diff --git a/addons/escoria-core/game/core-scripts/esc/commands/anim.gd b/addons/escoria-core/game/core-scripts/esc/commands/anim.gd index 08ce6c3d..376b506f 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/anim.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/anim.gd @@ -26,7 +26,7 @@ func configure() -> ESCCommandArgumentDescriptor: # Validate whether the given arguments match the command descriptor func validate(arguments: Array): - if not escoria.object_manager.objects.has(arguments[0]): + if not escoria.object_manager.has(arguments[0]): escoria.logger.report_errors( "anim: invalid object", [ @@ -39,7 +39,7 @@ func validate(arguments: Array): # Run the command func run(command_params: Array) -> int: - var obj = escoria.object_manager.objects[command_params[0]] + var obj = escoria.object_manager.get_object(command_params[0]) var anim_id = command_params[1] var reverse = command_params[2] var animator: ESCAnimationPlayer = \ diff --git a/addons/escoria-core/game/core-scripts/esc/commands/anim_block.gd b/addons/escoria-core/game/core-scripts/esc/commands/anim_block.gd index 0a4df639..303cb9c8 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/anim_block.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/anim_block.gd @@ -27,7 +27,7 @@ func configure() -> ESCCommandArgumentDescriptor: # Validate whether the given arguments match the command descriptor func validate(arguments: Array): - if not escoria.object_manager.objects.has(arguments[0]): + if not escoria.object_manager.has(arguments[0]): escoria.logger.report_errors( "anim_block.gd:validate", [ @@ -40,7 +40,7 @@ func validate(arguments: Array): # Run the command func run(command_params: Array) -> int: - var obj = escoria.object_manager.objects[command_params[0]] + var obj = escoria.object_manager.get_object(command_params[0]) var anim_id = command_params[1] var reverse = command_params[2] var animator: ESCAnimationPlayer = \ diff --git a/addons/escoria-core/game/core-scripts/esc/commands/camera_push.gd b/addons/escoria-core/game/core-scripts/esc/commands/camera_push.gd index 07960d6d..3e402575 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/camera_push.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/camera_push.gd @@ -44,7 +44,7 @@ func configure() -> ESCCommandArgumentDescriptor: # Validate whether the given arguments match the command descriptor func validate(arguments: Array): - if not escoria.object_manager.objects.has(arguments[0]): + if not escoria.object_manager.has(arguments[0]): escoria.logger.report_errors( "camera_push: invalid object", [ diff --git a/addons/escoria-core/game/core-scripts/esc/commands/camera_set_target.gd b/addons/escoria-core/game/core-scripts/esc/commands/camera_set_target.gd index 6c97203c..63ba9591 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/camera_set_target.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/camera_set_target.gd @@ -28,7 +28,7 @@ func configure() -> ESCCommandArgumentDescriptor: # Validate whether the given arguments match the command descriptor func validate(arguments: Array): - if not escoria.object_manager.objects.has(arguments[1]): + if not escoria.object_manager.has(arguments[1]): escoria.logger.report_errors( "camera_set_target: invalid object", [ diff --git a/addons/escoria-core/game/core-scripts/esc/commands/custom.gd b/addons/escoria-core/game/core-scripts/esc/commands/custom.gd index 288c2a63..218725ba 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/custom.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/custom.gd @@ -28,7 +28,7 @@ func configure() -> ESCCommandArgumentDescriptor: # Validate whether the given arguments match the command descriptor func validate(arguments: Array): - if not escoria.object_manager.objects.has(arguments[0]): + if not escoria.object_manager.has(arguments[0]): escoria.logger.report_errors( "custom: invalid object", [ diff --git a/addons/escoria-core/game/core-scripts/esc/commands/hide_menu.gd b/addons/escoria-core/game/core-scripts/esc/commands/hide_menu.gd index 792ed0b1..1e8ce749 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/hide_menu.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/hide_menu.gd @@ -50,12 +50,14 @@ func run(command_params: Array) -> int: "", ESCTransitionPlayer.TRANSITION_MODE.OUT ) - while yield( - escoria.main.scene_transition, - "transition_done" - ) != transition_id: - pass - + + if transition_id != ESCTransitionPlayer.TRANSITION_ID_INSTANT: + while yield( + escoria.main.scene_transition, + "transition_done" + ) != transition_id: + pass + if command_params[0] == "main": escoria.game_scene.hide_main_menu() elif command_params[0] == "pause": @@ -63,12 +65,12 @@ func run(command_params: Array) -> int: if command_params[1] and escoria.main.current_scene != null: transition_id = escoria.main.scene_transition.transition() - - if command_params[1] and escoria.main.current_scene != null: - while yield( - escoria.main.scene_transition, - "transition_done" - ) != transition_id: - pass - + + if transition_id != ESCTransitionPlayer.TRANSITION_ID_INSTANT: + while yield( + escoria.main.scene_transition, + "transition_done" + ) != transition_id: + pass + return ESCExecution.RC_OK diff --git a/addons/escoria-core/game/core-scripts/esc/commands/queue_event.gd b/addons/escoria-core/game/core-scripts/esc/commands/queue_event.gd index 04195591..72a43847 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/queue_event.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/queue_event.gd @@ -27,7 +27,7 @@ func configure() -> ESCCommandArgumentDescriptor: # Validate whether the given arguments match the command descriptor func validate(arguments: Array): - if not escoria.object_manager.objects.has(arguments[0]): + if not escoria.object_manager.has(arguments[0]): escoria.logger.report_errors( "queue_event.gd:validate", [ @@ -35,7 +35,7 @@ func validate(arguments: Array): ] ) return false - var node = escoria.object_manager.objects.get( + var node = escoria.object_manager.get_object( arguments[0] ).node if not "esc_script" in node or node.esc_script == "": @@ -68,7 +68,7 @@ func validate(arguments: Array): # Run the command func run(arguments: Array) -> int: - var node = escoria.object_manager.objects.get( + var node = escoria.object_manager.get_object( arguments[0] ).node var esc_script = escoria.esc_compiler.load_esc_file(node.esc_script) diff --git a/addons/escoria-core/game/core-scripts/esc/commands/say.gd b/addons/escoria-core/game/core-scripts/esc/commands/say.gd index 7bdc4857..64237bba 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/say.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/say.gd @@ -55,7 +55,7 @@ func configure() -> ESCCommandArgumentDescriptor: # Validate whether the given arguments match the command descriptor func validate(arguments: Array): - if not escoria.object_manager.objects.has(arguments[0]): + if not escoria.object_manager.has(arguments[0]): escoria.logger.report_errors( "anim: invalid object", [ diff --git a/addons/escoria-core/game/core-scripts/esc/commands/set_active.gd b/addons/escoria-core/game/core-scripts/esc/commands/set_active.gd index b69fd3f9..7c678a9f 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/set_active.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/set_active.gd @@ -24,7 +24,7 @@ func configure() -> ESCCommandArgumentDescriptor: # Validate whether the given arguments match the command descriptor func validate(arguments: Array): - if not escoria.object_manager.objects.has(arguments[0]): + if not escoria.object_manager.has(arguments[0]): escoria.logger.report_errors( "set_active: invalid object", [ diff --git a/addons/escoria-core/game/core-scripts/esc/commands/set_angle.gd b/addons/escoria-core/game/core-scripts/esc/commands/set_angle.gd index cada69f3..2a9cd12a 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/set_angle.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/set_angle.gd @@ -29,7 +29,7 @@ func configure() -> ESCCommandArgumentDescriptor: # Validate whether the given arguments match the command descriptor func validate(arguments: Array): - if not escoria.object_manager.objects.has(arguments[0]): + if not escoria.object_manager.has(arguments[0]): escoria.logger.report_errors( "set_angle: invalid object", [ diff --git a/addons/escoria-core/game/core-scripts/esc/commands/set_animations.gd b/addons/escoria-core/game/core-scripts/esc/commands/set_animations.gd index 53aed0e3..c93b3d97 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/set_animations.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/set_animations.gd @@ -23,7 +23,7 @@ func configure() -> ESCCommandArgumentDescriptor: # Validate whether the given arguments match the command descriptor func validate(arguments: Array): - if not escoria.object_manager.objects.has(arguments[0]): + if not escoria.object_manager.has(arguments[0]): escoria.logger.report_errors( "set_animations: invalid object", [ diff --git a/addons/escoria-core/game/core-scripts/esc/commands/set_interactive.gd b/addons/escoria-core/game/core-scripts/esc/commands/set_interactive.gd index 48a8812c..79322ec3 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/set_interactive.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/set_interactive.gd @@ -23,7 +23,7 @@ func configure() -> ESCCommandArgumentDescriptor: # Validate whether the given arguments match the command descriptor func validate(arguments: Array): - if not escoria.object_manager.objects.has(arguments[0]): + if not escoria.object_manager.has(arguments[0]): escoria.logger.report_errors( "set_interactive: invalid object", [ diff --git a/addons/escoria-core/game/core-scripts/esc/commands/set_speed.gd b/addons/escoria-core/game/core-scripts/esc/commands/set_speed.gd index 3437dfa0..b362474c 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/set_speed.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/set_speed.gd @@ -22,7 +22,7 @@ func configure() -> ESCCommandArgumentDescriptor: # Validate whether the given arguments match the command descriptor func validate(arguments: Array): - if not escoria.object_manager.objects.has(arguments[0]): + if not escoria.object_manager.has(arguments[0]): escoria.logger.report_errors( "set_speed: invalid object", [ @@ -34,6 +34,6 @@ func validate(arguments: Array): # Run the command func run(command_params: Array) -> int: - (escoria.object_manager.objects[command_params[0]].node as ESCItem).\ + (escoria.object_manager.get_object(command_params[0]).node as ESCItem).\ set_speed(command_params[1]) return ESCExecution.RC_OK diff --git a/addons/escoria-core/game/core-scripts/esc/commands/set_state.gd b/addons/escoria-core/game/core-scripts/esc/commands/set_state.gd index e960e727..fd670375 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/set_state.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/set_state.gd @@ -30,7 +30,7 @@ func configure() -> ESCCommandArgumentDescriptor: # Validate whether the given arguments match the command descriptor func validate(arguments: Array): - if not escoria.object_manager.objects.has(arguments[0]): + if not escoria.object_manager.has(arguments[0]): escoria.logger.report_errors( "set_state: invalid object", [ @@ -43,7 +43,7 @@ func validate(arguments: Array): # Run the command func run(command_params: Array) -> int: - (escoria.object_manager.objects[command_params[0]] as ESCObject).set_state( + (escoria.object_manager.get_object(command_params[0]) as ESCObject).set_state( command_params[1], command_params[2] ) diff --git a/addons/escoria-core/game/core-scripts/esc/commands/show_menu.gd b/addons/escoria-core/game/core-scripts/esc/commands/show_menu.gd index c589fa08..49458994 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/show_menu.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/show_menu.gd @@ -49,12 +49,14 @@ func run(command_params: Array) -> int: "", ESCTransitionPlayer.TRANSITION_MODE.OUT ) - while yield( - escoria.main.scene_transition, - "transition_done" - ) != transition_id: - pass - + + if transition_id != ESCTransitionPlayer.TRANSITION_ID_INSTANT: + while yield( + escoria.main.scene_transition, + "transition_done" + ) != transition_id: + pass + if command_params[0] == "main": escoria.game_scene.show_main_menu() elif command_params[0] == "pause": @@ -63,12 +65,12 @@ func run(command_params: Array) -> int: # Transition in to menu transition_id = escoria.main.scene_transition.transition() - while yield( - escoria.main.scene_transition, - "transition_done" - ) != transition_id: - pass - + if transition_id != ESCTransitionPlayer.TRANSITION_ID_INSTANT: + while yield( + escoria.main.scene_transition, + "transition_done" + ) != transition_id: + pass else: if command_params[0] == "main": escoria.game_scene.show_main_menu() diff --git a/addons/escoria-core/game/core-scripts/esc/commands/slide.gd b/addons/escoria-core/game/core-scripts/esc/commands/slide.gd index 078086cd..d9aff098 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/slide.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/slide.gd @@ -31,7 +31,7 @@ func configure() -> ESCCommandArgumentDescriptor: # Validate whether the given arguments match the command descriptor func validate(arguments: Array): - if not escoria.object_manager.objects.has(arguments[0]): + if not escoria.object_manager.has(arguments[0]): escoria.logger.report_errors( "slide: invalid first object", [ @@ -39,7 +39,7 @@ func validate(arguments: Array): ] ) return false - if not escoria.object_manager.objects.has(arguments[1]): + if not escoria.object_manager.has(arguments[1]): escoria.logger.report_errors( "slide: invalid second object", [ diff --git a/addons/escoria-core/game/core-scripts/esc/commands/spawn.gd b/addons/escoria-core/game/core-scripts/esc/commands/spawn.gd index bad3bacd..59a0f9d4 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/spawn.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/spawn.gd @@ -43,7 +43,7 @@ func validate(arguments: Array): ] ) return false - if arguments[3] and not escoria.object_manager.objects.has(arguments[3]): + if arguments[3] and not escoria.object_manager.has(arguments[3]): escoria.logger.report_errors( "spawn: invalid object", [ @@ -72,6 +72,7 @@ func run(command_params: Array) -> int: command_params[0], scene ), + null, true ) diff --git a/addons/escoria-core/game/core-scripts/esc/commands/teleport.gd b/addons/escoria-core/game/core-scripts/esc/commands/teleport.gd index 57a2b092..cc2000a0 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/teleport.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/teleport.gd @@ -24,7 +24,7 @@ func configure() -> ESCCommandArgumentDescriptor: # Validate whether the given arguments match the command descriptor func validate(arguments: Array): - if not escoria.object_manager.objects.has(arguments[0]): + if not escoria.object_manager.has(arguments[0]): escoria.logger.report_errors( "teleport: invalid first object", [ @@ -32,7 +32,7 @@ func validate(arguments: Array): ] ) return false - if not escoria.object_manager.objects.has(arguments[1]): + if not escoria.object_manager.has(arguments[1]): escoria.logger.report_errors( "teleport: invalid second object", [ diff --git a/addons/escoria-core/game/core-scripts/esc/commands/teleport_pos.gd b/addons/escoria-core/game/core-scripts/esc/commands/teleport_pos.gd index 89c97488..ae15e842 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/teleport_pos.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/teleport_pos.gd @@ -24,7 +24,7 @@ func configure() -> ESCCommandArgumentDescriptor: # Validate whether the given arguments match the command descriptor func validate(arguments: Array): - if not escoria.object_manager.objects.has(arguments[0]): + if not escoria.object_manager.has(arguments[0]): escoria.logger.report_errors( "teleport_pos: invalid first object", [ diff --git a/addons/escoria-core/game/core-scripts/esc/commands/transition.gd b/addons/escoria-core/game/core-scripts/esc/commands/transition.gd index 780ee945..4bd7df3e 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/transition.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/transition.gd @@ -52,7 +52,12 @@ func run(command_params: Array) -> int: else ESCTransitionPlayer.TRANSITION_MODE.IN, command_params[2] ) - escoria.logger.debug("Starting transition #%s [%s, %s]" + + if transition_id == ESCTransitionPlayer.TRANSITION_ID_INSTANT: + escoria.logger.debug("Performing instant transition.") + return ESCExecution.RC_OK + + escoria.logger.debug("Starting transition #%s [%s, %s]" % [transition_id, command_params[0], command_params[1]]) while yield( escoria.main.scene_transition, diff --git a/addons/escoria-core/game/core-scripts/esc/commands/turn_to.gd b/addons/escoria-core/game/core-scripts/esc/commands/turn_to.gd index ce7a06e0..6a178d46 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/turn_to.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/turn_to.gd @@ -31,7 +31,7 @@ func configure() -> ESCCommandArgumentDescriptor: # Validate whether the given arguments match the command descriptor func validate(arguments: Array): - if not escoria.object_manager.objects.has(arguments[0]): + if not escoria.object_manager.has(arguments[0]): escoria.logger.report_errors( "turn_to: invalid object", [ @@ -39,7 +39,7 @@ func validate(arguments: Array): ] ) return false - if not escoria.object_manager.objects.has(arguments[1]): + if not escoria.object_manager.has(arguments[1]): escoria.logger.report_errors( "turn_to: invalid target object", [ diff --git a/addons/escoria-core/game/core-scripts/esc/commands/walk.gd b/addons/escoria-core/game/core-scripts/esc/commands/walk.gd index bd908c32..69a8c378 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/walk.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/walk.gd @@ -26,7 +26,7 @@ func configure() -> ESCCommandArgumentDescriptor: # Validate whether the given arguments match the command descriptor func validate(arguments: Array): - if not escoria.object_manager.objects.has(arguments[0]): + if not escoria.object_manager.has(arguments[0]): escoria.logger.report_errors( "walk: invalid first object", [ @@ -34,7 +34,7 @@ func validate(arguments: Array): ] ) return false - if not escoria.object_manager.objects.has(arguments[1]): + if not escoria.object_manager.has(arguments[1]): escoria.logger.report_errors( "walk: invalid second object", [ diff --git a/addons/escoria-core/game/core-scripts/esc/commands/walk_block.gd b/addons/escoria-core/game/core-scripts/esc/commands/walk_block.gd index c6c3e9f6..a8977d32 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/walk_block.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/walk_block.gd @@ -26,7 +26,7 @@ func configure() -> ESCCommandArgumentDescriptor: # Validate whether the given arguments match the command descriptor func validate(arguments: Array): - if not escoria.object_manager.objects.has(arguments[0]): + if not escoria.object_manager.has(arguments[0]): escoria.logger.report_errors( "walk_block: invalid first object", [ @@ -34,7 +34,7 @@ func validate(arguments: Array): ] ) return false - if not escoria.object_manager.objects.has(arguments[1]): + if not escoria.object_manager.has(arguments[1]): escoria.logger.report_errors( "walk_block: invalid second object", [ @@ -52,7 +52,7 @@ func run(command_params: Array) -> int: command_params ) yield( - (escoria.object_manager.objects[command_params[0]].node as ESCItem), + (escoria.object_manager.get_object(command_params[0]).node as ESCItem), "arrived" ) return ESCExecution.RC_OK diff --git a/addons/escoria-core/game/core-scripts/esc/commands/walk_to_pos.gd b/addons/escoria-core/game/core-scripts/esc/commands/walk_to_pos.gd index 457a0a63..cccd5fa1 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/walk_to_pos.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/walk_to_pos.gd @@ -28,7 +28,7 @@ func configure() -> ESCCommandArgumentDescriptor: # Validate whether the given arguments match the command descriptor func validate(arguments: Array): - if not escoria.object_manager.objects.has(arguments[0]): + if not escoria.object_manager.has(arguments[0]): escoria.logger.report_errors( "walk_to_pos: invalid first object", [ diff --git a/addons/escoria-core/game/core-scripts/esc/commands/walk_to_pos_block.gd b/addons/escoria-core/game/core-scripts/esc/commands/walk_to_pos_block.gd index 68ec5a11..da70d48f 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/walk_to_pos_block.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/walk_to_pos_block.gd @@ -28,7 +28,7 @@ func configure() -> ESCCommandArgumentDescriptor: # Validate whether the given arguments match the command descriptor func validate(arguments: Array): - if not escoria.object_manager.objects.has(arguments[0]): + if not escoria.object_manager.has(arguments[0]): escoria.logger.report_errors( "walk_to_pos_block: invalid first object", [ @@ -46,7 +46,7 @@ func run(command_params: Array) -> int: Vector2(command_params[1], command_params[2]), command_params[3] ]) yield( - (escoria.object_manager.objects[command_params[0]].node as ESCItem), + (escoria.object_manager.get_object(command_params[0]).node as ESCItem), "arrived" ) return ESCExecution.RC_OK 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 2fd4abe7..88b8db42 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 @@ -15,30 +15,84 @@ const RESERVED_OBJECTS = [ CAMERA ] +# Separator to use for each room's entry in the objects dictionary. +const SEPARATOR = "!!!!" -# The hash of registered objects (the global id is the key) -var objects: Dictionary = {} +# Dictionary key for reserved objects. +const RESERVED_KEY = "reserved" + +# The hash of registered objects (organized by room, with the object's global id +# serving as the object's key). +# +# Example structure: +# +# { +# "reserved": +# { +# "_camera": camera +# }, +# "room1!!!!": +# { +# "obj1": val1, +# "obj2": val2 +# } +# } +# +# Note that the "reserved" entry cannot be altered or otherwise changed and +# that it belongs to no specific room. +var objects: Dictionary = {RESERVED_KEY: {}} + +# We also store the current room's complete key in objects for convenience. +var current_room_key: String = "" -# Make active objects visible +# Use this to track the room we just exited for the purpose o +var prev_room_key: String = "" + +# Make active objects in current room visible func _process(_delta): - for object in objects: + for object in objects[current_room_key]: if (object as ESCObject).node: (object as ESCObject).node.visible = (object as ESCObject).active + for object in objects[RESERVED_KEY]: + if (object as ESCObject).node: + (object as ESCObject).node.visible = (object as ESCObject).active + + +# Updates which object manager room is to be treated as the currently active one. +# +# #### Parameters +# +# - room: Room to register the object with in the object manager +func set_current_room(room: ESCRoom) -> void: + if room == null: + escoria.logger.report_errors( + "ESCObjectManager:set_current_room()", + [ + "Unable to set current room: No valid room specified." + ] + ) + + current_room_key = _make_room_key(room) + # Register the object in the manager # # #### Parameters # # - object: Object to register +# - room: Room to register the object with in the object manager # - force: Register the object, even if it has already been registered -func register_object(object: ESCObject, force: bool = false) -> void: +# - auto_unregister: Automatically unregister object on tree_exited +func register_object(object: ESCObject, room: ESCRoom = null, force: bool = false, \ + auto_unregister: bool = true) -> void: + if object.global_id.empty(): object.global_id = str(object.node.get_path()).split("/root/", false)[0] object.node.global_id = object.global_id escoria.logger.report_warnings( - "esc_object_manager.gd:register_object()", + "ESCObjectManager:register_object()", [ "Registering object with empty global_id.", "Using node's full path as global_id: %s" @@ -46,38 +100,84 @@ func register_object(object: ESCObject, force: bool = false) -> void: ] ) + # If this is a reserved object, let's make sure it's in the right place. + # Note that we also don't allow it to auto unregister and, as such, we need + # to make sure we clean these up when the application exits. + if object.global_id in RESERVED_OBJECTS: + objects[RESERVED_KEY][object.global_id] = object + return - if objects.has(object.global_id) and not force: - escoria.logger.report_errors( - "ESCObjectManager.register_object: Object already registered", - [ - "Object with global id %s already registered" % - object.global_id - ] - ) + var room_key: String = "" + + # If a room was passed in, then we're going to register the object with it; + # otherwise, we register the object with the "current room". + if room == null or room.global_id.empty(): + room_key = current_room_key + + if room_key.empty(): + escoria.logger.report_errors( + "ESCObjectManager:register_object()", + [ + "No room was specified to register object with, and no current room is properly set." + ] + ) else: - if not object.node.is_connected( + room_key = _make_room_key(room) + + if objects.has(room_key) and objects[room_key].has(object.global_id): + if force: + # If this ID already exists and we're about to overwrite it, do the + # safe thing and unregister the old object first + unregister_object_by_global_id(object.global_id, room_key) + else: + escoria.logger.report_errors( + "ESCObjectManager:register_object()", + [ + "Object with global id %s in room %s already registered" % + object.global_id, + room_key + ] + ) + + return + + + # If the object is already connected, disconnect it for the case of + # forcing the registration,since we don't know if this object will be + # overwritten ("forced") in the future and, if it is, if it's set to + # auto-unregister or not. In most cases, objects are set to auto unregister. + if object.node.is_connected( + "tree_exited", + self, + "unregister_object" + ): + object.node.disconnect( "tree_exited", self, "unregister_object" - ): - object.node.connect( - "tree_exited", - self, - "unregister_object", - [object] - ) + ) + + if auto_unregister: + object.node.connect( + "tree_exited", + self, + "unregister_object", + [object, room_key] + ) + + if "is_interactive" in object.node and object.node.is_interactive: + object.interactive = true + + if "esc_script" in object.node and not object.node.esc_script.empty(): + var script = escoria.esc_compiler.load_esc_file( + object.node.esc_script + ) + object.events = script.events + + if not objects.has(room_key): + objects[room_key] = {} - if "is_interactive" in object.node and object.node.is_interactive: - object.interactive = true - - if "esc_script" in object.node and not object.node.esc_script.empty(): - var script = escoria.esc_compiler.load_esc_file( - object.node.esc_script - ) - object.events = script.events - - objects[object.global_id] = object + objects[room_key][object.global_id] = object # Check whether an object was registered @@ -85,9 +185,30 @@ func register_object(object: ESCObject, force: bool = false) -> void: # #### Parameters # # - global_id: Global ID of object -# **Returns** Wether the object exists in the object registry -func has(global_id: String) -> bool: - return objects.has(global_id) +# - room: ESCRoom instance the object is registered with. +# **Returns** Whether the object exists in the object registry +func has(global_id: String, room: ESCRoom = null) -> bool: + if global_id in RESERVED_OBJECTS: + if objects[RESERVED_KEY] == null: + return false + + return objects[RESERVED_KEY].has(global_id) + + var room_key: String = "" + + if room == null: + escoria.logger.trace("ESCObjectManager.has(): No room specified." \ + + " Defaulting to current room." + ) + + room_key = current_room_key + else: + room_key = _make_room_key(room) + + if objects[room_key] == null: + return false + + return objects[room_key].has(global_id) # Get the object from the object registry @@ -95,16 +216,54 @@ func has(global_id: String) -> bool: # #### Parameters # # - global_id: The global id of the object to retrieve -# **Returns** The retrieved object, or null if not found -func get_object(global_id: String) -> ESCObject: - if objects.has(global_id): - return objects[global_id] +# - room: ESCRoom instance the object is registered with. +# **Returns** The retrieved object, or null if not found +func get_object(global_id: String, room: ESCRoom = null) -> ESCObject: + if global_id in RESERVED_OBJECTS: + if objects[RESERVED_KEY].has(global_id): + return objects[RESERVED_KEY][global_id] + else: + escoria.logger.report_warnings( + "ESCObjectManager:get_object()", + [ + "Invalid reserved object retrieved.", + "Reserved object with global id %s not found" + % global_id + ] + ) + return null + + var room_key: String = "" + + if room == null: + escoria.logger.trace("ESCObjectManager.has(): No room specified." \ + + " Defaulting to current room." + ) + + room_key = current_room_key + else: + room_key = _make_room_key(room) + + if objects[room_key] == null: + escoria.logger.report_warnings( + "ESCObjectManager:get_object()", + [ + "Specified room empty/not found.", + "Object with global id %s in room instance %s not found" + % global_id, room_key + ] + ) + return null + + if objects[room_key].has(global_id): + return objects[room_key][global_id] else: escoria.logger.report_warnings( - "esc_object_manager.gd:get_object()", + "ESCObjectManager:get_object()", [ - "Invalid object retrieved", - "Object with global id %s not found" % global_id + "Invalid object retrieved.", + "Object with global id %s in room instance %s not found" + % global_id, room_key ] ) return null @@ -115,42 +274,80 @@ func get_object(global_id: String) -> ESCObject: # #### Parameters # # - object: The object to unregister -func unregister_object(object: ESCObject) -> void: - if not escoria.inventory_manager.inventory_has(object.global_id) \ - and not object.global_id in RESERVED_OBJECTS: - objects.erase(object.global_id) +# - room_key: The room under which the object should be unregistered. +func unregister_object(object: ESCObject, room_key: String) -> void: + if objects[room_key] == null: + escoria.logger.report_errors( + "ESCObjectManager:unregister_object()", + [ + "Unable to unregister object.", + "Room with key %s not found." % room_key + ] + ) + + if not escoria.inventory_manager.inventory_has(object.global_id): + objects[room_key].erase(object.global_id) else: - if not object.global_id in RESERVED_OBJECTS: - # Re-instance the node if it is an item present in inventory. - objects[object.global_id].node = objects[object.global_id].node \ - .duplicate() + # Re-instance the node if it is an item present in inventory. + objects[room_key][object.global_id].node = \ + objects[room_key][object.global_id].node.duplicate() + + # If this room is truly empty, it's time to do away with it. + if objects[room_key].size() == 0: + objects.erase(room_key) -# Insert data to save into savegame. +# Remove an object from the registry by global_id +# +# #### Parameters +# +# - global_id: The global_id of the object to unregister +# - room_key: The room under which the object should be unregistered. +func unregister_object_by_global_id(global_id: String, room_key: String) -> void: + unregister_object(ESCObject.new(global_id, null), room_key) + + +# Insert data to save into savegame. For now, we only save the current room's +# objects. # # #### Parameters # # - p_savegame: The savegame resource func save_game(p_savegame: ESCSaveGame) -> void: + if current_room_key.empty() or objects[current_room_key] == null: + escoria.logger.report_errors( + "ESCObjectManager:save_game()", + [ + "No current room specified or found." + ] + ) + p_savegame.objects = {} - for obj_global_id in objects: - if !objects[obj_global_id] is ESCObject: + for obj_global_id in objects[current_room_key]: + if !objects[current_room_key][obj_global_id] is ESCObject: continue - p_savegame.objects[obj_global_id] = \ - objects[obj_global_id].get_save_data() + p_savegame.objects[current_room_key][obj_global_id] = \ + objects[current_room_key][obj_global_id].get_save_data() func get_start_location() -> ESCLocation: - for object in objects.values(): - if is_instance_valid(object.node) \ - and object.node is ESCLocation \ - and object.node.is_start_location: - return object + if objects.has(current_room_key): + for object in objects[current_room_key].values(): + if is_instance_valid(object.node) \ + and object.node is ESCLocation \ + and object.node.is_start_location: + return object + escoria.logger.report_warnings( - "esc_object_manager.gd:get_start_location()", + "ESCObjectManager:get_start_location()", [ "Room has no ESCLocation node with 'is_start_location' enabled.", "Player will be set at position (0,0) by default." ] ) return null + + +# Utility function to fashion a room key for the object manager. +func _make_room_key(room: ESCRoom) -> String: + return room.global_id + SEPARATOR + str(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 76880e84..4b774462 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 @@ -85,12 +85,13 @@ func change_scene(room_path: String, enable_automatic_transitions: bool) -> void ESCTransitionPlayer.TRANSITION_MODE.OUT ) - escoria.logger.debug( - "Awaiting transition %s (out) to be finished." % str(transition_id) - ) - - yield(escoria.main.scene_transition, "transition_done") - + if transition_id != escoria.main.scene_transition.TRANSITION_ID_INSTANT: + escoria.logger.debug( + "Awaiting transition %s (out) to be finished." % transition_id + ) + + yield(escoria.main.scene_transition, "transition_done") + # Hide main and pause menus escoria.game_scene.hide_main_menu() escoria.game_scene.unpause_game() @@ -232,8 +233,11 @@ func init_room(room: ESCRoom) -> void: room.player.global_id, room.player ), - true + room, + true, + false ) + if escoria.globals_manager.has( escoria.room_manager.GLOBAL_ANIMATION_RESOURCES ): @@ -269,8 +273,8 @@ func init_room(room: ESCRoom) -> void: func _perform_script_events(room: ESCRoom): if escoria.event_manager.is_channel_free(escoria.event_manager.CHANNEL_FRONT) \ or ( - not escoria.event_manager.is_channel_free(escoria.event_manager.CHANNEL_FRONT) and \ - not escoria.event_manager.get_running_event( + not escoria.event_manager.is_channel_free(escoria.event_manager.CHANNEL_FRONT) \ + and not escoria.event_manager.get_running_event( escoria.event_manager.CHANNEL_FRONT ).name == escoria.event_manager.EVENT_LOAD ): @@ -308,9 +312,28 @@ func _perform_script_events(room: ESCRoom): # Hide main and pause menus escoria.game_scene.hide_main_menu() escoria.game_scene.unpause_game() + + 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) + + if setup_event_added: + # Wait for setup event to be done + var rc = yield(escoria.event_manager, "event_finished") + while rc[1] != escoria.event_manager.EVENT_SETUP: + rc = yield(escoria.event_manager, "event_finished") + if rc[0] != ESCExecution.RC_OK: + return rc[0] - # Run the setup event - _run_script_event(escoria.event_manager.EVENT_SETUP, room) + # Switch the rooms (resources are freed at end of change_scene and in + # clear_scene). + + if room != escoria.main.current_scene: + escoria.main.current_scene.visible = false + #escoria.main.current_scene.z_index = -100 + + room.visible = true + #room.z_index = 0 if room.enabled_automatic_transitions \ or ( @@ -393,7 +416,7 @@ func _run_script_event(event_name: String, room: ESCRoom): [ "Queuing room script event %s" % event_name, "Composed of %s statements" % - str(room.compiled_script.events[event_name].statements.size()) + room.compiled_script.events[event_name].statements.size() ] ) escoria.event_manager.queue_event(room.compiled_script.events[event_name]) diff --git a/addons/escoria-core/game/core-scripts/esc_item.gd b/addons/escoria-core/game/core-scripts/esc_item.gd index 2da735cf..c512a381 100644 --- a/addons/escoria-core/game/core-scripts/esc_item.gd +++ b/addons/escoria-core/game/core-scripts/esc_item.gd @@ -200,6 +200,7 @@ func _ready(): global_id, self ), + null, true ) diff --git a/addons/escoria-core/game/core-scripts/esc_location.gd b/addons/escoria-core/game/core-scripts/esc_location.gd index 77442e32..6c789c7a 100644 --- a/addons/escoria-core/game/core-scripts/esc_location.gd +++ b/addons/escoria-core/game/core-scripts/esc_location.gd @@ -40,5 +40,6 @@ func _ready(): self.global_id, self ), + null, true ) diff --git a/addons/escoria-core/game/core-scripts/esc_room.gd b/addons/escoria-core/game/core-scripts/esc_room.gd index c251f2da..b2dd7e12 100644 --- a/addons/escoria-core/game/core-scripts/esc_room.gd +++ b/addons/escoria-core/game/core-scripts/esc_room.gd @@ -106,5 +106,3 @@ func set_editor_debug_mode(p_editor_debug_mode: int) -> void: editor_debug_mode = p_editor_debug_mode update() - - diff --git a/addons/escoria-core/game/main.gd b/addons/escoria-core/game/main.gd index 4e664453..5ef59231 100644 --- a/addons/escoria-core/game/main.gd +++ b/addons/escoria-core/game/main.gd @@ -37,13 +37,24 @@ func set_scene(p_scene: Node) -> void: if !p_scene: escoria.logger.report_errors("main", ["Trying to set empty scene"]) + if not p_scene.is_inside_tree(): + # Set the scene's visiblity for :setup events if the new room is not the + # same one as the current room. Note that the room's + # _ready() method will ensure that the room is visible when + # :setup is complete. + if not _is_same_scene(current_scene, p_scene): + p_scene.visible = false + + #p_scene.z_index = -100 + escoria.object_manager.set_current_room(p_scene) + add_child(p_scene) + move_child(p_scene, 0) + if current_scene != null: clear_scene() - if not p_scene.is_inside_tree(): - add_child(p_scene) - move_child(p_scene, 0) current_scene = p_scene + check_game_scene_methods() set_camera_limits() @@ -177,3 +188,9 @@ func check_game_scene_methods(): assert(current_scene.game.has_method("show_ui")) assert(current_scene.game.has_method("_on_event_done")) + +func _is_same_scene(scene_1: Node, scene_2: Node) -> bool: + if scene_1 is ESCRoom and scene_2 is ESCRoom: + return scene_1.global_id == scene_2.global_id + + return false diff --git a/addons/escoria-core/game/scenes/transitions/esc_transition_player.gd b/addons/escoria-core/game/scenes/transitions/esc_transition_player.gd index f3766145..ace493c2 100644 --- a/addons/escoria-core/game/scenes/transitions/esc_transition_player.gd +++ b/addons/escoria-core/game/scenes/transitions/esc_transition_player.gd @@ -2,12 +2,10 @@ extends ColorRect class_name ESCTransitionPlayer + # Emitted when the transition was played signal transition_done(transition_id) -# Id of the transition. Allows keeping track of the actual transition -# being played or finished -var transition_id: int = 0 # The valid transition modes enum TRANSITION_MODE { @@ -16,6 +14,17 @@ enum TRANSITION_MODE { } +# Id to represent instant/no transitions +const TRANSITION_ID_INSTANT = -1 + +# Instant transition type +const TRANSITION_INSTANT = "instant" + + +# Id of the transition. Allows keeping track of the actual transition +# being played or finished +var transition_id: int = 0 + # The tween instance to animate var _tween: Tween @@ -51,12 +60,27 @@ func transition( mode: int = TRANSITION_MODE.IN, duration: float = 1.0 ) -> int: + + if transition_name.empty(): + transition_name = escoria.project_settings_manager.get_setting( + escoria.project_settings_manager.DEFAULT_TRANISITION + ) + if not has_transition(transition_name): escoria.logger.report_errors( "transition: Transition %s not found" % transition_name, [] ) - + + # If this is an "instant" transition, we need to set the alpha of the base + # ColorRect to 0, since the transition materials used have a final state + # that sets this scene's root (ColorRect) alpha to 0. + if transition_name == TRANSITION_INSTANT: + color.a = 0 + return TRANSITION_ID_INSTANT + + var material_path = get_transition(transition_name) + material = ResourceLoader.load(get_transition(transition_name)) transition_id += 1 @@ -93,10 +117,6 @@ func transition( # # *Returns* the full path to the shader or an empty string, if it can't be found func get_transition(name: String) -> String: - if name.empty(): - name = escoria.project_settings_manager.get_setting( - escoria.project_settings_manager.DEFAULT_TRANISITION - ) for directory in escoria.project_settings_manager.get_setting( escoria.project_settings_manager.TRANSITION_PATHS ): @@ -114,7 +134,7 @@ func get_transition(name: String) -> String: # # *Returns* true if a transition exists with given name. func has_transition(name: String) -> bool: - return not get_transition(name) == "" + return name == TRANSITION_INSTANT or get_transition(name) != "" func _on_tween_completed(): diff --git a/addons/escoria-ui-simplemouse/game.gd b/addons/escoria-ui-simplemouse/game.gd index 3acc20ca..ad5238e8 100644 --- a/addons/escoria-ui-simplemouse/game.gd +++ b/addons/escoria-ui-simplemouse/game.gd @@ -1,6 +1,7 @@ extends ESCGame +const VERB_USE = "use" const VERB_WALK = "walk" @@ -69,8 +70,9 @@ var _is_gamepad_connected = false func _enter_tree(): var room_selector_parent = $CanvasLayer/ui/HBoxContainer/VBoxContainer - if ProjectSettings.get_setting("escoria/debug/enable_room_selector") and \ - room_selector_parent.get_node_or_null("room_select") == null: + if escoria.project_settings_manager.get_setting(escoria.project_settings_manager.ENABLE_ROOM_SELECTOR) \ + and room_selector_parent.get_node_or_null("room_select") == null: + room_selector_parent.add_child( preload( "res://addons/escoria-core/ui_library/tools/room_select" +\ @@ -204,10 +206,13 @@ func element_focused(element_id: String) -> void: var target_obj = escoria.object_manager.get_object(element_id).node $tooltip_layer/tooltip.set_target(target_obj.tooltip_name) - if escoria.action_manager.current_action != "use" \ + if escoria.action_manager.current_action != VERB_USE \ and escoria.action_manager.current_tool == null \ and target_obj is ESCItem: - $mouse_layer/verbs_menu.set_by_name(target_obj.default_action) + + $mouse_layer/verbs_menu.set_by_name( + target_obj.default_action + ) func element_unfocused() -> void: $tooltip_layer/tooltip.set_target("") @@ -239,8 +244,8 @@ func left_click_on_inventory_item(inventory_item_global_id: String, event: Input escoria.action_manager.ACTION.ITEM_LEFT_CLICK, [inventory_item_global_id, event] ) - - if escoria.action_manager.current_action == "use": + + if escoria.action_manager.current_action == VERB_USE: var item = escoria.object_manager.get_object( inventory_item_global_id ).node @@ -304,7 +309,7 @@ func show_main_menu(): func unpause_game(): if get_node(pause_menu).visible: get_node(pause_menu).hide() - escoria.object_manager.get_object("_camera").node.current = true + escoria.object_manager.get_object(escoria.object_manager.CAMERA).node.current = true escoria.main.current_scene.game.show_ui() escoria.main.current_scene.show() @@ -315,7 +320,7 @@ func pause_game(): escoria.save_manager.save_enabled ) get_node(pause_menu).show() - escoria.object_manager.get_object("_camera").node.current = false + escoria.object_manager.get_object(escoria.object_manager.CAMERA).node.current = false escoria.main.current_scene.game.hide_ui() escoria.main.current_scene.hide() diff --git a/game/rooms/room14/room14.tscn b/game/rooms/room14/room14.tscn index eb83a13f..f51f0112 100644 --- a/game/rooms/room14/room14.tscn +++ b/game/rooms/room14/room14.tscn @@ -97,7 +97,7 @@ margin_top = 194.216 margin_right = 408.569 margin_bottom = 259.216 text = "Show main menu -with autmatic +with automatic transitions enabled " align = 1