93 lines
4.1 KiB
GDScript
93 lines
4.1 KiB
GDScript
extends RefCounted
|
|
## The network belongs to expedition progress, so it survives visits and system travel.
|
|
const BUILD_COST := 200
|
|
const DEPOSIT_CHANCE := 0.60
|
|
const CREW_CHANCE := 0.40
|
|
const CABINS := ["cabin_1", "cabin_2", "cabin_3", "cabin_4", "cabin_5"]
|
|
const FIRST_NAMES := ["Ada", "Mira", "Jan", "Leon", "Iga", "Oskar", "Nina", "Tomasz", "Sara", "Emil"]
|
|
const LAST_NAMES := ["Nowak", "Voss", "Kowalski", "Orion", "Lis", "Ward", "Keller", "Wilk", "Stern", "Vale"]
|
|
|
|
static func planet_roll(profile: Dictionary, salt: int) -> RandomNumberGenerator:
|
|
var rng := RandomNumberGenerator.new()
|
|
rng.seed = int(profile.get("seed", 0)) ^ str(profile.get("id", "planet")).hash() ^ salt
|
|
return rng
|
|
|
|
static func has_deep_deposit(profile: Dictionary) -> bool:
|
|
return planet_roll(profile, 0x44454550).randf() < DEPOSIT_CHANCE
|
|
|
|
static func has_recruit(profile: Dictionary) -> bool:
|
|
return planet_roll(profile, 0x43524557).randf() < CREW_CHANCE
|
|
|
|
static func recruit(profile: Dictionary) -> Dictionary:
|
|
var rng := planet_roll(profile, 0x50455253)
|
|
var rating := clampi(1 + roundi(clampf(float(profile.get("difficulty", 0)), 0, 1) * 80) + rng.randi_range(0, 19), 1, 100)
|
|
return {"id":str(profile.id)+":crew", "name":FIRST_NAMES[rng.randi_range(0,9)]+" "+LAST_NAMES[rng.randi_range(0,9)], "management":rating, "planet_id":str(profile.id), "planet_name":str(profile.name), "cabin":""}
|
|
|
|
static func free_cabin(progress: Resource) -> String:
|
|
for cabin in CABINS:
|
|
if progress.freighter_rooms.get(cabin, "") != "crew_cabin": continue
|
|
if cabin_crew(progress, cabin).is_empty(): return cabin
|
|
return ""
|
|
|
|
static func cabin_crew(progress: Resource, cabin: String) -> Dictionary:
|
|
for member in progress.crew.values():
|
|
if str(member.cabin) == cabin: return member
|
|
return {}
|
|
|
|
static func hire(progress: Resource, profile: Dictionary) -> bool:
|
|
var candidate := recruit(profile)
|
|
var cabin := free_cabin(progress)
|
|
if not has_recruit(profile) or progress.recruited_planets.has(str(profile.id)) or cabin.is_empty(): return false
|
|
candidate.cabin = cabin
|
|
progress.crew[candidate.id] = candidate
|
|
progress.recruited_planets[str(profile.id)] = true
|
|
progress.emit_changed()
|
|
return true
|
|
|
|
static func dismiss(progress: Resource, member_id: String) -> bool:
|
|
if not progress.crew.has(member_id): return false
|
|
for station in progress.mining_stations.values():
|
|
if str(station.get("crew_id", "")) == member_id: station.crew_id = ""
|
|
progress.crew.erase(member_id)
|
|
progress.emit_changed()
|
|
return true
|
|
|
|
static func build(progress: Resource, captain: Resource, profile: Dictionary, system: int) -> bool:
|
|
var id := str(profile.id)
|
|
if not has_deep_deposit(profile) or progress.mining_stations.has(id) or captain.parts < BUILD_COST: return false
|
|
captain.parts -= BUILD_COST
|
|
progress.mining_stations[id] = {"id":id, "planet_name":str(profile.name), "system":system, "crew_id":"", "produced":0.0}
|
|
captain.emit_changed()
|
|
progress.emit_changed()
|
|
return true
|
|
|
|
static func assign(progress: Resource, station_id: String, member_id: String) -> bool:
|
|
if not progress.mining_stations.has(station_id): return false
|
|
if not member_id.is_empty() and not progress.crew.has(member_id): return false
|
|
if not member_id.is_empty():
|
|
for station in progress.mining_stations.values():
|
|
if str(station.get("crew_id", "")) == member_id: station.crew_id = ""
|
|
progress.mining_stations[station_id].crew_id = member_id
|
|
progress.emit_changed()
|
|
return true
|
|
|
|
static func station_rate(progress: Resource, station: Dictionary) -> float:
|
|
var id := str(station.get("crew_id", ""))
|
|
if not progress.crew.has(id): return 0.0
|
|
return 1.0 + clampi(int(progress.crew[id].management), 1, 100)
|
|
|
|
static func total_rate(progress: Resource) -> float:
|
|
var total := 0.0
|
|
for station in progress.mining_stations.values(): total += station_rate(progress, station)
|
|
return total
|
|
|
|
static func advance(progress: Resource, seconds: float) -> float:
|
|
if seconds <= 0: return 0
|
|
var gained := 0.0
|
|
for station in progress.mining_stations.values():
|
|
var amount := station_rate(progress, station) * seconds / 60.0
|
|
station.produced = float(station.get("produced", 0)) + amount
|
|
gained += amount
|
|
progress.deuter += gained
|
|
return gained
|