Randoloot/scripts/planets/planet_rewards.gd
2026-10-18 16:22:39 +02:00

49 lines
2.2 KiB
GDScript

extends RefCounted
## Shared planet reward rules. Ammo and consumables never use material scaling.
const ITEMS := preload("res://scripts/items/item_generator.gd")
const MATERIAL_KEYS := ["parts","iron","titanium","aluminium","uranium","sulfur","silicon","copper","nickel","tungsten","mercury"]
static func difficulty(profile: Dictionary) -> float:
return clampf(float(profile.get("difficulty",0.0)),0.0,1.0)
static func material_multiplier(profile: Dictionary) -> float:
return 1.0+2.0*difficulty(profile)
static func module_bonus_range(profile: Dictionary) -> Vector2i:
var d := difficulty(profile)
return Vector2i(roundi(2.0*d),roundi(2.0+8.0*d))
static func roll_module_bonus(rng: RandomNumberGenerator, profile: Dictionary) -> int:
var bounds := module_bonus_range(profile)
var count := bounds.y-bounds.x+1
var total := 0.0
for index in count:
total += pow(0.65,index)
var roll := rng.randf()*total
for index in count:
roll -= pow(0.65,index)
if roll < 0.0:
return bounds.x+index
return bounds.y
static func generate_module(rng: RandomNumberGenerator, profile: Dictionary, level: int, definition: ItemDefinition = null, tier := 0, exact_bonus := -1) -> ItemInstance:
if definition == null:
var definitions: Array = ITEMS.DEFINITIONS.filter(func(d): return d.category in [ItemDefinition.Category.SHIELD,ItemDefinition.Category.ARMOR,ItemDefinition.Category.ENGINE,ItemDefinition.Category.REACTOR,ItemDefinition.Category.COMPUTER])
definition = definitions[rng.randi_range(0,definitions.size()-1)]
var bonus := exact_bonus if exact_bonus >= 0 else roll_module_bonus(rng,profile)
# Events use biome bonuses; ancient structures explicitly set +1/+2/+3.
return ITEMS.generate_for_definition(definition,clampi(level+bonus,1,1000),tier)
static func scale_materials(reward: Dictionary, profile: Dictionary) -> Dictionary:
var scaled := reward.duplicate()
for key in scaled:
if key in MATERIAL_KEYS:
scaled[key] = maxi(1,roundi(int(scaled[key])*material_multiplier(profile))) if int(scaled[key]) > 0 else 0
return scaled
static func missile_price_ratio(profile: Dictionary) -> float:
return lerpf(0.70,0.50,difficulty(profile))
static func missile_barter_cost(profile: Dictionary) -> int:
return maxi(1,roundi(6.0*lerpf(1.0,0.65,difficulty(profile))))