41 lines
1.5 KiB
GDScript
41 lines
1.5 KiB
GDScript
extends RefCounted
|
|
|
|
const MAX_LEVEL := 1000
|
|
const COUNT_POINTS := [Vector2(1, 5), Vector2(10, 10), Vector2(50, 18), Vector2(100, 23), Vector2(250, 29), Vector2(500, 34), Vector2(1000, 40)]
|
|
# x = level, y = elite fraction. Each level has exactly one boss.
|
|
const TIER_POINTS := [Vector2(10, 0), Vector2(50, 0.15), Vector2(100, 0.25), Vector2(500, 0.45), Vector2(1000, 0.55)]
|
|
|
|
static func enemy_count(level: int) -> int:
|
|
var clamped_level := clampi(level, 1, MAX_LEVEL)
|
|
for index in range(1, COUNT_POINTS.size()):
|
|
var before: Vector2 = COUNT_POINTS[index - 1]
|
|
var after: Vector2 = COUNT_POINTS[index]
|
|
if clamped_level <= after.x:
|
|
return roundi(lerpf(before.y, after.y, inverse_lerp(before.x, after.x, clamped_level)))
|
|
return 40
|
|
|
|
static func enemy_tiers(level: int) -> Array[int]:
|
|
var count := enemy_count(level)
|
|
var elite_fraction := 0.0
|
|
for index in range(1, TIER_POINTS.size()):
|
|
var before: Vector2 = TIER_POINTS[index - 1]
|
|
var after: Vector2 = TIER_POINTS[index]
|
|
if level <= after.x:
|
|
var progress := clampf(inverse_lerp(before.x, after.x, level), 0.0, 1.0)
|
|
elite_fraction = lerpf(before.y, after.y, progress)
|
|
break
|
|
if level >= MAX_LEVEL:
|
|
elite_fraction = 0.55
|
|
# One boss on every level, included in the total enemy count.
|
|
var bosses := 1
|
|
var elites := mini(count - bosses, roundi(count * elite_fraction))
|
|
var tiers: Array[int] = [2]
|
|
for elite in elites:
|
|
tiers.append(1)
|
|
for normal in count - bosses - elites:
|
|
tiers.append(0)
|
|
return tiers
|
|
|
|
static func power_scale(level: int) -> float:
|
|
return 1.0 + 0.05 * (clampi(level, 1, MAX_LEVEL) - 1)
|