98 lines
5.1 KiB
GDScript
98 lines
5.1 KiB
GDScript
extends RefCounted
|
||
const EARTHLIKE_FAMILIES := ["Terrestrial", "Lush", "Tropical"]
|
||
const MATERIALS := ["silicon", "copper", "nickel", "tungsten", "mercury"]
|
||
const MATERIAL_NAMES := {"silicon":"Krzem","copper":"Miedź","nickel":"Nikiel","tungsten":"Wolfram","mercury":"Rtęć"}
|
||
const THREAT_KEYS := ["oxygen","temperature","biology"]
|
||
const POI_SAFE_CHANCES := [0.90,0.70,0.40]
|
||
const POI_DANGER_CHANCES := [0.15,0.05,0.0]
|
||
|
||
static func is_earthlike(texture: Texture2D) -> bool:
|
||
if texture == null: return false
|
||
for family in EARTHLIKE_FAMILIES:
|
||
if texture.resource_path.contains("/Solid/%s/" % family): return true
|
||
return false
|
||
|
||
static func earthlike_textures() -> Array[Texture2D]:
|
||
var found: Array[Texture2D] = []
|
||
for texture in preload("res://scripts/levels/celestial_texture_catalog.gd").PLANET_TEXTURES:
|
||
if is_earthlike(texture): found.append(texture)
|
||
return found
|
||
|
||
static func level(profile: Dictionary) -> int:
|
||
return clampi(int(profile.get("system_level",1)),1,1000)
|
||
|
||
static func generate(system_seed: int, index: int, name: String, system_level: int = 1) -> Dictionary:
|
||
var rng := RandomNumberGenerator.new()
|
||
rng.seed = system_seed ^ (index*0x504c414e) ^ 0x42494f4d
|
||
var progression := 1.0-exp(-float(maxi(1,system_level)-1)/45.0)
|
||
var difficulty := clampf(progression*rng.randf_range(0.85,1.15),0,1)
|
||
var oxygen := roundi(95.0-difficulty*rng.randf_range(55,95))
|
||
var extreme_temperature := rng.randf_range(65,100) if rng.randf() < 0.5 else rng.randf_range(-50,-20)
|
||
var temperature := roundi(lerpf(20.0,extreme_temperature,difficulty))
|
||
var flora := roundi(difficulty*rng.randf_range(15,50))
|
||
return {"id":"%d:planet:%d" % [system_seed,index],"name":name,"system_level":maxi(1,system_level),"oxygen":oxygen,"temperature":temperature,"flora":flora,"easy":difficulty < 0.18,"difficulty":difficulty,"landing_damage":roundi(5+10*difficulty),"seed":rng.randi(),"index":index}
|
||
|
||
static func raw_threats(profile: Dictionary) -> Dictionary:
|
||
var oxygen := clampf((80.0-float(profile.get("oxygen",95)))/80.0,0,1)*100
|
||
var temperature := float(profile.get("temperature",20))
|
||
var thermal := 0.0
|
||
if temperature < -10: thermal = clampf((-10-temperature)/40,0,1)*100
|
||
elif temperature > 40: thermal = clampf((temperature-40)/60,0,1)*100
|
||
return {"oxygen":oxygen,"temperature":thermal,"biology":clampf(float(profile.get("flora",0))/50.0,0,1)*100}
|
||
|
||
static func equipment_report(profile: Dictionary, captain: Resource, weights: Array = [1.0,1.0,1.0]) -> Dictionary:
|
||
var gear := preload("res://scripts/planets/captain_equipment.gd")
|
||
var raw := raw_threats(profile)
|
||
var deficit := 0.0
|
||
var surplus := 0.0
|
||
var weight_total := 0.0
|
||
var effective := {}
|
||
var requirements := {}
|
||
for index in 3:
|
||
var key: String = THREAT_KEYS[index]
|
||
var required := maxf(1.0,level(profile)*(0.85+0.45*float(raw[key])/100.0))
|
||
var ratio := float(gear.level(captain,gear.KINDS[index]))/required
|
||
var shortfall := clampf(1.0-ratio,0,1)
|
||
effective[key] = shortfall*100
|
||
requirements[key] = required
|
||
deficit += shortfall*float(weights[index])
|
||
surplus += clampf(ratio-1.0,0,1)*float(weights[index])
|
||
weight_total += float(weights[index])
|
||
return {"deficit":deficit/weight_total,"surplus":surplus/weight_total,"raw":raw,"effective":effective,"requirements":requirements}
|
||
|
||
static func threat_report(profile: Dictionary, captain: Resource) -> Dictionary:
|
||
var report := equipment_report(profile,captain)
|
||
var raw_total := 0.0
|
||
var total := 0.0
|
||
for key in THREAT_KEYS:
|
||
raw_total += float(report.raw[key])
|
||
total += float(report.effective[key])
|
||
return {"raw":report.raw,"effective":report.effective,"raw_total":raw_total,"total":total}
|
||
|
||
static func global_threat(profile: Dictionary, captain: Resource) -> float:
|
||
return float(threat_report(profile,captain).total)
|
||
|
||
static func poi_loot_report(profile: Dictionary, captain: Resource, weights: Array = [1.0,1.0,1.0]) -> Dictionary:
|
||
var gear := equipment_report(profile,captain,weights)
|
||
var recovery := 1.0-0.5*float(gear.deficit)
|
||
var gear_multiplier := 1.0+0.1*float(gear.surplus)
|
||
return {"multiplier":recovery*gear_multiplier,"recovery":recovery,"gear_multiplier":gear_multiplier,"threat":float(gear.deficit)*300,"deficit":gear.deficit,"surplus":gear.surplus}
|
||
|
||
static func success_chance(profile: Dictionary, captain: Resource, stage: int) -> float:
|
||
var index := clampi(stage,0,2)
|
||
return lerpf(POI_SAFE_CHANCES[index],POI_DANGER_CHANCES[index],clampf(global_threat(profile,captain)/150,0,1))
|
||
|
||
static func average_success_chance(profile: Dictionary, captain: Resource) -> float:
|
||
var total := 0.0
|
||
for stage in 3: total += success_chance(profile,captain,stage)
|
||
return total/3
|
||
|
||
static func biome_name(profile: Dictionary) -> String:
|
||
if bool(profile.get("easy",false)): return "Łagodna biosfera"
|
||
if int(profile.get("temperature",20)) < -10: return "Zimna biosfera"
|
||
if int(profile.get("temperature",20)) > 40: return "Gorąca biosfera"
|
||
return "Dzika biosfera"
|
||
|
||
static func scan_description(profile: Dictionary, captain: Resource) -> String:
|
||
return "%s · Poziom %d\nLądowanie: −%d HP\nLądownik: %d / 100 HP\nPOI: podleć i naciśnij E, aby zaplanować eksplorację." % [profile.name,level(profile),profile.landing_damage,ceili(captain.expedition.lander_hp)]
|