extends RefCounted const XP_BASE := 120 const XP_PER_LEVEL := 60 const LEARNING_POINTS_PER_LEVEL := 1 const MAX_SKILL_RANK := 20 const SKILL_RESET_COST_PER_LEVEL := 100 const BASE_CRITICAL_MULTIPLIER := 2.0 const KILL_XP := [20, 50, 150] const KILL_CREDITS := [15, 40, 120] const SKILL_NAMES := { "piloting": "Pilotaż", "gunner": "Strzelec", "mechanic": "Mechanik", "sharp_eye": "Celne oko", } const SKILL_HELP := { "piloting": "Malejące korzyści: 37,5% × punkty / (punkty + 10). Maksymalnie 25% uniku przy 20 punktach. Unik anuluje całe trafienie.", "gunner": "Każdy punkt: +2% obrażeń wszystkich broni. Maksymalnie +40% przy 20 punktach.", "mechanic": "Malejące korzyści: 50% × punkty / (punkty + 10). Maksymalnie 33,3% redukcji przy 20 punktach, przed tarczami i kadłubem.", "sharp_eye": "Każdy punkt: +1 punkt procentowy szansy na trafienie krytyczne. Maksymalnie +20 przy 20 punktach.", } static func skill_bonus(skill: String, rank: int) -> float: var points := float(clampi(rank, 0, MAX_SKILL_RANK)) match skill: "piloting": return 0.375 * points / (points + 10.0) "mechanic": return 0.5 * points / (points + 10.0) "gunner": return 0.02 * points "sharp_eye": return 0.01 * points return 0.0 static func xp_required(level: int) -> int: return XP_BASE + XP_PER_LEVEL * (maxi(1, level) - 1) # Full XP within two levels; progressively exhausted rewards on easy systems. static func encounter_xp_factor(captain_level: int, system_level: int) -> float: var gap := maxi(1, captain_level) - clampi(system_level, 1, 1000) if gap <= 2: return 1.0 if gap >= 8: return 0.0 return pow(0.5, gap - 2)