Initial commit with existing project files

This commit is contained in:
ChaoticByte 2025-08-06 10:22:38 +02:00
commit 0a39a7772a
No known key found for this signature in database
62 changed files with 1415 additions and 0 deletions

4
.editorconfig Normal file
View file

@ -0,0 +1,4 @@
root = true
[*]
charset = utf-8

2
.gitattributes vendored Normal file
View file

@ -0,0 +1,2 @@
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
# Godot 4+ specific ignores
.godot/
/android/

View file

@ -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

Binary file not shown.

View file

@ -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={}

BIN
assets/icons/CloseIcon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 B

View file

@ -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

BIN
assets/icons/CloseIcon.pxo Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

View file

@ -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

Binary file not shown.

BIN
assets/icons/RemoveIcon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

View file

@ -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

BIN
assets/icons/RemoveIcon.pxo Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 B

View file

@ -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

Binary file not shown.

BIN
assets/icons/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -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

BIN
assets/icons/icon.pxo Normal file

Binary file not shown.

View file

@ -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

BIN
assets/icons/icon_bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 KiB

View file

@ -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

216
export_presets.cfg Normal file
View file

@ -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

42
project.godot Normal file
View file

@ -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

13
resources/button_box.tres Normal file
View file

@ -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)

View file

@ -0,0 +1,4 @@
[gd_resource type="LabelSettings" format=3 uid="uid://cuynmxlj6maig"]
[resource]
font_size = 42

View file

@ -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)

View file

@ -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")

235
scenes/main.tscn Normal file
View file

@ -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"]

92
scenes/phrases_menu.tscn Normal file
View file

@ -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"]

View file

@ -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"]

82
scenes/settings_menu.tscn Normal file
View file

@ -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"]

View file

@ -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()

View file

@ -0,0 +1 @@
uid://rge5rigffdn1

View file

@ -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()

View file

@ -0,0 +1 @@
uid://b55k3utldjthk

View file

@ -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)

View file

@ -0,0 +1 @@
uid://dkhmrcp1txn0j

33
src/global/SaveManager.gd Normal file
View file

@ -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"]

View file

@ -0,0 +1 @@
uid://be87g4fh8faxa

View file

@ -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))

View file

@ -0,0 +1 @@
uid://pa34g1ghwwkc

View file

@ -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);
}

View file

@ -0,0 +1 @@
uid://da36ryj6twm16

9
src/ui/level_counter.gd Normal file
View file

@ -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

View file

@ -0,0 +1 @@
uid://cql88rfja2khm

40
src/ui/main.gd Normal file
View file

@ -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()

1
src/ui/main.gd.uid Normal file
View file

@ -0,0 +1 @@
uid://bga75qw3b2be3

View file

@ -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()

View file

@ -0,0 +1 @@
uid://bue5attfnwbd

13
src/ui/phrases_menu.gd Normal file
View file

@ -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()

View file

@ -0,0 +1 @@
uid://fbgxxich2qgd

View file

@ -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)

View file

@ -0,0 +1 @@
uid://bgb4gukelil6o

9
src/ui/points_counter.gd Normal file
View file

@ -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

View file

@ -0,0 +1 @@
uid://dyh2ejk0r2xeq

View file

@ -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

View file

@ -0,0 +1 @@
uid://b2n6p0wilywoj

12
src/ui/settings_menu.gd Normal file
View file

@ -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.")

View file

@ -0,0 +1 @@
uid://dj4i6sfufsa0t