update
This commit is contained in:
161
scripts/game.gd
161
scripts/game.gd
@@ -15,6 +15,7 @@ var known: Dictionary = {} # tech_id -> xp
|
||||
var active_mission: String = "" # human_id oder ""
|
||||
var progress: Dictionary = {} # human_id -> 0..100
|
||||
var used: Dictionary = {} # "human:tech" -> Anzahl
|
||||
var pipeline: Dictionary = {} # human_id -> {activity -> tech_id}
|
||||
var completed: Array = []
|
||||
var time_h: float = 7.0
|
||||
var day: int = 1
|
||||
@@ -23,6 +24,7 @@ var teleport_lock: float = 0.0
|
||||
|
||||
func _ready() -> void:
|
||||
_setup_input()
|
||||
welt_erzeugen()
|
||||
|
||||
|
||||
func _setup_input() -> void:
|
||||
@@ -50,6 +52,15 @@ func advance_time(delta: float) -> void:
|
||||
while time_h >= 24.0:
|
||||
time_h -= 24.0
|
||||
day += 1
|
||||
_gewoehnung_klingt_ab()
|
||||
|
||||
|
||||
## Abstand macht eine Technik wieder wirksam: über Nacht verfällt die Hälfte
|
||||
## der Gewöhnung. Wer täglich denselben Weg geht, hält ihn brauchbar — wer ihn
|
||||
## an einem Tag immer wieder auffährt, stumpft ihn ab.
|
||||
func _gewoehnung_klingt_ab() -> void:
|
||||
for key in used:
|
||||
used[key] = int(used[key]) / 2
|
||||
|
||||
|
||||
func time_string() -> String:
|
||||
@@ -58,6 +69,54 @@ func time_string() -> String:
|
||||
return "Tag %d · %02d:%02d" % [day, h, m]
|
||||
|
||||
|
||||
# ------------------------------------------------------------ Wachsende Welt
|
||||
# Das Traumdorf wird erzeugt. Fest sind nur Hörsaal, Dorfplatz und Tor.
|
||||
# Jeder erfüllte Traum bringt einen Bewohner mit seinem Haus, und jedes Haus
|
||||
# lehrt eine Technik, die es vorher nirgends gab.
|
||||
|
||||
const INSEL_GRUND := 46.0
|
||||
const OFFENE_MISSIONEN := 3
|
||||
|
||||
|
||||
func haeuser() -> int:
|
||||
return completed.size()
|
||||
|
||||
|
||||
func insel_radius() -> float:
|
||||
var ring := DreamDB.aeusserster_ring(haeuser())
|
||||
return maxf(INSEL_GRUND, ring + 14.0)
|
||||
|
||||
|
||||
## Baut Traumdorf und Menschheit auf den Stand der erfüllten Träume.
|
||||
func welt_erzeugen() -> void:
|
||||
DreamDB.erzeuge(haeuser())
|
||||
HumanDB.erzeuge(completed.size() + OFFENE_MISSIONEN)
|
||||
|
||||
|
||||
## Das Traumdorf beginnt leer. Mit jedem erfüllten Traum zieht ein Wesen ein.
|
||||
func wesen_eingezogen(index: int) -> bool:
|
||||
return index < haeuser()
|
||||
|
||||
|
||||
## Steht dieser Ort schon auf der Insel? Erzeugt wird nur, was schon da ist.
|
||||
func ort_offen(place_key: String) -> bool:
|
||||
return DreamDB.PLACES.has(place_key)
|
||||
|
||||
|
||||
## Ist die Technik überhaupt schon irgendwo zu finden?
|
||||
func technik_offen(tech_id: String) -> bool:
|
||||
var ort := DreamDB.ort_von_technik(tech_id)
|
||||
return ort != "" and ort_offen(ort)
|
||||
|
||||
|
||||
func offene_techniken() -> int:
|
||||
var n := 0
|
||||
for t in TechDB.LIST:
|
||||
if technik_offen(t["id"]):
|
||||
n += 1
|
||||
return n
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- Fertigkeiten
|
||||
|
||||
func knows(tech_id: String) -> bool:
|
||||
@@ -86,6 +145,10 @@ func xp_to_next(tech_id: String) -> String:
|
||||
func learn(tech_id: String) -> bool:
|
||||
if known.has(tech_id):
|
||||
return false
|
||||
if not technik_offen(tech_id):
|
||||
notified.emit("Diesen Weg kennt im Dorf noch niemand. Erfülle einen Traum.",
|
||||
Color(1, 0.8, 0.5))
|
||||
return false
|
||||
if einsicht < 1:
|
||||
notified.emit("Dafür fehlt dir Einsicht. Hilf erst einem Menschen.", Color(1, 0.6, 0.4))
|
||||
return false
|
||||
@@ -136,12 +199,107 @@ func accept_mission(human_id: String) -> bool:
|
||||
return true
|
||||
|
||||
|
||||
## Angenommen ist, wer schon einmal im Auftragsbuch stand.
|
||||
func angenommen(human_id: String) -> bool:
|
||||
return progress.has(human_id)
|
||||
|
||||
|
||||
func mission_progress(human_id: String) -> float:
|
||||
return progress.get(human_id, 0.0)
|
||||
|
||||
|
||||
## Ein erfüllter Traum lässt das Dorf wachsen: ein Wesen zieht mit seinem
|
||||
## Haus ein, und in diesem Haus wird ein neuer Weg gelehrt.
|
||||
func _insel_waechst() -> void:
|
||||
welt_erzeugen()
|
||||
var i := haeuser() - 1
|
||||
if i < 0 or i >= DreamDB.LIST.size():
|
||||
return
|
||||
var w: Dictionary = DreamDB.LIST[i]
|
||||
notified.emit("%s, %s, ist ins Traumdorf gezogen." % [w["name"], w["rolle"]],
|
||||
Color(0.85, 0.75, 1))
|
||||
var neu: Array = DreamDB.techniken_von(DreamDB.haus_key(i))
|
||||
if neu.is_empty():
|
||||
return
|
||||
notified.emit("In %s wird ein neuer Weg gelehrt: %s." %
|
||||
[DreamDB.PLACES[DreamDB.haus_key(i)]["name"], TechDB.by_id(str(neu[0]))["name"]],
|
||||
Color(0.75, 0.95, 1))
|
||||
|
||||
|
||||
# ------------------------------------------------------------------- Regelwerk
|
||||
# Eine Regel ist ein Wenn-Dann: tut der Mensch etwas Bestimmtes, greift die
|
||||
# zugeordnete Technik von allein. Damit automatisiert der Spieler den Fortschritt.
|
||||
|
||||
func regeln(human_id: String) -> Dictionary:
|
||||
return pipeline.get(human_id, {})
|
||||
|
||||
|
||||
func regel_fuer(human_id: String, activity: String) -> String:
|
||||
return regeln(human_id).get(activity, "")
|
||||
|
||||
|
||||
func regel_anzahl(human_id: String) -> int:
|
||||
return regeln(human_id).size()
|
||||
|
||||
|
||||
## Wo hängt diese Technik im Regelwerk gerade? "" wenn nirgends.
|
||||
func regel_moment(human_id: String, tech_id: String) -> String:
|
||||
for activity in regeln(human_id):
|
||||
if regeln(human_id)[activity] == tech_id:
|
||||
return activity
|
||||
return ""
|
||||
|
||||
|
||||
## Leere tech_id löscht die Regel. Eine Technik hält immer nur einen Posten —
|
||||
## sie an einen neuen Moment zu hängen nimmt sie vom alten weg. Das zwingt zur
|
||||
## Wahl und macht das Lernen weiterer Techniken erst wertvoll.
|
||||
func regel_setzen(human_id: String, activity: String, tech_id: String) -> void:
|
||||
if not pipeline.has(human_id):
|
||||
pipeline[human_id] = {}
|
||||
var r: Dictionary = pipeline[human_id]
|
||||
if tech_id == "":
|
||||
r.erase(activity)
|
||||
else:
|
||||
var vorher := regel_moment(human_id, tech_id)
|
||||
if vorher != "" and vorher != activity:
|
||||
r.erase(vorher)
|
||||
notified.emit("%s hängt jetzt an »%s« statt an »%s«." %
|
||||
[TechDB.by_id(tech_id)["name"], Orte.text(activity), Orte.text(vorher)],
|
||||
Color(0.85, 0.9, 1))
|
||||
r[activity] = tech_id
|
||||
state_changed.emit()
|
||||
|
||||
|
||||
## Der Mensch wechselt in eine Tätigkeit: greift dafür eine Regel?
|
||||
func regel_ausloesen(human_id: String, activity: String, resisting: bool) -> Dictionary:
|
||||
if human_id != active_mission:
|
||||
return {}
|
||||
var tech_id := regel_fuer(human_id, activity)
|
||||
if tech_id == "" or not known.has(tech_id):
|
||||
return {}
|
||||
var res := apply_technique(tech_id, human_id, activity, resisting)
|
||||
if not res["ok"]:
|
||||
return {}
|
||||
res["tech"] = tech_id
|
||||
var t := TechDB.by_id(tech_id)
|
||||
if res["success"]:
|
||||
notified.emit("Regel greift — %s bei »%s« (+%d %%)" %
|
||||
[t["name"], Orte.text(activity), int(round(float(res["gain"])))],
|
||||
Color(0.6, 1, 0.7))
|
||||
else:
|
||||
notified.emit("Regel läuft ins Leere — %s bei »%s« (%d %% Chance)" %
|
||||
[t["name"], Orte.text(activity), int(round(float(res["chance"]) * 100.0))],
|
||||
Color(1, 0.7, 0.5))
|
||||
return res
|
||||
|
||||
|
||||
# ----------------------------------------------------- Technik auf Mensch anwenden
|
||||
|
||||
## Schlafende erreicht keine Technik — weder von Hand noch über eine Regel.
|
||||
func erreichbar(activity: String) -> bool:
|
||||
return activity != "schlaeft"
|
||||
|
||||
|
||||
## Bewertet eine Technik in genau dieser Situation, ohne sie anzuwenden.
|
||||
func evaluate(tech_id: String, human_id: String, activity: String, resisting: bool) -> Dictionary:
|
||||
var t := TechDB.by_id(tech_id)
|
||||
@@ -151,7 +309,7 @@ func evaluate(tech_id: String, human_id: String, activity: String, resisting: bo
|
||||
"chance": 0.0, "tag": false, "moment": false, "blocked": false,
|
||||
"grund": "", "skill": skill,
|
||||
}
|
||||
if activity == "schlaeft":
|
||||
if not erreichbar(activity):
|
||||
res["blocked"] = true
|
||||
res["grund"] = "Sie oder er schläft. Techniken erreichen nur wache Menschen."
|
||||
return res
|
||||
@@ -214,6 +372,7 @@ func apply_technique(tech_id: String, human_id: String, activity: String, resist
|
||||
mission_done.emit(human_id)
|
||||
notified.emit("%s hat es geschafft. (+3 Einsicht)" % HumanDB.by_id(human_id)["name"],
|
||||
Color(1, 0.85, 0.4))
|
||||
_insel_waechst()
|
||||
state_changed.emit()
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user