This commit is contained in:
Team3
2026-09-16 20:06:38 +02:00
parent 7c4edaa439
commit a86d737d39
10 changed files with 252 additions and 96 deletions

View File

@@ -7,7 +7,7 @@ var humans: Array = []
var passanten: Array = [] # Statisten ohne Geschichte
var spieler: Node3D = null # setzt main, für den Etagenschnitt
var nav_map: RID # Navigationsnetz: Straßen, Türen, Möbel, Klötze
const HOEHE := 3.0 # Raumhöhe; Klötze sind Vielfache davon
const HOEHE := 3.0 # Raumhöhe -- alles in der Stadt ist Erdgeschoss
const NAV_ZELLE_HOCH := 0.1
var _bauten: Array = [] # alles, was der Etagenschnitt aufschneidet
@@ -66,9 +66,8 @@ func _environment() -> void:
_sky = ProceduralSkyMaterial.new()
sky.sky_material = _sky
_env.sky = sky
_env.ambient_light_source = Environment.AMBIENT_SOURCE_SKY
_env.glow_enabled = true
_env.glow_intensity = 0.35
_env.ambient_light_source = Environment.AMBIENT_SOURCE_COLOR # der Nachthimmel ist zu dunkel als Lichtquelle
_env.glow_enabled = false # Tageslicht braucht kein Leuchten; kostet ein Fünftel der Bildrate
_env.fog_enabled = true
_env.fog_density = 0.0012
we.environment = _env
@@ -76,7 +75,8 @@ func _environment() -> void:
_sun = DirectionalLight3D.new()
_sun.shadow_enabled = true
_sun.shadow_blur = 1.5
_sun.shadow_blur = 1.0
_sun.directional_shadow_max_distance = 110.0 # die Kamera sieht 60 m weit; nah und scharf statt weit und weich
add_child(_sun)
@@ -132,17 +132,16 @@ func _bebauung() -> void:
var g: Vector2 = p["size"]
if minf(g.x, g.y) < 3.0:
continue
var n := 1 + rng.randi_range(0, 3)
var hoehe := HOEHE * float(n)
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)
var hoehe := HOEHE # nur Erdgeschoss, wie alles in der Stadt
# acht Töne statt achtzig: gleiche Farbe heißt gleiches Material
var ton := Color.from_hsv(0.07 + float(rng.randi_range(0, 3)) * 0.04,
0.10 + float(rng.randi_range(0, 1)) * 0.12, 0.62 + float(rng.randi_range(0, 3)) * 0.08)
var bau := Node3D.new()
add_child(bau)
var klotz := Prims.box(bau, c + Vector3(0, hoehe * 0.5, 0), Vector3(g.x, hoehe, g.y), ton, false)
# Kollision etwas größer: so schließt sich die Fuge zum Nachbarn, niemand keilt sich hinein
Prims._add_box_body(klotz, Vector3(g.x + 0.9, hoehe, g.y + 0.9))
for f in range(n):
_fenster(bau, c + Vector3(0, HOEHE * float(f), 0), g, ton)
_fenster(bau, c, g, ton)
Prims.box(bau, 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:
@@ -167,7 +166,9 @@ func _orte() -> void:
add_child(raum)
var waende: Array = Prims.room(raum, c, groesse, farbe, farbe.darkened(0.35),
Orte.DIR_VEC[pl["dir"]], tuer, true)
_fenster(raum, c, Vector2(groesse.x, groesse.z), farbe)
var band := Node3D.new() # verschwindet drinnen mit dem Dach
add_child(band)
_fenster(band, c, Vector2(groesse.x, groesse.z), farbe, true)
_einrichtung(raum, c, groesse, farbe, key)
var wer := HumanDB.bewohner_von(key)
if not wer.is_empty():
@@ -183,19 +184,24 @@ func _orte() -> void:
add_child(dach)
Prims.box(dach, c + Vector3(0, HOEHE + 0.1, 0),
Vector3(groesse.x + 0.4, 0.2, groesse.z + 0.4), farbe.darkened(0.3))
Prims.label(self, c + Vector3(0, HOEHE + 1.6, 0), str(pl["name"]), 0.55, Color(1, 1, 0.9))
Prims.label(dach, c + Vector3(0, HOEHE + 1.6, 0), str(pl["name"]), 0.55, Color(1, 1, 0.9))
_bauten.append({"c": c, "size": Vector2(groesse.x, groesse.z), "hoch": HOEHE,
"teile": [dach], "waende": waende})
"teile": [dach, band], "waende": waende, "raum": raum})
## Ein Fensterband je Wand, damit man die Stockwerke von außen zählt.
func _fenster(parent: Node, cf: Vector3, g: Vector2, ton: Color) -> void:
## Ein Fensterband: bei Klötzen ein Kasten, der rundum eine Handbreit
## übersteht (ein Netz statt vier); bei Häusern vier dünne Streifen außen an
## den Wänden -- ein Kasten läge als Decke über dem Raum.
func _fenster(parent: Node, cf: Vector3, g: Vector2, ton: Color, hohl: bool = false) -> void:
var glas := ton.darkened(0.55).lerp(Color(0.35, 0.45, 0.6), 0.5)
if minf(g.x, g.y) < 3.4:
return
if not hohl:
Prims.box(parent, cf + Vector3(0, 1.75, 0), Vector3(g.x + 0.1, 0.9, g.y + 0.1), glas, false)
return
for d: Vector3 in [Vector3.FORWARD, Vector3.BACK, Vector3.LEFT, Vector3.RIGHT]:
var quer := absf(d.z) > 0.0
var laenge: float = (g.x if quer else g.y) - 2.4
if laenge < 1.0:
continue
var off := Vector3(d.x * (g.x * 0.5 + 0.05), 1.75, d.z * (g.y * 0.5 + 0.05))
Prims.box(parent, cf + off, Vector3(laenge, 0.9, 0.08) if quer else Vector3(0.08, 0.9, laenge),
glas, false)
@@ -390,7 +396,9 @@ func _himmel_aktualisieren() -> void:
_sky.sky_horizon_color = nacht_hor.lerp(tag_hor, sonne)
_sky.ground_horizon_color = nacht_hor.lerp(Color(0.55, 0.60, 0.55), sonne)
_sky.ground_bottom_color = nacht_top.lerp(Color(0.30, 0.38, 0.28), sonne)
_env.ambient_light_energy = 0.45 + sonne * 0.8
# nachts mondblau statt schwarz: die Stadt bleibt lesbar, die Lichter setzen Akzente
_env.ambient_light_color = Color(0.30, 0.34, 0.52).lerp(Color(0.62, 0.66, 0.74), sonne)
_env.ambient_light_energy = 1.0 - sonne * 0.35 # tags übernimmt die Sonne, sonst wäscht es aus
_env.fog_light_color = nacht_hor.lerp(tag_hor, sonne)
var nacht := 1.0 - sonne