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    : OFIRM.H
22 //Description : Header file of Object Firm
23 
24 #ifndef __OFIRM_H
25 #define __OFIRM_H
26 
27 #ifndef __GAMEDEF_H
28 #include <GAMEDEF.h>
29 #endif
30 
31 #ifndef __OFIRMA_H
32 #include <OFIRMA.h>
33 #endif
34 
35 #ifndef __OINFO_H
36 #include <OINFO.h>
37 #endif
38 
39 #ifndef __OFIRMID_H
40 #include <OFIRMID.h>
41 #endif
42 
43 #ifndef __OFIRMRES_H
44 #include <OFIRMRES.h>
45 #endif
46 
47 #ifndef __OSKILL_H
48 #include <OSKILL.h>
49 #endif
50 
51 //----------- Define constant ------------//
52 
53 #define MAX_WORKER         	 8       // maximum no. of workers in a firm
54 #define MAX_CARGO					 9
55 
56 #define WORKER_YEAR_SALARY    10
57 
58 #define CAN_SELL_HIT_POINTS_PERCENT	 80		// only when the firm's hit points is higher than this can the firm be sold
59 
60 //------- define firm menu modes --------//
61 
62 enum { FIRM_MENU_MAIN,
63 		 FIRM_MENU_SPY,
64 		 FIRM_MENU_SELECT_BRIBER,
65 		 FIRM_MENU_SET_BRIBE_AMOUNT,
66 		 FIRM_MENU_VIEW_SECRET,
67 		 FIRM_MENU_ASSASSINATE_RESULT };
68 
69 //------- define parameters for ai_status, used for AI ------//
70 
71 enum	{	FIRM_WITHOUT_ACTION=0,
72 			FACTORY_RELOCATE,
73 			MARKET_FOR_SELL,
74 			CAMP_IN_DEFENSE,
75 		};
76 
77 //-------- define values for Firm::bribe_result -------//
78 
79 enum { BRIBE_NONE,
80 		 BRIBE_SUCCEED,
81 		 BRIBE_FAIL,
82 	  };
83 
84 //-------- define values for Firm::assassinate_result -------//
85 
86 enum { ASSASSINATE_FAIL,
87 		 ASSASSINATE_SUCCEED_AT_LARGE,		// assassination succeed and the assassinator is at large
88 		 ASSASSINATE_SUCCEED_KILLED,			// assassination succeed and the assassinator is caught and executed
89 	  };
90 
91 //------------- Define struct Worker ------------//
92 
93 #pragma pack(1)
94 struct Worker
95 {
96 public:
97 	Worker();
98 
99 	char  race_id;
100 	char  unit_id;
101 	short town_recno;
102 	uint16_t name_id;
103 
104 	char	skill_id;
105 	char  skill_level;
106 	char  skill_level_minor;
107 	char  skill_potential;
108 
109 	char  combat_level;
110 	char  combat_level_minor;
111 
112 	short spy_recno;
113 
114 	char  rank_id;
115 	char  worker_loyalty;		// only for firms with live_in_town being 0
116 	short hit_points;
117 	short extra_para;			// weapon version for weapons and power attack points for human units
118 
119 	short	max_hit_points();
120 	int   loyalty();
121 	int	target_loyalty(int firmRecno);
122 	int	is_nation(int firmRecno, int nationRecno, int checkSpy=0);
123 
124 public:
125 	void	init_potential();
126 	char *small_icon_ptr();
127 	void  change_loyalty(int loyaltyChange);
128 	void	change_hit_points(int changePoints);
129 	int	max_attack_range();
130 };
131 #pragma pack()
132 
133 struct FirmCrc;
134 class FirmBase;
135 class FirmMine;
136 class FirmFactory;
137 class FirmMarket;
138 class FirmCamp;
139 class FirmFarm;
140 class FirmInn;
141 class FirmResearch;
142 class FirmWar;
143 class FirmHarbor;
144 
145 //----------- Define class Firm ------------//
146 
147 #pragma pack(1)
148 class Firm
149 {
150 public:
151 	char   firm_id;            // Firm ID, meanings are defined in OFIRMID.H
152 	short  firm_build_id;
153 	short  firm_recno;         // record no. of this firm in the firm_array
154 	char   firm_ai;            // whether Computer AI control this firm or not
155 	char	 ai_processed;			// some ai actions are processed once only in the processing day. To prevent multiple checking in the processing day
156 	char	 ai_status;
157 	char	 ai_link_checked;		// AI checks firms and towns location by links, disable checking by setting this parameter to 1
158 	char	 ai_sell_flag;			// this is true if the AI has queued the command to sell this firm
159 
160 	char   race_id;
161 	short  nation_recno;       // this firm's parent company nation
162 	char   majority_race();		// the race that has the majority of the population
163 	int    own_firm();         // whether the firm is controlled by the current player
can_sell()164 	int	 can_sell() 		{ return hit_points >= (int) max_hit_points * CAN_SELL_HIT_POINTS_PERCENT / 100; }
165 
166 	//-------- firm name vars ---------//
167 
168 	short	 closest_town_name_id;			// name id. of the town that is closest to this firm when it is built
169 	short	 firm_name_instance_id;
170 	virtual char*	 firm_name();
171 
172 	//--------- display info ----------//
173 
174 	short  loc_x1, loc_y1, loc_x2, loc_y2;
175 	short  abs_x1, abs_y1, abs_x2, abs_y2;
176 	short  center_x, center_y;
177 	uint8_t	 region_id;
178 
179 	char   cur_frame;          // current animation frame id.
180 	char   remain_frame_delay;
181 
182 	//---------- game vars ------------//
183 
184 	float  hit_points;
185 	float  max_hit_points;
186 	char	 under_construction;		// whether the firm is under construction
187 
188 	char   firm_skill_id;
189 	short  overseer_recno;
190 	short  overseer_town_recno;
191 	short	 builder_recno;		// the recno of the builder
192 	uint8_t 	 builder_region_id;	// the original region no. of builder
193 	float  productivity;
194 
195 	Worker* worker_array;
196 	char   worker_count;
197 	char   selected_worker_id;
198 
199 	char	 player_spy_count;
200 	uint8_t	 sabotage_level;			// 0-100 for counter productivity
201 
202 	int	 average_worker_skill();
203 
is_operating()204 	virtual int is_operating()		{ return productivity > 0; }
205 
206 	//------ inter-relationship -------//
207 
208 	char 	 linked_firm_count;
209 	char 	 linked_town_count;
210 
211 	short	 linked_firm_array[MAX_LINKED_FIRM_FIRM];
212 	short	 linked_town_array[MAX_LINKED_FIRM_TOWN];
213 
214 	char 	 linked_firm_enable_array[MAX_LINKED_FIRM_FIRM];
215 	char 	 linked_town_enable_array[MAX_LINKED_FIRM_TOWN];
216 
217 	//--------- financial vars ---------//
218 
219 	float  last_year_income;
220 	float  cur_year_income;
221 
income_365days()222 	float  income_365days()      { return last_year_income*(365-info.year_day)/365 +
223 											cur_year_income; }
224 	int	 year_expense();
225 
226 	//---------------------------------//
227 
228 	int    setup_date;             // the date which this firm is setup
229 	char*  setup_years_str(int=0); // return the no. of years this firm has been setup in string
230 
231 	char	 should_set_power;
232 	int 	 last_attacked_date;		 // the date when the firm was last being attacked.
233 
234 	//----------- AI vars ------------//
235 
236 	char	 should_close_flag;
237 	char	 no_neighbor_space;			// no space to build firms/towns next to this town
238 	char	 ai_should_build_factory_count;
239 
240 	//--------- static vars ----------//
241 
242 	static char  firm_menu_mode;
243 	static short action_spy_recno;	// recno of the spy that is doing the bribing or viewing secret reports of other nations
244 	static char  bribe_result;
245 	static char  assassinate_result;
246 
247 public:
248 	Firm();
249 	virtual ~Firm();
250 
251 	virtual void init(int xLoc, int yLoc, int nationRecno, int firmId, const char* buildCode=NULL, short builderRecno=0);
252 	virtual void deinit();
253 
254 	void		init_name();
255 	int 		get_closest_town_name_id();
256 
257    virtual void assign_unit(int unitRecno);
258    virtual void assign_overseer(int overseerUnitRecno);
259    virtual void assign_worker(int workerUnitRecno);
260 
261 	void		kill_overseer();
262 	void		kill_all_worker();
263 	void		kill_worker(int workerId);
264 	void		kill_builder(short builderRecno);
265 
266 	virtual void being_attacked(int attackerUnitRecno);
267 
268 	virtual int	 pull_town_people(int townRecno, char remoteAction, int raceId=0, int forcePull=0);
resign_overseer()269 	void 		resign_overseer()		{ assign_overseer(0); }
270 
271 	void     set_world_matrix();
272 	void     restore_world_matrix();
273 	int		get_should_set_power();
274 
275 	void 		establish_contact_with_player();
276 	void		complete_construction();		// complete construction instantly
277 
278 	void		capture_firm(int newNationRecno);
279 	virtual void change_nation(int newNationRecno);
280 
281 	void		setup_link();
282 	void		release_link();
283 	void		release_firm_link(int);
284 	void		release_town_link(int);
285 
286 	int 		can_toggle_town_link();
287 	int 		can_toggle_firm_link(int firmRecno);
288 
289 	int      is_in_zoom_win();
290 	int		find_settle_town();
291 	int 		should_show_info();
292 
293 	int		set_builder(short newBuilderRecno);
294 
295 	virtual void sell_firm(char remoteAction);
296 	void		destruct_firm(char remoteAction);
297 	void		cancel_construction(char remoteAction);
298 	int		can_assign_capture();
299 	int		can_worker_capture(int captureNationRecno);
300 	virtual int	 is_worker_full();
301 	int		have_own_workers(int checkSpy=0);
302 
303 	void 		set_worker_home_town(int townRecno, char remoteAction, int workerId=0);
304 	int 		can_spy_bribe(int bribeWorkerId, int briberNationRecno);
305 	int 		spy_bribe(int bribeAmount, short briber, short workerId);
306 	int 		spy_bribe_succeed_chance(int bribeAmount, short briberSpyRecno, short workerId);
307 	int 		validate_cur_bribe();
308 
309 	//------------------- defense --------------------//
310 	virtual void auto_defense(short targetRecno);
311 
312 	int		locate_space(int removeFirm, int &xLoc, int &yLoc, int xLoc2, int yLoc2, int width, int height, int mobileType=UNIT_LAND, int regionId=0);
313 	//---------------------------------------//
314 
315 	virtual void draw(int displayLayer=1);
316 	virtual void draw_full_size(int displayLayer=1);
317 	virtual void draw_frame(int frameId, int displayLayer=1);
318 			  void draw_selected();
319 			  int  draw_detect_link_line(int actionDetect);
320 
321 			  void disp_info_both(int refreshFlag);
322 			  void detect_info_both();
323 
put_info(int refreshFlag)324 	virtual void put_info(int refreshFlag)		{;}
detect_info()325 	virtual int  detect_info()						{;}
326 			  void sort_worker();
327 
328 	 		  void process_animation();
329 			  void process_construction();
330            void process_repair();
331 
332 			  void process_common_ai();
process_ai()333 	virtual void process_ai()      {;}
process_tell()334 	virtual void process_tell()    {;}
335 
336 	virtual void next_day();
337 	virtual void next_month();
338 	virtual void next_year();
339 
340 			  void mobilize_all_workers(char remoteAction);
341 	virtual int	 mobilize_worker(int workerId, char remoteAction);
342 			  int	 create_worker_unit(Worker& thisWorker);
343 	virtual int  mobilize_overseer();
344 			  int	 mobilize_builder(short recno);
345 
346 			  void resign_all_worker(int disappearFlag=0);
347 	virtual int  resign_worker(int workerId);
348 
349 			  void reward(int workerId, int remoteAction);
350 
351 			  void toggle_firm_link(int linkId, int toggleFlag, char remoteAction, int setBoth=0);
352 			  void toggle_town_link(int linkId, int toggleFlag, char remoteAction, int setBoth=0);
353 
354 	virtual int  write_derived_file(File*);
355 	virtual int  read_derived_file(File*);
356 
cast_to_FirmBase()357 	virtual FirmBase*		cast_to_FirmBase() { return 0; };
cast_to_FirmMine()358 	virtual FirmMine*		cast_to_FirmMine() { return 0; };
cast_to_FirmFactory()359 	virtual FirmFactory*	cast_to_FirmFactory() { return 0; };
cast_to_FirmMarket()360 	virtual FirmMarket*	cast_to_FirmMarket() { return 0; };
cast_to_FirmCamp()361 	virtual FirmCamp*		cast_to_FirmCamp() { return 0; };
cast_to_FirmFarm()362 	virtual FirmFarm*		cast_to_FirmFarm() { return 0; };
cast_to_FirmInn()363 	virtual FirmInn*		cast_to_FirmInn() { return 0; };
cast_to_FirmResearch()364 	virtual FirmResearch* cast_to_FirmResearch() { return 0; };
cast_to_FirmWar()365 	virtual FirmWar*		cast_to_FirmWar() { return 0; };
cast_to_FirmHarbor()366 	virtual FirmHarbor*	cast_to_FirmHarbor() { return 0; };
367 
368 	//---------- AI functions ----------//
369 
370 			  void 			think_repair();
371 			  void			ai_del_firm();
372 			  int 			ai_recruit_worker();
ai_has_excess_worker()373 	virtual int	   		ai_has_excess_worker()	 { return 0; }		// whether the AI has excess workers on this firm or not
374 			  int				think_build_factory(int rawId);
375 	virtual int				ai_should_close();
376 			  int 			ai_build_neighbor_firm(int firmId);
377 	virtual void			ai_update_link_status();
378 			  int 			think_hire_inn_unit();
379 			  int				think_capture();
380 	virtual void 			think_linked_town_change_nation(int linkedTownRecno, int oldNationRecno, int newNationRecno);
381 			  void 			ai_firm_captured(int capturerNationRecno);
382 
383 	//-------------- multiplayer checking codes ---------------//
384 	virtual	uint8_t crc8();
385 	virtual	void	clear_ptr();
386 	virtual	void	init_crc(FirmCrc *c);
387 
388    //---------------------------------------//
389 
390 protected:
init_derived()391 	virtual void init_derived()   {;}
deinit_derived()392 	virtual void deinit_derived() {;}
393 
394 			  void recruit_worker();
395 			  void free_worker_room();
396 			  int  assign_settle(int raceId, int unitLoyalty, int isOverseer);
397 			  int	 best_worker_id();
398 
399 			  void calc_productivity();
400 			  void update_worker();
401 			  void add_income(int incomeType, float incomeAmt);
402 			  void pay_expense();
403 			  void consume_food();
404 			  void update_loyalty();
405 
406            void think_worker_migrate();
407 			  void worker_migrate(int workerId, int destTownZoneRecno, int newLoyalty);
408 			  void process_independent_town_worker();
409 
410 			  void disp_spy_button(int x, int y, int refreshFlag);
411 			  int  detect_spy_button();
412 			  void disp_spy_menu(int refreshFlag);
413 			  void detect_spy_menu();
414 			  int  can_player_spy_capture();
415 
416 			  void disp_bribe_menu(int refreshFlag);
417 			  void detect_bribe_menu();
418 			  void spy_bribe(int bribeAmount);
419 			  void disp_bribe_unit(int dispY1);
420 
421 			  void disp_assassinate_result(int refreshFlag);
422 			  void detect_assassinate_result();
423 
424 			  void disp_worker_list(int dispY1, int refreshFlag);
425 			  int  detect_worker_list();
426            void disp_basic_info(int dispY1, int refreshFlag);
427 			  int  detect_basic_info();
428 			  void disp_worker_info(int dispY1, int refreshFlag);
429 			  void disp_overseer_info(int dispY1, int refreshFlag);
430 
431 			  void draw_cargo(int cargoCount, char* cargoBitmapPtr);
432 
433 				int create_unit(int unitId, int townZoneRecno=0, int unitHasJob=0);
434 			  void disp_hit_point(int dispY1);
435 			  // ##### begin Gilbert 18/10 #######//
436 			  int	construction_frame();			// for under construction only
437 			  // ##### end Gilbert 18/10 #######//
438 };
439 #pragma pack()
440 
441 //------------------------------------------//
442 
443 #endif
444 
445