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    : ONATION.CPP
22 //Description : Object Nation - part 1
23 
24 #include <OSTR.h>
25 #include <OSYS.h>
26 #include <ODATE.h>
27 #include <OBOX.h>
28 #include <OVGA.h>
29 #include <OFONT.h>
30 #include <ONEWS.h>
31 #include <OWORLD.h>
32 #include <OFIRM.h>
33 #include <OGAME.h>
34 #include <OPOWER.h>
35 #include <OREGIONS.h>
36 #include <ORACERES.h>
37 #include <OTALKRES.h>
38 #include <OMONSRES.h>
39 #include <OGODRES.h>
40 #include <OTOWN.h>
41 #include <OSPY.h>
42 #include <OF_MARK.h>
43 #include <OF_BASE.h>
44 #include <OF_MONS.h>
45 #include <OTECHRES.h>
46 #include <ONATION.h>
47 #include <OREBEL.h>
48 #include <OREMOTE.h>
49 #include <ConfigAdv.h>
50 #include "gettext.h"
51 
52 //-------- Define static variables --------//
53 
54 const char* NationRelation::relation_status_str_array[5] =
55 {
56 	N_("War"),
57 	N_("Tense"),
58 	N_("Neutral"),
59 	N_("Friendly"),
60 	N_("Alliance")
61 };
62 
63 const char* NationRelation::duration_of_status_str_array[5] =
64 {
65 	N_("Duration of War Status"),
66 	N_("Duration of Tense Status"),
67 	N_("Duration of Neutral Status"),
68 	N_("Duration of Friendly Status"),
69 	N_("Duration of Alliance Status")
70 };
71 
72 //--------- Define static functions -------//
73 
74 static int succeed_king_loyalty_change(int thisRaceId, int newKingRaceId, int oldKingRaceId);
75 
76 //--------- Begin of function NationBase::Nation --------//
77 
NationBase()78 NationBase::NationBase()
79 {
80 	memset( this, 0, sizeof(NationBase) );
81 }
82 //---------- End of function NationBase::Nation --------//
83 
84 
85 //--------- Begin of function NationBase::~Nation --------//
86 
~NationBase()87 NationBase::~NationBase()
88 {
89 #ifdef DEBUG
90 
91 	err_when( nation_recno );		// deinit() must be called first before this destructor is called
92 
93 	for( int i=0 ; i<MAX_RACE ; i++ )
94 		err_when( base_count_array[i] > 0 );		// it should be all zeros
95 
96 #endif
97 }
98 //---------- End of function NationBase::~Nation --------//
99 
100 
101 //--------- Begin of function NationBase::init --------//
102 //
103 // This function will be called directly by
104 //
105 // <int>   nationType    = the nation type (NATION_???)
106 // <int>   raceId      	 = id. of the race
107 // <int>	  colorSchemeId = color scheme id. of the nation
108 // [DWORD] playerId      = an unique player id. (for multiplayer game)
109 //
init(int nationType,int raceId,int colorSchemeId,uint32_t playerId)110 void NationBase::init(int nationType, int raceId, int colorSchemeId, uint32_t playerId)
111 {
112 	//------------- set vars ---------------//
113 
114 	nation_type  	 = nationType;
115 	race_id 	    	 = raceId;
116 	color_scheme_id = colorSchemeId;
117 	player_id    	 = playerId;
118 
119 	colorSchemeId	 = MIN( colorSchemeId, MAX_COLOR_SCHEME );
120 	nation_color	 = game.color_remap_array[colorSchemeId].main_color;
121 
122 	last_war_date   = info.game_date;
123 
124 	//------- if this is the local player's nation -------//
125 
126 	if( nation_type==NATION_OWN )
127 		nation_array.player_recno = nation_recno;
128 
129 	//---------- init game vars ------------//
130 
131 	static int start_up_cash_array[] = { 4000, 7000, 12000, 20000 };
132 
133 	if( is_ai() )
134 		cash = (float) start_up_cash_array[config.ai_start_up_cash-1];
135 	else
136 		cash = (float) start_up_cash_array[config.start_up_cash-1];
137 
138 	food = (float) 5000;			// startup food is 5000 for all nations in all settings
139 
140 	//---- initialize this nation's relation on other nations ----//
141 
142 	// #### Richard 6-12-2013: Moved this from init_relation to here, so it works with new independent nations spawning #### //
143 	is_allied_with_player = 0;
144 
145 	for( int i=nation_array.size() ; i>0 ; i-- )
146 	{
147 		if( nation_array.is_deleted(i) )
148 			continue;
149 
150 		init_relation(i);
151 		nation_array[i]->init_relation(nation_recno);
152 	}
153 
154 	//--------- init technology ----------//
155 
156 	tech_res.init_nation_tech(nation_recno);
157 
158 	//------- reset all god knowledge --------//
159 
160 	god_res.init_nation_know(nation_recno);
161 
162 	//### begin alex 23/9 ###//
163 	if(remote.is_enable() && nation_recno && !is_ai() && misc.is_file_exist("TECHGOD.SYS"))
164 	{
165 		tech_res.inc_all_tech_level(nation_recno);
166 		tech_res.inc_all_tech_level(nation_recno);
167 		tech_res.inc_all_tech_level(nation_recno);
168 		god_res.enable_know_all(nation_recno);
169 	}
170 	//#### end alex 23/9 ####//
171 	else
172 	{
173 		if( config_adv.nation_start_god_level == 1 )
174 		{
175 			god_res[race_id]->enable_know(nation_recno);
176 		}
177 		else if( config_adv.nation_start_god_level > 1 )
178 		{
179 			god_res.enable_know_all(nation_recno);
180 		}
181 
182 		for( int i=0; i<config_adv.nation_start_tech_inc_all_level; i++)
183 			tech_res.inc_all_tech_level(nation_recno);
184 	}
185 }
186 //----------- End of function NationBase::init ---------//
187 
188 
189 //--------- Begin of function NationBase::deinit --------//
190 //
191 // When a nation is to be deleted, NationBase::deinit() must
192 // be called first from nation_array before calling its
193 // destructor as when it deinitalizes units, some functions
194 // will need to access the nation_array[].
195 //
deinit()196 void NationBase::deinit()
197 {
198 	if( nation_recno==0 )		// has been deinitialized
199 		return;
200 
201 	//---- delete all talk messages to/from this nation ----//
202 
203 	talk_res.del_all_nation_msg(nation_recno);
204 
205 	//------- close down all firms --------//
206 
207 	close_all_firm();
208 
209 	//---- neutralize all towns belong to this nation ----//
210 
211 	Town* townPtr;
212 
213 	int i;
214 	for( i=town_array.size() ; i>0 ; i-- )
215 	{
216 		if( town_array.is_deleted(i) )
217 			continue;
218 
219 		townPtr = town_array[i];
220 
221 		if( townPtr->nation_recno == nation_recno )
222 			townPtr->set_nation(0);
223 	}
224 
225 	//------------- deinit our spies -------------//
226 
227 	for( i=spy_array.size() ; i>0 ; i-- )
228 	{
229 		if( spy_array.is_deleted(i) )
230 			continue;
231 
232 		Spy* spyPtr = spy_array[i];
233 
234 		//-----------------------------------------------------//
235 		// Convert all of spies of this nation to normal units,
236 		// so there  will be no more spies of this nation.
237 		//-----------------------------------------------------//
238 
239 		if( spyPtr->true_nation_recno == nation_recno )		// drop spy identities of spies in towns, firms and mobile ones
240 			spyPtr->drop_spy_identity();
241 
242 		//-----------------------------------------------------//
243 		// For spies of other nation cloaked as this nation,
244 		// their will uncover their cloak and change back
245 		// to their original nation.
246 		//-----------------------------------------------------//
247 
248 		else if( spyPtr->cloaked_nation_recno == nation_recno )
249 			spyPtr->change_cloaked_nation(spyPtr->true_nation_recno);
250 
251 		err_when( spyPtr->true_nation_recno == nation_recno ||		// there should be no more spies associated with this nation
252 				    spyPtr->cloaked_nation_recno == nation_recno );
253 	}
254 
255 	//----- deinit all units belonging to this nation -----//
256 
257 	deinit_all_unit();
258 
259 	//-------- if the viewing nation is this nation -------//
260 
261 	if( !sys.signal_exit_flag )
262 	{
263 		if( info.default_viewing_nation_recno == nation_recno )
264 		{
265 			info.default_viewing_nation_recno = nation_array.player_recno;
266 			sys.set_view_mode(MODE_NORMAL);
267 		}
268 
269 		else if( info.viewing_nation_recno == nation_recno )
270 			sys.set_view_mode(MODE_NORMAL); 		// it will set viewing_nation_recno to default_viewing_nation_recno
271 
272 		// ##### begin Gilbert 22/10 #######//
273 		// if deleting own nation, darken view mode buttons
274 		if( nation_recno == nation_array.player_recno )
275 		{
276 			sys.disp_view_mode(1);
277 		}
278 		// ##### end Gilbert 22/10 #######//
279 	}
280 
281 	nation_recno = 0;
282 }
283 //----------- End of function NationBase::deinit ---------//
284 
285 
286 //--------- Begin of function NationBase::init_relation --------//
287 //
288 // Initialize the relation vars with the given nation.
289 //
290 // <int> relationNationRecno - recno of the NationRelation to set.
291 //
init_relation(int relationNationRecno)292 void NationBase::init_relation(int relationNationRecno)
293 {
294 	NationRelation* nationRelation = relation_array+relationNationRecno-1;
295 
296 	memset( nationRelation, 0, sizeof(NationRelation) );
297 
298 	set_relation_should_attack(relationNationRecno, relationNationRecno!=nation_recno, COMMAND_AUTO);
299 
300 	if( is_ai() && nation_array[relationNationRecno]->is_ai() )		// AI has contact with each other in the beginning of the game.
301 		nationRelation->has_contact = 1;
302 	else
303 		nationRelation->has_contact = relationNationRecno==nation_recno || config.explore_whole_map;              // if the map is blackened out, no contact in the beginning
304 
305 	nationRelation->trade_treaty = relationNationRecno==nation_recno;
306 
307 	nationRelation->status       		 = NATION_NEUTRAL;
308 	nationRelation->ai_relation_level = NATION_NEUTRAL * RELATION_LEVEL_PER_STATUS;
309 	nationRelation->last_change_status_date = info.game_date;
310 
311 	if( relationNationRecno == nation_recno )		// own nation
312 		relation_status_array[relationNationRecno-1] = NATION_ALLIANCE;		// for facilitating searching
313 	else
314 		relation_status_array[relationNationRecno-1] = NATION_NEUTRAL;
315 
316 	set_relation_passable(relationNationRecno, NATION_FRIENDLY);
317 }
318 //----------- End of function NationBase::init_relation ---------//
319 
320 
321 //--------- Begin of function NationBase::close_all_firm --------//
322 //
323 // Close down all firms under this nation.
324 //
close_all_firm()325 void NationBase::close_all_firm()
326 {
327 	int i;
328 
329 	for( i=firm_array.size() ; i>0 ; i-- )
330 	{
331 		if( !firm_array.is_deleted(i) &&
332 			 firm_array[i]->nation_recno == nation_recno )
333 		{
334 			firm_array.del_firm(i);
335 		}
336 	}
337 }
338 //----------- End of function NationBase::close_all_firm ---------//
339 
340 
341 //--------- Begin of function NationBase::deinit_all_unit --------//
342 //
343 // Deinit all units belonging to this nation when this nation is deinitialized.
344 //
deinit_all_unit()345 void NationBase::deinit_all_unit()
346 {
347 	//--- update total_human_unit so the numbers will be correct ---//
348 
349 	#ifndef DEBUG  		// only do this in release version to on-fly fix bug
350 	nation_array.update_statistic();
351 	#endif
352 
353 	//--------------------------------------//
354 
355 	int   i;
356 	Unit* unitPtr;
357 
358 	for( i=unit_array.size() ; i>0 ; i-- )
359 	{
360 		if( unit_array.is_deleted(i) )
361 		{
362 			unitPtr = (Unit*) unit_array.get_ptr(i);		// this unit is dying, so is_deleted() return 1;
363 
364 			if( !unitPtr )
365 				continue;
366 
367 			if( unitPtr->nation_recno == nation_recno )
368 				unit_array.del(i);
369 
370 			continue;
371 		}
372 
373 		//--------------------------------------------//
374 
375 		unitPtr = unit_array[i];
376 
377 		if( unitPtr->nation_recno != nation_recno )
378 			 continue;
379 
380 		//----- only human units will betray -----//
381 
382 		if( unitPtr->race_id )
383 		{
384 			unitPtr->loyalty = 0;		// force it to detray
385 
386 			if( unitPtr->think_betray() )
387 				continue;
388 		}
389 
390 		//--- if the unit has not changed nation, the unit will disappear ---//
391 
392 		if( unit_array.get_ptr(i) )
393 			unit_array.del(i);
394 	}
395 
396 	//------------ debug code -------------//
397 
398 	for( i=unit_array.size() ; i>0 ; i-- )
399 	{
400 		if( unit_array.is_deleted(i) )
401 			continue;
402 
403 		unitPtr = unit_array[i];
404 
405 		err_when( unitPtr->nation_recno == nation_recno );		// they should have been all deleted.
406 	}
407 }
408 //----------- End of function NationBase::deinit_all_unit ---------//
409 
410 
411 //--------- Begin of function NationBase::hand_over_to --------//
412 //
413 // <int> handoverNationRecno - hand over the entire nation to this nation.
414 //
hand_over_to(int handoverNationRecno)415 void NationBase::hand_over_to(int handoverNationRecno)
416 {
417 	rebel_array.stop_attack_nation(nation_recno);
418 	town_array.stop_attack_nation(nation_recno);
419 	unit_array.stop_all_war(nation_recno);
420 	monster_res.stop_attack_nation(nation_recno);
421 
422 	nation_hand_over_flag = nation_recno;
423 
424 	//--- hand over units (should hand over units first as you cannot change a firm's nation without changing the nation of the overseer there ---//
425 
426 	Unit* unitPtr;
427 
428 	int i;
429 	for( i=unit_array.size() ; i>0 ; i-- )
430 	{
431 		if( unit_array.is_deleted(i) )
432 		{
433 			//-- If the unit is dying and isn't truly deleted yet, delete it now --//
434 
435 			if( !unit_array.is_truly_deleted(i) &&
436 				 unit_array[i]->nation_recno == nation_recno )
437 			{
438 				unit_array.die(i);
439 			}
440 
441 			continue;
442 		}
443 
444 		//---------------------------------------//
445 
446 		unitPtr = unit_array[i];
447 
448 		if( unitPtr->nation_recno != nation_recno )
449 			continue;
450 
451 		//----- if it is a god, resign it -------//
452 
453 		if( god_res.is_god_unit(unitPtr->unit_id) )
454 		{
455 			unitPtr->resign(COMMAND_AUTO);
456 			continue;
457 		}
458 
459 		//----- if it is a spy cloaked as this nation -------//
460 		//
461 		// If the unit is a overseer of a Camp or Base,
462 		// the Camp or Base will change nation as a result.
463 		//
464 		//---------------------------------------------------//
465 
466 		if( unitPtr->spy_recno )
467 			unitPtr->spy_change_nation(handoverNationRecno, COMMAND_AUTO);
468 		else
469 			unitPtr->change_nation(handoverNationRecno);
470 	}
471 
472 	//------- hand over firms ---------//
473 
474 	for( i=firm_array.size() ; i>0 ; i-- )
475 	{
476 		if( !firm_array.is_deleted(i) &&
477 			 firm_array[i]->nation_recno == nation_recno )
478 		{
479 			firm_array[i]->change_nation(handoverNationRecno);
480 		}
481 	}
482 
483 	//------- hand over towns ---------//
484 
485 	for( i=town_array.size() ; i>0 ; i-- )
486 	{
487 		if( !town_array.is_deleted(i) &&
488 			 town_array[i]->nation_recno == nation_recno )
489 		{
490 			town_array[i]->set_nation(handoverNationRecno);
491 		}
492 	}
493 
494 	//-------------------------------------------------//
495 	//
496 	// For the spies of this nation cloaked into other nations,
497 	// we need to update their true_nation_recno.
498 	//
499 	//-------------------------------------------------//
500 
501 	Spy* spyPtr;
502 
503 	for( i=spy_array.size() ; i>0 ; i-- )
504 	{
505 		if( spy_array.is_deleted(i) )
506 			continue;
507 
508 		spyPtr = spy_array[i];
509 
510 		err_when( spyPtr->cloaked_nation_recno == nation_recno );		// there should be no units in this nation after the above deinitialization
511 
512 		if( spyPtr->true_nation_recno == nation_recno )
513 			spyPtr->change_true_nation(handoverNationRecno);
514 	}
515 
516 	//------- delete this nation from nation_array -------//
517 
518 	nation_array.del_nation(nation_recno);
519 	nation_hand_over_flag = 0;
520 }
521 //----------- End of function NationBase::hand_over_to ---------//
522 
523 
524 //--------- Begin of function NationBase::set_king --------//
525 //
526 // Set the king unit recno.
527 //
528 // <int> kingUnitRecno - unit recno of the king
529 // <int> firstKing - whether this is the first king of the nation.
530 //
set_king(int kingUnitRecno,int firstKing)531 void NationBase::set_king(int kingUnitRecno, int firstKing)
532 {
533 	king_unit_recno = kingUnitRecno;
534 
535 	Unit* kingUnit = unit_array[king_unit_recno];
536 
537 	//--- if this unit currently has not have leadership ---//
538 
539 	if( kingUnit->skill.skill_id != SKILL_LEADING )
540 	{
541 		kingUnit->skill.skill_id = SKILL_LEADING;
542 		kingUnit->skill.skill_level = 0;
543 	}
544 
545 	kingUnit->set_rank(RANK_KING);
546 	kingUnit->stop2(); 		// clear the existing order, as there might be an assigning to firm/town order. But kings cannot be assigned to towns or firms as workers.
547 
548 	//---------- king related vars ----------//
549 
550 	if( nation_type == NATION_AI || !firstKing )		// for succession, no longer use the original player name
551 		nation_name_id = kingUnit->name_id;
552 	else
553 		nation_name_id = -nation_recno;   // for human players, the name is retrieved from NationArray::human_name_array
554 
555 	race_id 			 = kingUnit->race_id;
556 	king_leadership = kingUnit->skill.skill_level;
557 
558 	err_when( !nation_name_id );
559 	err_when( !race_id );
560 }
561 //----------- End of function NationBase::set_king ---------//
562 
563 
564 //--------- Begin of function NationBase::nation_name --------//
565 //
nation_name()566 char* NationBase::nation_name()
567 {
568 	// TRANSLATORS: <Name>'s Kingdom
569 	snprintf( nation_name_str, NATION_NAME_LEN+1, _("%s's Kingdom"), king_name(1) );
570 
571 	return nation_name_str;		// each name needs to have its own var as multiple nation names will be displayed at the same time in diplomatic talk choices
572 }
573 //----------- End of function NationBase::nation_name ---------//
574 
575 
576 //--------- Begin of function NationBase::king_name --------//
577 //
578 // [int] firstWordOnly - whether only get the first word of the name.
579 //								 (default: 0)
580 //
king_name(int firstWordOnly)581 const char* NationBase::king_name(int firstWordOnly)
582 {
583 	if( nation_name_id < 0 )		// human player custom names
584 	{
585 		return nation_array.get_human_name(nation_name_id, firstWordOnly);
586 	}
587 	else
588 	{
589 		if( firstWordOnly )
590 			return race_res[race_id]->get_single_name( static_cast<uint16_t>(nation_name_id) );
591 		else
592 			return race_res[race_id]->get_name( static_cast<uint16_t>(nation_name_id) );
593 	}
594 }
595 //----------- End of function NationBase::king_name ---------//
596 
597 
598 //------- Begin of function NationBase::cash_str ------//
599 //
600 // Return a text string with the current nation treasure and profit
601 // in the past 30 days.
602 //
cash_str()603 char* NationBase::cash_str()
604 {
605 	static String str;
606 
607 	if( cash >= 0 )
608 	{
609 		str = misc.format( (int)cash, 4 );			// format type 4 - no thousand separators
610 	}
611 	else
612 	{
613 		str  = "-";
614 		str += misc.format( (int)-cash, 4 );		// format type 4 - no thousand separators
615 	}
616 
617 	//--------------------------------------//
618 
619 	int curProfit = (int) profit_365days();
620 
621 	if( curProfit )
622 	{
623 		str += " (";
624 
625 		if( curProfit > 0 )
626 			str += "+";
627 		else
628 			str += "-";
629 
630 		str += misc.format( abs(curProfit), 4 ); 	// format type 4 - no thousand separators
631 		str += ")";
632 	}
633 
634 	return str;
635 }
636 //------- End of function NationBase::cash_str -------//
637 
638 
639 //------- Begin of function NationBase::food_str ------//
640 //
641 // Return a text string with the current nation treasure and profit
642 // in the past 30 days.
643 //
food_str()644 char* NationBase::food_str()
645 {
646 	static String str;
647 
648 	if( food >= 0 )
649 	{
650 		str = misc.format( (int)food, 4 );			// format type 4 - no thousand separators
651 	}
652 	else
653 	{
654 		str  = "-";
655 		str += misc.format( (int)-food, 4 );		// format type 4 - no thousand separators
656 	}
657 
658 	//--------------------------------------//
659 
660 	int foodChange = (int) food_change_365days();
661 
662 	if( foodChange )
663 	{
664 		str += " (";
665 
666 		if( foodChange > 0 )
667 			str += "+";
668 		else
669 			str += "-";
670 
671 		str += misc.format( abs(foodChange), 4 ); 	// format type 4 - no thousand separators
672 		str += ")";
673 	}
674 
675 	return str;
676 }
677 //------- End of function NationBase::food_str -------//
678 
679 
680 //---------- Begin of function NationBase::next_day --------//
681 //
682 // This function is called every day.
683 //
next_day()684 void NationBase::next_day()
685 {
686 	//------ post is at war flag -------/
687 
688 	if( is_at_war_today )
689 		last_war_date = info.game_date;
690 
691 	is_at_war_yesterday = is_at_war_today;
692 	is_at_war_today	  = 0;
693 
694 	//--- if the king is dead, and now looking for a successor ---//
695 
696 	if( !king_unit_recno )
697 	{
698 		if( info.game_date%3 == nation_recno%3 )		// decrease 1 loyalty point every 3 days
699 			change_all_people_loyalty(-1);
700 	}
701 
702 	//---------- debug code ------------//
703 
704 #ifdef DEBUG
705 	//---------- check king -----------//
706 
707 	if( king_unit_recno )
708 	{
709 		Unit* unitPtr = unit_array[king_unit_recno];
710 
711 		err_when( unitPtr->rank_id != RANK_KING );
712 		err_when( unitPtr->nation_recno != nation_recno );
713 	}
714 
715 	//---------- check relation -----------//
716 
717 	err_when( get_relation_status(nation_recno) != NATION_ALLIANCE );		// relation to own nation must be alliance
718 
719 #endif
720 
721 	//------ check if this nation has won the game -----//
722 
723 	check_win();
724 
725 	//-- if the player still hasn't selected a unit to succeed the died king, declare defeated if the all units are killed --//
726 
727 	if( !king_unit_recno )
728 		check_lose();
729 
730 	//---------- debug code --------------//
731 /*
732 	#ifdef DEBUG
733 
734 	int totalHumanCount=0;
735 
736 	for( int i=unit_array.size() ; i>0 ; i-- )
737 	{
738 		Unit* unitPtr = (Unit*) unit_array.get_ptr(i);
739 
740 		if( unitPtr &&
741 			 unitPtr->nation_recno == nation_recno &&
742 			 unitPtr->race_id &&
743 			 unitPtr->rank_id != RANK_KING )
744 		{
745 			totalHumanCount++;
746 		}
747 	}
748 
749 	for( i=firm_array.size() ; i>0 ; i-- )
750 	{
751 		if( firm_array.is_deleted(i) )
752 			continue;
753 
754 		Firm* firmPtr = firm_array[i];
755 
756 		if( firmPtr->nation_recno != nation_recno )
757 			continue;
758 
759 		if( firmPtr->firm_id == FIRM_CAMP ||
760 			 firmPtr->firm_id == FIRM_BASE )
761 		{
762 			totalHumanCount += firmPtr->worker_count;
763 		}
764 	}
765 
766 	err_when( total_human_count != totalHumanCount );
767 
768 	#endif
769 */
770 }
771 //----------- End of function NationBase::next_day ---------//
772 
773 
774 //---------- Begin of function NationBase::next_month --------//
775 //
776 // This function is called every month.
777 //
next_month()778 void NationBase::next_month()
779 {
780 	//--------------------------------------------------//
781 	// When the two nations, whose relationship is Tense,
782 	// do not have new conflicts for 3 years, their
783 	// relationship automatically becomes Neutral.
784 	//--------------------------------------------------//
785 
786 	NationRelation* nationRelation;
787 
788 	for( int i=1 ; i<=nation_array.size() ; i++ )
789 	{
790 		if( nation_array.is_deleted(i) )
791 			continue;
792 
793 		nationRelation = get_relation(i);
794 
795 		if( nationRelation->status == NATION_TENSE &&
796 			 info.game_date >= nationRelation->last_change_status_date + 365*3 )
797 		{
798 			set_relation_status(i, NATION_NEUTRAL);
799 		}
800 
801 		//--- update good_relation_duration_rating ---//
802 
803 		else if( nationRelation->status == NATION_FRIENDLY )
804 			nationRelation->good_relation_duration_rating += (float) 0.2;		// this is the monthly increase
805 
806 		else if( nationRelation->status == NATION_ALLIANCE )
807 			nationRelation->good_relation_duration_rating += (float) 0.4;
808 	}
809 
810 	//----- increase reputation gradually -----//
811 
812 	if( reputation < 100 )
813 		change_reputation((float)0.5);
814 }
815 //---------- End of function NationBase::next_month --------//
816 
817 
818 //---------- Begin of function NationBase::next_year --------//
819 //
820 // This function is called every year
821 //
next_year()822 void NationBase::next_year()
823 {
824 	//------ post financial data --------//
825 
826 	last_year_income = cur_year_income;
827 	cur_year_income  = (float) 0;
828 
829 	last_year_expense = cur_year_expense;
830 	cur_year_expense  = (float) 0;
831 
832 	last_year_fixed_income = cur_year_fixed_income;
833 	cur_year_fixed_income  = (float) 0;
834 
835 	last_year_fixed_expense = cur_year_fixed_expense;
836 	cur_year_fixed_expense  = (float) 0;
837 
838 	last_year_profit = cur_year_profit;
839 	cur_year_profit  = (float) 0;
840 
841 	last_year_cheat = cur_year_cheat;
842 	cur_year_cheat  = (float) 0;
843 
844 	//------ post income & expense breakdown ------//
845 
846 	int i;
847 	for( i=0 ; i<INCOME_TYPE_COUNT ; i++ )
848 	{
849 		last_year_income_array[i] = cur_year_income_array[i];
850 		cur_year_income_array[i]  = (float) 0;
851 	}
852 
853 	for( i=0 ; i<EXPENSE_TYPE_COUNT ; i++ )
854 	{
855 		last_year_expense_array[i] = cur_year_expense_array[i];
856 		cur_year_expense_array[i]  = (float) 0;
857 	}
858 
859 	//------ post good change data ------//
860 
861 	last_year_food_in = cur_year_food_in;
862 	cur_year_food_in  = (float) 0;
863 
864 	last_year_food_out = cur_year_food_out;
865 	cur_year_food_out  = (float) 0;
866 
867 	last_year_food_change = cur_year_food_change;
868 	cur_year_food_change  = (float) 0;
869 
870 	//---------- post imports ----------//
871 
872 	NationRelation* nationRelation = relation_array;
873 
874 	for( i=0; i<MAX_NATION ; i++, nationRelation++ )
875 	{
876 		for( int j=0 ; j<IMPORT_TYPE_COUNT ; j++ )
877 		{
878 			nationRelation->last_year_import[j] = nationRelation->cur_year_import[j];
879 			nationRelation->cur_year_import[j] = (float) 0;
880 		}
881 	}
882 
883 	//--------- post reputation ----------//
884 
885 	last_year_reputation_change = cur_year_reputation_change;
886 	cur_year_reputation_change  = (float) 0;
887 }
888 //---------- End of function NationBase::next_year --------//
889 
890 
891 //---------- Begin of function NationBase::add_income --------//
892 //
893 // <int>   incomeType  - the income type
894 // <float> incomeAmt   - the amount of the income.
895 // [int]   fixedIncome - whether this is a fixed income, or
896 //								 a variable income. (default: 0)
897 //
add_income(int incomeType,float incomeAmt,int fixedIncome)898 void NationBase::add_income(int incomeType, float incomeAmt, int fixedIncome)
899 {
900 	err_when( incomeType < 0 || incomeType >= INCOME_TYPE_COUNT );
901 
902 	cash += incomeAmt;
903 
904 	cur_year_income_array[incomeType] += incomeAmt;
905 
906 	cur_year_income += incomeAmt;
907 	cur_year_profit += incomeAmt;
908 
909 	if( fixedIncome )
910 		cur_year_fixed_income += incomeAmt;
911 }
912 //---------- End of function NationBase::add_income --------//
913 
914 
915 //---------- Begin of function NationBase::add_expense --------//
916 //
917 // <int>   expenseType  - the expense type
918 // <float> incomeAmt    - the amount of the income.
919 // <int>   fixedExpense - whether this is a fixed expense, or
920 //								  a variable income. (default: 0)
921 //
add_expense(int expenseType,float expenseAmt,int fixedExpense)922 void NationBase::add_expense(int expenseType, float expenseAmt, int fixedExpense)
923 {
924 	err_when( expenseType < 0 || expenseType >= EXPENSE_TYPE_COUNT );
925 
926 	cash -= expenseAmt;
927 
928 	cur_year_expense_array[expenseType] += expenseAmt;
929 
930 	cur_year_expense += expenseAmt;
931 	cur_year_profit  -= expenseAmt;
932 
933 	if( fixedExpense )
934 		cur_year_fixed_expense += expenseAmt;
935 }
936 //---------- End of function NationBase::add_expense --------//
937 
938 
939 //---------- Begin of function NationBase::add_cheat --------//
940 //
941 // <float> cheatAmount - the cheating amount.
942 //
add_cheat(float cheatAmount)943 void NationBase::add_cheat(float cheatAmount)
944 {
945 	if( sys.testing_session || nation_type == NATION_OWN )
946 	{
947 		add_income(INCOME_CHEAT, cheatAmount);
948 	}
949 	else		// cheat less obviously, randomly add to one of the account at a random amount //
950 	{
951 		add_income( misc.random(INCOME_TYPE_COUNT-1)+1, cheatAmount );
952 
953 		cur_year_cheat += cheatAmount;
954 	}
955 }
956 //---------- End of function NationBase::add_cheat --------//
957 
958 
959 //---------- Begin of function NationBase::import_goods --------//
960 //
961 // This function is called when the current nation imports
962 // goods from a specific nation.
963 //
964 // <int> importType - type of goods imported.
965 //
966 // <int> importNationRecno - recno of the nation from which this
967 //								     nation imports.
968 //
969 // <float> importAmt 		- the import amount
970 //
import_goods(int importType,int importNationRecno,float importAmt)971 void NationBase::import_goods(int importType, int importNationRecno, float importAmt)
972 {
973 	if( importNationRecno == nation_recno )
974 		return;
975 
976 	NationRelation* nationRelation = get_relation(importNationRecno);
977 
978 	nationRelation->cur_year_import[importType]   += importAmt;
979 	nationRelation->cur_year_import[IMPORT_TOTAL] += importAmt;
980 
981 	add_expense(EXPENSE_IMPORTS, importAmt, 1);
982 	nation_array[importNationRecno]->add_income(INCOME_EXPORTS, importAmt, 1);
983 }
984 //---------- End of function NationBase::import_goods --------//
985 
986 
987 //---------- Begin of function NationBase::add_food --------//
988 //
989 // <float> foodToAdd - quantity of food to be added
990 //
add_food(float foodToAdd)991 void NationBase::add_food(float foodToAdd)
992 {
993 	food += foodToAdd;
994 
995 	cur_year_food_in     += foodToAdd;
996 	cur_year_food_change += foodToAdd;
997 }
998 //----------- End of function NationBase::add_food ---------//
999 
1000 
1001 //---------- Begin of function NationBase::consume_food --------//
1002 //
1003 // <float> foodConsumed - quantity of food consumed
1004 //
consume_food(float foodConsumed)1005 void NationBase::consume_food(float foodConsumed)
1006 {
1007 	food -= foodConsumed;
1008 
1009 	cur_year_food_out    += foodConsumed;
1010 	cur_year_food_change -= foodConsumed;
1011 }
1012 //----------- End of function NationBase::consume_food ---------//
1013 
1014 
1015 //---------- Begin of function NationBase::change_reputation --------//
1016 //
1017 // <float> changeLevel - level of reputation to be changed.
1018 //
change_reputation(float changeLevel)1019 void NationBase::change_reputation(float changeLevel)
1020 {
1021 	//--- reputation increase more slowly when it is close to 100 ----//
1022 
1023 	if( changeLevel > 0 && reputation > 0 )
1024 		changeLevel = changeLevel * (150-reputation) / 150;
1025 
1026 	//-----------------------------------------------//
1027 
1028 	reputation += changeLevel;
1029 
1030 	if( reputation > 100 )
1031 		reputation = (float) 100;
1032 
1033 	if( reputation < -100 )
1034 		reputation = (float) -100;
1035 
1036 	//------ update cur_year_reputation_change ------//
1037 
1038 	cur_year_reputation_change += changeLevel;
1039 }
1040 //---------- End of function NationBase::change_reputation --------//
1041 
1042 
1043 //---------- Begin of function NationBase::change_ai_relation_level --------//
1044 //
1045 // Change this AI nation's subjectively relation levels towards the others,
1046 // the opposite nation's relation level is not the same as this.
1047 //
1048 // ai_relation_level is for AI only and will only be reviewed by AI functions.
1049 //
1050 // <short> nationRecno   - the nation recno of the relation
1051 // <int>   levelChange   - the amount of change to the relation level
1052 //
change_ai_relation_level(short nationRecno,int levelChange)1053 void NationBase::change_ai_relation_level(short nationRecno, int levelChange)
1054 {
1055 	NationRelation* nationRelation = get_relation(nationRecno);
1056 
1057 	int newLevel = nationRelation->ai_relation_level + levelChange;
1058 
1059 	newLevel = MIN(newLevel, 100);
1060 	newLevel = MAX(newLevel, 0  );
1061 
1062 	nationRelation->ai_relation_level = newLevel;
1063 }
1064 //----------- End of function NationBase::change_ai_relation_level -----------//
1065 
1066 
1067 //---------- Begin of function NationBase::set_relation_status --------//
1068 //
1069 // <short> nationRecno   - the nation recno of the relation
1070 // <char>  newStatus     - the new relationship status
1071 // [char]  recursiveCall - whether this is a recursive call from itself
1072 //                      	(default: 0)
1073 //
set_relation_status(short nationRecno,char newStatus,char recursiveCall)1074 void NationBase::set_relation_status(short nationRecno, char newStatus, char recursiveCall)
1075 {
1076 	if( nationRecno == nation_recno ) 		// cannot set relation to itself
1077 		return;
1078 
1079 	NationRelation* nationRelation = get_relation(nationRecno);
1080 
1081 	//--------- debug code --------// BUGHERE
1082 /*
1083 	#ifdef DEBUG
1084 	if( nation_array[nationRecno]->is_ai() && is_ai() )	// AI must terminate the treaty first before declaring war
1085 	{
1086 		err_when( nationRelation->status >= NATION_FRIENDLY &&
1087 					 newStatus == NATION_HOSTILE );
1088 	}
1089 	#endif
1090 */
1091 	//-------------------------------------------------//
1092 	//
1093 	// When two nations agree to a cease-fire, there may
1094 	// still be some bullets on their ways, and those
1095 	// will set the status back to War status, so we need
1096 	// the following code to handle this case.
1097 	//
1098 	//-------------------------------------------------//
1099 
1100 	if( !recursiveCall &&
1101 		 nationRelation->status == NATION_TENSE &&
1102 		 newStatus == NATION_HOSTILE &&
1103 		 info.game_date < nationRelation->last_change_status_date + 5 )		// 5 days after the cease-fire, the nation will remain cease-fire
1104 	{
1105 		return;
1106 	}
1107 
1108 	//-------------------------------------------------//
1109 	//
1110 	// If the nation cease fire or form a friendly/alliance
1111 	// treaty with a nation. And this nation current
1112 	// has plan to attack that nation, then cancel the plan.
1113 	//
1114 	//-------------------------------------------------//
1115 
1116 	if( is_ai() )
1117 	{
1118 		if( newStatus==NATION_TENSE ||		// cease fire
1119 			 newStatus>=NATION_FRIENDLY )		// new friendly/alliance treaty
1120 		{
1121 			if( ((Nation*)this)->ai_attack_target_nation_recno == nationRecno )
1122 				((Nation*)this)->reset_ai_attack_target();
1123 		}
1124 	}
1125 
1126 	//------------------------------------------------//
1127 
1128 	relation_status_array[nationRecno-1] = newStatus;
1129 	nationRelation->status = newStatus;
1130 	nationRelation->last_change_status_date = info.game_date;
1131 
1132 	int newRelationLevel = newStatus * RELATION_LEVEL_PER_STATUS;
1133 
1134 	if( newRelationLevel < nationRelation->ai_relation_level )		// only set it when the new value is lower than the current value
1135 		nationRelation->ai_relation_level = newRelationLevel;
1136 
1137 	set_relation_passable(nationRecno, NATION_FRIENDLY);
1138 
1139 	//---------- set should_attack -------//
1140 
1141 	if( newStatus==NATION_ALLIANCE || newStatus==NATION_FRIENDLY ||
1142 		 newStatus==NATION_TENSE )
1143 	{
1144 		set_relation_should_attack(nationRecno, 0, COMMAND_AUTO);
1145 	}
1146 	else if( newStatus==NATION_HOSTILE )
1147 	{
1148 		set_relation_should_attack(nationRecno, 1, COMMAND_AUTO);
1149 	}
1150 
1151 	//----- share the nation contact with each other -----//
1152 /*
1153 		// these segment code will cause multiplayer sync problem
1154 
1155 	if( newStatus == NATION_ALLIANCE )
1156 	{
1157 		Nation* withNation = nation_array[nationRecno];
1158 
1159 		for( i=nation_array.size() ; i>0 ; i-- )
1160 		{
1161 			if( i==nation_recno || i==nationRecno )
1162 				continue;
1163 
1164 			if( nation_array.is_deleted(i) )
1165 				continue;
1166 
1167 			//-- if we have contact with this nation and our ally doesn't, share the contact with it --//
1168 
1169 			if( get_relation(i)->has_contact &&
1170 				 withNation->get_relation(i)->has_contact==0 )
1171 			{
1172 				withNation->establish_contact(i);
1173 			}
1174 		}
1175 	}
1176 */
1177 	//--- if this is a call from a client function, not a recursive call ---//
1178 
1179 	if( !recursiveCall )
1180 	{
1181 		nation_array[nationRecno]->set_relation_status(nation_recno, newStatus, 1);
1182 
1183 		//-- auto terminate their trade treaty if two nations go into a war --//
1184 
1185 		if( newStatus == NATION_HOSTILE )
1186 			set_trade_treaty(nationRecno, 0);
1187 	}
1188 }
1189 //----------- End of function NationBase::set_relation_status -----------//
1190 
1191 
1192 //---------- Begin of function NationBase::get_relation_status --------//
1193 
get_relation_status(short nationRecno)1194 char NationBase::get_relation_status(short nationRecno)
1195 {
1196 	return relation_status_array[nationRecno-1];
1197 }
1198 //----------- End of function NationBase::get_relation_status -----------//
1199 
1200 
1201 //---------- Begin of function NationBase::set_relation_passable --------//
1202 
set_relation_passable(short nationRecno,char status)1203 void NationBase::set_relation_passable(short nationRecno, char status)
1204 {
1205 	relation_passable_array[nationRecno-1] = (relation_status_array[nationRecno-1] >= status);
1206 }
1207 //----------- End of function NationBase::set_relation_passable -----------//
1208 
1209 
1210 //---------- Begin of function NationBase::get_relation_passable --------//
1211 
get_relation_passable(short nationRecno)1212 char NationBase::get_relation_passable(short nationRecno)
1213 {
1214 	return relation_passable_array[nationRecno-1];
1215 }
1216 //----------- End of function NationBase::get_relation_passable -----------//
1217 
1218 #ifdef DEBUG
1219 
1220 //---------- Begin of function NationBase::get_relation --------//
1221 //
get_relation(int nationRecno)1222 NationRelation* NationBase::get_relation(int nationRecno)
1223 {
1224 	if( nationRecno<1 || nationRecno>MAX_NATION )
1225 		err.run( "NationBase::get_relation()" );
1226 
1227 	return relation_array+nationRecno-1;
1228 }
1229 //---------- End of function NationBase::get_relation --------//
1230 
1231 #endif
1232 
1233 //---------- Begin of function NationBase::set_relation_should_attack --------//
1234 
set_relation_should_attack(short nationRecno,char newValue,char remoteAction)1235 void NationBase::set_relation_should_attack(short nationRecno, char newValue, char remoteAction)
1236 {
1237 	if( !remoteAction && remote.is_enable() )
1238 	{
1239 		short *shortPtr = (short *) remote.new_send_queue_msg(MSG_NATION_SET_SHOULD_ATTACK, 3*sizeof(short));
1240 		*shortPtr = nation_recno;
1241 		shortPtr[1] = nationRecno;
1242 		shortPtr[2] = newValue;
1243 	}
1244 	else
1245 	{
1246 		relation_should_attack_array[nationRecno-1] = newValue;
1247 		get_relation(nationRecno)->should_attack    = newValue;
1248 	}
1249 }
1250 //---------- End of function NationBase::set_relation_should_attack --------//
1251 
1252 
1253 //---------- Begin of function NationBase::get_relation_should_attack --------//
1254 
get_relation_should_attack(short nationRecno)1255 char NationBase::get_relation_should_attack(short nationRecno)
1256 {
1257 	// ###### begin Gilbert 3/9 #######//
1258 	// always can attack independent unit
1259 	return nationRecno == 0 || relation_should_attack_array[nationRecno-1];
1260 	// ###### end Gilbert 3/9 #######//
1261 }
1262 //---------- End of function NationBase::get_relation_should_attack --------//
1263 
1264 
1265 //------- Begin of function NationBase::form_friendly_treaty ------//
1266 //
1267 // <int> nationRecno - recno of the nation with which this nation
1268 //							  will form treaty.
1269 //
form_friendly_treaty(int nationRecno)1270 void NationBase::form_friendly_treaty(int nationRecno)
1271 {
1272 	err_when( nationRecno == nation_recno );
1273 	err_when( nation_array.is_deleted(nationRecno) );
1274 
1275 	set_relation_status(nationRecno, NATION_FRIENDLY);
1276 }
1277 //------- End of function NationBase::form_friendly_treaty -------//
1278 
1279 
1280 //------- Begin of function NationBase::form_alliance_treaty ------//
1281 //
1282 // <int> nationRecno - recno of the nation with which this nation
1283 //							  will form treaty.
1284 //
form_alliance_treaty(int nationRecno)1285 void NationBase::form_alliance_treaty(int nationRecno)
1286 {
1287 	err_when( nationRecno == nation_recno );
1288 	err_when( nation_array.is_deleted(nationRecno) );
1289 
1290 	set_relation_status(nationRecno, NATION_ALLIANCE);
1291 
1292 	//--- allied nations are oblied to trade with each other ---//
1293 
1294 	set_trade_treaty(nationRecno, 1);
1295 
1296 	//------ set is_allied_with_player -------//
1297 
1298 	if( nationRecno == nation_array.player_recno )
1299 		is_allied_with_player = 1;
1300 
1301 	if( nation_recno == nation_array.player_recno )
1302 		nation_array[nationRecno]->is_allied_with_player = 1;
1303 }
1304 //------- End of function NationBase::form_alliance_treaty -------//
1305 
1306 
1307 //------- Begin of function NationBase::end_treaty ------//
1308 //
1309 // <int> withNationRecno - recno of the nation which ends treaty
1310 //							  			  with this nation. If it's an alliance treaty,
1311 //							  			  allied nations with break treaty with
1312 //							  			  this nation.
1313 //
1314 // <int> newStatus - the new status after breaking the treaty.
1315 //
end_treaty(int withNationRecno,int newStatus)1316 void NationBase::end_treaty(int withNationRecno,int newStatus)
1317 {
1318 	//----- decrease reputation when terminating a treaty -----//
1319 
1320 	Nation* withNation = nation_array[withNationRecno];
1321 
1322 	if( withNation->reputation > 0 )
1323 	{
1324 		int curStatus = get_relation_status(withNationRecno);
1325 
1326 		if( curStatus == TALK_END_FRIENDLY_TREATY )
1327 			change_reputation( -withNation->reputation * 10 / 100 );
1328 		else
1329 			change_reputation( -withNation->reputation * 20 / 100 );
1330 	}
1331 
1332 	//------- reset good_relation_duration_rating -----//
1333 
1334 	if( newStatus <= NATION_NEUTRAL )
1335 	{
1336 		get_relation(withNationRecno)->good_relation_duration_rating = (float) 0;
1337 		withNation->get_relation(nation_recno)->good_relation_duration_rating = (float) 0;
1338 	}
1339 
1340 	//------- set new relation status --------//
1341 
1342 	set_relation_status(withNationRecno, newStatus);
1343 
1344 	//------ set is_allied_with_player -------//
1345 
1346 	if( withNationRecno == nation_array.player_recno )
1347 		is_allied_with_player = 0;
1348 
1349 	if( nation_recno == nation_array.player_recno )
1350 		nation_array[withNationRecno]->is_allied_with_player = 0;
1351 }
1352 //------- End of function NationBase::end_treaty -------//
1353 
1354 
1355 //------- Begin of function NationBase::set_trade_treaty ------//
1356 //
1357 // <int> nationRecno - recno of the nation to change the trade allow flag
1358 //
set_trade_treaty(int nationRecno,char treatyFlag)1359 void NationBase::set_trade_treaty(int nationRecno, char treatyFlag)
1360 {
1361 	err_when( nation_recno==nationRecno );		// cannot set trade treaty with oneself
1362 
1363 	get_relation(nationRecno)->trade_treaty = treatyFlag;
1364 
1365 	nation_array[nationRecno]->get_relation(nation_recno)->trade_treaty = treatyFlag;
1366 }
1367 //------- End of function NationBase::set_trade_treaty -------//
1368 
1369 
1370 //------- Begin of function NationBase::establish_contact ------//
1371 //
1372 // <int> nationRecno - recno of the nation to establish contact with
1373 //
establish_contact(int nationRecno)1374 void NationBase::establish_contact(int nationRecno)
1375 {
1376 	get_relation(nationRecno)->has_contact = 1;
1377 	nation_array[nationRecno]->get_relation(nation_recno)->has_contact = 1;
1378 }
1379 //------- End of function NationBase::establish_contact -------//
1380 
1381 
1382 //------- Begin of function NationBase::being_attacked ------//
1383 //
1384 // <int> attackNationRecno - recno of the nation that does the attack.
1385 //
being_attacked(int attackNationRecno)1386 void NationBase::being_attacked(int attackNationRecno)
1387 {
1388 	if( nation_array.is_deleted(attackNationRecno) || attackNationRecno==nation_recno )
1389 		return;
1390 
1391 	//--- if it is an accidential attack (e.g. bullets attack with spreading damages) ---//
1392 
1393 	Nation* attackNation = nation_array[attackNationRecno];
1394 
1395 	if( attackNation->get_relation(nation_recno)->should_attack==0 )
1396 		return;
1397 
1398 	//--- check if there a treaty between these two nations ---//
1399 
1400 	NationRelation* nationRelation = get_relation(attackNationRecno);
1401 
1402 	if( nationRelation->status != NATION_HOSTILE )
1403 	{
1404 		//--- if this nation (the one being attacked) has a higher than 0 reputation, the attacker's reputation will decrease ---//
1405 
1406 		if( reputation > 0 )
1407 			attackNation->change_reputation( -reputation * 40 / 100 );
1408 
1409 		nationRelation->started_war_on_us_count++;	// how many times this nation has started a war with us, the more the times the worse this nation is.
1410 
1411 		if( nationRelation->status == NATION_ALLIANCE ||
1412 			 nationRelation->status == NATION_FRIENDLY )
1413 		{
1414 			attackNation->end_treaty(nation_recno, NATION_HOSTILE);		// the attacking nation abruptly terminates the treaty with us, not we terminate the treaty with them, so attackNation->end_treaty() should be called instead of end_treaty()
1415 		}
1416 		else
1417 		{
1418 			set_relation_status(attackNationRecno, NATION_HOSTILE);
1419 		}
1420 	}
1421 
1422 	//---- reset the inter-national peace days counter ----//
1423 
1424 	nation_array.nation_peace_days = 0;
1425 }
1426 //------- End of function NationBase::being_attacked -------//
1427 
1428 
1429 //------- Begin of function NationBase::disp_nation_color ------//
1430 //
1431 // Display the color of the nation in a rectangular box.
1432 //
disp_nation_color(int x,int y)1433 void NationBase::disp_nation_color(int x, int y)
1434 {
1435 	vga.active_buf->bar( x, y-2, x+12, y+10, nation_color );
1436 	vga.active_buf->rect( x, y-2, x+12, y+10, 1, nation_color+2 );
1437 }
1438 //------- End of function NationBase::disp_nation_color -------//
1439 
1440 
1441 //------- Begin of function NationBase::trade_rating ------//
1442 //
1443 // Return a rating from 0 to 100 telling the significance of
1444 // trading with the specific nation in this nation's regard.
1445 //
trade_rating(int nationRecno)1446 int NationBase::trade_rating(int nationRecno)
1447 {
1448 	// use an absolute value 5000 as the divider.
1449 
1450 	int tradeRating1 = 100 * (int) total_year_trade(nationRecno) / 5000;
1451 
1452 	int tradeRating2 = 50 * (int) nation_array[nationRecno]->get_relation(nation_recno)->last_year_import[IMPORT_TOTAL] / (int) (last_year_income+1) +
1453 							 50 * (int) get_relation(nationRecno)->last_year_import[IMPORT_TOTAL] / (int) (last_year_expense+1);
1454 
1455 	return MAX(tradeRating1, tradeRating2);
1456 }
1457 //------- End of function NationBase::trade_rating -------//
1458 
1459 
1460 //------- Begin of function NationBase::revealed_by_phoenix ------//
1461 //
1462 // Whether the area is revealed by phoenix of the nation or not.
1463 //
1464 // <int> xLoc, yLoc - the location
1465 //
revealed_by_phoenix(int xLoc,int yLoc)1466 int NationBase::revealed_by_phoenix(int xLoc, int yLoc)
1467 {
1468 	Unit* unitPtr;
1469 	int 	effectiveRange = unit_res[UNIT_PHOENIX]->visual_range;
1470 
1471 	for( int i=unit_array.size() ; i>0 ; i-- )
1472 	{
1473 		if( unit_array.is_deleted(i) )
1474 			continue;
1475 
1476 		unitPtr = unit_array[i];
1477 
1478 		if( unitPtr->unit_id == UNIT_PHOENIX &&
1479 			 unitPtr->nation_recno == nation_recno )
1480 		{
1481 			if( misc.points_distance( xLoc, yLoc,
1482 				 unitPtr->next_x_loc(), unitPtr->next_y_loc() ) <= effectiveRange )
1483 			{
1484 				return 1;
1485 			}
1486 		}
1487 	}
1488 
1489 	return 0;
1490 }
1491 //------- End of function NationBase::revealed_by_phoenix -------//
1492 
1493 
1494 //------- Begin of function NationBase::total_tech_level -------//
1495 //
1496 // The sum of the tech levels of weapons that this nation possesses.
1497 //
1498 // [int] unitClass - only calculate total tech levels of this
1499 //						   unit class. (default: 0, any classes)
1500 //
total_tech_level(int unitClass)1501 int NationBase::total_tech_level(int unitClass)
1502 {
1503 	TechInfo* techInfo;
1504 	int techLevel, totalTechLevel=0;
1505 
1506 	for( int i=1 ; i<=tech_res.tech_count ; i++ )
1507 	{
1508 		techInfo  = tech_res[i];
1509 		techLevel = techInfo->get_nation_tech_level(nation_recno);
1510 
1511 		if( techLevel > 0 )
1512 		{
1513 			if( !unitClass ||
1514 				 (unit_res[techInfo->unit_id]->unit_class == unitClass) )
1515 			{
1516 				totalTechLevel += techLevel;
1517 			}
1518 		}
1519 	}
1520 
1521 	return totalTechLevel;
1522 }
1523 //-------- End of function NationBase::total_tech_level -------//
1524 
1525 
1526 //---------- Begin of function NationBase::civilian_killed --------//
1527 //
1528 // This function is called when civilian units are killed and this
1529 // nation either killed the civilian units or this nation's civilian
1530 // units are killed.
1531 //
1532 // <int> civilianRaceId - the race id. of the civilian unit killed
1533 //								  0 - all races, when a Caravan is killed, 0 will
1534 //								  be passed, the loyalty of all races will be decreased.
1535 //
1536 // <int> penaltyLevel - positive value if this nation caused the death
1537 //								  negative value if this nation suffered the death
1538 //								  any nonzero value means loyalty will be decreased by
1539 //								  by that absolute amount
1540 //
1541 // Reputation penalties are based on severity coded below.
1542 // (Attacker,Defender)
1543 // Killed caravan: (-10,-3)
1544 // Killed town connected civilian: (-1,-0.3)
1545 // Killed any other non-combat mobile unit: (-0.3,-0.3)
civilian_killed(int civilianRaceId,int penaltyLevel)1546 void NationBase::civilian_killed(int civilianRaceId, int penaltyLevel)
1547 {
1548 	if( penaltyLevel )
1549 		change_all_people_loyalty(-abs(penaltyLevel), civilianRaceId);
1550 
1551 	if( penaltyLevel > 0 ) // caused the death by attacking a town or caravan
1552 	{
1553 		if( civilianRaceId==0 )				// a caravan
1554 			change_reputation(-(float)10);
1555 		else
1556 			change_reputation(-(float)1);
1557 	}
1558 	else // suffered the death or minor low-combat civilian death
1559 	{
1560 		if( civilianRaceId==0 )				// a caravan
1561 			change_reputation(-(float)3);
1562 		else
1563 			change_reputation(-(float)0.3);
1564 	}
1565 }
1566 //----------- End of function NationBase::civilian_killed ---------//
1567 
1568 
1569 //--------- Begin of function NationBase::succeed_king --------//
1570 //
1571 // Appoint a unit to succeed the king who has died.
1572 //
1573 // The loyalty of the people in the natino may change due
1574 // to the succession.
1575 //
succeed_king(int kingUnitRecno)1576 void NationBase::succeed_king(int kingUnitRecno)
1577 {
1578 	Unit* newKing = unit_array[kingUnitRecno];
1579 
1580 	err_when( newKing->skill.combat_level <= 0 );
1581 
1582 	int newKingLeadership=0;
1583 
1584 	if( newKing->skill.skill_id == SKILL_LEADING )
1585 		newKingLeadership = newKing->skill.skill_level;
1586 
1587 	newKingLeadership = MAX( 20, newKingLeadership );		// give the king a minimum level of leadership
1588 
1589 	//----- set the common loyalty change for all races ------//
1590 
1591 	int loyaltyChange=0;
1592 
1593 	if( newKingLeadership < king_leadership )
1594 		loyaltyChange = (newKingLeadership-king_leadership)/2;
1595 
1596 	if( newKing->rank_id != RANK_GENERAL )
1597 		loyaltyChange -= 20;
1598 
1599 	//---- update loyalty of units in this nation ----//
1600 
1601 	Unit* unitPtr;
1602 
1603 	int i;
1604 	for( i=unit_array.size() ; i>0 ; i-- )
1605 	{
1606 		if( unit_array.is_deleted(i) )
1607 			continue;
1608 
1609 		if( i==king_unit_recno || i==kingUnitRecno )
1610 			continue;
1611 
1612 		unitPtr = unit_array[i];
1613 
1614 		if( unitPtr->nation_recno != nation_recno )
1615 			continue;
1616 
1617 		//--------- update loyalty change ----------//
1618 
1619 		unitPtr->change_loyalty( loyaltyChange +
1620 			succeed_king_loyalty_change(unitPtr->race_id, newKing->race_id, race_id) );
1621 	}
1622 
1623 	//---- update loyalty of units in camps ----//
1624 
1625 	Firm* firmPtr;
1626 
1627 	for( i=firm_array.size() ; i>0 ; i-- )
1628 	{
1629 		if( firm_array.is_deleted(i) )
1630 			continue;
1631 
1632 		firmPtr = firm_array[i];
1633 
1634 		if( firmPtr->nation_recno != nation_recno )
1635 			continue;
1636 
1637 		//------ process military camps and seat of power -------//
1638 
1639 		if( firmPtr->firm_id == FIRM_CAMP || firmPtr->firm_id == FIRM_BASE )
1640 		{
1641 			Worker* workerPtr = firmPtr->worker_array;
1642 
1643 			for(int j=firmPtr->worker_count-1 ; j>=0 ; j--, workerPtr++ )
1644 			{
1645 				//--------- update loyalty change ----------//
1646 
1647 				workerPtr->change_loyalty( loyaltyChange +
1648 					succeed_king_loyalty_change(workerPtr->race_id, newKing->race_id, race_id ) );
1649 			}
1650 		}
1651 	}
1652 
1653 	//---- update loyalty of town people ----//
1654 
1655 	Town* townPtr;
1656 
1657 	for( i=town_array.size() ; i>0 ; i-- )
1658 	{
1659 		if( town_array.is_deleted(i) )
1660 			continue;
1661 
1662 		townPtr = town_array[i];
1663 
1664 		if( townPtr->nation_recno != nation_recno )
1665 			continue;
1666 
1667 		for(int raceId=1 ; raceId<=MAX_RACE ; raceId++ )
1668 		{
1669 			if( townPtr->race_pop_array[raceId-1]==0 )
1670 				continue;
1671 
1672 			//------ update loyalty now ------//
1673 
1674 			townPtr->change_loyalty(raceId, (float) loyaltyChange +
1675 				succeed_king_loyalty_change( raceId, newKing->race_id, race_id ) );
1676 		}
1677 	}
1678 
1679 	//------- add news --------//
1680 
1681 	news_array.new_king(nation_recno, kingUnitRecno);
1682 
1683 	//-------- set the new king now ------//
1684 
1685 	set_king(kingUnitRecno, 0);		// 0-not the first king, it is a succession
1686 
1687 	//------ if the new king is a spy -------//
1688 
1689 	if( newKing->spy_recno )
1690 	{
1691 		Spy* spyPtr = spy_array[newKing->spy_recno];
1692 
1693 		if( newKing->true_nation_recno() == nation_recno )      // if this is your spy
1694 			spyPtr->drop_spy_identity();
1695 		else
1696 			spyPtr->think_become_king();
1697 
1698 		err_when( newKing->rank_id==RANK_KING && newKing->spy_recno );		// it can't still be a spy when it asscends as the king
1699 	}
1700 }
1701 //----------- End of function NationBase::succeed_king ---------//
1702 
1703 
1704 //------ Begin of static function succeed_king_loyalty_change -----//
1705 //
1706 // Return the amount of loyalty should be changed.
1707 //
succeed_king_loyalty_change(int thisRaceId,int newKingRaceId,int oldKingRaceId)1708 static int succeed_king_loyalty_change(int thisRaceId, int newKingRaceId, int oldKingRaceId)
1709 {
1710 	#define SAME_RACE_LOYALTY_INC          20
1711 	#define DIFFERENT_RACE_LOYALTY_DEC	   30
1712 
1713 	//----- the races of the new and old kings are different ----//
1714 
1715 	if( newKingRaceId != oldKingRaceId )
1716 	{
1717 		//--- if this unit's race is the same as the new king ---//
1718 
1719 		if( thisRaceId == newKingRaceId )
1720 			return SAME_RACE_LOYALTY_INC;
1721 
1722 		//--- if this unit's race is the same as the old king ---//
1723 
1724 		else if( thisRaceId == oldKingRaceId )
1725 			return DIFFERENT_RACE_LOYALTY_DEC;
1726 	}
1727 
1728 	return 0;
1729 }
1730 //-------- End of static function succeed_king_loyalty_change ------//
1731 
1732 
1733 //--------- Begin of function NationBase::has_people --------//
1734 //
1735 // Whether the nation has any people (but not counting the king).
1736 // If no, then the nation is going to end.
1737 //
has_people()1738 int NationBase::has_people()
1739 {
1740 	return all_population() > 0;
1741 }
1742 //----------- End of function NationBase::has_people ---------//
1743 
1744 
1745 //--------- Begin of function NationBase::surrender --------//
1746 //
1747 // This nation surrenders.
1748 //
1749 // <int> toNationRecno - the recno of the nation this nation
1750 //								 surrenders to.
1751 //
surrender(int toNationRecno)1752 void NationBase::surrender(int toNationRecno)
1753 {
1754 	news_array.nation_surrender(nation_recno, toNationRecno);
1755 
1756 	//---- the king demote himself to General first ----//
1757 
1758 	if( king_unit_recno )
1759 	{
1760 		unit_array[king_unit_recno]->set_rank(RANK_GENERAL);
1761   		king_unit_recno = 0;
1762 	}
1763 
1764 	//------- if the player surrenders --------//
1765 
1766 	if( nation_recno==nation_array.player_recno )
1767 		game.game_end(0, 1, toNationRecno);
1768 
1769 	//--- hand over the entire nation to another nation ---//
1770 
1771 	hand_over_to(toNationRecno);
1772 }
1773 //----------- End of function NationBase::surrender ---------//
1774 
1775 
1776 //--------- Begin of function NationBase::defeated --------//
1777 //
1778 // This nation is defeated.
1779 //
defeated()1780 void NationBase::defeated()
1781 {
1782 	//---- if the defeated nation is the player's nation ----//
1783 
1784 	if( nation_recno == nation_array.player_recno )
1785 	{
1786 		game.game_end(0, 1);		// the player lost the game
1787 	}
1788 	else	// AI and remote players
1789 	{
1790 		news_array.nation_destroyed(nation_recno);
1791 	}
1792 
1793 	//---- delete this nation from nation_array ----//
1794 
1795 	nation_array.del_nation(nation_recno);
1796 }
1797 //----------- End of function NationBase::defeated ---------//
1798 
1799 
1800 //------- Begin of function NationBase::change_all_people_loyalty ------//
1801 //
1802 // Change the loyalty of all the people in your nation.
1803 //
1804 // <int> loyaltyChange - degree of loyalty change
1805 // [int] raceId		  - if this is given, then only people of this race
1806 //								 will be affected. (default: 0)
1807 //
change_all_people_loyalty(int loyaltyChange,int raceId)1808 void NationBase::change_all_people_loyalty(int loyaltyChange, int raceId)
1809 {
1810 	//---- update loyalty of units in this nation ----//
1811 
1812 	Unit* unitPtr;
1813 
1814 	int i;
1815 	for( i=unit_array.size() ; i>0 ; i-- )
1816 	{
1817 		if( unit_array.is_deleted(i) )
1818 			continue;
1819 
1820 		if( i==king_unit_recno )
1821 			continue;
1822 
1823 		unitPtr = unit_array[i];
1824 
1825 		if( unitPtr->nation_recno != nation_recno )
1826 			continue;
1827 
1828 		//--------- update loyalty change ----------//
1829 
1830 		if( !raceId || unitPtr->race_id == raceId )
1831 			unitPtr->change_loyalty(loyaltyChange);
1832 	}
1833 
1834 	//---- update loyalty of units in camps ----//
1835 
1836 	Firm* firmPtr;
1837 
1838 	for( i=firm_array.size() ; i>0 ; i-- )
1839 	{
1840 		if( firm_array.is_deleted(i) )
1841 			continue;
1842 
1843 		firmPtr = firm_array[i];
1844 
1845 		if( firmPtr->nation_recno != nation_recno )
1846 			continue;
1847 
1848 		//------ process military camps and seat of power -------//
1849 
1850 		if( firmPtr->firm_id == FIRM_CAMP || firmPtr->firm_id == FIRM_BASE )
1851 		{
1852 			Worker* workerPtr = firmPtr->worker_array;
1853 
1854 			for(int j=firmPtr->worker_count-1 ; j>=0 ; j--, workerPtr++ )
1855 			{
1856 				if( !raceId || workerPtr->race_id == raceId )
1857 					workerPtr->change_loyalty(loyaltyChange);
1858 			}
1859 		}
1860 	}
1861 
1862 	//---- update loyalty of town people ----//
1863 
1864 	Town* townPtr;
1865 
1866 	for( i=town_array.size() ; i>0 ; i-- )
1867 	{
1868 		if( town_array.is_deleted(i) )
1869 			continue;
1870 
1871 		townPtr = town_array[i];
1872 
1873 		if( townPtr->nation_recno != nation_recno )
1874 			continue;
1875 
1876 		//--------------------------------------//
1877 
1878 		if( raceId )		// decrease loyalty of a specific race
1879 		{
1880 			if( townPtr->race_pop_array[raceId-1] > 0 )
1881 				townPtr->change_loyalty(raceId, (float) loyaltyChange);
1882 		}
1883 		else					// decrease loyalty of all races
1884 		{
1885 			for(int j=0 ; j<MAX_RACE ; j++ )
1886 			{
1887 				if( townPtr->race_pop_array[j]==0 )
1888 					continue;
1889 
1890 				townPtr->change_loyalty(j+1, (float) loyaltyChange);
1891 			}
1892 		}
1893 	}
1894 }
1895 //------- End of function NationBase::change_all_people_loyalty -------//
1896 
1897 
1898 //------- Begin of function NationBase::total_year_trade ------//
1899 //
1900 // Return the total trade (import + export) with the specific
1901 // trade in the last year.
1902 //
total_year_trade(int nationRecno)1903 float NationBase::total_year_trade(int nationRecno)
1904 {
1905 	return get_relation(nationRecno)->last_year_import[IMPORT_TOTAL] +
1906 			 nation_array[nationRecno]->get_relation(nation_recno)->last_year_import[IMPORT_TOTAL];
1907 }
1908 //------- End of function NationBase::total_year_trade -------//
1909 
1910 
1911 //---------- Begin of function NationBase::check_win --------//
1912 //
1913 // Check if the player has won the game.
1914 //
check_win()1915 void NationBase::check_win()
1916 {
1917 	int hasWon = goal_destroy_nation_achieved() ||
1918 					 goal_destroy_monster_achieved() ||
1919 					 goal_population_achieved() ||
1920                 goal_economic_score_achieved() ||
1921 					 goal_total_score_achieved();
1922 
1923 	if( !hasWon )
1924 		return;
1925 
1926 	//--------------------------------------//
1927 
1928 	game.game_end(nation_recno, 0);		// if the player achieves the goal, the player wins, if one of the other kingdoms achieves the goal, it wins.
1929 }
1930 //----------- End of function NationBase::check_win ---------//
1931 
1932 
1933 //---------- Begin of function NationBase::check_lose --------//
1934 //
1935 // Check if the player has lost the game.
1936 //
1937 // If the player still hasn't selected a unit to succeed the
1938 // died king, declare defeated if the all units are killed.
1939 //
check_lose()1940 void NationBase::check_lose()
1941 {
1942 	//---- if the king of this nation is dead and it has no people left ----//
1943 
1944 	if( !king_unit_recno && !has_people() )
1945 		defeated();
1946 }
1947 //----------- End of function NationBase::check_lose ---------//
1948 
1949 
1950 //---------- Begin of function NationBase::give_tribute --------//
1951 //
1952 // Give tribute or aid to a nation.
1953 //
1954 // <int> toNationRecno - give tribute to this nation
1955 // <int> tributeAmt    - the amount of the tribute
1956 //
give_tribute(int toNationRecno,int tributeAmt)1957 void NationBase::give_tribute(int toNationRecno, int tributeAmt)
1958 {
1959 	Nation* toNation = nation_array[toNationRecno];
1960 
1961 	add_expense( EXPENSE_TRIBUTE, (float) tributeAmt );
1962 
1963 	toNation->add_income( INCOME_TRIBUTE, (float) tributeAmt );
1964 
1965 	NationRelation* nationRelation = get_relation(toNationRecno);
1966 
1967 	nationRelation->last_give_gift_date      = info.game_date;
1968 	nationRelation->total_given_gift_amount += tributeAmt;
1969 
1970 	//---- set the last rejected date so it won't request or give again soon ----//
1971 
1972 	nationRelation->last_talk_reject_date_array[TALK_GIVE_AID-1] = 0;
1973 	nationRelation->last_talk_reject_date_array[TALK_DEMAND_AID-1] = 0;
1974 	nationRelation->last_talk_reject_date_array[TALK_GIVE_TRIBUTE-1] = 0;
1975 	nationRelation->last_talk_reject_date_array[TALK_DEMAND_TRIBUTE-1] = 0;
1976 
1977 	NationRelation* nationRelation2 = toNation->get_relation(nation_recno);
1978 
1979 	nationRelation2->last_talk_reject_date_array[TALK_GIVE_AID-1] = 0;
1980 	nationRelation2->last_talk_reject_date_array[TALK_DEMAND_AID-1] = 0;
1981 	nationRelation2->last_talk_reject_date_array[TALK_GIVE_TRIBUTE-1] = 0;
1982 	nationRelation2->last_talk_reject_date_array[TALK_DEMAND_TRIBUTE-1] = 0;
1983 }
1984 //----------- End of function NationBase::give_tribute ---------//
1985 
1986 
1987 //---------- Begin of function NationBase::give_tech --------//
1988 //
1989 // Give tribute or aid to a nation.
1990 //
1991 // <int> toNationRecno - give tribute to this nation
1992 // <int> techId        - id. of the technology
1993 // <int> techVersion   - version of the technology
1994 //
give_tech(int toNationRecno,int techId,int techVersion)1995 void NationBase::give_tech(int toNationRecno, int techId, int techVersion)
1996 {
1997 	Nation* toNation = nation_array[toNationRecno];
1998 
1999 	int curVersion = tech_res[techId]->get_nation_tech_level(toNationRecno);
2000 
2001 	if( curVersion < techVersion )
2002 		tech_res[techId]->set_nation_tech_level( toNationRecno, techVersion );
2003 
2004 	NationRelation* nationRelation = get_relation(toNationRecno);
2005 
2006 	nationRelation->last_give_gift_date      = info.game_date;
2007 	nationRelation->total_given_gift_amount += (techVersion-curVersion) * 500;		// one version level is worth $500
2008 
2009 	//---- set the last rejected date so it won't request or give again soon ----//
2010 
2011 	nationRelation->last_talk_reject_date_array[TALK_GIVE_TECH-1] = 0;
2012 	nationRelation->last_talk_reject_date_array[TALK_DEMAND_TECH-1] = 0;
2013 
2014 	NationRelation* nationRelation2 = toNation->get_relation(nation_recno);
2015 
2016 	nationRelation2->last_talk_reject_date_array[TALK_GIVE_TECH-1] = 0;
2017 	nationRelation2->last_talk_reject_date_array[TALK_DEMAND_TECH-1] = 0;
2018 }
2019 //----------- End of function NationBase::give_tech ---------//
2020 
2021 
2022 //----- Begin of function NationBase::base_town_count_in_region -----//
2023 //
2024 // Return the number of base towns in the given region.
2025 //
base_town_count_in_region(int regionId)2026 int NationBase::base_town_count_in_region(int regionId)
2027 {
2028 	// ###### patch begin Gilbert 16/3 #######//
2029 	// regionStatId may be zero
2030 	int regionStatId = region_array[regionId]->region_stat_id;
2031 	if( regionStatId )
2032 	{
2033 		return region_array.get_region_stat2(regionStatId)->
2034 			 base_town_nation_count_array[nation_recno-1];
2035 	}
2036 	else if( region_array[regionId]->region_size < STD_TOWN_LOC_WIDTH*STD_TOWN_LOC_HEIGHT)
2037 	{
2038 		return 0;			// not enough to build any town
2039 	}
2040 	else
2041 	{
2042 		int townCount = 0;
2043 		for( int townRecno = town_array.size(); townRecno > 0; --townRecno )
2044 		{
2045 			if( town_array.is_deleted(townRecno) )
2046 				continue;
2047 
2048 			Town *townPtr = town_array[townRecno];
2049 			if( townPtr->region_id == regionId && townPtr->nation_recno == nation_recno )
2050 				townCount++;
2051 		}
2052 		return townCount == 0;
2053 	}
2054 	// ###### patch end Gilbert 16/3 #######//
2055 }
2056 //------ End of function NationBase::base_town_count_in_region -----//
2057 
2058 
2059 //----- Begin of function NationBase::peace_duration_str -----//
2060 //
peace_duration_str()2061 char* NationBase::peace_duration_str()
2062 {
2063 	int peaceDays  = peaceful_days();
2064 	int peaceYear  = peaceDays / 365;
2065 	int peaceMonth = (peaceDays - peaceYear * 365) / 30;
2066 
2067 	static String str;
2068 
2069 	str = "";
2070 
2071 	if( peaceYear )
2072 	{
2073 		str.catf(ngettext("%d year and", "%d years and", peaceYear), peaceYear);
2074 		str += " ";
2075 	}
2076 
2077 	str.catf(ngettext("%d month", "%d months", peaceMonth), peaceMonth);
2078 
2079 	return str;
2080 }
2081 //------ End of function NationBase::peace_duration_str -----//
2082 
2083 
2084 //----- Begin of function NationBase::true_income_365days -----//
2085 //
2086 // Return the total income of the nation, excluding cheats.
2087 //
true_income_365days()2088 float NationBase::true_income_365days()
2089 {
2090 	float curYearIncome=(float)0, lastYearIncome=(float)0;
2091 
2092 	for( int i=0 ; i<INCOME_TYPE_COUNT-1 ; i++ )		// -1 to exclude cheat
2093 	{
2094 		curYearIncome  += cur_year_income_array[i];
2095 		lastYearIncome += last_year_income_array[i];
2096 	}
2097 
2098 	return lastYearIncome * (365-info.year_day) / 365 + curYearIncome;
2099 }
2100 //------ End of function NationBase::true_income_365days -----//
2101 
2102 
2103 //----- Begin of function NationBase::update_nation_rating -----//
2104 //
update_nation_rating()2105 void NationBase::update_nation_rating()
2106 {
2107 	population_rating = get_population_rating();
2108 
2109 	economic_rating = get_economic_rating();
2110 
2111 	overall_rating  = get_overall_rating();
2112 }
2113 //------ End of function NationBase::update_nation_rating -----//
2114 
2115 
2116 //----- Begin of function NationBase::get_population_rating -----//
2117 //
get_population_rating()2118 int NationBase::get_population_rating()
2119 {
2120 	return all_population();
2121 }
2122 //------ End of function NationBase::get_population_rating -----//
2123 
2124 
2125 //----- Begin of function NationBase::get_economic_rating -----//
2126 //
get_economic_rating()2127 int NationBase::get_economic_rating()
2128 {
2129 	return (int) cash / 300 +
2130 			 (int) true_income_365days()/2 +
2131 			 (int) true_profit_365days();
2132 }
2133 //------ End of function NationBase::get_economic_rating -----//
2134 
2135 
2136 //----- Begin of function NationBase::get_overall_rating -----//
2137 //
get_overall_rating()2138 int NationBase::get_overall_rating()
2139 {
2140 	return  33*population_rating/500+
2141 			  33*military_rating/200+
2142 			  33*economic_rating/10000;
2143 }
2144 //------ End of function NationBase::get_overall_rating -----//
2145 
2146 
2147 //----- Begin of function NationBase::population_rank_rating -----//
2148 //
population_rank_rating()2149 int NationBase::population_rank_rating()
2150 {
2151 	if( nation_array.max_population_rating==0 )
2152 		return 0;
2153 
2154 	return 100 * population_rating / nation_array.max_population_rating;
2155 }
2156 //------ End of function NationBase::population_rank_rating -----//
2157 
2158 
2159 //----- Begin of function NationBase::military_rank_rating -----//
2160 //
military_rank_rating()2161 int NationBase::military_rank_rating()
2162 {
2163 	if( nation_array.max_military_rating==0 )
2164 		return 0;
2165 
2166 	return 100 * military_rating / nation_array.max_military_rating;
2167 }
2168 //------ End of function NationBase::military_rank_rating -----//
2169 
2170 
2171 //----- Begin of function NationBase::economic_rank_rating -----//
2172 //
economic_rank_rating()2173 int NationBase::economic_rank_rating()
2174 {
2175 	if( nation_array.max_economic_rating==0 )
2176 		return 0;
2177 
2178 	return 100 * economic_rating / nation_array.max_economic_rating;
2179 }
2180 //------ End of function NationBase::economic_rank_rating -----//
2181 
2182 
2183 //----- Begin of function NationBase::reputation_rank_rating -----//
2184 //
reputation_rank_rating()2185 int NationBase::reputation_rank_rating()
2186 {
2187 	if( nation_array.max_reputation==0 )
2188 		return 0;
2189 
2190 	return 100 * (int) reputation / nation_array.max_reputation;
2191 }
2192 //------ End of function NationBase::reputation_rank_rating -----//
2193 
2194 
2195 //----- Begin of function NationBase::kill_monster_rank_rating -----//
2196 //
kill_monster_rank_rating()2197 int NationBase::kill_monster_rank_rating()
2198 {
2199 	if( nation_array.max_kill_monster_score==0 )
2200 		return 0;
2201 
2202 	if( config.monster_type == OPTION_MONSTER_NONE )
2203 		return 0;
2204 
2205 	return 100 * (int) kill_monster_score / nation_array.max_kill_monster_score;
2206 }
2207 //------ End of function NationBase::kill_monster_rank_rating -----//
2208 
2209 
2210 //----- Begin of function NationBase::overall_rank_rating -----//
2211 //
overall_rank_rating()2212 int NationBase::overall_rank_rating()
2213 {
2214 	if( nation_array.max_overall_rating==0 )
2215 		return 0;
2216 
2217 	return 100 * overall_rating / nation_array.max_overall_rating;
2218 }
2219 //------ End of function NationBase::overall_rank_rating -----//
2220 
2221 
2222 //------- Begin of function NationBase::goal_destroy_nation_achieved --------//
2223 
goal_destroy_nation_achieved()2224 int NationBase::goal_destroy_nation_achieved()
2225 {
2226 	return nation_array.nation_count==1;
2227 }
2228 //------- End of function NationBase::goal_destroy_nation_achieved --------//
2229 
2230 
2231 //------- Begin of function NationBase::goal_destroy_monster_achieved --------//
2232 
goal_destroy_monster_achieved()2233 int NationBase::goal_destroy_monster_achieved()
2234 {
2235 	if( !config.goal_destroy_monster )		// this is not one of the required goals.
2236 		return 0;
2237 
2238 	if( config.monster_type == OPTION_MONSTER_NONE )
2239 		return 0;
2240 
2241 	//------- when all monsters have been killed -------//
2242 
2243 	if( firm_res[FIRM_MONSTER]->total_firm_count == 0 &&
2244 		 unit_res.mobile_monster_count == 0 )
2245 	{
2246 		Nation* nationPtr;
2247 		float	  maxScore=(float)0;
2248 
2249 		for( int i=nation_array.size() ; i>0 ; i-- )
2250 		{
2251 			if( nation_array.is_deleted(i) )
2252 				continue;
2253 
2254 			nationPtr = nation_array[i];
2255 
2256 			if( nationPtr->kill_monster_score > maxScore )
2257 				maxScore = nationPtr->kill_monster_score;
2258 		}
2259 
2260 		//-- if this nation is the one that has destroyed most monsters, it wins, otherwise it loses --//
2261 
2262 		return maxScore == kill_monster_score;
2263 	}
2264 
2265 	return 0;
2266 }
2267 //------- End of function NationBase::goal_destroy_monster_achieved --------//
2268 
2269 
2270 //------- Begin of function NationBase::goal_population_achieved --------//
2271 
goal_population_achieved()2272 int NationBase::goal_population_achieved()
2273 {
2274 	if( !config.goal_population_flag )		// this is not one of the required goals.
2275 		return 0;
2276 
2277 	return all_population() >= config.goal_population;
2278 }
2279 //------- End of function NationBase::goal_population_achieved --------//
2280 
2281 
2282 //------ Begin of function NationBase::goal_economic_score_achieved ------//
2283 
goal_economic_score_achieved()2284 int NationBase::goal_economic_score_achieved()
2285 {
2286 	if( !config.goal_economic_score_flag )
2287 		return 0;
2288 
2289 	info.set_rank_data(0);		// 0-set all nations, not just those that have contact with us
2290 
2291 	return info.get_rank_score(3,nation_recno) >= config.goal_economic_score;
2292 }
2293 //------- End of function NationBase::goal_economic_score_achieved -------//
2294 
2295 
2296 //------ Begin of function NationBase::goal_total_score_achieved -------//
2297 
goal_total_score_achieved()2298 int NationBase::goal_total_score_achieved()
2299 {
2300 	if( !config.goal_total_score_flag )
2301 		return 0;
2302 
2303 	info.set_rank_data(0);	   // 0-set all nations, not just those that have contact with us
2304 
2305 	return info.get_total_score(nation_recno) >= config.goal_total_score;
2306 }
2307 //------- End of function NationBase::goal_total_score_achieved --------//
2308 
2309 
2310 //----- Begin of function NationBase::set_auto_collect_tax_loyalty -----//
2311 //
set_auto_collect_tax_loyalty(int loyaltyLevel)2312 void NationBase::set_auto_collect_tax_loyalty(int loyaltyLevel)
2313 {
2314 	auto_collect_tax_loyalty = loyaltyLevel;
2315 
2316 	if( loyaltyLevel && auto_grant_loyalty >= auto_collect_tax_loyalty )
2317 	{
2318 		auto_grant_loyalty = auto_collect_tax_loyalty-10;
2319 	}
2320 }
2321 //------ End of function NationBase::set_auto_collect_tax_loyalty -----//
2322 
2323 
2324 //----- Begin of function NationBase::set_auto_grant_loyalty -----//
2325 //
set_auto_grant_loyalty(int loyaltyLevel)2326 void NationBase::set_auto_grant_loyalty(int loyaltyLevel)
2327 {
2328 	auto_grant_loyalty = loyaltyLevel;
2329 
2330 	if( loyaltyLevel && auto_grant_loyalty >= auto_collect_tax_loyalty )
2331 	{
2332 		auto_collect_tax_loyalty = auto_grant_loyalty+10;
2333 
2334 		if( auto_collect_tax_loyalty > 100 )
2335 			auto_collect_tax_loyalty = 0;					// disable auto collect tax if it's over 100
2336 	}
2337 }
2338 //------ End of function NationBase::set_auto_grant_loyalty -----//
2339 
2340 
2341 //----- Begin of function NationRelation::status_str -----//
2342 //
status_str()2343 const char* NationRelation::status_str()
2344 {
2345 	return _(relation_status_str_array[status]);
2346 }
2347 //------ End of function NationRelation::status_str -----//
2348 
2349 
2350 //----- Begin of function NationRelation::status_duration_str -----//
2351 //
status_duration_str()2352 char* NationRelation::status_duration_str()
2353 {
2354 	int statusDays  = info.game_date - last_change_status_date;
2355 	int statusYear  = statusDays / 365;
2356 	int statusMonth = (statusDays - statusYear * 365) / 30;
2357 
2358 	static String str;
2359 
2360 	str = "";
2361 
2362 	if( statusYear > 1 )
2363 	{
2364 		// TRANSLATORS: Part of "%d year(s) and %d month(s)"
2365 		str.catf(ngettext("%d year and", "%d years and", statusYear), statusYear);
2366 		str += " ";
2367 	}
2368 
2369 	str.catf(ngettext("%d month", "%d months", statusMonth), statusMonth);
2370 
2371 	return str;
2372 }
2373 //------ End of function NationRelation::status_duration_str -----//
2374 
2375 
2376 //----- Begin of function NationRelation::duration_of_status_str -----//
2377 //
duration_of_status_str()2378 const char* NationRelation::duration_of_status_str()
2379 {
2380 	return _(duration_of_status_str_array[status]);
2381 }
2382 //------ End of function NationRelation::duration_of_status_str -----//
2383 
2384