103 lines
5.1 KiB
GDScript
103 lines
5.1 KiB
GDScript
extends RefCounted
|
||
# These visually inspected families contain land, oceans and atmospheric clouds.
|
||
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ęć"}
|
||
|
||
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 generate(system_seed: int, index: int, name: String) -> Dictionary:
|
||
var rng := RandomNumberGenerator.new()
|
||
rng.seed = system_seed ^ (index * 0x504c414e) ^ 0x42494f4d
|
||
var easy := rng.randf() < 0.7
|
||
var oxygen := rng.randi_range(81, 100) if easy else rng.randi_range(0, 80)
|
||
var temperature := rng.randi_range(-10, 40) if easy else rng.randi_range(-50, 100)
|
||
var flora := 0 if easy else rng.randi_range(5, 50)
|
||
var raw := raw_threats({"oxygen":oxygen,"temperature":temperature,"flora":flora})
|
||
var difficulty := (float(raw.oxygen)+float(raw.temperature)+float(raw.biology))/300.0
|
||
return {"id": "%d:planet:%d" % [system_seed, index], "name": name, "oxygen": oxygen, "temperature": temperature, "flora": flora, "easy": easy, "difficulty": difficulty, "landing_damage": roundi(lerpf(5.0, 20.0, difficulty)), "seed": rng.randi(), "index": index}
|
||
|
||
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 raw_threats(profile: Dictionary) -> Dictionary:
|
||
var oxygen := clampf((80.0-float(profile.oxygen))/80.0,0.0,1.0)*100.0
|
||
var temperature := float(profile.temperature)
|
||
var thermal := 0.0
|
||
if temperature < -10.0:
|
||
thermal = clampf((-10.0-temperature)/40.0,0.0,1.0)*100.0
|
||
elif temperature > 40.0:
|
||
thermal = clampf((temperature-40.0)/60.0,0.0,1.0)*100.0
|
||
var biology := clampf(float(profile.flora)/50.0,0.0,1.0)*100.0
|
||
return {"oxygen":oxygen,"temperature":thermal,"biology":biology}
|
||
|
||
static func threat_report(profile: Dictionary, captain: Resource) -> Dictionary:
|
||
var gear := preload("res://scripts/planets/captain_equipment.gd")
|
||
var raw := raw_threats(profile)
|
||
var effective := {}
|
||
var raw_total := 0.0
|
||
var total := 0.0
|
||
for index in 3:
|
||
var key: String = THREAT_KEYS[index]
|
||
var protection := minf(100.0,2.0*maxi(0,gear.level(captain,gear.KINDS[index])))
|
||
effective[key] = maxf(0.0,float(raw[key])-protection)
|
||
raw_total += float(raw[key])
|
||
total += float(effective[key])
|
||
return {"raw":raw,"effective":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) -> Dictionary:
|
||
var gear := preload("res://scripts/planets/captain_equipment.gd")
|
||
var equipped_levels := 0.0
|
||
for kind in gear.KINDS: equipped_levels += clampi(gear.level(captain,kind),0,50)
|
||
var gear_multiplier := 1.0+(equipped_levels/3.0)*0.02
|
||
var threat := global_threat(profile,captain)
|
||
var recovery := clampf(1.0-threat/300.0,0.15,1.0)
|
||
return {"multiplier":gear_multiplier*recovery,"recovery":recovery,"gear_multiplier":gear_multiplier,"threat":threat}
|
||
|
||
static func success_chance(profile: Dictionary, captain: Resource, stage: int) -> float:
|
||
var index := clampi(stage,0,2)
|
||
var severity := clampf(global_threat(profile,captain)/150.0,0.0,1.0)
|
||
return lerpf(POI_SAFE_CHANCES[index],POI_DANGER_CHANCES[index],severity)
|
||
|
||
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.0
|
||
|
||
static func biome_name(profile: Dictionary) -> String:
|
||
if bool(profile.easy):
|
||
return "Łagodna biosfera"
|
||
if int(profile.temperature) < -10:
|
||
return "Zimna biosfera"
|
||
if int(profile.temperature) > 40:
|
||
return "Gorąca biosfera"
|
||
return "Dzika biosfera"
|
||
|
||
static func scan_description(profile: Dictionary, captain: Resource) -> String:
|
||
var report := threat_report(profile,captain)
|
||
var loot := poi_loot_report(profile,captain)
|
||
return "%s · %s\nTLEN %d%% · zagrożenie %.0f%% → %.0f%%\nTEMPERATURA %d°C · zagrożenie %.0f%% → %.0f%%\nBIOLOGICZNE %d/50 · zagrożenie %.0f%% → %.0f%%\nZAGROŻENIE GLOBALNE: %.1f%% / 300%%\nBez sprzętu: %.1f%% · redukcja 2 pp/poziom\nŁUP POI: ×%.2f · odzysk %.0f%% · sprzęt ×%.2f\nPOI: podleć i naciśnij E, aby odebrać znaleziska.\nLądowanie: −%d HP · Lądownik: %d%%" % [
|
||
profile.name,biome_name(profile),profile.oxygen,report.raw.oxygen,report.effective.oxygen,
|
||
profile.temperature,report.raw.temperature,report.effective.temperature,
|
||
profile.flora,report.raw.biology,report.effective.biology,
|
||
report.total,report.raw_total,loot.multiplier,loot.recovery*100.0,loot.gear_multiplier,
|
||
profile.landing_damage,ceili(captain.expedition.lander_hp)]
|