1 /*
2 * Seven Kingdoms: Ancient Adversaries
3 *
4 * Copyright 1997,1998 Enlight Software Ltd.
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21 //Filename : OAI_TALK.CPP
22 //Description: AI routines on diplomacy.
23
24 #include <OCONFIG.h>
25 #include <OTALKRES.h>
26 #include <OTECHRES.h>
27 #include <OF_MARK.h>
28 #include <ONATION.h>
29
30
31 //-------- Declare static functions ---------//
32
33 static int has_sent_same_msg(TalkMsg* talkMsg);
34
35
36 //----- Begin of function Nation::ai_process_talk_msg -----//
37 //
38 // action_para - recno of the message in talk_res.talk_msg_array.
39 //
ai_process_talk_msg(ActionNode * actionNode)40 int Nation::ai_process_talk_msg(ActionNode* actionNode)
41 {
42 if( talk_res.is_talk_msg_deleted(actionNode->action_para) ) // if the talk message has been deleted
43 return -1;
44
45 TalkMsg* talkMsg = talk_res.get_talk_msg(actionNode->action_para);
46
47 err_when( talkMsg->talk_id < 1 || talkMsg->talk_id > MAX_TALK_TYPE );
48
49 err_when( talkMsg->from_nation_recno == nation_recno );
50 err_when( talkMsg->to_nation_recno != nation_recno );
51
52 if( !talkMsg->is_valid_to_reply() ) // if it is no longer valid
53 return -1;
54
55 //----- call the consider function -------//
56
57 if( talkMsg->reply_type == REPLY_WAITING )
58 {
59 int rc = consider_talk_msg(talkMsg);
60
61 if( rc==1 ) // if rc is not 1 or 0, than the consider function have processed itself, no need to call reply_talk_msg() here
62 talk_res.reply_talk_msg( actionNode->action_para, REPLY_ACCEPT, COMMAND_AI );
63
64 else if( rc==0 )
65 talk_res.reply_talk_msg( actionNode->action_para, REPLY_REJECT, COMMAND_AI );
66
67 // don't reply if rc is neither 0 or 1
68 }
69 else
70 err_here();
71
72 return -1; // always return -1 to remove the action from action_array.
73 }
74 //------ End of function Nation::ai_process_talk_msg ------//
75
76
77 //----- Begin of function Nation::consider_talk_msg -----//
78 //
consider_talk_msg(TalkMsg * talkMsg)79 int Nation::consider_talk_msg(TalkMsg* talkMsg)
80 {
81 //--------------------------------------------//
82 // Whether the nation has already sent out a
83 // message that is the same as the one it received.
84 // If so, accept the message right now.
85 //--------------------------------------------//
86
87 switch( talkMsg->talk_id )
88 {
89 case TALK_PROPOSE_TRADE_TREATY:
90 case TALK_PROPOSE_FRIENDLY_TREATY:
91 case TALK_PROPOSE_ALLIANCE_TREATY:
92 case TALK_REQUEST_TRADE_EMBARGO:
93 case TALK_REQUEST_CEASE_WAR:
94 case TALK_REQUEST_DECLARE_WAR:
95 if( has_sent_same_msg(talkMsg) )
96 return 1;
97 };
98
99 //-------------------------------//
100
101 switch( talkMsg->talk_id )
102 {
103 case TALK_PROPOSE_TRADE_TREATY:
104 return consider_trade_treaty(talkMsg->from_nation_recno) >= 0; // the returned value is the curRating - acceptRating, if >=0, means it accepts
105
106 case TALK_PROPOSE_FRIENDLY_TREATY:
107 return consider_friendly_treaty(talkMsg->from_nation_recno) >= 0;
108
109 case TALK_PROPOSE_ALLIANCE_TREATY:
110 return consider_alliance_treaty(talkMsg->from_nation_recno) >= 0;
111
112 case TALK_REQUEST_MILITARY_AID:
113 return consider_military_aid(talkMsg);
114
115 case TALK_REQUEST_TRADE_EMBARGO:
116 return consider_trade_embargo(talkMsg);
117
118 case TALK_REQUEST_CEASE_WAR:
119 return consider_cease_war(talkMsg->from_nation_recno) >= 0;
120
121 case TALK_REQUEST_DECLARE_WAR:
122 return consider_declare_war(talkMsg);
123
124 case TALK_REQUEST_BUY_FOOD:
125 return consider_sell_food(talkMsg);
126
127 case TALK_GIVE_TRIBUTE:
128 return consider_take_tribute(talkMsg);
129
130 case TALK_DEMAND_TRIBUTE:
131 return consider_give_tribute(talkMsg);
132
133 case TALK_GIVE_AID:
134 return consider_take_aid(talkMsg);
135
136 case TALK_DEMAND_AID:
137 return consider_give_aid(talkMsg);
138
139 case TALK_GIVE_TECH:
140 return consider_take_tech(talkMsg);
141
142 case TALK_DEMAND_TECH:
143 return consider_give_tech(talkMsg);
144
145 case TALK_REQUEST_SURRENDER:
146 return consider_accept_surrender_request(talkMsg);
147
148 default:
149 err_here();
150 return 0;
151 }
152 }
153 //------ End of function Nation::consider_talk_msg ------//
154
155
156 //----- Begin of function Nation::notify_talk_msg -----//
157 //
158 // Notify the AI for a notification only message (reply not needed.)
159 //
160 // This function is called directly from TalkRes::send_talk_msg_now()
161 // when the message is sent.
162 //
notify_talk_msg(TalkMsg * talkMsg)163 void Nation::notify_talk_msg(TalkMsg* talkMsg)
164 {
165 int relationChange=0;
166 NationRelation* nationRelation = get_relation(talkMsg->from_nation_recno);
167
168 switch( talkMsg->talk_id )
169 {
170 case TALK_END_TRADE_TREATY: // it's a notification message only, no accept or reject
171 relationChange = -5;
172 nationRelation->last_talk_reject_date_array[TALK_PROPOSE_TRADE_TREATY-1] = info.game_date;
173 break;
174
175 case TALK_END_FRIENDLY_TREATY: // it's a notification message only, no accept or reject
176 case TALK_END_ALLIANCE_TREATY:
177 relationChange = -5;
178 nationRelation->last_talk_reject_date_array[TALK_PROPOSE_FRIENDLY_TREATY-1] = info.game_date;
179 nationRelation->last_talk_reject_date_array[TALK_PROPOSE_ALLIANCE_TREATY-1] = info.game_date;
180 break;
181
182 case TALK_DECLARE_WAR: // it already drops to zero when the status is set to hostile
183 break;
184
185 case TALK_GIVE_TRIBUTE:
186 case TALK_GIVE_AID:
187
188 //--------------------------------------------------------------//
189 // The less cash the nation, the more it will appreciate the
190 // tribute.
191 //
192 // $1000 for 100 ai relation increase if the nation's cash is 1000.
193 //--------------------------------------------------------------//
194
195 relationChange = 100 * talkMsg->talk_para1 / MAX(1000, (int) cash);
196 break;
197
198 case TALK_GIVE_TECH:
199
200 //--------------------------------------------------------------//
201 // The lower tech the nation has, the more it will appreciate the
202 // tech giveaway.
203 //
204 // Giving a level 2 weapon which the nation is unknown of
205 // increase the ai relation by 60 if its pref_use_weapon is 100.
206 // (by 30 if its pref_use_weapon is 0).
207 //--------------------------------------------------------------//
208 {
209 int ownLevel = tech_res[talkMsg->talk_para1]->get_nation_tech_level(nation_recno);
210
211 if( talkMsg->talk_para2 > ownLevel )
212 relationChange = 30 * (talkMsg->talk_para2-ownLevel)
213 * (100+pref_use_weapon) / 200;
214 break;
215 }
216
217 case TALK_SURRENDER:
218 break;
219
220 default:
221 err_here();
222 }
223
224 //------- chance relationship now -------//
225
226 if( relationChange < 0 )
227 relationChange -= relationChange * pref_forgiveness / 100;
228
229 if( relationChange != 0 )
230 change_ai_relation_level( talkMsg->from_nation_recno, relationChange );
231 }
232 //------ End of function Nation::notify_talk_msg ------//
233
234
235 //----- Begin of function Nation::consider_trade_treaty -----//
236 //
237 // Consider agreeing to open up trade with the given nation.
238 //
consider_trade_treaty(int withNationRecno)239 int Nation::consider_trade_treaty(int withNationRecno)
240 {
241 NationRelation* nationRelation = get_relation(withNationRecno);
242
243 //---- don't accept new trade treaty soon when the trade treaty was terminated not too long ago ----//
244
245 if( info.game_date < nationRelation->last_talk_reject_date_array[TALK_END_TRADE_TREATY-1] + 365 - pref_forgiveness )
246 return 0;
247
248 //-- if we look forward to have a trade treaty with this nation ourselves --//
249
250 if( nationRelation->ai_demand_trade_treaty )
251 return 1;
252
253 return ai_trade_with_rating(withNationRecno) > 0;
254 }
255 //------ End of function Nation::consider_trade_treaty ------//
256
257
258 //----- Begin of function Nation::ai_trade_with_rating -----//
259 //
260 // Return a rating from 0 to 100 indicating how important
261 // will be for us to trade with the given nation.
262 //
ai_trade_with_rating(int withNationRecno)263 int Nation::ai_trade_with_rating(int withNationRecno)
264 {
265 Nation* nationPtr = nation_array[withNationRecno];
266 int tradeRating=0;
267
268 for( int i=0 ; i<MAX_RAW ; i++ )
269 {
270 //--------------------------------------------------------------//
271 //
272 // If we have the raw material and it doesn't have, then we
273 // can export to it. And it is more favorite if the nation's
274 // population is high, so we can export more.
275 //
276 //--------------------------------------------------------------//
277
278 if( raw_count_array[i] && !nationPtr->raw_count_array[i] )
279 tradeRating += MIN(30, nationPtr->total_population/3);
280
281 //--------------------------------------------------------------//
282 //
283 // If the nation has the supply a raw material that we don't
284 // have, then we can import it.
285 //
286 //--------------------------------------------------------------//
287
288 else if( nationPtr->raw_count_array[i] && !raw_count_array[i] )
289 tradeRating += 30;
290 }
291
292 return tradeRating;
293 }
294 //------ End of function Nation::ai_trade_with_rating ------//
295
296
297 //----- Begin of function Nation::consider_friendly_treaty -----//
298 //
consider_friendly_treaty(int withNationRecno)299 int Nation::consider_friendly_treaty(int withNationRecno)
300 {
301 NationRelation* nationRelation = get_relation(withNationRecno);
302
303 if( nationRelation->status >= NATION_FRIENDLY ) // already has a friendly relationship
304 return -1; // -1 means don't reply
305
306 if( nationRelation->ai_relation_level < 20 )
307 return -1;
308
309 //------- some consideration first -------//
310
311 if( !should_consider_friendly(withNationRecno) )
312 return -1;
313
314 //------ total import and export amounts --------//
315
316 int curRating = consider_alliance_rating(withNationRecno);
317
318 int acceptRating = 60 - pref_allying_tendency/8 - pref_peacefulness/4; // range of acceptRating: 23 to 60
319
320 return curRating - acceptRating;
321 }
322 //------ End of function Nation::consider_friendly_treaty ------//
323
324
325 //----- Begin of function Nation::consider_alliance_treaty -----//
326 //
consider_alliance_treaty(int withNationRecno)327 int Nation::consider_alliance_treaty(int withNationRecno)
328 {
329 NationRelation* nationRelation = get_relation(withNationRecno);
330
331 if( nationRelation->status >= NATION_ALLIANCE ) // already has a friendly relationship
332 return -1; // -1 means don't reply
333
334 if( nationRelation->ai_relation_level < 40 )
335 return -1;
336
337 //------- some consideration first -------//
338
339 if( !should_consider_friendly(withNationRecno) )
340 return -1;
341
342 //------ total import and export amounts --------//
343
344 int curRating = consider_alliance_rating(withNationRecno);
345
346 int acceptRating = 80 - pref_allying_tendency/4 - pref_peacefulness/8; // range of acceptRating: 43 to 80
347
348 return curRating - acceptRating;
349 }
350 //------ End of function Nation::consider_alliance_treaty ------//
351
352
353 //----- Begin of function Nation::consider_cease_war -----//
354 //
355 // This function is shared by think_request_cease_war().
356 //
consider_cease_war(int withNationRecno)357 int Nation::consider_cease_war(int withNationRecno)
358 {
359 NationRelation* nationRelation = get_relation(withNationRecno);
360
361 if( nationRelation->status != NATION_HOSTILE )
362 return -1; // -1 means don't reply
363
364 //---- if we are attacking the nation, don't cease fire ----//
365
366 if( ai_attack_target_nation_recno == withNationRecno )
367 return -1;
368
369 //---- if we are planning to capture the enemy's town ---//
370
371 if( ai_capture_enemy_town_recno &&
372 !town_array.is_deleted(ai_capture_enemy_town_recno) &&
373 town_array[ai_capture_enemy_town_recno]->nation_recno == withNationRecno )
374 {
375 return -1;
376 }
377
378 //--- don't cease fire too soon after a war is declared ---//
379
380 if( info.game_date < nationRelation->last_change_status_date + 60 + (100-pref_peacefulness) ) // more peaceful nation may cease fire sooner (but the minimum is 60 days).
381 return -1;
382
383 //------ if we're run short of money for war -----//
384
385 Nation* withNation = nation_array[withNationRecno];
386
387 if( !ai_should_spend_war(withNation->military_rank_rating(), 1) ) // if we shouldn't spend any more on war, then return 1
388 return 1;
389
390 //------------------------------------------------//
391
392 int curRating = consider_alliance_rating(withNationRecno);
393
394 //------------------------------------//
395 //
396 // Tend to be easilier to accept cease-fire if this nation's
397 // military strength is weak.
398 //
399 // If the nation's peacefulness concern is high, it will
400 // also be more likely to accept cease-fire.
401 //
402 //-------------------------------------//
403
404 //--- if the enemy is more power than us, tend more to request cease-fire ---//
405
406 curRating += total_enemy_military() - military_rank_rating();
407
408 curRating += ai_trade_with_rating(withNationRecno) * (100+pref_trading_tendency) / 300; // when we have excessive supply, we may want to cease-fire with our enemy
409
410 curRating -= (military_rank_rating()-50)/2; // if our military ranking is high, we may like to continue the war, otherwise the nation should try to cease-fire
411
412 curRating -= nationRelation->started_war_on_us_count*10; // the number of times this nation has started a war with us, the higher the number, the more unlikely we will accept cease-fire
413
414 int acceptRating = pref_peacefulness/4;
415
416 return curRating - acceptRating;
417 }
418 //------ End of function Nation::consider_cease_war ------//
419
420
421 //----- Begin of function Nation::consider_sell_food -----//
422 //
423 // talkMsg->talk_para1 - qty of food wanted to buy.
424 // talkMsg->talk_para2 - buying price offered for 10 food.
425 //
consider_sell_food(TalkMsg * talkMsg)426 int Nation::consider_sell_food(TalkMsg* talkMsg)
427 {
428 int relationStatus = get_relation_status(talkMsg->from_nation_recno);
429
430 if( relationStatus == NATION_HOSTILE )
431 return 0;
432
433 //--- if after selling the food, the remaining is not enough for its own consumption for ? years ---//
434
435 float newFood = food-talkMsg->talk_para1;
436 float yearConsumption = (float) yearly_food_consumption();
437 int offeredAmount = talkMsg->talk_para2;
438 int relationLevel = get_relation(talkMsg->from_nation_recno)->ai_relation_level;
439
440 if( newFood < 1000 + 1000 * pref_food_reserve / 100 )
441 return 0;
442
443 if( relationLevel >= 50 )
444 offeredAmount += 5; // increase the chance of selling food
445
446 else if( relationLevel < 30 ) // decrease the chance of selling food
447 offeredAmount -=5 ;
448
449 //---- if we run short of cash, we tend to accept the offer ---//
450
451 float fixedExpense = fixed_expense_365days();
452
453 if( cash < fixedExpense )
454 offeredAmount += (int) (20 * (fixedExpense-cash) / fixedExpense);
455
456 //---------------------------------//
457
458 float reserveYears = (float) (100+pref_food_reserve) / 100; // 1 to 2 years
459
460 if( yearly_food_change() > 0 &&
461 newFood > yearConsumption * reserveYears )
462 {
463 if( offeredAmount >= 10 ) // offered >= $10
464 {
465 return 1;
466 }
467 else // < $10, only if we have plenty of reserve
468 {
469 if( newFood > yearConsumption * reserveYears * 2 )
470 return 1;
471 }
472 }
473 else
474 {
475 if( offeredAmount >= 20 )
476 {
477 if( yearly_food_change() > 0 &&
478 newFood > yearConsumption * reserveYears / 2 )
479 {
480 return 1;
481 }
482 }
483
484 if( offeredAmount >= 30 )
485 {
486 return yearly_food_change() > 0 ||
487 newFood > yearConsumption * reserveYears;
488 }
489 }
490
491 return 0;
492 }
493 //------ End of function Nation::consider_sell_food ------//
494
495
496 //----- Begin of function Nation::should_consider_friendly -----//
497 //
should_consider_friendly(int withNationRecno)498 int Nation::should_consider_friendly(int withNationRecno)
499 {
500 Nation* withNation = nation_array[withNationRecno];
501
502 //------- if this is a larger nation -------//
503
504 if( overall_rank_rating() / 100 > 50 )
505 {
506 //--- big nations don't ally with their biggest opponents ---//
507
508 int maxOverallRating=0;
509 int biggestOpponentNationRecno=0;
510
511 for( int i=nation_array.size() ; i>0 ; i-- )
512 {
513 if( nation_array.is_deleted(i) || i==nation_recno )
514 continue;
515
516 int overallRating = nation_array[i]->overall_rating;
517
518 if( overallRating > maxOverallRating )
519 {
520 maxOverallRating = overallRating;
521 biggestOpponentNationRecno = i;
522 }
523 }
524
525 if( biggestOpponentNationRecno == withNationRecno )
526 return 0;
527 }
528
529 //--- don't ally with nations with too low reputation ---//
530
531 return withNation->reputation >= MIN(20, reputation) - 20;
532 }
533 //------ End of function Nation::should_consider_friendly -----//
534
535
536 //----- Begin of function Nation::consider_alliance_rating -----//
537 //
538 // Return a rating from 0 to 100 for whether this nation should ally
539 // with the given nation.
540 //
consider_alliance_rating(int nationRecno)541 int Nation::consider_alliance_rating(int nationRecno)
542 {
543 Nation* nationPtr = nation_array[nationRecno];
544
545 //---- the current relation affect the alliance tendency ---//
546
547 NationRelation* nationRelation = get_relation(nationRecno);
548
549 int allianceRating = nationRelation->ai_relation_level-20;
550
551 //--- if the nation has a bad record of starting wars with us before, decrease the rating ---//
552
553 allianceRating -= nationRelation->started_war_on_us_count * 20;
554
555 //------ add the trade rating -------//
556
557 int tradeRating = trade_rating(nationRecno) + // existing trade amount
558 ai_trade_with_rating(nationRecno)/2; // possible trade
559
560 allianceRating += tradeRating;
561
562 //---- if the nation's power is larger than us, it's a plus ----//
563
564 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
565
566 if( powerRating > 0 )
567 allianceRating += powerRating;
568
569 return allianceRating;
570 }
571 //------ End of function Nation::consider_alliance_rating -----//
572
573
574 //----- Begin of function Nation::consider_take_tribute -----//
575 //
576 // talkMsg->talk_para1 - amount of the tribute.
577 //
consider_take_tribute(TalkMsg * talkMsg)578 int Nation::consider_take_tribute(TalkMsg* talkMsg)
579 {
580 int cashSignificance = 100 * talkMsg->talk_para1 / MAX(1000, (int) cash);
581
582 //--- It does not necessarily want the tribute ---//
583
584 int aiRelationLevel = get_relation(talkMsg->from_nation_recno)->ai_relation_level;
585
586 if( true_profit_365days() > 0 &&
587 cashSignificance < (100-aiRelationLevel)/5 )
588 {
589 return 0;
590 }
591
592 //----------- take the tribute ------------//
593
594 int relationChange = cashSignificance * (100+pref_cash_reserve) / 200;
595
596 change_ai_relation_level( talkMsg->from_nation_recno, relationChange );
597
598 return 1;
599 }
600 //------ End of function Nation::consider_take_tribute ------//
601
602
603 //----- Begin of function Nation::consider_take_aid -----//
604 //
605 // talkMsg->talk_para1 - amount of the tribute.
606 //
consider_take_aid(TalkMsg * talkMsg)607 int Nation::consider_take_aid(TalkMsg* talkMsg)
608 {
609 int cashSignificance = 100 * talkMsg->talk_para1 / MAX(1000, (int) cash);
610
611 //--- It does not necessarily want the tribute ---//
612
613 int aiRelationLevel = get_relation(talkMsg->from_nation_recno)->ai_relation_level;
614
615 if( true_profit_365days() > 0 &&
616 cashSignificance < (100-aiRelationLevel)/5 )
617 {
618 return 0;
619 }
620
621 //----------- take the tribute ------------//
622
623 int relationChange = cashSignificance * (100+pref_cash_reserve) / 200;
624
625 change_ai_relation_level( talkMsg->from_nation_recno, relationChange );
626
627 return 1;
628 }
629 //------ End of function Nation::consider_take_aid ------//
630
631
632 //-------- Begin of static function has_sent_same_msg --------//
633 //
634 // Whether the nation has already sent out a message that is
635 // the same as the one it received.
636 //
has_sent_same_msg(TalkMsg * talkMsgPtr)637 static int has_sent_same_msg(TalkMsg* talkMsgPtr)
638 {
639 TalkMsg talkMsg;
640
641 memcpy( &talkMsg, talkMsgPtr, sizeof(TalkMsg) );
642
643 talkMsg.from_nation_recno = talkMsg.to_nation_recno;
644 talkMsg.to_nation_recno = talkMsg.from_nation_recno;
645
646 return talk_res.is_talk_msg_exist(&talkMsg, 1); // 1-check talk_para1 & talk_para2
647 }
648 //------ End of static function has_sent_same_msg ------//
649
650
651 //----- Begin of function Nation::consider_take_tech -----//
652 //
653 // talkMsg->talk_para1 - id. of the technology.
654 // talkMsg->talk_para2 - level of the technology.
655 //
consider_take_tech(TalkMsg * talkMsg)656 int Nation::consider_take_tech(TalkMsg* talkMsg)
657 {
658 int ourTechLevel = tech_res[talkMsg->talk_para1]->get_nation_tech_level(nation_recno);
659
660 if( ourTechLevel >= talkMsg->talk_para2 )
661 return 0;
662
663 int relationChange = (talkMsg->talk_para2-ourTechLevel) * (15+pref_use_weapon/10);
664
665 change_ai_relation_level( talkMsg->from_nation_recno, relationChange );
666
667 return 1;
668 }
669 //------ End of function Nation::consider_take_tech ------//
670
671
672 //----- Begin of function Nation::surplus_supply_rating -----//
673 //
674 // Return a rating from 0 to 100 indicating how much surplus
675 // of supply this nation has in markets.
676 //
surplus_supply_rating()677 int Nation::surplus_supply_rating()
678 {
679 FirmMarket* firmMarket;
680 int stockQty, totalStockQty=0, totalStockSlot=0;
681
682 for( int i=ai_market_count-1; i>=0 ; i-- )
683 {
684 firmMarket = (FirmMarket*) firm_array[ ai_market_array[i] ];
685
686 err_when( firmMarket->firm_id != FIRM_MARKET );
687
688 MarketGoods* marketGoods = firmMarket->market_goods_array;
689
690 for( int j=0 ; j<MAX_MARKET_GOODS ; j++, marketGoods++ )
691 {
692 if( marketGoods->raw_id || marketGoods->product_raw_id )
693 {
694 stockQty = (int) marketGoods->stock_qty;
695
696 totalStockQty += stockQty;
697 totalStockSlot++;
698 }
699 }
700 }
701
702 if( totalStockSlot==0 )
703 return 0;
704
705 int avgStockQty = totalStockQty / totalStockSlot;
706
707 return 100 * avgStockQty / MAX_MARKET_STOCK;
708 }
709 //------ End of function Nation::surplus_supply_rating ------//
710
711
712 //----- Begin of function Nation::consider_give_aid -----//
713 //
714 // talkMsg->talk_para1 - amount of the tribute.
715 //
consider_give_aid(TalkMsg * talkMsg)716 int Nation::consider_give_aid(TalkMsg* talkMsg)
717 {
718 //-------- don't give tribute too frequently -------//
719
720 NationRelation* nationRelation = get_relation(talkMsg->from_nation_recno);
721
722 if( info.game_date <
723 nationRelation->last_talk_reject_date_array[TALK_GIVE_AID-1]
724 + 365 - pref_allying_tendency )
725 {
726 return 0;
727 }
728
729 //--------------------------------------------------//
730
731 int importanceRating = (int) nationRelation->good_relation_duration_rating;
732
733 if( nationRelation->status >= NATION_FRIENDLY &&
734 ai_should_spend( importanceRating, talkMsg->talk_para1 ) ) // 0-importance is 0
735 {
736 if( info.game_date > nationRelation->last_change_status_date
737 + 720 - pref_allying_tendency ) // we have allied with this nation for quite some while
738 {
739 nationRelation->last_talk_reject_date_array[TALK_GIVE_AID-1] = info.game_date;
740 return 1;
741 }
742 }
743
744 return 0;
745 }
746 //------ End of function Nation::consider_give_aid ------//
747
748
749 //----- Begin of function Nation::consider_give_tribute -----//
750 //
751 // talkMsg->talk_para1 - amount of the tribute.
752 //
consider_give_tribute(TalkMsg * talkMsg)753 int Nation::consider_give_tribute(TalkMsg* talkMsg)
754 {
755 //-------- don't give tribute too frequently -------//
756
757 NationRelation* nationRelation = get_relation(talkMsg->from_nation_recno);
758
759 if( info.game_date <
760 nationRelation->last_talk_reject_date_array[TALK_GIVE_TRIBUTE-1] + 365 - pref_allying_tendency )
761 {
762 return 0;
763 }
764
765 //---------------------------------------------//
766
767 int relationStatus = get_relation_status(talkMsg->from_nation_recno);
768 Nation* fromNation = nation_array[talkMsg->from_nation_recno];
769
770 if( true_profit_365days() < 0 ) // don't give tribute if we are losing money
771 return 0;
772
773 int reserveYears = 1 + 3 * pref_cash_reserve / 100; // 1 to 4 years
774
775 if( cash-talkMsg->talk_para1 < fixed_expense_365days() * reserveYears )
776 return 0;
777
778 int militaryDiff = fromNation->military_rank_rating() - military_rank_rating();
779
780 if( militaryDiff > 10+pref_military_courage/2 )
781 {
782 nationRelation->last_talk_reject_date_array[TALK_GIVE_TRIBUTE-1] = info.game_date;
783 return 1;
784 }
785
786 return 0;
787 }
788 //------ End of function Nation::consider_give_tribute ------//
789
790
791 //----- Begin of function Nation::consider_give_tech -----//
792 //
793 // Consider giving the latest level of the technology to the nation.
794 //
795 // talkMsg->talk_para1 - id. of the technology.
796 //
consider_give_tech(TalkMsg * talkMsg)797 int Nation::consider_give_tech(TalkMsg* talkMsg)
798 {
799 //-------- don't give tribute too frequently -------//
800
801 NationRelation* nationRelation = get_relation(talkMsg->from_nation_recno);
802
803 if( info.game_date <
804 nationRelation->last_talk_reject_date_array[TALK_GIVE_TECH-1] + 365 - pref_allying_tendency )
805 {
806 return 0;
807 }
808
809 //----------------------------------------------------//
810
811 int importanceRating = (int) nationRelation->good_relation_duration_rating;
812
813 if( nationRelation->status == NATION_ALLIANCE &&
814 importanceRating + pref_allying_tendency/10 > 30 )
815 {
816 nationRelation->last_talk_reject_date_array[TALK_GIVE_TECH-1] = info.game_date;
817 return 1;
818 }
819
820 return 0;
821 }
822 //------ End of function Nation::consider_give_tech ------//
823
824
825 //----- Begin of function Nation::consider_declare_war -----//
826 //
827 // Consider the request of declaring war on the target nation.
828 //
829 // talk_para1 - the recno nation to declare war with.
830 //
consider_declare_war(TalkMsg * talkMsg)831 int Nation::consider_declare_war(TalkMsg* talkMsg)
832 {
833 //--- if it even won't consider trade embargo, there is no reason that it will consider declaring war ---//
834
835 if( !consider_trade_embargo(talkMsg) )
836 return 0;
837
838 //---------------------------------------//
839
840 int fromRelationRating = ai_overall_relation_rating(talkMsg->from_nation_recno);
841 int againstRelationRating = ai_overall_relation_rating(talkMsg->talk_para1);
842
843 Nation* againstNation = nation_array[talkMsg->talk_para1];
844
845 NationRelation* fromRelation = get_relation(talkMsg->from_nation_recno);
846 NationRelation* againstRelation = get_relation(talkMsg->talk_para1);
847
848 //--- if we don't have a good enough relation with the requesting nation, turn down the request ---//
849
850 if( fromRelation->good_relation_duration_rating < 10 )
851 return 0;
852
853 //--- if we are more friendly with the against nation than the requesting nation, turn down the request ---//
854
855 if( againstRelation->good_relation_duration_rating >
856 fromRelation->good_relation_duration_rating )
857 {
858 return 0;
859 }
860
861 //--- if the nation is having a financial difficulty, it won't agree ---//
862
863 if( cash < 2000 * pref_cash_reserve / 100 )
864 return 0;
865
866 //--------------------------------------------//
867
868 int acceptRating = 100 + againstNation->total_enemy_military() -
869 military_rank_rating();
870
871 //--- it won't declare war with a friendly or allied nation easily ---//
872
873 if( againstRelation->status >= NATION_FRIENDLY ) // no need to handle NATION_ALLIANCE separately as ai_overall_relation_relation() has already taken it into account
874 acceptRating += 100;
875
876 return fromRelationRating - againstRelationRating > acceptRating;
877 }
878 //------ End of function Nation::consider_declare_war ------//
879
880
881 //----- Begin of function Nation::consider_trade_embargo -----//
882 //
consider_trade_embargo(TalkMsg * talkMsg)883 int Nation::consider_trade_embargo(TalkMsg* talkMsg)
884 {
885 int fromRelationRating = ai_overall_relation_rating(talkMsg->from_nation_recno);
886 int againstRelationRating = ai_overall_relation_rating(talkMsg->talk_para1);
887
888 NationRelation* fromRelation = get_relation(talkMsg->from_nation_recno);
889 NationRelation* againstRelation = get_relation(talkMsg->talk_para1);
890
891 //--- if we don't have a good enough relation with the requesting nation, turn down the request ---//
892
893 if( fromRelation->good_relation_duration_rating < 5 )
894 return 0;
895
896 //--- if we are more friendly with the against nation than the requesting nation, turn down the request ---//
897
898 if( againstRelation->good_relation_duration_rating >
899 fromRelation->good_relation_duration_rating )
900 {
901 return 0;
902 }
903
904 //--- if we have a large trade with the against nation or have a larger trade with the against nation than the requesting nation ---//
905
906 int fromTrade = trade_rating(talkMsg->from_nation_recno);
907 int againstTrade = trade_rating(talkMsg->talk_para1);
908
909 if( againstTrade > 40 ||
910 ( againstTrade > 10 && againstTrade - fromTrade > 15 ) )
911 {
912 return 0;
913 }
914
915 //--- if the nation is having a financial difficulty, it won't agree ---//
916
917 if( cash < 2000 * pref_cash_reserve / 100 )
918 return 0;
919
920 //--------------------------------------------//
921
922 int acceptRating = 75;
923
924 //--- it won't declare war with a friendly or allied nation easily ---//
925
926 if( againstRelation->status >= NATION_FRIENDLY ) // no need to handle NATION_ALLIANCE separately as ai_overall_relation_relation() has already taken it into account
927 acceptRating += 100;
928
929 return fromRelationRating - againstRelationRating > acceptRating;
930 }
931 //------ End of function Nation::consider_trade_embargo ------//
932
933
934 //----- Begin of function Nation::consider_military_aid -----//
935 //
consider_military_aid(TalkMsg * talkMsg)936 int Nation::consider_military_aid(TalkMsg* talkMsg)
937 {
938 Nation* fromNation = nation_array[talkMsg->from_nation_recno];
939 NationRelation* fromRelation = get_relation(talkMsg->from_nation_recno);
940
941 //----- don't aid too frequently ------//
942
943 if( info.game_date < fromRelation->last_military_aid_date + 200 - pref_allying_tendency )
944 return 0;
945
946 //------- only when the AI relation >= 60 --------//
947
948 if( fromRelation->ai_relation_level < 60 )
949 return 0;
950
951 //--- if the requesting nation is not at war now ----//
952
953 if( !fromNation->is_at_war() )
954 return 0;
955
956 //---- can't aid if we are at war ourselves -----//
957
958 if( is_at_war() )
959 return 0;
960
961 //--- if the nation is having a financial difficulty, it won't agree ---//
962
963 if( cash < 2000 * pref_cash_reserve / 100 )
964 return 0;
965
966 //----- can't aid if we are too weak ourselves ---//
967
968 if( ai_general_count*10 + total_human_count < 100-pref_military_courage/2 )
969 return 0;
970
971 //----- see what units are attacking the nation -----//
972
973 if( unit_array.is_deleted(fromNation->last_attacker_unit_recno) )
974 return 0;
975
976 Unit* unitPtr = unit_array[ fromNation->last_attacker_unit_recno ];
977
978 if( unitPtr->nation_recno == nation_recno ) // if it's our own units
979 return 0;
980
981 if( unitPtr->nation_recno == 0 )
982 return 0;
983
984 if( !unitPtr->is_visible() )
985 return 0;
986
987 //------ only attack if it's a common enemy to us and our ally -----//
988
989 if( get_relation(unitPtr->nation_recno)->status != NATION_HOSTILE )
990 return 0;
991
992 //------- calculate the combat level of the target units there ------//
993
994 int hasWar;
995
996 int targetCombatLevel = mobile_defense_combat_level( unitPtr->next_x_loc(), unitPtr->next_y_loc(),
997 unitPtr->nation_recno, 0, hasWar );
998
999 if( ai_attack_target(unitPtr->next_x_loc(), unitPtr->next_y_loc(), targetCombatLevel, 0, 1 ) ) //0-not defense mode, 1-just move to flag
1000 {
1001 fromRelation->last_military_aid_date = info.game_date;
1002 return 1;
1003 }
1004
1005 return 0;
1006 }
1007 //------ End of function Nation::consider_military_aid ------//
1008
1009
1010 //----- Begin of function Nation::consider_accept_surrender_request -----//
1011 //
1012 // Consider accepting the cash offer and sell the throne to another kingdom.
1013 //
1014 // talkMsg->talk_para1 - the amount offered.
1015 //
consider_accept_surrender_request(TalkMsg * talkMsg)1016 int Nation::consider_accept_surrender_request(TalkMsg* talkMsg)
1017 {
1018 Nation* nationPtr = nation_array[talkMsg->from_nation_recno];
1019 int offeredAmt = talkMsg->talk_para1 * 10; // *10 to restore its original value which has been divided by 10 to cope with <short> upper limit
1020
1021 //---- don't surrender to the player if the player is already the most powerful nation ---//
1022
1023 if( !nationPtr->is_ai() && config.ai_aggressiveness >= OPTION_HIGH )
1024 {
1025 if( nation_array.max_overall_nation_recno == nationPtr->nation_recno )
1026 return 0;
1027 }
1028
1029 //--- if we are running out of cash, ignore all normal thinking ---//
1030
1031 if( !(cash < 100 && profit_365days() < 0) )
1032 {
1033 //----- never surrender to a weaker nation ------//
1034
1035 if( nationPtr->overall_rank_rating() < overall_rank_rating() )
1036 return 0;
1037
1038 //------ don't surrender if we are still strong -----//
1039
1040 if( overall_rank_rating() > 30 + pref_peacefulness/4 ) // 30 to 55
1041 return 0;
1042
1043 //---- don't surrender if our cash is more than the amount they offered ----//
1044
1045 if( offeredAmt < cash * (75+pref_cash_reserve/2) / 100 ) // 75% to 125%
1046 return 0;
1047
1048 //-- if there are only two nations left, don't surrender if we still have some power --//
1049
1050 if( nation_array.nation_count == 2 )
1051 {
1052 if( overall_rank_rating() > 20 - 10 * pref_military_courage / 100 )
1053 return 0;
1054 }
1055 }
1056
1057 //-------------------------------------//
1058
1059 int surrenderToRating = ai_surrender_to_rating(talkMsg->from_nation_recno);
1060
1061 surrenderToRating += 100 * offeredAmt / 13000;
1062
1063 int acceptRating = overall_rank_rating()*13 + 100;
1064
1065 //------ AI aggressiveness effects -------//
1066
1067 switch( config.ai_aggressiveness )
1068 {
1069 case OPTION_HIGH:
1070 if( nationPtr->is_ai() ) // tend to accept AI kingdom offer easier
1071 acceptRating -= 75;
1072 else
1073 acceptRating += 75;
1074 break;
1075
1076 case OPTION_VERY_HIGH:
1077 if( nationPtr->is_ai() ) // tend to accept AI kingdom offer easier
1078 acceptRating -= 150;
1079 else
1080 acceptRating += 150;
1081 break;
1082 }
1083
1084 return surrenderToRating > acceptRating;
1085 }
1086 //------ End of function Nation::consider_accept_surrender_request ------//
1087
1088
1089 //----- Begin of function Nation::ai_overall_relation_rating -----//
1090 //
1091 // Return the overall relation rating of this nation with the
1092 // specific nation.
1093 //
ai_overall_relation_rating(int withNationRecno)1094 int Nation::ai_overall_relation_rating(int withNationRecno)
1095 {
1096 NationRelation* nationRelation = get_relation(withNationRecno);
1097 Nation* nationPtr = nation_array[withNationRecno];
1098
1099 int overallRating = nationRelation->ai_relation_level +
1100 (int) nationRelation->good_relation_duration_rating +
1101 (int) nationPtr->reputation +
1102 nationPtr->military_rank_rating() +
1103 trade_rating(withNationRecno) +
1104 ai_trade_with_rating(withNationRecno)/2 +
1105 nationPtr->total_alliance_military();
1106
1107 return overallRating;
1108 }
1109 //------ End of function Nation::ai_overall_relation_rating ------//
1110