mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2025-11-25 13:45:49 +00:00
Merge branch 'rewrite/master' into char-unlock-tinkers
This commit is contained in:
commit
d826f2a7bc
|
|
@ -29,8 +29,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- Implemented support for a new Instrumental Selector in Freeplay
|
- Implemented support for a new Instrumental Selector in Freeplay
|
||||||
- Beating a Pico remix lets you use that instrumental when playing as Boyfriend
|
- Beating a Pico remix lets you use that instrumental when playing as Boyfriend
|
||||||
- Added the first batch of Erect Stages! These graphical overhauls of the original stages will be used when playing Erect remixes and Pico remixes
|
- Added the first batch of Erect Stages! These graphical overhauls of the original stages will be used when playing Erect remixes and Pico remixes
|
||||||
|
- Week 1 Erect Stage
|
||||||
|
- Week 2 Erect Stage
|
||||||
|
- Week 3 Erect Stage
|
||||||
|
- Week 4 Erect Stage
|
||||||
|
- Week 5 Erect Stage
|
||||||
|
- Weekend 1 Erect Stage
|
||||||
|
- Implemented alternate animations and music for Pico in the results screen.
|
||||||
|
- These display on Pico remixes, as well as when playing Weekend 1.
|
||||||
- Implemented support for scripted Note Kinds. You can use HScript define a different note style to display for these notes as well as custom behavior. (community feature by lemz1)
|
- Implemented support for scripted Note Kinds. You can use HScript define a different note style to display for these notes as well as custom behavior. (community feature by lemz1)
|
||||||
- Implemented a new Strumline Background option, to display a darkened background behind the strumline with your choice of opacity.
|
|
||||||
- Implemented support for Numeric and Selector options in the Options menu. (community feature by FlooferLand)
|
- Implemented support for Numeric and Selector options in the Options menu. (community feature by FlooferLand)
|
||||||
## Changed
|
## Changed
|
||||||
- Girlfriend and Nene now perform previously unused animations when you achieve a large combo, or drop a large combo.
|
- Girlfriend and Nene now perform previously unused animations when you achieve a large combo, or drop a large combo.
|
||||||
|
|
|
||||||
2
art
2
art
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0bb988c49788fd25a230b56dd9e4448838bc79c9
|
Subproject commit 0dee03f11afc01c2883da223fa10405f7011dd33
|
||||||
2
assets
2
assets
|
|
@ -1 +1 @@
|
||||||
Subproject commit f4cf1d3721155e16ab4e547b6baabc1238b66dae
|
Subproject commit aede71ea384103393273fa72e8c02fa0f364da94
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
5. Run `haxelib --global install hmm` and then `haxelib --global run hmm setup` to install hmm.json
|
5. Run `haxelib --global install hmm` and then `haxelib --global run hmm setup` to install hmm.json
|
||||||
6. Run `hmm install` to install all haxelibs of the current branch
|
6. Run `hmm install` to install all haxelibs of the current branch
|
||||||
7. Run `haxelib run lime setup` to set up lime
|
7. Run `haxelib run lime setup` to set up lime
|
||||||
8. Platform setup
|
8. Perform additional platform setup
|
||||||
- For Windows, download the [Visual Studio Build Tools](https://aka.ms/vs/17/release/vs_BuildTools.exe)
|
- For Windows, download the [Visual Studio Build Tools](https://aka.ms/vs/17/release/vs_BuildTools.exe)
|
||||||
- When prompted, select "Individual Components" and make sure to download the following:
|
- When prompted, select "Individual Components" and make sure to download the following:
|
||||||
- MSVC v143 VS 2022 C++ x64/x86 build tools
|
- MSVC v143 VS 2022 C++ x64/x86 build tools
|
||||||
|
|
@ -22,8 +22,24 @@
|
||||||
- Mac: [`lime setup mac` Documentation](https://lime.openfl.org/docs/advanced-setup/macos/)
|
- Mac: [`lime setup mac` Documentation](https://lime.openfl.org/docs/advanced-setup/macos/)
|
||||||
- Linux: [`lime setup linux` Documentation](https://lime.openfl.org/docs/advanced-setup/linux/)
|
- Linux: [`lime setup linux` Documentation](https://lime.openfl.org/docs/advanced-setup/linux/)
|
||||||
- HTML5: Compiles without any extra setup
|
- HTML5: Compiles without any extra setup
|
||||||
9. If you are targeting for native, you may need to run `lime rebuild PLATFORM` and `lime rebuild PLATFORM -debug`
|
9. If you are targeting for native, you may need to run `lime rebuild <PLATFORM>` and `lime rebuild <PLATFORM> -debug`
|
||||||
10. `lime test PLATFORM` ! Add `-debug` to enable several debug features such as time travel (`PgUp`/`PgDn` in Play State).
|
10. `lime test <PLATFORM>` to build and launch the game for your platform (for example, `lime test windows`)
|
||||||
|
|
||||||
|
## Build Flags
|
||||||
|
|
||||||
|
There are several useful build flags you can add to a build to affect how it works. A full list can be found in `project.hxp`, but here's information on some of them:
|
||||||
|
|
||||||
|
- `-debug` to build the game in debug mode. This automatically enables several useful debug features.
|
||||||
|
- This includes enabling in-game debug functions, disables compile-time optimizations, enabling asset redirection (see below), and enabling the VSCode debug server (which can slow the game on some machines but allows for powerful debugging through breakpoints).
|
||||||
|
- `-DGITHUB_BUILD` will enable in-game debug functions (such as the ability to time travel in a song by pressing `PgUp`/`PgDn`), without enabling the other stuff
|
||||||
|
- `-DFEATURE_POLYMOD_MODS` or `-DNO_FEATURE_POLYMOD_MODS` to forcibly enable or disable modding support.
|
||||||
|
- `-DREDIRECT_ASSETS_FOLDER` or `-DNO_REDIRECT_ASSETS_FOLDER` to forcibly enable or disable asset redirection.
|
||||||
|
- This feature causes the game to load exported assets from the project's assets folder rather than the exported one. Great for fast iteration, but the game
|
||||||
|
- `-DFEATURE_DISCORD_RPC` or `-DNO_FEATURE_DISCORD_RPC` to forcibly enable or disable support for Discord Rich Presence.
|
||||||
|
- `-DFEATURE_VIDEO_PLAYBACK` or `-DNO_FEATURE_VIDEO_PLAYBACK` to forcibly enable or disable video cutscene support.
|
||||||
|
- `-DFEATURE_CHART_EDITOR` or `-DNO_FEATURE_CHART_EDITOR` to forcibly enable or disable the chart editor in the Debug menu.
|
||||||
|
- `-DFEATURE_STAGE_EDITOR` to forcibly enable the experimental stage editor.
|
||||||
|
- `-DFEATURE_GHOST_TAPPING` to forcibly enable an experimental gameplay change to the anti-mash system.
|
||||||
|
|
||||||
# Troubleshooting - GO THROUGH THESE STEPS BEFORE OPENING ISSUES ON GITHUB!
|
# Troubleshooting - GO THROUGH THESE STEPS BEFORE OPENING ISSUES ON GITHUB!
|
||||||
|
|
||||||
|
|
|
||||||
2
hmm.json
2
hmm.json
|
|
@ -194,7 +194,7 @@
|
||||||
"name": "polymod",
|
"name": "polymod",
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"dir": null,
|
"dir": null,
|
||||||
"ref": "96cfc5fa693b017e47f7cb13b765cc68698fa6b6",
|
"ref": "0fbdf27fe124549730accd540cec8a183f8652c0",
|
||||||
"url": "https://github.com/larsiusprime/polymod"
|
"url": "https://github.com/larsiusprime/polymod"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -67,15 +67,9 @@ class Main extends Sprite
|
||||||
function init(?event:Event):Void
|
function init(?event:Event):Void
|
||||||
{
|
{
|
||||||
#if web
|
#if web
|
||||||
untyped js.Syntax.code("
|
// set this variable (which is a function) from the lime version at lime/_internal/backend/html5/HTML5Application.hx
|
||||||
window.requestAnimationFrame = function(callback, element) {
|
// The framerate cap will more thoroughly initialize via Preferences in InitState.hx
|
||||||
var currTime = new Date().getTime();
|
funkin.Preferences.lockedFramerateFunction = untyped js.Syntax.code("window.requestAnimationFrame");
|
||||||
var timeToCall = 0;
|
|
||||||
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
|
|
||||||
timeToCall);
|
|
||||||
lastTime = currTime + timeToCall;
|
|
||||||
return id;
|
|
||||||
}");
|
|
||||||
#end
|
#end
|
||||||
|
|
||||||
if (hasEventListener(Event.ADDED_TO_STAGE))
|
if (hasEventListener(Event.ADDED_TO_STAGE))
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,48 @@ class Preferences
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static var unlockedFramerate(get, set):Bool;
|
||||||
|
|
||||||
|
static function get_unlockedFramerate():Bool
|
||||||
|
{
|
||||||
|
return Save?.instance?.options?.unlockedFramerate;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function set_unlockedFramerate(value:Bool):Bool
|
||||||
|
{
|
||||||
|
if (value != Save.instance.options.unlockedFramerate)
|
||||||
|
{
|
||||||
|
#if web
|
||||||
|
toggleFramerateCap(value);
|
||||||
|
#end
|
||||||
|
}
|
||||||
|
|
||||||
|
var save:Save = Save.instance;
|
||||||
|
save.options.unlockedFramerate = value;
|
||||||
|
save.flush();
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if web
|
||||||
|
// We create a haxe version of this just for readability.
|
||||||
|
// We use these to override `window.requestAnimationFrame` in Javascript to uncap the framerate / "animation" request rate
|
||||||
|
// Javascript is crazy since u can just do stuff like that lol
|
||||||
|
|
||||||
|
public static function unlockedFramerateFunction(callback, element)
|
||||||
|
{
|
||||||
|
var currTime = Date.now().getTime();
|
||||||
|
var timeToCall = 0;
|
||||||
|
var id = js.Browser.window.setTimeout(function() {
|
||||||
|
callback(currTime + timeToCall);
|
||||||
|
}, timeToCall);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lime already implements their own little framerate cap, so we can just use that
|
||||||
|
// This also gets set in the init function in Main.hx, since we need to definitely override it
|
||||||
|
public static var lockedFramerateFunction = untyped js.Syntax.code("window.requestAnimationFrame");
|
||||||
|
#end
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the user's preferences from the save data and apply them.
|
* Loads the user's preferences from the save data and apply them.
|
||||||
*/
|
*/
|
||||||
|
|
@ -137,6 +179,17 @@ class Preferences
|
||||||
FlxG.autoPause = Preferences.autoPause;
|
FlxG.autoPause = Preferences.autoPause;
|
||||||
// Apply the debugDisplay setting (enables the FPS and RAM display).
|
// Apply the debugDisplay setting (enables the FPS and RAM display).
|
||||||
toggleDebugDisplay(Preferences.debugDisplay);
|
toggleDebugDisplay(Preferences.debugDisplay);
|
||||||
|
#if web
|
||||||
|
toggleFramerateCap(Preferences.unlockedFramerate);
|
||||||
|
#end
|
||||||
|
}
|
||||||
|
|
||||||
|
static function toggleFramerateCap(unlocked:Bool):Void
|
||||||
|
{
|
||||||
|
#if web
|
||||||
|
var framerateFunction = unlocked ? unlockedFramerateFunction : lockedFramerateFunction;
|
||||||
|
untyped js.Syntax.code("window.requestAnimationFrame = framerateFunction;");
|
||||||
|
#end
|
||||||
}
|
}
|
||||||
|
|
||||||
static function toggleDebugDisplay(show:Bool):Void
|
static function toggleDebugDisplay(show:Bool):Void
|
||||||
|
|
|
||||||
|
|
@ -340,6 +340,8 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
|
||||||
if (songMusicData != null)
|
if (songMusicData != null)
|
||||||
{
|
{
|
||||||
Conductor.instance.mapTimeChanges(songMusicData.timeChanges);
|
Conductor.instance.mapTimeChanges(songMusicData.timeChanges);
|
||||||
|
|
||||||
|
if (songMusicData.looped != null && params.loop == null) params.loop = songMusicData.looped;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -567,6 +569,14 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
|
||||||
|
|
||||||
return sound;
|
return sound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Produces a string representation suitable for debugging.
|
||||||
|
*/
|
||||||
|
public override function toString():String
|
||||||
|
{
|
||||||
|
return 'FunkinSound(${this._label})';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,11 @@ class SoundGroup extends FlxTypedGroup<FunkinSound>
|
||||||
public function play(forceRestart:Bool = false, startTime:Float = 0.0, ?endTime:Float)
|
public function play(forceRestart:Bool = false, startTime:Float = 0.0, ?endTime:Float)
|
||||||
{
|
{
|
||||||
forEachAlive(function(sound:FunkinSound) {
|
forEachAlive(function(sound:FunkinSound) {
|
||||||
|
if (sound.length < startTime)
|
||||||
|
{
|
||||||
|
// trace('Queuing sound (${sound.toString()} past its length! Skipping...)');
|
||||||
|
return;
|
||||||
|
}
|
||||||
sound.play(forceRestart, startTime, endTime);
|
sound.play(forceRestart, startTime, endTime);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ class FlxAtlasSprite extends FlxAnimate
|
||||||
*/
|
*/
|
||||||
public function hasAnimation(id:String):Bool
|
public function hasAnimation(id:String):Bool
|
||||||
{
|
{
|
||||||
return getLabelIndex(id) != -1 || anim.symbolDictionary.exists(id) || anim.getByName(id) != null;
|
return getLabelIndex(id) != -1 || anim.symbolDictionary.exists(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -154,32 +154,27 @@ class FlxAtlasSprite extends FlxAnimate
|
||||||
{
|
{
|
||||||
if (!anim.isPlaying)
|
if (!anim.isPlaying)
|
||||||
{
|
{
|
||||||
|
if (fr != null) anim.curFrame = fr.index + startFrame;
|
||||||
|
else
|
||||||
|
anim.curFrame = startFrame;
|
||||||
|
|
||||||
// Resume animation if it's paused.
|
// Resume animation if it's paused.
|
||||||
anim.play('', restart, false, startFrame);
|
anim.resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else if (!hasAnimation(id))
|
||||||
{
|
{
|
||||||
// Skip if the animation doesn't exist
|
// Skip if the animation doesn't exist
|
||||||
if (!hasAnimation(id))
|
|
||||||
{
|
|
||||||
trace('Animation ' + id + ' not found');
|
trace('Animation ' + id + ' not found');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
this.currentAnimation = id;
|
||||||
anim.onComplete.removeAll();
|
anim.onComplete.removeAll();
|
||||||
anim.onComplete.add(function() {
|
anim.onComplete.add(function() {
|
||||||
if (loop)
|
_onAnimationComplete();
|
||||||
{
|
|
||||||
this.anim.play(id, restart, false, startFrame);
|
|
||||||
this.currentAnimation = id;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
onAnimationComplete.dispatch(id);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
looping = loop;
|
looping = loop;
|
||||||
|
|
@ -190,6 +185,14 @@ class FlxAtlasSprite extends FlxAnimate
|
||||||
// Move to the first frame of the animation.
|
// Move to the first frame of the animation.
|
||||||
// goToFrameLabel(id);
|
// goToFrameLabel(id);
|
||||||
trace('Playing animation $id');
|
trace('Playing animation $id');
|
||||||
|
if ((id == null || id == "") || this.anim.symbolDictionary.exists(id) || (this.anim.getByName(id) != null))
|
||||||
|
{
|
||||||
|
this.anim.play(id, restart, false, startFrame);
|
||||||
|
|
||||||
|
this.currentAnimation = anim.curSymbol.name;
|
||||||
|
|
||||||
|
fr = null;
|
||||||
|
}
|
||||||
// Only call goToFrameLabel if there is a frame label with that name. This prevents annoying warnings!
|
// Only call goToFrameLabel if there is a frame label with that name. This prevents annoying warnings!
|
||||||
if (getFrameLabelNames().indexOf(id) != -1)
|
if (getFrameLabelNames().indexOf(id) != -1)
|
||||||
{
|
{
|
||||||
|
|
@ -197,13 +200,6 @@ class FlxAtlasSprite extends FlxAnimate
|
||||||
fr = anim.getFrameLabel(id);
|
fr = anim.getFrameLabel(id);
|
||||||
anim.curFrame += startFrame;
|
anim.curFrame += startFrame;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
this.anim.play(id, restart, false, startFrame);
|
|
||||||
fr = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.currentAnimation = id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override public function update(elapsed:Float)
|
override public function update(elapsed:Float)
|
||||||
|
|
@ -301,12 +297,13 @@ class FlxAtlasSprite extends FlxAnimate
|
||||||
{
|
{
|
||||||
anim.pause();
|
anim.pause();
|
||||||
_onAnimationComplete();
|
_onAnimationComplete();
|
||||||
|
|
||||||
if (looping)
|
if (looping)
|
||||||
{
|
{
|
||||||
anim.curFrame = (fr != null) ? fr.index : 0;
|
anim.curFrame = (fr != null) ? fr.index : 0;
|
||||||
anim.resume();
|
anim.resume();
|
||||||
}
|
}
|
||||||
else
|
else if (fr != null && anim.curFrame != anim.length - 1)
|
||||||
{
|
{
|
||||||
anim.curFrame--;
|
anim.curFrame--;
|
||||||
}
|
}
|
||||||
|
|
@ -320,6 +317,10 @@ class FlxAtlasSprite extends FlxAnimate
|
||||||
{
|
{
|
||||||
onAnimationComplete.dispatch(currentAnimation);
|
onAnimationComplete.dispatch(currentAnimation);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
onAnimationComplete.dispatch('');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var prevFrames:Map<Int, FlxFrame> = [];
|
var prevFrames:Map<Int, FlxFrame> = [];
|
||||||
|
|
|
||||||
|
|
@ -395,9 +395,11 @@ class Controls extends FlxActionSet
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDialogueName(action:FlxActionDigital):String
|
public function getDialogueName(action:FlxActionDigital, ?ignoreSurrounding:Bool = false):String
|
||||||
{
|
{
|
||||||
var input = action.inputs[0];
|
var input = action.inputs[0];
|
||||||
|
if (ignoreSurrounding == false)
|
||||||
|
{
|
||||||
return switch (input.device)
|
return switch (input.device)
|
||||||
{
|
{
|
||||||
case KEYBOARD: return '[${(input.inputID : FlxKey)}]';
|
case KEYBOARD: return '[${(input.inputID : FlxKey)}]';
|
||||||
|
|
@ -405,10 +407,25 @@ class Controls extends FlxActionSet
|
||||||
case device: throw 'unhandled device: $device';
|
case device: throw 'unhandled device: $device';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
public function getDialogueNameFromToken(token:String):String
|
|
||||||
{
|
{
|
||||||
return getDialogueName(getActionFromControl(Control.createByName(token.toUpperCase())));
|
return switch (input.device)
|
||||||
|
{
|
||||||
|
case KEYBOARD: return '${(input.inputID : FlxKey)}';
|
||||||
|
case GAMEPAD: return '${(input.inputID : FlxGamepadInputID)}';
|
||||||
|
case device: throw 'unhandled device: $device';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDialogueNameFromToken(token:String, ?ignoreSurrounding:Bool = false):String
|
||||||
|
{
|
||||||
|
return getDialogueName(getActionFromControl(Control.createByName(token.toUpperCase())), ignoreSurrounding);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDialogueNameFromControl(control:Control, ?ignoreSurrounding:Bool = false):String
|
||||||
|
{
|
||||||
|
return getDialogueName(getActionFromControl(control), ignoreSurrounding);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getActionFromControl(control:Control):FlxActionDigital
|
function getActionFromControl(control:Control):FlxActionDigital
|
||||||
|
|
|
||||||
|
|
@ -194,6 +194,7 @@ class ResultState extends MusicBeatSubState
|
||||||
{
|
{
|
||||||
// Animation is not looped.
|
// Animation is not looped.
|
||||||
animation.onAnimationComplete.add((_name:String) -> {
|
animation.onAnimationComplete.add((_name:String) -> {
|
||||||
|
trace("AHAHAH 2");
|
||||||
if (animation != null)
|
if (animation != null)
|
||||||
{
|
{
|
||||||
animation.anim.pause();
|
animation.anim.pause();
|
||||||
|
|
@ -203,9 +204,10 @@ class ResultState extends MusicBeatSubState
|
||||||
else if (animData.loopFrameLabel != null)
|
else if (animData.loopFrameLabel != null)
|
||||||
{
|
{
|
||||||
animation.onAnimationComplete.add((_name:String) -> {
|
animation.onAnimationComplete.add((_name:String) -> {
|
||||||
|
trace("AHAHAH 2");
|
||||||
if (animation != null)
|
if (animation != null)
|
||||||
{
|
{
|
||||||
animation.playAnimation(animData.loopFrameLabel ?? ''); // unpauses this anim, since it's on PlayOnce!
|
animation.playAnimation(animData.loopFrameLabel ?? '', true, false, true); // unpauses this anim, since it's on PlayOnce!
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -214,6 +216,7 @@ class ResultState extends MusicBeatSubState
|
||||||
animation.onAnimationComplete.add((_name:String) -> {
|
animation.onAnimationComplete.add((_name:String) -> {
|
||||||
if (animation != null)
|
if (animation != null)
|
||||||
{
|
{
|
||||||
|
trace("AHAHAH");
|
||||||
animation.anim.curFrame = animData.loopFrame ?? 0;
|
animation.anim.curFrame = animData.loopFrame ?? 0;
|
||||||
animation.anim.play(); // unpauses this anim, since it's on PlayOnce!
|
animation.anim.play(); // unpauses this anim, since it's on PlayOnce!
|
||||||
}
|
}
|
||||||
|
|
@ -415,8 +418,7 @@ class ResultState extends MusicBeatSubState
|
||||||
{
|
{
|
||||||
startingVolume: 1.0,
|
startingVolume: 1.0,
|
||||||
overrideExisting: true,
|
overrideExisting: true,
|
||||||
restartTrack: true,
|
restartTrack: true
|
||||||
loop: rank.shouldMusicLoop()
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -426,8 +428,7 @@ class ResultState extends MusicBeatSubState
|
||||||
{
|
{
|
||||||
startingVolume: 1.0,
|
startingVolume: 1.0,
|
||||||
overrideExisting: true,
|
overrideExisting: true,
|
||||||
restartTrack: true,
|
restartTrack: true
|
||||||
loop: rank.shouldMusicLoop()
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -577,19 +577,6 @@ enum abstract ScoringRank(String)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function shouldMusicLoop():Bool
|
|
||||||
{
|
|
||||||
switch (abstract)
|
|
||||||
{
|
|
||||||
case PERFECT_GOLD | PERFECT | EXCELLENT | GREAT | GOOD:
|
|
||||||
return true;
|
|
||||||
case SHIT:
|
|
||||||
return false;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getHorTextAsset()
|
public function getHorTextAsset()
|
||||||
{
|
{
|
||||||
switch (abstract)
|
switch (abstract)
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,7 @@ class Save
|
||||||
autoPause: true,
|
autoPause: true,
|
||||||
inputOffset: 0,
|
inputOffset: 0,
|
||||||
audioVisualOffset: 0,
|
audioVisualOffset: 0,
|
||||||
|
unlockedFramerate: false,
|
||||||
|
|
||||||
controls:
|
controls:
|
||||||
{
|
{
|
||||||
|
|
@ -1180,6 +1181,12 @@ typedef SaveDataOptions =
|
||||||
*/
|
*/
|
||||||
var audioVisualOffset:Int;
|
var audioVisualOffset:Int;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If we want the framerate to be unlocked on HTML5.
|
||||||
|
* @default `false
|
||||||
|
*/
|
||||||
|
var unlockedFramerate:Bool;
|
||||||
|
|
||||||
var controls:
|
var controls:
|
||||||
{
|
{
|
||||||
var p1:
|
var p1:
|
||||||
|
|
|
||||||
|
|
@ -349,6 +349,9 @@ class CharSelectSubState extends MusicBeatSubState
|
||||||
// FlxG.camera.follow(camFollow, LOCKON, 0.01);
|
// FlxG.camera.follow(camFollow, LOCKON, 0.01);
|
||||||
FlxG.camera.follow(camFollow, LOCKON);
|
FlxG.camera.follow(camFollow, LOCKON);
|
||||||
|
|
||||||
|
var fadeShaderFilter:ShaderFilter = new ShaderFilter(fadeShader);
|
||||||
|
FlxG.camera.filters = [fadeShaderFilter];
|
||||||
|
|
||||||
var temp:FlxSprite = new FlxSprite();
|
var temp:FlxSprite = new FlxSprite();
|
||||||
temp.loadGraphic(Paths.image('charSelect/placement'));
|
temp.loadGraphic(Paths.image('charSelect/placement'));
|
||||||
add(temp);
|
add(temp);
|
||||||
|
|
@ -515,7 +518,7 @@ class CharSelectSubState extends MusicBeatSubState
|
||||||
|
|
||||||
syncLock = lock;
|
syncLock = lock;
|
||||||
|
|
||||||
// sync = true;
|
sync = true;
|
||||||
|
|
||||||
lock.onAnimationComplete.addOnce(function(_) {
|
lock.onAnimationComplete.addOnce(function(_) {
|
||||||
syncLock = null;
|
syncLock = null;
|
||||||
|
|
|
||||||
|
|
@ -8,20 +8,22 @@ import hxcodec.flixel.FlxVideoSprite;
|
||||||
#end
|
#end
|
||||||
import funkin.ui.MusicBeatSubState;
|
import funkin.ui.MusicBeatSubState;
|
||||||
import funkin.audio.FunkinSound;
|
import funkin.audio.FunkinSound;
|
||||||
|
import funkin.save.Save;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* After about 2 minutes of inactivity on the title screen,
|
* When you first enter the character select state, it will play an introductory video opening up the lights
|
||||||
* the game will enter the Attract state, as a reference to physical arcade machines.
|
|
||||||
*
|
|
||||||
* In the current version, this just plays the ~~Kickstarter trailer~~ Erect teaser, but this can be changed to
|
|
||||||
* gameplay footage, a generic game trailer, or something more elaborate.
|
|
||||||
*/
|
*/
|
||||||
class IntroSubState extends MusicBeatSubState
|
class IntroSubState extends MusicBeatSubState
|
||||||
{
|
{
|
||||||
static final ATTRACT_VIDEO_PATH:String = Paths.stripLibrary(Paths.videos('introSelect'));
|
static final LIGHTS_VIDEO_PATH:String = Paths.stripLibrary(Paths.videos('introSelect'));
|
||||||
|
|
||||||
public override function create():Void
|
public override function create():Void
|
||||||
{
|
{
|
||||||
|
if (Save.instance.oldChar)
|
||||||
|
{
|
||||||
|
onLightsEnd();
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Pause existing music.
|
// Pause existing music.
|
||||||
if (FlxG.sound.music != null)
|
if (FlxG.sound.music != null)
|
||||||
{
|
{
|
||||||
|
|
@ -30,14 +32,19 @@ class IntroSubState extends MusicBeatSubState
|
||||||
}
|
}
|
||||||
|
|
||||||
#if html5
|
#if html5
|
||||||
trace('Playing web video ${ATTRACT_VIDEO_PATH}');
|
trace('Playing web video ${LIGHTS_VIDEO_PATH}');
|
||||||
playVideoHTML5(ATTRACT_VIDEO_PATH);
|
playVideoHTML5(LIGHTS_VIDEO_PATH);
|
||||||
#end
|
#end
|
||||||
|
|
||||||
#if hxCodec
|
#if hxCodec
|
||||||
trace('Playing native video ${ATTRACT_VIDEO_PATH}');
|
trace('Playing native video ${LIGHTS_VIDEO_PATH}');
|
||||||
playVideoNative(ATTRACT_VIDEO_PATH);
|
playVideoNative(LIGHTS_VIDEO_PATH);
|
||||||
#end
|
#end
|
||||||
|
|
||||||
|
// Im TOO lazy to even care, so uh, yep
|
||||||
|
FlxG.camera.zoom = 0.66666666666666666666666666666667;
|
||||||
|
vid.x = -(FlxG.width - (FlxG.width * FlxG.camera.zoom));
|
||||||
|
vid.y = -((FlxG.height - (FlxG.height * FlxG.camera.zoom)) * 0.75);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if html5
|
#if html5
|
||||||
|
|
@ -53,7 +60,7 @@ class IntroSubState extends MusicBeatSubState
|
||||||
{
|
{
|
||||||
vid.zIndex = 0;
|
vid.zIndex = 0;
|
||||||
|
|
||||||
vid.finishCallback = onAttractEnd;
|
vid.finishCallback = onLightsEnd;
|
||||||
|
|
||||||
add(vid);
|
add(vid);
|
||||||
}
|
}
|
||||||
|
|
@ -77,7 +84,7 @@ class IntroSubState extends MusicBeatSubState
|
||||||
if (vid != null)
|
if (vid != null)
|
||||||
{
|
{
|
||||||
vid.zIndex = 0;
|
vid.zIndex = 0;
|
||||||
vid.bitmap.onEndReached.add(onAttractEnd);
|
vid.bitmap.onEndReached.add(onLightsEnd);
|
||||||
|
|
||||||
add(vid);
|
add(vid);
|
||||||
vid.play(filePath, false);
|
vid.play(filePath, false);
|
||||||
|
|
@ -93,37 +100,33 @@ class IntroSubState extends MusicBeatSubState
|
||||||
{
|
{
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
|
|
||||||
if (controls.ACCEPT)
|
// if (!introSound.paused)
|
||||||
{
|
// {
|
||||||
onAttractEnd();
|
// #if html5
|
||||||
}
|
// @:privateAccess
|
||||||
|
// vid.netStream.seek(introSound.time);
|
||||||
|
// #elseif hxCodec
|
||||||
|
// vid.bitmap.time = Std.int(introSound.time);
|
||||||
|
// #end
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When the attraction state ends (after the video ends or the user presses any button),
|
* When the lights video finishes, it will close the substate
|
||||||
* switch immediately to the title screen.
|
|
||||||
*/
|
*/
|
||||||
function onAttractEnd():Void
|
function onLightsEnd():Void
|
||||||
{
|
{
|
||||||
#if html5
|
|
||||||
if (vid != null)
|
if (vid != null)
|
||||||
{
|
{
|
||||||
remove(vid);
|
|
||||||
}
|
|
||||||
#end
|
|
||||||
|
|
||||||
#if hxCodec
|
#if hxCodec
|
||||||
if (vid != null)
|
|
||||||
{
|
|
||||||
vid.stop();
|
vid.stop();
|
||||||
remove(vid);
|
|
||||||
}
|
|
||||||
#end
|
#end
|
||||||
|
remove(vid);
|
||||||
#if (html5 || hxCodec)
|
|
||||||
vid.destroy();
|
vid.destroy();
|
||||||
vid = null;
|
vid = null;
|
||||||
#end
|
}
|
||||||
|
|
||||||
|
FlxG.camera.zoom = 1;
|
||||||
|
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,7 @@ class FreeplayDJ extends FlxAtlasSprite
|
||||||
}
|
}
|
||||||
else if (getCurrentAnimation() == animPrefixB)
|
else if (getCurrentAnimation() == animPrefixB)
|
||||||
{
|
{
|
||||||
|
trace("Loss Intro");
|
||||||
var endFrame = playableCharData.getFistPumpIntroBadEndFrame();
|
var endFrame = playableCharData.getFistPumpIntroBadEndFrame();
|
||||||
if (endFrame > -1 && anim.curFrame >= endFrame)
|
if (endFrame > -1 && anim.curFrame >= endFrame)
|
||||||
{
|
{
|
||||||
|
|
@ -166,6 +167,7 @@ class FreeplayDJ extends FlxAtlasSprite
|
||||||
}
|
}
|
||||||
else if (getCurrentAnimation() == animPrefixB)
|
else if (getCurrentAnimation() == animPrefixB)
|
||||||
{
|
{
|
||||||
|
trace("Loss GYATT");
|
||||||
var endFrame = playableCharData.getFistPumpLoopBadEndFrame();
|
var endFrame = playableCharData.getFistPumpLoopBadEndFrame();
|
||||||
if (endFrame > -1 && anim.curFrame >= endFrame)
|
if (endFrame > -1 && anim.curFrame >= endFrame)
|
||||||
{
|
{
|
||||||
|
|
@ -375,6 +377,13 @@ class FreeplayDJ extends FlxAtlasSprite
|
||||||
|
|
||||||
public function confirm():Void
|
public function confirm():Void
|
||||||
{
|
{
|
||||||
|
// We really don't want to play anything but the new character animation here.
|
||||||
|
if (PlayerRegistry.instance.hasNewCharacter())
|
||||||
|
{
|
||||||
|
currentState = NewUnlock;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
currentState = Confirm;
|
currentState = Confirm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -397,6 +406,13 @@ class FreeplayDJ extends FlxAtlasSprite
|
||||||
|
|
||||||
public function fistPumpIntro():Void
|
public function fistPumpIntro():Void
|
||||||
{
|
{
|
||||||
|
// We really don't want to play anything but the new character animation here.
|
||||||
|
if (PlayerRegistry.instance.hasNewCharacter())
|
||||||
|
{
|
||||||
|
currentState = NewUnlock;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
currentState = FistPumpIntro;
|
currentState = FistPumpIntro;
|
||||||
var animPrefix = playableCharData.getAnimationPrefix('fistPump');
|
var animPrefix = playableCharData.getAnimationPrefix('fistPump');
|
||||||
playFlashAnimation(animPrefix, true, false, false, playableCharData.getFistPumpIntroStartFrame());
|
playFlashAnimation(animPrefix, true, false, false, playableCharData.getFistPumpIntroStartFrame());
|
||||||
|
|
@ -404,6 +420,13 @@ class FreeplayDJ extends FlxAtlasSprite
|
||||||
|
|
||||||
public function fistPump():Void
|
public function fistPump():Void
|
||||||
{
|
{
|
||||||
|
// We really don't want to play anything but the new character animation here.
|
||||||
|
if (PlayerRegistry.instance.hasNewCharacter())
|
||||||
|
{
|
||||||
|
currentState = NewUnlock;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
currentState = FistPump;
|
currentState = FistPump;
|
||||||
var animPrefix = playableCharData.getAnimationPrefix('fistPump');
|
var animPrefix = playableCharData.getAnimationPrefix('fistPump');
|
||||||
playFlashAnimation(animPrefix, true, false, false, playableCharData.getFistPumpLoopStartFrame());
|
playFlashAnimation(animPrefix, true, false, false, playableCharData.getFistPumpLoopStartFrame());
|
||||||
|
|
@ -411,6 +434,13 @@ class FreeplayDJ extends FlxAtlasSprite
|
||||||
|
|
||||||
public function fistPumpLossIntro():Void
|
public function fistPumpLossIntro():Void
|
||||||
{
|
{
|
||||||
|
// We really don't want to play anything but the new character animation here.
|
||||||
|
if (PlayerRegistry.instance.hasNewCharacter())
|
||||||
|
{
|
||||||
|
currentState = NewUnlock;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
currentState = FistPumpIntro;
|
currentState = FistPumpIntro;
|
||||||
var animPrefix = playableCharData.getAnimationPrefix('loss');
|
var animPrefix = playableCharData.getAnimationPrefix('loss');
|
||||||
playFlashAnimation(animPrefix, true, false, false, playableCharData.getFistPumpIntroBadStartFrame());
|
playFlashAnimation(animPrefix, true, false, false, playableCharData.getFistPumpIntroBadStartFrame());
|
||||||
|
|
@ -418,6 +448,13 @@ class FreeplayDJ extends FlxAtlasSprite
|
||||||
|
|
||||||
public function fistPumpLoss():Void
|
public function fistPumpLoss():Void
|
||||||
{
|
{
|
||||||
|
// We really don't want to play anything but the new character animation here.
|
||||||
|
if (PlayerRegistry.instance.hasNewCharacter())
|
||||||
|
{
|
||||||
|
currentState = NewUnlock;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
currentState = FistPump;
|
currentState = FistPump;
|
||||||
var animPrefix = playableCharData.getAnimationPrefix('loss');
|
var animPrefix = playableCharData.getAnimationPrefix('loss');
|
||||||
playFlashAnimation(animPrefix, true, false, false, playableCharData.getFistPumpLoopBadStartFrame());
|
playFlashAnimation(animPrefix, true, false, false, playableCharData.getFistPumpLoopBadStartFrame());
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import flixel.group.FlxGroup.FlxTypedGroup;
|
||||||
import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup;
|
import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup;
|
||||||
import flixel.input.touch.FlxTouch;
|
import flixel.input.touch.FlxTouch;
|
||||||
import flixel.math.FlxAngle;
|
import flixel.math.FlxAngle;
|
||||||
|
import flixel.math.FlxMath;
|
||||||
import flixel.math.FlxPoint;
|
import flixel.math.FlxPoint;
|
||||||
import flixel.system.debug.watch.Tracker.TrackerProfile;
|
import flixel.system.debug.watch.Tracker.TrackerProfile;
|
||||||
import flixel.text.FlxText;
|
import flixel.text.FlxText;
|
||||||
|
|
@ -180,6 +181,8 @@ class FreeplayState extends MusicBeatSubState
|
||||||
var ostName:FlxText;
|
var ostName:FlxText;
|
||||||
var albumRoll:AlbumRoll;
|
var albumRoll:AlbumRoll;
|
||||||
|
|
||||||
|
var charSelectHint:FlxText;
|
||||||
|
|
||||||
var letterSort:LetterSort;
|
var letterSort:LetterSort;
|
||||||
var exitMovers:ExitMoverData = new Map();
|
var exitMovers:ExitMoverData = new Map();
|
||||||
|
|
||||||
|
|
@ -279,6 +282,7 @@ class FreeplayState extends MusicBeatSubState
|
||||||
txtCompletion = new AtlasText(1185, 87, '69', AtlasFont.FREEPLAY_CLEAR);
|
txtCompletion = new AtlasText(1185, 87, '69', AtlasFont.FREEPLAY_CLEAR);
|
||||||
|
|
||||||
ostName = new FlxText(8, 8, FlxG.width - 8 - 8, 'OFFICIAL OST', 48);
|
ostName = new FlxText(8, 8, FlxG.width - 8 - 8, 'OFFICIAL OST', 48);
|
||||||
|
charSelectHint = new FlxText(-40, 18, FlxG.width - 8 - 8, 'Press [ LOL ] to change characters', 32);
|
||||||
|
|
||||||
bgDad = new FlxSprite(backingCard.pinkBack.width * 0.74, 0).loadGraphic(styleData == null ? 'freeplay/freeplayBGdad' : styleData.getBgAssetGraphic());
|
bgDad = new FlxSprite(backingCard.pinkBack.width * 0.74, 0).loadGraphic(styleData == null ? 'freeplay/freeplayBGdad' : styleData.getBgAssetGraphic());
|
||||||
}
|
}
|
||||||
|
|
@ -354,10 +358,6 @@ class FreeplayState extends MusicBeatSubState
|
||||||
if (availableDifficultiesForSong.length == 0) continue;
|
if (availableDifficultiesForSong.length == 0) continue;
|
||||||
|
|
||||||
songs.push(new FreeplaySongData(levelId, songId, song, displayedVariations));
|
songs.push(new FreeplaySongData(levelId, songId, song, displayedVariations));
|
||||||
for (difficulty in availableDifficultiesForSong)
|
|
||||||
{
|
|
||||||
diffIdsTotal.pushUnique(difficulty);
|
|
||||||
}
|
|
||||||
for (difficulty in unsuffixedDifficulties)
|
for (difficulty in unsuffixedDifficulties)
|
||||||
{
|
{
|
||||||
diffIdsTotal.pushUnique(difficulty);
|
diffIdsTotal.pushUnique(difficulty);
|
||||||
|
|
@ -498,7 +498,14 @@ class FreeplayState extends MusicBeatSubState
|
||||||
ostName.alignment = RIGHT;
|
ostName.alignment = RIGHT;
|
||||||
ostName.visible = false;
|
ostName.visible = false;
|
||||||
|
|
||||||
exitMovers.set([overhangStuff, fnfFreeplay, ostName],
|
charSelectHint.alignment = CENTER;
|
||||||
|
charSelectHint.font = "5by7";
|
||||||
|
charSelectHint.color = 0xFF5F5F5F;
|
||||||
|
charSelectHint.text = 'Press [ ${controls.getDialogueNameFromControl(FREEPLAY_CHAR_SELECT, true)} ] to change characters';
|
||||||
|
charSelectHint.y -= 100;
|
||||||
|
FlxTween.tween(charSelectHint, {y: charSelectHint.y + 100}, 0.8, {ease: FlxEase.quartOut});
|
||||||
|
|
||||||
|
exitMovers.set([overhangStuff, fnfFreeplay, ostName, charSelectHint],
|
||||||
{
|
{
|
||||||
y: -overhangStuff.height,
|
y: -overhangStuff.height,
|
||||||
x: 0,
|
x: 0,
|
||||||
|
|
@ -506,7 +513,7 @@ class FreeplayState extends MusicBeatSubState
|
||||||
wait: 0
|
wait: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
exitMoversCharSel.set([overhangStuff, fnfFreeplay, ostName],
|
exitMoversCharSel.set([overhangStuff, fnfFreeplay, ostName, charSelectHint],
|
||||||
{
|
{
|
||||||
y: -300,
|
y: -300,
|
||||||
speed: 0.8,
|
speed: 0.8,
|
||||||
|
|
@ -604,6 +611,11 @@ class FreeplayState extends MusicBeatSubState
|
||||||
add(fnfFreeplay);
|
add(fnfFreeplay);
|
||||||
add(ostName);
|
add(ostName);
|
||||||
|
|
||||||
|
if (PlayerRegistry.instance.hasNewCharacter() == true)
|
||||||
|
{
|
||||||
|
add(charSelectHint);
|
||||||
|
}
|
||||||
|
|
||||||
// be careful not to "add()" things in here unless it's to a group that's already added to the state
|
// be careful not to "add()" things in here unless it's to a group that's already added to the state
|
||||||
// otherwise it won't be properly attatched to funnyCamera (relavent code should be at the bottom of create())
|
// otherwise it won't be properly attatched to funnyCamera (relavent code should be at the bottom of create())
|
||||||
var onDJIntroDone = function() {
|
var onDJIntroDone = function() {
|
||||||
|
|
@ -1348,10 +1360,19 @@ class FreeplayState extends MusicBeatSubState
|
||||||
|
|
||||||
var originalPos:FlxPoint = new FlxPoint();
|
var originalPos:FlxPoint = new FlxPoint();
|
||||||
|
|
||||||
|
var hintTimer:Float = 0;
|
||||||
|
|
||||||
override function update(elapsed:Float):Void
|
override function update(elapsed:Float):Void
|
||||||
{
|
{
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
|
|
||||||
|
if (charSelectHint != null)
|
||||||
|
{
|
||||||
|
hintTimer += elapsed * 2;
|
||||||
|
var targetAmt:Float = (Math.sin(hintTimer) + 1) / 2;
|
||||||
|
charSelectHint.alpha = FlxMath.lerp(0.3, 0.9, targetAmt);
|
||||||
|
}
|
||||||
|
|
||||||
#if FEATURE_DEBUG_FUNCTIONS
|
#if FEATURE_DEBUG_FUNCTIONS
|
||||||
if (FlxG.keys.justPressed.P)
|
if (FlxG.keys.justPressed.P)
|
||||||
{
|
{
|
||||||
|
|
@ -1764,12 +1785,13 @@ class FreeplayState extends MusicBeatSubState
|
||||||
var songScore:Null<SaveScoreData> = Save.instance.getSongScore(daSong.songId, suffixedDifficulty);
|
var songScore:Null<SaveScoreData> = Save.instance.getSongScore(daSong.songId, suffixedDifficulty);
|
||||||
intendedScore = songScore?.score ?? 0;
|
intendedScore = songScore?.score ?? 0;
|
||||||
intendedCompletion = songScore == null ? 0.0 : ((songScore.tallies.sick + songScore.tallies.good) / songScore.tallies.totalNotes);
|
intendedCompletion = songScore == null ? 0.0 : ((songScore.tallies.sick + songScore.tallies.good) / songScore.tallies.totalNotes);
|
||||||
rememberedDifficulty = currentDifficulty;
|
rememberedDifficulty = suffixedDifficulty;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
intendedScore = 0;
|
intendedScore = 0;
|
||||||
intendedCompletion = 0.0;
|
intendedCompletion = 0.0;
|
||||||
|
rememberedDifficulty = currentDifficulty;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (intendedCompletion == Math.POSITIVE_INFINITY || intendedCompletion == Math.NEGATIVE_INFINITY || Math.isNaN(intendedCompletion))
|
if (intendedCompletion == Math.POSITIVE_INFINITY || intendedCompletion == Math.NEGATIVE_INFINITY || Math.isNaN(intendedCompletion))
|
||||||
|
|
|
||||||
|
|
@ -358,6 +358,7 @@ class MainMenuState extends MusicBeatState
|
||||||
// Ctrl+Alt+Shift+W = Meet requirements for Pico Unlock
|
// Ctrl+Alt+Shift+W = Meet requirements for Pico Unlock
|
||||||
// Ctrl+Alt+Shift+L = Revoke requirements for Pico Unlock
|
// Ctrl+Alt+Shift+L = Revoke requirements for Pico Unlock
|
||||||
// Ctrl+Alt+Shift+R = Score/Rank conflict test
|
// Ctrl+Alt+Shift+R = Score/Rank conflict test
|
||||||
|
// Ctrl+Alt+Shift+N = Mark all characters as not seen
|
||||||
// Ctrl+Alt+Shift+E = Dump save data
|
// Ctrl+Alt+Shift+E = Dump save data
|
||||||
|
|
||||||
if (FlxG.keys.pressed.CONTROL && FlxG.keys.pressed.ALT && FlxG.keys.pressed.SHIFT && FlxG.keys.justPressed.P)
|
if (FlxG.keys.pressed.CONTROL && FlxG.keys.pressed.ALT && FlxG.keys.pressed.SHIFT && FlxG.keys.justPressed.P)
|
||||||
|
|
@ -433,6 +434,15 @@ class MainMenuState extends MusicBeatState
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (FlxG.keys.pressed.CONTROL && FlxG.keys.pressed.ALT && FlxG.keys.pressed.SHIFT && FlxG.keys.justPressed.N)
|
||||||
|
{
|
||||||
|
@:privateAccess
|
||||||
|
{
|
||||||
|
funkin.save.Save.instance.data.unlocks.charactersSeen = ["bf"];
|
||||||
|
funkin.save.Save.instance.data.unlocks.oldChar = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (FlxG.keys.pressed.CONTROL && FlxG.keys.pressed.ALT && FlxG.keys.pressed.SHIFT && FlxG.keys.justPressed.E)
|
if (FlxG.keys.pressed.CONTROL && FlxG.keys.pressed.ALT && FlxG.keys.pressed.SHIFT && FlxG.keys.justPressed.E)
|
||||||
{
|
{
|
||||||
funkin.save.Save.instance.debug_dumpSave();
|
funkin.save.Save.instance.debug_dumpSave();
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,12 @@ class PreferencesMenu extends Page
|
||||||
createPrefItemCheckbox('Auto Pause', 'Automatically pause the game when it loses focus', function(value:Bool):Void {
|
createPrefItemCheckbox('Auto Pause', 'Automatically pause the game when it loses focus', function(value:Bool):Void {
|
||||||
Preferences.autoPause = value;
|
Preferences.autoPause = value;
|
||||||
}, Preferences.autoPause);
|
}, Preferences.autoPause);
|
||||||
|
|
||||||
|
#if web
|
||||||
|
createPrefItemCheckbox('Unlocked Framerate', 'Enable to unlock the framerate', function(value:Bool):Void {
|
||||||
|
Preferences.unlockedFramerate = value;
|
||||||
|
}, Preferences.unlockedFramerate);
|
||||||
|
#end
|
||||||
}
|
}
|
||||||
|
|
||||||
override function update(elapsed:Float):Void
|
override function update(elapsed:Float):Void
|
||||||
|
|
|
||||||
|
|
@ -273,8 +273,11 @@ class TitleState extends MusicBeatState
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
|
|
||||||
if (Save.instance.charactersSeen.contains("pico")) Save.instance.charactersSeen.remove("pico");
|
if (Save.instance.charactersSeen.contains("pico"))
|
||||||
|
{
|
||||||
|
Save.instance.charactersSeen.remove("pico");
|
||||||
|
Save.instance.oldChar = false;
|
||||||
|
}
|
||||||
Conductor.instance.update();
|
Conductor.instance.update();
|
||||||
|
|
||||||
/* if (FlxG.onMobile)
|
/* if (FlxG.onMobile)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue