update
This commit is contained in:
236
scripts/ui.gd
236
scripts/ui.gd
@@ -133,6 +133,7 @@ func _process(_delta: float) -> void:
|
||||
var wunsch := _content.get_combined_minimum_size().y
|
||||
var platz := get_viewport().get_visible_rect().size.y - 220.0
|
||||
_scroll.custom_minimum_size.y = clampf(wunsch, 120.0, platz)
|
||||
_panel.reset_size() # sonst behält der Rahmen die Höhe des Panels davor
|
||||
if _scroll_frames > 0:
|
||||
_scroll.scroll_vertical = _scroll_wunsch
|
||||
_scroll_frames -= 1
|
||||
@@ -148,13 +149,14 @@ func _hud_aktualisieren() -> void:
|
||||
[Game.einsicht, Game.known.size(), TechDB.LIST.size()])
|
||||
if Game.active_mission != "":
|
||||
var h := HumanDB.by_id(Game.active_mission)
|
||||
zeilen.append("Mission: [color=#ffdd77]%s[/color] — %d %%" %
|
||||
[h["name"], int(Game.mission_progress(Game.active_mission))])
|
||||
zeilen.append("Mission: [color=#ffdd77]%s[/color] — %d %% · %d Regeln" %
|
||||
[h["name"], int(Game.mission_progress(Game.active_mission)),
|
||||
Game.regel_anzahl(Game.active_mission)])
|
||||
zeilen.append("[color=#aaaaaa]%s[/color]" % h["traum"])
|
||||
elif Game.completed.size() >= HumanDB.LIST.size():
|
||||
zeilen.append("[color=#88ff99]Alle Träume erfüllt.[/color]")
|
||||
else:
|
||||
zeilen.append("[color=#aaaaaa]Keine Mission. Journal öffnen mit J.[/color]")
|
||||
zeilen.append("[color=#aaaaaa]Keine Mission. Schwarzes Brett am Dorfplatz.[/color]")
|
||||
_hud.text = "\n".join(zeilen)
|
||||
|
||||
|
||||
@@ -250,8 +252,9 @@ func _hinweis_block(t: Dictionary) -> String:
|
||||
|
||||
# -------------------------------------------------------- Journal
|
||||
|
||||
## Das Journal ist immer dabei. Hier werden Techniken gelernt und vertieft
|
||||
## und Missionen angenommen.
|
||||
## Das Journal ist immer dabei und führt Buch: welche Techniken du gelernt hast
|
||||
## und welche Missionen du angenommen hast. Gelehrt wird im Hörsaal,
|
||||
## vergeben werden die Missionen am Schwarzen Brett.
|
||||
func journal_panel(seite: String = "") -> void:
|
||||
if seite != "":
|
||||
_journal_seite = seite
|
||||
@@ -271,7 +274,11 @@ func _reiter() -> void:
|
||||
var hb := HBoxContainer.new()
|
||||
hb.add_theme_constant_override("separation", 8)
|
||||
_content.add_child(hb)
|
||||
for eintrag in [["techniken", "Techniken"], ["missionen", "Missionen"]]:
|
||||
var seiten := [
|
||||
["techniken", "Techniken (%d)" % Game.known.size()],
|
||||
["missionen", "Missionen (%d)" % Game.progress.size()],
|
||||
]
|
||||
for eintrag in seiten:
|
||||
var b := Button.new()
|
||||
b.text = eintrag[1]
|
||||
b.custom_minimum_size = Vector2(0, 36)
|
||||
@@ -293,10 +300,153 @@ func _reiter() -> void:
|
||||
|
||||
|
||||
func _journal_techniken() -> void:
|
||||
_text("Zwölf Wege, die Menschen wirklich weiterbringen. Jede Anwendung " +
|
||||
"draußen macht eine Technik von allein besser. Vertiefen geht auch hier.", 15)
|
||||
if Game.known.is_empty():
|
||||
_text("[color=#ffcc66]Du hast noch keine Technik gelernt.[/color]\n" +
|
||||
"Im [b]Hörsaal der Wege[/b] hinter dem Dorfplatz wird der erste Weg gelehrt.", 16)
|
||||
return
|
||||
_text("Was du gelernt hast. Jede Anwendung draußen macht eine Technik von allein " +
|
||||
"besser; vertieft wird im Hörsaal.", 15)
|
||||
_trenner()
|
||||
for id in TechDB.ids():
|
||||
if not Game.knows(id):
|
||||
continue
|
||||
var t := TechDB.by_id(id)
|
||||
_text("[b][color=#ffe3a0]%s[/color][/b] · Stufe %d (%s)" %
|
||||
[t["name"], Game.skill_of(id), Game.xp_to_next(id)], 18)
|
||||
_text(_hinweis_block(t), 15)
|
||||
_text("[color=#9fb6ff]Hilft bei:[/color] %s [color=#9fb6ff]Momente:[/color] %s" %
|
||||
[TechDB.tags_text(t["tags"]), TechDB.momente_text(t["momente"])], 14)
|
||||
_trenner()
|
||||
|
||||
|
||||
func _journal_missionen() -> void:
|
||||
if Game.progress.is_empty():
|
||||
_text("[color=#ffcc66]Du hast noch keine Mission angenommen.[/color]\n" +
|
||||
"Am [b]Schwarzen Brett[/b] am Dorfplatz hängen die Menschen aus, " +
|
||||
"die nicht weiterkommen.", 16)
|
||||
return
|
||||
_text("Die Menschen, für die du dich entschieden hast.", 15)
|
||||
_trenner()
|
||||
for h in HumanDB.LIST:
|
||||
var id: String = h["id"]
|
||||
if not Game.angenommen(id):
|
||||
continue
|
||||
_text("[b][color=#ffe3a0]%s[/color][/b], %d — %s" %
|
||||
[h["name"], h["alter"], h["beruf"]], 18)
|
||||
_text("[b]Traum:[/b] %s" % h["traum"], 16)
|
||||
_text("[b]Was im Weg steht:[/b] %s" % h["problem"], 15)
|
||||
_text("[color=#9fb6ff]Themen:[/color] %s" % TechDB.tags_text(h["tags"]), 14)
|
||||
if Game.completed.has(id):
|
||||
_text("[color=#88ff99]★ Der Traum ist erfüllt.[/color]", 15)
|
||||
elif Game.active_mission == id:
|
||||
_text("[color=#ffdd77]Aktive Mission — %d %%[/color]" %
|
||||
int(Game.mission_progress(id)), 15)
|
||||
else:
|
||||
_text("[color=#aaaaaa]Zurückgestellt — %d %%[/color]" %
|
||||
int(Game.mission_progress(id)), 15)
|
||||
if not Game.completed.has(id):
|
||||
_knopf("Regelwerk — %d Regeln" % Game.regel_anzahl(id),
|
||||
func() -> void: pipeline_panel(id))
|
||||
_trenner()
|
||||
|
||||
|
||||
# -------------------------------------------------------- Regelwerk einer Mission
|
||||
|
||||
## Wenn-Dann-Regeln: tut der Mensch etwas Bestimmtes, greift die zugeordnete
|
||||
## Technik von allein. So automatisiert der Spieler den Fortschritt.
|
||||
func pipeline_panel(human_id: String) -> void:
|
||||
var scroll_alt := _scroll.scroll_vertical if offen and _kind == "pipeline" else 0
|
||||
var h := HumanDB.by_id(human_id)
|
||||
_leeren("Regelwerk — %s" % h["name"])
|
||||
_text("Jede Tätigkeit im Tag von %s kann eine Technik auslösen. " % h["name"] +
|
||||
"Wechselt sie hinein, greift die Regel von allein — solange du auf der Erde bist.", 15)
|
||||
_text("[color=#aaaaaa]Fortschritt: [b]%d %%[/b] · Regeln: [b]%d[/b][/color]" %
|
||||
[int(Game.mission_progress(human_id)), Game.regel_anzahl(human_id)], 15)
|
||||
_trenner()
|
||||
for activity in HumanDB.aktivitaeten(human_id):
|
||||
var tat := Orte.text(activity)
|
||||
if not Game.erreichbar(activity):
|
||||
_knopf("%s → unerreichbar" % tat, func() -> void: pass, false)
|
||||
continue
|
||||
var tech: String = Game.regel_fuer(human_id, activity)
|
||||
var beschriftung := "%s → keine Regel" % tat
|
||||
if tech != "":
|
||||
var ev := Game.evaluate(tech, human_id, activity, false)
|
||||
beschriftung = "%s → %s · %d %%" % [tat, TechDB.by_id(tech)["name"],
|
||||
int(round(float(ev["chance"]) * 100.0))]
|
||||
_knopf(beschriftung, func() -> void: regel_panel(human_id, activity))
|
||||
_trenner()
|
||||
_knopf("Zurück zum Journal", func() -> void: journal_panel("missionen"))
|
||||
_zeigen("pipeline")
|
||||
_scroll_wunsch = scroll_alt
|
||||
_scroll_frames = 4
|
||||
|
||||
|
||||
## Welche Technik soll bei dieser Tätigkeit greifen?
|
||||
func regel_panel(human_id: String, activity: String) -> void:
|
||||
var h := HumanDB.by_id(human_id)
|
||||
_leeren("Regel für »%s«" % Orte.text(activity))
|
||||
if Game.known.is_empty():
|
||||
_text("[color=#ffcc66]Du kennst keine Technik. Im Hörsaal der Wege " +
|
||||
"werden sie gelehrt.[/color]", 16)
|
||||
_knopf("Zurück", func() -> void: pipeline_panel(human_id))
|
||||
_zeigen("regel")
|
||||
return
|
||||
_text("Was soll greifen, wenn %s %s? Die Erfolgschance gilt für genau diesen Moment. " %
|
||||
[h["name"], Orte.text(activity)] +
|
||||
"Jede Technik hält nur einen Posten — sie hier einzusetzen nimmt sie anderswo weg.", 15)
|
||||
_trenner()
|
||||
for id in TechDB.ids():
|
||||
if not Game.knows(id):
|
||||
continue
|
||||
var t := TechDB.by_id(id)
|
||||
var ev := Game.evaluate(id, human_id, activity, false)
|
||||
var marker: Array = []
|
||||
if ev["tag"]:
|
||||
marker.append("[color=#88ff99]passt zum Thema[/color]")
|
||||
if ev["moment"]:
|
||||
marker.append("[color=#88ff99]passender Moment[/color]")
|
||||
if ev["blocked"]:
|
||||
marker.append("[color=#ff8877]%s[/color]" % ev["grund"])
|
||||
if marker.is_empty():
|
||||
marker.append("[color=#aaaaaa]weder Thema noch Moment passen[/color]")
|
||||
var gewaehlt := ""
|
||||
var haengt := Game.regel_moment(human_id, id)
|
||||
if haengt == activity:
|
||||
gewaehlt = " [color=#ffdd77](hier eingestellt)[/color]"
|
||||
elif haengt != "":
|
||||
gewaehlt = " [color=#ffaa66](hängt an »%s«)[/color]" % Orte.text(haengt)
|
||||
_text("[b]%s[/b] · Stufe %d%s\n[color=#cccccc]%s[/color]\n%s" %
|
||||
[t["name"], Game.skill_of(id), gewaehlt, t["wann"], " · ".join(marker)], 16)
|
||||
var beschriftung := "Blockiert" if ev["blocked"] else \
|
||||
"Diese Regel — %d %% Erfolgschance" % int(round(float(ev["chance"]) * 100.0))
|
||||
_knopf(beschriftung, func() -> void:
|
||||
Game.regel_setzen(human_id, activity, id)
|
||||
pipeline_panel(human_id), not ev["blocked"])
|
||||
_trenner()
|
||||
_knopf("Keine Regel für diese Tätigkeit", func() -> void:
|
||||
Game.regel_setzen(human_id, activity, "")
|
||||
pipeline_panel(human_id))
|
||||
_zeigen("regel")
|
||||
|
||||
|
||||
# -------------------------------------------------------- Lehrorte
|
||||
|
||||
## Jeder Lehrort unterrichtet genau einen Weg: der Hörsaal den ersten, jedes
|
||||
## Haus den, den sein Bewohner mitgebracht hat.
|
||||
func lehre_panel(ort: String = "hoersaal") -> void:
|
||||
if not DreamDB.PLACES.has(ort):
|
||||
return
|
||||
var scroll_alt := _scroll.scroll_vertical if offen and _kind == "lehre" else 0
|
||||
var pl: Dictionary = DreamDB.PLACES[ort]
|
||||
var ids: Array = DreamDB.techniken_von(ort)
|
||||
_leeren(str(pl["name"]))
|
||||
_text("[color=#aaaaaa]Einsicht: [b]%d[/b] · Gelernt: [b]%d / %d[/b] von %d entdeckten[/color]" %
|
||||
[Game.einsicht, Game.known.size(), TechDB.LIST.size(), Game.offene_techniken()], 15)
|
||||
_trenner()
|
||||
if ids.is_empty():
|
||||
_text("[color=#ffcc66]Hier wird nichts gelehrt.[/color]", 16)
|
||||
for id in ids:
|
||||
var t := TechDB.by_id(id)
|
||||
if Game.knows(id):
|
||||
_text("[b][color=#ffe3a0]%s[/color][/b] · Stufe %d (%s)" %
|
||||
@@ -309,16 +459,38 @@ func _journal_techniken() -> void:
|
||||
if Game.knows(id):
|
||||
_knopf("Vertiefen (1 Einsicht)", func() -> void:
|
||||
if Game.deepen(id):
|
||||
journal_panel(), Game.einsicht >= 1)
|
||||
lehre_panel(ort), Game.einsicht >= 1)
|
||||
else:
|
||||
_knopf("Lernen (1 Einsicht)", func() -> void:
|
||||
if Game.learn(id):
|
||||
journal_panel(), Game.einsicht >= 1)
|
||||
lehre_panel(ort), Game.einsicht >= 1)
|
||||
_trenner()
|
||||
_naechster_weg()
|
||||
_zeigen("lehre")
|
||||
_scroll_wunsch = scroll_alt
|
||||
_scroll_frames = 4
|
||||
|
||||
|
||||
func _journal_missionen() -> void:
|
||||
_text("Menschen, deren Traum feststeckt.", 15)
|
||||
## Was als Nächstes ins Dorf käme.
|
||||
func _naechster_weg() -> void:
|
||||
var offen_zahl := Game.offene_techniken()
|
||||
if offen_zahl >= TechDB.LIST.size():
|
||||
_text("[color=#88ff99]Alle zwölf Wege sind entdeckt. Das Dorf wächst weiter.[/color]", 15)
|
||||
return
|
||||
var naechste: Dictionary = TechDB.LIST[offen_zahl]
|
||||
_text("[color=#aaaaaa]Noch unentdeckt: [b]%s[/b] und %d weitere. Jeder erfüllte Traum " %
|
||||
[naechste["name"], TechDB.LIST.size() - offen_zahl - 1] +
|
||||
"bringt einen Bewohner ins Dorf, und er lehrt einen neuen Weg.[/color]", 15)
|
||||
|
||||
|
||||
# -------------------------------------------------------- Schwarzes Brett
|
||||
|
||||
## Hier hängen die Menschen aus, deren Traum feststeckt.
|
||||
func brett_panel() -> void:
|
||||
var scroll_alt := _scroll.scroll_vertical if offen and _kind == "brett" else 0
|
||||
_leeren("Schwarzes Brett")
|
||||
_text("Menschen, deren Traum feststeckt. Nimm einen an — das Tor zur Erde " +
|
||||
"öffnet sich nur mit einer Mission.", 15)
|
||||
_trenner()
|
||||
for h in HumanDB.LIST:
|
||||
var id: String = h["id"]
|
||||
@@ -333,11 +505,16 @@ func _journal_missionen() -> void:
|
||||
_text("[color=#ffdd77]Aktive Mission — %d %%[/color]" %
|
||||
int(Game.mission_progress(id)), 15)
|
||||
else:
|
||||
_text("Fortschritt: %d %%" % int(Game.mission_progress(id)), 15)
|
||||
if Game.angenommen(id):
|
||||
_text("[color=#aaaaaa]Schon einmal angenommen — %d %%[/color]" %
|
||||
int(Game.mission_progress(id)), 15)
|
||||
_knopf("Mission annehmen", func() -> void:
|
||||
Game.accept_mission(id)
|
||||
journal_panel())
|
||||
brett_panel())
|
||||
_trenner()
|
||||
_zeigen("brett")
|
||||
_scroll_wunsch = scroll_alt
|
||||
_scroll_frames = 4
|
||||
|
||||
|
||||
# -------------------------------------------------------- Anwenden auf der Erde
|
||||
@@ -411,37 +588,6 @@ func _anwenden(id: String) -> void:
|
||||
[t["name"], int(round(float(res["chance"]) * 100.0))], Color(1, 0.6, 0.5))
|
||||
|
||||
|
||||
# -------------------------------------------------------- Intro
|
||||
|
||||
func intro_panel(on_close: Callable) -> void:
|
||||
_leeren("Traumwandler")
|
||||
_text("Du bist ein Wesen aus der Traumwelt. Menschen tragen Träume mit sich herum, " +
|
||||
"die sie allein nicht bewegt bekommen. Du wirst zu ihnen geschickt.")
|
||||
_trenner()
|
||||
_text("[b]Dein Journal — Taste J[/b]\n" +
|
||||
"· Es ist immer dabei, in beiden Welten.\n" +
|
||||
"· [b]Techniken[/b] — lerne echte Lösungswege. Jede sagt dir, was sie tut, " +
|
||||
"wann sie passt und warum sie hilft. Anwenden macht sie von allein besser.\n" +
|
||||
"· [b]Missionen[/b] — nimm einen Menschen an, dem du helfen willst.")
|
||||
_text("[b]In der Traumwelt[/b]\n" +
|
||||
"· Ein Dorf auf einer schwebenden Insel. Vier Wesen wohnen hier, jedes in " +
|
||||
"seinem Haus, jedes mit eigenem Tagesablauf. Die Häuser stehen offen.\n" +
|
||||
"· [b]Tor zur Erde[/b] — reise hinab, sobald du eine Mission hast.")
|
||||
_text("[b]Auf der Erde[/b]\n" +
|
||||
"· Du bist ein unsichtbarer Geist und schwebst durch Wände. Leertaste hoch, Umschalt runter.\n" +
|
||||
"· Die Menschen leben ihren Tagesablauf: schlafen, arbeiten, grübeln, spazieren.\n" +
|
||||
"· Geh nah heran und drücke [b]E[/b]. Deine Erfolgschance hängt von deiner Stufe ab — " +
|
||||
"und davon, ob Technik und Moment zum Menschen passen.\n" +
|
||||
"· Schlafende erreichst du nicht. Wer abblockt, braucht eine Weile Ruhe.")
|
||||
_trenner()
|
||||
_text("[color=#aaaaaa]Du beginnst mit 3 Einsicht. Jede Technik kostet 1. " +
|
||||
"Ein erfüllter Traum bringt 3 zurück.[/color]", 15)
|
||||
_knopf("Losgehen", func() -> void:
|
||||
schliessen()
|
||||
on_close.call())
|
||||
_zeigen("intro")
|
||||
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if offen and event.is_action_pressed("ui_cancel"):
|
||||
schliessen()
|
||||
|
||||
Reference in New Issue
Block a user