Randoloot/scripts/planets/planet_progress.gd
2026-10-18 08:43:54 +02:00

150 lines
5.3 KiB
GDScript

extends Resource
const EQUIPMENT := preload("res://scripts/planets/captain_equipment.gd")
const REWARDS := preload("res://scripts/planets/planet_rewards.gd")
const PROFILES := preload("res://scripts/planets/planet_profiles.gd")
@export var lander_hp := 100.0
@export var visits: Dictionary = {}
@export var scans: Dictionary = {}
@export var delivered_modules: Array[Resource] = []
@export var research_records: Dictionary = {}
@export var delivered_missiles := 0
var cargo_credits := 0
var cargo_parts := 0
var cargo_missiles := 0
var active := false
var cargo: Dictionary = {}
var cargo_modules: Array[Resource] = []
var cargo_records: Dictionary = {}
var active_profile: Dictionary = {}
var visit_seed := 0
var last_result: Dictionary = {}
func repair_cost() -> int:
return maxi(0, ceili(100.0 - lander_hp - 0.00001))
func repair(captain: Resource) -> bool:
var cost := repair_cost()
if active or captain.parts < cost:
return false
captain.parts -= cost
lander_hp = 100
captain.emit_changed()
return true
func scan(profile: Dictionary) -> void:
scans[str(profile.id)] = profile.duplicate(true)
emit_changed()
func begin_visit(profile: Dictionary) -> bool:
if active or repair_cost() > 0:
return false
active_profile = profile.duplicate(true)
var count := int(visits.get(profile.id, 0)) + 1
visits[profile.id] = count
visit_seed = int(profile.seed) ^ (count * 7919)
cargo_credits = 0
cargo_parts = 0
cargo_missiles = 0
cargo.clear()
cargo_modules.clear()
cargo_records.clear()
active = true
lander_hp = maxf(0, lander_hp - float(profile.landing_damage))
last_result.clear()
return true
func damage(amount: float) -> void:
if active:
lander_hp = clampf(lander_hp - maxf(0, amount), 0, 100)
emit_changed()
func add_material(key: String, amount: int) -> void:
if active and amount > 0:
cargo[key] = int(cargo.get(key, 0)) + amount
emit_changed()
func resolve_poi(captain: Resource, poi: Dictionary, rng: RandomNumberGenerator) -> Dictionary:
if not active or bool(poi.get("complete", false)):
return {}
var stage := int(poi.get("stage", 0))
var chance := PROFILES.success_chance(active_profile, captain, stage)
var success := false
var result := {"success": success, "chance": chance, "damage": 0, "materials": {}, "module": null}
if chance <= 0.0:
result.blocked = true
result.reason = "Ten etap ma 0% szans. Potrzebujesz lepszego wyposażenia, aby zmniejszyć zagrożenie."
return result
success = rng.randf() < chance
result.success = success
if success:
var difficulty := float(active_profile.difficulty)
var multiplier := REWARDS.material_multiplier(active_profile) * (1.0 + stage * 0.65)
var ordinary: Array = ["iron", "titanium", "aluminium", "uranium", "sulfur"]
var pool: Array = PROFILES.MATERIALS if rng.randf() < 0.55 else ordinary
var key: String = pool[rng.randi_range(0, pool.size() - 1)]
var amount := maxi(1, roundi(rng.randi_range(5, 12) * multiplier))
add_material(key, amount)
result.materials[key] = amount
if rng.randf() < 0.15 + difficulty * 0.25:
var generator := preload("res://scripts/items/item_generator.gd")
var definitions: Array = generator.DEFINITIONS.filter(func(d): return d.category != ItemDefinition.Category.WEAPON)
var item: ItemInstance = REWARDS.generate_module(rng, active_profile, GameState.system_level, definitions[rng.randi_range(0, definitions.size()-1)], 1 if difficulty > 0.5 or stage >= 2 else 0)
cargo_modules.append(item)
result.module = item
if str(poi.kind) == "ruins":
var record := "Archiwum %s" % str(active_profile.name)
cargo_records[record] = int(cargo_records.get(record, 0)) + 1
poi.stage = stage + 1
if int(poi.stage) >= 3:
poi.complete = true
else:
var loss := rng.randi_range(8, 15) + stage * 5 + roundi(float(active_profile.difficulty) * 10)
damage(loss)
result.damage = loss
# Failure closes this location; previously collected loot stays until return.
poi.complete = true
emit_changed()
return result
func finish_visit(captain: Resource, success: bool) -> Dictionary:
if not active:
return last_result
success = success and lander_hp > 0
var result := {"success": success, "materials": cargo.duplicate(), "modules": cargo_modules.size(), "hp": lander_hp, "credits":cargo_credits, "parts":cargo_parts, "missiles":cargo_missiles}
if success:
captain.credits += cargo_credits
captain.parts += cargo_parts
delivered_missiles += cargo_missiles
for key in cargo:
captain.minerals[key] = int(captain.minerals.get(key, 0)) + int(cargo[key])
delivered_modules.append_array(cargo_modules)
for key in cargo_records:
research_records[key] = int(research_records.get(key, 0)) + int(cargo_records[key])
active = false
cargo_credits = 0
cargo_parts = 0
cargo_missiles = 0
cargo.clear()
cargo_modules.clear()
cargo_records.clear()
active_profile.clear()
last_result = result
captain.emit_changed()
emit_changed()
return result
func deliver_modules(inventory: Node) -> int:
if delivered_missiles > 0:
inventory.missile_ammunition += delivered_missiles
delivered_missiles = 0
inventory.ammunition_changed.emit()
inventory.inventory_changed.emit()
var delivered := 0
for index in range(delivered_modules.size() - 1, -1, -1):
if inventory.add_item(delivered_modules[index]):
delivered_modules.remove_at(index)
delivered += 1
emit_changed()
return delivered