This commit is contained in:
team3
2026-08-31 11:07:01 +02:00
parent f936dd2b2a
commit ef2ecc08f9
19 changed files with 2094 additions and 438 deletions

View File

@@ -14,6 +14,7 @@ var _nachtlichter: Array = []
func _ready() -> void:
_environment()
_boden()
_bebauung()
_orte()
_park()
_saeule()
@@ -44,107 +45,142 @@ func _environment() -> void:
func _boden() -> void:
var weite := 240.0
Prims.box(self, Vector3(0, -0.53, 0), Vector3(300, 1, 300), Color(0.42, 0.48, 0.40))
_strassen()
## Arterien breit, roji schmal -- beide als flaches Band mit Belag.
func _strassen() -> void:
for st in HumanDB.STRASSEN:
var a: Vector3 = st["a"]
var b: Vector3 = st["b"]
var d := b - a
if d.length() < 0.2:
continue
var breit := float(st["breite"])
var farbe := Color(0.62, 0.60, 0.58) if breit > 5.0 else Color(0.55, 0.53, 0.52)
var band := Prims.box(self, (a + b) * 0.5 + Vector3(0, 0.02, 0),
Vector3(breit, 0.06, d.length() + breit), farbe, false)
band.rotation.y = atan2(d.x, d.z)
## Alles, was nicht Wohnung oder Sonderbau ist, steht als geschlossener Bau da.
## Erst dadurch wird der Bezirk dicht.
func _bebauung() -> void:
var rng := RandomNumberGenerator.new()
rng.seed = 8123
var belegt: Dictionary = {}
for key in HumanDB.PLACES:
var pl: Dictionary = HumanDB.PLACES[key]
var p: Array = pl["pos"]
var s2: Array = pl["size"]
weite = maxf(weite, (absf(float(p[0])) + float(s2[0])) * 2.6)
weite = maxf(weite, (absf(float(p[1])) + float(s2[1])) * 2.6)
Prims.box(self, Vector3(0, -0.53, 0), Vector3(weite, 1, weite), Color(0.36, 0.52, 0.30))
# Ringweg, auf dem die Menschen gehen
for i in range(36):
var a := TAU * float(i) / 36.0
Prims.box(self, Vector3(cos(a) * 15.0, 0.03, sin(a) * 15.0),
Vector3(2.8, 0.06, 2.8), Color(0.62, 0.58, 0.50), false)
var s: Array = HumanDB.PLACES[key]["size"]
if float(s[0]) > 0.0:
belegt[Orte.center(HumanDB.PLACES, key).snapped(Vector3.ONE * 0.1)] = true
for p in HumanDB.PARZELLEN:
var c: Vector3 = p["pos"]
if belegt.has(c.snapped(Vector3.ONE * 0.1)):
continue
var g: Vector2 = p["size"]
if minf(g.x, g.y) < 3.0:
continue
var hoehe := rng.randf_range(4.0, 9.0)
var ton := Color.from_hsv(fmod(0.07 + rng.randf() * 0.12, 1.0),
0.10 + rng.randf() * 0.14, 0.62 + rng.randf() * 0.26)
Prims.box(self, c + Vector3(0, hoehe * 0.5, 0), Vector3(g.x, hoehe, g.y), ton)
Prims.box(self, c + Vector3(0, hoehe + 0.2, 0),
Vector3(g.x + 0.5, 0.4, g.y + 0.5), ton.darkened(0.25))
if rng.randf() < 0.35:
Prims.box(self, c + Vector3(0, hoehe + 0.9, 0),
Vector3(g.x * 0.4, 1.0, g.y * 0.4), ton.darkened(0.1))
## Wohnungen und Sonderbauten stehen offen, damit der Geist von oben hineinsieht.
func _orte() -> void:
for key in HumanDB.PLACES:
var pl: Dictionary = HumanDB.PLACES[key]
if float(pl["size"][0]) <= 0.0:
var s: Array = pl["size"]
if float(s[0]) <= 0.0:
continue
var c := Orte.center(HumanDB.PLACES, key)
var s: Array = pl["size"]
var groesse := Vector3(s[0], 2.3, s[1])
var groesse := Vector3(float(s[0]), 2.3, float(s[1]))
var farbe: Color = pl["color"]
var richtung: Vector3 = Orte.DIR_VEC[pl["dir"]]
Prims.room(self, c, groesse, farbe, farbe.darkened(0.35), richtung, 3.4, true)
Prims.label(self, c + Vector3(0, 5.0, 0), pl["name"], 0.6, Color(1, 1, 0.9))
var tuer: float = minf(3.0, minf(groesse.x, groesse.z) - 3.0)
Prims.room(self, c, groesse, farbe, farbe.darkened(0.35),
Orte.DIR_VEC[pl["dir"]], maxf(1.6, tuer), true)
Prims.label(self, c + Vector3(0, 4.4, 0), str(pl["name"]), 0.55, Color(1, 1, 0.9))
_einrichtung(c, groesse, farbe, key)
var tuer := Orte.door(HumanDB.PLACES, key)
var weg := tuer.normalized() * 15.0 - tuer
var b := Prims.box(self, (tuer + tuer.normalized() * 15.0) * 0.5 + Vector3(0, 0.03, 0),
Vector3(2.6, 0.06, weg.length()), Color(0.62, 0.58, 0.50), false)
b.rotation.y = atan2(weg.x, weg.z)
var l := OmniLight3D.new()
l.position = c + Vector3(0, 2.0, 0)
l.omni_range = 20.0
l.light_color = Color(1.0, 0.85, 0.6)
l.light_energy = 0.0
add_child(l)
_nachtlichter.append(l)
var licht := OmniLight3D.new()
licht.position = c + Vector3(0, 2.0, 0)
licht.omni_range = 16.0
licht.light_color = Color(1.0, 0.85, 0.6)
licht.light_energy = 0.0
add_child(licht)
_nachtlichter.append(licht)
## Ein paar Möbel, damit man sieht, wofür ein Raum da ist.
func _einrichtung(c: Vector3, groesse: Vector3, farbe: Color, key: String) -> void:
var h := groesse.z * 0.5 - 1.6
var w := groesse.x * 0.5 - 1.6
if key.begins_with("heim"):
Prims.box(self, c + Vector3(-w + 1.0, 0.35, -h + 1.2), Vector3(2.0, 0.7, 3.4),
Color(0.85, 0.85, 0.90)) # Bett
Prims.box(self, c + Vector3(w - 1.0, 0.75, 0), Vector3(1.6, 0.15, 2.6),
farbe.darkened(0.5)) # Schreibtisch
Prims.box(self, c + Vector3(w - 1.0, 1.05, 0), Vector3(0.9, 0.6, 0.1),
Color(0.2, 0.25, 0.3)) # Bildschirm
var w := maxf(0.5, groesse.x * 0.5 - 2.0)
var h := maxf(0.5, groesse.z * 0.5 - 2.0)
if key.begins_with("heim_"):
Prims.box(self, c + Vector3(-w * 0.6, 0.35, -h * 0.5), Vector3(1.9, 0.7, 3.0),
Color(0.85, 0.85, 0.90))
Prims.box(self, c + Vector3(w * 0.6, 0.75, 0), Vector3(1.5, 0.15, 2.2),
farbe.darkened(0.5))
Prims.box(self, c + Vector3(w * 0.6, 1.05, 0), Vector3(0.8, 0.55, 0.1),
Color(0.2, 0.25, 0.3))
elif key == "cafe":
for i in range(3):
Prims.cyl(self, c + Vector3(-3.0 + i * 3.0, 0.4, 0.5), 0.8, 0.8,
Prims.cyl(self, c + Vector3(-w * 0.5 + float(i) * w * 0.5, 0.4, 0.4), 0.7, 0.8,
Color(0.55, 0.40, 0.30))
Prims.box(self, c + Vector3(0, 0.55, -3.2), Vector3(groesse.x - 3.0, 1.1, 0.8),
Prims.box(self, c + Vector3(0, 0.55, -h * 0.7), Vector3(groesse.x - 3.0, 1.1, 0.8),
Color(0.45, 0.32, 0.24))
elif key == "buero":
for i in range(4):
Prims.box(self, c + Vector3(-4.5 + i * 3.0, 0.75, -1.0), Vector3(2.2, 0.15, 1.4),
Color(0.75, 0.75, 0.78))
for i in range(3):
Prims.box(self, c + Vector3(-w * 0.5 + float(i) * w * 0.5, 0.75, 0),
Vector3(1.6, 0.15, 1.2), Color(0.75, 0.75, 0.78))
elif key == "baeckerei":
Prims.box(self, c + Vector3(0, 0.55, 2.0), Vector3(groesse.x - 3.0, 1.1, 1.0),
Prims.box(self, c + Vector3(0, 0.55, h * 0.5), Vector3(groesse.x - 3.0, 1.1, 1.0),
Color(0.70, 0.55, 0.35))
Prims.box(self, c + Vector3(0, 0.85, -3.0), Vector3(3.0, 1.7, 1.5), Color(0.4, 0.4, 0.42))
Prims.box(self, c + Vector3(0, 0.85, -h * 0.6), Vector3(2.6, 1.7, 1.2),
Color(0.4, 0.4, 0.42))
elif key == "uni":
for i in range(3):
Prims.box(self, c + Vector3(0, 0.5, -2.0 + i * 2.2), Vector3(groesse.x - 4.0, 0.2, 0.8),
Color(0.66, 0.62, 0.58))
Prims.box(self, c + Vector3(0, 1.1, -4.0), Vector3(5.0, 1.6, 0.15), Color(0.15, 0.25, 0.20))
Prims.box(self, c + Vector3(0, 0.5, -h * 0.6 + float(i) * h * 0.6),
Vector3(groesse.x - 3.0, 0.2, 0.7), Color(0.66, 0.62, 0.58))
Prims.box(self, c + Vector3(0, 1.1, -h), Vector3(groesse.x * 0.55, 1.6, 0.15),
Color(0.15, 0.25, 0.20))
elif key == "werkstatt":
Prims.box(self, c + Vector3(0, 0.55, 0), Vector3(groesse.x - 4.0, 1.1, 1.4),
Color(0.55, 0.50, 0.48))
for i in range(3):
Prims.box(self, c + Vector3(-2.0 + i * 2.0, 1.5, -h + 0.6), Vector3(0.5, 0.9, 0.15),
Color(0.72, 0.68, 0.60), false)
Prims.box(self, c + Vector3(0, 0.6, 0), Vector3(groesse.x - 4.0, 1.2, 1.4),
Color(0.52, 0.48, 0.46))
## Der mittlere Block bleibt frei: Rasen, Teich, Bäume, Bänke. Der Park ist
## der einzige Ort im Bezirk, an dem nicht gebaut wird.
func _park() -> void:
var rng := RandomNumberGenerator.new()
rng.seed = 3
Prims.cyl(self, Vector3(-6, 0.05, 2), 4.0, 0.12, Color(0.30, 0.50, 0.72), false)
for i in range(14):
var a := rng.randf() * TAU
var r := rng.randf_range(5.0, 12.0)
var p := Vector3(cos(a) * r, 0, sin(a) * r + 2.0)
if p.length() < 4.0:
var halb: float = (float(HumanDB.ACHSEN[2]) - float(HumanDB.ACHSEN[1])) * 0.5 \
- HumanDB.ARTERIE * 0.5
Prims.box(self, Vector3(0, 0.01, 0), Vector3(halb * 2.0, 0.05, halb * 2.0),
Color(0.40, 0.58, 0.34), false)
Prims.cyl(self, Vector3(-halb * 0.4, 0.06, halb * 0.25), halb * 0.28, 0.1,
Color(0.30, 0.50, 0.72), false)
for i in range(26):
var p := Vector3(rng.randf_range(-halb, halb), 0, rng.randf_range(-halb, halb))
if p.distance_to(Vector3(-halb * 0.4, 0, halb * 0.25)) < halb * 0.38:
continue
var hoehe := rng.randf_range(2.4, 4.2)
if p.distance_to(Vector3(0, 0, 12.0)) < 6.0:
continue
var hoehe := rng.randf_range(2.6, 5.0)
Prims.cyl(self, p + Vector3(0, hoehe * 0.5, 0), 0.3, hoehe, Color(0.35, 0.26, 0.18))
Prims.sphere(self, p + Vector3(0, hoehe + 0.8, 0), rng.randf_range(1.2, 1.9),
Color(0.25, 0.5 + rng.randf() * 0.2, 0.22))
for i in range(4):
var a := TAU * float(i) / 4.0 + 0.4
var p := Vector3(cos(a) * 8.0, 0.45, sin(a) * 8.0 + 2.0)
Prims.sphere(self, p + Vector3(0, hoehe + 0.9, 0), rng.randf_range(1.3, 2.2),
Color(0.24, 0.48 + rng.randf() * 0.22, 0.22))
for i in range(5):
var a := TAU * float(i) / 5.0 + 0.4
var p := Vector3(cos(a) * halb * 0.62, 0.45, sin(a) * halb * 0.62)
var b := Prims.box(self, p, Vector3(2.4, 0.15, 0.7), Color(0.55, 0.40, 0.28))
b.rotation.y = -a
Prims.label(self, Vector3(0, 5.0, 10.0), "Stadtpark", 0.55, Color(1, 1, 0.9))
Prims.label(self, Vector3(0, 5.0, halb - 3.0), "Stadtpark", 0.6, Color(1, 1, 0.9))
func _saeule() -> void:
@@ -167,7 +203,7 @@ func _menschen() -> void:
for i in range(HumanDB.LIST.size()):
var m := Bewohner.new()
add_child(m)
m.setup(HumanDB.LIST[i], i, HumanDB.PLACES)
m.setup(HumanDB.LIST[i], i, HumanDB.PLACES, HumanDB.NETZ, HumanDB.ANKER)
humans.append(m)