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