Compare commits

..

11 commits
v0.9.2 ... main

58 changed files with 2494 additions and 82 deletions

46
LICENSE Normal file
View file

@ -0,0 +1,46 @@
THE KARKAT PUBLIC LICENSE (KKPL)
Version 2.2, January 2024
Copyright (C) 2023-2024 MeowcaTheoRange
THIS LICENSE GRANTS PERMISSION TO ANY
TROLL, HUMAN, GROUP, OR ANY OTHER
LEGALLY RECOGNIZED ENTITY ("YOU") TO
MODIFY, USE, AND DISTRIBUTE
("SCHMEEVE", "SCHMEEVING") THIS WORK
WITHIN THE DESIRED SCOPE DEFINED BELOW,
AS LONG AS THE KARKAT PUBLIC LICENSE
PERSISTS WITHIN.
BY SCHMEEVING THIS WORK, YOU AGREE TO
BE BOUND BY THIS LICENSE'S TERMS AND
CONDITIONS:
0. YOU WON'T BE A WUSS ABOUT THIS
LICENSE.
1. YOU WILL ONLY SCHMEEVE WITHIN THE
WORK'S DESIRED SCOPE FOR THIS
LICENSE.
2. YOU ACKNOWLEDGE THAT THE DEFINED
SCOPE OF THIS WORK COMES WITH NO
WARRANTY.
3. YOU FROND PROMISE THAT YOU WON'T
SUE IF YOUR COMPUTER EXPLODES
BECAUSE OF THIS PROGRAM.
4. YOU AGREE THAT KARKAT IS THE BEST
HACKER ON ALTERNIA.
5. YOU AGREE THAT BY WRITING IN THE
FORM BELOW, YOU ARE THE RIGHTFUL
OWNER OF THIS WORK.
WHAT PARTS OF THE WORK DOES THIS DAMNED
LICENSE APPLY TO:
All of it
WRITE THE WORK'S NAME HERE:
FunkPanion (v0.9.0-*, November 2024)
WRITE THE NAME(S) OF THE WORK'S
AUTHOR(S) HERE:
MeowcaTheoRange
FUCK FUCK FUCK FUCK FUCK FUCK FUCK.

View file

@ -1,34 +1,14 @@
[remap]
importer="texture"
type="CompressedTexture2D"
importer="image"
type="Image"
uid="uid://b6x537wsl3853"
path="res://.godot/imported/BOYFRIEND.png-39cdb7ee73d5290fc66317ae894c5c49.ctex"
metadata={
"vram_texture": false
}
path="res://.godot/imported/BOYFRIEND.png-39cdb7ee73d5290fc66317ae894c5c49.image"
[deps]
source_file="res://assets/BOYFRIEND.png"
dest_files=["res://.godot/imported/BOYFRIEND.png-39cdb7ee73d5290fc66317ae894c5c49.ctex"]
dest_files=["res://.godot/imported/BOYFRIEND.png-39cdb7ee73d5290fc66317ae894c5c49.image"]
[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.

After

Width:  |  Height:  |  Size: 149 B

View file

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://eudnts7c3nxy"
path="res://.godot/imported/background_checker.png-9bc2f2d6b47432d820b975ab35c9e5e1.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/background_checker.png"
dest_files=["res://.godot/imported/background_checker.png-9bc2f2d6b47432d820b975ab35c9e5e1.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

4
assets/config/bg.tres Normal file
View file

@ -0,0 +1,4 @@
[gd_resource type="StyleBoxFlat" format=3 uid="uid://bdkv45xc5lotp"]
[resource]
bg_color = Color(0.12549, 0.12549, 0.12549, 1)

4
assets/config/bg2.tres Normal file
View file

@ -0,0 +1,4 @@
[gd_resource type="StyleBoxFlat" format=3 uid="uid://bkwb4tqap7x7i"]
[resource]
bg_color = Color(0.188235, 0.188235, 0.188235, 1)

View file

@ -0,0 +1,9 @@
[gd_resource type="LabelSettings" load_steps=2 format=3 uid="uid://55elphqx3dqw"]
[ext_resource type="FontFile" uid="uid://ce5fs0ro7kp8r" path="res://assets/fonts/Lexend.ttf" id="1_3s1q8"]
[resource]
font = ExtResource("1_3s1q8")
font_size = 14
shadow_color = Color(0, 0, 0, 1)
shadow_offset = Vector2(0, 1)

8
assets/config/tiny.tres Normal file
View file

@ -0,0 +1,8 @@
[gd_resource type="LabelSettings" load_steps=2 format=3 uid="uid://xh3q8p65gbti"]
[ext_resource type="FontFile" uid="uid://ce5fs0ro7kp8r" path="res://assets/fonts/Lexend.ttf" id="1_r577y"]
[resource]
font = ExtResource("1_r577y")
font_size = 14
font_color = Color(1, 1, 1, 0.501961)

BIN
assets/icons/arrow_down.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 B

View file

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dbyhyqbmk8nip"
path="res://.godot/imported/arrow_down.png-c93ce13fc34e8f54091b090433da4319.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/icons/arrow_down.png"
dest_files=["res://.godot/imported/arrow_down.png-c93ce13fc34e8f54091b090433da4319.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/arrow_up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 B

View file

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bb6o3ff20sfcr"
path="res://.godot/imported/arrow_up.png-9447ca0e8f31ae4bf4a5d58081e09faa.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/icons/arrow_up.png"
dest_files=["res://.godot/imported/arrow_up.png-9447ca0e8f31ae4bf4a5d58081e09faa.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

13
assets/icons/checker.tres Normal file
View file

@ -0,0 +1,13 @@
[gd_resource type="GradientTexture2D" load_steps=2 format=3 uid="uid://c3sqmkn1m8f8"]
[sub_resource type="Gradient" id="Gradient_7tml3"]
interpolation_mode = 1
offsets = PackedFloat32Array(0, 0.5)
metadata/_snap_enabled = true
[resource]
gradient = SubResource("Gradient_7tml3")
width = 2
height = 2
fill_to = Vector2(1, 1)
repeat = 1

Binary file not shown.

Before

Width:  |  Height:  |  Size: 289 B

After

Width:  |  Height:  |  Size: 436 B

BIN
assets/icons/frame_open.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 B

View file

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dinhxs3byoi3s"
path="res://.godot/imported/frame_open.png-10f0b7b27982187741fba18357825080.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/icons/frame_open.png"
dest_files=["res://.godot/imported/frame_open.png-10f0b7b27982187741fba18357825080.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.

After

Width:  |  Height:  |  Size: 426 B

View file

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c5qf8o3yefmij"
path="res://.godot/imported/frames_open.png-642496cc6c7b46c1d0dd7b48beb9f71b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/icons/frames_open.png"
dest_files=["res://.godot/imported/frames_open.png-642496cc6c7b46c1d0dd7b48beb9f71b.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/preset_use.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 B

View file

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://m546urtgoxrk"
path="res://.godot/imported/preset_use.png-b19662e013e899f02e64516b13961eb7.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/icons/preset_use.png"
dest_files=["res://.godot/imported/preset_use.png-b19662e013e899f02e64516b13961eb7.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

3
assets/test.tres Normal file
View file

@ -0,0 +1,3 @@
[gd_resource type="Image" format=3 uid="uid://s7gvwrccwxv"]
[resource]

13
events/latest_events.xml Normal file
View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<events>
<event id="week_3" date="2024-12-08">
<tagline>FunkPanion Update Week 3</tagline>
<title>Matkap Sprites</title>
<thumb>mk_preview.png</thumb>
<desc>I made these cool-ass sprites of my sona Matkap.
I thought it'd be nice to have him in here, but I didn't want to make him the default because that'd be pretty jarring.
Imagine opening an FNF thingy and then not immediately seeing an FNF character.
So instead I made this panel. Check back here for more goodies, in case I make any.
WARNING: Applying will override some of your config and save.</desc>
</event>
</events>

BIN
events/week_3/matkap.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 KiB

View file

@ -0,0 +1,3 @@
[remap]
importer="keep"

33
events/week_3/matkap.xml Normal file
View file

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<TextureAtlas imagePath="C:/Users/Theo Range/Downloads/fnfanims/matkap.png">
<SubTexture name="MAT_IDLE0000" x="0" y="0" width="462" height="575" frameX="-9" frameY="0" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_IDLE0001" x="462" y="0" width="462" height="574" frameX="-9" frameY="-1" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_IDLE0002" x="924" y="0" width="466" height="573" frameX="-9" frameY="-2" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_IDLE0003" x="1390" y="0" width="463" height="574" frameX="-9" frameY="-1" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_IDLE0004" x="1390" y="0" width="463" height="574" frameX="-9" frameY="-1" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_IDLE0005" x="1390" y="0" width="463" height="574" frameX="-9" frameY="-1" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_LEFT0000" x="0" y="575" width="411" height="538" frameX="-54" frameY="-35" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_LEFT0001" x="411" y="574" width="413" height="541" frameX="-57" frameY="-32" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_LEFT0002" x="824" y="575" width="413" height="540" frameX="-59" frameY="-33" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_LEFT0003" x="1237" y="575" width="413" height="540" frameX="-59" frameY="-33" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_LEFT0004" x="1237" y="575" width="413" height="540" frameX="-59" frameY="-33" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_LEFT0005" x="1237" y="575" width="413" height="540" frameX="-59" frameY="-33" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_DOWN0000" x="0" y="1115" width="380" height="481" frameX="-43" frameY="-94" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_DOWN0001" x="380" y="1115" width="380" height="489" frameX="-43" frameY="-86" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_DOWN0002" x="760" y="1115" width="380" height="487" frameX="-43" frameY="-88" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_DOWN0003" x="1140" y="1115" width="380" height="487" frameX="-43" frameY="-88" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_DOWN0004" x="1140" y="1115" width="380" height="487" frameX="-43" frameY="-88" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_DOWN0005" x="1140" y="1115" width="380" height="487" frameX="-43" frameY="-88" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_UP0000" x="0" y="1604" width="425" height="574" frameX="0" frameY="-2" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_UP0001" x="425" y="1604" width="422" height="569" frameX="0" frameY="-10" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_UP0002" x="847" y="1604" width="422" height="574" frameX="0" frameY="-8" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_UP0003" x="1269" y="1604" width="422" height="574" frameX="0" frameY="-8" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_UP0004" x="1269" y="1604" width="422" height="574" frameX="0" frameY="-8" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_UP0005" x="1269" y="1604" width="422" height="574" frameX="0" frameY="-8" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_RIGHT0000" x="0" y="2178" width="384" height="515" frameX="-150" frameY="-60" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_RIGHT0001" x="384" y="2178" width="384" height="516" frameX="-148" frameY="-59" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_RIGHT0002" x="768" y="2178" width="383" height="518" frameX="-146" frameY="-57" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_RIGHT0003" x="1151" y="2178" width="383" height="518" frameX="-146" frameY="-57" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_RIGHT0004" x="1151" y="2178" width="383" height="518" frameX="-146" frameY="-57" frameWidth="534" frameHeight="582" />
<SubTexture name="MAT_RIGHT0005" x="1151" y="2178" width="383" height="518" frameX="-146" frameY="-57" frameWidth="534" frameHeight="582" />
</TextureAtlas>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bsk0t7any1rqg"
path="res://.godot/imported/mk_preview.png-b7001c2795528e49e48dd4a8d33d4284.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://events/week_3/mk_preview.png"
dest_files=["res://.godot/imported/mk_preview.png-b7001c2795528e49e48dd4a8d33d4284.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

35
events/week_3/redeem.gd Normal file
View file

@ -0,0 +1,35 @@
# extends AmongUs
var config_change = {
spritesheet_data = "user://uploads/matkap.xml",
spritesheet_image = "user://uploads/matkap.png",
spritesheet_anims = {
"MAT_IDLE" = {
alias = null,
type = Config.SpritesheetAnimType.IDLE
},
"MAT_LEFT" = {
alias = "left",
type = Config.SpritesheetAnimType.DEFAULT
},
"MAT_DOWN" = {
alias = "down",
type = Config.SpritesheetAnimType.DEFAULT
},
"MAT_UP" = {
alias = "up",
type = Config.SpritesheetAnimType.DEFAULT
},
"MAT_RIGHT" = {
alias = "right",
type = Config.SpritesheetAnimType.DEFAULT
},
}
}
func _init() -> void:
if not DirAccess.dir_exists_absolute("user://uploads/"):
DirAccess.make_dir_absolute("user://uploads/")
GlobalEvents.copy_fa("res://events/week_3/matkap.png", "user://uploads/matkap.png")
GlobalEvents.copy_fa("res://events/week_3/matkap.xml", "user://uploads/matkap.xml")

View file

@ -7,7 +7,7 @@ advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter="*.xml, *.png"
include_filter="*.xml, *.png, events/*"
exclude_filter=""
export_path="../export/FunkPanion/FunkPanion-win.zip"
encryption_include_filters=""
@ -21,7 +21,7 @@ script_export_mode=2
custom_template/debug=""
custom_template/release=""
debug/export_console_wrapper=1
binary_format/embed_pck=true
binary_format/embed_pck=false
texture_format/s3tc_bptc=true
texture_format/etc2_astc=false
binary_format/architecture="x86_64"
@ -108,3 +108,256 @@ rm -rf \"{temp_dir}\""
dotnet/include_scripts_content=false
dotnet/include_debug_symbols=false
dotnet/embed_build_outputs=false
[preset.2]
name="macOS"
platform="macOS"
runnable=true
advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path="../export/FunkPanion/FunkPanion-mac.zip"
encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
encrypt_directory=false
script_export_mode=2
[preset.2.options]
export/distribution_type=1
binary_format/architecture="universal"
custom_template/debug=""
custom_template/release=""
debug/export_console_wrapper=1
application/icon=""
application/icon_interpolation=4
application/bundle_identifier="link.abtmtr.fp"
application/signature=""
application/app_category="Utilities"
application/short_version=""
application/version=""
application/copyright="MeowcaTheoRange 2024"
application/copyright_localized={}
application/min_macos_version="10.12"
application/export_angle=2
display/high_res=true
application/additional_plist_content=""
xcode/platform_build="14C18"
xcode/sdk_version="13.1"
xcode/sdk_build="22C55"
xcode/sdk_name="macosx13.1"
xcode/xcode_version="1420"
xcode/xcode_build="14C18"
codesign/codesign=1
codesign/installer_identity=""
codesign/apple_team_id=""
codesign/identity=""
codesign/entitlements/custom_file=""
codesign/entitlements/allow_jit_code_execution=false
codesign/entitlements/allow_unsigned_executable_memory=false
codesign/entitlements/allow_dyld_environment_variables=false
codesign/entitlements/disable_library_validation=true
codesign/entitlements/audio_input=false
codesign/entitlements/camera=false
codesign/entitlements/location=false
codesign/entitlements/address_book=false
codesign/entitlements/calendars=false
codesign/entitlements/photos_library=false
codesign/entitlements/apple_events=false
codesign/entitlements/debugging=false
codesign/entitlements/app_sandbox/enabled=false
codesign/entitlements/app_sandbox/network_server=false
codesign/entitlements/app_sandbox/network_client=false
codesign/entitlements/app_sandbox/device_usb=false
codesign/entitlements/app_sandbox/device_bluetooth=false
codesign/entitlements/app_sandbox/files_downloads=0
codesign/entitlements/app_sandbox/files_pictures=0
codesign/entitlements/app_sandbox/files_music=0
codesign/entitlements/app_sandbox/files_movies=0
codesign/entitlements/app_sandbox/files_user_selected=0
codesign/entitlements/app_sandbox/helper_executables=[]
codesign/custom_options=PackedStringArray()
notarization/notarization=0
privacy/microphone_usage_description=""
privacy/microphone_usage_description_localized={}
privacy/camera_usage_description=""
privacy/camera_usage_description_localized={}
privacy/location_usage_description=""
privacy/location_usage_description_localized={}
privacy/address_book_usage_description=""
privacy/address_book_usage_description_localized={}
privacy/calendar_usage_description=""
privacy/calendar_usage_description_localized={}
privacy/photos_library_usage_description=""
privacy/photos_library_usage_description_localized={}
privacy/desktop_folder_usage_description=""
privacy/desktop_folder_usage_description_localized={}
privacy/documents_folder_usage_description=""
privacy/documents_folder_usage_description_localized={}
privacy/downloads_folder_usage_description=""
privacy/downloads_folder_usage_description_localized={}
privacy/network_volumes_usage_description=""
privacy/network_volumes_usage_description_localized={}
privacy/removable_volumes_usage_description=""
privacy/removable_volumes_usage_description_localized={}
privacy/tracking_enabled=false
privacy/tracking_domains=PackedStringArray()
privacy/collected_data/name/collected=false
privacy/collected_data/name/linked_to_user=false
privacy/collected_data/name/used_for_tracking=false
privacy/collected_data/name/collection_purposes=0
privacy/collected_data/email_address/collected=false
privacy/collected_data/email_address/linked_to_user=false
privacy/collected_data/email_address/used_for_tracking=false
privacy/collected_data/email_address/collection_purposes=0
privacy/collected_data/phone_number/collected=false
privacy/collected_data/phone_number/linked_to_user=false
privacy/collected_data/phone_number/used_for_tracking=false
privacy/collected_data/phone_number/collection_purposes=0
privacy/collected_data/physical_address/collected=false
privacy/collected_data/physical_address/linked_to_user=false
privacy/collected_data/physical_address/used_for_tracking=false
privacy/collected_data/physical_address/collection_purposes=0
privacy/collected_data/other_contact_info/collected=false
privacy/collected_data/other_contact_info/linked_to_user=false
privacy/collected_data/other_contact_info/used_for_tracking=false
privacy/collected_data/other_contact_info/collection_purposes=0
privacy/collected_data/health/collected=false
privacy/collected_data/health/linked_to_user=false
privacy/collected_data/health/used_for_tracking=false
privacy/collected_data/health/collection_purposes=0
privacy/collected_data/fitness/collected=false
privacy/collected_data/fitness/linked_to_user=false
privacy/collected_data/fitness/used_for_tracking=false
privacy/collected_data/fitness/collection_purposes=0
privacy/collected_data/payment_info/collected=false
privacy/collected_data/payment_info/linked_to_user=false
privacy/collected_data/payment_info/used_for_tracking=false
privacy/collected_data/payment_info/collection_purposes=0
privacy/collected_data/credit_info/collected=false
privacy/collected_data/credit_info/linked_to_user=false
privacy/collected_data/credit_info/used_for_tracking=false
privacy/collected_data/credit_info/collection_purposes=0
privacy/collected_data/other_financial_info/collected=false
privacy/collected_data/other_financial_info/linked_to_user=false
privacy/collected_data/other_financial_info/used_for_tracking=false
privacy/collected_data/other_financial_info/collection_purposes=0
privacy/collected_data/precise_location/collected=false
privacy/collected_data/precise_location/linked_to_user=false
privacy/collected_data/precise_location/used_for_tracking=false
privacy/collected_data/precise_location/collection_purposes=0
privacy/collected_data/coarse_location/collected=false
privacy/collected_data/coarse_location/linked_to_user=false
privacy/collected_data/coarse_location/used_for_tracking=false
privacy/collected_data/coarse_location/collection_purposes=0
privacy/collected_data/sensitive_info/collected=false
privacy/collected_data/sensitive_info/linked_to_user=false
privacy/collected_data/sensitive_info/used_for_tracking=false
privacy/collected_data/sensitive_info/collection_purposes=0
privacy/collected_data/contacts/collected=false
privacy/collected_data/contacts/linked_to_user=false
privacy/collected_data/contacts/used_for_tracking=false
privacy/collected_data/contacts/collection_purposes=0
privacy/collected_data/emails_or_text_messages/collected=false
privacy/collected_data/emails_or_text_messages/linked_to_user=false
privacy/collected_data/emails_or_text_messages/used_for_tracking=false
privacy/collected_data/emails_or_text_messages/collection_purposes=0
privacy/collected_data/photos_or_videos/collected=false
privacy/collected_data/photos_or_videos/linked_to_user=false
privacy/collected_data/photos_or_videos/used_for_tracking=false
privacy/collected_data/photos_or_videos/collection_purposes=0
privacy/collected_data/audio_data/collected=false
privacy/collected_data/audio_data/linked_to_user=false
privacy/collected_data/audio_data/used_for_tracking=false
privacy/collected_data/audio_data/collection_purposes=0
privacy/collected_data/gameplay_content/collected=false
privacy/collected_data/gameplay_content/linked_to_user=false
privacy/collected_data/gameplay_content/used_for_tracking=false
privacy/collected_data/gameplay_content/collection_purposes=0
privacy/collected_data/customer_support/collected=false
privacy/collected_data/customer_support/linked_to_user=false
privacy/collected_data/customer_support/used_for_tracking=false
privacy/collected_data/customer_support/collection_purposes=0
privacy/collected_data/other_user_content/collected=false
privacy/collected_data/other_user_content/linked_to_user=false
privacy/collected_data/other_user_content/used_for_tracking=false
privacy/collected_data/other_user_content/collection_purposes=0
privacy/collected_data/browsing_history/collected=false
privacy/collected_data/browsing_history/linked_to_user=false
privacy/collected_data/browsing_history/used_for_tracking=false
privacy/collected_data/browsing_history/collection_purposes=0
privacy/collected_data/search_hhistory/collected=false
privacy/collected_data/search_hhistory/linked_to_user=false
privacy/collected_data/search_hhistory/used_for_tracking=false
privacy/collected_data/search_hhistory/collection_purposes=0
privacy/collected_data/user_id/collected=false
privacy/collected_data/user_id/linked_to_user=false
privacy/collected_data/user_id/used_for_tracking=false
privacy/collected_data/user_id/collection_purposes=0
privacy/collected_data/device_id/collected=false
privacy/collected_data/device_id/linked_to_user=false
privacy/collected_data/device_id/used_for_tracking=false
privacy/collected_data/device_id/collection_purposes=0
privacy/collected_data/purchase_history/collected=false
privacy/collected_data/purchase_history/linked_to_user=false
privacy/collected_data/purchase_history/used_for_tracking=false
privacy/collected_data/purchase_history/collection_purposes=0
privacy/collected_data/product_interaction/collected=false
privacy/collected_data/product_interaction/linked_to_user=false
privacy/collected_data/product_interaction/used_for_tracking=false
privacy/collected_data/product_interaction/collection_purposes=0
privacy/collected_data/advertising_data/collected=false
privacy/collected_data/advertising_data/linked_to_user=false
privacy/collected_data/advertising_data/used_for_tracking=false
privacy/collected_data/advertising_data/collection_purposes=0
privacy/collected_data/other_usage_data/collected=false
privacy/collected_data/other_usage_data/linked_to_user=false
privacy/collected_data/other_usage_data/used_for_tracking=false
privacy/collected_data/other_usage_data/collection_purposes=0
privacy/collected_data/crash_data/collected=false
privacy/collected_data/crash_data/linked_to_user=false
privacy/collected_data/crash_data/used_for_tracking=false
privacy/collected_data/crash_data/collection_purposes=0
privacy/collected_data/performance_data/collected=false
privacy/collected_data/performance_data/linked_to_user=false
privacy/collected_data/performance_data/used_for_tracking=false
privacy/collected_data/performance_data/collection_purposes=0
privacy/collected_data/other_diagnostic_data/collected=false
privacy/collected_data/other_diagnostic_data/linked_to_user=false
privacy/collected_data/other_diagnostic_data/used_for_tracking=false
privacy/collected_data/other_diagnostic_data/collection_purposes=0
privacy/collected_data/environment_scanning/collected=false
privacy/collected_data/environment_scanning/linked_to_user=false
privacy/collected_data/environment_scanning/used_for_tracking=false
privacy/collected_data/environment_scanning/collection_purposes=0
privacy/collected_data/hands/collected=false
privacy/collected_data/hands/linked_to_user=false
privacy/collected_data/hands/used_for_tracking=false
privacy/collected_data/hands/collection_purposes=0
privacy/collected_data/head/collected=false
privacy/collected_data/head/linked_to_user=false
privacy/collected_data/head/used_for_tracking=false
privacy/collected_data/head/collection_purposes=0
privacy/collected_data/other_data_types/collected=false
privacy/collected_data/other_data_types/linked_to_user=false
privacy/collected_data/other_data_types/used_for_tracking=false
privacy/collected_data/other_data_types/collection_purposes=0
ssh_remote_deploy/enabled=false
ssh_remote_deploy/host="user@host_ip"
ssh_remote_deploy/port="22"
ssh_remote_deploy/extra_args_ssh=""
ssh_remote_deploy/extra_args_scp=""
ssh_remote_deploy/run_script="#!/usr/bin/env bash
unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\"
open \"{temp_dir}/{exe_name}.app\" --args {cmd_args}"
ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash
kill $(pgrep -x -f \"{temp_dir}/{exe_name}.app/Contents/MacOS/{exe_name} {cmd_args}\")
rm -rf \"{temp_dir}\""
dotnet/include_scripts_content=false
dotnet/include_debug_symbols=false
dotnet/embed_build_outputs=false

View file

@ -11,7 +11,7 @@ config_version=5
[application]
config/name="FunkPanion"
config/version="0.9.1"
config/version="0.10.0"
run/main_scene="res://scenes/main.tscn"
run/disable_stderr=true
config/use_custom_user_dir=true
@ -30,6 +30,7 @@ boot_splash/minimum_display_time=2000
GlobalInput="*res://plugins/GlobalInput/GlobalInputGDScript.tscn"
GlobalConfig="*res://scenes/global_config.tscn"
GlobalEvents="*res://scenes/global_events.tscn"
[display]
@ -104,3 +105,5 @@ mod_snap_coarse={
renderer/rendering_method="gl_compatibility"
renderer/rendering_method.mobile="gl_compatibility"
textures/vram_compression/import_etc2_astc=true
environment/defaults/default_clear_color=Color(0.188235, 0.188235, 0.188235, 1)

View file

@ -1,18 +1,18 @@
[gd_scene load_steps=13 format=3 uid="uid://b0m4v3w4sqrfs"]
[gd_scene load_steps=15 format=3 uid="uid://b0m4v3w4sqrfs"]
[ext_resource type="Script" path="res://scripts/config/config_window.gd" id="1_3y2tp"]
[ext_resource type="StyleBox" uid="uid://bdkv45xc5lotp" path="res://assets/config/bg.tres" id="1_kscu5"]
[ext_resource type="LabelSettings" uid="uid://2iu8q0tylumo" path="res://assets/config/header_bold.tres" id="1_lbm3n"]
[ext_resource type="FontFile" uid="uid://ce5fs0ro7kp8r" path="res://assets/fonts/Lexend.ttf" id="2_bbfo5"]
[ext_resource type="Script" path="res://scripts/config/form_handler.gd" id="2_ouac2"]
[ext_resource type="FontFile" uid="uid://4e3o2ds5xy7p" path="res://assets/fonts/MatSymOut.ttf" id="2_pm82g"]
[ext_resource type="LabelSettings" uid="uid://c2s3eclr25ots" path="res://assets/config/body.tres" id="3_gn7vd"]
[ext_resource type="FontFile" uid="uid://c6ck52v6qotm" path="res://assets/fonts/B_Lexend.ttf" id="3_qguou"]
[ext_resource type="Script" path="res://scripts/config/config_events.gd" id="6_kxysx"]
[ext_resource type="Script" path="res://scripts/config/config_presets.gd" id="6_th0jy"]
[ext_resource type="FontVariation" uid="uid://d1apfvux6r82v" path="res://assets/config/button_icon.tres" id="8_qusr6"]
[ext_resource type="Script" path="res://scripts/config/open_file_dialog.gd" id="9_1o6y4"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_3ax2o"]
bg_color = Color(0.12549, 0.12549, 0.12549, 1)
[sub_resource type="LabelSettings" id="LabelSettings_gk6wd"]
font = ExtResource("3_qguou")
font_size = 32
@ -30,7 +30,7 @@ grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
size_flags_vertical = 3
theme_override_styles/panel = SubResource("StyleBoxFlat_3ax2o")
theme_override_styles/panel = ExtResource("1_kscu5")
follow_focus = true
horizontal_scroll_mode = 0
script = ExtResource("1_3y2tp")
@ -71,15 +71,23 @@ size_flags_horizontal = 3
text = "Config"
label_settings = SubResource("LabelSettings_gk6wd")
[node name="Reset" type="Button" parent="MarginContainer/Form/Header"]
[node name="Encounters" type="Button" parent="MarginContainer/Form/Header"]
custom_minimum_size = Vector2(40, 40)
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 4
tooltip_text = "Save and exit."
tooltip_text = "Open the Events & Goodies menu."
theme_override_fonts/font = ExtResource("2_pm82g")
theme_override_font_sizes/font_size = 24
text = "reset_settings"
text = "featured_seasonal_and_gifts"
script = ExtResource("6_kxysx")
[node name="Button" type="Button" parent="MarginContainer/Form/Header"]
custom_minimum_size = Vector2(40, 40)
layout_mode = 2
tooltip_text = "Manage your configuration presets."
theme_override_fonts/font = ExtResource("2_pm82g")
theme_override_font_sizes/font_size = 24
text = "stack_hexagon"
script = ExtResource("6_th0jy")
[node name="OSD and UI" type="VBoxContainer" parent="MarginContainer/Form"]
layout_mode = 2
@ -525,7 +533,6 @@ layout_mode = 2
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 1
tooltip_text = "How big the sprite is compared to its default size."
mouse_filter = 0
text = "Flip Sprite"
label_settings = ExtResource("3_gn7vd")
@ -536,6 +543,25 @@ layout_mode = 2
size_flags_horizontal = 8
size_flags_vertical = 4
[node name="sprite_hold" type="HBoxContainer" parent="MarginContainer/Form/Sprites/Controls/VBoxContainer"]
custom_minimum_size = Vector2(0, 32)
layout_mode = 2
[node name="Label" type="Label" parent="MarginContainer/Form/Sprites/Controls/VBoxContainer/sprite_hold"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 1
tooltip_text = "If you hold an animation, it will loop on every beat."
mouse_filter = 0
text = "Loop Holds"
label_settings = ExtResource("3_gn7vd")
vertical_alignment = 1
[node name="input" type="CheckButton" parent="MarginContainer/Form/Sprites/Controls/VBoxContainer/sprite_hold"]
layout_mode = 2
size_flags_horizontal = 8
size_flags_vertical = 4
[node name="spritesheet_default_opacity" type="HBoxContainer" parent="MarginContainer/Form/Sprites/Controls/VBoxContainer"]
custom_minimum_size = Vector2(0, 32)
layout_mode = 2
@ -602,4 +628,4 @@ select_mode = 1
[connection signal="pressed" from="MarginContainer/Form/Header/BackButton" to="." method="_on_back_button_pressed"]
[connection signal="pressed" from="MarginContainer/Form/Header/BackButton" to="MarginContainer/Form" method="_on_back_button_pressed"]
[connection signal="pressed" from="MarginContainer/Form/Header/Reset" to="." method="_on_reset_pressed"]
[connection signal="change_config" from="MarginContainer/Form/Header/Encounters" to="MarginContainer/Form" method="_on_encounters_change_config"]

61
scenes/config_events.tscn Normal file
View file

@ -0,0 +1,61 @@
[gd_scene load_steps=5 format=3 uid="uid://dnr0jdrxiiifr"]
[ext_resource type="StyleBox" uid="uid://bdkv45xc5lotp" path="res://assets/config/bg.tres" id="1_4psbb"]
[ext_resource type="Script" path="res://scripts/config/config_window_events.gd" id="2_jnwha"]
[ext_resource type="FontFile" uid="uid://4e3o2ds5xy7p" path="res://assets/fonts/MatSymOut.ttf" id="3_qmpng"]
[ext_resource type="LabelSettings" uid="uid://2iu8q0tylumo" path="res://assets/config/header_bold.tres" id="4_k4g4o"]
[node name="ScrollContainer" type="ScrollContainer"]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
size_flags_vertical = 3
theme_override_styles/panel = ExtResource("1_4psbb")
horizontal_scroll_mode = 0
vertical_scroll_mode = 0
script = ExtResource("2_jnwha")
[node name="MarginContainer" type="MarginContainer" parent="."]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
theme_override_constants/margin_left = 8
theme_override_constants/margin_top = 8
theme_override_constants/margin_right = 8
theme_override_constants/margin_bottom = 8
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"]
layout_mode = 2
[node name="Header" type="HBoxContainer" parent="MarginContainer/VBoxContainer"]
layout_mode = 2
[node name="CloseButton" type="Button" parent="MarginContainer/VBoxContainer/Header"]
custom_minimum_size = Vector2(40, 40)
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 4
theme_override_fonts/font = ExtResource("3_qmpng")
theme_override_font_sizes/font_size = 24
text = "close"
flat = true
[node name="Header" type="Label" parent="MarginContainer/VBoxContainer/Header"]
layout_mode = 2
size_flags_horizontal = 3
text = "Events & Goodies"
label_settings = ExtResource("4_k4g4o")
[node name="ScrollContainer" type="ScrollContainer" parent="MarginContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/VBoxContainer/ScrollContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[connection signal="pressed" from="MarginContainer/VBoxContainer/Header/CloseButton" to="." method="_on_close_button_pressed"]

View file

@ -0,0 +1,83 @@
[gd_scene load_steps=5 format=3 uid="uid://b7a6e4l7mhqmt"]
[ext_resource type="StyleBox" uid="uid://bdkv45xc5lotp" path="res://assets/config/bg.tres" id="1_no4mj"]
[ext_resource type="Script" path="res://scripts/config/config_window_presets.gd" id="2_yjvpe"]
[ext_resource type="FontFile" uid="uid://4e3o2ds5xy7p" path="res://assets/fonts/MatSymOut.ttf" id="3_bra08"]
[ext_resource type="LabelSettings" uid="uid://2iu8q0tylumo" path="res://assets/config/header_bold.tres" id="4_mvauf"]
[node name="ScrollContainer" type="ScrollContainer"]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
theme_override_styles/panel = ExtResource("1_no4mj")
horizontal_scroll_mode = 0
vertical_scroll_mode = 0
script = ExtResource("2_yjvpe")
[node name="MarginContainer" type="MarginContainer" parent="."]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
theme_override_constants/margin_left = 8
theme_override_constants/margin_top = 8
theme_override_constants/margin_right = 8
theme_override_constants/margin_bottom = 8
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"]
layout_mode = 2
[node name="Header" type="HBoxContainer" parent="MarginContainer/VBoxContainer"]
layout_mode = 2
[node name="CloseButton" type="Button" parent="MarginContainer/VBoxContainer/Header"]
custom_minimum_size = Vector2(40, 40)
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 4
theme_override_fonts/font = ExtResource("3_bra08")
theme_override_font_sizes/font_size = 24
text = "close"
flat = true
[node name="Header" type="Label" parent="MarginContainer/VBoxContainer/Header"]
layout_mode = 2
size_flags_horizontal = 3
text = "Presets"
label_settings = ExtResource("4_mvauf")
[node name="ResetButton" type="Button" parent="MarginContainer/VBoxContainer/Header"]
custom_minimum_size = Vector2(40, 40)
layout_mode = 2
tooltip_text = "Reset your current configuration."
theme_override_fonts/font = ExtResource("3_bra08")
theme_override_font_sizes/font_size = 24
text = "reset_settings"
[node name="Tree" type="Tree" parent="MarginContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
columns = 2
column_titles_visible = true
hide_folding = true
enable_recursive_folding = false
hide_root = true
select_mode = 1
scroll_horizontal_enabled = false
[node name="AddNew" type="HBoxContainer" parent="MarginContainer/VBoxContainer"]
layout_mode = 2
[node name="name" type="LineEdit" parent="MarginContainer/VBoxContainer/AddNew"]
layout_mode = 2
size_flags_horizontal = 3
placeholder_text = "Preset Name"
[node name="switch" type="Button" parent="MarginContainer/VBoxContainer/AddNew"]
layout_mode = 2
text = "Save Preset"
[connection signal="pressed" from="MarginContainer/VBoxContainer/Header/CloseButton" to="." method="_on_close_button_pressed"]
[connection signal="pressed" from="MarginContainer/VBoxContainer/Header/ResetButton" to="." method="_on_reset_button_pressed"]

View file

@ -0,0 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://dxdsmwmjqrrl8"]
[ext_resource type="Script" path="res://scripts/GlobalEvents.gd" id="1_toif7"]
[node name="Events" type="Node"]
script = ExtResource("1_toif7")

View file

@ -1,17 +1,15 @@
[gd_scene load_steps=11 format=3 uid="uid://d0hedjnfwtu0"]
[gd_scene load_steps=10 format=3 uid="uid://d0hedjnfwtu0"]
[ext_resource type="Script" path="res://scripts/window.gd" id="1_6nwqw"]
[ext_resource type="Script" path="res://scripts/animator.gd" id="2_hov7x"]
[ext_resource type="PackedScene" uid="uid://qnb6qrsgpbwc" path="res://scenes/osd.tscn" id="2_m7sf8"]
[ext_resource type="AudioStream" uid="uid://bj6b8h153h1bn" path="res://assets/beep.ogg" id="3_tvnah"]
[ext_resource type="AudioStream" uid="uid://8ij8fr2uqb65" path="res://assets/tap.wav" id="3_xnh3p"]
[ext_resource type="Texture2D" uid="uid://b6x537wsl3853" path="res://assets/BOYFRIEND.png" id="4_fraqq"]
[ext_resource type="Theme" uid="uid://e62vyqlhf1v1" path="res://osd.tres" id="7_bx315"]
[ext_resource type="FontFile" uid="uid://4e3o2ds5xy7p" path="res://assets/fonts/MatSymOut.ttf" id="7_q7jy6"]
[ext_resource type="Script" path="res://scripts/menu.gd" id="8_3lc1r"]
[sub_resource type="AtlasTexture" id="AtlasTexture_y0egr"]
atlas = ExtResource("4_fraqq")
region = Rect2(0, 0, 1, 1)
[node name="Control" type="ColorRect"]
@ -77,8 +75,10 @@ theme = ExtResource("7_bx315")
theme_override_fonts/font = ExtResource("7_q7jy6")
theme_override_font_sizes/font_size = 32
text = "menu"
item_count = 2
item_count = 3
popup/item_0/text = "Config"
popup/item_1/text = "Exit"
popup/item_1/text = "XML Tuner"
popup/item_1/id = 1
popup/item_2/text = "Exit"
popup/item_2/id = 2
script = ExtResource("8_3lc1r")

28
scenes/thingy_event.gd Normal file
View file

@ -0,0 +1,28 @@
extends PanelContainer
signal change_config(config:Dictionary)
@onready var title = $"MarginContainer/VBoxContainer/Header/Title"
@onready var date = $"MarginContainer/VBoxContainer/Header/VBoxContainer/Date"
@onready var tagline = $"MarginContainer/VBoxContainer/Header/VBoxContainer/Tagline"
@onready var thumb = $"MarginContainer/VBoxContainer/HBoxContainer/TextureRect"
@onready var desc = $"MarginContainer/VBoxContainer/HBoxContainer/Label"
@onready var yes = $"MarginContainer/VBoxContainer/HBoxContainer2/Yes"
var event:Dictionary
func do_things():
set_event()
yes.pressed.connect(func():
var script = load("res://events/" + event.id + "/redeem.gd").new()
if script.config_change != null:
change_config.emit(script.config_change)
)
func set_event():
title.text = event.title
date.text = event.date
tagline.text = event.tagline
thumb.texture = load("res://events/" + event.id + "/" + event.thumb)
desc.text = event.desc

100
scenes/thingy_event.tscn Normal file
View file

@ -0,0 +1,100 @@
[gd_scene load_steps=7 format=3 uid="uid://qnji76gh8bjy"]
[ext_resource type="StyleBox" uid="uid://bkwb4tqap7x7i" path="res://assets/config/bg2.tres" id="1_uaet0"]
[ext_resource type="Script" path="res://scenes/thingy_event.gd" id="2_x0j35"]
[ext_resource type="LabelSettings" uid="uid://2iu8q0tylumo" path="res://assets/config/header_bold.tres" id="2_xndpd"]
[ext_resource type="LabelSettings" uid="uid://c2s3eclr25ots" path="res://assets/config/body.tres" id="3_40siy"]
[ext_resource type="LabelSettings" uid="uid://xh3q8p65gbti" path="res://assets/config/tiny.tres" id="4_e5d37"]
[ext_resource type="Texture2D" uid="uid://bsk0t7any1rqg" path="res://events/week_3/mk_preview.png" id="5_b74tb"]
[node name="ThingyEvent" type="PanelContainer"]
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -211.5
offset_top = -37.0
offset_right = 211.5
offset_bottom = 37.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
size_flags_vertical = 4
theme_override_styles/panel = ExtResource("1_uaet0")
script = ExtResource("2_x0j35")
[node name="MarginContainer" type="MarginContainer" parent="."]
layout_mode = 2
theme_override_constants/margin_left = 16
theme_override_constants/margin_top = 16
theme_override_constants/margin_right = 16
theme_override_constants/margin_bottom = 16
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"]
layout_mode = 2
theme_override_constants/separation = 16
[node name="Header" type="HBoxContainer" parent="MarginContainer/VBoxContainer"]
layout_mode = 2
theme_override_constants/separation = 16
[node name="Title" type="Label" parent="MarginContainer/VBoxContainer/Header"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 1
text = "Loading"
label_settings = ExtResource("2_xndpd")
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/VBoxContainer/Header"]
layout_mode = 2
size_flags_vertical = 0
theme_override_constants/separation = 0
alignment = 2
[node name="Date" type="Label" parent="MarginContainer/VBoxContainer/Header/VBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 1
text = "Soon..."
label_settings = ExtResource("3_40siy")
horizontal_alignment = 2
[node name="Tagline" type="Label" parent="MarginContainer/VBoxContainer/Header/VBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 1
text = "I can hardly wait!"
label_settings = ExtResource("4_e5d37")
horizontal_alignment = 2
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
theme_override_constants/separation = 16
[node name="Label" type="Label" parent="MarginContainer/VBoxContainer/HBoxContainer"]
custom_minimum_size = Vector2(300, 0)
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 0
text = "Loading..."
label_settings = ExtResource("3_40siy")
autowrap_mode = 3
[node name="TextureRect" type="TextureRect" parent="MarginContainer/VBoxContainer/HBoxContainer"]
custom_minimum_size = Vector2(128, 128)
layout_mode = 2
size_flags_vertical = 0
texture = ExtResource("5_b74tb")
expand_mode = 1
stretch_mode = 4
[node name="HBoxContainer2" type="HBoxContainer" parent="MarginContainer/VBoxContainer"]
layout_mode = 2
theme_override_constants/separation = 8
alignment = 2
[node name="Yes" type="Button" parent="MarginContainer/VBoxContainer/HBoxContainer2"]
layout_mode = 2
text = "Apply"

477
scenes/xml_editor.tscn Normal file
View file

@ -0,0 +1,477 @@
[gd_scene load_steps=12 format=3 uid="uid://d0w4cbu1jgqnx"]
[ext_resource type="Script" path="res://scripts/xmle/xml_editor_window.gd" id="1_gspou"]
[ext_resource type="StyleBox" uid="uid://bdkv45xc5lotp" path="res://assets/config/bg.tres" id="1_j0s65"]
[ext_resource type="LabelSettings" uid="uid://c2s3eclr25ots" path="res://assets/config/body.tres" id="2_m7ywi"]
[ext_resource type="LabelSettings" uid="uid://55elphqx3dqw" path="res://assets/config/section_header.tres" id="2_mi1pb"]
[ext_resource type="Script" path="res://scripts/xmle/load.gd" id="3_0whnd"]
[ext_resource type="Texture2D" uid="uid://eudnts7c3nxy" path="res://assets/background_checker.png" id="3_06msg"]
[ext_resource type="Script" path="res://scripts/xmle/form_handler.gd" id="3_aomrl"]
[ext_resource type="Script" path="res://scripts/xmle/save.gd" id="4_ye3qr"]
[sub_resource type="AtlasTexture" id="AtlasTexture_k1djj"]
[sub_resource type="AtlasTexture" id="AtlasTexture_3qyg2"]
[sub_resource type="AtlasTexture" id="AtlasTexture_iddor"]
[node name="PanelContainer" type="PanelContainer"]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
size_flags_vertical = 3
theme_override_styles/panel = ExtResource("1_j0s65")
script = ExtResource("1_gspou")
[node name="VBoxContainer" type="VBoxContainer" parent="."]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
theme_override_constants/separation = 0
[node name="Menu" type="MarginContainer" parent="VBoxContainer"]
z_index = 1
layout_mode = 2
theme_override_constants/margin_left = 8
theme_override_constants/margin_top = 4
theme_override_constants/margin_right = 8
theme_override_constants/margin_bottom = 4
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/Menu"]
layout_mode = 2
theme_override_constants/separation = 8
[node name="Load" type="MenuButton" parent="VBoxContainer/Menu/HBoxContainer"]
layout_mode = 2
text = "Load..."
item_count = 2
popup/item_0/text = "Load XML"
popup/item_1/text = "Load reference image"
popup/item_1/id = 1
script = ExtResource("3_0whnd")
[node name="Edit" type="MenuButton" parent="VBoxContainer/Menu/HBoxContainer"]
visible = false
layout_mode = 2
text = "Edit..."
item_count = 1
popup/item_0/text = "Image atlas wizard"
popup/item_0/id = 1
[node name="Save" type="Button" parent="VBoxContainer/Menu/HBoxContainer"]
layout_mode = 2
text = "Save"
flat = true
script = ExtResource("4_ye3qr")
[node name="Spacer" type="Control" parent="VBoxContainer/Menu/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="Exit" type="Button" parent="VBoxContainer/Menu/HBoxContainer"]
layout_mode = 2
text = "Exit"
flat = true
[node name="Editor" type="MarginContainer" parent="VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
theme_override_constants/margin_left = 8
theme_override_constants/margin_top = 8
theme_override_constants/margin_right = 8
theme_override_constants/margin_bottom = 8
script = ExtResource("3_aomrl")
[node name="HSplitContainer" type="HSplitContainer" parent="VBoxContainer/Editor"]
layout_mode = 2
size_flags_vertical = 3
theme_override_constants/separation = 0
theme_override_constants/autohide = 0
[node name="VSplitContainer" type="VSplitContainer" parent="VBoxContainer/Editor/HSplitContainer"]
layout_mode = 2
theme_override_constants/separation = 0
theme_override_constants/autohide = 0
[node name="Frames" type="VBoxContainer" parent="VBoxContainer/Editor/HSplitContainer/VSplitContainer"]
layout_mode = 2
size_flags_vertical = 3
[node name="Label" type="Label" parent="VBoxContainer/Editor/HSplitContainer/VSplitContainer/Frames"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 1
tooltip_text = "How big the character's sprites are allowed to get.
To FunkPanion, this is the window's size.
To Sparrow, Flixel, and FNF, this is the \"frame_\" properties on each frame."
mouse_filter = 0
text = "Frames"
label_settings = ExtResource("2_mi1pb")
vertical_alignment = 1
[node name="Tree" type="Tree" parent="VBoxContainer/Editor/HSplitContainer/VSplitContainer/Frames"]
custom_minimum_size = Vector2(200, 50)
layout_mode = 2
size_flags_vertical = 3
columns = 2
allow_search = false
hide_folding = true
enable_recursive_folding = false
select_mode = 1
scroll_horizontal_enabled = false
[node name="align_all" type="HBoxContainer" parent="VBoxContainer/Editor/HSplitContainer/VSplitContainer/Frames"]
custom_minimum_size = Vector2(0, 32)
layout_mode = 2
[node name="preset" type="MenuButton" parent="VBoxContainer/Editor/HSplitContainer/VSplitContainer/Frames/align_all"]
layout_mode = 2
size_flags_horizontal = 3
tooltip_text = "Align all frames in the animation."
text = "Align All..."
flat = false
item_count = 9
popup/item_0/text = "Top Left"
popup/item_1/text = "Top"
popup/item_1/id = 1
popup/item_2/text = "Top Right"
popup/item_2/id = 2
popup/item_3/text = "Left"
popup/item_3/id = 3
popup/item_4/text = "Center"
popup/item_4/id = 4
popup/item_5/text = "Right"
popup/item_5/id = 5
popup/item_6/text = "Bottom Left"
popup/item_6/id = 6
popup/item_7/text = "Bottom"
popup/item_7/id = 7
popup/item_8/text = "Bottom Right"
popup/item_8/id = 8
[node name="autocrop" type="Button" parent="VBoxContainer/Editor/HSplitContainer/VSplitContainer/Frames/align_all"]
layout_mode = 2
size_flags_horizontal = 3
tooltip_text = "Crop out transparent pixels in all frames of the animation."
text = "Autocrop All"
[node name="oskin" type="HBoxContainer" parent="VBoxContainer/Editor/HSplitContainer/VSplitContainer/Frames"]
custom_minimum_size = Vector2(0, 32)
layout_mode = 2
[node name="Label" type="Label" parent="VBoxContainer/Editor/HSplitContainer/VSplitContainer/Frames/oskin"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 1
tooltip_text = "How many frames each animation will have."
mouse_filter = 0
text = "Onion Skin"
label_settings = ExtResource("2_m7ywi")
vertical_alignment = 1
[node name="prev" type="CheckBox" parent="VBoxContainer/Editor/HSplitContainer/VSplitContainer/Frames/oskin"]
layout_mode = 2
text = "Previous"
[node name="next" type="CheckBox" parent="VBoxContainer/Editor/HSplitContainer/VSplitContainer/Frames/oskin"]
layout_mode = 2
text = "Next"
[node name="Animations" type="VBoxContainer" parent="VBoxContainer/Editor/HSplitContainer/VSplitContainer"]
custom_minimum_size = Vector2(0, 100)
layout_mode = 2
size_flags_vertical = 3
[node name="Label" type="Label" parent="VBoxContainer/Editor/HSplitContainer/VSplitContainer/Animations"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 1
tooltip_text = "How big the character's sprites are allowed to get.
To FunkPanion, this is the window's size.
To Sparrow, Flixel, and FNF, this is the \"frame_\" properties on each frame."
mouse_filter = 0
text = "Animations"
label_settings = ExtResource("2_mi1pb")
vertical_alignment = 1
[node name="Tree" type="Tree" parent="VBoxContainer/Editor/HSplitContainer/VSplitContainer/Animations"]
layout_mode = 2
size_flags_vertical = 3
allow_search = false
hide_folding = true
enable_recursive_folding = false
hide_root = true
select_mode = 1
scroll_horizontal_enabled = false
[node name="AddNew" type="HBoxContainer" parent="VBoxContainer/Editor/HSplitContainer/VSplitContainer/Animations"]
layout_mode = 2
[node name="name" type="LineEdit" parent="VBoxContainer/Editor/HSplitContainer/VSplitContainer/Animations/AddNew"]
layout_mode = 2
size_flags_horizontal = 3
placeholder_text = "Animation Name"
[node name="switch" type="Button" parent="VBoxContainer/Editor/HSplitContainer/VSplitContainer/Animations/AddNew"]
layout_mode = 2
text = "Add"
[node name="sprite_size" type="HBoxContainer" parent="VBoxContainer/Editor/HSplitContainer/VSplitContainer/Animations"]
custom_minimum_size = Vector2(0, 32)
layout_mode = 2
[node name="Label" type="Label" parent="VBoxContainer/Editor/HSplitContainer/VSplitContainer/Animations/sprite_size"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 1
tooltip_text = "How big the character's sprites are allowed to get.
To FunkPanion, this is the window's size.
To Sparrow, Flixel, and FNF, this is the \"frame_width/height\" properties on each frame."
mouse_filter = 0
text = "Sprite Size"
label_settings = ExtResource("2_m7ywi")
vertical_alignment = 1
[node name="value_w" type="SpinBox" parent="VBoxContainer/Editor/HSplitContainer/VSplitContainer/Animations/sprite_size"]
layout_mode = 2
size_flags_horizontal = 8
size_flags_vertical = 4
max_value = 8192.0
value = 500.0
select_all_on_focus = true
[node name="value_h" type="SpinBox" parent="VBoxContainer/Editor/HSplitContainer/VSplitContainer/Animations/sprite_size"]
layout_mode = 2
size_flags_horizontal = 8
size_flags_vertical = 4
max_value = 8192.0
value = 500.0
select_all_on_focus = true
[node name="frame_count" type="HBoxContainer" parent="VBoxContainer/Editor/HSplitContainer/VSplitContainer/Animations"]
custom_minimum_size = Vector2(0, 32)
layout_mode = 2
[node name="Label" type="Label" parent="VBoxContainer/Editor/HSplitContainer/VSplitContainer/Animations/frame_count"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 1
tooltip_text = "How many frames each animation will have."
mouse_filter = 0
text = "Frame Count"
label_settings = ExtResource("2_m7ywi")
vertical_alignment = 1
[node name="value" type="SpinBox" parent="VBoxContainer/Editor/HSplitContainer/VSplitContainer/Animations/frame_count"]
layout_mode = 2
size_flags_horizontal = 8
size_flags_vertical = 4
max_value = 240.0
value = 10.0
select_all_on_focus = true
[node name="Region" type="VBoxContainer" parent="VBoxContainer/Editor/HSplitContainer"]
layout_mode = 2
[node name="Label" type="Label" parent="VBoxContainer/Editor/HSplitContainer/Region"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 1
tooltip_text = "How big the character's sprites are allowed to get.
To FunkPanion, this is the window's size.
To Sparrow, Flixel, and FNF, this is the \"frame_\" properties on each frame."
mouse_filter = 0
text = "Region"
label_settings = ExtResource("2_mi1pb")
vertical_alignment = 2
[node name="RegionView" type="SubViewportContainer" parent="VBoxContainer/Editor/HSplitContainer/Region"]
custom_minimum_size = Vector2(250, 250)
layout_mode = 2
size_flags_vertical = 3
stretch = true
[node name="Viewport" type="SubViewport" parent="VBoxContainer/Editor/HSplitContainer/Region/RegionView"]
disable_3d = true
handle_input_locally = false
size = Vector2i(363, 298)
render_target_update_mode = 4
[node name="BG" type="TextureRect" parent="VBoxContainer/Editor/HSplitContainer/Region/RegionView/Viewport"]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
size_flags_vertical = 3
texture = ExtResource("3_06msg")
stretch_mode = 1
[node name="ReferenceRect" type="ReferenceRect" parent="VBoxContainer/Editor/HSplitContainer/Region/RegionView/Viewport"]
border_width = 2.0
editor_only = false
[node name="OSPrevCharacter" type="TextureRect" parent="VBoxContainer/Editor/HSplitContainer/Region/RegionView/Viewport/ReferenceRect"]
visible = false
modulate = Color(0, 0, 1, 0.501961)
layout_mode = 0
offset_right = 1.0
offset_bottom = 1.0
size_flags_horizontal = 4
size_flags_vertical = 4
texture = SubResource("AtlasTexture_k1djj")
stretch_mode = 2
[node name="Character" type="TextureRect" parent="VBoxContainer/Editor/HSplitContainer/Region/RegionView/Viewport/ReferenceRect"]
layout_mode = 0
offset_right = 1.0
offset_bottom = 1.0
size_flags_horizontal = 4
size_flags_vertical = 4
texture = SubResource("AtlasTexture_3qyg2")
stretch_mode = 2
[node name="OSNextCharacter" type="TextureRect" parent="VBoxContainer/Editor/HSplitContainer/Region/RegionView/Viewport/ReferenceRect"]
visible = false
modulate = Color(1, 0, 0, 0.501961)
layout_mode = 0
offset_right = 1.0
offset_bottom = 1.0
size_flags_horizontal = 4
size_flags_vertical = 4
texture = SubResource("AtlasTexture_iddor")
stretch_mode = 2
[node name="ReferenceRect" type="ReferenceRect" parent="VBoxContainer/Editor/HSplitContainer/Region/RegionView/Viewport/ReferenceRect"]
layout_mode = 0
border_color = Color(0, 0, 1, 1)
border_width = 2.0
editor_only = false
[node name="Controls" type="VBoxContainer" parent="VBoxContainer/Editor/HSplitContainer/Region"]
layout_mode = 2
[node name="region_pos" type="HBoxContainer" parent="VBoxContainer/Editor/HSplitContainer/Region/Controls"]
custom_minimum_size = Vector2(0, 32)
layout_mode = 2
[node name="Label" type="Label" parent="VBoxContainer/Editor/HSplitContainer/Region/Controls/region_pos"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 1
tooltip_text = "Position of the frame on the spritesheet."
mouse_filter = 0
text = "Region Position"
label_settings = ExtResource("2_m7ywi")
vertical_alignment = 1
[node name="value_w" type="SpinBox" parent="VBoxContainer/Editor/HSplitContainer/Region/Controls/region_pos"]
layout_mode = 2
size_flags_horizontal = 8
size_flags_vertical = 4
max_value = 8192.0
value = 500.0
select_all_on_focus = true
[node name="value_h" type="SpinBox" parent="VBoxContainer/Editor/HSplitContainer/Region/Controls/region_pos"]
layout_mode = 2
size_flags_horizontal = 8
size_flags_vertical = 4
max_value = 8192.0
value = 500.0
select_all_on_focus = true
[node name="region_size" type="HBoxContainer" parent="VBoxContainer/Editor/HSplitContainer/Region/Controls"]
custom_minimum_size = Vector2(0, 32)
layout_mode = 2
[node name="Label" type="Label" parent="VBoxContainer/Editor/HSplitContainer/Region/Controls/region_size"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 1
tooltip_text = "Size of the frame on the spritesheet."
mouse_filter = 0
text = "Region Size"
label_settings = ExtResource("2_m7ywi")
vertical_alignment = 1
[node name="autocrop" type="Button" parent="VBoxContainer/Editor/HSplitContainer/Region/Controls/region_size"]
layout_mode = 2
tooltip_text = "Crop out transparent pixels."
text = "Autocrop"
[node name="value_w" type="SpinBox" parent="VBoxContainer/Editor/HSplitContainer/Region/Controls/region_size"]
layout_mode = 2
size_flags_horizontal = 8
size_flags_vertical = 4
max_value = 8192.0
value = 500.0
select_all_on_focus = true
[node name="value_h" type="SpinBox" parent="VBoxContainer/Editor/HSplitContainer/Region/Controls/region_size"]
layout_mode = 2
size_flags_horizontal = 8
size_flags_vertical = 4
max_value = 8192.0
value = 500.0
select_all_on_focus = true
[node name="sprite_offset" type="HBoxContainer" parent="VBoxContainer/Editor/HSplitContainer/Region/Controls"]
custom_minimum_size = Vector2(0, 32)
layout_mode = 2
[node name="Label" type="Label" parent="VBoxContainer/Editor/HSplitContainer/Region/Controls/sprite_offset"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 1
tooltip_text = "Where the sprite is relative to the character size.
To FunkPanion, this is a margin.
To Sparrow, Flixel, and FNF, this is the inverse of the \"frame_x/y\" properties on each frame."
mouse_filter = 0
text = "Sprite Offset"
label_settings = ExtResource("2_m7ywi")
vertical_alignment = 1
[node name="preset" type="MenuButton" parent="VBoxContainer/Editor/HSplitContainer/Region/Controls/sprite_offset"]
layout_mode = 2
text = "Align..."
item_count = 9
popup/item_0/text = "Top Left"
popup/item_1/text = "Top"
popup/item_1/id = 1
popup/item_2/text = "Top Right"
popup/item_2/id = 2
popup/item_3/text = "Left"
popup/item_3/id = 3
popup/item_4/text = "Center"
popup/item_4/id = 4
popup/item_5/text = "Right"
popup/item_5/id = 5
popup/item_6/text = "Bottom Left"
popup/item_6/id = 6
popup/item_7/text = "Bottom"
popup/item_7/id = 7
popup/item_8/text = "Bottom Right"
popup/item_8/id = 8
[node name="value_w" type="SpinBox" parent="VBoxContainer/Editor/HSplitContainer/Region/Controls/sprite_offset"]
layout_mode = 2
size_flags_horizontal = 8
size_flags_vertical = 4
max_value = 8192.0
value = 500.0
select_all_on_focus = true
[node name="value_h" type="SpinBox" parent="VBoxContainer/Editor/HSplitContainer/Region/Controls/sprite_offset"]
layout_mode = 2
size_flags_horizontal = 8
size_flags_vertical = 4
max_value = 8192.0
value = 500.0
select_all_on_focus = true
[connection signal="pressed" from="VBoxContainer/Menu/HBoxContainer/Exit" to="." method="_on_exit_pressed"]

136
scenes/xml_wizard.tscn Normal file
View file

@ -0,0 +1,136 @@
[gd_scene load_steps=4 format=3 uid="uid://te4su73iol18"]
[ext_resource type="Texture2D" uid="uid://eudnts7c3nxy" path="res://assets/background_checker.png" id="1_cpi1h"]
[ext_resource type="Script" path="res://scripts/xmle/xml_wizard_window.gd" id="1_xn2dv"]
[sub_resource type="AtlasTexture" id="AtlasTexture_k1kbl"]
region = Rect2(0, 0, 1, 1)
[node name="Control" type="PanelContainer"]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
size_flags_vertical = 3
script = ExtResource("1_xn2dv")
[node name="MarginContainer" type="MarginContainer" parent="."]
layout_mode = 2
theme_override_constants/margin_left = 8
theme_override_constants/margin_top = 8
theme_override_constants/margin_right = 8
theme_override_constants/margin_bottom = 8
[node name="HSplitContainer" type="HSplitContainer" parent="MarginContainer"]
layout_mode = 2
size_flags_vertical = 3
theme_override_constants/separation = 0
theme_override_constants/autohide = 0
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/HSplitContainer"]
custom_minimum_size = Vector2(200, 0)
layout_mode = 2
theme_override_constants/separation = 8
[node name="AddNew" type="HBoxContainer" parent="MarginContainer/HSplitContainer/VBoxContainer"]
layout_mode = 2
[node name="name" type="LineEdit" parent="MarginContainer/HSplitContainer/VBoxContainer/AddNew"]
layout_mode = 2
size_flags_horizontal = 3
placeholder_text = "Animation Name"
[node name="switch" type="Button" parent="MarginContainer/HSplitContainer/VBoxContainer/AddNew"]
layout_mode = 2
text = "Add"
[node name="Tree" type="Tree" parent="MarginContainer/HSplitContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
allow_search = false
hide_folding = true
enable_recursive_folding = false
hide_root = true
select_mode = 1
scroll_horizontal_enabled = false
[node name="preset" type="MenuButton" parent="MarginContainer/HSplitContainer/VBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
tooltip_text = "Align all frames in the animation."
text = "Align All..."
flat = false
item_count = 9
popup/item_0/text = "Top Left"
popup/item_1/text = "Top"
popup/item_1/id = 1
popup/item_2/text = "Top Right"
popup/item_2/id = 2
popup/item_3/text = "Left"
popup/item_3/id = 3
popup/item_4/text = "Center"
popup/item_4/id = 4
popup/item_5/text = "Right"
popup/item_5/id = 5
popup/item_6/text = "Bottom Left"
popup/item_6/id = 6
popup/item_7/text = "Bottom"
popup/item_7/id = 7
popup/item_8/text = "Bottom Right"
popup/item_8/id = 8
[node name="Region" type="VBoxContainer" parent="MarginContainer/HSplitContainer"]
layout_mode = 2
theme_override_constants/separation = 8
[node name="RegionView" type="SubViewportContainer" parent="MarginContainer/HSplitContainer/Region"]
layout_mode = 2
size_flags_vertical = 3
stretch = true
[node name="Viewport" type="SubViewport" parent="MarginContainer/HSplitContainer/Region/RegionView"]
disable_3d = true
handle_input_locally = false
size = Vector2i(416, 428)
render_target_update_mode = 4
[node name="BG" type="TextureRect" parent="MarginContainer/HSplitContainer/Region/RegionView/Viewport"]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
size_flags_vertical = 3
texture = ExtResource("1_cpi1h")
stretch_mode = 1
[node name="ReferenceRect" type="ReferenceRect" parent="MarginContainer/HSplitContainer/Region/RegionView/Viewport"]
border_width = 2.0
editor_only = false
[node name="Character" type="TextureRect" parent="MarginContainer/HSplitContainer/Region/RegionView/Viewport/ReferenceRect"]
layout_mode = 0
offset_right = 1.0
offset_bottom = 1.0
size_flags_horizontal = 4
size_flags_vertical = 4
texture = SubResource("AtlasTexture_k1kbl")
stretch_mode = 2
[node name="ReferenceRect" type="ReferenceRect" parent="MarginContainer/HSplitContainer/Region/RegionView/Viewport/ReferenceRect"]
layout_mode = 0
border_color = Color(0, 0, 1, 1)
border_width = 2.0
editor_only = false
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/HSplitContainer/Region"]
layout_mode = 2
alignment = 2
[node name="Button" type="Button" parent="MarginContainer/HSplitContainer/Region/HBoxContainer"]
custom_minimum_size = Vector2(100, 0)
layout_mode = 2
text = "OK"

View file

@ -75,6 +75,7 @@ var spritesheet_anims = {
var spritesheet_anchor = SpritesheetAnchor.BOTTOM
var sprite_scale = 1.0
var sprite_flip = false
var sprite_hold = false
var spritesheet_default_opacity = 1.0
# Keybinds
@ -85,8 +86,8 @@ var bpm_increase:Array[Key] = [ KEY_R ]
var bpm_decrease:Array[Key] = [ KEY_F ]
var bpm_tsincrease:Array[Key] = [ KEY_T ]
var bpm_tsdecrease:Array[Key] = [ KEY_G ]
var bpm_opaincrease:Array[Key] = [ KEY_BRACELEFT ]
var bpm_opadecrease:Array[Key] = [ KEY_BRACERIGHT ]
var bpm_opaincrease:Array[Key] = [ KEY_Y ]
var bpm_opadecrease:Array[Key] = [ KEY_H ]
var bpm_reset:Array[Key] = [ KEY_V ]
# Bind modifiers
@ -137,6 +138,7 @@ func clone_config(config) -> void:
self.spritesheet_anchor = config.spritesheet_anchor
self.sprite_scale = config.sprite_scale
self.sprite_flip = config.sprite_flip
self.sprite_hold = config.sprite_hold
self.spritesheet_default_opacity = config.spritesheet_default_opacity
self.bpm_is_global = config.bpm_is_global
self.bpm_needs_enable = config.bpm_needs_enable
@ -170,6 +172,7 @@ func format_config() -> Dictionary:
dict.spritesheet_anims = self.spritesheet_anims.duplicate(true)
dict.sprite_scale = self.sprite_scale
dict.sprite_flip = self.sprite_flip
dict.sprite_hold = self.sprite_hold
dict.spritesheet_anchor = self.spritesheet_anchor
dict.spritesheet_default_opacity = self.spritesheet_default_opacity
dict.bpm_is_global = self.bpm_is_global
@ -188,3 +191,10 @@ func format_config() -> Dictionary:
dict.anim_needs_enable = self.anim_needs_enable
dict.anim_binds = self.anim_binds.duplicate(true)
return dict
func save_to_file(file:String) -> void:
var dict = self.format_config()
var config = ConfigFile.new()
for key in dict:
config.set_value("FunkPanion", key, dict[key])
config.save(file)

View file

@ -4,6 +4,7 @@ extends Config
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
load_from_file()
bind_keys()
func bind_keys() -> void:
bind_all_keys(self.bpm_increase, "bpm_increase")
@ -30,24 +31,21 @@ func bind_all_keys(array, action) -> void:
InputMap.action_add_event(action, ev)
func reset_settings() -> void:
var config = ConfigFile.new()
GlobalConfig.clone_config(Config.new())
config.save("user://config.cfg")
GlobalConfig.save_to_file()
bind_keys()
func save_to_file() -> void:
func save_to_file(file:String = "user://config.cfg") -> void:
var dict = self.format_config()
var config = ConfigFile.new()
for key in dict:
config.set_value("FunkPanion", key, dict[key])
config.save("user://config.cfg")
config.save(file)
bind_keys()
func load_from_file() -> void:
func load_from_file(file:String = "user://config.cfg") -> void:
var config = ConfigFile.new()
var err = config.load("user://config.cfg")
var err = config.load(file)
if err != OK:
return
@ -58,5 +56,3 @@ func load_from_file() -> void:
var value = config.get_value("FunkPanion", key)
if value != null:
self[key] = value
bind_keys()

15
scripts/GlobalEvents.gd Normal file
View file

@ -0,0 +1,15 @@
extends Node
func copy_fa(from: String, to: String) -> void:
var file_from = FileAccess.get_file_as_bytes(from)
var file_to = FileAccess.open(to, FileAccess.WRITE)
file_to.store_buffer(file_from)
file_to.close()
func _enter_tree() -> void:
print("Hello!")
func _notification(what):
if what == NOTIFICATION_WM_CLOSE_REQUEST:
print("Goodbye!")
get_tree().quit()

View file

@ -83,7 +83,7 @@ func get_props_of_animation_frame(anim:String, frameno:int):
margin = Rect2(-frame.frame_pos, frame.frame_size - frame.size)
}
static func load_image(path: String):
static func load_image(path: String) -> Image:
if path.begins_with('res'):
return load(path)
else:
@ -92,10 +92,24 @@ static func load_image(path: String):
print(str("Could not load image at: ",path))
return
var buffer = file.get_buffer(file.get_length())
var image = Image.new()
var image:Image = Image.new()
var error = image.load_png_from_buffer(buffer)
if error != OK:
print(str("Could not load image at: ",path," with error: ",error))
return
var texture = ImageTexture.create_from_image(image)
return texture
return image
static func spritesheet_to_xml(anims:Array, size: Vector2i, imgpath: String):
var xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
xml += "<TextureAtlas imagePath=\"%s\">\n" % imgpath
for animation in anims:
var animation_stack = ""
for frame in animation.frames.size():
var cur_frame = animation.frames[frame]
if cur_frame == null: continue
var frame_id = animation.name + str(frame).pad_zeros(4)
animation_stack += "\t<SubTexture name=\"%s\" x=\"%s\" y=\"%s\" width=\"%s\" height=\"%s\" frameX=\"%s\" frameY=\"%s\" frameWidth=\"%s\" frameHeight=\"%s\" />\n" % \
[ frame_id, cur_frame.pos.x, cur_frame.pos.y, cur_frame.size.x, cur_frame.size.y, -cur_frame.frame_pos.x, -cur_frame.frame_pos.y, size.x, size.y ]
xml += animation_stack
xml += "</TextureAtlas>"
return xml

View file

@ -9,7 +9,7 @@ var active_anims = []
func _ready() -> void:
texture = AtlasTexture.new()
texture.atlas = SpritesheetParser.load_image(GlobalConfig.spritesheet_image)
texture.atlas = ImageTexture.create_from_image(SpritesheetParser.load_image(GlobalConfig.spritesheet_image))
texture.region = Rect2(0, 0, 1, 1)
spritesheet_parser.parse_spritesheet(GlobalConfig.spritesheet_data)
@ -43,6 +43,9 @@ func _process(delta: float) -> void:
var beat_percentage = Tempo.beat_at_time(time - current_animation.tstamp, bpm)
if beat_percentage >= 1 and current_animation.active:
if GlobalConfig.sprite_hold and current_animation.keydown:
current_animation.tstamp = time
beat_percentage = 0
if current_animation.type == Config.SpritesheetAnimType.IDLE:
current_animation.tstamp = time
beat_percentage = 0

View file

@ -0,0 +1,27 @@
extends Button
signal change_config(config:Dictionary)
var config_events = preload("res://scenes/config_events.tscn")
@onready var root = get_tree().root
@onready var form = $"../.."
func _pressed() -> void:
var preset_window = Popup.new()
var cfev = config_events.instantiate()
preset_window.add_child(cfev)
root.add_child(preset_window)
preset_window.popup_centered_ratio()
var close = func():
preset_window.hide()
root.remove_child(preset_window)
preset_window.queue_free()
cfev.queue_free()
cfev.close.connect(close)
cfev.change_config.connect(func(config):
close.call()
change_config.emit(config)
)

View file

@ -0,0 +1,31 @@
extends Button
var config_presets = preload("res://scenes/config_presets.tscn")
@onready var root = get_tree().root
@onready var form = $"../.."
func _pressed() -> void:
var preset_window = Popup.new()
var cfps = config_presets.instantiate()
cfps.conf_reference = form.temp_config
preset_window.add_child(cfps)
root.add_child(preset_window)
preset_window.popup_centered_ratio()
var close = func():
preset_window.hide()
root.remove_child(preset_window)
preset_window.queue_free()
cfps.queue_free()
cfps.reset.connect(func():
GlobalConfig.reset_settings()
close.call()
get_tree().reload_current_scene()
)
cfps.close.connect(close)
cfps.preset_use.connect(func():
close.call()
get_tree().reload_current_scene()
)

View file

@ -1,31 +1,17 @@
extends ScrollContainer
var main_window
var exiting_to_config = false
var main_window: Window
# Called when the node enters the scene tree for the first time.
func _enter_tree() -> void:
print("enter tree")
main_window = get_tree().root
main_window.borderless = false
main_window.always_on_top = false
main_window.transparent = false
main_window.min_size = Vector2i(640, 480)
main_window.size = Vector2i(640, 480)
main_window.title = "FunkPanion Config"
ProjectSettings.set_setting("display/window/subwindows/embed_subwindows", false)
func _exit_tree() -> void:
if exiting_to_config: return
main_window.borderless = true
main_window.always_on_top = true
main_window.transparent = true
main_window.min_size = Vector2i(100, 100)
ProjectSettings.set_setting("display/window/subwindows/embed_subwindows", true)
func _on_back_button_pressed() -> void:
get_tree().change_scene_to_file("res://scenes/main.tscn")
func _on_reset_pressed() -> void:
GlobalConfig.reset_settings()
exiting_to_config = true
get_tree().reload_current_scene()

View file

@ -0,0 +1,58 @@
extends ScrollContainer
signal change_config(config:Dictionary)
signal close
var thingy_event = preload("res://scenes/thingy_event.tscn")
var events_parser:XMLParser = XMLParser.new()
var events = []
@onready var vbc = $"MarginContainer/VBoxContainer/ScrollContainer/VBoxContainer"
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
parse()
mount()
func parse():
var last_node_name = ""
events = []
events_parser.open("res://events/latest_events.xml")
while events_parser.read() != ERR_FILE_EOF:
var current = events.back()
var nt = events_parser.get_node_type()
if nt == XMLParser.NODE_TEXT:
if last_node_name == "": continue
current[last_node_name] = events_parser.get_node_data()
elif nt == XMLParser.NODE_ELEMENT:
var node_name = events_parser.get_node_name()
if node_name == "events":
continue
elif node_name == "event":
events.append({
id = events_parser.get_named_attribute_value_safe("id"),
date = events_parser.get_named_attribute_value_safe("date"),
tagline = "",
title = "",
thumb = "",
desc = ""
})
else:
last_node_name = node_name
else:
last_node_name = ""
func mount():
print(events)
for event in events:
var te = thingy_event.instantiate()
vbc.add_child(te)
te.event = event
te.do_things()
te.change_config.connect(change_config.emit)
vbc.move_child(te, 0)
func _on_close_button_pressed() -> void:
close.emit()

View file

@ -0,0 +1,76 @@
extends ScrollContainer
signal reset
signal preset_use
signal close
var dir
var conf_reference:Config
@onready var tree = $"MarginContainer/VBoxContainer/Tree"
var tree_root: TreeItem
@onready var addnew_name = $"MarginContainer/VBoxContainer/AddNew/name"
@onready var addnew_switch = $"MarginContainer/VBoxContainer/AddNew/switch"
@onready var close_icon = load("res://assets/icons/close.png")
@onready var preset_use_icon = load("res://assets/icons/preset_use.png")
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
tree.set_column_title(0, "Name")
tree.set_column_title(1, "Created")
tree_root = tree.create_item()
dir = DirAccess.open("user://presets/")
tree.button_clicked.connect(func(item:TreeItem, column:int, id:int, _mbi:int):
if column == 1:
if id == 0:
GlobalConfig.load_from_file(item.get_metadata(0))
GlobalConfig.save_to_file()
preset_use.emit()
if id == 1:
dir.remove(item.get_metadata(0))
refresh_tree()
)
addnew_switch.pressed.connect(func():
if addnew_name.text.length() > 0 and addnew_name.text.is_valid_filename():
addnew_name.text = addnew_name.text.simplify_path()
if addnew_name.text.get_extension() != "cfg":
addnew_name.text = addnew_name.text.get_basename() + ".cfg"
conf_reference.save_to_file(dir.get_current_dir().path_join(addnew_name.text))
addnew_name.text = ""
refresh_tree()
)
refresh_tree()
func refresh_tree() -> void:
for child in tree_root.get_children():
child.free()
if not dir:
DirAccess.make_dir_absolute("user://presets/")
dir = DirAccess.open("user://presets/")
dir.list_dir_begin()
var file_name = dir.get_next()
while file_name != "":
if file_name.get_extension() == "cfg":
var child:TreeItem = tree.create_item(tree_root)
var abs_file_name = dir.get_current_dir().path_join(file_name)
child.set_cell_mode(0, TreeItem.CELL_MODE_STRING)
child.set_text(0, file_name.get_basename())
var mod_time = FileAccess.get_modified_time(abs_file_name)
child.set_text(1, Time.get_datetime_string_from_unix_time(mod_time, true))
child.add_button(1, preset_use_icon)
child.add_button(1, close_icon)
child.set_metadata(0, abs_file_name)
file_name = dir.get_next()
func _on_close_button_pressed() -> void:
close.emit()
func _on_reset_button_pressed() -> void:
reset.emit()

View file

@ -1,5 +1,7 @@
extends VBoxContainer
@onready var encounters = $"Header/Encounters"
@onready var osd_dwell_time = $"OSD and UI/Controls/VBoxContainer/osd_dwell_time"
@onready var osd_fade_time = $"OSD and UI/Controls/VBoxContainer/osd_fade_time"
@onready var osd_opacity = $"OSD and UI/Controls/VBoxContainer/osd_opacity"
@ -15,6 +17,7 @@ extends VBoxContainer
@onready var spritesheet_anchor = $"Sprites/Controls/VBoxContainer/spritesheet_anchor"
@onready var sprite_scale = $"Sprites/Controls/VBoxContainer/sprite_scale"
@onready var sprite_flip = $"Sprites/Controls/VBoxContainer/sprite_flip"
@onready var sprite_hold = $"Sprites/Controls/VBoxContainer/sprite_hold"
@onready var spritesheet_default_opacity = $"Sprites/Controls/VBoxContainer/spritesheet_default_opacity"
@onready var anims = $"Binds/Controls/VBoxContainer"
@ -48,14 +51,20 @@ func _ready() -> void:
link_optionbutton_to_property(spritesheet_anchor, "spritesheet_anchor", Config.SpritesheetAnchor)
link_range_to_property(sprite_scale, "sprite_scale")
link_toggleable_to_property(sprite_flip, "sprite_flip")
link_toggleable_to_property(sprite_hold, "sprite_hold")
link_value_to_slider(spritesheet_default_opacity)
link_range_to_property(spritesheet_default_opacity, "spritesheet_default_opacity")
fuckwith_anims()
fuckwith_spritesheet_anims()
func _on_encounters_change_config(config: Dictionary) -> void:
for key in config:
GlobalConfig[key] = config[key]
GlobalConfig.save_to_file()
get_tree().reload_current_scene()
func _on_back_button_pressed() -> void:
GlobalConfig.clone_config(temp_config)
GlobalConfig.save_to_file()
var unlock_func = null

View file

@ -32,12 +32,13 @@ func _ready() -> void:
upload_file.pressed.connect(func():
if path.text.length() > 0:
print("path text yes", path.text)
if FileAccess.file_exists(path.text) and path.text.findn("user://") != 0 and ProjectSettings.localize_path(path.text).findn("user://") != 0:
if FileAccess.file_exists(path.text) and path.text.findn("user://") != 0 and path.text.findn("res://") != 0 and ProjectSettings.localize_path(path.text).findn("user://") != 0:
print("path exists")
if not DirAccess.dir_exists_absolute("user://uploads/"):
DirAccess.make_dir_absolute("user://uploads/")
var new_path = "user://uploads/".path_join(path.text.get_file())
DirAccess.copy_absolute(path.text, new_path)
var dir = DirAccess.open(path.text.get_base_dir())
dir.copy(path.text.get_file(), new_path)
path.text = new_path
file_changed.emit(new_path)
)

View file

@ -6,7 +6,9 @@ func _index_pressed(idx: int):
if idx == 0:
get_tree().change_scene_to_file("res://scenes/config.tscn")
elif idx == 1:
get_tree().quit()
get_tree().change_scene_to_file("res://scenes/xml_editor.tscn")
elif idx == 2:
get_tree().root.propagate_notification(NOTIFICATION_WM_CLOSE_REQUEST)
# Called when the node enters the scene tree for the first time.
func _ready() -> void:

View file

@ -24,6 +24,16 @@ var character_opacity = 100.0
var numerator = int(GlobalConfig.tempo_numerator)
var change_array = []
func _enter_tree() -> void:
main_window = get_tree().root
main_window.borderless = true
main_window.always_on_top = true
main_window.transparent = true
main_window.min_size = Vector2i(100, 100)
main_window.title = "FunkPanion"
main_window.set_mode(Window.MODE_WINDOWED)
ProjectSettings.set_setting("display/window/subwindows/embed_subwindows", true)
func _ready() -> void:
horiz_align.alignment = GlobalConfig.spritesheet_anchor[0]
vert_align.alignment = GlobalConfig.spritesheet_anchor[1]

View file

@ -0,0 +1,521 @@
extends Node
@onready var anims_tree = $"HSplitContainer/VSplitContainer/Animations"
@onready var frames_tree = $"HSplitContainer/VSplitContainer/Frames"
@onready var region_viewport = $"HSplitContainer/Region/RegionView/Viewport"
@onready var rg_oskin_prev_char = $"HSplitContainer/Region/RegionView/Viewport/ReferenceRect/OSPrevCharacter"
@onready var rg_oskin_next_char = $"HSplitContainer/Region/RegionView/Viewport/ReferenceRect/OSNextCharacter"
@onready var frame_count = $"HSplitContainer/VSplitContainer/Animations/frame_count"
@onready var sprite_size = $"HSplitContainer/VSplitContainer/Animations/sprite_size"
@onready var region_pos = $"HSplitContainer/Region/Controls/region_pos"
@onready var region_size = $"HSplitContainer/Region/Controls/region_size"
@onready var sprite_offset = $"HSplitContainer/Region/Controls/sprite_offset"
@onready var align_all = $"HSplitContainer/VSplitContainer/Frames/align_all"
@onready var oskin = $"HSplitContainer/VSplitContainer/Frames/oskin"
@onready var menu = $"../Menu/HBoxContainer"
@onready var close_icon = load("res://assets/icons/close.png")
@onready var frames_open_icon = load("res://assets/icons/frames_open.png")
@onready var frame_open_icon = load("res://assets/icons/frame_open.png")
@onready var arrow_up_icon = load("res://assets/icons/arrow_up.png")
@onready var arrow_down_icon = load("res://assets/icons/arrow_down.png")
var spritesheet_parser: SpritesheetParser = SpritesheetParser.new()
var preview_image:ImageTexture
var process_image:Image
var spritesheet_animations:Array = []
var spritesheet_size:Vector2i = Vector2i.ZERO
var spritesheet_frames:int = 0
var selected_animation:int = 0
var selected_frame:int = 0
var image_path = GlobalConfig.spritesheet_image
var data_path = GlobalConfig.spritesheet_data
var fuck_you_godot_signals = 0
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
var frame:ReferenceRect = region_viewport.get_node("ReferenceRect")
region_viewport.size_changed.connect(func():
frame.position = ((region_viewport.size / 2) - Vector2i(frame.size / 2)) - Vector2i.ONE
)
link_range_to_callable(frame_count, func(val: int):
for animation in spritesheet_animations:
spritesheet_frames = val
if selected_frame >= spritesheet_frames:
selected_frame = spritesheet_frames - 1
animation.frames.resize(spritesheet_frames)
set_frames_tree()
, spritesheet_frames)
link_pos_to_callable_e(sprite_size, func(_val: int):
spritesheet_size = get_vector(sprite_size)
set_region_view()
)
link_pos_to_callable_e(region_pos, func(_val: int):
if ts_dont_change_internal: return
set_property_on_current_frame("pos", get_vector(region_pos))
set_region_view()
set_frames_tree()
)
link_pos_to_callable_e(region_size, func(_val: int):
if ts_dont_change_internal: return
set_property_on_current_frame("size", get_vector(region_size))
set_region_view()
set_frames_tree()
)
link_pos_to_callable_e(sprite_offset, func(_val: int):
if ts_dont_change_internal: return
set_property_on_current_frame("frame_pos", get_vector(sprite_offset))
set_region_view()
set_frames_tree()
)
var rs_autocrop:Button = region_size.get_node("autocrop")
rs_autocrop.pressed.connect(func():
var pos = get_property_on_current_frame("pos")
var size = get_property_on_current_frame("size")
var cropped_image = process_image.get_region(Rect2i(pos, size))
var flood_fill_result = cropped_image.get_used_rect()
set_property_on_current_frame("pos", flood_fill_result.position + pos)
set_property_on_current_frame("size", flood_fill_result.size)
update_current_frame_child()
set_region_view()
set_three_stooges()
)
var aa_autocrop:Button = align_all.get_node("autocrop")
aa_autocrop.pressed.connect(func():
var cur_anim = spritesheet_animations[selected_animation]
if cur_anim.frames.size() < 1: return
for cur_frame in cur_anim.frames:
if cur_frame == null: continue
var cropped_image = process_image.get_region(Rect2i(cur_frame.pos, cur_frame.size))
var flood_fill_result = cropped_image.get_used_rect()
cur_frame.pos = (flood_fill_result.position + cur_frame.pos).max(cur_frame.pos)
cur_frame.size = flood_fill_result.size.min(cur_frame.size)
set_frames_tree()
set_region_view()
set_three_stooges()
)
var so_preset:MenuButton = sprite_offset.get_node("preset")
var sopre_pop:PopupMenu = so_preset.get_popup()
sopre_pop.index_pressed.connect(func(idx: int):
var frame_size = get_property_on_current_frame("size")
if frame_size == null: return
set_property_on_current_frame("frame_pos", align_to_vector(idx, frame_size, spritesheet_size))
set_region_view()
set_three_stooges()
)
var aa_preset:MenuButton = align_all.get_node("preset")
var aapre_pop:PopupMenu = aa_preset.get_popup()
aapre_pop.index_pressed.connect(func(idx: int):
var cur_anim = spritesheet_animations[selected_animation]
if cur_anim.frames.size() < 1: return
for cur_frame in cur_anim.frames:
if cur_frame == null: continue
cur_frame.frame_pos = align_to_vector(idx, cur_frame.size, spritesheet_size)
set_region_view()
set_three_stooges()
)
var oskin_prev:CheckBox = oskin.get_node("prev")
var oskin_next:CheckBox = oskin.get_node("next")
oskin_prev.toggled.connect(func(on:bool):
rg_oskin_prev_char.visible = on
)
oskin_next.toggled.connect(func(on:bool):
rg_oskin_next_char.visible = on
)
var load = menu.get_node("Load")
load.load_image.connect(func(path):
image_path = path
init_form_image()
)
load.load_xml.connect(func(path):
data_path = path
init_form_xml()
)
var save = menu.get_node("Save")
save.pressed.connect(func():
var xml = spritesheet_parser.spritesheet_to_xml(spritesheet_animations, spritesheet_size, image_path)
save.save(xml)
)
fuck_with_frames_tree()
fuck_with_anims_tree()
init_form_image()
init_form_xml()
func init_form_xml() -> void:
spritesheet_parser.parse_spritesheet(data_path)
spritesheet_size = spritesheet_parser.max_dimensions
spritesheet_animations = []
spritesheet_frames = 0
for animation in spritesheet_parser.spritesheet:
var frames = spritesheet_parser.spritesheet[animation]
for fr_ame in frames:
fr_ame.frame_pos = -fr_ame.frame_pos
fr_ame.erase("frame_size")
spritesheet_frames = max(frames.size(), spritesheet_frames)
spritesheet_animations.append({
name = animation,
frames = frames
})
for animation in spritesheet_animations:
animation.frames.resize(spritesheet_frames)
var ct:Range = frame_count.get_node("value")
ct.value = spritesheet_frames
set_vector(sprite_size, spritesheet_size)
set_frames_tree()
set_anims_tree()
func init_form_image() -> void:
process_image = SpritesheetParser.load_image(image_path)
preview_image = ImageTexture.create_from_image(process_image)
fuck_with_region_view()
func align_to_vector(idx:int, cs:Vector2i, ps:Vector2i) -> Vector2i:
var vector = Vector2i.ZERO
match idx:
1, 4, 7:
vector.x = (ps.x / 2) - (cs.x / 2)
2, 5, 8:
vector.x = ps.x - cs.x
match idx:
3, 4, 5:
vector.y = (ps.y / 2) - (cs.y / 2)
6, 7, 8:
vector.y = ps.y - cs.y
return vector
func link_range_to_callable(obj:BoxContainer, callable:Callable, value) -> void:
var input:Range = obj.get_node("value")
input.value = value
input.value_changed.connect(callable)
func set_vector(obj:BoxContainer, vector:Vector2) -> void:
var x:Range = obj.get_node("value_w")
var y:Range = obj.get_node("value_h")
x.set_value_no_signal(vector.x)
y.set_value_no_signal(vector.y)
func get_vector(obj:BoxContainer) -> Vector2:
var x:Range = obj.get_node("value_w")
var y:Range = obj.get_node("value_h")
return Vector2(x.value, y.value)
func link_pos_to_callable(obj:BoxContainer, callable:Callable, value:Vector2i) -> void:
var x:Range = obj.get_node("value_w")
var y:Range = obj.get_node("value_h")
x.value = value.x
y.value = value.y
x.value_changed.connect(callable)
y.value_changed.connect(callable)
func link_pos_to_callable_e(obj:BoxContainer, callable:Callable) -> void:
var x:Range = obj.get_node("value_w")
var y:Range = obj.get_node("value_h")
x.value_changed.connect(callable)
y.value_changed.connect(callable)
var dont_change_internal = false
func fuck_with_anims_tree() -> void:
var tree:Tree = anims_tree.get_node("Tree")
var add_new_name:LineEdit = anims_tree.get_node("AddNew/name")
var add_new_switch:Button = anims_tree.get_node("AddNew/switch")
var tree_root = tree.create_item()
tree.button_clicked.connect(func(item:TreeItem, column:int, id:int, _mbi):
var item_index = item.get_index()
if column == 0:
if id == 0:
spritesheet_animations.remove_at(item_index)
if selected_animation == item_index:
selected_animation = max(item_index - 1, 0)
if selected_animation > -1:
tree.set_selected(tree_root.get_child(selected_animation), 0)
set_anims_tree()
set_frames_tree()
)
tree.item_selected.connect(func():
if dont_change_internal:
dont_change_internal = false
return
var item = tree.get_selected()
selected_animation = item.get_index()
set_frames_tree()
)
add_new_switch.pressed.connect(func():
var text = add_new_name.text
if text.length() < 1:
return
for anim in spritesheet_animations:
if anim.name == text: return
var frames = []
frames.resize(spritesheet_frames)
spritesheet_animations.append({
name = text,
frames = frames
})
set_anims_tree()
add_new_name.text = ""
)
func set_anims_tree() -> void:
var tree:Tree = anims_tree.get_node("Tree")
var tree_root = tree.get_root()
for child in tree_root.get_children():
child.free()
for animation in spritesheet_animations:
var child = tree.create_item(tree_root)
child.set_cell_mode(0, TreeItem.CELL_MODE_STRING)
child.set_editable(0, false)
child.set_text(0, animation.name)
child.add_button(0, close_icon, 0)
dont_change_internal = true
tree.set_selected(tree_root.get_child(selected_animation), 0)
func fuck_with_frames_tree() -> void:
var tree:Tree = frames_tree.get_node("Tree")
var tree_root = tree.create_item()
tree_root.set_cell_mode(0, TreeItem.CELL_MODE_STRING)
tree_root.set_editable(0, false)
tree_root.set_text(0, "No animation selected")
tree.button_clicked.connect(func(item:TreeItem, column:int, id:int, _mbi):
var item_index = item.get_index()
var cur_anim = spritesheet_animations[selected_animation]
if item_index >= cur_anim.frames.size(): return
if column == 1:
var frame = cur_anim.frames[item_index]
var duplicate = Input.is_action_pressed("mod_enable")
if id == 0:
if item_index + 1 >= cur_anim.frames.size(): return
var next_frame = cur_anim.frames[item_index + 1]
var placeholder
if next_frame != null and not duplicate:
placeholder = next_frame.duplicate(false)
cur_anim.frames[item_index + 1] = frame.duplicate(false)
if next_frame != null and not duplicate:
cur_anim.frames[item_index] = placeholder
if id == 1:
if item_index - 1 < 0: return
var prev_frame = cur_anim.frames[item_index - 1]
var placeholder = prev_frame.duplicate(false)
cur_anim.frames[item_index - 1] = frame.duplicate(false)
cur_anim.frames[item_index] = placeholder
set_frames_tree()
)
tree.item_edited.connect(func():
var text = tree_root.get_text(0)
if text.length() < 1:
tree_root.set_text(0, spritesheet_animations[selected_animation].name)
return
for anim in spritesheet_animations:
if anim.name == text:
tree_root.set_text(0, spritesheet_animations[selected_animation].name)
return
spritesheet_animations[selected_animation].name = text
set_anims_tree()
)
tree.item_selected.connect(func():
var item = tree.get_selected()
selected_frame = item.get_index()
set_region_view()
set_three_stooges()
)
func set_frames_tree() -> void:
var tree:Tree = frames_tree.get_node("Tree")
var tree_root = tree.get_root()
tree_root.set_editable(0, false)
tree_root.set_text(0, "No animation selected")
for child in tree_root.get_children():
child.free()
if spritesheet_animations.size() <= selected_animation:
return
var cur_anim = spritesheet_animations[selected_animation]
tree_root.set_editable(0, true)
tree_root.set_text(0, cur_anim.name)
var frames = cur_anim.frames
for frame in spritesheet_frames:
var child = tree.create_item(tree_root)
child.set_cell_mode(0, TreeItem.CELL_MODE_STRING)
child.set_editable(0, false)
child.set_text(0, "Frame #" + str(frame + 1))
child.set_cell_mode(1, TreeItem.CELL_MODE_STRING)
child.set_editable(1, false)
child.set_text(1, "640x480")
child.set_text_alignment(1, HORIZONTAL_ALIGNMENT_RIGHT)
child.add_button(1, arrow_down_icon, 0)
child.add_button(1, arrow_up_icon, 1)
if frame >= frames.size() - 1:
child.set_button_disabled(1, 0, true)
if frame <= 0:
child.set_button_disabled(1, 1, true)
if frames.size() <= frame or frames[frame] == null:
child.set_text(1, "Empty")
child.set_button_disabled(1, 1, true)
child.set_button_disabled(1, 0, true)
else:
child.set_text(1, str(frames[frame].size.x) + "x" + str(frames[frame].size.y))
tree.set_selected(tree_root.get_child(selected_frame), 0)
set_region_view()
func update_current_frame_child() -> void:
var tree:Tree = frames_tree.get_node("Tree")
var tree_root = tree.get_root()
var current_frame = tree_root.get_child(selected_frame)
if spritesheet_animations.size() <= selected_animation:
return
var frames = spritesheet_animations[selected_animation].frames
var frame = selected_frame
if current_frame == null: return
if frames.size() <= frame or frames[frame] == null:
current_frame.set_text(1, "Empty")
else:
current_frame.set_text(1, str(frames[frame].size.x) + "x" + str(frames[frame].size.y))
func fuck_with_region_view() -> void:
var frame:ReferenceRect = region_viewport.get_node("ReferenceRect")
var character:TextureRect = frame.get_node("Character")
character.texture.atlas = preview_image
rg_oskin_prev_char.texture.atlas = preview_image
rg_oskin_next_char.texture.atlas = preview_image
func set_region_view() -> void:
var frame:ReferenceRect = region_viewport.get_node("ReferenceRect")
var character:TextureRect = frame.get_node("Character")
var character_frame:ReferenceRect = frame.get_node("ReferenceRect")
var atlas:AtlasTexture = character.texture
if spritesheet_animations.size() <= selected_animation:
rg_oskin_prev_char.position = Vector2.ZERO
rg_oskin_prev_char.texture.region = Rect2(0,0,1,1)
rg_oskin_next_char.position = Vector2.ZERO
rg_oskin_next_char.texture.region = Rect2(0,0,1,1)
character.position = Vector2.ZERO
character_frame.position = Vector2.ZERO
character_frame.size = Vector2.ZERO
atlas.region = Rect2(0,0,1,1)
return
var cur_anim = spritesheet_animations[selected_animation]
if cur_anim.frames.size() < selected_frame or cur_anim.frames[selected_frame] == null:
character.position = Vector2.ZERO
character_frame.position = Vector2.ZERO
character_frame.size = Vector2.ZERO
atlas.region = Rect2(0,0,1,1)
return
var cur_frame = cur_anim.frames[selected_frame]
if selected_frame - 1 < 0 or cur_anim.frames[selected_frame - 1] == null:
rg_oskin_prev_char.position = Vector2.ZERO
rg_oskin_prev_char.texture.region = Rect2(0,0,1,1)
else:
var prev_frame = cur_anim.frames[selected_frame - 1]
rg_oskin_prev_char.position = prev_frame.frame_pos + Vector2i.ONE
rg_oskin_prev_char.texture.region = Rect2(prev_frame.pos, prev_frame.size)
if selected_frame + 1 >= cur_anim.frames.size() or cur_anim.frames[selected_frame + 1] == null:
rg_oskin_next_char.position = Vector2.ZERO
rg_oskin_next_char.texture.region = Rect2(0,0,1,1)
else:
var next_frame = cur_anim.frames[selected_frame + 1]
rg_oskin_next_char.position = next_frame.frame_pos + Vector2i.ONE
rg_oskin_next_char.texture.region = Rect2(next_frame.pos, next_frame.size)
character.position = Vector2i(cur_frame.frame_pos) + Vector2i.ONE
character_frame.position = cur_frame.frame_pos
character_frame.size = Vector2i(cur_frame.size) + Vector2i(2,2)
atlas.region = Rect2(cur_frame.pos, cur_frame.size)
frame.size = spritesheet_size + Vector2i(2,2)
frame.position = ((region_viewport.size / 2) - Vector2i(frame.size / 2)) - Vector2i.ONE
var ts_dont_change_internal = false
func set_three_stooges() -> void:
var character:TextureRect = region_viewport.get_node("ReferenceRect/Character")
var atlas:AtlasTexture = character.texture
ts_dont_change_internal = true
region_pos.release_focus()
region_size.release_focus()
sprite_offset.release_focus()
set_vector(region_pos, atlas.region.position)
set_vector(region_size, atlas.region.size)
set_vector(sprite_offset, character.position - Vector2.ONE)
ts_dont_change_internal = false
func get_property_on_current_frame(prop:String):
var cur_anim = spritesheet_animations[selected_animation]
if cur_anim.frames.size() < 1: return null
var cur_frame = cur_anim.frames[selected_frame]
if cur_frame == null: return null
return cur_frame[prop]
func set_property_on_current_frame(prop:String, value:Variant):
var cur_anim = spritesheet_animations[selected_animation]
if cur_anim.frames.size() < 1: return
var cur_frame = cur_anim.frames[selected_frame]
if cur_frame == null:
cur_anim.frames[selected_frame] = {
pos = Vector2.ZERO,
size = Vector2.ONE,
frame_pos = Vector2.ZERO
}
cur_frame = cur_anim.frames[selected_frame]
cur_frame[prop] = value

35
scripts/xmle/load.gd Normal file
View file

@ -0,0 +1,35 @@
extends MenuButton
signal load_xml(path: String)
signal load_image(path: String)
@onready var root = get_tree().root
func _ready() -> void:
var popup = self.get_popup()
popup.index_pressed.connect(func(idx: int):
if idx < 0: return
var file_dialog = FileDialog.new()
file_dialog.use_native_dialog = true
file_dialog.file_mode = FileDialog.FILE_MODE_OPEN_FILE
if idx == 0:
file_dialog.add_filter("*.xml", "Sparrow spritesheet")
elif idx == 1:
file_dialog.add_filter("*.png", "Image")
file_dialog.access = FileDialog.ACCESS_FILESYSTEM
file_dialog.current_path = OS.get_data_dir().path_join("FunkPanion/")
file_dialog.file_selected.connect(func(path_string: String):
var localized = path_string.simplify_path().replace(OS.get_data_dir().path_join("FunkPanion/"), "user://")
if idx == 0:
load_xml.emit(localized)
elif idx == 1:
load_image.emit(localized)
file_dialog.queue_free()
)
file_dialog.canceled.connect(func(path_string: String):
root.remove_child(file_dialog)
file_dialog.queue_free()
)
root.add_child(file_dialog)
file_dialog.popup()
)

22
scripts/xmle/save.gd Normal file
View file

@ -0,0 +1,22 @@
extends Button
@onready var root = get_tree().root
func save(content:String) -> void:
var file_dialog = FileDialog.new()
file_dialog.use_native_dialog = true
file_dialog.file_mode = FileDialog.FILE_MODE_SAVE_FILE
file_dialog.add_filter("*.xml", "Sparrow spritesheet")
file_dialog.access = FileDialog.ACCESS_FILESYSTEM
file_dialog.current_path = OS.get_data_dir().path_join("FunkPanion/")
file_dialog.file_selected.connect(func(path_string: String):
var file = FileAccess.open(path_string, FileAccess.WRITE)
file.store_string(content)
file_dialog.queue_free()
)
file_dialog.canceled.connect(func(path_string: String):
root.remove_child(file_dialog)
file_dialog.queue_free()
)
root.add_child(file_dialog)
file_dialog.popup()

View file

@ -0,0 +1,17 @@
extends Node
var main_window
# Called when the node enters the scene tree for the first time.
func _enter_tree() -> void:
main_window = get_tree().root
main_window.borderless = false
main_window.always_on_top = false
main_window.transparent = false
main_window.min_size = Vector2i(800, 600)
main_window.size = Vector2i(800, 600)
main_window.title = "FP XML Tuner"
ProjectSettings.set_setting("display/window/subwindows/embed_subwindows", false)
func _on_exit_pressed() -> void:
get_tree().change_scene_to_file("res://scenes/main.tscn")

View file

@ -0,0 +1,17 @@
extends Node
var main_window
# Called when the node enters the scene tree for the first time.
func _enter_tree() -> void:
main_window = get_tree().root
main_window.borderless = false
main_window.always_on_top = false
main_window.transparent = false
main_window.min_size = Vector2i(480, 270)
main_window.size = Vector2i(480, 270)
main_window.title = "Image Atlas Wizard"
ProjectSettings.set_setting("display/window/subwindows/embed_subwindows", false)
func _on_exit_pressed() -> void:
get_tree().change_scene_to_file("res://scenes/main.tscn")