From b4bf5b82d6bc421c306abefe4618cd48be065a15 Mon Sep 17 00:00:00 2001 From: Julian Murgia Date: Tue, 7 Sep 2021 09:13:09 +0200 Subject: [PATCH] Event flags implementation (#382) * Added event flags * Added transition ESC command * Also edited .gitignore to ignore .translation files * docs: Automatic update of API docs Co-authored-by: StraToN --- .gitignore | 1 + .../esc/_test/test_esc_compiler.gd | 7 - .../core-scripts/esc/commands/change_scene.gd | 43 ++-- .../core-scripts/esc/commands/transition.gd | 45 ++++ .../game/core-scripts/esc/types/esc_event.gd | 18 +- .../game/core-scripts/esc_controller.gd | 133 +++++++++- .../save_data/esc_save_manager.gd | 9 + .../transitions/shaders/transition.material | Bin 578 -> 583 bytes .../game/scenes/transitions/transition.gd | 54 +++- .../game/scenes/transitions/transition.tscn | 117 ++++++--- addons/escoria-ui-9verbs/game.gd | 1 + addons/escoria-ui-simplemouse/game.gd | 1 + docs/api/ChangeSceneCommand.md | 12 +- docs/api/ESCEvent.md | 14 +- docs/api/ESCSaveManager.md | 8 + docs/api/TransitionCommand.md | 39 +++ docs/api/transition.gd.md | 37 ++- docs/esc.md | 15 +- game/items/inventory/bottle.tscn | 3 +- game/rooms/room01/r_door.tscn | 25 ++ game/rooms/room01/room01.tscn | 24 +- game/rooms/room10/background.tscn | 7 + game/rooms/room10/esc/right_exit.esc | 3 +- game/rooms/room10/r_door.tscn | 139 ++-------- game/rooms/room10/room10.tscn | 9 +- game/rooms/room11/background.tscn | 30 +++ game/rooms/room11/esc/left_exit.esc | 5 + .../room11/esc/mysterious_circle_fadein.esc | 5 + .../room11/esc/mysterious_circle_nohud.esc | 3 + .../room11/esc/mysterious_circle_nosave.esc | 3 + .../room11/esc/mysterious_circle_nott.esc | 3 + .../rooms/room11/esc/mysterious_circle_tk.esc | 3 + game/rooms/room11/esc/right_exit.esc | 5 + game/rooms/room11/esc/room11.esc | 18 ++ game/rooms/room11/r_door.tscn | 20 ++ game/rooms/room11/room11.tscn | 243 ++++++++++++++++++ game/rooms/room11/walkable_area.tscn | 18 ++ game/rooms/room12/background.tscn | 30 +++ game/rooms/room12/esc/left_exit.esc | 5 + game/rooms/room12/esc/right_exit.esc | 3 + game/rooms/room12/esc/room12.esc | 21 ++ game/rooms/room12/r_door.tscn | 25 ++ game/rooms/room12/room12.tscn | 82 ++++++ game/rooms/room12/walkable_area.tscn | 18 ++ game/start_game.esc | 9 + game/ui/commons/dialogs/insets/guybrush.jpeg | Bin 26964 -> 0 bytes .../dialogs/insets/guybrush.jpeg.import | 34 --- game/ui/commons/main_menu/main_menu.tscn | 15 +- game/ui/commons/pause_menu/pause_menu.gd | 4 + game/ui/commons/pause_menu/pause_menu.tscn | 2 +- project.godot | 8 +- 51 files changed, 1071 insertions(+), 305 deletions(-) create mode 100644 addons/escoria-core/game/core-scripts/esc/commands/transition.gd create mode 100644 docs/api/TransitionCommand.md create mode 100644 game/rooms/room01/r_door.tscn create mode 100644 game/rooms/room11/background.tscn create mode 100755 game/rooms/room11/esc/left_exit.esc create mode 100644 game/rooms/room11/esc/mysterious_circle_fadein.esc create mode 100755 game/rooms/room11/esc/mysterious_circle_nohud.esc create mode 100644 game/rooms/room11/esc/mysterious_circle_nosave.esc create mode 100755 game/rooms/room11/esc/mysterious_circle_nott.esc create mode 100755 game/rooms/room11/esc/mysterious_circle_tk.esc create mode 100755 game/rooms/room11/esc/right_exit.esc create mode 100755 game/rooms/room11/esc/room11.esc create mode 100644 game/rooms/room11/r_door.tscn create mode 100644 game/rooms/room11/room11.tscn create mode 100644 game/rooms/room11/walkable_area.tscn create mode 100644 game/rooms/room12/background.tscn create mode 100644 game/rooms/room12/esc/left_exit.esc create mode 100644 game/rooms/room12/esc/right_exit.esc create mode 100644 game/rooms/room12/esc/room12.esc create mode 100644 game/rooms/room12/r_door.tscn create mode 100644 game/rooms/room12/room12.tscn create mode 100644 game/rooms/room12/walkable_area.tscn delete mode 100644 game/ui/commons/dialogs/insets/guybrush.jpeg delete mode 100644 game/ui/commons/dialogs/insets/guybrush.jpeg.import diff --git a/.gitignore b/.gitignore index 0bb7076d..eca2952b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ bin *.import .import +*.translation diff --git a/addons/escoria-core/game/core-scripts/esc/_test/test_esc_compiler.gd b/addons/escoria-core/game/core-scripts/esc/_test/test_esc_compiler.gd index 4c69d8a4..dc183dcf 100644 --- a/addons/escoria-core/game/core-scripts/esc/_test/test_esc_compiler.gd +++ b/addons/escoria-core/game/core-scripts/esc/_test/test_esc_compiler.gd @@ -173,7 +173,6 @@ func _test_event_flags() -> bool: :test | TK :test2 | TK NO_TT :test3 | TK NO_TT NO_HUD -:test4 | TK NO_TT CUT_BLACK """ var script = escoria.esc_compiler.compile(esc.split("\n")) @@ -200,12 +199,6 @@ func _test_event_flags() -> bool: assert(subject.flags & ESCEvent.FLAG_NO_TT != 0) assert(subject.flags & ESCEvent.FLAG_NO_HUD != 0) - subject = script.events["test4"] - assert(subject.name == "test4") - assert(subject.flags & ESCEvent.FLAG_TK != 0) - assert(subject.flags & ESCEvent.FLAG_NO_TT != 0) - assert(subject.flags & ESCEvent.FLAG_NO_HUD == 0) - assert(subject.flags & ESCEvent.FLAG_CUT_BLACK != 0) return true diff --git a/addons/escoria-core/game/core-scripts/esc/commands/change_scene.gd b/addons/escoria-core/game/core-scripts/esc/commands/change_scene.gd index 74a78c11..67a89fc2 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/change_scene.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/change_scene.gd @@ -1,8 +1,12 @@ -# `change_scene path run_events` +# `change_scene path [disable_automatic_transition] [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. +# Loads a new scene, specified by "path". +# The `disable_automatic_transition` is a boolean (default false) can be set +# to true to disable automatic transitions between scenes, to allow you +# to control your transitions manually using the `transition` command. +# 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. # # @ESC extends ESCBaseCommand @@ -13,8 +17,8 @@ class_name ChangeSceneCommand func configure() -> ESCCommandArgumentDescriptor: return ESCCommandArgumentDescriptor.new( 1, - [TYPE_STRING, TYPE_BOOL], - [null, true] + [TYPE_STRING, TYPE_BOOL, TYPE_BOOL], + [null, false, true] ) @@ -42,9 +46,11 @@ func validate(arguments: Array) -> bool: # Run the command func run(command_params: Array) -> int: - escoria.logger.info("Changing scene to %s (run_events = %s)" % [ - command_params[0], - command_params[1] + escoria.logger.info( + "Changing scene to %s (disable_automatic_transition = %s, run_events = %s)" % [ + command_params[0], + command_params[1], + command_params[2] ]) if escoria.main.current_scene: @@ -53,9 +59,10 @@ func run(command_params: Array) -> int: escoria.main.current_scene.global_id, true ) - - escoria.main.scene_transition.fade_out() - yield(escoria.main.scene_transition, "transition_done") + + if !command_params[1]: + escoria.main.scene_transition.transition_out() + yield(escoria.main.scene_transition, "transition_done") escoria.inputs_manager.clear_stack() @@ -85,7 +92,7 @@ func run(command_params: Array) -> int: escoria.main.set_scene(room_scene) if "esc_script" in room_scene and room_scene.esc_script \ - and command_params[1]: + and command_params[2]: var script = escoria.esc_compiler.load_esc_file( room_scene.esc_script @@ -99,8 +106,9 @@ func run(command_params: Array) -> int: if rc[0] != ESCExecution.RC_OK: return rc[0] - escoria.main.scene_transition.fade_in() - yield(escoria.main.scene_transition, "transition_done") + if !command_params[1]: + escoria.main.scene_transition.transition_in() + yield(escoria.main.scene_transition, "transition_done") if script.events.has("ready"): escoria.event_manager.queue_event(script.events["ready"]) @@ -110,6 +118,11 @@ func run(command_params: Array) -> int: if rc[0] != ESCExecution.RC_OK: return rc[0] + else: + if !command_params[1]: + escoria.main.scene_transition.transition_in() + yield(escoria.main.scene_transition, "transition_done") + # Clear queued resources escoria.resource_cache.clear() diff --git a/addons/escoria-core/game/core-scripts/esc/commands/transition.gd b/addons/escoria-core/game/core-scripts/esc/commands/transition.gd new file mode 100644 index 00000000..fcb24952 --- /dev/null +++ b/addons/escoria-core/game/core-scripts/esc/commands/transition.gd @@ -0,0 +1,45 @@ +# `transition transition_name in|out` +# +# Performs a transition in our out manually. +# +# @ESC +extends ESCBaseCommand +class_name TransitionCommand + + +# Return the descriptor of the arguments of this command +func configure() -> ESCCommandArgumentDescriptor: + return ESCCommandArgumentDescriptor.new( + 2, + [TYPE_STRING, TYPE_STRING], + [null, null] + ) + + +# Validate wether the given arguments match the command descriptor +func validate(arguments: Array): + if not escoria.main.scene_transition.has_transition(arguments[0]): + escoria.logger.report_errors( + "transition: argument invalid", + [ + "transition with name '%s' doesn't exist" % arguments[0] + ] + ) + return false + if not arguments[1] in ["in", "out"]: + escoria.logger.report_errors( + "transition: argument invalid", + [ + "'in' or 'out' expected, but got '%s'" % arguments[1] + ] + ) + return false + return .validate(arguments) + + +# Run the command +func run(command_params: Array) -> int: + var transition_player = escoria.main.scene_transition + transition_player.call("transition_%s" % command_params[1], command_params[0]) + var animation_finished = yield(transition_player, "transition_done") + return ESCExecution.RC_OK diff --git a/addons/escoria-core/game/core-scripts/esc/types/esc_event.gd b/addons/escoria-core/game/core-scripts/esc/types/esc_event.gd index 036208ef..a17be15b 100644 --- a/addons/escoria-core/game/core-scripts/esc/types/esc_event.gd +++ b/addons/escoria-core/game/core-scripts/esc/types/esc_event.gd @@ -12,8 +12,8 @@ class_name ESCEvent # Regex identifying an ESC event const REGEX = \ - '^:(?[^|]+)( \\|(?( ' + \ - '(TK|NO_TT|NO_HUD|NO_SAVE|CUT_BLACK|LEAVE_BLACK)' + \ + '^:(?[^|]+)( \\|\\s*(?( ' + \ + '(TK|NO_TT|NO_HUD|NO_SAVE)' + \ ')+))?$' @@ -28,19 +28,11 @@ const REGEX = \ # 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. enum { FLAG_TK = 1, FLAG_NO_TT = 2, FLAG_NO_HUD = 4, - FLAG_NO_SAVE = 8, - FLAG_CUT_BLACK = 16, - FLAG_LEAVE_BLACK = 32 + FLAG_NO_SAVE = 8 } @@ -74,10 +66,6 @@ func _init(event_string: String): self.flags |= FLAG_NO_HUD if "NO_SAVE" in _flags: self.flags |= FLAG_NO_SAVE - if "CUT_BLACK" in _flags: - self.flags |= FLAG_CUT_BLACK - if "LEAVE_BLACK" in _flags: - self.flags |= FLAG_LEAVE_BLACK else: escoria.logger.report_errors( "Invalid event detected: %s" % event_string, diff --git a/addons/escoria-core/game/core-scripts/esc_controller.gd b/addons/escoria-core/game/core-scripts/esc_controller.gd index 6649d44b..284530df 100644 --- a/addons/escoria-core/game/core-scripts/esc_controller.gd +++ b/addons/escoria-core/game/core-scripts/esc_controller.gd @@ -96,6 +96,12 @@ func perform_inputevent_on_object( escoria.logger.info("%s left-clicked with event " % obj.global_id, [event]) + var event_flags = 0 + var has_current_action: bool = false + if obj.events.has(escoria.action_manager.current_action): + event_flags = obj.events[escoria.action_manager.current_action].flags + has_current_action = true + # Don't interact after player movement towards object # (because object is inactive for example) var dont_interact = false @@ -105,20 +111,21 @@ func perform_inputevent_on_object( # If clicked object not in inventory, player walks towards it if not obj.node is ESCPlayer and \ - not escoria.inventory_manager.inventory_has(obj.global_id): - var context = _walk_towards_object( - obj, - event.position, - event.doubleclick - ) - if context is GDScriptFunctionState: - context = yield(_walk_towards_object( + not escoria.inventory_manager.inventory_has(obj.global_id) and \ + (not has_current_action or not event_flags & ESCEvent.FLAG_TK): + var context = _walk_towards_object( obj, event.position, event.doubleclick - ), "completed") - destination_position = context.target_position - dont_interact = context.dont_interact_on_arrival + ) + if context is GDScriptFunctionState: + context = yield(_walk_towards_object( + obj, + event.position, + event.doubleclick + ), "completed") + destination_position = context.target_position + dont_interact = context.dont_interact_on_arrival # If no interaction should happen after player has arrived, leave # immediately. @@ -131,6 +138,50 @@ func perform_inputevent_on_object( # If player has arrived at the position he was supposed to reach # so he can interact if player_global_pos == destination_position: + + # If NO_TT flag is active, hide tooltip and connect for + # event finished to show it back + if event_flags & ESCEvent.FLAG_NO_TT \ + and not escoria.event_manager.is_connected( + "event_finished", + self, + "_on_no_tooltip_event_finished" + ): + escoria.main.current_scene.game.tooltip_node.hide() + escoria.event_manager.connect( + "event_finished", + self, + "_on_no_tooltip_event_finished" + ) + + if event_flags & ESCEvent.FLAG_NO_HUD and \ + not escoria.event_manager.is_connected( + "event_finished", + self, + "_on_no_hud_event_finished" + ): + escoria.main.current_scene.game.hide_ui() + escoria.event_manager.connect( + "event_finished", + self, + "_on_no_hud_event_finished" + ) + + if event_flags & ESCEvent.FLAG_NO_SAVE and \ + not escoria.event_manager.is_connected( + "event_finished", + self, + "_on_no_save_event_finished" + ): + escoria.save_manager.save_enabled = false + escoria.event_manager.connect( + "event_finished", + self, + "_on_no_save_event_finished" + ) + pass + + # Manage exits if obj.node.is_exit and escoria.action_manager.current_action \ in ["", "walk"]: @@ -246,3 +297,63 @@ func _walk_towards_object( walk_context.dont_interact_on_arrival = true return context + + +# Called when an event having "NO_TT" flag is finished. +# +# ## Parameters +# +# - _return_code: The ESCExecution return code sent by the events manager. +# - _event_name: the name of the event +func _on_no_tooltip_event_finished(_return_code: int, _event_name: String): + escoria.main.current_scene.game.tooltip_node.show() + if escoria.event_manager.is_connected( + "event_finished", + self, + "_on_no_tooltip_event_finished" + ): + escoria.event_manager.disconnect( + "event_finished", + self, + "_on_no_tooltip_event_finished" + ) + + +# Called when an event having "NO_HUD" flag is finished. +# +# ## Parameters +# +# - _return_code: The ESCExecution return code sent by the events manager. +# - _event_name: the name of the event +func _on_no_hud_event_finished(_return_code: int, _event_name: String): + escoria.main.current_scene.game.show_ui() + if escoria.event_manager.is_connected( + "event_finished", + self, + "_on_no_hud_event_finished" + ): + escoria.event_manager.disconnect( + "event_finished", + self, + "_on_no_hud_event_finished" + ) + + +# Called when an event having "NO_SAVE" flag is finished. +# +# ## Parameters +# +# - _return_code: The ESCExecution return code sent by the events manager. +# - _event_name: the name of the event +func _on_no_save_event_finished(_return_code: int, _event_name: String): + escoria.save_manager.save_enabled = true + if escoria.event_manager.is_connected( + "event_finished", + self, + "_on_no_save_event_finished" + ): + escoria.event_manager.disconnect( + "event_finished", + self, + "_on_no_save_event_finished" + ) diff --git a/addons/escoria-core/game/core-scripts/save_data/esc_save_manager.gd b/addons/escoria-core/game/core-scripts/save_data/esc_save_manager.gd index 84276b51..bc07d1e2 100644 --- a/addons/escoria-core/game/core-scripts/save_data/esc_save_manager.gd +++ b/addons/escoria-core/game/core-scripts/save_data/esc_save_manager.gd @@ -1,6 +1,9 @@ # Saves and loads savegame and settings files class_name ESCSaveManager +# If true, saving a game is enabled. Else, saving is disabled +var save_enabled: bool = true + # Variable containing the saves folder obtained from Project Settings var save_folder: String @@ -65,6 +68,12 @@ func save_game_exists(id: int) -> bool: # - id: integer suffix of the savegame file # - p_savename: name of the savegame func save_game(id: int, p_savename: String): + if not save_enabled: + escoria.logger.debug( + "esc_save_data_resources.gd", + ["Save requested while saving is not possible. Save canceled."]) + return + var save_game := ESCSaveGame.new() save_game.escoria_version = escoria.ESCORIA_VERSION save_game.game_version = ProjectSettings.get_setting( diff --git a/addons/escoria-core/game/scenes/transitions/shaders/transition.material b/addons/escoria-core/game/scenes/transitions/shaders/transition.material index fdefbda7a10da20024c749e74f035794e9081eae..c730e79a32a09096e9263f21b411e68bb2aaa329 100644 GIT binary patch delta 547 zcmV+;0^I$=1jht_Qd2`i0ssI201yBGEd&4nF9HAnD77#BU@ZeJ5dh{JT|7{2k`BFN8y{f7zqlz?xENEnxkL*2`cWXrMF6R_8R|jZt?WXpijRmGixAO+q)$UDXf9@Snhcif^DB6};y(-GXxmNFz&~Gg1eaq**K1;`Rn>L5zaq z%Y5uHE!&Wh`Y?ZSs1zYADn!KR!hZvw(3<4`3L2CS%KvA8_#qi19+dbXal*v^CcuF8 zVL^@KQR#=7FbYQn4h_hHn&yH<9t?&-a3VMi#g$IjTBvEEei{uKn8Q>yVO&jnfh-TJ zVXEX<*_POY^Aba-F{u*}WoTq1pfG^~=P&|85L0&t5ySm5dg+pTsu&0k`BFN8y{f7zqpFU;b~duhNA@1eyEP(rmvf4ls{=H+v8g@i_-)Bynk-u41Dr5pO^;#! zr$qor08IeVf`3%l6E+n!KZ)R#g6-&ki&K_R;upnPY32BTP4_>*Ij%Htmh5OWYc#E! zQ^c;TNxA=SjSR?wn&yH<9t?&(a3GU$0T+L)4y$3RB^$?JdX5N0} S7v<+ti|g);BLD+ZQ$s^bLGxb# diff --git a/addons/escoria-core/game/scenes/transitions/transition.gd b/addons/escoria-core/game/scenes/transitions/transition.gd index 3df22249..2c38988d 100644 --- a/addons/escoria-core/game/scenes/transitions/transition.gd +++ b/addons/escoria-core/game/scenes/transitions/transition.gd @@ -1,40 +1,68 @@ # A transition player for scene changes extends ColorRect - # Emitted when the transition was played signal transition_done -# The name of the transition to play +# The name of the default transition to play export( String, "fade_black", "fade_white", - "transition_in", - "transition_out" + "curtain" ) var transition_name: String + # Reference to the _AnimationPlayer_ node onready var _anim_player := $AnimationPlayer # Fade in when the scene is starting func _ready() -> void: - fade_in() + transition_in() -# Fade out the transition -func fade_out() -> void: - _anim_player.play(transition_name) +# Transition out +# +# ## Parameters +# +# - p_transition_name: name of the transition to play (if empty string, uses +# the default transition) +func transition_out(p_transition_name: String = "") -> void: + if p_transition_name.empty(): + _anim_player.play(transition_name) + else: + _anim_player.play(p_transition_name) yield(_anim_player, "animation_finished") emit_signal("transition_done") + _anim_player.seek(0.0) - -# Fade in the transition -func fade_in() -> void: - # Plays the Fade animation and wait until it finishes - _anim_player.play_backwards(transition_name) + +# Transition in +# +# ## Parameters +# +# - p_transition_name: name of the transition to play (if empty string, uses +# the default transition) +func transition_in(p_transition_name: String = "") -> void: + if p_transition_name.empty(): + _anim_player.play_backwards(transition_name) + else: + _anim_player.play_backwards(p_transition_name) yield(_anim_player, "animation_finished") emit_signal("transition_done") + _anim_player.seek(0.0) + + +# Returns true whether the transition scene has a transition corresponding +# to name provided. +# +# ## Parameters +# +# - p_name: The name of the transition to test +# +# *Returns* true if a transition exists with given name. +func has_transition(p_name: String) -> bool: + return _anim_player.has_animation(p_name) diff --git a/addons/escoria-core/game/scenes/transitions/transition.tscn b/addons/escoria-core/game/scenes/transitions/transition.tscn index 52777e84..db5ceb28 100644 --- a/addons/escoria-core/game/scenes/transitions/transition.tscn +++ b/addons/escoria-core/game/scenes/transitions/transition.tscn @@ -1,8 +1,47 @@ -[gd_scene load_steps=7 format=2] +[gd_scene load_steps=6 format=2] [ext_resource path="res://addons/escoria-core/game/scenes/transitions/transition.gd" type="Script" id=1] [ext_resource path="res://addons/escoria-core/game/scenes/transitions/shaders/transition.material" type="Material" id=2] +[sub_resource type="Animation" id=3] +resource_name = "curtain" +tracks/0/type = "value" +tracks/0/path = NodePath(".:material:shader_param/cutoff") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/keys = { +"times": PoolRealArray( 0, 1 ), +"transitions": PoolRealArray( 1, 1 ), +"update": 0, +"values": [ 0.0, 1.0 ] +} +tracks/1/type = "value" +tracks/1/path = NodePath(".:material:shader_param/color") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 0, +"values": [ Color( 0, 0, 0, 1 ) ] +} +tracks/2/type = "value" +tracks/2/path = NodePath(".:modulate") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 0, +"values": [ Color( 1, 1, 1, 1 ) ] +} + [sub_resource type="Animation" id=1] resource_name = "fade_black" length = 0.5 @@ -18,6 +57,30 @@ tracks/0/keys = { "update": 0, "values": [ Color( 0, 0, 0, 0 ), Color( 0, 0, 0, 1 ) ] } +tracks/1/type = "value" +tracks/1/path = NodePath(".:material:shader_param/cutoff") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 0, +"values": [ 0.0 ] +} +tracks/2/type = "value" +tracks/2/path = NodePath(".:material:shader_param/color") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 0, +"values": [ Color( 0, 0, 0, 1 ) ] +} [sub_resource type="Animation" id=2] resource_name = "fade_white" @@ -34,38 +97,33 @@ tracks/0/keys = { "update": 0, "values": [ Color( 1, 1, 1, 0 ), Color( 1, 1, 1, 1 ) ] } - -[sub_resource type="Animation" id=3] -resource_name = "transition_in" -tracks/0/type = "value" -tracks/0/path = NodePath(".:material:shader_param/cutoff") -tracks/0/interp = 1 -tracks/0/loop_wrap = true -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/keys = { -"times": PoolRealArray( 0, 1 ), -"transitions": PoolRealArray( 1, 1 ), +tracks/1/type = "value" +tracks/1/path = NodePath(".:material:shader_param/cutoff") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), "update": 0, -"values": [ 0.0, 1.0 ] +"values": [ 0.0 ] } - -[sub_resource type="Animation" id=4] -resource_name = "transition_out" -tracks/0/type = "value" -tracks/0/path = NodePath(".:material:shader_param/cutoff") -tracks/0/interp = 1 -tracks/0/loop_wrap = true -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/keys = { -"times": PoolRealArray( 0, 1 ), -"transitions": PoolRealArray( 1, 1 ), +tracks/2/type = "value" +tracks/2/path = NodePath(".:material:shader_param/color") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), "update": 0, -"values": [ 1.0, 0.0 ] +"values": [ Color( 1, 1, 1, 1 ) ] } [node name="scene_transition" type="ColorRect"] +modulate = Color( 0, 0, 0, 0 ) material = ExtResource( 2 ) anchor_right = 1.0 anchor_bottom = 1.0 @@ -74,10 +132,9 @@ script = ExtResource( 1 ) __meta__ = { "_edit_use_anchors_": false } -transition_name = "transition_out" +transition_name = "curtain" [node name="AnimationPlayer" type="AnimationPlayer" parent="."] +anims/curtain = SubResource( 3 ) anims/fade_black = SubResource( 1 ) anims/fade_white = SubResource( 2 ) -anims/transition_in = SubResource( 3 ) -anims/transition_out = SubResource( 4 ) diff --git a/addons/escoria-ui-9verbs/game.gd b/addons/escoria-ui-9verbs/game.gd index 2b902688..94530fef 100644 --- a/addons/escoria-ui-9verbs/game.gd +++ b/addons/escoria-ui-9verbs/game.gd @@ -178,6 +178,7 @@ func pause_game(): escoria.main.current_scene.show() escoria.set_game_paused(false) else: + $ui/pause_menu.set_save_enabled(escoria.save_manager.save_enabled) $ui/pause_menu.show() escoria.main.current_scene.game.get_node("camera").current = false escoria.main.current_scene.game.hide_ui() diff --git a/addons/escoria-ui-simplemouse/game.gd b/addons/escoria-ui-simplemouse/game.gd index 3ce595b6..8a9f38df 100644 --- a/addons/escoria-ui-simplemouse/game.gd +++ b/addons/escoria-ui-simplemouse/game.gd @@ -159,6 +159,7 @@ func pause_game(): escoria.main.current_scene.game.show_ui() escoria.main.current_scene.show() else: + $ui/pause_menu.set_save_enabled(escoria.save_manager.save_enabled) $ui/pause_menu.show() escoria.main.current_scene.game.get_node("camera").current = false escoria.main.current_scene.game.hide_ui() diff --git a/docs/api/ChangeSceneCommand.md b/docs/api/ChangeSceneCommand.md index e6a32f27..90630e49 100644 --- a/docs/api/ChangeSceneCommand.md +++ b/docs/api/ChangeSceneCommand.md @@ -6,11 +6,15 @@ ## Description -`change_scene path run_events` +`change_scene path [disable_automatic_transition] [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. +Loads a new scene, specified by "path". + The `disable_automatic_transition` is a boolean (default false) can be set +to true to disable automatic transitions between scenes, to allow you +to control your transitions manually using the `transition` command. +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. @ESC diff --git a/docs/api/ESCEvent.md b/docs/api/ESCEvent.md index ee77daa5..de407eff 100644 --- a/docs/api/ESCEvent.md +++ b/docs/api/ESCEvent.md @@ -17,18 +17,6 @@ Events are triggered from various sources. Common events include ## Constants Descriptions -### FLAG\_CUT\_BLACK - -```gdscript -const FLAG_CUT_BLACK: int = 16 -``` - -### FLAG\_LEAVE\_BLACK - -```gdscript -const FLAG_LEAVE_BLACK: int = 32 -``` - ### FLAG\_NO\_HUD ```gdscript @@ -56,7 +44,7 @@ const FLAG_TK: int = 1 ### REGEX ```gdscript -const REGEX: String = "^:(?[^|]+)( \\|(?( (TK|NO_TT|NO_HUD|NO_SAVE|CUT_BLACK|LEAVE_BLACK))+))?$" +const REGEX: String = "^:(?[^|]+)( \\|\\s*(?( (TK|NO_TT|NO_HUD|NO_SAVE))+))?$" ``` Regex identifying an ESC event diff --git a/docs/api/ESCSaveManager.md b/docs/api/ESCSaveManager.md index 48f5f9f1..dc3ee69b 100644 --- a/docs/api/ESCSaveManager.md +++ b/docs/api/ESCSaveManager.md @@ -22,6 +22,14 @@ Template for settings filename ## Property Descriptions +### save\_enabled + +```gdscript +var save_enabled: bool = true +``` + +If true, saving a game is enabled. Else, saving is disabled + ### save\_folder ```gdscript diff --git a/docs/api/TransitionCommand.md b/docs/api/TransitionCommand.md new file mode 100644 index 00000000..a425971a --- /dev/null +++ b/docs/api/TransitionCommand.md @@ -0,0 +1,39 @@ + + +# TransitionCommand + +**Extends:** [ESCBaseCommand](../ESCBaseCommand) < [Node](../Node) + +## Description + +`transition transition_name in|out` + +Performs a transition in our out manually. + +@ESC + +## Method Descriptions + +### configure + +```gdscript +func configure() -> ESCCommandArgumentDescriptor +``` + +Return the descriptor of the arguments of this command + +### validate + +```gdscript +func validate(arguments: Array) +``` + +Validate wether the given arguments match the command descriptor + +### run + +```gdscript +func run(command_params: Array) -> var +``` + +Run the command \ No newline at end of file diff --git a/docs/api/transition.gd.md b/docs/api/transition.gd.md index 13a636fa..71e9c5bd 100644 --- a/docs/api/transition.gd.md +++ b/docs/api/transition.gd.md @@ -18,21 +18,46 @@ export var transition_name: String = "" ## Method Descriptions -### fade\_out +### transition\_out ```gdscript -func fade_out() -> var +func transition_out(p_transition_name: String = "") -> var ``` -Fade out the transition +Transition out -### fade\_in +## Parameters + +- p_transition_name: name of the transition to play (if empty string, uses +the default transition) + +### transition\_in ```gdscript -func fade_in() -> var +func transition_in(p_transition_name: String = "") -> var ``` -Fade in the transition +Transition in + +## Parameters + +- p_transition_name: name of the transition to play (if empty string, uses +the default transition) + +### has\_transition + +```gdscript +func has_transition(p_name: String) -> bool +``` + +Returns true whether the transition scene has a transition corresponding +to name provided. + +## Parameters + +- p_name: The name of the transition to test + +*Returns* true if a transition exists with given name. ## Signals diff --git a/docs/esc.md b/docs/esc.md index e0f4e0df..001ccf69 100644 --- a/docs/esc.md +++ b/docs/esc.md @@ -193,11 +193,15 @@ to zoom into position. 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. -#### `change_scene path run_events` [API-Doc](api/ChangeSceneCommand.md) +#### `change_scene path [disable_automatic_transition] [run_events]` [API-Doc](api/ChangeSceneCommand.md) -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. +Loads a new scene, specified by "path". + The `disable_automatic_transition` is a boolean (default false) can be set +to true to disable automatic transitions between scenes, to allow you +to control your transitions manually using the `transition` command. +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. #### `custom object node func_name [params]` [API-Doc](api/CustomCommand.md) Calls the function `func_name` of the node `node` of object `object` with @@ -344,6 +348,9 @@ Sets the position of object1 to the position of object2. #### `teleport_pos object1 x y` [API-Doc](api/TeleportPosCommand.md) Sets the position of object1 to the position (x,y). +#### `transition transition_name in|out` [API-Doc](api/TransitionCommand.md) + +Performs a transition in our out manually. #### `turn_to object degrees [immediate]` [API-Doc](api/TurnToCommand.md) Turns object to a degrees angle with a directions animation. diff --git a/game/items/inventory/bottle.tscn b/game/items/inventory/bottle.tscn index 0aec0e18..f4a3d874 100644 --- a/game/items/inventory/bottle.tscn +++ b/game/items/inventory/bottle.tscn @@ -3,7 +3,7 @@ [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"] +[node name="bottle" type="TextureButton"] margin_right = 50.0 margin_bottom = 140.0 texture_normal = ExtResource( 2 ) @@ -11,4 +11,3 @@ script = ExtResource( 1 ) __meta__ = { "_edit_use_anchors_": false } -global_id = "r9_bottle" diff --git a/game/rooms/room01/r_door.tscn b/game/rooms/room01/r_door.tscn new file mode 100644 index 00000000..39b4fa38 --- /dev/null +++ b/game/rooms/room01/r_door.tscn @@ -0,0 +1,25 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_location.gd" type="Script" id=2] + +[node name="r_door" type="Area2D"] +pause_mode = 1 +script = ExtResource( 1 ) +__meta__ = { +"_editor_description_": "" +} +global_id = "r1_r_exit" +esc_script = "res://game/rooms/room01/esc/right_exit.esc" +is_exit = true +tooltip_name = "Exit" +default_action = "walk" +dialog_color = Color( 1, 1, 1, 1 ) +animations = null + +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="."] +polygon = PoolVector2Array( 1177.94, 348.61, 1175.95, 45.3759, 1276.06, 92.0953, 1277.95, 399.407 ) + +[node name="Position2D" type="Position2D" parent="."] +position = Vector2( 1225.47, 353.99 ) +script = ExtResource( 2 ) diff --git a/game/rooms/room01/room01.tscn b/game/rooms/room01/room01.tscn index bcf5dd15..1102a342 100644 --- a/game/rooms/room01/room01.tscn +++ b/game/rooms/room01/room01.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=8 format=2] +[gd_scene load_steps=9 format=2] [ext_resource path="res://game/rooms/room01/walkable_area.tscn" type="PackedScene" id=1] [ext_resource path="res://game/rooms/room01/background.tscn" type="PackedScene" id=2] @@ -7,6 +7,7 @@ [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://addons/escoria-core/game/core-scripts/esc_location.gd" type="Script" id=7] +[ext_resource path="res://game/rooms/room01/r_door.tscn" type="PackedScene" id=8] [node name="room1" type="Node2D"] script = ExtResource( 6 ) @@ -47,26 +48,7 @@ position = Vector2( 3.5636, 0 ) [node name="Hotspots" type="Node2D" parent="."] -[node name="r_door" type="Area2D" parent="Hotspots"] -pause_mode = 1 -script = ExtResource( 5 ) -__meta__ = { -"_editor_description_": "" -} -global_id = "r1_r_exit" -esc_script = "res://game/rooms/room01/esc/right_exit.esc" -is_exit = true -tooltip_name = "Exit" -default_action = "walk" -dialog_color = Color( 1, 1, 1, 1 ) -animations = null - -[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="Hotspots/r_door"] -polygon = PoolVector2Array( 1177.94, 348.61, 1175.95, 45.3759, 1276.06, 92.0953, 1277.95, 399.407 ) - -[node name="Position2D" type="Position2D" parent="Hotspots/r_door"] -position = Vector2( 1225.47, 353.99 ) -script = ExtResource( 7 ) +[node name="r_door" parent="Hotspots" instance=ExtResource( 8 )] [node name="item" type="Area2D" parent="Hotspots"] pause_mode = 1 diff --git a/game/rooms/room10/background.tscn b/game/rooms/room10/background.tscn index aa350e6d..fa42fc10 100644 --- a/game/rooms/room10/background.tscn +++ b/game/rooms/room10/background.tscn @@ -21,3 +21,10 @@ points = PoolVector2Array( 6.61201, 704.409, 6.61203, 389.558, 87.755, 339.775, __meta__ = { "_editor_description_": "" } + +[node name="r_door" type="Line2D" parent="."] +position = Vector2( 0, -267.828 ) +points = PoolVector2Array( 1175.07, 620.086, 1171.24, 311.267, 1274.8, 356.87, 1278.31, 672.412, 1188.64, 624.843 ) +__meta__ = { +"_editor_description_": "" +} diff --git a/game/rooms/room10/esc/right_exit.esc b/game/rooms/room10/esc/right_exit.esc index 25d9ba02..d2009491 100755 --- a/game/rooms/room10/esc/right_exit.esc +++ b/game/rooms/room10/esc/right_exit.esc @@ -1,2 +1,3 @@ :exit_scene - +set_sound_state bg_sound res://game/sfx/sounds/doorOpen_2.ogg false +change_scene "res://game/rooms/room11/room11.tscn" diff --git a/game/rooms/room10/r_door.tscn b/game/rooms/room10/r_door.tscn index f4877aff..39b4fa38 100644 --- a/game/rooms/room10/r_door.tscn +++ b/game/rooms/room10/r_door.tscn @@ -1,130 +1,25 @@ -[gd_scene load_steps=4 format=2] +[gd_scene load_steps=3 format=2] [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" -tracks/0/type = "value" -tracks/0/path = NodePath("r_door_closed:visible") -tracks/0/interp = 1 -tracks/0/loop_wrap = true -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/keys = { -"times": PoolRealArray( 0 ), -"transitions": PoolRealArray( 1 ), -"update": 1, -"values": [ true ] -} -tracks/1/type = "value" -tracks/1/path = NodePath("r_door_opened:visible") -tracks/1/interp = 1 -tracks/1/loop_wrap = true -tracks/1/imported = false -tracks/1/enabled = true -tracks/1/keys = { -"times": PoolRealArray( 0 ), -"transitions": PoolRealArray( 1 ), -"update": 1, -"values": [ false ] -} -tracks/2/type = "value" -tracks/2/path = NodePath(".:is_exit") -tracks/2/interp = 1 -tracks/2/loop_wrap = true -tracks/2/imported = false -tracks/2/enabled = true -tracks/2/keys = { -"times": PoolRealArray( 0 ), -"transitions": PoolRealArray( 1 ), -"update": 1, -"values": [ false ] -} -tracks/3/type = "value" -tracks/3/path = NodePath(".:default_action") -tracks/3/interp = 1 -tracks/3/loop_wrap = true -tracks/3/imported = false -tracks/3/enabled = true -tracks/3/keys = { -"times": PoolRealArray( 0 ), -"transitions": PoolRealArray( 1 ), -"update": 1, -"values": [ "look" ] -} - -[sub_resource type="Animation" id=2] -resource_name = "r_door_open" -length = 0.3 -tracks/0/type = "value" -tracks/0/path = NodePath("r_door_closed:visible") -tracks/0/interp = 1 -tracks/0/loop_wrap = true -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/keys = { -"times": PoolRealArray( 0 ), -"transitions": PoolRealArray( 1 ), -"update": 1, -"values": [ false ] -} -tracks/1/type = "value" -tracks/1/path = NodePath("r_door_opened:visible") -tracks/1/interp = 1 -tracks/1/loop_wrap = true -tracks/1/imported = false -tracks/1/enabled = true -tracks/1/keys = { -"times": PoolRealArray( 0 ), -"transitions": PoolRealArray( 1 ), -"update": 1, -"values": [ true ] -} -tracks/2/type = "value" -tracks/2/path = NodePath(".:is_exit") -tracks/2/interp = 1 -tracks/2/loop_wrap = true -tracks/2/imported = false -tracks/2/enabled = true -tracks/2/keys = { -"times": PoolRealArray( 0 ), -"transitions": PoolRealArray( 1 ), -"update": 1, -"values": [ true ] -} -tracks/3/type = "value" -tracks/3/path = NodePath(".:default_action") -tracks/3/interp = 1 -tracks/3/loop_wrap = true -tracks/3/imported = false -tracks/3/enabled = true -tracks/3/keys = { -"times": PoolRealArray( 0 ), -"transitions": PoolRealArray( 1 ), -"update": 1, -"values": [ "walk" ] -} +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_location.gd" type="Script" id=2] [node name="r_door" type="Area2D"] +pause_mode = 1 script = ExtResource( 1 ) -global_id = "r9_door" -esc_script = "res://game/rooms/room9/esc/r9_door.esc" -tooltip_name = "Door" -default_action = "look" +__meta__ = { +"_editor_description_": "" +} +global_id = "r1_r_exit" +esc_script = "res://game/rooms/room01/esc/right_exit.esc" +is_exit = true +tooltip_name = "Exit" +default_action = "walk" dialog_color = Color( 1, 1, 1, 1 ) - -[node name="r_door_closed" type="Polygon2D" parent="."] -color = Color( 0.482353, 0.568627, 1, 1 ) -polygon = PoolVector2Array( 1172.3, 44.8186, 1172.3, 348.012, 1273.9, 401.983, 1277.07, 89.2657 ) - -[node name="r_door_opened" type="Polygon2D" parent="."] -visible = false -color = Color( 0.482353, 0.568627, 1, 1 ) -polygon = PoolVector2Array( 1172.3, 44.8186, 1172.3, 348.012, 1029.82, 349.887, 1025.19, 42.1269 ) - -[node name="AnimationPlayer" type="AnimationPlayer" parent="."] -anims/r_door_close = SubResource( 1 ) -anims/r_door_open = SubResource( 2 ) +animations = null [node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="."] -polygon = PoolVector2Array( 1169.35, 41.7644, 1168.09, 347.925, 1275.18, 407.141, 1278.96, 88.3814 ) +polygon = PoolVector2Array( 1177.94, 348.61, 1175.95, 45.3759, 1276.06, 92.0953, 1277.95, 399.407 ) + +[node name="Position2D" type="Position2D" parent="."] +position = Vector2( 1225.47, 353.99 ) +script = ExtResource( 2 ) diff --git a/game/rooms/room10/room10.tscn b/game/rooms/room10/room10.tscn index 86c552a4..8db4ec33 100644 --- a/game/rooms/room10/room10.tscn +++ b/game/rooms/room10/room10.tscn @@ -49,6 +49,7 @@ __meta__ = { [node name="Hotspots" type="Node2D" parent="."] [node name="l_door" type="Area2D" parent="Hotspots"] +pause_mode = 1 script = ExtResource( 7 ) global_id = "r10_l_exit" esc_script = "res://game/rooms/room10/esc/left_exit.esc" @@ -66,14 +67,15 @@ position = Vector2( 37.4521, 392.045 ) script = ExtResource( 5 ) [node name="r_door" parent="Hotspots" instance=ExtResource( 9 )] +global_id = "r10_r_exit" esc_script = "res://game/rooms/room10/esc/right_exit.esc" -animations = null [node name="Position2D" type="Position2D" parent="Hotspots/r_door"] position = Vector2( 1198.65, 391.058 ) script = ExtResource( 5 ) [node name="button_stop_bg_music" parent="Hotspots" instance=ExtResource( 8 )] +pause_mode = 1 position = Vector2( 243.165, 154.97 ) global_id = "r10_btn_stop_bg_music" esc_script = "res://game/rooms/room10/esc/button_stop_bg_music.esc" @@ -95,6 +97,7 @@ __meta__ = { } [node name="button_play_bg_music" parent="Hotspots" instance=ExtResource( 8 )] +pause_mode = 1 position = Vector2( 377.976, 154.97 ) global_id = "r10_btn_play_bg_music" esc_script = "res://game/rooms/room10/esc/button_play_bg_music.esc" @@ -116,6 +119,7 @@ __meta__ = { } [node name="button_play_sound" parent="Hotspots" instance=ExtResource( 8 )] +pause_mode = 1 position = Vector2( 646.339, 154.97 ) global_id = "r10_btn_play_snd" esc_script = "res://game/rooms/room10/esc/button_play_snd.esc" @@ -137,6 +141,7 @@ __meta__ = { } [node name="button_accept_input" parent="Hotspots" instance=ExtResource( 8 )] +pause_mode = 1 position = Vector2( 823.113, 155.354 ) global_id = "test_accept_input" esc_script = "res://game/rooms/room10/esc/button_accept_input_test.esc" @@ -161,6 +166,7 @@ script = ExtResource( 5 ) global_id = "accept_input_location" [node name="button_slide" parent="Hotspots" instance=ExtResource( 8 )] +pause_mode = 1 position = Vector2( 939.497, 154.301 ) global_id = "button_slide" esc_script = "res://game/rooms/room10/esc/button_slide.esc" @@ -184,6 +190,7 @@ script = ExtResource( 5 ) global_id = "slide_location" [node name="button_turn_to" parent="Hotspots" instance=ExtResource( 8 )] +pause_mode = 1 position = Vector2( 1041.66, 152.721 ) global_id = "button_turn_to" esc_script = "res://game/rooms/room10/esc/button_turn_to.esc" diff --git a/game/rooms/room11/background.tscn b/game/rooms/room11/background.tscn new file mode 100644 index 00000000..fa42fc10 --- /dev/null +++ b/game/rooms/room11/background.tscn @@ -0,0 +1,30 @@ +[gd_scene load_steps=2 format=2] + +[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 +margin_bottom = 555.0 +mouse_filter = 2 +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="l_platform" type="Line2D" parent="."] +position = Vector2( 2, -266 ) +points = PoolVector2Array( -2.96298, 712.01, 129.973, 614.429, 1167.5, 612.894, 1274.59, 669.705, 1273.25, 812.694, 2.36697, 811.043, 2.36697, 713.389 ) + +[node name="l_door" type="Line2D" parent="."] +position = Vector2( 0, -266 ) +points = PoolVector2Array( 6.61201, 704.409, 6.61203, 389.558, 87.755, 339.775, 87.5463, 649.784 ) +__meta__ = { +"_editor_description_": "" +} + +[node name="r_door" type="Line2D" parent="."] +position = Vector2( 0, -267.828 ) +points = PoolVector2Array( 1175.07, 620.086, 1171.24, 311.267, 1274.8, 356.87, 1278.31, 672.412, 1188.64, 624.843 ) +__meta__ = { +"_editor_description_": "" +} diff --git a/game/rooms/room11/esc/left_exit.esc b/game/rooms/room11/esc/left_exit.esc new file mode 100755 index 00000000..8b620bbe --- /dev/null +++ b/game/rooms/room11/esc/left_exit.esc @@ -0,0 +1,5 @@ +:exit_scene +set_sound_state bg_sound res://game/sfx/sounds/doorOpen_2.ogg false +change_scene "res://game/rooms/room10/room10.tscn" + + diff --git a/game/rooms/room11/esc/mysterious_circle_fadein.esc b/game/rooms/room11/esc/mysterious_circle_fadein.esc new file mode 100644 index 00000000..ab057209 --- /dev/null +++ b/game/rooms/room11/esc/mysterious_circle_fadein.esc @@ -0,0 +1,5 @@ +:use +transition curtain out +wait 2 +transition fade_black in + diff --git a/game/rooms/room11/esc/mysterious_circle_nohud.esc b/game/rooms/room11/esc/mysterious_circle_nohud.esc new file mode 100755 index 00000000..a0d76617 --- /dev/null +++ b/game/rooms/room11/esc/mysterious_circle_nohud.esc @@ -0,0 +1,3 @@ +:look | NO_HUD +say player "NO_HUD" + diff --git a/game/rooms/room11/esc/mysterious_circle_nosave.esc b/game/rooms/room11/esc/mysterious_circle_nosave.esc new file mode 100644 index 00000000..d59d0fbd --- /dev/null +++ b/game/rooms/room11/esc/mysterious_circle_nosave.esc @@ -0,0 +1,3 @@ +:look | NO_SAVE +say player "NO_SAVE" + diff --git a/game/rooms/room11/esc/mysterious_circle_nott.esc b/game/rooms/room11/esc/mysterious_circle_nott.esc new file mode 100755 index 00000000..5ee3ecbb --- /dev/null +++ b/game/rooms/room11/esc/mysterious_circle_nott.esc @@ -0,0 +1,3 @@ +:look | NO_TT +say player "NO_TT." + diff --git a/game/rooms/room11/esc/mysterious_circle_tk.esc b/game/rooms/room11/esc/mysterious_circle_tk.esc new file mode 100755 index 00000000..9b7dd2fd --- /dev/null +++ b/game/rooms/room11/esc/mysterious_circle_tk.esc @@ -0,0 +1,3 @@ +:look | TK +say player "TK" + diff --git a/game/rooms/room11/esc/right_exit.esc b/game/rooms/room11/esc/right_exit.esc new file mode 100755 index 00000000..09662583 --- /dev/null +++ b/game/rooms/room11/esc/right_exit.esc @@ -0,0 +1,5 @@ +:exit_scene +set_sound_state bg_sound res://game/sfx/sounds/doorOpen_2.ogg false +transition fade_black out +change_scene "res://game/rooms/room12/room12.tscn" true + diff --git a/game/rooms/room11/esc/room11.esc b/game/rooms/room11/esc/room11.esc new file mode 100755 index 00000000..d92bd389 --- /dev/null +++ b/game/rooms/room11/esc/room11.esc @@ -0,0 +1,18 @@ + +:setup +set_state bg_music off false + +> [eq ESC_LAST_SCENE room10] + teleport player r11_l_exit + # Set player look right + set_angle player 180 + stop +> [eq ESC_LAST_SCENE room12] + teleport player r11_r_exit + # Set player look left + set_angle player 270 + stop +> [!last_scene] + teleport player player_start + stop + diff --git a/game/rooms/room11/r_door.tscn b/game/rooms/room11/r_door.tscn new file mode 100644 index 00000000..dbf63a66 --- /dev/null +++ b/game/rooms/room11/r_door.tscn @@ -0,0 +1,20 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=1] + +[node name="r_door" type="Area2D"] +pause_mode = 1 +script = ExtResource( 1 ) +__meta__ = { +"_editor_description_": "" +} +global_id = "r1_r_exit" +esc_script = "res://game/rooms/room01/esc/right_exit.esc" +is_exit = true +tooltip_name = "Exit" +default_action = "walk" +dialog_color = Color( 1, 1, 1, 1 ) +animations = null + +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="."] +polygon = PoolVector2Array( 1177.94, 348.61, 1175.95, 45.3759, 1276.06, 92.0953, 1277.95, 399.407 ) diff --git a/game/rooms/room11/room11.tscn b/game/rooms/room11/room11.tscn new file mode 100644 index 00000000..040d5d8d --- /dev/null +++ b/game/rooms/room11/room11.tscn @@ -0,0 +1,243 @@ +[gd_scene load_steps=11 format=2] + +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_terrain.gd" type="Script" id=1] +[ext_resource path="res://game/rooms/room11/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/esc_location.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://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=7] +[ext_resource path="res://game/rooms/room11/r_door.tscn" type="PackedScene" id=8] + +[sub_resource type="NavigationPolygon" id=1] +vertices = PoolVector2Array( 1168.92, 640.557, 1182.53, 588.863, 1269.59, 622.872, 1275.03, 799.721, 864.626, 613.518, 1143.08, 613.35, -9.16094, 803.802, 386.666, 618.012, 129.634, 615.792, 84.5821, 654.06, -6.44019, 711.297, 3.15687, 646.051, 59.2201, 628.698 ) +polygons = [ PoolIntArray( 0, 1, 2, 3 ), PoolIntArray( 4, 5, 0, 3, 6, 7 ), PoolIntArray( 8, 7, 6, 9 ), PoolIntArray( 9, 6, 10, 11, 12 ) ] +outlines = [ PoolVector2Array( -6.44019, 711.297, 3.15687, 646.051, 59.2201, 628.698, 84.5821, 654.06, 129.634, 615.792, 386.666, 618.012, 864.626, 613.518, 1143.08, 613.35, 1168.92, 640.557, 1182.53, 588.863, 1269.59, 622.872, 1275.03, 799.721, -9.16094, 803.802 ) ] + +[sub_resource type="CircleShape2D" id=2] +radius = 53.6249 + +[node name="room11" type="Node2D"] +script = ExtResource( 6 ) +__meta__ = { +"_edit_vertical_guides_": [ ] +} +global_id = "room11" +esc_script = "res://game/rooms/room11/esc/room11.esc" +player_scene = ExtResource( 4 ) +camera_limits = [ Rect2( 0, 0, 1289, 555 ) ] + +[node name="background" parent="." instance=ExtResource( 2 )] + +[node name="room_label" type="Label" parent="background"] +margin_right = 92.0 +margin_bottom = 21.0 +custom_fonts/font = ExtResource( 3 ) +text = "ROOM 11" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="walkable_area" type="Navigation2D" parent="."] +script = ExtResource( 1 ) + +[node name="platform" type="NavigationPolygonInstance" parent="walkable_area"] +position = Vector2( 6.73163, -264.779 ) +navpoly = SubResource( 1 ) +__meta__ = { +"_editor_description_": "" +} + +[node name="Hotspots" type="Node2D" parent="."] + +[node name="l_door" type="Area2D" parent="Hotspots"] +pause_mode = 1 +script = ExtResource( 7 ) +global_id = "r11_l_exit" +esc_script = "res://game/rooms/room11/esc/left_exit.esc" +is_exit = true +tooltip_name = "Left exit" +default_action = "walk" +dialog_color = Color( 1, 1, 1, 1 ) +animations = null + +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="Hotspots/l_door"] +polygon = PoolVector2Array( 0.328762, 440.897, 1.85199, 119.926, 85.9517, 74.6212, 87.1409, 377.869 ) + +[node name="ESCLocation" type="Position2D" parent="Hotspots/l_door"] +position = Vector2( 37.4521, 392.045 ) +script = ExtResource( 5 ) + +[node name="r_door" parent="Hotspots" instance=ExtResource( 8 )] +global_id = "r11_r_exit" +esc_script = "res://game/rooms/room11/esc/right_exit.esc" + +[node name="ESCLocation" type="Position2D" parent="Hotspots/r_door"] +position = Vector2( 1236.02, 366.281 ) +script = ExtResource( 5 ) + +[node name="circleTK" type="Area2D" parent="Hotspots"] +pause_mode = 1 +position = Vector2( -422.136, 0 ) +script = ExtResource( 7 ) +global_id = "r11_circle_tk" +esc_script = "res://game/rooms/room11/esc/mysterious_circle_tk.esc" +tooltip_name = "Mysterious circle" +dialog_color = Color( 1, 1, 1, 1 ) +animations = null + +[node name="Polygon2D" type="Polygon2D" parent="Hotspots/circleTK"] +position = Vector2( 50.9425, -76.4136 ) +polygon = PoolVector2Array( 555.881, 185.538, 519.921, 215.504, 525.914, 257.456, 552.884, 282.928, 587.345, 284.426, 623.305, 260.453, 623.305, 219.999, 594.837, 187.036 ) + +[node name="ESCLocation" type="Position2D" parent="Hotspots/circleTK"] +position = Vector2( 624.794, 379.072 ) +script = ExtResource( 5 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Hotspots/circleTK"] +position = Vector2( 623.668, 159.806 ) +shape = SubResource( 2 ) + +[node name="Label" type="Label" parent="Hotspots/circleTK"] +margin_left = 700.416 +margin_top = 152.655 +margin_right = 756.416 +margin_bottom = 166.655 +text = "FLAG: TK" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="circleNoTT" type="Area2D" parent="Hotspots"] +pause_mode = 1 +position = Vector2( -151.623, 0 ) +script = ExtResource( 7 ) +global_id = "r11_circle_nott" +esc_script = "res://game/rooms/room11/esc/mysterious_circle_nott.esc" +tooltip_name = "Mysterious circle" +dialog_color = Color( 1, 1, 1, 1 ) +animations = null + +[node name="Polygon2D" type="Polygon2D" parent="Hotspots/circleNoTT"] +position = Vector2( 50.9425, -76.4136 ) +polygon = PoolVector2Array( 555.881, 185.538, 519.921, 215.504, 525.914, 257.456, 552.884, 282.928, 587.345, 284.426, 623.305, 260.453, 623.305, 219.999, 594.837, 187.036 ) + +[node name="ESCLocation" type="Position2D" parent="Hotspots/circleNoTT"] +position = Vector2( 624.794, 379.072 ) +script = ExtResource( 5 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Hotspots/circleNoTT"] +position = Vector2( 623.668, 159.806 ) +shape = SubResource( 2 ) + +[node name="Label" type="Label" parent="Hotspots/circleNoTT"] +margin_left = 691.437 +margin_top = 152.655 +margin_right = 773.437 +margin_bottom = 166.655 +text = "FLAG: NO_TT" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="circleNoHUD" type="Area2D" parent="Hotspots"] +pause_mode = 1 +position = Vector2( 118.891, 0 ) +script = ExtResource( 7 ) +global_id = "r11_circle_nohud" +esc_script = "res://game/rooms/room11/esc/mysterious_circle_nohud.esc" +tooltip_name = "Mysterious circle" +dialog_color = Color( 1, 1, 1, 1 ) +animations = null + +[node name="Polygon2D" type="Polygon2D" parent="Hotspots/circleNoHUD"] +position = Vector2( 50.9425, -76.4136 ) +polygon = PoolVector2Array( 555.881, 185.538, 519.921, 215.504, 525.914, 257.456, 552.884, 282.928, 587.345, 284.426, 623.305, 260.453, 623.305, 219.999, 594.837, 187.036 ) + +[node name="ESCLocation" type="Position2D" parent="Hotspots/circleNoHUD"] +position = Vector2( 624.794, 379.072 ) +script = ExtResource( 5 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Hotspots/circleNoHUD"] +position = Vector2( 623.668, 159.806 ) +shape = SubResource( 2 ) + +[node name="Label" type="Label" parent="Hotspots/circleNoHUD"] +margin_left = 691.437 +margin_top = 152.655 +margin_right = 773.437 +margin_bottom = 166.655 +text = "FLAG: NO_HUD" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="circleNoSave" type="Area2D" parent="Hotspots"] +pause_mode = 1 +position = Vector2( 366.891, 0 ) +script = ExtResource( 7 ) +global_id = "r11_circle_nosave" +esc_script = "res://game/rooms/room11/esc/mysterious_circle_nosave.esc" +tooltip_name = "Mysterious circle" +dialog_color = Color( 1, 1, 1, 1 ) +animations = null + +[node name="Polygon2D" type="Polygon2D" parent="Hotspots/circleNoSave"] +position = Vector2( 50.9425, -76.4136 ) +polygon = PoolVector2Array( 555.881, 185.538, 519.921, 215.504, 525.914, 257.456, 552.884, 282.928, 587.345, 284.426, 623.305, 260.453, 623.305, 219.999, 594.837, 187.036 ) + +[node name="ESCLocation" type="Position2D" parent="Hotspots/circleNoSave"] +position = Vector2( 624.794, 379.072 ) +script = ExtResource( 5 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Hotspots/circleNoSave"] +position = Vector2( 623.668, 159.806 ) +shape = SubResource( 2 ) + +[node name="Label" type="Label" parent="Hotspots/circleNoSave"] +margin_left = 691.437 +margin_top = 152.655 +margin_right = 773.437 +margin_bottom = 166.655 +text = "FLAG: NO_SAVE" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="circleFadeIn" type="Area2D" parent="Hotspots"] +pause_mode = 1 +position = Vector2( -11.1087, 107 ) +script = ExtResource( 7 ) +global_id = "r11_circle_fadein" +esc_script = "res://game/rooms/room11/esc/mysterious_circle_fadein.esc" +tooltip_name = "Mysterious circle" +dialog_color = Color( 1, 1, 1, 1 ) +animations = null + +[node name="Polygon2D" type="Polygon2D" parent="Hotspots/circleFadeIn"] +position = Vector2( 50.9425, -76.4136 ) +polygon = PoolVector2Array( 555.881, 185.538, 519.921, 215.504, 525.914, 257.456, 552.884, 282.928, 587.345, 284.426, 623.305, 260.453, 623.305, 219.999, 594.837, 187.036 ) + +[node name="ESCLocation" type="Position2D" parent="Hotspots/circleFadeIn"] +position = Vector2( 624.794, 274.072 ) +script = ExtResource( 5 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Hotspots/circleFadeIn"] +position = Vector2( 623.668, 159.806 ) +shape = SubResource( 2 ) + +[node name="Label" type="Label" parent="Hotspots/circleFadeIn"] +margin_left = 691.437 +margin_top = 152.655 +margin_right = 773.437 +margin_bottom = 166.655 +text = "FADE OUT -> FADE IN" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="player_start" type="Position2D" parent="."] +position = Vector2( 542.824, 468.193 ) +script = ExtResource( 5 ) +global_id = "player_start" +is_start_location = true diff --git a/game/rooms/room11/walkable_area.tscn b/game/rooms/room11/walkable_area.tscn new file mode 100644 index 00000000..2d6b73ec --- /dev/null +++ b/game/rooms/room11/walkable_area.tscn @@ -0,0 +1,18 @@ +[gd_scene load_steps=3 format=2] + +[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 ) +polygons = [ PoolIntArray( 0, 1, 2, 3 ), PoolIntArray( 4, 5, 0, 3, 6, 7 ), PoolIntArray( 7, 6, 8, 9, 10 ) ] +outlines = [ PoolVector2Array( -6.44019, 711.297, 3.15687, 646.051, 59.2201, 628.698, 84.5821, 654.06, 129.634, 615.792, 1143.08, 613.35, 1168.92, 640.557, 1182.53, 588.863, 1269.59, 622.872, 1275.03, 799.721, -9.16094, 803.802 ) ] + +[node name="walkable_area" type="Navigation2D"] +script = ExtResource( 1 ) + +[node name="platform" type="NavigationPolygonInstance" parent="."] +position = Vector2( 6.73163, -264.779 ) +navpoly = SubResource( 1 ) +__meta__ = { +"_editor_description_": "" +} diff --git a/game/rooms/room12/background.tscn b/game/rooms/room12/background.tscn new file mode 100644 index 00000000..fa42fc10 --- /dev/null +++ b/game/rooms/room12/background.tscn @@ -0,0 +1,30 @@ +[gd_scene load_steps=2 format=2] + +[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 +margin_bottom = 555.0 +mouse_filter = 2 +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="l_platform" type="Line2D" parent="."] +position = Vector2( 2, -266 ) +points = PoolVector2Array( -2.96298, 712.01, 129.973, 614.429, 1167.5, 612.894, 1274.59, 669.705, 1273.25, 812.694, 2.36697, 811.043, 2.36697, 713.389 ) + +[node name="l_door" type="Line2D" parent="."] +position = Vector2( 0, -266 ) +points = PoolVector2Array( 6.61201, 704.409, 6.61203, 389.558, 87.755, 339.775, 87.5463, 649.784 ) +__meta__ = { +"_editor_description_": "" +} + +[node name="r_door" type="Line2D" parent="."] +position = Vector2( 0, -267.828 ) +points = PoolVector2Array( 1175.07, 620.086, 1171.24, 311.267, 1274.8, 356.87, 1278.31, 672.412, 1188.64, 624.843 ) +__meta__ = { +"_editor_description_": "" +} diff --git a/game/rooms/room12/esc/left_exit.esc b/game/rooms/room12/esc/left_exit.esc new file mode 100644 index 00000000..6f794b3c --- /dev/null +++ b/game/rooms/room12/esc/left_exit.esc @@ -0,0 +1,5 @@ +:exit_scene +set_sound_state bg_sound res://game/sfx/sounds/doorOpen_2.ogg false +change_scene "res://game/rooms/room11/room11.tscn" + + diff --git a/game/rooms/room12/esc/right_exit.esc b/game/rooms/room12/esc/right_exit.esc new file mode 100644 index 00000000..082fda66 --- /dev/null +++ b/game/rooms/room12/esc/right_exit.esc @@ -0,0 +1,3 @@ +:exit_scene +#set_sound_state bg_sound res://game/sfx/sounds/doorOpen_2.ogg false +#change_scene "res://game/rooms/room13/room13.tscn" diff --git a/game/rooms/room12/esc/room12.esc b/game/rooms/room12/esc/room12.esc new file mode 100644 index 00000000..79f502f4 --- /dev/null +++ b/game/rooms/room12/esc/room12.esc @@ -0,0 +1,21 @@ + +:setup + +> [eq ESC_LAST_SCENE room11] + teleport player r12_l_exit + # Set player look right + set_angle player 180 + stop +> [eq ESC_LAST_SCENE room13] + teleport player r12_r_exit + # Set player look left + set_angle player 270 + stop +> [!last_scene] + teleport player player_start + stop + + +:ready + +transition fade_white in diff --git a/game/rooms/room12/r_door.tscn b/game/rooms/room12/r_door.tscn new file mode 100644 index 00000000..39b4fa38 --- /dev/null +++ b/game/rooms/room12/r_door.tscn @@ -0,0 +1,25 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=1] +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_location.gd" type="Script" id=2] + +[node name="r_door" type="Area2D"] +pause_mode = 1 +script = ExtResource( 1 ) +__meta__ = { +"_editor_description_": "" +} +global_id = "r1_r_exit" +esc_script = "res://game/rooms/room01/esc/right_exit.esc" +is_exit = true +tooltip_name = "Exit" +default_action = "walk" +dialog_color = Color( 1, 1, 1, 1 ) +animations = null + +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="."] +polygon = PoolVector2Array( 1177.94, 348.61, 1175.95, 45.3759, 1276.06, 92.0953, 1277.95, 399.407 ) + +[node name="Position2D" type="Position2D" parent="."] +position = Vector2( 1225.47, 353.99 ) +script = ExtResource( 2 ) diff --git a/game/rooms/room12/room12.tscn b/game/rooms/room12/room12.tscn new file mode 100644 index 00000000..26d4618b --- /dev/null +++ b/game/rooms/room12/room12.tscn @@ -0,0 +1,82 @@ +[gd_scene load_steps=10 format=2] + +[ext_resource path="res://addons/escoria-core/game/core-scripts/esc_terrain.gd" type="Script" id=1] +[ext_resource path="res://game/rooms/room12/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/esc_location.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://addons/escoria-core/game/core-scripts/esc_item.gd" type="Script" id=7] +[ext_resource path="res://game/rooms/room12/r_door.tscn" type="PackedScene" id=8] + +[sub_resource type="NavigationPolygon" id=1] +vertices = PoolVector2Array( 1168.92, 640.557, 1182.53, 588.863, 1269.59, 622.872, 1275.03, 799.721, 864.626, 613.518, 1143.08, 613.35, -9.16094, 803.802, 386.666, 618.012, 129.634, 615.792, 84.5821, 654.06, -6.44019, 711.297, 3.15687, 646.051, 59.2201, 628.698 ) +polygons = [ PoolIntArray( 0, 1, 2, 3 ), PoolIntArray( 4, 5, 0, 3, 6, 7 ), PoolIntArray( 8, 7, 6, 9 ), PoolIntArray( 9, 6, 10, 11, 12 ) ] +outlines = [ PoolVector2Array( -6.44019, 711.297, 3.15687, 646.051, 59.2201, 628.698, 84.5821, 654.06, 129.634, 615.792, 386.666, 618.012, 864.626, 613.518, 1143.08, 613.35, 1168.92, 640.557, 1182.53, 588.863, 1269.59, 622.872, 1275.03, 799.721, -9.16094, 803.802 ) ] + +[node name="room12" type="Node2D"] +script = ExtResource( 6 ) +__meta__ = { +"_edit_vertical_guides_": [ ] +} +global_id = "room12" +esc_script = "res://game/rooms/room12/esc/room12.esc" +player_scene = ExtResource( 4 ) +camera_limits = [ Rect2( 0, 0, 1289, 555 ) ] + +[node name="background" parent="." instance=ExtResource( 2 )] + +[node name="room_label" type="Label" parent="background"] +margin_right = 92.0 +margin_bottom = 21.0 +custom_fonts/font = ExtResource( 3 ) +text = "ROOM 12 +" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="walkable_area" type="Navigation2D" parent="."] +script = ExtResource( 1 ) + +[node name="platform" type="NavigationPolygonInstance" parent="walkable_area"] +position = Vector2( 6.73163, -264.779 ) +navpoly = SubResource( 1 ) +__meta__ = { +"_editor_description_": "" +} + +[node name="Hotspots" type="Node2D" parent="."] + +[node name="l_door" type="Area2D" parent="Hotspots"] +pause_mode = 1 +script = ExtResource( 7 ) +global_id = "r12_l_exit" +esc_script = "res://game/rooms/room12/esc/left_exit.esc" +is_exit = true +tooltip_name = "Left exit" +default_action = "walk" +dialog_color = Color( 1, 1, 1, 1 ) +animations = null + +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="Hotspots/l_door"] +polygon = PoolVector2Array( 0.328762, 440.897, 1.85199, 119.926, 85.9517, 74.6212, 87.1409, 377.869 ) + +[node name="Position2D" type="Position2D" parent="Hotspots/l_door"] +position = Vector2( 37.4521, 392.045 ) +script = ExtResource( 5 ) +global_id = "r12_l_exit" + +[node name="r_door" parent="Hotspots" instance=ExtResource( 8 )] +global_id = "r12_r_exit" +esc_script = "res://game/rooms/room12/esc/right_exit.esc" + +[node name="ESCLocation" type="Position2D" parent="Hotspots/r_door"] +position = Vector2( 1231.78, 360.624 ) +script = ExtResource( 5 ) + +[node name="player_start" type="Position2D" parent="."] +position = Vector2( 542.824, 468.193 ) +script = ExtResource( 5 ) +global_id = "player_start" +is_start_location = true diff --git a/game/rooms/room12/walkable_area.tscn b/game/rooms/room12/walkable_area.tscn new file mode 100644 index 00000000..2d6b73ec --- /dev/null +++ b/game/rooms/room12/walkable_area.tscn @@ -0,0 +1,18 @@ +[gd_scene load_steps=3 format=2] + +[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 ) +polygons = [ PoolIntArray( 0, 1, 2, 3 ), PoolIntArray( 4, 5, 0, 3, 6, 7 ), PoolIntArray( 7, 6, 8, 9, 10 ) ] +outlines = [ PoolVector2Array( -6.44019, 711.297, 3.15687, 646.051, 59.2201, 628.698, 84.5821, 654.06, 129.634, 615.792, 1143.08, 613.35, 1168.92, 640.557, 1182.53, 588.863, 1269.59, 622.872, 1275.03, 799.721, -9.16094, 803.802 ) ] + +[node name="walkable_area" type="Navigation2D"] +script = ExtResource( 1 ) + +[node name="platform" type="NavigationPolygonInstance" parent="."] +position = Vector2( 6.73163, -264.779 ) +navpoly = SubResource( 1 ) +__meta__ = { +"_editor_description_": "" +} diff --git a/game/start_game.esc b/game/start_game.esc index 102f2c70..a2dec9e8 100755 --- a/game/start_game.esc +++ b/game/start_game.esc @@ -27,3 +27,12 @@ change_scene res://game/rooms/room01/room01.tscn # 9/ Indy4 3 closets #change_scene res://game/rooms/room09/room09.tscn + +# 10/ +#change_scene res://game/rooms/room10/room10.tscn + +# 11/ Event flags tests +#change_scene res://game/rooms/room11/room11.tscn + +# 12/ Event flags tests 2 +#change_scene res://game/rooms/room12/room12.tscn diff --git a/game/ui/commons/dialogs/insets/guybrush.jpeg b/game/ui/commons/dialogs/insets/guybrush.jpeg deleted file mode 100644 index cbbe821e93450547f3725ff7e0436400f3f4700d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26964 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