File: OSPATH.h

package info (click to toggle)
7kaa 2.15.7%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 134,980 kB
  • sloc: cpp: 137,722; ansic: 3,599; asm: 3,523; perl: 1,665; makefile: 1,185; sh: 185; pascal: 27
file content (254 lines) | stat: -rw-r--r-- 8,639 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
/*
 * Seven Kingdoms: Ancient Adversaries
 *
 * Copyright 1997,1998 Enlight Software Ltd.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

//Filename    : OSPATH.H
//Description : Header file of Object SeekPath
//Owner		  : Alex

#ifndef __OSPATH_H
#define __OSPATH_H

#ifndef __ALL_H
#include <ALL.h>
#endif

#ifndef __OVGA_H
#include <OVGA.h>
#endif

#ifndef __OWORLD_H
#include <OWORLD.h>
#endif

//---------- Define constants ------------//

enum { PATH_WAIT,				// Wait for path seeking orders
		 PATH_SEEKING,			// Seeking in process
		 PATH_FOUND,			// A path is found
		 PATH_NODE_USED_UP,	// All nodes have used, but still unable to find the destination
		 PATH_IMPOSSIBLE,		// impossible to move, no result at all
 		 PATH_REUSE_FOUND,	// a reuse path is found
	  };

//---------define the search mode------------//
enum	{	SEARCH_MODE_IN_A_GROUP = 1,		// general searching for a unit
			SEARCH_MODE_A_UNIT_IN_GROUP,		// general group searching
			SEARCH_MODE_TO_ATTACK,				// general attacking searching
			SEARCH_MODE_REUSE,					// reuse path searching
			SEARCH_MODE_BLOCKING,				// searching when blocking (mainly for 2x2 units)
			SEARCH_MODE_TO_VEHICLE,				// embarking searching
			
			//=================================================================//
			// for the following search mode, destination location may be not
			// walkable, group id together for speeding up chekcing in function
			// can_move_to()
			//-----------------------------------------------------------------//
			SEARCH_MODE_TO_FIRM,
			SEARCH_MODE_TO_TOWN,
			SEARCH_MODE_TO_WALL_FOR_GROUP,
			SEARCH_MODE_TO_WALL_FOR_UNIT,
			SEARCH_MODE_ATTACK_UNIT_BY_RANGE, // searching to attack by range attack (esp. for attacking target with different mobile_type from this unit)
			SEARCH_MODE_ATTACK_FIRM_BY_RANGE,
			SEARCH_MODE_ATTACK_TOWN_BY_RANGE,
			SEARCH_MODE_ATTACK_WALL_BY_RANGE,
			//=================================================================//
			
			SEARCH_MODE_TO_LAND_FOR_SHIP,		// for ship only
			SEARCH_MODE_LAST, //--- set to the last one
			MAX_SEARCH_MODE_TYPE = SEARCH_MODE_LAST-1,
		};

//--------------------- define sub-mode -----------------//
enum	{	SEARCH_SUB_MODE_NORMAL=0,
			SEARCH_SUB_MODE_PASSABLE,
		};

//----------- Define constants -----------//

#define MAX_BACKGROUND_NODE				2400		// the total no. of nodes can be used at a time
#define VALID_BACKGROUND_SEARCH_NODE	1600		// the search is considered unsuccessful if the node used > this value
#define MIN_BACKGROUND_NODE_USED_UP		400		// don't do any new search if the current available nodes is < this value

#define MAX_CHILD_NODE    8		// one for each direction
//#define MAX_STACK_NUM  2000		// maximum no. of stack entity in stack_aray, which is shared by all SeekPath objects. It is calculated based on: MAX possiblity: 500(MAX node) x 8(MAX child node) = 4000. Practical no. possiblities=2000. Memory occupied: 2000*4 = 8K
#define MAX_STACK_NUM  MAX_BACKGROUND_NODE	// maximum no. of stack entity in stack_aray, which is shared by all SeekPath objects. It is calculated based on: MAX possiblity: 500(MAX node) x 8(MAX child node) = 4000. Practical no. possiblities=2000. Memory occupied: 2000*4 = 8K

//---------- Define class Node -----------//

class Node
{
public:
	short node_x, node_y;
	int   node_f, node_h;// could be replaced by "unsigned short" to reduce memory, set all member vars to "unsigned short" for consistency
	short	node_g;
	char	node_type;// the type of the node, total 16 different type, 4 points in a 2x2 node, blocked/non-blocked, so there are 2^4 combinations
	char	enter_direction;
	// enter_direction -- 1-8 for eight directions, 0 for the starting node
	//
	//		8	7	6
	//		1	x	5		where x is the reference point
	//		2	3	4

	Node* parent_node;
	Node* child_node[MAX_CHILD_NODE];
	Node* next_node;

public:
	short generate_successors(short dir, short x , short y);
	short generate_succ(short x, short y, short direction, short cost);
	void	propagate_down();

	//------------- for scale 2 --------------//
	short generate_successors2(short x, short y);
	short generate_succ2(short x, short y, short cost=1);
	void	propagate_down2();
};

//------- Define struct ResultNode --------//

struct ResultNodeGF;

#pragma pack(1)
struct ResultNode
{
public:
	short node_x, node_y;

	void write_record(ResultNodeGF *r);
	void read_record(ResultNodeGF *r);
};
#pragma pack()

//---------- Define class Stack ----------//

struct Stack
{
	Node  *node_ptr;
	Stack *next_stack_ptr;
};

//---------- define struct NodePriorityQueue --------//

struct NodePriorityQueue
{
	#define MAX_ARRAY_SIZE	MAX_BACKGROUND_NODE+1
	public:
		unsigned int	size;
		Node	*elements[MAX_ARRAY_SIZE];

	public:
		void	reset_priority_queue();
		void	insert_node(Node *insertNode);
		Node*	return_min();
};

//--------- Define class SeekPath --------//

class SeekPath
{
friend class Node;

public:
	char	path_status;
	short real_sour_x, real_sour_y;	// the actual coordinate of the starting point
	short real_dest_x, real_dest_y;	// the actual coordinate of the destination point
	short	dest_x, dest_y;				// the coordinate of the destination represented in 2x2 node form
	char	is_dest_blocked;
	short	current_search_node_used;	// count the number of nodes used in the current searching

   short border_x1, border_y1, border_x2, border_y2;

	static NodePriorityQueue	open_node_list;
	static NodePriorityQueue	closed_node_list;

	short* node_matrix;
	Node*  node_array;

	int	max_node;
	int 	node_count;

	Node*	result_node_ptr;

	short	total_node_avail;
	void	reset_total_node_avail();

private:
	ResultNode* max_size_result_node_ptr;	// point to the temprory result node list
	ResultNode* parent_result_node_ptr;		// the parent node of the currently node pointed by max_size_result_node_ptr
	int	upper_left_x;	// x coord. of upper left corner of the 2x2 node
	int	upper_left_y;	// y coord. of upper left corner of the 2x2 node

public:
	SeekPath() 		{ node_array=NULL; node_matrix=NULL; }
	~SeekPath()		{ deinit(); }

	void  init(int maxNode);
	void  deinit();

	void	set_node_matrix(short reuseNodeMatrix[]);
	void	set_status(char newStatus) { path_status = newStatus; }
	int	is_valid_searching()	{ return total_node_avail>VALID_BACKGROUND_SEARCH_NODE; }

	void	reset();
	inline void add_result_node(int x, int y, ResultNode** curPtr, ResultNode** prePtr, int& count);
	int   seek(int sx,int sy,int dx,int dy,uint32_t groupId,char mobileType, short searchMode=SEARCH_MODE_IN_A_GROUP, short miscNo=0, short numOfPath=1, int maxTries=0,int borderX1=0, int borderY1=0, int borderX2=MAX_WORLD_X_LOC-1, int borderY2=MAX_WORLD_Y_LOC-1);
	int   continue_seek(int,char=0);

	ResultNode* get_result(int& resultNodeCount, short& pathDist);
	Node* 		return_closest_node();
	ResultNode* smooth_the_path(ResultNode* nodeArray, int& nodeCount); // smoothing the path

	//------------ for scale 2 -------------//
	int	seek2(int sx,int sy,int dx,int dy,short miscNo,short numOfPath,int maxTries);
	int   continue_seek2(int,char=0);
	ResultNode* get_result2(int& resultNodeCount, short& pathDist);

	void	set_attack_range_para(int attackRange);
	void	reset_attack_range_para();
	void	set_nation_recno(char nationRecno);
	void	set_nation_passable(char nationPassable[]);
	void	set_sub_mode(char subMode=SEARCH_SUB_MODE_NORMAL);

   int   write_file(File* filePtr);
   int   read_file(File* filePtr);

private:
	static Node* return_best_node();

	void	get_real_result_node(int &count, short enterDirection, short exitDirection, short nodeType, short xCoord, short yCoord);
	// function used to get the actual shortest path out of the 2x2 node path

	inline void		bound_check_x(short &paraX);
	inline void		bound_check_y(short &paraY);
	inline short	result_node_distance(ResultNode *node1, ResultNode *node2);
};

extern SeekPath seek_path;
//### begin alex 29/9 ###//
#ifdef DEBUG
extern unsigned long seek_path_profile_time;
extern unsigned long last_seek_path_profile_time;
#endif
//#### end alex 29/9 ####//

//-----------------------------------------//

#endif