From 81deaf81c800900e30046cb927be1c9d91ae61b8 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Thu, 4 Sep 2025 23:47:24 +0200 Subject: reorganize client gui files --- client/gui/components/blur_setup.gd | 24 + client/gui/components/blur_setup.gd.uid | 1 + client/gui/components/controller_button.gd | 41 ++ client/gui/components/controller_button.gd.uid | 1 + client/gui/components/message/chat_message.gd | 32 ++ client/gui/components/message/chat_message.gd.uid | 1 + client/gui/components/message/chat_message.tscn | 37 ++ client/gui/components/message/item/item_message.gd | 71 +++ .../components/message/item/item_message.gd.uid | 1 + .../gui/components/message/item/item_message.tscn | 48 ++ client/gui/components/message/item/item_render.gd | 41 ++ .../gui/components/message/item/item_render.gd.uid | 1 + .../gui/components/message/item/item_render.tscn | 23 + .../message/popup_message/pinned_item_messages.gd | 55 ++ .../popup_message/pinned_item_messages.gd.uid | 1 + .../popup_message/pinned_item_messages.tscn | 22 + .../message/popup_message/popup_message.gd | 230 +++++++++ .../message/popup_message/popup_message.gd.uid | 1 + .../message/popup_message/popup_message.tscn | 164 ++++++ .../message/popup_message/server_message.gd | 13 + .../message/popup_message/server_message.gd.uid | 1 + .../message/popup_message/server_message.tscn | 51 ++ client/gui/components/smart_margin_container.gd | 41 ++ .../gui/components/smart_margin_container.gd.uid | 1 + client/gui/components/touch_scroll_container.gd | 45 ++ .../gui/components/touch_scroll_container.gd.uid | 1 + client/gui/menus/character.gd | 96 ++++ client/gui/menus/character.gd.uid | 1 + client/gui/menus/character.tscn | 230 +++++++++ client/gui/menus/chat.gd | 48 ++ client/gui/menus/chat.gd.uid | 1 + client/gui/menus/chat.tscn | 56 +++ client/gui/menus/document/document.gd | 152 ++++++ client/gui/menus/document/document.gd.uid | 1 + client/gui/menus/document/document.tscn | 29 ++ client/gui/menus/entry.gd | 35 ++ client/gui/menus/entry.gd.uid | 1 + client/gui/menus/entry.tscn | 12 + client/gui/menus/error.gd | 23 + client/gui/menus/error.gd.uid | 1 + client/gui/menus/error.tscn | 70 +++ client/gui/menus/game.gd | 64 +++ client/gui/menus/game.gd.uid | 1 + client/gui/menus/game.tscn | 46 ++ client/gui/menus/ingame.gd | 82 +++ client/gui/menus/ingame.gd.uid | 1 + client/gui/menus/ingame.tscn | 142 ++++++ client/gui/menus/main/about.gd | 169 +++++++ client/gui/menus/main/about.gd.uid | 1 + client/gui/menus/main/about.tscn | 93 ++++ client/gui/menus/main/background.gd | 50 ++ client/gui/menus/main/background.gd.uid | 1 + client/gui/menus/main/background.tscn | 71 +++ client/gui/menus/main/clouds.gdshader | 36 ++ client/gui/menus/main/clouds.gdshader.uid | 1 + client/gui/menus/main/main.gd | 44 ++ client/gui/menus/main/main.gd.uid | 1 + client/gui/menus/main/main.tscn | 94 ++++ client/gui/menus/main/play.gd | 208 ++++++++ client/gui/menus/main/play.gd.uid | 1 + client/gui/menus/main/play.tscn | 149 ++++++ client/gui/menus/main/server_list_item.gd | 38 ++ client/gui/menus/main/server_list_item.gd.uid | 1 + client/gui/menus/main/server_list_item.tscn | 39 ++ client/gui/menus/menu.gd | 151 ++++++ client/gui/menus/menu.gd.uid | 1 + client/gui/menus/popup.gd | 32 ++ client/gui/menus/popup.gd.uid | 1 + client/gui/menus/popup.tscn | 52 ++ client/gui/menus/popup_large.gd | 25 + client/gui/menus/popup_large.gd.uid | 1 + client/gui/menus/popup_large.tscn | 74 +++ client/gui/menus/rating/desaturate.gdshader | 7 + client/gui/menus/rating/desaturate.gdshader.uid | 1 + client/gui/menus/rating/rating.gd | 65 +++ client/gui/menus/rating/rating.gd.uid | 1 + client/gui/menus/rating/rating.tscn | 168 +++++++ client/gui/menus/settings/button_setting.gd | 30 ++ client/gui/menus/settings/button_setting.gd.uid | 1 + client/gui/menus/settings/dropdown_setting.gd | 36 ++ client/gui/menus/settings/dropdown_setting.gd.uid | 1 + client/gui/menus/settings/game_setting.gd | 46 ++ client/gui/menus/settings/game_setting.gd.uid | 1 + client/gui/menus/settings/input/input_manager.gd | 101 ++++ .../gui/menus/settings/input/input_manager.gd.uid | 1 + client/gui/menus/settings/input/input_setting.gd | 39 ++ .../gui/menus/settings/input/input_setting.gd.uid | 1 + .../gui/menus/settings/input/input_value_node.gd | 74 +++ .../menus/settings/input/input_value_node.gd.uid | 1 + .../gui/menus/settings/input/input_value_node.tscn | 24 + client/gui/menus/settings/number_setting.gd | 41 ++ client/gui/menus/settings/number_setting.gd.uid | 1 + client/gui/menus/settings/path_setting.gd | 64 +++ client/gui/menus/settings/path_setting.gd.uid | 1 + client/gui/menus/settings/preset_row.gd | 46 ++ client/gui/menus/settings/preset_row.gd.uid | 1 + client/gui/menus/settings/range_setting.gd | 44 ++ client/gui/menus/settings/range_setting.gd.uid | 1 + client/gui/menus/settings/settings.gd | 40 ++ client/gui/menus/settings/settings.gd.uid | 1 + client/gui/menus/settings/settings.tscn | 61 +++ client/gui/menus/settings/settings_category.gd | 49 ++ client/gui/menus/settings/settings_category.gd.uid | 1 + client/gui/menus/settings/settings_root.gd | 40 ++ client/gui/menus/settings/settings_root.gd.uid | 1 + client/gui/menus/settings/settings_row.gd | 37 ++ client/gui/menus/settings/settings_row.gd.uid | 1 + client/gui/menus/settings/settings_row.tscn | 40 ++ client/gui/menus/settings/text_setting.gd | 38 ++ client/gui/menus/settings/text_setting.gd.uid | 1 + client/gui/menus/settings/toggle_setting.gd | 31 ++ client/gui/menus/settings/toggle_setting.gd.uid | 1 + client/gui/menus/setup/hairstyle_preview.gd | 27 + client/gui/menus/setup/hairstyle_preview.gd.uid | 1 + client/gui/menus/setup/hairstyle_preview.tscn | 55 ++ client/gui/menus/setup/setup.gd | 110 ++++ client/gui/menus/setup/setup.gd.uid | 1 + client/gui/menus/setup/setup.tscn | 398 +++++++++++++++ client/gui/menus/transition/scene_transition.gd | 66 +++ .../gui/menus/transition/scene_transition.gd.uid | 1 + client/gui/menus/transition/scene_transition.tscn | 135 +++++ .../menus/transition/text_loading_anim.gdshader | 13 + .../transition/text_loading_anim.gdshader.uid | 1 + client/gui/overlays/ingame/announce_title.gd | 42 ++ client/gui/overlays/ingame/announce_title.gd.uid | 1 + client/gui/overlays/ingame/chat.gd | 34 ++ client/gui/overlays/ingame/chat.gd.uid | 1 + client/gui/overlays/ingame/chat.tscn | 39 ++ client/gui/overlays/ingame/score.gd | 68 +++ client/gui/overlays/ingame/score.gd.uid | 1 + client/gui/overlays/ingame/score.tscn | 555 +++++++++++++++++++++ client/gui/overlays/lobby/lobby.gd | 204 ++++++++ client/gui/overlays/lobby/lobby.gd.uid | 1 + client/gui/overlays/lobby/lobby.tscn | 191 +++++++ client/gui/overlays/lobby/player.gd | 22 + client/gui/overlays/lobby/player.gd.uid | 1 + client/gui/overlays/lobby/player.tscn | 43 ++ client/gui/resources/fonts/font-azaret-mono.woff2 | Bin 0 -> 46132 bytes .../resources/fonts/font-azaret-mono.woff2.import | 35 ++ client/gui/resources/fonts/font-josefin-sans.woff2 | Bin 0 -> 47448 bytes .../resources/fonts/font-josefin-sans.woff2.import | 35 ++ .../gui/resources/fonts/font-sansita-swashed.woff2 | Bin 0 -> 92808 bytes .../fonts/font-sansita-swashed.woff2.import | 35 ++ client/gui/resources/icons/arrow.svg | 1 + client/gui/resources/icons/arrow.svg.import | 37 ++ client/gui/resources/icons/arrow_focus.svg | 1 + client/gui/resources/icons/arrow_focus.svg.import | 37 ++ client/gui/resources/icons/arrow_hover.svg | 1 + client/gui/resources/icons/arrow_hover.svg.import | 37 ++ client/gui/resources/icons/arrow_pressed.svg | 1 + .../gui/resources/icons/arrow_pressed.svg.import | 37 ++ client/gui/resources/icons/boost.webp | Bin 0 -> 3670 bytes client/gui/resources/icons/boost.webp.import | 34 ++ client/gui/resources/icons/circle.svg | 1 + client/gui/resources/icons/circle.svg.import | 37 ++ client/gui/resources/icons/controller_x.svg | 6 + client/gui/resources/icons/controller_x.svg.import | 37 ++ client/gui/resources/icons/controller_y.svg | 6 + client/gui/resources/icons/controller_y.svg.import | 37 ++ client/gui/resources/icons/hint.svg | 10 + client/gui/resources/icons/hint.svg.import | 37 ++ client/gui/resources/icons/interact.webp | Bin 0 -> 3604 bytes client/gui/resources/icons/interact.webp.import | 34 ++ client/gui/resources/icons/pause.webp | Bin 0 -> 3144 bytes client/gui/resources/icons/pause.webp.import | 34 ++ client/gui/resources/icons/plus.svg | 4 + client/gui/resources/icons/plus.svg.import | 37 ++ client/gui/resources/icons/reset.svg | 39 ++ client/gui/resources/icons/reset.svg.import | 37 ++ client/gui/resources/icons/select_directory.svg | 1 + .../resources/icons/select_directory.svg.import | 37 ++ client/gui/resources/icons/select_file.svg | 1 + client/gui/resources/icons/select_file.svg.import | 37 ++ client/gui/resources/icons/user.webp | Bin 0 -> 15122 bytes client/gui/resources/icons/user.webp.import | 34 ++ client/gui/resources/materials/blur_material.tres | 11 + .../resources/materials/dark_blur_material.tres | 11 + .../resources/materials/grayscale_material.tres | 6 + .../gui/resources/materials/printed_material.tres | 6 + client/gui/resources/shaders/blur_mix.gdshader | 34 ++ client/gui/resources/shaders/blur_mix.gdshader.uid | 1 + client/gui/resources/shaders/grayscale.gdshader | 25 + .../gui/resources/shaders/grayscale.gdshader.uid | 1 + client/gui/resources/shaders/paper.tres | 14 + client/gui/resources/shaders/printed.gdshader | 22 + client/gui/resources/shaders/printed.gdshader.uid | 1 + client/gui/resources/sounds/click.ogg | Bin 0 -> 24573 bytes client/gui/resources/sounds/click.ogg.import | 19 + client/gui/resources/sounds/failure.ogg | Bin 0 -> 8296 bytes client/gui/resources/sounds/failure.ogg.import | 19 + client/gui/resources/sounds/game_start.ogg | Bin 0 -> 73234 bytes client/gui/resources/sounds/game_start.ogg.import | 19 + client/gui/resources/sounds/hover.ogg | Bin 0 -> 15692 bytes client/gui/resources/sounds/hover.ogg.import | 19 + client/gui/resources/sounds/page.ogg | Bin 0 -> 11745 bytes client/gui/resources/sounds/page.ogg.import | 19 + client/gui/resources/sounds/sign.ogg | Bin 0 -> 17980 bytes client/gui/resources/sounds/sign.ogg.import | 19 + client/gui/resources/sounds/success.ogg | Bin 0 -> 10840 bytes client/gui/resources/sounds/success.ogg.import | 19 + client/gui/resources/style/error_focus_style.tres | 17 + client/gui/resources/style/focus_style.tres | 17 + client/gui/resources/style/hover_style.tres | 12 + .../style/item_bubble_progress_style.tres | 5 + .../item_bubble_progress_style_background.tres | 4 + .../gui/resources/style/lobby_panel_override.tres | 4 + client/gui/resources/style/normal_style.tres | 12 + client/gui/resources/style/panel_style.tres | 8 + .../gui/resources/style/panel_style_sidebar.tres | 3 + client/gui/resources/style/paper_panel_style.tres | 6 + client/gui/resources/theme/paper.tres | 109 ++++ client/gui/resources/theme/theme.tres | 70 +++ 212 files changed, 7813 insertions(+) create mode 100644 client/gui/components/blur_setup.gd create mode 100644 client/gui/components/blur_setup.gd.uid create mode 100644 client/gui/components/controller_button.gd create mode 100644 client/gui/components/controller_button.gd.uid create mode 100644 client/gui/components/message/chat_message.gd create mode 100644 client/gui/components/message/chat_message.gd.uid create mode 100644 client/gui/components/message/chat_message.tscn create mode 100644 client/gui/components/message/item/item_message.gd create mode 100644 client/gui/components/message/item/item_message.gd.uid create mode 100644 client/gui/components/message/item/item_message.tscn create mode 100644 client/gui/components/message/item/item_render.gd create mode 100644 client/gui/components/message/item/item_render.gd.uid create mode 100644 client/gui/components/message/item/item_render.tscn create mode 100644 client/gui/components/message/popup_message/pinned_item_messages.gd create mode 100644 client/gui/components/message/popup_message/pinned_item_messages.gd.uid create mode 100644 client/gui/components/message/popup_message/pinned_item_messages.tscn create mode 100644 client/gui/components/message/popup_message/popup_message.gd create mode 100644 client/gui/components/message/popup_message/popup_message.gd.uid create mode 100644 client/gui/components/message/popup_message/popup_message.tscn create mode 100644 client/gui/components/message/popup_message/server_message.gd create mode 100644 client/gui/components/message/popup_message/server_message.gd.uid create mode 100644 client/gui/components/message/popup_message/server_message.tscn create mode 100644 client/gui/components/smart_margin_container.gd create mode 100644 client/gui/components/smart_margin_container.gd.uid create mode 100644 client/gui/components/touch_scroll_container.gd create mode 100644 client/gui/components/touch_scroll_container.gd.uid create mode 100644 client/gui/menus/character.gd create mode 100644 client/gui/menus/character.gd.uid create mode 100644 client/gui/menus/character.tscn create mode 100644 client/gui/menus/chat.gd create mode 100644 client/gui/menus/chat.gd.uid create mode 100644 client/gui/menus/chat.tscn create mode 100644 client/gui/menus/document/document.gd create mode 100644 client/gui/menus/document/document.gd.uid create mode 100644 client/gui/menus/document/document.tscn create mode 100644 client/gui/menus/entry.gd create mode 100644 client/gui/menus/entry.gd.uid create mode 100644 client/gui/menus/entry.tscn create mode 100644 client/gui/menus/error.gd create mode 100644 client/gui/menus/error.gd.uid create mode 100644 client/gui/menus/error.tscn create mode 100644 client/gui/menus/game.gd create mode 100644 client/gui/menus/game.gd.uid create mode 100644 client/gui/menus/game.tscn create mode 100644 client/gui/menus/ingame.gd create mode 100644 client/gui/menus/ingame.gd.uid create mode 100644 client/gui/menus/ingame.tscn create mode 100644 client/gui/menus/main/about.gd create mode 100644 client/gui/menus/main/about.gd.uid create mode 100644 client/gui/menus/main/about.tscn create mode 100644 client/gui/menus/main/background.gd create mode 100644 client/gui/menus/main/background.gd.uid create mode 100644 client/gui/menus/main/background.tscn create mode 100644 client/gui/menus/main/clouds.gdshader create mode 100644 client/gui/menus/main/clouds.gdshader.uid create mode 100644 client/gui/menus/main/main.gd create mode 100644 client/gui/menus/main/main.gd.uid create mode 100644 client/gui/menus/main/main.tscn create mode 100644 client/gui/menus/main/play.gd create mode 100644 client/gui/menus/main/play.gd.uid create mode 100644 client/gui/menus/main/play.tscn create mode 100644 client/gui/menus/main/server_list_item.gd create mode 100644 client/gui/menus/main/server_list_item.gd.uid create mode 100644 client/gui/menus/main/server_list_item.tscn create mode 100644 client/gui/menus/menu.gd create mode 100644 client/gui/menus/menu.gd.uid create mode 100644 client/gui/menus/popup.gd create mode 100644 client/gui/menus/popup.gd.uid create mode 100644 client/gui/menus/popup.tscn create mode 100644 client/gui/menus/popup_large.gd create mode 100644 client/gui/menus/popup_large.gd.uid create mode 100644 client/gui/menus/popup_large.tscn create mode 100644 client/gui/menus/rating/desaturate.gdshader create mode 100644 client/gui/menus/rating/desaturate.gdshader.uid create mode 100644 client/gui/menus/rating/rating.gd create mode 100644 client/gui/menus/rating/rating.gd.uid create mode 100644 client/gui/menus/rating/rating.tscn create mode 100644 client/gui/menus/settings/button_setting.gd create mode 100644 client/gui/menus/settings/button_setting.gd.uid create mode 100644 client/gui/menus/settings/dropdown_setting.gd create mode 100644 client/gui/menus/settings/dropdown_setting.gd.uid create mode 100644 client/gui/menus/settings/game_setting.gd create mode 100644 client/gui/menus/settings/game_setting.gd.uid create mode 100644 client/gui/menus/settings/input/input_manager.gd create mode 100644 client/gui/menus/settings/input/input_manager.gd.uid create mode 100644 client/gui/menus/settings/input/input_setting.gd create mode 100644 client/gui/menus/settings/input/input_setting.gd.uid create mode 100644 client/gui/menus/settings/input/input_value_node.gd create mode 100644 client/gui/menus/settings/input/input_value_node.gd.uid create mode 100644 client/gui/menus/settings/input/input_value_node.tscn create mode 100644 client/gui/menus/settings/number_setting.gd create mode 100644 client/gui/menus/settings/number_setting.gd.uid create mode 100644 client/gui/menus/settings/path_setting.gd create mode 100644 client/gui/menus/settings/path_setting.gd.uid create mode 100644 client/gui/menus/settings/preset_row.gd create mode 100644 client/gui/menus/settings/preset_row.gd.uid create mode 100644 client/gui/menus/settings/range_setting.gd create mode 100644 client/gui/menus/settings/range_setting.gd.uid create mode 100644 client/gui/menus/settings/settings.gd create mode 100644 client/gui/menus/settings/settings.gd.uid create mode 100644 client/gui/menus/settings/settings.tscn create mode 100644 client/gui/menus/settings/settings_category.gd create mode 100644 client/gui/menus/settings/settings_category.gd.uid create mode 100644 client/gui/menus/settings/settings_root.gd create mode 100644 client/gui/menus/settings/settings_root.gd.uid create mode 100644 client/gui/menus/settings/settings_row.gd create mode 100644 client/gui/menus/settings/settings_row.gd.uid create mode 100644 client/gui/menus/settings/settings_row.tscn create mode 100644 client/gui/menus/settings/text_setting.gd create mode 100644 client/gui/menus/settings/text_setting.gd.uid create mode 100644 client/gui/menus/settings/toggle_setting.gd create mode 100644 client/gui/menus/settings/toggle_setting.gd.uid create mode 100644 client/gui/menus/setup/hairstyle_preview.gd create mode 100644 client/gui/menus/setup/hairstyle_preview.gd.uid create mode 100644 client/gui/menus/setup/hairstyle_preview.tscn create mode 100644 client/gui/menus/setup/setup.gd create mode 100644 client/gui/menus/setup/setup.gd.uid create mode 100644 client/gui/menus/setup/setup.tscn create mode 100644 client/gui/menus/transition/scene_transition.gd create mode 100644 client/gui/menus/transition/scene_transition.gd.uid create mode 100644 client/gui/menus/transition/scene_transition.tscn create mode 100644 client/gui/menus/transition/text_loading_anim.gdshader create mode 100644 client/gui/menus/transition/text_loading_anim.gdshader.uid create mode 100644 client/gui/overlays/ingame/announce_title.gd create mode 100644 client/gui/overlays/ingame/announce_title.gd.uid create mode 100644 client/gui/overlays/ingame/chat.gd create mode 100644 client/gui/overlays/ingame/chat.gd.uid create mode 100644 client/gui/overlays/ingame/chat.tscn create mode 100644 client/gui/overlays/ingame/score.gd create mode 100644 client/gui/overlays/ingame/score.gd.uid create mode 100644 client/gui/overlays/ingame/score.tscn create mode 100644 client/gui/overlays/lobby/lobby.gd create mode 100644 client/gui/overlays/lobby/lobby.gd.uid create mode 100644 client/gui/overlays/lobby/lobby.tscn create mode 100644 client/gui/overlays/lobby/player.gd create mode 100644 client/gui/overlays/lobby/player.gd.uid create mode 100644 client/gui/overlays/lobby/player.tscn create mode 100644 client/gui/resources/fonts/font-azaret-mono.woff2 create mode 100644 client/gui/resources/fonts/font-azaret-mono.woff2.import create mode 100644 client/gui/resources/fonts/font-josefin-sans.woff2 create mode 100644 client/gui/resources/fonts/font-josefin-sans.woff2.import create mode 100644 client/gui/resources/fonts/font-sansita-swashed.woff2 create mode 100644 client/gui/resources/fonts/font-sansita-swashed.woff2.import create mode 100644 client/gui/resources/icons/arrow.svg create mode 100644 client/gui/resources/icons/arrow.svg.import create mode 100644 client/gui/resources/icons/arrow_focus.svg create mode 100644 client/gui/resources/icons/arrow_focus.svg.import create mode 100644 client/gui/resources/icons/arrow_hover.svg create mode 100644 client/gui/resources/icons/arrow_hover.svg.import create mode 100644 client/gui/resources/icons/arrow_pressed.svg create mode 100644 client/gui/resources/icons/arrow_pressed.svg.import create mode 100644 client/gui/resources/icons/boost.webp create mode 100644 client/gui/resources/icons/boost.webp.import create mode 100644 client/gui/resources/icons/circle.svg create mode 100644 client/gui/resources/icons/circle.svg.import create mode 100644 client/gui/resources/icons/controller_x.svg create mode 100644 client/gui/resources/icons/controller_x.svg.import create mode 100644 client/gui/resources/icons/controller_y.svg create mode 100644 client/gui/resources/icons/controller_y.svg.import create mode 100644 client/gui/resources/icons/hint.svg create mode 100644 client/gui/resources/icons/hint.svg.import create mode 100644 client/gui/resources/icons/interact.webp create mode 100644 client/gui/resources/icons/interact.webp.import create mode 100644 client/gui/resources/icons/pause.webp create mode 100644 client/gui/resources/icons/pause.webp.import create mode 100644 client/gui/resources/icons/plus.svg create mode 100644 client/gui/resources/icons/plus.svg.import create mode 100644 client/gui/resources/icons/reset.svg create mode 100644 client/gui/resources/icons/reset.svg.import create mode 100644 client/gui/resources/icons/select_directory.svg create mode 100644 client/gui/resources/icons/select_directory.svg.import create mode 100644 client/gui/resources/icons/select_file.svg create mode 100644 client/gui/resources/icons/select_file.svg.import create mode 100644 client/gui/resources/icons/user.webp create mode 100644 client/gui/resources/icons/user.webp.import create mode 100644 client/gui/resources/materials/blur_material.tres create mode 100644 client/gui/resources/materials/dark_blur_material.tres create mode 100644 client/gui/resources/materials/grayscale_material.tres create mode 100644 client/gui/resources/materials/printed_material.tres create mode 100644 client/gui/resources/shaders/blur_mix.gdshader create mode 100644 client/gui/resources/shaders/blur_mix.gdshader.uid create mode 100644 client/gui/resources/shaders/grayscale.gdshader create mode 100644 client/gui/resources/shaders/grayscale.gdshader.uid create mode 100644 client/gui/resources/shaders/paper.tres create mode 100644 client/gui/resources/shaders/printed.gdshader create mode 100644 client/gui/resources/shaders/printed.gdshader.uid create mode 100644 client/gui/resources/sounds/click.ogg create mode 100644 client/gui/resources/sounds/click.ogg.import create mode 100644 client/gui/resources/sounds/failure.ogg create mode 100644 client/gui/resources/sounds/failure.ogg.import create mode 100644 client/gui/resources/sounds/game_start.ogg create mode 100644 client/gui/resources/sounds/game_start.ogg.import create mode 100644 client/gui/resources/sounds/hover.ogg create mode 100644 client/gui/resources/sounds/hover.ogg.import create mode 100644 client/gui/resources/sounds/page.ogg create mode 100644 client/gui/resources/sounds/page.ogg.import create mode 100644 client/gui/resources/sounds/sign.ogg create mode 100644 client/gui/resources/sounds/sign.ogg.import create mode 100644 client/gui/resources/sounds/success.ogg create mode 100644 client/gui/resources/sounds/success.ogg.import create mode 100644 client/gui/resources/style/error_focus_style.tres create mode 100644 client/gui/resources/style/focus_style.tres create mode 100644 client/gui/resources/style/hover_style.tres create mode 100644 client/gui/resources/style/item_bubble_progress_style.tres create mode 100644 client/gui/resources/style/item_bubble_progress_style_background.tres create mode 100644 client/gui/resources/style/lobby_panel_override.tres create mode 100644 client/gui/resources/style/normal_style.tres create mode 100644 client/gui/resources/style/panel_style.tres create mode 100644 client/gui/resources/style/panel_style_sidebar.tres create mode 100644 client/gui/resources/style/paper_panel_style.tres create mode 100644 client/gui/resources/theme/paper.tres create mode 100644 client/gui/resources/theme/theme.tres (limited to 'client/gui') diff --git a/client/gui/components/blur_setup.gd b/client/gui/components/blur_setup.gd new file mode 100644 index 00000000..567ac891 --- /dev/null +++ b/client/gui/components/blur_setup.gd @@ -0,0 +1,24 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends Control +class_name BlurSetup + +func _ready(): + update(Global.get_setting("graphics.ui_blur")) + Settings.hook_changed("graphics.ui_blur", false, update) + +func update(state): + material.set_shader_parameter("enable_blur", state) diff --git a/client/gui/components/blur_setup.gd.uid b/client/gui/components/blur_setup.gd.uid new file mode 100644 index 00000000..68ba7335 --- /dev/null +++ b/client/gui/components/blur_setup.gd.uid @@ -0,0 +1 @@ +uid://cmncjc06kadpe diff --git a/client/gui/components/controller_button.gd b/client/gui/components/controller_button.gd new file mode 100644 index 00000000..71f1332f --- /dev/null +++ b/client/gui/components/controller_button.gd @@ -0,0 +1,41 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +extends Button +class_name ControllerButton + +@export var controller_texture: Texture2D +@export var press_action: String + +func _ready(): + set_texture_enabled(Global.using_joypad) + Global.using_joypad_change.connect(set_texture_enabled) + +func _input(_event): + if press_action == null: + return + if not is_visible_in_tree(): + return + if disabled: + return + if Input.is_action_just_pressed(press_action): + pressed.emit() + +func set_texture_enabled(b: bool): + if b: + icon = controller_texture + else: + icon = null diff --git a/client/gui/components/controller_button.gd.uid b/client/gui/components/controller_button.gd.uid new file mode 100644 index 00000000..c8f5a86c --- /dev/null +++ b/client/gui/components/controller_button.gd.uid @@ -0,0 +1 @@ +uid://b1eomxildrq30 diff --git a/client/gui/components/message/chat_message.gd b/client/gui/components/message/chat_message.gd new file mode 100644 index 00000000..ce3dd0ca --- /dev/null +++ b/client/gui/components/message/chat_message.gd @@ -0,0 +1,32 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends VBoxContainer +class_name ChatMessage + +@onready var fade_away_timer: Timer = $FadeAway +@onready var sender_label: Label = $Sender +@onready var message_label: Label = $MarginContainer/Message + +func set_message(username: String, message: String, username_color: Color, fade_away: bool = false, fade_time: float = 5.): + sender_label.text = "<%s>" % username + message_label.text = message + sender_label.add_theme_color_override("font_color", username_color.lightened(.5)) + + if fade_away: + fade_away_timer.start(fade_time) + +func _on_fade_away_timeout() -> void: + queue_free() diff --git a/client/gui/components/message/chat_message.gd.uid b/client/gui/components/message/chat_message.gd.uid new file mode 100644 index 00000000..f1c4ff05 --- /dev/null +++ b/client/gui/components/message/chat_message.gd.uid @@ -0,0 +1 @@ +uid://6rprqelfdp3 diff --git a/client/gui/components/message/chat_message.tscn b/client/gui/components/message/chat_message.tscn new file mode 100644 index 00000000..1478c738 --- /dev/null +++ b/client/gui/components/message/chat_message.tscn @@ -0,0 +1,37 @@ +[gd_scene load_steps=4 format=3 uid="uid://bpc2qgsvcafhe"] + +[ext_resource type="Script" uid="uid://6rprqelfdp3" path="res://gui/components/message/chat_message.gd" id="1_ey0qp"] +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_rx6vg"] + +[sub_resource type="FontVariation" id="FontVariation_jfhbh"] +variation_embolden = 1.3 + +[node name="ChatMessage" type="VBoxContainer"] +offset_right = 72.0 +offset_bottom = 192.0 +theme = ExtResource("1_rx6vg") +script = ExtResource("1_ey0qp") + +[node name="Sender" type="Label" parent="."] +layout_mode = 2 +theme_override_fonts/font = SubResource("FontVariation_jfhbh") +text = "" + +[node name="FadeAway" type="Timer" parent="."] +one_shot = true + +[node name="MarginContainer" type="MarginContainer" parent="."] +layout_mode = 2 +theme_override_constants/margin_left = 10 +theme_override_constants/margin_top = 0 +theme_override_constants/margin_right = 0 +theme_override_constants/margin_bottom = 5 + +[node name="Message" type="Label" parent="MarginContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Message" +vertical_alignment = 1 +autowrap_mode = 3 + +[connection signal="timeout" from="FadeAway" to="." method="_on_fade_away_timeout"] diff --git a/client/gui/components/message/item/item_message.gd b/client/gui/components/message/item/item_message.gd new file mode 100644 index 00000000..e643c291 --- /dev/null +++ b/client/gui/components/message/item/item_message.gd @@ -0,0 +1,71 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +class_name ItemMessage +extends Control + +const PRINTED_MAT := preload("res://gui/resources/materials/printed_material.tres") + +@export var enable_rotation := true +@export var enable_grayscale := false + +var timeout_remaining := 0. +var timeout_initial := 0. + +@onready var item_render: ItemRender = $VBoxContainer/SubViewportContainer/SubViewport/ItemRender +@onready var progress: ProgressBar = $VBoxContainer/ProgressBar +@onready var sub_viewport: SubViewport = $VBoxContainer/SubViewportContainer/SubViewport +@onready var sub_viewport_container: SubViewportContainer = $VBoxContainer/SubViewportContainer +@onready var v_box_container: VBoxContainer = $VBoxContainer + +func _ready() -> void: + Global.configure_viewport_aa(sub_viewport, Global.get_setting("graphics.aa")) + + if enable_grayscale: + sub_viewport_container.material = PRINTED_MAT + +func set_subviewport_size(sub_viewport_size: Vector2): + sub_viewport.size = sub_viewport_size + progress.custom_minimum_size.y = sub_viewport_size.x - sub_viewport_size.y + v_box_container.size.y = 0 + +func set_round_corner_radius_progress(radius: int): + var style_bg: StyleBoxFlat = progress.get_theme_stylebox("background") + var style_fill: StyleBoxFlat = progress.get_theme_stylebox("fill") + + style_bg.corner_radius_bottom_left = radius + style_bg.corner_radius_bottom_right = radius + style_fill.corner_radius_bottom_left = radius + style_fill.corner_radius_bottom_right = radius + +func set_item(item_name: String, timeout_initial_: float, timeout_remaining_: float): + item_render.set_item(item_name, enable_rotation) + + timeout_remaining = timeout_remaining_ + timeout_initial = timeout_initial_ + progress.max_value = timeout_initial + progress.value = timeout_remaining + +func remove_item(): + item_render.remove_item() + +func _process(delta): + if item_render.item != null and !Global.game_paused: + timeout_remaining -= delta + progress.value = timeout_remaining + var x: float = timeout_remaining / timeout_initial + var progress_style: StyleBoxFlat = progress.get_theme_stylebox("fill") + progress_style.bg_color = Color(min((1-x) * 2, 1), min(x * 2, 1), 0.) + progress.add_theme_stylebox_override("fill", progress_style) diff --git a/client/gui/components/message/item/item_message.gd.uid b/client/gui/components/message/item/item_message.gd.uid new file mode 100644 index 00000000..d2600c43 --- /dev/null +++ b/client/gui/components/message/item/item_message.gd.uid @@ -0,0 +1 @@ +uid://boheclidwdafn diff --git a/client/gui/components/message/item/item_message.tscn b/client/gui/components/message/item/item_message.tscn new file mode 100644 index 00000000..59e0ebf9 --- /dev/null +++ b/client/gui/components/message/item/item_message.tscn @@ -0,0 +1,48 @@ +[gd_scene load_steps=6 format=3 uid="uid://fkqh36s4vl3p"] + +[ext_resource type="Script" uid="uid://boheclidwdafn" path="res://gui/components/message/item/item_message.gd" id="1_76lg0"] +[ext_resource type="PackedScene" uid="uid://cem5xcld6vn51" path="res://gui/components/message/item/item_render.tscn" id="1_sju7l"] +[ext_resource type="StyleBox" uid="uid://brw8uogdgx2gf" path="res://gui/resources/style/item_bubble_progress_style.tres" id="3_ipe76"] +[ext_resource type="StyleBox" uid="uid://cu0his4018e7h" path="res://gui/resources/style/item_bubble_progress_style_background.tres" id="3_t61n3"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_dpele"] +bg_color = Color(1, 1, 1, 1) +corner_radius_top_left = 30 +corner_radius_top_right = 30 +corner_radius_bottom_right = 30 +corner_radius_bottom_left = 30 + +[node name="ItemMessage" type="PanelContainer"] +auto_translate_mode = 2 +clip_children = 2 +offset_right = 256.0 +offset_bottom = 256.0 +size_flags_vertical = 0 +theme_override_styles/panel = SubResource("StyleBoxFlat_dpele") +script = ExtResource("1_76lg0") + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +layout_mode = 2 +size_flags_vertical = 0 +theme_override_constants/separation = 0 + +[node name="SubViewportContainer" type="SubViewportContainer" parent="VBoxContainer"] +layout_mode = 2 + +[node name="SubViewport" type="SubViewport" parent="VBoxContainer/SubViewportContainer"] +own_world_3d = true +transparent_bg = true +handle_input_locally = false +size = Vector2i(256, 224) +render_target_update_mode = 4 + +[node name="ItemRender" parent="VBoxContainer/SubViewportContainer/SubViewport" instance=ExtResource("1_sju7l")] + +[node name="ProgressBar" type="ProgressBar" parent="VBoxContainer"] +custom_minimum_size = Vector2(0, 32) +layout_mode = 2 +theme_override_styles/background = ExtResource("3_t61n3") +theme_override_styles/fill = ExtResource("3_ipe76") +step = 0.0 +value = 100.0 +show_percentage = false diff --git a/client/gui/components/message/item/item_render.gd b/client/gui/components/message/item/item_render.gd new file mode 100644 index 00000000..71a5eb7c --- /dev/null +++ b/client/gui/components/message/item/item_render.gd @@ -0,0 +1,41 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends Node3D +class_name ItemRender + +var item: Item +var do_rotate: bool + +var base := Node3D.new() + +func _ready() -> void: + add_child(base) + +func set_item(item_name: String, enable_rotation := true): + if item != null: + remove_item() + + item = ItemFactory.produce(item_name, base) + do_rotate = enable_rotation + base.add_child(item) + +func remove_item(): + if item != null: + item.queue_free() + +func _process(delta: float): + if do_rotate: + base.rotation.y += delta * TAU * .025 diff --git a/client/gui/components/message/item/item_render.gd.uid b/client/gui/components/message/item/item_render.gd.uid new file mode 100644 index 00000000..745b21ce --- /dev/null +++ b/client/gui/components/message/item/item_render.gd.uid @@ -0,0 +1 @@ +uid://bt7773og3p557 diff --git a/client/gui/components/message/item/item_render.tscn b/client/gui/components/message/item/item_render.tscn new file mode 100644 index 00000000..3d993b7a --- /dev/null +++ b/client/gui/components/message/item/item_render.tscn @@ -0,0 +1,23 @@ +[gd_scene load_steps=3 format=3 uid="uid://cem5xcld6vn51"] + +[ext_resource type="Script" uid="uid://bt7773og3p557" path="res://gui/components/message/item/item_render.gd" id="1_jfi7o"] + +[sub_resource type="Environment" id="Environment_iyxrx"] +ambient_light_source = 2 +ambient_light_color = Color(1, 1, 1, 1) +ambient_light_energy = 0.5 + +[node name="ItemRender" type="Node3D"] +script = ExtResource("1_jfi7o") + +[node name="Camera3D" type="Camera3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 0.939693, 0.34202, 0, -0.34202, 0.939693, 0, 0.5, 1) +projection = 1 +size = 0.6 + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 0.173648, 0.984808, 0, -0.984808, 0.173648, 0, 0, 0) +light_energy = 0.5 + +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource("Environment_iyxrx") diff --git a/client/gui/components/message/popup_message/pinned_item_messages.gd b/client/gui/components/message/popup_message/pinned_item_messages.gd new file mode 100644 index 00000000..fe82f904 --- /dev/null +++ b/client/gui/components/message/popup_message/pinned_item_messages.gd @@ -0,0 +1,55 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends Control +class_name PinnedItemMessages + +const ITEM_MESSAGE_SCENE := preload("res://gui/components/message/item/item_message.tscn") +const PAPER_PANEL_STYLE := preload("res://gui/resources/style/paper_panel_style.tres") + +var pinned_items := {} + +@onready var pinned_items_container: HBoxContainer = $HBoxContainer + +func pin_item(item_name: String, timeout_initial_: float, timeout_remaining_: float, player_id: float): + var item_message: ItemMessage = ITEM_MESSAGE_SCENE.instantiate() + item_message.remove_theme_stylebox_override("panel") + item_message.enable_rotation = false + item_message.enable_grayscale = true + item_message.add_theme_stylebox_override("panel", PAPER_PANEL_STYLE) + pinned_items_container.add_child(item_message) + item_message.set_subviewport_size(Vector2(96, 84)) + item_message.set_round_corner_radius_progress(0) + item_message.set_item(item_name, timeout_initial_, timeout_remaining_) + pinned_items[player_id] = item_message + sort_pins() + +func clear_item(player_id: float): + if player_id in pinned_items: + if is_instance_valid(pinned_items[player_id]): + pinned_items[player_id].queue_free() + +func sort_pins(): + var sorted_nodes := pinned_items_container.get_children() + + sorted_nodes.sort_custom( + func(a: Node, b: Node): return a.timeout_remaining < b.timeout_remaining + ) + + for node in pinned_items_container.get_children(): + pinned_items_container.remove_child(node) + + for node in sorted_nodes: + pinned_items_container.add_child(node) diff --git a/client/gui/components/message/popup_message/pinned_item_messages.gd.uid b/client/gui/components/message/popup_message/pinned_item_messages.gd.uid new file mode 100644 index 00000000..2325c656 --- /dev/null +++ b/client/gui/components/message/popup_message/pinned_item_messages.gd.uid @@ -0,0 +1 @@ +uid://c0k6f1wkynbkd diff --git a/client/gui/components/message/popup_message/pinned_item_messages.tscn b/client/gui/components/message/popup_message/pinned_item_messages.tscn new file mode 100644 index 00000000..30f27809 --- /dev/null +++ b/client/gui/components/message/popup_message/pinned_item_messages.tscn @@ -0,0 +1,22 @@ +[gd_scene load_steps=2 format=3 uid="uid://dcrr1rwdwbkq8"] + +[ext_resource type="Script" uid="uid://c0k6f1wkynbkd" path="res://gui/components/message/popup_message/pinned_item_messages.gd" id="1_q0jkk"] + +[node name="PinnedItemMessages" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +script = ExtResource("1_q0jkk") + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_direction = 2 +layout_mode = 1 +anchors_preset = 10 +anchor_right = 1.0 +offset_bottom = 256.0 +grow_horizontal = 2 +mouse_filter = 2 diff --git a/client/gui/components/message/popup_message/popup_message.gd b/client/gui/components/message/popup_message/popup_message.gd new file mode 100644 index 00000000..ae474914 --- /dev/null +++ b/client/gui/components/message/popup_message/popup_message.gd @@ -0,0 +1,230 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends Control +class_name PopupMessage + +const SERVER_MESSAGE_SCENE = preload("res://gui/components/message/popup_message/server_message.tscn") + +var is_ingame := false +var is_joined := false + +var positional_messages = {} + +@onready var positional_messages_node: Control = $Positional +@onready var server_msg = $Static/VBox/ServerMessage +@onready var hint_msg = $Static/VBox/HintMessage + +@onready var server_msg_label: Label = $Static/VBox/ServerMessage/CenterContainer/Label +@onready var hint_msg_label: Label = $Static/VBox/HintMessage/CenterContainer/Label + +@onready var auto_hint_timers: Node = $Timers/AutoHints +@onready var server_msg_timer: Timer = $Timers/Server +@onready var hint_msg_timer: Timer = $Timers/Hint +@onready var reset_timer = $Timers/Reset +@onready var join_while_running_timer = $Timers/JoinWhileRunning + +@onready var game: Game = $"../Game" + +func _ready(): + game.join_state_updated.connect(func(state: Game.JoinState): + is_joined = state == Game.JoinState.JOINED + ) + game.update_tutorial_running.connect( + func a(running: bool): + if running: + stop_game_hints() + else: + update_state() + ) + game.in_lobby_updated.connect( + func a(in_lobby): + is_ingame = not in_lobby + update_state() + ) + +func _process(_delta: float): + for pos: Vector2 in positional_messages.keys(): + var msg: PositionalMessage = positional_messages[pos] + var pos_3d = Vector3(pos.x + 0.5, 1.5, pos.y + 0.5) + var pos_2d = get_viewport().get_camera_3d().unproject_position(pos_3d) + + msg.node_2d.position = pos_2d.clamp( + Vector2.ZERO + 0.5 * msg.node.size, + Vector2(get_viewport_rect().size) - 0.5 * msg.node.size + ) + + if msg.node.size != msg.last_size: + msg.last_size = msg.node.size + msg.node.position = -0.5 * msg.last_size + +func update_state(): + if is_ingame and is_joined: + start_game_hints() + elif is_ingame: + stop_game_hints() + join_while_running_timer.start() + else: + stop_game_hints() + +func display_server_msg(msg: String, auto_remove := true): + server_msg.show() + server_msg_label.text = msg + + if auto_remove: + server_msg_timer.start() + +func _on_server_timeout() -> void: + clear_server_msg() + +func display_server_msg_positional(text: String, pos: Vector2, use_monospace: bool): + var msg := PositionalMessage.new() + msg.node = SERVER_MESSAGE_SCENE.instantiate() + msg.node_2d = Node2D.new() + positional_messages_node.add_child(msg.node_2d) + msg.node_2d.add_child(msg.node) + msg.node.set_text(text, use_monospace) + msg.node.size = Vector2.ZERO + msg.position = pos + positional_messages[pos] = msg + +func clear_server_msg(position_ = null): + if position_ == null: + server_msg_timer.stop() + server_msg.hide() + else: + if position_ in positional_messages: + var msg: PositionalMessage = positional_messages[position_] + msg.node_2d.queue_free() + positional_messages.erase(position_) + +func display_hint_msg(msg: String): + hint_msg.show() + hint_msg_label.text = msg + hint_msg_timer.start() + +func _on_hint_timer_timeout(): + hint_msg.hide() + +func start_game_hints(): + for c: Timer in auto_hint_timers.get_children(): + c.start() + +func stop_game_hints(): + _on_hint_timer_timeout() + for c: Timer in auto_hint_timers.get_children(): + c.stop() + reset_timer.stop() + join_while_running_timer.stop() + +func _input(_event): + if Input.is_action_just_pressed("boost"): + Global.set_hint("has_boosted", true) + if any_action_just_pressed(["forwards", "backwards", "left", "right"]): + Global.set_hint("has_moved", true) + if any_action_just_pressed(["rotate_left", "rotate_right", "rotate_up", "rotate_down"]): + if not Global.get_hint("has_reset"): + reset_timer.start() + Global.set_hint("has_rotated", true) + if any_action_just_pressed(["zoom_in", "zoom_out"]): + Global.set_hint("has_zoomed", true) + if Input.is_action_just_pressed("interact_left") or Input.is_action_just_pressed("interact_right"): + Global.set_hint("has_interacted", true) + if Input.is_action_just_pressed("reset"): + Global.set_hint("has_reset", true) + +func _on_boost_timeout(): + if not Global.get_hint("has_boosted") and not Global.using_touch: + display_hint_msg(tr("c.hint.boost").format([display_keybind("boost")])) + +func _on_move_timeout(): + if not Global.get_hint("has_moved") and not Global.using_touch: + display_hint_msg(tr("c.hint.movement").format([", ".join( + [ + display_keybind("forwards"), + display_keybind("left"), + display_keybind("backwards"), + display_keybind("right") + ] + )])) + +func _on_interact_timeout(): + if not Global.get_hint("has_interacted") and not Global.using_touch: + display_hint_msg(tr("c.hint.interact").format([display_keybind("interact")])) + +func _on_reset_timeout(): + if not Global.get_hint("has_reset") and not Global.using_touch: + display_hint_msg(tr("c.hint.reset_camera").format([display_keybind("reset")])) + +func _on_zoom_timeout(): + if not Global.get_hint("has_zoomed") and not Global.using_touch: + display_hint_msg(tr("c.hint.zoom_camera").format([", ".join( + [ + display_keybind("zoom_in"), + display_keybind("zoom_out") + ] + )])) + +func display_keybind(action_name: String) -> String: + var events := InputManager.get_events(action_name) + + if events.size() == 0: + # There are no events which match the action + return tr("c.settings.input.unknown_event") + + for event: InputEvent in events: + # Try to find event which matches input method + var type := InputManager.get_event_type(event) + if Global.using_joypad and type != InputManager.EventType.JOYPAD: + continue + if Global.using_touch and type != InputManager.EventType.TOUCH: + continue + return InputManager.display_input_event(event) + + # No matching event found. Just show any event. + return InputManager.display_input_event(events[0]) + +func any_action_just_pressed(actions: Array) -> bool: + for a: String in actions: + if Input.is_action_just_pressed(a): + return true + return false + +func _on_rotate_camera_timeout(): + if not Global.get_hint("has_rotated") and not Global.using_touch: + display_hint_msg(tr("c.hint.rotate").format([", ".join( + [ + display_keybind("rotate_up"), + display_keybind("rotate_left"), + display_keybind("rotate_down"), + display_keybind("rotate_right") + ] + )])) + +func _on_join_while_running_timeout(): + if not game.join_state == Game.JoinState.JOINED and not Global.get_hint("has_seen_join_while_running"): + Global.set_hint("has_seen_join_while_running", true) + display_hint_msg(tr("c.hint.join_while_running").format([display_keybind("menu")])) + +func _on_performance_timeout() -> void: + if not Global.get_hint("has_seen_performance") and Engine.get_frames_per_second() < DisplayServer.screen_get_refresh_rate() * 0.75: + Global.set_hint("has_seen_performance", true) + display_hint_msg(tr("c.hint.framerate_low")) + +class PositionalMessage: + var node: ServerMessage + var node_2d: Node2D + var position: Vector2 + var last_size: Vector2 diff --git a/client/gui/components/message/popup_message/popup_message.gd.uid b/client/gui/components/message/popup_message/popup_message.gd.uid new file mode 100644 index 00000000..d9aa95c5 --- /dev/null +++ b/client/gui/components/message/popup_message/popup_message.gd.uid @@ -0,0 +1 @@ +uid://c2cx41lrgf5b0 diff --git a/client/gui/components/message/popup_message/popup_message.tscn b/client/gui/components/message/popup_message/popup_message.tscn new file mode 100644 index 00000000..0f1bfcec --- /dev/null +++ b/client/gui/components/message/popup_message/popup_message.tscn @@ -0,0 +1,164 @@ +[gd_scene load_steps=12 format=3 uid="uid://b21nrnkygiyjt"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_a1566"] +[ext_resource type="Script" uid="uid://c2cx41lrgf5b0" path="res://gui/components/message/popup_message/popup_message.gd" id="2_sbew6"] +[ext_resource type="Shader" uid="uid://cwldxegcj55if" path="res://gui/resources/shaders/blur_mix.gdshader" id="3_2vnom"] +[ext_resource type="PackedScene" uid="uid://dq61p3a8og2b6" path="res://gui/components/message/popup_message/server_message.tscn" id="3_m3rok"] +[ext_resource type="Script" uid="uid://cmncjc06kadpe" path="res://gui/components/blur_setup.gd" id="4_pvwmw"] +[ext_resource type="FontFile" uid="uid://bk704sc5gkrb3" path="res://gui/resources/fonts/font-azaret-mono.woff2" id="4_wsrnf"] +[ext_resource type="Texture2D" uid="uid://b2uv5rf0enikf" path="res://gui/resources/icons/hint.svg" id="5_2dxsd"] + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_k0m35"] +shader = ExtResource("3_2vnom") +shader_parameter/blur_amount = 3.5 +shader_parameter/mix_amount = 0.85 +shader_parameter/mix_amount_no_blur = 1.0 +shader_parameter/color_over = Color(0, 0, 0, 1) +shader_parameter/enable_blur = false + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_vq4dg"] +bg_color = Color(1, 1, 1, 0.878431) +corner_radius_top_left = 16 +corner_radius_top_right = 16 +corner_radius_bottom_right = 16 +corner_radius_bottom_left = 16 + +[sub_resource type="FontVariation" id="FontVariation_qfltj"] +base_font = ExtResource("4_wsrnf") +variation_embolden = 0.75 + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_3rgop"] +content_margin_left = 32.0 +content_margin_top = 8.0 +content_margin_right = 32.0 +content_margin_bottom = 8.0 + +[node name="PopupMessage" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +script = ExtResource("2_sbew6") + +[node name="Static" type="MarginContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +theme = ExtResource("1_a1566") + +[node name="VBox" type="VBoxContainer" parent="Static"] +layout_mode = 2 +mouse_filter = 2 + +[node name="ServerMessage" parent="Static/VBox" instance=ExtResource("3_m3rok")] +visible = false +layout_mode = 2 + +[node name="HintMessage" type="PanelContainer" parent="Static/VBox"] +visible = false +material = SubResource("ShaderMaterial_k0m35") +layout_mode = 2 +size_flags_vertical = 0 +mouse_filter = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_vq4dg") +script = ExtResource("4_pvwmw") + +[node name="CenterContainer" type="HBoxContainer" parent="Static/VBox/HintMessage"] +layout_mode = 2 +mouse_filter = 2 +alignment = 1 + +[node name="MarginContainer" type="MarginContainer" parent="Static/VBox/HintMessage/CenterContainer"] +layout_mode = 2 +mouse_filter = 2 +theme_override_constants/margin_left = 4 +theme_override_constants/margin_top = 4 +theme_override_constants/margin_right = 4 +theme_override_constants/margin_bottom = 4 + +[node name="TextureRect" type="TextureRect" parent="Static/VBox/HintMessage/CenterContainer/MarginContainer"] +custom_minimum_size = Vector2(28, 28) +layout_mode = 2 +mouse_filter = 2 +texture = ExtResource("5_2dxsd") +expand_mode = 1 +stretch_mode = 4 + +[node name="Label" type="Label" parent="Static/VBox/HintMessage/CenterContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +theme_override_fonts/font = SubResource("FontVariation_qfltj") +theme_override_styles/normal = SubResource("StyleBoxEmpty_3rgop") +text = "A hint is worth more than a thousand manuals" +autowrap_mode = 3 + +[node name="Positional" type="Control" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 + +[node name="Timers" type="Node" parent="."] + +[node name="Server" type="Timer" parent="Timers"] +wait_time = 5.0 +one_shot = true + +[node name="Hint" type="Timer" parent="Timers"] +wait_time = 10.0 +one_shot = true + +[node name="AutoHints" type="Node" parent="Timers"] + +[node name="Move" type="Timer" parent="Timers/AutoHints"] +wait_time = 2.0 +one_shot = true + +[node name="Performance" type="Timer" parent="Timers/AutoHints"] +wait_time = 20.0 +one_shot = true + +[node name="Boost" type="Timer" parent="Timers/AutoHints"] +wait_time = 90.0 +one_shot = true + +[node name="Interact" type="Timer" parent="Timers/AutoHints"] +wait_time = 15.0 +one_shot = true + +[node name="RotateCamera" type="Timer" parent="Timers/AutoHints"] +wait_time = 120.0 +one_shot = true + +[node name="Zoom" type="Timer" parent="Timers/AutoHints"] +wait_time = 135.0 +one_shot = true + +[node name="Reset" type="Timer" parent="Timers"] +wait_time = 10.0 +one_shot = true + +[node name="JoinWhileRunning" type="Timer" parent="Timers"] +wait_time = 5.0 +one_shot = true + +[connection signal="timeout" from="Timers/Server" to="." method="_on_server_timeout"] +[connection signal="timeout" from="Timers/Hint" to="Static" method="_on_hint_timer_timeout"] +[connection signal="timeout" from="Timers/AutoHints/Move" to="Static" method="_on_move_timeout"] +[connection signal="timeout" from="Timers/AutoHints/Performance" to="Static" method="_on_performance_timeout"] +[connection signal="timeout" from="Timers/AutoHints/Boost" to="Static" method="_on_boost_timeout"] +[connection signal="timeout" from="Timers/AutoHints/Interact" to="Static" method="_on_interact_timeout"] +[connection signal="timeout" from="Timers/AutoHints/RotateCamera" to="Static" method="_on_rotate_camera_timeout"] +[connection signal="timeout" from="Timers/AutoHints/Zoom" to="Static" method="_on_zoom_timeout"] +[connection signal="timeout" from="Timers/Reset" to="Static" method="_on_reset_timeout"] +[connection signal="timeout" from="Timers/JoinWhileRunning" to="Static" method="_on_join_while_running_timeout"] diff --git a/client/gui/components/message/popup_message/server_message.gd b/client/gui/components/message/popup_message/server_message.gd new file mode 100644 index 00000000..a0688dc5 --- /dev/null +++ b/client/gui/components/message/popup_message/server_message.gd @@ -0,0 +1,13 @@ +extends BlurSetup +class_name ServerMessage + +const DEFAULT_FONT = preload("res://gui/resources/fonts/font-josefin-sans.woff2") +const MONOSPACE_FONT = preload("res://gui/resources/fonts/font-azaret-mono.woff2") + +@onready var label: Label = $CenterContainer/Label + +func set_text(text: String, use_monospace := true): + label.text = text + var font: FontVariation = label.get_theme_font("font") + font.base_font = MONOSPACE_FONT if use_monospace else DEFAULT_FONT + label.add_theme_font_size_override("font_size", 16 if use_monospace else 20) diff --git a/client/gui/components/message/popup_message/server_message.gd.uid b/client/gui/components/message/popup_message/server_message.gd.uid new file mode 100644 index 00000000..775979e0 --- /dev/null +++ b/client/gui/components/message/popup_message/server_message.gd.uid @@ -0,0 +1 @@ +uid://dfgwh7x7sqc21 diff --git a/client/gui/components/message/popup_message/server_message.tscn b/client/gui/components/message/popup_message/server_message.tscn new file mode 100644 index 00000000..fd128666 --- /dev/null +++ b/client/gui/components/message/popup_message/server_message.tscn @@ -0,0 +1,51 @@ +[gd_scene load_steps=8 format=3 uid="uid://dq61p3a8og2b6"] + +[ext_resource type="Shader" uid="uid://cwldxegcj55if" path="res://gui/resources/shaders/blur_mix.gdshader" id="1_qv8ew"] +[ext_resource type="Script" uid="uid://dfgwh7x7sqc21" path="res://gui/components/message/popup_message/server_message.gd" id="2_csqo8"] +[ext_resource type="FontFile" uid="uid://bk704sc5gkrb3" path="res://gui/resources/fonts/font-azaret-mono.woff2" id="3_dw20j"] + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_q3bbd"] +shader = ExtResource("1_qv8ew") +shader_parameter/blur_amount = 3.5 +shader_parameter/mix_amount = 0.85 +shader_parameter/mix_amount_no_blur = 0.85 +shader_parameter/color_over = Color(1, 1, 1, 1) +shader_parameter/enable_blur = true + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_vq4dg"] +bg_color = Color(1, 1, 1, 0.878431) +corner_radius_top_left = 16 +corner_radius_top_right = 16 +corner_radius_bottom_right = 16 +corner_radius_bottom_left = 16 + +[sub_resource type="FontVariation" id="FontVariation_qfltj"] +resource_local_to_scene = true +base_font = ExtResource("3_dw20j") +variation_embolden = 0.75 + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_3rgop"] +content_margin_left = 32.0 +content_margin_top = 8.0 +content_margin_right = 32.0 +content_margin_bottom = 8.0 + +[node name="ServerMessage" type="PanelContainer"] +material = SubResource("ShaderMaterial_q3bbd") +size_flags_horizontal = 4 +size_flags_vertical = 0 +mouse_filter = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_vq4dg") +script = ExtResource("2_csqo8") + +[node name="CenterContainer" type="CenterContainer" parent="."] +layout_mode = 2 +mouse_filter = 2 + +[node name="Label" type="Label" parent="CenterContainer"] +layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_fonts/font = SubResource("FontVariation_qfltj") +theme_override_font_sizes/font_size = 16 +theme_override_styles/normal = SubResource("StyleBoxEmpty_3rgop") +text = "Server message" diff --git a/client/gui/components/smart_margin_container.gd b/client/gui/components/smart_margin_container.gd new file mode 100644 index 00000000..046dc6f3 --- /dev/null +++ b/client/gui/components/smart_margin_container.gd @@ -0,0 +1,41 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends MarginContainer +class_name SmartMarginContainer +# A smart margin container which automatically adjusts the margin such that it doesn't cover notch on phones + +func _ready() -> void: + var os := OS.get_name() + if os == "iOS" or os == "Android": + update_margins() + +func update_margins() -> void: + var screen_safe_rect := Rect2(DisplayServer.get_display_safe_area()) + var viewport_transform := get_viewport().get_final_transform() + var viewport_safe_rect := screen_safe_rect * viewport_transform.affine_inverse() + var viewport_full_rect := get_viewport().get_visible_rect() + var left := viewport_safe_rect.position.x - viewport_full_rect.position.x + var top := viewport_safe_rect.position.y - viewport_full_rect.position.y + var right := viewport_full_rect.end.x - viewport_safe_rect.end.x + var bottom := viewport_full_rect.end.y - viewport_safe_rect.end.y + # print("OLD: ", get_theme_constant("margin_left")) + begin_bulk_theme_override() + add_theme_constant_override('margin_left', roundi(left) + get_theme_constant("margin_left")) + add_theme_constant_override('margin_top', roundi(top) + get_theme_constant("margin_top")) + add_theme_constant_override('margin_right', roundi(right) + get_theme_constant("margin_right")) + add_theme_constant_override('margin_bottom', roundi(bottom) + get_theme_constant("margin_bottom")) + end_bulk_theme_override() + # print("NEW: ", get_theme_constant("margin_left")) diff --git a/client/gui/components/smart_margin_container.gd.uid b/client/gui/components/smart_margin_container.gd.uid new file mode 100644 index 00000000..c5246aed --- /dev/null +++ b/client/gui/components/smart_margin_container.gd.uid @@ -0,0 +1 @@ +uid://byshs20og68tn diff --git a/client/gui/components/touch_scroll_container.gd b/client/gui/components/touch_scroll_container.gd new file mode 100644 index 00000000..41aa34c0 --- /dev/null +++ b/client/gui/components/touch_scroll_container.gd @@ -0,0 +1,45 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends ScrollContainer +class_name ScrollContainerCustom + +# Adds support for scrolling with joypad and touch + +const SCROLL_SPEED := 1000. +var velocity := 0. + +@export var auto_scroll_to_bottom := false + +func _init(): + follow_focus = true + +func _ready(): + if auto_scroll_to_bottom: + call_deferred("scroll_to_bottom") + +func scroll_to_bottom(): + set_deferred("scroll_vertical", get_v_scroll_bar().max_value) + +func _process(delta): + velocity = G.interpolate(velocity, 0., delta * 5.) + velocity = 0. if abs(velocity) < .001 else velocity + if Input.get_axis("scroll_up", "scroll_down") != 0.: + velocity = Input.get_axis("scroll_up", "scroll_down") + set_deferred("scroll_vertical", scroll_vertical + velocity * delta * SCROLL_SPEED) + +func _input(event): + if event is InputEventScreenDrag: + velocity = -(scroll_vertical - (scroll_vertical - event.relative.y)) * .1 diff --git a/client/gui/components/touch_scroll_container.gd.uid b/client/gui/components/touch_scroll_container.gd.uid new file mode 100644 index 00000000..56b74a3d --- /dev/null +++ b/client/gui/components/touch_scroll_container.gd.uid @@ -0,0 +1 @@ +uid://bd7bylb2t2m0 diff --git a/client/gui/menus/character.gd b/client/gui/menus/character.gd new file mode 100644 index 00000000..3c1230ae --- /dev/null +++ b/client/gui/menus/character.gd @@ -0,0 +1,96 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends Menu + +@onready var character: Character = $Node3D/Character +@onready var back_button := $VBoxContainer/bottom_panel/back +@onready var map: Map = $Node3D/Map +@onready var username_edit = $VBoxContainer/top_panel/a/username + +func _ready(): + super() + $VBoxContainer/top_panel/a/username.text = Global.get_profile("username") + character.set_style(Global.get_profile("character_style"), "chef") + init_map() + +func init_map(): + var map_tile = func (t): match t: + ".": return "floor" + "=": return "counter" + "s": return "stove" + "c": return "chair" + "t": return "table" + "o": return "oven" + "#": return "wall" + _: push_error("unknown tile: ", t) + var tiles = [ + "...............", + "###############", + "=oo==ss===.ctc#", + "..............#", + ".............=#", + ".............=#", + ".............=#" + ].map(func (l): return Array(l.split("")).map(map_tile)) + var gt = func (e): return null if e[1] >= tiles.size() else null if e[0] >= tiles[e[1]].size() else tiles[e[1]][e[0]] + var co = Vector2i(floor(tiles[0].size() / 2), floor(tiles.size() - 2)) + for y in tiles.size(): + for x in tiles[y].size(): + map.set_tile(Vector2i(x,y) - co, gt.call([x,y]), [[x,y-1],[x-1,y],[x,y+1],[x+1,y]].map(gt)) + map.flush() + +func exit(): + if username_edit.text == "": + var popup_data := MenuPopup.Data.new() + popup_data.text = tr("c.error.empty_username") + var accept_button := Button.new() + accept_button.text = tr("c.menu.accept") + popup_data.buttons = [accept_button] + await submenu("res://gui/menus/popup.tscn", popup_data) + return + Global.set_profile("username", username_edit.text) + Global.save_profile() + super() + +func _on_character_back_pressed(): + modify_style(func m(current_style: Dictionary): + current_style.color = G.rem_euclid(current_style.color - 1, character.COLORS.size())) + +func _on_character_forward_pressed(): + modify_style(func m(current_style: Dictionary): + current_style.color = G.rem_euclid(current_style.color + 1, character.COLORS.size())) + +func _on_headwear_back_pressed() -> void: + modify_style(func m(current_style: Dictionary): + current_style.headwear = G.rem_euclid(current_style.headwear - 1, character.headwears.size())) + +func _on_headwear_forward_pressed() -> void: + modify_style(func m(current_style: Dictionary): + current_style.headwear = G.rem_euclid(current_style.headwear + 1, character.headwears.size())) + +func _on_hairstyle_back_pressed() -> void: + modify_style(func m(current_style: Dictionary): + current_style.hairstyle = G.rem_euclid(current_style.hairstyle - 1, character.hairstyles.size())) + +func _on_hairstyle_forward_pressed() -> void: + modify_style(func m(current_style: Dictionary): + current_style.hairstyle = G.rem_euclid(current_style.hairstyle + 1, character.hairstyles.size())) + +func modify_style(modifier: Callable): + var current_style: Dictionary = Global.get_profile("character_style") + modifier.call(current_style) + Global.set_profile("character_style", current_style) + character.set_style(Global.get_profile("character_style"), "chef") diff --git a/client/gui/menus/character.gd.uid b/client/gui/menus/character.gd.uid new file mode 100644 index 00000000..d0df5488 --- /dev/null +++ b/client/gui/menus/character.gd.uid @@ -0,0 +1 @@ +uid://bglusga8l5c27 diff --git a/client/gui/menus/character.tscn b/client/gui/menus/character.tscn new file mode 100644 index 00000000..7bdf03e6 --- /dev/null +++ b/client/gui/menus/character.tscn @@ -0,0 +1,230 @@ +[gd_scene load_steps=11 format=3 uid="uid://1f7xpirm5d28"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_ak2pw"] +[ext_resource type="Script" uid="uid://bglusga8l5c27" path="res://gui/menus/character.gd" id="1_brhd1"] +[ext_resource type="PackedScene" uid="uid://b4gone8fu53r7" path="res://map/map.tscn" id="3_6mc88"] +[ext_resource type="PackedScene" uid="uid://b3hhir2fvnunu" path="res://player/character/character.tscn" id="3_odq7n"] +[ext_resource type="PackedScene" uid="uid://bg2d78ycorcqk" path="res://gui/menus/transition/scene_transition.tscn" id="4_c0ocf"] +[ext_resource type="Texture2D" uid="uid://35rd5gamtyqm" path="res://gui/resources/icons/arrow.svg" id="5_kvd7k"] +[ext_resource type="Texture2D" uid="uid://j75dbytlbju" path="res://gui/resources/icons/arrow_pressed.svg" id="5_xpff8"] +[ext_resource type="Texture2D" uid="uid://b33qmctbpf48g" path="res://gui/resources/icons/arrow_hover.svg" id="6_soj8g"] +[ext_resource type="Texture2D" uid="uid://by3qsrpxnfq4w" path="res://gui/resources/icons/arrow_focus.svg" id="6_u31hl"] + +[sub_resource type="Environment" id="Environment_ex25y"] +background_mode = 1 +background_color = Color(0.145548, 0.151043, 0.207031, 1) + +[node name="CharacterMenu" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("1_ak2pw") +script = ExtResource("1_brhd1") + +[node name="Node3D" type="Node3D" parent="."] + +[node name="WorldEnvironment" type="WorldEnvironment" parent="Node3D"] +environment = SubResource("Environment_ex25y") + +[node name="Camera3D" type="Camera3D" parent="Node3D"] +transform = Transform3D(1, 0, 0, 0, 0.977046, 0.21303, 0, -0.21303, 0.977046, 0, 1.137, 2.703) +current = true +fov = 41.8 + +[node name="Map" parent="Node3D" instance=ExtResource("3_6mc88")] +transform = Transform3D(0.866025, 0, 0.5, 0, 1, 0, -0.5, 0, 0.866025, 0, 0, 0) + +[node name="Character" parent="Node3D" instance=ExtResource("3_odq7n")] + +[node name="SpotLight3D" type="SpotLight3D" parent="Node3D"] +transform = Transform3D(0.631535, -0.571246, 0.524254, 0.0428654, 0.700843, 0.712026, -0.774162, -0.427197, 0.467093, 1.79161, 3.07541, 1.58055) +light_energy = 2.689 +spot_range = 20.159 +spot_angle = 17.9256 + +[node name="SpotLight3D2" type="SpotLight3D" parent="Node3D"] +transform = Transform3D(0.32457, 0.109091, -0.93955, 0.0604837, 0.9889, 0.135716, 0.943926, -0.100877, 0.314369, -5.22608, 2.10824, 2.35824) +light_energy = 2.689 +spot_range = 20.159 +spot_angle = 17.9256 + +[node name="SpotLight3D3" type="SpotLight3D" parent="Node3D"] +transform = Transform3D(0.114088, -0.0173997, 0.993318, 0.0610452, 0.99808, 0.0104718, -0.991594, 0.0594426, 0.114931, 8.10732, 0.437069, 2.35824) +light_energy = 2.689 +spot_range = 20.159 +spot_angle = 17.9256 + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="top_panel" type="Panel" parent="VBoxContainer"] +custom_minimum_size = Vector2(0, 100) +layout_mode = 2 + +[node name="a" type="VBoxContainer" parent="VBoxContainer/top_panel"] +layout_mode = 1 +anchors_preset = 5 +anchor_left = 0.5 +anchor_right = 0.5 +offset_left = -213.0 +offset_top = 13.0 +offset_right = 216.0 +offset_bottom = 110.0 +grow_horizontal = 2 + +[node name="Label" type="Label" parent="VBoxContainer/top_panel/a"] +layout_mode = 2 +text = "c.settings.username" +horizontal_alignment = 1 + +[node name="username" type="LineEdit" parent="VBoxContainer/top_panel/a"] +layout_mode = 2 +max_length = 32 + +[node name="Spacer" type="MarginContainer" parent="VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +theme_override_constants/margin_left = 50 +theme_override_constants/margin_top = 50 +theme_override_constants/margin_right = 50 +theme_override_constants/margin_bottom = 50 + +[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/Spacer"] +layout_mode = 2 +alignment = 1 + +[node name="Headware" type="HBoxContainer" parent="VBoxContainer/Spacer/VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +alignment = 1 + +[node name="Back" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Headware"] +layout_mode = 2 +size_flags_horizontal = 3 +focus_neighbor_right = NodePath("../Forward") +texture_normal = ExtResource("5_kvd7k") +texture_pressed = ExtResource("5_xpff8") +texture_hover = ExtResource("6_soj8g") +texture_focused = ExtResource("6_u31hl") +ignore_texture_size = true +stretch_mode = 5 +flip_h = true + +[node name="Spacer" type="Control" parent="VBoxContainer/Spacer/VBoxContainer/Headware"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Forward" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Headware"] +layout_mode = 2 +size_flags_horizontal = 3 +focus_neighbor_left = NodePath("../Back") +texture_normal = ExtResource("5_kvd7k") +texture_pressed = ExtResource("5_xpff8") +texture_hover = ExtResource("6_soj8g") +texture_focused = ExtResource("6_u31hl") +ignore_texture_size = true +stretch_mode = 5 + +[node name="Hairstyle" type="HBoxContainer" parent="VBoxContainer/Spacer/VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +alignment = 1 + +[node name="Back" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Hairstyle"] +layout_mode = 2 +size_flags_horizontal = 3 +focus_neighbor_right = NodePath("../Forward") +texture_normal = ExtResource("5_kvd7k") +texture_pressed = ExtResource("5_xpff8") +texture_hover = ExtResource("6_soj8g") +texture_focused = ExtResource("6_u31hl") +ignore_texture_size = true +stretch_mode = 5 +flip_h = true + +[node name="Spacer" type="Control" parent="VBoxContainer/Spacer/VBoxContainer/Hairstyle"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Forward" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Hairstyle"] +layout_mode = 2 +size_flags_horizontal = 3 +focus_neighbor_left = NodePath("../Back") +texture_normal = ExtResource("5_kvd7k") +texture_pressed = ExtResource("5_xpff8") +texture_hover = ExtResource("6_soj8g") +texture_focused = ExtResource("6_u31hl") +ignore_texture_size = true +stretch_mode = 5 + +[node name="Character" type="HBoxContainer" parent="VBoxContainer/Spacer/VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +alignment = 1 + +[node name="Back" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Character"] +layout_mode = 2 +size_flags_horizontal = 3 +focus_neighbor_right = NodePath("../Forward") +texture_normal = ExtResource("5_kvd7k") +texture_pressed = ExtResource("5_xpff8") +texture_hover = ExtResource("6_soj8g") +texture_focused = ExtResource("6_u31hl") +ignore_texture_size = true +stretch_mode = 5 +flip_h = true + +[node name="Spacer" type="Control" parent="VBoxContainer/Spacer/VBoxContainer/Character"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Forward" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Character"] +layout_mode = 2 +size_flags_horizontal = 3 +focus_neighbor_left = NodePath("../Back") +texture_normal = ExtResource("5_kvd7k") +texture_pressed = ExtResource("5_xpff8") +texture_hover = ExtResource("6_soj8g") +texture_focused = ExtResource("6_u31hl") +ignore_texture_size = true +stretch_mode = 5 + +[node name="bottom_panel" type="Panel" parent="VBoxContainer"] +custom_minimum_size = Vector2(0, 75) +layout_mode = 2 + +[node name="back" type="Button" parent="VBoxContainer/bottom_panel"] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -39.5 +offset_top = -22.0 +offset_right = 39.5 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_vertical = 8 +text = "c.menu.back" + +[node name="SceneTransition" parent="." instance=ExtResource("4_c0ocf")] +visible = false +layout_mode = 1 + +[connection signal="pressed" from="VBoxContainer/Spacer/VBoxContainer/Headware/Back" to="." method="_on_headwear_back_pressed"] +[connection signal="pressed" from="VBoxContainer/Spacer/VBoxContainer/Headware/Forward" to="." method="_on_headwear_forward_pressed"] +[connection signal="pressed" from="VBoxContainer/Spacer/VBoxContainer/Hairstyle/Back" to="." method="_on_hairstyle_back_pressed"] +[connection signal="pressed" from="VBoxContainer/Spacer/VBoxContainer/Hairstyle/Forward" to="." method="_on_hairstyle_forward_pressed"] +[connection signal="pressed" from="VBoxContainer/Spacer/VBoxContainer/Character/Back" to="." method="_on_character_back_pressed"] +[connection signal="pressed" from="VBoxContainer/Spacer/VBoxContainer/Character/Forward" to="." method="_on_character_forward_pressed"] +[connection signal="pressed" from="VBoxContainer/bottom_panel/back" to="." method="exit"] diff --git a/client/gui/menus/chat.gd b/client/gui/menus/chat.gd new file mode 100644 index 00000000..150b0e7e --- /dev/null +++ b/client/gui/menus/chat.gd @@ -0,0 +1,48 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends Menu +class_name ChatOpen + +const CHAT_MESSAGE_SCENE = preload("res://menu/communicate/chat/chat_message.tscn") + +@onready var messages_container: VBoxContainer = $PanelContainer/MarginContainer/VBoxContainer/ScrollContainerCustom/Messages +@onready var scroll_container: ScrollContainerCustom = $PanelContainer/MarginContainer/VBoxContainer/ScrollContainerCustom +@onready var line: LineEdit = $PanelContainer/MarginContainer/VBoxContainer/LineEdit +@onready var game_menu: GameMenu = get_parent() +@onready var game: Game = game_menu.game + +func _ready() -> void: + super() + for i in game.text_message_history: + add_message(i) + + game.text_message.connect( + func message(m: Game.TextMessage): + add_message(m) + ) + +func _input(event: InputEvent) -> void: + if Input.is_action_just_pressed("chat"): + if line.text != "": + game.mp.send_chat(game.my_player_id, line.text) + exit() + super(event) + +func add_message(message: Game.TextMessage): + var chat_message: ChatMessage = CHAT_MESSAGE_SCENE.instantiate() + messages_container.add_child(chat_message) + chat_message.set_message(message.username, message.text, message.color) + scroll_container.call_deferred("scroll_to_bottom") diff --git a/client/gui/menus/chat.gd.uid b/client/gui/menus/chat.gd.uid new file mode 100644 index 00000000..672792c0 --- /dev/null +++ b/client/gui/menus/chat.gd.uid @@ -0,0 +1 @@ +uid://cfweimyoq5vv0 diff --git a/client/gui/menus/chat.tscn b/client/gui/menus/chat.tscn new file mode 100644 index 00000000..626038f4 --- /dev/null +++ b/client/gui/menus/chat.tscn @@ -0,0 +1,56 @@ +[gd_scene load_steps=7 format=3 uid="uid://dbd6k56l4p0ls"] + +[ext_resource type="Script" uid="uid://cfweimyoq5vv0" path="res://gui/menus/chat.gd" id="1_gntkb"] +[ext_resource type="Material" uid="uid://beea1pc5nt67r" path="res://gui/resources/materials/dark_blur_material.tres" id="2_1au48"] +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="3_lrbjr"] +[ext_resource type="StyleBox" uid="uid://bw4jamyna1top" path="res://gui/resources/style/panel_style_sidebar.tres" id="4_d4nta"] +[ext_resource type="Script" uid="uid://cmncjc06kadpe" path="res://gui/components/blur_setup.gd" id="5_l1coj"] +[ext_resource type="Script" uid="uid://bd7bylb2t2m0" path="res://gui/components/touch_scroll_container.gd" id="6_ff15x"] + +[node name="ChatOpen" type="Control"] +layout_mode = 3 +anchors_preset = 9 +anchor_bottom = 1.0 +offset_right = 296.0 +grow_vertical = 2 +script = ExtResource("1_gntkb") +support_anim = false +auto_anim = null + +[node name="PanelContainer" type="PanelContainer" parent="."] +material = ExtResource("2_1au48") +layout_mode = 1 +anchors_preset = 9 +anchor_bottom = 1.0 +offset_right = 296.0 +grow_vertical = 2 +theme = ExtResource("3_lrbjr") +theme_override_styles/panel = ExtResource("4_d4nta") +script = ExtResource("5_l1coj") + +[node name="MarginContainer" type="MarginContainer" parent="PanelContainer"] +layout_mode = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/MarginContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +theme_override_constants/separation = 0 + +[node name="ScrollContainerCustom" type="ScrollContainer" parent="PanelContainer/MarginContainer/VBoxContainer"] +material = ExtResource("2_1au48") +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +script = ExtResource("6_ff15x") +auto_scroll_to_bottom = true + +[node name="Messages" type="VBoxContainer" parent="PanelContainer/MarginContainer/VBoxContainer/ScrollContainerCustom"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 + +[node name="LineEdit" type="LineEdit" parent="PanelContainer/MarginContainer/VBoxContainer" groups=["autoselect"]] +layout_mode = 2 +placeholder_text = "c.chat.write_message" +keep_editing_on_text_submit = true diff --git a/client/gui/menus/document/document.gd b/client/gui/menus/document/document.gd new file mode 100644 index 00000000..c7042852 --- /dev/null +++ b/client/gui/menus/document/document.gd @@ -0,0 +1,152 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends Menu + +const MARGIN: int = 75 + +var labels := {} + +func _ready(): + super() + $ScrollContainer/VBoxContainer.add_child(build_document(data)) + +func build_document(element: Dictionary, bullet: bool = false) -> Control: + var node: Control + match element["t"]: + "document": + node = VBoxContainer.new() + node.name = "Document" + for e in element["es"]: + node.add_child(build_document(e)) + "page": + node = PanelContainer.new() + node.name = "Page" + node.add_theme_stylebox_override("panel", preload("res://menu/theme/style/paper_panel_style.tres")) + node.set_custom_minimum_size(Vector2(800, 1131.371)) + var margin := MarginContainer.new() + margin.add_theme_constant_override("margin_bottom", MARGIN) + margin.add_theme_constant_override("margin_top", MARGIN) + margin.add_theme_constant_override("margin_left", MARGIN) + margin.add_theme_constant_override("margin_right", MARGIN) + var vbox := VBoxContainer.new() + if element["background"]: + margin.add_child(background(element["background"])) + margin.add_child(vbox) + for e in element["es"]: + vbox.add_child(build_document(e, bullet)) + node.add_child(margin) + "label": + var label_id = element["id"] + node = build_document(element["e"], bullet) + labels[label_id] = node + "list": + node = VBoxContainer.new() + node.name = "List" + for e in element["es"]: + node.add_child(build_document(e, true)) + "table": + node = VBoxContainer.new() + node.name = "Rows" + node.size_flags_horizontal = Control.SIZE_EXPAND_FILL + for r in range(element["es"].size()): + var row = HBoxContainer.new() + node.add_child(row) + row.size_flags_horizontal = Control.SIZE_EXPAND_FILL + row.name = "Row%d" % r + for c in element["es"][r]: + var e = build_document(c, bullet) + e.size_flags_horizontal = Control.SIZE_EXPAND_FILL + row.add_child(e) + "par": + node = VBoxContainer.new() + node.name = "Paragraph" + for e in element["es"]: + node.add_child(build_document(e, bullet)) + "ref": + # TODO: Support clicking + node = build_document(element["e"], bullet) + "conditional": + # Ignore all conditionals for now, since they are only revelant for typst version + node = Control.new() + "text": + node = text_node(element, bullet) + _: + node = Control.new() + push_error("Error building document: Unknown type \"%s\"" % element["t"]) + return node + +func text_node(element: Dictionary, bullet: bool) -> Control: + var node: Control + var label := Label.new() + # we need a hbox container for rtl + if bullet: + node = HBoxContainer.new() + var bullet_label := Label.new() + bullet_label.text = "•" + if element.get("size"): + bullet_label.add_theme_font_size_override("font_size", element["size"]) + # TODO: Ignore font color for now. Will be removed in the future. + # if element.get("color"): + # bullet_label.add_theme_color_override("font_color", Color(element["color"])) + bullet_label.add_theme_color_override("font_color", Color.BLACK) + label.add_theme_color_override("font_color", Color.BLACK) + node.add_child(bullet_label) + label.size_flags_horizontal = Control.SIZE_EXPAND_FILL + node.add_child(label) + else: + node = label + label.name = "Text" + label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART + label.text = Global.get_message_str(element["s"]) + if element.get("font"): + match element["font"]: + "Great Vibes": + node.add_theme_font_override("font", preload("res://menu/theme/fonts/font-sansita-swashed.woff2")) + if element.get("size"): + node.add_theme_font_size_override("font_size", element["size"]) + # TODO: Ignore font color for now. Will be removed in the future. + # if element.get("color"): + # label.add_theme_color_override("font_color", Color(element["color"])) + label.add_theme_color_override("font_color", Color.BLACK) + return node + +func background(background_name: String) -> SubViewportContainer: + var item_name: String + match background_name: + "cover": item_name = "plate:plate,plate,plate,dirt" + "toc": item_name = "tomato" + "tomato_soup": item_name = "plate:tomato-soup" + "burger": item_name = "plate:sliced-bun,sliced-tomato,sliced-lettuce" + "mochi": item_name = "plate:strawberry-mochi" + "curry": item_name = "plate:curry,cooked-rice" + "icecream": item_name = "plate:strawberry-icecream" + "drinks": item_name = "glass:strawberry-shake" + var n: item_name = n + var scene: ItemRender = preload("res://menu/communicate/item/item_render.tscn").instantiate() + scene.set_item(item_name, false) + var vc := SubViewportContainer.new() + var viewport := SubViewport.new() + viewport.add_child(scene) + viewport.own_world_3d = true + viewport.transparent_bg = true + vc.size_flags_horizontal = Control.SIZE_SHRINK_CENTER + vc.size_flags_vertical = Control.SIZE_SHRINK_END + #vc.material = preload("res://menu/theme/materials/printed_material.tres") + vc.add_child(viewport) + return vc + +func _menu_open(): pass +func _menu_exit(): pass diff --git a/client/gui/menus/document/document.gd.uid b/client/gui/menus/document/document.gd.uid new file mode 100644 index 00000000..c84b53b1 --- /dev/null +++ b/client/gui/menus/document/document.gd.uid @@ -0,0 +1 @@ +uid://c83p4k0nredmd diff --git a/client/gui/menus/document/document.tscn b/client/gui/menus/document/document.tscn new file mode 100644 index 00000000..537ac8b8 --- /dev/null +++ b/client/gui/menus/document/document.tscn @@ -0,0 +1,29 @@ +[gd_scene load_steps=3 format=3 uid="uid://bdggwo8un3mys"] + +[ext_resource type="Script" uid="uid://c83p4k0nredmd" path="res://gui/menus/document/document.gd" id="1_gyisx"] +[ext_resource type="Script" uid="uid://bd7bylb2t2m0" path="res://gui/components/touch_scroll_container.gd" id="2_0d0p0"] + +[node name="Document" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_gyisx") +support_anim = false +auto_anim = null + +[node name="ScrollContainer" type="ScrollContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("2_0d0p0") + +[node name="VBoxContainer" type="VBoxContainer" parent="ScrollContainer"] +layout_mode = 2 +size_flags_horizontal = 6 +size_flags_vertical = 4 diff --git a/client/gui/menus/entry.gd b/client/gui/menus/entry.gd new file mode 100644 index 00000000..91bec795 --- /dev/null +++ b/client/gui/menus/entry.gd @@ -0,0 +1,35 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +class_name Entry +extends Menu + +func _ready(): + super() + get_window().title = "Hurry Curry!" + + var args = OS.get_cmdline_user_args() + if args.size() == 1: + await submenu("res://gui/menus/game.tscn", args[0]) + elif not Global.get_setting("gameplay.setup_completed"): + await submenu("res://gui/menus/setup/setup.tscn") + else: + await submenu("res://gui/menus/main/main.tscn") + + print("Menu stack empty, quitting game.") + get_tree().quit() + +func quit(): + pass diff --git a/client/gui/menus/entry.gd.uid b/client/gui/menus/entry.gd.uid new file mode 100644 index 00000000..4bd126a6 --- /dev/null +++ b/client/gui/menus/entry.gd.uid @@ -0,0 +1 @@ +uid://yxaynnimyxgr diff --git a/client/gui/menus/entry.tscn b/client/gui/menus/entry.tscn new file mode 100644 index 00000000..f4eced3e --- /dev/null +++ b/client/gui/menus/entry.tscn @@ -0,0 +1,12 @@ +[gd_scene load_steps=2 format=3 uid="uid://cd52sr1cmo8oj"] + +[ext_resource type="Script" uid="uid://yxaynnimyxgr" path="res://gui/menus/entry.gd" id="1_kibw2"] + +[node name="Entry" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_kibw2") diff --git a/client/gui/menus/error.gd b/client/gui/menus/error.gd new file mode 100644 index 00000000..e11812d5 --- /dev/null +++ b/client/gui/menus/error.gd @@ -0,0 +1,23 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends Menu + +func _ready(): + super() + $Panel/SmartMarginContainer/contents/mesage.text = Global.error_message + +func _on_return_pressed(): + replace_menu("res://gui/menus/main/main.tscn") diff --git a/client/gui/menus/error.gd.uid b/client/gui/menus/error.gd.uid new file mode 100644 index 00000000..20a67804 --- /dev/null +++ b/client/gui/menus/error.gd.uid @@ -0,0 +1 @@ +uid://bl0n4atrdcogm diff --git a/client/gui/menus/error.tscn b/client/gui/menus/error.tscn new file mode 100644 index 00000000..dcebf322 --- /dev/null +++ b/client/gui/menus/error.tscn @@ -0,0 +1,70 @@ +[gd_scene load_steps=7 format=3 uid="uid://cimgn07lbcs4v"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_cabdu"] +[ext_resource type="PackedScene" uid="uid://l4vm07dtda4j" path="res://gui/menus/main/background.tscn" id="2_5fxol"] +[ext_resource type="Script" uid="uid://bl0n4atrdcogm" path="res://gui/menus/error.gd" id="2_dbe41"] +[ext_resource type="PackedScene" uid="uid://bg2d78ycorcqk" path="res://gui/menus/transition/scene_transition.tscn" id="4_1nbt3"] +[ext_resource type="Material" uid="uid://beea1pc5nt67r" path="res://gui/resources/materials/dark_blur_material.tres" id="4_hxkkd"] +[ext_resource type="Script" uid="uid://byshs20og68tn" path="res://gui/components/smart_margin_container.gd" id="5_rfcg2"] + +[node name="ErrorMenu" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("1_cabdu") +script = ExtResource("2_dbe41") + +[node name="MenuBackground" parent="." instance=ExtResource("2_5fxol")] + +[node name="Panel" type="Panel" parent="."] +material = ExtResource("4_hxkkd") +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="SmartMarginContainer" type="MarginContainer" parent="Panel"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("5_rfcg2") +metadata/_custom_type_script = "uid://byshs20og68tn" + +[node name="contents" type="VBoxContainer" parent="Panel/SmartMarginContainer"] +layout_mode = 2 +alignment = 1 + +[node name="title" type="Label" parent="Panel/SmartMarginContainer/contents"] +layout_mode = 2 +theme_override_font_sizes/font_size = 61 +text = "Error" +horizontal_alignment = 1 + +[node name="mesage" type="Label" parent="Panel/SmartMarginContainer/contents"] +layout_mode = 2 +theme_override_font_sizes/font_size = 24 +text = "This should be the error message." +horizontal_alignment = 1 + +[node name="Control" type="Control" parent="Panel/SmartMarginContainer/contents"] +custom_minimum_size = Vector2(0, 15.805) +layout_mode = 2 + +[node name="return" type="Button" parent="Panel/SmartMarginContainer/contents"] +layout_mode = 2 +size_flags_horizontal = 4 +text = "Return to Main Menu" + +[node name="SceneTransition" parent="." instance=ExtResource("4_1nbt3")] +visible = false +layout_mode = 1 + +[connection signal="pressed" from="Panel/SmartMarginContainer/contents/return" to="." method="_on_return_pressed"] diff --git a/client/gui/menus/game.gd b/client/gui/menus/game.gd new file mode 100644 index 00000000..a4916b92 --- /dev/null +++ b/client/gui/menus/game.gd @@ -0,0 +1,64 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends Menu +class_name GameMenu + +@onready var game: Game = $Game +@onready var debug_label: RichTextLabel = $Debug +@onready var overlay: Overlay = $Overlay +@onready var popup_message: PopupMessage = $PopupMessage +@onready var chat_preview: ChatPreview = $ChatPreview +@onready var pinned_items: PinnedItemMessages = $PinnedItemMessages + +func _ready(): + get_tree().get_root().go_back_requested.connect(open_ingame_menu) + super() + transition.set_loading_text(tr("c.menu.game.connecting")) + Settings.hook_changed_init("ui.hide_overlays", false, apply_hide_overlays) + +func _input(_event): + if Input.is_action_just_pressed("ui_menu"): + open_ingame_menu() + + if Input.is_action_just_pressed("chat"): + Sound.play_click() + chat_preview.visible = false + await submenu("res://gui/menus/chat.tscn") + chat_preview.visible = true + + if Input.is_action_just_pressed("toggle_overlay"): + Global.set_setting("ui.hide_overlays", not Global.get_setting("ui.hide_overlays")) + +func _menu_cover(state): + game.follow_camera.disable_input_menu = state + game.follow_camera.update_disable_input() + +func _process(_delta): + if Global.get_setting("graphics.debug_info"): + debug_label.show() + debug_label.text = "%d FPS\nDriver: %s" % [Engine.get_frames_per_second(), ProjectSettings.get_setting("rendering/rendering_device/driver")] + else: debug_label.hide() + +func open_ingame_menu(): + if popup != null: return + Sound.play_click() + submenu("res://gui/menus/ingame.tscn") + +func apply_hide_overlays(v: bool): + overlay.visible = v + pinned_items.visible = v + chat_preview.visible = v + popup_message.visible = false diff --git a/client/gui/menus/game.gd.uid b/client/gui/menus/game.gd.uid new file mode 100644 index 00000000..992bc7f3 --- /dev/null +++ b/client/gui/menus/game.gd.uid @@ -0,0 +1 @@ +uid://bmno0s2du3ie6 diff --git a/client/gui/menus/game.tscn b/client/gui/menus/game.tscn new file mode 100644 index 00000000..56df81d6 --- /dev/null +++ b/client/gui/menus/game.tscn @@ -0,0 +1,46 @@ +[gd_scene load_steps=8 format=3 uid="uid://bbjwoxs71fnsk"] + +[ext_resource type="Script" uid="uid://bmno0s2du3ie6" path="res://gui/menus/game.gd" id="1_cdpsh"] +[ext_resource type="PackedScene" uid="uid://c6krh36hoqfg8" path="res://game.tscn" id="2_uojcy"] +[ext_resource type="PackedScene" uid="uid://bpikve6wlsjfl" path="res://gui/overlays/ingame/score.tscn" id="3_i0ytb"] +[ext_resource type="PackedScene" uid="uid://bc50la65ntifb" path="res://gui/overlays/lobby/lobby.tscn" id="3_udxby"] +[ext_resource type="PackedScene" uid="uid://b21nrnkygiyjt" path="res://gui/components/message/popup_message/popup_message.tscn" id="5_n1wy0"] +[ext_resource type="PackedScene" uid="uid://xcxbmynn8mhi" path="res://gui/overlays/ingame/chat.tscn" id="6_dh5lr"] +[ext_resource type="PackedScene" uid="uid://dcrr1rwdwbkq8" path="res://gui/components/message/popup_message/pinned_item_messages.tscn" id="7_lf2li"] + +[node name="GameMenu" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_cdpsh") +auto_anim = false + +[node name="Game" parent="." instance=ExtResource("2_uojcy")] + +[node name="Overlay" parent="." instance=ExtResource("3_i0ytb")] +layout_mode = 1 + +[node name="Lobby" parent="." instance=ExtResource("3_udxby")] +layout_mode = 1 + +[node name="PinnedItemMessages" parent="." instance=ExtResource("7_lf2li")] +layout_mode = 1 + +[node name="ChatPreview" parent="." instance=ExtResource("6_dh5lr")] +layout_mode = 1 + +[node name="PopupMessage" parent="." instance=ExtResource("5_n1wy0")] +layout_mode = 1 + +[node name="Debug" type="RichTextLabel" parent="."] +visible = false +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 diff --git a/client/gui/menus/ingame.gd b/client/gui/menus/ingame.gd new file mode 100644 index 00000000..4809b2ee --- /dev/null +++ b/client/gui/menus/ingame.gd @@ -0,0 +1,82 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends Menu + +@onready var anim = $AnimationPlayer +@onready var options = $Side/Margin/Options +@onready var game: Game = $"../Game" +@onready var lobby_button: Button = $Side/Margin/Options/Lobby +@onready var leave_button: Button = $Side/Margin/Options/Leave + +var opened +func _ready(): + opened = Time.get_ticks_msec() + game.join_state_updated.connect(_on_game_join_state_changed) + _on_game_join_state_changed(game.join_state) + update_lobby_button() + super() + +func update_lobby_button(): + lobby_button.disabled = game.in_lobby or game.join_state == Game.JoinState.SPECTATING + if game.in_lobby: + lobby_button.tooltip_text = "Cannot cancel game since no game is running." + elif not game.join_state == Game.JoinState.JOINED: + lobby_button.tooltip_text = "You must join in order to be able to cancel the current game." + else: + lobby_button.tooltip_text = "" + +func anim_setup(): pass +func _menu_open(): + anim.play("activate") + await anim.animation_finished + game.mp.send_idle(true) +func _menu_exit(): + game.mp.send_idle(false) + anim.play_backwards("activate") + await anim.animation_finished + +func _on_resume_pressed(): + exit() + +func _on_main_menu_pressed(): + parent_menu.replace_menu("res://gui/menus/main/main.tscn") + +func _on_settings_pressed(): + submenu("res://gui/menus/settings/settings.tscn") + +func _on_reconnect_pressed(): + parent_menu.replace_menu("res://gui/menus/game.tscn", parent_menu.data) + +func _on_quit_pressed(): + quit() + +func _on_lobby_pressed(): + game.mp.send_chat(game.my_player_id, "/end") + exit() + +func _on_leave_pressed(): + game.toggle_join() + +func _on_game_join_state_changed(state: Game.JoinState): + match state: + Game.JoinState.JOINED: + leave_button.disabled = false + leave_button.text = tr("c.menu.ingame.leave") + Game.JoinState.SPECTATING: + leave_button.disabled = false + leave_button.text = tr("c.menu.ingame.join") + Game.JoinState.WAITING: + leave_button.disabled = true diff --git a/client/gui/menus/ingame.gd.uid b/client/gui/menus/ingame.gd.uid new file mode 100644 index 00000000..496c313c --- /dev/null +++ b/client/gui/menus/ingame.gd.uid @@ -0,0 +1 @@ +uid://dyi2xohgxeybb diff --git a/client/gui/menus/ingame.tscn b/client/gui/menus/ingame.tscn new file mode 100644 index 00000000..0a77af14 --- /dev/null +++ b/client/gui/menus/ingame.tscn @@ -0,0 +1,142 @@ +[gd_scene load_steps=12 format=3 uid="uid://lxlgtjm8hw7v"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_2vmyh"] +[ext_resource type="Script" uid="uid://dyi2xohgxeybb" path="res://gui/menus/ingame.gd" id="2_0h3no"] +[ext_resource type="Material" uid="uid://beea1pc5nt67r" path="res://gui/resources/materials/dark_blur_material.tres" id="3_vvvlt"] +[ext_resource type="Script" uid="uid://cmncjc06kadpe" path="res://gui/components/blur_setup.gd" id="4_b6bm7"] +[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://gui/resources/fonts/font-sansita-swashed.woff2" id="4_scupw"] +[ext_resource type="StyleBox" uid="uid://bw4jamyna1top" path="res://gui/resources/style/panel_style_sidebar.tres" id="4_vr8y1"] +[ext_resource type="Script" uid="uid://byshs20og68tn" path="res://gui/components/smart_margin_container.gd" id="6_poj4k"] + +[sub_resource type="Animation" id="Animation_8sedy"] +length = 0.001 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Side:position:x") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(0, -0.0005, 0, 0.0005, 0), +"times": PackedFloat32Array(0) +} + +[sub_resource type="Animation" id="Animation_660jl"] +resource_name = "activate" +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Side:position:x") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(-400, -0.25, 0, 0.25, 0, 0, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 1) +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_u0kyp"] +_data = { +&"RESET": SubResource("Animation_8sedy"), +&"activate": SubResource("Animation_660jl") +} + +[sub_resource type="FontVariation" id="FontVariation_ud3l8"] +base_font = ExtResource("4_scupw") +variation_embolden = 0.5 + +[node name="IngameMenu" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("1_2vmyh") +script = ExtResource("2_0h3no") + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +libraries = { +&"": SubResource("AnimationLibrary_u0kyp") +} +speed_scale = 8.0 + +[node name="Side" type="PanelContainer" parent="."] +material = ExtResource("3_vvvlt") +layout_mode = 1 +anchors_preset = 9 +anchor_bottom = 1.0 +offset_right = 296.0 +grow_vertical = 2 +theme_override_styles/panel = ExtResource("4_vr8y1") +script = ExtResource("4_b6bm7") + +[node name="Margin" type="MarginContainer" parent="Side"] +layout_mode = 2 +theme_override_constants/margin_left = 20 +theme_override_constants/margin_top = 20 +theme_override_constants/margin_right = 20 +theme_override_constants/margin_bottom = 20 +script = ExtResource("6_poj4k") + +[node name="Options" type="VBoxContainer" parent="Side/Margin"] +layout_mode = 2 + +[node name="Title" type="Label" parent="Side/Margin/Options"] +auto_translate_mode = 2 +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0.566408, 0.208917, 0.266045, 1) +theme_override_constants/outline_size = 10 +theme_override_fonts/font = SubResource("FontVariation_ud3l8") +theme_override_font_sizes/font_size = 48 +text = "Hurry Curry!" + +[node name="Spacer" type="Control" parent="Side/Margin/Options"] +custom_minimum_size = Vector2(0, 10) +layout_mode = 2 + +[node name="Resume" type="Button" parent="Side/Margin/Options"] +layout_mode = 2 +text = "c.menu.ingame.resume" +alignment = 0 + +[node name="Leave" type="Button" parent="Side/Margin/Options"] +layout_mode = 2 +text = "c.menu.ingame.join" +alignment = 0 + +[node name="Lobby" type="Button" parent="Side/Margin/Options"] +layout_mode = 2 +text = "c.menu.ingame.cancel" +alignment = 0 + +[node name="Reconnect" type="Button" parent="Side/Margin/Options"] +layout_mode = 2 +text = "c.menu.ingame.reconnect" +alignment = 0 + +[node name="Spacer2" type="Control" parent="Side/Margin/Options"] +custom_minimum_size = Vector2(0, 10) +layout_mode = 2 + +[node name="Settings" type="Button" parent="Side/Margin/Options"] +layout_mode = 2 +text = "c.menu.settings" +alignment = 0 + +[node name="Spacer3" type="Control" parent="Side/Margin/Options"] +custom_minimum_size = Vector2(0, 10) +layout_mode = 2 + +[node name="MainMenu" type="Button" parent="Side/Margin/Options"] +layout_mode = 2 +text = "c.menu.ingame.main_menu" +alignment = 0 + +[connection signal="pressed" from="Side/Margin/Options/Resume" to="." method="_on_resume_pressed"] +[connection signal="pressed" from="Side/Margin/Options/Leave" to="." method="_on_leave_pressed"] +[connection signal="pressed" from="Side/Margin/Options/Lobby" to="." method="_on_lobby_pressed"] +[connection signal="pressed" from="Side/Margin/Options/Reconnect" to="." method="_on_reconnect_pressed"] +[connection signal="pressed" from="Side/Margin/Options/Settings" to="." method="_on_settings_pressed"] +[connection signal="pressed" from="Side/Margin/Options/MainMenu" to="." method="_on_main_menu_pressed"] diff --git a/client/gui/menus/main/about.gd b/client/gui/menus/main/about.gd new file mode 100644 index 00000000..b56d3941 --- /dev/null +++ b/client/gui/menus/main/about.gd @@ -0,0 +1,169 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +extends Menu + +var authors := ["metamuffin", "nokoe", "tpart"] +var contributors := ["sofviic", "BigBrotherNii", "Miner34"] +const cc_by_4 := "CC-BY 4.0" +const cc_by_3 := "CC-BY 3.0" +const cc0 := "CC0" + +const AGPL_NOTICE := """This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, version 3 of the License only. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see .""" + +const SOURCE_CODE := "https://codeberg.org/hurrycurry/hurrycurry" + +func _ready() -> void: + super() + $side/margin/options/first/source.tooltip_text = SOURCE_CODE + +var credits := [ + [tr("c.credits.models"), [ + ["kenney.nl", "Various Models", cc0], + ["Kay Lousberg", "Kitchen tiles", cc0], + ["Poly by Google", "Strawberry", cc_by_3], + ["Poly by Google", "Fish", cc_by_3], + ["jeremy", "Propeller hat", cc_by_3] + ]], + [tr("c.credits.sounds"), [ + ["Dryoma", "Footstep sounds", cc_by_4], + ["Koops", "Page_Turn_24.wav", cc_by_4], + ["InspectorJ", "Pencil, Writing, Close, A.wav", cc_by_4], + ["Dillon Becker", "Super Dialogue Audio Pack", cc_by_4], + ["Ellr", "Universal UI/Menu Soundpack", cc_by_4], + ["toyoto", "Woosh Fleuret Escrime B.wav", cc_by_4], + ["deleted_user_877451", "Game_over.wav", cc_by_3], + ["Quaternius", "Someting, dont remember...", cc0], + ["Dillon Becker", "Super Dialogue Audio Pack V1", cc_by_4] + ]], + [tr("c.credits.translations"), { + tr("c.settings.ui.language.zh_Hans"): ["Outbreak2096"], + tr("c.settings.ui.language.zh_Hant"): ["hugoalh"], + tr("c.settings.ui.language.nl"): ["Vistaus"], + tr("c.settings.ui.language.it"): ["Miner34", "solemden"], + tr("c.settings.ui.language.eu"): ["josuigoa"], + tr("c.settings.ui.language.fr"): ["fnetX", "lejun"], + tr("c.settings.ui.language.pl"): ["tranzystorekk"], + tr("c.settings.ui.language.he"): ["RustyStriker"], + tr("c.settings.ui.language.el"): ["n0toose"], + tr("c.settings.ui.language.ja"): ["BigBrotherNii"], + tr("c.settings.ui.language.ar"): ["sofviic"], + tr("c.settings.ui.language.tr"): ["furkanunsalan", "tekrei"], + tr("c.settings.ui.language.ru"): ["0ko"], + }] +] + +func _menu_cover(state): + $side.visible = not state + +func credits_text() -> String: + var text = "[center]" + authors.shuffle() + contributors.shuffle() + + text += "\n\n\n[b]%s[/b]\n\n%s\n\n[b]%s[/b]\n\n%s\n\n[b]%s[/b]\n\n\n" % [ + tr("c.credits.title"), + tr("c.credits.developed_by"), + "\n".join(authors), + tr("c.credits.contributors"), + ", ".join(contributors), + ] + + for section in credits: + text += "[b]%s[/b]\n\n" % section[0] + if typeof(section[1]) == TYPE_DICTIONARY: + text += "[table=2]" + for key in section[1]: + text += "[cell][right]%s[/right][/cell]" % key + text += "[cell][left]%s[/left][/cell]" % ", ".join(section[1][key]) + text += "[/table]" + else: + text += "[table=3]" + for entry in section[1]: + text += "[cell][right]%s[/right][/cell]" % entry[0] + text += "[cell][left]%s[/left][/cell]" % entry[1] + text += "[cell][left]%s[/left][/cell]" % entry[2] + text += "[/table]" + text += "\n\n\n" + + text += "\n[b]%s[/b]\n\n\n[/center]" % tr("c.credits.thanks") + return text + +func legal_text() -> String: + var all: Array[String] = [] + var translators: Array[String] = [] + for c in credits[2][1].values(): + translators.append_array(c) + translators.shuffle() + authors.shuffle() + contributors.shuffle() + all.append_array(authors) + all.append_array(contributors) + all.append_array(translators) + + var text := "Hurry Curry! - a game about cooking\n" + text += "[code]Copyright 2024, 2025 %s\n\n" % ", ".join(dedup_array(all)) + text += "%s[/code]\n\n" % AGPL_NOTICE + text += tr("c.legal.using_godot") + text += "\n\n[code]%s[/code]" % Engine.get_license_text() + return text + +func version_text() -> String: + var text := "[center][b]Hurry Curry![/b]\n\n" + OS.get_version() + text += "[table=2]" + var row = "[cell][right]%s[/right][/cell][cell][left]%s[/left][/cell]" + text += row % [tr("c.version.game"), Global.VERSION] + text += row % [tr("c.version.protocol"), "%s.%s" % [Multiplayer.VERSION_MAJOR, Multiplayer.VERSION_MINOR]] + text += row % [tr("c.version.godot"), Engine.get_version_info().string] + text += row % [tr("c.version.os"), OS.get_name()] + text += row % [tr("c.version.arch"), Engine.get_architecture_name()] + text += row % [tr("c.version.distribution"), Global.DISTRIBUTION] + + text += "[/table]" + text += "[/center]" + return text + +func _on_credits_pressed() -> void: + submenu("res://gui/menus/popup_large.tscn", credits_text()) + +func _on_legal_pressed() -> void: + submenu("res://gui/menus/popup_large.tscn", legal_text()) + +func _on_version_pressed() -> void: + submenu("res://gui/menus/popup_large.tscn", version_text()) + +func _on_back_pressed() -> void: + exit() + + +func _on_source_pressed() -> void: + OS.shell_open(SOURCE_CODE) + +func dedup_array(a: Array) -> Array: + var b = [] + for x in a: if not b.has(x): b.append(x) + return b diff --git a/client/gui/menus/main/about.gd.uid b/client/gui/menus/main/about.gd.uid new file mode 100644 index 00000000..3929f2c3 --- /dev/null +++ b/client/gui/menus/main/about.gd.uid @@ -0,0 +1 @@ +uid://pcu87stpkgd8 diff --git a/client/gui/menus/main/about.tscn b/client/gui/menus/main/about.tscn new file mode 100644 index 00000000..006b61fe --- /dev/null +++ b/client/gui/menus/main/about.tscn @@ -0,0 +1,93 @@ +[gd_scene load_steps=7 format=3 uid="uid://bpaenm8c6nmo8"] + +[ext_resource type="Script" uid="uid://pcu87stpkgd8" path="res://gui/menus/main/about.gd" id="1_0acu0"] +[ext_resource type="Material" uid="uid://2j8a0c0a2ta5" path="res://gui/resources/materials/blur_material.tres" id="1_ai5pk"] +[ext_resource type="StyleBox" uid="uid://bw4jamyna1top" path="res://gui/resources/style/panel_style_sidebar.tres" id="2_pya1x"] +[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://gui/resources/fonts/font-sansita-swashed.woff2" id="4_kx3j7"] +[ext_resource type="Script" uid="uid://byshs20og68tn" path="res://gui/components/smart_margin_container.gd" id="4_t51wf"] + +[sub_resource type="FontVariation" id="FontVariation_o2r3e"] +base_font = ExtResource("4_kx3j7") +variation_embolden = 0.5 + +[node name="AboutMenu" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_0acu0") +support_anim = false + +[node name="side" type="PanelContainer" parent="."] +material = ExtResource("1_ai5pk") +layout_mode = 1 +anchors_preset = 9 +anchor_bottom = 1.0 +offset_right = 294.0 +grow_vertical = 2 +theme_override_styles/panel = ExtResource("2_pya1x") + +[node name="margin" type="MarginContainer" parent="side"] +layout_mode = 2 +theme_override_constants/margin_left = 20 +theme_override_constants/margin_top = 20 +theme_override_constants/margin_right = 20 +theme_override_constants/margin_bottom = 20 +script = ExtResource("4_t51wf") + +[node name="options" type="VBoxContainer" parent="side/margin"] +layout_mode = 2 + +[node name="title" type="Label" parent="side/margin/options"] +auto_translate_mode = 2 +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0.566408, 0.208917, 0.266045, 1) +theme_override_constants/outline_size = 10 +theme_override_fonts/font = SubResource("FontVariation_o2r3e") +theme_override_font_sizes/font_size = 48 +text = "Hurry Curry!" + +[node name="spacer" type="Control" parent="side/margin/options"] +custom_minimum_size = Vector2(0, 10) +layout_mode = 2 + +[node name="first" type="VBoxContainer" parent="side/margin/options"] +layout_mode = 2 + +[node name="credits" type="Button" parent="side/margin/options/first"] +layout_mode = 2 +text = "c.menu.about.credits" +alignment = 0 + +[node name="version" type="Button" parent="side/margin/options/first"] +layout_mode = 2 +text = "c.menu.about.version" +alignment = 0 + +[node name="legal" type="Button" parent="side/margin/options/first"] +layout_mode = 2 +text = "c.menu.about.legal" +alignment = 0 + +[node name="source" type="Button" parent="side/margin/options/first"] +layout_mode = 2 +text = "c.menu.about.source" +alignment = 0 + +[node name="first2" type="VBoxContainer" parent="side/margin/options"] +layout_mode = 2 +size_flags_vertical = 3 +alignment = 2 + +[node name="back" type="Button" parent="side/margin/options/first2"] +layout_mode = 2 +text = "c.menu.back" +alignment = 0 + +[connection signal="pressed" from="side/margin/options/first/credits" to="." method="_on_credits_pressed"] +[connection signal="pressed" from="side/margin/options/first/version" to="." method="_on_version_pressed"] +[connection signal="pressed" from="side/margin/options/first/legal" to="." method="_on_legal_pressed"] +[connection signal="pressed" from="side/margin/options/first/source" to="." method="_on_source_pressed"] +[connection signal="pressed" from="side/margin/options/first2/back" to="." method="_on_back_pressed"] diff --git a/client/gui/menus/main/background.gd b/client/gui/menus/main/background.gd new file mode 100644 index 00000000..4abb84b4 --- /dev/null +++ b/client/gui/menus/main/background.gd @@ -0,0 +1,50 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends Node3D + +const CRATES = ["tomato-crate", "steak-crate", "cheese-crate", "lettuce-crate", "flour-crate", "coconut-crate"] +const TOOLS = ["stove", "stove", "stove", "sink", "cuttingboard", "sink", "cuttingboard", "oven", "freezer"] + +@onready var environment: WorldEnvironment = $Environment +@onready var map: Map = $Map + +func _ready(): + if !Global.on_vulkan(): + environment.environment.tonemap_exposure = 0.25 + + var tiles = {} + for x in range(-10, 11): + for y in range(-10, 11): + var w = exp(-sqrt(x * x + y * y) * 0.15) + var k = randf() * w + var tn = null + if k > 0.25: tn = "floor" + if k > 0.4: tn = choose(CRATES) if randf() > 0.3 else "counter" + if k > 0.6: tn = choose(TOOLS) + if tn != null: tiles[str(Vector2i(x,y))] = [tn,[x,y]] + + var gt = func (cs): + var t = tiles.get(str(Vector2i(cs[0],cs[1]))) + return null if t == null else t[0] + for pk in tiles.keys(): + var x = tiles[pk][1][0] + var y = tiles[pk][1][1] + var t = gt.call([x,y]) + if t != null: map.set_tile(Vector2i(x,y), t, [[x,y-1],[x-1,y],[x,y+1],[x+1,y]].map(gt)) + + map.flush() + +func choose(a): return a[floor(a.size() * randf())] diff --git a/client/gui/menus/main/background.gd.uid b/client/gui/menus/main/background.gd.uid new file mode 100644 index 00000000..7d61d488 --- /dev/null +++ b/client/gui/menus/main/background.gd.uid @@ -0,0 +1 @@ +uid://b2tq5rcjjcxdg diff --git a/client/gui/menus/main/background.tscn b/client/gui/menus/main/background.tscn new file mode 100644 index 00000000..2bd4ee04 --- /dev/null +++ b/client/gui/menus/main/background.tscn @@ -0,0 +1,71 @@ +[gd_scene load_steps=12 format=3 uid="uid://l4vm07dtda4j"] + +[ext_resource type="Script" uid="uid://b2tq5rcjjcxdg" path="res://gui/menus/main/background.gd" id="1_pgu7b"] +[ext_resource type="Script" uid="uid://cwg7wympevxs4" path="res://map/auto_setup/environment_setup.gd" id="2_7dwbj"] +[ext_resource type="Shader" uid="uid://b1k6ipo0sagli" path="res://gui/menus/main/clouds.gdshader" id="3_lapmn"] +[ext_resource type="PackedScene" uid="uid://b4gone8fu53r7" path="res://map/map.tscn" id="4_nslxb"] + +[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_uw50b"] +sky_top_color = Color(0.55, 0.55, 0.55, 1) + +[sub_resource type="Sky" id="Sky_utrtx"] +sky_material = SubResource("ProceduralSkyMaterial_uw50b") + +[sub_resource type="Environment" id="Environment_slkjl"] +background_mode = 1 +background_color = Color(0.517035, 0.49506, 0.878906, 1) +sky = SubResource("Sky_utrtx") +tonemap_mode = 2 +tonemap_exposure = 0.6 +tonemap_white = 0.9 +ssao_enabled = true + +[sub_resource type="QuadMesh" id="QuadMesh_fvp2p"] +size = Vector2(100, 100) + +[sub_resource type="FastNoiseLite" id="FastNoiseLite_e3eby"] +noise_type = 2 +frequency = 0.008 +fractal_octaves = 7 +fractal_gain = 0.72 + +[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_s4fnp"] +width = 1024 +height = 1024 +generate_mipmaps = false +seamless = true +noise = SubResource("FastNoiseLite_e3eby") + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_gd87g"] +render_priority = 0 +shader = ExtResource("3_lapmn") +shader_parameter/noise = SubResource("NoiseTexture2D_s4fnp") +shader_parameter/ccloud = Color(0.835938, 0.835938, 0.835938, 1) +shader_parameter/csky = Color(0.329412, 0.333333, 0.8, 1) + +[node name="MenuBackground" type="Node3D"] +script = ExtResource("1_pgu7b") + +[node name="Camera" type="Camera3D" parent="."] +transform = Transform3D(0.614606, 0.499662, -0.610408, -0.00282255, 0.775198, 0.631712, 0.78883, -0.386531, 0.477852, -9.13611, 4.90356, 1.22532) +projection = 1 +current = true +size = 8.0 +far = 100.0 + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(0.290334, 0.904946, -0.311092, 0.336606, 0.207739, 0.918445, 0.895769, -0.371371, -0.244296, 0, 7, 0) +light_energy = 1.25 +shadow_enabled = true + +[node name="Environment" type="WorldEnvironment" parent="."] +environment = SubResource("Environment_slkjl") +script = ExtResource("2_7dwbj") +allow_sdfgi = false + +[node name="the-sky-tm" type="MeshInstance3D" parent="."] +transform = Transform3D(0.614606, 0.499662, -0.610408, -0.00282255, 0.775198, 0.631712, 0.78883, -0.386531, 0.477851, 6, -13, -11) +mesh = SubResource("QuadMesh_fvp2p") +surface_material_override/0 = SubResource("ShaderMaterial_gd87g") + +[node name="Map" parent="." instance=ExtResource("4_nslxb")] diff --git a/client/gui/menus/main/clouds.gdshader b/client/gui/menus/main/clouds.gdshader new file mode 100644 index 00000000..8103f691 --- /dev/null +++ b/client/gui/menus/main/clouds.gdshader @@ -0,0 +1,36 @@ +/* + Hurry Curry! - a game about cooking + Copyright (C) 2025 Hurry Curry! Contributors + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, version 3 of the License only. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +*/ +shader_type spatial; +render_mode unshaded; + +uniform sampler2D noise : source_color; +uniform vec3 ccloud : source_color; +uniform vec3 csky : source_color; + +void fragment() { + vec2 uv = UV * 0.9; + uv += TIME * vec2(0.001,0.002); + + float f = texture(noise, uv).x; + f = 1. - f; + f = pow(f, 1.5); + f = floor(f*5.)/5.; + f = pow(f, 2.); + + ALBEDO = mix(csky, ccloud, f); +} diff --git a/client/gui/menus/main/clouds.gdshader.uid b/client/gui/menus/main/clouds.gdshader.uid new file mode 100644 index 00000000..00c2d21a --- /dev/null +++ b/client/gui/menus/main/clouds.gdshader.uid @@ -0,0 +1 @@ +uid://b1k6ipo0sagli diff --git a/client/gui/menus/main/main.gd b/client/gui/menus/main/main.gd new file mode 100644 index 00000000..423f756e --- /dev/null +++ b/client/gui/menus/main/main.gd @@ -0,0 +1,44 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends Menu + +@onready var quit_button = $side/margin/options/first/quit +@onready var margin_container: MarginContainer = $side/margin + +func _ready(): + super() + if OS.has_feature("web"): + quit_button.hide() + Sound.play_music("MainMenu") + ServerList.one_shot() + +func _menu_cover(state): + $side.visible = not state + +func _on_quit_pressed(): + quit() + +func _on_about_pressed(): + submenu("res://gui/menus/main/about.tscn") + +func _on_change_character_pressed(): + replace_menu("res://gui/menus/character.tscn", null, "res://gui/menus/main.tscn") + +func _on_settings_pressed(): + submenu("res://gui/menus/settings/settings.tscn") + +func _on_play_pressed(): + submenu("res://gui/menus/main/play.tscn") diff --git a/client/gui/menus/main/main.gd.uid b/client/gui/menus/main/main.gd.uid new file mode 100644 index 00000000..dc2cecd3 --- /dev/null +++ b/client/gui/menus/main/main.gd.uid @@ -0,0 +1 @@ +uid://bpiynadrmdd37 diff --git a/client/gui/menus/main/main.tscn b/client/gui/menus/main/main.tscn new file mode 100644 index 00000000..81595966 --- /dev/null +++ b/client/gui/menus/main/main.tscn @@ -0,0 +1,94 @@ +[gd_scene load_steps=10 format=3 uid="uid://dbj8508whxgwv"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_3qfu3"] +[ext_resource type="Script" uid="uid://bpiynadrmdd37" path="res://gui/menus/main/main.gd" id="2_xjnc3"] +[ext_resource type="PackedScene" uid="uid://l4vm07dtda4j" path="res://gui/menus/main/background.tscn" id="3_4evao"] +[ext_resource type="Material" uid="uid://2j8a0c0a2ta5" path="res://gui/resources/materials/blur_material.tres" id="4_nx4vf"] +[ext_resource type="Script" uid="uid://cmncjc06kadpe" path="res://gui/components/blur_setup.gd" id="5_0mn56"] +[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://gui/resources/fonts/font-sansita-swashed.woff2" id="5_k7bqq"] +[ext_resource type="StyleBox" uid="uid://bw4jamyna1top" path="res://gui/resources/style/panel_style_sidebar.tres" id="5_qlyeo"] +[ext_resource type="Script" uid="uid://byshs20og68tn" path="res://gui/components/smart_margin_container.gd" id="7_btdj1"] + +[sub_resource type="FontVariation" id="FontVariation_htgmg"] +base_font = ExtResource("5_k7bqq") +variation_embolden = 0.5 + +[node name="MainMenu" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("1_3qfu3") +script = ExtResource("2_xjnc3") + +[node name="MenuBackground" parent="." instance=ExtResource("3_4evao")] + +[node name="side" type="PanelContainer" parent="."] +material = ExtResource("4_nx4vf") +layout_mode = 1 +anchors_preset = 9 +anchor_bottom = 1.0 +offset_right = 294.0 +grow_vertical = 2 +theme_override_styles/panel = ExtResource("5_qlyeo") +script = ExtResource("5_0mn56") + +[node name="margin" type="MarginContainer" parent="side"] +layout_mode = 2 +theme_override_constants/margin_left = 20 +theme_override_constants/margin_top = 20 +theme_override_constants/margin_right = 20 +theme_override_constants/margin_bottom = 20 +script = ExtResource("7_btdj1") + +[node name="options" type="VBoxContainer" parent="side/margin"] +layout_mode = 2 + +[node name="title" type="Label" parent="side/margin/options"] +auto_translate_mode = 2 +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0.566408, 0.208917, 0.266045, 1) +theme_override_constants/outline_size = 10 +theme_override_fonts/font = SubResource("FontVariation_htgmg") +theme_override_font_sizes/font_size = 48 +text = "Hurry Curry!" + +[node name="spacer" type="Control" parent="side/margin/options"] +custom_minimum_size = Vector2(0, 10) +layout_mode = 2 + +[node name="first" type="VBoxContainer" parent="side/margin/options"] +layout_mode = 2 + +[node name="play" type="Button" parent="side/margin/options/first"] +layout_mode = 2 +text = "c.menu.play" +alignment = 0 + +[node name="change_character" type="Button" parent="side/margin/options/first"] +layout_mode = 2 +text = "c.menu.my_chef" +alignment = 0 + +[node name="settings" type="Button" parent="side/margin/options/first"] +layout_mode = 2 +text = "c.menu.settings" +alignment = 0 + +[node name="about" type="Button" parent="side/margin/options/first"] +layout_mode = 2 +text = "c.menu.about" +alignment = 0 + +[node name="quit" type="Button" parent="side/margin/options/first"] +layout_mode = 2 +text = "c.menu.quit" +alignment = 0 + +[connection signal="pressed" from="side/margin/options/first/play" to="." method="_on_play_pressed"] +[connection signal="pressed" from="side/margin/options/first/change_character" to="." method="_on_change_character_pressed"] +[connection signal="pressed" from="side/margin/options/first/settings" to="." method="_on_settings_pressed"] +[connection signal="pressed" from="side/margin/options/first/about" to="." method="_on_about_pressed"] +[connection signal="pressed" from="side/margin/options/first/quit" to="." method="_on_quit_pressed"] diff --git a/client/gui/menus/main/play.gd b/client/gui/menus/main/play.gd new file mode 100644 index 00000000..c9cbee2f --- /dev/null +++ b/client/gui/menus/main/play.gd @@ -0,0 +1,208 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends Menu + +var server_list_item: PackedScene = preload("res://gui/menus/main/server_list_item.tscn") +var url_regex: RegEx = RegEx.new() + +@onready var server_list: VBoxContainer = $side/margin/options/second/ScrollContainerCustom/ServerList +@onready var server_list_loading: Label = $side/margin/options/second/Loading +@onready var server_list_empty: Label = $side/margin/options/second/NoServers +@onready var connect_uri = $side/margin/options/second/connect/uri +@onready var server = $side/margin/options/second/server +@onready var server_control = $side/margin/options/second/server/control +@onready var server_connect = $side/margin/options/second/server/connect +@onready var editor_control = $side/margin/options/second/editor/control +@onready var editor_connect = $side/margin/options/second/editor/connect +@onready var editor_container = $side/margin/options/second/editor + + +func _ready(): + url_regex.compile("^(?:(ws|wss)://)?([^:]+)(?::([0-9]+))?$") + if OS.has_feature("web"): + server.hide() + connect_uri.text = Global.get_profile("last_server_url") + Sound.play_music("MainMenu") + + ServerList.update_server_list.connect(update_server_list) + ServerList.update_loading.connect(update_server_list_loading) + update_server_list(ServerList.current_list) + update_server_list_loading(ServerList.loading) + + super() + if not Global.get_profile("registry_asked"): + var popup_data := MenuPopup.Data.new() + popup_data.text = tr("c.menu.play.allow_query_registry").format([Global.get_setting("online.registry_url")]) + var allow_button := Button.new() + allow_button.text = tr("c.menu.accept") + var deny_button := Button.new() + deny_button.text = tr("c.menu.deny") + allow_button.pressed.connect(func(): Global.set_setting("online.use_registry", true)) + deny_button.pressed.connect(func(): Global.set_setting("online.use_registry", false)) + popup_data.buttons = [allow_button, deny_button] + await submenu("res://gui/menus/popup.tscn", popup_data) + Global.set_profile("registry_asked", true) + Global.save_settings() + Global.save_profile() + + ServerList.start() + +func update_server_list(lists: Array[Array]): + # Find out the index of the currently focused server in the list + var prev_selected_idx := -1 + for i in range(server_list.get_children().size()): + if server_list.get_child(i).button.has_focus(): + prev_selected_idx = i + break + + for c in server_list.get_children(): + c.queue_free() + + var idx := 0 + for l in lists: + for i in l: + var server_item: ServerListItem = server_list_item.instantiate() + server_list.add_child(server_item) + # TODO: Implement fallback address correctly + server_item.setup(i.name, roundi(i.players_online), i.version) + server_item.button.pressed.connect(connect_to.bind(i.address[0])) + # Focus the same server with the same index as the previously focused one + if idx == prev_selected_idx: + server_item.button.grab_focus() + idx += 1 + + if prev_selected_idx > idx: + # Same index cannot be focused, since number of servers decreased + if idx - 1 < 0: + connect_uri.grab_focus() + else: + server_list.get_child(idx - 1).button.grab_focus() + + # Show message if no servers available + server_list_empty.visible = idx == 0 + +func update_server_list_loading(status: bool): + server_list_loading.visible = status + +func _menu_cover(state): + $side.visible = not state + +func _on_connect_pressed(): + var url = connect_uri.text + var result := url_regex.search(url) + if result != null: + if result.get_string(1) == "": + url = "ws://" + url + # only set default port for non-tls websocket connections + if result.get_string(3) == "" and result.get_string(1) != "wss": + url = url + ":27032" + connect_uri.text = url + Global.set_profile("last_server_url", url) + Global.save_profile() + connect_to(url) + +func _on_quick_connect_pressed(): + if OS.has_feature("web"): + connect_to(JavaScriptBridge.eval(""" + window.location.protocol.endsWith("s:") + ? `wss://${window.location.host}/` + : `ws://${window.location.hostname}:27032/` + """)) + else: + connect_to("wss://hurrycurry.metamuffin.org/") + +func connect_to(url: String): + print("Connecting to %s" % url) + get_parent().replace_menu("res://gui/menus/game.tscn", url) + +func _on_server_control_pressed(): + match Server.state: + Service.State.RUNNING: Server.stop() + Service.State.STOPPED: Server.start() + Service.State.FAILED: Server.start() + +func _on_editor_control_pressed(): + match Editor.state: + Service.State.RUNNING: Editor.stop() + Service.State.STOPPED: Editor.start(); Server.start() + Service.State.FAILED: Editor.start() + +func _on_server_connect_pressed(): + connect_to("ws://%s:%d" % [Server.connect_address(), Global.get_setting("server.bind_port")]) + +func _on_editor_connect_pressed(): + connect_to("ws://[::1]:27032/") + +func _process(_delta): + server_control.disabled = false + server_connect.visible = Server.state == Service.State.RUNNING + server_control.modulate = Color.WHITE + match Server.state: + Service.State.RUNNING: + server_control.text = tr("c.menu.play.server_stop") + server_control.modulate = Color.AQUAMARINE + Service.State.TESTING: + server_control.text = tr("c.menu.play.server_testing") + server_control.disabled = true + Service.State.STARTING: + server_control.text = tr("c.menu.play.server_starting") + server_control.disabled = true + Service.State.STOPPED: + server_control.text = tr("c.menu.play.server_start") + Service.State.FAILED: + server_control.text = tr("c.menu.play.server_failed") + server_control.modulate = Color(1, 0.4, 0.5) + server_control.tooltip_text = tr("c.menu.play.server_failed_tooltip") + Service.State.UNAVAILABLE: + server_control.text = tr("c.menu.play.server_unavailable") + server_control.disabled = true + server_control.tooltip_text = tr("c.menu.play.server_binary_not_found") + + editor_control.disabled = false + editor_connect.visible = Editor.state == Service.State.RUNNING + editor_control.modulate = Color.WHITE + editor_container.visible = Editor.state != Service.State.UNAVAILABLE + match Editor.state: + Service.State.RUNNING: + editor_control.text = tr("c.menu.play.editor_stop") + editor_control.modulate = Color.AQUAMARINE + Service.State.TESTING: + editor_control.text = tr("c.menu.play.editor_testing") + editor_control.disabled = true + Service.State.STARTING: + editor_control.text = tr("c.menu.play.editor_starting") + editor_control.disabled = true + Service.State.STOPPED: + editor_control.text = tr("c.menu.play.editor_start") + Service.State.FAILED: + editor_control.text = tr("c.menu.play.editor_failed") + editor_control.modulate = Color(1, 0.4, 0.5) + editor_control.tooltip_text = tr("c.menu.play.server_failed_tooltip") + Service.State.UNAVAILABLE: + editor_control.text = tr("c.menu.play.editor_unavailable") + editor_control.disabled = true + editor_control.tooltip_text = tr("c.menu.play.server_binary_not_found") + + +func _on_uri_text_changed(new_text): + connect_uri.modulate = Color.WHITE if url_regex.search(new_text) else Color.RED + +func _on_back_pressed(): + exit() + +func _menu_exit(): + ServerList.stop() + super() diff --git a/client/gui/menus/main/play.gd.uid b/client/gui/menus/main/play.gd.uid new file mode 100644 index 00000000..d8ca168f --- /dev/null +++ b/client/gui/menus/main/play.gd.uid @@ -0,0 +1 @@ +uid://b126k2228nj4s diff --git a/client/gui/menus/main/play.tscn b/client/gui/menus/main/play.tscn new file mode 100644 index 00000000..441024a2 --- /dev/null +++ b/client/gui/menus/main/play.tscn @@ -0,0 +1,149 @@ +[gd_scene load_steps=9 format=3 uid="uid://c8url5fpttbem"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_cckds"] +[ext_resource type="Script" uid="uid://b126k2228nj4s" path="res://gui/menus/main/play.gd" id="2_phxx0"] +[ext_resource type="Material" uid="uid://2j8a0c0a2ta5" path="res://gui/resources/materials/blur_material.tres" id="3_fsbt7"] +[ext_resource type="Script" uid="uid://byshs20og68tn" path="res://gui/components/smart_margin_container.gd" id="4_gst6r"] +[ext_resource type="Script" uid="uid://bd7bylb2t2m0" path="res://gui/components/touch_scroll_container.gd" id="5_cm120"] +[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://gui/resources/fonts/font-sansita-swashed.woff2" id="5_ojpbf"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ukani"] + +[sub_resource type="FontVariation" id="FontVariation_htgmg"] +base_font = ExtResource("5_ojpbf") +variation_embolden = 0.5 + +[node name="PlayMenu" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("1_cckds") +script = ExtResource("2_phxx0") +support_anim = false + +[node name="side" type="PanelContainer" parent="."] +material = ExtResource("3_fsbt7") +layout_mode = 1 +anchors_preset = 9 +anchor_bottom = 1.0 +offset_right = 294.0 +grow_vertical = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_ukani") + +[node name="margin" type="MarginContainer" parent="side"] +layout_mode = 2 +theme_override_constants/margin_left = 20 +theme_override_constants/margin_top = 20 +theme_override_constants/margin_right = 20 +theme_override_constants/margin_bottom = 20 +script = ExtResource("4_gst6r") + +[node name="options" type="VBoxContainer" parent="side/margin"] +layout_mode = 2 + +[node name="title" type="Label" parent="side/margin/options"] +auto_translate_mode = 2 +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0.566408, 0.208917, 0.266045, 1) +theme_override_constants/outline_size = 10 +theme_override_fonts/font = SubResource("FontVariation_htgmg") +theme_override_font_sizes/font_size = 48 +text = "Hurry Curry!" + +[node name="spacer" type="Control" parent="side/margin/options"] +custom_minimum_size = Vector2(0, 10) +layout_mode = 2 + +[node name="second" type="VBoxContainer" parent="side/margin/options"] +layout_mode = 2 +size_flags_vertical = 3 + +[node name="Loading" type="Label" parent="side/margin/options/second"] +visible = false +layout_mode = 2 +size_flags_horizontal = 3 +text = "c.menu.play.fetching_list" +horizontal_alignment = 1 + +[node name="NoServers" type="Label" parent="side/margin/options/second"] +visible = false +layout_mode = 2 +size_flags_horizontal = 3 +text = "c.menu.play.no_servers" +horizontal_alignment = 1 + +[node name="ScrollContainerCustom" type="ScrollContainer" parent="side/margin/options/second"] +layout_mode = 2 +size_flags_vertical = 3 +horizontal_scroll_mode = 0 +script = ExtResource("5_cm120") + +[node name="ServerList" type="VBoxContainer" parent="side/margin/options/second/ScrollContainerCustom"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="spacer" type="Control" parent="side/margin/options/second"] +custom_minimum_size = Vector2(0, 10) +layout_mode = 2 + +[node name="connect" type="HBoxContainer" parent="side/margin/options/second"] +layout_mode = 2 + +[node name="uri" type="LineEdit" parent="side/margin/options/second/connect"] +auto_translate_mode = 2 +layout_mode = 2 +size_flags_horizontal = 3 +placeholder_text = "wss://example.org" + +[node name="connect" type="Button" parent="side/margin/options/second/connect"] +layout_mode = 2 +text = "c.menu.play.connect" + +[node name="server" type="HBoxContainer" parent="side/margin/options/second"] +layout_mode = 2 + +[node name="control" type="Button" parent="side/margin/options/second/server"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "c.menu.play.server" +alignment = 0 + +[node name="connect" type="Button" parent="side/margin/options/second/server"] +layout_mode = 2 +text = "c.menu.play.connect" + +[node name="editor" type="HBoxContainer" parent="side/margin/options/second"] +layout_mode = 2 + +[node name="control" type="Button" parent="side/margin/options/second/editor"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "c.menu.play.editor" +alignment = 0 + +[node name="connect" type="Button" parent="side/margin/options/second/editor"] +layout_mode = 2 +text = "c.menu.play.connect" + +[node name="spacer2" type="Control" parent="side/margin/options/second"] +custom_minimum_size = Vector2(0, 10) +layout_mode = 2 + +[node name="back" type="Button" parent="side/margin/options/second"] +layout_mode = 2 +text = "c.menu.back" +alignment = 0 + +[node name="VBoxContainer" type="VBoxContainer" parent="side/margin/options/second"] +layout_mode = 2 + +[connection signal="text_changed" from="side/margin/options/second/connect/uri" to="." method="_on_uri_text_changed"] +[connection signal="pressed" from="side/margin/options/second/connect/connect" to="." method="_on_connect_pressed"] +[connection signal="pressed" from="side/margin/options/second/server/control" to="." method="_on_server_control_pressed"] +[connection signal="pressed" from="side/margin/options/second/server/connect" to="." method="_on_server_connect_pressed"] +[connection signal="pressed" from="side/margin/options/second/editor/control" to="." method="_on_editor_control_pressed"] +[connection signal="pressed" from="side/margin/options/second/editor/connect" to="." method="_on_editor_connect_pressed"] +[connection signal="pressed" from="side/margin/options/second/back" to="." method="_on_back_pressed"] diff --git a/client/gui/menus/main/server_list_item.gd b/client/gui/menus/main/server_list_item.gd new file mode 100644 index 00000000..0cffdd72 --- /dev/null +++ b/client/gui/menus/main/server_list_item.gd @@ -0,0 +1,38 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +class_name ServerListItem +extends PanelContainer + +var error_style_focus: StyleBoxFlat = preload("res://gui/resources/style/error_focus_style.tres") +@onready var title: Label = $MarginContainer/VBoxContainer/Title +@onready var info: Label = $MarginContainer/VBoxContainer/Info +@onready var button: Button = $Button + +func setup(name_: String, online_players: int, version: Array): + title.text = name_ + if version[0] != Multiplayer.VERSION_MAJOR or version[1] > Multiplayer.VERSION_MINOR: + button.disabled = true + button.add_theme_stylebox_override("focus", error_style_focus) + info.text = tr("c.menu.play.server_version_mismatch") + info.add_theme_color_override("font_color", Color("ff2222")) + return + info.text = tr("c.menu.play.server_players").format([online_players]) + + # This node is in group not no_click_sound, so sounds won't be automatically connected + # by menu system. Reason: These nodes are deleted and re-created every few seconds + # in server list, and signals are only connected on ready. + button.pressed.connect(Sound.play_click) + button.mouse_entered.connect(Sound.play_hover) diff --git a/client/gui/menus/main/server_list_item.gd.uid b/client/gui/menus/main/server_list_item.gd.uid new file mode 100644 index 00000000..276bb06f --- /dev/null +++ b/client/gui/menus/main/server_list_item.gd.uid @@ -0,0 +1 @@ +uid://xr5oigbgd0aw diff --git a/client/gui/menus/main/server_list_item.tscn b/client/gui/menus/main/server_list_item.tscn new file mode 100644 index 00000000..40e9eedb --- /dev/null +++ b/client/gui/menus/main/server_list_item.tscn @@ -0,0 +1,39 @@ +[gd_scene load_steps=3 format=3 uid="uid://t2h60dhuvfsk"] + +[ext_resource type="Script" uid="uid://xr5oigbgd0aw" path="res://gui/menus/main/server_list_item.gd" id="1_1n1yg"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_1n1yg"] + +[node name="ServerListItem" type="PanelContainer"] +offset_right = 400.0 +offset_bottom = 40.0 +size_flags_horizontal = 3 +theme_override_styles/panel = SubResource("StyleBoxEmpty_1n1yg") +script = ExtResource("1_1n1yg") + +[node name="Button" type="Button" parent="." groups=["no_click_sound"]] +layout_mode = 2 + +[node name="MarginContainer" type="MarginContainer" parent="."] +layout_mode = 2 +mouse_filter = 2 +theme_override_constants/margin_left = 10 +theme_override_constants/margin_top = 10 +theme_override_constants/margin_right = 10 +theme_override_constants/margin_bottom = 10 + +[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"] +layout_mode = 2 +mouse_filter = 2 + +[node name="Title" type="Label" parent="MarginContainer/VBoxContainer"] +layout_mode = 2 +theme_override_colors/font_color = Color(0.87451, 0.87451, 0.87451, 1) +theme_override_font_sizes/font_size = 18 +text = "Example Server" + +[node name="Info" type="Label" parent="MarginContainer/VBoxContainer"] +layout_mode = 2 +theme_override_colors/font_color = Color(0.749781, 0.74978, 0.74978, 1) +theme_override_font_sizes/font_size = 14 +text = "5 players online" diff --git a/client/gui/menus/menu.gd b/client/gui/menus/menu.gd new file mode 100644 index 00000000..0f6e0624 --- /dev/null +++ b/client/gui/menus/menu.gd @@ -0,0 +1,151 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +class_name Menu +extends Control + + +#enum Anim { NONE, FADE } +#@export var animation: Anim = Anim.NONE +@export var support_anim := true +@export var auto_anim := true + +var data + +signal submenu_close() + +const transition_scene = preload("res://gui/menus/transition/scene_transition.tscn") +var transition: SceneTransition +var parent_menu: Menu = null +var previous_path = null # : String +var open_since = 0 + +func _ready(): + open_since = Time.get_ticks_msec() + Global.focused_menu = self + focus_first(self) + connect_button_sounds(self) + disable_context_menus(self) + update_parent_menu(self.get_parent()) + if support_anim: anim_setup() + if auto_anim: _menu_open() + get_tree().get_root().go_back_requested.connect(exit_maybe) + +func anim_setup(): + transition = transition_scene.instantiate() + add_child(transition) +func _menu_open(): + if transition != null: await transition.fade_in() +func _menu_exit(): + if transition != null: await transition.fade_out() +func _menu_cover(_state: bool): + pass + +var popup: Menu = null +var covered := false +func submenu(path: String, data_ = null): + var prev_focus = Global.focused_node + if popup != null: return + _disable_recursive(self, true) + covered = true + await _menu_cover(true) + popup = load(path).instantiate() + popup.data = data_ + add_child(popup) + print("Submenu opened ", path) + await submenu_close + print("Submenu closed ", path) + await _menu_cover(false) + covered = false + Global.focused_menu = self + _disable_recursive(self, false) + if prev_focus != null: prev_focus.grab_focus() + +func _disable_recursive(node: Node, state: bool): + if node is BaseButton: + if state and node.disabled: node.add_to_group("was_disabled") + else: node.remove_from_group("was_disabled") + node.disabled = state or node.is_in_group("was_disabled") + for c in node.get_children(): _disable_recursive(c, state) + +func exit(): + await self._menu_exit() + if previous_path != null: + replace_menu(previous_path) + else: + get_parent().submenu_close.emit() + queue_free() + +func quit(): + await exit() + get_parent().quit() + +func replace_menu(path: String, data_ = null, prev_path = null): # prev_path: String? + print("Replace menu: ", path) + if popup != null: await popup.exit() + _disable_recursive(self, true) + await _menu_exit() + var new_popup: Menu = load(path).instantiate() + new_popup.data = data_ + if prev_path != null: new_popup.previous_path = prev_path + get_parent().add_child(new_popup) + if parent_menu != null: parent_menu.popup = new_popup + queue_free() + +var focus_auto_changed := false +func focus_first(node: Node) -> bool: + focus_auto_changed = true + if node.is_in_group("no_auto_focus"): + return false + if node is Button or node.is_in_group("autoselect"): + node.grab_focus() + print("Node %s (%s) was selected for focus" % [node.name, node]) + return true + for c in node.get_children(): + if focus_first(c): + return true + return false + +func connect_button_sounds(node: Node): + if node is Button or node is TextureButton: + if not node.is_in_group("no_click_sound"): + node.pressed.connect(Sound.play_click) + if (node is Button and not node.disabled) or (node is LineEdit and node.editable) or node is Slider: + if not node.is_in_group("no_click_sound"): + node.mouse_entered.connect(Sound.play_hover) + for c in node.get_children(): + connect_button_sounds(c) + +func disable_context_menus(node: Node): + if node is LineEdit: + node.context_menu_enabled = false + for c in node.get_children(): + disable_context_menus(c) + +func update_parent_menu(node: Node): + if node is Menu: parent_menu = node + elif node.get_parent() != null: update_parent_menu(node.get_parent()) + +func _input(_event): + if Input.is_action_just_pressed("menu"): + exit_maybe() + +func exit_maybe() -> void: + # Exit menu if all conditions are met + if popup != null: return + var time := Time.get_ticks_msec() + if time - open_since < 100: return + Sound.play_click() + exit() diff --git a/client/gui/menus/menu.gd.uid b/client/gui/menus/menu.gd.uid new file mode 100644 index 00000000..5711a6e0 --- /dev/null +++ b/client/gui/menus/menu.gd.uid @@ -0,0 +1 @@ +uid://d2h2q16vykpl4 diff --git a/client/gui/menus/popup.gd b/client/gui/menus/popup.gd new file mode 100644 index 00000000..d4849e92 --- /dev/null +++ b/client/gui/menus/popup.gd @@ -0,0 +1,32 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends Menu +class_name MenuPopup + +@onready var message := $MarginContainer/CenterContainer/Panel/MarginContainer/VBoxContainer/Message +@onready var button_container := $MarginContainer/CenterContainer/Panel/MarginContainer/VBoxContainer/HBoxContainer + +class Data: + var buttons: Array[Button] + var text: String + +func _ready(): + var setup: Data = self.data + for i in setup.buttons: + button_container.add_child(i) + i.pressed.connect(exit) + message.text = setup.text + super() diff --git a/client/gui/menus/popup.gd.uid b/client/gui/menus/popup.gd.uid new file mode 100644 index 00000000..4800ca4d --- /dev/null +++ b/client/gui/menus/popup.gd.uid @@ -0,0 +1 @@ +uid://bevyiytj5tawr diff --git a/client/gui/menus/popup.tscn b/client/gui/menus/popup.tscn new file mode 100644 index 00000000..13137ccb --- /dev/null +++ b/client/gui/menus/popup.tscn @@ -0,0 +1,52 @@ +[gd_scene load_steps=6 format=3 uid="uid://lwtym0pbc17g"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_m0d0r"] +[ext_resource type="Script" uid="uid://bevyiytj5tawr" path="res://gui/menus/popup.gd" id="2_1h10j"] +[ext_resource type="Material" uid="uid://beea1pc5nt67r" path="res://gui/resources/materials/dark_blur_material.tres" id="3_iouvy"] +[ext_resource type="Script" uid="uid://byshs20og68tn" path="res://gui/components/smart_margin_container.gd" id="3_j0ajn"] +[ext_resource type="Script" uid="uid://cmncjc06kadpe" path="res://gui/components/blur_setup.gd" id="4_e4iqk"] + +[node name="Popup" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("1_m0d0r") +script = ExtResource("2_1h10j") +support_anim = false + +[node name="MarginContainer" type="MarginContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("3_j0ajn") + +[node name="CenterContainer" type="CenterContainer" parent="MarginContainer"] +layout_mode = 2 + +[node name="Panel" type="PanelContainer" parent="MarginContainer/CenterContainer"] +material = ExtResource("3_iouvy") +layout_mode = 2 +script = ExtResource("4_e4iqk") + +[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/CenterContainer/Panel"] +layout_mode = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/CenterContainer/Panel/MarginContainer"] +layout_mode = 2 +theme_override_constants/separation = 16 + +[node name="Message" type="Label" parent="MarginContainer/CenterContainer/Panel/MarginContainer/VBoxContainer"] +custom_minimum_size = Vector2(400, 0) +layout_mode = 2 +horizontal_alignment = 1 +autowrap_mode = 3 + +[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/CenterContainer/Panel/MarginContainer/VBoxContainer"] +layout_mode = 2 +alignment = 1 diff --git a/client/gui/menus/popup_large.gd b/client/gui/menus/popup_large.gd new file mode 100644 index 00000000..909ee4c0 --- /dev/null +++ b/client/gui/menus/popup_large.gd @@ -0,0 +1,25 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends Menu + +@onready var label = $OuterMargin/Panel/InnerMargin/Vert/ScrollContainer/CreditsText + +func _ready(): + super() + label.text = data + +func _on_back_pressed(): + exit() diff --git a/client/gui/menus/popup_large.gd.uid b/client/gui/menus/popup_large.gd.uid new file mode 100644 index 00000000..aef2a852 --- /dev/null +++ b/client/gui/menus/popup_large.gd.uid @@ -0,0 +1 @@ +uid://c3eimx76ucpsp diff --git a/client/gui/menus/popup_large.tscn b/client/gui/menus/popup_large.tscn new file mode 100644 index 00000000..993dde9d --- /dev/null +++ b/client/gui/menus/popup_large.tscn @@ -0,0 +1,74 @@ +[gd_scene load_steps=7 format=3 uid="uid://7mqbxa054bjv"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_kabr3"] +[ext_resource type="Script" uid="uid://c3eimx76ucpsp" path="res://gui/menus/popup_large.gd" id="2_m0b5d"] +[ext_resource type="Script" uid="uid://byshs20og68tn" path="res://gui/components/smart_margin_container.gd" id="3_36vhf"] +[ext_resource type="Material" uid="uid://beea1pc5nt67r" path="res://gui/resources/materials/dark_blur_material.tres" id="4_8ybj3"] +[ext_resource type="Script" uid="uid://cmncjc06kadpe" path="res://gui/components/blur_setup.gd" id="5_63jf0"] +[ext_resource type="Script" uid="uid://bd7bylb2t2m0" path="res://gui/components/touch_scroll_container.gd" id="6_smk7v"] + +[node name="CreditsMenu" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("1_kabr3") +script = ExtResource("2_m0b5d") +support_anim = false + +[node name="OuterMargin" type="MarginContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("3_36vhf") + +[node name="Panel" type="Panel" parent="OuterMargin"] +material = ExtResource("4_8ybj3") +layout_mode = 2 +script = ExtResource("5_63jf0") + +[node name="InnerMargin" type="MarginContainer" parent="OuterMargin/Panel"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_constants/margin_left = 50 +theme_override_constants/margin_top = 50 +theme_override_constants/margin_right = 50 +theme_override_constants/margin_bottom = 50 + +[node name="Vert" type="VBoxContainer" parent="OuterMargin/Panel/InnerMargin"] +layout_mode = 2 + +[node name="ScrollContainer" type="ScrollContainer" parent="OuterMargin/Panel/InnerMargin/Vert"] +layout_mode = 2 +size_flags_vertical = 3 +script = ExtResource("6_smk7v") + +[node name="CreditsText" type="RichTextLabel" parent="OuterMargin/Panel/InnerMargin/Vert/ScrollContainer"] +auto_translate_mode = 2 +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +theme_override_constants/table_h_separation = 25 +theme_override_font_sizes/bold_italics_font_size = 22 +theme_override_font_sizes/italics_font_size = 22 +theme_override_font_sizes/mono_font_size = 22 +theme_override_font_sizes/normal_font_size = 22 +theme_override_font_sizes/bold_font_size = 22 +bbcode_enabled = true +fit_content = true +scroll_active = false + +[node name="back" type="Button" parent="OuterMargin/Panel/InnerMargin/Vert"] +layout_mode = 2 +text = "c.menu.back" + +[connection signal="pressed" from="OuterMargin/Panel/InnerMargin/Vert/back" to="." method="_on_back_pressed"] diff --git a/client/gui/menus/rating/desaturate.gdshader b/client/gui/menus/rating/desaturate.gdshader new file mode 100644 index 00000000..e6861560 --- /dev/null +++ b/client/gui/menus/rating/desaturate.gdshader @@ -0,0 +1,7 @@ +shader_type canvas_item; + +uniform float t : hint_range(0.0, 1.0); + +void fragment() { + COLOR.rgb = mix(vec3(pow((COLOR.r+COLOR.g+COLOR.b)/3.,3.)),COLOR.rgb,t); +} diff --git a/client/gui/menus/rating/desaturate.gdshader.uid b/client/gui/menus/rating/desaturate.gdshader.uid new file mode 100644 index 00000000..621837a6 --- /dev/null +++ b/client/gui/menus/rating/desaturate.gdshader.uid @@ -0,0 +1 @@ +uid://cekkkqsvd7rvw diff --git a/client/gui/menus/rating/rating.gd b/client/gui/menus/rating/rating.gd new file mode 100644 index 00000000..023c1333 --- /dev/null +++ b/client/gui/menus/rating/rating.gd @@ -0,0 +1,65 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends Menu + +const PARTICLE_AMOUNTS = [1, 6, 32, 128] + +@onready var game: Game = $"../Game" +@onready var title: Label = $MarginContainer/PanelContainer/VBoxContainer/Text/Title +@onready var subtitle: Label = $MarginContainer/PanelContainer/VBoxContainer/Text/Subtitle +@onready var stars = $MarginContainer/PanelContainer/VBoxContainer/Stars.get_children() +@onready var star_timer = $StarTimer +@onready var particles = $Control/Particles +@onready var close_button: Button = $MarginContainer/PanelContainer/VBoxContainer/HBoxContainer/Close + +func _ready(): + super() + show_rating(data[0], data[1]) + close_button.disabled = true # Disable for short time period to prevent accidental button press + +func _process(_delta): + particles.emission_rect_extents = get_viewport_rect().size * Vector2(0.5, 0.5) + +func show_rating(stars_: int, points: int): + match stars_: + 0: title.text = tr("c.score.poor") + 1: title.text = tr("c.score.acceptable") + 2: title.text = tr("c.score.good") + 3: title.text = tr("c.score.excellent") + + subtitle.text = tr("c.score.points_par").format([points]) + + for i in range(0, stars_): + var star: TextureRect = stars[i] + star_timer.start() + await star_timer.timeout + star.material.set_shader_parameter("t", 1) + star.get_node("Sound").play() + + particles.amount = PARTICLE_AMOUNTS[stars_] + + if stars_ > 1: + particles.emitting = true + +func _on_close_pressed(): + exit() + +func _on_button_timer_timeout() -> void: + close_button.disabled = false + +func _on_scoreboard_pressed() -> void: + exit() + game.mp.send_chat(game.my_player_id, "/scoreboard %s" % Global.last_map_name) diff --git a/client/gui/menus/rating/rating.gd.uid b/client/gui/menus/rating/rating.gd.uid new file mode 100644 index 00000000..fd729d8f --- /dev/null +++ b/client/gui/menus/rating/rating.gd.uid @@ -0,0 +1 @@ +uid://5tmklxkaa6e0 diff --git a/client/gui/menus/rating/rating.tscn b/client/gui/menus/rating/rating.tscn new file mode 100644 index 00000000..062dcca2 --- /dev/null +++ b/client/gui/menus/rating/rating.tscn @@ -0,0 +1,168 @@ +[gd_scene load_steps=12 format=3 uid="uid://buu3cdpigs8qq"] + +[ext_resource type="Texture2D" uid="uid://b10goh4dsa3b0" path="res://player/particles/satisfied/star.webp" id="1_7qv7r"] +[ext_resource type="Shader" uid="uid://cekkkqsvd7rvw" path="res://gui/menus/rating/desaturate.gdshader" id="1_pddsm"] +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_uwajf"] +[ext_resource type="Script" uid="uid://5tmklxkaa6e0" path="res://gui/menus/rating/rating.gd" id="2_cq0se"] +[ext_resource type="Material" uid="uid://beea1pc5nt67r" path="res://gui/resources/materials/dark_blur_material.tres" id="4_hdurb"] +[ext_resource type="AudioStream" uid="uid://camy77x26mmpv" path="res://gui/resources/sounds/success.ogg" id="5_tutpj"] + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_oi7xd"] +shader = ExtResource("1_pddsm") +shader_parameter/t = 0.0 + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_ney6s"] +shader = ExtResource("1_pddsm") +shader_parameter/t = 0.0 + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_27tx1"] +shader = ExtResource("1_pddsm") +shader_parameter/t = 0.0 + +[sub_resource type="Curve" id="Curve_dqga7"] +_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.0954774, 1), 0.262418, 0.0, 0, 0] +point_count = 2 + +[sub_resource type="Gradient" id="Gradient_majwe"] +offsets = PackedFloat32Array(0, 0.0584795, 1) +colors = PackedColorArray(1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0) + +[node name="Rating" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("1_uwajf") +script = ExtResource("2_cq0se") +support_anim = false + +[node name="MarginContainer" type="MarginContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_constants/margin_left = 128 +theme_override_constants/margin_top = 64 +theme_override_constants/margin_right = 128 +theme_override_constants/margin_bottom = 64 + +[node name="PanelContainer" type="PanelContainer" parent="MarginContainer"] +material = ExtResource("4_hdurb") +layout_mode = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/PanelContainer"] +layout_mode = 2 +theme_override_constants/separation = 64 +alignment = 1 + +[node name="Text" type="VBoxContainer" parent="MarginContainer/PanelContainer/VBoxContainer"] +layout_mode = 2 + +[node name="Title" type="Label" parent="MarginContainer/PanelContainer/VBoxContainer/Text"] +layout_mode = 2 +theme_override_font_sizes/font_size = 48 +text = "Title here" +horizontal_alignment = 1 + +[node name="Subtitle" type="Label" parent="MarginContainer/PanelContainer/VBoxContainer/Text"] +layout_mode = 2 +theme_override_font_sizes/font_size = 24 +text = "Subtitle here" +horizontal_alignment = 1 + +[node name="Stars" type="HBoxContainer" parent="MarginContainer/PanelContainer/VBoxContainer"] +layout_mode = 2 +alignment = 1 + +[node name="Star1" type="TextureRect" parent="MarginContainer/PanelContainer/VBoxContainer/Stars"] +material = SubResource("ShaderMaterial_oi7xd") +custom_minimum_size = Vector2(128, 128) +layout_mode = 2 +texture = ExtResource("1_7qv7r") +expand_mode = 1 +stretch_mode = 5 + +[node name="Sound" type="AudioStreamPlayer" parent="MarginContainer/PanelContainer/VBoxContainer/Stars/Star1"] +stream = ExtResource("5_tutpj") +pitch_scale = 1.5 + +[node name="Star2" type="TextureRect" parent="MarginContainer/PanelContainer/VBoxContainer/Stars"] +material = SubResource("ShaderMaterial_ney6s") +custom_minimum_size = Vector2(128, 128) +layout_mode = 2 +texture = ExtResource("1_7qv7r") +expand_mode = 1 +stretch_mode = 5 + +[node name="Sound" type="AudioStreamPlayer" parent="MarginContainer/PanelContainer/VBoxContainer/Stars/Star2"] +stream = ExtResource("5_tutpj") +pitch_scale = 1.65 + +[node name="Star3" type="TextureRect" parent="MarginContainer/PanelContainer/VBoxContainer/Stars"] +material = SubResource("ShaderMaterial_27tx1") +custom_minimum_size = Vector2(128, 128) +layout_mode = 2 +texture = ExtResource("1_7qv7r") +expand_mode = 1 +stretch_mode = 5 + +[node name="Sound" type="AudioStreamPlayer" parent="MarginContainer/PanelContainer/VBoxContainer/Stars/Star3"] +stream = ExtResource("5_tutpj") +pitch_scale = 1.9 + +[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/PanelContainer/VBoxContainer"] +layout_mode = 2 +theme_override_constants/separation = 64 +alignment = 1 + +[node name="Scoreboard" type="Button" parent="MarginContainer/PanelContainer/VBoxContainer/HBoxContainer"] +layout_mode = 2 +text = "c.menu.scoreboard.button" + +[node name="Close" type="Button" parent="MarginContainer/PanelContainer/VBoxContainer/HBoxContainer"] +layout_mode = 2 +text = "c.menu.accept" + +[node name="StarTimer" type="Timer" parent="."] +wait_time = 0.5 +one_shot = true + +[node name="ButtonTimer" type="Timer" parent="."] +one_shot = true +autostart = true + +[node name="Control" type="Control" parent="."] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="Particles" type="CPUParticles2D" parent="Control"] +emitting = false +amount = 32 +texture = ExtResource("1_7qv7r") +emission_shape = 3 +emission_rect_extents = Vector2(512, 256) +direction = Vector2(0, -1) +initial_velocity_min = 256.0 +initial_velocity_max = 256.0 +angular_velocity_min = -30.0 +angular_velocity_max = 30.0 +angle_min = -20.0 +angle_max = 20.0 +scale_amount_min = 0.1 +scale_amount_max = 0.2 +scale_amount_curve = SubResource("Curve_dqga7") +color_ramp = SubResource("Gradient_majwe") + +[connection signal="pressed" from="MarginContainer/PanelContainer/VBoxContainer/HBoxContainer/Scoreboard" to="." method="_on_scoreboard_pressed"] +[connection signal="pressed" from="MarginContainer/PanelContainer/VBoxContainer/HBoxContainer/Close" to="." method="_on_close_pressed"] +[connection signal="timeout" from="ButtonTimer" to="." method="_on_button_timer_timeout"] diff --git a/client/gui/menus/settings/button_setting.gd b/client/gui/menus/settings/button_setting.gd new file mode 100644 index 00000000..fff8c184 --- /dev/null +++ b/client/gui/menus/settings/button_setting.gd @@ -0,0 +1,30 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +class_name ButtonSetting +extends GameSetting + +var callback + +func _init(new_id: String, new_default, callback_): + callback = callback_ + super (new_id, new_default) + +func create_row(): + var row = super () + row.value_node = Button.new() + row.value_node.text = tr(nskey + ".button_label") + row.value_node.pressed.connect(callback) + return row diff --git a/client/gui/menus/settings/button_setting.gd.uid b/client/gui/menus/settings/button_setting.gd.uid new file mode 100644 index 00000000..cf0a8d95 --- /dev/null +++ b/client/gui/menus/settings/button_setting.gd.uid @@ -0,0 +1 @@ +uid://dku75bw31ux1k diff --git a/client/gui/menus/settings/dropdown_setting.gd b/client/gui/menus/settings/dropdown_setting.gd new file mode 100644 index 00000000..514df666 --- /dev/null +++ b/client/gui/menus/settings/dropdown_setting.gd @@ -0,0 +1,36 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +class_name DropdownSetting +extends GameSetting + +var options: Array + +func _init(new_id: String, new_default, new_options: Array): + super(new_id, new_default) + options = new_options + +func create_row(): + var row = super() + row.value_node = OptionButton.new() + row.value_node.clip_text = true + for i in options: row.value_node.add_item(tr(nskey + "." + i)) + Settings.hook_changed_init(key, true, + func(value): + if is_instance_valid(row): + row.value_node.select(options.find(value)) + ) + row.value_node.item_selected.connect(func(item): Global.set_setting(key, options[item])) + return row diff --git a/client/gui/menus/settings/dropdown_setting.gd.uid b/client/gui/menus/settings/dropdown_setting.gd.uid new file mode 100644 index 00000000..409bf3ab --- /dev/null +++ b/client/gui/menus/settings/dropdown_setting.gd.uid @@ -0,0 +1 @@ +uid://cjqswo4mwbvon diff --git a/client/gui/menus/settings/game_setting.gd b/client/gui/menus/settings/game_setting.gd new file mode 100644 index 00000000..1c04ad3b --- /dev/null +++ b/client/gui/menus/settings/game_setting.gd @@ -0,0 +1,46 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +class_name GameSetting +extends Object + +var default +var key: String +var nskey: String + +func _init(new_id: String, new_default = null): + default = new_default + key = new_id + +func set_parent(parent: GameSetting): + if parent != null: key = parent.key + "." + key + nskey = "c.settings." + key + +func create_row(): + var row = preload("res://gui/menus/settings/settings_row.tscn").instantiate() + row.description = tr(nskey) + row.reset.connect(func(): Global.set_setting(key, default)) + return row + +func check(): + if default != null: + if not key in Global.settings: + Global.set_setting_unchecked(key, default) + if typeof(default) != typeof(Global.settings[key]): + Global.set_setting_unchecked(key, default) + +func changed_keys(): + if Global.get_setting(key) != default: return [key] + else: return [] diff --git a/client/gui/menus/settings/game_setting.gd.uid b/client/gui/menus/settings/game_setting.gd.uid new file mode 100644 index 00000000..99d79bee --- /dev/null +++ b/client/gui/menus/settings/game_setting.gd.uid @@ -0,0 +1 @@ +uid://cyy8l32i44l63 diff --git a/client/gui/menus/settings/input/input_manager.gd b/client/gui/menus/settings/input/input_manager.gd new file mode 100644 index 00000000..e3158a03 --- /dev/null +++ b/client/gui/menus/settings/input/input_manager.gd @@ -0,0 +1,101 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends Node + +enum EventType { + KEYBOARD, + JOYPAD, + TOUCH, + OTHER +} + +var default_input_map = {} +var input_map: Dictionary + +func _init(): + default_input_map = get_input_map() + input_map = default_input_map.duplicate(true) + +func get_input_map() -> Dictionary: + var actions = InputMap.get_actions().filter(func isBuiltIn(k: String): return !k.begins_with("ui_")) + var kb = {} + for a in actions: + var input_events: Array[InputEvent] = InputMap.action_get_events(a).duplicate(true) + kb[a] = input_events + return kb + +func get_events(action_name: String) -> Array: + if not input_map.has(action_name): + push_error("Tried to get action %s in input map which does not exist" % action_name) + return [] + return input_map[action_name] + +func settings() -> Array: + var entries := [] + for k in input_map.keys(): entries.append(InputSetting.new(k)) + return entries + +func change_input_map_action(action_name: String, events: Array, save: bool = true): + if !InputMap.has_action(action_name): + push_error("Action %s does not exist" % action_name, false) + return + # Erase previous keybindings + InputMap.action_erase_events(action_name) + # Add new keybindings + for e in events: + InputMap.action_add_event(action_name, e) + + if save: + # Update input map dictionary + input_map = get_input_map() + # Save settings + Global.set_setting("input_map", input_map.duplicate(true)) + +func apply_input_map(new_input_map: Dictionary): + # Load into input map dictionary + for k in new_input_map.keys(): + input_map[k] = [] + for a in new_input_map[k]: + input_map[k].append(a) + + # Apply keybindings + for k in input_map.keys(): + change_input_map_action(k, input_map[k], false) + +func reset_input_map(): + Global.set_setting("input_map", default_input_map.duplicate()) + apply_input_map(Global.get_setting("input_map")) + +func get_event_type(input_event: InputEvent) -> EventType: + if input_event is InputEventKey or input_event is InputEventMouseButton: + return EventType.KEYBOARD + elif input_event is InputEventJoypadButton or input_event is InputEventJoypadMotion: + return EventType.JOYPAD + elif input_event is InputEventScreenTouch or input_event is InputEventScreenDrag: + return EventType.TOUCH + return EventType.OTHER + +func display_input_event(input_event: InputEvent) -> String: + if input_event is InputEventKey: + return tr("c.settings.input.keyboard").format([OS.get_keycode_string(input_event.physical_keycode)]) + elif input_event is InputEventMouseButton: + return tr("c.settings.input.mouse_button").format([input_event.button_index]) + elif input_event is InputEventJoypadButton: + return tr("c.settings.input.joypad").format([input_event.button_index]) + elif input_event is InputEventJoypadMotion: + return tr("c.settings.input.joypad_axis").format([input_event.axis]) + else: + return tr("c.settings.input.other_event") diff --git a/client/gui/menus/settings/input/input_manager.gd.uid b/client/gui/menus/settings/input/input_manager.gd.uid new file mode 100644 index 00000000..678c2192 --- /dev/null +++ b/client/gui/menus/settings/input/input_manager.gd.uid @@ -0,0 +1 @@ +uid://bfu78iwybbu2s diff --git a/client/gui/menus/settings/input/input_setting.gd b/client/gui/menus/settings/input/input_setting.gd new file mode 100644 index 00000000..fa903771 --- /dev/null +++ b/client/gui/menus/settings/input/input_setting.gd @@ -0,0 +1,39 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +class_name InputSetting +extends GameSetting + +const INPUT_VALUE_NODE_SCENE = preload("res://gui/menus/settings/input/input_value_node.tscn") + +func _init(new_id: String): + super(new_id) + default = InputManager.default_input_map[new_id] + +func create_row(): + var row = super() + row.value_node = INPUT_VALUE_NODE_SCENE.instantiate() + Settings.hook_changed_init(key, true, + func(value): + if is_instance_valid(row): + row.value_node.value = value + ) + row.value_node.changed.connect(func(): Global.set_setting(key, row.value_node.value)) + return row + +func changed_keys(): + return [key] + # if Global.array_eq(Global.get_setting(key), default): return [key] + # else: return [] diff --git a/client/gui/menus/settings/input/input_setting.gd.uid b/client/gui/menus/settings/input/input_setting.gd.uid new file mode 100644 index 00000000..7866fc2f --- /dev/null +++ b/client/gui/menus/settings/input/input_setting.gd.uid @@ -0,0 +1 @@ +uid://d2xwn2u4ycpe8 diff --git a/client/gui/menus/settings/input/input_value_node.gd b/client/gui/menus/settings/input/input_value_node.gd new file mode 100644 index 00000000..7c718e25 --- /dev/null +++ b/client/gui/menus/settings/input/input_value_node.gd @@ -0,0 +1,74 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends VBoxContainer +class_name InputValueNode + +var value: Array[InputEvent] = [] +var listening := false + +signal changed() + +@onready var actions_container: VBoxContainer = $ActionsContainer +@onready var add_button: Button = $Add +@onready var add_text = add_button.text + +func _ready(): + update() + +func update(fix_focus: bool = false): + for c in actions_container.get_children(): + c.queue_free() + + for e: InputEvent in value: + var description: String = InputManager.display_input_event(e) + var button := Button.new() + + button.text = description + button.pressed.connect(erase_event.bind(e)) + actions_container.add_child(button) + + if fix_focus: + add_button.grab_focus() + +func erase_event(e: InputEvent): + value.erase(e) + update(true) + changed.emit() + +func _input(e: InputEvent): + if listening: + if e is InputEventKey or e is InputEventMouseButton or e is InputEventJoypadButton or e is InputEventJoypadMotion: + # Check if key was already added + for e2 in value: + if events_equal(e, e2): return + + value.append(e) + _on_add_pressed() + update() + changed.emit() + +func events_equal(e1: InputEvent, e2: InputEvent) -> bool: + if e1 is InputEventKey and e2 is InputEventKey: + return e1.physical_keycode == e2.physical_keycode + if (e1 is InputEventMouseButton and e2 is InputEventMouseButton) or (e1 is InputEventJoypadButton and e2 is InputEventJoypadButton): + return e1.button_index == e2.button_index + if e1 is InputEventJoypadMotion and e2 is InputEventJoypadMotion: + return e1.axis == e2.axis + return false + +func _on_add_pressed() -> void: + listening = not listening + add_button.text = tr("c.settings.input.press_any_key") if listening else add_text diff --git a/client/gui/menus/settings/input/input_value_node.gd.uid b/client/gui/menus/settings/input/input_value_node.gd.uid new file mode 100644 index 00000000..3669b991 --- /dev/null +++ b/client/gui/menus/settings/input/input_value_node.gd.uid @@ -0,0 +1 @@ +uid://ckb78voiq05e3 diff --git a/client/gui/menus/settings/input/input_value_node.tscn b/client/gui/menus/settings/input/input_value_node.tscn new file mode 100644 index 00000000..1b2e89c4 --- /dev/null +++ b/client/gui/menus/settings/input/input_value_node.tscn @@ -0,0 +1,24 @@ +[gd_scene load_steps=3 format=3 uid="uid://c6r0nv5daq7wc"] + +[ext_resource type="Script" uid="uid://ckb78voiq05e3" path="res://gui/menus/settings/input/input_value_node.gd" id="1_snxax"] +[ext_resource type="Texture2D" uid="uid://cnfjbowd2i02r" path="res://gui/resources/icons/plus.svg" id="2_3vlvc"] + +[node name="InputValueNode" type="VBoxContainer"] +offset_right = 128.0 +offset_bottom = 31.0 +theme_override_constants/separation = 0 +script = ExtResource("1_snxax") + +[node name="ActionsContainer" type="VBoxContainer" parent="."] +layout_mode = 2 +theme_override_constants/separation = 0 + +[node name="Add" type="Button" parent="."] +custom_minimum_size = Vector2(128, 0) +layout_mode = 2 +size_flags_vertical = 3 +text = "c.settings.input.add" +icon = ExtResource("2_3vlvc") +expand_icon = true + +[connection signal="pressed" from="Add" to="." method="_on_add_pressed"] diff --git a/client/gui/menus/settings/number_setting.gd b/client/gui/menus/settings/number_setting.gd new file mode 100644 index 00000000..5fa5a115 --- /dev/null +++ b/client/gui/menus/settings/number_setting.gd @@ -0,0 +1,41 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +class_name NumberSetting +extends GameSetting + +var placeholder: String +var min_value: int +var max_value: int + +func _init(new_id: String, new_default: int, new_min_value: int, new_max_value: int): + super(new_id, new_default) + min_value = new_min_value + max_value = new_max_value + +func create_row(): + var row = super() + var input := SpinBox.new() + input.min_value = min_value + input.max_value = max_value + + input.value_changed.connect(func(value): Global.set_setting(key, value as int)) + Settings.hook_changed_init(key, true, + func(v): + if is_instance_valid(input): + input.value = v + ) + row.value_node = input + return row diff --git a/client/gui/menus/settings/number_setting.gd.uid b/client/gui/menus/settings/number_setting.gd.uid new file mode 100644 index 00000000..4301c642 --- /dev/null +++ b/client/gui/menus/settings/number_setting.gd.uid @@ -0,0 +1 @@ +uid://babmw2ohuhmuk diff --git a/client/gui/menus/settings/path_setting.gd b/client/gui/menus/settings/path_setting.gd new file mode 100644 index 00000000..37492ed7 --- /dev/null +++ b/client/gui/menus/settings/path_setting.gd @@ -0,0 +1,64 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +class_name PathSetting +extends TextSetting + +var select_file_icon: Texture2D = preload("res://gui/resources/icons/select_file.svg") +var select_dir_icon: Texture2D = preload("res://gui/resources/icons/select_directory.svg") + +var access: FileDialog.Access +var file_mode: FileDialog.FileMode + +func _init(new_id: String, + new_default: String, + new_file_mode: FileDialog.FileMode, + new_placeholder: String = "", + new_access: FileDialog.Access = FileDialog.Access.ACCESS_FILESYSTEM +): + super(new_id, new_default) + placeholder = new_placeholder + access = new_access + file_mode = new_file_mode + +func create_row(): + var row = super () + var input: LineEdit = row.value_node; + input.size_flags_horizontal = Control.SIZE_EXPAND_FILL + row.value_node = HBoxContainer.new() + row.value_node.add_child(input) + var button := Button.new() + button.icon = select_file_icon if file_mode == FileDialog.FileMode.FILE_MODE_OPEN_FILE else select_dir_icon + row.value_node.add_child(button) + button.pressed.connect(func(): + var d := FileDialog.new() + Global.focused_menu.add_child(d) + d.move_to_center() + d.use_native_dialog = true + d.borderless = true + d.dir_selected.connect(_selected.bind(input)) + d.file_selected.connect(_selected.bind(input)) + d.file_mode = file_mode + d.access = access + d.show() + # this feels wrong + d.canceled.connect(d.queue_free) + d.confirmed.connect(d.queue_free) + ) + return row + +func _selected(path: String, input: LineEdit): + input.text = path + input.text_changed.emit(path) diff --git a/client/gui/menus/settings/path_setting.gd.uid b/client/gui/menus/settings/path_setting.gd.uid new file mode 100644 index 00000000..a524b17c --- /dev/null +++ b/client/gui/menus/settings/path_setting.gd.uid @@ -0,0 +1 @@ +uid://cj5jf7t771j5b diff --git a/client/gui/menus/settings/preset_row.gd b/client/gui/menus/settings/preset_row.gd new file mode 100644 index 00000000..f3c46a26 --- /dev/null +++ b/client/gui/menus/settings/preset_row.gd @@ -0,0 +1,46 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +class_name PresetRow +extends GameSetting + +var options: Dictionary +var arr: Array[Button] + +func _init(id: String, options_: Dictionary): + super(id) + options = options_ + +var prefix = "" +func set_parent(parent): + super(parent) + if parent != null: prefix = parent.key + +func apply(preset_name: String): + var preset = options[preset_name] + for i in preset.keys(): + Global.set_setting(prefix + "." + i, preset[i]) + +func create_row(): + var row = super() + row.value_node = HBoxContainer.new() + for i in options.keys(): + var button := Button.new() + button.pressed.connect(apply.bind(i)) + button.text = tr(nskey + "." + i) + row.value_node.add_child(button) + return row + +func changed_keys(): return [] diff --git a/client/gui/menus/settings/preset_row.gd.uid b/client/gui/menus/settings/preset_row.gd.uid new file mode 100644 index 00000000..51605058 --- /dev/null +++ b/client/gui/menus/settings/preset_row.gd.uid @@ -0,0 +1 @@ +uid://dawqyyllgis0b diff --git a/client/gui/menus/settings/range_setting.gd b/client/gui/menus/settings/range_setting.gd new file mode 100644 index 00000000..b8d392a4 --- /dev/null +++ b/client/gui/menus/settings/range_setting.gd @@ -0,0 +1,44 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +class_name RangeSetting +extends GameSetting + +var min_value: float +var max_value: float +var tick_count +var smooth: bool + +func _init(new_id: String, new_default: float, new_min_value: float, new_max_value: float, new_smooth: bool = true, new_tick_count = null): + super(new_id, new_default) + min_value = new_min_value + max_value = new_max_value + tick_count = new_tick_count + smooth = new_smooth + +func create_row(): + var row = super() + row.value_node = HSlider.new() + row.value_node.min_value = min_value + row.value_node.max_value = max_value + row.value_node.tick_count = abs(max_value - min_value) if tick_count == null else tick_count + row.value_node.step = 0 if smooth else (1 if tick_count == null else abs(max_value - min_value) / (tick_count - 1)) + Settings.hook_changed_init(key, true, + func(value): + if is_instance_valid(row): + row.value_node.value = value + ) + row.value_node.value_changed.connect(func(value): Global.set_setting(key, value)) + return row diff --git a/client/gui/menus/settings/range_setting.gd.uid b/client/gui/menus/settings/range_setting.gd.uid new file mode 100644 index 00000000..a4ca49a2 --- /dev/null +++ b/client/gui/menus/settings/range_setting.gd.uid @@ -0,0 +1 @@ +uid://civr7cckqfndj diff --git a/client/gui/menus/settings/settings.gd b/client/gui/menus/settings/settings.gd new file mode 100644 index 00000000..32da54cc --- /dev/null +++ b/client/gui/menus/settings/settings.gd @@ -0,0 +1,40 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends Menu + +@onready var container = $OuterGap/Panel/InnerGap/VBoxContainer +@onready var outer_gap = $OuterGap + +func _ready(): + super() + var row = Global.settings_tree.create_row() + container.add_child(row) + container.move_child(row, 1) + +func _process(_dt): + var os := OS.get_name() + if os == "iOS" or os == "Android": return + # TODO probably bad performance, only update on change + var margin = max((self.size.x - 1200) / 2, 20) + outer_gap.add_theme_constant_override("margin_left", margin) + outer_gap.add_theme_constant_override("margin_right", margin) + +func _on_back_pressed(): + exit() + +func exit(): + Global.save_settings() + super() diff --git a/client/gui/menus/settings/settings.gd.uid b/client/gui/menus/settings/settings.gd.uid new file mode 100644 index 00000000..79b89b85 --- /dev/null +++ b/client/gui/menus/settings/settings.gd.uid @@ -0,0 +1 @@ +uid://bbqmsf8u5rhtn diff --git a/client/gui/menus/settings/settings.tscn b/client/gui/menus/settings/settings.tscn new file mode 100644 index 00000000..71549464 --- /dev/null +++ b/client/gui/menus/settings/settings.tscn @@ -0,0 +1,61 @@ +[gd_scene load_steps=6 format=3 uid="uid://8ic77jmadadj"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_1vjiw"] +[ext_resource type="Script" uid="uid://bbqmsf8u5rhtn" path="res://gui/menus/settings/settings.gd" id="2_5xn7x"] +[ext_resource type="Script" uid="uid://byshs20og68tn" path="res://gui/components/smart_margin_container.gd" id="3_h533i"] +[ext_resource type="Material" uid="uid://beea1pc5nt67r" path="res://gui/resources/materials/dark_blur_material.tres" id="4_b0x33"] +[ext_resource type="Script" uid="uid://cmncjc06kadpe" path="res://gui/components/blur_setup.gd" id="5_dvivs"] + +[node name="SettingsMenu" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("1_1vjiw") +script = ExtResource("2_5xn7x") +support_anim = false + +[node name="OuterGap" type="MarginContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_constants/margin_left = 80 +script = ExtResource("3_h533i") + +[node name="Panel" type="Panel" parent="OuterGap"] +material = ExtResource("4_b0x33") +layout_mode = 2 +script = ExtResource("5_dvivs") + +[node name="InnerGap" type="MarginContainer" parent="OuterGap/Panel"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_constants/margin_left = 40 +theme_override_constants/margin_top = 40 +theme_override_constants/margin_right = 40 +theme_override_constants/margin_bottom = 40 + +[node name="VBoxContainer" type="VBoxContainer" parent="OuterGap/Panel/InnerGap"] +layout_mode = 2 + +[node name="Title" type="Label" parent="OuterGap/Panel/InnerGap/VBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 0 +theme_override_font_sizes/font_size = 36 +text = "c.menu.settings" + +[node name="Back" type="Button" parent="OuterGap/Panel/InnerGap/VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 8 +text = "c.settings.apply" + +[connection signal="pressed" from="OuterGap/Panel/InnerGap/VBoxContainer/Back" to="." method="_on_back_pressed"] diff --git a/client/gui/menus/settings/settings_category.gd b/client/gui/menus/settings/settings_category.gd new file mode 100644 index 00000000..bf85abd9 --- /dev/null +++ b/client/gui/menus/settings/settings_category.gd @@ -0,0 +1,49 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +class_name SettingsCategory +extends GameSetting + +var settings: Array # Dictionary[String, GameSetting] + +func _init(new_id: String, new_settings: Array): + super(new_id) + settings = new_settings + +func set_parent(parent: GameSetting): + super(parent) + for c in settings: + c.set_parent(self) + +func create_row(): + var row = ScrollContainerCustom.new() + var options = VBoxContainer.new() + row.name = tr(nskey) + row.size_flags_horizontal = Control.SIZE_EXPAND_FILL + options.size_flags_horizontal = Control.SIZE_EXPAND_FILL + row.add_child(options) + + for r in settings: options.add_child(r.create_row()) + return row + +func check(): + for c in settings: + c.check() + +func changed_keys(): + var changed = [] + for c in settings: + changed.append_array(c.changed_keys()) + return changed diff --git a/client/gui/menus/settings/settings_category.gd.uid b/client/gui/menus/settings/settings_category.gd.uid new file mode 100644 index 00000000..421ce213 --- /dev/null +++ b/client/gui/menus/settings/settings_category.gd.uid @@ -0,0 +1 @@ +uid://b8s3cqb01w3wh diff --git a/client/gui/menus/settings/settings_root.gd b/client/gui/menus/settings/settings_root.gd new file mode 100644 index 00000000..a9a024d8 --- /dev/null +++ b/client/gui/menus/settings/settings_root.gd @@ -0,0 +1,40 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends GameSetting +class_name SettingsRoot + +var children: Array +func _init(new_children: Array): + super("root") + children = new_children + for c in children: + c.set_parent(null) + +func create_row(): + var row = TabContainer.new() + row.size_flags_vertical = Control.SIZE_EXPAND_FILL + for r in children: row.add_child(r.create_row()) + return row + +func check(): + for c in children: + c.check() + +func changed_keys(): + var changed = [] + for c in children: + changed.append_array(c.changed_keys()) + return changed diff --git a/client/gui/menus/settings/settings_root.gd.uid b/client/gui/menus/settings/settings_root.gd.uid new file mode 100644 index 00000000..95a46d5e --- /dev/null +++ b/client/gui/menus/settings/settings_root.gd.uid @@ -0,0 +1 @@ +uid://jonib2ixqsp7 diff --git a/client/gui/menus/settings/settings_row.gd b/client/gui/menus/settings/settings_row.gd new file mode 100644 index 00000000..d88d49c1 --- /dev/null +++ b/client/gui/menus/settings/settings_row.gd @@ -0,0 +1,37 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +class_name SettingsRow +extends PanelContainer + +signal reset() + +@onready var value_parent = $HBoxContainer/BoxContainer +@onready var label = $HBoxContainer/Label +@onready var reset_button = $HBoxContainer/Reset + +var value_node: Node +var description = "No value was given to the row" + +func _ready(): + if value_node != null: + var c: Control = value_node + c.size_flags_vertical = Control.SIZE_EXPAND_FILL + c.size_flags_horizontal = Control.SIZE_EXPAND_FILL + label.text = description + value_parent.add_child(c) + +func _on_reset_pressed(): + reset.emit() diff --git a/client/gui/menus/settings/settings_row.gd.uid b/client/gui/menus/settings/settings_row.gd.uid new file mode 100644 index 00000000..a6dea492 --- /dev/null +++ b/client/gui/menus/settings/settings_row.gd.uid @@ -0,0 +1 @@ +uid://b3m1f76o5qo68 diff --git a/client/gui/menus/settings/settings_row.tscn b/client/gui/menus/settings/settings_row.tscn new file mode 100644 index 00000000..09378ab6 --- /dev/null +++ b/client/gui/menus/settings/settings_row.tscn @@ -0,0 +1,40 @@ +[gd_scene load_steps=7 format=3 uid="uid://o5e5vpem8w0k"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_iij3k"] +[ext_resource type="Script" uid="uid://b3m1f76o5qo68" path="res://gui/menus/settings/settings_row.gd" id="2_l8i7p"] +[ext_resource type="FontFile" uid="uid://5ixo6b3bd3km" path="res://gui/resources/fonts/font-josefin-sans.woff2" id="3_7k5da"] +[ext_resource type="Texture2D" uid="uid://cucnmy0j5n8l8" path="res://gui/resources/icons/reset.svg" id="4_bj3dr"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_pk3rs"] +content_margin_left = 16.0 + +[sub_resource type="FontVariation" id="FontVariation_o6i7s"] +base_font = ExtResource("3_7k5da") + +[node name="SettingsRow" type="PanelContainer"] +offset_right = 105.0 +offset_bottom = 23.0 +size_flags_horizontal = 3 +theme = ExtResource("1_iij3k") +script = ExtResource("2_l8i7p") + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_mode = 2 + +[node name="Label" type="Label" parent="HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +theme_override_styles/normal = SubResource("StyleBoxEmpty_pk3rs") + +[node name="BoxContainer" type="BoxContainer" parent="HBoxContainer"] +custom_minimum_size = Vector2(300, 50) +layout_mode = 2 +alignment = 2 + +[node name="Reset" type="Button" parent="HBoxContainer"] +layout_mode = 2 +theme_override_fonts/font = SubResource("FontVariation_o6i7s") +theme_override_font_sizes/font_size = 24 +icon = ExtResource("4_bj3dr") + +[connection signal="pressed" from="HBoxContainer/Reset" to="." method="_on_reset_pressed"] diff --git a/client/gui/menus/settings/text_setting.gd b/client/gui/menus/settings/text_setting.gd new file mode 100644 index 00000000..8e2b6bec --- /dev/null +++ b/client/gui/menus/settings/text_setting.gd @@ -0,0 +1,38 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +class_name TextSetting +extends GameSetting + +var placeholder: String + +func _init(new_id: String, new_default: String, new_placeholder: String = ""): + super(new_id, new_default) + placeholder = new_placeholder + +func create_row(): + var row = super() + var input := LineEdit.new() + input.placeholder_text = placeholder + input.text_changed.connect(func(text): Global.set_setting(key, text)) + Settings.hook_changed_init(key, true, + func(text): + if is_instance_valid(input): + var pos = input.caret_column + input.text = text + input.caret_column = pos + ) + row.value_node = input + return row diff --git a/client/gui/menus/settings/text_setting.gd.uid b/client/gui/menus/settings/text_setting.gd.uid new file mode 100644 index 00000000..58ac5abe --- /dev/null +++ b/client/gui/menus/settings/text_setting.gd.uid @@ -0,0 +1 @@ +uid://3rgucgbbt135 diff --git a/client/gui/menus/settings/toggle_setting.gd b/client/gui/menus/settings/toggle_setting.gd new file mode 100644 index 00000000..abcb7f4a --- /dev/null +++ b/client/gui/menus/settings/toggle_setting.gd @@ -0,0 +1,31 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +class_name ToggleSetting +extends GameSetting + +func _init(new_id: String, new_default: bool): + super(new_id, new_default) + +func create_row(): + var row = super() + row.value_node = CheckButton.new() + row.value_node.pressed.connect(func(): Global.set_setting(key, row.value_node.button_pressed)) + Settings.hook_changed_init(key, true, + func(value): + if is_instance_valid(row): + row.value_node.button_pressed = value + ) + return row diff --git a/client/gui/menus/settings/toggle_setting.gd.uid b/client/gui/menus/settings/toggle_setting.gd.uid new file mode 100644 index 00000000..1d2ca55b --- /dev/null +++ b/client/gui/menus/settings/toggle_setting.gd.uid @@ -0,0 +1 @@ +uid://cojnv8bmv6aw5 diff --git a/client/gui/menus/setup/hairstyle_preview.gd b/client/gui/menus/setup/hairstyle_preview.gd new file mode 100644 index 00000000..78576491 --- /dev/null +++ b/client/gui/menus/setup/hairstyle_preview.gd @@ -0,0 +1,27 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +class_name HairstylePreview +extends VBoxContainer + +signal selected(character_style: Dictionary) + +func setup(hairstyle: int, group: ButtonGroup): + var character_style = Global.default_profile.character_style + character_style.hairstyle = hairstyle + $HairViewport/Node3D/Character.set_style(character_style, "chef") + $Select.button_group = group + $Select.text = tr("c.setup.uniform.value").format([hairstyle + 1]) + $Select.pressed.connect(func(): selected.emit(character_style)) diff --git a/client/gui/menus/setup/hairstyle_preview.gd.uid b/client/gui/menus/setup/hairstyle_preview.gd.uid new file mode 100644 index 00000000..8f5b3cd4 --- /dev/null +++ b/client/gui/menus/setup/hairstyle_preview.gd.uid @@ -0,0 +1 @@ +uid://dvveoqur81l0s diff --git a/client/gui/menus/setup/hairstyle_preview.tscn b/client/gui/menus/setup/hairstyle_preview.tscn new file mode 100644 index 00000000..ee4a65e9 --- /dev/null +++ b/client/gui/menus/setup/hairstyle_preview.tscn @@ -0,0 +1,55 @@ +[gd_scene load_steps=7 format=3 uid="uid://dfon56nwd2tgn"] + +[ext_resource type="Script" uid="uid://dvveoqur81l0s" path="res://gui/menus/setup/hairstyle_preview.gd" id="1_0qdmv"] +[ext_resource type="Shader" uid="uid://qjrh2imc53u1" path="res://gui/resources/shaders/grayscale.gdshader" id="1_sf0gc"] +[ext_resource type="PackedScene" uid="uid://b3hhir2fvnunu" path="res://player/character/character.tscn" id="2_jtitc"] + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_entrs"] +shader = ExtResource("1_sf0gc") + +[sub_resource type="ViewportTexture" id="ViewportTexture_giuq2"] +viewport_path = NodePath("HairViewport") + +[sub_resource type="ButtonGroup" id="ButtonGroup_c5p7t"] + +[node name="HairstylePreview" type="VBoxContainer"] +offset_right = 40.0 +offset_bottom = 40.0 +script = ExtResource("1_0qdmv") + +[node name="Preview" type="TextureRect" parent="."] +material = SubResource("ShaderMaterial_entrs") +layout_mode = 2 +texture = SubResource("ViewportTexture_giuq2") + +[node name="Select" type="CheckBox" parent="."] +layout_mode = 2 +button_group = SubResource("ButtonGroup_c5p7t") +text = "Hairstyle 1" + +[node name="HairViewport" type="SubViewport" parent="."] +own_world_3d = true +transparent_bg = true +msaa_3d = 1 +size = Vector2i(128, 128) + +[node name="Node3D" type="Node3D" parent="HairViewport"] + +[node name="Camera3D" type="Camera3D" parent="HairViewport/Node3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.75, 1.5) +fov = 25.5 + +[node name="Character" parent="HairViewport/Node3D" instance=ExtResource("2_jtitc")] + +[node name="SpotLight3D" type="SpotLight3D" parent="HairViewport/Node3D"] +transform = Transform3D(0.866025, 0, -0.5, 0, 1, 0, 0.5, 0, 0.866025, -2, 0, 2) + +[node name="SpotLight3D2" type="SpotLight3D" parent="HairViewport/Node3D"] +transform = Transform3D(0.876399, 0, 0.481585, 0, 1, 0, -0.481585, 0, 0.876399, 2, 0.499189, 2) +light_color = Color(0.857819, 0.80038, 0.775519, 1) +light_energy = 4.11 + +[node name="SpotLight3D3" type="SpotLight3D" parent="HairViewport/Node3D"] +transform = Transform3D(-0.965926, 0, -0.258819, -0.129409, 0.866025, 0.482963, 0.224144, 0.5, -0.836516, -1, 2, -2) +light_color = Color(0.540595, 0.865144, 1, 1) +light_energy = 8.2 diff --git a/client/gui/menus/setup/setup.gd b/client/gui/menus/setup/setup.gd new file mode 100644 index 00000000..6170786c --- /dev/null +++ b/client/gui/menus/setup/setup.gd @@ -0,0 +1,110 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends Menu + +const SCROLL_SPEED := 500. + +var character_style = null # : Dictionary? + +@onready var anim: AnimationPlayer = $AnimationPlayer +@onready var username: LineEdit = $ScrollContainer/Control/TextureRect/PaperMargin/Contents/NameEntry/LineEdit +@onready var sign_sound: AudioStreamPlayer = $Sign +@onready var sign_button: Button = $ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployeeMargin/Sign/Signature +@onready var scroll: ScrollContainer = $ScrollContainer +@onready var select_uniform: HBoxContainer = $ScrollContainer/Control/TextureRect/PaperMargin/Contents/SelectUniform +@onready var skip_tutorial: CheckBox = $ScrollContainer/Control/TextureRect/PaperMargin/Contents/SelectExperience/CheckBox + +func _ready(): + anim.play("paper_slide") + var button_group := ButtonGroup.new() + for i in range(3): + var preview: HairstylePreview = preload("res://gui/menus/setup/hairstyle_preview.tscn").instantiate() + select_uniform.add_child(preview) + preview.setup(i, button_group) + preview.selected.connect(_character_selected) + if i < 2: + var spacer = Control.new() + spacer.size_flags_vertical = Control.SIZE_EXPAND + spacer.custom_minimum_size.x = 50 + select_uniform.add_child(spacer) + + # Enable msaa 2D for this scene + Global.get_viewport().msaa_2d = Viewport.MSAA_4X + + if Global.profile.username != "": username.text = Global.profile.username + + if TranslationServer.get_locale().begins_with("zh"): + $ScrollContainer/Control/TextureRect.rotation = 0 + increase_font_size(self) + + super() + $Back.visible = not is_instance_of(parent_menu, Entry) + +func increase_font_size(node: Node): + if node is RichTextLabel: + for oname in ["bold_italics_font_size", "italics_font_size", "normal_font_size", "mono_font_size", "bold_font_size"]: + node.add_theme_font_size_override(oname, node.get_theme_default_font_size() * 1.2) + for c in node.get_children(): increase_font_size(c) + +func _on_back_pressed() -> void: + exit() + +func _character_selected(style: Dictionary): + character_style = style + +func _process(delta): + var s = Input.get_axis("rotate_up", "rotate_down") + scroll.set_deferred("scroll_vertical", scroll.scroll_vertical + s * delta * SCROLL_SPEED) + + +func check(): + if username.text == "": return tr("c.error.empty_username") + if character_style == null: return tr("c.error.select_hairstyle") + return null + +func _on_sign_pressed(): + if check() != null: + var popup_data := MenuPopup.Data.new() + popup_data.text = check() + var accept_button := Button.new() + accept_button.text = tr("c.menu.accept") + popup_data.buttons = [accept_button] + await submenu("res://gui/menus/popup.tscn", popup_data) + return + + sign_button.disabled = true + + sign_sound.play() + await sign_sound.finished + anim.play_backwards("paper_slide") + await anim.animation_finished + + Global.set_profile("username", username.text) + Global.set_profile("character_style", character_style) + if skip_tutorial.button_pressed: + for k in Global.profile["hints"].keys(): + Global.set_hint(k, true) + Global.save_profile() + + Global.set_setting("gameplay.hints_started", skip_tutorial.button_pressed) + Global.set_setting("gameplay.tutorial_disabled", skip_tutorial.button_pressed) + Global.set_setting("gameplay.setup_completed", true) + Global.save_settings() + + Global.get_viewport().msaa_2d = Viewport.MSAA_DISABLED + + if not is_instance_of(parent_menu, Entry): exit() + else: replace_menu("res://gui/menu/main/main.tscn") diff --git a/client/gui/menus/setup/setup.gd.uid b/client/gui/menus/setup/setup.gd.uid new file mode 100644 index 00000000..c9c2be3c --- /dev/null +++ b/client/gui/menus/setup/setup.gd.uid @@ -0,0 +1 @@ +uid://dxn6ow6hiwhbf diff --git a/client/gui/menus/setup/setup.tscn b/client/gui/menus/setup/setup.tscn new file mode 100644 index 00000000..d0cce350 --- /dev/null +++ b/client/gui/menus/setup/setup.tscn @@ -0,0 +1,398 @@ +[gd_scene load_steps=15 format=3 uid="uid://ddl3efikvqp66"] + +[ext_resource type="Script" uid="uid://dxn6ow6hiwhbf" path="res://gui/menus/setup/setup.gd" id="1_mo46n"] +[ext_resource type="Theme" uid="uid://ci2qajdoa1an1" path="res://gui/resources/theme/paper.tres" id="1_yq0aa"] +[ext_resource type="Script" uid="uid://bd7bylb2t2m0" path="res://gui/components/touch_scroll_container.gd" id="2_4caf2"] +[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://gui/resources/fonts/font-sansita-swashed.woff2" id="3_2vg4d"] +[ext_resource type="AudioStream" uid="uid://do7ii5hx71p0m" path="res://gui/resources/sounds/page.ogg" id="5_xac6d"] +[ext_resource type="AudioStream" uid="uid://5b3noxjmasmu" path="res://gui/resources/sounds/sign.ogg" id="6_wf0gh"] + +[sub_resource type="Animation" id="Animation_m4a1a"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("ScrollContainer:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0, 0)] +} + +[sub_resource type="Animation" id="Animation_s1to2"] +resource_name = "paper_slide" +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("ScrollContainer:position") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(0, -1800), Vector2(0, 0)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_wjgak"] +_data = { +&"RESET": SubResource("Animation_m4a1a"), +&"paper_slide": SubResource("Animation_s1to2") +} + +[sub_resource type="Gradient" id="Gradient_nsc3h"] +colors = PackedColorArray(0.941084, 0.949219, 0.918643, 1, 1, 1, 1, 1) + +[sub_resource type="FastNoiseLite" id="FastNoiseLite_amioi"] + +[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_bvvl7"] +color_ramp = SubResource("Gradient_nsc3h") +noise = SubResource("FastNoiseLite_amioi") + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_e7xn5"] +bg_color = Color(0.196078, 0.196078, 0.235294, 1) +corner_radius_top_left = 10 +corner_radius_top_right = 10 +corner_radius_bottom_right = 10 +corner_radius_bottom_left = 10 + +[sub_resource type="FontVariation" id="FontVariation_2cc7p"] +base_font = ExtResource("3_2vg4d") + +[node name="SetupMenu" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_mo46n") +support_anim = null +auto_anim = null + +[node name="ColorRect" type="ColorRect" parent="."] +layout_mode = 2 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +color = Color(0.196078, 0.196078, 0.235294, 1) + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +libraries = { +&"": SubResource("AnimationLibrary_wjgak") +} +speed_scale = 2.0 + +[node name="ScrollContainer" type="ScrollContainer" parent="."] +clip_contents = false +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +follow_focus = true +horizontal_scroll_mode = 0 +script = ExtResource("2_4caf2") + +[node name="Control" type="Control" parent="ScrollContainer"] +custom_minimum_size = Vector2(0, 1500) +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 + +[node name="TextureRect" type="TextureRect" parent="ScrollContainer/Control"] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -400.0 +offset_top = -559.57 +offset_right = 400.0 +offset_bottom = 571.801 +grow_horizontal = 2 +grow_vertical = 2 +rotation = 0.0174533 +theme = ExtResource("1_yq0aa") +texture = SubResource("NoiseTexture2D_bvvl7") + +[node name="Hole1" type="Panel" parent="ScrollContainer/Control/TextureRect"] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -365.0 +offset_top = -189.686 +offset_right = -345.0 +offset_bottom = -169.686 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_e7xn5") + +[node name="Hole2" type="Panel" parent="ScrollContainer/Control/TextureRect"] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -365.0 +offset_top = 130.314 +offset_right = -345.0 +offset_bottom = 150.314 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_e7xn5") + +[node name="PaperMargin" type="MarginContainer" parent="ScrollContainer/Control/TextureRect"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="Contents" type="VBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin"] +layout_mode = 2 + +[node name="Title" type="Label" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 +size_flags_horizontal = 4 +theme_override_font_sizes/font_size = 30 +text = "c.setup.contract_title" + +[node name="Sep" type="HSeparator" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 + +[node name="Intro" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 +bbcode_enabled = true +text = "c.setup.contract_desc" +fit_content = true +scroll_active = false + +[node name="Name" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 +bbcode_enabled = true +text = "c.setup.name" +fit_content = true +scroll_active = false +text_direction = 3 + +[node name="NameEntry" type="HBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 +tooltip_text = "c.setup.name.desc" + +[node name="LineEdit" type="LineEdit" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/NameEntry"] +custom_minimum_size = Vector2(300, 30) +layout_mode = 2 +max_length = 32 + +[node name="Control" type="Control" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/NameEntry"] +layout_mode = 2 + +[node name="Position" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 +bbcode_enabled = true +text = "c.setup.position" +fit_content = true +scroll_active = false +text_direction = 3 + +[node name="PositionEntry" type="HBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 + +[node name="LineEdit" type="LineEdit" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/PositionEntry"] +custom_minimum_size = Vector2(300, 30) +layout_mode = 2 +theme_override_colors/font_uneditable_color = Color(0.458824, 0, 0, 1) +theme_override_colors/font_color = Color(0.458824, 0, 0, 1) +editable = false + +[node name="LineEdit2" type="Label" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/PositionEntry/LineEdit"] +custom_minimum_size = Vector2(300, 30) +layout_mode = 1 +offset_left = 9.97753 +offset_top = 3.2088 +offset_right = 309.978 +offset_bottom = 33.2088 +theme_override_colors/font_color = Color(0.458824, 0, 0, 1) +theme_override_fonts/font = ExtResource("3_2vg4d") +text = "c.setup.position.value" + +[node name="Uniform" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 +bbcode_enabled = true +text = "c.setup.uniform" +fit_content = true +scroll_active = false +text_direction = 3 + +[node name="SelectUniform" type="HBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 +alignment = 1 + +[node name="Experience" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 +bbcode_enabled = true +text = "c.setup.experience" +fit_content = true +scroll_active = false +text_direction = 3 + +[node name="SelectExperience" type="HBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 +alignment = 1 + +[node name="CheckBox" type="CheckBox" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/SelectExperience"] +layout_mode = 2 +text = "c.setup.experience.skip" +text_direction = 3 + +[node name="Duties" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 +bbcode_enabled = true +text = "c.setup.duties" +fit_content = true +scroll_active = false +text_direction = 3 + +[node name="Terms" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 +bbcode_enabled = true +text = "c.setup.additional_terms" +fit_content = true +scroll_active = false +text_direction = 3 + +[node name="Compensation" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 +bbcode_enabled = true +text = "c.setup.compensation" +fit_content = true +scroll_active = false +text_direction = 3 + +[node name="CompensationEntry" type="HBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 + +[node name="Spacer" type="Control" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/CompensationEntry"] +custom_minimum_size = Vector2(15.045, 0) +layout_mode = 2 + +[node name="Text1" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/CompensationEntry"] +custom_minimum_size = Vector2(100.08, 0) +layout_mode = 2 +bbcode_enabled = true +text = "c.setup.compensation.salary.prefix" +fit_content = true +scroll_active = false +autowrap_mode = 0 + +[node name="LineEdit" type="LineEdit" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/CompensationEntry"] +custom_minimum_size = Vector2(50, 30) +layout_mode = 2 +theme_override_colors/font_uneditable_color = Color(0.478431, 0, 0, 1) +editable = false + +[node name="LineEdit2" type="Label" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/CompensationEntry/LineEdit"] +custom_minimum_size = Vector2(50, 30) +layout_mode = 1 +offset_left = 9.55965 +offset_top = 4.09178 +offset_right = 79.5597 +offset_bottom = 34.0918 +theme_override_colors/font_color = Color(0.478431, 0, 0, 1) +theme_override_fonts/font = ExtResource("3_2vg4d") +text = "c.setup.compensation.salary" + +[node name="Text2" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/CompensationEntry"] +custom_minimum_size = Vector2(100.08, 0) +layout_mode = 2 +bbcode_enabled = true +text = "c.setup.compensation.salary.suffix" +scroll_active = false + +[node name="Spacer" type="Control" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +custom_minimum_size = Vector2(0, 200) +layout_mode = 2 + +[node name="Signatures" type="HBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 + +[node name="EmployerMargin" type="MarginContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures"] +layout_mode = 2 + +[node name="Sign" type="VBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployerMargin"] +layout_mode = 2 + +[node name="Desc" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployerMargin/Sign"] +layout_mode = 2 +theme_override_font_sizes/normal_font_size = 15 +bbcode_enabled = true +text = "c.setup.frank_signature.desc" +fit_content = true +scroll_active = false +text_direction = 3 + +[node name="Signature" type="Label" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployerMargin/Sign"] +custom_minimum_size = Vector2(200, 80) +layout_mode = 2 +theme_override_colors/font_color = Color(0.415686, 0.0253044, 0.135441, 1) +theme_override_fonts/font = SubResource("FontVariation_2cc7p") +theme_override_font_sizes/font_size = 31 +text = "c.setup.frank_signature" +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="Underline" type="HSeparator" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployerMargin/Sign"] +layout_mode = 2 + +[node name="EmployeeMargin" type="MarginContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures"] +layout_mode = 2 + +[node name="Sign" type="VBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployeeMargin"] +layout_mode = 2 + +[node name="Desc" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployeeMargin/Sign"] +layout_mode = 2 +theme_override_font_sizes/normal_font_size = 15 +bbcode_enabled = true +text = "c.setup.user_signature.desc" +fit_content = true +scroll_active = false +text_direction = 3 + +[node name="Signature" type="Button" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployeeMargin/Sign" groups=["no_click_sound"]] +custom_minimum_size = Vector2(200, 80) +layout_mode = 2 +text = "c.setup.user_signature" + +[node name="Underline" type="HSeparator" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployeeMargin/Sign"] +layout_mode = 2 + +[node name="Back" type="Button" parent="."] +layout_mode = 1 +offset_right = 106.0 +offset_bottom = 31.0 +text = "c.menu.back" + +[node name="Page" type="AudioStreamPlayer" parent="."] +stream = ExtResource("5_xac6d") +volume_db = -16.0 +autoplay = true + +[node name="Sign" type="AudioStreamPlayer" parent="."] +stream = ExtResource("6_wf0gh") +volume_db = -16.0 + +[connection signal="pressed" from="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployeeMargin/Sign/Signature" to="." method="_on_sign_pressed"] +[connection signal="pressed" from="Back" to="." method="_on_back_pressed"] diff --git a/client/gui/menus/transition/scene_transition.gd b/client/gui/menus/transition/scene_transition.gd new file mode 100644 index 00000000..330d67d6 --- /dev/null +++ b/client/gui/menus/transition/scene_transition.gd @@ -0,0 +1,66 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +class_name SceneTransition +extends Control + +@onready var black_anim: AnimationPlayer = $black_fader +@onready var text_anim: AnimationPlayer = $text_fader +@onready var text: Label = $text_margin/text + +var s_current = false +var s_target = false +var fading = false + +func _ready(): + $black.visible = true + text.visible = true + text.text = "" + +func set_loading_text(s: String): + text.text = s + text_anim.play("fade") + +func next(): + while fading: await black_anim.animation_finished + if s_target == s_current: return + fading = true + if s_target: + if text.text != "": + text_anim.play_backwards("fade") + await text_anim.animation_finished + black_anim.play_backwards("fade") + await black_anim.animation_finished + self.mouse_filter = Control.MOUSE_FILTER_IGNORE + set_loading_text("") + s_current = true + else: + self.mouse_filter = Control.MOUSE_FILTER_STOP + black_anim.play("fade") + await black_anim.animation_finished + await get_tree().process_frame # animation finishes one frame early + s_current = false + fading = false + await next() + +func fade_in(): + s_target = true + await next() +func fade_out(): + s_target = false + await next() + +func _exit_tree(): + if fading: push_error("SceneTransition destroyed while fading") diff --git a/client/gui/menus/transition/scene_transition.gd.uid b/client/gui/menus/transition/scene_transition.gd.uid new file mode 100644 index 00000000..60f764ae --- /dev/null +++ b/client/gui/menus/transition/scene_transition.gd.uid @@ -0,0 +1 @@ +uid://ciml1u2x4f1ci diff --git a/client/gui/menus/transition/scene_transition.tscn b/client/gui/menus/transition/scene_transition.tscn new file mode 100644 index 00000000..dab16084 --- /dev/null +++ b/client/gui/menus/transition/scene_transition.tscn @@ -0,0 +1,135 @@ +[gd_scene load_steps=11 format=3 uid="uid://bg2d78ycorcqk"] + +[ext_resource type="Script" uid="uid://ciml1u2x4f1ci" path="res://gui/menus/transition/scene_transition.gd" id="1_fpbwj"] +[ext_resource type="Shader" uid="uid://bmxrbbw18xq7u" path="res://gui/menus/transition/text_loading_anim.gdshader" id="2_g21ck"] + +[sub_resource type="Animation" id="Animation_g21ck"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("black:color") +tracks/0/interp = 1 +tracks/0/loop_wrap = false +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Color(0, 0, 0, 1)] +} + +[sub_resource type="Animation" id="Animation_e6dcd"] +resource_name = "fade" +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("black:color") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Color(0, 0, 0, 0), Color(0, 0, 0, 1)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_00tv0"] +_data = { +&"RESET": SubResource("Animation_g21ck"), +&"fade": SubResource("Animation_e6dcd") +} + +[sub_resource type="Animation" id="Animation_xgn2a"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("text_margin/text:modulate") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Color(1, 1, 1, 0)] +} + +[sub_resource type="Animation" id="Animation_cq5i2"] +resource_name = "fade" +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("text_margin/text:modulate") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Color(1, 1, 1, 0), Color(1, 1, 1, 1)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_pea72"] +_data = { +&"RESET": SubResource("Animation_xgn2a"), +&"fade": SubResource("Animation_cq5i2") +} + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_00tv0"] +shader = ExtResource("2_g21ck") + +[sub_resource type="LabelSettings" id="LabelSettings_e6dcd"] +font_size = 34 + +[node name="SceneTransition" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_fpbwj") + +[node name="black_fader" type="AnimationPlayer" parent="."] +libraries = { +&"": SubResource("AnimationLibrary_00tv0") +} +speed_scale = 4.0 + +[node name="black" type="ColorRect" parent="."] +visible = false +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +color = Color(0, 0, 0, 1) + +[node name="text_fader" type="AnimationPlayer" parent="."] +libraries = { +&"": SubResource("AnimationLibrary_pea72") +} +speed_scale = 4.0 + +[node name="text_margin" type="MarginContainer" parent="."] +layout_mode = 1 +anchors_preset = 2 +anchor_top = 1.0 +anchor_bottom = 1.0 +offset_top = -107.0 +offset_right = 401.0 +grow_vertical = 0 +mouse_filter = 2 +theme_override_constants/margin_left = 50 +theme_override_constants/margin_top = 50 +theme_override_constants/margin_right = 50 +theme_override_constants/margin_bottom = 50 + +[node name="text" type="Label" parent="text_margin"] +modulate = Color(1, 1, 1, 0) +material = SubResource("ShaderMaterial_00tv0") +layout_mode = 2 +text = "Loading something..." +label_settings = SubResource("LabelSettings_e6dcd") diff --git a/client/gui/menus/transition/text_loading_anim.gdshader b/client/gui/menus/transition/text_loading_anim.gdshader new file mode 100644 index 00000000..145dab78 --- /dev/null +++ b/client/gui/menus/transition/text_loading_anim.gdshader @@ -0,0 +1,13 @@ +shader_type canvas_item; + +varying vec4 vertex_color; +void vertex() { + vertex_color = COLOR; +} + +void fragment() { + vec4 tex = texture(TEXTURE, UV) * COLOR; + float wave = sin(VERTEX.x*0.01-TIME*10.) * 0.5 + 0.5; + wave = pow(wave, 3.); + COLOR = tex * (1. - wave * 0.2); +} diff --git a/client/gui/menus/transition/text_loading_anim.gdshader.uid b/client/gui/menus/transition/text_loading_anim.gdshader.uid new file mode 100644 index 00000000..26730c73 --- /dev/null +++ b/client/gui/menus/transition/text_loading_anim.gdshader.uid @@ -0,0 +1 @@ +uid://bmxrbbw18xq7u diff --git a/client/gui/overlays/ingame/announce_title.gd b/client/gui/overlays/ingame/announce_title.gd new file mode 100644 index 00000000..227e184f --- /dev/null +++ b/client/gui/overlays/ingame/announce_title.gd @@ -0,0 +1,42 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends Control + +@onready var init_delay: Timer = $InitialDelay +@onready var prep_timer: Timer = $PreperationTimer +@onready var anim_player: AnimationPlayer = $AnimationPlayer +@onready var label: Label = $Center/Node2D/Label + +func announce_start() -> void: + init_delay.start() + await init_delay.timeout + + Sound.play_game_start() + show() + label.text = tr("c.announce.ready") + anim_player.play("fade_in") + await anim_player.animation_finished + prep_timer.start() + await prep_timer.timeout + anim_player.play("fade_out") + await anim_player.animation_finished + + label.text = tr("c.announce.go") + anim_player.play("fade_in") + await anim_player.animation_finished + anim_player.play("fade_out") + await anim_player.animation_finished + hide() diff --git a/client/gui/overlays/ingame/announce_title.gd.uid b/client/gui/overlays/ingame/announce_title.gd.uid new file mode 100644 index 00000000..e57b9722 --- /dev/null +++ b/client/gui/overlays/ingame/announce_title.gd.uid @@ -0,0 +1 @@ +uid://ci08whhm2ej1m diff --git a/client/gui/overlays/ingame/chat.gd b/client/gui/overlays/ingame/chat.gd new file mode 100644 index 00000000..673dc979 --- /dev/null +++ b/client/gui/overlays/ingame/chat.gd @@ -0,0 +1,34 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends Control +class_name ChatPreview + +const CHAT_MESSAGE_SCENE = preload("res://gui/components/message/chat_message.tscn") + +@onready var game: Game = $"../Game" +@onready var messages_container: VBoxContainer = $MarginContainer/ScrollContainer/PanelContainer/Messages + +func _ready(): + game.text_message.connect(func(message: Game.TextMessage): + var chat_message: ChatMessage = CHAT_MESSAGE_SCENE.instantiate() + messages_container.add_child(chat_message) + chat_message.set_message( + message.username, + message.text, + message.color, + true, + message.timeout_remaining) + ) diff --git a/client/gui/overlays/ingame/chat.gd.uid b/client/gui/overlays/ingame/chat.gd.uid new file mode 100644 index 00000000..7a372630 --- /dev/null +++ b/client/gui/overlays/ingame/chat.gd.uid @@ -0,0 +1 @@ +uid://bgt04y4ncl1fv diff --git a/client/gui/overlays/ingame/chat.tscn b/client/gui/overlays/ingame/chat.tscn new file mode 100644 index 00000000..f5b1060c --- /dev/null +++ b/client/gui/overlays/ingame/chat.tscn @@ -0,0 +1,39 @@ +[gd_scene load_steps=5 format=3 uid="uid://xcxbmynn8mhi"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_lmy51"] +[ext_resource type="Script" uid="uid://bgt04y4ncl1fv" path="res://gui/overlays/ingame/chat.gd" id="2_3543w"] +[ext_resource type="Material" uid="uid://beea1pc5nt67r" path="res://gui/resources/materials/dark_blur_material.tres" id="3_15i2y"] +[ext_resource type="Script" uid="uid://cmncjc06kadpe" path="res://gui/components/blur_setup.gd" id="4_3rmhr"] + +[node name="ChatPreview" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +theme = ExtResource("1_lmy51") +script = ExtResource("2_3543w") + +[node name="MarginContainer" type="MarginContainer" parent="."] +layout_mode = 2 +anchor_bottom = 1.0 +offset_right = 296.0 +grow_vertical = 2 + +[node name="ScrollContainer" type="ScrollContainer" parent="MarginContainer"] +layout_mode = 2 +horizontal_scroll_mode = 0 + +[node name="PanelContainer" type="PanelContainer" parent="MarginContainer/ScrollContainer"] +material = ExtResource("3_15i2y") +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 0 +mouse_filter = 2 +script = ExtResource("4_3rmhr") + +[node name="Messages" type="VBoxContainer" parent="MarginContainer/ScrollContainer/PanelContainer"] +layout_mode = 2 +mouse_filter = 2 diff --git a/client/gui/overlays/ingame/score.gd b/client/gui/overlays/ingame/score.gd new file mode 100644 index 00000000..d4e2e3d3 --- /dev/null +++ b/client/gui/overlays/ingame/score.gd @@ -0,0 +1,68 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +class_name Overlay +extends PanelContainer + +const LABEL_SCALE: Vector2 = Vector2(1.5, 1.5) + +var failed: int = 0 +var completed: int = 0 +var points: int = 0 + +@onready var failed_label: Label = $Score/Paper/Margin/Lines/Line2/Failed +@onready var completed_label: Label = $Score/Paper/Margin/Lines/Line1/Completed +@onready var points_label: Label = $Score/Paper/Margin/Lines/Line3/Points +@onready var timer: Timer = $Timer +@onready var seconds_label: Label = $Time/Paper/Line/Seconds +@onready var decimals_label: Label = $Time/Paper/Line/Decimals +@onready var announcement = $Announcement + +func update(failed_: int, completed_: int, points_: int, time: float): + if failed_ - failed: + failed_label.text = str(failed_) + failed_label.scale = LABEL_SCALE + failed = failed_ + if completed_ - completed: + completed_label.text = str(completed_) + completed_label.scale = LABEL_SCALE + completed = completed_ + if points_ - points: + points_label.text = str(points_) + points_label.scale = LABEL_SCALE + points = points_ + + timer.stop() + if time > 0.: + timer.wait_time = time + timer.start() + +func set_ingame(_state: bool, lobby: bool): + if lobby: + hide() + timer.stop() + else: + show() + +func announce_start(): + announcement.announce_start() + +func _process(delta): + failed_label.scale = G.interpolate(failed_label.scale, Vector2(1, 1), delta * 4.) + completed_label.scale = G.interpolate(completed_label.scale, Vector2(1, 1), delta * 4.) + points_label.scale = G.interpolate(points_label.scale, Vector2(1, 1), delta * 4.) + var seconds: float = floor(timer.time_left) + seconds_label.text = str(int(seconds)) + decimals_label.text = "%01d" % int((timer.time_left - seconds) * 10) diff --git a/client/gui/overlays/ingame/score.gd.uid b/client/gui/overlays/ingame/score.gd.uid new file mode 100644 index 00000000..ff13fb53 --- /dev/null +++ b/client/gui/overlays/ingame/score.gd.uid @@ -0,0 +1 @@ +uid://mcgg3q0l03dx diff --git a/client/gui/overlays/ingame/score.tscn b/client/gui/overlays/ingame/score.tscn new file mode 100644 index 00000000..497275f5 --- /dev/null +++ b/client/gui/overlays/ingame/score.tscn @@ -0,0 +1,555 @@ +[gd_scene load_steps=14 format=3 uid="uid://bpikve6wlsjfl"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_4kujw"] +[ext_resource type="Script" uid="uid://mcgg3q0l03dx" path="res://gui/overlays/ingame/score.gd" id="2_kbjds"] +[ext_resource type="Texture2D" uid="uid://chxkwohi56cxx" path="res://gui/resources/shaders/paper.tres" id="3_oum5g"] +[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://gui/resources/fonts/font-sansita-swashed.woff2" id="3_u54fv"] +[ext_resource type="Script" uid="uid://ci08whhm2ej1m" path="res://gui/overlays/ingame/announce_title.gd" id="5_874f2"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_04ujj"] +bg_color = Color(0, 0, 0, 0) + +[sub_resource type="FontVariation" id="FontVariation_8f216"] +base_font = ExtResource("3_u54fv") +variation_embolden = 0.5 + +[sub_resource type="Animation" id="Animation_owy7i"] +length = 0.001 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Center/Node2D:scale:x") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(1e-05, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Center/Node2D:scale:y") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(1e-05, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0) +} +tracks/2/type = "bezier" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Center/Node2D:modulate:r") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0) +} +tracks/3/type = "bezier" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Center/Node2D:modulate:g") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0) +} +tracks/4/type = "bezier" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Center/Node2D:modulate:b") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0) +} +tracks/5/type = "bezier" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Center/Node2D:modulate:a") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0) +} + +[sub_resource type="Animation" id="Animation_kmsgw"] +resource_name = "fade_in" +length = 0.5 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Center/Node2D:scale:x") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1e-05, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.5) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Center/Node2D:scale:y") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1e-05, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.5) +} +tracks/2/type = "bezier" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Center/Node2D:modulate:r") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.5) +} +tracks/3/type = "bezier" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Center/Node2D:modulate:g") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.5) +} +tracks/4/type = "bezier" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Center/Node2D:modulate:b") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.5) +} +tracks/5/type = "bezier" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Center/Node2D:modulate:a") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.5) +} + +[sub_resource type="Animation" id="Animation_874f2"] +resource_name = "fade_in_and_out" +length = 0.8 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Center/Node2D:modulate:r") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0, 0, 0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.3, 0.8) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Center/Node2D:modulate:g") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0, 0, 0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.3, 0.8) +} +tracks/2/type = "bezier" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Center/Node2D:modulate:b") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"handle_modes": PackedInt32Array(0, 0, 0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.3, 0.8) +} +tracks/3/type = "bezier" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Center/Node2D:modulate:a") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"handle_modes": PackedInt32Array(0, 0, 0), +"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0, 0, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.3, 0.8) +} +tracks/4/type = "bezier" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Center/Node2D:scale:x") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1e-05, -0.25, 0, 0.25, 0, 2, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.8) +} +tracks/5/type = "bezier" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Center/Node2D:scale:y") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1e-05, -0.25, 0, 0.25, 0, 2, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.8) +} + +[sub_resource type="Animation" id="Animation_x6gse"] +resource_name = "fade_out" +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Center/Node2D:modulate:r") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 1) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Center/Node2D:modulate:g") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 1) +} +tracks/2/type = "bezier" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Center/Node2D:modulate:b") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 1) +} +tracks/3/type = "bezier" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Center/Node2D:modulate:a") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0, 0, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 1) +} + +[sub_resource type="Animation" id="Animation_deqe4"] +resource_name = "fade_out_quick" +length = 0.25 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Center/Node2D:modulate:r") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1, -0.125, 0, 0.125, 0, 1, -0.125, 0, 0.125, 0), +"times": PackedFloat32Array(0, 0.25) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Center/Node2D:modulate:g") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1, -0.125, 0, 0.125, 0, 1, -0.125, 0, 0.125, 0), +"times": PackedFloat32Array(0, 0.25) +} +tracks/2/type = "bezier" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Center/Node2D:modulate:b") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1, -0.125, 0, 0.125, 0, 1, -0.125, 0, 0.125, 0), +"times": PackedFloat32Array(0, 0.25) +} +tracks/3/type = "bezier" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Center/Node2D:modulate:a") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1, -0.125, 0, 0.125, 0, 0, -0.125, 0, 0.125, 0), +"times": PackedFloat32Array(0, 0.25) +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_deqe4"] +_data = { +&"RESET": SubResource("Animation_owy7i"), +&"fade_in": SubResource("Animation_kmsgw"), +&"fade_in_and_out": SubResource("Animation_874f2"), +&"fade_out": SubResource("Animation_x6gse"), +&"fade_out_quick": SubResource("Animation_deqe4") +} + +[node name="Overlay" type="PanelContainer"] +layout_direction = 2 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +theme = ExtResource("1_4kujw") +theme_override_styles/panel = SubResource("StyleBoxFlat_04ujj") +script = ExtResource("2_kbjds") + +[node name="Timer" type="Timer" parent="."] +wait_time = 30.0 + +[node name="Score" type="Control" parent="."] +layout_mode = 2 +size_flags_horizontal = 8 +size_flags_vertical = 0 + +[node name="Paper" type="TextureRect" parent="Score"] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -242.0 +offset_top = -327.0 +offset_right = 270.0 +offset_bottom = 185.0 +grow_horizontal = 2 +grow_vertical = 2 +rotation = 0.0610865 +texture = ExtResource("3_oum5g") + +[node name="Margin" type="MarginContainer" parent="Score/Paper"] +layout_mode = 1 +anchors_preset = 2 +anchor_top = 1.0 +anchor_bottom = 1.0 +offset_top = -142.0 +offset_right = 258.0 +grow_vertical = 0 +theme_override_constants/margin_left = 10 +theme_override_constants/margin_bottom = 10 + +[node name="Lines" type="VBoxContainer" parent="Score/Paper/Margin"] +layout_direction = 1 +layout_mode = 2 +size_flags_horizontal = 0 +size_flags_vertical = 8 + +[node name="Line1" type="HBoxContainer" parent="Score/Paper/Margin/Lines"] +layout_mode = 2 + +[node name="Label" type="Label" parent="Score/Paper/Margin/Lines/Line1"] +layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_fonts/font = ExtResource("3_u54fv") +theme_override_font_sizes/font_size = 25 +text = "c.score.completed" + +[node name="Spacer" type="Control" parent="Score/Paper/Margin/Lines/Line1"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Completed" type="Label" parent="Score/Paper/Margin/Lines/Line1"] +auto_translate_mode = 2 +custom_minimum_size = Vector2(100, 0) +layout_mode = 2 +theme_override_colors/font_color = Color(0, 0.278431, 0, 1) +theme_override_fonts/font = ExtResource("3_u54fv") +theme_override_font_sizes/font_size = 35 +text = "0" +horizontal_alignment = 1 + +[node name="Line2" type="HBoxContainer" parent="Score/Paper/Margin/Lines"] +layout_mode = 2 + +[node name="Label" type="Label" parent="Score/Paper/Margin/Lines/Line2"] +layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_fonts/font = ExtResource("3_u54fv") +theme_override_font_sizes/font_size = 25 +text = "c.score.failed" + +[node name="Spacer" type="Control" parent="Score/Paper/Margin/Lines/Line2"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Failed" type="Label" parent="Score/Paper/Margin/Lines/Line2"] +auto_translate_mode = 2 +custom_minimum_size = Vector2(100, 0) +layout_mode = 2 +theme_override_colors/font_color = Color(0.505882, 0, 0, 1) +theme_override_fonts/font = ExtResource("3_u54fv") +theme_override_font_sizes/font_size = 35 +text = "0" +horizontal_alignment = 1 + +[node name="Line3" type="HBoxContainer" parent="Score/Paper/Margin/Lines"] +layout_mode = 2 + +[node name="Label" type="Label" parent="Score/Paper/Margin/Lines/Line3"] +layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_fonts/font = ExtResource("3_u54fv") +theme_override_font_sizes/font_size = 35 +text = "c.score.points" + +[node name="Spacer" type="Control" parent="Score/Paper/Margin/Lines/Line3"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Points" type="Label" parent="Score/Paper/Margin/Lines/Line3"] +auto_translate_mode = 2 +custom_minimum_size = Vector2(100, 0) +layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_fonts/font = ExtResource("3_u54fv") +theme_override_font_sizes/font_size = 45 +text = "0" +horizontal_alignment = 1 + +[node name="Time" type="Control" parent="."] +layout_mode = 2 +size_flags_horizontal = 8 +size_flags_vertical = 8 + +[node name="Paper" type="TextureRect" parent="Time"] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -206.0 +offset_top = -119.0 +offset_right = 306.0 +offset_bottom = 393.0 +grow_horizontal = 2 +grow_vertical = 2 +rotation = 0.0610865 +texture = ExtResource("3_oum5g") + +[node name="Line" type="HBoxContainer" parent="Time/Paper"] +layout_mode = 0 + +[node name="Seconds" type="Label" parent="Time/Paper/Line"] +auto_translate_mode = 2 +custom_minimum_size = Vector2(100, 0) +layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_fonts/font = ExtResource("3_u54fv") +theme_override_font_sizes/font_size = 45 +text = "300" +horizontal_alignment = 2 + +[node name="Point" type="Label" parent="Time/Paper/Line"] +auto_translate_mode = 2 +layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_fonts/font = ExtResource("3_u54fv") +theme_override_font_sizes/font_size = 45 +text = "." +horizontal_alignment = 1 + +[node name="Decimals" type="Label" parent="Time/Paper/Line"] +auto_translate_mode = 2 +layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_fonts/font = ExtResource("3_u54fv") +theme_override_font_sizes/font_size = 45 +text = "00" + +[node name="Announcement" type="Control" parent="."] +visible = false +layout_mode = 2 +script = ExtResource("5_874f2") + +[node name="Center" type="Control" parent="Announcement"] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="Node2D" type="Node2D" parent="Announcement/Center"] +modulate = Color(1, 1, 1, 0) +scale = Vector2(1e-05, 1e-05) + +[node name="Label" type="Label" parent="Announcement/Center/Node2D"] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -375.0 +offset_top = -50.0 +offset_right = 375.0 +offset_bottom = 50.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_vertical = 1 +theme_override_colors/font_outline_color = Color(0.564706, 0.207843, 0.266667, 1) +theme_override_constants/outline_size = 20 +theme_override_fonts/font = SubResource("FontVariation_8f216") +theme_override_font_sizes/font_size = 64 +text = "GO!" +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="AnimationPlayer" type="AnimationPlayer" parent="Announcement"] +libraries = { +&"": SubResource("AnimationLibrary_deqe4") +} + +[node name="PreperationTimer" type="Timer" parent="Announcement"] +one_shot = true + +[node name="InitialDelay" type="Timer" parent="Announcement"] +wait_time = 0.5 +one_shot = true diff --git a/client/gui/overlays/lobby/lobby.gd b/client/gui/overlays/lobby/lobby.gd new file mode 100644 index 00000000..3971dbb3 --- /dev/null +++ b/client/gui/overlays/lobby/lobby.gd @@ -0,0 +1,204 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends Control +class_name Lobby + +const MAX_BOT_COUNT_PER_TYPE: int = 3 +const PLAYER = preload("res://gui/overlays/lobby/player.tscn") + +var map_count +var selected_map := 0 +var selected_map_name: String + +var bots_enabled := false +var bot_counts := {} +var bot_reset_buttons := {} +var bot_inc_buttons := {} +var bot_dec_buttons := {} + +@onready var game: Game = $"../Game" +@onready var player_container = $PlayerList/VBoxContainer/Players + +@onready var map_name_label = $Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/Map/Name +@onready var map_player_label = $Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/Map/Players +@onready var map_difficulty_label = $Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/Map/Difficulty +@onready var map_list_container = $Sidebar/Bottom/MarginContainer/VBoxContainer/MapList/VBoxContainer +@onready var map_list = $Sidebar/Bottom/MarginContainer/VBoxContainer/MapList + +@onready var map_selector = $Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer +@onready var prev_map = $Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/VBoxContainer/Left +@onready var next_map = $Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/VBoxContainer2/Right + +@onready var bots_container = $Sidebar/Bottom/MarginContainer/VBoxContainer/Bots +@onready var bot_settings = $Sidebar/Bottom/MarginContainer/VBoxContainer/Bots/ScrollContainerCustom/BotSettings +@onready var bot_settings_conainer = $Sidebar/Bottom/MarginContainer/VBoxContainer/Bots/ScrollContainerCustom + +@onready var join_spectate = $Sidebar/Bottom/MarginContainer/VBoxContainer/VBoxContainer/JoinSpectate +@onready var start_button = $Sidebar/Bottom/MarginContainer/VBoxContainer/VBoxContainer/Start + +func _ready(): + game.update_players.connect(update_players) + initialize() + game.data_updated.connect(initialize) + game.join_state_updated.connect(_on_game_join_state_updated) + _on_game_join_state_updated(game.join_state) + check_for_music() + +func initialize(): + map_count = game.maps.size() + + for c in map_list_container.get_children(): + c.queue_free() + for c in bot_settings.get_children(): + c.queue_free() + + var i := 0 + for m in game.maps: + var b := Button.new() + b.name = m[0] + b.text = "%s (%d)" % [m[1]["name"], m[1]["players"]] + b.pressed.connect(select_map.bind(i)) + b.focus_entered.connect(select_map.bind(i)) + map_list_container.add_child(b) + i += 1 + select_map(0) + + for algo_id: String in game.bot_algos: + if algo_id == "customer" or algo_id == "test": + continue + + bot_counts[algo_id] = 0 + + var h := HBoxContainer.new() + h.name = algo_id + var add := Button.new() + add.text = "+" + var reset := Button.new() + reset.size_flags_horizontal = SIZE_EXPAND_FILL + var remove := Button.new() + remove.text = "-" + bot_reset_buttons[algo_id] = reset + bot_inc_buttons[algo_id] = add + bot_dec_buttons[algo_id] = remove + update_bot_reset_text(algo_id) + add.pressed.connect(increase_bot_count.bind(algo_id)) + reset.pressed.connect(reset_bot_count.bind(algo_id)) + remove.pressed.connect(decrease_bot_count.bind(algo_id)) + h.add_child(remove) + h.add_child(reset) + h.add_child(add) + bot_settings.add_child(h) + +func select_map(i: int): + if i >= map_count: + return + selected_map = i + var map_data: Dictionary = game.maps[i][1] + map_name_label.text = map_data["name"] + map_player_label.text = tr("c.map.players_recommended").format([roundi(map_data["players"])]) + map_difficulty_label.text = tr("c.map.difficulty.%d" % (map_data["difficulty"] - 1)) + selected_map_name = game.maps[i][0] + if not game.menu.covered: + map_list_container.get_child(i).grab_focus() + +func increase_bot_count(algo_id: String): + bot_counts[algo_id] += 1 + update_bot_reset_text(algo_id) + +func decrease_bot_count(algo_id: String): + bot_counts[algo_id] -= 1 + update_bot_reset_text(algo_id) + +func reset_bot_count(algo_id: String): + bot_counts[algo_id] = 0 + update_bot_reset_text(algo_id) + +func update_bot_reset_text(algo_id: String): + var display_name: String = tr("s.bot.%s" % algo_id) + bot_reset_buttons[algo_id].text = "%s (%d)" % [display_name, bot_counts[algo_id]] + bot_inc_buttons[algo_id].disabled = not bot_counts[algo_id] < MAX_BOT_COUNT_PER_TYPE + bot_dec_buttons[algo_id].disabled = not bot_counts[algo_id] > 0 + +func update_players(player_list: Dictionary): + for i in player_container.get_children(): + i.queue_free() + + for i in player_list.keys(): + var p: PlayerTag = PLAYER.instantiate() + player_container.add_child(p) + p.setup(player_list[i].username) + +func _input(_event): + if not visible: + return + + if Input.is_action_just_pressed("previous") and not prev_map.disabled: + prev_map.emit_signal("pressed") + elif Input.is_action_just_pressed("next") and not next_map.disabled: + next_map.emit_signal("pressed") + +func _on_left_pressed(): + selected_map = (selected_map - 1) % map_count + select_map(selected_map) + +func _on_right_pressed(): + selected_map = (selected_map + 1) % map_count + select_map(selected_map) + +func _on_start_pressed(): + if selected_map_name != null: + var start_msg := "/start %s" % selected_map_name + + if bots_enabled: + for k in bot_counts.keys(): + for i in range(bot_counts[k]): + start_msg += "\ncreate-bot %s" % k + + game.mp.send_chat(game.my_player_id, start_msg) + Sound.play_music("stop") # TODO: Game music enter + +func _on_game_join_state_updated(state: Game.JoinState): + match state: + Game.JoinState.JOINED: + map_selector.show() + map_list.show() + bots_container.show() + start_button.disabled = false + join_spectate.disabled = false + join_spectate.text = tr("c.menu.ingame.spectate") + Game.JoinState.SPECTATING: + map_selector.hide() + map_list.hide() + bots_container.hide() + start_button.disabled = true + join_spectate.disabled = false + join_spectate.text = tr("c.menu.ingame.join") + Game.JoinState.WAITING: + join_spectate.disabled = true + +func _on_join_spectate_pressed(): + game.toggle_join() + +func check_for_music(): + if visible: + Sound.play_music("Lobby") + else: + Sound.play_music("stop") # TODO: Game music enter + +func _on_enable_bots_toggled(toggled_on): + bots_enabled = toggled_on + bot_settings_conainer.visible = toggled_on + bots_container.size_flags_vertical = SIZE_EXPAND_FILL if toggled_on else SIZE_FILL diff --git a/client/gui/overlays/lobby/lobby.gd.uid b/client/gui/overlays/lobby/lobby.gd.uid new file mode 100644 index 00000000..b92e8681 --- /dev/null +++ b/client/gui/overlays/lobby/lobby.gd.uid @@ -0,0 +1 @@ +uid://bssjvsu44l0fn diff --git a/client/gui/overlays/lobby/lobby.tscn b/client/gui/overlays/lobby/lobby.tscn new file mode 100644 index 00000000..58ae2add --- /dev/null +++ b/client/gui/overlays/lobby/lobby.tscn @@ -0,0 +1,191 @@ +[gd_scene load_steps=17 format=3 uid="uid://bc50la65ntifb"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_u18ke"] +[ext_resource type="Script" uid="uid://bssjvsu44l0fn" path="res://gui/overlays/lobby/lobby.gd" id="2_7657i"] +[ext_resource type="StyleBox" uid="uid://de80aw86emnql" path="res://gui/resources/style/lobby_panel_override.tres" id="3_6iqoe"] +[ext_resource type="Material" uid="uid://beea1pc5nt67r" path="res://gui/resources/materials/dark_blur_material.tres" id="3_esmbx"] +[ext_resource type="Texture2D" uid="uid://35rd5gamtyqm" path="res://gui/resources/icons/arrow.svg" id="3_jxleg"] +[ext_resource type="Texture2D" uid="uid://j75dbytlbju" path="res://gui/resources/icons/arrow_pressed.svg" id="4_eapmn"] +[ext_resource type="Script" uid="uid://cmncjc06kadpe" path="res://gui/components/blur_setup.gd" id="5_am8pt"] +[ext_resource type="Texture2D" uid="uid://b33qmctbpf48g" path="res://gui/resources/icons/arrow_hover.svg" id="5_odwav"] +[ext_resource type="Script" uid="uid://byshs20og68tn" path="res://gui/components/smart_margin_container.gd" id="6_7mu2u"] +[ext_resource type="Texture2D" uid="uid://by3qsrpxnfq4w" path="res://gui/resources/icons/arrow_focus.svg" id="6_tulu3"] +[ext_resource type="FontFile" uid="uid://5ixo6b3bd3km" path="res://gui/resources/fonts/font-josefin-sans.woff2" id="8_cwbpa"] +[ext_resource type="Texture2D" uid="uid://bsx6fo7mv2u6a" path="res://gui/resources/icons/controller_x.svg" id="9_q14bw"] +[ext_resource type="Script" uid="uid://bd7bylb2t2m0" path="res://gui/components/touch_scroll_container.gd" id="10_bgene"] +[ext_resource type="Texture2D" uid="uid://cr2a6ide6vnnv" path="res://gui/resources/icons/controller_y.svg" id="11_5uugf"] +[ext_resource type="Script" uid="uid://b1eomxildrq30" path="res://gui/components/controller_button.gd" id="12_7mu2u"] + +[sub_resource type="FontVariation" id="FontVariation_5xxr2"] +base_font = ExtResource("8_cwbpa") +variation_embolden = 1.5 + +[node name="Lobby" type="Control" groups=["no_auto_focus"]] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("1_u18ke") +script = ExtResource("2_7657i") + +[node name="PlayerList" type="MarginContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +theme_override_constants/margin_left = 342 +theme_override_constants/margin_top = 32 +theme_override_constants/margin_right = 342 +theme_override_constants/margin_bottom = 32 + +[node name="VBoxContainer" type="VBoxContainer" parent="PlayerList"] +layout_mode = 2 + +[node name="Players" type="HBoxContainer" parent="PlayerList/VBoxContainer"] +layout_mode = 2 +alignment = 1 + +[node name="Sidebar" type="HBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +alignment = 2 + +[node name="Bottom" type="PanelContainer" parent="Sidebar"] +material = ExtResource("3_esmbx") +layout_mode = 2 +theme_override_styles/panel = ExtResource("3_6iqoe") +script = ExtResource("5_am8pt") + +[node name="MarginContainer" type="MarginContainer" parent="Sidebar/Bottom"] +layout_mode = 2 +script = ExtResource("6_7mu2u") + +[node name="VBoxContainer" type="VBoxContainer" parent="Sidebar/Bottom/MarginContainer"] +layout_mode = 2 +theme_override_constants/separation = 24 + +[node name="HBoxContainer" type="HBoxContainer" parent="Sidebar/Bottom/MarginContainer/VBoxContainer"] +layout_direction = 2 +layout_mode = 2 +alignment = 1 + +[node name="VBoxContainer" type="VBoxContainer" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer"] +layout_mode = 2 +alignment = 1 + +[node name="Left" type="TextureButton" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/VBoxContainer"] +custom_minimum_size = Vector2(19, 28) +layout_mode = 2 +focus_mode = 0 +texture_normal = ExtResource("3_jxleg") +texture_pressed = ExtResource("4_eapmn") +texture_hover = ExtResource("5_odwav") +texture_focused = ExtResource("6_tulu3") +ignore_texture_size = true +stretch_mode = 4 +flip_h = true + +[node name="Map" type="VBoxContainer" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer"] +layout_mode = 2 + +[node name="Name" type="Label" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/Map"] +custom_minimum_size = Vector2(200, 0) +layout_mode = 2 +theme_override_fonts/font = SubResource("FontVariation_5xxr2") +theme_override_font_sizes/font_size = 24 +text = "Map name" +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="Players" type="Label" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/Map"] +layout_mode = 2 +text = "Players" +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="Difficulty" type="Label" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/Map"] +layout_mode = 2 +text = "Difficulty" +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="VBoxContainer2" type="VBoxContainer" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer"] +layout_mode = 2 +alignment = 1 + +[node name="Right" type="TextureButton" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/VBoxContainer2"] +custom_minimum_size = Vector2(19, 28) +layout_mode = 2 +focus_mode = 0 +texture_normal = ExtResource("3_jxleg") +texture_pressed = ExtResource("4_eapmn") +texture_hover = ExtResource("5_odwav") +texture_focused = ExtResource("6_tulu3") +ignore_texture_size = true +stretch_mode = 4 + +[node name="MapList" type="ScrollContainer" parent="Sidebar/Bottom/MarginContainer/VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +script = ExtResource("10_bgene") + +[node name="VBoxContainer" type="VBoxContainer" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/MapList"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Bots" type="VBoxContainer" parent="Sidebar/Bottom/MarginContainer/VBoxContainer"] +layout_mode = 2 + +[node name="EnableBots" type="CheckButton" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/Bots"] +layout_mode = 2 +text = "c.menu.lobby.enable_bots" + +[node name="ScrollContainerCustom" type="ScrollContainer" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/Bots"] +visible = false +layout_mode = 2 +size_flags_vertical = 3 +script = ExtResource("10_bgene") + +[node name="BotSettings" type="VBoxContainer" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/Bots/ScrollContainerCustom"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 + +[node name="VBoxContainer" type="VBoxContainer" parent="Sidebar/Bottom/MarginContainer/VBoxContainer"] +layout_mode = 2 +theme_override_constants/separation = 15 +alignment = 1 + +[node name="JoinSpectate" type="Button" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/VBoxContainer"] +layout_mode = 2 +text = "c.menu.ingame.spectate" +expand_icon = true +script = ExtResource("12_7mu2u") +controller_texture = ExtResource("11_5uugf") +press_action = "join_spectate" +metadata/_custom_type_script = "uid://b1eomxildrq30" + +[node name="Start" type="Button" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/VBoxContainer"] +layout_mode = 2 +text = "c.menu.lobby.start" +expand_icon = true +script = ExtResource("12_7mu2u") +controller_texture = ExtResource("9_q14bw") +press_action = "start_game" +metadata/_custom_type_script = "uid://b1eomxildrq30" + +[connection signal="visibility_changed" from="." to="." method="check_for_music"] +[connection signal="pressed" from="Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/VBoxContainer/Left" to="." method="_on_left_pressed"] +[connection signal="pressed" from="Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/VBoxContainer2/Right" to="." method="_on_right_pressed"] +[connection signal="toggled" from="Sidebar/Bottom/MarginContainer/VBoxContainer/Bots/EnableBots" to="." method="_on_enable_bots_toggled"] +[connection signal="pressed" from="Sidebar/Bottom/MarginContainer/VBoxContainer/VBoxContainer/JoinSpectate" to="." method="_on_join_spectate_pressed"] +[connection signal="pressed" from="Sidebar/Bottom/MarginContainer/VBoxContainer/VBoxContainer/Start" to="." method="_on_start_pressed"] diff --git a/client/gui/overlays/lobby/player.gd b/client/gui/overlays/lobby/player.gd new file mode 100644 index 00000000..175d6341 --- /dev/null +++ b/client/gui/overlays/lobby/player.gd @@ -0,0 +1,22 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +extends PanelContainer +class_name PlayerTag + +@onready var name_label = $MarginContainer/HBoxContainer/Label + +func setup(player_name: String): + name_label.text = player_name diff --git a/client/gui/overlays/lobby/player.gd.uid b/client/gui/overlays/lobby/player.gd.uid new file mode 100644 index 00000000..b0971cdb --- /dev/null +++ b/client/gui/overlays/lobby/player.gd.uid @@ -0,0 +1 @@ +uid://buxb488rr2ncs diff --git a/client/gui/overlays/lobby/player.tscn b/client/gui/overlays/lobby/player.tscn new file mode 100644 index 00000000..aa8997a1 --- /dev/null +++ b/client/gui/overlays/lobby/player.tscn @@ -0,0 +1,43 @@ +[gd_scene load_steps=6 format=3 uid="uid://gmldnel4xbxy"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_flfqn"] +[ext_resource type="Texture2D" uid="uid://222w1wha75od" path="res://gui/resources/icons/user.webp" id="2_mnaqt"] +[ext_resource type="Script" uid="uid://buxb488rr2ncs" path="res://gui/overlays/lobby/player.gd" id="2_w3lyk"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_1227j"] +bg_color = Color(0, 0, 0, 1) +corner_radius_top_left = 16 +corner_radius_top_right = 16 +corner_radius_bottom_right = 16 +corner_radius_bottom_left = 16 + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_3yp6e"] +content_margin_right = 8.0 + +[node name="Player" type="PanelContainer"] +offset_right = 40.0 +offset_bottom = 40.0 +theme = ExtResource("1_flfqn") +theme_override_styles/panel = SubResource("StyleBoxFlat_1227j") +script = ExtResource("2_w3lyk") + +[node name="MarginContainer" type="MarginContainer" parent="."] +layout_mode = 2 +theme_override_constants/margin_left = 4 +theme_override_constants/margin_top = 4 +theme_override_constants/margin_right = 4 +theme_override_constants/margin_bottom = 4 + +[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer"] +layout_mode = 2 + +[node name="Icon" type="TextureRect" parent="MarginContainer/HBoxContainer"] +layout_mode = 2 +texture = ExtResource("2_mnaqt") +expand_mode = 2 + +[node name="Label" type="Label" parent="MarginContainer/HBoxContainer"] +layout_mode = 2 +theme_override_styles/normal = SubResource("StyleBoxEmpty_3yp6e") +text = "Player" +vertical_alignment = 1 diff --git a/client/gui/resources/fonts/font-azaret-mono.woff2 b/client/gui/resources/fonts/font-azaret-mono.woff2 new file mode 100644 index 00000000..c413b182 Binary files /dev/null and b/client/gui/resources/fonts/font-azaret-mono.woff2 differ diff --git a/client/gui/resources/fonts/font-azaret-mono.woff2.import b/client/gui/resources/fonts/font-azaret-mono.woff2.import new file mode 100644 index 00000000..364d3ba3 --- /dev/null +++ b/client/gui/resources/fonts/font-azaret-mono.woff2.import @@ -0,0 +1,35 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://bk704sc5gkrb3" +path="res://.godot/imported/font-azaret-mono.woff2-d201b5a023a336fb85edf509d0dd9fe6.fontdata" + +[deps] + +source_file="res://gui/resources/fonts/font-azaret-mono.woff2" +dest_files=["res://.godot/imported/font-azaret-mono.woff2-d201b5a023a336fb85edf509d0dd9fe6.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +hinting=1 +subpixel_positioning=1 +keep_rounding_remainders=true +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/client/gui/resources/fonts/font-josefin-sans.woff2 b/client/gui/resources/fonts/font-josefin-sans.woff2 new file mode 100644 index 00000000..dce2708f Binary files /dev/null and b/client/gui/resources/fonts/font-josefin-sans.woff2 differ diff --git a/client/gui/resources/fonts/font-josefin-sans.woff2.import b/client/gui/resources/fonts/font-josefin-sans.woff2.import new file mode 100644 index 00000000..849d69a4 --- /dev/null +++ b/client/gui/resources/fonts/font-josefin-sans.woff2.import @@ -0,0 +1,35 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://5ixo6b3bd3km" +path="res://.godot/imported/font-josefin-sans.woff2-f1848192fffe0aa973b972af6b2bb0c4.fontdata" + +[deps] + +source_file="res://gui/resources/fonts/font-josefin-sans.woff2" +dest_files=["res://.godot/imported/font-josefin-sans.woff2-f1848192fffe0aa973b972af6b2bb0c4.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +hinting=1 +subpixel_positioning=1 +keep_rounding_remainders=true +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/client/gui/resources/fonts/font-sansita-swashed.woff2 b/client/gui/resources/fonts/font-sansita-swashed.woff2 new file mode 100644 index 00000000..5c665fb0 Binary files /dev/null and b/client/gui/resources/fonts/font-sansita-swashed.woff2 differ diff --git a/client/gui/resources/fonts/font-sansita-swashed.woff2.import b/client/gui/resources/fonts/font-sansita-swashed.woff2.import new file mode 100644 index 00000000..7dab3339 --- /dev/null +++ b/client/gui/resources/fonts/font-sansita-swashed.woff2.import @@ -0,0 +1,35 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://bo4vh5xkpvrh1" +path="res://.godot/imported/font-sansita-swashed.woff2-094d5cb1ef3d4e2539ac9238e4b7564c.fontdata" + +[deps] + +source_file="res://gui/resources/fonts/font-sansita-swashed.woff2" +dest_files=["res://.godot/imported/font-sansita-swashed.woff2-094d5cb1ef3d4e2539ac9238e4b7564c.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +hinting=1 +subpixel_positioning=1 +keep_rounding_remainders=true +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/client/gui/resources/icons/arrow.svg b/client/gui/resources/icons/arrow.svg new file mode 100644 index 00000000..bafc9e69 --- /dev/null +++ b/client/gui/resources/icons/arrow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/gui/resources/icons/arrow.svg.import b/client/gui/resources/icons/arrow.svg.import new file mode 100644 index 00000000..5ea9e3c4 --- /dev/null +++ b/client/gui/resources/icons/arrow.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://35rd5gamtyqm" +path="res://.godot/imported/arrow.svg-5c6a786f82da6fec05fdd009d40f9e81.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/arrow.svg" +dest_files=["res://.godot/imported/arrow.svg-5c6a786f82da6fec05fdd009d40f9e81.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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 +svg/scale=2.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/client/gui/resources/icons/arrow_focus.svg b/client/gui/resources/icons/arrow_focus.svg new file mode 100644 index 00000000..456f0261 --- /dev/null +++ b/client/gui/resources/icons/arrow_focus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/gui/resources/icons/arrow_focus.svg.import b/client/gui/resources/icons/arrow_focus.svg.import new file mode 100644 index 00000000..e46a7698 --- /dev/null +++ b/client/gui/resources/icons/arrow_focus.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://by3qsrpxnfq4w" +path="res://.godot/imported/arrow_focus.svg-186cef816cf6f92795a6ffbcf94d9391.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/arrow_focus.svg" +dest_files=["res://.godot/imported/arrow_focus.svg-186cef816cf6f92795a6ffbcf94d9391.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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 +svg/scale=2.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/client/gui/resources/icons/arrow_hover.svg b/client/gui/resources/icons/arrow_hover.svg new file mode 100644 index 00000000..098063ec --- /dev/null +++ b/client/gui/resources/icons/arrow_hover.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/gui/resources/icons/arrow_hover.svg.import b/client/gui/resources/icons/arrow_hover.svg.import new file mode 100644 index 00000000..f750cbbc --- /dev/null +++ b/client/gui/resources/icons/arrow_hover.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b33qmctbpf48g" +path="res://.godot/imported/arrow_hover.svg-c150da1cc405914a2d4c1388aea94f6b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/arrow_hover.svg" +dest_files=["res://.godot/imported/arrow_hover.svg-c150da1cc405914a2d4c1388aea94f6b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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 +svg/scale=2.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/client/gui/resources/icons/arrow_pressed.svg b/client/gui/resources/icons/arrow_pressed.svg new file mode 100644 index 00000000..1abd9a8f --- /dev/null +++ b/client/gui/resources/icons/arrow_pressed.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/gui/resources/icons/arrow_pressed.svg.import b/client/gui/resources/icons/arrow_pressed.svg.import new file mode 100644 index 00000000..0cc07c10 --- /dev/null +++ b/client/gui/resources/icons/arrow_pressed.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://j75dbytlbju" +path="res://.godot/imported/arrow_pressed.svg-72b6835d5e0ec811cf9d5e7abb401b66.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/arrow_pressed.svg" +dest_files=["res://.godot/imported/arrow_pressed.svg-72b6835d5e0ec811cf9d5e7abb401b66.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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 +svg/scale=2.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/client/gui/resources/icons/boost.webp b/client/gui/resources/icons/boost.webp new file mode 100644 index 00000000..afea92df Binary files /dev/null and b/client/gui/resources/icons/boost.webp differ diff --git a/client/gui/resources/icons/boost.webp.import b/client/gui/resources/icons/boost.webp.import new file mode 100644 index 00000000..9fb9ddf8 --- /dev/null +++ b/client/gui/resources/icons/boost.webp.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bnxllatlo4clg" +path="res://.godot/imported/boost.webp-877bfed2e298bb49bb39ce05f703e97f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/boost.webp" +dest_files=["res://.godot/imported/boost.webp-877bfed2e298bb49bb39ce05f703e97f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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/client/gui/resources/icons/circle.svg b/client/gui/resources/icons/circle.svg new file mode 100644 index 00000000..05fab1cb --- /dev/null +++ b/client/gui/resources/icons/circle.svg @@ -0,0 +1 @@ + diff --git a/client/gui/resources/icons/circle.svg.import b/client/gui/resources/icons/circle.svg.import new file mode 100644 index 00000000..d49f9bc4 --- /dev/null +++ b/client/gui/resources/icons/circle.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d2xf8qdh01e41" +path="res://.godot/imported/circle.svg-87329764c20f8477bea7d035824f68a6.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/circle.svg" +dest_files=["res://.godot/imported/circle.svg-87329764c20f8477bea7d035824f68a6.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/client/gui/resources/icons/controller_x.svg b/client/gui/resources/icons/controller_x.svg new file mode 100644 index 00000000..9a5df2ea --- /dev/null +++ b/client/gui/resources/icons/controller_x.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/client/gui/resources/icons/controller_x.svg.import b/client/gui/resources/icons/controller_x.svg.import new file mode 100644 index 00000000..568c8672 --- /dev/null +++ b/client/gui/resources/icons/controller_x.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bsx6fo7mv2u6a" +path="res://.godot/imported/controller_x.svg-84020d372efbd30d861ba44f5b1c1f7a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/controller_x.svg" +dest_files=["res://.godot/imported/controller_x.svg-84020d372efbd30d861ba44f5b1c1f7a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/client/gui/resources/icons/controller_y.svg b/client/gui/resources/icons/controller_y.svg new file mode 100644 index 00000000..a378078b --- /dev/null +++ b/client/gui/resources/icons/controller_y.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/client/gui/resources/icons/controller_y.svg.import b/client/gui/resources/icons/controller_y.svg.import new file mode 100644 index 00000000..f3f67231 --- /dev/null +++ b/client/gui/resources/icons/controller_y.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cr2a6ide6vnnv" +path="res://.godot/imported/controller_y.svg-a116dee9a585fceb0e69cea069bc92d3.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/controller_y.svg" +dest_files=["res://.godot/imported/controller_y.svg-a116dee9a585fceb0e69cea069bc92d3.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/client/gui/resources/icons/hint.svg b/client/gui/resources/icons/hint.svg new file mode 100644 index 00000000..ad64de91 --- /dev/null +++ b/client/gui/resources/icons/hint.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/client/gui/resources/icons/hint.svg.import b/client/gui/resources/icons/hint.svg.import new file mode 100644 index 00000000..841acfb5 --- /dev/null +++ b/client/gui/resources/icons/hint.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b2uv5rf0enikf" +path="res://.godot/imported/hint.svg-d7d8c196848a6c538326a5f8ec385b64.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/hint.svg" +dest_files=["res://.godot/imported/hint.svg-d7d8c196848a6c538326a5f8ec385b64.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/client/gui/resources/icons/interact.webp b/client/gui/resources/icons/interact.webp new file mode 100644 index 00000000..cf57c4c0 Binary files /dev/null and b/client/gui/resources/icons/interact.webp differ diff --git a/client/gui/resources/icons/interact.webp.import b/client/gui/resources/icons/interact.webp.import new file mode 100644 index 00000000..64d375eb --- /dev/null +++ b/client/gui/resources/icons/interact.webp.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dcgt82qkya880" +path="res://.godot/imported/interact.webp-ba4dc2c22b6ace23a59d368b045b45ae.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/interact.webp" +dest_files=["res://.godot/imported/interact.webp-ba4dc2c22b6ace23a59d368b045b45ae.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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/client/gui/resources/icons/pause.webp b/client/gui/resources/icons/pause.webp new file mode 100644 index 00000000..24ec72d8 Binary files /dev/null and b/client/gui/resources/icons/pause.webp differ diff --git a/client/gui/resources/icons/pause.webp.import b/client/gui/resources/icons/pause.webp.import new file mode 100644 index 00000000..a79d5b1e --- /dev/null +++ b/client/gui/resources/icons/pause.webp.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://qto5rj6wlaeb" +path="res://.godot/imported/pause.webp-59d9c713545753734e408e3bcfa465c6.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/pause.webp" +dest_files=["res://.godot/imported/pause.webp-59d9c713545753734e408e3bcfa465c6.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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/client/gui/resources/icons/plus.svg b/client/gui/resources/icons/plus.svg new file mode 100644 index 00000000..c79169ba --- /dev/null +++ b/client/gui/resources/icons/plus.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/client/gui/resources/icons/plus.svg.import b/client/gui/resources/icons/plus.svg.import new file mode 100644 index 00000000..98e9bf8e --- /dev/null +++ b/client/gui/resources/icons/plus.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cnfjbowd2i02r" +path="res://.godot/imported/plus.svg-5dcb9f0bf2e5a1c55b74537b98e2ec06.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/plus.svg" +dest_files=["res://.godot/imported/plus.svg-5dcb9f0bf2e5a1c55b74537b98e2ec06.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/client/gui/resources/icons/reset.svg b/client/gui/resources/icons/reset.svg new file mode 100644 index 00000000..660d7759 --- /dev/null +++ b/client/gui/resources/icons/reset.svg @@ -0,0 +1,39 @@ + + + + + + diff --git a/client/gui/resources/icons/reset.svg.import b/client/gui/resources/icons/reset.svg.import new file mode 100644 index 00000000..16ba79b7 --- /dev/null +++ b/client/gui/resources/icons/reset.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cucnmy0j5n8l8" +path="res://.godot/imported/reset.svg-0004b05ae1181f52f03d82241e998f81.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/reset.svg" +dest_files=["res://.godot/imported/reset.svg-0004b05ae1181f52f03d82241e998f81.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/client/gui/resources/icons/select_directory.svg b/client/gui/resources/icons/select_directory.svg new file mode 100644 index 00000000..d3de2ef5 --- /dev/null +++ b/client/gui/resources/icons/select_directory.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/gui/resources/icons/select_directory.svg.import b/client/gui/resources/icons/select_directory.svg.import new file mode 100644 index 00000000..020fbd97 --- /dev/null +++ b/client/gui/resources/icons/select_directory.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://kxer318lo1oj" +path="res://.godot/imported/select_directory.svg-412137f7e6d959d951f8a9fb909150e5.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/select_directory.svg" +dest_files=["res://.godot/imported/select_directory.svg-412137f7e6d959d951f8a9fb909150e5.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/client/gui/resources/icons/select_file.svg b/client/gui/resources/icons/select_file.svg new file mode 100644 index 00000000..f44866de --- /dev/null +++ b/client/gui/resources/icons/select_file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/gui/resources/icons/select_file.svg.import b/client/gui/resources/icons/select_file.svg.import new file mode 100644 index 00000000..fe57469a --- /dev/null +++ b/client/gui/resources/icons/select_file.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bsw8vqebvc38c" +path="res://.godot/imported/select_file.svg-c2b2816e900869263e022805bb92f83c.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/select_file.svg" +dest_files=["res://.godot/imported/select_file.svg-c2b2816e900869263e022805bb92f83c.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/client/gui/resources/icons/user.webp b/client/gui/resources/icons/user.webp new file mode 100644 index 00000000..5bba0540 Binary files /dev/null and b/client/gui/resources/icons/user.webp differ diff --git a/client/gui/resources/icons/user.webp.import b/client/gui/resources/icons/user.webp.import new file mode 100644 index 00000000..3a21e21d --- /dev/null +++ b/client/gui/resources/icons/user.webp.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://222w1wha75od" +path="res://.godot/imported/user.webp-0851517d1d18a09719e1adf5c0bc8b2e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/user.webp" +dest_files=["res://.godot/imported/user.webp-0851517d1d18a09719e1adf5c0bc8b2e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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/client/gui/resources/materials/blur_material.tres b/client/gui/resources/materials/blur_material.tres new file mode 100644 index 00000000..a0e9d58c --- /dev/null +++ b/client/gui/resources/materials/blur_material.tres @@ -0,0 +1,11 @@ +[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://2j8a0c0a2ta5"] + +[ext_resource type="Shader" uid="uid://cwldxegcj55if" path="res://gui/resources/shaders/blur_mix.gdshader" id="1_d16rd"] + +[resource] +shader = ExtResource("1_d16rd") +shader_parameter/blur_amount = 3.5 +shader_parameter/mix_amount = 0.3 +shader_parameter/mix_amount_no_blur = 0.5 +shader_parameter/color_over = null +shader_parameter/enable_blur = false diff --git a/client/gui/resources/materials/dark_blur_material.tres b/client/gui/resources/materials/dark_blur_material.tres new file mode 100644 index 00000000..96cf1d3f --- /dev/null +++ b/client/gui/resources/materials/dark_blur_material.tres @@ -0,0 +1,11 @@ +[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://beea1pc5nt67r"] + +[ext_resource type="Shader" uid="uid://cwldxegcj55if" path="res://gui/resources/shaders/blur_mix.gdshader" id="1_cynu0"] + +[resource] +shader = ExtResource("1_cynu0") +shader_parameter/blur_amount = 3.5 +shader_parameter/mix_amount = 0.5 +shader_parameter/mix_amount_no_blur = 0.7 +shader_parameter/color_over = null +shader_parameter/enable_blur = null diff --git a/client/gui/resources/materials/grayscale_material.tres b/client/gui/resources/materials/grayscale_material.tres new file mode 100644 index 00000000..236ad443 --- /dev/null +++ b/client/gui/resources/materials/grayscale_material.tres @@ -0,0 +1,6 @@ +[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://bplhkekj6rebp"] + +[ext_resource type="Shader" uid="uid://qjrh2imc53u1" path="res://gui/resources/shaders/grayscale.gdshader" id="1_u0c2c"] + +[resource] +shader = ExtResource("1_u0c2c") diff --git a/client/gui/resources/materials/printed_material.tres b/client/gui/resources/materials/printed_material.tres new file mode 100644 index 00000000..3cc4a88c --- /dev/null +++ b/client/gui/resources/materials/printed_material.tres @@ -0,0 +1,6 @@ +[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://dogdyoqrmy6ft"] + +[ext_resource type="Shader" uid="uid://5p1xlwoc8qe5" path="res://gui/resources/shaders/printed.gdshader" id="1_sevww"] + +[resource] +shader = ExtResource("1_sevww") diff --git a/client/gui/resources/shaders/blur_mix.gdshader b/client/gui/resources/shaders/blur_mix.gdshader new file mode 100644 index 00000000..97686a54 --- /dev/null +++ b/client/gui/resources/shaders/blur_mix.gdshader @@ -0,0 +1,34 @@ +/* + Hurry Curry! - a game about cooking + Copyright (C) 2025 Hurry Curry! Contributors + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, version 3 of the License only. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +*/ +shader_type canvas_item; + +uniform float blur_amount : hint_range(-2.0, 10.0); +uniform float mix_amount : hint_range(0.0, 1.0); +uniform float mix_amount_no_blur : hint_range(0.0, 1.0); +uniform vec4 color_over: source_color; +uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap; +uniform bool enable_blur; + +void fragment() { + if (enable_blur) { + vec4 blurred = textureLod(SCREEN_TEXTURE, SCREEN_UV, blur_amount); + COLOR = mix(blurred, color_over, mix_amount); + } else { + COLOR = mix(texture(SCREEN_TEXTURE, SCREEN_UV), color_over, mix_amount_no_blur); + } +} \ No newline at end of file diff --git a/client/gui/resources/shaders/blur_mix.gdshader.uid b/client/gui/resources/shaders/blur_mix.gdshader.uid new file mode 100644 index 00000000..7279563b --- /dev/null +++ b/client/gui/resources/shaders/blur_mix.gdshader.uid @@ -0,0 +1 @@ +uid://cwldxegcj55if diff --git a/client/gui/resources/shaders/grayscale.gdshader b/client/gui/resources/shaders/grayscale.gdshader new file mode 100644 index 00000000..c058e7bf --- /dev/null +++ b/client/gui/resources/shaders/grayscale.gdshader @@ -0,0 +1,25 @@ +/* + Hurry Curry! - a game about cooking + Copyright (C) 2025 Hurry Curry! Contributors + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, version 3 of the License only. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +*/ +shader_type canvas_item; + +void fragment() { + float brightness = 0.2126 * COLOR.r + 0.7152 * COLOR.g + 0.0722 * COLOR.b; + brightness = (brightness - .5) * 2.; + COLOR.rgb = vec3(brightness); + COLOR.a *= 1. - brightness; +} diff --git a/client/gui/resources/shaders/grayscale.gdshader.uid b/client/gui/resources/shaders/grayscale.gdshader.uid new file mode 100644 index 00000000..b721a6e0 --- /dev/null +++ b/client/gui/resources/shaders/grayscale.gdshader.uid @@ -0,0 +1 @@ +uid://qjrh2imc53u1 diff --git a/client/gui/resources/shaders/paper.tres b/client/gui/resources/shaders/paper.tres new file mode 100644 index 00000000..2c681244 --- /dev/null +++ b/client/gui/resources/shaders/paper.tres @@ -0,0 +1,14 @@ +[gd_resource type="NoiseTexture2D" load_steps=3 format=3 uid="uid://chxkwohi56cxx"] + +[sub_resource type="Gradient" id="Gradient_pkrjd"] +colors = PackedColorArray(0.917969, 0.866454, 0.770122, 1, 0.832031, 0.781817, 0.666307, 1) + +[sub_resource type="FastNoiseLite" id="FastNoiseLite_k7p6k"] +noise_type = 0 +frequency = 0.0084 +domain_warp_enabled = true +domain_warp_frequency = -1.465 + +[resource] +color_ramp = SubResource("Gradient_pkrjd") +noise = SubResource("FastNoiseLite_k7p6k") diff --git a/client/gui/resources/shaders/printed.gdshader b/client/gui/resources/shaders/printed.gdshader new file mode 100644 index 00000000..c24cb679 --- /dev/null +++ b/client/gui/resources/shaders/printed.gdshader @@ -0,0 +1,22 @@ +/* + Hurry Curry! - a game about cooking + Copyright (C) 2025 Hurry Curry! Contributors + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, version 3 of the License only. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +*/ +shader_type canvas_item; + +void fragment() { + COLOR = floor(COLOR*5.)/5.; +} diff --git a/client/gui/resources/shaders/printed.gdshader.uid b/client/gui/resources/shaders/printed.gdshader.uid new file mode 100644 index 00000000..7c5fe12e --- /dev/null +++ b/client/gui/resources/shaders/printed.gdshader.uid @@ -0,0 +1 @@ +uid://5p1xlwoc8qe5 diff --git a/client/gui/resources/sounds/click.ogg b/client/gui/resources/sounds/click.ogg new file mode 100644 index 00000000..db4aaf4e Binary files /dev/null and b/client/gui/resources/sounds/click.ogg differ diff --git a/client/gui/resources/sounds/click.ogg.import b/client/gui/resources/sounds/click.ogg.import new file mode 100644 index 00000000..4c4604ec --- /dev/null +++ b/client/gui/resources/sounds/click.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://cpyn511c5mtni" +path="res://.godot/imported/click.ogg-ec24cb35b5d300c7ddbb1f50c2522ac5.oggvorbisstr" + +[deps] + +source_file="res://gui/resources/sounds/click.ogg" +dest_files=["res://.godot/imported/click.ogg-ec24cb35b5d300c7ddbb1f50c2522ac5.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/client/gui/resources/sounds/failure.ogg b/client/gui/resources/sounds/failure.ogg new file mode 100644 index 00000000..ef6d6ea4 Binary files /dev/null and b/client/gui/resources/sounds/failure.ogg differ diff --git a/client/gui/resources/sounds/failure.ogg.import b/client/gui/resources/sounds/failure.ogg.import new file mode 100644 index 00000000..495c1d96 --- /dev/null +++ b/client/gui/resources/sounds/failure.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://cv4isy6po6pqd" +path="res://.godot/imported/failure.ogg-cf79159cd8bc7c6cb1fc08dc9f16fc65.oggvorbisstr" + +[deps] + +source_file="res://gui/resources/sounds/failure.ogg" +dest_files=["res://.godot/imported/failure.ogg-cf79159cd8bc7c6cb1fc08dc9f16fc65.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/client/gui/resources/sounds/game_start.ogg b/client/gui/resources/sounds/game_start.ogg new file mode 100644 index 00000000..3282ff99 Binary files /dev/null and b/client/gui/resources/sounds/game_start.ogg differ diff --git a/client/gui/resources/sounds/game_start.ogg.import b/client/gui/resources/sounds/game_start.ogg.import new file mode 100644 index 00000000..79e28ada --- /dev/null +++ b/client/gui/resources/sounds/game_start.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://dft3m8utnxhs7" +path="res://.godot/imported/game_start.ogg-94857aa980bf125ce248d75f3d2a8bc2.oggvorbisstr" + +[deps] + +source_file="res://gui/resources/sounds/game_start.ogg" +dest_files=["res://.godot/imported/game_start.ogg-94857aa980bf125ce248d75f3d2a8bc2.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/client/gui/resources/sounds/hover.ogg b/client/gui/resources/sounds/hover.ogg new file mode 100644 index 00000000..17d414ca Binary files /dev/null and b/client/gui/resources/sounds/hover.ogg differ diff --git a/client/gui/resources/sounds/hover.ogg.import b/client/gui/resources/sounds/hover.ogg.import new file mode 100644 index 00000000..0bb47b0d --- /dev/null +++ b/client/gui/resources/sounds/hover.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://dtr1khfyqr56o" +path="res://.godot/imported/hover.ogg-604c32500c7d24a64b5d68b6146e31cc.oggvorbisstr" + +[deps] + +source_file="res://gui/resources/sounds/hover.ogg" +dest_files=["res://.godot/imported/hover.ogg-604c32500c7d24a64b5d68b6146e31cc.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/client/gui/resources/sounds/page.ogg b/client/gui/resources/sounds/page.ogg new file mode 100644 index 00000000..3038a8d9 Binary files /dev/null and b/client/gui/resources/sounds/page.ogg differ diff --git a/client/gui/resources/sounds/page.ogg.import b/client/gui/resources/sounds/page.ogg.import new file mode 100644 index 00000000..9c65dc93 --- /dev/null +++ b/client/gui/resources/sounds/page.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://do7ii5hx71p0m" +path="res://.godot/imported/page.ogg-0b33370bdbe86f4cddfd8a42d8f62a5d.oggvorbisstr" + +[deps] + +source_file="res://gui/resources/sounds/page.ogg" +dest_files=["res://.godot/imported/page.ogg-0b33370bdbe86f4cddfd8a42d8f62a5d.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/client/gui/resources/sounds/sign.ogg b/client/gui/resources/sounds/sign.ogg new file mode 100644 index 00000000..8811c50a Binary files /dev/null and b/client/gui/resources/sounds/sign.ogg differ diff --git a/client/gui/resources/sounds/sign.ogg.import b/client/gui/resources/sounds/sign.ogg.import new file mode 100644 index 00000000..8e524403 --- /dev/null +++ b/client/gui/resources/sounds/sign.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://5b3noxjmasmu" +path="res://.godot/imported/sign.ogg-9091117f7048611453ca1b0853de53ea.oggvorbisstr" + +[deps] + +source_file="res://gui/resources/sounds/sign.ogg" +dest_files=["res://.godot/imported/sign.ogg-9091117f7048611453ca1b0853de53ea.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/client/gui/resources/sounds/success.ogg b/client/gui/resources/sounds/success.ogg new file mode 100644 index 00000000..37cd2bcd Binary files /dev/null and b/client/gui/resources/sounds/success.ogg differ diff --git a/client/gui/resources/sounds/success.ogg.import b/client/gui/resources/sounds/success.ogg.import new file mode 100644 index 00000000..1c42b2e5 --- /dev/null +++ b/client/gui/resources/sounds/success.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://camy77x26mmpv" +path="res://.godot/imported/success.ogg-d726a1955ea1a9943ae576d6eb7645bb.oggvorbisstr" + +[deps] + +source_file="res://gui/resources/sounds/success.ogg" +dest_files=["res://.godot/imported/success.ogg-d726a1955ea1a9943ae576d6eb7645bb.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/client/gui/resources/style/error_focus_style.tres b/client/gui/resources/style/error_focus_style.tres new file mode 100644 index 00000000..f7c44505 --- /dev/null +++ b/client/gui/resources/style/error_focus_style.tres @@ -0,0 +1,17 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://devnduinj535f"] + +[resource] +content_margin_left = 10.0 +content_margin_top = 10.0 +content_margin_right = 10.0 +content_margin_bottom = 10.0 +bg_color = Color(1, 0, 0, 0.12549) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(1, 0.81804, 0.818076, 1) +corner_radius_top_left = 5 +corner_radius_top_right = 5 +corner_radius_bottom_right = 5 +corner_radius_bottom_left = 5 diff --git a/client/gui/resources/style/focus_style.tres b/client/gui/resources/style/focus_style.tres new file mode 100644 index 00000000..a01843fe --- /dev/null +++ b/client/gui/resources/style/focus_style.tres @@ -0,0 +1,17 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://b86kbd3pfkd5w"] + +[resource] +content_margin_left = 10.0 +content_margin_top = 10.0 +content_margin_right = 10.0 +content_margin_bottom = 10.0 +bg_color = Color(1, 1, 1, 0.0627451) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.818673, 0.926505, 1, 1) +corner_radius_top_left = 5 +corner_radius_top_right = 5 +corner_radius_bottom_right = 5 +corner_radius_bottom_left = 5 diff --git a/client/gui/resources/style/hover_style.tres b/client/gui/resources/style/hover_style.tres new file mode 100644 index 00000000..963ee2ca --- /dev/null +++ b/client/gui/resources/style/hover_style.tres @@ -0,0 +1,12 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://dua4jqje3704w"] + +[resource] +content_margin_left = 10.0 +content_margin_top = 10.0 +content_margin_right = 10.0 +content_margin_bottom = 10.0 +bg_color = Color(1, 1, 1, 0.266667) +corner_radius_top_left = 5 +corner_radius_top_right = 5 +corner_radius_bottom_right = 5 +corner_radius_bottom_left = 5 diff --git a/client/gui/resources/style/item_bubble_progress_style.tres b/client/gui/resources/style/item_bubble_progress_style.tres new file mode 100644 index 00000000..68054918 --- /dev/null +++ b/client/gui/resources/style/item_bubble_progress_style.tres @@ -0,0 +1,5 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://brw8uogdgx2gf"] + +[resource] +resource_local_to_scene = true +bg_color = Color(0.501961, 0, 0, 1) diff --git a/client/gui/resources/style/item_bubble_progress_style_background.tres b/client/gui/resources/style/item_bubble_progress_style_background.tres new file mode 100644 index 00000000..972b7055 --- /dev/null +++ b/client/gui/resources/style/item_bubble_progress_style_background.tres @@ -0,0 +1,4 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://cu0his4018e7h"] + +[resource] +resource_local_to_scene = true diff --git a/client/gui/resources/style/lobby_panel_override.tres b/client/gui/resources/style/lobby_panel_override.tres new file mode 100644 index 00000000..04fd16b0 --- /dev/null +++ b/client/gui/resources/style/lobby_panel_override.tres @@ -0,0 +1,4 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://de80aw86emnql"] + +[resource] +bg_color = Color(0.0941176, 0.0941176, 0.0941176, 1) diff --git a/client/gui/resources/style/normal_style.tres b/client/gui/resources/style/normal_style.tres new file mode 100644 index 00000000..96aecc8e --- /dev/null +++ b/client/gui/resources/style/normal_style.tres @@ -0,0 +1,12 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://pi5uhe0lrgka"] + +[resource] +content_margin_left = 10.0 +content_margin_top = 10.0 +content_margin_right = 10.0 +content_margin_bottom = 10.0 +bg_color = Color(1, 1, 1, 0.0352941) +corner_radius_top_left = 5 +corner_radius_top_right = 5 +corner_radius_bottom_right = 5 +corner_radius_bottom_left = 5 diff --git a/client/gui/resources/style/panel_style.tres b/client/gui/resources/style/panel_style.tres new file mode 100644 index 00000000..d1f27667 --- /dev/null +++ b/client/gui/resources/style/panel_style.tres @@ -0,0 +1,8 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://bcd4xcvtv7tws"] + +[resource] +bg_color = Color(0, 0, 0, 0.6) +corner_radius_top_left = 8 +corner_radius_top_right = 8 +corner_radius_bottom_right = 8 +corner_radius_bottom_left = 8 diff --git a/client/gui/resources/style/panel_style_sidebar.tres b/client/gui/resources/style/panel_style_sidebar.tres new file mode 100644 index 00000000..9615d88b --- /dev/null +++ b/client/gui/resources/style/panel_style_sidebar.tres @@ -0,0 +1,3 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://bw4jamyna1top"] + +[resource] diff --git a/client/gui/resources/style/paper_panel_style.tres b/client/gui/resources/style/paper_panel_style.tres new file mode 100644 index 00000000..effa2310 --- /dev/null +++ b/client/gui/resources/style/paper_panel_style.tres @@ -0,0 +1,6 @@ +[gd_resource type="StyleBoxTexture" load_steps=2 format=3 uid="uid://bqhs5wtdp2oax"] + +[ext_resource type="Texture2D" uid="uid://chxkwohi56cxx" path="res://gui/resources/shaders/paper.tres" id="1_u1kqj"] + +[resource] +texture = ExtResource("1_u1kqj") diff --git a/client/gui/resources/theme/paper.tres b/client/gui/resources/theme/paper.tres new file mode 100644 index 00000000..41417f39 --- /dev/null +++ b/client/gui/resources/theme/paper.tres @@ -0,0 +1,109 @@ +[gd_resource type="Theme" load_steps=17 format=3 uid="uid://ci2qajdoa1an1"] + +[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://gui/resources/fonts/font-sansita-swashed.woff2" id="1_koj1m"] +[ext_resource type="FontFile" uid="uid://5ixo6b3bd3km" path="res://gui/resources/fonts/font-josefin-sans.woff2" id="1_tc8bk"] + +[sub_resource type="FontVariation" id="FontVariation_pirkj"] +base_font = ExtResource("1_tc8bk") +variation_embolden = 0.5 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_l5fao"] +bg_color = Color(0, 0, 0, 0.305882) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.819608, 0.92549, 1, 1) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_3p3im"] +bg_color = Color(0, 0, 0, 0.145098) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_xxmhf"] +bg_color = Color(0, 0, 0, 0.305882) + +[sub_resource type="SystemFont" id="SystemFont_3j83h"] +font_names = PackedStringArray("Noto Sans") + +[sub_resource type="FontVariation" id="FontVariation_8qr07"] +base_font = SubResource("SystemFont_3j83h") +variation_embolden = -0.44 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_rq65v"] +content_margin_left = 10.0 +bg_color = Color(1, 1, 1, 0) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_st08c"] +content_margin_left = 10.0 +bg_color = Color(0, 0, 0, 0) +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 +border_color = Color(0.300781, 0.300781, 0.300781, 1) +corner_radius_top_left = 5 +corner_radius_top_right = 5 +corner_radius_bottom_right = 5 +corner_radius_bottom_left = 5 + +[sub_resource type="StyleBoxLine" id="StyleBoxLine_8q7ob"] +thickness = 3 + +[sub_resource type="FontVariation" id="FontVariation_cx2xx"] +base_font = ExtResource("1_koj1m") + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_huhkg"] +content_margin_left = 10.0 +bg_color = Color(0.6, 0.6, 0.6, 0) +border_width_bottom = 2 +border_color = Color(0, 0, 0, 1) + +[sub_resource type="SystemFont" id="SystemFont_c2823"] + +[sub_resource type="FontVariation" id="FontVariation_c3ws0"] +base_font = SubResource("SystemFont_c2823") +variation_embolden = 0.53 + +[sub_resource type="FontVariation" id="FontVariation_ex8wc"] +base_font = SubResource("SystemFont_3j83h") +variation_embolden = -0.44 + +[resource] +Button/colors/font_color = Color(0.21875, 0.21875, 0.21875, 1) +Button/fonts/font = SubResource("FontVariation_pirkj") +Button/styles/focus = SubResource("StyleBoxFlat_l5fao") +Button/styles/hover = SubResource("StyleBoxFlat_3p3im") +Button/styles/normal = SubResource("StyleBoxFlat_xxmhf") +Button/styles/pressed = SubResource("StyleBoxFlat_xxmhf") +CheckBox/colors/font_color = Color(0, 0, 0, 1) +CheckBox/colors/font_disabled_color = Color(0, 0, 0, 1) +CheckBox/colors/font_focus_color = Color(0, 0, 0, 1) +CheckBox/colors/font_hover_color = Color(0, 0, 0, 1) +CheckBox/colors/font_hover_pressed_color = Color(0, 0, 0, 1) +CheckBox/colors/font_pressed_color = Color(0, 0, 0, 1) +CheckBox/constants/h_separation = 4 +CheckBox/fonts/font = SubResource("FontVariation_8qr07") +CheckBox/styles/disabled = SubResource("StyleBoxFlat_rq65v") +CheckBox/styles/focus = SubResource("StyleBoxFlat_st08c") +CheckBox/styles/hover = SubResource("StyleBoxFlat_rq65v") +CheckBox/styles/hover_pressed = SubResource("StyleBoxFlat_rq65v") +CheckBox/styles/normal = SubResource("StyleBoxFlat_rq65v") +CheckBox/styles/pressed = SubResource("StyleBoxFlat_rq65v") +HSeparator/constants/separation = 6 +HSeparator/styles/separator = SubResource("StyleBoxLine_8q7ob") +Label/colors/font_color = Color(0, 0, 0, 1) +LineEdit/colors/caret_color = Color(0, 0.0209808, 0.414062, 1) +LineEdit/colors/font_color = Color(0, 0.0196078, 0.415686, 1) +LineEdit/fonts/font = SubResource("FontVariation_cx2xx") +LineEdit/styles/focus = SubResource("StyleBoxFlat_huhkg") +LineEdit/styles/normal = SubResource("StyleBoxFlat_huhkg") +LineEdit/styles/read_only = SubResource("StyleBoxFlat_huhkg") +MarginContainer/constants/margin_bottom = 30 +MarginContainer/constants/margin_left = 70 +MarginContainer/constants/margin_right = 30 +MarginContainer/constants/margin_top = 30 +RichTextLabel/colors/default_color = Color(0, 0, 0, 1) +RichTextLabel/fonts/bold_font = SubResource("FontVariation_c3ws0") +RichTextLabel/fonts/bold_italics_font = null +RichTextLabel/fonts/italics_font = null +RichTextLabel/fonts/mono_font = null +RichTextLabel/fonts/normal_font = SubResource("FontVariation_ex8wc") diff --git a/client/gui/resources/theme/theme.tres b/client/gui/resources/theme/theme.tres new file mode 100644 index 00000000..ca87a81c --- /dev/null +++ b/client/gui/resources/theme/theme.tres @@ -0,0 +1,70 @@ +[gd_resource type="Theme" load_steps=12 format=3 uid="uid://b0qmvo504e457"] + +[ext_resource type="FontFile" uid="uid://5ixo6b3bd3km" path="res://gui/resources/fonts/font-josefin-sans.woff2" id="1_f8qb0"] +[ext_resource type="StyleBox" uid="uid://b86kbd3pfkd5w" path="res://gui/resources/style/focus_style.tres" id="1_x88rs"] +[ext_resource type="StyleBox" uid="uid://pi5uhe0lrgka" path="res://gui/resources/style/normal_style.tres" id="2_8fwoi"] +[ext_resource type="StyleBox" uid="uid://dua4jqje3704w" path="res://gui/resources/style/hover_style.tres" id="2_ye28t"] +[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://gui/resources/fonts/font-sansita-swashed.woff2" id="3_8u6ww"] +[ext_resource type="StyleBox" uid="uid://bcd4xcvtv7tws" path="res://gui/resources/style/panel_style.tres" id="4_42dlp"] + +[sub_resource type="StyleBoxLine" id="StyleBoxLine_emtvk"] +content_margin_top = 5.0 +content_margin_bottom = 5.0 +color = Color(1, 1, 1, 1) +grow_begin = 0.0 +grow_end = 0.0 +thickness = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_25x32"] +content_margin_left = 10.0 +content_margin_top = 10.0 +content_margin_right = 10.0 +content_margin_bottom = 10.0 +bg_color = Color(1, 1, 1, 0.0352941) +corner_radius_top_left = 5 +corner_radius_top_right = 5 +corner_radius_bottom_right = 5 +corner_radius_bottom_left = 5 + +[sub_resource type="FontVariation" id="FontVariation_ff4nr"] +base_font = ExtResource("3_8u6ww") +variation_embolden = 0.7 + +[sub_resource type="FontVariation" id="FontVariation_lyo8w"] +base_font = ExtResource("1_f8qb0") +variation_embolden = 1.25 +spacing_top = 5 + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_or5ri"] + +[resource] +default_font = SubResource("FontVariation_lyo8w") +Button/font_sizes/font_size = 18 +Button/styles/disabled = ExtResource("2_8fwoi") +Button/styles/focus = ExtResource("1_x88rs") +Button/styles/hover = ExtResource("2_ye28t") +Button/styles/normal = ExtResource("2_8fwoi") +Button/styles/pressed = ExtResource("2_8fwoi") +CheckButton/font_sizes/font_size = 18 +CheckButton/styles/disabled = ExtResource("2_8fwoi") +CheckButton/styles/focus = ExtResource("1_x88rs") +CheckButton/styles/hover = ExtResource("2_ye28t") +CheckButton/styles/hover_pressed = ExtResource("2_ye28t") +CheckButton/styles/normal = ExtResource("2_8fwoi") +CheckButton/styles/pressed = ExtResource("2_8fwoi") +HSeparator/styles/separator = SubResource("StyleBoxLine_emtvk") +Label/font_sizes/font_size = 16 +LineEdit/styles/focus = ExtResource("1_x88rs") +LineEdit/styles/normal = SubResource("StyleBoxFlat_25x32") +LineEdit/styles/read_only = SubResource("StyleBoxFlat_25x32") +MarginContainer/constants/margin_bottom = 32 +MarginContainer/constants/margin_left = 32 +MarginContainer/constants/margin_right = 32 +MarginContainer/constants/margin_top = 32 +Panel/styles/panel = ExtResource("4_42dlp") +PanelContainer/styles/panel = ExtResource("4_42dlp") +RichTextLabel/fonts/bold_font = SubResource("FontVariation_ff4nr") +RichTextLabel/fonts/bold_italics_font = SubResource("FontVariation_lyo8w") +RichTextLabel/fonts/italics_font = SubResource("FontVariation_lyo8w") +RichTextLabel/fonts/mono_font = SubResource("FontVariation_lyo8w") +TabContainer/styles/panel = SubResource("StyleBoxEmpty_or5ri") -- cgit v1.2.3-70-g09d2