133 lines
4.2 KiB
GDScript
133 lines
4.2 KiB
GDScript
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"
|