/*
* 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 .
*
*/
//Filename : OSPREUSE.H
//Description : Header file of Object SeekPathReuse
//Owner : Alex
#ifndef __OSPREUSE_H
#define __OSPREUSE_H
#ifndef __OSPATH_H
#include
#endif
#ifndef __ALL_H
#include
#endif
#ifndef __OWORLD_H
#define
#endif
//---------- Define constants ------------//
enum{ REUSE_PATH_INITIAL=1, // 0 is used for other searching call with no path reuse, or for error checking
REUSE_PATH_FIRST_SEEK,
REUSE_PATH_SEARCH,
//REUSE_PATH_FOUND,
//REUSE_PATH_IMPOSSIBLE,
REUSE_PATH_INCOMPLETE_SEARCH,
};
enum{ GENERAL_GROUP_MOVEMENT = 1, // 0 is used for error checking
FORMATION_MOVEMENT,
};
#define RNA_RESET_AMOUNT 10
//---------- Define class SeekPathReuse -----------//
class SeekPathReuse
{
public:
char incomplete_search;
static int max_node; // max number of node used in searching
static short total_num_of_path; // equal to number of unit to process path-reuse
static short cur_path_num; // which unit in the group is processing path-reuse
static short unit_size; // the size of the current unit
static DWORD cur_group_id; // group id used to pass into SeekPath for searching
static char mobile_type; // mobile type used to pass into SeekPath for searching
static char unit_nation_recno; // the nation recno of this unit
static short move_scale; // 1 for UNIT_LAND, 2 for others
static short search_mode; // search mode to check whether path-reuse is used
static short reuse_mode; // reuse mode, general or formation movement of path-reuse
static short reuse_path_status; // initial, seek first or reuse
static short reuse_path_dist; // count the reuse-path distance
static short *reuse_node_matrix; // point to the node matrix that store offset path for reusing
static char reuse_nation_passable[MAX_NATION+1]; // Note: position 0 is not used for faster access
static char reuse_search_sub_mode;
//----------------- backup leader path(reference path) ----------------------//
static short leader_path_num; //------------------------------------------------------------------------------------------------//
// usually the unit calling with pathReuseStatus==REUSE_PATH_FIRST_SEEK should be the leader.
// However, in some condition, e.g. leader_num_of_node<2, another unit will be selected
// to be the leader. This variable stores which path number is selected to be the new leader path.
//------------------------------------------------------------------------------------------------//
static ResultNode *reuse_leader_path_backup;
static int reuse_leader_path_node_num;
static int leader_path_start_x;
static int leader_path_start_y;
static int leader_path_dest_x;
static int leader_path_dest_y;
//----------- decide which offset method is used ----------//
// some will be removed later
static int start_x_offset; // x offset in the starting location refer to that of leader unit
static int start_y_offset; // y offset in the starting location refer to that of leader unit
static int dest_x_offset; // x offset in the destination refer to that of leader unit
static int dest_y_offset; // y offset in the destination refer to that of leader unit
static int x_offset; // the x offset used in generating the offset path
static int y_offset; // the y offset used in generating the offset path
static int formation_x_offset; // formation x offset
static int formation_y_offset; // formation y offset
static int start_x; // the x location of the unit starting point
static int start_y; // the y location of the unit starting point
static int dest_x; // the x location of the unit destination
static int dest_y; // the y location of the unit destination
static int vir_dest_x;
static int vir_dest_y;
//---------- the current constructing result path --------//
static ResultNode *path_reuse_result_node_ptr; // store the reuse path result node
static int num_of_result_node; // store the number of result node of the reuse path
static ResultNode *cur_result_node_ptr; // point to the current result node used in the result node array
static short result_node_array_def_size; // the current node of node in the result node array
static short result_node_array_reset_amount; // the default size to adjust in the result node array each time
//-- determine the current offset difference(leader path information) --//
static ResultNode *cur_leader_node_ptr; // point to the leader result node backup array
static int cur_leader_node_num; // current number of node used in the leader backup node array
static short leader_vec_x; // the current unit vector in x-direction in the leader path
static short leader_vec_y; // the current unit vector in y-direction in teh leader path
//----------- for smoothing the result path --------------//
static short vec_x, vec_y;
static short new_vec_x, new_vec_y;
static int vec_magn, new_vec_magn;
static int result_vec_x, result_vec_y;
public:
void init(int maxNode);
void deinit();
void init_reuse_search(); // init data structure
void deinit_reuse_search(); // deinit data structure
void init_reuse_node_matrix();
void set_index_in_node_matrix(int xLoc, int yLoc);
int seek(int sx,int sy,int dx,int dy,short unitSize, DWORD groupId,char mobileType, short searchMode=4, short miscNo=0,
short numOfPath=1, short pathReuseStatus=REUSE_PATH_INITIAL, short reuseMode=GENERAL_GROUP_MOVEMENT,
int maxTries=0,int borderX1=0, int borderY1=0, int borderX2=MAX_WORLD_X_LOC-1, int borderY2=MAX_WORLD_Y_LOC-1);
ResultNode* get_result(int& resultNodeCount, short& pathDist);
inline ResultNode* call_seek(int sx, int sy, int dx, int dy, DWORD groupId, char mobileType, short searchMode, int& nodeCount)
{ seek_path.seek(sx, sy, dx, dy, groupId, mobileType, searchMode);
return seek_path.get_result(nodeCount, reuse_path_dist);
}
inline ResultNode* call_seek2(int sx, int sy, int dx, int dy, DWORD groupId, char mobileType, short searchMode, int& nodeCount, int& returnValue);
short count_path_dist(ResultNode* nodeArray, int nodeNum);
void extend_result_path(short addSize=RNA_RESET_AMOUNT);
void add_result(int x, int y); // record the result node in the node array
void add_result_path(ResultNode *pathPtr, int nodeNum);
void set_offset_condition(int startXOffset=0, int startYOffset=0, int destXOffset=0, int destYOffset=0);
int get_next_offset_loc(int& nextXLoc, int& nextYLoc);
int get_next_nonblocked_offset_loc(int& nextXLoc, int&nextYLoc);
void set_next_cur_path_num();
void seek_path_offset(); // process the offset method to get the shortest path
void seek_path_join_offset();
void use_offset_method(int xLoc, int yLoc);
inline void bound_check_x(int& x)
{ if(x<0) x = 0; else if(x>=MAX_WORLD_X_LOC) x = MAX_WORLD_X_LOC-move_scale; }
inline void bound_check_y(int& y)
{ if(y<0) y = 0; else if(y>=MAX_WORLD_X_LOC) y = MAX_WORLD_X_LOC-move_scale; }
char get_reuse_path_status();
void set_nation_passable(char nationPassable[]);
void set_sub_mode(char subMode=SEARCH_SUB_MODE_NORMAL);
void set_status(char newStatus);
//-------------- for optimize the result path ----------------//
void remove_duplicate_node(ResultNode* resultList, int& nodeCount); // remove duplicate node in the node array
ResultNode* smooth_reuse_path(ResultNode* resultPath, int& resultNodeNum); // smoothing the reuse path
ResultNode* smooth_path(ResultNode* resultPath, int& resultNodeNum); // smooth any path, subset of smooth_reuse_path()
ResultNode* smooth_path2(ResultNode* resultPath, int& resultNodeNum); // version for UNIT_SEA, UNIT_AIR
//-------------- for node limitation -----------------//
int is_node_avail_empty();
int is_leader_path_valid();
void copy_leader_path_offset();
void move_within_map(int preX, int preY, int curX, int curY);
void move_inside_map(int preX, int preY, int curX, int curY);
void move_outside_map(int preX, int preY, int curX, int curY);
void move_beyond_map(int preX, int preY, int curX, int curY);
public:
static int can_walk(int xLoc, int yLoc);
static int can_walk_s2(int xLoc, int yLoc);
static void sys_yield();
#ifdef DEBUG
void debug_check();
void debug_check_magnitude(int x1, int y1, int x2, int y2);
void debug_check_smode_node(int x, int y);
void debug_check_sub_mode_path(ResultNode *nodeArray, int count);
#endif
#ifdef DEBUG
#define debug_reuse_check_path() debug_check()
#define debug_reuse_check_xy_magn(x1, y1, x2, y2) debug_check_magnitude((x1), (y1), (x2), (y2))
#define debug_reuse_check_sub_mode_node(x, y) debug_check_smode_node((x), (y))
#define debug_reuse_check_sub_mode(nodeArray, count) debug_check_sub_mode_path((nodeArray), (count))
#else
#define debug_reuse_check_path()
#define debug_reuse_check_xy_magn(x1, y1, x2, y2)
#define debug_reuse_check_sub_mode_node(x, y)
#define debug_reuse_check_sub_mode(nodeArray, count)
#endif
protected:
private:
};
extern SeekPathReuse seek_path_reuse;
#endif