diff --git a/addons/escoria-core/game/core-scripts/esc/esc_object_manager.gd b/addons/escoria-core/game/core-scripts/esc/esc_object_manager.gd index 0fe5bff0..1a7595b6 100644 --- a/addons/escoria-core/game/core-scripts/esc/esc_object_manager.gd +++ b/addons/escoria-core/game/core-scripts/esc/esc_object_manager.gd @@ -12,7 +12,7 @@ const RESERVED_OBJECTS = [ MUSIC, SOUND, SPEECH, - CAMERA + #CAMERA ] @@ -283,6 +283,7 @@ func get_object(global_id: String, room: ESCRoom = null) -> ESCObject: room_key = current_room_key else: + room_key = ESCRoomObjectsKey.new() room_key.room_global_id = room.global_id room_key.room_instance_id = room.get_instance_id() diff --git a/addons/escoria-core/game/core-scripts/esc/esc_room_manager.gd b/addons/escoria-core/game/core-scripts/esc/esc_room_manager.gd index 39c0239e..f3cf5503 100644 --- a/addons/escoria-core/game/core-scripts/esc/esc_room_manager.gd +++ b/addons/escoria-core/game/core-scripts/esc/esc_room_manager.gd @@ -89,6 +89,10 @@ func change_scene(room_path: String, enable_automatic_transitions: bool) -> void ] ) + if escoria.main.current_scene \ + and escoria.game_scene.get_parent() == escoria.main.current_scene: + escoria.main.current_scene.remove_child(escoria.game_scene) + # Load room scene var res_room = escoria.resource_cache.get_resource(room_path) @@ -102,6 +106,16 @@ func change_scene(room_path: String, enable_automatic_transitions: bool) -> void else: room_scene.enabled_automatic_transitions = enable_automatic_transitions + # If the game scene is already in the tree but not a child of the room + # we remove it + if escoria.game_scene.is_inside_tree() \ + and escoria.game_scene.get_parent() != room_scene: + var game_parent = escoria.game_scene.get_parent() + game_parent.remove_child(escoria.game_scene) + + room_scene.add_child(escoria.game_scene) + room_scene.move_child(escoria.game_scene, 0) + room_scene.game = escoria.game_scene escoria.main.set_scene(room_scene) # We know the scene has been loaded. Make its global ID available for @@ -160,11 +174,7 @@ func init_room(room: ESCRoom) -> void: room.add_child(room.game) room.move_child(room.game, 0) - # Determine whether this room was run from change_scene or directly - if escoria.main.has_node(room.name): - room.is_run_directly = false - else: - room.is_run_directly = true + if room.is_run_directly: if escoria.main.current_scene == null: escoria.main.set_scene(room) @@ -219,25 +229,6 @@ func _perform_script_events(room: ESCRoom) -> void: # With the room transitioned out, finish any room prep and run :setup if # it exists. - if escoria.main.current_scene \ - and escoria.game_scene.get_parent() == escoria.main.current_scene: - escoria.main.current_scene.remove_child(escoria.game_scene) - - # If the game scene is already in the tree but not a child of the room - # we remove it - if escoria.game_scene.is_inside_tree() \ - and escoria.game_scene.get_parent() != room: - var game_parent = escoria.game_scene.get_parent() - game_parent.remove_child(escoria.game_scene) - - room.add_child(escoria.game_scene) - room.move_child(escoria.game_scene, 0) - room.game = escoria.game_scene - - # We must first et the camera limits, and then worry about subsequent - # player setup since it relies on this. - escoria.main.set_camera_limits(0, room) - if room.player_scene: room.player = room.player_scene.instance() room.add_child(room.player) @@ -264,7 +255,7 @@ func _perform_script_events(room: ESCRoom) -> void: ) room.player.update_idle() - escoria.object_manager.get_object(escoria.object_manager.CAMERA).node.set_target(room.player) + #escoria.object_manager.get_object(escoria.object_manager.CAMERA).node.set_target(room.player) if room.global_id.empty(): room.global_id = room.name @@ -274,7 +265,27 @@ func _perform_script_events(room: ESCRoom) -> void: and escoria.object_manager.get_start_location() != null: room.player.teleport(escoria.object_manager.get_start_location().node) + # We make sure 'room' is set as the new current_scene, but without making + # it visible/the current scene tree. + if not yielded: + escoria.main.finish_current_scene_init(room) + + # Add new camera to scene being prepared. + var new_player_camera: ESCCamera = escoria.resource_cache.get_resource(escoria.CAMERA_SCENE_PATH).instance() + new_player_camera.register() + room.player_camera = new_player_camera + + # We must first set the camera limits, and then worry about subsequent + # player setup since it relies on this. + escoria.main.set_camera_limits(0, room) + + # Add the camera in to the scene tree but don't make it active just yet. + new_player_camera.current = false + room.add_child(new_player_camera) + room.move_child(new_player_camera, 0) + var setup_event_added: bool = false + # Run the setup event, if there is one. setup_event_added = _run_script_event(escoria.event_manager.EVENT_SETUP, room) @@ -288,11 +299,17 @@ func _perform_script_events(room: ESCRoom) -> void: yielded = true - if not yielded: - escoria.main.finish_current_scene_init(room) + if room.player: + escoria.object_manager.get_object(escoria.object_manager.CAMERA).node.set_target(room.player) + # Conclude the call to set_scene (thankyouverymuch, coroutines), including + # making the new room visible. escoria.main.set_scene_finish() + # Maybe this is ok to put in set_scene_finish() above? But it might be a bit + # confusing to not see the matching camera.current updates. + new_player_camera.make_current() + # We know the scene has been loaded. Make its global ID available for # use by ESC script. escoria.globals_manager.set_global( diff --git a/addons/escoria-core/game/core-scripts/esc_animation_player.gd b/addons/escoria-core/game/core-scripts/esc_animation_player.gd index 1fc67658..9a6621b1 100644 --- a/addons/escoria-core/game/core-scripts/esc_animation_player.gd +++ b/addons/escoria-core/game/core-scripts/esc_animation_player.gd @@ -134,7 +134,7 @@ func has_animation(name: String) -> bool: func seek_end(name: String): if _is_animation_player: _animation_player.current_animation = name - _animation_player.seek(_animation_player.get_animation(name).length) + _animation_player.seek(_animation_player.get_animation(name).length, true) else: _animated_sprite.animation = name _animated_sprite.frame = _animated_sprite.frames.get_frame_count(name) diff --git a/addons/escoria-core/game/core-scripts/esc_room.gd b/addons/escoria-core/game/core-scripts/esc_room.gd index cc956f84..7492c4ad 100644 --- a/addons/escoria-core/game/core-scripts/esc_room.gd +++ b/addons/escoria-core/game/core-scripts/esc_room.gd @@ -34,6 +34,9 @@ export(EditorRoomDebugDisplay) var editor_debug_mode \ # The player scene instance var player +# The player camera +var player_camera: ESCCamera + # The game scene instance var game @@ -56,6 +59,10 @@ func _enter_tree(): # Sanitize camera limits, add player node and set the global id to the # name of this node if it's not set manually func _ready(): + # Might as well just check here. + if get_parent() == get_tree().root and ProjectSettings.get_setting("application/run/main_scene") != self.filename: + is_run_directly = true + escoria.room_manager.init_room(self) diff --git a/addons/escoria-core/game/escoria.gd b/addons/escoria-core/game/escoria.gd index 71c483ea..071c8f93 100644 --- a/addons/escoria-core/game/escoria.gd +++ b/addons/escoria-core/game/escoria.gd @@ -30,6 +30,8 @@ const BUS_SFX = "SFX" const BUS_MUSIC = "Music" const BUS_SPEECH = "Speech" +const CAMERA_SCENE_PATH = "res://addons/escoria-core/game/scenes/camera_player/camera.tscn" + # Logger used var logger: ESCLogger @@ -97,6 +99,9 @@ var save_manager: ESCSaveManager # The game scene loaded var game_scene: ESCGame +# The main player camera +var player_camera: ESCCamera + # The compiled start script loaded from ProjectSettings # escoria/main/game_start_script var start_script: ESCScript diff --git a/addons/escoria-core/game/main.gd b/addons/escoria-core/game/main.gd index ebdc4494..ca5c9698 100644 --- a/addons/escoria-core/game/main.gd +++ b/addons/escoria-core/game/main.gd @@ -67,10 +67,6 @@ func set_scene(p_scene: Node) -> void: current_scene = p_scene - check_game_scene_methods() - - #set_camera_limits(current_scene) - # Only called by the room manager in the case where it hasn't executed a # coroutine prior to calling set_scene_finish(). @@ -83,24 +79,23 @@ func finish_current_scene_init(p_scene: Node) -> void: current_scene = p_scene - check_game_scene_methods() - -# set_camera_limits(current_scene) - # Completes the room swap and should be called by the room manager at the # appropriate time. func set_scene_finish() -> void: - current_scene.visible = true + # Final check for the critical game scene's existence. + check_game_scene_methods() - if previous_scene != null: - clear_scene() + # Make our new scene visible. + current_scene.visible = true + + clear_previous_scene() emit_signal("room_ready") -# Cleanup the previous scene -func clear_scene() -> void: +# Cleanup the previous scene if there was one. +func clear_previous_scene() -> void: if previous_scene == null: return diff --git a/addons/escoria-core/game/scenes/camera_player/esc_camera.gd b/addons/escoria-core/game/scenes/camera_player/esc_camera.gd index d13cd70e..314e3437 100644 --- a/addons/escoria-core/game/scenes/camera_player/esc_camera.gd +++ b/addons/escoria-core/game/scenes/camera_player/esc_camera.gd @@ -21,14 +21,6 @@ func _ready(): _tween = Tween.new() add_child(_tween) _tween.connect("tween_all_completed", self, "_target_reached") - escoria.object_manager.register_object( - ESCObject.new( - escoria.object_manager.CAMERA, - self - ), - null, - true - ) # Update the position if the followed target is moving @@ -37,6 +29,24 @@ func _process(_delta): self.global_position = _follow_target.global_position +# Register this camera with the object manager. We do it out here so we can +# work with the camera before it's made active as part of the current scene +# tree. +# +# #### Parameters +# +# - room: The room with which to register the camera. +func register(room = null): + escoria.object_manager.register_object( + ESCObject.new( + escoria.object_manager.CAMERA, + self + ), + room, + true + ) + + # Sets camera limits so it doesn't go out of the scene # # #### Parameters diff --git a/addons/escoria-ui-9verbs/game.tscn b/addons/escoria-ui-9verbs/game.tscn index e3eaf514..77dd7535 100644 --- a/addons/escoria-ui-9verbs/game.tscn +++ b/addons/escoria-ui-9verbs/game.tscn @@ -1,11 +1,10 @@ -[gd_scene load_steps=11 format=2] +[gd_scene load_steps=10 format=2] [ext_resource path="res://addons/escoria-ui-9verbs/tooltip/action_target_tooltip.tscn" type="PackedScene" id=1] [ext_resource path="res://addons/escoria-ui-9verbs/inventory/inventory_ui.tscn" type="PackedScene" id=2] [ext_resource path="res://addons/escoria-ui-9verbs/verbs_menu.tscn" type="PackedScene" id=3] [ext_resource path="res://addons/escoria-core/game/scenes/dialogs/esc_dialog_player.gd" type="Script" id=4] [ext_resource path="res://addons/escoria-ui-9verbs/game.gd" type="Script" id=5] -[ext_resource path="res://addons/escoria-core/game/scenes/camera_player/camera.tscn" type="PackedScene" id=6] [ext_resource path="res://addons/escoria-core/ui_library/menus/main_menu/main_menu.tscn" type="PackedScene" id=7] [ext_resource path="res://addons/escoria-core/ui_library/menus/pause_menu/pause_menu.tscn" type="PackedScene" id=9] [ext_resource path="res://addons/escoria-ui-9verbs/theme.tres" type="Theme" id=10] @@ -160,6 +159,4 @@ visible = false visible = false theme = ExtResource( 10 ) -[node name="camera" parent="." instance=ExtResource( 6 )] - [connection signal="pressed" from="ui/Control/panel_down/VBoxContainer/HBoxContainer/MainMargin/VBoxContainer/MarginContainer/MenuButton" to="." method="_on_MenuButton_pressed"]