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