diff --git a/assets/first_party/user_interface/interact_talk-touch-button.png b/assets/first_party/user_interface/interact_talk-touch-button.png deleted file mode 100644 index f2a29129e7..0000000000 --- a/assets/first_party/user_interface/interact_talk-touch-button.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:87759982804ee6c527265bcf409e713ae345764dcb9ff0e6110a2d69f718846b -size 4852 diff --git a/assets/first_party/user_interface/interact_talk-touch-button.png.import b/assets/first_party/user_interface/interact_talk-touch-button.png.import deleted file mode 100644 index df6dbefa34..0000000000 --- a/assets/first_party/user_interface/interact_talk-touch-button.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://ns6755757cje" -path="res://.godot/imported/interact_talk-touch-button.png-cbb11c5a00f2b863d658ab0b86f69c22.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://assets/first_party/user_interface/interact_talk-touch-button.png" -dest_files=["res://.godot/imported/interact_talk-touch-button.png-cbb11c5a00f2b863d658ab0b86f69c22.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 diff --git a/assets/first_party/user_interface/interact_talk-touch-button_pressed.png b/assets/first_party/user_interface/interact_talk-touch-button_pressed.png deleted file mode 100644 index 8f7c742195..0000000000 --- a/assets/first_party/user_interface/interact_talk-touch-button_pressed.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7791818acad2e097db61168284116a8731e7be240ec15d29c21f89ff0a7c6019 -size 4792 diff --git a/assets/first_party/user_interface/interact_talk-touch-button_pressed.png.import b/assets/first_party/user_interface/interact_talk-touch-button_pressed.png.import deleted file mode 100644 index e30330f356..0000000000 --- a/assets/first_party/user_interface/interact_talk-touch-button_pressed.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://iwooycswl1bb" -path="res://.godot/imported/interact_talk-touch-button_pressed.png-1410bddf789f6f4a5a957d33e4fa18dd.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://assets/first_party/user_interface/interact_talk-touch-button_pressed.png" -dest_files=["res://.godot/imported/interact_talk-touch-button_pressed.png-1410bddf789f6f4a5a957d33e4fa18dd.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 diff --git a/assets/first_party/user_interface/interact_use-touch-button.png b/assets/first_party/user_interface/interact_use-touch-button.png deleted file mode 100644 index 3e7e91fd14..0000000000 --- a/assets/first_party/user_interface/interact_use-touch-button.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:21c9713fe4ddcfb9c877e906f43abd7092ddb092d383aa7661c3df2908a031fb -size 6608 diff --git a/assets/first_party/user_interface/interact_use-touch-button.png.import b/assets/first_party/user_interface/interact_use-touch-button.png.import deleted file mode 100644 index 7048805615..0000000000 --- a/assets/first_party/user_interface/interact_use-touch-button.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cjworl3bsj51d" -path="res://.godot/imported/interact_use-touch-button.png-648815f1a2b5fc654cad479885771a5b.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://assets/first_party/user_interface/interact_use-touch-button.png" -dest_files=["res://.godot/imported/interact_use-touch-button.png-648815f1a2b5fc654cad479885771a5b.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 diff --git a/assets/first_party/user_interface/interact_use-touch-button_pressed.png b/assets/first_party/user_interface/interact_use-touch-button_pressed.png deleted file mode 100644 index 98a6d85723..0000000000 --- a/assets/first_party/user_interface/interact_use-touch-button_pressed.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6df63287116db61e6cb096a4dde444d85c85a96a7938cd525f1e5c2133d96ff3 -size 6369 diff --git a/assets/first_party/user_interface/interact_use-touch-button_pressed.png.import b/assets/first_party/user_interface/interact_use-touch-button_pressed.png.import deleted file mode 100644 index dd980d5e4a..0000000000 --- a/assets/first_party/user_interface/interact_use-touch-button_pressed.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cmruhm7k3i3jm" -path="res://.godot/imported/interact_use-touch-button_pressed.png-b870c78285bb9aefcb958185be26601e.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://assets/first_party/user_interface/interact_use-touch-button_pressed.png" -dest_files=["res://.godot/imported/interact_use-touch-button_pressed.png-b870c78285bb9aefcb958185be26601e.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 diff --git a/assets/first_party/user_interface/repel-touch-button.png b/assets/first_party/user_interface/repel-touch-button.png deleted file mode 100644 index e6773a93e5..0000000000 --- a/assets/first_party/user_interface/repel-touch-button.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f0ad2217d78e356779bc5fc4b4d7ba5a233beb4d04ea8f4cb8815a0f53118320 -size 6066 diff --git a/assets/first_party/user_interface/repel-touch-button_pressed.png b/assets/first_party/user_interface/repel-touch-button_pressed.png deleted file mode 100644 index d51b295cd3..0000000000 --- a/assets/first_party/user_interface/repel-touch-button_pressed.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:285582a58fd81e50d83b96273b03d59c45dcb90315e16c61ff60a59421c05f0f -size 5976 diff --git a/assets/first_party/user_interface/repel-touch-button_pressed.png.import b/assets/first_party/user_interface/repel-touch-button_pressed.png.import deleted file mode 100644 index fafe6a63a6..0000000000 --- a/assets/first_party/user_interface/repel-touch-button_pressed.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cttum8v2mb62v" -path="res://.godot/imported/repel-touch-button_pressed.png-74661814a87f36012eabd5e398a676c6.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://assets/first_party/user_interface/repel-touch-button_pressed.png" -dest_files=["res://.godot/imported/repel-touch-button_pressed.png-74661814a87f36012eabd5e398a676c6.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 diff --git a/assets/third_party/kenney_input_prompts/touch_sheet_default.png b/assets/third_party/kenney_input_prompts/touch_sheet_default.png new file mode 100644 index 0000000000..9a865a1f43 --- /dev/null +++ b/assets/third_party/kenney_input_prompts/touch_sheet_default.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8df3d1e93851a28b0efad1b01ea4b07ba079d85eb198a2a3aef5790af7f258f9 +size 5105 diff --git a/assets/first_party/user_interface/repel-touch-button.png.import b/assets/third_party/kenney_input_prompts/touch_sheet_default.png.import similarity index 70% rename from assets/first_party/user_interface/repel-touch-button.png.import rename to assets/third_party/kenney_input_prompts/touch_sheet_default.png.import index cfda3ccf3e..c3e92f3a9a 100644 --- a/assets/first_party/user_interface/repel-touch-button.png.import +++ b/assets/third_party/kenney_input_prompts/touch_sheet_default.png.import @@ -2,16 +2,16 @@ importer="texture" type="CompressedTexture2D" -uid="uid://byra1c7yc54mg" -path="res://.godot/imported/repel-touch-button.png-79ecb9d4a242ef90e0ef33cb07527472.ctex" +uid="uid://7kk2uvil7u0f" +path="res://.godot/imported/touch_sheet_default.png-e0f640a282bc2b7c7b013a5d87237ce1.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/first_party/user_interface/repel-touch-button.png" -dest_files=["res://.godot/imported/repel-touch-button.png-79ecb9d4a242ef90e0ef33cb07527472.ctex"] +source_file="res://assets/third_party/kenney_input_prompts/touch_sheet_default.png" +dest_files=["res://.godot/imported/touch_sheet_default.png-e0f640a282bc2b7c7b013a5d87237ce1.ctex"] [params] diff --git a/locale/es.po b/locale/es.po index 6c3edae9a6..a9e07a5841 100644 --- a/locale/es.po +++ b/locale/es.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: Threadbare\n" -"PO-Revision-Date: 2026-11-10 14:52-0300\n" +"PO-Revision-Date: 2026-11-11 11:09-0300\n" "Last-Translator: Manuel Quiñones \n" "Language-Team: Spanish\n" "Language: es\n" @@ -922,12 +922,12 @@ msgstr "¡Juega con puertas y manijas!" #: scenes/dev/level_design/optional_threads/optional_threads.dialogue msgctxt "dialogue" msgid "Ulysses Thriftweed" -msgstr "" +msgstr "Ulysses Thriftweed" #. TRANSLATORS: Character: Ulysses Thriftweed #: scenes/dev/level_design/optional_threads/optional_threads.dialogue:4 msgid "If you go East, you can get out of here." -msgstr "" +msgstr "Si vas al este, puedes salir de aquí." #. TRANSLATORS: Character: Ulysses Thriftweed #: scenes/dev/level_design/optional_threads/optional_threads.dialogue:5 @@ -935,28 +935,28 @@ msgid "" "If you go through the cave up North, there's another thread you can collect " "first, if you're feeling brave." msgstr "" +"Si vas a la cueva del norte, hay otro hilo que puedes juntar antes, si eres " +"tan valiente." #. TRANSLATORS: Character: Ulysses Thriftweed #: scenes/dev/level_design/optional_threads/optional_threads.dialogue:7 msgid "I hope now you've learned to stop picking your nose." -msgstr "" +msgstr "Espero que hayas aprendido a dejar de meterte el dedo en la nariz." #. TRANSLATORS: Character: Ulysses Thriftweed #: scenes/dev/level_design/optional_threads/optional_threads.dialogue:11 msgid "You run THAT fast?" -msgstr "" +msgstr "¿Corres TAN rápido?" #. TRANSLATORS: Quest title #: scenes/dev/level_design/optional_threads/quest.tres -#, fuzzy -#| msgid "Options" msgid "Optional Threads" -msgstr "Opciones" +msgstr "Hilos opcionales" #. TRANSLATORS: Quest description #: scenes/dev/level_design/optional_threads/quest.tres msgid "Shows how to add an optional thread to a scene." -msgstr "" +msgstr "Muestra cómo añadir un hilo opcional a una escena." #: scenes/dev/level_design/time_and_weather/1_time_and_weather_museum.tscn msgid "This is the current time. One minute in this scene is one day." @@ -1508,6 +1508,10 @@ msgstr "Ajustes de mando" msgid "Touch Controls" msgstr "Control táctil" +#: scenes/menus/options/components/input_settings.tscn +msgid "Left-Handed" +msgstr "Para zurdos" + #: scenes/menus/options/components/input_settings.tscn msgid "Keyboard Only" msgstr "Sólo teclado" @@ -1602,6 +1606,7 @@ msgid "Move / Aim" msgstr "Mover / Apuntar" #: scenes/ui_elements/input_hints/repel_input_hint.tscn +#: scenes/ui_elements/input_hints/tap_input_hint.tscn msgid "Repel" msgstr "Repeler" @@ -1617,6 +1622,10 @@ msgstr "Correr" msgid "Skip" msgstr "Omitir" +#: scenes/ui_elements/input_hints/swipe_input_hint.tscn +msgid "Aim & Throw" +msgstr "Apuntar y lanzar" + #: scenes/ui_elements/input_hints/throw_input_hint.tscn msgid "Throw" msgstr "Lanzar" diff --git a/locale/threadbare.pot b/locale/threadbare.pot index 8b1d0ee319..4a79eaa8db 100644 --- a/locale/threadbare.pot +++ b/locale/threadbare.pot @@ -165,6 +165,8 @@ # res://scenes/ui_elements/input_hints/reset_input_hint.tscn # res://scenes/ui_elements/input_hints/run_input_hint.tscn # res://scenes/ui_elements/input_hints/skip_input_hint.tscn +# res://scenes/ui_elements/input_hints/swipe_input_hint.tscn +# res://scenes/ui_elements/input_hints/tap_input_hint.tscn # res://scenes/ui_elements/input_hints/throw_input_hint.tscn # res://scenes/ui_elements/input_hints/undo_input_hint.tscn # res://scenes/quests/template_quests/NO_EDIT/0_NO_EDIT_intro/NO_EDIT_intro.tscn @@ -1330,6 +1332,10 @@ msgstr "" msgid "Touch Controls" msgstr "" +#: scenes/menus/options/components/input_settings.tscn +msgid "Left-Handed" +msgstr "" + #: scenes/menus/options/components/input_settings.tscn msgid "Keyboard Only" msgstr "" @@ -1419,6 +1425,7 @@ msgid "Move / Aim" msgstr "" #: scenes/ui_elements/input_hints/repel_input_hint.tscn +#: scenes/ui_elements/input_hints/tap_input_hint.tscn msgid "Repel" msgstr "" @@ -1434,6 +1441,10 @@ msgstr "" msgid "Skip" msgstr "" +#: scenes/ui_elements/input_hints/swipe_input_hint.tscn +msgid "Aim & Throw" +msgstr "" + #: scenes/ui_elements/input_hints/throw_input_hint.tscn msgid "Throw" msgstr "" diff --git a/project.godot b/project.godot index 09e6b3aef5..256936ed0f 100644 --- a/project.godot +++ b/project.godot @@ -305,7 +305,7 @@ next_tab={ [internationalization] locale/translations=PackedStringArray("res://locale/es.po", "res://locale/fr.po") -locale/translations_pot_files=PackedStringArray("res://addons/storyquest_bootstrap/new_storyquest_dialog.tscn", "res://addons/storyquest_bootstrap/plugin.gd", "res://scenes/dev/basics/teleporter/quest.tres", "res://scenes/dev/basics/teleporter/teleporter_test_1.tscn", "res://scenes/dev/basics/teleporter/teleporter_test_2.tscn", "res://scenes/dev/basics/visuals/quest.tres", "res://scenes/dev/basics/visuals/visuals_test.tscn", "res://scenes/dev/components/dev_archipelago_basics_elder.dialogue", "res://scenes/dev/components/dev_archipelago_enemy_interaction_elder.dialogue", "res://scenes/dev/components/dev_archipelago_grapple_elder.dialogue", "res://scenes/dev/components/dev_archipelago_intro_islander.dialogue", "res://scenes/dev/components/dev_archipelago_level_design_elder.dialogue", "res://scenes/dev/components/dev_archipelago_repel_elder.dialogue", "res://scenes/dev/dev_archipelago.tscn", "res://scenes/dev/enemy_interaction/gym_area/gym_area_test.tscn", "res://scenes/dev/enemy_interaction/gym_area/quest.tres", "res://scenes/dev/grapple/custom_hookable_objects/custom_hookable_objects_test.tscn", "res://scenes/dev/grapple/custom_hookable_objects/quest.tres", "res://scenes/dev/grapple/grapple_gym_1/grapple_gym_1.tscn", "res://scenes/dev/grapple/grapple_gym_1/quest.tres", "res://scenes/dev/grapple/grapple_gym_2/grapple_gym_2.tscn", "res://scenes/dev/grapple/grapple_gym_2/quest.tres", "res://scenes/dev/level_design/area_filler/interactive_area_filler_test.tscn", "res://scenes/dev/level_design/area_filler/quest.tres", "res://scenes/dev/level_design/character_randomizer/character_randomizer_test.dialogue", "res://scenes/dev/level_design/character_randomizer/character_randomizer_test.tscn", "res://scenes/dev/level_design/character_randomizer/quest.tres", "res://scenes/dev/level_design/doors_and_levers/doors_and_levers.tscn", "res://scenes/dev/level_design/doors_and_levers/quest.tres", "res://scenes/dev/level_design/optional_threads/optional_threads.dialogue", "res://scenes/dev/level_design/optional_threads/optional_threads.tscn", "res://scenes/dev/level_design/optional_threads/quest.tres", "res://scenes/dev/level_design/time_and_weather/1_time_and_weather_museum.tscn", "res://scenes/dev/level_design/time_and_weather/2_time_and_weather_museum.tscn", "res://scenes/dev/level_design/time_and_weather/quest.tres", "res://scenes/dev/playground/unify_abilities/quest.tres", "res://scenes/dev/playground/unify_abilities/unify_abilities_test.tscn", "res://scenes/dev/playground/unify_abilities/unify_abilities_test_projectile.tscn", "res://scenes/dev/repel/custom_repellable_objects/custom_repellable_objects_test.tscn", "res://scenes/dev/repel/custom_repellable_objects/quest.tres", "res://scenes/dev/repel/ink_combat/ink_combat_test.tscn", "res://scenes/dev/repel/ink_combat/quest.tres", "res://scenes/game_elements/characters/components/character_sprites_museum.tscn", "res://scenes/game_elements/characters/components/health_bar/health_bar.tscn", "res://scenes/game_elements/characters/components/projectile_test.tscn", "res://scenes/game_elements/characters/enemies/guard/guard.tscn", "res://scenes/game_elements/characters/enemies/mothsache/Mothsache.tscn", "res://scenes/game_elements/characters/enemies/throwing_enemy/throwing_enemy.tscn", "res://scenes/game_elements/characters/enemies/void_spreading_enemy/components/void_particles.tscn", "res://scenes/game_elements/characters/enemies/void_spreading_enemy/void_spreading_enemy.tscn", "res://scenes/game_elements/characters/npcs/cat/cat.tscn", "res://scenes/game_elements/characters/npcs/components/default_helper.dialogue", "res://scenes/game_elements/characters/npcs/components/skin_tones_test.tscn", "res://scenes/game_elements/characters/npcs/elder/components/story_quest_starter.dialogue", "res://scenes/game_elements/characters/npcs/elder/components/template_quest_starter.dialogue", "res://scenes/game_elements/characters/npcs/elder/story_quest_elder.tscn", "res://scenes/game_elements/characters/npcs/elder/template_elder.tscn", "res://scenes/game_elements/characters/npcs/musician/musician.tscn", "res://scenes/game_elements/characters/npcs/npc_prop/fray_axeman.tscn", "res://scenes/game_elements/characters/npcs/npc_prop/fray_hammerman.tscn", "res://scenes/game_elements/characters/npcs/npc_prop/fray_idle.tscn", "res://scenes/game_elements/characters/npcs/talker/components/default.dialogue", "res://scenes/game_elements/characters/npcs/talker/talker.tscn", "res://scenes/game_elements/characters/npcs/townie.tscn", "res://scenes/game_elements/characters/player/components/player_hook.tscn", "res://scenes/game_elements/characters/player/components/player_repel.tscn", "res://scenes/game_elements/characters/player/player.tscn", "res://scenes/game_elements/components/elements_scale_museum.tscn", "res://scenes/game_elements/fx/clouds_shadow/clouds_shadow.tscn", "res://scenes/game_elements/fx/curly_trail/curly_trail.tscn", "res://scenes/game_elements/fx/fog/fog.tscn", "res://scenes/game_elements/fx/liquid_big_splat/liquid_big_splat.tscn", "res://scenes/game_elements/fx/liquid_small_splat/liquid_small_splat.tscn", "res://scenes/game_elements/fx/liquid_trail.tscn", "res://scenes/game_elements/fx/rain/rain.tscn", "res://scenes/game_elements/fx/rope_shatter.tscn", "res://scenes/game_elements/fx/shine_particles/shine_particles.tscn", "res://scenes/game_elements/fx/stitch_trail/stitch_trail.tscn", "res://scenes/game_elements/fx/time_and_weather/time_and_weather.tscn", "res://scenes/game_elements/fx/world_rewoven/components/line_trails_test.tscn", "res://scenes/game_elements/fx/world_rewoven/components/world_rewoven_cutscene_1.tscn", "res://scenes/game_elements/fx/world_rewoven/components/world_rewoven_cutscene_2.tscn", "res://scenes/game_elements/props/all_hooked/all_hooked.tscn", "res://scenes/game_elements/props/background_music/background_music.tscn", "res://scenes/game_elements/props/buildings/house/house_1.tscn", "res://scenes/game_elements/props/buildings/house/house_2.tscn", "res://scenes/game_elements/props/buildings/house/ruined_house.tscn", "res://scenes/game_elements/props/buildings/inn/inn.tscn", "res://scenes/game_elements/props/buildings/temple/temple.tscn", "res://scenes/game_elements/props/buildings/tower/tower.tscn", "res://scenes/game_elements/props/button_item/button_item.tscn", "res://scenes/game_elements/props/checkpoint/checkpoint.tscn", "res://scenes/game_elements/props/checkpoint/components/checkpoint.dialogue", "res://scenes/game_elements/props/collectible_item/collectible_item.tscn", "res://scenes/game_elements/props/collectible_item/components/collectible_item_test.tscn", "res://scenes/game_elements/props/decoration/books/books.tscn", "res://scenes/game_elements/props/decoration/bunny/bunny.tscn", "res://scenes/game_elements/props/decoration/bush/bush.tscn", "res://scenes/game_elements/props/decoration/butterfly/butterfly.tscn", "res://scenes/game_elements/props/decoration/capycorn/capycorn.tscn", "res://scenes/game_elements/props/decoration/crops/barley.tscn", "res://scenes/game_elements/props/decoration/crops/carrot.tscn", "res://scenes/game_elements/props/decoration/crops/tomato.tscn", "res://scenes/game_elements/props/decoration/flower/flower.tscn", "res://scenes/game_elements/props/decoration/hiding_mushroom/hiding_mushroom.tscn", "res://scenes/game_elements/props/decoration/rock/fabric_rock.tscn", "res://scenes/game_elements/props/decoration/rock/rock.tscn", "res://scenes/game_elements/props/decoration/sheep/sheep.tscn", "res://scenes/game_elements/props/decoration/spool/spool.tscn", "res://scenes/game_elements/props/decoration/water_rock/water_rock.tscn", "res://scenes/game_elements/props/door/horizontal_door.tscn", "res://scenes/game_elements/props/door/vertical_door.tscn", "res://scenes/game_elements/props/filling_barrel/filling_barrel.tscn", "res://scenes/game_elements/props/filling_barrel/fragile_barrel.tscn", "res://scenes/game_elements/props/fixed_size_label/fixed_size_label.tscn", "res://scenes/game_elements/props/hint/hint.tscn", "res://scenes/game_elements/props/hook_control/hook_control.tscn", "res://scenes/game_elements/props/hookable_area/components/hookable_indicator.tscn", "res://scenes/game_elements/props/hookable_box/hookable_box.tscn", "res://scenes/game_elements/props/hookable_button_item/hookable_button_item.tscn", "res://scenes/game_elements/props/hookable_lever/hookable_lever.tscn", "res://scenes/game_elements/props/hookable_needle/hookable_needle.tscn", "res://scenes/game_elements/props/hookable_pin/hookable_pin.tscn", "res://scenes/game_elements/props/interact_area/interact_indicator.tscn", "res://scenes/game_elements/props/lever/lever.tscn", "res://scenes/game_elements/props/powerup/components/default_powerup.dialogue", "res://scenes/game_elements/props/powerup/powerup.tscn", "res://scenes/game_elements/props/projectile/ink_blob_projectile.tscn", "res://scenes/game_elements/props/repellable_ball/repellable_ball.tscn", "res://scenes/game_elements/props/repellable_box/repellable_box.tscn", "res://scenes/game_elements/props/repellable_lever/repellable_lever.tscn", "res://scenes/game_elements/props/sequence_puzzle_hint_sign/sequence_puzzle_hint_sign.tscn", "res://scenes/game_elements/props/sequence_puzzle_object/sequence_puzzle_object.tscn", "res://scenes/game_elements/props/sign/sign.tscn", "res://scenes/game_elements/props/spawn_point/spawn_point.tscn", "res://scenes/game_elements/props/teleporter/quest_teleporter.tscn", "res://scenes/game_elements/props/teleporter/teleporter.tscn", "res://scenes/game_elements/props/tileomatic/tileomatic_test.tscn", "res://scenes/game_elements/props/tree/tree.tscn", "res://scenes/game_elements/props/tree/tree_void_affected.tscn", "res://scenes/game_elements/props/collectible_item/components/collectible_item.gd", "res://scenes/game_elements/props/powerup/components/powerup.gd", "res://scenes/game_logic/talk_behavior.gd", "res://scenes/globals/pause/pause_overlay.tscn", "res://scenes/globals/pause/quest_abandoned.dialogue", "res://scenes/menus/debug/components/debug_completed_quests.tscn", "res://scenes/menus/debug/components/debug_player_abilities.tscn", "res://scenes/menus/debug/debug_settings.tscn", "res://scenes/menus/options/components/back_button.tscn", "res://scenes/menus/options/components/input_settings.tscn", "res://scenes/menus/options/components/language_settings.tscn", "res://scenes/menus/options/components/sound_settings.tscn", "res://scenes/menus/options/components/video_settings.tscn", "res://scenes/menus/options/components/volume_slider.tscn", "res://scenes/menus/options/options.tscn", "res://scenes/menus/quest_separator/quest_separator.tscn", "res://scenes/menus/title/components/main_menu.tscn", "res://scenes/menus/title/components/main_menu.gd", "res://scenes/ui_elements/input_hints/aim_input_hint.tscn", "res://scenes/ui_elements/input_hints/back_input_hint.tscn", "res://scenes/ui_elements/input_hints/interact_input_hint.tscn", "res://scenes/ui_elements/input_hints/movement_input_hint.tscn", "res://scenes/ui_elements/input_hints/repel_input_hint.tscn", "res://scenes/ui_elements/input_hints/reset_input_hint.tscn", "res://scenes/ui_elements/input_hints/run_input_hint.tscn", "res://scenes/ui_elements/input_hints/skip_input_hint.tscn", "res://scenes/ui_elements/input_hints/throw_input_hint.tscn", "res://scenes/ui_elements/input_hints/undo_input_hint.tscn", "res://scenes/quests/template_quests/NO_EDIT/0_NO_EDIT_intro/NO_EDIT_intro.tscn", "res://scenes/quests/template_quests/NO_EDIT/0_NO_EDIT_intro/NO_EDIT_intro_components/NO_EDIT_intro.dialogue", "res://scenes/quests/template_quests/NO_EDIT/1_NO_EDIT_stealth/NO_EDIT_stealth.tscn", "res://scenes/quests/template_quests/NO_EDIT/1_NO_EDIT_stealth/NO_EDIT_stealth_components/NO_EDIT_checkpoint.dialogue", "res://scenes/quests/template_quests/NO_EDIT/1_NO_EDIT_stealth/NO_EDIT_stealth_components/NO_EDIT_collected.dialogue", "res://scenes/quests/template_quests/NO_EDIT/1_NO_EDIT_stealth/NO_EDIT_stealth_components/NO_EDIT_stealth.dialogue", "res://scenes/quests/template_quests/NO_EDIT/2_NO_EDIT_combat/NO_EDIT_combat.tscn", "res://scenes/quests/template_quests/NO_EDIT/2_NO_EDIT_combat/NO_EDIT_combat_components/NO_EDIT_combat.dialogue", "res://scenes/quests/template_quests/NO_EDIT/2_NO_EDIT_combat/NO_EDIT_combat_components/NO_EDIT_projectile.tscn", "res://scenes/quests/template_quests/NO_EDIT/3_NO_EDIT_sequence_puzzle/NO_EDIT_sequence_puzzle.dialogue", "res://scenes/quests/template_quests/NO_EDIT/3_NO_EDIT_sequence_puzzle/NO_EDIT_sequence_puzzle.tscn", "res://scenes/quests/template_quests/NO_EDIT/4_NO_EDIT_outro/NO_EDIT_outro.tscn", "res://scenes/quests/template_quests/NO_EDIT/4_NO_EDIT_outro/NO_EDIT_outro_components/NO_EDIT_outro.dialogue", "res://scenes/quests/template_quests/NO_EDIT/NO_EDIT_basic_scene.tscn", "res://scenes/quests/template_quests/NO_EDIT/quest.tres", "res://scenes/quests/template_quests/teleporter_challenge/teleporter_challenge.tscn", "res://scenes/quests/template_quests/void_challenge/void_challenge.tscn") +locale/translations_pot_files=PackedStringArray("res://addons/storyquest_bootstrap/new_storyquest_dialog.tscn", "res://addons/storyquest_bootstrap/plugin.gd", "res://scenes/dev/basics/teleporter/quest.tres", "res://scenes/dev/basics/teleporter/teleporter_test_1.tscn", "res://scenes/dev/basics/teleporter/teleporter_test_2.tscn", "res://scenes/dev/basics/visuals/quest.tres", "res://scenes/dev/basics/visuals/visuals_test.tscn", "res://scenes/dev/components/dev_archipelago_basics_elder.dialogue", "res://scenes/dev/components/dev_archipelago_enemy_interaction_elder.dialogue", "res://scenes/dev/components/dev_archipelago_grapple_elder.dialogue", "res://scenes/dev/components/dev_archipelago_intro_islander.dialogue", "res://scenes/dev/components/dev_archipelago_level_design_elder.dialogue", "res://scenes/dev/components/dev_archipelago_repel_elder.dialogue", "res://scenes/dev/dev_archipelago.tscn", "res://scenes/dev/enemy_interaction/gym_area/gym_area_test.tscn", "res://scenes/dev/enemy_interaction/gym_area/quest.tres", "res://scenes/dev/grapple/custom_hookable_objects/custom_hookable_objects_test.tscn", "res://scenes/dev/grapple/custom_hookable_objects/quest.tres", "res://scenes/dev/grapple/grapple_gym_1/grapple_gym_1.tscn", "res://scenes/dev/grapple/grapple_gym_1/quest.tres", "res://scenes/dev/grapple/grapple_gym_2/grapple_gym_2.tscn", "res://scenes/dev/grapple/grapple_gym_2/quest.tres", "res://scenes/dev/level_design/area_filler/interactive_area_filler_test.tscn", "res://scenes/dev/level_design/area_filler/quest.tres", "res://scenes/dev/level_design/character_randomizer/character_randomizer_test.dialogue", "res://scenes/dev/level_design/character_randomizer/character_randomizer_test.tscn", "res://scenes/dev/level_design/character_randomizer/quest.tres", "res://scenes/dev/level_design/doors_and_levers/doors_and_levers.tscn", "res://scenes/dev/level_design/doors_and_levers/quest.tres", "res://scenes/dev/level_design/optional_threads/optional_threads.dialogue", "res://scenes/dev/level_design/optional_threads/optional_threads.tscn", "res://scenes/dev/level_design/optional_threads/quest.tres", "res://scenes/dev/level_design/time_and_weather/1_time_and_weather_museum.tscn", "res://scenes/dev/level_design/time_and_weather/2_time_and_weather_museum.tscn", "res://scenes/dev/level_design/time_and_weather/quest.tres", "res://scenes/dev/playground/unify_abilities/quest.tres", "res://scenes/dev/playground/unify_abilities/unify_abilities_test.tscn", "res://scenes/dev/playground/unify_abilities/unify_abilities_test_projectile.tscn", "res://scenes/dev/repel/custom_repellable_objects/custom_repellable_objects_test.tscn", "res://scenes/dev/repel/custom_repellable_objects/quest.tres", "res://scenes/dev/repel/ink_combat/ink_combat_test.tscn", "res://scenes/dev/repel/ink_combat/quest.tres", "res://scenes/game_elements/characters/components/character_sprites_museum.tscn", "res://scenes/game_elements/characters/components/health_bar/health_bar.tscn", "res://scenes/game_elements/characters/components/projectile_test.tscn", "res://scenes/game_elements/characters/enemies/guard/guard.tscn", "res://scenes/game_elements/characters/enemies/mothsache/Mothsache.tscn", "res://scenes/game_elements/characters/enemies/throwing_enemy/throwing_enemy.tscn", "res://scenes/game_elements/characters/enemies/void_spreading_enemy/components/void_particles.tscn", "res://scenes/game_elements/characters/enemies/void_spreading_enemy/void_spreading_enemy.tscn", "res://scenes/game_elements/characters/npcs/cat/cat.tscn", "res://scenes/game_elements/characters/npcs/components/default_helper.dialogue", "res://scenes/game_elements/characters/npcs/components/skin_tones_test.tscn", "res://scenes/game_elements/characters/npcs/elder/components/story_quest_starter.dialogue", "res://scenes/game_elements/characters/npcs/elder/components/template_quest_starter.dialogue", "res://scenes/game_elements/characters/npcs/elder/story_quest_elder.tscn", "res://scenes/game_elements/characters/npcs/elder/template_elder.tscn", "res://scenes/game_elements/characters/npcs/musician/musician.tscn", "res://scenes/game_elements/characters/npcs/npc_prop/fray_axeman.tscn", "res://scenes/game_elements/characters/npcs/npc_prop/fray_hammerman.tscn", "res://scenes/game_elements/characters/npcs/npc_prop/fray_idle.tscn", "res://scenes/game_elements/characters/npcs/talker/components/default.dialogue", "res://scenes/game_elements/characters/npcs/talker/talker.tscn", "res://scenes/game_elements/characters/npcs/townie.tscn", "res://scenes/game_elements/characters/player/components/player_hook.tscn", "res://scenes/game_elements/characters/player/components/player_repel.tscn", "res://scenes/game_elements/characters/player/player.tscn", "res://scenes/game_elements/components/elements_scale_museum.tscn", "res://scenes/game_elements/fx/clouds_shadow/clouds_shadow.tscn", "res://scenes/game_elements/fx/curly_trail/curly_trail.tscn", "res://scenes/game_elements/fx/fog/fog.tscn", "res://scenes/game_elements/fx/liquid_big_splat/liquid_big_splat.tscn", "res://scenes/game_elements/fx/liquid_small_splat/liquid_small_splat.tscn", "res://scenes/game_elements/fx/liquid_trail.tscn", "res://scenes/game_elements/fx/rain/rain.tscn", "res://scenes/game_elements/fx/rope_shatter.tscn", "res://scenes/game_elements/fx/shine_particles/shine_particles.tscn", "res://scenes/game_elements/fx/stitch_trail/stitch_trail.tscn", "res://scenes/game_elements/fx/time_and_weather/time_and_weather.tscn", "res://scenes/game_elements/fx/world_rewoven/components/line_trails_test.tscn", "res://scenes/game_elements/fx/world_rewoven/components/world_rewoven_cutscene_1.tscn", "res://scenes/game_elements/fx/world_rewoven/components/world_rewoven_cutscene_2.tscn", "res://scenes/game_elements/props/all_hooked/all_hooked.tscn", "res://scenes/game_elements/props/background_music/background_music.tscn", "res://scenes/game_elements/props/buildings/house/house_1.tscn", "res://scenes/game_elements/props/buildings/house/house_2.tscn", "res://scenes/game_elements/props/buildings/house/ruined_house.tscn", "res://scenes/game_elements/props/buildings/inn/inn.tscn", "res://scenes/game_elements/props/buildings/temple/temple.tscn", "res://scenes/game_elements/props/buildings/tower/tower.tscn", "res://scenes/game_elements/props/button_item/button_item.tscn", "res://scenes/game_elements/props/checkpoint/checkpoint.tscn", "res://scenes/game_elements/props/checkpoint/components/checkpoint.dialogue", "res://scenes/game_elements/props/collectible_item/collectible_item.tscn", "res://scenes/game_elements/props/collectible_item/components/collectible_item_test.tscn", "res://scenes/game_elements/props/decoration/books/books.tscn", "res://scenes/game_elements/props/decoration/bunny/bunny.tscn", "res://scenes/game_elements/props/decoration/bush/bush.tscn", "res://scenes/game_elements/props/decoration/butterfly/butterfly.tscn", "res://scenes/game_elements/props/decoration/capycorn/capycorn.tscn", "res://scenes/game_elements/props/decoration/crops/barley.tscn", "res://scenes/game_elements/props/decoration/crops/carrot.tscn", "res://scenes/game_elements/props/decoration/crops/tomato.tscn", "res://scenes/game_elements/props/decoration/flower/flower.tscn", "res://scenes/game_elements/props/decoration/hiding_mushroom/hiding_mushroom.tscn", "res://scenes/game_elements/props/decoration/rock/fabric_rock.tscn", "res://scenes/game_elements/props/decoration/rock/rock.tscn", "res://scenes/game_elements/props/decoration/sheep/sheep.tscn", "res://scenes/game_elements/props/decoration/spool/spool.tscn", "res://scenes/game_elements/props/decoration/water_rock/water_rock.tscn", "res://scenes/game_elements/props/door/horizontal_door.tscn", "res://scenes/game_elements/props/door/vertical_door.tscn", "res://scenes/game_elements/props/filling_barrel/filling_barrel.tscn", "res://scenes/game_elements/props/filling_barrel/fragile_barrel.tscn", "res://scenes/game_elements/props/fixed_size_label/fixed_size_label.tscn", "res://scenes/game_elements/props/hint/hint.tscn", "res://scenes/game_elements/props/hook_control/hook_control.tscn", "res://scenes/game_elements/props/hookable_area/components/hookable_indicator.tscn", "res://scenes/game_elements/props/hookable_box/hookable_box.tscn", "res://scenes/game_elements/props/hookable_button_item/hookable_button_item.tscn", "res://scenes/game_elements/props/hookable_lever/hookable_lever.tscn", "res://scenes/game_elements/props/hookable_needle/hookable_needle.tscn", "res://scenes/game_elements/props/hookable_pin/hookable_pin.tscn", "res://scenes/game_elements/props/interact_area/interact_indicator.tscn", "res://scenes/game_elements/props/lever/lever.tscn", "res://scenes/game_elements/props/powerup/components/default_powerup.dialogue", "res://scenes/game_elements/props/powerup/powerup.tscn", "res://scenes/game_elements/props/projectile/ink_blob_projectile.tscn", "res://scenes/game_elements/props/repellable_ball/repellable_ball.tscn", "res://scenes/game_elements/props/repellable_box/repellable_box.tscn", "res://scenes/game_elements/props/repellable_lever/repellable_lever.tscn", "res://scenes/game_elements/props/sequence_puzzle_hint_sign/sequence_puzzle_hint_sign.tscn", "res://scenes/game_elements/props/sequence_puzzle_object/sequence_puzzle_object.tscn", "res://scenes/game_elements/props/sign/sign.tscn", "res://scenes/game_elements/props/spawn_point/spawn_point.tscn", "res://scenes/game_elements/props/teleporter/quest_teleporter.tscn", "res://scenes/game_elements/props/teleporter/teleporter.tscn", "res://scenes/game_elements/props/tileomatic/tileomatic_test.tscn", "res://scenes/game_elements/props/tree/tree.tscn", "res://scenes/game_elements/props/tree/tree_void_affected.tscn", "res://scenes/game_elements/props/collectible_item/components/collectible_item.gd", "res://scenes/game_elements/props/powerup/components/powerup.gd", "res://scenes/game_logic/talk_behavior.gd", "res://scenes/globals/pause/pause_overlay.tscn", "res://scenes/globals/pause/quest_abandoned.dialogue", "res://scenes/menus/debug/components/debug_completed_quests.tscn", "res://scenes/menus/debug/components/debug_player_abilities.tscn", "res://scenes/menus/debug/debug_settings.tscn", "res://scenes/menus/options/components/back_button.tscn", "res://scenes/menus/options/components/input_settings.tscn", "res://scenes/menus/options/components/language_settings.tscn", "res://scenes/menus/options/components/sound_settings.tscn", "res://scenes/menus/options/components/video_settings.tscn", "res://scenes/menus/options/components/volume_slider.tscn", "res://scenes/menus/options/options.tscn", "res://scenes/menus/quest_separator/quest_separator.tscn", "res://scenes/menus/title/components/main_menu.tscn", "res://scenes/menus/title/components/main_menu.gd", "res://scenes/ui_elements/input_hints/aim_input_hint.tscn", "res://scenes/ui_elements/input_hints/back_input_hint.tscn", "res://scenes/ui_elements/input_hints/interact_input_hint.tscn", "res://scenes/ui_elements/input_hints/movement_input_hint.tscn", "res://scenes/ui_elements/input_hints/repel_input_hint.tscn", "res://scenes/ui_elements/input_hints/reset_input_hint.tscn", "res://scenes/ui_elements/input_hints/run_input_hint.tscn", "res://scenes/ui_elements/input_hints/skip_input_hint.tscn", "res://scenes/ui_elements/input_hints/swipe_input_hint.tscn", "res://scenes/ui_elements/input_hints/tap_input_hint.tscn", "res://scenes/ui_elements/input_hints/throw_input_hint.tscn", "res://scenes/ui_elements/input_hints/undo_input_hint.tscn", "res://scenes/quests/template_quests/NO_EDIT/0_NO_EDIT_intro/NO_EDIT_intro.tscn", "res://scenes/quests/template_quests/NO_EDIT/0_NO_EDIT_intro/NO_EDIT_intro_components/NO_EDIT_intro.dialogue", "res://scenes/quests/template_quests/NO_EDIT/1_NO_EDIT_stealth/NO_EDIT_stealth.tscn", "res://scenes/quests/template_quests/NO_EDIT/1_NO_EDIT_stealth/NO_EDIT_stealth_components/NO_EDIT_checkpoint.dialogue", "res://scenes/quests/template_quests/NO_EDIT/1_NO_EDIT_stealth/NO_EDIT_stealth_components/NO_EDIT_collected.dialogue", "res://scenes/quests/template_quests/NO_EDIT/1_NO_EDIT_stealth/NO_EDIT_stealth_components/NO_EDIT_stealth.dialogue", "res://scenes/quests/template_quests/NO_EDIT/2_NO_EDIT_combat/NO_EDIT_combat.tscn", "res://scenes/quests/template_quests/NO_EDIT/2_NO_EDIT_combat/NO_EDIT_combat_components/NO_EDIT_combat.dialogue", "res://scenes/quests/template_quests/NO_EDIT/2_NO_EDIT_combat/NO_EDIT_combat_components/NO_EDIT_projectile.tscn", "res://scenes/quests/template_quests/NO_EDIT/3_NO_EDIT_sequence_puzzle/NO_EDIT_sequence_puzzle.dialogue", "res://scenes/quests/template_quests/NO_EDIT/3_NO_EDIT_sequence_puzzle/NO_EDIT_sequence_puzzle.tscn", "res://scenes/quests/template_quests/NO_EDIT/4_NO_EDIT_outro/NO_EDIT_outro.tscn", "res://scenes/quests/template_quests/NO_EDIT/4_NO_EDIT_outro/NO_EDIT_outro_components/NO_EDIT_outro.dialogue", "res://scenes/quests/template_quests/NO_EDIT/NO_EDIT_basic_scene.tscn", "res://scenes/quests/template_quests/NO_EDIT/quest.tres", "res://scenes/quests/template_quests/teleporter_challenge/teleporter_challenge.tscn", "res://scenes/quests/template_quests/void_challenge/void_challenge.tscn") [layer_names] diff --git a/scenes/dev/basics/visuals/visuals_test.tscn b/scenes/dev/basics/visuals/visuals_test.tscn index cf76fac460..6cb37baddf 100644 --- a/scenes/dev/basics/visuals/visuals_test.tscn +++ b/scenes/dev/basics/visuals/visuals_test.tscn @@ -325,7 +325,6 @@ collision_layer = 32 collision_mask = 0 script = ExtResource("30_qo1v4") action_text = "Activate" -action_type = 1 metadata/_custom_type_script = "uid://du8wfijr35r35" [node name="CollisionShape2D" type="CollisionShape2D" parent="OnTheGround/YSortExample/FabricRock/InteractAreaEnable" unique_id=1791995955] @@ -342,7 +341,6 @@ collision_layer = 32 collision_mask = 0 script = ExtResource("30_qo1v4") action_text = "Deactivate" -action_type = 1 metadata/_custom_type_script = "uid://du8wfijr35r35" [node name="CollisionShape2D" type="CollisionShape2D" parent="OnTheGround/YSortExample/FabricRock2/InteractAreaDisable" unique_id=1912479031] diff --git a/scenes/dev/dev_archipelago.tscn b/scenes/dev/dev_archipelago.tscn index ea97ea0165..33088cf6ff 100644 --- a/scenes/dev/dev_archipelago.tscn +++ b/scenes/dev/dev_archipelago.tscn @@ -919,7 +919,6 @@ collision_layer = 32 collision_mask = 0 script = ExtResource("39_rjphr") action_text = "Annoy" -action_type = 1 metadata/_custom_type_script = "uid://du8wfijr35r35" [node name="CollisionShape2D" type="CollisionShape2D" parent="OnTheGround/Node2D/SheepChase/Townie/InteractArea" unique_id=1906089914] diff --git a/scenes/dev/level_design/area_filler/interactive_area_filler_test.tscn b/scenes/dev/level_design/area_filler/interactive_area_filler_test.tscn index dfb945cb61..d5b3da21dc 100644 --- a/scenes/dev/level_design/area_filler/interactive_area_filler_test.tscn +++ b/scenes/dev/level_design/area_filler/interactive_area_filler_test.tscn @@ -60,7 +60,6 @@ collision_layer = 32 collision_mask = 0 script = ExtResource("6_e7oi0") action_text = "Regenerate" -action_type = 1 metadata/_custom_type_script = "uid://du8wfijr35r35" [node name="CollisionShape2D" type="CollisionShape2D" parent="OnTheGround/FabricRock/InteractArea" unique_id=1977446241] @@ -75,7 +74,6 @@ collision_layer = 32 collision_mask = 0 script = ExtResource("6_e7oi0") action_text = "Decrease" -action_type = 1 metadata/_custom_type_script = "uid://du8wfijr35r35" [node name="CollisionShape2D" type="CollisionShape2D" parent="OnTheGround/FabricRock2/InteractAreaDecrease" unique_id=876564450] @@ -90,7 +88,6 @@ collision_layer = 32 collision_mask = 0 script = ExtResource("6_e7oi0") action_text = "Increase" -action_type = 1 metadata/_custom_type_script = "uid://du8wfijr35r35" [node name="CollisionShape2D" type="CollisionShape2D" parent="OnTheGround/FabricRock3/InteractAreaIncrease" unique_id=1688650151] diff --git a/scenes/dev/level_design/time_and_weather/2_time_and_weather_museum.tscn b/scenes/dev/level_design/time_and_weather/2_time_and_weather_museum.tscn index 87d608335f..1d335c426b 100644 --- a/scenes/dev/level_design/time_and_weather/2_time_and_weather_museum.tscn +++ b/scenes/dev/level_design/time_and_weather/2_time_and_weather_museum.tscn @@ -100,7 +100,6 @@ collision_layer = 32 collision_mask = 0 script = ExtResource("15_o3luo") action_text = "6 AM" -action_type = 1 metadata/_custom_type_script = "uid://du8wfijr35r35" [node name="CollisionShape2D" type="CollisionShape2D" parent="OnTheGround/FabricRock/InteractAreaMorning" unique_id=223757199] @@ -117,7 +116,6 @@ collision_layer = 32 collision_mask = 0 script = ExtResource("15_o3luo") action_text = "6 PM" -action_type = 1 metadata/_custom_type_script = "uid://du8wfijr35r35" [node name="CollisionShape2D" type="CollisionShape2D" parent="OnTheGround/FabricRock2/InteractAreaEvening" unique_id=943679952] @@ -134,7 +132,6 @@ collision_layer = 32 collision_mask = 0 script = ExtResource("15_o3luo") action_text = "10 PM" -action_type = 1 metadata/_custom_type_script = "uid://du8wfijr35r35" [node name="CollisionShape2D" type="CollisionShape2D" parent="OnTheGround/FabricRock3/InteractAreaNight" unique_id=132025755] diff --git a/scenes/game_elements/characters/npcs/cat/cat.tscn b/scenes/game_elements/characters/npcs/cat/cat.tscn index e12c0ac826..b77c2273a2 100644 --- a/scenes/game_elements/characters/npcs/cat/cat.tscn +++ b/scenes/game_elements/characters/npcs/cat/cat.tscn @@ -63,7 +63,6 @@ collision_layer = 32 collision_mask = 0 script = ExtResource("4_8kxh7") action_text = "Pet the cat" -action_type = 1 metadata/_custom_type_script = "uid://du8wfijr35r35" [node name="CollisionShape2D" type="CollisionShape2D" parent="InteractArea" unique_id=1720455095] diff --git a/scenes/game_elements/characters/player/components/player_interaction.gd b/scenes/game_elements/characters/player/components/player_interaction.gd index 459e07af94..a1fc528d5f 100644 --- a/scenes/game_elements/characters/player/components/player_interaction.gd +++ b/scenes/game_elements/characters/player/components/player_interaction.gd @@ -35,15 +35,6 @@ func get_interact_action() -> String: return "" -## Returns the kind of [member character]'s current interact action, for example -## to choose an icon. Only meaningful while [method get_interact_action] is not -## empty. Use [signal interact_action_changed] to monitor for changes. -func get_interact_action_type() -> InteractArea.ActionType: - if character_sight.interact_area != null: - return character_sight.interact_area.action_type - return InteractArea.ActionType.TALK - - func _is_interacting() -> bool: return not character_sight.monitoring diff --git a/scenes/game_elements/props/collectible_item/collectible_item.tscn b/scenes/game_elements/props/collectible_item/collectible_item.tscn index bd957edad6..641bcd9fd1 100644 --- a/scenes/game_elements/props/collectible_item/collectible_item.tscn +++ b/scenes/game_elements/props/collectible_item/collectible_item.tscn @@ -714,7 +714,6 @@ collision_mask = 0 script = ExtResource("2_1kegn") marker = NodePath("Marker") action_text = "Collect Memory" -action_type = 1 metadata/_custom_type_script = "uid://du8wfijr35r35" [node name="CollisionShape2D" type="CollisionShape2D" parent="InteractArea" unique_id=1121983883] diff --git a/scenes/game_elements/props/decoration/sheep/sheep.tscn b/scenes/game_elements/props/decoration/sheep/sheep.tscn index c1643d9d14..1d4dd44a03 100644 --- a/scenes/game_elements/props/decoration/sheep/sheep.tscn +++ b/scenes/game_elements/props/decoration/sheep/sheep.tscn @@ -59,7 +59,6 @@ collision_layer = 32 collision_mask = 0 script = ExtResource("3_5wm27") action_text = "Annoy the sheep" -action_type = 1 metadata/_custom_type_script = "uid://du8wfijr35r35" [node name="CollisionShape2D" type="CollisionShape2D" parent="InteractArea" unique_id=1330536002] diff --git a/scenes/game_elements/props/eternal_loom/eternal_loom.tscn b/scenes/game_elements/props/eternal_loom/eternal_loom.tscn index dd32ae2607..d13f19a7c4 100644 --- a/scenes/game_elements/props/eternal_loom/eternal_loom.tscn +++ b/scenes/game_elements/props/eternal_loom/eternal_loom.tscn @@ -182,7 +182,6 @@ collision_mask = 0 script = ExtResource("3_mjlja") marker = NodePath("Marker") action_text = "Use Eternal Loom" -action_type = 1 metadata/_custom_type_script = "uid://du8wfijr35r35" [node name="CollisionShape2D" type="CollisionShape2D" parent="InteractArea" unique_id=1537085446] diff --git a/scenes/game_elements/props/hook_control/components/hook_control.gd b/scenes/game_elements/props/hook_control/components/hook_control.gd index 7d5070646a..b523af50b1 100644 --- a/scenes/game_elements/props/hook_control/components/hook_control.gd +++ b/scenes/game_elements/props/hook_control/components/hook_control.gd @@ -16,8 +16,9 @@ extends Node2D ## aim keys are ignored. They are also the movement keys. See ## [member Settings.keyboard_only]. Aiming with a joypad works in both cases. ## [br][br] -## On touchscreens, touching the screen aims towards the touch position, and -## dragging the finger keeps aiming. Lifting the finger throws. +## On touchscreens, swiping aims in the swipe direction, and lifting the finger +## throws. A swipe shorter than [constant SWIPE_MIN_DISTANCE], like a tap, doesn't +## aim or throw. ## [br][br] ## Aiming is effectively rotating the [member ray_cast_2d]. ## [br][br] @@ -41,6 +42,10 @@ enum State { AIMING_PAUSED, } +## How far, in viewport pixels, a finger has to move from where it touched the +## screen to count as a swipe. +const SWIPE_MIN_DISTANCE: float = 40.0 + ## How far a throw from this control can reach. ## This is the length of the [member ray_cast_2d]. @export_range(0.0, 500.0, 1.0, "or_greater") var string_length: float = 200.0: @@ -84,6 +89,10 @@ var _pointing_at_area: HookableArea ## The index of the finger touching the screen to aim and throw, or -1. var _touch_index: int = -1 +## Where the finger at [member _touch_index] touched the screen, in viewport +## coordinates. +var _touch_start_position: Vector2 + ## True if the finger was lifted, so the next frame should throw. var _touch_throw_requested: bool = false @@ -146,26 +155,38 @@ func _unhandled_input(_event: InputEvent) -> void: return -## Touching the screen aims towards the touch position, and dragging the -## finger keeps aiming. Lifting the finger throws. Only one finger is followed -## at a time. +## Swiping aims in the direction of the swipe, from where the finger touched +## the screen to where it is now. Lifting the finger throws, unless it ends up +## closer than [constant SWIPE_MIN_DISTANCE] to where it touched the screen. +## That way a tap doesn't throw, and moving the finger back cancels the throw. +## Only one finger is followed at a time. func _handle_touch(event: InputEvent) -> void: if event is InputEventScreenDrag: if event.index == _touch_index: - _aim_at(_screen_to_global(event.position)) + _aim_with_swipe(event.position) elif event.pressed: if _touch_index != -1: return _touch_index = event.index - _aim_at(_screen_to_global(event.position)) + _touch_start_position = event.position elif event.index == _touch_index: _touch_index = -1 - _aim_at(_screen_to_global(event.position)) - _touch_throw_requested = true + if _aim_with_swipe(event.position): + _touch_throw_requested = true -func _screen_to_global(screen_position: Vector2) -> Vector2: - return get_canvas_transform().affine_inverse() * screen_position +## Aim in the direction of the swipe that ends at [param swipe_end], in viewport +## coordinates. Returns false without aiming if the swipe is too short. +func _aim_with_swipe(swipe_end: Vector2) -> bool: + var swipe := swipe_end - _touch_start_position + if swipe.length() < SWIPE_MIN_DISTANCE: + return false + # Convert the direction from viewport to world space, in case the canvas is + # rotated or scaled unevenly. + var direction := get_canvas_transform().affine_inverse().basis_xform(swipe) + _hook_angle = direction.angle() + _hook_angle_set = true + return true ## True if the aim actions should aim: when playing with a joypad, or with the @@ -329,8 +350,9 @@ func _process(_delta: float) -> void: var touch_throw := _touch_throw_requested _touch_throw_requested = false if touch_throw: - # The finger may have been lifted somewhere else than the last drag, so - # update the ray now instead of waiting for the next physics frame. + # The finger may have been lifted somewhere else than the last drag, or + # the swipe may have been too fast for any drag, so update the ray now + # instead of waiting for the next physics frame. ray_cast_2d.force_raycast_update() if state == State.AIMING: _update_pointing_at_area() diff --git a/scenes/game_elements/props/interact_area/interact_area.gd b/scenes/game_elements/props/interact_area/interact_area.gd index 430426ebc1..bbc8f4bc91 100644 --- a/scenes/game_elements/props/interact_area/interact_area.gd +++ b/scenes/game_elements/props/interact_area/interact_area.gd @@ -20,15 +20,6 @@ signal interaction_ended ## Emitted when characters start or stop seeing this area for interaction. signal observers_changed -## The kind of interaction, used to choose the icon of the interact touch button. -enum ActionType { - ## Talking to a character, like an NPC. - TALK, - ## Using an object, like a lever or a sign. Or collecting an object through - ## interaction, like a magical thread. - USE, -} - const SHAPE_DEBUG_COLOR := Color(0.6, 0.545, 0.0, 0.42) const INDICATOR_SCENE := preload("uid://d252j2mhya0kq") @@ -53,9 +44,6 @@ const INDICATOR_SCENE := preload("uid://d252j2mhya0kq") ## Text shown in the interact hint, describing what interacting does. @export var action_text: String = "Talk" -## The kind of interaction. The default matches the default [member action_text]. -@export var action_type: ActionType = ActionType.TALK - ## Whether this area is being observed by one or more characters. ## That is, if a [CharacterSight] area is seeing this area for interaction. var is_being_observed: bool: diff --git a/scenes/game_elements/props/lever/lever.tscn b/scenes/game_elements/props/lever/lever.tscn index 4bda1761cc..a0a00cb580 100644 --- a/scenes/game_elements/props/lever/lever.tscn +++ b/scenes/game_elements/props/lever/lever.tscn @@ -25,7 +25,6 @@ collision_layer = 32 collision_mask = 0 script = ExtResource("3_v1ps0") action_text = "Toggle" -action_type = 1 [node name="CollisionShape2D" type="CollisionShape2D" parent="InteractArea" unique_id=1068512935] shape = SubResource("CircleShape2D_ri4rx") diff --git a/scenes/game_elements/props/powerup/powerup.tscn b/scenes/game_elements/props/powerup/powerup.tscn index 2fcbfa9cff..03959f05af 100644 --- a/scenes/game_elements/props/powerup/powerup.tscn +++ b/scenes/game_elements/props/powerup/powerup.tscn @@ -85,7 +85,6 @@ collision_mask = 0 script = ExtResource("2_q7xhf") marker = NodePath("Marker") action_text = "Collect Repel" -action_type = 1 [node name="InteractCollision" type="CollisionShape2D" parent="InteractArea" unique_id=1651676696] unique_name_in_owner = true diff --git a/scenes/game_elements/props/sequence_puzzle_hint_sign/sequence_puzzle_hint_sign.tscn b/scenes/game_elements/props/sequence_puzzle_hint_sign/sequence_puzzle_hint_sign.tscn index c73cc47499..de8ac9a611 100644 --- a/scenes/game_elements/props/sequence_puzzle_hint_sign/sequence_puzzle_hint_sign.tscn +++ b/scenes/game_elements/props/sequence_puzzle_hint_sign/sequence_puzzle_hint_sign.tscn @@ -38,7 +38,6 @@ collision_mask = 0 script = ExtResource("3_oa8ov") disabled = true action_text = "Examine" -action_type = 1 metadata/_custom_type_script = "uid://du8wfijr35r35" [node name="CollisionShape2D" type="CollisionShape2D" parent="InteractArea" unique_id=1281208512] diff --git a/scenes/game_elements/props/sequence_puzzle_object/sequence_puzzle_object.tscn b/scenes/game_elements/props/sequence_puzzle_object/sequence_puzzle_object.tscn index 2fecba6601..ea859da304 100644 --- a/scenes/game_elements/props/sequence_puzzle_object/sequence_puzzle_object.tscn +++ b/scenes/game_elements/props/sequence_puzzle_object/sequence_puzzle_object.tscn @@ -32,7 +32,6 @@ collision_mask = 0 script = ExtResource("3_55nmp") marker = NodePath("Marker") action_text = "Tap" -action_type = 1 [node name="CollisionShape2D" type="CollisionShape2D" parent="InteractArea" unique_id=1667228689] position = Vector2(0, -16) diff --git a/scenes/globals/pause/pause_overlay.tscn b/scenes/globals/pause/pause_overlay.tscn index 8bc7443a1b..c9c03edc66 100644 --- a/scenes/globals/pause/pause_overlay.tscn +++ b/scenes/globals/pause/pause_overlay.tscn @@ -130,6 +130,7 @@ layout_mode = 2 [node name="HintsContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer/MarginContainer/HBoxContainer" unique_id=1399339993] unique_name_in_owner = true layout_mode = 2 +theme_type_variation = &"InputHintsContainer" [node name="PauseContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer/MarginContainer/HBoxContainer/HintsContainer" unique_id=300043409] layout_mode = 2 diff --git a/scenes/globals/settings/settings.gd b/scenes/globals/settings/settings.gd index 6654305ec3..d95aba1f0f 100644 --- a/scenes/globals/settings/settings.gd +++ b/scenes/globals/settings/settings.gd @@ -9,6 +9,9 @@ signal keyboard_only_changed ## [method can_choose_touch_controls] does. signal touch_controls_changed +## Emitted when [member left_handed] changes. +signal left_handed_changed + const SETTINGS_PATH := "user://settings.cfg" const META_SECTION := "Meta" @@ -25,6 +28,7 @@ const INPUT_SECTION := "Input" const KEYBOARD_ONLY_KEY := "Keyboard Only" const VIBRATION_STRENGTH_KEY := "Vibration Strength" const TOUCH_CONTROLS_KEY := "Touch Controls" +const LEFT_HANDED_KEY := "Left Handed" const TOUCHSCREEN_DETECTED_KEY := "Touchscreen Detected" const KEYBOARD_DETECTED_KEY := "Keyboard Detected" const JOYPAD_DETECTED_KEY := "Joypad Detected" @@ -101,6 +105,20 @@ const SMALL_SCREEN_SHORTEST_SIDE_DP := 600.0 _save() touch_controls_changed.emit() +## Mirror the touch controls horizontally, for left-handed players: the virtual +## joystick goes to the bottom right, and the input hints to the bottom left. +## The pause button stays at the top left, because the top right is for other +## parts of the HUD. +@export var left_handed: bool: + get: + return _settings.get_value(INPUT_SECTION, LEFT_HANDED_KEY, false) + set(new_value): + if new_value == left_handed: + return + _settings.set_value(INPUT_SECTION, LEFT_HANDED_KEY, new_value) + _save() + left_handed_changed.emit() + ## True once the player has touched the screen, which confirms that the device ## has a touchscreen. Set from [signal InputHelper.touchscreen_detected]. var touchscreen_detected: bool: diff --git a/scenes/menus/options/components/input_settings.tscn b/scenes/menus/options/components/input_settings.tscn index 6ee1eb38b1..c872a240e8 100644 --- a/scenes/menus/options/components/input_settings.tscn +++ b/scenes/menus/options/components/input_settings.tscn @@ -47,6 +47,14 @@ script = ExtResource("4_toggle") setting = &"touch_controls" visible_when = 2 +[node name="LeftHandedButton" type="CheckButton" parent="VBoxContainer/GridContainer" unique_id=1413010977] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Left-Handed" +script = ExtResource("4_toggle") +setting = &"left_handed" +visible_when = 3 + [node name="KeyboardOnlyButton" type="CheckButton" parent="VBoxContainer/GridContainer" unique_id=1592846307] layout_mode = 2 size_flags_horizontal = 3 diff --git a/scenes/menus/options/components/settings_toggle.gd b/scenes/menus/options/components/settings_toggle.gd index 6ed1bd236c..b614f8f058 100644 --- a/scenes/menus/options/components/settings_toggle.gd +++ b/scenes/menus/options/components/settings_toggle.gd @@ -14,6 +14,9 @@ enum VisibleWhen { ## Visible when the player can choose between touch and keyboard. See ## [method Settings.can_choose_touch_controls]. TOUCH_CHOICE_AVAILABLE, + ## Visible while using the touch controls, for settings that only apply to + ## touch. + IN_TOUCH_MODE, } ## The name of a property of the [Settings] singleton. @@ -64,6 +67,8 @@ func _update_visibility() -> void: match visible_when: VisibleWhen.NOT_IN_TOUCH_MODE: visible = not Settings.touch_controls + VisibleWhen.IN_TOUCH_MODE: + visible = Settings.touch_controls VisibleWhen.TOUCH_CHOICE_AVAILABLE: visible = Settings.can_choose_touch_controls() diff --git a/scenes/menus/storybook/storybook.tscn b/scenes/menus/storybook/storybook.tscn index 073e5fb83e..5a4bace3ae 100644 --- a/scenes/menus/storybook/storybook.tscn +++ b/scenes/menus/storybook/storybook.tscn @@ -140,6 +140,7 @@ theme_override_constants/margin_right = 8 unique_name_in_owner = true custom_minimum_size = Vector2(200, 0) layout_mode = 2 +theme_type_variation = &"InputHintsContainer" [node name="BackInputHint" parent="VBoxContainer/MarginContainer/HintsContainer" unique_id=1752840391 instance=ExtResource("back_input_hint")] layout_mode = 2 diff --git a/scenes/menus/title/components/credits.tscn b/scenes/menus/title/components/credits.tscn index a4b98fbe2a..5db86387cc 100644 --- a/scenes/menus/title/components/credits.tscn +++ b/scenes/menus/title/components/credits.tscn @@ -455,6 +455,7 @@ anchor_bottom = 1.0 offset_top = -64.0 offset_right = 104.0 grow_vertical = 0 +theme_type_variation = &"InputHintsContainer" [node name="BackInputHint" parent="HintsContainer" unique_id=1686403549 instance=ExtResource("11_lqn5t")] layout_mode = 2 diff --git a/scenes/quests/lore_quests/quest_001/1_music_puzzle/components/musical_rock.tscn b/scenes/quests/lore_quests/quest_001/1_music_puzzle/components/musical_rock.tscn index b1d925fcd1..6ec63d53e6 100644 --- a/scenes/quests/lore_quests/quest_001/1_music_puzzle/components/musical_rock.tscn +++ b/scenes/quests/lore_quests/quest_001/1_music_puzzle/components/musical_rock.tscn @@ -34,7 +34,6 @@ collision_mask = 0 script = ExtResource("3_sbibg") marker = NodePath("Marker") action_text = "Tap" -action_type = 1 [node name="CollisionShape2D" type="CollisionShape2D" parent="InteractArea" unique_id=1665980500] position = Vector2(0, -16) diff --git a/scenes/quests/story_quests/champ/2_sequence_puzzle/champ_sequence_puzzle_object.tscn b/scenes/quests/story_quests/champ/2_sequence_puzzle/champ_sequence_puzzle_object.tscn index df152800e7..af770cc33b 100644 --- a/scenes/quests/story_quests/champ/2_sequence_puzzle/champ_sequence_puzzle_object.tscn +++ b/scenes/quests/story_quests/champ/2_sequence_puzzle/champ_sequence_puzzle_object.tscn @@ -35,7 +35,6 @@ collision_mask = 0 script = ExtResource("4_g5jna") marker = NodePath("Marker") action_text = "Tap" -action_type = 1 [node name="CollisionShape2D" type="CollisionShape2D" parent="InteractArea" unique_id=1674431163] position = Vector2(3, -11) diff --git a/scenes/quests/story_quests/stella/3_stella_sequence_puzzle/stella_sequence_components/stella_tortoise_shell_gem.tscn b/scenes/quests/story_quests/stella/3_stella_sequence_puzzle/stella_sequence_components/stella_tortoise_shell_gem.tscn index 48225271fb..9336c58ff2 100644 --- a/scenes/quests/story_quests/stella/3_stella_sequence_puzzle/stella_sequence_components/stella_tortoise_shell_gem.tscn +++ b/scenes/quests/story_quests/stella/3_stella_sequence_puzzle/stella_sequence_components/stella_tortoise_shell_gem.tscn @@ -21,7 +21,6 @@ collision_mask = 0 script = ExtResource("3_wah4k") marker = NodePath("Marker") action_text = "Tap" -action_type = 1 metadata/_custom_type_script = "uid://du8wfijr35r35" [node name="Marker" type="Marker2D" parent="InteractArea" unique_id=1868145125] diff --git a/scenes/ui_elements/components/theme.tres b/scenes/ui_elements/components/theme.tres index 5acfc72a8c..92c0501af5 100644 --- a/scenes/ui_elements/components/theme.tres +++ b/scenes/ui_elements/components/theme.tres @@ -251,6 +251,8 @@ HintLabel/colors/font_color = Color(1, 1, 1, 1) HintLabel/colors/font_shadow_color = Color(0, 0, 0, 1) HintLabel/constants/shadow_offset_x = 2 HintLabel/constants/shadow_offset_y = 2 +InputHintsContainer/base_type = &"HBoxContainer" +InputHintsContainer/constants/separation = 16 Label/colors/font_color = Color(0, 0, 0, 1) LargeHintLabel/base_type = &"HintLabel" LargeHintLabel/font_sizes/font_size = 34 diff --git a/scenes/ui_elements/input_hints/swipe_input_hint.tscn b/scenes/ui_elements/input_hints/swipe_input_hint.tscn new file mode 100644 index 0000000000..04b04bfccf --- /dev/null +++ b/scenes/ui_elements/input_hints/swipe_input_hint.tscn @@ -0,0 +1,22 @@ +[gd_scene format=3 uid="uid://dnmkgadtvyhj4"] + +[ext_resource type="Material" uid="uid://cruf3tlajs4jo" path="res://scenes/ui_elements/input_hints/components/drop_shadow_material.tres" id="1_shadow"] +[ext_resource type="Texture2D" uid="uid://7kk2uvil7u0f" path="res://assets/third_party/kenney_input_prompts/touch_sheet_default.png" id="2_touch"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_swipe"] +atlas = ExtResource("2_touch") +region = Rect2(192, 192, 64, 64) + +[node name="SwipeInputHint" type="HBoxContainer" unique_id=2051490133] + +[node name="GestureIcon" type="TextureRect" parent="." unique_id=973350992] +material = ExtResource("1_shadow") +layout_mode = 2 +size_flags_vertical = 4 +texture = SubResource("AtlasTexture_swipe") + +[node name="Label" type="Label" parent="." unique_id=1033890931] +layout_mode = 2 +size_flags_vertical = 4 +theme_type_variation = &"HintLabel" +text = "Aim & Throw" diff --git a/scenes/ui_elements/input_hints/tap_input_hint.tscn b/scenes/ui_elements/input_hints/tap_input_hint.tscn new file mode 100644 index 0000000000..1dc1880d1b --- /dev/null +++ b/scenes/ui_elements/input_hints/tap_input_hint.tscn @@ -0,0 +1,25 @@ +[gd_scene format=3 uid="uid://drtixyupr0jp"] + +[ext_resource type="Script" uid="uid://ntkyy7hnkwh7" path="res://scenes/ui_elements/input_hints/components/labeled_input_hint.gd" id="1_labeled"] +[ext_resource type="Material" uid="uid://cruf3tlajs4jo" path="res://scenes/ui_elements/input_hints/components/drop_shadow_material.tres" id="2_shadow"] +[ext_resource type="Texture2D" uid="uid://7kk2uvil7u0f" path="res://assets/third_party/kenney_input_prompts/touch_sheet_default.png" id="3_touch"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_tap"] +atlas = ExtResource("3_touch") +region = Rect2(128, 64, 64, 64) + +[node name="TapInputHint" type="HBoxContainer" unique_id=855525137] +script = ExtResource("1_labeled") + +[node name="GestureIcon" type="TextureRect" parent="." unique_id=1372995400] +material = ExtResource("2_shadow") +layout_mode = 2 +size_flags_vertical = 4 +texture = SubResource("AtlasTexture_tap") + +[node name="Label" type="Label" parent="." unique_id=42730071] +unique_name_in_owner = true +layout_mode = 2 +size_flags_vertical = 4 +theme_type_variation = &"HintLabel" +text = "Repel" diff --git a/scenes/ui_elements/input_hud/input_hud.tscn b/scenes/ui_elements/input_hud/input_hud.tscn index b83952c6f7..3473f4d7d4 100644 --- a/scenes/ui_elements/input_hud/input_hud.tscn +++ b/scenes/ui_elements/input_hud/input_hud.tscn @@ -34,7 +34,7 @@ tabs_visible = false unique_name_in_owner = true z_index = 38 layout_mode = 2 -theme_override_constants/separation = 8 +theme_type_variation = &"InputHintsContainer" metadata/_tab_index = 0 [node name="MovementInputHint" parent="TabContainer/NormalControls" unique_id=30281671 instance=ExtResource("2_bewlk")] @@ -69,7 +69,7 @@ layout_mode = 2 unique_name_in_owner = true visible = false layout_mode = 2 -theme_override_constants/separation = 8 +theme_type_variation = &"InputHintsContainer" metadata/_tab_index = 1 [node name="MovementInputHints" parent="TabContainer/SokobanControls" unique_id=1797965313 instance=ExtResource("2_bewlk")] diff --git a/scenes/ui_elements/touch_controls/components/touch_controls.gd b/scenes/ui_elements/touch_controls/components/touch_controls.gd index 40f298db02..e16710ce4a 100644 --- a/scenes/ui_elements/touch_controls/components/touch_controls.gd +++ b/scenes/ui_elements/touch_controls/components/touch_controls.gd @@ -1,59 +1,195 @@ # SPDX-FileCopyrightText: The Threadbare Authors # SPDX-License-Identifier: MPL-2.0 +@tool extends Control -## Interact button textures for each [enum InteractArea.ActionType]. -const INTERACT_TEXTURES: Dictionary[InteractArea.ActionType, Texture2D] = { - InteractArea.ActionType.TALK: preload("uid://ns6755757cje"), - InteractArea.ActionType.USE: preload("uid://cjworl3bsj51d"), -} -const INTERACT_PRESSED_TEXTURES: Dictionary[InteractArea.ActionType, Texture2D] = { - InteractArea.ActionType.TALK: preload("uid://iwooycswl1bb"), - InteractArea.ActionType.USE: preload("uid://cmruhm7k3i3jm"), -} - -## Theme type variations of the interact label, without and with +## Theme type variations of the input hint labels, without and with ## [member Settings.large_text]. const HINT_LABEL_TYPE_VARIATION := &"HintLabel" const LARGE_HINT_LABEL_TYPE_VARIATION := &"LargeHintLabel" +## The left and right anchors of the virtual joystick area, in each layout. The +## right-handed ones must match the scene. +const RIGHT_HANDED_JOYSTICK_ANCHORS := Vector2(0.0, 0.4) +const LEFT_HANDED_JOYSTICK_ANCHORS := Vector2(0.6, 1.0) + @export var player: CharacterBody2D @export var sokoban_ruleset: RuleEngine @export var displaying_dialogue: bool +## Preview the layout of [member Settings.left_handed] in the editor. +@export_tool_button( + "Left-handed layout" +) var left_handed_editor_button: Callable = preview_left_handed_layout + +## Preview the default layout in the editor. +@export_tool_button( + "Right-handed layout" +) var right_handed_editor_button: Callable = preview_right_handed_layout + var player_interaction: PlayerInteraction var player_repel: PlayerRepel var player_hook: PlayerHook -@onready var interact_button: TouchScreenButton = %InteractButton -@onready var interact_label: Label = %InteractLabel -@onready var repel_button: TouchScreenButton = %RepelButton +## Where each finger that may be tapping touched the screen, by finger index. +## A finger is forgotten once it moves far enough to be a swipe instead. +var _tap_start_positions: Dictionary[int, Vector2] + @onready var pause_button: TouchScreenButton = %PauseButton @onready var virtual_joystick: VirtualJoystick = %VirtualJoystick +@onready var swipe_input_hint: Control = %SwipeInputHint +@onready var tap_input_hint: LabeledInputHint = %TapInputHint +@onready var virtual_joystick_container: Control = %VirtualJoystickContainer +@onready var touch_input_hints: MarginContainer = %TouchInputHints +@onready var input_hints_box: BoxContainer = %InputHintsBox func _ready() -> void: + if Engine.is_editor_hint(): + set_process_unhandled_input(false) + return + visibility_changed.connect(_on_visibility_changed) # TouchScreenButton doesn't mark its touches as handled, so the game would - # also get them. For example, tapping the interact button would throw the - # grappling hook too. - for button: TouchScreenButton in [interact_button, repel_button, pause_button]: - button.pressed.connect(get_viewport().set_input_as_handled) - button.released.connect(get_viewport().set_input_as_handled) + # also get them. For example, tapping the pause button would also be a tap + # for the game. + pause_button.pressed.connect(get_viewport().set_input_as_handled) + pause_button.released.connect(get_viewport().set_input_as_handled) Transitions.started.connect(update_visibility) Transitions.finished.connect(update_visibility) Settings.touch_controls_changed.connect(update_visibility) + Settings.left_handed_changed.connect(_on_left_handed_changed) + _on_left_handed_changed() func _notification(what: int) -> void: + if Engine.is_editor_hint(): + return match what: NOTIFICATION_PAUSED, NOTIFICATION_UNPAUSED: update_visibility() +func _on_left_handed_changed() -> void: + set_left_handed_layout(Settings.left_handed) + + +func preview_left_handed_layout() -> void: + set_left_handed_layout(true) + + +func preview_right_handed_layout() -> void: + set_left_handed_layout(false) + + +## Mirror the touch controls horizontally for left-handed players, or put them +## back. The virtual joystick goes to the opposite bottom corner, and the input +## hints to the opposite side. The pause button doesn't move, because the top +## right corner is for other parts of the HUD. +func set_left_handed_layout(left_handed: bool) -> void: + var joystick_anchors := ( + LEFT_HANDED_JOYSTICK_ANCHORS if left_handed else RIGHT_HANDED_JOYSTICK_ANCHORS + ) + # Set first the side that moves towards the edge of the screen. Otherwise + # one anchor would cross the other, and Control would clamp it. + var sides := [SIDE_RIGHT, SIDE_LEFT] if left_handed else [SIDE_LEFT, SIDE_RIGHT] + for side: Side in sides: + var anchor := joystick_anchors.x if side == SIDE_LEFT else joystick_anchors.y + virtual_joystick_container.set_anchor_and_offset(side, anchor, 0.0, false) + virtual_joystick_container.grow_horizontal = ( + Control.GROW_DIRECTION_BEGIN if left_handed else Control.GROW_DIRECTION_END + ) + + input_hints_box.alignment = ( + BoxContainer.ALIGNMENT_BEGIN if left_handed else BoxContainer.ALIGNMENT_END + ) + # Keep the swipe hint next to the edge of the screen, so it doesn't move + # when the text of the tap hint changes, for example from repel to interact. + input_hints_box.move_child(swipe_input_hint, 0 if left_handed else -1) + + # Keep the margin on the side of the edge of the screen. + var margin := maxi( + touch_input_hints.get_theme_constant(&"margin_left"), + touch_input_hints.get_theme_constant(&"margin_right"), + ) + touch_input_hints.remove_theme_constant_override(&"margin_left") + touch_input_hints.remove_theme_constant_override(&"margin_right") + touch_input_hints.add_theme_constant_override( + &"margin_left" if left_handed else &"margin_right", + margin, + ) + + func _on_visibility_changed() -> void: if not is_visible_in_tree(): _reset_virtual_joystick() + _tap_start_positions.clear() + + +## Tapping anywhere else than the pause button and the virtual joystick +## interacts, or repels if there is nothing to interact with. See +## [method _get_tap_action]. The pause button and the virtual joystick handle +## their own touches, so those don't get here. A finger that moves at least +## [constant HookControl.SWIPE_MIN_DISTANCE] is a swipe, which throws the +## grappling hook instead. See [HookControl]. +func _unhandled_input(event: InputEvent) -> void: + if event is InputEventScreenDrag: + if event.index in _tap_start_positions and _is_swipe(event): + _tap_start_positions.erase(event.index) + elif event is InputEventScreenTouch: + if event.pressed: + if is_visible_in_tree(): + _tap_start_positions[event.index] = event.position + elif event.index in _tap_start_positions: + var is_tap: bool = not event.canceled and not _is_swipe(event) + _tap_start_positions.erase(event.index) + if is_tap and is_visible_in_tree(): + var tap_action := _get_tap_action() + if not tap_action.is_empty(): + _press_action_once(tap_action) + + +func _is_swipe(event: InputEvent) -> bool: + var distance: float = event.position.distance_to(_tap_start_positions[event.index]) + return distance >= HookControl.SWIPE_MIN_DISTANCE + + +## The action that a tap presses: interact when there is something to +## interact with, otherwise repel if the player can. Empty if neither. +func _get_tap_action() -> StringName: + if player_interaction and not player_interaction.get_interact_action().is_empty(): + return &"interact" + if player_repel and player_repel.visible: + return &"repel" + return &"" + + +## Press and release [param action], like a [TouchScreenButton] does with its +## action. +## [br][br] +## The release waits for a later frame. If both happened in the same frame, +## [method Input.is_action_just_pressed] would still be true when handling the +## release, and for example [PlayerRepel] would keep repelling. Neither the next +## [signal SceneTree.process_frame] nor a short timer guarantee a later frame: +## the first is emitted in the same frame, and the second too if the frame is +## slow. +func _press_action_once(action: StringName) -> void: + _push_action(action, true) + var press_frame := Engine.get_process_frames() + while Engine.get_process_frames() == press_frame: + await get_tree().process_frame + _push_action(action, false) + + +func _push_action(action: StringName, pressed: bool) -> void: + if pressed: + Input.action_press(action) + else: + Input.action_release(action) + var action_event := InputEventAction.new() + action_event.action = action + action_event.pressed = pressed + get_viewport().push_input(action_event) ## Release the virtual joystick and the movement actions it keeps pressed. @@ -74,7 +210,12 @@ func update_visibility() -> void: and not displaying_dialogue and (player or sokoban_ruleset) ) - if player: + _update_hint_labels_font() + + if not player: + swipe_input_hint.visible = false + tap_input_hint.visible = false + else: player_interaction = player.get("player_interaction") as PlayerInteraction if ( player_interaction @@ -93,26 +234,26 @@ func update_visibility() -> void: _update_player_state() -## Apply [member Settings.large_text]. It's checked each time the label changes, -## instead of once, because this node lives as long as the game, and the player -## may change the setting meanwhile. -func _update_interact_label_font() -> void: - interact_label.theme_type_variation = ( +## Apply [member Settings.large_text]. It's checked each time the touch controls +## are shown, instead of once, because this node lives as long as the game, and +## the player may change the setting meanwhile in the pause menu. +func _update_hint_labels_font() -> void: + var type_variation := ( LARGE_HINT_LABEL_TYPE_VARIATION if Settings.large_text else HINT_LABEL_TYPE_VARIATION ) + for hint: Control in [swipe_input_hint, tap_input_hint]: + for label: Label in hint.find_children("*", "Label", true, false): + label.theme_type_variation = type_variation func _update_player_state() -> void: - if player_interaction: - var action := player_interaction.get_interact_action() - interact_button.visible = not action.is_empty() - interact_label.text = action - _update_interact_label_font() - var action_type := player_interaction.get_interact_action_type() - interact_button.texture_normal = INTERACT_TEXTURES[action_type] - interact_button.texture_pressed = INTERACT_PRESSED_TEXTURES[action_type] - else: - interact_button.visible = false - interact_label.visible = interact_button.visible + swipe_input_hint.visible = player_hook and player_hook.visible - repel_button.visible = player_repel and player_repel.visible and not interact_button.visible + var tap_action := _get_tap_action() + tap_input_hint.visible = not tap_action.is_empty() + match tap_action: + &"interact": + tap_input_hint.text = player_interaction.get_interact_action() + &"repel": + # The label translates it. + tap_input_hint.text = "Repel" diff --git a/scenes/ui_elements/touch_controls/touch_controls.tscn b/scenes/ui_elements/touch_controls/touch_controls.tscn index 503a82550a..1e19c709f7 100644 --- a/scenes/ui_elements/touch_controls/touch_controls.tscn +++ b/scenes/ui_elements/touch_controls/touch_controls.tscn @@ -3,10 +3,8 @@ [ext_resource type="Script" uid="uid://dyyshnmovujje" path="res://scenes/ui_elements/touch_controls/components/touch_controls.gd" id="1_mjavl"] [ext_resource type="Texture2D" uid="uid://djsqefyd16tyg" path="res://assets/first_party/user_interface/pause-touch-button.png" id="2_pt1mb"] [ext_resource type="Texture2D" uid="uid://dv5gfkbecnvas" path="res://assets/first_party/user_interface/pause-touch-button_pressed.png" id="3_qk0o5"] -[ext_resource type="Texture2D" uid="uid://byra1c7yc54mg" path="res://assets/first_party/user_interface/repel-touch-button.png" id="4_pk8s8"] -[ext_resource type="Texture2D" uid="uid://cttum8v2mb62v" path="res://assets/first_party/user_interface/repel-touch-button_pressed.png" id="5_dtb3f"] -[ext_resource type="Texture2D" uid="uid://ns6755757cje" path="res://assets/first_party/user_interface/interact_talk-touch-button.png" id="6_pt1mb"] -[ext_resource type="Texture2D" uid="uid://iwooycswl1bb" path="res://assets/first_party/user_interface/interact_talk-touch-button_pressed.png" id="7_qk0o5"] +[ext_resource type="PackedScene" uid="uid://dnmkgadtvyhj4" path="res://scenes/ui_elements/input_hints/swipe_input_hint.tscn" id="4_swipe"] +[ext_resource type="PackedScene" uid="uid://drtixyupr0jp" path="res://scenes/ui_elements/input_hints/tap_input_hint.tscn" id="5_tap"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_fhnvg"] size = Vector2(128, 128) @@ -20,9 +18,9 @@ grow_horizontal = 2 grow_vertical = 2 mouse_filter = 2 script = ExtResource("1_mjavl") -metadata/_edit_horizontal_guides_ = [593.0] -[node name="Control" type="Control" parent="." unique_id=2006198045] +[node name="PauseButtonContainer" type="Control" parent="." unique_id=2006198045] +unique_name_in_owner = true custom_minimum_size = Vector2(148, 148) layout_mode = 1 anchors_preset = 0 @@ -32,11 +30,11 @@ size_flags_horizontal = 8 size_flags_vertical = 3 mouse_filter = 2 -[node name="CenterContainer" type="BoxContainer" parent="Control" unique_id=759928299] +[node name="CenterContainer" type="BoxContainer" parent="PauseButtonContainer" unique_id=759928299] layout_mode = 1 mouse_filter = 2 -[node name="PauseButton" type="TouchScreenButton" parent="Control/CenterContainer" unique_id=1825489206] +[node name="PauseButton" type="TouchScreenButton" parent="PauseButtonContainer/CenterContainer" unique_id=1825489206] unique_name_in_owner = true position = Vector2(16, 16) texture_normal = ExtResource("2_pt1mb") @@ -44,17 +42,17 @@ texture_pressed = ExtResource("3_qk0o5") shape = SubResource("RectangleShape2D_fhnvg") action = "pause" -[node name="BottomLeftContainer" type="BoxContainer" parent="." unique_id=1803916095] -custom_minimum_size = Vector2(250, 250) +[node name="VirtualJoystickContainer" type="BoxContainer" parent="." unique_id=1803916095] +unique_name_in_owner = true +editor_description = "The anchors make this area proportional to the screen." layout_mode = 1 -anchors_preset = 2 -anchor_top = 1.0 +anchors_preset = -1 +anchor_top = 0.4 +anchor_right = 0.4 anchor_bottom = 1.0 -offset_top = -250.0 -offset_right = 250.0 grow_vertical = 0 -[node name="VirtualJoystick" type="VirtualJoystick" parent="BottomLeftContainer" unique_id=1528042620] +[node name="VirtualJoystick" type="VirtualJoystick" parent="VirtualJoystickContainer" unique_id=1528042620] unique_name_in_owner = true layout_mode = 2 size_flags_horizontal = 3 @@ -67,47 +65,30 @@ action_right = &"move_right" action_up = &"move_up" action_down = &"move_down" -[node name="BottomRightContainer" type="Control" parent="." unique_id=1744849055] +[node name="TouchInputHints" type="MarginContainer" parent="." unique_id=394809655] +unique_name_in_owner = true +editor_description = "The 8px margin on the side of the screen edge matches the InputHud one." layout_mode = 1 -anchors_preset = 3 -anchor_left = 1.0 +anchors_preset = 12 anchor_top = 1.0 anchor_right = 1.0 anchor_bottom = 1.0 -offset_left = -216.0 -offset_top = -175.0 -offset_right = -216.0 -offset_bottom = -175.0 -grow_horizontal = 0 +offset_top = -64.0 +grow_horizontal = 2 grow_vertical = 0 -mouse_filter = 2 +mouse_behavior_recursive = 1 +theme_override_constants/margin_right = 8 -[node name="RepelButton" type="TouchScreenButton" parent="BottomRightContainer" unique_id=675930575] +[node name="InputHintsBox" type="HBoxContainer" parent="TouchInputHints" unique_id=111976134] unique_name_in_owner = true -position = Vector2(30, -16) -texture_normal = ExtResource("4_pk8s8") -texture_pressed = ExtResource("5_dtb3f") -shape = SubResource("RectangleShape2D_fhnvg") -action = "repel" +layout_mode = 2 +theme_type_variation = &"InputHintsContainer" +alignment = 2 -[node name="InteractButton" type="TouchScreenButton" parent="BottomRightContainer" unique_id=1674418296] +[node name="TapInputHint" parent="TouchInputHints/InputHintsBox" unique_id=1650266329 instance=ExtResource("5_tap")] unique_name_in_owner = true -position = Vector2(30, -16) -texture_normal = ExtResource("6_pt1mb") -texture_pressed = ExtResource("7_qk0o5") -shape = SubResource("RectangleShape2D_fhnvg") -action = "interact" +layout_mode = 2 -[node name="InteractLabel" type="Label" parent="BottomRightContainer" unique_id=290364264] +[node name="SwipeInputHint" parent="TouchInputHints/InputHintsBox" unique_id=1390036316 instance=ExtResource("4_swipe")] unique_name_in_owner = true -layout_mode = 1 -anchors_preset = -1 -offset_left = -278.0 -offset_top = 28.0 -offset_right = 22.0 -offset_bottom = 68.0 -grow_horizontal = 0 -theme_type_variation = &"HintLabel" -text = "Interact" -horizontal_alignment = 2 -vertical_alignment = 1 +layout_mode = 2