update
This commit is contained in:
171
scripts/game.gd
171
scripts/game.gd
@@ -13,7 +13,6 @@ const RESIST_SEKUNDEN := 18.0
|
||||
## nicht der Faktor — Stufe 2 läuft dreifach, Stufe 3 siebenfach.
|
||||
const TEMPO_FAKTOR := [1.0, 3.0, 7.0]
|
||||
const TECHNIK_COOLDOWN := 30.0 # eine Technik braucht Luft, bevor sie wieder greift
|
||||
const FEHLVERSUCH_VERLUST := 14.0 # ein Fehlschlag wirft den Traum zurück
|
||||
# Der Verlust ist mit Absicht so hoch, dass sich nur eine Technik lohnt, die
|
||||
# Thema UND Moment trifft. Wer eine Regel blind auf jede Tätigkeit hängt,
|
||||
# verliert unterm Strich — die Wahl muss aus der Technik gelesen werden.
|
||||
@@ -26,6 +25,11 @@ var systeme: Dictionary = {} # human_id -> {slot -> {tech, guete}}
|
||||
var erkannt_slots: Dictionary = {} # human_id -> {slot -> true}
|
||||
var gesehen: Dictionary = {} # human_id -> {slot -> true}, wo man dabei war
|
||||
var notiz_sperre: float = 0.0 # nach einem Fehlgriff kurz gesperrt
|
||||
var situation: Dictionary = {} # laufende Situation: mensch, key, rest
|
||||
var situation_pause: float = 0.0 # bis die nächste kommen darf
|
||||
var probleme_bekannt: Dictionary = {} # human_id -> {problem -> true}
|
||||
var problem_stand: Dictionary = {} # "human:problem" -> gelungene Anwendungen
|
||||
var ueberwunden: Dictionary = {} # human_id -> {problem -> true}
|
||||
var completed: Array = []
|
||||
var time_h: float = 7.0
|
||||
var day: int = 1
|
||||
@@ -344,6 +348,24 @@ func sehen(human_id: String, nr: int) -> void:
|
||||
state_changed.emit()
|
||||
|
||||
|
||||
## Der Zustand einer Stunde. HUD und Panel zeichnen denselben -- zwei
|
||||
## Auslegungen würden mit der Zeit auseinanderlaufen.
|
||||
enum Stunde { UNBEKANNT, GESEHEN, SCHLAF, UNGEKLAERT, BENANNT, GEBAUT }
|
||||
|
||||
|
||||
func slot_zustand(human_id: String, nr: int) -> int:
|
||||
if not gesehen_slot(human_id, nr):
|
||||
return Stunde.UNBEKANNT
|
||||
if not system_in(human_id, nr).is_empty():
|
||||
return Stunde.GEBAUT
|
||||
var grund := slot_grund(human_id, nr)
|
||||
if Ursachen.ist_blocker(grund):
|
||||
return Stunde.BENANNT if erkannt(human_id, nr) else Stunde.UNGEKLAERT
|
||||
if grund == "schlaeft":
|
||||
return Stunde.SCHLAF
|
||||
return Stunde.GESEHEN
|
||||
|
||||
|
||||
func slot_grund(human_id: String, nr: int) -> String:
|
||||
var r := slots(human_id)
|
||||
return str(r[nr][2]) if nr >= 0 and nr < r.size() else ""
|
||||
@@ -501,6 +523,8 @@ func system_anzahl(human_id: String) -> int:
|
||||
func traum_voranbringen(stunden: float) -> void:
|
||||
if active_mission == "":
|
||||
return
|
||||
if situation_bei(active_mission):
|
||||
return # im Moment geht nichts voran
|
||||
var p: float = progress.get(active_mission, 0.0) \
|
||||
+ traum_tempo(active_mission) * stunden / 24.0
|
||||
progress[active_mission] = minf(p, MISSION_ZIEL)
|
||||
@@ -514,6 +538,151 @@ func traum_voranbringen(stunden: float) -> void:
|
||||
state_changed.emit()
|
||||
|
||||
|
||||
# ------------------------------------------------------- Probleme und Momente
|
||||
# Die zweite Ebene. Eine Gewohnheit sitzt im Tagesablauf und läuft ohne dich
|
||||
# weiter, sobald ein System steht. Ein Problem sitzt in keiner Stunde -- es
|
||||
# bricht in Situationen auf. Solange eine läuft, kommt der Traum nicht voran.
|
||||
# Du kannst sie aussitzen oder mit der passenden Technik beenden.
|
||||
|
||||
const SITUATION_DAUER := 22.0 # so lange steht der Traum still
|
||||
const SITUATION_PAUSE := 40.0 # Luft zwischen zwei Situationen
|
||||
const PROBLEM_UEBERWINDEN := 3 # so oft muss eine Technik greifen
|
||||
const SITUATION_GEWINN := 6.0 # Prozent, wenn sie früh beendet wird
|
||||
|
||||
|
||||
func probleme_von(human_id: String) -> Array:
|
||||
var h := HumanDB.by_id(human_id)
|
||||
return h["probleme"] if h.has("probleme") else []
|
||||
|
||||
|
||||
func problem_bekannt(human_id: String, problem: String) -> bool:
|
||||
return probleme_bekannt.get(human_id, {}).has(problem)
|
||||
|
||||
|
||||
func problem_ueberwunden(human_id: String, problem: String) -> bool:
|
||||
return ueberwunden.get(human_id, {}).has(problem)
|
||||
|
||||
|
||||
func problem_fortschritt(human_id: String, problem: String) -> int:
|
||||
return int(problem_stand.get("%s:%s" % [human_id, problem], 0))
|
||||
|
||||
|
||||
func situation_laeuft() -> bool:
|
||||
return not situation.is_empty()
|
||||
|
||||
|
||||
func situation_bei(human_id: String) -> bool:
|
||||
return situation_laeuft() and str(situation["mensch"]) == human_id
|
||||
|
||||
|
||||
func situation_problem() -> String:
|
||||
return str(situation["problem"]) if situation_laeuft() else ""
|
||||
|
||||
|
||||
## Läuft die Uhr weiter, kommt irgendwann die nächste Situation -- aber nur
|
||||
## bei einem wachen Menschen, dem man gerade hilft.
|
||||
func situationen_ticken(delta: float, wach: bool) -> void:
|
||||
if situation_laeuft():
|
||||
situation["rest"] = float(situation["rest"]) - delta
|
||||
if float(situation["rest"]) <= 0.0:
|
||||
var p := situation_problem()
|
||||
notified.emit("Der Moment ist vorbei — %s bleibt." % Probleme.name_von(p),
|
||||
Color(1, 0.75, 0.55))
|
||||
situation = {}
|
||||
situation_pause = SITUATION_PAUSE
|
||||
state_changed.emit()
|
||||
return
|
||||
situation_pause = maxf(0.0, situation_pause - delta)
|
||||
if active_mission == "" or not wach or situation_pause > 0.0:
|
||||
return
|
||||
_situation_starten()
|
||||
|
||||
|
||||
func _situation_starten() -> void:
|
||||
var offen: Array = []
|
||||
for p in probleme_von(active_mission):
|
||||
if not problem_ueberwunden(active_mission, str(p)):
|
||||
offen.append(str(p))
|
||||
if offen.is_empty():
|
||||
situation_pause = SITUATION_PAUSE
|
||||
return
|
||||
var problem: String = str(offen[randi() % offen.size()])
|
||||
var moeglich := Probleme.situationen_von(problem)
|
||||
if moeglich.is_empty():
|
||||
situation_pause = SITUATION_PAUSE
|
||||
return
|
||||
situation = {
|
||||
"mensch": active_mission,
|
||||
"key": str(moeglich[randi() % moeglich.size()]),
|
||||
"problem": problem,
|
||||
"rest": SITUATION_DAUER,
|
||||
}
|
||||
state_changed.emit()
|
||||
|
||||
|
||||
## Dabeisein zeigt, welches Problem dahintersteckt.
|
||||
func situation_sehen() -> void:
|
||||
if not situation_laeuft():
|
||||
return
|
||||
var id := str(situation["mensch"])
|
||||
var p := situation_problem()
|
||||
if problem_bekannt(id, p):
|
||||
return
|
||||
if not probleme_bekannt.has(id):
|
||||
probleme_bekannt[id] = {}
|
||||
probleme_bekannt[id][p] = true
|
||||
notified.emit("Dahinter steckt: %s — %s" %
|
||||
[Probleme.name_von(p), Probleme.LISTE[p]["kurz"]], Color(0.8, 0.95, 1))
|
||||
state_changed.emit()
|
||||
|
||||
|
||||
## Eine Technik im Moment anwenden. Passt sie zum Problem, ist die Situation
|
||||
## vorbei; oft genug, und das Problem kommt nicht wieder.
|
||||
func situation_anwenden(tech_id: String) -> Dictionary:
|
||||
var res := {"ok": false, "grund": "", "treffer": false, "ueberwunden": false}
|
||||
if not situation_laeuft():
|
||||
res["grund"] = "Gerade ist kein Moment offen."
|
||||
return res
|
||||
if not known.has(tech_id):
|
||||
res["grund"] = "Diese Technik kennst du nicht."
|
||||
return res
|
||||
if not bereit(tech_id):
|
||||
res["grund"] = "%s braucht noch %.0f s." % [TechDB.by_id(tech_id)["name"],
|
||||
cooldown_rest(tech_id)]
|
||||
return res
|
||||
var id := str(situation["mensch"])
|
||||
var problem := situation_problem()
|
||||
cooldown[tech_id] = TECHNIK_COOLDOWN
|
||||
res["ok"] = true
|
||||
if not Probleme.hilft(tech_id, problem):
|
||||
add_xp(tech_id, 1)
|
||||
notified.emit("%s greift hier nicht." % TechDB.by_id(tech_id)["name"],
|
||||
Color(1, 0.7, 0.5))
|
||||
state_changed.emit()
|
||||
return res
|
||||
|
||||
res["treffer"] = true
|
||||
add_xp(tech_id, 2)
|
||||
var schluessel := "%s:%s" % [id, problem]
|
||||
problem_stand[schluessel] = problem_fortschritt(id, problem) + 1
|
||||
situation_sehen()
|
||||
situation = {}
|
||||
situation_pause = SITUATION_PAUSE
|
||||
if id == active_mission:
|
||||
progress[id] = minf(mission_progress(id) + SITUATION_GEWINN, MISSION_ZIEL)
|
||||
notified.emit("%s trägt durch den Moment. (+%d %%)" %
|
||||
[TechDB.by_id(tech_id)["name"], int(SITUATION_GEWINN)], Color(0.6, 1, 0.7))
|
||||
if problem_fortschritt(id, problem) >= PROBLEM_UEBERWINDEN:
|
||||
if not ueberwunden.has(id):
|
||||
ueberwunden[id] = {}
|
||||
ueberwunden[id][problem] = true
|
||||
res["ueberwunden"] = true
|
||||
notified.emit("%s ist überwunden — dieser Moment kommt nicht wieder." %
|
||||
Probleme.name_von(problem), Color(1, 0.85, 0.4))
|
||||
state_changed.emit()
|
||||
return res
|
||||
|
||||
|
||||
# --------------------------------------------------- Erreichbarkeit
|
||||
|
||||
## Schlafende erreicht niemand.
|
||||
|
||||
Reference in New Issue
Block a user