extends Node3D signal mappa_pronta @export_group("Impostazioni Mappa") @export var dimensione_chunk: float = 10.0 @export var lunghezza_percorso: int = 15 @export var larghezza_bioma: int = 5 @export var OFFSET_ROTATION: float = 0.0 # Regola qui se i pezzi nascono storti @export_group("Cataloghi") @export var scena_dritto: PackedScene @export var scena_curva: PackedScene @export var catalogo_bioma: Array[PackedScene] @export var path_treno: Path3D var mappa_virtuale: Dictionary = {} func _ready() -> void: mappa_virtuale.clear() if path_treno and path_treno.curve: path_treno.curve.clear_points() if scena_dritto and scena_curva: _genera_tutto() else: print("MANCANO GLI ASSET NELL'INSPECTOR!") func _genera_tutto() -> void: _genera_binari() _genera_bioma() emit_signal("mappa_pronta") # --- FASE 1: I BINARI (Logica 3x3) --- func _genera_binari() -> void: var pos_corrente = Vector2i(0, 0) var dir_corrente = Vector2i(0, -1) # Inizia verso Nord for i in range(lunghezza_percorso): var tipo = "dritto" if i > 2: tipo = "curva" if randf() > 0.6 else "dritto" if tipo == "dritto": _piazza_dritto(pos_corrente, dir_corrente) pos_corrente += dir_corrente else: var verso_destra = randf() > 0.5 var nuova_dir = Vector2i(-dir_corrente.y, dir_corrente.x) if verso_destra else Vector2i(dir_corrente.y, -dir_corrente.x) # In un 3x3, la curva occupa: # 1. Cella ingresso (dove siamo) # 2. Cella centrale (pivot) # 3. Cella uscita var cella_ingresso = pos_corrente var cella_centro = pos_corrente + dir_corrente var cella_uscita = cella_centro + nuova_dir _piazza_curva(cella_centro, dir_corrente, verso_destra) # Occupiamo le celle nella mappa per il bioma mappa_virtuale[cella_ingresso] = "binario" mappa_virtuale[cella_centro] = "binario" mappa_virtuale[cella_uscita] = "binario" # Occupiamo anche l'angolo interno della L per sicurezza mappa_virtuale[cella_ingresso + nuova_dir] = "binario" # Il prossimo pezzo parte dopo l'uscita pos_corrente = cella_uscita + nuova_dir dir_corrente = nuova_dir func _piazza_dritto(pos: Vector2i, dir: Vector2i) -> void: var d = scena_dritto.instantiate() add_child(d) d.position = Vector3(pos.x * dimensione_chunk, 0, pos.y * dimensione_chunk) d.rotation.y = _get_angolo_da_dir(dir) mappa_virtuale[pos] = "binario" _aggiungi_punti_path(d) func _piazza_curva(pos_centro: Vector2i, dir_ingresso: Vector2i, destra: bool) -> void: var c = scena_curva.instantiate() add_child(c) # Il pivot รจ al centro della 3x3, quindi lo piazziamo sulla cella centrale c.position = Vector3(pos_centro.x * dimensione_chunk, 0, pos_centro.y * dimensione_chunk) # Rotazione basata sulla direzione da cui entriamo c.rotation.y = _get_angolo_da_dir(dir_ingresso) if not destra: c.scale.x = -1 # Specchia per curva a sinistra # Se dopo lo specchio la curva guarda indietro, decommenta la riga sotto: # c.rotate_y(deg_to_rad(180)) _aggiungi_punti_path(c) func _get_angolo_da_dir(dir: Vector2i) -> float: var ang = 0.0 if dir == Vector2i(0, -1): ang = 0.0 # Nord elif dir == Vector2i(1, 0): ang = -PI/2.0 # Est elif dir == Vector2i(0, 1): ang = PI # Sud elif dir == Vector2i(-1, 0): ang = PI/2.0 # Ovest return ang + deg_to_rad(OFFSET_ROTATION) func _aggiungi_punti_path(chunk: Node3D) -> void: if not path_treno: return for i in range(1, 10): var m = chunk.find_child("Punto_" + str(i), true, false) if m: path_treno.curve.add_point(path_treno.to_local(m.global_position)) else: break # --- FASE 2: IL BIOMA (Onda BFS) --- func _genera_bioma() -> void: var coda = [] for p in mappa_virtuale.keys(): coda.append({"p": p, "d": 0}) while coda.size() > 0: var curr = coda.pop_front() if curr.d >= larghezza_bioma: continue for off in [Vector2i(0,1), Vector2i(0,-1), Vector2i(1,0), Vector2i(-1,0)]: var v = curr.p + off if not mappa_virtuale.has(v): _piazza_bioma(v) coda.append({"p": v, "d": curr.d + 1}) func _piazza_bioma(pos: Vector2i) -> void: var b = catalogo_bioma.pick_random().instantiate() add_child(b) b.position = Vector3(pos.x * dimensione_chunk, 0, pos.y * dimensione_chunk) b.rotation.y = (randi() % 4) * (PI/2) mappa_virtuale[pos] = "bioma"