diff --git a/game/scenes/Interaction/scene_teleporter.gd b/game/scenes/Interaction/scene_teleporter.gd new file mode 100644 index 0000000..692d43b --- /dev/null +++ b/game/scenes/Interaction/scene_teleporter.gd @@ -0,0 +1,39 @@ +extends Area3D + +@export_file("*.tscn") var target_scene_path := "res://scenes/Levels/transportation_level.tscn" +@export var target_group: StringName = &"player" +@export var one_shot := true + +var _is_transitioning := false + + +func _ready() -> void: + body_entered.connect(_on_body_entered) + + +func _on_body_entered(body: Node) -> void: + if _is_transitioning: + return + if target_group != StringName() and not body.is_in_group(target_group): + return + if target_scene_path.strip_edges() == "": + push_warning("Teleporter target scene is empty.") + return + if not ResourceLoader.exists(target_scene_path): + push_warning("Teleporter target scene does not exist: %s" % target_scene_path) + return + + _is_transitioning = true + if one_shot: + set_deferred("monitoring", false) + call_deferred("_deferred_change_scene") + + +func _deferred_change_scene() -> void: + var err := get_tree().change_scene_to_file(target_scene_path) + if err == OK: + return + push_warning("Failed to change scene to '%s' (%s)." % [target_scene_path, err]) + _is_transitioning = false + if one_shot: + set_deferred("monitoring", true) diff --git a/game/scenes/Interaction/scene_teleporter.gd.uid b/game/scenes/Interaction/scene_teleporter.gd.uid new file mode 100644 index 0000000..6f3537b --- /dev/null +++ b/game/scenes/Interaction/scene_teleporter.gd.uid @@ -0,0 +1 @@ +uid://dyvldjfan2beq diff --git a/game/scenes/Interaction/scene_teleporter.tscn b/game/scenes/Interaction/scene_teleporter.tscn new file mode 100644 index 0000000..8aa2de6 --- /dev/null +++ b/game/scenes/Interaction/scene_teleporter.tscn @@ -0,0 +1,32 @@ +[gd_scene load_steps=4 format=3] + +[ext_resource type="Script" path="res://scenes/Interaction/scene_teleporter.gd" id="1_tele"] + +[sub_resource type="CylinderShape3D" id="CylinderShape3D_tele"] +height = 3.0 +radius = 1.5 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_tele"] +transparency = 1 +shading_mode = 0 +albedo_color = Color(0.15, 0.95, 1, 0.25) +emission_enabled = true +emission = Color(0.1, 0.9, 1, 1) +emission_energy_multiplier = 1.5 + +[sub_resource type="CylinderMesh" id="CylinderMesh_tele"] +material = SubResource("StandardMaterial3D_tele") +top_radius = 1.6 +bottom_radius = 1.6 +height = 3.0 + +[node name="SceneTeleporter" type="Area3D"] +collision_layer = 2 +collision_mask = 1 +script = ExtResource("1_tele") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +shape = SubResource("CylinderShape3D_tele") + +[node name="Visual" type="MeshInstance3D" parent="."] +mesh = SubResource("CylinderMesh_tele") diff --git a/game/scenes/Levels/level.gd b/game/scenes/Levels/level.gd index 6d2b901..d3ebef6 100644 --- a/game/scenes/Levels/level.gd +++ b/game/scenes/Levels/level.gd @@ -13,10 +13,12 @@ var time := 0.0 @onready var _player: Node = $Player @onready var _quest_text: RichTextLabel = $PhoneUI/Control/PhoneFrame/QuestText -const FIRST_QUEST_ID := "first_drive" -const FIRST_QUEST := { - "id": FIRST_QUEST_ID, - "title": "RepoBot's First Task", +const FIRST_QUEST_ID := "first_drive" +const QUEST_PROMPT_META_PREFIX := "quest_intro_prompt_shown_" +const SPAWN_DIALOG_META_KEY := "level_spawn_dialog_shown" +const FIRST_QUEST := { + "id": FIRST_QUEST_ID, + "title": "RepoBot's First Task", "description": "Get familiar with movement and vehicles.", "steps": [ { @@ -32,16 +34,17 @@ const FIRST_QUEST := { ], } -func _ready() -> void: - _setup_quests() - if show_spawn_dialog and DialogSystem and DialogSystem.has_method("show_text"): - await get_tree().process_frame - DialogSystem.show_text(spawn_dialog_text) - if spawn_dialog_auto_close_seconds > 0.0: - await get_tree().create_timer(spawn_dialog_auto_close_seconds).timeout - if DialogSystem and DialogSystem.has_method("close_if_text"): - DialogSystem.close_if_text(spawn_dialog_text) - _show_quest_intro_dialog() +func _ready() -> void: + _setup_quests() + if _should_show_spawn_dialog() and DialogSystem and DialogSystem.has_method("show_text"): + await get_tree().process_frame + DialogSystem.show_text(spawn_dialog_text) + _mark_spawn_dialog_shown() + if spawn_dialog_auto_close_seconds > 0.0: + await get_tree().create_timer(spawn_dialog_auto_close_seconds).timeout + if DialogSystem and DialogSystem.has_method("close_if_text"): + DialogSystem.close_if_text(spawn_dialog_text) + _show_quest_intro_dialog() func _process(delta): time = fmod((time + delta), day_length) @@ -94,14 +97,36 @@ func _refresh_quest_ui() -> void: _quest_text.text = "[b]%s[/b]\nStep %d/%d\n%s" % [title, step_index + 1, total_steps, step_text] -func _show_quest_intro_dialog() -> void: - if QuestManager == null: - return - var state: Dictionary = QuestManager.get_active_quest_state() - if not bool(state.get("active", false)) or bool(state.get("completed", false)): - return - var step_text := String(state.get("current_step_text", "")) - if step_text.is_empty(): - return - if DialogSystem and DialogSystem.has_method("show_text"): - DialogSystem.show_text("RepoBot: New task assigned.\n\n%s" % step_text) +func _show_quest_intro_dialog() -> void: + if QuestManager == null: + return + var state: Dictionary = QuestManager.get_active_quest_state() + if not bool(state.get("active", false)) or bool(state.get("completed", false)): + return + var quest_id := String(state.get("quest_id", "")).strip_edges() + var step_id := String(state.get("current_step_id", "")).strip_edges() + var step_text := String(state.get("current_step_text", "")) + if quest_id.is_empty() or step_id.is_empty() or step_text.is_empty(): + return + var prompt_key := "%s%s_%s" % [QUEST_PROMPT_META_PREFIX, quest_id, step_id] + if QuestManager.has_meta(prompt_key) and bool(QuestManager.get_meta(prompt_key)): + return + if DialogSystem and DialogSystem.has_method("show_text"): + DialogSystem.show_text("RepoBot: New task assigned.\n\n%s" % step_text) + QuestManager.set_meta(prompt_key, true) + + +func _should_show_spawn_dialog() -> bool: + if not show_spawn_dialog: + return false + if QuestManager == null: + return true + if not QuestManager.has_meta(SPAWN_DIALOG_META_KEY): + return true + return not bool(QuestManager.get_meta(SPAWN_DIALOG_META_KEY)) + + +func _mark_spawn_dialog_shown() -> void: + if QuestManager == null: + return + QuestManager.set_meta(SPAWN_DIALOG_META_KEY, true) diff --git a/game/scenes/Levels/level.tscn b/game/scenes/Levels/level.tscn index 67848c3..6d56063 100644 --- a/game/scenes/Levels/level.tscn +++ b/game/scenes/Levels/level.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=81 format=3 uid="uid://dchj6g2i8ebph"] +[gd_scene load_steps=82 format=3 uid="uid://dchj6g2i8ebph"] [ext_resource type="Script" uid="uid://brgmxhhhtakja" path="res://scenes/Levels/level.gd" id="1_a4mo8"] [ext_resource type="PackedScene" uid="uid://bb6hj6l23043x" path="res://assets/models/human.blend" id="1_eg4yq"] @@ -10,6 +10,7 @@ [ext_resource type="PackedScene" uid="uid://bnqaqbgynoyys" path="res://assets/models/TestCharAnimated.glb" id="5_fi66n"] [ext_resource type="Script" uid="uid://bk53njt7i3kmv" path="res://scenes/Interaction/dialog_trigger_area.gd" id="6_dialog"] [ext_resource type="Script" uid="uid://cshtdpjp4xy2f" path="res://scenes/Quests/quest_trigger_area.gd" id="7_qtrigger"] +[ext_resource type="PackedScene" path="res://scenes/Interaction/scene_teleporter.tscn" id="8_teleporter"] [sub_resource type="PhysicsMaterial" id="PhysicsMaterial_2q6dc"] bounce = 0.5 @@ -609,6 +610,10 @@ scroll_active = false [node name="WorldEnvironment" type="WorldEnvironment" parent="."] environment = SubResource("Environment_a4mo8") +[node name="LevelExitTeleporter" parent="." instance=ExtResource("8_teleporter")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.5, 0.5, 0) +target_scene_path = "res://scenes/Levels/transportation_level.tscn" + [connection signal="pressed" from="Menu/Control/VBoxContainer/ContinueButton" to="Menu" method="_on_continue_button_pressed"] [connection signal="pressed" from="Menu/Control/VBoxContainer/MainMenuButton" to="Menu" method="_on_main_menu_button_pressed"] [connection signal="pressed" from="Menu/Control/VBoxContainer/QuitButton" to="Menu" method="_on_quit_button_pressed"] diff --git a/game/scenes/Levels/location_level.gd b/game/scenes/Levels/location_level.gd deleted file mode 100644 index a6c979e..0000000 --- a/game/scenes/Levels/location_level.gd +++ /dev/null @@ -1,235 +0,0 @@ -extends Node3D - -const LOCATIONS_API_URL := "https://ploc.ranaze.com/api/Locations" - -@export var tile_size := 4.0 -@export var block_height := 1.0 -@export_range(1, 8, 1) var tile_radius := 3 -@export var tracked_node_path: NodePath -@export var border_color: Color = Color(0.05, 0.05, 0.05, 1.0) -@export var border_height_bias := 0.005 -@export var show_tile_labels := true -@export var tile_label_height := 0.01 -@export var tile_label_color: Color = Color(1, 1, 1, 1) - -@onready var _block: MeshInstance3D = $TerrainBlock -@onready var _camera: Camera3D = $Camera3D - -var _center_coord := Vector2i.ZERO -var _tiles_root: Node3D -var _tracked_node: Node3D -var _tile_nodes: Dictionary = {} -var _camera_start_offset := Vector3(0.0, 6.0, 10.0) -var _border_material: StandardMaterial3D -var _known_location_coords: Dictionary = {} -var _locations_loaded := false - -func _ready() -> void: - _tiles_root = Node3D.new() - _tiles_root.name = "GeneratedTiles" - add_child(_tiles_root) - - if _camera: - _camera_start_offset = _camera.global_position - - _tracked_node = get_node_or_null(tracked_node_path) as Node3D - if _tracked_node == null: - _tracked_node = get_node_or_null("Player") as Node3D - - var start_coord := SelectedCharacter.get_coord() - _center_coord = Vector2i(roundi(start_coord.x), roundi(start_coord.y)) - - _block.visible = false - await _load_existing_locations() - _rebuild_tiles(_center_coord) - _snap_camera_to_coord(_center_coord) - - -func _process(_delta: float) -> void: - if not _locations_loaded: - return - var target_world_pos := _get_stream_position() - var target_coord := _world_to_coord(target_world_pos) - if target_coord == _center_coord: - return - _center_coord = target_coord - _rebuild_tiles(_center_coord) - - -func _get_stream_position() -> Vector3: - if _tracked_node: - return _tracked_node.global_position - if _camera: - return _camera.global_position - return _coord_to_world(_center_coord) - - -func _world_to_coord(world_pos: Vector3) -> Vector2i: - return Vector2i( - roundi(world_pos.x / tile_size), - roundi(world_pos.z / tile_size) - ) - - -func _coord_to_world(coord: Vector2i) -> Vector3: - return Vector3(coord.x * tile_size, block_height * 0.5, coord.y * tile_size) - - -func _snap_camera_to_coord(coord: Vector2i) -> void: - if _camera == null: - return - var center_world := _coord_to_world(coord) - _camera.global_position = center_world + _camera_start_offset - _camera.look_at(center_world, Vector3.UP) - - -func _rebuild_tiles(center: Vector2i) -> void: - var wanted_keys: Dictionary = {} - for x in range(center.x - tile_radius, center.x + tile_radius + 1): - for y in range(center.y - tile_radius, center.y + tile_radius + 1): - var coord := Vector2i(x, y) - if not _known_location_coords.has(coord): - continue - wanted_keys[coord] = true - if _tile_nodes.has(coord): - continue - _spawn_tile(coord) - - var keys_to_remove: Array = _tile_nodes.keys() - for key in keys_to_remove: - if wanted_keys.has(key): - continue - var tile_node := _tile_nodes[key] as Node3D - if tile_node: - tile_node.queue_free() - _tile_nodes.erase(key) - - -func _spawn_tile(coord: Vector2i) -> void: - var tile_root := Node3D.new() - tile_root.name = "Tile_%d_%d" % [coord.x, coord.y] - tile_root.position = _coord_to_world(coord) - _tiles_root.add_child(tile_root) - - var tile := _block.duplicate() as MeshInstance3D - tile.name = "TileMesh" - tile.visible = true - tile.scale = Vector3(tile_size, block_height, tile_size) - tile_root.add_child(tile) - - tile.add_child(_create_tile_border()) - if show_tile_labels: - tile_root.add_child(_create_tile_label(coord)) - - var anchor := Marker3D.new() - anchor.name = "NpcAnchor" - anchor.position = Vector3(0.0, (block_height * 0.5) + 0.5, 0.0) - tile_root.add_child(anchor) - - _tile_nodes[coord] = tile_root - - -func _create_tile_border() -> MeshInstance3D: - var top_y := 0.5 + border_height_bias - var corners := [ - Vector3(-0.5, top_y, -0.5), - Vector3(0.5, top_y, -0.5), - Vector3(0.5, top_y, 0.5), - Vector3(-0.5, top_y, 0.5), - ] - - var border_mesh := ImmediateMesh.new() - border_mesh.surface_begin(Mesh.PRIMITIVE_LINES, _get_border_material()) - for idx in range(corners.size()): - var current: Vector3 = corners[idx] - var next: Vector3 = corners[(idx + 1) % corners.size()] - border_mesh.surface_add_vertex(current) - border_mesh.surface_add_vertex(next) - border_mesh.surface_end() - - var border := MeshInstance3D.new() - border.name = "TileBorder" - border.mesh = border_mesh - return border - - -func _get_border_material() -> StandardMaterial3D: - if _border_material: - return _border_material - - var material := StandardMaterial3D.new() - material.albedo_color = border_color - material.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED - material.disable_receive_shadows = true - material.no_depth_test = true - _border_material = material - return _border_material - - -func _create_tile_label(coord: Vector2i) -> Label3D: - var label := Label3D.new() - label.name = "LocationIdLabel" - label.text = _location_id_for_coord(coord) - label.position = Vector3(0.0, (block_height * 0.5) + border_height_bias + tile_label_height, 0.0) - label.rotation_degrees = Vector3(-90.0, 0.0, 0.0) - label.billboard = BaseMaterial3D.BILLBOARD_DISABLED - label.modulate = tile_label_color - label.pixel_size = 0.01 - label.outline_size = 12 - label.no_depth_test = false - return label - - -func _location_id_for_coord(coord: Vector2i) -> String: - return "%d,%d" % [coord.x, coord.y] - - -func _load_existing_locations() -> void: - _locations_loaded = false - _known_location_coords.clear() - - var request := HTTPRequest.new() - add_child(request) - - var headers := PackedStringArray() - if not AuthState.access_token.is_empty(): - headers.append("Authorization: Bearer %s" % AuthState.access_token) - - var err := request.request(LOCATIONS_API_URL, headers, HTTPClient.METHOD_GET) - if err != OK: - push_warning("Failed to request locations: %s" % err) - request.queue_free() - _locations_loaded = true - return - - var result: Array = await request.request_completed - request.queue_free() - - var result_code: int = result[0] - var response_code: int = result[1] - var response_bytes: PackedByteArray = result[3] - var response_body: String = response_bytes.get_string_from_utf8() - if result_code != HTTPRequest.RESULT_SUCCESS or response_code < 200 or response_code >= 300: - push_warning("Failed to load locations (%s/%s): %s" % [result_code, response_code, response_body]) - _locations_loaded = true - return - - var parsed: Variant = JSON.parse_string(response_body) - if typeof(parsed) != TYPE_ARRAY: - push_warning("Locations response was not an array.") - _locations_loaded = true - return - - for item in parsed: - if typeof(item) != TYPE_DICTIONARY: - continue - var location: Dictionary = item - var coord_variant: Variant = location.get("coord", {}) - if typeof(coord_variant) != TYPE_DICTIONARY: - continue - var coord_dict: Dictionary = coord_variant - var x := int(coord_dict.get("x", 0)) - var y := int(coord_dict.get("y", 0)) - _known_location_coords[Vector2i(x, y)] = true - - _locations_loaded = true diff --git a/game/scenes/Levels/location_level.gd.uid b/game/scenes/Levels/location_level.gd.uid deleted file mode 100644 index 6befa8a..0000000 --- a/game/scenes/Levels/location_level.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://1fico5npv6dy diff --git a/game/scenes/Levels/location_level.tscn b/game/scenes/Levels/location_level.tscn deleted file mode 100644 index c62e156..0000000 --- a/game/scenes/Levels/location_level.tscn +++ /dev/null @@ -1,23 +0,0 @@ -[gd_scene load_steps=4 format=3 uid="uid://b7p7k1i4t0m2l"] - -[ext_resource type="Script" path="res://scenes/Levels/location_level.gd" id="1_6y4q1"] - -[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_yu2x4"] -albedo_color = Color(0.2, 0.6, 0.2, 1) - -[sub_resource type="BoxMesh" id="BoxMesh_t2a5k"] -material = SubResource("StandardMaterial3D_yu2x4") - -[node name="LocationLevel" type="Node3D"] -script = ExtResource("1_6y4q1") - -[node name="TerrainBlock" type="MeshInstance3D" parent="."] -mesh = SubResource("BoxMesh_t2a5k") - -[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 0.819152, 0.573576, 0, -0.573576, 0.819152, 0, 6, 0) -shadow_enabled = true - -[node name="Camera3D" type="Camera3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 0.92388, 0.382683, 0, -0.382683, 0.92388, 0, 6, 10) -current = true diff --git a/game/scenes/Levels/transportation_level.gd b/game/scenes/Levels/transportation_level.gd new file mode 100644 index 0000000..c6d89cd --- /dev/null +++ b/game/scenes/Levels/transportation_level.gd @@ -0,0 +1,37 @@ +extends Node3D + +@export var player_spawn_position := Vector3(0.0, 0.0, 0.0) +@export var day_length := 120.0 +@export var start_light_angle := -90.0 + +@onready var _player: RigidBody3D = get_node_or_null("Player") as RigidBody3D +@onready var _sun: DirectionalLight3D = $DirectionalLight3D + +var _time := 0.0 + + +func _ready() -> void: + _move_player_to_spawn() + + +func _process(delta: float) -> void: + _update_day_night(delta) + + +func _move_player_to_spawn() -> void: + if _player == null: + return + _player.global_position = player_spawn_position + _player.linear_velocity = Vector3.ZERO + _player.angular_velocity = Vector3.ZERO + + +func _update_day_night(delta: float) -> void: + if _sun == null or day_length <= 0.0: + return + _time = fmod(_time + delta, day_length) + var t: float = _time / day_length + var angle: float = lerp(start_light_angle, start_light_angle + 360.0, t) + _sun.rotation_degrees.x = angle + var energy_curve: float = -sin((t * TAU) + (start_light_angle * PI / 180.0)) + _sun.light_energy = clamp((energy_curve * 1.0) + 0.2, 0.0, 1.2) diff --git a/game/scenes/Levels/transportation_level.gd.uid b/game/scenes/Levels/transportation_level.gd.uid new file mode 100644 index 0000000..ecbc775 --- /dev/null +++ b/game/scenes/Levels/transportation_level.gd.uid @@ -0,0 +1 @@ +uid://c2vm651r4nepy diff --git a/game/scenes/Levels/transportation_level.tscn b/game/scenes/Levels/transportation_level.tscn new file mode 100644 index 0000000..a2c3f74 --- /dev/null +++ b/game/scenes/Levels/transportation_level.tscn @@ -0,0 +1,62 @@ +[gd_scene load_steps=9 format=3 uid="uid://b7p7k1i4t0m2l"] + +[ext_resource type="Script" path="res://scenes/Levels/transportation_level.gd" id="1_6y4q1"] +[ext_resource type="Script" path="res://scenes/player.gd" id="2_player"] +[ext_resource type="PackedScene" path="res://assets/models/TestCharAnimated.glb" id="3_model"] +[ext_resource type="PackedScene" path="res://scenes/Interaction/scene_teleporter.tscn" id="4_teleporter"] + +[sub_resource type="SphereShape3D" id="SphereShape3D_player"] + +[sub_resource type="BoxShape3D" id="BoxShape3D_ground"] +size = Vector3(1080, 2, 1080) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ground"] +albedo_color = Color(0.194, 0.575, 0.194, 1) + +[sub_resource type="BoxMesh" id="BoxMesh_ground"] +material = SubResource("StandardMaterial3D_ground") +size = Vector3(1080, 2, 1080) + +[node name="TransportationLevel" type="Node3D"] +script = ExtResource("1_6y4q1") + +[node name="Ground" type="StaticBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, 0) + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Ground"] +shape = SubResource("BoxShape3D_ground") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="Ground"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00053596497, 0.0075991154, -0.0019865036) +mesh = SubResource("BoxMesh_ground") + +[node name="Player" type="RigidBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0) +script = ExtResource("2_player") +camera_path = NodePath("Camera3D") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Player"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) +shape = SubResource("SphereShape3D_player") + +[node name="TestCharAnimated" parent="Player" instance=ExtResource("3_model")] +transform = Transform3D(-0.9998549, 0, 0.01703362, 0, 1, 0, -0.01703362, 0, -0.9998549, 0, 0, 0) + +[node name="Camera3D" type="Camera3D" parent="Player"] +transform = Transform3D(0.9989785, -4.651856e-10, -0.045188628, 0.006969331, 0.9880354, 0.15407, 0.044647958, -0.15422754, 0.9870261, 0.22036135, 1.8988357, 0.64972365) +current = true +fov = 49.0 + +[node name="SpotLight3D" type="SpotLight3D" parent="Player"] +transform = Transform3D(1, 0, 0, 0, 0.906308, -0.422618, 0, 0.422618, 0.906308, 0, 1.7, -0.35) +visible = false +spot_range = 30.0 +spot_angle = 25.0 + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 0.819152, 0.573576, 0, -0.573576, 0.819152, 0, 6, 0) +shadow_enabled = true + +[node name="ReturnTeleporter" parent="." instance=ExtResource("4_teleporter")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.5, 0.5, 0) +target_scene_path = "res://scenes/Levels/level.tscn" diff --git a/game/scenes/UI/character_screen.gd b/game/scenes/UI/character_screen.gd index 7723b95..2bc6502 100644 --- a/game/scenes/UI/character_screen.gd +++ b/game/scenes/UI/character_screen.gd @@ -110,7 +110,7 @@ func _on_select_button_pressed() -> void: var character: Dictionary = _characters[index] SelectedCharacter.set_character(character) - get_tree().change_scene_to_file("res://scenes/Levels/location_level.tscn") + get_tree().change_scene_to_file("res://scenes/Levels/transportation_level.tscn") func _on_refresh_button_pressed() -> void: _load_characters()