Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 1 addition & 6 deletions scripts/autoload/burden_manager.gd
Original file line number Diff line number Diff line change
Expand Up @@ -201,13 +201,8 @@ func reset() -> void:
# ---------------------------------------------------------------------------


## Safe helper to access ConfigLoader via AutoloadHelper.
func _config_int(key: String, fallback: int) -> int:
return AutoloadHelper.config_int(key, fallback)


func update_moral_weight(moral_flag: int) -> void:
var threshold: int = _config_int("MWT", GameConstants.MWT)
var threshold: int = AutoloadHelper.config_int("entity", "MWT", GameConstants.MWT)

var old_level := current_mwt_level
## Map moral_flag to MWT level (0-3) as a ratio of threshold.
Expand Down
65 changes: 48 additions & 17 deletions scripts/autoload/config_loader.gd
Original file line number Diff line number Diff line change
Expand Up @@ -177,27 +177,58 @@ func getValue(sectionOrKey: String, key: String = "", fallback: Variant = null)


## Convenience typed getters for hot-path values.
func getInt(key: String, fallback: int = 0) -> int:
var v: Variant = getValue(key, "", fallback)
if v is float:
return int(v)
if v is int:
return v
return fallback
## Supports both (key, fallback) and (section, key, fallback) signatures.
func getInt(sectionOrKey: String, arg2: Variant = null, arg3: Variant = null) -> int:
if arg2 is String:
# (section, key, fallback)
var f: int = int(arg3) if arg3 != null else 0
var v: Variant = getValue(sectionOrKey, arg2, f)
return int(v) if (v is float or v is int) else f
else:
# (key, fallback)
var f: int = int(arg2) if arg2 != null else 0
var v: Variant = getValue(sectionOrKey, "", f)
return int(v) if (v is float or v is int) else f


func getFloat(key: String, fallback: float = 0.0) -> float:
var v: Variant = getValue(key, "", fallback)
if v is float or v is int:
return float(v)
return fallback
func getFloat(sectionOrKey: String, arg2: Variant = null, arg3: Variant = null) -> float:
if arg2 is String:
# (section, key, fallback)
var f: float = float(arg3) if arg3 != null else 0.0
var v: Variant = getValue(sectionOrKey, arg2, f)
return float(v) if (v is float or v is int) else f
else:
# (key, fallback)
var f: float = float(arg2) if arg2 != null else 0.0
var v: Variant = getValue(sectionOrKey, "", f)
return float(v) if (v is float or v is int) else f


func getString(key: String, fallback: String = "") -> String:
var v: Variant = getValue(key, "", fallback)
if v is String:
return v
return fallback
func getString(sectionOrKey: String, arg2: Variant = null, arg3: Variant = null) -> String:
if arg3 != null:
# 3-arg mode: (section, key, fallback)
var v: Variant = getValue(sectionOrKey, str(arg2), str(arg3))
return str(v) if v != null else str(arg3)

if arg2 is String:
# Ambiguous 2-arg mode: (section, key) or (key, fallback)
# Heuristic: If config is not yet loaded, OR if sectionOrKey is a known section,
# treat as (section, key) with empty fallback.
# Otherwise, treat as (key, fallback).
if (
_configData.is_empty()
or (_configData.has(sectionOrKey) and _configData[sectionOrKey] is Dictionary)
):
var v: Variant = getValue(sectionOrKey, arg2, "")
return str(v) if v != null else ""
else:
var v: Variant = getValue(sectionOrKey, "", arg2)
return str(v) if v != null else str(arg2)

# 1-arg or (key, null fallback)
var f: String = str(arg2) if arg2 != null else ""
var v: Variant = getValue(sectionOrKey, "", f)
return str(v) if v != null else f


func isLoaded() -> bool:
Expand Down
33 changes: 21 additions & 12 deletions scripts/core/autoload_helper.gd
Original file line number Diff line number Diff line change
Expand Up @@ -111,28 +111,37 @@ static func secret_room_trigger() -> _SecretRoomTrigger:
# ── Derived Helpers ───────────────────────────────────────────────────────────


## Reads an int config value via ConfigLoader.get_int(), returning fallback
## Reads an int config value via ConfigLoader.getInt(), returning fallback
## if ConfigLoader is unavailable or the key is not set.
static func config_int(key: String, fallback: int) -> int:
## Supports both (key, fallback) and (section, key, fallback) signatures.
static func config_int(arg1: String, arg2: Variant = null, arg3: Variant = null) -> int:
var n: Node = config_loader()
if n != null and n.has_method("getInt"):
return n.getInt(key, fallback)
return fallback
return n.getInt(arg1, arg2, arg3)
if arg2 is String:
return int(arg3) if arg3 != null else 0
return int(arg2) if arg2 != null else 0


## Reads a float config value via ConfigLoader.get_float(), returning fallback
## Reads a float config value via ConfigLoader.getFloat(), returning fallback
## if ConfigLoader is unavailable or the key is not set.
static func config_float(key: String, fallback: float) -> float:
## Supports both (key, fallback) and (section, key, fallback) signatures.
static func config_float(arg1: String, arg2: Variant = null, arg3: Variant = null) -> float:
var n: Node = config_loader()
if n != null and n.has_method("getFloat"):
return n.getFloat(key, fallback)
return fallback
return n.getFloat(arg1, arg2, arg3)
if arg2 is String:
return float(arg3) if arg3 != null else 0.0
return float(arg2) if arg2 != null else 0.0


## Reads a String config value via ConfigLoader.get_string(), returning fallback
## Reads a String config value via ConfigLoader.getString(), returning fallback
## if ConfigLoader is unavailable or the key is not set.
static func config_string(key: String, fallback: String) -> String:
## Supports both (key, fallback) and (section, key, fallback) signatures.
static func config_string(arg1: String, arg2: Variant = null, arg3: Variant = null) -> String:
var n: Node = config_loader()
if n != null and n.has_method("getString"):
return n.getString(key, fallback)
return fallback
return n.getString(arg1, arg2, arg3)
if arg2 is String:
return str(arg3) if arg3 != null else ""
return str(arg2) if arg2 != null else ""
8 changes: 6 additions & 2 deletions scripts/core/combat_formula.gd
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,13 @@ static func action_cost(action_type: String) -> int:
"attack_ranged_3":
return 4
"ability_min":
return AutoloadHelper.config_int("ability_min", GameConstants.ABILITY_MIN_COST)
return AutoloadHelper.config_int(
"ap_economy", "ability_min", GameConstants.ABILITY_MIN_COST
)
"ability_max":
return AutoloadHelper.config_int("ability_max", GameConstants.ABILITY_MAX_COST)
return AutoloadHelper.config_int(
"ap_economy", "ability_max", GameConstants.ABILITY_MAX_COST
)
"interact":
return 1
"end_turn":
Expand Down
25 changes: 10 additions & 15 deletions scripts/core/elemental_resolver.gd
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,6 @@ class_name ElementalInteractionResolver
## Reference: DON-101 B3


# ── Config Helpers ──────────────────────────────────────────────────────
static func _config_float(key: String, fallback: float) -> float:
return AutoloadHelper.config_float(key, fallback)


static func _config_int(key: String, fallback: int) -> int:
return AutoloadHelper.config_int(key, fallback)


# ── Typed Element Queries ─────────────────────────────────────────────────
static func _has_element(
effects: Array[ElementalTypes.TileEffect], elem: ElementalTypes.ElementType
Expand Down Expand Up @@ -81,15 +72,15 @@ static func compute_tile_damage_multiplier(

# Priority 1: Water extinguishes Fire → 0.5× (extinguish overrides amplification)
if has_water and has_fire:
return _config_float("WATER_FIRE_MODIFIER", 0.5)
return AutoloadHelper.config_float("elemental", "WATER_FIRE_MODIFIER", 0.5)

# Priority 2: Wind fans Fire → 1.5×
if has_wind and has_fire:
return _config_float("WIND_FIRE_MODIFIER", 1.5)
return AutoloadHelper.config_float("elemental", "WIND_FIRE_MODIFIER", 1.5)

# Priority 3: Fire burns Oil → 2.0×
if has_fire and has_oil:
return _config_float("FIRE_OIL_MODIFIER", 2.0)
return AutoloadHelper.config_float("elemental", "FIRE_OIL_MODIFIER", 2.0)

# Fallback: no recognised combo
return 1.0
Expand All @@ -103,7 +94,7 @@ static func calculate_movement_speed_multiplier(
) -> float:
var active: Array[ElementalTypes.TileEffect] = _filter_active(effects, current_turn)
if _has_element(active, ElementalTypes.ElementType.OIL):
return _config_float("OIL_SLIP_SPEED_MULT", 0.8)
return AutoloadHelper.config_float("elemental", "OIL_SLIP_SPEED_MULT", 0.8)
return 1.0


Expand Down Expand Up @@ -197,7 +188,9 @@ static func process_turn_tick(
var fire_idx := _find_leftmost_element(working, ElementalTypes.ElementType.FIRE)
if fire_idx != -1 and fire_idx != i:
# Refresh fire duration
working[fire_idx].duration = _config_int("FIRE_DURATION_TURNS", 1)
working[fire_idx].duration = AutoloadHelper.config_int(
"elemental", "FIRE_DURATION_TURNS", 1
)
working[fire_idx].applied_turn = current_turn
# Remove wind
working.remove_at(i)
Expand All @@ -221,7 +214,9 @@ static func process_turn_tick(
if oil_idx < i:
i -= 1
# Refresh fire duration after consuming oil
working[i].duration = _config_int("FIRE_OIL_DURATION_TURNS", 1)
working[i].duration = AutoloadHelper.config_int(
"elemental", "FIRE_OIL_DURATION_TURNS", 1
)
working[i].applied_turn = current_turn

i += 1
Expand Down
14 changes: 7 additions & 7 deletions scripts/entities/entity_lifecycle.gd
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,6 @@ var player_entity: Entity = null:
# Delegated to AutoloadHelper — single source of truth for safe autoload access.


func _config_int(key: String, fallback: int) -> int:
return AutoloadHelper.config_int(key, fallback)


func _update_burden_weight(flag: int) -> void:
var n: Node = AutoloadHelper.burden_manager()
if n != null and n.has_method("update_moral_weight"):
Expand Down Expand Up @@ -97,7 +93,9 @@ func apply_damage(attacker: Entity, defender: Entity, damage: int) -> void:
and defender.state != Entity.State.GHOST
):
_change_state(defender, Entity.State.DYING)
var dying_duration: int = _config_int("DYING_DURATION_TURNS", 1)
var dying_duration: int = AutoloadHelper.config_int(
"run_manager", "DYING_DURATION_TURNS", 1
)
_dying_turns[defender.get_instance_id()] = dying_duration


Expand Down Expand Up @@ -144,7 +142,9 @@ func process_kill(
apply_damage(attacker, defender, defender.hp)

var delta: int = (
_config_int("MORAL_DELTA_KILL", 1) if sentient else _config_int("MORAL_DELTA_ENV", 0)
AutoloadHelper.config_int("entity", "MORAL_DELTA_KILL", 1)
if sentient
else AutoloadHelper.config_int("entity", "MORAL_DELTA_ENV", 0)
)
var record: MoralDeltaRecord = MoralDeltaRecord.new(
delta, enemy_id, enemy_name, sentient, "kill"
Expand Down Expand Up @@ -174,7 +174,7 @@ func spare_entity(player: Entity, target: Entity) -> bool:

player.ap = DeterministicMath.clampi(player.ap - 1, 0, player.ap)

var delta: int = _config_int("MORAL_DELTA_SPARE", -1)
var delta: int = AutoloadHelper.config_int("entity", "MORAL_DELTA_SPARE", -1)
var record: MoralDeltaRecord = MoralDeltaRecord.new(
delta, target.entity_name, target.entity_name, true, "spare"
)
Expand Down
8 changes: 4 additions & 4 deletions scripts/state_machine/run_manager.gd
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,10 @@ func setup_state_machine() -> void:
func _load_config_values() -> void:
if Engine.is_editor_hint():
return
biome_count = AutoloadHelper.config_int("BIOME_COUNT", 3)
rooms_per_biome_min = AutoloadHelper.config_int("ROOMS_PER_BIOME_MIN", 8)
rooms_per_biome_max = AutoloadHelper.config_int("ROOMS_PER_BIOME_MAX", 12)
_dying_duration = float(AutoloadHelper.config_int("DYING_DURATION_TURNS", 1))
biome_count = AutoloadHelper.config_int("run_manager", "BIOME_COUNT", 3)
rooms_per_biome_min = AutoloadHelper.config_int("run_manager", "ROOMS_PER_BIOME_MIN", 8)
rooms_per_biome_max = AutoloadHelper.config_int("run_manager", "ROOMS_PER_BIOME_MAX", 12)
_dying_duration = float(AutoloadHelper.config_int("run_manager", "DYING_DURATION_TURNS", 1))


# ---------------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions tests/test_new_enemies_spawn.gd.uid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
uid://b116pcdtasrlt
Loading