Herotrainstation
This commit is contained in:
Binary file not shown.
@@ -877,10 +877,10 @@ transform = Transform3D(0.08715579, -0.91147786, 0.4020097, 0, 0.4035453, 0.9149
|
|||||||
light_indirect_energy = 0.0
|
light_indirect_energy = 0.0
|
||||||
light_volumetric_fog_energy = 0.0
|
light_volumetric_fog_energy = 0.0
|
||||||
shadow_enabled = true
|
shadow_enabled = true
|
||||||
shadow_bias = 0.03
|
shadow_bias = 0.055
|
||||||
shadow_normal_bias = 0.0
|
shadow_normal_bias = 0.0
|
||||||
shadow_opacity = 0.98
|
shadow_opacity = 0.98
|
||||||
shadow_blur = 2.0
|
shadow_blur = 2.198
|
||||||
directional_shadow_fade_start = 0.647
|
directional_shadow_fade_start = 0.647
|
||||||
directional_shadow_max_distance = 200.0
|
directional_shadow_max_distance = 200.0
|
||||||
|
|
||||||
|
|||||||
@@ -10,13 +10,11 @@ extends Node3D
|
|||||||
@export var dimensione_chunk: float = 20.0
|
@export var dimensione_chunk: float = 20.0
|
||||||
@export var raggio_visivo: int = 3
|
@export var raggio_visivo: int = 3
|
||||||
@export var scala_distretti: float = 0.05
|
@export var scala_distretti: float = 0.05
|
||||||
@export var materiale_filo_palo: ShaderMaterial # <--- NUOVO MATERIALE PER I FILI
|
@export var materiale_filo_palo: ShaderMaterial
|
||||||
@export_range(0.01, 1.0) var spessore_filo: float = 0.05
|
@export_range(0.01, 1.0) var spessore_filo: float = 0.05
|
||||||
@export_range(0.0, 5.0) var forza_vento_fili: float = 1.0 # <--- SLIDER DEL VENTO
|
@export_range(0.0, 5.0) var forza_vento_fili: float = 1.0
|
||||||
|
|
||||||
# Memoria per non doppiare i fili tra due chunk
|
|
||||||
var connessioni_pali: Dictionary = {}
|
var connessioni_pali: Dictionary = {}
|
||||||
|
|
||||||
var scacchiera: Dictionary = {}
|
var scacchiera: Dictionary = {}
|
||||||
var ultima_pos_griglia_treno: Vector2i = Vector2i(999999, 999999)
|
var ultima_pos_griglia_treno: Vector2i = Vector2i(999999, 999999)
|
||||||
var generatore_rumore: FastNoiseLite
|
var generatore_rumore: FastNoiseLite
|
||||||
@@ -27,7 +25,6 @@ var dropdown_biomi: OptionButton
|
|||||||
var lbl_bioma: Label
|
var lbl_bioma: Label
|
||||||
var lbl_distanza: Label
|
var lbl_distanza: Label
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
if lista_biomi.is_empty() or path_treno == null: return
|
if lista_biomi.is_empty() or path_treno == null: return
|
||||||
|
|
||||||
@@ -49,17 +46,14 @@ func _crea_ui_gps() -> void:
|
|||||||
var canvas = CanvasLayer.new()
|
var canvas = CanvasLayer.new()
|
||||||
canvas.layer = 10
|
canvas.layer = 10
|
||||||
add_child(canvas)
|
add_child(canvas)
|
||||||
|
|
||||||
var margin = MarginContainer.new()
|
var margin = MarginContainer.new()
|
||||||
margin.set_anchors_preset(Control.PRESET_FULL_RECT)
|
margin.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||||
margin.add_theme_constant_override("margin_top", 20)
|
margin.add_theme_constant_override("margin_top", 20)
|
||||||
margin.add_theme_constant_override("margin_right", 20)
|
margin.add_theme_constant_override("margin_right", 20)
|
||||||
canvas.add_child(margin)
|
canvas.add_child(margin)
|
||||||
|
|
||||||
var vbox = VBoxContainer.new()
|
var vbox = VBoxContainer.new()
|
||||||
vbox.size_flags_horizontal = Control.SIZE_SHRINK_END
|
vbox.size_flags_horizontal = Control.SIZE_SHRINK_END
|
||||||
margin.add_child(vbox)
|
margin.add_child(vbox)
|
||||||
|
|
||||||
lbl_bioma = Label.new()
|
lbl_bioma = Label.new()
|
||||||
lbl_bioma.add_theme_font_size_override("font_size", 10)
|
lbl_bioma.add_theme_font_size_override("font_size", 10)
|
||||||
lbl_bioma.add_theme_color_override("font_color", Color(1, 0.9, 0.4))
|
lbl_bioma.add_theme_color_override("font_color", Color(1, 0.9, 0.4))
|
||||||
@@ -67,25 +61,20 @@ func _crea_ui_gps() -> void:
|
|||||||
lbl_bioma.add_theme_constant_override("outline_size", 3)
|
lbl_bioma.add_theme_constant_override("outline_size", 3)
|
||||||
lbl_bioma.text = "📍 Avvio GPS..."
|
lbl_bioma.text = "📍 Avvio GPS..."
|
||||||
vbox.add_child(lbl_bioma)
|
vbox.add_child(lbl_bioma)
|
||||||
|
|
||||||
lbl_distanza = Label.new()
|
lbl_distanza = Label.new()
|
||||||
lbl_distanza.add_theme_font_size_override("font_size", 8)
|
lbl_distanza.add_theme_font_size_override("font_size", 8)
|
||||||
lbl_distanza.add_theme_color_override("font_outline_color", Color.BLACK)
|
lbl_distanza.add_theme_color_override("font_outline_color", Color.BLACK)
|
||||||
lbl_distanza.add_theme_constant_override("outline_size", 3)
|
lbl_distanza.add_theme_constant_override("outline_size", 3)
|
||||||
lbl_distanza.text = "Calcolo tragitto..."
|
lbl_distanza.text = "Calcolo tragitto..."
|
||||||
vbox.add_child(lbl_distanza)
|
vbox.add_child(lbl_distanza)
|
||||||
|
|
||||||
var hbox = HBoxContainer.new()
|
var hbox = HBoxContainer.new()
|
||||||
vbox.add_child(hbox)
|
vbox.add_child(hbox)
|
||||||
|
|
||||||
dropdown_biomi = OptionButton.new()
|
dropdown_biomi = OptionButton.new()
|
||||||
dropdown_biomi.add_item("Dinamico (Procedurale)")
|
dropdown_biomi.add_item("Dinamico (Procedurale)")
|
||||||
for bioma in lista_biomi:
|
for bioma in lista_biomi:
|
||||||
dropdown_biomi.add_item(bioma.nome_bioma)
|
dropdown_biomi.add_item(bioma.nome_bioma)
|
||||||
|
|
||||||
dropdown_biomi.item_selected.connect(_on_dropdown_biomi_item_selected)
|
dropdown_biomi.item_selected.connect(_on_dropdown_biomi_item_selected)
|
||||||
hbox.add_child(dropdown_biomi)
|
hbox.add_child(dropdown_biomi)
|
||||||
|
|
||||||
_radar_bioma_treno()
|
_radar_bioma_treno()
|
||||||
|
|
||||||
func _aggiorna_set_pieces() -> void:
|
func _aggiorna_set_pieces() -> void:
|
||||||
@@ -93,7 +82,6 @@ func _aggiorna_set_pieces() -> void:
|
|||||||
for sp in set_pieces:
|
for sp in set_pieces:
|
||||||
if not "bioma_esclusivo" in sp or sp.bioma_esclusivo == "":
|
if not "bioma_esclusivo" in sp or sp.bioma_esclusivo == "":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
var bioma_locale = ""
|
var bioma_locale = ""
|
||||||
if bioma_manuale_attivo != null:
|
if bioma_manuale_attivo != null:
|
||||||
bioma_locale = bioma_manuale_attivo.nome_bioma
|
bioma_locale = bioma_manuale_attivo.nome_bioma
|
||||||
@@ -101,7 +89,6 @@ func _aggiorna_set_pieces() -> void:
|
|||||||
var grid_x = roundi(sp.global_position.x / dimensione_chunk)
|
var grid_x = roundi(sp.global_position.x / dimensione_chunk)
|
||||||
var grid_z = roundi(sp.global_position.z / dimensione_chunk)
|
var grid_z = roundi(sp.global_position.z / dimensione_chunk)
|
||||||
bioma_locale = _get_nome_bioma_procedurale(generatore_rumore.get_noise_2d(grid_x, grid_z))
|
bioma_locale = _get_nome_bioma_procedurale(generatore_rumore.get_noise_2d(grid_x, grid_z))
|
||||||
|
|
||||||
if bioma_locale == sp.bioma_esclusivo:
|
if bioma_locale == sp.bioma_esclusivo:
|
||||||
sp.show()
|
sp.show()
|
||||||
sp.process_mode = Node.PROCESS_MODE_INHERIT
|
sp.process_mode = Node.PROCESS_MODE_INHERIT
|
||||||
@@ -128,9 +115,6 @@ func _distruggi_e_rigenera_mondo() -> void:
|
|||||||
ultima_pos_griglia_treno = Vector2i(999999, 999999)
|
ultima_pos_griglia_treno = Vector2i(999999, 999999)
|
||||||
_radar_bioma_treno()
|
_radar_bioma_treno()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func _physics_process(_delta: float) -> void:
|
func _physics_process(_delta: float) -> void:
|
||||||
if path_treno == null or path_treno.treno_istanziato == null: return
|
if path_treno == null or path_treno.treno_istanziato == null: return
|
||||||
|
|
||||||
@@ -145,15 +129,27 @@ func _physics_process(_delta: float) -> void:
|
|||||||
_pulisci_chunk_lontani(pos_attuale)
|
_pulisci_chunk_lontani(pos_attuale)
|
||||||
_radar_bioma_treno()
|
_radar_bioma_treno()
|
||||||
|
|
||||||
# Aggiorna il vento dei fili
|
|
||||||
if materiale_filo_palo and materiale_filo_palo is ShaderMaterial:
|
if materiale_filo_palo and materiale_filo_palo is ShaderMaterial:
|
||||||
materiale_filo_palo.set_shader_parameter("forza_vento", forza_vento_fili)
|
materiale_filo_palo.set_shader_parameter("forza_vento", forza_vento_fili)
|
||||||
|
|
||||||
|
# ==========================================================
|
||||||
|
# ===== MOTORE DI RICERCA PROFONDA MULTI-CHUNK =============
|
||||||
|
# ==========================================================
|
||||||
|
|
||||||
|
# Setaccia l'intero albero e colleziona tutti i nodi InfoChunk
|
||||||
|
func _trova_tutti_nodi_info(radice: Node, lista: Array[Node]) -> void:
|
||||||
|
if radice == null: return
|
||||||
|
|
||||||
|
if radice.has_method("get_dati_ruotati") or "ha_palo_luce" in radice:
|
||||||
|
lista.append(radice)
|
||||||
|
|
||||||
|
for figlio in radice.get_children():
|
||||||
|
_trova_tutti_nodi_info(figlio, lista)
|
||||||
|
|
||||||
func _genera_attorno_al_treno(centro: Vector2i) -> void:
|
func _genera_attorno_al_treno(centro: Vector2i) -> void:
|
||||||
for x in range(-raggio_visivo, raggio_visivo + 1):
|
for x in range(-raggio_visivo, raggio_visivo + 1):
|
||||||
for z in range(-raggio_visivo, raggio_visivo + 1):
|
for z in range(-raggio_visivo, raggio_visivo + 1):
|
||||||
var pos_griglia = centro + Vector2i(x, z)
|
var pos_griglia = centro + Vector2i(x, z)
|
||||||
|
|
||||||
if not scacchiera.has(pos_griglia):
|
if not scacchiera.has(pos_griglia):
|
||||||
var ce_ostacolo = _registra_cella_con_laser(pos_griglia)
|
var ce_ostacolo = _registra_cella_con_laser(pos_griglia)
|
||||||
if not ce_ostacolo:
|
if not ce_ostacolo:
|
||||||
@@ -187,37 +183,65 @@ func _registra_cella_con_laser(pos_griglia: Vector2i) -> bool:
|
|||||||
|
|
||||||
if result.size() > 0:
|
if result.size() > 0:
|
||||||
var collider = result["collider"]
|
var collider = result["collider"]
|
||||||
var nodo_corrente = collider
|
var radice_chunk = collider
|
||||||
|
var lista_info: Array[Node] = []
|
||||||
|
|
||||||
|
# 1. Risaliamo l'albero per trovare il "Genitore" che contiene le logiche
|
||||||
|
while radice_chunk != null and radice_chunk != get_tree().root:
|
||||||
|
_trova_tutti_nodi_info(radice_chunk, lista_info)
|
||||||
|
if lista_info.size() > 0:
|
||||||
|
break
|
||||||
|
radice_chunk = radice_chunk.get_parent()
|
||||||
|
|
||||||
|
var nodo_info_corretto = null
|
||||||
|
|
||||||
|
# 2. SEZIONE MULTI-CHUNK: Scegliamo l'InfoChunk fisicamente più vicino al raggio laser in questa cella
|
||||||
|
if lista_info.size() > 0:
|
||||||
|
var min_distanza = 999999.0
|
||||||
|
var pos_centro_cella = Vector3(pos_mondo.x, 0, pos_mondo.z)
|
||||||
|
|
||||||
|
for info in lista_info:
|
||||||
|
if info is Node3D:
|
||||||
|
# Calcoliamo la distanza 2D
|
||||||
|
var pos_info = Vector3(info.global_position.x, 0, info.global_position.z)
|
||||||
|
var dist = pos_centro_cella.distance_to(pos_info)
|
||||||
|
|
||||||
|
if dist < min_distanza:
|
||||||
|
min_distanza = dist
|
||||||
|
nodo_info_corretto = info
|
||||||
|
|
||||||
|
# Fallback di sicurezza: prendiamo il primo trovato se il calcolo fallisce
|
||||||
|
if nodo_info_corretto == null and lista_info.size() > 0:
|
||||||
|
nodo_info_corretto = lista_info[0]
|
||||||
|
|
||||||
var uscite_trovate = {"nord": false, "est": false, "sud": false, "ovest": false}
|
var uscite_trovate = {"nord": false, "est": false, "sud": false, "ovest": false}
|
||||||
var altezze_trovate = {"nord": 0, "est": 0, "sud": 0, "ovest": 0}
|
var altezze_trovate = {"nord": 0, "est": 0, "sud": 0, "ovest": 0}
|
||||||
|
var ha_il_palo = false
|
||||||
|
|
||||||
# Risaliamo l'albero per trovare lo script InfoChunk
|
# 3. Estraiamo i dati dal VERO InfoChunk di QUESTA precisa cella
|
||||||
while nodo_corrente != null and nodo_corrente != get_tree().root:
|
if nodo_info_corretto != null:
|
||||||
if nodo_corrente.has_method("get_dati_ruotati"):
|
if nodo_info_corretto.has_method("get_dati_ruotati"):
|
||||||
var scatti_rotazione = roundi(rad_to_deg(nodo_corrente.global_rotation.y) / -90.0)
|
# Leggiamo la rotazione direttamente dal nodo info corretto
|
||||||
var dati = nodo_corrente.get_dati_ruotati(scatti_rotazione)
|
var scatti_rotazione = roundi(rad_to_deg(nodo_info_corretto.global_rotation.y) / -90.0)
|
||||||
|
var dati = nodo_info_corretto.get_dati_ruotati(scatti_rotazione)
|
||||||
uscite_trovate = dati["connessioni"]
|
uscite_trovate = dati["connessioni"]
|
||||||
altezze_trovate = dati["altezze"]
|
altezze_trovate = dati["altezze"]
|
||||||
break
|
|
||||||
nodo_corrente = nodo_corrente.get_parent()
|
if "ha_palo_luce" in nodo_info_corretto:
|
||||||
|
ha_il_palo = nodo_info_corretto.ha_palo_luce
|
||||||
# --- VERIFICA DEI PALI SUL PEZZO PRE-COSTRUITO ---
|
|
||||||
var ha_il_palo = false
|
# 4. Registriamo sulla scacchiera questo specifico pezzetto di mondo
|
||||||
if nodo_corrente != null and "ha_palo_luce" in nodo_corrente:
|
|
||||||
ha_il_palo = nodo_corrente.ha_palo_luce
|
|
||||||
|
|
||||||
scacchiera[pos_griglia] = {
|
scacchiera[pos_griglia] = {
|
||||||
"tipo": "ostacolo",
|
"tipo": "ostacolo",
|
||||||
"uscite": uscite_trovate,
|
"uscite": uscite_trovate,
|
||||||
"altezze": altezze_trovate,
|
"altezze": altezze_trovate,
|
||||||
"nodo": nodo_corrente,
|
"nodo": radice_chunk,
|
||||||
"ha_palo": ha_il_palo # Salviamo in memoria che questo binario ha i pali
|
"info": nodo_info_corretto,
|
||||||
|
"ha_palo": ha_il_palo
|
||||||
}
|
}
|
||||||
|
|
||||||
# MAGIA: Se il laser ha scoperto un tuo binario pre-costruito con i pali,
|
|
||||||
# lo tratta come se fosse appena spawnato e lancia i fili verso i vicini!
|
|
||||||
if ha_il_palo:
|
if ha_il_palo:
|
||||||
_collega_pali_luce(pos_griglia, nodo_corrente)
|
_collega_pali_luce(pos_griglia)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
return false
|
return false
|
||||||
@@ -241,10 +265,13 @@ func _piazza_bioma_compatibile(pos_griglia: Vector2i) -> void:
|
|||||||
|
|
||||||
for scena in catalogo_zona:
|
for scena in catalogo_zona:
|
||||||
var test_chunk = scena.instantiate()
|
var test_chunk = scena.instantiate()
|
||||||
|
var lista_test: Array[Node] = []
|
||||||
|
_trova_tutti_nodi_info(test_chunk, lista_test)
|
||||||
|
var info_test = lista_test[0] if lista_test.size() > 0 else null
|
||||||
|
|
||||||
if test_chunk.has_method("get_dati_ruotati"):
|
if info_test != null and info_test.has_method("get_dati_ruotati"):
|
||||||
for rot in range(4):
|
for rot in range(4):
|
||||||
var dati = test_chunk.get_dati_ruotati(rot)
|
var dati = info_test.get_dati_ruotati(rot)
|
||||||
var u_conn = dati["connessioni"]
|
var u_conn = dati["connessioni"]
|
||||||
var u_alt = dati["altezze"]
|
var u_alt = dati["altezze"]
|
||||||
|
|
||||||
@@ -270,7 +297,6 @@ func _piazza_bioma_compatibile(pos_griglia: Vector2i) -> void:
|
|||||||
if req_alt_est == -1 and u_alt["est"] == altitudine_target: score += 1
|
if req_alt_est == -1 and u_alt["est"] == altitudine_target: score += 1
|
||||||
if req_alt_sud == -1 and u_alt["sud"] == altitudine_target: score += 1
|
if req_alt_sud == -1 and u_alt["sud"] == altitudine_target: score += 1
|
||||||
if req_alt_ovest == -1 and u_alt["ovest"] == altitudine_target: score += 1
|
if req_alt_ovest == -1 and u_alt["ovest"] == altitudine_target: score += 1
|
||||||
|
|
||||||
candidati_validi.append({"scena": scena, "rotazione": rot, "dati": dati, "score": score})
|
candidati_validi.append({"scena": scena, "rotazione": rot, "dati": dati, "score": score})
|
||||||
|
|
||||||
test_chunk.queue_free()
|
test_chunk.queue_free()
|
||||||
@@ -279,7 +305,6 @@ func _piazza_bioma_compatibile(pos_griglia: Vector2i) -> void:
|
|||||||
var max_score = -1
|
var max_score = -1
|
||||||
for c in candidati_validi:
|
for c in candidati_validi:
|
||||||
if c.score > max_score: max_score = c.score
|
if c.score > max_score: max_score = c.score
|
||||||
|
|
||||||
var candidati_migliori = []
|
var candidati_migliori = []
|
||||||
for c in candidati_validi:
|
for c in candidati_validi:
|
||||||
if c.score == max_score: candidati_migliori.append(c)
|
if c.score == max_score: candidati_migliori.append(c)
|
||||||
@@ -290,31 +315,49 @@ func _piazza_bioma_compatibile(pos_griglia: Vector2i) -> void:
|
|||||||
nuovo_chunk.position = Vector3(pos_griglia.x * dimensione_chunk, 0, pos_griglia.y * dimensione_chunk)
|
nuovo_chunk.position = Vector3(pos_griglia.x * dimensione_chunk, 0, pos_griglia.y * dimensione_chunk)
|
||||||
nuovo_chunk.rotation.y = scelto.rotazione * (-PI / 2.0)
|
nuovo_chunk.rotation.y = scelto.rotazione * (-PI / 2.0)
|
||||||
|
|
||||||
# --- SALVATAGGIO NELLA SCACCHIERA INCLUDENDO IL PALO ---
|
var lista_nuovo: Array[Node] = []
|
||||||
var ha_il_palo = "ha_palo_luce" in nuovo_chunk and nuovo_chunk.ha_palo_luce
|
_trova_tutti_nodi_info(nuovo_chunk, lista_nuovo)
|
||||||
|
var info_nuovo = lista_nuovo[0] if lista_nuovo.size() > 0 else null
|
||||||
|
|
||||||
|
var ha_il_palo = false
|
||||||
|
if info_nuovo != null and "ha_palo_luce" in info_nuovo:
|
||||||
|
ha_il_palo = info_nuovo.ha_palo_luce
|
||||||
|
|
||||||
scacchiera[pos_griglia] = {
|
scacchiera[pos_griglia] = {
|
||||||
"tipo": "bioma",
|
"tipo": "bioma",
|
||||||
"uscite": scelto.dati["connessioni"],
|
"uscite": scelto.dati["connessioni"],
|
||||||
"altezze": scelto.dati["altezze"],
|
"altezze": scelto.dati["altezze"],
|
||||||
"nodo": nuovo_chunk,
|
"nodo": nuovo_chunk,
|
||||||
|
"info": info_nuovo,
|
||||||
"ha_palo": ha_il_palo
|
"ha_palo": ha_il_palo
|
||||||
}
|
}
|
||||||
|
|
||||||
# Se il chunk appena piazzato ha un palo, lanciamo i fili verso un vicino
|
|
||||||
if ha_il_palo:
|
if ha_il_palo:
|
||||||
_collega_pali_luce(pos_griglia, nuovo_chunk)
|
_collega_pali_luce(pos_griglia)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
var backup = catalogo_zona[0].instantiate()
|
var backup = catalogo_zona[0].instantiate()
|
||||||
add_child(backup)
|
add_child(backup)
|
||||||
backup.position = Vector3(pos_griglia.x * dimensione_chunk, 0, pos_griglia.y * dimensione_chunk)
|
backup.position = Vector3(pos_griglia.x * dimensione_chunk, 0, pos_griglia.y * dimensione_chunk)
|
||||||
|
|
||||||
|
var lista_backup: Array[Node] = []
|
||||||
|
_trova_tutti_nodi_info(backup, lista_backup)
|
||||||
|
var info_backup = lista_backup[0] if lista_backup.size() > 0 else null
|
||||||
|
|
||||||
var altezze_sicure = {
|
var altezze_sicure = {
|
||||||
"nord": req_alt_nord if req_alt_nord != -1 else altitudine_target,
|
"nord": req_alt_nord if req_alt_nord != -1 else altitudine_target,
|
||||||
"est": req_alt_est if req_alt_est != -1 else altitudine_target,
|
"est": req_alt_est if req_alt_est != -1 else altitudine_target,
|
||||||
"sud": req_alt_sud if req_alt_sud != -1 else altitudine_target,
|
"sud": req_alt_sud if req_alt_sud != -1 else altitudine_target,
|
||||||
"ovest": req_alt_ovest if req_alt_ovest != -1 else altitudine_target
|
"ovest": req_alt_ovest if req_alt_ovest != -1 else altitudine_target
|
||||||
}
|
}
|
||||||
scacchiera[pos_griglia] = {"tipo": "bioma", "uscite": {"nord":false, "est":false, "sud":false, "ovest":false}, "altezze": altezze_sicure, "nodo": backup, "ha_palo": false}
|
scacchiera[pos_griglia] = {
|
||||||
|
"tipo": "bioma",
|
||||||
|
"uscite": {"nord":false, "est":false, "sud":false, "ovest":false},
|
||||||
|
"altezze": altezze_sicure,
|
||||||
|
"nodo": backup,
|
||||||
|
"info": info_backup,
|
||||||
|
"ha_palo": false
|
||||||
|
}
|
||||||
|
|
||||||
func _richiede_connessione(pos_vicino: Vector2i, lato_richiesto: String) -> int:
|
func _richiede_connessione(pos_vicino: Vector2i, lato_richiesto: String) -> int:
|
||||||
if not scacchiera.has(pos_vicino):
|
if not scacchiera.has(pos_vicino):
|
||||||
@@ -376,6 +419,7 @@ func _pulisci_chunk_lontani(centro_attuale: Vector2i) -> void:
|
|||||||
|
|
||||||
if dist_x > raggio_visivo + margine_sicurezza or dist_z > raggio_visivo + margine_sicurezza:
|
if dist_x > raggio_visivo + margine_sicurezza or dist_z > raggio_visivo + margine_sicurezza:
|
||||||
if cella.has("nodo") and is_instance_valid(cella["nodo"]):
|
if cella.has("nodo") and is_instance_valid(cella["nodo"]):
|
||||||
|
# Questo distruggerà tutto il chunk, inclusi i fili ad esso agganciati
|
||||||
cella["nodo"].queue_free()
|
cella["nodo"].queue_free()
|
||||||
celle_da_rimuovere.append(pos_griglia)
|
celle_da_rimuovere.append(pos_griglia)
|
||||||
|
|
||||||
@@ -386,67 +430,65 @@ func _pulisci_chunk_lontani(centro_attuale: Vector2i) -> void:
|
|||||||
# ============ NUOVE FUNZIONI FILI DELLA LUCE ==============
|
# ============ NUOVE FUNZIONI FILI DELLA LUCE ==============
|
||||||
# ==========================================================
|
# ==========================================================
|
||||||
|
|
||||||
# --- 1. FUNZIONE SCUDO: Trova i pali anche se hai dimenticato di aggiornare l'Inspector ---
|
func _ottieni_pali(nodo_info: Node, lato: String) -> Array[Node3D]:
|
||||||
# --- 1. FUNZIONE SCUDO (Più sicura contro i nodi nulli) ---
|
|
||||||
func _ottieni_pali(chunk: Node3D, lato: String) -> Array[Node3D]:
|
|
||||||
var pali: Array[Node3D] = []
|
var pali: Array[Node3D] = []
|
||||||
if lato == "sx":
|
if lato == "sx":
|
||||||
if "attacchi_sx" in chunk and chunk.attacchi_sx != null:
|
if "attacchi_sx" in nodo_info and nodo_info.attacchi_sx != null:
|
||||||
for p in chunk.attacchi_sx:
|
for p in nodo_info.attacchi_sx:
|
||||||
if is_instance_valid(p): pali.append(p)
|
if is_instance_valid(p): pali.append(p)
|
||||||
# Se l'array è vuoto, usa il vecchio nodo singolo
|
if pali.is_empty() and "nodo_attacco_sx" in nodo_info and is_instance_valid(nodo_info.get("nodo_attacco_sx")):
|
||||||
if pali.is_empty() and "nodo_attacco_sx" in chunk and is_instance_valid(chunk.get("nodo_attacco_sx")):
|
pali.append(nodo_info.get("nodo_attacco_sx"))
|
||||||
pali.append(chunk.get("nodo_attacco_sx"))
|
|
||||||
else:
|
else:
|
||||||
if "attacchi_dx" in chunk and chunk.attacchi_dx != null:
|
if "attacchi_dx" in nodo_info and nodo_info.attacchi_dx != null:
|
||||||
for p in chunk.attacchi_dx:
|
for p in nodo_info.attacchi_dx:
|
||||||
if is_instance_valid(p): pali.append(p)
|
if is_instance_valid(p): pali.append(p)
|
||||||
if pali.is_empty() and "nodo_attacco_dx" in chunk and is_instance_valid(chunk.get("nodo_attacco_dx")):
|
if pali.is_empty() and "nodo_attacco_dx" in nodo_info and is_instance_valid(nodo_info.get("nodo_attacco_dx")):
|
||||||
pali.append(chunk.get("nodo_attacco_dx"))
|
pali.append(nodo_info.get("nodo_attacco_dx"))
|
||||||
return pali
|
return pali
|
||||||
|
|
||||||
# --- 2. LA LOGICA DI COLLEGAMENTO (Raggio Ampio) ---
|
func _collega_pali_luce(pos_griglia_nuovo: Vector2i) -> void:
|
||||||
func _collega_pali_luce(pos_griglia_nuovo: Vector2i, chunk_nuovo: Node3D) -> void:
|
var cella_nuova = scacchiera[pos_griglia_nuovo]
|
||||||
if chunk_nuovo is Node3D: chunk_nuovo.force_update_transform()
|
var radice_nuovo = cella_nuova["nodo"]
|
||||||
|
var info_nuovo = cella_nuova["info"]
|
||||||
|
|
||||||
|
if info_nuovo == null: return
|
||||||
|
if info_nuovo is Node3D: info_nuovo.force_update_transform()
|
||||||
|
|
||||||
var sx_nuovi = _ottieni_pali(chunk_nuovo, "sx")
|
var sx_nuovi = _ottieni_pali(info_nuovo, "sx")
|
||||||
var dx_nuovi = _ottieni_pali(chunk_nuovo, "dx")
|
var dx_nuovi = _ottieni_pali(info_nuovo, "dx")
|
||||||
if sx_nuovi.is_empty() or dx_nuovi.is_empty(): return
|
if sx_nuovi.is_empty() or dx_nuovi.is_empty(): return
|
||||||
|
|
||||||
var id_nuovo = chunk_nuovo.get_instance_id()
|
var id_nuovo = radice_nuovo.get_instance_id()
|
||||||
if not connessioni_pali.has(id_nuovo): connessioni_pali[id_nuovo] = 0
|
if not connessioni_pali.has(id_nuovo): connessioni_pali[id_nuovo] = 0
|
||||||
|
|
||||||
# Se ha già 2 fili, si ferma qui.
|
|
||||||
if connessioni_pali[id_nuovo] >= 2: return
|
if connessioni_pali[id_nuovo] >= 2: return
|
||||||
|
|
||||||
var p_sx_mio_best = null; var p_dx_mio_best = null
|
var p_sx_mio_best = null; var p_dx_mio_best = null
|
||||||
var p_sx_tuo_best = null; var p_dx_tuo_best = null
|
var p_sx_tuo_best = null; var p_dx_tuo_best = null
|
||||||
var miglior_vicino = null
|
var miglior_vicino_radice = null
|
||||||
var miglior_distanza = 999999.0
|
var miglior_distanza = 999999.0
|
||||||
|
|
||||||
# RAGGIO GIGANTE: Scansioniamo un'area 13x13 celle (circa 260 metri!)
|
|
||||||
# Questo garantisce che nessun palo venga MAI saltato, anche nelle curve più larghe.
|
|
||||||
var raggio_ricerca = 3
|
var raggio_ricerca = 3
|
||||||
|
|
||||||
# FASE 1: Cerchiamo un palo "pulito" (con meno di 2 fili)
|
|
||||||
for x in range(-raggio_ricerca, raggio_ricerca + 1):
|
for x in range(-raggio_ricerca, raggio_ricerca + 1):
|
||||||
for z in range(-raggio_ricerca, raggio_ricerca + 1):
|
for z in range(-raggio_ricerca, raggio_ricerca + 1):
|
||||||
if x == 0 and z == 0: continue
|
if x == 0 and z == 0: continue
|
||||||
|
|
||||||
var pos_vicino = pos_griglia_nuovo + Vector2i(x, z)
|
var pos_vicino = pos_griglia_nuovo + Vector2i(x, z)
|
||||||
if scacchiera.has(pos_vicino) and scacchiera[pos_vicino].get("ha_palo", false):
|
if scacchiera.has(pos_vicino) and scacchiera[pos_vicino].get("ha_palo", false):
|
||||||
var chunk_vicino = scacchiera[pos_vicino]["nodo"]
|
var radice_vicino = scacchiera[pos_vicino]["nodo"]
|
||||||
if not is_instance_valid(chunk_vicino) or chunk_vicino == chunk_nuovo: continue
|
var info_vicino = scacchiera[pos_vicino]["info"]
|
||||||
|
|
||||||
var id_vicino = chunk_vicino.get_instance_id()
|
if not is_instance_valid(radice_vicino) or radice_vicino == radice_nuovo or info_vicino == null: continue
|
||||||
|
|
||||||
|
var id_vicino = radice_vicino.get_instance_id()
|
||||||
var conn_vicino = connessioni_pali.get(id_vicino, 0)
|
var conn_vicino = connessioni_pali.get(id_vicino, 0)
|
||||||
|
|
||||||
# Ignoriamo i pali già pieni
|
|
||||||
if conn_vicino >= 2: continue
|
if conn_vicino >= 2: continue
|
||||||
|
|
||||||
if chunk_vicino is Node3D: chunk_vicino.force_update_transform()
|
if info_vicino is Node3D: info_vicino.force_update_transform()
|
||||||
var sx_vicini = _ottieni_pali(chunk_vicino, "sx")
|
var sx_vicini = _ottieni_pali(info_vicino, "sx")
|
||||||
var dx_vicini = _ottieni_pali(chunk_vicino, "dx")
|
var dx_vicini = _ottieni_pali(info_vicino, "dx")
|
||||||
if sx_vicini.is_empty() or dx_vicini.is_empty(): continue
|
if sx_vicini.is_empty() or dx_vicini.is_empty(): continue
|
||||||
|
|
||||||
for i_m in range(sx_nuovi.size()):
|
for i_m in range(sx_nuovi.size()):
|
||||||
@@ -457,27 +499,27 @@ func _collega_pali_luce(pos_griglia_nuovo: Vector2i, chunk_nuovo: Node3D) -> voi
|
|||||||
|
|
||||||
if dist < miglior_distanza:
|
if dist < miglior_distanza:
|
||||||
miglior_distanza = dist
|
miglior_distanza = dist
|
||||||
miglior_vicino = chunk_vicino
|
miglior_vicino_radice = radice_vicino
|
||||||
p_sx_mio_best = sx_nuovi[i_m]
|
p_sx_mio_best = sx_nuovi[i_m]
|
||||||
p_dx_mio_best = dx_nuovi[i_m]
|
p_dx_mio_best = dx_nuovi[i_m]
|
||||||
p_sx_tuo_best = sx_vicini[i_t]
|
p_sx_tuo_best = sx_vicini[i_t]
|
||||||
p_dx_tuo_best = dx_vicini[i_t]
|
p_dx_tuo_best = dx_vicini[i_t]
|
||||||
|
|
||||||
# FASE 2 (Estrema Razio): Se c'è un buco enorme e non troviamo pali "puliti",
|
if miglior_vicino_radice == null:
|
||||||
# ci leghiamo a QUALSIASI palo nel raggio di 260m pur di non rimanere isolati.
|
|
||||||
if miglior_vicino == null:
|
|
||||||
for x in range(-raggio_ricerca, raggio_ricerca + 1):
|
for x in range(-raggio_ricerca, raggio_ricerca + 1):
|
||||||
for z in range(-raggio_ricerca, raggio_ricerca + 1):
|
for z in range(-raggio_ricerca, raggio_ricerca + 1):
|
||||||
if x == 0 and z == 0: continue
|
if x == 0 and z == 0: continue
|
||||||
|
|
||||||
var pos_vicino = pos_griglia_nuovo + Vector2i(x, z)
|
var pos_vicino = pos_griglia_nuovo + Vector2i(x, z)
|
||||||
if scacchiera.has(pos_vicino) and scacchiera[pos_vicino].get("ha_palo", false):
|
if scacchiera.has(pos_vicino) and scacchiera[pos_vicino].get("ha_palo", false):
|
||||||
var chunk_vicino = scacchiera[pos_vicino]["nodo"]
|
var radice_vicino = scacchiera[pos_vicino]["nodo"]
|
||||||
if not is_instance_valid(chunk_vicino) or chunk_vicino == chunk_nuovo: continue
|
var info_vicino = scacchiera[pos_vicino]["info"]
|
||||||
|
|
||||||
if chunk_vicino is Node3D: chunk_vicino.force_update_transform()
|
if not is_instance_valid(radice_vicino) or radice_vicino == radice_nuovo or info_vicino == null: continue
|
||||||
var sx_vicini = _ottieni_pali(chunk_vicino, "sx")
|
|
||||||
var dx_vicini = _ottieni_pali(chunk_vicino, "dx")
|
if info_vicino is Node3D: info_vicino.force_update_transform()
|
||||||
|
var sx_vicini = _ottieni_pali(info_vicino, "sx")
|
||||||
|
var dx_vicini = _ottieni_pali(info_vicino, "dx")
|
||||||
if sx_vicini.is_empty() or dx_vicini.is_empty(): continue
|
if sx_vicini.is_empty() or dx_vicini.is_empty(): continue
|
||||||
|
|
||||||
for i_m in range(sx_nuovi.size()):
|
for i_m in range(sx_nuovi.size()):
|
||||||
@@ -488,29 +530,27 @@ func _collega_pali_luce(pos_griglia_nuovo: Vector2i, chunk_nuovo: Node3D) -> voi
|
|||||||
|
|
||||||
if dist < miglior_distanza:
|
if dist < miglior_distanza:
|
||||||
miglior_distanza = dist
|
miglior_distanza = dist
|
||||||
miglior_vicino = chunk_vicino
|
miglior_vicino_radice = radice_vicino
|
||||||
p_sx_mio_best = sx_nuovi[i_m]
|
p_sx_mio_best = sx_nuovi[i_m]
|
||||||
p_dx_mio_best = dx_nuovi[i_m]
|
p_dx_mio_best = dx_nuovi[i_m]
|
||||||
p_sx_tuo_best = sx_vicini[i_t]
|
p_sx_tuo_best = sx_vicini[i_t]
|
||||||
p_dx_tuo_best = dx_vicini[i_t]
|
p_dx_tuo_best = dx_vicini[i_t]
|
||||||
|
|
||||||
# CREAZIONE DEL COLLEGAMENTO
|
|
||||||
# Abbiamo allungato la tolleranza a 8 chunk (160 metri) per permettere fili lunghissimi se necessari!
|
|
||||||
var max_dist = dimensione_chunk * 8.0
|
var max_dist = dimensione_chunk * 8.0
|
||||||
|
|
||||||
if miglior_vicino != null and miglior_distanza < max_dist:
|
if miglior_vicino_radice != null and miglior_distanza < max_dist:
|
||||||
var dist_dritto = p_sx_mio_best.global_position.distance_to(p_sx_tuo_best.global_position) + p_dx_mio_best.global_position.distance_to(p_dx_tuo_best.global_position)
|
var dist_dritto = p_sx_mio_best.global_position.distance_to(p_sx_tuo_best.global_position) + p_dx_mio_best.global_position.distance_to(p_dx_tuo_best.global_position)
|
||||||
var dist_incrocio = p_sx_mio_best.global_position.distance_to(p_dx_tuo_best.global_position) + p_dx_mio_best.global_position.distance_to(p_sx_tuo_best.global_position)
|
var dist_incrocio = p_sx_mio_best.global_position.distance_to(p_dx_tuo_best.global_position) + p_dx_mio_best.global_position.distance_to(p_sx_tuo_best.global_position)
|
||||||
|
|
||||||
if dist_dritto <= dist_incrocio:
|
if dist_dritto <= dist_incrocio:
|
||||||
_disegna_parabola(p_sx_mio_best.global_position, p_sx_tuo_best.global_position, chunk_nuovo)
|
_disegna_parabola(p_sx_mio_best.global_position, p_sx_tuo_best.global_position, radice_nuovo)
|
||||||
_disegna_parabola(p_dx_mio_best.global_position, p_dx_tuo_best.global_position, chunk_nuovo)
|
_disegna_parabola(p_dx_mio_best.global_position, p_dx_tuo_best.global_position, radice_nuovo)
|
||||||
else:
|
else:
|
||||||
_disegna_parabola(p_sx_mio_best.global_position, p_dx_tuo_best.global_position, chunk_nuovo)
|
_disegna_parabola(p_sx_mio_best.global_position, p_dx_tuo_best.global_position, radice_nuovo)
|
||||||
_disegna_parabola(p_dx_mio_best.global_position, p_sx_tuo_best.global_position, chunk_nuovo)
|
_disegna_parabola(p_dx_mio_best.global_position, p_sx_tuo_best.global_position, radice_nuovo)
|
||||||
|
|
||||||
connessioni_pali[id_nuovo] += 1
|
connessioni_pali[id_nuovo] += 1
|
||||||
var id_vicino = miglior_vicino.get_instance_id()
|
var id_vicino = miglior_vicino_radice.get_instance_id()
|
||||||
if not connessioni_pali.has(id_vicino): connessioni_pali[id_vicino] = 0
|
if not connessioni_pali.has(id_vicino): connessioni_pali[id_vicino] = 0
|
||||||
connessioni_pali[id_vicino] += 1
|
connessioni_pali[id_vicino] += 1
|
||||||
|
|
||||||
@@ -518,7 +558,7 @@ func _disegna_parabola(p1: Vector3, p2: Vector3, genitore: Node3D) -> void:
|
|||||||
var segmenti = 15
|
var segmenti = 15
|
||||||
var abbassamento = 1.5
|
var abbassamento = 1.5
|
||||||
var punti_curva = []
|
var punti_curva = []
|
||||||
var sag_factors = [] # Salva quanto è "al centro" ogni punto
|
var sag_factors = []
|
||||||
|
|
||||||
for i in range(segmenti + 1):
|
for i in range(segmenti + 1):
|
||||||
var t = float(i) / float(segmenti)
|
var t = float(i) / float(segmenti)
|
||||||
@@ -527,8 +567,6 @@ func _disegna_parabola(p1: Vector3, p2: Vector3, genitore: Node3D) -> void:
|
|||||||
pos_globale.y -= gravita
|
pos_globale.y -= gravita
|
||||||
|
|
||||||
punti_curva.append(genitore.to_local(pos_globale))
|
punti_curva.append(genitore.to_local(pos_globale))
|
||||||
|
|
||||||
# Curva del vento: 0 agli estremi, 1.0 al centro spaccato
|
|
||||||
sag_factors.append(sin(t * PI))
|
sag_factors.append(sin(t * PI))
|
||||||
|
|
||||||
var st = SurfaceTool.new()
|
var st = SurfaceTool.new()
|
||||||
@@ -556,7 +594,6 @@ func _disegna_parabola(p1: Vector3, p2: Vector3, genitore: Node3D) -> void:
|
|||||||
var offset1 = (right * cos(ang1) + up * sin(ang1)) * raggio
|
var offset1 = (right * cos(ang1) + up * sin(ang1)) * raggio
|
||||||
var offset2 = (right * cos(ang2) + up * sin(ang2)) * raggio
|
var offset2 = (right * cos(ang2) + up * sin(ang2)) * raggio
|
||||||
|
|
||||||
# Diciamo al colore del vertice quanto può muoversi con il vento!
|
|
||||||
st.set_color(Color(sag_corrente, 0, 0, 1))
|
st.set_color(Color(sag_corrente, 0, 0, 1))
|
||||||
st.add_vertex(p_corrente + offset1)
|
st.add_vertex(p_corrente + offset1)
|
||||||
st.set_color(Color(sag_corrente, 0, 0, 1))
|
st.set_color(Color(sag_corrente, 0, 0, 1))
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user