update
This commit is contained in:
185
scripts/ui.gd
185
scripts/ui.gd
@@ -6,6 +6,7 @@ class_name UI
|
||||
## der Mitte für Orte. Die Zeitleiste unten ist der Tag des Menschen -- alles
|
||||
## im Spiel hängt daran.
|
||||
|
||||
signal hinfahren(id: String)
|
||||
signal panel_opened
|
||||
signal panel_closed
|
||||
|
||||
@@ -25,8 +26,15 @@ const C_UNBEKANNT := Color(0.22, 0.23, 0.30)
|
||||
const C_GESEHEN := Color(0.46, 0.50, 0.62)
|
||||
const C_SCHLAF := Color(0.30, 0.33, 0.44)
|
||||
const C_WARN := Color(0.85, 0.66, 0.32)
|
||||
const C_VERDAECHTIG := Color(0.58, 0.46, 0.26) # Spur gelesen, Stunde noch nicht gesehen
|
||||
const C_BLOCKER := Color(0.84, 0.42, 0.35)
|
||||
const C_SYSTEM := Color(0.44, 0.78, 0.50)
|
||||
const C_PAPIER := Color(0.95, 0.92, 0.85) # die Akte: Papier, dunkle Tinte
|
||||
const C_PAPIER_ZEILE := Color(0.90, 0.86, 0.78)
|
||||
const TINTE := "#2b2620"
|
||||
const TINTE_HELL := "#6b6257"
|
||||
const TINTE_ROT := "#a83a2e"
|
||||
const TINTE_GRUEN := "#3d7a45"
|
||||
|
||||
var offen := false
|
||||
var _kind := ""
|
||||
@@ -299,6 +307,8 @@ func _ablauf_farbe(human_id: String, nr: int) -> Color:
|
||||
return C_BLOCKER
|
||||
Game.Stunde.SCHLAF:
|
||||
return C_SCHLAF
|
||||
Game.Stunde.VERDAECHTIG:
|
||||
return C_VERDAECHTIG
|
||||
return C_GESEHEN
|
||||
|
||||
|
||||
@@ -310,20 +320,24 @@ func _ablauf_aktualisieren() -> void:
|
||||
return
|
||||
var jetzt := int(Game.time_h)
|
||||
var offen_std := 0
|
||||
var verdaechtig := 0
|
||||
var puls := 0.5 + 0.5 * sin(Time.get_ticks_msec() * 0.008)
|
||||
for stunde in range(24):
|
||||
var nr := Game.slot_bei_stunde(id, stunde)
|
||||
var f := _ablauf_farbe(id, nr)
|
||||
if not Game.gesehen_slot(id, nr):
|
||||
offen_std += 1
|
||||
if Game.slot_zustand(id, nr) == Game.Stunde.VERDAECHTIG:
|
||||
verdaechtig += 1
|
||||
var zelle: ColorRect = _zellen[stunde]
|
||||
if stunde == jetzt:
|
||||
f = f.lightened(0.55 if not Game.situation_bei(id) else 0.3 + 0.4 * puls)
|
||||
zelle.color = f
|
||||
zelle.custom_minimum_size.y = 24 if stunde == jetzt else 16
|
||||
zelle.tooltip_text = "%02d Uhr — %s" % [stunde, _stunden_text(id, nr)]
|
||||
_ablauf_titel.text = "Ihr Tag 0 – 23 Uhr%s" % \
|
||||
("" if offen_std == 0 else " · %d Stunden unbekannt" % offen_std)
|
||||
_ablauf_titel.text = "Ihr Tag 0 – 23 Uhr%s%s" % [
|
||||
"" if offen_std == 0 else " · %d Stunden unbekannt" % offen_std,
|
||||
"" if verdaechtig == 0 else " · %d verdächtig" % verdaechtig]
|
||||
|
||||
var urs: Array = []
|
||||
for u in Game.ursachen_von(id):
|
||||
@@ -414,7 +428,7 @@ func _baue_wirte() -> void:
|
||||
|
||||
func _wirt_fuer(kind: String) -> PanelContainer:
|
||||
match kind:
|
||||
"journal", "technik", "systeme":
|
||||
"journal", "technik", "akte":
|
||||
return _drawer
|
||||
"slot", "situation", "anwenden":
|
||||
return _karte_host
|
||||
@@ -609,7 +623,7 @@ func _reiter() -> void:
|
||||
_content.add_child(hb)
|
||||
var seiten := [
|
||||
["techniken", "Techniken (%d)" % Game.known.size()],
|
||||
["missionen", "Missionen (%d)" % Game.progress.size()],
|
||||
["missionen", "Akten (%d)" % Game.progress.size()],
|
||||
]
|
||||
for eintrag in seiten:
|
||||
var b := Button.new()
|
||||
@@ -675,44 +689,145 @@ func _journal_missionen() -> void:
|
||||
stand = "aktiv · %d %%" % int(Game.mission_progress(id))
|
||||
farbe = C_AKZENT
|
||||
_karte("%s · %s" % [h["name"], stand], farbe,
|
||||
func() -> void: systeme_panel(id))
|
||||
func() -> void: akte_panel(id))
|
||||
|
||||
|
||||
# ---------------------------------------------- Diagnose und Systeme
|
||||
# ---------------------------------------------- Die Akte
|
||||
|
||||
## Alles zu einem Menschen auf einem Blatt: Person und Traum, was im Weg steht,
|
||||
## der Befund aus Spuren und Beobachtungen, der Tag, die Routinen, die Notizen.
|
||||
## Keine Patientenakte -- die Leute sind nicht krank, sie haben Gewohnheiten.
|
||||
var _blatt: VBoxContainer = null
|
||||
|
||||
|
||||
## Der Traum scheitert an Ursachen. Die stehen nicht im Panel -- man findet sie,
|
||||
## indem man dabeisteht. Gegen jede gefundene Ursache baut man ein System in
|
||||
## den Tag. Je mehr abgedeckt ist, desto schneller kommt der Traum voran.
|
||||
func systeme_panel(human_id: String) -> void:
|
||||
var scroll_alt := _scroll.scroll_vertical if offen and _kind == "systeme" else 0
|
||||
var h := HumanDB.by_id(human_id)
|
||||
_leeren("%s — Tagesablauf" % h["name"])
|
||||
_text("%d %% · +%d %% je Tag · [color=#aaaaaa]%s[/color]" %
|
||||
[int(Game.mission_progress(human_id)), int(round(Game.traum_tempo(human_id))),
|
||||
h["traum"]], 16)
|
||||
_trenner()
|
||||
akte_panel(human_id)
|
||||
|
||||
_text("[b]Woran es scheitert[/b]", 17)
|
||||
var offene := 0
|
||||
|
||||
func akte_panel(human_id: String) -> void:
|
||||
var scroll_alt := _scroll.scroll_vertical if offen and _kind == "akte" else 0
|
||||
var h := HumanDB.by_id(human_id)
|
||||
_leeren("Akte")
|
||||
_papier()
|
||||
var erfuellt := Game.completed.has(human_id)
|
||||
_akte_text("[b]%s[/b] [color=%s]%d · %s[/color]" % [h["name"], TINTE_HELL,
|
||||
int(h.get("alter", 0)), h.get("beruf", "")], 20)
|
||||
_akte_text("[color=%s]Traum[/color] „%s“" % [TINTE_HELL, h["traum"]], 16)
|
||||
if erfuellt:
|
||||
_stempel("TRAUM ERFÜLLT")
|
||||
else:
|
||||
_akte_text("[color=%s]Stand[/color] %d %% · +%d %% je Tag" % [TINTE_HELL,
|
||||
int(Game.mission_progress(human_id)), int(round(Game.traum_tempo(human_id)))], 16)
|
||||
_knopf("Hinfahren — vor die Tür", func() -> void:
|
||||
schliessen()
|
||||
hinfahren.emit(human_id), true, _blatt)
|
||||
|
||||
_akte_abschnitt("Was im Weg steht")
|
||||
_akte_text(str(h["problem"]), 15)
|
||||
|
||||
_akte_abschnitt("Befund")
|
||||
for u in Game.ursachen_von(human_id):
|
||||
var name: String = str(u)
|
||||
if not Game.ursache_bekannt(human_id, name):
|
||||
_text("[color=#8e93a8]? — noch nicht erkannt[/color]", 15)
|
||||
offene += 1
|
||||
var stand: String
|
||||
if Game.ursache_geloest(human_id, name) > 0.0:
|
||||
stand = "[color=%s]Routine steht[/color]" % TINTE_GRUEN
|
||||
elif Game.ursache_bekannt(human_id, name):
|
||||
var woher := "Spur gelesen" if Game.spur_bekannt(human_id, name) else "beobachtet"
|
||||
stand = "[color=%s]%s · bremst auf %d %%[/color]" % [TINTE_ROT, woher,
|
||||
int(float(Ursachen.LISTE[name]["faktor"]) * 100.0)]
|
||||
else:
|
||||
_akte_text("[color=%s]? noch nichts gefunden — Spuren in der Wohnung, Momente im Tag[/color]" %
|
||||
TINTE_HELL, 15)
|
||||
continue
|
||||
var g := Game.ursache_geloest(human_id, name)
|
||||
var stand := "[color=#88ff99]gelöst[/color]" if g > 0.0 else \
|
||||
"[color=#ff9977]offen · bremst auf %d %%[/color]" % \
|
||||
int(float(Ursachen.LISTE[name]["faktor"]) * 100.0)
|
||||
_text("[b]%s[/b] %s" % [Ursachen.LISTE[name]["name"], stand], 15)
|
||||
if offene > 0: _trenner()
|
||||
_akte_text("[b]%s[/b] %s" % [Ursachen.LISTE[name]["name"], stand], 15)
|
||||
var probleme: Array = []
|
||||
for pr in Game.probleme_von(human_id):
|
||||
var key := str(pr)
|
||||
if not Game.problem_bekannt(human_id, key):
|
||||
probleme.append("[color=%s]?[/color]" % TINTE_HELL)
|
||||
elif Game.problem_ueberwunden(human_id, key):
|
||||
probleme.append("[color=%s]%s ✓[/color]" % [TINTE_GRUEN, Probleme.name_von(key)])
|
||||
else:
|
||||
probleme.append("%s %d/%d" % [Probleme.name_von(key),
|
||||
Game.problem_fortschritt(human_id, key), Game.PROBLEM_UEBERWINDEN])
|
||||
if not probleme.is_empty():
|
||||
_akte_text("[color=%s]In Momenten[/color] %s" % [TINTE_HELL, " · ".join(probleme)], 15)
|
||||
|
||||
_akte_abschnitt("Tag")
|
||||
_tagesablauf(human_id)
|
||||
_zeigen("systeme", journal_panel.bind("missionen"))
|
||||
|
||||
_akte_abschnitt("Notizen")
|
||||
var zeilen: Array = Game.notizen.get(human_id, [])
|
||||
if zeilen.is_empty():
|
||||
_akte_text("[color=%s]noch keine[/color]" % TINTE_HELL, 14)
|
||||
for i in range(maxi(0, zeilen.size() - 8), zeilen.size()):
|
||||
_akte_text("[color=%s]%s[/color]" % [TINTE, zeilen[i]], 14)
|
||||
|
||||
_zeigen("akte", journal_panel.bind("missionen"))
|
||||
_scroll_wunsch = scroll_alt
|
||||
_scroll_frames = 4
|
||||
|
||||
|
||||
## Ein Blatt Papier im Drawer; alles Weitere der Akte landet darauf.
|
||||
func _papier() -> void:
|
||||
var p := PanelContainer.new()
|
||||
var s := _sb(C_PAPIER, 3, Color(0.78, 0.72, 0.6), 1)
|
||||
s.content_margin_left = 16
|
||||
s.content_margin_right = 16
|
||||
s.content_margin_top = 12
|
||||
s.content_margin_bottom = 14
|
||||
p.add_theme_stylebox_override("panel", s)
|
||||
_content.add_child(p)
|
||||
_blatt = VBoxContainer.new()
|
||||
_blatt.add_theme_constant_override("separation", 6)
|
||||
p.add_child(_blatt)
|
||||
|
||||
|
||||
func _akte_text(bb: String, groesse: int = 15) -> RichTextLabel:
|
||||
var r := _text("[color=%s]%s[/color]" % [TINTE, bb], groesse, _blatt)
|
||||
return r
|
||||
|
||||
|
||||
func _akte_abschnitt(titel: String) -> void:
|
||||
var r := _text("[color=%s]%s[/color]" % [TINTE_HELL, titel.to_upper()], 12, _blatt)
|
||||
r.add_theme_constant_override("line_separation", 2)
|
||||
var linie := HSeparator.new()
|
||||
linie.add_theme_stylebox_override("separator", _sb(Color(0.78, 0.72, 0.6, 0.6), 0))
|
||||
linie.custom_minimum_size.y = 2
|
||||
_blatt.add_child(linie)
|
||||
|
||||
|
||||
func _stempel(text: String) -> void:
|
||||
var l := Label.new()
|
||||
l.text = text
|
||||
l.add_theme_font_size_override("font_size", 18)
|
||||
l.add_theme_color_override("font_color", Color(0.66, 0.2, 0.15))
|
||||
l.add_theme_stylebox_override("normal", _sb(Color(0, 0, 0, 0), 2, Color(0.66, 0.2, 0.15), 2))
|
||||
l.rotation_degrees = -4.0
|
||||
_blatt.add_child(l)
|
||||
|
||||
|
||||
## Eine Zeile der Akte, die sich aufschlagen lässt (Stunden des Tages).
|
||||
func _akte_karte(beschriftung: String, farbe: Color, cb: Callable, aktiv: bool = true) -> Button:
|
||||
var b := Button.new()
|
||||
b.text = beschriftung
|
||||
b.alignment = HORIZONTAL_ALIGNMENT_LEFT
|
||||
b.disabled = not aktiv
|
||||
b.custom_minimum_size = Vector2(0, 30)
|
||||
b.add_theme_font_size_override("font_size", 14)
|
||||
b.add_theme_color_override("font_color", Color(0.17, 0.15, 0.13))
|
||||
b.add_theme_color_override("font_hover_color", Color(0.1, 0.08, 0.06))
|
||||
b.add_theme_color_override("font_disabled_color", Color(0.3, 0.27, 0.24))
|
||||
b.add_theme_stylebox_override("normal", _sb(C_PAPIER_ZEILE, 3, farbe, 0, 4))
|
||||
b.add_theme_stylebox_override("hover", _sb(C_PAPIER_ZEILE.darkened(0.06), 3, farbe, 0, 4))
|
||||
b.add_theme_stylebox_override("pressed", _sb(C_PAPIER_ZEILE.darkened(0.1), 3, farbe, 0, 4))
|
||||
b.add_theme_stylebox_override("disabled", _sb(C_PAPIER_ZEILE, 3, farbe.darkened(0.2), 0, 4))
|
||||
_blatt.add_child(b)
|
||||
if aktiv:
|
||||
b.pressed.connect(cb)
|
||||
return b
|
||||
|
||||
|
||||
## Der Ablauf von 0 bis 23 Uhr. Jeder Tag ist gleich -- es gibt keine
|
||||
## Wochentage. Zu Beginn ist jede Stunde leer; wer dabeisteht, füllt sie.
|
||||
func _tagesablauf(human_id: String) -> void:
|
||||
@@ -720,8 +835,8 @@ func _tagesablauf(human_id: String) -> void:
|
||||
for stunde in range(24):
|
||||
if not Game.gesehen_slot(human_id, Game.slot_bei_stunde(human_id, stunde)):
|
||||
offen += 1
|
||||
_text("[b]Ihr Tag[/b]%s" %
|
||||
("" if offen == 0 else " [color=#8e93a8]%d Stunden leer[/color]" % offen), 17)
|
||||
if offen > 0:
|
||||
_akte_text("[color=%s]%d Stunden leer[/color]" % [TINTE_HELL, offen], 14)
|
||||
|
||||
# eine Zeile je Abschnitt des Tages -- auch wenn noch keiner bekannt ist,
|
||||
# steht der Tag vollständig da
|
||||
@@ -756,8 +871,8 @@ func _stunden_zeile(human_id: String, nr: int, von: int, bis: int, text: String)
|
||||
var spanne := "%02d – %02d" % [von, bis + 1 if bis < 23 else 24]
|
||||
var offen: bool = Game.gesehen_slot(human_id, nr) and Game.erkannt(human_id, nr) \
|
||||
and Game.slot_grund(human_id, nr) != "schlaeft"
|
||||
_karte("%s %s" % [spanne, text], _ablauf_farbe(human_id, nr),
|
||||
func() -> void: slot_panel(human_id, nr, systeme_panel.bind(human_id)), offen)
|
||||
_akte_karte("%s %s" % [spanne, text], _ablauf_farbe(human_id, nr),
|
||||
func() -> void: slot_panel(human_id, nr, akte_panel.bind(human_id)), offen)
|
||||
|
||||
|
||||
## Der offene Moment: hier zählt, welche Technik zu diesem Problem passt.
|
||||
@@ -808,13 +923,13 @@ func slot_panel(human_id: String, nr: int, zurueck: Callable = Callable()) -> vo
|
||||
_text("Sie %s.\n[b]Auslöser:[/b] %s\n[b]Belohnung:[/b] %s" %
|
||||
[b["name"], b["ausloeser"], Ursachen.belohnung_text(str(b["belohnung"]))], 16)
|
||||
else:
|
||||
_text("Hier ist Platz. Ein neues System passt in diesen Slot.", 16)
|
||||
_text("Hier ist Platz für eine neue Routine.", 16)
|
||||
_trenner()
|
||||
var sys := Game.system_in(human_id, nr)
|
||||
if not sys.is_empty():
|
||||
_text("[color=#88ff99]Hier steht: %s[/color]" %
|
||||
TechDB.by_id(str(sys["tech"]))["name"], 16)
|
||||
_knopf("System wieder herausnehmen", func() -> void:
|
||||
_knopf("Routine wieder herausnehmen", func() -> void:
|
||||
Game.system_entfernen(human_id, nr)
|
||||
systeme_panel(human_id))
|
||||
_trenner()
|
||||
@@ -1043,7 +1158,7 @@ func _vorschau_aktualisieren() -> void:
|
||||
var wert := int(bild["verhalten"][v])
|
||||
if wert != 0:
|
||||
zuege.append("%s %s" % [namen[v], "+" if wert > 0 else "−"])
|
||||
_vorschau.text = "[color=#ff9a8a]%s[/color]\n[color=#ffcc66]%s[/color] · %d Blocker im Tag\n[color=#8e93a8]%s[/color]" % \
|
||||
_vorschau.text = "[color=#ff9a8a]%s[/color]\n[color=#ffcc66]%s[/color] · %d Gewohnheiten im Tag\n[color=#8e93a8]%s[/color]" % \
|
||||
[" · ".join(urs), " · ".join(prob), (bild["blocker"] as Array).size(),
|
||||
" ".join(zuege) if not zuege.is_empty() else "unauffällig"]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user