Esempio n. 1
0
//----- Begin of function Nation::consider_trade_embargo -----//
//
int Nation::consider_trade_embargo(TalkMsg* talkMsg)
{
	int fromRelationRating    = ai_overall_relation_rating(talkMsg->from_nation_recno);
	int againstRelationRating = ai_overall_relation_rating(talkMsg->talk_para1);

	NationRelation* fromRelation 	  = get_relation(talkMsg->from_nation_recno);
	NationRelation* againstRelation = get_relation(talkMsg->talk_para1);

	//--- if we don't have a good enough relation with the requesting nation, turn down the request ---//

	if( fromRelation->good_relation_duration_rating < 5 )
		return 0;

	//--- if we are more friendly with the against nation than the requesting nation, turn down the request ---//

	if( againstRelation->good_relation_duration_rating >
		 fromRelation->good_relation_duration_rating )
	{
		return 0;
	}

	//--- if we have a large trade with the against nation or have a larger trade with the against nation than the requesting nation ---//

	int fromTrade 	  = trade_rating(talkMsg->from_nation_recno);
	int againstTrade = trade_rating(talkMsg->talk_para1);

	if( againstTrade > 40 ||
		 ( againstTrade > 10 && againstTrade - fromTrade > 15 ) )
	{
		return 0;
	}

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

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

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

	int acceptRating = 75;

	//--- it won't declare war with a friendly or allied nation easily ---//

	if( againstRelation->status >= RELATION_FRIENDLY )		// no need to handle RELATION_ALLIANCE separately as ai_overall_relation_relation() has already taken it into account
		acceptRating += 100;

	return fromRelationRating - againstRelationRating > acceptRating;
}
Esempio n. 2
0
//--------- Begin of function Nation::ai_improve_relation --------//
//
// This function is called once every year.
//
void Nation::ai_improve_relation()
{
	NationRelation* nationRelation;

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

		nationRelation = get_relation(i);

		if( nationRelation->status == NATION_HOSTILE )
			continue;

		//--- It improves the AI relation with nations that have trade with us. ---//

		change_ai_relation_level( i, trade_rating(i) / 10 );

		//--- decrease the started_war_on_us_count once per year, gradually forgiving other nations' wrong doing ---//

		if( nationRelation->started_war_on_us_count > 0
			 && misc.random(5-pref_forgiveness/20) > 0 )
		{
			nationRelation->started_war_on_us_count--;
		}
	}
}
Esempio n. 3
0
//----- Begin of function Nation::consider_alliance_rating -----//
//
// Return a rating from 0 to 100 for whether this nation should ally
// with the given nation.
//
int Nation::consider_alliance_rating(int nationRecno)
{
	Nation* nationPtr = nation_array[nationRecno];

	//---- the current relation affect the alliance tendency ---//

	NationRelation* nationRelation = get_relation(nationRecno);

	int allianceRating = nationRelation->ai_relation_level-20;

	//--- if the nation has a bad record of starting wars with us before, decrease the rating ---//

	allianceRating -= nationRelation->started_war_on_us_count * 20;

	//------ add the trade rating -------//

	int tradeRating = trade_rating(nationRecno) +				// existing trade amount
							ai_trade_with_rating(nationRecno)/2;	// possible trade

	allianceRating += tradeRating;

	//---- if the nation's power is larger than us, it's a plus ----//

	int powerRating = nationPtr->military_rank_rating() - military_rank_rating();		// if the nation's power is larger than ours, it's good to form treaty with them

	if( powerRating > 0 )
		allianceRating += powerRating;

	return allianceRating;
}
Esempio n. 4
0
//----- Begin of function Nation::ai_overall_relation_rating -----//
//
// Return the overall relation rating of this nation with the
// specific nation.
//
int Nation::ai_overall_relation_rating(int withNationRecno)
{
	NationRelation* nationRelation = get_relation(withNationRecno);
	Nation* 			 nationPtr = nation_array[withNationRecno];

	int overallRating = nationRelation->ai_relation_level +
							  (int) nationRelation->good_relation_duration_rating +
							  (int) nationPtr->reputation +
							  nationPtr->military_rank_rating() +
							  trade_rating(withNationRecno) +
							  ai_trade_with_rating(withNationRecno)/2 +
							  nationPtr->total_alliance_military();

	return overallRating;
}
Esempio n. 5
0
//----- Begin of function Nation::ai_should_attack_friendly -----//
//
// This function returns whether this nation should attack
// the given friendly nation.
//
// <int> friendlyNationRecno - the nation recno of the friendly nation.
// <int> attackTemptation    - a rating from 0 to 100 indicating
//										 temptation of attacking the target.
//
int Nation::ai_should_attack_friendly(int friendlyNationRecno, int attackTemptation)
{
	Nation  			*friendlyNation = nation_array[friendlyNationRecno];
	NationRelation *nationRelation = get_relation(friendlyNationRecno);

	//--- don't change terminate treaty too soon ---//

	if( info.game_date < nationRelation->last_change_status_date+60+pref_honesty/2 )		// only after 60 to 110 days
		return 0;

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

	int resistanceRating = friendlyNation->military_rank_rating()
								  - military_rank_rating();

	resistanceRating += nationRelation->ai_relation_level - 50;

	resistanceRating += trade_rating(friendlyNationRecno);

	return attackTemptation > resistanceRating;
}
Esempio n. 6
0
//----- Begin of function Nation::think_demand_tribute_aid -----//
//
// Demand tribute when the nation's economy is good and its
// military is weak.
//
int Nation::think_demand_tribute_aid()
{
	if( info.game_date < info.game_start_date + 180 + nation_recno*50 )		// don't ask for tribute too soon, as in the beginning, the ranking are all the same for all nations
		return 0;

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

	Nation* nationPtr;
	int	  totalNation=nation_array.size();
	int	  nationRecno=m.random(totalNation)+1;
	int	  curRating, requestRating;
	int	  talkId;
	int	  ourMilitary = military_rank_rating();
	int	  ourEconomy  = economic_rank_rating();

	for( int i=totalNation ; i>0 ; i-- )
	{
		if( ++nationRecno > totalNation )
			nationRecno = 1;

		if( nation_array.is_deleted(nationRecno) || nationRecno==nation_recno )
			continue;

		nationPtr = nation_array[nationRecno];

		//-- only demand tribute from non-friendly nations --//

		if( get_relation(nationRecno)->status <= RELATION_NEUTRAL )
			talkId = TALK_DEMAND_TRIBUTE;
		else
			talkId = TALK_DEMAND_AID;

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

		float fixedExpense = fixed_expense_365days();

		if( talkId == TALK_DEMAND_TRIBUTE )
		{
			if( !should_diplomacy_retry(talkId, nationRecno) )
				continue;

			curRating = ourMilitary - nationPtr->military_rank_rating();

			//---- if this is a Fryhtan nation, the tendency to request tribute is higher -----//

			if( is_monster() && nationPtr->is_human() )	// and the target is a human nation
			{
				curRating *= 2;

				//-- if we are running low of live points, it's time to kill somebody --//

				if( live_points < 500 * (100+pref_live_points_reserve) / 100 )
					curRating *= 2;
			}

			if( curRating < 0 )
				continue;

			//----------------------------------------------//
			//
			// Some nation will actually consider the ability
			// of the target nation to pay tribute, so nation
			// will not and just ask anyway.
			//
			//----------------------------------------------//

			if( pref_economic_development > 50 )
			{
				int addRating = nationPtr->economic_rank_rating()-ourEconomy;

				if( addRating > 0 )
					curRating += addRating;
			}

			requestRating = 20 + trade_rating(nationRecno)/2 +
								(100-pref_peacefulness)/3;

			if( cash < fixedExpense && fixedExpense != 0 )
				requestRating -= int( (float) requestRating * cash / fixedExpense);

		}
		else
		{
			if( cash >= fixedExpense )
				continue;

			if( cash > fixedExpense * (50+pref_cash_reserve) / 300 &&		// if the nation is runing short of cash, don't wait a while until next retry, retry immediately
				 !should_diplomacy_retry(talkId, nationRecno) )
			{
				continue;
			}

			//----- only ask for aid when the nation is short of cash ----//

			curRating = (ourMilitary - nationPtr->military_rank_rating())/2 +
							( nationPtr->economic_rank_rating()-ourEconomy );

			requestRating = 20 + 50 * (int)(cash / fixedExpense);
		}

		//----- if the target is a human player's nation -----//

		if( !nationPtr->is_ai() )
		{
			switch( config.ai_aggressiveness )
			{
				case OPTION_NONE:
					requestRating += 60;		// don't go against the player too easily
					break;

				case OPTION_LOW:
					requestRating += 40;		// don't go against the player too easily
					break;

				case OPTION_HIGH:
					requestRating -= 20;
					break;

				case OPTION_VERY_HIGH:
					requestRating -= 40;
					break;
			}

			//--- if the nation has plenty of cash, demand from it ----//

			if( nationPtr->cash > cash && config.ai_aggressiveness >= OPTION_HIGH )
			{
				requestRating -= (int) (nationPtr->cash - cash)/500;
			}
		}

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

		if( curRating > requestRating )
		{
			int tributeAmount;

			if( curRating - requestRating > 120 )
				tributeAmount = 4000;

			else if( curRating - requestRating > 80 )
				tributeAmount = 3000;

			else if( curRating - requestRating > 40 )
				tributeAmount = 2000;

			else if( curRating - requestRating > 20 )
				tributeAmount = 1000;

			else
				tributeAmount = 500;

			//------ stop in here if in tutorial mode -----//
			if( game.game_mode != GAME_TUTORIAL )
			{	
				cash += tributeAmount;
				return 0;
			}

			talk_res.ai_send_talk_msg(nationRecno, nation_recno, talkId, tributeAmount);

			return 1;
		}
	}

	return 0;
}
Esempio n. 7
0
//----- Begin of function Nation::think_declare_war -----//
//
int Nation::think_declare_war()
{
	NationRelation* nationRelation;
	int rc=0;

	//---- don't declare a new war if we already has enemies ---//

	int i;
	for( i=1 ; i<=nation_array.size() ; i++ )
	{
		if( nation_array.is_deleted(i) || i==nation_recno )
			continue;

		if( get_relation(i)->status == RELATION_HOSTILE )
			return 0;
	}

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

	int targetStrength, minStrength=0x1000, bestTargetNation=0;

	for( i=1 ; i<=nation_array.size() ; i++ )
	{
		if( nation_array.is_deleted(i) || i==nation_recno )
			continue;

		nationRelation = get_relation(i);

		if( !nationRelation->has_contact )
			continue;

		if( nationRelation->status == RELATION_HOSTILE )		// already at war
			continue;

		if( nationRelation->ai_relation_level >= 10 )
			continue;

		if( !ai_should_spend( 100-trade_rating(i) ) )		// if trade_rating is 0, importanceRating will be 100, if trade_rating is 100, importanceRating will be 0
			continue;

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

		Nation* targetNation = nation_array[i];

		targetStrength = targetNation->military_rank_rating() +
							  targetNation->population_rank_rating()/2 +
							  targetNation->economic_rank_rating()/3;

		if( targetStrength < minStrength )
		{
			minStrength = targetStrength;
			bestTargetNation = i;
		}
	}

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

	if( bestTargetNation )
	{
		if( should_diplomacy_retry(TALK_DECLARE_WAR, bestTargetNation) )
		{
			talk_res.ai_send_talk_msg(bestTargetNation, nation_recno, TALK_DECLARE_WAR);
			return 1;
		}
	}

	return 0;
}
Esempio n. 8
0
//----- Begin of function Nation::think_end_treaty -----//
//
int Nation::think_end_treaty()
{
	if( pref_honesty < 30 )		// never formally end a treaty if the honesty is < 30
		return 0;

	Nation* nationPtr;
	NationRelation* nationRelation;

	for( int i=1 ; i<=nation_array.size() ; i++ )
	{
		if( nation_array.is_deleted(i) || i==nation_recno )
			continue;

		nationRelation = get_relation(i);

		if( nationRelation->status < RELATION_FRIENDLY )
			continue;

		if( nationRelation->ai_secret_attack ||
			 ( nationRelation->ai_relation_level < 30 && trade_rating(i) < 50 ) )
		{
			//--- don't change terminate treaty too soon ---//

			if( info.game_date < nationRelation->last_change_status_date+60+pref_honesty/2 )		// only after 60 to 110 days
				continue;

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

			if( !talk_res.can_send_msg(i, nation_recno, nationRelation->status==RELATION_FRIENDLY ? TALK_END_FRIENDLY_TREATY : TALK_END_ALLIANCE_TREATY) )
				continue;

			nationPtr = nation_array[i];

			//-----------------------------------------//
			// What makes it tend to end treaty:
			// -higher honesty
			// -a larger overall power over the target nation.
			//
			// If honesty is > 50, if will end treaty
			// if its power is equal to the enemy.
			//
			// If honesty is < 50, if will end treaty
			// if its power is larger than the enemy.
			//
			// If honesty is > 50, if will end treaty
			// even if its power is lower than the enemy.
			//-----------------------------------------//

			if( pref_honesty-50 > nationPtr->overall_rating - overall_rating )
			{
				if( nationRelation->status == RELATION_FRIENDLY )
					talk_res.ai_send_talk_msg(i, nation_recno, TALK_END_FRIENDLY_TREATY);
				else
					talk_res.ai_send_talk_msg(i, nation_recno, TALK_END_ALLIANCE_TREATY);

				return 1;
			}
		}
	}

	return 0;
}
Esempio n. 9
0
//----- Begin of function Nation::think_against_mine_monopoly -----//
//
int Nation::think_against_mine_monopoly()
{
	//-- only think this after the game has been running for at least one year --//

	if( config.ai_aggressiveness < OPTION_HIGH )		// only attack if aggressiveness >= high
		return 0;

	if( info.game_date - info.game_start_date > 365 )
		return 0;

	if( profit_365days() > 0 )		// if we are making a profit, don't attack
		return 0;

	//-- for high aggressiveness, it will check cash before attack, for very high aggressiveness, it won't check cash before attack ---//

	if( config.ai_aggressiveness < OPTION_VERY_HIGH )		// only attack if aggressiveness >= high
	{
		if( cash > 2000 + 1000 * pref_cash_reserve / 100 )		// only attack if we run short of cash
			return 0;
	}

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

	if( !largest_town_recno )
		return 0;

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

	int baseRegionId = town_array[largest_town_recno]->region_id;

	// no region stat (region is too small), don't care
	if( !region_array[baseRegionId]->region_stat_id )
		return 0;

	RegionStat* regionStat = region_array.get_region_stat(baseRegionId);

	//---- if we already have a mine in this region ----//

	if( regionStat->mine_nation_count_array[nation_recno-1] > 0 )
		return 0;

	//----- if there is no mine in this region -----//

	if( regionStat->raw_count == 0 )
		return 0;

	//----- if enemies have occupied all mines -----//

	int mineCount, totalMineCount=0;
	int curRating, bestRating=0, targetNationRecno=0;

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

		//------ only deal with human players ------//

		if( nation_array[i]->is_ai() || i==nation_recno )
			continue;

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

		mineCount = regionStat->mine_nation_count_array[i-1];
		totalMineCount += mineCount;

		curRating = mineCount * 100
						- get_relation(i)->ai_relation_level
						- trade_rating(i);

		if( curRating > bestRating )
		{
			bestRating 		   = curRating;
			targetNationRecno = i;
		}
	}

	if( !targetNationRecno )
		return 0;

	//--- if the relationship with this nation is still good, don't attack yet, ask for aid first ---//

	NationRelation* nationRelation = get_relation(targetNationRecno);

	if( nationRelation->ai_relation_level > 30 )
	{
		int talkId;

		if( nationRelation->status >= NATION_FRIENDLY )
			talkId = TALK_DEMAND_AID;
		else
			talkId = TALK_DEMAND_TRIBUTE;

		if( should_diplomacy_retry(talkId, targetNationRecno) )
		{
			static short aidAmountArray[] = { 500, 1000, 2000 };

			int aidAmount = aidAmountArray[misc.random(3)];

			talk_res.ai_send_talk_msg(targetNationRecno, nation_recno, talkId, aidAmount);
		}

		return 0;
	}

	//------- attack one of the target enemy's mines -------//

	Firm* firmPtr;

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

		firmPtr = firm_array[i];

		if( firmPtr->firm_id != FIRM_MINE ||
			 firmPtr->nation_recno != targetNationRecno ||
			 firmPtr->region_id != baseRegionId )
		{
			continue;
		}

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

		int hasWar;
		int targetCombatLevel = enemy_firm_combat_level(firmPtr, 1, hasWar);

		return ai_attack_target( firmPtr->loc_x1, firmPtr->loc_y1,
										 targetCombatLevel, 0, 0, 0, 0, 1 );		// 1-use all camps
	}

	return 0;
}
Esempio n. 10
0
//----- Begin of function Nation::think_ally_against_big_enemy -----//
//
// Think about allying against a big enemy
//
int Nation::think_ally_against_big_enemy()
{
	if( info.game_date < info.game_start_date + 365 + nation_recno*70 )		// don't ask for tribute too soon, as in the beginning, the ranking are all the same for all nations
		return 0;

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

	int enemyNationRecno = nation_array.max_overall_nation_recno;

	if( enemyNationRecno == nation_recno )
		return 0;

	//-- if AI aggressiveness > high, only deal against the player, but not other kingdoms ---//

	if( config.ai_aggressiveness >= OPTION_HIGH )
	{
		if( nation_array[enemyNationRecno]->is_ai() )
			return 0;
	}

	//-- if AI aggressiveness is low, don't do this against the human player --//

	else if( config.ai_aggressiveness == OPTION_LOW )
	{
		if( !nation_array[enemyNationRecno]->is_ai() )
			return 0;
	}

	//--- increase the ai_relation_level towards other nations except the enemy so we can ally against the enemy ---//

	Nation* enemyNation = nation_array[enemyNationRecno];
	int     incRelationLevel = (100-overall_rank_rating())/10;

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

		if( i==nation_recno || i==enemyNationRecno )
			continue;

		int thisIncLevel = incRelationLevel * (100-get_relation(i)->ai_relation_level) / 100;

		change_ai_relation_level( i, thisIncLevel );
	}

	//---- don't have all nations doing it the same time ----//

	if( misc.random(nation_array.ai_nation_count)==0 )
		return 0;

	//---- if the trade rating is high, stay war-less with it ----//

	if( trade_rating(enemyNationRecno) +
		 ai_trade_with_rating(enemyNationRecno) > 100 - pref_trading_tendency/3 )
	{
		return 0;
	}

	//---- if the nation relation level is still high, then request aid/tribute ----//

	NationRelation* nationRelation = get_relation(enemyNationRecno);

	if( nationRelation->ai_relation_level > 30 )
	{
		int talkId;

		if( nationRelation->status >= NATION_FRIENDLY )
			talkId = TALK_DEMAND_AID;
		else
			talkId = TALK_DEMAND_TRIBUTE;

		if( should_diplomacy_retry(talkId, enemyNationRecno) )
		{
			static short aidAmountArray[] = { 500, 1000, 2000 };

			int aidAmount = aidAmountArray[misc.random(3)];

			talk_res.ai_send_talk_msg(enemyNationRecno, nation_recno, talkId, aidAmount);
		}

		return 0;
	}

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

	Nation* nationPtr;

	NationRelation *ourNationRelation, *enemyNationRelation;

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

		if( i==nation_recno || i==enemyNationRecno )
			continue;

		nationPtr = nation_array[i];

		ourNationRelation   = get_relation(i);
		enemyNationRelation = enemyNation->get_relation(i);

	}

	return 0;
}