diff --git a/Project.xml b/Project.xml
index cc0b7b41a9f..c73f53496c3 100644
--- a/Project.xml
+++ b/Project.xml
@@ -26,6 +26,7 @@
+
@@ -109,9 +110,9 @@
-
-
-
+
+
+
@@ -121,6 +122,7 @@
+
diff --git a/art/flashFiles/FNF_main_menu_assets_pt-BR.fla b/art/flashFiles/FNF_main_menu_assets_pt-BR.fla
new file mode 100644
index 00000000000..510407f72ff
Binary files /dev/null and b/art/flashFiles/FNF_main_menu_assets_pt-BR.fla differ
diff --git a/art/flashFiles/PsychGF.fla b/art/flashFiles/PsychGF.fla
new file mode 100644
index 00000000000..ae0983cdf5e
Binary files /dev/null and b/art/flashFiles/PsychGF.fla differ
diff --git a/art/flashFiles/PsychGF2.fla b/art/flashFiles/PsychGF2.fla
deleted file mode 100644
index de377c9c3a1..00000000000
Binary files a/art/flashFiles/PsychGF2.fla and /dev/null differ
diff --git a/assets/base_game/shared/data/2hot/preload.json b/assets/base_game/shared/data/2hot/preload.json
new file mode 100644
index 00000000000..66e2f8c5850
--- /dev/null
+++ b/assets/base_game/shared/data/2hot/preload.json
@@ -0,0 +1,12 @@
+{
+ "images/spraycanAtlas/": 3,
+ "images/PicoBullet": 2,
+ "images/spraypaintExplosionEZ": 3,
+
+ "sounds/Darnell_Lighter": 3,
+ "sounds/Kick_Can_UP": 3,
+ "sounds/Kick_Can_FORWARD": 3,
+ "sounds/Gun_Prep": 3,
+ "sounds/Pico_Bonk": 3,
+ "sounds/shots/": 3
+}
\ No newline at end of file
diff --git a/assets/base_game/shared/data/stress/preload.json b/assets/base_game/shared/data/stress/preload.json
index 5b0ecc2b36f..e318045f208 100644
--- a/assets/base_game/shared/data/stress/preload.json
+++ b/assets/base_game/shared/data/stress/preload.json
@@ -1,3 +1,3 @@
{
- "images": ["tankmanKilled1"]
+ "images/tankmanKilled1": 3
}
\ No newline at end of file
diff --git a/assets/base_game/shared/stages/phillyBlazin.json b/assets/base_game/shared/stages/phillyBlazin.json
index f96aee9c5d2..25ddd2c8770 100644
--- a/assets/base_game/shared/stages/phillyBlazin.json
+++ b/assets/base_game/shared/stages/phillyBlazin.json
@@ -20,7 +20,9 @@
"images/phillyBlazin/streetBlur": 3,
"images/phillyBlazin/skyBlur": 2,
- "images/phillyBlazin/lightning": 2
+ "images/phillyBlazin/lightning": 2,
+
+ "sounds/lightning/": 3
},
"_editorMeta": {
diff --git a/assets/base_game/shared/stages/phillyStreets.json b/assets/base_game/shared/stages/phillyStreets.json
index af10c9bfe37..26ba43b454a 100644
--- a/assets/base_game/shared/stages/phillyStreets.json
+++ b/assets/base_game/shared/stages/phillyStreets.json
@@ -18,6 +18,7 @@
"images/abot/systemEyes/": 3,
"images/abot/abotSystem/": 3,
+ "images/SpraycanPile": 3,
"images/phillyStreets/phillyConstruction": 3,
"images/phillyStreets/phillyHighwayLights": 3,
"images/phillyStreets/phillyHighway": 3,
diff --git a/assets/base_game/weekend1/sounds/Shoot_1.ogg b/assets/base_game/weekend1/sounds/Shoot_1.ogg
deleted file mode 100644
index 93e10003ade..00000000000
Binary files a/assets/base_game/weekend1/sounds/Shoot_1.ogg and /dev/null differ
diff --git a/assets/base_game/weekend1/sounds/fuse_burning.ogg b/assets/base_game/weekend1/sounds/fuse_burning.ogg
deleted file mode 100644
index 9813d0785ae..00000000000
Binary files a/assets/base_game/weekend1/sounds/fuse_burning.ogg and /dev/null differ
diff --git a/assets/base_game/weekend1/sounds/Lightning1.ogg b/assets/base_game/weekend1/sounds/lightning/Lightning1.ogg
similarity index 100%
rename from assets/base_game/weekend1/sounds/Lightning1.ogg
rename to assets/base_game/weekend1/sounds/lightning/Lightning1.ogg
diff --git a/assets/base_game/weekend1/sounds/Lightning2.ogg b/assets/base_game/weekend1/sounds/lightning/Lightning2.ogg
similarity index 100%
rename from assets/base_game/weekend1/sounds/Lightning2.ogg
rename to assets/base_game/weekend1/sounds/lightning/Lightning2.ogg
diff --git a/assets/base_game/weekend1/sounds/Lightning3.ogg b/assets/base_game/weekend1/sounds/lightning/Lightning3.ogg
similarity index 100%
rename from assets/base_game/weekend1/sounds/Lightning3.ogg
rename to assets/base_game/weekend1/sounds/lightning/Lightning3.ogg
diff --git a/assets/base_game/weekend1/sounds/shot1.ogg b/assets/base_game/weekend1/sounds/shots/shot1.ogg
similarity index 100%
rename from assets/base_game/weekend1/sounds/shot1.ogg
rename to assets/base_game/weekend1/sounds/shots/shot1.ogg
diff --git a/assets/base_game/weekend1/sounds/shot2.ogg b/assets/base_game/weekend1/sounds/shots/shot2.ogg
similarity index 100%
rename from assets/base_game/weekend1/sounds/shot2.ogg
rename to assets/base_game/weekend1/sounds/shots/shot2.ogg
diff --git a/assets/base_game/weekend1/sounds/shot3.ogg b/assets/base_game/weekend1/sounds/shots/shot3.ogg
similarity index 100%
rename from assets/base_game/weekend1/sounds/shot3.ogg
rename to assets/base_game/weekend1/sounds/shots/shot3.ogg
diff --git a/assets/base_game/weekend1/sounds/shot4.ogg b/assets/base_game/weekend1/sounds/shots/shot4.ogg
similarity index 100%
rename from assets/base_game/weekend1/sounds/shot4.ogg
rename to assets/base_game/weekend1/sounds/shots/shot4.ogg
diff --git a/assets/base_game/weekend1/sounds/singed_loop.ogg b/assets/base_game/weekend1/sounds/singed_loop.ogg
deleted file mode 100644
index b3e597ae603..00000000000
Binary files a/assets/base_game/weekend1/sounds/singed_loop.ogg and /dev/null differ
diff --git a/assets/secrets/images/PessyBump.png b/assets/secrets/images/PessyBump.png
new file mode 100644
index 00000000000..107f29c38c2
Binary files /dev/null and b/assets/secrets/images/PessyBump.png differ
diff --git a/assets/secrets/images/PessyBump.xml b/assets/secrets/images/PessyBump.xml
new file mode 100644
index 00000000000..4cf63c83fbe
--- /dev/null
+++ b/assets/secrets/images/PessyBump.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/secrets/images/RiverBump.png b/assets/secrets/images/RiverBump.png
deleted file mode 100644
index 44f978fd22b..00000000000
Binary files a/assets/secrets/images/RiverBump.png and /dev/null differ
diff --git a/assets/secrets/images/RiverBump.xml b/assets/secrets/images/RiverBump.xml
deleted file mode 100644
index 38c73e44bc5..00000000000
--- a/assets/secrets/images/RiverBump.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/assets/secrets/images/ShadowBump.xml b/assets/secrets/images/ShadowBump.xml
index b3d6293377a..16b32cba941 100644
--- a/assets/secrets/images/ShadowBump.xml
+++ b/assets/secrets/images/ShadowBump.xml
@@ -8,4 +8,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/secrets/images/ZRiverBump.png b/assets/secrets/images/ZRiverBump.png
new file mode 100644
index 00000000000..19f096b36fc
Binary files /dev/null and b/assets/secrets/images/ZRiverBump.png differ
diff --git a/assets/secrets/images/ZRiverBump.xml b/assets/secrets/images/ZRiverBump.xml
new file mode 100644
index 00000000000..6394744e5e2
--- /dev/null
+++ b/assets/secrets/images/ZRiverBump.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/secrets/sounds/JinglePessy.mp3 b/assets/secrets/sounds/JinglePessy.mp3
new file mode 100644
index 00000000000..81d0b9b3419
Binary files /dev/null and b/assets/secrets/sounds/JinglePessy.mp3 differ
diff --git a/assets/secrets/sounds/JinglePessy.ogg b/assets/secrets/sounds/JinglePessy.ogg
new file mode 100644
index 00000000000..3e3e7bdd5dc
Binary files /dev/null and b/assets/secrets/sounds/JinglePessy.ogg differ
diff --git a/assets/secrets/sounds/JingleRiver.mp3 b/assets/secrets/sounds/JingleRiver.mp3
index adeffde4e3b..385ebca73d5 100644
Binary files a/assets/secrets/sounds/JingleRiver.mp3 and b/assets/secrets/sounds/JingleRiver.mp3 differ
diff --git a/assets/secrets/sounds/JingleRiver.ogg b/assets/secrets/sounds/JingleRiver.ogg
index d679905e2ff..52a565a3580 100644
Binary files a/assets/secrets/sounds/JingleRiver.ogg and b/assets/secrets/sounds/JingleRiver.ogg differ
diff --git a/assets/shared/images/achievements/pessy_easter_egg.png b/assets/shared/images/achievements/pessy_easter_egg.png
new file mode 100644
index 00000000000..02362f5e95b
Binary files /dev/null and b/assets/shared/images/achievements/pessy_easter_egg.png differ
diff --git a/assets/shared/images/achievements/weekend1_nomiss.png b/assets/shared/images/achievements/weekend1_nomiss.png
new file mode 100644
index 00000000000..3c1a17f8de3
Binary files /dev/null and b/assets/shared/images/achievements/weekend1_nomiss.png differ
diff --git a/assets/shared/images/credits/majigsaw.png b/assets/shared/images/credits/majigsaw.png
new file mode 100644
index 00000000000..48a84e97f3e
Binary files /dev/null and b/assets/shared/images/credits/majigsaw.png differ
diff --git a/assets/shared/images/gfDanceTitle.json b/assets/shared/images/gfDanceTitle.json
index b3a304adf2b..bb5fe726e9b 100644
--- a/assets/shared/images/gfDanceTitle.json
+++ b/assets/shared/images/gfDanceTitle.json
@@ -1,10 +1,15 @@
{
- "titlex":-150,
- "titley":-100,
- "startx":100,
- "starty":576,
- "gfx":512,
- "gfy":40,
- "backgroundSprite":"",
- "bpm":102
+ "titlex": -150,
+ "titley": -100,
+ "startx": 100,
+ "starty": 576,
+ "gfx": 512,
+ "gfy": 40,
+ "backgroundSprite": "",
+ "bpm": 102,
+
+ "animation": "gfDance",
+ "dance_left": [30, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14],
+ "dance_right": [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
+ "idle": false
}
\ No newline at end of file
diff --git a/assets/shared/images/noteSplashes/noteSplashes-diamond.json b/assets/shared/images/noteSplashes/noteSplashes-diamond.json
index 2517fd70121..720742a050e 100644
--- a/assets/shared/images/noteSplashes/noteSplashes-diamond.json
+++ b/assets/shared/images/noteSplashes/noteSplashes-diamond.json
@@ -6,9 +6,11 @@
95,
68
],
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"prefix": "note splash diamond purple 10",
- "minFps": 22,
"name": "purple",
"indices": []
},
@@ -18,9 +20,11 @@
106,
60
],
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"prefix": "note splash diamond blue 20",
- "minFps": 22,
"name": "blue2",
"indices": []
},
@@ -30,9 +34,11 @@
106,
60
],
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"prefix": "note splash diamond red 20",
- "minFps": 22,
"name": "red2",
"indices": []
},
@@ -42,9 +48,11 @@
95,
68
],
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"prefix": "note splash diamond red 10",
- "minFps": 22,
"name": "red",
"indices": []
},
@@ -54,9 +62,11 @@
106,
60
],
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"prefix": "note splash diamond purple 20",
- "minFps": 22,
"name": "purple2",
"indices": []
},
@@ -66,9 +76,11 @@
95,
68
],
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"prefix": "note splash diamond blue 10",
- "minFps": 22,
"name": "blue",
"indices": []
},
@@ -78,9 +90,11 @@
106,
60
],
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"prefix": "note splash diamond green 20",
- "minFps": 22,
"name": "green2",
"indices": []
},
@@ -90,16 +104,16 @@
95,
68
],
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"prefix": "note splash diamond green 10",
- "minFps": 22,
"name": "green",
"indices": []
}
},
- "affectedByShader": true,
- "scale": [
- 1,
- 1
- ]
+ "allowRGB": true,
+ "allowPixel": true,
+ "scale": 1
}
\ No newline at end of file
diff --git a/assets/shared/images/noteSplashes/noteSplashes-electric.json b/assets/shared/images/noteSplashes/noteSplashes-electric.json
index f18a7fe0c82..430ab3d4866 100644
--- a/assets/shared/images/noteSplashes/noteSplashes-electric.json
+++ b/assets/shared/images/noteSplashes/noteSplashes-electric.json
@@ -6,11 +6,13 @@
62
],
"noteData": 0,
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"prefix": "splash electro purple 10",
"indices": [],
- "name": "purple",
- "minFps": 22
+ "name": "purple"
},
"blue": {
"offsets": [
@@ -18,11 +20,13 @@
62
],
"noteData": 1,
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"prefix": "splash electro blue 10",
"indices": [],
- "name": "blue",
- "minFps": 22
+ "name": "blue"
},
"red": {
"offsets": [
@@ -30,11 +34,13 @@
62
],
"noteData": 3,
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"prefix": "splash electro red 10",
"indices": [],
- "name": "red",
- "minFps": 22
+ "name": "red"
},
"green": {
"offsets": [
@@ -42,14 +48,17 @@
62
],
"noteData": 2,
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"prefix": "splash electro green 10",
"indices": [],
- "name": "green",
- "minFps": 22
+ "name": "green"
}
},
- "affectedByShader": true,
+ "allowRGB": true,
+ "allowPixel": true,
"rgb": [
{
"b": 0,
@@ -63,8 +72,5 @@
},
null
],
- "scale": [
- 1,
- 1
- ]
+ "scale": 1
}
\ No newline at end of file
diff --git a/assets/shared/images/noteSplashes/noteSplashes-sparkles.json b/assets/shared/images/noteSplashes/noteSplashes-sparkles.json
index a87aeabc3cb..7b4080ce132 100644
--- a/assets/shared/images/noteSplashes/noteSplashes-sparkles.json
+++ b/assets/shared/images/noteSplashes/noteSplashes-sparkles.json
@@ -6,11 +6,13 @@
68
],
"noteData": 1,
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"prefix": "splash sparkles blue 10",
"indices": [],
- "name": "blue",
- "minFps": 22
+ "name": "blue"
},
"purple": {
"offsets": [
@@ -18,23 +20,27 @@
68
],
"noteData": 0,
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"prefix": "splash sparkles purple 10",
"indices": [],
- "name": "purple",
- "minFps": 22
+ "name": "purple"
},
"green": {
"prefix": "splash sparkles green 10",
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"offsets": [
70,
70
],
"indices": [],
"name": "green",
- "noteData": 2,
- "minFps": 22
+ "noteData": 2
},
"red": {
"offsets": [
@@ -42,16 +48,16 @@
68
],
"noteData": 3,
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"prefix": "splash sparkles red 10",
"indices": [],
- "name": "red",
- "minFps": 22
+ "name": "red"
}
},
- "affectedByShader": true,
- "scale": [
- 1,
- 1
- ]
+ "allowRGB": true,
+ "allowPixel": true,
+ "scale": 1
}
\ No newline at end of file
diff --git a/assets/shared/images/noteSplashes/noteSplashes-vanilla.json b/assets/shared/images/noteSplashes/noteSplashes-vanilla.json
index 6885937ab6e..5aec3c950d3 100644
--- a/assets/shared/images/noteSplashes/noteSplashes-vanilla.json
+++ b/assets/shared/images/noteSplashes/noteSplashes-vanilla.json
@@ -6,9 +6,11 @@
95,
105
],
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"prefix": "vanilla splash purple 10",
- "minFps": 22,
"name": "purple",
"indices": []
},
@@ -18,9 +20,11 @@
105,
90
],
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"prefix": "vanilla splash blue 20",
- "minFps": 22,
"name": "blue2",
"indices": []
},
@@ -30,9 +34,11 @@
95,
100
],
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"prefix": "vanilla splash red 20",
- "minFps": 22,
"name": "red2",
"indices": []
},
@@ -42,9 +48,11 @@
80,
100
],
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"prefix": "vanilla splash red 10",
- "minFps": 22,
"name": "red",
"indices": []
},
@@ -54,9 +62,11 @@
105,
90
],
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"prefix": "vanilla splash purple 20",
- "minFps": 22,
"name": "purple2",
"indices": []
},
@@ -66,9 +76,11 @@
87,
103
],
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"prefix": "vanilla splash blue 10",
- "minFps": 22,
"name": "blue",
"indices": []
},
@@ -78,9 +90,11 @@
94,
100
],
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"prefix": "vanilla splash green 20",
- "minFps": 22,
"name": "green2",
"indices": []
},
@@ -90,16 +104,16 @@
90,
100
],
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"prefix": "vanilla splash green 10",
- "minFps": 22,
"name": "green",
"indices": []
}
},
- "affectedByShader": true,
- "scale": [
- 1,
- 1
- ]
+ "allowRGB": true,
+ "allowPixel": true,
+ "scale": 1
}
\ No newline at end of file
diff --git a/assets/shared/images/noteSplashes/noteSplashes.json b/assets/shared/images/noteSplashes/noteSplashes.json
index 1315a1fd935..a1769d603d2 100644
--- a/assets/shared/images/noteSplashes/noteSplashes.json
+++ b/assets/shared/images/noteSplashes/noteSplashes.json
@@ -2,104 +2,118 @@
"animations": {
"blue2": {
"prefix": "note splash blue 20",
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"offsets": [
70,
76
],
"indices": [],
"name": "blue2",
- "noteData": 5,
- "minFps": 22
+ "noteData": 5
},
"purple": {
"prefix": "note splash purple 10",
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"offsets": [
60,
60
],
"indices": [],
"name": "purple",
- "noteData": 0,
- "minFps": 22
+ "noteData": 0
},
"red": {
"prefix": "note splash red 10",
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"offsets": [
57,
58
],
"indices": [],
"name": "red",
- "noteData": 3,
- "minFps": 22
+ "noteData": 3
},
"red2": {
"prefix": "note splash red 20",
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"offsets": [
66,
80
],
"indices": [],
"name": "red2",
- "noteData": 7,
- "minFps": 22
+ "noteData": 7
},
"blue": {
"prefix": "note splash blue 10",
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"offsets": [
55,
60
],
"indices": [],
"name": "blue",
- "noteData": 1,
- "minFps": 22
+ "noteData": 1
},
"purple2": {
"prefix": "note splash purple 20",
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"offsets": [
76,
80
],
"indices": [],
"name": "purple2",
- "noteData": 4,
- "minFps": 22
+ "noteData": 4
},
"green": {
"prefix": "note splash green 10",
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"offsets": [
57,
61
],
"indices": [],
"name": "green",
- "noteData": 2,
- "minFps": 22
+ "noteData": 2
},
"green2": {
"prefix": "note splash green 20",
- "maxFps": 26,
+ "fps": [
+ 22,
+ 26
+ ],
"offsets": [
70,
80
],
"indices": [],
"name": "green2",
- "noteData": 6,
- "minFps": 22
+ "noteData": 6
}
},
- "affectedByShader": true,
- "scale": [
- 1,
- 1
- ]
+ "allowRGB": true,
+ "allowPixel": true,
+ "scale": 1
}
\ No newline at end of file
diff --git a/assets/translations/shared/data/pt-BR.lang b/assets/translations/shared/data/pt-BR.lang
index c2d43f96200..d3df9f86005 100644
--- a/assets/translations/shared/data/pt-BR.lang
+++ b/assets/translations/shared/data/pt-BR.lang
@@ -36,9 +36,8 @@ charting_mode: "Modo Charter"
blueballed: "Broxadas: {1}"
// Main Menu
-images/mainmenu/menu_story_mode: "images/mainmenu/menu_story_mode"
-images/mainmenu/menu_freeplay: "images/mainmenu/menu_freeplay"
-images/mainmenu/menu_credits: "images/mainmenu/menu_credits"
+images/mainmenu/menu_story_mode: "images/pt-BR/mainmenu/menu_story_mode"
+images/mainmenu/menu_credits: "images/pt-BR/mainmenu/menu_credits"
// Story Mode
images/Menu_Tracks: "images/pt-BR/Menu_Tracks"
@@ -87,6 +86,8 @@ achievement_week6_nomiss: "Novo Recorde!!"
description_week6_nomiss: "Complete a Week 6 no Modo Difícil e sem errar."
achievement_week7_nomiss: "Filho da P..."
description_week7_nomiss: "Complete a Week 7 no Modo Difícil e sem errar."
+achievement_weekend1_nomiss: "Briga sem Perder Amizade"
+description_weekend1_nomiss: "Complete a Weekend 1 no Modo Difícil e sem errar."
achievement_ur_bad: "Pontuação Desastrosa!"
description_ur_bad: "Complete uma Música com uma precisão menor que 20%."
achievement_ur_good: "Perfeccionista"
@@ -103,6 +104,8 @@ achievement_toastie: "PC de Torradeira"
description_toastie: "Jogando num belo de um PC da Xuxa, hein?"
achievement_debugger: "Modo Debug"
description_debugger: "Complete a Música "Test" através do Chart Editor."
+achievement_pessy_easter_egg: "Garota de Programação"
+description_pessy_easter_egg: "Hihi, você me encontrou~!"
// Options
options_note_colors: "Coloração das Notas"
diff --git a/assets/translations/shared/images/pt-BR/mainmenu/menu_credits.png b/assets/translations/shared/images/pt-BR/mainmenu/menu_credits.png
new file mode 100644
index 00000000000..dad10588a69
Binary files /dev/null and b/assets/translations/shared/images/pt-BR/mainmenu/menu_credits.png differ
diff --git a/assets/translations/shared/images/pt-BR/mainmenu/menu_credits.xml b/assets/translations/shared/images/pt-BR/mainmenu/menu_credits.xml
new file mode 100644
index 00000000000..eba93d05b18
--- /dev/null
+++ b/assets/translations/shared/images/pt-BR/mainmenu/menu_credits.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/translations/shared/images/pt-BR/mainmenu/menu_story_mode.png b/assets/translations/shared/images/pt-BR/mainmenu/menu_story_mode.png
new file mode 100644
index 00000000000..217229a174f
Binary files /dev/null and b/assets/translations/shared/images/pt-BR/mainmenu/menu_story_mode.png differ
diff --git a/assets/translations/shared/images/pt-BR/mainmenu/menu_story_mode.xml b/assets/translations/shared/images/pt-BR/mainmenu/menu_story_mode.xml
new file mode 100644
index 00000000000..da33d60d80b
--- /dev/null
+++ b/assets/translations/shared/images/pt-BR/mainmenu/menu_story_mode.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/setup/unix.sh b/setup/unix.sh
index 678c189cd6d..c3477882abc 100755
--- a/setup/unix.sh
+++ b/setup/unix.sh
@@ -3,19 +3,21 @@
# REMINDER THAT YOU NEED HAXE INSTALLED PRIOR TO USING THIS
# https://haxe.org/download
cd ..
+echo Makking the main haxelib and setuping folder in same time..
+mkdir ~/haxelib && haxelib setup ~/haxelib
echo Installing dependencies...
echo This might take a few moments depending on your internet speed.
haxelib install lime 8.1.2
haxelib install openfl 9.3.3
haxelib install flixel 5.6.1
haxelib install flixel-addons 3.2.2
-haxelib install flixel-tools 1.5.1
-haxelib install SScript 17.1.618
+haxelib install flixel-tools 1.5.1
+haxelib install hscript-iris 1.1.0
haxelib install tjson 1.4.0
+haxelib install hxdiscord_rpc 1.2.4
+haxelib install hxvlc 1.8.2
haxelib git flxanimate https://github.com/Dot-Stuff/flxanimate 768740a56b26aa0c072720e0d1236b94afe68e3e
-haxelib git linc_luajit https://github.com/superpowers04/linc_luajit 633fcc051399afed6781dd60cbf30ed8c3fe2c5a
-haxelib git hxdiscord_rpc https://github.com/MAJigsaw77/hxdiscord_rpc 3538a1c2bb07b04208cd014220207f8173acdb21
-haxelib git hxvlc https://github.com/MAJigsaw77/hxvlc 70e7f5f3e76d526ac6fb8f0e6665efe7dfda589d
-haxelib git funkin.vis https://github.com/FunkinCrew/funkVis d5361037efa3a02c4ab20b5bd14ca11e7d00f519
+haxelib git linc_luajit https://github.com/superpowers04/linc_luajit 1906c4a96f6bb6df66562b3f24c62f4c5bba14a7
+haxelib git funkin.vis https://github.com/FunkinCrew/funkVis 22b1ce089dd924f15cdc4632397ef3504d464e90
haxelib git grig.audio https://gitlab.com/haxe-grig/grig.audio.git cbf91e2180fd2e374924fe74844086aab7891666
-echo Finished!
\ No newline at end of file
+echo Finished!
diff --git a/setup/windows.bat b/setup/windows.bat
index 6762cd7d906..f998fe85c9a 100644
--- a/setup/windows.bat
+++ b/setup/windows.bat
@@ -9,13 +9,13 @@ haxelib install openfl 9.3.3
haxelib install flixel 5.6.1
haxelib install flixel-addons 3.2.2
haxelib install flixel-tools 1.5.1
-haxelib install SScript 17.1.618
+haxelib install hscript-iris 1.1.0
haxelib install tjson 1.4.0
+haxelib install hxdiscord_rpc 1.2.4
+haxelib install hxvlc 1.8.2
haxelib git flxanimate https://github.com/Dot-Stuff/flxanimate 768740a56b26aa0c072720e0d1236b94afe68e3e
-haxelib git linc_luajit https://github.com/superpowers04/linc_luajit 633fcc051399afed6781dd60cbf30ed8c3fe2c5a
-haxelib git hxdiscord_rpc https://github.com/MAJigsaw77/hxdiscord_rpc 3538a1c2bb07b04208cd014220207f8173acdb21
-haxelib git hxvlc https://github.com/MAJigsaw77/hxvlc 70e7f5f3e76d526ac6fb8f0e6665efe7dfda589d
-haxelib git funkin.vis https://github.com/FunkinCrew/funkVis d5361037efa3a02c4ab20b5bd14ca11e7d00f519
+haxelib git linc_luajit https://github.com/superpowers04/linc_luajit 1906c4a96f6bb6df66562b3f24c62f4c5bba14a7
+haxelib git funkin.vis https://github.com/FunkinCrew/funkVis 22b1ce089dd924f15cdc4632397ef3504d464e90
haxelib git grig.audio https://gitlab.com/haxe-grig/grig.audio.git cbf91e2180fd2e374924fe74844086aab7891666
echo Finished!
pause
diff --git a/source/backend/Achievements.hx b/source/backend/Achievements.hx
index e72d189f733..aac0c787a25 100644
--- a/source/backend/Achievements.hx
+++ b/source/backend/Achievements.hx
@@ -22,6 +22,13 @@ typedef Achievement =
@:optional var ID:Int;
}
+enum abstract AchievementOp(String)
+{
+ var GET = 'get';
+ var SET = 'set';
+ var ADD = 'add';
+}
+
class Achievements {
public static function init()
{
@@ -33,6 +40,7 @@ class Achievements {
createAchievement('week5_nomiss', {name: "Missless Christmas", description: "Beat Week 5 on Hard with no Misses."});
createAchievement('week6_nomiss', {name: "Highscore!!", description: "Beat Week 6 on Hard with no Misses."});
createAchievement('week7_nomiss', {name: "God Effing Damn It!", description: "Beat Week 7 on Hard with no Misses."});
+ createAchievement('weekend1_nomiss', {name: "Just a Friendly Sparring", description: "Beat Weekend 1 on Hard with no Misses."});
createAchievement('ur_bad', {name: "What a Funkin' Disaster!", description: "Complete a Song with a rating lower than 20%."});
createAchievement('ur_good', {name: "Perfectionist", description: "Complete a Song with a rating of 100%."});
createAchievement('roadkill_enthusiast', {name: "Roadkill Enthusiast", description: "Watch the Henchmen die 50 times.", maxScore: 50, maxDecimals: 0});
@@ -41,6 +49,7 @@ class Achievements {
createAchievement('two_keys', {name: "Just the Two of Us", description: "Finish a Song pressing only two keys."});
createAchievement('toastie', {name: "Toaster Gamer", description: "Have you tried to run the game on a toaster?"});
createAchievement('debugger', {name: "Debugger", description: "Beat the \"Test\" Stage from the Chart Editor.", hidden: true});
+ createAchievement('pessy_easter_egg', {name: "Engine Gal Pal", description: "Teehee, you found me~!", hidden: true});
//dont delete this thing below
_originalLength = _sortID + 1;
@@ -85,16 +94,15 @@ class Achievements {
}
public static function getScore(name:String):Float
- return _scoreFunc(name, 0);
+ return _scoreFunc(name, GET);
public static function setScore(name:String, value:Float, saveIfNotUnlocked:Bool = true):Float
- return _scoreFunc(name, 1, value, saveIfNotUnlocked);
+ return _scoreFunc(name, SET, value, saveIfNotUnlocked);
public static function addScore(name:String, value:Float = 1, saveIfNotUnlocked:Bool = true):Float
- return _scoreFunc(name, 2, value, saveIfNotUnlocked);
+ return _scoreFunc(name, ADD, value, saveIfNotUnlocked);
- //mode 0 = get, 1 = set, 2 = add
- static function _scoreFunc(name:String, mode:Int = 0, addOrSet:Float = 1, saveIfNotUnlocked:Bool = true):Float
+ static function _scoreFunc(name:String, mode:AchievementOp, addOrSet:Float = 1, saveIfNotUnlocked:Bool = true):Float
{
if(!variables.exists(name))
variables.set(name, 0);
@@ -109,8 +117,9 @@ class Achievements {
var val = addOrSet;
switch(mode)
{
- case 0: return variables.get(name); //get
- case 2: val += variables.get(name); //add
+ case GET: return variables.get(name); //get
+ case ADD: val += variables.get(name); //add
+ default:
}
if(val >= achievement.maxScore)
@@ -277,7 +286,7 @@ class Achievements {
}
return getScore(name);
});
- Lua_helper.add_callback(lua, "setAchievementScore", function(name:String, ?value:Float = 1, ?saveIfNotUnlocked:Bool = true):Float
+ Lua_helper.add_callback(lua, "setAchievementScore", function(name:String, ?value:Float = 0, ?saveIfNotUnlocked:Bool = true):Float
{
if(!achievements.exists(name))
{
diff --git a/source/backend/CoolUtil.hx b/source/backend/CoolUtil.hx
index 443224e3aec..7babc16f9da 100644
--- a/source/backend/CoolUtil.hx
+++ b/source/backend/CoolUtil.hx
@@ -64,14 +64,16 @@ class CoolUtil
inline public static function dominantColor(sprite:flixel.FlxSprite):Int
{
var countByColor:Map = [];
- for(col in 0...sprite.frameWidth) {
- for(row in 0...sprite.frameHeight) {
- var colorOfThisPixel:Int = sprite.pixels.getPixel32(col, row);
- if(colorOfThisPixel != 0) {
- if(countByColor.exists(colorOfThisPixel))
- countByColor[colorOfThisPixel] = countByColor[colorOfThisPixel] + 1;
- else if(countByColor[colorOfThisPixel] != 13520687 - (2*13520687))
- countByColor[colorOfThisPixel] = 1;
+ for(col in 0...sprite.frameWidth)
+ {
+ for(row in 0...sprite.frameHeight)
+ {
+ var colorOfThisPixel:FlxColor = sprite.pixels.getPixel32(col, row);
+ if(colorOfThisPixel.alphaFloat > 0.05)
+ {
+ colorOfThisPixel = FlxColor.fromRGB(colorOfThisPixel.red, colorOfThisPixel.green, colorOfThisPixel.blue, 255);
+ var count:Int = countByColor.exists(colorOfThisPixel) ? countByColor[colorOfThisPixel] : 0;
+ countByColor[colorOfThisPixel] = count + 1;
}
}
}
@@ -79,9 +81,11 @@ class CoolUtil
var maxCount = 0;
var maxKey:Int = 0; //after the loop this will store the max color
countByColor[FlxColor.BLACK] = 0;
- for(key in countByColor.keys()) {
- if(countByColor[key] >= maxCount) {
- maxCount = countByColor[key];
+ for(key => count in countByColor)
+ {
+ if(count >= maxCount)
+ {
+ maxCount = count;
maxKey = key;
}
}
diff --git a/source/backend/Language.hx b/source/backend/Language.hx
index f23e9906328..02f03ffd226 100644
--- a/source/backend/Language.hx
+++ b/source/backend/Language.hx
@@ -77,8 +77,10 @@ class Language
// More optimized for file loading
inline public static function getFileTranslation(key:String)
{
+ #if TRANSLATIONS_ALLOWED
var str:String = phrases.get(key.trim().toLowerCase());
if(str != null) key = str;
+ #end
return key;
}
diff --git a/source/backend/Mods.hx b/source/backend/Mods.hx
index 4951d305616..39eb6e1ea82 100644
--- a/source/backend/Mods.hx
+++ b/source/backend/Mods.hx
@@ -92,11 +92,16 @@ class Mods
inline public static function directoriesWithFile(path:String, fileToFind:String, mods:Bool = true)
{
var foldersToCheck:Array = [];
- #if sys
if(FileSystem.exists(path + fileToFind))
- #end
foldersToCheck.push(path + fileToFind);
+ if(Paths.currentLevel != null && Paths.currentLevel != path)
+ {
+ var pth:String = Paths.getFolderPath(fileToFind, Paths.currentLevel);
+ if(FileSystem.exists(pth))
+ foldersToCheck.push(pth);
+ }
+
#if MODS_ALLOWED
if(mods)
{
diff --git a/source/backend/MusicBeatState.hx b/source/backend/MusicBeatState.hx
index 751ec0629e2..d70e332d506 100644
--- a/source/backend/MusicBeatState.hx
+++ b/source/backend/MusicBeatState.hx
@@ -34,7 +34,7 @@ class MusicBeatState extends FlxState
super.create();
if(!skip) {
- openSubState(new CustomFadeTransition(0.6, true));
+ openSubState(new CustomFadeTransition(0.5, true));
}
FlxTransitionableState.skipNextTransOut = false;
timePassedOnState = 0;
@@ -156,7 +156,7 @@ class MusicBeatState extends FlxState
if(nextState == null)
nextState = FlxG.state;
- FlxG.state.openSubState(new CustomFadeTransition(0.6, false));
+ FlxG.state.openSubState(new CustomFadeTransition(0.5, false));
if(nextState == FlxG.state)
CustomFadeTransition.finishCallback = function() FlxG.resetState();
else
diff --git a/source/backend/Paths.hx b/source/backend/Paths.hx
index 83f926dd1be..4079a13c9a7 100644
--- a/source/backend/Paths.hx
+++ b/source/backend/Paths.hx
@@ -173,9 +173,7 @@ class Paths
public static var currentTrackedAssets:Map = [];
static public function image(key:String, ?parentFolder:String = null, ?allowGPU:Bool = true):FlxGraphic
{
- key = Language.getFileTranslation('images/$key');
- if(key.lastIndexOf('.') < 0) key += '.png';
-
+ key = Language.getFileTranslation('images/$key') + '.png';
var bitmap:BitmapData = null;
if (currentTrackedAssets.exists(key))
{
@@ -293,9 +291,29 @@ class Paths
}
return getPackerAtlas(key, parentFolder);
}
+
+ static public function getMultiAtlas(keys:Array, ?parentFolder:String = null, ?allowGPU:Bool = true):FlxAtlasFrames
+ {
+
+ var parentFrames:FlxAtlasFrames = Paths.getAtlas(keys[0].trim());
+ if(keys.length > 1)
+ {
+ var original:FlxAtlasFrames = parentFrames;
+ parentFrames = new FlxAtlasFrames(parentFrames.parent);
+ parentFrames.addAtlas(original, true);
+ for (i in 1...keys.length)
+ {
+ var extraFrames:FlxAtlasFrames = Paths.getAtlas(keys[i].trim(), parentFolder, allowGPU);
+ if(extraFrames != null)
+ parentFrames.addAtlas(extraFrames, true);
+ }
+ }
+ return parentFrames;
+ }
inline static public function getSparrowAtlas(key:String, ?parentFolder:String = null, ?allowGPU:Bool = true):FlxAtlasFrames
{
+ if(key.contains('psychic')) trace(key, parentFolder, allowGPU);
var imageLoaded:FlxGraphic = image(key, parentFolder, allowGPU);
#if MODS_ALLOWED
var xmlExists:Bool = false;
@@ -303,9 +321,9 @@ class Paths
var xml:String = modsXml(key);
if(FileSystem.exists(xml)) xmlExists = true;
- return FlxAtlasFrames.fromSparrow(imageLoaded, (xmlExists ? File.getContent(xml) : getPath('images/$key.xml', TEXT, parentFolder)));
+ return FlxAtlasFrames.fromSparrow(imageLoaded, (xmlExists ? File.getContent(xml) : getPath(Language.getFileTranslation('images/$key') + '.xml', TEXT, parentFolder)));
#else
- return FlxAtlasFrames.fromSparrow(imageLoaded, getPath('images/$key.xml', TEXT, parentFolder));
+ return FlxAtlasFrames.fromSparrow(imageLoaded, getPath(Language.getFileTranslation('images/$key') + '.xml', TEXT, parentFolder));
#end
}
@@ -318,9 +336,9 @@ class Paths
var txt:String = modsTxt(key);
if(FileSystem.exists(txt)) txtExists = true;
- return FlxAtlasFrames.fromSpriteSheetPacker(imageLoaded, (txtExists ? File.getContent(txt) : getPath('images/$key.txt', TEXT, parentFolder)));
+ return FlxAtlasFrames.fromSpriteSheetPacker(imageLoaded, (txtExists ? File.getContent(txt) : getPath(Language.getFileTranslation('images/$key') + '.txt', TEXT, parentFolder)));
#else
- return FlxAtlasFrames.fromSpriteSheetPacker(imageLoaded, getPath('images/$key.txt', TEXT, parentFolder));
+ return FlxAtlasFrames.fromSpriteSheetPacker(imageLoaded, getPath(Language.getFileTranslation('images/$key') + '.txt', TEXT, parentFolder));
#end
}
@@ -333,9 +351,9 @@ class Paths
var json:String = modsImagesJson(key);
if(FileSystem.exists(json)) jsonExists = true;
- return FlxAtlasFrames.fromTexturePackerJson(imageLoaded, (jsonExists ? File.getContent(json) : getPath('images/$key.json', TEXT, parentFolder)));
+ return FlxAtlasFrames.fromTexturePackerJson(imageLoaded, (jsonExists ? File.getContent(json) : getPath(Language.getFileTranslation('images/$key') + '.json', TEXT, parentFolder)));
#else
- return FlxAtlasFrames.fromTexturePackerJson(imageLoaded, getPath('images/$key.json', TEXT, parentFolder));
+ return FlxAtlasFrames.fromTexturePackerJson(imageLoaded, getPath(Language.getFileTranslation('images/$key') + '.json', TEXT, parentFolder));
#end
}
diff --git a/source/backend/SpectralAnalyzerEx.hx b/source/backend/SpectralAnalyzerEx.hx
deleted file mode 100644
index 3e32a242555..00000000000
--- a/source/backend/SpectralAnalyzerEx.hx
+++ /dev/null
@@ -1,161 +0,0 @@
-package backend;
-#if funkin.vis
-import funkin.vis._internal.html5.AnalyzerNode;
-import funkin.vis.audioclip.frontends.LimeAudioClip;
-import funkin.vis.dsp.SpectralAnalyzer;
-import funkin.vis.dsp.RecentPeakFinder;
-import grig.audio.FFT;
-import grig.audio.FFTVisualization;
-import lime.media.AudioSource;
-
-using grig.audio.lime.UInt8ArrayTools;
-#end
-
-class SpectralAnalyzerEx #if funkin.vis extends SpectralAnalyzer #end
-{
- #if funkin.vis
- var _levels:Array = [];
- public function recycledLevels():Array
- {
- #if web
- var amplitudes:Array = htmlAnalyzer.getFloatFrequencyData();
-
- for (i in 0...bars.length) {
- var bar = bars[i];
- var binLo = bar.binLo;
- var binHi = bar.binHi;
-
- var value:Float = minDb;
- for (j in (binLo + 1)...(binHi)) {
- value = Math.max(value, amplitudes[Std.int(j)]);
- }
-
- // this isn't for clamping, it's to get a value
- // between 0 and 1!
- value = normalizedB(value);
- bar.recentValues.push(value);
- var recentPeak = bar.recentValues.peak;
-
- if(_levels[i] != null)
- {
- _levels[i].value = value;
- _levels[i].peak = recentPeak;
- }
- else _levels.push({value: value, peak: recentPeak});
- }
-
- return _levels;
- #else
- var numOctets = Std.int(audioSource.buffer.bitsPerSample / 8);
- var wantedLength = fftN * numOctets * audioSource.buffer.channels;
- var startFrame = audioClip.currentFrame;
- startFrame -= startFrame % numOctets;
- var segment = audioSource.buffer.data.subarray(startFrame, min(startFrame + wantedLength, audioSource.buffer.data.length));
- var signal = recycledInterleaved(segment, audioSource.buffer.bitsPerSample);
-
- if (audioSource.buffer.channels > 1)
- {
- var mixed = [];
- mixed.resize(Std.int(signal.length / audioSource.buffer.channels));
- for (i in 0...mixed.length)
- {
- mixed[i] = 0.0;
- for (c in 0...audioSource.buffer.channels)
- mixed[i] += 0.7 * signal[i*audioSource.buffer.channels+c];
-
- mixed[i] *= blackmanWindow[i];
- }
- signal = mixed;
- }
-
- var range = 16;
- var freqs = fft.calcFreq(signal);
- var bars = vis.makeLogGraph(freqs, barCount, Math.floor(maxDb - minDb), range);
-
- if (bars.length > barHistories.length)
- barHistories.resize(bars.length);
-
- _levels.resize(bars.length);
- for (i in 0...bars.length)
- {
- if (barHistories[i] == null)
- {
- barHistories[i] = new RecentPeakFinder();
- trace('created barHistories[$i]');
- }
- var recentValues = barHistories[i];
- var value = bars[i] / range;
-
- // slew limiting
- var lastValue = recentValues.lastValue;
- if (maxDelta > 0.0)
- {
- var delta = clamp(value - lastValue, -1 * maxDelta, maxDelta);
- value = lastValue + delta;
- }
- recentValues.push(value);
-
- var recentPeak = recentValues.peak;
-
- if(_levels[i] != null)
- {
- _levels[i].value = value;
- _levels[i].peak = recentPeak;
- }
- else _levels[i] = {value: value, peak: recentPeak};
- }
- return _levels;
- #end
- }
-
- var _buffer:Array = [];
- function recycledInterleaved(data:lime.utils.UInt8Array, bitsPerSample:Int):Array
- {
- switch(bitsPerSample)
- {
- case 8:
- _buffer.resize(data.length);
- for (i in 0...data.length)
- _buffer[i] = data[i] / 128.0;
-
- case 16:
- _buffer.resize(Std.int(data.length / 2));
- for (i in 0..._buffer.length)
- _buffer[i] = data.getInt16(i * 2) / 32767.0;
-
- case 24:
- _buffer.resize(Std.int(data.length / 3));
- for (i in 0..._buffer.length)
- _buffer[i] = data.getInt24(i * 3) / 8388607.0;
-
- case 32:
- _buffer.resize(Std.int(data.length / 4));
- for (i in 0..._buffer.length)
- _buffer[i] = data.getInt32(i * 4) / 2147483647.0;
-
- default: trace('Unknown integer audio format');
- }
- return _buffer;
- }
-
- @:generic
- static inline function min(x:T, y:T):T
- {
- return x > y ? y : x;
- }
-
- @:generic
- static inline function clamp(val:T, min:T, max:T):T
- {
- return val <= min ? min : val >= max ? max : val;
- }
- #else
- //Just to avoid errors until they review my PR
- public var fftN:Int = 0;
- public function new(?v1:Dynamic, ?v2:Dynamic, ?v3:Dynamic, ?v4:Dynamic) {}
- public function recycledLevels():Array
- {
- return [{value: 0, peak: 0}];
- }
- #end
-}
\ No newline at end of file
diff --git a/source/backend/ui/PsychUIInputText.hx b/source/backend/ui/PsychUIInputText.hx
index d6c70ddf13c..f50dfc7c28e 100644
--- a/source/backend/ui/PsychUIInputText.hx
+++ b/source/backend/ui/PsychUIInputText.hx
@@ -660,7 +660,7 @@ class PsychUIInputText extends FlxSpriteGroup
var letter:String = String.fromCharCode(charCode);
letter = filter(letter);
- if(letter.length > 0 && (maxLength == 0 || (text.length + letter.length) < maxLength))
+ if(letter.length > 0 && (maxLength == 0 || (text.length + letter.length) <= maxLength))
{
var lastText = text;
//trace('Drawing character: $letter');
diff --git a/source/debug/FPSCounter.hx b/source/debug/FPSCounter.hx
index e774328b508..33786aee619 100644
--- a/source/debug/FPSCounter.hx
+++ b/source/debug/FPSCounter.hx
@@ -46,19 +46,18 @@ class FPSCounter extends TextField
// Event Handlers
private override function __enterFrame(deltaTime:Float):Void
{
- // prevents the overlay from updating every frame, why would you need to anyways
- if (deltaTimeout > 1000) {
- deltaTimeout = 0.0;
- return;
- }
-
final now:Float = haxe.Timer.stamp() * 1000;
times.push(now);
while (times[0] < now - 1000) times.shift();
+ // prevents the overlay from updating every frame, why would you need to anyways @crowplexus
+ if (deltaTimeout < 1000) {
+ deltaTimeout += deltaTime;
+ return;
+ }
currentFPS = times.length < FlxG.updateFramerate ? times.length : FlxG.updateFramerate;
updateText();
- deltaTimeout += deltaTime;
+ deltaTimeout = 0.0;
}
public dynamic function updateText():Void { // so people can override it in hscript
diff --git a/source/objects/Character.hx b/source/objects/Character.hx
index f8ec03d49e4..cbe232fe227 100644
--- a/source/objects/Character.hx
+++ b/source/objects/Character.hx
@@ -2,8 +2,6 @@ package objects;
import backend.animation.PsychAnimationController;
-import flixel.graphics.frames.FlxAtlasFrames;
-
import flixel.util.FlxSort;
import flixel.util.FlxDestroyUtil;
@@ -158,21 +156,7 @@ class Character extends FlxSprite
if(!isAnimateAtlas)
{
- var split:Array = json.image.split(',');
- var charFrames:FlxAtlasFrames = Paths.getAtlas(split[0].trim());
- if(split.length > 1)
- {
- var original:FlxAtlasFrames = charFrames;
- charFrames = new FlxAtlasFrames(charFrames.parent);
- charFrames.addAtlas(original, true);
- for (i in 1...split.length)
- {
- var extraFrames:FlxAtlasFrames = Paths.getAtlas(split[i].trim());
- if(extraFrames != null)
- charFrames.addAtlas(extraFrames, true);
- }
- }
- frames = charFrames;
+ frames = Paths.getMultiAtlas(json.image.split(','));
}
#if flxanimate
else
diff --git a/source/objects/HealthIcon.hx b/source/objects/HealthIcon.hx
index 18afe6788dc..317c02fb37a 100644
--- a/source/objects/HealthIcon.hx
+++ b/source/objects/HealthIcon.hx
@@ -30,12 +30,13 @@ class HealthIcon extends FlxSprite
if(!Paths.fileExists('images/' + name + '.png', IMAGE)) name = 'icons/icon-face'; //Prevents crash from missing icon
var graphic = Paths.image(name, allowGPU);
- loadGraphic(graphic, true, Math.floor(graphic.width / 2), Math.floor(graphic.height));
- iconOffsets[0] = (width - 150) / 2;
- iconOffsets[1] = (height - 150) / 2;
+ var iSize:Float = Math.round(graphic.width / graphic.height);
+ loadGraphic(graphic, true, Math.floor(graphic.width / iSize), Math.floor(graphic.height));
+ iconOffsets[0] = (width - 150) / iSize;
+ iconOffsets[1] = (height - 150) / iSize;
updateHitbox();
- animation.add(char, [0, 1], 0, false, isPlayer);
+ animation.add(char, [for(i in 0...frames.frames.length) i], 0, false, isPlayer);
animation.play(char);
this.char = char;
diff --git a/source/objects/NoteSplash.hx b/source/objects/NoteSplash.hx
index 6c74fb03545..e041b41fb79 100644
--- a/source/objects/NoteSplash.hx
+++ b/source/objects/NoteSplash.hx
@@ -1,13 +1,12 @@
package objects;
-import states.editors.NoteSplashEditorState;
-import haxe.Json;
import backend.animation.PsychAnimationController;
import shaders.RGBPalette;
+import states.editors.NoteSplashEditorState;
+
import flixel.system.FlxAssets.FlxShader;
-import flixel.util.FlxColor;
private typedef RGB = {
r:Null,
@@ -17,37 +16,39 @@ private typedef RGB = {
private typedef NoteSplashAnim = {
name:String,
- prefix:String,
- maxFps:Int,
- minFps:Int,
noteData:Int,
- offsets:Array,
+ prefix:String,
indices:Array,
+ offsets:Array,
+ fps:Array
}
typedef NoteSplashConfig = {
animations:Map,
- scale:Array,
- affectedByShader:Bool,
+ scale:Float,
+ allowRGB:Bool,
+ allowPixel:Bool,
rgb:Array>
}
class NoteSplash extends FlxSprite
{
+ public var rgbShader:PixelSplashShaderRef;
public var skin:String;
public var config(default, set):NoteSplashConfig;
- public static var DEFAULT_SKIN:String = "noteSplashes";
+
+ public static var DEFAULT_SKIN:String = "noteSplashes/noteSplashes";
public static var configs:Map = new Map();
public var babyArrow:StrumNote;
-
var noteDataMap:Map = new Map();
- var rgbShader:PixelSplashShaderRef;
public function new(?splash:String)
{
super();
+
animation = new PsychAnimationController(this);
+
rgbShader = new PixelSplashShaderRef();
shader = rgbShader.shader;
@@ -58,40 +59,39 @@ class NoteSplash extends FlxSprite
{
config = null; // Reset config to the default so when reloaded it can be set properly
skin = null;
-
+
var skin:String = splash;
-
if (skin == null || skin.length < 1)
skin = try PlayState.SONG.splashSkin catch(e) null;
if (skin == null || skin.length < 1)
skin = DEFAULT_SKIN + getSplashSkinPostfix();
-
+
this.skin = skin;
- try frames = Paths.getSparrowAtlas("noteSplashes/" + skin) catch (e) {
+ try frames = Paths.getSparrowAtlas(skin) catch (e) {
skin = DEFAULT_SKIN; // The splash skin was not found, return to the default
this.skin = skin;
- try frames = Paths.getSparrowAtlas("noteSplashes/" + skin) catch (e) {
+ try frames = Paths.getSparrowAtlas(skin) catch (e) {
active = visible = false;
}
}
- var path:String = 'images/noteSplashes/$skin.json';
- if (configs.exists(path))
- this.config = configs.get(path);
+ var path:String = 'images/$skin.json';
+ if (configs.exists(path)) this.config = configs.get(path);
else if (Paths.fileExists(path, TEXT))
{
- var config:Dynamic = Json.parse(Paths.getTextFromFile(path));
-
+ var config:Dynamic = haxe.Json.parse(Paths.getTextFromFile(path));
if (config != null)
{
var tempConfig:NoteSplashConfig = {
animations: new Map(),
scale: config.scale,
- affectedByShader: config.affectedByShader,
+ allowRGB: config.allowRGB,
+ allowPixel: config.allowPixel,
rgb: config.rgb
}
+
for (i in Reflect.fields(config.animations))
{
tempConfig.animations.set(i, Reflect.field(config.animations, i));
@@ -123,14 +123,17 @@ class NoteSplash extends FlxSprite
var anims:Int = 0;
var datas:Int = 0;
var animArray:Array = [];
+
while (true)
{
var data:Int = noteData % 4 + (datas * 4);
if (!noteDataMap.exists(data) || !animation.exists(noteDataMap[data]))
break;
+
datas++;
anims++;
}
+
if (anims > 1)
{
for (i in 0...anims)
@@ -154,94 +157,84 @@ class NoteSplash extends FlxSprite
this.animation.play(animation);
anim = animation;
}
- else
- visible = false;
+ else visible = false;
}
playDefaultAnim();
var tempShader:RGBPalette = null;
- if (note == null)
- note = new Note(0, noteData);
-
- Note.initializeGlobalRGBShader(noteData % 4);
- function useDefault()
+ if (config.allowRGB)
{
- tempShader = Note.globalRgbShaders[noteData % 4];
- }
+ if (note == null)
+ note = new Note(0, noteData);
- if(((cast FlxG.state) is NoteSplashEditorState) ||
- ((note.noteSplashData.useRGBShader) && (PlayState.SONG == null || !PlayState.SONG.disableNoteRGB)))
- {
- // If Note RGB is enabled:
- if((!note.noteSplashData.useGlobalShader || ((cast FlxG.state) is NoteSplashEditorState)))
+ Note.initializeGlobalRGBShader(noteData % 4);
+ function useDefault()
{
- var colors = config.rgb;
- if (colors != null)
+ tempShader = Note.globalRgbShaders[noteData % 4];
+ }
+
+ if(((cast FlxG.state) is NoteSplashEditorState) ||
+ ((note.noteSplashData.useRGBShader) && (PlayState.SONG == null || !PlayState.SONG.disableNoteRGB)))
+ {
+ // If Note RGB is enabled:
+ if((!note.noteSplashData.useGlobalShader || ((cast FlxG.state) is NoteSplashEditorState)))
{
- tempShader = new RGBPalette();
- for (i in 0...colors.length)
+ var colors = config.rgb;
+ if (colors != null)
{
- if (i > 2)
- break;
-
- var rgb = colors[i];
- var arr:Array = ClientPrefs.data.arrowRGB[noteData % 4];
- if(PlayState.isPixelStage) arr = ClientPrefs.data.arrowRGBPixel[noteData % 4];
- if (rgb == null)
+ tempShader = new RGBPalette();
+ for (i in 0...colors.length)
{
- if (i == 0)
- tempShader.r = arr[0];
- else if (i == 1)
- tempShader.g = arr[1];
- else if (i == 2)
- tempShader.b = arr[2];
- continue;
- }
-
- var r:Null = rgb.r;
- var g:Null = rgb.g;
- var b:Null = rgb.b;
-
- if (r == null || Math.isNaN(r) || r < 0)
- r = arr[0];
- if (g == null || Math.isNaN(g) || g < 0)
- g = arr[1];
- if (b == null || Math.isNaN(b) || b < 0)
- b = arr[2];
-
- var color:FlxColor = FlxColor.fromRGB(r, g, b);
- if (i == 0)
- tempShader.r = color;
- else if (i == 1)
- tempShader.g = color;
- else if (i == 2)
- tempShader.b = color;
- }
+ if (i > 2) break;
+
+ var arr:Array = ClientPrefs.data.arrowRGB[noteData % 4];
+ if(PlayState.isPixelStage) arr = ClientPrefs.data.arrowRGBPixel[noteData % 4];
+
+ var rgb = colors[i];
+ if (rgb == null)
+ {
+ if (i == 0) tempShader.r = arr[0];
+ else if (i == 1) tempShader.g = arr[1];
+ else if (i == 2) tempShader.b = arr[2];
+ continue;
+ }
+
+ var r:Null = rgb.r;
+ var g:Null = rgb.g;
+ var b:Null = rgb.b;
+
+ if (r == null || Math.isNaN(r) || r < 0) r = arr[0];
+ if (g == null || Math.isNaN(g) || g < 0) g = arr[1];
+ if (b == null || Math.isNaN(b) || b < 0) b = arr[2];
+
+ var color:FlxColor = FlxColor.fromRGB(r, g, b);
+ if (i == 0) tempShader.r = color;
+ else if (i == 1) tempShader.g = color;
+ else if (i == 2) tempShader.b = color;
+ }
+ }
+ else useDefault();
}
- else
- useDefault();
- }
- else
- {
- useDefault();
+ else useDefault();
}
}
+ rgbShader.copyValues(tempShader);
- if (config.affectedByShader)
- rgbShader.copyValues(tempShader);
- else
- rgbShader.reset();
+ if(!config.allowPixel) rgbShader.pixelAmount = 1;
var conf = config.animations.get(anim);
- var offsets = [0, 0];
+ var offsets:Array = [0, 0];
+
if (conf != null)
offsets = conf.offsets;
+
if (offsets != null)
{
centerOffsets();
offset.set(offsets[0], offsets[1]);
}
+
animation.finishCallback = function(name:String)
{
kill();
@@ -255,12 +248,12 @@ class NoteSplash extends FlxSprite
if(animation.curAnim != null && conf != null)
{
- var minFps = conf.minFps;
- if (minFps < 0)
- minFps = 0;
- var maxFps = conf.maxFps;
- if (maxFps < 0)
- maxFps = 0;
+ var minFps = conf.fps[0];
+ if (minFps < 0) minFps = 0;
+
+ var maxFps = conf.fps[1];
+ if (maxFps < 0) maxFps = 0;
+
animation.curAnim.frameRate = FlxG.random.int(minFps, maxFps);
}
}
@@ -288,26 +281,25 @@ class NoteSplash extends FlxSprite
{
return {
animations: new Map(),
- scale: [1, 1],
- affectedByShader: true,
+ scale: 1,
+ allowRGB: true,
+ allowPixel: true,
rgb: null
}
}
- public static function addAnimationToConfig(scale:Array, config:NoteSplashConfig, name:String, prefix:String, minFps:Int, maxFps:Int, offsets:Array, indices:Array, noteData:Int):NoteSplashConfig
+ public static function addAnimationToConfig(config:NoteSplashConfig, scale:Float, name:String, prefix:String, fps:Array, offsets:Array, indices:Array, noteData:Int):NoteSplashConfig
{
- if (config == null)
- config = createConfig();
+ if (config == null) config = createConfig();
- config.animations.set(name, {name: name, prefix: prefix, indices: indices, minFps: minFps, maxFps: maxFps, offsets: offsets, noteData: noteData});
+ config.animations.set(name, {name: name, noteData: noteData, prefix: prefix, indices: indices, offsets: offsets, fps: fps});
config.scale = scale;
return config;
}
function set_config(value:NoteSplashConfig):NoteSplashConfig
{
- if (value == null)
- value = createConfig();
+ if (value == null) value = createConfig();
noteDataMap.clear();
@@ -317,13 +309,15 @@ class NoteSplash extends FlxSprite
if (i.prefix.length > 0 && key != null && key.length > 0)
{
if (i.indices != null && i.indices.length > 0 && key != null && key.length > 0)
- animation.addByIndices(key, i.prefix, i.indices, "", i.maxFps, false);
+ animation.addByIndices(key, i.prefix, i.indices, "", i.fps[1], false);
else
- animation.addByPrefix(key, i.prefix, i.maxFps, false);
+ animation.addByPrefix(key, i.prefix, i.fps[1], false);
+
noteDataMap.set(i.noteData, key);
}
}
- scale.set(value.scale[0], value.scale[1]);
+
+ scale.set(value.scale, value.scale);
return config = value;
}
}
@@ -331,14 +325,12 @@ class NoteSplash extends FlxSprite
class PixelSplashShaderRef
{
public var shader:PixelSplashShader = new PixelSplashShader();
+ public var enabled(default, set):Bool = true;
+ public var pixelAmount(default, set):Float = 1;
public function copyValues(tempShader:RGBPalette)
{
- var enabled:Bool = false;
if(tempShader != null)
- enabled = true;
-
- if(enabled)
{
for (i in 0...3)
{
@@ -348,12 +340,21 @@ class PixelSplashShaderRef
}
shader.mult.value[0] = tempShader.shader.mult.value[0];
}
- else shader.mult.value[0] = 0.0;
+ else enabled = false;
+ }
+
+ public function set_enabled(value:Bool)
+ {
+ enabled = value;
+ shader.mult.value = [value ? 1 : 0];
+ return value;
}
- public function set(enabled:Bool = true)
+ public function set_pixelAmount(value:Float)
{
- shader.mult.value = [enabled ? 1 : 0];
+ pixelAmount = value;
+ shader.uBlocksize.value = [value, value];
+ return value;
}
public function reset()
@@ -366,11 +367,10 @@ class PixelSplashShaderRef
public function new()
{
reset();
- set();
+ enabled = true;
- var pixel:Float = 1;
- if(PlayState.isPixelStage) pixel = PlayState.daPixelZoom;
- shader.uBlocksize.value = [pixel, pixel];
+ if(!PlayState.isPixelStage) pixelAmount = 1;
+ else pixelAmount = PlayState.daPixelZoom;
//trace('Created shader ' + Conductor.songPosition);
}
}
@@ -379,7 +379,7 @@ class PixelSplashShader extends FlxShader
{
@:glFragmentHeader('
#pragma header
-
+
uniform vec3 r;
uniform vec3 g;
uniform vec3 b;
@@ -400,9 +400,9 @@ class PixelSplashShader extends FlxShader
vec4 newColor = color;
newColor.rgb = min(color.r * r + color.g * g + color.b * b, vec3(1.0));
newColor.a = color.a;
-
+
color = mix(color, newColor, mult);
-
+
if(color.a > 0.0) {
return vec4(color.rgb, color.a);
}
diff --git a/source/options/NotesSubState.hx b/source/options/NotesColorSubState.hx
similarity index 99%
rename from source/options/NotesSubState.hx
rename to source/options/NotesColorSubState.hx
index 466f9111f40..572c03bf426 100644
--- a/source/options/NotesSubState.hx
+++ b/source/options/NotesColorSubState.hx
@@ -13,7 +13,7 @@ import objects.Note;
import shaders.RGBPalette;
import shaders.RGBPalette.RGBShaderReference;
-class NotesSubState extends MusicBeatSubstate
+class NotesColorSubState extends MusicBeatSubstate
{
var onModeColumn:Bool = true;
var curSelectedMode:Int = 0;
@@ -54,6 +54,7 @@ class NotesSubState extends MusicBeatSubstate
DiscordClient.changePresence("Note Colors Menu", null);
#end
+ onPixel = PlayState.isPixelStage;
var bg:FlxSprite = new FlxSprite().loadGraphic(Paths.image('menuDesat'));
bg.color = 0xFFEA71FD;
bg.screenCenter();
diff --git a/source/options/OptionsState.hx b/source/options/OptionsState.hx
index ab8f7ab3ce5..a2e4a7c4317 100644
--- a/source/options/OptionsState.hx
+++ b/source/options/OptionsState.hx
@@ -23,7 +23,7 @@ class OptionsState extends MusicBeatState
switch(label)
{
case 'Note Colors':
- openSubState(new options.NotesSubState());
+ openSubState(new options.NotesColorSubState());
case 'Controls':
openSubState(new options.ControlsSubState());
case 'Graphics':
diff --git a/source/psychlua/CustomSubstate.hx b/source/psychlua/CustomSubstate.hx
index b4c82a60853..69a4702c4d6 100644
--- a/source/psychlua/CustomSubstate.hx
+++ b/source/psychlua/CustomSubstate.hx
@@ -31,8 +31,6 @@ class CustomSubstate extends MusicBeatSubstate
}
}
PlayState.instance.openSubState(new CustomSubstate(name));
- PlayState.instance.setOnHScript('customSubstate', instance);
- PlayState.instance.setOnHScript('customSubstateName', name);
}
public static function closeCustomSubstate()
@@ -51,7 +49,6 @@ class CustomSubstate extends MusicBeatSubstate
if(instance != null)
{
var tagObject:FlxObject = cast (MusicBeatState.getVariables().get(tag), FlxObject);
- #if LUA_ALLOWED if(tagObject == null) tagObject = cast (MusicBeatState.getVariables().get(tag), FlxObject); #end
if(tagObject != null)
{
@@ -66,6 +63,8 @@ class CustomSubstate extends MusicBeatSubstate
override function create()
{
instance = this;
+ PlayState.instance.setOnHScript('customSubstate', instance);
+
PlayState.instance.callOnScripts('onCustomSubstateCreate', [name]);
super.create();
@@ -75,6 +74,7 @@ class CustomSubstate extends MusicBeatSubstate
public function new(name:String)
{
CustomSubstate.name = name;
+ PlayState.instance.setOnHScript('customSubstateName', name);
super();
cameras = [FlxG.cameras.list[FlxG.cameras.list.length - 1]];
}
diff --git a/source/psychlua/FunkinLua.hx b/source/psychlua/FunkinLua.hx
index 914470c10ca..4f93e742d5d 100644
--- a/source/psychlua/FunkinLua.hx
+++ b/source/psychlua/FunkinLua.hx
@@ -31,7 +31,7 @@ import substates.GameOverSubstate;
import psychlua.LuaUtils;
import psychlua.LuaUtils.LuaTweenOptions;
-#if SScript
+#if HSCRIPT_ALLOWED
import psychlua.HScript;
#end
import psychlua.DebugLuaText;
@@ -84,6 +84,7 @@ class FunkinLua {
set('luaDebugMode', false);
set('luaDeprecatedWarnings', true);
set('version', MainMenuState.psychEngineVersion.trim());
+ set('modFolder', this.modFolder);
// Song/Week shit
set('curBpm', Conductor.bpm);
@@ -111,10 +112,6 @@ class FunkinLua {
set('seenCutscene', PlayState.seenCutscene);
set('hasVocals', PlayState.SONG.needsVoices);
- // Camera poo
- set('cameraX', 0);
- set('cameraY', 0);
-
// Screen stuff
set('screenWidth', FlxG.width);
set('screenHeight', FlxG.height);
@@ -133,10 +130,13 @@ class FunkinLua {
set('misses', 0);
set('hits', 0);
set('combo', 0);
+ set('deaths', PlayState.deathCounter);
set('rating', 0);
set('ratingName', '');
set('ratingFC', '');
+ set('totalPlayed', 0);
+ set('totalNotesHit', 0.0);
set('inGameOver', false);
set('mustHitSection', false);
@@ -257,110 +257,21 @@ class FunkinLua {
args = [];
}
- var foundScript:String = findScript(luaFile);
- if(foundScript != null)
- for (luaInstance in game.luaArray)
- if(luaInstance.scriptName == foundScript)
- {
- luaInstance.call(funcName, args);
- return;
- }
- });
-
- Lua_helper.add_callback(lua, "getGlobalFromScript", function(luaFile:String, global:String) { // returns the global from a script
- var foundScript:String = findScript(luaFile);
- if(foundScript != null)
- for (luaInstance in game.luaArray)
- if(luaInstance.scriptName == foundScript)
- {
- Lua.getglobal(luaInstance.lua, global);
- if(Lua.isnumber(luaInstance.lua,-1))
- Lua.pushnumber(lua, Lua.tonumber(luaInstance.lua, -1));
- else if(Lua.isstring(luaInstance.lua,-1))
- Lua.pushstring(lua, Lua.tostring(luaInstance.lua, -1));
- else if(Lua.isboolean(luaInstance.lua,-1))
- Lua.pushboolean(lua, Lua.toboolean(luaInstance.lua, -1));
- else
- Lua.pushnil(lua);
-
- // TODO: table
-
- Lua.pop(luaInstance.lua,1); // remove the global
+ for (luaInstance in game.luaArray)
+ if(luaInstance.scriptName == luaFile)
+ return luaInstance.call(funcName, args);
- return;
- }
+ return null;
});
- Lua_helper.add_callback(lua, "setGlobalFromScript", function(luaFile:String, global:String, val:Dynamic) { // returns the global from a script
- var foundScript:String = findScript(luaFile);
- if(foundScript != null)
- for (luaInstance in game.luaArray)
- if(luaInstance.scriptName == foundScript)
- luaInstance.set(global, val);
- });
- /*Lua_helper.add_callback(lua, "getGlobals", function(luaFile:String) { // returns a copy of the specified file's globals
- var foundScript:String = findScript(luaFile);
- if(foundScript != null)
- {
- for (luaInstance in game.luaArray)
- {
- if(luaInstance.scriptName == foundScript)
- {
- Lua.newtable(lua);
- var tableIdx = Lua.gettop(lua);
-
- Lua.pushvalue(luaInstance.lua, Lua.LUA_GLOBALSINDEX);
- while(Lua.next(luaInstance.lua, -2) != 0) {
- // key = -2
- // value = -1
-
- var pop:Int = 0;
-
- // Manual conversion
- // first we convert the key
- if(Lua.isnumber(luaInstance.lua,-2)){
- Lua.pushnumber(lua, Lua.tonumber(luaInstance.lua, -2));
- pop++;
- }else if(Lua.isstring(luaInstance.lua,-2)){
- Lua.pushstring(lua, Lua.tostring(luaInstance.lua, -2));
- pop++;
- }else if(Lua.isboolean(luaInstance.lua,-2)){
- Lua.pushboolean(lua, Lua.toboolean(luaInstance.lua, -2));
- pop++;
- }
- // TODO: table
-
-
- // then the value
- if(Lua.isnumber(luaInstance.lua,-1)){
- Lua.pushnumber(lua, Lua.tonumber(luaInstance.lua, -1));
- pop++;
- }else if(Lua.isstring(luaInstance.lua,-1)){
- Lua.pushstring(lua, Lua.tostring(luaInstance.lua, -1));
- pop++;
- }else if(Lua.isboolean(luaInstance.lua,-1)){
- Lua.pushboolean(lua, Lua.toboolean(luaInstance.lua, -1));
- pop++;
- }
- // TODO: table
-
- if(pop==2)Lua.rawset(lua, tableIdx); // then set it
- Lua.pop(luaInstance.lua, 1); // for the loop
- }
- Lua.pop(luaInstance.lua,1); // end the loop entirely
- Lua.pushvalue(lua, tableIdx); // push the table onto the stack so it gets returned
+ Lua_helper.add_callback(lua, "isRunning", function(scriptFile:String) {
+ for (luaInstance in game.luaArray)
+ if(luaInstance.scriptName == scriptFile)
+ return true;
- return;
- }
+ for (hscriptInstance in game.hscriptArray)
+ if(hscriptInstance.origin == scriptFile)
+ return true;
- }
- }
- });*/
- Lua_helper.add_callback(lua, "isRunning", function(luaFile:String) {
- var foundScript:String = findScript(luaFile);
- if(foundScript != null)
- for (luaInstance in game.luaArray)
- if(luaInstance.scriptName == foundScript)
- return true;
return false;
});
@@ -375,37 +286,43 @@ class FunkinLua {
return MusicBeatState.getVariables().remove(varName);
});
- Lua_helper.add_callback(lua, "addLuaScript", function(luaFile:String, ?ignoreAlreadyRunning:Bool = false) { //would be dope asf.
- var foundScript:String = findScript(luaFile);
- if(foundScript != null)
+ Lua_helper.add_callback(lua, "addLuaScript", function(luaFile:String, ?ignoreAlreadyRunning:Bool = false) {
+ #if sys
+ if(FileSystem.exists(luaFile))
+ #else
+ if(Assets.exists(luaFile, TEXT))
+ #end
{
if(!ignoreAlreadyRunning)
for (luaInstance in game.luaArray)
- if(luaInstance.scriptName == foundScript)
+ if(luaInstance.scriptName == luaFile)
{
- luaTrace('addLuaScript: The script "' + foundScript + '" is already running!');
+ luaTrace('addLuaScript: The script "' + luaFile + '" is already running!');
return;
}
- new FunkinLua(foundScript);
+ new FunkinLua(luaFile);
return;
}
luaTrace("addLuaScript: Script doesn't exist!", false, false, FlxColor.RED);
});
- Lua_helper.add_callback(lua, "addHScript", function(haxeFile:String, ?ignoreAlreadyRunning:Bool = false) {
+ Lua_helper.add_callback(lua, "addHScript", function(scriptFile:String, ?ignoreAlreadyRunning:Bool = false) {
#if HSCRIPT_ALLOWED
- var foundScript:String = findScript(haxeFile, '.hx');
- if(foundScript != null)
+ #if sys
+ if(FileSystem.exists(scriptFile))
+ #else
+ if(Assets.exists(scriptFile, TEXT))
+ #end
{
if(!ignoreAlreadyRunning)
for (script in game.hscriptArray)
- if(script.origin == foundScript)
+ if(script.origin == scriptFile)
{
- luaTrace('addHScript: The script "' + foundScript + '" is already running!');
+ luaTrace('addHScript: The script "' + scriptFile + '" is already running!');
return;
}
- PlayState.instance.initHScript(foundScript);
+ PlayState.instance.initHScript(scriptFile);
return;
}
luaTrace("addHScript: Script doesn't exist!", false, false, FlxColor.RED);
@@ -413,37 +330,37 @@ class FunkinLua {
luaTrace("addHScript: HScript is not supported on this platform!", false, false, FlxColor.RED);
#end
});
- Lua_helper.add_callback(lua, "removeLuaScript", function(luaFile:String, ?ignoreAlreadyRunning:Bool = false) {
- var foundScript:String = findScript(luaFile);
- if(foundScript != null)
+ Lua_helper.add_callback(lua, "removeLuaScript", function(luaFile:String) {
+ var foundAny:Bool = false;
+ for (luaInstance in game.luaArray)
{
- if(!ignoreAlreadyRunning)
- for (luaInstance in game.luaArray)
- if(luaInstance.scriptName == foundScript)
- {
- luaInstance.stop();
- trace('Closing script ' + luaInstance.scriptName);
- return true;
- }
+ if(luaInstance.scriptName == luaFile)
+ {
+ trace('Closing lua script $luaFile');
+ luaInstance.stop();
+ foundAny = true;
+ }
}
+ if(foundAny) return true;
+
luaTrace('removeLuaScript: Script $luaFile isn\'t running!', false, false, FlxColor.RED);
return false;
});
- Lua_helper.add_callback(lua, "removeHScript", function(luaFile:String, ?ignoreAlreadyRunning:Bool = false) {
+ Lua_helper.add_callback(lua, "removeHScript", function(scriptFile:String) {
#if HSCRIPT_ALLOWED
- var foundScript:String = findScript(luaFile, '.hx');
- if(foundScript != null)
+ var foundAny:Bool = false;
+ for (script in game.hscriptArray)
{
- if(!ignoreAlreadyRunning)
- for (script in game.hscriptArray)
- if(script.origin == foundScript)
- {
- trace('Closing script ' + (script.origin != null ? script.origin : luaFile));
- script.destroy();
- return true;
- }
+ if(script.origin == scriptFile)
+ {
+ trace('Closing hscript $scriptFile');
+ script.destroy();
+ foundAny = true;
+ }
}
- luaTrace('removeHScript: Script $luaFile isn\'t running!', false, false, FlxColor.RED);
+ if(foundAny) return true;
+
+ luaTrace('removeHScript: Script $scriptFile isn\'t running!', false, false, FlxColor.RED);
return false;
#else
luaTrace("removeHScript: HScript is not supported on this platform!", false, false, FlxColor.RED);
@@ -632,7 +549,7 @@ class FunkinLua {
Lua_helper.add_callback(lua, "noteTweenDirection", function(tag:String, note:Int, value:Dynamic, duration:Float, ease:String) {
noteTweenFunction(tag, note, {direction: value}, duration, ease);
});
- Lua_helper.add_callback(lua, "mouseClicked", function(button:String) {
+ Lua_helper.add_callback(lua, "mouseClicked", function(?button:String = 'left') {
var click:Bool = FlxG.mouse.justPressed;
switch(button.trim().toLowerCase())
{
@@ -643,7 +560,7 @@ class FunkinLua {
}
return click;
});
- Lua_helper.add_callback(lua, "mousePressed", function(button:String) {
+ Lua_helper.add_callback(lua, "mousePressed", function(?button:String = 'left') {
var press:Bool = FlxG.mouse.pressed;
switch(button.trim().toLowerCase())
{
@@ -654,7 +571,7 @@ class FunkinLua {
}
return press;
});
- Lua_helper.add_callback(lua, "mouseReleased", function(button:String) {
+ Lua_helper.add_callback(lua, "mouseReleased", function(?button:String = 'left') {
var released:Bool = FlxG.mouse.justReleased;
switch(button.trim().toLowerCase())
{
@@ -851,15 +768,28 @@ class FunkinLua {
game.moveCamera(isDad);
return isDad;
});
+
+ Lua_helper.add_callback(lua, "setCameraScroll", function(x:Float, y:Float) FlxG.camera.scroll.set(x - FlxG.width/2, y - FlxG.height/2));
+ Lua_helper.add_callback(lua, "setCameraFollowPoint", function(x:Float, y:Float) game.camFollow.setPosition(x, y));
+ Lua_helper.add_callback(lua, "addCameraScroll", function(?x:Float = 0, ?y:Float = 0) FlxG.camera.scroll.add(x, y));
+ Lua_helper.add_callback(lua, "addCameraFollowPoint", function(?x:Float = 0, ?y:Float = 0) {
+ game.camFollow.x += x;
+ game.camFollow.y += y;
+ });
+ Lua_helper.add_callback(lua, "getCameraScrollX", () -> FlxG.camera.scroll.x + FlxG.width/2);
+ Lua_helper.add_callback(lua, "getCameraScrollY", () -> FlxG.camera.scroll.y + FlxG.height/2);
+ Lua_helper.add_callback(lua, "getCameraFollowX", () -> game.camFollow.x);
+ Lua_helper.add_callback(lua, "getCameraFollowY", () -> game.camFollow.y);
+
Lua_helper.add_callback(lua, "cameraShake", function(camera:String, intensity:Float, duration:Float) {
LuaUtils.cameraFromString(camera).shake(intensity, duration);
});
Lua_helper.add_callback(lua, "cameraFlash", function(camera:String, color:String, duration:Float,forced:Bool) {
- LuaUtils.cameraFromString(camera).flash(CoolUtil.colorFromString(color), duration, null,forced);
+ LuaUtils.cameraFromString(camera).flash(CoolUtil.colorFromString(color), duration, null, forced);
});
- Lua_helper.add_callback(lua, "cameraFade", function(camera:String, color:String, duration:Float,forced:Bool) {
- LuaUtils.cameraFromString(camera).fade(CoolUtil.colorFromString(color), duration, false,null,forced);
+ Lua_helper.add_callback(lua, "cameraFade", function(camera:String, color:String, duration:Float, forced:Bool, ?fadeOut:Bool = false) {
+ LuaUtils.cameraFromString(camera).fade(CoolUtil.colorFromString(color), duration, fadeOut, null, forced);
});
Lua_helper.add_callback(lua, "setRatingPercent", function(value:Float) {
return game.ratingPercent = value;
@@ -870,11 +800,11 @@ class FunkinLua {
Lua_helper.add_callback(lua, "setRatingFC", function(value:String) {
return game.ratingFC = value;
});
- Lua_helper.add_callback(lua, "getMouseX", function(camera:String = 'game') {
+ Lua_helper.add_callback(lua, "getMouseX", function(?camera:String = 'game') {
var cam:FlxCamera = LuaUtils.cameraFromString(camera);
return FlxG.mouse.getScreenPosition(cam).x;
});
- Lua_helper.add_callback(lua, "getMouseY", function(camera:String = 'game') {
+ Lua_helper.add_callback(lua, "getMouseY", function(?camera:String = 'game') {
var cam:FlxCamera = LuaUtils.cameraFromString(camera);
return FlxG.mouse.getScreenPosition(cam).y;
});
@@ -1371,7 +1301,10 @@ class FunkinLua {
});
Lua_helper.add_callback(lua, "stopSound", function(tag:String) {
if(tag == null || tag.length < 1)
- if(FlxG.sound.music != null) FlxG.sound.music.stop();
+ {
+ if(FlxG.sound.music != null)
+ FlxG.sound.music.stop();
+ }
else
{
tag = LuaUtils.formatVariable('sound_$tag');
@@ -1386,7 +1319,10 @@ class FunkinLua {
});
Lua_helper.add_callback(lua, "pauseSound", function(tag:String) {
if(tag == null || tag.length < 1)
- if(FlxG.sound.music != null) FlxG.sound.music.pause();
+ {
+ if(FlxG.sound.music != null)
+ FlxG.sound.music.pause();
+ }
else
{
tag = LuaUtils.formatVariable('sound_$tag');
@@ -1396,7 +1332,10 @@ class FunkinLua {
});
Lua_helper.add_callback(lua, "resumeSound", function(tag:String) {
if(tag == null || tag.length < 1)
- if(FlxG.sound.music != null) FlxG.sound.music.play();
+ {
+ if(FlxG.sound.music != null)
+ FlxG.sound.music.play();
+ }
else
{
tag = LuaUtils.formatVariable('sound_$tag');
@@ -1762,27 +1701,6 @@ class FunkinLua {
return (result == 'true');
}
- function findScript(scriptFile:String, ext:String = '.lua')
- {
- if(!scriptFile.endsWith(ext)) scriptFile += ext;
- var preloadPath:String = Paths.getSharedPath(scriptFile);
- #if MODS_ALLOWED
- var path:String = Paths.modFolders(scriptFile);
- if(FileSystem.exists(scriptFile))
- return scriptFile;
- else if(FileSystem.exists(path))
- return path;
-
- if(FileSystem.exists(preloadPath))
- #else
- if(Assets.exists(preloadPath))
- #end
- {
- return preloadPath;
- }
- return null;
- }
-
public function getErrorMessage(status:Int):String {
var v:String = Lua.tostring(lua, -1);
Lua.pop(lua, 1);
@@ -1869,4 +1787,4 @@ class FunkinLua {
return false;
}
}
-#end
\ No newline at end of file
+#end
diff --git a/source/psychlua/HScript.hx b/source/psychlua/HScript.hx
index a421ee71e2a..59eca54b644 100644
--- a/source/psychlua/HScript.hx
+++ b/source/psychlua/HScript.hx
@@ -10,9 +10,11 @@ import psychlua.FunkinLua;
#end
#if HSCRIPT_ALLOWED
-import tea.SScript;
-class HScript extends SScript
+import crowplexus.iris.Iris;
+
+class HScript extends Iris
{
+ public var filePath:String;
public var modFolder:String;
#if LUA_ALLOWED
@@ -37,11 +39,14 @@ class HScript extends SScript
else
{
hs.varsToBring = varsToBring;
- hs.doString(code);
- @:privateAccess
- if(hs.parsingException != null)
+ try
+ {
+ hs.scriptCode = code;
+ hs.execute();
+ }
+ catch(e:Dynamic)
{
- PlayState.instance.addTextToDebug('ERROR ON LOADING (${hs.origin}): ${hs.parsingException.message}', FlxColor.RED);
+ FunkinLua.luaTrace('ERROR (${hs.origin}) - $e', false, false, FlxColor.RED);
}
}
}
@@ -53,7 +58,7 @@ class HScript extends SScript
if (file == null)
file = '';
- super(file, false, false);
+ super(null, {name: "hscript-iris", autoRun: false, autoPreset: false});
#if LUA_ALLOWED
parentLua = parent;
@@ -64,20 +69,31 @@ class HScript extends SScript
}
#end
- if (scriptFile != null && scriptFile.length > 0)
+ filePath = file;
+ if (filePath != null && filePath.length > 0)
{
- this.origin = scriptFile;
+ this.origin = filePath;
#if MODS_ALLOWED
- var myFolder:Array = scriptFile.split('/');
+ var myFolder:Array = filePath.split('/');
if(myFolder[0] + '/' == Paths.mods() && (Mods.currentModDirectory == myFolder[1] || Mods.getGlobalMods().contains(myFolder[1]))) //is inside mods folder
this.modFolder = myFolder[1];
#end
}
- this.varsToBring = varsToBring;
+ var scriptThing:String = file;
+ if(parent == null && file != null)
+ {
+ var f:String = file.replace('\\', '/');
+ if(f.contains('/') && !f.contains('\n'))
+ {
+ scriptThing = File.getContent(f);
+ }
+ }
+ this.scriptCode = scriptThing;
preset();
execute();
+ this.varsToBring = varsToBring;
}
var varsToBring(default, set):Any = null;
@@ -303,67 +319,56 @@ class HScript extends SScript
set('addBehindGF', PlayState.instance.addBehindGF);
set('addBehindDad', PlayState.instance.addBehindDad);
set('addBehindBF', PlayState.instance.addBehindBF);
- setSpecialObject(PlayState.instance, false, PlayState.instance.instancesExclude);
}
}
- public function executeCode(?funcToRun:String = null, ?funcArgs:Array = null):Tea {
+ public function executeCode(?funcToRun:String = null, ?funcArgs:Array = null):IrisCall {
if (funcToRun == null) return null;
if(!exists(funcToRun)) {
#if LUA_ALLOWED
- FunkinLua.luaTrace(origin + ' - No HScript function named: $funcToRun', false, false, FlxColor.RED);
+ FunkinLua.luaTrace(origin + ' - No function named: $funcToRun', false, false, FlxColor.RED);
#else
- PlayState.instance.addTextToDebug(origin + ' - No HScript function named: $funcToRun', FlxColor.RED);
+ PlayState.instance.addTextToDebug(origin + ' - No function named: $funcToRun', FlxColor.RED);
#end
return null;
}
- final callValue = call(funcToRun, funcArgs);
- if (!callValue.succeeded)
+ try
{
- final e = callValue.exceptions[0];
- if (e != null) {
- var msg:String = e.toString();
- #if LUA_ALLOWED
- if(parentLua != null)
- {
- FunkinLua.luaTrace('$origin: ${parentLua.lastCalledFunction} - $msg', false, false, FlxColor.RED);
- return null;
- }
- #end
- PlayState.instance.addTextToDebug('$origin - $msg', FlxColor.RED);
- }
- return null;
+ final callValue:IrisCall = call(funcToRun, funcArgs);
+ return callValue.signature;
}
- return callValue;
+ catch(e:Dynamic)
+ {
+ trace('ERROR ${funcToRun}: $e');
+ }
+ return null;
}
- public function executeFunction(funcToRun:String = null, funcArgs:Array):Tea {
- if (funcToRun == null) return null;
+ public function executeFunction(funcToRun:String = null, funcArgs:Array = null):IrisCall {
+ if (funcToRun == null || !exists(funcToRun)) return null;
return call(funcToRun, funcArgs);
}
#if LUA_ALLOWED
public static function implement(funk:FunkinLua) {
- funk.addLocalCallback("runHaxeCode", function(codeToRun:String, ?varsToBring:Any = null, ?funcToRun:String = null, ?funcArgs:Array = null):Dynamic {
- #if SScript
+ funk.addLocalCallback("runHaxeCode", function(codeToRun:String, ?varsToBring:Any = null, ?funcToRun:String = null, ?funcArgs:Array = null):IrisCall {
+ #if HSCRIPT_ALLOWED
initHaxeModuleCode(funk, codeToRun, varsToBring);
- final retVal:Tea = funk.hscript.executeCode(funcToRun, funcArgs);
- if (retVal != null) {
- if(retVal.succeeded)
- return (retVal.returnValue == null || LuaUtils.isOfTypes(retVal.returnValue, [Bool, Int, Float, String, Array])) ? retVal.returnValue : null;
-
- final e = retVal.exceptions[0];
- final calledFunc:String = if(funk.hscript.origin == funk.lastCalledFunction) funcToRun else funk.lastCalledFunction;
- if (e != null)
- FunkinLua.luaTrace(funk.hscript.origin + ":" + calledFunc + " - " + e, false, false, FlxColor.RED);
- return null;
+ try
+ {
+ final retVal:IrisCall = funk.hscript.executeCode(funcToRun, funcArgs);
+ if (retVal != null)
+ {
+ return (retVal.signature == null || LuaUtils.isOfTypes(retVal.signature, [Bool, Int, Float, String, Array])) ? retVal.signature : null;
+ }
}
- else if (funk.hscript.returnValue != null)
+ catch(e:Dynamic)
{
- return funk.hscript.returnValue;
+ FunkinLua.luaTrace('ERROR (${funk.hscript.origin}: $funcToRun) - $e', false, false, FlxColor.RED);
}
+
#else
FunkinLua.luaTrace("runHaxeCode: HScript isn't supported on this platform!", false, false, FlxColor.RED);
#end
@@ -371,22 +376,26 @@ class HScript extends SScript
});
funk.addLocalCallback("runHaxeFunction", function(funcToRun:String, ?funcArgs:Array = null) {
- #if SScript
- var callValue = funk.hscript.executeFunction(funcToRun, funcArgs);
- if (!callValue.succeeded)
+ #if HSCRIPT_ALLOWED
+ try
+ {
+ final retVal:IrisCall = funk.hscript.executeFunction(funcToRun, funcArgs);
+ if (retVal != null)
+ {
+ return (retVal.signature == null || LuaUtils.isOfTypes(retVal.signature, [Bool, Int, Float, String, Array])) ? retVal.signature : null;
+ }
+ }
+ catch(e:Dynamic)
{
- var e = callValue.exceptions[0];
- if (e != null)
- FunkinLua.luaTrace('ERROR (${funk.hscript.origin}: ${callValue.calledFunction}) - ' + e.message.substr(0, e.message.indexOf('\n')), false, false, FlxColor.RED);
- return null;
+ FunkinLua.luaTrace('ERROR (${funk.hscript.origin}: $funcToRun) - $e', false, false, FlxColor.RED);
}
- else
- return callValue.returnValue;
+ return null;
#else
FunkinLua.luaTrace("runHaxeFunction: HScript isn't supported on this platform!", false, false, FlxColor.RED);
+ return null;
#end
});
- // This function is unnecessary because import already exists in SScript as a native feature
+ // This function is unnecessary because import already exists in HScript as a native feature
funk.addLocalCallback("addHaxeLibrary", function(libName:String, ?libPackage:String = '') {
var str:String = '';
if(libPackage.length > 0)
@@ -398,12 +407,7 @@ class HScript extends SScript
if (c == null)
c = Type.resolveEnum(str + libName);
- #if SScript
- if (c != null)
- SScript.globalVariables[libName] = c;
- #end
-
- #if SScript
+ #if HSCRIPT_ALLOWED
if (funk.hscript != null)
{
try {
@@ -421,6 +425,17 @@ class HScript extends SScript
}
#end
+ override public function set(name:String, value:Dynamic, allowOverride:Bool = false):Void {
+ // should always override by default
+ super.set(name, value, true);
+ }
+
+ /*override function irisPrint(v):Void
+ {
+ FunkinLua.luaTrace('ERROR (${this.origin}:${interp.posInfos().lineNumber}): ${v}');
+ trace('[${ruleSet.name}:${interp.posInfos().lineNumber}]: ${v}\n');
+ }*/
+
override public function destroy()
{
origin = null;
@@ -430,14 +445,15 @@ class HScript extends SScript
}
function set_varsToBring(values:Any) {
- if (varsToBring != null) {
- for (key in Reflect.fields(varsToBring)) {
- unset(key.trim());
- }
- }
+ if (varsToBring != null)
+ for (key in Reflect.fields(varsToBring))
+ if(exists(key.trim()))
+ interp.variables.remove(key.trim());
- if (values != null) {
- for (key in Reflect.fields(values)) {
+ if (values != null)
+ {
+ for (key in Reflect.fields(values))
+ {
key = key.trim();
set(key, Reflect.field(values, key));
}
diff --git a/source/psychlua/LuaUtils.hx b/source/psychlua/LuaUtils.hx
index 2dbd096a5f5..99e382541c6 100644
--- a/source/psychlua/LuaUtils.hx
+++ b/source/psychlua/LuaUtils.hx
@@ -20,11 +20,11 @@ typedef LuaTweenOptions = {
class LuaUtils
{
- public static final Function_Stop:Dynamic = "##PSYCHLUA_FUNCTIONSTOP";
- public static final Function_Continue:Dynamic = "##PSYCHLUA_FUNCTIONCONTINUE";
- public static final Function_StopLua:Dynamic = "##PSYCHLUA_FUNCTIONSTOPLUA";
- public static final Function_StopHScript:Dynamic = "##PSYCHLUA_FUNCTIONSTOPHSCRIPT";
- public static final Function_StopAll:Dynamic = "##PSYCHLUA_FUNCTIONSTOPALL";
+ public static final Function_Stop:String = "##PSYCHLUA_FUNCTIONSTOP";
+ public static final Function_Continue:String = "##PSYCHLUA_FUNCTIONCONTINUE";
+ public static final Function_StopLua:String = "##PSYCHLUA_FUNCTIONSTOPLUA";
+ public static final Function_StopHScript:String = "##PSYCHLUA_FUNCTIONSTOPHSCRIPT";
+ public static final Function_StopAll:String = "##PSYCHLUA_FUNCTIONSTOPALL";
public static function getLuaTween(options:Dynamic)
{
@@ -497,9 +497,12 @@ class LuaUtils
public static function cameraFromString(cam:String):FlxCamera {
switch(cam.toLowerCase()) {
+ case 'camgame' | 'game': return PlayState.instance.camGame;
case 'camhud' | 'hud': return PlayState.instance.camHUD;
case 'camother' | 'other': return PlayState.instance.camOther;
}
- return PlayState.instance.camGame;
+ var camera:FlxCamera = MusicBeatState.getVariables().get(cam);
+ if (camera == null || !Std.isOfType(camera, FlxCamera)) camera = PlayState.instance.camGame;
+ return camera;
}
}
\ No newline at end of file
diff --git a/source/psychlua/ReflectionFunctions.hx b/source/psychlua/ReflectionFunctions.hx
index 1c32a6b27ca..b1a485e2ea0 100644
--- a/source/psychlua/ReflectionFunctions.hx
+++ b/source/psychlua/ReflectionFunctions.hx
@@ -26,10 +26,10 @@ class ReflectionFunctions
var split:Array = variable.split('.');
if(split.length > 1) {
LuaUtils.setVarInArray(LuaUtils.getPropertyLoop(split, true, allowMaps), split[split.length-1], value, allowMaps);
- return true;
+ return value;
}
LuaUtils.setVarInArray(LuaUtils.getTargetInstance(), variable, value, allowMaps);
- return true;
+ return value;
});
Lua_helper.add_callback(lua, "getPropertyFromClass", function(classVar:String, variable:String, ?allowMaps:Bool = false) {
var myClass:Dynamic = Type.resolveClass(classVar);
diff --git a/source/psychlua/ShaderFunctions.hx b/source/psychlua/ShaderFunctions.hx
index 79ae92ed637..c9f755d02c1 100644
--- a/source/psychlua/ShaderFunctions.hx
+++ b/source/psychlua/ShaderFunctions.hx
@@ -13,7 +13,7 @@ class ShaderFunctions
funk.addLocalCallback("initLuaShader", function(name:String, ?glslVersion:Int = 120) {
if(!ClientPrefs.data.shaders) return false;
- #if (!flash && MODS_ALLOWED && sys)
+ #if (!flash && sys)
return funk.initLuaShader(name, glslVersion);
#else
FunkinLua.luaTrace("initLuaShader: Platform unsupported for Runtime Shaders!", false, false, FlxColor.RED);
@@ -24,7 +24,7 @@ class ShaderFunctions
funk.addLocalCallback("setSpriteShader", function(obj:String, shader:String) {
if(!ClientPrefs.data.shaders) return false;
- #if (!flash && MODS_ALLOWED && sys)
+ #if (!flash && sys)
if(!funk.runtimeShaders.exists(shader) && !funk.initLuaShader(shader))
{
FunkinLua.luaTrace('setSpriteShader: Shader $shader is missing!', false, false, FlxColor.RED);
@@ -63,7 +63,7 @@ class ShaderFunctions
Lua_helper.add_callback(lua, "getShaderBool", function(obj:String, prop:String) {
- #if (!flash && MODS_ALLOWED && sys)
+ #if (!flash && sys)
var shader:FlxRuntimeShader = getShader(obj);
if (shader == null)
{
@@ -77,7 +77,7 @@ class ShaderFunctions
#end
});
Lua_helper.add_callback(lua, "getShaderBoolArray", function(obj:String, prop:String) {
- #if (!flash && MODS_ALLOWED && sys)
+ #if (!flash && sys)
var shader:FlxRuntimeShader = getShader(obj);
if (shader == null)
{
@@ -91,7 +91,7 @@ class ShaderFunctions
#end
});
Lua_helper.add_callback(lua, "getShaderInt", function(obj:String, prop:String) {
- #if (!flash && MODS_ALLOWED && sys)
+ #if (!flash && sys)
var shader:FlxRuntimeShader = getShader(obj);
if (shader == null)
{
@@ -105,7 +105,7 @@ class ShaderFunctions
#end
});
Lua_helper.add_callback(lua, "getShaderIntArray", function(obj:String, prop:String) {
- #if (!flash && MODS_ALLOWED && sys)
+ #if (!flash && sys)
var shader:FlxRuntimeShader = getShader(obj);
if (shader == null)
{
@@ -119,7 +119,7 @@ class ShaderFunctions
#end
});
Lua_helper.add_callback(lua, "getShaderFloat", function(obj:String, prop:String) {
- #if (!flash && MODS_ALLOWED && sys)
+ #if (!flash && sys)
var shader:FlxRuntimeShader = getShader(obj);
if (shader == null)
{
@@ -133,7 +133,7 @@ class ShaderFunctions
#end
});
Lua_helper.add_callback(lua, "getShaderFloatArray", function(obj:String, prop:String) {
- #if (!flash && MODS_ALLOWED && sys)
+ #if (!flash && sys)
var shader:FlxRuntimeShader = getShader(obj);
if (shader == null)
{
@@ -149,7 +149,7 @@ class ShaderFunctions
Lua_helper.add_callback(lua, "setShaderBool", function(obj:String, prop:String, value:Bool) {
- #if (!flash && MODS_ALLOWED && sys)
+ #if (!flash && sys)
var shader:FlxRuntimeShader = getShader(obj);
if(shader == null)
{
@@ -164,7 +164,7 @@ class ShaderFunctions
#end
});
Lua_helper.add_callback(lua, "setShaderBoolArray", function(obj:String, prop:String, values:Dynamic) {
- #if (!flash && MODS_ALLOWED && sys)
+ #if (!flash && sys)
var shader:FlxRuntimeShader = getShader(obj);
if(shader == null)
{
@@ -179,7 +179,7 @@ class ShaderFunctions
#end
});
Lua_helper.add_callback(lua, "setShaderInt", function(obj:String, prop:String, value:Int) {
- #if (!flash && MODS_ALLOWED && sys)
+ #if (!flash && sys)
var shader:FlxRuntimeShader = getShader(obj);
if(shader == null)
{
@@ -194,7 +194,7 @@ class ShaderFunctions
#end
});
Lua_helper.add_callback(lua, "setShaderIntArray", function(obj:String, prop:String, values:Dynamic) {
- #if (!flash && MODS_ALLOWED && sys)
+ #if (!flash && sys)
var shader:FlxRuntimeShader = getShader(obj);
if(shader == null)
{
@@ -209,7 +209,7 @@ class ShaderFunctions
#end
});
Lua_helper.add_callback(lua, "setShaderFloat", function(obj:String, prop:String, value:Float) {
- #if (!flash && MODS_ALLOWED && sys)
+ #if (!flash && sys)
var shader:FlxRuntimeShader = getShader(obj);
if(shader == null)
{
@@ -224,7 +224,7 @@ class ShaderFunctions
#end
});
Lua_helper.add_callback(lua, "setShaderFloatArray", function(obj:String, prop:String, values:Dynamic) {
- #if (!flash && MODS_ALLOWED && sys)
+ #if (!flash && sys)
var shader:FlxRuntimeShader = getShader(obj);
if(shader == null)
{
@@ -241,7 +241,7 @@ class ShaderFunctions
});
Lua_helper.add_callback(lua, "setShaderSampler2D", function(obj:String, prop:String, bitmapdataPath:String) {
- #if (!flash && MODS_ALLOWED && sys)
+ #if (!flash && sys)
var shader:FlxRuntimeShader = getShader(obj);
if(shader == null)
{
diff --git a/source/psychlua/TextFunctions.hx b/source/psychlua/TextFunctions.hx
index 9c011be1e67..4c25a2c9152 100644
--- a/source/psychlua/TextFunctions.hx
+++ b/source/psychlua/TextFunctions.hx
@@ -5,7 +5,7 @@ class TextFunctions
public static function implement(funk:FunkinLua)
{
var lua = funk.lua;
- Lua_helper.add_callback(lua, "makeLuaText", function(tag:String, text:String, width:Int, x:Float, y:Float) {
+ Lua_helper.add_callback(lua, "makeLuaText", function(tag:String, ?text:String = '', ?width:Int = 0, ?x:Float = 0, ?y:Float = 0) {
tag = tag.replace('.', '');
LuaUtils.destroyObject(tag);
diff --git a/source/states/CreditsState.hx b/source/states/CreditsState.hx
index 4e5b51e2ca1..33ab5312fc5 100644
--- a/source/states/CreditsState.hx
+++ b/source/states/CreditsState.hx
@@ -39,31 +39,31 @@ class CreditsState extends MusicBeatState
var defaultList:Array> = [ //Name - Icon name - Description - Link - BG Color
["Psych Engine Team"],
- ["Shadow Mario", "shadowmario", "Main Programmer and Head of Psych Engine", "https://ko-fi.com/shadowmario", "444444"],
- ["Riveren", "riveren", "Main Artist/Animator of Psych Engine", "https://twitter.com/riverennn", "14967B"],
+ ["Shadow Mario", "shadowmario", "Main Programmer and Head of Psych Engine", "https://ko-fi.com/shadowmario", "444444"],
+ ["Riveren", "riveren", "Main Artist/Animator of Psych Engine", "https://x.com/riverennn", "14967B"],
[""],
["Former Engine Members"],
- ["bb-panzu", "bb", "Ex-Programmer of Psych Engine", "https://twitter.com/bbsub3", "3E813A"],
+ ["bb-panzu", "bb", "Ex-Programmer of Psych Engine", "https://x.com/bbsub3", "3E813A"],
[""],
["Engine Contributors"],
- ["crowplexus", "crowplexus", "Input System v3, Major Help and Other PRs", "https://twitter.com/crowplexus", "A1A1A1"],
- ["Kamizeta", "kamizeta", "Creator of Pessy, Psych Engine's mascot.", "https://twitter.com/LittleCewwy", "D21C11"],
- ["MaxNeton", "maxneton", "Loading Screen Easter Egg Artist/Animator.", "https://twitter.com/MaxNeton", "3C2E4E"],
- ["Keoiki", "keoiki", "Note Splash Animations and Latin Alphabet", "https://twitter.com/Keoiki_", "D2D2D2"],
- ["SqirraRNG", "sqirra", "Crash Handler and Base code for\nChart Editor's Waveform", "https://twitter.com/gedehari", "E1843A"],
- ["EliteMasterEric", "mastereric", "Runtime Shaders support and Other PRs", "https://twitter.com/EliteMasterEric", "FFBD40"],
- ["MAJigsaw77", "majigsaw", ".MP4 Video Loader Library (hxvlc)", "https://twitter.com/MAJigsaw77", "A1A1A1"],
- ["Tahir Toprak Karabekiroglu", "tahir", "Implementing & Maintaining SScript and Other PRs", "https://twitter.com/TahirKarabekir", "A04397"],
- ["iFlicky", "flicky", "Composer of Psync and Tea Time\nMade the Dialogue Sounds", "https://twitter.com/flicky_i", "9E29CF"],
- ["KadeDev", "kade", "Fixed some issues on Chart Editor and Other PRs", "https://twitter.com/kade0912", "64A250"],
- ["superpowers04", "superpowers04", "LUA JIT Fork", "https://twitter.com/superpowers04", "B957ED"],
- ["CheemsAndFriends", "cheems", "Creator of FlxAnimate", "https://twitter.com/CheemsnFriendos", "E1E1E1"],
+ ["crowplexus", "crowplexus", "HScript Iris, Input System v3, and Other PRs", "https://github.com/crowplexus", "CFCFCF"],
+ ["Kamizeta", "kamizeta", "Creator of Pessy, Psych Engine's mascot.", "https://www.instagram.com/cewweey/", "D21C11"],
+ ["MaxNeton", "maxneton", "Loading Screen Easter Egg Artist/Animator.", "https://bsky.app/profile/maxneton.bsky.social","3C2E4E"],
+ ["Keoiki", "keoiki", "Note Splash Animations and Latin Alphabet", "https://x.com/Keoiki_", "D2D2D2"],
+ ["SqirraRNG", "sqirra", "Crash Handler and Base code for\nChart Editor's Waveform", "https://x.com/gedehari", "E1843A"],
+ ["EliteMasterEric", "mastereric", "Runtime Shaders support and Other PRs", "https://x.com/EliteMasterEric", "FFBD40"],
+ ["MAJigsaw77", "majigsaw", ".MP4 Video Loader Library (hxvlc)", "https://x.com/MAJigsaw77", "5F5F5F"],
+ ["Tahir Toprak Karabekiroglu", "tahir", "Note Splash Editor and Other PRs", "https://x.com/TahirKarabekir", "A04397"],
+ ["iFlicky", "flicky", "Composer of Psync and Tea Time\nAnd some sound effects", "https://x.com/flicky_i", "9E29CF"],
+ ["KadeDev", "kade", "Fixed some issues on Chart Editor and Other PRs", "https://x.com/kade0912", "64A250"],
+ ["superpowers04", "superpowers04", "LUA JIT Fork", "https://x.com/superpowers04", "B957ED"],
+ ["CheemsAndFriends", "cheems", "Creator of FlxAnimate", "https://x.com/CheemsnFriendos", "E1E1E1"],
[""],
["Funkin' Crew"],
- ["ninjamuffin99", "ninjamuffin99", "Programmer of Friday Night Funkin'", "https://twitter.com/ninja_muffin99", "CF2D2D"],
- ["PhantomArcade", "phantomarcade", "Animator of Friday Night Funkin'", "https://twitter.com/PhantomArcade3K", "FADC45"],
- ["evilsk8r", "evilsk8r", "Artist of Friday Night Funkin'", "https://twitter.com/evilsk8r", "5ABD4B"],
- ["kawaisprite", "kawaisprite", "Composer of Friday Night Funkin'", "https://twitter.com/kawaisprite", "378FC7"],
+ ["ninjamuffin99", "ninjamuffin99", "Programmer of Friday Night Funkin'", "https://x.com/ninja_muffin99", "CF2D2D"],
+ ["PhantomArcade", "phantomarcade", "Animator of Friday Night Funkin'", "https://x.com/PhantomArcade3K", "FADC45"],
+ ["evilsk8r", "evilsk8r", "Artist of Friday Night Funkin'", "https://x.com/evilsk8r", "5ABD4B"],
+ ["kawaisprite", "kawaisprite", "Composer of Friday Night Funkin'", "https://x.com/kawaisprite", "378FC7"],
[""],
["Psych Engine Discord"],
["Join the Psych Ward!", "discord", "", "https://discord.gg/2ka77eMXDv", "5165F6"]
diff --git a/source/states/FlashingState.hx b/source/states/FlashingState.hx
index 917dab5dd1e..a6ee4604b10 100644
--- a/source/states/FlashingState.hx
+++ b/source/states/FlashingState.hx
@@ -24,7 +24,7 @@ class FlashingState extends MusicBeatState
Press ESCAPE to ignore this message.\n
You've been warned!",
32);
- warnText.setFormat("VCR OSD Mono", 32, FlxColor.WHITE, CENTER);
+ warnText.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, CENTER);
warnText.screenCenter(Y);
add(warnText);
}
diff --git a/source/states/LoadingState.hx b/source/states/LoadingState.hx
index 371e860d36a..21d906d0e27 100644
--- a/source/states/LoadingState.hx
+++ b/source/states/LoadingState.hx
@@ -6,8 +6,11 @@ import openfl.display.BitmapData;
import openfl.utils.AssetType;
import openfl.utils.Assets as OpenFlAssets;
import flixel.graphics.FlxGraphic;
+import flixel.system.FlxAssets;
import flixel.FlxState;
+import flash.media.Sound;
+
import backend.Song;
import backend.StageData;
import objects.Character;
@@ -25,7 +28,7 @@ class LoadingState extends MusicBeatState
static var originalBitmapKeys:Map = [];
static var requestedBitmaps:Map = [];
- static var mutex:Mutex = new Mutex();
+ static var mutex:Mutex;
function new(target:FlxState, stopMusic:Bool)
{
@@ -194,21 +197,23 @@ class LoadingState extends MusicBeatState
FlxG.sound.play(Paths.sound('secret'));
pessy = new FlxSprite(700, 140);
+ pessy.frames = Paths.getSparrowAtlas('loading_screen/pessy');
+ pessy.animation.addByPrefix('run', 'run', 24, true);
+ pessy.animation.addByPrefix('spin', 'spin', 24, true);
+ pessy.antialiasing = ClientPrefs.data.antialiasing;
+ pessy.flipX = (logo.offset.x > 0);
+ pessy.x = FlxG.width + 200;
+ pessy.velocity.x = -1100;
+
new FlxTimer().start(0.01, function(tmr:FlxTimer) {
- pessy.frames = Paths.getSparrowAtlas('loading_screen/pessy');
- pessy.antialiasing = ClientPrefs.data.antialiasing;
- pessy.flipX = (logo.offset.x > 0);
- pessy.x = FlxG.width + 200;
- pessy.velocity.x = -1100;
if(pessy.flipX)
{
pessy.x = -pessy.width - 200;
- pessy.velocity.x = 1100;
+ pessy.velocity.x *= -1;
}
- pessy.animation.addByPrefix('run', 'run', 24, true);
- pessy.animation.addByPrefix('spin', 'spin', 24, true);
pessy.animation.play('run', true);
+ Achievements.unlock('pessy_easter_egg');
insert(members.indexOf(loadingText), pessy);
new FlxTimer().start(5, function(tmr:FlxTimer) canChangeState = true);
@@ -239,6 +244,7 @@ class LoadingState extends MusicBeatState
MusicBeatState.switchState(target);
transitioning = true;
finishedLoading = true;
+ mutex = null;
}
public static function checkLoaded():Bool
@@ -335,7 +341,7 @@ class LoadingState extends MusicBeatState
var noteSplash:String = NoteSplash.DEFAULT_SKIN;
if(PlayState.SONG.splashSkin != null && PlayState.SONG.splashSkin.length > 0) noteSplash = PlayState.SONG.splashSkin;
else noteSplash += NoteSplash.getSplashSkinPostfix();
- imagesToPrepare.push("noteSplashes/" + noteSplash);
+ imagesToPrepare.push(noteSplash);
try
{
@@ -382,24 +388,37 @@ class LoadingState extends MusicBeatState
song.stage = StageData.vanillaSongStage(folder);
var stageData:StageFile = StageData.getStageFile(song.stage);
- if (stageData != null && stageData.preload != null)
+ if (stageData != null)
{
var imgs:Array = [];
var snds:Array = [];
var mscs:Array = [];
- for (asset in Reflect.fields(stageData.preload))
+ if(stageData.preload != null)
{
- var filters:Int = Reflect.field(stageData.preload, asset);
- var asset:String = asset.trim();
+ for (asset in Reflect.fields(stageData.preload))
+ {
+ var filters:Int = Reflect.field(stageData.preload, asset);
+ var asset:String = asset.trim();
- if(filters < 0 || StageData.validateVisibility(filters))
+ if(filters < 0 || StageData.validateVisibility(filters))
+ {
+ if(asset.startsWith('images/'))
+ imgs.push(asset.substr('images/'.length));
+ else if(asset.startsWith('sounds/'))
+ snds.push(asset.substr('sounds/'.length));
+ else if(asset.startsWith('music/'))
+ mscs.push(asset.substr('music/'.length));
+ }
+ }
+ }
+
+ if (stageData.objects != null)
+ {
+ for (sprite in stageData.objects)
{
- if(asset.startsWith('images/'))
- imgs.push(asset.substr('images/'.length));
- else if(asset.startsWith('sounds/'))
- snds.push(asset.substr('sounds/'.length));
- else if(asset.startsWith('music/'))
- mscs.push(asset.substr('music/'.length));
+ if(sprite.type == 'sprite' || sprite.type == 'animatedSprite')
+ if((sprite.filters < 0 || StageData.validateVisibility(sprite.filters)) && !imgs.contains(sprite.image))
+ imgs.push(sprite.image);
}
}
prepare(imgs, snds, mscs);
@@ -460,15 +479,22 @@ class LoadingState extends MusicBeatState
static function clearInvalidFrom(arr:Array, prefix:String, ext:String, type:AssetType, ?parentFolder:String = null)
{
- for (i in 0...arr.length)
+ for (folder in arr.copy())
{
- var folder:String = arr[i];
- if(folder.trim().endsWith('/'))
+ var nam:String = folder.trim();
+ if(nam.endsWith('/'))
{
- for (subfolder in Mods.directoriesWithFile(Paths.getSharedPath(), '$prefix/$folder'))
+ for (subfolder in Mods.directoriesWithFile(Paths.getSharedPath(), '$prefix/$nam'))
+ {
for (file in FileSystem.readDirectory(subfolder))
+ {
if(file.endsWith(ext))
- arr.push(folder + file.substr(0, file.length - ext.length));
+ {
+ var toAdd:String = nam + haxe.io.Path.withoutExtension(file);
+ if(!arr.contains(toAdd)) arr.push(toAdd);
+ }
+ }
+ }
//trace('Folder detected! ' + folder);
}
@@ -495,53 +521,22 @@ class LoadingState extends MusicBeatState
public static function startThreads()
{
+ mutex = new Mutex();
loadMax = imagesToPrepare.length + soundsToPrepare.length + musicToPrepare.length + songsToPrepare.length;
loaded = 0;
//then start threads
- for (sound in soundsToPrepare) initThread(() -> Paths.sound(sound), 'sound $sound');
- for (music in musicToPrepare) initThread(() -> Paths.music(music), 'music $music');
- for (song in songsToPrepare) initThread(() -> Paths.returnSound(song, 'songs', true, false), 'song $song');
+ for (sound in soundsToPrepare) initThread(() -> preloadSound('sounds/$sound'), 'sound $sound');
+ for (music in musicToPrepare) initThread(() -> preloadSound('music/$music'), 'music $music');
+ for (song in songsToPrepare) initThread(() -> preloadSound(song, 'songs', true, false), 'song $song');
// for images, they get to have their own thread
- for (image in imagesToPrepare)
- Thread.create(() -> {
- mutex.acquire();
- try {
- var requestKey:String = 'images/$image';
- #if TRANSLATIONS_ALLOWED requestKey = Language.getFileTranslation(requestKey); #end
- if(requestKey.lastIndexOf('.') < 0) requestKey += '.png';
-
- if (!Paths.currentTrackedAssets.exists(requestKey))
- {
- var bitmap:BitmapData = null;
- var file:String = Paths.getPath(requestKey, IMAGE);
- if (#if sys FileSystem.exists(file) || #end OpenFlAssets.exists(file, IMAGE))
- {
- #if sys
- bitmap = BitmapData.fromFile(file);
- #else
- bitmap = OpenFlAssets.getBitmapData(file);
- #end
- requestedBitmaps.set(file, bitmap);
- originalBitmapKeys.set(file, requestKey);
- }
- else trace('no such image $image exists');
- }
- }
- catch(e:haxe.Exception)
- {
- trace('ERROR! fail on preloading image $image');
- }
- mutex.release();
- loaded++;
- });
+ for (image in imagesToPrepare) initThread(() -> preloadGraphic(image), 'image $image');
}
static function initThread(func:Void->Dynamic, traceData:String)
{
Thread.create(() -> {
- mutex.acquire();
try {
if (func() != null) trace('finished preloading $traceData');
else trace('ERROR! fail on preloading $traceData');
@@ -549,8 +544,9 @@ class LoadingState extends MusicBeatState
catch(e:Dynamic) {
trace('ERROR! fail on preloading $traceData');
}
- mutex.release();
+ mutex.acquire();
loaded++;
+ mutex.release();
});
}
@@ -611,4 +607,70 @@ class LoadingState extends MusicBeatState
trace(e.details());
}
}
+
+ // thread safe sound loader
+ static function preloadSound(key:String, ?path:String, ?modsAllowed:Bool = true, ?beepOnNull:Bool = true):Null
+ {
+ var file:String = Paths.getPath(Language.getFileTranslation(key) + '.${Paths.SOUND_EXT}', SOUND, path, modsAllowed);
+
+ //trace('precaching sound: $file');
+ if(!Paths.currentTrackedSounds.exists(file))
+ {
+ if (#if sys FileSystem.exists(file) || #end OpenFlAssets.exists(file, SOUND))
+ {
+ var sound:Sound = OpenFlAssets.getSound(file, false);
+ mutex.acquire();
+ Paths.currentTrackedSounds.set(file, sound);
+ mutex.release();
+ }
+ else if (beepOnNull)
+ {
+ trace('SOUND NOT FOUND: $key, PATH: $path');
+ FlxG.log.error('SOUND NOT FOUND: $key, PATH: $path');
+ return FlxAssets.getSound('flixel/sounds/beep');
+ }
+ }
+ mutex.acquire();
+ Paths.localTrackedAssets.push(file);
+ mutex.release();
+
+ return Paths.currentTrackedSounds.get(file);
+ }
+
+ // thread safe sound loader
+ static function preloadGraphic(key:String):Null
+ {
+ try {
+ var requestKey:String = 'images/$key';
+ #if TRANSLATIONS_ALLOWED requestKey = Language.getFileTranslation(requestKey); #end
+ if(requestKey.lastIndexOf('.') < 0) requestKey += '.png';
+
+ if (!Paths.currentTrackedAssets.exists(requestKey))
+ {
+ var file:String = Paths.getPath(requestKey, IMAGE);
+ if (#if sys FileSystem.exists(file) || #end OpenFlAssets.exists(file, IMAGE))
+ {
+ #if sys
+ var bitmap:BitmapData = BitmapData.fromFile(file);
+ #else
+ var bitmap:BitmapData = OpenFlAssets.getBitmapData(file, false);
+ #end
+ mutex.acquire();
+ requestedBitmaps.set(file, bitmap);
+ originalBitmapKeys.set(file, requestKey);
+ mutex.release();
+ return bitmap;
+ }
+ else trace('no such image $key exists');
+ }
+
+ return Paths.currentTrackedAssets.get(requestKey).bitmap;
+ }
+ catch(e:haxe.Exception)
+ {
+ trace('ERROR! fail on preloading image $key');
+ }
+
+ return null;
+ }
}
\ No newline at end of file
diff --git a/source/states/MainMenuState.hx b/source/states/MainMenuState.hx
index 2db463e0d3a..93e53b0977e 100644
--- a/source/states/MainMenuState.hx
+++ b/source/states/MainMenuState.hx
@@ -14,7 +14,7 @@ enum MainMenuColumn {
class MainMenuState extends MusicBeatState
{
- public static var psychEngineVersion:String = '1.0b'; // This is also used for Discord RPC
+ public static var psychEngineVersion:String = '1.0-prerelease'; // This is also used for Discord RPC
public static var curSelected:Int = 0;
public static var curColumn:MainMenuColumn = CENTER;
var allowMouse:Bool = true; //Turn this off to block mouse movement in menus
@@ -93,11 +93,11 @@ class MainMenuState extends MusicBeatState
var psychVer:FlxText = new FlxText(12, FlxG.height - 44, 0, "Psych Engine v" + psychEngineVersion, 12);
psychVer.scrollFactor.set();
- psychVer.setFormat("VCR OSD Mono", 16, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK);
+ psychVer.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK);
add(psychVer);
var fnfVer:FlxText = new FlxText(12, FlxG.height - 24, 0, "Friday Night Funkin' v" + Application.current.meta.get('version'), 12);
fnfVer.scrollFactor.set();
- fnfVer.setFormat("VCR OSD Mono", 16, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK);
+ fnfVer.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK);
add(fnfVer);
changeItem();
diff --git a/source/states/ModsMenuState.hx b/source/states/ModsMenuState.hx
index 47be4c0e61a..b2d2162bb30 100644
--- a/source/states/ModsMenuState.hx
+++ b/source/states/ModsMenuState.hx
@@ -818,11 +818,10 @@ class ModItem extends FlxSpriteGroup
var path:String = Paths.mods('$folder/data/settings.json');
if(FileSystem.exists(path))
{
- var data:String = File.getContent(path);
try
{
//trace('trying to load settings: $folder');
- settings = tjson.TJSON.parse(data);
+ settings = tjson.TJSON.parse(File.getContent(path));
}
catch(e:Dynamic)
{
diff --git a/source/states/OutdatedState.hx b/source/states/OutdatedState.hx
index a590cd3a0f8..5d3cb319e5e 100644
--- a/source/states/OutdatedState.hx
+++ b/source/states/OutdatedState.hx
@@ -20,7 +20,7 @@ class OutdatedState extends MusicBeatState
\n
Thank you for using the Engine!",
32);
- warnText.setFormat("VCR OSD Mono", 32, FlxColor.WHITE, CENTER);
+ warnText.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, CENTER);
warnText.screenCenter(Y);
add(warnText);
}
diff --git a/source/states/PlayState.hx b/source/states/PlayState.hx
index 4fdf0945731..67c1b1d0bd0 100644
--- a/source/states/PlayState.hx
+++ b/source/states/PlayState.hx
@@ -48,8 +48,8 @@ import psychlua.LuaUtils;
import psychlua.HScript;
#end
-#if SScript
-import tea.SScript;
+#if HSCRIPT_ALLOWED
+import crowplexus.iris.Iris;
#end
/**
@@ -95,7 +95,6 @@ class PlayState extends MusicBeatState
#if HSCRIPT_ALLOWED
public var hscriptArray:Array = [];
- public var instancesExclude:Array = [];
#end
public var BF_X:Float = 770;
@@ -146,10 +145,10 @@ class PlayState extends MusicBeatState
public var camFollow:FlxObject;
private static var prevCamFollow:FlxObject;
- public var strumLineNotes:FlxTypedGroup;
- public var opponentStrums:FlxTypedGroup;
- public var playerStrums:FlxTypedGroup;
- public var grpNoteSplashes:FlxTypedGroup;
+ public var strumLineNotes:FlxTypedGroup = new FlxTypedGroup();
+ public var opponentStrums:FlxTypedGroup = new FlxTypedGroup();
+ public var playerStrums:FlxTypedGroup = new FlxTypedGroup();
+ public var grpNoteSplashes:FlxTypedGroup = new FlxTypedGroup();
public var camZooming:Bool = false;
public var camZoomingMult:Float = 1;
@@ -248,10 +247,17 @@ class PlayState extends MusicBeatState
public var startCallback:Void->Void = null;
public var endCallback:Void->Void = null;
+ public static var nextReloadAll:Bool = false;
override public function create()
{
//trace('Playback Rate: ' + playbackRate);
Paths.clearStoredMemory();
+ if(nextReloadAll)
+ {
+ Paths.clearUnusedMemory();
+ Language.reloadPhrases();
+ }
+ nextReloadAll = false;
startCallback = startCountdown;
endCallback = endSong;
@@ -289,7 +295,6 @@ class PlayState extends MusicBeatState
FlxG.cameras.add(camHUD, false);
FlxG.cameras.add(camOther, false);
- grpNoteSplashes = new FlxTypedGroup();
persistentUpdate = true;
persistentDraw = true;
@@ -420,6 +425,7 @@ class PlayState extends MusicBeatState
initHScript(folder + file);
#end
}
+ #end
var camPos:FlxPoint = FlxPoint.get(girlfriendCameraOffset[0], girlfriendCameraOffset[1]);
if(gf != null)
@@ -434,7 +440,7 @@ class PlayState extends MusicBeatState
gf.visible = false;
}
-
+ #if (LUA_ALLOWED || HSCRIPT_ALLOWED)
// STAGE SCRIPTS
#if LUA_ALLOWED startLuasNamed('stages/' + curStage + '.lua'); #end
#if HSCRIPT_ALLOWED startHScriptsNamed('stages/' + curStage + '.hx'); #end
@@ -471,7 +477,6 @@ class PlayState extends MusicBeatState
uiGroup.add(timeBar);
uiGroup.add(timeTxt);
- strumLineNotes = new FlxTypedGroup();
noteGroup.add(strumLineNotes);
if(ClientPrefs.data.timeBarType == 'Song Name')
@@ -480,9 +485,6 @@ class PlayState extends MusicBeatState
timeTxt.y += 3;
}
- opponentStrums = new FlxTypedGroup();
- playerStrums = new FlxTypedGroup();
-
generateSong();
noteGroup.add(grpNoteSplashes);
@@ -534,14 +536,14 @@ class PlayState extends MusicBeatState
updateScore(false);
uiGroup.add(scoreTxt);
- botplayTxt = new FlxText(400, timeBar.y + 55, FlxG.width - 800, Language.getPhrase("Botplay").toUpperCase(), 32);
+ botplayTxt = new FlxText(400, healthBar.y - 90, FlxG.width - 800, Language.getPhrase("Botplay").toUpperCase(), 32);
botplayTxt.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK);
botplayTxt.scrollFactor.set();
botplayTxt.borderSize = 1.25;
botplayTxt.visible = cpuControlled;
uiGroup.add(botplayTxt);
if(ClientPrefs.data.downScroll)
- botplayTxt.y = timeBar.y - 78;
+ botplayTxt.y = healthBar.y + 70;
uiGroup.cameras = [camHUD];
noteGroup.cameras = [camHUD];
@@ -781,7 +783,7 @@ class PlayState extends MusicBeatState
if(doPush)
{
- if(SScript.global.exists(scriptFile))
+ if(Iris.instances.exists(scriptFile))
doPush = false;
if(doPush) initHScript(scriptFile);
@@ -1323,7 +1325,7 @@ class PlayState extends MusicBeatState
if (i != 0) {
// CLEAR ANY POSSIBLE GHOST NOTES
for (evilNote in unspawnNotes) {
- var matches: Bool = noteColumn == evilNote.noteData && gottaHitNote == evilNote.mustPress;
+ var matches: Bool = (noteColumn == evilNote.noteData && gottaHitNote == evilNote.mustPress && evilNote.noteType == noteType);
if (matches && Math.abs(spawnTime - evilNote.strumTime) == 0.0) {
evilNote.destroy();
unspawnNotes.remove(evilNote);
@@ -1334,8 +1336,8 @@ class PlayState extends MusicBeatState
}
var swagNote:Note = new Note(spawnTime, noteColumn, oldNote);
- var isAlt: Bool = section.altAnim && !swagNote.mustPress && !section.gfSection;
- swagNote.gfNote = (section.gfSection && gottaHitNote);
+ var isAlt: Bool = section.altAnim && !gottaHitNote;
+ swagNote.gfNote = (section.gfSection && gottaHitNote == section.mustHitSection);
swagNote.animSuffix = isAlt ? "-alt" : "";
swagNote.mustPress = gottaHitNote;
swagNote.sustainLength = holdLength;
@@ -1344,7 +1346,7 @@ class PlayState extends MusicBeatState
swagNote.scrollFactor.set();
unspawnNotes.push(swagNote);
- final roundSus:Int = Math.round(swagNote.sustainLength / Conductor.stepCrochet);
+ final roundSus:Int = Math.floor(swagNote.sustainLength / Conductor.stepCrochet);
if(roundSus > 0)
{
for (susNote in 0...roundSus + 1)
@@ -1454,8 +1456,9 @@ class PlayState extends MusicBeatState
}
function eventEarlyTrigger(event:EventNote):Float {
- var returnedValue:Null = callOnScripts('eventEarlyTrigger', [event.event, event.value1, event.value2, event.strumTime], true, [], [0]);
- if(returnedValue != null && returnedValue != 0 && returnedValue != LuaUtils.Function_Continue) {
+ var returnedValue:Dynamic = callOnScripts('eventEarlyTrigger', [event.event, event.value1, event.value2, event.strumTime], true, [], [0]);
+ returnedValue = Std.parseFloat(returnedValue);
+ if(!Math.isNaN(returnedValue) && returnedValue != 0) {
return returnedValue;
}
@@ -1677,8 +1680,8 @@ class PlayState extends MusicBeatState
Conductor.songPosition += elapsed * 1000 * playbackRate;
if (Conductor.songPosition >= Conductor.offset)
{
+ Conductor.songPosition = FlxMath.lerp(FlxG.sound.music.time + Conductor.offset, Conductor.songPosition, Math.exp(-elapsed * 5));
var timeDiff:Float = Math.abs((FlxG.sound.music.time + Conductor.offset) - Conductor.songPosition);
- Conductor.songPosition = FlxMath.lerp(FlxG.sound.music.time + Conductor.offset, Conductor.songPosition, Math.exp(-elapsed * 2.5));
if (timeDiff > 1000 * playbackRate)
Conductor.songPosition = Conductor.songPosition + 1000 * FlxMath.signOf(timeDiff);
}
@@ -1813,8 +1816,6 @@ class PlayState extends MusicBeatState
}
#end
- setOnScripts('cameraX', camFollow.x);
- setOnScripts('cameraY', camFollow.y);
setOnScripts('botPlay', cpuControlled);
callOnScripts('onUpdatePost', [elapsed]);
}
@@ -2247,7 +2248,6 @@ class PlayState extends MusicBeatState
callOnScripts('onEvent', [eventName, value1, value2, strumTime]);
}
- var lastCharFocus:String;
public function moveCameraSection(?sec:Null):Void {
if(sec == null) sec = curSection;
if(sec < 0) sec = 0;
@@ -2260,22 +2260,16 @@ class PlayState extends MusicBeatState
camFollow.x += gf.cameraPosition[0] + girlfriendCameraOffset[0];
camFollow.y += gf.cameraPosition[1] + girlfriendCameraOffset[1];
tweenCamIn();
- if (lastCharFocus != 'gf') {
- callOnScripts('onMoveCamera', ['gf']);
- lastCharFocus = 'gf';
- }
+ callOnScripts('onMoveCamera', ['gf']);
return;
}
var isDad:Bool = (SONG.notes[sec].mustHitSection != true);
moveCamera(isDad);
- if (isDad) {
- if (lastCharFocus != 'dad') callOnScripts('onMoveCamera', ['dad']);
- }
- else if (lastCharFocus != 'boyfriend') {
+ if (isDad)
+ callOnScripts('onMoveCamera', ['dad']);
+ else
callOnScripts('onMoveCamera', ['boyfriend']);
- }
- lastCharFocus = isDad ? 'dad' : 'boyfriend';
}
var cameraTwn:FlxTween;
@@ -2283,6 +2277,7 @@ class PlayState extends MusicBeatState
{
if(isDad)
{
+ if(dad == null) return;
camFollow.setPosition(dad.getMidpoint().x + 150, dad.getMidpoint().y - 100);
camFollow.x += dad.cameraPosition[0] + opponentCameraOffset[0];
camFollow.y += dad.cameraPosition[1] + opponentCameraOffset[1];
@@ -2290,6 +2285,7 @@ class PlayState extends MusicBeatState
}
else
{
+ if(boyfriend == null) return;
camFollow.setPosition(boyfriend.getMidpoint().x - 100, boyfriend.getMidpoint().y - 100);
camFollow.x -= boyfriend.cameraPosition[0] - boyfriendCameraOffset[0];
camFollow.y += boyfriend.cameraPosition[1] + boyfriendCameraOffset[1];
@@ -2668,13 +2664,11 @@ class PlayState extends MusicBeatState
// obtain notes that the player can hit
var plrInputNotes:Array = notes.members.filter(function(n:Note):Bool {
- var canHit:Bool = !strumsBlocked[n.noteData] && n.canBeHit && n.mustPress && !n.tooLate && !n.wasGoodHit && !n.blockHit;
- return n != null && canHit && !n.isSustainNote && n.noteData == key;
+ var canHit:Bool = n != null && !strumsBlocked[n.noteData] && n.canBeHit && n.mustPress && !n.tooLate && !n.wasGoodHit && !n.blockHit;
+ return canHit && !n.isSustainNote && n.noteData == key;
});
plrInputNotes.sort(sortHitNotes);
- var shouldMiss:Bool = !ClientPrefs.data.ghostTapping;
-
if (plrInputNotes.length != 0) { // slightly faster than doing `> 0` lol
var funnyNote:Note = plrInputNotes[0]; // front note
@@ -2694,10 +2688,12 @@ class PlayState extends MusicBeatState
}
goodNoteHit(funnyNote);
}
- else if(shouldMiss)
+ else
{
- callOnScripts('onGhostTap', [key]);
- noteMissPress(key);
+ if (ClientPrefs.data.ghostTapping)
+ callOnScripts('onGhostTap', [key]);
+ else
+ noteMissPress(key);
}
// Needed for the "Just the Two of Us" achievement.
@@ -3107,7 +3103,7 @@ class PlayState extends MusicBeatState
for (script in hscriptArray)
if(script != null)
{
- script.call('onDestroy');
+ script.executeFunction('onDestroy');
script.destroy();
}
@@ -3256,7 +3252,7 @@ class PlayState extends MusicBeatState
if(FileSystem.exists(scriptToLoad))
{
- if (SScript.global.exists(scriptToLoad)) return false;
+ if (Iris.instances.exists(scriptToLoad)) return false;
initHScript(scriptToLoad);
return true;
@@ -3266,57 +3262,26 @@ class PlayState extends MusicBeatState
public function initHScript(file:String)
{
+ var newScript:HScript = null;
try
{
- var newScript:HScript = new HScript(null, file);
- if(newScript.parsingException != null)
- {
- addTextToDebug('ERROR ON LOADING: ${newScript.parsingException.message}', FlxColor.RED);
- newScript.destroy();
- return;
- }
-
+ newScript = new HScript(null, file);
+ newScript.executeFunction('onCreate');
+ trace('initialized hscript interp successfully: $file');
hscriptArray.push(newScript);
- if(newScript.exists('onCreate'))
- {
- var callValue = newScript.call('onCreate');
- if(!callValue.succeeded)
- {
- for (e in callValue.exceptions)
- {
- if (e != null)
- {
- var len:Int = e.message.indexOf('\n') + 1;
- if(len <= 0) len = e.message.length;
- addTextToDebug('ERROR ($file: onCreate) - ${e.message.substr(0, len)}', FlxColor.RED);
- }
- }
-
- newScript.destroy();
- hscriptArray.remove(newScript);
- trace('failed to initialize tea interp!!! ($file)');
- }
- else trace('initialized tea interp successfully: $file');
- }
-
}
- catch(e)
+ catch(e:Dynamic)
{
- var len:Int = e.message.indexOf('\n') + 1;
- if(len <= 0) len = e.message.length;
- addTextToDebug('ERROR - ' + e.message.substr(0, len), FlxColor.RED);
- var newScript:HScript = cast (SScript.global.get(file), HScript);
+ addTextToDebug('ERROR ON LOADING ($file) - $e', FlxColor.RED);
+ var newScript:HScript = cast (Iris.instances.get(file), HScript);
if(newScript != null)
- {
newScript.destroy();
- hscriptArray.remove(newScript);
- }
}
}
#end
public function callOnScripts(funcToCall:String, args:Array = null, ignoreStops = false, exclusions:Array = null, excludeValues:Array = null):Dynamic {
- var returnVal:Dynamic = LuaUtils.Function_Continue;
+ var returnVal:String = LuaUtils.Function_Continue;
if(args == null) args = [];
if(exclusions == null) exclusions = [];
if(excludeValues == null) excludeValues = [LuaUtils.Function_Continue];
@@ -3327,7 +3292,7 @@ class PlayState extends MusicBeatState
}
public function callOnLuas(funcToCall:String, args:Array = null, ignoreStops = false, exclusions:Array = null, excludeValues:Array = null):Dynamic {
- var returnVal:Dynamic = LuaUtils.Function_Continue;
+ var returnVal:String = LuaUtils.Function_Continue;
#if LUA_ALLOWED
if(args == null) args = [];
if(exclusions == null) exclusions = [];
@@ -3366,7 +3331,7 @@ class PlayState extends MusicBeatState
}
public function callOnHScript(funcToCall:String, args:Array = null, ?ignoreStops:Bool = false, exclusions:Array = null, excludeValues:Array = null):Dynamic {
- var returnVal:Dynamic = LuaUtils.Function_Continue;
+ var returnVal:String = LuaUtils.Function_Continue;
#if HSCRIPT_ALLOWED
if(exclusions == null) exclusions = new Array();
@@ -3376,42 +3341,31 @@ class PlayState extends MusicBeatState
var len:Int = hscriptArray.length;
if (len < 1)
return returnVal;
- for(i in 0...len) {
- var script:HScript = hscriptArray[i];
+
+ for(script in hscriptArray)
+ {
+ @:privateAccess
if(script == null || !script.exists(funcToCall) || exclusions.contains(script.origin))
continue;
- var myValue:Dynamic = null;
- try {
+ try
+ {
var callValue = script.call(funcToCall, args);
- if(!callValue.succeeded)
+ var myValue:Dynamic = callValue.signature;
+
+ if((myValue == LuaUtils.Function_StopHScript || myValue == LuaUtils.Function_StopAll) && !excludeValues.contains(myValue) && !ignoreStops)
{
- var e = callValue.exceptions[0];
- if(e != null)
- {
- var len:Int = e.message.indexOf('\n') + 1;
- if(len <= 0) len = e.message.length;
- addTextToDebug('ERROR (${callValue.calledFunction}) - ' + e.message.substr(0, len), FlxColor.RED);
- }
+ returnVal = myValue;
+ break;
}
- else
- {
- myValue = callValue.returnValue;
-
- // compiler fuckup fix
- final stopHscript = myValue == LuaUtils.Function_StopHScript;
- final stopAll = myValue == LuaUtils.Function_StopAll;
- if((stopHscript || stopAll) && !excludeValues.contains(myValue) && !ignoreStops)
- {
- returnVal = myValue;
- break;
- }
- if(myValue != null && !excludeValues.contains(myValue))
- returnVal = myValue;
- }
+ if(myValue != null && !excludeValues.contains(myValue))
+ returnVal = myValue;
+ }
+ catch(e:Dynamic)
+ {
+ addTextToDebug('ERROR (${script.origin}: $funcToCall) - $e', FlxColor.RED);
}
- catch (e:Dynamic) {}
}
#end
@@ -3443,8 +3397,6 @@ class PlayState extends MusicBeatState
if(exclusions.contains(script.origin))
continue;
- if(!instancesExclude.contains(variable))
- instancesExclude.push(variable);
script.set(variable, arg);
}
#end
@@ -3495,10 +3447,12 @@ class PlayState extends MusicBeatState
}
fullComboFunction();
}
- updateScore(badHit); // score will only update after rating is calculated, if it's a badHit, it shouldn't bounce
setOnScripts('rating', ratingPercent);
setOnScripts('ratingName', ratingName);
setOnScripts('ratingFC', ratingFC);
+ setOnScripts('totalPlayed', totalPlayed);
+ setOnScripts('totalNotesHit', totalNotesHit);
+ updateScore(badHit); // score will only update after rating is calculated, if it's a badHit, it shouldn't bounce
}
#if ACHIEVEMENTS_ALLOWED
diff --git a/source/states/StoryMenuState.hx b/source/states/StoryMenuState.hx
index 001a684d96f..3db06eafd61 100644
--- a/source/states/StoryMenuState.hx
+++ b/source/states/StoryMenuState.hx
@@ -48,6 +48,7 @@ class StoryMenuState extends MusicBeatState
Paths.clearStoredMemory();
Paths.clearUnusedMemory();
+ persistentUpdate = persistentDraw = true;
PlayState.isStoryMode = true;
WeekData.reloadWeekFiles(true);
@@ -67,13 +68,12 @@ class StoryMenuState extends MusicBeatState
}
if(curWeek >= WeekData.weeksList.length) curWeek = 0;
- persistentUpdate = persistentDraw = true;
scoreText = new FlxText(10, 10, 0, Language.getPhrase('week_score', 'WEEK SCORE: {1}', [lerpScore]), 36);
- scoreText.setFormat("VCR OSD Mono", 32);
+ scoreText.setFormat(Paths.font("vcr.ttf"), 32);
txtWeekTitle = new FlxText(FlxG.width * 0.7, 10, 0, "", 32);
- txtWeekTitle.setFormat("VCR OSD Mono", 32, FlxColor.WHITE, RIGHT);
+ txtWeekTitle.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, RIGHT);
txtWeekTitle.alpha = 0.7;
var ui_tex = Paths.getSparrowAtlas('campaign_menu_UI_assets');
@@ -208,7 +208,7 @@ class StoryMenuState extends MusicBeatState
return;
}
- // scoreText.setFormat('VCR OSD Mono', 32);
+ // scoreText.setFormat(Paths.font("vcr.ttf"), 32);
if(intendedScore != lerpScore)
{
lerpScore = Math.floor(FlxMath.lerp(intendedScore, lerpScore, Math.exp(-elapsed * 30)));
diff --git a/source/states/TitleState.hx b/source/states/TitleState.hx
index a2d7690c236..d951751327d 100644
--- a/source/states/TitleState.hx
+++ b/source/states/TitleState.hx
@@ -21,14 +21,19 @@ import states.MainMenuState;
typedef TitleData =
{
- titlex:Float,
- titley:Float,
- startx:Float,
- starty:Float,
- gfx:Float,
- gfy:Float,
- backgroundSprite:String,
- bpm:Float
+ var titlex:Float;
+ var titley:Float;
+ var startx:Float;
+ var starty:Float;
+ var gfx:Float;
+ var gfy:Float;
+ var backgroundSprite:String;
+ var bpm:Float;
+
+ @:optional var animation:String;
+ @:optional var dance_left:Array;
+ @:optional var dance_right:Array;
+ @:optional var idle:Bool;
}
class TitleState extends MusicBeatState
@@ -39,10 +44,10 @@ class TitleState extends MusicBeatState
public static var initialized:Bool = false;
+ var credGroup:FlxGroup = new FlxGroup();
+ var textGroup:FlxGroup = new FlxGroup();
var blackScreen:FlxSprite;
- var credGroup:FlxGroup;
var credTextShit:Alphabet;
- var textGroup:FlxGroup;
var ngSpr:FlxSprite;
var titleTextColors:Array = [0xFF33FFFF, 0xFF3333CC];
@@ -53,27 +58,29 @@ class TitleState extends MusicBeatState
var wackyImage:FlxSprite;
#if TITLE_SCREEN_EASTER_EGG
- var easterEggKeys:Array = [
- 'SHADOW', 'RIVEREN', 'BBPANZU'
+ final easterEggKeys:Array = [
+ 'SHADOW', 'RIVEREN', 'BBPANZU', 'PESSY'
];
- var allowedKeys:String = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
+ final allowedKeys:String = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var easterEggKeysBuffer:String = '';
#end
var mustUpdate:Bool = false;
- var titleJSON:TitleData;
-
public static var updateVersion:String = '';
override public function create():Void
{
Paths.clearStoredMemory();
- ClientPrefs.loadPrefs();
- Language.reloadPhrases();
-
super.create();
-
+ Paths.clearUnusedMemory();
+
+ if(!initialized)
+ {
+ ClientPrefs.loadPrefs();
+ Language.reloadPhrases();
+ }
+
curWacky = FlxG.random.getObject(getIntroTextShit());
#if CHECK_FOR_UPDATES
@@ -100,26 +107,6 @@ class TitleState extends MusicBeatState
}
#end
-
- // IGNORE THIS!!!
- titleJSON = tjson.TJSON.parse(Paths.getTextFromFile('images/gfDanceTitle.json'));
-
- #if TITLE_SCREEN_EASTER_EGG
- if (FlxG.save.data.psychDevsEasterEgg == null) FlxG.save.data.psychDevsEasterEgg = ''; //Crash prevention
- switch(FlxG.save.data.psychDevsEasterEgg.toUpperCase())
- {
- case 'SHADOW':
- titleJSON.gfx += 210;
- titleJSON.gfy += 40;
- case 'RIVEREN':
- titleJSON.gfx += 180;
- titleJSON.gfy += 40;
- case 'BBPANZU':
- titleJSON.gfx += 45;
- titleJSON.gfy += 100;
- }
- #end
-
if(!initialized)
{
if(FlxG.save.data != null && FlxG.save.data.fullscreen)
@@ -142,20 +129,15 @@ class TitleState extends MusicBeatState
#elseif CHARTING
MusicBeatState.switchState(new ChartingState());
#else
- if(FlxG.save.data.flashing == null && !FlashingState.leftState) {
+ if(FlxG.save.data.flashing == null && !FlashingState.leftState)
+ {
FlxTransitionableState.skipNextTransIn = true;
FlxTransitionableState.skipNextTransOut = true;
MusicBeatState.switchState(new FlashingState());
- } else {
- if (initialized)
- startIntro();
- else
- {
- new FlxTimer().start(1, function(tmr:FlxTimer)
- {
- startIntro();
- });
- }
+ }
+ else
+ {
+ startIntro();
}
#end
}
@@ -168,142 +150,187 @@ class TitleState extends MusicBeatState
function startIntro()
{
+ persistentUpdate = true;
if (!initialized && FlxG.sound.music == null)
FlxG.sound.playMusic(Paths.music('freakyMenu'), 0);
- Conductor.bpm = titleJSON.bpm;
- persistentUpdate = true;
-
- var bg:FlxSprite = new FlxSprite();
- bg.antialiasing = ClientPrefs.data.antialiasing;
-
- if (titleJSON.backgroundSprite != null && titleJSON.backgroundSprite.length > 0 && titleJSON.backgroundSprite != "none"){
- bg.loadGraphic(Paths.image(titleJSON.backgroundSprite));
- }else{
- bg.makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK);
- }
-
- // bg.setGraphicSize(Std.int(bg.width * 0.6));
- // bg.updateHitbox();
- add(bg);
+ loadJsonData();
+ #if TITLE_SCREEN_EASTER_EGG easterEggData(); #end
+ Conductor.bpm = musicBPM;
- logoBl = new FlxSprite(titleJSON.titlex, titleJSON.titley);
+ logoBl = new FlxSprite(logoPosition.x, logoPosition.y);
logoBl.frames = Paths.getSparrowAtlas('logoBumpin');
logoBl.antialiasing = ClientPrefs.data.antialiasing;
logoBl.animation.addByPrefix('bump', 'logo bumpin', 24, false);
logoBl.animation.play('bump');
logoBl.updateHitbox();
- // logoBl.screenCenter();
- // logoBl.color = FlxColor.BLACK;
- if(ClientPrefs.data.shaders) swagShader = new ColorSwap();
- gfDance = new FlxSprite(titleJSON.gfx, titleJSON.gfy);
+ gfDance = new FlxSprite(gfPosition.x, gfPosition.y);
gfDance.antialiasing = ClientPrefs.data.antialiasing;
-
- var easterEgg:String = FlxG.save.data.psychDevsEasterEgg;
- if(easterEgg == null) easterEgg = ''; //html5 fix
-
- switch(easterEgg.toUpperCase())
- {
- // IGNORE THESE, GO DOWN A BIT
- #if TITLE_SCREEN_EASTER_EGG
- case 'SHADOW':
- gfDance.frames = Paths.getSparrowAtlas('ShadowBump');
- gfDance.animation.addByPrefix('danceLeft', 'Shadow Title Bump', 24);
- gfDance.animation.addByPrefix('danceRight', 'Shadow Title Bump', 24);
- case 'RIVEREN':
- gfDance.frames = Paths.getSparrowAtlas('RiverBump');
- gfDance.animation.addByIndices('danceLeft', 'River Title Bump', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false);
- gfDance.animation.addByIndices('danceRight', 'River Title Bump', [29, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false);
- case 'BBPANZU':
- gfDance.frames = Paths.getSparrowAtlas('BBBump');
- gfDance.animation.addByIndices('danceLeft', 'BB Title Bump', [14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27], "", 24, false);
- gfDance.animation.addByIndices('danceRight', 'BB Title Bump', [27, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], "", 24, false);
- #end
-
- default:
- //EDIT THIS ONE IF YOU'RE MAKING A SOURCE CODE MOD!!!!
- //EDIT THIS ONE IF YOU'RE MAKING A SOURCE CODE MOD!!!!
- //EDIT THIS ONE IF YOU'RE MAKING A SOURCE CODE MOD!!!!
- 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);
- }
-
- add(gfDance);
- add(logoBl);
- if(swagShader != null)
+
+ if(ClientPrefs.data.shaders)
{
+ swagShader = new ColorSwap();
gfDance.shader = swagShader.shader;
logoBl.shader = swagShader.shader;
}
+
+ gfDance.frames = Paths.getSparrowAtlas(characterImage);
+ if(!useIdle)
+ {
+ gfDance.animation.addByIndices('danceLeft', animationName, danceLeftFrames, "", 24, false);
+ gfDance.animation.addByIndices('danceRight', animationName, danceRightFrames, "", 24, false);
+ gfDance.animation.play('danceRight');
+ }
+ else
+ {
+ gfDance.animation.addByPrefix('idle', animationName, 24, false);
+ gfDance.animation.play('idle');
+ }
+
- titleText = new FlxSprite(titleJSON.startx, titleJSON.starty);
- titleText.frames = Paths.getSparrowAtlas('titleEnter');
var animFrames:Array = [];
- @:privateAccess {
+ titleText = new FlxSprite(enterPosition.x, enterPosition.y);
+ titleText.frames = Paths.getSparrowAtlas('titleEnter');
+ @:privateAccess
+ {
titleText.animation.findByPrefix(animFrames, "ENTER IDLE");
titleText.animation.findByPrefix(animFrames, "ENTER FREEZE");
}
- if (animFrames.length > 0) {
- newTitle = true;
-
+ if (newTitle = animFrames.length > 0)
+ {
titleText.animation.addByPrefix('idle', "ENTER IDLE", 24);
titleText.animation.addByPrefix('press', ClientPrefs.data.flashing ? "ENTER PRESSED" : "ENTER FREEZE", 24);
}
- else {
- newTitle = false;
-
+ else
+ {
titleText.animation.addByPrefix('idle', "Press Enter to Begin", 24);
titleText.animation.addByPrefix('press', "ENTER PRESSED", 24);
}
-
titleText.animation.play('idle');
titleText.updateHitbox();
- // titleText.screenCenter(X);
- add(titleText);
var logo:FlxSprite = new FlxSprite().loadGraphic(Paths.image('logo'));
logo.antialiasing = ClientPrefs.data.antialiasing;
logo.screenCenter();
- // add(logo);
-
- // FlxTween.tween(logoBl, {y: logoBl.y + 50}, 0.6, {ease: FlxEase.quadInOut, type: PINGPONG});
- // FlxTween.tween(logo, {y: logoBl.y + 50}, 0.6, {ease: FlxEase.quadInOut, type: PINGPONG, startDelay: 0.1});
-
- credGroup = new FlxGroup();
- add(credGroup);
- textGroup = new FlxGroup();
- blackScreen = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK);
+ blackScreen = new FlxSprite().makeGraphic(1, 1, FlxColor.BLACK);
+ blackScreen.scale.set(FlxG.width, FlxG.height);
+ blackScreen.updateHitbox();
credGroup.add(blackScreen);
credTextShit = new Alphabet(0, 0, "", true);
credTextShit.screenCenter();
-
- // credTextShit.alignment = CENTER;
-
credTextShit.visible = false;
ngSpr = new FlxSprite(0, FlxG.height * 0.52).loadGraphic(Paths.image('newgrounds_logo'));
- add(ngSpr);
ngSpr.visible = false;
ngSpr.setGraphicSize(Std.int(ngSpr.width * 0.8));
ngSpr.updateHitbox();
ngSpr.screenCenter(X);
ngSpr.antialiasing = ClientPrefs.data.antialiasing;
+ add(gfDance);
+ add(logoBl); //FNF Logo
+ add(titleText); //"Press Enter to Begin" text
+ add(credGroup);
+ add(ngSpr);
+
if (initialized)
skipIntro();
else
initialized = true;
- Paths.clearUnusedMemory();
// credGroup.add(credTextShit);
}
+ // JSON data
+ var characterImage:String = 'gfDanceTitle';
+ var animationName:String = 'gfDance';
+
+ var gfPosition:FlxPoint = FlxPoint.get(512, 40);
+ var logoPosition:FlxPoint = FlxPoint.get(-150, -100);
+ var enterPosition:FlxPoint = FlxPoint.get(100, 576);
+
+ var useIdle:Bool = false;
+ var musicBPM:Float = 102;
+ var danceLeftFrames:Array = [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29];
+ var danceRightFrames:Array = [30, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
+
+ function loadJsonData()
+ {
+ if(Paths.fileExists('images/gfDanceTitle.json', TEXT))
+ {
+ var titleRaw:String = Paths.getTextFromFile('images/gfDanceTitle.json');
+ if(titleRaw != null && titleRaw.length > 0)
+ {
+ try
+ {
+ var titleJSON:TitleData = tjson.TJSON.parse(titleRaw);
+ gfPosition.set(titleJSON.gfx, titleJSON.gfy);
+ logoPosition.set(titleJSON.titlex, titleJSON.titley);
+ enterPosition.set(titleJSON.startx, titleJSON.starty);
+ musicBPM = titleJSON.bpm;
+
+ if(titleJSON.animation != null && titleJSON.animation.length > 0) animationName = titleJSON.animation;
+ if(titleJSON.dance_left != null && titleJSON.dance_left.length > 0) danceLeftFrames = titleJSON.dance_left;
+ if(titleJSON.dance_right != null && titleJSON.dance_right.length > 0) danceRightFrames = titleJSON.dance_right;
+ useIdle = (titleJSON.idle == true);
+
+ if (titleJSON.backgroundSprite != null && titleJSON.backgroundSprite.trim().length > 0)
+ {
+ var bg:FlxSprite = new FlxSprite().loadGraphic(Paths.image(titleJSON.backgroundSprite));
+ bg.antialiasing = ClientPrefs.data.antialiasing;
+ add(bg);
+ }
+ }
+ catch(e:haxe.Exception)
+ {
+ trace('[WARN] Title JSON might broken, ignoring issue...\n${e.details()}');
+ }
+ }
+ else trace('[WARN] No Title JSON detected, using default values.');
+ }
+ //else trace('[WARN] No Title JSON detected, using default values.');
+ }
+
+ function easterEggData()
+ {
+ if (FlxG.save.data.psychDevsEasterEgg == null) FlxG.save.data.psychDevsEasterEgg = ''; //Crash prevention
+ var easterEgg:String = FlxG.save.data.psychDevsEasterEgg;
+ switch(easterEgg.toUpperCase())
+ {
+ case 'SHADOW':
+ characterImage = 'ShadowBump';
+ animationName = 'Shadow Title Bump';
+ gfPosition.x += 210;
+ gfPosition.y += 40;
+ useIdle = true;
+ case 'RIVEREN':
+ characterImage = 'ZRiverBump';
+ animationName = 'River Title Bump';
+ gfPosition.x += 180;
+ gfPosition.y += 40;
+ useIdle = true;
+ case 'BBPANZU':
+ characterImage = 'BBBump';
+ animationName = 'BB Title Bump';
+ danceLeftFrames = [14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27];
+ danceRightFrames = [27, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
+ gfPosition.x += 45;
+ gfPosition.y += 100;
+ case 'PESSY':
+ characterImage = 'PessyBump';
+ animationName = 'Pessy Title Bump';
+ gfPosition.x += 165;
+ gfPosition.y += 60;
+ danceLeftFrames = [29, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
+ danceRightFrames = [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28];
+ }
+ }
+
function getIntroTextShit():Array>
{
#if MODS_ALLOWED
@@ -395,11 +422,11 @@ class TitleState extends MusicBeatState
new FlxTimer().start(1, function(tmr:FlxTimer)
{
- if (mustUpdate) {
+ if (mustUpdate)
MusicBeatState.switchState(new OutdatedState());
- } else {
+ else
MusicBeatState.switchState(new MainMenuState());
- }
+
closedState = true;
});
// FlxG.sound.play(Paths.music('titleShoot'), 0.7);
@@ -428,7 +455,9 @@ class TitleState extends MusicBeatState
FlxG.sound.play(Paths.sound('secret'));
- var black:FlxSprite = new FlxSprite(0, 0).makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK);
+ var black:FlxSprite = new FlxSprite(0, 0).makeGraphic(1, 1, FlxColor.BLACK);
+ black.scale.set(FlxG.width, FlxG.height);
+ black.updateHitbox();
black.alpha = 0;
add(black);
@@ -477,7 +506,8 @@ class TitleState extends MusicBeatState
var money:Alphabet = new Alphabet(0, 0, textArray[i], true);
money.screenCenter(X);
money.y += (i * 60) + 200 + offset;
- if(credGroup != null && textGroup != null) {
+ if(credGroup != null && textGroup != null)
+ {
credGroup.add(money);
textGroup.add(money);
}
@@ -513,15 +543,21 @@ class TitleState extends MusicBeatState
if(logoBl != null)
logoBl.animation.play('bump', true);
- if(gfDance != null) {
+ if(gfDance != null)
+ {
danceLeft = !danceLeft;
- if (danceLeft)
- gfDance.animation.play('danceRight');
- else
- gfDance.animation.play('danceLeft');
+ if(!useIdle)
+ {
+ if (danceLeft)
+ gfDance.animation.play('danceRight');
+ else
+ gfDance.animation.play('danceLeft');
+ }
+ else if(curBeat % 2 == 0) gfDance.animation.play('idle', true);
}
- if(!closedState) {
+ if(!closedState)
+ {
sickBeats++;
switch (sickBeats)
{
@@ -572,6 +608,7 @@ class TitleState extends MusicBeatState
#if TITLE_SCREEN_EASTER_EGG
if (playJingle) //Ignore deez
{
+ playJingle = false;
var easteregg:String = FlxG.save.data.psychDevsEasterEgg;
if (easteregg == null) easteregg = '';
easteregg = easteregg.toUpperCase();
@@ -585,13 +622,14 @@ class TitleState extends MusicBeatState
FlxG.sound.play(Paths.sound('JingleShadow'));
case 'BBPANZU':
sound = FlxG.sound.play(Paths.sound('JingleBB'));
+ case 'PESSY':
+ sound = FlxG.sound.play(Paths.sound('JinglePessy'));
default: //Go back to normal ugly ass boring GF
remove(ngSpr);
remove(credGroup);
FlxG.camera.flash(FlxColor.WHITE, 2);
skippedIntro = true;
- playJingle = false;
FlxG.sound.playMusic(Paths.music('freakyMenu'), 0);
FlxG.sound.music.fadeIn(4, 0, 0.7);
@@ -618,9 +656,10 @@ class TitleState extends MusicBeatState
FlxG.sound.playMusic(Paths.music('freakyMenu'), 0);
FlxG.sound.music.fadeIn(4, 0, 0.7);
transitioning = false;
+ if(easteregg == 'PESSY')
+ Achievements.unlock('pessy_easter_egg');
};
}
- playJingle = false;
}
else #end //Default! Edit this one!!
{
diff --git a/source/states/editors/CharacterEditorState.hx b/source/states/editors/CharacterEditorState.hx
index febde87da42..4bba260b5f5 100644
--- a/source/states/editors/CharacterEditorState.hx
+++ b/source/states/editors/CharacterEditorState.hx
@@ -1,7 +1,6 @@
package states.editors;
import flixel.graphics.FlxGraphic;
-import flixel.graphics.frames.FlxAtlasFrames;
import flixel.system.debug.interaction.tools.Pointer.GraphicCursorCross;
import flixel.util.FlxDestroyUtil;
@@ -68,7 +67,8 @@ class CharacterEditorState extends MusicBeatState implements PsychUIEventHandler
override function create()
{
- if(ClientPrefs.data.cacheOnGPU) Paths.clearStoredMemory();
+ Paths.clearStoredMemory();
+ Paths.clearUnusedMemory();
FlxG.sound.music.stop();
camEditor = initPsychCamera();
@@ -815,22 +815,7 @@ class CharacterEditorState extends MusicBeatState implements PsychUIEventHandler
}
else
{
- var split:Array = character.imageFile.split(',');
- var charFrames:FlxAtlasFrames = Paths.getAtlas(split[0].trim());
-
- if(split.length > 1)
- {
- var original:FlxAtlasFrames = charFrames;
- charFrames = new FlxAtlasFrames(charFrames.parent);
- charFrames.addAtlas(original, true);
- for (i in 1...split.length)
- {
- var extraFrames:FlxAtlasFrames = Paths.getAtlas(split[i].trim());
- if(extraFrames != null)
- charFrames.addAtlas(extraFrames, true);
- }
- }
- character.frames = charFrames;
+ character.frames = Paths.getMultiAtlas(character.imageFile.split(','));
}
for (anim in anims) {
@@ -1065,7 +1050,6 @@ class CharacterEditorState extends MusicBeatState implements PsychUIEventHandler
}
else if(FlxG.keys.justPressed.ESCAPE)
{
- FlxG.mouse.visible = false;
if(!_goToPlayState)
{
if(!unsavedProgress)
@@ -1075,7 +1059,11 @@ class CharacterEditorState extends MusicBeatState implements PsychUIEventHandler
}
else openSubState(new ExitConfirmationPrompt());
}
- else MusicBeatState.switchState(new PlayState());
+ else
+ {
+ FlxG.mouse.visible = false;
+ MusicBeatState.switchState(new PlayState());
+ }
return;
}
}
diff --git a/source/states/editors/ChartingState.hx b/source/states/editors/ChartingState.hx
index 68799f9a5a4..1646fed3356 100644
--- a/source/states/editors/ChartingState.hx
+++ b/source/states/editors/ChartingState.hx
@@ -1,6 +1,5 @@
package states.editors;
-import flash.media.Sound;
import flixel.FlxSubState;
import flixel.util.FlxSave;
import flixel.util.FlxSort;
@@ -8,7 +7,16 @@ import flixel.util.FlxSpriteUtil;
import flixel.util.FlxStringUtil;
import flixel.util.FlxDestroyUtil;
import flixel.input.keyboard.FlxKey;
+
import lime.utils.Assets;
+import lime.media.AudioBuffer;
+
+import flash.media.Sound;
+import flash.geom.Rectangle;
+
+import haxe.Json;
+import haxe.Exception;
+import haxe.io.Bytes;
import states.editors.content.MetaNote;
import states.editors.content.VSlice;
@@ -24,8 +32,6 @@ import objects.Character;
import objects.HealthIcon;
import objects.Note;
import objects.StrumNote;
-import haxe.Json;
-import haxe.Exception;
using DateTools;
@@ -49,6 +55,13 @@ enum abstract ChartingTheme(String)
var DARK = 'dark';
}
+enum abstract WaveformTarget(String)
+{
+ var INST = 'inst';
+ var PLAYER = 'voc';
+ var OPPONENT = 'opp';
+}
+
class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychUIEvent
{
public static final defaultEvents:Array> =
@@ -72,7 +85,7 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
['Play Sound', "Value 1: Sound file name\nValue 2: Volume (Default: 1), ranges from 0 to 1"]
];
- public static var keysArray:Array = [ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT]; //Used for Vortex Editor
+ public static var keysArray:Array = [ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT]; //Used for Vortex Editor
public static var SHOW_EVENT_COLUMN = true;
public static var GRID_COLUMNS_PER_PLAYER = 4;
public static var GRID_PLAYERS = 2;
@@ -131,6 +144,7 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
var prevGridBg:ChartingGridSprite;
var gridBg:ChartingGridSprite;
var nextGridBg:ChartingGridSprite;
+ var waveformSprite:FlxSprite;
var scrollY:Float = 0;
var zoomList:Array = [
@@ -195,6 +209,10 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
var tipBg:FlxSprite;
var fullTipText:FlxText;
+
+ var vortexEnabled:Bool = false;
+ var waveformEnabled:Bool = false;
+ var waveformTarget:WaveformTarget = INST;
override function create()
{
@@ -231,7 +249,12 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
changeTheme(chartEditorSave.data.theme != null ? chartEditorSave.data.theme : DEFAULT, false);
- recreateGrids();
+ createGrids();
+
+ waveformSprite = new FlxSprite(gridBg.x + (SHOW_EVENT_COLUMN ? GRID_SIZE : 0), 0).makeGraphic(1, 1, 0x00FFFFFF);
+ waveformSprite.scrollFactor.x = 0;
+ waveformSprite.visible = false;
+ add(waveformSprite);
dummyArrow = new FlxSprite().makeGraphic(1, 1, FlxColor.WHITE);
dummyArrow.setGraphicSize(GRID_SIZE, GRID_SIZE);
@@ -479,6 +502,7 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
"Shift + Click - Select/Unselect Note(s)",
"Right Click - Selection Box",
"",
+ "R - Reset Section",
"Z/X - Zoom in/out",
"Left/Right - Change Snap",
#if FLX_PITCH
@@ -571,11 +595,11 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
function prepareReload()
{
updateJsonData();
- updateHeads(true);
loadMusic();
reloadNotes();
onChartLoaded();
-
+ updateHeads(true);
+
autoSaveTime = 0;
Conductor.songPosition = 0;
if(FlxG.sound.music != null) FlxG.sound.music.time = 0;
@@ -645,8 +669,8 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
var chartName:String = 'unknown';
if(Song.chartPath != null)
{
- chartName = Song.chartPath.replace('/', '\\');
- chartName = chartName.substring(chartName.lastIndexOf('\\')+1, chartName.lastIndexOf('.'));
+ chartName = Song.chartPath.replace('\\', '/');
+ chartName = chartName.substring(chartName.lastIndexOf('/')+1, chartName.lastIndexOf('.'));
}
chartName += DateTools.format(Date.now(), '_%Y-%m-%d_%H-%M-%S');
var songCopy:SwagSong = Reflect.copy(PlayState.SONG);
@@ -854,6 +878,10 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
}
}
}
+ else if(FlxG.keys.justPressed.R)
+ {
+ Conductor.songPosition = FlxG.sound.music.time = cachedSectionTimes[curSec] + (curSec > 0 ? 0.000001 : 0);
+ }
else if(FlxG.keys.pressed.W != FlxG.keys.pressed.S || FlxG.mouse.wheel != 0)
{
if(FlxG.sound.music.playing)
@@ -1013,7 +1041,8 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
selectedNotes.shift();
if(note == null) continue;
- trace('Removed ${!note.isEvent ? 'note' : 'event'} at time: ${note.strumTime}');
+ var kind:String = !note.isEvent ? 'note' : 'event';
+ trace('Removed $kind at time: ${note.strumTime}');
if(!note.isEvent)
{
notes.remove(note);
@@ -1244,7 +1273,7 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
var closeNotes:Array = curRenderedNotes.members.filter(function(note:MetaNote)
{
var chartY:Float = FlxG.mouse.y - note.chartY;
- return ((note.isEvent && noteData < 0) || note.songData[1] == noteData) && chartY >= 0 && chartY < GRID_SIZE;
+ return ((note.isEvent && noteData < 0) || (!note.isEvent && note.songData[1] == noteData)) && chartY >= 0 && chartY < GRID_SIZE;
});
closeNotes.sort(function(a:MetaNote, b:MetaNote) return Math.abs(a.strumTime - FlxG.mouse.y) < Math.abs(b.strumTime - FlxG.mouse.y) ? 1 : -1);
@@ -1262,16 +1291,15 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
else if(!holdingAlt)
{
resetSelectedNotes();
- selectedNotes = sel.copy();
selectedNotes.remove(closest);
addUndoAction(SELECT_NOTE, {old: sel, current: selectedNotes.copy()});
}
-
trace('Notes selected: ' + selectedNotes.length);
}
else if(!FlxG.keys.pressed.CONTROL) // Remove Note/Event
{
- trace('Removed ${!closest.isEvent ? 'note' : 'event'} at time: ${closest.strumTime}');
+ var kind:String = !closest.isEvent ? 'note' : 'event';
+ trace('Removed $kind at time: ${closest.strumTime}');
if(!closest.isEvent)
notes.remove(closest);
else
@@ -1504,11 +1532,19 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
var pushedEvents:Array = [];
movingNotes.forEachAlive(function(note:MetaNote)
{
- notes.push(note);
- if(!note.isEvent) pushedNotes.push(note);
- else pushedEvents.push(cast (note, EventMetaNote));
+ if(!note.isEvent)
+ {
+ notes.push(note);
+ pushedNotes.push(note);
+ }
+ else
+ {
+ events.push(cast (note, EventMetaNote));
+ pushedEvents.push(cast (note, EventMetaNote));
+ }
});
notes.sort(PlayState.sortByTime);
+ events.sort(PlayState.sortByTime);
movingNotes.clear();
isMovingNotes = false;
softReloadNotes();
@@ -1656,7 +1692,7 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
else selectedEventText.visible = false;
}
- function recreateGrids()
+ function createGrids()
{
var destroyed:Bool = false;
var stripes:Array = null;
@@ -2087,6 +2123,7 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
}
prevGridBg.vortexLineEnabled = gridBg.vortexLineEnabled = nextGridBg.vortexLineEnabled = vortexEnabled;
prevGridBg.vortexLineSpace = gridBg.vortexLineSpace = nextGridBg.vortexLineSpace = GRID_SIZE * 4 * curZoom;
+ updateWaveform();
}
function softReloadNotes(onlyCurrent:Bool = false)
@@ -2219,7 +2256,8 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
var _lastGfSection:Null = null;
function updateHeads(ignoreCheck:Bool = false):Void
{
- var isGfSection:Bool = (PlayState.SONG.notes[curSec].gfSection == true);
+ var curSecData:SwagSection = PlayState.SONG.notes[curSec];
+ var isGfSection:Bool = (curSecData != null && curSecData.gfSection == true);
if(_lastGfSection == isGfSection && _lastSec == curSec && !ignoreCheck) return; //optimization
for (i in 0...GRID_PLAYERS)
@@ -2234,7 +2272,7 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
{
var iconP1:HealthIcon = icons[0];
var iconP2:HealthIcon = icons[1];
- var mustHitSection:Bool = (PlayState.SONG.notes[curSec].mustHitSection == true);
+ var mustHitSection:Bool = (curSecData != null && curSecData.mustHitSection == true);
if (isGfSection)
{
if (mustHitSection)
@@ -2626,6 +2664,11 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
note.setStrumTime(Math.max(-5000, strumTimeStepper.value + (note.strumTime - firstTime)));
positionNoteYOnTime(note, curSec);
+
+ if(note.isEvent)
+ {
+ cast (note, EventMetaNote).updateEventText();
+ }
}
softReloadNotes();
};
@@ -2811,25 +2854,16 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
});
var clearButton:PsychUIButton = new PsychUIButton(objX + 200, objY, 'Clear', function()
{
- if(affectNotes.checked)
+ for (note in curRenderedNotes)
{
- for (note in curRenderedNotes)
- {
- if(note == null || note.isEvent) continue;
+ if(note == null) continue;
- selectedNotes.remove(note);
+ if(!note.isEvent && affectNotes.checked)
notes.remove(note);
- }
- }
- if(affectEvents.checked)
- {
- for (event in curRenderedNotes)
- {
- if(event == null || !event.isEvent) continue;
+ if(note.isEvent && affectEvents.checked)
+ events.remove(cast (note, EventMetaNote));
- selectedNotes.remove(event);
- events.remove(cast (event, EventMetaNote));
- }
+ selectedNotes.remove(note);
}
softReloadNotes(true);
});
@@ -2991,8 +3025,8 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
if(Song.chartPath != null && Song.chartPath.length > 0)
{
- var parentFolder:String = Song.chartPath.replace('/', '\\');
- parentFolder = parentFolder.substr(0, Song.chartPath.lastIndexOf('\\')+1);
+ var parentFolder:String = Song.chartPath.replace('\\', '/');
+ parentFolder = parentFolder.substr(0, Song.chartPath.lastIndexOf('/')+1);
var notetypeFile:Array = CoolUtil.coolTextFile(parentFolder + 'notetypes.txt');
if(notetypeFile.length > 0)
{
@@ -3131,6 +3165,7 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
{
PlayState.SONG.offset = audioOffsetStepper.value;
Conductor.offset = audioOffsetStepper.value;
+ updateWaveform();
};
tab_group.add(new FlxText(songNameInputText.x, songNameInputText.y - 15, 80, 'Song Name:'));
@@ -3226,8 +3261,8 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
{
try
{
- var filePath:String = fileDialog.path.replace('/', '\\');
- var loadedChart:SwagSong = Song.parseJSON(fileDialog.data, filePath.substr(filePath.lastIndexOf('\\')));
+ var filePath:String = fileDialog.path.replace('\\', '/');
+ var loadedChart:SwagSong = Song.parseJSON(fileDialog.data, filePath.substr(filePath.lastIndexOf('/')));
if(loadedChart == null || !Reflect.hasField(loadedChart, 'song')) //Check if chart is ACTUALLY a chart and valid
{
showOutput('Error: File loaded is not a Psych Engine/FNF 0.2.x.x chart.', true);
@@ -3298,7 +3333,6 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
var btn:PsychUIButton = new PsychUIButton(0, radioGrp.y + radioGrp.height + 20, 'Load', function()
{
-
var autosaveName:String = fileList[radioGrp.checked];
var path:String = 'backups/$autosaveName';
state.close();
@@ -3360,8 +3394,8 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
{
try
{
- var filePath:String = fileDialog.path.replace('/', '\\');
- var eventsFile:SwagSong = Song.parseJSON(fileDialog.data, filePath.substr(filePath.lastIndexOf('\\')));
+ var filePath:String = fileDialog.path.replace('\\', '/');
+ var eventsFile:SwagSong = Song.parseJSON(fileDialog.data, filePath.substr(filePath.lastIndexOf('/')));
if(eventsFile == null || Reflect.hasField(eventsFile, 'scrollSpeed') || eventsFile.events == null)
{
showOutput('Error: File loaded is not a Psych Engine chart/events file.', true);
@@ -3529,17 +3563,18 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
{
try
{
- var path:String = fileDialog.path.replace('/', '\\');
+ var path:String = fileDialog.path.replace('\\', '/');
var chartName:String = Paths.formatToSongPath(PlayState.SONG.song) + '.json';
- chartName = chartName.substring(chartName.lastIndexOf('\\')+1, chartName.lastIndexOf('.'));
+ chartName = chartName.substring(chartName.lastIndexOf('/')+1, chartName.lastIndexOf('.'));
- var chartFile:String = '$path\\$chartName-chart.json';
- var metadataFile:String = '$path\\$chartName-metadata.json';
+ var chartFile:String = '$path/$chartName-chart.json';
+ var metadataFile:String = '$path/$chartName-metadata.json';
updateChartData();
var pack:VSlicePackage = VSlice.export(PlayState.SONG);
+ ClientPrefs.toggleVolumeKeys(false);
openSubState(new BasePrompt('Metadata',
function(state:BasePrompt)
{
@@ -3611,8 +3646,8 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
fileDialog.open('song.json', 'Open a Psych Engine Chart JSON', function()
{
- var filePath:String = fileDialog.path.replace('/', '\\');
- var loadedChart:SwagSong = Song.parseJSON(fileDialog.data, filePath.substr(filePath.lastIndexOf('\\')));
+ var filePath:String = fileDialog.path.replace('\\', '/');
+ var loadedChart:SwagSong = Song.parseJSON(fileDialog.data, filePath.substr(filePath.lastIndexOf('/')));
if(loadedChart == null || !Reflect.hasField(loadedChart, 'song')) //Check if chart is ACTUALLY a chart and valid
{
showOutput('Error: File loaded is not a Psych Engine 0.x.x/FNF 0.2.x.x chart.', true);
@@ -3626,11 +3661,12 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
return;
}
+ ClientPrefs.toggleVolumeKeys(false);
openSubState(new BasePrompt('Metadata',
function(state:BasePrompt)
{
var songName:String = Paths.formatToSongPath(pack.metadata.songName);
- var parentFolder:String = filePath.substring(0, filePath.lastIndexOf('\\')+1);
+ var parentFolder:String = filePath.substring(0, filePath.lastIndexOf('/')+1);
var artistInput, charterInput, difficultiesInput:PsychUIInputText = null;
var btnX = 640;
@@ -3689,8 +3725,8 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
fileDialog.openDirectory('Save V-Slice Chart/Metadata JSONs', function()
{
overwriteSavedSomething = false;
- var path:String = fileDialog.path.replace('/', '\\');
- if(path.endsWith('\\')) path = path.substr(0, path.length-1);
+ var path:String = fileDialog.path.replace('\\', '/');
+ if(path.endsWith('/')) path = path.substr(0, path.length-1);
overwriteCheck('$path/$songName-chart.json', '$songName-chart.json', PsychJsonPrinter.print(pack.chart, ['events', 'notes', 'scrollSpeed']), function()
{
overwriteCheck('$path/$songName-metadata.json', '$songName-metadata.json', PsychJsonPrinter.print(pack.metadata, ['characters', 'difficulties', 'timeChanges']), function()
@@ -3798,8 +3834,8 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
{
fileDialog.openDirectory('Save Converted Psych JSONs', function()
{
- var path:String = fileDialog.path.replace('/', '\\');
- if(!path.endsWith('\\')) path += '\\';
+ var path:String = fileDialog.path.replace('\\', '/');
+ if(!path.endsWith('/')) path += '/';
var diffs:Array = metadata.playData.difficulties.copy();
var defaultDiff:String = Paths.formatToSongPath(Difficulty.getDefault());
@@ -3859,8 +3895,8 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
var oldSong = PlayState.SONG;
try
{
- var filePath:String = fileDialog.path.replace('/', '\\');
- filePath = filePath.substring(filePath.lastIndexOf('\\')+1, filePath.lastIndexOf('.'));
+ var filePath:String = fileDialog.path.replace('\\', '/');
+ filePath = filePath.substring(filePath.lastIndexOf('/')+1, filePath.lastIndexOf('.'));
var loadedChart:SwagSong = Song.parseJSON(fileDialog.data, filePath, '');
if(loadedChart == null || !Reflect.hasField(loadedChart, 'song')) //Check if chart is ACTUALLY a chart and valid
@@ -4078,7 +4114,6 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
var showNextGridButton:PsychUIButton;
var noteTypeLabelsButton:PsychUIButton;
var vortexEditorButton:PsychUIButton;
- var vortexEnabled:Bool = false;
function addViewTab()
{
var tab = upperBox.getTab('View');
@@ -4087,6 +4122,13 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
var btnY = 1;
var btnWid = Std.int(tab.width);
+ if(chartEditorSave.data.waveformEnabled != null)
+ waveformEnabled = chartEditorSave.data.waveformEnabled;
+ if(chartEditorSave.data.waveformTarget != null)
+ waveformTarget = chartEditorSave.data.waveformTarget;
+ if(chartEditorSave.data.waveformColor != null)
+ waveformSprite.color = CoolUtil.colorFromString(chartEditorSave.data.waveformColor);
+
showLastGridButton = new PsychUIButton(btnX, btnY, '', function()
{
showPreviousSection = !showPreviousSection;
@@ -4135,7 +4177,61 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
btnY++;
btnY += 20;
- var btn:PsychUIButton = new PsychUIButton(btnX, btnY, ' Waveform...', function() showOutput('Feature not implemented yet!', true), btnWid); //TO DO: Add functionality
+ var btn:PsychUIButton = new PsychUIButton(btnX, btnY, ' Waveform...', function()
+ {
+ ClientPrefs.toggleVolumeKeys(false);
+ openSubState(new BasePrompt(320, 200, 'Waveform Settings',
+ function(state:BasePrompt) {
+ upperBox.isMinimized = true;
+ upperBox.bg.visible = false;
+
+ var btn:PsychUIButton = new PsychUIButton(state.bg.x + state.bg.width - 40, state.bg.y, 'X', state.close, 40);
+ btn.cameras = state.cameras;
+ state.add(btn);
+
+ var check:PsychUICheckBox = new PsychUICheckBox(state.bg.x + 40, state.bg.y + 80, 'Enabled', 60);
+ check.onClick = function()
+ {
+ chartEditorSave.data.waveformEnabled = waveformEnabled = check.checked;
+ updateWaveform();
+ };
+ check.cameras = state.cameras;
+ check.checked = waveformEnabled;
+ state.add(check);
+
+ var waveformC:String = '0000FF';
+ if(chartEditorSave.data.waveformColor != null)
+ waveformC = chartEditorSave.data.waveformColor;
+
+ var input:PsychUIInputText = new PsychUIInputText(check.x, check.y + 50, 60, waveformC, 10);
+ input.onChange = function(old:String, cur:String)
+ {
+ chartEditorSave.data.waveformColor = cur;
+ waveformSprite.color = CoolUtil.colorFromString(cur);
+ }
+ input.maxLength = 6;
+ input.filterMode = ONLY_HEXADECIMAL;
+ input.cameras = state.cameras;
+ input.forceCase = UPPER_CASE;
+
+ var options:Array = [INST, PLAYER, OPPONENT];
+ var radioGrp:PsychUIRadioGroup = new PsychUIRadioGroup(check.x + 120, check.y, ['Instrumental', 'Main Vocals', 'Opponent Vocals']);
+ radioGrp.cameras = state.cameras;
+ radioGrp.onClick = function()
+ {
+ waveformTarget = chartEditorSave.data.waveformTarget = options[radioGrp.checked];
+ updateWaveform();
+ };
+ radioGrp.checked = options.indexOf(waveformTarget);
+ state.add(radioGrp);
+
+ var txt1:FlxText = new FlxText(input.x, input.y - 15, 80, 'Color (Hex):');
+ txt1.cameras = state.cameras;
+ state.add(txt1);
+ state.add(input);
+ }
+ ));
+ }, btnWid);
btn.text.alignment = LEFT;
tab_group.add(btn);
@@ -4311,12 +4407,12 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
else
{
var chartName:String = Paths.formatToSongPath(PlayState.SONG.song) + '.json';
- if(Song.chartPath != null) chartName = Song.chartPath.substr(Song.chartPath.lastIndexOf('\\')).trim();
+ if(Song.chartPath != null) chartName = Song.chartPath.substr(Song.chartPath.lastIndexOf('/')).trim();
fileDialog.save(chartName, chartData,
function()
{
var newPath:String = fileDialog.path;
- Song.chartPath = newPath.replace('/', '\\');
+ Song.chartPath = newPath.replace('\\', '/');
reloadNotesDropdowns();
showOutput('Chart saved successfully to: $newPath');
@@ -4529,6 +4625,7 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
override function closeSubState()
{
+ ClientPrefs.toggleVolumeKeys(true);
super.closeSubState();
upperBox.isMinimized = true;
upperBox.visible = mainBox.visible = infoBox.visible = true;
@@ -4685,10 +4782,12 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
case MOVE_NOTE:
actionRemoveNotes(action.data.movedNotes, action.data.movedEvents);
actionPushNotes(action.data.originalNotes, action.data.originalEvents);
+ onSelectNote();
case SELECT_NOTE:
resetSelectedNotes();
selectedNotes = action.data.old;
+ if(lockedEvents) selectedNotes = selectedNotes.filter((note:MetaNote) -> !note.isEvent);
onSelectNote();
}
showOutput('Undo #${currentUndo+1}: ${action.action}');
@@ -4716,10 +4815,12 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
case MOVE_NOTE:
actionRemoveNotes(action.data.originalNotes, action.data.originalEvents);
actionPushNotes(action.data.movedNotes, action.data.movedEvents);
+ onSelectNote();
case SELECT_NOTE:
resetSelectedNotes();
selectedNotes = action.data.current;
+ if(lockedEvents) selectedNotes = selectedNotes.filter((note:MetaNote) -> !note.isEvent);
onSelectNote();
}
showOutput('Redo #${currentUndo+1}: ${action.action}');
@@ -4737,6 +4838,8 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
{
notes.push(note);
selectedNotes.push(note);
+ note.songData[0] = note.strumTime;
+ note.songData[1] = note.chartNoteData;
}
}
notes.sort(PlayState.sortByTime);
@@ -4749,6 +4852,7 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
{
events.push(event);
selectedNotes.push(event);
+ event.songData[0] = event.strumTime;
}
}
events.sort(PlayState.sortByTime);
@@ -4759,21 +4863,40 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
function actionRemoveNotes(dataNotes:Array, dataEvents:Array)
{
if(dataNotes != null && dataNotes.length > 0)
+ {
for (note in dataNotes)
+ {
if(note != null)
{
notes.remove(note);
selectedNotes.remove(note);
+
+ if(note.exists)
+ {
+ note.colorTransform.redMultiplier = note.colorTransform.greenMultiplier = note.colorTransform.blueMultiplier = 1;
+ if(note.animation.curAnim != null) note.animation.curAnim.curFrame = 0;
+ }
}
+ }
+ }
if(dataEvents != null && dataEvents.length > 0)
+ {
for (event in dataEvents)
+ {
if(event != null)
{
- events.remove(event);
+ trace(events.remove(event));
selectedNotes.remove(event);
- }
+ if(event.exists)
+ {
+ event.colorTransform.redMultiplier = event.colorTransform.greenMultiplier = event.colorTransform.blueMultiplier = 1;
+ if(event.animation.curAnim != null) event.animation.curAnim.curFrame = 0;
+ }
+ }
+ }
+ }
softReloadNotes();
}
@@ -4791,4 +4914,189 @@ class ChartingState extends MusicBeatState implements PsychUIEventHandler.PsychU
}
}
}
-}
\ No newline at end of file
+
+ // Ported from the old chart editor
+ var wavData:Array>> = [[[0], [0]], [[0], [0]]];
+ function updateWaveform() {
+ #if (lime_cffi && !macro)
+ if(curSec < 0 || curSec >= cachedSectionTimes.length || !waveformEnabled)
+ {
+ waveformSprite.visible = false;
+ return;
+ }
+
+ waveformSprite.visible = true;
+ waveformSprite.y = gridBg.y;
+ var width:Int = Std.int(GRID_SIZE * GRID_COLUMNS_PER_PLAYER * GRID_PLAYERS);
+ var height:Int = Std.int(gridBg.height);
+ if(Std.int(waveformSprite.height) != height && waveformSprite.pixels != null)
+ {
+ waveformSprite.pixels.dispose();
+ waveformSprite.pixels.disposeImage();
+ waveformSprite.makeGraphic(width, height, 0x00FFFFFF);
+ }
+ waveformSprite.pixels.fillRect(new Rectangle(0, 0, width, height), 0x00FFFFFF);
+
+ wavData[0][0].resize(0);
+ wavData[0][1].resize(0);
+ wavData[1][0].resize(0);
+ wavData[1][1].resize(0);
+
+ var sound:FlxSound = switch(waveformTarget)
+ {
+ case INST:
+ FlxG.sound.music;
+ case PLAYER:
+ vocals;
+ case OPPONENT:
+ opponentVocals;
+ default:
+ null;
+ }
+
+ @:privateAccess
+ if (sound != null && sound._sound != null && sound._sound.__buffer != null)
+ {
+ var bytes:Bytes = sound._sound.__buffer.data.toBytes();
+ wavData = waveformData(sound._sound.__buffer, bytes, cachedSectionTimes[curSec] - Conductor.offset, cachedSectionTimes[curSec+1] - Conductor.offset, 1, wavData, height);
+ }
+
+ // Draws
+ var gSize:Int = Std.int(GRID_SIZE * 8);
+ var hSize:Int = Std.int(gSize / 2);
+ var size:Float = 1;
+
+ var leftLength:Int = (wavData[0][0].length > wavData[0][1].length ? wavData[0][0].length : wavData[0][1].length);
+ var rightLength:Int = (wavData[1][0].length > wavData[1][1].length ? wavData[1][0].length : wavData[1][1].length);
+
+ var length:Int = leftLength > rightLength ? leftLength : rightLength;
+
+ for (index in 0...length)
+ {
+ var lmin:Float = FlxMath.bound(((index < wavData[0][0].length && index >= 0) ? wavData[0][0][index] : 0) * (gSize / 1.12), -hSize, hSize) / 2;
+ var lmax:Float = FlxMath.bound(((index < wavData[0][1].length && index >= 0) ? wavData[0][1][index] : 0) * (gSize / 1.12), -hSize, hSize) / 2;
+
+ var rmin:Float = FlxMath.bound(((index < wavData[1][0].length && index >= 0) ? wavData[1][0][index] : 0) * (gSize / 1.12), -hSize, hSize) / 2;
+ var rmax:Float = FlxMath.bound(((index < wavData[1][1].length && index >= 0) ? wavData[1][1][index] : 0) * (gSize / 1.12), -hSize, hSize) / 2;
+
+ waveformSprite.pixels.fillRect(new Rectangle(hSize - (lmin + rmin), index * size, (lmin + rmin) + (lmax + rmax), size), FlxColor.WHITE);
+ }
+ #else
+ waveformSprite.visible = false;
+ #end
+ }
+
+ function waveformData(buffer:AudioBuffer, bytes:Bytes, time:Float, endTime:Float, multiply:Float = 1, ?array:Array>>, ?steps:Float):Array>>
+ {
+ #if (lime_cffi && !macro)
+ if (buffer == null || buffer.data == null) return [[[0], [0]], [[0], [0]]];
+
+ var khz:Float = (buffer.sampleRate / 1000);
+ var channels:Int = buffer.channels;
+
+ var index:Int = Std.int(time * khz);
+
+ var samples:Float = ((endTime - time) * khz);
+
+ if (steps == null) steps = 1280;
+
+ var samplesPerRow:Float = samples / steps;
+ var samplesPerRowI:Int = Std.int(samplesPerRow);
+
+ var gotIndex:Int = 0;
+
+ var lmin:Float = 0;
+ var lmax:Float = 0;
+
+ var rmin:Float = 0;
+ var rmax:Float = 0;
+
+ var rows:Float = 0;
+
+ var simpleSample:Bool = true;//samples > 17200;
+ var v1:Bool = false;
+
+ if (array == null) array = [[[0], [0]], [[0], [0]]];
+
+ while (index < (bytes.length - 1)) {
+ if (index >= 0) {
+ var byte:Int = bytes.getUInt16(index * channels * 2);
+
+ if (byte > 65535 / 2) byte -= 65535;
+
+ var sample:Float = (byte / 65535);
+
+ if (sample > 0)
+ if (sample > lmax) lmax = sample;
+ else if (sample < 0)
+ if (sample < lmin) lmin = sample;
+
+ if (channels >= 2) {
+ byte = bytes.getUInt16((index * channels * 2) + 2);
+
+ if (byte > 65535 / 2) byte -= 65535;
+
+ sample = (byte / 65535);
+
+ if (sample > 0) {
+ if (sample > rmax) rmax = sample;
+ } else if (sample < 0) {
+ if (sample < rmin) rmin = sample;
+ }
+ }
+ }
+
+ v1 = samplesPerRowI > 0 ? (index % samplesPerRowI == 0) : false;
+ while (simpleSample ? v1 : rows >= samplesPerRow) {
+ v1 = false;
+ rows -= samplesPerRow;
+
+ gotIndex++;
+
+ var lRMin:Float = Math.abs(lmin) * multiply;
+ var lRMax:Float = lmax * multiply;
+
+ var rRMin:Float = Math.abs(rmin) * multiply;
+ var rRMax:Float = rmax * multiply;
+
+ if (gotIndex > array[0][0].length) array[0][0].push(lRMin);
+ else array[0][0][gotIndex - 1] = array[0][0][gotIndex - 1] + lRMin;
+
+ if (gotIndex > array[0][1].length) array[0][1].push(lRMax);
+ else array[0][1][gotIndex - 1] = array[0][1][gotIndex - 1] + lRMax;
+
+ if (channels >= 2)
+ {
+ if (gotIndex > array[1][0].length) array[1][0].push(rRMin);
+ else array[1][0][gotIndex - 1] = array[1][0][gotIndex - 1] + rRMin;
+
+ if (gotIndex > array[1][1].length) array[1][1].push(rRMax);
+ else array[1][1][gotIndex - 1] = array[1][1][gotIndex - 1] + rRMax;
+ }
+ else
+ {
+ if (gotIndex > array[1][0].length) array[1][0].push(lRMin);
+ else array[1][0][gotIndex - 1] = array[1][0][gotIndex - 1] + lRMin;
+
+ if (gotIndex > array[1][1].length) array[1][1].push(lRMax);
+ else array[1][1][gotIndex - 1] = array[1][1][gotIndex - 1] + lRMax;
+ }
+
+ lmin = 0;
+ lmax = 0;
+
+ rmin = 0;
+ rmax = 0;
+ }
+
+ index++;
+ rows++;
+ if(gotIndex > steps) break;
+ }
+
+ return array;
+ #else
+ return [[[0], [0]], [[0], [0]]];
+ #end
+ }
+}
diff --git a/source/states/editors/MenuCharacterEditorState.hx b/source/states/editors/MenuCharacterEditorState.hx
index 2647985fa11..0bde7698175 100644
--- a/source/states/editors/MenuCharacterEditorState.hx
+++ b/source/states/editors/MenuCharacterEditorState.hx
@@ -49,7 +49,7 @@ class MenuCharacterEditorState extends MusicBeatState implements PsychUIEventHan
add(grpWeekCharacters);
txtOffsets = new FlxText(20, 10, 0, "[0, 0]", 32);
- txtOffsets.setFormat("VCR OSD Mono", 32, FlxColor.WHITE, CENTER);
+ txtOffsets.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, CENTER);
txtOffsets.alpha = 0.7;
add(txtOffsets);
@@ -378,4 +378,4 @@ class MenuCharacterEditorState extends MusicBeatState implements PsychUIEventHan
_file = null;
FlxG.log.error("Problem saving file");
}
-}
\ No newline at end of file
+}
diff --git a/source/states/editors/NoteSplashEditorState.hx b/source/states/editors/NoteSplashEditorState.hx
index 63c8cf0c056..24b10a8960c 100644
--- a/source/states/editors/NoteSplashEditorState.hx
+++ b/source/states/editors/NoteSplashEditorState.hx
@@ -1,21 +1,16 @@
package states.editors;
-import openfl.net.FileFilter;
import objects.Note;
import objects.NoteSplash;
import objects.StrumNote;
-import flixel.FlxSprite;
+
+import openfl.net.FileFilter;
import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup;
import flixel.input.keyboard.FlxKey;
-import flixel.text.FlxText;
-import flixel.tweens.FlxTween;
-import flixel.util.FlxColor;
-import haxe.Json;
import openfl.events.Event;
import openfl.events.IOErrorEvent;
import openfl.net.FileReference;
-
-using StringTools;
+import haxe.Json;
@:access(objects.NoteSplash)
class NoteSplashEditorState extends MusicBeatState
@@ -23,27 +18,23 @@ class NoteSplashEditorState extends MusicBeatState
var strums:FlxTypedSpriteGroup = new FlxTypedSpriteGroup();
var splashes:FlxTypedSpriteGroup = new FlxTypedSpriteGroup();
var config = NoteSplash.createConfig();
+
var tipText:FlxText;
var errorText:FlxText;
var curText:FlxText;
static var imageSkin:String = null;
-
var splash:NoteSplash;
var UI:PsychUIBox;
var properUI:PsychUIBox;
var shaderUI:PsychUIBox;
- var noteData:Int;
-
- var curType:String;
- var currentNoteType:PsychUIInputText;
override function create()
{
if (imageSkin == null)
imageSkin = NoteSplash.DEFAULT_SKIN + NoteSplash.getSplashSkinPostfix();
-
+
FlxG.mouse.visible = true;
FlxG.sound.volumeUpKeys = [];
@@ -92,10 +83,9 @@ class NoteSplashEditorState extends MusicBeatState
babyArrow.postAddedToGroup();
babyArrow.screenCenter(Y);
babyArrow.ID = i;
- //babyArrow.scale.scale(1.1, 1.1);
strums.add(babyArrow);
}
-
+
add(strums);
add(splashes);
@@ -158,11 +148,11 @@ class NoteSplashEditorState extends MusicBeatState
UI.add(indices_input);
UI.add(new FlxText(20, 110, 0, "Minimum FPS:"));
- var minFps:PsychUINumericStepper = new PsychUINumericStepper(20, 127.5, 1, 24, 1, 120);
+ var minFps:PsychUINumericStepper = new PsychUINumericStepper(20, 127.5, 1, 22, 1, 120);
UI.add(minFps);
UI.add(new FlxText(150, 110, 0, "Maximum FPS:"));
- var maxFps:PsychUINumericStepper = new PsychUINumericStepper(150, 127.5, 1, 24, 1, 120);
+ var maxFps:PsychUINumericStepper = new PsychUINumericStepper(150, 127.5, 1, 26, 1, 120);
UI.add(maxFps);
animDropDown = new PsychUIDropDownMenu(-155, 57, [""], function(id:Int, name:String)
@@ -177,12 +167,11 @@ class NoteSplashEditorState extends MusicBeatState
numericStepperData.min = 0;
numericStepperData.value = i.noteData;
curAnim = name;
- minFps.value = i.minFps;
- maxFps.value = i.maxFps;
+ minFps.value = i.fps[0];
+ maxFps.value = i.fps[1];
if (i.indices != null && i.indices.length > 0)
- {
indices_input.text = i.indices.toString().substring(1, i.indices.toString().length - 2);
- }
+
playStrumAnim(curAnim, i.noteData);
}
}
@@ -192,16 +181,14 @@ class NoteSplashEditorState extends MusicBeatState
{
var anims:Array = [];
if (config != null && config.animations != null)
- {
for (i in config.animations.keys())
{
anims.push(i);
}
- }
+
if (anims.length < 1)
- {
anims.push("");
- }
+
if (curAnim == null && anims[0].length > 0)
curAnim = anims[0];
@@ -221,8 +208,8 @@ class NoteSplashEditorState extends MusicBeatState
prefix_input.text = "";
indices_input.text = "";
numericStepperData.value = 0;
- minFps.value = 24;
- maxFps.value = 24;
+ minFps.value = 22;
+ maxFps.value = 26;
setAnimDropDown();
parseRGB();
changeShader.selectedLabel = "Red";
@@ -244,16 +231,18 @@ class NoteSplashEditorState extends MusicBeatState
}
}
- var offsets = [0, 0];
+ var offsets:Array = [0, 0];
var conf = config.animations.get(name_input.text);
+
if (conf != null)
offsets = conf.offsets;
+
if (offsets == null)
offsets = [0, 0];
else
offsets = offsets.copy();
- config = NoteSplash.addAnimationToConfig([scaleXNumericStepper.value, scaleYNumericStepper.value], config, name_input.text, prefix_input.text, cast minFps.value, cast maxFps.value, offsets, indices, cast numericStepperData.value);
+ config = NoteSplash.addAnimationToConfig(config, scaleNumericStepper.value, name_input.text, prefix_input.text, [cast minFps.value, cast maxFps.value], offsets, indices, cast numericStepperData.value);
curAnim = name_input.text;
playStrumAnim(curAnim, cast numericStepperData.value);
setAnimDropDown();
@@ -294,10 +283,11 @@ class NoteSplashEditorState extends MusicBeatState
errorText.color = FlxColor.RED;
FlxTween.cancelTweensOf(errorText);
- var image = Paths.image("noteSplashes/" + imageSkin);
+
+ var image = Paths.image(imageSkin);
if (image == null)
{
- errorText.text = "ERROR! Couldn't find noteSplashes/" + imageSkin + ".png";
+ errorText.text = 'ERROR! Couldn\'t find $imageSkin.png';
errorText.alpha = 1;
return;
}
@@ -305,27 +295,28 @@ class NoteSplashEditorState extends MusicBeatState
{
errorText.color = FlxColor.GREEN;
errorText.alpha = 1;
- errorText.text = "Succesfully loaded noteSplashes/" + imageSkin + ".png";
+ errorText.text = 'Succesfully loaded $imageSkin.png';
}
+
NoteSplash.configs.clear();
+
FlxTween.tween(errorText, {alpha: 0}, 1, {startDelay: 1, onComplete: (twn) -> {
errorText.color = FlxColor.RED;
}});
splash.loadSplash(imageSkin);
splash.alpha = 0.0001;
- if (splash.config != null)
- config = splash.config;
- else
- config = NoteSplash.createConfig();
+
+ if (splash.config != null) config = splash.config;
+ else config = NoteSplash.createConfig();
curAnim = null;
name_input.text = "";
prefix_input.text = "";
indices_input.text = "";
numericStepperData.value = 0;
- minFps.value = 24;
- maxFps.value = 24;
+ minFps.value = 22;
+ maxFps.value = 26;
setAnimDropDown();
parseRGB();
changeShader.selectedLabel = "Red";
@@ -334,8 +325,7 @@ class NoteSplashEditorState extends MusicBeatState
}
var imageInputText:PsychUIInputText;
- var scaleXNumericStepper:PsychUINumericStepper;
- var scaleYNumericStepper:PsychUINumericStepper;
+ var scaleNumericStepper:PsychUINumericStepper;
function addProperitiesTab()
{
var ui = properUI.getTab("Properties").menu;
@@ -350,12 +340,12 @@ class NoteSplashEditorState extends MusicBeatState
});
ui.add(reloadButton);
- ui.add(new FlxText(20, 40, "Scale X / Y:"));
- scaleXNumericStepper = new PsychUINumericStepper(20, 57.5, 0.25, 1, 0, 4, 2, 60);
- ui.add(scaleXNumericStepper);
+ ui.add(new FlxText(20, 40, "Scale:"));
+ scaleNumericStepper = new PsychUINumericStepper(20, 57.5, 0.1, 1, 0, 4, 2, 60);
+ ui.add(scaleNumericStepper);
+
+ scaleNumericStepper.value = config != null ? config.scale : 1;
- scaleYNumericStepper = new PsychUINumericStepper(20, 75, 0.25, 1, 0, 4, 2, 60);
- ui.add(scaleYNumericStepper);
ui.add(new FlxText(130, 40, "Animations:"));
var saveButton:PsychUIButton = new PsychUIButton(20, 130, "Save", saveSplash);
@@ -367,29 +357,37 @@ class NoteSplashEditorState extends MusicBeatState
var loadButton:PsychUIButton = new PsychUIButton(180, 155, "Convert TXT", loadTxt);
ui.add(loadButton);
- if (config != null && config.scale != null)
+ var allowRGBCheck:PsychUICheckBox = new PsychUICheckBox(20, 105, "", 1);
+ function check()
{
- scaleXNumericStepper.value = config.scale[0];
- scaleYNumericStepper.value = config.scale[1];
+ if (config != null)
+ config.allowRGB = allowRGBCheck.checked;
}
+ allowRGBCheck.onClick = check;
+ allowRGBCheck.checked = config != null && cast(config.allowRGB, Null) != null ? config.allowRGB : false;
+
+ var rgbText = new FlxText(allowRGBCheck.x + 20, 0);
+ rgbText.text = "Allow RGB?";
+ rgbText.y = allowRGBCheck.y + 2.5;
+ ui.add(rgbText);
+
+ ui.add(allowRGBCheck);
- var getsAffectedByShader:PsychUICheckBox = new PsychUICheckBox(20, 105, "", 1);
+ var allowPixelCheck:PsychUICheckBox = new PsychUICheckBox(allowRGBCheck.x + 110, allowRGBCheck.y, "", 1);
function check()
{
if (config != null)
- {
- config.affectedByShader = getsAffectedByShader.checked;
- }
+ config.allowPixel = allowPixelCheck.checked;
}
- getsAffectedByShader.onClick = check;
- getsAffectedByShader.checked = config != null && cast(config.affectedByShader, Null) != null ? config.affectedByShader : false;
+ allowPixelCheck.onClick = check;
+ allowPixelCheck.checked = config != null && cast(config.allowPixel, Null) != null ? config.allowPixel : false;
- var text = new FlxText(getsAffectedByShader.x + 20, 0);
- text.text = "Affected by Shader?";
- text.y = getsAffectedByShader.y + 2.5;
- ui.add(text);
+ var pixelText = new FlxText(allowPixelCheck.x + 20, 0);
+ pixelText.text = "Allow Pixel?";
+ pixelText.y = allowPixelCheck.y + 2.5;
+ ui.add(pixelText);
- ui.add(getsAffectedByShader);
+ ui.add(allowPixelCheck);
}
var redEnabled:Bool = true;
@@ -500,7 +498,9 @@ class NoteSplashEditorState extends MusicBeatState
//
}
- var copiedOffset:Array = [0, 0];
+ var holdingArrowsTime:Float = 0;
+ var holdingArrowsElapsed:Float = 0;
+ var copiedOffset:Array = [0, 0];
override function update(elapsed:Float)
{
super.update(elapsed);
@@ -509,9 +509,10 @@ class NoteSplashEditorState extends MusicBeatState
curText.text = 'Copied Offsets: ${Std.string(copiedOffset).replace(',', ', ')}\n';
curText.text += 'Current Animation: ${curAnim == null || curAnim.length < 1 ? "NONE" : curAnim}';
+
if (config != null && !curText.text.contains('NONE'))
{
- var offsets:Array = try config.animations.get(curAnim).offsets catch (e) [0, 0];
+ var offsets:Array = try config.animations.get(curAnim).offsets catch (e) [0, 0];
curText.text += ' ($offsets)'.replace(',', ', ');
}
@@ -519,34 +520,11 @@ class NoteSplashEditorState extends MusicBeatState
{
var currentAnim:String = curAnimText.text;
if (config.animations.exists(currentAnim) && config.animations.get(currentAnim) != null)
- {
addButton.label = 'Update';
- }
else
- {
addButton.label = 'Add';
- }
-
- config.scale[0] = scaleXNumericStepper.value;
- config.scale[1] = scaleYNumericStepper.value;
- }
- if (FlxG.keys.pressed.CONTROL)
- {
- if (FlxG.keys.justPressed.C)
- {
- if (config.animations.get(curAnim) != null)
- copiedOffset = config.animations.get(curAnim).offsets.copy();
- }
- else if (FlxG.keys.justPressed.V)
- {
- if (config.animations.get(curAnim) != null)
- {
- var conf = config.animations.get(curAnim);
- conf.offsets = copiedOffset.copy();
- config.animations.set(curAnim, conf);
- }
- }
+ config.scale = scaleNumericStepper.value;
}
var blockInput:Bool = PsychUIInputText.focusOn != null;
@@ -562,28 +540,58 @@ class NoteSplashEditorState extends MusicBeatState
}
}
- var multiplier:Int = FlxG.keys.pressed.SHIFT ? 10 : 1;
-
- if (FlxG.keys.justPressed.LEFT)
- {
- config.animations[curAnim].offsets[0] += multiplier;
- splash();
- }
- else if (FlxG.keys.justPressed.RIGHT)
+ var changedOffset = false;
+ if (FlxG.keys.pressed.CONTROL && config.animations.get(curAnim) != null)
{
- config.animations[curAnim].offsets[0] -= multiplier;
- splash();
+ if (FlxG.keys.justPressed.C)
+ {
+ copiedOffset = config.animations.get(curAnim).offsets.copy();
+ }
+ else if (FlxG.keys.justPressed.V)
+ {
+ var conf = config.animations.get(curAnim);
+ conf.offsets = copiedOffset.copy();
+ config.animations.set(curAnim, conf);
+ changedOffset = true;
+ }
+ else if(FlxG.keys.justPressed.R)
+ {
+ var conf = config.animations.get(curAnim);
+ conf.offsets = [0, 0];
+ config.animations.set(curAnim, conf);
+ changedOffset = true;
+ }
}
- else if (FlxG.keys.justPressed.UP)
+
+ var multiplier:Int = (FlxG.keys.pressed.SHIFT || FlxG.gamepads.anyPressed(LEFT_SHOULDER)) ? 10 : 1;
+
+ var moveKeysP = [FlxG.keys.justPressed.LEFT, FlxG.keys.justPressed.RIGHT, FlxG.keys.justPressed.UP, FlxG.keys.justPressed.DOWN];
+ if(moveKeysP.contains(true))
{
- config.animations[curAnim].offsets[1] += multiplier;
- splash();
+ config.animations[curAnim].offsets[0] += ((moveKeysP[0] ? 1 : 0) - (moveKeysP[1] ? 1 : 0)) * multiplier;
+ config.animations[curAnim].offsets[1] += ((moveKeysP[2] ? 1 : 0) - (moveKeysP[3] ? 1 : 0)) * multiplier;
+ changedOffset = true;
}
- else if (FlxG.keys.justPressed.DOWN)
+
+ var moveKeys = [FlxG.keys.pressed.LEFT, FlxG.keys.pressed.RIGHT, FlxG.keys.pressed.UP, FlxG.keys.pressed.DOWN];
+ if(moveKeys.contains(true))
{
- config.animations[curAnim].offsets[1] -= multiplier;
- splash();
+ holdingArrowsTime += elapsed;
+ if(holdingArrowsTime > 0.6)
+ {
+ holdingArrowsElapsed += elapsed;
+ while(holdingArrowsElapsed > (1/60))
+ {
+ config.animations[curAnim].offsets[0] += ((moveKeys[0] ? 1 : 0) - (moveKeys[1] ? 1 : 0)) * multiplier;
+ config.animations[curAnim].offsets[1] += ((moveKeys[2] ? 1 : 0) - (moveKeys[3] ? 1 : 0)) * multiplier;
+ holdingArrowsElapsed -= (1/60);
+ changedOffset = true;
+ }
+ }
}
+ else holdingArrowsTime = 0;
+
+ if(changedOffset || FlxG.keys.justPressed.SPACE) splash();
}
if (!blockInput)
@@ -617,14 +625,17 @@ class NoteSplashEditorState extends MusicBeatState
var anims:Int = 0;
var datas:Int = 0;
var animArray:Array = [];
+
while (true)
{
var data:Int = strum.ID % 4 + (datas * 4);
if (!splash.noteDataMap.exists(data) || !splash.animation.exists(splash.noteDataMap[data]))
break;
+
datas++;
anims++;
}
+
if (anims > 1)
{
for (i in 0...anims)
@@ -649,10 +660,7 @@ class NoteSplashEditorState extends MusicBeatState
splashes.add(splash);
}
}
- else
- {
- strum.playAnim('static');
- }
+ else strum.playAnim('static');
});
}
else
@@ -667,8 +675,7 @@ class NoteSplashEditorState extends MusicBeatState
var splash:NoteSplash = new NoteSplash(imageSkin);
splash.alpha = 1;
splash.config = config;
- if (noteData < 0)
- noteData = 0;
+ if (noteData < 0) noteData = 0;
if (name != null && splash.animation.exists(name) && noteData > -1)
{
@@ -701,8 +708,7 @@ class NoteSplashEditorState extends MusicBeatState
if (config.rgb != null)
for (i in 0...config.rgb.length)
{
- if (i > 2)
- break;
+ if (i > 2) break;
var rgb = config.rgb[i];
if (rgb == null)
@@ -888,12 +894,10 @@ class NoteSplashEditorState extends MusicBeatState
{
super.destroy();
- var FlxG = FlxG.sound;
-
- FlxG.music.volume = 1;
- FlxG.muteKeys = [FlxKey.ZERO];
- FlxG.volumeDownKeys = [FlxKey.NUMPADMINUS, FlxKey.MINUS];
- FlxG.volumeUpKeys = [FlxKey.NUMPADPLUS, FlxKey.PLUS];
+ FlxG.sound.music.volume = 1;
+ FlxG.sound.muteKeys = [FlxKey.ZERO];
+ FlxG.sound.volumeDownKeys = [FlxKey.NUMPADMINUS, FlxKey.MINUS];
+ FlxG.sound.volumeUpKeys = [FlxKey.NUMPADPLUS, FlxKey.PLUS];
}
public static function parseTxt(content:String):NoteSplashConfig
@@ -901,32 +905,28 @@ class NoteSplashEditorState extends MusicBeatState
var config = NoteSplash.createConfig();
if (content == null)
return config;
+
var trim:String = content.trim();
if (trim.length < 1) // empty txt
return config;
var configs = content.split('\n');
// checks for empty txts
- if (configs.length < 2)
- return config;
- if (configs[0].trim() == "")
+ if (configs.length < 2 || configs[0].trim() == "")
return config;
var animation:String = configs[0].rtrim();
- var minFps:Null = 24;
- var maxFps:Null = 24;
+ var fps:Array> = [22, 26];
if (configs[1] != null && configs[1].trim() != "")
{
- var fps = configs[1].trim().split(" ");
- minFps = Std.parseInt(fps[0]);
- maxFps = Std.parseInt(fps[1]);
- if (minFps == null)
- minFps = 24;
- if (maxFps == null)
- maxFps = 24;
+ var newFps = configs[1].trim().split(" ");
+ fps = [Std.parseInt(newFps[0]), Std.parseInt(newFps[1])];
+ if (fps[0] == null) fps[0] = 22;
+ if (fps[1] == null) fps[1] = 26;
}
+
var hasOneOffset = false;
- var offsets = [[0, 0]];
+ var offsets:Array>> = [[0, 0]];
if (configs.length == 3 || configs.length == 2)
{
hasOneOffset = true;
@@ -936,14 +936,11 @@ class NoteSplashEditorState extends MusicBeatState
var offset = configs[2].trim();
if (offset != "")
{
- var offset = offset.split(" ");
- var x = Std.parseInt(offset[0]);
- var y = Std.parseInt(offset[1]);
- if (x == null)
- x = 0;
- if (y == null)
- y = 0;
-
+ var offset:Array = offset.split(" ");
+ var x:Null = Std.parseFloat(offset[0]);
+ var y:Null = Std.parseFloat(offset[1]);
+ if (x == null) x = 0;
+ if (y == null) y = 0;
offsets.push([x, y]);
}
}
@@ -957,17 +954,15 @@ class NoteSplashEditorState extends MusicBeatState
var offset = configs[i].trim();
if (offset != "")
{
- var offset = offset.split(" ");
- var x = Std.parseInt(offset[0]);
- var y = Std.parseInt(offset[1]);
- if (x == null)
- x = 0;
- if (y == null)
- y = 0;
-
+ var offset:Array = offset.split(" ");
+ var x:Null = Std.parseFloat(offset[0]);
+ var y:Null = Std.parseFloat(offset[1]);
+ if (x == null) x = 0;
+ if (y == null) y = 0;
offsets.push([x, y]);
}
i++;
+
if (i + 1 > configs.length)
break;
}
@@ -978,8 +973,10 @@ class NoteSplashEditorState extends MusicBeatState
var offset = offsets[hasOneOffset ? 0 : i];
if (i + 1 > configs.length && !hasOneOffset)
break;
- config = NoteSplash.addAnimationToConfig([1, 1], config, Note.colArray[i], '$animation ${Note.colArray[i]} 10', minFps, maxFps, offset, [], i);
+
+ config = NoteSplash.addAnimationToConfig(config, 1, Note.colArray[i], '$animation ${Note.colArray[i]} 10', fps, offset, [], i);
}
+
if (offsets.length > 4)
{
for (i in 0...Note.colArray.length)
@@ -987,7 +984,8 @@ class NoteSplashEditorState extends MusicBeatState
var offset = offsets[i + 4];
if (i + 1 > offsets.length)
break;
- config = NoteSplash.addAnimationToConfig([1, 1], config, Note.colArray[i] + "2", '$animation ${Note.colArray[i]} 20', minFps, maxFps, offset, [], i + 4);
+
+ config = NoteSplash.addAnimationToConfig(config, 1, Note.colArray[i] + "2", '$animation ${Note.colArray[i]} 20', fps, offset, [], i + 4);
}
}
@@ -1006,21 +1004,40 @@ class NoteSplashEditorHelpSubState extends MusicBeatSubstate
bg.alpha = 0.6;
add(bg);
- var text:FlxText = new FlxText();
- text.setFormat(null, 32, FlxColor.WHITE, CENTER, OUTLINE_FAST, FlxColor.BLACK);
- text.text = "CLICK on strums to SPLASH them";
- text.text += "\n\nARROW KEYS - Move Offset";
- text.text += "\nHOLD SHIFT - Move Offset 10x faster";
- text.text += "\n\nCTRL C/V - Copy or Paste Offsets";
- text.screenCenter();
+ var str:Array = ["Click on a Strum or Press Space",
+ "to spawn a Splash",
+ "",
+ "Arrow Keys - Move Offset",
+ "Hold Shift - Move Offsets 10x faster",
+ "",
+ "",
+ "Ctrl + C - Copy Current Offset",
+ "Ctrl + V - Paste Copied Offset on Current Splash",
+ "Ctrl + R - Reset Current Offset"];
+
+ var helpTexts:FlxSpriteGroup = new FlxSpriteGroup();
+ for (i => txt in str)
+ {
+ if(txt.length < 1) continue;
+
+ var helpText:FlxText = new FlxText(0, 0, 0, txt, 32);
+ helpText.setFormat(null, 32, FlxColor.WHITE, CENTER, OUTLINE_FAST, FlxColor.BLACK);
+ helpText.borderColor = FlxColor.BLACK;
+ helpText.scrollFactor.set();
+ helpText.borderSize = 1;
+ helpText.screenCenter();
+ add(helpText);
+ helpText.y += ((i - str.length/2) * 32) + 16;
+ helpTexts.add(helpText);
+ }
+ add(helpTexts);
var noteDataText:FlxText = new FlxText();
noteDataText.setFormat(null, 32, FlxColor.WHITE, RIGHT, OUTLINE_FAST, FlxColor.BLACK);
noteDataText.text = "NOTE DATAS:\nLEFT: 0 and 4\nDOWN: 1 and 5\nUP: 2 and 6\nRIGHT: 3 and 7";
noteDataText.x = FlxG.width - noteDataText.width - 5;
noteDataText.y = FlxG.height - noteDataText.height - 5;
-
- add(text);
+
add(noteDataText);
}
diff --git a/source/states/editors/StageEditorState.hx b/source/states/editors/StageEditorState.hx
index 0b69838a003..0598c20edfa 100644
--- a/source/states/editors/StageEditorState.hx
+++ b/source/states/editors/StageEditorState.hx
@@ -1668,42 +1668,46 @@ class StageEditorState extends MusicBeatState implements PsychUIEventHandler.Psy
{
fullPath = fullPath.replace('\\', '/');
var exePath = Sys.getCwd().replace('\\', '/');
- if(fullPath.startsWith(exePath + 'assets/images/') #if MODS_ALLOWED || (fullPath.startsWith(exePath + 'mods/') && fullPath.contains('/images/')) #end)
+ if(fullPath.startsWith(exePath))
{
-
- var imageToLoad:String = fullPath.substring(fullPath.indexOf('/images/') + '/images/'.length, fullPath.indexOf('.'));
- if(_makeNewSprite != null)
+ fullPath = fullPath.substr(exePath.length);
+ if((fullPath.startsWith('assets/') #if MODS_ALLOWED || fullPath.startsWith('mods/') #end) && fullPath.contains('/images/'))
{
- if(_makeNewSprite == 'animatedSprite' && !Paths.fileExists('images/$imageToLoad.xml', TEXT) &&
- !Paths.fileExists('images/$imageToLoad.json', TEXT) && !Paths.fileExists('images/$imageToLoad.txt', TEXT))
+ var imageToLoad:String = fullPath.substring(fullPath.indexOf('/images/') + '/images/'.length, fullPath.lastIndexOf('.'));
+ if(_makeNewSprite != null)
{
- showOutput('No Animation file found with the same name of the image!', true);
- _makeNewSprite = null;
- _file = null;
- return;
+ if(_makeNewSprite == 'animatedSprite' && !Paths.fileExists('images/$imageToLoad.xml', TEXT) &&
+ !Paths.fileExists('images/$imageToLoad.json', TEXT) && !Paths.fileExists('images/$imageToLoad.txt', TEXT))
+ {
+ showOutput('No Animation file found with the same name of the image!', true);
+ _makeNewSprite = null;
+ _file = null;
+ return;
+ }
+ insertMeta(new StageEditorMetaSprite({type: _makeNewSprite, name: findUnoccupiedName()}, new ModchartSprite()));
}
- insertMeta(new StageEditorMetaSprite({type: _makeNewSprite, name: findUnoccupiedName()}, new ModchartSprite()));
- }
- var selected = getSelected();
- tryLoadImage(selected, imageToLoad);
-
- if(_makeNewSprite != null)
- {
- selected.sprite.x = Math.round(FlxG.camera.scroll.x + FlxG.width/2 - selected.sprite.width/2);
- selected.sprite.y = Math.round(FlxG.camera.scroll.y + FlxG.height/2 - selected.sprite.height/2);
- posTxt.visible = true;
- posTxt.text = 'X: ${selected.sprite.x}\nY: ${selected.sprite.y}';
+ var selected = getSelected();
+ tryLoadImage(selected, imageToLoad);
+
+ if(_makeNewSprite != null)
+ {
+ selected.sprite.x = Math.round(FlxG.camera.scroll.x + FlxG.width/2 - selected.sprite.width/2);
+ selected.sprite.y = Math.round(FlxG.camera.scroll.y + FlxG.height/2 - selected.sprite.height/2);
+ posTxt.visible = true;
+ posTxt.text = 'X: ${selected.sprite.x}\nY: ${selected.sprite.y}';
+ }
+ _makeNewSprite = null;
+ //trace('Inside Psych Engine Folder');
}
- _makeNewSprite = null;
- //trace('Inside Psych Engine Folder');
+ else showOutput('Can\'t load files outside of "images/" folder', true);
}
- else showOutput('Can\'t load files outside of "images/" folder', true);
+ else showOutput('Can\'t load files outside of Psych Engine\'s folder', true);
//TO DO: Maybe make copy of loaded file to an usable folder automatically? That would be very practical
//TO DO: Bring this to Character Editor too
}
_file = null;
#else
- trace('File couldn't be loaded! You aren't on Desktop, are you?');
+ trace('File couldn\'t be loaded! You aren\'t on Desktop, are you?');
#end
}
@@ -2324,4 +2328,4 @@ class StageEditorAnimationSubstate extends MusicBeatSubstate {
close();
}
}
-}
\ No newline at end of file
+}
diff --git a/source/states/editors/WeekEditorState.hx b/source/states/editors/WeekEditorState.hx
index c3312998e35..a3623350982 100644
--- a/source/states/editors/WeekEditorState.hx
+++ b/source/states/editors/WeekEditorState.hx
@@ -40,7 +40,7 @@ class WeekEditorState extends MusicBeatState implements PsychUIEventHandler.Psyc
override function create() {
txtWeekTitle = new FlxText(FlxG.width * 0.7, 10, 0, "", 32);
- txtWeekTitle.setFormat("VCR OSD Mono", 32, FlxColor.WHITE, RIGHT);
+ txtWeekTitle.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, RIGHT);
txtWeekTitle.alpha = 0.7;
var ui_tex = Paths.getSparrowAtlas('campaign_menu_UI_assets');
diff --git a/source/states/editors/content/EditorPlayState.hx b/source/states/editors/content/EditorPlayState.hx
index 69b76384ae7..a69582fe7d8 100644
--- a/source/states/editors/content/EditorPlayState.hx
+++ b/source/states/editors/content/EditorPlayState.hx
@@ -317,7 +317,7 @@ class EditorPlayState extends MusicBeatSubstate
if (idx != 0) {
// CLEAR ANY POSSIBLE GHOST NOTES
for (evilNote in unspawnNotes) {
- var matches: Bool = note.noteData == evilNote.noteData && note.mustPress == evilNote.mustPress;
+ var matches: Bool = note.noteData == evilNote.noteData && note.mustPress == evilNote.mustPress && note.noteType == evilNote.noteType;
if (matches && Math.abs(note.strumTime - evilNote.strumTime) == 0.0) {
evilNote.destroy();
unspawnNotes.remove(evilNote);
@@ -334,7 +334,7 @@ class EditorPlayState extends MusicBeatSubstate
swagNote.scrollFactor.set();
unspawnNotes.push(swagNote);
- var roundSus:Int = Math.floor(swagNote.sustainLength / Conductor.stepCrochet);
+ final roundSus:Int = Math.floor(swagNote.sustainLength / Conductor.stepCrochet);
if(roundSus > 0)
{
for (susNote in 0...roundSus + 1)
diff --git a/source/states/editors/content/MetaNote.hx b/source/states/editors/content/MetaNote.hx
index 09cf3905cbf..2f3a0d467b5 100644
--- a/source/states/editors/content/MetaNote.hx
+++ b/source/states/editors/content/MetaNote.hx
@@ -11,18 +11,22 @@ class MetaNote extends Note
public var songData:Array;
public var sustainSprite:FlxSprite;
public var chartY:Float = 0;
+ public var chartNoteData:Int = 0;
public function new(time:Float, data:Int, songData:Array)
{
super(time, data, null, false, true);
this.songData = songData;
this.strumTime = time;
+ this.chartNoteData = data;
}
public function changeNoteData(v:Int)
{
+ this.chartNoteData = v; //despite being so arbitrary its sadly needed to fix a bug on moving notes
this.songData[1] = v;
this.noteData = v % ChartingState.GRID_COLUMNS_PER_PLAYER;
+ this.mustPress = (v < ChartingState.GRID_COLUMNS_PER_PLAYER);
if(!PlayState.isPixelStage)
loadNoteAnims();
diff --git a/source/states/editors/content/VSlice.hx b/source/states/editors/content/VSlice.hx
index 90a80b2ec20..111ab1df209 100644
--- a/source/states/editors/content/VSlice.hx
+++ b/source/states/editors/content/VSlice.hx
@@ -331,10 +331,10 @@ class VSlice
var notes:Array = [];
var generatedBy:String = 'Psych Engine v${MainMenuState.psychEngineVersion} - Chart Editor V-Slice Exporter';
var timeChanges:Array = [];
-
+
var time:Float = 0;
var bpm:Float = songData.bpm;
-
+ timeChanges.push({t: 0, bpm: bpm}); //so there was first bpm issue (if the song has multiplier bpm)
var lastMustHit:Bool = false;
if(songData.notes != null)
{
@@ -376,9 +376,7 @@ class VSlice
}
events.sort(sortByTime);
notes.sort(sortByTime);
-
- if(timeChanges.length < 1) timeChanges.push({t: 0, bpm: bpm}); //failsafe
-
+
//try to find composer despite it not being a value on psych charts
var composer:String = 'Unknown';
if(Reflect.hasField(songData, 'artist')) composer = Reflect.field(songData, 'artist');
@@ -445,7 +443,7 @@ class VSlice
difficulties: diffs,
characters: {
player: songData.player1,
- girlfriend: songData.gfVersion != null ? songData.gfVersion : 'gf',
+ girlfriend: songData.gfVersion != null ? songData.gfVersion : '', //there is no problem if gf don't exist with it
opponent: songData.player2
},
noteStyle: !PlayState.isPixelStage ? 'funkin' : 'pixel',
@@ -470,4 +468,4 @@ class VSlice
static function sortByTime(Obj1:Dynamic, Obj2:Dynamic):Int
return FlxSort.byValues(FlxSort.ASCENDING, Obj1.t, Obj2.t);
-}
\ No newline at end of file
+}
diff --git a/source/states/stages/PhillyBlazin.hx b/source/states/stages/PhillyBlazin.hx
index 41e031ed81b..7a45d939284 100644
--- a/source/states/stages/PhillyBlazin.hx
+++ b/source/states/stages/PhillyBlazin.hx
@@ -167,8 +167,7 @@ class PhillyBlazin extends BaseStage
{
for (i in 1...4)
{
- //trace('Lightning$i');
- Paths.sound('Lightning$i');
+ Paths.sound('lightning/Lightning$i');
}
}
@@ -231,7 +230,7 @@ class PhillyBlazin extends BaseStage
FlxTween.color(abot, LIGHTNING_FADE_DURATION, 0xFF606060, 0xFF888888);
// Sound
- FlxG.sound.play(Paths.soundRandom('Lightning', 1, 3));
+ FlxG.sound.play(Paths.soundRandom('lightning/Lightning', 1, 3));
}
// Note functions
diff --git a/source/states/stages/PhillyStreets.hx b/source/states/stages/PhillyStreets.hx
index df60ab21f04..2514e300212 100644
--- a/source/states/stages/PhillyStreets.hx
+++ b/source/states/stages/PhillyStreets.hx
@@ -323,8 +323,9 @@ class PhillyStreets extends BaseStage
cutsceneHandler.timer(cutsceneDelay + 5.1, function() //pico fires at can
{
boyfriend.playAnim('intro2', true);
+ boyfriend.specialAnim = true;
- FlxG.sound.play(Paths.soundRandom('shot', 1, 4));
+ FlxG.sound.play(Paths.soundRandom('shots/shot', 1, 4));
FlxTween.tween(FlxG.camera.scroll, {x: camFollow.x + 100 - FlxG.width/2}, 2.5, {ease: FlxEase.quadInOut});
@@ -491,7 +492,7 @@ class PhillyStreets extends BaseStage
}
for (i in 1...5)
- Paths.sound('shot$i');
+ Paths.sound('shots/shot$i');
}
function setupRainShader()
@@ -833,7 +834,7 @@ class PhillyStreets extends BaseStage
boyfriend.holdTimer = 0;
boyfriend.playAnim('shoot', true);
boyfriend.specialAnim = true;
- FlxG.sound.play(Paths.soundRandom('shot', 1, 4));
+ FlxG.sound.play(Paths.soundRandom('shots/shot', 1, 4));
spraycan.playCanShot();
new FlxTimer().start(1/24, function(tmr)
diff --git a/source/states/stages/objects/ABotSpeaker.hx b/source/states/stages/objects/ABotSpeaker.hx
index 0b3eb1d222a..eefa6488835 100644
--- a/source/states/stages/objects/ABotSpeaker.hx
+++ b/source/states/stages/objects/ABotSpeaker.hx
@@ -1,6 +1,8 @@
package states.stages.objects;
-import backend.SpectralAnalyzerEx;
+#if funkin.vis
+import funkin.vis.dsp.SpectralAnalyzer;
+#end
class ABotSpeaker extends FlxSpriteGroup
{
@@ -14,14 +16,18 @@ class ABotSpeaker extends FlxSpriteGroup
public var eyes:FlxAnimate;
public var speaker:FlxAnimate;
- var analyzer:SpectralAnalyzerEx;
+ #if funkin.vis
+ var analyzer:SpectralAnalyzer;
+ #end
var volumes:Array = [];
public var snd(default, set):FlxSound;
function set_snd(changed:FlxSound)
{
snd = changed;
+ #if funkin.vis
initAnalyzer();
+ #end
return snd;
}
@@ -77,14 +83,15 @@ class ABotSpeaker extends FlxSpriteGroup
add(speaker);
}
+ #if funkin.vis
+ var levels:Array;
var levelMax:Int = 0;
override function update(elapsed:Float):Void
{
super.update(elapsed);
if(analyzer == null) return;
- //var levels = analyzer.getLevels(); //this has a memory leak, so i made my own function for it
- var levels = analyzer.recycledLevels();
+ levels = analyzer.getLevels(levels);
var oldLevelMax = levelMax;
levelMax = 0;
for (i in 0...Std.int(Math.min(vizSprites.length, levels.length)))
@@ -103,16 +110,18 @@ class ABotSpeaker extends FlxSpriteGroup
beatHit();
}
}
+ #end
public function beatHit()
{
speaker.anim.play('anim', true);
}
+ #if funkin.vis
public function initAnalyzer()
{
@:privateAccess
- analyzer = new SpectralAnalyzerEx(snd._channel.__audioSource, 7, 0.1, 40);
+ analyzer = new SpectralAnalyzer(snd._channel.__audioSource, 7, 0.1, 40);
#if desktop
// On desktop it uses FFT stuff that isn't as optimized as the direct browser stuff we use on HTML5
@@ -120,6 +129,7 @@ class ABotSpeaker extends FlxSpriteGroup
analyzer.fftN = 256;
#end
}
+ #end
var lookingAtRight:Bool = true;
public function lookLeft()
diff --git a/source/substates/GameOverSubstate.hx b/source/substates/GameOverSubstate.hx
index 08544795598..b4f870815ed 100644
--- a/source/substates/GameOverSubstate.hx
+++ b/source/substates/GameOverSubstate.hx
@@ -84,7 +84,7 @@ class GameOverSubstate extends MusicBeatSubstate
PlayState.instance.setOnScripts('inGameOver', true);
PlayState.instance.callOnScripts('onGameOverStart', []);
- FlxG.sound.music.loadEmbedded(Paths.music(loopSoundName));
+ FlxG.sound.music.loadEmbedded(Paths.music(loopSoundName), true);
if(characterName == 'pico-dead')
{
diff --git a/source/substates/PauseSubState.hx b/source/substates/PauseSubState.hx
index e033deb4bb2..c817b37c199 100644
--- a/source/substates/PauseSubState.hx
+++ b/source/substates/PauseSubState.hx
@@ -171,6 +171,14 @@ class PauseSubState extends MusicBeatSubstate
return;
}
+ if(FlxG.keys.justPressed.F5)
+ {
+ FlxTransitionableState.skipNextTransIn = true;
+ FlxTransitionableState.skipNextTransOut = true;
+ PlayState.nextReloadAll = true;
+ MusicBeatState.resetState();
+ }
+
updateSkipTextStuff();
if (controls.UI_UP_P)
{