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    : ONATIONB.H
22 //Description : class NationBase
23 
24 #ifndef __ONATIONB_H
25 #define __ONATIONB_H
26 
27 #ifndef __OINFO_H
28 #include <OINFO.h>
29 #endif
30 
31 #ifndef __ORAWRES_H
32 #include <ORAWRES.h>
33 #endif
34 
35 #ifndef __OTALKMSG_H
36 #include <OTALKMSG.h>
37 #endif
38 
39 //---------- Define constant -----------//
40 
41 enum { NATION_OWN=1, NATION_REMOTE, NATION_AI };       // NATION_MISC=Government
42 
43 enum { NATION_HOSTILE=0, NATION_TENSE, NATION_NEUTRAL, NATION_FRIENDLY, NATION_ALLIANCE };
44 
45 enum { RELATION_LEVEL_PER_STATUS = 20 };		// relation_level = status * NATION_LEVEL_PER_STATUS
46 
47 //---------- import type ----------//
48 
49 enum { IMPORT_TYPE_COUNT = 3 };
50 
51 enum { IMPORT_RAW,
52 		 IMPORT_PRODUCT,
53 		 IMPORT_TOTAL
54 	  };
55 
56 //--------- income types --------//
57 
58 enum { INCOME_TYPE_COUNT = 8 };
59 
60 enum { INCOME_SELL_GOODS,
61 		 INCOME_EXPORTS,
62 		 INCOME_TAX,
63 		 INCOME_TREASURE,
64 		 INCOME_FOREIGN_WORKER,
65 		 INCOME_SELL_FIRM,
66 		 INCOME_TRIBUTE,
67 		 INCOME_CHEAT,
68 	  };
69 
70 //--------- expense types --------//
71 
72 enum { EXPENSE_TYPE_COUNT = 16 };
73 
74 enum { EXPENSE_GENERAL,
75 		 EXPENSE_SPY,
76 		 EXPENSE_MOBILE_UNIT,
77 		 EXPENSE_CARAVAN,
78 		 EXPENSE_WEAPON,
79 		 EXPENSE_SHIP,
80 		 EXPENSE_FIRM,
81 		 EXPENSE_TRAIN_UNIT,
82 		 EXPENSE_HIRE_UNIT,
83 		 EXPENSE_REWARD_UNIT,
84 		 EXPENSE_FOREIGN_WORKER,
85 		 EXPENSE_GRANT_OWN_TOWN,
86 		 EXPENSE_GRANT_OTHER_TOWN,
87 		 EXPENSE_IMPORTS,
88 		 EXPENSE_TRIBUTE,
89 		 EXPENSE_BRIBE,
90 	  };
91 
92 //----- Define struct NationRelation -------//
93 
94 #pragma pack(1)
95 struct NationRelation			// many-to-many relationships between nations
96 {
97 	char  has_contact;			// whether this nation has been contacted or not
98 	char	should_attack;			// whether units should automatically attack units/firms of this nation when the relationship is hostile
99 
100 	char	trade_treaty;			// whether allow trading with this nation
101 
102 	char  status;
103 	const char* status_str();
104 	const char* duration_of_status_str();
105 
106 	int	last_change_status_date;
107    char* status_duration_str();
108 
109 	char  ai_relation_level;		// AI's subjectively relation levels towards the others, the opposite nation's relation level is not the same as this
110 	char	ai_secret_attack;
111 	char	ai_demand_trade_treaty;
112 
113 	float good_relation_duration_rating;		// a rating indicate how long does a good relation (friendly/alliance) lasts
114 	short	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.
115 
116 	float cur_year_import[IMPORT_TYPE_COUNT];
117 	float last_year_import[IMPORT_TYPE_COUNT];
118 	float lifetime_import[IMPORT_TYPE_COUNT];
119 
import_365daysNationRelation120 	float import_365days(int importType)	{ return last_year_import[importType]*(365-info.year_day)/365 +
121 															cur_year_import[importType]; }
122 
123 	int	last_talk_reject_date_array[MAX_TALK_TYPE];	// the date which the last diplomatic request was rejected.
124 	int	last_military_aid_date;
125 
126 	int	last_give_gift_date;				// the last date which the current nation give tribute, aid or technology to this nation
127 	short total_given_gift_amount;		// the total amount of gift the current nation has given to this nation
128 
129 	char	contact_msg_flag;										// used only in multiplayer
130 
131 	static const char* relation_status_str_array[5];
132 	static const char* duration_of_status_str_array[5];
133 };
134 #pragma pack()
135 
136 //---------- Define class Nation -----------//
137 
138 class Unit;
139 class Firm;
140 
141 #pragma pack(1)
142 class NationBase
143 {
144 public:
145 	enum { NATION_NAME_LEN=50 };
146 
147 	short	nation_recno;
148 	char  nation_type;
149 
150 	char  race_id;
151 	char  color_scheme_id;
152 	char	nation_color;				// main color of the nation, based on from color_scheme_id
153 
154 	short	king_unit_recno;			// recno of the king
155 	char	king_leadership;
156 
157 	int 	nation_name_id;			// name of the king/nation
158 	char  nation_name_str[NATION_NAME_LEN+1];		// for nation_name()'s use
159 	char* nation_name();
160 	const char* king_name(int firstWordOnly=0);
161 
162 	uint32_t player_id;				   // player id for multiplayer game
163 
164 	char  next_frame_ready;				// for indicating whether the next frame is ready or not
165 	short last_caravan_id;				// id. of the nation's caravan.
166 
167 	short	nation_firm_count;			// total no. of firms the nation has built
168 	int   last_build_firm_date;
169 
170 	char	know_base_array[MAX_RACE];		// whether the unit knows how to constructure seat of power or not
171 	char	base_count_array[MAX_RACE];   // no. of seat of power this nation has
172 
173 	char	is_at_war_today;
174 	char	is_at_war_yesterday;
175 	int	last_war_date;
176 	short last_attacker_unit_recno;
177 	int	last_independent_unit_join_date;
178 
peaceful_days()179 	int	peaceful_days()			{ return info.game_date - last_war_date; }
180 	char*	peace_duration_str();
181 
182 	void	set_at_war_today(int attackerUnitRecno=0)
183 			{ is_at_war_today=1; if(attackerUnitRecno) last_attacker_unit_recno=attackerUnitRecno; }
184 
is_at_war()185 	int	is_at_war()					{ return is_at_war_today || is_at_war_yesterday; }
186 
187 	char  cheat_enabled_flag;
188 
189 	//----------------------------------//
190 
191 	float		 cash;
192 	float		 food;
193 
194 	char*		 cash_str();
195 	char*		 food_str();
196 
yearly_food_consumption()197 	int		 yearly_food_consumption() { return PERSON_FOOD_YEAR_CONSUMPTION * all_population(); }
yearly_food_production()198 	int		 yearly_food_production() 	{ return PEASANT_FOOD_YEAR_PRODUCTION * total_jobless_population; }
yearly_food_change()199 	int       yearly_food_change() 	   { return yearly_food_production() - yearly_food_consumption(); }
200 
201 	float		 reputation;				// can be negative, means bad reputation
202 	float		 kill_monster_score;
203 
204 	//------- town auto policy -------------//
205 
206 	short		 auto_collect_tax_loyalty;		// auto collect tax if the loyalty reaches this level
207 	short		 auto_grant_loyalty;				// auto grant if the loyalty drop below this level
208 
209 	//----- yearly income, expense and profit ------//
210 
211 	float		 cur_year_profit;
212 	float		 last_year_profit;
profit_365days()213 	float		 profit_365days()				{ return last_year_profit*(365-info.year_day)/365 +
214 													  cur_year_profit; }
215 	float		 cur_year_fixed_income;
216 	float		 last_year_fixed_income;
fixed_income_365days()217 	float		 fixed_income_365days()		{ return last_year_fixed_income*(365-info.year_day)/365 +
218 													  cur_year_fixed_income; }
219 	float		 cur_year_fixed_expense;
220 	float		 last_year_fixed_expense;
fixed_expense_365days()221 	float		 fixed_expense_365days()	{ return last_year_fixed_expense*(365-info.year_day)/365 +
222 													  cur_year_fixed_expense; }
223 
fixed_profit_365days()224 	float		 fixed_profit_365days()		{ return fixed_income_365days() - fixed_expense_365days(); }
225 
226 	//------- yearly income ------//
227 
228 	float		 cur_year_income_array[INCOME_TYPE_COUNT];
229 	float		 last_year_income_array[INCOME_TYPE_COUNT];
230 
231 	float		 cur_year_income;		// total income
232 	float		 last_year_income;
233 
income_365days()234 	float		 income_365days()				{ return last_year_income*(365-info.year_day)/365 + cur_year_income; }
235 
income_365days(int incomeType)236 	float 	 income_365days(int incomeType)	{ return last_year_income_array[incomeType] * (365-info.year_day) / 365 +
237 																  cur_year_income_array[incomeType]; }
238 	float		 true_income_365days();		// total income, excluding cheats
239 
240 	//------- yearly expense ------//
241 
242 	float		 cur_year_expense_array[EXPENSE_TYPE_COUNT];
243 	float		 last_year_expense_array[EXPENSE_TYPE_COUNT];
244 
245 	float		 cur_year_expense;		// total expense
246 	float		 last_year_expense;
247 
expense_365days()248 	float		 expense_365days()				{ return last_year_expense*(365-info.year_day)/365 + cur_year_expense; }
249 
expense_365days(int expenseType)250 	float 	 expense_365days(int expenseType)	{ return last_year_expense_array[expenseType] * (365-info.year_day) / 365 +
251 																  cur_year_expense_array[expenseType]; }
252 	//------- yearly expense ------//
253 
254 	float		 cur_year_cheat;		// total cheat
255 	float		 last_year_cheat;
256 
cheat_365days()257 	float 	 cheat_365days()			{ return last_year_cheat*(365-info.year_day)/365 + cur_year_cheat; }
258 
true_profit_365days()259 	float		 true_profit_365days() 	{ return profit_365days() - cheat_365days(); }
260 
261 	//----- yearly food in, out and change ------//
262 
263 	float		 cur_year_food_in;
264 	float		 last_year_food_in;
265 
266 	float		 cur_year_food_out;
267 	float		 last_year_food_out;
268 
269 	float		 cur_year_food_change;
270 	float		 last_year_food_change;
food_change_365days()271 	float		 food_change_365days()		{ return last_year_food_change*(365-info.year_day)/365 +
272 													  cur_year_food_change; }
273 	//----- yearly reputatino change ------//
274 
275 	float     cur_year_reputation_change;
276 	float     last_year_reputation_change;
277 
reputation_change_365days()278 	float		 reputation_change_365days() { return last_year_reputation_change*(365-info.year_day)/365 +
279 														 cur_year_reputation_change; }
280 
281 	//--------- inter-nation relationship -----------//
282 
283 	NationRelation relation_array[MAX_NATION];				// inter-relationship with other nations
284 	char		 relation_status_array[MAX_NATION];				// replace status in struct NationRelation
285 	char		 relation_passable_array[MAX_NATION]; 			// for seeking to indicate whether passing other nation region
286 	char		 relation_should_attack_array[MAX_NATION];
287 	char		 is_allied_with_player;								// for fast access in visiting world functions
288 
289 	void		 set_relation_status(short nationRecno, char newStatus, char recursiveCall=0);
290 	char		 get_relation_status(short nationRecno);
291 	void		 set_relation_passable(short nationRecno, char status);
292 	char		 get_relation_passable(short nationRecno);
293 	void		 set_relation_should_attack(short nationRecno, char newValue, char remoteAction);
294 	char		 get_relation_should_attack(short nationRecno);
295 
296 	void		 set_trade_treaty(int nationRecno, char allowFlag);
297 	void		 establish_contact(int nationRecno);
298 	void		 change_ai_relation_level(short nationRecno, int levelChange);
299 
300 	#ifdef DEBUG
301 		NationRelation* get_relation(int nationRecno);
302 	#else
get_relation(int nationRecno)303 		NationRelation* get_relation(int nationRecno) { return relation_array+nationRecno-1; }
304 	#endif
305 
306 	//--------- total yearly trade amount --------//
307 
308 	float		 total_year_trade(int nationRecno);
309 	int 		 trade_rating(int nationRecno);
310 
311 	//---------- statistic ------------//
312 
313 	int  		 total_population;
314 	int		 total_jobless_population;
all_population()315 	int		 all_population()				{ return total_population + total_human_count; }
316 
317 	int		 total_unit_count;
318 	int		 total_human_count;
319 	int		 total_general_count;
320 	int		 total_weapon_count;
321 	int		 total_ship_count;
322 	int		 total_firm_count;
323 	int		 total_spy_count;
324 	int		 total_ship_combat_level;
325 
326 	short		 largest_town_recno;		// the recno of the biggest town of this nation
327 	short		 largest_town_pop;
328 
329 	int 		 total_tech_level(int unitClass=0);
330 	int 		 base_town_count_in_region(int regionId);
331 
332 	short		 raw_count_array[MAX_RAW];		// no. of natural resources site this nation possesses
333 
334 	uint16_t     last_unit_name_id_array[MAX_UNIT_TYPE];
335 
336 	//--------- rank ratings ---------//
337 
338 	int		 population_rating;
339 	int		 military_rating;
340 	int		 economic_rating;
341    int		 overall_rating;
342 
343 	void		 update_nation_rating();
344 
345 	int		 get_population_rating();
346 	int		 get_economic_rating();
347 	int		 get_overall_rating();
348 
349 	int		 population_rank_rating();
350 	int		 military_rank_rating();
351 	int		 economic_rank_rating();
352 	int		 reputation_rank_rating();
353 	int		 kill_monster_rank_rating();
354 	int		 overall_rank_rating();
355 
356 	//------ additional statistic ------//
357 
358 	int		 enemy_soldier_killed;
359 	int		 own_soldier_killed;
360 	int		 enemy_civilian_killed;
361 	int		 own_civilian_killed;
362 	int		 enemy_weapon_destroyed;
363 	int		 own_weapon_destroyed;
364 	int		 enemy_ship_destroyed;
365 	int		 own_ship_destroyed;
366 	int		 enemy_firm_destroyed;
367 	int		 own_firm_destroyed;
368 
369 	//---------- functions -------------//
370 
371 	int			goal_destroy_nation_achieved();
372 	int			goal_destroy_monster_achieved();
373 	int			goal_population_achieved();
374 	int			goal_economic_score_achieved();
375 	int			goal_total_score_achieved();
376 
is_own()377 	int			is_own()    	{ return nation_type==NATION_OWN;    }
is_ai()378 	int			is_ai()			{ return nation_type==NATION_AI;		 }
is_remote()379 	int			is_remote() 	{ return nation_type==NATION_REMOTE; }
380 
381 public:
382 	NationBase();
383 	~NationBase();
384 
385 	virtual	void init(int nationType, int raceId, int colorSchemeId, uint32_t playerId=0);
386    virtual  void deinit();
387 
388 	void 		init_relation(int relationNationRecno);
389 
390 	void 		close_all_firm();
391 	void		deinit_all_unit();
392 	void 		succeed_king(int kingUnitRecno);
393 	void 		set_king(int kingUnitRecno, int firstKing);
394 	void 		hand_over_to(int handoverNationRecno);
395 
396 	void 		disp_nation_color(int x, int y);
397 
398 	void 		next_day();
399 	void 		next_month();
400 	void 		next_year();
401 
402 	void		add_income(int incomeType, float incomeAmt, int fixedIncome=0);
403 	void		add_expense(int expenseType, float expenseAmt, int fixedExpense=0);
404 	void		add_cheat(float cheatAmt);
405 	void		change_reputation(float);
406 
407 	void		add_food(float);
408 	void		consume_food(float);
409 	void		import_goods(int importType, int nationRecno, float importAmt);
410 	void 		give_tribute(int toNationRecno, int tributeAmt);
411 	void 		give_tech(int toNationRecno, int techId, int techVersion);
412 
413 	void 		set_auto_collect_tax_loyalty(int loyaltyLevel);
414 	void 		set_auto_grant_loyalty(int loyaltyLevel);
415 
416 	int		has_people();		// whether the nation has any people (but not counting the king). If no, then the nation is going to end.
417 
418 	void		being_attacked(int attackNationRecno);
419 	void		civilian_killed(int civilianRaceId, int penaltyLevel);
420 	void 		change_all_people_loyalty(int loyaltyChange, int raceId=0);
421 
422 	void 		form_friendly_treaty(int nationRecno);
423 	void 		form_alliance_treaty(int nationRecno);
424 	void 		end_treaty(int endTreatyNationRecno, int newStatus);
425 
426 	void		surrender(int toNationRecno);
427 	void		defeated();
428 	void		check_win();
429 	void		check_lose();
430 
431 	int		revealed_by_phoenix(int xLoc, int yLoc);
432 
433 	//--------- file functions -----------//
434 
435 	int 		write_file(File* filePtr);
436 	int		read_file(File* filePtr);
437 
438 	//-------------- multiplayer checking codes ---------------//
439 	virtual	uint8_t crc8();
440 	virtual	void	clear_ptr();
441 };
442 #pragma pack()
443 
444 //--------------------------------------//
445 
446 //### begin alex 12/8 ###//
447 extern short nation_hand_over_flag; // 0 for no nation hand over, 1-MAX_NATION for nation hand over
448 //#### end alex 12/8 ####//
449 #endif
450