67 lines
4.4 KiB
GDScript
67 lines
4.4 KiB
GDScript
extends RefCounted
|
|
const NAMES := {"deposit":"Złoże surowców","ruins":"Starożytna struktura","warehouse":"Opuszczony magazyn","village":"Opuszczona wioska","cave":"Jaskinia","deep_deposit":"Głębokie złoże deuteru","crew":"Obóz specjalisty","hermit":"Pustelnik / Kartograf","time_engineer":"Inżynier chronalny"}
|
|
const KINDS := ["deposit","ruins","warehouse","village","cave"]
|
|
const WEIGHTS := {"deposit":[0.1,0.7,0.2],"ruins":[0.2,0.5,0.3],"warehouse":[0.1,0.25,0.65],"village":[0.15,0.2,0.65],"cave":[0.7,0.2,0.1]}
|
|
const PROFILES := preload("res://scripts/planets/planet_profiles.gd")
|
|
const REWARDS := preload("res://scripts/planets/planet_rewards.gd")
|
|
|
|
static func report(kind: String, profile: Dictionary, captain: Resource) -> Dictionary:
|
|
return PROFILES.poi_loot_report(profile,captain,WEIGHTS.get(kind,[1.0,1.0,1.0]))
|
|
|
|
static func richness(profile: Dictionary) -> float:
|
|
return REWARDS.material_multiplier(profile)*(1.0+0.02*(PROFILES.level(profile)-1))
|
|
|
|
static func reward(kind: String, rng: RandomNumberGenerator, profile: Dictionary, captain: Resource, risky: bool = false) -> Dictionary:
|
|
var result := {}
|
|
var multiplier: float = report(kind,profile,captain).multiplier*(0.35 if risky else 1.0)
|
|
var supplies := 1.0+0.5*REWARDS.difficulty(profile)+0.005*(PROFILES.level(profile)-1)
|
|
match kind:
|
|
"deposit":
|
|
var key: String = PROFILES.MATERIALS[rng.randi_range(0,PROFILES.MATERIALS.size()-1)]
|
|
result[key] = rng.randi_range(18,28)*richness(profile)
|
|
"warehouse":
|
|
result.ammunition = rng.randi_range(130,210)*supplies
|
|
result.missile = rng.randi_range(2,4)*supplies
|
|
if rng.randf() < 0.25: result.irradiated_ammunition = rng.randi_range(20,35)*supplies
|
|
var keys := ["iron","titanium","aluminium","uranium","sulfur"]
|
|
result[keys[rng.randi_range(0,4)]] = rng.randi_range(8,16)*richness(profile)
|
|
"village":
|
|
result.credits = rng.randi_range(140,220)*richness(profile)
|
|
var xp: int = captain.encounter_xp(6.0*pow(PROFILES.level(profile),0.75),PROFILES.level(profile))
|
|
if xp > 0: result.experience = xp
|
|
"cave": result.samples = rng.randi_range(3,5)*sqrt(richness(profile))
|
|
for key in result: result[key] = maxi(1,roundi(float(result[key])*multiplier))
|
|
return result
|
|
|
|
static func module_count(profile: Dictionary, captain: Resource, risky: bool = false) -> int:
|
|
if risky: return 1
|
|
return clampi(roundi((1.0+REWARDS.difficulty(profile))*float(report("ruins",profile,captain).multiplier)),1,3)
|
|
|
|
static func module_bonus(rng: RandomNumberGenerator, profile: Dictionary, captain: Resource, risky: bool = false) -> int:
|
|
var equipment := roundi((float(report("ruins",profile,captain).gear_multiplier)-1.0)*10)
|
|
return REWARDS.roll_module_bonus(rng,profile)+equipment+(2 if risky else 0)
|
|
|
|
static func has_bonus(poi: Dictionary, profile: Dictionary) -> bool:
|
|
if str(poi.get("kind","")) not in KINDS: return false
|
|
if poi.has("bonus_available"): return bool(poi.bonus_available)
|
|
var rng := rng_for(int(profile.get("seed",1)),poi,24)
|
|
return rng.randf() < 0.25
|
|
|
|
static func rng_for(visit_seed: int, poi: Dictionary, salt: int = 0) -> RandomNumberGenerator:
|
|
var rng := RandomNumberGenerator.new()
|
|
rng.seed = visit_seed ^ (int(poi.get("id",0))*7919) ^ str(poi.get("kind","")).hash() ^ ((salt+1)*104729)
|
|
return rng
|
|
|
|
static func damage_range(kind: String, profile: Dictionary, captain: Resource, risky: bool = false) -> Vector2i:
|
|
var equipment := report(kind,profile,captain)
|
|
var base := 13.0+5.0*REWARDS.difficulty(profile)+20.0*float(equipment.deficit)-3.0*float(equipment.surplus) if risky else 3.0+3.0*REWARDS.difficulty(profile)+16.0*float(equipment.deficit)-1.5*float(equipment.surplus)
|
|
var spread := 5 if risky else 1
|
|
return Vector2i(maxi(1,floori(base)-spread),maxi(1,ceili(base)+spread))
|
|
|
|
static func preview(profile: Dictionary, captain: Resource, poi: Dictionary, visit_seed: int, risky: bool = false) -> Dictionary:
|
|
var kind := str(poi.get("kind",""))
|
|
if kind not in KINDS: return {}
|
|
var bounds := REWARDS.module_bonus_range(profile)
|
|
var equipment := roundi((float(report("ruins",profile,captain).gear_multiplier)-1.0)*10)+(2 if risky else 0)
|
|
return {"materials":reward(kind,rng_for(visit_seed,poi,10 if risky else 0),profile,captain,risky),"modules":module_count(profile,captain,risky) if kind == "ruins" else 0,"module_levels":Vector2i(clampi(PROFILES.level(profile)+bounds.x+equipment,1,1000),clampi(PROFILES.level(profile)+bounds.y+equipment,1,1000)),"damage":damage_range(kind,profile,captain,risky),"bonus":risky}
|