OUNIT.h 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885
  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. //Filename : OUNIT.H
  21. //Description : Header file of Object Unit
  22. #ifndef __OUNIT_H
  23. #define __OUNIT_H
  24. #ifndef __OSPRITE_H
  25. #include <OSPRITE.h>
  26. #endif
  27. #ifndef __OSPATH_H
  28. #include <OSPATH.h>
  29. #endif
  30. //#ifndef __OSPATHS2_H
  31. //#include <OSPATHS2.h>
  32. //#endif
  33. #ifndef __OUNITRES_H
  34. #include <OUNITRES.h>
  35. #endif
  36. #ifndef __OBUTTON_H
  37. #include <OBUTTON.h>
  38. #endif
  39. #ifndef __OSKILL_H
  40. #include <OSKILL.h>
  41. #endif
  42. #ifndef __OSPREUSE_H
  43. #include <OSPREUSE.h>
  44. #endif
  45. #ifdef NO_DEBUG_UNIT
  46. #undef DEBUG
  47. #endif
  48. #define GAME_FRAMES_PER_DAY 10
  49. //-------- action code for action_mode ---------//
  50. enum { ACTION_STOP,
  51. ACTION_ATTACK_UNIT,
  52. ACTION_ATTACK_FIRM,
  53. ACTION_ATTACK_TOWN,
  54. ACTION_ATTACK_WALL,
  55. ACTION_ASSIGN_TO_FIRM,
  56. ACTION_ASSIGN_TO_TOWN,
  57. ACTION_ASSIGN_TO_VEHICLE,
  58. ACTION_ASSIGN_TO_SHIP,
  59. ACTION_SHIP_TO_BEACH, // used for UNIT_SEA only
  60. ACTION_BUILD_FIRM,
  61. ACTION_SETTLE,
  62. ACTION_BURN,
  63. ACTION_DIE,
  64. ACTION_MOVE,
  65. ACTION_GO_CAST_POWER, // for god only
  66. //------------ used only for action_mode2 -----------------//
  67. //------- put the following nine parameters together -------//
  68. ACTION_AUTO_DEFENSE_ATTACK_TARGET, // move to target for attacking
  69. ACTION_AUTO_DEFENSE_DETECT_TARGET, // is idle, detect target to attack or waiting for defense action, (detect range is larger as usual)
  70. ACTION_AUTO_DEFENSE_BACK_CAMP, // go back to camp for training or ready for next defense action
  71. ACTION_DEFEND_TOWN_ATTACK_TARGET,
  72. ACTION_DEFEND_TOWN_DETECT_TARGET,
  73. ACTION_DEFEND_TOWN_BACK_TOWN,
  74. ACTION_MONSTER_DEFEND_ATTACK_TARGET,
  75. ACTION_MONSTER_DEFEND_DETECT_TARGET,
  76. ACTION_MONSTER_DEFEND_BACK_FIRM,
  77. };
  78. //-------- define action type for action_misc ----------//
  79. enum { ACTION_MISC_STOP = 0,
  80. ACTION_MISC_CAPTURE_TOWN_RECNO,
  81. ACTION_MISC_DEFENSE_CAMP_RECNO,
  82. ACTION_MISC_DEFEND_TOWN_RECNO,
  83. ACTION_MISC_MONSTER_DEFEND_FIRM_RECNO,
  84. ACTION_MISC_PRE_SEARCH_NODE_USED_UP,
  85. };
  86. //--------- unit mode ------------//
  87. enum { UNIT_MODE_OVERSEE=1, // unit_mode_para is the recno of the firm the unit is overseeing
  88. UNIT_MODE_DEFEND_TOWN, // unit_mode_para is the recno of the town the unit is defending
  89. UNIT_MODE_CONSTRUCT, // unit_mode_para is the recno of the firm the unit is constructing
  90. UNIT_MODE_REBEL, // unit_mode_para is the recno of the rebel group the unit belongs to
  91. UNIT_MODE_MONSTER, // unit_mode_para is the recno of the firm recno of the monster firm it belongs to
  92. UNIT_MODE_ON_SHIP, // unit_mode_para is the recno of the ship unit this unit is on
  93. UNIT_MODE_IN_HARBOR, // for ships only, unit_mode_para is the recno of the harbor this marine unit is in
  94. UNIT_MODE_UNDER_TRAINING,
  95. };
  96. //-------------- unit rank -------------//
  97. enum { MAX_RANK=3 };
  98. enum { RANK_SOLDIER,
  99. RANK_GENERAL,
  100. RANK_KING,
  101. };
  102. //------------- unit salary -----------//
  103. enum { SOLDIER_YEAR_SALARY = 10,
  104. GENERAL_YEAR_SALARY = 50,
  105. SPY_YEAR_SALARY = 100 };
  106. //------- other constant ----------//
  107. enum { EFFECTIVE_LEADING_DISTANCE = 10 };
  108. enum { ATTACK_DIR = 8 }; // define number of attacking direction
  109. enum { MAX_TEAM_MEMBER = 9 }; // maximum no. of units a general/king can lead
  110. enum { MAX_NATION_CONTRIBUTION = 10000 }; // there is an upper limit nation_contribution as it is a <short>
  111. //---------- used in set_move_to_surround -----------//
  112. enum { BUILDING_TYPE_FIRM_MOVE_TO, // firm already exists
  113. BUILDING_TYPE_FIRM_BUILD, // no firm there
  114. BUILDING_TYPE_TOWN_MOVE_TO, // town already exists
  115. BUILDING_TYPE_SETTLE, // no town there
  116. BUILDING_TYPE_VEHICLE, // location is blocked by the vehicle
  117. BUILDING_TYPE_WALL, // location is occupied by the wall
  118. };
  119. //------------ define help mode ----------//
  120. enum { HELP_NOTHING =0,
  121. HELP_ATTACK_UNIT,
  122. HELP_ATTACK_FIRM,
  123. HELP_ATTACK_TOWN,
  124. HELP_ATTACK_WALL,
  125. };
  126. //---------- misc constant parameters ----------//
  127. enum { KEEP_PRESERVE_ACTION = 1, // used for stop2() to keep preserve action
  128. KEEP_DEFENSE_MODE = 2, // used for stop2() to keep the defense mode
  129. KEEP_DEFEND_TOWN_MODE = 3, // used for stop2() to keep the defend town mode
  130. MAX_WAITING_TERM_SAME = 3, // wait for same nation, used in handle_blocked...()
  131. MAX_WAITING_TERM_DIFF = 3, // wait for diff. nation, used in handle_blocked...()
  132. ATTACK_DETECT_DISTANCE = 6,// the distance for the unit to detect target while idle
  133. ATTACK_SEARCH_TRIES = 250, // the node no. used to process searching when target is close to this unit
  134. ATTACK_WAITING_TERM = 10, // terms no. to wait before calling searching to attack target
  135. //MAX_SEARCH_OR_STOP_WAIT_TERM = 15, // note: should be the largetest default value in waiting_term
  136. AUTO_DEFENSE_STAY_OUTSIDE_COUNT = 4, //4 days
  137. AUTO_DEFENSE_DETECT_COUNT = 3 + GAME_FRAMES_PER_DAY*AUTO_DEFENSE_STAY_OUTSIDE_COUNT,
  138. EFFECTIVE_AUTO_DEFENSE_DISTANCE = 9,
  139. AUTO_DEFENSE_SEARCH_TRIES = 100,
  140. UNIT_DEFEND_TOWN_DISTANCE = 8,
  141. UNIT_DEFEND_TOWN_STAY_OUTSIDE_COUNT = 4, // 4 days
  142. UNIT_DEFEND_TOWN_DETECT_COUNT = 3 + GAME_FRAMES_PER_DAY*UNIT_DEFEND_TOWN_STAY_OUTSIDE_COUNT,
  143. UNIT_DEFEND_TOWN_WAITING_TERM = 4,
  144. EFFECTIVE_DEFEND_TOWN_DISTANCE = 9,
  145. MONSTER_DEFEND_FIRM_DISTANCE = 8,
  146. MONSTER_DEFEND_STAY_OUTSIDE_COUNT = 4, // 4 days
  147. MONSTER_DEFEND_DETECT_COUNT = 3 + GAME_FRAMES_PER_DAY*MONSTER_DEFEND_STAY_OUTSIDE_COUNT,
  148. EFFECTIVE_MONSTER_DEFEND_FIRM_DISTANCE = 9,
  149. DO_CAST_POWER_RANGE = 3, // for god to cast power
  150. };
  151. //----------- Define TeamInfo -------------//
  152. #pragma pack(1)
  153. struct TeamInfo
  154. {
  155. TeamInfo();
  156. char member_count;
  157. short member_unit_array[MAX_TEAM_MEMBER];
  158. int ai_last_request_defense_date;
  159. };
  160. #pragma pack()
  161. //----------- Define class Unit -----------//
  162. #pragma pack(1)
  163. class Unit : public Sprite
  164. {
  165. public:
  166. char unit_id;
  167. char rank_id;
  168. char race_id;
  169. char nation_recno;
  170. char ai_unit;
  171. WORD name_id; // id. of the unit's name in RaceRes::first_name_array;
  172. DWORD unit_group_id; // the group id this unit belong to if it is selected
  173. DWORD team_id; // id. of defined team
  174. char selected_flag; // whether the unit has been selected or not
  175. char group_select_id; // id for group selection
  176. char waiting_term; // for 2x2 unit only, the term to wait before recalling A* to get a new path
  177. char blocked_by_member;
  178. char swapping;
  179. short leader_unit_recno; // recno of this unit's leader
  180. int is_visible() { return cur_x >= 0; } // whether the unit is visible on the map, it is not invisable if cur_x == -1
  181. virtual char* unit_name(int withTitle=1);
  182. BYTE region_id();
  183. //--------- action vars ------------//
  184. char action_misc;
  185. short action_misc_para;
  186. char action_mode;
  187. short action_para;
  188. short action_x_loc;
  189. short action_y_loc;
  190. char action_mode2; // store the existing action for speeding up the performance if same action is ordered.
  191. short action_para2; // to re-activiate the unit if its cur_action is idle
  192. short action_x_loc2;
  193. short action_y_loc2;
  194. char blocked_edge[4]; // for calling searching in attacking
  195. UCHAR attack_dir;
  196. //------------ attack parameters -----------//
  197. short range_attack_x_loc; // -1 for unable to do range_attack, use to store previous range attack location
  198. short range_attack_y_loc; // -1 for unable to do range_attack, use to store previous range attack location
  199. //------------- for unit movement ---------------//
  200. short move_to_x_loc; // the location the unit should be moving to
  201. short move_to_y_loc;
  202. //---------- game vars -------------//
  203. char loyalty;
  204. char target_loyalty;
  205. float hit_points;
  206. short max_hit_points;
  207. Skill skill;
  208. char unit_mode;
  209. short unit_mode_para; // if unit_mode==UNIT_MODE_REBEL, unit_mode_para is rebel_recno this unit belongs to
  210. short rebel_recno() { return unit_mode==UNIT_MODE_REBEL ? unit_mode_para : 0; }
  211. short spy_recno; // spy parameters
  212. short nation_contribution; // contribution to the nation
  213. short total_reward; // total amount of reward you have given to the unit
  214. int commander_power();
  215. //---- share the use of nation_contribution and total_reward ----//
  216. int get_monster_id() { return nation_contribution; }
  217. void set_monster_id(int monsterId) { nation_contribution = monsterId; }
  218. int get_monster_soldier_id() { return total_reward; }
  219. void set_monster_soldier_id(int monsterSoldierId) { total_reward = monsterSoldierId; }
  220. int get_weapon_version() { return nation_contribution; }
  221. void set_weapon_version(int weaponVersion) { nation_contribution = weaponVersion; }
  222. int unit_power();
  223. //------- attack parameters --------//
  224. AttackInfo* attack_info_array;
  225. char attack_count;
  226. char attack_range;
  227. short cur_power; // power for power attack
  228. short max_power;
  229. //------- path seeking vars --------//
  230. ResultNode* result_node_array;
  231. int result_node_count;
  232. short result_node_recno;
  233. short result_path_dist;
  234. //----------- way points -----------//
  235. enum { WAY_POINT_ADJUST_SIZE = 5};
  236. ResultNode* way_point_array;
  237. short way_point_array_size;
  238. short way_point_count;
  239. //--------- AI parameters ------------//
  240. WORD ai_action_id; // an unique id. for locating the AI action node this unit belongs to in Nation::action_array
  241. char original_action_mode;
  242. short original_action_para;
  243. short original_action_x_loc;
  244. short original_action_y_loc;
  245. short original_target_x_loc; // the original location of the attacking target when the attack() function is called
  246. short original_target_y_loc; // action_x_loc2 & action_y_loc2 will change when the unit move, but these two will not.
  247. short ai_original_target_x_loc; // for AI only
  248. short ai_original_target_y_loc;
  249. char ai_no_suitable_action;
  250. //-------- defense blocking ability flag ----------//
  251. char can_guard_flag; // bit0= standing guard, bit1=moving guard
  252. // copy from sprite_info->can_guard_flag when skill.combat level is high enough
  253. char can_attack_flag; // 1 able to attack, 0 unable to attack no matter what attack_count is
  254. char force_move_flag;
  255. short home_camp_firm_recno;
  256. char aggressive_mode;
  257. char seek_path_fail_count;
  258. char ignore_power_nation;
  259. //------ TeamInfo structure for general and king only ------//
  260. TeamInfo* team_info;
  261. int commanded_soldier_count();
  262. public:
  263. Unit();
  264. virtual ~Unit();
  265. //------- derived functions from Sprite ------//
  266. virtual void init(int unitId, int nationRecno, int rankId=0, int unitLoyalty=0, int startX= -1, int startY= -1);
  267. virtual void deinit();
  268. virtual void init_derived() {;}
  269. void init_sprite(int startXLoc, int startYLoc);
  270. void deinit_sprite(int keepSelected=0);
  271. void init_unit_id(int unitId);
  272. void deinit_unit_id();
  273. void deinit_unit_mode();
  274. void del_team_member(int);
  275. void validate_team();
  276. void draw();
  277. virtual void draw_outlined();
  278. void draw_selected();
  279. void draw_skill_icon();
  280. void set_spy(int spyRecno);
  281. void set_name(WORD newNameId);
  282. void set_mode(char modeId, short modePara=0) { unit_mode=modeId; unit_mode_para=modePara; }
  283. int is_shealth();
  284. int is_civilian();
  285. int is_own();
  286. int is_own_spy();
  287. int is_nation(int nationRecno);
  288. int true_nation_recno(); // the true nation recno of the unit, taking care of the situation where the unit is a spy
  289. virtual int is_ai_all_stop();
  290. int get_cur_loc(short& xLoc, short& yLoc);
  291. virtual void die() {;}
  292. //-------------- AI functions -------------//
  293. virtual void process_ai();
  294. int think_king_action();
  295. int think_general_action();
  296. int think_leader_action();
  297. int think_normal_human_action();
  298. int think_weapon_action();
  299. int think_ship_action();
  300. int think_assign_weapon_to_camp();
  301. int think_build_camp();
  302. int think_reward();
  303. void think_independent_unit();
  304. void think_spy_action();
  305. int think_king_flee();
  306. int think_general_flee();
  307. int think_stop_chase();
  308. void ai_move_to_nearby_town();
  309. int ai_escape_fire();
  310. void ai_leader_being_attacked(int attackerUnitRecno);
  311. int ai_build_camp();
  312. int ai_settle_new_town();
  313. int ai_handle_seek_path_fail();
  314. //------- functions for unit AI mode ---------//
  315. int think_aggressive_action();
  316. int think_change_attack_target();
  317. int think_resume_original_action();
  318. void save_original_action();
  319. void resume_original_action();
  320. void resume_original_attack_action();
  321. void ask_team_help_attack(Unit* attackerUnit);
  322. //------------- processing functions --------------------//
  323. virtual void pre_process();
  324. virtual void process_idle(); // derived function of Sprite
  325. virtual void process_move(); // derived function of Sprite
  326. virtual void process_wait(); // derived function of Sprite
  327. virtual void process_extra_move() {;}// derived function of Sprite, for ship only
  328. virtual int process_die();
  329. virtual void next_day();
  330. void set_next(int nextX, int nextY, int para=0, int blockedChecked=0);
  331. //------------------------------------//
  332. virtual void disp_info(int refreshFlag);
  333. virtual void disp_unit_profile(int dispY1, int refreshFlag);
  334. virtual int detect_unit_profile();
  335. virtual void detect_info();
  336. int should_show_info();
  337. int return_camp();
  338. //----------- parameters reseting functions ------------//
  339. virtual void stop(int preserveAction=0);
  340. void stop2(int preserveAction=0);
  341. void reset_action_para(); // reset action_mode parameters
  342. void reset_action_para2(int keepMode=0); // reset action_mode2 parameters
  343. void reset_action_misc_para();
  344. //--------------- die actions --------------//
  345. int is_unit_dead() { return (hit_points<=0 || action_mode==ACTION_DIE || cur_action==SPRITE_DIE); }
  346. //------------ movement action -----------------//
  347. virtual void move_to(int destX, int destY, int preserveAction=0, short searchMode=1, short miscNo=0, short numOfPath=1, short reuseMode=GENERAL_GROUP_MOVEMENT, short pathReuseStatus=0);
  348. void move_to_unit_surround(int destXLoc, int destYLoc, int width, int height, int miscNo=0, int readyDist=0);
  349. void move_to_firm_surround(int destXLoc, int destYLoc, int width, int height, int miscNo=0, int readyDist=0);
  350. void move_to_town_surround(int destXLoc, int destYLoc, int width, int height, int miscNo=0, int readyDist=0);
  351. void move_to_wall_surround(int destXLoc, int destYLoc, int width, int height, int miscNo=0, int readyDist=0);
  352. void enable_force_move();
  353. void disable_force_move();
  354. void select_search_sub_mode(int sx, int sy, int dx, int dy, short nationRecno, short searchMode);
  355. void different_territory_destination(int& destX, int& destY); // calculate new destination for move to location on different territory
  356. //----------------- attack action ----------------//
  357. void attack_unit(int targetXLoc, int targetYLoc, int xOffset=0, int yOffset=0, int resetBlockedEdge=1);
  358. void attack_unit(short targetRecno, int xOffset=0, int yOffset=0, int resetBlockedEdge=1);
  359. void attack_firm(int firmXLoc, int firmYLoc, int xOffset=0, int yOffset=0, int resetBlockedEdge=1);
  360. void attack_town(int townXLoc, int townYLoc, int xOffset=0, int yOffset=0, int resetBlockedEdge=1);
  361. void attack_wall(int wallXLoc, int wallYLoc, int xOffset=0, int yOffset=0, int resetBlockedEdge=1);
  362. void hit_target(Unit* parentUnit, Unit* targetUnit, float attackDamage);
  363. void hit_building(Unit* parentUnit, int targetXLoc, int targetYLoc, float attackDamage);
  364. void hit_firm(Unit* parentUnit, int targetXLoc, int targetYLoc, float attackDamage);
  365. void hit_town(Unit* parentUnit, int targetXLoc, int targetYLoc, float attackDamage);
  366. void hit_wall(Unit* attackUnit, int targetXLoc, int targetYLoc, float attackDamage);
  367. int max_attack_range();
  368. void gain_experience();
  369. virtual float actual_damage();
  370. int nation_can_attack(short nationRecno); // can this nation be attacked, no if alliance or etc..
  371. int independent_nation_can_attack(short nationRecno);
  372. void cycle_eqv_attack();
  373. int is_action_attack();
  374. inline int can_attack() { return (can_attack_flag && attack_count); }
  375. //----------------- defense actions ---------------------//
  376. //========== unit's defense mode ==========//
  377. void defense_attack_unit(short targetRecno);
  378. void defense_attack_firm(int targetXLoc, int targetYLoc);
  379. void defense_attack_town(int targetXLoc, int targetYLoc);
  380. void defense_attack_wall(int targetXLoc, int targetYLoc);
  381. void defense_detect_target();
  382. int in_auto_defense_mode();
  383. int in_defend_town_mode();
  384. int in_monster_defend_mode();
  385. void clear_unit_defense_mode();
  386. void clear_town_defend_mode();
  387. void clear_monster_defend_mode();
  388. //---------- embark to ship and other ship functions ---------//
  389. void assign_to_ship(int destX, int destY, short shipRecno, int miscNo=0);
  390. void ship_to_beach(int destX, int destY, int& finalDestX, int& finalDestY); // for ship only
  391. //----------- other main action functions -------------//
  392. void build_firm(int buildXLoc, int buildYLoc, int firmId, char remoteAction);
  393. void burn(int burnXLoc, int burnYLoc, char remoteAction);
  394. void settle(int settleXLoc, int settleYLoc, short curSettleUnitNum=1);
  395. void assign(int buildXLoc, int buildYLoc, short curAssignUnitNum=1);
  396. void go_cast_power(int castXLoc, int castYLoc, char castPowerType, char remoteAction);
  397. void add_way_point(short x, short y);
  398. void reset_way_point_array();
  399. void process_way_point();
  400. //------------------------------------//
  401. void change_nation(int newNationRecno);
  402. void overseer_migrate(int destTownRecno);
  403. int caravan_in_firm() { return cur_x==-2; }
  404. void update_loyalty();
  405. void set_combat_level(int);
  406. void inc_minor_combat_level(int);
  407. void inc_minor_skill_level(int);
  408. void set_rank(int rankId);
  409. virtual int can_resign();
  410. void resign(int remoteAction);
  411. void embark(int vehicleRecno);
  412. void reward(int rewardNationRecno);
  413. void transform();
  414. void group_transform(char remoteAction, short *selectedArray=NULL, short selectedCount=0);
  415. void spy_change_nation(int nationRecno, char remoteAction);
  416. int can_spy_change_nation();
  417. void change_hit_points(float changePoints);
  418. void change_loyalty(int loyaltyChange);
  419. int think_betray();
  420. int betray(int newNationRecno);
  421. int can_stand_guard() { return can_guard_flag & 1;}
  422. int can_move_guard() { return can_guard_flag & 2;}
  423. // #ifdef AMPLUS
  424. int can_attack_guard() { return can_guard_flag & 4;}
  425. // #endif
  426. int firm_can_assign(short firmRecno);
  427. void set_idle();
  428. void set_ready();
  429. void set_move();
  430. void set_wait();
  431. void set_attack();
  432. void set_turn();
  433. void set_ship_extra_move();
  434. void set_die();
  435. int write_file(File* filePtr);
  436. int read_file(File* filePtr);
  437. virtual int write_derived_file(File* filePtr);
  438. virtual int read_derived_file(File* filePtr);
  439. virtual void fix_attack_info(); // set attack_info_array appropriately
  440. //-------------- multiplayer checking codes ---------------//
  441. virtual UCHAR crc8();
  442. virtual void clear_ptr();
  443. private:
  444. //------------------ idle functions -------------------//
  445. int reactivate_idle_action();
  446. int idle_detect_attack(int startLoc=0, int dimensionInput=0, char defenseMode=0); // detect target to attack
  447. int idle_detect_choose_target(char defenseMode);
  448. void idle_detect_helper_attack(short unitRecno);
  449. int idle_detect_unit_checking(short targetRecno);
  450. int idle_detect_firm_checking(short targetRecno);
  451. int idle_detect_town_checking(short targetRecno);
  452. int idle_detect_wall_checking(int targetXLoc, int targetYLoc);
  453. //------------ movement action -----------------//
  454. int search(int destX, int destY, int preserveAction=0, short searchMode=1, short miscNo=0, short numOfPath=1, short reuseMode=GENERAL_GROUP_MOVEMENT, short pathReuseStatus=0);
  455. int searching(int destX, int destY, int preserveAction, short searchMode, short miscNo, short numOfPath, short reuseMode, short pathReuseStatus);
  456. int set_move_to_surround(int buildXLoc, int buildYLoc, int width, int height, int buildingType, int miscNo=0, int readyDist=0, short curSettleUnitNum=1);
  457. int edit_path_to_surround(int x1, int y1, int x2, int y2, int readyDist);
  458. void search_or_stop(int destX, int destY, int preserveAction=0, short searchMode=1, short miscNo=0);
  459. void search_or_wait();
  460. //void move_to_surround_s2(int destXLoc, int destYLoc); // for 2x2 unit only
  461. int move_to_range_attack(int targetXLoc, int targetYLoc, short miscNo, short searchMode, short maxRange); // move to target for using range attack
  462. void abort_searching(int reuseSetNext);
  463. void set_search_tries(int tries); // set parameters to limit the nodes used in searching
  464. void reset_search_tries(); // reset parameters for using default nodes in searching
  465. //---------------- handle blocked action ------------------//
  466. void move_to_my_loc(Unit* unitPtr);
  467. void handle_blocked_move(Location* blockedLoc); // used to determine unit size and call other handle_blocked_move.. functions
  468. void handle_blocked_move_s11(Unit* unitPtr);
  469. //void handle_blocked_move_s12(Unit* unitPtr);
  470. //void handle_blocked_move_s21(Unit* unitPtr);
  471. //void handle_blocked_move_s22(Unit* unitPtr);
  472. //int blocked_move_new_handle();
  473. //void set_path_to(int destXLoc, int destYLoc);
  474. void handle_blocked_by_idle_unit(Unit *unitPtr);
  475. int on_my_path(short checkXLoc, short checkYLoc);
  476. void handle_blocked_wait(Unit* unitPtr);
  477. void cycle_wait_shift_recno(Unit* curUnit, Unit* nextUnit);
  478. void opposite_direction_blocked(short vecX, short vecY, short unitPtrVecX, short unitPtrVecY, Unit* unitPtr);
  479. void handle_blocked_attack_unit(Unit *unitPtr, Unit *targetPtr);
  480. void handle_blocked_attack_firm(Unit *unitPtr);
  481. void handle_blocked_attack_town(Unit *unitPtr);
  482. void handle_blocked_attack_wall(Unit *unitPtr);
  483. void handle_blocked_same_target_attack(Unit* unitPtr, Unit* targetPtr);
  484. //====== support functions for process_attack_unit()
  485. void target_move(Unit* targetUnit);
  486. void attack_target(Unit* targetUnit);
  487. int on_way_to_attack(Unit* targetUnit);
  488. int detect_surround_target();
  489. int update_attack_path_dist();
  490. void set_attack_dir(short curX, short curY, short targetX, short targetY);
  491. //====== functions for attacking between UNIT_LAND, UNIT_SEA, UNIT_AIR
  492. int move_try_to_range_attack(Unit* targetUnit);
  493. //void move_to_range_attack(int targetXLoc, int targetYLoc, short miscNo, short searchMode, short maxRange); //---defined above
  494. int can_attack_different_target_type();
  495. int possible_place_for_range_attack(int targetXLoc, int targetYLoc, int targetWidth, int targetHeight, int maxRange);
  496. //====== functions for reactivating idle units and blocked units that are ordered to attack
  497. int space_for_attack(int targetXLoc, int targetYLoc, char targetMobileType, int targetWidth, int targetHeight);
  498. int space_around_target(int squareXLoc, int squareYLoc, int width, int height);
  499. int space_around_target_ver2(int targetXLoc, int targetYLoc, int targetWidth, int targetHeight);
  500. int ship_surr_has_free_land(int targetXLoc, int targetYLoc, UCHAR regionId);
  501. int free_space_for_range_attack(int targetXLoc, int targetYLoc, int targetWidth, int targetHeight, int targetMobileType, int maxRange);
  502. void choose_best_attack_mode(int attackDistance, char targetMobileType=UNIT_LAND);
  503. void unit_auto_guarding(Unit *attackUnit);
  504. void set_unreachable_location(int xLoc, int yLoc);
  505. void check_self_surround();
  506. int can_attack_with(int i); // 0 to attack_count-1
  507. int can_attack_with(AttackInfo *attackInfo);
  508. void get_hit_x_y(short *xPtr, short *yPtr);
  509. void add_close_attack_effect();
  510. //----------------- defense actions ---------------------//
  511. //=========== unit's defend mode generalized functions ============//
  512. int in_any_defense_mode();
  513. void general_defend_mode_detect_target(int checkDefendMode=0);
  514. int general_defend_mode_process_attack_target();
  515. //========== unit's defense mode ==========//
  516. void defense_back_camp(int targetXLoc, int targetYLoc);
  517. void process_auto_defense_attack_target();
  518. void process_auto_defense_detect_target();
  519. void process_auto_defense_back_camp();
  520. int defense_follow_target();
  521. //========== town unit's defend mode ==========//
  522. void defend_town_attack_unit(short targetRecno);
  523. void defend_town_detect_target();
  524. void defend_town_back_town(short townRecno);
  525. void process_defend_town_attack_target();
  526. void process_defend_town_detect_target();
  527. void process_defend_town_back_town();
  528. int defend_town_follow_target();
  529. //========== monster unit's defend mode ==========//
  530. void monster_defend_attack_unit(short targetRecno);
  531. void monster_defend_attack_firm(int targetXLoc, int targetYLoc);
  532. void monster_defend_attack_town(int targetXLoc, int targetYLoc);
  533. void monster_defend_attack_wall(int targetXLoc, int targetYLoc);
  534. void monster_defend_detect_target();
  535. void monster_defend_back_firm(int targetXLoc, int targetYLoc);
  536. void process_monster_defend_attack_target();
  537. void process_monster_defend_detect_target();
  538. void process_monster_defend_back_firm();
  539. int monster_defend_follow_target();
  540. //---------- embark to ship and other ship functions ---------//
  541. int ship_to_beach_path_edit(int& resultXLoc, int& resultYLoc, UCHAR regionNo);
  542. void ship_leave_beach(int shipOldXLoc, int shipOldYLoc);
  543. //---------------- other functions -----------------//
  544. int cal_distance(int targetXLoc, int targetYLoc, int targetWidth, int targetHeight); // calculate distance from this unit(can be 1x1, 2x2) to a known size object
  545. int is_in_surrounding(int checkXLoc, int checkYLoc, int width, int targetXLoc, int targetYLoc, int targetWidth, int targetHeight);
  546. int avail_node_enough_for_search(short x1, short y1, short x2, short y2);
  547. // int firm_can_assign(short firmRecno);
  548. protected:
  549. void disp_main_menu(int);
  550. void detect_main_menu();
  551. void disp_build_menu(int);
  552. void detect_build_menu();
  553. void disp_button(int dispY1);
  554. void detect_button();
  555. void disp_build(int);
  556. void detect_build();
  557. void disp_settle(int);
  558. void detect_settle();
  559. void disp_unit_info(int dispY1, int refreshFlag);
  560. void disp_basic_info(int dispY1, int refreshFlag);
  561. int detect_basic_info();
  562. void disp_spy_menu(int dispY1, int refreshFlag);
  563. void detect_spy_menu(int dispY1);
  564. int spy_menu_height();
  565. void disp_hit_point(int dispY1);
  566. void process_attack_unit();
  567. void process_attack_firm();
  568. void process_build_firm();
  569. void process_attack_town();
  570. void process_attack_wall();
  571. void process_assign();
  572. void process_burn();
  573. void process_settle();
  574. void process_assign_to_ship();
  575. void process_ship_to_beach();
  576. void process_rebel();
  577. void process_go_cast_power();
  578. void next_move();
  579. void terminate_move();
  580. void reset_path();
  581. void king_die();
  582. void general_die();
  583. void pay_expense();
  584. void process_recover();
  585. };
  586. #pragma pack()
  587. //--------------------------------------------------------------------------------------------//
  588. //------- Define class UnitArray ---------//
  589. class UnitArray : public SpriteArray
  590. {
  591. public:
  592. short selected_recno;
  593. short selected_count;
  594. DWORD cur_group_id; // for Unit::unit_group_id
  595. DWORD cur_team_id; // for Unit::team_id
  596. short idle_blocked_unit_reset_count; // used to improve performance for searching related to attack
  597. short visible_unit_count;
  598. char mp_first_frame_to_select_caravan; // for multiplayer, true if 1st frame to select caravan
  599. char mp_first_frame_to_select_ship; // ditto for ship
  600. short mp_pre_selected_caravan_recno; // for multiplayer, 0 or recno that caravan selected in previous frame
  601. short mp_pre_selected_ship_recno; // ditto for ship
  602. static short selected_land_unit_count;
  603. static short selected_sea_unit_count;
  604. static short selected_air_unit_count;
  605. static short *selected_land_unit_array;
  606. static short *selected_sea_unit_array;
  607. static short *selected_air_unit_array;
  608. public:
  609. UnitArray(int);
  610. void init();
  611. int add_unit(int unitId, int nationRecno, int rankId=0, int unitLoyalty=0, int startXLoc= -1, int startYLoc= -1);
  612. Unit* create_unit(int unitId);
  613. int unit_class_size(int);
  614. void disappear_in_town(int unitRecno, int townRecno);
  615. void disappear_in_firm(int unitRecno);
  616. void die(int unitRecno);
  617. void return_camp(int remoteAction, short* selectedUnitArray=NULL, int selectedCount=0);
  618. void draw_dot();
  619. void draw_profile();
  620. void process();
  621. void stop(short* selectedUnitArray, int selectedCount, char remoteAction);
  622. void stop_all_war(short oldNationRecno);
  623. void stop_war_between(short nationRecno1, short nationRecno2);
  624. void stop_attack_unit(short unitRecno);
  625. void stop_attack_firm(short firmRecno);
  626. void stop_attack_town(short townRecno);
  627. //---------- move main functions -------------//
  628. void move_to(int destX, int destY, int divided, short* selectedUnitArray, int selectedCount, char remoteAction);
  629. //------------- attack main functions ----------//
  630. // ###### patch begin Gilbert 5/8 ######//
  631. void attack(int destX, int destY, int divided, short* selectedUnitArray, int selectedCount, char remoteAction, int unitRecno);
  632. // ###### patch end Gilbert 5/8 ######//
  633. void attack_unit(int targetXLoc, int targetYLoc, short targetUnitRecno, short* selectedUnitArray, int selectedCount);
  634. void attack_firm(int targetXLoc, int targetYLoc, short firmRecno, short* selectedUnitArray, int selectedCount);
  635. void attack_town(int targetXLoc, int targetYLoc, short townRecno, short* selectedUnitArray, int selectedCount);
  636. void attack_wall(int targetXLoc, int targetYLoc, short* selectedUnitArray, int selectedCount);
  637. //---------- other actions functions -----------//
  638. void assign(int destX, int destY, int divided, char remoteAction, short* selectedUnitArray=NULL, int selectedCount=0);
  639. void assign_to_camp(int destX, int destY, char remoteAction, short* selectedUnitArray=NULL, int selectedCount=0);
  640. void settle(int destX, int destY, int divided, char remoteAction, short *selectedUnitArray=NULL, int selectedCount=0);
  641. // ##### patch begin Gilbert 5/8 ######//
  642. void assign_to_ship(int shipXLoc, int shipYLoc, int divided, short* selectedArray, int selectedCount, char remoteAction, int shipRecno);
  643. // ##### patch end Gilbert 5/8 ######//
  644. void ship_to_beach(int destX, int destY, int divided, short* selectedArray, int selectedCount, char remoteAction);
  645. void add_way_point(int pointX, int pointY, short* selectedArray, int selectedCount, char remoteAction);
  646. //--------- unit filter function ----------//
  647. int divide_attack_by_nation(short nationRecno, short *selectedArray, int selectedCount);
  648. //--------- for multiplayers' caravan and ship ---------//
  649. void mp_mark_selected_caravan();
  650. int mp_get_selected_caravan_count();
  651. void mp_reset_selected_caravan_count();
  652. void mp_add_selected_caravan(short unitRecno);
  653. int mp_is_selected_caravan(short unitRecno);
  654. void mp_mark_selected_ship();
  655. int mp_get_selected_ship_count();
  656. void mp_reset_selected_ship_count();
  657. void mp_add_selected_ship(short unitRecno);
  658. int mp_is_selected_ship(short unitRecno);
  659. void update_selected_trade_unit_info();
  660. int write_file(File* filePtr);
  661. int read_file(File* filePtr);
  662. #ifdef DEBUG
  663. Unit* operator[](int recNo);
  664. #else
  665. Unit* operator[](int recNo) { return (Unit*) get_ptr(recNo); }
  666. #endif
  667. int is_deleted(int recNo);
  668. int is_truly_deleted(int recNo);
  669. private:
  670. void divide_array(int locX, int locY, short* selectedArray, int selectedCount, int excludeSelectedLocUnit=0);
  671. void set_group_id(short* selectedArray, int selectedCount);
  672. //------------ move sub-functions --------------//
  673. void move_to_now_with_filter(int destX, int destY, short* selectedUnitArray, int selectedCount);
  674. void move_to_now(int destX, int destY, short* selectedUnitArray, int selectedCount);
  675. void construct_sorted_array(short* selectedUnitArray, int selectedCount);
  676. void determine_position_to_construct_table(int selectedCount, int destXLoc, int destYLoc, char mobileType);
  677. //-------------- attack sub-functions -----------//
  678. // ###### patch begin Gilbert 5/8 #######//
  679. void attack_call(int destX, int destY, char mobileType, char targetMobileType, int divided, short* selectedUnitArray, int selectedCount, int targetUnitRecno);
  680. // ###### patch end Gilbert 5/8 #######//
  681. void update_unreachable_table(int targetXLoc, int targetYLoc, int targetWidth, int targetHeight, char mobileType, int &analyseResult);
  682. char get_target_surround_loc(int targetWidth, int targetHeight);
  683. char* get_target_x_offset(int targetWidth, int targetHeight, char curDir);
  684. char* get_target_y_offset(int targetWidth, int targetHeight, char curDir);
  685. void arrange_units_in_group(int xLoc1, int yLoc1, int xLoc2, int yLoc2, short* selectedUnitArray, int selectedCount, DWORD unitGroupId, int targetType);
  686. int analyse_surround_location(int targetXLoc, int targetYLoc, int targetWidth, int targetHeight, char mobileType);
  687. void check_nearby_location(int targetXLoc, int targetYLoc, char xOffset, char yOffset, int targetWidth, int targetHeight, char targetMobileType, int& analyzeResult);
  688. void handle_attack_target_totally_blocked(int targetXLoc, int targetYLoc, short targetRecno, short *selectedUnitArray, short selectedCount, int targetType);
  689. //---------- other actions functions -----------//
  690. void group_assign(int destX, int destY, short* selectedArray, int selectedCount);
  691. void group_settle(int destX, int destY, short* selectedArray, int selectedCount);
  692. };
  693. extern UnitArray unit_array;
  694. extern int unit_search_node_used;
  695. extern int unit_search_tries; // the number of tries used in the current searching
  696. extern char unit_search_tries_flag; // indicate num of tries is set, reset after searching
  697. #ifdef DEBUG
  698. extern int check_unit_dir1, check_unit_dir2;
  699. #endif
  700. #endif