diff --git a/art/FMOD Logo Black - White Background.png b/art/FMOD Logo Black - White Background.png
index 273ef6f0..b7cf1d1c 100644
Binary files a/art/FMOD Logo Black - White Background.png and b/art/FMOD Logo Black - White Background.png differ
diff --git a/art/FMOD Logo White - Black Background.png b/art/FMOD Logo White - Black Background.png
index 1780488d..3e23026c 100644
Binary files a/art/FMOD Logo White - Black Background.png and b/art/FMOD Logo White - Black Background.png differ
diff --git a/art/burns.png b/art/burns.png
index 89b08ba6..91f5ca62 100644
Binary files a/art/burns.png and b/art/burns.png differ
diff --git a/art/design ideas/charter events/1.png b/art/design ideas/charter events/1.png
index 3340e41f..64b22751 100644
Binary files a/art/design ideas/charter events/1.png and b/art/design ideas/charter events/1.png differ
diff --git a/art/design ideas/charter events/2.png b/art/design ideas/charter events/2.png
index ac451a03..3abde9e4 100644
Binary files a/art/design ideas/charter events/2.png and b/art/design ideas/charter events/2.png differ
diff --git a/art/github/windows-installation-details.png b/art/github/windows-installation-details.png
index 5ff9dc19..c1291faf 100644
Binary files a/art/github/windows-installation-details.png and b/art/github/windows-installation-details.png differ
diff --git a/art/icon16.png b/art/icon16.png
index 2adacd69..ab61bcbe 100644
Binary files a/art/icon16.png and b/art/icon16.png differ
diff --git a/art/iconOG.png b/art/iconOG.png
index b0268e51..6ec3bcd5 100644
Binary files a/art/iconOG.png and b/art/iconOG.png differ
diff --git a/art/preloaderArt.png b/art/preloaderArt.png
index 176e51b3..54498023 100644
Binary files a/art/preloaderArt.png and b/art/preloaderArt.png differ
diff --git a/art/teaser discord.png b/art/teaser discord.png
index 45fa51ef..8eb306ae 100644
Binary files a/art/teaser discord.png and b/art/teaser discord.png differ
diff --git a/art/teaser layers/teaser bg.png b/art/teaser layers/teaser bg.png
index b4e6af05..a65e5ffe 100644
Binary files a/art/teaser layers/teaser bg.png and b/art/teaser layers/teaser bg.png differ
diff --git a/art/teaser layers/teaser checkerboard.png b/art/teaser layers/teaser checkerboard.png
index f515995f..7a9e6150 100644
Binary files a/art/teaser layers/teaser checkerboard.png and b/art/teaser layers/teaser checkerboard.png differ
diff --git a/art/teaser layers/teaser funkin logo.png b/art/teaser layers/teaser funkin logo.png
index 557b740a..ee707fea 100644
Binary files a/art/teaser layers/teaser funkin logo.png and b/art/teaser layers/teaser funkin logo.png differ
diff --git a/art/teaser layers/teaser question mark.png b/art/teaser layers/teaser question mark.png
index 0cbbec86..0dc7a17d 100644
Binary files a/art/teaser layers/teaser question mark.png and b/art/teaser layers/teaser question mark.png differ
diff --git a/art/teaser.png b/art/teaser.png
index b185f7ac..ff4ed3c6 100644
Binary files a/art/teaser.png and b/art/teaser.png differ
diff --git a/art/thumbnailNewer.png b/art/thumbnailNewer.png
index 73f381fc..d5de62e8 100644
Binary files a/art/thumbnailNewer.png and b/art/thumbnailNewer.png differ
diff --git a/art/veryimportant.png b/art/veryimportant.png
index 89910647..7d6d6789 100644
Binary files a/art/veryimportant.png and b/art/veryimportant.png differ
diff --git a/assets/data/scripts/pixel.hx b/assets/data/scripts/pixel.hx
index 8f1887c8..1109f2dc 100644
--- a/assets/data/scripts/pixel.hx
+++ b/assets/data/scripts/pixel.hx
@@ -97,9 +97,6 @@ function postCreate() {
defaultCamZoom /= daPixelZoom;
}
- iconP1.antialiasing = false;
- iconP2.antialiasing = false;
-
if (enablePixelGameOver) {
gameOverSong = "pixel/gameOver";
lossSFX = "pixel/gameOverSFX";
diff --git a/assets/images/characters/bf-car.png b/assets/images/characters/bf-car.png
index 41d64ad2..f84e7ef9 100644
Binary files a/assets/images/characters/bf-car.png and b/assets/images/characters/bf-car.png differ
diff --git a/assets/images/characters/bf-christmas.png b/assets/images/characters/bf-christmas.png
index 98fc69b9..e1676f4d 100644
Binary files a/assets/images/characters/bf-christmas.png and b/assets/images/characters/bf-christmas.png differ
diff --git a/assets/images/characters/bf-dead.png b/assets/images/characters/bf-dead.png
index 6d129a65..306c865a 100644
Binary files a/assets/images/characters/bf-dead.png and b/assets/images/characters/bf-dead.png differ
diff --git a/assets/images/characters/bf-holding-gf-dead.png b/assets/images/characters/bf-holding-gf-dead.png
index 1d6f3844..014b4183 100644
Binary files a/assets/images/characters/bf-holding-gf-dead.png and b/assets/images/characters/bf-holding-gf-dead.png differ
diff --git a/assets/images/characters/bf-holding-gf.png b/assets/images/characters/bf-holding-gf.png
index 0549ae76..c1f6f1e8 100644
Binary files a/assets/images/characters/bf-holding-gf.png and b/assets/images/characters/bf-holding-gf.png differ
diff --git a/assets/images/characters/bf-pixel-dead.png b/assets/images/characters/bf-pixel-dead.png
index ddb688a2..0ecc7915 100644
Binary files a/assets/images/characters/bf-pixel-dead.png and b/assets/images/characters/bf-pixel-dead.png differ
diff --git a/assets/images/characters/bf-pixel.png b/assets/images/characters/bf-pixel.png
index eb78553d..a9675b9b 100644
Binary files a/assets/images/characters/bf-pixel.png and b/assets/images/characters/bf-pixel.png differ
diff --git a/assets/images/characters/bf.png b/assets/images/characters/bf.png
index 2722d1c1..71f8ae96 100644
Binary files a/assets/images/characters/bf.png and b/assets/images/characters/bf.png differ
diff --git a/assets/images/characters/da.png b/assets/images/characters/da.png
index 9a1a2da5..af87c9c8 100644
Binary files a/assets/images/characters/da.png and b/assets/images/characters/da.png differ
diff --git a/assets/images/characters/dad.png b/assets/images/characters/dad.png
index cd37de1c..1bc637a4 100644
Binary files a/assets/images/characters/dad.png and b/assets/images/characters/dad.png differ
diff --git a/assets/images/characters/gf-car/spritemap1.png b/assets/images/characters/gf-car/spritemap1.png
index c7f64af5..25fbeae7 100644
Binary files a/assets/images/characters/gf-car/spritemap1.png and b/assets/images/characters/gf-car/spritemap1.png differ
diff --git a/assets/images/characters/gf-christmas/spritemap1.png b/assets/images/characters/gf-christmas/spritemap1.png
index 9b28e8ab..41325d0a 100644
Binary files a/assets/images/characters/gf-christmas/spritemap1.png and b/assets/images/characters/gf-christmas/spritemap1.png differ
diff --git a/assets/images/characters/gf-pixel.png b/assets/images/characters/gf-pixel.png
index fb3d596c..6bb4d9b9 100644
Binary files a/assets/images/characters/gf-pixel.png and b/assets/images/characters/gf-pixel.png differ
diff --git a/assets/images/characters/gf-tankmen/spritemap1.png b/assets/images/characters/gf-tankmen/spritemap1.png
index 7511af39..81f91c24 100644
Binary files a/assets/images/characters/gf-tankmen/spritemap1.png and b/assets/images/characters/gf-tankmen/spritemap1.png differ
diff --git a/assets/images/characters/gf/spritemap1.png b/assets/images/characters/gf/spritemap1.png
index ac70fc2d..488bde86 100644
Binary files a/assets/images/characters/gf/spritemap1.png and b/assets/images/characters/gf/spritemap1.png differ
diff --git a/assets/images/characters/mom-car.png b/assets/images/characters/mom-car.png
index 3c9405ac..8bb65934 100644
Binary files a/assets/images/characters/mom-car.png and b/assets/images/characters/mom-car.png differ
diff --git a/assets/images/characters/mom.png b/assets/images/characters/mom.png
index 033929a5..abf6cc6e 100644
Binary files a/assets/images/characters/mom.png and b/assets/images/characters/mom.png differ
diff --git a/assets/images/characters/monster-christmas.png b/assets/images/characters/monster-christmas.png
index 7dd02243..38795bb0 100644
Binary files a/assets/images/characters/monster-christmas.png and b/assets/images/characters/monster-christmas.png differ
diff --git a/assets/images/characters/monster.png b/assets/images/characters/monster.png
index 451d21b1..cb51575c 100644
Binary files a/assets/images/characters/monster.png and b/assets/images/characters/monster.png differ
diff --git a/assets/images/characters/parents-christmas.png b/assets/images/characters/parents-christmas.png
index e13fee01..947535e3 100644
Binary files a/assets/images/characters/parents-christmas.png and b/assets/images/characters/parents-christmas.png differ
diff --git a/assets/images/characters/pico-speakers.png b/assets/images/characters/pico-speakers.png
index f20d1a80..86d059a8 100644
Binary files a/assets/images/characters/pico-speakers.png and b/assets/images/characters/pico-speakers.png differ
diff --git a/assets/images/characters/pico.png b/assets/images/characters/pico.png
index 12c083d2..476e06ea 100644
Binary files a/assets/images/characters/pico.png and b/assets/images/characters/pico.png differ
diff --git a/assets/images/characters/senpai.png b/assets/images/characters/senpai.png
index 1c7f8f52..c4ab53ad 100644
Binary files a/assets/images/characters/senpai.png and b/assets/images/characters/senpai.png differ
diff --git a/assets/images/characters/spooky.png b/assets/images/characters/spooky.png
index f941ec2d..742a7623 100644
Binary files a/assets/images/characters/spooky.png and b/assets/images/characters/spooky.png differ
diff --git a/assets/images/characters/tankman.png b/assets/images/characters/tankman.png
index edfda54a..7f621ae8 100644
Binary files a/assets/images/characters/tankman.png and b/assets/images/characters/tankman.png differ
diff --git a/assets/images/credits/credit icon example.png b/assets/images/credits/credit icon example.png
index adbf906d..281fae23 100644
Binary files a/assets/images/credits/credit icon example.png and b/assets/images/credits/credit icon example.png differ
diff --git a/assets/images/dialogue/boxes/default.png b/assets/images/dialogue/boxes/default.png
index 1c22d73b..e8dc2f84 100644
Binary files a/assets/images/dialogue/boxes/default.png and b/assets/images/dialogue/boxes/default.png differ
diff --git a/assets/images/dialogue/boxes/pixel/dialogueBox-evil.png b/assets/images/dialogue/boxes/pixel/dialogueBox-evil.png
index fcbbfec3..18dcec5a 100644
Binary files a/assets/images/dialogue/boxes/pixel/dialogueBox-evil.png and b/assets/images/dialogue/boxes/pixel/dialogueBox-evil.png differ
diff --git a/assets/images/dialogue/boxes/pixel/dialogueBox.png b/assets/images/dialogue/boxes/pixel/dialogueBox.png
index 73afeea9..09d4c490 100644
Binary files a/assets/images/dialogue/boxes/pixel/dialogueBox.png and b/assets/images/dialogue/boxes/pixel/dialogueBox.png differ
diff --git a/assets/images/dialogue/characters/boyfriend.png b/assets/images/dialogue/characters/boyfriend.png
index 341ba166..f921159d 100644
Binary files a/assets/images/dialogue/characters/boyfriend.png and b/assets/images/dialogue/characters/boyfriend.png differ
diff --git a/assets/images/dialogue/characters/dad.png b/assets/images/dialogue/characters/dad.png
index de81cf3c..c1e21467 100644
Binary files a/assets/images/dialogue/characters/dad.png and b/assets/images/dialogue/characters/dad.png differ
diff --git a/assets/images/editors/autosave-delete.png b/assets/images/editors/autosave-delete.png
index 18ab7de0..3e4b8ab2 100644
Binary files a/assets/images/editors/autosave-delete.png and b/assets/images/editors/autosave-delete.png differ
diff --git a/assets/images/editors/autosave-icons.png b/assets/images/editors/autosave-icons.png
index 26f99bc2..6b5136f4 100644
Binary files a/assets/images/editors/autosave-icons.png and b/assets/images/editors/autosave-icons.png differ
diff --git a/assets/images/editors/bgs/charter.png b/assets/images/editors/bgs/charter.png
index e1a6f93a..03ea9580 100644
Binary files a/assets/images/editors/bgs/charter.png and b/assets/images/editors/bgs/charter.png differ
diff --git a/assets/images/editors/character/WOAH.png b/assets/images/editors/character/WOAH.png
index 8821bc1d..824b1d1a 100644
Binary files a/assets/images/editors/character/WOAH.png and b/assets/images/editors/character/WOAH.png differ
diff --git a/assets/images/editors/character/edit-button.png b/assets/images/editors/character/edit-button.png
index 4667961d..66c49aa8 100644
Binary files a/assets/images/editors/character/edit-button.png and b/assets/images/editors/character/edit-button.png differ
diff --git a/assets/images/editors/character/ghost-button.png b/assets/images/editors/character/ghost-button.png
index fa8e032b..a383bffd 100644
Binary files a/assets/images/editors/character/ghost-button.png and b/assets/images/editors/character/ghost-button.png differ
diff --git a/assets/images/editors/charter/add-button.png b/assets/images/editors/charter/add-button.png
index 906d8ca3..defdb6ef 100644
Binary files a/assets/images/editors/charter/add-button.png and b/assets/images/editors/charter/add-button.png differ
diff --git a/assets/images/editors/charter/event-icons/Add Camera Zoom.png b/assets/images/editors/charter/event-icons/Add Camera Zoom.png
index 48ce845c..044b1196 100644
Binary files a/assets/images/editors/charter/event-icons/Add Camera Zoom.png and b/assets/images/editors/charter/event-icons/Add Camera Zoom.png differ
diff --git a/assets/images/editors/charter/event-icons/Alt Animation Toggle.png b/assets/images/editors/charter/event-icons/Alt Animation Toggle.png
index e982158a..a2046320 100644
Binary files a/assets/images/editors/charter/event-icons/Alt Animation Toggle.png and b/assets/images/editors/charter/event-icons/Alt Animation Toggle.png differ
diff --git a/assets/images/editors/charter/event-icons/Camera Flash.png b/assets/images/editors/charter/event-icons/Camera Flash.png
index 22903bea..3abfd1cc 100644
Binary files a/assets/images/editors/charter/event-icons/Camera Flash.png and b/assets/images/editors/charter/event-icons/Camera Flash.png differ
diff --git a/assets/images/editors/charter/event-icons/Camera Modulo Change.png b/assets/images/editors/charter/event-icons/Camera Modulo Change.png
index 5eb5f064..27353aeb 100644
Binary files a/assets/images/editors/charter/event-icons/Camera Modulo Change.png and b/assets/images/editors/charter/event-icons/Camera Modulo Change.png differ
diff --git a/assets/images/editors/charter/event-icons/Camera Movement.png b/assets/images/editors/charter/event-icons/Camera Movement.png
index 3126c502..74ba908a 100644
Binary files a/assets/images/editors/charter/event-icons/Camera Movement.png and b/assets/images/editors/charter/event-icons/Camera Movement.png differ
diff --git a/assets/images/editors/charter/event-icons/HScript Call.png b/assets/images/editors/charter/event-icons/HScript Call.png
index 5aa4095a..f63e4a2b 100644
Binary files a/assets/images/editors/charter/event-icons/HScript Call.png and b/assets/images/editors/charter/event-icons/HScript Call.png differ
diff --git a/assets/images/editors/charter/event-icons/Play Animation.png b/assets/images/editors/charter/event-icons/Play Animation.png
index 1092f05f..54da0eb4 100644
Binary files a/assets/images/editors/charter/event-icons/Play Animation.png and b/assets/images/editors/charter/event-icons/Play Animation.png differ
diff --git a/assets/images/editors/charter/event-icons/Scroll Speed Change.png b/assets/images/editors/charter/event-icons/Scroll Speed Change.png
index 4b06071c..97b6fc95 100644
Binary files a/assets/images/editors/charter/event-icons/Scroll Speed Change.png and b/assets/images/editors/charter/event-icons/Scroll Speed Change.png differ
diff --git a/assets/images/editors/charter/event-icons/Unknown.png b/assets/images/editors/charter/event-icons/Unknown.png
index 26ac16c6..5fbbdbb8 100644
Binary files a/assets/images/editors/charter/event-icons/Unknown.png and b/assets/images/editors/charter/event-icons/Unknown.png differ
diff --git a/assets/images/editors/charter/event-spr-add.png b/assets/images/editors/charter/event-spr-add.png
index 21cc06d9..5898ea3b 100644
Binary files a/assets/images/editors/charter/event-spr-add.png and b/assets/images/editors/charter/event-spr-add.png differ
diff --git a/assets/images/editors/charter/event-spr.png b/assets/images/editors/charter/event-spr.png
index 45149581..1d006cff 100644
Binary files a/assets/images/editors/charter/event-spr.png and b/assets/images/editors/charter/event-spr.png differ
diff --git a/assets/images/editors/charter/event.png b/assets/images/editors/charter/event.png
index 8fe12787..c4f15c42 100644
Binary files a/assets/images/editors/charter/event.png and b/assets/images/editors/charter/event.png differ
diff --git a/assets/images/editors/charter/events-grid.png b/assets/images/editors/charter/events-grid.png
index 3a4f90e6..a49b3d72 100644
Binary files a/assets/images/editors/charter/events-grid.png and b/assets/images/editors/charter/events-grid.png differ
diff --git a/assets/images/editors/charter/lock-strumline.png b/assets/images/editors/charter/lock-strumline.png
index 637e5f64..3175325c 100644
Binary files a/assets/images/editors/charter/lock-strumline.png and b/assets/images/editors/charter/lock-strumline.png differ
diff --git a/assets/images/editors/charter/strumline-info-bg.png b/assets/images/editors/charter/strumline-info-bg.png
index 74d7d906..ba43e8ce 100644
Binary files a/assets/images/editors/charter/strumline-info-bg.png and b/assets/images/editors/charter/strumline-info-bg.png differ
diff --git a/assets/images/editors/delete-button.png b/assets/images/editors/delete-button.png
index 4a80427c..386c6662 100644
Binary files a/assets/images/editors/delete-button.png and b/assets/images/editors/delete-button.png differ
diff --git a/assets/images/editors/deleter circle.png b/assets/images/editors/deleter circle.png
index c4120b13..db63b885 100644
Binary files a/assets/images/editors/deleter circle.png and b/assets/images/editors/deleter circle.png differ
diff --git a/assets/images/editors/deleter.png b/assets/images/editors/deleter.png
index c3c39bcc..a872a17a 100644
Binary files a/assets/images/editors/deleter.png and b/assets/images/editors/deleter.png differ
diff --git a/assets/images/editors/icons.png b/assets/images/editors/icons.png
index 41dee63c..aecb3911 100644
Binary files a/assets/images/editors/icons.png and b/assets/images/editors/icons.png differ
diff --git a/assets/images/editors/new.png b/assets/images/editors/new.png
index 461fd2ea..5a062188 100644
Binary files a/assets/images/editors/new.png and b/assets/images/editors/new.png differ
diff --git a/assets/images/editors/ui/audio-buttons.png b/assets/images/editors/ui/audio-buttons.png
index 6bd347a8..7719e8eb 100644
Binary files a/assets/images/editors/ui/audio-buttons.png and b/assets/images/editors/ui/audio-buttons.png differ
diff --git a/assets/images/editors/ui/audio-icon.png b/assets/images/editors/ui/audio-icon.png
index 97eb7763..575450ba 100644
Binary files a/assets/images/editors/ui/audio-icon.png and b/assets/images/editors/ui/audio-icon.png differ
diff --git a/assets/images/editors/ui/audio-time-empty.png b/assets/images/editors/ui/audio-time-empty.png
index b08c0154..3efd42bf 100644
Binary files a/assets/images/editors/ui/audio-time-empty.png and b/assets/images/editors/ui/audio-time-empty.png differ
diff --git a/assets/images/editors/ui/audio-time-full.png b/assets/images/editors/ui/audio-time-full.png
index 85c4e77c..bd5ecd44 100644
Binary files a/assets/images/editors/ui/audio-time-full.png and b/assets/images/editors/ui/audio-time-full.png differ
diff --git a/assets/images/editors/ui/audio-volume-empty.png b/assets/images/editors/ui/audio-volume-empty.png
index 290f8099..c876657b 100644
Binary files a/assets/images/editors/ui/audio-volume-empty.png and b/assets/images/editors/ui/audio-volume-empty.png differ
diff --git a/assets/images/editors/ui/audio-volume-full.png b/assets/images/editors/ui/audio-volume-full.png
index eebab268..0304b3e3 100644
Binary files a/assets/images/editors/ui/audio-volume-full.png and b/assets/images/editors/ui/audio-volume-full.png differ
diff --git a/assets/images/editors/ui/button.png b/assets/images/editors/ui/button.png
index dc270bee..3107e42c 100644
Binary files a/assets/images/editors/ui/button.png and b/assets/images/editors/ui/button.png differ
diff --git a/assets/images/editors/ui/checkbox.png b/assets/images/editors/ui/checkbox.png
index 95ef7ccb..e4bdd9bb 100644
Binary files a/assets/images/editors/ui/checkbox.png and b/assets/images/editors/ui/checkbox.png differ
diff --git a/assets/images/editors/ui/context-bg.png b/assets/images/editors/ui/context-bg.png
index 4e46b537..1e4c74b3 100644
Binary files a/assets/images/editors/ui/context-bg.png and b/assets/images/editors/ui/context-bg.png differ
diff --git a/assets/images/editors/ui/context-icons.png b/assets/images/editors/ui/context-icons.png
index 733a8523..b7411d02 100644
Binary files a/assets/images/editors/ui/context-icons.png and b/assets/images/editors/ui/context-icons.png differ
diff --git a/assets/images/editors/ui/inputbox.png b/assets/images/editors/ui/inputbox.png
index f3b1df34..6c38457b 100644
Binary files a/assets/images/editors/ui/inputbox.png and b/assets/images/editors/ui/inputbox.png differ
diff --git a/assets/images/editors/ui/menu-item.png b/assets/images/editors/ui/menu-item.png
index 5babc03a..4a95616f 100644
Binary files a/assets/images/editors/ui/menu-item.png and b/assets/images/editors/ui/menu-item.png differ
diff --git a/assets/images/editors/ui/normal-popup.png b/assets/images/editors/ui/normal-popup.png
index 1227df6d..a4a0746b 100644
Binary files a/assets/images/editors/ui/normal-popup.png and b/assets/images/editors/ui/normal-popup.png differ
diff --git a/assets/images/editors/ui/scrollbar-bg.png b/assets/images/editors/ui/scrollbar-bg.png
index 1f49a24a..55fded94 100644
Binary files a/assets/images/editors/ui/scrollbar-bg.png and b/assets/images/editors/ui/scrollbar-bg.png differ
diff --git a/assets/images/editors/ui/scrollbar-icon.png b/assets/images/editors/ui/scrollbar-icon.png
index f2a5c0ec..feb29469 100644
Binary files a/assets/images/editors/ui/scrollbar-icon.png and b/assets/images/editors/ui/scrollbar-icon.png differ
diff --git a/assets/images/editors/ui/selection.png b/assets/images/editors/ui/selection.png
index 456897fe..2d95a2d1 100644
Binary files a/assets/images/editors/ui/selection.png and b/assets/images/editors/ui/selection.png differ
diff --git a/assets/images/editors/ui/slider.png b/assets/images/editors/ui/slider.png
index 82b6c80b..13758fbe 100644
Binary files a/assets/images/editors/ui/slider.png and b/assets/images/editors/ui/slider.png differ
diff --git a/assets/images/editors/ui/textbox.png b/assets/images/editors/ui/textbox.png
index a66637a4..2ada0766 100644
Binary files a/assets/images/editors/ui/textbox.png and b/assets/images/editors/ui/textbox.png differ
diff --git a/assets/images/editors/ui/topmenu.png b/assets/images/editors/ui/topmenu.png
index 4f010db4..3824c37f 100644
Binary files a/assets/images/editors/ui/topmenu.png and b/assets/images/editors/ui/topmenu.png differ
diff --git a/assets/images/editors/ui/upload-button.png b/assets/images/editors/ui/upload-button.png
index bfdba151..f3700640 100644
Binary files a/assets/images/editors/ui/upload-button.png and b/assets/images/editors/ui/upload-button.png differ
diff --git a/assets/images/editors/warnings/error.png b/assets/images/editors/warnings/error.png
index 07282f8b..aef47776 100644
Binary files a/assets/images/editors/warnings/error.png and b/assets/images/editors/warnings/error.png differ
diff --git a/assets/images/editors/warnings/warning.png b/assets/images/editors/warnings/warning.png
index 1d501046..44e8b560 100644
Binary files a/assets/images/editors/warnings/warning.png and b/assets/images/editors/warnings/warning.png differ
diff --git a/assets/images/game/cutscenes/tank/guns-tankman/spritemap1.png b/assets/images/game/cutscenes/tank/guns-tankman/spritemap1.png
index 337491b6..ccfe25ee 100644
Binary files a/assets/images/game/cutscenes/tank/guns-tankman/spritemap1.png and b/assets/images/game/cutscenes/tank/guns-tankman/spritemap1.png differ
diff --git a/assets/images/game/cutscenes/tank/stress-tankman/spritemap1.png b/assets/images/game/cutscenes/tank/stress-tankman/spritemap1.png
index 7ed88503..22a814a2 100644
Binary files a/assets/images/game/cutscenes/tank/stress-tankman/spritemap1.png and b/assets/images/game/cutscenes/tank/stress-tankman/spritemap1.png differ
diff --git a/assets/images/game/cutscenes/tank/ugh-tankman/spritemap1.png b/assets/images/game/cutscenes/tank/ugh-tankman/spritemap1.png
index 957cae53..b871f1f7 100644
Binary files a/assets/images/game/cutscenes/tank/ugh-tankman/spritemap1.png and b/assets/images/game/cutscenes/tank/ugh-tankman/spritemap1.png differ
diff --git a/assets/images/game/cutscenes/weeb/senpaiCrazy.png b/assets/images/game/cutscenes/weeb/senpaiCrazy.png
index 1091f92a..c35d2912 100644
Binary files a/assets/images/game/cutscenes/weeb/senpaiCrazy.png and b/assets/images/game/cutscenes/weeb/senpaiCrazy.png differ
diff --git a/assets/images/game/cutscenes/weeb/spiritFaceForward.png b/assets/images/game/cutscenes/weeb/spiritFaceForward.png
index 93c7ed04..9bf698ed 100644
Binary files a/assets/images/game/cutscenes/weeb/spiritFaceForward.png and b/assets/images/game/cutscenes/weeb/spiritFaceForward.png differ
diff --git a/assets/images/game/go.png b/assets/images/game/go.png
index 78cc7f68..d82c6b6d 100644
Binary files a/assets/images/game/go.png and b/assets/images/game/go.png differ
diff --git a/assets/images/game/healthBar.png b/assets/images/game/healthBar.png
index 8bfec941..08babb89 100644
Binary files a/assets/images/game/healthBar.png and b/assets/images/game/healthBar.png differ
diff --git a/assets/images/game/ready.png b/assets/images/game/ready.png
index 1ee103df..d6e8d062 100644
Binary files a/assets/images/game/ready.png and b/assets/images/game/ready.png differ
diff --git a/assets/images/game/restart.png b/assets/images/game/restart.png
index 82c210d0..34ce8252 100644
Binary files a/assets/images/game/restart.png and b/assets/images/game/restart.png differ
diff --git a/assets/images/game/score/bad.png b/assets/images/game/score/bad.png
index 7b7c7398..77c55576 100644
Binary files a/assets/images/game/score/bad.png and b/assets/images/game/score/bad.png differ
diff --git a/assets/images/game/score/combo.png b/assets/images/game/score/combo.png
index ffc94f44..450b7a11 100644
Binary files a/assets/images/game/score/combo.png and b/assets/images/game/score/combo.png differ
diff --git a/assets/images/game/score/good.png b/assets/images/game/score/good.png
index d6c8f386..0a9f4551 100644
Binary files a/assets/images/game/score/good.png and b/assets/images/game/score/good.png differ
diff --git a/assets/images/game/score/num0.png b/assets/images/game/score/num0.png
index 83958371..80b601e8 100644
Binary files a/assets/images/game/score/num0.png and b/assets/images/game/score/num0.png differ
diff --git a/assets/images/game/score/num1.png b/assets/images/game/score/num1.png
index 52452ae1..3255408c 100644
Binary files a/assets/images/game/score/num1.png and b/assets/images/game/score/num1.png differ
diff --git a/assets/images/game/score/num2.png b/assets/images/game/score/num2.png
index 2db35d5b..11df1c9a 100644
Binary files a/assets/images/game/score/num2.png and b/assets/images/game/score/num2.png differ
diff --git a/assets/images/game/score/num3.png b/assets/images/game/score/num3.png
index a6b32303..c2842efa 100644
Binary files a/assets/images/game/score/num3.png and b/assets/images/game/score/num3.png differ
diff --git a/assets/images/game/score/num4.png b/assets/images/game/score/num4.png
index 24f99bda..ae525c87 100644
Binary files a/assets/images/game/score/num4.png and b/assets/images/game/score/num4.png differ
diff --git a/assets/images/game/score/num5.png b/assets/images/game/score/num5.png
index 542423eb..1b16e1a8 100644
Binary files a/assets/images/game/score/num5.png and b/assets/images/game/score/num5.png differ
diff --git a/assets/images/game/score/num6.png b/assets/images/game/score/num6.png
index c6044194..682e2208 100644
Binary files a/assets/images/game/score/num6.png and b/assets/images/game/score/num6.png differ
diff --git a/assets/images/game/score/num7.png b/assets/images/game/score/num7.png
index 8b2d5498..6319ffff 100644
Binary files a/assets/images/game/score/num7.png and b/assets/images/game/score/num7.png differ
diff --git a/assets/images/game/score/num8.png b/assets/images/game/score/num8.png
index db61c3e9..c7a337ea 100644
Binary files a/assets/images/game/score/num8.png and b/assets/images/game/score/num8.png differ
diff --git a/assets/images/game/score/num9.png b/assets/images/game/score/num9.png
index 607f9ea7..e3ae145c 100644
Binary files a/assets/images/game/score/num9.png and b/assets/images/game/score/num9.png differ
diff --git a/assets/images/game/score/shit.png b/assets/images/game/score/shit.png
index 346141ad..7427ac85 100644
Binary files a/assets/images/game/score/shit.png and b/assets/images/game/score/shit.png differ
diff --git a/assets/images/game/score/sick.png b/assets/images/game/score/sick.png
index 5cbba1e2..2a3aacf4 100644
Binary files a/assets/images/game/score/sick.png and b/assets/images/game/score/sick.png differ
diff --git a/assets/images/game/set.png b/assets/images/game/set.png
index a0450751..09eabfa0 100644
Binary files a/assets/images/game/set.png and b/assets/images/game/set.png differ
diff --git a/assets/images/game/splashes/default.png b/assets/images/game/splashes/default.png
index e93fdcb7..6071b524 100644
Binary files a/assets/images/game/splashes/default.png and b/assets/images/game/splashes/default.png differ
diff --git a/assets/images/icons/bf-old.png b/assets/images/icons/bf-old.png
deleted file mode 100644
index b8369aca..00000000
Binary files a/assets/images/icons/bf-old.png and /dev/null differ
diff --git a/assets/images/icons/bf-old/icon.png b/assets/images/icons/bf-old/icon.png
new file mode 100644
index 00000000..ce349958
Binary files /dev/null and b/assets/images/icons/bf-old/icon.png differ
diff --git a/assets/images/icons/bf-pixel.png b/assets/images/icons/bf-pixel.png
deleted file mode 100644
index 1351f810..00000000
Binary files a/assets/images/icons/bf-pixel.png and /dev/null differ
diff --git a/assets/images/icons/bf-pixel/data.xml b/assets/images/icons/bf-pixel/data.xml
new file mode 100644
index 00000000..57653cad
--- /dev/null
+++ b/assets/images/icons/bf-pixel/data.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/assets/images/icons/bf-pixel/icon.png b/assets/images/icons/bf-pixel/icon.png
new file mode 100644
index 00000000..d1ae0f87
Binary files /dev/null and b/assets/images/icons/bf-pixel/icon.png differ
diff --git a/assets/images/icons/bf.png b/assets/images/icons/bf.png
deleted file mode 100644
index ab0903a7..00000000
Binary files a/assets/images/icons/bf.png and /dev/null differ
diff --git a/assets/images/icons/bf/icon.png b/assets/images/icons/bf/icon.png
new file mode 100644
index 00000000..426609fc
Binary files /dev/null and b/assets/images/icons/bf/icon.png differ
diff --git a/assets/images/icons/dad.png b/assets/images/icons/dad.png
deleted file mode 100644
index ffdf4ac1..00000000
Binary files a/assets/images/icons/dad.png and /dev/null differ
diff --git a/assets/images/icons/dad/icon.png b/assets/images/icons/dad/icon.png
new file mode 100644
index 00000000..c252c657
Binary files /dev/null and b/assets/images/icons/dad/icon.png differ
diff --git a/assets/images/icons/face.png b/assets/images/icons/face.png
deleted file mode 100644
index 622eb6dc..00000000
Binary files a/assets/images/icons/face.png and /dev/null differ
diff --git a/assets/images/icons/face/icon.png b/assets/images/icons/face/icon.png
new file mode 100644
index 00000000..bc24a5f8
Binary files /dev/null and b/assets/images/icons/face/icon.png differ
diff --git a/assets/images/icons/gf-pixel.png b/assets/images/icons/gf-pixel.png
deleted file mode 100644
index 5122ddc0..00000000
Binary files a/assets/images/icons/gf-pixel.png and /dev/null differ
diff --git a/assets/images/icons/gf-pixel/data.xml b/assets/images/icons/gf-pixel/data.xml
new file mode 100644
index 00000000..57653cad
--- /dev/null
+++ b/assets/images/icons/gf-pixel/data.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/assets/images/icons/gf-pixel/icon.png b/assets/images/icons/gf-pixel/icon.png
new file mode 100644
index 00000000..c2a6bdf6
Binary files /dev/null and b/assets/images/icons/gf-pixel/icon.png differ
diff --git a/assets/images/icons/gf.png b/assets/images/icons/gf.png
deleted file mode 100644
index ee837c1d..00000000
Binary files a/assets/images/icons/gf.png and /dev/null differ
diff --git a/assets/images/icons/gf/icon.png b/assets/images/icons/gf/icon.png
new file mode 100644
index 00000000..4b65187a
Binary files /dev/null and b/assets/images/icons/gf/icon.png differ
diff --git a/assets/images/icons/mom.png b/assets/images/icons/mom.png
deleted file mode 100644
index 1179e39b..00000000
Binary files a/assets/images/icons/mom.png and /dev/null differ
diff --git a/assets/images/icons/mom/icon.png b/assets/images/icons/mom/icon.png
new file mode 100644
index 00000000..793d846c
Binary files /dev/null and b/assets/images/icons/mom/icon.png differ
diff --git a/assets/images/icons/monster.png b/assets/images/icons/monster.png
deleted file mode 100644
index a7195ca3..00000000
Binary files a/assets/images/icons/monster.png and /dev/null differ
diff --git a/assets/images/icons/monster/icon.png b/assets/images/icons/monster/icon.png
new file mode 100644
index 00000000..525effd8
Binary files /dev/null and b/assets/images/icons/monster/icon.png differ
diff --git a/assets/images/icons/parents-christmas.png b/assets/images/icons/parents-christmas.png
deleted file mode 100644
index 64efb7fd..00000000
Binary files a/assets/images/icons/parents-christmas.png and /dev/null differ
diff --git a/assets/images/icons/parents-christmas/icon.png b/assets/images/icons/parents-christmas/icon.png
new file mode 100644
index 00000000..74e06a3d
Binary files /dev/null and b/assets/images/icons/parents-christmas/icon.png differ
diff --git a/assets/images/icons/pico.png b/assets/images/icons/pico.png
deleted file mode 100644
index c159e236..00000000
Binary files a/assets/images/icons/pico.png and /dev/null differ
diff --git a/assets/images/icons/pico/icon.png b/assets/images/icons/pico/icon.png
new file mode 100644
index 00000000..8a89b427
Binary files /dev/null and b/assets/images/icons/pico/icon.png differ
diff --git a/assets/images/icons/senpai.png b/assets/images/icons/senpai.png
deleted file mode 100644
index 22d0881b..00000000
Binary files a/assets/images/icons/senpai.png and /dev/null differ
diff --git a/assets/images/icons/senpai/data.xml b/assets/images/icons/senpai/data.xml
new file mode 100644
index 00000000..57653cad
--- /dev/null
+++ b/assets/images/icons/senpai/data.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/assets/images/icons/senpai/icon.png b/assets/images/icons/senpai/icon.png
new file mode 100644
index 00000000..0064cf42
Binary files /dev/null and b/assets/images/icons/senpai/icon.png differ
diff --git a/assets/images/icons/spirit.png b/assets/images/icons/spirit.png
deleted file mode 100644
index c4ccb2a9..00000000
Binary files a/assets/images/icons/spirit.png and /dev/null differ
diff --git a/assets/images/icons/spirit/data.xml b/assets/images/icons/spirit/data.xml
new file mode 100644
index 00000000..57653cad
--- /dev/null
+++ b/assets/images/icons/spirit/data.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/assets/images/icons/spirit/icon.png b/assets/images/icons/spirit/icon.png
new file mode 100644
index 00000000..e4cb0fd7
Binary files /dev/null and b/assets/images/icons/spirit/icon.png differ
diff --git a/assets/images/icons/spooky.png b/assets/images/icons/spooky.png
deleted file mode 100644
index 062eb196..00000000
Binary files a/assets/images/icons/spooky.png and /dev/null differ
diff --git a/assets/images/icons/spooky/icon.png b/assets/images/icons/spooky/icon.png
new file mode 100644
index 00000000..01534020
Binary files /dev/null and b/assets/images/icons/spooky/icon.png differ
diff --git a/assets/images/icons/tankman.png b/assets/images/icons/tankman.png
deleted file mode 100644
index d5d4ba46..00000000
Binary files a/assets/images/icons/tankman.png and /dev/null differ
diff --git a/assets/images/icons/tankman/icon.png b/assets/images/icons/tankman/icon.png
new file mode 100644
index 00000000..dafda943
Binary files /dev/null and b/assets/images/icons/tankman/icon.png differ
diff --git a/assets/images/menus/alphabet-bold.png b/assets/images/menus/alphabet-bold.png
index 012721ce..3979d25c 100644
Binary files a/assets/images/menus/alphabet-bold.png and b/assets/images/menus/alphabet-bold.png differ
diff --git a/assets/images/menus/alphabet.png b/assets/images/menus/alphabet.png
index 545e3505..41151548 100644
Binary files a/assets/images/menus/alphabet.png and b/assets/images/menus/alphabet.png differ
diff --git a/assets/images/menus/menuBG.png b/assets/images/menus/menuBG.png
index 35458e80..896f0c11 100644
Binary files a/assets/images/menus/menuBG.png and b/assets/images/menus/menuBG.png differ
diff --git a/assets/images/menus/menuBGBlue.png b/assets/images/menus/menuBGBlue.png
index d3b42842..273fc2e3 100644
Binary files a/assets/images/menus/menuBGBlue.png and b/assets/images/menus/menuBGBlue.png differ
diff --git a/assets/images/menus/menuBGMagenta.png b/assets/images/menus/menuBGMagenta.png
index 96794ec8..2046067f 100644
Binary files a/assets/images/menus/menuBGMagenta.png and b/assets/images/menus/menuBGMagenta.png differ
diff --git a/assets/images/menus/menuDesat.png b/assets/images/menus/menuDesat.png
index 65759840..9f440340 100644
Binary files a/assets/images/menus/menuDesat.png and b/assets/images/menus/menuDesat.png differ
diff --git a/assets/images/menus/menuEditors.png b/assets/images/menus/menuEditors.png
index d6afefd1..84d40b18 100644
Binary files a/assets/images/menus/menuEditors.png and b/assets/images/menus/menuEditors.png differ
diff --git a/assets/images/menus/menuTransparent.png b/assets/images/menus/menuTransparent.png
index 8ea4883b..d0f3f731 100644
Binary files a/assets/images/menus/menuTransparent.png and b/assets/images/menus/menuTransparent.png differ
diff --git a/assets/images/menus/options/checkboxThingie.png b/assets/images/menus/options/checkboxThingie.png
index ffdf3d30..7edb11c2 100644
Binary files a/assets/images/menus/options/checkboxThingie.png and b/assets/images/menus/options/checkboxThingie.png differ
diff --git a/assets/images/menus/pauseAlt/bfLol.png b/assets/images/menus/pauseAlt/bfLol.png
index bfbdb86a..901cca03 100644
Binary files a/assets/images/menus/pauseAlt/bfLol.png and b/assets/images/menus/pauseAlt/bfLol.png differ
diff --git a/assets/images/menus/pauseAlt/pauseBG.png b/assets/images/menus/pauseAlt/pauseBG.png
index 5b5a77c6..7d1b9ba4 100644
Binary files a/assets/images/menus/pauseAlt/pauseBG.png and b/assets/images/menus/pauseAlt/pauseBG.png differ
diff --git a/assets/images/menus/pauseAlt/pauseUI.png b/assets/images/menus/pauseAlt/pauseUI.png
index b395863b..8b7ca92d 100644
Binary files a/assets/images/menus/pauseAlt/pauseUI.png and b/assets/images/menus/pauseAlt/pauseUI.png differ
diff --git a/assets/images/menus/storymenu/assets.png b/assets/images/menus/storymenu/assets.png
index 914229b6..b4f5c1e7 100644
Binary files a/assets/images/menus/storymenu/assets.png and b/assets/images/menus/storymenu/assets.png differ
diff --git a/assets/images/menus/storymenu/characters/bf.png b/assets/images/menus/storymenu/characters/bf.png
index 74713c3d..1a74050c 100644
Binary files a/assets/images/menus/storymenu/characters/bf.png and b/assets/images/menus/storymenu/characters/bf.png differ
diff --git a/assets/images/menus/storymenu/characters/dad.png b/assets/images/menus/storymenu/characters/dad.png
index d63e4537..66026c5e 100644
Binary files a/assets/images/menus/storymenu/characters/dad.png and b/assets/images/menus/storymenu/characters/dad.png differ
diff --git a/assets/images/menus/storymenu/characters/gf.png b/assets/images/menus/storymenu/characters/gf.png
index 8ad08471..84a3736a 100644
Binary files a/assets/images/menus/storymenu/characters/gf.png and b/assets/images/menus/storymenu/characters/gf.png differ
diff --git a/assets/images/menus/storymenu/characters/mom.png b/assets/images/menus/storymenu/characters/mom.png
index 5ff1badf..91dbec8d 100644
Binary files a/assets/images/menus/storymenu/characters/mom.png and b/assets/images/menus/storymenu/characters/mom.png differ
diff --git a/assets/images/menus/storymenu/characters/parents-christmas.png b/assets/images/menus/storymenu/characters/parents-christmas.png
index 7f081ede..58ee07bd 100644
Binary files a/assets/images/menus/storymenu/characters/parents-christmas.png and b/assets/images/menus/storymenu/characters/parents-christmas.png differ
diff --git a/assets/images/menus/storymenu/characters/pico.png b/assets/images/menus/storymenu/characters/pico.png
index 46a4e375..cc121ade 100644
Binary files a/assets/images/menus/storymenu/characters/pico.png and b/assets/images/menus/storymenu/characters/pico.png differ
diff --git a/assets/images/menus/storymenu/characters/senpai.png b/assets/images/menus/storymenu/characters/senpai.png
index 8fe57d22..938adc4e 100644
Binary files a/assets/images/menus/storymenu/characters/senpai.png and b/assets/images/menus/storymenu/characters/senpai.png differ
diff --git a/assets/images/menus/storymenu/characters/spooky.png b/assets/images/menus/storymenu/characters/spooky.png
index e9bc3a15..ee6aa742 100644
Binary files a/assets/images/menus/storymenu/characters/spooky.png and b/assets/images/menus/storymenu/characters/spooky.png differ
diff --git a/assets/images/menus/storymenu/characters/tankman.png b/assets/images/menus/storymenu/characters/tankman.png
index 26f26dca..12a0211c 100644
Binary files a/assets/images/menus/storymenu/characters/tankman.png and b/assets/images/menus/storymenu/characters/tankman.png differ
diff --git a/assets/images/menus/storymenu/difficulties/easy.png b/assets/images/menus/storymenu/difficulties/easy.png
index e73783ad..b0941dd8 100644
Binary files a/assets/images/menus/storymenu/difficulties/easy.png and b/assets/images/menus/storymenu/difficulties/easy.png differ
diff --git a/assets/images/menus/storymenu/difficulties/hard.png b/assets/images/menus/storymenu/difficulties/hard.png
index 8c90f062..4c167dbc 100644
Binary files a/assets/images/menus/storymenu/difficulties/hard.png and b/assets/images/menus/storymenu/difficulties/hard.png differ
diff --git a/assets/images/menus/storymenu/difficulties/normal.png b/assets/images/menus/storymenu/difficulties/normal.png
index 8acd14e9..81958d5d 100644
Binary files a/assets/images/menus/storymenu/difficulties/normal.png and b/assets/images/menus/storymenu/difficulties/normal.png differ
diff --git a/assets/images/menus/storymenu/weeks/tutorial.png b/assets/images/menus/storymenu/weeks/tutorial.png
index 7ef58a55..17c960f8 100644
Binary files a/assets/images/menus/storymenu/weeks/tutorial.png and b/assets/images/menus/storymenu/weeks/tutorial.png differ
diff --git a/assets/images/menus/storymenu/weeks/week1.png b/assets/images/menus/storymenu/weeks/week1.png
index 9421bd85..f1563911 100644
Binary files a/assets/images/menus/storymenu/weeks/week1.png and b/assets/images/menus/storymenu/weeks/week1.png differ
diff --git a/assets/images/menus/storymenu/weeks/week2.png b/assets/images/menus/storymenu/weeks/week2.png
index 0b76c032..20edbaae 100644
Binary files a/assets/images/menus/storymenu/weeks/week2.png and b/assets/images/menus/storymenu/weeks/week2.png differ
diff --git a/assets/images/menus/storymenu/weeks/week3.png b/assets/images/menus/storymenu/weeks/week3.png
index 4a331b15..7a17b5d3 100644
Binary files a/assets/images/menus/storymenu/weeks/week3.png and b/assets/images/menus/storymenu/weeks/week3.png differ
diff --git a/assets/images/menus/storymenu/weeks/week4.png b/assets/images/menus/storymenu/weeks/week4.png
index 7122f979..654acecb 100644
Binary files a/assets/images/menus/storymenu/weeks/week4.png and b/assets/images/menus/storymenu/weeks/week4.png differ
diff --git a/assets/images/menus/storymenu/weeks/week5.png b/assets/images/menus/storymenu/weeks/week5.png
index 1a3a02a8..fe548757 100644
Binary files a/assets/images/menus/storymenu/weeks/week5.png and b/assets/images/menus/storymenu/weeks/week5.png differ
diff --git a/assets/images/menus/storymenu/weeks/week6.png b/assets/images/menus/storymenu/weeks/week6.png
index 0e02a8b1..1eb70de1 100644
Binary files a/assets/images/menus/storymenu/weeks/week6.png and b/assets/images/menus/storymenu/weeks/week6.png differ
diff --git a/assets/images/menus/storymenu/weeks/week7.png b/assets/images/menus/storymenu/weeks/week7.png
index 6b526d3f..8960961f 100644
Binary files a/assets/images/menus/storymenu/weeks/week7.png and b/assets/images/menus/storymenu/weeks/week7.png differ
diff --git a/assets/images/menus/titlescreen/gf.png b/assets/images/menus/titlescreen/gf.png
index 2705f13d..b8467282 100644
Binary files a/assets/images/menus/titlescreen/gf.png and b/assets/images/menus/titlescreen/gf.png differ
diff --git a/assets/images/menus/titlescreen/newgrounds_logo.png b/assets/images/menus/titlescreen/newgrounds_logo.png
index 26948b66..00e18517 100644
Binary files a/assets/images/menus/titlescreen/newgrounds_logo.png and b/assets/images/menus/titlescreen/newgrounds_logo.png differ
diff --git a/assets/images/menus/titlescreen/titleEnter.png b/assets/images/menus/titlescreen/titleEnter.png
index ad1a9f5f..634310a2 100644
Binary files a/assets/images/menus/titlescreen/titleEnter.png and b/assets/images/menus/titlescreen/titleEnter.png differ
diff --git a/assets/images/menus/transitionSpr.png b/assets/images/menus/transitionSpr.png
index 0044c064..3b973a46 100644
Binary files a/assets/images/menus/transitionSpr.png and b/assets/images/menus/transitionSpr.png differ
diff --git a/assets/images/menus/update/bf.png b/assets/images/menus/update/bf.png
index 975f3d1a..df7664a9 100644
Binary files a/assets/images/menus/update/bf.png and b/assets/images/menus/update/bf.png differ
diff --git a/assets/images/stages/default/stageback.png b/assets/images/stages/default/stageback.png
index f0e69407..3d4565b4 100644
Binary files a/assets/images/stages/default/stageback.png and b/assets/images/stages/default/stageback.png differ
diff --git a/assets/images/stages/default/stagecurtains.png b/assets/images/stages/default/stagecurtains.png
index de33c06e..47c36498 100644
Binary files a/assets/images/stages/default/stagecurtains.png and b/assets/images/stages/default/stagecurtains.png differ
diff --git a/assets/images/stages/default/stagefront.png b/assets/images/stages/default/stagefront.png
index 14790298..0cb1f56d 100644
Binary files a/assets/images/stages/default/stagefront.png and b/assets/images/stages/default/stagefront.png differ
diff --git a/assets/images/stages/limo/bgLimo.png b/assets/images/stages/limo/bgLimo.png
index 579862d0..292b1177 100644
Binary files a/assets/images/stages/limo/bgLimo.png and b/assets/images/stages/limo/bgLimo.png differ
diff --git a/assets/images/stages/limo/dumb.png b/assets/images/stages/limo/dumb.png
index 25ea6651..62516171 100644
Binary files a/assets/images/stages/limo/dumb.png and b/assets/images/stages/limo/dumb.png differ
diff --git a/assets/images/stages/limo/fastCarLol.png b/assets/images/stages/limo/fastCarLol.png
index 392bc8e4..88ef908e 100644
Binary files a/assets/images/stages/limo/fastCarLol.png and b/assets/images/stages/limo/fastCarLol.png differ
diff --git a/assets/images/stages/limo/limoDrive.png b/assets/images/stages/limo/limoDrive.png
index 7ba8dd90..58ad8af0 100644
Binary files a/assets/images/stages/limo/limoDrive.png and b/assets/images/stages/limo/limoDrive.png differ
diff --git a/assets/images/stages/limo/limoOverlay.png b/assets/images/stages/limo/limoOverlay.png
index 24ede11c..560a5687 100644
Binary files a/assets/images/stages/limo/limoOverlay.png and b/assets/images/stages/limo/limoOverlay.png differ
diff --git a/assets/images/stages/limo/limoSunset.png b/assets/images/stages/limo/limoSunset.png
index dddf07b2..476f22f5 100644
Binary files a/assets/images/stages/limo/limoSunset.png and b/assets/images/stages/limo/limoSunset.png differ
diff --git a/assets/images/stages/mall/bgEscalator.png b/assets/images/stages/mall/bgEscalator.png
index 8cff7edf..a75d918d 100644
Binary files a/assets/images/stages/mall/bgEscalator.png and b/assets/images/stages/mall/bgEscalator.png differ
diff --git a/assets/images/stages/mall/bgWalls.png b/assets/images/stages/mall/bgWalls.png
index 0222b8cf..b7613cbf 100644
Binary files a/assets/images/stages/mall/bgWalls.png and b/assets/images/stages/mall/bgWalls.png differ
diff --git a/assets/images/stages/mall/bottomBop.png b/assets/images/stages/mall/bottomBop.png
index d952e8e8..f044268c 100644
Binary files a/assets/images/stages/mall/bottomBop.png and b/assets/images/stages/mall/bottomBop.png differ
diff --git a/assets/images/stages/mall/christmasWall.png b/assets/images/stages/mall/christmasWall.png
index 0ac5c218..59ec77cd 100644
Binary files a/assets/images/stages/mall/christmasWall.png and b/assets/images/stages/mall/christmasWall.png differ
diff --git a/assets/images/stages/mall/evilBG.png b/assets/images/stages/mall/evilBG.png
index ea087576..6ed477d1 100644
Binary files a/assets/images/stages/mall/evilBG.png and b/assets/images/stages/mall/evilBG.png differ
diff --git a/assets/images/stages/mall/evilSnow.png b/assets/images/stages/mall/evilSnow.png
index ff420ce6..bae3f246 100644
Binary files a/assets/images/stages/mall/evilSnow.png and b/assets/images/stages/mall/evilSnow.png differ
diff --git a/assets/images/stages/mall/fgSnow.png b/assets/images/stages/mall/fgSnow.png
index 66091f02..c65ea057 100644
Binary files a/assets/images/stages/mall/fgSnow.png and b/assets/images/stages/mall/fgSnow.png differ
diff --git a/assets/images/stages/mall/santa.png b/assets/images/stages/mall/santa.png
index 58c1efad..1aeeb595 100644
Binary files a/assets/images/stages/mall/santa.png and b/assets/images/stages/mall/santa.png differ
diff --git a/assets/images/stages/mall/upperBop.png b/assets/images/stages/mall/upperBop.png
index d3741eb3..606c5aae 100644
Binary files a/assets/images/stages/mall/upperBop.png and b/assets/images/stages/mall/upperBop.png differ
diff --git a/assets/images/stages/philly/behindTrain.png b/assets/images/stages/philly/behindTrain.png
index fe5affe5..4df2fe41 100644
Binary files a/assets/images/stages/philly/behindTrain.png and b/assets/images/stages/philly/behindTrain.png differ
diff --git a/assets/images/stages/philly/city.png b/assets/images/stages/philly/city.png
index 46c44b20..883b2ad6 100644
Binary files a/assets/images/stages/philly/city.png and b/assets/images/stages/philly/city.png differ
diff --git a/assets/images/stages/philly/sky.png b/assets/images/stages/philly/sky.png
index cf502063..722b6579 100644
Binary files a/assets/images/stages/philly/sky.png and b/assets/images/stages/philly/sky.png differ
diff --git a/assets/images/stages/philly/street.png b/assets/images/stages/philly/street.png
index 14fd87bd..a8e54f1b 100644
Binary files a/assets/images/stages/philly/street.png and b/assets/images/stages/philly/street.png differ
diff --git a/assets/images/stages/philly/train.png b/assets/images/stages/philly/train.png
index cbee2da7..7df97b47 100644
Binary files a/assets/images/stages/philly/train.png and b/assets/images/stages/philly/train.png differ
diff --git a/assets/images/stages/philly/win.png b/assets/images/stages/philly/win.png
index 4e0091d6..dd8a43f7 100644
Binary files a/assets/images/stages/philly/win.png and b/assets/images/stages/philly/win.png differ
diff --git a/assets/images/stages/school/animatedEvilSchool.png b/assets/images/stages/school/animatedEvilSchool.png
index bc98fffc..9b2a1348 100644
Binary files a/assets/images/stages/school/animatedEvilSchool.png and b/assets/images/stages/school/animatedEvilSchool.png differ
diff --git a/assets/images/stages/school/bgFreaks.png b/assets/images/stages/school/bgFreaks.png
index db53cb20..f3dc46b3 100644
Binary files a/assets/images/stages/school/bgFreaks.png and b/assets/images/stages/school/bgFreaks.png differ
diff --git a/assets/images/stages/school/pause/bg.png b/assets/images/stages/school/pause/bg.png
index 44d136cc..80c41a70 100644
Binary files a/assets/images/stages/school/pause/bg.png and b/assets/images/stages/school/pause/bg.png differ
diff --git a/assets/images/stages/school/petals.png b/assets/images/stages/school/petals.png
index 9ec86f70..49c4a766 100644
Binary files a/assets/images/stages/school/petals.png and b/assets/images/stages/school/petals.png differ
diff --git a/assets/images/stages/school/ui/arrowEnds.png b/assets/images/stages/school/ui/arrowEnds.png
index 9d4dc874..6c645fb1 100644
Binary files a/assets/images/stages/school/ui/arrowEnds.png and b/assets/images/stages/school/ui/arrowEnds.png differ
diff --git a/assets/images/stages/school/ui/arrows-pixels.png b/assets/images/stages/school/ui/arrows-pixels.png
index 235cdf2e..93be11c6 100644
Binary files a/assets/images/stages/school/ui/arrows-pixels.png and b/assets/images/stages/school/ui/arrows-pixels.png differ
diff --git a/assets/images/stages/school/ui/bad.png b/assets/images/stages/school/ui/bad.png
index 364c8ac4..f74abdb6 100644
Binary files a/assets/images/stages/school/ui/bad.png and b/assets/images/stages/school/ui/bad.png differ
diff --git a/assets/images/stages/school/ui/combo.png b/assets/images/stages/school/ui/combo.png
index 154244a1..ee368626 100644
Binary files a/assets/images/stages/school/ui/combo.png and b/assets/images/stages/school/ui/combo.png differ
diff --git a/assets/images/stages/school/ui/go.png b/assets/images/stages/school/ui/go.png
index ee331059..c754a97d 100644
Binary files a/assets/images/stages/school/ui/go.png and b/assets/images/stages/school/ui/go.png differ
diff --git a/assets/images/stages/school/ui/good.png b/assets/images/stages/school/ui/good.png
index 302986dc..a5eba2b7 100644
Binary files a/assets/images/stages/school/ui/good.png and b/assets/images/stages/school/ui/good.png differ
diff --git a/assets/images/stages/school/ui/hand_textbox.png b/assets/images/stages/school/ui/hand_textbox.png
index 5b4f1361..0ba7fd43 100644
Binary files a/assets/images/stages/school/ui/hand_textbox.png and b/assets/images/stages/school/ui/hand_textbox.png differ
diff --git a/assets/images/stages/school/ui/num0.png b/assets/images/stages/school/ui/num0.png
index d002c36c..e3ed8016 100644
Binary files a/assets/images/stages/school/ui/num0.png and b/assets/images/stages/school/ui/num0.png differ
diff --git a/assets/images/stages/school/ui/num1.png b/assets/images/stages/school/ui/num1.png
index 45a78d5b..a92cac9a 100644
Binary files a/assets/images/stages/school/ui/num1.png and b/assets/images/stages/school/ui/num1.png differ
diff --git a/assets/images/stages/school/ui/num2.png b/assets/images/stages/school/ui/num2.png
index 29396f94..12941da6 100644
Binary files a/assets/images/stages/school/ui/num2.png and b/assets/images/stages/school/ui/num2.png differ
diff --git a/assets/images/stages/school/ui/num3.png b/assets/images/stages/school/ui/num3.png
index 00dde82e..3e60295e 100644
Binary files a/assets/images/stages/school/ui/num3.png and b/assets/images/stages/school/ui/num3.png differ
diff --git a/assets/images/stages/school/ui/num4.png b/assets/images/stages/school/ui/num4.png
index d3be8b8c..1f63ea86 100644
Binary files a/assets/images/stages/school/ui/num4.png and b/assets/images/stages/school/ui/num4.png differ
diff --git a/assets/images/stages/school/ui/num5.png b/assets/images/stages/school/ui/num5.png
index cde2a204..79bf20f1 100644
Binary files a/assets/images/stages/school/ui/num5.png and b/assets/images/stages/school/ui/num5.png differ
diff --git a/assets/images/stages/school/ui/num6.png b/assets/images/stages/school/ui/num6.png
index cea53eb9..76603795 100644
Binary files a/assets/images/stages/school/ui/num6.png and b/assets/images/stages/school/ui/num6.png differ
diff --git a/assets/images/stages/school/ui/num7.png b/assets/images/stages/school/ui/num7.png
index f43639e7..0306f3ec 100644
Binary files a/assets/images/stages/school/ui/num7.png and b/assets/images/stages/school/ui/num7.png differ
diff --git a/assets/images/stages/school/ui/num8.png b/assets/images/stages/school/ui/num8.png
index 63531c58..ed05add5 100644
Binary files a/assets/images/stages/school/ui/num8.png and b/assets/images/stages/school/ui/num8.png differ
diff --git a/assets/images/stages/school/ui/num9.png b/assets/images/stages/school/ui/num9.png
index 91b05b66..ec888d2e 100644
Binary files a/assets/images/stages/school/ui/num9.png and b/assets/images/stages/school/ui/num9.png differ
diff --git a/assets/images/stages/school/ui/pixel-secret-splashes.png b/assets/images/stages/school/ui/pixel-secret-splashes.png
index b686e686..6026fd13 100644
Binary files a/assets/images/stages/school/ui/pixel-secret-splashes.png and b/assets/images/stages/school/ui/pixel-secret-splashes.png differ
diff --git a/assets/images/stages/school/ui/pixel-splashes.png b/assets/images/stages/school/ui/pixel-splashes.png
index 78a06c6a..214c836d 100644
Binary files a/assets/images/stages/school/ui/pixel-splashes.png and b/assets/images/stages/school/ui/pixel-splashes.png differ
diff --git a/assets/images/stages/school/ui/ready.png b/assets/images/stages/school/ui/ready.png
index b2f1c039..ec220e74 100644
Binary files a/assets/images/stages/school/ui/ready.png and b/assets/images/stages/school/ui/ready.png differ
diff --git a/assets/images/stages/school/ui/set.png b/assets/images/stages/school/ui/set.png
index b73b8449..79f2166c 100644
Binary files a/assets/images/stages/school/ui/set.png and b/assets/images/stages/school/ui/set.png differ
diff --git a/assets/images/stages/school/ui/shit.png b/assets/images/stages/school/ui/shit.png
index 46f415eb..601266dd 100644
Binary files a/assets/images/stages/school/ui/shit.png and b/assets/images/stages/school/ui/shit.png differ
diff --git a/assets/images/stages/school/ui/sick.png b/assets/images/stages/school/ui/sick.png
index 3d7de624..f19dcded 100644
Binary files a/assets/images/stages/school/ui/sick.png and b/assets/images/stages/school/ui/sick.png differ
diff --git a/assets/images/stages/school/weebSchool.png b/assets/images/stages/school/weebSchool.png
index a54e6cc7..fb44fea7 100644
Binary files a/assets/images/stages/school/weebSchool.png and b/assets/images/stages/school/weebSchool.png differ
diff --git a/assets/images/stages/school/weebSky.png b/assets/images/stages/school/weebSky.png
index 4d7201d4..0e4933a8 100644
Binary files a/assets/images/stages/school/weebSky.png and b/assets/images/stages/school/weebSky.png differ
diff --git a/assets/images/stages/school/weebStreet.png b/assets/images/stages/school/weebStreet.png
index b8fc1247..cf90f5f4 100644
Binary files a/assets/images/stages/school/weebStreet.png and b/assets/images/stages/school/weebStreet.png differ
diff --git a/assets/images/stages/school/weebTrees.png b/assets/images/stages/school/weebTrees.png
index b62368f2..b9a3ab79 100644
Binary files a/assets/images/stages/school/weebTrees.png and b/assets/images/stages/school/weebTrees.png differ
diff --git a/assets/images/stages/school/weebTreesBack.png b/assets/images/stages/school/weebTreesBack.png
index 1a5fcbc2..78460fa2 100644
Binary files a/assets/images/stages/school/weebTreesBack.png and b/assets/images/stages/school/weebTreesBack.png differ
diff --git a/assets/images/stages/spooky/halloween_bg.png b/assets/images/stages/spooky/halloween_bg.png
index 2105bc83..d4d055ad 100644
Binary files a/assets/images/stages/spooky/halloween_bg.png and b/assets/images/stages/spooky/halloween_bg.png differ
diff --git a/assets/images/stages/tank/smokeLeft.png b/assets/images/stages/tank/smokeLeft.png
index 37dc5781..a1de4783 100644
Binary files a/assets/images/stages/tank/smokeLeft.png and b/assets/images/stages/tank/smokeLeft.png differ
diff --git a/assets/images/stages/tank/smokeRight.png b/assets/images/stages/tank/smokeRight.png
index d02890a3..0605d548 100644
Binary files a/assets/images/stages/tank/smokeRight.png and b/assets/images/stages/tank/smokeRight.png differ
diff --git a/assets/images/stages/tank/tankClouds.png b/assets/images/stages/tank/tankClouds.png
index c0112da0..1981f2c1 100644
Binary files a/assets/images/stages/tank/tankClouds.png and b/assets/images/stages/tank/tankClouds.png differ
diff --git a/assets/images/stages/tank/tankGround.png b/assets/images/stages/tank/tankGround.png
index 956b9e9e..53765eee 100644
Binary files a/assets/images/stages/tank/tankGround.png and b/assets/images/stages/tank/tankGround.png differ
diff --git a/assets/images/stages/tank/tankMountains.png b/assets/images/stages/tank/tankMountains.png
index 48e4158b..bc361ab0 100644
Binary files a/assets/images/stages/tank/tankMountains.png and b/assets/images/stages/tank/tankMountains.png differ
diff --git a/assets/images/stages/tank/tankRuins.png b/assets/images/stages/tank/tankRuins.png
index 1169d7f4..5837a69c 100644
Binary files a/assets/images/stages/tank/tankRuins.png and b/assets/images/stages/tank/tankRuins.png differ
diff --git a/assets/images/stages/tank/tankSky.png b/assets/images/stages/tank/tankSky.png
index 9a0a6207..dee84e7a 100644
Binary files a/assets/images/stages/tank/tankSky.png and b/assets/images/stages/tank/tankSky.png differ
diff --git a/assets/images/stages/tank/tankmanKilled1.png b/assets/images/stages/tank/tankmanKilled1.png
index c6553402..abf3e404 100644
Binary files a/assets/images/stages/tank/tankmanKilled1.png and b/assets/images/stages/tank/tankmanKilled1.png differ
diff --git a/assets/paths.json b/assets/paths.json
deleted file mode 100644
index e69de29b..00000000
diff --git a/assets/songs/winter horrorland/charts/easy.json b/assets/songs/winter horrorland/charts/easy.json
index 4ed4f5d9..983b5955 100644
--- a/assets/songs/winter horrorland/charts/easy.json
+++ b/assets/songs/winter horrorland/charts/easy.json
@@ -1 +1 @@
-{"song":{"gf":"gf-christmas","stage":"mall-evil","song":"Winter Horrorland","bpm":159.0,"needsVoices":true,"player1":"bf-christmas","player2":"Monster-christmas","speed":1.0,"notes":[{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[9433.962,0,283.01886],[9811.32,2,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[10566.0381,0,660.3774],[11320.7549,2,660.3774]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[12452.83,0,283.01886],[12830.1885,2,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[13584.9053,1,0.0],[14339.623,3,283.01886],[14716.9814,2,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[15094.34,5,754.717],[15471.6982,0,283.01886],[15849.0566,2,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[16603.7734,0,660.3774],[17358.49,2,660.3774]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[18490.5664,0,283.01886],[18867.9238,2,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[19622.64,1,0.0],[20377.36,3,283.01886],[20754.7168,2,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[21132.0762,1,283.01886],[21132.0762,5,754.717],[21886.793,2,283.01886],[22264.15,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[22641.51,1,471.69812],[23396.2266,0,0.0],[23773.584,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[24150.9434,3,283.01886],[24528.3027,2,0.0],[24905.66,2,0.0],[25283.02,2,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[25660.377,1,471.69812],[26415.0938,3,0.0],[26792.4531,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[27169.81,1,283.01886],[27924.5273,2,283.01886],[28301.8867,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[28679.2461,1,471.69812],[29433.9629,0,0.0],[29811.32,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[30188.68,3,283.01886],[30566.0371,2,0.0],[30943.3965,2,0.0],[31320.7539,2,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[31698.1133,1,471.69812],[32452.83,3,0.0],[32830.1875,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[33584.9063,2,0.0],[33962.2656,0,283.01886],[34528.3,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[35094.34,2,283.01886],[35471.7,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[36603.7734,2,0.0],[36981.1328,0,283.01886],[37358.4922,1,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[37735.8477,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[39622.64,2,0.0],[40000.0,0,283.01886],[40566.04,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[41132.0742,2,283.01886],[41509.4336,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[42641.5078,2,0.0],[43018.8672,0,283.01886],[43396.2266,1,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[43773.5859,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[45283.02,0,283.01886],[46037.7344,2,0.0],[46415.0938,2,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[46792.4531,5,283.01886],[47169.8125,0,0.0],[47547.168,3,0.0],[47924.5273,1,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[48301.8867,2,283.01886],[48301.8867,6,849.0566],[48679.2461,0,188.679245],[49056.6055,3,0.0],[49433.96,3,0.0],[49622.64,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[49937.1055,2,0.0],[50188.68,2,0.0],[50440.25,2,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[51320.7539,0,283.01886],[52075.4727,2,0.0],[52452.832,2,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[52830.1875,5,283.01886],[53207.5469,0,0.0],[53584.9063,3,0.0],[53962.2656,1,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[54339.62,6,1132.07544],[54339.62,2,283.01886],[54716.98,0,188.679245],[55094.34,3,0.0],[55471.7,3,0.0],[55660.38,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[56037.7344,2,0.0],[56415.0938,2,0.0],[56603.7734,2,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[57547.168,2,0.0],[58113.207,2,0.0],[58490.5664,2,0.0],[58679.2461,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[58867.9258,1,0.0],[59245.28,3,283.01886],[59622.64,2,0.0],[60000.0,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[60566.04,2,0.0],[61132.0742,2,0.0],[61509.4336,2,0.0],[61698.1133,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[61886.793,1,0.0],[62264.1523,3,283.01886],[62641.5078,2,0.0],[63018.8672,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[63396.2266,3,0.0],[63773.5859,1,283.01886],[64150.94,0,0.0],[64528.3,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[64905.66,4,0.0],[64905.66,3,0.0],[65283.02,1,283.01886],[65660.375,0,0.0],[66037.7344,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[66415.09,0,0.0],[66415.09,4,0.0],[66981.13,7,0.0],[66981.13,3,0.0],[67358.49,6,0.0],[67358.49,2,0.0],[67735.85,5,754.717],[67735.85,1,754.717]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[69622.64,0,0.0],[70188.68,1,0.0],[70754.72,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[71132.08,2,0.0],[71320.76,1,0.0],[71698.11,2,0.0],[72075.47,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[72452.83,2,283.01886],[72830.19,0,283.01886],[73207.55,3,283.01886],[73584.91,0,0.0],[73773.5859,1,566.0377]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[74716.9844,3,0.0],[74905.6641,0,0.0],[75094.3359,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[75660.375,0,0.0],[76226.4141,1,0.0],[76792.45,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[77169.81,2,0.0],[77358.49,1,0.0],[77735.85,2,0.0],[78113.21,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[78490.56,2,283.01886],[78867.92,0,283.01886],[79245.28,3,283.01886],[79622.64,0,0.0],[79811.32,1,566.0377]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[80754.72,3,0.0],[80943.4,0,0.0],[81132.08,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[81509.44,1,0.0],[81886.79,3,0.0],[82264.15,0,0.0],[82641.51,2,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[83018.87,1,0.0],[83396.23,3,0.0],[83773.5859,0,0.0],[84150.9453,2,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[84528.3047,2,0.0],[84905.6641,2,0.0],[85094.3359,0,0.0],[85283.0156,2,0.0],[85660.375,2,0.0],[85849.0547,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[86037.7344,2,0.0],[86415.09,2,0.0],[86603.77,0,0.0],[86792.45,2,0.0],[87169.81,2,0.0],[87358.49,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[87547.17,3,283.01886],[88113.21,1,283.01886],[88301.88,4,0.0],[88679.24,7,283.01886],[88679.24,1,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[89056.6,5,283.01886],[89056.6,3,0.0],[89433.96,3,0.0],[89811.32,1,283.01886],[89811.32,7,0.0],[90188.68,6,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[90566.04,5,283.01886],[90566.04,0,0.0],[91132.08,3,0.0],[91698.11,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[92075.47,2,566.0377],[92075.47,6,566.0377],[92830.19,3,566.0377],[92830.19,4,566.0377]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[93773.5859,3,0.0],[94150.9453,7,0.0],[94339.625,0,283.01886],[94716.9844,4,283.01886],[94905.6641,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[95283.0156,3,283.01886],[95471.6953,6,283.01886],[95849.0547,4,283.01886],[95849.0547,2,283.01886],[96226.4141,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[96792.45,7,94.33962],[96981.13,6,0.0],[97169.81,3,94.33962],[97358.49,4,283.01886],[97358.49,2,0.0],[97735.85,0,283.01886],[97735.85,5,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[98113.21,5,283.01886],[98113.21,0,283.01886],[98490.56,7,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[99811.32,3,0.0],[100188.68,7,0.0],[100377.359,0,283.01886],[100754.719,4,283.01886],[100943.4,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[101320.758,3,283.01886],[101509.438,6,283.01886],[101886.789,4,283.01886],[101886.789,2,283.01886],[102264.148,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[102830.188,3,94.33962],[103207.547,7,94.33962],[103396.227,0,283.01886],[103773.586,1,283.01886],[103773.586,4,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[104150.945,5,283.01886],[104150.945,0,283.01886],[104528.305,7,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[105849.055,2,0.0],[106415.094,2,0.0],[106792.453,2,0.0],[106981.133,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[107169.813,1,0.0],[107547.172,3,283.01886],[107924.531,2,0.0],[108301.883,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[108867.922,2,0.0],[109433.961,2,0.0],[109811.32,2,0.0],[110000.0,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[110188.68,1,0.0],[110566.039,3,283.01886],[110943.4,2,0.0],[111320.758,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[111698.109,3,0.0],[112075.469,1,283.01886],[112452.828,0,0.0],[112830.188,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[113207.547,4,0.0],[113207.547,3,0.0],[113584.906,1,283.01886],[113962.266,0,0.0],[114339.625,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[114716.984,4,0.0],[114716.984,0,0.0],[115283.016,3,0.0],[115283.016,7,0.0],[115660.375,6,0.0],[115660.375,2,0.0],[116037.734,1,754.717],[116037.734,5,754.717]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[117924.531,0,0.0],[118490.563,1,0.0],[118867.922,2,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[119245.281,2,283.01886],[119622.641,3,283.01886],[120000.0,0,283.01886],[120377.359,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[120754.719,6,754.717],[120943.4,0,0.0],[121509.438,1,0.0],[121886.789,2,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[122264.148,2,283.01886],[122641.508,3,283.01886],[123018.867,0,283.01886],[123396.227,3,754.717]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[123773.586,1,94.33962],[124150.945,3,0.0],[124528.305,2,283.01886],[124905.664,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[125283.016,2,0.0],[125283.016,5,283.01886],[125660.375,1,283.01886],[126037.734,3,0.0],[126415.094,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[126792.453,0,0.0],[126792.453,4,0.0],[127358.492,3,0.0],[127358.492,7,0.0],[127735.852,6,0.0],[127735.852,2,0.0],[128113.211,1,377.3585],[128113.211,5,377.3585]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[129056.6,0,0.0],[129245.281,3,0.0],[129433.961,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[129811.32,2,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]}]},"generatedBy":"SNIFF ver.6"}
\ No newline at end of file
+{"song":{"gf":"gf-christmas","stage":"mall-evil","song":"Winter Horrorland","bpm":159.0,"needsVoices":true,"player1":"bf-christmas","player2":"monster-christmas","speed":1.0,"notes":[{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[9433.962,0,283.01886],[9811.32,2,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[10566.0381,0,660.3774],[11320.7549,2,660.3774]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[12452.83,0,283.01886],[12830.1885,2,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[13584.9053,1,0.0],[14339.623,3,283.01886],[14716.9814,2,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[15094.34,5,754.717],[15471.6982,0,283.01886],[15849.0566,2,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[16603.7734,0,660.3774],[17358.49,2,660.3774]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[18490.5664,0,283.01886],[18867.9238,2,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[19622.64,1,0.0],[20377.36,3,283.01886],[20754.7168,2,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[21132.0762,1,283.01886],[21132.0762,5,754.717],[21886.793,2,283.01886],[22264.15,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[22641.51,1,471.69812],[23396.2266,0,0.0],[23773.584,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[24150.9434,3,283.01886],[24528.3027,2,0.0],[24905.66,2,0.0],[25283.02,2,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[25660.377,1,471.69812],[26415.0938,3,0.0],[26792.4531,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[27169.81,1,283.01886],[27924.5273,2,283.01886],[28301.8867,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[28679.2461,1,471.69812],[29433.9629,0,0.0],[29811.32,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[30188.68,3,283.01886],[30566.0371,2,0.0],[30943.3965,2,0.0],[31320.7539,2,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[31698.1133,1,471.69812],[32452.83,3,0.0],[32830.1875,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[33584.9063,2,0.0],[33962.2656,0,283.01886],[34528.3,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[35094.34,2,283.01886],[35471.7,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[36603.7734,2,0.0],[36981.1328,0,283.01886],[37358.4922,1,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[37735.8477,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[39622.64,2,0.0],[40000.0,0,283.01886],[40566.04,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[41132.0742,2,283.01886],[41509.4336,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[42641.5078,2,0.0],[43018.8672,0,283.01886],[43396.2266,1,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[43773.5859,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[45283.02,0,283.01886],[46037.7344,2,0.0],[46415.0938,2,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[46792.4531,5,283.01886],[47169.8125,0,0.0],[47547.168,3,0.0],[47924.5273,1,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[48301.8867,2,283.01886],[48301.8867,6,849.0566],[48679.2461,0,188.679245],[49056.6055,3,0.0],[49433.96,3,0.0],[49622.64,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[49937.1055,2,0.0],[50188.68,2,0.0],[50440.25,2,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[51320.7539,0,283.01886],[52075.4727,2,0.0],[52452.832,2,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[52830.1875,5,283.01886],[53207.5469,0,0.0],[53584.9063,3,0.0],[53962.2656,1,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[54339.62,6,1132.07544],[54339.62,2,283.01886],[54716.98,0,188.679245],[55094.34,3,0.0],[55471.7,3,0.0],[55660.38,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[56037.7344,2,0.0],[56415.0938,2,0.0],[56603.7734,2,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[57547.168,2,0.0],[58113.207,2,0.0],[58490.5664,2,0.0],[58679.2461,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[58867.9258,1,0.0],[59245.28,3,283.01886],[59622.64,2,0.0],[60000.0,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[60566.04,2,0.0],[61132.0742,2,0.0],[61509.4336,2,0.0],[61698.1133,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[61886.793,1,0.0],[62264.1523,3,283.01886],[62641.5078,2,0.0],[63018.8672,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[63396.2266,3,0.0],[63773.5859,1,283.01886],[64150.94,0,0.0],[64528.3,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[64905.66,4,0.0],[64905.66,3,0.0],[65283.02,1,283.01886],[65660.375,0,0.0],[66037.7344,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[66415.09,0,0.0],[66415.09,4,0.0],[66981.13,7,0.0],[66981.13,3,0.0],[67358.49,6,0.0],[67358.49,2,0.0],[67735.85,5,754.717],[67735.85,1,754.717]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[69622.64,0,0.0],[70188.68,1,0.0],[70754.72,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[71132.08,2,0.0],[71320.76,1,0.0],[71698.11,2,0.0],[72075.47,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[72452.83,2,283.01886],[72830.19,0,283.01886],[73207.55,3,283.01886],[73584.91,0,0.0],[73773.5859,1,566.0377]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[74716.9844,3,0.0],[74905.6641,0,0.0],[75094.3359,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[75660.375,0,0.0],[76226.4141,1,0.0],[76792.45,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[77169.81,2,0.0],[77358.49,1,0.0],[77735.85,2,0.0],[78113.21,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[78490.56,2,283.01886],[78867.92,0,283.01886],[79245.28,3,283.01886],[79622.64,0,0.0],[79811.32,1,566.0377]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[80754.72,3,0.0],[80943.4,0,0.0],[81132.08,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[81509.44,1,0.0],[81886.79,3,0.0],[82264.15,0,0.0],[82641.51,2,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[83018.87,1,0.0],[83396.23,3,0.0],[83773.5859,0,0.0],[84150.9453,2,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[84528.3047,2,0.0],[84905.6641,2,0.0],[85094.3359,0,0.0],[85283.0156,2,0.0],[85660.375,2,0.0],[85849.0547,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[86037.7344,2,0.0],[86415.09,2,0.0],[86603.77,0,0.0],[86792.45,2,0.0],[87169.81,2,0.0],[87358.49,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[87547.17,3,283.01886],[88113.21,1,283.01886],[88301.88,4,0.0],[88679.24,7,283.01886],[88679.24,1,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[89056.6,5,283.01886],[89056.6,3,0.0],[89433.96,3,0.0],[89811.32,1,283.01886],[89811.32,7,0.0],[90188.68,6,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[90566.04,5,283.01886],[90566.04,0,0.0],[91132.08,3,0.0],[91698.11,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[92075.47,2,566.0377],[92075.47,6,566.0377],[92830.19,3,566.0377],[92830.19,4,566.0377]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[93773.5859,3,0.0],[94150.9453,7,0.0],[94339.625,0,283.01886],[94716.9844,4,283.01886],[94905.6641,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[95283.0156,3,283.01886],[95471.6953,6,283.01886],[95849.0547,4,283.01886],[95849.0547,2,283.01886],[96226.4141,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[96792.45,7,94.33962],[96981.13,6,0.0],[97169.81,3,94.33962],[97358.49,4,283.01886],[97358.49,2,0.0],[97735.85,0,283.01886],[97735.85,5,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[98113.21,5,283.01886],[98113.21,0,283.01886],[98490.56,7,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[99811.32,3,0.0],[100188.68,7,0.0],[100377.359,0,283.01886],[100754.719,4,283.01886],[100943.4,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[101320.758,3,283.01886],[101509.438,6,283.01886],[101886.789,4,283.01886],[101886.789,2,283.01886],[102264.148,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[102830.188,3,94.33962],[103207.547,7,94.33962],[103396.227,0,283.01886],[103773.586,1,283.01886],[103773.586,4,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[104150.945,5,283.01886],[104150.945,0,283.01886],[104528.305,7,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[105849.055,2,0.0],[106415.094,2,0.0],[106792.453,2,0.0],[106981.133,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[107169.813,1,0.0],[107547.172,3,283.01886],[107924.531,2,0.0],[108301.883,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[108867.922,2,0.0],[109433.961,2,0.0],[109811.32,2,0.0],[110000.0,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[110188.68,1,0.0],[110566.039,3,283.01886],[110943.4,2,0.0],[111320.758,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[111698.109,3,0.0],[112075.469,1,283.01886],[112452.828,0,0.0],[112830.188,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[113207.547,4,0.0],[113207.547,3,0.0],[113584.906,1,283.01886],[113962.266,0,0.0],[114339.625,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[114716.984,4,0.0],[114716.984,0,0.0],[115283.016,3,0.0],[115283.016,7,0.0],[115660.375,6,0.0],[115660.375,2,0.0],[116037.734,1,754.717],[116037.734,5,754.717]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[117924.531,0,0.0],[118490.563,1,0.0],[118867.922,2,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[119245.281,2,283.01886],[119622.641,3,283.01886],[120000.0,0,283.01886],[120377.359,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[120754.719,6,754.717],[120943.4,0,0.0],[121509.438,1,0.0],[121886.789,2,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[122264.148,2,283.01886],[122641.508,3,283.01886],[123018.867,0,283.01886],[123396.227,3,754.717]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[123773.586,1,94.33962],[124150.945,3,0.0],[124528.305,2,283.01886],[124905.664,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[125283.016,2,0.0],[125283.016,5,283.01886],[125660.375,1,283.01886],[126037.734,3,0.0],[126415.094,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[126792.453,0,0.0],[126792.453,4,0.0],[127358.492,3,0.0],[127358.492,7,0.0],[127735.852,6,0.0],[127735.852,2,0.0],[128113.211,1,377.3585],[128113.211,5,377.3585]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[129056.6,0,0.0],[129245.281,3,0.0],[129433.961,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[129811.32,2,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]}]},"generatedBy":"SNIFF ver.6"}
diff --git a/assets/songs/winter horrorland/charts/hard.json b/assets/songs/winter horrorland/charts/hard.json
index fe118e9c..ce698c12 100644
--- a/assets/songs/winter horrorland/charts/hard.json
+++ b/assets/songs/winter horrorland/charts/hard.json
@@ -1 +1 @@
-{"song":{"gf":"gf-christmas","stage":"mall-evil","song":"Winter Horrorland","bpm":159.0,"needsVoices":true,"player1":"bf-christmas","player2":"Monster-christmas","speed":1.3,"notes":[{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[9433.962,0,283.01886],[9811.32,2,283.01886],[10188.68,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[10566.0381,0,660.3774],[11320.7549,2,566.0377]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[12452.83,0,283.01886],[12830.1885,2,283.01886],[13207.5469,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[13584.9053,1,0.0],[14150.9434,2,0.0],[14339.623,3,283.01886],[14716.9814,2,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[15094.34,5,754.717],[15471.6982,0,283.01886],[15849.0566,2,283.01886],[16226.415,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[16603.7734,0,660.3774],[17358.49,2,660.3774]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[18490.5664,0,283.01886],[18867.9238,2,283.01886],[19245.2832,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[19622.64,1,0.0],[20188.68,2,0.0],[20377.36,3,283.01886],[20754.7168,2,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[21132.0762,1,283.01886],[21132.0762,5,754.717],[21509.4336,3,283.01886],[21886.793,2,283.01886],[22264.15,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[22641.51,1,471.69812],[23207.5469,0,0.0],[23301.8867,2,0.0],[23396.2266,0,0.0],[23584.9063,3,0.0],[23773.584,0,0.0],[23962.2637,1,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[24150.9434,3,283.01886],[24528.3027,2,0.0],[24716.98,0,0.0],[24905.66,2,0.0],[25094.34,0,0.0],[25283.02,2,0.0],[25471.6973,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[25660.377,1,471.69812],[26226.416,2,0.0],[26415.0938,3,0.0],[26603.7734,2,0.0],[26792.4531,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[27169.81,1,283.01886],[27547.17,3,283.01886],[27924.5273,2,283.01886],[28301.8867,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[28679.2461,1,471.69812],[29245.2832,0,0.0],[29339.623,2,0.0],[29433.9629,0,0.0],[29622.64,3,0.0],[29811.32,0,0.0],[30000.0,1,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[30188.68,3,283.01886],[30566.0371,2,0.0],[30754.7168,0,0.0],[30943.3965,2,0.0],[31132.0762,0,0.0],[31320.7539,2,0.0],[31509.4336,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[31698.1133,1,471.69812],[32264.15,2,0.0],[32452.83,3,0.0],[32641.51,2,0.0],[32830.1875,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[33396.2266,3,0.0],[33490.5664,3,0.0],[33584.9063,2,0.0],[33773.5859,1,0.0],[33962.2656,0,283.01886],[34528.3,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[35094.34,2,283.01886],[35471.7,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[36415.0938,3,94.33962],[36603.7734,2,94.33962],[36792.4531,1,94.33962],[36981.1328,0,283.01886],[37358.4922,1,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[37735.8477,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[39433.96,3,0.0],[39528.3,3,0.0],[39622.64,2,0.0],[39811.32,1,0.0],[40000.0,0,283.01886],[40566.04,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[41132.0742,2,283.01886],[41509.4336,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[42452.832,3,94.33962],[42641.5078,2,94.33962],[42830.1875,1,94.33962],[43018.8672,0,283.01886],[43396.2266,1,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[43773.5859,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[45283.02,0,283.01886],[45660.38,1,283.01886],[46037.7344,2,0.0],[46226.4141,3,0.0],[46415.0938,2,0.0],[46603.7734,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[46792.4531,5,283.01886],[47169.8125,0,0.0],[47547.168,3,0.0],[47924.5273,1,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[48301.8867,6,849.0566],[48301.8867,2,283.01886],[48679.2461,0,188.679245],[49056.6055,3,0.0],[49245.28,0,0.0],[49339.62,0,0.0],[49433.96,3,0.0],[49622.64,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[49937.1055,2,0.0],[50188.68,2,0.0],[50440.25,2,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[51320.7539,0,283.01886],[51698.1133,1,283.01886],[52075.4727,2,0.0],[52264.1523,3,0.0],[52452.832,2,0.0],[52641.5078,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[52830.1875,5,283.01886],[53207.5469,0,0.0],[53584.9063,3,0.0],[53962.2656,1,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[54339.62,6,1132.07544],[54339.62,2,188.679245],[54716.98,0,188.679245],[55094.34,3,0.0],[55283.02,0,0.0],[55377.36,0,0.0],[55471.7,3,0.0],[55660.38,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[56037.7344,2,0.0],[56415.0938,2,0.0],[56603.7734,2,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[57547.168,2,0.0],[57924.5273,2,0.0],[58018.8672,3,0.0],[58113.207,2,0.0],[58301.8867,0,0.0],[58490.5664,2,0.0],[58679.2461,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[58867.9258,1,0.0],[59056.6055,0,0.0],[59245.28,3,283.01886],[59622.64,2,0.0],[59811.32,3,0.0],[60000.0,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[60566.04,2,0.0],[60943.3945,2,0.0],[61037.7344,3,0.0],[61132.0742,2,0.0],[61320.7539,0,0.0],[61509.4336,2,0.0],[61698.1133,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[61886.793,1,0.0],[62075.4727,0,0.0],[62264.1523,3,283.01886],[62641.5078,2,0.0],[62830.1875,3,0.0],[63018.8672,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[63396.2266,3,0.0],[63584.9063,3,0.0],[63773.5859,1,283.01886],[64150.94,0,0.0],[64528.3,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[64905.66,4,0.0],[64905.66,3,0.0],[65094.34,3,0.0],[65283.02,1,283.01886],[65660.375,0,0.0],[65849.0547,0,0.0],[66037.7344,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[66415.09,4,0.0],[66415.09,0,0.0],[66603.77,5,0.0],[66603.77,1,0.0],[66981.13,7,0.0],[66981.13,3,0.0],[67358.49,6,0.0],[67358.49,2,0.0],[67735.85,1,754.717],[67735.85,5,754.717]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[69622.64,0,0.0],[69716.9844,0,0.0],[69811.32,3,0.0],[70188.68,1,0.0],[70377.36,0,0.0],[70566.04,2,0.0],[70754.72,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[71132.08,2,0.0],[71226.4141,3,0.0],[71320.76,1,0.0],[71509.44,0,0.0],[71698.11,2,0.0],[71886.79,3,0.0],[72075.47,0,0.0],[72264.15,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[72452.83,2,283.01886],[72830.19,0,283.01886],[73207.55,3,283.01886],[73584.91,0,0.0],[73773.5859,1,566.0377]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[74528.3047,0,0.0],[74716.9844,3,0.0],[74905.6641,0,0.0],[75094.3359,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[75660.375,0,0.0],[75754.72,0,0.0],[75849.0547,3,0.0],[76226.4141,1,0.0],[76415.09,0,0.0],[76603.77,2,0.0],[76792.45,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[77169.81,2,0.0],[77264.15,3,0.0],[77358.49,1,0.0],[77547.17,0,0.0],[77735.85,2,0.0],[77924.53,3,0.0],[78113.21,0,0.0],[78301.88,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[78490.56,2,283.01886],[78867.92,0,283.01886],[79245.28,3,283.01886],[79622.64,0,0.0],[79811.32,1,566.0377]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[80566.04,0,0.0],[80754.72,3,0.0],[80943.4,0,0.0],[81132.08,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[81509.44,1,0.0],[81698.11,1,0.0],[81886.79,3,0.0],[82075.47,3,0.0],[82264.15,0,0.0],[82452.83,3,0.0],[82641.51,2,0.0],[82830.19,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[83018.87,1,0.0],[83207.55,1,0.0],[83396.23,3,0.0],[83584.91,3,0.0],[83773.5859,0,0.0],[83962.2656,3,0.0],[84150.9453,2,0.0],[84339.625,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[84528.3047,2,0.0],[84716.9844,3,0.0],[84905.6641,2,0.0],[85094.3359,0,0.0],[85283.0156,2,0.0],[85471.6953,3,0.0],[85660.375,2,0.0],[85849.0547,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[86037.7344,2,0.0],[86226.4141,3,0.0],[86415.09,2,0.0],[86603.77,0,0.0],[86792.45,2,0.0],[86981.13,3,0.0],[87169.81,2,0.0],[87358.49,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[87547.17,3,283.01886],[87924.53,0,94.33962],[88113.21,1,283.01886],[88301.88,4,0.0],[88490.56,0,0.0],[88490.56,7,0.0],[88679.24,1,0.0],[88679.24,7,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[89056.6,5,283.01886],[89056.6,3,0.0],[89433.96,3,0.0],[89811.32,1,283.01886],[89811.32,7,0.0],[90000.0,4,0.0],[90188.68,6,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[90566.04,5,283.01886],[90566.04,0,0.0],[91132.08,3,0.0],[91698.11,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[92075.47,6,566.0377],[92075.47,2,566.0377],[92830.19,3,566.0377],[92830.19,4,566.0377]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[93773.5859,3,0.0],[93867.92,3,0.0],[93962.2656,2,0.0],[94150.9453,1,0.0],[94150.9453,7,0.0],[94245.28,7,0.0],[94339.625,0,283.01886],[94339.625,6,0.0],[94528.3047,5,0.0],[94716.9844,4,283.01886],[94905.6641,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[95283.0156,3,283.01886],[95471.6953,6,283.01886],[95849.0547,2,283.01886],[95849.0547,4,283.01886],[96226.4141,0,283.01886],[96226.4141,7,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[96603.77,3,0.0],[96792.45,7,94.33962],[96981.13,6,94.33962],[97169.81,5,94.33962],[97169.81,3,94.33962],[97358.49,4,283.01886],[97358.49,2,94.33962],[97547.17,1,94.33962],[97735.85,0,283.01886],[97735.85,5,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[98113.21,5,283.01886],[98113.21,0,283.01886],[98490.56,7,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[99811.32,3,0.0],[99905.6641,3,0.0],[100000.0,2,0.0],[100188.68,7,0.0],[100188.68,1,0.0],[100283.016,7,0.0],[100377.359,6,0.0],[100377.359,0,283.01886],[100566.039,5,0.0],[100754.719,4,283.01886],[100943.4,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[101320.758,3,283.01886],[101509.438,6,283.01886],[101886.789,2,283.01886],[101886.789,4,283.01886],[102264.148,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[102830.188,3,94.33962],[103018.867,2,94.33962],[103207.547,7,94.33962],[103207.547,1,94.33962],[103396.227,0,283.01886],[103396.227,6,94.33962],[103584.906,5,94.33962],[103773.586,1,283.01886],[103773.586,4,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[104150.945,0,283.01886],[104150.945,5,283.01886],[104528.305,7,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[105849.055,2,0.0],[106226.414,2,0.0],[106320.758,3,0.0],[106415.094,2,0.0],[106603.773,0,0.0],[106792.453,2,0.0],[106981.133,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[107169.813,1,0.0],[107358.492,0,0.0],[107547.172,3,283.01886],[107924.531,2,0.0],[108113.211,3,0.0],[108301.883,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[108867.922,2,0.0],[109245.281,2,0.0],[109339.625,3,0.0],[109433.961,2,0.0],[109622.641,0,0.0],[109811.32,2,0.0],[110000.0,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[110188.68,1,0.0],[110377.359,0,0.0],[110566.039,3,283.01886],[110943.4,2,0.0],[111132.078,3,0.0],[111320.758,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[111698.109,3,0.0],[111886.789,3,0.0],[112075.469,1,283.01886],[112452.828,0,0.0],[112830.188,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[113207.547,4,0.0],[113207.547,3,0.0],[113396.227,3,0.0],[113584.906,1,283.01886],[113962.266,0,0.0],[114150.945,0,0.0],[114339.625,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[114716.984,0,0.0],[114716.984,4,0.0],[114905.664,1,0.0],[114905.664,5,0.0],[115283.016,3,0.0],[115283.016,7,0.0],[115660.375,2,0.0],[115660.375,6,0.0],[116037.734,5,754.717],[116037.734,1,754.717]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[117924.531,0,0.0],[118301.883,3,0.0],[118490.563,1,0.0],[118679.242,0,0.0],[118867.922,2,0.0],[119056.6,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[119245.281,2,283.01886],[119622.641,3,283.01886],[120000.0,0,283.01886],[120377.359,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[120754.719,6,754.717],[120943.4,0,0.0],[121320.758,3,0.0],[121509.438,1,0.0],[121698.109,0,0.0],[121886.789,2,0.0],[122075.469,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[122264.148,2,283.01886],[122641.508,3,283.01886],[123018.867,0,283.01886],[123396.227,3,754.717]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[123773.586,1,94.33962],[124150.945,3,0.0],[124339.625,3,0.0],[124528.305,2,283.01886],[124905.664,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[125283.016,5,283.01886],[125283.016,2,0.0],[125471.695,3,0.0],[125660.375,1,283.01886],[126037.734,3,0.0],[126226.414,0,0.0],[126415.094,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[126792.453,0,0.0],[126792.453,4,0.0],[126981.133,1,0.0],[126981.133,5,0.0],[127358.492,3,0.0],[127358.492,7,0.0],[127735.852,2,0.0],[127735.852,6,0.0],[128113.211,1,377.3585],[128113.211,5,377.3585]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[129056.6,0,0.0],[129245.281,3,0.0],[129433.961,0,0.0],[129622.641,1,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[129811.32,2,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]}]},"generatedBy":"SNIFF ver.6"}
\ No newline at end of file
+{"song":{"gf":"gf-christmas","stage":"mall-evil","song":"Winter Horrorland","bpm":159.0,"needsVoices":true,"player1":"bf-christmas","player2":"monster-christmas","speed":1.3,"notes":[{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[9433.962,0,283.01886],[9811.32,2,283.01886],[10188.68,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[10566.0381,0,660.3774],[11320.7549,2,566.0377]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[12452.83,0,283.01886],[12830.1885,2,283.01886],[13207.5469,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[13584.9053,1,0.0],[14150.9434,2,0.0],[14339.623,3,283.01886],[14716.9814,2,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[15094.34,5,754.717],[15471.6982,0,283.01886],[15849.0566,2,283.01886],[16226.415,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[16603.7734,0,660.3774],[17358.49,2,660.3774]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[18490.5664,0,283.01886],[18867.9238,2,283.01886],[19245.2832,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[19622.64,1,0.0],[20188.68,2,0.0],[20377.36,3,283.01886],[20754.7168,2,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[21132.0762,1,283.01886],[21132.0762,5,754.717],[21509.4336,3,283.01886],[21886.793,2,283.01886],[22264.15,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[22641.51,1,471.69812],[23207.5469,0,0.0],[23301.8867,2,0.0],[23396.2266,0,0.0],[23584.9063,3,0.0],[23773.584,0,0.0],[23962.2637,1,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[24150.9434,3,283.01886],[24528.3027,2,0.0],[24716.98,0,0.0],[24905.66,2,0.0],[25094.34,0,0.0],[25283.02,2,0.0],[25471.6973,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[25660.377,1,471.69812],[26226.416,2,0.0],[26415.0938,3,0.0],[26603.7734,2,0.0],[26792.4531,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[27169.81,1,283.01886],[27547.17,3,283.01886],[27924.5273,2,283.01886],[28301.8867,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[28679.2461,1,471.69812],[29245.2832,0,0.0],[29339.623,2,0.0],[29433.9629,0,0.0],[29622.64,3,0.0],[29811.32,0,0.0],[30000.0,1,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[30188.68,3,283.01886],[30566.0371,2,0.0],[30754.7168,0,0.0],[30943.3965,2,0.0],[31132.0762,0,0.0],[31320.7539,2,0.0],[31509.4336,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[31698.1133,1,471.69812],[32264.15,2,0.0],[32452.83,3,0.0],[32641.51,2,0.0],[32830.1875,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[33396.2266,3,0.0],[33490.5664,3,0.0],[33584.9063,2,0.0],[33773.5859,1,0.0],[33962.2656,0,283.01886],[34528.3,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[35094.34,2,283.01886],[35471.7,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[36415.0938,3,94.33962],[36603.7734,2,94.33962],[36792.4531,1,94.33962],[36981.1328,0,283.01886],[37358.4922,1,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[37735.8477,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[39433.96,3,0.0],[39528.3,3,0.0],[39622.64,2,0.0],[39811.32,1,0.0],[40000.0,0,283.01886],[40566.04,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[41132.0742,2,283.01886],[41509.4336,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[42452.832,3,94.33962],[42641.5078,2,94.33962],[42830.1875,1,94.33962],[43018.8672,0,283.01886],[43396.2266,1,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[43773.5859,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[45283.02,0,283.01886],[45660.38,1,283.01886],[46037.7344,2,0.0],[46226.4141,3,0.0],[46415.0938,2,0.0],[46603.7734,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[46792.4531,5,283.01886],[47169.8125,0,0.0],[47547.168,3,0.0],[47924.5273,1,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[48301.8867,6,849.0566],[48301.8867,2,283.01886],[48679.2461,0,188.679245],[49056.6055,3,0.0],[49245.28,0,0.0],[49339.62,0,0.0],[49433.96,3,0.0],[49622.64,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[49937.1055,2,0.0],[50188.68,2,0.0],[50440.25,2,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[51320.7539,0,283.01886],[51698.1133,1,283.01886],[52075.4727,2,0.0],[52264.1523,3,0.0],[52452.832,2,0.0],[52641.5078,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[52830.1875,5,283.01886],[53207.5469,0,0.0],[53584.9063,3,0.0],[53962.2656,1,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[54339.62,6,1132.07544],[54339.62,2,188.679245],[54716.98,0,188.679245],[55094.34,3,0.0],[55283.02,0,0.0],[55377.36,0,0.0],[55471.7,3,0.0],[55660.38,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[56037.7344,2,0.0],[56415.0938,2,0.0],[56603.7734,2,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[57547.168,2,0.0],[57924.5273,2,0.0],[58018.8672,3,0.0],[58113.207,2,0.0],[58301.8867,0,0.0],[58490.5664,2,0.0],[58679.2461,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[58867.9258,1,0.0],[59056.6055,0,0.0],[59245.28,3,283.01886],[59622.64,2,0.0],[59811.32,3,0.0],[60000.0,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[60566.04,2,0.0],[60943.3945,2,0.0],[61037.7344,3,0.0],[61132.0742,2,0.0],[61320.7539,0,0.0],[61509.4336,2,0.0],[61698.1133,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[61886.793,1,0.0],[62075.4727,0,0.0],[62264.1523,3,283.01886],[62641.5078,2,0.0],[62830.1875,3,0.0],[63018.8672,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[63396.2266,3,0.0],[63584.9063,3,0.0],[63773.5859,1,283.01886],[64150.94,0,0.0],[64528.3,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[64905.66,4,0.0],[64905.66,3,0.0],[65094.34,3,0.0],[65283.02,1,283.01886],[65660.375,0,0.0],[65849.0547,0,0.0],[66037.7344,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[66415.09,4,0.0],[66415.09,0,0.0],[66603.77,5,0.0],[66603.77,1,0.0],[66981.13,7,0.0],[66981.13,3,0.0],[67358.49,6,0.0],[67358.49,2,0.0],[67735.85,1,754.717],[67735.85,5,754.717]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[69622.64,0,0.0],[69716.9844,0,0.0],[69811.32,3,0.0],[70188.68,1,0.0],[70377.36,0,0.0],[70566.04,2,0.0],[70754.72,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[71132.08,2,0.0],[71226.4141,3,0.0],[71320.76,1,0.0],[71509.44,0,0.0],[71698.11,2,0.0],[71886.79,3,0.0],[72075.47,0,0.0],[72264.15,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[72452.83,2,283.01886],[72830.19,0,283.01886],[73207.55,3,283.01886],[73584.91,0,0.0],[73773.5859,1,566.0377]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[74528.3047,0,0.0],[74716.9844,3,0.0],[74905.6641,0,0.0],[75094.3359,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[75660.375,0,0.0],[75754.72,0,0.0],[75849.0547,3,0.0],[76226.4141,1,0.0],[76415.09,0,0.0],[76603.77,2,0.0],[76792.45,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[77169.81,2,0.0],[77264.15,3,0.0],[77358.49,1,0.0],[77547.17,0,0.0],[77735.85,2,0.0],[77924.53,3,0.0],[78113.21,0,0.0],[78301.88,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[78490.56,2,283.01886],[78867.92,0,283.01886],[79245.28,3,283.01886],[79622.64,0,0.0],[79811.32,1,566.0377]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[80566.04,0,0.0],[80754.72,3,0.0],[80943.4,0,0.0],[81132.08,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[81509.44,1,0.0],[81698.11,1,0.0],[81886.79,3,0.0],[82075.47,3,0.0],[82264.15,0,0.0],[82452.83,3,0.0],[82641.51,2,0.0],[82830.19,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[83018.87,1,0.0],[83207.55,1,0.0],[83396.23,3,0.0],[83584.91,3,0.0],[83773.5859,0,0.0],[83962.2656,3,0.0],[84150.9453,2,0.0],[84339.625,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[84528.3047,2,0.0],[84716.9844,3,0.0],[84905.6641,2,0.0],[85094.3359,0,0.0],[85283.0156,2,0.0],[85471.6953,3,0.0],[85660.375,2,0.0],[85849.0547,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[86037.7344,2,0.0],[86226.4141,3,0.0],[86415.09,2,0.0],[86603.77,0,0.0],[86792.45,2,0.0],[86981.13,3,0.0],[87169.81,2,0.0],[87358.49,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[87547.17,3,283.01886],[87924.53,0,94.33962],[88113.21,1,283.01886],[88301.88,4,0.0],[88490.56,0,0.0],[88490.56,7,0.0],[88679.24,1,0.0],[88679.24,7,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[89056.6,5,283.01886],[89056.6,3,0.0],[89433.96,3,0.0],[89811.32,1,283.01886],[89811.32,7,0.0],[90000.0,4,0.0],[90188.68,6,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[90566.04,5,283.01886],[90566.04,0,0.0],[91132.08,3,0.0],[91698.11,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[92075.47,6,566.0377],[92075.47,2,566.0377],[92830.19,3,566.0377],[92830.19,4,566.0377]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[93773.5859,3,0.0],[93867.92,3,0.0],[93962.2656,2,0.0],[94150.9453,1,0.0],[94150.9453,7,0.0],[94245.28,7,0.0],[94339.625,0,283.01886],[94339.625,6,0.0],[94528.3047,5,0.0],[94716.9844,4,283.01886],[94905.6641,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[95283.0156,3,283.01886],[95471.6953,6,283.01886],[95849.0547,2,283.01886],[95849.0547,4,283.01886],[96226.4141,0,283.01886],[96226.4141,7,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[96603.77,3,0.0],[96792.45,7,94.33962],[96981.13,6,94.33962],[97169.81,5,94.33962],[97169.81,3,94.33962],[97358.49,4,283.01886],[97358.49,2,94.33962],[97547.17,1,94.33962],[97735.85,0,283.01886],[97735.85,5,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[98113.21,5,283.01886],[98113.21,0,283.01886],[98490.56,7,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[99811.32,3,0.0],[99905.6641,3,0.0],[100000.0,2,0.0],[100188.68,7,0.0],[100188.68,1,0.0],[100283.016,7,0.0],[100377.359,6,0.0],[100377.359,0,283.01886],[100566.039,5,0.0],[100754.719,4,283.01886],[100943.4,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[101320.758,3,283.01886],[101509.438,6,283.01886],[101886.789,2,283.01886],[101886.789,4,283.01886],[102264.148,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[102830.188,3,94.33962],[103018.867,2,94.33962],[103207.547,7,94.33962],[103207.547,1,94.33962],[103396.227,0,283.01886],[103396.227,6,94.33962],[103584.906,5,94.33962],[103773.586,1,283.01886],[103773.586,4,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[104150.945,0,283.01886],[104150.945,5,283.01886],[104528.305,7,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[105849.055,2,0.0],[106226.414,2,0.0],[106320.758,3,0.0],[106415.094,2,0.0],[106603.773,0,0.0],[106792.453,2,0.0],[106981.133,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[107169.813,1,0.0],[107358.492,0,0.0],[107547.172,3,283.01886],[107924.531,2,0.0],[108113.211,3,0.0],[108301.883,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[108867.922,2,0.0],[109245.281,2,0.0],[109339.625,3,0.0],[109433.961,2,0.0],[109622.641,0,0.0],[109811.32,2,0.0],[110000.0,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[110188.68,1,0.0],[110377.359,0,0.0],[110566.039,3,283.01886],[110943.4,2,0.0],[111132.078,3,0.0],[111320.758,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[111698.109,3,0.0],[111886.789,3,0.0],[112075.469,1,283.01886],[112452.828,0,0.0],[112830.188,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[113207.547,4,0.0],[113207.547,3,0.0],[113396.227,3,0.0],[113584.906,1,283.01886],[113962.266,0,0.0],[114150.945,0,0.0],[114339.625,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[114716.984,0,0.0],[114716.984,4,0.0],[114905.664,1,0.0],[114905.664,5,0.0],[115283.016,3,0.0],[115283.016,7,0.0],[115660.375,2,0.0],[115660.375,6,0.0],[116037.734,5,754.717],[116037.734,1,754.717]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[117924.531,0,0.0],[118301.883,3,0.0],[118490.563,1,0.0],[118679.242,0,0.0],[118867.922,2,0.0],[119056.6,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[119245.281,2,283.01886],[119622.641,3,283.01886],[120000.0,0,283.01886],[120377.359,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[120754.719,6,754.717],[120943.4,0,0.0],[121320.758,3,0.0],[121509.438,1,0.0],[121698.109,0,0.0],[121886.789,2,0.0],[122075.469,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[122264.148,2,283.01886],[122641.508,3,283.01886],[123018.867,0,283.01886],[123396.227,3,754.717]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[123773.586,1,94.33962],[124150.945,3,0.0],[124339.625,3,0.0],[124528.305,2,283.01886],[124905.664,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[125283.016,5,283.01886],[125283.016,2,0.0],[125471.695,3,0.0],[125660.375,1,283.01886],[126037.734,3,0.0],[126226.414,0,0.0],[126415.094,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[126792.453,0,0.0],[126792.453,4,0.0],[126981.133,1,0.0],[126981.133,5,0.0],[127358.492,3,0.0],[127358.492,7,0.0],[127735.852,2,0.0],[127735.852,6,0.0],[128113.211,1,377.3585],[128113.211,5,377.3585]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[129056.6,0,0.0],[129245.281,3,0.0],[129433.961,0,0.0],[129622.641,1,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[129811.32,2,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]}]},"generatedBy":"SNIFF ver.6"}
diff --git a/assets/songs/winter horrorland/charts/normal.json b/assets/songs/winter horrorland/charts/normal.json
index a00dcf64..b1c4eda2 100644
--- a/assets/songs/winter horrorland/charts/normal.json
+++ b/assets/songs/winter horrorland/charts/normal.json
@@ -1 +1 @@
-{"song":{"gf":"gf-christmas","stage":"mall-evil","song":"Winter Horrorland","bpm":159.0,"needsVoices":true,"player1":"bf-christmas","player2":"Monster-christmas","speed":1.1,"notes":[{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[9433.962,0,283.01886],[9811.32,2,283.01886],[10188.68,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[10566.0381,0,660.3774],[11320.7549,2,660.3774]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[12452.83,0,283.01886],[12830.1885,2,283.01886],[13207.5469,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[13584.9053,1,0.0],[14339.623,3,283.01886],[14716.9814,2,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[15094.34,5,754.717],[15471.6982,0,283.01886],[15849.0566,2,283.01886],[16226.415,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[16603.7734,0,660.3774],[17358.49,2,660.3774]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[18490.5664,0,283.01886],[18867.9238,2,283.01886],[19245.2832,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[19622.64,1,0.0],[20377.36,3,283.01886],[20754.7168,2,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[21132.0762,1,283.01886],[21132.0762,5,754.717],[21509.4336,3,283.01886],[21886.793,2,283.01886],[22264.15,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[22641.51,1,471.69812],[23207.5469,0,0.0],[23396.2266,0,0.0],[23773.584,0,0.0],[23962.2637,1,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[24150.9434,3,283.01886],[24528.3027,2,0.0],[24905.66,2,0.0],[25283.02,2,0.0],[25471.6973,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[25660.377,1,471.69812],[26226.416,2,0.0],[26415.0938,3,0.0],[26603.7734,2,0.0],[26792.4531,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[27169.81,1,283.01886],[27547.17,3,283.01886],[27924.5273,2,283.01886],[28301.8867,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[28679.2461,1,471.69812],[29245.2832,0,0.0],[29433.9629,0,0.0],[29811.32,0,0.0],[30000.0,1,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[30188.68,3,283.01886],[30566.0371,2,0.0],[30943.3965,2,0.0],[31320.7539,2,0.0],[31509.4336,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[31698.1133,1,471.69812],[32264.15,2,0.0],[32452.83,3,0.0],[32641.51,2,0.0],[32830.1875,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[33396.2266,3,0.0],[33584.9063,2,0.0],[33962.2656,0,283.01886],[34528.3,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[35094.34,2,283.01886],[35471.7,0,283.01886],[35849.0547,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[36603.7734,2,0.0],[36981.1328,0,283.01886],[37358.4922,1,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[37735.8477,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[39433.96,3,0.0],[39622.64,2,0.0],[40000.0,0,283.01886],[40566.04,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[41132.0742,2,283.01886],[41509.4336,0,283.01886],[41886.793,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[42641.5078,2,0.0],[43018.8672,0,283.01886],[43396.2266,1,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[43773.5859,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[45283.02,0,283.01886],[45660.38,1,283.01886],[46037.7344,2,0.0],[46415.0938,2,0.0],[46603.7734,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[46792.4531,5,283.01886],[47169.8125,0,0.0],[47547.168,3,0.0],[47924.5273,1,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[48301.8867,2,283.01886],[48301.8867,6,849.0566],[48679.2461,0,188.679245],[49056.6055,3,0.0],[49245.28,0,0.0],[49433.96,3,0.0],[49622.64,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[49937.1055,2,0.0],[50188.68,2,0.0],[50440.25,2,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[51320.7539,0,283.01886],[51698.1133,1,283.01886],[52075.4727,2,0.0],[52452.832,2,0.0],[52641.5078,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[52830.1875,5,283.01886],[53207.5469,0,0.0],[53584.9063,3,0.0],[53962.2656,1,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[54339.62,6,1132.07544],[54339.62,2,188.679245],[54716.98,0,188.679245],[55094.34,3,0.0],[55283.02,0,0.0],[55471.7,3,0.0],[55660.38,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[56037.7344,2,0.0],[56415.0938,2,0.0],[56603.7734,2,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[57547.168,2,0.0],[57924.5273,2,0.0],[58113.207,2,0.0],[58490.5664,2,0.0],[58679.2461,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[58867.9258,1,0.0],[59245.28,3,283.01886],[59622.64,2,0.0],[60000.0,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[60566.04,2,0.0],[60943.3945,2,0.0],[61132.0742,2,0.0],[61509.4336,2,0.0],[61698.1133,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[61886.793,1,0.0],[62264.1523,3,283.01886],[62641.5078,2,0.0],[63018.8672,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[63396.2266,3,0.0],[63773.5859,1,283.01886],[64150.94,0,0.0],[64528.3,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[64905.66,4,0.0],[64905.66,3,0.0],[65283.02,1,283.01886],[65660.375,0,0.0],[66037.7344,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[66415.09,4,0.0],[66415.09,0,0.0],[66981.13,7,0.0],[66981.13,3,0.0],[67358.49,6,0.0],[67358.49,2,0.0],[67735.85,5,754.717],[67735.85,1,754.717]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[69622.64,0,0.0],[69811.32,3,0.0],[70188.68,1,0.0],[70566.04,2,0.0],[70754.72,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[71132.08,2,0.0],[71320.76,1,0.0],[71698.11,2,0.0],[72075.47,0,0.0],[72264.15,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[72452.83,2,283.01886],[72830.19,0,283.01886],[73207.55,3,283.01886],[73584.91,0,0.0],[73773.5859,1,566.0377]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[74528.3047,0,0.0],[74716.9844,3,0.0],[74905.6641,0,0.0],[75094.3359,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[75660.375,0,0.0],[75849.0547,3,0.0],[76226.4141,1,0.0],[76603.77,2,0.0],[76792.45,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[77169.81,2,0.0],[77358.49,1,0.0],[77735.85,2,0.0],[78113.21,0,0.0],[78301.88,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[78490.56,2,283.01886],[78867.92,0,283.01886],[79245.28,3,283.01886],[79622.64,0,0.0],[79811.32,1,566.0377]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[80566.04,0,0.0],[80754.72,3,0.0],[80943.4,0,0.0],[81132.08,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[81509.44,1,0.0],[81886.79,3,0.0],[82264.15,0,0.0],[82641.51,2,0.0],[82830.19,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[83018.87,1,0.0],[83396.23,3,0.0],[83773.5859,0,0.0],[84150.9453,2,0.0],[84339.625,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[84528.3047,2,0.0],[84905.6641,2,0.0],[85094.3359,0,0.0],[85283.0156,2,0.0],[85660.375,2,0.0],[85849.0547,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[86037.7344,2,0.0],[86415.09,2,0.0],[86603.77,0,0.0],[86792.45,2,0.0],[87169.81,2,0.0],[87358.49,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[87547.17,3,283.01886],[87924.53,0,94.33962],[88113.21,1,283.01886],[88301.88,4,0.0],[88679.24,1,0.0],[88679.24,7,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[89056.6,5,283.01886],[89056.6,3,0.0],[89433.96,3,0.0],[89811.32,1,283.01886],[89811.32,7,0.0],[90188.68,6,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[90566.04,5,283.01886],[90566.04,0,0.0],[91132.08,3,0.0],[91698.11,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[92075.47,2,566.0377],[92075.47,6,566.0377],[92830.19,3,566.0377],[92830.19,4,566.0377]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[93773.5859,3,0.0],[93962.2656,2,0.0],[94150.9453,7,0.0],[94339.625,6,0.0],[94339.625,0,283.01886],[94716.9844,4,283.01886],[94905.6641,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[95283.0156,3,283.01886],[95471.6953,6,283.01886],[95849.0547,2,283.01886],[95849.0547,4,283.01886],[96226.4141,0,283.01886],[96226.4141,7,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[96603.77,3,0.0],[96981.13,6,0.0],[97358.49,2,0.0],[97358.49,4,283.01886],[97735.85,0,283.01886],[97735.85,5,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[98113.21,5,283.01886],[98113.21,0,283.01886],[98490.56,7,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[99811.32,3,0.0],[100000.0,2,0.0],[100188.68,7,0.0],[100377.359,0,283.01886],[100377.359,6,0.0],[100754.719,4,283.01886],[100943.4,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[101320.758,3,283.01886],[101509.438,6,283.01886],[101886.789,2,283.01886],[101886.789,4,283.01886],[102264.148,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[102830.188,3,94.33962],[103018.867,2,94.33962],[103207.547,7,94.33962],[103396.227,0,283.01886],[103396.227,6,94.33962],[103773.586,1,283.01886],[103773.586,4,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[104150.945,0,283.01886],[104150.945,5,283.01886],[104528.305,7,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[105849.055,2,0.0],[106226.414,2,0.0],[106415.094,2,0.0],[106792.453,2,0.0],[106981.133,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[107169.813,1,0.0],[107547.172,3,283.01886],[107924.531,2,0.0],[108301.883,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[108867.922,2,0.0],[109245.281,2,0.0],[109433.961,2,0.0],[109811.32,2,0.0],[110000.0,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[110188.68,1,0.0],[110566.039,3,283.01886],[110943.4,2,0.0],[111320.758,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[111698.109,3,0.0],[112075.469,1,283.01886],[112452.828,0,0.0],[112830.188,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[113207.547,3,0.0],[113207.547,4,0.0],[113584.906,1,283.01886],[113962.266,0,0.0],[114339.625,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[114716.984,4,0.0],[114716.984,0,0.0],[115283.016,7,0.0],[115283.016,3,0.0],[115660.375,6,0.0],[115660.375,2,0.0],[116037.734,5,754.717],[116037.734,1,754.717]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[117924.531,0,0.0],[118490.563,1,0.0],[118867.922,2,0.0],[119056.6,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[119245.281,2,283.01886],[119622.641,3,283.01886],[120000.0,0,283.01886],[120377.359,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[120754.719,6,754.717],[120943.4,0,0.0],[121509.438,1,0.0],[121886.789,2,0.0],[122075.469,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[122264.148,2,283.01886],[122641.508,3,283.01886],[123018.867,0,283.01886],[123396.227,3,754.717]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[123773.586,1,94.33962],[124150.945,3,0.0],[124528.305,2,283.01886],[124905.664,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[125283.016,5,283.01886],[125283.016,2,0.0],[125660.375,1,283.01886],[126037.734,3,0.0],[126226.414,0,0.0],[126415.094,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[126792.453,0,0.0],[126792.453,4,0.0],[127358.492,3,0.0],[127358.492,7,0.0],[127735.852,2,0.0],[127735.852,6,0.0],[128113.211,1,377.3585],[128113.211,5,377.3585]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[129056.6,0,0.0],[129245.281,3,0.0],[129433.961,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[129811.32,2,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]}]},"generatedBy":"SNIFF ver.6"}
\ No newline at end of file
+{"song":{"gf":"gf-christmas","stage":"mall-evil","song":"Winter Horrorland","bpm":159.0,"needsVoices":true,"player1":"bf-christmas","player2":"monster-christmas","speed":1.1,"notes":[{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[9433.962,0,283.01886],[9811.32,2,283.01886],[10188.68,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[10566.0381,0,660.3774],[11320.7549,2,660.3774]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[12452.83,0,283.01886],[12830.1885,2,283.01886],[13207.5469,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[13584.9053,1,0.0],[14339.623,3,283.01886],[14716.9814,2,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[15094.34,5,754.717],[15471.6982,0,283.01886],[15849.0566,2,283.01886],[16226.415,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[16603.7734,0,660.3774],[17358.49,2,660.3774]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[18490.5664,0,283.01886],[18867.9238,2,283.01886],[19245.2832,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[19622.64,1,0.0],[20377.36,3,283.01886],[20754.7168,2,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[21132.0762,1,283.01886],[21132.0762,5,754.717],[21509.4336,3,283.01886],[21886.793,2,283.01886],[22264.15,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[22641.51,1,471.69812],[23207.5469,0,0.0],[23396.2266,0,0.0],[23773.584,0,0.0],[23962.2637,1,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[24150.9434,3,283.01886],[24528.3027,2,0.0],[24905.66,2,0.0],[25283.02,2,0.0],[25471.6973,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[25660.377,1,471.69812],[26226.416,2,0.0],[26415.0938,3,0.0],[26603.7734,2,0.0],[26792.4531,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[27169.81,1,283.01886],[27547.17,3,283.01886],[27924.5273,2,283.01886],[28301.8867,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[28679.2461,1,471.69812],[29245.2832,0,0.0],[29433.9629,0,0.0],[29811.32,0,0.0],[30000.0,1,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[30188.68,3,283.01886],[30566.0371,2,0.0],[30943.3965,2,0.0],[31320.7539,2,0.0],[31509.4336,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[31698.1133,1,471.69812],[32264.15,2,0.0],[32452.83,3,0.0],[32641.51,2,0.0],[32830.1875,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[33396.2266,3,0.0],[33584.9063,2,0.0],[33962.2656,0,283.01886],[34528.3,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[35094.34,2,283.01886],[35471.7,0,283.01886],[35849.0547,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[36603.7734,2,0.0],[36981.1328,0,283.01886],[37358.4922,1,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[37735.8477,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[39433.96,3,0.0],[39622.64,2,0.0],[40000.0,0,283.01886],[40566.04,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[41132.0742,2,283.01886],[41509.4336,0,283.01886],[41886.793,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[42641.5078,2,0.0],[43018.8672,0,283.01886],[43396.2266,1,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[43773.5859,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[45283.02,0,283.01886],[45660.38,1,283.01886],[46037.7344,2,0.0],[46415.0938,2,0.0],[46603.7734,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[46792.4531,5,283.01886],[47169.8125,0,0.0],[47547.168,3,0.0],[47924.5273,1,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[48301.8867,2,283.01886],[48301.8867,6,849.0566],[48679.2461,0,188.679245],[49056.6055,3,0.0],[49245.28,0,0.0],[49433.96,3,0.0],[49622.64,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[49937.1055,2,0.0],[50188.68,2,0.0],[50440.25,2,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[51320.7539,0,283.01886],[51698.1133,1,283.01886],[52075.4727,2,0.0],[52452.832,2,0.0],[52641.5078,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[52830.1875,5,283.01886],[53207.5469,0,0.0],[53584.9063,3,0.0],[53962.2656,1,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[54339.62,6,1132.07544],[54339.62,2,188.679245],[54716.98,0,188.679245],[55094.34,3,0.0],[55283.02,0,0.0],[55471.7,3,0.0],[55660.38,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[56037.7344,2,0.0],[56415.0938,2,0.0],[56603.7734,2,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[57547.168,2,0.0],[57924.5273,2,0.0],[58113.207,2,0.0],[58490.5664,2,0.0],[58679.2461,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[58867.9258,1,0.0],[59245.28,3,283.01886],[59622.64,2,0.0],[60000.0,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[60566.04,2,0.0],[60943.3945,2,0.0],[61132.0742,2,0.0],[61509.4336,2,0.0],[61698.1133,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[61886.793,1,0.0],[62264.1523,3,283.01886],[62641.5078,2,0.0],[63018.8672,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[63396.2266,3,0.0],[63773.5859,1,283.01886],[64150.94,0,0.0],[64528.3,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[64905.66,4,0.0],[64905.66,3,0.0],[65283.02,1,283.01886],[65660.375,0,0.0],[66037.7344,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[66415.09,4,0.0],[66415.09,0,0.0],[66981.13,7,0.0],[66981.13,3,0.0],[67358.49,6,0.0],[67358.49,2,0.0],[67735.85,5,754.717],[67735.85,1,754.717]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[69622.64,0,0.0],[69811.32,3,0.0],[70188.68,1,0.0],[70566.04,2,0.0],[70754.72,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[71132.08,2,0.0],[71320.76,1,0.0],[71698.11,2,0.0],[72075.47,0,0.0],[72264.15,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[72452.83,2,283.01886],[72830.19,0,283.01886],[73207.55,3,283.01886],[73584.91,0,0.0],[73773.5859,1,566.0377]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[74528.3047,0,0.0],[74716.9844,3,0.0],[74905.6641,0,0.0],[75094.3359,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[75660.375,0,0.0],[75849.0547,3,0.0],[76226.4141,1,0.0],[76603.77,2,0.0],[76792.45,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[77169.81,2,0.0],[77358.49,1,0.0],[77735.85,2,0.0],[78113.21,0,0.0],[78301.88,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[78490.56,2,283.01886],[78867.92,0,283.01886],[79245.28,3,283.01886],[79622.64,0,0.0],[79811.32,1,566.0377]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[80566.04,0,0.0],[80754.72,3,0.0],[80943.4,0,0.0],[81132.08,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[81509.44,1,0.0],[81886.79,3,0.0],[82264.15,0,0.0],[82641.51,2,0.0],[82830.19,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[83018.87,1,0.0],[83396.23,3,0.0],[83773.5859,0,0.0],[84150.9453,2,0.0],[84339.625,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[84528.3047,2,0.0],[84905.6641,2,0.0],[85094.3359,0,0.0],[85283.0156,2,0.0],[85660.375,2,0.0],[85849.0547,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[86037.7344,2,0.0],[86415.09,2,0.0],[86603.77,0,0.0],[86792.45,2,0.0],[87169.81,2,0.0],[87358.49,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[87547.17,3,283.01886],[87924.53,0,94.33962],[88113.21,1,283.01886],[88301.88,4,0.0],[88679.24,1,0.0],[88679.24,7,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[89056.6,5,283.01886],[89056.6,3,0.0],[89433.96,3,0.0],[89811.32,1,283.01886],[89811.32,7,0.0],[90188.68,6,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[90566.04,5,283.01886],[90566.04,0,0.0],[91132.08,3,0.0],[91698.11,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[92075.47,2,566.0377],[92075.47,6,566.0377],[92830.19,3,566.0377],[92830.19,4,566.0377]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[93773.5859,3,0.0],[93962.2656,2,0.0],[94150.9453,7,0.0],[94339.625,6,0.0],[94339.625,0,283.01886],[94716.9844,4,283.01886],[94905.6641,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[95283.0156,3,283.01886],[95471.6953,6,283.01886],[95849.0547,2,283.01886],[95849.0547,4,283.01886],[96226.4141,0,283.01886],[96226.4141,7,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[96603.77,3,0.0],[96981.13,6,0.0],[97358.49,2,0.0],[97358.49,4,283.01886],[97735.85,0,283.01886],[97735.85,5,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[98113.21,5,283.01886],[98113.21,0,283.01886],[98490.56,7,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[99811.32,3,0.0],[100000.0,2,0.0],[100188.68,7,0.0],[100377.359,0,283.01886],[100377.359,6,0.0],[100754.719,4,283.01886],[100943.4,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[101320.758,3,283.01886],[101509.438,6,283.01886],[101886.789,2,283.01886],[101886.789,4,283.01886],[102264.148,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[102830.188,3,94.33962],[103018.867,2,94.33962],[103207.547,7,94.33962],[103396.227,0,283.01886],[103396.227,6,94.33962],[103773.586,1,283.01886],[103773.586,4,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[104150.945,0,283.01886],[104150.945,5,283.01886],[104528.305,7,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[105849.055,2,0.0],[106226.414,2,0.0],[106415.094,2,0.0],[106792.453,2,0.0],[106981.133,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[107169.813,1,0.0],[107547.172,3,283.01886],[107924.531,2,0.0],[108301.883,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[108867.922,2,0.0],[109245.281,2,0.0],[109433.961,2,0.0],[109811.32,2,0.0],[110000.0,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[110188.68,1,0.0],[110566.039,3,283.01886],[110943.4,2,0.0],[111320.758,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[111698.109,3,0.0],[112075.469,1,283.01886],[112452.828,0,0.0],[112830.188,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[113207.547,3,0.0],[113207.547,4,0.0],[113584.906,1,283.01886],[113962.266,0,0.0],[114339.625,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[114716.984,4,0.0],[114716.984,0,0.0],[115283.016,7,0.0],[115283.016,3,0.0],[115660.375,6,0.0],[115660.375,2,0.0],[116037.734,5,754.717],[116037.734,1,754.717]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[117924.531,0,0.0],[118490.563,1,0.0],[118867.922,2,0.0],[119056.6,3,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[119245.281,2,283.01886],[119622.641,3,283.01886],[120000.0,0,283.01886],[120377.359,3,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[120754.719,6,754.717],[120943.4,0,0.0],[121509.438,1,0.0],[121886.789,2,0.0],[122075.469,3,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[122264.148,2,283.01886],[122641.508,3,283.01886],[123018.867,0,283.01886],[123396.227,3,754.717]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[123773.586,1,94.33962],[124150.945,3,0.0],[124528.305,2,283.01886],[124905.664,0,283.01886]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[125283.016,5,283.01886],[125283.016,2,0.0],[125660.375,1,283.01886],[126037.734,3,0.0],[126226.414,0,0.0],[126415.094,0,0.0]]},{"lengthInSteps":16,"mustHitSection":false,"sectionNotes":[[126792.453,0,0.0],[126792.453,4,0.0],[127358.492,3,0.0],[127358.492,7,0.0],[127735.852,2,0.0],[127735.852,6,0.0],[128113.211,1,377.3585],[128113.211,5,377.3585]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[129056.6,0,0.0],[129245.281,3,0.0],[129433.961,0,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[[129811.32,2,0.0]]},{"lengthInSteps":16,"mustHitSection":true,"sectionNotes":[]}]},"generatedBy":"SNIFF ver.6"}
diff --git a/source/funkin/backend/FunkinSprite.hx b/source/funkin/backend/FunkinSprite.hx
index 2e4df83d..2f999e0d 100644
--- a/source/funkin/backend/FunkinSprite.hx
+++ b/source/funkin/backend/FunkinSprite.hx
@@ -72,24 +72,34 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
moves = false;
}
- public static function copyFrom(source:FunkinSprite)
+ /**
+ * Gets the graphics and copies other properties from another sprite (Works both for `FlxSprite` and `FunkinSprite`!).
+ */
+ public static function copyFrom(source:FlxSprite):FunkinSprite
{
var spr = new FunkinSprite();
+ var casted:FunkinSprite = null;
+ if (source is FunkinSprite)
+ casted = cast source;
+
@:privateAccess {
spr.setPosition(source.x, source.y);
spr.frames = source.frames;
- if (source.animateAtlas != null && source.atlasPath != null)
- spr.loadSprite(source.atlasPath);
+ if (casted != null && casted.animateAtlas != null && casted.atlasPath != null)
+ spr.loadSprite(casted.atlasPath);
spr.animation.copyFrom(source.animation);
spr.visible = source.visible;
spr.alpha = source.alpha;
spr.antialiasing = source.antialiasing;
spr.scale.set(source.scale.x, source.scale.y);
spr.scrollFactor.set(source.scrollFactor.x, source.scrollFactor.y);
- spr.skew.set(source.skew.x, source.skew.y);
- spr.transformMatrix = source.transformMatrix;
- spr.matrixExposed = source.matrixExposed;
- spr.animOffsets = source.animOffsets.copy();
+
+ if (casted != null) {
+ spr.skew.set(casted.skew.x, casted.skew.y);
+ spr.transformMatrix = casted.transformMatrix;
+ spr.matrixExposed = casted.matrixExposed;
+ spr.animOffsets = casted.animOffsets.copy();
+ }
}
return spr;
}
diff --git a/source/funkin/backend/assets/AssetsLibraryList.hx b/source/funkin/backend/assets/AssetsLibraryList.hx
index 49447997..2afa2e3a 100644
--- a/source/funkin/backend/assets/AssetsLibraryList.hx
+++ b/source/funkin/backend/assets/AssetsLibraryList.hx
@@ -63,7 +63,8 @@ class AssetsLibraryList extends AssetLibrary {
if (l is IModsAssetLibrary) {
var lib = cast(l, IModsAssetLibrary);
for(e in lib.getFiles(folder))
- content.push(e);
+ if(!content.contains(e))
+ content.push(e);
}
#end
}
@@ -87,7 +88,8 @@ class AssetsLibraryList extends AssetLibrary {
if (l is IModsAssetLibrary) {
var lib = cast(l, IModsAssetLibrary);
for(e in lib.getFolders(folder))
- content.push(e);
+ if(!content.contains(e))
+ content.push(e);
}
#end
}
diff --git a/source/funkin/backend/assets/Paths.hx b/source/funkin/backend/assets/Paths.hx
index 9486aed6..a29d3909 100644
--- a/source/funkin/backend/assets/Paths.hx
+++ b/source/funkin/backend/assets/Paths.hx
@@ -200,6 +200,29 @@ class Paths
return tempFramesCache[key] = loadFrames(assetsPath ? key : Paths.image(key, library, true));
}
+ /**
+ * Checks if the images needed for using getFrames() exist.
+ * @param key Path to the image
+ * @param checkAtlas Whenever to check for the Animation.json file (used in FlxAnimate)
+ * @param assetsPath Whenever to use the raw path or to pass it through Paths.image()
+ * @param library (Additional) library to load the frames from.
+ * @return True if the images exist, false otherwise.
+ **/
+ public static function framesExists(key:String, checkAtlas:Bool = false, checkMulti:Bool = true, assetsPath:Bool = false, ?library:String) {
+ var path = assetsPath ? key : Paths.image(key, library, true);
+ var noExt = Path.withoutExtension(path);
+ if(checkAtlas && Assets.exists('$noExt/Animation.json'))
+ return true;
+ if(checkMulti && Assets.exists('$noExt/1.png'))
+ return true;
+ if(Assets.exists('$noExt.xml'))
+ return true;
+ if(Assets.exists('$noExt.txt'))
+ return true;
+ if(Assets.exists('$noExt.json'))
+ return true;
+ return false;
+ }
/**
* Loads frames from a specific image path. Supports Sparrow Atlases, Packer Atlases, and multiple spritesheets.
diff --git a/source/funkin/backend/scripting/HScript.hx b/source/funkin/backend/scripting/HScript.hx
index 0597a32f..888b8f3d 100644
--- a/source/funkin/backend/scripting/HScript.hx
+++ b/source/funkin/backend/scripting/HScript.hx
@@ -119,6 +119,10 @@ class HScript extends Script {
interp.execute(expr);
call("new", []);
}
+
+ #if GLOBAL_SCRIPT
+ funkin.backend.scripting.GlobalScript.call("onScriptSetup", [this, "hscript"]);
+ #end
}
public override function reload() {
diff --git a/source/funkin/backend/scripting/events/NoteHitEvent.hx b/source/funkin/backend/scripting/events/NoteHitEvent.hx
index a4595fd1..750e5f52 100644
--- a/source/funkin/backend/scripting/events/NoteHitEvent.hx
+++ b/source/funkin/backend/scripting/events/NoteHitEvent.hx
@@ -2,6 +2,7 @@ package funkin.backend.scripting.events;
import funkin.game.Note;
import funkin.game.Character;
+import funkin.game.HealthIcon;
final class NoteHitEvent extends CancellableEvent {
@:dox(hide) public var animCancelled:Bool = false;
@@ -113,6 +114,10 @@ final class NoteHitEvent extends CancellableEvent {
* Whenever the animation should be forced to play (if it's null it will be forced based on the sprite's data xml, if it has one).
*/
public var forceAnim:Null = true;
+ /**
+ * The attached healthIcon used distinction for icons amongst others
+ */
+ public var healthIcon:HealthIcon;
/**
* Prevents the default sing animation from being played.
diff --git a/source/funkin/backend/scripting/events/RatingUpdateEvent.hx b/source/funkin/backend/scripting/events/RatingUpdateEvent.hx
index 96ad7e7e..5f14ee50 100644
--- a/source/funkin/backend/scripting/events/RatingUpdateEvent.hx
+++ b/source/funkin/backend/scripting/events/RatingUpdateEvent.hx
@@ -2,12 +2,12 @@ package funkin.backend.scripting.events;
final class RatingUpdateEvent extends CancellableEvent {
/**
- New combo
+ New combo (may be null if no ratings were found)
**/
- public var rating:ComboRating;
+ public var rating:Null;
/**
Old combo (may be null)
**/
- public var oldRating:ComboRating;
+ public var oldRating:Null;
}
\ No newline at end of file
diff --git a/source/funkin/backend/shaders/FunkinShader.hx b/source/funkin/backend/shaders/FunkinShader.hx
index 152ca6c3..a2833e81 100644
--- a/source/funkin/backend/shaders/FunkinShader.hx
+++ b/source/funkin/backend/shaders/FunkinShader.hx
@@ -1,26 +1,20 @@
package funkin.backend.shaders;
+import flixel.graphics.FlxGraphic;
+import flixel.system.FlxAssets.FlxShader;
import haxe.Exception;
import hscript.IHScriptCustomBehaviour;
-import flixel.graphics.tile.FlxGraphicsShader;
-import openfl.display3D.Program3D;
-import flixel.system.FlxAssets.FlxShader;
-
+import lime.utils.Float32Array;
+import openfl.display.BitmapData;
+import openfl.display.ShaderInput;
+import openfl.display.ShaderParameter;
+import openfl.display.ShaderParameterType;
import openfl.display3D._internal.GLProgram;
import openfl.display3D._internal.GLShader;
import openfl.utils._internal.Log;
-import openfl.display.BitmapData;
-import openfl.display.ShaderParameter;
-import openfl.display.ShaderParameterType;
-import openfl.display.ShaderInput;
-import lime.utils.Float32Array;
using StringTools;
-import openfl.display.ShaderParameter;
-import openfl.display.BitmapData;
-import openfl.display.ShaderInput;
-
@:access(openfl.display3D.Context3D)
@:access(openfl.display3D.Program3D)
@:access(openfl.display.ShaderInput)
@@ -195,7 +189,7 @@ class FunkinShader extends FlxShader implements IHScriptCustomBehaviour {
var useBackCompat:Bool = true;
for (regex in ShaderTemplates.vertBackCompatVarList) if (!regex.match(value)) useBackCompat = false;
-
+
value = value.replace("#pragma header", useBackCompat ? ShaderTemplates.vertHeaderBackCompat : ShaderTemplates.vertHeader).replace("#pragma body", useBackCompat ? ShaderTemplates.vertBodyBackCompat : ShaderTemplates.vertBody);
if (value != __glVertexSource)
{
@@ -495,25 +489,26 @@ class FunkinShader extends FlxShader implements IHScriptCustomBehaviour {
} else {
var field = Reflect.field(data, name);
var cl = Type.getClassName(Type.getClass(field));
+ var isNotNull = val != null;
// cant do "field is ShaderInput" for some reason
if (cl.startsWith("openfl.display.ShaderParameter")) {
if (field.__length <= 1) {
// that means we wait for a single number, instead of an array
- if (field.__isInt && !(val is Int)) {
+ if (field.__isInt && isNotNull && !(val is Int)) {
throw new ShaderTypeException(name, Type.getClass(val), 'Int');
return null;
} else
- if (field.__isBool && !(val is Bool)) {
+ if (field.__isBool && isNotNull && !(val is Bool)) {
throw new ShaderTypeException(name, Type.getClass(val), 'Bool');
return null;
} else
- if (field.__isFloat && !(val is Float)) {
+ if (field.__isFloat && isNotNull && !(val is Float)) {
throw new ShaderTypeException(name, Type.getClass(val), 'Float');
return null;
}
- return field.value = [val];
+ return field.value = isNotNull ? [val] : null;
} else {
- if (!(val is Array)) {
+ if (isNotNull && !(val is Array)) {
throw new ShaderTypeException(name, Type.getClass(val), Array);
return null;
}
@@ -521,11 +516,15 @@ class FunkinShader extends FlxShader implements IHScriptCustomBehaviour {
}
} else if (cl.startsWith("openfl.display.ShaderInput")) {
// shader input!!
- if (!(val is BitmapData)) {
+ var bitmap:BitmapData;
+ if (!isNotNull) bitmap = null;
+ else if (val is BitmapData) bitmap = val;
+ else if (val is FlxGraphic) bitmap = val.bitmap;
+ else {
throw new ShaderTypeException(name, Type.getClass(val), BitmapData);
return null;
}
- field.input = cast val;
+ field.input = bitmap;
}
}
diff --git a/source/funkin/backend/system/net/Socket.hx b/source/funkin/backend/system/net/Socket.hx
index 4aefdabe..19ebf9a1 100644
--- a/source/funkin/backend/system/net/Socket.hx
+++ b/source/funkin/backend/system/net/Socket.hx
@@ -18,7 +18,7 @@ class Socket implements IFlxDestroyable {
public function read():String {
try {
- return this.socket.input.readUntil(('\n').charCodeAt(0)).replace("\\n", "\n");
+ return this.socket.input.readUntil('\n'.code).replace("\\n", "\n");
} catch(e) {
}
diff --git a/source/funkin/backend/utils/CoolUtil.hx b/source/funkin/backend/utils/CoolUtil.hx
index 48d8a10a..ba40f420 100644
--- a/source/funkin/backend/utils/CoolUtil.hx
+++ b/source/funkin/backend/utils/CoolUtil.hx
@@ -609,11 +609,11 @@ class CoolUtil
* @param spr Sprite to load the graphic for
* @param path Path to the graphic
*/
- public static function loadAnimatedGraphic(spr:FlxSprite, path:String) {
+ public static function loadAnimatedGraphic(spr:FlxSprite, path:String, fps:Float = 24.0) {
spr.frames = Paths.getFrames(path, true);
if (spr.frames != null && spr.frames.frames != null) {
- spr.animation.add("idle", [for(i in 0...spr.frames.frames.length) i], 24, true);
+ spr.animation.add("idle", [for(i in 0...spr.frames.frames.length) i], fps, true);
spr.animation.play("idle");
}
@@ -904,6 +904,124 @@ class CoolUtil
return result.join(seperator);
}
+
+ public inline static function parsePropertyString(fieldPath:String):Array> {
+ return FlxTween.parseFieldString(fieldPath);
+ }
+
+ public static function stringifyFieldsPath(fields:Array>):String {
+ var str = new StringBuf();
+ var first = true;
+ for (field in fields) {
+ if (Type.typeof(field) == TInt) {
+ str.add('[${field}]');
+ } else {
+ if (!first)
+ str.add('.');
+ str.add(field);
+ }
+ first = false;
+ }
+ return str.toString();
+ }
+
+ public static function parseProperty(target:Dynamic, fields:OneOfTwo>>):Dynamic {
+ var fields:Array> = {
+ if((fields is String)) CoolUtil.parsePropertyString(fields);
+ else fields;
+ }
+
+ var field = CoolUtil.last(fields);
+ for (i in 0...fields.length - 1) {
+ var component = fields[i];
+ if (Type.typeof(component) == TInt) {
+ if ((target is Array)) {
+ var index:Int = cast component;
+ var arr:Array = cast target;
+ target = arr[index];
+ }
+ } else { // TClass(String)
+ target = Reflect.getProperty(target, component);
+ }
+ if (!Reflect.isObject(target) && !(target is Array))
+ throw 'The object does not have the property "$component" in "${stringifyFieldsPath(fields)}"';
+ }
+ return new PropertyInfo(target, field);
+ }
+
+ public static function cloneProperty(toTarget:Dynamic, fields:OneOfTwo>>, fromTarget:Dynamic):Dynamic {
+ var fields:Array> = {
+ if((fields is String)) CoolUtil.parsePropertyString(fields);
+ else fields;
+ }
+
+ var toProperty = CoolUtil.parseProperty(toTarget, fields);
+ var fromProperty = CoolUtil.parseProperty(fromTarget, fields);
+
+ return toProperty.setValue(fromProperty.getValue());
+ }
+}
+
+class PropertyInfo {
+ public var object:Dynamic;
+ public var field:OneOfTwo;
+ public var typeOfField:Type.ValueType;
+ #if hscript_improved
+ public var isCustom:Bool = false;
+ public var custom:hscript.IHScriptCustomBehaviour;
+ #end
+
+ public function new(object:Dynamic, field:OneOfTwo) {
+ this.object = object;
+ this.field = field;
+ #if hscript_improved
+ if (object is hscript.IHScriptCustomBehaviour)
+ {
+ isCustom = true;
+ custom = cast object;
+ }
+ #end
+
+ typeOfField = Type.typeof(field);
+ }
+
+ public function getValue():Dynamic
+ {
+ if (typeOfField == TInt)
+ {
+ var index:Int = cast field;
+ var arr:Array = cast object;
+ return arr[index];
+ }
+ else
+ {
+ #if hscript_improved
+ if (isCustom)
+ return custom.hget(field);
+ else
+ #end
+ return Reflect.getProperty(object, field);
+ }
+ }
+
+ public function setValue(value:Dynamic):Void
+ {
+ if (typeOfField == TInt)
+ {
+ var index:Int = cast field;
+ var arr:Array = cast object;
+ arr[index] = value;
+ }
+ else
+ {
+ #if hscript_improved
+ if (isCustom)
+ custom.hset(field, value);
+ else
+ #end
+ Reflect.setProperty(object, field, value);
+ }
+ }
}
/**
diff --git a/source/funkin/backend/utils/ZipUtil.hx b/source/funkin/backend/utils/ZipUtil.hx
index eef06a6d..b90aecb4 100644
--- a/source/funkin/backend/utils/ZipUtil.hx
+++ b/source/funkin/backend/utils/ZipUtil.hx
@@ -135,12 +135,12 @@ class ZipUtil {
if (prog == null) prog = new ZipProgress();
try {
- var curPath:Array = ['$path'];
+ var curPath:Array = [path];
var destPath:Array = [];
if (prefix != "") {
prefix = prefix.replace("\\", "/");
- while(prefix.charAt(0) == "/") prefix = prefix.substr(1);
- while(prefix.charAt(prefix.length-1) == "/") prefix = prefix.substr(0, prefix.length-1);
+ while(prefix.charCodeAt(0) == "/".code) prefix = prefix.substr(1);
+ while(prefix.charCodeAt(prefix.length-1) == "/".code) prefix = prefix.substr(0, prefix.length-1);
destPath.push(prefix);
}
@@ -160,7 +160,7 @@ class ZipUtil {
} else {
// is file, put it in the list
var zipPath = '$zipPath/$e';
- while(zipPath.charAt(0) == "/") zipPath = zipPath.substr(1);
+ while(zipPath.charCodeAt(0) == "/".code) zipPath = zipPath.substr(1);
files.push(new StrNameLabel('$path/$e', zipPath));
}
}
diff --git a/source/funkin/editors/character/CharacterInfoScreen.hx b/source/funkin/editors/character/CharacterInfoScreen.hx
index 1d7f313b..bd1c803d 100644
--- a/source/funkin/editors/character/CharacterInfoScreen.hx
+++ b/source/funkin/editors/character/CharacterInfoScreen.hx
@@ -4,13 +4,14 @@ import flixel.math.FlxPoint;
import haxe.xml.Access;
import funkin.game.Character;
import funkin.editors.extra.PropertyButton;
+import funkin.game.HealthIcon;
class CharacterInfoScreen extends UISubstateWindow {
public var character:Character;
public var spriteTextBox:UITextBox;
public var iconTextBox:UITextBox;
- public var iconSprite:FlxSprite;
+ public var iconSprite:HealthIcon;
public var gameOverCharTextBox:UITextBox;
public var antialiasingCheckbox:UICheckbox;
public var flipXCheckbox:UICheckbox;
@@ -147,22 +148,14 @@ class CharacterInfoScreen extends UISubstateWindow {
}
function updateIcon(icon:String) {
- if (iconSprite == null) add(iconSprite = new FlxSprite());
+ if (iconSprite == null) add(iconSprite = new HealthIcon());
- if (iconSprite.animation.exists(icon)) return;
- @:privateAccess iconSprite.animation.clearAnimations();
-
- var path:String = Paths.image('icons/$icon');
- if (!Assets.exists(path)) path = Paths.image('icons/face');
-
- iconSprite.loadGraphic(path, true, 150, 150);
- iconSprite.animation.add(icon, [0], 0, false);
- iconSprite.antialiasing = true;
- iconSprite.animation.play(icon);
-
- iconSprite.scale.set(0.5, 0.5);
+ iconSprite.setIcon(icon);
+ var size = Std.int(150 * 0.5);
+ iconSprite.setUnstretchedGraphicSize(size, size, true);
iconSprite.updateHitbox();
- iconSprite.setPosition(iconTextBox.x + 150 + 8, (iconTextBox.y + 16) - (iconSprite.height/2));
+ iconSprite.setPosition(iconTextBox.x + iconTextBox.bWidth + 8, iconTextBox.y + (iconTextBox.bHeight / 2) - (iconSprite.height / 2));
+ iconSprite.scrollFactor.set(1, 1);
}
function saveCharacterInfo() {
diff --git a/source/funkin/editors/charter/ChartCreationScreen.hx b/source/funkin/editors/charter/ChartCreationScreen.hx
index c89835f9..1fe85e6b 100644
--- a/source/funkin/editors/charter/ChartCreationScreen.hx
+++ b/source/funkin/editors/charter/ChartCreationScreen.hx
@@ -320,7 +320,8 @@ class CompactCharacterButton extends UIButton {
autoAlpha = false;
charIcon = new HealthIcon(funkin.game.Character.getIconFromCharName(char));
- charIcon.scale.set(0.2, 0.2);
+ var size = Std.int(150 * 0.2);
+ charIcon.setUnstretchedGraphicSize(size, size, true);
charIcon.updateHitbox();
charIcon.setPosition(10, bHeight/2 - charIcon.height / 2);
charIcon.scrollFactor.set(1,1);
@@ -332,11 +333,10 @@ class CompactCharacterButton extends UIButton {
textBox.antialiasing = true;
textBox.onChange = function(char:String) {
char = funkin.game.Character.getIconFromCharName(char);
- var image = Paths.image("icons/" + char);
- if(!Assets.exists(image))
- image = Paths.image("icons/face");
- charIcon.loadGraphic(image, true, 150, 150);
+ charIcon.setIcon(char);
+ charIcon.setUnstretchedGraphicSize(size, size, true);
charIcon.updateHitbox();
+ charIcon.setPosition(10, bHeight/2 - charIcon.height / 2);
}
deleteButton = new UIButton(textBox.x + 115 + 16, bHeight/2 - (32/2), "", function () {
diff --git a/source/funkin/editors/charter/CharterMetaDataScreen.hx b/source/funkin/editors/charter/CharterMetaDataScreen.hx
index 4179dfc7..e58898c0 100644
--- a/source/funkin/editors/charter/CharterMetaDataScreen.hx
+++ b/source/funkin/editors/charter/CharterMetaDataScreen.hx
@@ -3,6 +3,7 @@ package funkin.editors.charter;
import flixel.math.FlxPoint;
import funkin.backend.chart.ChartData.ChartMetaData;
import funkin.editors.extra.PropertyButton;
+import funkin.game.HealthIcon;
using StringTools;
@@ -20,7 +21,7 @@ class CharterMetaDataScreen extends UISubstateWindow {
public var displayNameTextBox:UITextBox;
public var iconTextBox:UITextBox;
- public var iconSprite:FlxSprite;
+ public var iconSprite:HealthIcon;
public var opponentModeCheckbox:UICheckbox;
public var coopAllowedCheckbox:UICheckbox;
public var colorWheel:UIColorwheel;
@@ -130,22 +131,14 @@ class CharterMetaDataScreen extends UISubstateWindow {
}
function updateIcon(icon:String) {
- if (iconSprite == null) add(iconSprite = new FlxSprite());
+ if (iconSprite == null) add(iconSprite = new HealthIcon());
- if (iconSprite.animation.exists(icon)) return;
- @:privateAccess iconSprite.animation.clearAnimations();
-
- var path:String = Paths.image('icons/$icon');
- if (!Assets.exists(path)) path = Paths.image('icons/face');
-
- iconSprite.loadGraphic(path, true, 150, 150);
- iconSprite.animation.add(icon, [0], 0, false);
- iconSprite.antialiasing = true;
- iconSprite.animation.play(icon);
-
- iconSprite.scale.set(0.5, 0.5);
+ iconSprite.setIcon(icon);
+ var size = Std.int(150 * 0.5);
+ iconSprite.setUnstretchedGraphicSize(size, size, true);
iconSprite.updateHitbox();
- iconSprite.setPosition(iconTextBox.x + 150 + 8, (iconTextBox.y + 16) - (iconSprite.height/2));
+ iconSprite.setPosition(iconTextBox.x + iconTextBox.bWidth + 8, iconTextBox.y + (iconTextBox.bHeight / 2) - (iconSprite.height / 2));
+ iconSprite.scrollFactor.set(1, 1);
}
public function saveMeta() {
diff --git a/source/funkin/editors/charter/CharterStrumline.hx b/source/funkin/editors/charter/CharterStrumline.hx
index 3850c2fa..cc0bb4be 100644
--- a/source/funkin/editors/charter/CharterStrumline.hx
+++ b/source/funkin/editors/charter/CharterStrumline.hx
@@ -43,20 +43,7 @@ class CharterStrumline extends UISprite {
if(strumLine.visible == null) strumLine.visible = true;
- var icons = strumLine.characters != null ? strumLine.characters : [];
-
healthIcons = new FlxSpriteGroup(x, y);
-
- for (i=>icon in icons) {
- var healthIcon = new HealthIcon(Character.getIconFromCharName(icon));
- healthIcon.scale.x = healthIcon.scale.y = 0.6 - (icons.length / 20);
- healthIcon.updateHitbox();
- healthIcon.x = FlxMath.lerp(0, icons.length * 20, (icons.length-1 != 0 ? i / (icons.length-1) : 0));
- healthIcon.y = draggable ? 29 : 7;
- healthIcon.alpha = strumLine.visible ? 1 : 0.4;
- healthIcons.add(healthIcon);
- }
-
members.push(healthIcons);
draggingSprite = new UISprite();
@@ -70,8 +57,7 @@ class CharterStrumline extends UISprite {
button = new CharterStrumlineOptions(this);
members.push(button);
- vocals = strumLine.vocalsSuffix.length > 0 ? FlxG.sound.load(Paths.voices(PlayState.SONG.meta.name, PlayState.difficulty, strumLine.vocalsSuffix)) : new FlxSound();
- vocals.group = FlxG.sound.defaultMusicGroup;
+ updateInfo();
selectedWaveform = -1;
}
@@ -106,7 +92,9 @@ class CharterStrumline extends UISprite {
for (i=>icon in icons) {
var healthIcon = new HealthIcon(Character.getIconFromCharName(icon));
- healthIcon.scale.x = healthIcon.scale.y = 0.6 - (icons.length / 20);
+ var newScale = 0.6 - (icons.length / 20);
+ var size = Std.int(150 * newScale);
+ healthIcon.setUnstretchedGraphicSize(size, size, true);
healthIcon.updateHitbox();
healthIcon.x = FlxMath.lerp(0, icons.length * 20, (icons.length-1 != 0 ? i / (icons.length-1) : 0));
healthIcon.y = draggable ? 14 : 7;
diff --git a/source/funkin/editors/charter/CharterStrumlineScreen.hx b/source/funkin/editors/charter/CharterStrumlineScreen.hx
index d9298430..fe018979 100644
--- a/source/funkin/editors/charter/CharterStrumlineScreen.hx
+++ b/source/funkin/editors/charter/CharterStrumlineScreen.hx
@@ -194,7 +194,8 @@ class CharacterButton extends UIButton {
super(x, y, "", null, 250, 54);
charIcon = new HealthIcon(Character.getIconFromCharName(char));
- charIcon.scale.set(0.3, 0.3);
+ var size = Std.int(150 * 0.3);
+ charIcon.setUnstretchedGraphicSize(size, size, true);
charIcon.updateHitbox();
charIcon.setPosition(x + 10, bHeight/2 - charIcon.height / 2);
charIcon.scrollFactor.set(1,1);
@@ -206,11 +207,10 @@ class CharacterButton extends UIButton {
textBox.antialiasing = true;
textBox.onChange = function(char:String) {
char = Character.getIconFromCharName(char);
- var image = Paths.image("icons/" + char);
- if(!Assets.exists(image))
- image = Paths.image("icons/face");
- charIcon.loadGraphic(image, true, 150, 150);
+ charIcon.setIcon(char);
+ charIcon.setUnstretchedGraphicSize(size, size, true);
charIcon.updateHitbox();
+ charIcon.setPosition(x + 10, bHeight/2 - charIcon.height / 2);
}
deleteButton = new UIButton(textBox.x + 115 + 16, bHeight/2 - (32/2), "", function () {
diff --git a/source/funkin/editors/charter/SongCreationScreen.hx b/source/funkin/editors/charter/SongCreationScreen.hx
index fdd9cf1e..007c8f6c 100644
--- a/source/funkin/editors/charter/SongCreationScreen.hx
+++ b/source/funkin/editors/charter/SongCreationScreen.hx
@@ -5,6 +5,7 @@ import flixel.text.FlxText.FlxTextFormatMarkerPair;
import flixel.group.FlxGroup;
import funkin.backend.chart.ChartData.ChartMetaData;
import haxe.io.Bytes;
+import funkin.game.HealthIcon;
typedef SongCreationData = {
var meta:ChartMetaData;
@@ -25,7 +26,7 @@ class SongCreationScreen extends UISubstateWindow {
public var displayNameTextBox:UITextBox;
public var iconTextBox:UITextBox;
- public var iconSprite:FlxSprite;
+ public var iconSprite:HealthIcon;
public var opponentModeCheckbox:UICheckbox;
public var coopAllowedCheckbox:UICheckbox;
public var colorWheel:UIColorwheel;
@@ -231,22 +232,14 @@ class SongCreationScreen extends UISubstateWindow {
}
function updateIcon(icon:String) {
- if (iconSprite == null) menuDataGroup.add(iconSprite = new FlxSprite());
+ if (iconSprite == null) menuDataGroup.add(iconSprite = new HealthIcon());
- if (iconSprite.animation.exists(icon)) return;
- @:privateAccess iconSprite.animation.clearAnimations();
-
- var path:String = Paths.image('icons/$icon');
- if (!Assets.exists(path)) path = Paths.image('icons/face');
-
- iconSprite.loadGraphic(path, true, 150, 150);
- iconSprite.animation.add(icon, [0], 0, false);
- iconSprite.antialiasing = true;
- iconSprite.animation.play(icon);
-
- iconSprite.scale.set(0.5, 0.5);
+ iconSprite.setIcon(icon);
+ var size = Std.int(150 * 0.5);
+ iconSprite.setUnstretchedGraphicSize(size, size, true);
iconSprite.updateHitbox();
- iconSprite.setPosition(iconTextBox.x + 150 + 8, (iconTextBox.y + 16) - (iconSprite.height/2));
+ iconSprite.setPosition(iconTextBox.x + iconTextBox.bWidth + 8, iconTextBox.y + (iconTextBox.bHeight / 2) - (iconSprite.height / 2));
+ iconSprite.scrollFactor.set(1, 1);
}
function saveSongInfo() {
diff --git a/source/funkin/game/GameOverSubstate.hx b/source/funkin/game/GameOverSubstate.hx
index 66b37968..70f0a799 100644
--- a/source/funkin/game/GameOverSubstate.hx
+++ b/source/funkin/game/GameOverSubstate.hx
@@ -100,30 +100,8 @@ class GameOverSubstate extends MusicBeatSubstate
if (__cancelDefault)
return;
- if (controls.ACCEPT)
- {
- endBullshit();
- }
-
- if (controls.BACK)
- {
- if (PlayState.chartingMode && Charter.undos.unsaved)
- game.saveWarn(false);
- else {
- PlayState.resetSongInfos();
- if (Charter.instance != null) Charter.instance.__clearStatics();
-
- if (FlxG.sound.music != null)
- FlxG.sound.music.stop();
- FlxG.sound.music = null;
-
- if (PlayState.isStoryMode)
- FlxG.switchState(new StoryMenuState());
- else
- FlxG.switchState(new FreeplayState());
- }
-
- }
+ if (controls.ACCEPT) endBullshit();
+ if (controls.BACK) exit();
if (!isEnding && ((!lossSFX.playing) || (character.getAnimName() == "firstDeath" && character.isAnimFinished())) && (FlxG.sound.music == null || !FlxG.sound.music.playing))
{
@@ -192,6 +170,26 @@ class GameOverSubstate extends MusicBeatSubstate
});
}
+ function exit()
+ {
+ var event = new CancellableEvent();
+ gameoverScript.call('onReturnToMenu', [event]);
+
+ if (event.cancelled)
+ return;
+
+ if (PlayState.chartingMode && Charter.undos.unsaved) game.saveWarn(false);
+ else {
+ PlayState.resetSongInfos();
+ if (Charter.instance != null) Charter.instance.__clearStatics();
+
+ if (FlxG.sound.music != null) FlxG.sound.music.stop();
+ FlxG.sound.music = null;
+
+ FlxG.switchState(PlayState.isStoryMode ? new StoryMenuState() : new FreeplayState());
+ }
+ }
+
override function destroy()
{
gameoverScript.call("destroy");
diff --git a/source/funkin/game/HealthIcon.hx b/source/funkin/game/HealthIcon.hx
index 70f5024b..8c636376 100644
--- a/source/funkin/game/HealthIcon.hx
+++ b/source/funkin/game/HealthIcon.hx
@@ -1,12 +1,31 @@
package funkin.game;
+import flixel.graphics.FlxGraphic;
+import flixel.math.FlxPoint;
+import flixel.util.typeLimit.OneOfTwo;
-class HealthIcon extends FlxSprite
+class HealthIcon extends FunkinSprite
{
/**
- * Used for FreeplayState! If you use it elsewhere, prob gonna annoying
+ * Attaches the icon to a sprite, following it's position
*/
public var sprTracker:FlxSprite;
+ /**
+ * Where to place the icon in relation to the sprite
+ *
+ * LEFT: Left of the sprite
+ *
+ * CENTER: Center of the sprite
+ *
+ * RIGHT: Right of the sprite
+ */
+ public var sprTrackerAlignment:TrackerAlignment = RIGHT;
+ /**
+ * Offset of the icon in relation to the sprite
+ *
+ * By default it is set to (10, -30) and is intended to be used with Alphabet
+ */
+ public var sprTrackerOffset:FlxPoint = new FlxPoint(10, -30);
/**
* The currently showing icon
@@ -20,30 +39,64 @@ class HealthIcon extends FlxSprite
/**
* Health steps in this format:
- * Min Percentage => Frame Index
+ *
+ * Min Percentage => Frame Index / Animation Name
*/
- public var healthSteps:Map = null;
+ public var healthSteps:Map> = null;
+
+ /**
+ * Current animation state
+ */
+ public var curAnimState:OneOfTwo = -1;
+
+ /**
+ * The Default Scale For The Icon
+ *
+ * This is what scale the icon should return to when its bump animation is finished
+ */
+ public var defaultScale:Float = 1;
+
+ /**
+ * Whenever or not the icon is animated or not
+ */
+ public var animated:Bool = false;
+
+ /**
+ * XML Animated Icon data
+ *
+ * `null` if the icon is not animated or its invalid
+ */
+ public var xmlData:Xml;
+
+ /**
+ * Extra offsets to add when updating the hitbox
+ */
+ public var extraOffsets:FlxPoint = FlxPoint.get();
/**
* Helper for HScript who can't make maps
- * @param steps Something like this: `[[0, 1], [20, 0]]`
+ *
+ * THIS IS DEPRECATED AND WILL BE REMOVED IN THE FUTURE
+ *
+ * Please set the healthSteps directly in the script instead, hscript does support maps
+ *
+ * @param steps Something like this: `[[0, 1], [20, 0]]` or `[[0, "losing"], [20, "neutral"]]` for animated icons
*/
- public function setHealthSteps(steps:Array>) { // helper for hscript that can't do maps
+ @:dox(hide) @:noCompletion @:deprecated("use healthSteps instead")
+ public function setHealthSteps(steps:Array>>):Void { // helper for hscript that can't do maps
if (steps == null) return;
healthSteps = [];
- for(s in steps)
+ for (s in steps)
if (s.length > 1)
healthSteps[s[0]] = s[1];
- var am = 0;
- for(k=>e in healthSteps) am++;
- if (am <= 0) healthSteps = [
- 0 => 1, // losing icon
- 20 => 0, // normal icon
+ if (Lambda.count(healthSteps) <= 0) healthSteps = [
+ 0 => (this.animated ? "losing" : 1), // losing icon
+ 20 => (this.animated ? "neutral" : 0), // normal icon
];
}
- public function new(char:String = 'bf', isPlayer:Bool = false)
+ public function new(?char:String, isPlayer:Bool = false)
{
super();
health = 0.5;
@@ -53,44 +106,334 @@ class HealthIcon extends FlxSprite
scrollFactor.set();
}
- public function setIcon(char:String, width:Int = 150, height:Int = 150) {
- if(curCharacter != char || this.width != width || this.height != height) {
- curCharacter = char;
- var path = Paths.image('icons/$char');
- if (!Assets.exists(path)) path = Paths.image('icons/face');
-
- loadGraphic(path, true, width, height);
-
- animation.add(char, [for(i in 0...frames.frames.length) i], 0, false, isPlayer);
- antialiasing = true;
- animation.play(char);
-
- healthSteps = [
- 0 => 1, // losing icon
- 20 => 0, // normal icon
- ];
-
- if (frames.frames.length >= 3)
- healthSteps[80] = 2; // winning icon
- }
+ /**
+ * Called every beat, and causes the icon to become bigger
+ **/
+ public dynamic function bump():Void {
+ var iconScale = 1.2;
+ scale.set(defaultScale * iconScale, defaultScale * iconScale);
+ updateHitbox();
}
- override function update(elapsed:Float)
- {
- super.update(elapsed);
+ /**
+ * Called every frame and causes the icon to become smaller
+ **/
+ public dynamic function updateBump():Void {
+ var iconLerp = 0.33;
+ scale.set(CoolUtil.fpsLerp(scale.x, defaultScale, iconLerp), CoolUtil.fpsLerp(scale.y, defaultScale, iconLerp));
+ updateHitbox();
+ }
- if (sprTracker != null)
- setPosition(sprTracker.x + sprTracker.width + 10, sprTracker.y - 30);
+ /**
+ * Sets the icon to the specified character
+ * @param char Character to set the icon to
+ * @param allowAnimated Whenever the icon can be animated
+ **/
+ public function setIcon(char:String, allowAnimated:Bool = true):Void {
+ if (curCharacter == char) return;
- if (animation.curAnim != null) {
- var i:Int = -1;
- var oldKey:Int = -1;
- for (k=>icon in healthSteps) if (k > oldKey && k <= health * 100) {
- oldKey = k;
- i = icon;
+ var oldIconPath = 'icons/$char';
+ var newIconPath = 'icons/$char/icon';
+
+ if (!Assets.exists(Paths.image(oldIconPath)) && !Assets.exists(Paths.image(newIconPath))) {
+ char = 'face';
+ oldIconPath = 'icons/$char';
+ newIconPath = 'icons/$char/icon';
+ }
+ curCharacter = char;
+
+ var iconPath = Assets.exists(Paths.image(oldIconPath)) ? oldIconPath : newIconPath;
+ var iconXmlPath = Paths.getPath('images/icons/$char/data.xml');
+ var iconFoundData = Assets.exists(iconXmlPath);
+
+ try {
+ xmlData = iconFoundData ? Xml.parse(Assets.getText(iconXmlPath)) : null;
+ } catch(e) {
+ Logs.trace('Error while parsing icon data for $char: ${e.message}', ERROR);
+ xmlData = null;
+ }
+ var xmlValid = xmlData != null && (xmlData = xmlData.firstElement()) != null;
+
+ this.animated = allowAnimated && iconFoundData && xmlValid && Paths.framesExists(Paths.image(newIconPath), true, true, true);
+
+ var iconAmt:Int = 0;
+ var iconSize:Int = 0;
+ var iconIsPlayer = xmlValid ? xmlData.get("facing").getDefault("right").toLowerCase() == "left" : false;
+
+ animateAtlas = null; // reset
+ if (this.animated)
+ loadSprite(Paths.image(newIconPath));
+ else {
+ var iconAsset:FlxGraphic = FlxG.bitmap.add(Paths.image(iconPath));
+ var assetW:Float = iconAsset.width;
+ var assetH:Float = iconAsset.height;
+
+ iconAmt = Math.round(assetW / assetH); // Just in case the icon is in a weird aspect ratio
+ iconSize = Math.floor(assetW / iconAmt);
+ if (iconSize * iconAmt > assetW) {
+ iconSize = Math.floor(assetW / iconAmt);
+ iconAmt = Math.floor(assetW / iconSize);
}
- if (i >= 0) animation.curAnim.curFrame = i;
+ loadGraphic(iconAsset, true, Std.int(Math.min(iconSize, assetW)), Std.int(Math.min(iconSize, assetH)));
+
+ setGraphicSize(150);
+ updateHitbox();
+
+ animation.add(char, [for(i in 0...iconAmt) i], 0, false, isPlayer != iconIsPlayer);
+ animation.play(char);
+ }
+
+ if(!animation.onFinishEnd.has(animFinishCallback))
+ animation.onFinishEnd.add(animFinishCallback);
+ if(animateAtlas != null && !animateAtlas.anim.onFinishEnd.has(animFinishCallback))
+ animateAtlas.anim.onFinishEnd.add(animFinishCallback);
+
+ var parsedSteps:Map = [];
+
+ antialiasing = true;
+ if (xmlValid) {
+ if (xmlData.exists("antialiasing"))
+ antialiasing = xmlData.get("antialiasing").toLowerCase() == "true";
+ if (xmlData.exists("offsetX"))
+ extraOffsets.x = Std.parseFloat(xmlData.get("offsetX")).getDefault(0);
+ if (xmlData.exists("offsetY"))
+ extraOffsets.y = Std.parseFloat(xmlData.get("offsetY")).getDefault(0);
+
+ for (node in xmlData.elements())
+ switch(node.nodeName) {
+ case "transition":
+ if (this.animated == false) {
+ Logs.trace('Icon ${char} data is not allowed when not animated', WARNING);
+ continue;
+ }
+ if (!node.exists("anim")) {
+ Logs.trace('Icon ${char} data is missing anim', WARNING);
+ continue;
+ }
+ if (!node.exists("to")) {
+ Logs.trace('Icon ${char} data is missing to', WARNING);
+ continue;
+ }
+ if (!node.exists("from")) {
+ Logs.trace('Icon ${char} data is missing from', WARNING);
+ continue;
+ }
+
+ var animName = 'from-${node.get("from")}-to-${node.get("to")}';
+ if (node.exists("offsetX") || node.exists("offsetY"))
+ addOffset(animName, Std.parseFloat(node.get("offsetX")).getDefault(0), Std.parseFloat(node.get("offsetY")).getDefault(0));
+ addAnim(animName, node.get("anim"), Std.parseInt(node.get("fps")).getDefault(24), false); // don't allow looping for transitions
+ if (animateAtlas == null && animation.exists(animName))
+ animation.getByName(animName).flipX = isPlayer != iconIsPlayer;
+ case "anim":
+ if (this.animated == false) {
+ Logs.trace('Icon ${char} data is not allowed when not animated', WARNING);
+ continue;
+ }
+ if (!node.exists("name")) {
+ Logs.trace('Icon ${char} data is missing name', WARNING);
+ continue;
+ }
+ if (!node.exists("anim")) {
+ Logs.trace('Icon ${char} data is missing anim', WARNING);
+ continue;
+ }
+
+ var animName = node.get("name");
+
+ var offsetX:Float = 0;
+ var offsetY:Float = 0;
+ if (node.exists("offsetX"))
+ offsetX = Std.parseFloat(node.get("offsetX")).getDefault(0);
+ else if (node.exists("offsetx"))
+ offsetX = Std.parseFloat(node.get("offsetx")).getDefault(0);
+
+ if (node.exists("offsetY"))
+ offsetY = Std.parseFloat(node.get("offsetY")).getDefault(0);
+ else if (node.exists("offsety"))
+ offsetY = Std.parseFloat(node.get("offsety")).getDefault(0);
+
+ addOffset(animName, offsetX, offsetY);
+
+ addAnim(animName, node.get("anim"), Std.parseInt(node.get("fps")).getDefault(24), node.get("looped").getDefault("true").toLowerCase() == "true");
+ if (animateAtlas == null && animation.exists(animName))
+ animation.getByName(animName).flipX = isPlayer != iconIsPlayer;
+ case "step":
+ if (!node.exists("percent")) {
+ Logs.trace('Icon ${char} data is missing percent', WARNING);
+ continue;
+ }
+ if (!node.exists("name")) {
+ Logs.trace('Icon ${char} data is missing name', WARNING);
+ continue;
+ }
+
+ parsedSteps.set(Std.parseInt(node.get("percent")).getDefault(0), node.get("name"));
+ }
+ }
+
+ if (Lambda.count(parsedSteps) > 0) {
+ healthSteps = parsedSteps;
+ } else {
+ var hasLosing = this.animated ? hasAnim("losing") : iconAmt >= 2;
+ var hasWinning = this.animated ? hasAnim("winning") : iconAmt >= 3;
+
+ if (hasLosing) {
+ healthSteps = [
+ 0 => (this.animated ? "losing" : 1), // losing icon
+ 20 => (this.animated ? "neutral" : 0), // normal icon
+ ];
+ } else {
+ healthSteps = [
+ 0 => (this.animated ? "neutral" : 0), // normal icon
+ ];
+ }
+ if (hasWinning)
+ healthSteps.set(80, this.animated ? "winning" : 2); // winning icon
+ }
+ var data = getIconAnim(health);
+ if (data.isValid) {
+ if (this.animated)
+ playAnim(data.animState);
+ else
+ animation.curAnim.curFrame = data.animState;
+ curAnimState = data.animState;
+ }
+
+ if (animateAtlas != null) {
+ @:bypassAccessor
+ frameWidth = 150;
+ @:bypassAccessor
+ frameHeight = 150;
+ extraOffsets.x -= frameWidth / 2;
+ extraOffsets.y -= frameHeight / 2;
+ updateHitbox();
+ } else {
+ setGraphicSize(150);
+ updateHitbox();
+ }
+
+ defaultScale = (xmlValid && xmlData.exists("scale")) ? Std.parseFloat(xmlData.get("scale")).getDefault(scale.x) : scale.x;
+ scale.set(defaultScale, defaultScale);
+ updateHitbox();
+ }
+
+ var normalizedNames = ["neutral", "losing", "winning"];
+ private function normalizeAnim(anim:OneOfTwo):OneOfTwo {
+ if(this.animated) {
+ if (anim is Int) {
+ var _:Int = cast anim;
+ if(_ >= 0 && _ < normalizedNames.length)
+ anim = normalizedNames[anim];
+ }
+ } else {
+ if (anim is String) {
+ var _ = normalizedNames.indexOf(cast anim);
+ if(_ >= 0)
+ anim = _;
+ }
+ }
+ return anim;
+ }
+
+ /**
+ * Gets the animation data for a specific health percentage
+ * @param health Health percentage
+ * @return Animation data (-1 if invalid)
+ */
+ public dynamic function getIconAnim(health:Float):IconAnimData {
+ var i:OneOfTwo = -1;
+ var oldKey:Int = -1;
+ var isValid = false;
+ for (k=>icon in healthSteps) if (k > oldKey && k <= health * 100) {
+ oldKey = k;
+ i = icon;
+ isValid = true;
+ }
+
+ i = normalizeAnim(i);
+
+ return new IconAnimData(i, isValid);
+ }
+
+ override function update(elapsed:Float):Void {
+ super.update(elapsed);
+
+ if (sprTracker != null) {
+ setPosition(sprTracker.x + (switch sprTrackerAlignment {
+ case LEFT: -width;
+ case CENTER: (sprTracker.width - width) / 2;
+ case RIGHT: sprTracker.width;
+ }) + sprTrackerOffset.x, sprTracker.y + sprTrackerOffset.y);
+ }
+
+ if (animation.curAnim != null || (this.animated && animateAtlas != null)) {
+ var data = getIconAnim(health);
+ var localAnimState = data.animState;
+
+ if (data.isValid && curAnimState != localAnimState) {
+ if (this.animated) {
+ var transAnim = 'from-$curAnimState-to-$localAnimState';
+ playAnim(hasAnim(transAnim) ? transAnim : localAnimState);
+ } else {
+ if(animation.curAnim != null)
+ animation.curAnim.curFrame = localAnimState;
+ }
+
+ curAnimState = localAnimState;
+ }
}
}
+
+ function animFinishCallback(anim:String):Void {
+ if (this.animated)
+ if (anim.startsWith("from-"))
+ playAnim(anim.substr(anim.lastIndexOf('-') + 1));
+ }
+
+ override function updateHitbox():Void {
+ super.updateHitbox();
+ offset += extraOffsets;
+ }
}
+
+@:dox(hide)
+class IconAnimData {
+ public var animState:OneOfTwo;
+ public var isValid:Bool;
+
+ public function new(animState:OneOfTwo, isValid:Bool) {
+ this.animState = animState;
+ this.isValid = isValid;
+ }
+
+ public function toString():String {
+ return '$animState (Valid: $isValid)';
+ }
+}
+
+/**
+ * Used for `funkin.game.HealthIcon.sprTrackerAlignment`.
+ * This determines the position of the icon in relation to the sprite tracker.
+**/
+enum abstract TrackerAlignment(Int) {
+ /**
+ * Left of the sprite tracker
+ *
+ * Mathematically: `tracker.x - icon.width`
+ */
+ var LEFT = 0;
+ /**
+ * Center of the sprite tracker
+ *
+ * Mathematically: `tracker.x + (tracker.width - icon.width) / 2`
+ */
+ var CENTER = 1;
+ /**
+ * Right of the sprite tracker
+ *
+ * Mathematically: `tracker.x + tracker.width`
+ */
+ var RIGHT = 2;
+}
\ No newline at end of file
diff --git a/source/funkin/game/Note.hx b/source/funkin/game/Note.hx
index 9b06fc81..b8dd5e10 100644
--- a/source/funkin/game/Note.hx
+++ b/source/funkin/game/Note.hx
@@ -75,6 +75,11 @@ class Note extends FlxSprite
public var scrollSpeed:Null = null;
public var noteAngle:Null = null;
+ public var copyStrumAngle:Bool = true;
+ public var updateNotesPosX:Bool = true;
+ public var updateNotesPosY:Bool = true;
+ public var updateFlipY:Bool = true;
+
public var noteType(get, null):String;
@:dox(hide) public var __strumCameras:Array = null;
@@ -215,7 +220,7 @@ class Note extends FlxSprite
override function drawComplex(camera:FlxCamera) {
var downscrollCam = (camera is HudCamera ? cast(camera, HudCamera).downscroll : false);
- flipY = (isSustainNote && flipSustain) && (downscrollCam != (__strum != null && __strum.getScrollSpeed(this) < 0));
+ if (updateFlipY) flipY = (isSustainNote && flipSustain) && (downscrollCam != (__strum != null && __strum.getScrollSpeed(this) < 0));
if (downscrollCam) {
frameOffset.y += __notePosFrameOffset.y * 2;
super.drawComplex(camera);
diff --git a/source/funkin/game/PlayState.hx b/source/funkin/game/PlayState.hx
index 810120dd..870c7d3d 100644
--- a/source/funkin/game/PlayState.hx
+++ b/source/funkin/game/PlayState.hx
@@ -303,6 +303,11 @@ class PlayState extends MusicBeatState
* Opponent's icon
*/
public var iconP2:HealthIcon;
+ /**
+ * Every active icon that will be updated during gameplay (defaults to `iconP1` and `iconP1` between `create` and `postCreate` in scripts)
+ */
+ public var iconArray:Array = [];
+
/**
* Camera for the HUD (notes, misses).
*/
@@ -531,10 +536,10 @@ class PlayState extends MusicBeatState
*/
public function updateRating() {
var rating = null;
- var acc = get_accuracy();
+ var acc = accuracy; // caching since it has a getter with an operation - Nex
- for(e in comboRatings)
- if (e.percent <= acc && (rating == null || rating.percent < e.percent))
+ if (comboRatings != null && comboRatings.length > 0) for (e in comboRatings)
+ if ((e.percent <= acc && e.maxMisses >= misses) && (rating == null || (rating.percent < e.percent && e.maxMisses >= misses)))
rating = e;
var event = scripts.event("onRatingUpdate", EventManager.get(RatingUpdateEvent).recycle(rating, curRating));
@@ -618,10 +623,11 @@ class PlayState extends MusicBeatState
// case "":
// ADD YOUR HARDCODED SCRIPTS HERE!
default:
- var scriptsFolders:Array = ['songs/${SONG.meta.name.toLowerCase()}/scripts', 'data/charts/', 'songs/'];
+ var normal = 'songs/${SONG.meta.name.toLowerCase()}/scripts';
+ var scriptsFolders:Array = [normal, normal + '/$difficulty/', 'data/charts/', 'songs/'];
- for(folder in scriptsFolders) {
- for(file in Paths.getFolderContent(folder, true, fromMods ? MODS : BOTH)) {
+ for (folder in scriptsFolders) {
+ for (file in Paths.getFolderContent(folder, true, fromMods ? MODS : BOTH)) {
if (folder == 'data/charts/')
Logs.trace('data/charts/ is deprecrated and will be removed in the future. Please move script $file to songs/', WARNING, DARKYELLOW);
@@ -682,7 +688,7 @@ class PlayState extends MusicBeatState
case 2: "girlfriend";
}) : strumLine.position;
if (strumLine.characters != null) for(k=>charName in strumLine.characters) {
- var char = new Character(0, 0, charName, stage.isCharFlipped(charPosName, strumLine.type == 1));
+ var char = new Character(0, 0, charName, stage.isCharFlipped(stage.characterPoses[charName] != null ? charName : charPosName, strumLine.type == 1));
stage.applyCharStuff(char, charPosName, k);
chars.push(char);
}
@@ -758,9 +764,9 @@ class PlayState extends MusicBeatState
health = maxHealth / 2;
- iconP1 = new HealthIcon(boyfriend != null ? boyfriend.getIcon() : "face", true);
- iconP2 = new HealthIcon(dad != null ? dad.getIcon() : "face", false);
- for(icon in [iconP1, iconP2]) {
+ iconArray.push(iconP1 = new HealthIcon(boyfriend != null ? boyfriend.getIcon() : "face", true));
+ iconArray.push(iconP2 = new HealthIcon(dad != null ? dad.getIcon() : "face", false));
+ for (icon in iconArray) {
icon.y = healthBar.y - (icon.height / 2);
add(icon);
}
@@ -777,7 +783,8 @@ class PlayState extends MusicBeatState
scoreTxt.alignment = RIGHT;
missesTxt.alignment = CENTER;
accuracyTxt.alignment = LEFT;
- updateRatingStuff();
+ if (updateRatingStuff != null)
+ updateRatingStuff();
for(e in [healthBar, healthBarBG, iconP1, iconP2, scoreTxt, missesTxt, accuracyTxt])
e.cameras = [camHUD];
@@ -817,7 +824,8 @@ class PlayState extends MusicBeatState
// Make icons appear in the correct spot during cutscenes
healthBar.update(0);
- updateIconPositions();
+ if (updateIconPositions != null)
+ updateIconPositions();
__updateNote_event = EventManager.get(NoteUpdateEvent);
@@ -1217,21 +1225,22 @@ class PlayState extends MusicBeatState
]));
}
- function updateIconPositions() {
+ dynamic function updateIconPositions() {
var iconOffset:Int = 26;
+ var healthBarPercent = healthBar.percent;
- var center:Float = healthBar.x + healthBar.width * FlxMath.remapToRange(healthBar.percent, 0, 100, 1, 0);
+ var center:Float = healthBar.x + healthBar.width * FlxMath.remapToRange(healthBarPercent, 0, 100, 1, 0);
iconP1.x = center - iconOffset;
iconP2.x = center - (iconP2.width - iconOffset);
health = FlxMath.bound(health, 0, maxHealth);
- iconP1.health = healthBar.percent / 100;
- iconP2.health = 1 - (healthBar.percent / 100);
+ iconP1.health = healthBarPercent / 100;
+ iconP2.health = 1 - (healthBarPercent / 100);
}
- function updateRatingStuff() {
+ dynamic function updateRatingStuff() {
scoreTxt.text = 'Score:$songScore';
missesTxt.text = '${comboBreaks ? "Combo Breaks" : "Misses"}:$misses';
@@ -1261,10 +1270,8 @@ class PlayState extends MusicBeatState
return;
}
- updateRatingStuff();
-
- if (controls.PAUSE && startedCountdown && canPause)
- pauseGame();
+ if (updateRatingStuff != null)
+ updateRatingStuff();
if (canAccessDebugMenus) {
if (chartingMode && FlxG.keys.justPressed.SEVEN) {
@@ -1277,26 +1284,31 @@ class PlayState extends MusicBeatState
}
}
- if (doIconBop) {
- iconP1.scale.set(lerp(iconP1.scale.x, 1, 0.33), lerp(iconP1.scale.y, 1, 0.33));
- iconP2.scale.set(lerp(iconP2.scale.x, 1, 0.33), lerp(iconP2.scale.y, 1, 0.33));
+ if (doIconBop)
+ for (icon in iconArray)
+ if (icon.updateBump != null)
+ icon.updateBump();
- iconP1.updateHitbox();
- iconP2.updateHitbox();
- }
- updateIconPositions();
+ if (updateIconPositions != null)
+ updateIconPositions();
- if (startingSong)
- {
- if (startedCountdown)
- {
+ if (startingSong) {
+ if (startedCountdown) {
Conductor.songPosition += Conductor.songOffset + elapsed * 1000;
if (Conductor.songPosition >= 0)
startSong();
}
} else if (FlxG.sound.music != null) {
var instTime = FlxG.sound.music.time;
- var isOffsync = vocals.time != instTime || [for(strumLine in strumLines.members) strumLine.vocals.time != instTime].contains(true);
+ var isOffsync:Bool = vocals.time != instTime;
+ if(!isOffsync) {
+ for(strumLine in strumLines.members) {
+ if(strumLine.vocals.time != instTime) {
+ isOffsync = true;
+ break;
+ }
+ }
+ }
__vocalOffsetViolation = Math.max(0, __vocalOffsetViolation + (isOffsync ? elapsed : -elapsed / 2));
if (__vocalOffsetViolation > 25) {
resyncVocals();
@@ -1307,31 +1319,20 @@ class PlayState extends MusicBeatState
while(events.length > 0 && events.last().time <= Conductor.songPosition)
executeEvent(events.pop());
- if (generatedMusic && strumLines.members[curCameraTarget] != null)
- {
- var pos = FlxPoint.get();
- var r = 0;
- for(c in strumLines.members[curCameraTarget].characters) {
- if (c == null || !c.visible) continue;
- var cpos = c.getCameraPosition();
- pos.x += cpos.x;
- pos.y += cpos.y;
- r++;
- //cpos.put();
- }
- if (r > 0) {
- pos.x /= r;
- pos.y /= r;
+ if (controls.PAUSE && startedCountdown && canPause)
+ pauseGame();
- var event = scripts.event("onCameraMove", EventManager.get(CamMoveEvent).recycle(pos, strumLines.members[curCameraTarget], r));
+ if (generatedMusic && strumLines.members[curCameraTarget] != null) {
+ var data:CamPosData = getStrumlineCamPos(curCameraTarget);
+ if (data.amount > 0) {
+ var event = scripts.event("onCameraMove", EventManager.get(CamMoveEvent).recycle(data.pos, strumLines.members[curCameraTarget], data.amount));
if (!event.cancelled)
- camFollow.setPosition(pos.x, pos.y);
+ camFollow.setPosition(event.position.x, event.position.y);
}
- pos.put();
+ data.put();
}
- if (camZooming)
- {
+ if (camZooming) {
FlxG.camera.zoom = lerp(FlxG.camera.zoom, defaultCamZoom, camGameZoomLerp);
camHUD.zoom = lerp(camHUD.zoom, defaultHudZoom, camHUDZoomLerp);
}
@@ -1365,6 +1366,41 @@ class PlayState extends MusicBeatState
scripts.event("postDraw", e);
}
+ /**
+ * Returns the camera position of the specified strumline.
+ * @param strumLine The strumline to get the camera position of.
+ * @param pos The position to put the camera position in. If `null`, a new FlxPoint will be created.
+ * @param ignoreInvisible Whenever invisible characters should be ignored.
+ **/
+ public inline function getStrumlineCamPos(strumLine:Int, ?pos:FlxPoint = null, ?ignoreInvisible:Bool = true):CamPosData {
+ return getCharactersCamPos(strumLines.members[strumLine].characters, pos, ignoreInvisible);
+ }
+
+ /**
+ * Returns the camera position of the specified characters.
+ * @param chars The characters to get the camera position of.
+ * @param pos The position to put the camera position in. If `null`, a new FlxPoint will be created.
+ * @param ignoreInvisible Whenever invisible characters should be ignored.
+ **/
+ public function getCharactersCamPos(chars:Array, ?pos:FlxPoint = null, ?ignoreInvisible:Bool = true):CamPosData {
+ if (pos == null) pos = FlxPoint.get();
+ var amount = 0;
+ for(c in chars) {
+ if (c == null || (ignoreInvisible && !c.visible)) continue;
+ var cpos = c.getCameraPosition();
+ pos.x += cpos.x;
+ pos.y += cpos.y;
+ amount++;
+ //cpos.put(); // not actually in the pool, so no need
+ }
+ if (amount > 0) {
+ pos.x /= amount;
+ pos.y /= amount;
+ }
+ return new CamPosData(pos, amount);
+ }
+
+
public var scrollSpeedTween:FlxTween = null;
public function executeEvent(event:ChartEvent) @:privateAccess {
@@ -1375,7 +1411,27 @@ class PlayState extends MusicBeatState
switch(event.name) {
case "HScript Call":
- scripts.call(event.params[0], event.params[1].split(','));
+ var scriptPacks:Array = [scripts, stateScripts];
+ for (strLine in strumLines.members) for (char in strLine.characters) scriptPacks.push(char.scripts);
+ var args:Array = event.params[1].split(',');
+
+ for (pack in scriptPacks) {
+ pack.call(event.params[0], args);
+ //public functions
+ if (pack.publicVariables.exists(event.params[0])) {
+ var func = pack.publicVariables.get(event.params[0]);
+ if (func != null && Reflect.isFunction(func))
+ Reflect.callMethod(null, func, args);
+ }
+ }
+
+ //static functions
+ if (Script.staticVariables.exists(event.params[0])) {
+ var func = Script.staticVariables.get(event.params[0]);
+ if (func != null && Reflect.isFunction(func))
+ Reflect.callMethod(null, func, args);
+ }
+
case "Camera Movement":
curCameraTarget = event.params[0];
case "Add Camera Zoom":
@@ -1674,9 +1730,9 @@ class PlayState extends MusicBeatState
var event:NoteHitEvent;
if (strumLine != null && !strumLine.cpu)
- event = EventManager.get(NoteHitEvent).recycle(false, !note.isSustainNote, !note.isSustainNote, null, defaultDisplayRating, defaultDisplayCombo, note, strumLine.characters, true, note.noteType, note.animSuffix.getDefault(note.strumID < strumLine.members.length ? strumLine.members[note.strumID].animSuffix : strumLine.animSuffix), "game/score/", "", note.strumID, score, note.isSustainNote ? null : accuracy, 0.023, daRating, Options.splashesEnabled && !note.isSustainNote && daRating == "sick");
+ event = EventManager.get(NoteHitEvent).recycle(false, !note.isSustainNote, !note.isSustainNote, null, defaultDisplayRating, defaultDisplayCombo, note, strumLine.characters, true, note.noteType, note.animSuffix.getDefault(note.strumID < strumLine.members.length ? strumLine.members[note.strumID].animSuffix : strumLine.animSuffix), "game/score/", "", note.strumID, score, note.isSustainNote ? null : accuracy, 0.023, daRating, Options.splashesEnabled && !note.isSustainNote && daRating == "sick", 0.5, true, 0.7, true, true, iconP1);
else
- event = EventManager.get(NoteHitEvent).recycle(false, false, false, null, defaultDisplayRating, defaultDisplayCombo, note, strumLine.characters, false, note.noteType, note.animSuffix.getDefault(note.strumID < strumLine.members.length ? strumLine.members[note.strumID].animSuffix : strumLine.animSuffix), "game/score/", "", note.strumID, 0, null, 0, daRating, false);
+ event = EventManager.get(NoteHitEvent).recycle(false, false, false, null, defaultDisplayRating, defaultDisplayCombo, note, strumLine.characters, false, note.noteType, note.animSuffix.getDefault(note.strumID < strumLine.members.length ? strumLine.members[note.strumID].animSuffix : strumLine.animSuffix), "game/score/", "", note.strumID, 0, null, 0, daRating, false, 0.5, true, 0.7, true, true, iconP2);
event.deleteNote = !note.isSustainNote; // work around, to allow sustain notes to be deleted
event = scripts.event(strumLine != null && !strumLine.cpu ? "onPlayerHit" : "onDadHit", event);
strumLine.onHit.dispatch(event);
@@ -1836,14 +1892,10 @@ class PlayState extends MusicBeatState
camHUD.zoom += 0.03 * camZoomingStrength;
}
- if (doIconBop)
- {
- iconP1.scale.set(1.2, 1.2);
- iconP2.scale.set(1.2, 1.2);
-
- iconP1.updateHitbox();
- iconP2.updateHitbox();
- }
+ if (doIconBop)
+ for (icon in iconArray)
+ if (icon.bump != null)
+ icon.bump();
scripts.call("beatHit", [curBeat]);
}
@@ -1962,8 +2014,10 @@ final class ComboRating {
public var percent:Float;
public var rating:String;
public var color:FlxColor;
+ public var maxMisses:Float; // Float since it could be Math.POSITIVE_INFINITY - Nex
- public function new(percent:Float, rating:String, color:FlxColor) {
+ public function new(?percent:Float, ?rating:String, ?color:FlxColor, ?misses:Float) {
+ maxMisses = misses == null || Math.isNaN(misses) ? Math.POSITIVE_INFINITY : misses;
this.percent = percent;
this.rating = rating;
this.color = color;
@@ -1978,3 +2032,28 @@ typedef PlayStateTransitionData = {
var camFollowY:Float;
var camZoom:Float;
}
+
+class CamPosData {
+ /**
+ * The camera position.
+ **/
+ public var pos:FlxPoint;
+ /**
+ * The amount of characters that was involved in the calculation.
+ **/
+ public var amount:Int;
+
+ public function new(pos:FlxPoint, amount:Int) {
+ this.pos = pos;
+ this.amount = amount;
+ }
+
+ /**
+ * Puts the position back into the pool, making it reusable.
+ **/
+ public function put() {
+ if(pos == null) return;
+ pos.put();
+ pos = null;
+ }
+}
\ No newline at end of file
diff --git a/source/funkin/game/Strum.hx b/source/funkin/game/Strum.hx
index cbce2da4..d4a5cdb4 100644
--- a/source/funkin/game/Strum.hx
+++ b/source/funkin/game/Strum.hx
@@ -19,6 +19,18 @@ class Strum extends FlxSprite {
public var lastDrawCameras(default, null):Array = [];
+ // Copy fields
+ public var copyStrumCamera:Bool = true;
+ public var copyStrumScrollX:Bool = true;
+ public var copyStrumScrollY:Bool = true;
+ public var copyStrumAngle:Bool = true;
+ public var updateNotesPosX:Bool = true;
+ public var updateNotesPosY:Bool = true;
+ public var extraCopyFields(default, set):Array = [];
+
+ private inline function set_extraCopyFields(val:Array)
+ return extraCopyFields = val == null ? [] : val;
+
public var getPressed:StrumLine->Bool = null;
public var getJustPressed:StrumLine->Bool = null;
public var getJustReleased:StrumLine->Bool = null;
@@ -84,47 +96,61 @@ class Strum extends FlxSprite {
public function updateNotePosition(daNote:Note) {
if (!daNote.exists) return;
- daNote.__strumCameras = lastDrawCameras;
daNote.__strum = this;
- daNote.scrollFactor.set(scrollFactor.x, scrollFactor.y);
- daNote.__noteAngle = getNotesAngle(daNote);
- daNote.angle = daNote.isSustainNote ? daNote.__noteAngle : angle;
+ if (copyStrumCamera) daNote.__strumCameras = lastDrawCameras;
+ if (copyStrumScrollX) daNote.scrollFactor.x = scrollFactor.x;
+ if (copyStrumScrollY) daNote.scrollFactor.y = scrollFactor.y;
+ if (copyStrumAngle && daNote.copyStrumAngle) {
+ daNote.__noteAngle = getNotesAngle(daNote);
+ daNote.angle = daNote.isSustainNote ? daNote.__noteAngle : angle;
+ }
updateNotePos(daNote);
+ for (field in extraCopyFields)
+ CoolUtil.cloneProperty(daNote, field, this); // TODO: make this cached to reduce the reflection calls - Neo
}
private inline function updateNotePos(daNote:Note) {
- if (daNote.strumRelativePos) {
- daNote.setPosition((this.width - daNote.width) / 2, (daNote.strumTime - Conductor.songPosition) * (0.45 * CoolUtil.quantize(getScrollSpeed(daNote), 100)));
- if (daNote.isSustainNote) daNote.y += N_WIDTHDIV2;
- } else {
- var offset = FlxPoint.get(0, (Conductor.songPosition - daNote.strumTime) * (0.45 * CoolUtil.quantize(getScrollSpeed(daNote), 100)));
- var realOffset = FlxPoint.get(0, 0);
+ var shouldX = updateNotesPosX && daNote.updateNotesPosX;
+ var shouldY = updateNotesPosY && daNote.updateNotesPosY;
- if (daNote.isSustainNote) offset.y -= N_WIDTHDIV2;
-
- if (Std.int(daNote.__noteAngle % 360) != 0) {
- var noteAngleCos = FlxMath.fastCos(daNote.__noteAngle / PIX180);
- var noteAngleSin = FlxMath.fastSin(daNote.__noteAngle / PIX180);
-
- var aOffset:FlxPoint = FlxPoint.get(
- (daNote.origin.x / daNote.scale.x) - daNote.offset.x,
- (daNote.origin.y / daNote.scale.y) - daNote.offset.y
- );
- realOffset.x = -aOffset.x + (noteAngleCos * (offset.x + aOffset.x)) + (noteAngleSin * (offset.y + aOffset.y));
- realOffset.y = -aOffset.y + (noteAngleSin * (offset.x + aOffset.x)) + (noteAngleCos * (offset.y + aOffset.y));
-
- aOffset.put();
+ if (shouldX || shouldY) {
+ if (daNote.strumRelativePos) {
+ if (shouldX) daNote.x = (this.width - daNote.width) / 2;
+ if (shouldY) {
+ daNote.y = (daNote.strumTime - Conductor.songPosition) * (0.45 * CoolUtil.quantize(getScrollSpeed(daNote), 100));
+ if (daNote.isSustainNote) daNote.y += N_WIDTHDIV2;
+ }
} else {
- realOffset.x = offset.x;
- realOffset.y = offset.y;
+ var offset = FlxPoint.get(0, (Conductor.songPosition - daNote.strumTime) * (0.45 * CoolUtil.quantize(getScrollSpeed(daNote), 100)));
+ var realOffset = FlxPoint.get(0, 0);
+
+ if (daNote.isSustainNote) offset.y -= N_WIDTHDIV2;
+
+ if (Std.int(daNote.__noteAngle % 360) != 0) {
+ var noteAngleCos = FlxMath.fastCos(daNote.__noteAngle / PIX180);
+ var noteAngleSin = FlxMath.fastSin(daNote.__noteAngle / PIX180);
+
+ var aOffset:FlxPoint = FlxPoint.get(
+ (daNote.origin.x / daNote.scale.x) - daNote.offset.x,
+ (daNote.origin.y / daNote.scale.y) - daNote.offset.y
+ );
+ realOffset.x = -aOffset.x + (noteAngleCos * (offset.x + aOffset.x)) + (noteAngleSin * (offset.y + aOffset.y));
+ realOffset.y = -aOffset.y + (noteAngleSin * (offset.x + aOffset.x)) + (noteAngleCos * (offset.y + aOffset.y));
+
+ aOffset.put();
+ } else {
+ realOffset.x = offset.x;
+ realOffset.y = offset.y;
+ }
+ realOffset.y *= -1;
+
+ if (shouldX) daNote.x = x + realOffset.x;
+ if (shouldY) daNote.y = y + realOffset.y;
+
+ offset.put();
+ realOffset.put();
}
- realOffset.y *= -1;
-
- daNote.setPosition(x + realOffset.x, y + realOffset.y);
-
- offset.put();
- realOffset.put();
}
}
diff --git a/source/funkin/game/cutscenes/DialogueCutscene.hx b/source/funkin/game/cutscenes/DialogueCutscene.hx
index 99ba142b..b9a7c134 100644
--- a/source/funkin/game/cutscenes/DialogueCutscene.hx
+++ b/source/funkin/game/cutscenes/DialogueCutscene.hx
@@ -86,7 +86,7 @@ class DialogueCutscene extends Cutscene {
callback: node.getAtt('callback'),
changeDefAnim: node.getAtt('changeDefAnim'),
speed: Std.parseFloat(node.getAtt("speed")).getDefault(0.05),
- musicVolume: node.has.musicVolume ? (volume = Std.parseFloat(node.att.speed).getDefault(0.8)) : null,
+ musicVolume: node.has.musicVolume ? (volume = Std.parseFloat(node.att.musicVolume).getDefault(0.8)) : null,
changeMusic: node.has.changeMusic ? FlxG.sound.load(Paths.music(node.att.changeMusic), volume, true) : null,
playSound: node.has.playSound ? FlxG.sound.load(Paths.sound(node.att.playSound)) : null,
nextSound: node.has.nextSound ? FlxG.sound.load(Paths.sound(node.att.nextSound)) : null,
diff --git a/source/funkin/menus/FreeplayState.hx b/source/funkin/menus/FreeplayState.hx
index ec9cbeb9..0542ab17 100644
--- a/source/funkin/menus/FreeplayState.hx
+++ b/source/funkin/menus/FreeplayState.hx
@@ -141,6 +141,8 @@ class FreeplayState extends MusicBeatState
var icon:HealthIcon = new HealthIcon(songs[i].icon);
icon.sprTracker = songText;
+ icon.setUnstretchedGraphicSize(150, 150, true);
+ icon.updateHitbox();
// using a FlxGroup is too much fuss!
iconArray.push(icon);
diff --git a/source/funkin/options/type/IconOption.hx b/source/funkin/options/type/IconOption.hx
index 94923185..385dd563 100644
--- a/source/funkin/options/type/IconOption.hx
+++ b/source/funkin/options/type/IconOption.hx
@@ -10,6 +10,10 @@ class IconOption extends TextOption {
iconSpr = new HealthIcon(icon, false);
iconSpr.setPosition(90 - iconSpr.width, (__text.height - iconSpr.height) / 2);
+ iconSpr.setUnstretchedGraphicSize(150, 150, true);
+ iconSpr.updateHitbox();
+ iconSpr.sprTracker = __text;
+ iconSpr.sprTrackerAlignment = LEFT;
add(iconSpr);
}
}
\ No newline at end of file
diff --git a/source/funkin/options/type/NewOption.hx b/source/funkin/options/type/NewOption.hx
index bb8af3be..78201013 100644
--- a/source/funkin/options/type/NewOption.hx
+++ b/source/funkin/options/type/NewOption.hx
@@ -1,7 +1,6 @@
package funkin.options.type;
import flixel.util.FlxColor;
-import funkin.game.HealthIcon;
class NewOption extends TextOption {
public var iconSpr:FlxSprite;