This commit is contained in:
Team3
2026-09-15 23:17:07 +02:00
parent c62c6e551f
commit f1b0f15e30
16 changed files with 1116 additions and 44 deletions

View File

@@ -9,6 +9,7 @@ class_name HumanDB
## an da und leben ihren Tag.
const EINWOHNER := 16
const BLOCKER_MAX := 4 # mehr Blocker, und der Tag wäre nur noch kaputt
const ACHSEN := [-72.0, -24.0, 24.0, 72.0] # Arterien in x wie in z
const ARTERIE := 7.0 # Breite einer Arterie
const ROJI := 3.2 # Breite einer Gasse
@@ -103,6 +104,58 @@ static var ANLIEGEN: Array = [
## Der Grundtag. Blocker werden später in passende Fenster gesetzt.
## [Stunde, Ort, Tätigkeit, Fenster]
## Jeder Beruf hat einen Tagestyp -- der bestimmt, wann gearbeitet wird und
## wo im Tag Platz für Blocker ist. So bekommt jeder Mensch einen eigenen Alltag.
static var BERUF_TAGESTYP: Dictionary = {
"Illustratorin": "heim", "Programmiererin": "heim", "Musiker": "heim",
"Bäcker": "frueh", "Pfleger": "frueh", "Fahrer": "frueh", "Köchin": "frueh",
"Sachbearbeiter": "buero", "Archivarin": "buero", "Lehrer": "buero",
"Studentin": "studium", "Tischlerin": "werkstatt",
}
static var TAGESTYP_ARBEIT: Dictionary = {
"heim": "heim", "frueh": "baeckerei", "buero": "buero", "studium": "uni",
"werkstatt": "werkstatt",
}
static var TAGESTYPEN: Dictionary = {
"heim": [
[0, "heim", "schlaeft", "nacht"], [7, "heim", "morgenroutine", "morgen"],
[9, "heim", "arbeitet", "tag"], [12, "cafe", "essen", "tag"],
[14, "heim", "arbeitet", "tag"], [17, "park", "unterwegs", "abend"],
[19, "heim", "ruht", "abend"], [21, "heim", "ruht", "abend"],
[23, "heim", "abendroutine", "nacht"],
],
"frueh": [
[0, "heim", "schlaeft", "nacht"], [4, "arbeit", "arbeitet", "morgen"],
[10, "cafe", "pause", "tag"], [12, "heim", "essen", "tag"],
[14, "heim", "ruht", "tag"], [16, "park", "unterwegs", "abend"],
[18, "heim", "ruht", "abend"], [20, "heim", "ruht", "abend"],
[22, "heim", "abendroutine", "nacht"],
],
"buero": [
[0, "heim", "schlaeft", "nacht"], [6, "heim", "morgenroutine", "morgen"],
[8, "arbeit", "arbeitet", "tag"], [12, "cafe", "essen", "tag"],
[14, "arbeit", "arbeitet", "tag"], [18, "arbeit", "arbeitet", "abend"],
[20, "heim", "essen", "abend"], [22, "heim", "ruht", "abend"],
[23, "heim", "abendroutine", "nacht"],
],
"studium": [
[0, "heim", "schlaeft", "nacht"], [8, "heim", "morgenroutine", "morgen"],
[10, "arbeit", "arbeitet", "tag"], [13, "cafe", "essen", "tag"],
[15, "arbeit", "arbeitet", "tag"], [18, "heim", "ruht", "abend"],
[20, "park", "unterwegs", "abend"], [22, "heim", "ruht", "abend"],
[23, "heim", "abendroutine", "nacht"],
],
"werkstatt": [
[0, "heim", "schlaeft", "nacht"], [6, "heim", "morgenroutine", "morgen"],
[7, "arbeit", "arbeitet", "tag"], [12, "cafe", "essen", "tag"],
[13, "arbeit", "arbeitet", "tag"], [17, "heim", "ruht", "abend"],
[19, "park", "unterwegs", "abend"], [21, "heim", "ruht", "abend"],
[23, "heim", "abendroutine", "nacht"],
],
}
static var GRUNDTAG: Array = [
[0, "heim", "schlaeft", "nacht"],
[7, "heim", "morgenroutine", "morgen"],
@@ -145,8 +198,12 @@ static func erzeuge(_ungenutzt: int = 0) -> void:
_sonderbauten_verteilen()
_wohnhaeuser_verteilen()
_anker_setzen()
for i in range(EINWOHNER):
var eigene := Aushaenge.laden()
var n_eigen := mini(eigene.size(), EINWOHNER)
for i in range(EINWOHNER - n_eigen):
LIST.append(_mensch(i))
for k in range(n_eigen):
LIST.append(mensch_aus_profil(eigene[k], EINWOHNER - n_eigen + k))
# ------------------------------------------------------------ Bezirk
@@ -424,8 +481,16 @@ static func ursachen_von(i: int) -> Array:
## Der Tagesablauf: Grundtag, in den je Ursache ein Blocker gesetzt wird.
static func _tagesablauf(i: int, heim: String, arbeit: String) -> Array:
return _tag_belegen(GRUNDTAG, heim, arbeit, [], ursachen_von(i), i)
## Legt Blocker in den Tag. Zuerst bekommt jede Ursache einen -- sonst wäre sie
## nie zu erkennen und bremste den Traum für immer. Danach kommen weitere
## gewünschte dazu, bis der Tag voll ist. Jeder Blocker nur in sein Zeitfenster.
static func _tag_belegen(vorlage: Array, heim: String, arbeit: String,
gewuenscht: Array, ursachen: Array, i: int) -> Array:
var slots: Array = []
for e in GRUNDTAG:
for e in vorlage:
var ort: String = str(e[1])
if ort == "heim":
ort = heim
@@ -433,32 +498,103 @@ static func _tagesablauf(i: int, heim: String, arbeit: String) -> Array:
ort = arbeit
slots.append([int(e[0]), ort, str(e[2]), str(e[3])])
var belegt: Dictionary = {}
var gesetzt: Array = []
# 1. je Ursache ein Blocker -- aus den gewünschten, sonst aus dem Katalog
var nr := 0
for u in ursachen_von(i):
for fenster in ["tag", "abend", "morgen", "nacht"]:
var kandidaten: Array = Ursachen.blocker_fuer(str(u), fenster)
if kandidaten.is_empty():
continue
var blocker: String = str(kandidaten[(i + nr) % kandidaten.size()])
var gesetzt := false
for k in range(slots.size()):
if belegt.has(k) or str(slots[k][2]) == "schlaeft":
continue
if str(slots[k][3]) != fenster:
continue
slots[k][2] = blocker
belegt[k] = true
gesetzt = true
break
if gesetzt:
for u in ursachen:
var kandidaten: Array = []
for b in gewuenscht:
if Ursachen.ursache_von(str(b)) == str(u):
kandidaten.append(str(b))
for b in Ursachen.alle_blocker(str(u)):
if not kandidaten.has(str(b)):
kandidaten.append(str(b))
for k in range(kandidaten.size()):
var b: String = str(kandidaten[(k + i + nr) % kandidaten.size()])
if _blocker_setzen(slots, belegt, b):
gesetzt.append(b)
break
nr += 1
# 2. weitere gewünschte, solange Platz ist
for b in gewuenscht:
if gesetzt.size() >= BLOCKER_MAX:
break
if gesetzt.has(str(b)) or not Ursachen.BLOCKER.has(b):
continue
if _blocker_setzen(slots, belegt, str(b)):
gesetzt.append(str(b))
var out: Array = []
for e in slots:
out.append([e[0], e[1], e[2]])
return out
## Ein Blocker in den ersten freien Slot seines Zeitfensters. Nie in den Schlaf.
static func _blocker_setzen(slots: Array, belegt: Dictionary, b: String) -> bool:
var fenster := str(Ursachen.BLOCKER[b]["zeit"])
for k in range(slots.size()):
if belegt.has(k) or str(slots[k][2]) == "schlaeft" or str(slots[k][3]) != fenster:
continue
slots[k][2] = b
belegt[k] = true
return true
return false
## Ein Mensch, den jemand selbst geschrieben hat. Name, Beruf, Traum und
## Geschichte kommen vom Aushang; Ursachen, Blocker, Klemmen und Verhalten
## schließt das Spiel aus den angekreuzten Wörtern.
static func mensch_aus_profil(pr: Dictionary, i: int) -> Dictionary:
var bild := Woerter.profil(pr.get("woerter", []))
var beruf := str(pr.get("beruf", ""))
var typ := str(BERUF_TAGESTYP.get(beruf, "buero"))
var heim := heim_key(i)
var arbeit := str(TAGESTYP_ARBEIT.get(typ, "buero"))
if arbeit == "heim":
arbeit = heim
elif not PLACES.has(arbeit):
arbeit = _naechster_arbeitsplatz(heim, i)
return {
"id": str(pr.get("id", "eigen_%d" % i)),
"name": str(pr.get("name", "Unbekannt")),
"alter": int(pr.get("alter", 30)),
"beruf": beruf,
"traum": str(pr.get("traum", "")),
"problem": str(pr.get("geschichte", "")),
"tags": [],
"ursachen": bild["ursachen"],
"probleme": bild["probleme"],
"verhalten": bild["verhalten"],
"woerter": Array(pr.get("woerter", [])),
"eigen": true,
"mission": true,
"heim": heim,
"farbe": Color.from_hsv(fmod(0.02 + float(i) * 0.191, 1.0), 0.5, 0.8),
"routine": _tag_belegen(TAGESTYPEN[typ], heim, arbeit, bild["blocker"],
bild["ursachen"], i),
}
## Der Zufall-Knopf: füllt einen Aushang so, wie der Generator Menschen macht.
static func zufallsprofil() -> Dictionary:
var i := randi() % 1000
var anliegen: Dictionary = ANLIEGEN[i % ANLIEGEN.size()]
var alle: Array = Woerter.ids()
alle.shuffle()
var woerter: Array = alle.slice(0, Woerter.MINDESTENS + randi() % 4)
return {
"name": "%s %s" % [_vorname(i), _nachname(i)],
"alter": 20 + randi() % 45,
"beruf": str(BERUFE[i % BERUFE.size()]),
"traum": str(anliegen["traum"]),
"geschichte": str(anliegen["problem"]),
"woerter": woerter,
}
static func _mensch(i: int) -> Dictionary:
var anliegen: Dictionary = ANLIEGEN[i % ANLIEGEN.size()]
if i < PASSEND.size():
@@ -475,6 +611,7 @@ static func _mensch(i: int) -> Dictionary:
"tags": (anliegen["tags"] as Array).duplicate(),
"ursachen": ursachen_von(i),
"probleme": probleme_von(i),
"verhalten": {},
"mission": true,
"heim": heim,
"farbe": Color.from_hsv(fmod(0.02 + float(i) * 0.191, 1.0), 0.5, 0.8),