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