From d5a0022b7bdaea7310b7a62075d7ba85995372ec Mon Sep 17 00:00:00 2001 From: Dennis Ploeger Date: Sun, 20 Jun 2021 18:19:42 +0200 Subject: [PATCH] Optimization Part 2 (#6) Authored-by: Dennis Ploeger --- ...n.png-487276ed1e3a0c39cad0279d744ee560.md5 | 4 +- ....png-487276ed1e3a0c39cad0279d744ee560.stex | Bin 3493 -> 3841 bytes .../game/core-scripts/esc_item.gd | 38 ++-- .../game/core-scripts/esc_player.gd | 5 + addons/escoria-core/game/main.gd | 28 ++- .../game/scenes/camera_player/camera.tscn | 2 +- .../{esccamera.gd => esc_camera.gd} | 172 ++++++++++-------- .../scenes/camera_player/esc_camera_limits.gd | 28 +++ .../scenes/esc_prompt/esc_prompt_popup.gd | 24 +-- .../game/scenes/inventory/inventory_ui.gd | 132 +++++++++----- .../game/scenes/sound/bg_music.gd | 31 ++-- .../game/scenes/sound/bg_sound.gd | 30 +-- .../game/scenes/transitions/transition.gd | 31 +++- addons/escoria-core/plugin.cfg | 2 +- .../{editor/plugin_escoria.gd => plugin.gd} | 15 -- game/rooms/room7/esc/button_set_pos.esc | 2 - icon.png | Bin 3446 -> 3621 bytes project.godot | 8 +- 18 files changed, 330 insertions(+), 222 deletions(-) rename addons/escoria-core/game/scenes/camera_player/{esccamera.gd => esc_camera.gd} (50%) create mode 100644 addons/escoria-core/game/scenes/camera_player/esc_camera_limits.gd rename addons/escoria-core/{editor/plugin_escoria.gd => plugin.gd} (94%) diff --git a/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.md5 b/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.md5 index a111eeaa..2d669e69 100644 --- a/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.md5 +++ b/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.md5 @@ -1,3 +1,3 @@ -source_md5="0167658bc4406f0d0fe437e0197c415a" -dest_md5="64b0613b3173e1e1c96dd18b6569e62d" +source_md5="d7c036f59d6c4e0173f70e4eebbd2e05" +dest_md5="413338b9673fcea9c377d96aa3045396" diff --git a/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex b/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex index 002ad140fd6630db319e0b684cbd668888563df5..3415b9140746b1539c3ae6e96fb63229b4e7ffec 100644 GIT binary patch delta 3803 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 eR7zATCI1gLnmlA1Td*7e0000 void: - movable.teleport(target) + _movable.teleport(target) # Use the movable node to make the item walk to the given position @@ -282,7 +288,7 @@ func teleport(target: Node) -> void: # - pos: Position to walk to # - p_walk_context: Walk context to use func walk_to(pos : Vector2, p_walk_context: ESCWalkContext = null) -> void: - movable.walk_to(pos, p_walk_context) + _movable.walk_to(pos, p_walk_context) # Set the moving speed @@ -292,6 +298,11 @@ func walk_to(pos : Vector2, p_walk_context: ESCWalkContext = null) -> void: # - speed_value: Set the new speed func set_speed(speed_value : int) -> void: speed = speed_value + + +# Check wether this item moved +func has_moved() -> bool: + return _movable.moved if is_movable else false # Set the angle @@ -300,21 +311,21 @@ func set_speed(speed_value : int) -> void: # # Set the angle func set_angle(deg : int, immediate = true): - movable.set_angle(deg, immediate) + _movable.set_angle(deg, immediate) # Play the talking animation func start_talking(): if animation_sprite.is_playing(): animation_sprite.stop() - animation_sprite.play(animations.speaks[movable.last_dir][0]) + animation_sprite.play(animations.speaks[_movable.last_dir][0]) # Stop playing the talking animation func stop_talking(): if animation_sprite.is_playing(): animation_sprite.stop() - animation_sprite.play(animations.idles[movable.last_dir][0]) + animation_sprite.play(animations.idles[_movable.last_dir][0]) # Detect the child nodes and set respective references @@ -336,7 +347,8 @@ func _detect_children() -> void: # Upate the terrain when an event finished func _update_terrain(rc: int, event_name: String) -> void: - movable.update_terrain(event_name) + if is_movable: + _movable.update_terrain(event_name) # Get inventory item from the inventory item scene diff --git a/addons/escoria-core/game/core-scripts/esc_player.gd b/addons/escoria-core/game/core-scripts/esc_player.gd index 286cb1a1..b311ca08 100644 --- a/addons/escoria-core/game/core-scripts/esc_player.gd +++ b/addons/escoria-core/game/core-scripts/esc_player.gd @@ -12,6 +12,11 @@ class_name ESCPlayer export(NodePath) var camera_position_node +# A player is always movable +func _init(): + is_movable = true + + # Return the camera position if a camera_position_node exists or the # global position of the player func get_camera_pos(): diff --git a/addons/escoria-core/game/main.gd b/addons/escoria-core/game/main.gd index 70c96183..593c719a 100644 --- a/addons/escoria-core/game/main.gd +++ b/addons/escoria-core/game/main.gd @@ -92,23 +92,21 @@ func set_camera_limits(camera_limit_id : int = 0) -> void: area.size = get_viewport().size escoria.logger.info("Setting camera limits from scene ", [area]) - limits = { - "limit_left": area.position.x, - "limit_right": area.position.x + area.size.x, - "limit_top": area.position.y, - "limit_bottom": area.position.y + area.size.y, - "set_default": true, - } + limits = ESCCameraLimits.new( + area.position.x, + area.position.x + area.size.x, + area.position.y, + area.position.y + area.size.y + ) else: - limits = { - "limit_left": scene_camera_limits.position.x, - "limit_right": scene_camera_limits.position.x + \ + limits = ESCCameraLimits.new( + scene_camera_limits.position.x, + scene_camera_limits.position.x + \ scene_camera_limits.size.x, - "limit_top": scene_camera_limits.position.y, - "limit_bottom": scene_camera_limits.position.y + \ - scene_camera_limits.size.y + screen_ofs.y * 2, - "set_default": true, - } + scene_camera_limits.position.y, + scene_camera_limits.position.y + \ + scene_camera_limits.size.y + screen_ofs.y * 2 + ) escoria.logger.info( "Setting camera limits from parameter ", [scene_camera_limits] diff --git a/addons/escoria-core/game/scenes/camera_player/camera.tscn b/addons/escoria-core/game/scenes/camera_player/camera.tscn index 6c9cb0c8..fa7c9c60 100644 --- a/addons/escoria-core/game/scenes/camera_player/camera.tscn +++ b/addons/escoria-core/game/scenes/camera_player/camera.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=2 format=2] -[ext_resource path="res://addons/escoria-core/game/scenes/camera_player/esccamera.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/scenes/camera_player/esc_camera.gd" type="Script" id=1] [node name="camera" type="Camera2D"] current = true diff --git a/addons/escoria-core/game/scenes/camera_player/esccamera.gd b/addons/escoria-core/game/scenes/camera_player/esc_camera.gd similarity index 50% rename from addons/escoria-core/game/scenes/camera_player/esccamera.gd rename to addons/escoria-core/game/scenes/camera_player/esc_camera.gd index 00a719e5..0bf2b2e3 100644 --- a/addons/escoria-core/game/scenes/camera_player/esccamera.gd +++ b/addons/escoria-core/game/scenes/camera_player/esc_camera.gd @@ -1,67 +1,64 @@ +# Camera handling extends Camera2D class_name ESCCamera + +# Reference to the tween node for animating camera movements onready var tween = $"tween" -var default_limits = {} # This does not change once set +# Target position of the camera +var target: Vector2 = Vector2() -var speed = 0.0 -# Target can be object or Vector2. See resove_target_pos() -var target -var target_pos : Vector2 +# The object to follow +var follow_target: Node = null + +# Target zoom of the camera +var zoom_target: Vector2 var zoom_time -var zoom_target + # This is needed to adjust dialog positions and such, see dialog_instance.gd var zoom_transform -""" -Sets camera limits so it doesn't go out of the scene. If kwargs is null, default -limits are used. See Camera2D limits for more details. -- kwargs Dictionary (can be null) Limits to set. - - limit_left int Left limit. - - limit_right int Right limit. - - limit_top int Top limit. - - limit_bottom int Bottom limit. - - set_default bool (Facultative) If true, the given limits are save as default limits. -""" -func set_limits(kwargs=null): - if not kwargs: - kwargs = { - "limit_left": -10000, - "limit_right": 10000, - "limit_top": -10000, - "limit_bottom": 10000, - "set_default": false, - } - print_stack() +# Sets camera limits so it doesn't go out of the scene +# +# #### Parameters +# +# - limits: The limits to set +func set_limits(limits: ESCCameraLimits): + self.limit_left = limits.limit_left + self.limit_right = limits.limit_right + self.limit_top = limits.limit_top + self.limit_bottom = limits.limit_bottom - self.limit_left = kwargs["limit_left"] - self.limit_right = kwargs["limit_right"] - self.limit_top = kwargs["limit_top"] - self.limit_bottom = kwargs["limit_bottom"] - if "set_default" in kwargs and kwargs["set_default"] and not default_limits: - default_limits = kwargs +func _resolve_target_and_zoom(p_target) -> void: + target = Vector2() + zoom_target = Vector2() + follow_target = null + if p_target is Vector2: + target = p_target + elif p_target is Array: + var target_pos = Vector2() -func resolve_target_pos(): - if typeof(target) == TYPE_VECTOR2: - target_pos = target - elif typeof(target) == TYPE_ARRAY: - var count = 0 - - for obj in target: + for obj in p_target: target_pos += obj.get_camera_pos() - count += 1 # Let the error in if an empty array was passed (divzero) - target_pos = target_pos / count + target = target_pos / p_target.size() + elif p_target is Node and p_target.has_node("camera_pos") and \ + p_target.get_node("camera_pos") is Camera2D: + target = p_target.get_node("camera_pos").global_position + zoom_target = p_target.get_node("camera_pos").zoom + elif p_target is Node and "is_movable" in p_target and p_target.is_movable: + follow_target = p_target + elif p_target.has_method("get_camera_pos"): + target = p_target.get_camera_pos() else: - target_pos = target.get_camera_pos() + target = p_target.global_position - return target_pos func set_drag_margin_enabled(p_dm_h_enabled, p_dm_v_enabled): self.drag_margin_h_enabled = p_dm_h_enabled @@ -69,16 +66,19 @@ func set_drag_margin_enabled(p_dm_h_enabled, p_dm_v_enabled): func set_target(p_target, p_speed : float = 0.0): - speed = p_speed - target = p_target - - resolve_target_pos() + var speed = p_speed + + _resolve_target_and_zoom(p_target) + + if not follow_target == null: + target = follow_target.global_position + escoria.logger.info("Current camera position = " + str(self.global_position)) if speed == 0.0: - self.global_position = target_pos + self.global_position = target else: - var time = self.global_position.distance_to(target_pos) / speed + var time = self.global_position.distance_to(target) / speed if tween.is_active(): var tweenstat = String(tween.tell()) + "/" + String(tween.get_runtime()) @@ -86,8 +86,15 @@ func set_target(p_target, p_speed : float = 0.0): ["Tween still active running camera_set_target: " + tweenstat]) tween.emit_signal("tween_completed") - tween.interpolate_property(self, "global_position", self.global_position, - target_pos, time, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT) + tween.interpolate_property( + self, + "global_position", + self.global_position, + target, + time, + Tween.TRANS_LINEAR, + Tween.EASE_IN_OUT + ) tween.start() func set_camera_zoom(p_zoom_level, p_time): @@ -116,38 +123,52 @@ func push(p_target, p_time, p_type): var time = float(p_time) var type = "TRANS_" + p_type - target = p_target - - var camera_pos - var camera_pos_coords - if target.has_node("camera_pos"): - camera_pos = target.get_node("camera_pos") - camera_pos_coords = camera_pos.global_position + _resolve_target_and_zoom(p_target) + + var push_target = null + + if follow_target != null: + push_target = p_target.position else: - camera_pos_coords = target.global_position + push_target = target if time == 0: - self.global_position = camera_pos_coords - - if camera_pos and camera_pos is Camera2D: - self.zoom = camera_pos.zoom + self.global_position = push_target + if zoom_target != Vector2(): + self.zoom = zoom_target else: if tween.is_active(): var tweenstat = String(tween.tell()) + "/" + String(tween.get_runtime()) escoria.logger.report_warnings("camera", ["Tween still active running camera_push: " + tweenstat]) - tween.emit_signal("tween_completed") + tween.emit_signal("tween_completed", null, null) - if camera_pos and camera_pos is Camera2D: - tween.interpolate_property(self, "zoom", self.zoom, camera_pos.zoom, - time, tween.get(type), Tween.EASE_IN_OUT) + if zoom_target != Vector2(): + tween.interpolate_property( + self, + "zoom", + self.zoom, + zoom_target, + time, + tween.get(type), + Tween.EASE_IN_OUT + ) - tween.interpolate_property(self, "global_position", self.global_position, - camera_pos_coords, time, tween.get(type), Tween.EASE_IN_OUT) + tween.interpolate_property( + self, + "global_position", + self.global_position, + push_target, + time, + tween.get(type), + Tween.EASE_IN_OUT + ) + tween.start() func shift(p_x, p_y, p_time, p_type): + follow_target = null var x = int(p_x) var y = int(p_y) var time = float(p_time) @@ -173,18 +194,11 @@ func target_reached(): func _process(_delta): zoom_transform = self.get_canvas_transform() - if target and not tween.is_active(): - if typeof(target) == TYPE_VECTOR2 or typeof(target) == TYPE_ARRAY: - self.global_position = resolve_target_pos() - elif "moved" in target and target.moved \ - or "moved" in target.movable and target.movable.moved: - self.global_position = resolve_target_pos() + if follow_target and not tween.is_active() and follow_target.has_moved(): + self.global_position = follow_target.global_position func _ready(): - if not target: - target = Vector2(0, 0) - - tween.connect("tween_completed", self, "target_reached") + tween.connect("tween_all_completed", self, "target_reached") escoria.object_manager.register_object( ESCObject.new( self.name, diff --git a/addons/escoria-core/game/scenes/camera_player/esc_camera_limits.gd b/addons/escoria-core/game/scenes/camera_player/esc_camera_limits.gd new file mode 100644 index 00000000..bdbd06f1 --- /dev/null +++ b/addons/escoria-core/game/scenes/camera_player/esc_camera_limits.gd @@ -0,0 +1,28 @@ +# Describes a bounding box that limits the camera movement in the scene +extends Object +class_name ESCCameraLimits + + +# The left side of the bounding box +var limit_left: int = -10000 + +# The right side of the bounding box +var limit_right: int = 10000 + +# The top side of the bounding box +var limit_top: int = -10000 + +# The bottom side of the bounding box +var limit_bottom: int = 10000 + + +func _init( + left: int, + right: int, + top: int, + bottom: int +): + limit_left = left + limit_right = right + limit_top = top + limit_bottom = bottom diff --git a/addons/escoria-core/game/scenes/esc_prompt/esc_prompt_popup.gd b/addons/escoria-core/game/scenes/esc_prompt/esc_prompt_popup.gd index f75eed55..ecf016c3 100644 --- a/addons/escoria-core/game/scenes/esc_prompt/esc_prompt_popup.gd +++ b/addons/escoria-core/game/scenes/esc_prompt/esc_prompt_popup.gd @@ -1,15 +1,23 @@ +# A debug window which can run esc commands extends WindowDialog + +# Reference to the past actions display onready var past_actions = $VBoxContainer/past_actions + +# Reference to the command input onready var command = $VBoxContainer/command -var last_event_done := true +# Run a command +# +# #### Parameters +# +# - p_command_str: Command to execute func _on_command_text_entered(p_command_str : String): if p_command_str.empty(): return - last_event_done = false command.text = "" past_actions.text += "\n" past_actions.text += "# " + p_command_str @@ -24,19 +32,13 @@ func _on_command_text_entered(p_command_str : String): ]) if script: - escoria.event_manager.run(script.events["debug"]) + escoria.event_manager.queue_event(script.events["debug"]) var ret = yield(escoria.event_manager, "event_finished") while ret[1] != "debug": ret = yield(escoria.event_manager, "event_finished") - if not ret[0] == ESCExecution.RC_OK: - past_actions.text += "Returned code: %d" % ret[0] - - -func _on_event_done(event_name : String): - if event_name == "debug" and !last_event_done: - last_event_done = true -# past_actions.text += "\nDone.\n" + past_actions.text += "Returned code: %d" % ret[0] +# Set the focus to the command func _on_esc_prompt_popup_about_to_show(): command.grab_focus() diff --git a/addons/escoria-core/game/scenes/inventory/inventory_ui.gd b/addons/escoria-core/game/scenes/inventory/inventory_ui.gd index f74ada5b..e2188af0 100644 --- a/addons/escoria-core/game/scenes/inventory/inventory_ui.gd +++ b/addons/escoria-core/game/scenes/inventory/inventory_ui.gd @@ -1,43 +1,38 @@ +# Manages the inventory on the GUI connected to the inventory_ui_container +# variable extends Control class_name ESCInventory -func get_class(): - return "ESCInventory" -""" -This script is set on the inventory UI scene's root node. -The scene MUST contain the 2 following nodes: - - one node named "ESCORIA_ALL_ITEMS" containing ALL ESCItems of the game. This is required - to be able to get the ESCInventoryItem for a given ESCItem. - - one Container node (under Control type) that will contain the inventory items. - It must be set in the "items_container" export variable. -""" - - -# Define the actual container node to add items as children of. Should be a Container. +# Define the actual container node to add items as children of. +# Should be a Container. export(NodePath) var inventory_ui_container -onready var all_items = $ESCORIA_ALL_ITEMS -var items_ids_in_inventory : Dictionary = {} # { item_id : TextureButton} +# A registry of inventory ESCInventoryItem nodes +var items_ids_in_inventory : Dictionary = {} + + +# Fill the items the player has from the start, do sanity checks and +# listen when a global has changed func _ready(): -# # For debugging scene only. These 2 lines should remain commented on normal run. -# if !Engine.is_editor_hint(): -# return - + if inventory_ui_container == null or inventory_ui_container.is_empty(): + escoria.logger.report_errors( + self.get_path(), + ["Items container is empty."] + ) + return + for item_id in escoria.inventory_manager.items_in_inventory(): call_deferred("add_new_item_by_id", item_id) escoria.inventory = self - if inventory_ui_container == null or inventory_ui_container.is_empty(): - escoria.logger.report_errors(self.get_path(), ["Items container is empty."]) - return - for c in get_node(inventory_ui_container).get_items(): - items_ids_in_inventory[c.item_id] = c -# c.connect("pressed", escoria.inputs_manager, "_on_inventory_item_pressed", [c.item_id]) - - escoria.globals_manager.connect("global_changed", self, "_on_escoria_global_changed") + escoria.globals_manager.connect( + "global_changed", # + self, + "_on_escoria_global_changed" + ) # add item to Inventory UI using its id set in its scene @@ -73,7 +68,6 @@ func add_new_item_by_id(item_id : String) -> void: items_ids_in_inventory[item_id] = item_inventory_button get_node(inventory_ui_container).add_item(item_inventory_button) - # Add the item to inventory if not escoria.object_manager.has(item_id): escoria.object_manager.register_object( ESCObject.new( @@ -82,40 +76,74 @@ func add_new_item_by_id(item_id : String) -> void: ), true ) + item_inventory_button.visible = true - item_inventory_button.connect("mouse_left_inventory_item", - escoria.inputs_manager, "_on_mouse_left_click_inventory_item") - item_inventory_button.connect("mouse_double_left_inventory_item", - escoria.inputs_manager, "_on_mouse_double_left_click_inventory_item") - item_inventory_button.connect("mouse_right_inventory_item", - escoria.inputs_manager, "_on_mouse_right_click_inventory_item") + item_inventory_button.connect( + "mouse_left_inventory_item", + escoria.inputs_manager, + "_on_mouse_left_click_inventory_item" + ) + item_inventory_button.connect( + "mouse_double_left_inventory_item", + escoria.inputs_manager, + "_on_mouse_double_left_click_inventory_item" + ) + item_inventory_button.connect( + "mouse_right_inventory_item", + escoria.inputs_manager, + "_on_mouse_right_click_inventory_item" + ) - item_inventory_button.connect("inventory_item_focused", - escoria.inputs_manager, "_on_mouse_entered_inventory_item") - item_inventory_button.connect("inventory_item_unfocused", - escoria.inputs_manager, "_on_mouse_exited_inventory_item") + item_inventory_button.connect( + "inventory_item_focused", + escoria.inputs_manager, + "_on_mouse_entered_inventory_item" + ) + item_inventory_button.connect( + "inventory_item_unfocused", + escoria.inputs_manager, + "_on_mouse_exited_inventory_item" + ) + # remove item fromInventory UI using its id set in its scene func remove_item_by_id(item_id : String) -> void: if items_ids_in_inventory.has(item_id): var item_inventory_button = items_ids_in_inventory[item_id] - item_inventory_button.disconnect("mouse_left_inventory_item", - escoria.inputs_manager, "_on_mouse_left_click_inventory_item") - item_inventory_button.disconnect("mouse_double_left_inventory_item", - escoria.inputs_manager, "_on_mouse_double_left_click_inventory_item") - item_inventory_button.disconnect("mouse_right_inventory_item", - escoria.inputs_manager, "_on_mouse_right_click_inventory_item") - item_inventory_button.disconnect("inventory_item_focused", - escoria.inputs_manager, "_on_mouse_entered_inventory_item") - item_inventory_button.disconnect("inventory_item_unfocused", - escoria.inputs_manager, "_on_mouse_exited_inventory_item") + item_inventory_button.disconnect( + "mouse_left_inventory_item", + escoria.inputs_manager, + "_on_mouse_left_click_inventory_item" + ) + item_inventory_button.disconnect( + "mouse_double_left_inventory_item", + escoria.inputs_manager, + "_on_mouse_double_left_click_inventory_item" + ) + item_inventory_button.disconnect( + "mouse_right_inventory_item", + escoria.inputs_manager, + "_on_mouse_right_click_inventory_item" + ) + item_inventory_button.disconnect( + "inventory_item_focused", + escoria.inputs_manager, + "_on_mouse_entered_inventory_item" + ) + item_inventory_button.disconnect( + "inventory_item_unfocused", + escoria.inputs_manager, + "_on_mouse_exited_inventory_item" + ) get_node(inventory_ui_container).remove_item(item_inventory_button) item_inventory_button.queue_free() items_ids_in_inventory.erase(item_id) + +# React to changes to inventory globals adding items or removing them func _on_escoria_global_changed(global : String, old_value, new_value) -> void: if !global.begins_with("i/"): return @@ -126,4 +154,10 @@ func _on_escoria_global_changed(global : String, old_value, new_value) -> void: else: remove_item_by_id(item[0]) else: - escoria.logger.report_errors("inventory_ui.gd:_on_escoria_global_changed()", ["Global must contain 1 item name.", "(received: " + global + ")"]) + escoria.logger.report_errors( + "inventory_ui.gd:_on_escoria_global_changed()", + [ + "Global must contain only one item name.", + "(received: %s)" % global + ] + ) diff --git a/addons/escoria-core/game/scenes/sound/bg_music.gd b/addons/escoria-core/game/scenes/sound/bg_music.gd index b51bd032..c1398857 100644 --- a/addons/escoria-core/game/scenes/sound/bg_music.gd +++ b/addons/escoria-core/game/scenes/sound/bg_music.gd @@ -1,23 +1,28 @@ +# Background music player extends Control class_name ESCBackgroundMusic -func get_class(): - return "ESCBackgroundMusic" -onready var stream = $AudioStreamPlayer -var state = "default" -export var global_id = "bg_music" +# Global id of the background music player +export var global_id: String = "bg_music" -func game_cleared(): - set_state("off", true) - escoria.object_manager.register_object( - ESCObject.new(global_id, self), - true - ) +# The state of the music player. "default" or "off" disable music +# Any other state refers to a music stream that should be played +var state: String = "default" -func set_state(p_state, p_force = false): +# Reference to the audio player +onready var stream: AudioStreamPlayer = $AudioStreamPlayer + + +# Set the state of this player +# +# #### Parameters +# +# - p_state: New state to use +# - p_force: Override the existing state even if the stream is still playing +func set_state(p_state: String, p_force: bool = false) -> void: # If already playing this stream, keep playing, unless p_force if p_state == state and not p_force and stream.is_playing(): return @@ -39,6 +44,8 @@ func set_state(p_state, p_force = false): stream.volume_db = ProjectSettings.get_setting("escoria/sound/music_volume") stream.play() + +# Register to the object registry func _ready(): escoria.object_manager.register_object( ESCObject.new(global_id, self), diff --git a/addons/escoria-core/game/scenes/sound/bg_sound.gd b/addons/escoria-core/game/scenes/sound/bg_sound.gd index 88ddb488..eb0d07ef 100644 --- a/addons/escoria-core/game/scenes/sound/bg_sound.gd +++ b/addons/escoria-core/game/scenes/sound/bg_sound.gd @@ -1,23 +1,28 @@ +# Background sound player extends Control class_name ESCBackgroundSound -func get_class(): - return "ESCBackgroundSound" -onready var stream = $AudioStreamPlayer -var state = "default" -export var global_id = "bg_sound" +# Global id of the background sound player +export var global_id: String = "bg_sound" -func game_cleared(): - stream.stream = null - escoria.object_manager.register_object( - ESCObject.new(global_id, self), - true - ) +# The state of the sound player. "default" or "off" disable sound +# Any other state refers to a sound stream that should be played +var state: String = "default" -func set_state(p_state, p_force = false): +# Reference to the audio player +onready var stream: AudioStreamPlayer = $AudioStreamPlayer + + +# Set the state of this player +# +# #### Parameters +# +# - p_state: New state to use +# - p_force: Override the existing state even if the stream is still playing +func set_state(p_state: String, p_force: bool = false): # If already playing this stream, keep playing, unless p_force if p_state == state and not p_force and stream.is_playing(): return @@ -40,6 +45,7 @@ func set_state(p_state, p_force = false): stream.play() +# Register to the object registry func _ready(): escoria.object_manager.register_object( ESCObject.new(global_id, self), diff --git a/addons/escoria-core/game/scenes/transitions/transition.gd b/addons/escoria-core/game/scenes/transitions/transition.gd index b7232d34..bc681c95 100644 --- a/addons/escoria-core/game/scenes/transitions/transition.gd +++ b/addons/escoria-core/game/scenes/transitions/transition.gd @@ -1,28 +1,41 @@ +# A transition player for scene changes +# FIXME Add configuration to select a specific mask extends ColorRect -export(String, "fade_black", "fade_white", "transition_in", "transition_out") var transition_name + +# Emitted when the transition was player +signal transition_done + + +# The name of the transition to play +export( + String, + "fade_black", + "fade_white", + "transition_in", + "transition_out" +) var transition_name: String + + # Reference to the _AnimationPlayer_ node onready var _anim_player := $AnimationPlayer - -signal transition_done - - +# Fade in when the scene is starting func _ready() -> void: - # Plays the animation backward to fade in - _anim_player.play_backwards(transition_name) + fade_in() +# Fade out the transition func fade_out() -> void: - # Plays the Fade animation and wait until it finishes _anim_player.play(transition_name) yield(_anim_player, "animation_finished") emit_signal("transition_done") + +# Fade in the transition func fade_in() -> void: # Plays the Fade animation and wait until it finishes _anim_player.play_backwards(transition_name) yield(_anim_player, "animation_finished") emit_signal("transition_done") - diff --git a/addons/escoria-core/plugin.cfg b/addons/escoria-core/plugin.cfg index b6beea4f..d0ad6748 100755 --- a/addons/escoria-core/plugin.cfg +++ b/addons/escoria-core/plugin.cfg @@ -4,4 +4,4 @@ name="Escoria" description="A point'n'click framework within Godot Engine." author="StraToN" version="1.0.0" -script="editor/plugin_escoria.gd" +script="plugin.gd" diff --git a/addons/escoria-core/editor/plugin_escoria.gd b/addons/escoria-core/plugin.gd similarity index 94% rename from addons/escoria-core/editor/plugin_escoria.gd rename to addons/escoria-core/plugin.gd index 7cffcf98..ef06b4c8 100644 --- a/addons/escoria-core/editor/plugin_escoria.gd +++ b/addons/escoria-core/plugin.gd @@ -8,25 +8,12 @@ const autoloads = { "escoria": "res://addons/escoria-core/game/escoria.tscn", } -# Custom types to generate outside of Classes -const custom_types = [ - { - "type_name": "ESCItemsInventory", - "parent_type": "GridContainer", - "script_res": "res://addons/escoria-core/game/core-scripts/items_inventory.gd" - } -] - # Setup Escoria func _enter_tree(): for key in autoloads.keys(): add_autoload_singleton(key, autoloads[key]) - for custom_type in custom_types: - add_custom_type(custom_type.type_name, custom_type.parent_type, - load(custom_type.script_res), null) - # Prepare settings set_escoria_main_settings() set_escoria_debug_settings() @@ -251,7 +238,5 @@ func _exit_tree(): for key in autoloads.keys(): if ProjectSettings.has_setting(key): remove_autoload_singleton(key) - for custom_type in custom_types: - remove_custom_type(custom_type.type_name) diff --git a/game/rooms/room7/esc/button_set_pos.esc b/game/rooms/room7/esc/button_set_pos.esc index b39ea6e5..934b0fb6 100755 --- a/game/rooms/room7/esc/button_set_pos.esc +++ b/game/rooms/room7/esc/button_set_pos.esc @@ -6,8 +6,6 @@ camera_set_limits 2 camera_set_pos 500 150 150 wait 6 -camera_set_pos 1 1080 1000 -wait 1 camera_set_limits 0 camera_set_target 0 player diff --git a/icon.png b/icon.png index 2e42096c9664f3c8f496ec964d9989c551bda910..11f19e2de6fe26f8a51d34b6419ece1506b1f124 100644 GIT binary patch delta 3620 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 delta 3443 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 VKd{8edyoJC002ovPDHLkV1nna)QtcD diff --git a/project.godot b/project.godot index 489a7138..e6d3e320 100644 --- a/project.godot +++ b/project.godot @@ -107,7 +107,12 @@ _global_script_classes=[ { "base": "Camera2D", "class": "ESCCamera", "language": "GDScript", -"path": "res://addons/escoria-core/game/scenes/camera_player/esccamera.gd" +"path": "res://addons/escoria-core/game/scenes/camera_player/esc_camera.gd" +}, { +"base": "Object", +"class": "ESCCameraLimits", +"language": "GDScript", +"path": "res://addons/escoria-core/game/scenes/camera_player/esc_camera_limits.gd" }, { "base": "ESCStatement", "class": "ESCCommand", @@ -445,6 +450,7 @@ _global_script_class_icons={ "ESCBackgroundSound": "", "ESCBaseCommand": "", "ESCCamera": "", +"ESCCameraLimits": "", "ESCCommand": "", "ESCCommandArgumentDescriptor": "", "ESCCommandRegistry": "",