commit 0a39a7772acd57197dbab6d00779a930eae54715 Author: ChaoticByte Date: Wed Aug 6 10:22:38 2025 +0200 Initial commit with existing project files diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f28239b --- /dev/null +++ b/.editorconfig @@ -0,0 +1,4 @@ +root = true + +[*] +charset = utf-8 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8ad74f7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0af181c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# Godot 4+ specific ignores +.godot/ +/android/ diff --git a/assets/fonts/monogram/credits.txt b/assets/fonts/monogram/credits.txt new file mode 100644 index 0000000..1c053aa --- /dev/null +++ b/assets/fonts/monogram/credits.txt @@ -0,0 +1,15 @@ +# CREDITS + +Monogram is a free and Creative Commons Zero pixel font, +made by Vinícius Menézio (@vmenezio). + +https://datagoblin.itch.io/monogram + + +# SPECIAL THANKS + +thanks to Ateş Göral (@atesgoral) for creating the bitmap font converter: +https://codepen.io/atesgoral/details/RwGOvPZ + +thanks to Éric Araujo (@merwok_) for the inital port of monogram to PICO-8: +https://itch.io/post/2625522 \ No newline at end of file diff --git a/assets/fonts/monogram/monogram-extended.ttf b/assets/fonts/monogram/monogram-extended.ttf new file mode 100644 index 0000000..e1debf0 Binary files /dev/null and b/assets/fonts/monogram/monogram-extended.ttf differ diff --git a/assets/fonts/monogram/monogram-extended.ttf.import b/assets/fonts/monogram/monogram-extended.ttf.import new file mode 100644 index 0000000..fb36945 --- /dev/null +++ b/assets/fonts/monogram/monogram-extended.ttf.import @@ -0,0 +1,40 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://cfghoopnpsdsf" +path="res://.godot/imported/monogram-extended.ttf-56ae86f9f5736fb4eef35cc80a7635a8.fontdata" + +[deps] + +source_file="res://assets/fonts/monogram/monogram-extended.ttf" +dest_files=["res://.godot/imported/monogram-extended.ttf-56ae86f9f5736fb4eef35cc80a7635a8.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +hinting=1 +subpixel_positioning=4 +keep_rounding_remainders=true +oversampling=10.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[{ +"chars": [], +"glyphs": [], +"name": "New Configuration", +"size": Vector2i(16, 0) +}] +language_support={} +script_support={} +opentype_features={} diff --git a/assets/icons/CloseIcon.png b/assets/icons/CloseIcon.png new file mode 100644 index 0000000..9371d87 Binary files /dev/null and b/assets/icons/CloseIcon.png differ diff --git a/assets/icons/CloseIcon.png.import b/assets/icons/CloseIcon.png.import new file mode 100644 index 0000000..d2d66cb --- /dev/null +++ b/assets/icons/CloseIcon.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cbv7fmq2x6ucf" +path="res://.godot/imported/CloseIcon.png-b75d96efeff44030f114fd8cab0b66cc.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/icons/CloseIcon.png" +dest_files=["res://.godot/imported/CloseIcon.png-b75d96efeff44030f114fd8cab0b66cc.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/icons/CloseIcon.pxo b/assets/icons/CloseIcon.pxo new file mode 100644 index 0000000..ff3f670 Binary files /dev/null and b/assets/icons/CloseIcon.pxo differ diff --git a/assets/icons/PhrasesIcon.png b/assets/icons/PhrasesIcon.png new file mode 100644 index 0000000..2ee30b6 Binary files /dev/null and b/assets/icons/PhrasesIcon.png differ diff --git a/assets/icons/PhrasesIcon.png.import b/assets/icons/PhrasesIcon.png.import new file mode 100644 index 0000000..c92b868 --- /dev/null +++ b/assets/icons/PhrasesIcon.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://doin43i42hl82" +path="res://.godot/imported/PhrasesIcon.png-92c73302694a949aebc9f90a7fb0746c.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/icons/PhrasesIcon.png" +dest_files=["res://.godot/imported/PhrasesIcon.png-92c73302694a949aebc9f90a7fb0746c.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/icons/PhrasesIcon.pxo b/assets/icons/PhrasesIcon.pxo new file mode 100644 index 0000000..ae1eaa6 Binary files /dev/null and b/assets/icons/PhrasesIcon.pxo differ diff --git a/assets/icons/RemoveIcon.png b/assets/icons/RemoveIcon.png new file mode 100644 index 0000000..47c8a8f Binary files /dev/null and b/assets/icons/RemoveIcon.png differ diff --git a/assets/icons/RemoveIcon.png.import b/assets/icons/RemoveIcon.png.import new file mode 100644 index 0000000..1e25865 --- /dev/null +++ b/assets/icons/RemoveIcon.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cdf7kvjxmp6a" +path="res://.godot/imported/RemoveIcon.png-8df13dc96db1300c7fc18053deaf60fe.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/icons/RemoveIcon.png" +dest_files=["res://.godot/imported/RemoveIcon.png-8df13dc96db1300c7fc18053deaf60fe.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/icons/RemoveIcon.pxo b/assets/icons/RemoveIcon.pxo new file mode 100644 index 0000000..42bb8ae Binary files /dev/null and b/assets/icons/RemoveIcon.pxo differ diff --git a/assets/icons/SettingsIcon.png b/assets/icons/SettingsIcon.png new file mode 100644 index 0000000..5fd8b44 Binary files /dev/null and b/assets/icons/SettingsIcon.png differ diff --git a/assets/icons/SettingsIcon.png.import b/assets/icons/SettingsIcon.png.import new file mode 100644 index 0000000..11a66ea --- /dev/null +++ b/assets/icons/SettingsIcon.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://vl26lhjwxmmf" +path="res://.godot/imported/SettingsIcon.png-fa9ac0374a11970d22831483c55947c1.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/icons/SettingsIcon.png" +dest_files=["res://.godot/imported/SettingsIcon.png-fa9ac0374a11970d22831483c55947c1.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/icons/SettingsIcon.pxo b/assets/icons/SettingsIcon.pxo new file mode 100644 index 0000000..ec69e6e Binary files /dev/null and b/assets/icons/SettingsIcon.pxo differ diff --git a/assets/icons/icon.png b/assets/icons/icon.png new file mode 100644 index 0000000..2bb9a04 Binary files /dev/null and b/assets/icons/icon.png differ diff --git a/assets/icons/icon.png.import b/assets/icons/icon.png.import new file mode 100644 index 0000000..e949a47 --- /dev/null +++ b/assets/icons/icon.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://020ibqgo0y3m" +path="res://.godot/imported/icon.png-816117353ba57afc3af521f78eedcc3c.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/icons/icon.png" +dest_files=["res://.godot/imported/icon.png-816117353ba57afc3af521f78eedcc3c.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/icons/icon.pxo b/assets/icons/icon.pxo new file mode 100644 index 0000000..2889f75 Binary files /dev/null and b/assets/icons/icon.pxo differ diff --git a/assets/icons/icon.svg.import b/assets/icons/icon.svg.import new file mode 100644 index 0000000..61c8eaa --- /dev/null +++ b/assets/icons/icon.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://j7n2kpuwt04v" +path="res://.godot/imported/icon.svg-7c8e6dfe2213e2029f33175ecfc9166b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/icons/icon.svg" +dest_files=["res://.godot/imported/icon.svg-7c8e6dfe2213e2029f33175ecfc9166b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/assets/icons/icon_bg.png b/assets/icons/icon_bg.png new file mode 100644 index 0000000..136235c Binary files /dev/null and b/assets/icons/icon_bg.png differ diff --git a/assets/icons/icon_bg.png.import b/assets/icons/icon_bg.png.import new file mode 100644 index 0000000..f3aadad --- /dev/null +++ b/assets/icons/icon_bg.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cma2jcuhcs0g" +path="res://.godot/imported/icon_bg.png-966040e9004d7b7ef96822c2010a941b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/icons/icon_bg.png" +dest_files=["res://.godot/imported/icon_bg.png-966040e9004d7b7ef96822c2010a941b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/export_presets.cfg b/export_presets.cfg new file mode 100644 index 0000000..a0a2f90 --- /dev/null +++ b/export_presets.cfg @@ -0,0 +1,216 @@ +[preset.0] + +name="Android" +platform="Android" +runnable=true +advanced_options=false +dedicated_server=false +custom_features="" +export_filter="all_resources" +include_filter="" +exclude_filter="" +export_path="./Repeat After Me.apk" +patches=PackedStringArray() +encryption_include_filters="" +encryption_exclude_filters="" +seed=0 +encrypt_pck=false +encrypt_directory=false +script_export_mode=2 + +[preset.0.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="" +architectures/armeabi-v7a=false +architectures/arm64-v8a=true +architectures/x86=false +architectures/x86_64=false +version/code=1 +version/name="" +package/unique_name="net.chaoticbyte.repeatafterme" +package/name="" +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="uid://020ibqgo0y3m" +launcher_icons/adaptive_foreground_432x432="uid://020ibqgo0y3m" +launcher_icons/adaptive_background_432x432="uid://cma2jcuhcs0g" +launcher_icons/adaptive_monochrome_432x432="uid://020ibqgo0y3m" +graphics/opengl_debug=false +xr_features/xr_mode=0 +gesture/swipe_to_dismiss=false +screen/immersive_mode=true +screen/support_small=true +screen/support_normal=true +screen/support_large=true +screen/support_xlarge=true +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=false +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/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=false +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 diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..3378ee4 --- /dev/null +++ b/project.godot @@ -0,0 +1,42 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="Repeat After Me" +config/version="0.1.0" +run/main_scene="uid://cv38ubwerjlpx" +config/features=PackedStringArray("4.4", "Mobile") +boot_splash/bg_color=Color(0.0562916, 0.0562916, 0.0562916, 1) +boot_splash/image="uid://020ibqgo0y3m" +config/icon="uid://020ibqgo0y3m" + +[autoload] + +NotificationQueue="*res://src/global/NotificationQueue.gd" +XpLevelManager="*res://src/global/XpLevelManager.gd" +PhrasesManager="*res://src/global/PhrasesManager.gd" +CoreGameplayManager="*res://src/global/CoreGameplayManager.gd" +SaveManager="*res://src/global/SaveManager.gd" + +[display] + +window/size/viewport_width=256 +window/size/viewport_height=480 +window/stretch/mode="canvas_items" +window/stretch/aspect="expand" +window/handheld/orientation=1 + +[rendering] + +textures/canvas_textures/default_texture_filter=0 +renderer/rendering_method="mobile" +textures/vram_compression/import_etc2_astc=true +anti_aliasing/quality/msaa_2d=1 diff --git a/resources/button_box.tres b/resources/button_box.tres new file mode 100644 index 0000000..c790435 --- /dev/null +++ b/resources/button_box.tres @@ -0,0 +1,13 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://bv8sh5kxswy5"] + +[resource] +content_margin_left = 8.0 +content_margin_top = 1.0 +content_margin_right = 8.0 +content_margin_bottom = 2.0 +bg_color = Color(1, 1, 1, 0) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(1, 1, 1, 1) diff --git a/resources/level_label_settings.tres b/resources/level_label_settings.tres new file mode 100644 index 0000000..230935d --- /dev/null +++ b/resources/level_label_settings.tres @@ -0,0 +1,4 @@ +[gd_resource type="LabelSettings" format=3 uid="uid://cuynmxlj6maig"] + +[resource] +font_size = 42 diff --git a/resources/line_edit_box.tres b/resources/line_edit_box.tres new file mode 100644 index 0000000..7385e4b --- /dev/null +++ b/resources/line_edit_box.tres @@ -0,0 +1,9 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://3j2rdpeh0hbi"] + +[resource] +content_margin_left = 2.0 +content_margin_right = 2.0 +content_margin_bottom = 0.0 +bg_color = Color(1, 1, 1, 0) +border_width_bottom = 1 +border_color = Color(1, 1, 1, 0.698039) diff --git a/resources/main_theme_overrides.tres b/resources/main_theme_overrides.tres new file mode 100644 index 0000000..58ffd75 --- /dev/null +++ b/resources/main_theme_overrides.tres @@ -0,0 +1,49 @@ +[gd_resource type="Theme" load_steps=10 format=3 uid="uid://06umghrsjedx"] + +[ext_resource type="StyleBox" uid="uid://bv8sh5kxswy5" path="res://resources/button_box.tres" id="1_wpqen"] +[ext_resource type="StyleBox" uid="uid://3j2rdpeh0hbi" path="res://resources/line_edit_box.tres" id="2_u8fmd"] +[ext_resource type="FontFile" uid="uid://cfghoopnpsdsf" path="res://assets/fonts/monogram/monogram-extended.ttf" id="3_u8fmd"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_8p56c"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_b1161"] +bg_color = Color(1, 1, 1, 0.552941) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_wpqen"] +bg_color = Color(1, 1, 1, 0.552941) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_u8fmd"] +bg_color = Color(1, 1, 1, 0.552941) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_8p56c"] +border_width_left = 1 +border_width_right = 1 +border_color = Color(1, 1, 1, 0.113725) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_8kqed"] +border_width_left = 2 +border_width_right = 2 +border_color = Color(1, 1, 1, 0.113725) + +[resource] +default_font = ExtResource("3_u8fmd") +default_font_size = 20 +Button/colors/font_color = Color(1, 1, 1, 1) +Button/colors/font_focus_color = Color(1, 1, 1, 1) +Button/colors/font_hover_color = Color(1, 1, 1, 1) +Button/colors/font_hover_pressed_color = Color(1, 1, 1, 1) +Button/colors/font_pressed_color = Color(1, 1, 1, 1) +Button/styles/disabled = ExtResource("1_wpqen") +Button/styles/focus = ExtResource("1_wpqen") +Button/styles/hover = ExtResource("1_wpqen") +Button/styles/hover_pressed = ExtResource("1_wpqen") +Button/styles/normal = ExtResource("1_wpqen") +Button/styles/pressed = ExtResource("1_wpqen") +LineEdit/styles/focus = ExtResource("2_u8fmd") +LineEdit/styles/normal = ExtResource("2_u8fmd") +LineEdit/styles/read_only = SubResource("StyleBoxEmpty_8p56c") +VScrollBar/styles/grabber = SubResource("StyleBoxFlat_b1161") +VScrollBar/styles/grabber_highlight = SubResource("StyleBoxFlat_wpqen") +VScrollBar/styles/grabber_pressed = SubResource("StyleBoxFlat_u8fmd") +VScrollBar/styles/scroll = SubResource("StyleBoxFlat_8p56c") +VScrollBar/styles/scroll_focus = SubResource("StyleBoxFlat_8kqed") diff --git a/scenes/main.tscn b/scenes/main.tscn new file mode 100644 index 0000000..955c1e5 --- /dev/null +++ b/scenes/main.tscn @@ -0,0 +1,235 @@ +[gd_scene load_steps=18 format=3 uid="uid://cv38ubwerjlpx"] + +[ext_resource type="Script" uid="uid://bga75qw3b2be3" path="res://src/ui/main.gd" id="1_tipki"] +[ext_resource type="Theme" uid="uid://06umghrsjedx" path="res://resources/main_theme_overrides.tres" id="1_ya4ey"] +[ext_resource type="Script" uid="uid://dyh2ejk0r2xeq" path="res://src/ui/points_counter.gd" id="3_choun"] +[ext_resource type="Script" uid="uid://b2n6p0wilywoj" path="res://src/ui/required_points_counter.gd" id="6_85g3d"] +[ext_resource type="LabelSettings" uid="uid://cuynmxlj6maig" path="res://resources/level_label_settings.tres" id="7_a8y0u"] +[ext_resource type="PackedScene" uid="uid://dq3jysvuu7ix" path="res://scenes/settings_menu.tscn" id="8_85g3d"] +[ext_resource type="Texture2D" uid="uid://doin43i42hl82" path="res://assets/icons/PhrasesIcon.png" id="8_choun"] +[ext_resource type="Script" uid="uid://cql88rfja2khm" path="res://src/ui/level_counter.gd" id="8_jkv2x"] +[ext_resource type="Texture2D" uid="uid://vl26lhjwxmmf" path="res://assets/icons/SettingsIcon.png" id="9_choun"] +[ext_resource type="PackedScene" uid="uid://bqgcsf0855xq" path="res://scenes/phrases_menu.tscn" id="9_ya4ey"] +[ext_resource type="Script" uid="uid://bue5attfnwbd" path="res://src/ui/notification_container.gd" id="11_ya4ey"] + +[sub_resource type="Gradient" id="Gradient_ig7tw"] +interpolation_mode = 2 +interpolation_color_space = 2 +offsets = PackedFloat32Array(0, 0.598881, 0.880597, 0.979478) +colors = PackedColorArray(0.0181584, 0.00862847, 0.0428164, 1, 0.261449, 0.130655, 0.405365, 1, 0.707783, 0.30943, 0.382465, 1, 0.893104, 0.621238, 0.575639, 1) + +[sub_resource type="GradientTexture2D" id="GradientTexture2D_0xm2m"] +gradient = SubResource("Gradient_ig7tw") +width = 640 +height = 640 +fill = 1 +fill_from = Vector2(0.491453, 1) +fill_to = Vector2(0, 0.00854701) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_eb6dy"] + +[sub_resource type="LabelSettings" id="LabelSettings_ya4ey"] +font_color = Color(1, 1, 1, 0.792157) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ya4ey"] +content_margin_left = 10.0 +content_margin_top = 4.0 +content_margin_right = 10.0 +content_margin_bottom = 4.0 +bg_color = Color(1, 1, 1, 0.32549) + +[sub_resource type="LabelSettings" id="LabelSettings_eb6dy"] +font_size = 18 + +[node name="Main" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("1_ya4ey") +script = ExtResource("1_tipki") + +[node name="BackgroundTexture" type="TextureRect" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -96.0 +offset_top = -24.0 +offset_right = 288.0 +offset_bottom = 48.0 +grow_horizontal = 2 +grow_vertical = 2 +texture = SubResource("GradientTexture2D_0xm2m") +expand_mode = 1 + +[node name="ShowSettingsButton" type="TextureButton" parent="."] +texture_filter = 1 +layout_mode = 1 +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -36.0 +offset_top = 12.0 +offset_right = -8.0 +offset_bottom = 40.0 +grow_horizontal = 0 +texture_normal = ExtResource("9_choun") +stretch_mode = 0 + +[node name="ShowPhrasesButton" type="TextureButton" parent="."] +texture_filter = 1 +layout_mode = 1 +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -68.0 +offset_top = 12.0 +offset_right = -47.0 +offset_bottom = 40.0 +grow_horizontal = 0 +texture_normal = ExtResource("8_choun") +stretch_mode = 5 + +[node name="XpLevelsVBoxContainer" type="VBoxContainer" parent="."] +layout_mode = 2 +anchor_right = 1.0 +offset_left = 16.0 +offset_top = 64.0 +offset_right = -16.0 +offset_bottom = 152.0 +theme_override_constants/separation = 8 +alignment = 1 + +[node name="LevelHBoxContainer" type="HBoxContainer" parent="XpLevelsVBoxContainer"] +layout_mode = 2 +theme_override_constants/separation = 12 +alignment = 1 + +[node name="LevelLabel" type="Label" parent="XpLevelsVBoxContainer/LevelHBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 0 +text = "Level" +label_settings = ExtResource("7_a8y0u") + +[node name="LevelCounter" type="Label" parent="XpLevelsVBoxContainer/LevelHBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 8 +text = "0" +label_settings = ExtResource("7_a8y0u") +script = ExtResource("8_jkv2x") + +[node name="XpHBoxContainer" type="HBoxContainer" parent="XpLevelsVBoxContainer"] +layout_mode = 2 +theme_override_constants/separation = 5 +alignment = 1 + +[node name="PointsCounter" type="Label" parent="XpLevelsVBoxContainer/XpHBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 8 +text = "0" +script = ExtResource("3_choun") + +[node name="Label" type="Label" parent="XpLevelsVBoxContainer/XpHBoxContainer"] +layout_mode = 2 +text = "/" + +[node name="RequiredPointsCounter" type="Label" parent="XpLevelsVBoxContainer/XpHBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 8 +text = "0" +script = ExtResource("6_85g3d") + +[node name="PointsLabel" type="Label" parent="XpLevelsVBoxContainer/XpHBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 0 +text = "XP" + +[node name="PhrasesDisplayVBoxContainer" type="VBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = -1 +anchor_right = 1.0 +offset_left = 16.0 +offset_top = 168.0 +offset_right = -16.0 +offset_bottom = 280.0 +grow_horizontal = 2 +theme_override_constants/separation = 12 + +[node name="CurrentPhrase" type="RichTextLabel" parent="PhrasesDisplayVBoxContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(0, 56) +layout_mode = 2 +theme_override_font_sizes/normal_font_size = 22 +theme_override_styles/background = SubResource("StyleBoxFlat_eb6dy") +horizontal_alignment = 1 +vertical_alignment = 2 + +[node name="CurrentStatus" type="Label" parent="PhrasesDisplayVBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +label_settings = SubResource("LabelSettings_ya4ey") +horizontal_alignment = 1 + +[node name="AnswerInput" type="LineEdit" parent="."] +unique_name_in_owner = true +layout_mode = 2 +anchor_right = 1.0 +offset_left = 40.0 +offset_top = 296.0 +offset_right = -40.0 +offset_bottom = 320.0 +alignment = 1 +keep_editing_on_text_submit = true + +[node name="SubmitButton" type="Button" parent="."] +unique_name_in_owner = true +layout_mode = 2 +anchor_left = 0.5 +anchor_right = 0.5 +offset_left = -40.0 +offset_top = 344.0 +offset_right = 40.0 +offset_bottom = 376.0 +text = "Submit" + +[node name="SettingsMenu" parent="." instance=ExtResource("8_85g3d")] +unique_name_in_owner = true +visible = false +layout_mode = 1 + +[node name="PhrasesMenu" parent="." instance=ExtResource("9_ya4ey")] +unique_name_in_owner = true +visible = false +layout_mode = 1 + +[node name="NotificationContainer" type="PanelContainer" parent="."] +layout_mode = 1 +anchors_preset = 7 +anchor_left = 0.5 +anchor_top = 1.0 +anchor_right = 0.5 +anchor_bottom = 1.0 +offset_left = -32.0 +offset_top = -56.0 +offset_right = 32.0 +offset_bottom = -33.7 +grow_horizontal = 2 +grow_vertical = 0 +theme_override_styles/panel = SubResource("StyleBoxFlat_ya4ey") +script = ExtResource("11_ya4ey") + +[node name="Label" type="Label" parent="NotificationContainer"] +layout_mode = 2 +size_flags_horizontal = 4 +text = "......" +label_settings = SubResource("LabelSettings_eb6dy") +horizontal_alignment = 1 +vertical_alignment = 1 + +[connection signal="pressed" from="ShowSettingsButton" to="." method="_on_settings_button_pressed"] +[connection signal="pressed" from="ShowPhrasesButton" to="." method="_on_show_phrases_button_pressed"] +[connection signal="text_changed" from="AnswerInput" to="." method="_on_answer_input_text_changed"] +[connection signal="pressed" from="SubmitButton" to="." method="_on_submit_button_pressed"] diff --git a/scenes/phrases_menu.tscn b/scenes/phrases_menu.tscn new file mode 100644 index 0000000..17ed404 --- /dev/null +++ b/scenes/phrases_menu.tscn @@ -0,0 +1,92 @@ +[gd_scene load_steps=9 format=3 uid="uid://bqgcsf0855xq"] + +[ext_resource type="Shader" uid="uid://da36ryj6twm16" path="res://src/shaders/panel.gdshader" id="1_wplh1"] +[ext_resource type="Script" uid="uid://fbgxxich2qgd" path="res://src/ui/phrases_menu.gd" id="2_2b2sm"] +[ext_resource type="Theme" uid="uid://06umghrsjedx" path="res://resources/main_theme_overrides.tres" id="2_3hct6"] +[ext_resource type="Texture2D" uid="uid://cbv7fmq2x6ucf" path="res://assets/icons/CloseIcon.png" id="3_3hct6"] + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_choun"] +shader = ExtResource("1_wplh1") + +[sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_85g3d"] + +[sub_resource type="StyleBoxTexture" id="StyleBoxTexture_choun"] +texture = SubResource("PlaceholderTexture2D_85g3d") + +[sub_resource type="LabelSettings" id="LabelSettings_ya4ey"] +font_size = 24 + +[node name="PhrasesMenu" type="Panel"] +material = SubResource("ShaderMaterial_choun") +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("2_3hct6") +theme_override_styles/panel = SubResource("StyleBoxTexture_choun") +script = ExtResource("2_2b2sm") + +[node name="ClosePhrasesButton" type="TextureButton" parent="."] +layout_mode = 1 +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -32.0 +offset_top = 16.0 +offset_right = -12.0 +offset_bottom = 36.0 +grow_horizontal = 0 +texture_normal = ExtResource("3_3hct6") +stretch_mode = 0 + +[node name="Label" type="Label" parent="."] +layout_mode = 0 +offset_left = 16.0 +offset_top = 16.0 +offset_right = 79.0 +offset_bottom = 40.0 +text = "Phrases" +label_settings = SubResource("LabelSettings_ya4ey") + +[node name="LineEdit" type="LineEdit" parent="."] +layout_mode = 1 +anchors_preset = -1 +offset_left = 16.0 +offset_top = 56.0 +offset_right = 184.0 +offset_bottom = 75.0 +keep_editing_on_text_submit = true + +[node name="AddPhraseButton" type="Button" parent="."] +layout_mode = 1 +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -56.0 +offset_top = 56.0 +offset_right = -17.0 +offset_bottom = 75.0 +grow_horizontal = 0 +text = "Add" + +[node name="ScrollContainer" type="ScrollContainer" parent="."] +layout_mode = 1 +anchors_preset = -1 +anchor_top = 0.183 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = 16.0 +offset_top = 8.16 +offset_right = -8.0 +offset_bottom = -22.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="PhrasesList" type="VBoxContainer" parent="ScrollContainer"] +unique_name_in_owner = true +layout_mode = 2 +theme_override_constants/separation = 12 + +[connection signal="pressed" from="ClosePhrasesButton" to="." method="_on_close_phrases_button_pressed"] +[connection signal="pressed" from="AddPhraseButton" to="." method="_on_add_phrase_button_pressed"] diff --git a/scenes/phrases_menu_single_phrase.tscn b/scenes/phrases_menu_single_phrase.tscn new file mode 100644 index 0000000..4acdf84 --- /dev/null +++ b/scenes/phrases_menu_single_phrase.tscn @@ -0,0 +1,35 @@ +[gd_scene load_steps=4 format=3 uid="uid://b6hmd8gv7m2tv"] + +[ext_resource type="Script" uid="uid://bgb4gukelil6o" path="res://src/ui/phrases_menu_phrase.gd" id="1_6l37r"] +[ext_resource type="Theme" uid="uid://06umghrsjedx" path="res://resources/main_theme_overrides.tres" id="1_vmoog"] +[ext_resource type="Texture2D" uid="uid://cdf7kvjxmp6a" path="res://assets/icons/RemoveIcon.png" id="2_cv30m"] + +[node name="Phrase" type="Control"] +custom_minimum_size = Vector2(208, 16) +layout_mode = 3 +anchors_preset = 0 +offset_right = 224.0 +offset_bottom = 16.0 +theme = ExtResource("1_vmoog") +script = ExtResource("1_6l37r") + +[node name="Label" type="Label" parent="."] +layout_mode = 1 +anchors_preset = -1 +anchor_right = 1.143 +offset_right = -48.032 +offset_bottom = 16.0 +clip_text = true +text_overrun_behavior = 3 + +[node name="RemoveButton" type="TextureButton" parent="."] +layout_mode = 2 +anchor_left = 1.036 +anchor_right = 1.036 +offset_left = -16.064 +offset_right = -0.0639954 +offset_bottom = 16.0 +texture_normal = ExtResource("2_cv30m") +stretch_mode = 0 + +[connection signal="pressed" from="RemoveButton" to="." method="_on_remove_button_pressed"] diff --git a/scenes/settings_menu.tscn b/scenes/settings_menu.tscn new file mode 100644 index 0000000..e59260e --- /dev/null +++ b/scenes/settings_menu.tscn @@ -0,0 +1,82 @@ +[gd_scene load_steps=10 format=3 uid="uid://dq3jysvuu7ix"] + +[ext_resource type="Shader" uid="uid://da36ryj6twm16" path="res://src/shaders/panel.gdshader" id="1_cr101"] +[ext_resource type="Script" uid="uid://dj4i6sfufsa0t" path="res://src/ui/settings_menu.gd" id="2_labj1"] +[ext_resource type="Theme" uid="uid://06umghrsjedx" path="res://resources/main_theme_overrides.tres" id="2_lwwgp"] +[ext_resource type="Texture2D" uid="uid://cbv7fmq2x6ucf" path="res://assets/icons/CloseIcon.png" id="2_wswnh"] + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_choun"] +shader = ExtResource("1_cr101") + +[sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_85g3d"] + +[sub_resource type="StyleBoxTexture" id="StyleBoxTexture_choun"] +texture = SubResource("PlaceholderTexture2D_85g3d") + +[sub_resource type="LabelSettings" id="LabelSettings_labj1"] +font_size = 24 + +[sub_resource type="LabelSettings" id="LabelSettings_lwwgp"] +font_color = Color(1, 1, 1, 0.768627) + +[node name="SettingsMenu" type="Panel"] +material = SubResource("ShaderMaterial_choun") +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("2_lwwgp") +theme_override_styles/panel = SubResource("StyleBoxTexture_choun") +script = ExtResource("2_labj1") + +[node name="CloseSettingsButton" type="TextureButton" parent="."] +layout_mode = 1 +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -32.0 +offset_top = 16.0 +offset_right = -12.0 +offset_bottom = 36.0 +grow_horizontal = 0 +texture_normal = ExtResource("2_wswnh") +stretch_mode = 0 + +[node name="Label" type="Label" parent="."] +layout_mode = 0 +offset_left = 16.0 +offset_top = 16.0 +offset_right = 104.0 +offset_bottom = 39.0 +text = "Settings" +label_settings = SubResource("LabelSettings_labj1") + +[node name="ResetXPButton" type="Button" parent="."] +layout_mode = 0 +offset_left = 16.0 +offset_top = 72.0 +offset_right = 92.0 +offset_bottom = 96.0 +text = "Reset XP" + +[node name="by" type="Label" parent="."] +layout_mode = 1 +anchors_preset = 3 +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -168.0 +offset_top = -24.0 +offset_right = -10.0 +offset_bottom = -8.10001 +grow_horizontal = 0 +grow_vertical = 0 +text = "a game by ChaoticByte" +label_settings = SubResource("LabelSettings_lwwgp") +horizontal_alignment = 2 +vertical_alignment = 2 + +[connection signal="pressed" from="CloseSettingsButton" to="." method="_on_close_settings_button_pressed"] +[connection signal="pressed" from="ResetXPButton" to="." method="_on_reset_xp_button_pressed"] diff --git a/src/global/CoreGameplayManager.gd b/src/global/CoreGameplayManager.gd new file mode 100644 index 0000000..2a14529 --- /dev/null +++ b/src/global/CoreGameplayManager.gd @@ -0,0 +1,72 @@ +extends Node + +const XP_PER_ANSWER = 2 + +# interval for automatically cleaning +# the last_played_phrases dictionary +const AUTOCLEAN_INTERVAL = 2000 # in ms + +const STATUS_PLEASE_REPEAT = "please repeat the above phrase" +const STATUS_NONE_AVAILABLE = "no phrase available" + +var _last_autocleanup: int = 0 # ms since engine start + +var current_phrase: String = "" +var current_status: String = "" + +var last_played_phrases: Dictionary = {} # p: [timestamp1, timestamp2, ...] + + +func register_current_phrase_played(): + var t = Time.get_unix_time_from_system() + if current_phrase in last_played_phrases: + last_played_phrases[current_phrase].append(t) + else: + last_played_phrases[current_phrase] = [t] + SaveManager.save_game() + +func answer(p_in: String) -> bool: + if p_in.to_lower() == current_phrase.to_lower(): + XpLevelManager.add_xp(XP_PER_ANSWER) + register_current_phrase_played() + next_phrase() + return true + return false + +func next_phrase() -> void: + if len(PhrasesManager.phrases) < 1: + current_phrase = "" + current_status = STATUS_NONE_AVAILABLE + return + # search for a non played phrase + for p in PhrasesManager.phrases: + if not p in last_played_phrases: + current_phrase = p + current_status = STATUS_PLEASE_REPEAT + return + # find the phrase that was played the longest ago + var phrases_last_ts: Dictionary = {} # timestamp: phrase + var phrases_last_ts_keys: Array[float] = [] + for p in last_played_phrases: + if p in PhrasesManager.phrases: + var t_max = last_played_phrases[p].max() + phrases_last_ts[t_max] = p + phrases_last_ts_keys.append(t_max) + # return the phrase with the smallest timestamp (-> longest ago) + current_phrase = phrases_last_ts[phrases_last_ts_keys.min()] + current_status = STATUS_PLEASE_REPEAT + +func cleanup_last_played_phrases(): + var changed = false + # remove phrases that don't exist anymore + for p in last_played_phrases: + if not p in PhrasesManager.phrases: + last_played_phrases.erase(p) + changed = true + if changed: + SaveManager.save_game() + +func _process(_delta: float) -> void: + if Time.get_ticks_msec() - _last_autocleanup > AUTOCLEAN_INTERVAL: + cleanup_last_played_phrases() + _last_autocleanup = Time.get_ticks_msec() diff --git a/src/global/CoreGameplayManager.gd.uid b/src/global/CoreGameplayManager.gd.uid new file mode 100644 index 0000000..13e030f --- /dev/null +++ b/src/global/CoreGameplayManager.gd.uid @@ -0,0 +1 @@ +uid://rge5rigffdn1 diff --git a/src/global/NotificationQueue.gd b/src/global/NotificationQueue.gd new file mode 100644 index 0000000..9bc663e --- /dev/null +++ b/src/global/NotificationQueue.gd @@ -0,0 +1,12 @@ +extends Node + +var _queue: Array = [] # [] + +func add(n: String, timeout_ms: int = 3000): + # clamp timeout to 0.5s-30s + timeout_ms = clamp(timeout_ms, 500, 30_000) + if len(n) > 0: + _queue.append([n, timeout_ms]) + +func get_next(): # returns either String or Nil + return _queue.pop_front() diff --git a/src/global/NotificationQueue.gd.uid b/src/global/NotificationQueue.gd.uid new file mode 100644 index 0000000..a2fa7fa --- /dev/null +++ b/src/global/NotificationQueue.gd.uid @@ -0,0 +1 @@ +uid://b55k3utldjthk diff --git a/src/global/PhrasesManager.gd b/src/global/PhrasesManager.gd new file mode 100644 index 0000000..dc0f534 --- /dev/null +++ b/src/global/PhrasesManager.gd @@ -0,0 +1,34 @@ +extends Node + +var phrase_scene = preload("uid://b6hmd8gv7m2tv") + +var phrases: Array[String] = [] +var phrases_list_node: Control = null + +func add_phrase(p: String) -> bool: + if len(p) > 0: + if not p in phrases: + phrases.append(p) + update_phrases_list_node() + SaveManager.save_game() + if len(phrases) == 1: + # show new phrase if there was none before + CoreGameplayManager.next_phrase() + return true + return false + +func remove_phrase(p: String): + phrases.erase(p) + update_phrases_list_node() + SaveManager.save_game() + if CoreGameplayManager.current_phrase == p: + CoreGameplayManager.next_phrase() + +func update_phrases_list_node(): + if phrases_list_node != null: + for c in phrases_list_node.get_children(): + c.queue_free() + for p in phrases: + var p_node = phrase_scene.instantiate() + p_node.text = p + phrases_list_node.add_child(p_node) diff --git a/src/global/PhrasesManager.gd.uid b/src/global/PhrasesManager.gd.uid new file mode 100644 index 0000000..ceb3489 --- /dev/null +++ b/src/global/PhrasesManager.gd.uid @@ -0,0 +1 @@ +uid://dkhmrcp1txn0j diff --git a/src/global/SaveManager.gd b/src/global/SaveManager.gd new file mode 100644 index 0000000..e8b979c --- /dev/null +++ b/src/global/SaveManager.gd @@ -0,0 +1,33 @@ +extends Node + +const SAVEFILE = "user://save.dat" + +func _ready() -> void: + load_game() + +func save_game(): + var data: Dictionary = { + "player_xp": XpLevelManager.player_xp, + "phrases": PhrasesManager.phrases, + "last_played_phrases": CoreGameplayManager.last_played_phrases + } + var data_json = JSON.stringify(data) + var f = FileAccess.open(SAVEFILE, FileAccess.WRITE) + f.store_string(data_json) + f.close() + +func load_game(): + if FileAccess.file_exists(SAVEFILE): + var data_json = FileAccess.get_file_as_string(SAVEFILE) + var data = JSON.parse_string(data_json) + # set variables + if "player_xp" in data: + XpLevelManager.loading = true + XpLevelManager.player_xp = data["player_xp"] + XpLevelManager.loading = false + if "phrases" in data and data["phrases"] is Array: + PhrasesManager.phrases = [] + for p in data["phrases"]: + PhrasesManager.phrases.append(p) + if "last_played_phrases" in data and data["last_played_phrases"] is Dictionary: + CoreGameplayManager.last_played_phrases = data["last_played_phrases"] diff --git a/src/global/SaveManager.gd.uid b/src/global/SaveManager.gd.uid new file mode 100644 index 0000000..fa6c408 --- /dev/null +++ b/src/global/SaveManager.gd.uid @@ -0,0 +1 @@ +uid://be87g4fh8faxa diff --git a/src/global/XpLevelManager.gd b/src/global/XpLevelManager.gd new file mode 100644 index 0000000..4bcfbd9 --- /dev/null +++ b/src/global/XpLevelManager.gd @@ -0,0 +1,32 @@ +extends Node + +var player_level: int = 0: + set(v): + player_level = max(0, v) + +var loading: bool = false + +func update_level(): + var level = 0 + while true: # brute-forcing it bc. of precision problems when calculating it + if player_xp < get_required_xp(level + 1): + var old_player_level = player_level + player_level = level + if player_level > old_player_level and not loading: + NotificationQueue.add("Level Up!") + break + level += 1 + +var player_xp: int = 0: + set(v): + player_xp = max(0, v) + update_level() + +func add_xp(additional_xp: int): + player_xp += additional_xp + SaveManager.save_game() # TODO this might be a bit much... + +func get_required_xp(level: int) -> int: + if level == 0: return 0 + var xp = 3 * pow(level, 1.5) + return max(0, int(xp)) diff --git a/src/global/XpLevelManager.gd.uid b/src/global/XpLevelManager.gd.uid new file mode 100644 index 0000000..9ffa882 --- /dev/null +++ b/src/global/XpLevelManager.gd.uid @@ -0,0 +1 @@ +uid://pa34g1ghwwkc diff --git a/src/shaders/panel.gdshader b/src/shaders/panel.gdshader new file mode 100644 index 0000000..cf00b78 --- /dev/null +++ b/src/shaders/panel.gdshader @@ -0,0 +1,8 @@ +shader_type canvas_item; +render_mode unshaded; + +uniform sampler2D screen_texture: hint_screen_texture, filter_linear_mipmap; + +void fragment() { + COLOR = textureLod(screen_texture, SCREEN_UV, 6.0); +} diff --git a/src/shaders/panel.gdshader.uid b/src/shaders/panel.gdshader.uid new file mode 100644 index 0000000..02d24f0 --- /dev/null +++ b/src/shaders/panel.gdshader.uid @@ -0,0 +1 @@ +uid://da36ryj6twm16 diff --git a/src/ui/level_counter.gd b/src/ui/level_counter.gd new file mode 100644 index 0000000..543a303 --- /dev/null +++ b/src/ui/level_counter.gd @@ -0,0 +1,9 @@ +extends Label + +var last_level: int = -1 + +func _process(_delta: float) -> void: + var l = XpLevelManager.player_level + if last_level != l: + self.text = str(l) + last_level = l diff --git a/src/ui/level_counter.gd.uid b/src/ui/level_counter.gd.uid new file mode 100644 index 0000000..95435e7 --- /dev/null +++ b/src/ui/level_counter.gd.uid @@ -0,0 +1 @@ +uid://cql88rfja2khm diff --git a/src/ui/main.gd b/src/ui/main.gd new file mode 100644 index 0000000..04a4f7a --- /dev/null +++ b/src/ui/main.gd @@ -0,0 +1,40 @@ +extends Control + +func _ready() -> void: + CoreGameplayManager.next_phrase() + %SubmitButton.hide() + %AnswerInput.hide() + +func _on_settings_button_pressed() -> void: + %SettingsMenu.show() + +func _on_show_phrases_button_pressed() -> void: + PhrasesManager.update_phrases_list_node() + %PhrasesMenu.show() + +var last_known_phrase: String = "" +var last_known_status: String = "" + +func _process(_delta: float) -> void: + if last_known_phrase != CoreGameplayManager.current_phrase: + last_known_phrase = CoreGameplayManager.current_phrase + if len(last_known_phrase) > 0: + %CurrentPhrase.text = '"' + last_known_phrase + '"' + %AnswerInput.show() + else: + %CurrentPhrase.text = "" + %AnswerInput.hide() + %SubmitButton.hide() + if last_known_status != CoreGameplayManager.current_status: + last_known_status = CoreGameplayManager.current_status + %CurrentStatus.text = last_known_status + +func _on_submit_button_pressed() -> void: + if CoreGameplayManager.answer(%AnswerInput.text): + %AnswerInput.clear() + +func _on_answer_input_text_changed(new_text: String) -> void: + if new_text.to_lower() == CoreGameplayManager.current_phrase.to_lower(): + %SubmitButton.show() + else: + %SubmitButton.hide() diff --git a/src/ui/main.gd.uid b/src/ui/main.gd.uid new file mode 100644 index 0000000..0b74aff --- /dev/null +++ b/src/ui/main.gd.uid @@ -0,0 +1 @@ +uid://bga75qw3b2be3 diff --git a/src/ui/notification_container.gd b/src/ui/notification_container.gd new file mode 100644 index 0000000..ca3c14a --- /dev/null +++ b/src/ui/notification_container.gd @@ -0,0 +1,26 @@ +extends PanelContainer + +var showing_notification: bool = false +var notification_started: int = 0 # in ms +var current_notification_timeout: int = 0 # in ms + +func _ready() -> void: + hide() + +func _process(_delta: float) -> void: + var t = Time.get_ticks_msec() + if showing_notification: + if t - notification_started > current_notification_timeout: + showing_notification = false + else: + var n = NotificationQueue.get_next() # [text, timeout] or null + if n != null: + showing_notification = true + notification_started = t + $Label.text = n[0] + current_notification_timeout = n[1] + # + if not showing_notification and visible: + hide() + elif showing_notification and not visible: + show() diff --git a/src/ui/notification_container.gd.uid b/src/ui/notification_container.gd.uid new file mode 100644 index 0000000..8f3360e --- /dev/null +++ b/src/ui/notification_container.gd.uid @@ -0,0 +1 @@ +uid://bue5attfnwbd diff --git a/src/ui/phrases_menu.gd b/src/ui/phrases_menu.gd new file mode 100644 index 0000000..533883c --- /dev/null +++ b/src/ui/phrases_menu.gd @@ -0,0 +1,13 @@ +extends Control + +func _ready() -> void: + PhrasesManager.phrases_list_node = %PhrasesList + hide() + +func _on_add_phrase_button_pressed() -> void: + var phrase = $LineEdit.text + if PhrasesManager.add_phrase(phrase): + $LineEdit.clear() + +func _on_close_phrases_button_pressed() -> void: + hide() diff --git a/src/ui/phrases_menu.gd.uid b/src/ui/phrases_menu.gd.uid new file mode 100644 index 0000000..5d40426 --- /dev/null +++ b/src/ui/phrases_menu.gd.uid @@ -0,0 +1 @@ +uid://fbgxxich2qgd diff --git a/src/ui/phrases_menu_phrase.gd b/src/ui/phrases_menu_phrase.gd new file mode 100644 index 0000000..01b32e4 --- /dev/null +++ b/src/ui/phrases_menu_phrase.gd @@ -0,0 +1,10 @@ +extends Control + +var text: String: + set(v): + $Label.text = v + get(): + return $Label.text + +func _on_remove_button_pressed() -> void: + PhrasesManager.remove_phrase(text) diff --git a/src/ui/phrases_menu_phrase.gd.uid b/src/ui/phrases_menu_phrase.gd.uid new file mode 100644 index 0000000..e04656f --- /dev/null +++ b/src/ui/phrases_menu_phrase.gd.uid @@ -0,0 +1 @@ +uid://bgb4gukelil6o diff --git a/src/ui/points_counter.gd b/src/ui/points_counter.gd new file mode 100644 index 0000000..ac37f56 --- /dev/null +++ b/src/ui/points_counter.gd @@ -0,0 +1,9 @@ +extends Label + +var last_xp: int = -1 + +func _process(_delta: float) -> void: + var xp = XpLevelManager.player_xp + if last_xp != xp: + self.text = str(xp) + last_xp = xp diff --git a/src/ui/points_counter.gd.uid b/src/ui/points_counter.gd.uid new file mode 100644 index 0000000..eb4281f --- /dev/null +++ b/src/ui/points_counter.gd.uid @@ -0,0 +1 @@ +uid://dyh2ejk0r2xeq diff --git a/src/ui/required_points_counter.gd b/src/ui/required_points_counter.gd new file mode 100644 index 0000000..499e569 --- /dev/null +++ b/src/ui/required_points_counter.gd @@ -0,0 +1,9 @@ +extends Label + +var last_level: int = -1 + +func _process(_delta: float) -> void: + var l = XpLevelManager.player_level + if last_level != l: + self.text = str(XpLevelManager.get_required_xp(l+1)) + last_level = l diff --git a/src/ui/required_points_counter.gd.uid b/src/ui/required_points_counter.gd.uid new file mode 100644 index 0000000..4b8d693 --- /dev/null +++ b/src/ui/required_points_counter.gd.uid @@ -0,0 +1 @@ +uid://b2n6p0wilywoj diff --git a/src/ui/settings_menu.gd b/src/ui/settings_menu.gd new file mode 100644 index 0000000..aa45e01 --- /dev/null +++ b/src/ui/settings_menu.gd @@ -0,0 +1,12 @@ +extends Panel + +func _ready() -> void: + hide() + +func _on_close_settings_button_pressed() -> void: + hide() + +func _on_reset_xp_button_pressed() -> void: + XpLevelManager.player_xp = 0 + SaveManager.save_game() + NotificationQueue.add("Reset XP.") diff --git a/src/ui/settings_menu.gd.uid b/src/ui/settings_menu.gd.uid new file mode 100644 index 0000000..e2adc52 --- /dev/null +++ b/src/ui/settings_menu.gd.uid @@ -0,0 +1 @@ +uid://dj4i6sfufsa0t