diff --git a/README b/README deleted file mode 100644 index a004eee6..00000000 --- a/README +++ /dev/null @@ -1,48 +0,0 @@ -# Escoria Rewrite - -Libre framework for the creation of point-and-click adventure games with -the MIT-licensed multi-platform game engine [Godot Engine](https://godotengine.org). - -This repository is big rewrite of the original Escoria framework (see https://github.com/godotengine/escoria/tree/master). -Its purpose is to make Escoria work as a plugin for Godot Engine editor, instead of being a collection of scripts and scenes. -It is intended to be easier to use and easier to maintain. It is designed so that you can claim it for yourself and modify it to match -the needs of your specific game and team. - -Escoria should always be compatible with the current stable version of Godot Engine, and you should use -If you're encountering issues or incompatibilities, please raise an issue on [Escoria's Github repository](https://github.com/godotengine/escoria/issues). - -## Authors - -In alphabetical order: - -ArturM -Sylvain Beucler - beuc -Fleskevor -Ariel Manzur - punto (original author) -Julian Murgia - StraToN -Dennis Ploeger - dploeger -Markus Törnqvist - mjtorn - -## History - -This framework was initially developed for the adventure game -[The Interactive Adventures of Dog Mendonça and Pizzaboy®](http://store.steampowered.com/app/330420) -and later streamlined for broader usages and open sourced as promised -to the backers of the Dog Mendonça Kickstarter campaign. - -## Usage - - -## Documentation - - -## Licensing - -This framework (scripts, scenes) is distributed under the MIT license, -as described in the LICENSE file. - -### Art, sound, fonts credits - -See CREDITS file. - - diff --git a/README.md b/README.md new file mode 100644 index 00000000..6de69146 --- /dev/null +++ b/README.md @@ -0,0 +1,97 @@ +# Escoria Rewrite + +Libre framework for the creation of point-and-click adventure games with +the MIT-licensed multi-platform game engine [Godot Engine](https://godotengine.org). + +It is designed so that you can claim it for yourself and modify it to match +the needs of your specific game and team. + +This repository is big rewrite of the original [Escoria framework](https://github.com/godotengine/escoria/tree/master). Its purpose is to make Escoria work as a plugin for the Godot Engine editor, instead of being a collection of scripts and scenes. It is intended to be easier to use and easier to maintain. + +If you're encountering issues or incompatibilities, please raise an issue on [Escoria's Github repository](https://github.com/godotengine/escoria/issues). + +## History + +This framework was initially developed for the adventure game +[The Interactive Adventures of Dog Mendonça and Pizzaboy®](http://store.steampowered.com/app/330420) +and later streamlined for broader usages and open sourced as promised +to the backers of the Dog Mendonça Kickstarter campaign. + +## Authors + +In alphabetical order: + +* ArturM +* Sylvain Beucler - beuc +* Fleskevor +* Ariel Manzur - punto (original author) +* Julian Murgia - @StraToN +* Dennis Ploeger - @dploeger +* Markus Törnqvist - mjtorn + +## Documentation + +* Getting started +* [Architecture](docs/architecture.md) +* [Configuration](docs/configuration.md) +* [ESC language documentation](api/esc.md) + +## Roadmap + +The rewrite is currently ongoing and certain features of Escoria are missing or require optimization: + +### Basic features + +* [ ] Implement load/save games +* [ ] Implement switching player characters +* [ ] Visualize scaling in editor + +### Optimizations + +* [ ] Add the currently unfocused inventory item to the `inventory_item_unfocused` signal of `ESCInventoryItem` + +* [ ] The `_hover_stack_pop` method in `main_scene` doesn't pop (=remove the last element from the stack) but rather erases the given item from the stack. This may either be a hidden bug or a naming issue + +* [ ] The variable `screen_ofs` of main.gd is always set to Vector2(0, 0). Either it's unused or its function has yet to be documented + +* [ ] Should we keep defining the animations in a script instead of a real object? Providing a script as a parameter to a function seems weird + +* [ ] Fix all TODO and FIXME places in the code + +* [ ] Reimplement all missing ESC commands + +### Future features + +* [ ] Integrated ESC editor +* [ ] Graphical visualizer of room links +* [ ] Optimize character angles and animation helper + +## Licensing + +This framework (scripts, scenes) is distributed under the [MIT license](LICENCE). + +### Art credits + + +### Sound credits + + +### Font + +## Development + +Requirements: + +* git +* Current Godot version +* Current master of [GDScript docs maker](https://github.com/GDQuest/gdscript-docs-maker) + +During development, run the following to update the class list: + +``` +cd gdscripts-docs-maker +rm -rf export &>/dev/null +./generate_reference -d "addons/escoria" +cp export/* /docs/api +``` + diff --git a/addons/escoria-core/editor/plugin_escoria.gd b/addons/escoria-core/editor/plugin_escoria.gd index d2bb1ba4..7cffcf98 100644 --- a/addons/escoria-core/editor/plugin_escoria.gd +++ b/addons/escoria-core/editor/plugin_escoria.gd @@ -1,63 +1,42 @@ +# Plugin script to initialize Escoria tool extends EditorPlugin + +# Autoloads to instantiate const autoloads = { "escoria": "res://addons/escoria-core/game/escoria.tscn", - "esctypes": "res://addons/escoria-core/game/core-scripts/escoria_types.gd" } +# Custom types to generate outside of Classes const custom_types = [ - { - "type_name": "ESCBackground", - "parent_type": "Sprite", - "script_res": "res://addons/escoria-core/game/core-scripts/escbackground.gd" - }, - { - "type_name": "ESCItem", - "parent_type": "Area2D", - "script_res": "res://addons/escoria-core/game/core-scripts/escitem.gd" - }, { "type_name": "ESCItemsInventory", "parent_type": "GridContainer", "script_res": "res://addons/escoria-core/game/core-scripts/items_inventory.gd" - }, - { - "type_name": "ESCInventoryItem", - "parent_type": "TextureButton", - "script_res": "res://addons/escoria-core/game/core-scripts/escinventoryitem.gd" - }, - { - "type_name": "ESCPlayer", - "parent_type": "KinematicBody2D", - "script_res": "res://addons/escoria-core/game/core-scripts/escplayer.gd" - }, - { - "type_name": "ESCRoom", - "parent_type": "Node2D", - "script_res": "res://addons/escoria-core/game/core-scripts/escroom.gd" - }, - { - "type_name": "ESCTerrain", - "parent_type": "Navigation2D", - "script_res": "res://addons/escoria-core/game/core-scripts/escterrain.gd" } ] + +# Setup Escoria func _enter_tree(): - add_autoloads() + 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() set_escoria_ui_settings() set_escoria_internal_settings() set_escoria_sound_settings() - - + set_escoria_platform_settings() + + +# Prepare the settings in the Escoria UI category func set_escoria_ui_settings(): if !ProjectSettings.has_setting("escoria/ui/tooltip_follows_mouse"): ProjectSettings.set_setting("escoria/ui/tooltip_follows_mouse", true) @@ -110,8 +89,21 @@ func set_escoria_ui_settings(): "hint_string": "*.tscn, *.scn" } ProjectSettings.add_property_info(game_scene_property_info) + + if !ProjectSettings.has_setting("escoria/ui/items_autoregister_path"): + ProjectSettings.set_setting( + "escoria/ui/items_autoregister_path", + "res://game/items/escitems/" + ) + var game_scene_property_info = { + "name": "escoria/ui/items_autoregister_path", + "type": TYPE_STRING, + "hint": PROPERTY_HINT_DIR + } + ProjectSettings.add_property_info(game_scene_property_info) +# Prepare the settings in the Escoria main category func set_escoria_main_settings(): if !ProjectSettings.has_setting("escoria/main/game_start_script"): ProjectSettings.set_setting("escoria/main/game_start_script", "") @@ -132,7 +124,7 @@ func set_escoria_main_settings(): ProjectSettings.add_property_info(force_quit_property_info) ProjectSettings.set_setting("application/run/main_scene", "res://addons/escoria-core/game/main_scene.tscn") - + if not ProjectSettings.has_setting("escoria/main/command_directories"): ProjectSettings.set_setting("escoria/main/command_directories", [ "res://addons/escoria-core/game/core-scripts/esc/commands" @@ -142,7 +134,7 @@ func set_escoria_main_settings(): "type": TYPE_ARRAY, }) - + if !ProjectSettings.has_setting("escoria/main/text_lang"): ProjectSettings.set_setting("escoria/main/text_lang", TranslationServer.get_locale()) var text_lang_property_info = { @@ -151,7 +143,7 @@ func set_escoria_main_settings(): "hint": PROPERTY_HINT_NONE } ProjectSettings.add_property_info(text_lang_property_info) - + if !ProjectSettings.has_setting("escoria/main/voice_lang"): ProjectSettings.set_setting("escoria/main/voice_lang", TranslationServer.get_locale()) var voice_lang_property_info = { @@ -160,13 +152,9 @@ func set_escoria_main_settings(): "hint": PROPERTY_HINT_NONE } ProjectSettings.add_property_info(voice_lang_property_info) - - - - - - - + + +# Prepare the settings in the Escoria debug category func set_escoria_debug_settings(): if !ProjectSettings.has_setting("escoria/debug/terminate_on_warnings"): ProjectSettings.set_setting("escoria/debug/terminate_on_warnings", false) @@ -190,6 +178,7 @@ func set_escoria_debug_settings(): ProjectSettings.add_property_info(property_info) +# Prepare the settings in the Escoria internal category func set_escoria_internal_settings(): if !ProjectSettings.has_setting("escoria/internals/save_data"): ProjectSettings.set_setting("escoria/internals/save_data", "") @@ -202,6 +191,7 @@ func set_escoria_internal_settings(): ProjectSettings.add_property_info(save_data_property_info) +# Prepare the settings in the Escoria sound settings func set_escoria_sound_settings(): if !ProjectSettings.has_setting("escoria/sound/master_volume"): ProjectSettings.set_setting("escoria/sound/master_volume", 1) @@ -212,7 +202,7 @@ func set_escoria_sound_settings(): "hint_string": "0,1" } ProjectSettings.add_property_info(master_data_property_info) - + if !ProjectSettings.has_setting("escoria/sound/music_volume"): ProjectSettings.set_setting("escoria/sound/music_volume", 1) var music_data_property_info = { @@ -242,37 +232,26 @@ func set_escoria_sound_settings(): "hint_string": "0,1" } ProjectSettings.add_property_info(speech_data_property_info) - -# Defines platform-specific parameters. Those are the ones that must be re-set for each platform export. +# Prepare the settings in the Escoria platform category and may need special +# setting per build func set_escoria_platform_settings(): - # Skip cache - certain platforms (esp. mobile) lack memory for caching scenes - # If true, all generic scenes (UI, inventory, etc) will be loaded as any other scene. + # Skip cache - certain platforms (esp. mobile) lack memory for caching + # scenes. + # If set to true, all generic scenes (UI, inventory, etc) will be loaded + # as any other scene. if !ProjectSettings.has_setting("escoria/platform/skip_cache"): ProjectSettings.set_setting("escoria/platform/skip_cache", false) - - + if !ProjectSettings.has_setting("escoria/platform/skip_cache.mobile"): + ProjectSettings.set_setting("escoria/platform/skip_cache.mobile", true) -func add_autoloads(): - for key in autoloads.keys(): - add_autoload_singleton(key, autoloads[key]) - -func remove_autoloads(): +# Uninstall plugin +func _exit_tree(): for key in autoloads.keys(): if ProjectSettings.has_setting(key): remove_autoload_singleton(key) - - -func _exit_tree(): - remove_custom_type("ESCBackground") - remove_custom_type("ESCItem") - remove_custom_type("ESCInventoryItem") - remove_custom_type("ESCItemsInventory") - remove_custom_type("ESCPlayer") - remove_custom_type("ESCRoom") - remove_custom_type("ESCTerrain") - - remove_autoloads() + for custom_type in custom_types: + remove_custom_type(custom_type.type_name) diff --git a/addons/escoria-core/game/core-scripts/behaviors/esc_movable.gd b/addons/escoria-core/game/core-scripts/behaviors/esc_movable.gd new file mode 100644 index 00000000..b13fd84a --- /dev/null +++ b/addons/escoria-core/game/core-scripts/behaviors/esc_movable.gd @@ -0,0 +1,438 @@ +# Node that performs the moving (walk, teleport, terrain scaling...) actions on +# its parent node. +tool +extends Node +class_name ESCMovable + + +# Tasks carried out by this walkable node +# NONE - The node is inactive +# WALK - The node walks the parent somewhere +# SLIDE - The node slides the parent somewhere +enum MovableTask { + NONE, + WALK, + SLIDE +} + + +# Character path through the scene as calculated by the Pathfinder +var walk_path: Array = [] + +# Current active walk path entry +var path_ofs: int + +# The destination where the character should be moving to +var walk_destination: Vector2 + +# The walk context currently carried out by this movable node +var walk_context: ESCWalkContext = null + +# Wether the character was moved at all +var moved: bool + +# Angle degrees to the last position (TODO is that correct?) +var last_deg : int + +# Direction of the last position (TODO is that correct?) +var last_dir : int + +# Scale of the last position (TODO is that correct?) +var last_scale : Vector2 + +# TODO Isn't this actually the flip state of the current animation? +var pose_scale : int + + +var _orig_speed: float = 0.0 + + +# Shortcut variable that references the node's parent +onready var parent = get_parent() + +# If character misses an animation, bypass it and proceed. +onready var bypass_missing_animation = false + + +# Currenly running task +onready var task = MovableTask.NONE + + +# Add the signal "arrived" to the parent node, which is emitted when +# the destination position was reached +func _ready() -> void: + parent.add_user_signal("arrived") + + +# Main processing loop +# +# #### Parameters +# +# - delta: Time that has passed since the last call to this function +func _process(delta: float) -> void: + if Engine.is_editor_hint(): + return + + if task == MovableTask.WALK or \ + task == MovableTask.SLIDE: + var pos = parent.get_position() + var old_pos = pos + var next + if walk_path.size() > 1: + next = walk_path[path_ofs + 1] + else: + next = walk_path[path_ofs] + + var dist = parent.speed * delta * pow(last_scale.x, 2) * \ + parent.terrain.player_speed_multiplier + if walk_context.fast: + dist *= parent.terrain.player_doubleclick_speed_multiplier + var dir = (next - pos).normalized() + + # TODO comment what this is all about + dir = dir * (dir.x * dir.x + dir.y * dir.y * parent.v_speed_damp) + + var new_pos + if pos.distance_to(next) < dist: + new_pos = next + path_ofs += 1 + else: + new_pos = pos + dir * dist + + if path_ofs >= walk_path.size() - 1: + walk_stop(walk_destination) + return + + pos = new_pos + + var angle = (old_pos.angle_to_point(pos)) + parent.set_position(pos) + + if task == MovableTask.WALK: + last_deg = escoria.utils.get_deg_from_rad(angle) + last_dir = _get_dir_deg(last_deg, parent.animations) + + var current_animation = "" + if parent.animation_sprite != null: + current_animation = parent.animation_sprite.animation +# elif animation != null: +# current_animation = animation.current_animation + + # FIXME This is obviously wrong as bypass_missing_animation is + # always false + bypass_missing_animation = false + if !bypass_missing_animation: + var animation_to_play = \ + parent.animations.directions[last_dir][0] + if current_animation != animation_to_play: + if parent.animation_sprite.frames.has_animation( + animation_to_play + ): + parent.animation_sprite.play(animation_to_play) + else: + bypass_missing_animation = true + current_animation = animation_to_play + escoria.logger.report_warnings( + "movable.gd:_process()", + [ + "Character %s has no animation %s " + % [parent.global_id, animation_to_play], + "Bypassing missing animation and " + + "proceed movement." + ], + true + ) + + pose_scale = parent.animations.directions[last_dir][1] + + update_terrain() + else: + moved = false + set_process(false) + + +# Teleports this item to the target position. +# TODO angle is only used for logging and has no further use, so it probably +# can be removed +# +# #### Parameters +# +# - target: Vector2, Position2d or ESCItem +func teleport(target, angle : Object = null) -> void: + if typeof(target) == TYPE_VECTOR2 : + escoria.logger.info( + "Object %s teleported at position %s with angle" % + [parent.global_id, str(target)], + [angle] + ) + parent.position = target + elif target is Position2D: + escoria.logger.info( + "Object %s teleported at position %s with angle" % + [parent.global_id, str(target.position)], + [angle] + ) + parent.position = target.position + elif typeof(target) == TYPE_OBJECT: + # FIXME this is better written as target is ESCItem if that's + # the only case here +# if target.get("interact_positions") != null: +# parent.position = target.interact_positions.default +# else: +# parent.position = target.position + parent.position = target.get_interact_position() + escoria.logger.info("Object " + target.name + " teleported at position " + + str(parent.position) + " with angle ", str(angle)) + else: + escoria.logger.report_errors("escitem.gd:teleport()", + ["Target to teleport to is null or unusable (" + target + ")"]) + + +# Walk to a given position +# +# #### Parameters +# +# - pos: Position to walk to +# - p_walk_context: Walk context to use +func walk_to(pos : Vector2, p_walk_context: ESCWalkContext = null) -> void: + if not parent.terrain: + walk_stop(parent.get_position()) + return + + if task == MovableTask.WALK: + if walk_context.target_object == p_walk_context.target_object \ + or walk_context.target_position == p_walk_context.target_position: + walk_context.fast = p_walk_context.fast + + walk_context = p_walk_context + + if task == MovableTask.NONE: + task = MovableTask.WALK + + walk_path = parent.terrain.get_simple_path(parent.get_position(), pos, true) + + if walk_path.size() == 0: + task = MovableTask.NONE + walk_stop(parent.get_position()) + set_process(false) + return + moved = true + walk_destination = walk_path[walk_path.size()-1] + path_ofs = 0 + task = MovableTask.WALK + set_process(true) + + +# FIXME this function doesn't seem to be used anywhere +func walk(target_pos, p_speed, context = null) -> void: + if p_speed: + _orig_speed = parent.speed + parent.speed = p_speed + walk_to(target_pos, context) + + +# We have finished walking. Set the idle pose and complete +# +# #### Parameters +# +# - pos: Final target position +func walk_stop(pos: Vector2) -> void: + parent.position = pos +# parent.interact_status = parent.INTERACT_STATES.INTERACT_NONE + walk_path = [] + + if _orig_speed > 0: + parent.speed = _orig_speed + _orig_speed = 0.0 + + task = MovableTask.NONE + moved = false + set_process(false) + + # If we're heading to an object and reached its interaction position, + # orient towards the defined interaction direction set on the object + # (if any) + if walk_context.target_object and \ + walk_context.target_object.node.player_orients_on_arrival and \ + walk_context.target_object.interactive: + var orientation = walk_context.target_object.node.interaction_direction + last_dir = orientation + parent.animation_sprite.play( + parent.animations.idles[orientation][0] + ) + pose_scale = parent.animations.idles[orientation][1] + else: + parent.animation_sprite.play(parent.animations.idles[last_dir][0]) + pose_scale = parent.animations.idles[last_dir][1] + + update_terrain() + + yield(parent.animation_sprite, "animation_finished") + if walk_context.target_object: + escoria.logger.debug( + "%s arrived at %s" % [ + parent.global_id, + walk_context.target_object.global_id + ] + ) + else: + escoria.logger.debug( + "%s arrived at %s" % [ + parent.global_id, + walk_context.target_position + ] + ) + parent.emit_signal("arrived", walk_context) + + +# Update the sprite scale and lighting +# +# #### Parameters +# +# - on_event_finished_name: Used if this function is called from an ESC event +func update_terrain(on_event_finished_name = null) -> void: + if !parent.terrain or parent.terrain == null \ + or !is_instance_valid(parent.terrain): + return + if on_event_finished_name != null and on_event_finished_name != "setup": + return + if parent.get("is_exit"): + return + if parent.get("dont_apply_terrain_scaling"): + return + + var pos = parent.position + if pos.y <= VisualServer.CANVAS_ITEM_Z_MAX: + parent.z_index = pos.y + else: + parent.z_index = VisualServer.CANVAS_ITEM_Z_MAX + + var factor = parent.terrain.get_terrain(pos) + var scal = parent.terrain.get_scale_range(factor) + if scal != parent.get_scale(): + last_scale = scal + parent.scale = last_scale + + var color = parent.terrain.get_light(pos) + parent.modulate = color + + # Do not flip the entire character, because that would conflict + # with shadows that expect to be siblings of $texture + # TODO Make the character sprite not rely on the node name + if pose_scale == -1 and parent.get_node("sprite").scale.x > 0: + parent.get_node("sprite").scale.x *= pose_scale + parent.collision.scale.x *= pose_scale + elif pose_scale == 1 and parent.get_node("sprite").scale.x < 0: + parent.get_node("sprite").scale.x *= -1 + parent.collision.scale.x *= -1 + + +# Get the player direction index based on rotation angles +# +# FIXME: This function doesn't seem to be used anymore +# #### Parameters +# +# - angle: The rotation angle +# - animations: The list of character animations +func _get_dir(angle : float, animations) -> int: + var deg = escoria.utils.get_deg_from_rad(angle) + return _get_dir_deg(deg, animations) + + +# Get the player direction index based on degrees +# +# #### Parameters +# +# - deg: Degrees +# - animations: Player animations script +func _get_dir_deg(deg: int, animations: Script) -> int: + # We turn the angle by -90° because angle_to_point gives the angle + # against X axis, not Y + deg = wrapi(deg - 90, 0, 360) + var dir = -1 + var i = 0 + + for arr_angle_zone in animations.dir_angles: + if is_angle_in_interval(deg, arr_angle_zone): + dir = i + break + else: + i += 1 + continue + + # It's an error to have the animations misconfigured + if dir == -1: + escoria.logger.report_errors( + "escitem.gd:_get_dir_deg()", + ["No direction found for " + str(deg)] + ) + + return dir + + +# Returns true if given angle is inside the interval given by a starting_angle +# and the size. +# TODO Refactor to make this stuff understandable :D +# +# #### Parameters +# +# - angle: Angle to test +# - interval : Array of size 2, containing the starting angle, and the size of +# interval +# eg: [90, 40] corresponds to angle between 90° and 130° +func is_angle_in_interval(angle: float, interval : Array) -> bool: + angle = wrapi(angle, 0, 360) + if angle == 0: + angle = 360 + var start_angle = wrapi(interval[0], 0, 360) + var angle_area = interval[1] + var end_angle = wrapi(interval[0] + angle_area, 0, 360) + + if ((angle >= 270 and angle <= 360) \ + or (angle >= 0 and angle <= 90)) \ + and wrapi(angle + 180, 0, 360) > wrapi(interval[0] + 180, 0, 360) \ + and wrapi(angle + 180, 0, 360) <= wrapi( + interval[0] + angle_area + 180, 0, 360 + ): + return true + elif wrapi(angle, 0, 360) > start_angle \ + and wrapi(angle, 0, 360) <= end_angle: + return true + + return false + +# Sets character's angle and plays according animation. +# +# TODO: depending on current angle and current angle, the character may +# directly turn around with no "progression". We may enhance this by +# calculating successive directions to turn the character to, so that he +# doesn't switch to opposite direction too fast. +# For example, if character looks WEST and set_angle(EAST) is called, we may +# want the character to first turn SOUTHWEST, then SOUTH, then SOUTHEAST and +# finally EAST, all more or less fast. +# Whatever the implementation, this should be activated using "parameter +# "immediate" set to false. +# +# #### Parameters +# +# - deg int angle to set the character +# - immediate bool (currently unused, see TODO below) +# If true, direction is switched immediately. Else, successive animations are +# used so that the character turns to target angle. +func set_angle(deg : int, immediate = true) -> void: + if deg < 0 or deg > 360: + escoria.logger.report_errors( + "movable.gd:set_angle()", + ["Invalid degree to turn to " + str(deg)] + ) + moved = true + last_deg = deg + last_dir = _get_dir_deg(deg, parent.animations) + + # The character may have a state animation from before, which would be + # resumed, so we immediately force the correct idle animation + if parent.animation_sprite.animation != \ + parent.animations.idles[last_dir][0]: + parent.animation_sprite.play(parent.animations.idles[last_dir][0]) + pose_scale = parent.animations.idles[last_dir][1] + update_terrain() diff --git a/addons/escoria-core/game/core-scripts/behaviors/interactive.gd b/addons/escoria-core/game/core-scripts/behaviors/interactive.gd deleted file mode 100644 index 38c4d540..00000000 --- a/addons/escoria-core/game/core-scripts/behaviors/interactive.gd +++ /dev/null @@ -1,4 +0,0 @@ -extends Node - -func _ready(): - pass diff --git a/addons/escoria-core/game/core-scripts/behaviors/movable.gd b/addons/escoria-core/game/core-scripts/behaviors/movable.gd deleted file mode 100644 index a5c01938..00000000 --- a/addons/escoria-core/game/core-scripts/behaviors/movable.gd +++ /dev/null @@ -1,334 +0,0 @@ -tool -extends Node -class_name Movable - -""" -This class performs the moving (walk, teleport, terrain scaling...) actions on -the parent node. -""" - - -onready var parent = get_parent() - -# If character misses an animation, bypass it and proceed. -onready var bypass_missing_animation = false - -var walk_path : Array = [] -var walk_destination : Vector2 -var walk_context -var moved : bool -var path_ofs : float - -var last_deg : int -var last_dir : int -var last_scale : Vector2 -var pose_scale : int - - - -func _ready(): - parent.add_user_signal("arrived") - -func _process(time): - if Engine.is_editor_hint(): - return - - if parent.task == parent.PLAYER_TASKS.WALK or parent.task == parent.PLAYER_TASKS.SLIDE: - var pos = parent.get_position() - var old_pos = pos - var next - if walk_path.size() > 1: - next = walk_path[path_ofs + 1] - else: - next = walk_path[path_ofs] - - var dist = parent.speed * time * pow(last_scale.x, 2) * \ - parent.terrain.player_speed_multiplier - if walk_context and "fast" in walk_context and walk_context.fast: - dist *= parent.terrain.player_doubleclick_speed_multiplier - var dir = (next - pos).normalized() - - # assume that x^2 + y^2 == 1, apply v_speed_damp the y axis - #printt("dir before", dir) - dir = dir * (dir.x * dir.x + dir.y * dir.y * parent.v_speed_damp) - #printt("dir after", dir, dist) - - var new_pos - if pos.distance_to(next) < dist: - new_pos = next - path_ofs += 1 - else: - new_pos = pos + dir * dist - - if path_ofs >= walk_path.size() - 1: - walk_stop(walk_destination) - return - - pos = new_pos - - var angle = (old_pos.angle_to_point(pos)) - parent.set_position(pos) - - if parent.task == parent.PLAYER_TASKS.WALK: - last_deg = escoria.utils._get_deg_from_rad(angle) - last_dir = _get_dir_deg(last_deg, parent.animations) - - var current_animation = "" - if parent.animation_sprite != null: - current_animation = parent.animation_sprite.animation -# elif animation != null: -# current_animation = animation.current_animation - - bypass_missing_animation = false - if !bypass_missing_animation: - var animation_to_play = parent.animations.directions[last_dir][0] - if current_animation != animation_to_play: - if parent.animation_sprite.frames.has_animation(animation_to_play): - parent.animation_sprite.play(animation_to_play) - else: - bypass_missing_animation = true - current_animation = animation_to_play - escoria.logger.report_warnings("movable.gd:_process()", - ["Character " + parent.global_id + " has no animation " + animation_to_play, - "Bypassing missing animation and proceed movement."], true) - - pose_scale = parent.animations.directions[last_dir][1] - - update_terrain() - else: - moved = false - set_process(false) - - -func teleport(target, angle : Object = null) -> void: - """ - Teleports the item on target position. - target can be Vector2 or Object - """ - if typeof(target) == TYPE_VECTOR2 : - escoria.logger.info("Object " + parent.global_id + " teleported at position " + - str(target) + " with angle", [angle]) - parent.position = target - elif target is Position2D: - escoria.logger.info("Object " + parent.global_id + " teleported at position " + - str(target.position) + " with angle", [angle]) - parent.position = target.position - elif typeof(target) == TYPE_OBJECT: -# if target.get("interact_positions") != null: -# parent.position = target.interact_positions.default #.global_position -# else: -# parent.position = target.position - parent.position = target.get_interact_position() - escoria.logger.info("Object " + target.name + " teleported at position " - + str(parent.position) + " with angle ", str(angle)) - else: - escoria.logger.report_errors("escitem.gd:teleport()", ["Target to teleport to is null or unusable (" + target + ")"]) - -# PUBLIC FUNCTION -func walk_to(pos : Vector2, p_walk_context = null): - if not parent.terrain: - return walk_stop(parent.get_position()) - - if parent.task == parent.PLAYER_TASKS.WALK: - if walk_context.has("target_object") and p_walk_context.has("target_object"): - if walk_context["target_object"] == p_walk_context["target_object"]: - walk_context["fast"] = p_walk_context["fast"] - return true - elif walk_context.has("target") and p_walk_context.has("target"): - if walk_context["target"] == p_walk_context["target"]: - walk_context["fast"] = p_walk_context["fast"] - return true - else: - pass - if parent.task == parent.PLAYER_TASKS.NONE: - parent.task = parent.PLAYER_TASKS.WALK - walk_path = parent.terrain.get_terrain_path(parent.get_position(), pos) - walk_context = p_walk_context - if walk_path.size() == 0: - parent.task = parent.PLAYER_TASKS.NONE - walk_stop(parent.get_position()) - set_process(false) - return - moved = true - walk_destination = walk_path[walk_path.size()-1] - if parent.terrain.is_solid(pos): - walk_destination = walk_path[walk_path.size()-1] - path_ofs = 0.0 - parent.task = parent.PLAYER_TASKS.WALK - set_process(true) - -# PRIVATE FUNCTION -func walk(target_pos, p_speed, context = null): - if p_speed: - parent.orig_speed = parent.speed - parent.speed = p_speed - walk_to(target_pos, context) - -# PRIVATE FUNCTION -func walk_stop(pos): - parent.position = pos -# parent.interact_status = parent.INTERACT_STATES.INTERACT_NONE - walk_path = [] - - if parent.orig_speed: - parent.speed = parent.orig_speed - parent.orig_speed = 0.0 - - parent.task = parent.PLAYER_TASKS.NONE - moved = false - set_process(false) - if parent.params_queue != null && !parent.params_queue.empty(): - if parent.animations.dir_angles.size() > 0: - if parent.arams_queue[0].interact_angle == -1: - escoria.tools.resolve_angle_to(parent.params_queue[0]) - else: - last_dir = _get_dir_deg(parent.params_queue[0].interact_angle, parent.animations) - parent.animation_sprite.play(parent.animations.idles[last_dir][0]) - pose_scale = parent.animations.idles[last_dir][1] - update_terrain() - else: - parent.animation_sprite.play(parent.animations.idles[last_dir][0]) - pose_scale = parent.animations.idles[last_dir][1] - get_tree().call_group_flags(SceneTree.GROUP_CALL_DEFAULT, "game", "interact", parent.params_queue) - # Clear params queue to prevent the same action from being triggered again - parent.params_queue = [] - else: - - # If we're heading to an object and reached its interaction position, - # orient towards the defined interaction direction set on the object (if any) - if walk_context.has("target_object") \ - and walk_context.target_object.player_orients_on_arrival \ - and escoria.object_manager.get_object( - walk_context.target_object.global_id - ).interactive: - var orientation = walk_context["target_object"].interaction_direction - last_dir = orientation - parent.animation_sprite.play(parent.animations.idles[orientation][0]) - pose_scale = parent.animations.idles[orientation][1] - - else: - parent.animation_sprite.play(parent.animations.idles[last_dir][0]) - pose_scale = parent.animations.idles[last_dir][1] - update_terrain() - - yield(parent.animation_sprite, "animation_finished") - escoria.logger.info(parent.global_id + " arrived at " + str(walk_context)) - parent.emit_signal("arrived", walk_context) - - -func update_terrain(on_event_finished_name = null): - if !parent.terrain or parent.terrain == null or !is_instance_valid(parent.terrain): - return - if on_event_finished_name != null and on_event_finished_name != "setup": - return - if parent.get("is_exit"): - return - if parent.get("dont_apply_terrain_scaling"): - return - - var pos = parent.position - parent.z_index = pos.y if pos.y <= VisualServer.CANVAS_ITEM_Z_MAX else VisualServer.CANVAS_ITEM_Z_MAX - - var color - if parent.terrain_is_scalenodes: - last_scale = parent.terrain.get_terrain(pos) - parent.scale = last_scale - elif parent.check_maps: - color = parent.terrain.get_terrain(pos) - var scal = parent.terrain.get_scale_range(color.b) - if scal != parent.get_scale(): - last_scale = scal - parent.scale = last_scale - - # Do not flip the entire character, because that would conflict - # with shadows that expect to be siblings of $texture - if pose_scale == -1 and parent.get_node("sprite").scale.x > 0: - parent.get_node("sprite").scale.x *= pose_scale - parent.collision.scale.x *= pose_scale - elif pose_scale == 1 and parent.get_node("sprite").scale.x < 0: - parent.get_node("sprite").scale.x *= -1 - parent.collision.scale.x *= -1 - -# if parent.check_maps: -# color = parent.terrain.get_light(pos) -# -# if color: -# for s in sprites: -# s.set_modulate(color) - -func _get_dir(angle : float, animations) -> int: - var deg = escoria.utils._get_deg_from_rad(angle) - return _get_dir_deg(deg, animations) - - -func _get_dir_deg(deg : int, animations) -> int: - # We turn the angle by -90° because angle_to_point gives the angle against X axis, not Y - deg = wrapi(deg - 90, 0, 360) - var dir = -1 - var i = 0 - - for arr_angle_zone in animations.dir_angles: - if is_angle_in_interval(deg, arr_angle_zone): - dir = i - break - else: - i += 1 - continue - - # It's an error to have the animations misconfigured - if dir == -1: - escoria.logger.report_errors("escitem.gd:_get_dir_deg()", ["No direction found for " + str(deg)]) - - return dir - -""" -Returns true if given angle is inside the interval given by a starting_angle and the size. -@param angle : Angle to test -@param: interval : Array of size 2, containing the starting angle, and the size of interval - eg: [90, 40] corresponds to angle between 90° and 130° -""" -func is_angle_in_interval(angle: float, interval : Array) -> bool: - angle = wrapi(angle, 0, 360) - if angle == 0: - angle = 360 - var start_angle = wrapi(interval[0], 0, 360) - var angle_area = interval[1] - var end_angle = wrapi(interval[0] + angle_area, 0, 360) - - if (angle >= 270 and angle <= 360) or (angle >= 0 and angle <= 90): - if wrapi(angle+180, 0, 360) > wrapi(interval[0]+ 180, 0, 360) \ - && wrapi(angle+180, 0, 360) <= wrapi(interval[0] + angle_area + 180, 0, 360): - return true - else: - if wrapi(angle, 0, 360) > start_angle && wrapi(angle, 0, 360) <= end_angle: - return true - - return false - -""" -Sets character's angle and plays according animation. -- deg int angle to set the character -- immediate bool (currently unused, see TODO below) - If true, direction is switched immediately. Else, successive animations are - used so that the character turns to target angle. - -TODO: depending on current angle and current angle, the character may directly turn around -with no "progression". We may enhance this by calculating successive directions to turn the -character to, so that he doesn't switch to opposite direction too fast. -For example, if character looks WEST and set_angle(EAST) is called, we may want the character -to first turn SOUTHWEST, then SOUTH, then SOUTHEAST and finally EAST, all more or less fast. -Whatever the implementation, this should be activated using "parameter "immediate" set to false. -""" -func set_angle(deg : int, immediate = true): - if deg < 0 or deg > 360: - escoria.logger.report_errors("movable.gd:set_angle()", ["Invalid degree to turn to " + str(deg)]) - moved = true - last_deg = deg - last_dir = _get_dir_deg(deg, parent.animations) - - # The character may have a state animation from before, which would be - # resumed, so we immediately force the correct idle animation - if parent.animation_sprite.animation != parent.animations.idles[last_dir][0]: - parent.animation_sprite.play(parent.animations.idles[last_dir][0]) - pose_scale = parent.animations.idles[last_dir][1] - update_terrain() 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 54fd0a10..3738d77a 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/teleport.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/teleport.gd @@ -1,9 +1,7 @@ -# `teleport object1 object2 [angle]` +# `teleport object1 object2 # -# Sets the position of object1 to the position of object2. By default, -# object2's interact_angle is used to turn object1, but angle will override -# this. Useful for doors and such with an interact_angle you don't always want -# to adhere to when re-entering a room. +# Sets the position of object1 to the position of object2. +# FIXME re-add the angle parameter here # # @ESC extends ESCBaseCommand @@ -14,8 +12,8 @@ class_name TeleportCommand func configure() -> ESCCommandArgumentDescriptor: return ESCCommandArgumentDescriptor.new( 2, - [TYPE_STRING, TYPE_STRING, TYPE_INT], - [null, null, null] + [TYPE_STRING, TYPE_STRING], + [null, null] ) @@ -42,9 +40,8 @@ func validate(arguments: Array): # Run the command func run(command_params: Array) -> int: - escoria.object_manager.get_object(command_params[0]).node\ + (escoria.object_manager.get_object(command_params[0]).node as ESCPlayer)\ .teleport( - escoria.object_manager.get_object(command_params[1]).node, - command_params[2] + escoria.object_manager.get_object(command_params[1]).node ) return ESCExecution.RC_OK diff --git a/addons/escoria-core/game/core-scripts/esc/esc_command_registry.gd b/addons/escoria-core/game/core-scripts/esc/esc_command_registry.gd index 2e984a1e..d944437d 100644 --- a/addons/escoria-core/game/core-scripts/esc/esc_command_registry.gd +++ b/addons/escoria-core/game/core-scripts/esc/esc_command_registry.gd @@ -19,7 +19,10 @@ func load_command(command_name: String) -> ESCBaseCommand: ): if ResourceLoader.exists("%s/%s.gd" % [command_directory, command_name]): registry[command_name] = load( - "%s/%s.gd" % [command_directory, command_name] + "%s/%s.gd" % [ + command_directory.trim_suffix("/"), + command_name + ] ).new() return registry[command_name] diff --git a/addons/escoria-core/game/core-scripts/esc/esc_globals_manager.gd b/addons/escoria-core/game/core-scripts/esc/esc_globals_manager.gd index 7986da45..8caa9331 100644 --- a/addons/escoria-core/game/core-scripts/esc/esc_globals_manager.gd +++ b/addons/escoria-core/game/core-scripts/esc/esc_globals_manager.gd @@ -19,6 +19,11 @@ const RESERVED_GLOBALS = [ export(Dictionary) var _globals = {} + +func _init(): + set_global("ESC_LAST_SCENE", "", true) + + # Check if a global was registered # # #### Parameters diff --git a/addons/escoria-core/game/core-scripts/esc/types/esc_command.gd b/addons/escoria-core/game/core-scripts/esc/types/esc_command.gd index db6fccba..68ba9f88 100644 --- a/addons/escoria-core/game/core-scripts/esc/types/esc_command.gd +++ b/addons/escoria-core/game/core-scripts/esc/types/esc_command.gd @@ -82,7 +82,7 @@ func is_valid() -> bool: var command_found = false for base_path in ProjectSettings.get("escoria/main/command_directories"): var command_path = "%s/%s.gd" % [ - base_path, + base_path.trim_suffix("/"), self.name ] if ResourceLoader.exists(command_path): diff --git a/addons/escoria-core/game/core-scripts/escbackground.gd b/addons/escoria-core/game/core-scripts/esc_background.gd similarity index 54% rename from addons/escoria-core/game/core-scripts/escbackground.gd rename to addons/escoria-core/game/core-scripts/esc_background.gd index 4a641401..74dd0850 100644 --- a/addons/escoria-core/game/core-scripts/escbackground.gd +++ b/addons/escoria-core/game/core-scripts/esc_background.gd @@ -1,49 +1,53 @@ +# ESCBackground's purpose is to display a background image and receive input +# events on the background. More precisely, the TextureRect under ESCBackground +# does not receive events itself - if it did, it would also eat all events like +# hotspot focusing and such. Instead, we set the TextureRect mouse filter to +# MOUSE_FILTER_IGNORE, and we use an Area2D node to receive the input events. +# +# If ESCBackground doesn't contain a texture, it is important that its rect_size +# is set over the whole scene, because its rect_size is then used to create the +# Area2D node under it. If the rect_size is wrongly set, the background may +# receive no input. tool extends TextureRect class_name ESCBackground -func get_class(): - return "ESCBackground" +# The background was double clicked +# +# #### Parameters +# +# - position: The position where the player clicked signal double_left_click_on_bg(position) -signal left_click_on_bg(position) -signal right_click_on_bg(position) -signal mouse_moved +# The background was left clicked +# +# #### Parameters +# +# - position: The position where the player clicked +signal left_click_on_bg(position) + +# The background was right clicked +# +# #### Parameters +# +# - position: The position where the player clicked +signal right_click_on_bg(position) + + +# The ESC script connected to this background export(String, FILE, "*.esc") var esc_script = "" -# Actual size of the scene -var size : Vector2 - -""" -ESCBackground purpose is to display a background image and receive input events -on the background. More precisely, the TextureRect under ESCBackground does not -receive events itself - if it did, it would also eat all events like hotspot -focusing and such. Instead, we set the TextureRect mouse filter to -MOUSE_FILTER_IGNORE, and we use an Area2D node to receive the input events. - -If ESCBackground doesn't contain a texture, it is important that its rect_size -is set over the whole scene, because its rect_size is then used to create the -Area2D node under it. If the rect_size is wrongly set, the background may -receive no input. -""" - -# PRIVATE VARS -var area : Area2D -var actual_click_position : Vector2 - -# Godot doesn't do doubleclicks so we must -var last_lmb_dt = 0 -var waiting_dblclick = null # null or [pos, event] +# Create the underlying Area2D as an input device func _enter_tree(): - # Use size of background texture to calculate collision shape if any + var size if get_texture(): size = get_texture().get_size() else: size = rect_size - area = Area2D.new() + var area = Area2D.new() var shape = RectangleShape2D.new() var sid = area.create_shape_owner(area) @@ -53,24 +57,34 @@ func _enter_tree(): transform.origin = size / 2 area.shape_owner_set_transform(sid, transform) - # Set extents of RectangleShape2D to cover entire Sprite + # Set extents of RectangleShape2D to cover entire TextureRect shape.set_extents(size / 2) area.shape_owner_add_shape(sid, shape) + + # Handle inputs to the Area2D ourself + area.connect("input_event", self, "manage_input") add_child(area) +# Disable mouse filter events and connect our own events to the ESC input +# manager func _ready(): mouse_filter = MOUSE_FILTER_IGNORE - area.connect("input_event", self, "manage_input") - connect("gui_input", self, "manage_input_texturerect") - + if !Engine.is_editor_hint(): connect("left_click_on_bg", escoria.inputs_manager, "_on_left_click_on_bg") connect("right_click_on_bg", escoria.inputs_manager, "_on_right_click_on_bg") connect("double_left_click_on_bg", escoria.inputs_manager, "_on_double_left_click_on_bg") -# connect("mouse_moved_on_bg", escoria.inputs_manager, "_on_mouse_moved_on_bg") -func manage_input(_viewport, event, _shape_idx): + +# Manage inputs reaching the Area2D and emit the events to the input manager +# TODO: Don't change private variables here, use an event for BUTTON_WHEEL +# +# #### Parameters +# - _viewport: (not used) +# - event: Event received +# - _shape_idx: (not used) +func manage_input(_viewport, event, _shape_idx) -> void: if event.is_action_pressed("switch_action_verb"): if event.button_index == BUTTON_WHEEL_UP: escoria.inputs_manager._on_mousewheel_action(-1) @@ -87,21 +101,11 @@ func manage_input(_viewport, event, _shape_idx): emit_signal("left_click_on_bg", p) if event.button_index == BUTTON_RIGHT: emit_signal("right_click_on_bg", p) -# elif event is InputEventMouseMotion: -# emit_signal("mouse_moved_on_bg") - -func manage_input_texturerect(event): - if event is InputEventMouseButton and event.is_pressed(): - if event.button_index == BUTTON_LEFT: - emit_signal("left_click_on_bg", event.position) - if event.button_index == BUTTON_RIGHT: - emit_signal("right_click_on_bg", event.position) - else: - pass - - +# Calculate the actual area taken by this background depending on its +# Texture or set size +# **Returns** The correct area size func get_full_area_rect2() -> Rect2: var area_rect2 : Rect2 = Rect2() var pos = get_global_position() diff --git a/addons/escoria-core/game/core-scripts/esc_game.gd b/addons/escoria-core/game/core-scripts/esc_game.gd new file mode 100644 index 00000000..82031b12 --- /dev/null +++ b/addons/escoria-core/game/core-scripts/esc_game.gd @@ -0,0 +1,251 @@ +# A base class for ESC game scenes +# An extending class can be used in the project settings and is responsible +# for managing very basic game features and controls +tool +extends Node2D +class_name ESCGame + + +# Editor debug modes +# NONE - No debugging +# MOUSE_TOOLTIP_LIMITS - Visualize the tooltip limits +enum EDITOR_GAME_DEBUG_DISPLAY { + NONE, + MOUSE_TOOLTIP_LIMITS +} + + +# The safe margin around tooltips +export(float) var mouse_tooltip_margin = 50.0 + + +# A reference to the node handling tooltips +var tooltip_node : Object + + +# Which (if any) debug mode for the editor is used +export(EDITOR_GAME_DEBUG_DISPLAY) var editor_debug_mode = \ + EDITOR_GAME_DEBUG_DISPLAY.NONE setget _set_editor_debug_mode + + +# Handle debugging visualizations +func _draw(): + if !Engine.is_editor_hint(): + return + if editor_debug_mode == EDITOR_GAME_DEBUG_DISPLAY.NONE: + return + + if editor_debug_mode == EDITOR_GAME_DEBUG_DISPLAY.MOUSE_TOOLTIP_LIMITS: + var mouse_limits : Rect2 = get_viewport_rect().grow(-mouse_tooltip_margin) + print(mouse_limits) + + # Draw lines for tooltip limits + draw_rect(mouse_limits, ColorN("red"), false, 10.0) + + +# Called when the player left clicks on the background +# (Needs to be overridden, if supported) +# +# #### Parameters +# +# - position: Position clicked +func left_click_on_bg(position: Vector2) -> void: + pass + + +# Called when the player right clicks on the background +# (Needs to be overridden, if supported) +# +# #### Parameters +# +# - position: Position clicked +func right_click_on_bg(position: Vector2) -> void: + pass + + +# Called when the player double clicks on the background +# (Needs to be overridden, if supported) +# +# #### Parameters +# +# - position: Position clicked +func left_double_click_on_bg(position: Vector2) -> void: + pass + + +# Called when an element in the scene was focused +# (Needs to be overridden, if supported) +# +# #### Parameters +# +# - element_id: Global id of the element focused +func element_focused(element_id: String) -> void: + pass + + +# Called when no element is focused anymore +# (Needs to be overridden, if supported) +func element_unfocused() -> void: + pass + + +# Called when an item was left clicked +# (Needs to be overridden, if supported) +# +# #### Parameters +# +# - item_global_id: Global id of the item that was clicked +# - event: The received input event +func left_click_on_item(item_global_id: String, event: InputEvent) -> void: + pass + + +# Called when an item was right clicked +# (Needs to be overridden, if supported) +# +# #### Parameters +# +# - item_global_id: Global id of the item that was clicked +# - event: The received input event +func right_click_on_item(item_global_id: String, event: InputEvent) -> void: + pass + + +# Called when an item was double clicked +# (Needs to be overridden, if supported) +# +# #### Parameters +# +# - item_global_id: Global id of the item that was clicked +# - event: The received input event +func left_double_click_on_item( + item_global_id: String, + event: InputEvent +) -> void: + pass + + +# Called when an inventory item was left clicked +# (Needs to be overridden, if supported) +# +# #### Parameters +# +# - inventory_item_global_id: Global id of the inventory item was clicked +# - event: The received input event +func left_click_on_inventory_item( + inventory_item_global_id: String, + event: InputEvent +) -> void: + pass + + +# Called when an inventory item was right clicked +# (Needs to be overridden, if supported) +# +# #### Parameters +# +# - inventory_item_global_id: Global id of the inventory item was clicked +# - event: The received input event +func right_click_on_inventory_item( + inventory_item_global_id: String, + event: InputEvent +) -> void: + pass + + +# Called when an inventory item was double clicked +# (Needs to be overridden, if supported) +# +# #### Parameters +# +# - inventory_item_global_id: Global id of the inventory item was clicked +# - event: The received input event +func left_double_click_on_inventory_item( + inventory_item_global_id: String, + event: InputEvent +) -> void: + pass + + +# Called when an inventory item was focused +# (Needs to be overridden, if supported) +# +# #### Parameters +# +# - inventory_item_global_id: Global id of the inventory item that was focused +func inventory_item_focused(inventory_item_global_id : String) -> void: + pass + + +# Called when no inventory item is focused anymore +# (Needs to be overridden, if supported) +func inventory_item_unfocused() -> void: + pass + + +# Called when the inventory was opened +# (Needs to be overridden, if supported) +func open_inventory(): + pass + + +# Called when the inventory was closed +# (Needs to be overridden, if supported) +func close_inventory(): + pass + + +# Called when the mousewheel was used +# (Needs to be overridden, if supported) +# +# #### Parameter +# +# - direction: The direction in which the mouse wheel was rotated +func mousewheel_action(direction : int): + pass + + +# Called when the UI should be hidden +# (Needs to be overridden, if supported) +func hide_ui(): + pass + + +# Called when the UI should be shown +# (Needs to be overridden, if supported) +func show_ui(): + pass + + +# Function is called if Project setting escoria/ui/tooltip_follows_mouse = true +# +# #### Parameters +# +# - p_position: Position of the mouse +func update_tooltip_following_mouse_position(p_position : Vector2): + var corrected_position = p_position + + # clamp TOP + if tooltip_node.tooltip_distance_to_edge_top(p_position) <= mouse_tooltip_margin: + corrected_position.y = mouse_tooltip_margin + + # clamp BOTTOM + if tooltip_node.tooltip_distance_to_edge_bottom(p_position + tooltip_node.rect_size) <= mouse_tooltip_margin: + corrected_position.y = escoria.game_size.y - mouse_tooltip_margin - tooltip_node.rect_size.y + + # clamp LEFT + if tooltip_node.tooltip_distance_to_edge_left(p_position - tooltip_node.rect_size/2) <= mouse_tooltip_margin: + corrected_position.x = mouse_tooltip_margin + + # clamp RIGHT + if tooltip_node.tooltip_distance_to_edge_right(p_position + tooltip_node.rect_size/2) <= mouse_tooltip_margin: + corrected_position.x = escoria.game_size.x - mouse_tooltip_margin - tooltip_node.rect_size.x + + tooltip_node.anchor_right = 0.2 + tooltip_node.rect_position = corrected_position + tooltip_node.offset_from_cursor + + +# Set the Editor debug mode +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/core-scripts/esc_inventory_item.gd b/addons/escoria-core/game/core-scripts/esc_inventory_item.gd new file mode 100644 index 00000000..6591c3a3 --- /dev/null +++ b/addons/escoria-core/game/core-scripts/esc_inventory_item.gd @@ -0,0 +1,93 @@ +# The inventory representation of an ESC item if pickable +extends TextureButton +class_name ESCInventoryItem + + +# Signal emitted when the item was left clicked +# +# #### Parameters +# +# - item_id: Global ID of the clicked item +signal mouse_left_inventory_item(item_id) + +# Signal emitted when the item was right clicked +# +# #### Parameters +# +# - item_id: Global ID of the clicked item +signal mouse_right_inventory_item(item_id) + +# Signal emitted when the item was double clicked +# +# #### Parameters +# +# - item_id: Global ID of the clicked item +signal mouse_double_left_inventory_item(item_id) + +# Signal emitted when the item was focused +# +# #### Parameters +# +# - item_id: Global ID of the clicked item +signal inventory_item_focused(item_id) + +# Signal emitted when the item is not focused anymore +signal inventory_item_unfocused() + + +# Global ID of the ESCItem that uses this ESCInventoryItem +# Will be set by ESCItem automatically +var global_id + + +# Connect input handlers +func _ready(): + connect("gui_input", self, "_on_inventory_item_gui_input") + connect("mouse_entered", self, "_on_inventory_item_mouse_enter") + connect("mouse_exited", self, "_on_inventory_item_mouse_exit") + + +# Handle the gui input and emit the respective signals +# +# #### Parameters +# +# - event: The event received +func _on_inventory_item_gui_input(event : InputEvent): + if event.is_action_pressed("switch_action_verb"): + if event.button_index == BUTTON_WHEEL_UP: + escoria.inputs_manager._on_mousewheel_action(-1) + elif event.button_index == BUTTON_WHEEL_DOWN: + escoria.inputs_manager._on_mousewheel_action(1) + if event is InputEventMouseButton: +# var p = get_global_mouse_position() + if event.doubleclick: + if event.button_index == BUTTON_LEFT: + emit_signal( + "mouse_double_left_inventory_item", + global_id, + event + ) + else: + if event.is_pressed(): + if event.button_index == BUTTON_LEFT: + emit_signal( + "mouse_left_inventory_item", + global_id, + event + ) + if event.button_index == BUTTON_RIGHT: + emit_signal( + "mouse_right_inventory_item", + global_id, + event + ) + + +# Handle mouse entering the item and send the respecitve signal +func _on_inventory_item_mouse_enter(): + emit_signal("inventory_item_focused", global_id) + + +# Handle mouse leaving the item and send the respecitve signal +func _on_inventory_item_mouse_exit(): + emit_signal("inventory_item_unfocused") diff --git a/addons/escoria-core/game/core-scripts/esc_item.gd b/addons/escoria-core/game/core-scripts/esc_item.gd new file mode 100644 index 00000000..93c98bba --- /dev/null +++ b/addons/escoria-core/game/core-scripts/esc_item.gd @@ -0,0 +1,349 @@ +# ESCItem is a Sprite that defines an item, potentially interactive +tool +extends Area2D +class_name ESCItem + + +# Emitted when the mouse has entered this item +# +# #### Parameters +# +# - items: The inventory item node +signal mouse_entered_item(item) + +# Emitted when the mouse has exited this item +# +# #### Parameters +# +# - items: The inventory item node +signal mouse_exited_item(item) + +# Emitted when the item was left cliced +# +# #### Parameters +# +# - global_id: ID of this item +signal mouse_left_clicked_item(global_id) + +# Emitted when the item was double cliced +# +# #### Parameters +# +# - global_id: ID of this item +signal mouse_double_left_clicked_item(global_id) + +# Emitted when the item was right cliced +# +# #### Parameters +# +# - global_id: ID of this item +signal mouse_right_clicked_item(global_id) + +# Emitted when the item walked to a destination +# +# #### Parameters +# +# - walk_context: The walk context of the command +signal arrived(walk_context) + + +# The global ID of this item +export(String) var global_id + +# The ESC script for this item +export(String, FILE, "*.esc") var esc_script + +# If true, the ESC script may have an ":exit_scene" event to manage scene changes +export(bool) var is_exit + +# If true, object is considered as trigger. Allows using :trigger_in and +# :trigger_out verbs in ESC scripts. +export(bool) var is_trigger + +# The verb used for the trigger in ESC events +export(String) var trigger_in_verb = "trigger_in" + +# The verb used for the trigger out ESC events +export(String) var trigger_out_verb = "trigger_out" + +# If true, the player can interact with this item +export(bool) var is_interactive = true + +# If true, player orients towards 'interaction_direction' as +# player character arrives. +export(bool) var player_orients_on_arrival = true + +# Let the player turn to this direction when the player arrives at the +# item +export(int) var interaction_direction + +# The name for the tooltip of this item +export(String) var tooltip_name + +# Default action to use if object is not in the inventory +export(String) var default_action + +# Default action to use if object is in the inventory +export(String) var default_action_inventory + +# If action used by player is in this list, the game will wait for a second +# click on another item to combine objects together (typical +# `USE WITH `, `GIVE TO `) +export(PoolStringArray) var combine_if_action_used_among = [] + +# If true, combination must be done in the way it is written in ESC script +# ie. :use ON_ITEM +# If false, combination will be tried in the other way. +export(bool) var combine_is_one_way = false + +# If true, then the object must have been picked up before using it. +# A false value is useful for items in the background, such as buttons. +export(bool) var use_from_inventory_only = false + +# Scene based on ESCInventoryItem used in inventory for the object if it is +# picked up, that displays and handles the item +export(PackedScene) var inventory_item_scene_file : PackedScene + +# Color used for dialogs +export(Color) var dialog_color = ColorN("white") + +# If true, terrain scaling will not be applied and +# node will remain at the scale set in the scene. +export(bool) var dont_apply_terrain_scaling = false + +# Speed of this item ifmovable +export(int) var speed : int = 300 + +# Speed damp of this item if movable +export(float) var v_speed_damp : float = 1.0 + +# Animations script (for walking, idling...) +export(Script) var animations + +# The movable subnode +var movable: ESCMovable = null + +# Reference to the animation node (null if none was found) +var animation_sprite = null + +# Reference to the current terrain +var terrain: ESCTerrain + +# Reference to this items collision shape node +var collision: Node + +# The representation of this item in the scene. Will +# be loaded, if inventory_item_scene_file is set. +var inventory_item: ESCInventoryItem = null setget ,_get_inventory_item + + +# Add the movable node, connect signals, detect child nodes +# and register this item +func _ready(): + movable = ESCMovable.new() + + add_child(movable) + + _detect_children() + + connect("mouse_entered", self, "_on_mouse_entered") + connect("mouse_exited", self, "_on_mouse_exited") + connect("input_event", self, "manage_input") + + # Register and connect all elements to Escoria backoffice. + if not Engine.is_editor_hint(): + escoria.event_manager.connect("event_finished", self, "_update_terrain") + + escoria.object_manager.register_object( + ESCObject.new( + global_id, + self + ), + true + ) + + terrain = escoria.room_terrain + + if !is_trigger: + connect("mouse_entered_item", escoria.inputs_manager, "_on_mouse_entered_item") + connect("mouse_exited_item", escoria.inputs_manager, "_on_mouse_exited_item") + connect("mouse_left_clicked_item", escoria.inputs_manager, "_on_mouse_left_clicked_item") + connect("mouse_double_left_clicked_item", escoria.inputs_manager, "_on_mouse_left_double_clicked_item") + connect("mouse_right_clicked_item", escoria.inputs_manager, "_on_mouse_right_clicked_item") + else: + connect("area_entered", self, "element_entered") + connect("area_exited", self, "element_exited") + connect("body_entered", self, "element_entered") + connect("body_exited", self, "element_exited") + + # If object can be in the inventory, set default_action_inventory to same as + # default_action, if default_action_inventory is not set + if use_from_inventory_only and default_action_inventory.empty(): + default_action_inventory = default_action + + # Perform a first terrain scaling if we have to. + if !is_exit or dont_apply_terrain_scaling: + movable.last_scale = scale + movable.update_terrain() + + +# Return the animation player node +func get_animation_player(): + return animation_sprite + + +# Return the position the player needs to walk to to interact with this +# item. That can either be a direct Position2D child or a collision shape +# +# **Returns** The interaction position +func get_interact_position() -> Vector2: + var interact_position = null + for c in get_children(): + if c is Position2D: + if c.get_owner() == self: + continue + interact_position = c.global_position + + if interact_position == null and collision != null: + interact_position = collision.global_position + + return interact_position + + +# Manage mouse button clicks on this item by sending out signals +# +# #### Parameters +# +# - _viewport: not used +# - event: Triggered event +# - _shape_idx: not used +func manage_input( + _viewport : Viewport, + event : InputEvent, + _shape_idx : int +) -> void: + if event is InputEventMouseButton: + + if event.doubleclick: + if event.button_index == BUTTON_LEFT: + emit_signal("mouse_double_left_clicked_item", self, event) + else: + if event.is_pressed(): + if event.button_index == BUTTON_LEFT: + emit_signal("mouse_left_clicked_item", self, event) + elif event.button_index == BUTTON_RIGHT: + emit_signal("mouse_right_clicked_item", self, event) + + +# React to the mouse entering the item by emitting the respective signal +func _on_mouse_entered(): + emit_signal("mouse_entered_item", self) + + +# React to the mouse exiting the item by emitting the respective signal +func _on_mouse_exited(): + emit_signal("mouse_exited_item", self) + + +# Another item (e.g. the player) has entered this item +# +# #### Parameters +# +# - body: Other object that has entered the item +func element_entered(body): + if body is ESCBackground or body.get_parent() is ESCBackground: + return + escoria.do("trigger_in", [global_id, body.global_id, trigger_in_verb]) + + +# Another item (e.g. the player) has exited this element +# #### Parameters +# +# - body: Other object that has entered the item +func element_exited(body): + if body is ESCBackground or body.get_parent() is ESCBackground: + return + escoria.do("trigger_out", [global_id, body.global_id, trigger_out_verb]) + + +# Use the movable node to teleport this item to the target item +# +# #### Parameters +# +# - target: Target item to teleport to +func teleport(target: Node) -> void: + movable.teleport(target) + + +# Use the movable node to make the item walk to the given position +# +# #### Parameters +# +# - 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) + + +# Set the moving speed +# +# #### Parameters +# +# - speed_value: Set the new speed +func set_speed(speed_value : int) -> void: + speed = speed_value + + +# Set the angle +# +# #### Parameters +# +# Set the angle +func set_angle(deg : int, immediate = true): + 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]) + + +# 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]) + + +# Detect the child nodes and set respective references +func _detect_children() -> void: + # Detect animation player + for n in get_children(): + if n is AnimatedSprite: + animation_sprite = n + continue + if n is AnimationPlayer: + animation_sprite = n + continue + + # Initialize collision variable. + for c in get_children(): + if c is CollisionShape2D or c is CollisionPolygon2D: + collision = c + + +# Upate the terrain when an event finished +func _update_terrain(rc: int, event_name: String) -> void: + movable.update_terrain(event_name) + + +# Get inventory item from the inventory item scene +# **Returns** The inventory item of this ESCitem +func _get_inventory_item() -> ESCInventoryItem: + if not inventory_item and inventory_item_scene_file: + inventory_item = inventory_item_scene_file.instance() + inventory_item.global_id = self.global_id + return inventory_item + diff --git a/addons/escoria-core/game/core-scripts/esc_player.gd b/addons/escoria-core/game/core-scripts/esc_player.gd new file mode 100644 index 00000000..286cb1a1 --- /dev/null +++ b/addons/escoria-core/game/core-scripts/esc_player.gd @@ -0,0 +1,20 @@ +# A playable character +# TODO +# - Currently the sprite node needs to be named "sprite". This is bad. +# - Animation management doesn't allow using AnimationPlayer yet. Need to find +# the best solution to manage both AnimatedSprite and AnimationPlayer. +tool +extends ESCItem +class_name ESCPlayer + + +# The node that references the camera position +export(NodePath) var camera_position_node + + +# Return the camera position if a camera_position_node exists or the +# global position of the player +func get_camera_pos(): + if camera_position_node and get_node(camera_position_node): + return get_node(camera_position_node).global_position + return global_position diff --git a/addons/escoria-core/game/core-scripts/resource_queue.gd b/addons/escoria-core/game/core-scripts/esc_resource_cache.gd similarity index 99% rename from addons/escoria-core/game/core-scripts/resource_queue.gd rename to addons/escoria-core/game/core-scripts/esc_resource_cache.gd index f8eee837..00beb732 100644 --- a/addons/escoria-core/game/core-scripts/resource_queue.gd +++ b/addons/escoria-core/game/core-scripts/esc_resource_cache.gd @@ -1,6 +1,6 @@ # A cache for resources extends Object -class_name ResourceCache +class_name ESCResourceCache var thread : Thread var mutex : Mutex diff --git a/addons/escoria-core/game/core-scripts/escroom.gd b/addons/escoria-core/game/core-scripts/esc_room.gd similarity index 54% rename from addons/escoria-core/game/core-scripts/escroom.gd rename to addons/escoria-core/game/core-scripts/esc_room.gd index f803287c..d91170a6 100644 --- a/addons/escoria-core/game/core-scripts/escroom.gd +++ b/addons/escoria-core/game/core-scripts/esc_room.gd @@ -1,41 +1,62 @@ +# A room in an Escora based game tool extends Node2D class_name ESCRoom -func get_class(): - return "ESCRoom" -export(String) var global_id = "" -export(String, FILE, "*.esc") var esc_script = "" -export(PackedScene) var player_scene -export(Array, Rect2) var camera_limits : Array = [Rect2()] setget set_camera_limits -var player -onready var game = $game - -### EDITOR TOOLS ### -enum EDITOR_ROOM_DEBUG_DISPLAY { +# Debugging displays for a room +# NONE: No debug display +# CAMERA_LIMITS: Display the camera limits +enum EditorRoomDebugDisplay { NONE, CAMERA_LIMITS } -export(EDITOR_ROOM_DEBUG_DISPLAY) var editor_debug_mode = EDITOR_ROOM_DEBUG_DISPLAY.NONE setget set_editor_debug_mode -onready var camera_limits_colors : Array = [ - ColorN("red"), ColorN("blue"), ColorN("green") -] -### END EDITOR TOOLS ### + +# The global id of this room +export(String) var global_id = "" + +# The ESC script of this room +export(String, FILE, "*.esc") var esc_script = "" + +# The player inside this scene +export(PackedScene) var player_scene + +# The camera limits available in this room +export(Array, Rect2) var camera_limits : Array = [Rect2()] setget set_camera_limits + +# The editor debug display mode +export(int) var editor_debug_mode = EditorRoomDebugDisplay.NONE setget set_editor_debug_mode + + +# The player scene instance +var player + + +# The game scene instance +var game + + +# Start the random number generator when the camera limits should be displayed func _enter_tree(): - randomize() + if editor_debug_mode == EditorRoomDebugDisplay.CAMERA_LIMITS: + randomize() +# 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(): if camera_limits.empty(): camera_limits.push_back(Rect2()) if camera_limits.size() == 1 and camera_limits[0].has_no_area(): - camera_limits[0] = Rect2(0, 0, $background.rect_size.x, $background.rect_size.y) + camera_limits[0] = \ + Rect2(0, 0, $background.rect_size.x, $background.rect_size.y) if Engine.is_editor_hint(): return + game = $game + if player_scene: player = player_scene.instance() add_child(player) @@ -59,12 +80,18 @@ func _ready(): if global_id.empty(): global_id = name - + + +# Draw the camera limits visualization if enabled func _draw(): if !Engine.is_editor_hint(): return - if editor_debug_mode == EDITOR_ROOM_DEBUG_DISPLAY.NONE: + if editor_debug_mode == EditorRoomDebugDisplay.NONE: return + + var camera_limits_colors : Array = [ + ColorN("red"), ColorN("blue"), ColorN("green") + ] # If there are more camera limits than colors defined for them, add more. if camera_limits.size() > camera_limits_colors.size(): @@ -79,12 +106,22 @@ func _draw(): draw_string(default_font, Vector2(camera_limits[i].position.x + 30, camera_limits[i].position.y + 30), str(i), camera_limits_colors[i]) - return -func set_camera_limits(p_camera_limits : Array) -> void: +# Set the camera limits +# +# #### Parameters +# +# - p_camera_limits: An array of Rect2Ds as camera limits +func set_camera_limits(p_camera_limits: Array) -> void: camera_limits = p_camera_limits update() -func set_editor_debug_mode(p_editor_debug_mode : int) -> void: + +# Set the editor debug mode +# +# #### Parameters +# +# - p_editor_debug_mode: The debug mode to set for the room +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/core-scripts/esc_terrain.gd b/addons/escoria-core/game/core-scripts/esc_terrain.gd new file mode 100644 index 00000000..4463a8af --- /dev/null +++ b/addons/escoria-core/game/core-scripts/esc_terrain.gd @@ -0,0 +1,228 @@ +# A walkable Terrains +tool +extends Navigation2D +class_name ESCTerrain + + +# Visualize scales or the lightmap for debugging purposes +enum DebugMode { + NONE + SCALES + LIGHTMAP +} + + +# Scaling texture +export(Texture) var scales setget _set_scales + +# Minimum scaling +export(float) var scale_min = 0.3 + +# Maximum scaling +export(float) var scale_max = 1.0 + +# Lightmap texture +export(Texture) var lightmap setget _set_lightmap + +# The scaling factor for the scale and light maps +export(Vector2) var bitmaps_scale = Vector2(1,1) setget _set_bm_scale + +# Multiplier applied to the player speed on this terrain +export(float) var player_speed_multiplier = 1.0 + +# Multiplier how much faster the player will walk when fast mode is on +# (double clicked) +export(float) var player_doubleclick_speed_multiplier = 1.5 + +# Additional modulator to the lightmap texture +export(Color) var lightmap_modulate = Color(1, 1, 1, 1) + +# Currently selected debug visualize mode +export(int, "None", "Scales", "Lightmap") var debug_mode = DebugMode.NONE \ + setget _set_debug_mode + + +# The currently activ navigation polygon +var current_active_navigation_instance: NavigationPolygonInstance = null + + +# Currently visualized texture for debug mode +var _texture = null + +# The image from the lightmap texture +var _lightmap_data + +# Prohibits multiple calls to update_texture +var _texture_in_update = false + + +# Set a reference to the active navigation polygon, register to Escoria +# and update the texture +func _ready(): + var navigation_enabled_found = false + for n in get_children(): + if n is NavigationPolygonInstance: + if n.enabled: + if navigation_enabled_found: + escoria.logger.report_errors( + "ESCTerrain:_ready()", + [ + "Multiple NavigationPolygonInstances enabled " + \ + "at the same time." + ] + ) + navigation_enabled_found = true + current_active_navigation_instance = n + + if !Engine.is_editor_hint(): + escoria.room_terrain = self + _update_texture() + + +# Return the Color of the lightmap pixel for the specified position +# +# #### Parameters +# +# - pos: Position to calculate lightmap for +# **Returns** The color of the given point +func get_light(pos: Vector2) -> Color: + if not lightmap or lightmap.get_data().is_empty(): + return Color(1, 1, 1, 1) + var c = _get_color(_lightmap_data, pos) + return _get_color(_lightmap_data, pos) * lightmap_modulate + + +# Calculate the scale inside the scale range for a given scale factor +# +# #### Parameters +# +# - factor: The factor for the scaling according to the scale map +# **Returns** The scaling +func get_scale_range(factor: float) -> Vector2: + factor = scale_min + (scale_max - scale_min) * factor + return Vector2(factor, factor) + + +# Get the terrain scale factor for a given position +# +# #### Parameters +# +# - pos: The position to calculate for +# **Returns** The scale factor for the given position +func get_terrain(pos: Vector2) -> float: + if scales == null || scales.get_data().is_empty(): + return 1.0 + return _get_color(scales.get_data(), pos).v + + +# Small helper to get the color of an image at a position +func _get_color(image: Image, pos: Vector2) -> Color: + image.lock() + var color=image.get_pixel(pos.x, pos.y) + image.unlock() + return color + + +# Set the bitmap scaling +# +# #### Parameters +# +# - p_scale: Scale to set +func _set_bm_scale(p_scale: Vector2): + bitmaps_scale = p_scale + _update_texture() + + +# Set the lightmap texture +# +# #### Parameters +# +# - p_lightmap: Lightmap texture to set +func _set_lightmap(p_lightmap: Texture): + var need_init = (lightmap != p_lightmap) or (lightmap and not _lightmap_data) + + lightmap = p_lightmap + + # It's bad enough a new copy is created when reading a pixel, we don't + # also need to get the data for every read to make yet another copy + if need_init: + if _lightmap_data: + _lightmap_data.unlock() + _lightmap_data = lightmap.get_data() + _lightmap_data.lock() + + _update_texture() + + +# Set the scales texture +# +# #### Parameters +# +# - p_scales: Scale texture to set +func _set_scales(p_scales: Texture): + scales = p_scales + _update_texture() + + +# Set the debug mode +# +# #### Parameters +# +# - p_mode: Debug mode to set +func _set_debug_mode(p_mode: int): + debug_mode = p_mode + _update_texture() + + +# Update the debug texture, if it is dirty +func _update_texture(): + if _texture_in_update: + return + _texture_in_update = true + call_deferred("_do_update_texture") + + +# Update the texture and optionally set the debug texture +func _do_update_texture(): + _texture_in_update = false + if !is_inside_tree() or !Engine.is_editor_hint(): + return + + if debug_mode == DebugMode.NONE: + update() + return + + _texture = ImageTexture.new() + if debug_mode == DebugMode.SCALES: + if scales != null: + _texture = scales + elif debug_mode == DebugMode.LIGHTMAP: + if lightmap != null: + _texture = lightmap + + update() + + +# Draw debugging visualizations +func _draw(): + if _texture == null or \ + not Engine.is_editor_hint() or \ + debug_mode == DebugMode.NONE: + if current_active_navigation_instance: + current_active_navigation_instance.visible = true + return + + var scale_vect = bitmaps_scale + + if current_active_navigation_instance: + current_active_navigation_instance.visible = false + + var src = Rect2(0, 0, _texture.get_width(), _texture.get_height()) + var dst = Rect2( + 0, + 0, + _texture.get_width() * scale_vect.x, + _texture.get_height() * scale_vect.y + ) + + draw_texture_rect_region(_texture, dst, src) diff --git a/addons/escoria-core/game/core-scripts/esctooltip.gd b/addons/escoria-core/game/core-scripts/esc_tooltip.gd similarity index 100% rename from addons/escoria-core/game/core-scripts/esctooltip.gd rename to addons/escoria-core/game/core-scripts/esc_tooltip.gd diff --git a/addons/escoria-core/game/core-scripts/esc_walk_context.gd b/addons/escoria-core/game/core-scripts/esc_walk_context.gd new file mode 100644 index 00000000..5d0cd794 --- /dev/null +++ b/addons/escoria-core/game/core-scripts/esc_walk_context.gd @@ -0,0 +1,24 @@ +# The walk context describes the target of a walk command and if that command +# should be executed fast +extends Object +class_name ESCWalkContext + + +# Target object that the walk command tries to reach +var target_object: ESCObject = null + +# The target position +var target_position: Vector2 = Vector2() + +# Wether to move fast +var fast: bool + + +func _init( + p_target_object: ESCObject, + p_target_position: Vector2, + p_fast: bool +): + target_object = p_target_object + target_position = p_target_position + fast = p_fast diff --git a/addons/escoria-core/game/core-scripts/escgame.gd b/addons/escoria-core/game/core-scripts/escgame.gd deleted file mode 100644 index eb681a6f..00000000 --- a/addons/escoria-core/game/core-scripts/escgame.gd +++ /dev/null @@ -1,129 +0,0 @@ -tool -extends Node2D -class_name ESCGame - -func get_class(): - return "ESCGame" - - -export(float) var mouse_tooltip_margin = 50.0 -var tooltip_node : Object - -### EDITOR TOOLS ### -enum EDITOR_GAME_DEBUG_DISPLAY { - NONE, - MOUSE_TOOLTIP_LIMITS -} -export(EDITOR_GAME_DEBUG_DISPLAY) var editor_debug_mode = EDITOR_GAME_DEBUG_DISPLAY.NONE setget set_editor_debug_mode - - - -func set_editor_debug_mode(p_editor_debug_mode : int) -> void: - editor_debug_mode = p_editor_debug_mode - update() - -func _draw(): - if !Engine.is_editor_hint(): - return - if editor_debug_mode == EDITOR_GAME_DEBUG_DISPLAY.NONE: - return - - if editor_debug_mode == EDITOR_GAME_DEBUG_DISPLAY.MOUSE_TOOLTIP_LIMITS: - var mouse_limits : Rect2 = get_viewport_rect().grow(-mouse_tooltip_margin) - print(mouse_limits) - - # Draw lines for tooltip limits - draw_rect(mouse_limits, ColorN("red"), false, 10.0) - return - - -## BACKGROUND ## -func left_click_on_bg(position : Vector2) -> void: - pass - -func right_click_on_bg(position : Vector2) -> void: - pass - -func left_double_click_on_bg(position : Vector2) -> void: - pass - -## ITEM/HOTSPOT FOCUS ## -func element_focused(element_id : String) -> void: - pass - -func element_unfocused() -> void: - pass - - -## ITEMS ## -func left_click_on_item(item_global_id : String, event : InputEvent) -> void: - pass - -func right_click_on_item(item_global_id : String, event : InputEvent) -> void: - pass - -func left_double_click_on_item(item_global_id : String, event : InputEvent) -> void: - pass - - -## INVENTORY ## -func left_click_on_inventory_item(inventory_item_global_id : String, event : InputEvent) -> void: - pass - -func right_click_on_inventory_item(inventory_item_global_id : String, event : InputEvent) -> void: - pass - -func left_double_click_on_inventory_item(inventory_item_global_id : String, event : InputEvent) -> void: - pass - -func inventory_item_focused(inventory_item_global_id : String) -> void: - pass - -func inventory_item_unfocused() -> void: - pass - -func open_inventory(): - pass - -func close_inventory(): - pass - -## MOUSEWHEEL ACTION ## -func mousewheel_action(direction : int): - pass - - -## UI SPECIFICS -func hide_ui(): - pass - -func show_ui(): - pass - - - -## FUNCTIONS BELOW THIS POINT DON'T NEED TO BE REIMPLEMENTED BY USER -## (Although they can be, if required) - -# This function is called if Project setting escoria/ui/tooltip_follows_mouse = true -func update_tooltip_following_mouse_position(p_position : Vector2): - var corrected_position = p_position - - # clamp TOP - if tooltip_node.tooltip_distance_to_edge_top(p_position) <= mouse_tooltip_margin: - corrected_position.y = mouse_tooltip_margin - - # clamp BOTTOM - if tooltip_node.tooltip_distance_to_edge_bottom(p_position + tooltip_node.rect_size) <= mouse_tooltip_margin: - corrected_position.y = escoria.game_size.y - mouse_tooltip_margin - tooltip_node.rect_size.y - - # clamp LEFT - if tooltip_node.tooltip_distance_to_edge_left(p_position - tooltip_node.rect_size/2) <= mouse_tooltip_margin: - corrected_position.x = mouse_tooltip_margin - - # clamp RIGHT - if tooltip_node.tooltip_distance_to_edge_right(p_position + tooltip_node.rect_size/2) <= mouse_tooltip_margin: - corrected_position.x = escoria.game_size.x - mouse_tooltip_margin - tooltip_node.rect_size.x - - tooltip_node.anchor_right = 0.2 - tooltip_node.rect_position = corrected_position + tooltip_node.offset_from_cursor diff --git a/addons/escoria-core/game/core-scripts/escinventoryitem.gd b/addons/escoria-core/game/core-scripts/escinventoryitem.gd deleted file mode 100644 index db2e75f9..00000000 --- a/addons/escoria-core/game/core-scripts/escinventoryitem.gd +++ /dev/null @@ -1,45 +0,0 @@ -extends TextureButton -class_name ESCInventoryItem - -func get_class(): - return "ESCInventoryItem" - -export(String) var global_id - -signal mouse_left_inventory_item(item_id) -signal mouse_right_inventory_item(item_id) -signal mouse_double_left_inventory_item(item_id) -signal inventory_item_focused(item_id) -signal inventory_item_unfocused() - - -func _ready(): - connect("gui_input", self, "_on_inventory_item_gui_input") - connect("mouse_entered", self, "_on_inventory_item_mouse_enter") - connect("mouse_exited", self, "_on_inventory_item_mouse_exit") - -func _on_inventory_item_gui_input(event : InputEvent): - if event.is_action_pressed("switch_action_verb"): - if event.button_index == BUTTON_WHEEL_UP: - escoria.inputs_manager._on_mousewheel_action(-1) - elif event.button_index == BUTTON_WHEEL_DOWN: - escoria.inputs_manager._on_mousewheel_action(1) - if event is InputEventMouseButton: -# var p = get_global_mouse_position() - if event.doubleclick: - if event.button_index == BUTTON_LEFT: - emit_signal("mouse_double_left_inventory_item", global_id, event) - else: - if event.is_pressed(): - if event.button_index == BUTTON_LEFT: - emit_signal("mouse_left_inventory_item", global_id, event) - if event.button_index == BUTTON_RIGHT: - emit_signal("mouse_right_inventory_item", global_id, event) - -func _on_inventory_item_mouse_enter(): - # Notify UI that item is focused (room.game.ui.Label UI) - emit_signal("inventory_item_focused", global_id) - -func _on_inventory_item_mouse_exit(): - # Notify UI that item is unfocused (room.game.ui.Label UI) - emit_signal("inventory_item_unfocused") diff --git a/addons/escoria-core/game/core-scripts/escitem.gd b/addons/escoria-core/game/core-scripts/escitem.gd deleted file mode 100644 index 1da1721f..00000000 --- a/addons/escoria-core/game/core-scripts/escitem.gd +++ /dev/null @@ -1,269 +0,0 @@ -tool -extends Area2D -class_name ESCItem - -""" -ESCItem is a Sprite that defines an item, potentially interactive -""" - -signal mouse_entered_item(item) -signal mouse_exited_item(item) -signal mouse_left_clicked_item(global_id) -signal mouse_double_left_clicked_item(global_id) -signal mouse_right_clicked_item(global_id) - -var Movable -var MovableScript = load("res://addons/escoria-core/game/core-scripts/behaviors/movable.gd") - -export(String) var global_id -export(String, FILE, "*.esc") var esc_script - -# If true, the ESC script may have an ":exit_scene" event to manage scene changes -export(bool) var is_exit - -# is_trigger If true, object is considered as trigger. Allows using :trigger_in and -# :trigger_out verbs in ESC scripts. -export(bool) var is_trigger -export(String) var trigger_in_verb = "trigger_in" -export(String) var trigger_out_verb = "trigger_out" - -# is_interactive : If true, object is not "focusable". -export(bool) var is_interactive = true - -# player_orients_on_arrival : If true, player orients towards 'interaction_direction' as -# player character arrives. -export(bool) var player_orients_on_arrival = true - -export(ESCPlayer.Directions) var interaction_direction -export(String) var tooltip_name - -# Default action to use if object is not in the inventory -export(String) var default_action -# Default action to use if object is in the inventory -export(String) var default_action_inventory - -# If action used by player is in the list, game will wait for a second click on another item -# to combine objects together (typical USE WITH , GIVE TO ) -export(PoolStringArray) var combine_if_action_used_among = [] -# If true, combination must be done in the way it is written in ESC script -# ie. :use ON_ITEM -# If false, combination will be tried in the other way. -export(bool) var combine_is_one_way = false -# If use_from_inventory_only is true, then the object must have been picked up before using it. -# A false value is useful for items in the background, such as buttons. -export(bool) var use_from_inventory_only = false -# Scene used in inventory for the object if it is picked up -export(PackedScene) var inventory_item_scene_file : PackedScene - -# Color used for dialogs -export(Color) var dialog_color = ColorN("white") - - -# Detected interact position set by a Position2D node OUTSIDE OF THE SCENE. -# You have to add a child to the INSTANCED SCENE, IN THE ROOM SCENE. -#var interact_positions : Dictionary = { "default": null} - -# Animation node (null if none was found) -var animation_sprite - -# Animations script (for walking, idling...) -export(Script) var animations - -# TERRAIN -var terrain : ESCTerrain -# If the terrain node type is scalenodes -var terrain_is_scalenodes : bool -var check_maps = true -var collision -# If dont_apply_terrain_scaling is true, terrain scaling will not be applied and -# node will remain at the scale set in the scene. -export(bool) var dont_apply_terrain_scaling = false - -export(int) var speed : int = 300 -export(float) var v_speed_damp : float = 1.0 -var orig_speed : float - -enum PLAYER_TASKS { - NONE, - WALK, - SLIDE -} -onready var task = PLAYER_TASKS.NONE # type PLAYER_TASKS -var params_queue : Array - - -# PRIVATE VARS -# Size of the item -var size : Vector2 -var last_deg : int -var last_dir : int - - -func _ready(): - # Adds movable behavior - Movable = Node.new() - Movable.set_script(MovableScript) - add_child(Movable) - - for n in get_children(): - if n is AnimatedSprite: - animation_sprite = n - continue - if n is AnimationPlayer: - animation_sprite = n - continue - - connect("mouse_entered", self, "_on_mouse_entered") - connect("mouse_exited", self, "_on_mouse_exited") - connect("input_event", self, "manage_input") - - # Initialize collision variable. - for c in get_children(): - if c is CollisionShape2D or c is CollisionPolygon2D: - collision = c - - # Register and connect all elements to Escoria backoffice. - if !Engine.is_editor_hint(): - escoria.object_manager.register_object( - ESCObject.new( - global_id, - self - ), - true - ) - terrain = escoria.room_terrain - - if !is_trigger: - connect("mouse_entered_item", escoria.inputs_manager, "_on_mouse_entered_item") - connect("mouse_exited_item", escoria.inputs_manager, "_on_mouse_exited_item") - connect("mouse_left_clicked_item", escoria.inputs_manager, "_on_mouse_left_clicked_item") - connect("mouse_double_left_clicked_item", escoria.inputs_manager, "_on_mouse_left_double_clicked_item") - connect("mouse_right_clicked_item", escoria.inputs_manager, "_on_mouse_right_clicked_item") - else: - connect("area_entered", self, "element_entered") - connect("area_exited", self, "element_exited") - connect("body_entered", self, "element_entered") - connect("body_exited", self, "element_exited") - - # If object can be in the inventory, set default_action_inventory to same as - # default_action, if default_action_inventory is not set - if use_from_inventory_only and default_action_inventory.empty(): - default_action_inventory = default_action - - # Perform a first terrain scaling if we have to. - if !is_exit or dont_apply_terrain_scaling: - Movable.last_scale = scale - Movable.update_terrain() - - -func get_animation_player(): - if animation_sprite == null: - for n in get_children(): - if n is AnimationPlayer: - animation_sprite = n - return animation_sprite - - -#""" -#Initialize the interact_position attribute by searching for a Position2D -#node in children nodes. -#If any is found, the first one is used as interaction position with this hotspot. -#If none is found, we use the CollisionShape2D or CollisionPolygon2D child node's -#position instead. -#""" -#func init_interact_position_with_node(): -# interact_positions.default = null -# for c in get_children(): -# if c is Position2D: -# # If the position2D node is part of the hotspot, it means it is not an interact position -# # but a dialog position for example. Interact position node must be set in the room scene. -# if c.get_owner() == self: -# continue -# var globalpos = c.global_position -# interact_positions.default = c.global_position -# -# if c is CollisionShape2D or c is CollisionPolygon2D: -# collision = c -# if interact_positions.default == null: -# interact_positions.default = c.global_position - -func get_interact_position() -> Vector2: - var interact_position = null - for c in get_children(): - if c is Position2D: - # If the position2D node is part of the hotspot, it means it is not an interact position - # but a dialog position for example. Interact position node must be set in the room scene. - if c.get_owner() == self: - continue - interact_position = c.global_position - - if c is CollisionShape2D or c is CollisionPolygon2D: - if interact_position == null: - interact_position = c.global_position - - return interact_position - - - -func manage_input(viewport : Viewport, event : InputEvent, shape_idx : int): - if event is InputEventMouseButton: - - if event.doubleclick: - if event.button_index == BUTTON_LEFT: - emit_signal("mouse_double_left_clicked_item", self, event) - else: - if event.is_pressed(): - if event.button_index == BUTTON_LEFT: - emit_signal("mouse_left_clicked_item", self, event) - elif event.button_index == BUTTON_RIGHT: - emit_signal("mouse_right_clicked_item", self, event) - - -func _on_mouse_entered(): - emit_signal("mouse_entered_item", self) - -func _on_mouse_exited(): - emit_signal("mouse_exited_item", self) - -################################################################################ - -# TRIGGER functions - -func element_entered(body): - if body is ESCBackground or body.get_parent() is ESCBackground: - return - escoria.do("trigger_in", [global_id, body.global_id, trigger_in_verb]) - - -func element_exited(body): - if body is ESCBackground or body.get_parent() is ESCBackground: - return - escoria.do("trigger_out", [global_id, body.global_id, trigger_out_verb]) - -################################################################################ - -# MOVING OBJECT functions - -func teleport(target, angle : Object = null) -> void: - Movable.teleport(target, angle) - -func walk_to(pos : Vector2, p_walk_context = null) -> void: - Movable.walk_to(pos, p_walk_context) - -func set_speed(speed_value : int) -> void: - speed = speed_value - -################################################################################ - -# TALKATIVE object functions - -func start_talking(): -# if animation_sprite.is_playing(): -# animation_sprite.stop() -# animation_sprite.play(animations.speaks[last_dir][0]) - pass - -func stop_talking(): -# if animation_sprite.is_playing(): -# animation_sprite.stop() - pass diff --git a/addons/escoria-core/game/core-scripts/escoria_types.gd b/addons/escoria-core/game/core-scripts/escoria_types.gd deleted file mode 100644 index 489b4c25..00000000 --- a/addons/escoria-core/game/core-scripts/escoria_types.gd +++ /dev/null @@ -1,12 +0,0 @@ -extends Node - -const OBJ_DEFAULT_STATE = "default" - -enum EVENT_LEVEL_STATE { - RETURN, # 0 - YIELD, # 1 - BREAK, # 2 - REPEAT, # 3 - CALL, # 4 - JUMP # 5 -} diff --git a/addons/escoria-core/game/core-scripts/escplayer.gd b/addons/escoria-core/game/core-scripts/escplayer.gd deleted file mode 100644 index 34d41888..00000000 --- a/addons/escoria-core/game/core-scripts/escplayer.gd +++ /dev/null @@ -1,173 +0,0 @@ -tool -extends KinematicBody2D -class_name ESCPlayer - -func get_class(): - return "ESCPlayer" - -""" -TODO -- Currently the sprite node needs to be named "sprite". This is bad. -- Animation management doesn't allow using AnimationPlayer yet. Need to find - the best solution to manage both AnimatedSprite and AnimationPlayer. -""" - -var Movable : Node -var MovableScript = load("res://addons/escoria-core/game/core-scripts/behaviors/movable.gd") - -export var global_id : String - -var params_queue : Array -var terrain : ESCTerrain - -# If the terrain node type is scalenodes -var terrain_is_scalenodes : bool -var check_maps = true - -export(int) var speed : int = 300 -export(float) var v_speed_damp : float = 1.0 -var orig_speed : float - -enum PLAYER_TASKS { - NONE, - WALK, - SLIDE -} -onready var task = PLAYER_TASKS.NONE # type PLAYER_TASKS - - -enum Directions { - NORTH = 0, # 0 - NORTHEAST = 1, # 1 - EAST = 2, # 2 - SOUTHEAST = 3, # 3 - SOUTH = 4, # 4 - SOUTHWEST = 5, # 5 - WEST = 6, # 6 - NORTHWEST = 7, # 7 - TOP = 0, - TOP_RIGHT = 1 - RIGHT = 2, - BOTTOM_RIGHT = 3, - BOTTOM = 4, - BOTTOM_LEFT = 5, - LEFT = 6, - TOP_LEFT = 7, -} - -# Animations script (for walking, idling...) -export(Script) var animations - -# AnimatedSprite node (if any) -var animation_sprite -# AnimationPlayer node (if any) -## NOT USED YET -#var animation -var collision - -# Dialogs parameters -export(NodePath) var dialog_position_node -export(Color) var dialog_color = ColorN("white") - -# Camera parameters -export(NodePath) var camera_position_node - - -func _ready(): - # Adds movable behavior - Movable = Node.new() - Movable.set_script(MovableScript) - add_child(Movable) - - - # Connect the player to the event_done signal, so we can react to a finished - # ":setup" event. In this case, we need to run update_terrain() - escoria.event_manager.connect("event_finished", self, "update_terrain") - -# assert(is_angle_in_interval(0, [340,40])) # true -# assert(is_angle_in_interval(359, [340,40])) # true -# assert(is_angle_in_interval(1, [340,40])) # true -# assert(!is_angle_in_interval(90, [340,40])) # false -# -# assert(is_angle_in_interval(90, [70,40])) #true -# assert(!is_angle_in_interval(180, [70,40])) #false -# -# assert(is_angle_in_interval(179, [160, 40])) #true -# assert(is_angle_in_interval(180, [160, 40])) #true -# assert(is_angle_in_interval(181, [160, 40])) #true -# assert(!is_angle_in_interval(0, [160, 40])) #false -# -# assert(is_angle_in_interval(270, [250, 40])) # true -# assert(!is_angle_in_interval(270, [70,40])) #false - - for n in get_children(): - if n is AnimatedSprite: - animation_sprite = n - -# for sprite_child in n.get_children(): -# if sprite_child is AnimationPlayer: -# animation = sprite_child -# break - - if n is CollisionShape2D or n is CollisionPolygon2D: - collision = n - - animation_sprite.connect("animation_finished", self, "anim_finished") - - if Engine.is_editor_hint(): - return - - terrain = escoria.room_terrain - Movable.last_scale = scale - -# set_process(true) - - -func _process(time): - if Engine.is_editor_hint(): - return - $debug.text = str(z_index) - - -func anim_finished(): - pass - - -func get_camera_pos(): - if camera_position_node and get_node(camera_position_node): - return get_node(camera_position_node).global_position - return global_position - - -func get_animations_list() -> PoolStringArray: - return animation_sprite.get_sprite_frames().get_animation_names() - - -func start_talking(): - if animation_sprite.is_playing(): - animation_sprite.stop() - animation_sprite.play(animations.speaks[Movable.last_dir][0]) - -func stop_talking(): - if animation_sprite.is_playing(): - animation_sprite.stop() - animation_sprite.play(animations.idles[Movable.last_dir][0]) - - -func teleport(target, angle : Object = null) -> void: - Movable.teleport(target, angle) - - -func walk_to(pos : Vector2, p_walk_context = null): - return Movable.walk_to(pos, p_walk_context) - - -func set_angle(deg : int, immediate = true): - Movable.set_angle(deg, immediate) - - -func set_speed(speed_value : int) -> void: - speed = speed_value - -func update_terrain(rc: int, event_name: String) -> void: - Movable.update_terrain(event_name) diff --git a/addons/escoria-core/game/core-scripts/escterrain.gd b/addons/escoria-core/game/core-scripts/escterrain.gd deleted file mode 100644 index ed7c62ff..00000000 --- a/addons/escoria-core/game/core-scripts/escterrain.gd +++ /dev/null @@ -1,63 +0,0 @@ -tool -extends "res://addons/escoria-core/game/core-scripts/escterrain_base.gd" -class_name ESCTerrain - -func get_class(): - return "ESCTerrain" - -export var scale_min = 0.3 -export var scale_max = 1.0 - -var current_active_navigation_instance : NavigationPolygonInstance - -func _ready(): - var navigation_enabled_found = false - for n in get_children(): - if n is NavigationPolygonInstance: - if n.enabled: - if navigation_enabled_found: - escoria.logger.report_errors("escterrain.gd:_ready()", ["Multiple NavigationPolygonInstances enabled at the same time."]) - navigation_enabled_found = true - current_active_navigation_instance = n - - if !Engine.is_editor_hint(): - escoria.room_terrain = self - #path = ImagePathFinder.new() - _update_texture() - -func get_scale_range(r): - r = scale_min + (scale_max - scale_min) * r - return Vector2(r, r) - -func get_terrain(pos): - if scales == null || scales.get_data().is_empty(): - return Color(1, 1, 1, 1) - return get_pixel(pos, scales.get_data()) - -func get_pixel(pos, p_image): - if pos.x + 1 >= p_image.get_width() || pos.y + 1 >= p_image.get_height() || pos.x < 0 || pos.y < 0: - return Color(1.0, 0.0, 0.0) - - # `get_pixel()` is slow; this is accurate enough - # without interpolating neighboring pixels and accounting for fractions - p_image.lock() - var pixel = p_image.get_pixel(pos.x, pos.y) - p_image.unlock() - return pixel - -func _draw(): - if typeof(texture) == typeof(null): - return - if !Engine.is_editor_hint(): - return - if debug_mode == 0: - return - var scale_vect = bitmaps_scale - - var src = Rect2(0, 0, texture.get_width(), texture.get_height()) - var dst = Rect2(0, 0, texture.get_width() * scale_vect.x, texture.get_height() * scale_vect.y) - - draw_texture_rect_region(texture, dst, src) - #draw_texture(texture, Vector2(0, 0)) - - diff --git a/addons/escoria-core/game/core-scripts/escterrain_base.gd b/addons/escoria-core/game/core-scripts/escterrain_base.gd deleted file mode 100644 index 274aaa3d..00000000 --- a/addons/escoria-core/game/core-scripts/escterrain_base.gd +++ /dev/null @@ -1,177 +0,0 @@ -tool -extends Navigation2D - -export(Texture) var scales setget set_scales,get_scales -export var bitmaps_scale = Vector2(1,1) setget set_bm_scale,get_bm_scale -export(Texture) var lightmap setget set_lightmap,get_lightmap -var lightmap_data - -#warning-ignore:unused_class_variable -export var player_speed_multiplier = 1.0 # Override player speed in current scene -#warning-ignore:unused_class_variable -export var player_doubleclick_speed_multiplier = 1.5 # Make the player move faster when doubleclicked -export var lightmap_modulate = Color(1, 1, 1, 1) -export(int, "None", "Scales", "Lightmap") var debug_mode = 1 setget debug_mode_updated - -var texture -var img_area -var _texture_dirty = false - -func set_bm_scale(p_scale): - bitmaps_scale = p_scale - _update_texture() - -func get_bm_scale(): - return bitmaps_scale - -func set_lightmap(p_lightmap): - var need_init = (lightmap != p_lightmap) or (lightmap and not lightmap_data) - - lightmap = p_lightmap - - # It's bad enough a new copy is created when reading a pixel, we don't - # also need to get the data for every read to make yet another copy - if need_init: - if lightmap_data: - lightmap_data.unlock() - lightmap_data = lightmap.get_data() - lightmap_data.lock() - - _update_texture() - -func get_lightmap(): - return lightmap - -func set_scales(p_scales): - scales = p_scales - _update_texture() - -func get_scales(): - return scales - -func debug_mode_updated(p_mode): - debug_mode = p_mode - _update_texture() - -func _update_texture(): - if _texture_dirty: - return - - _texture_dirty = true - call_deferred("_do_update_texture") - -func _do_update_texture(): - _texture_dirty = false - if !is_inside_tree(): - return - if !Engine.is_editor_hint(): - return - - if debug_mode == 0: - update() - return - - texture = ImageTexture.new() - if debug_mode == 1: - if scales != null: - #texture.create_from_image(scales) - texture = scales - else: - if lightmap != null: - #texture.create_from_image(lightmap) - texture = lightmap - - update() - - - -func make_local(pos): - pos = pos - get_position() - pos = pos * 1.0 / get_scale() - pos = get_closest_point(pos) - return pos - -func make_global(pos): - pos = pos * get_scale() - pos = pos + get_position() - return pos - -func get_terrain_path(p_src, p_dest): - # printt("get path ", p_src, p_dest) - p_src = make_local(p_src) - p_dest = make_local(p_dest) - - var r_path = get_simple_path(p_src, p_dest, true) - r_path = Array(r_path) - for i in range(0, r_path.size()): - r_path[i] = make_global(r_path[i]) - return r_path - -func is_solid(pos): - pos = pos - get_position() - pos = pos * 1.0 / get_scale() - - var closest = get_closest_point(pos) - return pos == closest - -func _color_mul(a, b): - var c = Color() - c.r = a.r * b.r - c.g = a.g * b.g - c.b = a.b * b.b - c.a = a.a * b.a - return c - -func get_light(pos): - if not lightmap or lightmap.get_data().is_empty(): - return - - return _color_mul(get_pixel(pos, lightmap_data), lightmap_modulate) - -func get_pixel(pos, p_image): - p_image.lock() - - pos = make_local(pos) - pos = pos * 1.0 / bitmaps_scale - - if pos.x + 1 >= p_image.get_width() || pos.y + 1 >= p_image.get_height() || pos.x < 0 || pos.y < 0: - return Color() - - var ll = p_image.get_pixel(pos.x, pos.y) - var ndif = Vector2() - ndif.x = pos.x - floor(pos.x) - ndif.y = pos.y - floor(pos.y) - var ur - - img_area = Rect2(0, 0, p_image.get_width(), p_image.get_height()) - - var lr = ll - if ndif.x > 0 && img_area.has_point(Vector2(pos.x+1, pos.y)): - lr = p_image.get_pixel(pos.x+1, pos.y) - #if lr.a < 128: - # lr = ll - ur = lr - - var ul = ll - if ndif.y > 0 && img_area.has_point(Vector2(pos.x, pos.y+1)): - ul = p_image.get_pixel(pos.x, pos.y+1) - #if ul.a < 128: - # ul = ll - ur = ul - - if ndif.x > 0 && ndif.y > 0 && img_area.has_point(Vector2(pos.x+1, pos.y+1)): - var pix = p_image.get_pixel(pos.x+1, pos.y+1) - #if pix.a > 128: - ur = pix - - var bottom = ll.linear_interpolate(lr, ndif.x) - var top - if ur != null: - top = ul.linear_interpolate(ur, ndif.x) - else: - top = ul - - var final = bottom.linear_interpolate(top, ndif.y) - - p_image.unlock() - return final diff --git a/addons/escoria-core/game/core-scripts/escterrain_scalenodes.gd b/addons/escoria-core/game/core-scripts/escterrain_scalenodes.gd deleted file mode 100644 index 1c6b5ba2..00000000 --- a/addons/escoria-core/game/core-scripts/escterrain_scalenodes.gd +++ /dev/null @@ -1,92 +0,0 @@ -tool - -extends "terrain_base.gd" - -const DIST_EPSILON = 0.000001 - -var scale_nodes = [] - -onready var scale_min = $"scale_min" -onready var scale_max = $"scale_max" - -func debug_mode_updated(p_mode): - debug_mode = p_mode - - ._update_texture() - -func _do_update_texture(): - _texture_dirty = false - if !is_inside_tree(): - return - if !Engine.is_editor_hint(): - return - - if debug_mode == 0: - update() - return - - texture = ImageTexture.new() - - if lightmap != null: - #texture.create_from_image(lightmap) - texture = lightmap - - update() - -static func sort_by_y(a, b): - return a.global_position.y < b.global_position.y - -# Return a "scale range" immediately based on the interpolated scale size -func get_terrain(pos): - # printt("Called", pos) - var prev - var next - var prev_target - var node_target - for i in range(1, scale_nodes.size()): - prev = scale_nodes[i - 1] - next = scale_nodes[i] - - if prev.global_position.y < pos.y and pos.y < next.global_position.y: - # printt("1:", prev.global_position.y, " < ", pos.y, " and ", pos.y, " < ", next.global_position.y) - prev_target = prev.target_scale.y - node_target = next.target_scale.y - break - - var nodes_dist = next.global_position.y - prev.global_position.y - if nodes_dist < DIST_EPSILON: - nodes_dist = DIST_EPSILON - var interp_dist = (pos.y - prev.global_position.y) / nodes_dist - - var y_1 = Vector2(0, prev_target) - var y_2 = Vector2(0, node_target) - - var interp = y_1.linear_interpolate(y_2, interp_dist) - - return Vector2(interp.y, interp.y) - -func get_pixel(pos, p_image): - if pos.x + 1 >= p_image.get_width() || pos.y + 1 >= p_image.get_height() || pos.x < 0 || pos.y < 0: - return Color(1.0, 0.0, 0.0) - - # `get_pixel()` is slow; this is accurate enough - # without interpolating neighboring pixels and accounting for fractions - return p_image.get_pixel(pos.x, pos.y) - -func _draw(): - if not texture: - return - - if debug_mode == 0: - return - - draw_texture(texture, Vector2(0, 0)) - -func _ready(): - for c in get_children(): - if c is preload("scalenode.gd"): - scale_nodes.push_back(c) - - scale_nodes.sort_custom(self, "sort_by_y") - scale_nodes.push_front(scale_min) - scale_nodes.push_back(scale_max) diff --git a/addons/escoria-core/game/core-scripts/items_inventory.gd b/addons/escoria-core/game/core-scripts/items_inventory.gd deleted file mode 100644 index 996052af..00000000 --- a/addons/escoria-core/game/core-scripts/items_inventory.gd +++ /dev/null @@ -1,9 +0,0 @@ -extends Node - - -func get_inventory_item(item_id : String) -> ESCInventoryItem: - for c in get_children(): - if c.global_id == item_id: - if c.inventory_item_scene_file: - return c.inventory_item_scene_file.instance() - return null diff --git a/addons/escoria-core/game/core-scripts/log/logging.gd b/addons/escoria-core/game/core-scripts/log/esc_logger.gd similarity index 100% rename from addons/escoria-core/game/core-scripts/log/logging.gd rename to addons/escoria-core/game/core-scripts/log/esc_logger.gd diff --git a/addons/escoria-core/game/core-scripts/old/scalenode.gd b/addons/escoria-core/game/core-scripts/old/scalenode.gd deleted file mode 100644 index 6e283008..00000000 --- a/addons/escoria-core/game/core-scripts/old/scalenode.gd +++ /dev/null @@ -1,5 +0,0 @@ -extends Position2D - -#warning-ignore:unused_class_variable -export(Vector2) var target_scale = Vector2(1.0, 1.0) - diff --git a/addons/escoria-core/game/core-scripts/scalenode.gd b/addons/escoria-core/game/core-scripts/scalenode.gd deleted file mode 100644 index bf328f53..00000000 --- a/addons/escoria-core/game/core-scripts/scalenode.gd +++ /dev/null @@ -1,4 +0,0 @@ -extends Position2D - -#warning-ignore:unused_class_variable -export(Vector2) var target_scale = Vector2(1.0, 1.0) diff --git a/addons/escoria-core/game/core-scripts/utils/utils.gd b/addons/escoria-core/game/core-scripts/utils/esc_utils.gd similarity index 88% rename from addons/escoria-core/game/core-scripts/utils/utils.gd rename to addons/escoria-core/game/core-scripts/utils/esc_utils.gd index 6393a016..8902074e 100644 --- a/addons/escoria-core/game/core-scripts/utils/utils.gd +++ b/addons/escoria-core/game/core-scripts/utils/esc_utils.gd @@ -1,6 +1,15 @@ +# A set of common utilities +extends Object +class_name ESCUtils -# Helpers to deal with player's and items' angles -func _get_deg_from_rad(rad_angle : float): + +# Convert radians to degrees +# +# #### Parameters +# +# - rad_angle: Angle in radians +# **Returns** Degrees +func get_deg_from_rad(rad_angle : float): var deg = rad2deg(rad_angle) if deg >= 360.0: deg = clamp(deg, 0.0, 360.0) diff --git a/addons/escoria-core/game/escoria.gd b/addons/escoria-core/game/escoria.gd index 133b99f5..d7c4cd91 100644 --- a/addons/escoria-core/game/escoria.gd +++ b/addons/escoria-core/game/escoria.gd @@ -1,14 +1,24 @@ +# The escorie main script extends Node -# Scripts -onready var main = $main -onready var inputs_manager = $inputs_manager -onready var utils = load("res://addons/escoria-core/game/core-scripts/utils/utils.gd").new() -onready var save_data = load("res://addons/escoria-core/game/core-scripts/save_data/save_data.gd").new() + +# Current game state +# * DEFAULT: Common game function +# * DIALOG: Game is playing a dialog +# * WAIT: Game is waiting +enum GAME_STATE { + DEFAULT, + DIALOG, + WAIT +} + # Logger used var logger: ESCLogger +# Several utilities +var utils: ESCUtils + # The inventory manager instance var inventory_manager: ESCInventoryManager @@ -30,30 +40,24 @@ var object_manager: ESCObjectManager # ESC command registry instance var command_registry: ESCCommandRegistry -var resource_cache: ResourceCache +# Resource cache handler +var resource_cache: ESCResourceCache -# INSTANCES +# Instance of the main menu var main_menu_instance -## Dialog player instantiator. This instance is called directly for dialogs. -var dialog_player -## Inventory scene -var inventory - -# Game variables +# Terrain of the current room var room_terrain -enum GAME_STATE { - DEFAULT, - DIALOG, - WAIT -} -onready var current_state = GAME_STATE.DEFAULT +# Dialog player instantiator. This instance is called directly for dialogs. +var dialog_player -onready var game_size = get_viewport().size +# Inventory scene +var inventory # These are settings that the player can affect and save/load later var settings : Dictionary + # These are default settings var settings_default : Dictionary = { # Text language @@ -64,7 +68,7 @@ var settings_default : Dictionary = { "speech_enabled": ProjectSettings.get_setting("escoria/sound/speech_enabled"), # Master volume (max is 1.0) "master_volume": ProjectSettings.get_setting("escoria/sound/master_volume"), - # Music volume (max is 1.0) + # Music volume (max is 1.0) "music_volume": ProjectSettings.get_setting("escoria/sound/music_volume"), # Sound effects volume (max is 1.0) "sfx_volume": ProjectSettings.get_setting("escoria/sound/sfx_volume"), @@ -79,8 +83,26 @@ var settings_default : Dictionary = { } +# The current state of the game +onready var current_state = GAME_STATE.DEFAULT + +# The game resolution +onready var game_size = get_viewport().size + +# The main scene +onready var main = $main + +# The escoria inputs manager +onready var inputs_manager = $inputs_manager + +# Savegame management +onready var save_data = load("res://addons/escoria-core/game/core-scripts/save_data/save_data.gd").new() + + +# Initialize various objects func _init(): self.logger = ESCLogger.new() + self.utils = ESCUtils.new() self.inventory_manager = ESCInventoryManager.new() self.action_manager = ESCActionManager.new() self.event_manager = ESCEventManager.new() @@ -89,10 +111,11 @@ func _init(): self.object_manager = ESCObjectManager.new() self.command_registry = ESCCommandRegistry.new() self.esc_compiler = ESCCompiler.new() - self.resource_cache = ResourceCache.new() + self.resource_cache = ESCResourceCache.new() self.resource_cache.start() +# Load settings func _ready(): save_data.start() save_data.check_settings() @@ -101,8 +124,6 @@ func _ready(): escoria._on_settings_loaded(escoria.settings) -################################################################################## - # Called by Main menu "start new game" func new_game(): var script = self.esc_compiler.load_esc_file( @@ -112,19 +133,21 @@ func new_game(): var rc = yield(event_manager, "event_finished") while rc[1] != "start": rc = yield(event_manager, "event_finished") - + if rc[0] != ESCExecution.RC_OK: self.logger.report_errors( "Start event of the start script returned unsuccessful: %d" % rc[0], [] ) return - -""" -Generic action function that runs an action on an element of the room (eg player walk) -action: type of the action () -""" + +# Run a generic action +# +# #### Parameters +# +# - action: type of the action to run +# - params: Parameters for the action func do(action : String, params : Array = []) -> void: if current_state == GAME_STATE.DEFAULT: match action: @@ -134,10 +157,10 @@ func do(action : String, params : Array = []) -> void: # Check moving object. if not self.object_manager.has(params[0]): self.logger.report_errors( - "escoria.gd:do()", + "escoria.gd:do()", [ - "Walk action requested on inexisting object: %s "\ - % params[0] + "Walk action requested on inexisting " + \ + "object: %s " % params[0] ] ) return @@ -151,14 +174,18 @@ func do(action : String, params : Array = []) -> void: var is_fast : bool = false if params.size() > 2 and params[2] == true: is_fast = true - var walk_context = {"fast": is_fast, "target": target_position} + var walk_context = ESCWalkContext.new( + null, + target_position, + is_fast + ) moving_obj.walk_to(target_position, walk_context) # Walk to object from its id elif params[1] is String: if not self.object_manager.has(params[1]): self.logger.report_errors( - "escoria.gd:do()", + "escoria.gd:do()", [ "Walk action requested TOWARDS " +\ "inexisting object: %s" % params[1] @@ -168,31 +195,45 @@ func do(action : String, params : Array = []) -> void: var object = self.object_manager.get_object(params[1]) if object: - var target_position : Vector2 = object.node.interact_position + var target_position : Vector2 = \ + object.node.interact_position var is_fast : bool = false if params.size() > 2 and params[2] == true: is_fast = true - var walk_context = {"fast": is_fast, "target_object" : object} + var walk_context = ESCWalkContext.new( + object, + Vector2(), + is_fast + ) moving_obj.walk_to(target_position, walk_context) "item_left_click": if params[0] is String: - self.logger.info("escoria.do() : item_left_click on item ", [params[0]]) + self.logger.info( + "escoria.do() : item_left_click on item ", + [params[0]] + ) var item = self.object_manager.get_object(params[0]) - ev_left_click_on_item(item, params[1]) + _ev_left_click_on_item(item, params[1]) "item_right_click": if params[0] is String: - self.logger.info("escoria.do() : item_right_click on item ", [params[0]]) + self.logger.info( + "escoria.do() : item_right_click on item ", + [params[0]] + ) var item = self.object_manager.get_object(params[0]) - ev_left_click_on_item(item, params[1], true) + _ev_left_click_on_item(item, params[1], true) "trigger_in": var trigger_id = params[0] var object_id = params[1] var trigger_in_verb = params[2] - self.logger.info("escoria.do() : trigger_in " + trigger_id + " by " + object_id) + self.logger.info("escoria.do() : trigger_in %s by %s" % [ + trigger_id, + object_id + ]) self.event_manager.queue_event( object_manager.get_object(trigger_id).events[ trigger_in_verb @@ -203,7 +244,10 @@ func do(action : String, params : Array = []) -> void: var trigger_id = params[0] var object_id = params[1] var trigger_out_verb = params[2] - self.logger.info("escoria.do() : trigger_out " + trigger_id + " by " + object_id) + self.logger.info("escoria.do() : trigger_out %s by %s" % [ + trigger_id, + object_id + ]) self.event_manager.queue_event( object_manager.get_object(trigger_id).events[ trigger_out_verb @@ -211,26 +255,27 @@ func do(action : String, params : Array = []) -> void: ) _: - self.logger.report_warnings("escoria.gd:do()", + self.logger.report_warnings("escoria.gd:do()", ["Action received:", action, "with params ", params]) elif current_state == GAME_STATE.WAIT: pass - -# PRIVATE -func ev_left_click_on_item(obj, event, default_action = false): - """ - Event occurring when an object/item is left clicked - obj : object that was left clicked - event : - """ +# Event handler when an object/item was clicked +# FIXME this method is way to complex +# +# #### Parameters +# +# - ob: Object that was left clicked +# - event: Input event that was received +# - default_action: Run the inventory default action +func _ev_left_click_on_item(obj, event, default_action = false): if obj is String: obj = object_manager.get_object(obj) self.logger.info(obj.global_id + " left-clicked with event ", [event]) var need_combine = false - # Check if current_action and current_tool are already set + # Check if current_action and current_tool are already set if self.action_manager.current_action: if self.action_manager.current_tool: if self.action_manager.current_action in self.action_manager\ @@ -251,23 +296,24 @@ func ev_left_click_on_item(obj, event, default_action = false): self.action_manager.current_tool = obj - # Don't interact after player movement towards object (because object is inactive for example) + # Don't interact after player movement towards object + # (because object is inactive for example) var dont_interact = false - var destination_position : Vector2 = main.current_scene.player.global_position + var destination_position : Vector2 = main.current_scene.player.\ + global_position # Create walk context - var walk_context = {"fast": event.doubleclick, "target_object" : obj.node} + var walk_context = ESCWalkContext.new( + obj, + Vector2(), + event.doubleclick + ) # If object not in inventory, player walks towards it if not inventory_manager.inventory_has(obj.global_id): var clicked_object_has_interact_position = false if object_manager.get_object(obj.global_id).interactive: -# if obj.interact_positions.default != null: -# destination_position = obj.interact_positions.default#.global_position -# clicked_object_has_interact_position = true -# else: -# destination_position = obj.position if obj.node.get_interact_position() != null: destination_position = obj.node.get_interact_position() clicked_object_has_interact_position = true @@ -277,20 +323,25 @@ func ev_left_click_on_item(obj, event, default_action = false): destination_position = event.position dont_interact = true - # Use ESC for this? - var is_already_walking = main.current_scene.player.walk_to(destination_position, walk_context) + main.current_scene.player.walk_to( + destination_position, + walk_context + ) # Wait for the player to arrive before continuing with action. - var context = yield(main.current_scene.player, "arrived") + var context: ESCWalkContext = yield( + main.current_scene.player, + "arrived" + ) + self.logger.info("Context arrived: ", [context]) - if context.has("target_object") and walk_context.has("target_object"): - if (context.target_object.global_id != walk_context.target_object.global_id) \ - or (context.target_object.global_id == walk_context.target_object.global_id and is_already_walking): - dont_interact = true - elif context.has("target") and walk_context.has("target"): - if (context.target.global_id != walk_context.target.global_id) \ - or (context.target.global_id == walk_context.target.global_id and is_already_walking): - dont_interact = true + + if context.target_object and \ + context.target_object.global_id != walk_context.\ + target_object.global_id: + dont_interact = true + elif context.target_position != walk_context.target_position: + dont_interact = true # If no interaction should happen after player has arrived, leave immediately. if dont_interact: @@ -318,22 +369,24 @@ func ev_left_click_on_item(obj, event, default_action = false): # If apply_interact, perform combine between items if need_combine: self.action_manager.activate( - self.action_manager.current_action, - self.action_manager.current_tool, + self.action_manager.current_action, + self.action_manager.current_tool, obj ) else: self.action_manager.activate( - self.action_manager.current_action, + self.action_manager.current_action, obj ) - -# else: -## escoria.fallback("") -# pass -func _on_settings_loaded(p_settings : Dictionary): + +# Apply the loaded settings +# +# #### Parameters +# +# * p_settings: Loaded settings +func _on_settings_loaded(p_settings : Dictionary) -> void: escoria.logger.info("******* settings loaded", p_settings) if p_settings != null: settings = p_settings @@ -346,9 +399,18 @@ func _on_settings_loaded(p_settings : Dictionary): # TODO Apply globally # AudioServer.set_fx_global_volume_scale(settings.sfx_volume) - AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Master"), linear2db(settings.master_volume)) - AudioServer.set_bus_volume_db(AudioServer.get_bus_index("SFX"), linear2db(settings.sfx_volume)) - AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Music"), linear2db(settings.music_volume)) + AudioServer.set_bus_volume_db( + AudioServer.get_bus_index("Master"), + linear2db(settings.master_volume) + ) + AudioServer.set_bus_volume_db( + AudioServer.get_bus_index("SFX"), + linear2db(settings.sfx_volume) + ) + AudioServer.set_bus_volume_db( + AudioServer.get_bus_index("Music"), + linear2db(settings.music_volume) + ) TranslationServer.set_locale(settings.text_lang) # music_volume_changed() diff --git a/addons/escoria-core/game/inputs_manager.gd b/addons/escoria-core/game/inputs_manager.gd index 1faa37c1..c22fa506 100644 --- a/addons/escoria-core/game/inputs_manager.gd +++ b/addons/escoria-core/game/inputs_manager.gd @@ -1,15 +1,22 @@ +# Escoria inputs manager +# Catches, handles and distributes input events for the game tool extends Node + +# A LIFO stack of hovered items onready var hover_stack : Array = [] + +# The global id fo the topmost item from the hover_stack onready var hotspot_focused : String = "" -func _ready(): - set_process_input(true) - - -func _input(event): +# Input event handler +# +# #### Parameters +# +# - event: Godot input event received +func _input(event: InputEvent) -> void: if event.is_action_pressed("esc_show_debug_prompt"): escoria.main.get_node("layers/debug_layer/esc_prompt_popup").popup() @@ -21,57 +28,97 @@ func _input(event): if event is InputEventMouseMotion: escoria.main.current_scene.game.update_tooltip_following_mouse_position(event.position) -################################################################################### -func _on_left_click_on_bg(position : Vector2): +# The background was clicked with the LMB +# +# #### Parameters +# +# - position: Position of the click +func _on_left_click_on_bg(position: Vector2) -> void: if hotspot_focused.empty(): escoria.logger.info("Left click on background at ", [str(position)]) escoria.main.current_scene.game.left_click_on_bg(position) -func _on_double_left_click_on_bg(position : Vector2): +# The background was double-clicked with the LMB +# +# #### Parameters +# +# - position: Position of the click +func _on_double_left_click_on_bg(position: Vector2) -> void: if hotspot_focused.empty(): escoria.logger.info("Double left click on background at ", [str(position)]) escoria.main.current_scene.game.left_double_click_on_bg(position) -func _on_right_click_on_bg(position : Vector2): +# The background was clicked with the RMB +# +# #### Parameters +# +# - position: Position of the click +func _on_right_click_on_bg(position: Vector2) -> void: if hotspot_focused.empty(): escoria.logger.info("Right click on background at ", [str(position)]) escoria.main.current_scene.game.right_click_on_bg(position) -################################################################################## -func _on_mouse_left_click_inventory_item(inventory_item_global_id, event : InputEvent) -> void: +# An inventory item was clicked with the LMB +# +# #### Parameters +# +# - inventory_item_global_id: The global id of the clicked inventory item +# - event: The input event received +func _on_mouse_left_click_inventory_item(inventory_item_global_id: String, event: InputEvent) -> void: escoria.logger.info("Inventory item left clicked ", [inventory_item_global_id]) escoria.main.current_scene.game.left_click_on_inventory_item(inventory_item_global_id, event) -func _on_mouse_right_click_inventory_item(inventory_item_global_id, event : InputEvent) -> void: +# An inventory item was clicked with the RMB +# +# #### Parameters +# +# - inventory_item_global_id: The global id of the clicked inventory item +# - event: The input event received +func _on_mouse_right_click_inventory_item(inventory_item_global_id: String, event: InputEvent) -> void: escoria.logger.info("Inventory item right clicked ", [inventory_item_global_id]) escoria.main.current_scene.game.right_click_on_inventory_item(inventory_item_global_id, event) -func _on_mouse_double_left_click_inventory_item(inventory_item_global_id, event : InputEvent) -> void: +# An inventory item was doublce-clicked with the LMB +# +# #### Parameters +# +# - inventory_item_global_id: The global id of the clicked inventory item +# - event: The input event received +func _on_mouse_double_left_click_inventory_item(inventory_item_global_id: String, event: InputEvent) -> void: escoria.logger.info("Inventory item double left clicked ", [inventory_item_global_id]) escoria.main.current_scene.game.left_double_click_on_inventory_item(inventory_item_global_id, event) -func _on_mouse_entered_inventory_item(inventory_item_global_id) -> void: +# The mouse entered an inventory item +# +# #### Parameters +# +# - inventory_item_global_id: The global id of the inventory item that is hovered +func _on_mouse_entered_inventory_item(inventory_item_global_id: String) -> void: escoria.logger.info("Inventory item focused ", [inventory_item_global_id]) escoria.main.current_scene.game.inventory_item_focused(inventory_item_global_id) +# The mouse exited an inventory item func _on_mouse_exited_inventory_item() -> void: escoria.logger.info("Inventory item unfocused") escoria.main.current_scene.game.inventory_item_unfocused() -################################################################################## - -func _on_mouse_entered_item(item : ESCItem) -> void: +# The mouse entered an Escoria item +# +# #### Parameters +# +# - item: The Escoria item hovered +func _on_mouse_entered_item(item: ESCItem) -> void: escoria.logger.info("Item focused : ", [item.global_id]) - clean_hover_stack() + _clean_hover_stack() if !hover_stack.empty(): if item.z_index > hover_stack.back().z_index: @@ -85,9 +132,14 @@ func _on_mouse_entered_item(item : ESCItem) -> void: escoria.main.current_scene.game.element_focused(item.global_id) +# The mouse exited an Escoria item +# +# #### Parameters +# +# - item: The Escoria item hovered func _on_mouse_exited_item(item : ESCItem) -> void: escoria.logger.info("Item unfocused : ", [item.global_id]) - hover_stack_pop(item) + _hover_stack_pop(item) if hover_stack.empty(): hotspot_focused = "" escoria.main.current_scene.game.element_unfocused() @@ -95,40 +147,62 @@ func _on_mouse_exited_item(item : ESCItem) -> void: hotspot_focused = hover_stack.back().global_id escoria.main.current_scene.game.element_focused(hotspot_focused) - + +# An Escoria item was clicked with the LMB +# +# #### Parameters +# +# - item: The Escoria item clicked +# - event: The input event from the click func _on_mouse_left_clicked_item(item : ESCItem, event : InputEvent) -> void: if hover_stack.empty() or hover_stack.back() == item: escoria.logger.info("Item left clicked", [item.global_id, event]) escoria.main.current_scene.game.left_click_on_item(item.global_id, event) +# An Escoria item was double-clicked with the LMB +# +# #### Parameters +# +# - item: The Escoria item clicked +# - event: The input event from the click func _on_mouse_left_double_clicked_item(item : ESCItem, event : InputEvent) -> void: escoria.logger.info("Item left double clicked", [item.global_id, event]) escoria.main.current_scene.game.left_double_click_on_item(item.global_id, event) +# An Escoria item was clicked with the RMB +# +# #### Parameters +# +# - item: The Escoria item clicked +# - event: The input event from the click func _on_mouse_right_clicked_item(item : ESCItem, event : InputEvent) -> void: escoria.logger.info("Item right clicked", [item.global_id, event]) escoria.main.current_scene.game.right_click_on_item(item.global_id, event) -################################################################################## - +# The mousewheel was turned +# +# #### Parameters +# +# - direction: The direction the wheel was turned. 1 = up, -1 = down func _on_mousewheel_action(direction : int): escoria.main.current_scene.game.mousewheel_action(direction) -################################################################################## +# Event when the pause menu was requested +func _on_pause_menu_requested(): + escoria.main.current_scene.game.pause_game() -func clean_hover_stack(): + +# Clean the hover stack +func _clean_hover_stack(): for e in hover_stack: if e == null or !is_instance_valid(e): hover_stack.erase(e) -func hover_stack_pop(item): + +# Remove the given item from the stack +func _hover_stack_pop(item): hover_stack.erase(item) - -################################################################################ - -func _on_pause_menu_requested(): - escoria.main.current_scene.game.pause_game() diff --git a/addons/escoria-core/game/main.gd b/addons/escoria-core/game/main.gd index 0654b109..70c96183 100644 --- a/addons/escoria-core/game/main.gd +++ b/addons/escoria-core/game/main.gd @@ -1,43 +1,55 @@ +# Escoria main room handling and scene switcher extends Node # This script is basically the scene-switcher. # Global id of the last scene the player was before current scene -var last_scene_global_id -# Current scene room being displayed -var current_scene +var last_scene_global_id: String +# Current scene room being displayed +var current_scene: Node + +# The Escoria context currently in wait state var wait_level +# FIXME Document this variable var screen_ofs = Vector2(0, 0) -# ESCBackgroundMusic node +# Reference to the ESCBackgroundMusic node onready var bg_music = $bg_music + +# Reference to the scene transition node onready var scene_transition = $layers/curtain/scene_transition -# Set the new current scene +# Connect the wait timer event +func _ready() -> void: + $layers/wait_timer.connect("timeout", self, "_on_wait_finished") + + +# Set current scene # # #### Parameters # -# - p_scene: Current scene to set -func set_scene(p_scene: Node): +# - p_scene: Scene to set +func set_scene(p_scene: Node) -> void: if !p_scene: escoria.logger.report_errors("main", ["Trying to set empty scene"]) if current_scene != null: clear_scene() - + add_child(p_scene) move_child(p_scene, 0) - + current_scene = p_scene check_game_scene_methods() set_camera_limits() -func clear_scene(): +# Cleanup the current scene +func clear_scene() -> void: if current_scene == null: return @@ -48,14 +60,18 @@ func clear_scene(): current_scene.free() current_scene = null -func wait(params : Array, level): - wait_level = level - $layers/wait_timer.set_wait_time(float(params[0])) - $layers/wait_timer.set_one_shot(true) - $layers/wait_timer.start() + +# Triggered, when the wait has finished +func _on_wait_finished() -> void: + escoria.esc_level_runner.finished(wait_level) -func set_camera_limits(camera_limit_id : int = 0): +# Set the camera limits +# +# #### Parameters +# +# * camera_limits_id: The id of the room's camera limits to set +func set_camera_limits(camera_limit_id : int = 0) -> void: var limits = {} var scene_camera_limits = current_scene.camera_limits[camera_limit_id] if scene_camera_limits.size.x == 0 and scene_camera_limits.size.y == 0: @@ -65,10 +81,14 @@ func set_camera_limits(camera_limit_id : int = 0): area = child.get_full_area_rect2() break - # if the background is smaller than the viewport, we want the camera to stick centered on the background - if area.size.x == 0 or area.size.y == 0 or area.size < get_viewport().size: - escoria.logger.report_warning("main.gd:set_camera_limits()", - "No limit area! Using viewport.") + # if the background is smaller than the viewport, we want the camera + # to stick centered on the background + if area.size.x == 0 or area.size.y == 0 \ + or area.size < get_viewport().size: + escoria.logger.report_warning( + "main.gd:set_camera_limits()", + "No limit area! Using viewport." + ) area.size = get_viewport().size escoria.logger.info("Setting camera limits from scene ", [area]) @@ -82,21 +102,25 @@ func set_camera_limits(camera_limit_id : int = 0): else: limits = { "limit_left": scene_camera_limits.position.x, - "limit_right": scene_camera_limits.position.x + scene_camera_limits.size.x, + "limit_right": 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, + "limit_bottom": scene_camera_limits.position.y + \ + scene_camera_limits.size.y + screen_ofs.y * 2, "set_default": true, } - escoria.logger.info("Setting camera limits from parameter ", [scene_camera_limits]) + escoria.logger.info( + "Setting camera limits from parameter ", + [scene_camera_limits] + ) current_scene.game.get_node("camera").set_limits(limits) current_scene.game.get_node("camera").set_offset(screen_ofs * 2) -""" -The game.tscn scene's root node script MUST implement the following methods. -If they do not exist, stop immediately. Implement them, even if empty -""" +# Sanity check that the game.tscn scene's root node script MUST +# implement the following methods. If they do not exist, stop immediately. +# Implement them, even if empty func check_game_scene_methods(): assert(current_scene.game.has_method("left_click_on_bg")) assert(current_scene.game.has_method("right_click_on_bg")) diff --git a/addons/escoria-core/game/main_scene.gd b/addons/escoria-core/game/main_scene.gd index 25cb64a5..ddcfbee9 100644 --- a/addons/escoria-core/game/main_scene.gd +++ b/addons/escoria-core/game/main_scene.gd @@ -1,10 +1,13 @@ -extends Node - # Main_scene is the entry point for Godot Engine. # This scene sets up the main menu scene to load. +extends Node + +# Start the main menu func _ready(): - var main_menu_path = ProjectSettings.get_setting("escoria/ui/main_menu_scene") + var main_menu_path = ProjectSettings.get_setting( + "escoria/ui/main_menu_scene" + ) var main_menu_scene = load(main_menu_path).instance() # get_tree().get_root().call_deferred("add_child", main_menu_scene) escoria.call_deferred("add_child", main_menu_scene) diff --git a/addons/escoria-core/game/scenes/camera_player/esccamera.gd b/addons/escoria-core/game/scenes/camera_player/esccamera.gd index 51c437db..00a719e5 100644 --- a/addons/escoria-core/game/scenes/camera_player/esccamera.gd +++ b/addons/escoria-core/game/scenes/camera_player/esccamera.gd @@ -177,7 +177,7 @@ func _process(_delta): 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: + or "moved" in target.movable and target.movable.moved: self.global_position = resolve_target_pos() func _ready(): diff --git a/addons/escoria-core/game/scenes/inventory/inventory_ui.gd b/addons/escoria-core/game/scenes/inventory/inventory_ui.gd index 093ec721..f74ada5b 100644 --- a/addons/escoria-core/game/scenes/inventory/inventory_ui.gd +++ b/addons/escoria-core/game/scenes/inventory/inventory_ui.gd @@ -46,23 +46,30 @@ func add_new_item_by_id(item_id : String) -> void: item_id = item_id.rsplit("i/", false)[0] if not items_ids_in_inventory.has(item_id): if not escoria.object_manager.has(item_id): - escoria.logger.report_errors( - "inventory_ui.gd:add_new_item_by_id()", - [ - "Item global id '%s' does not exist." % item_id, - "Check item's id in ESCORIA_ALL_ITEMS scene." - ] - ) - if not all_items.get_inventory_item(item_id): - escoria.logger.report_errors( - "inventory_ui.gd:add_new_item_by_id()", - [ - "Item global id '%s' doesn't have a " +\ - "corresponding inventory item." % item_id, - "Check item's id in ESCORIA_ALL_ITEMS scene." - ] - ) - var item_inventory_button = all_items.get_inventory_item(item_id).duplicate() + var inventory_file = "%s/%s.tscn" % [ + ProjectSettings.get_setting( + "escoria/ui/items_autoregister_path" + ).trim_suffix("/"), + item_id + ] + if ResourceLoader.exists(inventory_file): + escoria.object_manager.register_object( + ESCObject.new( + item_id, + ResourceLoader.load(inventory_file).instance() + ) + ) + else: + escoria.logger.report_errors( + "inventory_ui.gd:add_new_item_by_id()", + [ + "Item global id '%s' does not exist." % item_id, + "Check item's id in ESCORIA_ALL_ITEMS scene." + ] + ) + var item_inventory_button = ( + escoria.object_manager.get_object(item_id).node as ESCItem + ).inventory_item.duplicate() items_ids_in_inventory[item_id] = item_inventory_button get_node(inventory_ui_container).add_item(item_inventory_button) diff --git a/addons/escoria-core/template_scenes/inventory_item.tscn b/addons/escoria-core/template_scenes/inventory_item.tscn index a3005708..bec085b6 100644 --- a/addons/escoria-core/template_scenes/inventory_item.tscn +++ b/addons/escoria-core/template_scenes/inventory_item.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escinventoryitem.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_inventory_item.gd" type="Script" id=1] [ext_resource path="res://addons/escoria-core/game/assets/images/no_image.png" type="Texture" id=2] [node name="inventory_item" type="TextureButton"] diff --git a/addons/escoria-core/template_scenes/items_inventory.tscn b/addons/escoria-core/template_scenes/items_inventory.tscn deleted file mode 100644 index f4c2c108..00000000 --- a/addons/escoria-core/template_scenes/items_inventory.tscn +++ /dev/null @@ -1,10 +0,0 @@ -[gd_scene load_steps=2 format=2] - -[ext_resource path="res://addons/escoria-core/game/core-scripts/items_inventory.gd" type="Script" id=1] - -[node name="items_inventory" type="GridContainer"] -columns = 5 -script = ExtResource( 1 ) -__meta__ = { -"_edit_use_anchors_": false -} diff --git a/addons/escoria-core/template_scenes/room.tscn b/addons/escoria-core/template_scenes/room.tscn index 21b7f934..23731d66 100644 --- a/addons/escoria-core/template_scenes/room.tscn +++ b/addons/escoria-core/template_scenes/room.tscn @@ -1,9 +1,9 @@ [gd_scene load_steps=6 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escterrain.gd" type="Script" id=1] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escbackground.gd" type="Script" id=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escitem.gd" type="Script" id=3] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escroom.gd" type="Script" id=4] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_terrain.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_background.gd" type="Script" id=2] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=3] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_room.gd" type="Script" id=4] [sub_resource type="NavigationPolygon" id=1] diff --git a/addons/escoria-core/testing/player_angles_finder.gd b/addons/escoria-core/testing/player_angles_finder.gd index 26959d77..678fae87 100644 --- a/addons/escoria-core/testing/player_angles_finder.gd +++ b/addons/escoria-core/testing/player_angles_finder.gd @@ -107,7 +107,7 @@ var result_angles = [] func _ready(): # Find player animations $player_animations.add_item("") - for anim_name in $player.get_animations_list(): + for anim_name in $player.get_animation_player.get_sprite_frames().get_animation_names(): $player_animations.add_item(anim_name) # Set initial angles diff --git a/docs/api/Movable.md b/docs/api/Movable.md new file mode 100644 index 00000000..4edf5594 --- /dev/null +++ b/docs/api/Movable.md @@ -0,0 +1,205 @@ + + +# Movable + +**Extends:** [Node](../Node) + +## Description + +Node that performs the moving (walk, teleport, terrain scaling...) actions on +its parent node. + +## Property Descriptions + +### walk\_path + +```gdscript +var walk_path: Array +``` + +Character path through the scene as calculated by the Pathfinder + +### path\_ofs + +```gdscript +var path_ofs: int +``` + +Current active walk path entry + +### walk\_destination + +```gdscript +var walk_destination: Vector2 +``` + +The destination where the character should be moving to + +### walk\_context + +```gdscript +var walk_context: Dictionary +``` + +A dictionary with context information about the walk command +fast => Wether to walk fast or slow +target => Walk target + +### moved + +```gdscript +var moved: bool +``` + +Wether the character was moved at all + +### last\_deg + +```gdscript +var last_deg: int +``` + +Angle degrees to the last position (TODO is that correct?) + +### last\_dir + +```gdscript +var last_dir: int +``` + +Direction of the last position (TODO is that correct?) + +### last\_scale + +```gdscript +var last_scale: Vector2 +``` + +Scale of the last position (TODO is that correct?) + +### pose\_scale + +```gdscript +var pose_scale: int +``` + +TODO Isn't this actually the flip state of the current animation? + +### parent + +```gdscript +var parent +``` + +Shortcut variable that references the node's parent + +### bypass\_missing\_animation + +```gdscript +var bypass_missing_animation +``` + + If character misses an animation, bypass it and proceed. + +## Method Descriptions + +### teleport + +```gdscript +func teleport(target, angle: Object = null) -> void +``` + +Teleports this item to the target position. +TODO angle is only used for logging and has no further use, so it probably +can be removed + +#### Parameters + +- target: Vector2, Position2d or ESCItem + +### walk\_to + +```gdscript +func walk_to(pos: Vector2, p_walk_context = null) -> void +``` + +Walk to a given position + +#### Parameters + +- pos: Position to walk to +- p_walk_context: Walk context to use + +### walk + +```gdscript +func walk(target_pos, p_speed, context = null) -> void +``` + +FIXME this function doesn't seem to be used anywhere + +### walk\_stop + +```gdscript +func walk_stop(pos: Vector2) -> var +``` + +We have finished walking. Set the idle pose and complete + +#### Parameters + +- pos: Final target position + +### update\_terrain + +```gdscript +func update_terrain(on_event_finished_name = null) -> void +``` + +Update the sprite scale and lighting + +#### Parameters + +- on_event_finished_name: Used if this function is called from an ESC event + +### is\_angle\_in\_interval + +```gdscript +func is_angle_in_interval(angle: float, interval: Array) -> bool +``` + +Returns true if given angle is inside the interval given by a starting_angle +and the size. +TODO Refactor to make this stuff understandable :D + +#### Parameters + +- angle: Angle to test +- interval : Array of size 2, containing the starting angle, and the size of + interval + eg: [90, 40] corresponds to angle between 90° and 130° + +### set\_angle + +```gdscript +func set_angle(deg: int, immediate = true) -> void +``` + +Sets character's angle and plays according animation. + +TODO: depending on current angle and current angle, the character may +directly turn around with no "progression". We may enhance this by +calculating successive directions to turn the character to, so that he +doesn't switch to opposite direction too fast. +For example, if character looks WEST and set_angle(EAST) is called, we may +want the character to first turn SOUTHWEST, then SOUTH, then SOUTHEAST and +finally EAST, all more or less fast. +Whatever the implementation, this should be activated using "parameter +"immediate" set to false. + +#### Parameters + +- deg int angle to set the character +- immediate bool (currently unused, see TODO below) + If true, direction is switched immediately. Else, successive animations are + used so that the character turns to target angle. \ No newline at end of file diff --git a/docs/api/esc_compiler.gd.md b/docs/api/esc_compiler.gd.md new file mode 100644 index 00000000..34f40178 --- /dev/null +++ b/docs/api/esc_compiler.gd.md @@ -0,0 +1,275 @@ + + +# esc\_compiler.gd + +**Extends:** [Node](../Node) + +## Description + +ESC compiler + +The workflow is like this: +Lines beginning with ":" such as :push, :say are EVENTS. +Lines in between are usually the ESC API functions calls. They are called COMMANDS. + +Steps +* compile_script(path/to/esc) : called once + * compile(path/to/esc, errors) : called once + * read_events() : called once\ + create an ESCState, initialized with 1st line\ + for each line in ESCState that corresponds to an event (:event), create a new level + * add_level(state, level, errors)\ + for each state.line that belongs to same group (same indentation), create a command + * read_cmd(state, level, errors)\ + get the token in state.line : this is the actual command (say, teleport, etc.)\ + get the parameters next to the token\ + create an ESCCommand, check it and push it into level array\ + * create an ESCEvent with the level created\ + * add it to the returned Dictionary of events + +In the end, the ESCState has read all lines in the file and is deleted + +Returned value is a Dictionary { event name : ESCEvent} + +And ESCEvent.level is an array of ESCCommand + +## Constants Descriptions + +### COMMANDS + +```gdscript +const COMMANDS: Dictionary = {"!":{"alias":"end_dialog","min_args":0},"%":{"alias":"label","min_args":1},">":{"alias":"branch"},"?":{"alias":"dialog"},"accept_input":{"min_args":1,"types":[4]},"anim":{"min_args":2,"types":[4,4,1,1,1]},"autosave":{"min_args":0},"camera_push":{"min_args":1,"types":[4]},"camera_set_drag_margin_enabled":{"min_args":2,"types":[1,1]},"camera_set_limits":{"min_args":1,"types":[2]},"camera_set_pos":{"min_args":3,"types":[3,2,2]},"camera_set_target":{"min_args":1,"types":[3]},"camera_set_zoom":{"min_args":1,"types":[3]},"camera_set_zoom_height":{"min_args":1,"types":[2]},"camera_shift":{"min_args":2,"types":[2,2]},"change_scene":{"min_args":1,"types":[4,1]},"custom":{"min_args":2,"types":[4,4]},"cut_scene":{"min_args":2,"types":[4,4,1,1,1]},"debug":{"min_args":1},"dec_global":{"min_args":2,"types":[4,2]},"enable_terrain":{"min_args":1,"types":[4]},"game_over":{"min_args":1,"types":[1]},"inc_global":{"min_args":2,"types":[4,2]},"inventory_add":{"min_args":1},"inventory_display":{"min_args":1,"types":[1]},"inventory_remove":{"min_args":1},"jump":{"min_args":1},"label":{"min_args":1},"queue_animation":{"min_args":2,"types":[4,4,1]},"queue_resource":{"min_args":1,"types":[4,1]},"repeat":true,"say":{"min_args":2},"sched_event":{"min_args":3,"types":[3,4,4]},"set_active":{"min_args":2,"types":[4,1]},"set_angle":{"min_args":2,"types":[4,2]},"set_global":{"min_args":2,"types":[4,4]},"set_globals":{"min_args":2,"types":[4,1]},"set_hud_visible":{"min_args":1,"types":[1]},"set_interactive":{"min_args":2,"types":[4,1]},"set_sound_state":{"min_args":2,"types":[4,4,1]},"set_speed":{"min_args":2,"types":[4,2]},"set_state":{"min_args":2,"types":[4,4,1]},"slide":{"min_args":2},"slide_block":{"min_args":2},"spawn":{"min_args":1},"stop":true,"superpose_scene":{"min_args":1,"types":[4,1]},"teleport":{"min_args":2,"types":[4,4,2]},"teleport_pos":{"min_args":3},"turn_to":{"min_args":2},"wait":true,"walk":{"min_args":2},"walk_block":{"min_args":2},"walk_to_pos":{"min_args":3},"walk_to_pos_block":{"min_args":3}} +``` + +A list of valid ESC commands + +### DEBUG\_COMMANDS + +```gdscript +const DEBUG_COMMANDS: Dictionary = {"get_active":{"min_args":1,"types":[4]},"get_global":{"min_args":1,"types":[4]},"get_interactive":{"min_args":1,"types":[4]},"get_state":{"min_args":1,"types":[4]}} +``` + +Commands that can be called only by the ESC debug prompt + +## Method Descriptions + +### compile\_str + +```gdscript +func compile_str(p_str: String, errors: Array) +``` + +Compile a string into a dictionary of ESC events + +#### Parameters + +- p_str: String to compile +- errors: List of errors occured during parsing +**Returns** A dictionary of ESCEvents + +### load\_esc\_file + +```gdscript +func load_esc_file(esc_file_path: String) -> Dictionary +``` + +Loads an ESC or special GDScript file and compiles it to a dictionary of +events. + +#### Parameters + +- esc_file_path: The path to the ESC file to load +**Returns** A dictionary of ESC events + +### compile\_script + +```gdscript +func compile_script(p_path: String) -> Dictionary +``` + +Compiles an ESC file into a dictionary of events. +Alternatively, a GDScript file can be specified as well. In that case, +the compiler expects a function get_events in that script that +returns a dictionary of events. + +#### Parameters + +- p_path: Path to the ESC/GDScript-file +**Returns** A dictionary of ESC events + +### compile + +```gdscript +func compile(p_fname: String, errors: Array) -> Dictionary +``` + +Compile an ESC file into a list of events + +#### Parameters + +- p_fname: Path to the ESC file +- errors: A list of errors that wil be filled by the compiler +**Returns** A dictionary of ESC events + +### read\_events + +```gdscript +func read_events(f, ret: Dictionary, errors: Array) -> void +``` + +Parse a file or a special dictionary into a dictionary of ESC events + +The dictionary is currently used as a workaround to parse ESC from text +(see read_line for specifics) + +#### Parameters + +- f: File or Dictionary to read +- ret: The parsed dictionary +- errors: A list of errors that have been found during parsing + +### add\_level + +```gdscript +func add_level(state: ESCState, level: Array, errors: Array) -> void +``` + +Add a new level of indent to the current event parsing + +#### Parameters + +- state: The state we're working on +- level: The existing levels +- errors: A list of errors during parsing + +### read\_cmd + +```gdscript +func read_cmd(state: ESCState, level: Array, errors: Array) -> void +``` + +Interpret a line in an esc event level as a command and add it to the +level commands + +#### Parameters + +- state: The state we're working on +- level: The list of level commands +- errors: A list of errors occured during parsing + +### add\_dialog + +```gdscript +func add_dialog(state: ESCState, level: Array, errors: Array) -> void +``` + +Add a dialog into the current level + +#### Parameters + +- state: State we're working on +- level: Current list of level commands +- errors: List of errors occured during parsing + +### read\_dialog\_option + +```gdscript +func read_dialog_option(state: ESCState, level: Array, errors: Array) -> void +``` + +### check\_normal\_command + +```gdscript +func check_normal_command(cmd: ESCCommand, state: ESCState, errors: Array) -> bool +``` + +### check\_debug\_command + +```gdscript +func check_debug_command(cmd: ESCCommand, state: ESCState, errors: Array) -> bool +``` + +### check\_command + +```gdscript +func check_command(commands_list: Dictionary, cmd: ESCCommand, state: ESCState, errors: Array) -> bool +``` + +### read\_line + +```gdscript +func read_line(state: ESCState) -> void +``` + +Advance to the next line in the state + +#### Parameters + +- state: State we're working on + +### is\_comment + +```gdscript +func is_comment(line: String) -> bool +``` + + Check wether line is a comment (starting with #) + +#### Parameters + +- line: Current line as string +**Returns** Wether the line is a comment or not + +### get\_indent + +```gdscript +func get_indent(line: String) -> int +``` + +Returns the position of the first non-blank character in given line string + +#### Parameters + +- line: Line to check +**Returns** Indent of the checked line + +### is\_event + +```gdscript +func is_event(line: String) +``` + +Check wether the given line is a event (begins with ":") + +#### Parameters + +- line: Line to check +**Returns** + +### is\_flags + +```gdscript +func is_flags(tk: String) -> bool +``` + +Checks wetehr the given token is a flag (ie. "[.+]") + +#### Parameters + +- tk: Token to check +**Returns** Wether the token is a flag or not + +### get\_token + +```gdscript +func get_token(line: String, p_from: int, line_count: int, errors: Array) -> int +``` + +### parse\_flags + +```gdscript +func parse_flags(p_flags: String, flags_list: Array, ifs: Dictionary) +``` + +Parses a flags string (usually defined by '[.*]') and fills the flags_list array +and ifs variable (Dictionary containing all ifs conditions) \ No newline at end of file diff --git a/docs/api/escoria.gd.md b/docs/api/escoria.gd.md new file mode 100644 index 00000000..e125c653 --- /dev/null +++ b/docs/api/escoria.gd.md @@ -0,0 +1,164 @@ + + +# escoria.gd + +**Extends:** [Node](../Node) + +## Description + +The escorie main script + +## Enumerations + +### GAME\_STATE + +```gdscript +const GAME_STATE: Dictionary = {"DEFAULT":0,"DIALOG":1,"WAIT":2} +``` + +An enum of game states +* DEFAULT - Default mode +* DIALOG - Game is running a dialog +* WAIT - Game is currently waiting for a specified time + +## Property Descriptions + +### main\_menu\_instance + +```gdscript +var main_menu_instance +``` + +The instance of the used main menu scene + +### dialog\_player + +```gdscript +var dialog_player +``` + +Dialog player instantiator. This instance is called directly for dialogs. + +### inventory + +```gdscript +var inventory +``` + +The inventory scene used + +### room\_terrain + +```gdscript +var room_terrain +``` + +The terrain of the current main room + +### esc\_compiler + +```gdscript +var esc_compiler +``` + +The ESC compiler instance + +### logger + +```gdscript +var logger +``` + +The logger instance + +### main + +```gdscript +var main +``` + +The main scene + +### esc\_runner + +```gdscript +var esc_runner +``` + +The ESC main loop + +### esc\_level\_runner + +```gdscript +var esc_level_runner +``` + +The ESC interpreter + +### inputs\_manager + +```gdscript +var inputs_manager +``` + +The escoria inputs manager + +### utils + +```gdscript +var utils +``` + +Several utilities + +### current\_state + +```gdscript +var current_state +``` + +The current state of the game + +### game\_size + +```gdscript +var game_size +``` + +The game resolution + +## Method Descriptions + +### new\_game + +```gdscript +func new_game() +``` + +Called by Main menu "start new game" + +### register\_object + +```gdscript +func register_object(object: Object) +``` + +Register an object to the matching manager. (A dialog player as the +main dialog player, an item in the ESC runner, etc.) + +#### Parameters + +- object: The object to register + +### do + +```gdscript +func do(action: String, params: Array) -> void +``` + +Run a generic action + +#### Parameters + +- action: type of the action to run +- params: Parameters for the action \ No newline at end of file diff --git a/docs/api/escoria_types.gd.md b/docs/api/escoria_types.gd.md new file mode 100644 index 00000000..ac3f429e --- /dev/null +++ b/docs/api/escoria_types.gd.md @@ -0,0 +1,144 @@ + + +# escoria\_types.gd + +**Extends:** [Node](../Node) + +## Description + +Escoria basic types + +## Enumerations + +### EVENT\_LEVEL\_STATE + +```gdscript +const EVENT_LEVEL_STATE: Dictionary = {"BREAK":2,"CALL":4,"JUMP":5,"REPEAT":3,"RETURN":0,"YIELD":1} +``` + +ESC script states +RETURN - The ESC script has been completed successfully +YIELD - ESC is waiting for Godot to finish something (e.g. Sprite animation) +BREAK - ESC has completed the current command block. Jump back +REPEAT - ESC is repeating a command block +CALL - Call another ESC command block +JUMP - Jump to another ESC label + +## Constants Descriptions + +### OBJ\_DEFAULT\_STATE + +```gdscript +const OBJ_DEFAULT_STATE: String = "default" +``` + +The default state of an object + +## Sub\-classes + +### ESCState + +#### Property Descriptions + +### file + +```gdscript +var file +``` + +File or Dictionary + +### line + +```gdscript +var line +``` + +String, can be null + +### indent + +```gdscript +var indent: int +``` + +### line\_count + +```gdscript +var line_count: int +``` + +#### Method Descriptions + +### \_init + +```gdscript +func _init(p_file, p_line, p_indent, p_line_count) +``` + +### ESCEvent + +#### Property Descriptions + +### ev\_name + +```gdscript +var ev_name: String +``` + +### ev\_level + +```gdscript +var ev_level: Array +``` + +### ev\_flags + +```gdscript +var ev_flags: Array +``` + +#### Method Descriptions + +### \_init + +```gdscript +func _init(p_name, p_level, p_flags) +``` + +### ESCCommand + +#### Property Descriptions + +### name + +```gdscript +var name: String +``` + +### params + +```gdscript +var params: Array +``` + +### conditions + +```gdscript +var conditions: Dictionary +``` + +### flags + +```gdscript +var flags: Array +``` + +#### Method Descriptions + +### \_init + +```gdscript +func _init(p_name) +``` + diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 00000000..ba555b1c --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,31 @@ +# Escoria architecture + +## The plugin script, autoload and classes + +According to the [concept of Godot plugins](https://docs.godotengine.org/en/stable/tutorials/plugins/editor/making_plugins.html), `Escoria`initializes itself in the plugin script `addons/escoria-core/editor/plugin_escoria.gd`. This script is mostly used to initialize the [Escoria configuration items](configuration.md) and initialize (and later remove) the autoloads. + +Escoria is based on an autoload scene available as [`escoria`](api/escoria.gd.md), that binds together all required objects and interfaces in a central place. An additional autoload, [`esctypes`](api/escoria_types.gd.md) defines basic escoria classes. + +In addition to this, various classes are defined in the respective class files and build up the various resources used in Escoria. + +* [Movable](api/Movable.md): A class that can be added to another node to handle movements on that node. + +## Nodes of the Escoria autoload scene + +The Escoria autoload scene holds various nodes that take vital parts of the engine. + +### Inputs Manager + +The central component in Escoria to receive, handle and deliver input events. + +### ESC Compiler + +The [ESC compiler](api/esc_compiler.gd.md) compiles files in the [ESC language](../esc.md) into a list of events that can be run by the ESC runner + +### Main + +`escoria.main` is the main scene manager used in Escoria that allows for switching scenes with transitions + +## The Godot main scene of Escoria + +The scene, that Godot loads when starting a game (the [*main scene*](https://docs.godotengine.org/en/stable/getting_started/step_by_step/exporting.html#setting-a-main-scene)) is set to `addons/escoria-core/game/main_scene.tscn` and basically instantiates the configured main menu scene and starts it. \ No newline at end of file diff --git a/docs/configuration.md b/docs/configuration.md new file mode 100644 index 00000000..15f1cc46 --- /dev/null +++ b/docs/configuration.md @@ -0,0 +1,27 @@ +# Game configuration + +Aside from the common [Godot project settings](https://docs.godotengine.org/en/stable/classes/class_projectsettings.html), Escoria includes some special settings to configuration the Escoria components. These settings can be found in the "Escoria"-section in the project settings: + +| Section | Setting | Description | +| -------- | ----------------------- | ------------------------------------------------------------ | +| Main | Game Start Script | ESC-script that will be executed when the game starts | +| | Force Quit | Allow quitting the game using the operating system's quit commands (Alt-F4 on Windows, Cmd-Q on macOS, etc.) | +| | Text Lang | Default language of texts displayed in the game | +| | Voice Lang | Default language of voices | +| Debug | Terminate On Warnings | If an Escoria warning is received, quit the game | +| | Terminate On Errors | If an Escoria error is received, quit the game | +| | Development Lang | Basic language the game is developed in. Useful for translation management | +| | Log Level | Level of log files produced. Even if this is set to DEBUG, debugging logs will not be available in production builds | +| Ui | Tooltip Follows Mouse | The tooltips for items in the scene follows the mouse cursor (used e.g. for mouse cursor icons UI) | +| | Dialogs Folder | Folder containing UI scenes related to dialogs | +| | Default Dialog Scene | The scene used for dialogs | +| | Main Menu Scene | The scene used for menus | +| | Pause Menu Scene | The scene used when the game is paused | +| | Game Scene | The game UI used | +| | Items Autoregister Path | Path that holds ESCItems that aren't registered in a scene before, but are added to the inventory for example | +| Sound | Music Volume | The volume used for music | +| | Sound Volume | The volume used for sound | +| | Speech Volume | The volume used for voices | +| | Master Volume | The master volume for all channels | +| Platform | Skip Cache | Wether to skip caching scenes. Some platforms might not have the enough amount of memory required for this (e.g. mobile platforms) and should have this setting set to true for their respective targets | + diff --git a/docs/esc.md b/docs/esc.md new file mode 100644 index 00000000..f150098f --- /dev/null +++ b/docs/esc.md @@ -0,0 +1,402 @@ +# ESC language documentation + +## Objects + +### Global IDs + +All objects in the game have a global ID, which is used to identify them in commands. The ID is configured in the object's scene. + +### States + +Each object can have a "state". The state is stored in the global state of the game, and the savegame, and it's set on the object when the scene is instanced. States can also be animations with the same name in the object's scene, in that case the animation is run when the state is set. + +### Active objects + +Objects can be active or not active. Non-active objects are hidden and non clickable. + +Item activity is also handled as a special case of global flags. If the check starts with "a/", like "a/elaine", you're checking if "elaine" is active. + +``` +:ready +> [!a/elaine] + say player player_no_elaine_yet:"It would appear Elaine hasn't arrived yet." +``` + +Caveat: This works only when `set_active` has been called. Therefore if "elaine" is not set `active` in the editor but `set_active elaine true` is +called later, everything works as expected. If you have an item that can be picked up, even if it's `active` in the editor, but its state *may* toggle, +you must use this pattern: + +``` +:setup +set_active broom true [!i/inv_broom] +``` + +Now it has been explicitly set and it will work. The underlying technical rationale is way beyond the scope of this reference; just trust us +that it's the best way to go. + +### Interactive objects + +If you have something that only blocks the terrain, something you can move behind, you probably don't want to hassle with interaction areas +and tooltip texts. In this case, just set `is_interactive` to `false` and the item will not be checked for areas and its mouse events will +not be connected. + +## Global flags + +Global flags define the state of the game, and can have a value of true, false or an integer. All commands or groups can be conditioned to the value of a global flag. + +### Inventory + +The inventory is handled as a special case of global flags. All flags with a name starting with "i/" are considered an inventory object, with the object's global id following. Example: + +``` +# adds the object "key" to the inventory +set_global i/key true +``` + +``` +# removes the object "key" to the inventory +set_global i/key false +``` + +## Game global state + +The following values are saved in the global game state and savegames: + +* Global flags +* Object's "state" values +* Object's "active" values +* Object's potisions if moved + +## Events + +When a scene is loaded, it may have events. We will not cover `:load` as it is used only internally for save games, nor will we cover `:start` here. + +To initialize a room properly, you may want to use `:setup` like this: + +``` +:setup +teleport player door1 [eq last_exit door1] +teleport player door2 [eq last_exit door2] +``` + +It covers the fact that your `player` can be set anywhere in the room and be visible for just a moment before the `teleport` happens. + +It's not mandatory, nor mutually exclusive with `:setup` to have a `:ready` event. + +``` +:ready +say player player_wants_out:"I want out! To live my life and to be free!" [want_out] +``` + +When the player interacts with an object in the game, the object receives an even. Each event executes a series of commands. + +Events start with the character ":" in the Events file. Example: + +``` +:use +``` + +Especially useful for fallbacks, you can give flags to events: + +``` +:use | TK +say player player_does_not_wanna:"I don't wanna." +``` + +These flags are implemented: + +* `TK` stands for "telekinetic". It means the player won't walk over to the item to say the line. +* `NO_TT` stands for "No tooltip". It hides the tooltip for the duration of the event. Probably not very useful, because events having multiple `say` commands in them are automatically hidden. +* `NO_HUD` stands for "No HUD". It hides the HUD for the duration of the event. Useful when you want something to look like a cut scene but not disable input for skipping dialog. +* `NO_SAVE` disables saving. Use this in cut scenes and anywhere a badly-timed autosave would leave your game in a messed-up state. +* `CUT_BLACK` applies only to `:setup`. It makes the screen go black during the setup phase. You will probably see a quick black flash, so use it only if you prefer it over the standard cut. +* `LEAVE_BLACK` applies only to `:setup`. In case your `:ready` starts with `cut_scene telon fade_in`, you must apply this flag or you will see a flash of your new scene before going black again for the `fade_in`. + +## Commands + +Commands consist of one word followed by parameters. Parameters can be one word, or strings in quotes. A string can also be preceeded by an ID for localization and the ":" character. Example: + +``` +# one parameter "player", another parameter "hello world", with id "dialog_hello" +say player dialog_hello:"hello world" +``` + +### Conditions + +In order to run a command conditionally dependin on the value of a flag, use [] with a list of conditions. All conditions in the list must be true. The character "!" before a flag can be used to negate it. + +Example: + +``` +# runs the command only if the door_open flag is true +say player "The door is open" [door_open] +``` + +``` +# runs the group only if door_open is false and i/key is true +> [!door_open,i/key] + say player "The door is close, maybe I can try this key in my inventory" +``` + +Additionally, there's a set of comparison operators for use with global integers: `eq`, `gt` and `lt`, all of which can be negated. +Example: + +``` +# runs the command only if the value of pieces_of_eight is greater than 5 +set_state inv_pieces_of_eight money_bag [gt pieces_of_eight 5] +``` + +### Groups + +Commands can be grouped using the character ">" to start a group, and incrementing the indentation of the commands that belong to the group. Example: + +``` +> + set_global door_open true + animation player pick_up +# end of group +``` + +### Blocking + +Some commands will block execution of the event until they finish, others won't. See the command's reference for details on which commands block. + +### List of commands + +#### `debug string [string2 ...]` + +Takes 1 or more strings, prints them to the console. + +#### `set_global name value` + +Changes the value of the global "name" with the value. Value can be "true", "false" or an integer. + +#### `dec_global name value` + +Subtracts the value from global with given "name". Value and global must both be integers. + +#### `inc_global name value` + +Adds the value to global with given "name". Value and global must both be integers. + +#### `set_globals pattern value` + +Changes the value of multiple globals using a wildcard pattern. Example: + +``` +# clears the inventory +set_globals i/#### false +``` + +#### `accept_input [ALL|NONE|SKIP]` + +What type of input does the game accept. `ALL` is the default, `SKIP` allows skipping of dialog but nothing else, `NONE` denies all input. Including opening the menu etc. +`SKIP` and `NONE` also disable autosaves. + +Note that `SKIP` gets reset to `ALL` when the event is done, but `NONE` persists. This allows you to create cut scenes with `SKIP` where the dialog can be skipped, but also +initiate locked#### down cutscenes with `accept_input NONE` in `:setup` and `accept_input ALL` later in `:ready`. + +#### `set_state object state` (Currently not available) + +Changes the state of an object, and executes the state animation if present. The command can be used to change the appearance of an item or a player character. + +When used on a player object, the command is used to dress the player in a costume identified by the state parameter. An `AnimationPlayer` with the given parameter should be a child of the player node, although one named "animation" is always the fallback when trying set a missing costume. + +Items can also change state by playing animations from an `AnimationPlayer` named "animation". The `AnimationPlayer` is typically used to change the texture of a `Sprite` node, but it's also possible to add additional tracks for changing the tooltip and other properties of the item scene. By using keyframes and looping, any given state can also use multiple textures to bring more life to the item. + +#### `set_hud_visible visible` (Currently not available) + +If you have a cut#### scene#### like sequence where the player doesn't have control, and you also have HUD elements visible, use this to hide the HUD. You want to do that because it explicitly signals the player that there is no control over the game at the moment. "visible" is true or false. + +#### `say object text [type] [avatar]` + +Runs the specified string as a dialog said by the object. Blocks execution until the dialog finishes playing. Optional parameters: + +* "type" determines the type of dialog UI to use. Default value is "default" +* "avatar" determines the avatar to use for the dialog. Default value is "default" + +#### `anim object name [reverse] [flip_x] [flip_y]` + +Executes the animation specificed with the "name" parameter on the object, without blocking. The next command in the event will be executed immediately after. Optional parameters: + +* reverse plays the animation in reverse when true +* flip_x flips the x axis of the object's sprites when true (object's root node needs to be Node2D) +* flip_y flips the y axis of the object's sprites when true (object's root node needs to be Node2D) + +#### `cut_scene object name [reverse] [flip_x] [flip_y]` + +Executes the animation specificed with the "name" parameter on the object, blocking. The next command in the event will be executed when the animation is finished playing. Optional parameters: + +* reverse plays the animation in reverse when true +* flip_x flips the x axis of the object's sprites when true (object's root node needs to be Node2D) +* flip_y flips the y axis of the object's sprites when true (object's root node needs to be Node2D) + +#### `play_snd object file [loop]` (Currently not available) + +Plays the sound specificed with the "file" parameter on the object, without blocking. You can play background sounds, eg. during scene changes, with `play_snd bg_snd res://...` + +#### `set_active object value` + +Changes the "active" state of the object, value can be true or false. Inactive objects are hidden in the scene. + +#### `set_interactive object value` + +Sets whether or not an action menu should be used, and a tooltip shown, on object. It must use the `item.gd` script. Value can be true or false. Useful for "soft#### disabling" objects without removing them by `set_active`. + +#### `wait seconds` + +Blocks execution of the current script for a number of seconds specified by the "seconds" parameter. + +#### `change_scene path run_events` + +Loads a new scene, specified by "path". The `run_events` variable is a boolean (default true) which you never want to set manually! It's there only to benefit save games, so they don't conflict with the scene's events. + +#### `set_speed object speed` + +Sets how fast object moves. It must use the `interactive.gd` script or something extended from it. Value is an integer. + +#### `teleport object1 object2 [angle]` + +Sets the position of object1 to the position of object2. By default object2's `interact_angle` is used to turn `object1`, but `angle` will override this. +Useful for doors and such with an `interact_angle` you don't always want to adhere to when re#### entering a room. + +#### `slide object1 object2 [speed]` + +Moves object1 towards the position of object2, at the speed determined by object1's "speed" property, unless overridden. This command is non#### blocking. It does not respect the room's navigation polygons, so you can move items where the player can't walk. + +#### `slide_block object1 object2 [speed]` + +Moves object1 towards the position of object2, at the speed determined by object1's "speed" propert, unless overriddeny. This command is blocking. It does not respect the room's navigation polygons, so you can move items where the player can't walk. + +#### `walk object1 object2 [speed]` + +Walks, using the walk animation, object1 towards the position of object2, at the speed determined by object1's "speed" property, unless overridden. This command is non#### blocking. + +#### `walk_block object1 object2 [speed]` + +Walks, using the walk animation, object1 towards the position of object2, at the speed determined by object1's "speed" property, unless overridden. This command is blocking. + +#### `turn_to object degrees` + +Turns `object` to a `degrees` angle with a `directions` animation. + +0 sets `object` facing forward, 90 sets it 90 degrees clockwise ("east") etc. When turning to the destination angle, animations are played if they're defined in `animations`. +`object` must be player or interactive. +`degrees` must be between [0, 360] or an error is reported. + +#### `set_angle object degrees` + +Turns `object` to a `degrees` angle without animations. +0 sets `object` facing forward, 90 sets it 90 degrees clockwise ("east") etc. When turning to the destination angle, animations are played if they're defined in `animations`. + +`object` must be player or interactive. +`degrees` must be between [0, 360] or an error is reported. + +#### `spawn path [object2]` + +Instances a scene determined by "path", and places in the position of object2 (object2 is optional) + +#### `stop` + +Stops the event's execution. + +#### `repeat` + +Restarts the execution of the current scope at the start. A scope can be a group or an event. + +#### `sched_event time object event` + +Schedules the execution of an "event" found in "object" in a time in seconds. If another event is running at the time, execution starts when the running event ends. +`event` can consist of multiple words like in `sched_event 0 tow_hook use inv_rope` + +#### `custom obj func_name [params]` + +If `obj` has a `(Node2D) custom` node, `func_name` will be searched for in its script and called with `params`. See device/contrib/custom/spine.gd for an example. + +#### `camera_set_pos speed x y` + +Moves the camera to a position defined by "x" and "y", at the speed defined by "speed" in pixels per second. If speed is 0, camera is teleported to the position. + +#### `camera_set_target speed object [object2 object3 ...]` + +Configures the camera to follow 1 or more objects, using "speed" as speed limit. This is the default behavior (default follow object is "player"). If there's more than 1 object, the camera follows the average position of all the objects specified. + +#### `camera_set_zoom magnitude [time]`yx + +Zooms the camera in/out to the desired magnitude. Values larger than 1 zooms the camera out, and smaller values zooms in, relative to the default value of 1. An optional time in seconds controls how long it takes for the camera to zoom into position. + +#### `camera_set_zoom_height pixels [time]` + +Similar to the command above, but uses pixel height instead of magnitude to zoom. + +#### `camera_push target [time] [type]` + +Push camera to target. Target must have `camera_pos` set. If it's of type `Camera2D`, its zoom will be used as well as position. +`type` is any of the `Tween.TransitionType` values without the prefix, eg. `LINEAR`, `QUART` or `CIRC`; defaults to `QUART`. +A `time` value of 0 will set the camera immediately. + +#### `camera_shift x y [time] [type]` + +Shift camera by `x` and `y` pixels over `time` seconds. +`type` is any of the `Tween.TransitionType` values without the prefix, eg. `LINEAR`, `QUART` or `CIRC`; defaults to `QUART`. + +#### `queue_resource path front_of_queue` + +Queues the load of a resource in a background thread. The path must be a full path inside your game, for example "res://scenes/next_scene.tscn". The "front_of_queue" parameter is optional (default value false), to put the resource in the front of the queue. Queued resources are cleared when a change scene happens (but after the scene is loaded, meaning you can queue resources that belong to the next scene). + +#### `queue_animation object animation` + +Similar to queue_resource, queues the resources necessary to have an animation loaded on an item. The resource paths are taken from the item placeholders. + +#### `game_over continue_enabled show_credits` + +Ends the game. Use the "continue_enabled" parameter to enable or disable the continue button in the main menu afterwards. The "show_credits" parameter loads the `ui/end_credits` scene if true. You can configure it to your regular credits scene if you want. + +## Dialogs + +To start a dialog, use the "?" character, with some parameters, followed by a list of dialog options. This hides the HUD. Each option starts with the "-" character, followed by a parameter with the text to display in the dialog interface. Inside the option, a group of commands is specified using indentation. Use "!" to signify the dialog is over and the HUD may be restored. The HUD will not be restored if the running event is flagged NO_HUD. Either way the Escoria virtual machine will know if the game is in a dialog context. + +Example: + +``` +# character's "talk" event +:talk +? type avatar timeout timeout_option + - "I'd like to buy a map." [!player_has_map] + say player "I'd like to buy a map" + say map_vendor "Do you know the secret code?" + ? + - "Uncle Sven sends regards." + say player "Uncle Sven sends regards." + + > [player_has_money] + say map_vendor "Here you go." + say player "Thanks!" + inventory_add map + set_global player_has_map true + stop + + > [!player_has_money] + say map_vendor "You can't afford it" + say player "I'll be back" + ! + stop + + - "Nevermind" + say player "Nevermind" + ! + stop + - "Nevermind" + say player "Nevermind" + ! + stop +repeat +``` + +All parameters are options: + +* type: (default value "default") the type of dialog menu to use. All types are in the "dd_player" scene. +* avatar: (default value "default") the avatar to use in the dialog ui. +* timeout: (default value 0) timeout to select an option. After the time has passed, the "timeout_option" will be selected automatically. If the value is 0, there's no timeout. +* timeout_option: (default value 0) option selected when timeout is reached. + diff --git a/game/characters/mark/mark.tscn b/game/characters/mark/mark.tscn index ea385604..1cf775d8 100644 --- a/game/characters/mark/mark.tscn +++ b/game/characters/mark/mark.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=40 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escplayer.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_player.gd" type="Script" id=1] [ext_resource path="res://game/characters/mark/png/mark_talk_down.png" type="Texture" id=2] [ext_resource path="res://game/characters/mark/mark_anims.gd" type="Script" id=3] [ext_resource path="res://game/characters/mark/png/mark.png" type="Texture" id=4] @@ -10,200 +10,200 @@ [sub_resource type="AtlasTexture" id=1] atlas = ExtResource( 4 ) -region = Rect2( 336, 0, 24, 70 ) +region = Rect2( 48, 0, 24, 70 ) [sub_resource type="AtlasTexture" id=2] -atlas = ExtResource( 4 ) -region = Rect2( 360, 0, 24, 70 ) +atlas = ExtResource( 5 ) +region = Rect2( 0, 0, 24, 70 ) [sub_resource type="AtlasTexture" id=3] -atlas = ExtResource( 4 ) -region = Rect2( 384, 0, 24, 70 ) +atlas = ExtResource( 5 ) +region = Rect2( 24, 0, 24, 70 ) [sub_resource type="AtlasTexture" id=4] -atlas = ExtResource( 4 ) -region = Rect2( 120, 0, 24, 70 ) +atlas = ExtResource( 5 ) +region = Rect2( 48, 0, 24, 70 ) [sub_resource type="AtlasTexture" id=5] -atlas = ExtResource( 5 ) -region = Rect2( 0, 0, 24, 70 ) +atlas = ExtResource( 4 ) +region = Rect2( 96, 0, 24, 70 ) [sub_resource type="AtlasTexture" id=6] -atlas = ExtResource( 5 ) -region = Rect2( 24, 0, 24, 70 ) - -[sub_resource type="AtlasTexture" id=7] -atlas = ExtResource( 5 ) -region = Rect2( 48, 0, 24, 70 ) - -[sub_resource type="AtlasTexture" id=8] -atlas = ExtResource( 7 ) -region = Rect2( 0, 0, 24, 70 ) - -[sub_resource type="AtlasTexture" id=9] -atlas = ExtResource( 7 ) -region = Rect2( 24, 0, 24, 70 ) - -[sub_resource type="AtlasTexture" id=10] -atlas = ExtResource( 7 ) -region = Rect2( 48, 0, 24, 70 ) - -[sub_resource type="AtlasTexture" id=11] -atlas = ExtResource( 7 ) +atlas = ExtResource( 4 ) region = Rect2( 72, 0, 24, 70 ) -[sub_resource type="AtlasTexture" id=12] -atlas = ExtResource( 7 ) -region = Rect2( 96, 0, 24, 70 ) - -[sub_resource type="AtlasTexture" id=13] -atlas = ExtResource( 4 ) -region = Rect2( 0, 0, 24, 70 ) - -[sub_resource type="AtlasTexture" id=14] -atlas = ExtResource( 4 ) -region = Rect2( 144, 0, 24, 70 ) - -[sub_resource type="AtlasTexture" id=15] -atlas = ExtResource( 4 ) -region = Rect2( 168, 0, 24, 70 ) - -[sub_resource type="AtlasTexture" id=16] -atlas = ExtResource( 4 ) -region = Rect2( 192, 0, 24, 70 ) - -[sub_resource type="AtlasTexture" id=17] -atlas = ExtResource( 6 ) -region = Rect2( 0, 0, 24, 70 ) - -[sub_resource type="AtlasTexture" id=18] -atlas = ExtResource( 6 ) -region = Rect2( 24, 0, 24, 70 ) - -[sub_resource type="AtlasTexture" id=19] -atlas = ExtResource( 4 ) -region = Rect2( 48, 0, 24, 70 ) - -[sub_resource type="AtlasTexture" id=20] -atlas = ExtResource( 4 ) -region = Rect2( 96, 0, 24, 70 ) - -[sub_resource type="AtlasTexture" id=21] -atlas = ExtResource( 2 ) -region = Rect2( 0, 0, 24, 70 ) - -[sub_resource type="AtlasTexture" id=22] -atlas = ExtResource( 2 ) -region = Rect2( 24, 0, 24, 70 ) - -[sub_resource type="AtlasTexture" id=23] -atlas = ExtResource( 2 ) -region = Rect2( 48, 0, 24, 70 ) - -[sub_resource type="AtlasTexture" id=24] +[sub_resource type="AtlasTexture" id=7] atlas = ExtResource( 4 ) region = Rect2( 216, 0, 24, 70 ) -[sub_resource type="AtlasTexture" id=25] +[sub_resource type="AtlasTexture" id=8] atlas = ExtResource( 4 ) region = Rect2( 240, 0, 24, 70 ) -[sub_resource type="AtlasTexture" id=26] +[sub_resource type="AtlasTexture" id=9] atlas = ExtResource( 4 ) region = Rect2( 264, 0, 24, 70 ) -[sub_resource type="AtlasTexture" id=27] +[sub_resource type="AtlasTexture" id=10] atlas = ExtResource( 4 ) region = Rect2( 288, 0, 24, 70 ) -[sub_resource type="AtlasTexture" id=28] +[sub_resource type="AtlasTexture" id=11] atlas = ExtResource( 4 ) region = Rect2( 312, 0, 24, 70 ) -[sub_resource type="AtlasTexture" id=29] +[sub_resource type="AtlasTexture" id=12] +atlas = ExtResource( 7 ) +region = Rect2( 0, 0, 24, 70 ) + +[sub_resource type="AtlasTexture" id=13] +atlas = ExtResource( 7 ) +region = Rect2( 24, 0, 24, 70 ) + +[sub_resource type="AtlasTexture" id=14] +atlas = ExtResource( 7 ) +region = Rect2( 48, 0, 24, 70 ) + +[sub_resource type="AtlasTexture" id=15] +atlas = ExtResource( 7 ) +region = Rect2( 72, 0, 24, 70 ) + +[sub_resource type="AtlasTexture" id=16] +atlas = ExtResource( 7 ) +region = Rect2( 96, 0, 24, 70 ) + +[sub_resource type="AtlasTexture" id=17] +atlas = ExtResource( 4 ) +region = Rect2( 0, 0, 24, 70 ) + +[sub_resource type="AtlasTexture" id=18] +atlas = ExtResource( 4 ) +region = Rect2( 120, 0, 24, 70 ) + +[sub_resource type="AtlasTexture" id=19] +atlas = ExtResource( 4 ) +region = Rect2( 144, 0, 24, 70 ) + +[sub_resource type="AtlasTexture" id=20] +atlas = ExtResource( 4 ) +region = Rect2( 168, 0, 24, 70 ) + +[sub_resource type="AtlasTexture" id=21] +atlas = ExtResource( 4 ) +region = Rect2( 192, 0, 24, 70 ) + +[sub_resource type="AtlasTexture" id=22] +atlas = ExtResource( 2 ) +region = Rect2( 0, 0, 24, 70 ) + +[sub_resource type="AtlasTexture" id=23] +atlas = ExtResource( 2 ) +region = Rect2( 24, 0, 24, 70 ) + +[sub_resource type="AtlasTexture" id=24] +atlas = ExtResource( 2 ) +region = Rect2( 48, 0, 24, 70 ) + +[sub_resource type="AtlasTexture" id=25] +atlas = ExtResource( 6 ) +region = Rect2( 0, 0, 24, 70 ) + +[sub_resource type="AtlasTexture" id=26] +atlas = ExtResource( 6 ) +region = Rect2( 24, 0, 24, 70 ) + +[sub_resource type="AtlasTexture" id=27] atlas = ExtResource( 4 ) region = Rect2( 24, 0, 24, 70 ) +[sub_resource type="AtlasTexture" id=28] +atlas = ExtResource( 4 ) +region = Rect2( 336, 0, 24, 70 ) + +[sub_resource type="AtlasTexture" id=29] +atlas = ExtResource( 4 ) +region = Rect2( 360, 0, 24, 70 ) + [sub_resource type="AtlasTexture" id=30] atlas = ExtResource( 4 ) -region = Rect2( 72, 0, 24, 70 ) +region = Rect2( 384, 0, 24, 70 ) [sub_resource type="SpriteFrames" id=31] animations = [ { -"frames": [ SubResource( 1 ), SubResource( 2 ), SubResource( 3 ), SubResource( 2 ) ], -"loop": true, -"name": "walk_up", -"speed": 6.0 -}, { -"frames": [ SubResource( 4 ) ], -"loop": true, -"name": "idle_down_left", -"speed": 5.0 -}, { -"frames": [ SubResource( 5 ), SubResource( 6 ), SubResource( 7 ) ], -"loop": true, -"name": "speak_down_right", -"speed": 6.0 -}, { -"frames": [ SubResource( 8 ), SubResource( 9 ), SubResource( 10 ), SubResource( 11 ), SubResource( 12 ) ], -"loop": true, -"name": "speak_right", -"speed": 5.0 -}, { -"frames": [ SubResource( 13 ) ], -"loop": true, -"name": "idle_down", -"speed": 5.0 -}, { -"frames": [ SubResource( 14 ), SubResource( 15 ), SubResource( 16 ), SubResource( 15 ) ], -"loop": true, -"name": "walk_down", -"speed": 6.0 -}, { -"frames": [ SubResource( 17 ), SubResource( 18 ), SubResource( 17 ), SubResource( 18 ), SubResource( 18 ) ], -"loop": true, -"name": "speak_up", -"speed": 3.0 -}, { -"frames": [ SubResource( 19 ) ], +"frames": [ SubResource( 1 ) ], "loop": true, "name": "idle_right", "speed": 5.0 }, { -"frames": [ SubResource( 20 ) ], +"frames": [ SubResource( 2 ), SubResource( 3 ), SubResource( 4 ) ], +"loop": true, +"name": "speak_down_right", +"speed": 6.0 +}, { +"frames": [ SubResource( 5 ) ], "loop": true, "name": "idle_left", "speed": 5.0 }, { -"frames": [ SubResource( 21 ), SubResource( 22 ), SubResource( 23 ), SubResource( 22 ), SubResource( 23 ) ], +"frames": [ SubResource( 6 ) ], "loop": true, -"name": "speak_down", -"speed": 6.0 +"name": "idle_up", +"speed": 5.0 }, { -"frames": [ SubResource( 24 ), SubResource( 25 ), SubResource( 26 ), SubResource( 27 ), SubResource( 28 ) ], +"frames": [ SubResource( 7 ), SubResource( 8 ), SubResource( 9 ), SubResource( 10 ), SubResource( 11 ) ], "loop": true, "name": "walk_right", "speed": 6.0 }, { -"frames": [ SubResource( 29 ) ], +"frames": [ SubResource( 12 ), SubResource( 13 ), SubResource( 14 ), SubResource( 15 ), SubResource( 16 ) ], +"loop": true, +"name": "speak_right", +"speed": 5.0 +}, { +"frames": [ SubResource( 17 ) ], +"loop": true, +"name": "idle_down", +"speed": 5.0 +}, { +"frames": [ SubResource( 18 ) ], +"loop": true, +"name": "idle_down_left", +"speed": 5.0 +}, { +"frames": [ SubResource( 19 ), SubResource( 20 ), SubResource( 21 ), SubResource( 20 ) ], +"loop": true, +"name": "walk_down", +"speed": 6.0 +}, { +"frames": [ SubResource( 22 ), SubResource( 23 ), SubResource( 24 ), SubResource( 23 ), SubResource( 24 ) ], +"loop": true, +"name": "speak_down", +"speed": 6.0 +}, { +"frames": [ SubResource( 25 ), SubResource( 26 ), SubResource( 25 ), SubResource( 26 ), SubResource( 26 ) ], +"loop": true, +"name": "speak_up", +"speed": 3.0 +}, { +"frames": [ SubResource( 27 ) ], "loop": true, "name": "idle_down_right", "speed": 5.0 }, { -"frames": [ SubResource( 30 ) ], +"frames": [ SubResource( 28 ), SubResource( 29 ), SubResource( 30 ), SubResource( 29 ) ], "loop": true, -"name": "idle_up", -"speed": 5.0 +"name": "walk_up", +"speed": 6.0 } ] [sub_resource type="CapsuleShape2D" id=32] height = 0.0 -[node name="mark" type="KinematicBody2D"] +[node name="mark" type="Area2D"] script = ExtResource( 1 ) global_id = "player" -animations = ExtResource( 3 ) dialog_color = Color( 1, 1, 1, 1 ) +animations = ExtResource( 3 ) [node name="sprite" type="AnimatedSprite" parent="."] position = Vector2( 0, -140.938 ) diff --git a/game/characters/worker/worker.tscn b/game/characters/worker/worker.tscn index c8519e10..0619b7dc 100644 --- a/game/characters/worker/worker.tscn +++ b/game/characters/worker/worker.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=7 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escitem.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=1] [ext_resource path="res://game/characters/worker/worker_anims.gd" type="Script" id=2] [ext_resource path="res://game/characters/worker/png/worker.png" type="Texture" id=4] diff --git a/game/items/ESCORIA_ALL_ITEMS.tscn b/game/items/ESCORIA_ALL_ITEMS.tscn deleted file mode 100644 index d2e14d4d..00000000 --- a/game/items/ESCORIA_ALL_ITEMS.tscn +++ /dev/null @@ -1,43 +0,0 @@ -[gd_scene load_steps=7 format=2] - -[ext_resource path="res://game/items/escitems/empty_sheet_escitem.tscn" type="PackedScene" id=1] -[ext_resource path="res://game/items/escitems/pen_escitem.tscn" type="PackedScene" id=2] -[ext_resource path="res://game/items/escitems/wrench_escitem.tscn" type="PackedScene" id=3] -[ext_resource path="res://game/items/escitems/filled_sheet_escitem.tscn" type="PackedScene" id=4] -[ext_resource path="res://addons/escoria-core/game/core-scripts/items_inventory.gd" type="Script" id=5] -[ext_resource path="res://game/items/escitems/bottle_escitem.tscn" type="PackedScene" id=6] - -[node name="ESCORIA_ALL_ITEMS" type="Node2D"] -visible = false -script = ExtResource( 5 ) - -[node name="empty_sheet" parent="." instance=ExtResource( 1 )] -dialog_color = Color( 1, 1, 1, 1 ) -interact_positions = { -"default": Vector2( 0, 0 ) -} - -[node name="filled_sheet" parent="." instance=ExtResource( 4 )] -position = Vector2( -29.7823, 133.569 ) -interact_positions = { -"default": Vector2( -29.7823, 133.569 ) -} - -[node name="pen" parent="." instance=ExtResource( 2 )] -position = Vector2( 136.277, 13.5374 ) -dialog_color = Color( 1, 1, 1, 1 ) -interact_positions = { -"default": Vector2( 136.277, 13.5374 ) -} - -[node name="wrench" parent="." instance=ExtResource( 3 )] -position = Vector2( 293.311, 2.70747 ) -interact_positions = { -"default": Vector2( 293.311, 2.70747 ) -} - -[node name="bottle" parent="." instance=ExtResource( 6 )] -position = Vector2( 59.4604, 167.678 ) -interact_positions = { -"default": Vector2( 59.4604, 167.678 ) -} diff --git a/game/items/escitems/button.tscn b/game/items/escitems/button.tscn index 52148894..67afb1fb 100644 --- a/game/items/escitems/button.tscn +++ b/game/items/escitems/button.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=10 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escitem.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=1] [ext_resource path="res://game/rooms/room3/smoke.png" type="Texture" id=2] [sub_resource type="Gradient" id=1] diff --git a/game/items/escitems/empty_sheet_escitem.tscn b/game/items/escitems/r5_empty_sheet.tscn similarity index 69% rename from game/items/escitems/empty_sheet_escitem.tscn rename to game/items/escitems/r5_empty_sheet.tscn index 6a3b98b7..81128810 100644 --- a/game/items/escitems/empty_sheet_escitem.tscn +++ b/game/items/escitems/r5_empty_sheet.tscn @@ -1,27 +1,26 @@ [gd_scene load_steps=5 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escitem.gd" type="Script" id=1] -[ext_resource path="res://game/rooms/room5/items/empty_sheet.png" type="Texture" id=2] -[ext_resource path="res://game/items/inventory/empty_sheet_escinventoryitem.tscn" type="PackedScene" id=3] +[ext_resource path="res://game/items/inventory/empty_sheet.tscn" type="PackedScene" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=2] +[ext_resource path="res://game/rooms/room5/items/empty_sheet.png" type="Texture" id=3] [sub_resource type="RectangleShape2D" id=1] extents = Vector2( 86.9568, 115.211 ) [node name="empty_sheet" type="Area2D"] -script = ExtResource( 1 ) +script = ExtResource( 2 ) global_id = "r5_empty_sheet" esc_script = "res://game/items/escitems/empty_sheet.esc" tooltip_name = "Empty sheet" default_action = "look" +default_action_inventory = "look" combine_if_action_used_among = PoolStringArray( "use", "give" ) use_from_inventory_only = true -inventory_item_scene_file = ExtResource( 3 ) -interact_positions = { -"default": null -} +inventory_item_scene_file = ExtResource( 1 ) +dialog_color = Color( 1, 1, 1, 1 ) [node name="sprite" type="Sprite" parent="."] -texture = ExtResource( 2 ) +texture = ExtResource( 3 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="."] rotation = 0.0218604 diff --git a/game/items/escitems/filled_sheet_escitem.tscn b/game/items/escitems/r5_filled_sheet.tscn similarity index 77% rename from game/items/escitems/filled_sheet_escitem.tscn rename to game/items/escitems/r5_filled_sheet.tscn index cbca5f6d..a67fd85c 100644 --- a/game/items/escitems/filled_sheet_escitem.tscn +++ b/game/items/escitems/r5_filled_sheet.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=4 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escitem.gd" type="Script" id=1] -[ext_resource path="res://game/items/inventory/filled_sheet_escinventoryitem.tscn" type="PackedScene" id=2] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=1] +[ext_resource path="res://game/items/inventory/filled_sheet.tscn" type="PackedScene" id=2] [sub_resource type="RectangleShape2D" id=1] @@ -15,9 +15,6 @@ combine_is_one_way = true use_from_inventory_only = true inventory_item_scene_file = ExtResource( 2 ) dialog_color = Color( 1, 1, 1, 1 ) -interact_positions = { -"default": Vector2( 0, 0 ) -} [node name="sprite" type="Sprite" parent="."] diff --git a/game/items/escitems/pen_escitem.tscn b/game/items/escitems/r5_pen.tscn similarity index 69% rename from game/items/escitems/pen_escitem.tscn rename to game/items/escitems/r5_pen.tscn index ea460390..509cda52 100644 --- a/game/items/escitems/pen_escitem.tscn +++ b/game/items/escitems/r5_pen.tscn @@ -1,28 +1,26 @@ [gd_scene load_steps=5 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escitem.gd" type="Script" id=1] -[ext_resource path="res://game/rooms/room5/items/pen.png" type="Texture" id=2] -[ext_resource path="res://game/items/inventory/pen_escinventoryitem.tscn" type="PackedScene" id=3] +[ext_resource path="res://game/rooms/room5/items/pen.png" type="Texture" id=1] +[ext_resource path="res://game/items/inventory/pen.tscn" type="PackedScene" id=2] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=3] [sub_resource type="RectangleShape2D" id=1] extents = Vector2( 51.8881, 43.8187 ) [node name="pen" type="Area2D"] -script = ExtResource( 1 ) +script = ExtResource( 3 ) global_id = "r5_pen" esc_script = "res://game/items/escitems/pen.esc" tooltip_name = "Pen" default_action = "look" +default_action_inventory = "look" combine_if_action_used_among = PoolStringArray( "use", "give" ) use_from_inventory_only = true -inventory_item_scene_file = ExtResource( 3 ) +inventory_item_scene_file = ExtResource( 2 ) dialog_color = Color( 1, 1, 1, 1 ) -interact_positions = { -"default": Vector2( 0, 0 ) -} [node name="sprite" type="Sprite" parent="."] -texture = ExtResource( 2 ) +texture = ExtResource( 1 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="."] shape = SubResource( 1 ) diff --git a/game/items/escitems/wrench_escitem.tscn b/game/items/escitems/r5_wrench.tscn similarity index 71% rename from game/items/escitems/wrench_escitem.tscn rename to game/items/escitems/r5_wrench.tscn index 9cfa844c..a6d01a1e 100644 --- a/game/items/escitems/wrench_escitem.tscn +++ b/game/items/escitems/r5_wrench.tscn @@ -1,25 +1,26 @@ [gd_scene load_steps=5 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escitem.gd" type="Script" id=1] -[ext_resource path="res://game/rooms/room5/items/wrench.png" type="Texture" id=2] -[ext_resource path="res://game/items/inventory/wrench_escinventoryitem.tscn" type="PackedScene" id=3] +[ext_resource path="res://game/items/inventory/wrench.tscn" type="PackedScene" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=2] +[ext_resource path="res://game/rooms/room5/items/wrench.png" type="Texture" id=3] [sub_resource type="RectangleShape2D" id=1] extents = Vector2( 44.696, 49.0953 ) [node name="wrench" type="Area2D"] -script = ExtResource( 1 ) +script = ExtResource( 2 ) global_id = "r5_wrench" esc_script = "res://game/items/escitems/wrench.esc" tooltip_name = "Wrench" default_action = "look" +default_action_inventory = "look" combine_if_action_used_among = PoolStringArray( "use" ) use_from_inventory_only = true -inventory_item_scene_file = ExtResource( 3 ) +inventory_item_scene_file = ExtResource( 1 ) dialog_color = Color( 1, 1, 1, 1 ) [node name="sprite" type="Sprite" parent="."] -texture = ExtResource( 2 ) +texture = ExtResource( 3 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="."] shape = SubResource( 1 ) diff --git a/game/items/escitems/bottle_escitem.tscn b/game/items/escitems/r9_bottle.tscn similarity index 73% rename from game/items/escitems/bottle_escitem.tscn rename to game/items/escitems/r9_bottle.tscn index 658f8261..8b97d538 100644 --- a/game/items/escitems/bottle_escitem.tscn +++ b/game/items/escitems/r9_bottle.tscn @@ -1,15 +1,15 @@ [gd_scene load_steps=5 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escitem.gd" type="Script" id=1] -[ext_resource path="res://game/items/textures/genericItem_color_127.png" type="Texture" id=2] -[ext_resource path="res://game/items/inventory/bottle_escinventoryitem.tscn" type="PackedScene" id=3] +[ext_resource path="res://game/items/textures/genericItem_color_127.png" type="Texture" id=1] +[ext_resource path="res://game/items/inventory/bottle.tscn" type="PackedScene" id=2] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=3] [sub_resource type="RectangleShape2D" id=1] extents = Vector2( 28.3873, 74.7806 ) [node name="bottle" type="Area2D"] z_index = 1 -script = ExtResource( 1 ) +script = ExtResource( 3 ) global_id = "r9_bottle" esc_script = "res://game/items/escitems/bottle.esc" tooltip_name = "Bottle" @@ -17,11 +17,11 @@ default_action = "pickup" default_action_inventory = "look" combine_if_action_used_among = PoolStringArray( "use" ) use_from_inventory_only = true -inventory_item_scene_file = ExtResource( 3 ) +inventory_item_scene_file = ExtResource( 2 ) dialog_color = Color( 1, 1, 1, 1 ) [node name="sprite" type="Sprite" parent="."] -texture = ExtResource( 2 ) +texture = ExtResource( 1 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="."] shape = SubResource( 1 ) diff --git a/game/items/inventory/axe_escinventoryitem.tscn b/game/items/inventory/axe_escinventoryitem.tscn deleted file mode 100644 index f014a0d9..00000000 --- a/game/items/inventory/axe_escinventoryitem.tscn +++ /dev/null @@ -1,13 +0,0 @@ -[gd_scene load_steps=3 format=2] - -[ext_resource path="res://addons/escoria-core/game/core-scripts/escinventoryitem.gd" type="Script" id=1] -[ext_resource path="res://game/items/textures/genericItem_color_020.png" type="Texture" id=2] - -[node name="axe" type="TextureButton"] -margin_right = 94.0 -margin_bottom = 128.0 -texture_normal = ExtResource( 2 ) -script = ExtResource( 1 ) -__meta__ = { -"_edit_use_anchors_": false -} diff --git a/game/items/inventory/bottle_escinventoryitem.tscn b/game/items/inventory/bottle.tscn similarity index 70% rename from game/items/inventory/bottle_escinventoryitem.tscn rename to game/items/inventory/bottle.tscn index 304287ea..0aec0e18 100644 --- a/game/items/inventory/bottle_escinventoryitem.tscn +++ b/game/items/inventory/bottle.tscn @@ -1,13 +1,13 @@ [gd_scene load_steps=3 format=2] -[ext_resource path="res://game/items/textures/genericItem_color_127.png" type="Texture" id=1] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escinventoryitem.gd" type="Script" id=2] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_inventory_item.gd" type="Script" id=1] +[ext_resource path="res://game/items/textures/genericItem_color_127.png" type="Texture" id=2] [node name="empty_sheet" type="TextureButton"] margin_right = 50.0 margin_bottom = 140.0 -texture_normal = ExtResource( 1 ) -script = ExtResource( 2 ) +texture_normal = ExtResource( 2 ) +script = ExtResource( 1 ) __meta__ = { "_edit_use_anchors_": false } diff --git a/game/items/inventory/empty_sheet_escinventoryitem.tscn b/game/items/inventory/empty_sheet.tscn similarity index 70% rename from game/items/inventory/empty_sheet_escinventoryitem.tscn rename to game/items/inventory/empty_sheet.tscn index 3054a79b..92987f9a 100644 --- a/game/items/inventory/empty_sheet_escinventoryitem.tscn +++ b/game/items/inventory/empty_sheet.tscn @@ -1,13 +1,13 @@ [gd_scene load_steps=3 format=2] -[ext_resource path="res://game/items/textures/genericItem_color_038.png" type="Texture" id=1] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escinventoryitem.gd" type="Script" id=2] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_inventory_item.gd" type="Script" id=1] +[ext_resource path="res://game/items/textures/genericItem_color_038.png" type="Texture" id=2] [node name="empty_sheet" type="TextureButton"] margin_right = 98.0 margin_bottom = 124.0 -texture_normal = ExtResource( 1 ) -script = ExtResource( 2 ) +texture_normal = ExtResource( 2 ) +script = ExtResource( 1 ) __meta__ = { "_edit_use_anchors_": false } diff --git a/game/items/inventory/filled_sheet_escinventoryitem.tscn b/game/items/inventory/filled_sheet.tscn similarity index 71% rename from game/items/inventory/filled_sheet_escinventoryitem.tscn rename to game/items/inventory/filled_sheet.tscn index f00eb37e..f29be970 100644 --- a/game/items/inventory/filled_sheet_escinventoryitem.tscn +++ b/game/items/inventory/filled_sheet.tscn @@ -1,13 +1,13 @@ [gd_scene load_steps=3 format=2] -[ext_resource path="res://game/rooms/room5/items/filled_sheet.png" type="Texture" id=1] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escinventoryitem.gd" type="Script" id=2] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_inventory_item.gd" type="Script" id=1] +[ext_resource path="res://game/rooms/room5/items/filled_sheet.png" type="Texture" id=2] [node name="filled_sheet" type="TextureButton"] margin_right = 88.0 margin_bottom = 124.0 -texture_normal = ExtResource( 1 ) -script = ExtResource( 2 ) +texture_normal = ExtResource( 2 ) +script = ExtResource( 1 ) __meta__ = { "_edit_use_anchors_": false } diff --git a/game/items/inventory/hammer_escinventoryitem.tscn b/game/items/inventory/hammer_escinventoryitem.tscn deleted file mode 100644 index 4caea16d..00000000 --- a/game/items/inventory/hammer_escinventoryitem.tscn +++ /dev/null @@ -1,13 +0,0 @@ -[gd_scene load_steps=3 format=2] - -[ext_resource path="res://addons/escoria-core/game/core-scripts/escinventoryitem.gd" type="Script" id=1] -[ext_resource path="res://game/items/textures/genericItem_color_010.png" type="Texture" id=2] - -[node name="hammer" type="TextureButton"] -margin_right = 70.0 -margin_bottom = 104.0 -texture_normal = ExtResource( 2 ) -script = ExtResource( 1 ) -__meta__ = { -"_edit_use_anchors_": false -} diff --git a/game/items/inventory/pen_escinventoryitem.tscn b/game/items/inventory/pen.tscn similarity index 90% rename from game/items/inventory/pen_escinventoryitem.tscn rename to game/items/inventory/pen.tscn index fc330ed9..05f7fafe 100644 --- a/game/items/inventory/pen_escinventoryitem.tscn +++ b/game/items/inventory/pen.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=3 format=2] [ext_resource path="res://game/items/textures/genericItem_color_026.png" type="Texture" id=1] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escinventoryitem.gd" type="Script" id=2] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_inventory_item.gd" type="Script" id=2] [node name="pen" type="TextureButton"] margin_right = 42.0 diff --git a/game/items/inventory/wrench_escinventoryitem.tscn b/game/items/inventory/wrench.tscn similarity index 90% rename from game/items/inventory/wrench_escinventoryitem.tscn rename to game/items/inventory/wrench.tscn index 95e3956e..daf92142 100644 --- a/game/items/inventory/wrench_escinventoryitem.tscn +++ b/game/items/inventory/wrench.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=3 format=2] [ext_resource path="res://game/items/textures/genericItem_color_004.png" type="Texture" id=1] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escinventoryitem.gd" type="Script" id=2] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_inventory_item.gd" type="Script" id=2] [node name="wrench" type="TextureButton"] margin_right = 70.0 diff --git a/game/rooms/room1/background.tscn b/game/rooms/room1/background.tscn index b68de9a8..993665d2 100644 --- a/game/rooms/room1/background.tscn +++ b/game/rooms/room1/background.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=2 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escbackground.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_background.gd" type="Script" id=1] [node name="background" type="TextureRect"] margin_right = 1289.0 diff --git a/game/rooms/room1/room1.tscn b/game/rooms/room1/room1.tscn index ff73a4d5..fe6cd124 100644 --- a/game/rooms/room1/room1.tscn +++ b/game/rooms/room1/room1.tscn @@ -4,8 +4,8 @@ [ext_resource path="res://game/rooms/room1/background.tscn" type="PackedScene" id=2] [ext_resource path="res://game/ui/commons/fonts/caslonantique.tres" type="DynamicFont" id=3] [ext_resource path="res://game/characters/mark/mark.tscn" type="PackedScene" id=4] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escitem.gd" type="Script" id=5] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escroom.gd" type="Script" id=6] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=5] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_room.gd" type="Script" id=6] [node name="room1" type="Node2D"] script = ExtResource( 6 ) diff --git a/game/rooms/room1/walkable_area.tscn b/game/rooms/room1/walkable_area.tscn index e1c0f031..872bfd15 100644 --- a/game/rooms/room1/walkable_area.tscn +++ b/game/rooms/room1/walkable_area.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escterrain.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_terrain.gd" type="Script" id=1] [sub_resource type="NavigationPolygon" id=1] vertices = PoolVector2Array( 1168.92, 640.557, 1182.53, 588.863, 1269.59, 622.872, 1275.03, 799.721, 129.634, 615.792, 1143.08, 613.35, -9.16094, 803.802, -6.44019, 711.297 ) diff --git a/game/rooms/room10/background.tscn b/game/rooms/room10/background.tscn index 4caa8e09..aa350e6d 100644 --- a/game/rooms/room10/background.tscn +++ b/game/rooms/room10/background.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=2 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escbackground.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_background.gd" type="Script" id=1] [node name="background" type="TextureRect"] margin_right = 1289.0 diff --git a/game/rooms/room10/r_door.tscn b/game/rooms/room10/r_door.tscn index 67f90545..f4877aff 100644 --- a/game/rooms/room10/r_door.tscn +++ b/game/rooms/room10/r_door.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=4 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escitem.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=1] [sub_resource type="Animation" id=1] resource_name = "r_door_close" diff --git a/game/rooms/room10/room10.tscn b/game/rooms/room10/room10.tscn index 0479cf73..42b1186b 100644 --- a/game/rooms/room10/room10.tscn +++ b/game/rooms/room10/room10.tscn @@ -1,11 +1,11 @@ [gd_scene load_steps=10 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escterrain.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_terrain.gd" type="Script" id=1] [ext_resource path="res://game/rooms/room10/background.tscn" type="PackedScene" id=2] [ext_resource path="res://game/ui/commons/fonts/caslonantique.tres" type="DynamicFont" id=3] [ext_resource path="res://game/characters/mark/mark.tscn" type="PackedScene" id=4] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escroom.gd" type="Script" id=6] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escitem.gd" type="Script" id=7] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_room.gd" type="Script" id=6] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=7] [ext_resource path="res://game/rooms/room2/button/button.tscn" type="PackedScene" id=8] [ext_resource path="res://game/rooms/room10/r_door.tscn" type="PackedScene" id=9] diff --git a/game/rooms/room10/walkable_area.tscn b/game/rooms/room10/walkable_area.tscn index 9e64765c..2d6b73ec 100644 --- a/game/rooms/room10/walkable_area.tscn +++ b/game/rooms/room10/walkable_area.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escterrain.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_terrain.gd" type="Script" id=1] [sub_resource type="NavigationPolygon" id=1] vertices = PoolVector2Array( 1168.92, 640.557, 1182.53, 588.863, 1269.59, 622.872, 1275.03, 799.721, 129.634, 615.792, 1143.08, 613.35, -9.16094, 803.802, 84.5821, 654.06, -6.44019, 711.297, 3.15687, 646.051, 59.2201, 628.698 ) diff --git a/game/rooms/room2/background.tscn b/game/rooms/room2/background.tscn index b3d9ec52..ff9042f6 100644 --- a/game/rooms/room2/background.tscn +++ b/game/rooms/room2/background.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escbackground.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_background.gd" type="Script" id=1] [ext_resource path="res://game/rooms/room2/bridge.tscn" type="PackedScene" id=2] [node name="background" type="TextureRect"] diff --git a/game/rooms/room2/bridge.tscn b/game/rooms/room2/bridge.tscn index 0ffc93c7..4f62dd50 100644 --- a/game/rooms/room2/bridge.tscn +++ b/game/rooms/room2/bridge.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=4 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escitem.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=1] [sub_resource type="Animation" id=1] resource_name = "bridge_close" diff --git a/game/rooms/room2/button/button.tscn b/game/rooms/room2/button/button.tscn index 86c81772..743e7ec8 100644 --- a/game/rooms/room2/button/button.tscn +++ b/game/rooms/room2/button/button.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escitem.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=1] [sub_resource type="RectangleShape2D" id=1] extents = Vector2( 28.6442, 29.8513 ) diff --git a/game/rooms/room2/room2.tscn b/game/rooms/room2/room2.tscn index 2c730f09..c9d5b84f 100644 --- a/game/rooms/room2/room2.tscn +++ b/game/rooms/room2/room2.tscn @@ -5,8 +5,8 @@ [ext_resource path="res://game/ui/commons/fonts/caslonantique.tres" type="DynamicFont" id=3] [ext_resource path="res://game/characters/mark/mark.tscn" type="PackedScene" id=4] [ext_resource path="res://game/rooms/room2/button/button.tscn" type="PackedScene" id=5] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escroom.gd" type="Script" id=6] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escitem.gd" type="Script" id=7] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_room.gd" type="Script" id=6] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=7] [node name="room2" type="Node2D"] script = ExtResource( 6 ) diff --git a/game/rooms/room2/walkable_area.tscn b/game/rooms/room2/walkable_area.tscn index 5cb99b8c..86eedaa8 100644 --- a/game/rooms/room2/walkable_area.tscn +++ b/game/rooms/room2/walkable_area.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=4 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escterrain.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_terrain.gd" type="Script" id=1] [sub_resource type="NavigationPolygon" id=1] vertices = PoolVector2Array( 129.634, 615.792, 488.56, 617.98, 454.637, 800.726, 2.69714, 805.103, 75.8943, 663.384, 3.79144, 707.712, 5.9538, 653.476, 63.1848, 626.267, 1284.99, 804.433, 868.119, 803.394, 828.615, 621.468, 1152.31, 619.946, 1181.97, 640.075, 1260.04, 615.231, 1282.91, 680.724, 1190.39, 590.281 ) diff --git a/game/rooms/room3/background.tscn b/game/rooms/room3/background.tscn index f0af2e02..f317b3a1 100644 --- a/game/rooms/room3/background.tscn +++ b/game/rooms/room3/background.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escbackground.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_background.gd" type="Script" id=1] [ext_resource path="res://game/rooms/room2/bridge.tscn" type="PackedScene" id=2] [node name="background" type="TextureRect"] diff --git a/game/rooms/room3/room3.tscn b/game/rooms/room3/room3.tscn index 0c44230e..7f925ab0 100644 --- a/game/rooms/room3/room3.tscn +++ b/game/rooms/room3/room3.tscn @@ -4,8 +4,8 @@ [ext_resource path="res://game/rooms/room3/background.tscn" type="PackedScene" id=2] [ext_resource path="res://game/ui/commons/fonts/caslonantique.tres" type="DynamicFont" id=3] [ext_resource path="res://game/characters/mark/mark.tscn" type="PackedScene" id=4] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escitem.gd" type="Script" id=5] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escroom.gd" type="Script" id=6] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=5] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_room.gd" type="Script" id=6] [ext_resource path="res://game/items/escitems/button.tscn" type="PackedScene" id=7] [node name="room3" type="Node2D"] diff --git a/game/rooms/room3/walkable_area.tscn b/game/rooms/room3/walkable_area.tscn index 5cb99b8c..86eedaa8 100644 --- a/game/rooms/room3/walkable_area.tscn +++ b/game/rooms/room3/walkable_area.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=4 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escterrain.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_terrain.gd" type="Script" id=1] [sub_resource type="NavigationPolygon" id=1] vertices = PoolVector2Array( 129.634, 615.792, 488.56, 617.98, 454.637, 800.726, 2.69714, 805.103, 75.8943, 663.384, 3.79144, 707.712, 5.9538, 653.476, 63.1848, 626.267, 1284.99, 804.433, 868.119, 803.394, 828.615, 621.468, 1152.31, 619.946, 1181.97, 640.075, 1260.04, 615.231, 1282.91, 680.724, 1190.39, 590.281 ) diff --git a/game/rooms/room4/esc/room4.esc b/game/rooms/room4/esc/room4.esc index 1420f6b6..cc9c1b42 100755 --- a/game/rooms/room4/esc/room4.esc +++ b/game/rooms/room4/esc/room4.esc @@ -9,7 +9,7 @@ # Set player look left set_angle player 270 stop -> [!last_scene] +> [eq ESC_LAST_SCENE ""] teleport player player_start stop diff --git a/game/rooms/room4/room4.tscn b/game/rooms/room4/room4.tscn index 34372756..1e30b484 100644 --- a/game/rooms/room4/room4.tscn +++ b/game/rooms/room4/room4.tscn @@ -1,11 +1,11 @@ [gd_scene load_steps=10 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escterrain.gd" type="Script" id=1] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escbackground.gd" type="Script" id=2] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_terrain.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_background.gd" type="Script" id=2] [ext_resource path="res://game/ui/commons/fonts/caslonantique.tres" type="DynamicFont" id=3] [ext_resource path="res://game/characters/mark/mark.tscn" type="PackedScene" id=4] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escitem.gd" type="Script" id=5] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escroom.gd" type="Script" id=6] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=5] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_room.gd" type="Script" id=6] [ext_resource path="res://game/rooms/room4/assets/background.png" type="Texture" id=7] [ext_resource path="res://game/rooms/room4/assets/depth_reduced.png" type="Texture" id=8] @@ -49,13 +49,16 @@ margin_right = 1008.3 margin_bottom = 109.657 custom_fonts/font = ExtResource( 3 ) text = "This room demonstrates how to use a background image AND using a large image width AND setting a depth map on the ESCTerrain node" +__meta__ = { +"_edit_use_anchors_": false +} [node name="walkable_area" type="Navigation2D" parent="."] script = ExtResource( 1 ) scales = ExtResource( 8 ) -player_doubleclick_speed_multiplier = 1.8 -debug_mode = 0 scale_min = 0.4 +lightmap = ExtResource( 8 ) +player_doubleclick_speed_multiplier = 1.8 [node name="platform" type="NavigationPolygonInstance" parent="walkable_area"] position = Vector2( 6.73163, -264.779 ) diff --git a/game/rooms/room5/background.tscn b/game/rooms/room5/background.tscn index feb68b1f..4c9deb59 100644 --- a/game/rooms/room5/background.tscn +++ b/game/rooms/room5/background.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=2 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escbackground.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_background.gd" type="Script" id=1] [node name="background" type="TextureRect"] margin_right = 1289.0 diff --git a/game/rooms/room5/item_wall/item_wall.tscn b/game/rooms/room5/item_wall/item_wall.tscn index 4b0a2de9..0e13f87d 100644 --- a/game/rooms/room5/item_wall/item_wall.tscn +++ b/game/rooms/room5/item_wall/item_wall.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=4 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escitem.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=1] [sub_resource type="Animation" id=1] resource_name = "state_round" diff --git a/game/rooms/room5/room5.tscn b/game/rooms/room5/room5.tscn index b3f22a31..f3de5fea 100644 --- a/game/rooms/room5/room5.tscn +++ b/game/rooms/room5/room5.tscn @@ -1,15 +1,15 @@ [gd_scene load_steps=12 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escterrain.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_terrain.gd" type="Script" id=1] [ext_resource path="res://game/rooms/room5/background.tscn" type="PackedScene" id=2] [ext_resource path="res://game/ui/commons/fonts/caslonantique.tres" type="DynamicFont" id=3] [ext_resource path="res://game/characters/mark/mark.tscn" type="PackedScene" id=4] [ext_resource path="res://game/rooms/room5/item_wall/item_wall.tscn" type="PackedScene" id=5] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escroom.gd" type="Script" id=6] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escitem.gd" type="Script" id=7] -[ext_resource path="res://game/items/escitems/wrench_escitem.tscn" type="PackedScene" id=8] -[ext_resource path="res://game/items/escitems/empty_sheet_escitem.tscn" type="PackedScene" id=9] -[ext_resource path="res://game/items/escitems/pen_escitem.tscn" type="PackedScene" id=10] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_room.gd" type="Script" id=6] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=7] +[ext_resource path="res://game/items/escitems/r5_wrench.tscn" type="PackedScene" id=8] +[ext_resource path="res://game/items/escitems/r5_empty_sheet.tscn" type="PackedScene" id=9] +[ext_resource path="res://game/items/escitems/r5_pen.tscn" type="PackedScene" id=10] [sub_resource type="NavigationPolygon" id=1] vertices = PoolVector2Array( 1168.92, 640.557, 1182.53, 588.863, 1269.59, 622.872, 1275.03, 799.721, 129.634, 615.792, 1143.08, 613.35, -9.16094, 803.802, 84.5821, 654.06, -6.44019, 711.297, 3.15687, 646.051, 59.2201, 628.698 ) diff --git a/game/rooms/room5/walkable_area.tscn b/game/rooms/room5/walkable_area.tscn index 9e64765c..2d6b73ec 100644 --- a/game/rooms/room5/walkable_area.tscn +++ b/game/rooms/room5/walkable_area.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escterrain.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_terrain.gd" type="Script" id=1] [sub_resource type="NavigationPolygon" id=1] vertices = PoolVector2Array( 1168.92, 640.557, 1182.53, 588.863, 1269.59, 622.872, 1275.03, 799.721, 129.634, 615.792, 1143.08, 613.35, -9.16094, 803.802, 84.5821, 654.06, -6.44019, 711.297, 3.15687, 646.051, 59.2201, 628.698 ) diff --git a/game/rooms/room6/background.tscn b/game/rooms/room6/background.tscn index feb68b1f..4c9deb59 100644 --- a/game/rooms/room6/background.tscn +++ b/game/rooms/room6/background.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=2 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escbackground.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_background.gd" type="Script" id=1] [node name="background" type="TextureRect"] margin_right = 1289.0 diff --git a/game/rooms/room6/l_exit.tscn b/game/rooms/room6/l_exit.tscn index 0852f690..4a79d521 100644 --- a/game/rooms/room6/l_exit.tscn +++ b/game/rooms/room6/l_exit.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=2 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escitem.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=1] [node name="l_exit" type="Area2D"] script = ExtResource( 1 ) diff --git a/game/rooms/room6/r_door.tscn b/game/rooms/room6/r_door.tscn index 02c47156..d21fed6c 100644 --- a/game/rooms/room6/r_door.tscn +++ b/game/rooms/room6/r_door.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=4 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escitem.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=1] [sub_resource type="Animation" id=1] resource_name = "r_door_close" diff --git a/game/rooms/room6/room6.tscn b/game/rooms/room6/room6.tscn index e0424293..d6381aa0 100644 --- a/game/rooms/room6/room6.tscn +++ b/game/rooms/room6/room6.tscn @@ -1,11 +1,11 @@ [gd_scene load_steps=10 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escterrain.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_terrain.gd" type="Script" id=1] [ext_resource path="res://game/rooms/room6/background.tscn" type="PackedScene" id=2] [ext_resource path="res://game/rooms/room6/l_exit.tscn" type="PackedScene" id=3] [ext_resource path="res://game/characters/mark/mark.tscn" type="PackedScene" id=4] [ext_resource path="res://game/rooms/room6/r_door.tscn" type="PackedScene" id=5] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escroom.gd" type="Script" id=6] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_room.gd" type="Script" id=6] [ext_resource path="res://game/characters/worker/worker.tscn" type="PackedScene" id=7] [ext_resource path="res://game/ui/commons/fonts/caslonantique.tres" type="DynamicFont" id=8] diff --git a/game/rooms/room6/walkable_area.tscn b/game/rooms/room6/walkable_area.tscn index 9e64765c..2d6b73ec 100644 --- a/game/rooms/room6/walkable_area.tscn +++ b/game/rooms/room6/walkable_area.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escterrain.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_terrain.gd" type="Script" id=1] [sub_resource type="NavigationPolygon" id=1] vertices = PoolVector2Array( 1168.92, 640.557, 1182.53, 588.863, 1269.59, 622.872, 1275.03, 799.721, 129.634, 615.792, 1143.08, 613.35, -9.16094, 803.802, 84.5821, 654.06, -6.44019, 711.297, 3.15687, 646.051, 59.2201, 628.698 ) diff --git a/game/rooms/room7/background.tscn b/game/rooms/room7/background.tscn index 2370ebab..817c4700 100644 --- a/game/rooms/room7/background.tscn +++ b/game/rooms/room7/background.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=2 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escbackground.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_background.gd" type="Script" id=1] [node name="background" type="TextureRect"] margin_right = 2092.0 diff --git a/game/rooms/room7/room7.tscn b/game/rooms/room7/room7.tscn index f5b91cec..3a3f3a4b 100644 --- a/game/rooms/room7/room7.tscn +++ b/game/rooms/room7/room7.tscn @@ -1,12 +1,12 @@ [gd_scene load_steps=16 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escterrain.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_terrain.gd" type="Script" id=1] [ext_resource path="res://game/rooms/room7/background.tscn" type="PackedScene" id=2] [ext_resource path="res://game/items/escitems/button.tscn" type="PackedScene" id=3] [ext_resource path="res://game/characters/mark/mark.tscn" type="PackedScene" id=4] [ext_resource path="res://game/ui/commons/fonts/caslonantique.tres" type="DynamicFont" id=5] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escroom.gd" type="Script" id=6] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escitem.gd" type="Script" id=7] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_room.gd" type="Script" id=6] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=7] [sub_resource type="NavigationPolygon" id=1] vertices = PoolVector2Array( 1976.63, 640.557, 1987.95, 588.863, 2070.07, 622.872, 2066.3, 799.721, 1015.72, 626.818, 1956.81, 616.096, -9.16094, 803.802, -6.44019, 711.297, 911.239, 554.152, 991.239, 554.152, 858.566, 628.405, 741.099, 620.468, 84.5821, 654.06, 3.15687, 646.051, 59.2201, 628.698, 129.634, 615.792 ) diff --git a/game/rooms/room7/walkable_area.tscn b/game/rooms/room7/walkable_area.tscn index 9e64765c..2d6b73ec 100644 --- a/game/rooms/room7/walkable_area.tscn +++ b/game/rooms/room7/walkable_area.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escterrain.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_terrain.gd" type="Script" id=1] [sub_resource type="NavigationPolygon" id=1] vertices = PoolVector2Array( 1168.92, 640.557, 1182.53, 588.863, 1269.59, 622.872, 1275.03, 799.721, 129.634, 615.792, 1143.08, 613.35, -9.16094, 803.802, 84.5821, 654.06, -6.44019, 711.297, 3.15687, 646.051, 59.2201, 628.698 ) diff --git a/game/rooms/room8/room8.tscn b/game/rooms/room8/room8.tscn index 556c6244..9e530e47 100644 --- a/game/rooms/room8/room8.tscn +++ b/game/rooms/room8/room8.tscn @@ -1,11 +1,11 @@ [gd_scene load_steps=11 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escterrain.gd" type="Script" id=1] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escbackground.gd" type="Script" id=2] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_terrain.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_background.gd" type="Script" id=2] [ext_resource path="res://game/ui/commons/fonts/caslonantique.tres" type="DynamicFont" id=3] [ext_resource path="res://game/characters/mark/mark.tscn" type="PackedScene" id=4] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escitem.gd" type="Script" id=5] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escroom.gd" type="Script" id=6] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=5] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_room.gd" type="Script" id=6] [sub_resource type="NavigationPolygon" id=1] vertices = PoolVector2Array( 1143.08, 613.35, 1267.68, 669.029, 1275.03, 799.721, -9.16094, 803.802, -6.44019, 711.297, 84.5821, 654.06, 742.298, 623.672, 581.028, 613.592, 583.548, 574.535, 707.02, 574.535, 714.58, 611.072, 3.15687, 646.051, 59.2201, 628.698, 129.634, 615.792, 530.631, 612.332, 550.79, 623.672, 783.875, 609.812 ) diff --git a/game/rooms/room9/background.tscn b/game/rooms/room9/background.tscn index 4caa8e09..aa350e6d 100644 --- a/game/rooms/room9/background.tscn +++ b/game/rooms/room9/background.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=2 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escbackground.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_background.gd" type="Script" id=1] [node name="background" type="TextureRect"] margin_right = 1289.0 diff --git a/game/rooms/room9/closet/magical_closet.tscn b/game/rooms/room9/closet/magical_closet.tscn index ad67ffcc..8779fe14 100644 --- a/game/rooms/room9/closet/magical_closet.tscn +++ b/game/rooms/room9/closet/magical_closet.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=5 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escitem.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=1] [sub_resource type="RectangleShape2D" id=1] extents = Vector2( 66.4415, 154.457 ) diff --git a/game/rooms/room9/r_door.tscn b/game/rooms/room9/r_door.tscn index 67f90545..f4877aff 100644 --- a/game/rooms/room9/r_door.tscn +++ b/game/rooms/room9/r_door.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=4 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escitem.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=1] [sub_resource type="Animation" id=1] resource_name = "r_door_close" diff --git a/game/rooms/room9/room9.tscn b/game/rooms/room9/room9.tscn index fb3bb9ad..7592993f 100644 --- a/game/rooms/room9/room9.tscn +++ b/game/rooms/room9/room9.tscn @@ -1,16 +1,16 @@ [gd_scene load_steps=14 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escterrain.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_terrain.gd" type="Script" id=1] [ext_resource path="res://game/rooms/room9/background.tscn" type="PackedScene" id=2] [ext_resource path="res://game/ui/commons/fonts/caslonantique.tres" type="DynamicFont" id=3] [ext_resource path="res://game/characters/mark/mark.tscn" type="PackedScene" id=4] [ext_resource path="res://game/rooms/room9/closet/magical_closet.tscn" type="PackedScene" id=5] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escroom.gd" type="Script" id=6] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escitem.gd" type="Script" id=7] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_room.gd" type="Script" id=6] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=7] [ext_resource path="res://game/rooms/room2/button/button.tscn" type="PackedScene" id=8] [ext_resource path="res://game/rooms/room9/r_door.tscn" type="PackedScene" id=9] [ext_resource path="res://game/items/textures/genericItem_color_127.png" type="Texture" id=10] -[ext_resource path="res://game/items/escitems/bottle_escitem.tscn" type="PackedScene" id=11] +[ext_resource path="res://game/items/escitems/r9_bottle.tscn" type="PackedScene" id=11] [sub_resource type="NavigationPolygon" id=1] vertices = PoolVector2Array( 1168.92, 640.557, 1182.53, 588.863, 1269.59, 622.872, 1275.03, 799.721, 1143.08, 613.35, -9.16094, 803.802, -6.44019, 711.297, 846.646, 637.49, 3.15687, 646.051, 59.2201, 628.698, 84.5821, 654.06, 864.626, 613.518, 428.618, 640.487, 386.666, 618.012, 129.634, 615.792 ) diff --git a/game/rooms/room9/walkable_area.tscn b/game/rooms/room9/walkable_area.tscn index 9e64765c..2d6b73ec 100644 --- a/game/rooms/room9/walkable_area.tscn +++ b/game/rooms/room9/walkable_area.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=2] -[ext_resource path="res://addons/escoria-core/game/core-scripts/escterrain.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_terrain.gd" type="Script" id=1] [sub_resource type="NavigationPolygon" id=1] vertices = PoolVector2Array( 1168.92, 640.557, 1182.53, 588.863, 1269.59, 622.872, 1275.03, 799.721, 129.634, 615.792, 1143.08, 613.35, -9.16094, 803.802, 84.5821, 654.06, -6.44019, 711.297, 3.15687, 646.051, 59.2201, 628.698 ) diff --git a/game/translations/game.en.translation b/game/translations/game.en.translation index 9c947db6..16037dc6 100644 Binary files a/game/translations/game.en.translation and b/game/translations/game.en.translation differ diff --git a/game/translations/game.fr.translation b/game/translations/game.fr.translation index aceaf3f4..37269b0e 100644 Binary files a/game/translations/game.fr.translation and b/game/translations/game.fr.translation differ diff --git a/game/translations/main_menu.en.translation b/game/translations/main_menu.en.translation index 1279c771..55baa043 100644 Binary files a/game/translations/main_menu.en.translation and b/game/translations/main_menu.en.translation differ diff --git a/game/translations/main_menu.fr.translation b/game/translations/main_menu.fr.translation index 45f4bd56..d85234db 100644 Binary files a/game/translations/main_menu.fr.translation and b/game/translations/main_menu.fr.translation differ diff --git a/game/ui/ui_9verbs/inventory/inventory_ui.tscn b/game/ui/ui_9verbs/inventory/inventory_ui.tscn index f6de2f32..9feb3106 100644 --- a/game/ui/ui_9verbs/inventory/inventory_ui.tscn +++ b/game/ui/ui_9verbs/inventory/inventory_ui.tscn @@ -1,7 +1,6 @@ -[gd_scene load_steps=4 format=2] +[gd_scene load_steps=3 format=2] [ext_resource path="res://addons/escoria-core/game/scenes/inventory/inventory_ui.gd" type="Script" id=1] -[ext_resource path="res://game/items/ESCORIA_ALL_ITEMS.tscn" type="PackedScene" id=2] [ext_resource path="res://game/ui/ui_9verbs/inventory/inventory_ui_container.gd" type="Script" id=3] [node name="inventory_ui" type="PanelContainer"] @@ -26,6 +25,3 @@ custom_constants/vseparation = 16 custom_constants/hseparation = 16 columns = 4 script = ExtResource( 3 ) - -[node name="ESCORIA_ALL_ITEMS" parent="." instance=ExtResource( 2 )] -position = Vector2( 269.391, 275.003 ) diff --git a/game/ui/ui_mouse_icons/game.gd b/game/ui/ui_mouse_icons/game.gd index 8ad9cec2..1c12d109 100644 --- a/game/ui/ui_mouse_icons/game.gd +++ b/game/ui/ui_mouse_icons/game.gd @@ -88,8 +88,8 @@ func left_click_on_inventory_item(inventory_item_global_id : String, event : Inp ).node if item.get_node("sprite").texture: $ui/verbs_layer/verbs_menu.set_tool_texture(item.get_node("sprite").texture) - elif item.inventory_item_scene_file.instance().texture_normal: - $ui/verbs_layer/verbs_menu.set_tool_texture(item.inventory_item_scene_file.instance().texture_normal) + elif item.inventory_item.texture_normal: + $ui/verbs_layer/verbs_menu.set_tool_texture(item.inventory_item.texture_normal) func right_click_on_inventory_item(inventory_item_global_id : String, event : InputEvent) -> void: diff --git a/game/ui/ui_mouse_icons/inventory/inventory_ui.tscn b/game/ui/ui_mouse_icons/inventory/inventory_ui.tscn index 23f6f755..81f31d7b 100644 --- a/game/ui/ui_mouse_icons/inventory/inventory_ui.tscn +++ b/game/ui/ui_mouse_icons/inventory/inventory_ui.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=10 format=2] +[gd_scene load_steps=9 format=2] [ext_resource path="res://addons/escoria-core/game/scenes/inventory/inventory_ui.gd" type="Script" id=1] [ext_resource path="res://game/ui/ui_mouse_icons/images/inventory_bg.png" type="Texture" id=2] @@ -6,7 +6,6 @@ [ext_resource path="res://game/ui/ui_mouse_icons/inventory/inventory_showhide.gd" type="Script" id=4] [ext_resource path="res://game/ui/ui_mouse_icons/images/frame.png" type="Texture" id=5] [ext_resource path="res://game/ui/ui_mouse_icons/images/inventory_icon.png" type="Texture" id=6] -[ext_resource path="res://game/items/ESCORIA_ALL_ITEMS.tscn" type="PackedScene" id=7] [sub_resource type="Animation" id=1] resource_name = "hide" @@ -100,9 +99,6 @@ __meta__ = { } inventory_ui_container = NodePath("inventory_button/panel/MarginContainer/ScrollContainer/container") -[node name="ESCORIA_ALL_ITEMS" parent="." instance=ExtResource( 7 )] -position = Vector2( 269.391, 275.003 ) - [node name="inventory_button" type="TextureButton" parent="."] margin_right = 256.0 margin_bottom = 322.0 diff --git a/project.godot b/project.godot index 515a6164..489a7138 100644 --- a/project.godot +++ b/project.godot @@ -87,7 +87,7 @@ _global_script_classes=[ { "base": "TextureRect", "class": "ESCBackground", "language": "GDScript", -"path": "res://addons/escoria-core/game/core-scripts/escbackground.gd" +"path": "res://addons/escoria-core/game/core-scripts/esc_background.gd" }, { "base": "Control", "class": "ESCBackgroundMusic", @@ -167,7 +167,7 @@ _global_script_classes=[ { "base": "Node2D", "class": "ESCGame", "language": "GDScript", -"path": "res://addons/escoria-core/game/core-scripts/escgame.gd" +"path": "res://addons/escoria-core/game/core-scripts/esc_game.gd" }, { "base": "Resource", "class": "ESCGlobalsManager", @@ -187,7 +187,7 @@ _global_script_classes=[ { "base": "TextureButton", "class": "ESCInventoryItem", "language": "GDScript", -"path": "res://addons/escoria-core/game/core-scripts/escinventoryitem.gd" +"path": "res://addons/escoria-core/game/core-scripts/esc_inventory_item.gd" }, { "base": "Object", "class": "ESCInventoryManager", @@ -197,12 +197,17 @@ _global_script_classes=[ { "base": "Area2D", "class": "ESCItem", "language": "GDScript", -"path": "res://addons/escoria-core/game/core-scripts/escitem.gd" +"path": "res://addons/escoria-core/game/core-scripts/esc_item.gd" }, { "base": "Object", "class": "ESCLogger", "language": "GDScript", -"path": "res://addons/escoria-core/game/core-scripts/log/logging.gd" +"path": "res://addons/escoria-core/game/core-scripts/log/esc_logger.gd" +}, { +"base": "Node", +"class": "ESCMovable", +"language": "GDScript", +"path": "res://addons/escoria-core/game/core-scripts/behaviors/esc_movable.gd" }, { "base": "Node", "class": "ESCObject", @@ -214,15 +219,20 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://addons/escoria-core/game/core-scripts/esc/esc_object_manager.gd" }, { -"base": "KinematicBody2D", +"base": "ESCItem", "class": "ESCPlayer", "language": "GDScript", -"path": "res://addons/escoria-core/game/core-scripts/escplayer.gd" +"path": "res://addons/escoria-core/game/core-scripts/esc_player.gd" +}, { +"base": "Object", +"class": "ESCResourceCache", +"language": "GDScript", +"path": "res://addons/escoria-core/game/core-scripts/esc_resource_cache.gd" }, { "base": "Node2D", "class": "ESCRoom", "language": "GDScript", -"path": "res://addons/escoria-core/game/core-scripts/escroom.gd" +"path": "res://addons/escoria-core/game/core-scripts/esc_room.gd" }, { "base": "Object", "class": "ESCScheduledEvent", @@ -242,12 +252,22 @@ _global_script_classes=[ { "base": "Navigation2D", "class": "ESCTerrain", "language": "GDScript", -"path": "res://addons/escoria-core/game/core-scripts/escterrain.gd" +"path": "res://addons/escoria-core/game/core-scripts/esc_terrain.gd" }, { "base": "RichTextLabel", "class": "ESCTooltip", "language": "GDScript", -"path": "res://addons/escoria-core/game/core-scripts/esctooltip.gd" +"path": "res://addons/escoria-core/game/core-scripts/esc_tooltip.gd" +}, { +"base": "Object", +"class": "ESCUtils", +"language": "GDScript", +"path": "res://addons/escoria-core/game/core-scripts/utils/esc_utils.gd" +}, { +"base": "Object", +"class": "ESCWalkContext", +"language": "GDScript", +"path": "res://addons/escoria-core/game/core-scripts/esc_walk_context.gd" }, { "base": "ESCBaseCommand", "class": "EnableTerrainCommand", @@ -274,11 +294,6 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://addons/escoria-core/game/core-scripts/esc/commands/inventory_remove.gd" }, { -"base": "Node", -"class": "Movable", -"language": "GDScript", -"path": "res://addons/escoria-core/game/core-scripts/behaviors/movable.gd" -}, { "base": "ESCBaseCommand", "class": "PlaySndCommand", "language": "GDScript", @@ -299,11 +314,6 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://addons/escoria-core/game/core-scripts/esc/commands/repeat.gd" }, { -"base": "Object", -"class": "ResourceCache", -"language": "GDScript", -"path": "res://addons/escoria-core/game/core-scripts/resource_queue.gd" -}, { "base": "ESCBaseCommand", "class": "SayCommand", "language": "GDScript", @@ -454,26 +464,28 @@ _global_script_class_icons={ "ESCInventoryManager": "", "ESCItem": "", "ESCLogger": "", +"ESCMovable": "", "ESCObject": "", "ESCObjectManager": "", "ESCPlayer": "", +"ESCResourceCache": "", "ESCRoom": "", "ESCScheduledEvent": "", "ESCScript": "", "ESCStatement": "", "ESCTerrain": "", "ESCTooltip": "", +"ESCUtils": "", +"ESCWalkContext": "", "EnableTerrainCommand": "", "GameOverCommand": "", "IncGlobalCommand": "", "InventoryAddCommand": "", "InventoryRemoveCommand": "", -"Movable": "", "PlaySndCommand": "", "QueueAnimationCommand": "", "QueueResourceCommand": "", "RepeatCommand": "", -"ResourceCache": "", "SayCommand": "", "SchedEventCommand": "", "SetActiveCommand": "", @@ -511,7 +523,6 @@ config/icon="res://icon.png" [autoload] escoria="*res://addons/escoria-core/game/escoria.tscn" -esctypes="*res://addons/escoria-core/game/core-scripts/escoria_types.gd" [display] @@ -550,6 +561,9 @@ sound/speech_volume=1 sound/master_volume=1 main/command_directories=[ "res://addons/escoria-core/game/core-scripts/esc/commands" ] debug/log_level="DEBUG" +platform/skip_cache=false +platform/skip_cache.mobile=true +ui/items_autoregister_path="res://game/items/escitems/" [input]