update
This commit is contained in:
@@ -1,26 +1,27 @@
|
|||||||
78098b89c88a74ebe8c20117b8754620
|
78098b89c88a74ebe8c20117b8754620
|
||||||
::res://::1788113016
|
::res://::1788260833
|
||||||
anforderungen.md::TextFile::-1::1788204851::0::1::::<><><>0<>0<><>::
|
anforderungen.md::TextFile::-1::1788584851::0::1::::<><><>0<>0<><>::
|
||||||
README.md::TextFile::-1::1788165734::0::1::::<><><>0<>0<><>::
|
README.md::TextFile::-1::1788471905::0::1::::<><><>0<>0<><>::
|
||||||
::res://scenes/::1787989294
|
::res://scenes/::1788012512
|
||||||
main.tscn::PackedScene::-1::1787989294::0::1::::<><><>0<>0<><>::res://scripts/main.gd
|
main.tscn::PackedScene::-1::1788012512::0::1::::<><><>0<>0<><>::res://scripts/main.gd
|
||||||
::res://scripts/::1788209300
|
::res://scripts/::1788584883
|
||||||
bewohner.gd::GDScript::2125278938812678811::1788209097::0::1::::Bewohner<>Node3D<><>0<>0<><>::
|
bewohner.gd::GDScript::2125278938812678811::1788463944::0::1::::Bewohner<>Node3D<><>0<>0<><>::
|
||||||
dream_db.gd::GDScript::4217518896355437099::1788164505::0::1::::DreamDB<>RefCounted<><>0<>0<><>::
|
dream_db.gd::GDScript::4217518896355437099::1788260794::0::1::::DreamDB<>RefCounted<><>0<>0<><>::
|
||||||
dream_world.gd::GDScript::8279158278942867258::1788164873::0::1::::DreamWorld<>Node3D<><>0<>0<><>::
|
dream_world.gd::GDScript::8279158278942867258::1788260794::0::1::::DreamWorld<>Node3D<><>0<>0<><>::
|
||||||
earth_world.gd::GDScript::6086818627272428934::1788165412::0::1::::EarthWorld<>Node3D<><>0<>0<><>::
|
earth_world.gd::GDScript::6086818627272428934::1788260794::0::1::::EarthWorld<>Node3D<><>0<>0<><>::
|
||||||
game.gd::GDScript::3600922541500868814::1788209816::0::1::::<>Node<><>0<>0<><>::
|
game.gd::GDScript::3600922541500868814::1788468437::0::1::::<>Node<><>0<>0<><>::
|
||||||
human_db.gd::GDScript::412604892032291296::1788208999::0::1::::HumanDB<>RefCounted<><>0<>0<><>::
|
human_db.gd::GDScript::412604892032291296::1788584883::0::1::::HumanDB<>RefCounted<><>0<>0<><>::
|
||||||
main.gd::GDScript::1504009331368977934::1788209245::0::1::::<>Node3D<><>0<>0<><>::
|
main.gd::GDScript::1504009331368977934::1788471754::0::1::::<>Node3D<><>0<>0<><>::
|
||||||
netz.gd::GDScript::8422943321868648339::1788163667::0::1::::Netz<>RefCounted<><>0<>0<><>::
|
netz.gd::GDScript::8422943321868648339::1788260794::0::1::::Netz<>RefCounted<><>0<>0<><>::
|
||||||
orte.gd::GDScript::5536340784294498671::1788209635::0::1::::Orte<>RefCounted<><>0<>0<><>::
|
orte.gd::GDScript::5536340784294498671::1788260833::0::1::::Orte<>RefCounted<><>0<>0<><>::
|
||||||
player.gd::GDScript::8724108548430371398::1788039718::0::1::::Player<>CharacterBody3D<><>0<>0<><>::
|
player.gd::GDScript::8724108548430371398::1788459499::0::1::::Player<>CharacterBody3D<><>0<>0<><>::
|
||||||
prims.gd::GDScript::322632462553361584::1788039797::0::1::::Prims<>RefCounted<><>0<>0<><>::
|
prims.gd::GDScript::322632462553361584::1788088940::0::1::::Prims<>RefCounted<><>0<>0<><>::
|
||||||
technique_db.gd::GDScript::4543286561661639701::1788209343::0::1::::TechDB<>RefCounted<><>0<>0<><>::
|
probleme.gd::GDScript::4928319609961045127::1788584883::0::1::::Probleme<>RefCounted<><>0<>0<><>::
|
||||||
ui.gd::GDScript::843471304695966286::1788209227::0::1::::UI<>CanvasLayer<><>0<>0<><>::
|
technique_db.gd::GDScript::4543286561661639701::1788260833::0::1::::TechDB<>RefCounted<><>0<>0<><>::
|
||||||
ursachen.gd::GDScript::7371116734724270900::1788208917::0::1::::Ursachen<>RefCounted<><>0<>0<><>::
|
ui.gd::GDScript::843471304695966286::1788471755::0::1::::UI<>CanvasLayer<><>0<>0<><>::
|
||||||
::res://tests/::1788209571
|
ursachen.gd::GDScript::7371116734724270900::1788260833::0::1::::Ursachen<>RefCounted<><>0<>0<><>::
|
||||||
shots.gd::GDScript::5999651346126871724::1788209816::0::1::::<>Node<><>0<>0<><>::
|
::res://tests/::1788471701
|
||||||
shots.tscn::PackedScene::-1::1787990528::0::1::::<><><>0<>0<><>::res://tests/shots.gd
|
shots.gd::GDScript::5999651346126871724::1788260833::0::1::::<>Node<><>0<>0<><>::
|
||||||
verify.gd::GDScript::4392606218392155269::1788209816::0::1::::<>Node<><>0<>0<><>::
|
shots.tscn::PackedScene::-1::1788012512::0::1::::<><><>0<>0<><>::res://tests/shots.gd
|
||||||
verify.tscn::PackedScene::-1::1787989983::0::1::::<><><>0<>0<><>::res://tests/verify.gd
|
verify.gd::GDScript::4392606218392155269::1788471838::0::1::::<>Node<><>0<>0<><>::
|
||||||
|
verify.tscn::PackedScene::-1::1788012512::0::1::::<><><>0<>0<><>::res://tests/verify.gd
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ select_mode=0
|
|||||||
|
|
||||||
[editor_metadata]
|
[editor_metadata]
|
||||||
|
|
||||||
executable_path="/home/arbeit/bin/godot"
|
executable_path="/home/arbeit/.local/bin/godot"
|
||||||
|
|
||||||
[recent_files]
|
[recent_files]
|
||||||
|
|
||||||
|
|||||||
@@ -72,6 +72,14 @@ list=[{
|
|||||||
"path": "res://scripts/prims.gd"
|
"path": "res://scripts/prims.gd"
|
||||||
}, {
|
}, {
|
||||||
"base": &"RefCounted",
|
"base": &"RefCounted",
|
||||||
|
"class": &"Probleme",
|
||||||
|
"icon": "",
|
||||||
|
"is_abstract": false,
|
||||||
|
"is_tool": false,
|
||||||
|
"language": &"GDScript",
|
||||||
|
"path": "res://scripts/probleme.gd"
|
||||||
|
}, {
|
||||||
|
"base": &"RefCounted",
|
||||||
"class": &"TechDB",
|
"class": &"TechDB",
|
||||||
"icon": "",
|
"icon": "",
|
||||||
"is_abstract": false,
|
"is_abstract": false,
|
||||||
|
|||||||
Binary file not shown.
51
README.md
51
README.md
@@ -34,6 +34,25 @@ Das Journal führt Buch — es lehrt und vergibt nichts.
|
|||||||
gibt keine Wochentage; jeder Tag ist derselbe. Zu Beginn steht in jedem
|
gibt keine Wochentage; jeder Tag ist derselbe. Zu Beginn steht in jedem
|
||||||
Abschnitt nur ein Strich — der Tag ist leer, bis du dabei warst.
|
Abschnitt nur ein Strich — der Tag ist leer, bis du dabei warst.
|
||||||
|
|
||||||
|
**Zwei Ebenen** — Gewohnheiten und Momente
|
||||||
|
|
||||||
|
Ein Mensch wird von zwei verschiedenen Dingen aufgehalten, und beide brauchen
|
||||||
|
eine andere Art zu spielen.
|
||||||
|
|
||||||
|
Gewohnheiten sitzen im Tagesablauf planend laufen ohne dich weiter
|
||||||
|
Probleme sitzen in Momenten reagierend du musst dabei sein
|
||||||
|
|
||||||
|
Eine Gewohnheit hat einen Platz im Tag: um zehn räumt sie auf, statt
|
||||||
|
anzufangen. Du findest den Platz, pflanzt eine Ersatzhandlung ein, und sie
|
||||||
|
läuft von allein. Ein psychisches Problem hat keinen Platz — es bricht in
|
||||||
|
**Situationen** auf, wann es will. Solange eine läuft, kommt der Traum nicht
|
||||||
|
voran; du kannst sie aussitzen oder mit der passenden Technik beenden.
|
||||||
|
|
||||||
|
Dreimal die richtige Technik im richtigen Moment, und das Problem ist
|
||||||
|
überwunden — dieser Moment kommt nicht wieder. Bis dahin umgehst du ihn jedes
|
||||||
|
Mal aufs Neue. Beides steht im HUD, bewusst verschieden gezeichnet: der Tag
|
||||||
|
als 24-Felder-Streifen, die Momente als Liste mit dem, was gerade aufbricht.
|
||||||
|
|
||||||
**Diagnose und Systeme** — der Kern des Spiels
|
**Diagnose und Systeme** — der Kern des Spiels
|
||||||
|
|
||||||
Ein Traum scheitert an Ursachen: *kein Anfang*, *keine Zeit*, *keine Kraft*,
|
Ein Traum scheitert an Ursachen: *kein Anfang*, *keine Zeit*, *keine Kraft*,
|
||||||
@@ -140,29 +159,31 @@ Abwehr. Am Ausgang ändert sich dadurch nichts, nur an der Wartezeit.
|
|||||||
Technik nur, ob Thema und Moment passen — keine Zahl.
|
Technik nur, ob Thema und Moment passen — keine Zahl.
|
||||||
* Die Säule im Park bringt dich zurück in die Traumwelt.
|
* Die Säule im Park bringt dich zurück in die Traumwelt.
|
||||||
|
|
||||||
## Erfolgschance
|
## Ob es gelingt
|
||||||
|
|
||||||
5 % + 9 % je Fertigkeitsstufe
|
Ein System einzurichten ist kein Selbstläufer:
|
||||||
+ 20 % wenn die Technik das Thema des Menschen trifft
|
|
||||||
+ 35 % wenn der Moment passt (z. B. Box-Atmung, während jemand angespannt ist)
|
20 % + 13 % je Fertigkeitsstufe
|
||||||
− 30 % wenn der Mensch gerade abblockt
|
− 25 % wenn der Mensch gerade abwehrt
|
||||||
begrenzt auf 5 … 95 %
|
begrenzt auf 5 … 95 %
|
||||||
|
|
||||||
Schlafende sind nicht erreichbar. Erfolg bringt Fortschritt und 2 EP, ein
|
Gelingt es, steht das System im Slot. Wie gut es trägt, entscheidet nicht der
|
||||||
Fehlversuch 1 EP, −14 % Fortschritt und 18 Sekunden Abwehr. Jeder Einsatz sperrt
|
Wurf, sondern die Passung: eine Ersatzhandlung mit **derselben Belohnung** wie
|
||||||
die Technik für 30 Sekunden. Dieselbe Technik wirkt bei Wiederholung schwächer —
|
der Blocker — oder eine Technik, die ihm den Auslöser nimmt — hält deutlich
|
||||||
es lohnt sich, mehrere zu lernen. 100 % erfüllen den Traum.
|
besser als eine, die nur den freien Platz füllt.
|
||||||
|
|
||||||
|
Im Moment einer Situation wird nicht gewürfelt. Entweder die Technik trifft das
|
||||||
|
Problem oder nicht. Jeder Einsatz sperrt die Technik für 30 Sekunden.
|
||||||
|
|
||||||
**Eine Technik wird nur besser, indem du sie anwendest.** Der Lehrort gibt sie
|
**Eine Technik wird nur besser, indem du sie anwendest.** Der Lehrort gibt sie
|
||||||
dir, mehr nicht: kein Üben, kein Trainieren, keine Währung, die man dagegen
|
dir, mehr nicht: kein Üben, kein Trainieren, keine Währung, die man dagegen
|
||||||
eintauschen könnte. Wer eine Technik auf Stufe 5 will, muss sie draußen bei
|
eintauschen könnte. Ein Erfolg bringt 2 EP, ein Fehlversuch 1 — auch der zählt.
|
||||||
Menschen einsetzen — auch Fehlversuche zählen.
|
|
||||||
|
|
||||||
## Aufbau
|
## Aufbau
|
||||||
|
|
||||||
project.godot Projekt, Autoload `Game`
|
project.godot Projekt, Autoload `Game`
|
||||||
scenes/main.tscn Einstieg
|
scenes/main.tscn Einstieg
|
||||||
scripts/game.gd Zustand, Diagnose, Systeme, Tempo, Uhr (Autoload)
|
scripts/game.gd Zustand, Diagnose, Systeme, Momente, Tempo, Uhr (Autoload)
|
||||||
scripts/technique_db.gd die zwölf Techniken mit ihren Hinweisen
|
scripts/technique_db.gd die zwölf Techniken mit ihren Hinweisen
|
||||||
scripts/human_db.gd Bezirk: Arterien, Blöcke, roji, Parzellen, Menschen
|
scripts/human_db.gd Bezirk: Arterien, Blöcke, roji, Parzellen, Menschen
|
||||||
scripts/dream_db.gd Traumdorf: wachsende Häuser, Wege, Bewohner, Lehrorte
|
scripts/dream_db.gd Traumdorf: wachsende Häuser, Wege, Bewohner, Lehrorte
|
||||||
@@ -170,10 +191,11 @@ Menschen einsetzen — auch Fehlversuche zählen.
|
|||||||
scripts/orte.gd Orte, Türen, Wege, Tätigkeiten (beide Welten)
|
scripts/orte.gd Orte, Türen, Wege, Tätigkeiten (beide Welten)
|
||||||
scripts/bewohner.gd Bewohner mit Tagesablauf und Slots
|
scripts/bewohner.gd Bewohner mit Tagesablauf und Slots
|
||||||
scripts/main.gd Weltenwechsel, Fokus, Interaktion
|
scripts/main.gd Weltenwechsel, Fokus, Interaktion
|
||||||
scripts/player.gd Läufer in der Traumwelt, Geist auf der Erde
|
scripts/player.gd Läufer in der Traumwelt, Geist auf der Erde, Verfolgung
|
||||||
scripts/dream_world.gd Insel mit Dorf
|
scripts/dream_world.gd Insel mit Dorf
|
||||||
scripts/earth_world.gd Stadt mit Tag-Nacht-Wechsel
|
scripts/earth_world.gd Stadt mit Tag-Nacht-Wechsel
|
||||||
scripts/ursachen.gd Ursachen, blockierende Tätigkeiten, Belohnungen
|
scripts/ursachen.gd Ursachen, blockierende Tätigkeiten, Belohnungen
|
||||||
|
scripts/probleme.gd Psychische Probleme und die Momente, in denen sie aufbrechen
|
||||||
scripts/ui.gd HUD, Journal, Tagesablauf, Hörsaal, Brett, Panels
|
scripts/ui.gd HUD, Journal, Tagesablauf, Hörsaal, Brett, Panels
|
||||||
scripts/prims.gd Bausteine aus Primitiven
|
scripts/prims.gd Bausteine aus Primitiven
|
||||||
|
|
||||||
@@ -186,7 +208,8 @@ Menschen einsetzen — auch Fehlversuche zählen.
|
|||||||
Tagesabläufen, gewachsenes Dorf und erzeugter Bezirk,
|
Tagesabläufen, gewachsenes Dorf und erzeugter Bezirk,
|
||||||
Häuser betreten, Journal in beiden Welten, im Hörsaal lernen,
|
Häuser betreten, Journal in beiden Welten, im Hörsaal lernen,
|
||||||
Verbessern allein durchs Anwenden, Mission am Schwarzen Brett annehmen,
|
Verbessern allein durchs Anwenden, Mission am Schwarzen Brett annehmen,
|
||||||
Ursachen aufdecken, Systeme bauen, Tempo messen, zur Erde reisen,
|
Ursachen benennen, Systeme bauen, Momente abfangen, Probleme überwinden,
|
||||||
|
Tempo messen, zur Erde reisen,
|
||||||
Tagesabläufe über einen ganzen Tag, Wirkung der Technikwahl, Cooldown,
|
Tagesabläufe über einen ganzen Tag, Wirkung der Technikwahl, Cooldown,
|
||||||
verdeckte Erfolgschance, keine Passungshinweise,
|
verdeckte Erfolgschance, keine Passungshinweise,
|
||||||
Tempo und Nachtsprung,
|
Tempo und Nachtsprung,
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ Kern
|
|||||||
Loops
|
Loops
|
||||||
- Träume erfüllen -> Welt vergrößeren -> Techniken entdecken
|
- Träume erfüllen -> Welt vergrößeren -> Techniken entdecken
|
||||||
- Techniken entdecken -> Techniken lernen -> Missionen freischalten
|
- Techniken entdecken -> Techniken lernen -> Missionen freischalten
|
||||||
- Menschen beobachten -> Probleme finden -> Techniken anwenden
|
- Menschen beobachten -> Tagesablauf herausfinden -> Gewohnheiten anpassen
|
||||||
|
- Menschen beobachten -> Probleme erkennen -> Techniken anwenden
|
||||||
|
|
||||||
Funktionen
|
Funktionen
|
||||||
- Bewegung: Bewegen, Springen, Geist, Anhängen
|
- Bewegung: Bewegen, Springen, Geist, Anhängen
|
||||||
|
|||||||
@@ -148,6 +148,8 @@ func beschriftung() -> String:
|
|||||||
if data.has("rolle"):
|
if data.has("rolle"):
|
||||||
s += ", " + str(data["rolle"])
|
s += ", " + str(data["rolle"])
|
||||||
s += "\n" + Orte.text(activity)
|
s += "\n" + Orte.text(activity)
|
||||||
|
if mit_mission and Game.situation_bei(str(data["id"])):
|
||||||
|
s += "\n» %s «" % Probleme.SITUATIONEN[Game.situation["key"]]["name"]
|
||||||
if resist_left > 0.0:
|
if resist_left > 0.0:
|
||||||
s += " (macht dicht)"
|
s += " (macht dicht)"
|
||||||
if mit_mission:
|
if mit_mission:
|
||||||
|
|||||||
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.
|
## nicht der Faktor — Stufe 2 läuft dreifach, Stufe 3 siebenfach.
|
||||||
const TEMPO_FAKTOR := [1.0, 3.0, 7.0]
|
const TEMPO_FAKTOR := [1.0, 3.0, 7.0]
|
||||||
const TECHNIK_COOLDOWN := 30.0 # eine Technik braucht Luft, bevor sie wieder greift
|
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
|
# 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,
|
# 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.
|
# 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 erkannt_slots: Dictionary = {} # human_id -> {slot -> true}
|
||||||
var gesehen: Dictionary = {} # human_id -> {slot -> true}, wo man dabei war
|
var gesehen: Dictionary = {} # human_id -> {slot -> true}, wo man dabei war
|
||||||
var notiz_sperre: float = 0.0 # nach einem Fehlgriff kurz gesperrt
|
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 completed: Array = []
|
||||||
var time_h: float = 7.0
|
var time_h: float = 7.0
|
||||||
var day: int = 1
|
var day: int = 1
|
||||||
@@ -344,6 +348,24 @@ func sehen(human_id: String, nr: int) -> void:
|
|||||||
state_changed.emit()
|
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:
|
func slot_grund(human_id: String, nr: int) -> String:
|
||||||
var r := slots(human_id)
|
var r := slots(human_id)
|
||||||
return str(r[nr][2]) if nr >= 0 and nr < r.size() else ""
|
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:
|
func traum_voranbringen(stunden: float) -> void:
|
||||||
if active_mission == "":
|
if active_mission == "":
|
||||||
return
|
return
|
||||||
|
if situation_bei(active_mission):
|
||||||
|
return # im Moment geht nichts voran
|
||||||
var p: float = progress.get(active_mission, 0.0) \
|
var p: float = progress.get(active_mission, 0.0) \
|
||||||
+ traum_tempo(active_mission) * stunden / 24.0
|
+ traum_tempo(active_mission) * stunden / 24.0
|
||||||
progress[active_mission] = minf(p, MISSION_ZIEL)
|
progress[active_mission] = minf(p, MISSION_ZIEL)
|
||||||
@@ -514,6 +538,151 @@ func traum_voranbringen(stunden: float) -> void:
|
|||||||
state_changed.emit()
|
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
|
# --------------------------------------------------- Erreichbarkeit
|
||||||
|
|
||||||
## Schlafende erreicht niemand.
|
## Schlafende erreicht niemand.
|
||||||
|
|||||||
@@ -391,6 +391,18 @@ static func _anker_setzen() -> void:
|
|||||||
ANKER[key] = int(NETZ.andocken(tuer)["knoten"])
|
ANKER[key] = int(NETZ.andocken(tuer)["knoten"])
|
||||||
|
|
||||||
|
|
||||||
|
## Was diesen Menschen nicht im Tagesablauf aufhält, sondern in Momenten.
|
||||||
|
## Ein bis zwei Probleme -- die zweite Ebene neben den Ursachen.
|
||||||
|
static func probleme_von(i: int) -> Array:
|
||||||
|
var alle: Array = Probleme.LISTE.keys()
|
||||||
|
var out: Array = [str(alle[i % alle.size()])]
|
||||||
|
if i % 2 == 1:
|
||||||
|
var zweites: String = str(alle[(i + 2) % alle.size()])
|
||||||
|
if zweites != out[0]:
|
||||||
|
out.append(zweites)
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
## Woran der Traum dieses Menschen scheitert. Zwei bis drei Ursachen, nie alle.
|
## Woran der Traum dieses Menschen scheitert. Zwei bis drei Ursachen, nie alle.
|
||||||
## Die erste hängt am Weg gleicher Nummer -- so ist der neueste Mensch immer
|
## Die erste hängt am Weg gleicher Nummer -- so ist der neueste Mensch immer
|
||||||
## mit dem neuesten Weg anzugehen.
|
## mit dem neuesten Weg anzugehen.
|
||||||
@@ -462,6 +474,7 @@ static func _mensch(i: int) -> Dictionary:
|
|||||||
"problem": str(anliegen["problem"]),
|
"problem": str(anliegen["problem"]),
|
||||||
"tags": (anliegen["tags"] as Array).duplicate(),
|
"tags": (anliegen["tags"] as Array).duplicate(),
|
||||||
"ursachen": ursachen_von(i),
|
"ursachen": ursachen_von(i),
|
||||||
|
"probleme": probleme_von(i),
|
||||||
"mission": true,
|
"mission": true,
|
||||||
"heim": heim,
|
"heim": heim,
|
||||||
"farbe": Color.from_hsv(fmod(0.02 + float(i) * 0.191, 1.0), 0.5, 0.8),
|
"farbe": Color.from_hsv(fmod(0.02 + float(i) * 0.191, 1.0), 0.5, 0.8),
|
||||||
@@ -495,15 +508,6 @@ static func _nachname(i: int) -> String:
|
|||||||
return str(NACHNAMEN[(i / VORNAMEN.size() + i) % NACHNAMEN.size()])
|
return str(NACHNAMEN[(i / VORNAMEN.size() + i) % NACHNAMEN.size()])
|
||||||
|
|
||||||
|
|
||||||
## Die Tätigkeiten eines Menschen in der Reihenfolge seines Tages, ohne Dopplung.
|
|
||||||
static func aktivitaeten(id: String) -> Array:
|
|
||||||
var out: Array = []
|
|
||||||
for e in by_id(id)["routine"]:
|
|
||||||
if not out.has(e[2]):
|
|
||||||
out.append(e[2])
|
|
||||||
return out
|
|
||||||
|
|
||||||
|
|
||||||
static func by_id(id: String) -> Dictionary:
|
static func by_id(id: String) -> Dictionary:
|
||||||
for h in LIST:
|
for h in LIST:
|
||||||
if h["id"] == id:
|
if h["id"] == id:
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ func _process(delta: float) -> void:
|
|||||||
ui.setze_hinweis("")
|
ui.setze_hinweis("")
|
||||||
return
|
return
|
||||||
Game.notiz_sperre = maxf(0.0, Game.notiz_sperre - delta)
|
Game.notiz_sperre = maxf(0.0, Game.notiz_sperre - delta)
|
||||||
|
Game.situationen_ticken(dt, auf_erde and not Game.schlaeft_ziel())
|
||||||
_fokus_suchen()
|
_fokus_suchen()
|
||||||
_dabeisein()
|
_dabeisein()
|
||||||
_hinweis_setzen()
|
_hinweis_setzen()
|
||||||
@@ -131,6 +132,9 @@ func _notiz_hinweis(mensch: Bewohner) -> String:
|
|||||||
var tat := Orte.text(mensch.activity)
|
var tat := Orte.text(mensch.activity)
|
||||||
if str(mensch.data["id"]) != Game.active_mission:
|
if str(mensch.data["id"]) != Game.active_mission:
|
||||||
return tat
|
return tat
|
||||||
|
if Game.situation_bei(str(mensch.data["id"])):
|
||||||
|
return "%s · [E] jetzt eine Technik" % \
|
||||||
|
Probleme.SITUATIONEN[Game.situation["key"]]["name"]
|
||||||
if Game.notiz_sperre > 0.0:
|
if Game.notiz_sperre > 0.0:
|
||||||
return "%s (%.0f s)" % [tat, Game.notiz_sperre]
|
return "%s (%.0f s)" % [tat, Game.notiz_sperre]
|
||||||
if Game.erkannt(str(mensch.data["id"]), int(mensch.slot)):
|
if Game.erkannt(str(mensch.data["id"]), int(mensch.slot)):
|
||||||
@@ -181,6 +185,8 @@ func _dabeisein() -> void:
|
|||||||
var id: String = str(_fokus_mensch.data["id"])
|
var id: String = str(_fokus_mensch.data["id"])
|
||||||
if id == Game.active_mission:
|
if id == Game.active_mission:
|
||||||
Game.sehen(id, int(_fokus_mensch.slot))
|
Game.sehen(id, int(_fokus_mensch.slot))
|
||||||
|
if Game.situation_bei(id):
|
||||||
|
Game.situation_sehen()
|
||||||
|
|
||||||
|
|
||||||
## Den Moment benennen: hier läuft etwas schief. Das ist der Kern des
|
## Den Moment benennen: hier läuft etwas schief. Das ist der Kern des
|
||||||
@@ -227,7 +233,11 @@ func _verfolgen() -> void:
|
|||||||
|
|
||||||
func _interagieren() -> void:
|
func _interagieren() -> void:
|
||||||
if _fokus_mensch != null:
|
if _fokus_mensch != null:
|
||||||
ui.anwenden_panel(_fokus_mensch)
|
# Der offene Moment geht vor: er ist gleich wieder vorbei
|
||||||
|
if Game.situation_bei(str(_fokus_mensch.data["id"])):
|
||||||
|
ui.situation_panel(_fokus_mensch)
|
||||||
|
else:
|
||||||
|
ui.anwenden_panel(_fokus_mensch)
|
||||||
return
|
return
|
||||||
if _fokus == null:
|
if _fokus == null:
|
||||||
return
|
return
|
||||||
|
|||||||
102
scripts/probleme.gd
Normal file
102
scripts/probleme.gd
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
class_name Probleme
|
||||||
|
## Die zweite Ebene: was einen Menschen nicht im Tagesablauf aufhält, sondern
|
||||||
|
## in einzelnen Momenten. Eine Gewohnheit hat einen Platz im Tag -- ein
|
||||||
|
## psychisches Problem hat keinen. Es zeigt sich in Situationen, und die
|
||||||
|
## kommen, wann sie wollen.
|
||||||
|
##
|
||||||
|
## Darum die andere Mechanik: Gewohnheiten pflanzt man ein und sie laufen ohne
|
||||||
|
## dich weiter. Bei einer Situation musst du dabei sein und im Moment die
|
||||||
|
## Technik wählen, die zu diesem Problem passt.
|
||||||
|
|
||||||
|
static var LISTE: Dictionary = {
|
||||||
|
"angst": {
|
||||||
|
"name": "Angst", "kurz": "der Körper macht dicht, bevor der Kopf mitredet",
|
||||||
|
},
|
||||||
|
"selbstzweifel": {
|
||||||
|
"name": "Selbstzweifel", "kurz": "die innere Stimme redet es klein",
|
||||||
|
},
|
||||||
|
"stress": {
|
||||||
|
"name": "Stress", "kurz": "alles gleichzeitig, nichts zu Ende",
|
||||||
|
},
|
||||||
|
"ueberforderung": {
|
||||||
|
"name": "Überforderung", "kurz": "der Berg ist zu groß zum Ansehen",
|
||||||
|
},
|
||||||
|
"erschoepfung": {
|
||||||
|
"name": "Erschöpfung", "kurz": "der Akku ist leer, bevor der Tag anfängt",
|
||||||
|
},
|
||||||
|
"einsamkeit": {
|
||||||
|
"name": "Einsamkeit", "kurz": "hängt allein an dem, was zu zweit ginge",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
## Situationen: was im Moment sichtbar wird. Jede gehört zu einem Problem.
|
||||||
|
static var SITUATIONEN: Dictionary = {
|
||||||
|
"blackout": {
|
||||||
|
"name": "wird starr", "was": "Ihr wird schwarz vor Augen.",
|
||||||
|
"problem": "angst",
|
||||||
|
},
|
||||||
|
"aufschieben_angst": {
|
||||||
|
"name": "meldet sich ab", "was": "Sie sagt den Termin wieder ab.",
|
||||||
|
"problem": "angst",
|
||||||
|
},
|
||||||
|
"kleinreden": {
|
||||||
|
"name": "redet es klein", "was": "»Das kann doch jeder besser.«",
|
||||||
|
"problem": "selbstzweifel",
|
||||||
|
},
|
||||||
|
"vergleich": {
|
||||||
|
"name": "vergleicht sich", "was": "Sie sieht, was andere schaffen.",
|
||||||
|
"problem": "selbstzweifel",
|
||||||
|
},
|
||||||
|
"alles_gleichzeitig": {
|
||||||
|
"name": "fängt drei Dinge an", "was": "Alles gleichzeitig, nichts zu Ende.",
|
||||||
|
"problem": "stress",
|
||||||
|
},
|
||||||
|
"noch_ein_ja": {
|
||||||
|
"name": "sagt schon wieder ja", "was": "Noch eine Bitte, noch ein Ja.",
|
||||||
|
"problem": "stress",
|
||||||
|
},
|
||||||
|
"erstarrt": {
|
||||||
|
"name": "erstarrt vor dem Berg", "was": "Sie sieht die Aufgabe und macht nichts.",
|
||||||
|
"problem": "ueberforderung",
|
||||||
|
},
|
||||||
|
"ausgebrannt": {
|
||||||
|
"name": "sackt zusammen", "was": "Sie sitzt da und starrt.",
|
||||||
|
"problem": "erschoepfung",
|
||||||
|
},
|
||||||
|
"allein": {
|
||||||
|
"name": "hängt allein fest", "was": "Sie kommt nicht weiter und fragt niemanden.",
|
||||||
|
"problem": "einsamkeit",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static func problem_da(schluessel: String) -> bool:
|
||||||
|
return LISTE.has(schluessel)
|
||||||
|
|
||||||
|
|
||||||
|
static func name_von(schluessel: String) -> String:
|
||||||
|
return str(LISTE[schluessel]["name"]) if LISTE.has(schluessel) else schluessel
|
||||||
|
|
||||||
|
|
||||||
|
## Alle Situationen, in denen sich dieses Problem zeigt.
|
||||||
|
static func situationen_von(problem: String) -> Array:
|
||||||
|
var out: Array = []
|
||||||
|
for key in SITUATIONEN:
|
||||||
|
if SITUATIONEN[key]["problem"] == problem:
|
||||||
|
out.append(key)
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
## Techniken, die gegen dieses Problem etwas ausrichten -- erkennbar am Feld
|
||||||
|
## `tags` der Technik.
|
||||||
|
static func techniken_gegen(problem: String) -> Array:
|
||||||
|
var out: Array = []
|
||||||
|
for t in TechDB.LIST:
|
||||||
|
if (t["tags"] as Array).has(problem):
|
||||||
|
out.append(str(t["id"]))
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
static func hilft(tech_id: String, problem: String) -> bool:
|
||||||
|
var t := TechDB.by_id(tech_id)
|
||||||
|
return not t.is_empty() and (t["tags"] as Array).has(problem)
|
||||||
1
scripts/probleme.gd.uid
Normal file
1
scripts/probleme.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://cchkx60v1a0e2
|
||||||
@@ -14,7 +14,6 @@ static var LIST: Array = [
|
|||||||
"belohnung": "erfolg",
|
"belohnung": "erfolg",
|
||||||
"ersatz": "arbeitet in Blöcken",
|
"ersatz": "arbeitet in Blöcken",
|
||||||
"tags": ["prokrastination", "fokus"],
|
"tags": ["prokrastination", "fokus"],
|
||||||
"momente": ["arbeitet", "zoegert"],
|
|
||||||
"farbe": Color(0.95, 0.45, 0.30),
|
"farbe": Color(0.95, 0.45, 0.30),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -28,7 +27,6 @@ static var LIST: Array = [
|
|||||||
"belohnung": "erfolg",
|
"belohnung": "erfolg",
|
||||||
"ersatz": "fängt zwei Minuten an",
|
"ersatz": "fängt zwei Minuten an",
|
||||||
"tags": ["prokrastination", "ueberforderung"],
|
"tags": ["prokrastination", "ueberforderung"],
|
||||||
"momente": ["zoegert", "aufraeumen", "arbeitet"],
|
|
||||||
"farbe": Color(0.98, 0.72, 0.25),
|
"farbe": Color(0.98, 0.72, 0.25),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -42,7 +40,6 @@ static var LIST: Array = [
|
|||||||
"belohnung": "ordnung",
|
"belohnung": "ordnung",
|
||||||
"ersatz": "folgt dem Wenn-Dann-Plan",
|
"ersatz": "folgt dem Wenn-Dann-Plan",
|
||||||
"tags": ["gewohnheit", "prokrastination"],
|
"tags": ["gewohnheit", "prokrastination"],
|
||||||
"momente": ["morgenroutine", "pause"],
|
|
||||||
"farbe": Color(0.45, 0.80, 0.55),
|
"farbe": Color(0.45, 0.80, 0.55),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -56,7 +53,6 @@ static var LIST: Array = [
|
|||||||
"belohnung": "ordnung",
|
"belohnung": "ordnung",
|
||||||
"ersatz": "hängt es an die Routine",
|
"ersatz": "hängt es an die Routine",
|
||||||
"tags": ["gewohnheit"],
|
"tags": ["gewohnheit"],
|
||||||
"momente": ["morgenroutine", "essen", "abendroutine"],
|
|
||||||
"farbe": Color(0.40, 0.70, 0.85),
|
"farbe": Color(0.40, 0.70, 0.85),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -70,7 +66,6 @@ static var LIST: Array = [
|
|||||||
"belohnung": "ordnung",
|
"belohnung": "ordnung",
|
||||||
"ersatz": "zerlegt die Aufgabe",
|
"ersatz": "zerlegt die Aufgabe",
|
||||||
"tags": ["ueberforderung", "prokrastination", "ziel"],
|
"tags": ["ueberforderung", "prokrastination", "ziel"],
|
||||||
"momente": ["gruebelt", "arbeitet"],
|
|
||||||
"farbe": Color(0.75, 0.55, 0.95),
|
"farbe": Color(0.75, 0.55, 0.95),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -84,7 +79,6 @@ static var LIST: Array = [
|
|||||||
"belohnung": "",
|
"belohnung": "",
|
||||||
"ersatz": "hat es sich leicht gemacht",
|
"ersatz": "hat es sich leicht gemacht",
|
||||||
"tags": ["ablenkung", "gewohnheit"],
|
"tags": ["ablenkung", "gewohnheit"],
|
||||||
"momente": ["aufraeumen", "arbeitet", "ruht"],
|
|
||||||
"farbe": Color(0.55, 0.85, 0.40),
|
"farbe": Color(0.55, 0.85, 0.40),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -98,7 +92,6 @@ static var LIST: Array = [
|
|||||||
"belohnung": "einordnung",
|
"belohnung": "einordnung",
|
||||||
"ersatz": "deutet den Gedanken um",
|
"ersatz": "deutet den Gedanken um",
|
||||||
"tags": ["selbstzweifel", "angst"],
|
"tags": ["selbstzweifel", "angst"],
|
||||||
"momente": ["gruebelt", "ruht", "angespannt"],
|
|
||||||
"farbe": Color(0.95, 0.55, 0.75),
|
"farbe": Color(0.95, 0.55, 0.75),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -112,7 +105,6 @@ static var LIST: Array = [
|
|||||||
"belohnung": "abschalten",
|
"belohnung": "abschalten",
|
||||||
"ersatz": "atmet sich ruhig",
|
"ersatz": "atmet sich ruhig",
|
||||||
"tags": ["angst", "stress"],
|
"tags": ["angst", "stress"],
|
||||||
"momente": ["angespannt", "wartet", "pause"],
|
|
||||||
"farbe": Color(0.40, 0.85, 0.95),
|
"farbe": Color(0.40, 0.85, 0.95),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -126,7 +118,6 @@ static var LIST: Array = [
|
|||||||
"belohnung": "verbundenheit",
|
"belohnung": "verbundenheit",
|
||||||
"ersatz": "ist freundlich mit sich",
|
"ersatz": "ist freundlich mit sich",
|
||||||
"tags": ["selbstzweifel", "rueckschlag"],
|
"tags": ["selbstzweifel", "rueckschlag"],
|
||||||
"momente": ["gruebelt", "ruht", "angespannt"],
|
|
||||||
"farbe": Color(1.0, 0.80, 0.60),
|
"farbe": Color(1.0, 0.80, 0.60),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -140,7 +131,6 @@ static var LIST: Array = [
|
|||||||
"belohnung": "zeit_fuer_sich",
|
"belohnung": "zeit_fuer_sich",
|
||||||
"ersatz": "hält das Schlaffenster",
|
"ersatz": "hält das Schlaffenster",
|
||||||
"tags": ["erschoepfung", "gesundheit"],
|
"tags": ["erschoepfung", "gesundheit"],
|
||||||
"momente": ["abendroutine", "muede", "ruht"],
|
|
||||||
"farbe": Color(0.45, 0.50, 0.90),
|
"farbe": Color(0.45, 0.50, 0.90),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -154,7 +144,6 @@ static var LIST: Array = [
|
|||||||
"belohnung": "anschluss",
|
"belohnung": "anschluss",
|
||||||
"ersatz": "bittet um Hilfe",
|
"ersatz": "bittet um Hilfe",
|
||||||
"tags": ["einsamkeit", "ueberforderung"],
|
"tags": ["einsamkeit", "ueberforderung"],
|
||||||
"momente": ["wartet", "pause", "unterwegs"],
|
|
||||||
"farbe": Color(0.90, 0.90, 0.45),
|
"farbe": Color(0.90, 0.90, 0.45),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -168,7 +157,6 @@ static var LIST: Array = [
|
|||||||
"belohnung": "anerkennung",
|
"belohnung": "anerkennung",
|
||||||
"ersatz": "sagt Nein mit Alternative",
|
"ersatz": "sagt Nein mit Alternative",
|
||||||
"tags": ["stress", "grenzen"],
|
"tags": ["stress", "grenzen"],
|
||||||
"momente": ["arbeitet", "angespannt", "unterwegs"],
|
|
||||||
"farbe": Color(0.85, 0.35, 0.45),
|
"farbe": Color(0.85, 0.35, 0.45),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|||||||
149
scripts/ui.gd
149
scripts/ui.gd
@@ -16,6 +16,8 @@ var _ablauf: HBoxContainer
|
|||||||
var _ablauf_titel: Label
|
var _ablauf_titel: Label
|
||||||
var _ablauf_jetzt: Label
|
var _ablauf_jetzt: Label
|
||||||
var _ablauf_grund: ColorRect
|
var _ablauf_grund: ColorRect
|
||||||
|
var _probleme: RichTextLabel
|
||||||
|
var _probleme_grund: ColorRect
|
||||||
var _zellen: Array = []
|
var _zellen: Array = []
|
||||||
var _ticks: Array = []
|
var _ticks: Array = []
|
||||||
var _dim: ColorRect
|
var _dim: ColorRect
|
||||||
@@ -27,7 +29,6 @@ var _apply_human: Node3D
|
|||||||
var _journal_seite := "techniken"
|
var _journal_seite := "techniken"
|
||||||
var _scroll_wunsch := 0
|
var _scroll_wunsch := 0
|
||||||
var _scroll_frames := 0
|
var _scroll_frames := 0
|
||||||
var _on_travel: Callable
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
@@ -54,6 +55,7 @@ func _baue_hud() -> void:
|
|||||||
add_child(_hud)
|
add_child(_hud)
|
||||||
|
|
||||||
_baue_ablauf()
|
_baue_ablauf()
|
||||||
|
_baue_probleme()
|
||||||
|
|
||||||
var steuerung := Label.new()
|
var steuerung := Label.new()
|
||||||
steuerung.text = "WASD Bewegen · Maus Umsehen · E Interagieren · F Folgen · " + \
|
steuerung.text = "WASD Bewegen · Maus Umsehen · E Interagieren · F Folgen · " + \
|
||||||
@@ -151,16 +153,17 @@ func _baue_ablauf() -> void:
|
|||||||
|
|
||||||
## Farbe je Stunde: unbekannt, gesehen, ungeklärt, benannt, gebaut.
|
## Farbe je Stunde: unbekannt, gesehen, ungeklärt, benannt, gebaut.
|
||||||
func _ablauf_farbe(human_id: String, nr: int) -> Color:
|
func _ablauf_farbe(human_id: String, nr: int) -> Color:
|
||||||
if not Game.gesehen_slot(human_id, nr):
|
match Game.slot_zustand(human_id, nr):
|
||||||
return Color(0.22, 0.23, 0.30)
|
Game.Stunde.UNBEKANNT:
|
||||||
if not Game.system_in(human_id, nr).is_empty():
|
return Color(0.22, 0.23, 0.30)
|
||||||
return Color(0.44, 0.78, 0.50)
|
Game.Stunde.GEBAUT:
|
||||||
var grund := Game.slot_grund(human_id, nr)
|
return Color(0.44, 0.78, 0.50)
|
||||||
if Ursachen.ist_blocker(grund):
|
Game.Stunde.UNGEKLAERT:
|
||||||
return Color(0.85, 0.66, 0.32) if not Game.erkannt(human_id, nr) \
|
return Color(0.85, 0.66, 0.32)
|
||||||
else Color(0.84, 0.42, 0.35)
|
Game.Stunde.BENANNT:
|
||||||
if grund == "schlaeft":
|
return Color(0.84, 0.42, 0.35)
|
||||||
return Color(0.30, 0.33, 0.44)
|
Game.Stunde.SCHLAF:
|
||||||
|
return Color(0.30, 0.33, 0.44)
|
||||||
return Color(0.46, 0.50, 0.62)
|
return Color(0.46, 0.50, 0.62)
|
||||||
|
|
||||||
|
|
||||||
@@ -193,6 +196,60 @@ func _ablauf_aktualisieren() -> void:
|
|||||||
_ablauf_jetzt.text = "%02d Uhr %s" % [jetzt, _stunden_text(id, nr_jetzt)]
|
_ablauf_jetzt.text = "%02d Uhr %s" % [jetzt, _stunden_text(id, nr_jetzt)]
|
||||||
|
|
||||||
|
|
||||||
|
## Die zweite Ebene im HUD: bekannte Probleme und der offene Moment.
|
||||||
|
## Bewusst anders gezeichnet als der Tagesstreifen -- sie hängt nicht an Stunden.
|
||||||
|
func _baue_probleme() -> void:
|
||||||
|
_probleme_grund = ColorRect.new()
|
||||||
|
_probleme_grund.color = Color(0, 0, 0, 0.42)
|
||||||
|
_probleme_grund.set_anchors_preset(Control.PRESET_TOP_LEFT)
|
||||||
|
_probleme_grund.position = Vector2(ABLAUF_X - 8.0, ABLAUF_Y + 88.0)
|
||||||
|
_probleme_grund.custom_minimum_size = Vector2(414.0, 74.0)
|
||||||
|
_probleme_grund.size = _probleme_grund.custom_minimum_size
|
||||||
|
_probleme_grund.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||||
|
add_child(_probleme_grund)
|
||||||
|
|
||||||
|
_probleme = RichTextLabel.new()
|
||||||
|
_probleme.bbcode_enabled = true
|
||||||
|
_probleme.fit_content = true
|
||||||
|
_probleme.scroll_active = false
|
||||||
|
_probleme.set_anchors_preset(Control.PRESET_TOP_LEFT)
|
||||||
|
_probleme.position = Vector2(ABLAUF_X, ABLAUF_Y + 94.0)
|
||||||
|
_probleme.custom_minimum_size = Vector2(400, 64)
|
||||||
|
_probleme.size = Vector2(400, 64)
|
||||||
|
_probleme.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||||
|
_probleme.add_theme_font_size_override("normal_font_size", 14)
|
||||||
|
_probleme.add_theme_font_size_override("bold_font_size", 14)
|
||||||
|
add_child(_probleme)
|
||||||
|
|
||||||
|
|
||||||
|
func _probleme_aktualisieren() -> void:
|
||||||
|
var id := Game.active_mission
|
||||||
|
var an := id != ""
|
||||||
|
_probleme.visible = an
|
||||||
|
_probleme_grund.visible = an
|
||||||
|
if not an:
|
||||||
|
return
|
||||||
|
var zeilen: Array = []
|
||||||
|
if Game.situation_laeuft() and Game.situation_bei(id):
|
||||||
|
var s: Dictionary = Probleme.SITUATIONEN[Game.situation["key"]]
|
||||||
|
zeilen.append("[color=#ffcc66][b]Jetzt: %s[/b][/color] %s [b]%.0f s[/b]" %
|
||||||
|
[s["name"], s["was"], float(Game.situation["rest"])])
|
||||||
|
else:
|
||||||
|
zeilen.append("[color=#8e93a8]Ihre Momente[/color]")
|
||||||
|
var bekannt: Array = []
|
||||||
|
for p in Game.probleme_von(id):
|
||||||
|
var key := str(p)
|
||||||
|
if not Game.problem_bekannt(id, key):
|
||||||
|
bekannt.append("[color=#55596b]?[/color]")
|
||||||
|
elif Game.problem_ueberwunden(id, key):
|
||||||
|
bekannt.append("[color=#88ff99]%s ✓[/color]" % Probleme.name_von(key))
|
||||||
|
else:
|
||||||
|
bekannt.append("[color=#ffb0a0]%s %d/%d[/color]" % [Probleme.name_von(key),
|
||||||
|
Game.problem_fortschritt(id, key), Game.PROBLEM_UEBERWINDEN])
|
||||||
|
zeilen.append(" · ".join(bekannt))
|
||||||
|
_probleme.text = "\n".join(zeilen)
|
||||||
|
|
||||||
|
|
||||||
func _baue_panel() -> void:
|
func _baue_panel() -> void:
|
||||||
_dim = ColorRect.new()
|
_dim = ColorRect.new()
|
||||||
_dim.color = Color(0, 0, 0, 0.62)
|
_dim.color = Color(0, 0, 0, 0.62)
|
||||||
@@ -278,6 +335,7 @@ func _hud_aktualisieren() -> void:
|
|||||||
zeilen.append("[color=#aaaaaa]Keine Mission. Schwarzes Brett am Dorfplatz.[/color]")
|
zeilen.append("[color=#aaaaaa]Keine Mission. Schwarzes Brett am Dorfplatz.[/color]")
|
||||||
_hud.text = "\n".join(zeilen)
|
_hud.text = "\n".join(zeilen)
|
||||||
_ablauf_aktualisieren()
|
_ablauf_aktualisieren()
|
||||||
|
_probleme_aktualisieren()
|
||||||
|
|
||||||
|
|
||||||
func setze_hinweis(text: String) -> void:
|
func setze_hinweis(text: String) -> void:
|
||||||
@@ -531,18 +589,19 @@ func _tagesablauf(human_id: String) -> void:
|
|||||||
|
|
||||||
|
|
||||||
func _stunden_text(human_id: String, nr: int) -> String:
|
func _stunden_text(human_id: String, nr: int) -> String:
|
||||||
if not Game.gesehen_slot(human_id, nr):
|
|
||||||
return "—"
|
|
||||||
var sys := Game.system_in(human_id, nr)
|
|
||||||
if not sys.is_empty():
|
|
||||||
return "%s ← %s" % [Game.slot_aktivitaet(human_id, nr),
|
|
||||||
TechDB.by_id(str(sys["tech"]))["name"]]
|
|
||||||
var grund := Game.slot_grund(human_id, nr)
|
var grund := Game.slot_grund(human_id, nr)
|
||||||
if not Game.erkannt(human_id, nr):
|
match Game.slot_zustand(human_id, nr):
|
||||||
return "?"
|
Game.Stunde.UNBEKANNT:
|
||||||
if Ursachen.ist_blocker(grund):
|
return "—"
|
||||||
return "%s (%s)" % [Ursachen.BLOCKER[grund]["name"],
|
Game.Stunde.GEBAUT:
|
||||||
Ursachen.LISTE[Ursachen.BLOCKER[grund]["ursache"]]["name"]]
|
var sys := Game.system_in(human_id, nr)
|
||||||
|
return "%s ← %s" % [Game.slot_aktivitaet(human_id, nr),
|
||||||
|
TechDB.by_id(str(sys["tech"]))["name"]]
|
||||||
|
Game.Stunde.UNGEKLAERT:
|
||||||
|
return "?"
|
||||||
|
Game.Stunde.BENANNT:
|
||||||
|
return "%s (%s)" % [Ursachen.BLOCKER[grund]["name"],
|
||||||
|
Ursachen.LISTE[Ursachen.BLOCKER[grund]["ursache"]]["name"]]
|
||||||
return Orte.text(grund)
|
return Orte.text(grund)
|
||||||
|
|
||||||
|
|
||||||
@@ -554,6 +613,49 @@ func _stunden_zeile(human_id: String, nr: int, von: int, bis: int, text: String)
|
|||||||
func() -> void: slot_panel(human_id, nr), offen)
|
func() -> void: slot_panel(human_id, nr), offen)
|
||||||
|
|
||||||
|
|
||||||
|
## Der offene Moment: hier zählt, welche Technik zu diesem Problem passt.
|
||||||
|
func situation_panel(mensch: Node3D) -> void:
|
||||||
|
_apply_human = mensch
|
||||||
|
var id: String = str(mensch.data["id"])
|
||||||
|
if not Game.situation_bei(id):
|
||||||
|
anwenden_panel(mensch)
|
||||||
|
return
|
||||||
|
var s: Dictionary = Probleme.SITUATIONEN[Game.situation["key"]]
|
||||||
|
var problem := Game.situation_problem()
|
||||||
|
_leeren("%s — %s" % [mensch.data["name"], s["name"]])
|
||||||
|
_text("[i]%s[/i]" % s["was"], 16)
|
||||||
|
if Game.problem_bekannt(id, problem):
|
||||||
|
_text("Dahinter steckt [b]%s[/b] — %s." %
|
||||||
|
[Probleme.name_von(problem), Probleme.LISTE[problem]["kurz"]], 15)
|
||||||
|
_text("[color=#aaaaaa]Überwunden nach %d von %d Malen.[/color]" %
|
||||||
|
[Game.problem_fortschritt(id, problem), Game.PROBLEM_UEBERWINDEN], 14)
|
||||||
|
else:
|
||||||
|
_text("[color=#ffcc66]Was dahintersteckt, weißt du noch nicht.[/color]", 15)
|
||||||
|
_text("[color=#aaaaaa]Noch %.0f Sekunden. Solange kommt ihr Traum nicht voran.[/color]" %
|
||||||
|
float(Game.situation["rest"]), 14)
|
||||||
|
_trenner()
|
||||||
|
if Game.known.is_empty():
|
||||||
|
_text("[color=#ffcc66]Du kennst keine Technik.[/color]", 16)
|
||||||
|
_zeigen("situation")
|
||||||
|
return
|
||||||
|
for tech_id in TechDB.ids():
|
||||||
|
if not Game.knows(tech_id):
|
||||||
|
continue
|
||||||
|
var t := TechDB.by_id(tech_id)
|
||||||
|
var wofuer: Array = []
|
||||||
|
for tag in t["tags"]:
|
||||||
|
wofuer.append(Probleme.name_von(str(tag)))
|
||||||
|
_text("[b]%s[/b] · Stufe %d\n[color=#cccccc]%s[/color]\n[color=#9fb6ff]Hilft bei:[/color] %s" %
|
||||||
|
[t["name"], Game.skill_of(tech_id), t["wann"], ", ".join(wofuer)], 15)
|
||||||
|
var frei := Game.bereit(tech_id)
|
||||||
|
var text := "Jetzt anwenden" if frei else "Noch %.0f s" % Game.cooldown_rest(tech_id)
|
||||||
|
_knopf(text, func() -> void:
|
||||||
|
Game.situation_anwenden(tech_id)
|
||||||
|
schliessen(), frei)
|
||||||
|
_trenner()
|
||||||
|
_zeigen("situation")
|
||||||
|
|
||||||
|
|
||||||
## Was soll in diesem Slot stehen?
|
## Was soll in diesem Slot stehen?
|
||||||
func slot_panel(human_id: String, nr: int) -> void:
|
func slot_panel(human_id: String, nr: int) -> void:
|
||||||
var h := HumanDB.by_id(human_id)
|
var h := HumanDB.by_id(human_id)
|
||||||
@@ -664,13 +766,14 @@ func brett_panel() -> void:
|
|||||||
_text("Ausgehängt wird nur, wem du mit dem, was du kannst, auch helfen kannst. " +
|
_text("Ausgehängt wird nur, wem du mit dem, was du kannst, auch helfen kannst. " +
|
||||||
"Das Tor zur Erde öffnet sich nur mit einer Mission.", 15)
|
"Das Tor zur Erde öffnet sich nur mit einer Mission.", 15)
|
||||||
_trenner()
|
_trenner()
|
||||||
|
var offen := Game.offene_missionen()
|
||||||
var gezeigt := 0
|
var gezeigt := 0
|
||||||
var verdeckt := 0
|
var verdeckt := 0
|
||||||
for h in HumanDB.LIST:
|
for h in HumanDB.LIST:
|
||||||
var id: String = h["id"]
|
var id: String = h["id"]
|
||||||
if Game.completed.has(id):
|
if Game.completed.has(id):
|
||||||
continue
|
continue
|
||||||
if Game.active_mission != id and not Game.machbar(id):
|
if not offen.has(id):
|
||||||
verdeckt += 1
|
verdeckt += 1
|
||||||
continue
|
continue
|
||||||
gezeigt += 1
|
gezeigt += 1
|
||||||
|
|||||||
@@ -13,27 +13,22 @@ class_name Ursachen
|
|||||||
static var LISTE: Dictionary = {
|
static var LISTE: Dictionary = {
|
||||||
"anfang": {
|
"anfang": {
|
||||||
"name": "Kein Anfang", "kurz": "kommt nie in Gang",
|
"name": "Kein Anfang", "kurz": "kommt nie in Gang",
|
||||||
"symptom": "Sie setzt sich hin und tut dann etwas anderes.",
|
|
||||||
"faktor": 0.30,
|
"faktor": 0.30,
|
||||||
},
|
},
|
||||||
"zeit": {
|
"zeit": {
|
||||||
"name": "Keine Zeit", "kurz": "der Tag ist voll",
|
"name": "Keine Zeit", "kurz": "der Tag ist voll",
|
||||||
"symptom": "Der Tag ist voll mit dem, was andere wollen.",
|
|
||||||
"faktor": 0.30,
|
"faktor": 0.30,
|
||||||
},
|
},
|
||||||
"kraft": {
|
"kraft": {
|
||||||
"name": "Keine Kraft", "kurz": "abends ist nichts mehr übrig",
|
"name": "Keine Kraft", "kurz": "abends ist nichts mehr übrig",
|
||||||
"symptom": "Am Abend reicht es nur noch für Berieselung.",
|
|
||||||
"faktor": 0.40,
|
"faktor": 0.40,
|
||||||
},
|
},
|
||||||
"halt": {
|
"halt": {
|
||||||
"name": "Kein Halt", "kurz": "fängt an und hört wieder auf",
|
"name": "Kein Halt", "kurz": "fängt an und hört wieder auf",
|
||||||
"symptom": "Angefangen wird oft, drangeblieben selten.",
|
|
||||||
"faktor": 0.50,
|
"faktor": 0.50,
|
||||||
},
|
},
|
||||||
"grund": {
|
"grund": {
|
||||||
"name": "Kein Grund", "kurz": "glaubt nicht mehr daran",
|
"name": "Kein Grund", "kurz": "glaubt nicht mehr daran",
|
||||||
"symptom": "Sie redet sich das Vorhaben selbst klein.",
|
|
||||||
"faktor": 0.40,
|
"faktor": 0.40,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
160
tests/verify.gd
160
tests/verify.gd
@@ -40,6 +40,7 @@ func _ready() -> void:
|
|||||||
await test_notieren_im_spiel()
|
await test_notieren_im_spiel()
|
||||||
await test_tagesablauf_anzeige()
|
await test_tagesablauf_anzeige()
|
||||||
await test_ablauf_im_hud()
|
await test_ablauf_im_hud()
|
||||||
|
await test_probleme_und_momente()
|
||||||
await test_systeme()
|
await test_systeme()
|
||||||
await test_tempo_des_traums()
|
await test_tempo_des_traums()
|
||||||
await test_cooldown()
|
await test_cooldown()
|
||||||
@@ -878,6 +879,165 @@ func test_diagnose() -> void:
|
|||||||
|
|
||||||
|
|
||||||
## Gegen eine Ursache baut man ein System. Passt die Belohnung, hält es besser.
|
## Gegen eine Ursache baut man ein System. Passt die Belohnung, hält es besser.
|
||||||
|
## Die zweite Ebene: Probleme hängen nicht an Stunden, sondern an Momenten.
|
||||||
|
## Gewohnheiten laufen ohne dich weiter -- hier musst du dabei sein.
|
||||||
|
func test_probleme_und_momente() -> void:
|
||||||
|
abschnitt("Probleme zeigen sich in Momenten")
|
||||||
|
var id := "mensch_0"
|
||||||
|
Game.active_mission = id
|
||||||
|
Game.situation = {}
|
||||||
|
Game.situation_pause = 0.0
|
||||||
|
Game.probleme_bekannt.clear()
|
||||||
|
Game.problem_stand.clear()
|
||||||
|
Game.ueberwunden.clear()
|
||||||
|
Game.cooldown.clear()
|
||||||
|
ui().schliessen()
|
||||||
|
|
||||||
|
var prob: Array = Game.probleme_von(id)
|
||||||
|
p(prob.size() >= 1 and prob.size() <= 2,
|
||||||
|
"%s trägt %d Problem(e): %s" % [HumanDB.by_id(id)["name"], prob.size(), str(prob)])
|
||||||
|
var alle_bekannt := true
|
||||||
|
for x in prob:
|
||||||
|
if not Probleme.problem_da(str(x)):
|
||||||
|
alle_bekannt = false
|
||||||
|
p(alle_bekannt, "Alle stehen im Katalog")
|
||||||
|
var ohne_situation: Array = []
|
||||||
|
for x in Probleme.LISTE:
|
||||||
|
if Probleme.situationen_von(str(x)).is_empty():
|
||||||
|
ohne_situation.append(str(x))
|
||||||
|
p(ohne_situation.is_empty(), "Jedes Problem zeigt sich in Situationen%s" %
|
||||||
|
("" if ohne_situation.is_empty() else " — außer " + ", ".join(ohne_situation)))
|
||||||
|
var ohne_technik: Array = []
|
||||||
|
for x in Probleme.LISTE:
|
||||||
|
if Probleme.techniken_gegen(str(x)).is_empty():
|
||||||
|
ohne_technik.append(str(x))
|
||||||
|
p(ohne_technik.is_empty(), "Und gegen jedes gibt es Techniken%s" %
|
||||||
|
("" if ohne_technik.is_empty() else " — außer " + ", ".join(ohne_technik)))
|
||||||
|
|
||||||
|
# Sie kommt von allein, aber nicht sofort
|
||||||
|
p(not Game.situation_laeuft(), "Erst läuft kein Moment")
|
||||||
|
Game.situationen_ticken(1.0, false)
|
||||||
|
p(not Game.situation_laeuft(), "Bei einem Schlafenden kommt keiner")
|
||||||
|
Game.situationen_ticken(1.0, true)
|
||||||
|
p(Game.situation_laeuft(), "Bei einem wachen Menschen bricht einer auf")
|
||||||
|
var problem := Game.situation_problem()
|
||||||
|
p(prob.has(problem), "Und gehört zu einem seiner Probleme: %s" % problem)
|
||||||
|
|
||||||
|
# Solange sie läuft, steht der Traum still
|
||||||
|
Game.progress[id] = 10.0
|
||||||
|
Game.traum_voranbringen(6.0)
|
||||||
|
p(is_equal_approx(Game.mission_progress(id), 10.0),
|
||||||
|
"Im Moment kommt der Traum nicht voran (%.1f %%)" % Game.mission_progress(id))
|
||||||
|
|
||||||
|
# Dabeisein zeigt, was dahintersteckt
|
||||||
|
p(not Game.problem_bekannt(id, problem), "Was dahintersteckt, ist noch unbekannt")
|
||||||
|
Game.situation_sehen()
|
||||||
|
p(Game.problem_bekannt(id, problem), "Dabeisein zeigt es: %s" %
|
||||||
|
Probleme.name_von(problem))
|
||||||
|
|
||||||
|
# Eine unpassende Technik greift nicht
|
||||||
|
var passend := ""
|
||||||
|
var unpassend := ""
|
||||||
|
for tid in TechDB.ids():
|
||||||
|
if Probleme.hilft(tid, problem) and passend == "":
|
||||||
|
passend = tid
|
||||||
|
elif not Probleme.hilft(tid, problem) and unpassend == "":
|
||||||
|
unpassend = tid
|
||||||
|
Game.known[passend] = 0
|
||||||
|
Game.known[unpassend] = 0
|
||||||
|
var res_falsch := Game.situation_anwenden(unpassend)
|
||||||
|
p(res_falsch["ok"] and not res_falsch["treffer"],
|
||||||
|
"%s greift bei %s nicht" % [TechDB.by_id(unpassend)["name"],
|
||||||
|
Probleme.name_von(problem)])
|
||||||
|
p(Game.situation_laeuft(), "Der Moment läuft weiter")
|
||||||
|
|
||||||
|
# Die passende beendet ihn
|
||||||
|
var vorher: float = Game.mission_progress(id)
|
||||||
|
var res := Game.situation_anwenden(passend)
|
||||||
|
p(res["treffer"], "%s trägt hindurch" % TechDB.by_id(passend)["name"])
|
||||||
|
p(not Game.situation_laeuft(), "Der Moment ist vorbei")
|
||||||
|
p(Game.mission_progress(id) > vorher, "Und bringt den Traum voran (%.0f → %.0f %%)" %
|
||||||
|
[vorher, Game.mission_progress(id)])
|
||||||
|
p(Game.problem_fortschritt(id, problem) == 1, "Einmal geschafft")
|
||||||
|
|
||||||
|
# Oft genug, und das Problem kommt nicht wieder
|
||||||
|
for i in range(Game.PROBLEM_UEBERWINDEN):
|
||||||
|
Game.situation = {"mensch": id, "key": Probleme.situationen_von(problem)[0],
|
||||||
|
"problem": problem, "rest": Game.SITUATION_DAUER}
|
||||||
|
Game.cooldown.clear()
|
||||||
|
Game.situation_anwenden(passend)
|
||||||
|
p(Game.problem_ueberwunden(id, problem),
|
||||||
|
"Nach %d Malen ist %s überwunden" % [Game.PROBLEM_UEBERWINDEN,
|
||||||
|
Probleme.name_von(problem)])
|
||||||
|
Game.situation = {}
|
||||||
|
Game.situation_pause = 0.0
|
||||||
|
var kommt_wieder := false
|
||||||
|
for i in range(200):
|
||||||
|
Game.situationen_ticken(1.0, true)
|
||||||
|
if Game.situation_laeuft() and Game.situation_problem() == problem:
|
||||||
|
kommt_wieder = true
|
||||||
|
break
|
||||||
|
p(not kommt_wieder, "Dieser Moment kommt nicht wieder")
|
||||||
|
|
||||||
|
# Beide Ebenen stehen nebeneinander im HUD
|
||||||
|
Game.situation = {}
|
||||||
|
ui()._hud_aktualisieren()
|
||||||
|
p(ui()._ablauf.visible and ui()._probleme.visible,
|
||||||
|
"Tagesablauf und Momente stehen beide im HUD")
|
||||||
|
p(ui()._probleme.text.contains(Probleme.name_von(problem)),
|
||||||
|
"Die Momente nennen das Problem: %s" % ui()._probleme.text.replace("\n", " / "))
|
||||||
|
Game.situation = {"mensch": id, "key": Probleme.situationen_von(problem)[0],
|
||||||
|
"problem": problem, "rest": 9.0}
|
||||||
|
ui()._hud_aktualisieren()
|
||||||
|
p(ui()._probleme.text.contains("Jetzt:"), "Der laufende Moment steht oben")
|
||||||
|
|
||||||
|
# Und er kündigt sich am Menschen selbst an, nicht nur im HUD
|
||||||
|
var wer: Bewohner = null
|
||||||
|
for mm in welt().humans:
|
||||||
|
if mm.data["id"] == id:
|
||||||
|
wer = mm
|
||||||
|
p(wer.beschriftung().contains(str(Probleme.SITUATIONEN[Game.situation["key"]]["name"])),
|
||||||
|
"Am Menschen steht, was gerade aufbricht: %s" %
|
||||||
|
wer.beschriftung().replace("\n", " / "))
|
||||||
|
Game.situation = {}
|
||||||
|
p(not wer.beschriftung().contains("»"), "Ohne Moment steht dort nichts davon")
|
||||||
|
# E führt in den Moment, sonst in den Tagesablauf -- die zwei Ebenen
|
||||||
|
# teilen sich eine Taste, ohne sich in die Quere zu kommen
|
||||||
|
var mensch: Bewohner = null
|
||||||
|
for mm in welt().humans:
|
||||||
|
if mm.data["id"] == id:
|
||||||
|
mensch = mm
|
||||||
|
main.player.set_mode(Player.Mode.GEIST)
|
||||||
|
main.player.folgt = null
|
||||||
|
main.player.global_position = mensch.global_position + Vector3(0, 1.5, 1.5)
|
||||||
|
Game.situation = {}
|
||||||
|
main._process(0.05)
|
||||||
|
main._interagieren()
|
||||||
|
p(ui()._kind == "anwenden", "Ohne Moment führt E in den Tagesablauf (%s)" % ui()._kind)
|
||||||
|
ui().schliessen()
|
||||||
|
Game.situation = {"mensch": id, "key": Probleme.situationen_von(problem)[0],
|
||||||
|
"problem": problem, "rest": 12.0}
|
||||||
|
main._process(0.05)
|
||||||
|
main._interagieren()
|
||||||
|
p(ui()._kind == "situation", "Im Moment führt dieselbe Taste dorthin (%s)" % ui()._kind)
|
||||||
|
p(_panel_text().contains(str(Probleme.SITUATIONEN[Game.situation["key"]]["was"])),
|
||||||
|
"Das Panel zeigt, was gerade passiert")
|
||||||
|
ui().schliessen()
|
||||||
|
|
||||||
|
# Die Gewohnheitsebene läuft davon unberührt weiter
|
||||||
|
Game.situation = {}
|
||||||
|
Game.progress[id] = 0.0
|
||||||
|
Game.traum_voranbringen(24.0)
|
||||||
|
p(Game.mission_progress(id) > 0.0,
|
||||||
|
"Ohne Moment liefert der Tagesablauf wieder sein Tempo (%.0f %%)" %
|
||||||
|
Game.mission_progress(id))
|
||||||
|
|
||||||
|
Game.situation = {}
|
||||||
|
Game.ueberwunden.clear()
|
||||||
|
Game.probleme_bekannt.clear()
|
||||||
|
Game.problem_stand.clear()
|
||||||
|
|
||||||
|
|
||||||
## Der Ablauf steht auch im HUD, ohne dass man ein Panel öffnen muss.
|
## Der Ablauf steht auch im HUD, ohne dass man ein Panel öffnen muss.
|
||||||
func test_ablauf_im_hud() -> void:
|
func test_ablauf_im_hud() -> void:
|
||||||
abschnitt("Der Ablauf steht im HUD")
|
abschnitt("Der Ablauf steht im HUD")
|
||||||
|
|||||||
Reference in New Issue
Block a user