-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathC3X.h
More file actions
2273 lines (1989 loc) · 91.3 KB
/
C3X.h
File metadata and controls
2273 lines (1989 loc) · 91.3 KB
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
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#include <stdbool.h>
#define NOVIRTUALKEYCODES // Keycodes defined in Civ3Conquests.h instead
#include "windows.h"
typedef unsigned char byte;
// Use fastcall as substitute for thiscall because TCC doesn't recognize thiscall
#define __fastcall __attribute__((fastcall))
#include "Civ3Conquests.h"
#define MOD_VERSION 2700
#define MOD_PREVIEW_VERSION 1
#define COUNT_TILE_HIGHLIGHTS 11
#define MAX_BUILDING_PREREQS_FOR_UNIT 10
#define COUNT_SPECIAL_DISTRICT_TYPES 10
#define USED_SPECIAL_DISTRICT_TYPES 11
#define MAX_DYNAMIC_DISTRICT_TYPES 22
#define COUNT_DISTRICT_TYPES (COUNT_SPECIAL_DISTRICT_TYPES + MAX_DYNAMIC_DISTRICT_TYPES)
#define MAX_WONDER_DISTRICT_TYPES 32
#define MAX_NATURAL_WONDER_DISTRICT_TYPES 32
#define MAX_DISTRICT_VARIANT_COUNT 5
#define MAX_DISTRICT_ERA_COUNT 4
#define MAX_DISTRICT_COLUMN_COUNT 10
#define C3X_DISTRICT_COMMAND_BASE (-11000000)
// Initialize to zero. Implementation is in common.c
struct table {
void * block;
size_t capacity_exponent; // Actual capacity is 1 << capacity_exponent
size_t len;
};
// Initialize to zero. Implementation in common.c
struct buffer {
byte * contents;
int length;
int capacity;
};
// A mill is a city improvement that spawns a resource. These are read from the "buildings_generating_resources" key in the config but are called
// "mills" internally for brevity.
enum mill_flag {
MF_LOCAL = 1,
MF_NO_TECH_REQ = 2,
MF_YIELDS = 4,
MF_SHOW_BONUS = 8,
MF_HIDE_NON_BONUS = 16
};
struct mill {
short improv_id;
short resource_id;
short flags;
};
#define ERA_ALIAS_LIST_CAPACITY 4 // Must not exceed 32 so we can store all genders as bits in an int
// A list of per-era aliases for a civ's noun, adjective, or formal name.
struct civ_era_alias_list {
char * key;
char * aliases[ERA_ALIAS_LIST_CAPACITY];
};
// A list of per-era aliases for a civ's leader's name, including genders and (optionally) titles.
struct leader_era_alias_list {
char * key;
char * aliases[ERA_ALIAS_LIST_CAPACITY];
int gender_bits; // Gender of each alias. Like LeaderGender in the Race object, 0 for male and 1 for female.
char * titles[ERA_ALIAS_LIST_CAPACITY]; // Title for each alias. May be NULL.
};
struct unit_type_limit {
int per_civ;
int per_city;
int cities_per;
};
struct work_area_improvement {
short improv_id;
int work_area_radius_limit;
int work_area_radius_bonus;
};
enum retreat_rules {
RR_STANDARD = 0,
RR_NONE,
RR_ALL_UNITS,
RR_IF_FASTER,
RR_IF_NOT_SLOWER,
RR_IF_FAST_AND_NOT_SLOWER,
};
enum line_drawing_override {
LDO_NEVER = 0,
LDO_WINE,
LDO_ALWAYS
};
enum minimap_doubling_mode {
MDM_NEVER = 0,
MDM_HIGH_DEF,
MDM_ALWAYS
};
enum unit_cycle_search_criteria {
UCSC_STANDARD = 0,
UCSC_SIMILAR_NEAR_START,
UCSC_SIMILAR_NEAR_DESTINATION
};
enum no_ai_patrol_override {
NAPO_ZERO = 0,
NAPO_ONE,
NAPO_NONE
};
enum barbarian_activity_override {
BAO_NONE = -2,
// The values for these levels must match what the game uses internally for Map.World.Final_Barbarians_Activity
BAO_NO_BARBARIANS = -1,
BAO_SEDENTARY = 0,
BAO_ROAMING = 1,
BAO_RESTLESS = 2,
BAO_RAGING = 3,
BAO_RANDOM = 4
};
enum special_defensive_bombard_rules {
SDBR_LETHAL = 1,
SDBR_NOT_INVISIBLE = 2,
SDBR_AERIAL = 4,
SDBR_BLITZ = 8,
SDBR_DOCKED_VS_LAND = 16,
};
enum special_zone_of_control_rules {
SZOCR_LETHAL = 1,
SZOCR_AERIAL = 2,
SZOCR_AMPHIBIOUS = 4,
SZOCR_NOT_FROM_INSIDE = 8,
};
enum land_transport_rules {
LTR_LOAD_ONTO_BOAT = 1,
LTR_JOIN_ARMY = 2,
LTR_NO_DEFENSE_FROM_INSIDE = 4,
LTR_NO_ESCAPE = 8,
};
enum special_helicopter_rules {
SHR_ALLOW_ON_CARRIERS = 1,
SHR_PASSENGER_AIRDROP = 2,
SHR_NO_DEFENSE_FROM_INSIDE = 4,
SHR_NO_ESCAPE = 8,
};
enum work_area_limit {
WAL_NONE = 0,
WAL_CULTURAL,
WAL_CULTURAL_MIN_2,
WAL_CULTURAL_OR_ADJACENT
};
enum day_night_cycle_mode {
DNCM_OFF = 0,
DNCM_TIMER,
DNCM_USER_TIME,
DNCM_EVERY_TURN,
DNCM_SPECIFIED
};
enum distribution_hub_yield_division_mode {
DHYDM_FLAT = 0,
DHYDM_SCALE_BY_CITY_COUNT
};
enum ai_distribution_hub_build_strategy {
ADHBS_AUTO = 0,
ADHBS_BY_CITY_COUNT
};
enum ai_auto_build_great_wall_strategy {
AAGWS_ALL_BORDERS = 0,
AAGWS_OTHER_CIV_BORDERED_ONLY
};
enum perfume_kind {
PK_PRODUCTION = 0,
PK_TECHNOLOGY,
PK_GOVERNMENT,
COUNT_PERFUME_KINDS
};
struct c3x_config {
bool enable_stack_bombard;
bool enable_disorder_warning;
bool allow_stealth_attack_against_single_unit;
bool show_detailed_city_production_info;
int limit_railroad_movement;
bool limited_railroads_work_like_fast_roads;
int limit_units_per_tile[3]; // Limits for land, sea, and air units respectively
bool exclude_cities_from_units_per_tile_limit;
struct table exclude_types_from_units_per_tile_limit;
bool enable_free_buildings_from_small_wonders;
bool enable_stack_unit_commands;
bool skip_repeated_tile_improv_replacement_asks;
bool autofill_best_gold_amount_when_trading;
int minimum_city_separation;
bool disallow_founding_next_to_foreign_city;
bool enable_trade_screen_scroll;
bool group_units_on_right_click_menu;
bool gray_out_units_on_menu_with_no_remaining_moves;
bool put_movement_icons_on_units_on_menu;
bool describe_states_of_units_on_menu;
int anarchy_length_percent;
bool show_golden_age_turns_remaining;
bool show_zoc_attacks_from_mid_stack;
bool show_armies_performing_defensive_bombard;
bool cut_research_spending_to_avoid_bankruptcy;
bool dont_pause_for_love_the_king_messages;
bool reverse_specialist_order_with_shift;
bool toggle_zoom_with_z_on_city_screen;
bool enable_mouse_wheel_zoom;
bool dont_give_king_names_in_non_regicide_games;
bool no_elvis_easter_egg;
bool disable_worker_automation;
bool enable_land_sea_intersections;
bool disallow_trespassing;
bool show_detailed_tile_info;
struct table perfume_specs[COUNT_PERFUME_KINDS]; // Each table maps strings to i31b's. Each i31b combines an amount and whether it's a percent
struct table building_unit_prereqs; // A mapping from int keys to int values. The keys are unit type IDs. If an ID is present as a key in the
// table that means that unit type has one or more prereq buildings. The associated value is either a
// pointer to a list of MAX_BUILDING_PREREQS_FOR_UNITS improvement IDs or a single encoded improv ID. The
// contents of the list are NOT encoded and unused slots store -1. Encoding an ID is done by left-shifting
// it one place then inserting a 1 in the LSB. This way encoded IDs can be told apart from list pointers
// by checking the LSB (1 => encoded improv ID, 0 => list pointer).
struct mill * mills;
int count_mills;
bool warn_about_unrecognized_names;
bool enable_ai_production_ranking;
bool enable_ai_city_location_desirability_display;
bool show_ai_city_location_desirability_if_settler;
bool zero_corruption_when_off;
bool disallow_land_units_from_affecting_water_tiles;
bool dont_end_units_turn_after_airdrop;
bool allow_airdrop_without_airport;
bool enable_negative_pop_pollution;
enum retreat_rules land_retreat_rules;
enum retreat_rules sea_retreat_rules;
bool allow_defensive_retreat_on_water;
struct table limit_defensive_retreat_on_water_to_types; // Table mapping unit type IDs to 1's; used as a hash set
int ai_multi_city_start;
int max_tries_to_place_fp_city;
int * ai_multi_start_extra_palaces;
int count_ai_multi_start_extra_palaces;
int ai_multi_start_extra_palaces_capacity;
bool promote_wonder_decorruption_effect;
bool allow_military_leaders_to_hurry_wonders;
int ai_research_multiplier;
int ai_settler_perfume_on_founding;
int ai_settler_perfume_on_founding_duration;
bool aggressively_penalize_bankruptcy;
bool no_penalty_exception_for_agri_fresh_water_city_tiles;
bool suppress_hypertext_links_exceeded_popup;
bool indicate_non_upgradability_in_pedia;
bool show_message_after_dodging_sam;
bool include_stealth_attack_cancel_option;
bool intercept_recon_missions;
bool charge_one_move_for_recon_and_interception;
bool polish_precision_striking;
bool enable_stealth_attack_via_bombardment;
bool immunize_aircraft_against_bombardment;
bool replay_ai_moves_in_hotseat_games;
struct table ptw_arty_types; // Table mapping unit type IDs to 1's; used as a hash set
struct table can_bombard_only_sea_tiles; // Table mapping unit type IDs to 1's; used as a hash set
bool restore_unit_directions_on_game_load;
bool apply_grid_ini_setting_on_game_load;
bool charm_flag_triggers_ptw_like_targeting;
bool city_icons_show_unit_effects_not_trade;
bool ignore_king_ability_for_defense_priority;
bool show_untradable_techs_on_trade_screen;
bool disallow_useless_bombard_vs_airfields;
enum line_drawing_override draw_lines_using_gdi_plus;
bool compact_luxury_display_on_city_screen;
bool compact_strategic_resource_display_on_city_screen;
bool warn_when_chosen_building_would_replace_another;
bool do_not_unassign_workers_from_polluted_tiles;
bool do_not_make_capital_cities_appear_larger;
bool show_territory_colors_on_water_tiles_in_minimap;
bool convert_some_popups_into_online_mp_messages;
bool enable_debug_mode_switch;
bool accentuate_cities_on_minimap;
enum minimap_doubling_mode double_minimap_size;
bool allow_multipage_civilopedia_descriptions;
enum unit_cycle_search_criteria unit_cycle_search_criteria;
bool reformat_turns_remaining_on_domestic_advisor_screen;
bool enable_city_capture_by_barbarians;
bool share_visibility_in_hotseat;
bool share_wonders_in_hotseat;
bool allow_precision_strikes_against_tile_improvements;
bool dont_end_units_turn_after_bombarding_barricade;
bool remove_land_artillery_target_restrictions;
bool allow_bombard_of_other_improvs_on_occupied_airfield;
bool show_total_city_count;
bool strengthen_forbidden_palace_ocn_effect;
int extra_unit_maintenance_per_shields;
enum special_zone_of_control_rules special_zone_of_control_rules;
enum special_defensive_bombard_rules special_defensive_bombard_rules;
struct civ_era_alias_list * civ_era_alias_lists;
int count_civ_era_alias_lists;
struct leader_era_alias_list * leader_era_alias_lists;
int count_leader_era_alias_lists;
struct table unit_limits; // Maps unit type names (strings) to pointers to limit objects (struct unit_type_limit *)
bool allow_upgrades_in_any_city;
bool do_not_generate_volcanos;
bool do_not_pollute_impassable_tiles;
bool show_hp_of_stealth_attack_options;
bool exclude_invisible_units_from_stealth_attack;
bool exclude_passengers_from_stealth_attack;
bool convert_to_landmark_after_planting_forest;
int chance_for_nukes_to_destroy_max_one_hp_units;
bool allow_sale_of_aqueducts_and_hospitals;
bool no_cross_shore_detection;
int city_work_radius;
bool auto_zoom_city_screen_for_large_work_areas;
enum work_area_limit work_area_limit;
struct work_area_improvement * work_area_improvements;
int count_work_area_improvements;
int rebase_range_multiplier;
bool limit_unit_loading_to_one_transport_per_turn;
bool prevent_old_units_from_upgrading_past_ability_block;
bool introduce_all_human_players_at_start_of_hotseat_game;
bool allow_unload_from_army;
enum land_transport_rules land_transport_rules;
bool allow_adjacent_resources_of_different_types;
bool allow_corruption_in_capital;
int special_capital_decorruption_effect;
int luxury_randomized_appearance_rate_percent;
int tiles_per_non_luxury_resource;
bool no_land_anti_air_from_inside_naval_transport;
enum special_helicopter_rules special_helicopter_rules;
bool prevent_enslaving_by_bombardment;
int years_to_double_building_culture;
int tourism_time_scale_percent;
bool allow_sale_of_small_wonders;
enum no_ai_patrol_override override_no_ai_patrol;
enum barbarian_activity_override override_barbarian_activity_level_for_scenario_maps;
bool initialize_preplaced_scenario_leaders_as_mgls;
bool enable_trade_net_x;
bool optimize_improvement_loops;
bool measure_turn_times;
bool use_offensive_artillery_ai;
bool dont_escort_unflagged_units;
int ai_build_artillery_ratio;
int ai_artillery_value_damage_percent;
int ai_build_bomber_ratio;
bool replace_leader_unit_ai;
bool fix_ai_army_composition;
bool enable_pop_unit_ai;
bool enable_caravan_unit_ai;
int max_ai_naval_escorts;
int ai_worker_requirement_percent;
bool remove_unit_limit;
bool remove_city_improvement_limit;
int city_limit;
bool remove_cap_on_turn_limit;
bool remove_era_limit;
bool patch_submarine_bug;
bool patch_science_age_bug;
bool patch_pedia_texture_bug;
bool patch_blocked_disembark_freeze;
bool patch_houseboat_bug;
bool patch_intercept_lost_turn_bug;
bool patch_phantom_resource_bug;
bool patch_maintenance_persisting_for_obsolete_buildings;
bool patch_barbarian_diagonal_bug;
bool patch_disease_stopping_tech_flag_bug;
bool patch_division_by_zero_in_ai_alliance_eval;
bool patch_empty_army_movement;
bool patch_empty_army_combat_crash;
bool delete_off_map_ai_units;
bool fix_overlapping_specialist_yield_icons;
bool patch_premature_truncation_of_found_paths;
bool patch_zero_production_crash;
bool patch_ai_can_form_army_without_special_ability;
bool patch_ai_can_sacrifice_without_special_ability;
bool patch_crash_in_leader_unit_ai;
bool patch_failure_to_find_new_city_build;
bool patch_passengers_out_of_order_on_menu;
bool prevent_autorazing;
bool prevent_razing_by_players;
bool allow_extraterritorial_colonies;
int per_extraterritorial_colony_relation_penalty;
bool draw_forests_over_roads_and_railroads;
bool enable_named_tiles;
char * aircraft_victory_animation; // NULL if set to "none" in config
int day_night_cycle_mode;
int elapsed_minutes_per_day_night_hour_transition;
int fixed_hours_per_turn_for_day_night_cycle;
int pinned_hour_for_day_night_cycle;
bool enable_natural_wonders;
bool add_natural_wonders_to_scenarios_if_none;
bool show_natural_wonder_name_on_map;
int minimum_natural_wonder_separation;
bool enable_districts;
bool enable_neighborhood_districts;
bool enable_wonder_districts;
bool enable_distribution_hub_districts;
bool enable_aerodrome_districts;
bool enable_port_districts;
bool enable_bridge_districts;
bool enable_canal_districts;
bool enable_central_rail_hub_districts;
bool enable_energy_grid_districts;
bool enable_great_wall_districts;
bool cities_with_mutual_district_receive_buildings;
bool cities_with_mutual_district_receive_wonders;
bool show_message_when_building_received_by_mutual_district;
bool show_message_when_building_lost_to_destroyed_district;
bool air_units_use_aerodrome_districts_not_cities;
bool naval_units_use_port_districts_not_cities;
int maximum_pop_before_neighborhood_needed;
int per_neighborhood_pop_growth_enabled;
int neighborhood_needed_message_frequency;
bool destroying_neighborhood_reduces_pop;
bool completed_wonder_districts_can_be_destroyed;
bool destroyed_wonders_can_be_built_again;
int distribution_hub_yield_division_mode;
int distribution_hub_food_yield_divisor;
int distribution_hub_shield_yield_divisor;
int ai_distribution_hub_build_strategy;
int ai_ideal_distribution_hub_count_per_100_cities;
int max_distribution_hub_count_per_100_cities;
int central_rail_hub_distribution_food_bonus_percent;
int central_rail_hub_distribution_shield_bonus_percent;
bool workers_can_enter_coast;
bool expand_water_tile_checks_to_city_work_area;
int max_contiguous_bridge_districts;
int max_contiguous_canal_districts;
int ai_canal_eval_min_bisected_land_tiles;
int ai_bridge_canal_eval_block_size;
int ai_bridge_eval_lake_tile_threshold;
bool ai_can_replace_existing_districts_with_canals;
bool ai_builds_bridges;
bool ai_builds_canals;
bool ai_defends_districts;
int ai_city_district_max_build_wait_turns;
bool disable_great_wall_city_defense_bonus;
bool great_wall_districts_impassible_by_others;
bool auto_build_great_wall_around_territory;
char * great_wall_auto_build_wonder_name;
int great_wall_auto_build_wonder_improv_id;
int ai_auto_build_great_wall_strategy;
bool enable_city_work_radii_highlights;
};
enum stackable_command {
SC_BOMBARD = 0,
SC_BOMB,
SC_FORTRESS,
SC_MINE,
SC_IRRIGATE,
SC_CHOP_FOREST,
SC_CHOP_JUNGLE,
SC_PLANT,
SC_CLEAN_POLLUTION,
SC_ROAD,
SC_RAILROAD,
SC_FORTIFY,
SC_UPGRADE,
SC_DISBAND,
COUNT_STACKABLE_COMMANDS
};
enum stackable_command_kind {
SCK_BOMBARD = 0,
SCK_TERRAFORM,
SCK_UNIT_MGMT,
COUNT_STACKABLE_COMMAND_KINDS
};
struct sc_button_info {
enum Unit_Command_Values command;
enum stackable_command_kind kind;
int tile_sheet_column,
tile_sheet_row;
} const sc_button_infos[COUNT_STACKABLE_COMMANDS] = {
/* Bombard */ { .command = UCV_Bombard , .kind = SCK_BOMBARD , .tile_sheet_column = 3, .tile_sheet_row = 1 },
/* Bomb */ { .command = UCV_Bombing , .kind = SCK_BOMBARD , .tile_sheet_column = 5, .tile_sheet_row = 4 },
/* Fortress */ { .command = UCV_Build_Fortress , .kind = SCK_TERRAFORM, .tile_sheet_column = 0, .tile_sheet_row = 3 },
/* Mine */ { .command = UCV_Build_Mine , .kind = SCK_TERRAFORM, .tile_sheet_column = 1, .tile_sheet_row = 3 },
/* Irrigate */ { .command = UCV_Irrigate , .kind = SCK_TERRAFORM, .tile_sheet_column = 2, .tile_sheet_row = 3 },
/* Chop For. */ { .command = UCV_Clear_Forest , .kind = SCK_TERRAFORM, .tile_sheet_column = 3, .tile_sheet_row = 3 },
/* Chop Jun. */ { .command = UCV_Clear_Jungle , .kind = SCK_TERRAFORM, .tile_sheet_column = 4, .tile_sheet_row = 3 },
/* Plant */ { .command = UCV_Plant_Forest , .kind = SCK_TERRAFORM, .tile_sheet_column = 5, .tile_sheet_row = 3 },
/* Clean Pol. */ { .command = UCV_Clear_Pollution, .kind = SCK_TERRAFORM, .tile_sheet_column = 6, .tile_sheet_row = 3 },
/* Road */ { .command = UCV_Build_Road , .kind = SCK_TERRAFORM, .tile_sheet_column = 6, .tile_sheet_row = 2 },
/* Railroad */ { .command = UCV_Build_Railroad , .kind = SCK_TERRAFORM, .tile_sheet_column = 7, .tile_sheet_row = 2 },
/* Fortify */ { .command = UCV_Fortify , .kind = SCK_UNIT_MGMT, .tile_sheet_column = 2, .tile_sheet_row = 0 },
/* Upgrade */ { .command = UCV_Upgrade_Unit , .kind = SCK_UNIT_MGMT, .tile_sheet_column = 7, .tile_sheet_row = 1 },
/* Disband */ { .command = UCV_Disband , .kind = SCK_UNIT_MGMT, .tile_sheet_column = 3, .tile_sheet_row = 0 },
};
enum init_state {
IS_UNINITED = 0,
IS_OK,
IS_INIT_FAILED
};
enum c3x_label {
CL_NEVER_COMPLETES = 0,
CL_HALTED,
CL_SURPLUS,
CL_SURPLUS_NONE,
CL_SURPLUS_NA,
CL_SB_TOOLTIP,
CL_CHOPPED,
CL_OFF,
CL_MOD_INFO_BUTTON_TEXT,
CL_VERSION,
CL_CONFIG_FILES_LOADED,
CL_CREATING_CITIES,
CL_MCS_FAILED_SANITY_CHECK,
CL_MCS_ADJACENT_CITIES,
CL_MCS_MISSING_CITIES,
CL_OBSOLETED_BY,
CL_NO_STEALTH_ATTACK,
CL_DODGED_SAM,
CL_PREVIEW,
CL_CITY_TOO_CLOSE_BUTTON_TOOLTIP,
CL_TOTAL_CITIES,
// Offense, Defense, Artillery, etc.
CL_FIRST_UNIT_STRAT,
CL_LAST_UNIT_STRAT = CL_FIRST_UNIT_STRAT + 19,
// Unit actions for right-click menu
CL_IDLE,
CL_FORTIFIED,
CL_SENTRY,
CL_MINING,
CL_IRRIGATING,
CL_BUILDING_FORTRESS,
CL_BUILDING_ROAD,
CL_BUILDING_RAILROAD,
CL_PLANTING_FOREST,
CL_CLEARING_FOREST,
CL_CLEARING_WETLANDS,
CL_CLEARING_DAMAGE,
CL_BUILDING_AIRFIELD,
CL_BUILDING_RADAR_TOWER,
CL_BUILDING_OUTPOST,
CL_BUILDING_BARRICADE,
CL_BUILDING_COLONY,
CL_INTERCEPTING,
CL_MOVING,
CL_AUTOMATED,
CL_EXPLORING,
CL_BOMBARDING,
// Generic "Building" phrase for Districts right-click menu
CL_BUILDING,
// Districts-related texts
CL_REQUIRES,
CL_TO_GROW,
CL_DISTRICT_DESTROYED_BY_VOLCANO,
CL_CONSTRUCTION_HALTED_DUE_TO_MISSING_DISTRICT,
CL_LOST_POPULATION_DUE_TO_DESTROYED_NEIGHBORHOOD,
CL_RECEIVED,
CL_FROM_SHARED,
CL_WITH,
CL_APOSTROPHE_S,
CL_AND,
CL_OTHER_BUILDINGS_HAVE_BEEN,
CL_LOST_DUE_TO_DESTROYED,
// Districts config mismatch checked on game load
CL_DISTRICT_ID,
CL_DISTRICT_IN_SAVE_BUT_MISSING_NOW,
CL_DISTRICT_NAME_MISMATCH,
CL_SAVE_FILE_HAD,
CL_CURRENT_CONFIG_HAS_ONLY,
CL_WARNING_DISTRICTS_CONFIG_MISMATCH,
CL_MAY_BE_OTHER_ERRORS_AS_WELL,
CL_DISTRICTS_IN_SAVE_FILE,
CL_CURRENTLY_CONFIGURED_DISTRICTS,
// Tile naming
CL_NAME_TILE,
CL_RENAME_TILE,
// "Action" for passenger units
CL_TRANSPORTED,
CL_IN_STATE_27,
CL_IN_STATE_28,
CL_IN_STATE_29,
CL_IN_STATE_30,
CL_IN_STATE_33,
CL_AGRICULTURAL,
CL_COMMERCIAL,
CL_EXPANSIONIST,
CL_INDUSTRIOUS,
CL_MILITARISTIC,
CL_RELIGIOUS,
CL_SCIENTIFIC,
CL_SEAFARING,
COUNT_C3X_LABELS
};
struct worker_job_and_location {
enum Worker_Jobs job;
int tile_x, tile_y;
};
struct ai_prod_valuation {
int order_type;
int order_id;
int point_value;
};
enum unit_rcm_icon {
URCMI_UNMOVED = 0,
URCMI_MOVED_CAN_ATTACK,
URCMI_MOVED_NO_ATTACK,
URCMI_CANT_MOVE,
COUNT_UNIT_RCM_ICONS
};
enum unit_rcm_icon_set {
URCMIS_ATTACKER = 0,
URCMIS_NONCOMBAT,
URCMIS_BUSY_ATTACKER,
URCMIS_BUSY_NONCOMBAT,
COUNT_UNIT_RCM_ICON_SETS
};
enum city_gain_reason {
CGR_FOUNDED = 0,
CGR_CONQUERED,
CGR_CONVERTED, // covers culture flips & bribes
CGR_TRADED,
CGR_POPPED_FROM_HUT,
CGR_PLACED_FOR_AI_RESPAWN,
CGR_PLACED_FOR_SCENARIO,
CGR_PLACED_FOR_AI_MULTI_CITY_START,
};
enum city_loss_reason {
CLR_DESTROYED = 0, // means city was razed for any reason (inc. by conqueror)
CLR_CONQUERED,
CLR_CONVERTED, // covers culture flips & bribes
CLR_TRADED
};
enum {
MAX_DISTRICT_DEPENDENTS = 64
};
enum {
DEFAULT_DISTRICT_BUILDABLE_MASK = (1 << SQ_Desert) | (1 << SQ_Plains) | (1 << SQ_Grassland) | (1 << SQ_Tundra) | (1 << SQ_FloodPlain) | (1 << SQ_Hills)
};
enum {
MAX_DISTRICT_BONUS_ENTRIES = 16
};
enum district_bonus_entry_type {
DBET_TILE = 0,
DBET_BUILDING = 1
};
enum great_wall_auto_build_state {
GWABS_NOT_STARTED = 0,
GWABS_RUNNING,
GWABS_DONE
};
struct district_bonus_entry {
enum district_bonus_entry_type type;
int bonus;
enum SquareTypes tile_type;
int building_id;
char const * building_name;
};
struct district_bonus_list {
int count;
struct district_bonus_entry entries[MAX_DISTRICT_BONUS_ENTRIES];
};
enum district_render_strategy {
DRS_BY_COUNT = 0,
DRS_BY_BUILDING = 1
};
enum district_ai_build_strategy {
DABS_DISTRICT = 0,
DABS_TILE_IMPROVEMENT = 1
};
struct district_config {
enum Unit_Command_Values command;
char const * name;
char const * display_name;
char const * tooltip;
char const * advance_prereqs[MAX_DISTRICT_DEPENDENTS];
int advance_prereq_count;
char const * obsoleted_by;
char const * resource_prereqs[MAX_DISTRICT_DEPENDENTS];
char const * resource_prereq_on_tile;
char const * dependent_improvements[MAX_DISTRICT_DEPENDENTS];
char const * wonder_prereqs[MAX_DISTRICT_DEPENDENTS];
char const * natural_wonder_prereqs[MAX_DISTRICT_DEPENDENTS];
char const * buildable_on_districts[MAX_DISTRICT_DEPENDENTS];
char const * buildable_adjacent_to_districts[MAX_DISTRICT_DEPENDENTS];
char const * img_paths[10];
unsigned int buildable_square_types_mask;
unsigned int buildable_adjacent_to_square_types_mask;
unsigned int buildable_without_removal_mask;
unsigned int buildable_on_overlays_mask;
unsigned int buildable_adjacent_to_overlays_mask;
bool buildable_on_rivers;
bool buildable_adjacent_to_allows_city;
bool allow_multiple;
bool vary_img_by_era;
bool vary_img_by_culture;
enum district_render_strategy render_strategy;
enum district_ai_build_strategy ai_build_strategy;
bool is_dynamic;
bool align_to_coast;
bool draw_over_resources;
bool allow_irrigation_from;
bool auto_add_road;
bool auto_add_railroad;
int custom_width;
int custom_height;
int x_offset;
int y_offset;
int resource_prereq_count;
int dependent_improvement_max_index;
int wonder_prereq_count;
int natural_wonder_prereq_count;
int buildable_on_district_count;
int buildable_adjacent_to_district_count;
int img_path_count;
int img_column_count;
bool has_img_column_count_override;
int btn_tile_sheet_column;
int btn_tile_sheet_row;
int culture_bonus;
int science_bonus;
int food_bonus;
int gold_bonus;
int shield_bonus;
int happiness_bonus;
struct district_bonus_list culture_bonus_extras;
struct district_bonus_list science_bonus_extras;
struct district_bonus_list food_bonus_extras;
struct district_bonus_list gold_bonus_extras;
struct district_bonus_list shield_bonus_extras;
struct district_bonus_list happiness_bonus_extras;
struct district_bonus_list defense_bonus_extras;
int defense_bonus_percent;
bool heal_units_in_one_turn;
bool impassible;
bool impassible_to_wheeled;
char const * generated_resource;
int generated_resource_id;
short generated_resource_flags;
int buildable_on_district_ids[MAX_DISTRICT_DEPENDENTS];
int buildable_on_district_id_count;
bool has_buildable_on_districts;
int buildable_adjacent_to_district_ids[MAX_DISTRICT_DEPENDENTS];
int buildable_adjacent_to_district_id_count;
bool has_buildable_adjacent_to;
bool has_buildable_adjacent_to_districts;
bool has_buildable_without_removal;
bool has_buildable_on_overlays;
bool has_buildable_adjacent_to_overlays;
bool has_buildable_on_rivers;
char const * buildable_by_civs[32];
int buildable_by_civ_count;
bool has_buildable_by_civs;
int buildable_by_civ_traits_ids[8];
int buildable_by_civ_traits_id_count;
bool has_buildable_by_civ_traits;
int buildable_by_civ_govs_ids[5];
int buildable_by_civ_govs_id_count;
bool has_buildable_by_civ_govs;
int buildable_by_civ_cultures_ids[5];
int buildable_by_civ_cultures_id_count;
bool has_buildable_by_civ_cultures;
bool buildable_by_war_allies;
bool buildable_by_pact_allies;
};
struct wonder_district_config {
char const * wonder_name;
char const * img_path;
int index,
img_row,
img_column,
img_construct_row,
img_construct_column,
img_alt_dir_construct_row,
img_alt_dir_construct_column,
img_alt_dir_row,
img_alt_dir_column,
custom_width,
custom_height;
unsigned int buildable_square_types_mask;
unsigned int buildable_adjacent_to_square_types_mask;
unsigned int buildable_adjacent_to_overlays_mask;
bool buildable_on_rivers;
bool buildable_adjacent_to_allows_city;
char const * buildable_by_civs[32];
int buildable_by_civ_count;
bool has_buildable_by_civs;
int buildable_by_civ_traits_ids[8];
int buildable_by_civ_traits_id_count;
bool has_buildable_by_civ_traits;
int buildable_by_civ_govs_ids[5];
int buildable_by_civ_govs_id_count;
bool has_buildable_by_civ_govs;
int buildable_by_civ_cultures_ids[5];
int buildable_by_civ_cultures_id_count;
bool has_buildable_by_civ_cultures;
bool enable_img_alt_dir;
bool is_dynamic;
bool has_buildable_adjacent_to;
bool has_buildable_adjacent_to_overlays;
};
enum square_type_extras {
SQ_INVALID = -1,
SQ_RIVER = SQ_Ocean + 1,
SQ_SNOW_VOLCANO,
SQ_SNOW_FOREST,
SQ_SNOW_MOUNTAIN
};
enum district_overlay_mask_bits {
DOM_MINE = 1u << 0,
DOM_IRRIGATION = 1u << 1,
DOM_FORTRESS = 1u << 2,
DOM_BARRICADE = 1u << 3,
DOM_OUTPOST = 1u << 4,
DOM_RADAR_TOWER = 1u << 5,
DOM_JUNGLE = 1u << 6,
DOM_FOREST = 1u << 7,
DOM_SWAMP = 1u << 8,
DOM_RIVER = 1u << 9,
DOM_AIRFIELD = 1u << 10
};
struct natural_wonder_district_config {
char const * name;
char const * img_path;
enum SquareTypes terrain_type;
enum SquareTypes adjacent_to;
enum direction adjacency_dir;
int index;
int img_row;
int img_column;
int culture_bonus;
int science_bonus;
int food_bonus;
int gold_bonus;
int shield_bonus;
int happiness_bonus;
bool impassible;
bool impassible_to_wheeled;
bool is_dynamic;
};
struct natural_wonder_candidate {
Tile * tile;
short x, y;
};
struct natural_wonder_candidate_list {
struct natural_wonder_candidate * entries;
int count;
int capacity;
};
struct wonder_location {
short x;
short y;
};
const struct district_config special_district_defaults[USED_SPECIAL_DISTRICT_TYPES] = {
{
.command = UCV_Build_Neighborhood, .name = "Neighborhood", .tooltip = "Build Neighborhood", .display_name = "Neighborhood",
.advance_prereqs = {0}, .advance_prereq_count = 0, .resource_prereqs = {0}, .resource_prereq_on_tile = NULL, .allow_multiple = true, .vary_img_by_era = true, .vary_img_by_culture = true, .is_dynamic = false, .resource_prereq_count = 0, .dependent_improvement_max_index = 0, .dependent_improvements = {0},
.img_paths = {"Neighborhood_AMER.pcx", "Neighborhood_EURO.pcx", "Neighborhood_ROMAN.pcx", "Neighborhood_MIDEAST.pcx", "Neighborhood_ASIAN.pcx"},
.buildable_square_types_mask = DEFAULT_DISTRICT_BUILDABLE_MASK,
.img_path_count = 5, .img_column_count = 4, .btn_tile_sheet_column = 0, .btn_tile_sheet_row = 0,
.culture_bonus = 1, .science_bonus = 1, .food_bonus = 0, .gold_bonus = 1, .shield_bonus = 0, .happiness_bonus = 0, .defense_bonus_percent = 25,
.generated_resource = NULL, .generated_resource_id = -1, .generated_resource_flags = 0
},
{
.command = UCV_Build_WonderDistrict, .name = "Wonder District", .tooltip = "Build Wonder District", .display_name = "Wonder District",
.advance_prereqs = {0}, .advance_prereq_count = 0, .resource_prereqs = {0}, .resource_prereq_on_tile = NULL, .allow_multiple = true, .vary_img_by_era = true, .vary_img_by_culture = false, .is_dynamic = false, .resource_prereq_count = 0, .dependent_improvement_max_index = 0, .dependent_improvements = {0},
.img_paths = {"WonderDistrict.pcx"},
.buildable_square_types_mask = (unsigned int)(DEFAULT_DISTRICT_BUILDABLE_MASK | (1 << SQ_Coast) | (1 << SQ_Mountains)),
.img_path_count = 1, .img_column_count = 1, .btn_tile_sheet_column = 1, .btn_tile_sheet_row = 0,
.culture_bonus = 0, .science_bonus = 0, .food_bonus = 0, .gold_bonus = 0, .shield_bonus = 0, .happiness_bonus = 0, .defense_bonus_percent = 0,
.generated_resource = NULL, .generated_resource_id = -1, .generated_resource_flags = 0
},
{
.command = UCV_Build_DistributionHub, .name = "Distribution Hub", .tooltip = "Build Distribution Hub", .display_name = "Distribution Hub",
.advance_prereqs = {"Construction"}, .advance_prereq_count = 1, .resource_prereqs = {0}, .resource_prereq_on_tile = NULL, .allow_multiple = true, .vary_img_by_era = true, .vary_img_by_culture = false, .is_dynamic = false, .resource_prereq_count = 0, .dependent_improvement_max_index = 0, .dependent_improvements = {0},
.img_paths = {"DistributionHub.pcx"},
.buildable_square_types_mask = DEFAULT_DISTRICT_BUILDABLE_MASK,
.img_path_count = 1, .img_column_count = 1, .btn_tile_sheet_column = 2, .btn_tile_sheet_row = 0,
.culture_bonus = 0, .science_bonus = 0, .food_bonus = 0, .gold_bonus = 0, .shield_bonus = 0, .happiness_bonus = 0, .defense_bonus_percent = 0,
.generated_resource = NULL, .generated_resource_id = -1, .generated_resource_flags = 0
},
{
.command = UCV_Build_Aerodrome, .name = "Aerodrome", .tooltip = "Build Aerodrome", .display_name = "Aerodrome",
.advance_prereqs = {"Flight"}, .advance_prereq_count = 1, .resource_prereqs = {0}, .resource_prereq_on_tile = NULL, .allow_multiple = true, .vary_img_by_era = true, .vary_img_by_culture = false, .is_dynamic = false, .resource_prereq_count = 0, .dependent_improvement_max_index = 1,
.img_paths = {"Aerodrome.pcx"}, .dependent_improvements = {"Airport"},
.buildable_square_types_mask = DEFAULT_DISTRICT_BUILDABLE_MASK,
.img_path_count = 1, .img_column_count = 2, .btn_tile_sheet_column = 3, .btn_tile_sheet_row = 0,
.culture_bonus = 0, .science_bonus = 0, .food_bonus = 0, .gold_bonus = 0, .shield_bonus = 0, .happiness_bonus = 0, .defense_bonus_percent = 0,
.generated_resource = NULL, .generated_resource_id = -1, .generated_resource_flags = 0
},
{
.command = -1, .name = "Natural Wonder", .tooltip = NULL, .display_name = "Natural Wonder",
.advance_prereqs = {0}, .advance_prereq_count = 0, .resource_prereqs = {0}, .resource_prereq_on_tile = NULL, .allow_multiple = true, .vary_img_by_era = false, .vary_img_by_culture = false, .is_dynamic = false, .resource_prereq_count = 0, .dependent_improvement_max_index = 0, .dependent_improvements = {0},
.img_paths = {0},
.buildable_square_types_mask = DEFAULT_DISTRICT_BUILDABLE_MASK,
.img_path_count = 0, .img_column_count = 0, .btn_tile_sheet_column = 0, .btn_tile_sheet_row = 0,
.culture_bonus = 0, .science_bonus = 0, .food_bonus = 0, .gold_bonus = 0, .shield_bonus = 0, .happiness_bonus = 0, .defense_bonus_percent = 0,
.generated_resource = NULL, .generated_resource_id = -1, .generated_resource_flags = 0
},
{
.command = UCV_Build_Port, .name = "Port", .tooltip = "Build Port", .display_name = "Port",
.advance_prereqs = {"Map Making"}, .advance_prereq_count = 1, .resource_prereqs = {0}, .resource_prereq_on_tile = NULL, .allow_multiple = true, .vary_img_by_era = true, .vary_img_by_culture = false, .is_dynamic = false, .resource_prereq_count = 0, .dependent_improvement_max_index = 2, .align_to_coast = true,
.img_paths = {"Port_NW.pcx", "Port_NE.pcx", "Port_SE.pcx", "Port_SW.pcx"}, .dependent_improvements = {"Harbor", "Commercial Dock"},
.buildable_square_types_mask = (1 << SQ_Coast),
.img_path_count = 4, .img_column_count = 4, .btn_tile_sheet_column = 4, .btn_tile_sheet_row = 0, .align_to_coast = true,
.culture_bonus = 0, .science_bonus = 0, .food_bonus = 0, .gold_bonus = 0, .shield_bonus = 0, .happiness_bonus = 0, .defense_bonus_percent = 0,
.generated_resource = NULL, .generated_resource_id = -1, .generated_resource_flags = 0
},
{
.command = UCV_Build_CentralRailHub, .name = "Central Rail Hub", .tooltip = "Build Central Rail Hub", .display_name = "Central Rail Hub",
.advance_prereqs = {"Steam Power"}, .advance_prereq_count = 1, .resource_prereqs = {"Iron", "Coal"}, .resource_prereq_on_tile = NULL, .allow_multiple = true, .vary_img_by_era = true, .vary_img_by_culture = false, .is_dynamic = false, .resource_prereq_count = 2, .dependent_improvement_max_index = 0,
.img_paths = {"CentralRailHub_AMER.pcx", "CentralRailHub_EURO.pcx", "CentralRailHub_ROMAN.pcx", "CentralRailHub_MIDEAST.pcx", "CentralRailHub_ASIAN.pcx"},
.buildable_square_types_mask = DEFAULT_DISTRICT_BUILDABLE_MASK, .auto_add_road = true, .auto_add_railroad = true,
.img_path_count = 5, .img_column_count = 2, .btn_tile_sheet_column = 5, .btn_tile_sheet_row = 0,
.culture_bonus = 0, .science_bonus = 0, .food_bonus = 0, .gold_bonus = 0, .shield_bonus = 0, .happiness_bonus = 0, .defense_bonus_percent = 0,
.generated_resource = NULL, .generated_resource_id = -1, .generated_resource_flags = 0
},
{
.command = UCV_Build_EnergyGrid, .name = "Energy Grid", .tooltip = "Build Energy Grid", .display_name = "Energy Grid",
.advance_prereqs = {"Industrialization"}, .advance_prereq_count = 1, .resource_prereqs = {0}, .resource_prereq_on_tile = NULL, .allow_multiple = true, .vary_img_by_era = true, .vary_img_by_culture = false, .is_dynamic = false, .resource_prereq_count = 0, .dependent_improvement_max_index = 4,
.img_paths = {"EnergyGrid.pcx"}, .dependent_improvements = {"Coal Plant", "Hydro Plant", "Nuclear Plant", "Solar Plant"},
.buildable_square_types_mask = DEFAULT_DISTRICT_BUILDABLE_MASK, .custom_height = 84,
.img_path_count = 1, .img_column_count = 5, .btn_tile_sheet_column = 6, .btn_tile_sheet_row = 0,
.culture_bonus = 0, .science_bonus = 0, .food_bonus = 0, .gold_bonus = 0, .shield_bonus = 2, .happiness_bonus = 0, .defense_bonus_percent = 0,
.generated_resource = NULL, .generated_resource_id = -1, .generated_resource_flags = 0