aboutsummaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/.gitignore1
-rw-r--r--client/README.md19
-rw-r--r--client/audio/music/error.oggbin0 -> 34768 bytes
-rw-r--r--client/audio/music/error.ogg.import19
-rw-r--r--client/audio/music/reflets-dans-leau.oggbin0 -> 966492 bytes
-rw-r--r--client/audio/music/reflets-dans-leau.ogg.import19
-rw-r--r--client/audio/play_random.gd2
-rw-r--r--client/audio/play_random.tscn4
-rw-r--r--client/audio/sound.gd106
-rw-r--r--client/audio/sound.tscn22
-rw-r--r--client/default_bus_layout.tres12
-rw-r--r--client/export_presets.cfg582
-rw-r--r--client/game.gd313
-rw-r--r--client/game.tscn14
-rw-r--r--client/global.gd54
-rw-r--r--client/gui/components/blur_setup.gd4
-rw-r--r--client/gui/components/controller_button.gd2
-rw-r--r--client/gui/components/message/chat_message.gd2
-rw-r--r--client/gui/components/message/chat_message.tscn14
-rw-r--r--client/gui/components/message/item/item_message.gd2
-rw-r--r--client/gui/components/message/item/item_message.tscn14
-rw-r--r--client/gui/components/message/item/item_render.gd2
-rw-r--r--client/gui/components/message/item/item_render.tscn10
-rw-r--r--client/gui/components/message/renderer.gd34
-rw-r--r--client/gui/components/message/renderer.gd.uid1
-rw-r--r--client/gui/components/message/renderer.tscn43
-rw-r--r--client/gui/components/smart_margin_container.gd2
-rw-r--r--client/gui/components/touch_scroll_container.gd2
-rw-r--r--client/gui/menus/book/book.gd117
-rw-r--r--client/gui/menus/book/book.gd.uid1
-rw-r--r--client/gui/menus/book/book.tscn110
-rw-r--r--client/gui/menus/book/diagram.gd124
-rw-r--r--client/gui/menus/book/diagram.gd.uid1
-rw-r--r--client/gui/menus/character.gd8
-rw-r--r--client/gui/menus/character.tscn77
-rw-r--r--client/gui/menus/chat.gd2
-rw-r--r--client/gui/menus/chat.tscn18
-rw-r--r--client/gui/menus/document/document.gd152
-rw-r--r--client/gui/menus/document/document.gd.uid1
-rw-r--r--client/gui/menus/document/document.tscn29
-rw-r--r--client/gui/menus/entry.gd5
-rw-r--r--client/gui/menus/entry.tscn4
-rw-r--r--client/gui/menus/error.gd4
-rw-r--r--client/gui/menus/error.tscn32
-rw-r--r--client/gui/menus/game.gd21
-rw-r--r--client/gui/menus/game.tscn8
-rw-r--r--client/gui/menus/ingame.gd4
-rw-r--r--client/gui/menus/ingame.tscn38
-rw-r--r--client/gui/menus/main/about.gd82
-rw-r--r--client/gui/menus/main/about.tscn34
-rw-r--r--client/gui/menus/main/background.gd65
-rw-r--r--client/gui/menus/main/background.tscn14
-rw-r--r--client/gui/menus/main/clouds.gdshader2
-rw-r--r--client/gui/menus/main/main.gd10
-rw-r--r--client/gui/menus/main/main.tscn30
-rw-r--r--client/gui/menus/main/play.gd32
-rw-r--r--client/gui/menus/main/play.tscn52
-rw-r--r--client/gui/menus/main/server_list_item.gd24
-rw-r--r--client/gui/menus/main/server_list_item.tscn30
-rw-r--r--client/gui/menus/map_selector/map_details_selector.gd120
-rw-r--r--client/gui/menus/map_selector/map_details_selector.gd.uid1
-rw-r--r--client/gui/menus/map_selector/map_details_selector.tscn112
-rw-r--r--client/gui/menus/map_selector/map_list_item.gd28
-rw-r--r--client/gui/menus/map_selector/map_list_item.gd.uid1
-rw-r--r--client/gui/menus/map_selector/map_list_item.tscn59
-rw-r--r--client/gui/menus/map_selector/map_selector.gd43
-rw-r--r--client/gui/menus/map_selector/map_selector.gd.uid1
-rw-r--r--client/gui/menus/map_selector/map_selector.tscn76
-rw-r--r--client/gui/menus/menu.gd70
-rw-r--r--client/gui/menus/popup.gd2
-rw-r--r--client/gui/menus/popup.tscn20
-rw-r--r--client/gui/menus/popup_large.gd5
-rw-r--r--client/gui/menus/popup_large.tscn25
-rw-r--r--client/gui/menus/rating/rating.gd10
-rw-r--r--client/gui/menus/rating/rating.tscn48
-rw-r--r--client/gui/menus/scoreboard.gd49
-rw-r--r--client/gui/menus/scoreboard.gd.uid1
-rw-r--r--client/gui/menus/scoreboard.tscn114
-rw-r--r--client/gui/menus/screen_info.tscn62
-rw-r--r--client/gui/menus/settings/button_setting.gd2
-rw-r--r--client/gui/menus/settings/dropdown_setting.gd11
-rw-r--r--client/gui/menus/settings/game_setting.gd4
-rw-r--r--client/gui/menus/settings/input/input_manager.gd4
-rw-r--r--client/gui/menus/settings/input/input_setting.gd4
-rw-r--r--client/gui/menus/settings/input/input_value_node.gd2
-rw-r--r--client/gui/menus/settings/input/input_value_node.tscn8
-rw-r--r--client/gui/menus/settings/number_setting.gd4
-rw-r--r--client/gui/menus/settings/path_setting.gd2
-rw-r--r--client/gui/menus/settings/preset_row.gd2
-rw-r--r--client/gui/menus/settings/range_setting.gd4
-rw-r--r--client/gui/menus/settings/settings.gd6
-rw-r--r--client/gui/menus/settings/settings.tscn18
-rw-r--r--client/gui/menus/settings/settings_category.gd2
-rw-r--r--client/gui/menus/settings/settings_root.gd2
-rw-r--r--client/gui/menus/settings/settings_row.gd2
-rw-r--r--client/gui/menus/settings/settings_row.tscn16
-rw-r--r--client/gui/menus/settings/text_setting.gd4
-rw-r--r--client/gui/menus/settings/toggle_setting.gd4
-rw-r--r--client/gui/menus/setup/hairstyle_preview.gd2
-rw-r--r--client/gui/menus/setup/hairstyle_preview.tscn22
-rw-r--r--client/gui/menus/setup/setup.gd2
-rw-r--r--client/gui/menus/setup/setup.tscn113
-rw-r--r--client/gui/menus/transition/scene_transition.gd6
-rw-r--r--client/gui/menus/transition/scene_transition.tscn24
-rw-r--r--client/gui/overlays/announce_title.gd2
-rw-r--r--client/gui/overlays/announce_title.tscn20
-rw-r--r--client/gui/overlays/chat.gd2
-rw-r--r--client/gui/overlays/chat.tscn18
-rw-r--r--client/gui/overlays/controls_visualization/controller/controller_explanation.gd2
-rw-r--r--client/gui/overlays/controls_visualization/controller/controller_explanation.tscn34
-rw-r--r--client/gui/overlays/controls_visualization/device_explanation.gd2
-rw-r--r--client/gui/overlays/controls_visualization/explanation.gd6
-rw-r--r--client/gui/overlays/controls_visualization/explanation.tscn24
-rw-r--r--client/gui/overlays/controls_visualization/keyboard/keyboard_button.tscn4
-rw-r--r--client/gui/overlays/controls_visualization/keyboard/keyboard_explanation.gd2
-rw-r--r--client/gui/overlays/controls_visualization/keyboard/keyboard_explanation.tscn66
-rw-r--r--client/gui/overlays/debug/debug.gd4
-rw-r--r--client/gui/overlays/debug/debug.tscn9
-rw-r--r--client/gui/overlays/debug/debug_pie.gd2
-rw-r--r--client/gui/overlays/debug/pie.tscn2
-rw-r--r--client/gui/overlays/lobby/lobby.gd181
-rw-r--r--client/gui/overlays/lobby/lobby.gd.uid1
-rw-r--r--client/gui/overlays/lobby/lobby.tscn182
-rw-r--r--client/gui/overlays/lobby/player.gd2
-rw-r--r--client/gui/overlays/lobby/player.tscn18
-rw-r--r--client/gui/overlays/overlays.gd4
-rw-r--r--client/gui/overlays/overlays.tscn20
-rw-r--r--client/gui/overlays/pinned_messages.gd2
-rw-r--r--client/gui/overlays/pinned_messages.tscn6
-rw-r--r--client/gui/overlays/popup_message/font_variation.tres10
-rw-r--r--client/gui/overlays/popup_message/popup_message.gd31
-rw-r--r--client/gui/overlays/popup_message/popup_message.tscn20
-rw-r--r--client/gui/overlays/popup_message/server_message.gd66
-rw-r--r--client/gui/overlays/popup_message/server_message.tscn37
-rw-r--r--client/gui/overlays/score.gd2
-rw-r--r--client/gui/overlays/score.tscn62
-rw-r--r--client/gui/resources/fonts/sansita-swashed-bold.tres2
-rw-r--r--client/gui/resources/materials/blur_material.tres2
-rw-r--r--client/gui/resources/materials/dark_blur_material.tres4
-rw-r--r--client/gui/resources/materials/grayscale_material.tres2
-rw-r--r--client/gui/resources/materials/printed_material.tres2
-rw-r--r--client/gui/resources/shaders/blur_mix.gdshader3
-rw-r--r--client/gui/resources/shaders/clouds_canvas_item.gdshader35
-rw-r--r--client/gui/resources/shaders/clouds_canvas_item.gdshader.uid1
-rw-r--r--client/gui/resources/shaders/grayscale.gdshader2
-rw-r--r--client/gui/resources/shaders/paper.tres2
-rw-r--r--client/gui/resources/shaders/printed.gdshader2
-rw-r--r--client/gui/resources/style/error_focus_style.tres10
-rw-r--r--client/gui/resources/style/error_normal_style.tres13
-rw-r--r--client/gui/resources/style/focus_style.tres10
-rw-r--r--client/gui/resources/style/hover_style.tres10
-rw-r--r--client/gui/resources/style/normal_style.tres10
-rw-r--r--client/gui/resources/style/panel_button_backround_style.tres8
-rw-r--r--client/gui/resources/style/panel_style.tres8
-rw-r--r--client/gui/resources/style/paper_panel_style.tres2
-rw-r--r--client/gui/resources/style/square_panel_override.tres (renamed from client/gui/resources/style/lobby_panel_override.tres)0
-rw-r--r--client/gui/resources/theme/default.tres (renamed from client/gui/resources/theme/theme.tres)8
-rw-r--r--client/gui/resources/theme/paper.tres2
l---------client/locale_book1
-rw-r--r--client/makefile33
-rw-r--r--client/map/auto_setup/environment_setup.gd8
-rw-r--r--client/map/auto_setup/light_setup.gd4
-rw-r--r--client/map/auto_setup/sky_light_setup.gd2
-rw-r--r--client/map/effects/angry/angry.gd26
-rw-r--r--client/map/effects/angry/angry.gd.uid1
-rw-r--r--client/map/effects/angry/angry.tscn63
-rw-r--r--client/map/effects/angry/angry.webp (renamed from client/player/particles/angry/angry.webp)bin5022 -> 5022 bytes
-rw-r--r--client/map/effects/angry/angry.webp.import (renamed from client/player/particles/angry/angry.webp.import)6
-rw-r--r--client/map/effects/effect.gd (renamed from client/map/tiles/bun_crate.gd)13
-rw-r--r--client/map/effects/effect.gd.uid (renamed from client/player/particles/effect.gd.uid)0
-rw-r--r--client/map/effects/effect_factory.gd34
-rw-r--r--client/map/effects/effect_factory.gd.uid1
-rw-r--r--client/map/effects/points/points.gd30
-rw-r--r--client/map/effects/points/points.gd.uid1
-rw-r--r--client/map/effects/points/points.tscn90
-rw-r--r--client/map/effects/satisfied/satisfied.gd (renamed from client/map/tiles/book.gd)15
-rw-r--r--client/map/effects/satisfied/satisfied.gd.uid1
-rw-r--r--client/map/effects/satisfied/satisfied.tscn (renamed from client/player/particles/satisfied/stars.tscn)15
-rw-r--r--client/map/effects/satisfied/star.webp (renamed from client/player/particles/satisfied/star.webp)bin5818 -> 5818 bytes
-rw-r--r--client/map/effects/satisfied/star.webp.import (renamed from client/player/particles/satisfied/star.webp.import)6
-rw-r--r--client/map/environment/environment.tscn12
-rw-r--r--client/map/environment/world_environment.tscn4
-rw-r--r--client/map/item_factory.gd20
-rw-r--r--client/map/items/basket.gd6
-rw-r--r--client/map/items/basket.tscn6
-rw-r--r--client/map/items/bun.gd2
-rw-r--r--client/map/items/bun.resbin17039 -> 27248 bytes
-rw-r--r--client/map/items/bun.tscn7
-rw-r--r--client/map/items/burned.gd2
-rw-r--r--client/map/items/burned.resbin6920 -> 12546 bytes
-rw-r--r--client/map/items/burned.tscn7
-rw-r--r--client/map/items/cheese.resbin10033 -> 16062 bytes
-rw-r--r--client/map/items/cheese.tscn7
-rw-r--r--client/map/items/cheese_bit.resbin0 -> 4783 bytes
-rw-r--r--client/map/items/coconut.resbin4211 -> 7411 bytes
-rw-r--r--client/map/items/coconut.tscn14
-rw-r--r--client/map/items/cooked_cheese_pizza.tscn33
-rw-r--r--client/map/items/cooked_noodles.resbin28921 -> 40060 bytes
-rw-r--r--client/map/items/cooked_noodles.tscn7
-rw-r--r--client/map/items/cooked_rice_fill.tscn10
-rw-r--r--client/map/items/cut.tscn4
-rw-r--r--client/map/items/cuttable.gd2
-rw-r--r--client/map/items/deep_fryer_basket.resbin14274 -> 35671 bytes
-rw-r--r--client/map/items/deep_frying.tscn4
-rw-r--r--client/map/items/dirt.resbin4343 -> 7436 bytes
-rw-r--r--client/map/items/dirt.tscn7
-rw-r--r--client/map/items/donut/donut-dough.resbin0 -> 25677 bytes
-rw-r--r--client/map/items/donut/donut-glaze.resbin0 -> 41617 bytes
-rw-r--r--client/map/items/donut/donut.tscn11
-rw-r--r--client/map/items/donut/glazed-donut.tscn14
-rw-r--r--client/map/items/dough.resbin11602 -> 17066 bytes
-rw-r--r--client/map/items/dough.tscn7
-rw-r--r--client/map/items/fish.resbin28432 -> 61492 bytes
-rw-r--r--client/map/items/fish.tscn7
-rw-r--r--client/map/items/flour.resbin2775 -> 6127 bytes
-rw-r--r--client/map/items/flour.tscn7
-rw-r--r--client/map/items/food_processor.gd25
-rw-r--r--client/map/items/food_processor.resbin23958 -> 60923 bytes
-rw-r--r--client/map/items/food_processor.tscn7
-rw-r--r--client/map/items/food_processor_fill.gd2
-rw-r--r--client/map/items/food_processor_fill.resbin3141 -> 7569 bytes
-rw-r--r--client/map/items/food_processor_fill.tscn5
-rw-r--r--client/map/items/french_fries.resbin12400 -> 21661 bytes
-rw-r--r--client/map/items/french_fries_basket.tscn7
-rw-r--r--client/map/items/french_fries_fill.resbin12383 -> 21633 bytes
-rw-r--r--client/map/items/french_fries_fill.tscn7
-rw-r--r--client/map/items/generic_item.gd2
-rw-r--r--client/map/items/glass.gd2
-rw-r--r--client/map/items/glass.resbin12738 -> 21809 bytes
-rw-r--r--client/map/items/glass.tscn7
-rw-r--r--client/map/items/glass_fill.gd2
-rw-r--r--client/map/items/glass_fill.resbin7770 -> 13735 bytes
-rw-r--r--client/map/items/glass_fill.tscn5
-rw-r--r--client/map/items/glass_items.gd2
-rw-r--r--client/map/items/icecream.gd2
-rw-r--r--client/map/items/icecream.resbin4046 -> 7163 bytes
-rw-r--r--client/map/items/icecream.tscn5
-rw-r--r--client/map/items/item.gd27
-rw-r--r--client/map/items/leek.resbin11736 -> 28503 bytes
-rw-r--r--client/map/items/leek.tscn7
-rw-r--r--client/map/items/lettuce.resbin17892 -> 26213 bytes
-rw-r--r--client/map/items/lettuce.tscn7
-rw-r--r--client/map/items/lettuce_crate.gd.uid1
-rw-r--r--client/map/items/mochi.gd2
-rw-r--r--client/map/items/mochi.resbin2674 -> 4337 bytes
-rw-r--r--client/map/items/mochi.tscn5
-rw-r--r--client/map/items/mushroom.resbin16149 -> 25398 bytes
-rw-r--r--client/map/items/mushroom.tscn9
-rw-r--r--client/map/items/mushroom_plate_fill.tscn17
-rw-r--r--client/map/items/nigiri.resbin23842 -> 35052 bytes
-rw-r--r--client/map/items/nigiri.tscn7
-rw-r--r--client/map/items/noodles.resbin28873 -> 40028 bytes
-rw-r--r--client/map/items/noodles.tscn7
-rw-r--r--client/map/items/noodles_cheese_fill.tscn25
-rw-r--r--client/map/items/noodles_tomato_sauce_fill.resbin0 -> 12528 bytes
-rw-r--r--client/map/items/noodles_tomato_sauce_fill.tscn9
-rw-r--r--client/map/items/pan.gd9
-rw-r--r--client/map/items/pan.resbin12348 -> 24164 bytes
-rw-r--r--client/map/items/pan.tscn7
-rw-r--r--client/map/items/patty.resbin7807 -> 14324 bytes
-rw-r--r--client/map/items/patty.tscn7
-rw-r--r--client/map/items/pizza.gd29
-rw-r--r--client/map/items/pizza.gd.uid1
-rw-r--r--client/map/items/pizza.resbin0 -> 20609 bytes
-rw-r--r--client/map/items/pizza/cheese_pizza_topping.tscn25
-rw-r--r--client/map/items/pizza/mushroom_pizza_topping.tscn17
-rw-r--r--client/map/items/pizza/mushroom_slice.resbin0 -> 12501 bytes
-rw-r--r--client/map/items/pizza/mushroom_slice.tscn9
-rw-r--r--client/map/items/plate.gd31
-rw-r--r--client/map/items/plate.resbin6227 -> 12240 bytes
-rw-r--r--client/map/items/plate.tscn7
-rw-r--r--client/map/items/plate_fill.gd2
-rw-r--r--client/map/items/plate_fill.resbin714 -> 1704 bytes
-rw-r--r--client/map/items/plate_fill.tscn5
-rw-r--r--client/map/items/pot.gd13
-rw-r--r--client/map/items/pot.resbin11500 -> 20878 bytes
-rw-r--r--client/map/items/pot.tscn7
-rw-r--r--client/map/items/pot_fill.gd2
-rw-r--r--client/map/items/pot_fill.resbin704 -> 1696 bytes
-rw-r--r--client/map/items/pot_fill.tscn5
-rw-r--r--client/map/items/pot_fill_transparent.gd22
-rw-r--r--client/map/items/pot_fill_transparent.gd.uid1
-rw-r--r--client/map/items/potato.resbin6490 -> 11495 bytes
-rw-r--r--client/map/items/potato.tscn7
-rw-r--r--client/map/items/processing.tscn5
-rw-r--r--client/map/items/raw_pizza.tscn11
-rw-r--r--client/map/items/rice.resbin32358 -> 62610 bytes
-rw-r--r--client/map/items/rice.tscn7
-rw-r--r--client/map/items/rice_content.resbin5424 -> 10535 bytes
-rw-r--r--client/map/items/rice_content.tscn5
-rw-r--r--client/map/items/rolled_dough.gd18
-rw-r--r--client/map/items/rolled_dough.resbin8737 -> 13152 bytes
-rw-r--r--client/map/items/rolled_dough.tscn7
-rw-r--r--client/map/items/seared_patty.resbin6314 -> 11879 bytes
-rw-r--r--client/map/items/seared_patty.tscn7
-rw-r--r--client/map/items/seared_steak.resbin13772 -> 20966 bytes
-rw-r--r--client/map/items/seared_steak.tscn7
-rw-r--r--client/map/items/sliced_bun.tscn10
-rw-r--r--client/map/items/sliced_bun_bottom.resbin6662 -> 12029 bytes
-rw-r--r--client/map/items/sliced_bun_bottom.tscn7
-rw-r--r--client/map/items/sliced_bun_top.resbin11225 -> 18422 bytes
-rw-r--r--client/map/items/sliced_bun_top.tscn7
-rw-r--r--client/map/items/sliced_cheese.resbin3862 -> 8337 bytes
-rw-r--r--client/map/items/sliced_cheese.tscn7
-rw-r--r--client/map/items/sliced_fish.resbin5903 -> 11142 bytes
-rw-r--r--client/map/items/sliced_fish.tscn7
-rw-r--r--client/map/items/sliced_leek/leek_ring.resbin0 -> 9074 bytes
-rw-r--r--client/map/items/sliced_leek/leek_ring.tscn9
-rw-r--r--client/map/items/sliced_leek/leek_ring_fill.tscn14
-rw-r--r--client/map/items/sliced_leek/sliced_leek.tscn21
-rw-r--r--client/map/items/sliced_leek/sliced_leek_1.resbin3739 -> 7722 bytes
-rw-r--r--client/map/items/sliced_leek/sliced_leek_2.resbin3513 -> 7454 bytes
-rw-r--r--client/map/items/sliced_leek/sliced_leek_3.resbin4136 -> 8334 bytes
-rw-r--r--client/map/items/sliced_leek/sliced_leek_4.resbin3397 -> 7454 bytes
-rw-r--r--client/map/items/sliced_leek/sliced_leek_5.resbin3411 -> 7454 bytes
-rw-r--r--client/map/items/sliced_leek/sliced_leek_6.resbin3479 -> 7466 bytes
-rw-r--r--client/map/items/sliced_lettuce.resbin5186 -> 8609 bytes
-rw-r--r--client/map/items/sliced_lettuce.tscn7
-rw-r--r--client/map/items/sliced_mushroom.resbin0 -> 44149 bytes
-rw-r--r--client/map/items/sliced_mushroom.tscn9
-rw-r--r--client/map/items/sliced_potato.tscn7
-rw-r--r--client/map/items/sliced_tomato.resbin8155 -> 18185 bytes
-rw-r--r--client/map/items/sliced_tomato.tscn7
-rw-r--r--client/map/items/sliced_tomato_sliced_lettuce_fill.tscn18
-rw-r--r--client/map/items/steak.resbin14012 -> 21408 bytes
-rw-r--r--client/map/items/steak.tscn7
-rw-r--r--client/map/items/steam.tscn4
-rw-r--r--client/map/items/strawberry.resbin11074 -> 27093 bytes
-rw-r--r--client/map/items/strawberry.tscn7
-rw-r--r--client/map/items/tomato.resbin18793 -> 34164 bytes
-rw-r--r--client/map/items/tomato.tscn7
-rw-r--r--client/map/items/unknown_item.gd2
-rw-r--r--client/map/items/unknown_item.tscn6
-rw-r--r--client/map/items/unknown_order.tscn6
-rw-r--r--client/map/kitchen_background.gd27
-rw-r--r--client/map/kitchen_background.tscn12
-rw-r--r--client/map/map.gd99
-rw-r--r--client/map/map.tscn6
-rw-r--r--client/map/particles/checkmark/checkmark.gd (renamed from client/player/particles/checkmark/checkmark.gd)2
-rw-r--r--client/map/particles/checkmark/checkmark.gd.uid (renamed from client/player/particles/checkmark/checkmark.gd.uid)0
-rw-r--r--client/map/particles/checkmark/checkmark.svg (renamed from client/player/particles/checkmark/checkmark.svg)0
-rw-r--r--client/map/particles/checkmark/checkmark.svg.import (renamed from client/player/particles/checkmark/checkmark.svg.import)8
-rw-r--r--client/map/particles/checkmark/checkmark.tscn (renamed from client/player/particles/checkmark/checkmark.tscn)11
-rw-r--r--client/map/progress/progress.gd2
-rw-r--r--client/map/progress/progress.gdshader2
-rw-r--r--client/map/progress/progress.tscn4
-rw-r--r--client/map/tile_factory.gd127
-rw-r--r--client/map/tiles/active_interact_counter.gd61
-rw-r--r--client/map/tiles/active_interact_counter.gd.uid1
-rw-r--r--client/map/tiles/book.gd.uid1
-rw-r--r--client/map/tiles/book.resbin2847 -> 6798 bytes
-rw-r--r--client/map/tiles/book.tscn7
-rw-r--r--client/map/tiles/bun_crate.gd.uid1
-rw-r--r--client/map/tiles/bun_crate.tscn18
-rw-r--r--client/map/tiles/button/accept.svg4
-rw-r--r--client/map/tiles/button/accept.svg.import45
-rw-r--r--client/map/tiles/button/button.gd (renamed from client/map/tiles/ceiling_lamp.gd)11
-rw-r--r--client/map/tiles/button/button.gd.uid1
-rw-r--r--client/map/tiles/button/button.tscn36
-rw-r--r--client/map/tiles/button/button_dynamic_accept.resbin0 -> 8442 bytes
-rw-r--r--client/map/tiles/button/button_dynamic_cancel.resbin0 -> 8439 bytes
-rw-r--r--client/map/tiles/button/button_model.gd28
-rw-r--r--client/map/tiles/button/button_model.gd.uid1
-rw-r--r--client/map/tiles/button/button_static.resbin0 -> 4629 bytes
-rw-r--r--client/map/tiles/button/cancel.svg4
-rw-r--r--client/map/tiles/button/cancel.svg.import45
-rw-r--r--client/map/tiles/button/map.svg4
-rw-r--r--client/map/tiles/button/map.svg.import45
-rw-r--r--client/map/tiles/button_base.gd (renamed from client/map/tiles/flour_crate.gd)11
-rw-r--r--client/map/tiles/button_base.gd.uid1
-rw-r--r--client/map/tiles/button_base.resbin0 -> 2646 bytes
-rw-r--r--client/map/tiles/button_base.tscn9
-rw-r--r--client/map/tiles/ceiling_lamp.gd.uid1
-rw-r--r--client/map/tiles/ceiling_lamp.resbin7229 -> 15054 bytes
-rw-r--r--client/map/tiles/ceiling_lamp.tscn9
-rw-r--r--client/map/tiles/chair.gd11
-rw-r--r--client/map/tiles/chair.resbin19899 -> 42642 bytes
-rw-r--r--client/map/tiles/chair.tscn7
-rw-r--r--client/map/tiles/chandelier.gd21
-rw-r--r--client/map/tiles/chandelier.gd.uid1
-rw-r--r--client/map/tiles/chandelier.resbin25437 -> 42121 bytes
-rw-r--r--client/map/tiles/chandelier.tscn9
-rw-r--r--client/map/tiles/cheese_crate.gd21
-rw-r--r--client/map/tiles/cheese_crate.gd.uid1
-rw-r--r--client/map/tiles/cheese_crate.tscn16
-rw-r--r--client/map/tiles/coconut_crate.gd21
-rw-r--r--client/map/tiles/coconut_crate.gd.uid1
-rw-r--r--client/map/tiles/coconut_crate.tscn12
-rw-r--r--client/map/tiles/conveyor.gd6
-rw-r--r--client/map/tiles/conveyor.resbin6513 -> 17742 bytes
-rw-r--r--client/map/tiles/conveyor.tscn13
-rw-r--r--client/map/tiles/conveyor_direction.gdshader2
-rw-r--r--client/map/tiles/conveyor_direction.tscn4
-rw-r--r--client/map/tiles/conveyor_model.gd4
-rw-r--r--client/map/tiles/counter.gd73
-rw-r--r--client/map/tiles/counter.gd.uid2
-rw-r--r--client/map/tiles/counter_base.gd.uid1
-rw-r--r--client/map/tiles/counter_like.gd80
-rw-r--r--client/map/tiles/counter_like.gd.uid1
-rw-r--r--client/map/tiles/counter_outer_corner.resbin2492 -> 6610 bytes
-rw-r--r--client/map/tiles/counter_outer_corner.tscn7
-rw-r--r--client/map/tiles/counter_straight.resbin6697 -> 17247 bytes
-rw-r--r--client/map/tiles/counter_straight.tscn7
-rw-r--r--client/map/tiles/counter_straight_backsplash.resbin7249 -> 18133 bytes
-rw-r--r--client/map/tiles/counter_straight_backsplash.tscn7
-rw-r--r--client/map/tiles/counter_window.gd4
-rw-r--r--client/map/tiles/counter_window.resbin5279 -> 14020 bytes
-rw-r--r--client/map/tiles/counter_window.tscn7
-rw-r--r--client/map/tiles/counter_window_conveyor.gd (renamed from client/map/tiles/counter_base.gd)27
-rw-r--r--client/map/tiles/counter_window_conveyor.gd.uid1
-rw-r--r--client/map/tiles/counter_window_conveyor.resbin0 -> 17920 bytes
-rw-r--r--client/map/tiles/counter_window_conveyor.tscn31
-rw-r--r--client/map/tiles/crate.gd53
-rw-r--r--client/map/tiles/crate.resbin4840 -> 13626 bytes
-rw-r--r--client/map/tiles/crate.tscn7
-rw-r--r--client/map/tiles/cutting_board.gd41
-rw-r--r--client/map/tiles/cutting_board.resbin2421 -> 6421 bytes
-rw-r--r--client/map/tiles/cutting_board.tscn17
-rw-r--r--client/map/tiles/deep_fryer.gd10
-rw-r--r--client/map/tiles/deep_fryer.gd.uid2
-rw-r--r--client/map/tiles/deep_fryer.tscn11
-rw-r--r--client/map/tiles/deep_fryer_base.resbin8029 -> 18452 bytes
-rw-r--r--client/map/tiles/deep_fryer_fill.resbin1566 -> 4146 bytes
-rw-r--r--client/map/tiles/door.gd4
-rw-r--r--client/map/tiles/door.resbin3444 -> 8880 bytes
-rw-r--r--client/map/tiles/door.tscn7
-rw-r--r--client/map/tiles/exterior_tree.gd46
-rw-r--r--client/map/tiles/fence.gd13
-rw-r--r--client/map/tiles/fence_corner.resbin4533 -> 12328 bytes
-rw-r--r--client/map/tiles/fence_corner.tscn7
-rw-r--r--client/map/tiles/fence_end.resbin0 -> 11803 bytes
-rw-r--r--client/map/tiles/fence_end.tscn9
-rw-r--r--client/map/tiles/fence_straight.resbin4243 -> 11618 bytes
-rw-r--r--client/map/tiles/fence_straight.tscn7
-rw-r--r--client/map/tiles/fence_t.resbin4858 -> 14332 bytes
-rw-r--r--client/map/tiles/fence_t.tscn7
-rw-r--r--client/map/tiles/fish_crate.gd21
-rw-r--r--client/map/tiles/fish_crate.gd.uid1
-rw-r--r--client/map/tiles/fish_crate.tscn14
-rw-r--r--client/map/tiles/floor.gd2
-rw-r--r--client/map/tiles/floor.gdshader2
-rw-r--r--client/map/tiles/floor.resbin2184 -> 7086 bytes
-rw-r--r--client/map/tiles/floor.tscn7
-rw-r--r--client/map/tiles/floor_like.gd2
-rw-r--r--client/map/tiles/floor_material.tres2
-rw-r--r--client/map/tiles/floor_mesher.gd2
-rw-r--r--client/map/tiles/flour_crate.gd.uid1
-rw-r--r--client/map/tiles/flour_crate.tscn16
-rw-r--r--client/map/tiles/freezer.gd4
-rw-r--r--client/map/tiles/freezer.tscn22
-rw-r--r--client/map/tiles/freezer_base.resbin8305 -> 22044 bytes
-rw-r--r--client/map/tiles/freezer_door.resbin9112 -> 18516 bytes
-rw-r--r--client/map/tiles/freezer_model.gd2
-rw-r--r--client/map/tiles/generic_tile.gd14
-rw-r--r--client/map/tiles/generic_tile.gd.uid2
-rw-r--r--client/map/tiles/grass.gd9
-rw-r--r--client/map/tiles/grass.resbin2140 -> 6951 bytes
-rw-r--r--client/map/tiles/grass.tscn7
-rw-r--r--client/map/tiles/grass_mesher.gd17
-rw-r--r--client/map/tiles/grass_side.tres2
-rw-r--r--client/map/tiles/house/balcony.resbin13786 -> 45698 bytes
-rw-r--r--client/map/tiles/house/balcony.tscn7
-rw-r--r--client/map/tiles/house/chimney.resbin3317 -> 9851 bytes
-rw-r--r--client/map/tiles/house/chimney.tscn7
-rw-r--r--client/map/tiles/house/corner.resbin11505 -> 36553 bytes
-rw-r--r--client/map/tiles/house/corner.tscn7
-rw-r--r--client/map/tiles/house/door.resbin14207 -> 42932 bytes
-rw-r--r--client/map/tiles/house/door.tscn7
-rw-r--r--client/map/tiles/house/oriel.resbin12695 -> 40680 bytes
-rw-r--r--client/map/tiles/house/oriel.tscn7
-rw-r--r--client/map/tiles/house/roof.resbin1378 -> 4041 bytes
-rw-r--r--client/map/tiles/house/roof.tscn7
-rw-r--r--client/map/tiles/house/side.resbin1716 -> 4920 bytes
-rw-r--r--client/map/tiles/house/side.tscn7
-rw-r--r--client/map/tiles/house/wall.resbin11677 -> 37023 bytes
-rw-r--r--client/map/tiles/house/wall.tscn7
-rw-r--r--client/map/tiles/house_balcony.gd2
-rw-r--r--client/map/tiles/house_door.gd2
-rw-r--r--client/map/tiles/house_oriel.gd2
-rw-r--r--client/map/tiles/house_roof.gd2
-rw-r--r--client/map/tiles/house_roof_chimney.gd2
-rw-r--r--client/map/tiles/house_side.gd2
-rw-r--r--client/map/tiles/house_tile.gd2
-rw-r--r--client/map/tiles/house_wall.gd2
-rw-r--r--client/map/tiles/item_portal.gd10
-rw-r--r--client/map/tiles/knife.resbin5546 -> 10298 bytes
-rw-r--r--client/map/tiles/knife.tscn7
-rw-r--r--client/map/tiles/lamp.gd2
-rw-r--r--client/map/tiles/lamp.resbin72760 -> 218504 bytes
-rw-r--r--client/map/tiles/lamp.tscn8
-rw-r--r--client/map/tiles/leek_crate.gd21
-rw-r--r--client/map/tiles/leek_crate.gd.uid1
-rw-r--r--client/map/tiles/leek_crate.tscn16
-rw-r--r--client/map/tiles/lettuce_crate.tscn12
-rw-r--r--client/map/tiles/light_tile.gd2
-rw-r--r--client/map/tiles/map_selector.resbin0 -> 2788 bytes
-rw-r--r--client/map/tiles/map_selector.tscn9
-rw-r--r--client/map/tiles/mushroom_crate.gd21
-rw-r--r--client/map/tiles/mushroom_crate.gd.uid1
-rw-r--r--client/map/tiles/mushroom_crate.tscn14
-rw-r--r--client/map/tiles/noodles_crate.tscn30
-rw-r--r--client/map/tiles/oven.gd4
-rw-r--r--client/map/tiles/oven.tscn18
-rw-r--r--client/map/tiles/oven_base.resbin12342 -> 36433 bytes
-rw-r--r--client/map/tiles/oven_door.resbin3424 -> 9565 bytes
-rw-r--r--client/map/tiles/oven_model.gd2
-rw-r--r--client/map/tiles/path.gd2
-rw-r--r--client/map/tiles/path.resbin1907 -> 5291 bytes
-rw-r--r--client/map/tiles/path.tscn7
-rw-r--r--client/map/tiles/player_portal.gd14
-rw-r--r--client/map/tiles/portal.gd23
-rw-r--r--client/map/tiles/portal.gdshader33
-rw-r--r--client/map/tiles/portal.tscn13
-rw-r--r--client/map/tiles/potato_crate.gd21
-rw-r--r--client/map/tiles/potato_crate.gd.uid1
-rw-r--r--client/map/tiles/potato_crate.tscn20
-rw-r--r--client/map/tiles/rice_crate.gd21
-rw-r--r--client/map/tiles/rice_crate.gd.uid1
-rw-r--r--client/map/tiles/rice_crate.tscn6
-rw-r--r--client/map/tiles/rolling_board.gd42
-rw-r--r--client/map/tiles/rolling_board.tscn9
-rw-r--r--client/map/tiles/rolling_pin.resbin28783 -> 48508 bytes
-rw-r--r--client/map/tiles/rolling_pin.tscn7
-rw-r--r--client/map/tiles/screen/screen.gd24
-rw-r--r--client/map/tiles/screen/screen.gd.uid1
-rw-r--r--client/map/tiles/screen/screen.res.deprenbin0 -> 7450 bytes
-rw-r--r--client/map/tiles/screen/screen.tscn36
-rw-r--r--client/map/tiles/screen/screen_base.resbin0 -> 14767 bytes
-rw-r--r--client/map/tiles/screen/screen_display.resbin0 -> 5761 bytes
-rw-r--r--client/map/tiles/screen/screen_model.gd (renamed from client/player/particles/effect.gd)27
-rw-r--r--client/map/tiles/screen/screen_model.gd.uid1
-rw-r--r--client/map/tiles/sink.gd4
-rw-r--r--client/map/tiles/sink.resbin24079 -> 49179 bytes
-rw-r--r--client/map/tiles/sink.tscn7
-rw-r--r--client/map/tiles/sink_backsplash.resbin24526 -> 50283 bytes
-rw-r--r--client/map/tiles/sink_backsplash.tscn7
-rw-r--r--client/map/tiles/sink_particles.gd2
-rw-r--r--client/map/tiles/sink_particles.tscn8
-rw-r--r--client/map/tiles/steak_crate.gd21
-rw-r--r--client/map/tiles/steak_crate.gd.uid1
-rw-r--r--client/map/tiles/steak_crate.resbin50290 -> 89808 bytes
-rw-r--r--client/map/tiles/steak_crate.tscn7
-rw-r--r--client/map/tiles/stove.gd6
-rw-r--r--client/map/tiles/stove.resbin25618 -> 58179 bytes
-rw-r--r--client/map/tiles/stove.tscn7
-rw-r--r--client/map/tiles/strawberry_crate.gd21
-rw-r--r--client/map/tiles/strawberry_crate.gd.uid1
-rw-r--r--client/map/tiles/strawberry_crate.tscn14
-rw-r--r--client/map/tiles/street.gd2
-rw-r--r--client/map/tiles/street.resbin1914 -> 5293 bytes
-rw-r--r--client/map/tiles/street.tscn7
-rw-r--r--client/map/tiles/table.gd6
-rw-r--r--client/map/tiles/table.resbin10832 -> 24238 bytes
-rw-r--r--client/map/tiles/table.tscn7
-rw-r--r--client/map/tiles/tile.gd28
-rw-r--r--client/map/tiles/tomato_crate.gd21
-rw-r--r--client/map/tiles/tomato_crate.gd.uid1
-rw-r--r--client/map/tiles/tomato_crate.resbin86505 -> 142716 bytes
-rw-r--r--client/map/tiles/tomato_crate.tscn7
-rw-r--r--client/map/tiles/trash.gd4
-rw-r--r--client/map/tiles/trash.resbin4874 -> 13650 bytes
-rw-r--r--client/map/tiles/trash.tscn7
-rw-r--r--client/map/tiles/tree/bark.tres2
-rw-r--r--client/map/tiles/tree/leaves.tres6
-rw-r--r--client/map/tiles/tree/leaves_1_hq.resbin181369 -> 224911 bytes
-rw-r--r--client/map/tiles/tree/leaves_1_lq.resbin20745 -> 35100 bytes
-rw-r--r--client/map/tiles/tree/leaves_2_hq.resbin133320 -> 165631 bytes
-rw-r--r--client/map/tiles/tree/leaves_2_lq.resbin29092 -> 49148 bytes
-rw-r--r--client/map/tiles/tree/leaves_3_hq.resbin105688 -> 131311 bytes
-rw-r--r--client/map/tiles/tree/leaves_3_lq.resbin28661 -> 48836 bytes
-rw-r--r--client/map/tiles/tree/leaves_4_hq.resbin136841 -> 169831 bytes
-rw-r--r--client/map/tiles/tree/leaves_4_lq.resbin16915 -> 28708 bytes
-rw-r--r--client/map/tiles/tree/leaves_5_hq.resbin40691 -> 50551 bytes
-rw-r--r--client/map/tiles/tree/leaves_5_lq.resbin28905 -> 48764 bytes
-rw-r--r--client/map/tiles/tree/leaves_lq.resbin1034 -> 2933 bytes
-rw-r--r--client/map/tiles/tree/trunk_1.resbin152953 -> 195642 bytes
-rw-r--r--client/map/tiles/tree/trunk_2.resbin169549 -> 216026 bytes
-rw-r--r--client/map/tiles/tree/trunk_3.resbin155114 -> 198778 bytes
-rw-r--r--client/map/tiles/tree/trunk_4.resbin110556 -> 141278 bytes
-rw-r--r--client/map/tiles/tree/trunk_5.resbin43147 -> 56650 bytes
-rw-r--r--client/map/tiles/unknown_tile.gd (renamed from client/map/items/lettuce_crate.gd)12
-rw-r--r--client/map/tiles/unknown_tile.gd.uid1
-rw-r--r--client/map/tiles/wall.gd2
-rw-r--r--client/map/tiles/wall_corner.resbin2936 -> 8252 bytes
-rw-r--r--client/map/tiles/wall_corner.tscn7
-rw-r--r--client/map/tiles/wall_cross.resbin3181 -> 9658 bytes
-rw-r--r--client/map/tiles/wall_cross.tscn7
-rw-r--r--client/map/tiles/wall_straight.resbin2427 -> 6512 bytes
-rw-r--r--client/map/tiles/wall_straight.tscn7
-rw-r--r--client/map/tiles/wall_t.resbin3046 -> 8866 bytes
-rw-r--r--client/map/tiles/wall_t.tscn7
-rw-r--r--client/map/tiles/wall_tile.gd16
-rw-r--r--client/map/tiles/window.gd4
-rw-r--r--client/map/tiles/window.resbin5758 -> 14816 bytes
-rw-r--r--client/map/tiles/window.tscn7
-rw-r--r--client/message_parser.gd71
-rw-r--r--client/message_parser.gd.uid1
-rw-r--r--client/multiplayer.gd136
-rw-r--r--client/multiplayer.tscn6
-rw-r--r--client/player/camera_recorder.gd8
-rw-r--r--client/player/character/character.gd2
-rw-r--r--client/player/character/character.tscn328
-rw-r--r--client/player/character/customer_body.resbin25327 -> 40660 bytes
-rw-r--r--client/player/character/default/hand_left.resbin11848 -> 25672 bytes
-rw-r--r--client/player/character/default/hand_right.resbin11784 -> 25813 bytes
-rw-r--r--client/player/character/default/head.resbin32308 -> 60847 bytes
-rw-r--r--client/player/character/default/main.resbin30072 -> 51147 bytes
-rw-r--r--client/player/character/default/tie.resbin6126 -> 13952 bytes
-rw-r--r--client/player/character/hairstyles/hair_1.resbin16938 -> 25668 bytes
-rw-r--r--client/player/character/hairstyles/hair_2.resbin16368 -> 25065 bytes
-rw-r--r--client/player/character/hairstyles/hair_3.resbin19738 -> 30474 bytes
-rw-r--r--client/player/character/headwear/cat_ears.gd16
-rw-r--r--client/player/character/headwear/cat_ears.resbin4691 -> 10181 bytes
-rw-r--r--client/player/character/headwear/cat_ears.tscn18
-rw-r--r--client/player/character/headwear/devil_horn.resbin5892 -> 11504 bytes
-rw-r--r--client/player/character/headwear/devil_horns.tscn10
-rw-r--r--client/player/character/headwear/propeller.resbin18086 -> 29769 bytes
-rw-r--r--client/player/character/headwear/propeller_hat.tscn4
-rw-r--r--client/player/character/robot/antenna.resbin4933 -> 8811 bytes
-rw-r--r--client/player/character/robot/ears.resbin10615 -> 19029 bytes
-rw-r--r--client/player/character/robot/head.resbin4021 -> 10046 bytes
-rw-r--r--client/player/character/robot/head.tscn11
-rw-r--r--client/player/character/tram/tram.resbin35349 -> 92805 bytes
-rw-r--r--client/player/character/tram/tram.tscn7
-rw-r--r--client/player/chat_bubble.gd2
-rw-r--r--client/player/chat_bubble.tscn8
-rw-r--r--client/player/chat_message.tscn6
-rw-r--r--client/player/controllable_player.gd333
-rw-r--r--client/player/follow_camera.gd44
-rw-r--r--client/player/follow_camera.tscn8
-rw-r--r--client/player/item_bubble.gd2
-rw-r--r--client/player/item_bubble.tscn8
-rw-r--r--client/player/marker/interact_marker.gdshader8
-rw-r--r--client/player/marker/marker.gd8
-rw-r--r--client/player/marker/marker.tscn7
-rw-r--r--client/player/mirror.gd2
-rw-r--r--client/player/onscreen_controls/controls.gd7
-rw-r--r--client/player/onscreen_controls/controls.tscn18
-rw-r--r--client/player/onscreen_controls/virtual_joystick.gd2
-rw-r--r--client/player/onscreen_controls/virtual_joystick_scene.tscn8
-rw-r--r--client/player/particles/angry/angry.tscn41
-rw-r--r--client/player/particles/effect.tscn36
-rw-r--r--client/player/player.gd103
-rw-r--r--client/project.godot53
-rw-r--r--client/service/discover.gd2
-rw-r--r--client/service/editor.gd2
-rw-r--r--client/service/server.gd2
-rw-r--r--client/service/service.gd2
-rw-r--r--client/system/cli.gd19
-rw-r--r--client/system/disable_wrong_joypads.gd2
-rw-r--r--client/system/gltf_apply_visibility.gd4
-rw-r--r--client/system/profile.gd2
-rw-r--r--client/system/render_tool.gd54
-rw-r--r--client/system/render_tool.tscn40
-rw-r--r--client/system/server_list.gd2
-rw-r--r--client/system/settings.gd64
-rw-r--r--client/system/translation_manager.gd25
-rw-r--r--client/test.tscn30
658 files changed, 5948 insertions, 3612 deletions
diff --git a/client/.gitignore b/client/.gitignore
index 03408ec6..867b4a38 100644
--- a/client/.gitignore
+++ b/client/.gitignore
@@ -3,3 +3,4 @@
/menu/book/book_*.webp*
/icons/*
!/icons/main.png
+/client.pck \ No newline at end of file
diff --git a/client/README.md b/client/README.md
index c1eace2e..4d8667bd 100644
--- a/client/README.md
+++ b/client/README.md
@@ -2,9 +2,16 @@
The main game client.
-- For development:
- - Requires Godot 4.4 or newer
- - Open the editor with `godot project.godot`
-- For release builds:
- - Requires Godot, make and ffmpeg
- - Run `make`
+## Development setup
+
+Supply a server address as first argument to the client to connect without going
+through menus.
+
+```
+godot -- ws://127.0.0.1:27032
+```
+
+The game has builtin overlays for debugging:
+
+- F3: Overlay with framerate, video driver, etc.
+- F3 + 1: Pie chart to explore node counts of each class
diff --git a/client/audio/music/error.ogg b/client/audio/music/error.ogg
new file mode 100644
index 00000000..db057380
--- /dev/null
+++ b/client/audio/music/error.ogg
Binary files differ
diff --git a/client/audio/music/error.ogg.import b/client/audio/music/error.ogg.import
new file mode 100644
index 00000000..ef7c25c4
--- /dev/null
+++ b/client/audio/music/error.ogg.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="oggvorbisstr"
+type="AudioStreamOggVorbis"
+uid="uid://rvxye5h3fvh0"
+path="res://.godot/imported/error.ogg-d05e4b9d043b8ee254ca5e65b090a5cc.oggvorbisstr"
+
+[deps]
+
+source_file="res://audio/music/error.ogg"
+dest_files=["res://.godot/imported/error.ogg-d05e4b9d043b8ee254ca5e65b090a5cc.oggvorbisstr"]
+
+[params]
+
+loop=false
+loop_offset=0
+bpm=0
+beat_count=0
+bar_beats=4
diff --git a/client/audio/music/reflets-dans-leau.ogg b/client/audio/music/reflets-dans-leau.ogg
new file mode 100644
index 00000000..13d78788
--- /dev/null
+++ b/client/audio/music/reflets-dans-leau.ogg
Binary files differ
diff --git a/client/audio/music/reflets-dans-leau.ogg.import b/client/audio/music/reflets-dans-leau.ogg.import
new file mode 100644
index 00000000..27b034c7
--- /dev/null
+++ b/client/audio/music/reflets-dans-leau.ogg.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="oggvorbisstr"
+type="AudioStreamOggVorbis"
+uid="uid://dpgt5loaberoj"
+path="res://.godot/imported/reflets-dans-leau.ogg-b4a7d816b71a4043429c7dc7d9411e8f.oggvorbisstr"
+
+[deps]
+
+source_file="res://audio/music/reflets-dans-leau.ogg"
+dest_files=["res://.godot/imported/reflets-dans-leau.ogg-b4a7d816b71a4043429c7dc7d9411e8f.oggvorbisstr"]
+
+[params]
+
+loop=true
+loop_offset=0.0
+bpm=0.0
+beat_count=0
+bar_beats=4
diff --git a/client/audio/play_random.gd b/client/audio/play_random.gd
index 4bab2b78..3196b963 100644
--- a/client/audio/play_random.gd
+++ b/client/audio/play_random.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/audio/play_random.tscn b/client/audio/play_random.tscn
index 0521eb5a..815dcabf 100644
--- a/client/audio/play_random.tscn
+++ b/client/audio/play_random.tscn
@@ -1,6 +1,6 @@
-[gd_scene load_steps=2 format=3 uid="uid://bncx0wul2ikrg"]
+[gd_scene format=3 uid="uid://bncx0wul2ikrg"]
[ext_resource type="Script" uid="uid://n4jwod1jfuiv" path="res://audio/play_random.gd" id="1_c8pxf"]
-[node name="PlayRandom" type="Node3D"]
+[node name="PlayRandom" type="Node3D" unique_id=709936730]
script = ExtResource("1_c8pxf")
diff --git a/client/audio/sound.gd b/client/audio/sound.gd
index 8c7649aa..579c0224 100644
--- a/client/audio/sound.gd
+++ b/client/audio/sound.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -22,23 +22,90 @@ extends Node
var item_sounds: Dictionary = {}
var item_id: int = 0
+var current_music_player: AudioStreamPlayer
+var current_music_filename
+var dampen_music := false
+var volume_target = 0.
+var dampen_target = 0.
+var dampen_value = 0.
-func play_music(music : String): # If music == "stop", this stops all music
- for stream in music_node.get_children():
- stream.stop()
-
- if music_node.get_node_or_null(music) == null:
- return
- else:
- music_node.get_node(music).play()
+const VOLUME_MIN = -30.
+const FADE_IN_SPEED = 200.
+const FADE_OUT_SPEED = 20.
+const EFFECT_FADE_SPEED = 0.5
-func set_volume(bus : int, value:float):
+var is_saved = false
+var saved_filename
+var saved_volume = 0.
+var saved_dampen = false
+
+func _ready() -> void:
+ get_window().focus_entered.connect(func(): restore_playing())
+ get_window().focus_exited.connect(func(): save_playing(); set_music(null))
+
+func restore_playing():
+ if is_saved: set_music(saved_filename, saved_volume, saved_dampen)
+ is_saved = false
+
+func save_playing():
+ saved_filename = current_music_filename
+ saved_dampen = dampen_music
+ saved_volume = volume_target
+ is_saved = true
+
+func set_music(filename, volume = 0., dampen = false):
+ dampen_music = dampen
+ if current_music_filename != filename:
+ if filename == null:
+ current_music_filename = null
+ current_music_player = null
+ else:
+ var player = AudioStreamPlayer.new()
+ player.stream = load("res://audio/music/%s.ogg" % filename)
+ player.volume_db = VOLUME_MIN + 1.
+ player.autoplay = true
+ player.name = filename
+ player.bus = "Music"
+ current_music_player = player
+ current_music_filename = filename
+ $Music.add_child(player)
+
+ volume_target = volume
+ dampen_target = 1. if dampen else 0.
+
+func _physics_process(dt: float):
+ for c in $Music.get_children():
+ if c is AudioStreamPlayer:
+ if c == current_music_player:
+ if c.volume_db > volume_target: c.volume_db = max(volume_target, c.volume_db - dt * FADE_OUT_SPEED)
+ else: c.volume_db = min(volume_target, c.volume_db + dt * FADE_IN_SPEED)
+ else:
+ c.volume_db -= dt * FADE_OUT_SPEED
+ if c.volume_db <= VOLUME_MIN: c.queue_free()
+
+ var prev_dampen = dampen_value
+ dampen_value = G.interpolate_linear(dampen_value, dampen_target, dt * EFFECT_FADE_SPEED)
+ AudioServer.set_bus_effect_enabled(1, 0, dampen_value > 0.)
+ AudioServer.set_bus_effect_enabled(1, 1, dampen_value > 0.)
+ if dampen_value != prev_dampen:
+ var lowpass = AudioServer.get_bus_effect(1, 0) as AudioEffectFilter
+ var reverb = AudioServer.get_bus_effect(1, 1) as AudioEffectReverb
+ lowpass.cutoff_hz = lerp(3200., 400., pow(dampen_value, 8.))
+ reverb.wet = dampen_value * 0.5
+
+ for k in item_sounds.keys():
+ if item_sounds[k][0] != null:
+ var position: Vector3 = item_sounds[k][0].position
+ item_sounds[k][1].position = position
+ item_sounds[k][2].position = position
+ elif not item_sounds[k][3]:
+ item_finished(k)
+
+
+func set_volume(bus: int, value: float):
AudioServer.set_bus_volume_db(bus, value)
-
- if value == -30:
- AudioServer.set_bus_mute(bus, true)
- else:
- AudioServer.set_bus_mute(bus, false)
+ if value == -30: AudioServer.set_bus_mute(bus, true)
+ else: AudioServer.set_bus_mute(bus, false)
func play_click():
click_sound.play()
@@ -89,12 +156,3 @@ func free_sound(id: int):
running_player.queue_free()
stopping_player.queue_free()
item_sounds.erase(id)
-
-func _physics_process(_delta):
- for k in item_sounds.keys():
- if item_sounds[k][0] != null:
- var position: Vector3 = item_sounds[k][0].position
- item_sounds[k][1].position = position
- item_sounds[k][2].position = position
- elif not item_sounds[k][3]:
- item_finished(k)
diff --git a/client/audio/sound.tscn b/client/audio/sound.tscn
index b15a3263..33974b50 100644
--- a/client/audio/sound.tscn
+++ b/client/audio/sound.tscn
@@ -1,33 +1,25 @@
-[gd_scene load_steps=5 format=3 uid="uid://d3h243yic44rr"]
+[gd_scene format=3 uid="uid://d3h243yic44rr"]
[ext_resource type="Script" uid="uid://cho8r5m78a4ur" path="res://audio/sound.gd" id="1_b0qb1"]
[ext_resource type="AudioStream" uid="uid://cpyn511c5mtni" path="res://gui/resources/sounds/click.ogg" id="2_mhrce"]
[ext_resource type="AudioStream" uid="uid://dtr1khfyqr56o" path="res://gui/resources/sounds/hover.ogg" id="3_qft2s"]
[ext_resource type="AudioStream" uid="uid://dft3m8utnxhs7" path="res://gui/resources/sounds/game_start.ogg" id="4_le874"]
-[node name="Sound" type="Node3D"]
+[node name="Sound" type="Node3D" unique_id=1522713818]
script = ExtResource("1_b0qb1")
-[node name="UI" type="Node" parent="."]
+[node name="UI" type="Node" parent="." unique_id=1715280669]
-[node name="Click" type="AudioStreamPlayer" parent="UI"]
+[node name="Click" type="AudioStreamPlayer" parent="UI" unique_id=711699613]
stream = ExtResource("2_mhrce")
bus = &"SFX"
-[node name="Hover" type="AudioStreamPlayer" parent="UI"]
+[node name="Hover" type="AudioStreamPlayer" parent="UI" unique_id=2039805700]
stream = ExtResource("3_qft2s")
bus = &"SFX"
-[node name="GameStart" type="AudioStreamPlayer" parent="UI"]
+[node name="GameStart" type="AudioStreamPlayer" parent="UI" unique_id=246241584]
stream = ExtResource("4_le874")
bus = &"SFX"
-[node name="Music" type="Node" parent="."]
-
-[node name="MainMenu" type="AudioStreamPlayer" parent="Music"]
-volume_db = 1.0
-bus = &"Music"
-
-[node name="Lobby" type="AudioStreamPlayer" parent="Music"]
-volume_db = -3.5
-bus = &"Music"
+[node name="Music" type="Node" parent="." unique_id=473283634]
diff --git a/client/default_bus_layout.tres b/client/default_bus_layout.tres
index b578bec4..33838b2a 100644
--- a/client/default_bus_layout.tres
+++ b/client/default_bus_layout.tres
@@ -1,5 +1,13 @@
[gd_resource type="AudioBusLayout" format=3 uid="uid://cco0uysin1okg"]
+[sub_resource type="AudioEffectLowPassFilter" id="AudioEffectLowPassFilter_j3pel"]
+resource_name = "LowPassFilter"
+cutoff_hz = 400.0
+
+[sub_resource type="AudioEffectReverb" id="AudioEffectReverb_j3pel"]
+resource_name = "Reverb"
+room_size = 1.0
+
[resource]
bus/1/name = &"Music"
bus/1/solo = false
@@ -7,6 +15,10 @@ bus/1/mute = false
bus/1/bypass_fx = false
bus/1/volume_db = 0.0
bus/1/send = &"Master"
+bus/1/effect/0/effect = SubResource("AudioEffectLowPassFilter_j3pel")
+bus/1/effect/0/enabled = false
+bus/1/effect/1/effect = SubResource("AudioEffectReverb_j3pel")
+bus/1/effect/1/enabled = false
bus/2/name = &"SFX"
bus/2/solo = false
bus/2/mute = false
diff --git a/client/export_presets.cfg b/client/export_presets.cfg
index 4c4cf273..3584dab4 100644
--- a/client/export_presets.cfg
+++ b/client/export_presets.cfg
@@ -3,7 +3,6 @@
name="wasm32-unknown-unknown"
platform="Web"
runnable=true
-advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
@@ -11,6 +10,11 @@ include_filter="*.ini, *.ini1"
exclude_filter=""
export_path=""
patches=PackedStringArray()
+patch_delta_encoding=false
+patch_delta_compression_level_zstd=19
+patch_delta_min_reduction=0.1
+patch_delta_include_filters="*"
+patch_delta_exclude_filters=""
encryption_include_filters=""
encryption_exclude_filters=""
seed=0
@@ -41,20 +45,26 @@ progressive_web_app/icon_144x144=""
progressive_web_app/icon_180x180=""
progressive_web_app/icon_512x512=""
progressive_web_app/background_color=Color(0, 0, 0, 1)
+threads/emscripten_pool_size=8
+threads/godot_pool_size=4
[preset.1]
name="x86_64-unknown-linux-gnu"
platform="Linux"
runnable=true
-advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter="*.ini, *.ini1"
exclude_filter=""
-export_path=""
+export_path="../../hurrycurry.x86_64"
patches=PackedStringArray()
+patch_delta_encoding=false
+patch_delta_compression_level_zstd=19
+patch_delta_min_reduction=0.1
+patch_delta_include_filters="*"
+patch_delta_exclude_filters=""
encryption_include_filters=""
encryption_exclude_filters=""
seed=0
@@ -70,6 +80,7 @@ debug/export_console_wrapper=1
binary_format/embed_pck=true
texture_format/s3tc_bptc=true
texture_format/etc2_astc=false
+shader_baker/enabled=false
binary_format/architecture="x86_64"
ssh_remote_deploy/enabled=false
ssh_remote_deploy/host=""
@@ -88,7 +99,6 @@ texture_format/etc2=false
name="aarch64-unknown-linux-gnu"
platform="Linux"
runnable=false
-advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
@@ -96,6 +106,11 @@ include_filter="*.ini, *.ini1"
exclude_filter=""
export_path=""
patches=PackedStringArray()
+patch_delta_encoding=false
+patch_delta_compression_level_zstd=19
+patch_delta_min_reduction=0.1
+patch_delta_include_filters="*"
+patch_delta_exclude_filters=""
encryption_include_filters=""
encryption_exclude_filters=""
seed=0
@@ -111,6 +126,7 @@ debug/export_console_wrapper=1
binary_format/embed_pck=true
texture_format/s3tc_bptc=true
texture_format/etc2_astc=false
+shader_baker/enabled=false
binary_format/architecture="arm64"
ssh_remote_deploy/enabled=false
ssh_remote_deploy/host=""
@@ -129,7 +145,6 @@ texture_format/etc2=false
name="armv7-unknown-linux-gnueabi"
platform="Linux"
runnable=false
-advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
@@ -137,6 +152,11 @@ include_filter="*.ini, *.ini1"
exclude_filter=""
export_path=""
patches=PackedStringArray()
+patch_delta_encoding=false
+patch_delta_compression_level_zstd=19
+patch_delta_min_reduction=0.1
+patch_delta_include_filters="*"
+patch_delta_exclude_filters=""
encryption_include_filters=""
encryption_exclude_filters=""
seed=0
@@ -152,6 +172,7 @@ debug/export_console_wrapper=1
binary_format/embed_pck=true
texture_format/s3tc_bptc=true
texture_format/etc2_astc=false
+shader_baker/enabled=false
binary_format/architecture="arm64"
ssh_remote_deploy/enabled=false
ssh_remote_deploy/host=""
@@ -170,7 +191,6 @@ texture_format/etc2=false
name="i686-unknown-linux-gnu"
platform="Linux"
runnable=false
-advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
@@ -178,6 +198,11 @@ include_filter="*.ini, *.ini1"
exclude_filter=""
export_path=""
patches=PackedStringArray()
+patch_delta_encoding=false
+patch_delta_compression_level_zstd=19
+patch_delta_min_reduction=0.1
+patch_delta_include_filters="*"
+patch_delta_exclude_filters=""
encryption_include_filters=""
encryption_exclude_filters=""
seed=0
@@ -193,6 +218,7 @@ debug/export_console_wrapper=1
binary_format/embed_pck=true
texture_format/s3tc_bptc=true
texture_format/etc2_astc=false
+shader_baker/enabled=false
binary_format/architecture="x86_32"
ssh_remote_deploy/enabled=false
ssh_remote_deploy/host=""
@@ -211,7 +237,6 @@ texture_format/etc2=false
name="x86_64-pc-windows-gnu"
platform="Windows Desktop"
runnable=true
-advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
@@ -219,6 +244,11 @@ include_filter="*.ini, *.ini1"
exclude_filter=""
export_path=""
patches=PackedStringArray()
+patch_delta_encoding=false
+patch_delta_compression_level_zstd=19
+patch_delta_min_reduction=0.1
+patch_delta_include_filters="*"
+patch_delta_exclude_filters=""
encryption_include_filters=""
encryption_exclude_filters=""
seed=0
@@ -234,6 +264,7 @@ debug/export_console_wrapper=1
binary_format/embed_pck=true
texture_format/s3tc_bptc=true
texture_format/etc2_astc=false
+shader_baker/enabled=false
binary_format/architecture="x86_64"
codesign/enable=false
codesign/timestamp=true
@@ -282,7 +313,6 @@ texture_format/etc2=false
name="i686-pc-windows-gnu"
platform="Windows Desktop"
runnable=false
-advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
@@ -290,6 +320,11 @@ include_filter="*.ini, *.ini1"
exclude_filter=""
export_path=""
patches=PackedStringArray()
+patch_delta_encoding=false
+patch_delta_compression_level_zstd=19
+patch_delta_min_reduction=0.1
+patch_delta_include_filters="*"
+patch_delta_exclude_filters=""
encryption_include_filters=""
encryption_exclude_filters=""
seed=0
@@ -305,6 +340,7 @@ debug/export_console_wrapper=1
binary_format/embed_pck=true
texture_format/s3tc_bptc=true
texture_format/etc2_astc=false
+shader_baker/enabled=false
binary_format/architecture="x86_32"
codesign/enable=false
codesign/timestamp=true
@@ -353,7 +389,6 @@ texture_format/etc2=false
name="aarch64-linux-android"
platform="Android"
runnable=true
-advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
@@ -361,6 +396,11 @@ include_filter="*.ini, *.ini1"
exclude_filter=""
export_path="../../aaabuild/hurrycurry.apk"
patches=PackedStringArray()
+patch_delta_encoding=false
+patch_delta_compression_level_zstd=19
+patch_delta_min_reduction=0.1
+patch_delta_include_filters="*"
+patch_delta_exclude_filters=""
encryption_include_filters=""
encryption_exclude_filters=""
seed=0
@@ -379,6 +419,7 @@ gradle_build/compress_native_libraries=false
gradle_build/export_format=0
gradle_build/min_sdk=""
gradle_build/target_sdk=""
+gradle_build/custom_theme_attributes={}
architectures/armeabi-v7a=false
architectures/arm64-v8a=true
architectures/x86=false
@@ -399,13 +440,16 @@ launcher_icons/adaptive_foreground_432x432="res://icons/adaptive-foreground.png"
launcher_icons/adaptive_background_432x432="res://icons/adaptive-background.png"
launcher_icons/adaptive_monochrome_432x432=""
graphics/opengl_debug=false
+shader_baker/enabled=false
xr_features/xr_mode=0
gesture/swipe_to_dismiss=false
screen/immersive_mode=true
+screen/edge_to_edge=false
screen/support_small=true
screen/support_normal=true
screen/support_large=true
screen/support_xlarge=true
+screen/background_color=Color(0, 0, 0, 1)
user_data_backup/allow=false
command_line/extra_args=""
apk_expansion/enable=false
@@ -486,6 +530,7 @@ permissions/manage_accounts=false
permissions/manage_app_tokens=false
permissions/manage_documents=false
permissions/manage_external_storage=false
+permissions/manage_media=false
permissions/master_clear=false
permissions/media_content_control=false
permissions/modify_audio_settings=false
@@ -570,7 +615,6 @@ permissions/write_user_dictionary=false
name="armv7-linux-androideabi"
platform="Android"
runnable=false
-advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
@@ -578,6 +622,11 @@ include_filter="*.ini, *.ini1"
exclude_filter=""
export_path=""
patches=PackedStringArray()
+patch_delta_encoding=false
+patch_delta_compression_level_zstd=19
+patch_delta_min_reduction=0.1
+patch_delta_include_filters="*"
+patch_delta_exclude_filters=""
encryption_include_filters=""
encryption_exclude_filters=""
seed=0
@@ -596,6 +645,7 @@ gradle_build/compress_native_libraries=false
gradle_build/export_format=0
gradle_build/min_sdk=""
gradle_build/target_sdk=""
+gradle_build/custom_theme_attributes={}
architectures/armeabi-v7a=true
architectures/arm64-v8a=false
architectures/x86=false
@@ -616,13 +666,16 @@ launcher_icons/adaptive_foreground_432x432="res://icons/adaptive-foreground.png"
launcher_icons/adaptive_background_432x432="res://icons/adaptive-background.png"
launcher_icons/adaptive_monochrome_432x432=""
graphics/opengl_debug=false
+shader_baker/enabled=false
xr_features/xr_mode=0
gesture/swipe_to_dismiss=false
screen/immersive_mode=true
+screen/edge_to_edge=false
screen/support_small=true
screen/support_normal=true
screen/support_large=true
screen/support_xlarge=true
+screen/background_color=Color(0, 0, 0, 1)
user_data_backup/allow=false
command_line/extra_args=""
apk_expansion/enable=false
@@ -703,6 +756,7 @@ permissions/manage_accounts=false
permissions/manage_app_tokens=false
permissions/manage_documents=false
permissions/manage_external_storage=false
+permissions/manage_media=false
permissions/master_clear=false
permissions/media_content_control=false
permissions/modify_audio_settings=false
@@ -787,7 +841,6 @@ permissions/write_user_dictionary=false
name="x86_64-linux-android"
platform="Android"
runnable=false
-advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
@@ -795,6 +848,11 @@ include_filter="*.ini, *.ini1"
exclude_filter=""
export_path=""
patches=PackedStringArray()
+patch_delta_encoding=false
+patch_delta_compression_level_zstd=19
+patch_delta_min_reduction=0.1
+patch_delta_include_filters="*"
+patch_delta_exclude_filters=""
encryption_include_filters=""
encryption_exclude_filters=""
seed=0
@@ -813,6 +871,7 @@ gradle_build/compress_native_libraries=false
gradle_build/export_format=0
gradle_build/min_sdk=""
gradle_build/target_sdk=""
+gradle_build/custom_theme_attributes={}
architectures/armeabi-v7a=false
architectures/arm64-v8a=false
architectures/x86=false
@@ -833,13 +892,16 @@ launcher_icons/adaptive_foreground_432x432="res://icons/adaptive-foreground.png"
launcher_icons/adaptive_background_432x432="res://icons/adaptive-background.png"
launcher_icons/adaptive_monochrome_432x432=""
graphics/opengl_debug=false
+shader_baker/enabled=false
xr_features/xr_mode=0
gesture/swipe_to_dismiss=false
screen/immersive_mode=true
+screen/edge_to_edge=false
screen/support_small=true
screen/support_normal=true
screen/support_large=true
screen/support_xlarge=true
+screen/background_color=Color(0, 0, 0, 1)
user_data_backup/allow=false
command_line/extra_args=""
apk_expansion/enable=false
@@ -920,6 +982,7 @@ permissions/manage_accounts=false
permissions/manage_app_tokens=false
permissions/manage_documents=false
permissions/manage_external_storage=false
+permissions/manage_media=false
permissions/master_clear=false
permissions/media_content_control=false
permissions/modify_audio_settings=false
@@ -1004,7 +1067,6 @@ permissions/write_user_dictionary=false
name="i686-linux-android"
platform="Android"
runnable=false
-advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
@@ -1012,6 +1074,11 @@ include_filter="*.ini, *.ini1"
exclude_filter=""
export_path=""
patches=PackedStringArray()
+patch_delta_encoding=false
+patch_delta_compression_level_zstd=19
+patch_delta_min_reduction=0.1
+patch_delta_include_filters="*"
+patch_delta_exclude_filters=""
encryption_include_filters=""
encryption_exclude_filters=""
seed=0
@@ -1030,6 +1097,7 @@ gradle_build/compress_native_libraries=false
gradle_build/export_format=0
gradle_build/min_sdk=""
gradle_build/target_sdk=""
+gradle_build/custom_theme_attributes={}
architectures/armeabi-v7a=false
architectures/arm64-v8a=false
architectures/x86=true
@@ -1050,13 +1118,242 @@ launcher_icons/adaptive_foreground_432x432="res://icons/adaptive-foreground.png"
launcher_icons/adaptive_background_432x432="res://icons/adaptive-background.png"
launcher_icons/adaptive_monochrome_432x432=""
graphics/opengl_debug=false
+shader_baker/enabled=false
+xr_features/xr_mode=0
+gesture/swipe_to_dismiss=false
+screen/immersive_mode=true
+screen/edge_to_edge=false
+screen/support_small=true
+screen/support_normal=true
+screen/support_large=true
+screen/support_xlarge=true
+screen/background_color=Color(0, 0, 0, 1)
+user_data_backup/allow=false
+command_line/extra_args=""
+apk_expansion/enable=false
+apk_expansion/SALT=""
+apk_expansion/public_key=""
+permissions/custom_permissions=PackedStringArray()
+permissions/access_checkin_properties=false
+permissions/access_coarse_location=false
+permissions/access_fine_location=false
+permissions/access_location_extra_commands=false
+permissions/access_media_location=false
+permissions/access_mock_location=false
+permissions/access_network_state=false
+permissions/access_surface_flinger=false
+permissions/access_wifi_state=false
+permissions/account_manager=false
+permissions/add_voicemail=false
+permissions/authenticate_accounts=false
+permissions/battery_stats=false
+permissions/bind_accessibility_service=false
+permissions/bind_appwidget=false
+permissions/bind_device_admin=false
+permissions/bind_input_method=false
+permissions/bind_nfc_service=false
+permissions/bind_notification_listener_service=false
+permissions/bind_print_service=false
+permissions/bind_remoteviews=false
+permissions/bind_text_service=false
+permissions/bind_vpn_service=false
+permissions/bind_wallpaper=false
+permissions/bluetooth=false
+permissions/bluetooth_admin=false
+permissions/bluetooth_privileged=false
+permissions/brick=false
+permissions/broadcast_package_removed=false
+permissions/broadcast_sms=false
+permissions/broadcast_sticky=false
+permissions/broadcast_wap_push=false
+permissions/call_phone=false
+permissions/call_privileged=false
+permissions/camera=false
+permissions/capture_audio_output=false
+permissions/capture_secure_video_output=false
+permissions/capture_video_output=false
+permissions/change_component_enabled_state=false
+permissions/change_configuration=false
+permissions/change_network_state=false
+permissions/change_wifi_multicast_state=false
+permissions/change_wifi_state=false
+permissions/clear_app_cache=false
+permissions/clear_app_user_data=false
+permissions/control_location_updates=false
+permissions/delete_cache_files=false
+permissions/delete_packages=false
+permissions/device_power=false
+permissions/diagnostic=false
+permissions/disable_keyguard=false
+permissions/dump=false
+permissions/expand_status_bar=false
+permissions/factory_test=false
+permissions/flashlight=false
+permissions/force_back=false
+permissions/get_accounts=false
+permissions/get_package_size=false
+permissions/get_tasks=false
+permissions/get_top_activity_info=false
+permissions/global_search=false
+permissions/hardware_test=false
+permissions/inject_events=false
+permissions/install_location_provider=false
+permissions/install_packages=false
+permissions/install_shortcut=false
+permissions/internal_system_window=false
+permissions/internet=true
+permissions/kill_background_processes=false
+permissions/location_hardware=false
+permissions/manage_accounts=false
+permissions/manage_app_tokens=false
+permissions/manage_documents=false
+permissions/manage_external_storage=false
+permissions/manage_media=false
+permissions/master_clear=false
+permissions/media_content_control=false
+permissions/modify_audio_settings=false
+permissions/modify_phone_state=false
+permissions/mount_format_filesystems=false
+permissions/mount_unmount_filesystems=false
+permissions/nfc=false
+permissions/persistent_activity=false
+permissions/post_notifications=false
+permissions/process_outgoing_calls=false
+permissions/read_calendar=false
+permissions/read_call_log=false
+permissions/read_contacts=false
+permissions/read_external_storage=false
+permissions/read_frame_buffer=false
+permissions/read_history_bookmarks=false
+permissions/read_input_state=false
+permissions/read_logs=false
+permissions/read_media_audio=false
+permissions/read_media_images=false
+permissions/read_media_video=false
+permissions/read_media_visual_user_selected=false
+permissions/read_phone_state=false
+permissions/read_profile=false
+permissions/read_sms=false
+permissions/read_social_stream=false
+permissions/read_sync_settings=false
+permissions/read_sync_stats=false
+permissions/read_user_dictionary=false
+permissions/reboot=false
+permissions/receive_boot_completed=false
+permissions/receive_mms=false
+permissions/receive_sms=false
+permissions/receive_wap_push=false
+permissions/record_audio=false
+permissions/reorder_tasks=false
+permissions/restart_packages=false
+permissions/send_respond_via_message=false
+permissions/send_sms=false
+permissions/set_activity_watcher=false
+permissions/set_alarm=false
+permissions/set_always_finish=false
+permissions/set_animation_scale=false
+permissions/set_debug_app=false
+permissions/set_orientation=false
+permissions/set_pointer_speed=false
+permissions/set_preferred_applications=false
+permissions/set_process_limit=false
+permissions/set_time=false
+permissions/set_time_zone=false
+permissions/set_wallpaper=false
+permissions/set_wallpaper_hints=false
+permissions/signal_persistent_processes=false
+permissions/status_bar=false
+permissions/subscribed_feeds_read=false
+permissions/subscribed_feeds_write=false
+permissions/system_alert_window=false
+permissions/transmit_ir=false
+permissions/uninstall_shortcut=false
+permissions/update_device_stats=false
+permissions/use_credentials=false
+permissions/use_sip=false
+permissions/vibrate=true
+permissions/wake_lock=false
+permissions/write_apn_settings=false
+permissions/write_calendar=false
+permissions/write_call_log=false
+permissions/write_contacts=false
+permissions/write_external_storage=false
+permissions/write_gservices=false
+permissions/write_history_bookmarks=false
+permissions/write_profile=false
+permissions/write_secure_settings=false
+permissions/write_settings=false
+permissions/write_sms=false
+permissions/write_social_stream=false
+permissions/write_sync_settings=false
+permissions/write_user_dictionary=false
+
+[preset.11]
+
+name="all-linux-android"
+platform="Android"
+runnable=false
+dedicated_server=false
+custom_features=""
+export_filter="all_resources"
+include_filter="*.ini, *.ini1"
+exclude_filter=""
+export_path=""
+patches=PackedStringArray()
+patch_delta_encoding=false
+patch_delta_compression_level_zstd=19
+patch_delta_min_reduction=0.1
+patch_delta_include_filters="*"
+patch_delta_exclude_filters=""
+encryption_include_filters=""
+encryption_exclude_filters=""
+seed=0
+encrypt_pck=false
+encrypt_directory=false
+script_export_mode=2
+
+[preset.11.options]
+
+custom_template/debug=""
+custom_template/release=""
+gradle_build/use_gradle_build=false
+gradle_build/gradle_build_directory=""
+gradle_build/android_source_template=""
+gradle_build/compress_native_libraries=false
+gradle_build/export_format=0
+gradle_build/min_sdk=""
+gradle_build/target_sdk=""
+gradle_build/custom_theme_attributes={}
+architectures/armeabi-v7a=true
+architectures/arm64-v8a=true
+architectures/x86=true
+architectures/x86_64=true
+version/code=1
+version/name=""
+package/unique_name="org.metamuffin.hurrycurry.client"
+package/name="Hurry Curry!"
+package/signed=true
+package/app_category=2
+package/retain_data_on_uninstall=false
+package/exclude_from_recents=false
+package/show_in_android_tv=false
+package/show_in_app_library=true
+package/show_as_launcher_app=false
+launcher_icons/main_192x192=""
+launcher_icons/adaptive_foreground_432x432="uid://djhxp3qw64mfb"
+launcher_icons/adaptive_background_432x432="uid://b7dnxjg0e1myc"
+launcher_icons/adaptive_monochrome_432x432=""
+graphics/opengl_debug=false
+shader_baker/enabled=false
xr_features/xr_mode=0
gesture/swipe_to_dismiss=false
screen/immersive_mode=true
+screen/edge_to_edge=false
screen/support_small=true
screen/support_normal=true
screen/support_large=true
screen/support_xlarge=true
+screen/background_color=Color(0, 0, 0, 1)
user_data_backup/allow=false
command_line/extra_args=""
apk_expansion/enable=false
@@ -1137,6 +1434,7 @@ permissions/manage_accounts=false
permissions/manage_app_tokens=false
permissions/manage_documents=false
permissions/manage_external_storage=false
+permissions/manage_media=false
permissions/master_clear=false
permissions/media_content_control=false
permissions/modify_audio_settings=false
@@ -1215,3 +1513,263 @@ permissions/write_sms=false
permissions/write_social_stream=false
permissions/write_sync_settings=false
permissions/write_user_dictionary=false
+
+[preset.12]
+
+name="all-apple-darwin"
+platform="macOS"
+runnable=true
+dedicated_server=false
+custom_features=""
+export_filter="all_resources"
+include_filter="*.ini, *.ini1"
+exclude_filter=""
+export_path=""
+patches=PackedStringArray()
+patch_delta_encoding=false
+patch_delta_compression_level_zstd=19
+patch_delta_min_reduction=0.1
+patch_delta_include_filters="*"
+patch_delta_exclude_filters=""
+encryption_include_filters=""
+encryption_exclude_filters=""
+seed=0
+encrypt_pck=false
+encrypt_directory=false
+script_export_mode=2
+
+[preset.12.options]
+
+export/distribution_type=1
+binary_format/architecture="universal"
+custom_template/debug=""
+custom_template/release=""
+debug/export_console_wrapper=1
+application/liquid_glass_icon=""
+application/icon="uid://b1hb26s0blceb"
+application/icon_interpolation=4
+application/bundle_identifier="org.hurrycurry.client"
+application/signature=""
+application/app_category="Games"
+application/short_version=""
+application/version=""
+application/copyright=""
+application/copyright_localized={}
+application/min_macos_version_x86_64="10.12"
+application/min_macos_version_arm64="11.00"
+application/export_angle=0
+display/high_res=true
+shader_baker/enabled=false
+application/additional_plist_content=""
+xcode/platform_build="14C18"
+xcode/sdk_version="13.1"
+xcode/sdk_build="22C55"
+xcode/sdk_name="macosx13.1"
+xcode/xcode_version="1420"
+xcode/xcode_build="14C18"
+codesign/codesign=1
+codesign/installer_identity=""
+codesign/apple_team_id=""
+codesign/identity=""
+codesign/entitlements/custom_file=""
+codesign/entitlements/allow_jit_code_execution=false
+codesign/entitlements/allow_unsigned_executable_memory=false
+codesign/entitlements/allow_dyld_environment_variables=false
+codesign/entitlements/disable_library_validation=false
+codesign/entitlements/audio_input=false
+codesign/entitlements/camera=false
+codesign/entitlements/location=false
+codesign/entitlements/address_book=false
+codesign/entitlements/calendars=false
+codesign/entitlements/photos_library=false
+codesign/entitlements/apple_events=false
+codesign/entitlements/debugging=false
+codesign/entitlements/app_sandbox/enabled=false
+codesign/entitlements/app_sandbox/network_server=false
+codesign/entitlements/app_sandbox/network_client=false
+codesign/entitlements/app_sandbox/device_usb=false
+codesign/entitlements/app_sandbox/device_bluetooth=false
+codesign/entitlements/app_sandbox/files_downloads=0
+codesign/entitlements/app_sandbox/files_pictures=0
+codesign/entitlements/app_sandbox/files_music=0
+codesign/entitlements/app_sandbox/files_movies=0
+codesign/entitlements/app_sandbox/files_user_selected=0
+codesign/entitlements/app_sandbox/helper_executables=[]
+codesign/entitlements/additional=""
+codesign/custom_options=PackedStringArray()
+notarization/notarization=0
+privacy/microphone_usage_description=""
+privacy/microphone_usage_description_localized={}
+privacy/camera_usage_description=""
+privacy/camera_usage_description_localized={}
+privacy/location_usage_description=""
+privacy/location_usage_description_localized={}
+privacy/address_book_usage_description=""
+privacy/address_book_usage_description_localized={}
+privacy/calendar_usage_description=""
+privacy/calendar_usage_description_localized={}
+privacy/photos_library_usage_description=""
+privacy/photos_library_usage_description_localized={}
+privacy/desktop_folder_usage_description=""
+privacy/desktop_folder_usage_description_localized={}
+privacy/documents_folder_usage_description=""
+privacy/documents_folder_usage_description_localized={}
+privacy/downloads_folder_usage_description=""
+privacy/downloads_folder_usage_description_localized={}
+privacy/network_volumes_usage_description=""
+privacy/network_volumes_usage_description_localized={}
+privacy/removable_volumes_usage_description=""
+privacy/removable_volumes_usage_description_localized={}
+privacy/tracking_enabled=false
+privacy/tracking_domains=PackedStringArray()
+privacy/collected_data/name/collected=false
+privacy/collected_data/name/linked_to_user=false
+privacy/collected_data/name/used_for_tracking=false
+privacy/collected_data/name/collection_purposes=0
+privacy/collected_data/email_address/collected=false
+privacy/collected_data/email_address/linked_to_user=false
+privacy/collected_data/email_address/used_for_tracking=false
+privacy/collected_data/email_address/collection_purposes=0
+privacy/collected_data/phone_number/collected=false
+privacy/collected_data/phone_number/linked_to_user=false
+privacy/collected_data/phone_number/used_for_tracking=false
+privacy/collected_data/phone_number/collection_purposes=0
+privacy/collected_data/physical_address/collected=false
+privacy/collected_data/physical_address/linked_to_user=false
+privacy/collected_data/physical_address/used_for_tracking=false
+privacy/collected_data/physical_address/collection_purposes=0
+privacy/collected_data/other_contact_info/collected=false
+privacy/collected_data/other_contact_info/linked_to_user=false
+privacy/collected_data/other_contact_info/used_for_tracking=false
+privacy/collected_data/other_contact_info/collection_purposes=0
+privacy/collected_data/health/collected=false
+privacy/collected_data/health/linked_to_user=false
+privacy/collected_data/health/used_for_tracking=false
+privacy/collected_data/health/collection_purposes=0
+privacy/collected_data/fitness/collected=false
+privacy/collected_data/fitness/linked_to_user=false
+privacy/collected_data/fitness/used_for_tracking=false
+privacy/collected_data/fitness/collection_purposes=0
+privacy/collected_data/payment_info/collected=false
+privacy/collected_data/payment_info/linked_to_user=false
+privacy/collected_data/payment_info/used_for_tracking=false
+privacy/collected_data/payment_info/collection_purposes=0
+privacy/collected_data/credit_info/collected=false
+privacy/collected_data/credit_info/linked_to_user=false
+privacy/collected_data/credit_info/used_for_tracking=false
+privacy/collected_data/credit_info/collection_purposes=0
+privacy/collected_data/other_financial_info/collected=false
+privacy/collected_data/other_financial_info/linked_to_user=false
+privacy/collected_data/other_financial_info/used_for_tracking=false
+privacy/collected_data/other_financial_info/collection_purposes=0
+privacy/collected_data/precise_location/collected=false
+privacy/collected_data/precise_location/linked_to_user=false
+privacy/collected_data/precise_location/used_for_tracking=false
+privacy/collected_data/precise_location/collection_purposes=0
+privacy/collected_data/coarse_location/collected=false
+privacy/collected_data/coarse_location/linked_to_user=false
+privacy/collected_data/coarse_location/used_for_tracking=false
+privacy/collected_data/coarse_location/collection_purposes=0
+privacy/collected_data/sensitive_info/collected=false
+privacy/collected_data/sensitive_info/linked_to_user=false
+privacy/collected_data/sensitive_info/used_for_tracking=false
+privacy/collected_data/sensitive_info/collection_purposes=0
+privacy/collected_data/contacts/collected=false
+privacy/collected_data/contacts/linked_to_user=false
+privacy/collected_data/contacts/used_for_tracking=false
+privacy/collected_data/contacts/collection_purposes=0
+privacy/collected_data/emails_or_text_messages/collected=false
+privacy/collected_data/emails_or_text_messages/linked_to_user=false
+privacy/collected_data/emails_or_text_messages/used_for_tracking=false
+privacy/collected_data/emails_or_text_messages/collection_purposes=0
+privacy/collected_data/photos_or_videos/collected=false
+privacy/collected_data/photos_or_videos/linked_to_user=false
+privacy/collected_data/photos_or_videos/used_for_tracking=false
+privacy/collected_data/photos_or_videos/collection_purposes=0
+privacy/collected_data/audio_data/collected=false
+privacy/collected_data/audio_data/linked_to_user=false
+privacy/collected_data/audio_data/used_for_tracking=false
+privacy/collected_data/audio_data/collection_purposes=0
+privacy/collected_data/gameplay_content/collected=false
+privacy/collected_data/gameplay_content/linked_to_user=false
+privacy/collected_data/gameplay_content/used_for_tracking=false
+privacy/collected_data/gameplay_content/collection_purposes=0
+privacy/collected_data/customer_support/collected=false
+privacy/collected_data/customer_support/linked_to_user=false
+privacy/collected_data/customer_support/used_for_tracking=false
+privacy/collected_data/customer_support/collection_purposes=0
+privacy/collected_data/other_user_content/collected=false
+privacy/collected_data/other_user_content/linked_to_user=false
+privacy/collected_data/other_user_content/used_for_tracking=false
+privacy/collected_data/other_user_content/collection_purposes=0
+privacy/collected_data/browsing_history/collected=false
+privacy/collected_data/browsing_history/linked_to_user=false
+privacy/collected_data/browsing_history/used_for_tracking=false
+privacy/collected_data/browsing_history/collection_purposes=0
+privacy/collected_data/search_history/collected=false
+privacy/collected_data/search_history/linked_to_user=false
+privacy/collected_data/search_history/used_for_tracking=false
+privacy/collected_data/search_history/collection_purposes=0
+privacy/collected_data/user_id/collected=false
+privacy/collected_data/user_id/linked_to_user=false
+privacy/collected_data/user_id/used_for_tracking=false
+privacy/collected_data/user_id/collection_purposes=0
+privacy/collected_data/device_id/collected=false
+privacy/collected_data/device_id/linked_to_user=false
+privacy/collected_data/device_id/used_for_tracking=false
+privacy/collected_data/device_id/collection_purposes=0
+privacy/collected_data/purchase_history/collected=false
+privacy/collected_data/purchase_history/linked_to_user=false
+privacy/collected_data/purchase_history/used_for_tracking=false
+privacy/collected_data/purchase_history/collection_purposes=0
+privacy/collected_data/product_interaction/collected=false
+privacy/collected_data/product_interaction/linked_to_user=false
+privacy/collected_data/product_interaction/used_for_tracking=false
+privacy/collected_data/product_interaction/collection_purposes=0
+privacy/collected_data/advertising_data/collected=false
+privacy/collected_data/advertising_data/linked_to_user=false
+privacy/collected_data/advertising_data/used_for_tracking=false
+privacy/collected_data/advertising_data/collection_purposes=0
+privacy/collected_data/other_usage_data/collected=false
+privacy/collected_data/other_usage_data/linked_to_user=false
+privacy/collected_data/other_usage_data/used_for_tracking=false
+privacy/collected_data/other_usage_data/collection_purposes=0
+privacy/collected_data/crash_data/collected=false
+privacy/collected_data/crash_data/linked_to_user=false
+privacy/collected_data/crash_data/used_for_tracking=false
+privacy/collected_data/crash_data/collection_purposes=0
+privacy/collected_data/performance_data/collected=false
+privacy/collected_data/performance_data/linked_to_user=false
+privacy/collected_data/performance_data/used_for_tracking=false
+privacy/collected_data/performance_data/collection_purposes=0
+privacy/collected_data/other_diagnostic_data/collected=false
+privacy/collected_data/other_diagnostic_data/linked_to_user=false
+privacy/collected_data/other_diagnostic_data/used_for_tracking=false
+privacy/collected_data/other_diagnostic_data/collection_purposes=0
+privacy/collected_data/environment_scanning/collected=false
+privacy/collected_data/environment_scanning/linked_to_user=false
+privacy/collected_data/environment_scanning/used_for_tracking=false
+privacy/collected_data/environment_scanning/collection_purposes=0
+privacy/collected_data/hands/collected=false
+privacy/collected_data/hands/linked_to_user=false
+privacy/collected_data/hands/used_for_tracking=false
+privacy/collected_data/hands/collection_purposes=0
+privacy/collected_data/head/collected=false
+privacy/collected_data/head/linked_to_user=false
+privacy/collected_data/head/used_for_tracking=false
+privacy/collected_data/head/collection_purposes=0
+privacy/collected_data/other_data_types/collected=false
+privacy/collected_data/other_data_types/linked_to_user=false
+privacy/collected_data/other_data_types/used_for_tracking=false
+privacy/collected_data/other_data_types/collection_purposes=0
+ssh_remote_deploy/enabled=false
+ssh_remote_deploy/host="user@host_ip"
+ssh_remote_deploy/port="22"
+ssh_remote_deploy/extra_args_ssh=""
+ssh_remote_deploy/extra_args_scp=""
+ssh_remote_deploy/run_script="#!/usr/bin/env bash
+unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\"
+open \"{temp_dir}/{exe_name}.app\" --args {cmd_args}"
+ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash
+pkill -x -f \"{temp_dir}/{exe_name}.app/Contents/MacOS/{exe_name} {cmd_args}\"
+rm -rf \"{temp_dir}\""
diff --git a/client/game.gd b/client/game.gd
index e9dff85b..157188e4 100644
--- a/client/game.gd
+++ b/client/game.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -18,7 +18,6 @@ extends Node3D
signal update_players(players: Dictionary)
signal data_updated()
-signal in_lobby_updated(in_lobby: bool)
signal join_state_updated(state: JoinState)
signal text_message(message: TextMessage)
signal update_tutorial_running(running: bool)
@@ -30,6 +29,12 @@ class TextMessage:
var timeout_initial: float
var timeout_remaining
+class ServerContext:
+ var name: String
+ var motd#: String?
+ func _init(name_: String, motd_) -> void:
+ name = name_; motd = motd_
+
enum SpectatingMode {
CENTER,
FREE,
@@ -43,13 +48,13 @@ enum JoinState {
var my_player_id: float = -1
var item_names: Array = []
-var item_index_by_name: Dictionary = {}
var tile_names: Array = []
-var tile_index_by_name: Dictionary = {}
-var tile_walkable: Dictionary = {}
-var tile_placeable_items: Dictionary = {}
-var tile_interactable_empty: Dictionary = {}
+var tile_collide: Array[String] = []
+var tile_placeable_any: Array[String] = []
+var tile_placeable_items: Dictionary[String, Array] = {} # Dictionary[String, Array[String]]
+var tile_interactable_empty: Array[String] = []
var maps: Array = []
+var server_context: ServerContext
var bot_algos: Array
var text_message_history: Array[TextMessage] = []
@@ -59,16 +64,14 @@ var in_lobby := false
var is_replay := false
var tutorial_running := false
var tutorial_queue := []
-var last_position = null # : Vector2?
-var players := {}
+var players: Dictionary[float, Player] = {}
var spectating_mode: SpectatingMode = SpectatingMode.CENTER
@onready var mp: Multiplayer = $Multiplayer
@onready var map: Map = $Map
# TODO move all of this somewhere else
-@onready var overlay_lobby: Lobby = $"../Overlays/Lobby"
@onready var overlay_score: Overlay = $"../Overlays/Score"
@onready var overlay_popup_message: PopupMessage = $"../Overlays/PopupMessage"
@onready var overlay_pinned_messages: PinnedItemMessages = $"../Overlays/PinnedMessages"
@@ -78,10 +81,9 @@ var spectating_mode: SpectatingMode = SpectatingMode.CENTER
func _ready():
mp.packet.connect(handle_packet)
- mp.connection_closed.connect(func(reason: String):
- get_parent().replace_menu("res://gui/menus/error.tscn", [reason, menu.data])
- )
- mp.connect_to_url(menu.data)
+ mp.connection_closed.connect(func(reason: String): show_error(reason))
+ mp.connect_to_urls(menu.data)
+
text_message.connect(func(m):
text_message_history.push_back(m)
while text_message_history.size() > 64:
@@ -91,39 +93,33 @@ func _ready():
func handle_packet(p):
match p.type:
"joined": my_player_id = p.id
- "data":
- item_names = p["data"]["item_names"]
- tile_names = p["data"]["tile_names"]
- tile_walkable = {}
- for tile in p["data"]["tile_walkable"]: tile_walkable[int(tile)] = true
- tile_interactable_empty = {}
- for tile in p["data"]["tile_interactable_empty"]: tile_interactable_empty[int(tile)] = true
+ "server_data":
+ maps = p["maps"]
+ bot_algos = p["bot_algos"]
+ server_context = ServerContext.new(p["name"], p["motd"])
+ "game_data":
+ item_names = p["item_names"]
+ tile_names = p["tile_names"]
+ tile_collide = []
+ tile_interactable_empty = []
+ tile_placeable_any = []
tile_placeable_items = {}
- for tile in p["data"]["tile_placeable_items"]:
- tile_placeable_items[int(tile)] = p["data"]["tile_placeable_items"][tile].map(func(x): return int(x))
- maps = p["data"]["maps"]
- bot_algos = p["data"]["bot_algos"]
- Global.hand_count = p["data"]["hand_count"]
+ for tile in p["tile_collide"]: tile_collide.append(tile_names[int(tile)])
+ for tile in p["tile_interactable_empty"]: tile_interactable_empty.append(tile_names[int(tile)])
+ for tile in p["tile_placeable_any"]: tile_placeable_any.append(tile_names[int(tile)])
+ for tile in p["tile_placeable_items"]:
+ tile_placeable_items[tile_names[int(tile)]] = p["tile_placeable_items"][tile].map(func(x): return item_names[int(x)])
+ Global.hand_count = p["hand_count"]
Global.hand_count_change.emit(Global.hand_count)
- tile_index_by_name.clear()
- for id in tile_names.size():
- tile_index_by_name[tile_names[id]] = id
-
- item_index_by_name.clear()
- for i in range(item_names.size()):
- item_index_by_name[item_names[i]] = i
-
Global.last_map_name = Global.current_map_name
- Global.current_map_name = p["data"]["current_map"]
+ Global.current_map_name = p.metadata.name
data_updated.emit()
"add_player":
var player_instance: Player
if p.id == my_player_id:
player_instance = ControllablePlayer.new(p.id, p.name, p.position, p.character, p.class, self)
- in_lobby_updated.connect(player_instance.onscreen_controls.in_lobby_updated)
- player_instance.onscreen_controls.in_lobby_updated(in_lobby)
follow_camera.target = player_instance.movement_base
follow_camera.reset()
set_join_state(JoinState.JOINED)
@@ -145,7 +141,6 @@ func handle_packet(p):
if p.id == my_player_id:
set_join_state(JoinState.SPECTATING)
follow_camera.target = $Center
- last_position = null
for h in player.hand:
if h != null:
h.queue_free()
@@ -155,35 +150,34 @@ func handle_packet(p):
"movement":
if not players.has(p.player): return
var player_instance: Player = players[p.player]
- player_instance.update_position(p.pos, p.rot, p.boost)
- if p.player == my_player_id: last_position = p.pos
- "movement_sync":
- if not players.has(my_player_id): return
- var player_instance: ControllablePlayer = players[my_player_id]
- if last_position != null:
- player_instance.position_ = last_position
+ player_instance.update_position(p.pos, p.dir, p.rot, p.boost)
+ if p.player == my_player_id and p.get("sync"): player_instance.position_ = p.pos
"move_item":
if "player" in p.from and "player" in p.to:
players[p.from.player[0]].pass_to(players[p.to.player[0]], int(p.from.player[1]), int(p.to.player[1]))
elif "tile" in p.from and "player" in p.to:
- var t: Tile = map.get_tile_instance(p.from.tile)
+ var t: Tile = map.get_topmost_instance(p.from.tile)
players[p.to.player[0]].take_item(t, int(p.to.player[1]))
elif "player" in p.from and "tile" in p.to:
- var t: Tile = map.get_tile_instance(p.to.tile)
+ var t: Tile = map.get_topmost_instance(p.to.tile)
players[p.from.player[0]].put_item(t, int(p.from.player[1]))
elif "tile" in p.from and "tile" in p.to:
- var from_tile2: Tile = map.get_tile_instance(p.from.tile)
- var to_tile2: Tile = map.get_tile_instance(p.to.tile)
+ var from_tile2: Tile = map.get_topmost_instance(p.from.tile)
+ var to_tile2: Tile = map.get_topmost_instance(p.to.tile)
from_tile2.pass_to(to_tile2)
"set_progress":
if "tile" in p.item:
- var t: Tile = map.get_tile_instance(p.item.tile)
- t.progress(p.position, p.speed, p.warn, players.get(p.player))
+ var t: Tile = map.get_topmost_instance(p.item.tile)
+ var acting_players: Array[Player] = []
+ for id: float in p.players:
+ if !players.has(id): continue
+ acting_players.append(players[id])
+ t.progress(p.position, p.speed, p.warn, acting_players)
else:
players[p.item.player[0]].progress(p.position, p.speed, p.warn, int(p.item.player[1]))
"clear_progress":
if "tile" in p.item:
- var t: Tile = map.get_tile_instance(p.item.tile)
+ var t: Tile = map.get_topmost_instance(p.item.tile)
t.finish()
else:
players[p.item.player[0]].finish(int(p.item.player[1]))
@@ -191,7 +185,7 @@ func handle_packet(p):
var location: Dictionary = p["location"]
if p.item != null:
if "tile" in p.location:
- var t: Tile = map.get_tile_instance(p.location.tile)
+ var t: Tile = map.get_topmost_instance(p.location.tile)
var i = ItemFactory.produce(item_names[p.item], t.item_base)
i.animate_spawn()
i.position = t.item_base.global_position
@@ -215,7 +209,7 @@ func handle_packet(p):
pl.set_item(i, h)
else:
if "tile" in p.location:
- var t: Tile = map.get_tile_instance(p.location.tile)
+ var t: Tile = map.get_topmost_instance(p.location.tile)
t.finish()
t.set_item(null)
else:
@@ -224,99 +218,101 @@ func handle_packet(p):
pl.finish(h)
pl.set_item(null, h)
"update_map":
- var neighbors: Array = p["neighbors"]
- if p.kind != null:
- if neighbors != null: neighbors = neighbors.map(func(x): return tile_names[x] if x != null else null)
- map.set_tile(p.tile, tile_names[p.kind], neighbors)
- else: map.clear_tile(p.tile)
- "flush_map":
+ var changes: Dictionary[Vector2i, Array] = {} # Dictionary[Vector2i, Array[String]]
+ for change in p["changes"]:
+ var pos := Vector2i(change[0][0], change[0][1])
+ var tiles: Array = change[1].map(func(x): return tile_names[int(x)] if x != null else null) # : Array[String]
+ changes[pos] = tiles
+
+ map.set_all_tiles(changes, server_context)
map.flush()
"communicate":
+ # TODO: use MessageParser
var timeout_initial: float = p.timeout.initial if p.timeout != null else 5.
var timeout_remaining: float = p.timeout.remaining if p.timeout != null else 5.
var pinned: bool = p.timeout.pinned if p.timeout != null and "pinned" in p.timeout else false
if p.message != null:
- if "item" in p.message:
- var item_name: String = item_names[p.message.item]
- var parsed_item := ItemFactory.ItemName.new(item_name)
- var ingredients := [parsed_item.name]
- ingredients.append_array(parsed_item.contents)
-
- if pinned:
- overlay_pinned_messages.pin_item(item_name, timeout_initial, timeout_remaining, p.player)
-
- var player: Player = players[p.player]
- player.item_message(item_name, timeout_initial, timeout_remaining)
-
- # Maybe start tutorial
- # after joining, the last item message that popped up is ignored. the next one will
- # be used for the tutorial
- if (player.is_customer
- and not Settings.read("gameplay.tutorial_disabled")
- and join_state == JoinState.JOINED):
- var completed_ingredients: Array = Profile.read("tutorial_ingredients_played")
- var completed := Global.array_has_all(completed_ingredients, ingredients)
-
- if not completed:
- if tutorial_running:
- tutorial_queue.push_back(item_name)
- else:
- tutorial_running = true
- update_tutorial_running.emit(tutorial_running)
- mp.send_chat(my_player_id, "/start-tutorial %s" % item_name)
- elif "text" in p.message or "translation" in p.message:
- var data = TextMessage.new()
- data.timeout_initial = timeout_initial
- data.timeout_remaining = timeout_remaining
- if pinned:
- push_error("Pinned text messages are currently not supported")
- var player: Player = players[p.player]
- data.color = Character.COLORS[G.rem_euclid(player.character_style.color, Character.COLORS.size())]
- data.username = players[p.player].username
- data.text = p.message.text if "text" in p.message else get_message_str(p.message)
+ var m = MessageParser.new(p.message, self)
+ match m.kind:
+ MessageParser.Kind.ITEM:
+ var item_name: String = m.result
+ var container := ItemFactory.ItemName.new(item_name)
+ var ingredients := [container.name]
+ ingredients.append_array(container.contents)
- player.text_message(data)
- text_message.emit(data)
- elif "tile" in p.message:
- push_error("TODO: tile message")
- else:
- push_error("unknown message kind")
+ if pinned:
+ overlay_pinned_messages.pin_item(item_name, timeout_initial, timeout_remaining, p.player)
+
+ var player: Player = players[p.player]
+ player.item_message(item_name, timeout_initial, timeout_remaining)
+
+ # Maybe start tutorial
+ # after joining, the last item message that popped up is ignored. the next one will
+ # be used for the tutorial
+ if (player.is_customer
+ and not Settings.read("gameplay.tutorial_disabled")
+ and join_state == JoinState.JOINED):
+ var completed_ingredients: Array = Profile.read("tutorial_ingredients_played")
+ var completed := Global.array_has_all(completed_ingredients, ingredients)
+
+ if not completed:
+ if tutorial_running:
+ tutorial_queue.push_back(item_name)
+ else:
+ tutorial_running = true
+ update_tutorial_running.emit(tutorial_running)
+ mp.send_chat(my_player_id, "/start-tutorial %s" % item_name)
+ MessageParser.Kind.TEXT:
+ var data = TextMessage.new()
+ data.timeout_initial = timeout_initial
+ data.timeout_remaining = timeout_remaining
+ if pinned:
+ push_error("Pinned text messages are currently not supported")
+ var player: Player = players[p.player]
+ data.color = Character.COLORS[G.rem_euclid(player.character_style.color, Character.COLORS.size())]
+ data.username = players[p.player].username
+ data.text = m.result
+
+ player.text_message(data)
+ text_message.emit(data)
+ _:
+ push_error("unsupported communicate message type")
else:
var player: Player = players[p.player]
if player.is_customer and player.current_item_message != null:
tutorial_queue.erase(player.current_item_message)
player.clear_text_message()
player.clear_item_message()
- player.clear_effect()
overlay_pinned_messages.clear_item(p.player)
"effect":
- players[p.player].effect_message(p.name)
+ var target
+ if "player" in p.location: target = players[p.location.player[0]].movement_base
+ elif "tile" in p.location: target = map.get_topmost_instance(p.location.tile).base
+ EffectFactory.play_effect(target, p)
+
"set_ingame":
in_lobby = p.lobby
overlay_score.set_ingame(p.state, p.lobby)
follow_camera.set_ingame(p.state, p.lobby)
if p.state:
- map.gi_bake()
+ reset_camera()
+ map.flush()
await get_parent()._menu_open()
- map.autobake = true
- in_lobby_updated.emit(in_lobby)
+ map.autoflush = true
if not in_lobby and not is_replay and not Global.using_touch and not join_state == JoinState.SPECTATING:
var using_joypad: bool = Global.using_joypad
var two_handed: bool = Global.hand_count >= 2
var profile_name: String = "controls_%s_%s_handed_explained" % [("joypad" if using_joypad else "keyboard"), ("two" if two_handed else "one")]
if not Profile.read(profile_name):
- menu.submenu("res://gui/overlays/controls_visualization/explanation.tscn", [profile_name, using_joypad, two_handed])
- else:
- mp.send_ready()
- else:
- mp.send_ready()
+ await menu.submenu("res://gui/overlays/controls_visualization/explanation.tscn", [profile_name, using_joypad, two_handed])
+ Profile.write(profile_name, true)
+ mp.send_ready()
else:
- map.autobake = false
+ map.autoflush = false
await get_parent()._menu_exit()
- if in_lobby: overlay_lobby.select_map(0)
if join_state == JoinState.SPECTATING:
if in_lobby:
toggle_join()
@@ -349,18 +345,23 @@ func handle_packet(p):
tutorial_queue.clear()
"menu":
match p.menu:
- "document":
- menu.submenu("res://gui/menus/document/document.tscn", p["data"])
"score":
menu.submenu("res://gui/menus/rating/rating.tscn", [p.data.stars, p.data.points])
+ "scoreboard":
+ menu.submenu("res://gui/menus/scoreboard.tscn", p.data)
"announce_start":
overlay_announce_title.announce_start()
+ "book":
+ menu.submenu("res://gui/menus/book/book.tscn", BookMenu.BookData.new(self, p.data))
+ "map_selector":
+ menu.submenu("res://gui/menus/map_selector/map_selector.tscn", [maps, bot_algos])
+ _:
+ push_error("Received unrecognized menu type %s" % p.menu)
"server_message":
- var mstr := get_message_str(p.message)
if p.error:
- overlay_popup_message.display_server_msg(tr("c.error.server").format([mstr]))
+ overlay_popup_message.display_server_msg(tr("c.error.server").format([MessageParser.new(p.message, self).result]))
else:
- overlay_popup_message.display_server_msg(mstr)
+ overlay_popup_message.display_server_msg(MessageParser.new(p.message, self).result)
"server_hint":
if p.player != my_player_id: return
@@ -370,19 +371,22 @@ func handle_packet(p):
if position_ == null:
# Global hint message
if message == null:
- overlay_popup_message.clear_server_msg()
+ overlay_popup_message.clear_server_hint()
else:
- overlay_popup_message.display_server_msg(get_message_str(message), false)
+ overlay_popup_message.display_server_hint(MessageParser.new(message, self).result)
else:
# Positional hint message
if message == null:
- overlay_popup_message.clear_server_msg(position_)
+ overlay_popup_message.clear_server_hint(position_)
else:
- overlay_popup_message.display_server_msg_positional(get_message_str(message), position_, false)
+ overlay_popup_message.display_server_hint_positional(MessageParser.new(message, self).result, position_, false)
"environment":
$Environment.update(p.effects)
"redirect":
get_parent().replace_menu("res://gui/menus/game.tscn", p.uri[0])
+ "disconnect":
+ var m := MessageParser.new(p.reason, self)
+ show_error(m.result)
"replay_start":
is_replay = true
"replay_stop":
@@ -391,8 +395,12 @@ func handle_packet(p):
"pause":
overlay_score.set_paused(p.state)
Global.game_paused = p.state
-
- _: push_error("Unrecognized packet type: %s" % p.type)
+ "debug":
+ pass # Only implemented in test client
+ _: push_warning("Unrecognized packet type: %s" % p.type)
+
+func show_error(message: String):
+ get_parent().replace_menu("res://gui/menus/error.tscn", [message, menu.data])
func system_message(s: String):
var message = TextMessage.new()
@@ -420,33 +428,35 @@ func _process(delta):
update_center()
if is_replay and mp != null:
- mp.send_replay_tick(delta)
-
-# TODO: move into PopupMessage and use RichTextLabel for tile/item images
-func get_message_str(m: Dictionary) -> String:
- if "translation" in m: return tr(m.translation.id).format(m.translation.params.map(get_message_str))
- if "tile" in m.keys(): return tile_names[m.tile]
- if "item" in m.keys(): return item_names[m.item]
- return Global.get_message_str(m)
+ mp.send_replay_tick(delta * float(Cli.opts.get("timescale", "1")))
func get_tile_collision(pos: Vector2i) -> bool:
- var t = map.get_tile_name(pos)
+ var t = map.get_tiles_at(pos)
if t == null: return true
- else: return not tile_walkable.has(tile_index_by_name[t])
+ else: return G.has_one(t, tile_collide)
-func get_tile_interactive(pos: Vector2i, hands: Array) -> bool:
- var tile_name = map.get_tile_name(pos)
- if tile_name == null: return false
- var tile = tile_index_by_name[tile_name]
- if map.get_tile_instance(pos).item != null: return true
- for hand in hands:
- if hand == null:
- if tile_interactable_empty.has(tile): return true
- else:
- if not tile_placeable_items.has(tile): return true
- if item_index_by_name[hand.item_name] in tile_placeable_items[tile]: return true
+func is_tile_interactive(pos: Vector2i, hands: Array) -> bool:
+ var tiles = map.get_tiles_at(pos)
+ if tiles == null: return false
+ if map.get_tile_item(pos) != null: return true # We can pick up this item with our empty hand!
+ for i in range(tiles.size() - 1, -1, -1):
+ var tile: String = tiles[i]
+ for hand in hands:
+ if hand == null:
+ if tile_interactable_empty.has(tile): return true
+ else:
+ if tile_placeable_any.has(tile): return true
+ if tile_placeable_items.has(tile):
+ return tile_placeable_items[tile].has(hand.item_name)
return false
+func reset_camera():
+ var extents = map.extents()
+ var map_center = ((extents[0] + extents[1]) / 2) + Vector2(.5, .5)
+ $FollowCamera.reset()
+ $Center.position = Vector3(map_center.x, 0., map_center.y)
+ $FollowCamera.jump_to_target()
+ $FollowCamera.camera_distance = 20.
func update_center():
$FollowCamera.autozoom = spectating_mode == SpectatingMode.CENTER and join_state == JoinState.SPECTATING
@@ -461,10 +471,8 @@ func update_center():
elif spectating_mode == SpectatingMode.FREE and Input.is_action_just_pressed("reset"):
spectating_mode = SpectatingMode.CENTER
match spectating_mode:
- SpectatingMode.CENTER:
- spectate_center()
- SpectatingMode.FREE:
- spectate_free()
+ SpectatingMode.CENTER: spectate_center()
+ SpectatingMode.FREE: spectate_free()
func spectate_center():
var any_chefs = false
@@ -501,7 +509,6 @@ func spectate_center():
$Center.position = Vector3(map_center.x, 0.,map_center.y)
$FollowCamera.camera_distance_target = (extents[1] - extents[0]).length() / 2
-
func spectate_free():
var direction := Input.get_vector("left", "right", "forwards", "backwards")
direction = direction.rotated(-follow_camera.angle_target)
diff --git a/client/game.tscn b/client/game.tscn
index 7189c84f..3556cd6b 100644
--- a/client/game.tscn
+++ b/client/game.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=6 format=3 uid="uid://c6krh36hoqfg8"]
+[gd_scene format=3 uid="uid://c6krh36hoqfg8"]
[ext_resource type="Script" uid="uid://tk4cdqtcuk4x" path="res://game.gd" id="1_sftfn"]
[ext_resource type="PackedScene" uid="uid://b31mlnao6ybt8" path="res://player/follow_camera.tscn" id="2_s8y6o"]
@@ -6,20 +6,20 @@
[ext_resource type="PackedScene" uid="uid://b4gone8fu53r7" path="res://map/map.tscn" id="6_prg6t"]
[ext_resource type="PackedScene" uid="uid://nroo08m5og0" path="res://map/environment/environment.tscn" id="7_v2apt"]
-[node name="Game" type="Node3D"]
+[node name="Game" type="Node3D" unique_id=438007157]
script = ExtResource("1_sftfn")
-[node name="Multiplayer" type="Node" parent="."]
+[node name="Multiplayer" type="Node" parent="." unique_id=1217792370]
script = ExtResource("6_fbxu8")
-[node name="FollowCamera" parent="." node_paths=PackedStringArray("target") instance=ExtResource("2_s8y6o")]
+[node name="FollowCamera" parent="." unique_id=183098155 node_paths=PackedStringArray("target") instance=ExtResource("2_s8y6o")]
transform = Transform3D(0.728777, 0.294253, -0.618303, 0, 0.902961, 0.429723, 0.684751, -0.313173, 0.658057, -2.36537, 1.99403, 3.29507)
current = true
far = 150.0
target = NodePath("../Center")
-[node name="Map" parent="." instance=ExtResource("6_prg6t")]
+[node name="Map" parent="." unique_id=1982524804 instance=ExtResource("6_prg6t")]
-[node name="Center" type="Node3D" parent="."]
+[node name="Center" type="Node3D" parent="." unique_id=1442964817]
-[node name="Environment" parent="." instance=ExtResource("7_v2apt")]
+[node name="Environment" parent="." unique_id=811858736 instance=ExtResource("7_v2apt")]
diff --git a/client/global.gd b/client/global.gd
index 35fd215e..72fb2f2b 100644
--- a/client/global.gd
+++ b/client/global.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -16,7 +16,7 @@
class_name G
extends Node
-const VERSION := "2.3.5"
+const VERSION := "3.0.1"
const DISTRIBUTION := "unknown"
signal using_joypad_change(using: bool)
@@ -37,6 +37,7 @@ var focused_node: Control
var focused_menu: Menu # only use this as a last resort, currently exists to open setup menu from settings
func _ready():
+ TranslationManager.load_locales()
GLTFDocument.register_gltf_document_extension(GLTFApplyNodeVisibility.new())
Profile.load(OS.get_data_dir().path_join("hurrycurry").path_join("profile"))
Settings.load(OS.get_config_dir().path_join("hurrycurry").path_join("settings.json"))
@@ -89,6 +90,10 @@ func on_vulkan() -> bool:
static func interpolate(current, target, dt):
return target + (current - target) * exp(-dt)
+static func interpolate_linear(current, target, dt):
+ if current > target: return max(target, current - dt)
+ else: return min(target, current + dt)
+
static func interpolate_angle(current, target, dt) -> float:
current = fmod(current, PI * 2)
target = fmod(target, PI * 2)
@@ -105,23 +110,33 @@ static func angle_closest_quarter(current, target) -> float:
else: target -= PI / 2
return target
-func find_menu(node: Node) -> Menu:
- if node is Menu: return node
- else: return find_menu(node.get_parent())
-
-func get_message_str(m: Dictionary) -> String:
- if "text" in m: return m.text
- if "translation" in m: return tr(m.translation.id).format(m.translation.params.map(get_message_str))
- return "[unsupported message type]"
-
func language_list():
var a = TranslationServer.get_loaded_locales()
a.sort()
a.insert(0, "system")
return a
-func array_eq(a, b):
- return a.all(func(e): return a.count(e) == b.count(e))
+func language_tooltip_list():
+ var out = []
+ for l in language_list():
+ var percentage = "%.0d" % (TranslationManager.LOCALE_STATS.get(l, 0.) * 100.)
+ out.append(tr("c.settings.ui.language.tooltip").format([percentage]))
+ return out
+
+func is_protocol_version_compatible(version: Array) -> bool:
+ return version[0] == Multiplayer.VERSION_MAJOR and version[1] <= Multiplayer.VERSION_MINOR
+
+static func unordered_array_eq(a: Array, b: Array) -> bool:
+ return unordered_array_subset(a, b) and unordered_array_subset(b, a)
+
+static func unordered_array_subset(a: Array, b: Array) -> bool:
+ return a.all(func(e): return b.has(e))
+
+static func unordered_array_difference(a: Array, b: Array) -> Array:
+ var c := []
+ for i in a:
+ if not b.has(i): c.append(i)
+ return c
static func add_missing_keys(dict: Dictionary, reference: Dictionary):
for k in reference.keys():
@@ -164,4 +179,15 @@ static func rem_euclid(i: int, mod: int) -> int:
num += mod
num %= mod
return num
-
+
+static func has_one(arr: Array, items: Array):
+ for item in items:
+ if arr.has(item):
+ return true
+ return false
+
+static func has_all(arr: Array, items: Array):
+ for item in items:
+ if not arr.has(item):
+ return false
+ return true
diff --git a/client/gui/components/blur_setup.gd b/client/gui/components/blur_setup.gd
index 6034aa7f..89a6b322 100644
--- a/client/gui/components/blur_setup.gd
+++ b/client/gui/components/blur_setup.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -18,7 +18,7 @@ class_name BlurSetup
func _ready():
update(Settings.read("graphics.ui_blur"))
- Settings.hook_changed("graphics.ui_blur", "main", update)
+ Settings.hook_changed("graphics.ui_blur", self, update)
func update(state):
material.set_shader_parameter("enable_blur", state)
diff --git a/client/gui/components/controller_button.gd b/client/gui/components/controller_button.gd
index 71f1332f..06de9bf3 100644
--- a/client/gui/components/controller_button.gd
+++ b/client/gui/components/controller_button.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/gui/components/message/chat_message.gd b/client/gui/components/message/chat_message.gd
index 27403701..547b2651 100644
--- a/client/gui/components/message/chat_message.gd
+++ b/client/gui/components/message/chat_message.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/gui/components/message/chat_message.tscn b/client/gui/components/message/chat_message.tscn
index 1478c738..e09b16e6 100644
--- a/client/gui/components/message/chat_message.tscn
+++ b/client/gui/components/message/chat_message.tscn
@@ -1,33 +1,31 @@
-[gd_scene load_steps=4 format=3 uid="uid://bpc2qgsvcafhe"]
+[gd_scene 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"]
+[node name="ChatMessage" type="VBoxContainer" unique_id=1631647881]
offset_right = 72.0
offset_bottom = 192.0
-theme = ExtResource("1_rx6vg")
script = ExtResource("1_ey0qp")
-[node name="Sender" type="Label" parent="."]
+[node name="Sender" type="Label" parent="." unique_id=1014991872]
layout_mode = 2
theme_override_fonts/font = SubResource("FontVariation_jfhbh")
text = "<Name>"
-[node name="FadeAway" type="Timer" parent="."]
+[node name="FadeAway" type="Timer" parent="." unique_id=2014646]
one_shot = true
-[node name="MarginContainer" type="MarginContainer" parent="."]
+[node name="MarginContainer" type="MarginContainer" parent="." unique_id=813671083]
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"]
+[node name="Message" type="Label" parent="MarginContainer" unique_id=1374308464]
layout_mode = 2
size_flags_horizontal = 3
text = "Message"
diff --git a/client/gui/components/message/item/item_message.gd b/client/gui/components/message/item/item_message.gd
index f5a97723..6ea0d1a0 100644
--- a/client/gui/components/message/item/item_message.gd
+++ b/client/gui/components/message/item/item_message.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/gui/components/message/item/item_message.tscn b/client/gui/components/message/item/item_message.tscn
index 59e0ebf9..1a858d31 100644
--- a/client/gui/components/message/item/item_message.tscn
+++ b/client/gui/components/message/item/item_message.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=6 format=3 uid="uid://fkqh36s4vl3p"]
+[gd_scene 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"]
@@ -12,7 +12,7 @@ corner_radius_top_right = 30
corner_radius_bottom_right = 30
corner_radius_bottom_left = 30
-[node name="ItemMessage" type="PanelContainer"]
+[node name="ItemMessage" type="PanelContainer" unique_id=1861821904]
auto_translate_mode = 2
clip_children = 2
offset_right = 256.0
@@ -21,24 +21,24 @@ size_flags_vertical = 0
theme_override_styles/panel = SubResource("StyleBoxFlat_dpele")
script = ExtResource("1_76lg0")
-[node name="VBoxContainer" type="VBoxContainer" parent="."]
+[node name="VBoxContainer" type="VBoxContainer" parent="." unique_id=28071380]
layout_mode = 2
size_flags_vertical = 0
theme_override_constants/separation = 0
-[node name="SubViewportContainer" type="SubViewportContainer" parent="VBoxContainer"]
+[node name="SubViewportContainer" type="SubViewportContainer" parent="VBoxContainer" unique_id=2111560579]
layout_mode = 2
-[node name="SubViewport" type="SubViewport" parent="VBoxContainer/SubViewportContainer"]
+[node name="SubViewport" type="SubViewport" parent="VBoxContainer/SubViewportContainer" unique_id=1284360089]
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="ItemRender" parent="VBoxContainer/SubViewportContainer/SubViewport" unique_id=1937813006 instance=ExtResource("1_sju7l")]
-[node name="ProgressBar" type="ProgressBar" parent="VBoxContainer"]
+[node name="ProgressBar" type="ProgressBar" parent="VBoxContainer" unique_id=299145094]
custom_minimum_size = Vector2(0, 32)
layout_mode = 2
theme_override_styles/background = ExtResource("3_t61n3")
diff --git a/client/gui/components/message/item/item_render.gd b/client/gui/components/message/item/item_render.gd
index 374644c3..0c488e64 100644
--- a/client/gui/components/message/item/item_render.gd
+++ b/client/gui/components/message/item/item_render.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/gui/components/message/item/item_render.tscn b/client/gui/components/message/item/item_render.tscn
index 3d993b7a..fb636eb4 100644
--- a/client/gui/components/message/item/item_render.tscn
+++ b/client/gui/components/message/item/item_render.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=3 format=3 uid="uid://cem5xcld6vn51"]
+[gd_scene format=3 uid="uid://cem5xcld6vn51"]
[ext_resource type="Script" uid="uid://bt7773og3p557" path="res://gui/components/message/item/item_render.gd" id="1_jfi7o"]
@@ -7,17 +7,17 @@ ambient_light_source = 2
ambient_light_color = Color(1, 1, 1, 1)
ambient_light_energy = 0.5
-[node name="ItemRender" type="Node3D"]
+[node name="ItemRender" type="Node3D" unique_id=888778935]
script = ExtResource("1_jfi7o")
-[node name="Camera3D" type="Camera3D" parent="."]
+[node name="Camera3D" type="Camera3D" parent="." unique_id=345542198]
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="."]
+[node name="DirectionalLight3D" type="DirectionalLight3D" parent="." unique_id=1536463653]
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="."]
+[node name="WorldEnvironment" type="WorldEnvironment" parent="." unique_id=554449090]
environment = SubResource("Environment_iyxrx")
diff --git a/client/gui/components/message/renderer.gd b/client/gui/components/message/renderer.gd
new file mode 100644
index 00000000..fda880de
--- /dev/null
+++ b/client/gui/components/message/renderer.gd
@@ -0,0 +1,34 @@
+# Hurry Curry! - a game about cooking
+# Copyright (C) 2026 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 <https://www.gnu.org/licenses/>.
+#
+class_name Renderer
+extends SubViewportContainer
+
+var current_object: Node3D = null
+
+func setup_item(name: String):
+ if current_object: current_object.queue_free()
+ current_object = ItemFactory.produce(name, $SubViewport/Node3D/Base)
+ $SubViewport/Node3D/Camera3D.size = 1.
+ $SubViewport/Node3D/Base.add_child(current_object)
+
+func setup_tile(parts: Array):
+ if current_object: current_object.queue_free()
+ var tf = TileFactory.new()
+ current_object = Node3D.new()
+ tf.produce(current_object, parts, Vector2i(0, 0), [["counter"], ["floor"], ["counter"], []])
+ current_object.translate(Vector3(-0.5, 0.0, -0.5))
+ $SubViewport/Node3D/Camera3D.size = 2.
+ $SubViewport/Node3D/Base.add_child(current_object)
diff --git a/client/gui/components/message/renderer.gd.uid b/client/gui/components/message/renderer.gd.uid
new file mode 100644
index 00000000..333f8bb2
--- /dev/null
+++ b/client/gui/components/message/renderer.gd.uid
@@ -0,0 +1 @@
+uid://bv6faf7woy4yo
diff --git a/client/gui/components/message/renderer.tscn b/client/gui/components/message/renderer.tscn
new file mode 100644
index 00000000..8436405e
--- /dev/null
+++ b/client/gui/components/message/renderer.tscn
@@ -0,0 +1,43 @@
+[gd_scene format=3 uid="uid://hdgsa0yfhnfw"]
+
+[ext_resource type="Script" uid="uid://bv6faf7woy4yo" path="res://gui/components/message/renderer.gd" id="1_3x5y3"]
+
+[sub_resource type="BoxMesh" id="BoxMesh_pcjn7"]
+
+[sub_resource type="Environment" id="Environment_vdkpo"]
+background_mode = 1
+background_color = Color(0, 0, 0, 0)
+ambient_light_source = 2
+ambient_light_color = Color(1, 1, 1, 1)
+
+[node name="Renderer" type="SubViewportContainer" unique_id=1275527447]
+offset_right = 512.0
+offset_bottom = 512.0
+script = ExtResource("1_3x5y3")
+
+[node name="SubViewport" type="SubViewport" parent="." unique_id=541744446]
+own_world_3d = true
+transparent_bg = true
+handle_input_locally = false
+render_target_update_mode = 4
+
+[node name="Node3D" type="Node3D" parent="SubViewport" unique_id=973467049]
+
+[node name="DebugPlaceholder" type="MeshInstance3D" parent="SubViewport/Node3D" unique_id=703186492]
+visible = false
+mesh = SubResource("BoxMesh_pcjn7")
+skeleton = NodePath("../../../..")
+
+[node name="WorldEnvironment" type="WorldEnvironment" parent="SubViewport/Node3D" unique_id=1814649689]
+environment = SubResource("Environment_vdkpo")
+
+[node name="Camera3D" type="Camera3D" parent="SubViewport/Node3D" unique_id=298159124]
+transform = Transform3D(1, 0, 0, 0, 0.8660254, 0.5, 0, -0.5, 0.8660254, 0, 2, 3)
+projection = 1
+far = 30.0
+
+[node name="DirectionalLight3D" type="DirectionalLight3D" parent="SubViewport/Node3D" unique_id=687060995]
+transform = Transform3D(0.7071067, 0.49999997, -0.4999999, 0, 0.70710677, 0.7071067, 0.7071067, -0.49999997, 0.4999999, 0, 0, 0)
+
+[node name="Base" type="Node3D" parent="SubViewport/Node3D" unique_id=1655606239]
+transform = Transform3D(0.70710677, 0, 0.70710677, 0, 1, 0, -0.70710677, 0, 0.70710677, 0, 0, 0)
diff --git a/client/gui/components/smart_margin_container.gd b/client/gui/components/smart_margin_container.gd
index 046dc6f3..30a219f3 100644
--- a/client/gui/components/smart_margin_container.gd
+++ b/client/gui/components/smart_margin_container.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/gui/components/touch_scroll_container.gd b/client/gui/components/touch_scroll_container.gd
index 292d084a..f262b99c 100644
--- a/client/gui/components/touch_scroll_container.gd
+++ b/client/gui/components/touch_scroll_container.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/gui/menus/book/book.gd b/client/gui/menus/book/book.gd
new file mode 100644
index 00000000..8a0e0db1
--- /dev/null
+++ b/client/gui/menus/book/book.gd
@@ -0,0 +1,117 @@
+# Hurry Curry! - a game about cooking
+# Copyright (C) 2026 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 <https://www.gnu.org/licenses/>.
+#
+class_name BookMenu
+extends Menu
+
+const MARGIN: int = 32
+
+var current_page := 0
+
+@onready var first := $Margin/HBoxContainer/First/PanelContainer/MarginContainer
+@onready var second := $Margin/HBoxContainer/Second/PanelContainer/MarginContainer
+
+static var TOOLS_WITH_COUNTER = ["cutting-board", "rolling-board", "deep-fryer", "sink", "book"]
+
+@export var title_font: Font
+@export var default_font: Font
+
+var pages: Array
+
+class BookData:
+ var game: Game
+ var data: Dictionary
+
+ func _init(game_, data_) -> void:
+ game = game_
+ data = data_
+
+var book_data: BookData
+
+func _ready():
+ super()
+ book_data = data
+ pages = book_data.data["pages"]
+ # Flip book for rtl languages
+ $Margin/HBoxContainer/Previous.flip_h = not is_layout_rtl()
+ $Margin/HBoxContainer/Next.flip_h = is_layout_rtl()
+ build_page()
+
+func build_page() -> void:
+ $Margin/HBoxContainer/Previous.disabled = current_page == 0
+ $Margin/HBoxContainer/Next.disabled = current_page == pages.size() - 1
+ for c: Node in first.get_children():
+ c.queue_free()
+ for c: Node in second.get_children():
+ c.queue_free()
+
+ var p: Dictionary = pages[current_page]
+ match p.page_type:
+ "contents":
+ var title := build_title(MessageParser.new(p["title"], book_data.game).result)
+ var vbox := VBoxContainer.new()
+ vbox.add_child(title)
+ for i: Array in p.table:
+ var m := MessageParser.new(i[0], book_data.game)
+ vbox.add_child(build_contents_entry(m.result, i[1]))
+ second.add_child(vbox)
+ "recipe":
+ var title := build_title(MessageParser.new(p["title"], book_data.game).result)
+ var par := build_paragraph(MessageParser.new(p["description"], book_data.game).result)
+ var vbox := VBoxContainer.new()
+ vbox.add_child(title)
+ vbox.add_child(par)
+ var dia := Diagram.new(p["diagram"], book_data.game)
+ first.add_child(vbox)
+ second.add_child(dia)
+ _: push_error("%s not known" % p.page_type)
+ return Control.new()
+
+func build_title(m: String) -> Label:
+ var label := Label.new()
+ label.add_theme_font_override("font", title_font)
+ label.add_theme_font_size_override("font_size", 42)
+ label.add_theme_color_override("font_color", Color.BLACK)
+ label.text = m
+ return label
+
+func build_paragraph(m: String) -> Label:
+ var label := Label.new()
+ label.add_theme_font_override("font", default_font)
+ label.add_theme_font_size_override("font_size", 32)
+ label.add_theme_color_override("font_color", Color.BLACK)
+ label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
+ label.text = m
+ return label
+
+func build_contents_entry(m: String, ref: int) -> Control:
+ var b := LinkButton.new()
+ b.text = m
+ b.pressed.connect(func():
+ current_page = ref
+ build_page()
+ )
+ b.add_theme_font_override("font", default_font)
+ b.add_theme_font_size_override("font_size", 32)
+ b.add_theme_color_override("font_color", Color.BLACK)
+ return b
+
+func _on_previous_pressed() -> void:
+ current_page = clampi(current_page - 1, 0, pages.size() - 1)
+ build_page()
+
+func _on_next_pressed() -> void:
+ current_page = clampi(current_page + 1, 0, pages.size() - 1)
+ build_page()
diff --git a/client/gui/menus/book/book.gd.uid b/client/gui/menus/book/book.gd.uid
new file mode 100644
index 00000000..9bda6bc4
--- /dev/null
+++ b/client/gui/menus/book/book.gd.uid
@@ -0,0 +1 @@
+uid://d1jive3atu4k7
diff --git a/client/gui/menus/book/book.tscn b/client/gui/menus/book/book.tscn
new file mode 100644
index 00000000..1d178b50
--- /dev/null
+++ b/client/gui/menus/book/book.tscn
@@ -0,0 +1,110 @@
+[gd_scene format=3 uid="uid://bdggwo8un3mys"]
+
+[ext_resource type="Script" uid="uid://d1jive3atu4k7" path="res://gui/menus/book/book.gd" id="1_gyisx"]
+[ext_resource type="Material" uid="uid://beea1pc5nt67r" path="res://gui/resources/materials/dark_blur_material.tres" id="2_0j5mt"]
+[ext_resource type="FontVariation" uid="uid://cl6m4hqsnrpav" path="res://gui/resources/fonts/sansita-swashed-bold.tres" id="2_blsld"]
+[ext_resource type="Texture2D" uid="uid://35rd5gamtyqm" path="res://gui/resources/icons/arrow.svg" id="2_x03iu"]
+[ext_resource type="FontFile" uid="uid://5ixo6b3bd3km" path="res://gui/resources/fonts/font-josefin-sans.woff2" id="3_5pkoa"]
+[ext_resource type="Texture2D" uid="uid://j75dbytlbju" path="res://gui/resources/icons/arrow_pressed.svg" id="3_raafv"]
+[ext_resource type="Texture2D" uid="uid://b33qmctbpf48g" path="res://gui/resources/icons/arrow_hover.svg" id="4_ee6vw"]
+[ext_resource type="Texture2D" uid="uid://by3qsrpxnfq4w" path="res://gui/resources/icons/arrow_focus.svg" id="5_0j5mt"]
+[ext_resource type="StyleBox" uid="uid://bqhs5wtdp2oax" path="res://gui/resources/style/paper_panel_style.tres" id="6_raafv"]
+[ext_resource type="Script" uid="uid://cmncjc06kadpe" path="res://gui/components/blur_setup.gd" id="7_ee6vw"]
+
+[sub_resource type="FontVariation" id="FontVariation_ns2fj"]
+base_font = ExtResource("2_blsld")
+
+[sub_resource type="FontVariation" id="FontVariation_wsg84"]
+base_font = ExtResource("3_5pkoa")
+variation_opentype = {
+2003265652: 300
+}
+
+[node name="Book" type="Control" unique_id=2012988471]
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+script = ExtResource("1_gyisx")
+title_font = SubResource("FontVariation_ns2fj")
+default_font = SubResource("FontVariation_wsg84")
+support_anim = false
+
+[node name="Panel" type="Panel" parent="." unique_id=172674263]
+material = ExtResource("2_0j5mt")
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+script = ExtResource("7_ee6vw")
+
+[node name="Margin" type="MarginContainer" parent="." unique_id=782381175]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_constants/margin_top = 16
+theme_override_constants/margin_bottom = 16
+
+[node name="HBoxContainer" type="HBoxContainer" parent="Margin" unique_id=410074371]
+layout_mode = 2
+
+[node name="Previous" type="TextureButton" parent="Margin/HBoxContainer" unique_id=1963804769]
+layout_mode = 2
+texture_normal = ExtResource("2_x03iu")
+texture_pressed = ExtResource("3_raafv")
+texture_hover = ExtResource("4_ee6vw")
+texture_disabled = ExtResource("3_raafv")
+texture_focused = ExtResource("5_0j5mt")
+stretch_mode = 3
+flip_h = true
+
+[node name="First" type="HBoxContainer" parent="Margin/HBoxContainer" unique_id=418992738]
+layout_mode = 2
+size_flags_horizontal = 3
+
+[node name="PanelContainer" type="PanelContainer" parent="Margin/HBoxContainer/First" unique_id=1651447616]
+layout_mode = 2
+size_flags_horizontal = 3
+theme_override_styles/panel = ExtResource("6_raafv")
+
+[node name="MarginContainer" type="MarginContainer" parent="Margin/HBoxContainer/First/PanelContainer" unique_id=1382780384]
+layout_mode = 2
+theme_override_constants/margin_left = 32
+theme_override_constants/margin_top = 32
+theme_override_constants/margin_right = 32
+theme_override_constants/margin_bottom = 32
+
+[node name="Second" type="HBoxContainer" parent="Margin/HBoxContainer" unique_id=1289010064]
+layout_mode = 2
+size_flags_horizontal = 3
+
+[node name="PanelContainer" type="PanelContainer" parent="Margin/HBoxContainer/Second" unique_id=1634660876]
+layout_mode = 2
+size_flags_horizontal = 3
+theme_override_styles/panel = ExtResource("6_raafv")
+
+[node name="MarginContainer" type="MarginContainer" parent="Margin/HBoxContainer/Second/PanelContainer" unique_id=455360074]
+layout_mode = 2
+theme_override_constants/margin_left = 32
+theme_override_constants/margin_top = 32
+theme_override_constants/margin_right = 32
+theme_override_constants/margin_bottom = 32
+
+[node name="Next" type="TextureButton" parent="Margin/HBoxContainer" unique_id=1006389953]
+layout_mode = 2
+texture_normal = ExtResource("2_x03iu")
+texture_pressed = ExtResource("3_raafv")
+texture_hover = ExtResource("4_ee6vw")
+texture_disabled = ExtResource("3_raafv")
+texture_focused = ExtResource("5_0j5mt")
+stretch_mode = 3
+
+[connection signal="pressed" from="Margin/HBoxContainer/Previous" to="." method="_on_previous_pressed"]
+[connection signal="pressed" from="Margin/HBoxContainer/Next" to="." method="_on_next_pressed"]
diff --git a/client/gui/menus/book/diagram.gd b/client/gui/menus/book/diagram.gd
new file mode 100644
index 00000000..b4ae3f30
--- /dev/null
+++ b/client/gui/menus/book/diagram.gd
@@ -0,0 +1,124 @@
+# Hurry Curry! - a game about cooking
+# Copyright (C) 2026 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 <https://www.gnu.org/licenses/>.
+#
+class_name Diagram
+extends Control
+
+const RENDERER := preload("res://gui/components/message/renderer.tscn")
+var BASE_SIZE: float = 64.;
+var hsize: float = 32.;
+
+var raw: Dictionary
+var nodes: Array#[DiagramNode]
+var edges: Array#[DiagramEdge]
+var draw_nodes: Array
+var renderers: Array[Renderer] = []
+
+class DiagramNode:
+ var position: Vector2
+ var label: MessageParser
+ var style: String
+
+ func _init(raw: Dictionary, game: Game):
+ position = Vector2(raw["position"][0], raw["position"][1])
+ label = MessageParser.new(raw["label"], game)
+ style = raw["style"]
+
+class DiagramEdge:
+ var src: int
+ var dst: int
+
+ func _init(raw: Dictionary):
+ src = raw["src"]
+ dst = raw["dst"]
+
+func _init(raw_: Dictionary, game: Game) -> void:
+ raw = raw_
+ nodes = raw["nodes"].map(func(r): return DiagramNode.new(r, game))
+ edges = raw["edges"].map(func(r): return DiagramEdge.new(r))
+ # ugh
+ draw_nodes = raw["nodes"].map(func(r): return DiagramNode.new(r, game))
+
+func _ready() -> void:
+ redraw_images()
+ item_rect_changed.connect(func():
+ if size != Vector2(64, 64): scale()
+ )
+
+func redraw_images() -> void:
+ for r in renderers:
+ r.queue_free()
+ renderers.clear()
+ for n: DiagramNode in draw_nodes:
+ var r: Renderer = RENDERER.instantiate()
+ r.get_node("SubViewport").size = Vector2.ONE * hsize * 2.
+ add_child(r)
+ r.position = n.position - Vector2(hsize, hsize)
+ match n.label.kind:
+ MessageParser.Kind.ITEM: r.setup_object(n.label.result)
+ MessageParser.Kind.TILE: r.setup_object([n.label.result])
+ renderers.push_back(r)
+
+func scale() -> void:
+ var bounds = Rect2(Vector2.ONE * BASE_SIZE * 0.5, Vector2(size.x - BASE_SIZE, size.y - BASE_SIZE))
+ var current := Rect2(Vector2(INF, INF), Vector2(-INF, -INF))
+ for n: DiagramNode in nodes:
+ current.position = current.position.min(n.position)
+ current.end = current.end.max(n.position)
+ var s = Vector2.ONE.min(bounds.size / current.size)
+ hsize = BASE_SIZE * 0.5 * min(s.x, s.y)
+ for i in nodes.size():
+ var dn: DiagramNode = draw_nodes[i]
+ var n: DiagramNode = nodes[i]
+ dn.position = n.position - current.position
+ dn.position *= s
+ dn.position += bounds.position
+ redraw_images()
+
+func _draw() -> void:
+ for n: DiagramNode in draw_nodes:
+ match n.style:
+ "intermediate_product":
+ draw_circle(n.position, hsize, Color("#555"), true, -1., true)
+ "final_product":
+ draw_circle(n.position, hsize, Color("#333"), true, -1., true)
+ "process_active":
+ draw_rect(Rect2(n.position - Vector2(hsize, hsize), Vector2(hsize, hsize) * 2.), Color("#47c42b"))
+ "process_passive":
+ draw_rect(Rect2(n.position - Vector2(hsize, hsize), Vector2(hsize, hsize) * 2.), Color("#c4a32b"))
+ "process_instant":
+ draw_rect(Rect2(n.position - Vector2(hsize, hsize), Vector2(hsize, hsize) * 2.), Color("#5452d8"))
+
+ for e: DiagramEdge in edges:
+ var src_node: DiagramNode = draw_nodes[e.src]
+ var dst_node: DiagramNode = draw_nodes[e.dst]
+ var src := node_edge_connect_pos(src_node, dst_node)
+ var dst := node_edge_connect_pos(dst_node, src_node)
+
+ var dir = (src - dst).normalized()
+ var tip0 = dst
+ var tip1 = dst + dir.rotated(0.2 * PI) * 10.
+ var tip2 = dst + dir.rotated(-0.2 * PI) * 10.
+ dst += dir * 5.
+
+ draw_colored_polygon([tip0, tip1, tip2], Color.BLACK)
+ draw_line(src, dst, Color.BLACK, 2., true)
+
+func node_edge_connect_pos(src: DiagramNode, dst: DiagramNode) -> Vector2:
+ var dir = (dst.position - src.position).normalized()
+ if src.style == "intermediate_product" or src.style == "final_product":
+ return src.position + dir * hsize
+ else:
+ return src.position + dir / max(abs(dir.y), abs(dir.x)) * hsize
diff --git a/client/gui/menus/book/diagram.gd.uid b/client/gui/menus/book/diagram.gd.uid
new file mode 100644
index 00000000..debd91e5
--- /dev/null
+++ b/client/gui/menus/book/diagram.gd.uid
@@ -0,0 +1 @@
+uid://jqmllc8hafx0
diff --git a/client/gui/menus/character.gd b/client/gui/menus/character.gd
index fa3d213e..42b22918 100644
--- a/client/gui/menus/character.gd
+++ b/client/gui/menus/character.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -24,7 +24,9 @@ func _ready():
$VBoxContainer/top_panel/a/username.text = Profile.read("username")
character.set_style(Profile.read("character_style"), "chef")
-func exit():
+func _menu_music(): Sound.set_music("reflets-dans-leau", -3, true)
+
+func exit(exit_data = null):
if username_edit.text == "":
var popup_data := MenuPopup.Data.new()
popup_data.text = tr("c.error.empty_username")
@@ -34,7 +36,7 @@ func exit():
await submenu("res://gui/menus/popup.tscn", popup_data)
return
Profile.write("username", username_edit.text)
- super()
+ super(exit_data)
func _on_character_back_pressed():
modify_style(func m(current_style: Dictionary):
diff --git a/client/gui/menus/character.tscn b/client/gui/menus/character.tscn
index fa5f513c..24d698c5 100644
--- a/client/gui/menus/character.tscn
+++ b/client/gui/menus/character.tscn
@@ -1,6 +1,5 @@
-[gd_scene load_steps=14 format=3 uid="uid://1f7xpirm5d28"]
+[gd_scene 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://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"]
@@ -14,67 +13,66 @@
[ext_resource type="Script" uid="uid://cmncjc06kadpe" path="res://gui/components/blur_setup.gd" id="7_nj82n"]
[ext_resource type="Material" uid="uid://beea1pc5nt67r" path="res://gui/resources/materials/dark_blur_material.tres" id="12_mjf6q"]
-[node name="CharacterMenu" type="Control"]
+[node name="CharacterMenu" type="Control" unique_id=1936971311]
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="Node3D" type="Node3D" parent="." unique_id=1910363995]
-[node name="Character" parent="Node3D" instance=ExtResource("3_odq7n")]
+[node name="Character" parent="Node3D" unique_id=331462834 instance=ExtResource("3_odq7n")]
-[node name="Camera3D" type="Camera3D" parent="Node3D"]
+[node name="Camera3D" type="Camera3D" parent="Node3D" unique_id=1576520390]
transform = Transform3D(1, 0, 0, 0, 0.9781476, 0.2079117, 0, -0.2079117, 0.9781476, 0, 1.125, 2.75)
current = true
fov = 40.0
-[node name="KitchenBackground" parent="Node3D" instance=ExtResource("4_oanna")]
+[node name="KitchenBackground" parent="Node3D" unique_id=2119883164 instance=ExtResource("4_oanna")]
transform = Transform3D(0.8660254, 0, 0.5, 0, 1, 0, -0.5, 0, 0.8660254, 0, 0, 0)
-[node name="SpotLight3D" type="SpotLight3D" parent="Node3D"]
+[node name="SpotLight3D" type="SpotLight3D" parent="Node3D" unique_id=1688426082]
transform = Transform3D(0.8825786, -0.13509111, 0.4503392, 0, 0.9578325, 0.2873271, -0.47016487, -0.25358877, 0.8453625, 1.1277027, 1.109924, 2.02365)
light_color = Color(0.87094337, 0.86437446, 0.85403997, 1)
light_energy = 1.5
shadow_enabled = true
shadow_blur = 3.0
-[node name="SpotLight3D2" type="SpotLight3D" parent="Node3D"]
+[node name="SpotLight3D2" type="SpotLight3D" parent="Node3D" unique_id=104233494]
transform = Transform3D(0.9149456, 0.11595869, -0.3865594, 0, 0.9578325, 0.28732717, 0.40357724, -0.2628887, 0.87636465, -1.2921853, 1.109924, 2.02365)
light_color = Color(0.87094337, 0.86437446, 0.85403997, 1)
light_energy = 0.8
shadow_enabled = true
shadow_blur = 3.0
-[node name="SpotLight3D5" type="SpotLight3D" parent="Node3D"]
+[node name="SpotLight3D5" type="SpotLight3D" parent="Node3D" unique_id=807895905]
transform = Transform3D(0.99089444, -0.009957474, -0.13427223, 0.029642614, -0.95665854, 0.2896995, -0.13133734, -0.29104182, -0.94765246, -0.27793396, 1.5702409, -1.0504578)
light_color = Color(0.6709639, 0.8500128, 1, 1)
light_energy = 5.0
spot_range = 1.9395764
spot_angle = 25.84634
-[node name="SpotLight3D4" type="SpotLight3D" parent="Node3D"]
+[node name="SpotLight3D4" type="SpotLight3D" parent="Node3D" unique_id=33030011]
transform = Transform3D(0.9139213, -0.3175812, 0.2527643, -0.093218885, -0.77032155, -0.63080496, 0.39504167, 0.5529437, -0.73361796, 1.0089738, 0.124474704, -1.4214872)
light_color = Color(0.7758381, 0.7974717, 1, 1)
light_energy = 5.0
-[node name="OmniLight3D3" type="OmniLight3D" parent="Node3D"]
+[node name="OmniLight3D3" type="OmniLight3D" parent="Node3D" unique_id=513945686]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.6456945, 0.76124895, 0.72990704)
-light_color = Color(0.84705883, 0.5019608, 0.43529412, 1)
+light_color = Color(0.79, 0.3476, 0.50244, 1)
light_energy = 0.75
omni_range = 6.4840736
-[node name="OmniLight3D4" type="OmniLight3D" parent="Node3D"]
+[node name="OmniLight3D4" type="OmniLight3D" parent="Node3D" unique_id=1260513554]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.5320137, 0.48659694, 0.6924461)
-light_color = Color(0.5875623, 0.58040434, 0.8120325, 1)
+light_color = Color(0.42633, 0.4131, 0.81, 1)
light_energy = 0.75
omni_range = 6.071165
-[node name="VBoxContainer" type="VBoxContainer" parent="."]
+[node name="VBoxContainer" type="VBoxContainer" parent="." unique_id=841911331]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
@@ -82,14 +80,14 @@ anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
-[node name="top_panel" type="Panel" parent="VBoxContainer"]
+[node name="top_panel" type="Panel" parent="VBoxContainer" unique_id=1181042323]
material = ExtResource("5_cgkmt")
custom_minimum_size = Vector2(0, 100)
layout_mode = 2
theme_override_styles/panel = ExtResource("6_wxiis")
script = ExtResource("7_nj82n")
-[node name="a" type="VBoxContainer" parent="VBoxContainer/top_panel"]
+[node name="a" type="VBoxContainer" parent="VBoxContainer/top_panel" unique_id=1129893219]
layout_mode = 1
anchors_preset = 5
anchor_left = 0.5
@@ -100,16 +98,16 @@ offset_right = 216.0
offset_bottom = 110.0
grow_horizontal = 2
-[node name="Label" type="Label" parent="VBoxContainer/top_panel/a"]
+[node name="Label" type="Label" parent="VBoxContainer/top_panel/a" unique_id=535228051]
layout_mode = 2
text = "c.settings.username"
horizontal_alignment = 1
-[node name="username" type="LineEdit" parent="VBoxContainer/top_panel/a"]
+[node name="username" type="LineEdit" parent="VBoxContainer/top_panel/a" unique_id=79006791]
layout_mode = 2
max_length = 32
-[node name="Spacer" type="MarginContainer" parent="VBoxContainer"]
+[node name="Spacer" type="MarginContainer" parent="VBoxContainer" unique_id=1314962703]
layout_mode = 2
size_flags_vertical = 3
theme_override_constants/margin_left = 50
@@ -117,16 +115,17 @@ 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"]
+[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/Spacer" unique_id=355029923]
layout_mode = 2
alignment = 1
-[node name="Headware" type="HBoxContainer" parent="VBoxContainer/Spacer/VBoxContainer"]
+[node name="Headware" type="HBoxContainer" parent="VBoxContainer/Spacer/VBoxContainer" unique_id=337136830]
+layout_direction = 2
layout_mode = 2
size_flags_vertical = 3
alignment = 1
-[node name="Back" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Headware"]
+[node name="Back" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Headware" unique_id=39776895]
layout_mode = 2
size_flags_horizontal = 3
focus_neighbor_right = NodePath("../Forward")
@@ -138,11 +137,11 @@ ignore_texture_size = true
stretch_mode = 5
flip_h = true
-[node name="Spacer" type="Control" parent="VBoxContainer/Spacer/VBoxContainer/Headware"]
+[node name="Spacer" type="Control" parent="VBoxContainer/Spacer/VBoxContainer/Headware" unique_id=480930147]
layout_mode = 2
size_flags_horizontal = 3
-[node name="Forward" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Headware"]
+[node name="Forward" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Headware" unique_id=743596728]
layout_mode = 2
size_flags_horizontal = 3
focus_neighbor_left = NodePath("../Back")
@@ -153,12 +152,13 @@ texture_focused = ExtResource("6_u31hl")
ignore_texture_size = true
stretch_mode = 5
-[node name="Hairstyle" type="HBoxContainer" parent="VBoxContainer/Spacer/VBoxContainer"]
+[node name="Hairstyle" type="HBoxContainer" parent="VBoxContainer/Spacer/VBoxContainer" unique_id=46243549]
+layout_direction = 2
layout_mode = 2
size_flags_vertical = 3
alignment = 1
-[node name="Back" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Hairstyle"]
+[node name="Back" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Hairstyle" unique_id=1986439220]
layout_mode = 2
size_flags_horizontal = 3
focus_neighbor_right = NodePath("../Forward")
@@ -170,11 +170,11 @@ ignore_texture_size = true
stretch_mode = 5
flip_h = true
-[node name="Spacer" type="Control" parent="VBoxContainer/Spacer/VBoxContainer/Hairstyle"]
+[node name="Spacer" type="Control" parent="VBoxContainer/Spacer/VBoxContainer/Hairstyle" unique_id=1730649887]
layout_mode = 2
size_flags_horizontal = 3
-[node name="Forward" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Hairstyle"]
+[node name="Forward" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Hairstyle" unique_id=1174265017]
layout_mode = 2
size_flags_horizontal = 3
focus_neighbor_left = NodePath("../Back")
@@ -185,12 +185,13 @@ texture_focused = ExtResource("6_u31hl")
ignore_texture_size = true
stretch_mode = 5
-[node name="Character" type="HBoxContainer" parent="VBoxContainer/Spacer/VBoxContainer"]
+[node name="Character" type="HBoxContainer" parent="VBoxContainer/Spacer/VBoxContainer" unique_id=1020578308]
+layout_direction = 2
layout_mode = 2
size_flags_vertical = 3
alignment = 1
-[node name="Back" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Character"]
+[node name="Back" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Character" unique_id=65037917]
layout_mode = 2
size_flags_horizontal = 3
focus_neighbor_right = NodePath("../Forward")
@@ -202,11 +203,11 @@ ignore_texture_size = true
stretch_mode = 5
flip_h = true
-[node name="Spacer" type="Control" parent="VBoxContainer/Spacer/VBoxContainer/Character"]
+[node name="Spacer" type="Control" parent="VBoxContainer/Spacer/VBoxContainer/Character" unique_id=1821703862]
layout_mode = 2
size_flags_horizontal = 3
-[node name="Forward" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Character"]
+[node name="Forward" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Character" unique_id=1721685554]
layout_mode = 2
size_flags_horizontal = 3
focus_neighbor_left = NodePath("../Back")
@@ -217,14 +218,14 @@ texture_focused = ExtResource("6_u31hl")
ignore_texture_size = true
stretch_mode = 5
-[node name="bottom_panel" type="Panel" parent="VBoxContainer"]
+[node name="bottom_panel" type="Panel" parent="VBoxContainer" unique_id=971465503]
material = ExtResource("12_mjf6q")
custom_minimum_size = Vector2(0, 75)
layout_mode = 2
theme_override_styles/panel = ExtResource("6_wxiis")
script = ExtResource("7_nj82n")
-[node name="back" type="Button" parent="VBoxContainer/bottom_panel"]
+[node name="back" type="Button" parent="VBoxContainer/bottom_panel" unique_id=68338925]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
@@ -240,7 +241,7 @@ grow_vertical = 2
size_flags_vertical = 8
text = "c.menu.back"
-[node name="SceneTransition" parent="." instance=ExtResource("4_c0ocf")]
+[node name="SceneTransition" parent="." unique_id=863534827 instance=ExtResource("4_c0ocf")]
visible = false
layout_mode = 1
diff --git a/client/gui/menus/chat.gd b/client/gui/menus/chat.gd
index aae76f82..df065ebc 100644
--- a/client/gui/menus/chat.gd
+++ b/client/gui/menus/chat.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/gui/menus/chat.tscn b/client/gui/menus/chat.tscn
index 5b046191..441f3eea 100644
--- a/client/gui/menus/chat.tscn
+++ b/client/gui/menus/chat.tscn
@@ -1,13 +1,12 @@
-[gd_scene load_steps=7 format=3 uid="uid://dbd6k56l4p0ls"]
+[gd_scene 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"]
+[node name="ChatOpen" type="Control" unique_id=2023475735]
layout_mode = 3
anchors_preset = 9
anchor_bottom = 1.0
@@ -16,27 +15,26 @@ grow_vertical = 2
script = ExtResource("1_gntkb")
support_anim = false
-[node name="PanelContainer" type="PanelContainer" parent="."]
+[node name="PanelContainer" type="PanelContainer" parent="." unique_id=947723788]
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"]
+[node name="MarginContainer" type="MarginContainer" parent="PanelContainer" unique_id=1727397765]
layout_mode = 2
-[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/MarginContainer"]
+[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/MarginContainer" unique_id=1494822989]
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"]
+[node name="ScrollContainerCustom" type="ScrollContainer" parent="PanelContainer/MarginContainer/VBoxContainer" unique_id=505698548]
material = ExtResource("2_1au48")
layout_mode = 2
size_flags_horizontal = 3
@@ -44,12 +42,12 @@ size_flags_vertical = 3
script = ExtResource("6_ff15x")
auto_scroll_to_bottom = true
-[node name="Messages" type="VBoxContainer" parent="PanelContainer/MarginContainer/VBoxContainer/ScrollContainerCustom"]
+[node name="Messages" type="VBoxContainer" parent="PanelContainer/MarginContainer/VBoxContainer/ScrollContainerCustom" unique_id=284153322]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
-[node name="LineEdit" type="LineEdit" parent="PanelContainer/MarginContainer/VBoxContainer" groups=["autoselect"]]
+[node name="LineEdit" type="LineEdit" parent="PanelContainer/MarginContainer/VBoxContainer" unique_id=1024788333 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
deleted file mode 100644
index 781dbfca..00000000
--- a/client/gui/menus/document/document.gd
+++ /dev/null
@@ -1,152 +0,0 @@
-# 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 <https://www.gnu.org/licenses/>.
-#
-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://gui/resources/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://gui/resources/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://gui/components/message/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
deleted file mode 100644
index c84b53b1..00000000
--- a/client/gui/menus/document/document.gd.uid
+++ /dev/null
@@ -1 +0,0 @@
-uid://c83p4k0nredmd
diff --git a/client/gui/menus/document/document.tscn b/client/gui/menus/document/document.tscn
deleted file mode 100644
index 537ac8b8..00000000
--- a/client/gui/menus/document/document.tscn
+++ /dev/null
@@ -1,29 +0,0 @@
-[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
index 4006f00b..2c5905fa 100644
--- a/client/gui/menus/entry.gd
+++ b/client/gui/menus/entry.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -27,7 +27,8 @@ func _ready():
if Cli.opts.has("render-items") or Cli.opts.has("render-tiles"):
await submenu("res://system/render_tool.tscn")
if Cli.opts.has("connect_address"):
- await submenu("res://gui/menus/game.tscn", Cli.opts["connect_address"])
+ var urls: Array[String] = [Cli.opts["connect_address"]]
+ await submenu("res://gui/menus/game.tscn", urls)
elif not Settings.read("gameplay.setup_completed"):
await submenu("res://gui/menus/setup/setup.tscn")
else:
diff --git a/client/gui/menus/entry.tscn b/client/gui/menus/entry.tscn
index f4eced3e..a4e74f5e 100644
--- a/client/gui/menus/entry.tscn
+++ b/client/gui/menus/entry.tscn
@@ -1,8 +1,8 @@
-[gd_scene load_steps=2 format=3 uid="uid://cd52sr1cmo8oj"]
+[gd_scene 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"]
+[node name="Entry" type="Control" unique_id=1447244984]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
diff --git a/client/gui/menus/error.gd b/client/gui/menus/error.gd
index efe173c3..1e122fac 100644
--- a/client/gui/menus/error.gd
+++ b/client/gui/menus/error.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -20,6 +20,8 @@ extends Menu
func _ready():
super()
message.text = data[0]
+ previous_path = "res://gui/menus/main/main.tscn"
+ Sound.set_music("error", -1, true)
func _on_return_pressed():
replace_menu("res://gui/menus/main/main.tscn")
diff --git a/client/gui/menus/error.tscn b/client/gui/menus/error.tscn
index 37f8019f..ccfcaeb4 100644
--- a/client/gui/menus/error.tscn
+++ b/client/gui/menus/error.tscn
@@ -1,25 +1,24 @@
-[gd_scene load_steps=7 format=3 uid="uid://cimgn07lbcs4v"]
+[gd_scene 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="StyleBox" uid="uid://de80aw86emnql" path="res://gui/resources/style/square_panel_override.tres" id="5_42a6r"]
[ext_resource type="Script" uid="uid://byshs20og68tn" path="res://gui/components/smart_margin_container.gd" id="5_rfcg2"]
-[node name="ErrorMenu" type="Control"]
+[node name="ErrorMenu" type="Control" unique_id=1514511445]
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="MenuBackground" parent="." unique_id=2057939786 instance=ExtResource("2_5fxol")]
-[node name="Panel" type="Panel" parent="."]
+[node name="Panel" type="Panel" parent="." unique_id=192312358]
material = ExtResource("4_hxkkd")
layout_mode = 1
anchors_preset = 15
@@ -27,8 +26,9 @@ anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
+theme_override_styles/panel = ExtResource("5_42a6r")
-[node name="SmartMarginContainer" type="MarginContainer" parent="Panel"]
+[node name="SmartMarginContainer" type="MarginContainer" parent="Panel" unique_id=1539898124]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
@@ -38,40 +38,42 @@ grow_vertical = 2
script = ExtResource("5_rfcg2")
metadata/_custom_type_script = "uid://byshs20og68tn"
-[node name="Contents" type="VBoxContainer" parent="Panel/SmartMarginContainer"]
+[node name="Contents" type="VBoxContainer" parent="Panel/SmartMarginContainer" unique_id=454783322]
layout_mode = 2
alignment = 1
-[node name="Title" type="Label" parent="Panel/SmartMarginContainer/Contents"]
+[node name="Title" type="Label" parent="Panel/SmartMarginContainer/Contents" unique_id=777220090]
layout_mode = 2
theme_override_font_sizes/font_size = 61
text = "c.menu.error.title"
horizontal_alignment = 1
-[node name="Message" type="Label" parent="Panel/SmartMarginContainer/Contents"]
+[node name="Message" type="Label" parent="Panel/SmartMarginContainer/Contents" unique_id=989678496]
+custom_minimum_size = Vector2(500, 0)
layout_mode = 2
theme_override_font_sizes/font_size = 24
text = "This should be the error message."
horizontal_alignment = 1
+autowrap_mode = 3
-[node name="Control" type="Control" parent="Panel/SmartMarginContainer/Contents"]
+[node name="Control" type="Control" parent="Panel/SmartMarginContainer/Contents" unique_id=2080730031]
custom_minimum_size = Vector2(0, 15.805)
layout_mode = 2
-[node name="HBoxContainer" type="HBoxContainer" parent="Panel/SmartMarginContainer/Contents"]
+[node name="HBoxContainer" type="HBoxContainer" parent="Panel/SmartMarginContainer/Contents" unique_id=847704926]
layout_mode = 2
alignment = 1
-[node name="Return" type="Button" parent="Panel/SmartMarginContainer/Contents/HBoxContainer"]
+[node name="Return" type="Button" parent="Panel/SmartMarginContainer/Contents/HBoxContainer" unique_id=2058870738]
layout_mode = 2
size_flags_horizontal = 4
text = "c.menu.ingame.main_menu"
-[node name="Reconnect" type="Button" parent="Panel/SmartMarginContainer/Contents/HBoxContainer"]
+[node name="Reconnect" type="Button" parent="Panel/SmartMarginContainer/Contents/HBoxContainer" unique_id=1168099563]
layout_mode = 2
text = "c.menu.ingame.reconnect"
-[node name="SceneTransition" parent="." instance=ExtResource("4_1nbt3")]
+[node name="SceneTransition" parent="." unique_id=1340959213 instance=ExtResource("4_1nbt3")]
visible = false
layout_mode = 1
diff --git a/client/gui/menus/game.gd b/client/gui/menus/game.gd
index e0ab5de7..5379d32d 100644
--- a/client/gui/menus/game.gd
+++ b/client/gui/menus/game.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -17,6 +17,7 @@ extends Menu
class_name GameMenu
@onready var game: Game = $Game
+@onready var overlays: Overlays = $Overlays
@onready var popup_message: PopupMessage = $Overlays/PopupMessage
@onready var chat_preview: ChatPreview = $Overlays/ChatPreview
@onready var pinned_items: PinnedItemMessages = $Overlays/PinnedMessages
@@ -25,7 +26,6 @@ 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("gameplay.first_person", "mouse_lock", func (_a): update_mouse_capture())
func _input(_event):
if Input.is_action_just_pressed("ui_menu"):
@@ -59,19 +59,22 @@ func get_shot_path(template: String) -> String:
var filename = template % Time.get_datetime_string_from_system()
return "%s/%s" % [path, filename]
+func _menu_open():
+ await super()
+ Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
+
func _menu_cover(state):
super(state)
- game.follow_camera.disable_input_menu = state
- game.follow_camera.update_disable_input()
- update_mouse_capture()
+ overlays.visible = not state
+ game.mp.send_idle(state)
+ game.follow_camera._disable_input = state
+ Input.mouse_mode = Input.MOUSE_MODE_CAPTURED if not covered else Input.MOUSE_MODE_VISIBLE
func _menu_exit():
- super()
+ await super()
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
-func update_mouse_capture():
- var cap = Settings.read("gameplay.first_person") and not covered
- Input.mouse_mode = Input.MOUSE_MODE_CAPTURED if cap else Input.MOUSE_MODE_VISIBLE
+func _menu_music(): Sound.set_music(null)
func open_ingame_menu():
if popup != null: return
diff --git a/client/gui/menus/game.tscn b/client/gui/menus/game.tscn
index 44efef21..f0322454 100644
--- a/client/gui/menus/game.tscn
+++ b/client/gui/menus/game.tscn
@@ -1,10 +1,10 @@
-[gd_scene load_steps=4 format=3 uid="uid://bbjwoxs71fnsk"]
+[gd_scene 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://cr26jennm5c0c" path="res://gui/overlays/overlays.tscn" id="3_eaud4"]
-[node name="GameMenu" type="Control"]
+[node name="GameMenu" type="Control" unique_id=348091771]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
@@ -14,7 +14,7 @@ grow_vertical = 2
script = ExtResource("1_cdpsh")
auto_anim = false
-[node name="Game" parent="." instance=ExtResource("2_uojcy")]
+[node name="Game" parent="." unique_id=229241562 instance=ExtResource("2_uojcy")]
-[node name="Overlays" parent="." instance=ExtResource("3_eaud4")]
+[node name="Overlays" parent="." unique_id=553707754 instance=ExtResource("3_eaud4")]
layout_mode = 1
diff --git a/client/gui/menus/ingame.gd b/client/gui/menus/ingame.gd
index 133b6d8f..809bac32 100644
--- a/client/gui/menus/ingame.gd
+++ b/client/gui/menus/ingame.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -39,10 +39,8 @@ 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
diff --git a/client/gui/menus/ingame.tscn b/client/gui/menus/ingame.tscn
index 2eb47b7d..eb5d5f1f 100644
--- a/client/gui/menus/ingame.tscn
+++ b/client/gui/menus/ingame.tscn
@@ -1,6 +1,5 @@
-[gd_scene load_steps=12 format=3 uid="uid://lxlgtjm8hw7v"]
+[gd_scene 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"]
@@ -46,23 +45,20 @@ _data = {
base_font = ExtResource("4_scupw")
variation_embolden = 0.5
-[node name="IngameMenu" type="Control"]
+[node name="IngameMenu" type="Control" unique_id=419075883]
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")
-}
+[node name="AnimationPlayer" type="AnimationPlayer" parent="." unique_id=697888286]
+libraries/ = SubResource("AnimationLibrary_u0kyp")
speed_scale = 8.0
-[node name="Side" type="PanelContainer" parent="."]
+[node name="Side" type="PanelContainer" parent="." unique_id=957227252]
material = ExtResource("3_vvvlt")
layout_mode = 1
anchors_preset = 9
@@ -72,7 +68,7 @@ grow_vertical = 2
theme_override_styles/panel = ExtResource("4_vr8y1")
script = ExtResource("4_b6bm7")
-[node name="Margin" type="MarginContainer" parent="Side"]
+[node name="Margin" type="MarginContainer" parent="Side" unique_id=1942923773]
layout_mode = 2
theme_override_constants/margin_left = 20
theme_override_constants/margin_top = 20
@@ -80,10 +76,10 @@ theme_override_constants/margin_right = 20
theme_override_constants/margin_bottom = 20
script = ExtResource("6_poj4k")
-[node name="Options" type="VBoxContainer" parent="Side/Margin"]
+[node name="Options" type="VBoxContainer" parent="Side/Margin" unique_id=878742867]
layout_mode = 2
-[node name="Title" type="Label" parent="Side/Margin/Options"]
+[node name="Title" type="Label" parent="Side/Margin/Options" unique_id=629270934]
auto_translate_mode = 2
layout_mode = 2
theme_override_colors/font_outline_color = Color(0.566408, 0.208917, 0.266045, 1)
@@ -92,44 +88,44 @@ 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"]
+[node name="Spacer" type="Control" parent="Side/Margin/Options" unique_id=419321461]
custom_minimum_size = Vector2(0, 10)
layout_mode = 2
-[node name="Resume" type="Button" parent="Side/Margin/Options"]
+[node name="Resume" type="Button" parent="Side/Margin/Options" unique_id=431520230]
layout_mode = 2
text = "c.menu.ingame.resume"
alignment = 0
-[node name="Leave" type="Button" parent="Side/Margin/Options"]
+[node name="Leave" type="Button" parent="Side/Margin/Options" unique_id=2061159794]
layout_mode = 2
text = "c.menu.ingame.join"
alignment = 0
-[node name="Abort" type="Button" parent="Side/Margin/Options"]
+[node name="Abort" type="Button" parent="Side/Margin/Options" unique_id=1050558982]
layout_mode = 2
text = "c.menu.ingame.cancel"
alignment = 0
-[node name="Reconnect" type="Button" parent="Side/Margin/Options"]
+[node name="Reconnect" type="Button" parent="Side/Margin/Options" unique_id=1904838944]
layout_mode = 2
text = "c.menu.ingame.reconnect"
alignment = 0
-[node name="Spacer2" type="Control" parent="Side/Margin/Options"]
+[node name="Spacer2" type="Control" parent="Side/Margin/Options" unique_id=11264676]
custom_minimum_size = Vector2(0, 10)
layout_mode = 2
-[node name="Settings" type="Button" parent="Side/Margin/Options"]
+[node name="Settings" type="Button" parent="Side/Margin/Options" unique_id=1505522399]
layout_mode = 2
text = "c.menu.settings"
alignment = 0
-[node name="Spacer3" type="Control" parent="Side/Margin/Options"]
+[node name="Spacer3" type="Control" parent="Side/Margin/Options" unique_id=834104183]
custom_minimum_size = Vector2(0, 10)
layout_mode = 2
-[node name="MainMenu" type="Button" parent="Side/Margin/Options"]
+[node name="MainMenu" type="Button" parent="Side/Margin/Options" unique_id=1519330892]
layout_mode = 2
text = "c.menu.ingame.main_menu"
alignment = 0
diff --git a/client/gui/menus/main/about.gd b/client/gui/menus/main/about.gd
index 95f98d30..f1f71ef6 100644
--- a/client/gui/menus/main/about.gd
+++ b/client/gui/menus/main/about.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -17,11 +17,18 @@
extends Menu
var authors := ["metamuffin", "nokoe", "tpart"]
-var contributors := ["sofviic", "BigBrotherNii", "Miner34"]
+var contributors := ["sofviic", "BigBrotherNii", "Miner34", "jnms"]
const cc_by_4 := "CC-BY 4.0"
const cc_by_3 := "CC-BY 3.0"
+const cc_by_sa_4 := "CC-BY-SA 4.0"
const cc0 := "CC0"
+const LICENSE_LINKS = {
+ cc_by_4: "https://creativecommons.org/licenses/by/4.0/",
+ cc_by_3: "https://creativecommons.org/licenses/by/3.0/",
+ cc0: "https://creativecommons.org/publicdomain/zero/1.0/",
+}
+
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.
@@ -35,10 +42,32 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>."""
const SOURCE_CODE := "https://codeberg.org/hurrycurry/hurrycurry"
+const REPORT_ISSUE := "https://codeberg.org/hurrycurry/hurrycurry/issues"
func _ready() -> void:
- super()
+ super ()
$side/margin/options/first/source.tooltip_text = SOURCE_CODE
+ $side/margin/options/first/report_issue.tooltip_text = REPORT_ISSUE
+
+var translators = {
+ tr("c.settings.ui.language.ar"): ["sofviic"],
+ tr("c.settings.ui.language.bar"): ["Ember"],
+ tr("c.settings.ui.language.el"): ["n0toose"],
+ tr("c.settings.ui.language.eu"): ["josuigoa"],
+ tr("c.settings.ui.language.fi"): ["Ricky-Tigg"],
+ tr("c.settings.ui.language.fr"): ["fnetX", "lejun", "macbook-girl"],
+ tr("c.settings.ui.language.he"): ["RustyStriker"],
+ tr("c.settings.ui.language.it"): ["Miner34", "solemden"],
+ tr("c.settings.ui.language.ja"): ["BigBrotherNii"],
+ tr("c.settings.ui.language.nl"): ["Vistaus"],
+ tr("c.settings.ui.language.pl"): ["tranzystorekk"],
+ tr("c.settings.ui.language.ru"): ["0ko"],
+ tr("c.settings.ui.language.sv"): ["Mahatma_G"],
+ tr("c.settings.ui.language.tr"): ["furkanunsalan", "tekrei"],
+ tr("c.settings.ui.language.vi"): ["hthienloc"],
+ tr("c.settings.ui.language.zh_Hans"): ["Outbreak2096"],
+ tr("c.settings.ui.language.zh_Hant"): ["hugoalh"],
+}
var credits := [
[tr("c.credits.models"), [
@@ -47,7 +76,8 @@ var credits := [
["Poly by Google", "Strawberry", cc_by_3],
["Poly by Google", "Fish", cc_by_3],
["Poly by Google", "Rolling pin", cc_by_3],
- ["jeremy", "Propeller hat", cc_by_3]
+ ["jeremy", "Propeller hat", cc_by_3],
+ ["jeremy", "Donut", cc_by_3]
]],
[tr("c.credits.sounds"), [
["Dryoma", "Footstep sounds", cc_by_4],
@@ -61,25 +91,14 @@ var credits := [
["Dillon Becker", "Super Dialogue Audio Pack V1", cc_by_4],
["Ekrcoaster", "Water steaming on hot surface #2", cc0]
]],
+ [tr("c.credits.music"), [
+ ["Giorgi Latso, Asuas", "Debussy: Images I. Reflets dans l'eau (adapted: bars 1-35)", cc_by_sa_4],
+ ]],
[tr("c.credits.other"), [
["Ray Trace", "Nintendo_Switch_Pro_Controller.svg", cc_by_4],
["Amousey", "Curved solid arrow.svg", cc0]
]],
- [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"],
- }]
+ [tr("c.credits.translations"), translators]
]
func _menu_cover(state):
@@ -114,24 +133,29 @@ func credits_text() -> String:
text += "[cell][left]%s[/left][/cell]" % entry[2]
text += "[/table]"
text += "\n\n\n"
+
+ text += "[b]%s[/b]\n\n[table=2]" % tr("c.credits.licenses")
+ for key in LICENSE_LINKS:
+ text += "[cell][right]%s[/right][/cell]" % key
+ text += "[cell][left][url=%s]%s[/url][/left][/cell]" % [LICENSE_LINKS[key], tr("c.credits.licenses.link_label")]
+ text += "[/table]\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[3][1].values():
- translators.append_array(c)
- translators.shuffle()
+ var translators_list: Array[String] = []
+ for c in translators.values(): translators_list.append_array(c)
+ translators_list.shuffle()
authors.shuffle()
contributors.shuffle()
all.append_array(authors)
all.append_array(contributors)
- all.append_array(translators)
+ all.append_array(translators_list)
var text := "Hurry Curry! - a game about cooking\n"
- text += "[code]Copyright 2024, 2025 %s\n\n" % ", ".join(dedup_array(all))
+ text += "[code]Copyright 2024, 2025, 2026 %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()
@@ -162,13 +186,15 @@ func _on_legal_pressed() -> void:
func _on_version_pressed() -> void:
submenu("res://gui/menus/popup_large.tscn", version_text())
-func _on_back_pressed() -> void:
- exit()
-
+func _on_report_issue_pressed() -> void:
+ OS.shell_open(REPORT_ISSUE)
func _on_source_pressed() -> void:
OS.shell_open(SOURCE_CODE)
+func _on_back_pressed() -> void:
+ exit()
+
func dedup_array(a: Array) -> Array:
var b = []
for x in a: if not b.has(x): b.append(x)
diff --git a/client/gui/menus/main/about.tscn b/client/gui/menus/main/about.tscn
index 006b61fe..4972f925 100644
--- a/client/gui/menus/main/about.tscn
+++ b/client/gui/menus/main/about.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=7 format=3 uid="uid://bpaenm8c6nmo8"]
+[gd_scene 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"]
@@ -10,7 +10,7 @@
base_font = ExtResource("4_kx3j7")
variation_embolden = 0.5
-[node name="AboutMenu" type="Control"]
+[node name="AboutMenu" type="Control" unique_id=328206708]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
@@ -20,7 +20,7 @@ grow_vertical = 2
script = ExtResource("1_0acu0")
support_anim = false
-[node name="side" type="PanelContainer" parent="."]
+[node name="side" type="PanelContainer" parent="." unique_id=1730663891]
material = ExtResource("1_ai5pk")
layout_mode = 1
anchors_preset = 9
@@ -29,7 +29,7 @@ offset_right = 294.0
grow_vertical = 2
theme_override_styles/panel = ExtResource("2_pya1x")
-[node name="margin" type="MarginContainer" parent="side"]
+[node name="margin" type="MarginContainer" parent="side" unique_id=1640262757]
layout_mode = 2
theme_override_constants/margin_left = 20
theme_override_constants/margin_top = 20
@@ -37,10 +37,10 @@ theme_override_constants/margin_right = 20
theme_override_constants/margin_bottom = 20
script = ExtResource("4_t51wf")
-[node name="options" type="VBoxContainer" parent="side/margin"]
+[node name="options" type="VBoxContainer" parent="side/margin" unique_id=604487146]
layout_mode = 2
-[node name="title" type="Label" parent="side/margin/options"]
+[node name="title" type="Label" parent="side/margin/options" unique_id=1445391877]
auto_translate_mode = 2
layout_mode = 2
theme_override_colors/font_outline_color = Color(0.566408, 0.208917, 0.266045, 1)
@@ -49,39 +49,44 @@ 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"]
+[node name="spacer" type="Control" parent="side/margin/options" unique_id=1554190815]
custom_minimum_size = Vector2(0, 10)
layout_mode = 2
-[node name="first" type="VBoxContainer" parent="side/margin/options"]
+[node name="first" type="VBoxContainer" parent="side/margin/options" unique_id=1664599829]
layout_mode = 2
-[node name="credits" type="Button" parent="side/margin/options/first"]
+[node name="credits" type="Button" parent="side/margin/options/first" unique_id=1348170129]
layout_mode = 2
text = "c.menu.about.credits"
alignment = 0
-[node name="version" type="Button" parent="side/margin/options/first"]
+[node name="version" type="Button" parent="side/margin/options/first" unique_id=451517354]
layout_mode = 2
text = "c.menu.about.version"
alignment = 0
-[node name="legal" type="Button" parent="side/margin/options/first"]
+[node name="legal" type="Button" parent="side/margin/options/first" unique_id=1574566583]
layout_mode = 2
text = "c.menu.about.legal"
alignment = 0
-[node name="source" type="Button" parent="side/margin/options/first"]
+[node name="source" type="Button" parent="side/margin/options/first" unique_id=111074078]
layout_mode = 2
text = "c.menu.about.source"
alignment = 0
-[node name="first2" type="VBoxContainer" parent="side/margin/options"]
+[node name="report_issue" type="Button" parent="side/margin/options/first" unique_id=2075032381]
+layout_mode = 2
+text = "c.menu.about.report_issue"
+alignment = 0
+
+[node name="first2" type="VBoxContainer" parent="side/margin/options" unique_id=2077205946]
layout_mode = 2
size_flags_vertical = 3
alignment = 2
-[node name="back" type="Button" parent="side/margin/options/first2"]
+[node name="back" type="Button" parent="side/margin/options/first2" unique_id=2024436203]
layout_mode = 2
text = "c.menu.back"
alignment = 0
@@ -90,4 +95,5 @@ alignment = 0
[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/first/report_issue" to="." method="_on_report_issue_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
index a0a71a08..e4ca9e5b 100644
--- a/client/gui/menus/main/background.gd
+++ b/client/gui/menus/main/background.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -15,8 +15,17 @@
#
extends Node3D
-const CRATES = ["tomato-crate", "bun-crate", "steak-crate", "cheese-crate", "lettuce-crate", "flour-crate", "coconut-crate"]
-const TOOLS = ["stove", "stove", "stove", "sink", "cutting-board", "sink", "cutting-board", "rolling-board", "oven", "freezer"]
+const CRATES = ["tomato-crate", "bun-crate", "steak-crate", "cheese-crate", "lettuce-crate", "mushroom-crate"]
+const TOOLS_WEIGHTED: Dictionary[Array, float] = {
+ ["stove"]: 3,
+ ["counter", "sink"]: 2,
+ ["counter", "cutting-board"]: 2,
+ ["counter", "rolling-board"]: 2,
+ ["oven"]: 1,
+ ["freezer"]: 1,
+ ["counter", "deep-fryer"]: 1
+}
+const ITEMS = ["pot", "pan", "foodprocessor", "plate", "basket", "lettuce", "dirty-plate", "cheese"]
@onready var environment: WorldEnvironment = $Environment
@onready var map: Map = $Map
@@ -25,26 +34,42 @@ func _ready():
if !Global.on_vulkan():
environment.environment.tonemap_exposure = 0.25
- var tiles = {}
+ var tiles_dict: Dictionary[Vector2i, Array] = {} # : Dictionary[Vector2i, Array[String]]
+ var item_counters := []
for x in range(-10, 11):
for y in range(-10, 11):
- var w = exp(-sqrt(x * x + y * y) * 0.15)
+ var w = exp(-Vector2(x, y).length() * 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))
-
+ var tiles: Array = []
+ if k > 0.25: tiles = ["floor"]
+ if k > 0.4: tiles = ["floor"] + [choose(CRATES)] if randf() > 0.7 else ["floor", "counter"]
+ if k > 0.6: tiles = ["floor"] + choose_weighted(TOOLS_WEIGHTED)
+ if not tiles.is_empty():
+ tiles_dict[Vector2i(x,y)] = tiles
+ if tiles.has("counter") and tiles.size() <= 2 and randf() > 0.5 and w > 0.45:
+ item_counters.push_back(Vector2i(x, y))
+ map.set_all_tiles(tiles_dict)
map.flush()
+ for v: Vector2i in item_counters:
+ var t = map.get_topmost_instance(v)
+ var item := ItemFactory.produce(choose(ITEMS), t)
+ add_child(item)
+ item.position = t.item_base.global_position
+ var rot := randf() * 2 * PI
+ item.rotation.y = rot
+ item.rotation_target = rot
+ t.set_item(item)
+
func choose(a): return a[floor(a.size() * randf())]
+
+func choose_weighted(weighted_options: Dictionary[Array, float]): # -> Array?
+ var weight_sum := 0.
+ var areas: Dictionary[float, Array] = {}
+ for k in weighted_options:
+ weight_sum += weighted_options[k]
+ areas[weight_sum] = k
+ var selection = randf() * weight_sum
+ for k in areas:
+ if k >= selection:
+ return areas[k]
diff --git a/client/gui/menus/main/background.tscn b/client/gui/menus/main/background.tscn
index c1b11c7d..e379da7e 100644
--- a/client/gui/menus/main/background.tscn
+++ b/client/gui/menus/main/background.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=12 format=3 uid="uid://l4vm07dtda4j"]
+[gd_scene 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"]
@@ -43,29 +43,29 @@ 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"]
+[node name="MenuBackground" type="Node3D" unique_id=1471208495]
script = ExtResource("1_pgu7b")
-[node name="Camera" type="Camera3D" parent="."]
+[node name="Camera" type="Camera3D" parent="." unique_id=258327854]
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="."]
+[node name="DirectionalLight3D" type="DirectionalLight3D" parent="." unique_id=1203649791]
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="."]
+[node name="Environment" type="WorldEnvironment" parent="." unique_id=1003206879]
environment = SubResource("Environment_slkjl")
script = ExtResource("2_7dwbj")
allow_sdfgi = false
-[node name="the-sky-tm" type="MeshInstance3D" parent="."]
+[node name="the-sky-tm" type="MeshInstance3D" parent="." unique_id=1016857390]
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")]
+[node name="Map" parent="." unique_id=1077103745 instance=ExtResource("4_nslxb")]
diff --git a/client/gui/menus/main/clouds.gdshader b/client/gui/menus/main/clouds.gdshader
index 8103f691..02073e7a 100644
--- a/client/gui/menus/main/clouds.gdshader
+++ b/client/gui/menus/main/clouds.gdshader
@@ -1,6 +1,6 @@
/*
Hurry Curry! - a game about cooking
- Copyright (C) 2025 Hurry Curry! Contributors
+ Copyright (C) 2026 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
diff --git a/client/gui/menus/main/main.gd b/client/gui/menus/main/main.gd
index 7a389304..584dd404 100644
--- a/client/gui/menus/main/main.gd
+++ b/client/gui/menus/main/main.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -22,12 +22,18 @@ func _ready():
super()
if OS.has_feature("web"):
quit_button.hide()
- Sound.play_music("MainMenu")
ServerList.one_shot()
+ await get_tree().create_timer(0.7).timeout
+
+func _menu_music(): Sound.set_music("reflets-dans-leau", 3, false)
func _menu_cover(state):
$side.visible = not state
+func exit(exit_data = null):
+ Sound.set_music(null)
+ super(exit_data)
+
func _on_quit_pressed():
quit()
diff --git a/client/gui/menus/main/main.tscn b/client/gui/menus/main/main.tscn
index 1cfb2b26..86d9eda2 100644
--- a/client/gui/menus/main/main.tscn
+++ b/client/gui/menus/main/main.tscn
@@ -1,6 +1,5 @@
-[gd_scene load_steps=10 format=3 uid="uid://dbj8508whxgwv"]
+[gd_scene 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"]
@@ -13,19 +12,18 @@
base_font = ExtResource("5_k7bqq")
variation_embolden = 0.5
-[node name="MainMenu" type="Control"]
+[node name="MainMenu" type="Control" unique_id=934155310]
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="MenuBackground" parent="." unique_id=828608925 instance=ExtResource("3_4evao")]
-[node name="side" type="PanelContainer" parent="."]
+[node name="side" type="PanelContainer" parent="." unique_id=1401818823]
material = ExtResource("4_nx4vf")
layout_mode = 1
anchors_preset = 9
@@ -35,7 +33,7 @@ grow_vertical = 2
theme_override_styles/panel = ExtResource("5_qlyeo")
script = ExtResource("5_0mn56")
-[node name="margin" type="MarginContainer" parent="side"]
+[node name="margin" type="MarginContainer" parent="side" unique_id=549446082]
layout_mode = 2
theme_override_constants/margin_left = 20
theme_override_constants/margin_top = 20
@@ -43,10 +41,10 @@ theme_override_constants/margin_right = 20
theme_override_constants/margin_bottom = 20
script = ExtResource("7_btdj1")
-[node name="options" type="VBoxContainer" parent="side/margin"]
+[node name="options" type="VBoxContainer" parent="side/margin" unique_id=1558510257]
layout_mode = 2
-[node name="title" type="Label" parent="side/margin/options"]
+[node name="title" type="Label" parent="side/margin/options" unique_id=540540059]
auto_translate_mode = 2
layout_mode = 2
theme_override_colors/font_outline_color = Color(0.566408, 0.208917, 0.266045, 1)
@@ -55,34 +53,34 @@ 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"]
+[node name="spacer" type="Control" parent="side/margin/options" unique_id=1242411861]
custom_minimum_size = Vector2(0, 10)
layout_mode = 2
-[node name="first" type="VBoxContainer" parent="side/margin/options"]
+[node name="first" type="VBoxContainer" parent="side/margin/options" unique_id=1694849718]
layout_mode = 2
-[node name="play" type="Button" parent="side/margin/options/first"]
+[node name="play" type="Button" parent="side/margin/options/first" unique_id=1447115479]
layout_mode = 2
text = "c.menu.play"
alignment = 0
-[node name="change_character" type="Button" parent="side/margin/options/first"]
+[node name="change_character" type="Button" parent="side/margin/options/first" unique_id=1051730060]
layout_mode = 2
text = "c.menu.customize_chef"
alignment = 0
-[node name="settings" type="Button" parent="side/margin/options/first"]
+[node name="settings" type="Button" parent="side/margin/options/first" unique_id=568488542]
layout_mode = 2
text = "c.menu.settings"
alignment = 0
-[node name="about" type="Button" parent="side/margin/options/first"]
+[node name="about" type="Button" parent="side/margin/options/first" unique_id=1838863329]
layout_mode = 2
text = "c.menu.about"
alignment = 0
-[node name="quit" type="Button" parent="side/margin/options/first"]
+[node name="quit" type="Button" parent="side/margin/options/first" unique_id=1209482714]
layout_mode = 2
text = "c.menu.quit"
alignment = 0
diff --git a/client/gui/menus/main/play.gd b/client/gui/menus/main/play.gd
index 206b4d9f..0100a556 100644
--- a/client/gui/menus/main/play.gd
+++ b/client/gui/menus/main/play.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -35,7 +35,6 @@ func _ready():
if OS.has_feature("web"):
server.hide()
connect_uri.text = Profile.read("last_server_url")
- Sound.play_music("MainMenu")
ServerList.update_server_list.connect(update_server_list)
ServerList.update_loading.connect(update_server_list_loading)
@@ -72,12 +71,21 @@ func update_server_list(lists: Array[Array]):
var idx := 0
for l in lists:
+ # Move incompatible servers to the end of list
+ for i in l:
+ if not Global.is_protocol_version_compatible(i.version):
+ l.erase(i)
+ l.push_back(i)
+
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]))
+
+ var urls: Array[String] = []
+ urls.append_array(i.address)
+
+ server_item.setup(i.name, roundi(i.players_online), i.version, urls)
+ server_item.button.pressed.connect(connect_to.bind(urls))
# Focus the same server with the same index as the previously focused one
if idx == prev_selected_idx:
server_item.button.grab_focus()
@@ -110,8 +118,9 @@ func _on_connect_pressed():
url = url + ":27032"
connect_uri.text = url
Profile.write("last_server_url", url)
- connect_to(url)
+ connect_to([url])
+# TODO unused code
func _on_quick_connect_pressed():
if OS.has_feature("web"):
connect_to(JavaScriptBridge.eval("""
@@ -120,11 +129,10 @@ func _on_quick_connect_pressed():
: `ws://${window.location.hostname}:27032/`
"""))
else:
- connect_to("wss://hurrycurry.metamuffin.org/")
+ 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 connect_to(urls: Array[String]):
+ get_parent().replace_menu("res://gui/menus/game.tscn", urls)
func _on_server_control_pressed():
match Server.state:
@@ -139,10 +147,10 @@ func _on_editor_control_pressed():
Service.State.FAILED: Editor.start()
func _on_server_connect_pressed():
- connect_to("ws://%s:%d" % [ServerService.connect_address(), Settings.read("server.bind_port")])
+ connect_to(["ws://%s:%d" % [ServerService.connect_address(), Settings.read("server.bind_port")]])
func _on_editor_connect_pressed():
- connect_to("ws://[::1]:27032/")
+ connect_to(["ws://[::1]:27035/"])
func _process(_delta):
server_control.disabled = false
diff --git a/client/gui/menus/main/play.tscn b/client/gui/menus/main/play.tscn
index 441024a2..bad01b3d 100644
--- a/client/gui/menus/main/play.tscn
+++ b/client/gui/menus/main/play.tscn
@@ -1,6 +1,5 @@
-[gd_scene load_steps=9 format=3 uid="uid://c8url5fpttbem"]
+[gd_scene 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"]
@@ -13,18 +12,17 @@
base_font = ExtResource("5_ojpbf")
variation_embolden = 0.5
-[node name="PlayMenu" type="Control"]
+[node name="PlayMenu" type="Control" unique_id=1252891233]
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="."]
+[node name="side" type="PanelContainer" parent="." unique_id=1284540533]
material = ExtResource("3_fsbt7")
layout_mode = 1
anchors_preset = 9
@@ -33,7 +31,7 @@ offset_right = 294.0
grow_vertical = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_ukani")
-[node name="margin" type="MarginContainer" parent="side"]
+[node name="margin" type="MarginContainer" parent="side" unique_id=1784114587]
layout_mode = 2
theme_override_constants/margin_left = 20
theme_override_constants/margin_top = 20
@@ -41,10 +39,10 @@ theme_override_constants/margin_right = 20
theme_override_constants/margin_bottom = 20
script = ExtResource("4_gst6r")
-[node name="options" type="VBoxContainer" parent="side/margin"]
+[node name="options" type="VBoxContainer" parent="side/margin" unique_id=393125381]
layout_mode = 2
-[node name="title" type="Label" parent="side/margin/options"]
+[node name="title" type="Label" parent="side/margin/options" unique_id=793049090]
auto_translate_mode = 2
layout_mode = 2
theme_override_colors/font_outline_color = Color(0.566408, 0.208917, 0.266045, 1)
@@ -53,91 +51,91 @@ 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"]
+[node name="spacer" type="Control" parent="side/margin/options" unique_id=1031721504]
custom_minimum_size = Vector2(0, 10)
layout_mode = 2
-[node name="second" type="VBoxContainer" parent="side/margin/options"]
+[node name="second" type="VBoxContainer" parent="side/margin/options" unique_id=704950761]
layout_mode = 2
size_flags_vertical = 3
-[node name="Loading" type="Label" parent="side/margin/options/second"]
+[node name="Loading" type="Label" parent="side/margin/options/second" unique_id=135556328]
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"]
+[node name="NoServers" type="Label" parent="side/margin/options/second" unique_id=410117321]
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"]
+[node name="ScrollContainerCustom" type="ScrollContainer" parent="side/margin/options/second" unique_id=333759324]
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"]
+[node name="ServerList" type="VBoxContainer" parent="side/margin/options/second/ScrollContainerCustom" unique_id=80221134]
layout_mode = 2
size_flags_horizontal = 3
-[node name="spacer" type="Control" parent="side/margin/options/second"]
+[node name="spacer" type="Control" parent="side/margin/options/second" unique_id=1444292306]
custom_minimum_size = Vector2(0, 10)
layout_mode = 2
-[node name="connect" type="HBoxContainer" parent="side/margin/options/second"]
+[node name="connect" type="HBoxContainer" parent="side/margin/options/second" unique_id=1829587107]
layout_mode = 2
-[node name="uri" type="LineEdit" parent="side/margin/options/second/connect"]
+[node name="uri" type="LineEdit" parent="side/margin/options/second/connect" unique_id=1944124428]
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"]
+[node name="connect" type="Button" parent="side/margin/options/second/connect" unique_id=1041792506]
layout_mode = 2
text = "c.menu.play.connect"
-[node name="server" type="HBoxContainer" parent="side/margin/options/second"]
+[node name="server" type="HBoxContainer" parent="side/margin/options/second" unique_id=1567357857]
layout_mode = 2
-[node name="control" type="Button" parent="side/margin/options/second/server"]
+[node name="control" type="Button" parent="side/margin/options/second/server" unique_id=1099190373]
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"]
+[node name="connect" type="Button" parent="side/margin/options/second/server" unique_id=1829531390]
layout_mode = 2
text = "c.menu.play.connect"
-[node name="editor" type="HBoxContainer" parent="side/margin/options/second"]
+[node name="editor" type="HBoxContainer" parent="side/margin/options/second" unique_id=1123501321]
layout_mode = 2
-[node name="control" type="Button" parent="side/margin/options/second/editor"]
+[node name="control" type="Button" parent="side/margin/options/second/editor" unique_id=613744759]
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"]
+[node name="connect" type="Button" parent="side/margin/options/second/editor" unique_id=1523696561]
layout_mode = 2
text = "c.menu.play.connect"
-[node name="spacer2" type="Control" parent="side/margin/options/second"]
+[node name="spacer2" type="Control" parent="side/margin/options/second" unique_id=1087902272]
custom_minimum_size = Vector2(0, 10)
layout_mode = 2
-[node name="back" type="Button" parent="side/margin/options/second"]
+[node name="back" type="Button" parent="side/margin/options/second" unique_id=1719311439]
layout_mode = 2
text = "c.menu.back"
alignment = 0
-[node name="VBoxContainer" type="VBoxContainer" parent="side/margin/options/second"]
+[node name="VBoxContainer" type="VBoxContainer" parent="side/margin/options/second" unique_id=1532324619]
layout_mode = 2
[connection signal="text_changed" from="side/margin/options/second/connect/uri" to="." method="_on_uri_text_changed"]
diff --git a/client/gui/menus/main/server_list_item.gd b/client/gui/menus/main/server_list_item.gd
index 0cffdd72..4ec191a3 100644
--- a/client/gui/menus/main/server_list_item.gd
+++ b/client/gui/menus/main/server_list_item.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -17,19 +17,29 @@ class_name ServerListItem
extends PanelContainer
var error_style_focus: StyleBoxFlat = preload("res://gui/resources/style/error_focus_style.tres")
+var error_style_normal: StyleBoxFlat = preload("res://gui/resources/style/error_normal_style.tres")
+
@onready var title: Label = $MarginContainer/VBoxContainer/Title
-@onready var info: Label = $MarginContainer/VBoxContainer/Info
+@onready var online: Label = $MarginContainer/VBoxContainer/HBoxContainer/Online
+@onready var address: Label = $MarginContainer/VBoxContainer/HBoxContainer/Address
@onready var button: Button = $Button
-func setup(name_: String, online_players: int, version: Array):
+func setup(name_: String, online_players: int, version: Array, addresses: Array[String]):
title.text = name_
- if version[0] != Multiplayer.VERSION_MAJOR or version[1] > Multiplayer.VERSION_MINOR:
+ if not Global.is_protocol_version_compatible(version):
button.disabled = true
+ button.add_theme_stylebox_override("disabled", error_style_normal)
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"))
+ online.text = tr("c.menu.play.server_version_mismatch")
+ online.add_theme_color_override("font_color", Color("ff2222"))
+ address.visible = false
return
- info.text = tr("c.menu.play.server_players").format([online_players])
+ online.text = tr("c.menu.play.server_players").format([online_players])
+
+ if addresses.size() > 1 or not addresses[0].begins_with("wss://"):
+ address.visible = false
+ else:
+ address.text = addresses[0].trim_suffix(":443").trim_prefix("wss://").trim_prefix("hurrycurry.")
# 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
diff --git a/client/gui/menus/main/server_list_item.tscn b/client/gui/menus/main/server_list_item.tscn
index ee1b9bf7..7d892a78 100644
--- a/client/gui/menus/main/server_list_item.tscn
+++ b/client/gui/menus/main/server_list_item.tscn
@@ -1,20 +1,20 @@
-[gd_scene load_steps=3 format=3 uid="uid://t2h60dhuvfsk"]
+[gd_scene 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"]
+[node name="ServerListItem" type="PanelContainer" unique_id=2062705951]
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"]]
+[node name="Button" type="Button" parent="." unique_id=1213365601 groups=["no_click_sound"]]
layout_mode = 2
-[node name="MarginContainer" type="MarginContainer" parent="."]
+[node name="MarginContainer" type="MarginContainer" parent="." unique_id=1363186299]
layout_mode = 2
mouse_filter = 2
theme_override_constants/margin_left = 10
@@ -22,19 +22,33 @@ 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"]
+[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer" unique_id=1686608173]
layout_mode = 2
mouse_filter = 2
-[node name="Title" type="Label" parent="MarginContainer/VBoxContainer"]
+[node name="Title" type="Label" parent="MarginContainer/VBoxContainer" unique_id=27759863]
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"
text_overrun_behavior = 3
-[node name="Info" type="Label" parent="MarginContainer/VBoxContainer"]
+[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer" unique_id=1537690218]
+layout_mode = 2
+mouse_filter = 2
+theme_override_constants/separation = 16
+
+[node name="Online" type="Label" parent="MarginContainer/VBoxContainer/HBoxContainer" unique_id=741851992]
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"
+text = "5 players"
+
+[node name="Address" type="Label" parent="MarginContainer/VBoxContainer/HBoxContainer" unique_id=1214181115]
+layout_mode = 2
+size_flags_horizontal = 3
+theme_override_colors/font_color = Color(0.749781, 0.74978, 0.74978, 1)
+theme_override_font_sizes/font_size = 14
+text = "wss://example.example.example.org"
+horizontal_alignment = 2
+text_overrun_behavior = 3
diff --git a/client/gui/menus/map_selector/map_details_selector.gd b/client/gui/menus/map_selector/map_details_selector.gd
new file mode 100644
index 00000000..250c299b
--- /dev/null
+++ b/client/gui/menus/map_selector/map_details_selector.gd
@@ -0,0 +1,120 @@
+# Hurry Curry! - a game about cooking
+# Copyright (C) 2026 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 <https://www.gnu.org/licenses/>.
+#
+extends Menu
+class_name MapDetailsSelector
+
+const MAX_BOT_COUNT_PER_TYPE: int = 3
+
+var two_handed: bool
+var default_two_handed: bool
+var bots_enabled := false
+var bot_counts: Dictionary[String, int] = {}
+
+var bot_reset_buttons: Dictionary[String, Button] = {}
+var bot_inc_buttons: Dictionary[String, Button] = {}
+var bot_dec_buttons: Dictionary[String, Button] = {}
+
+@onready var game: Game = $"../../Game" # TODO
+
+@onready var title_label: Label = $OuterMargin/Panel/InnerMargin/VBoxContainer/Title
+@onready var bots_container: VBoxContainer = $OuterMargin/Panel/InnerMargin/VBoxContainer/VBoxContainer/Bots
+@onready var bot_settings: Control = $OuterMargin/Panel/InnerMargin/VBoxContainer/VBoxContainer/Bots/ScrollContainerCustom/BotSettings
+@onready var bot_settings_container: Control = $OuterMargin/Panel/InnerMargin/VBoxContainer/VBoxContainer/Bots/ScrollContainerCustom
+@onready var start_button: Button = $OuterMargin/Panel/InnerMargin/VBoxContainer/HBoxContainer/Start
+@onready var two_handed_button: CheckButton = $OuterMargin/Panel/InnerMargin/VBoxContainer/VBoxContainer/TwoHanded
+@onready var custom_game_warning: Label = $OuterMargin/Panel/InnerMargin/VBoxContainer/CustomGameWarning
+
+func _ready() -> void:
+ title_label.text = data[0]["display_name"]
+ default_two_handed = false if data[0]["hand_count"] == 1. else true
+ two_handed = default_two_handed
+ two_handed_button.button_pressed = two_handed
+
+ var bot_algos: Array = data[1]
+ for algo: String in bot_algos:
+ bot_counts[algo] = 0
+
+ var h := HBoxContainer.new()
+ h.name = algo
+ 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] = reset
+ bot_inc_buttons[algo] = add
+ bot_dec_buttons[algo] = remove
+ update_bot_reset_text(algo)
+ add.pressed.connect(increase_bot_count.bind(algo))
+ reset.pressed.connect(reset_bot_count.bind(algo))
+ remove.pressed.connect(decrease_bot_count.bind(algo))
+ h.add_child(remove)
+ h.add_child(reset)
+ h.add_child(add)
+ bot_settings.add_child(h)
+
+ super()
+ start_button.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):
+ if bot_counts[algo_id] == 0: bot_counts[algo_id] = 1
+ else: 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]]
+ set_disabled(bot_reset_buttons[algo_id], false)
+ set_disabled(bot_inc_buttons[algo_id], not bot_counts[algo_id] < MAX_BOT_COUNT_PER_TYPE)
+ set_disabled(bot_dec_buttons[algo_id], not bot_counts[algo_id] > 0)
+
+func _on_enable_bots_toggled(toggled_on: bool) -> void:
+ bots_enabled = toggled_on
+ bot_settings_container.visible = toggled_on
+ update_warning()
+
+func _on_two_handed_toggled(toggled_on: bool) -> void:
+ two_handed = toggled_on
+ update_warning()
+
+func _on_back_pressed() -> void:
+ exit(false)
+
+func _on_start_pressed() -> void:
+ var selected_map_name: String = data[0]["name"]
+ var hand_count: int = 2 if two_handed else 1
+
+ var selected_bots: Array[String] = []
+ if bots_enabled:
+ for k in bot_counts.keys():
+ for i in range(bot_counts[k]):
+ selected_bots.append(k)
+
+ @warning_ignore("incompatible_ternary")
+ game.mp.send_start_game_vote(game.my_player_id, selected_map_name, hand_count if two_handed != default_two_handed else null, selected_bots if bots_enabled else null)
+ exit(true)
+
+func update_warning():
+ custom_game_warning.visible = two_handed != default_two_handed or bots_enabled
diff --git a/client/gui/menus/map_selector/map_details_selector.gd.uid b/client/gui/menus/map_selector/map_details_selector.gd.uid
new file mode 100644
index 00000000..7a32eb14
--- /dev/null
+++ b/client/gui/menus/map_selector/map_details_selector.gd.uid
@@ -0,0 +1 @@
+uid://cntuh7y15r4uy
diff --git a/client/gui/menus/map_selector/map_details_selector.tscn b/client/gui/menus/map_selector/map_details_selector.tscn
new file mode 100644
index 00000000..750f6d57
--- /dev/null
+++ b/client/gui/menus/map_selector/map_details_selector.tscn
@@ -0,0 +1,112 @@
+[gd_scene format=3 uid="uid://bx0n0h6jh7hrd"]
+
+[ext_resource type="Script" uid="uid://cntuh7y15r4uy" path="res://gui/menus/map_selector/map_details_selector.gd" id="1_jsc2p"]
+[ext_resource type="Script" uid="uid://byshs20og68tn" path="res://gui/components/smart_margin_container.gd" id="2_ksn3m"]
+[ext_resource type="Material" uid="uid://beea1pc5nt67r" path="res://gui/resources/materials/dark_blur_material.tres" id="3_f0rsd"]
+[ext_resource type="Script" uid="uid://cmncjc06kadpe" path="res://gui/components/blur_setup.gd" id="4_d3ya2"]
+[ext_resource type="Script" uid="uid://bd7bylb2t2m0" path="res://gui/components/touch_scroll_container.gd" id="6_dxk78"]
+
+[node name="MapDetailsSelector" type="Control" unique_id=510306535]
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+script = ExtResource("1_jsc2p")
+support_anim = false
+
+[node name="OuterMargin" type="MarginContainer" parent="." unique_id=869412596]
+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
+script = ExtResource("2_ksn3m")
+
+[node name="Panel" type="Panel" parent="OuterMargin" unique_id=1557970649]
+material = ExtResource("3_f0rsd")
+layout_mode = 2
+script = ExtResource("4_d3ya2")
+
+[node name="InnerMargin" type="MarginContainer" parent="OuterMargin/Panel" unique_id=2023236197]
+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="VBoxContainer" type="VBoxContainer" parent="OuterMargin/Panel/InnerMargin" unique_id=2137087020]
+layout_mode = 2
+size_flags_horizontal = 3
+
+[node name="Title" type="Label" parent="OuterMargin/Panel/InnerMargin/VBoxContainer" unique_id=1471975030]
+layout_mode = 2
+theme_override_font_sizes/font_size = 36
+text = "Map name"
+horizontal_alignment = 1
+
+[node name="VBoxContainer" type="VBoxContainer" parent="OuterMargin/Panel/InnerMargin/VBoxContainer" unique_id=1831622843]
+layout_mode = 2
+size_flags_vertical = 3
+
+[node name="TwoHanded" type="CheckButton" parent="OuterMargin/Panel/InnerMargin/VBoxContainer/VBoxContainer" unique_id=1928176691]
+layout_mode = 2
+text = "c.menu.map_selector.two_handed"
+
+[node name="Bots" type="VBoxContainer" parent="OuterMargin/Panel/InnerMargin/VBoxContainer/VBoxContainer" unique_id=1569430044]
+layout_mode = 2
+size_flags_vertical = 3
+
+[node name="EnableBots" type="CheckButton" parent="OuterMargin/Panel/InnerMargin/VBoxContainer/VBoxContainer/Bots" unique_id=1715103927]
+layout_mode = 2
+text = "c.menu.map_selector.enable_bots"
+
+[node name="ScrollContainerCustom" type="ScrollContainer" parent="OuterMargin/Panel/InnerMargin/VBoxContainer/VBoxContainer/Bots" unique_id=1499397868]
+visible = false
+layout_mode = 2
+size_flags_vertical = 3
+script = ExtResource("6_dxk78")
+metadata/_custom_type_script = "uid://bd7bylb2t2m0"
+
+[node name="BotSettings" type="VBoxContainer" parent="OuterMargin/Panel/InnerMargin/VBoxContainer/VBoxContainer/Bots/ScrollContainerCustom" unique_id=101347071]
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 3
+
+[node name="CustomGameWarning" type="Label" parent="OuterMargin/Panel/InnerMargin/VBoxContainer" unique_id=557709694]
+visible = false
+layout_mode = 2
+theme_override_colors/font_color = Color(1, 0.9019608, 0.49803922, 1)
+text = "s.custom_game_warn"
+horizontal_alignment = 1
+
+[node name="HBoxContainer" type="HBoxContainer" parent="OuterMargin/Panel/InnerMargin/VBoxContainer" unique_id=2025174871]
+layout_mode = 2
+
+[node name="Back" type="Button" parent="OuterMargin/Panel/InnerMargin/VBoxContainer/HBoxContainer" unique_id=2006434901]
+layout_mode = 2
+text = "c.menu.back"
+
+[node name="Spacer" type="Control" parent="OuterMargin/Panel/InnerMargin/VBoxContainer/HBoxContainer" unique_id=399194568]
+layout_mode = 2
+size_flags_horizontal = 3
+
+[node name="Start" type="Button" parent="OuterMargin/Panel/InnerMargin/VBoxContainer/HBoxContainer" unique_id=1675695981]
+layout_mode = 2
+text = "c.menu.map_selector.start"
+
+[connection signal="toggled" from="OuterMargin/Panel/InnerMargin/VBoxContainer/VBoxContainer/TwoHanded" to="." method="_on_two_handed_toggled"]
+[connection signal="toggled" from="OuterMargin/Panel/InnerMargin/VBoxContainer/VBoxContainer/Bots/EnableBots" to="." method="_on_enable_bots_toggled"]
+[connection signal="pressed" from="OuterMargin/Panel/InnerMargin/VBoxContainer/HBoxContainer/Back" to="." method="_on_back_pressed"]
+[connection signal="pressed" from="OuterMargin/Panel/InnerMargin/VBoxContainer/HBoxContainer/Start" to="." method="_on_start_pressed"]
diff --git a/client/gui/menus/map_selector/map_list_item.gd b/client/gui/menus/map_selector/map_list_item.gd
new file mode 100644
index 00000000..7775c079
--- /dev/null
+++ b/client/gui/menus/map_selector/map_list_item.gd
@@ -0,0 +1,28 @@
+# Hurry Curry! - a game about cooking
+# Copyright (C) 2026 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 <https://www.gnu.org/licenses/>.
+#
+class_name MapListItem
+extends PanelContainer
+
+@onready var button: Button = $Button
+
+@onready var name_label: Label = $MarginContainer/VBoxContainer/Name
+@onready var difficulty_label: Label = $MarginContainer/VBoxContainer/HBoxContainer/Difficulty
+@onready var recommended_players_label: Label = $MarginContainer/VBoxContainer/HBoxContainer/RecommendedPlayers
+
+func setup(name_: String, difficulty: int, recommended_players: int):
+ name_label.text = name_
+ difficulty_label.text = tr("c.map.difficulty.%d" % (difficulty - 1))
+ recommended_players_label.text = tr("c.map.players_recommended").format([recommended_players])
diff --git a/client/gui/menus/map_selector/map_list_item.gd.uid b/client/gui/menus/map_selector/map_list_item.gd.uid
new file mode 100644
index 00000000..41f512a7
--- /dev/null
+++ b/client/gui/menus/map_selector/map_list_item.gd.uid
@@ -0,0 +1 @@
+uid://di7j0scdcg2ox
diff --git a/client/gui/menus/map_selector/map_list_item.tscn b/client/gui/menus/map_selector/map_list_item.tscn
new file mode 100644
index 00000000..65736fc7
--- /dev/null
+++ b/client/gui/menus/map_selector/map_list_item.tscn
@@ -0,0 +1,59 @@
+[gd_scene format=3 uid="uid://buyelb8w7edpe"]
+
+[ext_resource type="Script" uid="uid://di7j0scdcg2ox" path="res://gui/menus/map_selector/map_list_item.gd" id="1_fywrp"]
+[ext_resource type="StyleBox" uid="uid://d1xhwgrptnlli" path="res://gui/resources/style/panel_button_backround_style.tres" id="2_3fooa"]
+
+[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_1n1yg"]
+
+[node name="ServerListItem" type="PanelContainer" unique_id=2062705951]
+offset_right = 400.0
+offset_bottom = 40.0
+size_flags_horizontal = 3
+theme_override_styles/panel = SubResource("StyleBoxEmpty_1n1yg")
+script = ExtResource("1_fywrp")
+
+[node name="Panel" type="Panel" parent="." unique_id=485329348]
+layout_mode = 2
+theme_override_styles/panel = ExtResource("2_3fooa")
+
+[node name="Button" type="Button" parent="." unique_id=1213365601]
+layout_mode = 2
+
+[node name="MarginContainer" type="MarginContainer" parent="." unique_id=1363186299]
+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" unique_id=1686608173]
+layout_mode = 2
+mouse_filter = 2
+
+[node name="Name" type="Label" parent="MarginContainer/VBoxContainer" unique_id=27759863]
+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 Map"
+text_overrun_behavior = 3
+
+[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer" unique_id=1537690218]
+layout_mode = 2
+mouse_filter = 2
+theme_override_constants/separation = 16
+
+[node name="Difficulty" type="Label" parent="MarginContainer/VBoxContainer/HBoxContainer" unique_id=741851992]
+layout_mode = 2
+theme_override_colors/font_color = Color(0.749781, 0.74978, 0.74978, 1)
+theme_override_font_sizes/font_size = 14
+text = "Medium"
+
+[node name="RecommendedPlayers" type="Label" parent="MarginContainer/VBoxContainer/HBoxContainer" unique_id=1214181115]
+layout_mode = 2
+size_flags_horizontal = 3
+theme_override_colors/font_color = Color(0.749781, 0.74978, 0.74978, 1)
+theme_override_font_sizes/font_size = 14
+text = "5 players recommended"
+horizontal_alignment = 2
+text_overrun_behavior = 3
diff --git a/client/gui/menus/map_selector/map_selector.gd b/client/gui/menus/map_selector/map_selector.gd
new file mode 100644
index 00000000..9190b8f3
--- /dev/null
+++ b/client/gui/menus/map_selector/map_selector.gd
@@ -0,0 +1,43 @@
+# Hurry Curry! - a game about cooking
+# Copyright (C) 2026 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 <https://www.gnu.org/licenses/>.
+#
+extends Menu
+class_name MapSelector
+
+const MAP_LIST_ITEM = preload("res://gui/menus/map_selector/map_list_item.tscn")
+
+@onready var map_container: VBoxContainer = $OuterMargin/Panel/InnerMargin/VBoxContainer/ScrollContainer/VBoxContainer
+
+func _ready() -> void:
+ var maps: Array = data[0]
+ for m in maps:
+ var item: MapListItem = MAP_LIST_ITEM.instantiate()
+ item.name = m["name"]
+ map_container.add_child(item)
+ item.setup(m["display_name"], int(m["difficulty"]), int(m["players"]))
+ item.button.pressed.connect(select_map.bind(m))
+ super()
+
+func select_map(map):
+ var algos: Array = data[1]
+ var success = await submenu("res://gui/menus/map_selector/map_details_selector.tscn", [map, algos])
+ if success: exit()
+
+func _menu_cover(state: bool):
+ # TODO: Find a better way to hide this menu without hiding submenu, this feels hacky
+ $OuterMargin.visible = not state
+
+func _on_back_pressed() -> void:
+ exit()
diff --git a/client/gui/menus/map_selector/map_selector.gd.uid b/client/gui/menus/map_selector/map_selector.gd.uid
new file mode 100644
index 00000000..64f6e6d9
--- /dev/null
+++ b/client/gui/menus/map_selector/map_selector.gd.uid
@@ -0,0 +1 @@
+uid://dgl836r2uwjfw
diff --git a/client/gui/menus/map_selector/map_selector.tscn b/client/gui/menus/map_selector/map_selector.tscn
new file mode 100644
index 00000000..b88ec0ea
--- /dev/null
+++ b/client/gui/menus/map_selector/map_selector.tscn
@@ -0,0 +1,76 @@
+[gd_scene format=3 uid="uid://b26sufndh0pm5"]
+
+[ext_resource type="Script" uid="uid://dgl836r2uwjfw" path="res://gui/menus/map_selector/map_selector.gd" id="1_37to6"]
+[ext_resource type="Script" uid="uid://byshs20og68tn" path="res://gui/components/smart_margin_container.gd" id="2_5vs08"]
+[ext_resource type="Material" uid="uid://beea1pc5nt67r" path="res://gui/resources/materials/dark_blur_material.tres" id="3_txniv"]
+[ext_resource type="Script" uid="uid://cmncjc06kadpe" path="res://gui/components/blur_setup.gd" id="4_kobpr"]
+[ext_resource type="Script" uid="uid://bd7bylb2t2m0" path="res://gui/components/touch_scroll_container.gd" id="6_7xmra"]
+
+[node name="MapSelector" type="Control" unique_id=510306535]
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+script = ExtResource("1_37to6")
+support_anim = false
+
+[node name="OuterMargin" type="MarginContainer" parent="." unique_id=869412596]
+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
+script = ExtResource("2_5vs08")
+
+[node name="Panel" type="Panel" parent="OuterMargin" unique_id=1557970649]
+material = ExtResource("3_txniv")
+layout_mode = 2
+script = ExtResource("4_kobpr")
+
+[node name="InnerMargin" type="MarginContainer" parent="OuterMargin/Panel" unique_id=2023236197]
+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="VBoxContainer" type="VBoxContainer" parent="OuterMargin/Panel/InnerMargin" unique_id=2137087020]
+layout_mode = 2
+size_flags_horizontal = 3
+
+[node name="Title" type="Label" parent="OuterMargin/Panel/InnerMargin/VBoxContainer" unique_id=1471975030]
+layout_mode = 2
+theme_override_font_sizes/font_size = 36
+text = "c.map.select"
+horizontal_alignment = 1
+
+[node name="ScrollContainer" type="ScrollContainer" parent="OuterMargin/Panel/InnerMargin/VBoxContainer" unique_id=394287120]
+layout_mode = 2
+size_flags_vertical = 3
+script = ExtResource("6_7xmra")
+
+[node name="VBoxContainer" type="VBoxContainer" parent="OuterMargin/Panel/InnerMargin/VBoxContainer/ScrollContainer" unique_id=1798845933]
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 3
+
+[node name="HBoxContainer" type="HBoxContainer" parent="OuterMargin/Panel/InnerMargin/VBoxContainer" unique_id=1907231166]
+layout_mode = 2
+
+[node name="Back" type="Button" parent="OuterMargin/Panel/InnerMargin/VBoxContainer/HBoxContainer" unique_id=1801916460]
+layout_mode = 2
+text = "c.menu.back"
+
+[connection signal="pressed" from="OuterMargin/Panel/InnerMargin/VBoxContainer/HBoxContainer/Back" to="." method="_on_back_pressed"]
diff --git a/client/gui/menus/menu.gd b/client/gui/menus/menu.gd
index e0d5472a..6d440118 100644
--- a/client/gui/menus/menu.gd
+++ b/client/gui/menus/menu.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -24,13 +24,15 @@ extends Control
var data
-signal submenu_close()
+signal submenu_close(exit_data: Variant)
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
+var exiting := false
+var disabled := false
func _ready():
open_since = Time.get_ticks_msec()
@@ -41,6 +43,7 @@ func _ready():
update_parent_menu(self.get_parent())
if support_anim: anim_setup()
if auto_anim: _menu_open()
+ _menu_music()
get_tree().get_root().go_back_requested.connect(exit_maybe)
func anim_setup():
@@ -52,40 +55,60 @@ func _menu_exit():
if transition != null: await transition.fade_out()
func _menu_cover(_state: bool):
pass
+func _menu_music():
+ pass
var popup: Menu = null
var covered := false
-func submenu(path: String, data_ = null):
+func submenu(path: String, data_ = null) -> Variant:
var prev_focus = Global.focused_node
if popup != null: return
- _disable_recursive(self, true)
+ disabled = true; _update_disabled(self)
covered = true
await _menu_cover(true)
popup = load(path).instantiate()
popup.data = data_
add_child(popup)
# print("Submenu opened ", path)
- await submenu_close
+ var exit_data = await submenu_close
# print("Submenu closed ", path)
covered = false
await _menu_cover(false)
Global.focused_menu = self
- _disable_recursive(self, false)
+ _menu_music()
+ disabled = false; _update_disabled(self)
if prev_focus != null: prev_focus.grab_focus()
+ return exit_data
+
+func _update_disabled(node: Node):
+ if node is BaseButton: _update_button_disabled(node)
+ for c in node.get_children(): _update_disabled(c)
+
+func _update_button_disabled(node: BaseButton):
+ if disabled:
+ if node.disabled: node.add_to_group("disabled")
+ else: node.remove_from_group("disabled")
+ node.disabled = true
+ else:
+ node.disabled = node.is_in_group("disabled")
+ node.remove_from_group("disabled")
-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 set_disabled(node: BaseButton, state: bool):
+ if state: node.add_to_group("disabled")
+ else: node.remove_from_group("disabled")
+ node.disabled = state or disabled
-func exit():
+func exit(exit_data: Variant = null):
+ disabled = true; _update_disabled(self)
+ if transition and transition.fading:
+ push_error("menu exit() called twice")
+ return
+ if popup != null: await popup.exit()
await self._menu_exit()
if previous_path != null:
replace_menu(previous_path)
else:
- get_parent().submenu_close.emit()
+ get_parent().submenu_close.emit(exit_data)
queue_free()
func quit():
@@ -93,15 +116,17 @@ func quit():
get_parent().quit()
func replace_menu(path: String, data_ = null, prev_path = null): # prev_path: String?
+ if exiting: return # Already fading out
print("Replace menu: ", path)
+ exiting = true
if popup != null: await popup.exit()
- _disable_recursive(self, true)
+ disabled = true; _update_disabled(self)
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
+ var new_menu: Menu = load(path).instantiate()
+ new_menu.data = data_
+ if prev_path != null: new_menu.previous_path = prev_path
+ get_parent().add_child(new_menu)
+ if parent_menu != null: parent_menu.popup = new_menu
queue_free()
var focus_auto_changed := false
@@ -145,7 +170,12 @@ func _input(_event):
func exit_maybe() -> void:
# Exit menu if all conditions are met
if popup != null: return
+ if transition and transition.fading: return
var time := Time.get_ticks_msec()
if time - open_since < 100: return
Sound.play_click()
exit()
+
+static func get_parent_menu(node: Node) -> Menu:
+ if node is Menu: return node
+ else: return Menu.get_parent_menu(node.get_parent())
diff --git a/client/gui/menus/popup.gd b/client/gui/menus/popup.gd
index d4849e92..75ed20fd 100644
--- a/client/gui/menus/popup.gd
+++ b/client/gui/menus/popup.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/gui/menus/popup.tscn b/client/gui/menus/popup.tscn
index 13137ccb..9824befd 100644
--- a/client/gui/menus/popup.tscn
+++ b/client/gui/menus/popup.tscn
@@ -1,23 +1,21 @@
-[gd_scene load_steps=6 format=3 uid="uid://lwtym0pbc17g"]
+[gd_scene 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"]
+[node name="Popup" type="Control" unique_id=1672917346]
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="."]
+[node name="MarginContainer" type="MarginContainer" parent="." unique_id=1225266694]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
@@ -26,27 +24,27 @@ grow_horizontal = 2
grow_vertical = 2
script = ExtResource("3_j0ajn")
-[node name="CenterContainer" type="CenterContainer" parent="MarginContainer"]
+[node name="CenterContainer" type="CenterContainer" parent="MarginContainer" unique_id=1460089015]
layout_mode = 2
-[node name="Panel" type="PanelContainer" parent="MarginContainer/CenterContainer"]
+[node name="Panel" type="PanelContainer" parent="MarginContainer/CenterContainer" unique_id=1826029895]
material = ExtResource("3_iouvy")
layout_mode = 2
script = ExtResource("4_e4iqk")
-[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/CenterContainer/Panel"]
+[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/CenterContainer/Panel" unique_id=52701780]
layout_mode = 2
-[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/CenterContainer/Panel/MarginContainer"]
+[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/CenterContainer/Panel/MarginContainer" unique_id=1126454074]
layout_mode = 2
theme_override_constants/separation = 16
-[node name="Message" type="Label" parent="MarginContainer/CenterContainer/Panel/MarginContainer/VBoxContainer"]
+[node name="Message" type="Label" parent="MarginContainer/CenterContainer/Panel/MarginContainer/VBoxContainer" unique_id=1617024507]
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"]
+[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/CenterContainer/Panel/MarginContainer/VBoxContainer" unique_id=1415559610]
layout_mode = 2
alignment = 1
diff --git a/client/gui/menus/popup_large.gd b/client/gui/menus/popup_large.gd
index 772a8373..41f6bd9f 100644
--- a/client/gui/menus/popup_large.gd
+++ b/client/gui/menus/popup_large.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -23,3 +23,6 @@ func _ready():
func _on_back_pressed():
exit()
+
+func _on_text_meta_clicked(meta: Variant) -> void:
+ OS.shell_open(str(meta))
diff --git a/client/gui/menus/popup_large.tscn b/client/gui/menus/popup_large.tscn
index bcbafe1b..4bf5109e 100644
--- a/client/gui/menus/popup_large.tscn
+++ b/client/gui/menus/popup_large.tscn
@@ -1,24 +1,22 @@
-[gd_scene load_steps=7 format=3 uid="uid://7mqbxa054bjv"]
+[gd_scene 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="PopupLarge" type="Control"]
+[node name="PopupLarge" type="Control" unique_id=958921744]
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="."]
+[node name="OuterMargin" type="MarginContainer" parent="." unique_id=296321292]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
@@ -27,12 +25,12 @@ grow_horizontal = 2
grow_vertical = 2
script = ExtResource("3_36vhf")
-[node name="Panel" type="Panel" parent="OuterMargin"]
+[node name="Panel" type="Panel" parent="OuterMargin" unique_id=751771892]
material = ExtResource("4_8ybj3")
layout_mode = 2
script = ExtResource("5_63jf0")
-[node name="InnerMargin" type="MarginContainer" parent="OuterMargin/Panel"]
+[node name="InnerMargin" type="MarginContainer" parent="OuterMargin/Panel" unique_id=1609382166]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
@@ -44,31 +42,32 @@ 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"]
+[node name="Vert" type="VBoxContainer" parent="OuterMargin/Panel/InnerMargin" unique_id=798911037]
layout_mode = 2
-[node name="ScrollContainer" type="ScrollContainer" parent="OuterMargin/Panel/InnerMargin/Vert"]
+[node name="ScrollContainer" type="ScrollContainer" parent="OuterMargin/Panel/InnerMargin/Vert" unique_id=1639832367]
layout_mode = 2
size_flags_vertical = 3
script = ExtResource("6_smk7v")
-[node name="Text" type="RichTextLabel" parent="OuterMargin/Panel/InnerMargin/Vert/ScrollContainer"]
+[node name="Text" type="RichTextLabel" parent="OuterMargin/Panel/InnerMargin/Vert/ScrollContainer" unique_id=87487052]
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/normal_font_size = 22
+theme_override_font_sizes/bold_font_size = 22
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"]
+[node name="back" type="Button" parent="OuterMargin/Panel/InnerMargin/Vert" unique_id=323355152]
layout_mode = 2
text = "c.menu.back"
+[connection signal="meta_clicked" from="OuterMargin/Panel/InnerMargin/Vert/ScrollContainer/Text" to="." method="_on_text_meta_clicked"]
[connection signal="pressed" from="OuterMargin/Panel/InnerMargin/Vert/back" to="." method="_on_back_pressed"]
diff --git a/client/gui/menus/rating/rating.gd b/client/gui/menus/rating/rating.gd
index 023c1333..4d47637f 100644
--- a/client/gui/menus/rating/rating.gd
+++ b/client/gui/menus/rating/rating.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -35,10 +35,10 @@ func _process(_delta):
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")
+ 0: title.text = tr("c.score.stars.poor")
+ 1: title.text = tr("c.score.stars.acceptable")
+ 2: title.text = tr("c.score.stars.good")
+ 3: title.text = tr("c.score.stars.excellent")
subtitle.text = tr("c.score.points_par").format([points])
diff --git a/client/gui/menus/rating/rating.tscn b/client/gui/menus/rating/rating.tscn
index 062dcca2..4e54572c 100644
--- a/client/gui/menus/rating/rating.tscn
+++ b/client/gui/menus/rating/rating.tscn
@@ -1,8 +1,7 @@
-[gd_scene load_steps=12 format=3 uid="uid://buu3cdpigs8qq"]
+[gd_scene 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="Texture2D" uid="uid://b10goh4dsa3b0" path="res://map/effects/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"]
@@ -27,18 +26,17 @@ point_count = 2
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"]
+[node name="Rating" type="Control" unique_id=1594483139]
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="."]
+[node name="MarginContainer" type="MarginContainer" parent="." unique_id=1435310334]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
@@ -50,35 +48,35 @@ 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"]
+[node name="PanelContainer" type="PanelContainer" parent="MarginContainer" unique_id=1405558399]
material = ExtResource("4_hdurb")
layout_mode = 2
-[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/PanelContainer"]
+[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/PanelContainer" unique_id=1254262874]
layout_mode = 2
theme_override_constants/separation = 64
alignment = 1
-[node name="Text" type="VBoxContainer" parent="MarginContainer/PanelContainer/VBoxContainer"]
+[node name="Text" type="VBoxContainer" parent="MarginContainer/PanelContainer/VBoxContainer" unique_id=1793831024]
layout_mode = 2
-[node name="Title" type="Label" parent="MarginContainer/PanelContainer/VBoxContainer/Text"]
+[node name="Title" type="Label" parent="MarginContainer/PanelContainer/VBoxContainer/Text" unique_id=1695693158]
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"]
+[node name="Subtitle" type="Label" parent="MarginContainer/PanelContainer/VBoxContainer/Text" unique_id=100592740]
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"]
+[node name="Stars" type="HBoxContainer" parent="MarginContainer/PanelContainer/VBoxContainer" unique_id=800110825]
layout_mode = 2
alignment = 1
-[node name="Star1" type="TextureRect" parent="MarginContainer/PanelContainer/VBoxContainer/Stars"]
+[node name="Star1" type="TextureRect" parent="MarginContainer/PanelContainer/VBoxContainer/Stars" unique_id=968347719]
material = SubResource("ShaderMaterial_oi7xd")
custom_minimum_size = Vector2(128, 128)
layout_mode = 2
@@ -86,11 +84,11 @@ texture = ExtResource("1_7qv7r")
expand_mode = 1
stretch_mode = 5
-[node name="Sound" type="AudioStreamPlayer" parent="MarginContainer/PanelContainer/VBoxContainer/Stars/Star1"]
+[node name="Sound" type="AudioStreamPlayer" parent="MarginContainer/PanelContainer/VBoxContainer/Stars/Star1" unique_id=720864083]
stream = ExtResource("5_tutpj")
pitch_scale = 1.5
-[node name="Star2" type="TextureRect" parent="MarginContainer/PanelContainer/VBoxContainer/Stars"]
+[node name="Star2" type="TextureRect" parent="MarginContainer/PanelContainer/VBoxContainer/Stars" unique_id=1682444818]
material = SubResource("ShaderMaterial_ney6s")
custom_minimum_size = Vector2(128, 128)
layout_mode = 2
@@ -98,11 +96,11 @@ texture = ExtResource("1_7qv7r")
expand_mode = 1
stretch_mode = 5
-[node name="Sound" type="AudioStreamPlayer" parent="MarginContainer/PanelContainer/VBoxContainer/Stars/Star2"]
+[node name="Sound" type="AudioStreamPlayer" parent="MarginContainer/PanelContainer/VBoxContainer/Stars/Star2" unique_id=1243382756]
stream = ExtResource("5_tutpj")
pitch_scale = 1.65
-[node name="Star3" type="TextureRect" parent="MarginContainer/PanelContainer/VBoxContainer/Stars"]
+[node name="Star3" type="TextureRect" parent="MarginContainer/PanelContainer/VBoxContainer/Stars" unique_id=1083493921]
material = SubResource("ShaderMaterial_27tx1")
custom_minimum_size = Vector2(128, 128)
layout_mode = 2
@@ -110,32 +108,32 @@ texture = ExtResource("1_7qv7r")
expand_mode = 1
stretch_mode = 5
-[node name="Sound" type="AudioStreamPlayer" parent="MarginContainer/PanelContainer/VBoxContainer/Stars/Star3"]
+[node name="Sound" type="AudioStreamPlayer" parent="MarginContainer/PanelContainer/VBoxContainer/Stars/Star3" unique_id=914623751]
stream = ExtResource("5_tutpj")
pitch_scale = 1.9
-[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/PanelContainer/VBoxContainer"]
+[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/PanelContainer/VBoxContainer" unique_id=1069207568]
layout_mode = 2
theme_override_constants/separation = 64
alignment = 1
-[node name="Scoreboard" type="Button" parent="MarginContainer/PanelContainer/VBoxContainer/HBoxContainer"]
+[node name="Scoreboard" type="Button" parent="MarginContainer/PanelContainer/VBoxContainer/HBoxContainer" unique_id=1025430333]
layout_mode = 2
text = "c.menu.scoreboard.button"
-[node name="Close" type="Button" parent="MarginContainer/PanelContainer/VBoxContainer/HBoxContainer"]
+[node name="Close" type="Button" parent="MarginContainer/PanelContainer/VBoxContainer/HBoxContainer" unique_id=268757521]
layout_mode = 2
text = "c.menu.accept"
-[node name="StarTimer" type="Timer" parent="."]
+[node name="StarTimer" type="Timer" parent="." unique_id=1015283419]
wait_time = 0.5
one_shot = true
-[node name="ButtonTimer" type="Timer" parent="."]
+[node name="ButtonTimer" type="Timer" parent="." unique_id=1816650084]
one_shot = true
autostart = true
-[node name="Control" type="Control" parent="."]
+[node name="Control" type="Control" parent="." unique_id=2091475568]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
@@ -145,7 +143,7 @@ anchor_bottom = 0.5
grow_horizontal = 2
grow_vertical = 2
-[node name="Particles" type="CPUParticles2D" parent="Control"]
+[node name="Particles" type="CPUParticles2D" parent="Control" unique_id=751600196]
emitting = false
amount = 32
texture = ExtResource("1_7qv7r")
diff --git a/client/gui/menus/scoreboard.gd b/client/gui/menus/scoreboard.gd
new file mode 100644
index 00000000..464705b5
--- /dev/null
+++ b/client/gui/menus/scoreboard.gd
@@ -0,0 +1,49 @@
+# Hurry Curry! - a game about cooking
+# Copyright (C) 2026 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 <https://www.gnu.org/licenses/>.
+#
+extends Menu
+
+@onready var table: GridContainer = $OuterMargin/Panel/InnerMargin/VBoxContainer/ScrollContainer/Table
+@onready var title: Label = $OuterMargin/Panel/InnerMargin/VBoxContainer/Title
+@onready var play_count: Label = $OuterMargin/Panel/InnerMargin/VBoxContainer/PlayCount
+
+@export var font: Font
+
+func _ready() -> void:
+ super()
+ var i = 1
+ title.text = tr("c.menu.scoreboard.title").format([data.map])
+ play_count.text = tr("c.menu.scoreboard.finish_count").format([int(data.plays)])
+ for entry in data.best:
+ var tt = ""
+ for key in entry.score:
+ tt += "%s: %d\n" % [tr("c.score.%s" % key), entry.score[key]]
+ print(tt)
+ push_label("%d." % i, tt)
+ push_label("%d" % entry.score.points, tt)
+ push_label(", ".join(entry.players), tt)
+ i += 1
+
+func push_label(text: String, tooltip: String):
+ var label = Label.new()
+ label.add_theme_font_size_override("font_size", 21)
+ label.add_theme_font_override("font", font)
+ label.mouse_filter = Control.MOUSE_FILTER_STOP
+ label.text = text
+ label.tooltip_text = tooltip
+ table.add_child(label)
+
+func _on_back_pressed() -> void:
+ exit()
diff --git a/client/gui/menus/scoreboard.gd.uid b/client/gui/menus/scoreboard.gd.uid
new file mode 100644
index 00000000..53f2b288
--- /dev/null
+++ b/client/gui/menus/scoreboard.gd.uid
@@ -0,0 +1 @@
+uid://d3dd83ooacgmw
diff --git a/client/gui/menus/scoreboard.tscn b/client/gui/menus/scoreboard.tscn
new file mode 100644
index 00000000..c2b6a5d9
--- /dev/null
+++ b/client/gui/menus/scoreboard.tscn
@@ -0,0 +1,114 @@
+[gd_scene format=3 uid="uid://cgevgyr5out81"]
+
+[ext_resource type="Script" uid="uid://d3dd83ooacgmw" path="res://gui/menus/scoreboard.gd" id="1_8iwl3"]
+[ext_resource type="Script" uid="uid://byshs20og68tn" path="res://gui/components/smart_margin_container.gd" id="1_bfqap"]
+[ext_resource type="Material" uid="uid://beea1pc5nt67r" path="res://gui/resources/materials/dark_blur_material.tres" id="2_s6kc8"]
+[ext_resource type="Script" uid="uid://cmncjc06kadpe" path="res://gui/components/blur_setup.gd" id="3_8iwl3"]
+[ext_resource type="Script" uid="uid://bd7bylb2t2m0" path="res://gui/components/touch_scroll_container.gd" id="5_c3g22"]
+[ext_resource type="FontFile" uid="uid://5ixo6b3bd3km" path="res://gui/resources/fonts/font-josefin-sans.woff2" id="6_b3vhr"]
+[ext_resource type="FontVariation" uid="uid://cl6m4hqsnrpav" path="res://gui/resources/fonts/sansita-swashed-bold.tres" id="7_tlf07"]
+
+[sub_resource type="Theme" id="Theme_grptf"]
+
+[sub_resource type="FontVariation" id="FontVariation_t5x0r"]
+base_font = ExtResource("7_tlf07")
+variation_opentype = {
+2003265652: 800
+}
+
+[sub_resource type="FontVariation" id="FontVariation_tlf07"]
+base_font = ExtResource("6_b3vhr")
+variation_opentype = {
+2003265652: 700
+}
+
+[node name="Scoreboard" type="Control" unique_id=510306535]
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+theme = SubResource("Theme_grptf")
+script = ExtResource("1_8iwl3")
+support_anim = false
+
+[node name="OuterMargin" type="MarginContainer" parent="." unique_id=869412596]
+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
+script = ExtResource("1_bfqap")
+
+[node name="Panel" type="Panel" parent="OuterMargin" unique_id=1557970649]
+material = ExtResource("2_s6kc8")
+layout_mode = 2
+script = ExtResource("3_8iwl3")
+
+[node name="InnerMargin" type="MarginContainer" parent="OuterMargin/Panel" unique_id=2023236197]
+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="VBoxContainer" type="VBoxContainer" parent="OuterMargin/Panel/InnerMargin" unique_id=2137087020]
+layout_mode = 2
+size_flags_horizontal = 3
+
+[node name="Title" type="Label" parent="OuterMargin/Panel/InnerMargin/VBoxContainer" unique_id=1471975030]
+layout_mode = 2
+theme_override_fonts/font = SubResource("FontVariation_t5x0r")
+theme_override_font_sizes/font_size = 48
+text = "Scoreboard for placeholder"
+horizontal_alignment = 1
+
+[node name="PlayCount" type="Label" parent="OuterMargin/Panel/InnerMargin/VBoxContainer" unique_id=1041103739]
+layout_mode = 2
+text = "123 games were played on this map"
+horizontal_alignment = 1
+
+[node name="ScrollContainer" type="ScrollContainer" parent="OuterMargin/Panel/InnerMargin/VBoxContainer" unique_id=394287120]
+layout_mode = 2
+size_flags_vertical = 3
+script = ExtResource("5_c3g22")
+
+[node name="Table" type="GridContainer" parent="OuterMargin/Panel/InnerMargin/VBoxContainer/ScrollContainer" unique_id=1680462103]
+layout_mode = 2
+columns = 3
+
+[node name="Rank" type="Label" parent="OuterMargin/Panel/InnerMargin/VBoxContainer/ScrollContainer/Table" unique_id=1490761538]
+layout_mode = 2
+theme_override_fonts/font = SubResource("FontVariation_tlf07")
+theme_override_font_sizes/font_size = 21
+text = "c.menu.scoreboard.rank"
+
+[node name="Points" type="Label" parent="OuterMargin/Panel/InnerMargin/VBoxContainer/ScrollContainer/Table" unique_id=1705556425]
+layout_mode = 2
+theme_override_fonts/font = SubResource("FontVariation_tlf07")
+theme_override_font_sizes/font_size = 21
+text = "c.score.points"
+
+[node name="Players" type="Label" parent="OuterMargin/Panel/InnerMargin/VBoxContainer/ScrollContainer/Table" unique_id=118623876]
+layout_mode = 2
+size_flags_horizontal = 3
+theme_override_fonts/font = SubResource("FontVariation_tlf07")
+theme_override_font_sizes/font_size = 21
+text = "c.menu.scoreboard.players"
+
+[node name="Back" type="Button" parent="OuterMargin/Panel/InnerMargin/VBoxContainer" unique_id=859010245]
+layout_mode = 2
+text = "c.menu.back"
+
+[connection signal="pressed" from="OuterMargin/Panel/InnerMargin/VBoxContainer/Back" to="." method="_on_back_pressed"]
diff --git a/client/gui/menus/screen_info.tscn b/client/gui/menus/screen_info.tscn
new file mode 100644
index 00000000..c05598d9
--- /dev/null
+++ b/client/gui/menus/screen_info.tscn
@@ -0,0 +1,62 @@
+[gd_scene format=3 uid="uid://dgtdfctc0x78v"]
+
+[ext_resource type="Shader" uid="uid://b7p7umdb51hhn" path="res://gui/resources/shaders/clouds_canvas_item.gdshader" id="1_ogbng"]
+
+[sub_resource type="FastNoiseLite" id="FastNoiseLite_ogbng"]
+frequency = 0.004
+
+[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_07dxw"]
+width = 834
+height = 480
+generate_mipmaps = false
+noise = SubResource("FastNoiseLite_ogbng")
+seamless = true
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_86n4b"]
+shader = ExtResource("1_ogbng")
+shader_parameter/noise = SubResource("NoiseTexture2D_07dxw")
+shader_parameter/ccloud = Color(0.63119745, 0.6848105, 0.72822344, 1)
+shader_parameter/csky = Color(0.2257854, 0.2183806, 0.60477614, 1)
+
+[node name="ScreenInfo" type="Control" unique_id=1334476146]
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+
+[node name="ColorRect" type="ColorRect" parent="." unique_id=642803588]
+material = SubResource("ShaderMaterial_86n4b")
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+
+[node name="MarginContainer" type="MarginContainer" parent="." unique_id=2116706251]
+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 = 64
+theme_override_constants/margin_top = 64
+theme_override_constants/margin_right = 64
+theme_override_constants/margin_bottom = 64
+
+[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer" unique_id=1504875155]
+layout_mode = 2
+
+[node name="RichTextLabel" type="RichTextLabel" parent="MarginContainer/VBoxContainer" unique_id=489259053]
+layout_mode = 2
+size_flags_vertical = 3
+bbcode_enabled = true
+text = "[font_size=48][b]Example server[/b]
+
+This is an example motd. Enjoy![/font_size]"
+fit_content = true
+horizontal_alignment = 1
+vertical_alignment = 1
diff --git a/client/gui/menus/settings/button_setting.gd b/client/gui/menus/settings/button_setting.gd
index e8a2ab42..6d7f9f2f 100644
--- a/client/gui/menus/settings/button_setting.gd
+++ b/client/gui/menus/settings/button_setting.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/gui/menus/settings/dropdown_setting.gd b/client/gui/menus/settings/dropdown_setting.gd
index bf4c3d48..dce4e4b3 100644
--- a/client/gui/menus/settings/dropdown_setting.gd
+++ b/client/gui/menus/settings/dropdown_setting.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -17,17 +17,20 @@ class_name DropdownSetting
extends GameSetting
var options: Array
+var tooltips: Array
-func _init(new_id: String, new_default, new_options: Array):
+func _init(new_id: String, new_default, new_options: Array, new_tooltips = null):
super(new_id, new_default)
options = new_options
+ tooltips = new_tooltips if new_tooltips else []
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, "preview",
+ for k in options: row.value_node.add_item(tr(nskey + "." + k))
+ for i in range(tooltips.size()): row.value_node.set_item_tooltip(i, tooltips[i])
+ Settings.hook_changed_init(key, row.value_node,
func(value):
if is_instance_valid(row):
row.value_node.select(options.find(value))
diff --git a/client/gui/menus/settings/game_setting.gd b/client/gui/menus/settings/game_setting.gd
index d0b38b34..e9be3f45 100644
--- a/client/gui/menus/settings/game_setting.gd
+++ b/client/gui/menus/settings/game_setting.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -35,7 +35,7 @@ func create_row():
if hide_reset(): row.hide_reset = true
else:
row.reset.connect(func(): Settings.write(key, default))
- Settings.hook_changed_init(key, "preview_reset", func (_value):
+ Settings.hook_changed_init(key, row, func (_value):
if is_instance_valid(row): row.set_reset_disabled(is_default())
)
return row
diff --git a/client/gui/menus/settings/input/input_manager.gd b/client/gui/menus/settings/input/input_manager.gd
index b0b80a39..6700029a 100644
--- a/client/gui/menus/settings/input/input_manager.gd
+++ b/client/gui/menus/settings/input/input_manager.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -25,7 +25,7 @@ enum EventType {
func action_list() -> Array: # Array[String]
return InputMap.get_actions().filter(func isBuiltIn(k: String): return !k.begins_with("ui_")).map(func (x): return str(x))
-func update_input_map(action: String):
+func update_input_map(_value, action: String):
if not action in action_list(): return
InputMap.action_erase_events(action)
for event in Settings.read("input.%s" % action):
diff --git a/client/gui/menus/settings/input/input_setting.gd b/client/gui/menus/settings/input/input_setting.gd
index 2fb4af3d..e689cbf2 100644
--- a/client/gui/menus/settings/input/input_setting.gd
+++ b/client/gui/menus/settings/input/input_setting.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -27,7 +27,7 @@ func create_row():
row.value_node = INPUT_VALUE_NODE_SCENE.instantiate()
# Manual initial update without update() since that needs to wait for _ready
row.value_node.value = Settings.read(key)
- Settings.hook_changed(key, "preview",
+ Settings.hook_changed(key, row.value_node,
func(value):
if is_instance_valid(row):
row.value_node.value = value
diff --git a/client/gui/menus/settings/input/input_value_node.gd b/client/gui/menus/settings/input/input_value_node.gd
index fe5768cf..6034d7cc 100644
--- a/client/gui/menus/settings/input/input_value_node.gd
+++ b/client/gui/menus/settings/input/input_value_node.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/gui/menus/settings/input/input_value_node.tscn b/client/gui/menus/settings/input/input_value_node.tscn
index 1b2e89c4..11997d6d 100644
--- a/client/gui/menus/settings/input/input_value_node.tscn
+++ b/client/gui/menus/settings/input/input_value_node.tscn
@@ -1,19 +1,19 @@
-[gd_scene load_steps=3 format=3 uid="uid://c6r0nv5daq7wc"]
+[gd_scene 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"]
+[node name="InputValueNode" type="VBoxContainer" unique_id=533450939]
offset_right = 128.0
offset_bottom = 31.0
theme_override_constants/separation = 0
script = ExtResource("1_snxax")
-[node name="ActionsContainer" type="VBoxContainer" parent="."]
+[node name="ActionsContainer" type="VBoxContainer" parent="." unique_id=1714871417]
layout_mode = 2
theme_override_constants/separation = 0
-[node name="Add" type="Button" parent="."]
+[node name="Add" type="Button" parent="." unique_id=1977567965]
custom_minimum_size = Vector2(128, 0)
layout_mode = 2
size_flags_vertical = 3
diff --git a/client/gui/menus/settings/number_setting.gd b/client/gui/menus/settings/number_setting.gd
index 48dd0a82..85f3f363 100644
--- a/client/gui/menus/settings/number_setting.gd
+++ b/client/gui/menus/settings/number_setting.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -32,7 +32,7 @@ func create_row():
input.max_value = max_value
input.value_changed.connect(func(value): Settings.write(key, value as int))
- Settings.hook_changed_init(key, "preview",
+ Settings.hook_changed_init(key, input,
func(v):
if is_instance_valid(input):
input.value = v
diff --git a/client/gui/menus/settings/path_setting.gd b/client/gui/menus/settings/path_setting.gd
index 37492ed7..81d79777 100644
--- a/client/gui/menus/settings/path_setting.gd
+++ b/client/gui/menus/settings/path_setting.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/gui/menus/settings/preset_row.gd b/client/gui/menus/settings/preset_row.gd
index ad878d00..5b83a9a2 100644
--- a/client/gui/menus/settings/preset_row.gd
+++ b/client/gui/menus/settings/preset_row.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/gui/menus/settings/range_setting.gd b/client/gui/menus/settings/range_setting.gd
index 2d7e88b4..c400aa2c 100644
--- a/client/gui/menus/settings/range_setting.gd
+++ b/client/gui/menus/settings/range_setting.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -35,7 +35,7 @@ func create_row():
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, "preview",
+ Settings.hook_changed_init(key, row.value_node,
func(value):
if is_instance_valid(row):
row.value_node.value = value
diff --git a/client/gui/menus/settings/settings.gd b/client/gui/menus/settings/settings.gd
index 7523b9fb..1099ba1d 100644
--- a/client/gui/menus/settings/settings.gd
+++ b/client/gui/menus/settings/settings.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -35,6 +35,6 @@ func _process(_dt):
func _on_back_pressed():
exit()
-func exit():
+func exit(exit_data = null):
Settings.save()
- super()
+ super(exit_data)
diff --git a/client/gui/menus/settings/settings.tscn b/client/gui/menus/settings/settings.tscn
index 71549464..c9cc4a26 100644
--- a/client/gui/menus/settings/settings.tscn
+++ b/client/gui/menus/settings/settings.tscn
@@ -1,23 +1,21 @@
-[gd_scene load_steps=6 format=3 uid="uid://8ic77jmadadj"]
+[gd_scene 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"]
+[node name="SettingsMenu" type="Control" unique_id=47869629]
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="."]
+[node name="OuterGap" type="MarginContainer" parent="." unique_id=116100814]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
@@ -27,12 +25,12 @@ grow_vertical = 2
theme_override_constants/margin_left = 80
script = ExtResource("3_h533i")
-[node name="Panel" type="Panel" parent="OuterGap"]
+[node name="Panel" type="Panel" parent="OuterGap" unique_id=686950833]
material = ExtResource("4_b0x33")
layout_mode = 2
script = ExtResource("5_dvivs")
-[node name="InnerGap" type="MarginContainer" parent="OuterGap/Panel"]
+[node name="InnerGap" type="MarginContainer" parent="OuterGap/Panel" unique_id=475296017]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
@@ -44,16 +42,16 @@ 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"]
+[node name="VBoxContainer" type="VBoxContainer" parent="OuterGap/Panel/InnerGap" unique_id=1596642785]
layout_mode = 2
-[node name="Title" type="Label" parent="OuterGap/Panel/InnerGap/VBoxContainer"]
+[node name="Title" type="Label" parent="OuterGap/Panel/InnerGap/VBoxContainer" unique_id=1055890814]
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"]
+[node name="Back" type="Button" parent="OuterGap/Panel/InnerGap/VBoxContainer" unique_id=285069063]
layout_mode = 2
size_flags_vertical = 8
text = "c.settings.apply"
diff --git a/client/gui/menus/settings/settings_category.gd b/client/gui/menus/settings/settings_category.gd
index 28a0e75b..3801b4f1 100644
--- a/client/gui/menus/settings/settings_category.gd
+++ b/client/gui/menus/settings/settings_category.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/gui/menus/settings/settings_root.gd b/client/gui/menus/settings/settings_root.gd
index 3f7fc027..972cc1f6 100644
--- a/client/gui/menus/settings/settings_root.gd
+++ b/client/gui/menus/settings/settings_root.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/gui/menus/settings/settings_row.gd b/client/gui/menus/settings/settings_row.gd
index 15555eb0..4003ab5f 100644
--- a/client/gui/menus/settings/settings_row.gd
+++ b/client/gui/menus/settings/settings_row.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/gui/menus/settings/settings_row.tscn b/client/gui/menus/settings/settings_row.tscn
index 09378ab6..f72ca0f5 100644
--- a/client/gui/menus/settings/settings_row.tscn
+++ b/client/gui/menus/settings/settings_row.tscn
@@ -1,6 +1,6 @@
-[gd_scene load_steps=7 format=3 uid="uid://o5e5vpem8w0k"]
+[gd_scene 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="StyleBox" uid="uid://d1xhwgrptnlli" path="res://gui/resources/style/panel_button_backround_style.tres" id="1_ik3io"]
[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"]
@@ -11,27 +11,27 @@ content_margin_left = 16.0
[sub_resource type="FontVariation" id="FontVariation_o6i7s"]
base_font = ExtResource("3_7k5da")
-[node name="SettingsRow" type="PanelContainer"]
+[node name="SettingsRow" type="PanelContainer" unique_id=1948353988]
offset_right = 105.0
offset_bottom = 23.0
size_flags_horizontal = 3
-theme = ExtResource("1_iij3k")
+theme_override_styles/panel = ExtResource("1_ik3io")
script = ExtResource("2_l8i7p")
-[node name="HBoxContainer" type="HBoxContainer" parent="."]
+[node name="HBoxContainer" type="HBoxContainer" parent="." unique_id=523957987]
layout_mode = 2
-[node name="Label" type="Label" parent="HBoxContainer"]
+[node name="Label" type="Label" parent="HBoxContainer" unique_id=1327916149]
layout_mode = 2
size_flags_horizontal = 3
theme_override_styles/normal = SubResource("StyleBoxEmpty_pk3rs")
-[node name="BoxContainer" type="BoxContainer" parent="HBoxContainer"]
+[node name="BoxContainer" type="BoxContainer" parent="HBoxContainer" unique_id=926679424]
custom_minimum_size = Vector2(300, 50)
layout_mode = 2
alignment = 2
-[node name="Reset" type="Button" parent="HBoxContainer"]
+[node name="Reset" type="Button" parent="HBoxContainer" unique_id=1056996279]
layout_mode = 2
theme_override_fonts/font = SubResource("FontVariation_o6i7s")
theme_override_font_sizes/font_size = 24
diff --git a/client/gui/menus/settings/text_setting.gd b/client/gui/menus/settings/text_setting.gd
index de0ef218..1be2bbc1 100644
--- a/client/gui/menus/settings/text_setting.gd
+++ b/client/gui/menus/settings/text_setting.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -27,7 +27,7 @@ func create_row():
var input := LineEdit.new()
input.placeholder_text = placeholder
input.text_changed.connect(func(text): Settings.write(key, text))
- Settings.hook_changed_init(key, "preview",
+ Settings.hook_changed_init(key, input,
func(text):
if is_instance_valid(input):
var pos = input.caret_column
diff --git a/client/gui/menus/settings/toggle_setting.gd b/client/gui/menus/settings/toggle_setting.gd
index fa60ca74..b0dbd352 100644
--- a/client/gui/menus/settings/toggle_setting.gd
+++ b/client/gui/menus/settings/toggle_setting.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -23,7 +23,7 @@ func create_row():
var row = super()
row.value_node = CheckButton.new()
row.value_node.pressed.connect(func(): Settings.write(key, row.value_node.button_pressed))
- Settings.hook_changed_init(key, "preview",
+ Settings.hook_changed_init(key, row.value_node,
func(value):
if is_instance_valid(row):
row.value_node.button_pressed = value
diff --git a/client/gui/menus/setup/hairstyle_preview.gd b/client/gui/menus/setup/hairstyle_preview.gd
index eee3a9f2..7f85f03a 100644
--- a/client/gui/menus/setup/hairstyle_preview.gd
+++ b/client/gui/menus/setup/hairstyle_preview.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/gui/menus/setup/hairstyle_preview.tscn b/client/gui/menus/setup/hairstyle_preview.tscn
index ee4a65e9..81fe79b7 100644
--- a/client/gui/menus/setup/hairstyle_preview.tscn
+++ b/client/gui/menus/setup/hairstyle_preview.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=7 format=3 uid="uid://dfon56nwd2tgn"]
+[gd_scene 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"]
@@ -12,44 +12,44 @@ viewport_path = NodePath("HairViewport")
[sub_resource type="ButtonGroup" id="ButtonGroup_c5p7t"]
-[node name="HairstylePreview" type="VBoxContainer"]
+[node name="HairstylePreview" type="VBoxContainer" unique_id=528079266]
offset_right = 40.0
offset_bottom = 40.0
script = ExtResource("1_0qdmv")
-[node name="Preview" type="TextureRect" parent="."]
+[node name="Preview" type="TextureRect" parent="." unique_id=533401392]
material = SubResource("ShaderMaterial_entrs")
layout_mode = 2
texture = SubResource("ViewportTexture_giuq2")
-[node name="Select" type="CheckBox" parent="."]
+[node name="Select" type="CheckBox" parent="." unique_id=1919288280]
layout_mode = 2
button_group = SubResource("ButtonGroup_c5p7t")
text = "Hairstyle 1"
-[node name="HairViewport" type="SubViewport" parent="."]
+[node name="HairViewport" type="SubViewport" parent="." unique_id=1740411305]
own_world_3d = true
transparent_bg = true
msaa_3d = 1
size = Vector2i(128, 128)
-[node name="Node3D" type="Node3D" parent="HairViewport"]
+[node name="Node3D" type="Node3D" parent="HairViewport" unique_id=880401079]
-[node name="Camera3D" type="Camera3D" parent="HairViewport/Node3D"]
+[node name="Camera3D" type="Camera3D" parent="HairViewport/Node3D" unique_id=1793031655]
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="Character" parent="HairViewport/Node3D" unique_id=186667018 instance=ExtResource("2_jtitc")]
-[node name="SpotLight3D" type="SpotLight3D" parent="HairViewport/Node3D"]
+[node name="SpotLight3D" type="SpotLight3D" parent="HairViewport/Node3D" unique_id=1171647836]
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"]
+[node name="SpotLight3D2" type="SpotLight3D" parent="HairViewport/Node3D" unique_id=2048802047]
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"]
+[node name="SpotLight3D3" type="SpotLight3D" parent="HairViewport/Node3D" unique_id=302072119]
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
index 36972870..bf970029 100644
--- a/client/gui/menus/setup/setup.gd
+++ b/client/gui/menus/setup/setup.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/gui/menus/setup/setup.tscn b/client/gui/menus/setup/setup.tscn
index 763a6676..9254e9d3 100644
--- a/client/gui/menus/setup/setup.tscn
+++ b/client/gui/menus/setup/setup.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=16 format=3 uid="uid://ddl3efikvqp66"]
+[gd_scene 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"]
@@ -63,7 +63,7 @@ corner_radius_bottom_left = 10
[sub_resource type="FontVariation" id="FontVariation_2cc7p"]
base_font = ExtResource("3_2vg4d")
-[node name="SetupMenu" type="Control"]
+[node name="SetupMenu" type="Control" unique_id=404427509]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
@@ -72,13 +72,11 @@ grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_mo46n")
-[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
-libraries = {
-&"": SubResource("AnimationLibrary_wjgak")
-}
+[node name="AnimationPlayer" type="AnimationPlayer" parent="." unique_id=801678418]
+libraries/ = SubResource("AnimationLibrary_wjgak")
speed_scale = 2.0
-[node name="ScrollContainer" type="ScrollContainer" parent="."]
+[node name="ScrollContainer" type="ScrollContainer" parent="." unique_id=453732115]
clip_contents = false
layout_mode = 1
anchors_preset = 15
@@ -90,13 +88,13 @@ follow_focus = true
horizontal_scroll_mode = 0
script = ExtResource("2_4caf2")
-[node name="Control" type="Control" parent="ScrollContainer"]
+[node name="Control" type="Control" parent="ScrollContainer" unique_id=926239249]
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"]
+[node name="TextureRect" type="TextureRect" parent="ScrollContainer/Control" unique_id=193277072]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
@@ -113,7 +111,7 @@ rotation = 0.0174533
theme = ExtResource("1_yq0aa")
texture = SubResource("NoiseTexture2D_bvvl7")
-[node name="Hole1" type="Panel" parent="ScrollContainer/Control/TextureRect"]
+[node name="Hole1" type="Panel" parent="ScrollContainer/Control/TextureRect" unique_id=1669256894]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
@@ -128,7 +126,7 @@ grow_horizontal = 2
grow_vertical = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_e7xn5")
-[node name="Hole2" type="Panel" parent="ScrollContainer/Control/TextureRect"]
+[node name="Hole2" type="Panel" parent="ScrollContainer/Control/TextureRect" unique_id=1933964118]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
@@ -143,7 +141,7 @@ grow_horizontal = 2
grow_vertical = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_e7xn5")
-[node name="PaperMargin" type="MarginContainer" parent="ScrollContainer/Control/TextureRect"]
+[node name="PaperMargin" type="MarginContainer" parent="ScrollContainer/Control/TextureRect" unique_id=259726363]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
@@ -151,26 +149,26 @@ anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
-[node name="Contents" type="VBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin"]
+[node name="Contents" type="VBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin" unique_id=762897518]
layout_mode = 2
-[node name="Title" type="Label" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"]
+[node name="Title" type="Label" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents" unique_id=444263773]
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"]
+[node name="Sep" type="HSeparator" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents" unique_id=597860934]
layout_mode = 2
-[node name="Intro" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"]
+[node name="Intro" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents" unique_id=1526857931]
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"]
+[node name="Name" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents" unique_id=1957936520]
layout_mode = 2
bbcode_enabled = true
text = "c.setup.name"
@@ -178,19 +176,18 @@ fit_content = true
scroll_active = false
text_direction = 3
-[node name="NameEntry" type="HBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"]
+[node name="NameEntry" type="HBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents" unique_id=981353664]
layout_mode = 2
-tooltip_text = "c.setup.name.desc"
-[node name="LineEdit" type="LineEdit" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/NameEntry"]
+[node name="LineEdit" type="LineEdit" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/NameEntry" unique_id=656391196]
custom_minimum_size = Vector2(300, 30)
layout_mode = 2
max_length = 32
-[node name="Control" type="Control" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/NameEntry"]
+[node name="Control" type="Control" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/NameEntry" unique_id=1004452718]
layout_mode = 2
-[node name="Position" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"]
+[node name="Position" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents" unique_id=2100745661]
layout_mode = 2
bbcode_enabled = true
text = "c.setup.position"
@@ -198,17 +195,17 @@ fit_content = true
scroll_active = false
text_direction = 3
-[node name="PositionEntry" type="HBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"]
+[node name="PositionEntry" type="HBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents" unique_id=699954849]
layout_mode = 2
-[node name="LineEdit" type="LineEdit" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/PositionEntry"]
+[node name="LineEdit" type="LineEdit" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/PositionEntry" unique_id=1006902347]
custom_minimum_size = Vector2(300, 30)
layout_mode = 2
theme_override_colors/font_color = Color(0.458824, 0, 0, 1)
theme_override_colors/font_uneditable_color = Color(0.458824, 0, 0, 1)
editable = false
-[node name="LineEdit2" type="Label" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/PositionEntry/LineEdit"]
+[node name="LineEdit2" type="Label" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/PositionEntry/LineEdit" unique_id=931716188]
custom_minimum_size = Vector2(300, 30)
layout_mode = 1
offset_left = 9.97753
@@ -219,7 +216,7 @@ 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"]
+[node name="Uniform" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents" unique_id=134922495]
layout_mode = 2
bbcode_enabled = true
text = "c.setup.uniform"
@@ -227,11 +224,11 @@ fit_content = true
scroll_active = false
text_direction = 3
-[node name="SelectUniform" type="HBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"]
+[node name="SelectUniform" type="HBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents" unique_id=1348732855]
layout_mode = 2
alignment = 1
-[node name="Experience" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"]
+[node name="Experience" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents" unique_id=1585821122]
layout_mode = 2
bbcode_enabled = true
text = "c.setup.experience"
@@ -239,16 +236,16 @@ fit_content = true
scroll_active = false
text_direction = 3
-[node name="SelectExperience" type="HBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"]
+[node name="SelectExperience" type="HBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents" unique_id=1160761410]
layout_mode = 2
alignment = 1
-[node name="CheckBox" type="CheckBox" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/SelectExperience"]
+[node name="CheckBox" type="CheckBox" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/SelectExperience" unique_id=2127551975]
layout_mode = 2
text = "c.setup.experience.skip"
text_direction = 3
-[node name="Duties" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"]
+[node name="Duties" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents" unique_id=1120701239]
layout_mode = 2
bbcode_enabled = true
text = "c.setup.duties"
@@ -256,7 +253,7 @@ fit_content = true
scroll_active = false
text_direction = 3
-[node name="Terms" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"]
+[node name="Terms" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents" unique_id=2064820043]
layout_mode = 2
bbcode_enabled = true
text = "c.setup.additional_terms"
@@ -264,7 +261,7 @@ fit_content = true
scroll_active = false
text_direction = 3
-[node name="Compensation" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"]
+[node name="Compensation" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents" unique_id=395129177]
layout_mode = 2
bbcode_enabled = true
text = "c.setup.compensation"
@@ -272,14 +269,14 @@ fit_content = true
scroll_active = false
text_direction = 3
-[node name="CompensationEntry" type="HBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"]
+[node name="CompensationEntry" type="HBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents" unique_id=1052789456]
layout_mode = 2
-[node name="Spacer" type="Control" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/CompensationEntry"]
+[node name="Spacer" type="Control" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/CompensationEntry" unique_id=217082601]
custom_minimum_size = Vector2(15.045, 0)
layout_mode = 2
-[node name="Text1" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/CompensationEntry"]
+[node name="Text1" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/CompensationEntry" unique_id=1462759622]
custom_minimum_size = Vector2(100.08, 0)
layout_mode = 2
bbcode_enabled = true
@@ -288,13 +285,13 @@ fit_content = true
scroll_active = false
autowrap_mode = 0
-[node name="LineEdit" type="LineEdit" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/CompensationEntry"]
+[node name="LineEdit" type="LineEdit" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/CompensationEntry" unique_id=92292513]
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"]
+[node name="LineEdit2" type="Label" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/CompensationEntry/LineEdit" unique_id=1393543854]
custom_minimum_size = Vector2(50, 30)
layout_mode = 1
offset_left = 9.55965
@@ -305,27 +302,27 @@ 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"]
+[node name="Text2" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/CompensationEntry" unique_id=1170626801]
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"]
+[node name="Spacer" type="Control" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents" unique_id=1081095665]
custom_minimum_size = Vector2(0, 200)
layout_mode = 2
-[node name="Signatures" type="HBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"]
+[node name="Signatures" type="HBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents" unique_id=1621874485]
layout_mode = 2
-[node name="EmployerMargin" type="MarginContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures"]
+[node name="EmployerMargin" type="MarginContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures" unique_id=1739540174]
layout_mode = 2
-[node name="Sign" type="VBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployerMargin"]
+[node name="Sign" type="VBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployerMargin" unique_id=1040025870]
layout_mode = 2
-[node name="Desc" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployerMargin/Sign"]
+[node name="Desc" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployerMargin/Sign" unique_id=531586924]
layout_mode = 2
theme_override_font_sizes/normal_font_size = 15
bbcode_enabled = true
@@ -334,7 +331,7 @@ fit_content = true
scroll_active = false
text_direction = 3
-[node name="Signature" type="Label" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployerMargin/Sign"]
+[node name="Signature" type="Label" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployerMargin/Sign" unique_id=883266746]
custom_minimum_size = Vector2(200, 80)
layout_mode = 2
theme_override_colors/font_color = Color(0.415686, 0.0253044, 0.135441, 1)
@@ -344,16 +341,16 @@ 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"]
+[node name="Underline" type="HSeparator" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployerMargin/Sign" unique_id=1504477549]
layout_mode = 2
-[node name="EmployeeMargin" type="MarginContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures"]
+[node name="EmployeeMargin" type="MarginContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures" unique_id=669831450]
layout_mode = 2
-[node name="Sign" type="VBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployeeMargin"]
+[node name="Sign" type="VBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployeeMargin" unique_id=2121728827]
layout_mode = 2
-[node name="Desc" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployeeMargin/Sign"]
+[node name="Desc" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployeeMargin/Sign" unique_id=20375357]
layout_mode = 2
theme_override_font_sizes/normal_font_size = 15
bbcode_enabled = true
@@ -362,41 +359,41 @@ 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"]]
+[node name="Signature" type="Button" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployeeMargin/Sign" unique_id=237647876 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"]
+[node name="Underline" type="HSeparator" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployeeMargin/Sign" unique_id=1899750452]
layout_mode = 2
-[node name="Back" type="Button" parent="."]
+[node name="Back" type="Button" parent="." unique_id=529132579]
layout_mode = 1
offset_right = 106.0
offset_bottom = 31.0
text = "c.menu.back"
-[node name="Page" type="AudioStreamPlayer" parent="."]
+[node name="Page" type="AudioStreamPlayer" parent="." unique_id=1328578081]
stream = ExtResource("5_xac6d")
volume_db = -16.0
autoplay = true
-[node name="Sign" type="AudioStreamPlayer" parent="."]
+[node name="Sign" type="AudioStreamPlayer" parent="." unique_id=83399550]
stream = ExtResource("6_wf0gh")
volume_db = -16.0
-[node name="Background" type="Node3D" parent="."]
+[node name="Background" type="Node3D" parent="." unique_id=2140117190]
-[node name="Camera3D" type="Camera3D" parent="Background"]
+[node name="Camera3D" type="Camera3D" parent="Background" unique_id=178945527]
transform = Transform3D(1, 0, 0, 0, 0.9781476, 0.2079117, 0, -0.2079117, 0.9781476, 0, 1.125, 2.75)
fov = 40.0
-[node name="OmniLight3D" type="OmniLight3D" parent="Background"]
+[node name="OmniLight3D" type="OmniLight3D" parent="Background" unique_id=848182505]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.9320438, 1.5322332, 4.4919252)
light_color = Color(0.91730624, 0.87936515, 0.8454916, 1)
omni_range = 16.873302
-[node name="KitchenBackground" parent="Background" instance=ExtResource("7_k81bu")]
+[node name="KitchenBackground" parent="Background" unique_id=506434831 instance=ExtResource("7_k81bu")]
transform = Transform3D(0.8660254, 0, 0.5, 0, 1, 0, -0.5, 0, 0.8660254, 0, 0, 0)
[connection signal="pressed" from="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployeeMargin/Sign/Signature" to="." method="_on_sign_pressed"]
diff --git a/client/gui/menus/transition/scene_transition.gd b/client/gui/menus/transition/scene_transition.gd
index 332647b5..ffb0c8c5 100644
--- a/client/gui/menus/transition/scene_transition.gd
+++ b/client/gui/menus/transition/scene_transition.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -30,6 +30,10 @@ func _ready():
$black.visible = true
text.visible = true
text.text = ""
+ Settings.hook_changed_init("ui.transition_speed", self, func(v):
+ black_anim.speed_scale = v
+ text_anim.speed_scale = v
+ )
func set_loading_text(s: String):
text.text = s
diff --git a/client/gui/menus/transition/scene_transition.tscn b/client/gui/menus/transition/scene_transition.tscn
index dab16084..f7a81183 100644
--- a/client/gui/menus/transition/scene_transition.tscn
+++ b/client/gui/menus/transition/scene_transition.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=11 format=3 uid="uid://bg2d78ycorcqk"]
+[gd_scene 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"]
@@ -81,7 +81,7 @@ shader = ExtResource("2_g21ck")
[sub_resource type="LabelSettings" id="LabelSettings_e6dcd"]
font_size = 34
-[node name="SceneTransition" type="Control"]
+[node name="SceneTransition" type="Control" unique_id=1141390469]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
@@ -90,13 +90,10 @@ 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_fader" type="AnimationPlayer" parent="." unique_id=209744426]
+libraries/ = SubResource("AnimationLibrary_00tv0")
-[node name="black" type="ColorRect" parent="."]
+[node name="black" type="ColorRect" parent="." unique_id=275752521]
visible = false
layout_mode = 1
anchors_preset = 15
@@ -107,13 +104,10 @@ 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_fader" type="AnimationPlayer" parent="." unique_id=1775963619]
+libraries/ = SubResource("AnimationLibrary_pea72")
-[node name="text_margin" type="MarginContainer" parent="."]
+[node name="text_margin" type="MarginContainer" parent="." unique_id=1336652601]
layout_mode = 1
anchors_preset = 2
anchor_top = 1.0
@@ -127,7 +121,7 @@ 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"]
+[node name="text" type="Label" parent="text_margin" unique_id=1553303999]
modulate = Color(1, 1, 1, 0)
material = SubResource("ShaderMaterial_00tv0")
layout_mode = 2
diff --git a/client/gui/overlays/announce_title.gd b/client/gui/overlays/announce_title.gd
index 66d5434b..b9e7c542 100644
--- a/client/gui/overlays/announce_title.gd
+++ b/client/gui/overlays/announce_title.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/gui/overlays/announce_title.tscn b/client/gui/overlays/announce_title.tscn
index 79ec11e8..b2e4dcc6 100644
--- a/client/gui/overlays/announce_title.tscn
+++ b/client/gui/overlays/announce_title.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=10 format=3 uid="uid://c7pykhpdhgs64"]
+[gd_scene format=3 uid="uid://c7pykhpdhgs64"]
[ext_resource type="Script" uid="uid://ci08whhm2ej1m" path="res://gui/overlays/announce_title.gd" id="1_6bcyw"]
[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://gui/resources/fonts/font-sansita-swashed.woff2" id="2_037n2"]
@@ -320,13 +320,13 @@ _data = {
&"fade_out_quick": SubResource("Animation_deqe4")
}
-[node name="AnnounceTitle" type="Control"]
+[node name="AnnounceTitle" type="Control" unique_id=343666759]
visible = false
layout_mode = 3
anchors_preset = 0
script = ExtResource("1_6bcyw")
-[node name="Center" type="Control" parent="."]
+[node name="Center" type="Control" parent="." unique_id=1028083340]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
@@ -336,11 +336,11 @@ anchor_bottom = 0.5
grow_horizontal = 2
grow_vertical = 2
-[node name="Node2D" type="Node2D" parent="Center"]
+[node name="Node2D" type="Node2D" parent="Center" unique_id=2095678670]
modulate = Color(1, 1, 1, 0)
scale = Vector2(1e-05, 1e-05)
-[node name="Label" type="Label" parent="Center/Node2D"]
+[node name="Label" type="Label" parent="Center/Node2D" unique_id=267605128]
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
@@ -361,14 +361,12 @@ text = "GO!"
horizontal_alignment = 1
vertical_alignment = 1
-[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
-libraries = {
-&"": SubResource("AnimationLibrary_deqe4")
-}
+[node name="AnimationPlayer" type="AnimationPlayer" parent="." unique_id=237178568]
+libraries/ = SubResource("AnimationLibrary_deqe4")
-[node name="PreperationTimer" type="Timer" parent="."]
+[node name="PreperationTimer" type="Timer" parent="." unique_id=806142906]
one_shot = true
-[node name="InitialDelay" type="Timer" parent="."]
+[node name="InitialDelay" type="Timer" parent="." unique_id=1150912956]
wait_time = 0.5
one_shot = true
diff --git a/client/gui/overlays/chat.gd b/client/gui/overlays/chat.gd
index 676337a6..a831cf2c 100644
--- a/client/gui/overlays/chat.gd
+++ b/client/gui/overlays/chat.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/gui/overlays/chat.tscn b/client/gui/overlays/chat.tscn
index 068d0ee4..b0bd9728 100644
--- a/client/gui/overlays/chat.tscn
+++ b/client/gui/overlays/chat.tscn
@@ -1,11 +1,10 @@
-[gd_scene load_steps=5 format=3 uid="uid://xcxbmynn8mhi"]
+[gd_scene 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/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"]
+[node name="ChatPreview" type="Control" unique_id=1086008487]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
@@ -13,27 +12,26 @@ 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
+[node name="MarginContainer" type="MarginContainer" parent="." unique_id=468015652]
+layout_mode = 0
anchor_bottom = 1.0
offset_right = 296.0
grow_vertical = 2
-[node name="ScrollContainer" type="ScrollContainer" parent="MarginContainer"]
+[node name="ScrollContainer" type="ScrollContainer" parent="MarginContainer" unique_id=1928434577]
layout_mode = 2
horizontal_scroll_mode = 0
-[node name="PanelContainer" type="PanelContainer" parent="MarginContainer/ScrollContainer"]
+[node name="PanelContainer" type="PanelContainer" parent="MarginContainer/ScrollContainer" unique_id=547642679]
material = ExtResource("3_15i2y")
layout_mode = 2
size_flags_horizontal = 3
-size_flags_vertical = 0
+size_flags_vertical = 10
mouse_filter = 2
script = ExtResource("4_3rmhr")
-[node name="Messages" type="VBoxContainer" parent="MarginContainer/ScrollContainer/PanelContainer"]
+[node name="Messages" type="VBoxContainer" parent="MarginContainer/ScrollContainer/PanelContainer" unique_id=76448729]
layout_mode = 2
mouse_filter = 2
diff --git a/client/gui/overlays/controls_visualization/controller/controller_explanation.gd b/client/gui/overlays/controls_visualization/controller/controller_explanation.gd
index 84e93cfa..cb1a876e 100644
--- a/client/gui/overlays/controls_visualization/controller/controller_explanation.gd
+++ b/client/gui/overlays/controls_visualization/controller/controller_explanation.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/gui/overlays/controls_visualization/controller/controller_explanation.tscn b/client/gui/overlays/controls_visualization/controller/controller_explanation.tscn
index 410f2592..dbe17ee3 100644
--- a/client/gui/overlays/controls_visualization/controller/controller_explanation.tscn
+++ b/client/gui/overlays/controls_visualization/controller/controller_explanation.tscn
@@ -1,11 +1,11 @@
-[gd_scene load_steps=5 format=3 uid="uid://ceex0cpjrb81p"]
+[gd_scene format=3 uid="uid://ceex0cpjrb81p"]
[ext_resource type="Script" uid="uid://dsg537e6dc68" path="res://gui/overlays/controls_visualization/controller/controller_explanation.gd" id="1_n0s1n"]
[ext_resource type="FontVariation" uid="uid://cl6m4hqsnrpav" path="res://gui/resources/fonts/sansita-swashed-bold.tres" id="2_ewgm4"]
[ext_resource type="Texture2D" uid="uid://cf8hrxilqe2ih" path="res://gui/overlays/controls_visualization/arrow.svg" id="3_565r1"]
[ext_resource type="Texture2D" uid="uid://doo07i13vtb34" path="res://gui/overlays/controls_visualization/controller/controller.svg" id="5_nalwd"]
-[node name="ControllerExplanation" type="Control"]
+[node name="ControllerExplanation" type="Control" unique_id=225005545]
custom_minimum_size = Vector2(0, 450)
layout_mode = 3
anchors_preset = 15
@@ -16,7 +16,7 @@ grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_n0s1n")
-[node name="Control" type="Control" parent="."]
+[node name="Control" type="Control" parent="." unique_id=612138847]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
@@ -26,40 +26,40 @@ anchor_bottom = 0.5
grow_horizontal = 2
grow_vertical = 2
-[node name="Node2D" type="Node2D" parent="Control"]
+[node name="Node2D" type="Node2D" parent="Control" unique_id=1382260045]
position = Vector2(0, 50)
-[node name="Controller" type="Sprite2D" parent="Control/Node2D"]
+[node name="Controller" type="Sprite2D" parent="Control/Node2D" unique_id=443484705]
scale = Vector2(0.4, 0.4)
texture = ExtResource("5_nalwd")
-[node name="Arrow" type="Sprite2D" parent="Control/Node2D"]
+[node name="Arrow" type="Sprite2D" parent="Control/Node2D" unique_id=2024226522]
position = Vector2(-250, -150)
rotation = 1.5707964
scale = Vector2(0.5, 0.5)
texture = ExtResource("3_565r1")
-[node name="Arrow4" type="Sprite2D" parent="Control/Node2D"]
+[node name="Arrow4" type="Sprite2D" parent="Control/Node2D" unique_id=366803430]
position = Vector2(45, -150)
scale = Vector2(0.5, -0.5)
texture = ExtResource("3_565r1")
-[node name="Arrow2" type="Sprite2D" parent="Control/Node2D"]
+[node name="Arrow2" type="Sprite2D" parent="Control/Node2D" unique_id=2011085377]
position = Vector2(260, -140)
rotation = 1.5707963
scale = Vector2(0.5, -0.5)
texture = ExtResource("3_565r1")
-[node name="Arrow3" type="Sprite2D" parent="Control/Node2D"]
+[node name="Arrow3" type="Sprite2D" parent="Control/Node2D" unique_id=1350514919]
position = Vector2(215, 20)
rotation = -1.5707964
scale = Vector2(0.5, 0.5)
texture = ExtResource("3_565r1")
-[node name="Move" type="Node2D" parent="Control/Node2D"]
+[node name="Move" type="Node2D" parent="Control/Node2D" unique_id=1101261466]
position = Vector2(-330, -175)
-[node name="Label" type="Label" parent="Control/Node2D/Move"]
+[node name="Label" type="Label" parent="Control/Node2D/Move" unique_id=1806122210]
anchors_preset = 6
anchor_left = 1.0
anchor_top = 0.5
@@ -75,10 +75,10 @@ theme_override_font_sizes/font_size = 40
text = "c.controls_explanation.move"
horizontal_alignment = 2
-[node name="Boost" type="Node2D" parent="Control/Node2D"]
+[node name="Boost" type="Node2D" parent="Control/Node2D" unique_id=1174801668]
position = Vector2(335, -165)
-[node name="Label" type="Label" parent="Control/Node2D/Boost"]
+[node name="Label" type="Label" parent="Control/Node2D/Boost" unique_id=372533033]
anchors_preset = 4
anchor_top = 0.5
anchor_bottom = 0.5
@@ -90,10 +90,10 @@ theme_override_fonts/font = ExtResource("2_ewgm4")
theme_override_font_sizes/font_size = 40
text = "c.controls_explanation.boost"
-[node name="InteractRight" type="Node2D" parent="Control/Node2D"]
+[node name="InteractRight" type="Node2D" parent="Control/Node2D" unique_id=629169846]
position = Vector2(290, 25)
-[node name="Label" type="Label" parent="Control/Node2D/InteractRight"]
+[node name="Label" type="Label" parent="Control/Node2D/InteractRight" unique_id=1237574916]
anchors_preset = 4
anchor_top = 0.5
anchor_bottom = 0.5
@@ -105,10 +105,10 @@ theme_override_fonts/font = ExtResource("2_ewgm4")
theme_override_font_sizes/font_size = 40
text = "c.controls_explanation.interact_right"
-[node name="InteractLeft" type="Node2D" parent="Control/Node2D"]
+[node name="InteractLeft" type="Node2D" parent="Control/Node2D" unique_id=1696365379]
position = Vector2(20, -250)
-[node name="Label" type="Label" parent="Control/Node2D/InteractLeft"]
+[node name="Label" type="Label" parent="Control/Node2D/InteractLeft" unique_id=558541274]
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
diff --git a/client/gui/overlays/controls_visualization/device_explanation.gd b/client/gui/overlays/controls_visualization/device_explanation.gd
index 7bfe2fb4..ae39c3b6 100644
--- a/client/gui/overlays/controls_visualization/device_explanation.gd
+++ b/client/gui/overlays/controls_visualization/device_explanation.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/gui/overlays/controls_visualization/explanation.gd b/client/gui/overlays/controls_visualization/explanation.gd
index 77147f1d..20d60dc5 100644
--- a/client/gui/overlays/controls_visualization/explanation.gd
+++ b/client/gui/overlays/controls_visualization/explanation.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -20,8 +20,6 @@ var profile_name: String
var using_joypad: bool
var two_handed: bool
-@onready var game: Game = $"../Game"
-
@onready var title: Label = $MarginContainer/PanelContainer/SmartMarginContainer/VBoxContainer/Title
@onready var keyboard_explanation: KeyboardExplanation = $MarginContainer/PanelContainer/SmartMarginContainer/VBoxContainer/KeyboardExplanation
@onready var controller_explanation: ControllerExplanation = $MarginContainer/PanelContainer/SmartMarginContainer/VBoxContainer/ControllerExplanation
@@ -39,6 +37,4 @@ func _ready():
super()
func _on_accept_pressed() -> void:
- Profile.write(profile_name, true)
- game.mp.send_ready()
exit()
diff --git a/client/gui/overlays/controls_visualization/explanation.tscn b/client/gui/overlays/controls_visualization/explanation.tscn
index e102fa85..87cfd024 100644
--- a/client/gui/overlays/controls_visualization/explanation.tscn
+++ b/client/gui/overlays/controls_visualization/explanation.tscn
@@ -1,6 +1,5 @@
-[gd_scene load_steps=8 format=3 uid="uid://c7g5gpiyofmu8"]
+[gd_scene format=3 uid="uid://c7g5gpiyofmu8"]
-[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_81hfk"]
[ext_resource type="Script" uid="uid://bs2xryd5vamjf" path="res://gui/overlays/controls_visualization/explanation.gd" id="2_lxysr"]
[ext_resource type="Script" uid="uid://byshs20og68tn" path="res://gui/components/smart_margin_container.gd" id="2_m528b"]
[ext_resource type="Material" uid="uid://beea1pc5nt67r" path="res://gui/resources/materials/dark_blur_material.tres" id="3_pomap"]
@@ -8,18 +7,17 @@
[ext_resource type="PackedScene" uid="uid://wwj1ow1f437s" path="res://gui/overlays/controls_visualization/keyboard/keyboard_explanation.tscn" id="5_v3ijr"]
[ext_resource type="PackedScene" uid="uid://ceex0cpjrb81p" path="res://gui/overlays/controls_visualization/controller/controller_explanation.tscn" id="7_yuxcv"]
-[node name="Explanation" type="Control"]
+[node name="Explanation" type="Control" unique_id=1844082160]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
-theme = ExtResource("1_81hfk")
script = ExtResource("2_lxysr")
support_anim = false
-[node name="MarginContainer" type="MarginContainer" parent="."]
+[node name="MarginContainer" type="MarginContainer" parent="." unique_id=1783444226]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
@@ -29,38 +27,38 @@ grow_vertical = 2
script = ExtResource("2_m528b")
metadata/_custom_type_script = "uid://byshs20og68tn"
-[node name="PanelContainer" type="PanelContainer" parent="MarginContainer"]
+[node name="PanelContainer" type="PanelContainer" parent="MarginContainer" unique_id=1011034861]
material = ExtResource("3_pomap")
layout_mode = 2
script = ExtResource("4_v3ijr")
-[node name="SmartMarginContainer" type="MarginContainer" parent="MarginContainer/PanelContainer"]
+[node name="SmartMarginContainer" type="MarginContainer" parent="MarginContainer/PanelContainer" unique_id=412197848]
layout_mode = 2
script = ExtResource("2_m528b")
metadata/_custom_type_script = "uid://byshs20og68tn"
-[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/PanelContainer/SmartMarginContainer"]
+[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/PanelContainer/SmartMarginContainer" unique_id=801432498]
layout_mode = 2
-[node name="Title" type="Label" parent="MarginContainer/PanelContainer/SmartMarginContainer/VBoxContainer"]
+[node name="Title" type="Label" parent="MarginContainer/PanelContainer/SmartMarginContainer/VBoxContainer" unique_id=1143098368]
layout_mode = 2
theme_override_font_sizes/font_size = 36
text = "c.settings.input"
horizontal_alignment = 1
-[node name="KeyboardExplanation" parent="MarginContainer/PanelContainer/SmartMarginContainer/VBoxContainer" instance=ExtResource("5_v3ijr")]
+[node name="KeyboardExplanation" parent="MarginContainer/PanelContainer/SmartMarginContainer/VBoxContainer" unique_id=1601826141 instance=ExtResource("5_v3ijr")]
visible = false
layout_mode = 2
-[node name="ControllerExplanation" parent="MarginContainer/PanelContainer/SmartMarginContainer/VBoxContainer" instance=ExtResource("7_yuxcv")]
+[node name="ControllerExplanation" parent="MarginContainer/PanelContainer/SmartMarginContainer/VBoxContainer" unique_id=2048880330 instance=ExtResource("7_yuxcv")]
visible = false
layout_mode = 2
-[node name="Spacer" type="Control" parent="MarginContainer/PanelContainer/SmartMarginContainer/VBoxContainer"]
+[node name="Spacer" type="Control" parent="MarginContainer/PanelContainer/SmartMarginContainer/VBoxContainer" unique_id=846502741]
layout_mode = 2
size_flags_vertical = 3
-[node name="Accept" type="Button" parent="MarginContainer/PanelContainer/SmartMarginContainer/VBoxContainer"]
+[node name="Accept" type="Button" parent="MarginContainer/PanelContainer/SmartMarginContainer/VBoxContainer" unique_id=1036973256]
layout_mode = 2
size_flags_horizontal = 4
text = "c.menu.accept"
diff --git a/client/gui/overlays/controls_visualization/keyboard/keyboard_button.tscn b/client/gui/overlays/controls_visualization/keyboard/keyboard_button.tscn
index e4462464..09f1eb04 100644
--- a/client/gui/overlays/controls_visualization/keyboard/keyboard_button.tscn
+++ b/client/gui/overlays/controls_visualization/keyboard/keyboard_button.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=2 format=3 uid="uid://dj7tqrgpdja42"]
+[gd_scene format=3 uid="uid://dj7tqrgpdja42"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ilwpo"]
content_margin_left = 5.0
@@ -17,7 +17,7 @@ corner_radius_bottom_right = 15
corner_radius_bottom_left = 15
shadow_size = 3
-[node name="KeyboardButton" type="Button"]
+[node name="KeyboardButton" type="Button" unique_id=744392589]
custom_minimum_size = Vector2(75, 75)
offset_right = 8.0
offset_bottom = 8.0
diff --git a/client/gui/overlays/controls_visualization/keyboard/keyboard_explanation.gd b/client/gui/overlays/controls_visualization/keyboard/keyboard_explanation.gd
index 5d6dfb42..eb536556 100644
--- a/client/gui/overlays/controls_visualization/keyboard/keyboard_explanation.gd
+++ b/client/gui/overlays/controls_visualization/keyboard/keyboard_explanation.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/gui/overlays/controls_visualization/keyboard/keyboard_explanation.tscn b/client/gui/overlays/controls_visualization/keyboard/keyboard_explanation.tscn
index 54001686..3c68c8fe 100644
--- a/client/gui/overlays/controls_visualization/keyboard/keyboard_explanation.tscn
+++ b/client/gui/overlays/controls_visualization/keyboard/keyboard_explanation.tscn
@@ -1,11 +1,11 @@
-[gd_scene load_steps=5 format=3 uid="uid://wwj1ow1f437s"]
+[gd_scene format=3 uid="uid://wwj1ow1f437s"]
[ext_resource type="Script" uid="uid://dekpmw0i03eyi" path="res://gui/overlays/controls_visualization/keyboard/keyboard_explanation.gd" id="1_ubxjd"]
[ext_resource type="PackedScene" uid="uid://dj7tqrgpdja42" path="res://gui/overlays/controls_visualization/keyboard/keyboard_button.tscn" id="2_8nrgi"]
[ext_resource type="FontVariation" uid="uid://cl6m4hqsnrpav" path="res://gui/resources/fonts/sansita-swashed-bold.tres" id="3_nvtkh"]
[ext_resource type="Texture2D" uid="uid://cf8hrxilqe2ih" path="res://gui/overlays/controls_visualization/arrow.svg" id="4_mjakv"]
-[node name="KeyboardExplanation" type="Control"]
+[node name="KeyboardExplanation" type="Control" unique_id=651660867]
custom_minimum_size = Vector2(0, 450)
layout_mode = 3
anchors_preset = 15
@@ -15,7 +15,7 @@ grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_ubxjd")
-[node name="VBoxContainer" type="HBoxContainer" parent="."]
+[node name="VBoxContainer" type="HBoxContainer" parent="." unique_id=484836512]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
@@ -23,17 +23,17 @@ anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
-[node name="Control" type="Control" parent="VBoxContainer"]
+[node name="Control" type="Control" parent="VBoxContainer" unique_id=1305117984]
custom_minimum_size = Vector2(400, 375)
layout_mode = 2
size_flags_vertical = 4
-[node name="WASD" type="Node2D" parent="VBoxContainer/Control"]
+[node name="WASD" type="Node2D" parent="VBoxContainer/Control" unique_id=1579800839]
-[node name="Node2D" type="Node2D" parent="VBoxContainer/Control/WASD"]
+[node name="Node2D" type="Node2D" parent="VBoxContainer/Control/WASD" unique_id=341970939]
position = Vector2(200, 100)
-[node name="KeyboardButton" parent="VBoxContainer/Control/WASD/Node2D" instance=ExtResource("2_8nrgi")]
+[node name="KeyboardButton" parent="VBoxContainer/Control/WASD/Node2D" unique_id=2048931801 instance=ExtResource("2_8nrgi")]
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
@@ -47,10 +47,10 @@ grow_horizontal = 2
grow_vertical = 2
text = "W"
-[node name="Node2D2" type="Node2D" parent="VBoxContainer/Control/WASD"]
+[node name="Node2D2" type="Node2D" parent="VBoxContainer/Control/WASD" unique_id=799400559]
position = Vector2(200, 175)
-[node name="KeyboardButton" parent="VBoxContainer/Control/WASD/Node2D2" instance=ExtResource("2_8nrgi")]
+[node name="KeyboardButton" parent="VBoxContainer/Control/WASD/Node2D2" unique_id=33904465 instance=ExtResource("2_8nrgi")]
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
@@ -64,10 +64,10 @@ grow_horizontal = 2
grow_vertical = 2
text = "S"
-[node name="Node2D3" type="Node2D" parent="VBoxContainer/Control/WASD"]
+[node name="Node2D3" type="Node2D" parent="VBoxContainer/Control/WASD" unique_id=217001624]
position = Vector2(125, 175)
-[node name="KeyboardButton" parent="VBoxContainer/Control/WASD/Node2D3" instance=ExtResource("2_8nrgi")]
+[node name="KeyboardButton" parent="VBoxContainer/Control/WASD/Node2D3" unique_id=98593509 instance=ExtResource("2_8nrgi")]
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
@@ -80,10 +80,10 @@ offset_bottom = 24.5
grow_horizontal = 2
grow_vertical = 2
-[node name="Node2D4" type="Node2D" parent="VBoxContainer/Control/WASD"]
+[node name="Node2D4" type="Node2D" parent="VBoxContainer/Control/WASD" unique_id=1178217426]
position = Vector2(275, 175)
-[node name="KeyboardButton" parent="VBoxContainer/Control/WASD/Node2D4" instance=ExtResource("2_8nrgi")]
+[node name="KeyboardButton" parent="VBoxContainer/Control/WASD/Node2D4" unique_id=670344825 instance=ExtResource("2_8nrgi")]
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
@@ -97,10 +97,10 @@ grow_horizontal = 2
grow_vertical = 2
text = "D"
-[node name="Node2D5" type="Node2D" parent="VBoxContainer/Control/WASD"]
+[node name="Node2D5" type="Node2D" parent="VBoxContainer/Control/WASD" unique_id=1418657218]
position = Vector2(200, 275)
-[node name="Label" type="Label" parent="VBoxContainer/Control/WASD/Node2D5"]
+[node name="Label" type="Label" parent="VBoxContainer/Control/WASD/Node2D5" unique_id=2144646890]
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
@@ -116,22 +116,22 @@ theme_override_fonts/font = ExtResource("3_nvtkh")
theme_override_font_sizes/font_size = 40
text = "c.controls_explanation.move"
-[node name="Spacer" type="Control" parent="VBoxContainer"]
+[node name="Spacer" type="Control" parent="VBoxContainer" unique_id=1026478006]
layout_mode = 2
size_flags_horizontal = 3
-[node name="Control2" type="Control" parent="VBoxContainer"]
+[node name="Control2" type="Control" parent="VBoxContainer" unique_id=1412018875]
custom_minimum_size = Vector2(750, 450)
layout_mode = 2
size_flags_vertical = 4
-[node name="JKL" type="Node2D" parent="VBoxContainer/Control2"]
+[node name="JKL" type="Node2D" parent="VBoxContainer/Control2" unique_id=1177184769]
position = Vector2(150, 0)
-[node name="K" type="Node2D" parent="VBoxContainer/Control2/JKL"]
+[node name="K" type="Node2D" parent="VBoxContainer/Control2/JKL" unique_id=774521440]
position = Vector2(200, 175)
-[node name="KeyboardButton" parent="VBoxContainer/Control2/JKL/K" instance=ExtResource("2_8nrgi")]
+[node name="KeyboardButton" parent="VBoxContainer/Control2/JKL/K" unique_id=1633407160 instance=ExtResource("2_8nrgi")]
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
@@ -145,10 +145,10 @@ grow_horizontal = 2
grow_vertical = 2
text = "K"
-[node name="J" type="Node2D" parent="VBoxContainer/Control2/JKL"]
+[node name="J" type="Node2D" parent="VBoxContainer/Control2/JKL" unique_id=1136751368]
position = Vector2(125, 175)
-[node name="KeyboardButton" parent="VBoxContainer/Control2/JKL/J" instance=ExtResource("2_8nrgi")]
+[node name="KeyboardButton" parent="VBoxContainer/Control2/JKL/J" unique_id=1132698164 instance=ExtResource("2_8nrgi")]
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
@@ -162,10 +162,10 @@ grow_horizontal = 2
grow_vertical = 2
text = "J"
-[node name="L" type="Node2D" parent="VBoxContainer/Control2/JKL"]
+[node name="L" type="Node2D" parent="VBoxContainer/Control2/JKL" unique_id=1442550083]
position = Vector2(275, 175)
-[node name="KeyboardButton" parent="VBoxContainer/Control2/JKL/L" instance=ExtResource("2_8nrgi")]
+[node name="KeyboardButton" parent="VBoxContainer/Control2/JKL/L" unique_id=1327035512 instance=ExtResource("2_8nrgi")]
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
@@ -179,10 +179,10 @@ grow_horizontal = 2
grow_vertical = 2
text = "L"
-[node name="LeftHand" type="Node2D" parent="VBoxContainer/Control2/JKL"]
+[node name="LeftHand" type="Node2D" parent="VBoxContainer/Control2/JKL" unique_id=1230277954]
position = Vector2(25, 375)
-[node name="Label" type="Label" parent="VBoxContainer/Control2/JKL/LeftHand"]
+[node name="Label" type="Label" parent="VBoxContainer/Control2/JKL/LeftHand" unique_id=228034435]
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
@@ -198,10 +198,10 @@ theme_override_fonts/font = ExtResource("3_nvtkh")
theme_override_font_sizes/font_size = 40
text = "c.controls_explanation.interact_left"
-[node name="RightHand" type="Node2D" parent="VBoxContainer/Control2/JKL"]
+[node name="RightHand" type="Node2D" parent="VBoxContainer/Control2/JKL" unique_id=359568535]
position = Vector2(375, 375)
-[node name="Label" type="Label" parent="VBoxContainer/Control2/JKL/RightHand"]
+[node name="Label" type="Label" parent="VBoxContainer/Control2/JKL/RightHand" unique_id=500510356]
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
@@ -217,10 +217,10 @@ theme_override_fonts/font = ExtResource("3_nvtkh")
theme_override_font_sizes/font_size = 40
text = "c.controls_explanation.interact_right"
-[node name="Boost" type="Node2D" parent="VBoxContainer/Control2/JKL"]
+[node name="Boost" type="Node2D" parent="VBoxContainer/Control2/JKL" unique_id=394841057]
position = Vector2(335, 65)
-[node name="Label" type="Label" parent="VBoxContainer/Control2/JKL/Boost"]
+[node name="Label" type="Label" parent="VBoxContainer/Control2/JKL/Boost" unique_id=2055301401]
anchors_preset = 4
anchor_top = 0.5
anchor_bottom = 0.5
@@ -232,17 +232,17 @@ theme_override_fonts/font = ExtResource("3_nvtkh")
theme_override_font_sizes/font_size = 40
text = "c.controls_explanation.boost"
-[node name="Sprite2D" type="Sprite2D" parent="VBoxContainer/Control2/JKL"]
+[node name="Sprite2D" type="Sprite2D" parent="VBoxContainer/Control2/JKL" unique_id=1855495404]
position = Vector2(50, 275)
scale = Vector2(0.5, 0.5)
texture = ExtResource("4_mjakv")
-[node name="Sprite2D2" type="Sprite2D" parent="VBoxContainer/Control2/JKL"]
+[node name="Sprite2D2" type="Sprite2D" parent="VBoxContainer/Control2/JKL" unique_id=770199290]
position = Vector2(350, 275)
scale = Vector2(-0.5, 0.5)
texture = ExtResource("4_mjakv")
-[node name="Sprite2D3" type="Sprite2D" parent="VBoxContainer/Control2/JKL"]
+[node name="Sprite2D3" type="Sprite2D" parent="VBoxContainer/Control2/JKL" unique_id=495337642]
position = Vector2(250, 90)
rotation = -1.5707964
scale = Vector2(-0.5, 0.5)
diff --git a/client/gui/overlays/debug/debug.gd b/client/gui/overlays/debug/debug.gd
index 3a37a1b7..51bd0a48 100644
--- a/client/gui/overlays/debug/debug.gd
+++ b/client/gui/overlays/debug/debug.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -16,7 +16,7 @@
extends RichTextLabel
func _ready():
- Settings.hook_changed_init("graphics.debug_info", "main", func (v):
+ Settings.hook_changed_init("graphics.debug_info", self, func (v):
visible = v
RenderingServer.viewport_set_measure_render_time(get_viewport().get_viewport_rid(), visible)
)
diff --git a/client/gui/overlays/debug/debug.tscn b/client/gui/overlays/debug/debug.tscn
index c794c161..0013f4ad 100644
--- a/client/gui/overlays/debug/debug.tscn
+++ b/client/gui/overlays/debug/debug.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=6 format=3 uid="uid://3lytexnfrub6"]
+[gd_scene format=3 uid="uid://3lytexnfrub6"]
[ext_resource type="Script" uid="uid://bpmdfuqjtwf5v" path="res://gui/overlays/debug/debug.gd" id="1_62otr"]
[ext_resource type="Script" uid="uid://byshs20og68tn" path="res://gui/components/smart_margin_container.gd" id="1_c21gy"]
@@ -11,7 +11,8 @@ variation_opentype = {
2003265652: 700
}
-[node name="SmartMarginContainer" type="MarginContainer"]
+[node name="SmartMarginContainer" type="MarginContainer" unique_id=207473556]
+z_index = 99
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
@@ -25,7 +26,7 @@ theme_override_constants/margin_bottom = 10
script = ExtResource("1_c21gy")
metadata/_custom_type_script = "uid://byshs20og68tn"
-[node name="Debug" type="RichTextLabel" parent="."]
+[node name="Debug" type="RichTextLabel" parent="." unique_id=599133286]
visible = false
layout_mode = 2
mouse_filter = 2
@@ -33,7 +34,7 @@ theme_override_colors/font_outline_color = Color(0, 0, 0, 1)
theme_override_constants/outline_size = 10
script = ExtResource("1_62otr")
-[node name="DebugPie" type="Control" parent="."]
+[node name="DebugPie" type="Control" parent="." unique_id=1967345075]
visible = false
layout_mode = 2
size_flags_horizontal = 8
diff --git a/client/gui/overlays/debug/debug_pie.gd b/client/gui/overlays/debug/debug_pie.gd
index 02201776..ce32c93a 100644
--- a/client/gui/overlays/debug/debug_pie.gd
+++ b/client/gui/overlays/debug/debug_pie.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/gui/overlays/debug/pie.tscn b/client/gui/overlays/debug/pie.tscn
index 69872d72..bb65703c 100644
--- a/client/gui/overlays/debug/pie.tscn
+++ b/client/gui/overlays/debug/pie.tscn
@@ -1,6 +1,6 @@
[gd_scene format=3 uid="uid://27qwbrf7mh7i"]
-[node name="DebugPie" type="Control"]
+[node name="DebugPie" type="Control" unique_id=12646477]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
diff --git a/client/gui/overlays/lobby/lobby.gd b/client/gui/overlays/lobby/lobby.gd
deleted file mode 100644
index 2b40cada..00000000
--- a/client/gui/overlays/lobby/lobby.gd
+++ /dev/null
@@ -1,181 +0,0 @@
-# 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 <https://www.gnu.org/licenses/>.
-#
-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" # TODO
-@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 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
-
-func _ready():
- game.update_players.connect(update_players)
- initialize()
- game.data_updated.connect(initialize)
- game.join_state_updated.connect(_update_visible)
- game.in_lobby_updated.connect(_update_visible)
- _update_visible(false)
- 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 _update_visible(_state: bool):
- visible = game.in_lobby and game.join_state == Game.JoinState.JOINED
-
-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
deleted file mode 100644
index b92e8681..00000000
--- a/client/gui/overlays/lobby/lobby.gd.uid
+++ /dev/null
@@ -1 +0,0 @@
-uid://bssjvsu44l0fn
diff --git a/client/gui/overlays/lobby/lobby.tscn b/client/gui/overlays/lobby/lobby.tscn
deleted file mode 100644
index 28959838..00000000
--- a/client/gui/overlays/lobby/lobby.tscn
+++ /dev/null
@@ -1,182 +0,0 @@
-[gd_scene load_steps=16 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="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_opentype = {
-2003265652: 700
-}
-
-[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="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/Start" to="." method="_on_start_pressed"]
diff --git a/client/gui/overlays/lobby/player.gd b/client/gui/overlays/lobby/player.gd
index 175d6341..5b2b50e4 100644
--- a/client/gui/overlays/lobby/player.gd
+++ b/client/gui/overlays/lobby/player.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/gui/overlays/lobby/player.tscn b/client/gui/overlays/lobby/player.tscn
index aa8997a1..4c924fb9 100644
--- a/client/gui/overlays/lobby/player.tscn
+++ b/client/gui/overlays/lobby/player.tscn
@@ -1,6 +1,6 @@
-[gd_scene load_steps=6 format=3 uid="uid://gmldnel4xbxy"]
+[gd_scene 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="Material" uid="uid://beea1pc5nt67r" path="res://gui/resources/materials/dark_blur_material.tres" id="1_jy1rs"]
[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"]
@@ -14,29 +14,29 @@ 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
+[node name="Player" type="PanelContainer" unique_id=141359444]
+material = ExtResource("1_jy1rs")
+offset_right = 98.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="."]
+[node name="MarginContainer" type="MarginContainer" parent="." unique_id=2016059636]
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"]
+[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer" unique_id=1039786929]
layout_mode = 2
-[node name="Icon" type="TextureRect" parent="MarginContainer/HBoxContainer"]
+[node name="Icon" type="TextureRect" parent="MarginContainer/HBoxContainer" unique_id=1840719777]
layout_mode = 2
texture = ExtResource("2_mnaqt")
expand_mode = 2
-[node name="Label" type="Label" parent="MarginContainer/HBoxContainer"]
+[node name="Label" type="Label" parent="MarginContainer/HBoxContainer" unique_id=895904561]
layout_mode = 2
theme_override_styles/normal = SubResource("StyleBoxEmpty_3yp6e")
text = "Player"
diff --git a/client/gui/overlays/overlays.gd b/client/gui/overlays/overlays.gd
index 9971ea53..fc24fb2d 100644
--- a/client/gui/overlays/overlays.gd
+++ b/client/gui/overlays/overlays.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -17,7 +17,7 @@ extends Control
class_name Overlays
func _ready():
- Settings.hook_changed_init("ui.hide_overlays", "main", func (v): visible = not v)
+ Settings.hook_changed_init("ui.hide_overlays", self, func (v): visible = not v)
func _input(_event):
if Input.is_action_just_pressed("toggle_overlay"):
diff --git a/client/gui/overlays/overlays.tscn b/client/gui/overlays/overlays.tscn
index 93717736..158ec403 100644
--- a/client/gui/overlays/overlays.tscn
+++ b/client/gui/overlays/overlays.tscn
@@ -1,15 +1,14 @@
-[gd_scene load_steps=9 format=3 uid="uid://cr26jennm5c0c"]
+[gd_scene format=3 uid="uid://cr26jennm5c0c"]
[ext_resource type="Script" uid="uid://bkvtm1jlme6jf" path="res://gui/overlays/overlays.gd" id="1_dcvak"]
[ext_resource type="PackedScene" uid="uid://xcxbmynn8mhi" path="res://gui/overlays/chat.tscn" id="1_n4uhr"]
[ext_resource type="PackedScene" uid="uid://bpikve6wlsjfl" path="res://gui/overlays/score.tscn" id="2_whygm"]
[ext_resource type="PackedScene" uid="uid://dcrr1rwdwbkq8" path="res://gui/overlays/pinned_messages.tscn" id="3_dcvak"]
-[ext_resource type="PackedScene" uid="uid://bc50la65ntifb" path="res://gui/overlays/lobby/lobby.tscn" id="4_jwd7s"]
[ext_resource type="PackedScene" uid="uid://c7pykhpdhgs64" path="res://gui/overlays/announce_title.tscn" id="5_whygm"]
[ext_resource type="PackedScene" uid="uid://b21nrnkygiyjt" path="res://gui/overlays/popup_message/popup_message.tscn" id="7_jwd7s"]
[ext_resource type="PackedScene" uid="uid://3lytexnfrub6" path="res://gui/overlays/debug/debug.tscn" id="8_8ouu3"]
-[node name="Overlays" type="Control"]
+[node name="Overlays" type="Control" unique_id=2071182967]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
@@ -18,19 +17,16 @@ grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_dcvak")
-[node name="ChatPreview" parent="." instance=ExtResource("1_n4uhr")]
+[node name="PinnedMessages" parent="." unique_id=1769024201 instance=ExtResource("3_dcvak")]
layout_mode = 1
-[node name="Score" parent="." instance=ExtResource("2_whygm")]
+[node name="Score" parent="." unique_id=2068981342 instance=ExtResource("2_whygm")]
layout_mode = 1
-[node name="PinnedMessages" parent="." instance=ExtResource("3_dcvak")]
+[node name="ChatPreview" parent="." unique_id=1306284704 instance=ExtResource("1_n4uhr")]
layout_mode = 1
-[node name="Lobby" parent="." instance=ExtResource("4_jwd7s")]
-layout_mode = 1
-
-[node name="AnnounceTitle" parent="." instance=ExtResource("5_whygm")]
+[node name="AnnounceTitle" parent="." unique_id=1456313117 instance=ExtResource("5_whygm")]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
@@ -38,8 +34,8 @@ anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
-[node name="PopupMessage" parent="." instance=ExtResource("7_jwd7s")]
+[node name="PopupMessage" parent="." unique_id=1024925196 instance=ExtResource("7_jwd7s")]
layout_mode = 1
-[node name="Debug" parent="." instance=ExtResource("8_8ouu3")]
+[node name="Debug" parent="." unique_id=2125601218 instance=ExtResource("8_8ouu3")]
layout_mode = 1
diff --git a/client/gui/overlays/pinned_messages.gd b/client/gui/overlays/pinned_messages.gd
index fe82f904..1cca455d 100644
--- a/client/gui/overlays/pinned_messages.gd
+++ b/client/gui/overlays/pinned_messages.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/gui/overlays/pinned_messages.tscn b/client/gui/overlays/pinned_messages.tscn
index 318c9b85..a09eddee 100644
--- a/client/gui/overlays/pinned_messages.tscn
+++ b/client/gui/overlays/pinned_messages.tscn
@@ -1,8 +1,8 @@
-[gd_scene load_steps=2 format=3 uid="uid://dcrr1rwdwbkq8"]
+[gd_scene format=3 uid="uid://dcrr1rwdwbkq8"]
[ext_resource type="Script" uid="uid://c0k6f1wkynbkd" path="res://gui/overlays/pinned_messages.gd" id="1_q0jkk"]
-[node name="PinnedItemMessages" type="Control"]
+[node name="PinnedItemMessages" type="Control" unique_id=1436447205]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
@@ -12,7 +12,7 @@ grow_vertical = 2
mouse_filter = 2
script = ExtResource("1_q0jkk")
-[node name="HBoxContainer" type="HBoxContainer" parent="."]
+[node name="HBoxContainer" type="HBoxContainer" parent="." unique_id=15845709]
layout_direction = 2
layout_mode = 1
anchors_preset = 10
diff --git a/client/gui/overlays/popup_message/font_variation.tres b/client/gui/overlays/popup_message/font_variation.tres
new file mode 100644
index 00000000..84254e1c
--- /dev/null
+++ b/client/gui/overlays/popup_message/font_variation.tres
@@ -0,0 +1,10 @@
+[gd_resource type="FontVariation" format=3 uid="uid://c4g6ucr5piwy1"]
+
+[ext_resource type="FontFile" uid="uid://bk704sc5gkrb3" path="res://gui/resources/fonts/font-azaret-mono.woff2" id="1_gewoj"]
+
+[resource]
+resource_local_to_scene = true
+base_font = ExtResource("1_gewoj")
+variation_opentype = {
+2003265652: 400
+}
diff --git a/client/gui/overlays/popup_message/popup_message.gd b/client/gui/overlays/popup_message/popup_message.gd
index 4ea5aa2f..0fd88b78 100644
--- a/client/gui/overlays/popup_message/popup_message.gd
+++ b/client/gui/overlays/popup_message/popup_message.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -22,17 +22,20 @@ var positional_messages = {}
@onready var positional_messages_node: Control = $Positional
@onready var server_msg = $Static/VBox/ServerMessage
-@onready var server_msg_label: Label = $Static/VBox/ServerMessage/CenterContainer/Label
+@onready var server_hint = $Static/VBox/ServerHint
@onready var server_msg_timer: Timer = $ServerMessage
@onready var game: Game = $"../../Game" # TODO
func _process(_delta: float):
for pos: Vector2 in positional_messages.keys():
+ var camera: Camera3D = get_viewport().get_camera_3d()
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)
-
+ var pos_2d = camera.unproject_position(pos_3d)
+ var behind = camera.is_position_behind(pos_3d)
+
+ msg.node_2d.visible = not behind
msg.node_2d.position = pos_2d.clamp(
Vector2.ZERO + 0.5 * msg.node.size,
Vector2(get_viewport_rect().size) - 0.5 * msg.node.size
@@ -42,17 +45,20 @@ func _process(_delta: float):
msg.last_size = msg.node.size
msg.node.position = -0.5 * msg.last_size
-func display_server_msg(msg: String, auto_remove := true):
+func display_server_hint(msg):
+ server_hint.show()
+ server_hint.set_text(msg)
+
+func display_server_msg(msg, auto_remove := true):
server_msg.show()
- server_msg_label.text = msg
-
+ server_msg.set_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):
+func display_server_hint_positional(text, pos: Vector2, use_monospace: bool):
var msg := PositionalMessage.new()
msg.node = SERVER_MESSAGE_SCENE.instantiate()
msg.node_2d = Node2D.new()
@@ -63,10 +69,13 @@ func display_server_msg_positional(text: String, pos: Vector2, use_monospace: bo
msg.position = pos
positional_messages[pos] = msg
-func clear_server_msg(position_ = null):
+func clear_server_msg():
+ server_msg_timer.stop()
+ server_msg.hide()
+
+func clear_server_hint(position_ = null):
if position_ == null:
- server_msg_timer.stop()
- server_msg.hide()
+ server_hint.hide()
else:
if position_ in positional_messages:
var msg: PositionalMessage = positional_messages[position_]
diff --git a/client/gui/overlays/popup_message/popup_message.tscn b/client/gui/overlays/popup_message/popup_message.tscn
index fab35e3e..dd6c1bc8 100644
--- a/client/gui/overlays/popup_message/popup_message.tscn
+++ b/client/gui/overlays/popup_message/popup_message.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=4 format=3 uid="uid://b21nrnkygiyjt"]
+[gd_scene 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/overlays/popup_message/popup_message.gd" id="2_sbew6"]
[ext_resource type="PackedScene" uid="uid://dq61p3a8og2b6" path="res://gui/overlays/popup_message/server_message.tscn" id="3_m3rok"]
-[node name="PopupMessage" type="Control"]
+[node name="PopupMessage" type="Control" unique_id=739397547]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
@@ -14,11 +13,11 @@ grow_vertical = 2
mouse_filter = 2
script = ExtResource("2_sbew6")
-[node name="ServerMessage" type="Timer" parent="."]
+[node name="ServerMessage" type="Timer" parent="." unique_id=265858330]
wait_time = 5.0
one_shot = true
-[node name="Static" type="MarginContainer" parent="."]
+[node name="Static" type="MarginContainer" parent="." unique_id=138464647]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
@@ -26,17 +25,20 @@ anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
-theme = ExtResource("1_a1566")
-[node name="VBox" type="VBoxContainer" parent="Static"]
+[node name="VBox" type="VBoxContainer" parent="Static" unique_id=312654300]
layout_mode = 2
mouse_filter = 2
-[node name="ServerMessage" parent="Static/VBox" instance=ExtResource("3_m3rok")]
+[node name="ServerMessage" parent="Static/VBox" unique_id=337238699 instance=ExtResource("3_m3rok")]
visible = false
layout_mode = 2
-[node name="Positional" type="Control" parent="."]
+[node name="ServerHint" parent="Static/VBox" unique_id=704424213 instance=ExtResource("3_m3rok")]
+visible = false
+layout_mode = 2
+
+[node name="Positional" type="Control" parent="." unique_id=610159147]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
diff --git a/client/gui/overlays/popup_message/server_message.gd b/client/gui/overlays/popup_message/server_message.gd
index a0688dc5..a17ff612 100644
--- a/client/gui/overlays/popup_message/server_message.gd
+++ b/client/gui/overlays/popup_message/server_message.gd
@@ -1,13 +1,69 @@
+# Hurry Curry! - a game about cooking
+# Copyright (C) 2026 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 <https://www.gnu.org/licenses/>.
+#
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")
+const RENDERER = preload("res://gui/components/message/renderer.tscn")
-@onready var label: Label = $CenterContainer/Label
+@onready var flow: VFlowContainer = $CenterContainer/VFlowContainer
-func set_text(text: String, use_monospace := true):
- label.text = text
- var font: FontVariation = label.get_theme_font("font")
+func set_text(text, use_monospace := true):
+ for c: Node in flow.get_children():
+ c.queue_free()
+ if text is String:
+ flow.add_child(build_label(text, use_monospace))
+ elif text is Array:
+ for e: MessageParser in text:
+ var c: Control = build_message(e, use_monospace)
+ c.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
+ c.size_flags_vertical = Control.SIZE_EXPAND_FILL
+ flow.add_child(c)
+
+static func font_size(use_monospace: bool):
+ return 16 if use_monospace else 20
+
+func build_label(text: String, use_monospace: bool) -> Label:
+ var label = Label.new()
+ var font: FontVariation = preload("res://gui/overlays/popup_message/font_variation.tres")
+ var sb := StyleBoxEmpty.new()
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)
+ label.add_theme_font_size_override("font_size", font_size(use_monospace))
+ label.add_theme_font_override("font", font)
+ label.add_theme_color_override("font_color", Color.BLACK)
+ label.add_theme_stylebox_override("normal", sb)
+ label.autowrap_mode = TextServer.AUTOWRAP_OFF
+ label.text = text
+ label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
+ label.update_minimum_size()
+ return label
+
+func build_message(m: MessageParser, use_monospace: bool) -> Control:
+ match m.kind:
+ MessageParser.Kind.ITEM:
+ var r: Renderer = RENDERER.instantiate()
+ r.get_node("SubViewport").size = Vector2i.ONE * font_size(use_monospace) * 2
+ r.setup_item(m.result)
+ return r
+ MessageParser.Kind.TILE:
+ var r: Renderer = RENDERER.instantiate()
+ r.get_node("SubViewport").size = Vector2i.ONE * font_size(use_monospace) * 2
+ r.setup_tile([m.result])
+ return r
+ MessageParser.Kind.TEXT:
+ return build_label(m.result, use_monospace)
+ return null
diff --git a/client/gui/overlays/popup_message/server_message.tscn b/client/gui/overlays/popup_message/server_message.tscn
index 255c5e56..e64cad79 100644
--- a/client/gui/overlays/popup_message/server_message.tscn
+++ b/client/gui/overlays/popup_message/server_message.tscn
@@ -1,8 +1,7 @@
-[gd_scene load_steps=8 format=3 uid="uid://dq61p3a8og2b6"]
+[gd_scene 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/overlays/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")
@@ -19,35 +18,27 @@ 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_opentype = {
-2003265652: 400
-}
-
-[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"]
+[node name="ServerMessage" type="PanelContainer" unique_id=241738499]
material = SubResource("ShaderMaterial_q3bbd")
+offset_right = 210.0
+offset_bottom = 35.0
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="."]
+[node name="CenterContainer" type="MarginContainer" parent="." unique_id=1965686626]
layout_mode = 2
mouse_filter = 2
+theme_override_constants/margin_left = 32
+theme_override_constants/margin_top = 8
+theme_override_constants/margin_right = 32
+theme_override_constants/margin_bottom = 8
-[node name="Label" type="Label" parent="CenterContainer"]
+[node name="VFlowContainer" type="VFlowContainer" parent="CenterContainer" unique_id=1522041734]
+layout_direction = 1
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"
+theme_override_constants/h_separation = 0
+theme_override_constants/v_separation = 0
+last_wrap_alignment = 2
diff --git a/client/gui/overlays/score.gd b/client/gui/overlays/score.gd
index f66ae559..a5207746 100644
--- a/client/gui/overlays/score.gd
+++ b/client/gui/overlays/score.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/gui/overlays/score.tscn b/client/gui/overlays/score.tscn
index fcdfb514..db3e8723 100644
--- a/client/gui/overlays/score.tscn
+++ b/client/gui/overlays/score.tscn
@@ -1,6 +1,5 @@
-[gd_scene load_steps=6 format=3 uid="uid://bpikve6wlsjfl"]
+[gd_scene 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/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"]
@@ -8,7 +7,7 @@
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_04ujj"]
bg_color = Color(0, 0, 0, 0)
-[node name="ScoreOverlay" type="PanelContainer"]
+[node name="ScoreOverlay" type="PanelContainer" unique_id=1846677990]
layout_direction = 2
anchors_preset = 15
anchor_right = 1.0
@@ -16,22 +15,21 @@ 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="GameTime" type="Timer" parent="."]
+[node name="GameTime" type="Timer" parent="." unique_id=210885742]
wait_time = 30.0
-[node name="WarningTime" type="Timer" parent="."]
+[node name="WarningTime" type="Timer" parent="." unique_id=2123014988]
one_shot = true
-[node name="Score" type="Control" parent="."]
+[node name="Score" type="Control" parent="." unique_id=2011529559]
layout_mode = 2
size_flags_horizontal = 8
size_flags_vertical = 0
-[node name="Paper" type="TextureRect" parent="Score"]
+[node name="Paper" type="TextureRect" parent="Score" unique_id=1153834916]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
@@ -47,7 +45,7 @@ grow_vertical = 2
rotation = 0.0610865
texture = ExtResource("3_oum5g")
-[node name="Margin" type="MarginContainer" parent="Score/Paper"]
+[node name="Margin" type="MarginContainer" parent="Score/Paper" unique_id=1572878834]
layout_mode = 1
anchors_preset = 2
anchor_top = 1.0
@@ -58,27 +56,27 @@ grow_vertical = 0
theme_override_constants/margin_left = 10
theme_override_constants/margin_bottom = 10
-[node name="Lines" type="VBoxContainer" parent="Score/Paper/Margin"]
+[node name="Lines" type="VBoxContainer" parent="Score/Paper/Margin" unique_id=837263051]
layout_direction = 1
layout_mode = 2
size_flags_horizontal = 0
size_flags_vertical = 8
-[node name="Line1" type="HBoxContainer" parent="Score/Paper/Margin/Lines"]
+[node name="Line1" type="HBoxContainer" parent="Score/Paper/Margin/Lines" unique_id=994156258]
layout_mode = 2
-[node name="Label" type="Label" parent="Score/Paper/Margin/Lines/Line1"]
+[node name="Label" type="Label" parent="Score/Paper/Margin/Lines/Line1" unique_id=1286515503]
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"
+text = "c.score.demands_completed"
-[node name="Spacer" type="Control" parent="Score/Paper/Margin/Lines/Line1"]
+[node name="Spacer" type="Control" parent="Score/Paper/Margin/Lines/Line1" unique_id=1404497590]
layout_mode = 2
size_flags_horizontal = 3
-[node name="Completed" type="Label" parent="Score/Paper/Margin/Lines/Line1"]
+[node name="Completed" type="Label" parent="Score/Paper/Margin/Lines/Line1" unique_id=1103013403]
auto_translate_mode = 2
custom_minimum_size = Vector2(100, 0)
layout_mode = 2
@@ -88,21 +86,21 @@ theme_override_font_sizes/font_size = 35
text = "0"
horizontal_alignment = 1
-[node name="Line2" type="HBoxContainer" parent="Score/Paper/Margin/Lines"]
+[node name="Line2" type="HBoxContainer" parent="Score/Paper/Margin/Lines" unique_id=1837168386]
layout_mode = 2
-[node name="Label" type="Label" parent="Score/Paper/Margin/Lines/Line2"]
+[node name="Label" type="Label" parent="Score/Paper/Margin/Lines/Line2" unique_id=655498209]
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"
+text = "c.score.demands_failed"
-[node name="Spacer" type="Control" parent="Score/Paper/Margin/Lines/Line2"]
+[node name="Spacer" type="Control" parent="Score/Paper/Margin/Lines/Line2" unique_id=1118920525]
layout_mode = 2
size_flags_horizontal = 3
-[node name="Failed" type="Label" parent="Score/Paper/Margin/Lines/Line2"]
+[node name="Failed" type="Label" parent="Score/Paper/Margin/Lines/Line2" unique_id=820452433]
auto_translate_mode = 2
custom_minimum_size = Vector2(100, 0)
layout_mode = 2
@@ -112,21 +110,21 @@ theme_override_font_sizes/font_size = 35
text = "0"
horizontal_alignment = 1
-[node name="Line3" type="HBoxContainer" parent="Score/Paper/Margin/Lines"]
+[node name="Line3" type="HBoxContainer" parent="Score/Paper/Margin/Lines" unique_id=395828137]
layout_mode = 2
-[node name="Label" type="Label" parent="Score/Paper/Margin/Lines/Line3"]
+[node name="Label" type="Label" parent="Score/Paper/Margin/Lines/Line3" unique_id=692176995]
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"]
+[node name="Spacer" type="Control" parent="Score/Paper/Margin/Lines/Line3" unique_id=1198568818]
layout_mode = 2
size_flags_horizontal = 3
-[node name="Points" type="Label" parent="Score/Paper/Margin/Lines/Line3"]
+[node name="Points" type="Label" parent="Score/Paper/Margin/Lines/Line3" unique_id=1181984380]
auto_translate_mode = 2
custom_minimum_size = Vector2(100, 0)
layout_mode = 2
@@ -136,12 +134,12 @@ theme_override_font_sizes/font_size = 45
text = "0"
horizontal_alignment = 1
-[node name="Time" type="Control" parent="."]
+[node name="Time" type="Control" parent="." unique_id=374078299]
layout_mode = 2
size_flags_horizontal = 8
size_flags_vertical = 8
-[node name="Paper" type="TextureRect" parent="Time"]
+[node name="Paper" type="TextureRect" parent="Time" unique_id=594422819]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
@@ -157,17 +155,17 @@ grow_vertical = 2
rotation = 0.0610865
texture = ExtResource("3_oum5g")
-[node name="Node2D" type="Node2D" parent="Time/Paper"]
+[node name="Node2D" type="Node2D" parent="Time/Paper" unique_id=1716596348]
position = Vector2(95, 30)
-[node name="Line" type="HBoxContainer" parent="Time/Paper/Node2D"]
+[node name="Line" type="HBoxContainer" parent="Time/Paper/Node2D" unique_id=1351708448]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
-[node name="Minutes" type="Label" parent="Time/Paper/Node2D/Line"]
+[node name="Minutes" type="Label" parent="Time/Paper/Node2D/Line" unique_id=1901555605]
auto_translate_mode = 2
layout_mode = 2
theme_override_colors/font_color = Color(0, 0, 0, 1)
@@ -176,7 +174,7 @@ theme_override_font_sizes/font_size = 45
text = "05"
horizontal_alignment = 2
-[node name="Colon" type="Label" parent="Time/Paper/Node2D/Line"]
+[node name="Colon" type="Label" parent="Time/Paper/Node2D/Line" unique_id=2075984843]
auto_translate_mode = 2
layout_mode = 2
theme_override_colors/font_color = Color(0, 0, 0, 1)
@@ -185,7 +183,7 @@ theme_override_font_sizes/font_size = 45
text = ":"
horizontal_alignment = 1
-[node name="Seconds" type="Label" parent="Time/Paper/Node2D/Line"]
+[node name="Seconds" type="Label" parent="Time/Paper/Node2D/Line" unique_id=1543571528]
auto_translate_mode = 2
layout_mode = 2
theme_override_colors/font_color = Color(0, 0, 0, 1)
@@ -193,7 +191,7 @@ theme_override_fonts/font = ExtResource("3_u54fv")
theme_override_font_sizes/font_size = 45
text = "00"
-[node name="PulsatingTime" type="Timer" parent="Time/Paper/Node2D/Line"]
+[node name="PulsatingTime" type="Timer" parent="Time/Paper/Node2D/Line" unique_id=660955497]
wait_time = 0.5
[connection signal="timeout" from="WarningTime" to="." method="_on_warning_time_timeout"]
diff --git a/client/gui/resources/fonts/sansita-swashed-bold.tres b/client/gui/resources/fonts/sansita-swashed-bold.tres
index 17903145..d0bb5003 100644
--- a/client/gui/resources/fonts/sansita-swashed-bold.tres
+++ b/client/gui/resources/fonts/sansita-swashed-bold.tres
@@ -1,4 +1,4 @@
-[gd_resource type="FontVariation" load_steps=2 format=3 uid="uid://cl6m4hqsnrpav"]
+[gd_resource type="FontVariation" format=3 uid="uid://cl6m4hqsnrpav"]
[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://gui/resources/fonts/font-sansita-swashed.woff2" id="1_x5a5j"]
diff --git a/client/gui/resources/materials/blur_material.tres b/client/gui/resources/materials/blur_material.tres
index b6ebf183..2ebc3385 100644
--- a/client/gui/resources/materials/blur_material.tres
+++ b/client/gui/resources/materials/blur_material.tres
@@ -1,4 +1,4 @@
-[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://2j8a0c0a2ta5"]
+[gd_resource type="ShaderMaterial" format=3 uid="uid://2j8a0c0a2ta5"]
[ext_resource type="Shader" uid="uid://cwldxegcj55if" path="res://gui/resources/shaders/blur_mix.gdshader" id="1_d16rd"]
diff --git a/client/gui/resources/materials/dark_blur_material.tres b/client/gui/resources/materials/dark_blur_material.tres
index 9a59c614..e6a74077 100644
--- a/client/gui/resources/materials/dark_blur_material.tres
+++ b/client/gui/resources/materials/dark_blur_material.tres
@@ -1,11 +1,11 @@
-[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://beea1pc5nt67r"]
+[gd_resource type="ShaderMaterial" 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 = 0.6
shader_parameter/mix_amount_no_blur = 0.7
shader_parameter/color_over = Color(0, 0, 0, 1)
shader_parameter/enable_blur = false
diff --git a/client/gui/resources/materials/grayscale_material.tres b/client/gui/resources/materials/grayscale_material.tres
index 236ad443..819894b8 100644
--- a/client/gui/resources/materials/grayscale_material.tres
+++ b/client/gui/resources/materials/grayscale_material.tres
@@ -1,4 +1,4 @@
-[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://bplhkekj6rebp"]
+[gd_resource type="ShaderMaterial" format=3 uid="uid://bplhkekj6rebp"]
[ext_resource type="Shader" uid="uid://qjrh2imc53u1" path="res://gui/resources/shaders/grayscale.gdshader" id="1_u0c2c"]
diff --git a/client/gui/resources/materials/printed_material.tres b/client/gui/resources/materials/printed_material.tres
index 3cc4a88c..1648e6cc 100644
--- a/client/gui/resources/materials/printed_material.tres
+++ b/client/gui/resources/materials/printed_material.tres
@@ -1,4 +1,4 @@
-[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://dogdyoqrmy6ft"]
+[gd_resource type="ShaderMaterial" format=3 uid="uid://dogdyoqrmy6ft"]
[ext_resource type="Shader" uid="uid://5p1xlwoc8qe5" path="res://gui/resources/shaders/printed.gdshader" id="1_sevww"]
diff --git a/client/gui/resources/shaders/blur_mix.gdshader b/client/gui/resources/shaders/blur_mix.gdshader
index 97686a54..fc29603f 100644
--- a/client/gui/resources/shaders/blur_mix.gdshader
+++ b/client/gui/resources/shaders/blur_mix.gdshader
@@ -1,6 +1,6 @@
/*
Hurry Curry! - a game about cooking
- Copyright (C) 2025 Hurry Curry! Contributors
+ Copyright (C) 2026 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
@@ -27,6 +27,7 @@ uniform bool enable_blur;
void fragment() {
if (enable_blur) {
vec4 blurred = textureLod(SCREEN_TEXTURE, SCREEN_UV, blur_amount);
+ blurred.a = 1.;
COLOR = mix(blurred, color_over, mix_amount);
} else {
COLOR = mix(texture(SCREEN_TEXTURE, SCREEN_UV), color_over, mix_amount_no_blur);
diff --git a/client/gui/resources/shaders/clouds_canvas_item.gdshader b/client/gui/resources/shaders/clouds_canvas_item.gdshader
new file mode 100644
index 00000000..b5868b74
--- /dev/null
+++ b/client/gui/resources/shaders/clouds_canvas_item.gdshader
@@ -0,0 +1,35 @@
+/*
+ Hurry Curry! - a game about cooking
+ Copyright (C) 2026 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 <https://www.gnu.org/licenses/>.
+
+*/
+shader_type canvas_item;
+
+uniform sampler2D noise : source_color, repeat_enable;
+uniform vec4 ccloud : source_color;
+uniform vec4 csky : source_color;
+
+void fragment() {
+ vec2 uv = UV * 0.9;
+ uv += TIME * vec2(0.01,0.02);
+
+ float f = texture(noise, uv).x;
+ f = 1. - f;
+ f = pow(f, 1.5);
+ f = floor(f*5.)/5.;
+ f = pow(f, 2.);
+
+ COLOR = mix(csky, ccloud, f);
+}
diff --git a/client/gui/resources/shaders/clouds_canvas_item.gdshader.uid b/client/gui/resources/shaders/clouds_canvas_item.gdshader.uid
new file mode 100644
index 00000000..1b5ea7f0
--- /dev/null
+++ b/client/gui/resources/shaders/clouds_canvas_item.gdshader.uid
@@ -0,0 +1 @@
+uid://b7p7umdb51hhn
diff --git a/client/gui/resources/shaders/grayscale.gdshader b/client/gui/resources/shaders/grayscale.gdshader
index c058e7bf..61ae539c 100644
--- a/client/gui/resources/shaders/grayscale.gdshader
+++ b/client/gui/resources/shaders/grayscale.gdshader
@@ -1,6 +1,6 @@
/*
Hurry Curry! - a game about cooking
- Copyright (C) 2025 Hurry Curry! Contributors
+ Copyright (C) 2026 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
diff --git a/client/gui/resources/shaders/paper.tres b/client/gui/resources/shaders/paper.tres
index f99aec03..c2102a14 100644
--- a/client/gui/resources/shaders/paper.tres
+++ b/client/gui/resources/shaders/paper.tres
@@ -1,4 +1,4 @@
-[gd_resource type="NoiseTexture2D" load_steps=3 format=3 uid="uid://chxkwohi56cxx"]
+[gd_resource type="NoiseTexture2D" 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)
diff --git a/client/gui/resources/shaders/printed.gdshader b/client/gui/resources/shaders/printed.gdshader
index c24cb679..adcabb7b 100644
--- a/client/gui/resources/shaders/printed.gdshader
+++ b/client/gui/resources/shaders/printed.gdshader
@@ -1,6 +1,6 @@
/*
Hurry Curry! - a game about cooking
- Copyright (C) 2025 Hurry Curry! Contributors
+ Copyright (C) 2026 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
diff --git a/client/gui/resources/style/error_focus_style.tres b/client/gui/resources/style/error_focus_style.tres
index f7c44505..c1472895 100644
--- a/client/gui/resources/style/error_focus_style.tres
+++ b/client/gui/resources/style/error_focus_style.tres
@@ -5,13 +5,13 @@ 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)
+bg_color = Color(0.36078432, 0, 0, 0)
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
+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/error_normal_style.tres b/client/gui/resources/style/error_normal_style.tres
new file mode 100644
index 00000000..a22ca2ee
--- /dev/null
+++ b/client/gui/resources/style/error_normal_style.tres
@@ -0,0 +1,13 @@
+[gd_resource type="StyleBoxFlat" format=3 uid="uid://c7jksrejojryo"]
+
+[resource]
+content_margin_left = 10.0
+content_margin_top = 10.0
+content_margin_right = 10.0
+content_margin_bottom = 10.0
+bg_color = Color(0.36078432, 0, 0, 0.2509804)
+border_color = Color(1, 0.81804, 0.818076, 1)
+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/focus_style.tres b/client/gui/resources/style/focus_style.tres
index a01843fe..a8169f9d 100644
--- a/client/gui/resources/style/focus_style.tres
+++ b/client/gui/resources/style/focus_style.tres
@@ -5,13 +5,13 @@ 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)
+bg_color = Color(0.03137255, 0.03137255, 0.03137255, 0)
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
+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/hover_style.tres b/client/gui/resources/style/hover_style.tres
index 963ee2ca..2d65f39a 100644
--- a/client/gui/resources/style/hover_style.tres
+++ b/client/gui/resources/style/hover_style.tres
@@ -5,8 +5,8 @@ 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
+bg_color = Color(1, 1, 1, 0.1254902)
+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/normal_style.tres b/client/gui/resources/style/normal_style.tres
index 96aecc8e..3d1da731 100644
--- a/client/gui/resources/style/normal_style.tres
+++ b/client/gui/resources/style/normal_style.tres
@@ -5,8 +5,8 @@ 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
+bg_color = Color(0.03137255, 0.03137255, 0.03137255, 0.2509804)
+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_button_backround_style.tres b/client/gui/resources/style/panel_button_backround_style.tres
new file mode 100644
index 00000000..6b27ca1e
--- /dev/null
+++ b/client/gui/resources/style/panel_button_backround_style.tres
@@ -0,0 +1,8 @@
+[gd_resource type="StyleBoxFlat" format=3 uid="uid://d1xhwgrptnlli"]
+
+[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.tres b/client/gui/resources/style/panel_style.tres
index d1f27667..f12ec8bf 100644
--- a/client/gui/resources/style/panel_style.tres
+++ b/client/gui/resources/style/panel_style.tres
@@ -2,7 +2,7 @@
[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
+corner_radius_top_left = 16
+corner_radius_top_right = 16
+corner_radius_bottom_right = 16
+corner_radius_bottom_left = 16
diff --git a/client/gui/resources/style/paper_panel_style.tres b/client/gui/resources/style/paper_panel_style.tres
index effa2310..4336d5b1 100644
--- a/client/gui/resources/style/paper_panel_style.tres
+++ b/client/gui/resources/style/paper_panel_style.tres
@@ -1,4 +1,4 @@
-[gd_resource type="StyleBoxTexture" load_steps=2 format=3 uid="uid://bqhs5wtdp2oax"]
+[gd_resource type="StyleBoxTexture" format=3 uid="uid://bqhs5wtdp2oax"]
[ext_resource type="Texture2D" uid="uid://chxkwohi56cxx" path="res://gui/resources/shaders/paper.tres" id="1_u1kqj"]
diff --git a/client/gui/resources/style/lobby_panel_override.tres b/client/gui/resources/style/square_panel_override.tres
index 04fd16b0..04fd16b0 100644
--- a/client/gui/resources/style/lobby_panel_override.tres
+++ b/client/gui/resources/style/square_panel_override.tres
diff --git a/client/gui/resources/theme/theme.tres b/client/gui/resources/theme/default.tres
index ca87a81c..2b3344b1 100644
--- a/client/gui/resources/theme/theme.tres
+++ b/client/gui/resources/theme/default.tres
@@ -1,4 +1,4 @@
-[gd_resource type="Theme" load_steps=12 format=3 uid="uid://b0qmvo504e457"]
+[gd_resource type="Theme" 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"]
@@ -32,7 +32,9 @@ variation_embolden = 0.7
[sub_resource type="FontVariation" id="FontVariation_lyo8w"]
base_font = ExtResource("1_f8qb0")
-variation_embolden = 1.25
+variation_opentype = {
+2003265652: 500
+}
spacing_top = 5
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_or5ri"]
@@ -55,7 +57,7 @@ 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/normal = ExtResource("2_8fwoi")
LineEdit/styles/read_only = SubResource("StyleBoxFlat_25x32")
MarginContainer/constants/margin_bottom = 32
MarginContainer/constants/margin_left = 32
diff --git a/client/gui/resources/theme/paper.tres b/client/gui/resources/theme/paper.tres
index 41417f39..480f6f46 100644
--- a/client/gui/resources/theme/paper.tres
+++ b/client/gui/resources/theme/paper.tres
@@ -1,4 +1,4 @@
-[gd_resource type="Theme" load_steps=17 format=3 uid="uid://ci2qajdoa1an1"]
+[gd_resource type="Theme" 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"]
diff --git a/client/locale_book b/client/locale_book
deleted file mode 120000
index 89e799e8..00000000
--- a/client/locale_book
+++ /dev/null
@@ -1 +0,0 @@
-../book/locale \ No newline at end of file
diff --git a/client/makefile b/client/makefile
deleted file mode 100644
index 281ea431..00000000
--- a/client/makefile
+++ /dev/null
@@ -1,33 +0,0 @@
-# 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 <https://www.gnu.org/licenses/>.
-#
-GODOT = godot
-
-.PHONY: assets clean all
-all: .godot/import-finished icons/adaptive-background.png icons/adaptive-foreground.png
-
-clean:
- rm -f menu/book/book_*.webp
- rm -f icons/adaptive-foreground.png icons/adaptive-background.png
- rm .godot/import-finished
-
-.godot/import-finished:
- if test ! -e $@; then $(GODOT) --headless --import project.godot; fi
- touch $@
-
-icons/adaptive-background.png:
- ffmpeg -f lavfi -i "color=color=#E28142,scale=432x432" -frames:v 1 -y $@
-icons/adaptive-foreground.png: icons/main.png
- ffmpeg -f image2 -i $< -vf "scale=280x280,pad=432:432:(ow-iw)/2:(oh-ih)/2:0x00000000" -frames:v 1 -y $@
diff --git a/client/map/auto_setup/environment_setup.gd b/client/map/auto_setup/environment_setup.gd
index 7b6c5c8a..25d75b35 100644
--- a/client/map/auto_setup/environment_setup.gd
+++ b/client/map/auto_setup/environment_setup.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -22,9 +22,9 @@ func set_sky(sky_name: String):
environment.sky.sky_material = load("res://map/environment/presets/%s_sky.tres" % sky_name)
func _ready():
- Settings.hook_changed_init("graphics.ssao", "main", func (x): environment.ssao_enabled = x)
- Settings.hook_changed_init("graphics.gi", "main", func (x): environment.sdfgi_enabled = x == "sdfgi" and allow_sdfgi)
- Settings.hook_changed_init("graphics.glow", "main", func (x): environment.glow_enabled = x)
+ Settings.hook_changed_init("graphics.ssao", self, func (x): environment.ssao_enabled = x)
+ Settings.hook_changed_init("graphics.gi", self, func (x): environment.sdfgi_enabled = x == "sdfgi" and allow_sdfgi)
+ Settings.hook_changed_init("graphics.glow", self, func (x): environment.glow_enabled = x)
if !Global.on_vulkan():
environment.environment.tonemap_exposure = 0.5
diff --git a/client/map/auto_setup/light_setup.gd b/client/map/auto_setup/light_setup.gd
index 0d71f54b..3056998e 100644
--- a/client/map/auto_setup/light_setup.gd
+++ b/client/map/auto_setup/light_setup.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -20,7 +20,7 @@ class_name LightSetup
var shadows_enabled: bool
func _ready():
- Settings.hook_changed_init("graphics.shadows", "main", apply_settings)
+ Settings.hook_changed_init("graphics.shadows", self, apply_settings)
func set_visible_(val: bool):
if completely_disable_light_if_shadows_disabled and not shadows_enabled:
diff --git a/client/map/auto_setup/sky_light_setup.gd b/client/map/auto_setup/sky_light_setup.gd
index cb59fbf1..f888f79d 100644
--- a/client/map/auto_setup/sky_light_setup.gd
+++ b/client/map/auto_setup/sky_light_setup.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/effects/angry/angry.gd b/client/map/effects/angry/angry.gd
new file mode 100644
index 00000000..151507cd
--- /dev/null
+++ b/client/map/effects/angry/angry.gd
@@ -0,0 +1,26 @@
+# Hurry Curry! - a game about cooking
+# Copyright (C) 2026 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 <https://www.gnu.org/licenses/>.
+#
+extends Effect
+
+@onready var failure = $Failure
+@onready var angry_grunt: PlayRandom = $AngryGrunt
+@onready var particles = $Particles
+
+func _ready() -> void:
+ delete_timer(5)
+ particles.emitting = true
+ angry_grunt.play_random()
+ failure.play()
diff --git a/client/map/effects/angry/angry.gd.uid b/client/map/effects/angry/angry.gd.uid
new file mode 100644
index 00000000..642ef1f2
--- /dev/null
+++ b/client/map/effects/angry/angry.gd.uid
@@ -0,0 +1 @@
+uid://dxiq14ilf5bk
diff --git a/client/map/effects/angry/angry.tscn b/client/map/effects/angry/angry.tscn
new file mode 100644
index 00000000..94c6473d
--- /dev/null
+++ b/client/map/effects/angry/angry.tscn
@@ -0,0 +1,63 @@
+[gd_scene format=3 uid="uid://cvty1rwt52anq"]
+
+[ext_resource type="Texture2D" uid="uid://unjbxplj845n" path="res://map/effects/angry/angry.webp" id="1_5op6v"]
+[ext_resource type="Script" uid="uid://dxiq14ilf5bk" path="res://map/effects/angry/angry.gd" id="1_m21dl"]
+[ext_resource type="AudioStream" uid="uid://cv4isy6po6pqd" path="res://gui/resources/sounds/failure.ogg" id="2_vlpct"]
+[ext_resource type="Script" uid="uid://n4jwod1jfuiv" path="res://audio/play_random.gd" id="3_o0kjt"]
+[ext_resource type="AudioStream" uid="uid://c3gatgrsb0npf" path="res://player/sounds/angry1.ogg" id="4_wfdot"]
+[ext_resource type="AudioStream" uid="uid://cty282m6ckt62" path="res://player/sounds/angry2.ogg" id="5_ym83o"]
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ysmnk"]
+transparency = 1
+no_depth_test = true
+shading_mode = 0
+vertex_color_use_as_albedo = true
+albedo_texture = ExtResource("1_5op6v")
+billboard_mode = 3
+billboard_keep_scale = true
+particles_anim_h_frames = 1
+particles_anim_v_frames = 1
+particles_anim_loop = false
+
+[sub_resource type="QuadMesh" id="QuadMesh_5nim7"]
+material = SubResource("StandardMaterial3D_ysmnk")
+
+[sub_resource type="Curve" id="Curve_0rju1"]
+_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.51927, 1), 0.0, 0.0, 0, 0]
+point_count = 2
+
+[sub_resource type="Gradient" id="Gradient_lmymu"]
+offsets = PackedFloat32Array(0, 0.711828, 1)
+colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)
+
+[node name="Angry" type="Node3D" unique_id=1448163105]
+script = ExtResource("1_m21dl")
+
+[node name="Particles" type="CPUParticles3D" parent="." unique_id=691382738]
+emitting = false
+amount = 5
+lifetime = 2.0
+one_shot = true
+explosiveness = 1.0
+mesh = SubResource("QuadMesh_5nim7")
+direction = Vector3(0, 1, 0)
+spread = 30.0
+gravity = Vector3(0, 0, 0)
+initial_velocity_min = 1.0
+initial_velocity_max = 1.5
+scale_amount_curve = SubResource("Curve_0rju1")
+color_ramp = SubResource("Gradient_lmymu")
+
+[node name="Failure" type="AudioStreamPlayer" parent="." unique_id=1310258100]
+stream = ExtResource("2_vlpct")
+volume_db = -8.0
+
+[node name="AngryGrunt" type="Node3D" parent="." unique_id=681036661]
+script = ExtResource("3_o0kjt")
+volume_db = -8.0
+
+[node name="Angry1" type="AudioStreamPlayer3D" parent="AngryGrunt" unique_id=278427723]
+stream = ExtResource("4_wfdot")
+
+[node name="Angry2" type="AudioStreamPlayer3D" parent="AngryGrunt" unique_id=1539145236]
+stream = ExtResource("5_ym83o")
diff --git a/client/player/particles/angry/angry.webp b/client/map/effects/angry/angry.webp
index 866ba92c..866ba92c 100644
--- a/client/player/particles/angry/angry.webp
+++ b/client/map/effects/angry/angry.webp
Binary files differ
diff --git a/client/player/particles/angry/angry.webp.import b/client/map/effects/angry/angry.webp.import
index fe6b5449..eac70392 100644
--- a/client/player/particles/angry/angry.webp.import
+++ b/client/map/effects/angry/angry.webp.import
@@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://unjbxplj845n"
-path="res://.godot/imported/angry.webp-f649f66bf6a009b3b61480c4e451c61b.ctex"
+path="res://.godot/imported/angry.webp-fd51236e60c2d6e246b04296d67f5f19.ctex"
metadata={
"vram_texture": false
}
[deps]
-source_file="res://player/particles/angry/angry.webp"
-dest_files=["res://.godot/imported/angry.webp-f649f66bf6a009b3b61480c4e451c61b.ctex"]
+source_file="res://map/effects/angry/angry.webp"
+dest_files=["res://.godot/imported/angry.webp-fd51236e60c2d6e246b04296d67f5f19.ctex"]
[params]
diff --git a/client/map/tiles/bun_crate.gd b/client/map/effects/effect.gd
index 10a69aa8..a7b08bae 100644
--- a/client/map/tiles/bun_crate.gd
+++ b/client/map/effects/effect.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -13,9 +13,10 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
-class_name BunCrate
-extends Crate
+class_name Effect
+extends Node3D
-func _init(ctx: TileFactory.TileCC):
- super(ctx)
- base.add_child(load("res://map/tiles/bun_crate.tscn").instantiate())
+var data: Variant
+func delete_timer(delay: float):
+ await get_tree().create_timer(delay).timeout
+ queue_free()
diff --git a/client/player/particles/effect.gd.uid b/client/map/effects/effect.gd.uid
index b9ddd1ee..b9ddd1ee 100644
--- a/client/player/particles/effect.gd.uid
+++ b/client/map/effects/effect.gd.uid
diff --git a/client/map/effects/effect_factory.gd b/client/map/effects/effect_factory.gd
new file mode 100644
index 00000000..246aca1f
--- /dev/null
+++ b/client/map/effects/effect_factory.gd
@@ -0,0 +1,34 @@
+# Hurry Curry! - a game about cooking
+# Copyright (C) 2026 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 <https://www.gnu.org/licenses/>.
+#
+class_name EffectFactory
+extends Object
+
+const ANGRY = preload("res://map/effects/angry/angry.tscn")
+const SATISFIED = preload("res://map/effects/satisfied/satisfied.tscn")
+const POINTS = preload("res://map/effects/points/points.tscn")
+
+static func create_effect(p: Dictionary):
+ match p["effect"]:
+ "angry": return ANGRY.instantiate()
+ "satisfied": return SATISFIED.instantiate()
+ "points":
+ var points = POINTS.instantiate()
+ points.amount = p["amount"]
+ return points
+ _: push_error("unknown effect " + p["effect"])
+
+static func play_effect(target: Node3D, p: Dictionary):
+ target.add_child(create_effect(p))
diff --git a/client/map/effects/effect_factory.gd.uid b/client/map/effects/effect_factory.gd.uid
new file mode 100644
index 00000000..8a154ad0
--- /dev/null
+++ b/client/map/effects/effect_factory.gd.uid
@@ -0,0 +1 @@
+uid://w2l71qjjoshv
diff --git a/client/map/effects/points/points.gd b/client/map/effects/points/points.gd
new file mode 100644
index 00000000..35894902
--- /dev/null
+++ b/client/map/effects/points/points.gd
@@ -0,0 +1,30 @@
+# Hurry Curry! - a game about cooking
+# Copyright (C) 2026 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 <https://www.gnu.org/licenses/>.
+#
+extends Effect
+
+var amount: int
+
+@onready var points: CPUParticles3D = $Points
+@onready var amount_label: Label = $SubViewport/Control/AmountLabel
+
+func _ready():
+ delete_timer(5)
+ var num_string: String = str(amount)
+ if amount >= 0:
+ num_string = "+" + num_string
+ points.color = Color(.1,.6,.1) if amount >= 0 else Color(.6,.1,.1)
+ amount_label.text = num_string
+ points.emitting = true
diff --git a/client/map/effects/points/points.gd.uid b/client/map/effects/points/points.gd.uid
new file mode 100644
index 00000000..2bf5b594
--- /dev/null
+++ b/client/map/effects/points/points.gd.uid
@@ -0,0 +1 @@
+uid://528xphnsg62u
diff --git a/client/map/effects/points/points.tscn b/client/map/effects/points/points.tscn
new file mode 100644
index 00000000..57e11ddf
--- /dev/null
+++ b/client/map/effects/points/points.tscn
@@ -0,0 +1,90 @@
+[gd_scene format=3 uid="uid://x00adyx4umft"]
+
+[ext_resource type="Script" uid="uid://528xphnsg62u" path="res://map/effects/points/points.gd" id="1_wveft"]
+[ext_resource type="AudioStream" uid="uid://camy77x26mmpv" path="res://gui/resources/sounds/success.ogg" id="2_ixmsm"]
+[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://gui/resources/fonts/font-sansita-swashed.woff2" id="3_op1cb"]
+
+[sub_resource type="FontVariation" id="FontVariation_u8wnh"]
+base_font = ExtResource("3_op1cb")
+variation_opentype = {
+2003265652: 600
+}
+
+[sub_resource type="ViewportTexture" id="ViewportTexture_7hygc"]
+viewport_path = NodePath("SubViewport")
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_uepl5"]
+resource_local_to_scene = true
+render_priority = 1
+transparency = 1
+no_depth_test = true
+shading_mode = 0
+vertex_color_use_as_albedo = true
+albedo_texture = SubResource("ViewportTexture_7hygc")
+billboard_mode = 3
+billboard_keep_scale = true
+particles_anim_h_frames = 1
+particles_anim_v_frames = 1
+particles_anim_loop = false
+
+[sub_resource type="QuadMesh" id="QuadMesh_u8wnh"]
+resource_local_to_scene = true
+material = SubResource("StandardMaterial3D_uepl5")
+
+[sub_resource type="Curve" id="Curve_0rju1"]
+_data = [Vector2(0, 0), 0.0, 5.0, 0, 0, Vector2(0.49840245, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), -5.0, 0.0, 0, 0]
+point_count = 3
+
+[sub_resource type="Gradient" id="Gradient_uepl5"]
+offsets = PackedFloat32Array(0, 0.26672226, 0.4904026, 1)
+colors = PackedColorArray(1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)
+
+[node name="Points" type="Node3D" unique_id=1800089616]
+script = ExtResource("1_wveft")
+
+[node name="Success" type="AudioStreamPlayer" parent="." unique_id=710129954]
+stream = ExtResource("2_ixmsm")
+
+[node name="SubViewport" type="SubViewport" parent="." unique_id=2117836549]
+transparent_bg = true
+size = Vector2i(256, 256)
+
+[node name="Control" type="Control" parent="SubViewport" unique_id=1691084866]
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+
+[node name="AmountLabel" type="Label" parent="SubViewport/Control" unique_id=358131106]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_colors/font_outline_color = Color(0.1254902, 0.1254902, 0.1254902, 1)
+theme_override_constants/outline_size = 48
+theme_override_fonts/font = SubResource("FontVariation_u8wnh")
+theme_override_font_sizes/font_size = 165
+text = "+5"
+horizontal_alignment = 1
+vertical_alignment = 1
+
+[node name="Points" type="CPUParticles3D" parent="." unique_id=1697923795]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
+emitting = false
+amount = 1
+one_shot = true
+explosiveness = 1.0
+mesh = SubResource("QuadMesh_u8wnh")
+direction = Vector3(0, -1, 0)
+spread = 0.0
+gravity = Vector3(0, 0, 0)
+initial_velocity_min = 0.01
+initial_velocity_max = 0.01
+scale_amount_min = 0.65
+scale_amount_max = 0.65
+scale_amount_curve = SubResource("Curve_0rju1")
+color_ramp = SubResource("Gradient_uepl5")
diff --git a/client/map/tiles/book.gd b/client/map/effects/satisfied/satisfied.gd
index 6a48752a..67cbb4d2 100644
--- a/client/map/tiles/book.gd
+++ b/client/map/effects/satisfied/satisfied.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -13,9 +13,12 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
-class_name Book
-extends CounterBase
+extends Effect
-func _init(ctx: TileFactory.TileCC):
- super(ctx)
- base.add_child(load("res://map/tiles/book.tscn").instantiate())
+@onready var success = $Success
+@onready var stars = $Stars
+
+func _ready():
+ delete_timer(5)
+ stars.emitting = true
+ success.play()
diff --git a/client/map/effects/satisfied/satisfied.gd.uid b/client/map/effects/satisfied/satisfied.gd.uid
new file mode 100644
index 00000000..904996ad
--- /dev/null
+++ b/client/map/effects/satisfied/satisfied.gd.uid
@@ -0,0 +1 @@
+uid://dsepgasa5ki43
diff --git a/client/player/particles/satisfied/stars.tscn b/client/map/effects/satisfied/satisfied.tscn
index 77b4406d..bbd337c4 100644
--- a/client/player/particles/satisfied/stars.tscn
+++ b/client/map/effects/satisfied/satisfied.tscn
@@ -1,6 +1,8 @@
-[gd_scene load_steps=6 format=3 uid="uid://yaed1vnhd0aa"]
+[gd_scene format=3 uid="uid://yaed1vnhd0aa"]
-[ext_resource type="Texture2D" uid="uid://b10goh4dsa3b0" path="res://player/particles/satisfied/star.webp" id="1_v8q3r"]
+[ext_resource type="AudioStream" uid="uid://camy77x26mmpv" path="res://gui/resources/sounds/success.ogg" id="1_rxp1p"]
+[ext_resource type="Script" uid="uid://dsepgasa5ki43" path="res://map/effects/satisfied/satisfied.gd" id="1_sujye"]
+[ext_resource type="Texture2D" uid="uid://b10goh4dsa3b0" path="res://map/effects/satisfied/star.webp" id="1_v8q3r"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_d8uy0"]
transparency = 1
@@ -25,7 +27,14 @@ point_count = 2
offsets = PackedFloat32Array(0, 0.711828, 1)
colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)
-[node name="Stars" type="CPUParticles3D"]
+[node name="Satisfied" type="Node3D" unique_id=1800089616]
+script = ExtResource("1_sujye")
+
+[node name="Success" type="AudioStreamPlayer" parent="." unique_id=710129954]
+stream = ExtResource("1_rxp1p")
+
+[node name="Stars" type="CPUParticles3D" parent="." unique_id=1697923795]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
emitting = false
amount = 5
lifetime = 2.0
diff --git a/client/player/particles/satisfied/star.webp b/client/map/effects/satisfied/star.webp
index c1d2e8ff..c1d2e8ff 100644
--- a/client/player/particles/satisfied/star.webp
+++ b/client/map/effects/satisfied/star.webp
Binary files differ
diff --git a/client/player/particles/satisfied/star.webp.import b/client/map/effects/satisfied/star.webp.import
index 816f6af0..2ac435b7 100644
--- a/client/player/particles/satisfied/star.webp.import
+++ b/client/map/effects/satisfied/star.webp.import
@@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://b10goh4dsa3b0"
-path="res://.godot/imported/star.webp-4edd9a951e46ba686b105839f622c981.ctex"
+path="res://.godot/imported/star.webp-74beadf67879cd7f7736819dd8ef7e05.ctex"
metadata={
"vram_texture": false
}
[deps]
-source_file="res://player/particles/satisfied/star.webp"
-dest_files=["res://.godot/imported/star.webp-4edd9a951e46ba686b105839f622c981.ctex"]
+source_file="res://map/effects/satisfied/star.webp"
+dest_files=["res://.godot/imported/star.webp-74beadf67879cd7f7736819dd8ef7e05.ctex"]
[params]
diff --git a/client/map/environment/environment.tscn b/client/map/environment/environment.tscn
index fe8bdcbc..aaa4ed55 100644
--- a/client/map/environment/environment.tscn
+++ b/client/map/environment/environment.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=12 format=3 uid="uid://nroo08m5og0"]
+[gd_scene format=3 uid="uid://nroo08m5og0"]
[ext_resource type="Script" uid="uid://drv5el01y7fr" path="res://map/environment/environment.gd" id="1_qy481"]
[ext_resource type="PackedScene" uid="uid://cb4ic3ssk4r8r" path="res://map/environment/world_environment.tscn" id="2_68o16"]
@@ -58,25 +58,25 @@ material = SubResource("StandardMaterial3D_ig8qu")
radius = 0.03
height = 0.06
-[node name="Environment" type="Node3D"]
+[node name="Environment" type="Node3D" unique_id=857364835]
script = ExtResource("1_qy481")
-[node name="Rain" type="GPUParticles3D" parent="."]
+[node name="Rain" type="GPUParticles3D" parent="." unique_id=1938136108]
emitting = false
amount = 500
process_material = SubResource("ParticleProcessMaterial_fyrr8")
draw_pass_1 = SubResource("CapsuleMesh_6kss1")
-[node name="Wind" type="GPUParticles3D" parent="."]
+[node name="Wind" type="GPUParticles3D" parent="." unique_id=1893429122]
emitting = false
amount = 150
lifetime = 5.0
process_material = SubResource("ParticleProcessMaterial_pyn6b")
draw_pass_1 = SubResource("SphereMesh_4trvf")
-[node name="WorldEnvironment" parent="." instance=ExtResource("2_68o16")]
+[node name="WorldEnvironment" parent="." unique_id=976396102 instance=ExtResource("2_68o16")]
-[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
+[node name="DirectionalLight3D" type="DirectionalLight3D" parent="." unique_id=1587208474]
transform = Transform3D(-0.413104, 0.834517, -0.364591, 0, 0.400349, 0.916363, 0.910684, 0.378553, -0.165386, 0, 0, 0)
shadow_enabled = true
script = ExtResource("3_fcjh2")
diff --git a/client/map/environment/world_environment.tscn b/client/map/environment/world_environment.tscn
index e3f6c0f7..dfa33585 100644
--- a/client/map/environment/world_environment.tscn
+++ b/client/map/environment/world_environment.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=5 format=3 uid="uid://cb4ic3ssk4r8r"]
+[gd_scene format=3 uid="uid://cb4ic3ssk4r8r"]
[ext_resource type="Script" uid="uid://cwg7wympevxs4" path="res://map/auto_setup/environment_setup.gd" id="1_iatcp"]
[ext_resource type="Material" uid="uid://617pq1rgdgbn" path="res://map/environment/presets/day_sky.tres" id="1_jk80v"]
@@ -14,6 +14,6 @@ ssao_enabled = true
sdfgi_use_occlusion = true
sdfgi_energy = 2.0
-[node name="WorldEnvironment" type="WorldEnvironment"]
+[node name="WorldEnvironment" type="WorldEnvironment" unique_id=1422427611]
environment = SubResource("Environment_8cwcp")
script = ExtResource("1_iatcp")
diff --git a/client/map/item_factory.gd b/client/map/item_factory.gd
index 56842a47..5fccb526 100644
--- a/client/map/item_factory.gd
+++ b/client/map/item_factory.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -23,15 +23,21 @@ class ItemName:
func _init(raw_name: String):
raw = raw_name
- var c = Array(raw_name.split(":"))
+ var c = Array(raw_name.split(":", false, 1))
name = c[0]
- contents = c[1].split(",") if c.size() > 1 else []
+ if c.size() == 1:
+ contents = []
+ elif not c[1].contains(":"):
+ contents = c[1].split(",")
+ else:
+ contents = [c[1]] # Don't parse it, handle it in the item instead
-static func produce(raw_name: String, owned_by: Node3D) -> Item:
+static func produce(raw_name: String, owned_by: Node3D, scale := 1.) -> Item:
var name = ItemName.new(raw_name)
var item: Item = produce_inner(name, owned_by)
item.add_contents(name.contents)
item.item_name = raw_name
+ item.scale = Vector3(scale, scale, scale)
return item
static func produce_inner(item: ItemName, owned_by: Node3D) -> Item:
@@ -46,12 +52,14 @@ static func produce_inner(item: ItemName, owned_by: Node3D) -> Item:
"burned": return Burned.new(owned_by)
"coconut": return GenericItem.new(owned_by, preload("res://map/items/coconut.tscn"))
"dough": return GenericItem.new(owned_by, preload("res://map/items/dough.tscn"))
+ "doughnut": return GenericItem.new(owned_by, preload("res://map/items/donut/glazed-donut.tscn"))
"fish": return GenericItem.new(owned_by, preload("res://map/items/fish.tscn"))
"flour": return GenericItem.new(owned_by, preload("res://map/items/flour.tscn"))
"leek": return GenericItem.new(owned_by, preload("res://map/items/leek.tscn"))
"mushroom": return GenericItem.new(owned_by, preload("res://map/items/mushroom.tscn"))
+ "sliced-mushroom": return GenericItem.new(owned_by, preload("res://map/items/sliced_mushroom.tscn"))
"noodles": return GenericItem.new(owned_by, preload("res://map/items/noodles.tscn"))
- "rolled-dough": return GenericItem.new(owned_by, preload("res://map/items/rolled_dough.tscn"))
+ "rolled-dough": return RolledDough.new(owned_by)
"strawberry-mochi": return Mochi.new(owned_by, Color(.98, .70, .75))
"nigiri": return GenericItem.new(owned_by, preload("res://map/items/nigiri.tscn"))
"steak": return Cuttable.new(owned_by, preload("res://map/items/steak.tscn"), Color(0.74, 0.192, 0.22))
@@ -73,10 +81,10 @@ static func produce_inner(item: ItemName, owned_by: Node3D) -> Item:
var plate = Plate.new(owned_by)
plate.add_contents(["dirt"])
return plate
-
"pot": return Pot.new(owned_by)
"basket": return Basket.new(owned_by)
"pan": return Pan.new(owned_by)
+ "pizza": return Pizza.new(owned_by)
"foodprocessor": return FoodProcessor.new(owned_by)
"glass": return Glass.new(owned_by)
"plate": return Plate.new(owned_by)
diff --git a/client/map/items/basket.gd b/client/map/items/basket.gd
index df37b5dd..4da74aca 100644
--- a/client/map/items/basket.gd
+++ b/client/map/items/basket.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -26,11 +26,15 @@ func _init(owned_by_: Node3D):
base.add_child(bubbles)
base.position.z = -.075
+func is_round(): return false
+
func add_contents(contents: Array[String]):
for i in contents:
match i:
"french-fries":
base.add_child(load("res://map/items/french_fries_basket.tscn").instantiate())
+ "dough":
+ base.add_child(load("res://map/items/donut/donut.tscn").instantiate())
_:
super([i])
diff --git a/client/map/items/basket.tscn b/client/map/items/basket.tscn
index 4a3e046d..628e4bd6 100644
--- a/client/map/items/basket.tscn
+++ b/client/map/items/basket.tscn
@@ -1,9 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://bu0o7coy26rwx"]
+[gd_scene format=3 uid="uid://bu0o7coy26rwx"]
[ext_resource type="ArrayMesh" uid="uid://bqwi4qvtgjlk5" path="res://map/items/deep_fryer_basket.res" id="1_7yj46"]
-[node name="Basket" type="Node3D"]
+[node name="Basket" type="Node3D" unique_id=606292015]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1069269296]
transform = Transform3D(-0.75, 0, -6.556708e-08, 0, 0.75, 0, 6.556708e-08, 0, -0.75, 0, 0, 0)
mesh = ExtResource("1_7yj46")
diff --git a/client/map/items/bun.gd b/client/map/items/bun.gd
index 38fd582d..0423d7e6 100644
--- a/client/map/items/bun.gd
+++ b/client/map/items/bun.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/items/bun.res b/client/map/items/bun.res
index 3f1821df..ec6cbe4e 100644
--- a/client/map/items/bun.res
+++ b/client/map/items/bun.res
Binary files differ
diff --git a/client/map/items/bun.tscn b/client/map/items/bun.tscn
index 88483ee3..650a1efb 100644
--- a/client/map/items/bun.tscn
+++ b/client/map/items/bun.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://dgifus08aktx0"]
+[gd_scene format=3 uid="uid://dgifus08aktx0"]
[ext_resource type="ArrayMesh" uid="uid://ke5s5itvrqce" path="res://map/items/bun.res" id="1_limvy"]
-[node name="Bun" type="Node3D"]
+[node name="Bun" type="Node3D" unique_id=1561269631]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=338156627]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_limvy")
-skeleton = NodePath("")
diff --git a/client/map/items/burned.gd b/client/map/items/burned.gd
index 2646a551..2ed456a6 100644
--- a/client/map/items/burned.gd
+++ b/client/map/items/burned.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/items/burned.res b/client/map/items/burned.res
index 8305ca6e..3cff4081 100644
--- a/client/map/items/burned.res
+++ b/client/map/items/burned.res
Binary files differ
diff --git a/client/map/items/burned.tscn b/client/map/items/burned.tscn
index 241bbf77..a37d45b8 100644
--- a/client/map/items/burned.tscn
+++ b/client/map/items/burned.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://b48ximtiqbwvo"]
+[gd_scene format=3 uid="uid://b48ximtiqbwvo"]
[ext_resource type="ArrayMesh" uid="uid://bpndpup4f6g6v" path="res://map/items/burned.res" id="1_wu5eo"]
-[node name="Burned" type="Node3D"]
+[node name="Burned" type="Node3D" unique_id=2043673784]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1570232437]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_wu5eo")
-skeleton = NodePath("")
diff --git a/client/map/items/cheese.res b/client/map/items/cheese.res
index eac705e5..1936b0c8 100644
--- a/client/map/items/cheese.res
+++ b/client/map/items/cheese.res
Binary files differ
diff --git a/client/map/items/cheese.tscn b/client/map/items/cheese.tscn
index 515262c8..9702b324 100644
--- a/client/map/items/cheese.tscn
+++ b/client/map/items/cheese.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://0lbjf2sie4rk"]
+[gd_scene format=3 uid="uid://0lbjf2sie4rk"]
[ext_resource type="ArrayMesh" uid="uid://cshqtme8isvmw" path="res://map/items/cheese.res" id="1_p24nf"]
-[node name="Cheese" type="Node3D"]
+[node name="Cheese" type="Node3D" unique_id=93481419]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=595142792]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_p24nf")
-skeleton = NodePath("")
diff --git a/client/map/items/cheese_bit.res b/client/map/items/cheese_bit.res
new file mode 100644
index 00000000..78c32494
--- /dev/null
+++ b/client/map/items/cheese_bit.res
Binary files differ
diff --git a/client/map/items/coconut.res b/client/map/items/coconut.res
index 63778607..0719fec4 100644
--- a/client/map/items/coconut.res
+++ b/client/map/items/coconut.res
Binary files differ
diff --git a/client/map/items/coconut.tscn b/client/map/items/coconut.tscn
index 679bf9b5..19fb7b80 100644
--- a/client/map/items/coconut.tscn
+++ b/client/map/items/coconut.tscn
@@ -1,10 +1,16 @@
-[gd_scene load_steps=2 format=3 uid="uid://cmsirxgv7iqnk"]
+[gd_scene format=3 uid="uid://cmsirxgv7iqnk"]
[ext_resource type="ArrayMesh" uid="uid://djenv8k2nnqyt" path="res://map/items/coconut.res" id="1_c4upd"]
+[ext_resource type="Texture2D" uid="uid://dgcs4wkxsxe6a" path="res://map/textures/palette.png" id="2_e3g14"]
-[node name="Coconut" type="Node3D"]
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_qtcu3"]
+resource_name = "Material.001"
+cull_mode = 2
+albedo_texture = ExtResource("2_e3g14")
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Coconut" type="Node3D" unique_id=1082368642]
+
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1732359079]
transform = Transform3D(0.2, 0, 0, 0, 0.2, 0, 0, 0, 0.2, 0, 0.2, 0)
mesh = ExtResource("1_c4upd")
-skeleton = NodePath("")
+surface_material_override/0 = SubResource("StandardMaterial3D_qtcu3")
diff --git a/client/map/items/cooked_cheese_pizza.tscn b/client/map/items/cooked_cheese_pizza.tscn
new file mode 100644
index 00000000..de677b2a
--- /dev/null
+++ b/client/map/items/cooked_cheese_pizza.tscn
@@ -0,0 +1,33 @@
+[gd_scene format=3 uid="uid://cl1etmr26p262"]
+
+[ext_resource type="ArrayMesh" uid="uid://cwstqugiw76tc" path="res://map/items/pizza.res" id="1_vnyro"]
+
+[sub_resource type="Gradient" id="Gradient_xogo6"]
+offsets = PackedFloat32Array(0, 0.14086306, 0.84237576, 1)
+colors = PackedColorArray(0.52, 0.104000024, 0, 1, 0.7294118, 0.23921569, 0.11764706, 1, 1, 0.7391868, 0.13702077, 1, 1, 0.88600004, 0.43, 1)
+
+[sub_resource type="FastNoiseLite" id="FastNoiseLite_7am5t"]
+frequency = 0.0139
+fractal_octaves = 3
+fractal_gain = 0.2
+
+[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_gf4r2"]
+width = 256
+height = 256
+noise = SubResource("FastNoiseLite_7am5t")
+color_ramp = SubResource("Gradient_xogo6")
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_vnyro"]
+resource_name = "Material.001"
+cull_mode = 2
+albedo_texture = SubResource("NoiseTexture2D_gf4r2")
+uv1_scale = Vector3(0.5, 0.5, 0.5)
+uv1_offset = Vector3(0.5, 0, 0.5)
+uv1_triplanar = true
+
+[node name="CookedCheesePizza" type="Node3D" unique_id=1618397990]
+
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=2039708425]
+transform = Transform3D(0.3, 0, 0, 0, 0.05, 0, 0, 0, 0.3, 0, 0.05, 0)
+mesh = ExtResource("1_vnyro")
+surface_material_override/1 = SubResource("StandardMaterial3D_vnyro")
diff --git a/client/map/items/cooked_noodles.res b/client/map/items/cooked_noodles.res
index f98b4976..4ba4012c 100644
--- a/client/map/items/cooked_noodles.res
+++ b/client/map/items/cooked_noodles.res
Binary files differ
diff --git a/client/map/items/cooked_noodles.tscn b/client/map/items/cooked_noodles.tscn
index 419e5eaa..895e1edd 100644
--- a/client/map/items/cooked_noodles.tscn
+++ b/client/map/items/cooked_noodles.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://ct4f8jtnvfn56"]
+[gd_scene format=3 uid="uid://ct4f8jtnvfn56"]
[ext_resource type="ArrayMesh" uid="uid://cwhr8luqwpo7a" path="res://map/items/cooked_noodles.res" id="1_ahfxi"]
-[node name="CookedNoodles" type="Node3D"]
+[node name="CookedNoodles" type="Node3D" unique_id=663842765]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=675901793]
transform = Transform3D(0.378, 0, 0, 0, 0.378, 0, 0, 0, 0.378, -0.027, 0, 0.095)
mesh = ExtResource("1_ahfxi")
-skeleton = NodePath("")
diff --git a/client/map/items/cooked_rice_fill.tscn b/client/map/items/cooked_rice_fill.tscn
index 825e1f63..d55ee61e 100644
--- a/client/map/items/cooked_rice_fill.tscn
+++ b/client/map/items/cooked_rice_fill.tscn
@@ -1,14 +1,14 @@
-[gd_scene load_steps=3 format=3 uid="uid://c17tdqcs3a33i"]
+[gd_scene format=3 uid="uid://c17tdqcs3a33i"]
[ext_resource type="PackedScene" uid="uid://do4qxd1d1x7cc" path="res://map/items/rice_content.tscn" id="1_mteor"]
-[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_vr3i3"]
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_wuevv"]
resource_local_to_scene = true
albedo_color = Color(0.933333, 0.933333, 0.666667, 1)
-[node name="CookedRiceFIll" type="Node3D"]
+[node name="CookedRiceFIll" type="Node3D" unique_id=1097928494]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
-[node name="RiceContent" parent="." instance=ExtResource("1_mteor")]
+[node name="RiceContent" parent="." unique_id=1357077206 instance=ExtResource("1_mteor")]
transform = Transform3D(0.3, 0, 0, 0, 0.15, 0, 0, 0, 0.562, 0.194, 0.07, 0)
-surface_material_override/0 = SubResource("StandardMaterial3D_vr3i3")
+surface_material_override/0 = SubResource("StandardMaterial3D_wuevv")
diff --git a/client/map/items/cut.tscn b/client/map/items/cut.tscn
index d465d788..69fad628 100644
--- a/client/map/items/cut.tscn
+++ b/client/map/items/cut.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=5 format=3 uid="uid://bbjair4iw1841"]
+[gd_scene format=3 uid="uid://bbjair4iw1841"]
[sub_resource type="Curve" id="Curve_3m5vp"]
_data = [Vector2(0, 0), 0.0, 9.741706, 0, 0, Vector2(0.24820146, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), -1.9750195, 0.0, 0, 0]
@@ -20,7 +20,7 @@ curve = SubResource("Curve_3m5vp")
_data = [Vector2(0.7027972, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
point_count = 2
-[node name="Cut" type="CPUParticles3D"]
+[node name="Cut" type="CPUParticles3D" unique_id=1642709239]
cast_shadow = 0
emitting = false
amount = 15
diff --git a/client/map/items/cuttable.gd b/client/map/items/cuttable.gd
index e106a96d..4eb48e19 100644
--- a/client/map/items/cuttable.gd
+++ b/client/map/items/cuttable.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/items/deep_fryer_basket.res b/client/map/items/deep_fryer_basket.res
index 40f1c05d..f31999e7 100644
--- a/client/map/items/deep_fryer_basket.res
+++ b/client/map/items/deep_fryer_basket.res
Binary files differ
diff --git a/client/map/items/deep_frying.tscn b/client/map/items/deep_frying.tscn
index 81a4ccfb..1cf5de19 100644
--- a/client/map/items/deep_frying.tscn
+++ b/client/map/items/deep_frying.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=3 format=3 uid="uid://c2g5ncvn45263"]
+[gd_scene format=3 uid="uid://c2g5ncvn45263"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_3xkdk"]
albedo_color = Color(0.9153118, 0.62961817, 0.44200557, 1)
@@ -9,7 +9,7 @@ material = SubResource("StandardMaterial3D_3xkdk")
radius = 0.1
height = 0.2
-[node name="DeepFrying" type="CPUParticles3D"]
+[node name="DeepFrying" type="CPUParticles3D" unique_id=1522889960]
emitting = false
mesh = SubResource("SphereMesh_iygiy")
emission_shape = 6
diff --git a/client/map/items/dirt.res b/client/map/items/dirt.res
index 3043f8d8..a9b64efe 100644
--- a/client/map/items/dirt.res
+++ b/client/map/items/dirt.res
Binary files differ
diff --git a/client/map/items/dirt.tscn b/client/map/items/dirt.tscn
index 18956b3d..e3d1cdc1 100644
--- a/client/map/items/dirt.tscn
+++ b/client/map/items/dirt.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://cluraed43qoeb"]
+[gd_scene format=3 uid="uid://cluraed43qoeb"]
[ext_resource type="ArrayMesh" uid="uid://dla7bxb6byk48" path="res://map/items/dirt.res" id="1_xmsre"]
-[node name="Dirt" type="Node3D"]
+[node name="Dirt" type="Node3D" unique_id=913711020]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=114452767]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, -0.015, 0)
mesh = ExtResource("1_xmsre")
-skeleton = NodePath("")
diff --git a/client/map/items/donut/donut-dough.res b/client/map/items/donut/donut-dough.res
new file mode 100644
index 00000000..cae6e975
--- /dev/null
+++ b/client/map/items/donut/donut-dough.res
Binary files differ
diff --git a/client/map/items/donut/donut-glaze.res b/client/map/items/donut/donut-glaze.res
new file mode 100644
index 00000000..6a8dac5b
--- /dev/null
+++ b/client/map/items/donut/donut-glaze.res
Binary files differ
diff --git a/client/map/items/donut/donut.tscn b/client/map/items/donut/donut.tscn
new file mode 100644
index 00000000..6815828c
--- /dev/null
+++ b/client/map/items/donut/donut.tscn
@@ -0,0 +1,11 @@
+[gd_scene format=3 uid="uid://cvnkxd1tslqvf"]
+
+[ext_resource type="ArrayMesh" uid="uid://cy1ifpobr21c0" path="res://map/items/donut/donut-dough.res" id="1_65l5f"]
+[ext_resource type="Material" uid="uid://cg7o7rn06bve1" path="res://map/items/dough_material.tres" id="2_65l5f"]
+
+[node name="Donut" type="Node3D" unique_id=517668687]
+
+[node name="Dough" type="MeshInstance3D" parent="." unique_id=697273469]
+transform = Transform3D(0.35, 0, 0, 0, 0.35, 0, 0, 0, 0.35, 0, 0, 0)
+mesh = ExtResource("1_65l5f")
+surface_material_override/0 = ExtResource("2_65l5f")
diff --git a/client/map/items/donut/glazed-donut.tscn b/client/map/items/donut/glazed-donut.tscn
new file mode 100644
index 00000000..913a9ab5
--- /dev/null
+++ b/client/map/items/donut/glazed-donut.tscn
@@ -0,0 +1,14 @@
+[gd_scene format=3 uid="uid://dglrxvp3126g4"]
+
+[ext_resource type="ArrayMesh" uid="uid://cy1ifpobr21c0" path="res://map/items/donut/donut-dough.res" id="1_1ef7l"]
+[ext_resource type="ArrayMesh" uid="uid://dauwp2akjkafa" path="res://map/items/donut/donut-glaze.res" id="2_1jama"]
+
+[node name="Donut" type="Node3D" unique_id=1096172423]
+
+[node name="Dough" type="MeshInstance3D" parent="." unique_id=218737516]
+transform = Transform3D(0.35, 0, 0, 0, 0.35, 0, 0, 0, 0.35, 0, 0, 0)
+mesh = ExtResource("1_1ef7l")
+
+[node name="Glaze" type="MeshInstance3D" parent="." unique_id=267596717]
+transform = Transform3D(0.35, 0, 0, 0, 0.35, 0, 0, 0, 0.35, 0, 0, 0)
+mesh = ExtResource("2_1jama")
diff --git a/client/map/items/dough.res b/client/map/items/dough.res
index 9ccb0c48..7df7ca56 100644
--- a/client/map/items/dough.res
+++ b/client/map/items/dough.res
Binary files differ
diff --git a/client/map/items/dough.tscn b/client/map/items/dough.tscn
index 73f8c494..6ffec7a5 100644
--- a/client/map/items/dough.tscn
+++ b/client/map/items/dough.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://dw5gdtilcsdcc"]
+[gd_scene format=3 uid="uid://dw5gdtilcsdcc"]
[ext_resource type="ArrayMesh" uid="uid://duv7fs8jmwjn5" path="res://map/items/dough.res" id="1_fe02r"]
-[node name="Dough" type="Node3D"]
+[node name="Dough" type="Node3D" unique_id=1817119001]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1090567646]
transform = Transform3D(0.4, 0, 0, 0, 0.4, 0, 0, 0, 0.4, 0, 0, 0)
mesh = ExtResource("1_fe02r")
-skeleton = NodePath("")
diff --git a/client/map/items/fish.res b/client/map/items/fish.res
index 65f099bb..e75acfb0 100644
--- a/client/map/items/fish.res
+++ b/client/map/items/fish.res
Binary files differ
diff --git a/client/map/items/fish.tscn b/client/map/items/fish.tscn
index 2ca59cf9..6ec64459 100644
--- a/client/map/items/fish.tscn
+++ b/client/map/items/fish.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://dom5n7h7l7sr8"]
+[gd_scene format=3 uid="uid://dom5n7h7l7sr8"]
[ext_resource type="ArrayMesh" uid="uid://dgsvwyghdj0es" path="res://map/items/fish.res" id="1_ysgnj"]
-[node name="Fish" type="Node3D"]
+[node name="Fish" type="Node3D" unique_id=291512971]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=120424767]
transform = Transform3D(-4.37114e-10, 0.01, 0, -0.01, -4.37114e-10, 0, 0, 0, 0.01, 0, 0.0754571, 0)
mesh = ExtResource("1_ysgnj")
-skeleton = NodePath("")
diff --git a/client/map/items/flour.res b/client/map/items/flour.res
index 19f2db82..f04dd757 100644
--- a/client/map/items/flour.res
+++ b/client/map/items/flour.res
Binary files differ
diff --git a/client/map/items/flour.tscn b/client/map/items/flour.tscn
index c283eae5..6557cd24 100644
--- a/client/map/items/flour.tscn
+++ b/client/map/items/flour.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://dgo8cknr1o6ml"]
+[gd_scene format=3 uid="uid://dgo8cknr1o6ml"]
[ext_resource type="ArrayMesh" uid="uid://b76c6o88lkei2" path="res://map/items/flour.res" id="1_55ndm"]
-[node name="Flour" type="Node3D"]
+[node name="Flour" type="Node3D" unique_id=540926944]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=191664914]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_55ndm")
-skeleton = NodePath("")
diff --git a/client/map/items/food_processor.gd b/client/map/items/food_processor.gd
index 0a78904f..fab8bd48 100644
--- a/client/map/items/food_processor.gd
+++ b/client/map/items/food_processor.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -16,7 +16,6 @@
class_name FoodProcessor
extends Item
-var time := 0.
var processing: CPUParticles3D = load("res://map/items/processing.tscn").instantiate()
func _init(owned_by_: Node3D):
@@ -25,6 +24,8 @@ func _init(owned_by_: Node3D):
add_child(load("res://map/items/food_processor.tscn").instantiate())
add_child(processing)
+func is_round(): return false
+
func add_contents(contents: Array[String]):
for i in contents:
match i:
@@ -34,36 +35,40 @@ func add_contents(contents: Array[String]):
add_child(FoodProcessorFill.new(self, Color(1.,1.,.8)))
"rice":
processing.color = Color(1.,1.,.8)
- base.add_child(load("res://map/items/rice.tscn").instantiate())
+ super([i])
"flour":
processing.color = Color(.9, .9, .9)
- base.add_child(load("res://map/items/flour.tscn").instantiate())
+ super([i])
+ "mushroom":
+ processing.color = Color(0.596, 0.341, 0.259)
+ super([i])
"dough":
add_child(FoodProcessorFill.new(self, Color8(200, 180, 160)))
"coconut":
add_child(FoodProcessorFill.new(self, Color(.8, .5, .4)))
- base.add_child(load("res://map/items/coconut.tscn").instantiate())
+ super([i])
"strawberry":
processing.color = Color(.9, .0, .0)
- base.add_child(load("res://map/items/strawberry.tscn").instantiate())
+ super([i])
"strawberry-shake":
add_child(FoodProcessorFill.new(self, Color8(250, 140, 180)))
"strawberry-icecream":
add_child(FoodProcessorFill.new(self, Color8(250, 180, 210)))
"strawberry-puree":
add_child(FoodProcessorFill.new(self, Color8(200, 80, 80)))
+ "processed-mushroom":
+ add_child(FoodProcessorFill.new(self, Color(0.596, 0.341, 0.259)))
"tomato":
processing.color = Color(1.,0.,0.)
- base.add_child(load("res://map/items/tomato.tscn").instantiate())
+ super([i])
"tomato-juice":
add_child(FoodProcessorFill.new(self, Color(1., .0, .0)))
_: super([i])
func _process(delta: float):
super(delta)
- time += delta
- processing.rotation.y += time * TAU
- base.rotation.y += time * TAU
+ processing.rotation.y += delta * TAU * 10
+ base.rotation.y += delta * TAU * 15
func progress(position_: float, speed: float, warn: bool):
super(position_, speed, warn)
diff --git a/client/map/items/food_processor.res b/client/map/items/food_processor.res
index 726a7868..3b85f78b 100644
--- a/client/map/items/food_processor.res
+++ b/client/map/items/food_processor.res
Binary files differ
diff --git a/client/map/items/food_processor.tscn b/client/map/items/food_processor.tscn
index bb95d580..8082930a 100644
--- a/client/map/items/food_processor.tscn
+++ b/client/map/items/food_processor.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://daxjpvycs85ec"]
+[gd_scene format=3 uid="uid://daxjpvycs85ec"]
[ext_resource type="ArrayMesh" uid="uid://bpjl5dlst6yg" path="res://map/items/food_processor.res" id="1_65ilg"]
-[node name="FoodProcessor" type="Node3D"]
+[node name="FoodProcessor" type="Node3D" unique_id=1181054569]
-[node name="FoodProcessor" type="MeshInstance3D" parent="."]
+[node name="FoodProcessor" type="MeshInstance3D" parent="." unique_id=68402722]
transform = Transform3D(0.15, 0, 0, 0, 0.15, 0, 0, 0, 0.15, 0, 0.3, 0)
mesh = ExtResource("1_65ilg")
-skeleton = NodePath("")
diff --git a/client/map/items/food_processor_fill.gd b/client/map/items/food_processor_fill.gd
index 25d634da..ed695a99 100644
--- a/client/map/items/food_processor_fill.gd
+++ b/client/map/items/food_processor_fill.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/items/food_processor_fill.res b/client/map/items/food_processor_fill.res
index 7511cc75..46dc32a0 100644
--- a/client/map/items/food_processor_fill.res
+++ b/client/map/items/food_processor_fill.res
Binary files differ
diff --git a/client/map/items/food_processor_fill.tscn b/client/map/items/food_processor_fill.tscn
index fa85e40a..21d74c57 100644
--- a/client/map/items/food_processor_fill.tscn
+++ b/client/map/items/food_processor_fill.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=3 format=3 uid="uid://di5nq2vgvostp"]
+[gd_scene format=3 uid="uid://di5nq2vgvostp"]
[ext_resource type="ArrayMesh" uid="uid://vkd0ty7khthl" path="res://map/items/food_processor_fill.res" id="1_tcr3k"]
@@ -6,8 +6,7 @@
resource_local_to_scene = true
cull_mode = 1
-[node name="FoodProcessorFill" type="MeshInstance3D"]
+[node name="FoodProcessorFill" type="MeshInstance3D" unique_id=2135483159]
transform = Transform3D(0.15, 0, 0, 0, 0.15, 0, 0, 0, 0.15, 0, 0.3, 0)
mesh = ExtResource("1_tcr3k")
-skeleton = NodePath("")
surface_material_override/0 = SubResource("StandardMaterial3D_0xb6r")
diff --git a/client/map/items/french_fries.res b/client/map/items/french_fries.res
index 8019c006..2c312e36 100644
--- a/client/map/items/french_fries.res
+++ b/client/map/items/french_fries.res
Binary files differ
diff --git a/client/map/items/french_fries_basket.tscn b/client/map/items/french_fries_basket.tscn
index 516efe0a..71ce3676 100644
--- a/client/map/items/french_fries_basket.tscn
+++ b/client/map/items/french_fries_basket.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://dfxksiofrs477"]
+[gd_scene format=3 uid="uid://dfxksiofrs477"]
[ext_resource type="ArrayMesh" uid="uid://b4ayvyhakbe7t" path="res://map/items/french_fries.res" id="1_skqej"]
-[node name="FrenchFriesBasket" type="Node3D"]
+[node name="FrenchFriesBasket" type="Node3D" unique_id=1793149830]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=972639015]
transform = Transform3D(0.75, 0, 0, 0, 0.75, 0, 0, 0, 0.75, 0, 0, -0.112)
mesh = ExtResource("1_skqej")
-skeleton = NodePath("")
diff --git a/client/map/items/french_fries_fill.res b/client/map/items/french_fries_fill.res
index f9bd5e0a..e7b78a46 100644
--- a/client/map/items/french_fries_fill.res
+++ b/client/map/items/french_fries_fill.res
Binary files differ
diff --git a/client/map/items/french_fries_fill.tscn b/client/map/items/french_fries_fill.tscn
index 10684f67..8c98cfe7 100644
--- a/client/map/items/french_fries_fill.tscn
+++ b/client/map/items/french_fries_fill.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://buxshcsyokc3y"]
+[gd_scene format=3 uid="uid://buxshcsyokc3y"]
[ext_resource type="ArrayMesh" uid="uid://cl5aobuv0duao" path="res://map/items/french_fries_fill.res" id="1_bt0td"]
-[node name="FrenchFriesFill" type="Node3D"]
+[node name="FrenchFriesFill" type="Node3D" unique_id=87677793]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=802219019]
transform = Transform3D(-0.64, 0, -5.5950576e-08, 0, 0.64, 0, 5.5950576e-08, 0, -0.64, 0.01, -0.031, 0.025)
mesh = ExtResource("1_bt0td")
-skeleton = NodePath("")
diff --git a/client/map/items/generic_item.gd b/client/map/items/generic_item.gd
index 5f101646..e20385ef 100644
--- a/client/map/items/generic_item.gd
+++ b/client/map/items/generic_item.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/items/glass.gd b/client/map/items/glass.gd
index b9582a3a..8b0208e1 100644
--- a/client/map/items/glass.gd
+++ b/client/map/items/glass.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/items/glass.res b/client/map/items/glass.res
index 8386865f..400ca1cd 100644
--- a/client/map/items/glass.res
+++ b/client/map/items/glass.res
Binary files differ
diff --git a/client/map/items/glass.tscn b/client/map/items/glass.tscn
index 29bdda8b..877946a2 100644
--- a/client/map/items/glass.tscn
+++ b/client/map/items/glass.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://c875kaj4v7nfv"]
+[gd_scene format=3 uid="uid://c875kaj4v7nfv"]
[ext_resource type="ArrayMesh" uid="uid://dywkxdkny1urs" path="res://map/items/glass.res" id="1_v2eeu"]
-[node name="Glass" type="Node3D"]
+[node name="Glass" type="Node3D" unique_id=1014845055]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1301902472]
transform = Transform3D(0.125, 0, 0, 0, 0.125, 0, 0, 0, 0.125, 0, 0.125, 0)
mesh = ExtResource("1_v2eeu")
-skeleton = NodePath("")
diff --git a/client/map/items/glass_fill.gd b/client/map/items/glass_fill.gd
index 27cceb1f..4331965d 100644
--- a/client/map/items/glass_fill.gd
+++ b/client/map/items/glass_fill.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/items/glass_fill.res b/client/map/items/glass_fill.res
index 8226fb04..4845b3da 100644
--- a/client/map/items/glass_fill.res
+++ b/client/map/items/glass_fill.res
Binary files differ
diff --git a/client/map/items/glass_fill.tscn b/client/map/items/glass_fill.tscn
index dbcc1a61..a33d77de 100644
--- a/client/map/items/glass_fill.tscn
+++ b/client/map/items/glass_fill.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=3 format=3 uid="uid://dvdwxct8qu2fm"]
+[gd_scene format=3 uid="uid://dvdwxct8qu2fm"]
[ext_resource type="ArrayMesh" uid="uid://byebq6oifi2jk" path="res://map/items/glass_fill.res" id="1_apxu2"]
@@ -8,9 +8,8 @@ resource_name = "Material.002"
cull_mode = 2
metallic_specular = 0.0
-[node name="GlassFill" type="MeshInstance3D"]
+[node name="GlassFill" type="MeshInstance3D" unique_id=652949023]
transform = Transform3D(0.125, 0, 0, 0, 0.125, 0, 0, 0, 0.125, 0, 0.125, 0)
lod_bias = 3.0
mesh = ExtResource("1_apxu2")
-skeleton = NodePath("")
surface_material_override/0 = SubResource("StandardMaterial3D_g0wwk")
diff --git a/client/map/items/glass_items.gd b/client/map/items/glass_items.gd
index 970b25d1..b3a5542b 100644
--- a/client/map/items/glass_items.gd
+++ b/client/map/items/glass_items.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/items/icecream.gd b/client/map/items/icecream.gd
index 19e3c91d..c29f6ef3 100644
--- a/client/map/items/icecream.gd
+++ b/client/map/items/icecream.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/items/icecream.res b/client/map/items/icecream.res
index af888a45..1d867b07 100644
--- a/client/map/items/icecream.res
+++ b/client/map/items/icecream.res
Binary files differ
diff --git a/client/map/items/icecream.tscn b/client/map/items/icecream.tscn
index 97eb32cf..d727e0c7 100644
--- a/client/map/items/icecream.tscn
+++ b/client/map/items/icecream.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=5 format=4 uid="uid://c7peyvvr7rgko"]
+[gd_scene format=4 uid="uid://c7peyvvr7rgko"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_fah5o"]
resource_name = "Sprinkles"
@@ -67,8 +67,7 @@ resource_name = "Ice"
cull_mode = 2
roughness = 0.690035
-[node name="IceCream" type="MeshInstance3D"]
+[node name="IceCream" type="MeshInstance3D" unique_id=1714074191]
transform = Transform3D(0.6, 0, 0, 0, 0.6, 0, 0, 0, 0.6, 0, 0.2, 0)
mesh = SubResource("ArrayMesh_vb1ms")
-skeleton = NodePath("")
surface_material_override/1 = SubResource("StandardMaterial3D_2ckef")
diff --git a/client/map/items/item.gd b/client/map/items/item.gd
index 39c7afc1..bad9c7cf 100644
--- a/client/map/items/item.gd
+++ b/client/map/items/item.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -58,30 +58,35 @@ func _init(owned_by_: Node3D):
add_child(base)
owned_by = owned_by_
+# is_round is used to determine if the cursor should be rotated to match the
+# item's rotation (rotate if it's not round)
+func is_round(): return true
+
func add_contents(contents: Array[String]):
for i in contents:
- match i:
- _:
- base.add_child(ItemFactory.produce(i, self))
+ base.add_child(ItemFactory.produce(i, self))
func animate_spawn():
creation_timer = 0.0
scale = Vector3.ONE * 0.001 # setting to zero breaks assertions somewhere in the engine
func _process(delta):
- if not is_instance_valid(owned_by): return
- if owned_by.get_parent() is Item or owned_by is Item: return
- var player_owned = owned_by.get_parent().get_parent() is Player
- player_owned_timer = player_owned_timer + delta if player_owned else 0.
- var anim_speed = 10.0 * exp(player_owned_timer * 3.0) # infinity is fine. G.interpolate can handle it
- position = G.interpolate(position, position_target, delta * anim_speed)
- rotation.y = G.interpolate_angle(rotation.y, rotation_target, delta * anim_speed)
+ # Update position
+ if is_instance_valid(owned_by):
+ if owned_by.get_parent() is Item or owned_by is Item: return
+ var player_owned = owned_by.get_parent().get_parent() is Player
+ player_owned_timer = player_owned_timer + delta if player_owned else 0.
+ var anim_speed = 10.0 * exp(player_owned_timer * 3.0) # infinity is fine. G.interpolate can handle it
+ position = G.interpolate(position, position_target, delta * anim_speed)
+ rotation.y = G.interpolate_angle(rotation.y, rotation_target, delta * anim_speed)
+ # Fade in
if creation_timer != null:
creation_timer += delta * 10.0
if creation_timer > 1:
scale = Vector3.ONE
creation_timer = null
else: scale = Vector3.ONE * creation_timer
+ # Fade out
if destroy_timeout != null:
destroy_timeout -= delta * 5.0
if is_instance_valid(progress_instance): progress_instance.hide()
diff --git a/client/map/items/leek.res b/client/map/items/leek.res
index 16c45f6f..3fcafcd2 100644
--- a/client/map/items/leek.res
+++ b/client/map/items/leek.res
Binary files differ
diff --git a/client/map/items/leek.tscn b/client/map/items/leek.tscn
index 4967246a..cd70ffa5 100644
--- a/client/map/items/leek.tscn
+++ b/client/map/items/leek.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://cmpwfkdnrm6e6"]
+[gd_scene format=3 uid="uid://cmpwfkdnrm6e6"]
[ext_resource type="ArrayMesh" uid="uid://cix4ji823kitw" path="res://map/items/leek.res" id="1_sum7m"]
-[node name="Leek" type="Node3D"]
+[node name="Leek" type="Node3D" unique_id=490278594]
-[node name="leek" type="MeshInstance3D" parent="."]
+[node name="leek" type="MeshInstance3D" parent="." unique_id=1208900817]
transform = Transform3D(-4.371139e-08, 0.75, -4.371139e-08, 0, -3.278354e-08, -1, -1, -3.278354e-08, 1.9106855e-15, -0.25, 0.1, 0)
mesh = ExtResource("1_sum7m")
-skeleton = NodePath("")
diff --git a/client/map/items/lettuce.res b/client/map/items/lettuce.res
index 0ae1a660..066494fe 100644
--- a/client/map/items/lettuce.res
+++ b/client/map/items/lettuce.res
Binary files differ
diff --git a/client/map/items/lettuce.tscn b/client/map/items/lettuce.tscn
index c4ca7cb9..35f4aeb2 100644
--- a/client/map/items/lettuce.tscn
+++ b/client/map/items/lettuce.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://cuf8vwqk6xujk"]
+[gd_scene format=3 uid="uid://cuf8vwqk6xujk"]
[ext_resource type="ArrayMesh" uid="uid://cyomlupimgm43" path="res://map/items/lettuce.res" id="1_axcdp"]
-[node name="Lettuce" type="Node3D"]
+[node name="Lettuce" type="Node3D" unique_id=337328089]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1106316228]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_axcdp")
-skeleton = NodePath("")
diff --git a/client/map/items/lettuce_crate.gd.uid b/client/map/items/lettuce_crate.gd.uid
deleted file mode 100644
index d206a1e3..00000000
--- a/client/map/items/lettuce_crate.gd.uid
+++ /dev/null
@@ -1 +0,0 @@
-uid://b3oxc5pyij02s
diff --git a/client/map/items/mochi.gd b/client/map/items/mochi.gd
index 9ec98658..dc3a860d 100644
--- a/client/map/items/mochi.gd
+++ b/client/map/items/mochi.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/items/mochi.res b/client/map/items/mochi.res
index d9a4a97b..63af04da 100644
--- a/client/map/items/mochi.res
+++ b/client/map/items/mochi.res
Binary files differ
diff --git a/client/map/items/mochi.tscn b/client/map/items/mochi.tscn
index aaf20af6..0d9ed7e7 100644
--- a/client/map/items/mochi.tscn
+++ b/client/map/items/mochi.tscn
@@ -1,11 +1,10 @@
-[gd_scene load_steps=3 format=3 uid="uid://2warur3hlxao"]
+[gd_scene format=3 uid="uid://2warur3hlxao"]
[ext_resource type="ArrayMesh" uid="uid://c3s71kxt7nhfb" path="res://map/items/mochi.res" id="1_ygb5f"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_c143l"]
-[node name="Mochi" type="MeshInstance3D"]
+[node name="Mochi" type="MeshInstance3D" unique_id=1419288615]
transform = Transform3D(0.15, 0, 0, 0, 0.104, 0, 0, 0, 0.15, 0, 0.075, 0)
mesh = ExtResource("1_ygb5f")
-skeleton = NodePath("")
surface_material_override/0 = SubResource("StandardMaterial3D_c143l")
diff --git a/client/map/items/mushroom.res b/client/map/items/mushroom.res
index ad8dbc46..d4ce1bc1 100644
--- a/client/map/items/mushroom.res
+++ b/client/map/items/mushroom.res
Binary files differ
diff --git a/client/map/items/mushroom.tscn b/client/map/items/mushroom.tscn
index 7c8ab942..ec3237bb 100644
--- a/client/map/items/mushroom.tscn
+++ b/client/map/items/mushroom.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://cc0jqiiywrrc0"]
+[gd_scene format=3 uid="uid://cc0jqiiywrrc0"]
[ext_resource type="ArrayMesh" uid="uid://fmglxabrvyld" path="res://map/items/mushroom.res" id="1_3saxa"]
-[node name="Mushroom" type="Node3D"]
+[node name="Mushroom" type="Node3D" unique_id=513538861]
-[node name="Mesh" type="MeshInstance3D" parent="."]
-transform = Transform3D(1.7207295, 5.5918704e-08, 2.4574564, 2.4574564, -1.07418835e-07, -1.7207295, 5.5918697e-08, 3.0000005, -1.0741883e-07, 0.125, 0.035, 0)
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1807329182]
+transform = Transform3D(1.2167394, -2.1213207, 1.7376841, 2.4574564, -1.07418835e-07, -1.7207295, 1.2167397, 2.1213207, 1.7376841, 0.125, 0.035, 0.125)
mesh = ExtResource("1_3saxa")
-skeleton = NodePath("")
diff --git a/client/map/items/mushroom_plate_fill.tscn b/client/map/items/mushroom_plate_fill.tscn
new file mode 100644
index 00000000..5c4f20bc
--- /dev/null
+++ b/client/map/items/mushroom_plate_fill.tscn
@@ -0,0 +1,17 @@
+[gd_scene format=3 uid="uid://dvh0w2l8ly53e"]
+
+[ext_resource type="PackedScene" uid="uid://da3d6rgfss3su" path="res://map/items/pizza/mushroom_slice.tscn" id="1_iihb3"]
+
+[node name="MushroomPlateTopping" type="Node3D" unique_id=764525280]
+
+[node name="CookedMushroomSlice" parent="." unique_id=397861394 instance=ExtResource("1_iihb3")]
+transform = Transform3D(-0.53290087, 0.09379602, 0.8409631, 0.111597665, 0.9929469, -0.040030282, -0.8387864, 0.07251734, -0.5396097, 0.083272, 0.020344693, -0.06993499)
+
+[node name="CookedMushroomSlice2" parent="." unique_id=913110476 instance=ExtResource("1_iihb3")]
+transform = Transform3D(0.8638758, -0.24161705, 0.44197255, 0.2151002, 0.97037166, 0.11004867, -0.45546728, 0, 0.89025253, -0.06327816, 0.024188552, -0.060519822)
+
+[node name="CookedMushroomSlice3" parent="." unique_id=653241564 instance=ExtResource("1_iihb3")]
+transform = Transform3D(-0.95794797, -0.20063338, 0.20513889, -0.19618548, 0.9796664, 0.04201196, -0.20939668, 0, -0.97783077, 0.08738138, 0.020179842, 0.036596574)
+
+[node name="CookedMushroomSlice4" parent="." unique_id=1676048566 instance=ExtResource("1_iihb3")]
+transform = Transform3D(0.8235921, 0, -0.5671827, -0.12658499, 0.9747768, -0.18381096, 0.5528766, 0.2231821, 0.8028185, -0.08654484, 0.023021702, 0.08201364)
diff --git a/client/map/items/nigiri.res b/client/map/items/nigiri.res
index ffe47e3e..bd64e3d1 100644
--- a/client/map/items/nigiri.res
+++ b/client/map/items/nigiri.res
Binary files differ
diff --git a/client/map/items/nigiri.tscn b/client/map/items/nigiri.tscn
index 0a616eed..25e0324c 100644
--- a/client/map/items/nigiri.tscn
+++ b/client/map/items/nigiri.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://d34n41tk304ey"]
+[gd_scene format=3 uid="uid://d34n41tk304ey"]
[ext_resource type="ArrayMesh" uid="uid://g2ko273otndc" path="res://map/items/nigiri.res" id="1_my3m1"]
-[node name="Nigiri" type="Node3D"]
+[node name="Nigiri" type="Node3D" unique_id=713001924]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=916811039]
transform = Transform3D(0.144, 0, 0, 0, -2.27299e-09, -0.073, 0, 0.052, -3.19093e-09, 0, 0.1, 0)
mesh = ExtResource("1_my3m1")
-skeleton = NodePath("")
diff --git a/client/map/items/noodles.res b/client/map/items/noodles.res
index 9f8d6347..1a5013bb 100644
--- a/client/map/items/noodles.res
+++ b/client/map/items/noodles.res
Binary files differ
diff --git a/client/map/items/noodles.tscn b/client/map/items/noodles.tscn
index cad0b17b..37d59dcd 100644
--- a/client/map/items/noodles.tscn
+++ b/client/map/items/noodles.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://cfc4wyxsgtnuy"]
+[gd_scene format=3 uid="uid://cfc4wyxsgtnuy"]
[ext_resource type="ArrayMesh" uid="uid://c7nmboj44jn7a" path="res://map/items/noodles.res" id="1_7j6yk"]
-[node name="Noodles" type="Node3D"]
+[node name="Noodles" type="Node3D" unique_id=32514619]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1535551693]
transform = Transform3D(0.378, 0, 0, 0, 0.378, 0, 0, 0, 0.378, -0.027, 0, 0.095)
mesh = ExtResource("1_7j6yk")
-skeleton = NodePath("")
diff --git a/client/map/items/noodles_cheese_fill.tscn b/client/map/items/noodles_cheese_fill.tscn
new file mode 100644
index 00000000..fb5c10d9
--- /dev/null
+++ b/client/map/items/noodles_cheese_fill.tscn
@@ -0,0 +1,25 @@
+[gd_scene format=3 uid="uid://3l14rutbc6ma"]
+
+[ext_resource type="ArrayMesh" uid="uid://68yn4bguhuq3" path="res://map/items/cheese_bit.res" id="1_1dqn5"]
+
+[node name="NoodlesCheeseFill" type="Node3D" unique_id=1485282420]
+
+[node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=73653329]
+transform = Transform3D(0.5177467, -0.21455958, -0.6909487, -0.07600415, 0.9169244, -0.38597953, 0.53727245, 0.33647275, 0.61123633, -0.125, 0.108, 0.096)
+mesh = ExtResource("1_1dqn5")
+
+[node name="MeshInstance3D5" type="MeshInstance3D" parent="." unique_id=1909498497]
+transform = Transform3D(0.74895734, 0.019033965, -0.049147546, -0.013184706, 0.9993994, 0.029855367, 0.037264794, -0.028949905, 0.9983451, -0.009, 0.165, -0.025)
+mesh = ExtResource("1_1dqn5")
+
+[node name="MeshInstance3D2" type="MeshInstance3D" parent="." unique_id=833722459]
+transform = Transform3D(0.6929721, 0.34747887, 0.1598467, -0.22719976, 0.9199635, -0.24879485, -0.17512806, 0.18145435, 0.9552748, 0.071, 0.113, 0.078)
+mesh = ExtResource("1_1dqn5")
+
+[node name="MeshInstance3D3" type="MeshInstance3D" parent="." unique_id=1585980071]
+transform = Transform3D(0.47207838, 0.50925, -0.58691764, -0.11057563, 0.81986195, 0.5532535, 0.57220167, -0.26170707, 0.5911329, 0.105, 0.113, -0.09)
+mesh = ExtResource("1_1dqn5")
+
+[node name="MeshInstance3D4" type="MeshInstance3D" parent="." unique_id=665036024]
+transform = Transform3D(0.7185697, 0, -0.28645763, 0.057966992, 0.9629134, 0.2585037, 0.20687544, -0.26981068, 0.9225605, -0.082, 0.149, -0.128)
+mesh = ExtResource("1_1dqn5")
diff --git a/client/map/items/noodles_tomato_sauce_fill.res b/client/map/items/noodles_tomato_sauce_fill.res
new file mode 100644
index 00000000..2bf8fad6
--- /dev/null
+++ b/client/map/items/noodles_tomato_sauce_fill.res
Binary files differ
diff --git a/client/map/items/noodles_tomato_sauce_fill.tscn b/client/map/items/noodles_tomato_sauce_fill.tscn
new file mode 100644
index 00000000..aac0ccd4
--- /dev/null
+++ b/client/map/items/noodles_tomato_sauce_fill.tscn
@@ -0,0 +1,9 @@
+[gd_scene format=3 uid="uid://cxwoxg732tgd8"]
+
+[ext_resource type="ArrayMesh" uid="uid://kwctvv8h54xj" path="res://map/items/noodles_tomato_sauce_fill.res" id="1_wu5sg"]
+
+[node name="NoodlesTomatoSauceFill" type="Node3D" unique_id=1260606454]
+
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1027670850]
+transform = Transform3D(-0.60932875, -0.0051440885, -0.022176262, -0.014863605, 0.24028103, 0.038889483, 0.024445973, 0.017876228, -0.5291095, -0.007, 0.023, 0.011)
+mesh = ExtResource("1_wu5sg")
diff --git a/client/map/items/pan.gd b/client/map/items/pan.gd
index 497d8832..99be1805 100644
--- a/client/map/items/pan.gd
+++ b/client/map/items/pan.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -23,6 +23,13 @@ func _init(owned_by_: Node3D):
add_child(load("res://map/items/pan.tscn").instantiate())
base.add_child(steam)
+func add_contents(contents: Array[String]):
+ for i: String in contents:
+ if i == "steak" or i == "seared-steak":
+ base.add_child(ItemFactory.produce(i, self, .85))
+ else:
+ super([i])
+
func progress(position_: float, speed: float, warn: bool):
super(position_, speed, warn)
steam.emitting = true
diff --git a/client/map/items/pan.res b/client/map/items/pan.res
index 03dcf8f9..307df9ce 100644
--- a/client/map/items/pan.res
+++ b/client/map/items/pan.res
Binary files differ
diff --git a/client/map/items/pan.tscn b/client/map/items/pan.tscn
index 661814d9..908471f0 100644
--- a/client/map/items/pan.tscn
+++ b/client/map/items/pan.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://b1fuw04fcbko8"]
+[gd_scene format=3 uid="uid://b1fuw04fcbko8"]
[ext_resource type="ArrayMesh" uid="uid://be0d8a6no06na" path="res://map/items/pan.res" id="1_m08s2"]
-[node name="Pan" type="Node3D"]
+[node name="Pan" type="Node3D" unique_id=1343705456]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=2018580953]
transform = Transform3D(-2.18557e-08, 0, -0.5, 0, 0.5, 0, 0.5, 0, -2.18557e-08, 0, 0, 0)
mesh = ExtResource("1_m08s2")
-skeleton = NodePath("")
diff --git a/client/map/items/patty.res b/client/map/items/patty.res
index 87880285..3ac0a9f1 100644
--- a/client/map/items/patty.res
+++ b/client/map/items/patty.res
Binary files differ
diff --git a/client/map/items/patty.tscn b/client/map/items/patty.tscn
index 2d1bdab6..494f623f 100644
--- a/client/map/items/patty.tscn
+++ b/client/map/items/patty.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://b1grk3gj58qbn"]
+[gd_scene format=3 uid="uid://b1grk3gj58qbn"]
[ext_resource type="ArrayMesh" uid="uid://wp3747kxnah1" path="res://map/items/patty.res" id="1_7tkah"]
-[node name="Patty" type="Node3D"]
+[node name="Patty" type="Node3D" unique_id=2110034130]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1300893752]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_7tkah")
-skeleton = NodePath("")
diff --git a/client/map/items/pizza.gd b/client/map/items/pizza.gd
new file mode 100644
index 00000000..a6c1a2ee
--- /dev/null
+++ b/client/map/items/pizza.gd
@@ -0,0 +1,29 @@
+# Hurry Curry! - a game about cooking
+# Copyright (C) 2026 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 <https://www.gnu.org/licenses/>.
+#
+class_name Pizza
+extends Item
+
+func _init(owned_by_: Node3D):
+ super(owned_by_)
+
+func add_contents(contents: Array[String]):
+ base.add_child(load("res://map/items/cooked_cheese_pizza.tscn").instantiate())
+ for c: String in contents:
+ match c:
+ "sliced-cheese": continue
+ "tomato-juice": continue
+ "sliced-mushroom": base.add_child(load("res://map/items/pizza/mushroom_pizza_topping.tscn").instantiate())
+ _: base.add_child(UnknownItem.new(owned_by, c))
diff --git a/client/map/items/pizza.gd.uid b/client/map/items/pizza.gd.uid
new file mode 100644
index 00000000..0a7a85c5
--- /dev/null
+++ b/client/map/items/pizza.gd.uid
@@ -0,0 +1 @@
+uid://3ptl5whwr0s5
diff --git a/client/map/items/pizza.res b/client/map/items/pizza.res
new file mode 100644
index 00000000..ef8b7e68
--- /dev/null
+++ b/client/map/items/pizza.res
Binary files differ
diff --git a/client/map/items/pizza/cheese_pizza_topping.tscn b/client/map/items/pizza/cheese_pizza_topping.tscn
new file mode 100644
index 00000000..45f73056
--- /dev/null
+++ b/client/map/items/pizza/cheese_pizza_topping.tscn
@@ -0,0 +1,25 @@
+[gd_scene format=3 uid="uid://746ly6kg6fym"]
+
+[ext_resource type="ArrayMesh" uid="uid://68yn4bguhuq3" path="res://map/items/cheese_bit.res" id="1_tuxk6"]
+
+[node name="CheesePizzaTopping" type="Node3D" unique_id=1491104077]
+
+[node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=571985640]
+transform = Transform3D(0.7090622, 0, 0.24439889, 0, 0.5, 0, -0.24439889, 0, 0.7090622, 0, 0.0901646, 0)
+mesh = ExtResource("1_tuxk6")
+
+[node name="MeshInstance3D2" type="MeshInstance3D" parent="." unique_id=2125195768]
+transform = Transform3D(0.26293755, 0, -0.70239866, 0, 0.5, 0, 0.70239866, 0, 0.26293755, -0.13107976, 0.0901646, -0.08822491)
+mesh = ExtResource("1_tuxk6")
+
+[node name="MeshInstance3D3" type="MeshInstance3D" parent="." unique_id=2077733221]
+transform = Transform3D(0.59963775, 0, -0.4504826, 0, 0.5, 0, 0.4504826, 0, 0.59963775, -0.1088517, 0.0901646, 0.09697052)
+mesh = ExtResource("1_tuxk6")
+
+[node name="MeshInstance3D4" type="MeshInstance3D" parent="." unique_id=508222957]
+transform = Transform3D(-0.025716748, 0, 0.7495589, 0, 0.5, 0, -0.7495589, 0, -0.025716748, 0.09534076, 0.0901646, 0.10794736)
+mesh = ExtResource("1_tuxk6")
+
+[node name="MeshInstance3D5" type="MeshInstance3D" parent="." unique_id=348571710]
+transform = Transform3D(0.5133626, 0, 0.5467713, 0, 0.5, 0, -0.5467713, 0, 0.5133626, 0.09534076, 0.0901646, -0.14092311)
+mesh = ExtResource("1_tuxk6")
diff --git a/client/map/items/pizza/mushroom_pizza_topping.tscn b/client/map/items/pizza/mushroom_pizza_topping.tscn
new file mode 100644
index 00000000..2dbe8e3d
--- /dev/null
+++ b/client/map/items/pizza/mushroom_pizza_topping.tscn
@@ -0,0 +1,17 @@
+[gd_scene format=3 uid="uid://b8md64r8oddij"]
+
+[ext_resource type="PackedScene" uid="uid://da3d6rgfss3su" path="res://map/items/pizza/mushroom_slice.tscn" id="1_m4x3a"]
+
+[node name="MushroomPizzaTopping" type="Node3D" unique_id=1982303343]
+
+[node name="CookedMushroomSlice" parent="." unique_id=1762083109 instance=ExtResource("1_m4x3a")]
+transform = Transform3D(0.44027928, 0, 1.2274243, 0, 1.304, 0, -1.2274243, 0, 0.44027928, 0.09475949, 0.075, -0.090857096)
+
+[node name="CookedMushroomSlice2" parent="." unique_id=1383642696 instance=ExtResource("1_m4x3a")]
+transform = Transform3D(1.1608893, 0, 0.59392935, 0, 1.304, 0, -0.59392935, 0, 1.1608893, -0.088593446, 0.075, -0.07241271)
+
+[node name="CookedMushroomSlice3" parent="." unique_id=1087751451 instance=ExtResource("1_m4x3a")]
+transform = Transform3D(-1.2750913, 0, 0.27305326, 0, 1.304, 0, -0.27305326, 0, -1.2750913, 0.090249225, 0.075, 0.075857505)
+
+[node name="CookedMushroomSlice4" parent="." unique_id=298075280 instance=ExtResource("1_m4x3a")]
+transform = Transform3D(1.0739639, 0, -0.73960626, 0, 1.304, 0, 0.73960626, 0, 1.0739639, -0.11389688, 0.075, 0.098924026)
diff --git a/client/map/items/pizza/mushroom_slice.res b/client/map/items/pizza/mushroom_slice.res
new file mode 100644
index 00000000..e50c5a19
--- /dev/null
+++ b/client/map/items/pizza/mushroom_slice.res
Binary files differ
diff --git a/client/map/items/pizza/mushroom_slice.tscn b/client/map/items/pizza/mushroom_slice.tscn
new file mode 100644
index 00000000..fbe1379b
--- /dev/null
+++ b/client/map/items/pizza/mushroom_slice.tscn
@@ -0,0 +1,9 @@
+[gd_scene format=3 uid="uid://da3d6rgfss3su"]
+
+[ext_resource type="ArrayMesh" uid="uid://b24bxvhik0ab2" path="res://map/items/pizza/mushroom_slice.res" id="1_6tyh4"]
+
+[node name="CookedMushroomSlice" type="Node3D" unique_id=1237055269]
+
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=964430930]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.05)
+mesh = ExtResource("1_6tyh4")
diff --git a/client/map/items/plate.gd b/client/map/items/plate.gd
index e5b86df2..e71b7d0a 100644
--- a/client/map/items/plate.gd
+++ b/client/map/items/plate.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -39,33 +39,54 @@ func add_contents(contents: Array[String]):
contents.append("bun-small")
# Tomato + lettuce salad has a custom mesh
- if contents.has("sliced-tomato") and contents.has("sliced-lettuce") and contents.size() == 2:
+ if G.unordered_array_eq(contents, ["sliced-tomato", "sliced-lettuce"]):
contents.erase("sliced-tomato")
contents.erase("sliced-lettuce")
contents.append("tomato-lettuce-salad")
+ # Noodles + tomato soup has a custom tomato sauce mesh
+ if G.unordered_array_subset(["cooked-noodles", "tomato-soup"], contents):
+ contents.erase("tomato-soup")
+ contents.append("noodles-tomato-fill")
+
+ # Noodles + sliced cheese has a custom cheese mesh
+ if G.unordered_array_subset(["cooked-noodles", "sliced-cheese"], contents):
+ contents.erase("sliced-cheese")
+ contents.append("noodles-cheese-fill")
+
# Stack content items on top of each other
var height_sum := 0.
- for c in contents:
+ for c: String in contents:
var item: Item
match c:
"curry": add_child(PlateFill.new(self, Color(.75, .45, .1)))
- "cheese-leek-soup": add_child(PlateFill.new(self, Color(0.747, 0.77, 0.493)))
+ "cheese-leek-soup":
+ add_child(PlateFill.new(self, Color(0.747, 0.77, 0.493)))
+ add_child(load("res://map/items/sliced_leek/leek_ring_fill.tscn").instantiate())
+ "mushroom-soup":
+ add_child(PlateFill.new(self, Color(0.747, 0.454, 0.36)))
+ add_child(load("res://map/items/mushroom_plate_fill.tscn").instantiate())
"cooked-rice": add_child(load("res://map/items/cooked_rice_fill.tscn").instantiate())
"tomato-lettuce-salad": add_child(load("res://map/items/sliced_tomato_sliced_lettuce_fill.tscn").instantiate())
"tomato-soup": add_child(PlateFill.new(self, Color(1., .3, .2)))
+ "noodles-tomato-fill": add_child(load("res://map/items/noodles_tomato_sauce_fill.tscn").instantiate())
+ "noodles-cheese-fill": add_child(load("res://map/items/noodles_cheese_fill.tscn").instantiate())
"french-fries": base.add_child(load("res://map/items/french_fries_fill.tscn").instantiate())
"bun-small":
var bun = ItemFactory.produce("bun", base)
base.add_child(bun)
bun.scale *= 0.5
bun.position += Vector3(-.1, 0, -.1)
+ "seared-steak": base.add_child(ItemFactory.produce(c, base, .85))
"seared-steak-small":
var seared_steak = ItemFactory.produce("seared-steak", base)
base.add_child(seared_steak)
seared_steak.scale *= 0.5
seared_steak.position += Vector3(.1, 0, .1)
- _: item = ItemFactory.produce(c, base)
+ _:
+ item = ItemFactory.produce(c, base)
+ if c.contains("pizza"):
+ item.scale = Vector3(.7, .7, .7)
if item != null:
base.add_child(item)
item.position.y = height_sum
diff --git a/client/map/items/plate.res b/client/map/items/plate.res
index b57844c3..2890171a 100644
--- a/client/map/items/plate.res
+++ b/client/map/items/plate.res
Binary files differ
diff --git a/client/map/items/plate.tscn b/client/map/items/plate.tscn
index 8503fe81..ca4aac58 100644
--- a/client/map/items/plate.tscn
+++ b/client/map/items/plate.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://daxh3hgia7qyp"]
+[gd_scene format=3 uid="uid://daxh3hgia7qyp"]
[ext_resource type="ArrayMesh" uid="uid://bnku7g8g0ts81" path="res://map/items/plate.res" id="1_70hux"]
-[node name="Plate" type="Node3D"]
+[node name="Plate" type="Node3D" unique_id=351447493]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=279311129]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_70hux")
-skeleton = NodePath("")
diff --git a/client/map/items/plate_fill.gd b/client/map/items/plate_fill.gd
index 057fc11f..fc2a3310 100644
--- a/client/map/items/plate_fill.gd
+++ b/client/map/items/plate_fill.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/items/plate_fill.res b/client/map/items/plate_fill.res
index 8aad5797..fb198090 100644
--- a/client/map/items/plate_fill.res
+++ b/client/map/items/plate_fill.res
Binary files differ
diff --git a/client/map/items/plate_fill.tscn b/client/map/items/plate_fill.tscn
index 1ba34231..29264c86 100644
--- a/client/map/items/plate_fill.tscn
+++ b/client/map/items/plate_fill.tscn
@@ -1,12 +1,11 @@
-[gd_scene load_steps=3 format=3 uid="uid://btktb7yb1y0yq"]
+[gd_scene format=3 uid="uid://btktb7yb1y0yq"]
[ext_resource type="ArrayMesh" uid="uid://c8l6gbfjikyv3" path="res://map/items/plate_fill.res" id="1_dgygv"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_q0leg"]
resource_local_to_scene = true
-[node name="PlateFill" type="MeshInstance3D"]
+[node name="PlateFill" type="MeshInstance3D" unique_id=601792816]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_dgygv")
-skeleton = NodePath("")
surface_material_override/0 = SubResource("StandardMaterial3D_q0leg")
diff --git a/client/map/items/pot.gd b/client/map/items/pot.gd
index 77c8ebd1..06b63f58 100644
--- a/client/map/items/pot.gd
+++ b/client/map/items/pot.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -26,6 +26,8 @@ func _init(owned_by_: Node3D):
func add_contents(contents: Array[String]):
for i in contents:
match i:
+ "cheese":
+ add_child(PotFill.new(self, Color(0.99, 0.75, 0.337, 1.0)))
"cheese-leek-soup":
add_child(PotFill.new(self, Color(0.747, 0.77, 0.493)))
"mochi-dough":
@@ -43,6 +45,15 @@ func add_contents(contents: Array[String]):
leek.rotation_degrees = Vector3(-75.5, 0, -25)
leek.position = Vector3(.03, .1, .25)
base.add_child(leek)
+ "cooked-noodles":
+ base.add_child(ItemFactory.produce(i, self, .85))
+ "noodles":
+ add_child(PotFillTransparent.new(self, Color(0.46, 0.68, 0.73, 0.392))) # water
+ base.add_child(ItemFactory.produce(i, self, .85))
+ "processed-mushroom":
+ add_child(PotFill.new(self, Color(0.596, 0.341, 0.259)))
+ "mushroom-soup":
+ add_child(PotFill.new(self, Color(0.747, 0.454, 0.36, 1.0)))
"cooked-rice":
add_child(PotFill.new(self, Color(1.,1.,1.)))
"curry":
diff --git a/client/map/items/pot.res b/client/map/items/pot.res
index df67fed3..827e6e28 100644
--- a/client/map/items/pot.res
+++ b/client/map/items/pot.res
Binary files differ
diff --git a/client/map/items/pot.tscn b/client/map/items/pot.tscn
index f823cae2..68a6f440 100644
--- a/client/map/items/pot.tscn
+++ b/client/map/items/pot.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://df0hhdcyubyid"]
+[gd_scene format=3 uid="uid://df0hhdcyubyid"]
[ext_resource type="ArrayMesh" uid="uid://dm14h4sasn2bm" path="res://map/items/pot.res" id="1_41enh"]
-[node name="Pot" type="Node3D"]
+[node name="Pot" type="Node3D" unique_id=1778291833]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=955140522]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_41enh")
-skeleton = NodePath("")
diff --git a/client/map/items/pot_fill.gd b/client/map/items/pot_fill.gd
index 0a59038d..e8dfaa1e 100644
--- a/client/map/items/pot_fill.gd
+++ b/client/map/items/pot_fill.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/items/pot_fill.res b/client/map/items/pot_fill.res
index 06c8590c..94942edb 100644
--- a/client/map/items/pot_fill.res
+++ b/client/map/items/pot_fill.res
Binary files differ
diff --git a/client/map/items/pot_fill.tscn b/client/map/items/pot_fill.tscn
index 2b3a1eda..674899ad 100644
--- a/client/map/items/pot_fill.tscn
+++ b/client/map/items/pot_fill.tscn
@@ -1,12 +1,11 @@
-[gd_scene load_steps=3 format=3 uid="uid://cwo8o5a6f5p4i"]
+[gd_scene format=3 uid="uid://cwo8o5a6f5p4i"]
[ext_resource type="ArrayMesh" uid="uid://bduftri3viodq" path="res://map/items/pot_fill.res" id="1_5suf6"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_djkvw"]
resource_local_to_scene = true
-[node name="PotFill" type="MeshInstance3D"]
+[node name="PotFill" type="MeshInstance3D" unique_id=1219055572]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_5suf6")
-skeleton = NodePath("")
surface_material_override/0 = SubResource("StandardMaterial3D_djkvw")
diff --git a/client/map/items/pot_fill_transparent.gd b/client/map/items/pot_fill_transparent.gd
new file mode 100644
index 00000000..f8585733
--- /dev/null
+++ b/client/map/items/pot_fill_transparent.gd
@@ -0,0 +1,22 @@
+# Hurry Curry! - a game about cooking
+# Copyright (C) 2026 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 <https://www.gnu.org/licenses/>.
+#
+class_name PotFillTransparent
+extends PotFill
+
+func _init(owned_by_: Node3D, c: Color):
+ super(owned_by_, c)
+ var mat: BaseMaterial3D = fill.get_active_material(0)
+ mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
diff --git a/client/map/items/pot_fill_transparent.gd.uid b/client/map/items/pot_fill_transparent.gd.uid
new file mode 100644
index 00000000..863ef626
--- /dev/null
+++ b/client/map/items/pot_fill_transparent.gd.uid
@@ -0,0 +1 @@
+uid://b7mtr0omy3nx4
diff --git a/client/map/items/potato.res b/client/map/items/potato.res
index 1a920e6f..3e54bece 100644
--- a/client/map/items/potato.res
+++ b/client/map/items/potato.res
Binary files differ
diff --git a/client/map/items/potato.tscn b/client/map/items/potato.tscn
index b57b2bbf..7d97b648 100644
--- a/client/map/items/potato.tscn
+++ b/client/map/items/potato.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://dw24qu0oscohw"]
+[gd_scene format=3 uid="uid://dw24qu0oscohw"]
[ext_resource type="ArrayMesh" uid="uid://hj2dib0t8em3" path="res://map/items/potato.res" id="1_rg7i5"]
-[node name="Potato" type="Node3D"]
+[node name="Potato" type="Node3D" unique_id=1149637460]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=544200943]
transform = Transform3D(-0.07814168, -2.3085807e-08, -0.44316345, -0.44316345, -1.937129e-08, 0.07814168, -2.3085807e-08, 0.45, -1.937129e-08, 0, 0.1, 0)
mesh = ExtResource("1_rg7i5")
-skeleton = NodePath("")
diff --git a/client/map/items/processing.tscn b/client/map/items/processing.tscn
index f8deb6be..28f785fa 100644
--- a/client/map/items/processing.tscn
+++ b/client/map/items/processing.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=3 format=3 uid="uid://sk5i14bxi0qr"]
+[gd_scene format=3 uid="uid://sk5i14bxi0qr"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_tqrr3"]
vertex_color_use_as_albedo = true
@@ -8,7 +8,7 @@ material = SubResource("StandardMaterial3D_tqrr3")
radius = 0.1
height = 0.2
-[node name="Processing" type="CPUParticles3D"]
+[node name="Processing" type="CPUParticles3D" unique_id=412007652]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.6, 0)
emitting = false
amount = 15
@@ -19,6 +19,7 @@ emission_ring_axis = Vector3(0, 1, 0)
emission_ring_height = 0.2
emission_ring_radius = 0.1
emission_ring_inner_radius = 0.0
+emission_ring_cone_angle = 90.0
direction = Vector3(0, 1, 0)
spread = 180.0
gravity = Vector3(0, 0, 0)
diff --git a/client/map/items/raw_pizza.tscn b/client/map/items/raw_pizza.tscn
new file mode 100644
index 00000000..5b7359cf
--- /dev/null
+++ b/client/map/items/raw_pizza.tscn
@@ -0,0 +1,11 @@
+[gd_scene format=3 uid="uid://d18w3kwuaehvv"]
+
+[ext_resource type="ArrayMesh" uid="uid://cwstqugiw76tc" path="res://map/items/pizza.res" id="1_lcgk8"]
+[ext_resource type="Material" uid="uid://cg7o7rn06bve1" path="res://map/items/dough_material.tres" id="2_snge3"]
+
+[node name="RawPizza" type="Node3D" unique_id=1513785364]
+
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=449857524]
+transform = Transform3D(0.3, 0, 0, 0, 0.05, 0, 0, 0, 0.3, 0, 0.05, 0)
+mesh = ExtResource("1_lcgk8")
+surface_material_override/0 = ExtResource("2_snge3")
diff --git a/client/map/items/rice.res b/client/map/items/rice.res
index f9a6a81c..d57d301b 100644
--- a/client/map/items/rice.res
+++ b/client/map/items/rice.res
Binary files differ
diff --git a/client/map/items/rice.tscn b/client/map/items/rice.tscn
index bb41f3e8..03f69422 100644
--- a/client/map/items/rice.tscn
+++ b/client/map/items/rice.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://rs4b17lp80cx"]
+[gd_scene format=3 uid="uid://rs4b17lp80cx"]
[ext_resource type="ArrayMesh" uid="uid://cclj4k0d1d1qk" path="res://map/items/rice.res" id="1_fmn8b"]
-[node name="Rice" type="Node3D"]
+[node name="Rice" type="Node3D" unique_id=132148842]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1049224626]
transform = Transform3D(0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1, 0, 0, 0)
mesh = ExtResource("1_fmn8b")
-skeleton = NodePath("")
diff --git a/client/map/items/rice_content.res b/client/map/items/rice_content.res
index 0f5dd44d..9aba9cfc 100644
--- a/client/map/items/rice_content.res
+++ b/client/map/items/rice_content.res
Binary files differ
diff --git a/client/map/items/rice_content.tscn b/client/map/items/rice_content.tscn
index 71038a4e..cc042d0a 100644
--- a/client/map/items/rice_content.tscn
+++ b/client/map/items/rice_content.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=3 format=3 uid="uid://do4qxd1d1x7cc"]
+[gd_scene format=3 uid="uid://do4qxd1d1x7cc"]
[ext_resource type="ArrayMesh" uid="uid://dfvubawp7vieh" path="res://map/items/rice_content.res" id="1_r5kmu"]
@@ -6,8 +6,7 @@
resource_local_to_scene = true
albedo_color = Color(0.933333, 0.933333, 0.666667, 1)
-[node name="RiceContent" type="MeshInstance3D"]
+[node name="RiceContent" type="MeshInstance3D" unique_id=867972096]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_r5kmu")
-skeleton = NodePath("")
surface_material_override/0 = SubResource("StandardMaterial3D_ce6yj")
diff --git a/client/map/items/rolled_dough.gd b/client/map/items/rolled_dough.gd
index cd59d907..3d0b5d25 100644
--- a/client/map/items/rolled_dough.gd
+++ b/client/map/items/rolled_dough.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -16,10 +16,20 @@
class_name RolledDough
extends Item
-
func _init(owned_by_: Node3D):
super(owned_by_)
- add_child(load("res://map/items/rolled_dough.tscn").instantiate())
func add_contents(contents: Array[String]):
- super(contents)
+ contents.sort()
+
+ if contents.has("tomato-juice"):
+ base.add_child(load("res://map/items/raw_pizza.tscn").instantiate())
+ else:
+ base.add_child(load("res://map/items/rolled_dough.tscn").instantiate())
+
+ for c: String in contents:
+ match c:
+ "tomato-juice": continue
+ "sliced-cheese": base.add_child(load("res://map/items/pizza/cheese_pizza_topping.tscn").instantiate())
+ "sliced-mushroom": base.add_child(load("res://map/items/pizza/mushroom_pizza_topping.tscn").instantiate())
+ _: base.add_child(UnknownItem.new(owned_by, c))
diff --git a/client/map/items/rolled_dough.res b/client/map/items/rolled_dough.res
index 2759b731..c432a638 100644
--- a/client/map/items/rolled_dough.res
+++ b/client/map/items/rolled_dough.res
Binary files differ
diff --git a/client/map/items/rolled_dough.tscn b/client/map/items/rolled_dough.tscn
index 04577c96..0fc9c103 100644
--- a/client/map/items/rolled_dough.tscn
+++ b/client/map/items/rolled_dough.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://dwfvdvvgenyn5"]
+[gd_scene format=3 uid="uid://dwfvdvvgenyn5"]
[ext_resource type="ArrayMesh" uid="uid://dtqjpqwxq5mvn" path="res://map/items/rolled_dough.res" id="1_uyf2v"]
-[node name="RolledDough" type="Node3D"]
+[node name="RolledDough" type="Node3D" unique_id=1623668918]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1841908103]
transform = Transform3D(0.3, 0, 0, 0, 0.05, 0, 0, 0, 0.3, 0, 0.05, 0)
mesh = ExtResource("1_uyf2v")
-skeleton = NodePath("")
diff --git a/client/map/items/seared_patty.res b/client/map/items/seared_patty.res
index 255b95df..d7ac0a30 100644
--- a/client/map/items/seared_patty.res
+++ b/client/map/items/seared_patty.res
Binary files differ
diff --git a/client/map/items/seared_patty.tscn b/client/map/items/seared_patty.tscn
index 7ffe65f2..d72e2681 100644
--- a/client/map/items/seared_patty.tscn
+++ b/client/map/items/seared_patty.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://dfriokxmga3c8"]
+[gd_scene format=3 uid="uid://dfriokxmga3c8"]
[ext_resource type="ArrayMesh" uid="uid://dl8hstmmdkog4" path="res://map/items/seared_patty.res" id="1_gy1aa"]
-[node name="SearedPatty" type="Node3D"]
+[node name="SearedPatty" type="Node3D" unique_id=580728218]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1808379124]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_gy1aa")
-skeleton = NodePath("")
diff --git a/client/map/items/seared_steak.res b/client/map/items/seared_steak.res
index 32c784fb..b91da335 100644
--- a/client/map/items/seared_steak.res
+++ b/client/map/items/seared_steak.res
Binary files differ
diff --git a/client/map/items/seared_steak.tscn b/client/map/items/seared_steak.tscn
index 8592e851..ee7797f4 100644
--- a/client/map/items/seared_steak.tscn
+++ b/client/map/items/seared_steak.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://c70af18pms3gw"]
+[gd_scene format=3 uid="uid://c70af18pms3gw"]
[ext_resource type="ArrayMesh" uid="uid://kfod37qy5sx" path="res://map/items/seared_steak.res" id="1_keoxi"]
-[node name="Steak" type="Node3D"]
+[node name="Steak" type="Node3D" unique_id=201918396]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=151167089]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_keoxi")
-skeleton = NodePath("")
diff --git a/client/map/items/sliced_bun.tscn b/client/map/items/sliced_bun.tscn
index 961d0f70..48b0b303 100644
--- a/client/map/items/sliced_bun.tscn
+++ b/client/map/items/sliced_bun.tscn
@@ -1,16 +1,14 @@
-[gd_scene load_steps=3 format=3 uid="uid://cm88wpf64l4fu"]
+[gd_scene format=3 uid="uid://cm88wpf64l4fu"]
[ext_resource type="ArrayMesh" uid="uid://c1qyv55xpv30n" path="res://map/items/sliced_bun_bottom.res" id="1_plvi5"]
[ext_resource type="ArrayMesh" uid="uid://dy180cecs6rb1" path="res://map/items/sliced_bun_top.res" id="2_l6cg2"]
-[node name="SlicedBun" type="Node3D"]
+[node name="SlicedBun" type="Node3D" unique_id=289245464]
-[node name="MeshBottom" type="MeshInstance3D" parent="."]
+[node name="MeshBottom" type="MeshInstance3D" parent="." unique_id=2050604098]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_plvi5")
-skeleton = NodePath("")
-[node name="MeshTop" type="MeshInstance3D" parent="."]
+[node name="MeshTop" type="MeshInstance3D" parent="." unique_id=1553309169]
transform = Transform3D(0.433013, 0.25, 0, -0.25, 0.433013, 0, 0, 0, 0.5, 0.18, 0.08, 0)
mesh = ExtResource("2_l6cg2")
-skeleton = NodePath("")
diff --git a/client/map/items/sliced_bun_bottom.res b/client/map/items/sliced_bun_bottom.res
index df7bab99..350e9693 100644
--- a/client/map/items/sliced_bun_bottom.res
+++ b/client/map/items/sliced_bun_bottom.res
Binary files differ
diff --git a/client/map/items/sliced_bun_bottom.tscn b/client/map/items/sliced_bun_bottom.tscn
index 573dba13..45e7af68 100644
--- a/client/map/items/sliced_bun_bottom.tscn
+++ b/client/map/items/sliced_bun_bottom.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://djtfnj11lljke"]
+[gd_scene format=3 uid="uid://djtfnj11lljke"]
[ext_resource type="ArrayMesh" uid="uid://c1qyv55xpv30n" path="res://map/items/sliced_bun_bottom.res" id="1_ekr5f"]
-[node name="SlicedBunBottom" type="Node3D"]
+[node name="SlicedBunBottom" type="Node3D" unique_id=1954514598]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=234719865]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_ekr5f")
-skeleton = NodePath("")
diff --git a/client/map/items/sliced_bun_top.res b/client/map/items/sliced_bun_top.res
index fc88dcbe..4d4d57fc 100644
--- a/client/map/items/sliced_bun_top.res
+++ b/client/map/items/sliced_bun_top.res
Binary files differ
diff --git a/client/map/items/sliced_bun_top.tscn b/client/map/items/sliced_bun_top.tscn
index 403ecea7..b57c72ef 100644
--- a/client/map/items/sliced_bun_top.tscn
+++ b/client/map/items/sliced_bun_top.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://cpmnp5sy6fwbe"]
+[gd_scene format=3 uid="uid://cpmnp5sy6fwbe"]
[ext_resource type="ArrayMesh" uid="uid://dy180cecs6rb1" path="res://map/items/sliced_bun_top.res" id="1_q5w8k"]
-[node name="SlicedBunTop" type="Node3D"]
+[node name="SlicedBunTop" type="Node3D" unique_id=45817428]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=487537457]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_q5w8k")
-skeleton = NodePath("")
diff --git a/client/map/items/sliced_cheese.res b/client/map/items/sliced_cheese.res
index ece9c0e0..799e4508 100644
--- a/client/map/items/sliced_cheese.res
+++ b/client/map/items/sliced_cheese.res
Binary files differ
diff --git a/client/map/items/sliced_cheese.tscn b/client/map/items/sliced_cheese.tscn
index 4e9ba406..22a6df5f 100644
--- a/client/map/items/sliced_cheese.tscn
+++ b/client/map/items/sliced_cheese.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://cfdfhxgo4ot7m"]
+[gd_scene format=3 uid="uid://cfdfhxgo4ot7m"]
[ext_resource type="ArrayMesh" uid="uid://2qsg2dadmf1y" path="res://map/items/sliced_cheese.res" id="1_bbycg"]
-[node name="SlicedCheese" type="Node3D"]
+[node name="SlicedCheese" type="Node3D" unique_id=1506920915]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1120946141]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0.04, 0)
mesh = ExtResource("1_bbycg")
-skeleton = NodePath("")
diff --git a/client/map/items/sliced_fish.res b/client/map/items/sliced_fish.res
index 9937a93b..a7d27cf5 100644
--- a/client/map/items/sliced_fish.res
+++ b/client/map/items/sliced_fish.res
Binary files differ
diff --git a/client/map/items/sliced_fish.tscn b/client/map/items/sliced_fish.tscn
index 5e60f301..d6ed4bec 100644
--- a/client/map/items/sliced_fish.tscn
+++ b/client/map/items/sliced_fish.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://dxs04puo5ow7u"]
+[gd_scene format=3 uid="uid://dxs04puo5ow7u"]
[ext_resource type="ArrayMesh" uid="uid://c3pxaxxbv721y" path="res://map/items/sliced_fish.res" id="1_nt0xc"]
-[node name="SlicedFish" type="Node3D"]
+[node name="SlicedFish" type="Node3D" unique_id=1546314626]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1817309076]
transform = Transform3D(0.1, 0, 0, 0, -4.37114e-09, -0.1, 0, 0.1, -4.37114e-09, 0, 0.045, 0)
mesh = ExtResource("1_nt0xc")
-skeleton = NodePath("")
diff --git a/client/map/items/sliced_leek/leek_ring.res b/client/map/items/sliced_leek/leek_ring.res
new file mode 100644
index 00000000..78d57354
--- /dev/null
+++ b/client/map/items/sliced_leek/leek_ring.res
Binary files differ
diff --git a/client/map/items/sliced_leek/leek_ring.tscn b/client/map/items/sliced_leek/leek_ring.tscn
new file mode 100644
index 00000000..a8575b05
--- /dev/null
+++ b/client/map/items/sliced_leek/leek_ring.tscn
@@ -0,0 +1,9 @@
+[gd_scene format=3 uid="uid://b25ajkbydfoi8"]
+
+[ext_resource type="ArrayMesh" uid="uid://ck1dtslyq0xqk" path="res://map/items/sliced_leek/leek_ring.res" id="1_wdt75"]
+
+[node name="LeekRing" type="Node3D" unique_id=6349426]
+
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=207039888]
+transform = Transform3D(0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1, 0, 0, 0)
+mesh = ExtResource("1_wdt75")
diff --git a/client/map/items/sliced_leek/leek_ring_fill.tscn b/client/map/items/sliced_leek/leek_ring_fill.tscn
new file mode 100644
index 00000000..83fc2542
--- /dev/null
+++ b/client/map/items/sliced_leek/leek_ring_fill.tscn
@@ -0,0 +1,14 @@
+[gd_scene format=3 uid="uid://y7mg0uh4ghxe"]
+
+[ext_resource type="PackedScene" uid="uid://b25ajkbydfoi8" path="res://map/items/sliced_leek/leek_ring.tscn" id="1_cb47f"]
+
+[node name="LeekRingFill" type="Node3D" unique_id=1649292111]
+
+[node name="LeekRing" parent="." unique_id=601839974 instance=ExtResource("1_cb47f")]
+transform = Transform3D(0.5, 0, 0, 0, 0.4, 0, 0, 0, 0.5, 0.053702652, 0.04, -0.082)
+
+[node name="LeekRing2" parent="." unique_id=871702627 instance=ExtResource("1_cb47f")]
+transform = Transform3D(0.5, 0, 0, 0, 0.4, 0, 0, 0, 0.5, -0.09291987, 0.04, 0.0293293)
+
+[node name="LeekRing3" parent="." unique_id=1947059454 instance=ExtResource("1_cb47f")]
+transform = Transform3D(0.5, 0, 0, 0, 0.4, 0, 0, 0, 0.5, 0.05727595, 0.04, 0.08234578)
diff --git a/client/map/items/sliced_leek/sliced_leek.tscn b/client/map/items/sliced_leek/sliced_leek.tscn
index 701f4844..8d8bc2d7 100644
--- a/client/map/items/sliced_leek/sliced_leek.tscn
+++ b/client/map/items/sliced_leek/sliced_leek.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=6 format=3 uid="uid://dght3ftij5nx6"]
+[gd_scene format=3 uid="uid://dght3ftij5nx6"]
[ext_resource type="ArrayMesh" uid="uid://bjb2vxii3mkny" path="res://map/items/sliced_leek/sliced_leek_1.res" id="1_ub7pe"]
[ext_resource type="ArrayMesh" uid="uid://bthgt3jvyaet5" path="res://map/items/sliced_leek/sliced_leek_2.res" id="2_krib3"]
@@ -6,32 +6,27 @@
[ext_resource type="ArrayMesh" uid="uid://deqd1uok1ahtn" path="res://map/items/sliced_leek/sliced_leek_4.res" id="4_eia2k"]
[ext_resource type="ArrayMesh" uid="uid://cl36j3pufjfil" path="res://map/items/sliced_leek/sliced_leek_5.res" id="5_26kjl"]
-[node name="SlicedLeek" type="Node3D"]
+[node name="SlicedLeek" type="Node3D" unique_id=754926403]
-[node name="Node3D" type="Node3D" parent="."]
+[node name="Node3D" type="Node3D" parent="." unique_id=1618880656]
transform = Transform3D(-7.649493e-08, 0, 1.75, 0, 1.75, 0, -1.75, 0, -7.649493e-08, 0, 0, 0)
-[node name="leek_001" type="MeshInstance3D" parent="Node3D"]
+[node name="leek_001" type="MeshInstance3D" parent="Node3D" unique_id=1739603265]
transform = Transform3D(1, 0, 0, 0, 0.591008, 0.61566144, 0, -0.4617461, 0.7880107, 0, 0.03454741, 0.09892485)
mesh = ExtResource("1_ub7pe")
-skeleton = NodePath("")
-[node name="leek_002" type="MeshInstance3D" parent="Node3D"]
+[node name="leek_002" type="MeshInstance3D" parent="Node3D" unique_id=10737438]
transform = Transform3D(1, 0, 0, 0, 0.591008, 0.61566144, 0, -0.4617461, 0.7880107, -2.0835932e-06, 0.03454531, 0.04651942)
mesh = ExtResource("2_krib3")
-skeleton = NodePath("")
-[node name="leek_003" type="MeshInstance3D" parent="Node3D"]
+[node name="leek_003" type="MeshInstance3D" parent="Node3D" unique_id=1275702161]
transform = Transform3D(1, 0, 0, 0, 0.591008, 0.61566144, 0, -0.4617461, 0.7880107, -2.0874368e-06, 0.034545287, -0.004093088)
mesh = ExtResource("3_eq1cv")
-skeleton = NodePath("")
-[node name="leek_004" type="MeshInstance3D" parent="Node3D"]
+[node name="leek_004" type="MeshInstance3D" parent="Node3D" unique_id=2052531974]
transform = Transform3D(1, 0, 0, 0, 0.591008, 0.61566144, 0, -0.4617461, 0.7880107, -2.085316e-06, 0.03454527, -0.05421468)
mesh = ExtResource("4_eia2k")
-skeleton = NodePath("")
-[node name="leek_005" type="MeshInstance3D" parent="Node3D"]
+[node name="leek_005" type="MeshInstance3D" parent="Node3D" unique_id=1421505896]
transform = Transform3D(1, 0, 0, 0, 0.591008, 0.61566144, 0, -0.4617461, 0.7880107, -2.0847467e-06, 0.034545254, -0.10421119)
mesh = ExtResource("5_26kjl")
-skeleton = NodePath("")
diff --git a/client/map/items/sliced_leek/sliced_leek_1.res b/client/map/items/sliced_leek/sliced_leek_1.res
index 9a786370..dc5275d5 100644
--- a/client/map/items/sliced_leek/sliced_leek_1.res
+++ b/client/map/items/sliced_leek/sliced_leek_1.res
Binary files differ
diff --git a/client/map/items/sliced_leek/sliced_leek_2.res b/client/map/items/sliced_leek/sliced_leek_2.res
index 3234cd54..c0d7ccd3 100644
--- a/client/map/items/sliced_leek/sliced_leek_2.res
+++ b/client/map/items/sliced_leek/sliced_leek_2.res
Binary files differ
diff --git a/client/map/items/sliced_leek/sliced_leek_3.res b/client/map/items/sliced_leek/sliced_leek_3.res
index 2165204a..2fe303a4 100644
--- a/client/map/items/sliced_leek/sliced_leek_3.res
+++ b/client/map/items/sliced_leek/sliced_leek_3.res
Binary files differ
diff --git a/client/map/items/sliced_leek/sliced_leek_4.res b/client/map/items/sliced_leek/sliced_leek_4.res
index 05d54114..32c02690 100644
--- a/client/map/items/sliced_leek/sliced_leek_4.res
+++ b/client/map/items/sliced_leek/sliced_leek_4.res
Binary files differ
diff --git a/client/map/items/sliced_leek/sliced_leek_5.res b/client/map/items/sliced_leek/sliced_leek_5.res
index 90f4d4b2..93f9e009 100644
--- a/client/map/items/sliced_leek/sliced_leek_5.res
+++ b/client/map/items/sliced_leek/sliced_leek_5.res
Binary files differ
diff --git a/client/map/items/sliced_leek/sliced_leek_6.res b/client/map/items/sliced_leek/sliced_leek_6.res
index db0baeda..1cd6c906 100644
--- a/client/map/items/sliced_leek/sliced_leek_6.res
+++ b/client/map/items/sliced_leek/sliced_leek_6.res
Binary files differ
diff --git a/client/map/items/sliced_lettuce.res b/client/map/items/sliced_lettuce.res
index 1a748947..40cb0702 100644
--- a/client/map/items/sliced_lettuce.res
+++ b/client/map/items/sliced_lettuce.res
Binary files differ
diff --git a/client/map/items/sliced_lettuce.tscn b/client/map/items/sliced_lettuce.tscn
index f2840059..d5ec39ed 100644
--- a/client/map/items/sliced_lettuce.tscn
+++ b/client/map/items/sliced_lettuce.tscn
@@ -1,11 +1,10 @@
-[gd_scene load_steps=2 format=3 uid="uid://c8tjoqcdn1gpj"]
+[gd_scene format=3 uid="uid://c8tjoqcdn1gpj"]
[ext_resource type="ArrayMesh" uid="uid://jkb0e8d584uo" path="res://map/items/sliced_lettuce.res" id="1_y7x7n"]
-[node name="SlicedLettuce" type="Node3D"]
+[node name="SlicedLettuce" type="Node3D" unique_id=814161375]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.01, 0)
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=189735380]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0.01, 0)
mesh = ExtResource("1_y7x7n")
-skeleton = NodePath("")
diff --git a/client/map/items/sliced_mushroom.res b/client/map/items/sliced_mushroom.res
new file mode 100644
index 00000000..94b17fe4
--- /dev/null
+++ b/client/map/items/sliced_mushroom.res
Binary files differ
diff --git a/client/map/items/sliced_mushroom.tscn b/client/map/items/sliced_mushroom.tscn
new file mode 100644
index 00000000..17945fc0
--- /dev/null
+++ b/client/map/items/sliced_mushroom.tscn
@@ -0,0 +1,9 @@
+[gd_scene format=3 uid="uid://8waoyr3a7c6q"]
+
+[ext_resource type="ArrayMesh" uid="uid://13uivbfdn4kb" path="res://map/items/sliced_mushroom.res" id="1_4k44b"]
+
+[node name="SlicedMushroom" type="Node3D" unique_id=771921867]
+
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1483580511]
+transform = Transform3D(0.8, 0, 0, 0, -0.7250462, -0.33809468, 0, 0.33809468, -0.7250462, 0, 0.059715845, 0.1)
+mesh = ExtResource("1_4k44b")
diff --git a/client/map/items/sliced_potato.tscn b/client/map/items/sliced_potato.tscn
index ec48414d..f64eafd3 100644
--- a/client/map/items/sliced_potato.tscn
+++ b/client/map/items/sliced_potato.tscn
@@ -1,14 +1,13 @@
-[gd_scene load_steps=3 format=3 uid="uid://b85iw6rv2snx8"]
+[gd_scene format=3 uid="uid://b85iw6rv2snx8"]
[ext_resource type="ArrayMesh" uid="uid://b4ayvyhakbe7t" path="res://map/items/french_fries.res" id="1_ikao7"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_qhqrd"]
albedo_color = Color(0.88, 0.7546, 0.484, 1)
-[node name="SlicedPotato" type="Node3D"]
+[node name="SlicedPotato" type="Node3D" unique_id=552755740]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=983811931]
transform = Transform3D(0.75, 0, 0, 0, 0.75, 0, 0, 0, 0.75, 0, 0, -0.112)
mesh = ExtResource("1_ikao7")
-skeleton = NodePath("")
surface_material_override/0 = SubResource("StandardMaterial3D_qhqrd")
diff --git a/client/map/items/sliced_tomato.res b/client/map/items/sliced_tomato.res
index 3594e6f9..37996910 100644
--- a/client/map/items/sliced_tomato.res
+++ b/client/map/items/sliced_tomato.res
Binary files differ
diff --git a/client/map/items/sliced_tomato.tscn b/client/map/items/sliced_tomato.tscn
index 28ba45f4..9ea93827 100644
--- a/client/map/items/sliced_tomato.tscn
+++ b/client/map/items/sliced_tomato.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://8u4yp0323kiw"]
+[gd_scene format=3 uid="uid://8u4yp0323kiw"]
[ext_resource type="ArrayMesh" uid="uid://cwjqxolxw0ttl" path="res://map/items/sliced_tomato.res" id="1_6yvlk"]
-[node name="SlicedTomato" type="Node3D"]
+[node name="SlicedTomato" type="Node3D" unique_id=1212521096]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=642983217]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_6yvlk")
-skeleton = NodePath("")
diff --git a/client/map/items/sliced_tomato_sliced_lettuce_fill.tscn b/client/map/items/sliced_tomato_sliced_lettuce_fill.tscn
index 75ef95f1..4d0c4c4f 100644
--- a/client/map/items/sliced_tomato_sliced_lettuce_fill.tscn
+++ b/client/map/items/sliced_tomato_sliced_lettuce_fill.tscn
@@ -1,35 +1,35 @@
-[gd_scene load_steps=3 format=3 uid="uid://cy12k7ghclh2g"]
+[gd_scene format=3 uid="uid://cy12k7ghclh2g"]
[ext_resource type="ArrayMesh" uid="uid://cwjqxolxw0ttl" path="res://map/items/sliced_tomato.res" id="1_gnakr"]
[ext_resource type="ArrayMesh" uid="uid://jkb0e8d584uo" path="res://map/items/sliced_lettuce.res" id="3_6hedi"]
-[node name="SlicedTomatoFill" type="Node3D"]
+[node name="SlicedTomatoFill" type="Node3D" unique_id=1588553817]
-[node name="Mesh8" type="MeshInstance3D" parent="."]
+[node name="Mesh8" type="MeshInstance3D" parent="." unique_id=1786817704]
transform = Transform3D(0.25, 0, 0, 0, 0.25, 0, 0, 0, 0.25, -0.1, 0.04, 0)
mesh = ExtResource("1_gnakr")
-[node name="Mesh11" type="MeshInstance3D" parent="."]
+[node name="Mesh11" type="MeshInstance3D" parent="." unique_id=64683158]
transform = Transform3D(0.25, 0, 0, 0, 0.25, 0, 0, 0, 0.25, 0.1, 0.04, 0)
mesh = ExtResource("1_gnakr")
-[node name="Mesh12" type="MeshInstance3D" parent="."]
+[node name="Mesh12" type="MeshInstance3D" parent="." unique_id=1975270560]
transform = Transform3D(0.25, 0, 0, 0, 0.25, 0, 0, 0, 0.25, 0, 0.04, 0.1)
mesh = ExtResource("1_gnakr")
-[node name="Mesh13" type="MeshInstance3D" parent="."]
+[node name="Mesh13" type="MeshInstance3D" parent="." unique_id=1081920419]
transform = Transform3D(0.25, 0, 0, 0, 0.25, 0, 0, 0, 0.25, 0, 0.04, -0.1)
mesh = ExtResource("1_gnakr")
-[node name="Mesh9" type="MeshInstance3D" parent="."]
+[node name="Mesh9" type="MeshInstance3D" parent="." unique_id=1635978560]
transform = Transform3D(0.28, 0, 0, 0, 0.28, 0, 0, 0, 0.28, 0.0815632, 0.0377627, -0.0198822)
visible = false
mesh = ExtResource("1_gnakr")
-[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
+[node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=364673189]
transform = Transform3D(0.45, 0, 0, 0, 0.45, 0, 0, 0, 0.45, 0, 0.025, 0)
mesh = ExtResource("3_6hedi")
-[node name="MeshInstance3D4" type="MeshInstance3D" parent="."]
+[node name="MeshInstance3D4" type="MeshInstance3D" parent="." unique_id=196525840]
transform = Transform3D(0.279, 0, 0, 0, 0.279, 0, 0, 0, 0.279, 0, 0.075, 0)
mesh = ExtResource("3_6hedi")
diff --git a/client/map/items/steak.res b/client/map/items/steak.res
index 8deb7f8a..21d27302 100644
--- a/client/map/items/steak.res
+++ b/client/map/items/steak.res
Binary files differ
diff --git a/client/map/items/steak.tscn b/client/map/items/steak.tscn
index 59846d8a..8efb2b19 100644
--- a/client/map/items/steak.tscn
+++ b/client/map/items/steak.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://c8ylx2rsklp2y"]
+[gd_scene format=3 uid="uid://c8ylx2rsklp2y"]
[ext_resource type="ArrayMesh" uid="uid://tuorjx63f0ij" path="res://map/items/steak.res" id="1_iei2f"]
-[node name="Steak" type="Node3D"]
+[node name="Steak" type="Node3D" unique_id=273592414]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=683408760]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_iei2f")
-skeleton = NodePath("")
diff --git a/client/map/items/steam.tscn b/client/map/items/steam.tscn
index a6114124..2097c1ee 100644
--- a/client/map/items/steam.tscn
+++ b/client/map/items/steam.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=4 format=3 uid="uid://g1wsqgb56o1o"]
+[gd_scene format=3 uid="uid://g1wsqgb56o1o"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_e1q7j"]
transparency = 1
@@ -13,7 +13,7 @@ height = 0.2
_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(1, 0.10989), 0.0, 0.0, 0, 0]
point_count = 2
-[node name="Steam" type="CPUParticles3D"]
+[node name="Steam" type="CPUParticles3D" unique_id=1010015344]
emitting = false
amount = 25
lifetime = 2.0
diff --git a/client/map/items/strawberry.res b/client/map/items/strawberry.res
index 60da68ed..b92780ef 100644
--- a/client/map/items/strawberry.res
+++ b/client/map/items/strawberry.res
Binary files differ
diff --git a/client/map/items/strawberry.tscn b/client/map/items/strawberry.tscn
index 90df0c3c..cc9464e0 100644
--- a/client/map/items/strawberry.tscn
+++ b/client/map/items/strawberry.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://df1xktleeqg3m"]
+[gd_scene format=3 uid="uid://df1xktleeqg3m"]
[ext_resource type="ArrayMesh" uid="uid://c2uwqjxx7mnqp" path="res://map/items/strawberry.res" id="1_8dx1o"]
-[node name="Strawberry" type="Node3D"]
+[node name="Strawberry" type="Node3D" unique_id=613205790]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1524130613]
transform = Transform3D(-5.68248e-10, 1.1365e-09, 0.013, 0, -0.013, 1.1365e-09, 0.013, 4.96778e-17, 5.68248e-10, 0, 0.125, 0)
mesh = ExtResource("1_8dx1o")
-skeleton = NodePath("")
diff --git a/client/map/items/tomato.res b/client/map/items/tomato.res
index aafc8738..77d921cf 100644
--- a/client/map/items/tomato.res
+++ b/client/map/items/tomato.res
Binary files differ
diff --git a/client/map/items/tomato.tscn b/client/map/items/tomato.tscn
index 4589cca5..e68801d8 100644
--- a/client/map/items/tomato.tscn
+++ b/client/map/items/tomato.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://cvgmmrm8xqg4t"]
+[gd_scene format=3 uid="uid://cvgmmrm8xqg4t"]
[ext_resource type="ArrayMesh" uid="uid://bh5t6gqdxv1t8" path="res://map/items/tomato.res" id="1_8xuup"]
-[node name="Tomato" type="Node3D"]
+[node name="Tomato" type="Node3D" unique_id=256268001]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1541018452]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_8xuup")
-skeleton = NodePath("")
diff --git a/client/map/items/unknown_item.gd b/client/map/items/unknown_item.gd
index ec6cab1a..da43eb08 100644
--- a/client/map/items/unknown_item.gd
+++ b/client/map/items/unknown_item.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/items/unknown_item.tscn b/client/map/items/unknown_item.tscn
index 5e8b317a..fa838e9b 100644
--- a/client/map/items/unknown_item.tscn
+++ b/client/map/items/unknown_item.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=3 format=3 uid="uid://cw54drt6oqxpd"]
+[gd_scene format=3 uid="uid://cw54drt6oqxpd"]
[sub_resource type="BoxMesh" id="BoxMesh_e6d7n"]
@@ -7,9 +7,9 @@ albedo_color = Color(1, 0, 1, 1)
emission_enabled = true
emission = Color(1, 0, 1, 1)
-[node name="UnknownItem" type="Node3D"]
+[node name="UnknownItem" type="Node3D" unique_id=1035215297]
-[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
+[node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=1034064644]
transform = Transform3D(0.4, 0, 0, 0, 0.4, 0, 0, 0, 0.4, 0, 0.2, 0)
mesh = SubResource("BoxMesh_e6d7n")
surface_material_override/0 = SubResource("StandardMaterial3D_voy47")
diff --git a/client/map/items/unknown_order.tscn b/client/map/items/unknown_order.tscn
index 24116387..558be6f4 100644
--- a/client/map/items/unknown_order.tscn
+++ b/client/map/items/unknown_order.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=3 format=3 uid="uid://dgg7srscxmtmy"]
+[gd_scene format=3 uid="uid://dgg7srscxmtmy"]
[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://gui/resources/fonts/font-sansita-swashed.woff2" id="1_3pq52"]
@@ -8,9 +8,9 @@ variation_opentype = {
2003265652: 700
}
-[node name="UnknownOrder" type="Node3D"]
+[node name="UnknownOrder" type="Node3D" unique_id=1440369537]
-[node name="Label3D" type="Label3D" parent="."]
+[node name="Label3D" type="Label3D" parent="." unique_id=717159416]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.189058, 0)
pixel_size = 0.0025
billboard = 1
diff --git a/client/map/kitchen_background.gd b/client/map/kitchen_background.gd
index 4b728a94..456aa598 100644
--- a/client/map/kitchen_background.gd
+++ b/client/map/kitchen_background.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -22,13 +22,13 @@ func _ready() -> void:
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"
+ ".": 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 = [
"...............",
@@ -39,9 +39,10 @@ func init_map():
".............=#",
".............=#"
].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))
+ var offset = Vector2i(floor(tiles[0].size() / 2), floor(tiles.size() - 2))
+ var pos_to_tile: Dictionary[Vector2i, Array] = {} # : Dictionary[Vector2i, Array[String]]
+ for y in range(tiles.size()):
+ for x in range(tiles[y].size()):
+ pos_to_tile[Vector2i(x,y) - offset] = tiles[y][x]
+ map.set_all_tiles(pos_to_tile)
map.flush()
diff --git a/client/map/kitchen_background.tscn b/client/map/kitchen_background.tscn
index 5d572f73..918a6403 100644
--- a/client/map/kitchen_background.tscn
+++ b/client/map/kitchen_background.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=6 format=3 uid="uid://wwu574dq2r8h"]
+[gd_scene format=3 uid="uid://wwu574dq2r8h"]
[ext_resource type="PackedScene" uid="uid://b4gone8fu53r7" path="res://map/map.tscn" id="1_heqla"]
[ext_resource type="Script" uid="uid://ddpr5p4c6p8pn" path="res://map/kitchen_background.gd" id="1_ppf8f"]
@@ -13,18 +13,18 @@ size = Vector3(14, 5, 0.3)
[sub_resource type="BoxMesh" id="BoxMesh_xidlh"]
size = Vector3(7.5, 5, 0.3)
-[node name="KitchenBackground" type="Node3D"]
+[node name="KitchenBackground" type="Node3D" unique_id=296843447]
script = ExtResource("1_ppf8f")
-[node name="Map" parent="." instance=ExtResource("1_heqla")]
+[node name="Map" parent="." unique_id=1312929770 instance=ExtResource("1_heqla")]
-[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
+[node name="WorldEnvironment" type="WorldEnvironment" parent="." unique_id=1245737099]
environment = SubResource("Environment_ex25y")
-[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
+[node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=1705656468]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 0.5, -3.5)
mesh = SubResource("BoxMesh_ppf8f")
-[node name="MeshInstance3D2" type="MeshInstance3D" parent="."]
+[node name="MeshInstance3D2" type="MeshInstance3D" parent="." unique_id=1171319920]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 7.5, 0.5, -1)
mesh = SubResource("BoxMesh_xidlh")
diff --git a/client/map/map.gd b/client/map/map.gd
index f6cb2f82..00f0f7b3 100644
--- a/client/map/map.gd
+++ b/client/map/map.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -17,52 +17,87 @@ class_name Map
extends Node3D
class TileInfo:
- func _init(position_, name_, tile_, neighbours_) -> void:
- position = position_; name = name_; tile = tile_; neighbours = neighbours_
+ func _init(position_, tiles_, tile_instances_, tile_parent_) -> void:
+ position = position_; tiles = tiles_; tile_instances = tile_instances_; tile_parent = tile_parent_
var position: Vector2i
- var name: String
- var tile: Tile
- var neighbours: Array
+ var tiles: Array # Array[String]
+ var tile_instances: Array[Tile]
+ var tile_parent: Node3D
+ var interact_tile: Tile
+
+const NEIGHBOR_OFFSETS: Array[Vector2i] = [Vector2i.UP, Vector2i.LEFT, Vector2i.DOWN, Vector2i.RIGHT]
var tile_by_pos: Dictionary[Vector2i, TileInfo] = {}
-var autobake = false
+var autoflush = false
var currently_baked = false
var floor_node := MeshInstance3D.new()
-var tile_factory = TileFactory.new()
+var tile_factory := TileFactory.new()
-func get_tile_name(pos: Vector2i): # -> String?
+func get_tiles_at(pos: Vector2i): # -> Array[String]?
var e = tile_by_pos.get(pos)
- if e != null: return e.name
- else: return null
-func get_tile_instance(pos: Vector2i) -> Tile:
+ if e == null: return null
+ return e.tiles
+func get_topmost_instance(pos: Vector2i): # -> Tile?
var e = tile_by_pos.get(pos)
- if e != null: return e.tile
- else: return null
+ if e == null: return null
+ return e.tile_instances[-1]
+func get_tile_item(pos: Vector2i): # -> Item?
+ var e = get_topmost_instance(pos)
+ if e == null: return null
+ return e.item
-func set_tile(pos: Vector2i, name_: String, neighbors: Array = [null,null,null,null]) -> Tile:
- clear_tile(pos)
- var tile := tile_factory.produce(name_, pos, neighbors)
- add_child(tile)
- tile.position = Vector3(pos.x, 0, pos.y)
- tile_by_pos[pos] = TileInfo.new(pos, name_, tile, neighbors)
- return tile
+func set_all_tiles(changes: Dictionary[Vector2i, Array], srv: Game.ServerContext = null):
+ for pos: Vector2i in changes:
+ set_tiles(Vector2i(pos.x, pos.y), changes[pos], changes, srv)
-func clear_tile(pos: Vector2i):
- var tile = get_tile_instance(pos)
- if tile == null: return
- if tile.item != null: tile.item.queue_free()
- if tile is FloorLike:
- var floor_mesher = tile_factory.floor_meshers.get(tile.fm_id())
- if floor_mesher != null:
- floor_mesher.remove_tile(pos)
- tile.queue_free()
+func set_tiles(pos: Vector2i, tiles: Array = [], pending_changes: Dictionary[Vector2i, Array] = {}, srv: Game.ServerContext = null): # tiles: Array[String]
+ var tile_info = tile_by_pos.get(pos)
+ if tile_info != null:
+ for inst: Tile in tile_info.tile_instances:
+ for tile: String in tiles:
+ # TODO: Don't return, but handle changes which weren't handled by the instance below.
+ if inst.change(tile): return # Instance handled change itself!
+ _remove_tile(pos)
+ if not tiles.is_empty(): _add_tiles(pos, tiles, pending_changes, srv)
+ if autoflush: flush()
+
+func _add_tiles(pos: Vector2i, tiles: Array, pending_changes: Dictionary[Vector2i, Array], srv: Game.ServerContext) -> void:
+ # Find neighbor tile names
+ var neighbors: Array[Array] = [] # Array[Array[String]]
+ for offset: Vector2i in NEIGHBOR_OFFSETS:
+ var neighbor_pos: Vector2i = pos + offset
+ if pending_changes.has(neighbor_pos):
+ neighbors.append(pending_changes[neighbor_pos])
+ elif tile_by_pos.has(neighbor_pos):
+ neighbors.append(tile_by_pos[neighbor_pos])
+ else: neighbors.append([])
+
+ var tiles_parent = Node3D.new()
+ tiles_parent.name = str(pos)
+ var tile_instances = tile_factory.produce(tiles_parent, tiles, pos, neighbors, srv)
+ tile_by_pos[pos] = TileInfo.new(pos, tiles, tile_instances, tiles_parent)
+ add_child(tiles_parent)
+
+func _remove_tile(pos: Vector2i):
+ var tile_info = tile_by_pos.get(pos)
+ if tile_info == null: return
+
+ var topmost_instance = get_topmost_instance(pos)
+ if topmost_instance.item != null:
+ topmost_instance.item.queue_free()
+
+ for instance: Tile in tile_info.tile_instances:
+ if instance is FloorLike:
+ var floor_mesher = tile_factory.floor_meshers.get(instance.fm_id())
+ if floor_mesher != null:
+ floor_mesher.remove_tile(pos)
+ instance.queue_free()
tile_by_pos.erase(pos)
- tile.name += "_queued_free"
@onready var voxelgi: VoxelGI = $VoxelGI
func _ready():
- Settings.hook_changed("graphics.gi", "main", apply_gi_setting)
+ Settings.hook_changed("graphics.gi", self, apply_gi_setting)
floor_node.material_override = preload("res://map/tiles/floor_material.tres")
for fm in tile_factory.floor_meshers.values():
add_child(fm.mesh_instance)
diff --git a/client/map/map.tscn b/client/map/map.tscn
index 84a4f09b..27cd3900 100644
--- a/client/map/map.tscn
+++ b/client/map/map.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=4 format=3 uid="uid://b4gone8fu53r7"]
+[gd_scene format=3 uid="uid://b4gone8fu53r7"]
[ext_resource type="Script" uid="uid://bxuukjyme1git" path="res://map/map.gd" id="1_3en0a"]
@@ -6,9 +6,9 @@
[sub_resource type="VoxelGIData" id="VoxelGIData_m5j5n"]
-[node name="Map" type="Node3D"]
+[node name="Map" type="Node3D" unique_id=764657840]
script = ExtResource("1_3en0a")
-[node name="VoxelGI" type="VoxelGI" parent="."]
+[node name="VoxelGI" type="VoxelGI" parent="." unique_id=1789448607]
camera_attributes = SubResource("CameraAttributesPractical_kwk4i")
data = SubResource("VoxelGIData_m5j5n")
diff --git a/client/player/particles/checkmark/checkmark.gd b/client/map/particles/checkmark/checkmark.gd
index 106b1cc7..8a5cc248 100644
--- a/client/player/particles/checkmark/checkmark.gd
+++ b/client/map/particles/checkmark/checkmark.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/player/particles/checkmark/checkmark.gd.uid b/client/map/particles/checkmark/checkmark.gd.uid
index 913fb945..913fb945 100644
--- a/client/player/particles/checkmark/checkmark.gd.uid
+++ b/client/map/particles/checkmark/checkmark.gd.uid
diff --git a/client/player/particles/checkmark/checkmark.svg b/client/map/particles/checkmark/checkmark.svg
index f8a31e29..f8a31e29 100644
--- a/client/player/particles/checkmark/checkmark.svg
+++ b/client/map/particles/checkmark/checkmark.svg
diff --git a/client/player/particles/checkmark/checkmark.svg.import b/client/map/particles/checkmark/checkmark.svg.import
index 58f42635..4011e4f8 100644
--- a/client/player/particles/checkmark/checkmark.svg.import
+++ b/client/map/particles/checkmark/checkmark.svg.import
@@ -3,8 +3,8 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://c10wjga8ni7eq"
-path.s3tc="res://.godot/imported/checkmark.svg-fa4b3748aa6561b9772a9b05d1a5b098.s3tc.ctex"
-path.etc2="res://.godot/imported/checkmark.svg-fa4b3748aa6561b9772a9b05d1a5b098.etc2.ctex"
+path.s3tc="res://.godot/imported/checkmark.svg-6dd7b104b667f47666846eb9f77215a8.s3tc.ctex"
+path.etc2="res://.godot/imported/checkmark.svg-6dd7b104b667f47666846eb9f77215a8.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
@@ -12,8 +12,8 @@ metadata={
[deps]
-source_file="res://player/particles/checkmark/checkmark.svg"
-dest_files=["res://.godot/imported/checkmark.svg-fa4b3748aa6561b9772a9b05d1a5b098.s3tc.ctex", "res://.godot/imported/checkmark.svg-fa4b3748aa6561b9772a9b05d1a5b098.etc2.ctex"]
+source_file="res://map/particles/checkmark/checkmark.svg"
+dest_files=["res://.godot/imported/checkmark.svg-6dd7b104b667f47666846eb9f77215a8.s3tc.ctex", "res://.godot/imported/checkmark.svg-6dd7b104b667f47666846eb9f77215a8.etc2.ctex"]
[params]
diff --git a/client/player/particles/checkmark/checkmark.tscn b/client/map/particles/checkmark/checkmark.tscn
index b45056d4..25e3d606 100644
--- a/client/player/particles/checkmark/checkmark.tscn
+++ b/client/map/particles/checkmark/checkmark.tscn
@@ -1,7 +1,7 @@
-[gd_scene load_steps=7 format=3 uid="uid://bdbw8whs3data"]
+[gd_scene format=3 uid="uid://bdbw8whs3data"]
-[ext_resource type="Texture2D" uid="uid://c10wjga8ni7eq" path="res://player/particles/checkmark/checkmark.svg" id="1_co83x"]
-[ext_resource type="Script" uid="uid://bj1h0r3qvy6vm" path="res://player/particles/checkmark/checkmark.gd" id="2_ru6ov"]
+[ext_resource type="Texture2D" uid="uid://c10wjga8ni7eq" path="res://map/particles/checkmark/checkmark.svg" id="1_co83x"]
+[ext_resource type="Script" uid="uid://bj1h0r3qvy6vm" path="res://map/particles/checkmark/checkmark.gd" id="2_ru6ov"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ru6ov"]
transparency = 1
@@ -11,6 +11,9 @@ vertex_color_use_as_albedo = true
albedo_texture = ExtResource("1_co83x")
billboard_mode = 3
billboard_keep_scale = true
+particles_anim_h_frames = 1
+particles_anim_v_frames = 1
+particles_anim_loop = false
[sub_resource type="QuadMesh" id="QuadMesh_4d8iq"]
material = SubResource("StandardMaterial3D_ru6ov")
@@ -23,7 +26,7 @@ point_count = 3
offsets = PackedFloat32Array(0, 0.26672226, 0.4904026, 1)
colors = PackedColorArray(1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)
-[node name="Checkmark" type="CPUParticles3D"]
+[node name="Checkmark" type="CPUParticles3D" unique_id=56025052]
emitting = false
amount = 1
one_shot = true
diff --git a/client/map/progress/progress.gd b/client/map/progress/progress.gd
index d8d714ba..be8de5ae 100644
--- a/client/map/progress/progress.gd
+++ b/client/map/progress/progress.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/progress/progress.gdshader b/client/map/progress/progress.gdshader
index 3c3557cd..cbf1a3d2 100644
--- a/client/map/progress/progress.gdshader
+++ b/client/map/progress/progress.gdshader
@@ -1,6 +1,6 @@
/*
Hurry Curry! - a game about cooking
- Copyright (C) 2025 Hurry Curry! Contributors
+ Copyright (C) 2026 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
diff --git a/client/map/progress/progress.tscn b/client/map/progress/progress.tscn
index af7dfe0a..b8182ea5 100644
--- a/client/map/progress/progress.tscn
+++ b/client/map/progress/progress.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=5 format=3 uid="uid://4ewufm6tqhpb"]
+[gd_scene format=3 uid="uid://4ewufm6tqhpb"]
[ext_resource type="Shader" uid="uid://b3w7j4oka0yeb" path="res://map/progress/progress.gdshader" id="1_6f2a0"]
[ext_resource type="Script" uid="uid://dmdqg418vkip6" path="res://map/progress/progress.gd" id="2_bb3u3"]
@@ -13,7 +13,7 @@ shader = ExtResource("1_6f2a0")
shader_parameter/progress = 0.0
shader_parameter/bad = false
-[node name="Progress" type="MeshInstance3D"]
+[node name="Progress" type="MeshInstance3D" unique_id=2131670011]
mesh = SubResource("QuadMesh_m0itj")
surface_material_override/0 = SubResource("ShaderMaterial_4k6cy")
script = ExtResource("2_bb3u3")
diff --git a/client/map/tile_factory.gd b/client/map/tile_factory.gd
index 5a7f7e3e..d3d1ca8d 100644
--- a/client/map/tile_factory.gd
+++ b/client/map/tile_factory.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -20,8 +20,10 @@ extends Object
class TileName:
var name# : String
var variant #: String?
- func _init(raw_name: String):
- var c = Array(raw_name.split(":"))
+ var raw_name: String
+ func _init(raw_name_: String):
+ raw_name = raw_name_
+ var c = Array(raw_name_.split(":"))
name = c[0]; variant = c[1] if c.size() >= 2 else null # TODO Array.get throws errors
class TileCC:
@@ -29,6 +31,9 @@ class TileCC:
var position: Vector2i
var neighbors: Array
var floor_meshers: Dictionary[String, FloorMesher]
+ var server_context: Game.ServerContext
+ var below_tile_instances: Array[Tile]
+ var above_tile_names: Array[String]
var floor_meshers: Dictionary[String, FloorMesher] = {
"floor": FloorMesher.new(Floor.floor_mesh()),
@@ -37,25 +42,57 @@ var floor_meshers: Dictionary[String, FloorMesher] = {
"street": FloorMesher.new(Street.floor_mesh())
}
-func produce(raw_name: String, position: Vector2i, neighbors: Array) -> Tile:
+const TILE_COMBINATOR: Dictionary[Array, Array] = { # : Dictionary[Array[String], Array[String]]
+ ["counter", "sink"]: ["sink"]
+}
+
+func produce(parent: Node3D, tile_names: Array, position: Vector2i, neighbors: Array, server_context: Game.ServerContext = null) -> Array[Tile]:
+ # Combinate tiles
+ tile_names = tile_names.duplicate()
+ for k in TILE_COMBINATOR:
+ if G.has_all(tile_names, k):
+ for item: String in k: tile_names.erase(item)
+ tile_names.append_array(TILE_COMBINATOR[k])
+
+ var tile_instances: Array[Tile] = []
+ for i in range(tile_names.size()):
+ var tile_name: String = tile_names[i]
+ var above_tile_names: Array[String] = []
+ above_tile_names.append_array(tile_names.slice(i+1, tile_names.size()))
+ var tile := produce_part(tile_name, position, neighbors, tile_instances, above_tile_names, server_context)
+ tile_instances.append(tile)
+ tile.position = Vector3(position.x, 0, position.y)
+ parent.add_child(tile)
+
+ return tile_instances
+
+func produce_part(raw_name: String, position: Vector2i, neighbors: Array, below_tile_instances: Array[Tile] = [], above_tile_names: Array[String] = [], server_context: Game.ServerContext = null) -> Tile:
var tile_name = TileName.new(raw_name)
var ctx := TileCC.new()
ctx.tile_name = tile_name
ctx.position = position
- ctx.neighbors = neighbors.map(func(n): return null if n == null else TileName.new(n).name)
+ ctx.neighbors = neighbors.map(func(a):
+ if a != null:
+ return a.map(func(b): return null if b == null else TileName.new(b).name)
+ else: return null
+ )
ctx.floor_meshers = floor_meshers
+ ctx.server_context = server_context
+ ctx.below_tile_instances = below_tile_instances
+ ctx.above_tile_names = above_tile_names
match tile_name.name:
- "black-hole-counter": return ItemPortal.new(ctx, false)
- "black-hole": return PlayerPortal.new(ctx, false)
- "book": return Book.new(ctx)
- "ceiling-lamp": return CeilingLamp.new(ctx)
+ "book": return GenericTile.new(ctx, preload("res://map/tiles/book.tscn"))
+ "button": return Button_.new(ctx)
+ "button-base": return ButtonBase.new(ctx)
+ "ceiling-lamp": return GenericTile.new(ctx, preload("res://map/tiles/ceiling_lamp.tscn"))
"chair": return Chair.new(ctx)
- "chandelier": return Chandelier.new(ctx)
+ "chandelier": return GenericTile.new(ctx, preload("res://map/tiles/chandelier.tscn"))
"conveyor": return Conveyor.new(ctx)
"counter-window": return CounterWindow.new(ctx)
- "counter": return CounterBase.new(ctx)
+ "counter-window-conveyor": return CounterWindowConveyor.new(ctx)
+ "counter": return Counter.new(ctx)
"cutting-board": return CuttingBoard.new(ctx)
"door": return Door.new(ctx)
"fence": return Fence.new(ctx)
@@ -63,9 +100,11 @@ func produce(raw_name: String, position: Vector2i, neighbors: Array) -> Tile:
"freezer": return Freezer.new(ctx)
"grass": return Grass.new(ctx)
"lamp": return Lamp.new(ctx)
+ "map-selector": return GenericTile.new(ctx, preload("res://map/tiles/map_selector.tscn"))
"oven": return Oven.new(ctx)
"path": return Path.new(ctx)
"rolling-board": return RollingBoard.new(ctx)
+ "screen": return Screen.new(ctx)
"deep-fryer": return DeepFryer.new(ctx)
"sink": return Sink.new(ctx)
"stove": return Stove.new(ctx)
@@ -75,8 +114,12 @@ func produce(raw_name: String, position: Vector2i, neighbors: Array) -> Tile:
"tree": return ExteriorTree.new(ctx)
"wall-window": return WallWindow.new(ctx)
"wall": return Wall.new(ctx)
- "white-hole-counter": return ItemPortal.new(ctx, true)
- "white-hole": return PlayerPortal.new(ctx, true)
+ "white-hole-counter": return ItemPortal.new(ctx, 1)
+ "white-hole": return PlayerPortal.new(ctx)
+ "grey-hole-counter": return ItemPortal.new(ctx, 0)
+ "grey-hole": return PlayerPortal.new(ctx)
+ "black-hole-counter": return ItemPortal.new(ctx, -1)
+ "black-hole": return PlayerPortal.new(ctx)
"house-balcony": return HouseBalcony.new(ctx)
"house-door": return HouseDoor.new(ctx)
@@ -86,19 +129,51 @@ func produce(raw_name: String, position: Vector2i, neighbors: Array) -> Tile:
"house-roof": return HouseRoof.new(ctx)
"house-roof-chimney": return HouseRoofChimney.new(ctx)
- "bun-crate": return BunCrate.new(ctx)
- "cheese-crate": return CheeseCrate.new(ctx)
- "coconut-crate": return CoconutCrate.new(ctx)
- "fish-crate": return FishCrate.new(ctx)
- "flour-crate": return FlourCrate.new(ctx)
- "leek-crate": return LeekCrate.new(ctx)
- "lettuce-crate": return LettuceCrate.new(ctx)
- "mushroom-crate": return MushroomCrate.new(ctx)
- "steak-crate": return SteakCrate.new(ctx)
- "rice-crate": return RiceCrate.new(ctx)
- "strawberry-crate": return StrawberryCrate.new(ctx)
- "tomato-crate": return TomatoCrate.new(ctx)
- "potato-crate": return PotatoCrate.new(ctx)
+ "crate": return Crate.new(ctx)
+
+ # TODO: update maps to use "crate:..."
+ "bun-crate":
+ ctx.tile_name.variant = "bun"
+ return Crate.new(ctx)
+ "cheese-crate":
+ ctx.tile_name.variant = "cheese"
+ return Crate.new(ctx)
+ "coconut-crate":
+ ctx.tile_name.variant = "coconut"
+ return Crate.new(ctx)
+ "fish-crate":
+ ctx.tile_name.variant = "fish"
+ return Crate.new(ctx)
+ "flour-crate":
+ ctx.tile_name.variant = "flour"
+ return Crate.new(ctx)
+ "leek-crate":
+ ctx.tile_name.variant = "leek"
+ return Crate.new(ctx)
+ "lettuce-crate":
+ ctx.tile_name.variant = "lettuce"
+ return Crate.new(ctx)
+ "mushroom-crate":
+ ctx.tile_name.variant = "mushroom"
+ return Crate.new(ctx)
+ "noodles-crate":
+ ctx.tile_name.variant = "noodles"
+ return Crate.new(ctx)
+ "steak-crate":
+ ctx.tile_name.variant = "steak"
+ return Crate.new(ctx)
+ "rice-crate":
+ ctx.tile_name.variant = "rice"
+ return Crate.new(ctx)
+ "strawberry-crate":
+ ctx.tile_name.variant = "strawberry"
+ return Crate.new(ctx)
+ "tomato-crate":
+ ctx.tile_name.variant = "tomato"
+ return Crate.new(ctx)
+ "potato-crate":
+ ctx.tile_name.variant = "potato"
+ return Crate.new(ctx)
var t:
push_warning("tile %s unknown" % t)
diff --git a/client/map/tiles/active_interact_counter.gd b/client/map/tiles/active_interact_counter.gd
new file mode 100644
index 00000000..b44c862a
--- /dev/null
+++ b/client/map/tiles/active_interact_counter.gd
@@ -0,0 +1,61 @@
+# Hurry Curry! - a game about cooking
+# Copyright (C) 2026 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 <https://www.gnu.org/licenses/>.
+#
+@abstract
+class_name ActiveInteractCounter
+extends Tile
+
+var interact_sound: AudioStreamPlayer3D = AudioStreamPlayer3D.new()
+var interact_tool: Node3D
+var acting_players: Array[Player] = []
+var play_character_animation: Callable
+
+func _init(ctx: TileFactory.TileCC, station_model_: PackedScene, interact_tool_path: NodePath, play_character_animation_: Callable, audio_stream_: AudioStream):
+ super(ctx)
+ base.add_child(station_model_.instantiate())
+ interact_sound.stream = audio_stream_
+ add_child(interact_sound)
+ interact_tool = base.get_node(interact_tool_path)
+ play_character_animation = play_character_animation_
+
+func progress(position_: float, speed: float, warn: bool, acting_players_: Array[Player]):
+ super(position_, speed, warn, acting_players)
+
+ if speed != 0.:
+ if not interact_sound.playing: interact_sound.play()
+ acting_players = acting_players.filter(is_instance_valid) # Some players might have disconnected
+ var players_who_stopped := G.unordered_array_difference(acting_players, acting_players_)
+ for p: Player in players_who_stopped:
+ if p != null: play_character_animation.call(p, false)
+ for p: Player in acting_players_:
+ interact_tool.visible = false
+ play_character_animation.call(p, true)
+ elif speed == 0:
+ interact_sound.stop()
+ interact_tool.visible = true
+ for p: Player in acting_players:
+ play_character_animation.call(p, false)
+ acting_players = acting_players_
+
+func finish():
+ super()
+ acting_players = acting_players.filter(is_instance_valid) # Some players might have disconnected
+ for p: Player in acting_players:
+ play_character_animation.call(p, false)
+ interact_tool.visible = true
+ interact_sound.stop()
+
+static func interact_target(): # -> Vector3?
+ return Vector3(0., 0.575, 0.)
diff --git a/client/map/tiles/active_interact_counter.gd.uid b/client/map/tiles/active_interact_counter.gd.uid
new file mode 100644
index 00000000..c83526ff
--- /dev/null
+++ b/client/map/tiles/active_interact_counter.gd.uid
@@ -0,0 +1 @@
+uid://bc4l8km0pnuq5
diff --git a/client/map/tiles/book.gd.uid b/client/map/tiles/book.gd.uid
deleted file mode 100644
index a53157dc..00000000
--- a/client/map/tiles/book.gd.uid
+++ /dev/null
@@ -1 +0,0 @@
-uid://tx2an1h38i3c
diff --git a/client/map/tiles/book.res b/client/map/tiles/book.res
index 9caf89f1..fa64057a 100644
--- a/client/map/tiles/book.res
+++ b/client/map/tiles/book.res
Binary files differ
diff --git a/client/map/tiles/book.tscn b/client/map/tiles/book.tscn
index 9e1b144c..c7e9d141 100644
--- a/client/map/tiles/book.tscn
+++ b/client/map/tiles/book.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://c7fjfp5ygxsjc"]
+[gd_scene format=3 uid="uid://c7fjfp5ygxsjc"]
[ext_resource type="ArrayMesh" uid="uid://cgvow28wkwesp" path="res://map/tiles/book.res" id="1_vxs3d"]
-[node name="Book" type="Node3D"]
+[node name="Book" type="Node3D" unique_id=517586832]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=664640069]
transform = Transform3D(1.19249e-08, 0, -1, 0, 1, 0, 1, 0, 1.19249e-08, 0, 0.5, 0)
mesh = ExtResource("1_vxs3d")
-skeleton = NodePath("")
diff --git a/client/map/tiles/bun_crate.gd.uid b/client/map/tiles/bun_crate.gd.uid
deleted file mode 100644
index 508d423c..00000000
--- a/client/map/tiles/bun_crate.gd.uid
+++ /dev/null
@@ -1 +0,0 @@
-uid://db7xuasfi403l
diff --git a/client/map/tiles/bun_crate.tscn b/client/map/tiles/bun_crate.tscn
index 00c8ead5..47460a14 100644
--- a/client/map/tiles/bun_crate.tscn
+++ b/client/map/tiles/bun_crate.tscn
@@ -1,34 +1,34 @@
-[gd_scene load_steps=3 format=3 uid="uid://bg2ykqq6rnyx6"]
+[gd_scene format=3 uid="uid://bg2ykqq6rnyx6"]
[ext_resource type="ArrayMesh" uid="uid://btn7oh1v2k40p" path="res://map/tiles/crate.res" id="1_84iuk"]
[ext_resource type="ArrayMesh" uid="uid://ke5s5itvrqce" path="res://map/items/bun.res" id="2_a48hy"]
-[node name="BunCrate" type="Node3D"]
+[node name="BunCrate" type="Node3D" unique_id=1836475580]
-[node name="Crate" type="MeshInstance3D" parent="."]
+[node name="Crate" type="MeshInstance3D" parent="." unique_id=982382847]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_84iuk")
-[node name="Bun" type="MeshInstance3D" parent="."]
+[node name="Bun" type="MeshInstance3D" parent="." unique_id=1348733542]
transform = Transform3D(0.35355335, -0.35355335, 0, 0.35355335, 0.35355335, 0, 0, 0, 0.5, 0.075, 0.15, -0.175)
mesh = ExtResource("2_a48hy")
-[node name="Bun2" type="MeshInstance3D" parent="."]
+[node name="Bun2" type="MeshInstance3D" parent="." unique_id=590760409]
transform = Transform3D(0.35355335, -0.35355335, 0, 0.35355335, 0.35355335, 0, 0, 0, 0.5, -0.15, 0.15, -0.175)
mesh = ExtResource("2_a48hy")
-[node name="Bun3" type="MeshInstance3D" parent="."]
+[node name="Bun3" type="MeshInstance3D" parent="." unique_id=1530470047]
transform = Transform3D(0.35355335, -0.35355335, 0, 0.35355335, 0.35355335, 0, 0, 0, 0.5, 0.3, 0.15, -0.175)
mesh = ExtResource("2_a48hy")
-[node name="Bun4" type="MeshInstance3D" parent="."]
+[node name="Bun4" type="MeshInstance3D" parent="." unique_id=765223744]
transform = Transform3D(-0.35355338, 0.35355338, -4.371139e-08, 0.35355338, 0.35355338, 0, 3.090862e-08, -3.090862e-08, -0.5, -0.09912277, 0.15, 0.175)
mesh = ExtResource("2_a48hy")
-[node name="Bun5" type="MeshInstance3D" parent="."]
+[node name="Bun5" type="MeshInstance3D" parent="." unique_id=1175873093]
transform = Transform3D(-0.35355338, 0.35355338, -4.371139e-08, 0.35355338, 0.35355338, 0, 3.090862e-08, -3.090862e-08, -0.5, 0.12587723, 0.15, 0.17499998)
mesh = ExtResource("2_a48hy")
-[node name="Bun6" type="MeshInstance3D" parent="."]
+[node name="Bun6" type="MeshInstance3D" parent="." unique_id=1315373041]
transform = Transform3D(-0.35355338, 0.35355338, -4.371139e-08, 0.35355338, 0.35355338, 0, 3.090862e-08, -3.090862e-08, -0.5, -0.3241228, 0.15, 0.17500001)
mesh = ExtResource("2_a48hy")
diff --git a/client/map/tiles/button/accept.svg b/client/map/tiles/button/accept.svg
new file mode 100644
index 00000000..c703ae9a
--- /dev/null
+++ b/client/map/tiles/button/accept.svg
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="128px" viewBox="0 -960 960 960" width="128px">
+ <rect width="960" height="960" x="0" y="-960" fill="#00A300"/>
+ <path fill="#FFFFFF" d="m382-388 321-321q19-19 45-19t45 19q19 19 19 45t-19 45L427-253q-19 19-45 19t-45-19L167-423q-19-19-19-45t19-45q19-19 45-19t45 19l125 125Z"/>
+</svg>
diff --git a/client/map/tiles/button/accept.svg.import b/client/map/tiles/button/accept.svg.import
new file mode 100644
index 00000000..010d0f2a
--- /dev/null
+++ b/client/map/tiles/button/accept.svg.import
@@ -0,0 +1,45 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://c1rx5o81pcv8g"
+path.s3tc="res://.godot/imported/accept.svg-3967b4e72211bf837c252cb2420fcd55.s3tc.ctex"
+path.etc2="res://.godot/imported/accept.svg-3967b4e72211bf837c252cb2420fcd55.etc2.ctex"
+metadata={
+"imported_formats": ["s3tc_bptc", "etc2_astc"],
+"vram_texture": true
+}
+
+[deps]
+
+source_file="res://map/tiles/button/accept.svg"
+dest_files=["res://.godot/imported/accept.svg-3967b4e72211bf837c252cb2420fcd55.s3tc.ctex", "res://.godot/imported/accept.svg-3967b4e72211bf837c252cb2420fcd55.etc2.ctex"]
+
+[params]
+
+compress/mode=2
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=true
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=0
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/client/map/tiles/ceiling_lamp.gd b/client/map/tiles/button/button.gd
index 3b504ed7..f47eba2d 100644
--- a/client/map/tiles/ceiling_lamp.gd
+++ b/client/map/tiles/button/button.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -13,9 +13,12 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
-class_name CeilingLamp
-extends Floor
+class_name Button_
+extends Tile
+
+var button: ButtonModel = load("res://map/tiles/button/button.tscn").instantiate()
func _init(ctx: TileFactory.TileCC):
super(ctx)
- base.add_child(load("res://map/tiles/ceiling_lamp.tscn").instantiate())
+ base.add_child(button)
+ button.set_up(ctx.tile_name.variant)
diff --git a/client/map/tiles/button/button.gd.uid b/client/map/tiles/button/button.gd.uid
new file mode 100644
index 00000000..1475ad20
--- /dev/null
+++ b/client/map/tiles/button/button.gd.uid
@@ -0,0 +1 @@
+uid://dyxxrus52yxxi
diff --git a/client/map/tiles/button/button.tscn b/client/map/tiles/button/button.tscn
new file mode 100644
index 00000000..c8ba94ac
--- /dev/null
+++ b/client/map/tiles/button/button.tscn
@@ -0,0 +1,36 @@
+[gd_scene format=3 uid="uid://nhmmgqwlmc8g"]
+
+[ext_resource type="ArrayMesh" uid="uid://cgq0beass0omg" path="res://map/tiles/button/button_static.res" id="1_tihjt"]
+[ext_resource type="Script" uid="uid://c06qln7x5266q" path="res://map/tiles/button/button_model.gd" id="1_ubqac"]
+[ext_resource type="ArrayMesh" uid="uid://dhaxbrl6a0vg" path="res://map/tiles/button/button_dynamic_cancel.res" id="2_ubqac"]
+[ext_resource type="ArrayMesh" uid="uid://u6ugrx5nrfj7" path="res://map/tiles/button/button_dynamic_accept.res" id="3_lxai3"]
+
+[node name="Button" type="Node3D" unique_id=1558887746]
+script = ExtResource("1_ubqac")
+
+[node name="StaticMesh" type="MeshInstance3D" parent="." unique_id=1131117450]
+transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0.55, 0)
+mesh = ExtResource("1_tihjt")
+
+[node name="Dynamic" type="Node3D" parent="." unique_id=509704898]
+
+[node name="Reject" type="MeshInstance3D" parent="Dynamic" unique_id=1474668033]
+transform = Transform3D(0.375, 0, 0, 0, 0.5, 0, 0, 0, 0.375, 0, 0.525, 0)
+visible = false
+mesh = ExtResource("2_ubqac")
+
+[node name="Accept" type="MeshInstance3D" parent="Dynamic" unique_id=1159246571]
+transform = Transform3D(0.375, 0, 0, 0, 0.5, 0, 0, 0, 0.375, 0, 0.525, 0)
+mesh = ExtResource("3_lxai3")
+
+[node name="DynamicPressed" type="MeshInstance3D" parent="." unique_id=90564715]
+transform = Transform3D(0.75, 0, 0, 0, 1, 0, 0, 0, 0.75, 0, 1.0500001, 0)
+visible = false
+mesh = ExtResource("2_ubqac")
+
+[node name="OmniLight3D" type="OmniLight3D" parent="DynamicPressed" unique_id=172878339]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.52889466, 0)
+light_color = Color(1, 0, 0, 1)
+omni_range = 2.0
+
+[node name="AnimationPlayer" type="AnimationPlayer" parent="." unique_id=326186226]
diff --git a/client/map/tiles/button/button_dynamic_accept.res b/client/map/tiles/button/button_dynamic_accept.res
new file mode 100644
index 00000000..21440b95
--- /dev/null
+++ b/client/map/tiles/button/button_dynamic_accept.res
Binary files differ
diff --git a/client/map/tiles/button/button_dynamic_cancel.res b/client/map/tiles/button/button_dynamic_cancel.res
new file mode 100644
index 00000000..d17c4dd3
--- /dev/null
+++ b/client/map/tiles/button/button_dynamic_cancel.res
Binary files differ
diff --git a/client/map/tiles/button/button_model.gd b/client/map/tiles/button/button_model.gd
new file mode 100644
index 00000000..41a4674f
--- /dev/null
+++ b/client/map/tiles/button/button_model.gd
@@ -0,0 +1,28 @@
+# Hurry Curry! - a game about cooking
+# Copyright (C) 2026 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 <https://www.gnu.org/licenses/>.
+#
+class_name ButtonModel
+extends Node3D
+
+func set_up(variant: String):
+ match variant:
+ "accept":
+ $Dynamic/Accept.visible = true
+ $Dynamic/Reject.visible = false
+ "reject":
+ $Dynamic/Accept.visible = false
+ $Dynamic/Reject.visible = true
+ _:
+ push_error("Unrecognized button variant: %s" % variant)
diff --git a/client/map/tiles/button/button_model.gd.uid b/client/map/tiles/button/button_model.gd.uid
new file mode 100644
index 00000000..c9555c31
--- /dev/null
+++ b/client/map/tiles/button/button_model.gd.uid
@@ -0,0 +1 @@
+uid://c06qln7x5266q
diff --git a/client/map/tiles/button/button_static.res b/client/map/tiles/button/button_static.res
new file mode 100644
index 00000000..23ec99ec
--- /dev/null
+++ b/client/map/tiles/button/button_static.res
Binary files differ
diff --git a/client/map/tiles/button/cancel.svg b/client/map/tiles/button/cancel.svg
new file mode 100644
index 00000000..4f62fa5f
--- /dev/null
+++ b/client/map/tiles/button/cancel.svg
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="128px" viewBox="0 -960 960 960" width="128px">
+ <rect width="960" height="960" x="0" y="-960" fill="#EA0026"/>
+ <path fill="#FFFFFF" d="M480-392 300-212q-18 18-44 18t-44-18q-18-18-18-44t18-44l180-180-180-180q-18-18-18-44t18-44q18-18 44-18t44 18l180 180 180-180q18-18 44-18t44 18q18 18 18 44t-18 44L568-480l180 180q18 18 18 44t-18 44q-18 18-44 18t-44-18L480-392Z"/>
+</svg>
diff --git a/client/map/tiles/button/cancel.svg.import b/client/map/tiles/button/cancel.svg.import
new file mode 100644
index 00000000..98ab8ec5
--- /dev/null
+++ b/client/map/tiles/button/cancel.svg.import
@@ -0,0 +1,45 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://blp5workmjdpi"
+path.s3tc="res://.godot/imported/cancel.svg-c3c8e16f267e99928c19f8a5251da6ef.s3tc.ctex"
+path.etc2="res://.godot/imported/cancel.svg-c3c8e16f267e99928c19f8a5251da6ef.etc2.ctex"
+metadata={
+"imported_formats": ["s3tc_bptc", "etc2_astc"],
+"vram_texture": true
+}
+
+[deps]
+
+source_file="res://map/tiles/button/cancel.svg"
+dest_files=["res://.godot/imported/cancel.svg-c3c8e16f267e99928c19f8a5251da6ef.s3tc.ctex", "res://.godot/imported/cancel.svg-c3c8e16f267e99928c19f8a5251da6ef.etc2.ctex"]
+
+[params]
+
+compress/mode=2
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=true
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=0
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/client/map/tiles/button/map.svg b/client/map/tiles/button/map.svg
new file mode 100644
index 00000000..11146ddd
--- /dev/null
+++ b/client/map/tiles/button/map.svg
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="128px" viewBox="0 -960 960 960" width="128px">
+ <rect width="960" height="960" x="0" y="-960" fill="#0053C1"/>
+ <path fill="#FFFFFF" d="m612-94-263-93-170 69q-30 14-57-3.5T95-173v-558q0-21 12-38t32-24l210-73 263 92 169-69q30-13 57.5 4t27.5 51v565q0 20-12.5 34.5T822-168L612-94Zm-34-112v-484l-196-66v484l196 66Zm60 0 133-43v-492l-133 51v484Zm-449-15 133-51v-484l-133 44v491Zm449-469v484-484Zm-316-66v484-484Z"/>
+</svg>
diff --git a/client/map/tiles/button/map.svg.import b/client/map/tiles/button/map.svg.import
new file mode 100644
index 00000000..c2471747
--- /dev/null
+++ b/client/map/tiles/button/map.svg.import
@@ -0,0 +1,45 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dnbivk0cko3kn"
+path.s3tc="res://.godot/imported/map.svg-83021c6555bc23e5e8a2e0aa8351ba08.s3tc.ctex"
+path.etc2="res://.godot/imported/map.svg-83021c6555bc23e5e8a2e0aa8351ba08.etc2.ctex"
+metadata={
+"imported_formats": ["s3tc_bptc", "etc2_astc"],
+"vram_texture": true
+}
+
+[deps]
+
+source_file="res://map/tiles/button/map.svg"
+dest_files=["res://.godot/imported/map.svg-83021c6555bc23e5e8a2e0aa8351ba08.s3tc.ctex", "res://.godot/imported/map.svg-83021c6555bc23e5e8a2e0aa8351ba08.etc2.ctex"]
+
+[params]
+
+compress/mode=2
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=true
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=0
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/client/map/tiles/flour_crate.gd b/client/map/tiles/button_base.gd
index a8fd5386..1ceee5e2 100644
--- a/client/map/tiles/flour_crate.gd
+++ b/client/map/tiles/button_base.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -13,9 +13,12 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
-class_name FlourCrate
-extends Crate
+class_name ButtonBase
+extends Tile
func _init(ctx: TileFactory.TileCC):
super(ctx)
- base.add_child(load("res://map/tiles/flour_crate.tscn").instantiate())
+ base.add_child(load("res://map/tiles/button_base.tscn").instantiate())
+
+static func interact_target(): # -> Vector3?
+ return Vector3(0, .5, 0)
diff --git a/client/map/tiles/button_base.gd.uid b/client/map/tiles/button_base.gd.uid
new file mode 100644
index 00000000..eafbd5d4
--- /dev/null
+++ b/client/map/tiles/button_base.gd.uid
@@ -0,0 +1 @@
+uid://dblj24kid00tx
diff --git a/client/map/tiles/button_base.res b/client/map/tiles/button_base.res
new file mode 100644
index 00000000..ba909081
--- /dev/null
+++ b/client/map/tiles/button_base.res
Binary files differ
diff --git a/client/map/tiles/button_base.tscn b/client/map/tiles/button_base.tscn
new file mode 100644
index 00000000..8e3efbab
--- /dev/null
+++ b/client/map/tiles/button_base.tscn
@@ -0,0 +1,9 @@
+[gd_scene format=3 uid="uid://bfbq0lsh7gp21"]
+
+[ext_resource type="ArrayMesh" uid="uid://d3867ya8moxb5" path="res://map/tiles/button_base.res" id="1_yvd7h"]
+
+[node name="ButtonBase" type="Node3D" unique_id=1753800164]
+
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=305913322]
+transform = Transform3D(-2.1855694e-08, 0.5, -2.1855694e-08, 0, -2.1855694e-08, -0.5, -0.5, -2.1855694e-08, 9.553427e-16, 0, 0, 0)
+mesh = ExtResource("1_yvd7h")
diff --git a/client/map/tiles/ceiling_lamp.gd.uid b/client/map/tiles/ceiling_lamp.gd.uid
deleted file mode 100644
index 23e304d9..00000000
--- a/client/map/tiles/ceiling_lamp.gd.uid
+++ /dev/null
@@ -1 +0,0 @@
-uid://c2eke3hg0l85c
diff --git a/client/map/tiles/ceiling_lamp.res b/client/map/tiles/ceiling_lamp.res
index f35e266b..37c4aa7b 100644
--- a/client/map/tiles/ceiling_lamp.res
+++ b/client/map/tiles/ceiling_lamp.res
Binary files differ
diff --git a/client/map/tiles/ceiling_lamp.tscn b/client/map/tiles/ceiling_lamp.tscn
index 50f79e11..dd2f5511 100644
--- a/client/map/tiles/ceiling_lamp.tscn
+++ b/client/map/tiles/ceiling_lamp.tscn
@@ -1,16 +1,15 @@
-[gd_scene load_steps=3 format=3 uid="uid://c8hu5h6dt0ixj"]
+[gd_scene format=3 uid="uid://c8hu5h6dt0ixj"]
[ext_resource type="ArrayMesh" uid="uid://bsir47jru4um7" path="res://map/tiles/ceiling_lamp.res" id="1_twi66"]
[ext_resource type="Script" uid="uid://nm4trjneu1qt" path="res://map/tiles/light_tile.gd" id="1_yyibl"]
-[node name="CeilingLamp" type="Node3D" node_paths=PackedStringArray("lights")]
+[node name="CeilingLamp" type="Node3D" unique_id=1236677325 node_paths=PackedStringArray("lights")]
script = ExtResource("1_yyibl")
lights = [NodePath("OmniLight3D")]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1645317673]
transform = Transform3D(100, 0, 0, 0, -1.19209e-05, 100, 0, -100, -1.19209e-05, 0, 1.875, 0)
mesh = ExtResource("1_twi66")
-skeleton = NodePath("")
-[node name="OmniLight3D" type="OmniLight3D" parent="."]
+[node name="OmniLight3D" type="OmniLight3D" parent="." unique_id=1571857968]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.4, 0)
diff --git a/client/map/tiles/chair.gd b/client/map/tiles/chair.gd
index c17f3f9b..d5669dca 100644
--- a/client/map/tiles/chair.gd
+++ b/client/map/tiles/chair.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -14,19 +14,16 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
class_name Chair
-extends Floor
+extends Tile
func _init(ctx: TileFactory.TileCC):
super(ctx)
var chair = preload("res://map/tiles/chair.tscn").instantiate()
var facing = 0;
for i in range(4):
- if ctx.neighbors[i] == "conveyor":
- facing = i
- break
- for i in range(4):
- if ctx.neighbors[i] == "table":
+ if G.has_one(ctx.neighbors[i], ["coveyor", "table", "counter"]):
facing = i
break
+
base.add_child(chair)
turn_facing(facing)
diff --git a/client/map/tiles/chair.res b/client/map/tiles/chair.res
index cbf730ab..b6f1aa48 100644
--- a/client/map/tiles/chair.res
+++ b/client/map/tiles/chair.res
Binary files differ
diff --git a/client/map/tiles/chair.tscn b/client/map/tiles/chair.tscn
index 5ba28da7..406f2661 100644
--- a/client/map/tiles/chair.tscn
+++ b/client/map/tiles/chair.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://bn1l1mcn8240o"]
+[gd_scene format=3 uid="uid://bn1l1mcn8240o"]
[ext_resource type="ArrayMesh" uid="uid://cwn5nt017j62d" path="res://map/tiles/chair.res" id="1_8tboh"]
-[node name="Chair" type="Node3D"]
+[node name="Chair" type="Node3D" unique_id=446076584]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=311426126]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_8tboh")
-skeleton = NodePath("")
diff --git a/client/map/tiles/chandelier.gd b/client/map/tiles/chandelier.gd
deleted file mode 100644
index cce877ea..00000000
--- a/client/map/tiles/chandelier.gd
+++ /dev/null
@@ -1,21 +0,0 @@
-# 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 <https://www.gnu.org/licenses/>.
-#
-class_name Chandelier
-extends Floor
-
-func _init(ctx: TileFactory.TileCC):
- super(ctx)
- base.add_child(load("res://map/tiles/chandelier.tscn").instantiate())
diff --git a/client/map/tiles/chandelier.gd.uid b/client/map/tiles/chandelier.gd.uid
deleted file mode 100644
index df037e09..00000000
--- a/client/map/tiles/chandelier.gd.uid
+++ /dev/null
@@ -1 +0,0 @@
-uid://xj1r8ubad6mu
diff --git a/client/map/tiles/chandelier.res b/client/map/tiles/chandelier.res
index d8007bb8..47b1c017 100644
--- a/client/map/tiles/chandelier.res
+++ b/client/map/tiles/chandelier.res
Binary files differ
diff --git a/client/map/tiles/chandelier.tscn b/client/map/tiles/chandelier.tscn
index d4e4dd71..a8a4b617 100644
--- a/client/map/tiles/chandelier.tscn
+++ b/client/map/tiles/chandelier.tscn
@@ -1,16 +1,15 @@
-[gd_scene load_steps=3 format=3 uid="uid://coql3wlp3jwoc"]
+[gd_scene format=3 uid="uid://coql3wlp3jwoc"]
[ext_resource type="Script" uid="uid://nm4trjneu1qt" path="res://map/tiles/light_tile.gd" id="1_6vise"]
[ext_resource type="ArrayMesh" uid="uid://d11c3fl48g7qb" path="res://map/tiles/chandelier.res" id="1_urqpe"]
-[node name="Chandelier" type="Node3D"]
+[node name="Chandelier" type="Node3D" unique_id=396940130]
script = ExtResource("1_6vise")
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=989396255]
transform = Transform3D(100, 0, 0, 0, -1.19209e-05, 100, 0, -100, -1.19209e-05, 0, 1.875, 0)
mesh = ExtResource("1_urqpe")
-skeleton = NodePath("")
-[node name="OmniLight3D" type="OmniLight3D" parent="."]
+[node name="OmniLight3D" type="OmniLight3D" parent="." unique_id=102026265]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, 0)
light_color = Color(0.945098, 0.886275, 0.745098, 1)
diff --git a/client/map/tiles/cheese_crate.gd b/client/map/tiles/cheese_crate.gd
deleted file mode 100644
index 2965b8c0..00000000
--- a/client/map/tiles/cheese_crate.gd
+++ /dev/null
@@ -1,21 +0,0 @@
-# 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 <https://www.gnu.org/licenses/>.
-#
-class_name CheeseCrate
-extends Crate
-
-func _init(ctx: TileFactory.TileCC):
- super(ctx)
- base.add_child(load("res://map/tiles/cheese_crate.tscn").instantiate())
diff --git a/client/map/tiles/cheese_crate.gd.uid b/client/map/tiles/cheese_crate.gd.uid
deleted file mode 100644
index 36a6ceb9..00000000
--- a/client/map/tiles/cheese_crate.gd.uid
+++ /dev/null
@@ -1 +0,0 @@
-uid://pwmpgyk3prdi
diff --git a/client/map/tiles/cheese_crate.tscn b/client/map/tiles/cheese_crate.tscn
index 7a1bd93a..f78ea177 100644
--- a/client/map/tiles/cheese_crate.tscn
+++ b/client/map/tiles/cheese_crate.tscn
@@ -1,24 +1,24 @@
-[gd_scene load_steps=3 format=3 uid="uid://do7vpyky2hdd0"]
+[gd_scene format=3 uid="uid://do7vpyky2hdd0"]
[ext_resource type="PackedScene" uid="uid://xdui0oya4lpb" path="res://map/tiles/crate.tscn" id="1_7kkwt"]
[ext_resource type="PackedScene" uid="uid://0lbjf2sie4rk" path="res://map/items/cheese.tscn" id="2_3iu16"]
-[node name="CheeseCrate" instance=ExtResource("1_7kkwt")]
+[node name="CheeseCrate" unique_id=1947061861 instance=ExtResource("1_7kkwt")]
-[node name="Cheese" parent="." index="1" instance=ExtResource("2_3iu16")]
+[node name="Cheese" parent="." index="1" unique_id=1357798385 instance=ExtResource("2_3iu16")]
transform = Transform3D(0.939693, 0, 0.34202, 0, 1, 0, -0.34202, 0, 0.939693, -0.155919, 0.03, -0.239194)
-[node name="Cheese2" parent="." index="2" instance=ExtResource("2_3iu16")]
+[node name="Cheese2" parent="." index="2" unique_id=1162582783 instance=ExtResource("2_3iu16")]
transform = Transform3D(-0.766045, 0, -0.642788, 0, 1, 0, 0.642788, 0, -0.766045, 0.143516, 0.03, -0.129342)
-[node name="Cheese3" parent="." index="3" instance=ExtResource("2_3iu16")]
+[node name="Cheese3" parent="." index="3" unique_id=2099970654 instance=ExtResource("2_3iu16")]
transform = Transform3D(0.822958, 0, -0.568102, 0, 1, 0, 0.568102, 0, 0.822958, -0.139973, 0.03, 0.178952)
-[node name="Cheese4" parent="." index="4" instance=ExtResource("2_3iu16")]
+[node name="Cheese4" parent="." index="4" unique_id=1356373605 instance=ExtResource("2_3iu16")]
transform = Transform3D(-0.909381, 0, 0.415964, 0, 1, 0, -0.415964, 0, -0.909381, 0.17718, 0.03, 0.178952)
-[node name="Cheese5" parent="." index="5" instance=ExtResource("2_3iu16")]
+[node name="Cheese5" parent="." index="5" unique_id=1934598214 instance=ExtResource("2_3iu16")]
transform = Transform3D(-0.909381, 0, 0.415964, 0, 1, 0, -0.415964, 0, -0.909381, 0.102617, 0.25, -0.074814)
-[node name="Cheese6" parent="." index="6" instance=ExtResource("2_3iu16")]
+[node name="Cheese6" parent="." index="6" unique_id=1487135630 instance=ExtResource("2_3iu16")]
transform = Transform3D(-0.11381, 0, 0.993503, 0, 1, 0, -0.993503, 0, -0.11381, -0.207069, 0.25, 0.0827757)
diff --git a/client/map/tiles/coconut_crate.gd b/client/map/tiles/coconut_crate.gd
deleted file mode 100644
index 34c41f18..00000000
--- a/client/map/tiles/coconut_crate.gd
+++ /dev/null
@@ -1,21 +0,0 @@
-# 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 <https://www.gnu.org/licenses/>.
-#
-class_name CoconutCrate
-extends Crate
-
-func _init(ctx: TileFactory.TileCC):
- super(ctx)
- base.add_child(load("res://map/tiles/coconut_crate.tscn").instantiate())
diff --git a/client/map/tiles/coconut_crate.gd.uid b/client/map/tiles/coconut_crate.gd.uid
deleted file mode 100644
index 82cbfa8f..00000000
--- a/client/map/tiles/coconut_crate.gd.uid
+++ /dev/null
@@ -1 +0,0 @@
-uid://d2m7s35j2lyeb
diff --git a/client/map/tiles/coconut_crate.tscn b/client/map/tiles/coconut_crate.tscn
index af2146b1..e379d0ba 100644
--- a/client/map/tiles/coconut_crate.tscn
+++ b/client/map/tiles/coconut_crate.tscn
@@ -1,18 +1,18 @@
-[gd_scene load_steps=3 format=3 uid="uid://cti8difugwnxm"]
+[gd_scene format=3 uid="uid://cti8difugwnxm"]
[ext_resource type="PackedScene" uid="uid://xdui0oya4lpb" path="res://map/tiles/crate.tscn" id="1_1qpmd"]
[ext_resource type="PackedScene" uid="uid://cmsirxgv7iqnk" path="res://map/items/coconut.tscn" id="3_s5fgf"]
-[node name="StrawberryCrate" instance=ExtResource("1_1qpmd")]
+[node name="StrawberryCrate" unique_id=238285369 instance=ExtResource("1_1qpmd")]
-[node name="Coconut" parent="." index="1" instance=ExtResource("3_s5fgf")]
+[node name="Coconut" parent="." index="1" unique_id=1982239539 instance=ExtResource("3_s5fgf")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.177501, 0, -0.17735)
-[node name="Coconut2" parent="." index="2" instance=ExtResource("3_s5fgf")]
+[node name="Coconut2" parent="." index="2" unique_id=1881504205 instance=ExtResource("3_s5fgf")]
transform = Transform3D(0.735258, 0, 0.677788, 0, 1, 0, -0.677788, 0, 0.735258, 0.185726, 0, -0.192698)
-[node name="Coconut3" parent="." index="3" instance=ExtResource("3_s5fgf")]
+[node name="Coconut3" parent="." index="3" unique_id=71866705 instance=ExtResource("3_s5fgf")]
transform = Transform3D(0.835347, 0, -0.549723, 0, 1, 0, 0.549723, 0, 0.835347, -0.177501, 0, 0.17735)
-[node name="Coconut4" parent="." index="4" instance=ExtResource("3_s5fgf")]
+[node name="Coconut4" parent="." index="4" unique_id=1363077163 instance=ExtResource("3_s5fgf")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.184021, 0, 0.17735)
diff --git a/client/map/tiles/conveyor.gd b/client/map/tiles/conveyor.gd
index 60505425..e5e908b4 100644
--- a/client/map/tiles/conveyor.gd
+++ b/client/map/tiles/conveyor.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -14,7 +14,7 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
class_name Conveyor
-extends Floor
+extends Tile
var conveyor: ConveyorModel = preload("res://map/tiles/conveyor.tscn").instantiate()
@@ -22,7 +22,7 @@ func _init(ctx: TileFactory.TileCC):
super(ctx)
base.add_child(conveyor)
-static func interact_target() -> Vector3:
+static func interact_target(): # -> Vector3?
return Vector3(0., .425, 0.)
func pass_to(tile: Tile):
diff --git a/client/map/tiles/conveyor.res b/client/map/tiles/conveyor.res
index e28bb057..2fcdf2bc 100644
--- a/client/map/tiles/conveyor.res
+++ b/client/map/tiles/conveyor.res
Binary files differ
diff --git a/client/map/tiles/conveyor.tscn b/client/map/tiles/conveyor.tscn
index 62e967a2..d5a53a6e 100644
--- a/client/map/tiles/conveyor.tscn
+++ b/client/map/tiles/conveyor.tscn
@@ -1,11 +1,11 @@
-[gd_scene load_steps=6 format=3 uid="uid://df5wbypoqbkf"]
+[gd_scene format=3 uid="uid://df5wbypoqbkf"]
[ext_resource type="ArrayMesh" uid="uid://djet05vuyh6iv" path="res://map/tiles/conveyor.res" id="1_hoctt"]
[ext_resource type="Script" uid="uid://sawoy4fqmd43" path="res://map/tiles/conveyor_model.gd" id="1_xdf1u"]
[ext_resource type="PackedScene" uid="uid://60wue8ult1bx" path="res://map/tiles/conveyor_direction.tscn" id="2_sf55l"]
[ext_resource type="Shader" uid="uid://2cpdtie0rquv" path="res://map/tiles/conveyor_direction.gdshader" id="4_8s3rd"]
-[sub_resource type="ShaderMaterial" id="ShaderMaterial_bgatf"]
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_vkrca"]
resource_local_to_scene = true
render_priority = 0
shader = ExtResource("4_8s3rd")
@@ -15,14 +15,13 @@ shader_parameter/width = 0.2
shader_parameter/speed = 1.0
shader_parameter/alpha_fac = 1.0
-[node name="Conveyor" type="Node3D"]
+[node name="Conveyor" type="Node3D" unique_id=1694281657]
script = ExtResource("1_xdf1u")
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=863772891]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_hoctt")
-skeleton = NodePath("")
-[node name="ConveyorDirection" parent="." instance=ExtResource("2_sf55l")]
+[node name="ConveyorDirection" parent="." unique_id=889314478 instance=ExtResource("2_sf55l")]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0.43, 0)
-surface_material_override/0 = SubResource("ShaderMaterial_bgatf")
+surface_material_override/0 = SubResource("ShaderMaterial_vkrca")
diff --git a/client/map/tiles/conveyor_direction.gdshader b/client/map/tiles/conveyor_direction.gdshader
index d59fcd2d..7adef653 100644
--- a/client/map/tiles/conveyor_direction.gdshader
+++ b/client/map/tiles/conveyor_direction.gdshader
@@ -1,6 +1,6 @@
/*
Hurry Curry! - a game about cooking
- Copyright (C) 2025 Hurry Curry! Contributors
+ Copyright (C) 2026 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
diff --git a/client/map/tiles/conveyor_direction.tscn b/client/map/tiles/conveyor_direction.tscn
index 79eae94c..5fe0baf1 100644
--- a/client/map/tiles/conveyor_direction.tscn
+++ b/client/map/tiles/conveyor_direction.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=4 format=3 uid="uid://60wue8ult1bx"]
+[gd_scene format=3 uid="uid://60wue8ult1bx"]
[ext_resource type="Shader" uid="uid://2cpdtie0rquv" path="res://map/tiles/conveyor_direction.gdshader" id="1_47s57"]
@@ -15,7 +15,7 @@ shader_parameter/width = 0.2
shader_parameter/speed = 1.0
shader_parameter/alpha_fac = 1.0
-[node name="ConveyorDirection" type="MeshInstance3D"]
+[node name="ConveyorDirection" type="MeshInstance3D" unique_id=1563649411]
transform = Transform3D(1, 0, 0, 0, 1.19249e-08, 1, 0, -1, 1.19249e-08, 0, 0, 0)
mesh = SubResource("QuadMesh_hr8jj")
surface_material_override/0 = SubResource("ShaderMaterial_h5q6r")
diff --git a/client/map/tiles/conveyor_model.gd b/client/map/tiles/conveyor_model.gd
index 1cbeb8a2..fcf36675 100644
--- a/client/map/tiles/conveyor_model.gd
+++ b/client/map/tiles/conveyor_model.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -26,5 +26,5 @@ func _process(delta):
func to_direction(direction: Vector2):
direction.y *= -1
- $ConveyorDirection.rotation.y = direction.angle() + .5 * PI
+ $ConveyorDirection.global_rotation.y = direction.angle() + .5 * PI
alpha = 1.
diff --git a/client/map/tiles/counter.gd b/client/map/tiles/counter.gd
index bd16c7a3..b8e7531a 100644
--- a/client/map/tiles/counter.gd
+++ b/client/map/tiles/counter.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -14,69 +14,14 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
class_name Counter
-extends Floor
-
-const COUNTERS: Array = [
- "counter",
- "pan",
- "sink",
- "oven",
-]
-
-const FLOORS: Array = [
- "floor",
- "chandelier",
- "ceiling-lamp",
- "grass",
- "table",
- "chair"
-]
-
-enum CounterKind {
- OUTER_CORNER,
- STRAIGHT,
- STRAIGHT_BACKSPLASH
-}
-
-var kind: CounterKind = CounterKind.STRAIGHT
-
-static func interact_target() -> Vector3:
- return Vector3(0, 0.5, 0)
+extends CounterLike
func _init(ctx: TileFactory.TileCC):
super(ctx)
-
- var facing: int = 0
- var max_series: int = 0
- var max_idx: int = 0
- for start in range(4):
- var series = 0
- for i in range(4):
- if Counter.is_floor(ctx.neighbors[(start + i) % 4]):
- series += 1
- else:
- break
- if series > max_series:
- max_series = series
- max_idx = start
-
- # we can neither find out whether it is an inner corner nor an outer corner
- # backsplash
- facing = max_idx
- if max_series == 1:
- if WallTile.WALLS.has(ctx.neighbors[(max_idx + 2) % 4]):
- kind = CounterKind.STRAIGHT_BACKSPLASH
- else:
- kind = CounterKind.STRAIGHT
- elif max_series == 2:
- kind = CounterKind.OUTER_CORNER
-
- turn_facing(facing)
-
-static func is_counter(tile_name_t) -> bool:
- if tile_name_t == null:
- return false
- return tile_name_t.ends_with("crate") or COUNTERS.has(tile_name_t)
-
-static func is_floor(floor_name) -> bool:
- return FLOORS.has(floor_name)
+ match kind:
+ CounterKind.OUTER_CORNER:
+ base.add_child(load("res://map/tiles/counter_outer_corner.tscn").instantiate())
+ CounterKind.STRAIGHT:
+ base.add_child(load("res://map/tiles/counter_straight.tscn").instantiate())
+ CounterKind.STRAIGHT_BACKSPLASH:
+ base.add_child(load("res://map/tiles/counter_straight_backsplash.tscn").instantiate())
diff --git a/client/map/tiles/counter.gd.uid b/client/map/tiles/counter.gd.uid
index 0fd45b66..395db459 100644
--- a/client/map/tiles/counter.gd.uid
+++ b/client/map/tiles/counter.gd.uid
@@ -1 +1 @@
-uid://bs61uem0427k6
+uid://bj8o06q70sek2
diff --git a/client/map/tiles/counter_base.gd.uid b/client/map/tiles/counter_base.gd.uid
deleted file mode 100644
index f46c79fa..00000000
--- a/client/map/tiles/counter_base.gd.uid
+++ /dev/null
@@ -1 +0,0 @@
-uid://dx116e5ebg1p4
diff --git a/client/map/tiles/counter_like.gd b/client/map/tiles/counter_like.gd
new file mode 100644
index 00000000..ebecbbfa
--- /dev/null
+++ b/client/map/tiles/counter_like.gd
@@ -0,0 +1,80 @@
+# Hurry Curry! - a game about cooking
+# Copyright (C) 2026 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 <https://www.gnu.org/licenses/>.
+#
+class_name CounterLike
+extends Tile
+
+const COUNTERS: Array = [
+ "counter",
+ "pan",
+ "sink",
+ "oven",
+]
+
+const FLOORS: Array = [
+ "floor",
+ "chandelier",
+ "ceiling-lamp",
+ "grass",
+ "table",
+ "chair"
+]
+
+enum CounterKind {
+ OUTER_CORNER,
+ STRAIGHT,
+ STRAIGHT_BACKSPLASH
+}
+
+var kind: CounterKind = CounterKind.STRAIGHT
+
+static func interact_target(): # -> Vector3?
+ return Vector3(0, 0.5, 0)
+
+func _init(ctx: TileFactory.TileCC):
+ super(ctx)
+
+ var facing: int = 0
+ var max_series: int = 0
+ var max_idx: int = 0
+ for start in range(4):
+ var series = 0
+ for i in range(4):
+ if not is_attachable(ctx.neighbors[(start + i) % 4]):
+ series += 1
+ else:
+ break
+ if series > max_series:
+ max_series = series
+ max_idx = start
+
+ # we can neither find out whether it is an inner corner nor an outer corner
+ # backsplash
+ facing = max_idx
+ if max_series == 1:
+ if G.has_one(WallTile.WALLS, ctx.neighbors[(max_idx + 2) % 4]):
+ kind = CounterKind.STRAIGHT_BACKSPLASH
+ else:
+ kind = CounterKind.STRAIGHT
+ elif max_series == 2:
+ kind = CounterKind.OUTER_CORNER
+
+ turn_facing(facing)
+
+static func is_attachable(neighbor: Array) -> bool:
+ for tile: String in neighbor:
+ if tile.ends_with("crate"): return true
+ if COUNTERS.has(tile): return true
+ return false
diff --git a/client/map/tiles/counter_like.gd.uid b/client/map/tiles/counter_like.gd.uid
new file mode 100644
index 00000000..0fd45b66
--- /dev/null
+++ b/client/map/tiles/counter_like.gd.uid
@@ -0,0 +1 @@
+uid://bs61uem0427k6
diff --git a/client/map/tiles/counter_outer_corner.res b/client/map/tiles/counter_outer_corner.res
index 68488c25..e647a046 100644
--- a/client/map/tiles/counter_outer_corner.res
+++ b/client/map/tiles/counter_outer_corner.res
Binary files differ
diff --git a/client/map/tiles/counter_outer_corner.tscn b/client/map/tiles/counter_outer_corner.tscn
index c5227dfc..ca202f48 100644
--- a/client/map/tiles/counter_outer_corner.tscn
+++ b/client/map/tiles/counter_outer_corner.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://blh11npblosbh"]
+[gd_scene format=3 uid="uid://blh11npblosbh"]
[ext_resource type="ArrayMesh" uid="uid://brpeawypw3jmg" path="res://map/tiles/counter_outer_corner.res" id="1_rq22t"]
-[node name="Counter" type="Node3D"]
+[node name="Counter" type="Node3D" unique_id=1053408630]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1111773353]
transform = Transform3D(-2.18557e-08, 0, 0.5, 0, 0.5, 0, -0.5, 0, -2.18557e-08, 0, 0, 0)
mesh = ExtResource("1_rq22t")
-skeleton = NodePath("")
diff --git a/client/map/tiles/counter_straight.res b/client/map/tiles/counter_straight.res
index 78a0cad3..9e95bccc 100644
--- a/client/map/tiles/counter_straight.res
+++ b/client/map/tiles/counter_straight.res
Binary files differ
diff --git a/client/map/tiles/counter_straight.tscn b/client/map/tiles/counter_straight.tscn
index 74517d2d..20016723 100644
--- a/client/map/tiles/counter_straight.tscn
+++ b/client/map/tiles/counter_straight.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://cg084pjthp7tn"]
+[gd_scene format=3 uid="uid://cg084pjthp7tn"]
[ext_resource type="ArrayMesh" uid="uid://btafby3tayv7r" path="res://map/tiles/counter_straight.res" id="1_5ksmf"]
-[node name="Counter" type="Node3D"]
+[node name="Counter" type="Node3D" unique_id=264805024]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=9093183]
mesh = ExtResource("1_5ksmf")
-skeleton = NodePath("")
diff --git a/client/map/tiles/counter_straight_backsplash.res b/client/map/tiles/counter_straight_backsplash.res
index 80845fc0..313c99f8 100644
--- a/client/map/tiles/counter_straight_backsplash.res
+++ b/client/map/tiles/counter_straight_backsplash.res
Binary files differ
diff --git a/client/map/tiles/counter_straight_backsplash.tscn b/client/map/tiles/counter_straight_backsplash.tscn
index 3490df9c..e243836a 100644
--- a/client/map/tiles/counter_straight_backsplash.tscn
+++ b/client/map/tiles/counter_straight_backsplash.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://blcqlogspnah1"]
+[gd_scene format=3 uid="uid://blcqlogspnah1"]
[ext_resource type="ArrayMesh" uid="uid://cdlmrxt42emtr" path="res://map/tiles/counter_straight_backsplash.res" id="1_3t3hs"]
-[node name="Counter" type="Node3D"]
+[node name="Counter" type="Node3D" unique_id=693383210]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1678672210]
mesh = ExtResource("1_3t3hs")
-skeleton = NodePath("")
diff --git a/client/map/tiles/counter_window.gd b/client/map/tiles/counter_window.gd
index 46889e43..d9cf6d24 100644
--- a/client/map/tiles/counter_window.gd
+++ b/client/map/tiles/counter_window.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -16,7 +16,7 @@
class_name CounterWindow
extends WallTile
-static func interact_target() -> Vector3:
+static func interact_target(): # -> Vector3?
return Vector3(0, 0.625, 0)
func _init(ctx: TileFactory.TileCC):
diff --git a/client/map/tiles/counter_window.res b/client/map/tiles/counter_window.res
index 2cb0f059..98d52663 100644
--- a/client/map/tiles/counter_window.res
+++ b/client/map/tiles/counter_window.res
Binary files differ
diff --git a/client/map/tiles/counter_window.tscn b/client/map/tiles/counter_window.tscn
index 8ae5a54d..09a5eaff 100644
--- a/client/map/tiles/counter_window.tscn
+++ b/client/map/tiles/counter_window.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://bwgkd65215m7e"]
+[gd_scene format=3 uid="uid://bwgkd65215m7e"]
[ext_resource type="ArrayMesh" uid="uid://lywflqnpelc7" path="res://map/tiles/counter_window.res" id="1_gyddt"]
-[node name="CounterWindow" type="Node3D"]
+[node name="CounterWindow" type="Node3D" unique_id=1350548242]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=2102120795]
transform = Transform3D(-2.18557e-08, 0, 0.5, 0, 0.5, 0, -0.5, 0, -2.18557e-08, 0, 0, 0)
mesh = ExtResource("1_gyddt")
-skeleton = NodePath("")
diff --git a/client/map/tiles/counter_base.gd b/client/map/tiles/counter_window_conveyor.gd
index 34bc5b59..e34dd2fd 100644
--- a/client/map/tiles/counter_base.gd
+++ b/client/map/tiles/counter_window_conveyor.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -13,15 +13,24 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
-class_name CounterBase
-extends Counter
+class_name CounterWindowConveyor
+extends WallTile
+
+var conveyor: ConveyorModel = preload("res://map/tiles/counter_window_conveyor.tscn").instantiate()
func _init(ctx: TileFactory.TileCC):
super(ctx)
match kind:
- CounterKind.OUTER_CORNER:
- base.add_child(load("res://map/tiles/counter_outer_corner.tscn").instantiate())
- CounterKind.STRAIGHT:
- base.add_child(load("res://map/tiles/counter_straight.tscn").instantiate())
- CounterKind.STRAIGHT_BACKSPLASH:
- base.add_child(load("res://map/tiles/counter_straight_backsplash.tscn").instantiate())
+ WallKind.STRAIGHT:
+ add_dyed_mesh(ctx, conveyor)
+ WallKind.OUTER_CORNER:
+ push_warning("There is no corner counter window!")
+ add_dyed_mesh(ctx, conveyor)
+
+static func interact_target(): # -> Vector3?
+ return Vector3(0., .425, 0.)
+
+func pass_to(tile: Tile):
+ super(tile)
+ var dir: Vector3 = (tile.position - position)
+ conveyor.to_direction(Vector2(dir.x, dir.z).normalized())
diff --git a/client/map/tiles/counter_window_conveyor.gd.uid b/client/map/tiles/counter_window_conveyor.gd.uid
new file mode 100644
index 00000000..861f4f0c
--- /dev/null
+++ b/client/map/tiles/counter_window_conveyor.gd.uid
@@ -0,0 +1 @@
+uid://onp3ijhfm4hg
diff --git a/client/map/tiles/counter_window_conveyor.res b/client/map/tiles/counter_window_conveyor.res
new file mode 100644
index 00000000..af234851
--- /dev/null
+++ b/client/map/tiles/counter_window_conveyor.res
Binary files differ
diff --git a/client/map/tiles/counter_window_conveyor.tscn b/client/map/tiles/counter_window_conveyor.tscn
new file mode 100644
index 00000000..5b977ecc
--- /dev/null
+++ b/client/map/tiles/counter_window_conveyor.tscn
@@ -0,0 +1,31 @@
+[gd_scene format=3 uid="uid://qxbupftye50d"]
+
+[ext_resource type="ArrayMesh" uid="uid://cgxmagghg40l3" path="res://map/tiles/counter_window_conveyor.res" id="1_sxc4d"]
+[ext_resource type="Script" uid="uid://sawoy4fqmd43" path="res://map/tiles/conveyor_model.gd" id="1_yowx8"]
+[ext_resource type="PackedScene" uid="uid://60wue8ult1bx" path="res://map/tiles/conveyor_direction.tscn" id="2_5k25t"]
+[ext_resource type="Shader" uid="uid://2cpdtie0rquv" path="res://map/tiles/conveyor_direction.gdshader" id="3_yowx8"]
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_yowx8"]
+albedo_color = Color(0, 0, 0, 1)
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_yowx8"]
+resource_local_to_scene = true
+render_priority = 0
+shader = ExtResource("3_yowx8")
+shader_parameter/angle = 0.2
+shader_parameter/frequency = 0.5
+shader_parameter/width = 0.2
+shader_parameter/speed = 1.0
+shader_parameter/alpha_fac = 1.0
+
+[node name="CounterWindowConveyor" type="Node3D" unique_id=326965642]
+script = ExtResource("1_yowx8")
+
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1365726575]
+transform = Transform3D(-2.1855694e-08, 0, 0.5, 0, 0.5, 0, -0.5, 0, -2.1855694e-08, 0, 0, 0)
+mesh = ExtResource("1_sxc4d")
+surface_material_override/3 = SubResource("StandardMaterial3D_yowx8")
+
+[node name="ConveyorDirection" parent="." unique_id=61838280 instance=ExtResource("2_5k25t")]
+transform = Transform3D(-4.371139e-08, -1, -4.371139e-08, 0, -4.371139e-08, 1, -1, 4.371139e-08, 1.9106855e-15, 0, 0.43, 0)
+surface_material_override/0 = SubResource("ShaderMaterial_yowx8")
diff --git a/client/map/tiles/crate.gd b/client/map/tiles/crate.gd
index a952c2e8..bb96b919 100644
--- a/client/map/tiles/crate.gd
+++ b/client/map/tiles/crate.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -14,10 +14,57 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
class_name Crate
-extends Counter
+extends CounterLike
-static func interact_target() -> Vector3:
+static func interact_target(): # -> Vector3?
return Vector3(0, 0.25, 0)
func _init(ctx: TileFactory.TileCC):
super(ctx)
+ match ctx.tile_name.variant:
+ "bun":
+ base.add_child(load("res://map/tiles/bun_crate.tscn").instantiate())
+ "cheese":
+ base.add_child(load("res://map/tiles/cheese_crate.tscn").instantiate())
+ "coconut":
+ base.add_child(load("res://map/tiles/coconut_crate.tscn").instantiate())
+ "fish":
+ base.add_child(load("res://map/tiles/fish_crate.tscn").instantiate())
+ "flour":
+ base.add_child(load("res://map/tiles/flour_crate.tscn").instantiate())
+ "leek":
+ base.add_child(load("res://map/tiles/leek_crate.tscn").instantiate())
+ "lettuce":
+ base.add_child(load("res://map/tiles/lettuce_crate.tscn").instantiate())
+ "mushroom":
+ base.add_child(load("res://map/tiles/mushroom_crate.tscn").instantiate())
+ "noodles":
+ base.add_child(load("res://map/tiles/noodles_crate.tscn").instantiate())
+ "potato":
+ base.add_child(load("res://map/tiles/potato_crate.tscn").instantiate())
+ "rice":
+ base.add_child(load("res://map/tiles/rice_crate.tscn").instantiate())
+ "steak":
+ base.add_child(load("res://map/tiles/steak_crate.tscn").instantiate())
+ "strawberry":
+ base.add_child(load("res://map/tiles/strawberry_crate.tscn").instantiate())
+ "tomato":
+ base.add_child(load("res://map/tiles/tomato_crate.tscn").instantiate())
+ var item_name:
+ base.add_child(load("res://map/tiles/crate.tscn").instantiate())
+ for i in [
+ [Vector3(0.25, 0.1, -0.2), deg_to_rad(-8)],
+ [Vector3(0.25, 0.15, 0.2), deg_to_rad(8)],
+ [Vector3(0, 0.1, -0.2), deg_to_rad(12)],
+ [Vector3(0, 0.1, 0.1), deg_to_rad(-6)],
+ [Vector3(-0.25, 0.15, -0.2), deg_to_rad(-8)],
+ [Vector3(-0.25, 0.1, 0.2), deg_to_rad(4)],
+ ]:
+ var crate_item_base = Node3D.new()
+ var crate_item = ItemFactory.produce(item_name, crate_item_base)
+ crate_item.position = i[0]
+ crate_item_base.position = i[0]
+ crate_item.rotation.y = i[1]
+ crate_item_base.rotation.y = i[1]
+ crate_item_base.add_child(crate_item)
+ base.add_child(crate_item_base)
diff --git a/client/map/tiles/crate.res b/client/map/tiles/crate.res
index 1d1183c5..6b1e5251 100644
--- a/client/map/tiles/crate.res
+++ b/client/map/tiles/crate.res
Binary files differ
diff --git a/client/map/tiles/crate.tscn b/client/map/tiles/crate.tscn
index 55da257b..885bee8e 100644
--- a/client/map/tiles/crate.tscn
+++ b/client/map/tiles/crate.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://xdui0oya4lpb"]
+[gd_scene format=3 uid="uid://xdui0oya4lpb"]
[ext_resource type="ArrayMesh" uid="uid://btn7oh1v2k40p" path="res://map/tiles/crate.res" id="1_qu7f0"]
-[node name="Crate" type="Node3D"]
+[node name="Crate" type="Node3D" unique_id=1797382951]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=473438995]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_qu7f0")
-skeleton = NodePath("")
diff --git a/client/map/tiles/cutting_board.gd b/client/map/tiles/cutting_board.gd
index 300b5700..d9f95911 100644
--- a/client/map/tiles/cutting_board.gd
+++ b/client/map/tiles/cutting_board.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -14,43 +14,10 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
class_name CuttingBoard
-extends CounterBase
-
-var board = load("res://map/tiles/cutting_board.tscn").instantiate()
-var chopping: AudioStreamPlayer3D = AudioStreamPlayer3D.new()
-var acting_player
+extends ActiveInteractCounter
func _init(ctx: TileFactory.TileCC):
- super(ctx)
- chopping.stream = preload("res://map/tiles/sounds/chop.ogg")
- add_child(chopping)
- base.add_child(board)
-
-func progress(position_: float, speed: float, warn: bool, acting_player_):
- super(position_, speed, warn, acting_player)
- var knife: Node3D = board.get_node("Knife")
- acting_player = acting_player_
-
- if not chopping.playing and speed != 0.:
- chopping.play()
- if acting_player != null:
- knife.visible = false
- var acting_character: Character = acting_player.character
- acting_character.cutting = true
- elif speed == 0:
- chopping.stop()
- knife.visible = true
- if acting_player != null:
- var acting_character: Character = acting_player.character
- acting_character.cutting = false
-
-func finish():
- super()
- if is_instance_valid(acting_player):
- var acting_character: Character = acting_player.character
- acting_character.cutting = false
- board.get_node("Knife").visible = true
- chopping.stop()
+ super(ctx, preload("res://map/tiles/cutting_board.tscn"), "CuttingBoard/Knife", func (p: Player, x: bool): p.character.cutting = x, preload("res://map/tiles/sounds/chop.ogg"))
-static func interact_target() -> Vector3:
+static func interact_target(): # -> Vector3?
return Vector3(0., 0.575, 0.)
diff --git a/client/map/tiles/cutting_board.res b/client/map/tiles/cutting_board.res
index 15a1b5c3..9511f542 100644
--- a/client/map/tiles/cutting_board.res
+++ b/client/map/tiles/cutting_board.res
Binary files differ
diff --git a/client/map/tiles/cutting_board.tscn b/client/map/tiles/cutting_board.tscn
index dd469417..498665eb 100644
--- a/client/map/tiles/cutting_board.tscn
+++ b/client/map/tiles/cutting_board.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=6 format=3 uid="uid://bslx1a7kdufde"]
+[gd_scene format=3 uid="uid://bslx1a7kdufde"]
[ext_resource type="ArrayMesh" uid="uid://dd4g04lgvsly5" path="res://map/tiles/cutting_board.res" id="1_d4k2k"]
[ext_resource type="PackedScene" uid="uid://cufype1bex3r3" path="res://map/tiles/knife.tscn" id="3_wvxni"]
@@ -150,17 +150,14 @@ _data = {
&"cut_loop": SubResource("Animation_vu13j")
}
-[node name="CuttingBoard" type="Node3D"]
+[node name="CuttingBoard" type="Node3D" unique_id=238504632]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=396141108]
transform = Transform3D(0.4, 0, 0, 0, 0.5, 0, 0, 0, 0.5, -0.075, 0.5, 0)
mesh = ExtResource("1_d4k2k")
-skeleton = NodePath("")
-[node name="Knife" parent="." instance=ExtResource("3_wvxni")]
-transform = Transform3D(1, 0, 0, 0, -3.61999e-06, 1, 0, -1, -3.61999e-06, 0.375, 0.52, 0.19)
+[node name="Knife" parent="." unique_id=1126807225 instance=ExtResource("3_wvxni")]
+transform = Transform3D(1, 0, 0, 0, -3.6199901e-06, 1, 0, -1, -3.6199901e-06, 0.375, 0.52, 0.19)
-[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
-libraries = {
-"": SubResource("AnimationLibrary_fy61n")
-}
+[node name="AnimationPlayer" type="AnimationPlayer" parent="." unique_id=127266211]
+libraries/ = SubResource("AnimationLibrary_fy61n")
diff --git a/client/map/tiles/deep_fryer.gd b/client/map/tiles/deep_fryer.gd
index 82204cb8..d730207f 100644
--- a/client/map/tiles/deep_fryer.gd
+++ b/client/map/tiles/deep_fryer.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -14,18 +14,16 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
class_name DeepFryer
-extends CounterBase
-
-var deep_fryer = load("res://map/tiles/deep_fryer.tscn").instantiate()
+extends Tile
func _init(ctx: TileFactory.TileCC):
super(ctx)
- base.add_child(deep_fryer)
+ base.add_child(preload("res://map/tiles/deep_fryer.tscn").instantiate())
func set_item(i: Item):
super(i)
if i != null:
i.rotation_target = item_base.global_rotation.y + PI
-static func interact_target() -> Vector3:
+static func interact_target(): # -> Vector3?
return Vector3(0., 0.55, 0.)
diff --git a/client/map/tiles/deep_fryer.gd.uid b/client/map/tiles/deep_fryer.gd.uid
index 0fc161a4..26210181 100644
--- a/client/map/tiles/deep_fryer.gd.uid
+++ b/client/map/tiles/deep_fryer.gd.uid
@@ -1 +1 @@
-uid://x4gtbub0vfun
+uid://bd0pophijvqv5
diff --git a/client/map/tiles/deep_fryer.tscn b/client/map/tiles/deep_fryer.tscn
index cb854ec0..a163411f 100644
--- a/client/map/tiles/deep_fryer.tscn
+++ b/client/map/tiles/deep_fryer.tscn
@@ -1,20 +1,21 @@
-[gd_scene load_steps=4 format=3 uid="uid://bys6bffu5srpt"]
+[gd_scene format=3 uid="uid://bys6bffu5srpt"]
[ext_resource type="ArrayMesh" uid="uid://bketpomfy35to" path="res://map/tiles/deep_fryer_base.res" id="1_e4g0d"]
[ext_resource type="ArrayMesh" uid="uid://c7k6gevpwdbv0" path="res://map/tiles/deep_fryer_fill.res" id="3_1rwcx"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1rwcx"]
+transparency = 1
cull_mode = 1
-albedo_color = Color(0.75, 0.58, 0.45000002, 1)
+albedo_color = Color(0.75, 0.58, 0.45000002, 0.6666667)
roughness = 0.1
-[node name="DeepFryer" type="Node3D"]
+[node name="DeepFryer" type="Node3D" unique_id=1218321913]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1815767562]
transform = Transform3D(0.75, 0, 0, 0, -3.278354e-08, -0.75, 0, 0.75, -3.278354e-08, 0, 0.5, 0)
mesh = ExtResource("1_e4g0d")
-[node name="Fill" type="MeshInstance3D" parent="."]
+[node name="Fill" type="MeshInstance3D" parent="." unique_id=56430436]
transform = Transform3D(0.75, 0, 0, 0, -3.278354e-08, -0.75, 0, 0.75, -3.278354e-08, 0, 0.5, 0)
mesh = ExtResource("3_1rwcx")
surface_material_override/0 = SubResource("StandardMaterial3D_1rwcx")
diff --git a/client/map/tiles/deep_fryer_base.res b/client/map/tiles/deep_fryer_base.res
index 2a392ab6..e6fd0377 100644
--- a/client/map/tiles/deep_fryer_base.res
+++ b/client/map/tiles/deep_fryer_base.res
Binary files differ
diff --git a/client/map/tiles/deep_fryer_fill.res b/client/map/tiles/deep_fryer_fill.res
index 0280a561..5c450bf1 100644
--- a/client/map/tiles/deep_fryer_fill.res
+++ b/client/map/tiles/deep_fryer_fill.res
Binary files differ
diff --git a/client/map/tiles/door.gd b/client/map/tiles/door.gd
index 7fe23c93..37dd012f 100644
--- a/client/map/tiles/door.gd
+++ b/client/map/tiles/door.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -21,7 +21,7 @@ func _init(ctx: TileFactory.TileCC):
var new_facing = 0
for i in range(4):
- if ctx.neighbors[i] == "door":
+ if ctx.neighbors[i].has("door"):
new_facing = i
turn_facing(new_facing)
add_dyed_mesh(ctx, load("res://map/tiles/door.tscn").instantiate(), "Door", 1)
diff --git a/client/map/tiles/door.res b/client/map/tiles/door.res
index ad64d5b6..d2dbbdcf 100644
--- a/client/map/tiles/door.res
+++ b/client/map/tiles/door.res
Binary files differ
diff --git a/client/map/tiles/door.tscn b/client/map/tiles/door.tscn
index 894d30a2..d00e99ec 100644
--- a/client/map/tiles/door.tscn
+++ b/client/map/tiles/door.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://coxh3mgvch5bd"]
+[gd_scene format=3 uid="uid://coxh3mgvch5bd"]
[ext_resource type="ArrayMesh" uid="uid://bomlbxf33hd11" path="res://map/tiles/door.res" id="1_wfoe6"]
-[node name="Door" type="Node3D"]
+[node name="Door" type="Node3D" unique_id=1352926697]
-[node name="Door" type="MeshInstance3D" parent="."]
+[node name="Door" type="MeshInstance3D" parent="." unique_id=1538534480]
transform = Transform3D(5.96244e-09, 0, -0.5, 0, 0.5, 0, 0.5, 0, 5.96244e-09, 0, 0, 0)
mesh = ExtResource("1_wfoe6")
-skeleton = NodePath("")
diff --git a/client/map/tiles/exterior_tree.gd b/client/map/tiles/exterior_tree.gd
index fe9eeaf8..82c457e2 100644
--- a/client/map/tiles/exterior_tree.gd
+++ b/client/map/tiles/exterior_tree.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -14,7 +14,7 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
class_name ExteriorTree
-extends Grass
+extends Tile
const SCALE: Vector3 = Vector3(100., 100., 100.)
const ROT: Vector3 = Vector3(1.5 * PI, 0., 0.)
@@ -23,23 +23,41 @@ func _init(ctx: TileFactory.TileCC):
super(ctx)
var random = RandomNumberGenerator.new()
random.seed = str(ctx.position).hash()
- var tree: int = random.randi_range(1,5)
- var trunk: Mesh = load("res://map/tiles/tree/trunk_%d.res" % tree)
- var leaves: Mesh = load("res://map/tiles/tree/leaves_%d_%s.res" % [
- tree,
- "lq" if Settings.read("graphics.lq_trees") else "hq"
- ])
+ var tree_type: int = random.randi_range(1,5)
+ var no_leaves := false
+
+ if ctx.tile_name.variant != null:
+ var variant: String = ctx.tile_name.variant
+ if variant == "no_leaves":
+ no_leaves = true
+ else:
+ if variant.is_valid_int():
+ var variant_int := int(variant)
+ if variant_int >= 1 and variant_int <= 5:
+ tree_type = variant_int
+ else:
+ push_error("Tree variant \"%d\" is out of bounds (expected element of [1..5])" % variant_int)
+ push_error("Tree variant \"%s\" not recognized" % variant)
+
+ var tree_node: Node3D = Node3D.new()
+
+ if not no_leaves:
+ var leaves: Mesh = load("res://map/tiles/tree/leaves_%d_%s.res" % [
+ tree_type,
+ "lq" if Settings.read("graphics.lq_trees") else "hq"
+ ])
+ var leaves_instance: MeshInstance3D = MeshInstance3D.new()
+ leaves_instance.mesh = leaves
+ leaves_instance.scale = SCALE
+ leaves_instance.rotation = ROT
+ tree_node.add_child(leaves_instance)
+
+ var trunk: Mesh = load("res://map/tiles/tree/trunk_%d.res" % tree_type)
var trunk_instance: MeshInstance3D = MeshInstance3D.new()
trunk_instance.mesh = trunk
trunk_instance.scale = SCALE
trunk_instance.rotation = ROT
- var leaves_instance: MeshInstance3D = MeshInstance3D.new()
- leaves_instance.mesh = leaves
- leaves_instance.scale = SCALE
- leaves_instance.rotation = ROT
- var tree_node: Node3D = Node3D.new()
tree_node.add_child(trunk_instance)
- tree_node.add_child(leaves_instance)
tree_node.name = "Tree"
base.add_child(tree_node)
diff --git a/client/map/tiles/fence.gd b/client/map/tiles/fence.gd
index 0510c4b9..5d2dfdd8 100644
--- a/client/map/tiles/fence.gd
+++ b/client/map/tiles/fence.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -17,10 +17,15 @@ class_name Fence
extends WallTile
func _init(ctx: TileFactory.TileCC):
+ walls = ["fence"]
super(ctx)
+ var neighboring_fences := ctx.neighbors.map(is_wall).count(true)
match kind:
WallKind.STRAIGHT:
- base.add_child(load("res://map/tiles/fence_straight.tscn").instantiate())
+ if neighboring_fences == 1:
+ base.add_child(load("res://map/tiles/fence_end.tscn").instantiate())
+ else:
+ base.add_child(load("res://map/tiles/fence_straight.tscn").instantiate())
WallKind.OUTER_CORNER:
base.add_child(load("res://map/tiles/fence_corner.tscn").instantiate())
WallKind.T:
@@ -29,5 +34,5 @@ func _init(ctx: TileFactory.TileCC):
push_warning("no wall cross available!")
base.add_child(load("res://map/tiles/fence_straight.tscn").instantiate())
-func get_base_mesh():
- return preload("res://map/tiles/grass.tscn").instantiate()
+static func fm_id() -> String:
+ return "grass"
diff --git a/client/map/tiles/fence_corner.res b/client/map/tiles/fence_corner.res
index 14e345a6..8324c435 100644
--- a/client/map/tiles/fence_corner.res
+++ b/client/map/tiles/fence_corner.res
Binary files differ
diff --git a/client/map/tiles/fence_corner.tscn b/client/map/tiles/fence_corner.tscn
index b7b0d356..57adebf5 100644
--- a/client/map/tiles/fence_corner.tscn
+++ b/client/map/tiles/fence_corner.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://cvac5lq82xqhq"]
+[gd_scene format=3 uid="uid://cvac5lq82xqhq"]
[ext_resource type="ArrayMesh" uid="uid://25vo0ohcya7a" path="res://map/tiles/fence_corner.res" id="1_5aqc4"]
-[node name="FenceCorner" type="Node3D"]
+[node name="FenceCorner" type="Node3D" unique_id=1550671344]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=669814619]
transform = Transform3D(-2.18557e-06, 0, 50, 0, 50, 0, -50, 0, -2.18557e-06, 0, 0, 0)
mesh = ExtResource("1_5aqc4")
-skeleton = NodePath("")
diff --git a/client/map/tiles/fence_end.res b/client/map/tiles/fence_end.res
new file mode 100644
index 00000000..c7862747
--- /dev/null
+++ b/client/map/tiles/fence_end.res
Binary files differ
diff --git a/client/map/tiles/fence_end.tscn b/client/map/tiles/fence_end.tscn
new file mode 100644
index 00000000..5d8e185c
--- /dev/null
+++ b/client/map/tiles/fence_end.tscn
@@ -0,0 +1,9 @@
+[gd_scene format=3 uid="uid://dseef40ucueuv"]
+
+[ext_resource type="ArrayMesh" uid="uid://bhdxbn6ivop6k" path="res://map/tiles/fence_end.res" id="1_cdo5n"]
+
+[node name="FenceEnd" type="Node3D" unique_id=1482639971]
+
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=461934852]
+transform = Transform3D(5.9624404e-07, 0, -50, 0, 50, 0, 50, 0, 5.9624404e-07, 0, 0, 0)
+mesh = ExtResource("1_cdo5n")
diff --git a/client/map/tiles/fence_straight.res b/client/map/tiles/fence_straight.res
index c3975138..44f673ed 100644
--- a/client/map/tiles/fence_straight.res
+++ b/client/map/tiles/fence_straight.res
Binary files differ
diff --git a/client/map/tiles/fence_straight.tscn b/client/map/tiles/fence_straight.tscn
index d31af10d..eb31dc7f 100644
--- a/client/map/tiles/fence_straight.tscn
+++ b/client/map/tiles/fence_straight.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://d0w3mrbe8w8m0"]
+[gd_scene format=3 uid="uid://d0w3mrbe8w8m0"]
[ext_resource type="ArrayMesh" uid="uid://d1jfqqjhaqsgn" path="res://map/tiles/fence_straight.res" id="1_4ta43"]
-[node name="FenceStraight" type="Node3D"]
+[node name="FenceStraight" type="Node3D" unique_id=186177964]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1512127781]
transform = Transform3D(-2.18557e-06, 0, 50, 0, 50, 0, -50, 0, -2.18557e-06, 0, 0, 0)
mesh = ExtResource("1_4ta43")
-skeleton = NodePath("")
diff --git a/client/map/tiles/fence_t.res b/client/map/tiles/fence_t.res
index 93043f7c..65e66589 100644
--- a/client/map/tiles/fence_t.res
+++ b/client/map/tiles/fence_t.res
Binary files differ
diff --git a/client/map/tiles/fence_t.tscn b/client/map/tiles/fence_t.tscn
index 1efb3fe8..c85f3c56 100644
--- a/client/map/tiles/fence_t.tscn
+++ b/client/map/tiles/fence_t.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://bk6ufdmbtrkkh"]
+[gd_scene format=3 uid="uid://bk6ufdmbtrkkh"]
[ext_resource type="ArrayMesh" uid="uid://b8v4k4o8cusn4" path="res://map/tiles/fence_t.res" id="1_i484t"]
-[node name="FenceT" type="Node3D"]
+[node name="FenceT" type="Node3D" unique_id=1903555463]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=891470237]
transform = Transform3D(50, 0, 0, 0, 50, 0, 0, 0, 50, 0, 0, 0)
mesh = ExtResource("1_i484t")
-skeleton = NodePath("")
diff --git a/client/map/tiles/fish_crate.gd b/client/map/tiles/fish_crate.gd
deleted file mode 100644
index 76859159..00000000
--- a/client/map/tiles/fish_crate.gd
+++ /dev/null
@@ -1,21 +0,0 @@
-# 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 <https://www.gnu.org/licenses/>.
-#
-class_name FishCrate
-extends Crate
-
-func _init(ctx: TileFactory.TileCC):
- super(ctx)
- base.add_child(load("res://map/tiles/fish_crate.tscn").instantiate())
diff --git a/client/map/tiles/fish_crate.gd.uid b/client/map/tiles/fish_crate.gd.uid
deleted file mode 100644
index 2974ccf5..00000000
--- a/client/map/tiles/fish_crate.gd.uid
+++ /dev/null
@@ -1 +0,0 @@
-uid://c346hqdpfl3df
diff --git a/client/map/tiles/fish_crate.tscn b/client/map/tiles/fish_crate.tscn
index a096a000..f55c203b 100644
--- a/client/map/tiles/fish_crate.tscn
+++ b/client/map/tiles/fish_crate.tscn
@@ -1,21 +1,21 @@
-[gd_scene load_steps=3 format=3 uid="uid://d0u4ym5vny6v3"]
+[gd_scene format=3 uid="uid://d0u4ym5vny6v3"]
[ext_resource type="PackedScene" uid="uid://xdui0oya4lpb" path="res://map/tiles/crate.tscn" id="1_uotdf"]
[ext_resource type="PackedScene" uid="uid://dom5n7h7l7sr8" path="res://map/items/fish.tscn" id="3_p6tbn"]
-[node name="FishCrate" instance=ExtResource("1_uotdf")]
+[node name="FishCrate" unique_id=702043979 instance=ExtResource("1_uotdf")]
-[node name="Fish" parent="." index="1" instance=ExtResource("3_p6tbn")]
+[node name="Fish" parent="." index="1" unique_id=417741247 instance=ExtResource("3_p6tbn")]
transform = Transform3D(-0.449443, -0.771467, -0.450378, 0.791587, -0.577595, 0.199436, -0.413994, -0.266878, 0.870279, -0.214561, 0.395904, -0.219162)
-[node name="Fish2" parent="." index="2" instance=ExtResource("3_p6tbn")]
+[node name="Fish2" parent="." index="2" unique_id=345509005 instance=ExtResource("3_p6tbn")]
transform = Transform3D(-0.711008, -0.637308, 0.297164, 0.702745, -0.65893, 0.268256, 0.024849, 0.399563, 0.916369, -0.214561, 0.387099, 0.251797)
-[node name="Fish3" parent="." index="3" instance=ExtResource("3_p6tbn")]
+[node name="Fish3" parent="." index="3" unique_id=903314315 instance=ExtResource("3_p6tbn")]
transform = Transform3D(0.570404, 0.618182, 0.540824, 0.777163, -0.619291, -0.111795, 0.265817, 0.484076, -0.833674, 0.258679, 0.387099, 0.251797)
-[node name="Fish4" parent="." index="4" instance=ExtResource("3_p6tbn")]
+[node name="Fish4" parent="." index="4" unique_id=532382365 instance=ExtResource("3_p6tbn")]
transform = Transform3D(0.392672, 0.829406, 0.397361, 0.896997, -0.25003, -0.364529, -0.202991, 0.499572, -0.842154, 0.224403, 0.387099, -0.0202113)
-[node name="Fish5" parent="." index="5" instance=ExtResource("3_p6tbn")]
+[node name="Fish5" parent="." index="5" unique_id=984963027 instance=ExtResource("3_p6tbn")]
transform = Transform3D(0.667773, 0.721732, 0.18216, 0.744349, -0.64583, -0.169849, -0.00494065, 0.249011, -0.968488, 0.162187, 0.340659, -0.264269)
diff --git a/client/map/tiles/floor.gd b/client/map/tiles/floor.gd
index e0959708..6baae392 100644
--- a/client/map/tiles/floor.gd
+++ b/client/map/tiles/floor.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/tiles/floor.gdshader b/client/map/tiles/floor.gdshader
index a1567189..dd6f277f 100644
--- a/client/map/tiles/floor.gdshader
+++ b/client/map/tiles/floor.gdshader
@@ -1,6 +1,6 @@
/*
Hurry Curry! - a game about cooking
- Copyright (C) 2025 Hurry Curry! Contributors
+ Copyright (C) 2026 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
diff --git a/client/map/tiles/floor.res b/client/map/tiles/floor.res
index bcd3625c..3e50860a 100644
--- a/client/map/tiles/floor.res
+++ b/client/map/tiles/floor.res
Binary files differ
diff --git a/client/map/tiles/floor.tscn b/client/map/tiles/floor.tscn
index 61299e3a..e4bd7fd4 100644
--- a/client/map/tiles/floor.tscn
+++ b/client/map/tiles/floor.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://d22cslgao5jd4"]
+[gd_scene format=3 uid="uid://d22cslgao5jd4"]
[ext_resource type="ArrayMesh" uid="uid://bd11w8rl78pab" path="res://map/tiles/floor.res" id="1_8pd6m"]
-[node name="Floor" type="Node3D"]
+[node name="Floor" type="Node3D" unique_id=1210077403]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1731675264]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_8pd6m")
-skeleton = NodePath("")
diff --git a/client/map/tiles/floor_like.gd b/client/map/tiles/floor_like.gd
index 228a95e9..fc9be052 100644
--- a/client/map/tiles/floor_like.gd
+++ b/client/map/tiles/floor_like.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/tiles/floor_material.tres b/client/map/tiles/floor_material.tres
index d0d4ad4f..dedb50ba 100644
--- a/client/map/tiles/floor_material.tres
+++ b/client/map/tiles/floor_material.tres
@@ -1,4 +1,4 @@
-[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://dngt21phuitvu"]
+[gd_resource type="ShaderMaterial" format=3 uid="uid://dngt21phuitvu"]
[ext_resource type="Shader" uid="uid://bf1jo3phn2pvs" path="res://map/tiles/floor.gdshader" id="1_7ju4h"]
diff --git a/client/map/tiles/floor_mesher.gd b/client/map/tiles/floor_mesher.gd
index cb89cc0b..addd23d2 100644
--- a/client/map/tiles/floor_mesher.gd
+++ b/client/map/tiles/floor_mesher.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/tiles/flour_crate.gd.uid b/client/map/tiles/flour_crate.gd.uid
deleted file mode 100644
index 9dd3f3de..00000000
--- a/client/map/tiles/flour_crate.gd.uid
+++ /dev/null
@@ -1 +0,0 @@
-uid://fangsumpqnoy
diff --git a/client/map/tiles/flour_crate.tscn b/client/map/tiles/flour_crate.tscn
index 1e4a7b7d..8f7d39bd 100644
--- a/client/map/tiles/flour_crate.tscn
+++ b/client/map/tiles/flour_crate.tscn
@@ -1,24 +1,24 @@
-[gd_scene load_steps=3 format=3 uid="uid://qwk6nih458mh"]
+[gd_scene format=3 uid="uid://qwk6nih458mh"]
[ext_resource type="PackedScene" uid="uid://xdui0oya4lpb" path="res://map/tiles/crate.tscn" id="1_7xctt"]
[ext_resource type="PackedScene" uid="uid://dgo8cknr1o6ml" path="res://map/items/flour.tscn" id="2_i5ha0"]
-[node name="FlourCrate" instance=ExtResource("1_7xctt")]
+[node name="FlourCrate" unique_id=457614471 instance=ExtResource("1_7xctt")]
-[node name="Flour" parent="." index="1" instance=ExtResource("2_i5ha0")]
+[node name="Flour" parent="." index="1" unique_id=1669483030 instance=ExtResource("2_i5ha0")]
transform = Transform3D(0.990268, 0, -0.139173, 0, 1, 0, 0.139173, 0, 0.990268, 0.25, 0, -0.2)
-[node name="Flour2" parent="." index="2" instance=ExtResource("2_i5ha0")]
+[node name="Flour2" parent="." index="2" unique_id=145159583 instance=ExtResource("2_i5ha0")]
transform = Transform3D(0.990268, 0, 0.139173, 0, 1, 0, -0.139173, 0, 0.990268, 0.25, 0, 0.2)
-[node name="Flour3" parent="." index="3" instance=ExtResource("2_i5ha0")]
+[node name="Flour3" parent="." index="3" unique_id=663539735 instance=ExtResource("2_i5ha0")]
transform = Transform3D(0.973674, 0, 0.227943, 0, 1, 0, -0.227943, 0, 0.973674, 0, 0, -0.202263)
-[node name="Flour4" parent="." index="4" instance=ExtResource("2_i5ha0")]
+[node name="Flour4" parent="." index="4" unique_id=152480553 instance=ExtResource("2_i5ha0")]
transform = Transform3D(0.99525, -0.00903298, -0.0969282, -0.0219365, 0.949266, -0.313707, 0.0948444, 0.314343, 0.94456, 0, 0, 0.106343)
-[node name="Flour5" parent="." index="5" instance=ExtResource("2_i5ha0")]
+[node name="Flour5" parent="." index="5" unique_id=1577002603 instance=ExtResource("2_i5ha0")]
transform = Transform3D(0.990268, 0, -0.139173, 0, 1, 0, 0.139173, 0, 0.990268, -0.25, 0, -0.2)
-[node name="Flour6" parent="." index="6" instance=ExtResource("2_i5ha0")]
+[node name="Flour6" parent="." index="6" unique_id=1425393970 instance=ExtResource("2_i5ha0")]
transform = Transform3D(0.997564, 0, 0.0697565, 0, 1, 0, -0.0697565, 0, 0.997564, -0.25, 0, 0.2)
diff --git a/client/map/tiles/freezer.gd b/client/map/tiles/freezer.gd
index 47ab89a9..72aa4660 100644
--- a/client/map/tiles/freezer.gd
+++ b/client/map/tiles/freezer.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -14,7 +14,7 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
class_name Freezer
-extends Counter
+extends CounterLike
var freezer: FreezerModel = load("res://map/tiles/freezer.tscn").instantiate()
diff --git a/client/map/tiles/freezer.tscn b/client/map/tiles/freezer.tscn
index 604bd439..950d1ce3 100644
--- a/client/map/tiles/freezer.tscn
+++ b/client/map/tiles/freezer.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=8 format=3 uid="uid://ch753p32b3jl8"]
+[gd_scene format=3 uid="uid://ch753p32b3jl8"]
[ext_resource type="Script" uid="uid://b8r7lcqws42yr" path="res://map/tiles/freezer_model.gd" id="1_kso20"]
[ext_resource type="ArrayMesh" uid="uid://cbdalq2gofyu8" path="res://map/tiles/freezer_base.res" id="2_akcb5"]
@@ -42,20 +42,18 @@ _data = {
&"open": SubResource("Animation_axsnk")
}
-[node name="Freezer" type="Node3D"]
+[node name="Freezer" type="Node3D" unique_id=758213999]
script = ExtResource("1_kso20")
-[node name="FreezerBase" type="MeshInstance3D" parent="."]
+[node name="FreezerBase" type="MeshInstance3D" parent="." unique_id=54052954]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("2_akcb5")
-skeleton = NodePath("")
-[node name="FreezerDoor" type="MeshInstance3D" parent="FreezerBase"]
+[node name="FreezerDoor" type="MeshInstance3D" parent="FreezerBase" unique_id=438445392]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.850006, 1.25, 0.5)
mesh = ExtResource("3_0pgw0")
-skeleton = NodePath("")
-[node name="OmniLight3D" type="OmniLight3D" parent="."]
+[node name="OmniLight3D" type="OmniLight3D" parent="." unique_id=565200753]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.25, 0)
visible = false
light_color = Color(0.566816, 0.801037, 0.838352, 1)
@@ -64,7 +62,7 @@ omni_range = 3.0
script = ExtResource("4_1eu4t")
completely_disable_light_if_shadows_disabled = true
-[node name="OmniLight3D2" type="OmniLight3D" parent="."]
+[node name="OmniLight3D2" type="OmniLight3D" parent="." unique_id=452354585]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.6, 0)
visible = false
light_color = Color(0.566816, 0.801037, 0.838352, 1)
@@ -73,7 +71,7 @@ omni_range = 3.0
script = ExtResource("4_1eu4t")
completely_disable_light_if_shadows_disabled = true
-[node name="OmniLight3D3" type="OmniLight3D" parent="."]
+[node name="OmniLight3D3" type="OmniLight3D" parent="." unique_id=1314789449]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.9, 0)
visible = false
light_color = Color(0.566816, 0.801037, 0.838352, 1)
@@ -82,9 +80,7 @@ omni_range = 3.0
script = ExtResource("4_1eu4t")
completely_disable_light_if_shadows_disabled = true
-[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
-libraries = {
-&"": SubResource("AnimationLibrary_usga0")
-}
+[node name="AnimationPlayer" type="AnimationPlayer" parent="." unique_id=1644020234]
+libraries/ = SubResource("AnimationLibrary_usga0")
[connection signal="animation_finished" from="AnimationPlayer" to="." method="_on_animation_player_animation_finished"]
diff --git a/client/map/tiles/freezer_base.res b/client/map/tiles/freezer_base.res
index dded8a8b..172564a5 100644
--- a/client/map/tiles/freezer_base.res
+++ b/client/map/tiles/freezer_base.res
Binary files differ
diff --git a/client/map/tiles/freezer_door.res b/client/map/tiles/freezer_door.res
index 9efb17a3..3fe84dfc 100644
--- a/client/map/tiles/freezer_door.res
+++ b/client/map/tiles/freezer_door.res
Binary files differ
diff --git a/client/map/tiles/freezer_model.gd b/client/map/tiles/freezer_model.gd
index 4defda9c..b05c6959 100644
--- a/client/map/tiles/freezer_model.gd
+++ b/client/map/tiles/freezer_model.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/tiles/generic_tile.gd b/client/map/tiles/generic_tile.gd
index 0a11efc6..73ac3fac 100644
--- a/client/map/tiles/generic_tile.gd
+++ b/client/map/tiles/generic_tile.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -13,13 +13,9 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
-class_name UnknownTile
-extends Floor
+class_name GenericTile
+extends Tile
-func _init(ctx: TileFactory.TileCC):
+func _init(ctx: TileFactory.TileCC, scene: PackedScene):
super(ctx)
- var label = Label3D.new()
- label.text = ctx.tile_name.name
- label.position.y = 0.5
- label.billboard = BaseMaterial3D.BILLBOARD_ENABLED
- item_base.add_child(label)
+ base.add_child(scene.instantiate())
diff --git a/client/map/tiles/generic_tile.gd.uid b/client/map/tiles/generic_tile.gd.uid
index 3c331921..f73a3209 100644
--- a/client/map/tiles/generic_tile.gd.uid
+++ b/client/map/tiles/generic_tile.gd.uid
@@ -1 +1 @@
-uid://l154vna0x8de
+uid://dtq5tlmwi8gxy
diff --git a/client/map/tiles/grass.gd b/client/map/tiles/grass.gd
index d9ebce7c..bc555b93 100644
--- a/client/map/tiles/grass.gd
+++ b/client/map/tiles/grass.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -16,6 +16,13 @@
class_name Grass
extends FloorLike
+func _init(ctx: TileFactory.TileCC):
+ super(ctx)
+ if not base_mesh:
+ var grass_mesher: GrassMesher = ctx.floor_meshers[fm_id()]
+ var use_no_grass: bool = ctx.above_tile_names.any(func (s): return s == "chair" or s == "table" or s == "conveyor")
+ grass_mesher.add_tile(ctx.position, use_no_grass)
+
static func fm_id() -> String:
return "grass"
diff --git a/client/map/tiles/grass.res b/client/map/tiles/grass.res
index 1c4565a1..6a070c8e 100644
--- a/client/map/tiles/grass.res
+++ b/client/map/tiles/grass.res
Binary files differ
diff --git a/client/map/tiles/grass.tscn b/client/map/tiles/grass.tscn
index 649cc6c1..720786c2 100644
--- a/client/map/tiles/grass.tscn
+++ b/client/map/tiles/grass.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://bi6o7lbvhunj1"]
+[gd_scene format=3 uid="uid://bi6o7lbvhunj1"]
[ext_resource type="ArrayMesh" uid="uid://dyu8iuolwqr5l" path="res://map/tiles/grass.res" id="1_pjjrj"]
-[node name="Grass" type="Node3D"]
+[node name="Grass" type="Node3D" unique_id=380813708]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=714753882]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_pjjrj")
-skeleton = NodePath("")
diff --git a/client/map/tiles/grass_mesher.gd b/client/map/tiles/grass_mesher.gd
index 466c3c1e..f157c84c 100644
--- a/client/map/tiles/grass_mesher.gd
+++ b/client/map/tiles/grass_mesher.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -19,10 +19,21 @@ extends FloorMesher
const GRASS_MESH: Mesh = preload("res://map/tiles/grass_side.tres")
var multimesh_instance := MultiMeshInstance3D.new()
+var no_grass_tiles: Dictionary[String, Vector2i] = {}
+
func _init(mesh: MeshInstance3D) -> void:
super(mesh)
mesh_instance.add_child(multimesh_instance)
+func add_tile(pos: Vector2i, use_no_grass: bool = false):
+ super(pos)
+ if use_no_grass:
+ no_grass_tiles[str(pos)] = pos
+
+func remove_tile(pos: Vector2i):
+ super(pos)
+ no_grass_tiles.erase(str(pos))
+
func flush() -> void:
super()
var random = RandomNumberGenerator.new()
@@ -33,8 +44,10 @@ func flush() -> void:
multimesh.transform_format = MultiMesh.TRANSFORM_3D
multimesh.instance_count = tiles.size() * Settings.read("graphics.grass_amount")
var t := tiles.values()
+ var no_grass := no_grass_tiles.values()
for i in multimesh.instance_count:
- var p = t[i / Settings.read("graphics.grass_amount")]
+ var p: Vector2i = t[i / Settings.read("graphics.grass_amount")]
+ if p in no_grass: continue
var origin := Vector3(random.randf_range(-.5, .5), 0.25, random.randf_range(-.5, .5)) + Vector3(p.x + 0.5, 0.0, p.y + 0.5)
var basis_ := (Basis(Vector3(0, 1, 0), random.randf_range(0, PI)) * Basis(Vector3(1, 0, 0), PI/2)).scaled(Vector3(0.75, 0.5, 0.75))
multimesh.set_instance_transform(i, Transform3D(basis_, origin))
diff --git a/client/map/tiles/grass_side.tres b/client/map/tiles/grass_side.tres
index 3f29e10e..52042308 100644
--- a/client/map/tiles/grass_side.tres
+++ b/client/map/tiles/grass_side.tres
@@ -1,4 +1,4 @@
-[gd_resource type="ArrayMesh" load_steps=4 format=3 uid="uid://l2by4gv4wpd1"]
+[gd_resource type="ArrayMesh" format=3 uid="uid://l2by4gv4wpd1"]
[ext_resource type="Texture2D" uid="uid://p35o0tkyfmrl" path="res://map/tiles/grass_side.webp" id="1_d17wb"]
diff --git a/client/map/tiles/house/balcony.res b/client/map/tiles/house/balcony.res
index 6a8b9c8e..012c7fbb 100644
--- a/client/map/tiles/house/balcony.res
+++ b/client/map/tiles/house/balcony.res
Binary files differ
diff --git a/client/map/tiles/house/balcony.tscn b/client/map/tiles/house/balcony.tscn
index 1c0232ff..7613c68b 100644
--- a/client/map/tiles/house/balcony.tscn
+++ b/client/map/tiles/house/balcony.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=6 format=3 uid="uid://dymxdxvmgjtae"]
+[gd_scene format=3 uid="uid://dymxdxvmgjtae"]
[ext_resource type="ArrayMesh" uid="uid://1y54ofmdj40i" path="res://map/tiles/house/balcony.res" id="1_6niu3"]
[ext_resource type="Material" uid="uid://djepfh3hn45mt" path="res://map/tiles/house/window_glass.tres" id="2_1yhve"]
@@ -6,12 +6,11 @@
[ext_resource type="Material" uid="uid://p1okexdmch4x" path="res://map/tiles/house/wall_color.tres" id="4_dqlht"]
[ext_resource type="Material" uid="uid://c56pgcp4onece" path="res://map/tiles/house/frame.tres" id="5_xtshi"]
-[node name="HouseBalcony" type="Node3D"]
+[node name="HouseBalcony" type="Node3D" unique_id=1463800129]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1473000161]
transform = Transform3D(5.96244e-09, 0, -0.5, 0, 0.5, 0, 0.5, 0, 5.96244e-09, 0, 0, 0)
mesh = ExtResource("1_6niu3")
-skeleton = NodePath("")
surface_material_override/0 = ExtResource("2_1yhve")
surface_material_override/1 = ExtResource("3_phigl")
surface_material_override/2 = ExtResource("4_dqlht")
diff --git a/client/map/tiles/house/chimney.res b/client/map/tiles/house/chimney.res
index 3c7d43a3..00487f53 100644
--- a/client/map/tiles/house/chimney.res
+++ b/client/map/tiles/house/chimney.res
Binary files differ
diff --git a/client/map/tiles/house/chimney.tscn b/client/map/tiles/house/chimney.tscn
index 68b8faa3..1c40f67b 100644
--- a/client/map/tiles/house/chimney.tscn
+++ b/client/map/tiles/house/chimney.tscn
@@ -1,14 +1,13 @@
-[gd_scene load_steps=4 format=3 uid="uid://bu1y3cish4snv"]
+[gd_scene format=3 uid="uid://bu1y3cish4snv"]
[ext_resource type="ArrayMesh" uid="uid://cji0k4mpudcxs" path="res://map/tiles/house/chimney.res" id="1_tq8p8"]
[ext_resource type="Material" uid="uid://dtoltk5uaa2l6" path="res://map/tiles/house/roof.tres" id="2_epifg"]
[ext_resource type="Material" uid="uid://bnip4xf36u1vv" path="res://map/tiles/house/rooftop.tres" id="2_q0gbv"]
-[node name="HouseRoofChimney" type="Node3D"]
+[node name="HouseRoofChimney" type="Node3D" unique_id=1380252236]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1708887236]
transform = Transform3D(5.96244e-09, 0, -0.5, 0, 0.5, 0, 0.5, 0, 5.96244e-09, 0, 0, 0)
mesh = ExtResource("1_tq8p8")
-skeleton = NodePath("")
surface_material_override/0 = ExtResource("2_q0gbv")
surface_material_override/1 = ExtResource("2_epifg")
diff --git a/client/map/tiles/house/corner.res b/client/map/tiles/house/corner.res
index 33db9356..e116a260 100644
--- a/client/map/tiles/house/corner.res
+++ b/client/map/tiles/house/corner.res
Binary files differ
diff --git a/client/map/tiles/house/corner.tscn b/client/map/tiles/house/corner.tscn
index dc2f5c15..89f9e79e 100644
--- a/client/map/tiles/house/corner.tscn
+++ b/client/map/tiles/house/corner.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=7 format=3 uid="uid://dyl01w3dwdodh"]
+[gd_scene format=3 uid="uid://dyl01w3dwdodh"]
[ext_resource type="ArrayMesh" uid="uid://qa436i3ovnsa" path="res://map/tiles/house/corner.res" id="1_trrsu"]
[ext_resource type="Material" uid="uid://djepfh3hn45mt" path="res://map/tiles/house/window_glass.tres" id="2_dpdnb"]
@@ -7,12 +7,11 @@
[ext_resource type="Material" uid="uid://p1okexdmch4x" path="res://map/tiles/house/wall_color.tres" id="3_x4hec"]
[ext_resource type="Material" uid="uid://c56pgcp4onece" path="res://map/tiles/house/frame.tres" id="4_p1skd"]
-[node name="HouseCorner" type="Node3D"]
+[node name="HouseCorner" type="Node3D" unique_id=902381028]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=527847211]
transform = Transform3D(5.96244e-09, 0, -0.5, 0, 0.5, 0, 0.5, 0, 5.96244e-09, 0, 0, 0)
mesh = ExtResource("1_trrsu")
-skeleton = NodePath("")
surface_material_override/0 = ExtResource("2_dpdnb")
surface_material_override/1 = ExtResource("3_edb5f")
surface_material_override/2 = ExtResource("4_p1skd")
diff --git a/client/map/tiles/house/door.res b/client/map/tiles/house/door.res
index 4314a3ce..e4005e41 100644
--- a/client/map/tiles/house/door.res
+++ b/client/map/tiles/house/door.res
Binary files differ
diff --git a/client/map/tiles/house/door.tscn b/client/map/tiles/house/door.tscn
index 4b6f840f..8e2ccd9c 100644
--- a/client/map/tiles/house/door.tscn
+++ b/client/map/tiles/house/door.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=8 format=3 uid="uid://me0va8kbn0ck"]
+[gd_scene format=3 uid="uid://me0va8kbn0ck"]
[ext_resource type="Material" uid="uid://c56pgcp4onece" path="res://map/tiles/house/frame.tres" id="1_7cj7h"]
[ext_resource type="ArrayMesh" uid="uid://bvrrb1rr6f41l" path="res://map/tiles/house/door.res" id="1_k0ila"]
@@ -11,12 +11,11 @@
cull_mode = 1
albedo_color = Color(0.160784, 0.180392, 0.0901961, 1)
-[node name="HouseDoor" type="Node3D"]
+[node name="HouseDoor" type="Node3D" unique_id=309824877]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1256654900]
transform = Transform3D(5.96244e-09, 0, -0.5, 0, 0.5, 0, 0.5, 0, 5.96244e-09, 0, 0, 0)
mesh = ExtResource("1_k0ila")
-skeleton = NodePath("")
surface_material_override/0 = ExtResource("2_n2fsy")
surface_material_override/1 = ExtResource("3_ca1vx")
surface_material_override/2 = ExtResource("4_lvj6j")
diff --git a/client/map/tiles/house/oriel.res b/client/map/tiles/house/oriel.res
index c25d1c64..fc2f19a0 100644
--- a/client/map/tiles/house/oriel.res
+++ b/client/map/tiles/house/oriel.res
Binary files differ
diff --git a/client/map/tiles/house/oriel.tscn b/client/map/tiles/house/oriel.tscn
index 2f67cf9c..1843bda0 100644
--- a/client/map/tiles/house/oriel.tscn
+++ b/client/map/tiles/house/oriel.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=6 format=3 uid="uid://cvu75687xehqb"]
+[gd_scene format=3 uid="uid://cvu75687xehqb"]
[ext_resource type="ArrayMesh" uid="uid://bvi7worim1fe5" path="res://map/tiles/house/oriel.res" id="1_66iue"]
[ext_resource type="Material" uid="uid://djepfh3hn45mt" path="res://map/tiles/house/window_glass.tres" id="2_66iue"]
@@ -6,12 +6,11 @@
[ext_resource type="Material" uid="uid://p1okexdmch4x" path="res://map/tiles/house/wall_color.tres" id="4_fd1my"]
[ext_resource type="Material" uid="uid://c56pgcp4onece" path="res://map/tiles/house/frame.tres" id="5_5mym6"]
-[node name="HouseOriel" type="Node3D"]
+[node name="HouseOriel" type="Node3D" unique_id=1351378153]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1577039197]
transform = Transform3D(5.96244e-09, 0, -0.5, 0, 0.5, 0, 0.5, 0, 5.96244e-09, 0, 0, 0)
mesh = ExtResource("1_66iue")
-skeleton = NodePath("")
surface_material_override/0 = ExtResource("2_66iue")
surface_material_override/1 = ExtResource("3_fqtxf")
surface_material_override/2 = ExtResource("4_fd1my")
diff --git a/client/map/tiles/house/roof.res b/client/map/tiles/house/roof.res
index b5efd434..ee0ab279 100644
--- a/client/map/tiles/house/roof.res
+++ b/client/map/tiles/house/roof.res
Binary files differ
diff --git a/client/map/tiles/house/roof.tscn b/client/map/tiles/house/roof.tscn
index b9eb92c2..11170208 100644
--- a/client/map/tiles/house/roof.tscn
+++ b/client/map/tiles/house/roof.tscn
@@ -1,12 +1,11 @@
-[gd_scene load_steps=3 format=3 uid="uid://ct7832jj3fewr"]
+[gd_scene format=3 uid="uid://ct7832jj3fewr"]
[ext_resource type="ArrayMesh" uid="uid://xuscogcrjlv0" path="res://map/tiles/house/roof.res" id="1_ar68v"]
[ext_resource type="Material" uid="uid://bnip4xf36u1vv" path="res://map/tiles/house/rooftop.tres" id="2_cfl0y"]
-[node name="HouseRoof" type="Node3D"]
+[node name="HouseRoof" type="Node3D" unique_id=1848385786]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=134240680]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_ar68v")
-skeleton = NodePath("")
surface_material_override/0 = ExtResource("2_cfl0y")
diff --git a/client/map/tiles/house/side.res b/client/map/tiles/house/side.res
index ff974a33..709b07cc 100644
--- a/client/map/tiles/house/side.res
+++ b/client/map/tiles/house/side.res
Binary files differ
diff --git a/client/map/tiles/house/side.tscn b/client/map/tiles/house/side.tscn
index b6d22484..11f1c241 100644
--- a/client/map/tiles/house/side.tscn
+++ b/client/map/tiles/house/side.tscn
@@ -1,14 +1,13 @@
-[gd_scene load_steps=4 format=3 uid="uid://booer6datgac"]
+[gd_scene format=3 uid="uid://booer6datgac"]
[ext_resource type="ArrayMesh" uid="uid://bd72yr7fhdbb6" path="res://map/tiles/house/side.res" id="1_h8y51"]
[ext_resource type="Material" uid="uid://bnip4xf36u1vv" path="res://map/tiles/house/rooftop.tres" id="2_caago"]
[ext_resource type="Material" uid="uid://p1okexdmch4x" path="res://map/tiles/house/wall_color.tres" id="3_rlg5c"]
-[node name="HouseSide" type="Node3D"]
+[node name="HouseSide" type="Node3D" unique_id=876251696]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=605370668]
transform = Transform3D(5.96244e-09, 0, -0.5, 0, 0.5, 0, 0.5, 0, 5.96244e-09, 0, 0, 0)
mesh = ExtResource("1_h8y51")
-skeleton = NodePath("")
surface_material_override/0 = ExtResource("2_caago")
surface_material_override/1 = ExtResource("3_rlg5c")
diff --git a/client/map/tiles/house/wall.res b/client/map/tiles/house/wall.res
index daeaa55c..d9c48a44 100644
--- a/client/map/tiles/house/wall.res
+++ b/client/map/tiles/house/wall.res
Binary files differ
diff --git a/client/map/tiles/house/wall.tscn b/client/map/tiles/house/wall.tscn
index 05bb73ef..e024158e 100644
--- a/client/map/tiles/house/wall.tscn
+++ b/client/map/tiles/house/wall.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=6 format=3 uid="uid://ctd63c1uvf6va"]
+[gd_scene format=3 uid="uid://ctd63c1uvf6va"]
[ext_resource type="ArrayMesh" uid="uid://c4tqpo8dn2mm7" path="res://map/tiles/house/wall.res" id="1_oovdv"]
[ext_resource type="Material" uid="uid://c56pgcp4onece" path="res://map/tiles/house/frame.tres" id="1_xlk0v"]
@@ -6,12 +6,11 @@
[ext_resource type="Material" uid="uid://djepfh3hn45mt" path="res://map/tiles/house/window_glass.tres" id="2_oovdv"]
[ext_resource type="Material" uid="uid://p1okexdmch4x" path="res://map/tiles/house/wall_color.tres" id="4_oovdv"]
-[node name="HouseWall" type="Node3D"]
+[node name="HouseWall" type="Node3D" unique_id=205942806]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1914595227]
transform = Transform3D(5.96244e-09, 0, -0.5, 0, 0.5, 0, 0.5, 0, 5.96244e-09, 0, 0, 0)
mesh = ExtResource("1_oovdv")
-skeleton = NodePath("")
surface_material_override/0 = ExtResource("2_oovdv")
surface_material_override/1 = ExtResource("2_gloxj")
surface_material_override/2 = ExtResource("4_oovdv")
diff --git a/client/map/tiles/house_balcony.gd b/client/map/tiles/house_balcony.gd
index 98fc63ac..210faaa5 100644
--- a/client/map/tiles/house_balcony.gd
+++ b/client/map/tiles/house_balcony.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/tiles/house_door.gd b/client/map/tiles/house_door.gd
index bcd35254..96c14459 100644
--- a/client/map/tiles/house_door.gd
+++ b/client/map/tiles/house_door.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/tiles/house_oriel.gd b/client/map/tiles/house_oriel.gd
index a659267b..828663f7 100644
--- a/client/map/tiles/house_oriel.gd
+++ b/client/map/tiles/house_oriel.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/tiles/house_roof.gd b/client/map/tiles/house_roof.gd
index 9e3e7b5c..30dfb517 100644
--- a/client/map/tiles/house_roof.gd
+++ b/client/map/tiles/house_roof.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/tiles/house_roof_chimney.gd b/client/map/tiles/house_roof_chimney.gd
index d46686d5..4d178788 100644
--- a/client/map/tiles/house_roof_chimney.gd
+++ b/client/map/tiles/house_roof_chimney.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/tiles/house_side.gd b/client/map/tiles/house_side.gd
index bca0317a..3fbaae9d 100644
--- a/client/map/tiles/house_side.gd
+++ b/client/map/tiles/house_side.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/tiles/house_tile.gd b/client/map/tiles/house_tile.gd
index cd0ff6c3..aba81f80 100644
--- a/client/map/tiles/house_tile.gd
+++ b/client/map/tiles/house_tile.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/tiles/house_wall.gd b/client/map/tiles/house_wall.gd
index fea2515d..e01fda08 100644
--- a/client/map/tiles/house_wall.gd
+++ b/client/map/tiles/house_wall.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/tiles/item_portal.gd b/client/map/tiles/item_portal.gd
index 69bad5e9..23e14caf 100644
--- a/client/map/tiles/item_portal.gd
+++ b/client/map/tiles/item_portal.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -14,10 +14,10 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
class_name ItemPortal
-extends CounterBase
+extends Tile
-var model: PortalModel = load("res://map/tiles/portal.tscn").instantiate()
-func _init(ctx: TileFactory.TileCC, type: bool):
+var model := preload("res://map/tiles/portal.tscn")
+func _init(ctx: TileFactory.TileCC, type: float):
super(ctx)
+ base.add_child(model.instantiate())
model.configure(0.2, type)
- base.add_child(model)
diff --git a/client/map/tiles/knife.res b/client/map/tiles/knife.res
index 622d9eb3..8e49bd2e 100644
--- a/client/map/tiles/knife.res
+++ b/client/map/tiles/knife.res
Binary files differ
diff --git a/client/map/tiles/knife.tscn b/client/map/tiles/knife.tscn
index a7cd690e..02836ca3 100644
--- a/client/map/tiles/knife.tscn
+++ b/client/map/tiles/knife.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://cufype1bex3r3"]
+[gd_scene format=3 uid="uid://cufype1bex3r3"]
[ext_resource type="ArrayMesh" uid="uid://buqo28euvn7ru" path="res://map/tiles/knife.res" id="1_uotix"]
-[node name="Knife" type="Node3D"]
+[node name="Knife" type="Node3D" unique_id=49665079]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=772515596]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_uotix")
-skeleton = NodePath("")
diff --git a/client/map/tiles/lamp.gd b/client/map/tiles/lamp.gd
index d315f737..d99949ee 100644
--- a/client/map/tiles/lamp.gd
+++ b/client/map/tiles/lamp.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/tiles/lamp.res b/client/map/tiles/lamp.res
index b4817fac..fa4085b9 100644
--- a/client/map/tiles/lamp.res
+++ b/client/map/tiles/lamp.res
Binary files differ
diff --git a/client/map/tiles/lamp.tscn b/client/map/tiles/lamp.tscn
index 6dbe9e86..13bc8dc8 100644
--- a/client/map/tiles/lamp.tscn
+++ b/client/map/tiles/lamp.tscn
@@ -1,18 +1,18 @@
-[gd_scene load_steps=3 format=3 uid="uid://b6x5xlchih2mc"]
+[gd_scene format=3 uid="uid://b6x5xlchih2mc"]
[ext_resource type="ArrayMesh" uid="uid://cranpcmdoa8mx" path="res://map/tiles/lamp.res" id="1_2f0v1"]
[ext_resource type="Script" uid="uid://nm4trjneu1qt" path="res://map/tiles/light_tile.gd" id="1_87gp4"]
-[node name="Lamp" type="Node3D" node_paths=PackedStringArray("lights")]
+[node name="Lamp" type="Node3D" unique_id=742335162 node_paths=PackedStringArray("lights")]
script = ExtResource("1_87gp4")
lights = [NodePath("OmniLight3D")]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1819243081]
transform = Transform3D(0.3, 0, 0, 0, 0.3, 0, 0, 0, 0.3, 0, 0, 0)
cast_shadow = 0
mesh = ExtResource("1_2f0v1")
-[node name="OmniLight3D" type="OmniLight3D" parent="."]
+[node name="OmniLight3D" type="OmniLight3D" parent="." unique_id=421050732]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.68634, 0)
light_color = Color(0.896459, 0.717604, 0.587842, 1)
light_energy = 3.0
diff --git a/client/map/tiles/leek_crate.gd b/client/map/tiles/leek_crate.gd
deleted file mode 100644
index b90f6602..00000000
--- a/client/map/tiles/leek_crate.gd
+++ /dev/null
@@ -1,21 +0,0 @@
-# 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 <https://www.gnu.org/licenses/>.
-#
-class_name LeekCrate
-extends Crate
-
-func _init(ctx: TileFactory.TileCC):
- super(ctx)
- base.add_child(load("res://map/tiles/leek_crate.tscn").instantiate())
diff --git a/client/map/tiles/leek_crate.gd.uid b/client/map/tiles/leek_crate.gd.uid
deleted file mode 100644
index 8366b070..00000000
--- a/client/map/tiles/leek_crate.gd.uid
+++ /dev/null
@@ -1 +0,0 @@
-uid://fmpnrlya8too
diff --git a/client/map/tiles/leek_crate.tscn b/client/map/tiles/leek_crate.tscn
index 2cf77bc2..9e40ae72 100644
--- a/client/map/tiles/leek_crate.tscn
+++ b/client/map/tiles/leek_crate.tscn
@@ -1,24 +1,24 @@
-[gd_scene load_steps=3 format=3 uid="uid://bkrly2qyttgwh"]
+[gd_scene format=3 uid="uid://bkrly2qyttgwh"]
[ext_resource type="PackedScene" uid="uid://xdui0oya4lpb" path="res://map/tiles/crate.tscn" id="1_l8q4i"]
[ext_resource type="PackedScene" uid="uid://cmpwfkdnrm6e6" path="res://map/items/leek.tscn" id="2_n2ove"]
-[node name="LeekCrate" instance=ExtResource("1_l8q4i")]
+[node name="LeekCrate" unique_id=1033364037 instance=ExtResource("1_l8q4i")]
-[node name="Leek" parent="." index="1" instance=ExtResource("2_n2ove")]
+[node name="Leek" parent="." index="1" unique_id=1746190140 instance=ExtResource("2_n2ove")]
transform = Transform3D(-0.5767554, -0.79622483, -0.18269974, 0.8157721, -0.573194, -0.07723002, -0.043229926, -0.19358417, 0.9801311, -0.11139119, 0.28240138, -0.204823)
-[node name="Leek2" parent="." index="2" instance=ExtResource("2_n2ove")]
+[node name="Leek2" parent="." index="2" unique_id=974732976 instance=ExtResource("2_n2ove")]
transform = Transform3D(0.5011232, -0.9659322, -0.3177097, 0.8640088, 0.5337136, 0.23595639, -0.04862662, -0.471297, 0.91836, 0.3106259, 0.18931627, -0.223387)
-[node name="Leek3" parent="." index="3" instance=ExtResource("2_n2ove")]
+[node name="Leek3" parent="." index="3" unique_id=1903030949 instance=ExtResource("2_n2ove")]
transform = Transform3D(-0.40310276, -0.9025585, 0.15131347, 0.911373, -0.41092736, -0.023192208, 0.08311114, 0.12855409, 0.9882142, -0.136853, 0.30587843, 0.253195)
-[node name="Leek4" parent="." index="4" instance=ExtResource("2_n2ove")]
+[node name="Leek4" parent="." index="4" unique_id=1669547444 instance=ExtResource("2_n2ove")]
transform = Transform3D(0.47521883, 0.51630676, -0.7674939, 0.8236207, 0.10721652, 0.560059, 0.3095418, -1.0779284, -0.31190884, 0.1674414, 0.2460402, 0.34835967)
-[node name="Leek5" parent="." index="5" instance=ExtResource("2_n2ove")]
+[node name="Leek5" parent="." index="5" unique_id=2085585545 instance=ExtResource("2_n2ove")]
transform = Transform3D(0.32411182, -0.028707754, -0.94571644, 0.9431412, 0.10330227, 0.32105142, 0.0737312, -1.1951997, 0.050463554, 0.22963816, 0.2460402, 0.07488689)
-[node name="Leek6" parent="." index="6" instance=ExtResource("2_n2ove")]
+[node name="Leek6" parent="." index="6" unique_id=1797263298 instance=ExtResource("2_n2ove")]
transform = Transform3D(-0.4909433, -1.0452821, 0.014611006, 0.85173434, -0.58012193, -0.2020859, 0.1830938, -0.10412076, 0.9792587, -0.10463678, 0.29387888, 0.014548987)
diff --git a/client/map/tiles/lettuce_crate.tscn b/client/map/tiles/lettuce_crate.tscn
index 922773bf..e98f26c2 100644
--- a/client/map/tiles/lettuce_crate.tscn
+++ b/client/map/tiles/lettuce_crate.tscn
@@ -1,18 +1,18 @@
-[gd_scene load_steps=3 format=3 uid="uid://brgkq8x5jgxyb"]
+[gd_scene format=3 uid="uid://brgkq8x5jgxyb"]
[ext_resource type="PackedScene" uid="uid://xdui0oya4lpb" path="res://map/tiles/crate.tscn" id="1_57wln"]
[ext_resource type="PackedScene" uid="uid://cuf8vwqk6xujk" path="res://map/items/lettuce.tscn" id="3_03evc"]
-[node name="LettuceCrate" instance=ExtResource("1_57wln")]
+[node name="LettuceCrate" unique_id=1488715909 instance=ExtResource("1_57wln")]
-[node name="Lettuce" parent="." index="1" instance=ExtResource("3_03evc")]
+[node name="Lettuce" parent="." index="1" unique_id=1196212278 instance=ExtResource("3_03evc")]
transform = Transform3D(0.258819, 0, -0.965926, 0, 1, 0, 0.965926, 0, 0.258819, -0.15, 0, -0.15)
-[node name="Lettuce2" parent="." index="2" instance=ExtResource("3_03evc")]
+[node name="Lettuce2" parent="." index="2" unique_id=867063712 instance=ExtResource("3_03evc")]
transform = Transform3D(0.939693, 0, -0.34202, 0, 1, 0, 0.34202, 0, 0.939693, 0.15, 0, 0.15)
-[node name="Lettuce3" parent="." index="3" instance=ExtResource("3_03evc")]
+[node name="Lettuce3" parent="." index="3" unique_id=1638372503 instance=ExtResource("3_03evc")]
transform = Transform3D(0.939693, 0, -0.34202, 0, 1, 0, 0.34202, 0, 0.939693, -0.15, 0.15, 0.15)
-[node name="Lettuce4" parent="." index="4" instance=ExtResource("3_03evc")]
+[node name="Lettuce4" parent="." index="4" unique_id=563023149 instance=ExtResource("3_03evc")]
transform = Transform3D(0.939693, 0, -0.34202, 0, 1, 0, 0.34202, 0, 0.939693, 0.15, 0.15, -0.15)
diff --git a/client/map/tiles/light_tile.gd b/client/map/tiles/light_tile.gd
index 2476d8eb..2187ec6f 100644
--- a/client/map/tiles/light_tile.gd
+++ b/client/map/tiles/light_tile.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/tiles/map_selector.res b/client/map/tiles/map_selector.res
new file mode 100644
index 00000000..4b25868d
--- /dev/null
+++ b/client/map/tiles/map_selector.res
Binary files differ
diff --git a/client/map/tiles/map_selector.tscn b/client/map/tiles/map_selector.tscn
new file mode 100644
index 00000000..a91b8cb7
--- /dev/null
+++ b/client/map/tiles/map_selector.tscn
@@ -0,0 +1,9 @@
+[gd_scene format=3 uid="uid://bsl8lb18f8hcv"]
+
+[ext_resource type="ArrayMesh" uid="uid://bbfwavihrmf4i" path="res://map/tiles/map_selector.res" id="1_ktcsy"]
+
+[node name="MapSelector" type="Node3D" unique_id=2017272843]
+
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=767071822]
+transform = Transform3D(-2.1855694e-08, 0, 0.5, 0, 0.5, 0, -0.5, 0, -2.1855694e-08, 0, 0.525, 0)
+mesh = ExtResource("1_ktcsy")
diff --git a/client/map/tiles/mushroom_crate.gd b/client/map/tiles/mushroom_crate.gd
deleted file mode 100644
index de59b8f5..00000000
--- a/client/map/tiles/mushroom_crate.gd
+++ /dev/null
@@ -1,21 +0,0 @@
-# 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 <https://www.gnu.org/licenses/>.
-#
-class_name MushroomCrate
-extends Crate
-
-func _init(ctx: TileFactory.TileCC):
- super(ctx)
- base.add_child(load("res://map/tiles/mushroom_crate.tscn").instantiate())
diff --git a/client/map/tiles/mushroom_crate.gd.uid b/client/map/tiles/mushroom_crate.gd.uid
deleted file mode 100644
index b0c54434..00000000
--- a/client/map/tiles/mushroom_crate.gd.uid
+++ /dev/null
@@ -1 +0,0 @@
-uid://by0dud130fog6
diff --git a/client/map/tiles/mushroom_crate.tscn b/client/map/tiles/mushroom_crate.tscn
index 01a5ed87..aa42f482 100644
--- a/client/map/tiles/mushroom_crate.tscn
+++ b/client/map/tiles/mushroom_crate.tscn
@@ -1,21 +1,21 @@
-[gd_scene load_steps=3 format=3 uid="uid://dn4o5dyp7t021"]
+[gd_scene format=3 uid="uid://dn4o5dyp7t021"]
[ext_resource type="PackedScene" uid="uid://xdui0oya4lpb" path="res://map/tiles/crate.tscn" id="1_juoqu"]
[ext_resource type="PackedScene" uid="uid://cc0jqiiywrrc0" path="res://map/items/mushroom.tscn" id="2_juoqu"]
-[node name="MushroomCrate" instance=ExtResource("1_juoqu")]
+[node name="MushroomCrate" unique_id=2098365067 instance=ExtResource("1_juoqu")]
-[node name="Mushroom" parent="." index="1" instance=ExtResource("2_juoqu")]
+[node name="Mushroom" parent="." index="1" unique_id=1158588513 instance=ExtResource("2_juoqu")]
transform = Transform3D(0.3251556, 0, -0.94566053, 0.22043908, 0.9724513, 0.075795695, 0.91960883, -0.23310593, 0.316198, -0.18228972, 0.08433756, -0.16040182)
-[node name="Mushroom2" parent="." index="2" instance=ExtResource("2_juoqu")]
+[node name="Mushroom2" parent="." index="2" unique_id=1505234337 instance=ExtResource("2_juoqu")]
transform = Transform3D(1.0213542, -0.27169096, -0.30499113, 0.30648074, 1.0527234, 0.08855964, 0.27000946, -0.16720423, 1.0531559, -0.15469912, 0.08611792, 0.22869657)
-[node name="Mushroom3" parent="." index="3" instance=ExtResource("2_juoqu")]
+[node name="Mushroom3" parent="." index="3" unique_id=1740137701 instance=ExtResource("2_juoqu")]
transform = Transform3D(0.905218, -0.124258906, 0.40637422, 0.12618923, 0.9917586, 0.022162013, -0.40577894, 0.031218598, 0.91343796, 0.25116885, 0.080719024, 0.16321422)
-[node name="Mushroom4" parent="." index="4" instance=ExtResource("2_juoqu")]
+[node name="Mushroom4" parent="." index="4" unique_id=382878953 instance=ExtResource("2_juoqu")]
transform = Transform3D(-0.34809524, -0.05838425, -0.93563926, 0.1280063, 0.9857505, -0.10913467, 0.9286787, -0.15775698, -0.33566153, 0.2079333, 0.058740195, -0.1254655)
-[node name="Mushroom5" parent="." index="5" instance=ExtResource("2_juoqu")]
+[node name="Mushroom5" parent="." index="5" unique_id=1716232471 instance=ExtResource("2_juoqu")]
transform = Transform3D(-0.09821522, -0.16101892, -0.9820523, 0.3132099, 0.9316722, -0.18408266, 0.94459164, -0.32566825, -0.041071653, 0, 0.15, 0.03306987)
diff --git a/client/map/tiles/noodles_crate.tscn b/client/map/tiles/noodles_crate.tscn
new file mode 100644
index 00000000..151219aa
--- /dev/null
+++ b/client/map/tiles/noodles_crate.tscn
@@ -0,0 +1,30 @@
+[gd_scene format=3 uid="uid://b0jyx2gu6fcx7"]
+
+[ext_resource type="ArrayMesh" uid="uid://btn7oh1v2k40p" path="res://map/tiles/crate.res" id="1_vcnsh"]
+[ext_resource type="ArrayMesh" uid="uid://c7nmboj44jn7a" path="res://map/items/noodles.res" id="2_3k214"]
+
+[node name="Crate" type="Node3D" unique_id=235966363]
+
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=2104345741]
+transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
+mesh = ExtResource("1_vcnsh")
+
+[node name="Noodles" type="MeshInstance3D" parent="." unique_id=330418144]
+transform = Transform3D(0.49983656, 0.012705037, 0.0014109544, -0.012783143, 0.4967825, 0.05517004, 0, -0.05518808, 0.49694493, -0.02444148, 0.3581394, 0.099653274)
+mesh = ExtResource("2_3k214")
+
+[node name="Noodles2" type="MeshInstance3D" parent="." unique_id=39703036]
+transform = Transform3D(0.36541817, 0, 0.16269466, 0, 0.4, 0, -0.16269466, 0, 0.36541817, -0.151, 0.239, 0.265)
+mesh = ExtResource("2_3k214")
+
+[node name="Noodles3" type="MeshInstance3D" parent="." unique_id=1633575361]
+transform = Transform3D(-0.19513778, 0, 0.3491722, 0, 0.39999998, 0, -0.3491722, 0, -0.19513778, 0.23498613, 0.24920535, 0.14507401)
+mesh = ExtResource("2_3k214")
+
+[node name="Noodles4" type="MeshInstance3D" parent="." unique_id=264982564]
+transform = Transform3D(-0.3997121, 0, -0.015173763, 0, 0.39999998, 0, 0.015173763, 0, -0.3997121, 0.16035348, 0.24920535, -0.2861838)
+mesh = ExtResource("2_3k214")
+
+[node name="Noodles5" type="MeshInstance3D" parent="." unique_id=1506519209]
+transform = Transform3D(0.111918226, 0, -0.38402385, 0, 0.39999995, 0, 0.38402385, 0, 0.111918226, -0.2625249, 0.24920535, -0.16159214)
+mesh = ExtResource("2_3k214")
diff --git a/client/map/tiles/oven.gd b/client/map/tiles/oven.gd
index ef47047f..14ff0758 100644
--- a/client/map/tiles/oven.gd
+++ b/client/map/tiles/oven.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -14,7 +14,7 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
class_name Oven
-extends Counter
+extends CounterLike
var oven: OvenModel = load("res://map/tiles/oven.tscn").instantiate()
diff --git a/client/map/tiles/oven.tscn b/client/map/tiles/oven.tscn
index 69fea89d..14b0a7cc 100644
--- a/client/map/tiles/oven.tscn
+++ b/client/map/tiles/oven.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=8 format=3 uid="uid://bil6eip7uwqvs"]
+[gd_scene format=3 uid="uid://bil6eip7uwqvs"]
[ext_resource type="Script" uid="uid://evb48gqf08js" path="res://map/tiles/oven_model.gd" id="1_3v43w"]
[ext_resource type="ArrayMesh" uid="uid://blc1q50d5ky86" path="res://map/tiles/oven_base.res" id="1_d1hwl"]
@@ -39,25 +39,21 @@ _data = {
&"open": SubResource("Animation_yb3ht")
}
-[node name="Oven" type="Node3D"]
+[node name="Oven" type="Node3D" unique_id=144691918]
script = ExtResource("1_3v43w")
-[node name="Base" type="MeshInstance3D" parent="."]
+[node name="Base" type="MeshInstance3D" parent="." unique_id=1278985448]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_d1hwl")
-skeleton = NodePath("")
-[node name="Door" type="MeshInstance3D" parent="Base"]
+[node name="Door" type="MeshInstance3D" parent="Base" unique_id=964634352]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.25, 0.43, 0.9)
mesh = ExtResource("2_i5vso")
-skeleton = NodePath("")
-[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
-libraries = {
-&"": SubResource("AnimationLibrary_io5nw")
-}
+[node name="AnimationPlayer" type="AnimationPlayer" parent="." unique_id=1708626511]
+libraries/ = SubResource("AnimationLibrary_io5nw")
-[node name="OmniLight3D" type="OmniLight3D" parent="."]
+[node name="OmniLight3D" type="OmniLight3D" parent="." unique_id=1222495133]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.7, 0)
visible = false
light_color = Color(0.944743, 0.70243, 0.38641, 1)
diff --git a/client/map/tiles/oven_base.res b/client/map/tiles/oven_base.res
index 6cef2533..c9a9cb73 100644
--- a/client/map/tiles/oven_base.res
+++ b/client/map/tiles/oven_base.res
Binary files differ
diff --git a/client/map/tiles/oven_door.res b/client/map/tiles/oven_door.res
index 8c468117..695b437b 100644
--- a/client/map/tiles/oven_door.res
+++ b/client/map/tiles/oven_door.res
Binary files differ
diff --git a/client/map/tiles/oven_model.gd b/client/map/tiles/oven_model.gd
index 9ad66bd6..644213ff 100644
--- a/client/map/tiles/oven_model.gd
+++ b/client/map/tiles/oven_model.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/tiles/path.gd b/client/map/tiles/path.gd
index 1127c0bf..cfb598ca 100644
--- a/client/map/tiles/path.gd
+++ b/client/map/tiles/path.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/tiles/path.res b/client/map/tiles/path.res
index e775b24e..9bd9f0dd 100644
--- a/client/map/tiles/path.res
+++ b/client/map/tiles/path.res
Binary files differ
diff --git a/client/map/tiles/path.tscn b/client/map/tiles/path.tscn
index b618e279..a5a04374 100644
--- a/client/map/tiles/path.tscn
+++ b/client/map/tiles/path.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://bwyb2ujmcrsar"]
+[gd_scene format=3 uid="uid://bwyb2ujmcrsar"]
[ext_resource type="ArrayMesh" uid="uid://1jelocokc0vu" path="res://map/tiles/path.res" id="1_6fqu5"]
-[node name="Path" type="Node3D"]
+[node name="Path" type="Node3D" unique_id=1933680340]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1928567105]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, -0.3, 0)
mesh = ExtResource("1_6fqu5")
-skeleton = NodePath("")
diff --git a/client/map/tiles/player_portal.gd b/client/map/tiles/player_portal.gd
index e722a7ee..a9bd7fa0 100644
--- a/client/map/tiles/player_portal.gd
+++ b/client/map/tiles/player_portal.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -14,10 +14,16 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
class_name PlayerPortal
-extends Floor
+extends Tile
var model: PortalModel = load("res://map/tiles/portal.tscn").instantiate()
-func _init(ctx: TileFactory.TileCC, type: bool):
+func _init(ctx: TileFactory.TileCC):
super(ctx)
- model.configure(0.4, type)
+ change(ctx.tile_name.name)
base.add_child(model)
+
+func change(tn: String) -> bool:
+ if tn == "white-hole": model.target_type = 1.; model.target_size = 0.4; return true
+ if tn == "grey-hole": model.target_type = 0.; model.target_size = 0.2; return true
+ if tn == "black-hole": model.target_type = -1.; model.target_size = 0.4; return true
+ return false
diff --git a/client/map/tiles/portal.gd b/client/map/tiles/portal.gd
index 961a8615..dc7d8700 100644
--- a/client/map/tiles/portal.gd
+++ b/client/map/tiles/portal.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -16,7 +16,22 @@
class_name PortalModel
extends Node3D
+var target_type = 0.
+var current_type = 0.
+var target_size = 0.
+var current_size = 0.
+@onready var mat: ShaderMaterial = $Mesh.get_active_material(0)
+
+func _process(delta: float) -> void:
+ if not mat: return
+ if abs(target_type - current_type) > 0.01:
+ current_type = G.interpolate(current_type, target_type, delta * 15.)
+ mat.set_shader_parameter("type", current_type)
+ if abs(target_size - current_size) > 0.01:
+ current_size = G.interpolate(current_size, target_size, delta * 5.)
+ mat.set_shader_parameter("size", current_size)
+
func configure(size: float, type: bool):
- var mat: ShaderMaterial = $Mesh.get_active_material(0)
- mat.set_shader_parameter("size", size)
- mat.set_shader_parameter("type", 1. if type else -1.)
+ mat = $Mesh.get_active_material(0)
+ target_type = 1. if type else -1.
+ target_size = size
diff --git a/client/map/tiles/portal.gdshader b/client/map/tiles/portal.gdshader
index a9dbd1e6..e3093b07 100644
--- a/client/map/tiles/portal.gdshader
+++ b/client/map/tiles/portal.gdshader
@@ -1,6 +1,6 @@
/*
Hurry Curry! - a game about cooking
- Copyright (C) 2025 Hurry Curry! Contributors
+ Copyright (C) 2026 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
@@ -25,6 +25,7 @@ varying vec3 world_position;
uniform float type : hint_range(-1.0, 1.0);
uniform float size : hint_range(0.0, 2.0);
+uniform vec3 glow : source_color;
void vertex() {
MODELVIEW_MATRIX = VIEW_MATRIX * mat4(
@@ -37,25 +38,21 @@ void vertex() {
world_camera = (inverse(MODELVIEW_MATRIX) * vec4(0, 0, 0, 1)).xyz;
}
+vec2 rv_to_screen(mat4 pm, vec3 rv) {
+ vec4 k = pm * vec4(rv*1000.0, 1.0);
+ k /= k.w;
+ return (k.xy + 1.) / 2.;
+}
+
void fragment() {
vec3 ray = world_camera / size;
vec3 rv = normalize(world_position - world_camera);
- vec3 em = vec3(0.);
- bool hit = false;
-
- for (int i = 0; i < 100; i++) {
- float st = length(ray) * 0.1;
- ray += normalize(rv) * st;
- if (length(ray) < 1.) { hit = true; break; }
- rv += -normalize(ray) * -type / exp(dot(ray,ray)) * st;
- em += st * smoothstep(1.5,1.2,length(ray)) * 0.2;
- }
-
- vec4 k = PROJECTION_MATRIX * vec4(rv*1000.0, 1.0);
- k /= k.w;
- vec2 k2 = (k.xy + 1.) / 2.;
-
- vec3 col = hit ? vec3(type*0.5+0.5) : texture(screen_texture, k2).rgb;
- col += vec3(0.3,0.0,1.0) * max(em - 0.1,0.);
+
+ vec3 o = ray + length(ray)*rv;
+ float d = length(o) - 1.;
+ rv += o / (exp(d*2.)-1.) * type * 0.08;
+ vec2 screen = rv_to_screen(PROJECTION_MATRIX, rv);
+ vec3 col = d<0. ? vec3(type*0.5+0.5) : texture(screen_texture, screen).rgb;
+ col += glow * exp(d < 0. ? d*30. : d*-10.);
ALBEDO = col;
}
diff --git a/client/map/tiles/portal.tscn b/client/map/tiles/portal.tscn
index 372b97ea..07c39c76 100644
--- a/client/map/tiles/portal.tscn
+++ b/client/map/tiles/portal.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=5 format=3 uid="uid://cc5ubao3ln3r6"]
+[gd_scene format=3 uid="uid://cc5ubao3ln3r6"]
[ext_resource type="Shader" uid="uid://emcvwj5fjmju" path="res://map/tiles/portal.gdshader" id="1_aiexk"]
[ext_resource type="Script" uid="uid://cbr1qsqk5cyl2" path="res://map/tiles/portal.gd" id="1_h7xlp"]
@@ -10,13 +10,14 @@ size = Vector2(3, 3)
resource_local_to_scene = true
render_priority = 0
shader = ExtResource("1_aiexk")
-shader_parameter/type = 4.75e-08
-shader_parameter/size = 0.2
+shader_parameter/type = -1.0
+shader_parameter/size = 0.2000000095
+shader_parameter/glow = Color(0.6156863, 0.003921569, 1, 1)
-[node name="Portal" type="Node3D"]
+[node name="Portal" type="Node3D" unique_id=1362510877]
script = ExtResource("1_h7xlp")
-[node name="Mesh" type="MeshInstance3D" parent="."]
-transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.7, 0)
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=726727519]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0022193193, 0.69999975, -0.0013526678)
mesh = SubResource("QuadMesh_us4em")
surface_material_override/0 = SubResource("ShaderMaterial_hvgsb")
diff --git a/client/map/tiles/potato_crate.gd b/client/map/tiles/potato_crate.gd
deleted file mode 100644
index d5fdd8e9..00000000
--- a/client/map/tiles/potato_crate.gd
+++ /dev/null
@@ -1,21 +0,0 @@
-# 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 <https://www.gnu.org/licenses/>.
-#
-class_name PotatoCrate
-extends Crate
-
-func _init(ctx: TileFactory.TileCC):
- super(ctx)
- base.add_child(load("res://map/tiles/potato_crate.tscn").instantiate())
diff --git a/client/map/tiles/potato_crate.gd.uid b/client/map/tiles/potato_crate.gd.uid
deleted file mode 100644
index cf021ee9..00000000
--- a/client/map/tiles/potato_crate.gd.uid
+++ /dev/null
@@ -1 +0,0 @@
-uid://tyivqc0wc6mi
diff --git a/client/map/tiles/potato_crate.tscn b/client/map/tiles/potato_crate.tscn
index 9ced8854..404e3fdc 100644
--- a/client/map/tiles/potato_crate.tscn
+++ b/client/map/tiles/potato_crate.tscn
@@ -1,38 +1,38 @@
-[gd_scene load_steps=3 format=3 uid="uid://c764nf6aojyvx"]
+[gd_scene format=3 uid="uid://c764nf6aojyvx"]
[ext_resource type="ArrayMesh" uid="uid://btn7oh1v2k40p" path="res://map/tiles/crate.res" id="1_3ga66"]
[ext_resource type="ArrayMesh" uid="uid://hj2dib0t8em3" path="res://map/items/potato.res" id="2_3ga66"]
-[node name="PotatoCrate" type="Node3D"]
+[node name="PotatoCrate" type="Node3D" unique_id=958359962]
-[node name="Crate" type="MeshInstance3D" parent="."]
+[node name="Crate" type="MeshInstance3D" parent="." unique_id=1476692277]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_3ga66")
-[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
+[node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=737788022]
transform = Transform3D(1.9395866e-08, 0.44372568, 0.074883275, 0.43525255, 0.019013587, -0.112666346, -0.11425943, 0.0724292, -0.42918384, -0.2245059, 0.2020701, -0.17833076)
mesh = ExtResource("2_3ga66")
-[node name="MeshInstance3D6" type="MeshInstance3D" parent="."]
+[node name="MeshInstance3D6" type="MeshInstance3D" parent="." unique_id=11436800]
transform = Transform3D(1.9395866e-08, 0.44372568, 0.074883275, 0.43525255, 0.019013587, -0.112666346, -0.11425943, 0.0724292, -0.42918384, -0.0090149045, 0.35778415, -0.17833076)
mesh = ExtResource("2_3ga66")
-[node name="MeshInstance3D7" type="MeshInstance3D" parent="."]
+[node name="MeshInstance3D7" type="MeshInstance3D" parent="." unique_id=866909482]
transform = Transform3D(0.07296345, 0.06498954, -0.43926376, 0.43169037, 0.09389621, 0.08559741, 0.10401813, -0.4352699, -0.04712081, 0.015495509, 0.3663897, 0.14554687)
mesh = ExtResource("2_3ga66")
-[node name="MeshInstance3D2" type="MeshInstance3D" parent="."]
+[node name="MeshInstance3D2" type="MeshInstance3D" parent="." unique_id=1979398488]
transform = Transform3D(-0.12614171, -0.25575554, -0.3481054, 0.43195862, -0.07468642, -0.10165464, -1.5851693e-08, -0.3626445, 0.26643753, -0.18310761, 0.21690153, 0.19903006)
mesh = ExtResource("2_3ga66")
-[node name="MeshInstance3D3" type="MeshInstance3D" parent="."]
+[node name="MeshInstance3D3" type="MeshInstance3D" parent="." unique_id=934217696]
transform = Transform3D(0.08798323, 0.09877133, 0.43012, 0.44131497, -0.019691661, -0.08575129, 1.8829489e-08, 0.43858457, -0.1007151, 0.19106877, 0.19821344, -0.2371732)
mesh = ExtResource("2_3ga66")
-[node name="MeshInstance3D5" type="MeshInstance3D" parent="."]
+[node name="MeshInstance3D5" type="MeshInstance3D" parent="." unique_id=455737052]
transform = Transform3D(-0.061073676, -0.043150976, 0.4437432, 0.4453779, 0.0143979285, 0.062698804, -0.020209989, 0.4476948, 0.040753797, 0.1624504, 0.19821344, -0.01481241)
mesh = ExtResource("2_3ga66")
-[node name="MeshInstance3D4" type="MeshInstance3D" parent="."]
+[node name="MeshInstance3D4" type="MeshInstance3D" parent="." unique_id=702936552]
transform = Transform3D(-6.4949006e-09, -0.148586, 0.31689468, 0.35, -1.5298985e-08, 2.6817607e-17, 1.3851905e-08, 0.31689468, 0.148586, 0.23736578, 0.175, 0.22895074)
mesh = ExtResource("2_3ga66")
diff --git a/client/map/tiles/rice_crate.gd b/client/map/tiles/rice_crate.gd
deleted file mode 100644
index 456a18f7..00000000
--- a/client/map/tiles/rice_crate.gd
+++ /dev/null
@@ -1,21 +0,0 @@
-# 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 <https://www.gnu.org/licenses/>.
-#
-class_name RiceCrate
-extends Crate
-
-func _init(ctx: TileFactory.TileCC):
- super(ctx)
- base.add_child(load("res://map/tiles/rice_crate.tscn").instantiate())
diff --git a/client/map/tiles/rice_crate.gd.uid b/client/map/tiles/rice_crate.gd.uid
deleted file mode 100644
index c1e454e7..00000000
--- a/client/map/tiles/rice_crate.gd.uid
+++ /dev/null
@@ -1 +0,0 @@
-uid://b51bickm0rq1y
diff --git a/client/map/tiles/rice_crate.tscn b/client/map/tiles/rice_crate.tscn
index 72c6c540..f9b86963 100644
--- a/client/map/tiles/rice_crate.tscn
+++ b/client/map/tiles/rice_crate.tscn
@@ -1,9 +1,9 @@
-[gd_scene load_steps=3 format=3 uid="uid://bk0jvgj6xg23d"]
+[gd_scene format=3 uid="uid://bk0jvgj6xg23d"]
[ext_resource type="PackedScene" uid="uid://xdui0oya4lpb" path="res://map/tiles/crate.tscn" id="1_wfea8"]
[ext_resource type="PackedScene" uid="uid://rs4b17lp80cx" path="res://map/items/rice.tscn" id="2_fbw0j"]
-[node name="RiceCrate" instance=ExtResource("1_wfea8")]
+[node name="RiceCrate" unique_id=1561944393 instance=ExtResource("1_wfea8")]
-[node name="Rice" parent="." index="1" instance=ExtResource("2_fbw0j")]
+[node name="Rice" parent="." index="1" unique_id=38870235 instance=ExtResource("2_fbw0j")]
transform = Transform3D(3, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0)
diff --git a/client/map/tiles/rolling_board.gd b/client/map/tiles/rolling_board.gd
index 078897b1..93db2989 100644
--- a/client/map/tiles/rolling_board.gd
+++ b/client/map/tiles/rolling_board.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -14,44 +14,10 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
class_name RollingBoard
-extends CounterBase
-
-var board = load("res://map/tiles/rolling_board.tscn").instantiate()
-var rolling: AudioStreamPlayer3D = AudioStreamPlayer3D.new()
-var acting_player
+extends ActiveInteractCounter
func _init(ctx: TileFactory.TileCC):
- super(ctx)
- rolling.stream = preload("res://map/tiles/sounds/roll.ogg")
- rolling.volume_db = -10
- add_child(rolling)
- base.add_child(board)
-
-func progress(position_: float, speed: float, warn: bool, acting_player_):
- super(position_, speed, warn, acting_player)
- var pin: Node3D = board.get_node("RollingPin")
- acting_player = acting_player_
-
- if not rolling.playing and speed != 0.:
- rolling.play()
- if acting_player != null:
- pin.visible = false
- var acting_character: Character = acting_player.character
- acting_character.rolling = true
- elif speed == 0:
- rolling.stop()
- pin.visible = true
- if acting_player != null:
- var acting_character: Character = acting_player.character
- acting_character.rolling = false
-
-func finish():
- super()
- if is_instance_valid(acting_player):
- var acting_character: Character = acting_player.character
- acting_character.rolling = false
- board.get_node("RollingPin").visible = true
- rolling.stop()
+ super(ctx, preload("res://map/tiles/rolling_board.tscn"), "RollingBoard/RollingPin", func (p: Player, x: bool): p.character.rolling = x, preload("res://map/tiles/sounds/roll.ogg"))
-static func interact_target() -> Vector3:
+static func interact_target(): # -> Vector3?
return Vector3(0., 0.575, 0.)
diff --git a/client/map/tiles/rolling_board.tscn b/client/map/tiles/rolling_board.tscn
index ecf1c036..3e366ad3 100644
--- a/client/map/tiles/rolling_board.tscn
+++ b/client/map/tiles/rolling_board.tscn
@@ -1,14 +1,13 @@
-[gd_scene load_steps=3 format=3 uid="uid://c15xsbx0bduqt"]
+[gd_scene format=3 uid="uid://c15xsbx0bduqt"]
[ext_resource type="ArrayMesh" uid="uid://dd4g04lgvsly5" path="res://map/tiles/cutting_board.res" id="1_cuxby"]
[ext_resource type="PackedScene" uid="uid://c8t04dfp45a86" path="res://map/tiles/rolling_pin.tscn" id="2_cuxby"]
-[node name="CuttingBoard" type="Node3D"]
+[node name="RollingBoard" type="Node3D" unique_id=145149049]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1864479003]
transform = Transform3D(0.4, 0, 0, 0, 0.5, 0, 0, 0, 0.5, -0.075, 0.5, 0)
mesh = ExtResource("1_cuxby")
-skeleton = NodePath("")
-[node name="RollingPin" parent="." instance=ExtResource("2_cuxby")]
+[node name="RollingPin" parent="." unique_id=397072105 instance=ExtResource("2_cuxby")]
transform = Transform3D(0.0979824, 0, -0.9951882, 0, 1, 0, 0.9951882, 0, 0.0979824, 0.3562666, 0.575, 0)
diff --git a/client/map/tiles/rolling_pin.res b/client/map/tiles/rolling_pin.res
index 29a31bc7..c5be7946 100644
--- a/client/map/tiles/rolling_pin.res
+++ b/client/map/tiles/rolling_pin.res
Binary files differ
diff --git a/client/map/tiles/rolling_pin.tscn b/client/map/tiles/rolling_pin.tscn
index b25419cd..c2cbc343 100644
--- a/client/map/tiles/rolling_pin.tscn
+++ b/client/map/tiles/rolling_pin.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://c8t04dfp45a86"]
+[gd_scene format=3 uid="uid://c8t04dfp45a86"]
[ext_resource type="ArrayMesh" uid="uid://bijk6tpibbek3" path="res://map/tiles/rolling_pin.res" id="1_s0lm5"]
-[node name="RollingPin" type="Node3D"]
+[node name="RollingPin" type="Node3D" unique_id=1931827681]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1368520525]
transform = Transform3D(1.75, 0, 0, 0, 1.75, 0, 0, 0, 1.75, 0, 0, 0)
mesh = ExtResource("1_s0lm5")
-skeleton = NodePath("")
diff --git a/client/map/tiles/screen/screen.gd b/client/map/tiles/screen/screen.gd
new file mode 100644
index 00000000..41667830
--- /dev/null
+++ b/client/map/tiles/screen/screen.gd
@@ -0,0 +1,24 @@
+# Hurry Curry! - a game about cooking
+# Copyright (C) 2026 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 <https://www.gnu.org/licenses/>.
+#
+class_name Screen
+extends Tile
+
+func _init(ctx: TileFactory.TileCC):
+ super(ctx)
+ var screen_model: ScreenModel = load("res://map/tiles/screen/screen.tscn").instantiate()
+ base.add_child(screen_model)
+ screen_model.set_server_context(ctx.server_context)
+ \ No newline at end of file
diff --git a/client/map/tiles/screen/screen.gd.uid b/client/map/tiles/screen/screen.gd.uid
new file mode 100644
index 00000000..c55416cb
--- /dev/null
+++ b/client/map/tiles/screen/screen.gd.uid
@@ -0,0 +1 @@
+uid://dodq5s5bpfr3c
diff --git a/client/map/tiles/screen/screen.res.depren b/client/map/tiles/screen/screen.res.depren
new file mode 100644
index 00000000..365a3c86
--- /dev/null
+++ b/client/map/tiles/screen/screen.res.depren
Binary files differ
diff --git a/client/map/tiles/screen/screen.tscn b/client/map/tiles/screen/screen.tscn
new file mode 100644
index 00000000..a1f88294
--- /dev/null
+++ b/client/map/tiles/screen/screen.tscn
@@ -0,0 +1,36 @@
+[gd_scene format=3 uid="uid://vqe0wrt0ddq"]
+
+[ext_resource type="ArrayMesh" uid="uid://g6nwwhptmmmd" path="res://map/tiles/screen/screen_display.res" id="1_d1utq"]
+[ext_resource type="Script" uid="uid://cye7akcsp46cv" path="res://map/tiles/screen/screen_model.gd" id="1_fabw7"]
+[ext_resource type="ArrayMesh" uid="uid://nsmq1ko2woad" path="res://map/tiles/screen/screen_base.res" id="1_mm46a"]
+[ext_resource type="PackedScene" uid="uid://d22cslgao5jd4" path="res://map/tiles/floor.tscn" id="3_dmy1m"]
+[ext_resource type="PackedScene" uid="uid://dgtdfctc0x78v" path="res://gui/menus/screen_info.tscn" id="4_ebgc8"]
+
+[node name="Screen" type="Node3D" unique_id=1614533170]
+script = ExtResource("1_fabw7")
+
+[node name="Base" type="MeshInstance3D" parent="." unique_id=597805735]
+transform = Transform3D(2, 0, 0, 0, 0, -2, 0, 2, 0, 0, 0, 0)
+mesh = ExtResource("1_mm46a")
+
+[node name="Display" type="MeshInstance3D" parent="." unique_id=1268321578]
+transform = Transform3D(3, 0, 0, 0, 0, -3, 0, 3, 0, -0.004130006, 2.244278, 0.3346749)
+mesh = ExtResource("1_d1utq")
+
+[node name="ScreenViewport" type="SubViewport" parent="Display" unique_id=1731785275]
+disable_3d = true
+size = Vector2i(834, 480)
+
+[node name="ScreenInfo" parent="Display/ScreenViewport" unique_id=907327052 instance=ExtResource("4_ebgc8")]
+script = null
+
+[node name="Floor" parent="." unique_id=527188940 instance=ExtResource("3_dmy1m")]
+transform = Transform3D(12.117, 0, 0, 0, 12.117, 0, 0, 0, 12.117, 0, 0, 0)
+visible = false
+
+[node name="OmniLight3D" type="SpotLight3D" parent="." unique_id=1339528342]
+transform = Transform3D(1, 0, 0, 0, -0.9653816, 0.26084167, 0, -0.26084167, -0.9653816, 0, 2.1330748, 0.46361876)
+light_color = Color(0.3137255, 0.32941177, 0.76862746, 1)
+light_energy = 7.0
+spot_range = 3.25
+spot_angle = 75.0
diff --git a/client/map/tiles/screen/screen_base.res b/client/map/tiles/screen/screen_base.res
new file mode 100644
index 00000000..885becfe
--- /dev/null
+++ b/client/map/tiles/screen/screen_base.res
Binary files differ
diff --git a/client/map/tiles/screen/screen_display.res b/client/map/tiles/screen/screen_display.res
new file mode 100644
index 00000000..f7e8ee59
--- /dev/null
+++ b/client/map/tiles/screen/screen_display.res
Binary files differ
diff --git a/client/player/particles/effect.gd b/client/map/tiles/screen/screen_model.gd
index 1b221248..9f63fc3f 100644
--- a/client/player/particles/effect.gd
+++ b/client/map/tiles/screen/screen_model.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -13,24 +13,13 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
-class_name Effect
extends Node3D
+class_name ScreenModel
-@onready var success = $Success
-@onready var failure = $Failure
-@onready var angry_grunt: PlayRandom = $AngryGrunt
-@onready var stars = $Stars
-@onready var angry = $Angry
+func set_server_context(server_context: Game.ServerContext) -> void:
+ if server_context.motd == null:
+ $Display/ScreenViewport/ScreenInfo/MarginContainer/VBoxContainer/RichTextLabel.text = "[font_size=48][b]%s[/b]" % server_context.name
+ else:
+ $Display/ScreenViewport/ScreenInfo/MarginContainer/VBoxContainer/RichTextLabel.text = """[font_size=48][b]%s[/b]
-
-func set_effect(e: String):
- match e:
- "satisfied":
- stars.emitting = true
- success.play()
- "angry":
- angry.emitting = true
- angry_grunt.play_random()
- failure.play()
- _:
- push_warning("effect %s unknown" % e)
+%s[/font_size]""" % [server_context.name, server_context.motd]
diff --git a/client/map/tiles/screen/screen_model.gd.uid b/client/map/tiles/screen/screen_model.gd.uid
new file mode 100644
index 00000000..6a2a81b0
--- /dev/null
+++ b/client/map/tiles/screen/screen_model.gd.uid
@@ -0,0 +1 @@
+uid://cye7akcsp46cv
diff --git a/client/map/tiles/sink.gd b/client/map/tiles/sink.gd
index 055cc353..4f9fffdf 100644
--- a/client/map/tiles/sink.gd
+++ b/client/map/tiles/sink.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -14,7 +14,7 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
class_name Sink
-extends Counter
+extends CounterLike
var particles: SinkParticles = preload("res://map/tiles/sink_particles.tscn").instantiate()
var running: AudioStreamPlayer3D = AudioStreamPlayer3D.new()
diff --git a/client/map/tiles/sink.res b/client/map/tiles/sink.res
index dc8b2f8d..6ac27f7d 100644
--- a/client/map/tiles/sink.res
+++ b/client/map/tiles/sink.res
Binary files differ
diff --git a/client/map/tiles/sink.tscn b/client/map/tiles/sink.tscn
index 887a6a86..d2c85160 100644
--- a/client/map/tiles/sink.tscn
+++ b/client/map/tiles/sink.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://pxa0p42ojyg1"]
+[gd_scene format=3 uid="uid://pxa0p42ojyg1"]
[ext_resource type="ArrayMesh" uid="uid://bibdbxyp15njt" path="res://map/tiles/sink.res" id="1_w6v3o"]
-[node name="Sink" type="Node3D"]
+[node name="Sink" type="Node3D" unique_id=1560247840]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1377464037]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_w6v3o")
-skeleton = NodePath("")
diff --git a/client/map/tiles/sink_backsplash.res b/client/map/tiles/sink_backsplash.res
index a1bec8c2..5a7577a1 100644
--- a/client/map/tiles/sink_backsplash.res
+++ b/client/map/tiles/sink_backsplash.res
Binary files differ
diff --git a/client/map/tiles/sink_backsplash.tscn b/client/map/tiles/sink_backsplash.tscn
index 8154023c..632603a3 100644
--- a/client/map/tiles/sink_backsplash.tscn
+++ b/client/map/tiles/sink_backsplash.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://ctwkcro4c528y"]
+[gd_scene format=3 uid="uid://ctwkcro4c528y"]
[ext_resource type="ArrayMesh" uid="uid://rlvhl2hknvf6" path="res://map/tiles/sink_backsplash.res" id="1_bwi78"]
-[node name="Sink" type="Node3D"]
+[node name="Sink" type="Node3D" unique_id=921333855]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1099590544]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_bwi78")
-skeleton = NodePath("")
diff --git a/client/map/tiles/sink_particles.gd b/client/map/tiles/sink_particles.gd
index 415b1d64..6674c21d 100644
--- a/client/map/tiles/sink_particles.gd
+++ b/client/map/tiles/sink_particles.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/tiles/sink_particles.tscn b/client/map/tiles/sink_particles.tscn
index 6d655c45..2543d59c 100644
--- a/client/map/tiles/sink_particles.tscn
+++ b/client/map/tiles/sink_particles.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=8 format=3 uid="uid://ckxtlgx7hg368"]
+[gd_scene format=3 uid="uid://ckxtlgx7hg368"]
[ext_resource type="Script" uid="uid://bmk30s2yv3j05" path="res://map/tiles/sink_particles.gd" id="1_vh7ox"]
@@ -26,10 +26,10 @@ height = 0.1
_data = [Vector2(0.264045, 0), 0.0, 0.0, 0, 0, Vector2(0.460674, 1), 0.0, 0.0, 0, 0, Vector2(0.949438, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
point_count = 4
-[node name="SinkParticles" type="Node3D"]
+[node name="SinkParticles" type="Node3D" unique_id=974890413]
script = ExtResource("1_vh7ox")
-[node name="Stream" type="CPUParticles3D" parent="."]
+[node name="Stream" type="CPUParticles3D" parent="." unique_id=685739412]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.75, -0.05)
emitting = false
amount = 10
@@ -41,7 +41,7 @@ initial_velocity_min = 0.1
initial_velocity_max = 0.3
color_ramp = SubResource("Gradient_p7a7b")
-[node name="Bubbles" type="CPUParticles3D" parent="."]
+[node name="Bubbles" type="CPUParticles3D" parent="." unique_id=2070218564]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.55, 0)
emitting = false
amount = 30
diff --git a/client/map/tiles/steak_crate.gd b/client/map/tiles/steak_crate.gd
deleted file mode 100644
index df3d8154..00000000
--- a/client/map/tiles/steak_crate.gd
+++ /dev/null
@@ -1,21 +0,0 @@
-# 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 <https://www.gnu.org/licenses/>.
-#
-class_name SteakCrate
-extends Crate
-
-func _init(ctx: TileFactory.TileCC):
- super(ctx)
- base.add_child(load("res://map/tiles/steak_crate.tscn").instantiate())
diff --git a/client/map/tiles/steak_crate.gd.uid b/client/map/tiles/steak_crate.gd.uid
deleted file mode 100644
index 40de1785..00000000
--- a/client/map/tiles/steak_crate.gd.uid
+++ /dev/null
@@ -1 +0,0 @@
-uid://cgjeokxei2o1d
diff --git a/client/map/tiles/steak_crate.res b/client/map/tiles/steak_crate.res
index afb91ff5..0fe078bf 100644
--- a/client/map/tiles/steak_crate.res
+++ b/client/map/tiles/steak_crate.res
Binary files differ
diff --git a/client/map/tiles/steak_crate.tscn b/client/map/tiles/steak_crate.tscn
index 985dcfdd..48bc48dc 100644
--- a/client/map/tiles/steak_crate.tscn
+++ b/client/map/tiles/steak_crate.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://cyi73ubyehy37"]
+[gd_scene format=3 uid="uid://cyi73ubyehy37"]
[ext_resource type="ArrayMesh" uid="uid://bdsqnesyjl3kv" path="res://map/tiles/steak_crate.res" id="1_ewp50"]
-[node name="SteakCrate" type="Node3D"]
+[node name="SteakCrate" type="Node3D" unique_id=766152255]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=432520379]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_ewp50")
-skeleton = NodePath("")
diff --git a/client/map/tiles/stove.gd b/client/map/tiles/stove.gd
index d305da8c..13ae2c7e 100644
--- a/client/map/tiles/stove.gd
+++ b/client/map/tiles/stove.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -14,11 +14,11 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
class_name Stove
-extends Counter
+extends CounterLike
func _init(ctx: TileFactory.TileCC):
super(ctx)
base.add_child(load("res://map/tiles/stove.tscn").instantiate())
-static func interact_target() -> Vector3:
+static func interact_target(): # -> Vector3?
return Vector3(0., 0.625, 0.)
diff --git a/client/map/tiles/stove.res b/client/map/tiles/stove.res
index 5008a897..4b4de9aa 100644
--- a/client/map/tiles/stove.res
+++ b/client/map/tiles/stove.res
Binary files differ
diff --git a/client/map/tiles/stove.tscn b/client/map/tiles/stove.tscn
index c47b9a55..85c1c477 100644
--- a/client/map/tiles/stove.tscn
+++ b/client/map/tiles/stove.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://gns51upjpuaf"]
+[gd_scene format=3 uid="uid://gns51upjpuaf"]
[ext_resource type="ArrayMesh" uid="uid://b343sdfdwvqne" path="res://map/tiles/stove.res" id="1_dpdf3"]
-[node name="Stove" type="Node3D"]
+[node name="Stove" type="Node3D" unique_id=1168423898]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1617771593]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_dpdf3")
-skeleton = NodePath("")
diff --git a/client/map/tiles/strawberry_crate.gd b/client/map/tiles/strawberry_crate.gd
deleted file mode 100644
index cf941df2..00000000
--- a/client/map/tiles/strawberry_crate.gd
+++ /dev/null
@@ -1,21 +0,0 @@
-# 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 <https://www.gnu.org/licenses/>.
-#
-class_name StrawberryCrate
-extends Crate
-
-func _init(ctx: TileFactory.TileCC):
- super(ctx)
- base.add_child(load("res://map/tiles/strawberry_crate.tscn").instantiate())
diff --git a/client/map/tiles/strawberry_crate.gd.uid b/client/map/tiles/strawberry_crate.gd.uid
deleted file mode 100644
index 70f4ef4e..00000000
--- a/client/map/tiles/strawberry_crate.gd.uid
+++ /dev/null
@@ -1 +0,0 @@
-uid://bc8jd34nankae
diff --git a/client/map/tiles/strawberry_crate.tscn b/client/map/tiles/strawberry_crate.tscn
index 070323b6..0e85a59d 100644
--- a/client/map/tiles/strawberry_crate.tscn
+++ b/client/map/tiles/strawberry_crate.tscn
@@ -1,21 +1,21 @@
-[gd_scene load_steps=3 format=3 uid="uid://disox718eydry"]
+[gd_scene format=3 uid="uid://disox718eydry"]
[ext_resource type="PackedScene" uid="uid://xdui0oya4lpb" path="res://map/tiles/crate.tscn" id="1_j8iml"]
[ext_resource type="PackedScene" uid="uid://df1xktleeqg3m" path="res://map/items/strawberry.tscn" id="3_pv4co"]
-[node name="StrawberryCrate" instance=ExtResource("1_j8iml")]
+[node name="StrawberryCrate" unique_id=824564931 instance=ExtResource("1_j8iml")]
-[node name="Strawberry" parent="." index="1" instance=ExtResource("3_pv4co")]
+[node name="Strawberry" parent="." index="1" unique_id=1554090960 instance=ExtResource("3_pv4co")]
transform = Transform3D(0.450462, -0.749695, 0.48481, 0.857167, 0.515038, 0, -0.249695, 0.415563, 0.87462, 0.280431, 0.2, -0.249977)
-[node name="Strawberry2" parent="." index="2" instance=ExtResource("3_pv4co")]
+[node name="Strawberry2" parent="." index="2" unique_id=605451216 instance=ExtResource("3_pv4co")]
transform = Transform3D(0.514594, -0.856429, -0.0415094, 0.857167, 0.515038, 0, 0.0213789, -0.0355805, 0.999138, 0.304305, 0.2, 0.224393)
-[node name="Strawberry3" parent="." index="3" instance=ExtResource("3_pv4co")]
+[node name="Strawberry3" parent="." index="3" unique_id=1846780345 instance=ExtResource("3_pv4co")]
transform = Transform3D(0.333174, -0.941988, -0.0406744, 0.942623, 0.333757, -0.00828417, 0.0213789, -0.0355805, 0.999138, 0.0704219, 0.2, 0.0109546)
-[node name="Strawberry4" parent="." index="4" instance=ExtResource("3_pv4co")]
+[node name="Strawberry4" parent="." index="4" unique_id=711548062 instance=ExtResource("3_pv4co")]
transform = Transform3D(-0.06674, -0.173859, -0.982506, 0.976472, -0.213751, -0.0285059, -0.205055, -0.961293, 0.184035, -0.181014, 0.232884, -0.103933)
-[node name="Strawberry5" parent="." index="5" instance=ExtResource("3_pv4co")]
+[node name="Strawberry5" parent="." index="5" unique_id=50238983 instance=ExtResource("3_pv4co")]
transform = Transform3D(-0.0250969, -0.243938, 0.969466, 0.976472, -0.213751, -0.0285059, 0.214178, 0.945941, 0.243563, -0.181014, 0.232884, 0.0976371)
diff --git a/client/map/tiles/street.gd b/client/map/tiles/street.gd
index 38fb61f4..1ed21111 100644
--- a/client/map/tiles/street.gd
+++ b/client/map/tiles/street.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/tiles/street.res b/client/map/tiles/street.res
index 13da376b..5edd49a2 100644
--- a/client/map/tiles/street.res
+++ b/client/map/tiles/street.res
Binary files differ
diff --git a/client/map/tiles/street.tscn b/client/map/tiles/street.tscn
index 4200c4ab..435f93ff 100644
--- a/client/map/tiles/street.tscn
+++ b/client/map/tiles/street.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://dhdu8gbrhj6wy"]
+[gd_scene format=3 uid="uid://dhdu8gbrhj6wy"]
[ext_resource type="ArrayMesh" uid="uid://bamfsa38y0o20" path="res://map/tiles/street.res" id="1_h0wov"]
-[node name="Street" type="Node3D"]
+[node name="Street" type="Node3D" unique_id=846434626]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=308299248]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, -0.3, 0)
mesh = ExtResource("1_h0wov")
-skeleton = NodePath("")
diff --git a/client/map/tiles/table.gd b/client/map/tiles/table.gd
index 43e3dbea..4fe10323 100644
--- a/client/map/tiles/table.gd
+++ b/client/map/tiles/table.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -14,11 +14,11 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
class_name Table
-extends Floor
+extends Tile
func _init(ctx: TileFactory.TileCC):
super(ctx)
base.add_child(load("res://map/tiles/table.tscn").instantiate())
-static func interact_target() -> Vector3:
+static func interact_target(): # -> Vector3?
return Vector3(0., .5, 0.)
diff --git a/client/map/tiles/table.res b/client/map/tiles/table.res
index 0e4f0fa9..ed98d026 100644
--- a/client/map/tiles/table.res
+++ b/client/map/tiles/table.res
Binary files differ
diff --git a/client/map/tiles/table.tscn b/client/map/tiles/table.tscn
index 96efc7eb..a0d9155d 100644
--- a/client/map/tiles/table.tscn
+++ b/client/map/tiles/table.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://ctuxsfv7rcqb4"]
+[gd_scene format=3 uid="uid://ctuxsfv7rcqb4"]
[ext_resource type="ArrayMesh" uid="uid://caf1m4egynwvn" path="res://map/tiles/table.res" id="1_ycvmt"]
-[node name="Table" type="Node3D"]
+[node name="Table" type="Node3D" unique_id=1328090581]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1607758610]
mesh = ExtResource("1_ycvmt")
-skeleton = NodePath("")
diff --git a/client/map/tiles/tile.gd b/client/map/tiles/tile.gd
index 9d4d732e..df7aa38d 100644
--- a/client/map/tiles/tile.gd
+++ b/client/map/tiles/tile.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -32,32 +32,42 @@ func _init(ctx: TileFactory.TileCC):
base.name = "Base"
base.position += Vector3(0.5, 0, 0.5)
add_child(base)
- self.name = str(ctx.position)
+ self.name = ctx.tile_name.raw_name
var item_base_ = Node3D.new()
# this method is supposed to be overriden
@warning_ignore("static_called_on_instance")
- item_base_.position = interact_target()
+
+ var item_base_pos = interact_target()
+ if item_base_pos == null:
+ if ctx.below_tile_instances.is_empty():
+ item_base_pos = Vector3.ZERO
+ else:
+ item_base_pos = ctx.below_tile_instances[-1].item_base.position
+ item_base_.position = item_base_pos
item_base_.name = "ItemBase"
base.add_child(item_base_)
item_base = item_base_
+
base_mesh = get_base_mesh()
if base_mesh != null:
var m: Node3D = base_mesh
m.position += Vector3(0.5, 0, 0.5)
add_child(m)
+ if not ctx.below_tile_instances.is_empty():
+ base.rotation.y = ctx.below_tile_instances[-1].base.rotation.y
func turn_facing(facing: Facing):
base.rotation.y = facing * 0.5 * PI + PI
# defines where items go when interacting
-static func interact_target() -> Vector3:
- return Vector3(0, 0, 0)
+static func interact_target(): #-> Vector3?
+ return null
# actions when interacting, e.g. animations
func interact():
pass
-func progress(position_: float, speed: float, warn: bool, _acting_player):
+func progress(position_: float, speed: float, warn: bool, _acting_players: Array[Player]):
if item != null:
item.progress(position_, speed, warn)
@@ -94,3 +104,9 @@ func take_item() -> Item:
func get_base_mesh():
return null
+
+# Called when about to be changed to different tile
+# returning false deletes the tile and replaces it normally
+# returning true means this function applies the change
+func change(_name: String) -> bool:
+ return false
diff --git a/client/map/tiles/tomato_crate.gd b/client/map/tiles/tomato_crate.gd
deleted file mode 100644
index 29b8e3a5..00000000
--- a/client/map/tiles/tomato_crate.gd
+++ /dev/null
@@ -1,21 +0,0 @@
-# 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 <https://www.gnu.org/licenses/>.
-#
-class_name TomatoCrate
-extends Crate
-
-func _init(ctx: TileFactory.TileCC):
- super(ctx)
- base.add_child(load("res://map/tiles/tomato_crate.tscn").instantiate())
diff --git a/client/map/tiles/tomato_crate.gd.uid b/client/map/tiles/tomato_crate.gd.uid
deleted file mode 100644
index fcdce7a8..00000000
--- a/client/map/tiles/tomato_crate.gd.uid
+++ /dev/null
@@ -1 +0,0 @@
-uid://chvydto06s4qk
diff --git a/client/map/tiles/tomato_crate.res b/client/map/tiles/tomato_crate.res
index 4490208b..e5add892 100644
--- a/client/map/tiles/tomato_crate.res
+++ b/client/map/tiles/tomato_crate.res
Binary files differ
diff --git a/client/map/tiles/tomato_crate.tscn b/client/map/tiles/tomato_crate.tscn
index 999a9017..2730983c 100644
--- a/client/map/tiles/tomato_crate.tscn
+++ b/client/map/tiles/tomato_crate.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://div5vbcn10yv8"]
+[gd_scene format=3 uid="uid://div5vbcn10yv8"]
[ext_resource type="ArrayMesh" uid="uid://ycxehic1fe7x" path="res://map/tiles/tomato_crate.res" id="1_2nsw8"]
-[node name="TomatoCrate" type="Node3D"]
+[node name="TomatoCrate" type="Node3D" unique_id=210851246]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1201079374]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_2nsw8")
-skeleton = NodePath("")
diff --git a/client/map/tiles/trash.gd b/client/map/tiles/trash.gd
index 14ef9ad2..68e7f7d1 100644
--- a/client/map/tiles/trash.gd
+++ b/client/map/tiles/trash.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -14,7 +14,7 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
class_name Trash
-extends Crate
+extends CounterLike
func _init(ctx: TileFactory.TileCC):
super(ctx)
diff --git a/client/map/tiles/trash.res b/client/map/tiles/trash.res
index 925af56e..131a8f74 100644
--- a/client/map/tiles/trash.res
+++ b/client/map/tiles/trash.res
Binary files differ
diff --git a/client/map/tiles/trash.tscn b/client/map/tiles/trash.tscn
index f1458277..f07e53dc 100644
--- a/client/map/tiles/trash.tscn
+++ b/client/map/tiles/trash.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://dab8capc4hhks"]
+[gd_scene format=3 uid="uid://dab8capc4hhks"]
[ext_resource type="ArrayMesh" uid="uid://b5jcsnrkaqnsu" path="res://map/tiles/trash.res" id="1_w302o"]
-[node name="Crate" type="Node3D"]
+[node name="Crate" type="Node3D" unique_id=1478036191]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=710606675]
mesh = ExtResource("1_w302o")
-skeleton = NodePath("")
diff --git a/client/map/tiles/tree/bark.tres b/client/map/tiles/tree/bark.tres
index 3a6e8a04..01d9dd89 100644
--- a/client/map/tiles/tree/bark.tres
+++ b/client/map/tiles/tree/bark.tres
@@ -1,4 +1,4 @@
-[gd_resource type="StandardMaterial3D" load_steps=3 format=3 uid="uid://beyncaufbtoay"]
+[gd_resource type="StandardMaterial3D" format=3 uid="uid://beyncaufbtoay"]
[ext_resource type="Texture2D" uid="uid://bgh74bmrp46qc" path="res://map/tiles/tree/bark.webp" id="1_3mn2u"]
[ext_resource type="Texture2D" uid="uid://bmvab6kdyccm4" path="res://map/tiles/tree/bark_normal.webp" id="2_v3ray"]
diff --git a/client/map/tiles/tree/leaves.tres b/client/map/tiles/tree/leaves.tres
index ad1b14e9..4347214f 100644
--- a/client/map/tiles/tree/leaves.tres
+++ b/client/map/tiles/tree/leaves.tres
@@ -1,10 +1,12 @@
-[gd_resource type="StandardMaterial3D" load_steps=2 format=3 uid="uid://bwkrkt2cb0wa"]
+[gd_resource type="StandardMaterial3D" format=3 uid="uid://bwkrkt2cb0wa"]
[ext_resource type="Texture2D" uid="uid://bxxh66na6bumt" path="res://map/tiles/tree/leaves.webp" id="1_jg4r8"]
[resource]
resource_name = "NormalTree_Leaves"
-transparency = 4
+transparency = 2
+alpha_scissor_threshold = 0.5
+alpha_antialiasing_mode = 0
albedo_texture = ExtResource("1_jg4r8")
metallic_specular = 0.0
distance_fade_min_distance = 2.0
diff --git a/client/map/tiles/tree/leaves_1_hq.res b/client/map/tiles/tree/leaves_1_hq.res
index 776aab86..e73c0414 100644
--- a/client/map/tiles/tree/leaves_1_hq.res
+++ b/client/map/tiles/tree/leaves_1_hq.res
Binary files differ
diff --git a/client/map/tiles/tree/leaves_1_lq.res b/client/map/tiles/tree/leaves_1_lq.res
index b701536a..29ff9170 100644
--- a/client/map/tiles/tree/leaves_1_lq.res
+++ b/client/map/tiles/tree/leaves_1_lq.res
Binary files differ
diff --git a/client/map/tiles/tree/leaves_2_hq.res b/client/map/tiles/tree/leaves_2_hq.res
index ce83d2f1..dd544faf 100644
--- a/client/map/tiles/tree/leaves_2_hq.res
+++ b/client/map/tiles/tree/leaves_2_hq.res
Binary files differ
diff --git a/client/map/tiles/tree/leaves_2_lq.res b/client/map/tiles/tree/leaves_2_lq.res
index 5064b2bb..f01221d4 100644
--- a/client/map/tiles/tree/leaves_2_lq.res
+++ b/client/map/tiles/tree/leaves_2_lq.res
Binary files differ
diff --git a/client/map/tiles/tree/leaves_3_hq.res b/client/map/tiles/tree/leaves_3_hq.res
index fef80645..528d5a0d 100644
--- a/client/map/tiles/tree/leaves_3_hq.res
+++ b/client/map/tiles/tree/leaves_3_hq.res
Binary files differ
diff --git a/client/map/tiles/tree/leaves_3_lq.res b/client/map/tiles/tree/leaves_3_lq.res
index 108f9120..0888c744 100644
--- a/client/map/tiles/tree/leaves_3_lq.res
+++ b/client/map/tiles/tree/leaves_3_lq.res
Binary files differ
diff --git a/client/map/tiles/tree/leaves_4_hq.res b/client/map/tiles/tree/leaves_4_hq.res
index e0657993..9c9cbec4 100644
--- a/client/map/tiles/tree/leaves_4_hq.res
+++ b/client/map/tiles/tree/leaves_4_hq.res
Binary files differ
diff --git a/client/map/tiles/tree/leaves_4_lq.res b/client/map/tiles/tree/leaves_4_lq.res
index 156b18e2..6b0d9b45 100644
--- a/client/map/tiles/tree/leaves_4_lq.res
+++ b/client/map/tiles/tree/leaves_4_lq.res
Binary files differ
diff --git a/client/map/tiles/tree/leaves_5_hq.res b/client/map/tiles/tree/leaves_5_hq.res
index 63839358..11005d72 100644
--- a/client/map/tiles/tree/leaves_5_hq.res
+++ b/client/map/tiles/tree/leaves_5_hq.res
Binary files differ
diff --git a/client/map/tiles/tree/leaves_5_lq.res b/client/map/tiles/tree/leaves_5_lq.res
index 4ed6ae0e..d265681b 100644
--- a/client/map/tiles/tree/leaves_5_lq.res
+++ b/client/map/tiles/tree/leaves_5_lq.res
Binary files differ
diff --git a/client/map/tiles/tree/leaves_lq.res b/client/map/tiles/tree/leaves_lq.res
index 3b5b5549..ae8e6713 100644
--- a/client/map/tiles/tree/leaves_lq.res
+++ b/client/map/tiles/tree/leaves_lq.res
Binary files differ
diff --git a/client/map/tiles/tree/trunk_1.res b/client/map/tiles/tree/trunk_1.res
index abdbc3ab..2cade494 100644
--- a/client/map/tiles/tree/trunk_1.res
+++ b/client/map/tiles/tree/trunk_1.res
Binary files differ
diff --git a/client/map/tiles/tree/trunk_2.res b/client/map/tiles/tree/trunk_2.res
index 2a66054f..058b8bd5 100644
--- a/client/map/tiles/tree/trunk_2.res
+++ b/client/map/tiles/tree/trunk_2.res
Binary files differ
diff --git a/client/map/tiles/tree/trunk_3.res b/client/map/tiles/tree/trunk_3.res
index 02cb6023..aa61effd 100644
--- a/client/map/tiles/tree/trunk_3.res
+++ b/client/map/tiles/tree/trunk_3.res
Binary files differ
diff --git a/client/map/tiles/tree/trunk_4.res b/client/map/tiles/tree/trunk_4.res
index 87c47b25..a015328d 100644
--- a/client/map/tiles/tree/trunk_4.res
+++ b/client/map/tiles/tree/trunk_4.res
Binary files differ
diff --git a/client/map/tiles/tree/trunk_5.res b/client/map/tiles/tree/trunk_5.res
index 82722415..cf5a5111 100644
--- a/client/map/tiles/tree/trunk_5.res
+++ b/client/map/tiles/tree/trunk_5.res
Binary files differ
diff --git a/client/map/items/lettuce_crate.gd b/client/map/tiles/unknown_tile.gd
index 2a0ff5a5..aa6eee79 100644
--- a/client/map/items/lettuce_crate.gd
+++ b/client/map/tiles/unknown_tile.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -13,9 +13,13 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
-class_name LettuceCrate
-extends Crate
+class_name UnknownTile
+extends Tile
func _init(ctx: TileFactory.TileCC):
super(ctx)
- base.add_child(load("res://map/tiles/lettuce_crate.tscn").instantiate())
+ var label = Label3D.new()
+ label.text = ctx.tile_name.name
+ label.position.y = 0.5
+ label.billboard = BaseMaterial3D.BILLBOARD_ENABLED
+ item_base.add_child(label)
diff --git a/client/map/tiles/unknown_tile.gd.uid b/client/map/tiles/unknown_tile.gd.uid
new file mode 100644
index 00000000..3c331921
--- /dev/null
+++ b/client/map/tiles/unknown_tile.gd.uid
@@ -0,0 +1 @@
+uid://l154vna0x8de
diff --git a/client/map/tiles/wall.gd b/client/map/tiles/wall.gd
index 25289635..1c14de11 100644
--- a/client/map/tiles/wall.gd
+++ b/client/map/tiles/wall.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/map/tiles/wall_corner.res b/client/map/tiles/wall_corner.res
index f232815a..5a76913d 100644
--- a/client/map/tiles/wall_corner.res
+++ b/client/map/tiles/wall_corner.res
Binary files differ
diff --git a/client/map/tiles/wall_corner.tscn b/client/map/tiles/wall_corner.tscn
index a158a119..c79b718e 100644
--- a/client/map/tiles/wall_corner.tscn
+++ b/client/map/tiles/wall_corner.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://ooke2w0txqvo"]
+[gd_scene format=3 uid="uid://ooke2w0txqvo"]
[ext_resource type="ArrayMesh" uid="uid://bjhbhom37qena" path="res://map/tiles/wall_corner.res" id="1_8v0wt"]
-[node name="Wall" type="Node3D"]
+[node name="Wall" type="Node3D" unique_id=170493502]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1971348054]
transform = Transform3D(-2.18557e-08, 0, 0.5, 0, 0.5, 0, -0.5, 0, -2.18557e-08, 0, 0, 0)
mesh = ExtResource("1_8v0wt")
-skeleton = NodePath("")
diff --git a/client/map/tiles/wall_cross.res b/client/map/tiles/wall_cross.res
index d23f908d..4a2ce34e 100644
--- a/client/map/tiles/wall_cross.res
+++ b/client/map/tiles/wall_cross.res
Binary files differ
diff --git a/client/map/tiles/wall_cross.tscn b/client/map/tiles/wall_cross.tscn
index 15a8b24a..b10838b2 100644
--- a/client/map/tiles/wall_cross.tscn
+++ b/client/map/tiles/wall_cross.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://37s417kannw"]
+[gd_scene format=3 uid="uid://37s417kannw"]
[ext_resource type="ArrayMesh" uid="uid://csy08a5uaejvm" path="res://map/tiles/wall_cross.res" id="1_cq25f"]
-[node name="WallCross" type="Node3D"]
+[node name="WallCross" type="Node3D" unique_id=480226603]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=635719470]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_cq25f")
-skeleton = NodePath("")
diff --git a/client/map/tiles/wall_straight.res b/client/map/tiles/wall_straight.res
index 61e00eea..587f0e63 100644
--- a/client/map/tiles/wall_straight.res
+++ b/client/map/tiles/wall_straight.res
Binary files differ
diff --git a/client/map/tiles/wall_straight.tscn b/client/map/tiles/wall_straight.tscn
index 0de536b8..0c9ca066 100644
--- a/client/map/tiles/wall_straight.tscn
+++ b/client/map/tiles/wall_straight.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://tx8anusdso4j"]
+[gd_scene format=3 uid="uid://tx8anusdso4j"]
[ext_resource type="ArrayMesh" uid="uid://sxg6np20cvs2" path="res://map/tiles/wall_straight.res" id="1_stsuc"]
-[node name="Wall" type="Node3D"]
+[node name="Wall" type="Node3D" unique_id=1493672826]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=2012998439]
transform = Transform3D(-2.18557e-08, 0, 0.5, 0, 0.5, 0, -0.5, 0, -2.18557e-08, 0, 0, 0)
mesh = ExtResource("1_stsuc")
-skeleton = NodePath("")
diff --git a/client/map/tiles/wall_t.res b/client/map/tiles/wall_t.res
index 5de79639..84776fb8 100644
--- a/client/map/tiles/wall_t.res
+++ b/client/map/tiles/wall_t.res
Binary files differ
diff --git a/client/map/tiles/wall_t.tscn b/client/map/tiles/wall_t.tscn
index 9d390517..b8fd430c 100644
--- a/client/map/tiles/wall_t.tscn
+++ b/client/map/tiles/wall_t.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://canjwc3qoprsp"]
+[gd_scene format=3 uid="uid://canjwc3qoprsp"]
[ext_resource type="ArrayMesh" uid="uid://bysasgavbv1mj" path="res://map/tiles/wall_t.res" id="1_sb5lc"]
-[node name="Wall" type="Node3D"]
+[node name="Wall" type="Node3D" unique_id=1440368655]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=836503802]
transform = Transform3D(5.96244e-09, 0, -0.5, 0, 0.5, 0, 0.5, 0, 5.96244e-09, 0, 0, 0)
mesh = ExtResource("1_sb5lc")
-skeleton = NodePath("")
diff --git a/client/map/tiles/wall_tile.gd b/client/map/tiles/wall_tile.gd
index 390a4bfb..01522609 100644
--- a/client/map/tiles/wall_tile.gd
+++ b/client/map/tiles/wall_tile.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -14,7 +14,7 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
class_name WallTile
-extends Floor
+extends Tile
static func create_material(color: Color):
var mat = StandardMaterial3D.new()
@@ -31,8 +31,8 @@ const WALLS: Array = [
"wall",
"wall-window",
"counter-window",
+ "counter-window-conveyor",
"door",
- "fence"
]
var walls: Array = WALLS
@@ -56,8 +56,8 @@ func _init(ctx: TileFactory.TileCC):
for start in range(4):
var series = 0
for i in range(4):
- var i_name = ctx.neighbors[(start + i) % 4]
- if is_wall(i_name):
+ var neighbor: Array = ctx.neighbors[(start + i) % 4]
+ if is_wall(neighbor):
series += 1
else:
break
@@ -68,7 +68,7 @@ func _init(ctx: TileFactory.TileCC):
if max_series == 1:
facing = max_idx
kind = WallKind.STRAIGHT
- if not env.is_empty() and env.has(ctx.neighbors[(facing + 1) % 4]) or ctx.neighbors[(facing + 1) % 4] == null:
+ if not env.is_empty() and G.has_one(env, ctx.neighbors[(facing + 1) % 4]) or ctx.neighbors[(facing + 1) % 4].is_empty():
facing = (facing + 2) % 4
elif max_series == 2:
facing = max_idx
@@ -86,5 +86,5 @@ func add_dyed_mesh(ctx: TileFactory.TileCC, node: Node3D, node_name = "Mesh", su
meshi.set_surface_override_material(surface, MATERIALS.get(ctx.tile_name.variant, MATERIALS["green"]))
base.add_child(node)
-func is_wall(tile_name_t) -> bool:
- return walls.has(tile_name_t)
+func is_wall(neighbor: Array) -> bool:
+ return G.has_one(neighbor, walls)
diff --git a/client/map/tiles/window.gd b/client/map/tiles/window.gd
index da0963ed..9f8670a7 100644
--- a/client/map/tiles/window.gd
+++ b/client/map/tiles/window.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -16,7 +16,7 @@
class_name WallWindow
extends WallTile
-static func interact_target() -> Vector3:
+static func interact_target(): # -> Vector3?
return Vector3(0, 0.625, 0)
func _init(ctx: TileFactory.TileCC):
diff --git a/client/map/tiles/window.res b/client/map/tiles/window.res
index b2ff56f0..f685d179 100644
--- a/client/map/tiles/window.res
+++ b/client/map/tiles/window.res
Binary files differ
diff --git a/client/map/tiles/window.tscn b/client/map/tiles/window.tscn
index b2db9c74..d086bc13 100644
--- a/client/map/tiles/window.tscn
+++ b/client/map/tiles/window.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://mn0avehv0qtt"]
+[gd_scene format=3 uid="uid://mn0avehv0qtt"]
[ext_resource type="ArrayMesh" uid="uid://ce60y0y6dqypp" path="res://map/tiles/window.res" id="1_ek3mj"]
-[node name="Window" type="Node3D"]
+[node name="Window" type="Node3D" unique_id=1268337780]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=753789933]
transform = Transform3D(-2.18557e-08, 0, 0.5, 0, 0.5, 0, -0.5, 0, -2.18557e-08, 0, 0, 0)
mesh = ExtResource("1_ek3mj")
-skeleton = NodePath("")
diff --git a/client/message_parser.gd b/client/message_parser.gd
new file mode 100644
index 00000000..c7ef2e1a
--- /dev/null
+++ b/client/message_parser.gd
@@ -0,0 +1,71 @@
+# Hurry Curry! - a game about cooking
+# Copyright (C) 2026 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 <https://www.gnu.org/licenses/>.
+#
+class_name MessageParser
+extends Object
+
+var raw: Dictionary
+var kind := Kind.UNKNOWN
+var result
+var game: Game
+
+enum Kind {
+ ITEM,
+ TILE,
+ TEXT,
+ TRANSLATION,
+ UNKNOWN
+}
+
+func _init(raw_: Dictionary, game_: Game) -> void:
+ raw = raw_
+ game = game_
+ if "text" in raw:
+ kind = Kind.TEXT
+ result = raw["text"]
+ elif "translation" in raw:
+ kind = Kind.TRANSLATION
+ # TODO: move function here
+ var params: Array = raw.translation.params.map(MessageParser.new.bind(game))
+ var unformatted := tr(raw.translation.id)
+ result = split_translation(unformatted, 0, params)
+ if result.size() == 1 && result[0].kind == Kind.TEXT:
+ kind = Kind.TEXT
+ result = result[0].result
+ elif "tile" in raw:
+ kind = Kind.TILE
+ result = game.tile_names[raw["tile"]]
+ elif "item" in raw:
+ kind = Kind.ITEM
+ result = game.item_names[raw["item"]]
+
+func split_translation(msgstr: String, idx: int, params: Array) -> Array:
+ if msgstr.contains("{%d}" % idx):
+ var s := msgstr.split("{%d}" % idx, true, 1)
+ var l := split_translation(s[0], idx + 1, params)
+ if params[idx].kind == Kind.TRANSLATION:
+ l.append_array(params[idx].result)
+ else:
+ l.push_back(params[idx])
+ var r := split_translation(s[1], idx + 1, params)
+ l.append_array(r)
+ var res := [l.front()]
+ for e: MessageParser in l.slice(1):
+ if res.back().kind == Kind.TEXT and e.kind == Kind.TEXT:
+ res.back().result = "%s%s" % [res.back().result, e.result]
+ else:
+ res.push_back(e)
+ return res
+ else: return [] if msgstr.is_empty() else [MessageParser.new({"text": msgstr}, game)]
diff --git a/client/message_parser.gd.uid b/client/message_parser.gd.uid
new file mode 100644
index 00000000..6959eee9
--- /dev/null
+++ b/client/message_parser.gd.uid
@@ -0,0 +1 @@
+uid://bmmtfaxe2qbcv
diff --git a/client/multiplayer.gd b/client/multiplayer.gd
index e8747995..9bd735fa 100644
--- a/client/multiplayer.gd
+++ b/client/multiplayer.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -19,23 +19,70 @@ extends Node
signal packet(packet: Dictionary)
signal connection_closed()
-static var VERSION_MAJOR: int = 11
+static var VERSION_MAJOR: int = 13
static var VERSION_MINOR: int = 0
var connected := false
-var socket := WebSocketPeer.new()
+var socket: WebSocketPeer
+var keep_alive := Timer.new()
func _ready():
- print("Multiplayer connect");
- socket.inbound_buffer_size = 1024 * 1024 * 4
+ add_child(keep_alive)
+ keep_alive.wait_time = 1.
+ keep_alive.timeout.connect(send_keep_alive)
-func connect_to_url(url):
- socket.connect_to_url(url)
+func connect_to_urls(urls: Array[String]):
+ if urls.is_empty():
+ connection_closed.emit("No connection address available.")
+ return
+
+ var error_info: Dictionary[String, int] = {}
+
+ # Create a WebSocketPeer for each url
+ var peers: Array[WebSocketPeer] = []
+ for url: String in urls:
+ var ws := WebSocketPeer.new()
+ ws.inbound_buffer_size = 1024 * 1024 * 4
+ var err := ws.connect_to_url(url)
+ if err == OK: peers.append(ws)
+ else: error_info[url] = err
+
+ # Now keep polling until one of them is succesful, or we run out of peers.
+ # Peers are removed from the peers array when they fail to connect.
+ var open_peer_found := false
+ while not peers.is_empty() and not open_peer_found:
+ await get_tree().physics_frame
+ for peer: WebSocketPeer in peers:
+ peer.poll()
+ var state := peer.get_ready_state()
+ match state:
+ WebSocketPeer.STATE_CLOSED:
+ print("URL %s failed" % peer.get_requested_url())
+ error_info[peer.get_requested_url()] = peer.get_close_code()
+ peers.erase(peer)
+ WebSocketPeer.STATE_OPEN:
+ # We found a connection that works. Close all others.
+ print("URL %s connected!" % peer.get_requested_url())
+ socket = peer
+ var other_peers := peers.filter(func (p): return p != peer)
+ for p: WebSocketPeer in other_peers:
+ p.close()
+ open_peer_found = true
+ break
+ _: pass
+
+ if not open_peer_found:
+ var err_msg: String = tr("c.error.could_not_connect")
+ for url: String in error_info.keys():
+ err_msg += "\nURL %s failed with code %d" % [url, error_info[url]]
+ connection_closed.emit(err_msg)
+ return
+
connected = true
+ keep_alive.start()
func _notification(what):
- if what == NOTIFICATION_PREDELETE:
- print("Multiplayer disconnect");
+ if what == NOTIFICATION_PREDELETE and socket != null:
socket.close()
connected = false
@@ -43,34 +90,29 @@ func _process(_delta):
if connected:
socket.poll()
var state = socket.get_ready_state()
- if state == WebSocketPeer.STATE_OPEN:
- while socket.get_available_packet_count():
- handle_packet(socket.get_packet())
- elif state == WebSocketPeer.STATE_CLOSED:
- var code = socket.get_close_code()
- var reason = socket.get_close_reason() if code == socket.STATE_CLOSED else tr("c.error.websocket.unavailable")
- connection_closed.emit(tr("c.error.websocket").format([code, reason, code != -1]))
- self.queue_free()
+ while socket.get_available_packet_count():
+ handle_packet(socket.get_packet())
+ if state == WebSocketPeer.STATE_CLOSED:
+ connection_closed.emit("c.error.connection_closed")
+ connected = false
-func fix_packet_types(val):
+func fix_packet_types(val: Variant):
match typeof(val):
TYPE_FLOAT: return val
TYPE_STRING: return val
TYPE_BOOL: return val
TYPE_ARRAY: return val.map(fix_packet_types)
TYPE_DICTIONARY:
- var newval = {}
+ var new_dict = {}
for k in val.keys():
- if typeof(val[k]) == TYPE_ARRAY and val[k].size() == 2 and typeof(val[k][0]) == TYPE_FLOAT and typeof(val[k][1]) == TYPE_FLOAT:
- if k in ["tile"]: newval[k] = Vector2i(val[k][0], val[k][1])
- elif k in ["pos", "position"]: newval[k] = Vector2(val[k][0], val[k][1])
- else: newval[k] = val[k]
- # TODO reenable when fixed
- # elif k in ["player", "id"] and typeof(val[k]) == TYPE_FLOAT:
- # newval[k] = int(val[k])
- else:
- newval[k] = fix_packet_types(val[k])
- return newval
+ if val[k] is Array and val[k].size() == 2:
+ # A Vector2 is represented as an array with 2 elements in our protocol.
+ # We need to convert it to Godot's Vector2 type for easier handling.
+ if k in ["tile"]: new_dict[k] = Vector2i(val[k][0], val[k][1]) # TODO: Are these still necessary?
+ elif k in ["pos", "position", "dir"]: new_dict[k] = Vector2(val[k][0], val[k][1])
+ else: new_dict[k] = fix_packet_types(val[k])
+ else: new_dict[k] = fix_packet_types(val[k])
+ return new_dict
func handle_packet(coded):
var p = decode_packet(coded)
@@ -104,18 +146,25 @@ func send_movement(player, pos: Vector2, direction: Vector2, boost: bool):
"dir": [direction.x, direction.y],
"boost": boost
})
+
func send_tile_interact(player, pos: Vector2i, edge: bool, hand: int):
@warning_ignore("incompatible_ternary")
send_packet({
"type": "interact",
"player": player,
+ "target": {"tile": [pos.x, pos.y]} if edge else null,
"hand": hand,
- "pos": [pos.x, pos.y] if edge else null,
})
-func send_player_interact(_player, _edge: bool):
- push_error("not yet implemented")
+func send_player_interact(player, target_player, target_hand: int, edge: bool, hand: int):
+ @warning_ignore("incompatible_ternary")
+ send_packet({
+ "type": "interact",
+ "player": player,
+ "target": {"player": [target_player, target_hand]} if edge else null,
+ "hand": hand,
+ })
func send_chat(player, message: String):
send_packet({
@@ -150,8 +199,31 @@ func send_ready():
"type": "ready"
})
+func send_start_game_vote(player_id: float, map: String, hand_count = 1, bots = []):
+ var config := {
+ "map": map
+ }
+ if hand_count != null: config["hand_count"] = hand_count
+ if bots != null: config["bots"] = bots
+ send_packet({
+ "type": "initiate_vote",
+ "player": player_id,
+ "subject": {
+ "action": "start_game",
+ "config": config
+ }
+ })
+
+func send_keep_alive() -> void:
+ send_packet({
+ "type": "keepalive"
+ })
+
func send_packet(p):
var json = JSON.stringify(p)
+ if socket.get_ready_state() != WebSocketPeer.State.STATE_OPEN:
+ push_warning("Can not send packet: Socket not open")
+ return
socket.send_text(json)
func decode_packet(bytes: PackedByteArray):
diff --git a/client/multiplayer.tscn b/client/multiplayer.tscn
deleted file mode 100644
index cb181ad2..00000000
--- a/client/multiplayer.tscn
+++ /dev/null
@@ -1,6 +0,0 @@
-[gd_scene load_steps=2 format=3 uid="uid://b0sibwbndh7jp"]
-
-[ext_resource type="Script" uid="uid://dgyxsaqaq33sw" path="res://multiplayer.gd" id="1_xinpa"]
-
-[node name="Multiplayer" type="Node"]
-script = ExtResource("1_xinpa")
diff --git a/client/player/camera_recorder.gd b/client/player/camera_recorder.gd
index 8f398c2b..896666e9 100644
--- a/client/player/camera_recorder.gd
+++ b/client/player/camera_recorder.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -25,7 +25,9 @@ var time = 0.
var keyframes = [] # Array<[float, Transform3D]>
func _ready() -> void:
- if record and replay: return push_error("concurrent ecord and replay is not supported")
+ if Cli.opts.has("record-camera"): record = true; recording_path = Cli.opts["record-camera"]
+ if Cli.opts.has("replay-camera"): replay = true; recording_path = Cli.opts["replay-camera"]
+ if record and replay: return push_error("concurrent record and replay is not supported")
if replay: load_recording()
func _exit_tree() -> void:
@@ -80,7 +82,7 @@ func parse_transform(s: String) -> Transform3D:
func _process(dt: float):
if Global.game_paused: return
- time += dt
+ time += dt * float(Cli.opts.get("timescale", "1"))
if record: keyframes.push_back([time, camera.global_transform, camera.fov])
if replay:
var index = keyframes.bsearch_custom([time], func (a, b): return a[0] < b[0])
diff --git a/client/player/character/character.gd b/client/player/character/character.gd
index 14a66930..262ffa22 100644
--- a/client/player/character/character.gd
+++ b/client/player/character/character.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/player/character/character.tscn b/client/player/character/character.tscn
index 748cdaed..a38652c5 100644
--- a/client/player/character/character.tscn
+++ b/client/player/character/character.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=27 format=3 uid="uid://b3hhir2fvnunu"]
+[gd_scene format=3 uid="uid://b3hhir2fvnunu"]
[ext_resource type="Script" uid="uid://dwk3vd4nv2k65" path="res://player/character/character.gd" id="1_12lbh"]
[ext_resource type="ArrayMesh" uid="uid://bnmm01yjwultj" path="res://player/character/default/main.res" id="2_uovyg"]
@@ -601,312 +601,312 @@ tracks/11/keys = {
"times": PackedFloat32Array(0, 0.75, 1.5)
}
-[sub_resource type="Animation" id="Animation_7kiho"]
-resource_name = "walk"
-length = 0.4
+[sub_resource type="Animation" id="Animation_01ngc"]
+resource_name = "roll"
loop_mode = 1
-step = 0.05
+step = 0.01
tracks/0/type = "bezier"
tracks/0/imported = false
tracks/0/enabled = true
-tracks/0/path = NodePath("Main/HandLeft:position:x")
+tracks/0/path = NodePath("Main/HandRight:position:x")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
-"handle_modes": PackedInt32Array(1, 1, 0, 1, 0),
-"points": PackedFloat32Array(1.302, 0, 0, 0, 0, 1.302, 0, 0, 0, 0, 1.302, 0, 0, 0, 0, 1.302, 0, 0, 0, 0, 1.302, 0, 0, 0, 0),
-"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4)
+"handle_modes": PackedInt32Array(0, 0, 0),
+"points": PackedFloat32Array(-1, -0.125, 0, 0.125, 0, -1, -0.083333336, 0, 0, 0, -1, -0.125, 0, 0.125, 0),
+"times": PackedFloat32Array(0, 0.5, 1)
}
tracks/1/type = "bezier"
tracks/1/imported = false
tracks/1/enabled = true
-tracks/1/path = NodePath("Main/HandLeft:position:y")
+tracks/1/path = NodePath("Main/HandRight:position:y")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
-"handle_modes": PackedInt32Array(1, 1, 0, 1, 0),
-"points": PackedFloat32Array(-0.17, 0, 0, 0, 0, -0.17, 0, 0, 0, 0, -0.17, 0, 0, 0, 0, -0.17, 0, 0, 0, 0, -0.17, 0, 0, 0, 0),
-"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4)
+"handle_modes": PackedInt32Array(0, 0, 0),
+"points": PackedFloat32Array(1, -0.125, 0, 0.125, 0, 1, -0.083333336, 0, 0, 0, 1, -0.125, 0, 0.125, 0),
+"times": PackedFloat32Array(0, 0.5, 1)
}
tracks/2/type = "bezier"
tracks/2/imported = false
tracks/2/enabled = true
-tracks/2/path = NodePath("Main/HandLeft:position:z")
+tracks/2/path = NodePath("Main/HandRight:position:z")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
-"handle_modes": PackedInt32Array(1, 1, 0, 1, 0),
-"points": PackedFloat32Array(0, 0, 0, 0, 0, 0.25, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.25, 0, 0, 0, 0, 0, 0, 0, 0, 0),
-"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4)
+"handle_modes": PackedInt32Array(0, 0, 0),
+"points": PackedFloat32Array(1, -0.125, 0, 0.125, 0, 2, -0.2, 0, 0.2, 0, 1, -0.125, 0, 0.125, 0),
+"times": PackedFloat32Array(0, 0.5, 1)
}
tracks/3/type = "bezier"
tracks/3/imported = false
tracks/3/enabled = true
-tracks/3/path = NodePath("Main/HandLeft:rotation:x")
+tracks/3/path = NodePath("Main/HandRight:rotation:x")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
-"handle_modes": PackedInt32Array(1, 1, 0, 1, 0),
-"points": PackedFloat32Array(4.14408e-16, 0, 0, 0, 0, 0.436332, 0, 0, 0, 0, 4.14408e-16, 0, 0, 0, 0, -0.436332, 0, 0, 0, 0, 4.14408e-16, 0, 0, 0, 0),
-"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4)
+"handle_modes": PackedInt32Array(0),
+"points": PackedFloat32Array(0, -0.125, 0, 0.125, 0),
+"times": PackedFloat32Array(0)
}
tracks/4/type = "bezier"
tracks/4/imported = false
tracks/4/enabled = true
-tracks/4/path = NodePath("Main/HandLeft:rotation:y")
+tracks/4/path = NodePath("Main/HandRight:rotation:y")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/keys = {
-"handle_modes": PackedInt32Array(1, 1, 0, 1, 0),
-"points": PackedFloat32Array(3.14159, 0, 0, 0, 0, 3.14159, 0, 0, 0, 0, 3.14159, 0, 0, 0, 0, 3.14159, 0, 0, 0, 0, 3.14159, 0, 0, 0, 0),
-"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4)
+"handle_modes": PackedInt32Array(0),
+"points": PackedFloat32Array(-2.0943952, -0.125, 0, 0.125, 0),
+"times": PackedFloat32Array(0)
}
tracks/5/type = "bezier"
tracks/5/imported = false
tracks/5/enabled = true
-tracks/5/path = NodePath("Main/HandLeft:rotation:z")
+tracks/5/path = NodePath("Main/HandRight:rotation:z")
tracks/5/interp = 1
tracks/5/loop_wrap = true
tracks/5/keys = {
-"handle_modes": PackedInt32Array(1, 1, 0, 1, 0),
-"points": PackedFloat32Array(-2.0944, 0, 0, 0, 0, -2.0944, 0, 0, 0, 0, -2.0944, 0, 0, 0, 0, -2.0944, 0, 0, 0, 0, -2.0944, 0, 0, 0, 0),
-"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4)
+"handle_modes": PackedInt32Array(0),
+"points": PackedFloat32Array(-3.1415927, -0.125, 0, 0.125, 0),
+"times": PackedFloat32Array(0)
}
tracks/6/type = "bezier"
tracks/6/imported = false
tracks/6/enabled = true
-tracks/6/path = NodePath("Main/HandRight:position:x")
+tracks/6/path = NodePath("Main/HandLeft:position:x")
tracks/6/interp = 1
tracks/6/loop_wrap = true
tracks/6/keys = {
-"handle_modes": PackedInt32Array(1, 1, 0, 1, 0),
-"points": PackedFloat32Array(-1.302, 0, 0, 0, 0, -1.302, 0, 0, 0, 0, -1.302, 0, 0, 0, 0, -1.302, 0, 0, 0, 0, -1.302, 0, 0, 0, 0),
-"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4)
+"handle_modes": PackedInt32Array(0, 2, 0),
+"points": PackedFloat32Array(1, -0.125, 0, 0.125, 0, 1, -0.083333336, 0, 0, 0, 1, -0.125, 0, 0.125, 0),
+"times": PackedFloat32Array(0, 0.5, 1)
}
tracks/7/type = "bezier"
tracks/7/imported = false
tracks/7/enabled = true
-tracks/7/path = NodePath("Main/HandRight:position:y")
+tracks/7/path = NodePath("Main/HandLeft:position:y")
tracks/7/interp = 1
tracks/7/loop_wrap = true
tracks/7/keys = {
-"handle_modes": PackedInt32Array(1, 1, 0, 1, 0),
-"points": PackedFloat32Array(-0.17, 0, 0, 0, 0, -0.17, 0, 0, 0, 0, -0.17, 0, 0, 0, 0, -0.17, 0, 0, 0, 0, -0.17, 0, 0, 0, 0),
-"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4)
+"handle_modes": PackedInt32Array(0, 2, 0),
+"points": PackedFloat32Array(1, -0.125, 0, 0.125, 0, 1, -0.083333336, 0, 0, 0, 1, -0.125, 0, 0.125, 0),
+"times": PackedFloat32Array(0, 0.5, 1)
}
tracks/8/type = "bezier"
tracks/8/imported = false
tracks/8/enabled = true
-tracks/8/path = NodePath("Main/HandRight:position:z")
+tracks/8/path = NodePath("Main/HandLeft:position:z")
tracks/8/interp = 1
tracks/8/loop_wrap = true
tracks/8/keys = {
-"handle_modes": PackedInt32Array(1, 1, 0, 1, 0),
-"points": PackedFloat32Array(0, 0, 0, 0, 0, -0.25, 0, 0, 0, 0, -7.09899e-06, 0, 0, 0, 0, 0.25, 0, 0, 0, 0, 0, 0, 0, 0, 0),
-"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4)
+"handle_modes": PackedInt32Array(0, 2, 0),
+"points": PackedFloat32Array(1, -0.125, 0, 0.125, 0, 2, -0.2, 0, 0.2, 0, 1, -0.125, 0, 0.125, 0),
+"times": PackedFloat32Array(0, 0.5, 1)
}
tracks/9/type = "bezier"
tracks/9/imported = false
tracks/9/enabled = true
-tracks/9/path = NodePath("Main/HandRight:rotation:x")
+tracks/9/path = NodePath("Main/HandLeft:rotation:x")
tracks/9/interp = 1
tracks/9/loop_wrap = true
tracks/9/keys = {
-"handle_modes": PackedInt32Array(1, 1, 0, 1, 0),
-"points": PackedFloat32Array(-0.628319, 0, 0, 0, 0, -1.06465, 0, 0, 0, 0, -0.628331, 0, 0, 0, 0, -0.191986, 0, 0, 0, 0, -0.628319, 0, 0, 0, 0),
-"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4)
+"handle_modes": PackedInt32Array(0),
+"points": PackedFloat32Array(0, -0.125, 0, 0.125, 0),
+"times": PackedFloat32Array(0)
}
tracks/10/type = "bezier"
tracks/10/imported = false
tracks/10/enabled = true
-tracks/10/path = NodePath("Main/HandRight:rotation:y")
+tracks/10/path = NodePath("Main/HandLeft:rotation:y")
tracks/10/interp = 1
tracks/10/loop_wrap = true
tracks/10/keys = {
-"handle_modes": PackedInt32Array(1, 1, 0, 1, 0),
-"points": PackedFloat32Array(-3.14159, 0, 0, 0, 0, -3.14159, 0, 0, 0, 0, -3.14159, 0, 0, 0, 0, -3.14159, 0, 0, 0, 0, -3.14159, 0, 0, 0, 0),
-"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4)
+"handle_modes": PackedInt32Array(0),
+"points": PackedFloat32Array(1.3962634, -0.125, 0, 0.125, 0),
+"times": PackedFloat32Array(0)
}
tracks/11/type = "bezier"
tracks/11/imported = false
tracks/11/enabled = true
-tracks/11/path = NodePath("Main/HandRight:rotation:z")
+tracks/11/path = NodePath("Main/HandLeft:rotation:z")
tracks/11/interp = 1
tracks/11/loop_wrap = true
tracks/11/keys = {
-"handle_modes": PackedInt32Array(1, 1, 0, 1, 0),
-"points": PackedFloat32Array(2.0944, 0, 0, 0, 0, 2.0944, 0, 0, 0, 0, 2.0944, 0, 0, 0, 0, 2.0944, 0, 0, 0, 0, 2.0944, 0, 0, 0, 0),
-"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4)
+"handle_modes": PackedInt32Array(0),
+"points": PackedFloat32Array(-3.1415927, -0.125, 0, 0.125, 0),
+"times": PackedFloat32Array(0)
+}
+tracks/12/type = "bezier"
+tracks/12/imported = false
+tracks/12/enabled = true
+tracks/12/path = NodePath("Main/RollingPin:position:x")
+tracks/12/interp = 1
+tracks/12/loop_wrap = true
+tracks/12/keys = {
+"handle_modes": PackedInt32Array(0, 2, 0),
+"points": PackedFloat32Array(0, -0.125, 0, 0.125, 0, 0, -0.083333336, 0, 0, 0, 0, -0.125, 0, 0.125, 0),
+"times": PackedFloat32Array(0, 0.5, 1)
+}
+tracks/13/type = "bezier"
+tracks/13/imported = false
+tracks/13/enabled = true
+tracks/13/path = NodePath("Main/RollingPin:position:y")
+tracks/13/interp = 1
+tracks/13/loop_wrap = true
+tracks/13/keys = {
+"handle_modes": PackedInt32Array(0, 2, 0),
+"points": PackedFloat32Array(1, -0.125, 0, 0.125, 0, 1, -0.083333336, 0, 0, 0, 1, -0.125, 0, 0.125, 0),
+"times": PackedFloat32Array(0, 0.5, 1)
+}
+tracks/14/type = "bezier"
+tracks/14/imported = false
+tracks/14/enabled = true
+tracks/14/path = NodePath("Main/RollingPin:position:z")
+tracks/14/interp = 1
+tracks/14/loop_wrap = true
+tracks/14/keys = {
+"handle_modes": PackedInt32Array(0, 2, 0),
+"points": PackedFloat32Array(1, -0.125, 0, 0.125, 0, 2, -0.2, 0, 0.2, 0, 1, -0.125, 0, 0.125, 0),
+"times": PackedFloat32Array(0, 0.5, 1)
}
-[sub_resource type="Animation" id="Animation_01ngc"]
-resource_name = "roll"
+[sub_resource type="Animation" id="Animation_7kiho"]
+resource_name = "walk"
+length = 0.4
loop_mode = 1
-step = 0.01
+step = 0.05
tracks/0/type = "bezier"
tracks/0/imported = false
tracks/0/enabled = true
-tracks/0/path = NodePath("Main/HandRight:position:x")
+tracks/0/path = NodePath("Main/HandLeft:position:x")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
-"handle_modes": PackedInt32Array(0, 0, 0),
-"points": PackedFloat32Array(-1, -0.125, 0, 0.125, 0, -1, -0.083333336, 0, 0, 0, -1, -0.125, 0, 0.125, 0),
-"times": PackedFloat32Array(0, 0.5, 1)
+"handle_modes": PackedInt32Array(1, 1, 0, 1, 0),
+"points": PackedFloat32Array(1.302, 0, 0, 0, 0, 1.302, 0, 0, 0, 0, 1.302, 0, 0, 0, 0, 1.302, 0, 0, 0, 0, 1.302, 0, 0, 0, 0),
+"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4)
}
tracks/1/type = "bezier"
tracks/1/imported = false
tracks/1/enabled = true
-tracks/1/path = NodePath("Main/HandRight:position:y")
+tracks/1/path = NodePath("Main/HandLeft:position:y")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
-"handle_modes": PackedInt32Array(0, 0, 0),
-"points": PackedFloat32Array(1, -0.125, 0, 0.125, 0, 1, -0.083333336, 0, 0, 0, 1, -0.125, 0, 0.125, 0),
-"times": PackedFloat32Array(0, 0.5, 1)
+"handle_modes": PackedInt32Array(1, 1, 0, 1, 0),
+"points": PackedFloat32Array(-0.17, 0, 0, 0, 0, -0.17, 0, 0, 0, 0, -0.17, 0, 0, 0, 0, -0.17, 0, 0, 0, 0, -0.17, 0, 0, 0, 0),
+"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4)
}
tracks/2/type = "bezier"
tracks/2/imported = false
tracks/2/enabled = true
-tracks/2/path = NodePath("Main/HandRight:position:z")
+tracks/2/path = NodePath("Main/HandLeft:position:z")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
-"handle_modes": PackedInt32Array(0, 0, 0),
-"points": PackedFloat32Array(1, -0.125, 0, 0.125, 0, 2, -0.2, 0, 0.2, 0, 1, -0.125, 0, 0.125, 0),
-"times": PackedFloat32Array(0, 0.5, 1)
+"handle_modes": PackedInt32Array(1, 1, 0, 1, 0),
+"points": PackedFloat32Array(0, 0, 0, 0, 0, 0.25, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.25, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4)
}
tracks/3/type = "bezier"
tracks/3/imported = false
tracks/3/enabled = true
-tracks/3/path = NodePath("Main/HandRight:rotation:x")
+tracks/3/path = NodePath("Main/HandLeft:rotation:x")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
-"handle_modes": PackedInt32Array(0),
-"points": PackedFloat32Array(0, -0.125, 0, 0.125, 0),
-"times": PackedFloat32Array(0)
+"handle_modes": PackedInt32Array(1, 1, 0, 1, 0),
+"points": PackedFloat32Array(4.14408e-16, 0, 0, 0, 0, 0.436332, 0, 0, 0, 0, 4.14408e-16, 0, 0, 0, 0, -0.436332, 0, 0, 0, 0, 4.14408e-16, 0, 0, 0, 0),
+"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4)
}
tracks/4/type = "bezier"
tracks/4/imported = false
tracks/4/enabled = true
-tracks/4/path = NodePath("Main/HandRight:rotation:y")
+tracks/4/path = NodePath("Main/HandLeft:rotation:y")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/keys = {
-"handle_modes": PackedInt32Array(0),
-"points": PackedFloat32Array(-2.0943952, -0.125, 0, 0.125, 0),
-"times": PackedFloat32Array(0)
+"handle_modes": PackedInt32Array(1, 1, 0, 1, 0),
+"points": PackedFloat32Array(3.14159, 0, 0, 0, 0, 3.14159, 0, 0, 0, 0, 3.14159, 0, 0, 0, 0, 3.14159, 0, 0, 0, 0, 3.14159, 0, 0, 0, 0),
+"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4)
}
tracks/5/type = "bezier"
tracks/5/imported = false
tracks/5/enabled = true
-tracks/5/path = NodePath("Main/HandRight:rotation:z")
+tracks/5/path = NodePath("Main/HandLeft:rotation:z")
tracks/5/interp = 1
tracks/5/loop_wrap = true
tracks/5/keys = {
-"handle_modes": PackedInt32Array(0),
-"points": PackedFloat32Array(-3.1415927, -0.125, 0, 0.125, 0),
-"times": PackedFloat32Array(0)
+"handle_modes": PackedInt32Array(1, 1, 0, 1, 0),
+"points": PackedFloat32Array(-2.0944, 0, 0, 0, 0, -2.0944, 0, 0, 0, 0, -2.0944, 0, 0, 0, 0, -2.0944, 0, 0, 0, 0, -2.0944, 0, 0, 0, 0),
+"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4)
}
tracks/6/type = "bezier"
tracks/6/imported = false
tracks/6/enabled = true
-tracks/6/path = NodePath("Main/HandLeft:position:x")
+tracks/6/path = NodePath("Main/HandRight:position:x")
tracks/6/interp = 1
tracks/6/loop_wrap = true
tracks/6/keys = {
-"handle_modes": PackedInt32Array(0, 2, 0),
-"points": PackedFloat32Array(1, -0.125, 0, 0.125, 0, 1, -0.083333336, 0, 0, 0, 1, -0.125, 0, 0.125, 0),
-"times": PackedFloat32Array(0, 0.5, 1)
+"handle_modes": PackedInt32Array(1, 1, 0, 1, 0),
+"points": PackedFloat32Array(-1.302, 0, 0, 0, 0, -1.302, 0, 0, 0, 0, -1.302, 0, 0, 0, 0, -1.302, 0, 0, 0, 0, -1.302, 0, 0, 0, 0),
+"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4)
}
tracks/7/type = "bezier"
tracks/7/imported = false
tracks/7/enabled = true
-tracks/7/path = NodePath("Main/HandLeft:position:y")
+tracks/7/path = NodePath("Main/HandRight:position:y")
tracks/7/interp = 1
tracks/7/loop_wrap = true
tracks/7/keys = {
-"handle_modes": PackedInt32Array(0, 2, 0),
-"points": PackedFloat32Array(1, -0.125, 0, 0.125, 0, 1, -0.083333336, 0, 0, 0, 1, -0.125, 0, 0.125, 0),
-"times": PackedFloat32Array(0, 0.5, 1)
+"handle_modes": PackedInt32Array(1, 1, 0, 1, 0),
+"points": PackedFloat32Array(-0.17, 0, 0, 0, 0, -0.17, 0, 0, 0, 0, -0.17, 0, 0, 0, 0, -0.17, 0, 0, 0, 0, -0.17, 0, 0, 0, 0),
+"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4)
}
tracks/8/type = "bezier"
tracks/8/imported = false
tracks/8/enabled = true
-tracks/8/path = NodePath("Main/HandLeft:position:z")
+tracks/8/path = NodePath("Main/HandRight:position:z")
tracks/8/interp = 1
tracks/8/loop_wrap = true
tracks/8/keys = {
-"handle_modes": PackedInt32Array(0, 2, 0),
-"points": PackedFloat32Array(1, -0.125, 0, 0.125, 0, 2, -0.2, 0, 0.2, 0, 1, -0.125, 0, 0.125, 0),
-"times": PackedFloat32Array(0, 0.5, 1)
+"handle_modes": PackedInt32Array(1, 1, 0, 1, 0),
+"points": PackedFloat32Array(0, 0, 0, 0, 0, -0.25, 0, 0, 0, 0, -7.09899e-06, 0, 0, 0, 0, 0.25, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4)
}
tracks/9/type = "bezier"
tracks/9/imported = false
tracks/9/enabled = true
-tracks/9/path = NodePath("Main/HandLeft:rotation:x")
+tracks/9/path = NodePath("Main/HandRight:rotation:x")
tracks/9/interp = 1
tracks/9/loop_wrap = true
tracks/9/keys = {
-"handle_modes": PackedInt32Array(0),
-"points": PackedFloat32Array(0, -0.125, 0, 0.125, 0),
-"times": PackedFloat32Array(0)
+"handle_modes": PackedInt32Array(1, 1, 0, 1, 0),
+"points": PackedFloat32Array(-0.628319, 0, 0, 0, 0, -1.06465, 0, 0, 0, 0, -0.628331, 0, 0, 0, 0, -0.191986, 0, 0, 0, 0, -0.628319, 0, 0, 0, 0),
+"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4)
}
tracks/10/type = "bezier"
tracks/10/imported = false
tracks/10/enabled = true
-tracks/10/path = NodePath("Main/HandLeft:rotation:y")
+tracks/10/path = NodePath("Main/HandRight:rotation:y")
tracks/10/interp = 1
tracks/10/loop_wrap = true
tracks/10/keys = {
-"handle_modes": PackedInt32Array(0),
-"points": PackedFloat32Array(1.3962634, -0.125, 0, 0.125, 0),
-"times": PackedFloat32Array(0)
+"handle_modes": PackedInt32Array(1, 1, 0, 1, 0),
+"points": PackedFloat32Array(-3.14159, 0, 0, 0, 0, -3.14159, 0, 0, 0, 0, -3.14159, 0, 0, 0, 0, -3.14159, 0, 0, 0, 0, -3.14159, 0, 0, 0, 0),
+"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4)
}
tracks/11/type = "bezier"
tracks/11/imported = false
tracks/11/enabled = true
-tracks/11/path = NodePath("Main/HandLeft:rotation:z")
+tracks/11/path = NodePath("Main/HandRight:rotation:z")
tracks/11/interp = 1
tracks/11/loop_wrap = true
tracks/11/keys = {
-"handle_modes": PackedInt32Array(0),
-"points": PackedFloat32Array(-3.1415927, -0.125, 0, 0.125, 0),
-"times": PackedFloat32Array(0)
-}
-tracks/12/type = "bezier"
-tracks/12/imported = false
-tracks/12/enabled = true
-tracks/12/path = NodePath("Main/RollingPin:position:x")
-tracks/12/interp = 1
-tracks/12/loop_wrap = true
-tracks/12/keys = {
-"handle_modes": PackedInt32Array(0, 2, 0),
-"points": PackedFloat32Array(0, -0.125, 0, 0.125, 0, 0, -0.083333336, 0, 0, 0, 0, -0.125, 0, 0.125, 0),
-"times": PackedFloat32Array(0, 0.5, 1)
-}
-tracks/13/type = "bezier"
-tracks/13/imported = false
-tracks/13/enabled = true
-tracks/13/path = NodePath("Main/RollingPin:position:y")
-tracks/13/interp = 1
-tracks/13/loop_wrap = true
-tracks/13/keys = {
-"handle_modes": PackedInt32Array(0, 2, 0),
-"points": PackedFloat32Array(1, -0.125, 0, 0.125, 0, 1, -0.083333336, 0, 0, 0, 1, -0.125, 0, 0.125, 0),
-"times": PackedFloat32Array(0, 0.5, 1)
-}
-tracks/14/type = "bezier"
-tracks/14/imported = false
-tracks/14/enabled = true
-tracks/14/path = NodePath("Main/RollingPin:position:z")
-tracks/14/interp = 1
-tracks/14/loop_wrap = true
-tracks/14/keys = {
-"handle_modes": PackedInt32Array(0, 2, 0),
-"points": PackedFloat32Array(1, -0.125, 0, 0.125, 0, 2, -0.2, 0, 0.2, 0, 1, -0.125, 0, 0.125, 0),
-"times": PackedFloat32Array(0, 0.5, 1)
+"handle_modes": PackedInt32Array(1, 1, 0, 1, 0),
+"points": PackedFloat32Array(2.0944, 0, 0, 0, 0, 2.0944, 0, 0, 0, 0, 2.0944, 0, 0, 0, 0, 2.0944, 0, 0, 0, 0, 2.0944, 0, 0, 0, 0),
+"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4)
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_xtrfe"]
@@ -929,60 +929,52 @@ height = 0.2
_data = [Vector2(0, 0.054945), 0.0, 0.0, 0, 0, Vector2(0.174157, 1), 0.0, 0.0, 0, 0, Vector2(0.573034, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
point_count = 4
-[node name="Character" type="Node3D"]
+[node name="Character" type="Node3D" unique_id=257669240]
script = ExtResource("1_12lbh")
-[node name="Main" type="MeshInstance3D" parent="."]
+[node name="Main" type="MeshInstance3D" parent="." unique_id=431310873]
transform = Transform3D(0.33, 0, 0, 0, 0.33, 0, 0, 0, 0.33, 0, 0.33, 0)
mesh = ExtResource("2_uovyg")
-skeleton = NodePath("")
surface_material_override/0 = SubResource("StandardMaterial3D_7ojaw")
-[node name="RollingPin" parent="Main" instance=ExtResource("5_kl3lh")]
+[node name="RollingPin" parent="Main" unique_id=1109548085 instance=ExtResource("5_kl3lh")]
transform = Transform3D(3.030303, -1.1268961e-05, -1.5955811e-05, 1.7894663e-05, 0.47404197, 2.992996, -8.746808e-06, -2.992996, 0.47404295, 0, 1, 1)
visible = false
-[node name="HandRight" type="MeshInstance3D" parent="Main"]
+[node name="HandRight" type="MeshInstance3D" parent="Main" unique_id=877421762]
transform = Transform3D(0.28714395, 0.28639996, -1.177853e-06, 0.40235722, -0.13377503, 0.33755422, 0.29232922, -0.09719407, -0.46460304, -1.302, -0.17, 0)
mesh = ExtResource("3_k28vh")
-skeleton = NodePath("")
-[node name="Knife" parent="Main/HandRight" instance=ExtResource("4_tjq3a")]
+[node name="Knife" parent="Main/HandRight" unique_id=919616367 instance=ExtResource("4_tjq3a")]
transform = Transform3D(3.69699, 2.68602, 2.63837, -3.70658, -2.69301, 7.93544, 3.10156, -4.26893, -1.08623e-05, -0.157983, 0.472216, -0.19819)
visible = false
-[node name="HandLeft" type="MeshInstance3D" parent="Main"]
+[node name="HandLeft" type="MeshInstance3D" parent="Main" unique_id=1856363654]
transform = Transform3D(0.2871431, -0.28640002, 1.4559066e-06, -0.49734095, -0.16535497, -2.3798664e-16, 7.2796e-07, -7.2607605e-07, -0.574281, 1.302, -0.17, 0)
mesh = ExtResource("4_tcrm3")
-skeleton = NodePath("")
-[node name="HeadDefault" type="MeshInstance3D" parent="Main"]
+[node name="HeadDefault" type="MeshInstance3D" parent="Main" unique_id=1393186576]
transform = Transform3D(0.75, 0, 0, 0, 0.75, 0, 0, 0, 0.75, 0, 1.25, 0)
mesh = ExtResource("5_n1vl0")
-skeleton = NodePath("")
-[node name="HairMesh" type="MeshInstance3D" parent="Main/HeadDefault"]
+[node name="HairMesh" type="MeshInstance3D" parent="Main/HeadDefault" unique_id=676273220]
transform = Transform3D(1.06667, 0, 0, 0, 1.06667, 0, 0, 0, 1.06667, 0, 0.4, 0)
visible = false
-skeleton = NodePath("")
-[node name="Headwear" type="Node3D" parent="Main/HeadDefault"]
+[node name="Headwear" type="Node3D" parent="Main/HeadDefault" unique_id=666867049]
-[node name="Tie" type="MeshInstance3D" parent="Main"]
+[node name="Tie" type="MeshInstance3D" parent="Main" unique_id=10511655]
transform = Transform3D(0.125, 0, 0, 0, 0.125, 0, 0, 0, 0.125, 0, 0.47772, 0.445265)
mesh = ExtResource("9_kgric")
-skeleton = NodePath("")
-[node name="HeadRobot" parent="Main" instance=ExtResource("10_w8s0d")]
+[node name="HeadRobot" parent="Main" unique_id=536884315 instance=ExtResource("10_w8s0d")]
transform = Transform3D(1.875, 0, 0, 0, 1.25, 0, 0, 0, 1.25, 0, 1.25, 0)
visible = false
-[node name="HandAnimations" type="AnimationPlayer" parent="."]
-libraries = {
-&"": SubResource("AnimationLibrary_xtrfe")
-}
+[node name="HandAnimations" type="AnimationPlayer" parent="." unique_id=1634474082]
+libraries/ = SubResource("AnimationLibrary_xtrfe")
-[node name="Walking" type="CPUParticles3D" parent="."]
+[node name="Walking" type="CPUParticles3D" parent="." unique_id=1367441210]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.2)
emitting = false
amount = 2
@@ -995,7 +987,7 @@ initial_velocity_max = 3.0
scale_amount_min = 0.4
scale_amount_max = 0.75
-[node name="Boosting" type="CPUParticles3D" parent="."]
+[node name="Boosting" type="CPUParticles3D" parent="." unique_id=1067342627]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.2)
emitting = false
amount = 30
@@ -1012,30 +1004,30 @@ scale_amount_min = 0.5
scale_amount_max = 0.75
scale_amount_curve = SubResource("Curve_7ml8g")
-[node name="Steps" type="Node3D" parent="."]
+[node name="Steps" type="Node3D" parent="." unique_id=1520408668]
script = ExtResource("14_3rb6x")
volume_db = -30.0
-[node name="Step1" type="AudioStreamPlayer3D" parent="Steps"]
+[node name="Step1" type="AudioStreamPlayer3D" parent="Steps" unique_id=1552447825]
stream = ExtResource("10_qpd6x")
-[node name="Step2" type="AudioStreamPlayer3D" parent="Steps"]
+[node name="Step2" type="AudioStreamPlayer3D" parent="Steps" unique_id=1044225430]
stream = ExtResource("11_2dmo8")
-[node name="Step3" type="AudioStreamPlayer3D" parent="Steps"]
+[node name="Step3" type="AudioStreamPlayer3D" parent="Steps" unique_id=1134192529]
stream = ExtResource("12_bj5ue")
-[node name="Boosts" type="Node3D" parent="."]
+[node name="Boosts" type="Node3D" parent="." unique_id=87964766]
script = ExtResource("14_3rb6x")
volume_db = -12.0
-[node name="Woosh1" type="AudioStreamPlayer3D" parent="Boosts"]
+[node name="Woosh1" type="AudioStreamPlayer3D" parent="Boosts" unique_id=1239674416]
stream = ExtResource("14_ikcec")
-[node name="Woosh2" type="AudioStreamPlayer3D" parent="Boosts"]
+[node name="Woosh2" type="AudioStreamPlayer3D" parent="Boosts" unique_id=1115799746]
stream = ExtResource("15_iv4wu")
-[node name="Username" type="Label3D" parent="."]
+[node name="Username" type="Label3D" parent="." unique_id=156476575]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.2, 0)
visible = false
billboard = 1
diff --git a/client/player/character/customer_body.res b/client/player/character/customer_body.res
index 33249d24..ec628302 100644
--- a/client/player/character/customer_body.res
+++ b/client/player/character/customer_body.res
Binary files differ
diff --git a/client/player/character/default/hand_left.res b/client/player/character/default/hand_left.res
index 8736dad6..d7e1091d 100644
--- a/client/player/character/default/hand_left.res
+++ b/client/player/character/default/hand_left.res
Binary files differ
diff --git a/client/player/character/default/hand_right.res b/client/player/character/default/hand_right.res
index 44e3683d..8b2a5c1a 100644
--- a/client/player/character/default/hand_right.res
+++ b/client/player/character/default/hand_right.res
Binary files differ
diff --git a/client/player/character/default/head.res b/client/player/character/default/head.res
index 69be33e7..897c9f07 100644
--- a/client/player/character/default/head.res
+++ b/client/player/character/default/head.res
Binary files differ
diff --git a/client/player/character/default/main.res b/client/player/character/default/main.res
index eda8300f..dcdd593f 100644
--- a/client/player/character/default/main.res
+++ b/client/player/character/default/main.res
Binary files differ
diff --git a/client/player/character/default/tie.res b/client/player/character/default/tie.res
index 406a4779..90e8d12d 100644
--- a/client/player/character/default/tie.res
+++ b/client/player/character/default/tie.res
Binary files differ
diff --git a/client/player/character/hairstyles/hair_1.res b/client/player/character/hairstyles/hair_1.res
index bea01119..be0fcd9d 100644
--- a/client/player/character/hairstyles/hair_1.res
+++ b/client/player/character/hairstyles/hair_1.res
Binary files differ
diff --git a/client/player/character/hairstyles/hair_2.res b/client/player/character/hairstyles/hair_2.res
index 5d41a4b5..c8eb1b19 100644
--- a/client/player/character/hairstyles/hair_2.res
+++ b/client/player/character/hairstyles/hair_2.res
Binary files differ
diff --git a/client/player/character/hairstyles/hair_3.res b/client/player/character/hairstyles/hair_3.res
index 911afa30..37421aa8 100644
--- a/client/player/character/hairstyles/hair_3.res
+++ b/client/player/character/hairstyles/hair_3.res
Binary files differ
diff --git a/client/player/character/headwear/cat_ears.gd b/client/player/character/headwear/cat_ears.gd
index e5911005..41c777e7 100644
--- a/client/player/character/headwear/cat_ears.gd
+++ b/client/player/character/headwear/cat_ears.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -16,19 +16,19 @@
class_name CatEars
extends Node3D
-const EAR_ROTATION := deg_to_rad(20.)
+const EAR_ROTATION := deg_to_rad(0.)
var ear_target := 0.
@onready var character: Character = get_parent().get_parent().get_parent().get_parent()
func set_inner_mat(mat: BaseMaterial3D):
- $Left.set_surface_override_material(1, mat)
- $Right.set_surface_override_material(1, mat)
+ $Left/Mesh.set_surface_override_material(1, mat)
+ $Right/Mesh.set_surface_override_material(1, mat)
func set_outer_mat(mat: BaseMaterial3D):
- $Left.set_surface_override_material(0, mat)
- $Right.set_surface_override_material(0, mat)
+ $Left/Mesh.set_surface_override_material(0, mat)
+ $Right/Mesh.set_surface_override_material(0, mat)
func _ready() -> void:
set_inner_mat(character.main.get_active_material(0))
@@ -37,8 +37,8 @@ func _ready() -> void:
var t := 0.
func _process(delta: float) -> void:
if visible:
- $Right.rotation.z = G.interpolate_angle($Right.rotation.z, ear_target + EAR_ROTATION, delta * 10.)
- $Left.rotation.z = G.interpolate_angle($Left.rotation.z, PI + ear_target + EAR_ROTATION, delta * 10.)
+ $Right.rotation.z = G.interpolate_angle($Right.rotation.z, ear_target + EAR_ROTATION, delta * 17.5)
+ $Left.rotation.z = G.interpolate_angle($Left.rotation.z, -ear_target + -EAR_ROTATION, delta * 17.5)
if character.walking:
t += delta
ear_target = sin(t * character.WALK_ANIM_SPEED) * 0.075 if character.walking else 0.
diff --git a/client/player/character/headwear/cat_ears.res b/client/player/character/headwear/cat_ears.res
index ae31fa69..0b5eec24 100644
--- a/client/player/character/headwear/cat_ears.res
+++ b/client/player/character/headwear/cat_ears.res
Binary files differ
diff --git a/client/player/character/headwear/cat_ears.tscn b/client/player/character/headwear/cat_ears.tscn
index 3d611484..e8c14ff2 100644
--- a/client/player/character/headwear/cat_ears.tscn
+++ b/client/player/character/headwear/cat_ears.tscn
@@ -1,17 +1,19 @@
-[gd_scene load_steps=3 format=3 uid="uid://dspkdcg1ui6dl"]
+[gd_scene format=3 uid="uid://dspkdcg1ui6dl"]
[ext_resource type="ArrayMesh" uid="uid://3k87npushfgh" path="res://player/character/headwear/cat_ears.res" id="1_5c3r8"]
[ext_resource type="Script" uid="uid://cyyugv3ylq8ux" path="res://player/character/headwear/cat_ears.gd" id="1_q747p"]
-[node name="CatEars" type="Node3D"]
+[node name="CatEars" type="Node3D" unique_id=984113826]
script = ExtResource("1_q747p")
-[node name="Left" type="MeshInstance3D" parent="."]
-transform = Transform3D(-0.391948, 0.0798526, 2.14072e-08, 0.0798526, 0.391948, 6.34998e-09, 1.97086e-08, -1.04957e-08, 0.4, -0.0100086, 0.361507, 1.20572e-08)
+[node name="Right" type="Node3D" parent="." unique_id=2100889132]
+
+[node name="Mesh" type="MeshInstance3D" parent="Right" unique_id=1124875900]
+transform = Transform3D(0.28284273, -0.28284273, 0, 0.28284273, 0.28284273, 0, 0, 0, 0.4, -0.645, 0.7, 0)
mesh = ExtResource("1_5c3r8")
-skeleton = NodePath("")
-[node name="Right" type="MeshInstance3D" parent="."]
-transform = Transform3D(0.389421, -0.0913844, -2.23025e-08, 0.0913844, 0.389421, 5.89238e-09, 2.03665e-08, -1.08318e-08, 0.4, 0.0104306, 0.370664, 1.26181e-08)
+[node name="Left" type="Node3D" parent="." unique_id=1057112591]
+
+[node name="Mesh" type="MeshInstance3D" parent="Left" unique_id=1314823784]
+transform = Transform3D(0.28284273, 0.28284273, 0, -0.28284273, 0.28284273, 0, 0, 0, 0.4, 0.645, 0.7, 0)
mesh = ExtResource("1_5c3r8")
-skeleton = NodePath("")
diff --git a/client/player/character/headwear/devil_horn.res b/client/player/character/headwear/devil_horn.res
index aab67051..ea55fc46 100644
--- a/client/player/character/headwear/devil_horn.res
+++ b/client/player/character/headwear/devil_horn.res
Binary files differ
diff --git a/client/player/character/headwear/devil_horns.tscn b/client/player/character/headwear/devil_horns.tscn
index d952b480..859f6aa7 100644
--- a/client/player/character/headwear/devil_horns.tscn
+++ b/client/player/character/headwear/devil_horns.tscn
@@ -1,15 +1,13 @@
-[gd_scene load_steps=2 format=3 uid="uid://ciw1ngkslskaw"]
+[gd_scene format=3 uid="uid://ciw1ngkslskaw"]
[ext_resource type="ArrayMesh" uid="uid://mwaobrw3mab4" path="res://player/character/headwear/devil_horn.res" id="1_kadxh"]
-[node name="DevilHorns" type="Node3D"]
+[node name="DevilHorns" type="Node3D" unique_id=997946975]
-[node name="Left" type="MeshInstance3D" parent="."]
+[node name="Left" type="MeshInstance3D" parent="." unique_id=319747709]
transform = Transform3D(-1.74846e-08, -0.16383, -0.172073, 0, 0.114715, -0.245746, 0.4, -7.16125e-09, -7.52155e-09, -0.8, 0.75, 0)
mesh = ExtResource("1_kadxh")
-skeleton = NodePath("")
-[node name="Right" type="MeshInstance3D" parent="."]
+[node name="Right" type="MeshInstance3D" parent="." unique_id=1059260263]
transform = Transform3D(-1.74846e-08, 0.16383, 0.172073, 0, 0.114715, -0.245746, -0.4, -7.16125e-09, -7.52155e-09, 0.8, 0.75, 0)
mesh = ExtResource("1_kadxh")
-skeleton = NodePath("")
diff --git a/client/player/character/headwear/propeller.res b/client/player/character/headwear/propeller.res
index e293561b..3c0c85c8 100644
--- a/client/player/character/headwear/propeller.res
+++ b/client/player/character/headwear/propeller.res
Binary files differ
diff --git a/client/player/character/headwear/propeller_hat.tscn b/client/player/character/headwear/propeller_hat.tscn
index e913da9e..8115cfae 100644
--- a/client/player/character/headwear/propeller_hat.tscn
+++ b/client/player/character/headwear/propeller_hat.tscn
@@ -1,7 +1,7 @@
-[gd_scene load_steps=2 format=3 uid="uid://dd60wq65on6cf"]
+[gd_scene format=3 uid="uid://dd60wq65on6cf"]
[ext_resource type="ArrayMesh" uid="uid://cxftkcxlde6m2" path="res://player/character/headwear/propeller.res" id="1_24m5a"]
-[node name="PropellerHat" type="MeshInstance3D"]
+[node name="PropellerHat" type="MeshInstance3D" unique_id=605936529]
transform = Transform3D(0.3, 0, 0, 0, -1.31134e-08, -0.3, 0, 0.3, -1.31134e-08, 0, 0.165, 0.45)
mesh = ExtResource("1_24m5a")
diff --git a/client/player/character/robot/antenna.res b/client/player/character/robot/antenna.res
index 11416ebf..687ae965 100644
--- a/client/player/character/robot/antenna.res
+++ b/client/player/character/robot/antenna.res
Binary files differ
diff --git a/client/player/character/robot/ears.res b/client/player/character/robot/ears.res
index a41c80e7..8f8f4eb4 100644
--- a/client/player/character/robot/ears.res
+++ b/client/player/character/robot/ears.res
Binary files differ
diff --git a/client/player/character/robot/head.res b/client/player/character/robot/head.res
index d5b1df33..26f38dc0 100644
--- a/client/player/character/robot/head.res
+++ b/client/player/character/robot/head.res
Binary files differ
diff --git a/client/player/character/robot/head.tscn b/client/player/character/robot/head.tscn
index 1684131d..ee0d189b 100644
--- a/client/player/character/robot/head.tscn
+++ b/client/player/character/robot/head.tscn
@@ -1,20 +1,17 @@
-[gd_scene load_steps=4 format=3 uid="uid://c6sqsj7r03qp1"]
+[gd_scene format=3 uid="uid://c6sqsj7r03qp1"]
[ext_resource type="ArrayMesh" uid="uid://b6jg603dkd4ys" path="res://player/character/robot/head.res" id="1_phkuo"]
[ext_resource type="ArrayMesh" uid="uid://d06pr5ahve2ni" path="res://player/character/robot/ears.res" id="2_2lybj"]
[ext_resource type="ArrayMesh" uid="uid://cv86smrevtpid" path="res://player/character/robot/antenna.res" id="3_dmtg5"]
-[node name="Head" type="MeshInstance3D"]
+[node name="Head" type="MeshInstance3D" unique_id=200713535]
transform = Transform3D(1.875, 0, 0, 0, 1.25, 0, 0, 0, 1.25, 0, 2.125, 0)
mesh = ExtResource("1_phkuo")
-skeleton = NodePath("")
-[node name="Ears" type="MeshInstance3D" parent="."]
+[node name="Ears" type="MeshInstance3D" parent="." unique_id=2101182845]
transform = Transform3D(0, 0.533333, 0, -0.24, 0, 0, 0, 0, 0.24, 0, 0, 0)
mesh = ExtResource("2_2lybj")
-skeleton = NodePath("")
-[node name="Antenna" type="MeshInstance3D" parent="."]
+[node name="Antenna" type="MeshInstance3D" parent="." unique_id=544517483]
transform = Transform3D(0.533333, 0, 0, 0, 0.8, 0, 0, 0, 0.8, 0, 0.7, 0)
mesh = ExtResource("3_dmtg5")
-skeleton = NodePath("")
diff --git a/client/player/character/tram/tram.res b/client/player/character/tram/tram.res
index ae423eb9..9457a31e 100644
--- a/client/player/character/tram/tram.res
+++ b/client/player/character/tram/tram.res
Binary files differ
diff --git a/client/player/character/tram/tram.tscn b/client/player/character/tram/tram.tscn
index 0aaedbf4..843b3833 100644
--- a/client/player/character/tram/tram.tscn
+++ b/client/player/character/tram/tram.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=5 format=3 uid="uid://xq5claqewtb3"]
+[gd_scene format=3 uid="uid://xq5claqewtb3"]
[ext_resource type="ArrayMesh" uid="uid://co1ygecaclgaq" path="res://player/character/tram/tram.res" id="1_lw3pl"]
@@ -14,12 +14,11 @@ roughness = 0.07
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_c7y58"]
albedo_color = Color(0.129558, 0.129558, 0.129558, 1)
-[node name="Tram" type="Node3D"]
+[node name="Tram" type="Node3D" unique_id=1034285574]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=965659143]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
mesh = ExtResource("1_lw3pl")
-skeleton = NodePath("")
surface_material_override/0 = SubResource("StandardMaterial3D_eboss")
surface_material_override/1 = SubResource("StandardMaterial3D_36qjs")
surface_material_override/2 = SubResource("StandardMaterial3D_c7y58")
diff --git a/client/player/chat_bubble.gd b/client/player/chat_bubble.gd
index abeacc66..6052eb50 100644
--- a/client/player/chat_bubble.gd
+++ b/client/player/chat_bubble.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/player/chat_bubble.tscn b/client/player/chat_bubble.tscn
index 12bbe3bf..86e4ab25 100644
--- a/client/player/chat_bubble.tscn
+++ b/client/player/chat_bubble.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=6 format=3 uid="uid://cgi6vcfrnqp0i"]
+[gd_scene format=3 uid="uid://cgi6vcfrnqp0i"]
[ext_resource type="Script" uid="uid://cgawpg2ll6vx1" path="res://player/chat_bubble.gd" id="1_4v1cx"]
[ext_resource type="PackedScene" uid="uid://5rcfoyuiwuya" path="res://player/chat_message.tscn" id="2_lyyq0"]
@@ -17,15 +17,15 @@ shading_mode = 0
albedo_texture = SubResource("ViewportTexture_mko8a")
billboard_mode = 1
-[node name="ChatBubble" type="MeshInstance3D"]
+[node name="ChatBubble" type="MeshInstance3D" unique_id=1144632585]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, 0)
mesh = SubResource("QuadMesh_u8lr5")
surface_material_override/0 = SubResource("StandardMaterial3D_5iy0t")
script = ExtResource("1_4v1cx")
-[node name="SubViewport" type="SubViewport" parent="."]
+[node name="SubViewport" type="SubViewport" parent="." unique_id=38120223]
disable_3d = true
transparent_bg = true
size = Vector2i(512, 128)
-[node name="ChatMessage" parent="SubViewport" instance=ExtResource("2_lyyq0")]
+[node name="ChatMessage" parent="SubViewport" unique_id=449750458 instance=ExtResource("2_lyyq0")]
diff --git a/client/player/chat_message.tscn b/client/player/chat_message.tscn
index b91dcba4..97a24896 100644
--- a/client/player/chat_message.tscn
+++ b/client/player/chat_message.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=4 format=3 uid="uid://5rcfoyuiwuya"]
+[gd_scene format=3 uid="uid://5rcfoyuiwuya"]
[ext_resource type="FontFile" uid="uid://5ixo6b3bd3km" path="res://gui/resources/fonts/font-josefin-sans.woff2" id="1_3ximm"]
@@ -13,13 +13,13 @@ corner_radius_bottom_left = 30
base_font = ExtResource("1_3ximm")
variation_embolden = 1.0
-[node name="ChatMessage" type="Panel"]
+[node name="ChatMessage" type="Panel" unique_id=1317312449]
auto_translate_mode = 2
offset_right = 512.0
offset_bottom = 128.0
theme_override_styles/panel = SubResource("StyleBoxFlat_dpele")
-[node name="Label" type="Label" parent="."]
+[node name="Label" type="Label" parent="." unique_id=614164231]
auto_translate_mode = 2
layout_mode = 1
anchors_preset = 15
diff --git a/client/player/controllable_player.gd b/client/player/controllable_player.gd
index 3a64743b..a48892a7 100644
--- a/client/player/controllable_player.gd
+++ b/client/player/controllable_player.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -16,20 +16,37 @@
class_name ControllablePlayer
extends Player
-const PLAYER_SPEED = 55
-const PLAYER_FRICTION = 15
-const BOOST_FACTOR = 2.5
-const BOOST_DURATION = 0.3
-const BOOST_RESTORE = 0.5
+@abstract class InteractTarget:
+ var target_visual_pos: Vector3
+ var target_visual_rot: float
+
+class EmptyTarget extends InteractTarget:
+ pass
+
+class PlayerTarget extends InteractTarget:
+ var player: Player
+ var distance: float
+ func _init(player_: Player, target_visual_pos_: Vector3, target_visual_rot_: float, distance_: float) -> void:
+ player = player_
+ target_visual_pos = target_visual_pos_
+ target_visual_rot = target_visual_rot_
+ distance = distance_
+
+class TileTarget extends InteractTarget:
+ var pos: Vector2i
+ var tile: Tile
+ func _init(pos_: Vector2i, tile_: Tile, target_visual_pos_: Vector3, target_visual_rot_: float) -> void:
+ pos = pos_
+ tile = tile_
+ target_visual_pos = target_visual_pos_
+ target_visual_rot = target_visual_rot_
+
const MAX_PLAYER_INTERACT_DIST := 1.9
var onscreen_controls = preload("res://player/onscreen_controls/controls.tscn").instantiate()
var marker: Marker = preload("res://player/marker/marker.tscn").instantiate()
-var facing := Vector2(1, 0)
-var velocity_ := Vector2(0, 0)
-var direction := Vector2(0, 0)
-var stamina := 0.
+var current_interact_target: InteractTarget = EmptyTarget.new()
var chat_open := false
var input_rotation = 0
@@ -37,42 +54,25 @@ var vibration_timer := Timer.new()
var current_vibration_strength := 0.
var current_vibration_change := 0.
-var target_tile: Vector2i = Vector2i.ZERO
-var target_visual: Vector3 = Vector3.ZERO
-var found_interact_target := false
-
-var last_interaction = null # : Vector2i?
+var was_boosting = boosting
func _ready():
vibration_timer = Timer.new()
vibration_timer.wait_time = 0.1
vibration_timer.timeout.connect(_on_vibration_timeout)
add_child(vibration_timer)
- var timer = Timer.new()
- timer.one_shot = false
- timer.wait_time = 1. / 50.
- add_child(timer)
- timer.start()
- timer.connect("timeout", func():
- if game.mp != null and game.join_state == Game.JoinState.JOINED:
- game.mp.send_movement(game.my_player_id, position_, direction, boosting)
- )
add_child(onscreen_controls)
add_child(marker)
super()
- Settings.hook_changed_init("gameplay.first_person", "hide_head", func(fps):
+ Settings.hook_changed_init("gameplay.first_person", self, func(fps):
character.head_default.visible = not fps
character.username_tag.visible = not fps
)
-const MAX_DT = 1. / 50.
func _process(delta):
super(delta)
- marker.position = G.interpolate(marker.position, target_visual, delta * 30.)
- while delta > 0.001:
- var dt = min(delta, MAX_DT)
- _process_movement(dt)
- delta -= dt
+ marker.position = G.interpolate(marker.position, current_interact_target.target_visual_pos, delta * 30.)
+ if is_despawning: return
update_touch_scrolls()
func _input(event: InputEvent):
@@ -90,16 +90,14 @@ func _input(event: InputEvent):
_: return
if event.pressed: Input.action_press(action)
else: Input.action_release(action)
-
-var moving_duration = 0
var fps_look = Vector2(0., 0.)
func _process_movement(delta):
var input = Input.get_vector("left", "right", "forwards", "backwards") if is_input_enabled() else Vector2.ZERO
+ if Input.is_action_pressed("stop_movement"): input *= 0.4
if Settings.read("gameplay.first_person"): input = (input + Vector2(0.0, -0.1)).rotated(fps_look.y)
else: input = input.rotated(input_rotation)
- var boost = Input.is_action_pressed("boost") or (Settings.read("gameplay.latch_boost") and boosting)
if (Input.is_action_pressed("interact_left")
or Input.is_action_just_released("interact_left")
@@ -107,18 +105,21 @@ func _process_movement(delta):
or Input.is_action_just_released("interact_right")):
input *= 0
else:
- update_interact_target()
+ if Settings.read("gameplay.first_person"): current_interact_target = get_interact_target_fps()
+ else: current_interact_target = get_interact_target()
- if Settings.read("gameplay.accessible_movement"):
- if input.length() < 0.5: moving_duration -= delta * 2
- else: moving_duration += delta
- moving_duration = clamp(moving_duration, 0, 1)
- input *= min(1, moving_duration)
+ interact(current_interact_target)
- interact()
- var was_boosting = boosting
+ var boost = Input.is_action_pressed("boost") or (Settings.read("gameplay.latch_boost") and boosting)
+
+ if direction != input or boosting != was_boosting:
+ if game.mp != null and game.join_state == Game.JoinState.JOINED:
+ # print("sending %s %s" % [boost, was_boosting])
+ game.mp.send_movement(game.my_player_id, position_, input, boost)
+
+ was_boosting = boosting
direction = input
- update(delta, boost)
+ update_movement(delta, boost)
if boosting and not was_boosting and Settings.read("gameplay.vibration"):
Input.start_joy_vibration(0, 0, input.length(), 0.15)
Input.vibrate_handheld(75, input.length() * 0.1)
@@ -126,50 +127,6 @@ func _process_movement(delta):
position_anim = position_
rotation_anim = rotation_
-func update(dt: float, boost: bool):
- direction = direction.limit_length(1.)
- if direction.length() > 0.05:
- facing = direction + (facing - direction) * exp(-dt * 10.)
- if direction.length() < 0.5:
- direction *= 0
- rotation_ = atan2(facing.x, facing.y);
- boost = boost and direction.length() > 0.1
- boosting = boost and (boosting or stamina >= 1.0) and stamina > 0
- if boosting: stamina -= dt / BOOST_DURATION
- else: stamina += dt / BOOST_RESTORE
- stamina = max(min(stamina, 1.0), 0.0)
- var speed = PLAYER_SPEED * (BOOST_FACTOR if boosting else 1.)
- velocity_ += direction * dt * speed
- position_ += velocity_ * dt
- velocity_ = velocity_ * exp(-dt * PLAYER_FRICTION)
- collide(dt)
-
-func collide(dt: float):
- for xo in range(-1, 2):
- for yo in range(-1, 2):
- var tile = Vector2i(xo, yo) + Vector2i(position_)
- if !game.get_tile_collision(tile): continue
- tile = Vector2(tile)
- var d = aabb_point_distance(tile, tile + Vector2.ONE, position_)
- if d > PLAYER_SIZE: continue
- var h = 0.01;
- var d_sample_x = aabb_point_distance(tile, tile + Vector2.ONE, position_ + Vector2(h, 0))
- var d_sample_y = aabb_point_distance(tile, tile + Vector2.ONE, position_ + Vector2(0, h))
- var grad = (Vector2(d_sample_x - d, d_sample_y - d)) / h
-
- position_ += (PLAYER_SIZE - d) * grad;
- velocity_ -= grad * grad.dot(velocity_)
-
- for player: Player in game.players.values():
- var diff = position_ - player.position_
- var d = diff.length()
- if d < 0.01: continue
- if d >= PLAYER_SIZE * 2: continue
- var norm = diff.normalized();
- var f = 100 / (1 + d)
- velocity_.x += norm.x * f * dt
- velocity_.y += norm.y * f * dt
-
func is_input_enabled() -> bool:
return not game.menu.covered and not Global.game_paused
@@ -179,13 +136,12 @@ func update_touch_scrolls():
if onscreen_controls.touch_enabled:
onscreen_controls.visible = is_input_enabled()
-func aabb_point_distance(mi: Vector2, ma: Vector2, p: Vector2) -> float:
- return (p - p.clamp(mi, ma)).length()
-
-func update_position(_new_position: Vector2, _new_rotation: float, _new_boosting: bool):
+func update_position(_new_position: Vector2, _new_direction: Vector2, _new_rotation: float, _new_boosting: bool):
+ # Ignore movement packets from server. (This is not a movement sync)
pass
func progress(position__: float, speed: float, warn: bool, h):
+ # An item the player is holding is making progress
super(position__, speed, warn, h)
if warn:
current_vibration_strength = position__
@@ -220,134 +176,109 @@ func take_item(tile: Tile, h: int):
Input.start_joy_vibration(0, 0.1, 0.0, 0.075)
Input.vibrate_handheld(75, 0.1)
-func interact():
+func interact(interact_target: InteractTarget):
if not is_input_enabled(): return
- var tile = game.map.get_tile_instance(target_tile)
- if tile != null:
+ if interact_target is EmptyTarget:
+ marker.visible = false
+ marker.rotation.y = 0.
+ return
+ else:
if not marker.visible:
+ # New target acquired!
marker.visible = true
- marker.position = target_visual
-
- # clear last interaction if target_tile has moved since
- if last_interaction != null and not last_interaction == target_tile:
- game.mp.send_tile_interact(game.my_player_id, last_interaction, false, 0)
- marker.set_interacting(false)
- last_interaction = null
- marker.set_interactive(found_interact_target)
+ marker.position = interact_target.target_visual_pos
+ marker.rotation.y = interact_target.target_visual_rot
+
+ if interact_target is TileTarget:
for h in [0, 1]:
- if Input.is_action_just_pressed("interact_" + G.index_to_hand(h)) and last_interaction == null:
- last_interaction = target_tile
- game.mp.send_tile_interact(game.my_player_id, target_tile, true, h if h < Global.hand_count else 0)
- tile.interact()
+ var hand_: int = h if h < Global.hand_count else 0
+ if Input.is_action_just_pressed("interact_" + G.index_to_hand(h)) and not marker.interacting:
+ game.mp.send_tile_interact(game.my_player_id, interact_target.pos, true, hand_)
+ interact_target.tile.interact()
marker.set_interacting(true)
if Input.is_action_just_released("interact_" + G.index_to_hand(h)):
- last_interaction = null
- game.mp.send_tile_interact(game.my_player_id, target_tile, false, h if h < Global.hand_count else 0)
+ game.mp.send_tile_interact(game.my_player_id, interact_target.pos, false, hand_)
+ marker.set_interacting(false)
+ elif interact_target is PlayerTarget:
+ for h in [0, 1]:
+ var hand_: int = h if h < Global.hand_count else 0
+ if Input.is_action_just_pressed("interact_" + G.index_to_hand(h)) and not marker.interacting:
+ game.mp.send_player_interact(game.my_player_id, interact_target.player.id, hand_, true, hand_)
+ marker.set_interacting(true)
+ if Input.is_action_just_released("interact_" + G.index_to_hand(h)):
+ game.mp.send_player_interact(game.my_player_id, interact_target.player.id, hand_, false, hand_)
marker.set_interacting(false)
- else:
- marker.visible = false
-
-func update_interact_target():
- if Settings.read("gameplay.first_person"):
- return update_interact_target_fps()
- match Settings.read("gameplay.interact_target"):
- "dirsnap": return update_interact_target_dirsnap()
- "dir": return update_interact_target_dir()
- _: return update_interact_target_dir()
-
-func update_interact_target_dir():
- target_tile = Vector2i(
- int(floor(movement_base.position.x + sin(movement_base.rotation.y))),
- int(floor(movement_base.position.z + cos(movement_base.rotation.y)))
- )
- var tile = game.map.get_tile_instance(target_tile)
- if tile != null:
- found_interact_target = game.get_tile_interactive(target_tile, hand)
- target_visual = tile.item_base.global_position
- else:
- found_interact_target = false
- target_visual = Vector3(float(target_tile.x), 1., float(target_tile.y))
-func update_interact_target_fps():
- target_tile = Vector2i(
+func get_interact_target_fps() -> InteractTarget:
+ var best_interact_target: InteractTarget = EmptyTarget.new()
+ var target_tile = Vector2i(
int(floor(movement_base.position.x + sin(-fps_look.y + PI))),
int(floor(movement_base.position.z + cos(-fps_look.y + PI)))
)
- var tile = game.map.get_tile_instance(target_tile)
- if tile != null:
- found_interact_target = game.get_tile_interactive(target_tile, hand)
- target_visual = tile.item_base.global_position
- else:
- found_interact_target = false
- target_visual = Vector3(float(target_tile.x), 1., float(target_tile.y))
+ var target = get_best_player_target(target_tile, Vector2(movement_base.position.x, movement_base.position.z))
+ if target is PlayerTarget and target.distance < 1.25:
+ best_interact_target = target
-func update_interact_target_dirsnap():
- var interact_target := Vector2(
- movement_base.position.x + sin(movement_base.rotation.y) * 0.7,
- movement_base.position.z + cos(movement_base.rotation.y) * 0.7
+ var tile = game.map.get_topmost_instance(target_tile)
+ if game.is_tile_interactive(target_tile, hand):
+ var target_rot: float = tile.item.rotation.y if tile.item != null and not tile.item.is_round() else 0.
+ best_interact_target = TileTarget.new(target_tile, tile, tile.item_base.global_position, target_rot)
+
+ return best_interact_target
+
+func get_interact_target() -> InteractTarget:
+ var movement_base_2d := Vector2(movement_base.position.x, movement_base.position.z)
+ var interact_target_pos := movement_base_2d + Vector2(
+ sin(movement_base.rotation.y) * 0.7,
+ cos(movement_base.rotation.y) * 0.7
)
- var interact_target_i := interact_target.floor()
- target_visual = Vector3(interact_target_i.x, 0, interact_target_i.y)
- target_tile = interact_target_i
- var best_distance := 100.
- found_interact_target = false
+ var interact_target_pos_i := interact_target_pos.floor()
- # Calculate player positions. Tiles with players on them are valid interact targets.
- var player_positions: Dictionary = {} # Dictionary[id: int, pos: Vector3]
- for p: Player in game.players.values():
- if not p.is_chef: continue
- player_positions[p.id] = Vector3(p.position_anim.x, 0, p.position_anim.y)
+ # Find the player closest to the interact target
+ var best_interact_target: InteractTarget = EmptyTarget.new()
+ if Settings.read("gameplay.allow_focus_players"):
+ best_interact_target = get_best_player_target(interact_target_pos, movement_base_2d)
+ var best_distance: float = best_interact_target.distance if best_interact_target is PlayerTarget else 100.
+ # Let's see if we can find a tile wsith an even better distance!
# Test all tiles in a 3x3 square around the player for interactible tiles.
- # Return the one which is closest to interact_target.
+ # Return the one which is closest to interact_target_pos.
for offset_x in range(-1, 2):
- for offset_y in range (-1, 2):
- var offset_cursor := interact_target_i + Vector2(offset_x, offset_y)
+ for offset_y in range(-1, 2):
+ var offset_cursor := interact_target_pos_i + Vector2(offset_x, offset_y)
var tile_center := Vector2(offset_cursor) + Vector2(0.5, 0.5)
- if game.get_tile_interactive(offset_cursor, hand):
- var cursor_tile_distance := interact_target.distance_to(tile_center)
- var player_tile_distance := Vector2(
- movement_base.position.x - tile_center.x,
- movement_base.position.z - tile_center.y
- ).length()
- if player_tile_distance < MAX_PLAYER_INTERACT_DIST && cursor_tile_distance < best_distance:
- found_interact_target = true
- best_distance = cursor_tile_distance
- var tile = game.map.get_tile_instance(offset_cursor)
- target_visual = tile.item_base.global_position
- if tile.item != null:
- marker.rotation.y = tile.item.rotation.y
- else: marker.rotation.y = 0.
- target_tile = offset_cursor
- continue
-
- # Check if there are any players on this tile.
- # If there are multilpe, remember the player closest to the center of the tile
- # (They will be the interact target)
- var best_cursor_tile_distance := 100.
- var best_player_tile_distance := 100.
- var best_player_pos: Vector3
- var best_player_rot: float
- for p_id in player_positions.keys():
- if p_id == game.my_player_id: continue # I can't interact with myself
- var p_pos: Vector3 = player_positions[p_id]
- var p_pos_2d := Vector2(p_pos.x, p_pos.z)
- var tile_center_distance := p_pos_2d.distance_to(tile_center)
- var cursor_tile_distance := interact_target.distance_to(tile_center)
- var player_tile_distance := Vector2(movement_base.position.x, movement_base.position.z).distance_to(tile_center)
- if tile_center_distance < 0.7:
- if cursor_tile_distance < best_cursor_tile_distance:
- best_cursor_tile_distance = cursor_tile_distance
- best_player_tile_distance = player_tile_distance
- best_player_pos = p_pos
- best_player_rot = game.players[p_id].rotation_anim
-
- if best_player_tile_distance < MAX_PLAYER_INTERACT_DIST && best_cursor_tile_distance < best_distance:
- found_interact_target = true
- best_distance = best_cursor_tile_distance
- target_visual = best_player_pos
- marker.rotation.y = best_player_rot
- target_tile = offset_cursor
+ if game.is_tile_interactive(offset_cursor, hand):
+ var distance := interact_target_pos.distance_to(tile_center)
+ var self_target_distance := movement_base_2d.distance_to(tile_center)
+ if self_target_distance < MAX_PLAYER_INTERACT_DIST && distance < best_distance:
+ best_distance = distance
+ var tile = game.map.get_topmost_instance(offset_cursor)
+ var tile_item = game.map.get_tile_item(offset_cursor)
+ var target_rot: float = tile_item.rotation.y if tile_item != null and not tile_item.is_round() else 0.
+ best_interact_target = TileTarget.new(offset_cursor, tile, tile.item_base.global_position, target_rot)
+
+ return best_interact_target
+
+func get_best_player_target(interact_target_pos: Vector2, movement_base_2d: Vector2) -> InteractTarget:
+ var best_interact_target: InteractTarget = EmptyTarget.new()
+ var best_distance := 100.
+
+ for p: Player in game.players.values():
+ if not p.is_chef: continue # Customers cannot be interacted with
+ if p.id == game.my_player_id: continue # I can't interact with myself
+
+ var interact_possible := false
+ for i in range(p.hand.size()):
+ interact_possible = interact_possible or (p.hand[i] != null or p.hand[i] != null)
+ if not interact_possible: continue # Interaction not possible if all hand pairs are empty
+
+ var distance: float = p.position_anim.distance_to(interact_target_pos)
+ var self_target_distance: float = p.position_anim.distance_to(movement_base_2d)
+ if self_target_distance < MAX_PLAYER_INTERACT_DIST and distance < best_distance:
+ best_distance = distance
+ best_interact_target = PlayerTarget.new(p, Vector3(p.position_anim.x, 0, p.position_anim.y), p.rotation_anim, distance)
+
+ return best_interact_target
diff --git a/client/player/follow_camera.gd b/client/player/follow_camera.gd
index 42670118..c4e4d657 100644
--- a/client/player/follow_camera.gd
+++ b/client/player/follow_camera.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -43,9 +43,6 @@ var ground: Vector3
var camera_distance: float = 10.
var camera_distance_target: float = camera_distance
-var disable_input_menu := false
-var disable_input_lobby := false
-
var _disable_input := false
func _ready():
@@ -56,6 +53,7 @@ func _ready():
func _process(delta):
if target != null:
+ handle_input(delta)
follow(delta)
func _input(event):
@@ -74,6 +72,20 @@ func zoom(zoom_dist: float) -> void:
camera_distance_target *= exp(zoom_dist * ZOOM_SPEED)
camera_distance_target = clamp(camera_distance_target, MIN_ZOOM, MAX_ZOOM)
+func handle_input(delta):
+ if _disable_input: return
+ var invert_factor = -1 if Settings.read("gameplay.invert_camera") else 1;
+ angle_target += Input.get_axis("rotate_left", "rotate_right") * ROTATE_SPEED * delta * invert_factor
+ angle_up_target += Input.get_axis("rotate_down", "rotate_up") * ROTATE_UP_SPEED * delta * invert_factor
+
+ var zoom_dist = Input.get_axis("zoom_in", "zoom_out") * delta
+ zoom_dist += float(Input.is_action_just_pressed("zoom_out_discrete")) * DISCRETE_DURATION
+ zoom_dist -= float(Input.is_action_just_pressed("zoom_in_discrete")) * DISCRETE_DURATION
+ zoom(zoom_dist)
+
+func jump_to_target():
+ follow(INF)
+
func follow(delta):
if Settings.read("gameplay.first_person"):
var player = target.get_parent()
@@ -86,15 +98,9 @@ func follow(delta):
target.get_parent().input_rotation = -rotation.y
return
else: fov = 45.
-
- var invert_factor = -1 if Settings.read("gameplay.invert_camera") else 1;
- if not _disable_input:
- angle_target += Input.get_axis("rotate_left", "rotate_right") * ROTATE_SPEED * delta * invert_factor
angle = G.interpolate_angle(angle, angle_target, delta * ROTATE_WEIGHT)
- if not _disable_input:
- angle_up_target += Input.get_axis("rotate_down", "rotate_up") * ROTATE_UP_SPEED * delta * invert_factor
angle_up_target = clamp(angle_up_target, ANGLE_UP_MIN, ANGLE_UP_MAX)
angle_up = G.interpolate_angle(angle_up, angle_up_target, delta * ROTATE_UP_WEIGHT)
@@ -116,26 +122,12 @@ func follow(delta):
# add 0.5, this is the head height
ground = G.interpolate(ground, target.position + Vector3(0., 0.5, 0.), delta * MOVE_WEIGHT)
- if not _disable_input:
- var zoom_dist = Input.get_axis("zoom_in", "zoom_out") * delta
- zoom_dist += float(Input.is_action_just_pressed("zoom_out_discrete")) * DISCRETE_DURATION
- zoom_dist -= float(Input.is_action_just_pressed("zoom_in_discrete")) * DISCRETE_DURATION
- zoom(zoom_dist)
-
camera_distance = G.interpolate(camera_distance, camera_distance_target, delta * (ZOOM_WEIGHT_AUTO if autozoom else ZOOM_WEIGHT))
position = ground + offset
if target.get_parent() is ControllablePlayer:
target.get_parent().input_rotation = -angle_target
-func set_ingame(state: bool, in_lobby: bool):
+func set_ingame(state: bool, _in_lobby: bool):
# Disable input in lobby
- if state and in_lobby:
- reset()
- disable_input_lobby = true
- else:
- disable_input_lobby = false
- update_disable_input()
-
-func update_disable_input():
- _disable_input = disable_input_lobby or disable_input_menu
+ if state: reset()
diff --git a/client/player/follow_camera.tscn b/client/player/follow_camera.tscn
index f2f1138c..ee99af3d 100644
--- a/client/player/follow_camera.tscn
+++ b/client/player/follow_camera.tscn
@@ -1,11 +1,11 @@
-[gd_scene load_steps=3 format=3 uid="uid://b31mlnao6ybt8"]
+[gd_scene format=3 uid="uid://b31mlnao6ybt8"]
[ext_resource type="Script" uid="uid://eieoab04mpqc" path="res://player/follow_camera.gd" id="1_qipju"]
-[ext_resource type="Script" path="res://player/camera_recorder.gd" id="2_12um7"]
+[ext_resource type="Script" uid="uid://b7wqp72o1bxvu" path="res://player/camera_recorder.gd" id="2_12um7"]
-[node name="FollowCamera" type="Camera3D"]
+[node name="FollowCamera" type="Camera3D" unique_id=659967799]
fov = 45.0
script = ExtResource("1_qipju")
-[node name="CameraRecorder" type="Node" parent="."]
+[node name="CameraRecorder" type="Node" parent="." unique_id=847685374]
script = ExtResource("2_12um7")
diff --git a/client/player/item_bubble.gd b/client/player/item_bubble.gd
index 92e6da87..39872d5d 100644
--- a/client/player/item_bubble.gd
+++ b/client/player/item_bubble.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/player/item_bubble.tscn b/client/player/item_bubble.tscn
index 8d55ebd0..f9cbe567 100644
--- a/client/player/item_bubble.tscn
+++ b/client/player/item_bubble.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=6 format=3 uid="uid://cj777mi5nok6c"]
+[gd_scene format=3 uid="uid://cj777mi5nok6c"]
[ext_resource type="Script" uid="uid://c34w2snsabjqp" path="res://player/item_bubble.gd" id="1_84g24"]
[ext_resource type="PackedScene" uid="uid://fkqh36s4vl3p" path="res://gui/components/message/item/item_message.tscn" id="2_hgmra"]
@@ -17,15 +17,15 @@ shading_mode = 0
albedo_texture = SubResource("ViewportTexture_mko8a")
billboard_mode = 1
-[node name="ItemBubble" type="MeshInstance3D"]
+[node name="ItemBubble" type="MeshInstance3D" unique_id=2121165455]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, 0)
mesh = SubResource("QuadMesh_tlsxo")
surface_material_override/0 = SubResource("StandardMaterial3D_5iy0t")
script = ExtResource("1_84g24")
-[node name="SubViewport" type="SubViewport" parent="."]
+[node name="SubViewport" type="SubViewport" parent="." unique_id=940665713]
disable_3d = true
transparent_bg = true
size = Vector2i(256, 256)
-[node name="ItemMessage" parent="SubViewport" instance=ExtResource("2_hgmra")]
+[node name="ItemMessage" parent="SubViewport" unique_id=81852846 instance=ExtResource("2_hgmra")]
diff --git a/client/player/marker/interact_marker.gdshader b/client/player/marker/interact_marker.gdshader
index a85147ca..66377cb8 100644
--- a/client/player/marker/interact_marker.gdshader
+++ b/client/player/marker/interact_marker.gdshader
@@ -1,6 +1,6 @@
/*
Hurry Curry! - a game about cooking
- Copyright (C) 2025 Hurry Curry! Contributors
+ Copyright (C) 2026 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
@@ -16,7 +16,7 @@
*/
shader_type spatial;
-render_mode depth_test_disabled;
+render_mode depth_test_disabled, unshaded;
uniform float max_width = .1;
uniform float marker_length = .5;
@@ -25,9 +25,9 @@ uniform bool interacting = false;
void fragment() {
if (interacting) {
- ALBEDO = vec3(0., 0., 15.);
+ ALBEDO = vec3(0., 0., 5.);
} else {
- ALBEDO = vec3(15., 0., 0.);
+ ALBEDO = vec3(5., 0., 0.);
}
vec2 uv = abs(2. * UV.xy - 1.);
float m_length = marker_length / max_width;
diff --git a/client/player/marker/marker.gd b/client/player/marker/marker.gd
index 31c99e2d..70bffe16 100644
--- a/client/player/marker/marker.gd
+++ b/client/player/marker/marker.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -16,11 +16,11 @@
class_name Marker
extends Node3D
+var interacting := false
+
@onready var _cube: MeshInstance3D = $Cube
@onready var mat: ShaderMaterial = _cube.get_active_material(0)
-func set_interactive(val: bool):
- visible = val
-
func set_interacting(val: bool):
mat.set_shader_parameter("interacting", val)
+ interacting = val
diff --git a/client/player/marker/marker.tscn b/client/player/marker/marker.tscn
index 755b6053..757bf9d0 100644
--- a/client/player/marker/marker.tscn
+++ b/client/player/marker/marker.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=7 format=4 uid="uid://c0euiv7duqfp4"]
+[gd_scene format=4 uid="uid://c0euiv7duqfp4"]
[ext_resource type="Script" uid="uid://nq4a28jq34nm" path="res://player/marker/marker.gd" id="1_3njdu"]
[ext_resource type="Shader" uid="uid://c0w3xqd4siqw3" path="res://player/marker/interact_marker.gdshader" id="2_dejwy"]
@@ -43,12 +43,11 @@ shader_parameter/marker_length = 0.5
shader_parameter/pulse_speed = 4.0
shader_parameter/interacting = false
-[node name="Marker" type="Node3D"]
+[node name="Marker" type="Node3D" unique_id=1029636113]
visible = false
script = ExtResource("1_3njdu")
-[node name="Cube" type="MeshInstance3D" parent="."]
+[node name="Cube" type="MeshInstance3D" parent="." unique_id=993558357]
transform = Transform3D(0.25, 0, 0, 0, 0.25, 0, 0, 0, 0.25, 0, 0.25, 0)
mesh = SubResource("ArrayMesh_2ie13")
-skeleton = NodePath("")
surface_material_override/0 = SubResource("ShaderMaterial_wuj1v")
diff --git a/client/player/mirror.gd b/client/player/mirror.gd
index 6ef2b483..218a0715 100644
--- a/client/player/mirror.gd
+++ b/client/player/mirror.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/player/onscreen_controls/controls.gd b/client/player/onscreen_controls/controls.gd
index 3f38e7c2..310a35b7 100644
--- a/client/player/onscreen_controls/controls.gd
+++ b/client/player/onscreen_controls/controls.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -24,7 +24,7 @@ extends CanvasLayer
var touch_enabled := false
func _ready():
- Settings.hook_changed_init("ui.touch_controls", "main", apply_touch)
+ Settings.hook_changed_init("ui.touch_controls", self, apply_touch)
Global.using_touch_change.connect(func f(_x): apply_touch(Settings.read("ui.touch_controls"))) # throw away useless argument
Global.hand_count_change.connect(apply_hand_count)
apply_hand_count(Global.hand_count)
@@ -36,9 +36,6 @@ func apply_touch(touch_controls: String):
func apply_hand_count(count: int):
interact_left.visible = count >= 2
-func in_lobby_updated(in_lobby: bool):
- $Buttons.visible = not in_lobby
-
func _on_boost_pressed():
Input.action_press("boost")
boost.modulate = modulate_color
diff --git a/client/player/onscreen_controls/controls.tscn b/client/player/onscreen_controls/controls.tscn
index 2f88ee6a..6a4c3466 100644
--- a/client/player/onscreen_controls/controls.tscn
+++ b/client/player/onscreen_controls/controls.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=6 format=3 uid="uid://bq2sqb1u1l5ve"]
+[gd_scene format=3 uid="uid://bq2sqb1u1l5ve"]
[ext_resource type="PackedScene" uid="uid://dmr0fcamx7t56" path="res://player/onscreen_controls/virtual_joystick_scene.tscn" id="1_4k4lh"]
[ext_resource type="Script" uid="uid://b25j7ua3og5rh" path="res://player/onscreen_controls/controls.gd" id="1_rnoki"]
@@ -6,14 +6,14 @@
[ext_resource type="Texture2D" uid="uid://dcgt82qkya880" path="res://gui/resources/icons/interact.webp" id="3_37rne"]
[ext_resource type="Texture2D" uid="uid://qto5rj6wlaeb" path="res://gui/resources/icons/pause.webp" id="5_4bttq"]
-[node name="UI" type="CanvasLayer"]
+[node name="UI" type="CanvasLayer" unique_id=1028546052]
script = ExtResource("1_rnoki")
-[node name="MovementStick" parent="." instance=ExtResource("1_4k4lh")]
+[node name="MovementStick" parent="." unique_id=784964015 instance=ExtResource("1_4k4lh")]
modulate = Color(1, 1, 1, 0.752941)
joystick_mode = 1
-[node name="Buttons" type="Control" parent="."]
+[node name="Buttons" type="Control" parent="." unique_id=1444894564]
modulate = Color(1, 1, 1, 0.752941)
layout_mode = 3
anchors_preset = 3
@@ -26,29 +26,29 @@ offset_top = -300.0
grow_horizontal = 0
grow_vertical = 0
-[node name="Boost" type="TouchScreenButton" parent="Buttons"]
+[node name="Boost" type="TouchScreenButton" parent="Buttons" unique_id=2098457571]
position = Vector2(150, 25)
scale = Vector2(0.5, 0.5)
texture_normal = ExtResource("2_i4ife")
-[node name="InteractL" type="TouchScreenButton" parent="Buttons"]
+[node name="InteractL" type="TouchScreenButton" parent="Buttons" unique_id=2030978112]
position = Vector2(25, 150)
scale = Vector2(0.5, 0.5)
texture_normal = ExtResource("3_37rne")
-[node name="InteractR" type="TouchScreenButton" parent="Buttons"]
+[node name="InteractR" type="TouchScreenButton" parent="Buttons" unique_id=1220259904]
position = Vector2(150, 150)
scale = Vector2(0.5, 0.5)
texture_normal = ExtResource("3_37rne")
-[node name="Buttons2" type="Control" parent="."]
+[node name="Buttons2" type="Control" parent="." unique_id=669794865]
modulate = Color(1, 1, 1, 0.752941)
layout_mode = 3
anchors_preset = 0
offset_right = 300.0
offset_bottom = 300.0
-[node name="Pause" type="TouchScreenButton" parent="Buttons2"]
+[node name="Pause" type="TouchScreenButton" parent="Buttons2" unique_id=640033902]
position = Vector2(50, 50)
scale = Vector2(0.5, 0.5)
texture_normal = ExtResource("5_4bttq")
diff --git a/client/player/onscreen_controls/virtual_joystick.gd b/client/player/onscreen_controls/virtual_joystick.gd
index cb16a435..44a13b05 100644
--- a/client/player/onscreen_controls/virtual_joystick.gd
+++ b/client/player/onscreen_controls/virtual_joystick.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/player/onscreen_controls/virtual_joystick_scene.tscn b/client/player/onscreen_controls/virtual_joystick_scene.tscn
index 7e2446b1..fd26cc96 100644
--- a/client/player/onscreen_controls/virtual_joystick_scene.tscn
+++ b/client/player/onscreen_controls/virtual_joystick_scene.tscn
@@ -1,10 +1,10 @@
-[gd_scene load_steps=4 format=3 uid="uid://dmr0fcamx7t56"]
+[gd_scene format=3 uid="uid://dmr0fcamx7t56"]
[ext_resource type="Script" uid="uid://bltt7ymeeynrg" path="res://player/onscreen_controls/virtual_joystick.gd" id="1_8x4dy"]
[ext_resource type="Texture2D" uid="uid://bm30au8mjfc2f" path="res://player/onscreen_controls/textures/joystick_base_outline.png" id="2_jhjs2"]
[ext_resource type="Texture2D" uid="uid://dt13r06u87fib" path="res://player/onscreen_controls/textures/joystick_tip_arrows.png" id="3_3etdg"]
-[node name="Virtual Joystick" type="Control"]
+[node name="Virtual Joystick" type="Control" unique_id=1908272951]
layout_mode = 3
anchors_preset = 2
anchor_top = 1.0
@@ -15,7 +15,7 @@ offset_bottom = -8.0
grow_vertical = 0
script = ExtResource("1_8x4dy")
-[node name="Base" type="TextureRect" parent="."]
+[node name="Base" type="TextureRect" parent="." unique_id=1162450556]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
@@ -33,7 +33,7 @@ mouse_force_pass_scroll_events = false
texture = ExtResource("2_jhjs2")
stretch_mode = 5
-[node name="Tip" type="TextureRect" parent="Base"]
+[node name="Tip" type="TextureRect" parent="Base" unique_id=859830698]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
diff --git a/client/player/particles/angry/angry.tscn b/client/player/particles/angry/angry.tscn
deleted file mode 100644
index b88bc6ee..00000000
--- a/client/player/particles/angry/angry.tscn
+++ /dev/null
@@ -1,41 +0,0 @@
-[gd_scene load_steps=6 format=3 uid="uid://cvty1rwt52anq"]
-
-[ext_resource type="Texture2D" uid="uid://unjbxplj845n" path="res://player/particles/angry/angry.webp" id="1_5op6v"]
-
-[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ysmnk"]
-transparency = 1
-no_depth_test = true
-shading_mode = 0
-vertex_color_use_as_albedo = true
-albedo_texture = ExtResource("1_5op6v")
-billboard_mode = 3
-billboard_keep_scale = true
-particles_anim_h_frames = 1
-particles_anim_v_frames = 1
-particles_anim_loop = false
-
-[sub_resource type="QuadMesh" id="QuadMesh_5nim7"]
-material = SubResource("StandardMaterial3D_ysmnk")
-
-[sub_resource type="Curve" id="Curve_0rju1"]
-_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.51927, 1), 0.0, 0.0, 0, 0]
-point_count = 2
-
-[sub_resource type="Gradient" id="Gradient_lmymu"]
-offsets = PackedFloat32Array(0, 0.711828, 1)
-colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)
-
-[node name="Angry" type="CPUParticles3D"]
-emitting = false
-amount = 5
-lifetime = 2.0
-one_shot = true
-explosiveness = 1.0
-mesh = SubResource("QuadMesh_5nim7")
-direction = Vector3(0, 1, 0)
-spread = 30.0
-gravity = Vector3(0, 0, 0)
-initial_velocity_min = 1.0
-initial_velocity_max = 1.5
-scale_amount_curve = SubResource("Curve_0rju1")
-color_ramp = SubResource("Gradient_lmymu")
diff --git a/client/player/particles/effect.tscn b/client/player/particles/effect.tscn
deleted file mode 100644
index 4495ce12..00000000
--- a/client/player/particles/effect.tscn
+++ /dev/null
@@ -1,36 +0,0 @@
-[gd_scene load_steps=9 format=3 uid="uid://dn2ne30t81ame"]
-
-[ext_resource type="Script" uid="uid://ecsoi03822i5" path="res://player/particles/effect.gd" id="1_aqsk6"]
-[ext_resource type="PackedScene" uid="uid://yaed1vnhd0aa" path="res://player/particles/satisfied/stars.tscn" id="2_shb5l"]
-[ext_resource type="PackedScene" uid="uid://cvty1rwt52anq" path="res://player/particles/angry/angry.tscn" id="3_bnidm"]
-[ext_resource type="AudioStream" uid="uid://camy77x26mmpv" path="res://gui/resources/sounds/success.ogg" id="3_favyn"]
-[ext_resource type="AudioStream" uid="uid://cv4isy6po6pqd" path="res://gui/resources/sounds/failure.ogg" id="4_j38qf"]
-[ext_resource type="Script" uid="uid://n4jwod1jfuiv" path="res://audio/play_random.gd" id="5_t2upj"]
-[ext_resource type="AudioStream" uid="uid://c3gatgrsb0npf" path="res://player/sounds/angry1.ogg" id="6_ou7uy"]
-[ext_resource type="AudioStream" uid="uid://cty282m6ckt62" path="res://player/sounds/angry2.ogg" id="7_r21iy"]
-
-[node name="Effect" type="Node3D"]
-script = ExtResource("1_aqsk6")
-
-[node name="Stars" parent="." instance=ExtResource("2_shb5l")]
-transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
-
-[node name="Angry" parent="." instance=ExtResource("3_bnidm")]
-transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
-
-[node name="Success" type="AudioStreamPlayer" parent="."]
-stream = ExtResource("3_favyn")
-
-[node name="Failure" type="AudioStreamPlayer" parent="."]
-stream = ExtResource("4_j38qf")
-volume_db = -8.0
-
-[node name="AngryGrunt" type="Node3D" parent="."]
-script = ExtResource("5_t2upj")
-volume_db = -8.0
-
-[node name="Angry1" type="AudioStreamPlayer3D" parent="AngryGrunt"]
-stream = ExtResource("6_ou7uy")
-
-[node name="Angry2" type="AudioStreamPlayer3D" parent="AngryGrunt"]
-stream = ExtResource("7_r21iy")
diff --git a/client/player/player.gd b/client/player/player.gd
index 828a4495..90671924 100644
--- a/client/player/player.gd
+++ b/client/player/player.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -18,10 +18,13 @@ extends Node3D
const CHAT_BUBBLE: PackedScene = preload("res://player/chat_bubble.tscn")
const ITEM_BUBBLE: PackedScene = preload("res://player/item_bubble.tscn")
-const EFFECT: PackedScene = preload("res://player/particles/effect.tscn")
const PLAYER_SIZE: float = 0.4
-const SPEED: float = 25.
+const PLAYER_ACCELERATION = 10
+const PLAYER_SPEED = 3.8
+const BOOST_FACTOR = 2.5
+const BOOST_DURATION = 0.3
+const BOOST_RESTORE = 0.5
var game: Game
var id := -1. # float because json
@@ -30,6 +33,7 @@ var rotation_anim = 0.
var position_ = Vector2(0, 0)
var position_anim = Vector2(0, 0)
var boosting := false
+var boost_pressed := false # only used in non-controllable players
var walking := false
var username: String
@@ -38,11 +42,9 @@ var movement_base: Node3D = Node3D.new()
var character: Character = preload("res://player/character/character.tscn").instantiate()
var chat_bubble: ChatBubble = null
var item_bubble: ItemBubble = null
-var effect: Effect = null
var clear_chat_timer: Timer = Timer.new()
var clear_item_timer: Timer = Timer.new()
-var clear_effect_timer: Timer = Timer.new()
var is_despawning: bool = false
@@ -54,6 +56,11 @@ var is_customer: bool
var is_chef: bool
var current_item_message = null
+var velocity_ := Vector2(0, 0)
+var direction := Vector2(0, 0)
+var facing := Vector2(1, 0)
+var stamina := 0.
+
var _anim_angle: float = 0.0
const DEFAULT_HAND_BASE_POSITION_CENTER: Vector3 = Vector3(0, .425, .4)
@@ -96,10 +103,8 @@ func _init(_id: int, name_: String, pos: Vector2, character_style_: Dictionary,
clear_chat_timer.one_shot = true
clear_item_timer.one_shot = true
- clear_effect_timer.one_shot = true
add_child(clear_chat_timer)
add_child(clear_item_timer)
- add_child(clear_effect_timer)
is_customer = player_class == "customer"
is_chef = player_class == "chef"
@@ -111,14 +116,62 @@ func _ready():
clear_chat_timer.timeout.connect(clear_text_message)
clear_item_timer.timeout.connect(clear_item_message)
- clear_effect_timer.timeout.connect(clear_effect)
- Settings.hook_changed_init("gameplay.usernames", "main", update_username_tag)
+ Settings.hook_changed_init("gameplay.usernames", self, update_username_tag)
-func update_position(new_position: Vector2, new_rotation: float, new_boosting: bool):
+func update_position(new_position: Vector2, new_direction: Vector2, new_rotation: float, new_boosting: bool):
position_ = new_position
rotation_ = new_rotation
- boosting = new_boosting
+ boost_pressed = new_boosting
+ direction = new_direction
+
+func update_movement(dt: float, boost: bool):
+ # This function implements the server's movement system.
+ # It may not be modified, so that it matches the server's logic.
+ direction = direction.limit_length(1.)
+ if direction.length() > 0.05:
+ facing = direction + (facing - direction) * exp(-dt * 10.)
+ if direction.length() < 0.5:
+ direction *= 0
+ rotation_ = atan2(facing.x, facing.y);
+ boost = boost and direction.length() > 0.1
+ boosting = boost and (boosting or stamina >= 1.0) and stamina > 0
+ if boosting: stamina -= dt / BOOST_DURATION
+ else: stamina += dt / BOOST_RESTORE
+ stamina = max(min(stamina, 1.0), 0.0)
+ var target_v = direction * PLAYER_SPEED * (BOOST_FACTOR if boosting else 1.)
+ velocity_ = target_v + (velocity_ - target_v) * exp(-dt * PLAYER_ACCELERATION)
+ position_ += velocity_ * dt
+ collide(dt)
+
+func collide(dt: float):
+ for xo in range(-1, 2):
+ for yo in range(-1, 2):
+ var tile = Vector2i(xo, yo) + Vector2i(position_)
+ if !game.get_tile_collision(tile): continue
+ tile = Vector2(tile)
+ var d = aabb_point_distance(tile, tile + Vector2.ONE, position_)
+ if d > PLAYER_SIZE: continue
+ var h = 0.01;
+ var d_sample_x = aabb_point_distance(tile, tile + Vector2.ONE, position_ + Vector2(h, 0))
+ var d_sample_y = aabb_point_distance(tile, tile + Vector2.ONE, position_ + Vector2(0, h))
+ var grad = (Vector2(d_sample_x - d, d_sample_y - d)) / h
+
+ position_ += (PLAYER_SIZE - d) * grad;
+ velocity_ -= grad * grad.dot(velocity_)
+ for player: Player in game.players.values():
+ var diff = position_ - player.position_
+ var d = diff.length()
+ if d < 0.01: continue
+ if d >= PLAYER_SIZE * 2: continue
+ var norm = diff.normalized();
+ var f = 100 / (1 + d)
+ velocity_.x += norm.x * f * dt
+ velocity_.y += norm.y * f * dt
+
+func aabb_point_distance(mi: Vector2, ma: Vector2, p: Vector2) -> float:
+ # Calculates the signed distance of a point p to an axis aligned bounding box
+ return (p - p.clamp(mi, ma)).length()
func update_username_tag(state):
var tag: Label3D = character.username_tag
@@ -167,26 +220,34 @@ func pass_to(player: Player, hfrom: int, hto: int):
push_error("target is already holding an item")
player.set_item(i, hto)
+const MAX_DT = 1. / 50.
func _process(delta):
for h in hand.size():
if hand[h] != null:
hand[h].rotation_target = hand_base[h].global_rotation.y
hand[h].position_target = hand_base[h].global_position
_anim_angle = fmod(_anim_angle + delta, TAU)
- position_anim = G.interpolate(position_anim, position_, delta * 10)
- rotation_anim = G.interpolate_angle(rotation_anim, rotation_, delta * 10)
+ position_anim = G.interpolate(position_anim, position_, delta * 20)
+ rotation_anim = G.interpolate_angle(rotation_anim, rotation_, delta * 20)
movement_base.position.x = position_anim.x
movement_base.position.z = position_anim.y
movement_base.rotation.y = rotation_anim
- walking = walking or position_.distance_squared_to(position_anim) > 0.001
+ walking = direction.length_squared() > 0.1
character.walking = walking
character.boosting = boosting
- walking = false
if is_despawning:
movement_base.scale /= exp(delta * 8)
if movement_base.scale.length() < 0.01: self.queue_free()
else:
movement_base.scale = Vector3.ONE * G.interpolate(movement_base.scale.x, 1, delta * 8)
+
+ while delta > 0.001:
+ var dt = min(delta, MAX_DT)
+ _process_movement(delta)
+ delta -= dt
+
+func _process_movement(dt):
+ update_movement(dt, boost_pressed)
func item_message(item_name: String, timeout_initial: float, timeout_remaining: float):
if item_bubble != null:
@@ -213,15 +274,3 @@ func text_message(message: Game.TextMessage):
func clear_text_message():
if chat_bubble != null:
chat_bubble.queue_free()
-
-func effect_message(effect_name: String):
- if effect != null:
- effect.queue_free()
- effect = EFFECT.instantiate()
- movement_base.add_child(effect)
- effect.set_effect(effect_name)
- clear_effect_timer.start(5)
-
-func clear_effect():
- if effect != null:
- effect.queue_free()
diff --git a/client/project.godot b/client/project.godot
index bf64566c..6dd69367 100644
--- a/client/project.godot
+++ b/client/project.godot
@@ -13,13 +13,16 @@ config_version=5
config/name="hurrycurry"
run/main_scene="res://gui/menus/entry.tscn"
config/quit_on_go_back=false
-config/features=PackedStringArray("4.5", "Forward Plus")
+config/features=PackedStringArray("4.6", "Forward Plus")
boot_splash/image="res://icons/main.png"
config/icon="res://icons/main.png"
+[audio]
+
+buses/default_bus_layout="uid://cco0uysin1okg"
+
[autoload]
-TranslationManager="*res://system/translation_manager.gd"
Global="*res://global.gd"
Sound="*res://audio/sound.tscn"
DisableWrongJoypads="*res://system/disable_wrong_joypads.gd"
@@ -46,6 +49,10 @@ display_server/driver.linuxbsd="wayland"
movie_writer/movie_file="/tmp/output.avi"
movie_writer/mjpeg_quality=0.9
+[gui]
+
+theme/custom="uid://b0qmvo504e457"
+
[input]
ui_accept={
@@ -54,6 +61,7 @@ ui_accept={
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194310,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":32,"physical_keycode":0,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":0,"pressure":0.0,"pressed":true,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":74,"key_label":0,"unicode":106,"location":0,"echo":false,"script":null)
]
}
ui_cancel={
@@ -63,6 +71,38 @@ ui_cancel={
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":6,"pressure":0.0,"pressed":true,"script":null)
]
}
+ui_left={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194319,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
+, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":-1.0,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null)
+]
+}
+ui_right={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194321,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":14,"pressure":0.0,"pressed":false,"script":null)
+, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":1.0,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null)
+]
+}
+ui_up={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194320,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":11,"pressure":0.0,"pressed":false,"script":null)
+, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":-1.0,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null)
+]
+}
+ui_down={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194322,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
+, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":1.0,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null)
+]
+}
ui_menu={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194370,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
@@ -94,6 +134,11 @@ right={
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":1.0,"script":null)
]
}
+stop_movement={
+"deadzone": 0.2,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194326,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
+]
+}
rotate_left={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
@@ -252,6 +297,10 @@ toggle_first_person={
pointing/android/enable_pan_and_scale_gestures=true
+[network]
+
+limits/tcp/connect_timeout_seconds=10
+
[physics]
3d/physics_engine="Dummy"
diff --git a/client/service/discover.gd b/client/service/discover.gd
index 8ebd52da..6e8fd462 100644
--- a/client/service/discover.gd
+++ b/client/service/discover.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/service/editor.gd b/client/service/editor.gd
index 2197a5e1..a503ada2 100644
--- a/client/service/editor.gd
+++ b/client/service/editor.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/service/server.gd b/client/service/server.gd
index 9a314aca..bf1b7059 100644
--- a/client/service/server.gd
+++ b/client/service/server.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/service/service.gd b/client/service/service.gd
index 80c37f79..e2d1ed49 100644
--- a/client/service/service.gd
+++ b/client/service/service.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/system/cli.gd b/client/system/cli.gd
index d503d536..f4d0674b 100644
--- a/client/system/cli.gd
+++ b/client/system/cli.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -33,6 +33,12 @@ static var OPTIONS := [
Option.new(null, "render-tiles", Mode.OPTION, "Render tiles from text file to images"),
Option.new(null, "render-resolution", Mode.OPTION, "Resolution for rendering items or tiles"),
Option.new(null, "render-output", Mode.OPTION, "Output directory for rendering items or tiles"),
+ Option.new(null, "render-format", Mode.OPTION, "Render output format (possible values: png, gltf)"),
+ Option.new(null, "render-include-tool-base", Mode.FLAG, "Add counters to cutting board and such"),
+ Option.new(null, "record-camera", Mode.OPTION, "Record camera movement to file"),
+ Option.new(null, "replay-camera", Mode.OPTION, "Replay camera movement"),
+ Option.new(null, "timescale", Mode.OPTION, "Time scaling factor for replay playback and camera recorder"),
+ Option.new(null, "render-output", Mode.OPTION, "Output directory for rendering items or tiles"),
Option.new(null, "connect_address", Mode.POSITIONAL, "Connect to a server directly without menu interaction")
]
@@ -60,10 +66,11 @@ static func print_help():
line += " " + opt.help
print(line)
+static var args: Array
static func parse() -> bool:
- var args := OS.get_cmdline_user_args()
+ args = Array(OS.get_cmdline_user_args())
while not args.is_empty():
- var arg := args[0]
+ var arg = args[0]
args.remove_at(0)
if arg.begins_with("--"):
var long = arg.trim_prefix("--")
@@ -71,14 +78,14 @@ static func parse() -> bool:
if opt_index == -1:
push_error("unknown long option \"%s\"" % long)
return false
- if not _parse_opt(args, OPTIONS[opt_index]): return false
+ if not _parse_opt(OPTIONS[opt_index]): return false
elif arg.begins_with("-"):
for short in arg.trim_prefix("-"):
var opt_index = OPTIONS.find_custom(func(x): return x.short == short)
if opt_index == -1:
push_error("unknown short option \"%s\"" % short)
return false
- if not _parse_opt(args, OPTIONS[opt_index]): return false
+ if not _parse_opt(OPTIONS[opt_index]): return false
else:
var opt_index = OPTIONS.find_custom(func(x): return x.mode == Mode.POSITIONAL)
if opt_index == -1:
@@ -90,7 +97,7 @@ static func parse() -> bool:
print("Parsed options: ", opts)
return true
-static func _parse_opt(args: Array[String], opt: Option) -> bool:
+static func _parse_opt(opt: Option) -> bool:
match opt.mode:
Mode.FLAG:
opts[opt.long] = true
diff --git a/client/system/disable_wrong_joypads.gd b/client/system/disable_wrong_joypads.gd
index 029768b3..aec80aa0 100644
--- a/client/system/disable_wrong_joypads.gd
+++ b/client/system/disable_wrong_joypads.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/system/gltf_apply_visibility.gd b/client/system/gltf_apply_visibility.gd
index 5635bf6e..8a2bed01 100644
--- a/client/system/gltf_apply_visibility.gd
+++ b/client/system/gltf_apply_visibility.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -28,8 +28,6 @@ func _export_post(state: GLTFState) -> Error:
return Error.OK
func hide_node(nodes: Array, node: Dictionary):
- if node.has("mesh"): print("clear mesh")
node.erase("mesh")
for child_index in node.get("children", []):
- print("clear child child_index")
hide_node(nodes, nodes[child_index])
diff --git a/client/system/profile.gd b/client/system/profile.gd
index dd4da430..5cc6acce 100644
--- a/client/system/profile.gd
+++ b/client/system/profile.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/system/render_tool.gd b/client/system/render_tool.gd
index 825f25bb..47875c9f 100644
--- a/client/system/render_tool.gd
+++ b/client/system/render_tool.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -15,26 +15,15 @@
#
extends Menu
-enum Mode {
- ITEMS,
- TILES
-}
-
-@onready var camera = $SubViewportContainer/SubViewport/Node3D/Camera3D
-@onready var base = $SubViewportContainer/SubViewport/Node3D
-
-var current_object: Node3D = null
-var mode: Mode
+@onready var renderer: Renderer = $Renderer
func _ready():
super()
var input_file: String
if Cli.opts.has("render-items"):
- mode = Mode.ITEMS
input_file = Cli.opts["render-items"]
elif Cli.opts.has("render-tiles"):
- mode = Mode.TILES
input_file = Cli.opts["render-tiles"]
else:
push_error("cannot open render_tool menu without corresponding cli options")
@@ -43,25 +32,26 @@ func _ready():
var file = FileAccess.open(input_file, FileAccess.READ)
var object_name_list = file.get_as_text().strip_edges().split("\n")
var resolution = Vector2i.ONE * int(Cli.opts.get("render-resolution", "256"))
- $SubViewportContainer/SubViewport.size = resolution
+ $Renderer/SubViewport.size = resolution
for object_name in object_name_list:
- setup_object(object_name)
- await RenderingServer.frame_post_draw
- var path = Cli.opts.get("render-output", ".").path_join(object_name + ".png")
- $SubViewportContainer/SubViewport.get_texture().get_image().save_png(path)
-
+ print(object_name)
+ if Cli.opts.has("render-items"):
+ renderer.setup_item(object_name)
+ else:
+ var parts = [object_name]
+ if Cli.opts.has("render-include-tool-base") and object_name in BookMenu.TOOLS_WITH_COUNTER: parts.insert(0, "counter")
+ renderer.setup_tile(parts)
+ match Cli.opts.get("render-format", "png"):
+ "png":
+ await RenderingServer.frame_post_draw
+ var path = Cli.opts.get("render-output", ".").path_join(object_name + ".png")
+ $Renderer/SubViewport.get_texture().get_image().save_png(path)
+ "gltf":
+ await get_tree().process_frame
+ var path = Cli.opts.get("render-output", ".").path_join(object_name + ".glb")
+ var doc := GLTFDocument.new()
+ var state := GLTFState.new()
+ doc.append_from_scene($Renderer/SubViewport/Node3D, state)
+ doc.write_to_filesystem(state, path)
exit()
-
-func setup_object(object_name: String):
- if current_object: base.remove_child(current_object)
- match mode:
- Mode.ITEMS:
- current_object = ItemFactory.produce(object_name, base)
- Mode.TILES:
- var tf = TileFactory.new()
- current_object = tf.produce(object_name, Vector2i(0, 0), ["counter", "floor", "counter", null])
- current_object.rotation_degrees.y = 45.
- current_object.translate(Vector3(-0.5, 0.0, -0.5))
- camera.size = 2.
- base.add_child(current_object)
diff --git a/client/system/render_tool.tscn b/client/system/render_tool.tscn
index 5a1a208f..6f69e4ae 100644
--- a/client/system/render_tool.tscn
+++ b/client/system/render_tool.tscn
@@ -1,16 +1,9 @@
-[gd_scene load_steps=4 format=3 uid="uid://xppn2tnr0hcx"]
+[gd_scene format=3 uid="uid://xppn2tnr0hcx"]
[ext_resource type="Script" uid="uid://byw3ney1w3bww" path="res://system/render_tool.gd" id="1_gmn7h"]
+[ext_resource type="PackedScene" uid="uid://hdgsa0yfhnfw" path="res://gui/components/message/renderer.tscn" id="2_6bhk5"]
-[sub_resource type="BoxMesh" id="BoxMesh_pcjn7"]
-
-[sub_resource type="Environment" id="Environment_vdkpo"]
-background_mode = 1
-background_color = Color(0, 0, 0, 0)
-ambient_light_source = 2
-ambient_light_color = Color(1, 1, 1, 1)
-
-[node name="ItemExport" type="Control"]
+[node name="ItemExport" type="Control" unique_id=75589330]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
@@ -19,30 +12,5 @@ grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_gmn7h")
-[node name="SubViewportContainer" type="SubViewportContainer" parent="."]
+[node name="Renderer" parent="." unique_id=522207570 instance=ExtResource("2_6bhk5")]
layout_mode = 0
-offset_right = 512.0
-offset_bottom = 512.0
-
-[node name="SubViewport" type="SubViewport" parent="SubViewportContainer"]
-transparent_bg = true
-handle_input_locally = false
-render_target_update_mode = 4
-
-[node name="Node3D" type="Node3D" parent="SubViewportContainer/SubViewport"]
-
-[node name="DebugPlaceholder" type="MeshInstance3D" parent="SubViewportContainer/SubViewport/Node3D"]
-visible = false
-mesh = SubResource("BoxMesh_pcjn7")
-skeleton = NodePath("../../../..")
-
-[node name="WorldEnvironment" type="WorldEnvironment" parent="SubViewportContainer/SubViewport/Node3D"]
-environment = SubResource("Environment_vdkpo")
-
-[node name="Camera3D" type="Camera3D" parent="SubViewportContainer/SubViewport/Node3D"]
-transform = Transform3D(1, 0, 0, 0, 0.8660254, 0.5, 0, -0.5, 0.8660254, 0, 2, 3)
-projection = 1
-far = 30.0
-
-[node name="DirectionalLight3D" type="DirectionalLight3D" parent="SubViewportContainer/SubViewport/Node3D"]
-transform = Transform3D(0.7071067, 0.49999997, -0.4999999, 0, 0.70710677, 0.7071067, 0.7071067, -0.49999997, 0.4999999, 0, 0, 0)
diff --git a/client/system/server_list.gd b/client/system/server_list.gd
index a7e83729..985afab5 100644
--- a/client/system/server_list.gd
+++ b/client/system/server_list.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
diff --git a/client/system/settings.gd b/client/system/settings.gd
index e7f3e2f7..c8f4ef79 100644
--- a/client/system/settings.gd
+++ b/client/system/settings.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -21,14 +21,13 @@ static func get_root():
SettingsCategory.new("gameplay", [
ToggleSetting.new("usernames", true),
ToggleSetting.new("latch_boost", true),
+ ToggleSetting.new("allow_focus_players", true),
ToggleSetting.new("vibration", true),
ToggleSetting.new("invert_camera", false),
ToggleSetting.new("interpolate_camera_rotation", false),
ButtonSetting.new("setup_completed", false, launch_setup),
ToggleSetting.new("tutorial_disabled", false),
- ToggleSetting.new("accessible_movement", false),
ToggleSetting.new("first_person", false),
- DropdownSetting.new("interact_target", "dirsnap", ["dir", "dirsnap"]),
PathSetting.new("screenshot_path", "", FileDialog.FileMode.FILE_MODE_OPEN_DIR),
]),
SettingsCategory.new("graphics", [
@@ -56,17 +55,18 @@ static func get_root():
]),
SettingsCategory.new("ui", [
DropdownSetting.new("touch_controls", "automatic", ["automatic", "enabled", "disabled"]),
- DropdownSetting.new("language", "system", Global.language_list()),
+ DropdownSetting.new("language", "system", Global.language_list(), Global.language_tooltip_list()),
ToggleSetting.new("hide_overlays", false),
DropdownSetting.new("scale_mode", "resize", ["resize", "disabled"]),
RangeSetting.new("scale_factor", 1. if not Global.on_mobile() else 1.5, 0.5, 1.5, 3),
+ RangeSetting.new("transition_speed", 4., 1., 8.),
]),
SettingsCategory.new("input", InputManager.settings([
RangeSetting.new("fps_mouse_sensitivity", 0.001, 0.0001, 0.003)
])),
SettingsCategory.new("server", [
PathSetting.new("binary_path", "", FileDialog.FileMode.FILE_MODE_OPEN_FILE),
- PathSetting.new("editor_binary_path", "", FileDialog.FileMode.FILE_MODE_OPEN_DIR),
+ PathSetting.new("editor_binary_path", "", FileDialog.FileMode.FILE_MODE_OPEN_FILE),
PathSetting.new("data_path", "", FileDialog.FileMode.FILE_MODE_OPEN_DIR),
TextSetting.new("name", "A Hurry Curry! Server"),
ToggleSetting.new("allow_external_connections", true),
@@ -78,7 +78,7 @@ static func get_root():
]),
SettingsCategory.new("online", [
ToggleSetting.new("use_registry", false),
- TextSetting.new("registry_url", "https://hurrycurry-registry.metamuffin.org/"),
+ TextSetting.new("registry_url", "https://registry.hurrycurry.org/"),
ToggleSetting.new("use_discover", true),
PathSetting.new("discover_binary", "", FileDialog.FileMode.FILE_MODE_OPEN_FILE),
])
@@ -115,6 +115,7 @@ static func load(path: String):
var f = FileAccess.open(path, FileAccess.READ)
changed = JSON.parse_string(f.get_as_text())
tree.load(changed)
+ setup_static_hooks()
static func save():
var changed = {}
@@ -128,11 +129,27 @@ static func trigger_hook(key: String, value):
change_hooks[key][slot].callv([value] if value != null else [])
if key.find(".") != -1: trigger_hook(key.rsplit(".", false, 1)[0], key.rsplit(".", false, 1)[1])
-static func hook_changed(key: String, slot: String, callable: Callable):
+# slot: String | Node
+static func hook_changed(key: String, slot, callable: Callable):
+ var slot_id = 0
+ if slot is Node:
+ slot_id = slot.get_instance_id()
+ if not slot.tree_exiting.is_connected(_unhook_changed):
+ slot.tree_exiting.connect(_unhook_changed.bind(slot_id), CONNECT_ONE_SHOT)
+ elif slot is String:
+ slot_id = slot.hash()
+ else:
+ push_error("hook_changed called with invalid slot")
+ return
if not change_hooks.has(key): change_hooks[key] = {}
- change_hooks[key][slot] = callable
+ change_hooks[key][slot_id] = callable
+
+static func _unhook_changed(slot_id: int):
+ for key in change_hooks:
+ change_hooks[key].erase(slot_id)
-static func hook_changed_init(key: String, slot: String, callable: Callable):
+# slot: String | Node
+static func hook_changed_init(key: String, slot, callable: Callable):
hook_changed(key, slot, callable)
callable.call(read(key))
@@ -147,18 +164,20 @@ static func get_category_dict(prefix: String):
static func launch_setup():
Global.focused_menu.submenu("res://gui/menus/setup/setup.tscn")
-static var change_hooks = {
- "input": { "static": h_input },
- "graphics.aa": { "static": h_aa },
- "graphics.taa": { "static": h_taa },
- "graphics.fullscreen": { "static": h_fullscreen },
- "ui.scale_mode": { "static": h_scale_mode },
- "ui.scale_factor": { "static": h_scale_factor },
- "ui.language": { "static": h_language },
- "audio.master_volume": { "static": h_volume_master },
- "audio.music_volume": { "static": h_volume_music },
- "audio.sfx_volume": { "static": h_volume_sfx },
-}
+static var change_hooks = {}
+
+static func setup_static_hooks():
+ for action in InputManager.action_list():
+ hook_changed_init("input.%s" % action, "static", InputManager.update_input_map.bind(action))
+ hook_changed_init("graphics.aa", "static", h_aa)
+ hook_changed_init("graphics.taa", "static", h_taa)
+ hook_changed_init("graphics.fullscreen", "static", h_fullscreen)
+ hook_changed_init("ui.scale_mode", "static", h_scale_mode)
+ hook_changed_init("ui.scale_factor", "static", h_scale_factor)
+ hook_changed_init("ui.language", "static", h_language)
+ hook_changed_init("audio.master_volume", "static", h_volume_master)
+ hook_changed_init("audio.music_volume", "static", h_volume_music)
+ hook_changed_init("audio.sfx_volume", "static", h_volume_sfx)
static func h_aa(_mode):
Global.configure_viewport_aa(Global.get_viewport())
@@ -186,9 +205,6 @@ static func h_language(language: String):
if language == "system": language = OS.get_locale_language()
TranslationServer.set_locale(language)
-static func h_input(key: String):
- InputManager.update_input_map(key)
-
static func h_fullscreen(mode: String):
match mode:
"keep": pass
diff --git a/client/system/translation_manager.gd b/client/system/translation_manager.gd
index 9aa374b2..fab5af80 100644
--- a/client/system/translation_manager.gd
+++ b/client/system/translation_manager.gd
@@ -1,5 +1,5 @@
# Hurry Curry! - a game about cooking
-# Copyright (C) 2025 Hurry Curry! contributors
+# Copyright (C) 2026 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
@@ -14,16 +14,17 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
extends Node
+class_name TranslationManager
const LOCALE_PATH := "res://locale/"
-const LOCALE_BOOK_PATH := "res://locale_book/"
const NATIVE_LANGUAGE_NAMES_FILE_NAME := "native_language_names.ini1"
-func _init() -> void:
+static var LOCALE_STATS = {}
+
+static func load_locales() -> void:
# Use english as fallback
var native_language_names := get_ini_dict(NATIVE_LANGUAGE_NAMES_FILE_NAME, LOCALE_PATH)
var fallback_strings := get_ini_dict("en.ini", LOCALE_PATH)
- var fallback_strings_book := get_ini_dict("en.ini", LOCALE_BOOK_PATH)
for file_name in DirAccess.get_files_at(LOCALE_PATH):
if !file_name.ends_with(".ini"):
@@ -31,20 +32,20 @@ func _init() -> void:
var translation := Translation.new()
translation.locale = file_name.trim_suffix(".ini")
- var trans_strings := get_ini_dict(file_name, LOCALE_PATH)
- var trans_book_strings := get_ini_dict(file_name, LOCALE_BOOK_PATH)
+ var strings := get_ini_dict(file_name, LOCALE_PATH)
+ var strings_total = fallback_strings.size()
+ var strings_found = 0
for k in fallback_strings.keys():
- translation.add_message(k, trans_strings[k] if trans_strings.has(k) else fallback_strings[k])
- for k in fallback_strings_book.keys():
- translation.add_message(k, trans_book_strings[k] if trans_book_strings.has(k) else fallback_strings_book[k])
+ translation.add_message(k, strings[k] if strings.has(k) else fallback_strings[k])
+ if strings.has(k): strings_found += 1
for k in native_language_names.keys():
translation.add_message("c.settings.ui.language.%s" % k, native_language_names[k])
-
- TranslationServer.add_translation(translation)
+ LOCALE_STATS[translation.locale] = float(strings_found) / float(strings_total)
+ TranslationServer.add_translation(translation)
-func get_ini_dict(file_name: String, locale_path: String) -> Dictionary: # Dictionary[String, String]
+static func get_ini_dict(file_name: String, locale_path: String) -> Dictionary: # Dictionary[String, String]
var dict := {}
var lines := FileAccess.get_file_as_string(locale_path + file_name).split("\n", false)
if lines.size() > 0:
diff --git a/client/test.tscn b/client/test.tscn
deleted file mode 100644
index 57f7e13a..00000000
--- a/client/test.tscn
+++ /dev/null
@@ -1,30 +0,0 @@
-[gd_scene load_steps=2 format=3 uid="uid://d3cvepu7803x8"]
-
-[sub_resource type="GDScript" id="GDScript_mf4mk"]
-script/source = "extends Button
-
-
-func _on_pressed() -> void:
- if Rect2(Vector2(), size).has_point(get_local_mouse_position()):
- print(\"release\")
- release_focus()
-"
-
-[node name="Control" type="Control"]
-layout_mode = 3
-anchors_preset = 15
-anchor_right = 1.0
-anchor_bottom = 1.0
-grow_horizontal = 2
-grow_vertical = 2
-
-[node name="Button" type="Button" parent="."]
-layout_mode = 0
-offset_left = 590.0
-offset_top = 271.0
-offset_right = 838.0
-offset_bottom = 396.0
-text = "Hello"
-script = SubResource("GDScript_mf4mk")
-
-[connection signal="pressed" from="Button" to="Button" method="_on_pressed"]