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    : OWORLD.H
22 //Description : Header file of Object World
23 
24 #ifndef __OWORLD_H
25 #define __OWORLD_H
26 
27 #ifndef __OWORLDMT_H
28 #include <OWORLDMT.h>
29 #endif
30 
31 #ifndef __ALL_H
32 #include <ALL.h>
33 #endif
34 
35 #ifndef __OUNITRES_H
36 #include <OUNITRES.h>
37 #endif
38 
39 //----------- Define constant ------------//
40 
41 #define EXPLORE_RANGE   10
42 #define SCAN_FIRE_DIST 4
43 
44 //--------------- Define constant -----------------//
45 
46 #define MIN_LAND_COST   500000       // Minimum land cost even there is no population at all
47 
48 //------- define terrain map --------//
49 
50 #define MIN_GRASS_HEIGHT    100
51 #define MIN_HILL_HEIGHT  	 230
52 #define MIN_MOUNTAIN_HEIGHT 242
53 #define MIN_ICE_HEIGHT 		 252
54 
55 //---------------- Define class World -------------//
56 
57 class Weather;
58 class Plasma;
59 
60 class World
61 {
62 public:
63 	MapMatrix    *map_matrix;
64 	ZoomMatrix   *zoom_matrix;
65 	Location     *loc_matrix;
66 
67 	unsigned long	 		 next_scroll_time;		 // next scroll time
68 
69 	char			 scan_fire_x;				// cycle from 0 to SCAN_FIRE_DIST-1
70 	char			 scan_fire_y;
71 	char			 lightning_signal;
72 	int			 plant_count;
73 	int			 plant_limit;
74 
75 	//--------- static member vars --------------//
76 
77 	static short view_top_x, view_top_y;		// the view window in the scene, they are relative coordinations on the entire virtual surface.
78 	static int   max_x_loc , max_y_loc;		   // these must be static vars as MAX_WORLD_X_LOC & MAX_WORLD_Y_LOC are defined to use them.
79 
80 public:
81 	World();
82 	~World();
83 
84 	void 		init();
85 	void 		deinit();
86 
87 	void 		generate_map();
88 	void 		assign_map();
89 
90 	void 		paint();
91 	void 		refresh();
disp_zoom()92 	void		disp_zoom()		{ zoom_matrix->disp(); }
93 
94 	void		load_map(char*);
95 
96 	int  		detect();
97 	// ###### begin Gilbert 16/9 ########//
98 	int		detect_firm_town();
99 	// ###### end Gilbert 16/9 ########//
100 	void 		go_loc(int xLoc, int yLoc, int selectedFlag=0);
101 	void		disp_next(int seekDir, int sameNation);
102 
103 	int  		write_file(File*);
104 	int  		read_file(File*);
105 
106 public:
107 	#ifdef DEBUG3
108 		Location* get_loc(int xLoc,int yLoc);
109 		uint8_t		 get_region_id(int xLoc,int yLoc);
110 	#else
111 		Location* get_loc(int xLoc,int yLoc)
112 						{ return loc_matrix + MAX_WORLD_X_LOC * yLoc + xLoc; }
113 
114 		uint8_t		 get_region_id(int xLoc,int yLoc)
115 						{ return loc_matrix[MAX_WORLD_X_LOC*yLoc+xLoc].region_id; }
116 	#endif
117 
118 	short		get_unit_recno(int xLoc,int yLoc, int mobileType);
119 	void 		set_unit_recno(int xLoc, int yLoc, int mobileType, int newCargoRecno);
120 
121 	int 		distance_rating(int xLoc1, int yLoc1, int xLoc2, int yLoc2);
122 
123 	void		unveil(int xLoc1, int yLoc1, int xLoc2, int yLoc2);
124 	void		explore(int xLoc1, int yLoc1, int xLoc2, int yLoc2);
125 	int  		is_explored(int xLoc1, int yLoc1, int xLoc2, int yLoc2);
126 	// always call unveil before visit //
127 	void		visit(int xLoc1, int yLoc1, int xLoc2, int yLoc2, int range, int extend =0);
128 	void		visit_shell(int xLoc1, int yLoc1, int xLoc2, int yLoc2, int visitLevel);
129 
130 	int		can_build_firm(int xLoc1, int yLoc1, int firmId, short unitRecno= -1);
131 	int		can_build_town(int xLoc1, int yLoc1, short unitRecno= -1);
132 	int		can_build_wall(int xLoc1, int yLoc1, short nationRecno);
133 	int		can_destruct_wall(int xLoc1, int yLoc1, short nationRecno);
134 	void		build_wall_tile(int xLoc1, int yLoc1, short nationRecno, char remoteAction);
135 	void		destruct_wall_tile(int xLoc1, int yLoc1, short nationRecno, char remoteAction);
136 
137 	int 		locate_space(int* /*in/out*/ xLoc1, int* /*in/out*/ yLoc1, int xLoc2, int yLoc2,
138 										int spaceLocWidth, int spaceLocHeight, int mobileType=UNIT_LAND, int regionId=0, int buildFlag=0);
139 	int		check_unit_space(int xLoc1, int yLoc1, int xLoc2, int yLoc2, int mobileType=UNIT_LAND, int buildFlag=0);
140 
141 	int 		locate_space_random(int& xLoc1, int& yLoc1, int xLoc2, int yLoc2,
142 										  int spaceLocWidth, int spaceLocHeight, int maxTries,
143 										  int regionId=0, int buildSite=0, char teraMask=1);
144 	int		is_adjacent_region( int x, int y, int regionId );
145 
146 	void 		draw_link_line(int srcFirmId, int srcTownRecno, int srcXLoc1, int srcYLoc1, int srcXLoc2, int srcYLoc2, int giveEffectiveDis=0);
147 
148 	void 		set_all_power();
149 	void 		set_power(int xLoc1, int yLoc1, int xLoc2, int yLoc2, int nationRecno);
150 	void 		restore_power(int xLoc1, int yLoc1, int xLoc2, int yLoc2, int townRecno, int firmRecno);
151 	void		set_surr_power_off(int xLoc, int yLoc);
152 
153 	void		process();
154 	void		process_visibility();
155 	void		next_day();
156 
157 	//------- functions related to plant's growth, see ow_plant.cpp -----//
158 
159 	void		plant_ops();
160 	void		plant_grow(int pGrow =4, int scanDensity =8);
161 	void		plant_reprod(int pRepord =1, int scanDensity =8);
162 	void		plant_death(int scanDensity =8);
163 	void		plant_spread(int pSpread =5);
164 	void		plant_init();
165 	void		plant_spray(short *plantIdArray, char strength, short x, short y);
166 
167 	//------- functions related to fire's spreading, see ow_fire.cpp ----//
168 
169 	void		init_fire();
170 	void		spread_fire(Weather &);
171 	void		setup_fire(short x, short y, char fireStrength = 30);
172 
173 	//------- function related to city wall ----------//
174 	void		build_wall_section(short x1, short y1, short x2, short y2,
175 				short townRecno, short initHp = 99);
176 	void		build_wall(int townRecno, short initHp = 99);
177 
178 	void		open_west_gate(short x2, short y1, short townRecno);
179 	void		open_east_gate(short x1, short y1, short townRecno);
180 	void		open_north_gate(short x1, short y2, short townRecno);
181 	void		open_south_gate(short x1, short y1, short townRecno);
182 
183 	int		form_wall(short x, short y, short maxRecur=0);
184 	void		form_world_wall();
185 	int		correct_wall(short x, short y, short maxRecur=2);
186 
187 	//-------- function related to rock ----------//
188 	void		add_rock(short rockRecno, short x1, short y1);
189 	void		add_dirt(short dirtRecno, short x1, short y1);
190 	// ###### begin Gilbert 22/9 ######//
191 	int		can_add_rock(short x1, short y1, short x2, short y2);
192 	int		can_add_dirt(short x1, short y1, short x2, short y2);
193 	// ###### end Gilbert 22/9 ######//
194 
195 	// ------ function related to weather ---------//
196 
197    void     earth_quake();
198    void     lightning_strike(short x, short y, short radius=0);
199 
200 private:
201 	int	  	detect_scroll();
202 	// int		detect_firm_town();
203 
204 	//--------- ambient sound functions --------//
205 
206 	void		process_ambient_sound();
207 
208 	//--- called by generate_map() only ---//
209 
210 	void    add_base_level();
211 	void    gen_plasma_map();
212 	void    set_tera_id(Plasma &);
213 	void    remove_odd(Plasma &, short x, short y, short recur);
214 	void    set_climate();
215 	void	  set_loc_flags();
216 	void	  substitute_pattern();
217 	void    set_region_id();
218 	void    fill_region(short x, short y);
219 	// ####### begin Gilbert 22/9 ########//
220 	void    gen_rocks(int nGrouped, int nLarge, int nSmall);
221 	void    gen_dirt(int nGrouped, int nLarge, int nSmall);
222 	// ####### end Gilbert 22/9 ########//
223 	void    set_harbor_bit();
224 
225 	// private function called by build_wall_section
226 	int	can_build_area(short x1, short y1, short x2, short y2);
227 	void	build_west_gate(short x1, short y1, short townRec, short initHp);
228 	void	build_east_gate(short x1, short y1, short townRec, short initHp);
229 	void	build_north_gate(short x1, short y1, short townRec, short initHp);
230 	void	build_south_gate(short x1, short y1, short townRec, short initHp);
231 
232 	void	build_west_wall(short x1, short y1, short y2, short townRec, short initHp);
233 	void	build_east_wall(short x1, short y1, short y2, short townRec, short initHp);
234 	void	build_north_wall(short x1, short x2, short y1, short townRec, short initHp);
235 	void	build_south_wall(short x1, short x2, short y1, short townRec, short initHp);
236 
237 	// see OGENHILL.CPP
238 	void	gen_hills(int terrainType);
239 	void	put_hill_set(short *px, short *py, short hSetId);
240 	void	put_hill_pattern(short *px, short *py, unsigned char patternId);
241 	void	fill_hill(short x, short y);
242 };
243 
244 //-------- Begin of function World::get_unit_recno -------//
245 
get_unit_recno(int xLoc,int yLoc,int mobileType)246 inline short World::get_unit_recno(int xLoc, int yLoc, int mobileType)
247 {
248 	if( mobileType==UNIT_AIR )
249 		return loc_matrix[MAX_WORLD_X_LOC*yLoc+xLoc].air_cargo_recno;
250 	else
251 		return loc_matrix[MAX_WORLD_X_LOC*yLoc+xLoc].cargo_recno;
252 }
253 //--------- End of function World::get_unit_recno -------//
254 
255 
256 //-------- Begin of function World::set_unit_recno -------//
257 
set_unit_recno(int xLoc,int yLoc,int mobileType,int newCargoRecno)258 inline void World::set_unit_recno(int xLoc,int yLoc, int mobileType, int newCargoRecno)
259 {
260 	if( mobileType==UNIT_AIR )
261 		loc_matrix[MAX_WORLD_X_LOC*yLoc+xLoc].air_cargo_recno = newCargoRecno;
262 	else
263 		loc_matrix[MAX_WORLD_X_LOC*yLoc+xLoc].cargo_recno = newCargoRecno;
264 
265 	err_when(mobileType!=UNIT_AIR && loc_matrix[MAX_WORLD_X_LOC*yLoc+xLoc].is_firm());
266 }
267 //--------- End of function World::set_unit_recno -------//
268 
269 
270 //--------- Begin of function World::distance_rating --------//
271 //
distance_rating(int xLoc1,int yLoc1,int xLoc2,int yLoc2)272 inline int World::distance_rating(int xLoc1, int yLoc1, int xLoc2, int yLoc2)
273 {
274 	int curDistance = misc.points_distance(xLoc1, yLoc1, xLoc2, yLoc2);
275 
276 	return 100 - 100 * curDistance / MAX_WORLD_X_LOC;
277 }
278 //----------- End of function World::distance_rating --------//
279 
280 
281 extern World world;
282 
283 #endif
284