From 8e1ba915a21b9944f288b25da4e1fb429de91c3f Mon Sep 17 00:00:00 2001 From: Overside srl Date: Mon, 4 May 2026 23:43:22 +0200 Subject: [PATCH] add scenes --- core/biome_generator/biome_generator.gd | 134 ++++++++++++++++++ core/ui_events.gd | 4 + docs/museums/biome_generator/museum_map.tscn | 15 ++ docs/museums/daynight/control.gd | 3 + .../scene/chunk_railway_station_hero.tscn | 1 + .../scene/chunk_railway_straight_2.tscn | 1 + .../scene/chunk_railway_straight_bridge.tscn | 1 + 7 files changed, 159 insertions(+) diff --git a/core/biome_generator/biome_generator.gd b/core/biome_generator/biome_generator.gd index 436a97e..ec0dbaa 100644 --- a/core/biome_generator/biome_generator.gd +++ b/core/biome_generator/biome_generator.gd @@ -1,8 +1,13 @@ extends Node3D +const CHUNK_TYPE_BIOME: int = 0 +const CHUNK_TYPE_STRAIGHT_TRACK: int = 1 +const CHUNK_TYPE_CURVED_TRACK: int = 2 + const CHUNK_GENERATION_STEPS_PER_FRAME: int = 2 const CHUNK_CLEANUP_STEPS_PER_FRAME: int = 4 const LAMPPOST_WIRE_STEPS_PER_FRAME: int = 1 +const RAILWAY_SCENE_DIRECTORY: String = "res://tgcc/chunk/railway/scene" @export_group("Rails") @export var rail_path: Path3D @@ -31,11 +36,15 @@ var pending_cleanup_cells: Array[Vector2i] = [] var pending_wire_cells: Array[Vector2i] = [] var pending_wire_lookup: Dictionary = {} var pending_radar_update: bool = false +var rail_chunk_catalogue: Dictionary = {} var manual_biome: Biome = null func _ready() -> void: if biome_list.is_empty() or rail_path == null: return + + #connect events + UIEvents.update_rail_chunks.connect(_update_rail_chunks) noise_generator = FastNoiseLite.new() noise_generator.noise_type = FastNoiseLite.TYPE_PERLIN @@ -48,6 +57,7 @@ func _ready() -> void: altitude_generator.frequency = district_scale * 0.5 _warm_chunk_candidate_cache() + _warm_rail_chunk_catalogue() _update_set_pieces() func _update_set_pieces() -> void: @@ -154,6 +164,28 @@ func _warm_chunk_candidate_cache() -> void: for scene in unique_scenes.values(): _get_chunk_scene_metadata(scene) +func _warm_rail_chunk_catalogue() -> void: + rail_chunk_catalogue.clear() + + var directory := DirAccess.open(RAILWAY_SCENE_DIRECTORY) + if directory == null: + return + + directory.list_dir_begin() + var file_name := directory.get_next() + while file_name != "": + if not directory.current_is_dir() and file_name.ends_with(".tscn"): + var scene_path := "%s/%s" % [RAILWAY_SCENE_DIRECTORY, file_name] + var scene := load(scene_path) as PackedScene + if scene != null: + var chunk_type = _get_chunk_type_from_scene(scene) + if chunk_type == CHUNK_TYPE_STRAIGHT_TRACK or chunk_type == CHUNK_TYPE_CURVED_TRACK: + if not rail_chunk_catalogue.has(chunk_type): + rail_chunk_catalogue[chunk_type] = [] + rail_chunk_catalogue[chunk_type].append(scene) + file_name = directory.get_next() + directory.list_dir_end() + func _get_chunk_scene_cache_key(scene: PackedScene) -> String: if scene == null: return "" @@ -209,6 +241,20 @@ func _get_cached_chunk_info(instance: Node, scene: PackedScene) -> Node: return instance return instance.get_node_or_null(info_path) +func _get_chunk_type_from_scene(scene: PackedScene) -> int: + if scene == null: + return CHUNK_TYPE_BIOME + + var preview_chunk = scene.instantiate() + var info_list: Array[Node] = [] + collect_all_chunkinfo(preview_chunk, info_list) + var info_node = info_list[0] if info_list.size() > 0 else null + var chunk_type = CHUNK_TYPE_BIOME + if info_node != null and "chunk_type" in info_node: + chunk_type = info_node.chunk_type + preview_chunk.queue_free() + return chunk_type + func _clear_pending_world_work() -> void: pending_generation_cells.clear() pending_cleanup_cells.clear() @@ -216,6 +262,94 @@ func _clear_pending_world_work() -> void: pending_wire_lookup.clear() pending_radar_update = false +func _collect_replaceable_rail_chunks(root: Node, result: Array[Node3D]) -> void: + if root == null: + return + + if root is Node3D: + var node_3d := root as Node3D + if node_3d.scene_file_path.begins_with(RAILWAY_SCENE_DIRECTORY): + var info_list: Array[Node] = [] + collect_all_chunkinfo(node_3d, info_list) + var info_node = info_list[0] if info_list.size() > 0 else null + if info_node != null and "chunk_type" in info_node: + var chunk_type = info_node.chunk_type + if chunk_type == CHUNK_TYPE_STRAIGHT_TRACK or chunk_type == CHUNK_TYPE_CURVED_TRACK: + result.append(node_3d) + return + + for child in root.get_children(): + _collect_replaceable_rail_chunks(child, result) + +func _pick_replacement_rail_scene(chunk_type: int, current_scene_path: String) -> PackedScene: + var candidates: Array = rail_chunk_catalogue.get(chunk_type, []) + if candidates.is_empty(): + return null + + var alternatives: Array[PackedScene] = [] + for candidate in candidates: + var scene := candidate as PackedScene + if scene != null and scene.resource_path != current_scene_path: + alternatives.append(scene) + + if not alternatives.is_empty(): + return alternatives.pick_random() + return candidates.pick_random() as PackedScene + +func _replace_rail_chunk_instance(chunk_root: Node3D) -> bool: + if chunk_root == null or not is_instance_valid(chunk_root): + return false + + var info_list: Array[Node] = [] + collect_all_chunkinfo(chunk_root, info_list) + var info_node = info_list[0] if info_list.size() > 0 else null + if info_node == null or not "chunk_type" in info_node: + return false + + var replacement_scene = _pick_replacement_rail_scene(info_node.chunk_type, chunk_root.scene_file_path) + if replacement_scene == null: + return false + + var chunk_parent = chunk_root.get_parent() + var replacement = replacement_scene.instantiate() as Node3D + if chunk_parent == null or replacement == null: + return false + + var chunk_index = chunk_root.get_index() + var chunk_name = chunk_root.name + chunk_root.name = "%s_old" % chunk_name + + replacement.transform = chunk_root.transform + chunk_parent.add_child(replacement) + chunk_parent.move_child(replacement, chunk_index) + replacement.name = chunk_name + replacement.owner = chunk_root.owner + chunk_root.queue_free() + return true + +func _refresh_rail_chunks() -> void: + print("update rail chunks") + _warm_rail_chunk_catalogue() + + var current_scene: Node = get_tree().current_scene + if current_scene == null: + return + + var replaceable_chunks: Array[Node3D] = [] + _collect_replaceable_rail_chunks(current_scene, replaceable_chunks) + + var replaced_count = 0 + for chunk_root in replaceable_chunks: + if _replace_rail_chunk_instance(chunk_root): + replaced_count += 1 + + if replaced_count > 0: + await get_tree().process_frame + _destroy_and_regenrate_world() + +func _update_rail_chunks() -> void: + call_deferred("_refresh_rail_chunks") + func _refresh_world(center: Vector2i) -> void: _rebuild_generation_queue(center) _rebuild_cleanup_queue(center) diff --git a/core/ui_events.gd b/core/ui_events.gd index fcd8ceb..274b7ec 100644 --- a/core/ui_events.gd +++ b/core/ui_events.gd @@ -30,6 +30,10 @@ signal toggle_shadows(value: bool) @warning_ignore("unused_signal") signal toggle_fog(value: bool) +#railway signals +@warning_ignore("unused_signal") +signal update_rail_chunks() + #day cycle signals @warning_ignore("unused_signal") signal toggle_pause_daytime(value: bool) diff --git a/docs/museums/biome_generator/museum_map.tscn b/docs/museums/biome_generator/museum_map.tscn index 98a5c07..586f584 100644 --- a/docs/museums/biome_generator/museum_map.tscn +++ b/docs/museums/biome_generator/museum_map.tscn @@ -412,6 +412,20 @@ theme_override_colors/font_hover_pressed_color = Color(1, 1, 1, 1) theme_override_colors/font_outline_color = Color(1, 1, 1, 1) text = "Fog" +[node name="UpdateRails" type="Button" parent="Control" unique_id=267134156] +layout_mode = 0 +offset_left = 12.0 +offset_top = 351.0 +offset_right = 195.0 +offset_bottom = 382.0 +theme_override_colors/font_color = Color(1, 1, 1, 1) +theme_override_colors/font_focus_color = Color(1, 1, 1, 1) +theme_override_colors/font_pressed_color = Color(1, 1, 1, 1) +theme_override_colors/font_hover_color = Color(1, 1, 1, 1) +theme_override_colors/font_hover_pressed_color = Color(1, 1, 1, 1) +theme_override_colors/font_outline_color = Color(1, 1, 1, 1) +text = "Update Rails" + [connection signal="toggled" from="Control/Snow" to="Control" method="_on_snow_toggled"] [connection signal="toggled" from="Control/Rain" to="Control" method="_on_rain_toggled"] [connection signal="toggled" from="Control/Wind" to="Control" method="_on_wind_toggled"] @@ -426,3 +440,4 @@ text = "Fog" [connection signal="toggled" from="Control/Shadows" to="Control" method="_on_shadows_toggled"] [connection signal="pressed" from="Control/RandomWeather" to="Control" method="_on_random_weather_pressed"] [connection signal="toggled" from="Control/Fog" to="Control" method="_on_fog_toggled"] +[connection signal="pressed" from="Control/UpdateRails" to="Control" method="_on_update_rails_pressed"] diff --git a/docs/museums/daynight/control.gd b/docs/museums/daynight/control.gd index 8668dfb..babd294 100644 --- a/docs/museums/daynight/control.gd +++ b/docs/museums/daynight/control.gd @@ -99,3 +99,6 @@ func _on_option_button_item_selected(index: int) -> void: func _on_fog_toggled(toggled_on: bool) -> void: UIEvents.toggle_fog.emit(toggled_on) + +func _on_update_rails_pressed() -> void: + UIEvents.update_rail_chunks.emit() diff --git a/tgcc/chunk/railway/scene/chunk_railway_station_hero.tscn b/tgcc/chunk/railway/scene/chunk_railway_station_hero.tscn index dbc00dd..6235b51 100644 --- a/tgcc/chunk/railway/scene/chunk_railway_station_hero.tscn +++ b/tgcc/chunk/railway/scene/chunk_railway_station_hero.tscn @@ -123,6 +123,7 @@ buffer = PackedFloat32Array(0.09478149, -0.4699982, -0.8787032, -19.27537, -0.99 [node name="chunk_railway_station_hero" unique_id=1050909298 node_paths=PackedStringArray("connection_left", "connection_right") instance=ExtResource("1_c8ljj")] script = ExtResource("9_5ow1i") +chunk_type = 1 have_lamppost = true connection_left = [NodePath("PaloLuce3/sx"), NodePath("PaloLuce2/sx"), NodePath("PaloLuce/sx")] connection_right = [NodePath("PaloLuce/dx"), NodePath("PaloLuce2/dx"), NodePath("PaloLuce3/dx")] diff --git a/tgcc/chunk/railway/scene/chunk_railway_straight_2.tscn b/tgcc/chunk/railway/scene/chunk_railway_straight_2.tscn index d1ff8e9..b17c393 100644 --- a/tgcc/chunk/railway/scene/chunk_railway_straight_2.tscn +++ b/tgcc/chunk/railway/scene/chunk_railway_straight_2.tscn @@ -39,6 +39,7 @@ size = Vector3(20, 10, 20) [node name="chunk_railway_straight_2" unique_id=476549215 instance=ExtResource("1_g8fwq")] script = ExtResource("2_5gtba") +chunk_type = 1 est = true [node name="Chunk_014" parent="." index="0" unique_id=1534185754] diff --git a/tgcc/chunk/railway/scene/chunk_railway_straight_bridge.tscn b/tgcc/chunk/railway/scene/chunk_railway_straight_bridge.tscn index 02891cc..d03e48e 100644 --- a/tgcc/chunk/railway/scene/chunk_railway_straight_bridge.tscn +++ b/tgcc/chunk/railway/scene/chunk_railway_straight_bridge.tscn @@ -66,6 +66,7 @@ size = Vector3(20, 10, 20) [node name="chunk_railway_straight_bridge" unique_id=1049036234 node_paths=PackedStringArray("connection_left", "connection_right") instance=ExtResource("1_bwiif")] script = ExtResource("1_uoylj") +chunk_type = 1 est = true west = true have_lamppost = true