diff --git a/Project.xml b/Project.xml
index d2cac59..eeffad6 100644
--- a/Project.xml
+++ b/Project.xml
@@ -112,6 +112,9 @@
+
+
+
diff --git a/README.md b/README.md
index 8b06cf5..832467c 100644
--- a/README.md
+++ b/README.md
@@ -60,3 +60,9 @@ This game was made with love to Newgrounds and its community. Extra love to Tom
### Kade Engine
- [KadeDeveloper](https://twitter.com/KadeDeveloper) - Maintainer and lead programmer
- [The contributors](https://github.com/KadeDev/Kade-Engine/graphs/contributors)
+
+
+### Shoutouts
+- [GWebDev](https://github.com/GrowtopiaFli) - Video Code
+- [Rozebud](https://github.com/ThatRozebudDude) - Ideas (that I stole)
+- [Puyo](https://github.com/daniel11420) - Setting up appveyor and a lot of other help
\ No newline at end of file
diff --git a/assets/preload/videos/daWeirdVid/dontDelete.webm b/assets/preload/videos/daWeirdVid/dontDelete.webm
new file mode 100644
index 0000000..c8865c7
Binary files /dev/null and b/assets/preload/videos/daWeirdVid/dontDelete.webm differ
diff --git a/docs/_includes/header.html b/docs/_includes/header.html
index b5765cd..9780191 100644
--- a/docs/_includes/header.html
+++ b/docs/_includes/header.html
@@ -26,7 +26,7 @@ hr {
-
+
diff --git a/docs/building.md b/docs/building.md
index 8ceaa26..fa8d5a9 100644
--- a/docs/building.md
+++ b/docs/building.md
@@ -28,6 +28,9 @@
- `haxelib git faxe https://github.com/uhrobots/faxe`
- `haxelib git polymod https://github.com/larsiusprime/polymod.git`
- `haxelib git discord_rpc https://github.com/Aidan63/linc_discord-rpc`
+ - `haxelib install actuate`
+ - `haxelib git extension-webm https://github.com/KadeDev/extension-webm`
+ - `lime rebuild extension-webm windows`
### Windows-only dependencies (only for building *to* Windows. Building html5 on Windows does not require this)
If you are planning to build for Windows, you also need to install **Visual Studio 2019**. While installing it, *don't click on any of the options to install workloads*. Instead, go to the **individual components** tab and choose the following:
diff --git a/docs/changelogs/changelog-1.5.3.md b/docs/changelogs/changelog-1.5.3.md
new file mode 100644
index 0000000..510ff5b
--- /dev/null
+++ b/docs/changelogs/changelog-1.5.3.md
@@ -0,0 +1,16 @@
+# Latest (master) changelog
+
+Changes marked with 💖 will be listed in the short version of the changelog in `version.downloadMe`.
+
+### Additions
+- Score Screen (💖)
+- Show your highest combo in the freeplay menu
+- New asset loading system (💖)
+- New Logo (💖)
+
+### Changes
+- Rewrote the entire hit ranking system (💖)
+
+### Bugfixes
+- NPS not showing if accuracy is disabled
+- Fixed song names so they don't crash (💖)
diff --git a/docs/changelogs/index.md b/docs/changelogs/index.md
index aa2dca3..38dc1b7 100644
--- a/docs/changelogs/index.md
+++ b/docs/changelogs/index.md
@@ -1,6 +1,7 @@
# Changelogs
- [Latest](latest) (Contains changes that are not in a release yet)
+- [1.5.3](changelog-1.5.3)
- [1.5.2](changelog-1.5.2)
- [1.5.1](changelog-1.5.1)
- [1.5.0](changelog-1.5.0)
diff --git a/docs/changelogs/latest.md b/docs/changelogs/latest.md
index d7def91..5d6ee6f 100644
--- a/docs/changelogs/latest.md
+++ b/docs/changelogs/latest.md
@@ -3,10 +3,10 @@
Changes marked with 💖 will be listed in the short version of the changelog in `version.downloadMe`.
### Additions
-- Nothing here yet!
+- Nothing yet!
### Changes
-- Nothing here yet!
+- Nothing yet!
### Bugfixes
-- Nothing here yet!
+- Nothing yet!
\ No newline at end of file
diff --git a/docs/modchart.md b/docs/modchart.md
index e1fae25..20b9f65 100644
--- a/docs/modchart.md
+++ b/docs/modchart.md
@@ -1,531 +1,2 @@
-# Lua Modcharts
-
-In the 1.4.2 release of Kade Engine, we introduced Mod Charts. Mod Charts are a way of changing gameplay without hard coded values. This is achieved by using the Lua Scripting language to create script files that run during runtime.
-
-Song data is located in `assets/data//`, so the Lua file containing your scripts should be located at exactly `assets/data//modchart.lua`. (replace with the name of the song. for example, `assets/data/milf/` for milf)
-
-If the file doesn't exist, Lua code won't be ran.
-
-## Examples
-
-Full Example
-
-```lua
-function start (song)
- print("Song: " .. song .. " @ " .. bpm .. " downscroll: " .. downscroll)
-end
-
-
-function update (elapsed) -- example https://twitter.com/KadeDeveloper/status/1382178179184422918
- local currentBeat = (songPos / 1000)*(bpm/60)
- for i=0,7 do
- setActorX(_G['defaultStrum'..i..'X'] + 32 * math.sin((currentBeat + i*0.25) * math.pi), i)
- setActorY(_G['defaultStrum'..i..'Y'] + 32 * math.cos((currentBeat + i*0.25) * math.pi), i)
- end
-end
-
-function beatHit (beat)
- -- do nothing
-end
-
-function stepHit (step)
- -- do nothing
-end
-
-function keyPressed (key)
- -- do nothing
-end
-
-print("Mod Chart script loaded :)")
-```
-
-Spinning Receptor Example
-
-```lua
-function update (elapsed)
- for i=0,7 do
- setActorAngle(getActorAngle(i) + 15, i)
- end
-end
-```
-
-Spinning Hud Example
-
-```lua
-function update (elapsed)
- camHudAngle = camHudAngle + 0.005
-end
-```
-
-Spin at a specific part of the song
-
-```lua
-function update (elapsed)
- if curStep >= 352 and curStep < 400 then
- local currentBeat = (songPos / 1000)*(bpm/60)
- for i=0,7 do
- setActorX(_G['defaultStrum'..i..'X'] + 32 * math.sin((currentBeat + i*0.25) * math.pi), i)
- setActorY(_G['defaultStrum'..i..'Y'] + 32 * math.cos((currentBeat + i*0.25) * math.pi), i)
- end
- else
- for i=0,7 do
- setActorX(_G['defaultStrum'..i..'X'],i)
- setActorY(_G['defaultStrum'..i..'Y'],i)
- end
- end
-end
-```
-
-Showing/Hiding receptors/the hud
-
-```lua
-function start (song)
- showOnlyStrums = true -- remove all hud elements besides notes and strums
- for i=0,3 do -- fade out the first 4 receptors (the ai receptors)
- tweenFadeIn(i,0,0.6)
- end
-end
-```
-
-Looping through all of the rendered notes
-
-```lua
-for i = 0, getRenderedNotes() do -- sets all of the rendered notes to 0 0 on the x and y axsis
- setRenderedNotePos(0,0,i)
-end
-```
-
-Centering BF's Side
-
-```lua
-function setDefault(id)
- _G['defaultStrum'..id..'X'] = getActorX(id)
-end
-
--- put this somewhere in a function
-
-for i = 4, 7 do -- go to the center
- tweenPosXAngle(i, _G['defaultStrum'..i..'X'] - 275,getActorAngle(i) + 360, 0.6, 'setDefault')
-end
-```
-
-Jumping Arrows Example
-```lua
-function stepHit (step)
- if step == 1 then
- setActorAccelerationY(100, 4)
- end
- if step == 3 then
- setActorAccelerationY(100, 5)
- end
- if step == 5 then
- setActorAccelerationY(100, 6)
- end
- if step == 7 then
- setActorAccelerationY(100, 7)
- end
- for i=4,7 do
- if getActorY(i) >= 100 then
- setActorY(100, i)
- setActorVelocityY(-100, i)
- end
- end
-end
-```
-
-
-### Available Hooks
-
-Current calls to functions include,
-
-| Name | Arguments | Description |
-| :-----: | :------------: | :----------------------------------------------------------: |
-| start | Song Name | Gets called when the song starts |
-| update | Elapsed frames | Gets called every frame (after the song starts) |
-| stepHit | Current Step | Gets called when ever a step hits (steps are in between beats, aka 4 steps are in a beat) |
-| beatHit | Current Beat | Gets called when ever a beat hits |
-| keyPressed | Key Pressed | Gets called when a key just got pressed (up, down, left, right, accept) |
-
-
-
-### Global Variables
-
-Kade Engine provides a list of global variables to be used in the lua scripting interface.
-
-| G Name | Type | Description |
-| :------------------: | :---: | :----------------------------------------------------------: |
-| bpm | Float | The current BPM of the song |
-| fpsCap | Int | The current FPS Cap (set by the player) |
-| downscroll | Bool | Whether the player is in downscroll or not |
-| cameraAngle | Float | The angle that the Main Camera should be rotated |
-| camHudAngle | Float | The angle that the Hud should be rotated |
-| followXOffset | Float | The x offset to be added when the camera moves between a character |
-| followYOffset | Float | The y offset to be added when the camera moves between a character |
-| showOnlyStrums | Bool | Whether to show the Hud and Strums or only the Strums |
-| strumLine1Visible | Bool | Whether to show the first strum line or not |
-| strumLine2Visible | Bool | Whether to show the secondstrum line or not |
-| defaultStrum0-7X | Float | (0-7 is strum0,strum1,strum2,etc) get the default X coordinate for the strum |
-| defaultStrum0-7Y | Float | (0-7 is strum0,strum1,strum2,etc) get the default Y coordinate for the strum |
-| defaultStrum0-7Angle | Float | (0-7 is strum0,strum1,strum2,etc) get the default Angle for the strum |
-| screenWidth | Int | The width of the current gamespace |
-| screenHeight | Int | The height of the current gamespace |
-| hudWidth | Int | The width of the hud |
-| hudHeight | Int | The height of the hud |
-| scrollSpeed | Int | The current scrollspeed |
-| mustHit | Bool | If the current section is a must hit section |
-| strumLineY | Float | The current Strum Line Y Position |
-
-## Functions
-
-Kade Engine exposes a lot of functions that let you modify elements in the game field.
-
-
-
-To get started every sprite has an id, and there are some id's that are accessible without creating one.
-
-These premade id's are the following:
-
-| Sprite Id | Value |
-| :--------: | :--------------------------------------: |
-| 0-7 | Represents Receptor 0-7 |
-| boyfriend | Represents the Boyfriend Actor (player1) |
-| dad | Represents the Dad Actor (player2) |
-| girlfriend | Represents the Girlfriend Actor |
-
-
-
-### Sprites
-
-##### makeSprite(string SpritePath,string SpriteId,bool DrawBehind)
-
-Creates a sprite out of the specified image, returns the id you gave it.
-
-*Note: Sprite Path is normally the FILE NAME so if your file is named `Image` it'll go to assets/data/songName/Image.png so don't include the extension*
-
-### Hud/Camera
-
-##### setHudPosition(int x, int y)
-
-Sets the game hud's position in space.
-
-##### getHudX()
-
-Returns the hud's x position
-
-##### getHudY()
-
-Returns the hud's y position
-
-##### setCamPosition(int x, int y)
-
-Set's the current camera's position in space
-
-##### getCameraX()
-
-Returns the current camera's x position
-
-##### getCameraY()
-
-Returns the current camera's y position
-
-##### setCamZoom(float zoomAmount)
-
-Set's the current camera's zoom
-
-##### setHudZoom(float zoomAmount)
-
-Set's the hud's zoom
-
-### Strumline
-
-##### setStrumlineY(float y)
-
-Set's the y position of the strumLine
-
-### Actors
-
-##### getRenderedNotes()
-
-Returns the amount of rendered notes.
-
-##### getRenderedNoteX(int id)
-
-Returns the x position of the rendered note id
-
-*Note: Rendered Notes id's are special in the way that they act. 0 = closest note to any receptor, last index = the farthest away from any receptor.*
-
-##### getRenderedNoteY(int id)
-
-Returns the y position of the rendered note id
-
-*Note: Rendered Notes id's are special in the way that they act. 0 = closest note to any receptor, last index = the farthest away from any receptor.*
-
-##### getRenderedNoteScaleX(int id)
-
-Returns the scale x of the rendered note id
-
-*Note: Rendered Notes id's are special in the way that they act. 0 = closest note to any receptor, last index = the farthest away from any receptor.*
-
-##### getRenderedNoteScaleY(int id)
-
-Returns the scale y of the rendered note id
-
-*Note: Rendered Notes id's are special in the way that they act. 0 = closest note to any receptor, last index = the farthest away from any receptor.*
-
-##### getRenderedNoteType(int id)
-
-Returns the note data of an note (0-3, left, down, up, right)
-
-*Note: Rendered Notes id's are special in the way that they act. 0 = closest note to any receptor, last index = the farthest away from any receptor.*
-
-##### getRenderedNoteHit(int id)
-
-Returns whether a rendered note must be hit by the player or not
-
-*Note: Rendered Notes id's are special in the way that they act. 0 = closest note to any receptor, last index = the farthest away from any receptor.*
-
-##### isSustain(int id)
-
-Returns whether a rendered note is a sustain note or not (if they appear as the trail)
-
-*Note: Rendered Notes id's are special in the way that they act. 0 = closest note to any receptor, last index = the farthest away from any receptor.*
-
-##### isParentSustain(int id)
-
-Returns whether a rendered note's parrent is a sustain note or not (if they appear as the trail)
-
-*Note: Rendered Notes id's are special in the way that they act. 0 = closest note to any receptor, last index = the farthest away from any receptor.*
-
-##### getRenderedNoteParentX(int id)
-
-Returns the current parent x of the specified rendered note's id
-
-*Note: Rendered Notes id's are special in the way that they act. 0 = closest note to any receptor, last index = the farthest away from any receptor.*
-
-##### getRenderedNoteParentY(int id)
-
-Returns the current parent y of the specified rendered note's id
-
-*Note: Rendered Notes id's are special in the way that they act. 0 = closest note to any receptor, last index = the farthest away from any receptor.*
-
-##### getRenderedNoteCalcX(int id)
-
-Returns what the game would normally put the specified rendered note x.
-
-*Note: Rendered Notes id's are special in the way that they act. 0 = closest note to any receptor, last index = the farthest away from any receptor.*
-
-##### anyNotes()
-
-Returns true if there are rendered notes, and returns false if there are none
-
-##### getRenderedNoteStrumtime(int id)
-
-Returns strum time of the rendered note.
-
-*Note: Rendered Notes id's are special in the way that they act. 0 = closest note to any receptor, last index = the farthest away from any receptor.*
-
-##### getRenderedNoteAlpha(int id)
-
-Returns the alpha of the rendered note id
-
-*Note: Rendered Notes id's are special in the way that they act. 0 = closest note to any receptor, last index = the farthest away from any receptor.*
-
-##### getRenderedNoteWidth(int id)
-
-Returns the width of the specified rendered note.
-
-*Note: Rendered Notes id's are special in the way that they act. 0 = closest note to any receptor, last index = the farthest away from any receptor.*
-
-##### getRenderedNoteAngle(int id)
-
-Returns the angle of the specified rendered note.
-
-*Note: Rendered Notes id's are special in the way that they act. 0 = closest note to any receptor, last index = the farthest away from any receptor.*
-
-##### setRenderedNotePos(int x, int y, int id)
-
-Set's the position of the rendered note id
-
-*Note: Setting a Rendered Note's property will stop the note from updating it's alpha & x properties*
-
-##### setRenderedNoteAlpha(float alpha, int id)
-
-Set's the alpha of the rendered note id
-
-*Note: Setting a Rendered Note's property will stop the note from updating it's alpha & x properties*
-
-##### setRenderedNoteScale(float scale, int id)
-
-Set's the scale of the rendered note id
-
-*Note: Setting a Rendered Note's property will stop the note from updating it's alpha & x properties*
-
-##### setRenderedNoteScaleX(float scale, int id) **Currently broken**
-
-Set's the scale x of the rendered note id
-
-*Note: Setting a Rendered Note's property will stop the note from updating it's alpha & x properties*
-
-##### setRenderedNoteScaleY(float scale, int id) **Currently broken**
-
-Set's the scale y of the rendered note id
-
-*Note: Setting a Rendered Note's property will stop the note from updating it's alpha & x properties*
-
-##### getActorX(string/int id)
-
-Returns the x position for the sprite id
-
-##### getActorY(string/int id)
-
-Returns the y position for the sprite id
-
-##### getActorScaleX(string/int id)
-
-Returns the scale x for the sprite id
-
-##### getActorScaleY(string/int id)
-
-Returns the scale y for the sprite id
-
-##### getActorAlpha(string/int id)
-
-Returns the alpha for the sprite id
-
-##### getActorAngle(string/int id)
-
-Returns the angle for the sprite id
-
-##### setActorX(int x, string/int id)
-
-Set's the x position for the sprite id
-
-##### setActorAccelerationX(int x, string/int id)
-
-Sets the x acceleration for the sprite id
-
-##### setActorDragX(int x, string/int id)
-
-Sets the x drag for the sprite id
-
-##### setActorVelocityX(int x, string/int id)
-
-Sets the x velocity for the sprite id
-
-##### setActorY(int y, string/int id)
-
-Set's the y position for the sprite id
-
-##### setActorAccelerationY(int y, string/int id)
-
-Sets the y acceleration for the sprite id
-
-##### setActorDragY(int y, string/int id)
-
-Sets the y drag for the sprite id
-
-##### setActorVelocityY(int y, string/int id)
-
-Sets the y velocity for the sprite id
-
-##### setActorAlpha(float alpha, string/int id)
-
-Set's the alpha for the sprite id
-
-##### setActorAngle(int alpha, string/int id)
-
-Set's the angle for the sprite id
-
-##### setActorScale(float scale, string/int id)
-
-Set's the scale for the sprite id
-
-##### setActorScaleXY(float scaleX, float scaleY, string/int id)
-
-Set's the x and y scale for the sprite id
-
-##### setActorFlipX(bool flip, string/int id)
-
-Set's the x flip for the sprite id
-
-##### setActorFlipY(bool flip, string/int id)
-
-Set's the y flip for the sprite id
-
-##### getActorWidth(string/int id)
-
-Returns the width for the sprite id
-
-##### getActorHeight(string/int id)
-
-Returns the height for the sprite id
-
-##### changeBoyfriendCharacter(string id)
-
-Changes the Boyfriend sprite to another character
-
-##### changeDadCharacter(string id)
-
-Changes the Dad sprite to another character
-
-##### playActorAnimation(string/int id, string anim, bool force, bool reverse)
-
-Plays an animation on a sprite
-
-### Tweens
-
-*Note, On Complete functions are based by the function name (and they also well get called when the tween completes)*
-
-##### tweenPos(string/int id, int toX, int toY, float time, string onComplete)
-
-Smoothly tween into a x and y position
-
-##### tweenPosXAngle(string/int id, int toX, float toAngle, float time, string onComplete)
-
-Smoothly tween into a x position and angle
-
-##### tweenPosYAngle(string/int id, int toY, float toAngle, float time, string onComplete)
-
-Smoothly tween into a y position and angle
-
-##### tweenAngle(string/int id, float toAngle, float time, string onComplete)
-
-Smoothly tween into a angle
-
-##### tweenFadeIn(string/int id, float toAlpha, float time, string onComplete)
-
-Smoothly fade in to an alpha
-
-##### tweenFadeOut(string/int id, float toAlpha, float time, string onComplete)
-
-Smoothly fade out to an alpha
-
-
-
-
-
-### Window & Screen
-
-##### getWindowX()
-
-Returns the window's x position
-
-##### getWindowY()
-
-Returns the window's y position
-
-##### getScreenWidth()
-
-Returns the width of the screen
-
-##### getScreenHeight()
-
-Returns the height of the screen
-
-##### setWindowPos(int x, int y)
-
-Sets the window's position
-
-##### resizeWindow(int width, int height)
-
-Resizes the window
+### RELOCATED
+Relocated to [here](https://github.com/KadeDev/Kade-Engine/wiki/)
diff --git a/source/Caching.hx b/source/Caching.hx
new file mode 100644
index 0000000..2c6fb50
--- /dev/null
+++ b/source/Caching.hx
@@ -0,0 +1,128 @@
+package;
+
+import haxe.Exception;
+import flixel.tweens.FlxEase;
+import flixel.tweens.FlxTween;
+import sys.FileSystem;
+import sys.io.File;
+import flixel.FlxG;
+import flixel.FlxSprite;
+import flixel.addons.transition.FlxTransitionSprite.GraphicTransTileDiamond;
+import flixel.addons.transition.FlxTransitionableState;
+import flixel.addons.transition.TransitionData;
+import flixel.graphics.FlxGraphic;
+import flixel.graphics.frames.FlxAtlasFrames;
+import flixel.math.FlxPoint;
+import flixel.math.FlxRect;
+import flixel.util.FlxColor;
+import flixel.util.FlxTimer;
+import flixel.text.FlxText;
+
+using StringTools;
+
+class Caching extends MusicBeatState
+{
+ var toBeDone = 0;
+ var done = 0;
+
+ var text:FlxText;
+ var kadeLogo:FlxSprite;
+
+ override function create()
+ {
+ FlxG.mouse.visible = false;
+
+ FlxG.worldBounds.set(0,0);
+
+ text = new FlxText(FlxG.width / 2, FlxG.height / 2 + 300,0,"Loading...");
+ text.size = 34;
+ text.alignment = FlxTextAlign.CENTER;
+ text.alpha = 0;
+
+ kadeLogo = new FlxSprite(FlxG.width / 2, FlxG.height / 2).loadGraphic(Paths.image('KadeEngineLogo'));
+ kadeLogo.x -= kadeLogo.width / 2;
+ kadeLogo.y -= kadeLogo.height / 2 + 100;
+ text.y -= kadeLogo.height / 2 - 125;
+ text.x -= 170;
+ kadeLogo.setGraphicSize(Std.int(kadeLogo.width * 0.6));
+
+ kadeLogo.alpha = 0;
+
+ add(kadeLogo);
+ add(text);
+
+ trace('starting caching..');
+
+ sys.thread.Thread.create(() -> {
+ cache();
+ });
+
+
+ super.create();
+ }
+
+ var calledDone = false;
+
+ override function update(elapsed)
+ {
+
+ if (toBeDone != 0 && done != toBeDone)
+ {
+ var alpha = HelperFunctions.truncateFloat(done / toBeDone * 100,2) / 100;
+ kadeLogo.alpha = alpha;
+ text.alpha = alpha;
+ text.text = "Loading... (" + done + "/" + toBeDone + ")";
+ }
+
+ super.update(elapsed);
+ }
+
+
+ function cache()
+ {
+
+ var images = [];
+ var music = [];
+
+ trace("caching images...");
+
+ for (i in FileSystem.readDirectory(FileSystem.absolutePath("assets/shared/images/characters")))
+ {
+ if (!i.endsWith(".png"))
+ continue;
+ images.push(i);
+ }
+
+ trace("caching music...");
+
+ for (i in FileSystem.readDirectory(FileSystem.absolutePath("assets/songs")))
+ {
+ music.push(i);
+ }
+
+ toBeDone = Lambda.count(images) + Lambda.count(music);
+
+ trace("LOADING: " + toBeDone + " OBJECTS.");
+
+ for (i in images)
+ {
+ var replaced = i.replace(".png","");
+ FlxG.bitmap.add(Paths.image("characters/" + replaced,"shared"));
+ trace("cached " + replaced);
+ done++;
+ }
+
+ for (i in music)
+ {
+ FlxG.sound.cache(Paths.inst(i));
+ FlxG.sound.cache(Paths.voices(i));
+ trace("cached " + i);
+ done++;
+ }
+
+ trace("Finished caching...");
+
+ FlxG.switchState(new TitleState());
+ }
+
+}
\ No newline at end of file
diff --git a/source/FreeplayState.hx b/source/FreeplayState.hx
index 6f7388d..91ca64a 100644
--- a/source/FreeplayState.hx
+++ b/source/FreeplayState.hx
@@ -26,9 +26,11 @@ class FreeplayState extends MusicBeatState
var curDifficulty:Int = 1;
var scoreText:FlxText;
+ var comboText:FlxText;
var diffText:FlxText;
var lerpScore:Int = 0;
var intendedScore:Int = 0;
+ var combo:String = '';
private var grpSongs:FlxTypedGroup;
private var curPlaying:Bool = false;
@@ -106,6 +108,10 @@ class FreeplayState extends MusicBeatState
diffText.font = scoreText.font;
add(diffText);
+ comboText = new FlxText(diffText.x + 100, diffText.y, 0, "", 24);
+ comboText.font = diffText.font;
+ add(comboText);
+
add(scoreText);
changeSelection();
@@ -176,6 +182,7 @@ class FreeplayState extends MusicBeatState
lerpScore = intendedScore;
scoreText.text = "PERSONAL BEST:" + lerpScore;
+ comboText.text = combo + '\n';
var upP = controls.UP_P;
var downP = controls.DOWN_P;
@@ -202,27 +209,20 @@ class FreeplayState extends MusicBeatState
if (accepted)
{
- // pre lowercasing the song name (update)
- var songLowercase = StringTools.replace(songs[curSelected].songName, " ", "-").toLowerCase();
- switch (songLowercase) {
- case 'dad-battle': songLowercase = 'dadbattle';
- case 'philly-nice': songLowercase = 'philly';
- }
- // adjusting the highscore song name to be compatible (update)
- // would read original scores if we didn't change packages
- var songHighscore = StringTools.replace(songs[curSelected].songName, " ", "-");
- switch (songHighscore) {
- case 'Dad-Battle': songHighscore = 'Dadbattle';
- case 'Philly-Nice': songHighscore = 'Philly';
+ // adjusting the song name to be compatible
+ var songFormat = StringTools.replace(songs[curSelected].songName, " ", "-");
+ switch (songFormat) {
+ case 'Dad-Battle': songFormat = 'Dadbattle';
+ case 'Philly-Nice': songFormat = 'Philly';
}
- trace(songLowercase);
+ trace(songs[curSelected].songName);
- var poop:String = Highscore.formatSong(songHighscore, curDifficulty);
+ var poop:String = Highscore.formatSong(songFormat, curDifficulty);
trace(poop);
- PlayState.SONG = Song.loadFromJson(poop, songLowercase);
+ PlayState.SONG = Song.loadFromJson(poop, songs[curSelected].songName);
PlayState.isStoryMode = false;
PlayState.storyDifficulty = curDifficulty;
PlayState.storyWeek = songs[curSelected].week;
@@ -249,6 +249,7 @@ class FreeplayState extends MusicBeatState
#if !switch
intendedScore = Highscore.getScore(songHighscore, curDifficulty);
+ combo = Highscore.getCombo(songHighscore, curDifficulty);
#end
switch (curDifficulty)
@@ -290,6 +291,7 @@ class FreeplayState extends MusicBeatState
#if !switch
intendedScore = Highscore.getScore(songHighscore, curDifficulty);
+ combo = Highscore.getCombo(songHighscore, curDifficulty);
// lerpScore = 0;
#end
diff --git a/source/GameDimensions.hx b/source/GameDimensions.hx
new file mode 100644
index 0000000..db4a62a
--- /dev/null
+++ b/source/GameDimensions.hx
@@ -0,0 +1,7 @@
+package;
+
+class GameDimensions
+{
+ public static var width:Int = 1280;
+ public static var height:Int = 720;
+}
\ No newline at end of file
diff --git a/source/GlobalVideo.hx b/source/GlobalVideo.hx
new file mode 100644
index 0000000..2c4f707
--- /dev/null
+++ b/source/GlobalVideo.hx
@@ -0,0 +1,95 @@
+package;
+
+import openfl.Lib;
+
+class GlobalVideo
+{
+ private static var video:VideoHandler;
+ private static var webm:WebmHandler;
+ public static var isWebm:Bool = false;
+ public static var isAndroid:Bool = false;
+ public static var daAlpha1:Float = 0.2;
+ public static var daAlpha2:Float = 1;
+
+ public static function setVid(vid:VideoHandler):Void
+ {
+ video = vid;
+ }
+
+ public static function getVid():VideoHandler
+ {
+ return video;
+ }
+
+ public static function setWebm(vid:WebmHandler):Void
+ {
+ webm = vid;
+ isWebm = true;
+ }
+
+ public static function getWebm():WebmHandler
+ {
+ return webm;
+ }
+
+ public static function get():Dynamic
+ {
+ if (isWebm)
+ {
+ return getWebm();
+ } else {
+ return getVid();
+ }
+ }
+
+ public static function calc(ind:Int):Dynamic
+ {
+ var stageWidth:Int = Lib.current.stage.stageWidth;
+ var stageHeight:Int = Lib.current.stage.stageHeight;
+
+ var width:Float = GameDimensions.width;
+ var height:Float = GameDimensions.height;
+
+ //trace("AH: " + stageWidth);
+ //trace(width);
+
+ var ratioX:Float = height / width;
+ var ratioY:Float = width / height;
+ var appliedWidth:Float = stageHeight * ratioY;
+ var appliedHeight:Float = stageWidth * ratioX;
+ //trace(appliedWidth);
+ var remainingX:Float = stageWidth - appliedWidth;
+ var remainingY:Float = stageHeight - appliedHeight;
+ remainingX = remainingX / 2;
+ remainingY = remainingY / 2;
+
+ appliedWidth = Std.int(appliedWidth);
+ appliedHeight = Std.int(appliedHeight);
+
+ if (appliedHeight > stageHeight)
+ {
+ remainingY = 0;
+ appliedHeight = stageHeight;
+ }
+
+ if (appliedWidth > stageWidth)
+ {
+ remainingX = 0;
+ appliedWidth = stageWidth;
+ }
+
+ switch(ind)
+ {
+ case 0:
+ return remainingX;
+ case 1:
+ return remainingY;
+ case 2:
+ return appliedWidth;
+ case 3:
+ return appliedHeight;
+ }
+
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/source/HelperFunctions.hx b/source/HelperFunctions.hx
index 8f6c6fc..b17dc6a 100644
--- a/source/HelperFunctions.hx
+++ b/source/HelperFunctions.hx
@@ -1,3 +1,5 @@
+import flixel.math.FlxMath;
+
class HelperFunctions
{
public static function truncateFloat( number : Float, precision : Int): Float {
@@ -6,4 +8,8 @@ class HelperFunctions
num = Math.round( num ) / Math.pow(10, precision);
return num;
}
+
+ public static function GCD(a, b) {
+ return b == 0 ? FlxMath.absInt(a) : GCD(b, a % b);
+ }
}
\ No newline at end of file
diff --git a/source/Highscore.hx b/source/Highscore.hx
index 78a6d30..8d82fcb 100644
--- a/source/Highscore.hx
+++ b/source/Highscore.hx
@@ -2,12 +2,15 @@ package;
import flixel.FlxG;
+using StringTools;
class Highscore
{
#if (haxe >= "4.0.0")
public static var songScores:Map = new Map();
+ public static var songCombos:Map = new Map();
#else
public static var songScores:Map = new Map();
+ public static var songCombos:Map = new Map();
#end
@@ -32,6 +35,23 @@ class Highscore
}else trace('BotPlay detected. Score saving is disabled.');
}
+ public static function saveCombo(song:String, combo:String, ?diff:Int = 0):Void
+ {
+ var daSong:String = formatSong(song, diff);
+ var finalCombo:String = combo.split(')')[0].replace('(', '');
+
+ if(!FlxG.save.data.botplay)
+ {
+ if (songCombos.exists(daSong))
+ {
+ if (getComboInt(songCombos.get(daSong)) < getComboInt(finalCombo))
+ setCombo(daSong, finalCombo);
+ }
+ else
+ setCombo(daSong, finalCombo);
+ }
+ }
+
public static function saveWeekScore(week:Int = 1, score:Int = 0, ?diff:Int = 0):Void
{
@@ -64,6 +84,14 @@ class Highscore
FlxG.save.flush();
}
+ static function setCombo(song:String, combo:String):Void
+ {
+ // Reminder that I don't need to format this song, it should come formatted!
+ songCombos.set(song, combo);
+ FlxG.save.data.songCombos = songCombos;
+ FlxG.save.flush();
+ }
+
public static function formatSong(song:String, diff:Int):String
{
var daSong:String = song;
@@ -76,6 +104,23 @@ class Highscore
return daSong;
}
+ static function getComboInt(combo:String):Int
+ {
+ switch(combo)
+ {
+ case 'SDCB':
+ return 1;
+ case 'FC':
+ return 2;
+ case 'GFC':
+ return 3;
+ case 'MFC':
+ return 4;
+ default:
+ return 0;
+ }
+ }
+
public static function getScore(song:String, diff:Int):Int
{
if (!songScores.exists(formatSong(song, diff)))
@@ -84,6 +129,14 @@ class Highscore
return songScores.get(formatSong(song, diff));
}
+ public static function getCombo(song:String, diff:Int):String
+ {
+ if (!songCombos.exists(formatSong(song, diff)))
+ setCombo(formatSong(song, diff), '');
+
+ return songCombos.get(formatSong(song, diff));
+ }
+
public static function getWeekScore(week:Int, diff:Int):Int
{
if (!songScores.exists(formatSong('week' + week, diff)))
@@ -98,5 +151,9 @@ class Highscore
{
songScores = FlxG.save.data.songScores;
}
+ if (FlxG.save.data.songCombos != null)
+ {
+ songCombos = FlxG.save.data.songCombos;
+ }
}
-}
\ No newline at end of file
+}
diff --git a/source/HitGraph.hx b/source/HitGraph.hx
new file mode 100644
index 0000000..e3b3790
--- /dev/null
+++ b/source/HitGraph.hx
@@ -0,0 +1,250 @@
+import openfl.display.Bitmap;
+import openfl.display.BitmapData;
+import openfl.text.TextFieldAutoSize;
+import flixel.system.FlxAssets;
+import openfl.text.TextFormat;
+import flash.display.Graphics;
+import flash.display.Shape;
+import flash.display.Sprite;
+import flash.text.TextField;
+import flash.text.TextFormatAlign;
+import flixel.math.FlxMath;
+import flixel.util.FlxColor;
+import flixel.util.FlxDestroyUtil;
+
+/**
+ * stolen from https://github.com/HaxeFlixel/flixel/blob/master/flixel/system/debug/stats/StatsGraph.hx
+ */
+class HitGraph extends Sprite
+{
+ static inline var AXIS_COLOR:FlxColor = 0xffffff;
+ static inline var AXIS_ALPHA:Float = 0.5;
+ inline static var HISTORY_MAX:Int = 30;
+
+ public var minLabel:TextField;
+ public var curLabel:TextField;
+ public var maxLabel:TextField;
+ public var avgLabel:TextField;
+
+ public var minValue:Float = -(Math.floor((PlayState.rep.replay.sf / 60) * 1000) + 95);
+ public var maxValue:Float = Math.floor((PlayState.rep.replay.sf / 60) * 1000) + 95;
+
+ public var graphColor:FlxColor;
+
+ public var history:Array = [];
+
+ public var bitmap:Bitmap;
+
+ var _axis:Shape;
+ var _width:Int;
+ var _height:Int;
+ var _unit:String;
+ var _labelWidth:Int;
+ var _label:String;
+
+ public function new(X:Int, Y:Int, Width:Int, Height:Int)
+ {
+ super();
+ x = X;
+ y = Y;
+ _width = Width;
+ _height = Height;
+
+ var bm = new BitmapData(Width,Height);
+ bm.draw(this);
+ bitmap = new Bitmap(bm);
+
+ _axis = new Shape();
+ _axis.x = _labelWidth + 10;
+
+ var ts = Math.floor((PlayState.rep.replay.sf / 60) * 1000) / 166;
+
+ var early = createTextField(10,10,FlxColor.WHITE,12);
+ var late = createTextField(10,_height - 20,FlxColor.WHITE,12);
+
+ early.text = "Early (" + -166 * ts + "ms)";
+ late.text = "Late (" + 166 * ts + "ms)";
+
+ addChild(early);
+ addChild(late);
+
+ addChild(_axis);
+
+ drawAxes();
+ }
+
+ /**
+ * Redraws the axes of the graph.
+ */
+ function drawAxes():Void
+ {
+ var gfx = _axis.graphics;
+ gfx.clear();
+ gfx.lineStyle(1, AXIS_COLOR, AXIS_ALPHA);
+
+ // y-Axis
+ gfx.moveTo(0, 0);
+ gfx.lineTo(0, _height);
+
+ // x-Axis
+ gfx.moveTo(0, _height);
+ gfx.lineTo(_width, _height);
+
+ gfx.moveTo(0, _height / 2);
+ gfx.lineTo(_width, _height / 2);
+
+ }
+
+ public static function createTextField(X:Float = 0, Y:Float = 0, Color:FlxColor = FlxColor.WHITE, Size:Int = 12):TextField
+ {
+ return initTextField(new TextField(), X, Y, Color, Size);
+ }
+
+ public static function initTextField(tf:T, X:Float = 0, Y:Float = 0, Color:FlxColor = FlxColor.WHITE, Size:Int = 12):T
+ {
+ tf.x = X;
+ tf.y = Y;
+ tf.multiline = false;
+ tf.wordWrap = false;
+ tf.embedFonts = true;
+ tf.selectable = false;
+ #if flash
+ tf.antiAliasType = AntiAliasType.NORMAL;
+ tf.gridFitType = GridFitType.PIXEL;
+ #end
+ tf.defaultTextFormat = new TextFormat("assets/fonts/vcr.ttf", Size, Color.to24Bit());
+ tf.alpha = Color.alphaFloat;
+ tf.autoSize = TextFieldAutoSize.LEFT;
+ return tf;
+ }
+
+ function drawJudgementLine(ms:Float):Void
+ {
+
+ var gfx:Graphics = graphics;
+
+ gfx.lineStyle(1, graphColor, 0.3);
+
+ var ts = Math.floor((PlayState.rep.replay.sf / 60) * 1000) / 166;
+ var range:Float = Math.max(maxValue - minValue, maxValue * 0.1);
+
+ var value = ((ms * ts) - minValue) / range;
+
+ var pointY = _axis.y + ((-value * _height - 1) + _height);
+
+ var graphX = _axis.x + 1;
+
+ if (ms == 45)
+ gfx.moveTo(graphX, _axis.y + pointY);
+
+ var graphX = _axis.x + 1;
+
+ gfx.drawRect(graphX,pointY, _width,1);
+
+ gfx.lineStyle(1, graphColor, 1);
+ }
+
+ /**
+ * Redraws the graph based on the values stored in the history.
+ */
+ function drawGraph():Void
+ {
+ var gfx:Graphics = graphics;
+ gfx.clear();
+ gfx.lineStyle(1, graphColor, 1);
+
+ gfx.beginFill(0x00FF00);
+ drawJudgementLine(45);
+ gfx.endFill();
+
+ gfx.beginFill(0xFF0000);
+ drawJudgementLine(90);
+ gfx.endFill();
+
+ gfx.beginFill(0x8b0000);
+ drawJudgementLine(135);
+ gfx.endFill();
+
+ gfx.beginFill(0x580000);
+ drawJudgementLine(166);
+ gfx.endFill();
+
+ gfx.beginFill(0x00FF00);
+ drawJudgementLine(-45);
+ gfx.endFill();
+
+ gfx.beginFill(0xFF0000);
+ drawJudgementLine(-90);
+ gfx.endFill();
+
+ gfx.beginFill(0x8b0000);
+ drawJudgementLine(-135);
+ gfx.endFill();
+
+ gfx.beginFill(0x580000);
+ drawJudgementLine(-166);
+ gfx.endFill();
+
+
+ var inc:Float = _width / (PlayState.rep.replay.songNotes.length);
+ var range:Float = Math.max(maxValue - minValue, maxValue * 0.1);
+ var graphX = _axis.x + 1;
+
+ for (i in 0...history.length)
+ {
+
+ var value = (history[i][0] - minValue) / range;
+ var judge = history[i][1];
+
+ switch(judge)
+ {
+ case "sick":
+ gfx.beginFill(0x00FFFF);
+ case "good":
+ gfx.beginFill(0x00FF00);
+ case "bad":
+ gfx.beginFill(0xFF0000);
+ case "shit":
+ gfx.beginFill(0x8b0000);
+ case "miss":
+ gfx.beginFill(0x580000);
+ default:
+ gfx.beginFill(0xFFFFFF);
+ }
+ var pointY = (-value * _height - 1) + _height;
+ /*if (i == 0)
+ gfx.moveTo(graphX, _axis.y + pointY);*/
+ gfx.drawRect(graphX + (i * inc), pointY,4,4);
+
+ gfx.endFill();
+ }
+
+ var bm = new BitmapData(_width,_height);
+ bm.draw(this);
+ bitmap = new Bitmap(bm);
+ }
+
+ public function addToHistory(diff:Float, judge:String)
+ {
+ history.push([diff,judge]);
+ }
+
+ public function update():Void
+ {
+ drawGraph();
+ }
+
+ public function average():Float
+ {
+ var sum:Float = 0;
+ for (value in history)
+ sum += value;
+ return sum / history.length;
+ }
+
+ public function destroy():Void
+ {
+ _axis = FlxDestroyUtil.removeChild(this, _axis);
+ history = null;
+ }
+}
\ No newline at end of file
diff --git a/source/KadeEngineData.hx b/source/KadeEngineData.hx
index 5ae671a..0a8204d 100644
--- a/source/KadeEngineData.hx
+++ b/source/KadeEngineData.hx
@@ -81,6 +81,12 @@ class KadeEngineData
if (FlxG.save.data.customStrumLine == null)
FlxG.save.data.customStrumLine = 0;
+ if (FlxG.save.data.camzoom == null)
+ FlxG.save.data.camzoom = true;
+
+ if (FlxG.save.data.scoreScreen == null)
+ FlxG.save.data.scoreScreen = true;
+
Conductor.recalculateTimings();
PlayerSettings.player1.controls.loadKeyBinds();
KeyBinds.keyCheck();
diff --git a/source/LoadReplayState.hx b/source/LoadReplayState.hx
index 1be8679..b654f24 100644
--- a/source/LoadReplayState.hx
+++ b/source/LoadReplayState.hx
@@ -80,7 +80,7 @@ class LoadReplayState extends MusicBeatState
}
- versionShit = new FlxText(5, FlxG.height - 34, 0, "Replay Loader (ESCAPE TO GO BACK)\nNOTICE!!!! Replays are in a beta stage, and they are probably not 100% correct. expect misses and other stuff that isn't there!", 12);
+ versionShit = new FlxText(5, FlxG.height - 34, 0, "Replay Loader (ESCAPE TO GO BACK)\nNOTICE!!!! Replays are in a beta stage, and they are probably not 100% correct. expect misses and other stuff that isn't there!\n", 12);
versionShit.scrollFactor.set();
versionShit.setFormat("VCR OSD Mono", 16, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK);
add(versionShit);
@@ -102,7 +102,7 @@ class LoadReplayState extends MusicBeatState
for (i in 0...songs.length)
{
var pog:FreeplayState.SongMetadata = songs[i];
- if (pog.songName.toLowerCase() == songName)
+ if (pog.songName == songName)
week = pog.week;
}
return week;
@@ -148,13 +148,32 @@ class LoadReplayState extends MusicBeatState
PlayState.loadRep = true;
- var poop:String = Highscore.formatSong(PlayState.rep.replay.songName.toLowerCase(), PlayState.rep.replay.songDiff);
+ if (PlayState.rep.replay.replayGameVer == Replay.version)
+ {
- PlayState.SONG = Song.loadFromJson(poop, PlayState.rep.replay.songName.toLowerCase());
- PlayState.isStoryMode = false;
- PlayState.storyDifficulty = PlayState.rep.replay.songDiff;
- PlayState.storyWeek = getWeekNumbFromSong(PlayState.rep.replay.songName);
- LoadingState.loadAndSwitchState(new PlayState());
+ // adjusting the song name to be compatible
+ var songFormat = StringTools.replace(PlayState.rep.replay.songName, " ", "-");
+ switch (songFormat) {
+ case 'Dad-Battle': songFormat = 'Dadbattle';
+ case 'Philly-Nice': songFormat = 'Philly';
+ // Replay v1.0 support
+ case 'dad-battle': songFormat = 'Dadbattle';
+ case 'philly-nice': songFormat = 'Philly';
+ }
+
+ var poop:String = Highscore.formatSong(songFormat, PlayState.rep.replay.songDiff);
+
+ PlayState.SONG = Song.loadFromJson(poop, PlayState.rep.replay.songName);
+ PlayState.isStoryMode = false;
+ PlayState.storyDifficulty = PlayState.rep.replay.songDiff;
+ PlayState.storyWeek = getWeekNumbFromSong(PlayState.rep.replay.songName);
+ LoadingState.loadAndSwitchState(new PlayState());
+ }
+ else
+ {
+ PlayState.rep = null;
+ PlayState.loadRep = false;
+ }
}
}
@@ -177,7 +196,7 @@ class LoadReplayState extends MusicBeatState
var rep:Replay = Replay.LoadReplay(actualNames[curSelected]);
- poggerDetails.text = "Replay Details - \nDate Created: " + rep.replay.timestamp + "\nSong: " + rep.replay.songName + "\nReplay Version: " + (rep.replay.replayGameVer != Replay.version ? "OUTDATED" : "Latest");
+ poggerDetails.text = "Replay Details - \nDate Created: " + rep.replay.timestamp + "\nSong: " + rep.replay.songName + "\nReplay Version: " + rep.replay.replayGameVer + ' (' + (rep.replay.replayGameVer != Replay.version ? "OUTDATED not useable!" : "Latest") + ')\n';
// selector.y = (70 * curSelected) + 30;
diff --git a/source/Main.hx b/source/Main.hx
index 48f0fc3..e04c2f5 100644
--- a/source/Main.hx
+++ b/source/Main.hx
@@ -1,5 +1,7 @@
package;
+
+import webm.WebmPlayer;
import openfl.display.BlendMode;
import openfl.text.TextFormat;
import openfl.display.Application;
@@ -49,6 +51,8 @@ class Main extends Sprite
}
}
+ public static var webmHandler:WebmHandler;
+
private function init(?E:Event):Void
{
if (hasEventListener(Event.ADDED_TO_STAGE))
@@ -73,10 +77,8 @@ class Main extends Sprite
gameHeight = Math.ceil(stageHeight / zoom);
}
- #if !debug
- initialState = TitleState;
- #end
-
+ initialState = Caching;
+
game = new FlxGame(gameWidth, gameHeight, initialState, zoom, framerate, framerate, skipSplash, startFullscreen);
addChild(game);
diff --git a/source/MainMenuState.hx b/source/MainMenuState.hx
index 2815cfd..e3e0756 100644
--- a/source/MainMenuState.hx
+++ b/source/MainMenuState.hx
@@ -39,7 +39,7 @@ class MainMenuState extends MusicBeatState
public static var nightly:String = "";
- public static var kadeEngineVer:String = "1.5.2" + nightly;
+ public static var kadeEngineVer:String = "1.5.3" + nightly;
public static var gameVer:String = "0.2.7.1";
var magenta:FlxSprite;
diff --git a/source/ModchartState.hx b/source/ModchartState.hx
index 1203ea5..6e194d1 100644
--- a/source/ModchartState.hx
+++ b/source/ModchartState.hx
@@ -1,6 +1,7 @@
// this file is for modchart things, this is to declutter playstate.hx
// Lua
+import openfl.display3D.textures.VideoTexture;
import flixel.graphics.FlxGraphic;
import flixel.graphics.frames.FlxAtlasFrames;
#if windows
@@ -255,11 +256,18 @@ class ModchartState
function makeAnimatedLuaSprite(spritePath:String,names:Array,prefixes:Array,startAnim:String, id:String)
{
#if sys
- var data:BitmapData = BitmapData.fromFile(Sys.getCwd() + "assets/data/" + PlayState.SONG.song.toLowerCase() + '/' + spritePath + ".png");
+ // pre lowercasing the song name (makeAnimatedLuaSprite)
+ var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase();
+ switch (songLowercase) {
+ case 'dad-battle': songLowercase = 'dadbattle';
+ case 'philly-nice': songLowercase = 'philly';
+ }
+
+ var data:BitmapData = BitmapData.fromFile(Sys.getCwd() + "assets/data/" + songLowercase + '/' + spritePath + ".png");
var sprite:FlxSprite = new FlxSprite(0,0);
- sprite.frames = FlxAtlasFrames.fromSparrow(FlxGraphic.fromBitmapData(data), Sys.getCwd() + "assets/data/" + PlayState.SONG.song.toLowerCase() + "/" + spritePath + ".xml");
+ sprite.frames = FlxAtlasFrames.fromSparrow(FlxGraphic.fromBitmapData(data), Sys.getCwd() + "assets/data/" + songLowercase + "/" + spritePath + ".xml");
trace(sprite.frames.frames.length);
@@ -282,7 +290,14 @@ class ModchartState
function makeLuaSprite(spritePath:String,toBeCalled:String, drawBehind:Bool)
{
#if sys
- var data:BitmapData = BitmapData.fromFile(Sys.getCwd() + "assets/data/" + PlayState.SONG.song.toLowerCase() + '/' + spritePath + ".png");
+ // pre lowercasing the song name (makeLuaSprite)
+ var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase();
+ switch (songLowercase) {
+ case 'dad-battle': songLowercase = 'dadbattle';
+ case 'philly-nice': songLowercase = 'philly';
+ }
+
+ var data:BitmapData = BitmapData.fromFile(Sys.getCwd() + "assets/data/" + songLowercase + '/' + spritePath + ".png");
var sprite:FlxSprite = new FlxSprite(0,0);
var imgWidth:Float = FlxG.width / data.width;
@@ -345,7 +360,14 @@ class ModchartState
//shaders = new Array();
- var result = LuaL.dofile(lua, Paths.lua(PlayState.SONG.song.toLowerCase() + "/modchart")); // execute le file
+ // pre lowercasing the song name (new)
+ var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase();
+ switch (songLowercase) {
+ case 'dad-battle': songLowercase = 'dadbattle';
+ case 'philly-nice': songLowercase = 'philly';
+ }
+
+ var result = LuaL.dofile(lua, Paths.lua(songLowercase + "/modchart")); // execute le file
if (result != 0)
{
@@ -361,6 +383,8 @@ class ModchartState
setVar("scrollspeed", FlxG.save.data.scrollSpeed != 1 ? FlxG.save.data.scrollSpeed : PlayState.SONG.speed);
setVar("fpsCap", FlxG.save.data.fpsCap);
setVar("downscroll", FlxG.save.data.downscroll);
+ setVar("flashing", FlxG.save.data.flashing);
+ setVar("distractions", FlxG.save.data.distractions);
setVar("curStep", 0);
setVar("curBeat", 0);
@@ -413,10 +437,43 @@ class ModchartState
PlayState.instance.removeObject(sprite);
return true;
});
-
-
// hud/camera
+
+ Lua_helper.add_callback(lua,"initBackgroundVideo", function(videoName:String) {
+ trace('playing assets/videos/' + videoName + '.webm');
+ PlayState.instance.backgroundVideo("assets/videos/" + videoName + ".webm");
+ });
+
+ Lua_helper.add_callback(lua,"pauseVideo", function() {
+ if (!GlobalVideo.get().paused)
+ GlobalVideo.get().pause();
+ });
+
+ Lua_helper.add_callback(lua,"resumeVideo", function() {
+ if (GlobalVideo.get().paused)
+ GlobalVideo.get().pause();
+ });
+
+ Lua_helper.add_callback(lua,"restartVideo", function() {
+ GlobalVideo.get().restart();
+ });
+
+ Lua_helper.add_callback(lua,"getVideoSpriteX", function() {
+ return PlayState.instance.videoSprite.x;
+ });
+
+ Lua_helper.add_callback(lua,"getVideoSpriteY", function() {
+ return PlayState.instance.videoSprite.y;
+ });
+
+ Lua_helper.add_callback(lua,"setVideoSpritePos", function(x:Int,y:Int) {
+ PlayState.instance.videoSprite.setPosition(x,y);
+ });
+
+ Lua_helper.add_callback(lua,"setVideoSpriteScale", function(scale:Float) {
+ PlayState.instance.videoSprite.setGraphicSize(Std.int(PlayState.instance.videoSprite.width * scale));
+ });
Lua_helper.add_callback(lua,"setHudAngle", function (x:Float) {
PlayState.instance.camHUD.angle = x;
diff --git a/source/Note.hx b/source/Note.hx
index 7e29d7b..f7f915e 100644
--- a/source/Note.hx
+++ b/source/Note.hx
@@ -50,7 +50,7 @@ class Note extends FlxSprite
x += 50;
// MAKE SURE ITS DEFINITELY OFF SCREEN?
y -= 2000;
- this.strumTime = strumTime;
+ this.strumTime = Math.round(strumTime);
if (this.strumTime < 0 )
this.strumTime = 0;
@@ -59,7 +59,14 @@ class Note extends FlxSprite
var daStage:String = PlayState.curStage;
- switch (PlayState.SONG.noteStyle)
+ //defaults if no noteStyle was found in chart
+ var noteTypeCheck:String = 'normal';
+
+ if (PlayState.SONG.noteStyle == null) {
+ switch(PlayState.storyWeek) {case 6: noteTypeCheck = 'pixel';}
+ } else {noteTypeCheck = PlayState.SONG.noteStyle;}
+
+ switch (noteTypeCheck)
{
case 'pixel':
loadGraphic(Paths.image('weeb/pixelUI/arrows-pixels','week6'), true, 17, 17);
diff --git a/source/Options.hx b/source/Options.hx
index 1d6208c..4ed6a5f 100644
--- a/source/Options.hx
+++ b/source/Options.hx
@@ -296,8 +296,8 @@ class Judgement extends Option
override function getValue():String {
return "Safe Frames: " + Conductor.safeFrames +
- " - SIK: " + HelperFunctions.truncateFloat(45 * Conductor.timeScale, 0) +
- "ms GD: " + HelperFunctions.truncateFloat(90 * Conductor.timeScale, 0) +
+ " - SIK: " + HelperFunctions.truncateFloat(22 * Conductor.timeScale, 0) +
+ "ms GD: " + HelperFunctions.truncateFloat(45 * Conductor.timeScale, 0) +
"ms BD: " + HelperFunctions.truncateFloat(135 * Conductor.timeScale, 0) +
"ms SHT: " + HelperFunctions.truncateFloat(155 * Conductor.timeScale, 0) +
"ms TOTAL: " + HelperFunctions.truncateFloat(Conductor.safeZoneOffset,0) + "ms";
@@ -338,6 +338,27 @@ class FPSOption extends Option
}
}
+class ScoreScreen extends Option
+{
+ public function new(desc:String)
+ {
+ super();
+ description = desc;
+ }
+
+ public override function press():Bool
+ {
+ FlxG.save.data.scoreScreen = !FlxG.save.data.scoreScreen;
+ return true;
+ }
+
+ private override function updateDisplay():String
+ {
+ return (FlxG.save.data.scoreScreen ? "Show Score Screen" : "No Score Screen");
+ }
+}
+
+
class FPSCapOption extends Option
@@ -614,3 +635,23 @@ class BotPlay extends Option
private override function updateDisplay():String
return "BotPlay " + (FlxG.save.data.botplay ? "on" : "off");
}
+
+class CamZoomOption extends Option
+{
+ public function new(desc:String)
+ {
+ super();
+ description = desc;
+ }
+ public override function press():Bool
+ {
+ FlxG.save.data.camzoom = !FlxG.save.data.camzoom;
+ display = updateDisplay();
+ return true;
+ }
+
+ private override function updateDisplay():String
+ {
+ return "Camera Zoom " + (!FlxG.save.data.camzoom ? "off" : "on");
+ }
+}
diff --git a/source/OptionsMenu.hx b/source/OptionsMenu.hx
index 9d690e7..28aa34b 100644
--- a/source/OptionsMenu.hx
+++ b/source/OptionsMenu.hx
@@ -39,15 +39,14 @@ class OptionsMenu extends MusicBeatState
new CustomizeGameplay("Drag'n'Drop Gameplay Modules around to your preference")
]),
new OptionCategory("Appearance", [
- #if desktop
new DistractionsAndEffectsOption("Toggle stage distractions that can hinder your gameplay."),
+ new CamZoomOption("Toggle the camera zoom in-game."),
+ #if desktop
new RainbowFPSOption("Make the FPS Counter Rainbow"),
new AccuracyOption("Display accuracy information."),
new NPSDisplayOption("Shows your current Notes Per Second."),
new SongPositionOption("Show the songs current position (as a bar)"),
new CpuStrums("CPU's strumline lights up when a note hits it."),
- #else
- new DistractionsAndEffectsOption("Toggle stage distractions that can hinder your gameplay.")
#end
]),
@@ -58,7 +57,8 @@ class OptionsMenu extends MusicBeatState
#end
new FlashingLightsOption("Toggle flashing lights that can cause epileptic seizures and strain."),
new WatermarkOption("Enable and disable all watermarks from the engine."),
- new BotPlay("Showcase your charts and mods with autoplay.")
+ new BotPlay("Showcase your charts and mods with autoplay."),
+ new ScoreScreen("Show the score screen after the end of a song")
])
];
@@ -130,14 +130,17 @@ class OptionsMenu extends MusicBeatState
isCat = false;
grpControls.clear();
for (i in 0...options.length)
- {
- var controlLabel:Alphabet = new Alphabet(0, (70 * i) + 30, options[i].getName(), true, false);
- controlLabel.isMenuItem = true;
- controlLabel.targetY = i;
- grpControls.add(controlLabel);
- // DONT PUT X IN THE FIRST PARAMETER OF new ALPHABET() !!
- }
+ {
+ var controlLabel:Alphabet = new Alphabet(0, (70 * i) + 30, options[i].getName(), true, false);
+ controlLabel.isMenuItem = true;
+ controlLabel.targetY = i;
+ grpControls.add(controlLabel);
+ // DONT PUT X IN THE FIRST PARAMETER OF new ALPHABET() !!
+ }
+
curSelected = 0;
+
+ changeSelection(curSelected);
}
if (controls.UP_P)
changeSelection(-1);
@@ -146,7 +149,6 @@ class OptionsMenu extends MusicBeatState
if (isCat)
{
-
if (currentSelectedCat.getOptions()[curSelected].getAccept())
{
if (FlxG.keys.pressed.SHIFT)
@@ -166,7 +168,6 @@ class OptionsMenu extends MusicBeatState
}
else
{
-
if (FlxG.keys.pressed.SHIFT)
{
if (FlxG.keys.justPressed.RIGHT)
@@ -179,7 +180,7 @@ class OptionsMenu extends MusicBeatState
else if (FlxG.keys.pressed.LEFT)
FlxG.save.data.offset -= 0.1;
-
+ versionShit.text = "Offset (Left, Right, Shift for slow): " + HelperFunctions.truncateFloat(FlxG.save.data.offset,2) + " - Description - " + currentDescription;
}
if (currentSelectedCat.getOptions()[curSelected].getAccept())
versionShit.text = currentSelectedCat.getOptions()[curSelected].getValue() + " - Description - " + currentDescription;
@@ -189,16 +190,18 @@ class OptionsMenu extends MusicBeatState
else
{
if (FlxG.keys.pressed.SHIFT)
- {
- if (FlxG.keys.justPressed.RIGHT)
- FlxG.save.data.offset += 0.1;
- else if (FlxG.keys.justPressed.LEFT)
- FlxG.save.data.offset -= 0.1;
- }
- else if (FlxG.keys.pressed.RIGHT)
+ {
+ if (FlxG.keys.justPressed.RIGHT)
FlxG.save.data.offset += 0.1;
- else if (FlxG.keys.pressed.LEFT)
+ else if (FlxG.keys.justPressed.LEFT)
FlxG.save.data.offset -= 0.1;
+ }
+ else if (FlxG.keys.pressed.RIGHT)
+ FlxG.save.data.offset += 0.1;
+ else if (FlxG.keys.pressed.LEFT)
+ FlxG.save.data.offset -= 0.1;
+
+ versionShit.text = "Offset (Left, Right, Shift for slow): " + HelperFunctions.truncateFloat(FlxG.save.data.offset,2) + " - Description - " + currentDescription;
}
@@ -231,6 +234,8 @@ class OptionsMenu extends MusicBeatState
}
curSelected = 0;
}
+
+ changeSelection(curSelected);
}
}
FlxG.save.flush();
diff --git a/source/PauseSubState.hx b/source/PauseSubState.hx
index e59e72b..08cfe98 100644
--- a/source/PauseSubState.hx
+++ b/source/PauseSubState.hx
@@ -33,6 +33,13 @@ class PauseSubState extends MusicBeatSubstate
{
super();
+ if (PlayState.instance.useVideo)
+ {
+ menuItems.remove("Resume");
+ if (GlobalVideo.get().playing)
+ GlobalVideo.get().pause();
+ }
+
pauseMusic = new FlxSound().loadEmbedded(Paths.music('breakfast'), true, true);
pauseMusic.volume = 0;
pauseMusic.play(false, FlxG.random.int(0, Std.int(pauseMusic.length / 2)));
@@ -98,13 +105,23 @@ class PauseSubState extends MusicBeatSubstate
super.update(elapsed);
+ if (PlayState.instance.useVideo)
+ menuItems.remove('Resume');
+
var upP = controls.UP_P;
var downP = controls.DOWN_P;
var leftP = controls.LEFT_P;
var rightP = controls.RIGHT_P;
var accepted = controls.ACCEPT;
var oldOffset:Float = 0;
- var songPath = 'assets/data/' + PlayState.SONG.song.toLowerCase() + '/';
+
+ // pre lowercasing the song name (update)
+ var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase();
+ switch (songLowercase) {
+ case 'dad-battle': songLowercase = 'dadbattle';
+ case 'philly-nice': songLowercase = 'philly';
+ }
+ var songPath = 'assets/data/' + songLowercase + '/';
if (upP)
{
@@ -180,8 +197,20 @@ class PauseSubState extends MusicBeatSubstate
case "Resume":
close();
case "Restart Song":
+ if (PlayState.instance.useVideo)
+ {
+ GlobalVideo.get().stop();
+ PlayState.instance.remove(PlayState.instance.videoSprite);
+ PlayState.instance.removedVideo = true;
+ }
FlxG.resetState();
case "Exit to menu":
+ if (PlayState.instance.useVideo)
+ {
+ GlobalVideo.get().stop();
+ PlayState.instance.remove(PlayState.instance.videoSprite);
+ PlayState.instance.removedVideo = true;
+ }
if(PlayState.loadRep)
{
FlxG.save.data.botplay = false;
diff --git a/source/PlayState.hx b/source/PlayState.hx
index b5107eb..39e8b2b 100644
--- a/source/PlayState.hx
+++ b/source/PlayState.hx
@@ -1,5 +1,6 @@
package;
+import webm.WebmPlayer;
import flixel.input.keyboard.FlxKey;
import haxe.Exception;
import openfl.geom.Matrix;
@@ -75,6 +76,7 @@ class PlayState extends MusicBeatState
public static var storyPlaylist:Array = [];
public static var storyDifficulty:Int = 1;
public static var weekSong:Int = 0;
+ public static var weekScore:Int = 0;
public static var shits:Int = 0;
public static var bads:Int = 0;
public static var goods:Int = 0;
@@ -103,6 +105,8 @@ class PlayState extends MusicBeatState
private var vocals:FlxSound;
+ public var originalX:Float;
+
public static var dad:Character;
public static var gf:Character;
public static var boyfriend:Boyfriend;
@@ -128,7 +132,8 @@ class PlayState extends MusicBeatState
public var health:Float = 1; //making public because sethealth doesnt work without it
private var combo:Int = 0;
public static var misses:Int = 0;
- private var accuracy:Float = 0.00;
+ public static var campaignMisses:Int = 0;
+ public var accuracy:Float = 0.00;
private var accuracyDefault:Float = 0.00;
private var totalNotesHit:Float = 0;
private var totalNotesHitDefault:Float = 0;
@@ -176,7 +181,7 @@ class PlayState extends MusicBeatState
var wiggleShit:WiggleEffect = new WiggleEffect();
var talking:Bool = true;
- var songScore:Int = 0;
+ public var songScore:Int = 0;
var songScoreDef:Int = 0;
var scoreTxt:FlxText;
var replayTxt:FlxText;
@@ -206,7 +211,9 @@ class PlayState extends MusicBeatState
// BotPlay text
private var botPlayState:FlxText;
// Replay shit
- private var saveNotes:Array = [];
+ private var saveNotes:Array = [];
+
+ public static var highestCombo:Int = 0;
private var executeModchart = false;
@@ -226,23 +233,34 @@ class PlayState extends MusicBeatState
if (FlxG.sound.music != null)
FlxG.sound.music.stop();
- sicks = 0;
- bads = 0;
- shits = 0;
- goods = 0;
-
+ if (!isStoryMode)
+ {
+ sicks = 0;
+ bads = 0;
+ shits = 0;
+ goods = 0;
+ }
misses = 0;
repPresses = 0;
repReleases = 0;
+
+ PlayStateChangeables.useDownscroll = FlxG.save.data.downscroll;
+ PlayStateChangeables.safeFrames = FlxG.save.data.frames;
+ PlayStateChangeables.scrollSpeed = FlxG.save.data.scrollSpeed;
+ PlayStateChangeables.botPlay = FlxG.save.data.botplay;
+
+
// pre lowercasing the song name (create)
var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase();
- switch (songLowercase) {
- case 'dad-battle': songLowercase = 'dadbattle';
- case 'philly-nice': songLowercase = 'philly';
- }
+ switch (songLowercase) {
+ case 'dad-battle': songLowercase = 'dadbattle';
+ case 'philly-nice': songLowercase = 'philly';
+ }
+ removedVideo = false;
+
#if windows
executeModchart = FileSystem.exists(Paths.lua(songLowercase + "/modchart"));
#end
@@ -309,12 +327,12 @@ class PlayState extends MusicBeatState
persistentDraw = true;
if (SONG == null)
- SONG = Song.loadFromJson('tutorial');
+ SONG = Song.loadFromJson('tutorial', 'tutorial');
Conductor.mapBPMChanges(SONG);
Conductor.changeBPM(SONG.bpm);
- trace('INFORMATION ABOUT WHAT U PLAYIN WIT:\nFRAMES: ' + Conductor.safeFrames + '\nZONE: ' + Conductor.safeZoneOffset + '\nTS: ' + Conductor.timeScale + '\nBotPlay : ' + FlxG.save.data.botplay);
+ trace('INFORMATION ABOUT WHAT U PLAYIN WIT:\nFRAMES: ' + PlayStateChangeables.safeFrames + '\nZONE: ' + Conductor.safeZoneOffset + '\nTS: ' + Conductor.timeScale + '\nBotPlay : ' + PlayStateChangeables.botPlay);
//dialogue shit
switch (songLowercase)
@@ -344,7 +362,22 @@ class PlayState extends MusicBeatState
dialogue = CoolUtil.coolTextFile(Paths.txt('thorns/thornsDialogue'));
}
- switch(SONG.stage)
+ //defaults if no stage was found in chart
+ var stageCheck:String = 'stage';
+
+ if (SONG.stage == null) {
+ switch(storyWeek)
+ {
+ case 2: stageCheck = 'halloween';
+ case 3: stageCheck = 'philly';
+ case 4: stageCheck = 'limo';
+ case 5: if (songLowercase == 'winter-horrorland') {stageCheck = 'mallEvil';} else {stageCheck = 'mall';}
+ case 6: if (songLowercase == 'thorns') {stageCheck = 'schoolEvil';} else {stageCheck = 'school';}
+ //i should check if its stage (but this is when none is found in chart anyway)
+ }
+ } else {stageCheck = SONG.stage;}
+
+ switch(stageCheck)
{
case 'halloween':
{
@@ -723,21 +756,33 @@ class PlayState extends MusicBeatState
add(stageCurtains);
}
}
- var gfVersion:String = 'gf';
- switch (SONG.gfVersion)
+ //defaults if no gf was found in chart
+ var gfCheck:String = 'gf';
+
+ if (SONG.gfVersion == null) {
+ switch(storyWeek)
+ {
+ case 4: gfCheck = 'gf-car';
+ case 5: gfCheck = 'gf-christmas';
+ case 6: gfCheck = 'gf-pixel';
+ }
+ } else {gfCheck = SONG.gfVersion;}
+
+ var curGf:String = '';
+ switch (gfCheck)
{
case 'gf-car':
- gfVersion = 'gf-car';
+ curGf = 'gf-car';
case 'gf-christmas':
- gfVersion = 'gf-christmas';
+ curGf = 'gf-christmas';
case 'gf-pixel':
- gfVersion = 'gf-pixel';
+ curGf = 'gf-pixel';
default:
- gfVersion = 'gf';
+ curGf = 'gf';
}
- gf = new Character(400, 130, gfVersion);
+ gf = new Character(400, 130, curGf);
gf.scrollFactor.set(0.95, 0.95);
dad = new Character(100, 100, SONG.player2);
@@ -837,13 +882,17 @@ class PlayState extends MusicBeatState
{
FlxG.watch.addQuick('rep rpesses',repPresses);
FlxG.watch.addQuick('rep releases',repReleases);
-
- FlxG.save.data.botplay = true;
- FlxG.save.data.scrollSpeed = rep.replay.noteSpeed;
- FlxG.save.data.downscroll = rep.replay.isDownscroll;
// FlxG.watch.addQuick('Queued',inputsQueued);
+
+ PlayStateChangeables.useDownscroll = rep.replay.isDownscroll;
+ PlayStateChangeables.safeFrames = rep.replay.sf;
+ PlayStateChangeables.botPlay = true;
}
+ trace('uh ' + PlayStateChangeables.safeFrames);
+
+ trace("SF CALC: " + Math.floor((PlayStateChangeables.safeFrames / 60) * 1000));
+
var doof:DialogueBox = new DialogueBox(false, dialogue);
// doof.x += 70;
// doof.y = FlxG.height * 0.5;
@@ -855,7 +904,7 @@ class PlayState extends MusicBeatState
strumLine = new FlxSprite(0, 50).makeGraphic(FlxG.width, 10);
strumLine.scrollFactor.set();
- if (FlxG.save.data.downscroll)
+ if (PlayStateChangeables.useDownscroll)
strumLine.y = FlxG.height - 165;
strumLineNotes = new FlxTypedGroup();
@@ -901,7 +950,7 @@ class PlayState extends MusicBeatState
if (FlxG.save.data.songPosition) // I dont wanna talk about this code :(
{
songPosBG = new FlxSprite(0, 10).loadGraphic(Paths.image('healthBar'));
- if (FlxG.save.data.downscroll)
+ if (PlayStateChangeables.useDownscroll)
songPosBG.y = FlxG.height * 0.9 + 45;
songPosBG.screenCenter(X);
songPosBG.scrollFactor.set();
@@ -914,7 +963,7 @@ class PlayState extends MusicBeatState
add(songPosBar);
var songName = new FlxText(songPosBG.x + (songPosBG.width / 2) - 20,songPosBG.y,0,SONG.song, 16);
- if (FlxG.save.data.downscroll)
+ if (PlayStateChangeables.useDownscroll)
songName.y -= 3;
songName.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK);
songName.scrollFactor.set();
@@ -923,7 +972,7 @@ class PlayState extends MusicBeatState
}
healthBarBG = new FlxSprite(0, FlxG.height * 0.9).loadGraphic(Paths.image('healthBar'));
- if (FlxG.save.data.downscroll)
+ if (PlayStateChangeables.useDownscroll)
healthBarBG.y = 50;
healthBarBG.screenCenter(X);
healthBarBG.scrollFactor.set();
@@ -942,32 +991,38 @@ class PlayState extends MusicBeatState
kadeEngineWatermark.scrollFactor.set();
add(kadeEngineWatermark);
- if (FlxG.save.data.downscroll)
+ if (PlayStateChangeables.useDownscroll)
kadeEngineWatermark.y = FlxG.height * 0.9 + 45;
scoreTxt = new FlxText(FlxG.width / 2 - 235, healthBarBG.y + 50, 0, "", 20);
- if (!FlxG.save.data.accuracyDisplay)
- scoreTxt.x = healthBarBG.x + healthBarBG.width / 2;
- scoreTxt.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK);
+
+ scoreTxt.screenCenter(X);
+
+ originalX = scoreTxt.x;
+
+
scoreTxt.scrollFactor.set();
- if (offsetTesting)
- scoreTxt.x += 300;
- if(FlxG.save.data.botplay) scoreTxt.x = FlxG.width / 2 - 20;
+
+ scoreTxt.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, FlxTextAlign.CENTER, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK);
+
add(scoreTxt);
- replayTxt = new FlxText(healthBarBG.x + healthBarBG.width / 2 - 75, healthBarBG.y + (FlxG.save.data.downscroll ? 100 : -100), 0, "REPLAY", 20);
+ replayTxt = new FlxText(healthBarBG.x + healthBarBG.width / 2 - 75, healthBarBG.y + (PlayStateChangeables.useDownscroll ? 100 : -100), 0, "REPLAY", 20);
replayTxt.setFormat(Paths.font("vcr.ttf"), 42, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK);
+ replayTxt.borderSize = 4;
+ replayTxt.borderQuality = 2;
replayTxt.scrollFactor.set();
if (loadRep)
{
add(replayTxt);
}
// Literally copy-paste of the above, fu
- botPlayState = new FlxText(healthBarBG.x + healthBarBG.width / 2 - 75, healthBarBG.y + (FlxG.save.data.downscroll ? 100 : -100), 0, "BOTPLAY", 20);
+ botPlayState = new FlxText(healthBarBG.x + healthBarBG.width / 2 - 75, healthBarBG.y + (PlayStateChangeables.useDownscroll ? 100 : -100), 0, "BOTPLAY", 20);
botPlayState.setFormat(Paths.font("vcr.ttf"), 42, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK);
botPlayState.scrollFactor.set();
-
- if(FlxG.save.data.botplay && !loadRep) add(botPlayState);
+ botPlayState.borderSize = 4;
+ botPlayState.borderQuality = 2;
+ if(PlayStateChangeables.botPlay && !loadRep) add(botPlayState);
iconP1 = new HealthIcon(SONG.player1, true);
iconP1.y = healthBar.y - (iconP1.height / 2);
@@ -1078,17 +1133,11 @@ class PlayState extends MusicBeatState
senpaiEvil.updateHitbox();
senpaiEvil.screenCenter();
- // pre lowercasing the song name (schoolIntro)
- var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase();
- switch (songLowercase) {
- case 'dad-battle': songLowercase = 'dadbattle';
- case 'philly-nice': songLowercase = 'philly';
- }
- if (songLowercase == 'roses' || songLowercase == 'thorns')
+ if (StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase() == 'roses' || StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase() == 'thorns')
{
remove(black);
- if (songLowercase == 'thorns')
+ if (StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase() == 'thorns')
{
add(red);
}
@@ -1108,7 +1157,7 @@ class PlayState extends MusicBeatState
{
inCutscene = true;
- if (songLowercase == 'thorns')
+ if (StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase() == 'thorns')
{
add(senpaiEvil);
senpaiEvil.alpha = 0;
@@ -1169,10 +1218,16 @@ class PlayState extends MusicBeatState
#if windows
+ // pre lowercasing the song name (startCountdown)
+ var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase();
+ switch (songLowercase) {
+ case 'dad-battle': songLowercase = 'dadbattle';
+ case 'philly-nice': songLowercase = 'philly';
+ }
if (executeModchart)
{
luaModchart = ModchartState.createModchartState();
- luaModchart.executeState('start',[PlayState.SONG.song]);
+ luaModchart.executeState('start',[songLowercase]);
}
#end
@@ -1313,7 +1368,7 @@ class PlayState extends MusicBeatState
remove(songName);
songPosBG = new FlxSprite(0, 10).loadGraphic(Paths.image('healthBar'));
- if (FlxG.save.data.downscroll)
+ if (PlayStateChangeables.useDownscroll)
songPosBG.y = FlxG.height * 0.9 + 45;
songPosBG.screenCenter(X);
songPosBG.scrollFactor.set();
@@ -1327,7 +1382,7 @@ class PlayState extends MusicBeatState
add(songPosBar);
var songName = new FlxText(songPosBG.x + (songPosBG.width / 2) - 20,songPosBG.y,0,SONG.song, 16);
- if (FlxG.save.data.downscroll)
+ if (PlayStateChangeables.useDownscroll)
songName.y -= 3;
songName.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE,FlxColor.BLACK);
songName.scrollFactor.set();
@@ -1344,6 +1399,9 @@ class PlayState extends MusicBeatState
case 'Bopeebo' | 'Philly Nice' | 'Blammed' | 'Cocoa' | 'Eggnog': allowedToHeadbang = true;
default: allowedToHeadbang = false;
}
+
+ if (useVideo)
+ GlobalVideo.get().resume();
#if windows
// Updating Discord Rich Presence (with Time Left)
@@ -1381,14 +1439,15 @@ class PlayState extends MusicBeatState
var playerCounter:Int = 0;
- // pre lowercasing the song name (generateSong)
- var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase();
- switch (songLowercase) {
- case 'dad-battle': songLowercase = 'dadbattle';
- case 'philly-nice': songLowercase = 'philly';
- }
// Per song offset check
#if windows
+ // pre lowercasing the song name (generateSong)
+ var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase();
+ switch (songLowercase) {
+ case 'dad-battle': songLowercase = 'dadbattle';
+ case 'philly-nice': songLowercase = 'philly';
+ }
+
var songPath = 'assets/data/' + songLowercase + '/';
for(file in sys.FileSystem.readDirectory(songPath))
@@ -1491,7 +1550,14 @@ class PlayState extends MusicBeatState
// FlxG.log.add(i);
var babyArrow:FlxSprite = new FlxSprite(0, strumLine.y);
- switch (SONG.noteStyle)
+ //defaults if no noteStyle was found in chart
+ var noteTypeCheck:String = 'normal';
+
+ if (SONG.noteStyle == null) {
+ switch(storyWeek) {case 6: noteTypeCheck = 'pixel';}
+ } else {noteTypeCheck = SONG.noteStyle;}
+
+ switch (noteTypeCheck)
{
case 'pixel':
babyArrow.loadGraphic(Paths.image('weeb/pixelUI/arrows-pixels'), true, 17, 17);
@@ -1506,16 +1572,6 @@ class PlayState extends MusicBeatState
switch (Math.abs(i))
{
- case 0:
- babyArrow.x += Note.swagWidth * 0;
- babyArrow.animation.add('static', [0]);
- babyArrow.animation.add('pressed', [4, 8], 12, false);
- babyArrow.animation.add('confirm', [12, 16], 24, false);
- case 1:
- babyArrow.x += Note.swagWidth * 1;
- babyArrow.animation.add('static', [1]);
- babyArrow.animation.add('pressed', [5, 9], 12, false);
- babyArrow.animation.add('confirm', [13, 17], 24, false);
case 2:
babyArrow.x += Note.swagWidth * 2;
babyArrow.animation.add('static', [2]);
@@ -1526,75 +1582,85 @@ class PlayState extends MusicBeatState
babyArrow.animation.add('static', [3]);
babyArrow.animation.add('pressed', [7, 11], 12, false);
babyArrow.animation.add('confirm', [15, 19], 24, false);
+ case 1:
+ babyArrow.x += Note.swagWidth * 1;
+ babyArrow.animation.add('static', [1]);
+ babyArrow.animation.add('pressed', [5, 9], 12, false);
+ babyArrow.animation.add('confirm', [13, 17], 24, false);
+ case 0:
+ babyArrow.x += Note.swagWidth * 0;
+ babyArrow.animation.add('static', [0]);
+ babyArrow.animation.add('pressed', [4, 8], 12, false);
+ babyArrow.animation.add('confirm', [12, 16], 24, false);
}
- case 'normal':
- babyArrow.frames = Paths.getSparrowAtlas('NOTE_assets');
- babyArrow.animation.addByPrefix('green', 'arrowUP');
- babyArrow.animation.addByPrefix('blue', 'arrowDOWN');
- babyArrow.animation.addByPrefix('purple', 'arrowLEFT');
- babyArrow.animation.addByPrefix('red', 'arrowRIGHT');
+ case 'normal':
+ babyArrow.frames = Paths.getSparrowAtlas('NOTE_assets');
+ babyArrow.animation.addByPrefix('green', 'arrowUP');
+ babyArrow.animation.addByPrefix('blue', 'arrowDOWN');
+ babyArrow.animation.addByPrefix('purple', 'arrowLEFT');
+ babyArrow.animation.addByPrefix('red', 'arrowRIGHT');
+
+ babyArrow.antialiasing = true;
+ babyArrow.setGraphicSize(Std.int(babyArrow.width * 0.7));
+
+ switch (Math.abs(i))
+ {
+ case 0:
+ babyArrow.x += Note.swagWidth * 0;
+ babyArrow.animation.addByPrefix('static', 'arrowLEFT');
+ babyArrow.animation.addByPrefix('pressed', 'left press', 24, false);
+ babyArrow.animation.addByPrefix('confirm', 'left confirm', 24, false);
+ case 1:
+ babyArrow.x += Note.swagWidth * 1;
+ babyArrow.animation.addByPrefix('static', 'arrowDOWN');
+ babyArrow.animation.addByPrefix('pressed', 'down press', 24, false);
+ babyArrow.animation.addByPrefix('confirm', 'down confirm', 24, false);
+ case 2:
+ babyArrow.x += Note.swagWidth * 2;
+ babyArrow.animation.addByPrefix('static', 'arrowUP');
+ babyArrow.animation.addByPrefix('pressed', 'up press', 24, false);
+ babyArrow.animation.addByPrefix('confirm', 'up confirm', 24, false);
+ case 3:
+ babyArrow.x += Note.swagWidth * 3;
+ babyArrow.animation.addByPrefix('static', 'arrowRIGHT');
+ babyArrow.animation.addByPrefix('pressed', 'right press', 24, false);
+ babyArrow.animation.addByPrefix('confirm', 'right confirm', 24, false);
+ }
- babyArrow.antialiasing = true;
- babyArrow.setGraphicSize(Std.int(babyArrow.width * 0.7));
+ default:
+ babyArrow.frames = Paths.getSparrowAtlas('NOTE_assets');
+ babyArrow.animation.addByPrefix('green', 'arrowUP');
+ babyArrow.animation.addByPrefix('blue', 'arrowDOWN');
+ babyArrow.animation.addByPrefix('purple', 'arrowLEFT');
+ babyArrow.animation.addByPrefix('red', 'arrowRIGHT');
- switch (Math.abs(i))
- {
- case 0:
- babyArrow.x += Note.swagWidth * 0;
- babyArrow.animation.addByPrefix('static', 'arrowLEFT');
- babyArrow.animation.addByPrefix('pressed', 'left press', 24, false);
- babyArrow.animation.addByPrefix('confirm', 'left confirm', 24, false);
- case 1:
- babyArrow.x += Note.swagWidth * 1;
- babyArrow.animation.addByPrefix('static', 'arrowDOWN');
- babyArrow.animation.addByPrefix('pressed', 'down press', 24, false);
- babyArrow.animation.addByPrefix('confirm', 'down confirm', 24, false);
- case 2:
- babyArrow.x += Note.swagWidth * 2;
- babyArrow.animation.addByPrefix('static', 'arrowUP');
- babyArrow.animation.addByPrefix('pressed', 'up press', 24, false);
- babyArrow.animation.addByPrefix('confirm', 'up confirm', 24, false);
- case 3:
- babyArrow.x += Note.swagWidth * 3;
- babyArrow.animation.addByPrefix('static', 'arrowRIGHT');
- babyArrow.animation.addByPrefix('pressed', 'right press', 24, false);
- babyArrow.animation.addByPrefix('confirm', 'right confirm', 24, false);
+ babyArrow.antialiasing = true;
+ babyArrow.setGraphicSize(Std.int(babyArrow.width * 0.7));
+
+ switch (Math.abs(i))
+ {
+ case 0:
+ babyArrow.x += Note.swagWidth * 0;
+ babyArrow.animation.addByPrefix('static', 'arrowLEFT');
+ babyArrow.animation.addByPrefix('pressed', 'left press', 24, false);
+ babyArrow.animation.addByPrefix('confirm', 'left confirm', 24, false);
+ case 1:
+ babyArrow.x += Note.swagWidth * 1;
+ babyArrow.animation.addByPrefix('static', 'arrowDOWN');
+ babyArrow.animation.addByPrefix('pressed', 'down press', 24, false);
+ babyArrow.animation.addByPrefix('confirm', 'down confirm', 24, false);
+ case 2:
+ babyArrow.x += Note.swagWidth * 2;
+ babyArrow.animation.addByPrefix('static', 'arrowUP');
+ babyArrow.animation.addByPrefix('pressed', 'up press', 24, false);
+ babyArrow.animation.addByPrefix('confirm', 'up confirm', 24, false);
+ case 3:
+ babyArrow.x += Note.swagWidth * 3;
+ babyArrow.animation.addByPrefix('static', 'arrowRIGHT');
+ babyArrow.animation.addByPrefix('pressed', 'right press', 24, false);
+ babyArrow.animation.addByPrefix('confirm', 'right confirm', 24, false);
}
-
- default:
- babyArrow.frames = Paths.getSparrowAtlas('NOTE_assets');
- babyArrow.animation.addByPrefix('green', 'arrowUP');
- babyArrow.animation.addByPrefix('blue', 'arrowDOWN');
- babyArrow.animation.addByPrefix('purple', 'arrowLEFT');
- babyArrow.animation.addByPrefix('red', 'arrowRIGHT');
-
- babyArrow.antialiasing = true;
- babyArrow.setGraphicSize(Std.int(babyArrow.width * 0.7));
-
- switch (Math.abs(i))
- {
- case 0:
- babyArrow.x += Note.swagWidth * 0;
- babyArrow.animation.addByPrefix('static', 'arrowLEFT');
- babyArrow.animation.addByPrefix('pressed', 'left press', 24, false);
- babyArrow.animation.addByPrefix('confirm', 'left confirm', 24, false);
- case 1:
- babyArrow.x += Note.swagWidth * 1;
- babyArrow.animation.addByPrefix('static', 'arrowDOWN');
- babyArrow.animation.addByPrefix('pressed', 'down press', 24, false);
- babyArrow.animation.addByPrefix('confirm', 'down confirm', 24, false);
- case 2:
- babyArrow.x += Note.swagWidth * 2;
- babyArrow.animation.addByPrefix('static', 'arrowUP');
- babyArrow.animation.addByPrefix('pressed', 'up press', 24, false);
- babyArrow.animation.addByPrefix('confirm', 'up confirm', 24, false);
- case 3:
- babyArrow.x += Note.swagWidth * 3;
- babyArrow.animation.addByPrefix('static', 'arrowRIGHT');
- babyArrow.animation.addByPrefix('pressed', 'right press', 24, false);
- babyArrow.animation.addByPrefix('confirm', 'right confirm', 24, false);
- }
}
babyArrow.updateHitbox();
@@ -1706,15 +1772,32 @@ class PlayState extends MusicBeatState
public static var songRate = 1.5;
+ public var stopUpdate = false;
+ public var removedVideo = false;
+
override public function update(elapsed:Float)
{
#if !debug
perfectMode = false;
#end
- if (FlxG.save.data.botplay && FlxG.keys.justPressed.ONE)
+ if (PlayStateChangeables.botPlay && FlxG.keys.justPressed.ONE)
camHUD.visible = !camHUD.visible;
+
+ if (useVideo && GlobalVideo.get() != null && !stopUpdate)
+ {
+ if (GlobalVideo.get().ended && !removedVideo)
+ {
+ remove(videoSprite);
+ FlxG.stage.window.onFocusOut.remove(focusOut);
+ FlxG.stage.window.onFocusIn.remove(focusIn);
+ removedVideo = true;
+ }
+ }
+
+
+
#if windows
if (executeModchart && luaModchart != null && songStarted)
{
@@ -1817,8 +1900,10 @@ class PlayState extends MusicBeatState
super.update(elapsed);
scoreTxt.text = Ratings.CalculateRanking(songScore,songScoreDef,nps,maxNPS,accuracy);
- if (!FlxG.save.data.accuracyDisplay)
- scoreTxt.text = "Score: " + songScore;
+
+ var lengthInPx = scoreTxt.textField.length * scoreTxt.frameHeight; // bad way but does more or less a better job
+
+ scoreTxt.x = (originalX - (lengthInPx / 2)) + 335;
if (FlxG.keys.justPressed.ENTER && startedCountdown && canPause)
{
@@ -1838,6 +1923,14 @@ class PlayState extends MusicBeatState
if (FlxG.keys.justPressed.SEVEN)
{
+ if (useVideo)
+ {
+ GlobalVideo.get().stop();
+ remove(videoSprite);
+ FlxG.stage.window.onFocusOut.remove(focusOut);
+ FlxG.stage.window.onFocusIn.remove(focusIn);
+ removedVideo = true;
+ }
#if windows
DiscordClient.changePresence("Chart Editor", null, null, true);
#end
@@ -1883,6 +1976,15 @@ class PlayState extends MusicBeatState
#if debug
if (FlxG.keys.justPressed.EIGHT)
{
+ if (useVideo)
+ {
+ GlobalVideo.get().stop();
+ remove(videoSprite);
+ FlxG.stage.window.onFocusOut.remove(focusOut);
+ FlxG.stage.window.onFocusIn.remove(focusIn);
+ removedVideo = true;
+ }
+
FlxG.switchState(new AnimationDebug(SONG.player2));
#if windows
if (luaModchart != null)
@@ -2230,12 +2332,12 @@ class PlayState extends MusicBeatState
if (!daNote.modifiedByLua)
{
- if (FlxG.save.data.downscroll)
+ if (PlayStateChangeables.useDownscroll)
{
if (daNote.mustPress)
- daNote.y = (playerStrums.members[Math.floor(Math.abs(daNote.noteData))].y + 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(FlxG.save.data.scrollSpeed == 1 ? SONG.speed : FlxG.save.data.scrollSpeed, 2));
+ daNote.y = (playerStrums.members[Math.floor(Math.abs(daNote.noteData))].y + 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed, 2));
else
- daNote.y = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y + 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(FlxG.save.data.scrollSpeed == 1 ? SONG.speed : FlxG.save.data.scrollSpeed, 2));
+ daNote.y = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y + 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed, 2));
if(daNote.isSustainNote)
{
// Remember = minus makes notes go up, plus makes them go down
@@ -2245,7 +2347,7 @@ class PlayState extends MusicBeatState
daNote.y += daNote.height / 2;
// If not in botplay, only clip sustain notes when properly hit, botplay gets to clip it everytime
- if(!FlxG.save.data.botplay)
+ if(!PlayStateChangeables.botPlay)
{
if((!daNote.mustPress || daNote.wasGoodHit || daNote.prevNote.wasGoodHit && !daNote.canBeHit) && daNote.y - daNote.offset.y * daNote.scale.y + daNote.height >= (strumLine.y + Note.swagWidth / 2))
{
@@ -2267,14 +2369,14 @@ class PlayState extends MusicBeatState
}else
{
if (daNote.mustPress)
- daNote.y = (playerStrums.members[Math.floor(Math.abs(daNote.noteData))].y - 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(FlxG.save.data.scrollSpeed == 1 ? SONG.speed : FlxG.save.data.scrollSpeed, 2));
+ daNote.y = (playerStrums.members[Math.floor(Math.abs(daNote.noteData))].y - 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed, 2));
else
- daNote.y = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y - 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(FlxG.save.data.scrollSpeed == 1 ? SONG.speed : FlxG.save.data.scrollSpeed, 2));
+ daNote.y = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y - 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed, 2));
if(daNote.isSustainNote)
{
daNote.y -= daNote.height / 2;
- if(!FlxG.save.data.botplay)
+ if(!PlayStateChangeables.botPlay)
{
if((!daNote.mustPress || daNote.wasGoodHit || daNote.prevNote.wasGoodHit && !daNote.canBeHit) && daNote.y + daNote.offset.y * daNote.scale.y <= (strumLine.y + Note.swagWidth / 2))
{
@@ -2386,7 +2488,7 @@ class PlayState extends MusicBeatState
// WIP interpolation shit? Need to fix the pause issue
// daNote.y = (strumLine.y - (songTime - daNote.strumTime) * (0.45 * PlayState.SONG.speed));
- if ((daNote.mustPress && daNote.tooLate && !FlxG.save.data.downscroll || daNote.mustPress && daNote.tooLate && FlxG.save.data.downscroll) && daNote.mustPress)
+ if ((daNote.mustPress && daNote.tooLate && !PlayStateChangeables.useDownscroll || daNote.mustPress && daNote.tooLate && PlayStateChangeables.useDownscroll) && daNote.mustPress)
{
if (daNote.isSustainNote && daNote.wasGoodHit)
{
@@ -2395,10 +2497,26 @@ class PlayState extends MusicBeatState
}
else
{
- health -= 0.075;
- vocals.volume = 0;
- if (theFunne)
- noteMiss(daNote.noteData, daNote);
+ if (loadRep && daNote.isSustainNote)
+ {
+ // im tired and lazy this sucks I know i'm dumb
+ if (findByTime(daNote.strumTime) != null)
+ totalNotesHit += 1;
+ else
+ {
+ health -= 0.075;
+ vocals.volume = 0;
+ if (theFunne)
+ noteMiss(daNote.noteData, daNote);
+ }
+ }
+ else
+ {
+ health -= 0.075;
+ vocals.volume = 0;
+ if (theFunne)
+ noteMiss(daNote.noteData, daNote);
+ }
}
daNote.visible = false;
@@ -2433,13 +2551,24 @@ class PlayState extends MusicBeatState
function endSong():Void
{
+ if (useVideo)
+ {
+ GlobalVideo.get().stop();
+ FlxG.stage.window.onFocusOut.remove(focusOut);
+ FlxG.stage.window.onFocusIn.remove(focusIn);
+ PlayState.instance.remove(PlayState.instance.videoSprite);
+ }
+
+ if (isStoryMode)
+ campaignMisses = misses;
+
if (!loadRep)
rep.SaveReplay(saveNotes);
else
{
- FlxG.save.data.botplay = false;
- FlxG.save.data.scrollSpeed = 1;
- FlxG.save.data.downscroll = false;
+ PlayStateChangeables.botPlay = false;
+ PlayStateChangeables.scrollSpeed = 1;
+ PlayStateChangeables.useDownscroll = false;
}
if (FlxG.save.data.fpsCap > 290)
@@ -2456,6 +2585,8 @@ class PlayState extends MusicBeatState
canPause = false;
FlxG.sound.music.volume = 0;
vocals.volume = 0;
+ FlxG.sound.music.pause();
+ vocals.pause();
if (SONG.validScore)
{
// adjusting the highscore song name to be compatible
@@ -2468,6 +2599,7 @@ class PlayState extends MusicBeatState
#if !switch
Highscore.saveScore(songHighscore, Math.round(songScore), storyDifficulty);
+ Highscore.saveCombo(songHighscore, Ratings.GenerateLetterRank(accuracy), storyDifficulty);
#end
}
@@ -2488,12 +2620,20 @@ class PlayState extends MusicBeatState
if (storyPlaylist.length <= 0)
{
- FlxG.sound.playMusic(Paths.music('freakyMenu'));
-
transIn = FlxTransitionableState.defaultTransIn;
transOut = FlxTransitionableState.defaultTransOut;
- FlxG.switchState(new StoryMenuState());
+ paused = true;
+
+ FlxG.sound.music.stop();
+ vocals.stop();
+ if (FlxG.save.data.scoreScreen)
+ openSubState(new ResultsScreen());
+ else
+ {
+ FlxG.sound.playMusic(Paths.music('freakyMenu'));
+ FlxG.switchState(new MainMenuState());
+ }
#if windows
if (luaModchart != null)
@@ -2517,30 +2657,20 @@ class PlayState extends MusicBeatState
}
else
{
- var difficulty:String = "";
+
+ // adjusting the song name to be compatible
+ var songFormat = StringTools.replace(PlayState.storyPlaylist[0], " ", "-");
+ switch (songFormat) {
+ case 'Dad-Battle': songFormat = 'Dadbattle';
+ case 'Philly-Nice': songFormat = 'Philly';
+ }
- if (storyDifficulty == 0)
- difficulty = '-easy';
-
- if (storyDifficulty == 2)
- difficulty = '-hard';
+ var poop:String = Highscore.formatSong(songFormat, storyDifficulty);
trace('LOADING NEXT SONG');
- // pre lowercasing the next story song name
- var nextSongLowercase = StringTools.replace(PlayState.storyPlaylist[0], " ", "-").toLowerCase();
- switch (nextSongLowercase) {
- case 'dad-battle': nextSongLowercase = 'dadbattle';
- case 'philly-nice': nextSongLowercase = 'philly';
- }
- trace(nextSongLowercase + difficulty);
+ trace(poop);
- // pre lowercasing the song name (endSong)
- var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase();
- switch (songLowercase) {
- case 'dad-battle': songLowercase = 'dadbattle';
- case 'philly-nice': songLowercase = 'philly';
- }
- if (songLowercase == 'eggnog')
+ if (StringTools.replace(PlayState.storyPlaylist[0], " ", "-").toLowerCase() == 'eggnog')
{
var blackShit:FlxSprite = new FlxSprite(-FlxG.width * FlxG.camera.zoom,
-FlxG.height * FlxG.camera.zoom).makeGraphic(FlxG.width * 3, FlxG.height * 3, FlxColor.BLACK);
@@ -2555,7 +2685,8 @@ class PlayState extends MusicBeatState
FlxTransitionableState.skipNextTransOut = true;
prevCamFollow = camFollow;
- PlayState.SONG = Song.loadFromJson(nextSongLowercase + difficulty, PlayState.storyPlaylist[0]);
+
+ PlayState.SONG = Song.loadFromJson(poop, PlayState.storyPlaylist[0]);
FlxG.sound.music.stop();
LoadingState.loadAndSwitchState(new PlayState());
@@ -2564,7 +2695,17 @@ class PlayState extends MusicBeatState
else
{
trace('WENT BACK TO FREEPLAY??');
- FlxG.switchState(new FreeplayState());
+
+ paused = true;
+
+
+ FlxG.sound.music.stop();
+ vocals.stop();
+
+ if (FlxG.save.data.scoreScreen)
+ openSubState(new ResultsScreen());
+ else
+ FlxG.switchState(new PlayState());
}
}
}
@@ -2580,11 +2721,10 @@ class PlayState extends MusicBeatState
private function popUpScore(daNote:Note):Void
{
- var noteDiff:Float = Math.abs(Conductor.songPosition - daNote.strumTime);
- var wife:Float = EtternaFunctions.wife3(noteDiff, Conductor.timeScale);
+ var noteDiff:Float = -(daNote.strumTime - Conductor.songPosition);
+ var wife:Float = EtternaFunctions.wife3(-noteDiff, Conductor.timeScale);
// boyfriend.playAnim('hey');
vocals.volume = 1;
-
var placement:String = Std.string(combo);
var coolText:FlxText = new FlxText(0, 0, 0, placement, 32);
@@ -2679,7 +2819,10 @@ class PlayState extends MusicBeatState
rating.velocity.x -= FlxG.random.int(0, 10);
var msTiming = HelperFunctions.truncateFloat(noteDiff, 3);
- if(FlxG.save.data.botplay) msTiming = 0;
+ if(PlayStateChangeables.botPlay && !loadRep) msTiming = 0;
+
+ if (loadRep)
+ msTiming = HelperFunctions.truncateFloat(findByTime(daNote.strumTime)[3], 3);
if (currentTimingShown != null)
remove(currentTimingShown);
@@ -2725,7 +2868,7 @@ class PlayState extends MusicBeatState
if (currentTimingShown.alpha != 1)
currentTimingShown.alpha = 1;
- if(!FlxG.save.data.botplay) add(currentTimingShown);
+ if(!PlayStateChangeables.botPlay || loadRep) add(currentTimingShown);
var comboSpr:FlxSprite = new FlxSprite().loadGraphic(Paths.image(pixelShitPart1 + 'combo' + pixelShitPart2));
comboSpr.screenCenter();
@@ -2742,7 +2885,7 @@ class PlayState extends MusicBeatState
comboSpr.velocity.x += FlxG.random.int(1, 10);
currentTimingShown.velocity.x += comboSpr.velocity.x;
- if(!FlxG.save.data.botplay) add(rating);
+ if(!PlayStateChangeables.botPlay || loadRep) add(rating);
if (!curStage.startsWith('school'))
{
@@ -2769,6 +2912,9 @@ class PlayState extends MusicBeatState
var comboSplit:Array = (combo + "").split('');
+ if (combo > highestCombo)
+ highestCombo = combo;
+
// make sure we have 3 digits to display (looks weird otherwise lol)
if (comboSplit.length == 1)
{
@@ -2893,7 +3039,7 @@ class PlayState extends MusicBeatState
#end
// Prevent player input if botplay is on
- if(FlxG.save.data.botplay)
+ if(PlayStateChangeables.botPlay)
{
holdArray = [false, false, false, false];
pressArray = [false, false, false, false];
@@ -2953,8 +3099,6 @@ class PlayState extends MusicBeatState
}
});
- trace('\nCURRENT LINE:\n' + directionsAccounted);
-
for (note in dumbNotes)
{
FlxG.log.add("killing dumb ass note at " + note.strumTime);
@@ -3003,7 +3147,7 @@ class PlayState extends MusicBeatState
noteMiss(shit, null);
}
- if(dontCheck && possibleNotes.length > 0 && FlxG.save.data.ghost && !FlxG.save.data.botplay)
+ if(dontCheck && possibleNotes.length > 0 && FlxG.save.data.ghost && !PlayStateChangeables.botPlay)
{
if (mashViolations > 8)
{
@@ -3019,17 +3163,19 @@ class PlayState extends MusicBeatState
notes.forEachAlive(function(daNote:Note)
{
- if(FlxG.save.data.downscroll && daNote.y > strumLine.y ||
- !FlxG.save.data.downscroll && daNote.y < strumLine.y)
+ if(PlayStateChangeables.useDownscroll && daNote.y > strumLine.y ||
+ !PlayStateChangeables.useDownscroll && daNote.y < strumLine.y)
{
// Force good note hit regardless if it's too late to hit it or not as a fail safe
- if(FlxG.save.data.botplay && daNote.canBeHit && daNote.mustPress ||
- FlxG.save.data.botplay && daNote.tooLate && daNote.mustPress)
+ if(PlayStateChangeables.botPlay && daNote.canBeHit && daNote.mustPress ||
+ PlayStateChangeables.botPlay && daNote.tooLate && daNote.mustPress)
{
if(loadRep)
{
//trace('ReplayNote ' + tmpRepNote.strumtime + ' | ' + tmpRepNote.direction);
- if(rep.replay.songNotes.contains(HelperFunctions.truncateFloat(daNote.strumTime, 2)))
+ var n = findByTime(daNote.strumTime);
+ trace(n);
+ if(n != null)
{
goodNoteHit(daNote);
boyfriend.holdTimer = daNote.sustainLength;
@@ -3042,7 +3188,7 @@ class PlayState extends MusicBeatState
}
});
- if (boyfriend.holdTimer > Conductor.stepCrochet * 4 * 0.001 && (!holdArray.contains(true) || FlxG.save.data.botplay))
+ if (boyfriend.holdTimer > Conductor.stepCrochet * 4 * 0.001 && (!holdArray.contains(true) || PlayStateChangeables.botPlay))
{
if (boyfriend.animation.curAnim.name.startsWith('sing') && !boyfriend.animation.curAnim.name.endsWith('miss'))
boyfriend.playAnim('idle');
@@ -3066,6 +3212,101 @@ class PlayState extends MusicBeatState
});
}
+ public function findByTime(time:Float):Array
+ {
+ for (i in rep.replay.songNotes)
+ {
+ //trace('checking ' + Math.round(i[0]) + ' against ' + Math.round(time));
+ if (i[0] == time)
+ return i;
+ }
+ return null;
+ }
+
+ public var fuckingVolume:Float = 1;
+ public var useVideo = false;
+
+ public static var webmHandler:WebmHandler;
+
+ public var playingDathing = false;
+
+ public var videoSprite:FlxSprite;
+
+ public function focusOut() {
+ if (paused)
+ return;
+ persistentUpdate = false;
+ persistentDraw = true;
+ paused = true;
+
+ if (FlxG.sound.music != null)
+ {
+ FlxG.sound.music.pause();
+ vocals.pause();
+ }
+
+ openSubState(new PauseSubState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y));
+ }
+ public function focusIn()
+ {
+ // nada
+ }
+
+
+ public function backgroundVideo(source:String) // for background videos
+ {
+ useVideo = true;
+
+ FlxG.stage.window.onFocusOut.add(focusOut);
+ FlxG.stage.window.onFocusIn.add(focusIn);
+
+ var ourSource:String = "assets/videos/daWeirdVid/dontDelete.webm";
+ WebmPlayer.SKIP_STEP_LIMIT = 90;
+ var str1:String = "WEBM SHIT";
+ webmHandler = new WebmHandler();
+ webmHandler.source(ourSource);
+ webmHandler.makePlayer();
+ webmHandler.webm.name = str1;
+
+ GlobalVideo.setWebm(webmHandler);
+
+ GlobalVideo.get().source(source);
+ GlobalVideo.get().clearPause();
+ if (GlobalVideo.isWebm)
+ {
+ GlobalVideo.get().updatePlayer();
+ }
+ GlobalVideo.get().show();
+
+ if (GlobalVideo.isWebm)
+ {
+ GlobalVideo.get().restart();
+ } else {
+ GlobalVideo.get().play();
+ }
+
+ var data = webmHandler.webm.bitmapData;
+
+ videoSprite = new FlxSprite(-470,-30).loadGraphic(data);
+
+ videoSprite.setGraphicSize(Std.int(videoSprite.width * 1.2));
+
+ remove(gf);
+ remove(boyfriend);
+ remove(dad);
+ add(videoSprite);
+ add(gf);
+ add(boyfriend);
+ add(dad);
+
+ trace('poggers');
+
+ if (!songStarted)
+ webmHandler.pause();
+ else
+ webmHandler.resume();
+ }
+
function noteMiss(direction:Int = 1, daNote:Note):Void
{
if (!boyfriend.stunned)
@@ -3078,6 +3319,15 @@ class PlayState extends MusicBeatState
combo = 0;
misses++;
+ if (daNote != null)
+ {
+ if (!loadRep)
+ saveNotes.push([daNote.strumTime,0,direction,166 * Math.floor((PlayState.rep.replay.sf / 60) * 1000) / 166]);
+ }
+ else
+ if (!loadRep)
+ saveNotes.push([Conductor.songPosition,0,direction,166 * Math.floor((PlayState.rep.replay.sf / 60) * 1000) / 166]);
+
//var noteDiff:Float = Math.abs(daNote.strumTime - Conductor.songPosition);
//var wife:Float = EtternaFunctions.wife3(noteDiff, FlxG.save.data.etternaMode ? 1 : 1.7);
@@ -3164,9 +3414,9 @@ class PlayState extends MusicBeatState
function noteCheck(controlArray:Array, note:Note):Void // sorry lol
{
- var noteDiff:Float = Math.abs(note.strumTime - Conductor.songPosition);
+ var noteDiff:Float = -(note.strumTime - Conductor.songPosition);
- note.rating = Ratings.CalculateRating(noteDiff);
+ note.rating = Ratings.CalculateRating(noteDiff, Math.floor((PlayStateChangeables.safeFrames / 60) * 1000));
/* if (loadRep)
{
@@ -3215,10 +3465,16 @@ class PlayState extends MusicBeatState
if (mashing != 0)
mashing = 0;
- var noteDiff:Float = Math.abs(note.strumTime - Conductor.songPosition);
+ var noteDiff:Float = -(note.strumTime - Conductor.songPosition);
+
+ if(loadRep)
+ noteDiff = findByTime(note.strumTime)[3];
note.rating = Ratings.CalculateRating(noteDiff);
+ if (note.rating == "miss")
+ return;
+
// add newest note to front of notesHitArray
// the oldest notes are at the end and are removed first
if (!note.isSustainNote)
@@ -3260,7 +3516,13 @@ class PlayState extends MusicBeatState
if(!loadRep && note.mustPress)
- saveNotes.push(HelperFunctions.truncateFloat(note.strumTime, 2));
+ {
+ var array = [note.strumTime,note.sustainLength,note.noteData,noteDiff];
+ if (note.isSustainNote)
+ array[1] = -1;
+ trace('pushing ' + array[0]);
+ saveNotes.push(array);
+ }
playerStrums.forEach(function(spr:FlxSprite)
{
@@ -3399,8 +3661,6 @@ class PlayState extends MusicBeatState
}
#end
-
-
// yes this updates every step.
// yes this is bad
// but i'm doing it to update misses and accuracy
@@ -3423,7 +3683,7 @@ class PlayState extends MusicBeatState
if (generatedMusic)
{
- notes.sort(FlxSort.byY, (FlxG.save.data.downscroll ? FlxSort.ASCENDING : FlxSort.DESCENDING));
+ notes.sort(FlxSort.byY, (PlayStateChangeables.useDownscroll ? FlxSort.ASCENDING : FlxSort.DESCENDING));
}
#if windows
@@ -3458,22 +3718,26 @@ class PlayState extends MusicBeatState
// FlxG.log.add('change bpm' + SONG.notes[Std.int(curStep / 16)].changeBPM);
wiggleShit.update(Conductor.crochet);
- // HARDCODING FOR MILF ZOOMS!
- if (curSong.toLowerCase() == 'milf' && curBeat >= 168 && curBeat < 200 && camZooming && FlxG.camera.zoom < 1.35)
+ if (FlxG.save.data.camzoom)
{
- FlxG.camera.zoom += 0.015;
- camHUD.zoom += 0.03;
- }
-
- if (camZooming && FlxG.camera.zoom < 1.35 && curBeat % 4 == 0)
- {
- FlxG.camera.zoom += 0.015;
- camHUD.zoom += 0.03;
+ // HARDCODING FOR MILF ZOOMS!
+ if (curSong.toLowerCase() == 'milf' && curBeat >= 168 && curBeat < 200 && camZooming && FlxG.camera.zoom < 1.35)
+ {
+ FlxG.camera.zoom += 0.015;
+ camHUD.zoom += 0.03;
+ }
+
+ if (camZooming && FlxG.camera.zoom < 1.35 && curBeat % 4 == 0)
+ {
+ FlxG.camera.zoom += 0.015;
+ camHUD.zoom += 0.03;
+ }
+
}
iconP1.setGraphicSize(Std.int(iconP1.width + 30));
iconP2.setGraphicSize(Std.int(iconP2.width + 30));
-
+
iconP1.updateHitbox();
iconP2.updateHitbox();
diff --git a/source/PlayStateChangeables.hx b/source/PlayStateChangeables.hx
new file mode 100644
index 0000000..8ee4995
--- /dev/null
+++ b/source/PlayStateChangeables.hx
@@ -0,0 +1,7 @@
+class PlayStateChangeables
+{
+ public static var useDownscroll:Bool;
+ public static var safeFrames:Int;
+ public static var scrollSpeed:Float;
+ public static var botPlay:Bool;
+}
\ No newline at end of file
diff --git a/source/Ratings.hx b/source/Ratings.hx
index 615d3ba..92b0ee5 100644
--- a/source/Ratings.hx
+++ b/source/Ratings.hx
@@ -5,7 +5,7 @@ class Ratings
public static function GenerateLetterRank(accuracy:Float) // generate a letter ranking
{
var ranking:String = "N/A";
- if(FlxG.save.data.botplay)
+ if(FlxG.save.data.botplay && !PlayState.loadRep)
ranking = "BotPlay";
if (PlayState.misses == 0 && PlayState.bads == 0 && PlayState.shits == 0 && PlayState.goods == 0) // Marvelous (SICK) Full Combo
@@ -86,7 +86,7 @@ class Ratings
if (accuracy == 0)
ranking = "N/A";
- else if(FlxG.save.data.botplay)
+ else if(FlxG.save.data.botplay && !PlayState.loadRep)
ranking = "BotPlay";
return ranking;
@@ -107,35 +107,45 @@ class Ratings
// trace('Hit Info\nDifference: ' + noteDiff + '\nZone: ' + Conductor.safeZoneOffset * 1.5 + "\nTS: " + customTimeScale + "\nLate: " + 155 * customTimeScale);
- if (FlxG.save.data.botplay)
- return "good"; // FUNNY
-
- if (noteDiff > 166 * customTimeScale) // so god damn early its a miss
- return "miss";
- if (noteDiff > 135 * customTimeScale) // way early
- return "shit";
- else if (noteDiff > 90 * customTimeScale) // early
- return "bad";
- else if (noteDiff > 45 * customTimeScale) // your kinda there
- return "good";
- else if (noteDiff < -45 * customTimeScale) // little late
- return "good";
- else if (noteDiff < -90 * customTimeScale) // late
- return "bad";
- else if (noteDiff < -135 * customTimeScale) // late as fuck
- return "shit";
- else if (noteDiff < -166 * customTimeScale) // so god damn late its a miss
- return "miss";
- return "sick";
+ if (FlxG.save.data.botplay && !PlayState.loadRep)
+ return "sick"; // FUNNY
+
+
+ var rating = checkRating(noteDiff,customTimeScale);
+
+
+ return rating;
+ }
+
+ public static function checkRating(ms:Float, ts:Float)
+ {
+ var rating = "miss";
+ if (ms < 166 * ts && ms > 135 * ts)
+ rating = "shit";
+ if (ms > -166 * ts && ms < -135 * ts)
+ rating = "shit";
+ if (ms < 135 * ts && ms > 90 * ts)
+ rating = "bad";
+ if (ms > -135 * ts && ms < -90 * ts)
+ rating = "bad";
+ if (ms < 90 * ts && ms > 45 * ts)
+ rating = "good";
+ if (ms > -90 * ts && ms < -45 * ts)
+ rating = "good";
+ if (ms < 45 * ts && ms > -45 * ts)
+ rating = "sick";
+ return rating;
}
public static function CalculateRanking(score:Int,scoreDef:Int,nps:Int,maxNPS:Int,accuracy:Float):String
{
- return
- (FlxG.save.data.npsDisplay ? "NPS: " + nps + " (Max " + maxNPS + ")" + (!FlxG.save.data.botplay ? " | " : "") : "") + (!FlxG.save.data.botplay ? // NPS Toggle
- "Score:" + (Conductor.safeFrames != 10 ? score + " (" + scoreDef + ")" : "" + score) + // Score
- " | Combo Breaks:" + PlayState.misses + // Misses/Combo Breaks
- " | Accuracy:" + (FlxG.save.data.botplay ? "N/A" : HelperFunctions.truncateFloat(accuracy, 2) + " %") + // Accuracy
- " | " + GenerateLetterRank(accuracy) : ""); // Letter Rank
+ return
+ (FlxG.save.data.npsDisplay ? // NPS Toggle
+ "NPS: " + nps + " (Max " + maxNPS + ")" + (!PlayStateChangeables.botPlay || PlayState.loadRep ? " | " : "") : "") + // NPS
+ (!PlayStateChangeables.botPlay || PlayState.loadRep ? "Score:" + (Conductor.safeFrames != 10 ? score + " (" + scoreDef + ")" : "" + score) + // Score
+ (FlxG.save.data.accuracyDisplay ? // Accuracy Toggle
+ " | Combo Breaks:" + PlayState.misses + // Misses/Combo Breaks
+ " | Accuracy:" + (PlayStateChangeables.botPlay && !PlayState.loadRep ? "N/A" : HelperFunctions.truncateFloat(accuracy, 2) + " %") + // Accuracy
+ " | " + GenerateLetterRank(accuracy) : "") : ""); // Letter Rank
}
}
diff --git a/source/Replay.hx b/source/Replay.hx
index bf43d77..51fddf2 100644
--- a/source/Replay.hx
+++ b/source/Replay.hx
@@ -13,79 +13,88 @@ import openfl.utils.Dictionary;
typedef ReplayJSON =
{
- public var replayGameVer:String;
- public var timestamp:Date;
- public var songName:String;
- public var songDiff:Int;
- public var songNotes:Array;
+ public var replayGameVer:String;
+ public var timestamp:Date;
+ public var songName:String;
+ public var songDiff:Int;
+ public var songNotes:Array;
public var noteSpeed:Float;
public var isDownscroll:Bool;
+ public var sf:Int;
}
class Replay
{
- public static var version:String = "1.0"; // replay file version
+ public static var version:String = "1.2"; // replay file version
- public var path:String = "";
- public var replay:ReplayJSON;
- public function new(path:String)
- {
- this.path = path;
- replay = {
- songName: "Tutorial",
- songDiff: 1,
+ public var path:String = "";
+ public var replay:ReplayJSON;
+ public function new(path:String)
+ {
+ this.path = path;
+ replay = {
+ songName: "No Song Found",
+ songDiff: 1,
noteSpeed: 1.5,
isDownscroll: false,
songNotes: [],
- replayGameVer: version,
- timestamp: Date.now()
- };
- }
+ replayGameVer: version,
+ timestamp: Date.now(),
+ sf: Conductor.safeFrames
+ };
+ }
- public static function LoadReplay(path:String):Replay
+ public static function LoadReplay(path:String):Replay
{
- var rep:Replay = new Replay(path);
+ var rep:Replay = new Replay(path);
- rep.LoadFromJSON();
+ rep.LoadFromJSON();
- trace('basic replay data:\nSong Name: ' + rep.replay.songName + '\nSong Diff: ' + rep.replay.songDiff + '\nNotes Length: ' + rep.replay.songNotes.length);
+ trace('basic replay data:\nSong Name: ' + rep.replay.songName + '\nSong Diff: ' + rep.replay.songDiff);
- return rep;
- }
+ return rep;
+ }
- public function SaveReplay(notearray:Array)
- {
- var json = {
- "songName": PlayState.SONG.song.toLowerCase(),
- "songDiff": PlayState.storyDifficulty,
+ public function SaveReplay(notearray:Array)
+ {
+ var json = {
+ "songName": PlayState.SONG.song,
+ "songDiff": PlayState.storyDifficulty,
"noteSpeed": (FlxG.save.data.scrollSpeed > 1 ? FlxG.save.data.scrollSpeed : PlayState.SONG.speed),
"isDownscroll": FlxG.save.data.downscroll,
"songNotes": notearray,
- "timestamp": Date.now(),
- "replayGameVer": version
- };
+ "timestamp": Date.now(),
+ "replayGameVer": version,
+ "sf": Conductor.safeFrames
+ };
- var data:String = Json.stringify(json);
+ var data:String = Json.stringify(json);
+
+ var time = Date.now().getTime();
- #if sys
- File.saveContent("assets/replays/replay-" + PlayState.SONG.song + "-time" + Date.now().getTime() + ".kadeReplay", data);
- #end
- }
+ #if sys
+ File.saveContent("assets/replays/replay-" + PlayState.SONG.song + "-time" + time + ".kadeReplay", data);
- public function LoadFromJSON()
- {
- #if sys
- trace('loading ' + Sys.getCwd() + 'assets/replays/' + path + ' replay...');
- try
- {
- var repl:ReplayJSON = cast Json.parse(File.getContent(Sys.getCwd() + "assets/replays/" + path));
- replay = repl;
- }
- catch(e)
- {
- trace('failed!\n' + e.message);
- }
- #end
- }
+ path = "replay-" + PlayState.SONG.song + "-time" + time + ".kadeReplay"; // for score screen shit
+
+ LoadFromJSON();
+ #end
+ }
+
+ public function LoadFromJSON()
+ {
+ #if sys
+ trace('loading ' + Sys.getCwd() + 'assets/replays/' + path + ' replay...');
+ try
+ {
+ var repl:ReplayJSON = cast Json.parse(File.getContent(Sys.getCwd() + "assets/replays/" + path));
+ replay = repl;
+ }
+ catch(e)
+ {
+ trace('failed!\n' + e.message);
+ }
+ #end
+ }
}
diff --git a/source/ResultsScreen.hx b/source/ResultsScreen.hx
new file mode 100644
index 0000000..2c8e258
--- /dev/null
+++ b/source/ResultsScreen.hx
@@ -0,0 +1,250 @@
+package;
+
+import openfl.geom.Matrix;
+import openfl.display.BitmapData;
+import flixel.system.FlxSound;
+import flixel.util.FlxAxes;
+import flixel.FlxSubState;
+import Options.Option;
+import flixel.input.FlxInput;
+import flixel.input.keyboard.FlxKey;
+import flixel.FlxG;
+import flixel.FlxObject;
+import flixel.FlxSprite;
+import flixel.effects.FlxFlicker;
+import flixel.graphics.frames.FlxAtlasFrames;
+import flixel.group.FlxGroup.FlxTypedGroup;
+import flixel.text.FlxText;
+import flixel.tweens.FlxEase;
+import flixel.tweens.FlxTween;
+import flixel.util.FlxColor;
+import io.newgrounds.NG;
+import lime.app.Application;
+import lime.utils.Assets;
+import flixel.math.FlxMath;
+import flixel.text.FlxText;
+import flixel.input.FlxKeyManager;
+
+
+using StringTools;
+
+class ResultsScreen extends FlxSubState
+{
+ public var background:FlxSprite;
+ public var text:FlxText;
+
+ public var anotherBackground:FlxSprite;
+ public var graph:HitGraph;
+ public var graphSprite:FlxSprite;
+
+ public var comboText:FlxText;
+ public var contText:FlxText;
+ public var settingsText:FlxText;
+
+ public var music:FlxSound;
+
+ public var graphData:BitmapData;
+
+ public var ranking:String;
+ public var accuracy:String;
+
+ override function create()
+ {
+ background = new FlxSprite(0,0).makeGraphic(FlxG.width,FlxG.height,FlxColor.BLACK);
+ background.scrollFactor.set();
+ add(background);
+
+ music = new FlxSound().loadEmbedded(Paths.music('breakfast'), true, true);
+ music.volume = 0;
+ music.play(false, FlxG.random.int(0, Std.int(music.length / 2)));
+
+ background.alpha = 0;
+
+ text = new FlxText(20,-55,0,"Song Cleared!");
+ text.size = 34;
+ text.setBorderStyle(FlxTextBorderStyle.OUTLINE,FlxColor.BLACK,4,1);
+ text.color = FlxColor.WHITE;
+ text.scrollFactor.set();
+ add(text);
+
+ var score = PlayState.instance.songScore;
+ if (PlayState.isStoryMode)
+ {
+ score = PlayState.campaignScore;
+ text.text = "Week Cleared!";
+ }
+
+ comboText = new FlxText(20,-75,0,'Judgements:\nSicks - ${PlayState.sicks}\nGoods - ${PlayState.goods}\nBads - ${PlayState.bads}\n\nCombo Breaks: ${(PlayState.isStoryMode ? PlayState.campaignMisses : PlayState.misses) + PlayState.shits}\nHighest Combo: ${PlayState.highestCombo + 1}\n\nScore: ${PlayState.instance.songScore}\nAccuracy: ${HelperFunctions.truncateFloat(PlayState.instance.accuracy,2)}%\n\n${Ratings.GenerateLetterRank(PlayState.instance.accuracy)}\n\nF1 - View replay\nF2 - Replay song
+ ');
+ comboText.size = 28;
+ comboText.setBorderStyle(FlxTextBorderStyle.OUTLINE,FlxColor.BLACK,4,1);
+ comboText.color = FlxColor.WHITE;
+ comboText.scrollFactor.set();
+ add(comboText);
+
+ contText = new FlxText(FlxG.width - 475,FlxG.height + 50,0,'Press ENTER to continue.');
+ contText.size = 28;
+ contText.setBorderStyle(FlxTextBorderStyle.OUTLINE,FlxColor.BLACK,4,1);
+ contText.color = FlxColor.WHITE;
+ contText.scrollFactor.set();
+ add(contText);
+
+ anotherBackground = new FlxSprite(FlxG.width - 500,45).makeGraphic(450,240,FlxColor.BLACK);
+ anotherBackground.scrollFactor.set();
+ anotherBackground.alpha = 0;
+ add(anotherBackground);
+
+ graph = new HitGraph(FlxG.width - 500,45,495,240);
+ graph.alpha = 0;
+
+ graphSprite = new FlxSprite(FlxG.width - 510,45);
+
+ graphSprite.scrollFactor.set();
+ graphSprite.alpha = 0;
+
+ add(graphSprite);
+
+
+ var sicks = HelperFunctions.truncateFloat(PlayState.sicks / PlayState.goods,1);
+ var goods = HelperFunctions.truncateFloat(PlayState.goods / PlayState.bads,1);
+
+ if (sicks == Math.POSITIVE_INFINITY)
+ sicks = 0;
+ if (goods == Math.POSITIVE_INFINITY)
+ goods = 0;
+
+ var mean:Float = 0;
+
+
+ for (i in PlayState.rep.replay.songNotes)
+ {
+ // 0 = time
+ // 1 = length
+ // 2 = type
+ // 3 = diff
+ var diff = i[3];
+ var judge = Ratings.CalculateRating(diff, Math.floor((PlayState.rep.replay.sf / 60) * 1000));
+ mean += diff;
+ if (i[1] != -1)
+ graph.addToHistory(diff, judge);
+ }
+
+ graph.update();
+
+ graphSprite.makeGraphic(460,240,FlxColor.TRANSPARENT);
+
+ graphSprite.pixels.draw(graph);
+
+ mean = HelperFunctions.truncateFloat(mean / PlayState.rep.replay.songNotes.length,2);
+
+ settingsText = new FlxText(20,FlxG.height + 50,0,'SF: ${PlayState.rep.replay.sf} | Ratio (SA/GA): ${Math.round(sicks)}:1 ${Math.round(goods)}:1 | Mean: ${mean}ms | Played on ${PlayState.SONG.song} ${CoolUtil.difficultyString()}');
+ settingsText.size = 16;
+ settingsText.setBorderStyle(FlxTextBorderStyle.OUTLINE,FlxColor.BLACK,2,1);
+ settingsText.color = FlxColor.WHITE;
+ settingsText.scrollFactor.set();
+ add(settingsText);
+
+
+ FlxTween.tween(background, {alpha: 0.5},0.5);
+ FlxTween.tween(text, {y:20},0.5,{ease: FlxEase.expoInOut});
+ FlxTween.tween(comboText, {y:145},0.5,{ease: FlxEase.expoInOut});
+ FlxTween.tween(contText, {y:FlxG.height - 45},0.5,{ease: FlxEase.expoInOut});
+ FlxTween.tween(settingsText, {y:FlxG.height - 35},0.5,{ease: FlxEase.expoInOut});
+ FlxTween.tween(anotherBackground, {alpha: 0.6},0.5, {onUpdate: function(tween:FlxTween) {
+ graph.alpha = FlxMath.lerp(0,1,tween.percent);
+ graphSprite.alpha = FlxMath.lerp(0,1,tween.percent);
+ }});
+
+ cameras = [FlxG.cameras.list[FlxG.cameras.list.length - 1]];
+
+ super.create();
+ }
+
+
+ var frames = 0;
+
+ override function update(elapsed:Float)
+ {
+ if (music.volume < 0.5)
+ music.volume += 0.01 * elapsed;
+
+ // render
+ if (frames != 2)
+ {
+ graphSprite.pixels.draw(graph);
+ frames++;
+ }
+ // keybinds
+
+ if (FlxG.keys.justPressed.ENTER)
+ {
+ music.fadeOut(0.3);
+
+ PlayState.loadRep = false;
+ PlayState.rep = null;
+
+ if (PlayState.isStoryMode)
+ {
+ FlxG.sound.playMusic(Paths.music('freakyMenu'));
+ FlxG.switchState(new MainMenuState());
+ }
+ else
+ FlxG.switchState(new FreeplayState());
+ }
+
+ if (FlxG.keys.justPressed.F1)
+ {
+ trace(PlayState.rep.path);
+ PlayState.rep = Replay.LoadReplay(PlayState.rep.path);
+
+ PlayState.loadRep = true;
+
+ var songFormat = StringTools.replace(PlayState.rep.replay.songName, " ", "-");
+ switch (songFormat) {
+ case 'Dad-Battle': songFormat = 'Dadbattle';
+ case 'Philly-Nice': songFormat = 'Philly';
+ // Replay v1.0 support
+ case 'dad-battle': songFormat = 'Dadbattle';
+ case 'philly-nice': songFormat = 'Philly';
+ }
+
+ var poop:String = Highscore.formatSong(songFormat, PlayState.rep.replay.songDiff);
+
+ music.fadeOut(0.3);
+
+ PlayState.SONG = Song.loadFromJson(poop, PlayState.rep.replay.songName);
+ PlayState.isStoryMode = false;
+ PlayState.storyDifficulty = PlayState.rep.replay.songDiff;
+ PlayState.storyWeek = 0;
+ LoadingState.loadAndSwitchState(new PlayState());
+ }
+
+ if (FlxG.keys.justPressed.F2 )
+ {
+ PlayState.rep = null;
+
+ PlayState.loadRep = false;
+
+ var songFormat = StringTools.replace(PlayState.SONG.song, " ", "-");
+ switch (songFormat) {
+ case 'Dad-Battle': songFormat = 'Dadbattle';
+ case 'Philly-Nice': songFormat = 'Philly';
+ case 'dad-battle': songFormat = 'Dadbattle';
+ case 'philly-nice': songFormat = 'Philly';
+ }
+
+ var poop:String = Highscore.formatSong(songFormat, PlayState.storyDifficulty);
+
+ music.fadeOut(0.3);
+
+ PlayState.SONG = Song.loadFromJson(poop, PlayState.SONG.song);
+ PlayState.isStoryMode = false;
+ PlayState.storyDifficulty = PlayState.storyDifficulty;
+ PlayState.storyWeek = 0;
+ LoadingState.loadAndSwitchState(new PlayState());
+ }
+
+ super.update(elapsed);
+
+ }
+}
diff --git a/source/Song.hx b/source/Song.hx
index 00d8e94..5329079 100644
--- a/source/Song.hx
+++ b/source/Song.hx
@@ -33,9 +33,9 @@ class Song
public var player1:String = 'bf';
public var player2:String = 'dad';
- public var gfVersion:String = 'gf';
- public var noteStyle:String = 'normal';
- public var stage:String = 'stage';
+ public var gfVersion:String = '';
+ public var noteStyle:String = '';
+ public var stage:String = '';
public function new(song, notes, bpm)
{
@@ -47,8 +47,8 @@ class Song
public static function loadFromJson(jsonInput:String, ?folder:String):SwagSong
{
trace(jsonInput);
-
- // pre lowercasing the song name (update)
+
+ // pre lowercasing the folder name
var folderLowercase = StringTools.replace(folder, " ", "-").toLowerCase();
switch (folderLowercase) {
case 'dad-battle': folderLowercase = 'dadbattle';
diff --git a/source/StoryMenuState.hx b/source/StoryMenuState.hx
index 501cf2b..443b8e0 100644
--- a/source/StoryMenuState.hx
+++ b/source/StoryMenuState.hx
@@ -285,19 +285,23 @@ class StoryMenuState extends MusicBeatState
PlayState.isStoryMode = true;
selectedWeek = true;
- var diffic = "";
-
- switch (curDifficulty)
- {
- case 0:
- diffic = '-easy';
- case 2:
- diffic = '-hard';
- }
PlayState.storyDifficulty = curDifficulty;
- PlayState.SONG = Song.loadFromJson(StringTools.replace(PlayState.storyPlaylist[0]," ", "-").toLowerCase() + diffic, StringTools.replace(PlayState.storyPlaylist[0]," ", "-").toLowerCase());
+ // adjusting the song name to be compatible
+ var songFormat = StringTools.replace(PlayState.storyPlaylist[0], " ", "-");
+ switch (songFormat) {
+ case 'Dad-Battle': songFormat = 'Dadbattle';
+ case 'Philly-Nice': songFormat = 'Philly';
+ }
+
+ var poop:String = Highscore.formatSong(songFormat, curDifficulty);
+ PlayState.sicks = 0;
+ PlayState.bads = 0;
+ PlayState.shits = 0;
+ PlayState.goods = 0;
+ PlayState.campaignMisses = 0;
+ PlayState.SONG = Song.loadFromJson(poop, PlayState.storyPlaylist[0]);
PlayState.storyWeek = curWeek;
PlayState.campaignScore = 0;
new FlxTimer().start(1, function(tmr:FlxTimer)
diff --git a/source/VideoHandler.hx b/source/VideoHandler.hx
new file mode 100644
index 0000000..1b01699
--- /dev/null
+++ b/source/VideoHandler.hx
@@ -0,0 +1,195 @@
+//This was made by GWebDev lol btw this uses actuate
+package;
+
+import motion.Actuate;
+import openfl.display.Sprite;
+import openfl.events.AsyncErrorEvent;
+import openfl.events.MouseEvent;
+import openfl.events.NetStatusEvent;
+import openfl.media.Video;
+import openfl.net.NetConnection;
+import openfl.net.NetStream;
+import flixel.FlxG;
+
+using StringTools;
+
+class VideoHandler
+{
+ public var netStream:NetStream;
+ public var video:Video;
+ public var isReady:Bool = false;
+ public var addOverlay:Bool = false;
+ public var vidPath:String = "";
+ public var ignoreShit:Bool = false;
+
+ public function new()
+ {
+ isReady = false;
+ }
+
+ public function source(?vPath:String):Void
+ {
+ if (vPath != null && vPath.length > 0)
+ {
+ vidPath = vPath;
+ }
+ }
+
+ public function init1():Void
+ {
+ isReady = false;
+ video = new Video();
+ video.visible = false;
+ }
+
+ public function init2():Void
+ {
+ #if web
+ var netConnection = new NetConnection ();
+ netConnection.connect (null);
+
+ netStream = new NetStream (netConnection);
+ netStream.client = { onMetaData: client_onMetaData };
+ netStream.addEventListener (AsyncErrorEvent.ASYNC_ERROR, netStream_onAsyncError);
+
+ netConnection.addEventListener (NetStatusEvent.NET_STATUS, netConnection_onNetStatus);
+ netConnection.addEventListener (NetStatusEvent.NET_STATUS, onPlay);
+ netConnection.addEventListener (NetStatusEvent.NET_STATUS, onEnd);
+ #end
+ }
+
+ public function client_onMetaData (metaData:Dynamic) {
+
+ video.attachNetStream (netStream);
+
+ video.width = FlxG.width;
+ video.height = FlxG.height;
+
+ }
+
+
+ public function netStream_onAsyncError (event:AsyncErrorEvent):Void {
+
+ trace ("Error loading video");
+
+ }
+
+
+ public function netConnection_onNetStatus (event:NetStatusEvent):Void {
+ trace (event.info.code);
+ }
+
+ public function play():Void
+ {
+ #if web
+ ignoreShit = true;
+ netStream.close();
+ init2();
+ netStream.play(vidPath);
+ ignoreShit = false;
+ #end
+ trace(vidPath);
+ }
+
+ public function stop():Void
+ {
+ netStream.close();
+ onStop();
+ }
+
+ public function restart():Void
+ {
+ play();
+ onRestart();
+ }
+
+ public function update(elapsed:Float):Void
+ {
+ video.x = GlobalVideo.calc(0);
+ video.y = GlobalVideo.calc(1);
+ video.width = GlobalVideo.calc(2);
+ video.height = GlobalVideo.calc(3);
+ }
+
+ public var stopped:Bool = false;
+ public var restarted:Bool = false;
+ public var played:Bool = false;
+ public var ended:Bool = false;
+ public var paused:Bool = false;
+
+ public function pause():Void
+ {
+ netStream.pause();
+ paused = true;
+ }
+
+ public function resume():Void
+ {
+ netStream.resume();
+ paused = false;
+ }
+
+ public function togglePause():Void
+ {
+ if (paused)
+ {
+ resume();
+ } else {
+ pause();
+ }
+ }
+
+ public function clearPause():Void
+ {
+ paused = false;
+ }
+
+ public function onStop():Void
+ {
+ if (!ignoreShit)
+ {
+ stopped = true;
+ }
+ }
+
+ public function onRestart():Void
+ {
+ restarted = true;
+ }
+
+ public function onPlay(event:NetStatusEvent):Void
+ {
+ if (event.info.code == "NetStream.Play.Start")
+ {
+ played = true;
+ }
+ }
+
+ public function onEnd(event:NetStatusEvent):Void
+ {
+ if (event.info.code == "NetStream.Play.Complete")
+ {
+ ended = true;
+ }
+ }
+
+ public function alpha():Void
+ {
+ video.alpha = GlobalVideo.daAlpha1;
+ }
+
+ public function unalpha():Void
+ {
+ video.alpha = GlobalVideo.daAlpha2;
+ }
+
+ public function hide():Void
+ {
+ video.visible = false;
+ }
+
+ public function show():Void
+ {
+ video.visible = true;
+ }
+}
\ No newline at end of file
diff --git a/source/WebmHandler.hx b/source/WebmHandler.hx
new file mode 100644
index 0000000..77b9391
--- /dev/null
+++ b/source/WebmHandler.hx
@@ -0,0 +1,169 @@
+package;
+
+import flixel.FlxG;
+import openfl.display.Sprite;
+#if desktop
+import webm.*;
+#end
+
+class WebmHandler
+{
+ #if desktop
+ public var webm:WebmPlayer;
+ public var vidPath:String = "";
+ public var io:WebmIo;
+ public var initialized:Bool = false;
+
+ public function new()
+ {
+ }
+
+ public function source(?vPath:String):Void
+ {
+ if (vPath != null && vPath.length > 0)
+ {
+ vidPath = vPath;
+ }
+ }
+
+ public function makePlayer():Void
+ {
+ io = new WebmIoFile(vidPath);
+ webm = new WebmPlayer();
+ webm.fuck(io, false);
+ webm.addEventListener(WebmEvent.PLAY, function(e) {
+ onPlay();
+ });
+ webm.addEventListener(WebmEvent.COMPLETE, function(e) {
+ onEnd();
+ });
+ webm.addEventListener(WebmEvent.STOP, function(e) {
+ onStop();
+ });
+ webm.addEventListener(WebmEvent.RESTART, function(e) {
+ onRestart();
+ });
+ webm.visible = false;
+ initialized = true;
+ }
+
+ public function updatePlayer():Void
+ {
+ io = new WebmIoFile(vidPath);
+ webm.fuck(io, false);
+ }
+
+ public function play():Void
+ {
+ if (initialized)
+ {
+ webm.play();
+ }
+ }
+
+ public function stop():Void
+ {
+ if (initialized)
+ {
+ webm.stop();
+ }
+ }
+
+ public function restart():Void
+ {
+ if (initialized)
+ {
+ webm.restart();
+ }
+ }
+
+ public function update(elapsed:Float)
+ {
+ webm.x = GlobalVideo.calc(0);
+ webm.y = GlobalVideo.calc(1);
+ webm.width = GlobalVideo.calc(2);
+ webm.height = GlobalVideo.calc(3);
+ }
+
+ public var stopped:Bool = false;
+ public var restarted:Bool = false;
+ public var played:Bool = false;
+ public var ended:Bool = false;
+ public var paused:Bool = false;
+
+ public function pause():Void
+ {
+ webm.changePlaying(false);
+ paused = true;
+ }
+
+ public function resume():Void
+ {
+ webm.changePlaying(true);
+ paused = false;
+ }
+
+ public function togglePause():Void
+ {
+ if (paused)
+ {
+ resume();
+ } else {
+ pause();
+ }
+ }
+
+ public function clearPause():Void
+ {
+ paused = false;
+ webm.removePause();
+ }
+
+ public function onStop():Void
+ {
+ stopped = true;
+ }
+
+ public function onRestart():Void
+ {
+ restarted = true;
+ }
+
+ public function onPlay():Void
+ {
+ played = true;
+ }
+
+ public function onEnd():Void
+ {
+ trace("IT ENDED!");
+ ended = true;
+ }
+
+ public function alpha():Void
+ {
+ webm.alpha = GlobalVideo.daAlpha1;
+ }
+
+ public function unalpha():Void
+ {
+ webm.alpha = GlobalVideo.daAlpha2;
+ }
+
+ public function hide():Void
+ {
+ webm.visible = false;
+ }
+
+ public function show():Void
+ {
+ webm.visible = true;
+ }
+ #else
+ public var webm:Sprite;
+ public function new()
+ {
+ trace("THIS IS ANDROID! or some shit...");
+ }
+ #end
+}
\ No newline at end of file
diff --git a/version.downloadMe b/version.downloadMe
index b8cb634..b03f579 100644
--- a/version.downloadMe
+++ b/version.downloadMe
@@ -1,11 +1,6 @@
-1.5.2;
-- (1.5.2) Fix crashes on some songs
-- Added toggle for ghost tapping
-- Officially support macOS (and add macOS requirements to docs)
-- Autoplay
-- Clap assist for syncing charts
-- Bring back R to reset, but now you can toggle it in the options
-- You can now fully customize your keybinds
-- Change how replays work + store scroll speed and direction in replays
-- Opponent strumline now lights up when they hit a note, like the player's does
-- Now using the new recharts from Funkin v0.2.8
+1.5.3;
+- Score Screen
+- Rewrote the entire hit ranking system
+- Fixed song names so they don't crash
+- New asset loading system
+- New Logo
\ No newline at end of file