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