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    : OSPREUSE.H
22 //Description : Header file of Object SeekPathReuse
23 //Owner		  : Alex
24 
25 #ifndef __OSPREUSE_H
26 #define __OSPREUSE_H
27 
28 #ifndef	__OSPATH_H
29 #include <OSPATH.h>
30 #endif
31 
32 #ifndef __ALL_H
33 #include <ALL.h>
34 #endif
35 
36 #ifndef __OWORLD_H
37 #define <OWORLD.H>
38 #endif
39 
40 //---------- Define constants ------------//
41 enum{	REUSE_PATH_INITIAL=1,			// 0 is used for other searching call with no path reuse, or for error checking
42 		REUSE_PATH_FIRST_SEEK,
43 		REUSE_PATH_SEARCH,
44 		//REUSE_PATH_FOUND,
45 		//REUSE_PATH_IMPOSSIBLE,
46 		REUSE_PATH_INCOMPLETE_SEARCH,
47 	 };
48 
49 enum{	GENERAL_GROUP_MOVEMENT = 1,	// 0 is used for error checking
50 		FORMATION_MOVEMENT,
51 	 };
52 
53 #define RNA_RESET_AMOUNT	10
54 
55 //---------- Define class SeekPathReuse -----------//
56 class SeekPathReuse
57 {
58 	public:
59 		char			incomplete_search;
60 
61 		static int				max_node;				// MAX number of node used in searching
62 		static short			total_num_of_path;	// equal to number of unit to process path-reuse
63 		static short			cur_path_num;			// which unit in the group is processing path-reuse
64 		static short			unit_size;				// the size of the current unit
65 		static uint32_t			cur_group_id;			// group id used to pass into SeekPath for searching
66 		static char				mobile_type;			// mobile type used to pass into SeekPath for searching
67 		static char				unit_nation_recno;	// the nation recno of this unit
68 		static short			move_scale;				// 1 for UNIT_LAND, 2 for others
69 		static short			search_mode;			// search mode to check whether path-reuse is used
70 		static short			reuse_mode;				// reuse mode, general or formation movement of path-reuse
71 		static short			reuse_path_status;	// initial, seek first or reuse
72 		static short			reuse_path_dist;		// count the reuse-path distance
73 		static short			*reuse_node_matrix;	// point to the node matrix that store offset path for reusing
74 
75 		static char				reuse_nation_passable[MAX_NATION+1]; // Note: position 0 is not used for faster access
76 		static char				reuse_search_sub_mode;
77 
78 		//----------------- backup leader path(reference path) ----------------------//
79 		static short			leader_path_num;	//------------------------------------------------------------------------------------------------//
80 															// usually the unit calling with pathReuseStatus==REUSE_PATH_FIRST_SEEK should be the leader.
81 															// However, in some condition, e.g. leader_num_of_node<2, another unit will be selected
82 															// to be the leader. This variable stores which path number is selected to be the new leader path.
83 															//------------------------------------------------------------------------------------------------//
84 		static ResultNode		*reuse_leader_path_backup;
85 		static int				reuse_leader_path_node_num;
86 		static int				leader_path_start_x;
87 		static int				leader_path_start_y;
88 		static int				leader_path_dest_x;
89 		static int				leader_path_dest_y;
90 
91 		//----------- decide which offset method is used ----------//
92 		// some will be removed later
93 		static int				start_x_offset;		// x offset in the starting location refer to that of leader unit
94 		static int				start_y_offset;		// y offset in the starting location refer to that of leader unit
95 		static int				dest_x_offset;			// x offset in the destination refer to that of leader unit
96 		static int				dest_y_offset;			// y offset in the destination refer to that of leader unit
97 		static int				x_offset;				// the x offset used in generating the offset path
98 		static int				y_offset;				// the y offset used in generating the offset path
99 		static int				formation_x_offset;	// formation x offset
100 		static int				formation_y_offset;	// formation y offset
101 		static int				start_x;					// the x location of the unit starting point
102 		static int				start_y;					// the y location of the unit starting point
103 		static int				dest_x;					// the x location of the unit destination
104 		static int				dest_y;					// the y location of the unit destination
105 		static int				vir_dest_x;
106 		static int				vir_dest_y;
107 
108 		//---------- the current constructing result path --------//
109 		static ResultNode		*path_reuse_result_node_ptr;		// store the reuse path result node
110 		static int				num_of_result_node;					// store the number of result node of the reuse path
111 		static ResultNode		*cur_result_node_ptr;				// point to the current result node used in the result node array
112 
113 		static short			result_node_array_def_size;		// the current node of node in the result node array
114 		static short			result_node_array_reset_amount;	// the default size to adjust in the result node array each time
115 
116 		//-- determine the current offset difference(leader path information) --//
117 		static ResultNode		*cur_leader_node_ptr;	// point to the leader result node backup array
118 		static int				cur_leader_node_num;		// current number of node used in the leader backup node array
119 
120 		static short			leader_vec_x;			// the current unit vector in x-direction in the leader path
121 		static short			leader_vec_y;			// the current unit vector in y-direction in teh leader path
122 
123 		//----------- for smoothing the result path --------------//
124 		static short			vec_x, vec_y;
125 		static short			new_vec_x, new_vec_y;
126 		static int				vec_magn, new_vec_magn;
127 		static int				result_vec_x, result_vec_y;
128 
129 	public:
130 
131 		void			init(int maxNode);
132 		void			deinit();
133 		void			init_reuse_search();		// init data structure
134 		void			deinit_reuse_search();	// deinit data structure
135 		void			init_reuse_node_matrix();
136 		void			set_index_in_node_matrix(int xLoc, int yLoc);
137 
138 		int			seek(int sx,int sy,int dx,int dy,short unitSize, uint32_t groupId,char mobileType, short searchMode=4, short miscNo=0,
139 							 short numOfPath=1, short pathReuseStatus=REUSE_PATH_INITIAL, short reuseMode=GENERAL_GROUP_MOVEMENT,
140 							 int maxTries=0,int borderX1=0, int borderY1=0, int borderX2=MAX_WORLD_X_LOC-1, int borderY2=MAX_WORLD_Y_LOC-1);
141 		ResultNode* get_result(int& resultNodeCount, short& pathDist);
call_seek(int sx,int sy,int dx,int dy,uint32_t groupId,char mobileType,short searchMode,int & nodeCount)142 		inline ResultNode* call_seek(int sx, int sy, int dx, int dy, uint32_t groupId, char mobileType, short searchMode, int& nodeCount)
143 						{	seek_path.seek(sx, sy, dx, dy, groupId, mobileType, searchMode);
144 							return seek_path.get_result(nodeCount, reuse_path_dist);
145 						}
146 		short			count_path_dist(ResultNode* nodeArray, int nodeNum);
147 
148 		void			extend_result_path(short addSize=RNA_RESET_AMOUNT);
149 		void			add_result(int x, int y);	// record the result node in the node array
150 		void			add_result_path(ResultNode *pathPtr, int nodeNum);
151 		void			set_offset_condition(int startXOffset=0, int startYOffset=0, int destXOffset=0, int destYOffset=0);
152 		int			get_next_offset_loc(int& nextXLoc, int& nextYLoc);
153 		int			get_next_nonblocked_offset_loc(int& nextXLoc, int&nextYLoc);
154 		void			set_next_cur_path_num();
155 
156 		void			seek_path_offset();	// process the offset method to get the shortest path
157 		void			seek_path_join_offset();
158 		void			use_offset_method(int xLoc, int yLoc);
159 
bound_check_x(int & x)160 		inline void	bound_check_x(int& x)
161 						{ if(x<0) x = 0; else if(x>=MAX_WORLD_X_LOC)	x = MAX_WORLD_X_LOC-move_scale; }
bound_check_y(int & y)162 		inline void	bound_check_y(int& y)
163 						{ if(y<0) y = 0; else if(y>=MAX_WORLD_X_LOC)	y = MAX_WORLD_X_LOC-move_scale; }
164 		char			get_reuse_path_status();
165 
166 		void			set_nation_passable(char nationPassable[]);
167 		void			set_sub_mode(char subMode=SEARCH_SUB_MODE_NORMAL);
168 		void			set_status(char newStatus);
169 
170 		//-------------- for optimize the result path ----------------//
171 		void			remove_duplicate_node(ResultNode* resultList, int& nodeCount);	// remove duplicate node in the node array
172 		ResultNode*	smooth_reuse_path(ResultNode* resultPath, int& resultNodeNum);	// smoothing the reuse path
173 		ResultNode*	smooth_path(ResultNode* resultPath, int& resultNodeNum);			// smooth any path, subset of smooth_reuse_path()
174 		ResultNode*	smooth_path2(ResultNode* resultPath, int& resultNodeNum);			// version for UNIT_SEA, UNIT_AIR
175 
176 		//-------------- for node limitation -----------------//
177 		int			is_node_avail_empty();
178 		int			is_leader_path_valid();
179 		void			copy_leader_path_offset();
180 		void			move_within_map(int preX, int preY, int curX, int curY);
181 		void			move_inside_map(int preX, int preY, int curX, int curY);
182 		void			move_outside_map(int preX, int preY, int curX, int curY);
183 		void			move_beyond_map(int preX, int preY, int curX, int curY);
184 
185 	public:
186 		static int	can_walk(int xLoc, int yLoc);
187 		static int	can_walk_s2(int xLoc, int yLoc);
188 		static void	sys_yield();
189 
190 		#ifdef DEBUG
191 		void			debug_check();
192 		void			debug_check_magnitude(int x1, int y1, int x2, int y2);
193 		void			debug_check_smode_node(int x, int y);
194 		void			debug_check_sub_mode_path(ResultNode *nodeArray, int count);
195 		#endif
196 
197 		#ifdef DEBUG
198 		#define debug_reuse_check_path()								debug_check()
199 		#define debug_reuse_check_xy_magn(x1, y1, x2, y2)		debug_check_magnitude((x1), (y1), (x2), (y2))
200 		#define debug_reuse_check_sub_mode_node(x, y)			debug_check_smode_node((x), (y))
201 		#define debug_reuse_check_sub_mode(nodeArray, count)	debug_check_sub_mode_path((nodeArray), (count))
202 		#else
203 		#define debug_reuse_check_path()
204 		#define debug_reuse_check_xy_magn(x1, y1, x2, y2)
205 		#define debug_reuse_check_sub_mode_node(x, y)
206 		#define debug_reuse_check_sub_mode(nodeArray, count)
207 		#endif
208 
209 	protected:
210 	private:
211 };
212 
213 extern SeekPathReuse seek_path_reuse;
214 
215 #endif