diff --git a/.vscode/.temp b/.vscode/.temp
new file mode 100644
index 0000000..177a799
--- /dev/null
+++ b/.vscode/.temp
@@ -0,0 +1 @@
+TBA: tasks.json
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
new file mode 100644
index 0000000..0930c09
--- /dev/null
+++ b/.vscode/tasks.json
@@ -0,0 +1,21 @@
+{
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "type": "lime",
+ "command": "test",
+ "group": {
+ "kind": "build",
+ "isDefault": true
+ }
+ },
+ {
+ "type": "lime",
+ "command": "build",
+ "group": {
+ "kind": "build",
+ "isDefault": true
+ }
+ }
+ ]
+}
diff --git a/KadeEngineWithBackground.png b/KadeEngineWithBackground.png
index 374a0c1..8629a24 100644
Binary files a/KadeEngineWithBackground.png and b/KadeEngineWithBackground.png differ
diff --git a/Project.xml b/Project.xml
index eeffad6..1eace03 100644
--- a/Project.xml
+++ b/Project.xml
@@ -57,6 +57,7 @@
+
@@ -89,7 +91,9 @@
-
+
+
+
@@ -160,6 +164,8 @@
+
+
diff --git a/README.md b/README.md
index 832467c..deaf970 100644
--- a/README.md
+++ b/README.md
@@ -24,17 +24,23 @@ If you're looking for documentation, changelogs, or guides, you can find those o
# Previews ([skip](#features))
- 
+
-
+
-
+
-
+
-
+
-
+
+
+
+
+
+
+
# Features
@@ -43,12 +49,15 @@ If you're looking for documentation, changelogs, or guides, you can find those o
- **More information during gameplay**
- While you're playing, we show you information about how you're doing, such as your accuracy, combo break count, notes per second, and your grade/rating.
- **Customizable keybinds**
- - Instead of being forced to use WASD and the arrow keys, you can customize the keybinds to any keys you want!
+ - Instead of being forced to use WASD and the arrow keys, you can set any keybinds you want!
- **Replays** (in beta)
- Have you ever gotten a crazy score but didn't record? The replay system solves that: it automatically saves a "replay" of your gameplay every time you complete a song, which you can play back inside of the game.
- Replays just store information about what you're doing, they don't actually record the screen -- so they take up way less space on your disk than videos.
- **Audio offset**
- - If your headphones are delayed, you can set an offset in the options menu to line the game up with the delay and play with synced audio like intended.
+ - If your speakers or headphones are delayed, you can set an offset in the options menu to line the game up with the delay and play with synced audio like intended!
+ - **And much, much more!**
+ - There's so much more in store than just what's listed here! If you can imagine a quality of life feature, it's probably
+ either already included in Kade Engine or is being worked on!
# Credits
### Friday Night Funkin'
@@ -65,4 +74,6 @@ This game was made with love to Newgrounds and its community. Extra love to Tom
### Shoutouts
- [GWebDev](https://github.com/GrowtopiaFli) - Video Code
- [Rozebud](https://github.com/ThatRozebudDude) - Ideas (that I stole)
-- [Puyo](https://github.com/daniel11420) - Setting up appveyor and a lot of other help
\ No newline at end of file
+- [Puyo](https://github.com/puyoxyz) - Setting up appveyor and a lot of other help
+- [Smokey](https://github.com/Smokey555) - telling me that I should do the tricky asset loading
+- [Poco](https://github.com/poco0317) - math degree (aka most of the fucking math in this project)
diff --git a/appveyor-linux.yml b/appveyor-linux.yml
index dc06bb0..6dfee0f 100644
--- a/appveyor-linux.yml
+++ b/appveyor-linux.yml
@@ -9,7 +9,7 @@ install:
- cd /home/appveyor
- sudo add-apt-repository ppa:haxe/releases -y
- sudo apt update
- - sudo apt install neko tar gcc-multilib g++-multilib -y
+ - sudo apt install neko tar gcc-7 g++-7 gcc-7-multilib g++-7-multilib -y
- wget https://github.com/HaxeFoundation/haxe/releases/download/4.1.5/haxe-4.1.5-linux64.tar.gz
- mkdir $HAXE_INSTALLDIR
- tar -xf haxe-4.1.5-linux64.tar.gz -C $HAXE_INSTALLDIR
diff --git a/appveyor-windows.yml b/appveyor-windows.yml
index f1d47f5..58d5d98 100644
--- a/appveyor-windows.yml
+++ b/appveyor-windows.yml
@@ -36,7 +36,10 @@ install:
- haxelib git extension-webm https://github.com/KadeDev/extension-webm
- haxelib run lime rebuild extension-webm windows
- haxelib install linc_luajit
- - haxelib install actuate
+ - haxelib install actuate
+ #- haxelib git extension-webm https://github.com/KadeDev/extension-webm
+ #- haxelib run lime rebuild extension-webm windows
+ #why here's dublicate lmao
- haxelib list
# No tests idk lol
diff --git a/art/flashFiles/NOTE_assets.fla b/art/flashFiles/NOTE_assets.fla
index 523cc95..d3e4f32 100644
Binary files a/art/flashFiles/NOTE_assets.fla and b/art/flashFiles/NOTE_assets.fla differ
diff --git a/art/readme/KadeEngineDialogue.png b/art/readme/KadeEngineDialogue.png
new file mode 100644
index 0000000..36ebeb8
Binary files /dev/null and b/art/readme/KadeEngineDialogue.png differ
diff --git a/art/readme/KadeEngineFreeplay.png b/art/readme/KadeEngineFreeplay.png
new file mode 100644
index 0000000..a3ed2a9
Binary files /dev/null and b/art/readme/KadeEngineFreeplay.png differ
diff --git a/art/readme/KadeEngineOptions.png b/art/readme/KadeEngineOptions.png
new file mode 100644
index 0000000..2005272
Binary files /dev/null and b/art/readme/KadeEngineOptions.png differ
diff --git a/art/readme/KadeEnginePauseScreen.png b/art/readme/KadeEnginePauseScreen.png
new file mode 100644
index 0000000..c31edf7
Binary files /dev/null and b/art/readme/KadeEnginePauseScreen.png differ
diff --git a/art/readme/KadeEnginePixelGameplay.png b/art/readme/KadeEnginePixelGameplay.png
new file mode 100644
index 0000000..20416ab
Binary files /dev/null and b/art/readme/KadeEnginePixelGameplay.png differ
diff --git a/art/readme/KadeEngineReplayLoader.png b/art/readme/KadeEngineReplayLoader.png
new file mode 100644
index 0000000..4c7fc9c
Binary files /dev/null and b/art/readme/KadeEngineReplayLoader.png differ
diff --git a/art/readme/KadeEngineResultsScreen.png b/art/readme/KadeEngineResultsScreen.png
new file mode 100644
index 0000000..110bade
Binary files /dev/null and b/art/readme/KadeEngineResultsScreen.png differ
diff --git a/art/readme/KadeEngineTitleScreen.png b/art/readme/KadeEngineTitleScreen.png
new file mode 100644
index 0000000..405fe80
Binary files /dev/null and b/art/readme/KadeEngineTitleScreen.png differ
diff --git a/art/readme/KadeEngineWeekSelect.png b/art/readme/KadeEngineWeekSelect.png
new file mode 100644
index 0000000..d8327c8
Binary files /dev/null and b/art/readme/KadeEngineWeekSelect.png differ
diff --git a/assets/preload/data/freeplaySonglist.txt b/assets/preload/data/freeplaySonglist.txt
index a5939ad..7af8115 100644
--- a/assets/preload/data/freeplaySonglist.txt
+++ b/assets/preload/data/freeplaySonglist.txt
@@ -1,4 +1,4 @@
-Tutorial:gf:1
+Tutorial:gf:0
Bopeebo:dad:1
Fresh:dad:1
Dad Battle:dad:1
diff --git a/assets/preload/data/satin-panties/satin-panties-hard.json b/assets/preload/data/satin-panties/satin-panties-hard.json
index 27ac0b6..d1578b2 100644
--- a/assets/preload/data/satin-panties/satin-panties-hard.json
+++ b/assets/preload/data/satin-panties/satin-panties-hard.json
@@ -1 +1,2904 @@
-{"song":{"player1":"bf-car","gfVersion":"gf-car","notes":[{"sectionNotes":[[0,0,0],[272.727264,0,0],[545.4545,0,0],[818.181763,0,0],[954.5454,0,0],[1227.27271,0,0],[1363.63635,0,0],[1636.36353,0,0],[1909.09082,0,0],[2045.45447,0,0]],"lengthInSteps":16,"mustHitSection":false},{"sectionNotes":[[2181.818,3,0],[2454.54541,3,0],[2727.27271,3,0],[3000,3,0],[3136.36353,3,0],[3409.09082,3,0],[3545.45435,3,0],[3818.18164,3,0],[4090.909,3,0],[4227.27246,3,0]],"lengthInSteps":16,"mustHitSection":true},{"sectionNotes":[[4636.36328,2,0],[4909.091,3,0],[5181.818,2,0],[5318.18164,3,0],[5590.90869,0,0],[5863.636,2,0],[6000,3,0],[6272.727,0,0],[6409.091,3,0]],"lengthInSteps":16,"mustHitSection":false},{"sectionNotes":[[6818.18164,2,0],[7090.90869,3,0],[7363.636,2,0],[7500,3,0],[7772.727,0,0],[8045.454,2,0],[8181.818,3,0],[8318.182,0,0],[8454.545,1,0]],"lengthInSteps":16,"mustHitSection":false},{"sectionNotes":[[8727.272,6,545.4545],[9000,2,0],[9272.727,3,0],[9545.454,2,0],[9681.818,3,0],[9954.545,0,0],[10227.2725,2,0],[10363.6357,3,0],[10636.3633,0,0],[10772.7266,3,0]],"lengthInSteps":16,"mustHitSection":true},{"sectionNotes":[[11181.8174,2,0],[11454.5449,3,0],[11727.2725,2,0],[11863.6357,3,0],[12136.3633,0,0],[12409.0908,2,0],[12545.4541,3,0],[12681.8174,0,0],[12818.1816,1,0]],"lengthInSteps":16,"mustHitSection":true},{"sectionNotes":[[13090.9082,6,545.4545],[13363.6357,1,0],[13500,1,0],[13636.3633,0,0],[13909.0908,0,0],[14045.4541,3,0],[14181.8174,2,272.727264],[14590.9082,3,0],[14727.2725,0,0],[15000,1,0]],"lengthInSteps":16,"mustHitSection":false},{"sectionNotes":[[15272.7266,3,272.727264],[15681.8174,0,0],[15954.5449,0,0],[16090.9082,0,0],[16227.2725,0,0],[16363.6357,2,272.727264],[16772.7266,3,0],[16909.09,0,0],[17045.4531,1,0],[17181.8184,0,0]],"lengthInSteps":16,"mustHitSection":false},{"sectionNotes":[[17454.5449,6,545.4545],[17727.2715,1,0],[17863.6367,1,0],[18000,0,0],[18272.7266,0,0],[18409.09,3,0],[18545.4531,2,272.727264],[18954.5449,3,0],[19090.9082,0,0],[19363.6367,1,0]],"lengthInSteps":16,"mustHitSection":true},{"sectionNotes":[[19636.3633,3,272.727264],[20045.4531,0,0],[20318.1816,0,0],[20454.5449,0,0],[20590.9082,0,0],[20727.2715,2,272.727264],[21136.3633,3,0],[21272.7266,0,0],[21409.09,1,0],[21545.4531,0,0]],"lengthInSteps":16,"mustHitSection":true},{"sectionNotes":[[21818.1816,6,409.090881],[21818.1816,2,409.090881],[22363.6348,7,0],[22363.6348,3,0],[22500,6,0],[22500,2,0],[22636.3633,7,0],[22636.3633,3,0],[22772.7266,6,0],[22772.7266,2,0],[22909.09,4,0],[22909.09,0,0],[23045.4531,5,0],[23045.4531,1,0],[23181.8184,4,0],[23181.8184,0,0],[23318.1816,5,0],[23318.1816,1,0],[23454.5449,4,0],[23454.5449,0,0],[23590.9082,7,0],[23590.9082,3,0],[23727.2715,4,0],[23727.2715,0,0],[23863.6348,7,0],[23863.6348,3,0]],"lengthInSteps":16,"mustHitSection":false},{"sectionNotes":[[24000,1,409.090881],[24000,5,409.090881],[24545.4531,4,0],[24545.4531,0,0],[24681.8184,7,0],[24681.8184,3,0],[24818.1816,4,0],[24818.1816,0,0],[24954.5449,7,0],[24954.5449,3,0],[25090.9082,6,136.363632],[25090.9082,2,136.363632],[25363.6348,7,0],[25363.6348,3,0],[25636.3633,7,0],[25636.3633,3,0],[25909.09,5,0],[25909.09,1,0]],"lengthInSteps":16,"mustHitSection":false},{"sectionNotes":[[26181.8164,4,409.090881],[26181.8164,3,409.090881],[26727.2715,0,409.090881],[26727.2715,7,409.090881],[27272.7266,6,0],[27272.7266,2,0],[27545.4531,6,0],[27545.4531,2,0],[27681.8164,6,0],[27681.8164,2,0],[27818.1816,7,409.090881],[27818.1816,0,409.090881]],"lengthInSteps":16,"mustHitSection":true},{"sectionNotes":[[28363.6348,5,409.090881],[28363.6348,1,409.090881],[28909.09,7,409.090881],[28909.09,3,409.090881],[29454.5449,6,409.090881],[29454.5449,2,409.090881],[30000,4,0],[30000,0,0],[30272.7266,7,409.090881],[30272.7266,3,0]],"lengthInSteps":16,"mustHitSection":true},{"sectionNotes":[[30545.4531,5,545.4545],[30818.1816,2,0],[30954.5449,3,0],[31090.9082,0,0],[31363.6348,1,0],[31636.3633,3,0],[31772.7266,0,0],[31909.09,3,0],[32181.8164,3,0],[32318.1816,0,0],[32454.5449,1,0]],"lengthInSteps":16,"mustHitSection":false},{"sectionNotes":[[33000,1,0],[33136.3633,3,0],[33272.7266,0,136.363632],[33545.4531,1,0],[33818.18,2,0],[33954.543,3,0],[34090.9063,0,0],[34227.2734,0,0],[34363.6367,3,0],[34500,0,0],[34636.3633,0,0],[34772.7266,1,0]],"lengthInSteps":16,"mustHitSection":false},{"sectionNotes":[[34909.09,7,0],[35045.4531,6,0],[35181.8164,2,0],[35181.8164,7,0],[35318.18,3,0],[35454.543,0,0],[35727.2734,1,0],[36000,3,0],[36136.3633,0,0],[36272.7266,3,0],[36545.4531,3,0],[36681.8164,0,0],[36818.18,1,0]],"lengthInSteps":16,"mustHitSection":true},{"sectionNotes":[[37363.6367,1,0],[37500,3,0],[37636.3633,0,136.363632],[37909.09,1,0],[38181.8164,2,0],[38318.18,3,0],[38454.543,0,0],[38590.9063,0,0],[38727.2734,7,0],[38727.2734,3,0],[38863.6367,4,0],[38863.6367,0,0],[39000,5,0],[39000,0,0],[39136.3633,7,0],[39136.3633,1,0]],"lengthInSteps":16,"mustHitSection":true},{"sectionNotes":[[39272.7266,2,136.363632],[39272.7266,7,0],[39409.09,6,0],[39545.4531,7,0],[39545.4531,2,0],[39681.8164,3,0],[39818.18,0,0],[39954.543,1,0],[40090.9063,3,0],[40227.2734,1,0],[40363.6367,3,0],[40500,0,0],[40636.3633,3,0],[40772.7266,1,0],[40909.09,3,0],[41045.4531,0,0],[41181.8164,1,0]],"lengthInSteps":16,"mustHitSection":false},{"sectionNotes":[[41454.543,0,0],[41727.27,1,0],[41863.6367,3,0],[42000,0,136.363632],[42272.7266,1,0],[42545.4531,2,0],[42681.8164,3,0],[42818.18,0,0],[42954.543,0,0],[43090.9063,7,0],[43090.9063,3,0],[43227.27,4,0],[43227.27,0,0],[43363.6367,5,0],[43363.6367,0,0],[43500,7,0],[43500,1,0]],"lengthInSteps":16,"mustHitSection":false},{"sectionNotes":[[43636.3633,2,136.363632],[43909.09,2,0],[44045.4531,3,0],[44181.8164,0,0],[44318.18,1,0],[44454.543,3,0],[44590.9063,1,0],[44727.27,3,0],[44863.6367,0,0],[45000,3,0],[45136.3633,1,0],[45272.7266,3,0],[45409.09,0,0],[45545.4531,1,0]],"lengthInSteps":16,"mustHitSection":true},{"sectionNotes":[[45818.18,0,0],[46090.9063,1,0],[46227.27,3,0],[46363.6367,0,136.363632],[46636.3633,1,0],[46909.09,2,0],[47045.4531,3,0],[47181.8164,0,0],[47318.18,0,0],[47454.543,3,0],[47590.9063,0,0],[47727.27,0,0],[47863.6367,1,0]],"lengthInSteps":16,"mustHitSection":true},{"sectionNotes":[[48272.7266,2,0],[48409.09,3,0],[48545.4531,0,0],[48681.8164,3,0],[48818.18,0,0],[48954.543,2,0],[49090.9063,3,0],[49363.6367,3,0],[49636.3633,1,0],[49909.09,0,0]],"lengthInSteps":16,"mustHitSection":false},{"sectionNotes":[[50454.543,3,0],[50590.9063,1,0],[50727.27,0,0],[50863.6367,3,0],[51000,2,0],[51272.7266,0,0],[51545.4531,2,0],[51818.18,0,0],[52090.9063,1,0]],"lengthInSteps":16,"mustHitSection":false},{"sectionNotes":[[52363.6328,6,545.4545],[52636.3633,2,0],[52772.7266,3,0],[52909.09,0,0],[53045.4531,3,0],[53181.8164,0,0],[53318.18,2,0],[53454.543,3,0],[53727.27,3,0],[54000,1,0],[54272.7266,0,0]],"lengthInSteps":16,"mustHitSection":true},{"sectionNotes":[[54818.18,3,0],[54954.543,1,0],[55090.9063,0,0],[55227.27,3,0],[55363.6328,2,0],[55636.3633,0,0],[55909.09,2,0],[56181.8164,0,0],[56454.543,1,0]],"lengthInSteps":16,"mustHitSection":true},{"sectionNotes":[[56727.27,6,409.090881],[56727.27,2,409.090881],[57272.7266,3,0],[57272.7266,7,0],[57409.09,2,0],[57409.09,6,0],[57545.4531,3,0],[57545.4531,7,0],[57681.8164,2,0],[57681.8164,6,0],[57818.18,0,0],[57818.18,4,0],[57954.543,1,0],[57954.543,5,0],[58090.9063,0,0],[58090.9063,4,0],[58227.27,1,0],[58227.27,5,0],[58363.6328,0,0],[58363.6328,4,0],[58500,3,0],[58500,7,0],[58636.3633,0,0],[58636.3633,4,0],[58772.7266,3,0],[58772.7266,7,0]],"lengthInSteps":16,"mustHitSection":false},{"sectionNotes":[[58909.09,1,409.090881],[58909.09,5,409.090881],[59454.543,4,0],[59454.543,0,0],[59590.9063,7,0],[59590.9063,3,0],[59727.27,4,0],[59727.27,0,0],[59863.6328,7,0],[59863.6328,3,0],[60000,6,136.363632],[60000,2,136.363632],[60272.7266,7,0],[60272.7266,3,0],[60545.4531,7,0],[60545.4531,3,0],[60818.18,5,0],[60818.18,1,0]],"lengthInSteps":16,"mustHitSection":false},{"sectionNotes":[[61090.9063,0,409.090881],[61090.9063,7,409.090881],[61636.3633,4,409.090881],[61636.3633,3,409.090881],[62181.8164,2,0],[62181.8164,6,0],[62454.543,2,0],[62454.543,6,0],[62590.9063,2,0],[62590.9063,6,0],[62727.27,3,409.090881],[62727.27,4,409.090881]],"lengthInSteps":16,"mustHitSection":true},{"sectionNotes":[[63272.7266,5,409.090881],[63272.7266,1,409.090881],[63818.18,7,409.090881],[63818.18,3,409.090881],[64363.6328,6,409.090881],[64363.6328,2,409.090881],[64909.09,4,0],[64909.09,0,0],[65181.8164,7,0],[65181.8164,3,0]],"lengthInSteps":16,"mustHitSection":true},{"sectionNotes":[[65454.543,5,545.4545],[65454.543,2,0],[65727.27,2,0],[65863.63,3,0],[66000,0,0],[66272.73,1,0],[66545.45,3,0],[66681.81,0,0],[66818.18,3,0],[67090.91,3,0],[67227.27,0,0],[67363.63,1,0]],"lengthInSteps":16,"mustHitSection":false},{"sectionNotes":[[67909.0859,1,0],[68045.45,3,0],[68181.81,0,136.363632],[68454.55,1,0],[68727.27,2,0],[68818.18,0,0],[68909.0859,3,0],[69000,0,0],[69181.81,0,0],[69272.73,3,0],[69363.63,0,0],[69454.55,3,0],[69545.45,1,0],[69727.27,0,0]],"lengthInSteps":16,"mustHitSection":false},{"sectionNotes":[[69818.18,5,409.090881],[70090.91,2,0],[70227.27,3,0],[70363.63,0,0],[70363.63,7,409.090881],[70636.36,1,0],[70909.0859,3,0],[70909.0859,6,409.090881],[71045.45,0,0],[71181.81,3,0],[71454.55,3,0],[71454.55,7,409.090881],[71590.91,0,0],[71727.27,1,0]],"lengthInSteps":16,"mustHitSection":true},{"sectionNotes":[[72000,5,409.090881],[72272.73,1,0],[72409.0859,3,0],[72545.45,0,136.363632],[72545.45,7,409.090881],[72818.18,1,0],[73090.91,2,0],[73181.81,0,0],[73272.73,3,0],[73363.63,0,0],[73545.45,0,0],[73636.36,3,0],[73727.27,0,0],[73818.18,3,0],[73909.0859,1,0],[74090.91,0,0]],"lengthInSteps":16,"mustHitSection":true},{"sectionNotes":[[74181.81,0,136.363632],[74181.81,5,409.090881],[74454.55,2,0],[74590.91,3,0],[74727.27,0,0],[74727.27,7,409.090881],[74863.63,1,0],[75000,3,0],[75136.36,1,0],[75272.73,3,0],[75272.73,6,409.090881],[75409.0859,0,0],[75545.45,3,0],[75681.81,1,0],[75818.18,3,0],[75818.18,7,409.090881],[75954.55,0,0],[76090.91,1,0]],"lengthInSteps":16,"mustHitSection":false},{"sectionNotes":[[76363.63,0,0],[76363.63,5,409.090881],[76636.36,1,0],[76772.73,3,0],[76909.0859,0,136.363632],[76909.0859,7,409.090881],[77181.81,1,0],[77454.55,2,0],[77454.55,6,409.090881],[77590.91,3,0],[77727.27,0,0],[77863.63,0,0],[78000,3,0],[78000,7,0],[78136.36,0,0],[78136.36,4,0],[78272.73,0,0],[78272.73,4,0],[78409.0859,1,0],[78409.0859,5,0]],"lengthInSteps":16,"mustHitSection":false},{"sectionNotes":[[78545.45,0,136.363632],[78818.18,2,0],[78954.55,3,0],[79090.91,0,0],[79227.27,1,0],[79363.63,3,0],[79500,1,0],[79636.36,3,0],[79772.73,0,0],[79909.0859,3,0],[80045.45,1,0],[80181.81,3,0],[80318.18,0,0],[80454.55,1,0]],"lengthInSteps":16,"mustHitSection":true},{"sectionNotes":[[80727.27,0,0],[81000,1,0],[81136.36,3,0],[81272.73,0,136.363632],[81545.45,1,0],[81818.18,2,0],[81954.54,3,0],[82090.91,0,0],[82227.27,0,0],[82363.63,3,0],[82500,0,0],[82636.36,0,0],[82772.73,1,0]],"lengthInSteps":16,"mustHitSection":true},{"sectionNotes":[[82909.0859,7,1090.909],[83181.81,2,0],[83454.54,3,0],[83727.27,2,0],[83863.63,3,0],[84136.36,0,0],[84409.0859,2,0],[84545.45,3,0],[84818.18,0,0],[84954.54,3,0]],"lengthInSteps":16,"mustHitSection":false},{"sectionNotes":[[85363.63,2,0],[85636.36,3,0],[85909.0859,2,0],[86045.45,3,0],[86318.18,0,0],[86590.91,2,0],[86727.27,3,0],[86863.63,0,0],[87000,1,0]],"lengthInSteps":16,"mustHitSection":true},{"sectionNotes":[[87272.73,2,545.4545]],"lengthInSteps":16,"mustHitSection":true},{"sectionNotes":[],"lengthInSteps":16,"mustHitSection":true},{"sectionNotes":[],"lengthInSteps":16,"mustHitSection":true},{"sectionNotes":[],"lengthInSteps":16,"mustHitSection":true},{"lengthInSteps":16,"altAnim":false,"typeOfSection":0,"sectionNotes":[],"bpm":110,"changeBPM":false,"mustHitSection":true}],"player2":"mom-car","song":"Satin Panties","stage":"limo","needsVoices":true,"validScore":true,"bpm":110,"speed":1.8}}
\ No newline at end of file
+{
+ "song": {
+ "player1": "bf-car",
+ "player2": "mom-car",
+ "notes": [
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 272.727264,
+ 0,
+ 0
+ ],
+ [
+ 545.4545,
+ 0,
+ 0
+ ],
+ [
+ 818.181763,
+ 0,
+ 0
+ ],
+ [
+ 954.5454,
+ 0,
+ 0
+ ],
+ [
+ 1227.27271,
+ 0,
+ 0
+ ],
+ [
+ 1363.63635,
+ 0,
+ 0
+ ],
+ [
+ 1636.36353,
+ 0,
+ 0
+ ],
+ [
+ 1909.09082,
+ 0,
+ 0
+ ],
+ [
+ 2045.45447,
+ 0,
+ 0
+ ]
+ ],
+ "mustHitSection": false
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 2181.818,
+ 3,
+ 0
+ ],
+ [
+ 2454.54541,
+ 3,
+ 0
+ ],
+ [
+ 2727.27271,
+ 3,
+ 0
+ ],
+ [
+ 3000,
+ 3,
+ 0
+ ],
+ [
+ 3136.36353,
+ 3,
+ 0
+ ],
+ [
+ 3409.09082,
+ 3,
+ 0
+ ],
+ [
+ 3545.45435,
+ 3,
+ 0
+ ],
+ [
+ 3818.18164,
+ 3,
+ 0
+ ],
+ [
+ 4090.909,
+ 3,
+ 0
+ ],
+ [
+ 4227.27246,
+ 3,
+ 0
+ ]
+ ],
+ "mustHitSection": true
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 4636.36328,
+ 2,
+ 0
+ ],
+ [
+ 4909.091,
+ 3,
+ 0
+ ],
+ [
+ 5181.818,
+ 2,
+ 0
+ ],
+ [
+ 5318.18164,
+ 3,
+ 0
+ ],
+ [
+ 5590.90869,
+ 0,
+ 0
+ ],
+ [
+ 5863.636,
+ 2,
+ 0
+ ],
+ [
+ 6000,
+ 3,
+ 0
+ ],
+ [
+ 6272.727,
+ 0,
+ 0
+ ],
+ [
+ 6409.091,
+ 3,
+ 0
+ ]
+ ],
+ "mustHitSection": false
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 6818.18164,
+ 2,
+ 0
+ ],
+ [
+ 7090.90869,
+ 3,
+ 0
+ ],
+ [
+ 7363.636,
+ 2,
+ 0
+ ],
+ [
+ 7500,
+ 3,
+ 0
+ ],
+ [
+ 7772.727,
+ 0,
+ 0
+ ],
+ [
+ 8045.454,
+ 2,
+ 0
+ ],
+ [
+ 8181.818,
+ 3,
+ 0
+ ],
+ [
+ 8318.182,
+ 0,
+ 0
+ ],
+ [
+ 8454.545,
+ 1,
+ 0
+ ]
+ ],
+ "mustHitSection": false
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 8727.272,
+ 6,
+ 545.4545
+ ],
+ [
+ 9000,
+ 2,
+ 0
+ ],
+ [
+ 9272.727,
+ 3,
+ 0
+ ],
+ [
+ 9545.454,
+ 2,
+ 0
+ ],
+ [
+ 9681.818,
+ 3,
+ 0
+ ],
+ [
+ 9954.545,
+ 0,
+ 0
+ ],
+ [
+ 10227.2725,
+ 2,
+ 0
+ ],
+ [
+ 10363.6357,
+ 3,
+ 0
+ ],
+ [
+ 10636.3633,
+ 0,
+ 0
+ ],
+ [
+ 10772.7266,
+ 3,
+ 0
+ ]
+ ],
+ "mustHitSection": true
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 11181.8174,
+ 2,
+ 0
+ ],
+ [
+ 11454.5449,
+ 3,
+ 0
+ ],
+ [
+ 11727.2725,
+ 2,
+ 0
+ ],
+ [
+ 11863.6357,
+ 3,
+ 0
+ ],
+ [
+ 12136.3633,
+ 0,
+ 0
+ ],
+ [
+ 12409.0908,
+ 2,
+ 0
+ ],
+ [
+ 12545.4541,
+ 3,
+ 0
+ ],
+ [
+ 12681.8174,
+ 0,
+ 0
+ ],
+ [
+ 12818.1816,
+ 1,
+ 0
+ ]
+ ],
+ "mustHitSection": true
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 13090.9082,
+ 6,
+ 545.4545
+ ],
+ [
+ 13363.6357,
+ 1,
+ 0
+ ],
+ [
+ 13500,
+ 1,
+ 0
+ ],
+ [
+ 13636.3633,
+ 0,
+ 0
+ ],
+ [
+ 13909.0908,
+ 0,
+ 0
+ ],
+ [
+ 14045.4541,
+ 3,
+ 0
+ ],
+ [
+ 14181.8174,
+ 2,
+ 272.727264
+ ],
+ [
+ 14590.9082,
+ 3,
+ 0
+ ],
+ [
+ 14727.2725,
+ 0,
+ 0
+ ],
+ [
+ 15000,
+ 1,
+ 0
+ ]
+ ],
+ "mustHitSection": false
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 15272.7266,
+ 3,
+ 272.727264
+ ],
+ [
+ 15681.8174,
+ 0,
+ 0
+ ],
+ [
+ 15954.5449,
+ 0,
+ 0
+ ],
+ [
+ 16090.9082,
+ 0,
+ 0
+ ],
+ [
+ 16227.2725,
+ 0,
+ 0
+ ],
+ [
+ 16363.6357,
+ 2,
+ 272.727264
+ ],
+ [
+ 16772.7266,
+ 3,
+ 0
+ ],
+ [
+ 16909.09,
+ 0,
+ 0
+ ],
+ [
+ 17045.4531,
+ 1,
+ 0
+ ],
+ [
+ 17181.8184,
+ 0,
+ 0
+ ]
+ ],
+ "mustHitSection": false
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 17454.5449,
+ 6,
+ 545.4545
+ ],
+ [
+ 17727.2715,
+ 1,
+ 0
+ ],
+ [
+ 17863.6367,
+ 1,
+ 0
+ ],
+ [
+ 18000,
+ 0,
+ 0
+ ],
+ [
+ 18272.7266,
+ 0,
+ 0
+ ],
+ [
+ 18409.09,
+ 3,
+ 0
+ ],
+ [
+ 18545.4531,
+ 2,
+ 272.727264
+ ],
+ [
+ 18954.5449,
+ 3,
+ 0
+ ],
+ [
+ 19090.9082,
+ 0,
+ 0
+ ],
+ [
+ 19363.6367,
+ 1,
+ 0
+ ]
+ ],
+ "mustHitSection": true
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 19636.3633,
+ 3,
+ 272.727264
+ ],
+ [
+ 20045.4531,
+ 0,
+ 0
+ ],
+ [
+ 20318.1816,
+ 0,
+ 0
+ ],
+ [
+ 20454.5449,
+ 0,
+ 0
+ ],
+ [
+ 20590.9082,
+ 0,
+ 0
+ ],
+ [
+ 20727.2715,
+ 2,
+ 272.727264
+ ],
+ [
+ 21136.3633,
+ 3,
+ 0
+ ],
+ [
+ 21272.7266,
+ 0,
+ 0
+ ],
+ [
+ 21409.09,
+ 1,
+ 0
+ ],
+ [
+ 21545.4531,
+ 0,
+ 0
+ ]
+ ],
+ "mustHitSection": true
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 21818.1816,
+ 6,
+ 409.090881
+ ],
+ [
+ 21818.1816,
+ 2,
+ 409.090881
+ ],
+ [
+ 22363.6348,
+ 7,
+ 0
+ ],
+ [
+ 22363.6348,
+ 3,
+ 0
+ ],
+ [
+ 22500,
+ 6,
+ 0
+ ],
+ [
+ 22500,
+ 2,
+ 0
+ ],
+ [
+ 22636.3633,
+ 7,
+ 0
+ ],
+ [
+ 22636.3633,
+ 3,
+ 0
+ ],
+ [
+ 22772.7266,
+ 6,
+ 0
+ ],
+ [
+ 22772.7266,
+ 2,
+ 0
+ ],
+ [
+ 22909.09,
+ 4,
+ 0
+ ],
+ [
+ 22909.09,
+ 0,
+ 0
+ ],
+ [
+ 23045.4531,
+ 5,
+ 0
+ ],
+ [
+ 23045.4531,
+ 1,
+ 0
+ ],
+ [
+ 23181.8184,
+ 4,
+ 0
+ ],
+ [
+ 23181.8184,
+ 0,
+ 0
+ ],
+ [
+ 23318.1816,
+ 5,
+ 0
+ ],
+ [
+ 23318.1816,
+ 1,
+ 0
+ ],
+ [
+ 23454.5449,
+ 4,
+ 0
+ ],
+ [
+ 23454.5449,
+ 0,
+ 0
+ ],
+ [
+ 23590.9082,
+ 7,
+ 0
+ ],
+ [
+ 23590.9082,
+ 3,
+ 0
+ ],
+ [
+ 23727.2715,
+ 4,
+ 0
+ ],
+ [
+ 23727.2715,
+ 0,
+ 0
+ ],
+ [
+ 23863.6348,
+ 7,
+ 0
+ ],
+ [
+ 23863.6348,
+ 3,
+ 0
+ ]
+ ],
+ "mustHitSection": false
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 24000,
+ 1,
+ 409.090881
+ ],
+ [
+ 24000,
+ 5,
+ 409.090881
+ ],
+ [
+ 24545.4531,
+ 4,
+ 0
+ ],
+ [
+ 24545.4531,
+ 0,
+ 0
+ ],
+ [
+ 24681.8184,
+ 7,
+ 0
+ ],
+ [
+ 24681.8184,
+ 3,
+ 0
+ ],
+ [
+ 24818.1816,
+ 4,
+ 0
+ ],
+ [
+ 24818.1816,
+ 0,
+ 0
+ ],
+ [
+ 24954.5449,
+ 7,
+ 0
+ ],
+ [
+ 24954.5449,
+ 3,
+ 0
+ ],
+ [
+ 25090.9082,
+ 6,
+ 136.363632
+ ],
+ [
+ 25090.9082,
+ 2,
+ 136.363632
+ ],
+ [
+ 25363.6348,
+ 7,
+ 0
+ ],
+ [
+ 25363.6348,
+ 3,
+ 0
+ ],
+ [
+ 25636.3633,
+ 7,
+ 0
+ ],
+ [
+ 25636.3633,
+ 3,
+ 0
+ ],
+ [
+ 25909.09,
+ 5,
+ 0
+ ],
+ [
+ 25909.09,
+ 1,
+ 0
+ ]
+ ],
+ "mustHitSection": false
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 26181.8164,
+ 4,
+ 409.090881
+ ],
+ [
+ 26181.8164,
+ 3,
+ 409.090881
+ ],
+ [
+ 26727.2715,
+ 0,
+ 409.090881
+ ],
+ [
+ 26727.2715,
+ 7,
+ 409.090881
+ ],
+ [
+ 27272.7266,
+ 6,
+ 0
+ ],
+ [
+ 27272.7266,
+ 2,
+ 0
+ ],
+ [
+ 27545.4531,
+ 6,
+ 0
+ ],
+ [
+ 27545.4531,
+ 2,
+ 0
+ ],
+ [
+ 27681.8164,
+ 6,
+ 0
+ ],
+ [
+ 27681.8164,
+ 2,
+ 0
+ ],
+ [
+ 27818.1816,
+ 7,
+ 409.090881
+ ],
+ [
+ 27818.1816,
+ 0,
+ 409.090881
+ ]
+ ],
+ "mustHitSection": true
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 28363.6348,
+ 5,
+ 409.090881
+ ],
+ [
+ 28363.6348,
+ 1,
+ 409.090881
+ ],
+ [
+ 28909.09,
+ 7,
+ 409.090881
+ ],
+ [
+ 28909.09,
+ 3,
+ 409.090881
+ ],
+ [
+ 29454.5449,
+ 6,
+ 409.090881
+ ],
+ [
+ 29454.5449,
+ 2,
+ 409.090881
+ ],
+ [
+ 30000,
+ 4,
+ 0
+ ],
+ [
+ 30000,
+ 0,
+ 0
+ ],
+ [
+ 30272.7266,
+ 7,
+ 409.090881
+ ],
+ [
+ 30272.7266,
+ 3,
+ 0
+ ]
+ ],
+ "mustHitSection": true
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 30545.4531,
+ 5,
+ 545.4545
+ ],
+ [
+ 30818.1816,
+ 2,
+ 0
+ ],
+ [
+ 30954.5449,
+ 3,
+ 0
+ ],
+ [
+ 31090.9082,
+ 0,
+ 0
+ ],
+ [
+ 31363.6348,
+ 1,
+ 0
+ ],
+ [
+ 31636.3633,
+ 3,
+ 0
+ ],
+ [
+ 31772.7266,
+ 0,
+ 0
+ ],
+ [
+ 31909.09,
+ 3,
+ 0
+ ],
+ [
+ 32181.8164,
+ 3,
+ 0
+ ],
+ [
+ 32318.1816,
+ 0,
+ 0
+ ],
+ [
+ 32454.5449,
+ 1,
+ 0
+ ]
+ ],
+ "mustHitSection": false
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 33000,
+ 1,
+ 0
+ ],
+ [
+ 33136.3633,
+ 3,
+ 0
+ ],
+ [
+ 33272.7266,
+ 0,
+ 136.363632
+ ],
+ [
+ 33545.4531,
+ 1,
+ 0
+ ],
+ [
+ 33818.18,
+ 2,
+ 0
+ ],
+ [
+ 33954.543,
+ 3,
+ 0
+ ],
+ [
+ 34090.9063,
+ 0,
+ 0
+ ],
+ [
+ 34227.2734,
+ 0,
+ 0
+ ],
+ [
+ 34363.6367,
+ 3,
+ 0
+ ],
+ [
+ 34500,
+ 0,
+ 0
+ ],
+ [
+ 34636.3633,
+ 0,
+ 0
+ ],
+ [
+ 34772.7266,
+ 1,
+ 0
+ ]
+ ],
+ "mustHitSection": false
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 34909.09,
+ 7,
+ 0
+ ],
+ [
+ 35045.4531,
+ 6,
+ 0
+ ],
+ [
+ 35181.8164,
+ 2,
+ 0
+ ],
+ [
+ 35181.8164,
+ 7,
+ 0
+ ],
+ [
+ 35318.18,
+ 3,
+ 0
+ ],
+ [
+ 35454.543,
+ 0,
+ 0
+ ],
+ [
+ 35727.2734,
+ 1,
+ 0
+ ],
+ [
+ 36000,
+ 3,
+ 0
+ ],
+ [
+ 36136.3633,
+ 0,
+ 0
+ ],
+ [
+ 36272.7266,
+ 3,
+ 0
+ ],
+ [
+ 36545.4531,
+ 3,
+ 0
+ ],
+ [
+ 36681.8164,
+ 0,
+ 0
+ ],
+ [
+ 36818.18,
+ 1,
+ 0
+ ]
+ ],
+ "mustHitSection": true
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 37363.6367,
+ 1,
+ 0
+ ],
+ [
+ 37500,
+ 3,
+ 0
+ ],
+ [
+ 37636.3633,
+ 0,
+ 136.363632
+ ],
+ [
+ 37909.09,
+ 1,
+ 0
+ ],
+ [
+ 38181.8164,
+ 2,
+ 0
+ ],
+ [
+ 38318.18,
+ 3,
+ 0
+ ],
+ [
+ 38454.543,
+ 0,
+ 0
+ ],
+ [
+ 38590.9063,
+ 0,
+ 0
+ ],
+ [
+ 38727.2734,
+ 7,
+ 0
+ ],
+ [
+ 38727.2734,
+ 3,
+ 0
+ ],
+ [
+ 38863.6367,
+ 4,
+ 0
+ ],
+ [
+ 38863.6367,
+ 0,
+ 0
+ ],
+ [
+ 39000,
+ 5,
+ 0
+ ],
+ [
+ 39000,
+ 0,
+ 0
+ ],
+ [
+ 39136.3633,
+ 7,
+ 0
+ ],
+ [
+ 39136.3633,
+ 1,
+ 0
+ ]
+ ],
+ "mustHitSection": true
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 39272.7266,
+ 2,
+ 136.363632
+ ],
+ [
+ 39272.7266,
+ 7,
+ 0
+ ],
+ [
+ 39409.09,
+ 6,
+ 0
+ ],
+ [
+ 39545.4531,
+ 7,
+ 0
+ ],
+ [
+ 39545.4531,
+ 2,
+ 0
+ ],
+ [
+ 39681.8164,
+ 3,
+ 0
+ ],
+ [
+ 39818.18,
+ 0,
+ 0
+ ],
+ [
+ 39954.543,
+ 1,
+ 0
+ ],
+ [
+ 40090.9063,
+ 3,
+ 0
+ ],
+ [
+ 40227.2734,
+ 1,
+ 0
+ ],
+ [
+ 40363.6367,
+ 3,
+ 0
+ ],
+ [
+ 40500,
+ 0,
+ 0
+ ],
+ [
+ 40636.3633,
+ 3,
+ 0
+ ],
+ [
+ 40772.7266,
+ 1,
+ 0
+ ],
+ [
+ 40909.09,
+ 3,
+ 0
+ ],
+ [
+ 41045.4531,
+ 0,
+ 0
+ ],
+ [
+ 41181.8164,
+ 1,
+ 0
+ ]
+ ],
+ "mustHitSection": false
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 41454.543,
+ 0,
+ 0
+ ],
+ [
+ 41727.27,
+ 1,
+ 0
+ ],
+ [
+ 41863.6367,
+ 3,
+ 0
+ ],
+ [
+ 42000,
+ 0,
+ 136.363632
+ ],
+ [
+ 42272.7266,
+ 1,
+ 0
+ ],
+ [
+ 42545.4531,
+ 2,
+ 0
+ ],
+ [
+ 42681.8164,
+ 3,
+ 0
+ ],
+ [
+ 42818.18,
+ 0,
+ 0
+ ],
+ [
+ 42954.543,
+ 0,
+ 0
+ ],
+ [
+ 43090.9063,
+ 7,
+ 0
+ ],
+ [
+ 43090.9063,
+ 3,
+ 0
+ ],
+ [
+ 43227.27,
+ 4,
+ 0
+ ],
+ [
+ 43227.27,
+ 0,
+ 0
+ ],
+ [
+ 43363.6367,
+ 5,
+ 0
+ ],
+ [
+ 43363.6367,
+ 0,
+ 0
+ ],
+ [
+ 43500,
+ 7,
+ 0
+ ],
+ [
+ 43500,
+ 1,
+ 0
+ ]
+ ],
+ "mustHitSection": false
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 43636.3633,
+ 2,
+ 136.363632
+ ],
+ [
+ 43909.09,
+ 2,
+ 0
+ ],
+ [
+ 44045.4531,
+ 3,
+ 0
+ ],
+ [
+ 44181.8164,
+ 0,
+ 0
+ ],
+ [
+ 44318.18,
+ 1,
+ 0
+ ],
+ [
+ 44454.543,
+ 3,
+ 0
+ ],
+ [
+ 44590.9063,
+ 1,
+ 0
+ ],
+ [
+ 44727.27,
+ 3,
+ 0
+ ],
+ [
+ 44863.6367,
+ 0,
+ 0
+ ],
+ [
+ 45000,
+ 3,
+ 0
+ ],
+ [
+ 45136.3633,
+ 1,
+ 0
+ ],
+ [
+ 45272.7266,
+ 3,
+ 0
+ ],
+ [
+ 45409.09,
+ 0,
+ 0
+ ],
+ [
+ 45545.4531,
+ 1,
+ 0
+ ]
+ ],
+ "mustHitSection": true
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 45818.18,
+ 0,
+ 0
+ ],
+ [
+ 46090.9063,
+ 1,
+ 0
+ ],
+ [
+ 46227.27,
+ 3,
+ 0
+ ],
+ [
+ 46363.6367,
+ 0,
+ 136.363632
+ ],
+ [
+ 46636.3633,
+ 1,
+ 0
+ ],
+ [
+ 46909.09,
+ 2,
+ 0
+ ],
+ [
+ 47045.4531,
+ 3,
+ 0
+ ],
+ [
+ 47181.8164,
+ 0,
+ 0
+ ],
+ [
+ 47318.18,
+ 0,
+ 0
+ ],
+ [
+ 47454.543,
+ 3,
+ 0
+ ],
+ [
+ 47590.9063,
+ 0,
+ 0
+ ],
+ [
+ 47727.27,
+ 0,
+ 0
+ ],
+ [
+ 47863.6367,
+ 1,
+ 0
+ ]
+ ],
+ "mustHitSection": true
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 48272.7266,
+ 2,
+ 0
+ ],
+ [
+ 48409.09,
+ 3,
+ 0
+ ],
+ [
+ 48545.4531,
+ 0,
+ 0
+ ],
+ [
+ 48681.8164,
+ 3,
+ 0
+ ],
+ [
+ 48818.18,
+ 0,
+ 0
+ ],
+ [
+ 48954.543,
+ 2,
+ 0
+ ],
+ [
+ 49090.9063,
+ 3,
+ 0
+ ],
+ [
+ 49363.6367,
+ 3,
+ 0
+ ],
+ [
+ 49636.3633,
+ 1,
+ 0
+ ],
+ [
+ 49909.09,
+ 0,
+ 0
+ ]
+ ],
+ "mustHitSection": false
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 50454.543,
+ 3,
+ 0
+ ],
+ [
+ 50590.9063,
+ 1,
+ 0
+ ],
+ [
+ 50727.27,
+ 0,
+ 0
+ ],
+ [
+ 50863.6367,
+ 3,
+ 0
+ ],
+ [
+ 51000,
+ 2,
+ 0
+ ],
+ [
+ 51272.7266,
+ 0,
+ 0
+ ],
+ [
+ 51545.4531,
+ 2,
+ 0
+ ],
+ [
+ 51818.18,
+ 0,
+ 0
+ ],
+ [
+ 52090.9063,
+ 1,
+ 0
+ ]
+ ],
+ "mustHitSection": false
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 52363.6328,
+ 6,
+ 545.4545
+ ],
+ [
+ 52636.3633,
+ 2,
+ 0
+ ],
+ [
+ 52772.7266,
+ 3,
+ 0
+ ],
+ [
+ 52909.09,
+ 0,
+ 0
+ ],
+ [
+ 53045.4531,
+ 3,
+ 0
+ ],
+ [
+ 53181.8164,
+ 0,
+ 0
+ ],
+ [
+ 53318.18,
+ 2,
+ 0
+ ],
+ [
+ 53454.543,
+ 3,
+ 0
+ ],
+ [
+ 53727.27,
+ 3,
+ 0
+ ],
+ [
+ 54000,
+ 1,
+ 0
+ ],
+ [
+ 54272.7266,
+ 0,
+ 0
+ ]
+ ],
+ "mustHitSection": true
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 54818.18,
+ 3,
+ 0
+ ],
+ [
+ 54954.543,
+ 1,
+ 0
+ ],
+ [
+ 55090.9063,
+ 0,
+ 0
+ ],
+ [
+ 55227.27,
+ 3,
+ 0
+ ],
+ [
+ 55363.6328,
+ 2,
+ 0
+ ],
+ [
+ 55636.3633,
+ 0,
+ 0
+ ],
+ [
+ 55909.09,
+ 2,
+ 0
+ ],
+ [
+ 56181.8164,
+ 0,
+ 0
+ ],
+ [
+ 56454.543,
+ 1,
+ 0
+ ]
+ ],
+ "mustHitSection": true
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 56727.27,
+ 6,
+ 409.090881
+ ],
+ [
+ 56727.27,
+ 2,
+ 409.090881
+ ],
+ [
+ 57272.7266,
+ 3,
+ 0
+ ],
+ [
+ 57272.7266,
+ 7,
+ 0
+ ],
+ [
+ 57409.09,
+ 2,
+ 0
+ ],
+ [
+ 57409.09,
+ 6,
+ 0
+ ],
+ [
+ 57545.4531,
+ 3,
+ 0
+ ],
+ [
+ 57545.4531,
+ 7,
+ 0
+ ],
+ [
+ 57681.8164,
+ 2,
+ 0
+ ],
+ [
+ 57681.8164,
+ 6,
+ 0
+ ],
+ [
+ 57818.18,
+ 0,
+ 0
+ ],
+ [
+ 57818.18,
+ 4,
+ 0
+ ],
+ [
+ 57954.543,
+ 1,
+ 0
+ ],
+ [
+ 57954.543,
+ 5,
+ 0
+ ],
+ [
+ 58090.9063,
+ 0,
+ 0
+ ],
+ [
+ 58090.9063,
+ 4,
+ 0
+ ],
+ [
+ 58227.27,
+ 1,
+ 0
+ ],
+ [
+ 58227.27,
+ 5,
+ 0
+ ],
+ [
+ 58363.6328,
+ 0,
+ 0
+ ],
+ [
+ 58363.6328,
+ 4,
+ 0
+ ],
+ [
+ 58500,
+ 3,
+ 0
+ ],
+ [
+ 58500,
+ 7,
+ 0
+ ],
+ [
+ 58636.3633,
+ 0,
+ 0
+ ],
+ [
+ 58636.3633,
+ 4,
+ 0
+ ],
+ [
+ 58772.7266,
+ 3,
+ 0
+ ],
+ [
+ 58772.7266,
+ 7,
+ 0
+ ]
+ ],
+ "mustHitSection": false
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 58909.09,
+ 1,
+ 409.090881
+ ],
+ [
+ 58909.09,
+ 5,
+ 409.090881
+ ],
+ [
+ 59454.543,
+ 4,
+ 0
+ ],
+ [
+ 59454.543,
+ 0,
+ 0
+ ],
+ [
+ 59590.9063,
+ 7,
+ 0
+ ],
+ [
+ 59590.9063,
+ 3,
+ 0
+ ],
+ [
+ 59727.27,
+ 4,
+ 0
+ ],
+ [
+ 59727.27,
+ 0,
+ 0
+ ],
+ [
+ 59863.6328,
+ 7,
+ 0
+ ],
+ [
+ 59863.6328,
+ 3,
+ 0
+ ],
+ [
+ 60000,
+ 6,
+ 136.363632
+ ],
+ [
+ 60000,
+ 2,
+ 136.363632
+ ],
+ [
+ 60272.7266,
+ 7,
+ 0
+ ],
+ [
+ 60272.7266,
+ 3,
+ 0
+ ],
+ [
+ 60545.4531,
+ 7,
+ 0
+ ],
+ [
+ 60545.4531,
+ 3,
+ 0
+ ],
+ [
+ 60818.18,
+ 5,
+ 0
+ ],
+ [
+ 60818.18,
+ 1,
+ 0
+ ]
+ ],
+ "mustHitSection": false
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 61090.9063,
+ 0,
+ 409.090881
+ ],
+ [
+ 61090.9063,
+ 7,
+ 409.090881
+ ],
+ [
+ 61636.3633,
+ 4,
+ 409.090881
+ ],
+ [
+ 61636.3633,
+ 3,
+ 409.090881
+ ],
+ [
+ 62181.8164,
+ 2,
+ 0
+ ],
+ [
+ 62181.8164,
+ 6,
+ 0
+ ],
+ [
+ 62454.543,
+ 2,
+ 0
+ ],
+ [
+ 62454.543,
+ 6,
+ 0
+ ],
+ [
+ 62590.9063,
+ 2,
+ 0
+ ],
+ [
+ 62590.9063,
+ 6,
+ 0
+ ],
+ [
+ 62727.27,
+ 3,
+ 409.090881
+ ],
+ [
+ 62727.27,
+ 4,
+ 409.090881
+ ]
+ ],
+ "mustHitSection": true
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 63272.7266,
+ 5,
+ 409.090881
+ ],
+ [
+ 63272.7266,
+ 1,
+ 409.090881
+ ],
+ [
+ 63818.18,
+ 7,
+ 409.090881
+ ],
+ [
+ 63818.18,
+ 3,
+ 409.090881
+ ],
+ [
+ 64363.6328,
+ 6,
+ 409.090881
+ ],
+ [
+ 64363.6328,
+ 2,
+ 409.090881
+ ],
+ [
+ 64909.09,
+ 4,
+ 0
+ ],
+ [
+ 64909.09,
+ 0,
+ 0
+ ],
+ [
+ 65181.8164,
+ 7,
+ 0
+ ],
+ [
+ 65181.8164,
+ 3,
+ 0
+ ]
+ ],
+ "mustHitSection": true
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 65454.543,
+ 5,
+ 545.4545
+ ],
+ [
+ 65454.543,
+ 2,
+ 0
+ ],
+ [
+ 65727.27,
+ 2,
+ 0
+ ],
+ [
+ 65863.63,
+ 3,
+ 0
+ ],
+ [
+ 66000,
+ 0,
+ 0
+ ],
+ [
+ 66272.73,
+ 1,
+ 0
+ ],
+ [
+ 66545.45,
+ 3,
+ 0
+ ],
+ [
+ 66681.81,
+ 0,
+ 0
+ ],
+ [
+ 66818.18,
+ 3,
+ 0
+ ],
+ [
+ 67090.91,
+ 3,
+ 0
+ ],
+ [
+ 67227.27,
+ 0,
+ 0
+ ],
+ [
+ 67363.63,
+ 1,
+ 0
+ ]
+ ],
+ "mustHitSection": false
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 67909.0859,
+ 1,
+ 0
+ ],
+ [
+ 68045.45,
+ 3,
+ 0
+ ],
+ [
+ 68181.81,
+ 0,
+ 136.363632
+ ],
+ [
+ 68454.55,
+ 1,
+ 0
+ ],
+ [
+ 68727.27,
+ 2,
+ 0
+ ],
+ [
+ 69000,
+ 0,
+ 0
+ ],
+ [
+ 69272.73,
+ 3,
+ 0
+ ],
+ [
+ 69545.45,
+ 1,
+ 0
+ ],
+ [
+ 68818.1818181819,
+ 0,
+ 0
+ ],
+ [
+ 68909.090909091,
+ 3,
+ 0
+ ],
+ [
+ 69181.8181818182,
+ 0,
+ 0
+ ],
+ [
+ 69363.6363636364,
+ 0,
+ 0
+ ],
+ [
+ 69454.5454545455,
+ 3,
+ 0
+ ],
+ [
+ 69727.2727272728,
+ 0,
+ 0
+ ]
+ ],
+ "mustHitSection": false
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 69818.18,
+ 5,
+ 409.090881
+ ],
+ [
+ 70090.91,
+ 2,
+ 0
+ ],
+ [
+ 70227.27,
+ 3,
+ 0
+ ],
+ [
+ 70363.63,
+ 0,
+ 0
+ ],
+ [
+ 70363.63,
+ 7,
+ 409.090881
+ ],
+ [
+ 70636.36,
+ 1,
+ 0
+ ],
+ [
+ 70909.0859,
+ 3,
+ 0
+ ],
+ [
+ 70909.0859,
+ 6,
+ 409.090881
+ ],
+ [
+ 71045.45,
+ 0,
+ 0
+ ],
+ [
+ 71181.81,
+ 3,
+ 0
+ ],
+ [
+ 71454.55,
+ 3,
+ 0
+ ],
+ [
+ 71454.55,
+ 7,
+ 409.090881
+ ],
+ [
+ 71590.91,
+ 0,
+ 0
+ ],
+ [
+ 71727.27,
+ 1,
+ 0
+ ]
+ ],
+ "mustHitSection": true
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 72000,
+ 5,
+ 409.090881
+ ],
+ [
+ 72272.73,
+ 1,
+ 0
+ ],
+ [
+ 72409.0859,
+ 3,
+ 0
+ ],
+ [
+ 72545.45,
+ 0,
+ 136.363632
+ ],
+ [
+ 72545.45,
+ 7,
+ 409.090881
+ ],
+ [
+ 72818.18,
+ 1,
+ 0
+ ],
+ [
+ 73090.91,
+ 2,
+ 0
+ ],
+ [
+ 73363.63,
+ 0,
+ 0
+ ],
+ [
+ 73636.36,
+ 3,
+ 0
+ ],
+ [
+ 73909.0859,
+ 1,
+ 0
+ ],
+ [
+ 73181.8181818182,
+ 0,
+ 0
+ ],
+ [
+ 73272.7272727273,
+ 3,
+ 0
+ ],
+ [
+ 73545.4545454546,
+ 0,
+ 0
+ ],
+ [
+ 73727.2727272727,
+ 0,
+ 0
+ ],
+ [
+ 73818.1818181819,
+ 3,
+ 0
+ ],
+ [
+ 74090.9090909091,
+ 0,
+ 0
+ ]
+ ],
+ "mustHitSection": true
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 74181.81,
+ 0,
+ 136.363632
+ ],
+ [
+ 74181.81,
+ 5,
+ 409.090881
+ ],
+ [
+ 74454.55,
+ 2,
+ 0
+ ],
+ [
+ 74590.91,
+ 3,
+ 0
+ ],
+ [
+ 74727.27,
+ 0,
+ 0
+ ],
+ [
+ 74727.27,
+ 7,
+ 409.090881
+ ],
+ [
+ 74863.63,
+ 1,
+ 0
+ ],
+ [
+ 75000,
+ 3,
+ 0
+ ],
+ [
+ 75136.36,
+ 1,
+ 0
+ ],
+ [
+ 75272.73,
+ 3,
+ 0
+ ],
+ [
+ 75272.73,
+ 6,
+ 409.090881
+ ],
+ [
+ 75409.0859,
+ 0,
+ 0
+ ],
+ [
+ 75545.45,
+ 3,
+ 0
+ ],
+ [
+ 75681.81,
+ 1,
+ 0
+ ],
+ [
+ 75818.18,
+ 3,
+ 0
+ ],
+ [
+ 75818.18,
+ 7,
+ 409.090881
+ ],
+ [
+ 75954.55,
+ 0,
+ 0
+ ],
+ [
+ 76090.91,
+ 1,
+ 0
+ ]
+ ],
+ "mustHitSection": false
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 76363.63,
+ 0,
+ 0
+ ],
+ [
+ 76363.63,
+ 5,
+ 409.090881
+ ],
+ [
+ 76636.36,
+ 1,
+ 0
+ ],
+ [
+ 76772.73,
+ 3,
+ 0
+ ],
+ [
+ 76909.0859,
+ 0,
+ 136.363632
+ ],
+ [
+ 76909.0859,
+ 7,
+ 409.090881
+ ],
+ [
+ 77181.81,
+ 1,
+ 0
+ ],
+ [
+ 77454.55,
+ 2,
+ 0
+ ],
+ [
+ 77454.55,
+ 6,
+ 409.090881
+ ],
+ [
+ 77590.91,
+ 3,
+ 0
+ ],
+ [
+ 77727.27,
+ 0,
+ 0
+ ],
+ [
+ 77863.63,
+ 0,
+ 0
+ ],
+ [
+ 78000,
+ 3,
+ 0
+ ],
+ [
+ 78000,
+ 7,
+ 0
+ ],
+ [
+ 78136.36,
+ 0,
+ 0
+ ],
+ [
+ 78136.36,
+ 4,
+ 0
+ ],
+ [
+ 78272.73,
+ 0,
+ 0
+ ],
+ [
+ 78272.73,
+ 4,
+ 0
+ ],
+ [
+ 78409.0859,
+ 1,
+ 0
+ ],
+ [
+ 78409.0859,
+ 5,
+ 0
+ ]
+ ],
+ "mustHitSection": false
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 78545.45,
+ 0,
+ 136.363632
+ ],
+ [
+ 78818.18,
+ 2,
+ 0
+ ],
+ [
+ 78954.55,
+ 3,
+ 0
+ ],
+ [
+ 79090.91,
+ 0,
+ 0
+ ],
+ [
+ 79227.27,
+ 1,
+ 0
+ ],
+ [
+ 79363.63,
+ 3,
+ 0
+ ],
+ [
+ 79500,
+ 1,
+ 0
+ ],
+ [
+ 79636.36,
+ 3,
+ 0
+ ],
+ [
+ 79772.73,
+ 0,
+ 0
+ ],
+ [
+ 79909.0859,
+ 3,
+ 0
+ ],
+ [
+ 80045.45,
+ 1,
+ 0
+ ],
+ [
+ 80181.81,
+ 3,
+ 0
+ ],
+ [
+ 80318.18,
+ 0,
+ 0
+ ],
+ [
+ 80454.55,
+ 1,
+ 0
+ ]
+ ],
+ "mustHitSection": true
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 80727.27,
+ 0,
+ 0
+ ],
+ [
+ 81000,
+ 1,
+ 0
+ ],
+ [
+ 81136.36,
+ 3,
+ 0
+ ],
+ [
+ 81272.73,
+ 0,
+ 136.363632
+ ],
+ [
+ 81545.45,
+ 1,
+ 0
+ ],
+ [
+ 81818.18,
+ 2,
+ 0
+ ],
+ [
+ 81954.54,
+ 3,
+ 0
+ ],
+ [
+ 82090.91,
+ 0,
+ 0
+ ],
+ [
+ 82227.27,
+ 0,
+ 0
+ ],
+ [
+ 82363.63,
+ 3,
+ 0
+ ],
+ [
+ 82500,
+ 0,
+ 0
+ ],
+ [
+ 82636.36,
+ 0,
+ 0
+ ],
+ [
+ 82772.73,
+ 1,
+ 0
+ ]
+ ],
+ "mustHitSection": true
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 82909.0859,
+ 7,
+ 1090.909
+ ],
+ [
+ 83181.81,
+ 2,
+ 0
+ ],
+ [
+ 83454.54,
+ 3,
+ 0
+ ],
+ [
+ 83727.27,
+ 2,
+ 0
+ ],
+ [
+ 83863.63,
+ 3,
+ 0
+ ],
+ [
+ 84136.36,
+ 0,
+ 0
+ ],
+ [
+ 84409.0859,
+ 2,
+ 0
+ ],
+ [
+ 84545.45,
+ 3,
+ 0
+ ],
+ [
+ 84818.18,
+ 0,
+ 0
+ ],
+ [
+ 84954.54,
+ 3,
+ 0
+ ]
+ ],
+ "mustHitSection": false
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 85363.63,
+ 2,
+ 0
+ ],
+ [
+ 85636.36,
+ 3,
+ 0
+ ],
+ [
+ 85909.0859,
+ 2,
+ 0
+ ],
+ [
+ 86045.45,
+ 3,
+ 0
+ ],
+ [
+ 86318.18,
+ 0,
+ 0
+ ],
+ [
+ 86590.91,
+ 2,
+ 0
+ ],
+ [
+ 86727.27,
+ 3,
+ 0
+ ],
+ [
+ 86863.63,
+ 0,
+ 0
+ ],
+ [
+ 87000,
+ 1,
+ 0
+ ]
+ ],
+ "mustHitSection": true
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [
+ [
+ 87272.73,
+ 2,
+ 545.4545
+ ]
+ ],
+ "mustHitSection": true
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [],
+ "mustHitSection": true
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [],
+ "mustHitSection": true
+ },
+ {
+ "lengthInSteps": 16,
+ "sectionNotes": [],
+ "mustHitSection": true
+ },
+ {
+ "sectionNotes": [],
+ "typeOfSection": 0,
+ "lengthInSteps": 16,
+ "altAnim": false,
+ "mustHitSection": true,
+ "changeBPM": false,
+ "bpm": 110
+ },
+ {
+ "lengthInSteps": 16,
+ "altAnim": false,
+ "typeOfSection": 0,
+ "sectionNotes": [],
+ "bpm": 110,
+ "changeBPM": false,
+ "mustHitSection": true
+ }
+ ],
+ "gfVersion": "gf-car",
+ "song": "Satin Panties",
+ "stage": "limo",
+ "needsVoices": true,
+ "validScore": true,
+ "speed": 1.8,
+ "bpm": 110
+ }
+}
\ No newline at end of file
diff --git a/assets/preload/data/test/test.json b/assets/preload/data/test/test.json
new file mode 100644
index 0000000..6ccba5e
--- /dev/null
+++ b/assets/preload/data/test/test.json
@@ -0,0 +1 @@
+{"song": {"song": "Test", "notes": [{"lengthInSteps": 16, "bpm": 95.0, "changeBPM": false, "mustHitSection": true, "typeOfSection": 0, "sectionNotes": [[668.578947368421, 3, 947.3684210526317], [1615.9473684210527, 1, 631.578947368421], [2247.5263157894738, 0, 315.7894736842104]]}, {"lengthInSteps": 16, "bpm": 95.0, "changeBPM": false, "mustHitSection": true, "typeOfSection": 0, "sectionNotes": [[2563.315789473684, 3, 631.5789473684213], [3194.8947368421054, 2, 631.5789473684208], [3826.4736842105262, 1, 631.5789473684213], [4773.8421052631575, 1, 0]]}, {"lengthInSteps": 16, "bpm": 95.0, "changeBPM": false, "mustHitSection": true, "typeOfSection": 0, "sectionNotes": [[5089.631578947368, 2, 0], [5563.315789473684, 1, 0], [5879.105263157895, 3, 0], [6037.0, 1, 0], [6194.894736842105, 0, 0], [6352.789473684211, 2, 315.78947368420995], [6668.578947368421, 1, 315.78947368421086], [6984.368421052632, 0, 0], [7142.263157894737, 1, 0], [7300.1578947368425, 2, 0], [7458.0526315789475, 0, 0]]}, {"lengthInSteps": 16, "bpm": 95.0, "changeBPM": false, "mustHitSection": true, "typeOfSection": 0, "sectionNotes": [[7615.9473684210525, 1, 1578.9473684210525], [7615.9473684210525, 3, 947.3684210526326], [8721.21052631579, 3, 0], [8879.105263157895, 0, 0], [9194.894736842105, 2, 0], [9352.78947368421, 1, 0], [9352.78947368421, 3, 0], [9510.684210526315, 0, 0], [9510.684210526315, 2, 0], [9668.578947368422, 0, 0], [9668.578947368422, 2, 0], [9826.473684210527, 1, 0], [9826.473684210527, 3, 0], [9984.368421052632, 0, 0], [9984.368421052632, 2, 0]]}, {"lengthInSteps": 16, "bpm": 95.0, "changeBPM": false, "mustHitSection": true, "typeOfSection": 0, "sectionNotes": [[10142.263157894737, 3, 0], [10458.052631578947, 3, 0], [10773.842105263158, 3, 0], [11089.631578947368, 1, 0], [11247.526315789473, 2, 0], [11405.421052631578, 0, 0], [11721.21052631579, 0, 0], [12037.0, 0, 0], [12194.894736842105, 2, 0], [12352.78947368421, 1, 0], [12510.684210526315, 2, 0]]}, {"lengthInSteps": 16, "bpm": 95.0, "changeBPM": false, "mustHitSection": true, "typeOfSection": 0, "sectionNotes": [[12668.578947368422, 3, 0], [12984.368421052632, 1, 0], [13300.157894736842, 2, 315.78947368421177], [13615.947368421053, 0, 0], [13773.842105263158, 1, 0], [13931.736842105263, 3, 1263.1578947368416], [14563.315789473685, 0, 0], [14721.21052631579, 1, 0], [14879.105263157895, 2, 0], [15037.0, 1, 0]]}, {"lengthInSteps": 16, "bpm": 95.0, "changeBPM": false, "mustHitSection": true, "typeOfSection": 0, "sectionNotes": [[15194.894736842105, 0, 0], [15352.78947368421, 2, 0], [15510.684210526315, 0, 631.5789473684217], [16142.263157894737, 2, 0], [16300.157894736842, 1, 0], [16458.052631578947, 0, 0], [16773.842105263157, 0, 0], [17089.63157894737, 0, 0], [17405.42105263158, 1, 315.78947368420995]]}, {"lengthInSteps": 16, "bpm": 95.0, "changeBPM": false, "mustHitSection": true, "typeOfSection": 0, "sectionNotes": [[17721.21052631579, 0, 1263.1578947368398], [17721.21052631579, 3, 1263.1578947368398], [18984.36842105263, 1, 0], [18984.36842105263, 2, 0], [19300.157894736843, 1, 0], [19300.157894736843, 2, 0], [19615.947368421053, 1, 0], [19615.947368421053, 2, 0], [19826.473684210527, 1, 0], [19826.473684210527, 2, 0], [20037.0, 1, 0], [20037.0, 2, 0]]}, {"lengthInSteps": 16, "bpm": 95.0, "changeBPM": false, "mustHitSection": true, "typeOfSection": 0, "sectionNotes": [[20247.526315789473, 3, 631.5789473684199], [20879.105263157893, 1, 0], [21194.894736842107, 1, 0], [21510.684210526317, 1, 0], [21826.473684210527, 1, 0], [22142.263157894737, 1, 0], [22300.157894736843, 2, 0], [22458.052631578947, 0, 0], [22615.947368421053, 2, 0]]}, {"lengthInSteps": 16, "bpm": 95.0, "changeBPM": false, "mustHitSection": true, "typeOfSection": 0, "sectionNotes": [[22773.842105263157, 3, 0], [22931.736842105263, 1, 0], [23089.63157894737, 2, 0], [23405.42105263158, 1, 0], [23721.21052631579, 1, 0], [24037.0, 1, 0], [24352.78947368421, 2, 0], [24510.684210526317, 3, 0], [24668.57894736842, 1, 0], [24826.473684210527, 2, 0], [24984.36842105263, 1, 0], [25142.263157894737, 0, 473.68421052631675]]}, {"lengthInSteps": 16, "bpm": 95.0, "changeBPM": false, "mustHitSection": true, "typeOfSection": 0, "sectionNotes": [[25773.842105263157, 2, 0], [25931.736842105263, 3, 0], [26089.63157894737, 1, 0], [26247.526315789473, 2, 0], [26563.315789473683, 1, 0], [26879.105263157893, 0, 0], [27194.894736842107, 0, 0], [27352.78947368421, 1, 0], [27510.684210526317, 2, 0], [27668.57894736842, 3, 0]]}, {"lengthInSteps": 16, "bpm": 95.0, "changeBPM": false, "mustHitSection": true, "typeOfSection": 0, "sectionNotes": [[27826.473684210527, 2, 0], [28142.263157894737, 2, 0], [28458.052631578947, 3, 1894.7368421052633], [28615.947368421053, 2, 0], [28773.842105263157, 1, 0], [28931.736842105263, 0, 0], [29089.63157894737, 2, 0], [29247.526315789473, 1, 0], [29405.42105263158, 0, 0], [29563.315789473683, 1, 0], [29879.105263157893, 2, 0], [30037.0, 1, 0], [30194.894736842107, 0, 0]]}, {"lengthInSteps": 16, "bpm": 95.0, "changeBPM": false, "mustHitSection": true, "typeOfSection": 0, "sectionNotes": [[30352.78947368421, 2, 0], [30431.736842105263, 1, 0], [30510.684210526317, 0, 0], [30668.57894736842, 0, 0], [30826.473684210527, 0, 0], [30905.42105263158, 1, 0], [30984.36842105263, 2, 0], [31142.263157894737, 3, 0], [31300.157894736843, 1, 0], [31458.052631578947, 2, 0], [31615.947368421053, 0, 0], [31773.842105263157, 2, 0], [31931.736842105263, 1, 0], [32089.63157894737, 2, 0], [32405.42105263158, 2, 0], [32721.21052631579, 2, 0]]}, {"lengthInSteps": 16, "bpm": 95.0, "changeBPM": false, "mustHitSection": true, "typeOfSection": 0, "sectionNotes": [[32879.10526315789, 2, 0], [32958.05263157895, 3, 0], [33037.0, 1, 0], [33194.89473684211, 0, 0], [33352.78947368421, 2, 0], [33510.68421052631, 1, 0], [33668.57894736842, 2, 0], [33826.47368421053, 3, 0], [33984.36842105263, 1, 0], [34063.31578947369, 2, 0], [34142.26315789474, 0, 0], [34300.15789473684, 0, 0], [34458.05263157895, 1, 0], [34615.94736842105, 2, 0], [34694.89473684211, 1, 0], [34773.84210526316, 2, 0], [34931.73684210526, 3, 0], [35089.63157894737, 1, 0], [35247.52631578947, 2, 0]]}, {"lengthInSteps": 16, "bpm": 95.0, "changeBPM": false, "mustHitSection": true, "typeOfSection": 0, "sectionNotes": [[35405.42105263158, 0, 0], [35563.31578947369, 1, 0], [35721.21052631579, 2, 0], [35879.10526315789, 3, 0], [36194.89473684211, 2, 0], [36352.78947368421, 1, 0], [36510.68421052631, 0, 0], [36826.47368421053, 2, 0], [36984.36842105263, 1, 0], [37142.26315789474, 0, 236.84210526315292], [37458.05263157895, 0, 236.8421052631602], [37773.84210526316, 0, 0]]}, {"lengthInSteps": 16, "bpm": 95.0, "changeBPM": false, "mustHitSection": true, "typeOfSection": 0, "sectionNotes": [[37931.73684210526, 2, 0], [38089.63157894737, 1, 0], [38247.52631578947, 0, 0], [38405.42105263158, 1, 0], [38563.31578947369, 3, 0], [38721.21052631579, 3, 0], [38879.10526315789, 2, 552.6315789473665], [39510.68421052631, 1, 315.7894736842136], [39826.47368421053, 3, 1263.1578947368398]]}, {"lengthInSteps": 16, "bpm": 95.0, "changeBPM": false, "mustHitSection": true, "typeOfSection": 0, "sectionNotes": [[41721.21052631579, 1, 631.5789473684272], [42431.73684210526, 0, 0], [42510.68421052631, 1, 0], [42589.63157894737, 2, 0], [42668.57894736842, 3, 0], [42747.52631578947, 2, 0], [42826.47368421053, 1, 0], [42905.42105263158, 0, 0]]}, {"lengthInSteps": 16, "bpm": 95.0, "changeBPM": false, "mustHitSection": true, "typeOfSection": 0, "sectionNotes": [[42984.36842105263, 3, 631.5789473684199], [43615.94736842105, 1, 552.6315789473665], [44247.52631578947, 1, 631.5789473684199], [44958.05263157895, 0, 0], [45037.0, 1, 0], [45115.94736842105, 2, 0], [45194.89473684211, 3, 0], [45273.84210526316, 1, 0], [45352.78947368421, 2, 0], [45431.73684210526, 1, 0]]}, {"lengthInSteps": 16, "bpm": 95.0, "changeBPM": false, "mustHitSection": true, "typeOfSection": 0, "sectionNotes": [[45510.68421052631, 3, 631.5789473684272], [46142.26315789474, 1, 0], [46142.26315789474, 2, 631.5789473684199], [46300.15789473684, 0, 0], [46458.05263157895, 1, 0], [46615.94736842105, 0, 0], [46773.84210526316, 1, 0], [46773.84210526316, 3, 631.5789473684199], [46931.73684210526, 0, 0], [47089.63157894737, 1, 0], [47247.52631578947, 0, 0], [47405.42105263158, 1, 0], [47405.42105263158, 2, 631.5789473684199], [47484.36842105263, 0, 0], [47563.31578947369, 1, 0], [47642.26315789474, 0, 0], [47721.21052631579, 1, 0], [47800.15789473684, 0, 0], [47879.10526315789, 1, 0], [47958.05263157895, 0, 0]]}, {"lengthInSteps": 16, "bpm": 95.0, "changeBPM": false, "mustHitSection": true, "typeOfSection": 0, "sectionNotes": [[48037.0, 1, 0], [48194.89473684211, 2, 0], [48352.78947368421, 1, 315.7894736842063], [48668.57894736842, 2, 236.8421052631602], [48984.36842105263, 1, 0], [49063.31578947369, 2, 0], [49142.26315789474, 3, 0], [49221.21052631579, 2, 0], [49300.15789473684, 0, 631.5789473684199], [49458.05263157895, 1, 0], [49615.94736842105, 2, 0], [49773.84210526316, 1, 0], [49931.73684210526, 2, 0], [50010.68421052631, 0, 0], [50089.63157894737, 1, 0], [50168.57894736842, 2, 0], [50247.52631578947, 1, 0], [50326.47368421053, 2, 0], [50405.42105263158, 3, 0], [50484.36842105263, 2, 0]]}, {"lengthInSteps": 16, "bpm": 95.0, "changeBPM": false, "mustHitSection": true, "typeOfSection": 0, "sectionNotes": [[50563.31578947369, 1, 631.5789473684199], [50563.31578947369, 3, 631.5789473684199], [51194.89473684211, 0, 631.5789473684199], [51194.89473684211, 2, 631.5789473684199], [51826.47368421053, 3, 0], [51984.36842105263, 2, 0], [52142.26315789474, 1, 0], [52300.15789473684, 3, 0], [52458.05263157895, 2, 0], [52615.94736842105, 1, 0], [52773.84210526316, 3, 0], [52931.73684210526, 2, 0]]}, {"lengthInSteps": 16, "bpm": 95.0, "changeBPM": false, "mustHitSection": true, "typeOfSection": 0, "sectionNotes": [[53089.63157894737, 1, 0], [53247.52631578947, 3, 0], [53405.42105263158, 2, 0], [53563.31578947369, 1, 0], [53721.21052631579, 3, 0], [53879.10526315789, 2, 0], [54037.0, 1, 0], [54194.89473684211, 0, 0], [54352.78947368421, 1, 0], [54510.68421052631, 2, 0], [54668.57894736842, 3, 0], [54826.47368421053, 2, 0], [54984.36842105263, 1, 0], [55142.26315789474, 3, 0], [55300.15789473684, 2, 0], [55458.05263157895, 1, 0]]}, {"lengthInSteps": 16, "bpm": 95.0, "changeBPM": false, "mustHitSection": true, "typeOfSection": 0, "sectionNotes": [[55615.94736842105, 3, 0], [55773.84210526316, 2, 0], [55931.73684210526, 1, 0], [56089.63157894737, 3, 0], [56247.52631578947, 2, 0], [56405.42105263158, 1, 0], [56563.31578947369, 3, 0], [56721.21052631579, 2, 0], [56879.10526315789, 1, 0], [57037.0, 0, 0], [57194.89473684211, 1, 0], [57352.78947368421, 0, 0], [57510.68421052631, 1, 0], [57668.57894736842, 2, 0], [57826.47368421053, 0, 0], [57984.36842105263, 1, 0]]}, {"lengthInSteps": 16, "bpm": 95.0, "changeBPM": false, "mustHitSection": true, "typeOfSection": 0, "sectionNotes": [[58142.26315789474, 2, 0], [58300.15789473684, 3, 0], [58458.05263157895, 2, 0], [58615.94736842105, 1, 0], [58773.84210526316, 0, 0], [58931.73684210526, 1, 0], [59089.63157894737, 2, 0], [59247.52631578947, 3, 0], [59405.42105263158, 2, 0], [59563.31578947369, 3, 0], [59721.21052631579, 0, 0], [59879.10526315789, 1, 0], [60037.0, 2, 0], [60194.89473684211, 0, 0], [60352.78947368421, 1, 0], [60510.68421052631, 2, 0]]}, {"lengthInSteps": 16, "bpm": 95.0, "changeBPM": false, "mustHitSection": true, "typeOfSection": 0, "sectionNotes": [[60668.57894736842, 3, 0], [60826.47368421053, 2, 0], [60984.36842105263, 0, 0], [61142.26315789474, 1, 0], [61300.15789473684, 2, 0], [61458.05263157895, 0, 0], [61615.94736842105, 1, 0], [61773.84210526316, 2, 0], [61931.73684210526, 3, 0], [62089.63157894737, 2, 0], [62247.52631578947, 1, 2210.5263157894733]]}, {"lengthInSteps": 16, "bpm": 95.0, "changeBPM": false, "mustHitSection": true, "typeOfSection": 0, "sectionNotes": []}], "bpm": 95.0, "sections": 0, "needsVoices": false, "player1": "bf", "player2": "gf", "sectionLengths": [], "speed": 3}}
\ No newline at end of file
diff --git a/assets/preload/data/weekNames.txt b/assets/preload/data/weekNames.txt
new file mode 100644
index 0000000..09b7036
--- /dev/null
+++ b/assets/preload/data/weekNames.txt
@@ -0,0 +1,7 @@
+Tutorial
+Daddy Dearest
+Spooky Month
+PICO
+MOMMY MUST MURDER
+RED SNOW
+Hating Simulator ft. Moawling
\ No newline at end of file
diff --git a/assets/preload/images/iconGrid.png b/assets/preload/images/iconGrid.png
index 9d3b1c0..876010a 100644
Binary files a/assets/preload/images/iconGrid.png and b/assets/preload/images/iconGrid.png differ
diff --git a/assets/preload/images/stepmania-icon.png b/assets/preload/images/stepmania-icon.png
new file mode 100644
index 0000000..023353b
Binary files /dev/null and b/assets/preload/images/stepmania-icon.png differ
diff --git a/assets/preload/music/freakyMenu.mp3 b/assets/preload/music/freakyMenu.mp3
index 8132bfe..c8b0a56 100644
Binary files a/assets/preload/music/freakyMenu.mp3 and b/assets/preload/music/freakyMenu.mp3 differ
diff --git a/assets/preload/music/freakyMenu.ogg b/assets/preload/music/freakyMenu.ogg
index 372111d..a3ac889 100644
Binary files a/assets/preload/music/freakyMenu.ogg and b/assets/preload/music/freakyMenu.ogg differ
diff --git a/assets/shared/images/NOTE_assets.png b/assets/shared/images/NOTE_assets.png
index 8e9f3a0..2b348a2 100644
Binary files a/assets/shared/images/NOTE_assets.png and b/assets/shared/images/NOTE_assets.png differ
diff --git a/assets/shared/images/NOTE_assets.xml b/assets/shared/images/NOTE_assets.xml
index 6e80b13..d3e1257 100644
--- a/assets/shared/images/NOTE_assets.xml
+++ b/assets/shared/images/NOTE_assets.xml
@@ -1,92 +1,92 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/shared/images/characters/bf-carOffsets.txt b/assets/shared/images/characters/bf-carOffsets.txt
new file mode 100644
index 0000000..5bbfae1
--- /dev/null
+++ b/assets/shared/images/characters/bf-carOffsets.txt
@@ -0,0 +1,9 @@
+idle -5 0
+singUP -29 27
+singRIGHT -38 -7
+singLEFT 12 -6
+singDOWN -10 -50
+singUPmiss -29 27
+singRIGHTmiss -30 21
+singLEFTmiss 12 24
+singDOWNmiss -11 -19
diff --git a/assets/shared/images/characters/bf-christmasOffsets.txt b/assets/shared/images/characters/bf-christmasOffsets.txt
new file mode 100644
index 0000000..0142844
--- /dev/null
+++ b/assets/shared/images/characters/bf-christmasOffsets.txt
@@ -0,0 +1,10 @@
+idle -5 0
+singUP -29 27
+singRIGHT -38 -7
+singLEFT 12 -6
+singDOWN -10 -50
+singUPmiss -29 27
+singRIGHTmiss -30 21
+singLEFTmiss 12 24
+singDOWNmiss -11 -19
+hey 7 4
diff --git a/assets/shared/images/characters/bf-pixel-deadOffsets.txt b/assets/shared/images/characters/bf-pixel-deadOffsets.txt
new file mode 100644
index 0000000..3544a2c
--- /dev/null
+++ b/assets/shared/images/characters/bf-pixel-deadOffsets.txt
@@ -0,0 +1,3 @@
+firstDeath 0 0
+deathLoop -30 -12
+deathConfirm -30 -12
diff --git a/assets/shared/images/characters/bf-pixelOffsets.txt b/assets/shared/images/characters/bf-pixelOffsets.txt
new file mode 100644
index 0000000..b8a8292
--- /dev/null
+++ b/assets/shared/images/characters/bf-pixelOffsets.txt
@@ -0,0 +1,9 @@
+idle 0 0
+singUP 0 0
+singRIGHT 0 0
+singLEFT 0 0
+singDOWN 0 0
+singUPmiss 0 0
+singRIGHTmiss 0 0
+singLEFTmiss 0 0
+singDOWNmiss 0 0
diff --git a/assets/shared/images/characters/bfOffsets.txt b/assets/shared/images/characters/bfOffsets.txt
new file mode 100644
index 0000000..6ec2321
--- /dev/null
+++ b/assets/shared/images/characters/bfOffsets.txt
@@ -0,0 +1,14 @@
+idle -5 0
+singUP -29 27
+singRIGHT -38 -7
+singLEFT 12 -6
+singDOWN -10 -50
+singUPmiss -29 27
+singRIGHTmiss -30 21
+singLEFTmiss 12 24
+singDOWNmiss -11 -19
+hey 7 4
+firstDeath 37 11
+deathLoop 37 5
+deathConfirm 37 69
+scared -4 0
diff --git a/assets/shared/images/characters/bfPixelsDEAD.xml b/assets/shared/images/characters/bfPixelsDEAD.xml
index 2d741ca..be3478c 100644
--- a/assets/shared/images/characters/bfPixelsDEAD.xml
+++ b/assets/shared/images/characters/bfPixelsDEAD.xml
@@ -1,7 +1,7 @@

-
-
+
+
@@ -58,8 +58,8 @@
-
-
+
+
diff --git a/assets/shared/images/characters/dadOffsets.txt b/assets/shared/images/characters/dadOffsets.txt
new file mode 100644
index 0000000..69ba153
--- /dev/null
+++ b/assets/shared/images/characters/dadOffsets.txt
@@ -0,0 +1,5 @@
+idle 0 0
+singUP -6 50
+singRIGHT 0 27
+singLEFT -10 10
+singDOWN 0 -30
diff --git a/assets/shared/images/characters/gf-carOffsets.txt b/assets/shared/images/characters/gf-carOffsets.txt
new file mode 100644
index 0000000..9862aae
--- /dev/null
+++ b/assets/shared/images/characters/gf-carOffsets.txt
@@ -0,0 +1,2 @@
+danceLeft 0 0
+danceRight 0 0
diff --git a/assets/shared/images/characters/gf-christmasOffsets.txt b/assets/shared/images/characters/gf-christmasOffsets.txt
new file mode 100644
index 0000000..05abb7a
--- /dev/null
+++ b/assets/shared/images/characters/gf-christmasOffsets.txt
@@ -0,0 +1,11 @@
+cheer 0 0
+sad -2 -21
+danceLeft 0 -9
+danceRight 0 -9
+singUP 0 4
+singRIGHT 0 -20
+singLEFT 0 -19
+singDOWN 0 -20
+hairBlow 45 -8
+hairFall 0 -9
+scared -2 -17
diff --git a/assets/shared/images/characters/gf-pixelOffsets.txt b/assets/shared/images/characters/gf-pixelOffsets.txt
new file mode 100644
index 0000000..9862aae
--- /dev/null
+++ b/assets/shared/images/characters/gf-pixelOffsets.txt
@@ -0,0 +1,2 @@
+danceLeft 0 0
+danceRight 0 0
diff --git a/assets/shared/images/characters/gfOffsets.txt b/assets/shared/images/characters/gfOffsets.txt
new file mode 100644
index 0000000..05abb7a
--- /dev/null
+++ b/assets/shared/images/characters/gfOffsets.txt
@@ -0,0 +1,11 @@
+cheer 0 0
+sad -2 -21
+danceLeft 0 -9
+danceRight 0 -9
+singUP 0 4
+singRIGHT 0 -20
+singLEFT 0 -19
+singDOWN 0 -20
+hairBlow 45 -8
+hairFall 0 -9
+scared -2 -17
diff --git a/assets/shared/images/characters/mom-carOffsets.txt b/assets/shared/images/characters/mom-carOffsets.txt
new file mode 100644
index 0000000..65cbecd
--- /dev/null
+++ b/assets/shared/images/characters/mom-carOffsets.txt
@@ -0,0 +1,5 @@
+idle 0 0
+singUP 14 71
+singRIGHT 10 -60
+singLEFT 250 -23
+singDOWN 20 -160
diff --git a/assets/shared/images/characters/momOffsets.txt b/assets/shared/images/characters/momOffsets.txt
new file mode 100644
index 0000000..65cbecd
--- /dev/null
+++ b/assets/shared/images/characters/momOffsets.txt
@@ -0,0 +1,5 @@
+idle 0 0
+singUP 14 71
+singRIGHT 10 -60
+singLEFT 250 -23
+singDOWN 20 -160
diff --git a/assets/shared/images/characters/monster-christmasOffsets.txt b/assets/shared/images/characters/monster-christmasOffsets.txt
new file mode 100644
index 0000000..a357046
--- /dev/null
+++ b/assets/shared/images/characters/monster-christmasOffsets.txt
@@ -0,0 +1,5 @@
+idle 0 0
+singUP -20 50
+singRIGHT -51 0
+singLEFT -30 0
+singDOWN -40 -94
diff --git a/assets/shared/images/characters/monsterOffsets.txt b/assets/shared/images/characters/monsterOffsets.txt
new file mode 100644
index 0000000..e211a5f
--- /dev/null
+++ b/assets/shared/images/characters/monsterOffsets.txt
@@ -0,0 +1,5 @@
+idle 0 0
+singUP -20 94
+singRIGHT -51 30
+singLEFT -30 20
+singDOWN -50 -80
diff --git a/assets/shared/images/characters/parents-christmasOffsets.txt b/assets/shared/images/characters/parents-christmasOffsets.txt
new file mode 100644
index 0000000..bdee13c
--- /dev/null
+++ b/assets/shared/images/characters/parents-christmasOffsets.txt
@@ -0,0 +1,9 @@
+idle 0 0
+singUP -47 24
+singRIGHT -1 -23
+singLEFT -30 16
+singDOWN -31 -29
+singUP-alt -47 24
+singRIGHT-alt -1 -24
+singLEFT-alt -30 15
+singDOWN-alt -30 -27
diff --git a/assets/shared/images/characters/picoOffsets.txt b/assets/shared/images/characters/picoOffsets.txt
new file mode 100644
index 0000000..e209da7
--- /dev/null
+++ b/assets/shared/images/characters/picoOffsets.txt
@@ -0,0 +1,9 @@
+idle 0 0
+singUP -29 27
+singRIGHT -68 -7
+singLEFT 65 9
+singDOWN 200 -70
+singUPmiss -19 67
+singRIGHTmiss -60 41
+singLEFTmiss 62 64
+singDOWNmiss 210 -28
diff --git a/assets/shared/images/characters/senpai-angryOffsets.txt b/assets/shared/images/characters/senpai-angryOffsets.txt
new file mode 100644
index 0000000..c118259
--- /dev/null
+++ b/assets/shared/images/characters/senpai-angryOffsets.txt
@@ -0,0 +1,5 @@
+idle 0 0
+singUP 5 37
+singRIGHT 0 0
+singLEFT 40 0
+singDOWN 14 0
diff --git a/assets/shared/images/characters/senpaiOffsets.txt b/assets/shared/images/characters/senpaiOffsets.txt
new file mode 100644
index 0000000..c118259
--- /dev/null
+++ b/assets/shared/images/characters/senpaiOffsets.txt
@@ -0,0 +1,5 @@
+idle 0 0
+singUP 5 37
+singRIGHT 0 0
+singLEFT 40 0
+singDOWN 14 0
diff --git a/assets/shared/images/characters/spiritOffsets.txt b/assets/shared/images/characters/spiritOffsets.txt
new file mode 100644
index 0000000..ed2442d
--- /dev/null
+++ b/assets/shared/images/characters/spiritOffsets.txt
@@ -0,0 +1,5 @@
+idle -220 -280
+singUP -220 -240
+singRIGHT -220 -280
+singLEFT -200 -280
+singDOWN 170 110
diff --git a/assets/shared/images/characters/spookyOffsets.txt b/assets/shared/images/characters/spookyOffsets.txt
new file mode 100644
index 0000000..c14c5e7
--- /dev/null
+++ b/assets/shared/images/characters/spookyOffsets.txt
@@ -0,0 +1,6 @@
+danceLeft 0 0
+danceRight 0 0
+singUP -20 26
+singRIGHT -130 -14
+singLEFT 130 -10
+singDOWN -50 -130
diff --git a/assets/shared/sounds/CLAP.mp3 b/assets/shared/sounds/CLAP.mp3
new file mode 100644
index 0000000..21b3f27
Binary files /dev/null and b/assets/shared/sounds/CLAP.mp3 differ
diff --git a/assets/shared/sounds/SNAP.mp3 b/assets/shared/sounds/SNAP.mp3
new file mode 100644
index 0000000..67971fe
Binary files /dev/null and b/assets/shared/sounds/SNAP.mp3 differ
diff --git a/assets/sm/HOW TO ADD SM FILES.txt b/assets/sm/HOW TO ADD SM FILES.txt
new file mode 100644
index 0000000..b9fa864
--- /dev/null
+++ b/assets/sm/HOW TO ADD SM FILES.txt
@@ -0,0 +1,5 @@
+Put both the .sm and .ogg in the same folder and put the folder in this folder. Launch the game and go into freeplay, it'll load into the song list.
+
+Limitations:
+- You can only use songs that have one difficulty, so if a song has more than one. Remove all but the one you want to play. (it doesn't matter if it's challenge or what ever)
+- The song must be a .ogg
\ No newline at end of file
diff --git a/assets/songs/test/Inst.mp3 b/assets/songs/test/Inst.mp3
deleted file mode 100644
index 87d9932..0000000
Binary files a/assets/songs/test/Inst.mp3 and /dev/null differ
diff --git a/assets/songs/test/Inst.ogg b/assets/songs/test/Inst.ogg
index f39e2b1..7a16671 100644
Binary files a/assets/songs/test/Inst.ogg and b/assets/songs/test/Inst.ogg differ
diff --git a/assets/songs/test/Voices.mp3 b/assets/songs/test/Voices.mp3
deleted file mode 100644
index 9625266..0000000
Binary files a/assets/songs/test/Voices.mp3 and /dev/null differ
diff --git a/assets/songs/test/Voices.ogg b/assets/songs/test/Voices.ogg
deleted file mode 100644
index 49f0f5d..0000000
Binary files a/assets/songs/test/Voices.ogg and /dev/null differ
diff --git a/docs/building.md b/docs/building.md
index fa8d5a9..e824a0f 100644
--- a/docs/building.md
+++ b/docs/building.md
@@ -30,26 +30,19 @@
- `haxelib git discord_rpc https://github.com/Aidan63/linc_discord-rpc`
- `haxelib install actuate`
- `haxelib git extension-webm https://github.com/KadeDev/extension-webm`
- - `lime rebuild extension-webm windows`
+ - `lime rebuild extension-webm `
### Windows-only dependencies (only for building *to* Windows. Building html5 on Windows does not require this)
If you are planning to build for Windows, you also need to install **Visual Studio 2019**. While installing it, *don't click on any of the options to install workloads*. Instead, go to the **individual components** tab and choose the following:
- MSVC v142 - VS 2019 C++ x64/x86 build tools
+- MSVC v141 - VS 2017 C++ x64/x86 build tools
- Windows SDK (10.0.17763.0)
- C++ Profiling tools
- C++ CMake tools for windows
- C++ ATL for v142 build tools (x86 & x64)
-- C++ MFC for v142 build tools (x86 & x64)
-- C++/CLI support for v142 build tools (14.21)
-- C++ Modules for v142 build tools (x64/x86)
-- Clang Compiler for Windows
-- Windows 10 SDK (10.0.17134.0)
-- Windows 10 SDK (10.0.16299.0)
-- MSVC v141 - VS 2017 C++ x64/x86 build tools
-- MSVC v140 - VS 2015 C++ build tools (v14.00)
-This will install about 22 GB of crap, but is necessary to build for Windows.
+This will install about 7 GB of crap, but is necessary to build for Windows.
### macOS-only dependencies (these are required for building on macOS at all, including html5.)
If you are running macOS, you'll need to install Xcode. You can download it from the macOS App Store or from the [Xcode website](https://developer.apple.com/xcode/).
diff --git a/docs/changelogs/changelog-1.6.md b/docs/changelogs/changelog-1.6.md
new file mode 100644
index 0000000..57e70d5
--- /dev/null
+++ b/docs/changelogs/changelog-1.6.md
@@ -0,0 +1,35 @@
+# Latest (master) changelog
+
+Changes marked with 💖 will be listed in the short version of the changelog in `version.downloadMe`.
+
+### Additions
+- 💖 Full reworked charter
+- Note quantization
+- 💖 BPM Changes & Scroll Speed Change Support
+- 💖 StepMania File Format support
+- Anti-Aliasing option for low end pc's
+- 💖 Pre-loading for characters option
+- New Logo
+- 💖 New Main Menu Remix
+- 💖 Difficulty Calculator
+- Week Locking
+- Character Offset Files
+- Many new options
+
+### Changes
+- Reworked Health Drain to be harsher
+- 💖 Held notes being weird as fuck (completely reworked them)
+- Many beat based things actually go to the beat (blue balls, title screen, etc)
+- Losing Icon for Father Dearest & Mommy Mearest together
+
+### Bugfixes
+- BF Animation ending too early
+- Held note end fix (this made me mad)
+- Up arrow having a 8 pixels next to it
+- Stop crashes with "R"
+- Fixed dropped inputs for stacked notes.
+- Fixed multiple crashes
+- Fixed spirit being weird
+- Fixed a lot of desyncs
+- Ghost Tapping works now
+- Pressing 7 while dying no longer freezes you in time.
\ No newline at end of file
diff --git a/docs/guides/weeks.md b/docs/guides/weeks.md
index 020fc5d..7fcdfc0 100644
--- a/docs/guides/weeks.md
+++ b/docs/guides/weeks.md
@@ -15,8 +15,10 @@ Scroll down to Line 26, or Search (Windows/Linux: `Ctrl+F`, Mac: `Cmd+F`) for "w
---
```haxe
-var weekData:Array = [
-
+static function weekData():Array
+{
+ return [
+
['Tutorial'],
['Bopeebo', 'Fresh', 'Dadbattle'],
@@ -30,8 +32,9 @@ var weekData:Array = [
['Cocoa', 'Eggnog', 'Winter-Horrorland'],
['Senpai', 'Roses', 'Thorns']
-
-];
+
+ ];
+}
```
---
@@ -45,8 +48,10 @@ Example
---
```haxe
-var weekData:Array = [
-
+static function weekData():Array
+{
+ return [
+
['Tutorial'],
['Bopeebo', 'Fresh', 'Dadbattle'],
@@ -58,12 +63,13 @@ var weekData:Array = [
['Satin-Panties', "High", "Milf"],
['Cocoa', 'Eggnog', 'Winter-Horrorland'],
-
+
['Senpai', 'Roses', 'Thorns'],
['Ugh', 'Guns', 'Stress']
-
-];
+
+ ];
+}
```
---
@@ -103,32 +109,21 @@ var weekCharacters:Array = [
### Step 4. Week Names
-Underneath the song list, there should be another array called `weekNames`. Creating a new line in that array, just enter a string that represents what you want the week to be called.
+In `assets/preload/data`, there should be a .txt file called `weekNames`. Creating a new line in that file, just enter a string that represents what you want the week to be called.
Example
---
---
-```haxe
-var weekNames:Array = [
-
- "How to Funk",
-
- "Daddy dearest",
-
- "Spooky Month",
-
- "PICO",
-
- "Mommy Must Murder",
-
- "Red Snow",
-
- "Hating Simulator ft. Moawlings",
-
- "Tankman"
-
-];
+```
+Tutorial
+Daddy Dearest
+Spooky Month
+PICO
+MOMMY MUST MURDER
+RED SNOW
+Hating Simulator ft. Moawling
+TANKMAN
```
---
@@ -137,23 +132,29 @@ var weekNames:Array = [
### Step 5. Graphics
-Displaying a week icon for your custom week is as simple as dropping a .png into `assets/images/storymenu`. Rename the file to `week7.png`, `week8.png`, etc.
+Displaying a week icon for your custom week is as simple as dropping a .png into `assets/preload/images/storymenu`. Rename the file to `week7.png`, `week8.png`, etc.
Example
---
---
+


+
+=======
+
+
NOTE: You will have to add a new item to `weekUnlocked`, so that the week is playable.
Locate to line 39 and add in a new boolean called True so that the week can be playable.
-
+---
+ \* *for this screenshot I removed tankman from weekCharacters as it would crash because I don't have a tankman character added*
### Conclusion
If you followed all of the steps correctly, you have successfully created a new week in the Story Mode.
diff --git a/source/Alphabet.hx b/source/Alphabet.hx
index a92b5d1..eec323d 100644
--- a/source/Alphabet.hx
+++ b/source/Alphabet.hx
@@ -278,8 +278,10 @@ class AlphaCharacter extends FlxSprite
super(x, y);
var tex = Paths.getSparrowAtlas('alphabet');
frames = tex;
-
- antialiasing = true;
+ if(FlxG.save.data.antialiasing)
+ {
+ antialiasing = true;
+ }
}
public function createBold(letter:String)
diff --git a/source/AnimationDebug.hx b/source/AnimationDebug.hx
index 05b40d6..46d2188 100644
--- a/source/AnimationDebug.hx
+++ b/source/AnimationDebug.hx
@@ -118,6 +118,9 @@ class AnimationDebug extends FlxState
if (FlxG.keys.justPressed.Q)
FlxG.camera.zoom -= 0.25;
+ if (FlxG.keys.justPressed.F)
+ char.flipX = !char.flipX;
+
if (FlxG.keys.pressed.I || FlxG.keys.pressed.J || FlxG.keys.pressed.K || FlxG.keys.pressed.L)
{
if (FlxG.keys.pressed.I)
diff --git a/source/BackgroundDancer.hx b/source/BackgroundDancer.hx
index c572c1e..07ef6da 100644
--- a/source/BackgroundDancer.hx
+++ b/source/BackgroundDancer.hx
@@ -1,5 +1,6 @@
package;
+import flixel.FlxG;
import flixel.FlxSprite;
import flixel.graphics.frames.FlxAtlasFrames;
@@ -13,7 +14,10 @@ class BackgroundDancer extends FlxSprite
animation.addByIndices('danceLeft', 'bg dancer sketch PINK', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false);
animation.addByIndices('danceRight', 'bg dancer sketch PINK', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false);
animation.play('danceLeft');
- antialiasing = true;
+ if(FlxG.save.data.antialiasing)
+ {
+ antialiasing = true;
+ }
}
var danceDir:Bool = false;
diff --git a/source/Caching.hx b/source/Caching.hx
index 2c6fb50..568c921 100644
--- a/source/Caching.hx
+++ b/source/Caching.hx
@@ -1,10 +1,20 @@
+#if sys
package;
+import lime.app.Application;
+#if windows
+import Discord.DiscordClient;
+#end
+import openfl.display.BitmapData;
+import openfl.utils.Assets;
+import flixel.ui.FlxBar;
import haxe.Exception;
import flixel.tweens.FlxEase;
import flixel.tweens.FlxTween;
+#if cpp
import sys.FileSystem;
import sys.io.File;
+#end
import flixel.FlxG;
import flixel.FlxSprite;
import flixel.addons.transition.FlxTransitionSprite.GraphicTransTileDiamond;
@@ -22,107 +32,152 @@ using StringTools;
class Caching extends MusicBeatState
{
- var toBeDone = 0;
- var done = 0;
+ var toBeDone = 0;
+ var done = 0;
+
+ var loaded = false;
+
+ var text:FlxText;
+ var kadeLogo:FlxSprite;
+
+ public static var bitmapData:Map;
+
+ var images = [];
+ var music = [];
+ var charts = [];
- var text:FlxText;
- var kadeLogo:FlxSprite;
override function create()
{
- FlxG.mouse.visible = false;
- FlxG.worldBounds.set(0,0);
+ FlxG.save.bind('funkin', 'ninjamuffin99');
- text = new FlxText(FlxG.width / 2, FlxG.height / 2 + 300,0,"Loading...");
- text.size = 34;
- text.alignment = FlxTextAlign.CENTER;
- text.alpha = 0;
+ PlayerSettings.init();
- kadeLogo = new FlxSprite(FlxG.width / 2, FlxG.height / 2).loadGraphic(Paths.image('KadeEngineLogo'));
- kadeLogo.x -= kadeLogo.width / 2;
- kadeLogo.y -= kadeLogo.height / 2 + 100;
- text.y -= kadeLogo.height / 2 - 125;
- text.x -= 170;
- kadeLogo.setGraphicSize(Std.int(kadeLogo.width * 0.6));
+ KadeEngineData.initSave();
- kadeLogo.alpha = 0;
+ FlxG.mouse.visible = false;
- add(kadeLogo);
- add(text);
+ FlxG.worldBounds.set(0,0);
- trace('starting caching..');
-
- sys.thread.Thread.create(() -> {
- cache();
- });
+ bitmapData = new Map();
+
+ text = new FlxText(FlxG.width / 2, FlxG.height / 2 + 300,0,"Loading...");
+ text.size = 34;
+ text.alignment = FlxTextAlign.CENTER;
+ text.alpha = 0;
+
+ kadeLogo = new FlxSprite(FlxG.width / 2, FlxG.height / 2).loadGraphic(Paths.image('KadeEngineLogo'));
+ kadeLogo.x -= kadeLogo.width / 2;
+ kadeLogo.y -= kadeLogo.height / 2 + 100;
+ text.y -= kadeLogo.height / 2 - 125;
+ text.x -= 170;
+ kadeLogo.setGraphicSize(Std.int(kadeLogo.width * 0.6));
+ kadeLogo.antialiasing = true;
+
+ kadeLogo.alpha = 0;
+
+ #if cpp
+ if (FlxG.save.data.cacheImages)
+ {
+ trace("caching images...");
+
+ for (i in FileSystem.readDirectory(FileSystem.absolutePath("assets/shared/images/characters")))
+ {
+ if (!i.endsWith(".png"))
+ continue;
+ images.push(i);
+ }
+ }
+
+ trace("caching music...");
+
+ for (i in FileSystem.readDirectory(FileSystem.absolutePath("assets/songs")))
+ {
+ music.push(i);
+ }
+ #end
+
+ toBeDone = Lambda.count(images) + Lambda.count(music);
+
+ var bar = new FlxBar(10,FlxG.height - 50,FlxBarFillDirection.LEFT_TO_RIGHT,FlxG.width,40,null,"done",0,toBeDone);
+ bar.color = FlxColor.PURPLE;
+
+ add(bar);
+
+ add(kadeLogo);
+ add(text);
+
+ trace('starting caching..');
+
+ #if cpp
+ // update thread
+
+ sys.thread.Thread.create(() -> {
+ while(!loaded)
+ {
+ if (toBeDone != 0 && done != toBeDone)
+ {
+ var alpha = HelperFunctions.truncateFloat(done / toBeDone * 100,2) / 100;
+ kadeLogo.alpha = alpha;
+ text.alpha = alpha;
+ text.text = "Loading... (" + done + "/" + toBeDone + ")";
+ }
+ }
+
+ });
+
+ // cache thread
+
+ sys.thread.Thread.create(() -> {
+ cache();
+ });
+ #end
+
+ super.create();
+ }
+
+ var calledDone = false;
+
+ override function update(elapsed)
+ {
+ super.update(elapsed);
+ }
- super.create();
- }
+ function cache()
+ {
+ trace("LOADING: " + toBeDone + " OBJECTS.");
- var calledDone = false;
+ for (i in images)
+ {
+ var replaced = i.replace(".png","");
+ var data:BitmapData = BitmapData.fromFile("assets/shared/images/characters/" + i);
+ trace('id ' + replaced + ' file - assets/shared/images/characters/' + i + ' ${data.width}');
+ var graph = FlxGraphic.fromBitmapData(data);
+ graph.persist = true;
+ graph.destroyOnNoUse = false;
+ bitmapData.set(replaced,graph);
+ done++;
+ }
- override function update(elapsed)
- {
-
- if (toBeDone != 0 && done != toBeDone)
- {
- var alpha = HelperFunctions.truncateFloat(done / toBeDone * 100,2) / 100;
- kadeLogo.alpha = alpha;
- text.alpha = alpha;
- text.text = "Loading... (" + done + "/" + toBeDone + ")";
- }
-
- super.update(elapsed);
- }
+ for (i in music)
+ {
+ FlxG.sound.cache(Paths.inst(i));
+ FlxG.sound.cache(Paths.voices(i));
+ trace("cached " + i);
+ done++;
+ }
- function cache()
- {
+ trace("Finished caching...");
- var images = [];
- var music = [];
+ loaded = true;
- trace("caching images...");
+ trace(Assets.cache.hasBitmapData('GF_assets'));
- for (i in FileSystem.readDirectory(FileSystem.absolutePath("assets/shared/images/characters")))
- {
- if (!i.endsWith(".png"))
- continue;
- images.push(i);
- }
+ FlxG.switchState(new TitleState());
+ }
- trace("caching music...");
-
- for (i in FileSystem.readDirectory(FileSystem.absolutePath("assets/songs")))
- {
- music.push(i);
- }
-
- toBeDone = Lambda.count(images) + Lambda.count(music);
-
- trace("LOADING: " + toBeDone + " OBJECTS.");
-
- for (i in images)
- {
- var replaced = i.replace(".png","");
- FlxG.bitmap.add(Paths.image("characters/" + replaced,"shared"));
- trace("cached " + replaced);
- done++;
- }
-
- for (i in music)
- {
- FlxG.sound.cache(Paths.inst(i));
- FlxG.sound.cache(Paths.voices(i));
- trace("cached " + i);
- done++;
- }
-
- trace("Finished caching...");
-
- FlxG.switchState(new TitleState());
- }
-
-}
\ No newline at end of file
+}
+#end
\ No newline at end of file
diff --git a/source/Character.hx b/source/Character.hx
index f9df179..2f15c00 100644
--- a/source/Character.hx
+++ b/source/Character.hx
@@ -26,13 +26,16 @@ class Character extends FlxSprite
this.isPlayer = isPlayer;
var tex:FlxAtlasFrames;
- antialiasing = true;
+ if(FlxG.save.data.antialiasing)
+ {
+ antialiasing = true;
+ }
switch (curCharacter)
{
case 'gf':
// GIRLFRIEND CODE
- tex = Paths.getSparrowAtlas('characters/GF_assets');
+ tex = Paths.getSparrowAtlas('GF_assets','shared',true);
frames = tex;
animation.addByPrefix('cheer', 'GF Cheer', 24, false);
animation.addByPrefix('singLEFT', 'GF left note', 24, false);
@@ -46,24 +49,12 @@ class Character extends FlxSprite
animation.addByIndices('hairFall', "GF Dancing Beat Hair Landing", [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "", 24, false);
animation.addByPrefix('scared', 'GF FEAR', 24);
- addOffset('cheer');
- addOffset('sad', -2, -2);
- addOffset('danceLeft', 0, -9);
- addOffset('danceRight', 0, -9);
-
- addOffset("singUP", 0, 4);
- addOffset("singRIGHT", 0, -20);
- addOffset("singLEFT", 0, -19);
- addOffset("singDOWN", 0, -20);
- addOffset('hairBlow', 45, -8);
- addOffset('hairFall', 0, -9);
-
- addOffset('scared', -2, -17);
+ loadOffsetFile(curCharacter);
playAnim('danceRight');
case 'gf-christmas':
- tex = Paths.getSparrowAtlas('characters/gfChristmas');
+ tex = Paths.getSparrowAtlas('gfChristmas','shared',true);
frames = tex;
animation.addByPrefix('cheer', 'GF Cheer', 24, false);
animation.addByPrefix('singLEFT', 'GF left note', 24, false);
@@ -77,44 +68,30 @@ class Character extends FlxSprite
animation.addByIndices('hairFall', "GF Dancing Beat Hair Landing", [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "", 24, false);
animation.addByPrefix('scared', 'GF FEAR', 24);
- addOffset('cheer');
- addOffset('sad', -2, -2);
- addOffset('danceLeft', 0, -9);
- addOffset('danceRight', 0, -9);
-
- addOffset("singUP", 0, 4);
- addOffset("singRIGHT", 0, -20);
- addOffset("singLEFT", 0, -19);
- addOffset("singDOWN", 0, -20);
- addOffset('hairBlow', 45, -8);
- addOffset('hairFall', 0, -9);
-
- addOffset('scared', -2, -17);
+ loadOffsetFile(curCharacter);
playAnim('danceRight');
case 'gf-car':
- tex = Paths.getSparrowAtlas('characters/gfCar');
+ tex = Paths.getSparrowAtlas('gfCar','shared',true);
frames = tex;
animation.addByIndices('singUP', 'GF Dancing Beat Hair blowing CAR', [0], "", 24, false);
animation.addByIndices('danceLeft', 'GF Dancing Beat Hair blowing CAR', [30, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false);
animation.addByIndices('danceRight', 'GF Dancing Beat Hair blowing CAR', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24,
false);
- addOffset('danceLeft', 0);
- addOffset('danceRight', 0);
+ loadOffsetFile(curCharacter);
playAnim('danceRight');
case 'gf-pixel':
- tex = Paths.getSparrowAtlas('characters/gfPixel');
+ tex = Paths.getSparrowAtlas('gfPixel','shared',true);
frames = tex;
animation.addByIndices('singUP', 'GF IDLE', [2], "", 24, false);
animation.addByIndices('danceLeft', 'GF IDLE', [30, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false);
animation.addByIndices('danceRight', 'GF IDLE', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false);
- addOffset('danceLeft', 0);
- addOffset('danceRight', 0);
+ loadOffsetFile(curCharacter);
playAnim('danceRight');
@@ -124,7 +101,7 @@ class Character extends FlxSprite
case 'dad':
// DAD ANIMATION LOADING CODE
- tex = Paths.getSparrowAtlas('characters/DADDY_DEAREST', 'shared');
+ tex = Paths.getSparrowAtlas('DADDY_DEAREST','shared',true);
frames = tex;
animation.addByPrefix('idle', 'Dad idle dance', 24);
animation.addByPrefix('singUP', 'Dad Sing Note UP', 24);
@@ -132,15 +109,11 @@ class Character extends FlxSprite
animation.addByPrefix('singDOWN', 'Dad Sing Note DOWN', 24);
animation.addByPrefix('singLEFT', 'Dad Sing Note LEFT', 24);
- addOffset('idle');
- addOffset("singUP", -6, 50);
- addOffset("singRIGHT", 0, 27);
- addOffset("singLEFT", -10, 10);
- addOffset("singDOWN", 0, -30);
+ loadOffsetFile(curCharacter);
playAnim('idle');
case 'spooky':
- tex = Paths.getSparrowAtlas('characters/spooky_kids_assets');
+ tex = Paths.getSparrowAtlas('spooky_kids_assets','shared',true);
frames = tex;
animation.addByPrefix('singUP', 'spooky UP NOTE', 24, false);
animation.addByPrefix('singDOWN', 'spooky DOWN note', 24, false);
@@ -149,17 +122,11 @@ class Character extends FlxSprite
animation.addByIndices('danceLeft', 'spooky dance idle', [0, 2, 6], "", 12, false);
animation.addByIndices('danceRight', 'spooky dance idle', [8, 10, 12, 14], "", 12, false);
- addOffset('danceLeft');
- addOffset('danceRight');
-
- addOffset("singUP", -20, 26);
- addOffset("singRIGHT", -130, -14);
- addOffset("singLEFT", 130, -10);
- addOffset("singDOWN", -50, -130);
+ loadOffsetFile(curCharacter);
playAnim('danceRight');
case 'mom':
- tex = Paths.getSparrowAtlas('characters/Mom_Assets');
+ tex = Paths.getSparrowAtlas('Mom_Assets','shared',true);
frames = tex;
animation.addByPrefix('idle', "Mom Idle", 24, false);
@@ -170,16 +137,12 @@ class Character extends FlxSprite
// CUZ DAVE IS DUMB!
animation.addByPrefix('singRIGHT', 'Mom Pose Left', 24, false);
- addOffset('idle');
- addOffset("singUP", 14, 71);
- addOffset("singRIGHT", 10, -60);
- addOffset("singLEFT", 250, -23);
- addOffset("singDOWN", 20, -160);
+ loadOffsetFile(curCharacter);
playAnim('idle');
case 'mom-car':
- tex = Paths.getSparrowAtlas('characters/momCar');
+ tex = Paths.getSparrowAtlas('momCar','shared',true);
frames = tex;
animation.addByPrefix('idle', "Mom Idle", 24, false);
@@ -190,15 +153,11 @@ class Character extends FlxSprite
// CUZ DAVE IS DUMB!
animation.addByPrefix('singRIGHT', 'Mom Pose Left', 24, false);
- addOffset('idle');
- addOffset("singUP", 14, 71);
- addOffset("singRIGHT", 10, -60);
- addOffset("singLEFT", 250, -23);
- addOffset("singDOWN", 20, -160);
+ loadOffsetFile(curCharacter);
playAnim('idle');
case 'monster':
- tex = Paths.getSparrowAtlas('characters/Monster_Assets');
+ tex = Paths.getSparrowAtlas('Monster_Assets','shared',true);
frames = tex;
animation.addByPrefix('idle', 'monster idle', 24, false);
animation.addByPrefix('singUP', 'monster up note', 24, false);
@@ -206,14 +165,10 @@ class Character extends FlxSprite
animation.addByPrefix('singLEFT', 'Monster left note', 24, false);
animation.addByPrefix('singRIGHT', 'Monster Right note', 24, false);
- addOffset('idle');
- addOffset("singUP", -20, 50);
- addOffset("singRIGHT", -51);
- addOffset("singLEFT", -30);
- addOffset("singDOWN", -30, -40);
+ loadOffsetFile(curCharacter);
playAnim('idle');
case 'monster-christmas':
- tex = Paths.getSparrowAtlas('characters/monsterChristmas');
+ tex = Paths.getSparrowAtlas('monsterChristmas','shared',true);
frames = tex;
animation.addByPrefix('idle', 'monster idle', 24, false);
animation.addByPrefix('singUP', 'monster up note', 24, false);
@@ -221,14 +176,10 @@ class Character extends FlxSprite
animation.addByPrefix('singLEFT', 'Monster left note', 24, false);
animation.addByPrefix('singRIGHT', 'Monster Right note', 24, false);
- addOffset('idle');
- addOffset("singUP", -20, 50);
- addOffset("singRIGHT", -51);
- addOffset("singLEFT", -30);
- addOffset("singDOWN", -40, -94);
+ loadOffsetFile(curCharacter);
playAnim('idle');
case 'pico':
- tex = Paths.getSparrowAtlas('characters/Pico_FNF_assetss');
+ tex = Paths.getSparrowAtlas('Pico_FNF_assetss','shared',true);
frames = tex;
animation.addByPrefix('idle', "Pico Idle Dance", 24);
animation.addByPrefix('singUP', 'pico Up note0', 24, false);
@@ -252,22 +203,14 @@ class Character extends FlxSprite
animation.addByPrefix('singUPmiss', 'pico Up note miss', 24);
animation.addByPrefix('singDOWNmiss', 'Pico Down Note MISS', 24);
- addOffset('idle');
- addOffset("singUP", -29, 27);
- addOffset("singRIGHT", -68, -7);
- addOffset("singLEFT", 65, 9);
- addOffset("singDOWN", 200, -70);
- addOffset("singUPmiss", -19, 67);
- addOffset("singRIGHTmiss", -60, 41);
- addOffset("singLEFTmiss", 62, 64);
- addOffset("singDOWNmiss", 210, -28);
+ loadOffsetFile(curCharacter);
playAnim('idle');
flipX = true;
case 'bf':
- var tex = Paths.getSparrowAtlas('characters/BOYFRIEND', 'shared');
+ var tex = Paths.getSparrowAtlas('BOYFRIEND','shared',true);
frames = tex;
trace(tex.frames.length);
@@ -284,32 +227,19 @@ class Character extends FlxSprite
animation.addByPrefix('hey', 'BF HEY', 24, false);
animation.addByPrefix('firstDeath', "BF dies", 24, false);
- animation.addByPrefix('deathLoop', "BF Dead Loop", 24, true);
+ animation.addByPrefix('deathLoop', "BF Dead Loop", 24, false);
animation.addByPrefix('deathConfirm', "BF Dead confirm", 24, false);
animation.addByPrefix('scared', 'BF idle shaking', 24);
- addOffset('idle', -5);
- addOffset("singUP", -29, 27);
- addOffset("singRIGHT", -38, -7);
- addOffset("singLEFT", 12, -6);
- addOffset("singDOWN", -10, -50);
- addOffset("singUPmiss", -29, 27);
- addOffset("singRIGHTmiss", -30, 21);
- addOffset("singLEFTmiss", 12, 24);
- addOffset("singDOWNmiss", -11, -19);
- addOffset("hey", 7, 4);
- addOffset('firstDeath', 37, 11);
- addOffset('deathLoop', 37, 5);
- addOffset('deathConfirm', 37, 69);
- addOffset('scared', -4);
+ loadOffsetFile(curCharacter);
playAnim('idle');
flipX = true;
case 'bf-christmas':
- var tex = Paths.getSparrowAtlas('characters/bfChristmas');
+ var tex = Paths.getSparrowAtlas('bfChristmas','shared',true);
frames = tex;
animation.addByPrefix('idle', 'BF idle dance', 24, false);
animation.addByPrefix('singUP', 'BF NOTE UP0', 24, false);
@@ -322,22 +252,13 @@ class Character extends FlxSprite
animation.addByPrefix('singDOWNmiss', 'BF NOTE DOWN MISS', 24, false);
animation.addByPrefix('hey', 'BF HEY', 24, false);
- addOffset('idle', -5);
- addOffset("singUP", -29, 27);
- addOffset("singRIGHT", -38, -7);
- addOffset("singLEFT", 12, -6);
- addOffset("singDOWN", -10, -50);
- addOffset("singUPmiss", -29, 27);
- addOffset("singRIGHTmiss", -30, 21);
- addOffset("singLEFTmiss", 12, 24);
- addOffset("singDOWNmiss", -11, -19);
- addOffset("hey", 7, 4);
+ loadOffsetFile(curCharacter);
playAnim('idle');
flipX = true;
case 'bf-car':
- var tex = Paths.getSparrowAtlas('characters/bfCar');
+ var tex = Paths.getSparrowAtlas('bfCar','shared',true);
frames = tex;
animation.addByPrefix('idle', 'BF idle dance', 24, false);
animation.addByPrefix('singUP', 'BF NOTE UP0', 24, false);
@@ -349,20 +270,12 @@ class Character extends FlxSprite
animation.addByPrefix('singRIGHTmiss', 'BF NOTE RIGHT MISS', 24, false);
animation.addByPrefix('singDOWNmiss', 'BF NOTE DOWN MISS', 24, false);
- addOffset('idle', -5);
- addOffset("singUP", -29, 27);
- addOffset("singRIGHT", -38, -7);
- addOffset("singLEFT", 12, -6);
- addOffset("singDOWN", -10, -50);
- addOffset("singUPmiss", -29, 27);
- addOffset("singRIGHTmiss", -30, 21);
- addOffset("singLEFTmiss", 12, 24);
- addOffset("singDOWNmiss", -11, -19);
+ loadOffsetFile(curCharacter);
playAnim('idle');
flipX = true;
case 'bf-pixel':
- frames = Paths.getSparrowAtlas('characters/bfPixel');
+ frames = Paths.getSparrowAtlas('bfPixel','shared',true);
animation.addByPrefix('idle', 'BF IDLE', 24, false);
animation.addByPrefix('singUP', 'BF UP NOTE', 24, false);
animation.addByPrefix('singLEFT', 'BF LEFT NOTE', 24, false);
@@ -373,15 +286,7 @@ class Character extends FlxSprite
animation.addByPrefix('singRIGHTmiss', 'BF RIGHT MISS', 24, false);
animation.addByPrefix('singDOWNmiss', 'BF DOWN MISS', 24, false);
- addOffset('idle');
- addOffset("singUP");
- addOffset("singRIGHT");
- addOffset("singLEFT");
- addOffset("singDOWN");
- addOffset("singUPmiss");
- addOffset("singRIGHTmiss");
- addOffset("singLEFTmiss");
- addOffset("singDOWNmiss");
+ loadOffsetFile(curCharacter);
setGraphicSize(Std.int(width * 6));
updateHitbox();
@@ -395,16 +300,14 @@ class Character extends FlxSprite
flipX = true;
case 'bf-pixel-dead':
- frames = Paths.getSparrowAtlas('characters/bfPixelsDEAD');
+ frames = Paths.getSparrowAtlas('bfPixelsDEAD','shared',true);
animation.addByPrefix('singUP', "BF Dies pixel", 24, false);
animation.addByPrefix('firstDeath', "BF Dies pixel", 24, false);
- animation.addByPrefix('deathLoop', "Retry Loop", 24, true);
+ animation.addByPrefix('deathLoop', "Retry Loop", 24, false);
animation.addByPrefix('deathConfirm', "RETRY CONFIRM", 24, false);
animation.play('firstDeath');
- addOffset('firstDeath');
- addOffset('deathLoop', -37);
- addOffset('deathConfirm', -37);
+ loadOffsetFile(curCharacter);
playAnim('firstDeath');
// pixel bullshit
setGraphicSize(Std.int(width * 6));
@@ -413,18 +316,14 @@ class Character extends FlxSprite
flipX = true;
case 'senpai':
- frames = Paths.getSparrowAtlas('characters/senpai');
+ frames = Paths.getSparrowAtlas('senpai','shared',true);
animation.addByPrefix('idle', 'Senpai Idle', 24, false);
animation.addByPrefix('singUP', 'SENPAI UP NOTE', 24, false);
animation.addByPrefix('singLEFT', 'SENPAI LEFT NOTE', 24, false);
animation.addByPrefix('singRIGHT', 'SENPAI RIGHT NOTE', 24, false);
animation.addByPrefix('singDOWN', 'SENPAI DOWN NOTE', 24, false);
- addOffset('idle');
- addOffset("singUP", 5, 37);
- addOffset("singRIGHT");
- addOffset("singLEFT", 40);
- addOffset("singDOWN", 14);
+ loadOffsetFile(curCharacter);
playAnim('idle');
@@ -433,18 +332,14 @@ class Character extends FlxSprite
antialiasing = false;
case 'senpai-angry':
- frames = Paths.getSparrowAtlas('characters/senpai');
+ frames = Paths.getSparrowAtlas('senpai','shared',true);
animation.addByPrefix('idle', 'Angry Senpai Idle', 24, false);
animation.addByPrefix('singUP', 'Angry Senpai UP NOTE', 24, false);
animation.addByPrefix('singLEFT', 'Angry Senpai LEFT NOTE', 24, false);
animation.addByPrefix('singRIGHT', 'Angry Senpai RIGHT NOTE', 24, false);
animation.addByPrefix('singDOWN', 'Angry Senpai DOWN NOTE', 24, false);
- addOffset('idle');
- addOffset("singUP", 5, 37);
- addOffset("singRIGHT");
- addOffset("singLEFT", 40);
- addOffset("singDOWN", 14);
+ loadOffsetFile(curCharacter);
playAnim('idle');
setGraphicSize(Std.int(width * 6));
@@ -453,18 +348,14 @@ class Character extends FlxSprite
antialiasing = false;
case 'spirit':
- frames = Paths.getPackerAtlas('characters/spirit');
+ frames = Paths.getPackerAtlas('spirit','shared',true);
animation.addByPrefix('idle', "idle spirit_", 24, false);
animation.addByPrefix('singUP', "up_", 24, false);
animation.addByPrefix('singRIGHT', "right_", 24, false);
animation.addByPrefix('singLEFT', "left_", 24, false);
animation.addByPrefix('singDOWN', "spirit down_", 24, false);
- addOffset('idle', -220, -280);
- addOffset('singUP', -220, -240);
- addOffset("singRIGHT", -220, -280);
- addOffset("singLEFT", -200, -280);
- addOffset("singDOWN", 170, 110);
+ loadOffsetFile(curCharacter);
setGraphicSize(Std.int(width * 6));
updateHitbox();
@@ -474,7 +365,7 @@ class Character extends FlxSprite
antialiasing = false;
case 'parents-christmas':
- frames = Paths.getSparrowAtlas('characters/mom_dad_christmas_assets');
+ frames = Paths.getSparrowAtlas('mom_dad_christmas_assets','shared',true);
animation.addByPrefix('idle', 'Parent Christmas Idle', 24, false);
animation.addByPrefix('singUP', 'Parent Up Note Dad', 24, false);
animation.addByPrefix('singDOWN', 'Parent Down Note Dad', 24, false);
@@ -487,15 +378,7 @@ class Character extends FlxSprite
animation.addByPrefix('singLEFT-alt', 'Parent Left Note Mom', 24, false);
animation.addByPrefix('singRIGHT-alt', 'Parent Right Note Mom', 24, false);
- addOffset('idle');
- addOffset("singUP", -47, 24);
- addOffset("singRIGHT", -1, -23);
- addOffset("singLEFT", -30, 16);
- addOffset("singDOWN", -31, -29);
- addOffset("singUP-alt", -47, 24);
- addOffset("singRIGHT-alt", -1, -24);
- addOffset("singLEFT-alt", -30, 15);
- addOffset("singDOWN-alt", -30, -27);
+ loadOffsetFile(curCharacter);
playAnim('idle');
}
@@ -525,6 +408,17 @@ class Character extends FlxSprite
}
}
+ public function loadOffsetFile(character:String)
+ {
+ var offset:Array = CoolUtil.coolTextFile(Paths.txt('images/characters/' + character + "Offsets", 'shared'));
+
+ for (i in 0...offset.length)
+ {
+ var data:Array = offset[i].split(' ');
+ addOffset(data[0], Std.parseInt(data[1]), Std.parseInt(data[2]));
+ }
+ }
+
override function update(elapsed:Float)
{
if (!curCharacter.startsWith('bf'))
@@ -561,13 +455,13 @@ class Character extends FlxSprite
/**
* FOR GF DANCING SHIT
*/
- public function dance()
+ public function dance(forced:Bool = false)
{
if (!debugMode)
{
switch (curCharacter)
{
- case 'gf':
+ case 'gf' | 'gf-christmas' | 'gf-car' | 'gf-pixel':
if (!animation.curAnim.name.startsWith('hair'))
{
danced = !danced;
@@ -577,39 +471,6 @@ class Character extends FlxSprite
else
playAnim('danceLeft');
}
-
- case 'gf-christmas':
- if (!animation.curAnim.name.startsWith('hair'))
- {
- danced = !danced;
-
- if (danced)
- playAnim('danceRight');
- else
- playAnim('danceLeft');
- }
-
- case 'gf-car':
- if (!animation.curAnim.name.startsWith('hair'))
- {
- danced = !danced;
-
- if (danced)
- playAnim('danceRight');
- else
- playAnim('danceLeft');
- }
- case 'gf-pixel':
- if (!animation.curAnim.name.startsWith('hair'))
- {
- danced = !danced;
-
- if (danced)
- playAnim('danceRight');
- else
- playAnim('danceLeft');
- }
-
case 'spooky':
danced = !danced;
@@ -618,7 +479,7 @@ class Character extends FlxSprite
else
playAnim('danceLeft');
default:
- playAnim('idle');
+ playAnim('idle', forced);
}
}
}
diff --git a/source/ChartingState.hx b/source/ChartingState.hx
index 4371fad..5237e1e 100644
--- a/source/ChartingState.hx
+++ b/source/ChartingState.hx
@@ -1,6 +1,14 @@
package;
+import openfl.system.System;
+import lime.app.Application;
+#if sys
+import sys.io.File;
+#end
+import flixel.addons.ui.FlxUIButton;
+import flixel.addons.ui.StrNameLabel;
import flixel.FlxCamera;
+import flixel.FlxObject;
import flixel.addons.ui.FlxUIText;
import haxe.zip.Writer;
import Conductor.BPMChangeEvent;
@@ -41,13 +49,24 @@ using StringTools;
class ChartingState extends MusicBeatState
{
+ public static var instance:ChartingState;
+
var _file:FileReference;
public var playClaps:Bool = false;
- public var snap:Int = 1;
+ public var snap:Int = 16;
+
+ public var deezNuts:Map = new Map(); // snap conversion map
var UI_box:FlxUITabMenu;
+ var UI_options:FlxUITabMenu;
+
+ public static var lengthInSteps:Float = 0;
+ public static var lengthInBeats:Float = 0;
+
+ public var beatsShown:Float = 1; // for the zoom factor
+ public var zoomFactor:Float = 1;
/**
* Array of notes showing when each section STARTS in STEPS
@@ -68,14 +87,20 @@ class ChartingState extends MusicBeatState
var GRID_SIZE:Int = 40;
+ var subDivisions:Float = 1;
+ var defaultSnap:Bool = true;
+
var dummyArrow:FlxSprite;
+
var curRenderedNotes:FlxTypedGroup;
var curRenderedSustains:FlxTypedGroup;
var gridBG:FlxSprite;
- var _song:SwagSong;
+ public var sectionRenderes:FlxTypedGroup;
+
+ public static var _song:SwagSong;
var typingShit:FlxInputText;
/*
@@ -90,25 +115,55 @@ class ChartingState extends MusicBeatState
var player2:Character = new Character(0,0, "dad");
var player1:Boyfriend = new Boyfriend(0,0, "bf");
- var leftIcon:HealthIcon;
- var rightIcon:HealthIcon;
+ public static var leftIcon:HealthIcon;
+
+ var height = 0;
+
+ public static var rightIcon:HealthIcon;
private var lastNote:Note;
+
+ public var lines:FlxTypedGroup;
+
var claps:Array = [];
public var snapText:FlxText;
+ var camFollow:FlxObject;
+
+ public static var latestChartVersion = "2";
+
override function create()
{
curSection = lastSection;
+ trace(1 > Math.POSITIVE_INFINITY);
+
+ FlxG.mouse.visible = true;
+
+ instance = this;
+
+ deezNuts.set(4,1);
+ deezNuts.set(8,2);
+ deezNuts.set(16,4);
+ deezNuts.set(32,8);
+ deezNuts.set(64,16);
+
+ sectionRenderes = new FlxTypedGroup();
+ lines = new FlxTypedGroup();
+ texts = new FlxTypedGroup();
+
+ TimingStruct.clearTimings();
+
if (PlayState.SONG != null)
_song = PlayState.SONG;
else
{
_song = {
+ chartVersion: latestChartVersion,
song: 'Test',
notes: [],
+ eventObjects: [],
bpm: 150,
needsVoices: true,
player1: 'bf',
@@ -121,19 +176,21 @@ class ChartingState extends MusicBeatState
};
}
- gridBG = FlxGridOverlay.create(GRID_SIZE, GRID_SIZE, GRID_SIZE * 8, GRID_SIZE * 16);
- add(gridBG);
+ addGrid(1);
- var blackBorder:FlxSprite = new FlxSprite(60,10).makeGraphic(120,100,FlxColor.BLACK);
- blackBorder.scrollFactor.set();
+ if (_song.chartVersion == null)
+ _song.chartVersion = "2";
+
- blackBorder.alpha = 0.3;
+ //var blackBorder:FlxSprite = new FlxSprite(60,10).makeGraphic(120,100,FlxColor.BLACK);
+ //blackBorder.scrollFactor.set();
- snapText = new FlxText(60,10,0,"Snap: 1/" + snap + " (Press Control to unsnap the cursor)\nAdd Notes: 1-8 (or click)\n", 14);
+ //blackBorder.alpha = 0.3;
+
+
+ snapText = new FlxText(60,10,0,"", 14);
snapText.scrollFactor.set();
-
- gridBlackLine = new FlxSprite(gridBG.x + gridBG.width / 2).makeGraphic(2, Std.int(gridBG.height), FlxColor.BLACK);
- add(gridBlackLine);
+
curRenderedNotes = new FlxTypedGroup();
curRenderedSustains = new FlxTypedGroup();
@@ -147,16 +204,122 @@ class ChartingState extends MusicBeatState
// sections = _song.notes;
- updateGrid();
-
loadSong(_song.song);
Conductor.changeBPM(_song.bpm);
Conductor.mapBPMChanges(_song);
leftIcon = new HealthIcon(_song.player1);
rightIcon = new HealthIcon(_song.player2);
- leftIcon.scrollFactor.set(1, 1);
- rightIcon.scrollFactor.set(1, 1);
+
+ var index = 0;
+
+ if (_song.eventObjects == null)
+ _song.eventObjects = [new Song.Event("Init BPM",0,_song.bpm,"BPM Change")];
+
+ if (_song.eventObjects.length == 0)
+ _song.eventObjects = [new Song.Event("Init BPM",0,_song.bpm,"BPM Change")];
+
+
+ trace("goin");
+
+ var currentIndex = 0;
+ for (i in _song.eventObjects)
+ {
+ var name = Reflect.field(i,"name");
+ var type = Reflect.field(i,"type");
+ var pos = Reflect.field(i,"position");
+ var value = Reflect.field(i,"value");
+
+ if (type == "BPM Change")
+ {
+ var beat:Float = pos;
+
+ var endBeat:Float = Math.POSITIVE_INFINITY;
+
+ TimingStruct.addTiming(beat,value,endBeat, 0); // offset in this case = start time since we don't have a offset
+
+ if (currentIndex != 0)
+ {
+ var data = TimingStruct.AllTimings[currentIndex - 1];
+ data.endBeat = beat;
+ data.length = (data.endBeat - data.startBeat) / (data.bpm / 60);
+ TimingStruct.AllTimings[currentIndex].startTime = data.startTime + data.length;
+ }
+
+ currentIndex++;
+ }
+ }
+
+ var lastSeg = TimingStruct.AllTimings[TimingStruct.AllTimings.length - 1];
+
+ for (i in 0...TimingStruct.AllTimings.length)
+ {
+ var seg = TimingStruct.AllTimings[i];
+ if (i == TimingStruct.AllTimings.length - 1)
+ lastSeg = seg;
+ }
+
+ recalculateAllSectionTimes();
+
+ trace("Song length in MS: " + FlxG.sound.music.length);
+
+ for(i in 0...9000000) // REALLY HIGH BEATS just cuz like ig this is the upper limit, I mean ur chart is probably going to run like ass anyways
+ {
+ var seg = TimingStruct.getTimingAtBeat(i);
+
+
+ var start:Float = (i - seg.startBeat) / (seg.bpm / 60);
+
+ var time = (seg.startTime + start) * 1000;
+
+ if (time > FlxG.sound.music.length)
+ break;
+
+ lengthInBeats = i;
+ }
+
+ lengthInSteps = lengthInBeats * 4;
+
+ trace('LENGTH IN STEPS ' + lengthInSteps + ' | LENGTH IN BEATS ' + lengthInBeats + ' | SECTIONS: ' + Math.floor(((lengthInSteps + 16)) / 16));
+
+ var sections = Math.floor(((lengthInSteps + 16)) / 16);
+
+ var targetY = getYfromStrum(FlxG.sound.music.length);
+
+ trace("TARGET " + targetY);
+
+ for (awfgaw in 0...Math.round(targetY / 640) + 1920) // grids/steps
+ {
+ var renderer = new SectionRender(0,640 * awfgaw,GRID_SIZE);
+ if (_song.notes[awfgaw] == null)
+ _song.notes.push(newSection(16,true,false));
+ renderer.section = _song.notes[awfgaw];
+
+ sectionRenderes.add(renderer);
+
+ var down = getYfromStrum(renderer.section.startTime) * zoomFactor;
+
+ var sectionicon = _song.notes[awfgaw].mustHitSection ? new HealthIcon(_song.player1).clone() : new HealthIcon(_song.player2).clone();
+ sectionicon.x = -95;
+ sectionicon.y = down - 75;
+ sectionicon.setGraphicSize(0, 45);
+
+ renderer.icon = sectionicon;
+ renderer.lastUpdated = _song.notes[awfgaw].mustHitSection;
+
+ add(sectionicon);
+ height = Math.floor(renderer.y);
+ }
+
+
+
+ trace(height);
+
+ gridBlackLine = new FlxSprite(gridBG.width / 2).makeGraphic(2, height, FlxColor.BLACK);
+
+ //leftIcon.scrollFactor.set();
+ //rightIcon.scrollFactor.set();
+
leftIcon.setGraphicSize(0, 45);
rightIcon.setGraphicSize(0, 45);
@@ -167,16 +330,16 @@ class ChartingState extends MusicBeatState
leftIcon.setPosition(0, -100);
rightIcon.setPosition(gridBG.width / 2, -100);
+ leftIcon.scrollFactor.set();
+ rightIcon.scrollFactor.set();
+
bpmTxt = new FlxText(1000, 50, 0, "", 16);
bpmTxt.scrollFactor.set();
add(bpmTxt);
- strumLine = new FlxSprite(0, 50).makeGraphic(Std.int(FlxG.width / 2), 4);
- add(strumLine);
+ strumLine = new FlxSprite(0, 0).makeGraphic(Std.int(GRID_SIZE * 8), 4);
dummyArrow = new FlxSprite().makeGraphic(GRID_SIZE, GRID_SIZE);
- add(dummyArrow);
-
var tabs = [
{name: "Song", label: 'Song Data'},
{name: "Section", label: 'Section Data'},
@@ -185,27 +348,614 @@ class ChartingState extends MusicBeatState
];
UI_box = new FlxUITabMenu(null, tabs, true);
-
+
+ UI_box.scrollFactor.set();
UI_box.resize(300, 400);
- UI_box.x = FlxG.width / 2;
+ UI_box.x = FlxG.width / 2 + 40;
UI_box.y = 20;
+
+ var opt_tabs = [{name: "Options", label:'Song Options'}, {name: "Events", label:'Song Events'}];
+
+ UI_options = new FlxUITabMenu(null, opt_tabs, true);
+
+ UI_options.scrollFactor.set();
+ UI_options.selected_tab = 0;
+ UI_options.resize(300, 200);
+ UI_options.x = UI_box.x;
+ UI_options.y = FlxG.height - 300;
+ add(UI_options);
add(UI_box);
+
addSongUI();
addSectionUI();
addNoteUI();
+ addOptionsUI();
+ addEventsUI();
+
+ regenerateLines();
+
+
+ updateGrid();
+
+ trace("bruh");
+
+
+ add(sectionRenderes);
+ add(dummyArrow);
+ add(strumLine);
+ add(lines);
+ add(texts);
+ add(gridBlackLine);
add(curRenderedNotes);
add(curRenderedSustains);
- add(blackBorder);
+ trace("bruh");
+
+ //add(blackBorder);
add(snapText);
+ trace("bruh");
+ trace("create");
+ TimingStruct.clearTimings();
+
+ var currentIndex = 0;
+ for (i in _song.eventObjects)
+ {
+ if (i.type == "BPM Change")
+ {
+ var beat:Float = i.position;
+
+ var endBeat:Float = Math.POSITIVE_INFINITY;
+
+ TimingStruct.addTiming(beat,i.value,endBeat, 0); // offset in this case = start time since we don't have a offset
+
+ if (currentIndex != 0)
+ {
+ var data = TimingStruct.AllTimings[currentIndex - 1];
+ data.endBeat = beat;
+ data.length = (data.endBeat - data.startBeat) / (data.bpm / 60);
+ TimingStruct.AllTimings[currentIndex].startTime = data.startTime + data.length;
+ }
+
+ currentIndex++;
+ }
+ }
super.create();
}
+ public var texts:FlxTypedGroup;
+
+ function regenerateLines()
+ {
+ while(lines.members.length > 0)
+ {
+ lines.members[0].destroy();
+ lines.members.remove(lines.members[0]);
+ }
+
+ while(texts.members.length > 0)
+ {
+ texts.members[0].destroy();
+ texts.members.remove(texts.members[0]);
+ }
+ trace("removed lines and texts");
+
+ if (_song.eventObjects != null)
+ for(i in _song.eventObjects)
+ {
+ var seg = TimingStruct.getTimingAtBeat(i.position);
+
+ var posi:Float = 0;
+
+ if (seg != null)
+ {
+ var start:Float = (i.position - seg.startBeat) / (seg.bpm / 60);
+
+ posi = seg.startTime + start;
+ }
+
+ var pos = getYfromStrum(posi * 1000) * zoomFactor;
+
+ if (pos < 0)
+ pos = 0;
+
+ var type = i.type;
+
+ var text = new FlxText(-190, pos,0,i.name + "\n" + type + "\n" + i.value,12);
+ var line = new FlxSprite(0, pos).makeGraphic(Std.int(GRID_SIZE * 8), 4, FlxColor.BLUE);
+
+ line.alpha = 0.2;
+
+ lines.add(line);
+ texts.add(text);
+
+ add(line);
+ add(text);
+ }
+
+ for (i in sectionRenderes)
+ {
+ var pos = getYfromStrum(i.section.startTime) * zoomFactor;
+ i.icon.y = pos - 75;
+
+ var line = new FlxSprite(0, pos).makeGraphic(Std.int(GRID_SIZE * 8), 4, FlxColor.BLACK);
+ line.alpha = 0.4;
+ lines.add(line);
+ }
+ }
+
+ function addGrid(?divisions:Float = 1)
+ {
+ // This here is because non-integer numbers aren't supported as grid sizes, making the grid slowly 'drift' as it goes on
+ var h = GRID_SIZE / divisions;
+ if (Math.floor(h) != h)
+ h = GRID_SIZE;
+
+ remove(gridBG);
+ gridBG = FlxGridOverlay.create(GRID_SIZE, Std.int(h), GRID_SIZE * 8,GRID_SIZE * 16);
+ trace(gridBG.height);
+ //gridBG.scrollFactor.set();
+ //gridBG.x += 358;
+ //gridBG.y += 390;
+ trace("height of " + (Math.floor(lengthInSteps)));
+
+
+ /*for(i in 0...Math.floor(lengthInSteps))
+ {
+ trace("Creating sprite " + i);
+ var grid = FlxGridOverlay.create(GRID_SIZE, Std.int(h), GRID_SIZE * 8, GRID_SIZE * 16);
+ add(grid);
+ if (i > lengthInSteps)
+ break;
+ }*/
+
+ var totalHeight = 0;
+
+ //add(gridBG);
+
+
+ remove(gridBlackLine);
+ gridBlackLine = new FlxSprite(0 + gridBG.width / 2).makeGraphic(2, Std.int(Math.floor(lengthInSteps)), FlxColor.BLACK);
+ add(gridBlackLine);
+ }
+
+ var stepperDiv:FlxUINumericStepper;
+ var check_snap:FlxUICheckBox;
+ var listOfEvents:FlxUIDropDownMenu;
+ var currentSelectedEventName:String = "";
+ var savedType:String = "";
+ var savedValue:String = "";
+ var currentEventPosition:Float = 0;
+
+ function containsName(name:String, events:Array):Song.Event
+ {
+ for (i in events)
+ {
+ var thisName = Reflect.field(i,"name");
+
+ if (thisName == name)
+ return i;
+ }
+ return null;
+ }
+
+ public var chartEvents:Array = [];
+
+ public var Typeables:Array = [];
+
+ function addEventsUI()
+ {
+ if (_song.eventObjects == null)
+ {
+ _song.eventObjects = [new Song.Event("Init BPM",0,_song.bpm,"BPM Change")];
+ }
+
+ var firstEvent = "";
+
+ if (Lambda.count(_song.eventObjects) != 0)
+ {
+ firstEvent = _song.eventObjects[0].name;
+ }
+
+ var listLabel = new FlxText(10, 5, 'List of Events');
+ var nameLabel = new FlxText(150, 5, 'Event Name');
+ var eventName = new FlxUIInputText(150,20,80,"");
+ var typeLabel = new FlxText(10, 45, 'Type of Event');
+ var eventType = new FlxUIDropDownMenu(10,60,FlxUIDropDownMenu.makeStrIdLabelArray(["BPM Change", "Scroll Speed Change"], true));
+ var valueLabel = new FlxText(150, 45, 'Event Value');
+ var eventValue = new FlxUIInputText(150,60,80,"");
+ var eventSave = new FlxButton(10,155,"Save Event", function() {
+ var pog:Song.Event = new Song.Event(currentSelectedEventName,currentEventPosition,HelperFunctions.truncateFloat(Std.parseFloat(savedValue), 3),savedType);
+
+ trace("trying to save " + currentSelectedEventName);
+
+ var obj = containsName(pog.name,_song.eventObjects);
+
+
+ if (pog.name == "")
+ return;
+
+ trace("yeah we can save it");
+
+ if (obj != null)
+ _song.eventObjects.remove(obj);
+ _song.eventObjects.push(pog);
+
+ trace(_song.eventObjects.length);
+
+ TimingStruct.clearTimings();
+
+ var currentIndex = 0;
+ for (i in _song.eventObjects)
+ {
+ var name = Reflect.field(i,"name");
+ var type = Reflect.field(i,"type");
+ var pos = Reflect.field(i,"position");
+ var value = Reflect.field(i,"value");
+
+ trace(i.type);
+ if (type == "BPM Change")
+ {
+ var beat:Float = pos;
+
+ var endBeat:Float = Math.POSITIVE_INFINITY;
+
+ TimingStruct.addTiming(beat,value,endBeat, 0); // offset in this case = start time since we don't have a offset
+
+ if (currentIndex != 0)
+ {
+ var data = TimingStruct.AllTimings[currentIndex - 1];
+ data.endBeat = beat;
+ data.length = (data.endBeat - data.startBeat) / (data.bpm / 60);
+ TimingStruct.AllTimings[currentIndex].startTime = data.startTime + data.length;
+ }
+
+ currentIndex++;
+ }
+ }
+
+ if (pog.type == "BPM Change")
+ recalculateAllSectionTimes();
+
+ regenerateLines();
+
+ var listofnames = [];
+
+ for (key => value in _song.eventObjects) {
+ listofnames.push(value.name);
+ }
+
+ listOfEvents.setData(FlxUIDropDownMenu.makeStrIdLabelArray(listofnames, true));
+
+ listOfEvents.selectedLabel = pog.name;
+
+ trace('end');
+ });
+ var posLabel = new FlxText(150, 85, 'Event Position');
+ var eventPos = new FlxUIInputText(150,100,80,"");
+ var eventAdd = new FlxButton(95,155,"Add Event", function() {
+
+ var pog:Song.Event = new Song.Event("New Event " + HelperFunctions.truncateFloat(curDecimalBeat, 3),HelperFunctions.truncateFloat(curDecimalBeat, 3),_song.bpm + "","BPM Change");
+
+ trace("adding " + pog.name);
+
+ var obj = containsName(pog.name,_song.eventObjects);
+
+ if (obj != null)
+ return;
+
+ trace("yeah we can add it");
+
+ _song.eventObjects.push(pog);
+
+ eventName.text = pog.name;
+ eventType.selectedLabel = pog.type;
+ eventValue.text = pog.value;
+ eventPos.text = pog.position + "";
+ currentSelectedEventName = pog.name;
+ currentEventPosition = pog.position;
+
+ savedType = pog.type;
+ savedValue = pog.value;
+
+ var listofnames = [];
+
+ for (key => value in _song.eventObjects) {
+ listofnames.push(value.name);
+ }
+
+ listOfEvents.setData(FlxUIDropDownMenu.makeStrIdLabelArray(listofnames, true));
+
+ listOfEvents.selectedLabel = pog.name;
+
+ TimingStruct.clearTimings();
+
+ var currentIndex = 0;
+ for (i in _song.eventObjects)
+ {
+ var name = Reflect.field(i,"name");
+ var type = Reflect.field(i,"type");
+ var pos = Reflect.field(i,"position");
+ var value = Reflect.field(i,"value");
+
+ trace(i.type);
+ if (type == "BPM Change")
+ {
+ var beat:Float = pos;
+
+ var endBeat:Float = Math.POSITIVE_INFINITY;
+
+ TimingStruct.addTiming(beat,value,endBeat, 0); // offset in this case = start time since we don't have a offset
+
+ if (currentIndex != 0)
+ {
+ var data = TimingStruct.AllTimings[currentIndex - 1];
+ data.endBeat = beat;
+ data.length = (data.endBeat - data.startBeat) / (data.bpm / 60);
+ TimingStruct.AllTimings[currentIndex].startTime = data.startTime + data.length;
+ }
+
+ currentIndex++;
+ }
+ }
+ trace("BPM CHANGES:");
+
+ for (i in TimingStruct.AllTimings)
+ trace(i.bpm + " - START: " + i.startBeat + " - END: " + i.endBeat + " - START-TIME: " + i.startTime);
+
+ recalculateAllSectionTimes();
+
+ regenerateLines();
+
+
+ });
+ var eventRemove = new FlxButton(180,155,"Remove Event", function() {
+
+ trace("lets see if we can remove " + listOfEvents.selectedLabel);
+
+ var obj = containsName(listOfEvents.selectedLabel,_song.eventObjects);
+
+ trace(obj);
+
+ if (obj == null)
+ return;
+
+ trace("yeah we can remove it it");
+
+ _song.eventObjects.remove(obj);
+
+ var firstEvent = _song.eventObjects[0];
+
+ if (firstEvent == null)
+ {
+ _song.eventObjects.push(new Song.Event("Init BPM",0,_song.bpm,"BPM Change"));
+ firstEvent = _song.eventObjects[0];
+ }
+
+ eventName.text = firstEvent.name;
+ eventType.selectedLabel = firstEvent.type;
+ eventValue.text = firstEvent.value;
+ eventPos.text = firstEvent.position + "";
+ currentSelectedEventName = firstEvent.name;
+ currentEventPosition = firstEvent.position;
+
+ savedType = firstEvent.type;
+ savedValue = firstEvent.value;
+
+ var listofnames = [];
+
+ for (key => value in _song.eventObjects) {
+ listofnames.push(value.name);
+ }
+
+ listOfEvents.setData(FlxUIDropDownMenu.makeStrIdLabelArray(listofnames, true));
+
+ listOfEvents.selectedLabel = firstEvent.name;
+
+ TimingStruct.clearTimings();
+
+ var currentIndex = 0;
+ for (i in _song.eventObjects)
+ {
+ var name = Reflect.field(i,"name");
+ var type = Reflect.field(i,"type");
+ var pos = Reflect.field(i,"position");
+ var value = Reflect.field(i,"value");
+
+ trace(i.type);
+ if (type == "BPM Change")
+ {
+ var beat:Float = pos;
+
+ var endBeat:Float = Math.POSITIVE_INFINITY;
+
+ TimingStruct.addTiming(beat,value,endBeat, 0); // offset in this case = start time since we don't have a offset
+
+ if (currentIndex != 0)
+ {
+ var data = TimingStruct.AllTimings[currentIndex - 1];
+ data.endBeat = beat;
+ data.length = (data.endBeat - data.startBeat) / (data.bpm / 60);
+ TimingStruct.AllTimings[currentIndex].startTime = data.startTime + data.length;
+ }
+
+ currentIndex++;
+ }
+ }
+
+ recalculateAllSectionTimes();
+
+ regenerateLines();
+
+
+ });
+ var updatePos = new FlxButton(150,120,"Update Pos", function() {
+ var obj = containsName(currentSelectedEventName,_song.eventObjects);
+ if (obj == null)
+ return;
+ currentEventPosition = curDecimalBeat;
+ obj.position = currentEventPosition;
+ eventPos.text = currentEventPosition + "";
+ });
+
+
+
+ var listofnames = [];
+
+ var firstEventObject = null;
+
+ for (event in _song.eventObjects) {
+ var name = Reflect.field(event,"name");
+ var type = Reflect.field(event,"type");
+ var pos = Reflect.field(event,"position");
+ var value = Reflect.field(event,"value");
+
+ trace(value);
+
+ var eventt = new Song.Event(name,pos,value,type);
+
+ chartEvents.push(eventt);
+ listofnames.push(name);
+ }
+
+ _song.eventObjects = chartEvents;
+
+ if (listofnames.length == 0)
+ listofnames.push("");
+
+ if (_song.eventObjects.length != 0)
+ firstEventObject = _song.eventObjects[0];
+ trace("bruh");
+
+
+ if (firstEvent != "")
+ {
+ trace(firstEventObject);
+ eventName.text = firstEventObject.name;
+ trace("bruh");
+ eventType.selectedLabel = firstEventObject.type;
+ trace("bruh");
+ eventValue.text = firstEventObject.value;
+ trace("bruh");
+ currentSelectedEventName = firstEventObject.name;
+ trace("bruh");
+ currentEventPosition = firstEventObject.position;
+ trace("bruh");
+ eventPos.text = currentEventPosition + "";
+ trace("bruh");
+ }
+
+ listOfEvents = new FlxUIDropDownMenu(10,20, FlxUIDropDownMenu.makeStrIdLabelArray(listofnames, true), function(name:String)
+ {
+ var event = containsName(listOfEvents.selectedLabel,_song.eventObjects);
+
+ if (event == null)
+ return;
+
+ trace('selecting ' + name + ' found: ' + event);
+
+ eventName.text = event.name;
+ eventValue.text = event.value;
+ eventPos.text = event.position + "";
+ eventType.selectedLabel = event.type;
+ currentSelectedEventName = event.name;
+ currentEventPosition = event.position;
+ });
+
+ eventValue.callback = function(string:String, string2:String)
+ {
+ trace(string + " - value");
+ savedValue = string;
+ };
+
+ eventType.callback = function(type:String)
+ {
+ savedType = eventType.selectedLabel;
+ };
+
+ eventName.callback = function(string:String, string2:String)
+ {
+ var obj = containsName(currentSelectedEventName,_song.eventObjects);
+ if (obj == null)
+ {
+ currentSelectedEventName = string;
+ return;
+ }
+ obj = containsName(string,_song.eventObjects);
+ if (obj != null)
+ return;
+ obj = containsName(currentSelectedEventName,_song.eventObjects);
+ obj.name = string;
+ currentSelectedEventName = string;
+ };
+ trace("bruh");
+
+ Typeables.push(eventPos);
+ Typeables.push(eventValue);
+ Typeables.push(eventName);
+
+ var tab_events = new FlxUI(null, UI_options);
+ tab_events.name = "Events";
+ tab_events.add(posLabel);
+ tab_events.add(valueLabel);
+ tab_events.add(nameLabel);
+ tab_events.add(listLabel);
+ tab_events.add(typeLabel);
+ tab_events.add(eventName);
+ tab_events.add(eventType);
+ tab_events.add(listOfEvents);
+ tab_events.add(eventValue);
+ tab_events.add(eventSave);
+ tab_events.add(eventAdd);
+ tab_events.add(eventRemove);
+ tab_events.add(eventPos);
+ tab_events.add(updatePos);
+ UI_options.addGroup(tab_events);
+ }
+
+ function addOptionsUI()
+ {
+
+
+ var hitsounds = new FlxUICheckBox(10, 60, null, null, "Play hitsounds", 100);
+ hitsounds.checked = false;
+ hitsounds.callback = function()
+ {
+ playClaps = hitsounds.checked;
+ };
+
+ var check_mute_inst = new FlxUICheckBox(10, 90, null, null, "Mute Instrumental", 100);
+ check_mute_inst.checked = false;
+ check_mute_inst.callback = function()
+ {
+ var vol:Float = 1;
+
+ if (check_mute_inst.checked)
+ vol = 0;
+
+ FlxG.sound.music.volume = vol;
+ };
+
+ check_snap = new FlxUICheckBox(80, 25, null, null, "Snap to grid", 100);
+ check_snap.checked = defaultSnap;
+ // _song.needsVoices = check_voices.checked;
+ check_snap.callback = function()
+ {
+ defaultSnap = check_snap.checked;
+ trace('CHECKED!');
+ };
+
+ var tab_options = new FlxUI(null, UI_options);
+ tab_options.name = "Options";
+ tab_options.add(hitsounds);
+ tab_options.add(check_mute_inst);
+ UI_options.addGroup(tab_options);
+ }
+
function addSongUI():Void
{
var UI_songTitle = new FlxUIInputText(10, 10, 70, _song.song, 8);
@@ -220,18 +970,6 @@ class ChartingState extends MusicBeatState
trace('CHECKED!');
};
- var check_mute_inst = new FlxUICheckBox(10, 200, null, null, "Mute Instrumental (in editor)", 100);
- check_mute_inst.checked = false;
- check_mute_inst.callback = function()
- {
- var vol:Float = 1;
-
- if (check_mute_inst.checked)
- vol = 0;
-
- FlxG.sound.music.volume = vol;
- };
-
var saveButton:FlxButton = new FlxButton(110, 8, "Save", function()
{
saveLevel();
@@ -274,7 +1012,14 @@ class ChartingState extends MusicBeatState
var stepperSpeedLabel = new FlxText(74,80,'Scroll Speed');
var stepperVocalVol:FlxUINumericStepper = new FlxUINumericStepper(10, 95, 0.1, 1, 0.1, 10, 1);
+ #if sys
+ if (!PlayState.isSM)
+ stepperVocalVol.value = vocals.volume;
+ else
+ stepperVocalVol.value = 1;
+ #else
stepperVocalVol.value = vocals.volume;
+ #end
stepperVocalVol.name = 'song_vocalvol';
var stepperVocalVolLabel = new FlxText(74, 95, 'Vocal Volume');
@@ -283,14 +1028,6 @@ class ChartingState extends MusicBeatState
stepperSongVol.value = FlxG.sound.music.volume;
stepperSongVol.name = 'song_instvol';
-
- var hitsounds = new FlxUICheckBox(10, stepperSongVol.y + 60, null, null, "Play hitsounds", 100);
- hitsounds.checked = false;
- hitsounds.callback = function()
- {
- playClaps = hitsounds.checked;
- };
-
var stepperSongVolLabel = new FlxText(74, 110, 'Instrumental Volume');
@@ -309,10 +1046,10 @@ class ChartingState extends MusicBeatState
shiftNotes(Std.int(stepperShiftNoteDial.value),Std.int(stepperShiftNoteDialstep.value),Std.int(stepperShiftNoteDialms.value));
});
- var characters:Array = CoolUtil.coolTextFile(Paths.txt('characterList'));
- var gfVersions:Array = CoolUtil.coolTextFile(Paths.txt('gfVersionList'));
- var stages:Array = CoolUtil.coolTextFile(Paths.txt('stageList'));
- var noteStyles:Array = CoolUtil.coolTextFile(Paths.txt('noteStyleList'));
+ var characters:Array = CoolUtil.coolTextFile(Paths.txt('data/characterList'));
+ var gfVersions:Array = CoolUtil.coolTextFile(Paths.txt('data/gfVersionList'));
+ var stages:Array = CoolUtil.coolTextFile(Paths.txt('data/stageList'));
+ var noteStyles:Array = CoolUtil.coolTextFile(Paths.txt('data/noteStyleList'));
var player1DropDown = new FlxUIDropDownMenu(10, 100, FlxUIDropDownMenu.makeStrIdLabelArray(characters, true), function(character:String)
{
@@ -354,12 +1091,13 @@ class ChartingState extends MusicBeatState
var noteStyleLabel = new FlxText(10,280,64,'Note Skin');
+
var tab_group_song = new FlxUI(null, UI_box);
tab_group_song.name = "Song";
tab_group_song.add(UI_songTitle);
tab_group_song.add(restart);
tab_group_song.add(check_voices);
- tab_group_song.add(check_mute_inst);
+ //tab_group_song.add(check_mute_inst);
tab_group_song.add(saveButton);
tab_group_song.add(reloadSong);
tab_group_song.add(reloadSongJson);
@@ -379,7 +1117,7 @@ class ChartingState extends MusicBeatState
tab_group_song.add(shiftNoteDialLabel3);
tab_group_song.add(stepperShiftNoteDialms);
tab_group_song.add(shiftNoteButton);
- tab_group_song.add(hitsounds);
+ //tab_group_song.add(hitsounds);
var tab_group_assets = new FlxUI(null, UI_box);
tab_group_assets.name = "Assets";
@@ -396,9 +1134,11 @@ class ChartingState extends MusicBeatState
UI_box.addGroup(tab_group_song);
UI_box.addGroup(tab_group_assets);
- UI_box.scrollFactor.set();
+
+ camFollow = new FlxObject(280, 0, 1, 1);
+ add(camFollow);
- FlxG.camera.follow(strumLine);
+ FlxG.camera.follow(camFollow);
}
var stepperLength:FlxUINumericStepper;
@@ -412,15 +1152,6 @@ class ChartingState extends MusicBeatState
var tab_group_section = new FlxUI(null, UI_box);
tab_group_section.name = 'Section';
- stepperLength = new FlxUINumericStepper(10, 10, 4, 0, 0, 999, 0);
- stepperLength.value = _song.notes[curSection].lengthInSteps;
- stepperLength.name = "section_length";
-
- var stepperLengthLabel = new FlxText(74,10,'Section Length (in steps)');
-
- stepperSectionBPM = new FlxUINumericStepper(10, 80, 1, Conductor.bpm, 0, 999, 0);
- stepperSectionBPM.value = Conductor.bpm;
- stepperSectionBPM.name = 'section_bpm';
var stepperCopy:FlxUINumericStepper = new FlxUINumericStepper(110, 132, 1, 1, -999, 999, 0);
var stepperCopyLabel = new FlxText(174,132,'sections back');
@@ -431,39 +1162,87 @@ class ChartingState extends MusicBeatState
});
var clearSectionButton:FlxButton = new FlxButton(10, 150, "Clear Section", clearSection);
+ var startSection:FlxButton = new FlxButton(10, 85, "Play Here", function() {
+ PlayState.SONG = _song;
+ FlxG.sound.music.stop();
+ if (!PlayState.isSM)
+ vocals.stop();
+ PlayState.startTime = lastUpdatedSection.startTime;
+ LoadingState.loadAndSwitchState(new PlayState());
+ });
var swapSection:FlxButton = new FlxButton(10, 170, "Swap Section", function()
{
- for (i in 0..._song.notes[curSection].sectionNotes.length)
+
+ var sect = lastUpdatedSection;
+
+ if (sect == null)
+ return;
+
+ for (i in 0...sect.sectionNotes.length)
{
- var note = _song.notes[curSection].sectionNotes[i];
- note[1] = (note[1] + 4) % 8;
- _song.notes[curSection].sectionNotes[i] = note;
+ var note = sect.sectionNotes[i];
+ if (note[1] < 4)
+ note[1] += 4;
+ else
+ note[1] -= 4;
+ sect.sectionNotes[i] = note;
updateGrid();
}
});
- check_mustHitSection = new FlxUICheckBox(10, 30, null, null, "Camera Points to P1?", 100);
- check_mustHitSection.name = 'check_mustHit';
+ check_mustHitSection = new FlxUICheckBox(10, 30, null, null, "Camera Points to P1?", 100,null,function() {
+ var sect = lastUpdatedSection;
+
+ trace(sect);
+
+ if (sect == null)
+ return;
+
+ sect.mustHitSection = check_mustHitSection.checked;
+
+ for (i in sectionRenderes)
+ {
+ if (i.section.startTime == sect.startTime)
+ {
+ var cachedY = i.icon.y;
+ remove(i.icon);
+ var sectionicon = check_mustHitSection.checked ? new HealthIcon(_song.player1).clone() : new HealthIcon(_song.player2).clone();
+ sectionicon.x = -95;
+ sectionicon.y = cachedY;
+ sectionicon.setGraphicSize(0, 45);
+
+ i.icon = sectionicon;
+ i.lastUpdated = sect.mustHitSection;
+
+ add(sectionicon);
+ }
+ }
+ });
check_mustHitSection.checked = true;
// _song.needsVoices = check_mustHit.checked;
- check_altAnim = new FlxUICheckBox(10, 400, null, null, "Alternate Animation", 100);
+ check_altAnim = new FlxUICheckBox(10, 340, null, null, "Alternate Animation", 100);
check_altAnim.name = 'check_altAnim';
- check_changeBPM = new FlxUICheckBox(10, 60, null, null, 'Change BPM', 100);
- check_changeBPM.name = 'check_changeBPM';
+ var refresh = new FlxButton(10, 60, 'Refresh Section', function() {
+ var section = getSectionByTime(Conductor.songPosition);
- tab_group_section.add(stepperLength);
- tab_group_section.add(stepperLengthLabel);
- tab_group_section.add(stepperSectionBPM);
+ if (section == null)
+ return;
+
+ check_mustHitSection.checked = section.mustHitSection;
+ check_altAnim.checked = section.altAnim;
+ });
+
+ tab_group_section.add(refresh);
tab_group_section.add(stepperCopy);
tab_group_section.add(stepperCopyLabel);
tab_group_section.add(check_mustHitSection);
tab_group_section.add(check_altAnim);
- tab_group_section.add(check_changeBPM);
tab_group_section.add(copyButton);
tab_group_section.add(clearSectionButton);
tab_group_section.add(swapSection);
+ tab_group_section.add(startSection);
UI_box.addGroup(tab_group_section);
}
@@ -480,7 +1259,7 @@ class ChartingState extends MusicBeatState
writingNotesText = new FlxUIText(20,100, 0, "");
writingNotesText.setFormat("Arial",20,FlxColor.WHITE,FlxTextAlign.LEFT,FlxTextBorderStyle.OUTLINE,FlxColor.BLACK);
- stepperSusLength = new FlxUINumericStepper(10, 10, Conductor.stepCrochet / 2, 0, 0, Conductor.stepCrochet * _song.notes[curSection].lengthInSteps * 4);
+ stepperSusLength = new FlxUINumericStepper(10, 10, Conductor.stepCrochet / 2, 0, 0, Conductor.stepCrochet * 16 * 4);
stepperSusLength.value = 0;
stepperSusLength.name = 'note_susLength';
@@ -494,8 +1273,8 @@ class ChartingState extends MusicBeatState
UI_box.addGroup(tab_group_note);
- /*player2 = new Character(0,gridBG.y, _song.player2);
- player1 = new Boyfriend(player2.width * 0.2,gridBG.y + player2.height, _song.player1);
+ /*player2 = new Character(0,0, _song.player2);
+ player1 = new Boyfriend(player2.width * 0.2,0 + player2.height, _song.player1);
player1.y = player1.y - player1.height;
@@ -506,6 +1285,8 @@ class ChartingState extends MusicBeatState
UI_box.add(player2);*/
}
+
+
function loadSong(daSong:String):Void
{
@@ -514,23 +1295,41 @@ class ChartingState extends MusicBeatState
FlxG.sound.music.stop();
// vocals.stop();
}
-
+ #if sys
+ if (PlayState.isSM)
+ {
+ trace("Loading " + PlayState.pathToSm + "/" + PlayState.sm.header.MUSIC);
+ var bytes = File.getBytes(PlayState.pathToSm + "/" + PlayState.sm.header.MUSIC);
+ var sound = new Sound();
+ sound.loadCompressedDataFromByteArray(bytes.getData(), bytes.length);
+ FlxG.sound.playMusic(sound);
+ }
+ else
+ FlxG.sound.playMusic(Paths.inst(daSong), 0.6);
+ #else
FlxG.sound.playMusic(Paths.inst(daSong), 0.6);
+ #end
// WONT WORK FOR TUTORIAL OR TEST SONG!!! REDO LATER
+ #if sys
+ if (PlayState.isSM)
+ vocals = null;
+ else
+ vocals = new FlxSound().loadEmbedded(Paths.voices(daSong));
+ #else
vocals = new FlxSound().loadEmbedded(Paths.voices(daSong));
+ #end
FlxG.sound.list.add(vocals);
FlxG.sound.music.pause();
- vocals.pause();
+ if (!PlayState.isSM)
+ vocals.pause();
FlxG.sound.music.onComplete = function()
{
- vocals.pause();
- vocals.time = 0;
+ if (!PlayState.isSM)
+ vocals.pause();
FlxG.sound.music.pause();
- FlxG.sound.music.time = 0;
- changeSection();
};
}
@@ -561,13 +1360,8 @@ class ChartingState extends MusicBeatState
var label = check.getLabel().text;
switch (label)
{
- case 'Camera Points to P1?':
- _song.notes[curSection].mustHitSection = check.checked;
- case 'Change BPM':
- _song.notes[curSection].changeBPM = check.checked;
- FlxG.log.add('changed bpm shit');
case "Alternate Animation":
- _song.notes[curSection].altAnim = check.checked;
+ getSectionByTime(Conductor.songPosition).altAnim = check.checked;
}
}
else if (id == FlxUINumericStepper.CHANGE_EVENT && (sender is FlxUINumericStepper))
@@ -575,53 +1369,56 @@ class ChartingState extends MusicBeatState
var nums:FlxUINumericStepper = cast sender;
var wname = nums.name;
FlxG.log.add(wname);
- if (wname == 'section_length')
- {
- if (nums.value <= 4)
- nums.value = 4;
- _song.notes[curSection].lengthInSteps = Std.int(nums.value);
- updateGrid();
- }
- else if (wname == 'song_speed')
- {
- if (nums.value <= 0)
- nums.value = 0;
- _song.speed = nums.value;
- }
- else if (wname == 'song_bpm')
- {
- if (nums.value <= 0)
- nums.value = 1;
- tempBpm = Std.int(nums.value);
- Conductor.mapBPMChanges(_song);
- Conductor.changeBPM(Std.int(nums.value));
- }
- else if (wname == 'note_susLength')
- {
- if (curSelectedNote == null)
- return;
- if (nums.value <= 0)
- nums.value = 0;
- curSelectedNote[2] = nums.value;
- updateGrid();
- }
- else if (wname == 'section_bpm')
+ switch (wname)
{
- if (nums.value <= 0.1)
- nums.value = 0.1;
- _song.notes[curSection].bpm = Std.int(nums.value);
- updateGrid();
- }else if (wname == 'song_vocalvol')
- {
- if (nums.value <= 0.1)
- nums.value = 0.1;
- vocals.volume = nums.value;
- }else if (wname == 'song_instvol')
- {
- if (nums.value <= 0.1)
- nums.value = 0.1;
- FlxG.sound.music.volume = nums.value;
+ case 'section_length':
+ if (nums.value <= 4)
+ nums.value = 4;
+ getSectionByTime(Conductor.songPosition).lengthInSteps = Std.int(nums.value);
+ updateGrid();
+
+ case 'song_speed':
+ if (nums.value <= 0)
+ nums.value = 0;
+ _song.speed = nums.value;
+
+ case 'song_bpm':
+ if (nums.value <= 0)
+ nums.value = 1;
+ tempBpm = Std.int(nums.value);
+ Conductor.mapBPMChanges(_song);
+ Conductor.changeBPM(Std.int(nums.value));
+
+ case 'note_susLength':
+ if (curSelectedNote == null)
+ return;
+
+ if (nums.value <= 0)
+ nums.value = 0;
+ curSelectedNote[2] = nums.value;
+ updateGrid();
+
+ case 'section_bpm':
+ if (nums.value <= 0.1)
+ nums.value = 0.1;
+ getSectionByTime(Conductor.songPosition).bpm = Std.int(nums.value);
+ updateGrid();
+
+ case 'song_vocalvol':
+ if (nums.value <= 0.1)
+ nums.value = 0.1;
+ if (!PlayState.isSM)
+ vocals.volume = nums.value;
+
+ case 'song_instvol':
+ if (nums.value <= 0.1)
+ nums.value = 0.1;
+ FlxG.sound.music.volume = nums.value;
+
+ case 'divisions':
+ subDivisions = nums.value;
+ updateGrid();
}
}
@@ -633,58 +1430,272 @@ class ChartingState extends MusicBeatState
/* this function got owned LOL
function lengthBpmBullshit():Float
{
- if (_song.notes[curSection].changeBPM)
- return _song.notes[curSection].lengthInSteps * (_song.notes[curSection].bpm / _song.bpm);
+ if (getSectionByTime(Conductor.songPosition).changeBPM)
+ return getSectionByTime(Conductor.songPosition).lengthInSteps * (getSectionByTime(Conductor.songPosition).bpm / _song.bpm);
else
- return _song.notes[curSection].lengthInSteps;
+ return getSectionByTime(Conductor.songPosition).lengthInSteps;
}*/
+
+
function stepStartTime(step):Float
{
- return _song.bpm / (step / 4) / 60;
+ return Conductor.bpm / (step / 4) / 60;
}
- function sectionStartTime():Float
+ function sectionStartTime(?customIndex:Int = -1):Float
{
- var daBPM:Float = _song.bpm;
+ if (customIndex == -1)
+ customIndex = curSection;
+ var daBPM:Float = Conductor.bpm;
var daPos:Float = 0;
- for (i in 0...curSection)
+ for (i in 0...customIndex)
{
- if (_song.notes[i].changeBPM)
- {
- daBPM = _song.notes[i].bpm;
- }
daPos += 4 * (1000 * 60 / daBPM);
}
return daPos;
}
var writingNotes:Bool = false;
- var doSnapShit:Bool = true;
+ var doSnapShit:Bool = false;
+
+ public var diff:Float = 0;
+
+ public var changeIndex = 0;
+
+ public var currentBPM:Float = 0;
+ public var lastBPM:Float = 0;
+
+ public var updateFrame = 0;
+ public var lastUpdatedSection:SwagSection = null;
+
+ public function resizeEverything()
+ {
+ curRenderedNotes.forEach(function(note) {
+ var seg = TimingStruct.getTimingAtTimestamp(note.strumTime);
+ note.y = getYfromStrum(note.strumTime) * zoomFactor;
+ var stepCrochet = (((60 / seg.bpm) * 1000) / 4);
+ if (note.sustainLength >= 2)
+ {
+ note.noteCharterObject.y = note.y + GRID_SIZE;
+ note.noteCharterObject.makeGraphic(8,Math.floor((getYfromStrum(note.strumTime + note.sustainLength) * zoomFactor) - note.y),FlxColor.WHITE);
+ }
+ });
+
+ regenerateLines();
+ }
+
+
override function update(elapsed:Float)
{
updateHeads();
- snapText.text = "Snap: 1/" + snap + " (" + (doSnapShit ? "Control to disable" : "Snap Disabled, Control to renable") + ")\nAdd Notes: 1-8 (or click)\n";
+ var doInput = true;
- curStep = recalculateSteps();
+ for (i in Typeables)
+ {
+ if (i.hasFocus)
+ doInput = false;
+ }
- /*if (FlxG.keys.pressed.CONTROL && FlxG.keys.justPressed.RIGHT)
+ if (doInput)
+ {
+ if (FlxG.mouse.wheel != 0)
+ {
+ FlxG.sound.music.pause();
+
+ if (!PlayState.isSM)
+ vocals.pause();
+ claps.splice(0, claps.length);
+
+
+ if (FlxG.keys.pressed.CONTROL)
+ {
+ var amount = FlxG.mouse.wheel;
+
+ if(amount > 0)
+ amount = 0;
+
+ var increase:Float = 0;
+
+ if (amount < 0)
+ increase = -0.02;
+ else
+ increase = 0.02;
+
+
+ zoomFactor += increase;
+
+ if (zoomFactor > 2)
+ zoomFactor = 2;
+
+ if (zoomFactor < 0.1)
+ zoomFactor = 0.1;
+
+ resizeEverything();
+ }
+ else
+ {
+ var amount = FlxG.mouse.wheel;
+
+ if(amount > 0 && strumLine.y < 0)
+ amount = 0;
+
+ if (doSnapShit)
+ {
+ var increase:Float = 0;
+ var beats:Float = 0;
+
+ if (amount < 0)
+ {
+ increase = 1 / deezNuts.get(snap);
+ beats = (Math.floor((curDecimalBeat * deezNuts.get(snap)) + 0.001) / deezNuts.get(snap)) + increase;
+ }
+ else
+ {
+ increase = -1 / deezNuts.get(snap);
+ beats = ((Math.ceil(curDecimalBeat * deezNuts.get(snap)) - 0.001) / deezNuts.get(snap)) + increase;
+ }
+
+ trace("SNAP - " + snap + " INCREASE - " + increase + " - GO TO BEAT " + beats);
+
+ var data = TimingStruct.getTimingAtBeat(beats);
+
+ if (beats <= 0)
+ FlxG.sound.music.time = 0;
+
+ var bpm = data != null ? data.bpm : _song.bpm;
+
+ if (data != null)
+ {
+
+ FlxG.sound.music.time = (data.startTime + ((beats - data.startBeat) / (bpm/60)) ) * 1000;
+ }
+ }
+ if (!PlayState.isSM)
+ vocals.time = FlxG.sound.music.time;
+ }
+ }
+ }
+
+ if (updateFrame == 4)
+ {
+ TimingStruct.clearTimings();
+
+ var currentIndex = 0;
+ for (i in _song.eventObjects)
+ {
+ if (i.type == "BPM Change")
+ {
+ var beat:Float = i.position;
+
+ var endBeat:Float = Math.POSITIVE_INFINITY;
+
+ TimingStruct.addTiming(beat,i.value,endBeat, 0); // offset in this case = start time since we don't have a offset
+
+ if (currentIndex != 0)
+ {
+ var data = TimingStruct.AllTimings[currentIndex - 1];
+ data.endBeat = beat;
+ data.length = (data.endBeat - data.startBeat) / (data.bpm / 60);
+ TimingStruct.AllTimings[currentIndex].startTime = data.startTime + data.length;
+ }
+
+ currentIndex++;
+ }
+ }
+
+ recalculateAllSectionTimes();
+
+ regenerateLines();
+ updateFrame++;
+ }
+ else if (updateFrame != 5)
+ updateFrame++;
+
+ snapText.text = "Snap: 1/" + snap + " (" + (doSnapShit ? "Shift to disable, Left or Right to increase/decrease" : "Snap Disabled, Shift to renable.") + ")\nAdd Notes: 1-8 (or click)\nZoom: " + zoomFactor;
+
+
+ if (FlxG.keys.justPressed.RIGHT)
snap = snap * 2;
- if (FlxG.keys.pressed.CONTROL && FlxG.keys.justPressed.LEFT)
+ if (FlxG.keys.justPressed.LEFT)
snap = Math.round(snap / 2);
- if (snap >= 192)
- snap = 192;
- if (snap <= 1)
- snap = 1;*/
-
- if (FlxG.keys.justPressed.CONTROL)
+ if (snap >= 64)
+ snap = 64;
+ if (snap <= 4)
+ snap = 4;
+ /*
+ if (FlxG.keys.justPressed.SHIFT)
doSnapShit = !doSnapShit;
+ */
+
+ doSnapShit = defaultSnap;
+ if (FlxG.keys.pressed.SHIFT)
+ {
+ doSnapShit = !defaultSnap;
+ }
+
+
+ check_snap.checked = doSnapShit;
Conductor.songPosition = FlxG.sound.music.time;
_song.song = typingShit.text;
+
+ var timingSeg = TimingStruct.getTimingAtTimestamp(Conductor.songPosition);
+
+ var start = Conductor.songPosition;
+
+ if (timingSeg != null)
+ {
+ var timingSegBpm = timingSeg.bpm;
+ currentBPM = timingSegBpm;
+
+ if (currentBPM != Conductor.bpm)
+ {
+ trace("BPM CHANGE to " + currentBPM);
+ Conductor.changeBPM(currentBPM, false);
+ }
+
+ var pog:Float = (curDecimalBeat - timingSeg.startBeat) / (Conductor.bpm / 60);
+
+ start = (timingSeg.startTime + pog) * 1000;
+ }
+
+
+ var weird = getSectionByTime(start, true);
+
+ FlxG.watch.addQuick("Section",weird);
+
+ if (weird != null)
+ {
+ if (lastUpdatedSection != getSectionByTime(start,true))
+ {
+ lastUpdatedSection = weird;
+ check_mustHitSection.checked = weird.mustHitSection;
+ check_altAnim.checked = weird.altAnim;
+ }
+ }
+
+
+ strumLine.y = getYfromStrum(start) * zoomFactor;
+ camFollow.y = strumLine.y;
+
+
+ bpmTxt.text = Std.string(FlxMath.roundDecimal(Conductor.songPosition / 1000, 2))
+ + " / "
+ + Std.string(FlxMath.roundDecimal(FlxG.sound.music.length / 1000, 2))
+ + "\nCur Section: "
+ + curSection
+ + "\nCurBPM: "
+ + currentBPM
+ + "\nCurBeat: "
+ + HelperFunctions.truncateFloat(curDecimalBeat,3)
+ + "\nZoom: "
+ + zoomFactor;
+
+
var left = FlxG.keys.justPressed.ONE;
var down = FlxG.keys.justPressed.TWO;
var up = FlxG.keys.justPressed.THREE;
@@ -696,6 +1707,8 @@ class ChartingState extends MusicBeatState
var pressArray = [left, down, up, right, leftO, downO, upO, rightO];
var delete = false;
+ if (doInput)
+ {
curRenderedNotes.forEach(function(note:Note)
{
if (strumLine.overlaps(note) && pressArray[Math.floor(Math.abs(note.noteData))])
@@ -713,10 +1726,7 @@ class ChartingState extends MusicBeatState
addNote(new Note(Conductor.songPosition,p));
}
}
-
- strumLine.y = getYfromStrum((Conductor.songPosition - sectionStartTime()) % (Conductor.stepCrochet * _song.notes[curSection].lengthInSteps));
-
-
+ }
if (playClaps)
{
@@ -724,21 +1734,21 @@ class ChartingState extends MusicBeatState
{
if (FlxG.sound.music.playing)
{
- FlxG.overlap(strumLine, note, function(_, _)
+ if (strumLine.overlaps(note))
{
if(!claps.contains(note))
{
claps.push(note);
FlxG.sound.play(Paths.sound('SNAP'));
}
- });
+ }
}
});
}
/*curRenderedNotes.forEach(function(note:Note) {
if (strumLine.overlaps(note) && strumLine.y == note.y) // yandere dev type shit
{
- if (_song.notes[curSection].mustHitSection)
+ if (getSectionByTime(Conductor.songPosition).mustHitSection)
{
trace('must hit ' + Math.abs(note.noteData));
if (note.noteData < 4)
@@ -805,23 +1815,10 @@ class ChartingState extends MusicBeatState
}
});*/
- if (curBeat % 4 == 0 && curStep >= 16 * (curSection + 1))
- {
- trace(curStep);
- trace((_song.notes[curSection].lengthInSteps) * (curSection + 1));
- trace('DUMBSHIT');
- if (_song.notes[curSection + 1] == null)
- {
- addSection();
- }
-
- changeSection(curSection + 1, false);
- }
-
- FlxG.watch.addQuick('daBeat', curBeat);
- FlxG.watch.addQuick('daStep', curStep);
+ FlxG.watch.addQuick('daBeat', curDecimalBeat);
+
if (FlxG.mouse.justPressed)
{
if (FlxG.mouse.overlaps(curRenderedNotes))
@@ -843,10 +1840,10 @@ class ChartingState extends MusicBeatState
}
else
{
- if (FlxG.mouse.x > gridBG.x
- && FlxG.mouse.x < gridBG.x + gridBG.width
- && FlxG.mouse.y > gridBG.y
- && FlxG.mouse.y < gridBG.y + (GRID_SIZE * _song.notes[curSection].lengthInSteps))
+ if (FlxG.mouse.x > 0
+ && FlxG.mouse.x < 0 + gridBG.width
+ && FlxG.mouse.y > 0
+ && FlxG.mouse.y < 0 + height)
{
FlxG.log.add('added note');
addNote();
@@ -854,35 +1851,42 @@ class ChartingState extends MusicBeatState
}
}
- if (FlxG.mouse.x > gridBG.x
- && FlxG.mouse.x < gridBG.x + gridBG.width
- && FlxG.mouse.y > gridBG.y
- && FlxG.mouse.y < gridBG.y + (GRID_SIZE * _song.notes[curSection].lengthInSteps))
+ if (FlxG.mouse.x > 0
+ && FlxG.mouse.x < gridBG.width
+ && FlxG.mouse.y > 0
+ && FlxG.mouse.y < height)
{
+ dummyArrow.visible = true;
+
dummyArrow.x = Math.floor(FlxG.mouse.x / GRID_SIZE) * GRID_SIZE;
- if (FlxG.keys.pressed.SHIFT)
- dummyArrow.y = FlxG.mouse.y;
- else
- dummyArrow.y = Math.floor(FlxG.mouse.y / GRID_SIZE) * GRID_SIZE;
+
+ dummyArrow.y = (Math.floor(FlxG.mouse.y / (GRID_SIZE / deezNuts.get(snap))) * (GRID_SIZE / deezNuts.get(snap)));
+ }
+ else
+ {
+ dummyArrow.visible = false;
}
+ if (doInput)
+ {
if (FlxG.keys.justPressed.ENTER)
{
lastSection = curSection;
PlayState.SONG = _song;
FlxG.sound.music.stop();
+ if (!PlayState.isSM)
vocals.stop();
LoadingState.loadAndSwitchState(new PlayState());
}
if (FlxG.keys.justPressed.E)
{
- changeNoteSustain(Conductor.stepCrochet);
+ changeNoteSustain(((60 / (timingSeg != null ? timingSeg.bpm : _song.bpm)) * 1000) / 4);
}
if (FlxG.keys.justPressed.Q)
{
- changeNoteSustain(-Conductor.stepCrochet);
+ changeNoteSustain(-(((60 / (timingSeg != null ? timingSeg.bpm : _song.bpm)) * 1000) / 4));
}
if (FlxG.keys.justPressed.TAB)
@@ -919,65 +1923,33 @@ class ChartingState extends MusicBeatState
var shiftThing:Int = 1;
if (FlxG.keys.pressed.SHIFT)
shiftThing = 4;
- if (!FlxG.keys.pressed.CONTROL)
- {
- if (FlxG.keys.justPressed.RIGHT || FlxG.keys.justPressed.D)
- changeSection(curSection + shiftThing);
- if (FlxG.keys.justPressed.LEFT || FlxG.keys.justPressed.A)
- changeSection(curSection - shiftThing);
- }
if (FlxG.keys.justPressed.SPACE)
{
if (FlxG.sound.music.playing)
{
FlxG.sound.music.pause();
+ if (!PlayState.isSM)
vocals.pause();
claps.splice(0, claps.length);
}
else
{
+ if (!PlayState.isSM)
vocals.play();
FlxG.sound.music.play();
}
}
- if (FlxG.keys.justPressed.R)
- {
- if (FlxG.keys.pressed.SHIFT)
- resetSection(true);
- else
- resetSection();
- }
-
- if (FlxG.sound.music.time < 0 || curStep < 0)
+ if (FlxG.sound.music.time < 0 || curDecimalBeat < 0)
FlxG.sound.music.time = 0;
- if (FlxG.mouse.wheel != 0)
- {
- FlxG.sound.music.pause();
- vocals.pause();
- claps.splice(0, claps.length);
-
- var stepMs = curStep * Conductor.stepCrochet;
-
-
- trace(Conductor.stepCrochet / snap);
-
- if (doSnapShit)
- FlxG.sound.music.time = stepMs - (FlxG.mouse.wheel * Conductor.stepCrochet / snap);
- else
- FlxG.sound.music.time -= (FlxG.mouse.wheel * Conductor.stepCrochet * 0.4);
- trace(stepMs + " + " + Conductor.stepCrochet / snap + " -> " + FlxG.sound.music.time);
-
- vocals.time = FlxG.sound.music.time;
- }
-
if (!FlxG.keys.pressed.SHIFT)
{
if (FlxG.keys.pressed.W || FlxG.keys.pressed.S)
{
FlxG.sound.music.pause();
+ if (!PlayState.isSM)
vocals.pause();
claps.splice(0, claps.length);
@@ -990,6 +1962,7 @@ class ChartingState extends MusicBeatState
else
FlxG.sound.music.time += daTime;
+ if (!PlayState.isSM)
vocals.time = FlxG.sound.music.time;
}
}
@@ -998,6 +1971,7 @@ class ChartingState extends MusicBeatState
if (FlxG.keys.justPressed.W || FlxG.keys.justPressed.S)
{
FlxG.sound.music.pause();
+ if (!PlayState.isSM)
vocals.pause();
var daTime:Float = Conductor.stepCrochet * 2;
@@ -1009,25 +1983,18 @@ class ChartingState extends MusicBeatState
else
FlxG.sound.music.time += daTime;
+ if (!PlayState.isSM)
vocals.time = FlxG.sound.music.time;
}
}
}
-
+ }
_song.bpm = tempBpm;
/* if (FlxG.keys.justPressed.UP)
Conductor.changeBPM(Conductor.bpm + 1);
if (FlxG.keys.justPressed.DOWN)
Conductor.changeBPM(Conductor.bpm - 1); */
-
- bpmTxt.text = bpmTxt.text = Std.string(FlxMath.roundDecimal(Conductor.songPosition / 1000, 2))
- + " / "
- + Std.string(FlxMath.roundDecimal(FlxG.sound.music.length / 1000, 2))
- + "\nSection: "
- + curSection
- + "\nCurStep: "
- + curStep;
super.update(elapsed);
}
@@ -1046,58 +2013,21 @@ class ChartingState extends MusicBeatState
updateGrid();
}
- override function beatHit()
- {
- trace('beat');
-
- super.beatHit();
- if (!player2.animation.curAnim.name.startsWith("sing"))
- {
- player2.playAnim('idle');
- }
- player1.dance();
- }
-
- function recalculateSteps():Int
- {
- var lastChange:BPMChangeEvent = {
- stepTime: 0,
- songTime: 0,
- bpm: 0
- }
- for (i in 0...Conductor.bpmChangeMap.length)
- {
- if (FlxG.sound.music.time > Conductor.bpmChangeMap[i].songTime)
- lastChange = Conductor.bpmChangeMap[i];
- }
-
- curStep = lastChange.stepTime + Math.floor((FlxG.sound.music.time - lastChange.songTime) / Conductor.stepCrochet);
- updateBeat();
-
- return curStep;
- }
-
function resetSection(songBeginning:Bool = false):Void
{
- updateGrid();
-
FlxG.sound.music.pause();
+ if (!PlayState.isSM)
vocals.pause();
// Basically old shit from changeSection???
- FlxG.sound.music.time = sectionStartTime();
-
- if (songBeginning)
- {
- FlxG.sound.music.time = 0;
- curSection = 0;
- }
+ FlxG.sound.music.time = 0;
+ if (!PlayState.isSM)
vocals.time = FlxG.sound.music.time;
- updateCurStep();
updateGrid();
- updateSectionUI();
+ if (!songBeginning)
+ updateSectionUI();
}
function changeSection(sec:Int = 0, ?updateMusic:Bool = true):Void
@@ -1114,6 +2044,7 @@ class ChartingState extends MusicBeatState
if (updateMusic)
{
FlxG.sound.music.pause();
+ if (!PlayState.isSM)
vocals.pause();
/*var daNum:Int = 0;
@@ -1125,6 +2056,7 @@ class ChartingState extends MusicBeatState
}*/
FlxG.sound.music.time = sectionStartTime();
+ if (!PlayState.isSM)
vocals.time = FlxG.sound.music.time;
updateCurStep();
}
@@ -1139,13 +2071,17 @@ class ChartingState extends MusicBeatState
function copySection(?sectionNum:Int = 1)
{
var daSec = FlxMath.maxInt(curSection, sectionNum);
+ var sect = lastUpdatedSection;
+
+ if (sect == null)
+ return;
for (note in _song.notes[daSec - sectionNum].sectionNotes)
{
var strum = note[0] + Conductor.stepCrochet * (_song.notes[daSec].lengthInSteps * sectionNum);
var copiedNote:Array = [strum, note[1], note[2]];
- _song.notes[daSec].sectionNotes.push(copiedNote);
+ sect.sectionNotes.push(copiedNote);
}
updateGrid();
@@ -1153,13 +2089,19 @@ class ChartingState extends MusicBeatState
function updateSectionUI():Void
{
- var sec = _song.notes[curSection];
+ var sec = getSectionByTime(Conductor.songPosition);
- stepperLength.value = sec.lengthInSteps;
- check_mustHitSection.checked = sec.mustHitSection;
- check_altAnim.checked = sec.altAnim;
- check_changeBPM.checked = sec.changeBPM;
- stepperSectionBPM.value = sec.bpm;
+ if (sec == null)
+ {
+ check_mustHitSection.checked = true;
+ check_altAnim.checked = false;
+ }
+ else
+ {
+ check_mustHitSection.checked = sec.mustHitSection;
+ check_altAnim.checked = sec.altAnim;
+ check_changeBPM.checked = sec.changeBPM;
+ }
}
function updateHeads():Void
@@ -1184,14 +2126,6 @@ class ChartingState extends MusicBeatState
function updateGrid():Void
{
- remove(gridBG);
- gridBG = FlxGridOverlay.create(GRID_SIZE, GRID_SIZE, GRID_SIZE * 8, GRID_SIZE * _song.notes[curSection].lengthInSteps);
- add(gridBG);
-
- remove(gridBlackLine);
- gridBlackLine = new FlxSprite(gridBG.x + gridBG.width / 2).makeGraphic(2, Std.int(gridBG.height), FlxColor.BLACK);
- add(gridBlackLine);
-
while (curRenderedNotes.members.length > 0)
{
curRenderedNotes.remove(curRenderedNotes.members[0], true);
@@ -1202,23 +2136,6 @@ class ChartingState extends MusicBeatState
curRenderedSustains.remove(curRenderedSustains.members[0], true);
}
- var sectionInfo:Array = _song.notes[curSection].sectionNotes;
-
- if (_song.notes[curSection].changeBPM && _song.notes[curSection].bpm > 0)
- {
- Conductor.changeBPM(_song.notes[curSection].bpm);
- FlxG.log.add('CHANGED BPM!');
- }
- else
- {
- // get last bpm
- var daBPM:Float = _song.bpm;
- for (i in 0...curSection)
- if (_song.notes[i].changeBPM)
- daBPM = _song.notes[i].bpm;
- Conductor.changeBPM(daBPM);
- }
-
/* // PORT BULLSHIT, INCASE THERE'S NO SUSTAIN DATA FOR A NOTE
for (sec in 0..._song.notes.length)
{
@@ -1233,37 +2150,69 @@ class ChartingState extends MusicBeatState
}
*/
- for (i in sectionInfo)
+ var currentSection = 0;
+
+ for (section in _song.notes)
{
- var daNoteInfo = i[1];
- var daStrumTime = i[0];
- var daSus = i[2];
-
- var note:Note = new Note(daStrumTime, daNoteInfo % 4,null,false,true);
- note.sustainLength = daSus;
- note.setGraphicSize(GRID_SIZE, GRID_SIZE);
- note.updateHitbox();
- note.x = Math.floor(daNoteInfo * GRID_SIZE);
- note.y = Math.floor(getYfromStrum((daStrumTime - sectionStartTime()) % (Conductor.stepCrochet * _song.notes[curSection].lengthInSteps)));
-
- if (curSelectedNote != null)
- if (curSelectedNote[0] == note.strumTime)
- lastNote = note;
-
- curRenderedNotes.add(note);
-
- if (daSus > 0)
+ for (i in section.sectionNotes)
{
- var sustainVis:FlxSprite = new FlxSprite(note.x + (GRID_SIZE / 2),
- note.y + GRID_SIZE).makeGraphic(8, Math.floor(FlxMath.remapToRange(daSus, 0, Conductor.stepCrochet * _song.notes[curSection].lengthInSteps, 0, gridBG.height)));
- curRenderedSustains.add(sustainVis);
+ var seg = TimingStruct.getTimingAtTimestamp(i[0]);
+ var daNoteInfo = i[1];
+ var daStrumTime = i[0];
+ var daSus = i[2];
+
+ var note:Note = new Note(daStrumTime, daNoteInfo % 4,null,false,true);
+ note.rawNoteData = daNoteInfo;
+ note.sustainLength = daSus;
+ note.setGraphicSize(Math.floor(GRID_SIZE), Math.floor(GRID_SIZE));
+ note.updateHitbox();
+ note.x = Math.floor(daNoteInfo * GRID_SIZE);
+
+ note.y = Math.floor(getYfromStrum(daStrumTime) * zoomFactor);
+
+ if (curSelectedNote != null)
+ if (curSelectedNote[0] == note.strumTime)
+ lastNote = note;
+
+ curRenderedNotes.add(note);
+
+ var stepCrochet = (((60 / seg.bpm) * 1000) / 4);
+
+ if (daSus > 0)
+ {
+ var sustainVis:FlxSprite = new FlxSprite(note.x + (GRID_SIZE / 2),
+ note.y + GRID_SIZE).makeGraphic(8, Math.floor((getYfromStrum(note.strumTime + note.sustainLength) * zoomFactor) - note.y));
+
+ note.noteCharterObject = sustainVis;
+
+ curRenderedSustains.add(sustainVis);
+ }
}
+ currentSection++;
}
+
}
private function addSection(lengthInSteps:Int = 16):Void
{
+ var daPos:Float = 0;
+ var start:Float = 0;
+
+ var bpm = _song.bpm;
+ for (i in 0...curSection)
+ {
+ for(ii in TimingStruct.AllTimings)
+ {
+ var data = TimingStruct.getTimingAtTimestamp(start);
+ if ((data != null ? data.bpm : _song.bpm) != bpm && bpm != ii.bpm)
+ bpm = ii.bpm;
+ }
+ start += (4 * (60 / bpm)) * 1000;
+ }
+
var sec:SwagSection = {
+ startTime: daPos,
+ endTime: Math.POSITIVE_INFINITY,
lengthInSteps: lengthInSteps,
bpm: _song.bpm,
changeBPM: false,
@@ -1280,11 +2229,11 @@ class ChartingState extends MusicBeatState
{
var swagNum:Int = 0;
- for (i in _song.notes[curSection].sectionNotes)
+ for (i in getSectionByTime(note.strumTime).sectionNotes)
{
- if (i.strumTime == note.strumTime && i.noteData % 4 == note.noteData)
+ if (i[0] == note.strumTime && i[1] == note.rawNoteData)
{
- curSelectedNote = _song.notes[curSection].sectionNotes[swagNum];
+ curSelectedNote = getSectionByTime(note.strumTime).sectionNotes[swagNum];
}
swagNum += 1;
@@ -1298,20 +2247,40 @@ class ChartingState extends MusicBeatState
function deleteNote(note:Note):Void
{
lastNote = note;
- for (i in _song.notes[curSection].sectionNotes)
+
+ var section = getSectionByTime(note.strumTime);
+
+ trace(section);
+
+ var found = false;
+
+ for (i in section.sectionNotes)
{
- if (i[0] == note.strumTime && i[1] % 4 == note.noteData)
+ if (i[0] == note.strumTime && i[1] == note.rawNoteData)
{
- _song.notes[curSection].sectionNotes.remove(i);
+ section.sectionNotes.remove(i);
+ found = true;
+ }
+ }
+
+ if (!found) // backup check
+ {
+ for(i in _song.notes)
+ {
+ for (n in i.sectionNotes)
+ if (n[0] == note.strumTime && n[1] == note.rawNoteData)
+ i.sectionNotes.remove(n);
}
}
+ trace("DELETED!");
+
updateGrid();
}
function clearSection():Void
{
- _song.notes[curSection].sectionNotes = [];
+ getSectionByTime(Conductor.songPosition).sectionNotes = [];
updateGrid();
}
@@ -1328,7 +2297,26 @@ class ChartingState extends MusicBeatState
private function newSection(lengthInSteps:Int = 16,mustHitSection:Bool = false,altAnim:Bool = true):SwagSection
{
+
+ var daPos:Float = 0;
+
+ var currentSeg = TimingStruct.AllTimings[TimingStruct.AllTimings.length - 1];
+
+ var currentBeat = 4;
+
+ for(i in _song.notes)
+ currentBeat += 4;
+
+ if (currentSeg == null)
+ return null;
+
+ var start:Float = (currentBeat - currentSeg.startBeat) / (currentSeg.bpm / 60);
+
+ daPos = (currentSeg.startTime + start) * 1000;
+
var sec:SwagSection = {
+ startTime: daPos,
+ endTime: Math.POSITIVE_INFINITY,
lengthInSteps: lengthInSteps,
bpm: _song.bpm,
changeBPM: false,
@@ -1338,15 +2326,67 @@ class ChartingState extends MusicBeatState
altAnim: altAnim
};
+
return sec;
}
+ function recalculateAllSectionTimes()
+ {
+
+ /*if (TimingStruct.AllTimings.length > 0)
+ {
+ trace("Song length in MS: " + FlxG.sound.music.length);
+
+ for(i in 0...9000000) // REALLY HIGH BEATS just cuz like ig this is the upper limit, I mean ur chart is probably going to run like ass anyways
+ {
+ var seg = TimingStruct.getTimingAtBeat(i);
+
+ var time = (i / (seg.bpm / 60)) * 1000;
+
+ if (time > FlxG.sound.music.length)
+ break;
+
+ lengthInBeats = i;
+ }
+
+ lengthInSteps = lengthInBeats * 4;
+
+ trace('LENGTH IN STEPS ' + lengthInSteps + ' | LENGTH IN BEATS ' + lengthInBeats);
+ }*/
+
+ trace("RECALCULATING SECTION TIMES");
+ for (i in 0..._song.notes.length) // loops through sections
+ {
+ var section = _song.notes[i];
+
+ var currentBeat = 4 * i;
+
+ var currentSeg = TimingStruct.getTimingAtBeat(currentBeat);
+
+ if (currentSeg == null)
+ return;
+
+ var start:Float = (currentBeat - currentSeg.startBeat) / (currentSeg.bpm / 60);
+
+ section.startTime = (currentSeg.startTime + start) * 1000;
+
+ if (i != 0)
+ _song.notes[i - 1].endTime = section.startTime;
+ section.endTime = Math.POSITIVE_INFINITY;
+
+ }
+ once = true;
+ }
+
+ var once = false;
+
+
function shiftNotes(measure:Int=0,step:Int=0,ms:Int = 0):Void
{
var newSong = [];
- var millisecadd = (((measure*4)+step/4)*(60000/_song.bpm))+ms;
- var totaladdsection = Std.int((millisecadd/(60000/_song.bpm)/4));
+ var millisecadd = (((measure*4)+step/4)*(60000/currentBPM))+ms;
+ var totaladdsection = Std.int((millisecadd/(60000/currentBPM)/4));
trace(millisecadd,totaladdsection);
if(millisecadd > 0)
{
@@ -1374,7 +2414,7 @@ class ChartingState extends MusicBeatState
{
newtiming = 0;
}
- var futureSection = Math.floor(newtiming/4/(60000/_song.bpm));
+ var futureSection = Math.floor(newtiming/4/(60000/currentBPM));
_song.notes[daSection].sectionNotes[daNote][0] = newtiming;
newSong[futureSection].sectionNotes.push(_song.notes[daSection].sectionNotes[daNote]);
@@ -1384,22 +2424,68 @@ class ChartingState extends MusicBeatState
}
//trace("DONE BITCH");
_song.notes = newSong;
+ recalculateAllSectionTimes();
updateGrid();
updateSectionUI();
updateNoteUI();
}
+
+ public function getSectionByTime(ms:Float, ?changeCurSectionIndex:Bool = false):SwagSection
+ {
+ var index = 0;
+
+
+
+ for (i in _song.notes)
+ {
+ if (ms >= i.startTime && ms < i.endTime)
+ {
+ if (changeCurSectionIndex)
+ curSection = index;
+ return i;
+ }
+ index++;
+ }
+
+
+ return null;
+ }
+
+ public function getNoteByTime(ms:Float)
+ {
+ for(i in _song.notes)
+ {
+ for(n in i.sectionNotes)
+ if (n[0] == ms)
+ return i;
+ }
+ return null;
+ }
+
+
private function addNote(?n:Note):Void
{
- var noteStrum = getStrumTime(dummyArrow.y) + sectionStartTime();
+ var strum = getStrumTime(dummyArrow.y) / zoomFactor;
+
+ trace(strum + " from " + dummyArrow.y);
+
+ trace("adding note with " + strum + " from dummyArrow");
+
+ var section = getSectionByTime(strum);
+
+ if (section == null)
+ return;
+
+ var noteStrum = strum;
var noteData = Math.floor(FlxG.mouse.x / GRID_SIZE);
var noteSus = 0;
if (n != null)
- _song.notes[curSection].sectionNotes.push([n.strumTime, n.noteData, n.sustainLength]);
+ section.sectionNotes.push([n.strumTime, n.noteData, n.sustainLength]);
else
- _song.notes[curSection].sectionNotes.push([noteStrum, noteData, noteSus]);
+ section.sectionNotes.push([noteStrum, noteData, noteSus]);
- var thingy = _song.notes[curSection].sectionNotes[_song.notes[curSection].sectionNotes.length - 1];
+ var thingy = section.sectionNotes[section.sectionNotes.length - 1];
curSelectedNote = thingy;
@@ -1411,12 +2497,12 @@ class ChartingState extends MusicBeatState
function getStrumTime(yPos:Float):Float
{
- return FlxMath.remapToRange(yPos, gridBG.y, gridBG.y + gridBG.height, 0, 16 * Conductor.stepCrochet);
+ return FlxMath.remapToRange(yPos, 0, lengthInSteps, 0, lengthInSteps);
}
function getYfromStrum(strumTime:Float):Float
{
- return FlxMath.remapToRange(strumTime, 0, 16 * Conductor.stepCrochet, gridBG.y, gridBG.y + gridBG.height);
+ return FlxMath.remapToRange(strumTime, 0, lengthInSteps, 0, lengthInSteps);
}
/*
@@ -1463,7 +2549,12 @@ class ChartingState extends MusicBeatState
function loadJson(song:String):Void
{
- PlayState.SONG = Song.loadFromJson(song.toLowerCase(), song.toLowerCase());
+ var format = StringTools.replace(PlayState.SONG.song.toLowerCase(), " ", "-");
+ switch (format) {
+ case 'Dad-Battle': format = 'Dadbattle';
+ case 'Philly-Nice': format = 'Philly';
+ }
+ PlayState.SONG = Song.loadFromJson(format, format);
LoadingState.loadAndSwitchState(new ChartingState());
}
@@ -1487,7 +2578,7 @@ class ChartingState extends MusicBeatState
"song": _song
};
- var data:String = Json.stringify(json);
+ var data:String = Json.stringify(json,null," ");
if ((data != null) && (data.length > 0))
{
@@ -1510,7 +2601,7 @@ class ChartingState extends MusicBeatState
/**
* Called when the save file dialog is cancelled.
- */
+ */
function onSaveCancel(_):Void
{
_file.removeEventListener(Event.COMPLETE, onSaveComplete);
diff --git a/source/Conductor.hx b/source/Conductor.hx
index 03847d1..f5c40c1 100644
--- a/source/Conductor.hx
+++ b/source/Conductor.hx
@@ -68,7 +68,23 @@ class Conductor
trace("new BPM map BUDDY " + bpmChangeMap);
}
- public static function changeBPM(newBpm:Float)
+ public static function recalculateTimingStruct(SONG:Song)
+ {
+ for(i in SONG.eventObjects)
+ {
+ /*TimingStruct.addTiming(beat,bpm,endBeat, Std.parseFloat(OFFSET));
+
+ if (changeEvents.length != 0)
+ {
+ var data = TimingStruct.AllTimings[currentIndex - 1];
+ data.endBeat = beat;
+ data.length = (data.endBeat - data.startBeat) / (data.bpm / 60);
+ TimingStruct.AllTimings[currentIndex].startTime = data.startTime + data.length;
+ }*/
+ }
+ }
+
+ public static function changeBPM(newBpm:Float, ?recalcLength = true)
{
bpm = newBpm;
diff --git a/source/Controls.hx b/source/Controls.hx
index b52b858..0219115 100644
--- a/source/Controls.hx
+++ b/source/Controls.hx
@@ -594,7 +594,7 @@ class Controls extends FlxActionSet
inline bindKeys(Control.RIGHT, [FlxKey.fromString(FlxG.save.data.rightBind), FlxKey.RIGHT]);
inline bindKeys(Control.ACCEPT, [Z, SPACE, ENTER]);
inline bindKeys(Control.BACK, [BACKSPACE, ESCAPE]);
- inline bindKeys(Control.PAUSE, [P, ENTER, ESCAPE]);
+ inline bindKeys(Control.PAUSE, [ENTER, ESCAPE]);
inline bindKeys(Control.RESET, [FlxKey.fromString(FlxG.save.data.killBind)]);
}
diff --git a/source/DialogueBox.hx b/source/DialogueBox.hx
index d52358c..07363c6 100644
--- a/source/DialogueBox.hx
+++ b/source/DialogueBox.hx
@@ -155,7 +155,7 @@ class DialogueBox extends FlxSpriteGroup
portraitLeft.visible = false;
if (PlayState.SONG.song.toLowerCase() == 'thorns')
{
- portraitLeft.color = FlxColor.BLACK;
+ portraitLeft.visible = false;
swagDialogue.color = FlxColor.WHITE;
dropText.color = FlxColor.BLACK;
}
diff --git a/source/DiffCalc.hx b/source/DiffCalc.hx
new file mode 100644
index 0000000..5022cb8
--- /dev/null
+++ b/source/DiffCalc.hx
@@ -0,0 +1,372 @@
+import openfl.system.System;
+import flixel.math.FlxMath;
+import Song.SwagSong;
+
+class SmallNote // basically Note.hx but small as fuck
+{
+ public var strumTime:Float;
+ public var noteData:Int;
+
+ public function new(strum,data)
+ {
+ strumTime = strum;
+ noteData = data;
+ }
+}
+
+class DiffCalc
+{
+ public static var scale = 3 * 1.8;
+
+ public static var lastDiffHandOne:Array = [];
+ public static var lastDiffHandTwo:Array = [];
+
+ public static function CalculateDiff(song:SwagSong, ?accuracy:Float = .93)
+ {
+ trace('calcuilafjwaf');
+ // cleaned notes
+ var cleanedNotes:Array = [];
+
+ if (song.notes == null)
+ return 0.0;
+
+ if (song.notes.length == 0)
+ return 0.0;
+
+ // find all of the notes
+ for(i in song.notes) // sections
+ {
+ for (ii in i.sectionNotes) // notes
+ {
+ if (ii[1] > 3 && !i.mustHitSection)
+ cleanedNotes.push(new SmallNote(ii[0],Math.floor(Math.abs(ii[1]))));
+ else if (ii[1] < 4 && i.mustHitSection)
+ cleanedNotes.push(new SmallNote(ii[0],Math.floor(Math.abs(ii[1]))));
+ }
+ }
+
+ trace(cleanedNotes.length + " - playable notes");
+
+ var handOne:Array = [];
+ var handTwo:Array = [];
+
+ cleanedNotes.sort((a, b) -> Std.int(a.strumTime - b.strumTime));
+
+
+
+ var firstNoteTime = cleanedNotes[0].strumTime;
+
+ // normalize the notes
+
+ for(i in cleanedNotes)
+ {
+ i.strumTime = (i.strumTime - firstNoteTime) * 2;
+ }
+
+ for (i in cleanedNotes)
+ {
+ switch(i.noteData)
+ {
+ case 0:
+ handOne.push(i);
+ case 1:
+ handOne.push(i);
+ case 2:
+ handTwo.push(i);
+ case 3:
+ handTwo.push(i);
+ }
+ }
+
+ // collect all of the notes in each col
+
+ var leftHandCol:Array = []; // d 0
+ var leftMHandCol:Array = []; // f 1
+ var rightMHandCol:Array = []; // j 2
+ var rightHandCol:Array = []; // k 3
+
+ for(i in 0...handOne.length - 1)
+ {
+ if (handOne[i].noteData == 0)
+ leftHandCol.push(handOne[i].strumTime);
+ else
+ leftMHandCol.push(handOne[i].strumTime);
+ }
+ for(i in 0...handTwo.length - 1)
+ {
+ if (handTwo[i].noteData == 3)
+ rightHandCol.push(handTwo[i].strumTime);
+ else
+ rightMHandCol.push(handTwo[i].strumTime);
+ }
+
+
+ // length in segments of the song
+ var length = ((cleanedNotes[cleanedNotes.length - 1].strumTime / 1000) / 0.5);
+
+ // hackey way of creating a array with a length
+ var segmentsOne = new haxe.ds.Vector(Math.floor(length));
+
+ var segmentsTwo = new haxe.ds.Vector(Math.floor(length));
+
+ // set em all to array's (so no null's)
+
+ for(i in 0...segmentsOne.length)
+ segmentsOne[i] = new Array();
+ for(i in 0...segmentsTwo.length)
+ segmentsTwo[i] = new Array();
+
+ // algo loop
+ for(i in handOne)
+ {
+ var index = Std.int((((i.strumTime * 2) / 1000)));
+ if (index + 1 > length)
+ continue;
+ segmentsOne[index].push(i);
+ }
+
+ for(i in handTwo)
+ {
+ var index = Std.int((((i.strumTime * 2) / 1000)));
+ if (index + 1 > length)
+ continue;
+ segmentsTwo[index].push(i);
+ }
+
+ // Remove 0 intervals
+ /*for(i in 0...segmentsOne.length)
+ {
+ if (segmentsOne[i].length == 0)
+ segmentsOne[i] = null;
+ }
+
+ for(i in 0...segmentsTwo.length)
+ {
+ if (segmentsTwo[i].length == 0)
+ segmentsTwo[i] = null;
+ }*/
+
+ // get nps for both hands
+
+ var hand_npsOne:Array = new Array();
+ var hand_npsTwo:Array = new Array();
+
+ for(i in segmentsOne)
+ {
+ if (i == null)
+ continue;
+ hand_npsOne.push(i.length * scale * 1.6);
+ }
+ for(i in segmentsTwo)
+ {
+ if (i == null)
+ continue;
+ hand_npsTwo.push(i.length * scale * 1.6);
+ }
+
+ // get the diff vector's for all of the hands
+
+ var hand_diffOne:Array = new Array();
+ var hand_diffTwo:Array = new Array();
+
+ for(i in 0...segmentsOne.length)
+ {
+ var ve = segmentsOne[i];
+ if (ve == null)
+ continue;
+ var fuckYouOne:Array = [];
+ var fuckYouTwo:Array = [];
+ for(note in ve)
+ {
+ switch(note.noteData)
+ {
+ case 0: // fingie 1
+ fuckYouOne.push(note);
+ case 1: // fingie 2
+ fuckYouTwo.push(note);
+ }
+ }
+
+ var one = fingieCalc(fuckYouOne,leftHandCol);
+ var two = fingieCalc(fuckYouTwo,leftMHandCol);
+
+
+ var bigFuck = ((((one > two ? one : two) * 8) + (hand_npsOne[i] / scale) * 5) / 13) * scale;
+
+ //trace(bigFuck + " - hand one [" + i + "]");
+
+
+ hand_diffOne.push(bigFuck);
+ }
+
+ for(i in 0...segmentsTwo.length)
+ {
+ var ve = segmentsTwo[i];
+ if (ve == null)
+ continue;
+ var fuckYouOne:Array = [];
+ var fuckYouTwo:Array = [];
+ for(note in ve)
+ {
+ switch(note.noteData)
+ {
+ case 2: // fingie 1
+ fuckYouOne.push(note);
+ case 3: // fingie 2
+ fuckYouTwo.push(note);
+ }
+ }
+
+ var one = fingieCalc(fuckYouOne,rightMHandCol);
+ var two = fingieCalc(fuckYouTwo,rightHandCol);
+
+ var bigFuck = ((((one > two ? one : two) * 8) + (hand_npsTwo[i] / scale) * 5) / 13) * scale;
+
+ hand_diffTwo.push(bigFuck);
+
+ // trace(bigFuck + " - hand two [" + i + "]");
+ }
+
+ for (i in 0...4)
+ {
+ smoothBrain(hand_npsOne,0);
+ smoothBrain(hand_npsTwo,0);
+
+ smoothBrainTwo(hand_diffOne);
+ smoothBrainTwo(hand_diffTwo);
+ }
+
+ //trace(hand_diffOne);
+ //trace(hand_diffTwo);
+
+ //trace(hand_npsOne);
+ //trace(hand_npsTwo);
+
+ var point_npsOne:Array = new Array();
+ var point_npsTwo:Array = new Array();
+
+ for(i in segmentsOne)
+ {
+ if (i == null)
+ continue;
+ point_npsOne.push(i.length);
+ }
+ for(i in segmentsTwo)
+ {
+ if (i == null)
+ continue;
+ point_npsTwo.push(i.length);
+ }
+
+ var maxPoints:Float = 0;
+
+ for(i in point_npsOne)
+ maxPoints += i;
+ for(i in point_npsTwo)
+ maxPoints += i;
+
+ if (accuracy > .965)
+ accuracy = .965;
+
+ lastDiffHandOne = hand_diffOne;
+ lastDiffHandTwo = hand_diffTwo;
+
+
+ return HelperFunctions.truncateFloat(chisel(accuracy,hand_diffOne,hand_diffTwo,point_npsOne,point_npsTwo,maxPoints),2);
+ }
+
+ public static function chisel(scoreGoal:Float,diffOne:Array,diffTwo:Array,pointsOne:Array,pointsTwo:Array,maxPoints:Float)
+ {
+ var lowerBound:Float = 0;
+ var upperBound:Float = 100;
+
+ while(upperBound - lowerBound > 0.01)
+ {
+ var average:Float = (upperBound + lowerBound) / 2;
+ var amtOfPoints:Float = calcuate(average,diffOne,pointsOne) + calcuate(average,diffTwo,pointsTwo);
+ if (amtOfPoints / maxPoints < scoreGoal)
+ lowerBound = average;
+ else
+ upperBound = average;
+
+ }
+ return upperBound;
+ }
+
+ public static function calcuate(midPoint:Float,diff:Array,points:Array)
+ {
+ var output:Float = 0;
+
+ for (i in 0...diff.length)
+ {
+ var res = diff[i];
+ if (midPoint > res)
+ output += points[i];
+ else
+ output += points[i] * Math.pow(midPoint / res,1.2);
+ }
+ return output;
+ }
+
+ public static function findStupid(strumTime:Float, array:Array)
+ {
+ for(i in 0...array.length)
+ if (array[i] == strumTime)
+ return i;
+ return -1;
+ }
+
+ public static function fingieCalc(floats:Array, columArray:Array):Float
+ {
+ var sum:Float = 0;
+ if (floats.length == 0)
+ return 0;
+ var startIndex = findStupid(floats[0].strumTime,columArray);
+ if (startIndex == -1)
+ return 0;
+ for(i in floats)
+ {
+ sum += columArray[startIndex + 1] - columArray[startIndex];
+ startIndex++;
+ }
+
+ if (sum == 0)
+ return 0;
+
+ return (1375 * (floats.length)) / sum;
+ }
+
+ // based arrayer
+ // basicily smmoth the shit
+ public static function smoothBrain(npsVector:Array, weirdchamp:Float)
+ {
+ var floatOne = weirdchamp;
+ var floatTwo = weirdchamp;
+
+ for (i in 0...npsVector.length)
+ {
+ var result = npsVector[i];
+
+ var chunker = floatOne;
+ floatOne = floatTwo;
+ floatTwo = result;
+
+ npsVector[i] = (chunker + floatOne + floatTwo) / 3;
+ }
+ }
+
+ // Smooth the shit but less
+ public static function smoothBrainTwo(diffVector:Array)
+ {
+ var floatZero:Float = 0;
+
+ for(i in 0...diffVector.length)
+ {
+ var result = diffVector[i];
+
+ var fuck = floatZero;
+ floatZero = result;
+ diffVector[i] = (fuck + floatZero) / 2;
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/DiffOverview.hx b/source/DiffOverview.hx
new file mode 100644
index 0000000..4f27fcc
--- /dev/null
+++ b/source/DiffOverview.hx
@@ -0,0 +1,506 @@
+package;
+
+import Conductor.BPMChangeEvent;
+import flixel.FlxCamera;
+import flixel.math.FlxRect;
+import Song.SwagSong;
+import Section.SwagSection;
+import flixel.system.FlxSound;
+import flixel.input.gamepad.FlxGamepad;
+import flixel.util.FlxAxes;
+import flixel.FlxSubState;
+import Options.Option;
+import flixel.input.FlxInput;
+import flixel.input.keyboard.FlxKey;
+import flixel.FlxG;
+import flixel.FlxObject;
+import flixel.FlxSprite;
+import flixel.effects.FlxFlicker;
+import flixel.graphics.frames.FlxAtlasFrames;
+import flixel.group.FlxGroup.FlxTypedGroup;
+import flixel.text.FlxText;
+import flixel.util.FlxSort;
+import flixel.tweens.FlxEase;
+import flixel.tweens.FlxTween;
+import flixel.util.FlxColor;
+import io.newgrounds.NG;
+import lime.app.Application;
+import lime.utils.Assets;
+import flixel.math.FlxMath;
+import flixel.text.FlxText;
+import flixel.input.FlxKeyManager;
+
+using StringTools;
+
+class DiffOverview extends FlxSubState
+{
+ var blackBox:FlxSprite;
+
+ var handOne:Array;
+ var handTwo:Array;
+
+ var giantText:FlxText;
+
+ var SONG:SwagSong;
+ var strumLine:FlxSprite;
+ var camHUD:FlxCamera;
+
+ var offset:FlxText;
+
+ public static var playerStrums:FlxTypedGroup = null;
+
+ override function create()
+ {
+ Conductor.songPosition = 0;
+ Conductor.lastSongPos = 0;
+
+ camHUD = new FlxCamera();
+ camHUD.bgColor.alpha = 0;
+ var camGame = new FlxCamera();
+
+ FlxG.cameras.add(camGame);
+
+ FlxG.cameras.add(camHUD);
+
+ FlxCamera.defaultCameras = [camGame];
+
+ playerStrums = new FlxTypedGroup();
+
+ SONG = FreeplayState.songData.get(FreeplayState.songs[FreeplayState.curSelected].songName)[FreeplayState.curDifficulty];
+
+ strumLine = new FlxSprite(0, (FlxG.height / 2) - 295).makeGraphic(FlxG.width, 10);
+ strumLine.scrollFactor.set();
+
+ blackBox = new FlxSprite(0, 0).makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK);
+ blackBox.alpha = 0;
+ add(blackBox);
+
+ FreeplayState.openedPreview = true;
+
+ handOne = DiffCalc.lastDiffHandOne;
+ handTwo = DiffCalc.lastDiffHandTwo;
+ for (i in 0...4)
+ {
+ // FlxG.log.add(i);
+ var babyArrow:FlxSprite = new FlxSprite(0, strumLine.y);
+
+ babyArrow.frames = Paths.getSparrowAtlas('NOTE_assets','shared');
+ babyArrow.animation.addByPrefix('green', 'arrowUP');
+ babyArrow.animation.addByPrefix('blue', 'arrowDOWN');
+ babyArrow.animation.addByPrefix('purple', 'arrowLEFT');
+ babyArrow.animation.addByPrefix('red', 'arrowRIGHT');
+ if(FlxG.save.data.antialiasing)
+ {
+ babyArrow.antialiasing = true;
+ }
+ babyArrow.setGraphicSize(Std.int(babyArrow.width * 0.7));
+
+ switch (Math.abs(i))
+ {
+ case 2:
+ babyArrow.x += Note.swagWidth * 2;
+ babyArrow.animation.addByPrefix('static', 'arrowUP');
+ babyArrow.animation.addByPrefix('pressed', 'up press', 24, false);
+ babyArrow.animation.addByPrefix('confirm', 'up confirm', 24, false);
+ case 3:
+ babyArrow.x += Note.swagWidth * 3;
+ babyArrow.animation.addByPrefix('static', 'arrowRIGHT');
+ babyArrow.animation.addByPrefix('pressed', 'right press', 24, false);
+ babyArrow.animation.addByPrefix('confirm', 'right confirm', 24, false);
+ case 1:
+ babyArrow.x += Note.swagWidth * 1;
+ babyArrow.animation.addByPrefix('static', 'arrowDOWN');
+ babyArrow.animation.addByPrefix('pressed', 'down press', 24, false);
+ babyArrow.animation.addByPrefix('confirm', 'down confirm', 24, false);
+ case 0:
+ babyArrow.x += Note.swagWidth * 0;
+ babyArrow.animation.addByPrefix('static', 'arrowLEFT');
+ babyArrow.animation.addByPrefix('pressed', 'left press', 24, false);
+ babyArrow.animation.addByPrefix('confirm', 'left confirm', 24, false);
+ }
+
+ babyArrow.updateHitbox();
+ babyArrow.scrollFactor.set();
+
+ babyArrow.y -= 10;
+ babyArrow.alpha = 1;
+
+ babyArrow.ID = i;
+
+ playerStrums.add(babyArrow);
+
+ babyArrow.animation.play('static');
+ babyArrow.x += 50;
+ babyArrow.x += ((FlxG.width / 2));
+ }
+
+ add(playerStrums);
+
+ generateSong("assItch");
+
+ playerStrums.cameras = [camHUD];
+ notes.cameras = [camHUD];
+ blackBox.cameras = [camHUD];
+
+ blackBox.x = playerStrums.members[0].x;
+ blackBox.y = strumLine.y;
+
+ camHUD.zoom = 0.6;
+ camHUD.alpha = 0;
+ camHUD.height = 5000;
+ blackBox.height = camHUD.height;
+
+ camHUD.x += 280;
+
+ blackBox.y -= 100;
+ blackBox.x -= 100;
+
+ offset = new FlxText(10,FlxG.height - 40,0,"Offset: " + HelperFunctions.truncateFloat(FlxG.save.data.offset,0) + " (LEFT/RIGHT to decrease/increase)",16);
+ offset.setBorderStyle(FlxTextBorderStyle.OUTLINE,FlxColor.BLACK,4,1);
+ offset.color = FlxColor.WHITE;
+ offset.scrollFactor.set();
+ //add(offset);
+
+ FlxTween.tween(blackBox, {alpha: 0.5}, 1, {ease: FlxEase.expoInOut});
+ FlxTween.tween(camHUD, {alpha: 1}, 0.5, {ease: FlxEase.expoInOut});
+ FlxTween.tween(offset, {alpha: 1}, 0.5, {ease: FlxEase.expoInOut});
+
+ trace('pog');
+
+ super.create();
+ }
+
+ function endSong()
+ {
+ if (stopDoingShit)
+ return;
+ }
+
+ function resyncVocals():Void
+ {
+ vocals.pause();
+
+ FlxG.sound.music.play();
+ Conductor.songPosition = FlxG.sound.music.time;
+ vocals.time = Conductor.songPosition;
+ vocals.play();
+ }
+
+ public var stopDoingShit = false;
+
+ public var currentStep = 0;
+ public var oldStep = 0;
+
+ private function updateCurStep():Void
+ {
+ var lastChange:BPMChangeEvent = {
+ stepTime: 0,
+ songTime: 0,
+ bpm: 0
+ }
+ for (i in 0...Conductor.bpmChangeMap.length)
+ {
+ if (Conductor.songPosition >= Conductor.bpmChangeMap[i].songTime)
+ lastChange = Conductor.bpmChangeMap[i];
+ }
+
+ currentStep = lastChange.stepTime + Math.floor((Conductor.songPosition - lastChange.songTime) / Conductor.stepCrochet);
+ }
+
+ function stepHit()
+ {
+ if (FlxG.sound.music.time > Conductor.songPosition + 20 || FlxG.sound.music.time < Conductor.songPosition - 20)
+ {
+ trace("resync");
+ resyncVocals();
+ }
+ oldStep = currentStep;
+ }
+
+ function offsetChange()
+ {
+ for (i in unspawnNotes)
+ i.strumTime = i.baseStrum + FlxG.save.data.offset;
+ for (i in notes)
+ i.strumTime = i.baseStrum + FlxG.save.data.offset;
+ }
+
+ var frames = 0;
+
+ override function update(elapsed:Float)
+ {
+ super.update(elapsed);
+
+
+ // input
+
+ if (frames < 10)
+ {
+ frames++;
+ return;
+ }
+
+ if (stopDoingShit)
+ return;
+
+ updateCurStep();
+
+ if (oldStep != currentStep && currentStep > 0)
+ stepHit();
+
+ if (FlxG.keys.pressed.SPACE)
+ {
+ stopDoingShit = true;
+ quit();
+ }
+
+ var gamepad:FlxGamepad = FlxG.gamepads.lastActive;
+
+ if (gamepad != null)
+ if (gamepad.justPressed.X)
+ {
+ stopDoingShit = true;
+ quit();
+ }
+
+ /*if (FlxG.keys.pressed.RIGHT)
+ {
+ if (FlxG.keys.pressed.SHIFT)
+ {
+ FlxG.save.data.offset++;
+ offsetChange();
+ }
+ }
+ if (FlxG.keys.pressed.LEFT)
+ {
+ if (FlxG.keys.pressed.SHIFT)
+ {
+ FlxG.save.data.offset--;
+ offsetChange();
+ }
+ }
+
+ if (FlxG.keys.justPressed.RIGHT)
+ {
+ FlxG.save.data.offset++;
+ offsetChange();
+ }
+ if (FlxG.keys.justPressed.LEFT)
+ {
+ FlxG.save.data.offset--;
+ offsetChange();
+ }
+
+
+ offset.text = "Offset: " + HelperFunctions.truncateFloat(FlxG.save.data.offset,0) + " (LEFT/RIGHT to decrease/increase, SHIFT to go faster) - Time: " + HelperFunctions.truncateFloat(Conductor.songPosition / 1000,0) + "s - Step: " + currentStep;
+ */
+
+ if (vocals != null)
+ if (vocals.playing)
+ Conductor.songPosition += FlxG.elapsed * 1000;
+
+ if (unspawnNotes[0] != null)
+ {
+ if (unspawnNotes[0].strumTime - Conductor.songPosition < 3500)
+ {
+ var dunceNote:Note = unspawnNotes[0];
+ notes.add(dunceNote);
+
+ var index:Int = unspawnNotes.indexOf(dunceNote);
+ unspawnNotes.splice(index, 1);
+ }
+ }
+
+
+
+ notes.forEachAlive(function(daNote:Note)
+ {
+ // instead of doing stupid y > FlxG.height
+ // we be men and actually calculate the time :)
+ if (daNote.tooLate)
+ {
+ daNote.active = false;
+ daNote.visible = false;
+ }
+ else
+ {
+ daNote.visible = true;
+ daNote.active = true;
+ }
+
+ daNote.y = (playerStrums.members[Math.floor(Math.abs(daNote.noteData))].y
+ - 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(SONG.speed,
+ 2));
+
+ if (daNote.isSustainNote)
+ {
+ daNote.y -= daNote.height / 2;
+
+ if ((!daNote.mustPress || daNote.wasGoodHit || daNote.prevNote.wasGoodHit && !daNote.canBeHit)
+ && daNote.y + daNote.offset.y * daNote.scale.y <= (strumLine.y + Note.swagWidth / 2))
+ {
+ // Clip to strumline
+ var swagRect = new FlxRect(0, 0, daNote.width / daNote.scale.x, daNote.height / daNote.scale.y);
+ swagRect.y = (playerStrums.members[Math.floor(Math.abs(daNote.noteData))].y + Note.swagWidth / 2 - daNote.y) / daNote.scale.y;
+ swagRect.height -= swagRect.y;
+
+ daNote.clipRect = swagRect;
+ }
+ }
+
+ daNote.visible = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].visible;
+ daNote.x = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].x;
+ if (!daNote.isSustainNote)
+ daNote.angle = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].angle;
+ daNote.alpha = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].alpha;
+
+ // auto hit
+
+ if(daNote.y < strumLine.y)
+ {
+ // Force good note hit regardless if it's too late to hit it or not as a fail safe
+ if(daNote.canBeHit && daNote.mustPress || daNote.tooLate && daNote.mustPress)
+ {
+
+ daNote.wasGoodHit = true;
+ vocals.volume = 1;
+
+ daNote.kill();
+ notes.remove(daNote, true);
+ daNote.destroy();
+ }
+ }
+ });
+
+ }
+
+ function quit()
+ {
+ FlxTween.tween(blackBox, {alpha: 0}, 1, {ease: FlxEase.expoInOut});
+ FlxTween.tween(camHUD, {alpha: 0}, 1, {ease: FlxEase.expoInOut});
+ FlxTween.tween(offset, {alpha: 0}, 1, {ease: FlxEase.expoInOut});
+
+ vocals.fadeOut();
+
+ FreeplayState.openedPreview = false;
+ }
+
+ var vocals:FlxSound;
+
+ var notes:FlxTypedGroup;
+ var unspawnNotes:Array = [];
+
+ public function generateSong(dataPath:String):Void
+ {
+ // FlxG.log.add(ChartParser.parse());
+
+ var songData = FreeplayState.songData.get(FreeplayState.songs[FreeplayState.curSelected].songName)[FreeplayState.curDifficulty];
+ Conductor.changeBPM(songData.bpm);
+
+ if (SONG.needsVoices)
+ vocals = new FlxSound().loadEmbedded(Paths.voices(SONG.song));
+ else
+ vocals = new FlxSound();
+
+ trace('loaded vocals');
+
+ FlxG.sound.list.add(vocals);
+
+ notes = new FlxTypedGroup();
+ add(notes);
+
+ var noteData:Array;
+
+ // NEW SHIT
+ noteData = songData.notes;
+
+ var playerCounter:Int = 0;
+
+ var daBeats:Int = 0; // Not exactly representative of 'daBeats' lol, just how much it has looped
+ for (section in noteData)
+ {
+ var coolSection:Int = Std.int(section.lengthInSteps / 4);
+
+ for (songNotes in section.sectionNotes)
+ {
+ var daStrumTime:Float = songNotes[0] + FlxG.save.data.offset;
+ if (daStrumTime < 0)
+ daStrumTime = 0;
+ var daNoteData:Int = Std.int(songNotes[1] % 4);
+
+ var gottaHitNote:Bool = section.mustHitSection;
+
+ if (songNotes[1] > 3)
+ {
+ gottaHitNote = !section.mustHitSection;
+ }
+
+ var oldNote:Note;
+ if (unspawnNotes.length > 0)
+ oldNote = unspawnNotes[Std.int(unspawnNotes.length - 1)];
+ else
+ oldNote = null;
+
+ var swagNote:Note = new Note(daStrumTime, daNoteData, oldNote,false, true);
+
+
+ if (!gottaHitNote)
+ continue;
+
+ swagNote.baseStrum = Math.round(songNotes[0]);
+
+ swagNote.sustainLength = songNotes[2];
+ swagNote.scrollFactor.set(0, 0);
+
+ var susLength:Float = swagNote.sustainLength;
+
+ susLength = susLength / Conductor.stepCrochet;
+ unspawnNotes.push(swagNote);
+
+ for (susNote in 0...Math.floor(susLength))
+ {
+ oldNote = unspawnNotes[Std.int(unspawnNotes.length - 1)];
+
+ var sustainNote:Note = new Note(daStrumTime + (Conductor.stepCrochet * susNote) + Conductor.stepCrochet, daNoteData, oldNote, true, true);
+ sustainNote.scrollFactor.set();
+ unspawnNotes.push(sustainNote);
+
+ sustainNote.mustPress = gottaHitNote;
+
+ if (sustainNote.mustPress)
+ {
+ sustainNote.x += FlxG.width / 2; // general offset
+ }
+ }
+
+ swagNote.mustPress = gottaHitNote;
+
+ if (swagNote.mustPress)
+ {
+ swagNote.x += FlxG.width / 2; // general offset
+ }
+ else
+ {
+ }
+ }
+ daBeats += 1;
+ }
+
+ // trace(unspawnNotes.length);
+ // playerCounter += 1;
+
+ unspawnNotes.sort(sortByShit);
+
+ Conductor.mapBPMChanges(SONG);
+ Conductor.changeBPM(SONG.bpm);
+
+ FlxG.sound.playMusic(Paths.inst(SONG.song), 1, false);
+ FlxG.sound.music.onComplete = endSong;
+ vocals.play();
+ }
+
+ function sortByShit(Obj1:Note, Obj2:Note):Int
+ {
+ return FlxSort.byValues(FlxSort.ASCENDING, Obj1.strumTime, Obj2.strumTime);
+ }
+}
diff --git a/source/FreeplayState.hx b/source/FreeplayState.hx
index 243d970..dc27df6 100644
--- a/source/FreeplayState.hx
+++ b/source/FreeplayState.hx
@@ -1,5 +1,13 @@
package;
-
+import openfl.utils.Future;
+import openfl.media.Sound;
+import flixel.system.FlxSound;
+#if sys
+import smTools.SMFile;
+import sys.FileSystem;
+import sys.io.File;
+#end
+import Song.SwagSong;
import flixel.input.gamepad.FlxGamepad;
import flash.text.TextField;
import flixel.FlxG;
@@ -20,15 +28,17 @@ using StringTools;
class FreeplayState extends MusicBeatState
{
- var songs:Array = [];
+ public static var songs:Array = [];
var selector:FlxText;
- var curSelected:Int = 0;
- var curDifficulty:Int = 1;
+ public static var curSelected:Int = 0;
+ public static var curDifficulty:Int = 1;
var scoreText:FlxText;
var comboText:FlxText;
var diffText:FlxText;
+ var diffCalcText:FlxText;
+ var previewtext:FlxText;
var lerpScore:Int = 0;
var intendedScore:Int = 0;
var combo:String = '';
@@ -38,16 +48,82 @@ class FreeplayState extends MusicBeatState
private var iconArray:Array = [];
+ public static var openedPreview = false;
+
+ public static var songData:Map> = [];
+
+ public static function loadDiff(diff:Int, format:String, name:String, array:Array)
+ {
+ try
+ {
+ array.push(Song.loadFromJson(Highscore.formatSong(format, diff), name));
+ }
+ catch(ex)
+ {
+ // do nada
+ }
+ }
+
override function create()
{
- var initSonglist = CoolUtil.coolTextFile(Paths.txt('freeplaySonglist'));
+ var initSonglist = CoolUtil.coolTextFile(Paths.txt('data/freeplaySonglist'));
+
+ //var diffList = "";
+
+ songData = [];
+ songs = [];
for (i in 0...initSonglist.length)
{
var data:Array = initSonglist[i].split(':');
- songs.push(new SongMetadata(data[0], Std.parseInt(data[2]), data[1]));
+ var meta = new SongMetadata(data[0], Std.parseInt(data[2]), data[1]);
+ songs.push(meta);
+ var format = StringTools.replace(meta.songName, " ", "-");
+ switch (format) {
+ case 'Dad-Battle': format = 'Dadbattle';
+ case 'Philly-Nice': format = 'Philly';
+ }
+
+ var diffs = [];
+ FreeplayState.loadDiff(0,format,meta.songName,diffs);
+ FreeplayState.loadDiff(1,format,meta.songName,diffs);
+ FreeplayState.loadDiff(2,format,meta.songName,diffs);
+ FreeplayState.songData.set(meta.songName,diffs);
+ trace('loaded diffs for ' + meta.songName);
+
}
+ trace("tryin to load sm files");
+
+ #if sys
+ for(i in FileSystem.readDirectory("assets/sm/"))
+ {
+ trace(i);
+ if (FileSystem.isDirectory("assets/sm/" + i))
+ {
+ trace("Reading SM file dir " + i);
+ for (file in FileSystem.readDirectory("assets/sm/" + i))
+ {
+ if (file.contains(" "))
+ FileSystem.rename("assets/sm/" + i + "/" + file,"assets/sm/" + i + "/" + file.replace(" ","_"));
+ if (file.endsWith(".sm"))
+ {
+ trace("reading " + file);
+ var file:SMFile = SMFile.loadFile("assets/sm/" + i + "/" + file.replace(" ","_"));
+ trace("Converting " + file.header.TITLE);
+ var data = file.convertToFNF("assets/sm/" + i + "/converted.json");
+ var meta = new SongMetadata(file.header.TITLE, 0, "sm",file,"assets/sm/" + i);
+ songs.push(meta);
+ var song = Song.loadFromJsonRAW(data);
+ songData.set(file.header.TITLE, [song,song,song]);
+ }
+ }
+ }
+ }
+ #end
+
+ //trace("\n" + diffList);
+
/*
if (FlxG.sound.music != null)
{
@@ -67,11 +143,17 @@ class FreeplayState extends MusicBeatState
isDebug = true;
#end
+ persistentUpdate = true;
+
// LOAD MUSIC
// LOAD CHARACTERS
var bg:FlxSprite = new FlxSprite().loadGraphic(Paths.image('menuBGBlue'));
+ if(FlxG.save.data.antialiasing)
+ {
+ bg.antialiasing = true;
+ }
add(bg);
grpSongs = new FlxTypedGroup();
@@ -101,7 +183,7 @@ class FreeplayState extends MusicBeatState
scoreText.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, RIGHT);
// scoreText.alignment = RIGHT;
- var scoreBG:FlxSprite = new FlxSprite(scoreText.x - 6, 0).makeGraphic(Std.int(FlxG.width * 0.35), 66, 0xFF000000);
+ var scoreBG:FlxSprite = new FlxSprite(scoreText.x - 6, 0).makeGraphic(Std.int(FlxG.width * 0.35), 105, 0xFF000000);
scoreBG.alpha = 0.6;
add(scoreBG);
@@ -109,6 +191,14 @@ class FreeplayState extends MusicBeatState
diffText.font = scoreText.font;
add(diffText);
+ diffCalcText = new FlxText(scoreText.x, scoreText.y + 66, 0, "", 24);
+ diffCalcText.font = scoreText.font;
+ add(diffCalcText);
+
+ previewtext = new FlxText(scoreText.x, scoreText.y + 94, 0, "" + (KeyBinds.gamepad ? "X" : "SPACE") + " to preview", 24);
+ previewtext.font = scoreText.font;
+ //add(previewtext);
+
comboText = new FlxText(diffText.x + 100, diffText.y, 0, "", 24);
comboText.font = diffText.font;
add(comboText);
@@ -167,7 +257,7 @@ class FreeplayState extends MusicBeatState
num++;
}
}
-
+
override function update(elapsed:Float)
{
super.update(elapsed);
@@ -185,14 +275,20 @@ class FreeplayState extends MusicBeatState
scoreText.text = "PERSONAL BEST:" + lerpScore;
comboText.text = combo + '\n';
+ if (FlxG.sound.music.volume > 0.8)
+ {
+ FlxG.sound.music.volume -= 0.5 * FlxG.elapsed;
+ }
+
var upP = FlxG.keys.justPressed.UP;
var downP = FlxG.keys.justPressed.DOWN;
- var accepted = controls.ACCEPT;
+ var accepted = FlxG.keys.justPressed.ENTER;
var gamepad:FlxGamepad = FlxG.gamepads.lastActive;
if (gamepad != null)
{
+
if (gamepad.justPressed.DPAD_UP)
{
changeSelection(-1);
@@ -209,6 +305,9 @@ class FreeplayState extends MusicBeatState
{
changeDiff(1);
}
+
+ //if (gamepad.justPressed.X && !openedPreview)
+ //openSubState(new DiffOverview());
}
if (upP)
@@ -220,6 +319,9 @@ class FreeplayState extends MusicBeatState
changeSelection(1);
}
+ //if (FlxG.keys.justPressed.SPACE && !openedPreview)
+ //openSubState(new DiffOverview());
+
if (FlxG.keys.justPressed.LEFT)
changeDiff(-1);
if (FlxG.keys.justPressed.RIGHT)
@@ -238,18 +340,36 @@ class FreeplayState extends MusicBeatState
case 'Dad-Battle': songFormat = 'Dadbattle';
case 'Philly-Nice': songFormat = 'Philly';
}
-
- trace(songs[curSelected].songName);
+ var hmm;
+ try
+ {
+ hmm = songData.get(songs[curSelected].songName)[curDifficulty];
+ if (hmm == null)
+ return;
+ }
+ catch(ex)
+ {
+ return;
+ }
- var poop:String = Highscore.formatSong(songFormat, curDifficulty);
- trace(poop);
-
- PlayState.SONG = Song.loadFromJson(poop, songs[curSelected].songName);
+ PlayState.SONG = hmm;
PlayState.isStoryMode = false;
PlayState.storyDifficulty = curDifficulty;
PlayState.storyWeek = songs[curSelected].week;
trace('CUR WEEK' + PlayState.storyWeek);
+ #if sys
+ if (songs[curSelected].songCharacter == "sm")
+ {
+ PlayState.isSM = true;
+ PlayState.sm = songs[curSelected].sm;
+ PlayState.pathToSm = songs[curSelected].path;
+ }
+ else
+ PlayState.isSM = false;
+ #else
+ PlayState.isSM = false;
+ #end
LoadingState.loadAndSwitchState(new PlayState());
}
}
@@ -263,6 +383,7 @@ class FreeplayState extends MusicBeatState
if (curDifficulty > 2)
curDifficulty = 0;
+
// adjusting the highscore song name to be compatible (changeDiff)
var songHighscore = StringTools.replace(songs[curSelected].songName, " ", "-");
switch (songHighscore) {
@@ -274,7 +395,7 @@ class FreeplayState extends MusicBeatState
intendedScore = Highscore.getScore(songHighscore, curDifficulty);
combo = Highscore.getCombo(songHighscore, curDifficulty);
#end
-
+ diffCalcText.text = 'RATING: ${DiffCalc.CalculateDiff(songData.get(songs[curSelected].songName)[curDifficulty])}';
diffText.text = CoolUtil.difficultyFromInt(curDifficulty).toUpperCase();
}
@@ -287,6 +408,8 @@ class FreeplayState extends MusicBeatState
// NGio.logEvent('Fresh');
FlxG.sound.play(Paths.sound('scrollMenu'), 0.4);
+
+
curSelected += change;
if (curSelected < 0)
@@ -310,10 +433,38 @@ class FreeplayState extends MusicBeatState
// lerpScore = 0;
#end
+ diffCalcText.text = 'RATING: ${DiffCalc.CalculateDiff(songData.get(songs[curSelected].songName)[curDifficulty])}';
+
#if PRELOAD_ALL
- FlxG.sound.playMusic(Paths.inst(songs[curSelected].songName), 0);
+ if (songs[curSelected].songCharacter == "sm")
+ {
+ var data = songs[curSelected];
+ trace("Loading " + data.path + "/" + data.sm.header.MUSIC);
+ var bytes = File.getBytes(data.path + "/" + data.sm.header.MUSIC);
+ var sound = new Sound();
+ sound.loadCompressedDataFromByteArray(bytes.getData(), bytes.length);
+ FlxG.sound.playMusic(sound);
+ }
+ else
+ FlxG.sound.playMusic(Paths.inst(songs[curSelected].songName), 0);
#end
+ var hmm;
+ try
+ {
+ hmm = songData.get(songs[curSelected].songName)[curDifficulty];
+ if (hmm != null)
+ Conductor.changeBPM(hmm.bpm);
+ }
+ catch(ex)
+ {}
+
+ if (openedPreview)
+ {
+ closeSubState();
+ openSubState(new DiffOverview());
+ }
+
var bullShit:Int = 0;
for (i in 0...iconArray.length)
@@ -344,12 +495,27 @@ class SongMetadata
{
public var songName:String = "";
public var week:Int = 0;
+ #if sys
+ public var sm:SMFile;
+ public var path:String;
+ #end
public var songCharacter:String = "";
+ #if sys
+ public function new(song:String, week:Int, songCharacter:String, ?sm:SMFile = null, ?path:String = "")
+ {
+ this.songName = song;
+ this.week = week;
+ this.songCharacter = songCharacter;
+ this.sm = sm;
+ this.path = path;
+ }
+ #else
public function new(song:String, week:Int, songCharacter:String)
{
this.songName = song;
this.week = week;
this.songCharacter = songCharacter;
}
+ #end
}
diff --git a/source/GameOverState.hx b/source/GameOverState.hx
index c26c063..250095e 100644
--- a/source/GameOverState.hx
+++ b/source/GameOverState.hx
@@ -41,7 +41,10 @@ class GameOverState extends FlxTransitionableState
restart.setGraphicSize(Std.int(restart.width * 0.6));
restart.updateHitbox();
restart.alpha = 0;
- restart.antialiasing = true;
+ if(FlxG.save.data.antialiasing)
+ {
+ restart.antialiasing = true;
+ }
add(restart);
FlxG.sound.music.fadeOut(2, FlxG.sound.music.volume * 0.6);
diff --git a/source/GameOverSubstate.hx b/source/GameOverSubstate.hx
index f784827..5cef652 100644
--- a/source/GameOverSubstate.hx
+++ b/source/GameOverSubstate.hx
@@ -48,6 +48,8 @@ class GameOverSubstate extends MusicBeatSubstate
bf.playAnim('firstDeath');
}
+ var startVibin:Bool = false;
+
override function update(elapsed:Float)
{
super.update(elapsed);
@@ -76,6 +78,7 @@ class GameOverSubstate extends MusicBeatSubstate
if (bf.animation.curAnim.name == 'firstDeath' && bf.animation.curAnim.finished)
{
FlxG.sound.playMusic(Paths.music('gameOver' + stageSuffix));
+ startVibin = true;
}
if (FlxG.sound.music.playing)
@@ -88,6 +91,10 @@ class GameOverSubstate extends MusicBeatSubstate
{
super.beatHit();
+ if (startVibin && !isEnding)
+ {
+ bf.playAnim('deathLoop', true);
+ }
FlxG.log.add('beat');
}
@@ -97,6 +104,7 @@ class GameOverSubstate extends MusicBeatSubstate
{
if (!isEnding)
{
+ PlayState.startTime = 0;
isEnding = true;
bf.playAnim('deathConfirm', true);
FlxG.sound.music.stop();
diff --git a/source/GameplayCustomizeState.hx b/source/GameplayCustomizeState.hx
index 7bcfa31..26e29e6 100644
--- a/source/GameplayCustomizeState.hx
+++ b/source/GameplayCustomizeState.hx
@@ -33,6 +33,7 @@ class GameplayCustomizeState extends MusicBeatState
var bf:Boyfriend;
var dad:Character;
+ var gf:Character;
var strumLine:FlxSprite;
var strumLineNotes:FlxTypedGroup;
@@ -42,7 +43,7 @@ class GameplayCustomizeState extends MusicBeatState
public override function create() {
#if windows
// Updating Discord Rich Presence
- DiscordClient.changePresence("Customizing Gameplay", null);
+ DiscordClient.changePresence("Customizing Gameplay Modules", null);
#end
sick = new FlxSprite().loadGraphic(Paths.image('sick','shared'));
@@ -51,7 +52,7 @@ class GameplayCustomizeState extends MusicBeatState
curt = new FlxSprite(-500, -300).loadGraphic(Paths.image('stagecurtains','shared'));
front = new FlxSprite(-650, 600).loadGraphic(Paths.image('stagefront','shared'));
- Conductor.changeBPM(102);
+ //Conductor.changeBPM(102);
persistentUpdate = true;
super.create();
@@ -74,10 +75,14 @@ class GameplayCustomizeState extends MusicBeatState
bf = new Boyfriend(770, 450, 'bf');
+ gf = new Character(400, 130, 'gf');
+ gf.scrollFactor.set(0.95, 0.95);
+
var camPos:FlxPoint = new FlxPoint(dad.getGraphicMidpoint().x + 400, dad.getGraphicMidpoint().y);
camFollow.setPosition(camPos.x, camPos.y);
+ add(gf);
add(bf);
add(dad);
@@ -111,7 +116,7 @@ class GameplayCustomizeState extends MusicBeatState
generateStaticArrows(0);
generateStaticArrows(1);
- text = new FlxText(5, FlxG.height + 40, 0, "Drag around gameplay elements, R to reset, Escape to go back.", 12);
+ text = new FlxText(5, FlxG.height + 40, 0, "Click and drag around gameplay elements to customize their positions.\nPress R to reset.\nPress Escape to go back.", 12);
text.scrollFactor.set();
text.setFormat("VCR OSD Mono", 16, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK);
@@ -188,8 +193,9 @@ class GameplayCustomizeState extends MusicBeatState
{
super.beatHit();
- bf.playAnim('idle');
- dad.dance();
+ bf.playAnim('idle', true);
+ dad.dance(true);
+ gf.dance();
FlxG.camera.zoom += 0.015;
camHUD.zoom += 0.010;
diff --git a/source/GitarooPause.hx b/source/GitarooPause.hx
index cb9705c..a8c5f99 100644
--- a/source/GitarooPause.hx
+++ b/source/GitarooPause.hx
@@ -22,12 +22,20 @@ class GitarooPause extends MusicBeatState
FlxG.sound.music.stop();
var bg:FlxSprite = new FlxSprite().loadGraphic(Paths.image('pauseAlt/pauseBG'));
+ if(FlxG.save.data.antialiasing)
+ {
+ bg.antialiasing = true;
+ }
add(bg);
var bf:FlxSprite = new FlxSprite(0, 30);
bf.frames = Paths.getSparrowAtlas('pauseAlt/bfLol');
bf.animation.addByPrefix('lol', "funnyThing", 13);
bf.animation.play('lol');
+ if(FlxG.save.data.antialiasing)
+ {
+ bf.antialiasing = true;
+ }
add(bf);
bf.screenCenter(X);
@@ -36,6 +44,10 @@ class GitarooPause extends MusicBeatState
replayButton.animation.addByPrefix('selected', 'bluereplay', 0, false);
replayButton.animation.appendByPrefix('selected', 'yellowreplay');
replayButton.animation.play('selected');
+ if(FlxG.save.data.antialiasing)
+ {
+ replayButton.antialiasing = true;
+ }
add(replayButton);
cancelButton = new FlxSprite(FlxG.width * 0.58, replayButton.y);
@@ -43,6 +55,10 @@ class GitarooPause extends MusicBeatState
cancelButton.animation.addByPrefix('selected', 'bluecancel', 0, false);
cancelButton.animation.appendByPrefix('selected', 'cancelyellow');
cancelButton.animation.play('selected');
+ if(FlxG.save.data.antialiasing)
+ {
+ cancelButton.antialiasing = true;
+ }
add(cancelButton);
changeThing();
diff --git a/source/HealthIcon.hx b/source/HealthIcon.hx
index 74f46a1..ec24910 100644
--- a/source/HealthIcon.hx
+++ b/source/HealthIcon.hx
@@ -1,5 +1,6 @@
package;
+import flixel.FlxG;
import flixel.FlxSprite;
class HealthIcon extends FlxSprite
@@ -12,10 +13,17 @@ class HealthIcon extends FlxSprite
public function new(char:String = 'bf', isPlayer:Bool = false)
{
super();
-
- loadGraphic(Paths.image('iconGrid'), true, 150, 150);
- antialiasing = true;
+ if(FlxG.save.data.antialiasing)
+ {
+ antialiasing = true;
+ }
+ if (char == 'sm')
+ {
+ loadGraphic(Paths.image("stepmania-icon"));
+ return;
+ }
+ loadGraphic(Paths.image('iconGrid'), true, 150, 150);
animation.add('bf', [0, 1], 0, false, isPlayer);
animation.add('bf-car', [0, 1], 0, false, isPlayer);
animation.add('bf-christmas', [0, 1], 0, false, isPlayer);
diff --git a/source/HelperFunctions.hx b/source/HelperFunctions.hx
index b17dc6a..4b704c1 100644
--- a/source/HelperFunctions.hx
+++ b/source/HelperFunctions.hx
@@ -12,4 +12,5 @@ class HelperFunctions
public static function GCD(a, b) {
return b == 0 ? FlxMath.absInt(a) : GCD(b, a % b);
}
+
}
\ No newline at end of file
diff --git a/source/KadeEngineData.hx b/source/KadeEngineData.hx
index 0a26829..89039ff 100644
--- a/source/KadeEngineData.hx
+++ b/source/KadeEngineData.hx
@@ -6,12 +6,21 @@ class KadeEngineData
{
public static function initSave()
{
- if (FlxG.save.data.newInput == null)
+ if (FlxG.save.data.weekUnlocked == null)
+ FlxG.save.data.weekUnlocked = 7;
+
+ if (FlxG.save.data.newInput == null)
FlxG.save.data.newInput = true;
if (FlxG.save.data.downscroll == null)
FlxG.save.data.downscroll = false;
+ if (FlxG.save.data.antialiasing == null)
+ FlxG.save.data.antialiasing = true;
+
+ if (FlxG.save.data.missSounds == null)
+ FlxG.save.data.missSounds = true;
+
if (FlxG.save.data.dfjk == null)
FlxG.save.data.dfjk = false;
@@ -63,6 +72,9 @@ class KadeEngineData
if (FlxG.save.data.distractions == null)
FlxG.save.data.distractions = true;
+
+ if (FlxG.save.data.stepMania == null)
+ FlxG.save.data.stepMania = false;
if (FlxG.save.data.flashing == null)
FlxG.save.data.flashing = true;
@@ -94,6 +106,9 @@ class KadeEngineData
if (FlxG.save.data.optimize == null)
FlxG.save.data.optimize = false;
+ if (FlxG.save.data.cacheImages == null)
+ FlxG.save.data.cacheImages = false;
+
var gamepad:FlxGamepad = FlxG.gamepads.lastActive;
KeyBinds.gamepad = gamepad != null;
diff --git a/source/KeyBindMenu.hx b/source/KeyBindMenu.hx
index d5a3d41..e7efdc8 100644
--- a/source/KeyBindMenu.hx
+++ b/source/KeyBindMenu.hx
@@ -119,6 +119,8 @@ class KeyBindMenu extends FlxSubState
if (frames <= 10)
frames++;
+ infoText.text = 'Current Mode: ${KeyBinds.gamepad ? 'GAMEPAD' : 'KEYBOARD'}. Press TAB to switch\n(${KeyBinds.gamepad ? 'RIGHT Trigger' : 'Escape'} to save, ${KeyBinds.gamepad ? 'LEFT Trigger' : 'Backspace'} to leave without saving. ${KeyBinds.gamepad ? 'START To change a keybind' : ''})\n${lastKey != "" ? lastKey + " is blacklisted!" : ""}';
+
switch(state){
case "select":
@@ -137,7 +139,6 @@ class KeyBindMenu extends FlxSubState
if (FlxG.keys.justPressed.TAB)
{
KeyBinds.gamepad = !KeyBinds.gamepad;
- infoText.text = 'Current Mode: ${KeyBinds.gamepad ? 'GAMEPAD' : 'KEYBOARD'}. Press TAB to switch\n(${KeyBinds.gamepad ? 'RIGHT Trigger' : 'Escape'} to save, ${KeyBinds.gamepad ? 'LEFT Trigger' : 'Backspace'} to leave without saving. ${KeyBinds.gamepad ? 'START To change a keybind' : ''})';
textUpdate();
}
@@ -320,7 +321,7 @@ class KeyBindMenu extends FlxSubState
var shouldReturn:Bool = true;
- var notAllowed:Array = ["START", "RIGHT_TRIGGER", "LEFT_TRIGGER"];
+ var notAllowed:Array = ["START"];
for(x in 0...gpKeys.length)
{
@@ -330,6 +331,7 @@ class KeyBindMenu extends FlxSubState
if (notAllowed.contains(oK))
{
gpKeys[x] = null;
+ lastKey = r;
return;
}
}
@@ -340,14 +342,13 @@ class KeyBindMenu extends FlxSubState
}
else{
gpKeys[curSelected] = tempKey;
- FlxG.sound.play(Paths.sound('scrollMenu'));
- keyWarning.alpha = 1;
- warningTween.cancel();
- warningTween = FlxTween.tween(keyWarning, {alpha: 0}, 0.5, {ease: FlxEase.circOut, startDelay: 2});
+ lastKey = r;
}
}
+ public var lastKey:String = "";
+
function addKey(r:String){
var shouldReturn:Bool = true;
@@ -366,6 +367,7 @@ class KeyBindMenu extends FlxSubState
if (notAllowed.contains(oK))
{
keys[x] = null;
+ lastKey = oK;
return;
}
}
@@ -373,19 +375,19 @@ class KeyBindMenu extends FlxSubState
if (r.contains("NUMPAD"))
{
keys[curSelected] = null;
+ lastKey = r;
return;
}
+ lastKey = "";
+
if(shouldReturn){
keys[curSelected] = r;
FlxG.sound.play(Paths.sound('scrollMenu'));
}
else{
keys[curSelected] = tempKey;
- FlxG.sound.play(Paths.sound('scrollMenu'));
- keyWarning.alpha = 1;
- warningTween.cancel();
- warningTween = FlxTween.tween(keyWarning, {alpha: 0}, 0.5, {ease: FlxEase.circOut, startDelay: 2});
+ lastKey = r;
}
}
diff --git a/source/LoadReplayState.hx b/source/LoadReplayState.hx
index 3560888..135c5ae 100644
--- a/source/LoadReplayState.hx
+++ b/source/LoadReplayState.hx
@@ -1,5 +1,12 @@
package;
+import haxe.Exception;
+import lime.app.Application;
+
+#if sys
+import smTools.SMFile;
+import sys.FileSystem;
+#end
import Controls.KeyboardScheme;
import Controls.Control;
import flash.text.TextField;
@@ -64,7 +71,10 @@ class LoadReplayState extends MusicBeatState
menuBG.setGraphicSize(Std.int(menuBG.width * 1.1));
menuBG.updateHitbox();
menuBG.screenCenter();
- menuBG.antialiasing = true;
+ if(FlxG.save.data.antialiasing)
+ {
+ menuBG.antialiasing = true;
+ }
add(menuBG);
grpControls = new FlxTypedGroup();
@@ -161,9 +171,55 @@ class LoadReplayState extends MusicBeatState
case 'philly-nice': songFormat = 'Philly';
}
- var poop:String = Highscore.formatSong(songFormat, PlayState.rep.replay.songDiff);
+ var poop = "";
+
+ #if sys
+ if (PlayState.rep.replay.sm)
+ if (!FileSystem.exists(StringTools.replace(PlayState.rep.replay.chartPath,"converted.json","")))
+ {
+ Application.current.window.alert("The SM file in this replay does not exist!","SM Replays");
+ return;
+ }
+ #end
- PlayState.SONG = Song.loadFromJson(poop, PlayState.rep.replay.songName);
+ PlayState.isSM = PlayState.rep.replay.sm;
+ #if sys
+ if (PlayState.isSM)
+ PlayState.pathToSm = StringTools.replace(PlayState.rep.replay.chartPath,"converted.json","");
+ #end
+
+ #if sys
+ if (PlayState.isSM)
+ {
+ poop = File.getContent(PlayState.rep.replay.chartPath);
+ try
+ {
+ PlayState.sm = SMFile.loadFile(PlayState.pathToSm + "/" + StringTools.replace(PlayState.rep.replay.songName," ", "_") + ".sm");
+ }
+ catch(e:Exception)
+ {
+ Application.current.window.alert("Make sure that the SM file is called " + PlayState.pathToSm + "/" + StringTools.replace(PlayState.rep.replay.songName," ", "_") + ".sm!\nAs I couldn't read it.","SM Replays");
+ return;
+ }
+ }
+ else
+ poop = Highscore.formatSong(songFormat, PlayState.rep.replay.songDiff);
+ #else
+ poop = Highscore.formatSong(songFormat, PlayState.rep.replay.songDiff);
+ #end
+
+ try
+ {
+ if (PlayState.isSM)
+ PlayState.SONG = Song.loadFromJsonRAW(poop);
+ else
+ PlayState.SONG = Song.loadFromJson(poop, PlayState.rep.replay.songName);
+ }
+ catch(e:Exception)
+ {
+ Application.current.window.alert("Failed to load the song! Does the JSON exist?","Replays");
+ return;
+ }
PlayState.isStoryMode = false;
PlayState.storyDifficulty = PlayState.rep.replay.songDiff;
PlayState.storyWeek = getWeekNumbFromSong(PlayState.rep.replay.songName);
diff --git a/source/LoadingState.hx b/source/LoadingState.hx
index 23bce2e..6609fa4 100644
--- a/source/LoadingState.hx
+++ b/source/LoadingState.hx
@@ -38,7 +38,10 @@ class LoadingState extends MusicBeatState
{
logo = new FlxSprite(-150, -100);
logo.frames = Paths.getSparrowAtlas('logoBumpin');
- logo.antialiasing = true;
+ if(FlxG.save.data.antialiasing)
+ {
+ logo.antialiasing = true;
+ }
logo.animation.addByPrefix('bump', 'logo bumpin', 24);
logo.animation.play('bump');
logo.updateHitbox();
@@ -49,7 +52,10 @@ class LoadingState extends MusicBeatState
gfDance.frames = Paths.getSparrowAtlas('gfDanceTitle');
gfDance.animation.addByIndices('danceLeft', 'gfDance', [30, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false);
gfDance.animation.addByIndices('danceRight', 'gfDance', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false);
- gfDance.antialiasing = true;
+ if(FlxG.save.data.antialiasing)
+ {
+ gfDance.antialiasing = true;
+ }
add(gfDance);
add(logo);
diff --git a/source/Main.hx b/source/Main.hx
index a065da2..788ba61 100644
--- a/source/Main.hx
+++ b/source/Main.hx
@@ -1,8 +1,11 @@
package;
+import lime.app.Application;
+#if windows
+import Discord.DiscordClient;
+#end
import openfl.display.BlendMode;
import openfl.text.TextFormat;
-import openfl.display.Application;
import flixel.util.FlxColor;
import flixel.FlxG;
import flixel.FlxGame;
@@ -23,7 +26,7 @@ class Main extends Sprite
var skipSplash:Bool = true; // Whether to skip the flixel splash screen that appears in release mode.
var startFullscreen:Bool = false; // Whether to start the game in fullscreen on desktop targets
- public static var watermarks = true; // Whether to put Kade Engine liteartly anywhere
+ public static var watermarks = true; // Whether to put Kade Engine literally anywhere
// You can pretty much ignore everything from here on - your code should go in your states.
@@ -82,12 +85,19 @@ class Main extends Sprite
game = new FlxGame(gameWidth, gameHeight, initialState, zoom, framerate, framerate, skipSplash, startFullscreen);
#end
addChild(game);
-
+ #if windows
+ DiscordClient.initialize();
+
+ Application.current.onExit.add (function (exitCode) {
+ DiscordClient.shutdown();
+ });
+
+ #end
+
#if !mobile
fpsCounter = new FPS(10, 3, 0xFFFFFF);
addChild(fpsCounter);
toggleFPS(FlxG.save.data.fps);
-
#end
}
diff --git a/source/MainMenuState.hx b/source/MainMenuState.hx
index ab5f444..2d676ae 100644
--- a/source/MainMenuState.hx
+++ b/source/MainMenuState.hx
@@ -40,7 +40,7 @@ class MainMenuState extends MusicBeatState
public static var nightly:String = "";
- public static var kadeEngineVer:String = "1.5.4" + nightly;
+ public static var kadeEngineVer:String = "1.6" + nightly;
public static var gameVer:String = "0.2.7.1";
var magenta:FlxSprite;
@@ -67,7 +67,10 @@ class MainMenuState extends MusicBeatState
bg.setGraphicSize(Std.int(bg.width * 1.1));
bg.updateHitbox();
bg.screenCenter();
- bg.antialiasing = true;
+ if(FlxG.save.data.antialiasing)
+ {
+ bg.antialiasing = true;
+ }
add(bg);
camFollow = new FlxObject(0, 0, 1, 1);
@@ -80,7 +83,10 @@ class MainMenuState extends MusicBeatState
magenta.updateHitbox();
magenta.screenCenter();
magenta.visible = false;
- magenta.antialiasing = true;
+ if(FlxG.save.data.antialiasing)
+ {
+ magenta.antialiasing = true;
+ }
magenta.color = 0xFFfd719b;
add(magenta);
// magenta.scrollFactor.set();
@@ -101,7 +107,10 @@ class MainMenuState extends MusicBeatState
menuItem.screenCenter(X);
menuItems.add(menuItem);
menuItem.scrollFactor.set();
- menuItem.antialiasing = true;
+ if(FlxG.save.data.antialiasing)
+ {
+ menuItem.antialiasing = true;
+ }
if (firstStart)
FlxTween.tween(menuItem,{y: 60 + (i * 160)},1 + (i * 0.25) ,{ease: FlxEase.expoInOut, onComplete: function(flxTween:FlxTween)
{
diff --git a/source/MenuCharacter.hx b/source/MenuCharacter.hx
index 1cf3e5b..c35e25a 100644
--- a/source/MenuCharacter.hx
+++ b/source/MenuCharacter.hx
@@ -1,6 +1,7 @@
package;
import flixel.FlxSprite;
+import flixel.FlxG;
import flixel.graphics.frames.FlxAtlasFrames;
class CharacterSetting
@@ -33,25 +34,34 @@ class MenuCharacter extends FlxSprite
];
private var flipped:Bool = false;
+ //questionable variable name lmfao
+ private var goesLeftNRight:Bool = false;
+ private var danceLeft:Bool = false;
+ private var character:String = '';
public function new(x:Int, y:Int, scale:Float, flipped:Bool)
{
super(x, y);
this.flipped = flipped;
- antialiasing = true;
+ if(FlxG.save.data.antialiasing)
+ {
+ antialiasing = true;
+ }
frames = Paths.getSparrowAtlas('campaign_menu_UI_characters');
- animation.addByPrefix('bf', "BF idle dance white", 24);
+ animation.addByPrefix('bf', "BF idle dance white", 24, false);
animation.addByPrefix('bfConfirm', 'BF HEY!!', 24, false);
- animation.addByPrefix('gf', "GF Dancing Beat WHITE", 24);
- animation.addByPrefix('dad', "Dad idle dance BLACK LINE", 24);
- animation.addByPrefix('spooky', "spooky dance idle BLACK LINES", 24);
- animation.addByPrefix('pico', "Pico Idle Dance", 24);
- animation.addByPrefix('mom', "Mom Idle BLACK LINES", 24);
- animation.addByPrefix('parents-christmas', "Parent Christmas Idle", 24);
- animation.addByPrefix('senpai', "SENPAI idle Black Lines", 24);
+ animation.addByIndices('gf-left', 'GF Dancing Beat WHITE', [30, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false);
+ animation.addByIndices('gf-right', 'GF Dancing Beat WHITE', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false);
+ animation.addByPrefix('dad', "Dad idle dance BLACK LINE", 24, false);
+ animation.addByIndices('spooky-left', 'spooky dance idle BLACK LINES', [0, 2, 6], "", 12, false);
+ animation.addByIndices('spooky-right', 'spooky dance idle BLACK LINES', [8, 10, 12, 14], "", 12, false);
+ animation.addByPrefix('pico', "Pico Idle Dance", 24, false);
+ animation.addByPrefix('mom', "Mom Idle BLACK LINES", 24, false);
+ animation.addByPrefix('parents-christmas', "Parent Christmas Idle", 24, false);
+ animation.addByPrefix('senpai', "SENPAI idle Black Lines", 24, false);
setGraphicSize(Std.int(width * scale));
updateHitbox();
@@ -59,6 +69,8 @@ class MenuCharacter extends FlxSprite
public function setCharacter(character:String):Void
{
+ var sameCharacter:Bool = character == this.character;
+ this.character = character;
if (character == '')
{
visible = false;
@@ -69,11 +81,33 @@ class MenuCharacter extends FlxSprite
visible = true;
}
- animation.play(character);
+ if (!sameCharacter) {
+ bopHead(true);
+ }
var setting:CharacterSetting = settings[character];
offset.set(setting.x, setting.y);
setGraphicSize(Std.int(width * setting.scale));
flipX = setting.flipped != flipped;
}
+
+ public function bopHead(LastFrame:Bool = false):Void
+ {
+ if (character == 'gf' || character == 'spooky') {
+ danceLeft = !danceLeft;
+
+ if (danceLeft)
+ animation.play(character + "-left", true);
+ else
+ animation.play(character + "-right", true);
+ } else {
+ //no spooky nor girlfriend so we do da normal animation
+ if (animation.name == "bfConfirm")
+ return;
+ animation.play(character, true);
+ }
+ if (LastFrame) {
+ animation.finish();
+ }
+ }
}
diff --git a/source/ModchartState.hx b/source/ModchartState.hx
index 6e194d1..571edbf 100644
--- a/source/ModchartState.hx
+++ b/source/ModchartState.hx
@@ -250,7 +250,7 @@ class ModchartState
PlayState.instance.removeObject(PlayState.boyfriend);
PlayState.boyfriend = new Boyfriend(oldboyfriendx, oldboyfriendy, id);
PlayState.instance.addObject(PlayState.boyfriend);
- PlayState.instance.iconP2.animation.play(id);
+ PlayState.instance.iconP1.animation.play(id);
}
function makeAnimatedLuaSprite(spritePath:String,names:Array,prefixes:Array,startAnim:String, id:String)
diff --git a/source/MusicBeatState.hx b/source/MusicBeatState.hx
index d98bd64..7a3bde8 100644
--- a/source/MusicBeatState.hx
+++ b/source/MusicBeatState.hx
@@ -3,15 +3,11 @@ package;
#if windows
import Discord.DiscordClient;
#end
-import flixel.tweens.FlxTween;
import flixel.util.FlxColor;
import openfl.Lib;
import Conductor.BPMChangeEvent;
import flixel.FlxG;
-import flixel.addons.transition.FlxTransitionableState;
import flixel.addons.ui.FlxUIState;
-import flixel.math.FlxRect;
-import flixel.util.FlxTimer;
class MusicBeatState extends FlxUIState
{
@@ -20,6 +16,7 @@ class MusicBeatState extends FlxUIState
private var curStep:Int = 0;
private var curBeat:Int = 0;
+ private var curDecimalBeat:Float = 0;
private var controls(get, never):Controls;
inline function get_controls():Controls
@@ -27,6 +24,7 @@ class MusicBeatState extends FlxUIState
override function create()
{
+ TimingStruct.clearTimings();
(cast (Lib.current.getChildAt(0), Main)).setFPSCap(FlxG.save.data.fpsCap);
if (transIn != null)
@@ -51,13 +49,50 @@ class MusicBeatState extends FlxUIState
override function update(elapsed:Float)
{
//everyStep();
- var oldStep:Int = curStep;
+ var nextStep:Int = updateCurStep();
- updateCurStep();
- updateBeat();
+ if (nextStep >= 0)
+ {
+ if (nextStep > curStep)
+ {
+ for (i in curStep...nextStep)
+ {
+ curStep++;
+ updateBeat();
+ stepHit();
+ }
+ }
+ else if (nextStep < curStep)
+ {
+ //Song reset?
+ curStep = nextStep;
+ updateBeat();
+ stepHit();
+ }
+ }
- if (oldStep != curStep && curStep > 0)
- stepHit();
+ if (Conductor.songPosition < 0)
+ curDecimalBeat = 0;
+ else
+ {
+ if (TimingStruct.AllTimings.length > 1)
+ {
+ var data = TimingStruct.getTimingAtTimestamp(Conductor.songPosition);
+
+ FlxG.watch.addQuick("Current Conductor Timing Seg", data.bpm);
+
+ Conductor.crochet = ((60 / data.bpm) * 1000);
+
+ var percent = (Conductor.songPosition - (data.startTime * 1000)) / (data.length * 1000);
+
+ curDecimalBeat = data.startBeat + (((Conductor.songPosition/1000) - data.startTime) * (data.bpm / 60));
+ }
+ else
+ {
+ curDecimalBeat = (Conductor.songPosition / 1000) * (Conductor.bpm/60);
+ Conductor.crochet = ((60 / Conductor.bpm) * 1000);
+ }
+ }
if (FlxG.save.data.fpsRain && skippedFrames >= 6)
{
@@ -78,13 +113,13 @@ class MusicBeatState extends FlxUIState
private function updateBeat():Void
{
- lastBeat = curStep;
+ lastBeat = curBeat;
curBeat = Math.floor(curStep / 4);
}
public static var currentColor = 0;
- private function updateCurStep():Void
+ private function updateCurStep():Int
{
var lastChange:BPMChangeEvent = {
stepTime: 0,
@@ -97,12 +132,11 @@ class MusicBeatState extends FlxUIState
lastChange = Conductor.bpmChangeMap[i];
}
- curStep = lastChange.stepTime + Math.floor((Conductor.songPosition - lastChange.songTime) / Conductor.stepCrochet);
+ return lastChange.stepTime + Math.floor((Conductor.songPosition - lastChange.songTime) / Conductor.stepCrochet);
}
public function stepHit():Void
{
-
if (curStep % 4 == 0)
beatHit();
}
diff --git a/source/MusicBeatSubstate.hx b/source/MusicBeatSubstate.hx
index c6da0fb..ee15697 100644
--- a/source/MusicBeatSubstate.hx
+++ b/source/MusicBeatSubstate.hx
@@ -24,19 +24,38 @@ class MusicBeatSubstate extends FlxSubState
override function update(elapsed:Float)
{
//everyStep();
- var oldStep:Int = curStep;
-
- updateCurStep();
- curBeat = Math.floor(curStep / 4);
-
- if (oldStep != curStep && curStep > 0)
- stepHit();
+ var nextStep = updateCurStep();
+ if (nextStep >= 0)
+ {
+ if (nextStep > curStep)
+ {
+ for (i in curStep...nextStep)
+ {
+ curStep++;
+ updateBeat();
+ stepHit();
+ }
+ }
+ else if (nextStep < curStep)
+ {
+ //Song reset?
+ curStep = nextStep;
+ updateBeat();
+ stepHit();
+ }
+ }
super.update(elapsed);
}
- private function updateCurStep():Void
+ private function updateBeat():Void
+ {
+ lastBeat = curBeat;
+ curBeat = Math.floor(curStep / 4);
+ }
+
+ private function updateCurStep():Int
{
var lastChange:BPMChangeEvent = {
stepTime: 0,
@@ -49,7 +68,7 @@ class MusicBeatSubstate extends FlxSubState
lastChange = Conductor.bpmChangeMap[i];
}
- curStep = lastChange.stepTime + Math.floor((Conductor.songPosition - lastChange.songTime) / Conductor.stepCrochet);
+ return lastChange.stepTime + Math.floor((Conductor.songPosition - lastChange.songTime) / Conductor.stepCrochet);
}
public function stepHit():Void
diff --git a/source/Note.hx b/source/Note.hx
index ec67490..700c14e 100644
--- a/source/Note.hx
+++ b/source/Note.hx
@@ -16,9 +16,13 @@ using StringTools;
class Note extends FlxSprite
{
public var strumTime:Float = 0;
+ public var baseStrum:Float = 0;
+
+ public var rStrumTime:Float = 0;
public var mustPress:Bool = false;
public var noteData:Int = 0;
+ public var rawNoteData:Int = 0;
public var canBeHit:Bool = false;
public var tooLate:Bool = false;
public var wasGoodHit:Bool = false;
@@ -26,9 +30,15 @@ class Note extends FlxSprite
public var modifiedByLua:Bool = false;
public var sustainLength:Float = 0;
public var isSustainNote:Bool = false;
+ public var originColor:Int = 0; // The sustain note's original note's color
+ public var noteSection:Int = 0;
+
+ public var noteCharterObject:FlxSprite;
public var noteScore:Float = 1;
+ public var noteYOff:Int = 0;
+
public static var swagWidth:Float = 160 * 0.7;
public static var PURP_NOTE:Int = 0;
public static var GREEN_NOTE:Int = 2;
@@ -37,6 +47,20 @@ class Note extends FlxSprite
public var rating:String = "shit";
+ public var modAngle:Float = 0; // The angle set by modcharts
+ public var localAngle:Float = 0; // The angle to be edited inside Note.hx
+
+ public var dataColor:Array = ['purple', 'blue', 'green', 'red'];
+ public var quantityColor:Array = [RED_NOTE, 2, BLUE_NOTE, 2, PURP_NOTE, 2, BLUE_NOTE, 2];
+ public var arrowAngles:Array = [180, 90, 270, 0];
+
+ public var isParent:Bool = false;
+ public var parent:Note = null;
+ public var spotInLine:Int = 0;
+ public var sustainActive:Bool = true;
+
+ public var children:Array = [];
+
public function new(strumTime:Float, noteData:Int, ?prevNote:Note, ?sustainNote:Bool = false, ?inCharter:Bool = false)
{
super();
@@ -50,10 +74,24 @@ class Note extends FlxSprite
x += 50;
// MAKE SURE ITS DEFINITELY OFF SCREEN?
y -= 2000;
+
if (inCharter)
+ {
this.strumTime = strumTime;
- else
- this.strumTime = Math.round(strumTime);
+ rStrumTime = strumTime;
+ }
+ else
+ {
+ this.strumTime = strumTime;
+ rStrumTime = strumTime - (FlxG.save.data.offset + PlayState.songOffset);
+ #if sys
+ if (PlayState.isSM)
+ {
+ rStrumTime = Math.round(rStrumTime + Std.parseFloat(PlayState.sm.header.OFFSET));
+ }
+ #end
+ }
+
if (this.strumTime < 0 )
this.strumTime = 0;
@@ -65,84 +103,98 @@ class Note extends FlxSprite
//defaults if no noteStyle was found in chart
var noteTypeCheck:String = 'normal';
- if (PlayState.SONG.noteStyle == null) {
- switch(PlayState.storyWeek) {case 6: noteTypeCheck = 'pixel';}
- } else {noteTypeCheck = PlayState.SONG.noteStyle;}
-
- switch (noteTypeCheck)
+ if (inCharter)
{
- case 'pixel':
- loadGraphic(Paths.image('weeb/pixelUI/arrows-pixels','week6'), true, 17, 17);
+ frames = Paths.getSparrowAtlas('NOTE_assets');
- animation.add('greenScroll', [6]);
- animation.add('redScroll', [7]);
- animation.add('blueScroll', [5]);
- animation.add('purpleScroll', [4]);
+ for (i in 0...4)
+ {
+ animation.addByPrefix(dataColor[i] + 'Scroll', dataColor[i] + ' alone'); // Normal notes
+ animation.addByPrefix(dataColor[i] + 'hold', dataColor[i] + ' hold'); // Hold
+ animation.addByPrefix(dataColor[i] + 'holdend', dataColor[i] + ' tail'); // Tails
+ }
- if (isSustainNote)
+ setGraphicSize(Std.int(width * 0.7));
+ updateHitbox();
+ if(FlxG.save.data.antialiasing)
{
- loadGraphic(Paths.image('weeb/pixelUI/arrowEnds','week6'), true, 7, 6);
-
- animation.add('purpleholdend', [4]);
- animation.add('greenholdend', [6]);
- animation.add('redholdend', [7]);
- animation.add('blueholdend', [5]);
-
- animation.add('purplehold', [0]);
- animation.add('greenhold', [2]);
- animation.add('redhold', [3]);
- animation.add('bluehold', [1]);
+ antialiasing = true;
}
-
- setGraphicSize(Std.int(width * PlayState.daPixelZoom));
- updateHitbox();
- default:
- frames = Paths.getSparrowAtlas('NOTE_assets');
-
- animation.addByPrefix('greenScroll', 'green instance 1');
- animation.addByPrefix('redScroll', 'red instance 1');
- animation.addByPrefix('blueScroll', 'blue instance 1');
- animation.addByPrefix('purpleScroll', 'purple instance 1');
-
- animation.addByPrefix('purpleholdend', 'pruple end hold instance 1');
- animation.addByPrefix('greenholdend', 'green hold end instance 1');
- animation.addByPrefix('redholdend', 'red hold end instance 1');
- animation.addByPrefix('blueholdend', 'blue hold end instance 1');
-
- animation.addByPrefix('purplehold', 'purple hold piece instance 1');
- animation.addByPrefix('greenhold', 'green hold piece instance 1');
- animation.addByPrefix('redhold', 'red hold piece instance 1');
- animation.addByPrefix('bluehold', 'blue hold piece instance 1');
-
- setGraphicSize(Std.int(width * 0.7));
- updateHitbox();
- antialiasing = true;
}
-
- switch (noteData)
+ else
{
- case 0:
- x += swagWidth * 0;
- animation.play('purpleScroll');
- case 1:
- x += swagWidth * 1;
- animation.play('blueScroll');
- case 2:
- x += swagWidth * 2;
- animation.play('greenScroll');
- case 3:
- x += swagWidth * 3;
- animation.play('redScroll');
+ if (PlayState.SONG.noteStyle == null) {
+ switch(PlayState.storyWeek) {case 6: noteTypeCheck = 'pixel';}
+ } else {noteTypeCheck = PlayState.SONG.noteStyle;}
+
+ switch (noteTypeCheck)
+ {
+ case 'pixel':
+ loadGraphic(Paths.image('weeb/pixelUI/arrows-pixels', 'week6'), true, 17, 17);
+ if (isSustainNote)
+ loadGraphic(Paths.image('weeb/pixelUI/arrowEnds', 'week6'), true, 7, 6);
+
+ for (i in 0...4)
+ {
+ animation.add(dataColor[i] + 'Scroll', [i + 4]); // Normal notes
+ animation.add(dataColor[i] + 'hold', [i]); // Holds
+ animation.add(dataColor[i] + 'holdend', [i + 4]); // Tails
+ }
+
+ setGraphicSize(Std.int(width * PlayState.daPixelZoom));
+ updateHitbox();
+ default:
+ frames = Paths.getSparrowAtlas('NOTE_assets');
+
+ for (i in 0...4)
+ {
+ animation.addByPrefix(dataColor[i] + 'Scroll', dataColor[i] + ' alone'); // Normal notes
+ animation.addByPrefix(dataColor[i] + 'hold', dataColor[i] + ' hold'); // Hold
+ animation.addByPrefix(dataColor[i] + 'holdend', dataColor[i] + ' tail'); // Tails
+ }
+
+ setGraphicSize(Std.int(width * 0.7));
+ updateHitbox();
+
+ if(FlxG.save.data.antialiasing)
+ {
+ antialiasing = true;
+ }
+ }
}
- // trace(prevNote);
+ x += swagWidth * noteData;
+ animation.play(dataColor[noteData] + 'Scroll');
+ originColor = noteData; // The note's origin color will be checked by its sustain notes
+ if (FlxG.save.data.stepMania && !isSustainNote)
+ {
+ var strumCheck:Float = rStrumTime;
+
+ // I give up on fluctuating bpms. something has to be subtracted from strumCheck to make them look right but idk what.
+ // I'd use the note's section's start time but neither the note's section nor its start time are accessible by themselves
+ //strumCheck -= ???
+
+ var ind:Int = Std.int(Math.round(strumCheck / (Conductor.stepCrochet / 2)));
+
+ var col:Int = 0;
+ col = quantityColor[ind % 8]; // Set the color depending on the beats
+
+ animation.play(dataColor[col] + 'Scroll');
+ localAngle -= arrowAngles[col];
+ localAngle += arrowAngles[noteData];
+ originColor = col;
+ }
+
// we make sure its downscroll and its a SUSTAIN NOTE (aka a trail, not a note)
// and flip it so it doesn't look weird.
// THIS DOESN'T FUCKING FLIP THE NOTE, CONTRIBUTERS DON'T JUST COMMENT THIS OUT JESUS
+ // then what is this lol
if (FlxG.save.data.downscroll && sustainNote)
flipY = true;
+ var stepHeight = (0.45 * Conductor.stepCrochet * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? PlayState.SONG.speed : PlayStateChangeables.scrollSpeed, 2));
+
if (isSustainNote && prevNote != null)
{
noteScore * 0.2;
@@ -150,46 +202,30 @@ class Note extends FlxSprite
x += width / 2;
- switch (noteData)
- {
- case 2:
- animation.play('greenholdend');
- case 3:
- animation.play('redholdend');
- case 1:
- animation.play('blueholdend');
- case 0:
- animation.play('purpleholdend');
- }
+ originColor = prevNote.originColor;
+ animation.play(dataColor[originColor] + 'holdend'); // This works both for normal colors and quantization colors
updateHitbox();
x -= width / 2;
- if (PlayState.curStage.startsWith('school'))
+ //if (noteTypeCheck == 'pixel')
+ // x += 30;
+ if (inCharter)
x += 30;
if (prevNote.isSustainNote)
{
- switch (prevNote.noteData)
- {
- case 0:
- prevNote.animation.play('purplehold');
- case 1:
- prevNote.animation.play('bluehold');
- case 2:
- prevNote.animation.play('greenhold');
- case 3:
- prevNote.animation.play('redhold');
- }
-
-
- if(FlxG.save.data.scrollSpeed != 1)
- prevNote.scale.y *= Conductor.stepCrochet / 100 * 1.5 * FlxG.save.data.scrollSpeed;
- else
- prevNote.scale.y *= Conductor.stepCrochet / 100 * 1.5 * PlayState.SONG.speed;
+ prevNote.animation.play(dataColor[prevNote.originColor] + 'hold');
prevNote.updateHitbox();
+
+ prevNote.scale.y *= (stepHeight + 1) / prevNote.height; // + 1 so that there's no odd gaps as the notes scroll
+ prevNote.updateHitbox();
+ prevNote.noteYOff = Math.round(-prevNote.offset.y);
+
// prevNote.setGraphicSize();
+
+ noteYOff = Math.round(-offset.y);
}
}
}
@@ -197,6 +233,15 @@ class Note extends FlxSprite
override function update(elapsed:Float)
{
super.update(elapsed);
+ angle = modAngle + localAngle;
+
+ if (!modifiedByLua)
+ {
+ if (!sustainActive)
+ {
+ alpha = 0.3;
+ }
+ }
if (mustPress)
{
diff --git a/source/OFLWaveform.hx b/source/OFLWaveform.hx
new file mode 100644
index 0000000..46d1512
--- /dev/null
+++ b/source/OFLWaveform.hx
@@ -0,0 +1,30 @@
+import lime.media.AudioSource;
+import lime.media.AudioBuffer;
+import openfl.media.Sound;
+import openfl.display.Graphics;
+import openfl.display.Sprite;
+
+class OFLWaveform extends Sprite
+{
+ public var musicLength = 0;
+ public var _x = 0;
+ public var _y = 0;
+
+ public var _sound:String;
+
+ function new(x,y,musicLength, data:String)
+ {
+ super();
+
+ _x = x;
+ _y = y;
+ _sound = data;
+ this.musicLength = musicLength;
+ }
+
+ public function drawWaveform()
+ {
+ var gfx:Graphics = graphics;
+ gfx.clear();
+ }
+}
\ No newline at end of file
diff --git a/source/Options.hx b/source/Options.hx
index 7c8f411..37403ff 100644
--- a/source/Options.hx
+++ b/source/Options.hx
@@ -119,6 +119,29 @@ class CpuStrums extends Option
}
+class GraphicLoading extends Option
+{
+ public function new(desc:String)
+ {
+ super();
+ description = desc;
+ }
+
+ public override function press():Bool
+ {
+ FlxG.save.data.cacheImages = !FlxG.save.data.cacheImages;
+
+ display = updateDisplay();
+ return true;
+ }
+
+ private override function updateDisplay():String
+ {
+ return FlxG.save.data.cacheImages ? "Preload Characters" : "Do not Preload Characters";
+ }
+
+}
+
class DownscrollOption extends Option
{
public function new(desc:String)
@@ -221,6 +244,26 @@ class DistractionsAndEffectsOption extends Option
}
}
+class StepManiaOption extends Option
+{
+ public function new(desc:String)
+ {
+ super();
+ description = desc;
+ }
+ public override function press():Bool
+ {
+ FlxG.save.data.stepMania = !FlxG.save.data.stepMania;
+ display = updateDisplay();
+ return true;
+ }
+
+ private override function updateDisplay():String
+ {
+ return "Colors by quantization " + (!FlxG.save.data.stepMania ? "off" : "on");
+ }
+}
+
class ResetButtonOption extends Option
{
public function new(desc:String)
@@ -261,6 +304,46 @@ class FlashingLightsOption extends Option
}
}
+class AntialiasingOption extends Option
+{
+ public function new(desc:String)
+ {
+ super();
+ description = desc;
+ }
+ public override function press():Bool
+ {
+ FlxG.save.data.antialiasing = !FlxG.save.data.antialiasing;
+ display = updateDisplay();
+ return true;
+ }
+
+ private override function updateDisplay():String
+ {
+ return "Antialiasing " + (!FlxG.save.data.antialiasing ? "off" : "on");
+ }
+}
+
+class MissSoundsOption extends Option
+{
+ public function new(desc:String)
+ {
+ super();
+ description = desc;
+ }
+ public override function press():Bool
+ {
+ FlxG.save.data.missSounds = !FlxG.save.data.missSounds;
+ display = updateDisplay();
+ return true;
+ }
+
+ private override function updateDisplay():String
+ {
+ return "Miss Sounds " + (!FlxG.save.data.missSounds ? "off" : "on");
+ }
+}
+
class ShowInput extends Option
{
public function new(desc:String)
@@ -698,3 +781,128 @@ class CamZoomOption extends Option
return "Camera Zoom " + (!FlxG.save.data.camzoom ? "off" : "on");
}
}
+
+class LockWeeksOption extends Option
+{
+ var confirm:Bool = false;
+
+ public function new(desc:String)
+ {
+ super();
+ description = desc;
+ }
+ public override function press():Bool
+ {
+ if(!confirm)
+ {
+ confirm = true;
+ display = updateDisplay();
+ return true;
+ }
+ FlxG.save.data.weekUnlocked = 1;
+ StoryMenuState.weekUnlocked = [true, true];
+ trace('Weeks Locked');
+ display = updateDisplay();
+ return true;
+ }
+
+ private override function updateDisplay():String
+ {
+ return confirm ? "Confirm Story Reset" : "Reset Story Progress";
+ }
+}
+
+class ResetScoreOption extends Option
+{
+ var confirm:Bool = false;
+
+ public function new(desc:String)
+ {
+ super();
+ description = desc;
+ }
+ public override function press():Bool
+ {
+ if(!confirm)
+ {
+ confirm = true;
+ display = updateDisplay();
+ return true;
+ }
+ FlxG.save.data.songScores = null;
+ for(key in Highscore.songScores.keys())
+ {
+ Highscore.songScores[key] = 0;
+ }
+ FlxG.save.data.songCombos = null;
+ for(key in Highscore.songCombos.keys())
+ {
+ Highscore.songCombos[key] = '';
+ }
+ confirm = false;
+ trace('Highscores Wiped');
+ display = updateDisplay();
+ return true;
+ }
+
+ private override function updateDisplay():String
+ {
+ return confirm ? "Confirm Score Reset" : "Reset Score";
+ }
+}
+
+class ResetSettings extends Option
+{
+ var confirm:Bool = false;
+
+ public function new(desc:String)
+ {
+ super();
+ description = desc;
+ }
+ public override function press():Bool
+ {
+ if(!confirm)
+ {
+ confirm = true;
+ display = updateDisplay();
+ return true;
+ }
+ FlxG.save.data.weekUnlocked = null;
+ FlxG.save.data.newInput = null;
+ FlxG.save.data.downscroll = null;
+ FlxG.save.data.dfjk = null;
+ FlxG.save.data.accuracyDisplay = null;
+ FlxG.save.data.offset = null;
+ FlxG.save.data.songPosition = null;
+ FlxG.save.data.fps = null;
+ FlxG.save.data.changedHit = null;
+ FlxG.save.data.fpsRain = null;
+ FlxG.save.data.fpsCap = null;
+ FlxG.save.data.scrollSpeed = null;
+ FlxG.save.data.npsDisplay = null;
+ FlxG.save.data.frames = null;
+ FlxG.save.data.accuracyMod = null;
+ FlxG.save.data.watermark = null;
+ FlxG.save.data.ghost = null;
+ FlxG.save.data.distractions = null;
+ FlxG.save.data.flashing = null;
+ FlxG.save.data.resetButton = null;
+ FlxG.save.data.botplay = null;
+ FlxG.save.data.cpuStrums = null;
+ FlxG.save.data.strumline = null;
+ FlxG.save.data.customStrumLine = null;
+ FlxG.save.data.camzoom = null;
+ FlxG.save.data.stepMania = null;
+ KadeEngineData.initSave();
+ confirm = false;
+ trace('All settings have been reset');
+ display = updateDisplay();
+ return true;
+ }
+
+ private override function updateDisplay():String
+ {
+ return confirm ? "Confirm Settings Reset" : "Reset Settings";
+ }
+}
diff --git a/source/OptionsMenu.hx b/source/OptionsMenu.hx
index 6581771..495219b 100644
--- a/source/OptionsMenu.hx
+++ b/source/OptionsMenu.hx
@@ -27,41 +27,49 @@ class OptionsMenu extends MusicBeatState
var options:Array = [
new OptionCategory("Gameplay", [
new DFJKOption(controls),
- new DownscrollOption("Change the layout of the strumline."),
- new GhostTapOption("Ghost Tapping is when you tap a direction and it doesn't give you a miss."),
- new Judgement("Customize your Hit Timings (LEFT or RIGHT)"),
+ new DownscrollOption("Toggle making the notes scroll down rather than up."),
+ new GhostTapOption("Toggle counting pressing a directional input when no arrow is there as a miss."),
+ new Judgement("Customize your Hit Timings. (LEFT or RIGHT)"),
#if desktop
- new FPSCapOption("Cap your FPS"),
+ new FPSCapOption("Change your FPS Cap."),
#end
- new ScrollSpeedOption("Change your scroll speed (1 = Chart dependent)"),
+ new ScrollSpeedOption("Change your scroll speed. (1 = Chart dependent)"),
new AccuracyDOption("Change how accuracy is calculated. (Accurate = Simple, Complex = Milisecond Based)"),
new ResetButtonOption("Toggle pressing R to gameover."),
// new OffsetMenu("Get a note offset based off of your inputs!"),
- new CustomizeGameplay("Drag'n'Drop Gameplay Modules around to your preference")
+ new CustomizeGameplay("Drag and drop gameplay modules to your prefered positions!")
]),
new OptionCategory("Appearance", [
new DistractionsAndEffectsOption("Toggle stage distractions that can hinder your gameplay."),
new CamZoomOption("Toggle the camera zoom in-game."),
- #if desktop
- new RainbowFPSOption("Make the FPS Counter Rainbow"),
- new AccuracyOption("Display accuracy information."),
- new NPSDisplayOption("Shows your current Notes Per Second."),
- new SongPositionOption("Show the songs current position (as a bar)"),
- new CpuStrums("CPU's strumline lights up when a note hits it."),
- #end
+ new StepManiaOption("Sets the colors of the arrows depending on quantization instead of direction."),
+ new AccuracyOption("Display accuracy information on the info bar."),
+ new SongPositionOption("Show the song's current position as a scrolling bar."),
+ new NPSDisplayOption("Shows your current Notes Per Second on the info bar."),
+ new RainbowFPSOption("Make the FPS Counter flicker through rainbow colors."),
+ new CpuStrums("Toggle the CPU's strumline lighting up when it hits a note."),
]),
new OptionCategory("Misc", [
- #if desktop
new FPSOption("Toggle the FPS Counter"),
- new ReplayOption("View replays"),
- #end
new FlashingLightsOption("Toggle flashing lights that can cause epileptic seizures and strain."),
new WatermarkOption("Enable and disable all watermarks from the engine."),
+ new AntialiasingOption("Toggle antialiasing, improving graphics quality at a slight performance penalty."),
+ new MissSoundsOption("Toggle miss sounds playing when you don't hit a note."),
new ScoreScreen("Show the score screen after the end of a song"),
- new ShowInput("Display every single input in the score screen."),
- new Optimization("No backgrounds, no characters, centered notes, no player 2."),
- new BotPlay("Showcase your charts and mods with autoplay."),
+ new ShowInput("Display every single input on the score screen."),
+ new Optimization("No characters or backgrounds. Just a usual rhythm game layout."),
+ new GraphicLoading("On startup, cache every character. Significantly decrease load times. (HIGH MEMORY)"),
+ new BotPlay("Showcase your charts and mods with autoplay.")
+ ]),
+
+ new OptionCategory("Saves and Data", [
+ #if desktop
+ new ReplayOption("View saved song replays."),
+ #end
+ new ResetScoreOption("Reset your score on all songs and weeks. This is irreversible!"),
+ new LockWeeksOption("Reset your story mode progress. This is irreversible!"),
+ new ResetSettings("Reset ALL your settings. This is irreversible!")
])
];
@@ -83,7 +91,10 @@ class OptionsMenu extends MusicBeatState
menuBG.setGraphicSize(Std.int(menuBG.width * 1.1));
menuBG.updateHitbox();
menuBG.screenCenter();
- menuBG.antialiasing = true;
+ if(FlxG.save.data.antialiasing)
+ {
+ menuBG.antialiasing = true;
+ }
add(menuBG);
grpControls = new FlxTypedGroup();
diff --git a/source/OutdatedSubState.hx b/source/OutdatedSubState.hx
index f7015c4..c825c50 100644
--- a/source/OutdatedSubState.hx
+++ b/source/OutdatedSubState.hx
@@ -32,6 +32,10 @@ class OutdatedSubState extends MusicBeatState
bg.scale.x *= 1.55;
bg.scale.y *= 1.55;
bg.screenCenter();
+ if(FlxG.save.data.antialiasing)
+ {
+ bg.antialiasing = true;
+ }
add(bg);
var kadeLogo:FlxSprite = new FlxSprite(FlxG.width, 0).loadGraphic(Paths.image('KadeEngineLogo'));
@@ -40,6 +44,10 @@ class OutdatedSubState extends MusicBeatState
kadeLogo.x -= kadeLogo.frameHeight;
kadeLogo.y -= 180;
kadeLogo.alpha = 0.8;
+ if(FlxG.save.data.antialiasing)
+ {
+ kadeLogo.antialiasing = true;
+ }
add(kadeLogo);
var txt:FlxText = new FlxText(0, 0, FlxG.width,
@@ -51,6 +59,13 @@ class OutdatedSubState extends MusicBeatState
+ "\n& more changes and bugfixes in the full changelog"
+ "\n\nPress Space to view the full changelog and update\nor ESCAPE to ignore this",
32);
+
+ if (MainMenuState.nightly != "")
+ txt.text =
+ "You are on\n"
+ + MainMenuState.kadeEngineVer
+ + "\nWhich is a PRE-RELEASE BUILD!"
+ + "\n\nReport all bugs to the author of the pre-release.\nSpace/Escape ignores this.";
txt.setFormat("VCR OSD Mono", 32, FlxColor.fromRGB(200, 200, 200), CENTER);
txt.borderColor = FlxColor.BLACK;
@@ -84,10 +99,15 @@ class OutdatedSubState extends MusicBeatState
override function update(elapsed:Float)
{
- if (controls.ACCEPT)
+ if (controls.ACCEPT && MainMenuState.nightly == "")
{
fancyOpenURL("https://kadedev.github.io/Kade-Engine/changelogs/changelog-" + needVer);
}
+ else if (controls.ACCEPT)
+ {
+ leftState = true;
+ FlxG.switchState(new MainMenuState());
+ }
if (controls.BACK)
{
leftState = true;
diff --git a/source/Paths.hx b/source/Paths.hx
index 075adbd..69adc31 100644
--- a/source/Paths.hx
+++ b/source/Paths.hx
@@ -1,5 +1,8 @@
package;
+import openfl.utils.Assets;
+import flixel.graphics.FlxGraphic;
+import flixel.system.FlxAssets.FlxGraphicAsset;
import flixel.FlxG;
import flixel.graphics.frames.FlxAtlasFrames;
import openfl.utils.AssetType;
@@ -50,7 +53,7 @@ class Paths
return 'assets/$file';
}
- inline static public function file(file:String, type:AssetType = TEXT, ?library:String)
+ inline static public function file(file:String, ?library:String, type:AssetType = TEXT)
{
return getPath(file, type, library);
}
@@ -67,7 +70,7 @@ class Paths
inline static public function txt(key:String, ?library:String)
{
- return getPath('data/$key.txt', TEXT, library);
+ return getPath('$key.txt', TEXT, library);
}
inline static public function xml(key:String, ?library:String)
@@ -125,13 +128,48 @@ class Paths
return 'assets/fonts/$key';
}
- inline static public function getSparrowAtlas(key:String, ?library:String)
+ inline static public function getSparrowAtlas(key:String, ?library:String, ?isCharacter:Bool = false)
{
+ var usecahce = FlxG.save.data.cacheImages;
+ #if !cpp
+ usecahce = false;
+ #end
+ if (isCharacter)
+ if (usecahce)
+ #if cpp
+ return FlxAtlasFrames.fromSparrow(imageCached(key), file('images/characters/$key.xml', library));
+ #else
+ return null;
+ #end
+ else
+ return FlxAtlasFrames.fromSparrow(image('characters/$key', library), file('images/characters/$key.xml', library));
return FlxAtlasFrames.fromSparrow(image(key, library), file('images/$key.xml', library));
}
- inline static public function getPackerAtlas(key:String, ?library:String)
+ #if cpp
+ inline static public function imageCached(key:String):FlxGraphic
{
+ var data = Caching.bitmapData.get(key);
+ trace('finding ${key} - ${data.bitmap}');
+ return data;
+ }
+ #end
+
+ inline static public function getPackerAtlas(key:String, ?library:String, ?isCharacter:Bool = false)
+ {
+ var usecahce = FlxG.save.data.cacheImages;
+ #if !cpp
+ usecahce = false;
+ #end
+ if (isCharacter)
+ if (usecahce)
+ #if cpp
+ return FlxAtlasFrames.fromSpriteSheetPacker(imageCached(key), file('images/$key.txt', library));
+ #else
+ return null;
+ #end
+ else
+ return FlxAtlasFrames.fromSpriteSheetPacker(image('characters/$key'), file('images/characters/$key.txt', library));
return FlxAtlasFrames.fromSpriteSheetPacker(image(key, library), file('images/$key.txt', library));
}
}
diff --git a/source/PauseSubState.hx b/source/PauseSubState.hx
index f2e3a0b..e6b68af 100644
--- a/source/PauseSubState.hx
+++ b/source/PauseSubState.hx
@@ -133,6 +133,11 @@ class PauseSubState extends MusicBeatSubstate
}
var songPath = 'assets/data/' + songLowercase + '/';
+ #if sys
+ if (PlayState.isSM && !PlayState.isStoryMode)
+ songPath = PlayState.pathToSm;
+ #end
+
if (controls.UP_P || upPcontroller)
{
changeSelection(-1);
@@ -209,6 +214,7 @@ class PauseSubState extends MusicBeatSubstate
case "Resume":
close();
case "Restart Song":
+ PlayState.startTime = 0;
if (PlayState.instance.useVideo)
{
GlobalVideo.get().stop();
@@ -217,6 +223,7 @@ class PauseSubState extends MusicBeatSubstate
}
FlxG.resetState();
case "Exit to menu":
+ PlayState.startTime = 0;
if (PlayState.instance.useVideo)
{
GlobalVideo.get().stop();
@@ -240,7 +247,10 @@ class PauseSubState extends MusicBeatSubstate
if (FlxG.save.data.fpsCap > 290)
(cast (Lib.current.getChildAt(0), Main)).setFPSCap(290);
- FlxG.switchState(new MainMenuState());
+ if (PlayState.isStoryMode)
+ FlxG.switchState(new StoryMenuState());
+ else
+ FlxG.switchState(new FreeplayState());
}
}
@@ -261,6 +271,8 @@ class PauseSubState extends MusicBeatSubstate
function changeSelection(change:Int = 0):Void
{
curSelected += change;
+
+ FlxG.sound.play(Paths.sound('scrollMenu'), 0.4);
if (curSelected < 0)
curSelected = menuItems.length - 1;
@@ -284,4 +296,4 @@ class PauseSubState extends MusicBeatSubstate
}
}
}
-}
\ No newline at end of file
+}
diff --git a/source/PlayState.hx b/source/PlayState.hx
index af3babe..487ca7a 100644
--- a/source/PlayState.hx
+++ b/source/PlayState.hx
@@ -1,5 +1,11 @@
package;
+import Song.Event;
+import openfl.media.Sound;
+#if sys
+import sys.io.File;
+import smTools.SMFile;
+#end
import openfl.ui.KeyLocation;
import openfl.events.Event;
import haxe.EnumTools;
@@ -20,7 +26,6 @@ import flixel.graphics.FlxGraphic;
import openfl.utils.AssetManifest;
import openfl.utils.AssetLibrary;
import flixel.system.FlxAssets;
-
import lime.app.Application;
import lime.media.AudioContext;
import lime.media.AudioManager;
@@ -63,7 +68,6 @@ import lime.utils.Assets;
import openfl.display.BlendMode;
import openfl.display.StageQuality;
import openfl.filters.ShaderFilter;
-
#if windows
import Discord.DiscordClient;
#end
@@ -96,6 +100,7 @@ class PlayState extends MusicBeatState
public static var rep:Replay;
public static var loadRep:Bool = false;
+ public static var inResults:Bool = false;
public static var noteBools:Array = [false, false, false, false];
@@ -103,7 +108,7 @@ class PlayState extends MusicBeatState
var songLength:Float = 0;
var kadeEngineWatermark:FlxText;
-
+
#if windows
// Discord RPC variables
var storyDifficultyText:String = "";
@@ -114,6 +119,12 @@ class PlayState extends MusicBeatState
private var vocals:FlxSound;
+ public static var isSM:Bool = false;
+ #if sys
+ public static var sm:SMFile;
+ public static var pathToSm:String;
+ #end
+
public var originalX:Float;
public static var dad:Character;
@@ -121,9 +132,11 @@ class PlayState extends MusicBeatState
public static var boyfriend:Boyfriend;
public var notes:FlxTypedGroup;
+
private var unspawnNotes:Array = [];
public var strumLine:FlxSprite;
+
private var curSection:Int = 0;
private var camFollow:FlxObject;
@@ -138,34 +151,45 @@ class PlayState extends MusicBeatState
private var curSong:String = "";
private var gfSpeed:Int = 1;
- public var health:Float = 1; //making public because sethealth doesnt work without it
+
+ public var health:Float = 1; // making public because sethealth doesnt work without it
+
private var combo:Int = 0;
+
public static var misses:Int = 0;
public static var campaignMisses:Int = 0;
+
+
public var accuracy:Float = 0.00;
+
private var accuracyDefault:Float = 0.00;
private var totalNotesHit:Float = 0;
private var totalNotesHitDefault:Float = 0;
private var totalPlayed:Int = 0;
private var ss:Bool = false;
-
private var healthBarBG:FlxSprite;
private var healthBar:FlxBar;
private var songPositionBar:Float = 0;
-
+
private var generatedMusic:Bool = false;
private var startingSong:Bool = false;
- public var iconP1:HealthIcon; //making these public again because i may be stupid
- public var iconP2:HealthIcon; //what could go wrong?
+ public var iconP1:HealthIcon; // making these public again because i may be stupid
+ public var iconP2:HealthIcon; // what could go wrong?
public var camHUD:FlxCamera;
+
private var camGame:FlxCamera;
+ public var cannotDie = false;
public static var offsetTesting:Bool = false;
+ public var isSMFile:Bool = false;
+
var notesHitArray:Array = [];
var currentFrames:Int = 0;
+ var idleToBeat:Bool = true; // change if bf and dad would idle to the beat of the song
+ var idleBeat:Int = 4; // how frequently bf and dad would play their idle animation(1 - every beat, 2 - every 2 beats and so on)
public var dialogue:Array = ['dad:blah blah blah', 'bf:coolswag'];
@@ -190,7 +214,9 @@ class PlayState extends MusicBeatState
var wiggleShit:WiggleEffect = new WiggleEffect();
var talking:Bool = true;
+
public var songScore:Int = 0;
+
var songScoreDef:Int = 0;
var scoreTxt:FlxText;
var replayTxt:FlxText;
@@ -202,21 +228,26 @@ class PlayState extends MusicBeatState
public static var daPixelZoom:Float = 6;
public static var theFunne:Bool = true;
+
var funneEffect:FlxSprite;
var inCutscene:Bool = false;
+ var usedTimeTravel:Bool = false;
+
public static var repPresses:Int = 0;
public static var repReleases:Int = 0;
public static var timeCurrently:Float = 0;
public static var timeCurrentlyR:Float = 0;
-
+
// Will fire once to prevent debug spam messages and broken animations
private var triggeredAlready:Bool = false;
-
+
// Will decide if she's even allowed to headbang at all depending on the song
private var allowedToHeadbang:Bool = false;
+
// Per song additive offset
public static var songOffset:Float = 0;
+
// BotPlay text
private var botPlayState:FlxText;
// Replay shit
@@ -228,19 +259,33 @@ class PlayState extends MusicBeatState
private var executeModchart = false;
- // API stuff
-
- public function addObject(object:FlxBasic) { add(object); }
- public function removeObject(object:FlxBasic) { remove(object); }
+ // Animation common suffixes
+ private var dataSuffix:Array = ['LEFT', 'DOWN', 'UP', 'RIGHT'];
+ private var dataColor:Array = ['purple', 'blue', 'green', 'red'];
+ public static var startTime = 0.0;
+
+ // API stuff
+
+ public function addObject(object:FlxBasic)
+ {
+ add(object);
+ }
+
+ public function removeObject(object:FlxBasic)
+ {
+ remove(object);
+ }
override public function create()
{
+
+ FlxG.mouse.visible = false;
instance = this;
-
+
if (FlxG.save.data.fpsCap > 290)
- (cast (Lib.current.getChildAt(0), Main)).setFPSCap(800);
-
+ (cast(Lib.current.getChildAt(0), Main)).setFPSCap(800);
+
if (FlxG.sound.music != null)
FlxG.sound.music.stop();
@@ -253,9 +298,10 @@ class PlayState extends MusicBeatState
}
misses = 0;
+ highestCombo = 0;
repPresses = 0;
repReleases = 0;
-
+ inResults = false;
PlayStateChangeables.useDownscroll = FlxG.save.data.downscroll;
PlayStateChangeables.safeFrames = FlxG.save.data.frames;
@@ -265,15 +311,18 @@ class PlayState extends MusicBeatState
// pre lowercasing the song name (create)
var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase();
- switch (songLowercase) {
- case 'dad-battle': songLowercase = 'dadbattle';
- case 'philly-nice': songLowercase = 'philly';
+ switch (songLowercase)
+ {
+ case 'dad-battle':
+ songLowercase = 'dadbattle';
+ case 'philly-nice':
+ songLowercase = 'philly';
}
-
+
removedVideo = false;
#if windows
- executeModchart = FileSystem.exists(Paths.lua(songLowercase + "/modchart"));
+ executeModchart = FileSystem.exists(Paths.lua(songLowercase + "/modchart"));
if (executeModchart)
PlayStateChangeables.Optimize = false;
#end
@@ -314,10 +363,21 @@ class PlayState extends MusicBeatState
detailsPausedText = "Paused - " + detailsText;
// Updating Discord Rich Presence.
- DiscordClient.changePresence(detailsText + " " + SONG.song + " (" + storyDifficultyText + ") " + Ratings.GenerateLetterRank(accuracy), "\nAcc: " + HelperFunctions.truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses , iconRPC);
+ DiscordClient.changePresence(detailsText
+ + " "
+ + SONG.song
+ + " ("
+ + storyDifficultyText
+ + ") "
+ + Ratings.GenerateLetterRank(accuracy),
+ "\nAcc: "
+ + HelperFunctions.truncateFloat(accuracy, 2)
+ + "% | Score: "
+ + songScore
+ + " | Misses: "
+ + misses, iconRPC);
#end
-
// var gameCam:FlxCamera = FlxG.camera;
camGame = new FlxCamera();
camHUD = new FlxCamera();
@@ -337,9 +397,51 @@ class PlayState extends MusicBeatState
Conductor.mapBPMChanges(SONG);
Conductor.changeBPM(SONG.bpm);
- trace('INFORMATION ABOUT WHAT U PLAYIN WIT:\nFRAMES: ' + PlayStateChangeables.safeFrames + '\nZONE: ' + Conductor.safeZoneOffset + '\nTS: ' + Conductor.timeScale + '\nBotPlay : ' + PlayStateChangeables.botPlay);
+ if (SONG.eventObjects == null)
+ {
+ SONG.eventObjects = [new Song.Event("Init BPM",0,SONG.bpm,"BPM Change")];
+ }
- //dialogue shit
+
+ TimingStruct.clearTimings();
+
+ var convertedStuff:Array = [];
+
+ var currentIndex = 0;
+ for (i in SONG.eventObjects)
+ {
+ var name = Reflect.field(i,"name");
+ var type = Reflect.field(i,"type");
+ var pos = Reflect.field(i,"position");
+ var value = Reflect.field(i,"value");
+
+ if (type == "BPM Change")
+ {
+ var beat:Float = pos;
+
+ var endBeat:Float = Math.POSITIVE_INFINITY;
+
+ TimingStruct.addTiming(beat,value,endBeat, 0); // offset in this case = start time since we don't have a offset
+
+ if (currentIndex != 0)
+ {
+ var data = TimingStruct.AllTimings[currentIndex - 1];
+ data.endBeat = beat;
+ data.length = (data.endBeat - data.startBeat) / (data.bpm / 60);
+ TimingStruct.AllTimings[currentIndex].startTime = data.startTime + data.length;
+ }
+
+ currentIndex++;
+ }
+ convertedStuff.push(new Song.Event(name,pos,value,type));
+ }
+
+ SONG.eventObjects = convertedStuff;
+
+ trace('INFORMATION ABOUT WHAT U PLAYIN WIT:\nFRAMES: ' + PlayStateChangeables.safeFrames + '\nZONE: ' + Conductor.safeZoneOffset + '\nTS: '
+ + Conductor.timeScale + '\nBotPlay : ' + PlayStateChangeables.botPlay);
+
+ // dialogue shit
switch (songLowercase)
{
case 'tutorial':
@@ -360,318 +462,389 @@ class PlayState extends MusicBeatState
"Only then I will even CONSIDER letting you\ndate my daughter!"
];
case 'senpai':
- dialogue = CoolUtil.coolTextFile(Paths.txt('senpai/senpaiDialogue'));
+ dialogue = CoolUtil.coolTextFile(Paths.txt('data/senpai/senpaiDialogue'));
case 'roses':
- dialogue = CoolUtil.coolTextFile(Paths.txt('roses/rosesDialogue'));
+ dialogue = CoolUtil.coolTextFile(Paths.txt('data/roses/rosesDialogue'));
case 'thorns':
- dialogue = CoolUtil.coolTextFile(Paths.txt('thorns/thornsDialogue'));
+ dialogue = CoolUtil.coolTextFile(Paths.txt('data/thorns/thornsDialogue'));
}
- //defaults if no stage was found in chart
+ // defaults if no stage was found in chart
var stageCheck:String = 'stage';
-
- if (SONG.stage == null) {
- switch(storyWeek)
+
+ if (SONG.stage == null)
+ {
+ switch (storyWeek)
{
- case 2: stageCheck = 'halloween';
- case 3: stageCheck = 'philly';
- case 4: stageCheck = 'limo';
- case 5: if (songLowercase == 'winter-horrorland') {stageCheck = 'mallEvil';} else {stageCheck = 'mall';}
- case 6: if (songLowercase == 'thorns') {stageCheck = 'schoolEvil';} else {stageCheck = 'school';}
- //i should check if its stage (but this is when none is found in chart anyway)
+ case 2:
+ stageCheck = 'halloween';
+ case 3:
+ stageCheck = 'philly';
+ case 4:
+ stageCheck = 'limo';
+ case 5:
+ if (songLowercase == 'winter-horrorland')
+ {
+ stageCheck = 'mallEvil';
+ }
+ else
+ {
+ stageCheck = 'mall';
+ }
+ case 6:
+ if (songLowercase == 'thorns')
+ {
+ stageCheck = 'schoolEvil';
+ }
+ else
+ {
+ stageCheck = 'school';
+ }
+ // i should check if its stage (but this is when none is found in chart anyway)
}
- } else {stageCheck = SONG.stage;}
+ }
+ else
+ {
+ stageCheck = SONG.stage;
+ }
if (!PlayStateChangeables.Optimize)
{
-
- switch(stageCheck)
- {
- case 'halloween':
+ switch (stageCheck)
{
- curStage = 'spooky';
- halloweenLevel = true;
-
- var hallowTex = Paths.getSparrowAtlas('halloween_bg','week2');
-
- halloweenBG = new FlxSprite(-200, -100);
- halloweenBG.frames = hallowTex;
- halloweenBG.animation.addByPrefix('idle', 'halloweem bg0');
- halloweenBG.animation.addByPrefix('lightning', 'halloweem bg lightning strike', 24, false);
- halloweenBG.animation.play('idle');
- halloweenBG.antialiasing = true;
- add(halloweenBG);
-
- isHalloween = true;
- }
- case 'philly':
+ case 'halloween':
{
- curStage = 'philly';
+ curStage = 'spooky';
+ halloweenLevel = true;
- var bg:FlxSprite = new FlxSprite(-100).loadGraphic(Paths.image('philly/sky', 'week3'));
- bg.scrollFactor.set(0.1, 0.1);
- add(bg);
+ var hallowTex = Paths.getSparrowAtlas('halloween_bg', 'week2');
- var city:FlxSprite = new FlxSprite(-10).loadGraphic(Paths.image('philly/city', 'week3'));
- city.scrollFactor.set(0.3, 0.3);
- city.setGraphicSize(Std.int(city.width * 0.85));
- city.updateHitbox();
- add(city);
+ halloweenBG = new FlxSprite(-200, -100);
+ halloweenBG.frames = hallowTex;
+ halloweenBG.animation.addByPrefix('idle', 'halloweem bg0');
+ halloweenBG.animation.addByPrefix('lightning', 'halloweem bg lightning strike', 24, false);
+ halloweenBG.animation.play('idle');
+ if(FlxG.save.data.antialiasing)
+ {
+ halloweenBG.antialiasing = true;
+ }
+ add(halloweenBG);
- phillyCityLights = new FlxTypedGroup();
- if(FlxG.save.data.distractions){
- add(phillyCityLights);
+ isHalloween = true;
}
-
- for (i in 0...5)
+ case 'philly':
{
+ curStage = 'philly';
+
+ var bg:FlxSprite = new FlxSprite(-100).loadGraphic(Paths.image('philly/sky', 'week3'));
+ bg.scrollFactor.set(0.1, 0.1);
+ add(bg);
+
+ var city:FlxSprite = new FlxSprite(-10).loadGraphic(Paths.image('philly/city', 'week3'));
+ city.scrollFactor.set(0.3, 0.3);
+ city.setGraphicSize(Std.int(city.width * 0.85));
+ city.updateHitbox();
+ add(city);
+
+ phillyCityLights = new FlxTypedGroup();
+ if (FlxG.save.data.distractions)
+ {
+ add(phillyCityLights);
+ }
+
+ for (i in 0...5)
+ {
var light:FlxSprite = new FlxSprite(city.x).loadGraphic(Paths.image('philly/win' + i, 'week3'));
light.scrollFactor.set(0.3, 0.3);
light.visible = false;
light.setGraphicSize(Std.int(light.width * 0.85));
light.updateHitbox();
- light.antialiasing = true;
+ if(FlxG.save.data.antialiasing)
+ {
+ light.antialiasing = true;
+ }
phillyCityLights.add(light);
- }
+ }
- var streetBehind:FlxSprite = new FlxSprite(-40, 50).loadGraphic(Paths.image('philly/behindTrain','week3'));
- add(streetBehind);
+ var streetBehind:FlxSprite = new FlxSprite(-40, 50).loadGraphic(Paths.image('philly/behindTrain', 'week3'));
+ add(streetBehind);
- phillyTrain = new FlxSprite(2000, 360).loadGraphic(Paths.image('philly/train','week3'));
- if(FlxG.save.data.distractions){
- add(phillyTrain);
- }
-
- trainSound = new FlxSound().loadEmbedded(Paths.sound('train_passes','week3'));
- FlxG.sound.list.add(trainSound);
-
- // var cityLights:FlxSprite = new FlxSprite().loadGraphic(AssetPaths.win0.png);
-
- var street:FlxSprite = new FlxSprite(-40, streetBehind.y).loadGraphic(Paths.image('philly/street','week3'));
- add(street);
- }
- case 'limo':
- {
- curStage = 'limo';
- defaultCamZoom = 0.90;
-
- var skyBG:FlxSprite = new FlxSprite(-120, -50).loadGraphic(Paths.image('limo/limoSunset','week4'));
- skyBG.scrollFactor.set(0.1, 0.1);
- add(skyBG);
-
- var bgLimo:FlxSprite = new FlxSprite(-200, 480);
- bgLimo.frames = Paths.getSparrowAtlas('limo/bgLimo','week4');
- bgLimo.animation.addByPrefix('drive', "background limo pink", 24);
- bgLimo.animation.play('drive');
- bgLimo.scrollFactor.set(0.4, 0.4);
- add(bgLimo);
- if(FlxG.save.data.distractions){
- grpLimoDancers = new FlxTypedGroup();
- add(grpLimoDancers);
-
- for (i in 0...5)
+ phillyTrain = new FlxSprite(2000, 360).loadGraphic(Paths.image('philly/train', 'week3'));
+ if (FlxG.save.data.distractions)
{
+ add(phillyTrain);
+ }
+
+ trainSound = new FlxSound().loadEmbedded(Paths.sound('train_passes', 'week3'));
+ FlxG.sound.list.add(trainSound);
+
+ // var cityLights:FlxSprite = new FlxSprite().loadGraphic(AssetPaths.win0.png);
+
+ var street:FlxSprite = new FlxSprite(-40, streetBehind.y).loadGraphic(Paths.image('philly/street', 'week3'));
+ add(street);
+ }
+ case 'limo':
+ {
+ curStage = 'limo';
+ defaultCamZoom = 0.90;
+
+ var skyBG:FlxSprite = new FlxSprite(-120, -50).loadGraphic(Paths.image('limo/limoSunset', 'week4'));
+ skyBG.scrollFactor.set(0.1, 0.1);
+ add(skyBG);
+
+ var bgLimo:FlxSprite = new FlxSprite(-200, 480);
+ bgLimo.frames = Paths.getSparrowAtlas('limo/bgLimo', 'week4');
+ bgLimo.animation.addByPrefix('drive', "background limo pink", 24);
+ bgLimo.animation.play('drive');
+ bgLimo.scrollFactor.set(0.4, 0.4);
+ add(bgLimo);
+ if (FlxG.save.data.distractions)
+ {
+ grpLimoDancers = new FlxTypedGroup();
+ add(grpLimoDancers);
+
+ for (i in 0...5)
+ {
var dancer:BackgroundDancer = new BackgroundDancer((370 * i) + 130, bgLimo.y - 400);
dancer.scrollFactor.set(0.4, 0.4);
grpLimoDancers.add(dancer);
+ }
+ }
+
+ var overlayShit:FlxSprite = new FlxSprite(-500, -600).loadGraphic(Paths.image('limo/limoOverlay', 'week4'));
+ overlayShit.alpha = 0.5;
+ // add(overlayShit);
+
+ // var shaderBullshit = new BlendModeEffect(new OverlayShader(), FlxColor.RED);
+
+ // FlxG.camera.setFilters([new ShaderFilter(cast shaderBullshit.shader)]);
+
+ // overlayShit.shader = shaderBullshit;
+
+ var limoTex = Paths.getSparrowAtlas('limo/limoDrive', 'week4');
+
+ limo = new FlxSprite(-120, 550);
+ limo.frames = limoTex;
+ limo.animation.addByPrefix('drive', "Limo stage", 24);
+ limo.animation.play('drive');
+ if(FlxG.save.data.antialiasing)
+ {
+ limo.antialiasing = true;
+ }
+
+ fastCar = new FlxSprite(-300, 160).loadGraphic(Paths.image('limo/fastCarLol', 'week4'));
+ // add(limo);
+ }
+ case 'mall':
+ {
+ curStage = 'mall';
+
+ defaultCamZoom = 0.80;
+
+ var bg:FlxSprite = new FlxSprite(-1000, -500).loadGraphic(Paths.image('christmas/bgWalls', 'week5'));
+ if(FlxG.save.data.antialiasing)
+ {
+ bg.antialiasing = true;
+ }
+ bg.scrollFactor.set(0.2, 0.2);
+ bg.active = false;
+ bg.setGraphicSize(Std.int(bg.width * 0.8));
+ bg.updateHitbox();
+ add(bg);
+
+ upperBoppers = new FlxSprite(-240, -90);
+ upperBoppers.frames = Paths.getSparrowAtlas('christmas/upperBop', 'week5');
+ upperBoppers.animation.addByPrefix('bop', "Upper Crowd Bob", 24, false);
+ if(FlxG.save.data.antialiasing)
+ {
+ upperBoppers.antialiasing = true;
+ }
+ upperBoppers.scrollFactor.set(0.33, 0.33);
+ upperBoppers.setGraphicSize(Std.int(upperBoppers.width * 0.85));
+ upperBoppers.updateHitbox();
+ if (FlxG.save.data.distractions)
+ {
+ add(upperBoppers);
+ }
+
+ var bgEscalator:FlxSprite = new FlxSprite(-1100, -600).loadGraphic(Paths.image('christmas/bgEscalator', 'week5'));
+ if(FlxG.save.data.antialiasing)
+ {
+ bgEscalator.antialiasing = true;
+ }
+ bgEscalator.scrollFactor.set(0.3, 0.3);
+ bgEscalator.active = false;
+ bgEscalator.setGraphicSize(Std.int(bgEscalator.width * 0.9));
+ bgEscalator.updateHitbox();
+ add(bgEscalator);
+
+ var tree:FlxSprite = new FlxSprite(370, -250).loadGraphic(Paths.image('christmas/christmasTree', 'week5'));
+ if(FlxG.save.data.antialiasing)
+ {
+ tree.antialiasing = true;
+ }
+ tree.scrollFactor.set(0.40, 0.40);
+ add(tree);
+
+ bottomBoppers = new FlxSprite(-300, 140);
+ bottomBoppers.frames = Paths.getSparrowAtlas('christmas/bottomBop', 'week5');
+ bottomBoppers.animation.addByPrefix('bop', 'Bottom Level Boppers', 24, false);
+ if(FlxG.save.data.antialiasing)
+ {
+ bottomBoppers.antialiasing = true;
+ }
+ bottomBoppers.scrollFactor.set(0.9, 0.9);
+ bottomBoppers.setGraphicSize(Std.int(bottomBoppers.width * 1));
+ bottomBoppers.updateHitbox();
+ if (FlxG.save.data.distractions)
+ {
+ add(bottomBoppers);
+ }
+
+ var fgSnow:FlxSprite = new FlxSprite(-600, 700).loadGraphic(Paths.image('christmas/fgSnow', 'week5'));
+ fgSnow.active = false;
+ if(FlxG.save.data.antialiasing)
+ {
+ fgSnow.antialiasing = true;
+ }
+ add(fgSnow);
+
+ santa = new FlxSprite(-840, 150);
+ santa.frames = Paths.getSparrowAtlas('christmas/santa', 'week5');
+ santa.animation.addByPrefix('idle', 'santa idle in fear', 24, false);
+ if(FlxG.save.data.antialiasing)
+ {
+ santa.antialiasing = true;
+ }
+ if (FlxG.save.data.distractions)
+ {
+ add(santa);
}
}
+ case 'mallEvil':
+ {
+ curStage = 'mallEvil';
+ var bg:FlxSprite = new FlxSprite(-400, -500).loadGraphic(Paths.image('christmas/evilBG', 'week5'));
+ if(FlxG.save.data.antialiasing)
+ {
+ bg.antialiasing = true;
+ }
+ bg.scrollFactor.set(0.2, 0.2);
+ bg.active = false;
+ bg.setGraphicSize(Std.int(bg.width * 0.8));
+ bg.updateHitbox();
+ add(bg);
- var overlayShit:FlxSprite = new FlxSprite(-500, -600).loadGraphic(Paths.image('limo/limoOverlay','week4'));
- overlayShit.alpha = 0.5;
- // add(overlayShit);
+ var evilTree:FlxSprite = new FlxSprite(300, -300).loadGraphic(Paths.image('christmas/evilTree', 'week5'));
+ if(FlxG.save.data.antialiasing)
+ {
+ evilTree.antialiasing = true;
+ }
+ evilTree.scrollFactor.set(0.2, 0.2);
+ add(evilTree);
- // var shaderBullshit = new BlendModeEffect(new OverlayShader(), FlxColor.RED);
-
- // FlxG.camera.setFilters([new ShaderFilter(cast shaderBullshit.shader)]);
-
- // overlayShit.shader = shaderBullshit;
-
- var limoTex = Paths.getSparrowAtlas('limo/limoDrive','week4');
-
- limo = new FlxSprite(-120, 550);
- limo.frames = limoTex;
- limo.animation.addByPrefix('drive', "Limo stage", 24);
- limo.animation.play('drive');
- limo.antialiasing = true;
-
- fastCar = new FlxSprite(-300, 160).loadGraphic(Paths.image('limo/fastCarLol','week4'));
- // add(limo);
- }
- case 'mall':
- {
- curStage = 'mall';
-
- defaultCamZoom = 0.80;
-
- var bg:FlxSprite = new FlxSprite(-1000, -500).loadGraphic(Paths.image('christmas/bgWalls','week5'));
- bg.antialiasing = true;
- bg.scrollFactor.set(0.2, 0.2);
- bg.active = false;
- bg.setGraphicSize(Std.int(bg.width * 0.8));
- bg.updateHitbox();
- add(bg);
-
- upperBoppers = new FlxSprite(-240, -90);
- upperBoppers.frames = Paths.getSparrowAtlas('christmas/upperBop','week5');
- upperBoppers.animation.addByPrefix('bop', "Upper Crowd Bob", 24, false);
- upperBoppers.antialiasing = true;
- upperBoppers.scrollFactor.set(0.33, 0.33);
- upperBoppers.setGraphicSize(Std.int(upperBoppers.width * 0.85));
- upperBoppers.updateHitbox();
- if(FlxG.save.data.distractions){
- add(upperBoppers);
+ var evilSnow:FlxSprite = new FlxSprite(-200, 700).loadGraphic(Paths.image("christmas/evilSnow", 'week5'));
+ if(FlxG.save.data.antialiasing)
+ {
+ evilSnow.antialiasing = true;
+ }
+ add(evilSnow);
}
+ case 'school':
+ {
+ curStage = 'school';
+ // defaultCamZoom = 0.9;
- var bgEscalator:FlxSprite = new FlxSprite(-1100, -600).loadGraphic(Paths.image('christmas/bgEscalator','week5'));
- bgEscalator.antialiasing = true;
- bgEscalator.scrollFactor.set(0.3, 0.3);
- bgEscalator.active = false;
- bgEscalator.setGraphicSize(Std.int(bgEscalator.width * 0.9));
- bgEscalator.updateHitbox();
- add(bgEscalator);
+ var bgSky = new FlxSprite().loadGraphic(Paths.image('weeb/weebSky', 'week6'));
+ bgSky.scrollFactor.set(0.1, 0.1);
+ add(bgSky);
- var tree:FlxSprite = new FlxSprite(370, -250).loadGraphic(Paths.image('christmas/christmasTree','week5'));
- tree.antialiasing = true;
- tree.scrollFactor.set(0.40, 0.40);
- add(tree);
+ var repositionShit = -200;
- bottomBoppers = new FlxSprite(-300, 140);
- bottomBoppers.frames = Paths.getSparrowAtlas('christmas/bottomBop','week5');
- bottomBoppers.animation.addByPrefix('bop', 'Bottom Level Boppers', 24, false);
- bottomBoppers.antialiasing = true;
- bottomBoppers.scrollFactor.set(0.9, 0.9);
- bottomBoppers.setGraphicSize(Std.int(bottomBoppers.width * 1));
- bottomBoppers.updateHitbox();
- if(FlxG.save.data.distractions){
- add(bottomBoppers);
- }
+ var bgSchool:FlxSprite = new FlxSprite(repositionShit, 0).loadGraphic(Paths.image('weeb/weebSchool', 'week6'));
+ bgSchool.scrollFactor.set(0.6, 0.90);
+ add(bgSchool);
+ var bgStreet:FlxSprite = new FlxSprite(repositionShit).loadGraphic(Paths.image('weeb/weebStreet', 'week6'));
+ bgStreet.scrollFactor.set(0.95, 0.95);
+ add(bgStreet);
- var fgSnow:FlxSprite = new FlxSprite(-600, 700).loadGraphic(Paths.image('christmas/fgSnow','week5'));
- fgSnow.active = false;
- fgSnow.antialiasing = true;
- add(fgSnow);
+ var fgTrees:FlxSprite = new FlxSprite(repositionShit + 170, 130).loadGraphic(Paths.image('weeb/weebTreesBack', 'week6'));
+ fgTrees.scrollFactor.set(0.9, 0.9);
+ add(fgTrees);
- santa = new FlxSprite(-840, 150);
- santa.frames = Paths.getSparrowAtlas('christmas/santa','week5');
- santa.animation.addByPrefix('idle', 'santa idle in fear', 24, false);
- santa.antialiasing = true;
- if(FlxG.save.data.distractions){
- add(santa);
- }
- }
- case 'mallEvil':
- {
- curStage = 'mallEvil';
- var bg:FlxSprite = new FlxSprite(-400, -500).loadGraphic(Paths.image('christmas/evilBG','week5'));
- bg.antialiasing = true;
- bg.scrollFactor.set(0.2, 0.2);
- bg.active = false;
- bg.setGraphicSize(Std.int(bg.width * 0.8));
- bg.updateHitbox();
- add(bg);
+ var bgTrees:FlxSprite = new FlxSprite(repositionShit - 380, -800);
+ var treetex = Paths.getPackerAtlas('weeb/weebTrees', 'week6');
+ bgTrees.frames = treetex;
+ bgTrees.animation.add('treeLoop', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], 12);
+ bgTrees.animation.play('treeLoop');
+ bgTrees.scrollFactor.set(0.85, 0.85);
+ add(bgTrees);
- var evilTree:FlxSprite = new FlxSprite(300, -300).loadGraphic(Paths.image('christmas/evilTree','week5'));
- evilTree.antialiasing = true;
- evilTree.scrollFactor.set(0.2, 0.2);
- add(evilTree);
+ var treeLeaves:FlxSprite = new FlxSprite(repositionShit, -40);
+ treeLeaves.frames = Paths.getSparrowAtlas('weeb/petals', 'week6');
+ treeLeaves.animation.addByPrefix('leaves', 'PETALS ALL', 24, true);
+ treeLeaves.animation.play('leaves');
+ treeLeaves.scrollFactor.set(0.85, 0.85);
+ add(treeLeaves);
- var evilSnow:FlxSprite = new FlxSprite(-200, 700).loadGraphic(Paths.image("christmas/evilSnow",'week5'));
- evilSnow.antialiasing = true;
- add(evilSnow);
- }
- case 'school':
- {
- curStage = 'school';
+ var widShit = Std.int(bgSky.width * 6);
- // defaultCamZoom = 0.9;
+ bgSky.setGraphicSize(widShit);
+ bgSchool.setGraphicSize(widShit);
+ bgStreet.setGraphicSize(widShit);
+ bgTrees.setGraphicSize(Std.int(widShit * 1.4));
+ fgTrees.setGraphicSize(Std.int(widShit * 0.8));
+ treeLeaves.setGraphicSize(widShit);
- var bgSky = new FlxSprite().loadGraphic(Paths.image('weeb/weebSky','week6'));
- bgSky.scrollFactor.set(0.1, 0.1);
- add(bgSky);
+ fgTrees.updateHitbox();
+ bgSky.updateHitbox();
+ bgSchool.updateHitbox();
+ bgStreet.updateHitbox();
+ bgTrees.updateHitbox();
+ treeLeaves.updateHitbox();
- var repositionShit = -200;
+ bgGirls = new BackgroundGirls(-100, 190);
+ bgGirls.scrollFactor.set(0.9, 0.9);
- var bgSchool:FlxSprite = new FlxSprite(repositionShit, 0).loadGraphic(Paths.image('weeb/weebSchool','week6'));
- bgSchool.scrollFactor.set(0.6, 0.90);
- add(bgSchool);
-
- var bgStreet:FlxSprite = new FlxSprite(repositionShit).loadGraphic(Paths.image('weeb/weebStreet','week6'));
- bgStreet.scrollFactor.set(0.95, 0.95);
- add(bgStreet);
-
- var fgTrees:FlxSprite = new FlxSprite(repositionShit + 170, 130).loadGraphic(Paths.image('weeb/weebTreesBack','week6'));
- fgTrees.scrollFactor.set(0.9, 0.9);
- add(fgTrees);
-
- var bgTrees:FlxSprite = new FlxSprite(repositionShit - 380, -800);
- var treetex = Paths.getPackerAtlas('weeb/weebTrees','week6');
- bgTrees.frames = treetex;
- bgTrees.animation.add('treeLoop', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], 12);
- bgTrees.animation.play('treeLoop');
- bgTrees.scrollFactor.set(0.85, 0.85);
- add(bgTrees);
-
- var treeLeaves:FlxSprite = new FlxSprite(repositionShit, -40);
- treeLeaves.frames = Paths.getSparrowAtlas('weeb/petals','week6');
- treeLeaves.animation.addByPrefix('leaves', 'PETALS ALL', 24, true);
- treeLeaves.animation.play('leaves');
- treeLeaves.scrollFactor.set(0.85, 0.85);
- add(treeLeaves);
-
- var widShit = Std.int(bgSky.width * 6);
-
- bgSky.setGraphicSize(widShit);
- bgSchool.setGraphicSize(widShit);
- bgStreet.setGraphicSize(widShit);
- bgTrees.setGraphicSize(Std.int(widShit * 1.4));
- fgTrees.setGraphicSize(Std.int(widShit * 0.8));
- treeLeaves.setGraphicSize(widShit);
-
- fgTrees.updateHitbox();
- bgSky.updateHitbox();
- bgSchool.updateHitbox();
- bgStreet.updateHitbox();
- bgTrees.updateHitbox();
- treeLeaves.updateHitbox();
-
- bgGirls = new BackgroundGirls(-100, 190);
- bgGirls.scrollFactor.set(0.9, 0.9);
-
- if (songLowercase == 'roses')
+ if (songLowercase == 'roses')
{
- if(FlxG.save.data.distractions){
+ if (FlxG.save.data.distractions)
+ {
bgGirls.getScared();
}
}
- bgGirls.setGraphicSize(Std.int(bgGirls.width * daPixelZoom));
- bgGirls.updateHitbox();
- if(FlxG.save.data.distractions){
- add(bgGirls);
+ bgGirls.setGraphicSize(Std.int(bgGirls.width * daPixelZoom));
+ bgGirls.updateHitbox();
+ if (FlxG.save.data.distractions)
+ {
+ add(bgGirls);
+ }
}
- }
- case 'schoolEvil':
- {
- curStage = 'schoolEvil';
+ case 'schoolEvil':
+ {
+ curStage = 'schoolEvil';
- var waveEffectBG = new FlxWaveEffect(FlxWaveMode.ALL, 2, -1, 3, 2);
- var waveEffectFG = new FlxWaveEffect(FlxWaveMode.ALL, 2, -1, 5, 2);
+ if (!PlayStateChangeables.Optimize)
+ {
+ var waveEffectBG = new FlxWaveEffect(FlxWaveMode.ALL, 2, -1, 3, 2);
+ var waveEffectFG = new FlxWaveEffect(FlxWaveMode.ALL, 2, -1, 5, 2);
+ }
- var posX = 400;
- var posY = 200;
+ var posX = 400;
+ var posY = 200;
- var bg:FlxSprite = new FlxSprite(posX, posY);
- bg.frames = Paths.getSparrowAtlas('weeb/animatedEvilSchool','week6');
- bg.animation.addByPrefix('idle', 'background 2', 24);
- bg.animation.play('idle');
- bg.scrollFactor.set(0.8, 0.9);
- bg.scale.set(6, 6);
- add(bg);
+ var bg:FlxSprite = new FlxSprite(posX, posY);
+ bg.frames = Paths.getSparrowAtlas('weeb/animatedEvilSchool', 'week6');
+ bg.animation.addByPrefix('idle', 'background 2', 24);
+ bg.animation.play('idle');
+ bg.scrollFactor.set(0.8, 0.9);
+ bg.scale.set(6, 6);
+ add(bg);
- /*
+ /*
var bg:FlxSprite = new FlxSprite(posX, posY).loadGraphic(Paths.image('weeb/evilSchoolBG'));
bg.scale.set(6, 6);
// bg.setGraphicSize(Std.int(bg.width * 6));
@@ -686,96 +859,86 @@ class PlayState extends MusicBeatState
wiggleShit.waveAmplitude = 0.01;
wiggleShit.waveFrequency = 60;
wiggleShit.waveSpeed = 0.8;
- */
+ */
- // bg.shader = wiggleShit.shader;
- // fg.shader = wiggleShit.shader;
+ // bg.shader = wiggleShit.shader;
+ // fg.shader = wiggleShit.shader;
- /*
- var waveSprite = new FlxEffectSprite(bg, [waveEffectBG]);
- var waveSpriteFG = new FlxEffectSprite(fg, [waveEffectFG]);
- // Using scale since setGraphicSize() doesnt work???
- waveSprite.scale.set(6, 6);
- waveSpriteFG.scale.set(6, 6);
- waveSprite.setPosition(posX, posY);
- waveSpriteFG.setPosition(posX, posY);
- waveSprite.scrollFactor.set(0.7, 0.8);
- waveSpriteFG.scrollFactor.set(0.9, 0.8);
- // waveSprite.setGraphicSize(Std.int(waveSprite.width * 6));
- // waveSprite.updateHitbox();
- // waveSpriteFG.setGraphicSize(Std.int(fg.width * 6));
- // waveSpriteFG.updateHitbox();
- add(waveSprite);
- add(waveSpriteFG);
- */
- }
- case 'stage':
- {
+ /*
+ var waveSprite = new FlxEffectSprite(bg, [waveEffectBG]);
+ var waveSpriteFG = new FlxEffectSprite(fg, [waveEffectFG]);
+ // Using scale since setGraphicSize() doesnt work???
+ waveSprite.scale.set(6, 6);
+ waveSpriteFG.scale.set(6, 6);
+ waveSprite.setPosition(posX, posY);
+ waveSpriteFG.setPosition(posX, posY);
+ waveSprite.scrollFactor.set(0.7, 0.8);
+ waveSpriteFG.scrollFactor.set(0.9, 0.8);
+ // waveSprite.setGraphicSize(Std.int(waveSprite.width * 6));
+ // waveSprite.updateHitbox();
+ // waveSpriteFG.setGraphicSize(Std.int(fg.width * 6));
+ // waveSpriteFG.updateHitbox();
+ add(waveSprite);
+ add(waveSpriteFG);
+ */
+ }
+ default:
+ {
defaultCamZoom = 0.9;
curStage = 'stage';
var bg:FlxSprite = new FlxSprite(-600, -200).loadGraphic(Paths.image('stageback'));
- bg.antialiasing = true;
+ if(FlxG.save.data.antialiasing)
+ {
+ bg.antialiasing = true;
+ }
bg.scrollFactor.set(0.9, 0.9);
bg.active = false;
add(bg);
-
+
var stageFront:FlxSprite = new FlxSprite(-650, 600).loadGraphic(Paths.image('stagefront'));
stageFront.setGraphicSize(Std.int(stageFront.width * 1.1));
stageFront.updateHitbox();
- stageFront.antialiasing = true;
+ if(FlxG.save.data.antialiasing)
+ {
+ stageFront.antialiasing = true;
+ }
stageFront.scrollFactor.set(0.9, 0.9);
stageFront.active = false;
add(stageFront);
-
+
var stageCurtains:FlxSprite = new FlxSprite(-500, -300).loadGraphic(Paths.image('stagecurtains'));
stageCurtains.setGraphicSize(Std.int(stageCurtains.width * 0.9));
stageCurtains.updateHitbox();
- stageCurtains.antialiasing = true;
+ if(FlxG.save.data.antialiasing)
+ {
+ stageCurtains.antialiasing = true;
+ }
stageCurtains.scrollFactor.set(1.3, 1.3);
stageCurtains.active = false;
-
+
add(stageCurtains);
- }
- default:
- {
- defaultCamZoom = 0.9;
- curStage = 'stage';
- var bg:FlxSprite = new FlxSprite(-600, -200).loadGraphic(Paths.image('stageback'));
- bg.antialiasing = true;
- bg.scrollFactor.set(0.9, 0.9);
- bg.active = false;
- add(bg);
-
- var stageFront:FlxSprite = new FlxSprite(-650, 600).loadGraphic(Paths.image('stagefront'));
- stageFront.setGraphicSize(Std.int(stageFront.width * 1.1));
- stageFront.updateHitbox();
- stageFront.antialiasing = true;
- stageFront.scrollFactor.set(0.9, 0.9);
- stageFront.active = false;
- add(stageFront);
-
- var stageCurtains:FlxSprite = new FlxSprite(-500, -300).loadGraphic(Paths.image('stagecurtains'));
- stageCurtains.setGraphicSize(Std.int(stageCurtains.width * 0.9));
- stageCurtains.updateHitbox();
- stageCurtains.antialiasing = true;
- stageCurtains.scrollFactor.set(1.3, 1.3);
- stageCurtains.active = false;
-
- add(stageCurtains);
+ }
}
}
- }
- //defaults if no gf was found in chart
+ // defaults if no gf was found in chart
var gfCheck:String = 'gf';
-
- if (SONG.gfVersion == null) {
- switch(storyWeek)
+
+ if (SONG.gfVersion == null)
+ {
+ switch (storyWeek)
{
- case 4: gfCheck = 'gf-car';
- case 5: gfCheck = 'gf-christmas';
- case 6: gfCheck = 'gf-pixel';
+ case 4:
+ gfCheck = 'gf-car';
+ case 5:
+ gfCheck = 'gf-christmas';
+ case 6:
+ gfCheck = 'gf-pixel';
}
- } else {gfCheck = SONG.gfVersion;}
+ }
+ else
+ {
+ gfCheck = SONG.gfVersion;
+ }
var curGf:String = '';
switch (gfCheck)
@@ -789,7 +952,7 @@ class PlayState extends MusicBeatState
default:
curGf = 'gf';
}
-
+
gf = new Character(400, 130, curGf);
gf.scrollFactor.set(0.95, 0.95);
@@ -830,13 +993,24 @@ class PlayState extends MusicBeatState
dad.y += 360;
camPos.set(dad.getGraphicMidpoint().x + 300, dad.getGraphicMidpoint().y);
case 'spirit':
+ if (FlxG.save.data.distractions)
+ {
+ // trailArea.scrollFactor.set();
+ if (!PlayStateChangeables.Optimize)
+ {
+ var evilTrail = new FlxTrail(dad, null, 4, 24, 0.3, 0.069);
+ // evilTrail.changeValuesEnabled(false, false, false, false);
+ // evilTrail.changeGraphic()
+ add(evilTrail);
+ }
+ // evilTrail.scrollFactor.set(1.1, 1.1);
+ }
+
dad.x -= 150;
dad.y += 100;
camPos.set(dad.getGraphicMidpoint().x + 300, dad.getGraphicMidpoint().y);
}
-
-
boyfriend = new Boyfriend(770, 450, SONG.player1);
// REPOSITIONING PER STAGE
@@ -845,7 +1019,8 @@ class PlayState extends MusicBeatState
case 'limo':
boyfriend.y -= 220;
boyfriend.x += 260;
- if(FlxG.save.data.distractions){
+ if (FlxG.save.data.distractions)
+ {
resetFastCar();
add(fastCar);
}
@@ -862,16 +1037,6 @@ class PlayState extends MusicBeatState
gf.x += 180;
gf.y += 300;
case 'schoolEvil':
- if(FlxG.save.data.distractions){
- // trailArea.scrollFactor.set();
- var evilTrail = new FlxTrail(dad, null, 4, 24, 0.3, 0.069);
- // evilTrail.changeValuesEnabled(false, false, false, false);
- // evilTrail.changeGraphic()
- add(evilTrail);
- // evilTrail.scrollFactor.set(1.1, 1.1);
- }
-
-
boyfriend.x += 200;
boyfriend.y += 220;
gf.x += 180;
@@ -890,11 +1055,10 @@ class PlayState extends MusicBeatState
add(boyfriend);
}
-
if (loadRep)
{
- FlxG.watch.addQuick('rep rpesses',repPresses);
- FlxG.watch.addQuick('rep releases',repReleases);
+ FlxG.watch.addQuick('rep rpesses', repPresses);
+ FlxG.watch.addQuick('rep releases', repReleases);
// FlxG.watch.addQuick('Queued',inputsQueued);
PlayStateChangeables.useDownscroll = rep.replay.isDownscroll;
@@ -913,10 +1077,10 @@ class PlayState extends MusicBeatState
doof.finishThing = startCountdown;
Conductor.songPosition = -5000;
-
+
strumLine = new FlxSprite(0, 50).makeGraphic(FlxG.width, 10);
strumLine.scrollFactor.set();
-
+
if (PlayStateChangeables.useDownscroll)
strumLine.y = FlxG.height - 165;
@@ -926,6 +1090,9 @@ class PlayState extends MusicBeatState
playerStrums = new FlxTypedGroup();
cpuStrums = new FlxTypedGroup();
+ generateStaticArrows(0);
+ generateStaticArrows(1);
+
// startCountdown();
if (SONG.song == null)
@@ -951,7 +1118,7 @@ class PlayState extends MusicBeatState
add(camFollow);
- FlxG.camera.follow(camFollow, LOCKON, 0.04 * (30 / (cast (Lib.current.getChildAt(0), Main)).getFPS()));
+ FlxG.camera.follow(camFollow, LOCKON, 0.04 * (30 / (cast(Lib.current.getChildAt(0), Main)).getFPS()));
// FlxG.camera.setScrollBounds(0, FlxG.width, 0, FlxG.height);
FlxG.camera.zoom = defaultCamZoom;
FlxG.camera.focusOn(camFollow.getPosition());
@@ -961,28 +1128,28 @@ class PlayState extends MusicBeatState
FlxG.fixedTimestep = false;
if (FlxG.save.data.songPosition) // I dont wanna talk about this code :(
- {
- songPosBG = new FlxSprite(0, 10).loadGraphic(Paths.image('healthBar'));
- if (PlayStateChangeables.useDownscroll)
- songPosBG.y = FlxG.height * 0.9 + 45;
- songPosBG.screenCenter(X);
- songPosBG.scrollFactor.set();
- add(songPosBG);
-
- songPosBar = new FlxBar(songPosBG.x + 4, songPosBG.y + 4, LEFT_TO_RIGHT, Std.int(songPosBG.width - 8), Std.int(songPosBG.height - 8), this,
- 'songPositionBar', 0, 90000);
- songPosBar.scrollFactor.set();
- songPosBar.createFilledBar(FlxColor.GRAY, FlxColor.LIME);
- add(songPosBar);
-
- var songName = new FlxText(songPosBG.x + (songPosBG.width / 2) - (SONG.song.length * 5),songPosBG.y,0,SONG.song, 16);
- if (PlayStateChangeables.useDownscroll)
- songName.y -= 3;
- songName.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK);
- songName.scrollFactor.set();
- add(songName);
- songName.cameras = [camHUD];
- }
+ {
+ songPosBG = new FlxSprite(0, 10).loadGraphic(Paths.image('healthBar'));
+ if (PlayStateChangeables.useDownscroll)
+ songPosBG.y = FlxG.height * 0.9 + 45;
+ songPosBG.screenCenter(X);
+ songPosBG.scrollFactor.set();
+ add(songPosBG);
+
+ songPosBar = new FlxBar(songPosBG.x + 4, songPosBG.y + 4, LEFT_TO_RIGHT, Std.int(songPosBG.width - 8), Std.int(songPosBG.height - 8), this,
+ 'songPositionBar', 0, 90000);
+ songPosBar.scrollFactor.set();
+ songPosBar.createFilledBar(FlxColor.GRAY, FlxColor.LIME);
+ add(songPosBar);
+
+ var songName = new FlxText(songPosBG.x + (songPosBG.width / 2) - (SONG.song.length * 5), songPosBG.y, 0, SONG.song, 16);
+ if (PlayStateChangeables.useDownscroll)
+ songName.y -= 3;
+ songName.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK);
+ songName.scrollFactor.set();
+ add(songName);
+ songName.cameras = [camHUD];
+ }
healthBarBG = new FlxSprite(0, FlxG.height * 0.9).loadGraphic(Paths.image('healthBar'));
if (PlayStateChangeables.useDownscroll)
@@ -999,8 +1166,13 @@ class PlayState extends MusicBeatState
add(healthBar);
// Add Kade Engine watermark
- kadeEngineWatermark = new FlxText(4,healthBarBG.y + 50,0,SONG.song + " - " + CoolUtil.difficultyFromInt(storyDifficulty) + (Main.watermarks ? " | KE " + MainMenuState.kadeEngineVer : ""), 16);
- kadeEngineWatermark.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK);
+ kadeEngineWatermark = new FlxText(4, healthBarBG.y
+ + 50, 0,
+ SONG.song
+ + " - "
+ + CoolUtil.difficultyFromInt(storyDifficulty)
+ + (Main.watermarks ? " | KE " + MainMenuState.kadeEngineVer : ""), 16);
+ kadeEngineWatermark.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK);
kadeEngineWatermark.scrollFactor.set();
add(kadeEngineWatermark);
@@ -1013,15 +1185,15 @@ class PlayState extends MusicBeatState
originalX = scoreTxt.x;
-
scoreTxt.scrollFactor.set();
-
- scoreTxt.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, FlxTextAlign.CENTER, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK);
+
+ scoreTxt.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, FlxTextAlign.CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK);
add(scoreTxt);
- replayTxt = new FlxText(healthBarBG.x + healthBarBG.width / 2 - 75, healthBarBG.y + (PlayStateChangeables.useDownscroll ? 100 : -100), 0, "REPLAY", 20);
- replayTxt.setFormat(Paths.font("vcr.ttf"), 42, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK);
+ replayTxt = new FlxText(healthBarBG.x + healthBarBG.width / 2 - 75, healthBarBG.y + (PlayStateChangeables.useDownscroll ? 100 : -100), 0, "REPLAY",
+ 20);
+ replayTxt.setFormat(Paths.font("vcr.ttf"), 42, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK);
replayTxt.borderSize = 4;
replayTxt.borderQuality = 2;
replayTxt.scrollFactor.set();
@@ -1030,12 +1202,14 @@ class PlayState extends MusicBeatState
add(replayTxt);
}
// Literally copy-paste of the above, fu
- botPlayState = new FlxText(healthBarBG.x + healthBarBG.width / 2 - 75, healthBarBG.y + (PlayStateChangeables.useDownscroll ? 100 : -100), 0, "BOTPLAY", 20);
- botPlayState.setFormat(Paths.font("vcr.ttf"), 42, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK);
+ botPlayState = new FlxText(healthBarBG.x + healthBarBG.width / 2 - 75, healthBarBG.y + (PlayStateChangeables.useDownscroll ? 100 : -100), 0,
+ "BOTPLAY", 20);
+ botPlayState.setFormat(Paths.font("vcr.ttf"), 42, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK);
botPlayState.scrollFactor.set();
botPlayState.borderSize = 4;
botPlayState.borderQuality = 2;
- if(PlayStateChangeables.botPlay && !loadRep) add(botPlayState);
+ if (PlayStateChangeables.botPlay && !loadRep)
+ add(botPlayState);
iconP1 = new HealthIcon(SONG.player1, true);
iconP1.y = healthBar.y - (iconP1.height / 2);
@@ -1068,12 +1242,12 @@ class PlayState extends MusicBeatState
// cameras = [FlxG.cameras.list[1]];
startingSong = true;
-
+
trace('starting');
if (isStoryMode)
{
- switch (StringTools.replace(curSong," ", "-").toLowerCase())
+ switch (StringTools.replace(curSong, " ", "-").toLowerCase())
{
case "winter-horrorland":
var blackScreen:FlxSprite = new FlxSprite(0, 0).makeGraphic(Std.int(FlxG.width * 2), Std.int(FlxG.height * 2), FlxColor.BLACK);
@@ -1116,18 +1290,14 @@ class PlayState extends MusicBeatState
}
else
{
- switch (curSong.toLowerCase())
- {
- default:
- startCountdown();
- }
+ startCountdown();
}
if (!loadRep)
rep = new Replay("na");
- FlxG.stage.addEventListener(KeyboardEvent.KEY_DOWN,handleInput);
-
+ FlxG.stage.addEventListener(KeyboardEvent.KEY_DOWN, handleInput);
+ FlxG.stage.addEventListener(KeyboardEvent.KEY_UP, releaseInput);
super.create();
}
@@ -1148,7 +1318,8 @@ class PlayState extends MusicBeatState
senpaiEvil.updateHitbox();
senpaiEvil.screenCenter();
- if (StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase() == 'roses' || StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase() == 'thorns')
+ if (StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase() == 'roses'
+ || StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase() == 'thorns')
{
remove(black);
@@ -1228,21 +1399,53 @@ class PlayState extends MusicBeatState
{
inCutscene = false;
- generateStaticArrows(0);
- generateStaticArrows(1);
+ appearStaticArrows();
+ //generateStaticArrows(0);
+ //generateStaticArrows(1);
+ if (startTime != 0)
+ {
+ var toBeRemoved = [];
+ for(i in 0...unspawnNotes.length)
+ {
+ var dunceNote:Note = unspawnNotes[i];
+
+ if (dunceNote.strumTime - startTime <= 0)
+ toBeRemoved.push(dunceNote);
+ else if (dunceNote.strumTime - startTime < 3500)
+ {
+ notes.add(dunceNote);
+
+ if (dunceNote.mustPress)
+ dunceNote.y = (playerStrums.members[Math.floor(Math.abs(dunceNote.noteData))].y
+ + 0.45 * (startTime - dunceNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed,
+ 2)) - dunceNote.noteYOff;
+ else
+ dunceNote.y = (strumLineNotes.members[Math.floor(Math.abs(dunceNote.noteData))].y
+ + 0.45 * (startTime - dunceNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed,
+ 2)) - dunceNote.noteYOff;
+ toBeRemoved.push(dunceNote);
+ }
+ }
+
+ for(i in toBeRemoved)
+ unspawnNotes.remove(i);
+ }
#if windows
// pre lowercasing the song name (startCountdown)
var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase();
- switch (songLowercase) {
- case 'dad-battle': songLowercase = 'dadbattle';
- case 'philly-nice': songLowercase = 'philly';
+ switch (songLowercase)
+ {
+ case 'dad-battle':
+ songLowercase = 'dadbattle';
+ case 'philly-nice':
+ songLowercase = 'philly';
}
if (executeModchart)
{
luaModchart = ModchartState.createModchartState();
- luaModchart.executeState('start',[songLowercase]);
+ luaModchart.executeState('start', [songLowercase]);
}
#end
@@ -1261,16 +1464,8 @@ class PlayState extends MusicBeatState
var introAssets:Map> = new Map>();
introAssets.set('default', ['ready', "set", "go"]);
- introAssets.set('school', [
- 'weeb/pixelUI/ready-pixel',
- 'weeb/pixelUI/set-pixel',
- 'weeb/pixelUI/date-pixel'
- ]);
- introAssets.set('schoolEvil', [
- 'weeb/pixelUI/ready-pixel',
- 'weeb/pixelUI/set-pixel',
- 'weeb/pixelUI/date-pixel'
- ]);
+ introAssets.set('school', ['weeb/pixelUI/ready-pixel', 'weeb/pixelUI/set-pixel', 'weeb/pixelUI/date-pixel']);
+ introAssets.set('schoolEvil', ['weeb/pixelUI/ready-pixel', 'weeb/pixelUI/set-pixel', 'weeb/pixelUI/date-pixel']);
var introAlts:Array = introAssets.get('default');
var altSuffix:String = "";
@@ -1279,8 +1474,10 @@ class PlayState extends MusicBeatState
{
if (value == curStage)
{
+ trace(value + " - " + curStage);
introAlts = introAssets.get(value);
- altSuffix = '-pixel';
+ if (curStage.contains('school'))
+ altSuffix = '-pixel';
}
}
@@ -1355,7 +1552,6 @@ class PlayState extends MusicBeatState
var lastReportedPlayheadPosition:Int = 0;
var songTime:Float = 0;
-
private function getKey(charCode:Int):String
{
for (key => value in FlxKey.fromStringMap)
@@ -1366,23 +1562,23 @@ class PlayState extends MusicBeatState
return null;
}
- private function handleInput(evt:KeyboardEvent):Void { // this actually handles press inputs
-
- if (PlayStateChangeables.botPlay || loadRep || paused)
- return;
-
- // first convert it from openfl to a flixel key code
- // then use FlxKey to get the key's name based off of the FlxKey dictionary
- // this makes it work for special characters
+ var keys = [false, false, false, false];
+ private function releaseInput(evt:KeyboardEvent):Void // handles releases
+ {
@:privateAccess
var key = FlxKey.toStringMap.get(Keyboard.__convertKeyCode(evt.keyCode));
-
- var binds:Array = [FlxG.save.data.leftBind,FlxG.save.data.downBind, FlxG.save.data.upBind, FlxG.save.data.rightBind];
+
+ var binds:Array = [
+ FlxG.save.data.leftBind,
+ FlxG.save.data.downBind,
+ FlxG.save.data.upBind,
+ FlxG.save.data.rightBind
+ ];
var data = -1;
-
- switch(evt.keyCode) // arrow keys
+
+ switch (evt.keyCode) // arrow keys
{
case 37:
data = 0;
@@ -1400,14 +1596,64 @@ class PlayState extends MusicBeatState
data = i;
}
- if (evt.keyLocation == KeyLocation.NUM_PAD)
- {
- trace(String.fromCharCode(evt.charCode) + " " + key);
- }
-
if (data == -1)
return;
+ keys[data] = false;
+ }
+
+ private function handleInput(evt:KeyboardEvent):Void
+ { // this actually handles press inputs
+
+ if (PlayStateChangeables.botPlay || loadRep || paused)
+ return;
+
+ // first convert it from openfl to a flixel key code
+ // then use FlxKey to get the key's name based off of the FlxKey dictionary
+ // this makes it work for special characters
+
+ @:privateAccess
+ var key = FlxKey.toStringMap.get(Keyboard.__convertKeyCode(evt.keyCode));
+
+ var binds:Array = [
+ FlxG.save.data.leftBind,
+ FlxG.save.data.downBind,
+ FlxG.save.data.upBind,
+ FlxG.save.data.rightBind
+ ];
+
+ var data = -1;
+
+ switch (evt.keyCode) // arrow keys
+ {
+ case 37:
+ data = 0;
+ case 40:
+ data = 1;
+ case 38:
+ data = 2;
+ case 39:
+ data = 3;
+ }
+
+ for (i in 0...binds.length) // binds
+ {
+ if (binds[i].toLowerCase() == key.toLowerCase())
+ data = i;
+ }
+ if (data == -1)
+ {
+ trace("couldn't find a keybind with the code " + key);
+ return;
+ }
+ if (keys[data])
+ {
+ trace("ur already holding " + key);
+ return;
+ }
+
+ keys[data] = true;
+
var ana = new Ana(Conductor.songPosition, null, false, "miss", data);
var dataNotes = [];
@@ -1417,20 +1663,58 @@ class PlayState extends MusicBeatState
dataNotes.push(daNote);
}); // Collect notes that can be hit
-
dataNotes.sort((a, b) -> Std.int(a.strumTime - b.strumTime)); // sort by the earliest note
-
+
if (dataNotes.length != 0)
{
- var coolNote = dataNotes[0];
+ var coolNote = null;
+
+ for (i in dataNotes)
+ if (!i.isSustainNote)
+ {
+ coolNote = i;
+ break;
+ }
+
+ if (coolNote == null) // Note is null, which means it's probably a sustain note. Update will handle this (HOPEFULLY???)
+ {
+ return;
+ }
+
+ if (dataNotes.length > 1) // stacked notes or really close ones
+ {
+ for (i in 0...dataNotes.length)
+ {
+ if (i == 0) // skip the first note
+ continue;
+
+ var note = dataNotes[i];
+
+ if (!note.isSustainNote && (note.strumTime - coolNote.strumTime) < 2)
+ {
+ trace('found a stacked/really close note ' + (note.strumTime - coolNote.strumTime));
+ // just fuckin remove it since it's a stacked note and shouldn't be there
+ note.kill();
+ notes.remove(note, true);
+ note.destroy();
+ }
+ }
+ }
goodNoteHit(coolNote);
var noteDiff:Float = -(coolNote.strumTime - Conductor.songPosition);
ana.hit = true;
ana.hitJudge = Ratings.CalculateRating(noteDiff, Math.floor((PlayStateChangeables.safeFrames / 60) * 1000));
- ana.nearestNote = [coolNote.strumTime,coolNote.noteData,coolNote.sustainLength];
+ ana.nearestNote = [coolNote.strumTime, coolNote.noteData, coolNote.sustainLength];
+ }
+ else if (!FlxG.save.data.ghost && songStarted)
+ {
+ noteMiss(data, null);
+ ana.hit = false;
+ ana.hitJudge = "shit";
+ ana.nearestNote = [];
+ health -= 0.10;
}
-
}
var songStarted = false;
@@ -1444,7 +1728,20 @@ class PlayState extends MusicBeatState
if (!paused)
{
+ #if sys
+ if (!isStoryMode && isSM)
+ {
+ trace("Loading " + pathToSm + "/" + sm.header.MUSIC);
+ var bytes = File.getBytes(pathToSm + "/" + sm.header.MUSIC);
+ var sound = new Sound();
+ sound.loadCompressedDataFromByteArray(bytes.getData(), bytes.length);
+ FlxG.sound.playMusic(sound);
+ }
+ else
+ FlxG.sound.playMusic(Paths.inst(PlayState.SONG.song), 1, false);
+ #else
FlxG.sound.playMusic(Paths.inst(PlayState.SONG.song), 1, false);
+ #end
}
FlxG.sound.music.onComplete = endSong;
@@ -1461,22 +1758,25 @@ class PlayState extends MusicBeatState
songPosBG = new FlxSprite(0, 10).loadGraphic(Paths.image('healthBar'));
if (PlayStateChangeables.useDownscroll)
- songPosBG.y = FlxG.height * 0.9 + 45;
+ songPosBG.y = FlxG.height * 0.9 + 45;
songPosBG.screenCenter(X);
songPosBG.scrollFactor.set();
add(songPosBG);
- songPosBar = new FlxBar(songPosBG.x + 4, songPosBG.y + 4, LEFT_TO_RIGHT, Std.int(songPosBG.width - 8), Std.int(songPosBG.height - 8), this,
- 'songPositionBar', 0, songLength - 1000);
+ songPosBar = new FlxBar(songPosBG.x
+ + 4, songPosBG.y
+ + 4, LEFT_TO_RIGHT, Std.int(songPosBG.width - 8), Std.int(songPosBG.height - 8), this,
+ 'songPositionBar', 0, songLength
+ - 1000);
songPosBar.numDivisions = 1000;
songPosBar.scrollFactor.set();
songPosBar.createFilledBar(FlxColor.GRAY, FlxColor.LIME);
add(songPosBar);
- var songName = new FlxText(songPosBG.x + (songPosBG.width / 2) - (SONG.song.length * 5),songPosBG.y,0,SONG.song, 16);
+ var songName = new FlxText(songPosBG.x + (songPosBG.width / 2) - (SONG.song.length * 5), songPosBG.y, 0, SONG.song, 16);
if (PlayStateChangeables.useDownscroll)
songName.y -= 3;
- songName.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK);
+ songName.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK);
songName.scrollFactor.set();
add(songName);
@@ -1484,26 +1784,49 @@ class PlayState extends MusicBeatState
songPosBar.cameras = [camHUD];
songName.cameras = [camHUD];
}
-
+
// Song check real quick
- switch(curSong)
+ switch (curSong)
{
- case 'Bopeebo' | 'Philly Nice' | 'Blammed' | 'Cocoa' | 'Eggnog': allowedToHeadbang = true;
- default: allowedToHeadbang = false;
+ case 'Bopeebo' | 'Philly Nice' | 'Blammed' | 'Cocoa' | 'Eggnog':
+ allowedToHeadbang = true;
+ default:
+ allowedToHeadbang = false;
}
if (useVideo)
GlobalVideo.get().resume();
-
+
#if windows
// Updating Discord Rich Presence (with Time Left)
- DiscordClient.changePresence(detailsText + " " + SONG.song + " (" + storyDifficultyText + ") " + Ratings.GenerateLetterRank(accuracy), "\nAcc: " + HelperFunctions.truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses , iconRPC);
+ DiscordClient.changePresence(detailsText
+ + " "
+ + SONG.song
+ + " ("
+ + storyDifficultyText
+ + ") "
+ + Ratings.GenerateLetterRank(accuracy),
+ "\nAcc: "
+ + HelperFunctions.truncateFloat(accuracy, 2)
+ + "% | Score: "
+ + songScore
+ + " | Misses: "
+ + misses, iconRPC);
#end
+
+ FlxG.sound.music.time = startTime;
+ vocals.time = startTime;
+ Conductor.songPosition = startTime;
+ startTime = 0;
+
+ for(i in 0...unspawnNotes.length)
+ if (unspawnNotes[i].strumTime < startTime)
+ unspawnNotes.remove(unspawnNotes[i]);
}
var debugNum:Int = 0;
- private function generateSong(dataPath:String):Void
+ public function generateSong(dataPath:String):Void
{
// FlxG.log.add(ChartParser.parse());
@@ -1512,10 +1835,17 @@ class PlayState extends MusicBeatState
curSong = songData.song;
+ #if sys
+ if (SONG.needsVoices && !isSM)
+ vocals = new FlxSound().loadEmbedded(Paths.voices(PlayState.SONG.song));
+ else
+ vocals = new FlxSound();
+ #else
if (SONG.needsVoices)
vocals = new FlxSound().loadEmbedded(Paths.voices(PlayState.SONG.song));
else
vocals = new FlxSound();
+ #end
trace('loaded vocals');
@@ -1533,33 +1863,45 @@ class PlayState extends MusicBeatState
// Per song offset check
#if windows
- // pre lowercasing the song name (generateSong)
- var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase();
- switch (songLowercase) {
- case 'dad-battle': songLowercase = 'dadbattle';
- case 'philly-nice': songLowercase = 'philly';
- }
+ // pre lowercasing the song name (generateSong)
+ var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase();
+ switch (songLowercase)
+ {
+ case 'dad-battle':
+ songLowercase = 'dadbattle';
+ case 'philly-nice':
+ songLowercase = 'philly';
+ }
- var songPath = 'assets/data/' + songLowercase + '/';
-
- for(file in sys.FileSystem.readDirectory(songPath))
+ var songPath = 'assets/data/' + songLowercase + '/';
+
+ #if sys
+ if (isSM && !isStoryMode)
+ songPath = pathToSm;
+ #end
+
+ for (file in sys.FileSystem.readDirectory(songPath))
+ {
+ var path = haxe.io.Path.join([songPath, file]);
+ if (!sys.FileSystem.isDirectory(path))
{
- var path = haxe.io.Path.join([songPath, file]);
- if(!sys.FileSystem.isDirectory(path))
+ if (path.endsWith('.offset'))
{
- if(path.endsWith('.offset'))
- {
- trace('Found offset file: ' + path);
- songOffset = Std.parseFloat(file.substring(0, file.indexOf('.off')));
- break;
- }else {
- trace('Offset file not found. Creating one @: ' + songPath);
- sys.io.File.saveContent(songPath + songOffset + '.offset', '');
- }
+ trace('Found offset file: ' + path);
+ songOffset = Std.parseFloat(file.substring(0, file.indexOf('.off')));
+ break;
+ }
+ else
+ {
+ trace('Offset file not found. Creating one @: ' + songPath);
+ sys.io.File.saveContent(songPath + songOffset + '.offset', '');
}
}
+ }
#end
var daBeats:Int = 0; // Not exactly representative of 'daBeats' lol, just how much it has looped
+
+
for (section in noteData)
{
var coolSection:Int = Std.int(section.lengthInSteps / 4);
@@ -1597,6 +1939,11 @@ class PlayState extends MusicBeatState
susLength = susLength / Conductor.stepCrochet;
unspawnNotes.push(swagNote);
+ if (susLength > 0)
+ swagNote.isParent = true;
+
+ var type = 0;
+
for (susNote in 0...Math.floor(susLength))
{
oldNote = unspawnNotes[Std.int(unspawnNotes.length - 1)];
@@ -1611,6 +1958,11 @@ class PlayState extends MusicBeatState
{
sustainNote.x += FlxG.width / 2; // general offset
}
+
+ sustainNote.parent = swagNote;
+ swagNote.children.push(sustainNote);
+ sustainNote.spotInLine = type;
+ type++;
}
swagNote.mustPress = gottaHitNote;
@@ -1619,9 +1971,6 @@ class PlayState extends MusicBeatState
{
swagNote.x += FlxG.width / 2; // general offset
}
- else
- {
- }
}
daBeats += 1;
}
@@ -1646,15 +1995,24 @@ class PlayState extends MusicBeatState
// FlxG.log.add(i);
var babyArrow:FlxSprite = new FlxSprite(0, strumLine.y);
- //defaults if no noteStyle was found in chart
+ // defaults if no noteStyle was found in chart
var noteTypeCheck:String = 'normal';
-
+
if (PlayStateChangeables.Optimize && player == 0)
continue;
- if (SONG.noteStyle == null) {
- switch(storyWeek) {case 6: noteTypeCheck = 'pixel';}
- } else {noteTypeCheck = SONG.noteStyle;}
+ if (SONG.noteStyle == null)
+ {
+ switch (storyWeek)
+ {
+ case 6:
+ noteTypeCheck = 'pixel';
+ }
+ }
+ else
+ {
+ noteTypeCheck = SONG.noteStyle;
+ }
switch (noteTypeCheck)
{
@@ -1692,83 +2050,37 @@ class PlayState extends MusicBeatState
babyArrow.animation.add('pressed', [4, 8], 12, false);
babyArrow.animation.add('confirm', [12, 16], 24, false);
}
-
- case 'normal':
- babyArrow.frames = Paths.getSparrowAtlas('NOTE_assets');
- babyArrow.animation.addByPrefix('green', 'arrow static instance 1');
- babyArrow.animation.addByPrefix('blue', 'arrow static instance 2');
- babyArrow.animation.addByPrefix('purple', 'arrow static instance 3');
- babyArrow.animation.addByPrefix('red', 'arrow static instance 4');
-
- babyArrow.antialiasing = true;
- babyArrow.setGraphicSize(Std.int(babyArrow.width * 0.7));
-
- switch (Math.abs(i))
- {
- case 0:
- babyArrow.x += Note.swagWidth * 0;
- babyArrow.animation.addByPrefix('static', 'arrow static instance 1');
- babyArrow.animation.addByPrefix('pressed', 'left press instance 1', 24, false);
- babyArrow.animation.addByPrefix('confirm', 'left confirm instance 1', 24, false);
- case 1:
- babyArrow.x += Note.swagWidth * 1;
- babyArrow.animation.addByPrefix('static', 'arrow static instance 2');
- babyArrow.animation.addByPrefix('pressed', 'down press instance 1', 24, false);
- babyArrow.animation.addByPrefix('confirm', 'down confirm instance 1', 24, false);
- case 2:
- babyArrow.x += Note.swagWidth * 2;
- babyArrow.animation.addByPrefix('static', 'arrow static instance 4');
- babyArrow.animation.addByPrefix('pressed', 'up press instance 1', 24, false);
- babyArrow.animation.addByPrefix('confirm', 'up confirm instance 1', 24, false);
- case 3:
- babyArrow.x += Note.swagWidth * 3;
- babyArrow.animation.addByPrefix('static', 'arrow static instance 3');
- babyArrow.animation.addByPrefix('pressed', 'right press instance 1', 24, false);
- babyArrow.animation.addByPrefix('confirm', 'right confirm instance 1', 24, false);
- }
default:
babyArrow.frames = Paths.getSparrowAtlas('NOTE_assets');
- babyArrow.animation.addByPrefix('green', 'arrow static instance 1');
- babyArrow.animation.addByPrefix('blue', 'arrow static instance 2');
- babyArrow.animation.addByPrefix('purple', 'arrow static instance 3');
- babyArrow.animation.addByPrefix('red', 'arrow static instance 4');
-
- babyArrow.antialiasing = true;
- babyArrow.setGraphicSize(Std.int(babyArrow.width * 0.7));
-
- switch (Math.abs(i))
+ for (j in 0...4)
{
- case 0:
- babyArrow.x += Note.swagWidth * 0;
- babyArrow.animation.addByPrefix('static', 'arrow static instance 1');
- babyArrow.animation.addByPrefix('pressed', 'left press instance 1', 24, false);
- babyArrow.animation.addByPrefix('confirm', 'left confirm instance 1', 24, false);
- case 1:
- babyArrow.x += Note.swagWidth * 1;
- babyArrow.animation.addByPrefix('static', 'arrow static instance 2');
- babyArrow.animation.addByPrefix('pressed', 'down press instance 1', 24, false);
- babyArrow.animation.addByPrefix('confirm', 'down confirm instance 1', 24, false);
- case 2:
- babyArrow.x += Note.swagWidth * 2;
- babyArrow.animation.addByPrefix('static', 'arrow static instance 4');
- babyArrow.animation.addByPrefix('pressed', 'up press instance 1', 24, false);
- babyArrow.animation.addByPrefix('confirm', 'up confirm instance 1', 24, false);
- case 3:
- babyArrow.x += Note.swagWidth * 3;
- babyArrow.animation.addByPrefix('static', 'arrow static instance 3');
- babyArrow.animation.addByPrefix('pressed', 'right press instance 1', 24, false);
- babyArrow.animation.addByPrefix('confirm', 'right confirm instance 1', 24, false);
+ babyArrow.animation.addByPrefix(dataColor[j], 'arrow' + dataSuffix[j]);
}
+
+ var lowerDir:String = dataSuffix[i].toLowerCase();
+
+ babyArrow.animation.addByPrefix('static', 'arrow' + dataSuffix[i]);
+ babyArrow.animation.addByPrefix('pressed', lowerDir + ' press', 24, false);
+ babyArrow.animation.addByPrefix('confirm', lowerDir + ' confirm', 24, false);
+
+ babyArrow.x += Note.swagWidth * i;
+
+ if(FlxG.save.data.antialiasing)
+ {
+ babyArrow.antialiasing = true;
+ }
+ babyArrow.setGraphicSize(Std.int(babyArrow.width * 0.7));
}
babyArrow.updateHitbox();
babyArrow.scrollFactor.set();
+ babyArrow.alpha = 0;
if (!isStoryMode)
{
babyArrow.y -= 10;
- babyArrow.alpha = 0;
+ //babyArrow.alpha = 0;
FlxTween.tween(babyArrow, {y: babyArrow.y + 10, alpha: 1}, 1, {ease: FlxEase.circOut, startDelay: 0.5 + (0.2 * i)});
}
@@ -1785,19 +2097,28 @@ class PlayState extends MusicBeatState
babyArrow.animation.play('static');
babyArrow.x += 50;
babyArrow.x += ((FlxG.width / 2) * player);
-
+
if (PlayStateChangeables.Optimize)
babyArrow.x -= 275;
-
+
cpuStrums.forEach(function(spr:FlxSprite)
- {
- spr.centerOffsets(); //CPU arrows start out slightly off-center
+ {
+ spr.centerOffsets(); // CPU arrows start out slightly off-center
});
strumLineNotes.add(babyArrow);
}
}
+ private function appearStaticArrows():Void
+ {
+ strumLineNotes.forEach(function(babyArrow:FlxSprite)
+ {
+ if (isStoryMode)
+ babyArrow.alpha = 1;
+ });
+ }
+
function tweenCamIn():Void
{
FlxTween.tween(FlxG.camera, {zoom: 1.3}, (Conductor.stepCrochet * 4 / 1000), {ease: FlxEase.elasticInOut});
@@ -1814,7 +2135,18 @@ class PlayState extends MusicBeatState
}
#if windows
- DiscordClient.changePresence("PAUSED on " + SONG.song + " (" + storyDifficultyText + ") " + Ratings.GenerateLetterRank(accuracy), "Acc: " + HelperFunctions.truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses , iconRPC);
+ DiscordClient.changePresence("PAUSED on "
+ + SONG.song
+ + " ("
+ + storyDifficultyText
+ + ") "
+ + Ratings.GenerateLetterRank(accuracy),
+ "Acc: "
+ + HelperFunctions.truncateFloat(accuracy, 2)
+ + "% | Score: "
+ + songScore
+ + " | Misses: "
+ + misses, iconRPC);
#end
if (!startTimer.finished)
startTimer.active = false;
@@ -1839,7 +2171,21 @@ class PlayState extends MusicBeatState
#if windows
if (startTimer.finished)
{
- DiscordClient.changePresence(detailsText + " " + SONG.song + " (" + storyDifficultyText + ") " + Ratings.GenerateLetterRank(accuracy), "\nAcc: " + HelperFunctions.truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses, iconRPC, true, songLength - Conductor.songPosition);
+ DiscordClient.changePresence(detailsText
+ + " "
+ + SONG.song
+ + " ("
+ + storyDifficultyText
+ + ") "
+ + Ratings.GenerateLetterRank(accuracy),
+ "\nAcc: "
+ + HelperFunctions.truncateFloat(accuracy, 2)
+ + "% | Score: "
+ + songScore
+ + " | Misses: "
+ + misses, iconRPC, true,
+ songLength
+ - Conductor.songPosition);
}
else
{
@@ -1850,7 +2196,6 @@ class PlayState extends MusicBeatState
super.closeSubState();
}
-
function resyncVocals():Void
{
@@ -1862,7 +2207,19 @@ class PlayState extends MusicBeatState
vocals.play();
#if windows
- DiscordClient.changePresence(detailsText + " " + SONG.song + " (" + storyDifficultyText + ") " + Ratings.GenerateLetterRank(accuracy), "\nAcc: " + HelperFunctions.truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses , iconRPC);
+ DiscordClient.changePresence(detailsText
+ + " "
+ + SONG.song
+ + " ("
+ + storyDifficultyText
+ + ") "
+ + Ratings.GenerateLetterRank(accuracy),
+ "\nAcc: "
+ + HelperFunctions.truncateFloat(accuracy, 2)
+ + "% | Score: "
+ + songScore
+ + " | Misses: "
+ + misses, iconRPC);
#end
}
@@ -1877,35 +2234,97 @@ class PlayState extends MusicBeatState
public var stopUpdate = false;
public var removedVideo = false;
+ public var currentBPM = 0;
+
+ public var updateFrame = 0;
+
override public function update(elapsed:Float)
{
#if !debug
perfectMode = false;
#end
+ if (updateFrame == 4)
+ {
+ TimingStruct.clearTimings();
+
+ var currentIndex = 0;
+ for (i in SONG.eventObjects)
+ {
+ if (i.type == "BPM Change")
+ {
+ var beat:Float = i.position;
+
+ var endBeat:Float = Math.POSITIVE_INFINITY;
+
+ TimingStruct.addTiming(beat,i.value,endBeat, 0); // offset in this case = start time since we don't have a offset
+
+ if (currentIndex != 0)
+ {
+ var data = TimingStruct.AllTimings[currentIndex - 1];
+ data.endBeat = beat;
+ data.length = (data.endBeat - data.startBeat) / (data.bpm / 60);
+ TimingStruct.AllTimings[currentIndex].startTime = data.startTime + data.length;
+ }
+
+ currentIndex++;
+ }
+ }
+ updateFrame++;
+ }
+ else if (updateFrame != 5)
+ updateFrame++;
+
+
+ var timingSeg = TimingStruct.getTimingAtTimestamp(Conductor.songPosition);
+
+ if (timingSeg != null)
+ {
+
+ var timingSegBpm = timingSeg.bpm;
+
+ if (timingSegBpm != Conductor.bpm)
+ {
+ trace("BPM CHANGE to " + timingSegBpm);
+ Conductor.changeBPM(timingSegBpm, false);
+ }
+
+ }
+
+ var newScroll = PlayStateChangeables.scrollSpeed;
+
+ for(i in SONG.eventObjects)
+ {
+ switch(i.type)
+ {
+ case "Scroll Speed Change":
+ if (i.position < curDecimalBeat)
+ newScroll = i.value;
+ }
+ }
+
+ PlayStateChangeables.scrollSpeed = newScroll;
+
if (PlayStateChangeables.botPlay && FlxG.keys.justPressed.ONE)
camHUD.visible = !camHUD.visible;
-
if (useVideo && GlobalVideo.get() != null && !stopUpdate)
- {
- if (GlobalVideo.get().ended && !removedVideo)
- {
- remove(videoSprite);
- FlxG.stage.window.onFocusOut.remove(focusOut);
- FlxG.stage.window.onFocusIn.remove(focusIn);
- removedVideo = true;
- }
+ {
+ if (GlobalVideo.get().ended && !removedVideo)
+ {
+ remove(videoSprite);
+ FlxG.stage.window.onFocusOut.remove(focusOut);
+ FlxG.stage.window.onFocusIn.remove(focusIn);
+ removedVideo = true;
}
+ }
-
-
#if windows
if (executeModchart && luaModchart != null && songStarted)
{
- luaModchart.setVar('songPos',Conductor.songPosition);
+ luaModchart.setVar('songPos', Conductor.songPosition);
luaModchart.setVar('hudZoom', camHUD.zoom);
- luaModchart.setVar('cameraZoom',FlxG.camera.zoom);
+ luaModchart.setVar('cameraZoom', FlxG.camera.zoom);
luaModchart.executeState('update', [elapsed]);
for (i in luaWiggles)
@@ -1922,9 +2341,9 @@ class PlayState extends MusicBeatState
}*/
FlxG.camera.angle = luaModchart.getVar('cameraAngle', 'float');
- camHUD.angle = luaModchart.getVar('camHudAngle','float');
+ camHUD.angle = luaModchart.getVar('camHudAngle', 'float');
- if (luaModchart.getVar("showOnlyStrums",'bool'))
+ if (luaModchart.getVar("showOnlyStrums", 'bool'))
{
healthBarBG.visible = false;
kadeEngineWatermark.visible = false;
@@ -1943,8 +2362,8 @@ class PlayState extends MusicBeatState
scoreTxt.visible = true;
}
- var p1 = luaModchart.getVar("strumLine1Visible",'bool');
- var p2 = luaModchart.getVar("strumLine2Visible",'bool');
+ var p1 = luaModchart.getVar("strumLine1Visible", 'bool');
+ var p2 = luaModchart.getVar("strumLine2Visible", 'bool');
for (i in 0...4)
{
@@ -1953,14 +2372,13 @@ class PlayState extends MusicBeatState
playerStrums.members[i].visible = p2;
}
}
-
#end
// reverse iterate to remove oldest notes first and not invalidate the iteration
// stop iteration as soon as a note is not removed
// all notes should be kept in the correct order and this is optimal, safe to do every frame/update
{
- var balls = notesHitArray.length-1;
+ var balls = notesHitArray.length - 1;
while (balls >= 0)
{
var cock:Date = notesHitArray[balls];
@@ -2001,7 +2419,7 @@ class PlayState extends MusicBeatState
super.update(elapsed);
- scoreTxt.text = Ratings.CalculateRanking(songScore,songScoreDef,nps,maxNPS,accuracy);
+ scoreTxt.text = Ratings.CalculateRanking(songScore, songScoreDef, nps, maxNPS, accuracy);
var lengthInPx = scoreTxt.textField.length * scoreTxt.frameHeight; // bad way but does more or less a better job
@@ -2023,22 +2441,25 @@ class PlayState extends MusicBeatState
openSubState(new PauseSubState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y));
}
-
if (FlxG.keys.justPressed.SEVEN)
{
if (useVideo)
- {
- GlobalVideo.get().stop();
- remove(videoSprite);
- FlxG.stage.window.onFocusOut.remove(focusOut);
- FlxG.stage.window.onFocusIn.remove(focusIn);
- removedVideo = true;
- }
+ {
+ GlobalVideo.get().stop();
+ remove(videoSprite);
+ #if sys
+ FlxG.stage.window.onFocusOut.remove(focusOut);
+ FlxG.stage.window.onFocusIn.remove(focusIn);
+ #end
+ removedVideo = true;
+ }
+ cannotDie = true;
#if windows
DiscordClient.changePresence("Chart Editor", null, null, true);
#end
FlxG.switchState(new ChartingState());
- FlxG.stage.removeEventListener(KeyboardEvent.KEY_DOWN,handleInput);
+ FlxG.stage.removeEventListener(KeyboardEvent.KEY_DOWN, handleInput);
+ FlxG.stage.removeEventListener(KeyboardEvent.KEY_UP, releaseInput);
#if windows
if (luaModchart != null)
{
@@ -2081,16 +2502,17 @@ class PlayState extends MusicBeatState
if (FlxG.keys.justPressed.SIX)
{
if (useVideo)
- {
- GlobalVideo.get().stop();
- remove(videoSprite);
- FlxG.stage.window.onFocusOut.remove(focusOut);
- FlxG.stage.window.onFocusIn.remove(focusIn);
- removedVideo = true;
- }
+ {
+ GlobalVideo.get().stop();
+ remove(videoSprite);
+ FlxG.stage.window.onFocusOut.remove(focusOut);
+ FlxG.stage.window.onFocusIn.remove(focusIn);
+ removedVideo = true;
+ }
FlxG.switchState(new AnimationDebug(SONG.player2));
- FlxG.stage.removeEventListener(KeyboardEvent.KEY_DOWN,handleInput);
+ FlxG.stage.removeEventListener(KeyboardEvent.KEY_DOWN, handleInput);
+ FlxG.stage.removeEventListener(KeyboardEvent.KEY_UP, releaseInput);
#if windows
if (luaModchart != null)
{
@@ -2103,7 +2525,8 @@ class PlayState extends MusicBeatState
if (FlxG.keys.justPressed.ZERO)
{
FlxG.switchState(new AnimationDebug(SONG.player1));
- FlxG.stage.removeEventListener(KeyboardEvent.KEY_DOWN,handleInput);
+ FlxG.stage.removeEventListener(KeyboardEvent.KEY_DOWN, handleInput);
+ FlxG.stage.removeEventListener(KeyboardEvent.KEY_UP, releaseInput);
#if windows
if (luaModchart != null)
{
@@ -2112,7 +2535,45 @@ class PlayState extends MusicBeatState
}
#end
}
+
+ if(FlxG.keys.justPressed.TWO) { //Go 10 seconds into the future, credit: Shadow Mario#9396
+ if (!usedTimeTravel && Conductor.songPosition + 10000 < FlxG.sound.music.length)
+ {
+ usedTimeTravel = true;
+ FlxG.sound.music.pause();
+ vocals.pause();
+ Conductor.songPosition += 10000;
+ notes.forEachAlive(function(daNote:Note)
+ {
+ if(daNote.strumTime - 500 < Conductor.songPosition) {
+ daNote.active = false;
+ daNote.visible = false;
+
+ daNote.kill();
+ notes.remove(daNote, true);
+ daNote.destroy();
+ }
+ });
+ for (i in 0...unspawnNotes.length) {
+ var daNote:Note = unspawnNotes[0];
+ if(daNote.strumTime - 500 >= Conductor.songPosition) {
+ break;
+ }
+ unspawnNotes.splice(unspawnNotes.indexOf(daNote), 1);
+ }
+
+ FlxG.sound.music.time = Conductor.songPosition;
+ FlxG.sound.music.play();
+
+ vocals.time = Conductor.songPosition;
+ vocals.play();
+ new FlxTimer().start(0.5, function(tmr:FlxTimer)
+ {
+ usedTimeTravel = false;
+ });
+ }
+ }
#end
if (startingSong)
@@ -2129,8 +2590,8 @@ class PlayState extends MusicBeatState
// Conductor.songPosition = FlxG.sound.music.time;
Conductor.songPosition += FlxG.elapsed * 1000;
/*@:privateAccess
- {
- FlxG.sound.music._channel.
+ {
+ FlxG.sound.music._channel.
}*/
songPositionBar = Conductor.songPosition;
@@ -2155,104 +2616,116 @@ class PlayState extends MusicBeatState
if (generatedMusic && PlayState.SONG.notes[Std.int(curStep / 16)] != null)
{
// Make sure Girlfriend cheers only for certain songs
- if(allowedToHeadbang)
+ if (allowedToHeadbang)
{
// Don't animate GF if something else is already animating her (eg. train passing)
- if(gf.animation.curAnim.name == 'danceLeft' || gf.animation.curAnim.name == 'danceRight' || gf.animation.curAnim.name == 'idle')
+ if (gf.animation.curAnim.name == 'danceLeft'
+ || gf.animation.curAnim.name == 'danceRight'
+ || gf.animation.curAnim.name == 'idle')
{
// Per song treatment since some songs will only have the 'Hey' at certain times
- switch(curSong)
+ switch (curSong)
{
case 'Philly Nice':
- {
- // General duration of the song
- if(curBeat < 250)
{
- // Beats to skip or to stop GF from cheering
- if(curBeat != 184 && curBeat != 216)
+ // General duration of the song
+ if (curBeat < 250)
{
- if(curBeat % 16 == 8)
+ // Beats to skip or to stop GF from cheering
+ if (curBeat != 184 && curBeat != 216)
{
- // Just a garantee that it'll trigger just once
- if(!triggeredAlready)
+ if (curBeat % 16 == 8)
{
- gf.playAnim('cheer');
- triggeredAlready = true;
+ // Just a garantee that it'll trigger just once
+ if (!triggeredAlready)
+ {
+ gf.playAnim('cheer');
+ triggeredAlready = true;
+ }
}
- }else triggeredAlready = false;
+ else
+ triggeredAlready = false;
+ }
}
}
- }
case 'Bopeebo':
- {
- // Where it starts || where it ends
- if(curBeat > 5 && curBeat < 130)
{
- if(curBeat % 8 == 7)
+ // Where it starts || where it ends
+ if (curBeat > 5 && curBeat < 130)
{
- if(!triggeredAlready)
+ if (curBeat % 8 == 7)
{
- gf.playAnim('cheer');
- triggeredAlready = true;
+ if (!triggeredAlready)
+ {
+ gf.playAnim('cheer');
+ triggeredAlready = true;
+ }
}
- }else triggeredAlready = false;
+ else
+ triggeredAlready = false;
+ }
}
- }
case 'Blammed':
- {
- if(curBeat > 30 && curBeat < 190)
{
- if(curBeat < 90 || curBeat > 128)
+ if (curBeat > 30 && curBeat < 190)
{
- if(curBeat % 4 == 2)
+ if (curBeat < 90 || curBeat > 128)
{
- if(!triggeredAlready)
+ if (curBeat % 4 == 2)
{
- gf.playAnim('cheer');
- triggeredAlready = true;
+ if (!triggeredAlready)
+ {
+ gf.playAnim('cheer');
+ triggeredAlready = true;
+ }
}
- }else triggeredAlready = false;
- }
- }
- }
- case 'Cocoa':
- {
- if(curBeat < 170)
- {
- if(curBeat < 65 || curBeat > 130 && curBeat < 145)
- {
- if(curBeat % 16 == 15)
- {
- if(!triggeredAlready)
- {
- gf.playAnim('cheer');
- triggeredAlready = true;
- }
- }else triggeredAlready = false;
- }
- }
- }
- case 'Eggnog':
- {
- if(curBeat > 10 && curBeat != 111 && curBeat < 220)
- {
- if(curBeat % 8 == 7)
- {
- if(!triggeredAlready)
- {
- gf.playAnim('cheer');
- triggeredAlready = true;
+ else
+ triggeredAlready = false;
}
- }else triggeredAlready = false;
+ }
+ }
+ case 'Cocoa':
+ {
+ if (curBeat < 170)
+ {
+ if (curBeat < 65 || curBeat > 130 && curBeat < 145)
+ {
+ if (curBeat % 16 == 15)
+ {
+ if (!triggeredAlready)
+ {
+ gf.playAnim('cheer');
+ triggeredAlready = true;
+ }
+ }
+ else
+ triggeredAlready = false;
+ }
+ }
+ }
+ case 'Eggnog':
+ {
+ if (curBeat > 10 && curBeat != 111 && curBeat < 220)
+ {
+ if (curBeat % 8 == 7)
+ {
+ if (!triggeredAlready)
+ {
+ gf.playAnim('cheer');
+ triggeredAlready = true;
+ }
+ }
+ else
+ triggeredAlready = false;
+ }
}
- }
}
}
}
-
+
#if windows
if (luaModchart != null)
- luaModchart.setVar("mustHit",PlayState.SONG.notes[Std.int(curStep / 16)].mustHitSection);
+ luaModchart.setVar("mustHit", PlayState.SONG.notes[Std.int(curStep / 16)].mustHitSection);
#end
if (camFollow.x != dad.getMidpoint().x + 150 && !PlayState.SONG.notes[Std.int(curStep / 16)].mustHitSection)
@@ -2275,18 +2748,12 @@ class PlayState extends MusicBeatState
switch (dad.curCharacter)
{
- case 'mom':
+ case 'mom' | 'mom-car':
camFollow.y = dad.getMidpoint().y;
- case 'senpai':
- camFollow.y = dad.getMidpoint().y - 430;
- camFollow.x = dad.getMidpoint().x - 100;
- case 'senpai-angry':
+ case 'senpai' | 'senpai-angry':
camFollow.y = dad.getMidpoint().y - 430;
camFollow.x = dad.getMidpoint().x - 100;
}
-
- if (dad.curCharacter == 'mom')
- vocals.volume = 1;
}
if (PlayState.SONG.notes[Std.int(curStep / 16)].mustHitSection && camFollow.x != boyfriend.getMidpoint().x - 100)
@@ -2329,6 +2796,9 @@ class PlayState extends MusicBeatState
camHUD.zoom = FlxMath.lerp(1, camHUD.zoom, 0.95);
}
+ FlxG.watch.addQuick("curBPM", Conductor.bpm);
+ FlxG.watch.addQuick("Closest Note", (unspawnNotes.length != 0 ? unspawnNotes[0].strumTime - Conductor.songPosition : "No note"));
+
FlxG.watch.addQuick("beatShit", curBeat);
FlxG.watch.addQuick("stepShit", curStep);
@@ -2362,48 +2832,75 @@ class PlayState extends MusicBeatState
}
}
- if (health <= 0)
+ if (health <= 0 && !cannotDie)
{
- boyfriend.stunned = true;
+ if (!usedTimeTravel)
+ {
+ boyfriend.stunned = true;
- persistentUpdate = false;
- persistentDraw = false;
- paused = true;
+ persistentUpdate = false;
+ persistentDraw = false;
+ paused = true;
- vocals.stop();
- FlxG.sound.music.stop();
+ vocals.stop();
+ FlxG.sound.music.stop();
- openSubState(new GameOverSubstate(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y));
+ openSubState(new GameOverSubstate(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y));
- #if windows
- // Game Over doesn't get his own variable because it's only used here
- DiscordClient.changePresence("GAME OVER -- " + SONG.song + " (" + storyDifficultyText + ") " + Ratings.GenerateLetterRank(accuracy),"\nAcc: " + HelperFunctions.truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses , iconRPC);
- #end
+ #if windows
+ // Game Over doesn't get his own variable because it's only used here
+ DiscordClient.changePresence("GAME OVER -- "
+ + SONG.song
+ + " ("
+ + storyDifficultyText
+ + ") "
+ + Ratings.GenerateLetterRank(accuracy),
+ "\nAcc: "
+ + HelperFunctions.truncateFloat(accuracy, 2)
+ + "% | Score: "
+ + songScore
+ + " | Misses: "
+ + misses, iconRPC);
+ #end
- // FlxG.switchState(new GameOverState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y));
+ // FlxG.switchState(new GameOverState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y));
+ }
+ else
+ health = 1;
}
- if (FlxG.save.data.resetButton)
+ if (!inCutscene && FlxG.save.data.resetButton)
{
- if(FlxG.keys.justPressed.R)
- {
- boyfriend.stunned = true;
+ if (FlxG.keys.justPressed.R)
+ {
+ boyfriend.stunned = true;
- persistentUpdate = false;
- persistentDraw = false;
- paused = true;
-
- vocals.stop();
- FlxG.sound.music.stop();
-
- openSubState(new GameOverSubstate(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y));
-
- #if windows
- // Game Over doesn't get his own variable because it's only used here
- DiscordClient.changePresence("GAME OVER -- " + SONG.song + " (" + storyDifficultyText + ") " + Ratings.GenerateLetterRank(accuracy),"\nAcc: " + HelperFunctions.truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses , iconRPC);
- #end
-
- // FlxG.switchState(new GameOverState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y));
- }
+ persistentUpdate = false;
+ persistentDraw = false;
+ paused = true;
+
+ vocals.stop();
+ FlxG.sound.music.stop();
+
+ openSubState(new GameOverSubstate(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y));
+
+ #if windows
+ // Game Over doesn't get his own variable because it's only used here
+ DiscordClient.changePresence("GAME OVER -- "
+ + SONG.song
+ + " ("
+ + storyDifficultyText
+ + ") "
+ + Ratings.GenerateLetterRank(accuracy),
+ "\nAcc: "
+ + HelperFunctions.truncateFloat(accuracy, 2)
+ + "% | Score: "
+ + songScore
+ + " | Misses: "
+ + misses, iconRPC);
+ #end
+
+ // FlxG.switchState(new GameOverState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y));
+ }
}
if (unspawnNotes[0] != null)
@@ -2419,219 +2916,302 @@ class PlayState extends MusicBeatState
}
if (generatedMusic)
+ {
+ var holdArray:Array = [controls.LEFT, controls.DOWN, controls.UP, controls.RIGHT];
+
+ notes.forEachAlive(function(daNote:Note)
{
- notes.forEachAlive(function(daNote:Note)
- {
+ // instead of doing stupid y > FlxG.height
+ // we be men and actually calculate the time :)
+ if (daNote.tooLate)
+ {
+ daNote.active = false;
+ daNote.visible = false;
+ }
+ else
+ {
+ daNote.visible = true;
+ daNote.active = true;
+ }
- // instead of doing stupid y > FlxG.height
- // we be men and actually calculate the time :)
- if (daNote.tooLate)
+ if (!daNote.modifiedByLua)
+ {
+ if (PlayStateChangeables.useDownscroll)
{
- daNote.active = false;
- daNote.visible = false;
- }
- else
- {
- daNote.visible = true;
- daNote.active = true;
- }
-
- if (!daNote.modifiedByLua)
+ if (daNote.mustPress)
+ daNote.y = (playerStrums.members[Math.floor(Math.abs(daNote.noteData))].y
+ + 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed,
+ 2)) - daNote.noteYOff;
+ else
+ daNote.y = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y
+ + 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed,
+ 2)) - daNote.noteYOff;
+ if (daNote.isSustainNote)
{
- if (PlayStateChangeables.useDownscroll)
+ // Remember = minus makes notes go up, plus makes them go down
+ if (daNote.animation.curAnim.name.endsWith('end') && daNote.prevNote != null)
+ daNote.y += daNote.prevNote.height;
+ else
+ daNote.y += daNote.height / 2;
+
+ // If not in botplay, only clip sustain notes when properly hit, botplay gets to clip it everytime
+ if (!PlayStateChangeables.botPlay)
{
- if (daNote.mustPress)
- daNote.y = (playerStrums.members[Math.floor(Math.abs(daNote.noteData))].y + 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed, 2));
- else
- daNote.y = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y + 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed, 2));
- if(daNote.isSustainNote)
+ if ((!daNote.mustPress || daNote.wasGoodHit || daNote.prevNote.wasGoodHit && !daNote.canBeHit)
+ && daNote.y - daNote.offset.y * daNote.scale.y + daNote.height >= (strumLine.y + Note.swagWidth / 2))
{
- // Remember = minus makes notes go up, plus makes them go down
- if(daNote.animation.curAnim.name.endsWith('end') && daNote.prevNote != null)
- daNote.y += daNote.prevNote.height;
- else
- daNote.y += daNote.height / 2;
-
- // If not in botplay, only clip sustain notes when properly hit, botplay gets to clip it everytime
- if(!PlayStateChangeables.botPlay)
- {
- if((!daNote.mustPress || daNote.wasGoodHit || daNote.prevNote.wasGoodHit && !daNote.canBeHit) && daNote.y - daNote.offset.y * daNote.scale.y + daNote.height >= (strumLine.y + Note.swagWidth / 2))
- {
- // Clip to strumline
- var swagRect = new FlxRect(0, 0, daNote.frameWidth * 2, daNote.frameHeight * 2);
- swagRect.height = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y + Note.swagWidth / 2 - daNote.y) / daNote.scale.y;
- swagRect.y = daNote.frameHeight - swagRect.height;
-
- daNote.clipRect = swagRect;
- }
- }else {
- var swagRect = new FlxRect(0, 0, daNote.frameWidth * 2, daNote.frameHeight * 2);
- swagRect.height = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y + Note.swagWidth / 2 - daNote.y) / daNote.scale.y;
- swagRect.y = daNote.frameHeight - swagRect.height;
-
- daNote.clipRect = swagRect;
- }
+ // Clip to strumline
+ var swagRect = new FlxRect(0, 0, daNote.frameWidth * 2, daNote.frameHeight * 2);
+ swagRect.height = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y
+ + Note.swagWidth / 2
+ - daNote.y) / daNote.scale.y;
+ swagRect.y = daNote.frameHeight - swagRect.height;
+
+ daNote.clipRect = swagRect;
}
- }else
- {
- if (daNote.mustPress)
- daNote.y = (playerStrums.members[Math.floor(Math.abs(daNote.noteData))].y - 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed, 2));
- else
- daNote.y = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y - 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed, 2));
- if(daNote.isSustainNote)
- {
- daNote.y -= daNote.height / 2;
-
- if(!PlayStateChangeables.botPlay)
- {
- if((!daNote.mustPress || daNote.wasGoodHit || daNote.prevNote.wasGoodHit && !daNote.canBeHit) && daNote.y + daNote.offset.y * daNote.scale.y <= (strumLine.y + Note.swagWidth / 2))
- {
- // Clip to strumline
- var swagRect = new FlxRect(0, 0, daNote.width / daNote.scale.x, daNote.height / daNote.scale.y);
- swagRect.y = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y + Note.swagWidth / 2 - daNote.y) / daNote.scale.y;
- swagRect.height -= swagRect.y;
-
- daNote.clipRect = swagRect;
- }
- }else {
- var swagRect = new FlxRect(0, 0, daNote.width / daNote.scale.x, daNote.height / daNote.scale.y);
- swagRect.y = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y + Note.swagWidth / 2 - daNote.y) / daNote.scale.y;
- swagRect.height -= swagRect.y;
-
- daNote.clipRect = swagRect;
- }
- }
- }
- }
-
-
- if (!daNote.mustPress && daNote.wasGoodHit)
- {
- if (SONG.song != 'Tutorial')
- camZooming = true;
-
- var altAnim:String = "";
-
- if (SONG.notes[Math.floor(curStep / 16)] != null)
- {
- if (SONG.notes[Math.floor(curStep / 16)].altAnim)
- altAnim = '-alt';
- }
-
- switch (Math.abs(daNote.noteData))
- {
- case 2:
- dad.playAnim('singUP' + altAnim, true);
- case 3:
- dad.playAnim('singRIGHT' + altAnim, true);
- case 1:
- dad.playAnim('singDOWN' + altAnim, true);
- case 0:
- dad.playAnim('singLEFT' + altAnim, true);
- }
-
- if (FlxG.save.data.cpuStrums)
- {
- cpuStrums.forEach(function(spr:FlxSprite)
- {
- if (Math.abs(daNote.noteData) == spr.ID)
- {
- spr.animation.play('confirm', true);
- }
- if (spr.animation.curAnim.name == 'confirm' && !curStage.startsWith('school'))
- {
- spr.centerOffsets();
- spr.offset.x -= 13;
- spr.offset.y -= 13;
- }
- else
- spr.centerOffsets();
- });
- }
-
- #if windows
- if (luaModchart != null)
- luaModchart.executeState('playerTwoSing', [Math.abs(daNote.noteData), Conductor.songPosition]);
- #end
-
- dad.holdTimer = 0;
-
- if (SONG.needsVoices)
- vocals.volume = 1;
-
- daNote.active = false;
-
-
- daNote.kill();
- notes.remove(daNote, true);
- daNote.destroy();
- }
-
- if (daNote.mustPress && !daNote.modifiedByLua)
- {
- daNote.visible = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].visible;
- daNote.x = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].x;
- if (!daNote.isSustainNote)
- daNote.angle = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].angle;
- daNote.alpha = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].alpha;
- }
- else if (!daNote.wasGoodHit && !daNote.modifiedByLua)
- {
- daNote.visible = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].visible;
- daNote.x = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].x;
- if (!daNote.isSustainNote)
- daNote.angle = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].angle;
- daNote.alpha = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].alpha;
- }
-
-
-
- if (daNote.isSustainNote)
- daNote.x += daNote.width / 2 + 17;
-
-
- //trace(daNote.y);
- // WIP interpolation shit? Need to fix the pause issue
- // daNote.y = (strumLine.y - (songTime - daNote.strumTime) * (0.45 * PlayState.SONG.speed));
-
- if ((daNote.mustPress && daNote.tooLate && !PlayStateChangeables.useDownscroll || daNote.mustPress && daNote.tooLate && PlayStateChangeables.useDownscroll) && daNote.mustPress)
- {
- if (daNote.isSustainNote && daNote.wasGoodHit)
- {
- daNote.kill();
- notes.remove(daNote, true);
}
else
{
- if (loadRep && daNote.isSustainNote)
+ var swagRect = new FlxRect(0, 0, daNote.frameWidth * 2, daNote.frameHeight * 2);
+ swagRect.height = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y
+ + Note.swagWidth / 2
+ - daNote.y) / daNote.scale.y;
+ swagRect.y = daNote.frameHeight - swagRect.height;
+
+ daNote.clipRect = swagRect;
+ }
+ }
+ }
+ else
+ {
+ if (daNote.mustPress)
+ daNote.y = (playerStrums.members[Math.floor(Math.abs(daNote.noteData))].y
+ - 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed,
+ 2)) + daNote.noteYOff;
+ else
+ daNote.y = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y
+ - 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed,
+ 2)) + daNote.noteYOff;
+ if (daNote.isSustainNote)
+ {
+ daNote.y -= daNote.height / 2;
+
+ if (!PlayStateChangeables.botPlay)
+ {
+ if ((!daNote.mustPress || daNote.wasGoodHit || daNote.prevNote.wasGoodHit && !daNote.canBeHit)
+ && daNote.y + daNote.offset.y * daNote.scale.y <= (strumLine.y + Note.swagWidth / 2))
{
- // im tired and lazy this sucks I know i'm dumb
- if (findByTime(daNote.strumTime) != null)
- totalNotesHit += 1;
+ // Clip to strumline
+ var swagRect = new FlxRect(0, 0, daNote.width / daNote.scale.x, daNote.height / daNote.scale.y);
+ swagRect.y = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y
+ + Note.swagWidth / 2
+ - daNote.y) / daNote.scale.y;
+ swagRect.height -= swagRect.y;
+
+ daNote.clipRect = swagRect;
+ }
+ }
+ else
+ {
+ var swagRect = new FlxRect(0, 0, daNote.width / daNote.scale.x, daNote.height / daNote.scale.y);
+ swagRect.y = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y
+ + Note.swagWidth / 2
+ - daNote.y) / daNote.scale.y;
+ swagRect.height -= swagRect.y;
+
+ daNote.clipRect = swagRect;
+ }
+ }
+ }
+ }
+
+ if (!daNote.mustPress && daNote.wasGoodHit)
+ {
+ if (SONG.song != 'Tutorial')
+ camZooming = true;
+
+ var altAnim:String = "";
+
+ if (SONG.notes[Math.floor(curStep / 16)] != null)
+ {
+ if (SONG.notes[Math.floor(curStep / 16)].altAnim)
+ altAnim = '-alt';
+ }
+
+ // Accessing the animation name directly to play it
+ var singData:Int = Std.int(Math.abs(daNote.noteData));
+ dad.playAnim('sing' + dataSuffix[singData] + altAnim, true);
+
+ if (FlxG.save.data.cpuStrums)
+ {
+ cpuStrums.forEach(function(spr:FlxSprite)
+ {
+ if (Math.abs(daNote.noteData) == spr.ID)
+ {
+ spr.animation.play('confirm', true);
+ }
+ if (spr.animation.curAnim.name == 'confirm' && !curStage.startsWith('school'))
+ {
+ spr.centerOffsets();
+ spr.offset.x -= 13;
+ spr.offset.y -= 13;
+ }
+ else
+ spr.centerOffsets();
+ });
+ }
+
+ #if windows
+ if (luaModchart != null)
+ luaModchart.executeState('playerTwoSing', [Math.abs(daNote.noteData), Conductor.songPosition]);
+ #end
+
+ dad.holdTimer = 0;
+
+ if (SONG.needsVoices)
+ vocals.volume = 1;
+
+ daNote.active = false;
+
+ daNote.kill();
+ notes.remove(daNote, true);
+ daNote.destroy();
+ }
+
+ if (daNote.mustPress && !daNote.modifiedByLua)
+ {
+ daNote.visible = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].visible;
+ daNote.x = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].x;
+ if (!daNote.isSustainNote)
+ daNote.modAngle = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].angle;
+ if (daNote.sustainActive)
+ daNote.alpha = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].alpha;
+ daNote.modAngle = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].angle;
+ }
+ else if (!daNote.wasGoodHit && !daNote.modifiedByLua)
+ {
+ daNote.visible = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].visible;
+ daNote.x = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].x;
+ if (!daNote.isSustainNote)
+ daNote.modAngle = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].angle;
+ if (daNote.sustainActive)
+ daNote.alpha = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].alpha;
+ daNote.modAngle = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].angle;
+ }
+
+ if (daNote.isSustainNote)
+ {
+ daNote.x += daNote.width / 2 + 20;
+ if (PlayState.curStage.startsWith('school'))
+ daNote.x -= 11;
+ }
+
+ // trace(daNote.y);
+ // WIP interpolation shit? Need to fix the pause issue
+ // daNote.y = (strumLine.y - (songTime - daNote.strumTime) * (0.45 * PlayState.SONG.speed));
+
+ if ((daNote.mustPress && daNote.tooLate && !PlayStateChangeables.useDownscroll || daNote.mustPress && daNote.tooLate
+ && PlayStateChangeables.useDownscroll)
+ && daNote.mustPress)
+ {
+ if (daNote.isSustainNote && daNote.wasGoodHit)
+ {
+ daNote.kill();
+ notes.remove(daNote, true);
+ }
+ else
+ {
+ if (loadRep && daNote.isSustainNote)
+ {
+ // im tired and lazy this sucks I know i'm dumb
+ if (findByTime(daNote.strumTime) != null)
+ totalNotesHit += 1;
+ else
+ {
+ if (!daNote.isSustainNote)
+ health -= 0.10;
+ vocals.volume = 0;
+ if (theFunne && !daNote.isSustainNote)
+ noteMiss(daNote.noteData, daNote);
+ if (daNote.isParent)
+ {
+ health -= 0.20; // give a health punishment for failing a LN
+ trace("hold fell over at the start");
+ for (i in daNote.children)
+ {
+ i.alpha = 0.3;
+ i.sustainActive = false;
+ }
+ }
else
{
- health -= 0.075;
- vocals.volume = 0;
- if (theFunne)
- noteMiss(daNote.noteData, daNote);
+ if (!daNote.wasGoodHit
+ && daNote.isSustainNote
+ && daNote.sustainActive
+ && daNote.spotInLine != daNote.parent.children.length)
+ {
+ health -= 0.20; // give a health punishment for failing a LN
+ trace("hold fell over at " + daNote.spotInLine);
+ for (i in daNote.parent.children)
+ {
+ i.alpha = 0.3;
+ i.sustainActive = false;
+ }
+ if (daNote.parent.wasGoodHit)
+ misses++;
+ updateAccuracy();
+ }
+ }
+ }
+ }
+ else
+ {
+ if (!daNote.isSustainNote)
+ health -= 0.10;
+ vocals.volume = 0;
+ if (theFunne && !daNote.isSustainNote)
+ noteMiss(daNote.noteData, daNote);
+
+ if (daNote.isParent)
+ {
+ health -= 0.20; // give a health punishment for failing a LN
+ trace("hold fell over at the start");
+ for (i in daNote.children)
+ {
+ i.alpha = 0.3;
+ i.sustainActive = false;
+ trace(i.alpha);
}
}
else
{
- health -= 0.075;
- vocals.volume = 0;
- if (theFunne)
- noteMiss(daNote.noteData, daNote);
+ if (!daNote.wasGoodHit
+ && daNote.isSustainNote
+ && daNote.sustainActive
+ && daNote.spotInLine != daNote.parent.children.length)
+ {
+ health -= 0.20; // give a health punishment for failing a LN
+ trace("hold fell over at " + daNote.spotInLine);
+ for (i in daNote.parent.children)
+ {
+ i.alpha = 0.3;
+ i.sustainActive = false;
+ trace(i.alpha);
+ }
+ if (daNote.parent.wasGoodHit)
+ misses++;
+ updateAccuracy();
+ }
}
}
-
- daNote.visible = false;
- daNote.kill();
- notes.remove(daNote, true);
}
-
- });
- }
+
+ daNote.visible = false;
+ daNote.kill();
+ notes.remove(daNote, true);
+ }
+ });
+ }
if (FlxG.save.data.cpuStrums)
{
@@ -2645,10 +3225,9 @@ class PlayState extends MusicBeatState
});
}
- if (!inCutscene)
+ if (!inCutscene && songStarted)
keyShit();
-
#if debug
if (FlxG.keys.justPressed.ONE)
endSong();
@@ -2657,14 +3236,15 @@ class PlayState extends MusicBeatState
function endSong():Void
{
- FlxG.stage.removeEventListener(KeyboardEvent.KEY_DOWN,handleInput);
+ FlxG.stage.removeEventListener(KeyboardEvent.KEY_DOWN, handleInput);
+ FlxG.stage.removeEventListener(KeyboardEvent.KEY_UP, releaseInput);
if (useVideo)
- {
- GlobalVideo.get().stop();
- FlxG.stage.window.onFocusOut.remove(focusOut);
- FlxG.stage.window.onFocusIn.remove(focusIn);
- PlayState.instance.remove(PlayState.instance.videoSprite);
- }
+ {
+ GlobalVideo.get().stop();
+ FlxG.stage.window.onFocusOut.remove(focusOut);
+ FlxG.stage.window.onFocusIn.remove(focusIn);
+ PlayState.instance.remove(PlayState.instance.videoSprite);
+ }
if (isStoryMode)
campaignMisses = misses;
@@ -2679,7 +3259,7 @@ class PlayState extends MusicBeatState
}
if (FlxG.save.data.fpsCap > 290)
- (cast (Lib.current.getChildAt(0), Main)).setFPSCap(290);
+ (cast(Lib.current.getChildAt(0), Main)).setFPSCap(290);
#if windows
if (luaModchart != null)
@@ -2699,9 +3279,12 @@ class PlayState extends MusicBeatState
// adjusting the highscore song name to be compatible
// would read original scores if we didn't change packages
var songHighscore = StringTools.replace(PlayState.SONG.song, " ", "-");
- switch (songHighscore) {
- case 'Dad-Battle': songHighscore = 'Dadbattle';
- case 'Philly-Nice': songHighscore = 'Philly';
+ switch (songHighscore)
+ {
+ case 'Dad-Battle':
+ songHighscore = 'Dadbattle';
+ case 'Philly-Nice':
+ songHighscore = 'Philly';
}
#if !switch
@@ -2735,11 +3318,18 @@ class PlayState extends MusicBeatState
FlxG.sound.music.stop();
vocals.stop();
if (FlxG.save.data.scoreScreen)
+ {
openSubState(new ResultsScreen());
+ new FlxTimer().start(1, function(tmr:FlxTimer)
+ {
+ inResults = true;
+ });
+ }
else
{
FlxG.sound.playMusic(Paths.music('freakyMenu'));
- FlxG.switchState(new MainMenuState());
+ Conductor.changeBPM(102);
+ FlxG.switchState(new StoryMenuState());
}
#if windows
@@ -2750,26 +3340,24 @@ class PlayState extends MusicBeatState
}
#end
- // if ()
- StoryMenuState.weekUnlocked[Std.int(Math.min(storyWeek + 1, StoryMenuState.weekUnlocked.length - 1))] = true;
-
if (SONG.validScore)
{
NGio.unlockMedal(60961);
Highscore.saveWeekScore(storyWeek, campaignScore, storyDifficulty);
}
- FlxG.save.data.weekUnlocked = StoryMenuState.weekUnlocked;
- FlxG.save.flush();
+ StoryMenuState.unlockNextWeek(storyWeek);
}
else
{
-
// adjusting the song name to be compatible
var songFormat = StringTools.replace(PlayState.storyPlaylist[0], " ", "-");
- switch (songFormat) {
- case 'Dad-Battle': songFormat = 'Dadbattle';
- case 'Philly-Nice': songFormat = 'Philly';
+ switch (songFormat)
+ {
+ case 'Dad-Battle':
+ songFormat = 'Dadbattle';
+ case 'Philly-Nice':
+ songFormat = 'Philly';
}
var poop:String = Highscore.formatSong(songFormat, storyDifficulty);
@@ -2792,7 +3380,6 @@ class PlayState extends MusicBeatState
FlxTransitionableState.skipNextTransOut = true;
prevCamFollow = camFollow;
-
PlayState.SONG = Song.loadFromJson(poop, PlayState.storyPlaylist[0]);
FlxG.sound.music.stop();
@@ -2805,19 +3392,23 @@ class PlayState extends MusicBeatState
paused = true;
-
FlxG.sound.music.stop();
vocals.stop();
- if (FlxG.save.data.scoreScreen)
+ if (FlxG.save.data.scoreScreen)
+ {
openSubState(new ResultsScreen());
+ new FlxTimer().start(1, function(tmr:FlxTimer)
+ {
+ inResults = true;
+ });
+ }
else
FlxG.switchState(new FreeplayState());
}
}
}
-
var endingSong:Bool = false;
var hits:Array = [];
@@ -2827,73 +3418,70 @@ class PlayState extends MusicBeatState
var currentTimingShown:FlxText = null;
private function popUpScore(daNote:Note):Void
+ {
+ var noteDiff:Float = -(daNote.strumTime - Conductor.songPosition);
+ var wife:Float = EtternaFunctions.wife3(-noteDiff, Conductor.timeScale);
+ // boyfriend.playAnim('hey');
+ vocals.volume = 1;
+ var placement:String = Std.string(combo);
+
+ var coolText:FlxText = new FlxText(0, 0, 0, placement, 32);
+ coolText.screenCenter();
+ coolText.x = FlxG.width * 0.55;
+ coolText.y -= 350;
+ coolText.cameras = [camHUD];
+ //
+
+ var rating:FlxSprite = new FlxSprite();
+ var score:Float = 350;
+
+ if (FlxG.save.data.accuracyMod == 1)
+ totalNotesHit += wife;
+
+ var daRating = daNote.rating;
+
+ switch (daRating)
{
- var noteDiff:Float = -(daNote.strumTime - Conductor.songPosition);
- var wife:Float = EtternaFunctions.wife3(-noteDiff, Conductor.timeScale);
- // boyfriend.playAnim('hey');
- vocals.volume = 1;
- var placement:String = Std.string(combo);
-
- var coolText:FlxText = new FlxText(0, 0, 0, placement, 32);
- coolText.screenCenter();
- coolText.x = FlxG.width * 0.55;
- coolText.y -= 350;
- coolText.cameras = [camHUD];
- //
-
- var rating:FlxSprite = new FlxSprite();
- var score:Float = 350;
+ case 'shit':
+ score = -300;
+ combo = 0;
+ misses++;
+ health -= 0.06;
+ ss = false;
+ shits++;
+ if (FlxG.save.data.accuracyMod == 0)
+ totalNotesHit -= 1;
+ case 'bad':
+ daRating = 'bad';
+ score = 0;
+ health -= 0.03;
+ ss = false;
+ bads++;
+ if (FlxG.save.data.accuracyMod == 0)
+ totalNotesHit += 0.50;
+ case 'good':
+ daRating = 'good';
+ score = 200;
+ ss = false;
+ goods++;
+ if (FlxG.save.data.accuracyMod == 0)
+ totalNotesHit += 0.75;
+ case 'sick':
+ if (health < 2)
+ health += 0.04;
+ if (FlxG.save.data.accuracyMod == 0)
+ totalNotesHit += 1;
+ sicks++;
+ }
- if (FlxG.save.data.accuracyMod == 1)
- totalNotesHit += wife;
- var daRating = daNote.rating;
+ // trace('Wife accuracy loss: ' + wife + ' | Rating: ' + daRating + ' | Score: ' + score + ' | Weight: ' + (1 - wife));
- switch(daRating)
- {
- case 'shit':
- score = -300;
- combo = 0;
- misses++;
- health -= 0.2;
- ss = false;
- shits++;
- if (FlxG.save.data.accuracyMod == 0)
- totalNotesHit -= 1;
- case 'bad':
- daRating = 'bad';
- score = 0;
- health -= 0.06;
- ss = false;
- bads++;
- if (FlxG.save.data.accuracyMod == 0)
- totalNotesHit += 0.50;
- case 'good':
- daRating = 'good';
- score = 200;
- ss = false;
- goods++;
- if (health < 2)
- health += 0.04;
- if (FlxG.save.data.accuracyMod == 0)
- totalNotesHit += 0.75;
- case 'sick':
- if (health < 2)
- health += 0.1;
- if (FlxG.save.data.accuracyMod == 0)
- totalNotesHit += 1;
- sicks++;
- }
-
- // trace('Wife accuracy loss: ' + wife + ' | Rating: ' + daRating + ' | Score: ' + score + ' | Weight: ' + (1 - wife));
-
- if (daRating != 'shit' || daRating != 'bad')
- {
-
-
+ if (daRating != 'shit' || daRating != 'bad')
+ {
songScore += Math.round(score);
songScoreDef += Math.round(ConvertScore.convertScore(noteDiff));
-
+
/* if (combo > 60)
daRating = 'sick';
else if (combo > 12)
@@ -2901,21 +3489,21 @@ class PlayState extends MusicBeatState
else if (combo > 4)
daRating = 'bad';
*/
-
+
var pixelShitPart1:String = "";
var pixelShitPart2:String = '';
-
+
if (curStage.startsWith('school'))
{
pixelShitPart1 = 'weeb/pixelUI/';
pixelShitPart2 = '-pixel';
}
-
+
rating.loadGraphic(Paths.image(pixelShitPart1 + daRating + pixelShitPart2));
rating.screenCenter();
rating.y -= 50;
rating.x = coolText.x - 125;
-
+
if (FlxG.save.data.changedHit)
{
rating.x = FlxG.save.data.changedHitX;
@@ -2924,19 +3512,20 @@ class PlayState extends MusicBeatState
rating.acceleration.y = 550;
rating.velocity.y -= FlxG.random.int(140, 175);
rating.velocity.x -= FlxG.random.int(0, 10);
-
+
var msTiming = HelperFunctions.truncateFloat(noteDiff, 3);
- if(PlayStateChangeables.botPlay && !loadRep) msTiming = 0;
-
+ if (PlayStateChangeables.botPlay && !loadRep)
+ msTiming = 0;
+
if (loadRep)
msTiming = HelperFunctions.truncateFloat(findByTime(daNote.strumTime)[3], 3);
if (currentTimingShown != null)
remove(currentTimingShown);
- currentTimingShown = new FlxText(0,0,0,"0ms");
+ currentTimingShown = new FlxText(0, 0, 0, "0ms");
timeShown = 0;
- switch(daRating)
+ switch (daRating)
{
case 'shit' | 'bad':
currentTimingShown.color = FlxColor.RED;
@@ -2953,7 +3542,7 @@ class PlayState extends MusicBeatState
if (msTiming >= 0.03 && offsetTesting)
{
- //Remove Outliers
+ // Remove Outliers
hits.shift();
hits.shift();
hits.shift();
@@ -2964,19 +3553,18 @@ class PlayState extends MusicBeatState
var total = 0.0;
- for(i in hits)
+ for (i in hits)
total += i;
-
-
- offsetTest = HelperFunctions.truncateFloat(total / hits.length,2);
+ offsetTest = HelperFunctions.truncateFloat(total / hits.length, 2);
}
if (currentTimingShown.alpha != 1)
currentTimingShown.alpha = 1;
- if(!PlayStateChangeables.botPlay || loadRep) add(currentTimingShown);
-
+ if (!PlayStateChangeables.botPlay || loadRep)
+ add(currentTimingShown);
+
var comboSpr:FlxSprite = new FlxSprite().loadGraphic(Paths.image(pixelShitPart1 + 'combo' + pixelShitPart2));
comboSpr.screenCenter();
comboSpr.x = rating.x;
@@ -2989,34 +3577,41 @@ class PlayState extends MusicBeatState
currentTimingShown.y = rating.y + 100;
currentTimingShown.acceleration.y = 600;
currentTimingShown.velocity.y -= 150;
-
+
comboSpr.velocity.x += FlxG.random.int(1, 10);
currentTimingShown.velocity.x += comboSpr.velocity.x;
- if(!PlayStateChangeables.botPlay || loadRep) add(rating);
-
+ if (!PlayStateChangeables.botPlay || loadRep)
+ add(rating);
+
if (!curStage.startsWith('school'))
{
rating.setGraphicSize(Std.int(rating.width * 0.7));
- rating.antialiasing = true;
+ if(FlxG.save.data.antialiasing)
+ {
+ rating.antialiasing = true;
+ }
comboSpr.setGraphicSize(Std.int(comboSpr.width * 0.7));
- comboSpr.antialiasing = true;
+ if(FlxG.save.data.antialiasing)
+ {
+ comboSpr.antialiasing = true;
+ }
}
else
{
rating.setGraphicSize(Std.int(rating.width * daPixelZoom * 0.7));
comboSpr.setGraphicSize(Std.int(comboSpr.width * daPixelZoom * 0.7));
}
-
+
currentTimingShown.updateHitbox();
comboSpr.updateHitbox();
rating.updateHitbox();
-
+
currentTimingShown.cameras = [camHUD];
comboSpr.cameras = [camHUD];
rating.cameras = [camHUD];
var seperatedScore:Array = [];
-
+
var comboSplit:Array = (combo + "").split('');
if (combo > highestCombo)
@@ -3031,12 +3626,12 @@ class PlayState extends MusicBeatState
else if (comboSplit.length == 2)
seperatedScore.push(0);
- for(i in 0...comboSplit.length)
+ for (i in 0...comboSplit.length)
{
var str:String = comboSplit[i];
seperatedScore.push(Std.parseInt(str));
}
-
+
var daLoop:Int = 0;
for (i in seperatedScore)
{
@@ -3048,7 +3643,10 @@ class PlayState extends MusicBeatState
if (!curStage.startsWith('school'))
{
- numScore.antialiasing = true;
+ if(FlxG.save.data.antialiasing)
+ {
+ numScore.antialiasing = true;
+ }
numScore.setGraphicSize(Std.int(numScore.width * 0.5));
}
else
@@ -3056,13 +3654,13 @@ class PlayState extends MusicBeatState
numScore.setGraphicSize(Std.int(numScore.width * daPixelZoom));
}
numScore.updateHitbox();
-
+
numScore.acceleration.y = FlxG.random.int(200, 300);
numScore.velocity.y -= FlxG.random.int(140, 160);
numScore.velocity.x = FlxG.random.float(-5, 5);
-
+
add(numScore);
-
+
FlxTween.tween(numScore, {alpha: 0}, 0.2, {
onComplete: function(tween:FlxTween)
{
@@ -3070,17 +3668,17 @@ class PlayState extends MusicBeatState
},
startDelay: Conductor.crochet * 0.002
});
-
+
daLoop++;
}
/*
trace(combo);
trace(seperatedScore);
*/
-
+
coolText.text = Std.string(seperatedScore);
// add(coolText);
-
+
FlxTween.tween(rating, {alpha: 0}, 0.2, {
startDelay: Conductor.crochet * 0.001,
onUpdate: function(tween:FlxTween)
@@ -3105,329 +3703,348 @@ class PlayState extends MusicBeatState
},
startDelay: Conductor.crochet * 0.001
});
-
+
curSection += 1;
- }
}
+ }
public function NearlyEquals(value1:Float, value2:Float, unimportantDifference:Float = 10):Bool
+ {
+ return Math.abs(FlxMath.roundDecimal(value1, 1) - FlxMath.roundDecimal(value2, 1)) < unimportantDifference;
+ }
+
+ var upHold:Bool = false;
+ var downHold:Bool = false;
+ var rightHold:Bool = false;
+ var leftHold:Bool = false;
+
+ // THIS FUNCTION JUST FUCKS WIT HELD NOTES AND BOTPLAY/REPLAY (also gamepad shit)
+
+ private function keyShit():Void // I've invested in emma stocks
+ {
+ // control arrays, order L D R U
+ var holdArray:Array = [controls.LEFT, controls.DOWN, controls.UP, controls.RIGHT];
+ var pressArray:Array = [controls.LEFT_P, controls.DOWN_P, controls.UP_P, controls.RIGHT_P];
+ var releaseArray:Array = [controls.LEFT_R, controls.DOWN_R, controls.UP_R, controls.RIGHT_R];
+ #if windows
+ if (luaModchart != null)
{
- return Math.abs(FlxMath.roundDecimal(value1, 1) - FlxMath.roundDecimal(value2, 1)) < unimportantDifference;
+ if (controls.LEFT_P)
+ {
+ luaModchart.executeState('keyPressed', ["left"]);
+ };
+ if (controls.DOWN_P)
+ {
+ luaModchart.executeState('keyPressed', ["down"]);
+ };
+ if (controls.UP_P)
+ {
+ luaModchart.executeState('keyPressed', ["up"]);
+ };
+ if (controls.RIGHT_P)
+ {
+ luaModchart.executeState('keyPressed', ["right"]);
+ };
+ };
+ #end
+
+ // Prevent player input if botplay is on
+ if (PlayStateChangeables.botPlay)
+ {
+ holdArray = [false, false, false, false];
+ pressArray = [false, false, false, false];
+ releaseArray = [false, false, false, false];
}
- var upHold:Bool = false;
- var downHold:Bool = false;
- var rightHold:Bool = false;
- var leftHold:Bool = false;
+ var anas:Array = [null, null, null, null];
- // THIS FUNCTION JUST FUCKS WIT HELD NOTES AND BOTPLAY/REPLAY (also gamepad shit)
+ for (i in 0...pressArray.length)
+ if (pressArray[i])
+ anas[i] = new Ana(Conductor.songPosition, null, false, "miss", i);
- private function keyShit():Void // I've invested in emma stocks
+ // HOLDS, check for sustain notes
+ if (holdArray.contains(true) && /*!boyfriend.stunned && */ generatedMusic)
+ {
+ notes.forEachAlive(function(daNote:Note)
{
- // control arrays, order L D R U
- var holdArray:Array = [controls.LEFT, controls.DOWN, controls.UP, controls.RIGHT];
- var pressArray:Array = [
- controls.LEFT_P,
- controls.DOWN_P,
- controls.UP_P,
- controls.RIGHT_P
- ];
- var releaseArray:Array = [
- controls.LEFT_R,
- controls.DOWN_R,
- controls.UP_R,
- controls.RIGHT_R
- ];
- #if windows
- if (luaModchart != null){
- if (controls.LEFT_P){luaModchart.executeState('keyPressed',["left"]);};
- if (controls.DOWN_P){luaModchart.executeState('keyPressed',["down"]);};
- if (controls.UP_P){luaModchart.executeState('keyPressed',["up"]);};
- if (controls.RIGHT_P){luaModchart.executeState('keyPressed',["right"]);};
- };
- #end
-
-
- // Prevent player input if botplay is on
- if(PlayStateChangeables.botPlay)
+ if (daNote.isSustainNote && daNote.canBeHit && daNote.mustPress && holdArray[daNote.noteData] && daNote.sustainActive)
{
- holdArray = [false, false, false, false];
- pressArray = [false, false, false, false];
- releaseArray = [false, false, false, false];
- }
-
- var anas:Array = [null,null,null,null];
-
- for (i in 0...pressArray.length)
- if (pressArray[i])
- anas[i] = new Ana(Conductor.songPosition, null, false, "miss", i);
-
- // HOLDS, check for sustain notes
- if (holdArray.contains(true) && /*!boyfriend.stunned && */ generatedMusic)
- {
- notes.forEachAlive(function(daNote:Note)
- {
- if (daNote.isSustainNote && daNote.canBeHit && daNote.mustPress && holdArray[daNote.noteData])
- goodNoteHit(daNote);
- });
+ trace(daNote.sustainActive);
+ goodNoteHit(daNote);
}
-
- if (KeyBinds.gamepad && !FlxG.keys.justPressed.ANY)
- {
- // PRESSES, check for note hits
- if (pressArray.contains(true) && generatedMusic)
- {
- boyfriend.holdTimer = 0;
-
- var possibleNotes:Array = []; // notes that can be hit
- var directionList:Array = []; // directions that can be hit
- var dumbNotes:Array = []; // notes to kill later
- var directionsAccounted:Array = [false,false,false,false]; // we don't want to do judgments for more than one presses
-
- notes.forEachAlive(function(daNote:Note)
- {
- if (daNote.canBeHit && daNote.mustPress && !daNote.tooLate && !daNote.wasGoodHit && !directionsAccounted[daNote.noteData])
- {
- if (directionList.contains(daNote.noteData))
- {
- directionsAccounted[daNote.noteData] = true;
- for (coolNote in possibleNotes)
- {
- if (coolNote.noteData == daNote.noteData && Math.abs(daNote.strumTime - coolNote.strumTime) < 10)
- { // if it's the same note twice at < 10ms distance, just delete it
- // EXCEPT u cant delete it in this loop cuz it fucks with the collection lol
- dumbNotes.push(daNote);
- break;
- }
- else if (coolNote.noteData == daNote.noteData && daNote.strumTime < coolNote.strumTime)
- { // if daNote is earlier than existing note (coolNote), replace
- possibleNotes.remove(coolNote);
- possibleNotes.push(daNote);
- break;
- }
- }
- }
- else
- {
- possibleNotes.push(daNote);
- directionList.push(daNote.noteData);
- }
- }
- });
+ });
+ }
- for (note in dumbNotes)
- {
- FlxG.log.add("killing dumb ass note at " + note.strumTime);
- note.kill();
- notes.remove(note, true);
- note.destroy();
- }
-
- possibleNotes.sort((a, b) -> Std.int(a.strumTime - b.strumTime));
- if (perfectMode)
- goodNoteHit(possibleNotes[0]);
- else if (possibleNotes.length > 0)
- {
- if (!FlxG.save.data.ghost)
- {
- for (shit in 0...pressArray.length)
- { // if a direction is hit that shouldn't be
- if (pressArray[shit] && !directionList.contains(shit))
- noteMiss(shit, null);
- }
- }
- for (coolNote in possibleNotes)
- {
- if (pressArray[coolNote.noteData])
- {
- if (mashViolations != 0)
- mashViolations--;
- scoreTxt.color = FlxColor.WHITE;
- var noteDiff:Float = -(coolNote.strumTime - Conductor.songPosition);
- anas[coolNote.noteData].hit = true;
- anas[coolNote.noteData].hitJudge = Ratings.CalculateRating(noteDiff, Math.floor((PlayStateChangeables.safeFrames / 60) * 1000));
- anas[coolNote.noteData].nearestNote = [coolNote.strumTime,coolNote.noteData,coolNote.sustainLength];
- goodNoteHit(coolNote);
- }
- }
- }
- else if (!FlxG.save.data.ghost)
- {
- for (shit in 0...pressArray.length)
- if (pressArray[shit])
- noteMiss(shit, null);
- }
- }
+ if ((KeyBinds.gamepad && !FlxG.keys.justPressed.ANY))
+ {
+ // PRESSES, check for note hits
+ if (pressArray.contains(true) && generatedMusic)
+ {
+ boyfriend.holdTimer = 0;
+
+ var possibleNotes:Array = []; // notes that can be hit
+ var directionList:Array = []; // directions that can be hit
+ var dumbNotes:Array = []; // notes to kill later
+ var directionsAccounted:Array = [false, false, false, false]; // we don't want to do judgments for more than one presses
- if (!loadRep)
- for (i in anas)
- if (i != null)
- replayAna.anaArray.push(i); // put em all there
- }
notes.forEachAlive(function(daNote:Note)
{
- if(PlayStateChangeables.useDownscroll && daNote.y > strumLine.y ||
- !PlayStateChangeables.useDownscroll && daNote.y < strumLine.y)
+ if (daNote.canBeHit && daNote.mustPress && !daNote.tooLate && !daNote.wasGoodHit && !directionsAccounted[daNote.noteData])
{
- // Force good note hit regardless if it's too late to hit it or not as a fail safe
- if(PlayStateChangeables.botPlay && daNote.canBeHit && daNote.mustPress ||
- PlayStateChangeables.botPlay && daNote.tooLate && daNote.mustPress)
+ if (directionList.contains(daNote.noteData))
{
- if(loadRep)
+ directionsAccounted[daNote.noteData] = true;
+ for (coolNote in possibleNotes)
{
- //trace('ReplayNote ' + tmpRepNote.strumtime + ' | ' + tmpRepNote.direction);
- var n = findByTime(daNote.strumTime);
- trace(n);
- if(n != null)
- {
- goodNoteHit(daNote);
- boyfriend.holdTimer = daNote.sustainLength;
+ if (coolNote.noteData == daNote.noteData && Math.abs(daNote.strumTime - coolNote.strumTime) < 10)
+ { // if it's the same note twice at < 10ms distance, just delete it
+ // EXCEPT u cant delete it in this loop cuz it fucks with the collection lol
+ dumbNotes.push(daNote);
+ break;
+ }
+ else if (coolNote.noteData == daNote.noteData && daNote.strumTime < coolNote.strumTime)
+ { // if daNote is earlier than existing note (coolNote), replace
+ possibleNotes.remove(coolNote);
+ possibleNotes.push(daNote);
+ break;
}
- }else {
- goodNoteHit(daNote);
- boyfriend.holdTimer = daNote.sustainLength;
}
}
+ else
+ {
+ directionsAccounted[daNote.noteData] = true;
+ possibleNotes.push(daNote);
+ directionList.push(daNote.noteData);
+ }
}
});
+
+ for (note in dumbNotes)
+ {
+ FlxG.log.add("killing dumb ass note at " + note.strumTime);
+ note.kill();
+ notes.remove(note, true);
+ note.destroy();
+ }
+
+ possibleNotes.sort((a, b) -> Std.int(a.strumTime - b.strumTime));
+
+ var hit = [false,false,false,false];
+
+ if (perfectMode)
+ goodNoteHit(possibleNotes[0]);
+ else if (possibleNotes.length > 0)
+ {
+ if (!FlxG.save.data.ghost)
+ {
+ for (shit in 0...pressArray.length)
+ { // if a direction is hit that shouldn't be
+ if (pressArray[shit] && !directionList.contains(shit))
+ noteMiss(shit, null);
+ }
+ }
+ for (coolNote in possibleNotes)
+ {
+ if (pressArray[coolNote.noteData] && !hit[coolNote.noteData])
+ {
+ if (mashViolations != 0)
+ mashViolations--;
+ hit[coolNote.noteData] = true;
+ scoreTxt.color = FlxColor.WHITE;
+ var noteDiff:Float = -(coolNote.strumTime - Conductor.songPosition);
+ anas[coolNote.noteData].hit = true;
+ anas[coolNote.noteData].hitJudge = Ratings.CalculateRating(noteDiff, Math.floor((PlayStateChangeables.safeFrames / 60) * 1000));
+ anas[coolNote.noteData].nearestNote = [coolNote.strumTime, coolNote.noteData, coolNote.sustainLength];
+ goodNoteHit(coolNote);
+ }
+ }
+ };
if (boyfriend.holdTimer > Conductor.stepCrochet * 4 * 0.001 && (!holdArray.contains(true) || PlayStateChangeables.botPlay))
{
- if (boyfriend.animation.curAnim.name.startsWith('sing') && !boyfriend.animation.curAnim.name.endsWith('miss'))
+ if (boyfriend.animation.curAnim.name.startsWith('sing') && !boyfriend.animation.curAnim.name.endsWith('miss') && boyfriend.animation.curAnim.curFrame >= 10)
boyfriend.playAnim('idle');
}
-
- playerStrums.forEach(function(spr:FlxSprite)
+ else if (!FlxG.save.data.ghost)
{
- if (pressArray[spr.ID] && spr.animation.curAnim.name != 'confirm')
- spr.animation.play('pressed');
- if (!holdArray[spr.ID])
- spr.animation.play('static');
-
- if (spr.animation.curAnim.name == 'confirm' && !curStage.startsWith('school'))
+ for (shit in 0...pressArray.length)
+ if (pressArray[shit])
+ noteMiss(shit, null);
+ }
+ }
+
+ if (!loadRep)
+ for (i in anas)
+ if (i != null)
+ replayAna.anaArray.push(i); // put em all there
+ }
+ notes.forEachAlive(function(daNote:Note)
+ {
+ if (PlayStateChangeables.useDownscroll && daNote.y > strumLine.y || !PlayStateChangeables.useDownscroll && daNote.y < strumLine.y)
+ {
+ // Force good note hit regardless if it's too late to hit it or not as a fail safe
+ if (PlayStateChangeables.botPlay && daNote.canBeHit && daNote.mustPress || PlayStateChangeables.botPlay && daNote.tooLate && daNote.mustPress)
+ {
+ if (loadRep)
{
- spr.centerOffsets();
- spr.offset.x -= 13;
- spr.offset.y -= 13;
+ // trace('ReplayNote ' + tmpRepNote.strumtime + ' | ' + tmpRepNote.direction);
+ var n = findByTime(daNote.strumTime);
+ trace(n);
+ if (n != null)
+ {
+ goodNoteHit(daNote);
+ boyfriend.holdTimer = daNote.sustainLength;
+ }
}
else
- spr.centerOffsets();
- });
- }
-
- public function findByTime(time:Float):Array
- {
- for (i in rep.replay.songNotes)
{
- //trace('checking ' + Math.round(i[0]) + ' against ' + Math.round(time));
- if (i[0] == time)
- return i;
+ goodNoteHit(daNote);
+ boyfriend.holdTimer = daNote.sustainLength;
}
- return null;
}
-
- public function findByTimeIndex(time:Float):Int
- {
- for (i in 0...rep.replay.songNotes.length)
- {
- //trace('checking ' + Math.round(i[0]) + ' against ' + Math.round(time));
- if (rep.replay.songNotes[i][0] == time)
- return i;
- }
- return -1;
- }
-
- public var fuckingVolume:Float = 1;
- public var useVideo = false;
-
- public static var webmHandler:WebmHandler;
-
- public var playingDathing = false;
-
- public var videoSprite:FlxSprite;
-
- public function focusOut() {
- if (paused)
- return;
- persistentUpdate = false;
- persistentDraw = true;
- paused = true;
-
- if (FlxG.sound.music != null)
- {
- FlxG.sound.music.pause();
- vocals.pause();
- }
-
- openSubState(new PauseSubState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y));
}
- public function focusIn()
- {
- // nada
+ });
+
+ if (boyfriend.holdTimer > Conductor.stepCrochet * 4 * 0.001 && (!holdArray.contains(true) || PlayStateChangeables.botPlay))
+ {
+ if (boyfriend.animation.curAnim.name.startsWith('sing') && !boyfriend.animation.curAnim.name.endsWith('miss') && boyfriend.animation.curAnim.curFrame >= 10)
+ boyfriend.playAnim('idle');
+ }
+
+ playerStrums.forEach(function(spr:FlxSprite)
+ {
+ if (keys[spr.ID] && spr.animation.curAnim.name != 'confirm')
+ spr.animation.play('pressed');
+ if (!keys[spr.ID])
+ spr.animation.play('static');
+
+ if (spr.animation.curAnim.name == 'confirm' && !curStage.startsWith('school'))
+ {
+ spr.centerOffsets();
+ spr.offset.x -= 13;
+ spr.offset.y -= 13;
}
+ else
+ spr.centerOffsets();
+ });
+ }
+ public function findByTime(time:Float):Array
+ {
+ for (i in rep.replay.songNotes)
+ {
+ // trace('checking ' + Math.round(i[0]) + ' against ' + Math.round(time));
+ if (i[0] == time)
+ return i;
+ }
+ return null;
+ }
- public function backgroundVideo(source:String) // for background videos
- {
- #if cpp
- useVideo = true;
-
- FlxG.stage.window.onFocusOut.add(focusOut);
- FlxG.stage.window.onFocusIn.add(focusIn);
+ public function findByTimeIndex(time:Float):Int
+ {
+ for (i in 0...rep.replay.songNotes.length)
+ {
+ // trace('checking ' + Math.round(i[0]) + ' against ' + Math.round(time));
+ if (rep.replay.songNotes[i][0] == time)
+ return i;
+ }
+ return -1;
+ }
- var ourSource:String = "assets/videos/daWeirdVid/dontDelete.webm";
- WebmPlayer.SKIP_STEP_LIMIT = 90;
- var str1:String = "WEBM SHIT";
- webmHandler = new WebmHandler();
- webmHandler.source(ourSource);
- webmHandler.makePlayer();
- webmHandler.webm.name = str1;
-
- GlobalVideo.setWebm(webmHandler);
+ public var fuckingVolume:Float = 1;
+ public var useVideo = false;
- GlobalVideo.get().source(source);
- GlobalVideo.get().clearPause();
- if (GlobalVideo.isWebm)
- {
- GlobalVideo.get().updatePlayer();
- }
- GlobalVideo.get().show();
-
- if (GlobalVideo.isWebm)
- {
- GlobalVideo.get().restart();
- } else {
- GlobalVideo.get().play();
- }
-
- var data = webmHandler.webm.bitmapData;
-
- videoSprite = new FlxSprite(-470,-30).loadGraphic(data);
-
- videoSprite.setGraphicSize(Std.int(videoSprite.width * 1.2));
-
- remove(gf);
- remove(boyfriend);
- remove(dad);
- add(videoSprite);
- add(gf);
- add(boyfriend);
- add(dad);
-
- trace('poggers');
-
- if (!songStarted)
- webmHandler.pause();
- else
- webmHandler.resume();
- #end
- }
+ public static var webmHandler:WebmHandler;
+
+ public var playingDathing = false;
+
+ public var videoSprite:FlxSprite;
+
+ public function focusOut()
+ {
+ if (paused)
+ return;
+ persistentUpdate = false;
+ persistentDraw = true;
+ paused = true;
+
+ if (FlxG.sound.music != null)
+ {
+ FlxG.sound.music.pause();
+ vocals.pause();
+ }
+
+ openSubState(new PauseSubState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y));
+ }
+
+ public function focusIn()
+ {
+ // nada
+ }
+
+ public function backgroundVideo(source:String) // for background videos
+ {
+ #if cpp
+ useVideo = true;
+
+ FlxG.stage.window.onFocusOut.add(focusOut);
+ FlxG.stage.window.onFocusIn.add(focusIn);
+
+ var ourSource:String = "assets/videos/daWeirdVid/dontDelete.webm";
+ WebmPlayer.SKIP_STEP_LIMIT = 90;
+ var str1:String = "WEBM SHIT";
+ webmHandler = new WebmHandler();
+ webmHandler.source(ourSource);
+ webmHandler.makePlayer();
+ webmHandler.webm.name = str1;
+
+ GlobalVideo.setWebm(webmHandler);
+
+ GlobalVideo.get().source(source);
+ GlobalVideo.get().clearPause();
+ if (GlobalVideo.isWebm)
+ {
+ GlobalVideo.get().updatePlayer();
+ }
+ GlobalVideo.get().show();
+
+ if (GlobalVideo.isWebm)
+ {
+ GlobalVideo.get().restart();
+ }
+ else
+ {
+ GlobalVideo.get().play();
+ }
+
+ var data = webmHandler.webm.bitmapData;
+
+ videoSprite = new FlxSprite(-470, -30).loadGraphic(data);
+
+ videoSprite.setGraphicSize(Std.int(videoSprite.width * 1.2));
+
+ remove(gf);
+ remove(boyfriend);
+ remove(dad);
+ add(videoSprite);
+ add(gf);
+ add(boyfriend);
+ add(dad);
+
+ trace('poggers');
+
+ if (!songStarted)
+ webmHandler.pause();
+ else
+ webmHandler.resume();
+ #end
+ }
function noteMiss(direction:Int = 1, daNote:Note):Void
{
if (!boyfriend.stunned)
{
- health -= 0.04;
+ //health -= 0.2;
if (combo > 5 && gf.animOffsets.exists('sad'))
{
gf.playAnim('sad');
@@ -3439,78 +4056,85 @@ class PlayState extends MusicBeatState
{
if (!loadRep)
{
- saveNotes.push([daNote.strumTime,0,direction,166 * Math.floor((PlayState.rep.replay.sf / 60) * 1000) / 166]);
+ saveNotes.push([
+ daNote.strumTime,
+ 0,
+ direction,
+ 166 * Math.floor((PlayState.rep.replay.sf / 60) * 1000) / 166
+ ]);
saveJudge.push("miss");
}
}
- else
- if (!loadRep)
- {
- saveNotes.push([Conductor.songPosition,0,direction,166 * Math.floor((PlayState.rep.replay.sf / 60) * 1000) / 166]);
- saveJudge.push("miss");
- }
+ else if (!loadRep)
+ {
+ saveNotes.push([
+ Conductor.songPosition,
+ 0,
+ direction,
+ 166 * Math.floor((PlayState.rep.replay.sf / 60) * 1000) / 166
+ ]);
+ saveJudge.push("miss");
+ }
- //var noteDiff:Float = Math.abs(daNote.strumTime - Conductor.songPosition);
- //var wife:Float = EtternaFunctions.wife3(noteDiff, FlxG.save.data.etternaMode ? 1 : 1.7);
+ // var noteDiff:Float = Math.abs(daNote.strumTime - Conductor.songPosition);
+ // var wife:Float = EtternaFunctions.wife3(noteDiff, FlxG.save.data.etternaMode ? 1 : 1.7);
if (FlxG.save.data.accuracyMod == 1)
totalNotesHit -= 1;
- songScore -= 10;
-
- FlxG.sound.play(Paths.soundRandom('missnote', 1, 3), FlxG.random.float(0.1, 0.2));
- // FlxG.sound.play(Paths.sound('missnote1'), 1, false);
- // FlxG.log.add('played imss note');
-
- switch (direction)
+ if (daNote != null)
{
- case 0:
- boyfriend.playAnim('singLEFTmiss', true);
- case 1:
- boyfriend.playAnim('singDOWNmiss', true);
- case 2:
- boyfriend.playAnim('singUPmiss', true);
- case 3:
- boyfriend.playAnim('singRIGHTmiss', true);
+ if (!daNote.isSustainNote)
+ songScore -= 10;
}
+ else
+ songScore -= 10;
+
+ if(FlxG.save.data.missSounds)
+ {
+ FlxG.sound.play(Paths.soundRandom('missnote', 1, 3), FlxG.random.float(0.1, 0.2));
+ // FlxG.sound.play(Paths.sound('missnote1'), 1, false);
+ // FlxG.log.add('played imss note');
+ }
+
+ // Hole switch statement replaced with a single line :)
+ boyfriend.playAnim('sing' + dataSuffix[direction] + 'miss', true);
#if windows
if (luaModchart != null)
luaModchart.executeState('playerOneMiss', [direction, Conductor.songPosition]);
#end
-
updateAccuracy();
}
}
/*function badNoteCheck()
- {
- // just double pasting this shit cuz fuk u
- // REDO THIS SYSTEM!
- var upP = controls.UP_P;
- var rightP = controls.RIGHT_P;
- var downP = controls.DOWN_P;
- var leftP = controls.LEFT_P;
-
- if (leftP)
- noteMiss(0);
- if (upP)
- noteMiss(2);
- if (rightP)
- noteMiss(3);
- if (downP)
- noteMiss(1);
- updateAccuracy();
- }
- */
- function updateAccuracy()
- {
- totalPlayed += 1;
- accuracy = Math.max(0,totalNotesHit / totalPlayed * 100);
- accuracyDefault = Math.max(0, totalNotesHitDefault / totalPlayed * 100);
- }
+ {
+ // just double pasting this shit cuz fuk u
+ // REDO THIS SYSTEM!
+ var upP = controls.UP_P;
+ var rightP = controls.RIGHT_P;
+ var downP = controls.DOWN_P;
+ var leftP = controls.LEFT_P;
+ if (leftP)
+ noteMiss(0);
+ if (upP)
+ noteMiss(2);
+ if (rightP)
+ noteMiss(3);
+ if (downP)
+ noteMiss(1);
+ updateAccuracy();
+ }
+ */
+ function updateAccuracy()
+ {
+ totalPlayed += 1;
+ accuracy = Math.max(0, totalNotesHit / totalPlayed * 100);
+ accuracyDefault = Math.max(0, totalNotesHitDefault / totalPlayed * 100);
+ }
function getKeyPresses(note:Note):Int
{
@@ -3528,19 +4152,19 @@ class PlayState extends MusicBeatState
return possibleNotes.length + 1;
return possibleNotes.length;
}
-
+
var mashing:Int = 0;
var mashViolations:Int = 0;
var etternaModeScore:Int = 0;
function noteCheck(controlArray:Array, note:Note):Void // sorry lol
- {
- var noteDiff:Float = -(note.strumTime - Conductor.songPosition);
+ {
+ var noteDiff:Float = -(note.strumTime - Conductor.songPosition);
- note.rating = Ratings.CalculateRating(noteDiff, Math.floor((PlayStateChangeables.safeFrames / 60) * 1000));
+ note.rating = Ratings.CalculateRating(noteDiff, Math.floor((PlayStateChangeables.safeFrames / 60) * 1000));
- /* if (loadRep)
+ /* if (loadRep)
{
if (controlArray[note.noteData])
goodNoteHit(note, false);
@@ -3551,13 +4175,13 @@ class PlayState extends MusicBeatState
goodNoteHit(note, false);
}
}
- } */
-
- if (controlArray[note.noteData])
- {
- goodNoteHit(note, (mashing > getKeyPresses(note)));
-
- /*if (mashing > getKeyPresses(note) && mashViolations <= 2)
+ }*/
+
+ if (controlArray[note.noteData])
+ {
+ goodNoteHit(note, (mashing > getKeyPresses(note)));
+
+ /*if (mashing > getKeyPresses(note) && mashViolations <= 2)
{
mashViolations++;
@@ -3576,104 +4200,97 @@ class PlayState extends MusicBeatState
mashing = 0;
}
else
- goodNoteHit(note, false);*/
-
- }
+ goodNoteHit(note, false); */
}
+ }
- function goodNoteHit(note:Note, resetMashViolation = true):Void
+ function goodNoteHit(note:Note, resetMashViolation = true):Void
+ {
+ if (mashing != 0)
+ mashing = 0;
+
+ var noteDiff:Float = -(note.strumTime - Conductor.songPosition);
+
+ if (loadRep)
+ {
+ noteDiff = findByTime(note.strumTime)[3];
+ note.rating = rep.replay.songJudgements[findByTimeIndex(note.strumTime)];
+ }
+ else
+ note.rating = Ratings.CalculateRating(noteDiff);
+
+ if (note.rating == "miss")
+ return;
+
+ // add newest note to front of notesHitArray
+ // the oldest notes are at the end and are removed first
+ if (!note.isSustainNote)
+ notesHitArray.unshift(Date.now());
+
+ if (!resetMashViolation && mashViolations >= 1)
+ mashViolations--;
+
+ if (mashViolations < 0)
+ mashViolations = 0;
+
+ if (!note.wasGoodHit)
+ {
+ if (!note.isSustainNote)
{
-
- if (mashing != 0)
- mashing = 0;
-
- var noteDiff:Float = -(note.strumTime - Conductor.songPosition);
-
- if(loadRep)
- {
- noteDiff = findByTime(note.strumTime)[3];
- note.rating = rep.replay.songJudgements[findByTimeIndex(note.strumTime)];
- }
- else
- note.rating = Ratings.CalculateRating(noteDiff);
-
- if (note.rating == "miss")
- return;
-
- // add newest note to front of notesHitArray
- // the oldest notes are at the end and are removed first
- if (!note.isSustainNote)
- notesHitArray.unshift(Date.now());
-
- if (!resetMashViolation && mashViolations >= 1)
- mashViolations--;
-
- if (mashViolations < 0)
- mashViolations = 0;
-
- if (!note.wasGoodHit)
- {
- if (!note.isSustainNote)
- {
- popUpScore(note);
- combo += 1;
- }
- else
- totalNotesHit += 1;
-
-
- switch (note.noteData)
- {
- case 2:
- boyfriend.playAnim('singUP', true);
- case 3:
- boyfriend.playAnim('singRIGHT', true);
- case 1:
- boyfriend.playAnim('singDOWN', true);
- case 0:
- boyfriend.playAnim('singLEFT', true);
- }
-
- #if windows
- if (luaModchart != null)
- luaModchart.executeState('playerOneSing', [note.noteData, Conductor.songPosition]);
- #end
-
-
- if(!loadRep && note.mustPress)
- {
- var array = [note.strumTime,note.sustainLength,note.noteData,noteDiff];
- if (note.isSustainNote)
- array[1] = -1;
- saveNotes.push(array);
- saveJudge.push(note.rating);
- }
-
- playerStrums.forEach(function(spr:FlxSprite)
- {
- if (Math.abs(note.noteData) == spr.ID)
- {
- spr.animation.play('confirm', true);
- }
- });
-
- note.wasGoodHit = true;
- vocals.volume = 1;
-
- note.kill();
- notes.remove(note, true);
- note.destroy();
-
- updateAccuracy();
- }
+ popUpScore(note);
+ combo += 1;
}
-
+ else
+ totalNotesHit += 1;
+
+ switch (note.noteData)
+ {
+ case 2:
+ boyfriend.playAnim('singUP', true);
+ case 3:
+ boyfriend.playAnim('singRIGHT', true);
+ case 1:
+ boyfriend.playAnim('singDOWN', true);
+ case 0:
+ boyfriend.playAnim('singLEFT', true);
+ }
+
+ #if windows
+ if (luaModchart != null)
+ luaModchart.executeState('playerOneSing', [note.noteData, Conductor.songPosition]);
+ #end
+
+ if (!loadRep && note.mustPress)
+ {
+ var array = [note.strumTime, note.sustainLength, note.noteData, noteDiff];
+ if (note.isSustainNote)
+ array[1] = -1;
+ saveNotes.push(array);
+ saveJudge.push(note.rating);
+ }
+
+ playerStrums.forEach(function(spr:FlxSprite)
+ {
+ if (Math.abs(note.noteData) == spr.ID)
+ {
+ spr.animation.play('confirm', true);
+ }
+ });
+
+ note.kill();
+ notes.remove(note, true);
+ note.destroy();
+
+ updateAccuracy();
+ }
+ }
var fastCarCanDrive:Bool = true;
function resetFastCar():Void
{
- if(FlxG.save.data.distractions){
+ if (FlxG.save.data.distractions)
+ {
fastCar.x = -12600;
fastCar.y = FlxG.random.int(140, 250);
fastCar.velocity.x = 0;
@@ -3683,7 +4300,8 @@ class PlayState extends MusicBeatState
function fastCarDrive()
{
- if(FlxG.save.data.distractions){
+ if (FlxG.save.data.distractions)
+ {
FlxG.sound.play(Paths.soundRandom('carPass', 0, 1), 0.7);
fastCar.velocity.x = (FlxG.random.int(170, 220) / FlxG.elapsed) * 3;
@@ -3704,7 +4322,8 @@ class PlayState extends MusicBeatState
function trainStart():Void
{
- if(FlxG.save.data.distractions){
+ if (FlxG.save.data.distractions)
+ {
trainMoving = true;
if (!trainSound.playing)
trainSound.play(true);
@@ -3715,36 +4334,37 @@ class PlayState extends MusicBeatState
function updateTrainPos():Void
{
- if(FlxG.save.data.distractions){
+ if (FlxG.save.data.distractions)
+ {
if (trainSound.time >= 4700)
- {
- startedMoving = true;
- gf.playAnim('hairBlow');
- }
-
- if (startedMoving)
- {
- phillyTrain.x -= 400;
-
- if (phillyTrain.x < -2000 && !trainFinishing)
- {
- phillyTrain.x = -1150;
- trainCars -= 1;
-
- if (trainCars <= 0)
- trainFinishing = true;
- }
-
- if (phillyTrain.x < -4000 && trainFinishing)
- trainReset();
- }
- }
+ {
+ startedMoving = true;
+ gf.playAnim('hairBlow');
+ }
+ if (startedMoving)
+ {
+ phillyTrain.x -= 400;
+
+ if (phillyTrain.x < -2000 && !trainFinishing)
+ {
+ phillyTrain.x = -1150;
+ trainCars -= 1;
+
+ if (trainCars <= 0)
+ trainFinishing = true;
+ }
+
+ if (phillyTrain.x < -4000 && trainFinishing)
+ trainReset();
+ }
+ }
}
function trainReset():Void
{
- if(FlxG.save.data.distractions){
+ if (FlxG.save.data.distractions)
+ {
gf.playAnim('hairFall');
phillyTrain.x = FlxG.width + 200;
trainMoving = false;
@@ -3781,8 +4401,8 @@ class PlayState extends MusicBeatState
#if windows
if (executeModchart && luaModchart != null)
{
- luaModchart.setVar('curStep',curStep);
- luaModchart.executeState('stepHit',[curStep]);
+ luaModchart.setVar('curStep', curStep);
+ luaModchart.executeState('stepHit', [curStep]);
}
#end
@@ -3794,9 +4414,22 @@ class PlayState extends MusicBeatState
songLength = FlxG.sound.music.length;
// Updating Discord Rich Presence (with Time Left)
- DiscordClient.changePresence(detailsText + " " + SONG.song + " (" + storyDifficultyText + ") " + Ratings.GenerateLetterRank(accuracy), "Acc: " + HelperFunctions.truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + misses , iconRPC,true, songLength - Conductor.songPosition);
+ DiscordClient.changePresence(detailsText
+ + " "
+ + SONG.song
+ + " ("
+ + storyDifficultyText
+ + ") "
+ + Ratings.GenerateLetterRank(accuracy),
+ "Acc: "
+ + HelperFunctions.truncateFloat(accuracy, 2)
+ + "% | Score: "
+ + songScore
+ + " | Misses: "
+ + misses, iconRPC, true,
+ songLength
+ - Conductor.songPosition);
#end
-
}
var lightningStrikeBeat:Int = 0;
@@ -3814,12 +4447,13 @@ class PlayState extends MusicBeatState
#if windows
if (executeModchart && luaModchart != null)
{
- luaModchart.setVar('curBeat',curBeat);
- luaModchart.executeState('beatHit',[curBeat]);
+ luaModchart.setVar('curBeat', curBeat);
+ luaModchart.executeState('beatHit', [curBeat]);
}
#end
- if (curSong == 'Tutorial' && dad.curCharacter == 'gf') {
+ if (curSong == 'Tutorial' && dad.curCharacter == 'gf')
+ {
if (curBeat % 2 == 1 && dad.animOffsets.exists('danceLeft'))
dad.playAnim('danceLeft');
if (curBeat % 2 == 0 && dad.animOffsets.exists('danceRight'))
@@ -3828,17 +4462,13 @@ class PlayState extends MusicBeatState
if (SONG.notes[Math.floor(curStep / 16)] != null)
{
- if (SONG.notes[Math.floor(curStep / 16)].changeBPM)
- {
- Conductor.changeBPM(SONG.notes[Math.floor(curStep / 16)].bpm);
- FlxG.log.add('CHANGED BPM!');
- }
// else
// Conductor.changeBPM(SONG.bpm);
// Dad doesnt interupt his own notes
- if (SONG.notes[Math.floor(curStep / 16)].mustHitSection && dad.curCharacter != 'gf')
- dad.dance();
+ if ((SONG.notes[Math.floor(curStep / 16)].mustHitSection || !dad.animation.curAnim.name.startsWith("sing")) && dad.curCharacter != 'gf')
+ if (curBeat % idleBeat == 0 || dad.curCharacter == "spooky")
+ dad.dance(idleToBeat);
}
// FlxG.log.add('change bpm' + SONG.notes[Std.int(curStep / 16)].changeBPM);
wiggleShit.update(Conductor.crochet);
@@ -3851,18 +4481,17 @@ class PlayState extends MusicBeatState
FlxG.camera.zoom += 0.015;
camHUD.zoom += 0.03;
}
-
+
if (camZooming && FlxG.camera.zoom < 1.35 && curBeat % 4 == 0)
{
FlxG.camera.zoom += 0.015;
camHUD.zoom += 0.03;
}
-
}
iconP1.setGraphicSize(Std.int(iconP1.width + 30));
iconP2.setGraphicSize(Std.int(iconP2.width + 30));
-
+
iconP1.updateHitbox();
iconP2.updateHitbox();
@@ -3871,11 +4500,15 @@ class PlayState extends MusicBeatState
gf.dance();
}
- if (!boyfriend.animation.curAnim.name.startsWith("sing"))
+ if (!boyfriend.animation.curAnim.name.startsWith("sing") && curBeat % idleBeat == 0)
{
- boyfriend.playAnim('idle');
+ boyfriend.playAnim('idle', idleToBeat);
}
-
+
+ /*if (!dad.animation.curAnim.name.startsWith("sing"))
+ {
+ dad.dance();
+ }*/
if (curBeat % 8 == 7 && curSong == 'Bopeebo')
{
@@ -3883,58 +4516,62 @@ class PlayState extends MusicBeatState
}
if (curBeat % 16 == 15 && SONG.song == 'Tutorial' && dad.curCharacter == 'gf' && curBeat > 16 && curBeat < 48)
- {
- boyfriend.playAnim('hey', true);
- dad.playAnim('cheer', true);
- }
+ {
+ boyfriend.playAnim('hey', true);
+ dad.playAnim('cheer', true);
+ }
switch (curStage)
{
case 'school':
- if(FlxG.save.data.distractions){
+ if (FlxG.save.data.distractions)
+ {
bgGirls.dance();
}
case 'mall':
- if(FlxG.save.data.distractions){
+ if (FlxG.save.data.distractions)
+ {
upperBoppers.animation.play('bop', true);
bottomBoppers.animation.play('bop', true);
santa.animation.play('idle', true);
}
case 'limo':
- if(FlxG.save.data.distractions){
+ if (FlxG.save.data.distractions)
+ {
grpLimoDancers.forEach(function(dancer:BackgroundDancer)
- {
- dancer.dance();
- });
-
- if (FlxG.random.bool(10) && fastCarCanDrive)
- fastCarDrive();
+ {
+ dancer.dance();
+ });
+
+ if (FlxG.random.bool(10) && fastCarCanDrive)
+ fastCarDrive();
}
case "philly":
- if(FlxG.save.data.distractions){
+ if (FlxG.save.data.distractions)
+ {
if (!trainMoving)
trainCooldown += 1;
-
+
if (curBeat % 4 == 0)
{
phillyCityLights.forEach(function(light:FlxSprite)
{
light.visible = false;
});
-
+
curLight = FlxG.random.int(0, phillyCityLights.length - 1);
-
+
phillyCityLights.members[curLight].visible = true;
// phillyCityLights.members[curLight].alpha = 1;
- }
-
+ }
}
if (curBeat % 8 == 4 && FlxG.random.bool(30) && !trainMoving && trainCooldown > 8)
{
- if(FlxG.save.data.distractions){
+ if (FlxG.save.data.distractions)
+ {
trainCooldown = FlxG.random.int(-4, 0);
trainStart();
}
@@ -3943,7 +4580,8 @@ class PlayState extends MusicBeatState
if (isHalloween && FlxG.random.bool(10) && curBeat > lightningStrikeBeat + lightningOffset)
{
- if(FlxG.save.data.distractions){
+ if (FlxG.save.data.distractions)
+ {
lightningStrikeShit();
}
}
diff --git a/source/Replay.hx b/source/Replay.hx
index 18ce656..5d88f32 100644
--- a/source/Replay.hx
+++ b/source/Replay.hx
@@ -45,8 +45,10 @@ typedef ReplayJSON =
public var songNotes:Array;
public var songJudgements:Array;
public var noteSpeed:Float;
+ public var chartPath:String;
public var isDownscroll:Bool;
public var sf:Int;
+ public var sm:Bool;
public var ana:Analysis;
}
@@ -66,6 +68,8 @@ class Replay
isDownscroll: false,
songNotes: [],
replayGameVer: version,
+ chartPath: "",
+ sm: false,
timestamp: Date.now(),
sf: Conductor.safeFrames,
ana: new Analysis(),
@@ -86,20 +90,28 @@ class Replay
public function SaveReplay(notearray:Array, judge:Array, ana:Analysis)
{
+ #if sys
+ var chartPath = PlayState.isSM ? PlayState.pathToSm + "/converted.json" : "";
+ #else
+ var chartPath = "";
+ #end
+
var json = {
"songName": PlayState.SONG.song,
"songDiff": PlayState.storyDifficulty,
+ "chartPath": chartPath,
+ "sm": PlayState.isSM,
+ "timestamp": Date.now(),
+ "replayGameVer": version,
+ "sf": Conductor.safeFrames,
"noteSpeed": (FlxG.save.data.scrollSpeed > 1 ? FlxG.save.data.scrollSpeed : PlayState.SONG.speed),
"isDownscroll": FlxG.save.data.downscroll,
"songNotes": notearray,
"songJudgements": judge,
- "timestamp": Date.now(),
- "replayGameVer": version,
- "sf": Conductor.safeFrames,
"ana": ana
};
- var data:String = Json.stringify(json);
+ var data:String = Json.stringify(json, null, "");
var time = Date.now().getTime();
diff --git a/source/ResultsScreen.hx b/source/ResultsScreen.hx
index 255ab8c..be8371e 100644
--- a/source/ResultsScreen.hx
+++ b/source/ResultsScreen.hx
@@ -1,5 +1,10 @@
package;
-
+import haxe.Exception;
+#if sys
+import smTools.SMFile;
+import sys.FileSystem;
+import sys.io.File;
+#end
import openfl.geom.Matrix;
import openfl.display.BitmapData;
import flixel.system.FlxSound;
@@ -54,9 +59,13 @@ class ResultsScreen extends FlxSubState
background.scrollFactor.set();
add(background);
- music = new FlxSound().loadEmbedded(Paths.music('breakfast'), true, true);
- music.volume = 0;
- music.play(false, FlxG.random.int(0, Std.int(music.length / 2)));
+ if (!PlayState.inResults)
+ {
+ music = new FlxSound().loadEmbedded(Paths.music('breakfast'), true, true);
+ music.volume = 0;
+ music.play(false, FlxG.random.int(0, Std.int(music.length / 2)));
+ FlxG.sound.list.add(music);
+ }
background.alpha = 0;
@@ -74,7 +83,7 @@ class ResultsScreen extends FlxSubState
text.text = "Week Cleared!";
}
- comboText = new FlxText(20,-75,0,'Judgements:\nSicks - ${PlayState.sicks}\nGoods - ${PlayState.goods}\nBads - ${PlayState.bads}\n\nCombo Breaks: ${(PlayState.isStoryMode ? PlayState.campaignMisses : PlayState.misses)}\nHighest Combo: ${PlayState.highestCombo + 1}\n\nScore: ${PlayState.instance.songScore}\nAccuracy: ${HelperFunctions.truncateFloat(PlayState.instance.accuracy,2)}%\n\n${Ratings.GenerateLetterRank(PlayState.instance.accuracy)}\n\nF1 - View replay\nF2 - Replay song
+ comboText = new FlxText(20,-75,0,'Judgements:\nSicks - ${PlayState.sicks}\nGoods - ${PlayState.goods}\nBads - ${PlayState.bads}\n\nCombo Breaks: ${(PlayState.isStoryMode ? PlayState.campaignMisses : PlayState.misses)}\nHighest Combo: ${PlayState.highestCombo + 1}\nScore: ${PlayState.instance.songScore}\nAccuracy: ${HelperFunctions.truncateFloat(PlayState.instance.accuracy,2)}%\n\n${Ratings.GenerateLetterRank(PlayState.instance.accuracy)}\n\n${!PlayState.loadRep ? "F1 - View replay\nF2 - Replay song" : ""}
');
comboText.size = 28;
comboText.setBorderStyle(FlxTextBorderStyle.OUTLINE,FlxColor.BLACK,4,1);
@@ -130,7 +139,8 @@ class ResultsScreen extends FlxSubState
var diff = obj[3];
var judge = obj2;
- mean += diff;
+ if (diff != (166 * Math.floor((PlayState.rep.replay.sf / 60) * 1000) / 166))
+ mean += diff;
if (obj[1] != -1)
graph.addToHistory(diff, judge, obj3);
}
@@ -167,8 +177,8 @@ class ResultsScreen extends FlxSubState
override function update(elapsed:Float)
{
- if (music.volume < 0.5)
- music.volume += 0.01 * elapsed;
+ if (music != null && music.volume < 0.5)
+ music.volume += 0.01 * elapsed;
// keybinds
@@ -193,18 +203,20 @@ class ResultsScreen extends FlxSubState
if (PlayState.isStoryMode)
{
FlxG.sound.playMusic(Paths.music('freakyMenu'));
+ Conductor.changeBPM(102);
FlxG.switchState(new MainMenuState());
}
else
FlxG.switchState(new FreeplayState());
}
- if (FlxG.keys.justPressed.F1)
+ if (FlxG.keys.justPressed.F1 && !PlayState.loadRep)
{
trace(PlayState.rep.path);
PlayState.rep = Replay.LoadReplay(PlayState.rep.path);
PlayState.loadRep = true;
+ PlayState.isSM = PlayState.rep.replay.sm;
var songFormat = StringTools.replace(PlayState.rep.replay.songName, " ", "-");
switch (songFormat) {
@@ -226,18 +238,49 @@ class ResultsScreen extends FlxSubState
Highscore.saveCombo(songHighscore, Ratings.GenerateLetterRank(PlayState.instance.accuracy),PlayState.storyDifficulty);
#end
- var poop:String = Highscore.formatSong(songFormat, PlayState.rep.replay.songDiff);
+ #if sys
+ if (PlayState.rep.replay.sm)
+ if (!FileSystem.exists(StringTools.replace(PlayState.rep.replay.chartPath,"converted.json","")))
+ {
+ Application.current.window.alert("The SM file in this replay does not exist!","SM Replays");
+ return;
+ }
+ #end
+
+ var poop = "";
+
+ #if sys
+ if (PlayState.isSM)
+ {
+ poop = File.getContent(PlayState.rep.replay.chartPath);
+ try
+ {
+ PlayState.sm = SMFile.loadFile(PlayState.pathToSm + "/" + StringTools.replace(PlayState.rep.replay.songName," ", "_") + ".sm");
+ }
+ catch(e:Exception)
+ {
+ Application.current.window.alert("Make sure that the SM file is called " + PlayState.pathToSm + "/" + StringTools.replace(PlayState.rep.replay.songName," ", "_") + ".sm!\nAs I couldn't read it.","SM Replays");
+ return;
+ }
+ }
+ else
+ poop = Highscore.formatSong(songFormat, PlayState.rep.replay.songDiff);
+ #else
+ poop = Highscore.formatSong(PlayState.rep.replay.songName, PlayState.rep.replay.songDiff);
+ #end
music.fadeOut(0.3);
- PlayState.SONG = Song.loadFromJson(poop, PlayState.rep.replay.songName);
+ if (PlayState.isSM)
+ PlayState.SONG = Song.loadFromJsonRAW(poop);
+ else
+ PlayState.SONG = Song.loadFromJson(poop, PlayState.rep.replay.songName);
PlayState.isStoryMode = false;
PlayState.storyDifficulty = PlayState.rep.replay.songDiff;
- PlayState.storyWeek = 0;
LoadingState.loadAndSwitchState(new PlayState());
}
- if (FlxG.keys.justPressed.F2 )
+ if (FlxG.keys.justPressed.F2 && !PlayState.loadRep)
{
PlayState.rep = null;
@@ -264,12 +307,12 @@ class ResultsScreen extends FlxSubState
var poop:String = Highscore.formatSong(songFormat, PlayState.storyDifficulty);
- music.fadeOut(0.3);
+ if (music != null)
+ music.fadeOut(0.3);
PlayState.SONG = Song.loadFromJson(poop, PlayState.SONG.song);
PlayState.isStoryMode = false;
PlayState.storyDifficulty = PlayState.storyDifficulty;
- PlayState.storyWeek = 0;
LoadingState.loadAndSwitchState(new PlayState());
}
diff --git a/source/Section.hx b/source/Section.hx
index f153da5..fcb574a 100644
--- a/source/Section.hx
+++ b/source/Section.hx
@@ -2,7 +2,9 @@ package;
typedef SwagSection =
{
- var sectionNotes:Array;
+ var startTime:Float;
+ var endTime:Float;
+ var sectionNotes:Array>;
var lengthInSteps:Int;
var typeOfSection:Int;
var mustHitSection:Bool;
@@ -13,7 +15,9 @@ typedef SwagSection =
class Section
{
- public var sectionNotes:Array = [];
+ public var startTime:Float = 0;
+ public var endTime:Float = 0;
+ public var sectionNotes:Array> = [];
public var lengthInSteps:Int = 16;
public var typeOfSection:Int = 0;
diff --git a/source/SectionRender.hx b/source/SectionRender.hx
new file mode 100644
index 0000000..3410ccb
--- /dev/null
+++ b/source/SectionRender.hx
@@ -0,0 +1,32 @@
+import flixel.FlxG;
+import flixel.util.FlxColor;
+import flixel.group.FlxGroup.FlxTypedGroup;
+import Section.SwagSection;
+import flixel.addons.display.FlxGridOverlay;
+import flixel.FlxSprite;
+
+class SectionRender extends FlxSprite
+{
+ public var section:SwagSection;
+ public var icon:FlxSprite;
+ public var lastUpdated:Bool;
+
+ public function new(x:Float,y:Float,GRID_SIZE:Int, ?Height:Int = 16)
+ {
+ super(x,y);
+
+ makeGraphic(GRID_SIZE * 8, GRID_SIZE * Height,FlxColor.BLACK);
+
+ var h = GRID_SIZE;
+ if (Math.floor(h) != h)
+ h = GRID_SIZE;
+
+ FlxGridOverlay.overlay(this,GRID_SIZE, Std.int(h), GRID_SIZE * 8,GRID_SIZE * Height);
+ }
+
+
+
+ override function update(elapsed)
+ {
+ }
+}
\ No newline at end of file
diff --git a/source/Song.hx b/source/Song.hx
index 5329079..abbec7f 100644
--- a/source/Song.hx
+++ b/source/Song.hx
@@ -7,10 +7,28 @@ import lime.utils.Assets;
using StringTools;
+class Event
+{
+ public var name:String;
+ public var position:Float;
+ public var value:Dynamic;
+ public var type:String;
+
+ public function new(name:String,pos:Float,value:Dynamic,type:String)
+ {
+ this.name = name;
+ this.position = pos;
+ this.value = value;
+ this.type = type;
+ }
+}
+
typedef SwagSong =
{
+ var chartVersion:String;
var song:String;
var notes:Array;
+ var eventObjects:Array;
var bpm:Float;
var needsVoices:Bool;
var speed:Float;
@@ -25,10 +43,12 @@ typedef SwagSong =
class Song
{
+ public var chartVersion:String;
public var song:String;
public var notes:Array;
public var bpm:Float;
public var needsVoices:Bool = true;
+ public var eventObjects:Array;
public var speed:Float = 1;
public var player1:String = 'bf';
@@ -44,10 +64,19 @@ class Song
this.bpm = bpm;
}
+ public static function loadFromJsonRAW(rawJson:String)
+ {
+ while (!rawJson.endsWith("}"))
+ {
+ rawJson = rawJson.substr(0, rawJson.length - 1);
+ // LOL GOING THROUGH THE BULLSHIT TO CLEAN IDK WHATS STRANGE
+ }
+
+ return parseJSONshit(rawJson);
+ }
+
public static function loadFromJson(jsonInput:String, ?folder:String):SwagSong
{
- trace(jsonInput);
-
// pre lowercasing the folder name
var folderLowercase = StringTools.replace(folder, " ", "-").toLowerCase();
switch (folderLowercase) {
diff --git a/source/StoryMenuState.hx b/source/StoryMenuState.hx
index 5957720..ce2d49d 100644
--- a/source/StoryMenuState.hx
+++ b/source/StoryMenuState.hx
@@ -24,18 +24,21 @@ class StoryMenuState extends MusicBeatState
{
var scoreText:FlxText;
- var weekData:Array = [
- ['Tutorial'],
- ['Bopeebo', 'Fresh', 'Dad Battle'],
- ['Spookeez', 'South', "Monster"],
- ['Pico', 'Philly Nice', "Blammed"],
- ['Satin Panties', "High", "Milf"],
- ['Cocoa', 'Eggnog', 'Winter Horrorland'],
- ['Senpai', 'Roses', 'Thorns']
- ];
+ static function weekData():Array
+ {
+ return [
+ ['Tutorial'],
+ ['Bopeebo', 'Fresh', 'Dad Battle'],
+ ['Spookeez', 'South', "Monster"],
+ ['Pico', 'Philly Nice', "Blammed"],
+ ['Satin Panties', "High", "Milf"],
+ ['Cocoa', 'Eggnog', 'Winter Horrorland'],
+ ['Senpai', 'Roses', 'Thorns']
+ ];
+ }
var curDifficulty:Int = 1;
- public static var weekUnlocked:Array = [true, true, true, true, true, true, true];
+ public static var weekUnlocked:Array = [];
var weekCharacters:Array = [
['', 'bf', 'gf'],
@@ -47,15 +50,7 @@ class StoryMenuState extends MusicBeatState
['senpai', 'bf', 'gf']
];
- var weekNames:Array = [
- "",
- "Daddy Dearest",
- "Spooky Month",
- "PICO",
- "MOMMY MUST MURDER",
- "RED SNOW",
- "Hating Simulator ft. Moawling"
- ];
+ var weekNames:Array = CoolUtil.coolTextFile(Paths.txt('data/weekNames'));
var txtWeekTitle:FlxText;
@@ -73,8 +68,28 @@ class StoryMenuState extends MusicBeatState
var leftArrow:FlxSprite;
var rightArrow:FlxSprite;
+ function unlockWeeks():Array
+ {
+ var weeks:Array = [];
+ #if debug
+ for(i in 0...weekNames.length)
+ weeks.push(true);
+ return weeks;
+ #end
+
+ weeks.push(true);
+
+ for(i in 0...FlxG.save.data.weekUnlocked)
+ {
+ weeks.push(true);
+ }
+ return weeks;
+ }
+
override function create()
{
+ weekUnlocked = unlockWeeks();
+
#if windows
// Updating Discord Rich Presence
DiscordClient.changePresence("In the Story Mode Menu", null);
@@ -86,7 +101,10 @@ class StoryMenuState extends MusicBeatState
if (FlxG.sound.music != null)
{
if (!FlxG.sound.music.playing)
+ {
FlxG.sound.playMusic(Paths.music('freakyMenu'));
+ Conductor.changeBPM(102);
+ }
}
persistentUpdate = persistentDraw = true;
@@ -110,17 +128,17 @@ class StoryMenuState extends MusicBeatState
grpWeekText = new FlxTypedGroup