Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
0401b7b
Add view distance, no configuration yet
Philiquaz May 22, 2026
84ae9a1
Global toggle. still no radar support, fortification bonus still unfi…
Philiquaz May 22, 2026
2b76d9f
Merge branch 'master' into viewdistance
Philiquaz May 22, 2026
39752d0
fix compile (never rename things)
Philiquaz May 22, 2026
217eee1
Config parsing for base rules
Philiquaz Jun 1, 2026
0bfff07
Add euclidean distance clipping
Philiquaz Jun 3, 2026
421009a
add radar support, allow fortify bonus 0, unitstate_intercept, refact…
Philiquaz Jun 4, 2026
91f3329
Add unit rule parsing, clean up some hacks
Philiquaz Jun 5, 2026
fe3c719
Patch visibility update checks so non-sea units can take advantage of…
Philiquaz Jun 5, 2026
acb9d87
Clean up debugging, pre-delcare calc
Philiquaz Jun 5, 2026
f049e7c
Decode Leader vtable m30 as ai_negotiate_with_other_ai
maxpetul Jun 30, 2026
0debeca
Fix PCGames.de addresses and move new addresses above the ignored ones
maxpetul Jul 2, 2026
e8c4b9f
trivial fixes (naming, mem free, orphaned vars, config doc)
Philiquaz Jul 2, 2026
8bb4104
Multiple unit ids, multiple unit name parsing while we're there.
Philiquaz Jul 2, 2026
16391ad
unit visiblity: Less jank parsing, init unit_ids values in case.
Philiquaz Jul 3, 2026
a8b97ef
Fix continent-locked fort bonus stacking with flat bonus. Remove quot…
Philiquaz Jul 7, 2026
b881046
Clarify config option.
Philiquaz Jul 7, 2026
294fede
Merge branch 'master' of https://github.com/maxpetul/C3X
maxpetul Jul 13, 2026
fba8d76
Merge branch 'master' into viewdistance
maxpetul Jul 13, 2026
725125a
Fix small grammar mistakes
maxpetul Jul 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions C3X.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,16 @@ struct work_area_improvement {
int work_area_radius_bonus;
};

struct unit_visibility_rule {
struct table unit_ids; // Table mapping unit type IDs to 1's; used as a hash set
enum UnitTypeClasses unit_class;

int base_visibility;
int terrain_bonus_multiplier;
int fortification_bonus;
bool fortification_bonus_continent_lock;
};

enum retreat_rules {
RR_STANDARD = 0,
RR_NONE,
Expand Down Expand Up @@ -568,6 +578,20 @@ struct c3x_config {
int ai_auto_build_great_wall_strategy;

bool enable_city_work_radii_highlights;

bool enable_alternate_view_distance_logic; //enable the whole system or not
bool terrain_visibility_euclidean; //whether the upper bound should be determined by a euclidean metric than a chebyshev one.
int base_visibility_range; //should default to 1
int terrain_visibility_see_height[14]; //most tiles are 1, mountains+volcanoes are 2
int terrain_visibility_seen_height[14]; //most tiles are 0, forest+jungle+hills are 1, mountains+volcanoes are 2
int terrain_visibility_bonus[14]; //most tiles are 0, hills+mountains+volcanoes are 1
bool terrain_visibility_bonus_can_stack; //whether seeing hills and being on a hill provides double the bonus
bool terrain_visibility_flat_bonus[14]; //water tiles provide height bonus to tiles being seen across them [ie +2] / adjacent tiles always seen
int terrain_visibility_flat_bonus_limit; //maximum size of the flat bonus, in tiles
bool terrain_visibility_flat_bonus_can_stack; //whether flat bonus and regular bonus can both apply at once
struct unit_visibility_rule * unit_visibility_rule_list; //should default to naval unit type has +1 range in fortification with continent lock
Comment thread
Philiquaz marked this conversation as resolved.
int c_unit_visibility_rules;
//tiles blocked by obstructions are visible if *either* intermediate tile is not blocking in height.
};

enum stackable_command {
Expand Down
2 changes: 1 addition & 1 deletion Civ3Conquests.h
Original file line number Diff line number Diff line change
Expand Up @@ -3312,7 +3312,7 @@ struct Leader_vtable
// void (__thiscall *m28)(Leader *);
void *m28;
int m29;
int m30;
void (__fastcall * ai_negotiate_with_other_ai) (Leader * this, int edx, int other_civ_id);
int m31;
int m32;
int (__fastcall * get_attitude_toward) (Leader * this, int edx, int civ_id, int param_2);
Expand Down
12 changes: 11 additions & 1 deletion civ_prog_objects.csv
Original file line number Diff line number Diff line change
Expand Up @@ -952,6 +952,17 @@ define, 0x4D519C, 0x4DD953, 0x4D525C, "ADDR_AIR_UNIT_CHECK_TO_DRAW_PEDIA_STAT
define, 0x1A8, 0x1A9, 0x1A8, "LBL_BOMBARD_RANGE", "int"
define, 0x437F20, 0x439AC0, 0x437FA0, "Unit_get_transport_capacity", "int (__fastcall *) (Unit * this)"
inlead, 0x5543B0, 0x55FB10, 0x554360, "Main_GUI_get_unit_stat_str", "void (__fastcall *) (Main_GUI * this, int edx, char * out_str, Unit * unit)"
inlead, 0x5BA010, 0x5C8AD0, 0x5B9D20, "Unit_can_see_tile", "bool (__fastcall *) (Unit * this, int edx, int x, int y)"
define, 0x44A8D0, 0x44C870, 0x44A950, "Map_chebyshev_distance", "int (__fastcall *) (Map * this, int edx, int x1, int y1, int x2, int y2)"
define, 0x5BA1F9, 0x5C8CD6, 0x5B9F09, "ADDR_UNIT_VISIBILITY_RADIUS_1", "byte *"
define, 0x5BA29B, 0x5C8D76, 0x5B9FAB, "ADDR_UNIT_VISIBILITY_RADIUS_2", "byte *"
define, 0x5BA5F4, 0x5C90CD, 0x5BA304, "ADDR_UNIT_VISIBILITY_RADIUS_3", "byte *"
define, 0x5C811A, 0x5D6FF5, 0x5C7E2A, "ADDR_UNIT_TO_UNIT_VISIBILITY_RADIUS", "byte *"
define, 0x5BB7E6, 0x5CA333, 0x5BB4F6, "ADDR_CIV_UNIT_VISIBILITY_RADIUS", "byte *"
define, 0x5BEB25, 0x5CD745, 0x5BE835, "ADDR_UTC_SEA_CMP_1", "byte *"
define, 0x5C644C, 0x5D529C, 0x5C615C, "ADDR_UTC_SEA_CMP_2", "byte *"
define, 0x5C65C8, 0x5D5418, 0x5C62D8, "ADDR_UTC_SEA_CMP_3", "byte *"
define, 0x5C7E43, 0x5D6D08, 0x5C7B53, "ADDR_UTC_SEA_CMP_4", "byte *"

ignore, 0x5FC710, 0x0, 0x0, "PCX_Image_create_and_init_jgl_image", "int (__fastcall *) (PCX_Image * this, int edx, int width, int height, int bit_depth, int param_4, int param_5, int param_6)"
ignore, 0x5FCC50, 0x0, 0x0, "PCX_Image_draw_region_to_location", "void (__fastcall *) (PCX_Image * this, int edx, PCX_Image * canvas, int src_x, int src_y, int dest_x, int dest_y, int width, int height)"
Expand All @@ -976,4 +987,3 @@ ignore, 0x4BF660, 0x4C6C10, 0x4BF6F0, "City_draw_citizens", "void (__fastc
ignore, 0x4B9F60, 0x4C15D0, 0x4B9FF0, "City_add_population", "void (__fastcall *) (City * this, int edx, int num, int race_id)"
ignore, 0x670234, 0x68D2E0, 0x670234, "Tile_m27_Check_Shield_Bonus", "bool (__fastcall *) (Tile * this)"
ignore, 0x5f3448, 0x6032DF, 0x5F3378, "CHECK_SHIELD_BONUS_TO_CAN_SPAWN_RES_RETURN", "int"

23 changes: 23 additions & 0 deletions common.c
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,29 @@ parse_bracketed_block (char ** p_cursor, struct string_slice * out)
return 0;
}

int
parse_until_punctuation (char ** p_cursor, struct string_slice * out, char punct)
{
char * cur = *p_cursor;
struct string_slice unused;
char * str_start = cur;
while (1) {
if (*cur == punct) {
break;
} else if (*cur == '"') {
if (! parse_string (&cur, &unused))
return 0;
} else if (*cur == '\0')
return 0;
else
cur++;
}
out->str = str_start;
out->len = cur - str_start;
*p_cursor = cur;
return 1;
}

int
parse_csv_value (char ** p_cursor, char ** out_val, int * out_len)
{
Expand Down
38 changes: 38 additions & 0 deletions default.c3x_config.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1015,6 +1015,44 @@ prefer_less_expensive_defenders = false
; Sets the number of turns for which a successful "Steal Plans" espionage mission reveals the target civ's units. Values below 1 are treated as 1.
steal_plans_duration = 1

[==================]
[=== VISIBILITY ===]
[==================]

; Whether to enable the alternate visibility system. Within this system, the total view distance cannot exceed 7 tiles due to technical limitations. Any visibility beyond this will be clamped.
enable_alternate_view_distance_logic = false

; Whether a euclidean (circular) metric is used instead of the normal chebyshev (square) one
terrain_visibility_euclidean = false

; The base view distance of units
base_visibility_range = 1
; The following settings have an entry for each terrain type, annotated and abbreviated as follows
; [DESRT, PLAIN, GRSLD, TNDRA, FLDPL, HILLS, MNTNS, FORST, JUNGL, MARSH, VLCNO, COAST, SEA, OCEAN]
; The height a unit is considered to be standing at when on this type of tile.
terrain_visibility_see_height = [1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1]
; The hight a tile is considered to be seen from another tile. If this equals or exceed the see height, it will occlude tiles beyond.
terrain_visibility_seen_height = [0, 0, 0, 0, 0, 1, 2, 1, 1, 0, 2, 0, 0, 0]
; The bonus sight range granted by standing on or looking at a given tile
terrain_visibility_bonus = [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0]
; Whether a unit on a tile with a bonus and seeing a tile with bonus is double rewarded. Otherwise, the large value is used. This may be necessary if you wish to use negative bonuses.
terrain_visibility_bonus_can_stack = false
; Whether tiles of the given type provide bonus view distance for seeing across them. This config only supports true and false.
terrain_visibility_flat_bonus = [false, false, false, false, false, false, false, false, false, false, false, true, true, true]
; The number of times the flat bonus may be applied.
terrain_visibility_flat_bonus_limit = 1
; Whether the flat bonus may stack with the regular, height-based bonus.
terrain_visibility_flat_bonus_can_stack = false

; A list of rules for unit types or unit classes (Land, Sea, Air)
; A single unit class may be given, or a list of unit names.
; A base visibility can be given, a multiplier to the height based bonus visibility can be given (times-bonus), and a single fortification bonus can be given.
; There are two mutually-exclusive types of fortification bonus: when-fortified and when-fortified-same-continent.
; The latter reveals tiles on the same continent regardless of intermediate tiles and their bonuses.
; The last rule matching a unit is used. Therefore, unit class rules should be at the start of the list.
; The following is an example: [Scout: 1 + 2 times-bonus, "Landmine": 0 + 0 times-bonus, "Army" Leader Fleet: 2 + 2 when-fortified]
unit_visibility_rules = [Sea: 2 when-fortified-same-continent]

[==================]
[=== AESTHETICS ===]
[==================]
Expand Down
Loading