//----- Begin of function Nation::consider_give_aid -----// // // talkMsg->talk_para1 - amount of the tribute. // int Nation::consider_give_aid(TalkMsg* talkMsg) { //-------- don't give tribute too frequently -------// NationRelation* nationRelation = get_relation(talkMsg->from_nation_recno); if( info.game_date < nationRelation->never_accept_until_date_array[TALK_GIVE_AID-1] ) return 0; //--------------------------------------------------// int importanceRating = (int) nationRelation->good_relation_duration_rating; if( nationRelation->status >= RELATION_FRIENDLY && ai_should_spend( importanceRating, talkMsg->talk_para1 ) ) // 0-importance is 0 { if( info.game_date > nationRelation->last_change_status_date + 720 - pref_allying_tendency ) // we have allied with this nation for quite some while { nationRelation->set_never_accept_until_date(TALK_GIVE_AID, 180); // don't give aid again too soon return 1; } } return 0; }
//----- Begin of function Nation::consider_give_tribute -----// // // talkMsg->talk_para1 - amount of the tribute. // int Nation::consider_give_tribute(TalkMsg* talkMsg) { //-------- don't give tribute too frequently -------// NationRelation* nationRelation = get_relation(talkMsg->from_nation_recno); if( info.game_date < nationRelation->never_accept_until_date_array[TALK_GIVE_TRIBUTE-1] ) return 0; //---------------------------------------------// int relationStatus = get_relation_status(talkMsg->from_nation_recno); Nation* fromNation = nation_array[talkMsg->from_nation_recno]; if( true_profit_365days() < 0 ) // don't give tribute if we are losing money return 0; int reserveYears = 1 + 3 * pref_cash_reserve / 100; // 1 to 4 years if( cash-talkMsg->talk_para1 < fixed_expense_365days() * reserveYears ) return 0; int militaryDiff = fromNation->military_rank_rating() - military_rank_rating(); if( militaryDiff > 10+pref_military_courage/2 ) { nationRelation->set_never_accept_until_date(TALK_GIVE_TRIBUTE, 180); return 1; } return 0; }
//----- Begin of function Nation::think_give_tribute_aid -----// // // This function is called when a nation rejected our request // which is important to us and we want to give tribute to the // nation so it may accept next time. // // <TalkMsg*> rejectedMsg - the TalkMsg that has been rejected. // int Nation::think_give_tribute_aid(TalkMsg* rejectedMsg) { //-----------get the talk id. ------------// int talkId; int talkNationRecno = rejectedMsg->to_nation_recno; int rejectedTalkId = rejectedMsg->talk_id; NationRelation* nationRelation = get_relation(talkNationRecno); if( nationRelation->status >= RELATION_FRIENDLY ) talkId = TALK_GIVE_AID; else talkId = TALK_GIVE_TRIBUTE; //-------- don't give tribute too frequently -------// if( info.game_date < nationRelation->never_accept_until_date_array[talkId-1] ) return 0; //---- think if the nation should spend money now ----// static short tributeAmountArray[] = { 500, 1000 }; int tributeAmount = tributeAmountArray[m.random(2)]; if( !ai_should_spend(0, (float) tributeAmount) ) // importance rating is 0 return 0; //--------------------------------------// Nation* talkNation = nation_array[talkNationRecno]; int rc; if( rejectedTalkId == TALK_PROPOSE_TRADE_TREATY ) { rc = ai_trade_with_rating(talkNationRecno) > 100-pref_trading_tendency/2; } else if ( rejectedTalkId == TALK_PROPOSE_FRIENDLY_TREATY || rejectedTalkId == TALK_PROPOSE_ALLIANCE_TREATY ) { int curRating = talkNation->trade_rating(talkNationRecno) + ai_trade_with_rating(talkNationRecno) + talkNation->overall_rating - overall_rating; int acceptRating = 200-pref_trading_tendency/4 -pref_allying_tendency/4; rc = curRating >= acceptRating; } //--------------------------------------// else if( rejectedTalkId == TALK_REQUEST_CEASE_WAR ) { rc = talkNation->military_rank_rating() > military_rank_rating() + (100-pref_peacefulness)/2; } //--------------------------------------// if( rc ) { //------ give tribute --------// talk_res.ai_send_talk_msg(talkNationRecno, nation_recno, talkId, tributeAmount); nationRelation->set_never_accept_until_date(talkId, 100); // don't offer tribute too often //------ request again after giving tribute ----// nationRelation->last_talk_reject_date_array[rejectedTalkId-1] = 0; // reset the rejected talk id. nationRelation->never_accept_until_date_array[rejectedTalkId-1] = 0; // reset the rejected talk id. talk_res.ai_send_talk_msg(talkNationRecno, nation_recno, rejectedTalkId, rejectedMsg->talk_para1, rejectedMsg->talk_para2 ); } return rc; }
//------- Begin of function TalkMsg::process_accepted_reply --------// // void TalkMsg::process_accepted_reply() { Nation* toNation = nation_array[to_nation_recno]; Nation* fromNation = nation_array[from_nation_recno]; NationRelation* fromRelation = fromNation->get_relation(to_nation_recno); NationRelation* toRelation = toNation->get_relation(from_nation_recno); int goodRelationDec=0; // whether the message is for requesting help. switch(talk_id) { case TALK_PROPOSE_TRADE_TREATY: toNation->set_trade_treaty(from_nation_recno, 1); break; case TALK_PROPOSE_FRIENDLY_TREATY: toNation->form_friendly_treaty(from_nation_recno); break; case TALK_PROPOSE_ALLIANCE_TREATY: toNation->form_alliance_treaty(from_nation_recno); break; case TALK_END_TRADE_TREATY: toNation->set_trade_treaty(from_nation_recno, 0); //---- set reject date on proposing treaty ----// fromRelation->set_never_accept_until_date(TALK_PROPOSE_TRADE_TREATY, 180); toRelation->set_never_accept_until_date(TALK_PROPOSE_TRADE_TREATY, 180); fromRelation->set_never_accept_until_date(TALK_END_TRADE_TREATY, 180); toRelation->set_never_accept_until_date(TALK_END_TRADE_TREATY, 180); //----- decrease reputation -----// if( toNation->reputation > 0 ) fromNation->change_reputation( -toNation->reputation * 5 / 100 ); break; case TALK_END_FRIENDLY_TREATY: case TALK_END_ALLIANCE_TREATY: fromNation->end_treaty(to_nation_recno, RELATION_NEUTRAL); //---- set reject date on proposing treaty ----// // // If a friendly treaty is rejected, assuming an alliance treaty // is even more impossible. (thus set reject date on both friendly // and alliance treaties.) // // If a alliance treaty is rejected, only set reject date on // alliance treaty, it may still try proposing friendly treaty later. // //---------------------------------------------// fromRelation->set_never_accept_until_date(TALK_PROPOSE_FRIENDLY_TREATY, 300); toRelation->set_never_accept_until_date(TALK_PROPOSE_FRIENDLY_TREATY, 300); fromRelation->set_never_accept_until_date(TALK_PROPOSE_ALLIANCE_TREATY, 300); toRelation->set_never_accept_until_date(TALK_PROPOSE_ALLIANCE_TREATY, 300); break; case TALK_REQUEST_MILITARY_AID: goodRelationDec = 10; break; case TALK_REQUEST_TRADE_EMBARGO: { //--- send an end treaty message to the target kingdom ---// TalkMsg talkMsg; memset(&talkMsg, 0, sizeof(TalkMsg)); talkMsg.to_nation_recno = (char) talk_para1; talkMsg.from_nation_recno = to_nation_recno; talkMsg.talk_id = TALK_END_TRADE_TREATY; talk_res.send_talk_msg( &talkMsg, COMMAND_AUTO ); goodRelationDec = 4; } break; case TALK_REQUEST_CEASE_WAR: unit_array.stop_war_between(to_nation_recno, from_nation_recno); toNation->set_relation_status(from_nation_recno, RELATION_TENSE); fromRelation->set_never_accept_until_date(TALK_DECLARE_WAR, 180); toRelation->set_never_accept_until_date(TALK_DECLARE_WAR, 180); break; case TALK_REQUEST_DECLARE_WAR: if( fromNation->get_relation_status(talk_para1) == RELATION_HOSTILE ) // the requesting nation must be at war with the enemy { //-- if we are currently allied or friendly with the nation, we need to terminate the friendly/alliance treaty first --// TalkMsg talkMsg; if( toNation->get_relation_status(talk_para1) == RELATION_ALLIANCE ) { memset(&talkMsg, 0, sizeof(TalkMsg)); talkMsg.to_nation_recno = (char) talk_para1; talkMsg.from_nation_recno = to_nation_recno; talkMsg.talk_id = TALK_END_ALLIANCE_TREATY; talk_res.send_talk_msg( &talkMsg, COMMAND_AUTO ); } else if( toNation->get_relation_status(talk_para1) == RELATION_FRIENDLY ) { memset(&talkMsg, 0, sizeof(TalkMsg)); talkMsg.to_nation_recno = (char) talk_para1; talkMsg.from_nation_recno = to_nation_recno; talkMsg.talk_id = TALK_END_FRIENDLY_TREATY; talk_res.send_talk_msg( &talkMsg, COMMAND_AUTO ); } //--- send a declare war message to the target kingdom ---// memset(&talkMsg, 0, sizeof(TalkMsg)); talkMsg.to_nation_recno = (char) talk_para1; talkMsg.from_nation_recno = to_nation_recno; talkMsg.talk_id = TALK_DECLARE_WAR; talk_res.send_talk_msg( &talkMsg, COMMAND_AUTO ); //----------------------------------------------------// goodRelationDec = 10; } break; case TALK_REQUEST_BUY_FOOD: { int buyCost = talk_para1 * talk_para2 / 10; fromNation->add_food( (float) talk_para1 ); fromNation->add_expense( EXPENSE_IMPORTS, (float) buyCost, 0 ); toNation->consume_food( (float) talk_para1 ); toNation->add_income( INCOME_EXPORTS, (float) buyCost, 0 ); break; } case TALK_DECLARE_WAR: toRelation->started_war_on_us_count++; // how many times this nation has started a war with us, the more the times the worse this nation is. toNation->set_relation_status(from_nation_recno, RELATION_HOSTILE); fromRelation->set_never_accept_until_date(TALK_REQUEST_CEASE_WAR, 150); toRelation->set_never_accept_until_date(TALK_REQUEST_CEASE_WAR, 150); fromRelation->set_never_accept_until_date(TALK_GIVE_TRIBUTE, 300); toRelation->set_never_accept_until_date(TALK_GIVE_TRIBUTE, 300); //--- decrease reputation of the nation which declares war ---// if( toNation->reputation > 0 ) fromNation->change_reputation( -toNation->reputation * 20 / 100 ); break; case TALK_GIVE_TRIBUTE: case TALK_GIVE_AID: fromNation->give_tribute( to_nation_recno, talk_para1 ); break; case TALK_DEMAND_TRIBUTE: case TALK_DEMAND_AID: toNation->give_tribute( from_nation_recno, talk_para1 ); goodRelationDec = talk_para1/200; break; case TALK_EXCHANGE_TECH: fromNation->give_tech( to_nation_recno, talk_para1, talk_para3 ); // give this tech to the target nation toNation->give_tech( from_nation_recno, talk_para2, talk_para4 ); // receive this tech from the target nation break; case TALK_REQUEST_SURRENDER: { float offeredAmt = (float) talk_para1 * 10; // * 10 is to restore its original value. It has been divided by 10 to cope with the upper limit of <short> toNation->add_income(INCOME_TRIBUTE, offeredAmt); fromNation->add_expense(EXPENSE_TRIBUTE, offeredAmt); toNation->surrender(from_nation_recno); break; } case TALK_SURRENDER: fromNation->surrender(to_nation_recno); break; default: err_here(); } //---- if the nation accepts a message that is requesting help, then decrease its good_relation_duration_rating, so it won't accept so easily next time ---// if( goodRelationDec ) toRelation->good_relation_duration_rating -= (float) goodRelationDec; //-- remove talk messges that are the same but sent from the opposite nation --// TalkMsg talkMsg; talkMsg.from_nation_recno = to_nation_recno; talkMsg.to_nation_recno = from_nation_recno; talkMsg.talk_id = talk_id; int loopCount=0; while(1) { err_when( loopCount++ > 100 ); int talkMsgRecno = talk_res.is_talk_msg_exist(&talkMsg, 0); // don't check talk_para1 & talk_para2 if( talkMsgRecno && talkMsg.talk_id != TALK_DECLARE_WAR ) // Exception handling - Declare War as both nations can send one when a spy creates an incident talk_res.del_talk_msg(talkMsgRecno); else break; } }
//----- Begin of function Nation::notify_talk_msg -----// // // Notify the AI for a notification only message (reply not needed.) // // This function is called directly from TalkRes::send_talk_msg_now() // when the message is sent. // void Nation::notify_talk_msg(TalkMsg* talkMsg) { int relationChange=0; NationRelation* nationRelation = get_relation(talkMsg->from_nation_recno); switch( talkMsg->talk_id ) { case TALK_END_TRADE_TREATY: // it's a notification message only, no accept or reject relationChange = -5; nationRelation->set_never_accept_until_date(TALK_PROPOSE_TRADE_TREATY, 180); break; case TALK_END_FRIENDLY_TREATY: // it's a notification message only, no accept or reject case TALK_END_ALLIANCE_TREATY: relationChange = -5; nationRelation->set_never_accept_until_date(TALK_PROPOSE_FRIENDLY_TREATY, 180); nationRelation->set_never_accept_until_date(TALK_PROPOSE_ALLIANCE_TREATY, 180); break; case TALK_DECLARE_WAR: // it already drops to zero when the status is set to hostile break; case TALK_GIVE_TRIBUTE: case TALK_GIVE_AID: //--------------------------------------------------------------// // The less cash the nation, the more it will appreciate the // tribute. // // $1000 for 100 ai relation increase if the nation's cash is 1000. //--------------------------------------------------------------// relationChange = 100 * talkMsg->talk_para1 / max(1000, (int) cash); break; case TALK_EXCHANGE_TECH: //--------------------------------------------------------------// // The lower tech the nation has, the more it will appreciate the // tech giveaway. // // Giving a level 2 weapon which the nation is unknown of // increase the ai relation by 60 if its pref_use_weapon is 100. // (by 30 if its pref_use_weapon is 0). //--------------------------------------------------------------// { relationChange += 5; break; } case TALK_SURRENDER: break; default: err_here(); } //------- chance relationship now -------// if( relationChange < 0 ) relationChange -= relationChange * pref_forgiveness / 100; if( relationChange != 0 ) change_ai_relation_level( talkMsg->from_nation_recno, relationChange ); }