Пример #1
0
//----- Begin of function Nation::think_eliminate_enemy_unit -----//
//
// This function is called to eliminate remaining enemy firms
// when all enemy towns have been destroyed.
//
int Nation::think_eliminate_enemy_unit(int enemyNationRecno)
{
	Unit *unitPtr;
	int  hasWar;

	for( int i=unit_array.size() ; i>0 ; i-- )
	{
		if( unit_array.is_deleted(i) )
			continue;

		unitPtr = unit_array[i];

		if( unitPtr->nation_recno != enemyNationRecno )
			continue;

		if( !unitPtr->is_visible() || unitPtr->mobile_type != UNIT_LAND )		// only deal with land units now 
			continue;

		//--- only attack if we have any base town in the enemy unit's region ---//

		if( base_town_count_in_region(unitPtr->region_id()) == 0 )
			continue;

		//----- take into account of the mobile units around this town -----//

		int mobileCombatLevel = mobile_defense_combat_level(unitPtr->next_x_loc(), unitPtr->next_y_loc(), unitPtr->nation_recno, 1, hasWar);

		if( mobileCombatLevel == -1 )		// do not attack this town because a battle is already going on
			continue;

		return ai_attack_target(unitPtr->next_x_loc(), unitPtr->next_y_loc(), mobileCombatLevel + (int) unitPtr->unit_power());
	}

	return 0;
}
Пример #2
0
//--------- Begin of function Nation::attack_enemy_town_defense --------//
//
// Attack enemy's defending forces on the target town.
//
// <Town*> targetTown - the pointer to the target town.
// [int]   useAllCamp   - whether use troops in all camps to attack the enemy town
//								  (default: 0)
//
// return: <int> 1 - a troop has been sent to attack the target.
//					  0 - we don't have sufficient troops for attacking the target.
//					 -1 - no defense on the target town, no attacking is needed.
//
int Nation::attack_enemy_town_defense(Town* targetTown, int useAllCamp)
{
	err_when( targetTown->nation_recno == nation_recno );		// cannot attack itself

	if( targetTown->nation_recno == 0 )
		return -1;

	//--- if there are any command bases linked to the town, attack them first ---//

	int  campCombatLevel, maxCampCombatLevel= -1;
	Firm *firmPtr, *bestTargetFirm=NULL;

	for( int i=targetTown->linked_firm_count-1 ; i>=0 ; i-- )
	{
		firmPtr = firm_array[ targetTown->linked_firm_array[i] ];

		if( firmPtr->nation_recno == targetTown->nation_recno &&
			 firmPtr->firm_id == FIRM_CAMP )
		{
			campCombatLevel = ((FirmCamp*)firmPtr)->total_combat_level();

			if( campCombatLevel > maxCampCombatLevel )
			{
				maxCampCombatLevel = campCombatLevel;
				bestTargetFirm = firmPtr;
			}
		}
	}

	//----- get the defense combat level of the mobile units around the town ----//

	int hasWar;
	int townMobileCombatLevel = mobile_defense_combat_level(targetTown->center_x, targetTown->center_y, targetTown->nation_recno, 0, hasWar);
	int totalDefenseCombatLevel = maxCampCombatLevel + townMobileCombatLevel;

	//----------------------------------------//

	if( bestTargetFirm )
	{
		Nation* targetNation = nation_array[bestTargetFirm->nation_recno];

		if( targetNation->is_at_war() )		// use all camps force if the nation is at war
			useAllCamp = 1;

		return ai_attack_target(bestTargetFirm->loc_x1, bestTargetFirm->loc_y1, totalDefenseCombatLevel,
										0, 0, 0, 0, useAllCamp );
	}
	else
	{
		//--- if there are any mobile defense force around the town ----//

		if( townMobileCombatLevel > 0 )
			return ai_attack_target(targetTown->center_x, targetTown->center_y, totalDefenseCombatLevel, 0, 1 );      // 1-just all move there and wait for the units to attack the enemies automatically
	}

	return -1;
}
Пример #3
0
//--------- Begin of function Nation::think_monster_target --------//
//
// Think about the best monster target in the given region.
//
// <int&> targetCombatLevel - var for returning the total combat level of the target firm.
//
int Nation::think_monster_target(int& targetCombatLevel)
{
	if( !largest_town_recno )
		return 0;

	Town* largestTown = town_array[largest_town_recno];
	Firm* firmPtr;
	int	combatLevel;
	int	curRating, bestRating= -10000, bestFirmRecno=0, hasWar;

	for( int firmRecno=firm_array.size() ; firmRecno>0 ; firmRecno-- )
	{
		if( firm_array.is_deleted(firmRecno) )
			continue;

		firmPtr = firm_array[firmRecno];

		if( firmPtr->firm_id != FIRM_MONSTER ||
			 firmPtr->region_id != largestTown->region_id )
		{
			continue;
		}

		//----- take into account of the mobile units around this town -----//

		int mobileCombatLevel = mobile_defense_combat_level(firmPtr->center_x, firmPtr->center_y, firmPtr->nation_recno, 1, hasWar);

		if( mobileCombatLevel == -1 )		// do not attack this town because a battle is already going on
			continue;

		curRating = 3 * misc.points_distance( largestTown->center_x, largestTown->center_y,
													  firmPtr->center_x, firmPtr->center_y );

		combatLevel = mobileCombatLevel +
						  ((FirmMonster*)firmPtr)->total_combat_level();

		curRating -= combatLevel;

		//---------------------------------//

		if( curRating > bestRating )
		{
			targetCombatLevel = combatLevel;
			bestRating        = curRating;
			bestFirmRecno     = firmRecno;
		}
	}

	return bestFirmRecno;
}
Пример #4
0
//----- Begin of function Nation::think_eliminate_enemy_firm -----//
//
// This function is called to eliminate remaining enemy firms
// when all enemy towns have been destroyed.
//
int Nation::think_eliminate_enemy_firm(int enemyNationRecno)
{
	//---- look for enemy firms to attack ----//

	int  hasWar;
	Firm *firmPtr;

	for( int i=firm_array.size() ; i>0 ; i-- )
	{
		if( firm_array.is_deleted(i) )
			continue;

		firmPtr = firm_array[i];

		if( firmPtr->nation_recno != enemyNationRecno )
			continue;

		//--- only attack if we have any base town in the enemy firm's region ---//

		if( base_town_count_in_region(firmPtr->region_id)==0 )
			continue;

		//----- take into account of the mobile units around this town -----//

		int mobileCombatLevel = mobile_defense_combat_level(firmPtr->center_x, firmPtr->center_y, firmPtr->nation_recno, 1, hasWar);

		if( mobileCombatLevel == -1 )		// do not attack this town because a battle is already going on
			continue;
	
		//---- calculate the combat level of this target firm ----//

		int firmCombatLevel;

		if( firmPtr->firm_id == FIRM_CAMP )                              		// other civilian firms
			firmCombatLevel = ((FirmCamp*)firmPtr)->total_combat_level();
		else
			firmCombatLevel = firmPtr->worker_count * 10;		// civilian firms have very low combat level

		return ai_attack_target(firmPtr->loc_x1, firmPtr->loc_y1, mobileCombatLevel + firmCombatLevel);
	}
	
	return 0;
}
Пример #5
0
//--------- Begin of function Nation::enemy_town_combat_level --------//
//
// <Town*> targetTown  - the target town
// <int>   returnIfWar - return -1 if there is any war around the town
// <int&>  hasWar      - a reference var for returning whether there is any war
//
// return: <int> the enemy's total defense combat level minus the player's
//					  combat level.
///		        return -1 if there is war and returnIfWar is 1
//
int Nation::enemy_town_combat_level(Town* targetTown, int returnIfWar, int hasWar)
{
	int enemyCombatLevel = mobile_defense_combat_level(targetTown->center_x, targetTown->center_y, targetTown->nation_recno, returnIfWar, hasWar);		//0-don't return even there are wars around the town

	if( enemyCombatLevel < 0 )		// there is a war going on
		return -1;

	//---- calculate the attack rating of this target town ----//

//	enemyCombatLevel += targetTown->jobless_population * 5;	//**BUGHERE

	//--- calculate the combat level of enemy camps linked to this town ---//

	Firm* firmPtr;

	for( int i=targetTown->linked_firm_count-1 ; i>=0 ; i-- )
	{
		firmPtr = firm_array[ targetTown->linked_firm_array[i] ];

		if( firmPtr->nation_recno == targetTown->nation_recno &&
			 firmPtr->firm_id == FIRM_CAMP )
		{
			enemyCombatLevel += ((FirmCamp*)firmPtr)->total_combat_level();
		}
	}
/*
	//----- add this and neighbor town's needed combat level ----//

	Town* townPtr;

	for( i=targetTown->linked_town_count-1 ; i>=0 ; i-- )
	{
		townPtr = town_array[ targetTown->linked_town_array[i] ];

		if( townPtr->nation_recno == targetTown->nation_recno )	//**BUGHERE
			enemyCombatLevel += townPtr->jobless_population * 5;
	}
*/
	return enemyCombatLevel;
}
Пример #6
0
//----- Begin of function Nation::think_eliminate_enemy_town -----//
//
// This function is called to eliminate remaining enemy firms
// when all enemy towns have been destroyed.
//
int Nation::think_eliminate_enemy_town(int enemyNationRecno)
{
	//---- look for enemy firms to attack ----//

	int  hasWar;
	Town *townPtr;

	for( int i=town_array.size() ; i>0 ; i-- )
	{
		if( town_array.is_deleted(i) )
			continue;

		townPtr = town_array[i];

		if( townPtr->nation_recno != enemyNationRecno )
			continue;

		//--- only attack if we have any base town in the enemy town's region ---//

		if( base_town_count_in_region(townPtr->region_id)==0 )
			continue;

		//----- take into account of the mobile units around this town -----//

		int mobileCombatLevel = mobile_defense_combat_level(townPtr->center_x, townPtr->center_y, townPtr->nation_recno, 1, hasWar);

		if( mobileCombatLevel == -1 )		// do not attack this town because a battle is already going on
			continue;

		//---- calculate the combat level of this target town ----//

		int townCombatLevel = townPtr->protection_available();

		return ai_attack_target(townPtr->loc_x1, townPtr->loc_y1, mobileCombatLevel + townCombatLevel);
	}

	return 0;
}
Пример #7
0
//--------- Begin of function Nation::enemy_firm_combat_level --------//
//
// <Firm*> targetFirm  - the target firm
// <int>   returnIfWar - return -1 if there is any war around the town
// <int&>  hasWar      - a reference var for returning whether there is any war
//
// return: <int> the enemy's total defense combat level minus the player's
//					  combat level.
///		        return -1 if there is war and returnIfWar is 1
//
int Nation::enemy_firm_combat_level(Firm* targetFirm, int returnIfWar, int hasWar)
{
	int enemyCombatLevel = mobile_defense_combat_level(targetFirm->center_x, targetFirm->center_y, targetFirm->nation_recno, returnIfWar, hasWar);		//0-don't return even there are wars around the town

	if( enemyCombatLevel < 0 )		// there is a war going on
		return -1;

	//--- calculate the combat level of enemy camps linked to this towns that are linked to this mine ---//

	Town* linkedTown;
	Firm* firmPtr;
	int   targetNationRecno = targetFirm->nation_recno;

	//---- scan towns linked to this mine -----//

	for( int i=targetFirm->linked_town_count-1 ; i>=0 ; i-- )
	{
		linkedTown = town_array[ targetFirm->linked_town_array[i] ];

		if( linkedTown->nation_recno != targetNationRecno )
			continue;

		//------ scan firms linked to this town -------//

		for( int j=linkedTown->linked_firm_count-1 ; j>=0 ; j-- )
		{
			firmPtr = firm_array[ linkedTown->linked_firm_array[j] ];

			if( firmPtr->nation_recno == targetNationRecno &&
				 firmPtr->firm_id == FIRM_CAMP )
			{
				enemyCombatLevel += ((FirmCamp*)firmPtr)->total_combat_level();
			}
		}
	}

	return enemyCombatLevel;
}
Пример #8
0
//--------- Begin of function Nation::think_destroy_raw_site_guard --------//
//
int Nation::think_destroy_raw_site_guard()
{
    Site* 	 sitePtr;
    Location* locPtr;
    Unit* 	 unitPtr;

    for( int i=site_array.size() ; i>0 ; i-- )
    {
        if( site_array.is_deleted(i) )
            continue;

        sitePtr = site_array[i];

        //--- if there is already a mine built on this raw site ---//

        if( sitePtr->has_mine )
            continue;

        //----- if there is a unit standing on this site -----//

        locPtr = world.get_loc( sitePtr->map_x_loc, sitePtr->map_y_loc );

        if( !locPtr->unit_recno(UNIT_LAND) )
            continue;

        unitPtr = unit_array[ locPtr->unit_recno(UNIT_LAND) ];

        if( unitPtr->cur_action != SPRITE_IDLE )		// only attack if this unit is idle
            continue;

        if( unitPtr->nation_recno == nation_recno )	// don't attack our own units
            continue;

        //------ check if we have a presence in this region ----//

        if( is_human() && base_town_count_in_region(sitePtr->region_id) == 0 )
            continue;

        //------ check the relationship with this unit ------//
        //
        // If we are friendly with this nation, don't attack it.
        //
        //---------------------------------------------------//

        if( get_relation_status(unitPtr->nation_recno) >= RELATION_FRIENDLY )
            continue;

        //--------- attack the enemy unit ---------//

        int hasWar;
        int enemyCombatLevel = mobile_defense_combat_level( sitePtr->map_x_loc,
                               sitePtr->map_y_loc, unitPtr->nation_recno, 1, hasWar );

        if( enemyCombatLevel == - 1 )		// a war is going on here, don't attack this target
            continue;

        if( ai_attack_target(sitePtr->map_x_loc, sitePtr->map_y_loc, enemyCombatLevel, 0, 0, 0, 0, 1) )		// 1-use all camps
            return 1;
    }

    return 0;
}
Пример #9
0
void Nation::think_capturing_enemy_town()
{
	if( !ai_capture_enemy_town_recno )
		return;

	if( town_array.is_deleted(ai_capture_enemy_town_recno) ||
		 town_array[ai_capture_enemy_town_recno]->nation_recno == nation_recno )		// this town has been captured already
	{
		ai_capture_enemy_town_recno = 0;
		return;
	}

	//--- check the enemy's mobile defense combat level around the town ---//

	Town* targetTown = town_array[ai_capture_enemy_town_recno];
	int	hasWar;

	int mobileCombatLevel = mobile_defense_combat_level(targetTown->center_x, targetTown->center_y, targetTown->nation_recno, 0, hasWar);		// 0-don't return immediately even if there is war around this town

	//---- if we haven't started attacking the town yet -----//

	if( !ai_capture_enemy_town_start_attack_date )
	{
		if( hasWar==2 )		// we are at war with the nation now
			ai_capture_enemy_town_start_attack_date = info.game_date;

		if( info.game_date > ai_capture_enemy_town_plan_date + 90 )		// when 3 months have gone and there still hasn't been any attack on the town, there must be something bad happened to our troop, cancel the entire action
			ai_capture_enemy_town_recno = 0;

		return;		// do nothing if the attack hasn't started yet
	}

	//--------- check if we need reinforcement --------//

	//-----------------------------------------------------------//
	// Check how long we have started attacking because only
	// when the it has been started for a while, our force
	// will reach the target and the offensive and defensive force
	// total can be calculated accurately.
	//-----------------------------------------------------------//

	if( info.game_date - ai_capture_enemy_town_start_attack_date >= 15 )
	{
		//-------- check if we need any reinforcement --------//

		if( mobileCombatLevel > 0 && hasWar==2 )		// we are still in war with the enemy
		{
			ai_attack_target(targetTown->center_x, targetTown->center_y, mobileCombatLevel, 0, 1 );      // 1-just all move there and wait for the units to attack the enemies automatically
			return;
		}
	}

	//----- there is currently no war at the town  -----//
	//
	// - either we are defeated or we have destroyed their command base.
	//
	//--------------------------------------------------//

	if( hasWar != 2 )
	{
		//---- attack enemy's defending forces on the target town ----//

		int rc = attack_enemy_town_defense(targetTown, ai_capture_enemy_town_use_all_camp);

		if( rc == 1 )		// 1 means a troop has been sent to attack the town
		{
			ai_capture_enemy_town_start_attack_date = 0;
			return;
		}

		//---------- reset the vars --------//

		ai_capture_enemy_town_recno = 0;
		ai_capture_enemy_town_start_attack_date = 0;

		//--------- other situations --------//

		if( rc == -1 )		// -1 means no defense on the target town, no attacking is needed.
		{
			start_capture( targetTown->town_recno );		// call AI functions in OAI_CAPT.CPP to capture the town
		}
		
		// 0 means we don't have enough troop to attack the enemy
	}
}
Пример #10
0
//----- Begin of function Nation::consider_military_aid -----//
//
int Nation::consider_military_aid(TalkMsg* talkMsg)
{
	Nation*			 fromNation   = nation_array[talkMsg->from_nation_recno];
	NationRelation* fromRelation = get_relation(talkMsg->from_nation_recno);

	//----- don't aid too frequently ------//

	if( info.game_date < fromRelation->last_military_aid_date + 200 - pref_allying_tendency )
		return 0;

	//------- only when the AI relation >= 60 --------//

	if( fromRelation->ai_relation_level < 60 )
		return 0;

	//--- if the requesting nation is not at war now ----//

	if( !fromNation->is_at_war() )
		return 0;

	//---- can't aid if we are at war ourselves -----//

	if( is_at_war() )
		return 0;

	//--- if the nation is having a financial difficulty, it won't agree ---//

	if( cash < 2000 * pref_cash_reserve / 100  )
		return 0;

	//----- can't aid if we are too weak ourselves ---//

	if( ai_general_count*10 + total_human_count + total_monster_count
		 < 100-pref_military_courage/2 )
	{
		return 0;
	}

	//----- see what units are attacking the nation -----//

	if( unit_array.is_deleted(fromNation->last_attacker_obj_recno) )
		return 0;

	BaseObj* baseObj = base_obj_array[ fromNation->last_attacker_obj_recno ];

	if( baseObj->nation_recno == nation_recno )		// if it's our own units
		return 0;

	if( baseObj->nation_recno == 0 )
		return 0;

	if( !baseObj->is_visible() )
		return 0;

	//------ only attack if it's a common enemy to us and our ally -----//

	if( get_relation(baseObj->nation_recno)->status != RELATION_HOSTILE )
		return 0;

	//------- calculate the combat level of the target units there ------//

	int hasWar;

	int targetCombatLevel = mobile_defense_combat_level( baseObj->obj_loc_x1(), baseObj->obj_loc_y1(),
									baseObj->nation_recno, 0, hasWar );

	if( ai_attack_target(baseObj->obj_loc_x1(), baseObj->obj_loc_y1(),
		 targetCombatLevel, 0, 1 ) )		//0-not defense mode, 1-just move to flag
	{
		fromRelation->last_military_aid_date = info.game_date;
		return 1;
	}

	return 0;
}