//----- 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; }
//--------- 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--; } } }
//----- 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; }
//----- 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; }
//----- 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; }
//----- 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; }
//----- 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; }
//----- 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; }
//----- 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; }
//----- 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; }