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)]