diff --git a/scripts/autoload/burden_manager.gd b/scripts/autoload/burden_manager.gd index 5bb7137..1316c34 100644 --- a/scripts/autoload/burden_manager.gd +++ b/scripts/autoload/burden_manager.gd @@ -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. diff --git a/scripts/autoload/config_loader.gd b/scripts/autoload/config_loader.gd index 132ab94..3b65935 100644 --- a/scripts/autoload/config_loader.gd +++ b/scripts/autoload/config_loader.gd @@ -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: diff --git a/scripts/core/autoload_helper.gd b/scripts/core/autoload_helper.gd index 0ed09bb..b903425 100644 --- a/scripts/core/autoload_helper.gd +++ b/scripts/core/autoload_helper.gd @@ -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 "" diff --git a/scripts/core/combat_formula.gd b/scripts/core/combat_formula.gd index 700eba3..55ba181 100644 --- a/scripts/core/combat_formula.gd +++ b/scripts/core/combat_formula.gd @@ -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": diff --git a/scripts/core/elemental_resolver.gd b/scripts/core/elemental_resolver.gd index 42efebe..168348e 100644 --- a/scripts/core/elemental_resolver.gd +++ b/scripts/core/elemental_resolver.gd @@ -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 @@ -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 @@ -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 @@ -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) @@ -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 diff --git a/scripts/entities/entity_lifecycle.gd b/scripts/entities/entity_lifecycle.gd index d164a82..f4bede1 100644 --- a/scripts/entities/entity_lifecycle.gd +++ b/scripts/entities/entity_lifecycle.gd @@ -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"): @@ -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 @@ -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" @@ -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" ) diff --git a/scripts/state_machine/run_manager.gd b/scripts/state_machine/run_manager.gd index ed05af7..cffda38 100644 --- a/scripts/state_machine/run_manager.gd +++ b/scripts/state_machine/run_manager.gd @@ -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)) # --------------------------------------------------------------------------- diff --git a/tests/test_new_enemies_spawn.gd.uid b/tests/test_new_enemies_spawn.gd.uid new file mode 100644 index 0000000..028694d --- /dev/null +++ b/tests/test_new_enemies_spawn.gd.uid @@ -0,0 +1 @@ +uid://b116pcdtasrlt