extends RefCounted const CHANCES := [1.0, 0.25, 0.05, 0.01, 0.0015, 0.0002] static func tail_chance(quality: float) -> float: var scaled := clampf(quality, 0.0, 1.0) * 5.0 var index := mini(4, floori(scaled)) return exp(lerpf(log(CHANCES[index]), log(CHANCES[index + 1]), scaled - index)) static func rank_from_roll(steps: int, roll: float) -> int: for rank in range(steps, 0, -1): if roll < tail_chance(float(rank) / steps): return rank return 0 static func roll_value(effect: String, roll: float = -1.0) -> float: var chance := randf() if roll < 0.0 else roll match effect: "recycler": return 0.5 + rank_from_roll(79, chance) * 0.5 "virus": return 1.0 + rank_from_roll(19, chance) "titanium_armor": return 5.0 + rank_from_roll(45, chance) return 0.0