class_name LuneWaves extends RefCounted ## Endless monster waves. Both teams receive the identical composition per lane, so the ## waves never favour a side. Count is capped; strength grows through stats and later types. const MELEE: Array[String] = ["e01", "e02", "e05"] static func strength(balance: LuneBalance, round_number: int, growth: float) -> float: var r: float = float(maxi(1, round_number) - 1) return 1.0 + growth * r + balance.wave_growth_quadratic * r * r static func monster_count(balance: LuneBalance, round_number: int) -> int: var extra: int = (maxi(1, round_number) - 1) / maxi(1, balance.wave_count_every) return mini(balance.wave_max_count, balance.wave_base_count + extra) static func unlocked_types(balance: LuneBalance, round_number: int) -> PackedStringArray: var pool: PackedStringArray = balance.monster_pool var available: int = clampi(1 + (maxi(1, round_number) - 1) / 2, 1, pool.size()) return pool.slice(0, available) ## Definitions for one lane of one team, melee first so they lead the march. static func build(balance: LuneBalance, round_number: int) -> Array[Dictionary]: var types: PackedStringArray = unlocked_types(balance, round_number) var hp_factor: float = strength(balance, round_number, balance.wave_hp_growth) var damage_factor: float = strength(balance, round_number, balance.wave_damage_growth) var bounty_factor: float = balance.monster_bounty_scale * (1.0 + balance.bounty_growth * float(maxi(1, round_number) - 1)) var melee: Array[Dictionary] = [] var ranged: Array[Dictionary] = [] for index: int in range(monster_count(balance, round_number)): var type_id: String = types[(index + round_number) % types.size()] var source: Dictionary = DataCatalog.ENEMIES[type_id] var monster: Dictionary = source.duplicate(true) monster.max_hp = float(source.max_hp) * hp_factor monster.damage = float(source.damage) * damage_factor monster.hp_factor = hp_factor monster.bounty = int(clampf(roundf(float(source.bounty) * bounty_factor), 1.0, 1.0e12)) (melee if type_id in MELEE else ranged).append(monster) return melee + ranged