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_GRAN.CPP
22 //Description: AI grand plans
23
24 #include <OCONFIG.h>
25 #include <OTALKRES.h>
26 #include <ORACERES.h>
27 #include <OREGIONS.h>
28 #include <OF_CAMP.h>
29 #include <ONATION.h>
30 #include <ConfigAdv.h>
31
32
33 //----- Begin of function Nation::think_grand_plan -----//
34 //
think_grand_plan()35 void Nation::think_grand_plan()
36 {
37 think_deal_with_all_enemy();
38
39 think_against_mine_monopoly();
40
41 think_ally_against_big_enemy();
42 }
43 //------ End of function Nation::think_grand_plan ------//
44
45
46 //----- Begin of function Nation::total_alliance_military -----//
47 //
48 // Return the total power of this nation and its friendly/allied
49 // nation.
50 //
total_alliance_military()51 int Nation::total_alliance_military()
52 {
53 int totalPower = military_rank_rating();
54
55 for( int i=nation_array.size() ; i>0 ; i-- )
56 {
57 if( nation_array.is_deleted(i) || i==nation_recno )
58 continue;
59
60 switch( get_relation_status(i) )
61 {
62 case NATION_ALLIANCE:
63 totalPower += nation_array[i]->military_rank_rating() * 3 / 4; // 75%
64 break;
65 /*
66 case NATION_FRIENDLY:
67 totalPower += nation_array[i]->military_rank_rating() / 2; //50%
68 break;
69 */
70 }
71 }
72
73 return totalPower;
74 }
75 //------ End of function Nation::total_alliance_military ------//
76
77
78 //----- Begin of function Nation::total_enemy_military -----//
79 //
80 // Return the total power of this nation's enemies and potential
81 // enemies.
82 //
total_enemy_military()83 int Nation::total_enemy_military()
84 {
85 Nation *nationPtr;
86 int totalPower=0, relationStatus;
87 // int relationStatus2, enemyRelationStatus;
88
89 for( int i=nation_array.size() ; i>0 ; i-- )
90 {
91 if( nation_array.is_deleted(i) || i==nation_recno )
92 continue;
93
94 nationPtr = nation_array[i];
95 relationStatus = get_relation_status(i);
96
97 if( relationStatus == NATION_HOSTILE )
98 {
99 totalPower += nationPtr->military_rank_rating();
100 }
101 /*
102 else
103 {
104 //--- check this nation's status with our enemies ---//
105
106 enemyRelationStatus = 0;
107
108 for( int j=nation_array.size() ; j>0 ; j-- )
109 {
110 if( nation_array.is_deleted(j) || j==nation_recno )
111 continue;
112
113 if( get_relation_status(j) != NATION_HOSTILE ) // only if this is one of our enemies.
114 continue;
115
116 //--- check if it is allied or friendly to any of our enemies ---//
117
118 relationStatus2 = nationPtr->get_relation_status(j);
119
120 if( relationStatus2 > enemyRelationStatus ) // Friendly will replace none, Alliance will replace Friendly
121 enemyRelationStatus = relationStatus2;
122 }
123
124 if( enemyRelationStatus == NATION_ALLIANCE )
125 totalPower += nationPtr->military_rank_rating() * 3 / 4; // 75%
126
127 else if( enemyRelationStatus == NATION_FRIENDLY )
128 totalPower += nationPtr->military_rank_rating() / 2; // 50%
129 }
130 */
131 }
132
133 return totalPower;
134 }
135 //------ End of function Nation::total_enemy_military ------//
136
137
138 //----- Begin of function Nation::total_enemy_count -----//
139 //
total_enemy_count()140 int Nation::total_enemy_count()
141 {
142 int totalEnemy=0;
143
144 for( int i=nation_array.size() ; i>0 ; i-- )
145 {
146 if( nation_array.is_deleted(i) || i==nation_recno )
147 continue;
148
149 if( get_relation_status(i) == NATION_HOSTILE )
150 totalEnemy++;
151 }
152
153 return totalEnemy;
154 }
155 //------ End of function Nation::total_enemy_count ------//
156
157
158 //----- Begin of function Nation::think_deal_with_all_enemy -----//
159 //
160 // Think about dealing with the enemy. The following are the
161 // actions a nation can take to deal with its enemies.
162 //
163 // >ask our allies to attack the enemy.
164 //
165 // >try to break the enemy's existing alliance/friendly treaty with other
166 // nations - to reduce its alliance strength.
167 //
168 // >convert enemy's allies to ours.
169 //
170 // >ask other nations to impose trade embargos on the enemy.
171 //
think_deal_with_all_enemy()172 void Nation::think_deal_with_all_enemy()
173 {
174 Nation* nationPtr;
175
176 int ourMilitary = military_rank_rating();
177 int enemyCount = total_enemy_count();
178
179 for( int i=1 ; i<=nation_array.size() ; i++ )
180 {
181 if( nation_array.is_deleted(i) || nation_recno == i )
182 continue;
183
184 if( get_relation_status(i) != NATION_HOSTILE )
185 continue;
186
187 nationPtr = nation_array[i];
188
189 //------- think about eliminating the enemy ------//
190
191 int rc = 0;
192
193 if( nationPtr->total_population==0 ) // the enemy has no towns left
194 rc = 1;
195
196 if( enemyCount==1 &&
197 ourMilitary > 100-pref_military_courage/5 ) // 80 to 100
198 {
199 int enemyMilitary = nationPtr->military_rank_rating();
200
201 if( enemyMilitary < 20 && ai_should_spend_war(enemyMilitary) )
202 rc = 1;
203 }
204
205 if( rc )
206 {
207 if( think_eliminate_enemy_firm(i) )
208 continue;
209
210 if( think_eliminate_enemy_town(i) )
211 continue;
212
213 think_eliminate_enemy_unit(i);
214 continue;
215 }
216
217 //----- think about dealing with the enemy with diplomacy -----//
218
219 think_deal_with_one_enemy(i);
220 }
221 }
222 //------ End of function Nation::think_deal_with_all_enemy ------//
223
224
225 //----- Begin of function Nation::think_deal_with_one_enemy -----//
226 //
think_deal_with_one_enemy(int enemyNationRecno)227 void Nation::think_deal_with_one_enemy(int enemyNationRecno)
228 {
229 Nation* nationPtr;
230 NationRelation* nationRelation;
231
232 for( int i=1 ; i<=nation_array.size() ; i++ )
233 {
234 if( nation_array.is_deleted(i) || nation_recno == i )
235 continue;
236
237 nationPtr = nation_array[i];
238
239 nationRelation = nationPtr->get_relation(nation_recno);
240
241 //--- if this nation is already allied to us, request it to declare war with the enemy ---//
242
243 if( nationRelation->status == NATION_ALLIANCE &&
244 nationPtr->get_relation_status(enemyNationRecno) != NATION_HOSTILE )
245 {
246 if( should_diplomacy_retry(TALK_REQUEST_DECLARE_WAR, i) )
247 {
248 talk_res.ai_send_talk_msg(i, nation_recno, TALK_REQUEST_DECLARE_WAR, enemyNationRecno);
249 continue;
250 }
251 }
252
253 //---- if this nation is not friendly or alliance to our enemy ----//
254
255 if( nationPtr->get_relation_status(enemyNationRecno) < NATION_FRIENDLY )
256 {
257 //--- and this nation is neutral or friendly with us ---//
258
259 if( nationRelation->status >= NATION_NEUTRAL &&
260 nationPtr->get_relation(enemyNationRecno)->trade_treaty )
261 {
262 //--- ask it to join a trade embargo on the enemy ---//
263
264 if( should_diplomacy_retry(TALK_REQUEST_TRADE_EMBARGO, i) )
265 talk_res.ai_send_talk_msg(i, nation_recno, TALK_REQUEST_TRADE_EMBARGO, enemyNationRecno );
266 }
267 }
268 else //---- if this nation is friendly or alliance to our enemy ----//
269 {
270 //----- and this nation is not at war with us -----//
271
272 if( nationRelation->status != NATION_HOSTILE )
273 {
274 //--- if we do not have trade treaty with this nation, propose one ---//
275
276 if( !nationRelation->trade_treaty )
277 {
278 if( should_diplomacy_retry(TALK_PROPOSE_TRADE_TREATY, i) )
279 talk_res.ai_send_talk_msg(i, nation_recno, TALK_PROPOSE_TRADE_TREATY );
280 }
281 else //--- if we already have a trade treaty with this nation ---//
282 {
283 // if this nation is already friendly to us, propose an alliance treaty now --//
284
285 if( nationRelation->status == NATION_FRIENDLY )
286 {
287 if( should_diplomacy_retry(TALK_PROPOSE_ALLIANCE_TREATY, i) )
288 talk_res.ai_send_talk_msg(i, nation_recno, TALK_PROPOSE_ALLIANCE_TREATY );
289 }
290
291 //-- if the nation has significiant trade with us, propose a friendly treaty now --//
292
293 else if( nationPtr->trade_rating(nation_recno) > 10 ||
294 nationPtr->ai_trade_with_rating(nation_recno) >= 50 ) // or if the product complement each other very well
295 {
296 if( should_diplomacy_retry(TALK_PROPOSE_FRIENDLY_TREATY, i) )
297 talk_res.ai_send_talk_msg(i, nation_recno, TALK_PROPOSE_FRIENDLY_TREATY );
298 }
299 }
300 }
301 }
302 }
303 }
304 //------ End of function Nation::think_deal_with_one_enemy ------//
305
306
307 //----- Begin of function Nation::think_surrender -----//
308 //
think_surrender()309 int Nation::think_surrender()
310 {
311 //--- don't surrender if the nation still has a town ---//
312
313 int rc=0;
314
315 if( total_population == 0 )
316 rc = 1;
317
318 if( cash <= 0 && income_365days()==0 )
319 rc = 1;
320
321 if( !rc )
322 return 0;
323
324 //---- see if there is any nation worth getting our surrender ---//
325
326 Nation* nationPtr;
327 int curRating, bestRating=0, bestNationRecno=0;
328
329 if( !king_unit_recno ) // if there is no successor to the king, the nation will tend more to surrender
330 bestRating = -100;
331
332 for( int i=nation_array.size() ; i>0 ; i-- )
333 {
334 if( nation_array.is_deleted(i) || i==nation_recno )
335 continue;
336
337 nationPtr = nation_array[i];
338
339 if( nationPtr->cash <= 300 ) // don't surrender to an economically handicapped nation
340 continue;
341
342 curRating = ai_surrender_to_rating(i);
343
344 //--- the nation will tend to surrender if there is only a small number of units left ---//
345
346 curRating += 50 - total_unit_count*5;
347
348 if( curRating > bestRating )
349 {
350 bestRating = curRating;
351 bestNationRecno = i;
352 }
353 }
354
355 //---------------------------------------//
356
357 if( bestNationRecno )
358 {
359 surrender(bestNationRecno);
360 return 1;
361 }
362
363 return 0;
364 }
365 //------ End of function Nation::think_surrender ------//
366
367
368 //----- Begin of function Nation::think_unite_against_big_enemy -----//
369 //
think_unite_against_big_enemy()370 int Nation::think_unite_against_big_enemy()
371 {
372 if( info.game_date - info.game_start_date <
373 365 * 3 * (100+pref_military_development) / 100 ) // only do this after 3 to 6 years into the game
374 {
375 return 0;
376 }
377
378 //-----------------------------------------------//
379
380 if( config.ai_aggressiveness < OPTION_HIGH )
381 return 0;
382
383 if( config.ai_aggressiveness == OPTION_HIGH )
384 {
385 if( misc.random(10)!=0 )
386 return 0;
387 }
388 else // OPTION_VERY_HIGH
389 {
390 if( misc.random(5)!=0 )
391 return 0;
392 }
393
394 //---------------------------------------//
395
396 int enemyNationRecno = nation_array.max_overall_nation_recno;
397
398 if( !enemyNationRecno )
399 return 0;
400
401 Nation* enemyNation = nation_array[enemyNationRecno];
402
403 //----- only against human players -----//
404
405 if( enemyNation->is_ai() )
406 return 0;
407
408 //---- find the overall rank rating of the second most powerful computer kingdom ---//
409
410 Nation* nationPtr;
411 int secondBestOverall=0, secondBestNationRecno=0;
412
413 for( int i=nation_array.size() ; i>0 ; i-- )
414 {
415 if( nation_array.is_deleted(i) || i==enemyNationRecno )
416 continue;
417
418 nationPtr = nation_array[i];
419
420 if( !nationPtr->is_ai() ) // don't count human players
421 continue;
422
423 if( nationPtr->overall_rank_rating() > secondBestOverall )
424 {
425 secondBestOverall = nationPtr->overall_rank_rating();
426 secondBestNationRecno = i;
427 }
428 }
429
430 if( !secondBestNationRecno || secondBestNationRecno==nation_recno )
431 return 0;
432
433 //------- don't surrender to hostile nation -------//
434
435 if( get_relation_status(secondBestNationRecno) < config_adv.nation_ai_unite_min_relation_level ) // defaults to NATION_NEUTRAL
436 return 0;
437
438 //--- if all AI kingdoms are way behind the human players, unite to against the human player ---//
439
440 int compareRating;
441
442 if( config.ai_aggressiveness == OPTION_HIGH )
443 compareRating = 50;
444 else // OPTION_VERY_AGGRESSIVE
445 compareRating = 80;
446
447 if( secondBestOverall < compareRating &&
448 secondBestNationRecno != nation_recno )
449 {
450 surrender(secondBestNationRecno);
451 return 1;
452 }
453
454 return 0;
455 }
456 //------ End of function Nation::think_unite_against_big_enemy ------//
457
458
459 //----- Begin of function Nation::ai_surrender_to_rating -----//
460 //
461 // return a rating on how much the nation will tend to surrender
462 // to the specific nation.
463 //
ai_surrender_to_rating(int nationRecno)464 int Nation::ai_surrender_to_rating(int nationRecno)
465 {
466 Nation* nationPtr = nation_array[nationRecno];
467 NationRelation* nationRelation = get_relation(nationRecno);
468
469 //--- higher tendency to surrender to a powerful nation ---//
470
471 int curRating = nationPtr->overall_rank_rating() - overall_rank_rating();
472
473 curRating += (nationRelation->ai_relation_level-40);
474
475 curRating += (int) nationRelation->good_relation_duration_rating*3;
476
477 curRating += (int) nationPtr->reputation/2;
478
479 //------ shouldn't surrender to an enemy --------//
480
481 if( nationRelation->status == NATION_HOSTILE )
482 curRating -= 100;
483
484 //--- if the race of the kings are the same, the chance is higher ---//
485
486 if( race_res.is_same_race( nationPtr->race_id, race_id ) )
487 curRating += 20;
488
489 return curRating;
490 }
491 //------ End of function Nation::ai_surrender_to_rating ------//
492
493
494 //----- Begin of function Nation::think_eliminate_enemy_town -----//
495 //
496 // This function is called to eliminate remaining enemy firms
497 // when all enemy towns have been destroyed.
498 //
think_eliminate_enemy_town(int enemyNationRecno)499 int Nation::think_eliminate_enemy_town(int enemyNationRecno)
500 {
501 //---- look for enemy firms to attack ----//
502
503 int hasWar;
504 Town *townPtr;
505
506 for( int i=town_array.size() ; i>0 ; i-- )
507 {
508 if( town_array.is_deleted(i) )
509 continue;
510
511 townPtr = town_array[i];
512
513 if( townPtr->nation_recno != enemyNationRecno )
514 continue;
515
516 //--- only attack if we have any base town in the enemy town's region ---//
517
518 if( base_town_count_in_region(townPtr->region_id)==0 )
519 continue;
520
521 //----- take into account of the mobile units around this town -----//
522
523 int mobileCombatLevel = mobile_defense_combat_level(townPtr->center_x, townPtr->center_y, townPtr->nation_recno, 1, hasWar);
524
525 if( mobileCombatLevel == -1 ) // do not attack this town because a battle is already going on
526 continue;
527
528 //---- calculate the combat level of this target town ----//
529
530 int townCombatLevel = townPtr->protection_available();
531
532 return ai_attack_target(townPtr->loc_x1, townPtr->loc_y1, mobileCombatLevel + townCombatLevel);
533 }
534
535 return 0;
536 }
537 //------ End of function Nation::think_eliminate_enemy_town ------//
538
539
540 //----- Begin of function Nation::think_eliminate_enemy_firm -----//
541 //
542 // This function is called to eliminate remaining enemy firms
543 // when all enemy towns have been destroyed.
544 //
think_eliminate_enemy_firm(int enemyNationRecno)545 int Nation::think_eliminate_enemy_firm(int enemyNationRecno)
546 {
547 //---- look for enemy firms to attack ----//
548
549 int hasWar;
550 Firm *firmPtr;
551
552 for( int i=firm_array.size() ; i>0 ; i-- )
553 {
554 if( firm_array.is_deleted(i) )
555 continue;
556
557 firmPtr = firm_array[i];
558
559 if( firmPtr->nation_recno != enemyNationRecno )
560 continue;
561
562 //--- only attack if we have any base town in the enemy firm's region ---//
563
564 if( base_town_count_in_region(firmPtr->region_id)==0 )
565 continue;
566
567 //----- take into account of the mobile units around this town -----//
568
569 int mobileCombatLevel = mobile_defense_combat_level(firmPtr->center_x, firmPtr->center_y, firmPtr->nation_recno, 1, hasWar);
570
571 if( mobileCombatLevel == -1 ) // do not attack this town because a battle is already going on
572 continue;
573
574 //---- calculate the combat level of this target firm ----//
575
576 int firmCombatLevel;
577
578 if( firmPtr->firm_id == FIRM_CAMP ) // other civilian firms
579 firmCombatLevel = ((FirmCamp*)firmPtr)->total_combat_level();
580 else
581 firmCombatLevel = firmPtr->worker_count * 10; // civilian firms have very low combat level
582
583 return ai_attack_target(firmPtr->loc_x1, firmPtr->loc_y1, mobileCombatLevel + firmCombatLevel);
584 }
585
586 return 0;
587 }
588 //------ End of function Nation::think_eliminate_enemy_firm ------//
589
590
591 //----- Begin of function Nation::think_eliminate_enemy_unit -----//
592 //
593 // This function is called to eliminate remaining enemy firms
594 // when all enemy towns have been destroyed.
595 //
think_eliminate_enemy_unit(int enemyNationRecno)596 int Nation::think_eliminate_enemy_unit(int enemyNationRecno)
597 {
598 Unit *unitPtr;
599 int hasWar;
600
601 for( int i=unit_array.size() ; i>0 ; i-- )
602 {
603 if( unit_array.is_deleted(i) )
604 continue;
605
606 unitPtr = unit_array[i];
607
608 if( unitPtr->nation_recno != enemyNationRecno )
609 continue;
610
611 if( !unitPtr->is_visible() || unitPtr->mobile_type != UNIT_LAND ) // only deal with land units now
612 continue;
613
614 //--- only attack if we have any base town in the enemy unit's region ---//
615
616 if( base_town_count_in_region(unitPtr->region_id()) == 0 )
617 continue;
618
619 //----- take into account of the mobile units around this town -----//
620
621 int mobileCombatLevel = mobile_defense_combat_level(unitPtr->next_x_loc(), unitPtr->next_y_loc(), unitPtr->nation_recno, 1, hasWar);
622
623 if( mobileCombatLevel == -1 ) // do not attack this town because a battle is already going on
624 continue;
625
626 return ai_attack_target(unitPtr->next_x_loc(), unitPtr->next_y_loc(), mobileCombatLevel + (int) unitPtr->unit_power());
627 }
628
629 return 0;
630 }
631 //------ End of function Nation::think_eliminate_enemy_unit ------//
632
633
634 //----- Begin of function Nation::think_ally_against_big_enemy -----//
635 //
636 // Think about allying against a big enemy
637 //
think_ally_against_big_enemy()638 int Nation::think_ally_against_big_enemy()
639 {
640 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
641 return 0;
642
643 //---------------------------------------//
644
645 int enemyNationRecno = nation_array.max_overall_nation_recno;
646
647 if( enemyNationRecno == nation_recno )
648 return 0;
649
650 //-- if AI aggressiveness > high, only deal against the player, but not other kingdoms ---//
651
652 if( config.ai_aggressiveness >= OPTION_HIGH )
653 {
654 if( nation_array[enemyNationRecno]->is_ai() )
655 return 0;
656 }
657
658 //-- if AI aggressiveness is low, don't do this against the human player --//
659
660 else if( config.ai_aggressiveness == OPTION_LOW )
661 {
662 if( !nation_array[enemyNationRecno]->is_ai() )
663 return 0;
664 }
665
666 //--- increase the ai_relation_level towards other nations except the enemy so we can ally against the enemy ---//
667
668 Nation* enemyNation = nation_array[enemyNationRecno];
669 int incRelationLevel = (100-overall_rank_rating())/10;
670
671 int i;
672 for( i=nation_array.size() ; i>0 ; i-- )
673 {
674 if( nation_array.is_deleted(i) )
675 continue;
676
677 if( i==nation_recno || i==enemyNationRecno )
678 continue;
679
680 int thisIncLevel = incRelationLevel * (100-get_relation(i)->ai_relation_level) / 100;
681
682 change_ai_relation_level( i, thisIncLevel );
683 }
684
685 //---- don't have all nations doing it the same time ----//
686
687 if( misc.random(nation_array.ai_nation_count)==0 )
688 return 0;
689
690 //---- if the trade rating is high, stay war-less with it ----//
691
692 if( trade_rating(enemyNationRecno) +
693 ai_trade_with_rating(enemyNationRecno) > 100 - pref_trading_tendency/3 )
694 {
695 return 0;
696 }
697
698 //---- if the nation relation level is still high, then request aid/tribute ----//
699
700 NationRelation* nationRelation = get_relation(enemyNationRecno);
701
702 if( nationRelation->ai_relation_level > 30 )
703 {
704 int talkId;
705
706 if( nationRelation->status >= NATION_FRIENDLY )
707 talkId = TALK_DEMAND_AID;
708 else
709 talkId = TALK_DEMAND_TRIBUTE;
710
711 if( should_diplomacy_retry(talkId, enemyNationRecno) )
712 {
713 static short aidAmountArray[] = { 500, 1000, 2000 };
714
715 int aidAmount = aidAmountArray[misc.random(3)];
716
717 talk_res.ai_send_talk_msg(enemyNationRecno, nation_recno, talkId, aidAmount);
718 }
719
720 return 0;
721 }
722
723 //-------------------------------------//
724
725 Nation* nationPtr;
726
727 NationRelation *ourNationRelation, *enemyNationRelation;
728
729 for( i=nation_array.size() ; i>0 ; i-- )
730 {
731 if( nation_array.is_deleted(i) )
732 continue;
733
734 if( i==nation_recno || i==enemyNationRecno )
735 continue;
736
737 nationPtr = nation_array[i];
738
739 ourNationRelation = get_relation(i);
740 enemyNationRelation = enemyNation->get_relation(i);
741
742 }
743
744 return 0;
745 }
746 //------ End of function Nation::think_ally_against_big_enemy ------//
747
748
749 //----- Begin of function Nation::ai_should_attack_friendly -----//
750 //
751 // This function returns whether this nation should attack
752 // the given friendly nation.
753 //
754 // <int> friendlyNationRecno - the nation recno of the friendly nation.
755 // <int> attackTemptation - a rating from 0 to 100 indicating
756 // temptation of attacking the target.
757 //
ai_should_attack_friendly(int friendlyNationRecno,int attackTemptation)758 int Nation::ai_should_attack_friendly(int friendlyNationRecno, int attackTemptation)
759 {
760 Nation *friendlyNation = nation_array[friendlyNationRecno];
761 NationRelation *nationRelation = get_relation(friendlyNationRecno);
762
763 //--- don't change terminate treaty too soon ---//
764
765 if( info.game_date < nationRelation->last_change_status_date+60+pref_honesty/2 ) // only after 60 to 110 days
766 return 0;
767
768 //------------------------------------------------//
769
770 int resistanceRating = friendlyNation->military_rank_rating()
771 - military_rank_rating();
772
773 resistanceRating += nationRelation->ai_relation_level - 50;
774
775 resistanceRating += trade_rating(friendlyNationRecno);
776
777 return attackTemptation > resistanceRating;
778 }
779 //------ End of function Nation::ai_should_attack_friendly ------//
780
781
782 //----- Begin of function Nation::ai_end_treaty -----//
783 //
784 // Terminate the treaty with the given nation.
785 //
786 // <int> nationRecno - the nation to terminate treaty with.
787 //
ai_end_treaty(int nationRecno)788 void Nation::ai_end_treaty(int nationRecno)
789 {
790 NationRelation *nationRelation = get_relation(nationRecno);
791
792 err_when( nationRelation->status < NATION_FRIENDLY );
793
794 if( nationRelation->status == NATION_FRIENDLY )
795 {
796 talk_res.ai_send_talk_msg(nationRecno, nation_recno, TALK_END_FRIENDLY_TREATY, 0, 0, 1); // 1-force send
797 }
798 else if( nationRelation->status == NATION_ALLIANCE )
799 {
800 talk_res.ai_send_talk_msg(nationRecno, nation_recno, TALK_END_ALLIANCE_TREATY, 0, 0, 1);
801 }
802
803 err_when( nationRelation->status >= NATION_FRIENDLY ); // when the status is still friendly or alliance
804 }
805 //------ End of function Nation::ai_end_treaty ------//
806
807
808 //----- Begin of function Nation::ai_has_enough_food -----//
809 //
810 // return whether this nation has enough food or not.
811 //
ai_has_enough_food()812 int Nation::ai_has_enough_food()
813 {
814 return food > 2000 + 2000 * pref_food_reserve / 100
815 || yearly_food_change() > 0;
816 }
817 //------ End of function Nation::ai_has_enough_food ------//
818
819
820 //----- Begin of function Nation::think_attack_enemy_firm -----//
821 //
822 // Think about attacking a specific type of firm of a specific enemy.
823 //
think_attack_enemy_firm(int enemyNationRecno,int firmId)824 int Nation::think_attack_enemy_firm(int enemyNationRecno, int firmId)
825 {
826 if( !largest_town_recno )
827 return 0;
828
829 Town* ourLargestTown = town_array[largest_town_recno];
830 Nation *nationPtr = nation_array[enemyNationRecno];
831 Firm *firmPtr, *targetFirm=NULL;
832 int curRating, bestRating=0, targetCombatLevel, hasWar;
833
834 for( int i=firm_array.size() ; i>0 ; i-- )
835 {
836 if( firm_array.is_deleted(i) )
837 continue;
838
839 firmPtr = firm_array[i];
840
841 if( firmPtr->firm_id != firmId ||
842 firmPtr->nation_recno != enemyNationRecno )
843 {
844 continue;
845 }
846
847 int combatLevel = enemy_firm_combat_level(firmPtr, 1, hasWar);
848
849 if( combatLevel==0 ) // no protection with this mine
850 {
851 targetFirm = firmPtr;
852 targetCombatLevel = combatLevel;
853 break;
854 }
855
856 curRating = world.distance_rating( firmPtr->center_x, firmPtr->center_y,
857 ourLargestTown->center_x, ourLargestTown->center_y );
858
859 curRating += 1000 - combatLevel/5;
860
861 if( curRating > bestRating )
862 {
863 bestRating = curRating;
864 targetFirm = firmPtr;
865 targetCombatLevel = combatLevel;
866 }
867 }
868
869 if( !targetFirm )
870 return 0;
871
872 //---------------------------------------------//
873
874 int useAllCamp=1;
875
876 return ai_attack_target( targetFirm->loc_x1, targetFirm->loc_y1,
877 targetCombatLevel, 0, 0, 0, 0, useAllCamp );
878 }
879 //------ End of function Nation::think_attack_enemy_firm ------//
880
881
882 //----- Begin of function Nation::think_against_mine_monopoly -----//
883 //
think_against_mine_monopoly()884 int Nation::think_against_mine_monopoly()
885 {
886 //-- only think this after the game has been running for at least one year --//
887
888 if( config.ai_aggressiveness < OPTION_HIGH ) // only attack if aggressiveness >= high
889 return 0;
890
891 if( info.game_date - info.game_start_date > 365 )
892 return 0;
893
894 if( profit_365days() > 0 ) // if we are making a profit, don't attack
895 return 0;
896
897 //-- for high aggressiveness, it will check cash before attack, for very high aggressiveness, it won't check cash before attack ---//
898
899 if( config.ai_aggressiveness < OPTION_VERY_HIGH ) // only attack if aggressiveness >= high
900 {
901 if( cash > 2000 + 1000 * pref_cash_reserve / 100 ) // only attack if we run short of cash
902 return 0;
903 }
904
905 //--------------------------------------------------------//
906
907 if( !largest_town_recno )
908 return 0;
909
910 //--------------------------------------------------//
911
912 int baseRegionId = town_array[largest_town_recno]->region_id;
913
914 // no region stat (region is too small), don't care
915 if( !region_array[baseRegionId]->region_stat_id )
916 return 0;
917
918 RegionStat* regionStat = region_array.get_region_stat(baseRegionId);
919
920 //---- if we already have a mine in this region ----//
921
922 if( regionStat->mine_nation_count_array[nation_recno-1] > 0 )
923 return 0;
924
925 //----- if there is no mine in this region -----//
926
927 if( regionStat->raw_count == 0 )
928 return 0;
929
930 //----- if enemies have occupied all mines -----//
931
932 int mineCount, totalMineCount=0;
933 int curRating, bestRating=0, targetNationRecno=0;
934
935 int i;
936 for( i=nation_array.size() ; i>0 ; i-- )
937 {
938 if( nation_array.is_deleted(i) )
939 continue;
940
941 //------ only deal with human players ------//
942
943 if( nation_array[i]->is_ai() || i==nation_recno )
944 continue;
945
946 //------------------------------------------//
947
948 mineCount = regionStat->mine_nation_count_array[i-1];
949 totalMineCount += mineCount;
950
951 curRating = mineCount * 100
952 - get_relation(i)->ai_relation_level
953 - trade_rating(i);
954
955 if( curRating > bestRating )
956 {
957 bestRating = curRating;
958 targetNationRecno = i;
959 }
960 }
961
962 if( !targetNationRecno )
963 return 0;
964
965 //--- if the relationship with this nation is still good, don't attack yet, ask for aid first ---//
966
967 NationRelation* nationRelation = get_relation(targetNationRecno);
968
969 if( nationRelation->ai_relation_level > 30 )
970 {
971 int talkId;
972
973 if( nationRelation->status >= NATION_FRIENDLY )
974 talkId = TALK_DEMAND_AID;
975 else
976 talkId = TALK_DEMAND_TRIBUTE;
977
978 if( should_diplomacy_retry(talkId, targetNationRecno) )
979 {
980 static short aidAmountArray[] = { 500, 1000, 2000 };
981
982 int aidAmount = aidAmountArray[misc.random(3)];
983
984 talk_res.ai_send_talk_msg(targetNationRecno, nation_recno, talkId, aidAmount);
985 }
986
987 return 0;
988 }
989
990 //------- attack one of the target enemy's mines -------//
991
992 Firm* firmPtr;
993
994 for( i=firm_array.size() ; i>0 ; i-- )
995 {
996 if( firm_array.is_deleted(i) )
997 continue;
998
999 firmPtr = firm_array[i];
1000
1001 if( firmPtr->firm_id != FIRM_MINE ||
1002 firmPtr->nation_recno != targetNationRecno ||
1003 firmPtr->region_id != baseRegionId )
1004 {
1005 continue;
1006 }
1007
1008 //--------------------------------------------//
1009
1010 int hasWar;
1011 int targetCombatLevel = enemy_firm_combat_level(firmPtr, 1, hasWar);
1012
1013 return ai_attack_target( firmPtr->loc_x1, firmPtr->loc_y1,
1014 targetCombatLevel, 0, 0, 0, 0, 1 ); // 1-use all camps
1015 }
1016
1017 return 0;
1018 }
1019 //------ End of function Nation::think_against_mine_monopoly ------//
1020
1021