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 : OTOWN.H 22 //Description : Header file of Object Town 23 24 #ifndef __OTOWN_H 25 #define __OTOWN_H 26 27 #ifndef __ODYNARRB_H 28 #include <ODYNARRB.h> 29 #endif 30 31 #ifndef __OSKILL_H 32 #include <OSKILL.h> 33 #endif 34 35 #ifndef __OFIRMID_H 36 #include <OFIRMID.h> 37 #endif 38 39 #ifndef __ORAWRES_H 40 #include <ORAWRES.h> 41 #endif 42 43 #ifndef __OTOWNRES_H 44 #include <OTOWNRES.h> 45 #endif 46 47 //------- define constant --------// 48 49 #define MAX_TOWN_GROWTH_POPULATION 60 // grow up to 60 persons in a town 50 #define MAX_TOWN_POPULATION 60 // MAX number of units in a town 51 52 //-------- Define constant -----------// 53 54 #define STD_TOWN_LOC_WIDTH 4 55 #define STD_TOWN_LOC_HEIGHT 4 56 57 //--------- Define training cost and level --------// 58 59 #define TRAIN_SKILL_COST 30 60 #define TRAIN_SKILL_LEVEL 20 61 #define TOTAL_TRAIN_DAYS 5 // No. of days needed for training an unit 62 63 #define MIN_RECRUIT_LOYALTY 30 // only when loyalty > this, the unit can be recruited 64 #define MIN_NATION_DEFEND_LOYALTY 50 // if the loyalty of the town people > this, they will defense against the attack 65 #define MIN_INDEPENDENT_DEFEND_LOYALTY 30 66 #define SURRENDER_LOYALTY 29 // when the loyalty of the town is <= this, and being attacked by a nation, the town will surrender 67 #define REBEL_LOYALTY 29 // if loyalty <= REBEL_LOYALTY, the unit may rebel 68 69 #define INDEPENDENT_LINK_RESISTANCE 50 // only if the resistance of an independent town is lower than this, the town will enable its link with a foreign firm 70 71 #define TAX_PER_PERSON 5 // amount of tax can be collected from each person 72 #define COLLECT_TAX_LOYALTY_DECREASE 10 // Reduce 10 loyalty points per tax collection 73 74 #define TOWN_REWARD_PER_PERSON 10 75 #define TOWN_REWARD_LOYALTY_INCREASE 10 76 77 #define IND_TOWN_GRANT_PER_PERSON 30 // independent town granting cost per person 78 #define IND_TOWN_GRANT_RESISTANCE_DECREASE 10 // resistance decrease per grant 79 80 #define RECEIVED_HIT_PER_KILL (200/ATTACK_SLOW_DOWN) // no. of received hits will result in one death of town people 81 82 #define MAX_TRAIN_QUEUE 10 83 84 //-------- Define class Town ----------// 85 86 class Unit; 87 #pragma pack(1) 88 class Town 89 { 90 public: 91 enum { TOWN_NAME_LEN=20 }; 92 93 short town_recno; 94 short town_name_id; town_name()95 char* town_name() { return town_res.get_name(town_name_id); } 96 97 short nation_recno; 98 short rebel_recno; // whether this town is controlled by a rebel 99 char race_id; 100 101 int setup_date; // the setup date of this town 102 103 char ai_town; 104 char ai_link_checked; // AI check firm and town locatin by links, disable checking by setting this parameter to 1 105 106 char independ_town_nation_relation; // each bit n is high representing this independent town will attack nation n. 107 char has_linked_own_camp; // whether the town has linked military camps of the same nation 108 char has_linked_enemy_camp; // whether the town has linked military camps of the same nation 109 110 char is_base_town; // whether this town is base town or not 111 112 short loc_x1, loc_y1, loc_x2, loc_y2; 113 short abs_x1, abs_y1, abs_x2, abs_y2; 114 loc_width()115 short loc_width() { return loc_x2-loc_x1+1; } loc_height()116 short loc_height() { return loc_y2-loc_y1+1; } 117 118 short center_x; 119 short center_y; 120 uint8_t region_id; 121 122 short layout_id; // town layout id. 123 short first_slot_id; // the first slot id. of the layout 124 125 short slot_object_id_array[MAX_TOWN_LAYOUT_SLOT]; // the race id. of each slot building 126 127 //---------- game vars ----------// 128 129 short population; 130 short jobless_population; worker_population()131 short worker_population() { return population-jobless_population; } 132 133 short max_race_pop_array[MAX_RACE]; // the MAX population the current town layout supports 134 short race_pop_array[MAX_RACE]; // population of each race 135 unsigned char race_pop_growth_array[MAX_RACE]; // population growth, when it reaches 100, there will be one more person in the town 136 short jobless_race_pop_array[MAX_RACE]; 137 int recruitable_race_pop(int raceId, int recruitSpy); 138 139 float race_loyalty_array[MAX_RACE]; 140 char race_target_loyalty_array[MAX_RACE]; 141 short race_spy_count_array[MAX_RACE]; // no. of spies in each race 142 143 float race_resistance_array[MAX_RACE][MAX_NATION]; 144 char race_target_resistance_array[MAX_RACE][MAX_NATION]; 145 146 int race_harmony(int raceId); 147 int majority_race(); // the race that has the majority of the population 148 149 int average_loyalty(); 150 int average_target_loyalty(); 151 int average_resistance(int nationRecno); 152 int average_target_resistance(int nationRecno); 153 154 short town_defender_count; // no. of units currently defending this town 155 int last_being_attacked_date; 156 float received_hit_count; // no. of received hit by attackers, when this > RECEIVED_HIT_PER_KILL, a town people will be killed 157 158 char train_queue_skill_array[MAX_TRAIN_QUEUE]; // it stores the skill id. 159 char train_queue_race_array[MAX_TRAIN_QUEUE]; // it stores the race id. 160 char train_queue_count; 161 short train_unit_recno; // race id. of the unit the town is currently training, 0-if currently not training any 162 int train_unit_action_id; // id. of the action to be assigned to this unit when it is finished training. 163 uint32_t start_train_frame_no; 164 short defend_target_recno; // used in defend mode, store recno of latest target atttacking this town 165 166 enum {TOWN_TRAIN_BATCH_COUNT = 8}; // Number of units enqueued when holding shift - ensure this is less than MAX_TRAIN_QUEUE 167 168 //-------- other vars ----------// 169 170 int accumulated_collect_tax_penalty; 171 int accumulated_reward_penalty; 172 int accumulated_recruit_penalty; 173 int accumulated_enemy_grant_penalty; 174 175 int last_rebel_date; 176 short independent_unit_join_nation_min_rating; 177 178 short quality_of_life; 179 void update_quality_of_life(); 180 181 //------- auto policy -------------// 182 183 short auto_collect_tax_loyalty; // auto collect tax if the loyalty reaches this level 184 short auto_grant_loyalty; // auto grant if the loyalty drop below this level 185 186 //----------- AI vars ------------// 187 188 char town_combat_level; // combat level of the people in this town 189 char has_product_supply[MAX_PRODUCT]; // whether this town has the supply of these products 190 char no_neighbor_space; // 1 if there is no space to build firms/towns next to this town 191 192 //------ inter-relationship -------// 193 194 short linked_firm_count; 195 short linked_town_count; 196 197 short linked_firm_array[MAX_LINKED_FIRM_TOWN]; 198 short linked_town_array[MAX_LINKED_TOWN_TOWN]; 199 200 char linked_firm_enable_array[MAX_LINKED_FIRM_TOWN]; 201 char linked_town_enable_array[MAX_LINKED_TOWN_TOWN]; 202 203 int closest_own_camp(); 204 205 //========== NOTE: The following members are not loaded from/saved to file ==========// 206 enum {SIZEOF_NONSAVED_ELEMENTS = sizeof(int)+sizeof(bool)}; 207 208 //--------- town network ----------// 209 int town_network_recno; // The recno of the town network this town belongs to. Note: this value can change between saving and loading. 210 bool town_network_pulsed; // Used for pulsing the town network to check which parts are still connected. Must always be set to false, and can only be true during a pulse-operation 211 212 //------ static class member var ------// 213 214 static short if_town_recno; 215 216 public: 217 Town(); 218 219 void init(int,int,int,int); 220 void deinit(); 221 222 void next_day(); 223 void draw(int displayLayer=1); 224 void process_ai(); 225 226 void disp_info(int refreshFlag); 227 void detect_info(); 228 int browse_selected_race_id(); 229 230 void assign_unit(int unitRecno); 231 int recruit(int withTraining, int raceId, char remoteAction); 232 int recruit_dec_loyalty(int raceId, int decNow=1); 233 void cancel_train_unit(); 234 int form_new_nation(); 235 236 int can_recruit(int raceId); 237 int can_train(int raceId); 238 bool can_migrate(int destTownRecno, bool migrateNow=false, int raceId=0); // if not called by Town::migrate, don't set migrateNow to TRUE 239 void move_pop(Town* destTown, int raceId, int hasJob); 240 int pick_random_race(int pickNonRecruitableAlso, int pickSpyFlag); 241 int camp_influence(int unitRecno); 242 243 void setup_link(); 244 void release_link(); 245 void release_firm_link(int); 246 void release_town_link(int); 247 int linked_active_camp_count(); 248 int can_toggle_firm_link(int firmRecno); 249 void update_camp_link(); 250 251 void init_pop(int raceId, int addPop, int loyalty, int hasJob=0, int firstInit=0); 252 void inc_pop(int raceId, int unitHasJob, int unitLoyalty); 253 void dec_pop(int raceId, int unitHasJob); 254 255 void draw_selected(); 256 int draw_detect_link_line(int); 257 int is_in_zoom_win(); 258 259 int has_linked_camp(int nationRecno, int needOverseer); 260 261 void auto_set_layout(); 262 void set_nation(int nationRecno); 263 void surrender(int toNationRecno); 264 265 void set_hostile_nation(int nationRecno); 266 void reset_hostile_nation(int nationRecno); 267 int is_hostile_nation(int nationRecno); 268 269 int create_rebel_unit(int raceId, int isLeader); 270 int mobilize_town_people(int raceId, int decPop, int mobilizeSpy); 271 int mobilize_defender(int attackerNationRecno); 272 273 int migrate_to(int destTownRecno, char remoteAction, int raceId=0, int count=1); 274 void collect_yearly_tax(); 275 void collect_tax(char remoteAction); 276 void reward(char remoteAction); 277 void distribute_demand(); 278 void being_attacked(int attackerUnitRecno, float attackDamage); 279 void clear_defense_mode(); 280 void reduce_defender_count(); 281 void kill_town_people(int raceId, int attackerUnitRecno=0); 282 283 int can_grant_to_non_own_town(int grantNationRecno); 284 int grant_to_non_own_town(int grantNationRecno, int remoteAction); 285 286 void get_most_populated_race(int& mostRaceId1, int& mostRaceId2); 287 288 void update_target_loyalty(); 289 void update_target_resistance(); 290 void update_loyalty(); 291 void update_resistance(); 292 void update_product_supply(); 293 void change_loyalty(int raceId, float loyaltyChange); 294 void change_resistance(int raceId, int nationRecno, float loyaltyChange); 295 296 void toggle_firm_link(int linkId, int toggleFlag, char remoteAction, int setBoth=0); 297 void toggle_town_link(int linkId, int toggleFlag, char remoteAction, int setBoth=0); 298 299 void auto_defense(short targetRecno); 300 int has_player_spy(); 301 void verify_slot_object_id_array(); 302 303 void set_auto_collect_tax_loyalty(int loyaltyLevel); 304 void set_auto_grant_loyalty(int loyaltyLevel); 305 void disp_auto_loyalty(); 306 307 void add_queue(char skillId, char raceId, int amount = 1); 308 void remove_queue(char skillId, int amount = 1); 309 310 int write_file(File*); 311 int read_file(File*); 312 313 //-------- ai functions ---------// 314 315 void think_collect_tax(); 316 void think_reward(); 317 int think_build_firm(int firmId, int maxFirm); 318 int think_build_market(); 319 int think_build_camp(); 320 int think_build_research(); 321 int think_build_war_factory(); 322 int think_build_base(); 323 int think_build_inn(); 324 int think_ai_migrate(); 325 int think_ai_migrate_to_town(); 326 void think_defense(); 327 int think_split_town(); 328 void think_move_between_town(); 329 int think_attack_nearby_enemy(); 330 int think_attack_linked_enemy(); 331 void think_capture_linked_firm(); 332 int think_capture_enemy_town(); 333 int think_scout(); 334 335 void update_base_town_status(); 336 int new_base_town_status(); 337 338 int think_counter_spy(); 339 int needed_anti_spy_level(); 340 341 int think_spying_town(); 342 int think_spying_town_assign_to(int raceId); 343 344 int should_ai_migrate(); 345 int detect_enemy(int); 346 347 int protection_needed(); // an index from 0 to 100 indicating the military protection needed for this town 348 int protection_available(); 349 350 int ai_build_neighbor_firm(int firmId, int firmRaceId=0); 351 int ai_settle_new(int raceId); 352 353 //-------- independent town ai functions ---------// 354 355 void think_independent_town(); 356 void think_independent_set_link(); 357 int think_independent_form_new_nation(); 358 int think_independent_unit_join_nation(); 359 int independent_unit_join_nation(int raceId, int toNationRecno); 360 361 //--------- function for cheat key ----------// 362 int get_selected_race(); 363 364 //-------------- multiplayer checking codes ---------------// 365 uint8_t crc8(); 366 void clear_ptr(); 367 368 //-------------------------------// 369 370 private: 371 void set_world_matrix(); 372 void restore_world_matrix(); 373 void establish_contact_with_player(); 374 375 void process_food(); 376 void process_auto(); 377 void process_train(); 378 void finish_train(Unit*); 379 void population_grow(); 380 void process_queue(); 381 void think_migrate(); 382 int think_migrate_one(Town* targetTown, int raceId, int townDistance); 383 void migrate(int raceId, int destTownZoneRecno, int newLoyalty); 384 int unjob_town_people(int raceId, int unjobOverseer, int killOverseer=0); 385 386 int think_layout_id(); 387 388 void draw_flag(int,int); 389 void draw_farm(int,int,int); 390 391 void disp_basic_info(int refreshFlag); 392 void disp_train_info(int refreshFlag); 393 394 void disp_main_menu(int refreshFlag); 395 int detect_main_menu(); 396 void disp_debug_resistance(int refreshFlag); 397 398 void disp_train_menu(int refreshFlag); 399 int detect_train_menu(); 400 401 void disp_auto_menu(int modeCollectTax); 402 int detect_auto_menu(int modeCollectTax); 403 404 void disp_spy_menu(int refreshFlag); 405 int detect_spy_menu(); 406 407 void think_rebel(); 408 int think_surrender(); 409 }; 410 #pragma pack() 411 412 //-------- Begin of class TownArray ------------// 413 414 class TownArray : public DynArrayB 415 { 416 public: 417 int selected_recno; // the firm current being selected 418 int race_wander_pop_array[MAX_RACE]; // no. of wandering people of each race. They are people for setting up independent towns later 419 420 public: 421 TownArray(); 422 ~TownArray(); 423 424 void init(); 425 void deinit(); 426 427 int add_town(int nationRecno, int raceId, int xLoc, int yLoc); 428 void del_town(int townRecno); 429 Town* create_town(); 430 431 void draw(); 432 void draw_dot(); 433 void draw_profile(); 434 435 void process(); 436 437 int independent_town_resistance(); 438 void think_new_independent_town(); 439 440 int think_town_loc(int maxTries, int& xLoc, int& yLoc); 441 int find_nearest_town(int xLoc, int yLoc, int nationRecno=0); 442 443 int settle(int unitRecno, int xLoc, int yLoc); 444 void distribute_demand(); 445 446 void stop_attack_nation(short nationRecno); 447 448 int write_file(File*); 449 int read_file(File*); 450 451 int is_deleted(int recNo); 452 453 #ifdef DYNARRAY_DEBUG_ELEMENT_ACCESS 454 Town* operator[](int recNo); 455 #else 456 Town* operator[](int recNo) { return (Town*) get_ptr(recNo); } 457 #endif 458 459 void disp_next(int seekDir, int sameNation); 460 }; 461 462 extern TownArray town_array; 463 464 //---------------------------------------------------// 465 466 #endif 467