mirror of
https://github.com/FunkinCrew/Funkin.git
synced 2024-11-23 08:07:54 -05:00
Merge branch 'rewrite/master' into bugfix/chart-editor-vocal-crash
This commit is contained in:
commit
3aa4c23340
10 changed files with 162 additions and 94 deletions
|
@ -23,10 +23,10 @@
|
|||
},
|
||||
{
|
||||
"props": {
|
||||
"allowSingleArgParens": false,
|
||||
"allowReturn": false,
|
||||
"allowFunction": false,
|
||||
"allowCurlyBody": false
|
||||
"allowSingleArgParens": true,
|
||||
"allowReturn": true,
|
||||
"allowFunction": true,
|
||||
"allowCurlyBody": true
|
||||
},
|
||||
"type": "ArrowFunction"
|
||||
},
|
||||
|
@ -80,7 +80,7 @@
|
|||
"props": {
|
||||
"ignoreExtern": true,
|
||||
"format": "^[A-Z][A-Z0-9]*(_[A-Z0-9_]+)*$",
|
||||
"tokens": []
|
||||
"tokens": ["INLINE", "NOTINLINE"]
|
||||
},
|
||||
"type": "ConstantName"
|
||||
},
|
||||
|
@ -178,13 +178,7 @@
|
|||
"fieldType": "BOTH",
|
||||
"requireReturn": true,
|
||||
"ignoreOverride": true,
|
||||
"tokens": [
|
||||
"ABSTRACT_DEF",
|
||||
"CLASS_DEF",
|
||||
"ENUM_DEF",
|
||||
"INTERFACE_DEF",
|
||||
"TYPEDEF_DEF"
|
||||
],
|
||||
"tokens": ["ABSTRACT_DEF", "CLASS_DEF", "ENUM_DEF", "INTERFACE_DEF"],
|
||||
"modifier": "PUBLIC",
|
||||
"excludeNames": ["new", "toString"]
|
||||
},
|
||||
|
@ -198,10 +192,6 @@
|
|||
},
|
||||
"type": "FileLength"
|
||||
},
|
||||
{
|
||||
"props": {},
|
||||
"type": "Final"
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"option": "upperCase"
|
||||
|
@ -375,7 +365,7 @@
|
|||
},
|
||||
{
|
||||
"props": {
|
||||
"max": 1
|
||||
"max": 4
|
||||
},
|
||||
"type": "NestedIfDepth"
|
||||
},
|
||||
|
@ -387,7 +377,7 @@
|
|||
},
|
||||
{
|
||||
"props": {
|
||||
"option": "nullDefault"
|
||||
"option": "questionMark"
|
||||
},
|
||||
"type": "NullableParameter"
|
||||
},
|
||||
|
@ -396,7 +386,6 @@
|
|||
"oldFunctionTypePolicy": "none",
|
||||
"unaryOpPolicy": "none",
|
||||
"intervalOpPolicy": "none",
|
||||
|
||||
"newFunctionTypePolicy": "around",
|
||||
"ternaryOpPolicy": "around",
|
||||
"boolOpPolicy": "around",
|
||||
|
@ -589,19 +578,7 @@
|
|||
},
|
||||
{
|
||||
"props": {
|
||||
"ignoreEnumAbstractValues": true
|
||||
},
|
||||
"type": "Type"
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"tokens": [
|
||||
"ABSTRACT_DEF",
|
||||
"CLASS_DEF",
|
||||
"ENUM_DEF",
|
||||
"INTERFACE_DEF",
|
||||
"TYPEDEF_DEF"
|
||||
]
|
||||
"tokens": ["CLASS_DEF", "ENUM_DEF", "INTERFACE_DEF", "TYPEDEF_DEF"]
|
||||
},
|
||||
"type": "TypeDocComment"
|
||||
},
|
||||
|
@ -630,12 +607,6 @@
|
|||
},
|
||||
"type": "UnusedLocalVar"
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"severity": "IGNORE"
|
||||
},
|
||||
"type": "VariableInitialisation"
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"typeHintPolicy": "enforce_all",
|
||||
|
|
|
@ -1,31 +1,30 @@
|
|||
{
|
||||
"disableFormatting": false,
|
||||
|
||||
"indentation": {
|
||||
"character": " ",
|
||||
"tabWidth": 2,
|
||||
"indentCaseLabels": true
|
||||
},
|
||||
|
||||
"lineEnds": {
|
||||
"anonFunctionCurly": {
|
||||
"emptyCurly": "break",
|
||||
"leftCurly": "after",
|
||||
"rightCurly": "both"
|
||||
},
|
||||
"leftCurly": "both",
|
||||
"rightCurly": "both"
|
||||
},
|
||||
|
||||
"sameLine": {
|
||||
"ifBody": "same",
|
||||
"ifElse": "next",
|
||||
"doWhile": "next",
|
||||
"tryBody": "next",
|
||||
"tryCatch": "next"
|
||||
},
|
||||
|
||||
"whitespace": {
|
||||
"switchPolicy": "around"
|
||||
}
|
||||
}
|
||||
{
|
||||
"disableFormatting": false,
|
||||
|
||||
"indentation": {
|
||||
"character": " ",
|
||||
"tabWidth": 2,
|
||||
"indentCaseLabels": true
|
||||
},
|
||||
"lineEnds": {
|
||||
"anonFunctionCurly": {
|
||||
"emptyCurly": "break",
|
||||
"leftCurly": "after",
|
||||
"rightCurly": "both"
|
||||
},
|
||||
"leftCurly": "both",
|
||||
"rightCurly": "both"
|
||||
},
|
||||
|
||||
"sameLine": {
|
||||
"ifBody": "same",
|
||||
"ifElse": "next",
|
||||
"doWhile": "next",
|
||||
"tryBody": "next",
|
||||
"tryCatch": "next"
|
||||
},
|
||||
|
||||
"whitespace": {
|
||||
"switchPolicy": "around"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,42 @@ package funkin;
|
|||
*/
|
||||
class Highscore
|
||||
{
|
||||
/**
|
||||
* Keeps track of notes hit for the current song
|
||||
* and how accurate you were with each note (bad, missed, shit, etc.)
|
||||
*/
|
||||
public static var tallies:Tallies = new Tallies();
|
||||
|
||||
/**
|
||||
* Keeps track of notes hit for the current WEEK / level
|
||||
* for use with storymode, or likely any other "playlist" esque option
|
||||
*/
|
||||
public static var talliesLevel:Tallies = new Tallies();
|
||||
|
||||
/**
|
||||
* Produces a new Tallies object which represents the sum of two existing Tallies
|
||||
* @param newTally The first tally
|
||||
* @param baseTally The second tally
|
||||
* @return The combined tally
|
||||
*/
|
||||
public static function combineTallies(newTally:Tallies, baseTally:Tallies):Tallies
|
||||
{
|
||||
var combinedTally:Tallies = new Tallies();
|
||||
combinedTally.missed = newTally.missed + baseTally.missed;
|
||||
combinedTally.shit = newTally.shit + baseTally.shit;
|
||||
combinedTally.bad = newTally.bad + baseTally.bad;
|
||||
combinedTally.good = newTally.good + baseTally.good;
|
||||
combinedTally.sick = newTally.sick + baseTally.sick;
|
||||
combinedTally.totalNotes = newTally.totalNotes + baseTally.totalNotes;
|
||||
combinedTally.totalNotesHit = newTally.totalNotesHit + baseTally.totalNotesHit;
|
||||
|
||||
// Current combo = use most recent.
|
||||
combinedTally.combo = newTally.combo;
|
||||
// Max combo = use maximum value.
|
||||
combinedTally.maxCombo = Std.int(Math.max(newTally.maxCombo, baseTally.maxCombo));
|
||||
|
||||
return combinedTally;
|
||||
}
|
||||
}
|
||||
|
||||
@:forward
|
||||
|
@ -29,6 +64,9 @@ abstract Tallies(RawTallies)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A structure object containing the data for highscore tallies.
|
||||
*/
|
||||
typedef RawTallies =
|
||||
{
|
||||
var combo:Int;
|
||||
|
@ -51,7 +89,7 @@ typedef RawTallies =
|
|||
var totalNotesHit:Int;
|
||||
|
||||
/**
|
||||
* How many notes PASSED BY AND/OR HIT!!!
|
||||
* How many notes in the current chart
|
||||
*/
|
||||
var totalNotes:Int;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import funkin.util.CLIUtil;
|
|||
import funkin.util.CLIUtil.CLIParams;
|
||||
import funkin.util.tools.TimerTools;
|
||||
import funkin.ui.transition.LoadingState;
|
||||
import funkin.util.TrackerUtil;
|
||||
#if discord_rpc
|
||||
import Discord.DiscordClient;
|
||||
#end
|
||||
|
@ -67,7 +68,7 @@ class InitState extends FlxState
|
|||
/**
|
||||
* Setup a bunch of important Flixel stuff.
|
||||
*/
|
||||
function setupShit()
|
||||
function setupShit():Void
|
||||
{
|
||||
//
|
||||
// GAME SETUP
|
||||
|
@ -95,7 +96,7 @@ class InitState extends FlxState
|
|||
#if (debug || FORCE_DEBUG_VERSION)
|
||||
// Disable using ~ to open the console (we use that for the Editor menu)
|
||||
FlxG.debugger.toggleKeys = [F2];
|
||||
|
||||
TrackerUtil.initTrackers();
|
||||
// Adds an additional Close Debugger button.
|
||||
// This big obnoxious white button is for MOBILE, so that you can press it
|
||||
// easily with your finger when debug bullshit pops up during testing lol!
|
||||
|
|
|
@ -90,6 +90,11 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
|
|||
*/
|
||||
var _label:String = "unknown";
|
||||
|
||||
/**
|
||||
* Whether we received a focus lost event.
|
||||
*/
|
||||
var _lostFocus:Bool = false;
|
||||
|
||||
public function new()
|
||||
{
|
||||
super();
|
||||
|
@ -167,8 +172,18 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
|
|||
|
||||
public override function pause():FunkinSound
|
||||
{
|
||||
super.pause();
|
||||
this._shouldPlay = false;
|
||||
if (_shouldPlay)
|
||||
{
|
||||
// This sound will eventually play, but is still at a negative timestamp.
|
||||
// Manually set the paused flag to ensure proper focus/unfocus behavior.
|
||||
_shouldPlay = false;
|
||||
_paused = true;
|
||||
active = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
super.pause();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -177,7 +192,10 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
|
|||
*/
|
||||
override function onFocus():Void
|
||||
{
|
||||
if (!_alreadyPaused)
|
||||
// Flixel can sometimes toss spurious `onFocus` events, e.g. if the Flixel debugger is toggled
|
||||
// on and off. We only want to resume the sound if we actually lost focus, and if we weren't
|
||||
// already paused before we lost focus.
|
||||
if (_lostFocus && !_alreadyPaused)
|
||||
{
|
||||
resume();
|
||||
}
|
||||
|
@ -185,6 +203,7 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
|
|||
{
|
||||
trace('Not resuming audio on focus!');
|
||||
}
|
||||
_lostFocus = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -193,6 +212,7 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
|
|||
override function onFocusLost():Void
|
||||
{
|
||||
trace('Focus lost, pausing audio!');
|
||||
_lostFocus = true;
|
||||
_alreadyPaused = _paused;
|
||||
pause();
|
||||
}
|
||||
|
@ -201,7 +221,10 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
|
|||
{
|
||||
if (this._time < 0)
|
||||
{
|
||||
this._shouldPlay = true;
|
||||
// Sound with negative timestamp, restart the timer.
|
||||
_shouldPlay = true;
|
||||
_paused = false;
|
||||
active = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -106,6 +106,8 @@ class SongMetadata implements ICloneable<SongMetadata>
|
|||
|
||||
/**
|
||||
* Serialize this SongMetadata into a JSON string.
|
||||
* @param pretty Whether the JSON should be big ol string (false),
|
||||
* or formatted with tabs (true)
|
||||
* @return The JSON string.
|
||||
*/
|
||||
public function serialize(pretty:Bool = true):String
|
||||
|
|
|
@ -1732,7 +1732,6 @@ class PlayState extends MusicBeatSubState
|
|||
if (strumTime < startTime) continue; // Skip notes that are before the start time.
|
||||
|
||||
var noteData:Int = songNote.getDirection();
|
||||
|
||||
var playerNote:Bool = true;
|
||||
|
||||
if (noteData > 3) playerNote = false;
|
||||
|
@ -1741,6 +1740,8 @@ class PlayState extends MusicBeatSubState
|
|||
{
|
||||
case 0:
|
||||
playerNoteData.push(songNote);
|
||||
// increment totalNotes for total possible notes able to be hit by the player
|
||||
Highscore.tallies.totalNotes++;
|
||||
case 1:
|
||||
opponentNoteData.push(songNote);
|
||||
}
|
||||
|
@ -2622,6 +2623,9 @@ class PlayState extends MusicBeatSubState
|
|||
accuracy: Highscore.tallies.totalNotesHit / Highscore.tallies.totalNotes,
|
||||
};
|
||||
|
||||
// adds current song data into the tallies for the level (story levels)
|
||||
Highscore.talliesLevel = Highscore.combineTallies(Highscore.tallies, Highscore.talliesLevel);
|
||||
|
||||
if (Save.instance.isSongHighScore(currentSong.id, currentDifficulty, data))
|
||||
{
|
||||
Save.instance.setSongScore(currentSong.id, currentDifficulty, data);
|
||||
|
@ -2895,11 +2899,14 @@ class PlayState extends MusicBeatSubState
|
|||
persistentUpdate = false;
|
||||
vocals.stop();
|
||||
camHUD.alpha = 1;
|
||||
|
||||
var talliesToUse:Tallies = PlayStatePlaylist.isStoryMode ? Highscore.talliesLevel : Highscore.tallies;
|
||||
|
||||
var res:ResultState = new ResultState(
|
||||
{
|
||||
storyMode: PlayStatePlaylist.isStoryMode,
|
||||
title: PlayStatePlaylist.isStoryMode ? ('${PlayStatePlaylist.campaignTitle}') : ('${currentChart.songName} by ${currentChart.songArtist}'),
|
||||
tallies: Highscore.tallies,
|
||||
tallies: talliesToUse,
|
||||
});
|
||||
res.camera = camHUD;
|
||||
openSubState(res);
|
||||
|
|
|
@ -2,27 +2,25 @@ package funkin.play;
|
|||
|
||||
import funkin.ui.story.StoryMenuState;
|
||||
import funkin.graphics.adobeanimate.FlxAtlasSprite;
|
||||
import flixel.FlxBasic;
|
||||
import flixel.FlxSprite;
|
||||
import funkin.graphics.FunkinSprite;
|
||||
import flixel.graphics.frames.FlxAtlasFrames;
|
||||
import flixel.graphics.frames.FlxBitmapFont;
|
||||
import flixel.group.FlxGroup.FlxTypedGroup;
|
||||
import flixel.math.FlxPoint;
|
||||
import funkin.ui.MusicBeatSubState;
|
||||
import flixel.math.FlxRect;
|
||||
import flixel.text.FlxBitmapText;
|
||||
import flixel.text.FlxText;
|
||||
import flixel.tweens.FlxEase;
|
||||
import funkin.ui.freeplay.FreeplayState;
|
||||
import flixel.tweens.FlxTween;
|
||||
import flixel.util.FlxColor;
|
||||
import flixel.util.FlxGradient;
|
||||
import flixel.util.FlxTimer;
|
||||
import funkin.graphics.shaders.LeftMaskShader;
|
||||
import funkin.play.components.TallyCounter;
|
||||
import flxanimate.FlxAnimate.Settings;
|
||||
|
||||
/**
|
||||
* The state for the results screen after a song or week is finished.
|
||||
*/
|
||||
class ResultState extends MusicBeatSubState
|
||||
{
|
||||
final params:ResultsStateParams;
|
||||
|
@ -31,8 +29,8 @@ class ResultState extends MusicBeatSubState
|
|||
var songName:FlxBitmapText;
|
||||
var difficulty:FlxSprite;
|
||||
|
||||
var maskShaderSongName = new LeftMaskShader();
|
||||
var maskShaderDifficulty = new LeftMaskShader();
|
||||
var maskShaderSongName:LeftMaskShader = new LeftMaskShader();
|
||||
var maskShaderDifficulty:LeftMaskShader = new LeftMaskShader();
|
||||
|
||||
public function new(params:ResultsStateParams)
|
||||
{
|
||||
|
@ -50,22 +48,22 @@ class ResultState extends MusicBeatSubState
|
|||
else
|
||||
resultsVariation = NORMAL;
|
||||
|
||||
var loops = resultsVariation != SHIT;
|
||||
var loops:Bool = resultsVariation != SHIT;
|
||||
|
||||
FlxG.sound.playMusic(Paths.music("results" + resultsVariation), 1, loops);
|
||||
|
||||
// TEMP-ish, just used to sorta "cache" the 3000x3000 image!
|
||||
var cacheBullShit = new FlxSprite().loadGraphic(Paths.image("resultScreen/soundSystem"));
|
||||
var cacheBullShit:FlxSprite = new FlxSprite().loadGraphic(Paths.image("resultScreen/soundSystem"));
|
||||
add(cacheBullShit);
|
||||
|
||||
var dumb = new FlxSprite().loadGraphic(Paths.image("resultScreen/scorePopin"));
|
||||
var dumb:FlxSprite = new FlxSprite().loadGraphic(Paths.image("resultScreen/scorePopin"));
|
||||
add(dumb);
|
||||
|
||||
var bg:FlxSprite = FlxGradient.createGradientFlxSprite(FlxG.width, FlxG.height, [0xFFFECC5C, 0xFFFDC05C], 90);
|
||||
bg.scrollFactor.set();
|
||||
add(bg);
|
||||
|
||||
var bgFlash:FlxSprite = FlxGradient.createGradientFlxSprite(FlxG.width, FlxG.height, [0xFFffeb69, 0xFFffe66a], 90);
|
||||
var bgFlash:FlxSprite = FlxGradient.createGradientFlxSprite(FlxG.width, FlxG.height, [0xFFFFEB69, 0xFFFFE66A], 90);
|
||||
bgFlash.scrollFactor.set();
|
||||
bgFlash.visible = false;
|
||||
add(bgFlash);
|
||||
|
@ -188,6 +186,10 @@ class ResultState extends MusicBeatSubState
|
|||
var ratingGrp:FlxTypedGroup<TallyCounter> = new FlxTypedGroup<TallyCounter>();
|
||||
add(ratingGrp);
|
||||
|
||||
/**
|
||||
* NOTE: We display how many notes were HIT, not how many notes there were in total.
|
||||
*
|
||||
*/
|
||||
var totalHit:TallyCounter = new TallyCounter(375, hStuf * 3, params.tallies.totalNotesHit);
|
||||
ratingGrp.add(totalHit);
|
||||
|
||||
|
@ -202,7 +204,7 @@ class ResultState extends MusicBeatSubState
|
|||
var tallyGood:TallyCounter = new TallyCounter(210, (hStuf * 6) + extraYOffset, params.tallies.good, 0xFF89C9E5);
|
||||
ratingGrp.add(tallyGood);
|
||||
|
||||
var tallyBad:TallyCounter = new TallyCounter(190, (hStuf * 7) + extraYOffset, params.tallies.bad, 0xffE6CF8A);
|
||||
var tallyBad:TallyCounter = new TallyCounter(190, (hStuf * 7) + extraYOffset, params.tallies.bad, 0xFFE6CF8A);
|
||||
ratingGrp.add(tallyBad);
|
||||
|
||||
var tallyShit:TallyCounter = new TallyCounter(220, (hStuf * 8) + extraYOffset, params.tallies.shit, 0xFFE68C8A);
|
||||
|
@ -274,13 +276,13 @@ class ResultState extends MusicBeatSubState
|
|||
super.create();
|
||||
}
|
||||
|
||||
function timerThenSongName()
|
||||
function timerThenSongName():Void
|
||||
{
|
||||
movingSongStuff = false;
|
||||
|
||||
difficulty.x = 555;
|
||||
|
||||
var diffYTween = 122;
|
||||
var diffYTween:Float = 122;
|
||||
|
||||
difficulty.y = -difficulty.height;
|
||||
FlxTween.tween(difficulty, {y: diffYTween}, 0.5, {ease: FlxEase.quartOut, startDelay: 0.8});
|
||||
|
@ -310,7 +312,7 @@ class ResultState extends MusicBeatSubState
|
|||
// maskShaderSongName.frameUV = songName.frame.uv;
|
||||
}
|
||||
|
||||
override function update(elapsed:Float)
|
||||
override function update(elapsed:Float):Void
|
||||
{
|
||||
// maskShaderSongName.swagSprX = songName.x;
|
||||
maskShaderDifficulty.swagSprX = difficulty.x;
|
||||
|
|
|
@ -519,7 +519,7 @@ class StoryMenuState extends MusicBeatState
|
|||
}
|
||||
}
|
||||
|
||||
function selectLevel()
|
||||
function selectLevel():Void
|
||||
{
|
||||
if (!currentLevel.isUnlocked())
|
||||
{
|
||||
|
@ -554,6 +554,8 @@ class StoryMenuState extends MusicBeatState
|
|||
PlayStatePlaylist.campaignTitle = currentLevel.getTitle();
|
||||
PlayStatePlaylist.campaignDifficulty = currentDifficultyId;
|
||||
|
||||
Highscore.talliesLevel = new funkin.Highscore.Tallies();
|
||||
|
||||
new FlxTimer().start(1, function(tmr:FlxTimer) {
|
||||
FlxTransitionableState.skipNextTransIn = false;
|
||||
FlxTransitionableState.skipNextTransOut = false;
|
||||
|
|
23
source/funkin/util/TrackerUtil.hx
Normal file
23
source/funkin/util/TrackerUtil.hx
Normal file
|
@ -0,0 +1,23 @@
|
|||
package funkin.util;
|
||||
|
||||
// This may or may not already be imported via imports.hx...
|
||||
import flixel.system.debug.watch.Tracker;
|
||||
import flixel.FlxG;
|
||||
|
||||
/**
|
||||
* Utility class that helps manage adding profiles to the flixel debugger tracker
|
||||
*/
|
||||
class TrackerUtil
|
||||
{
|
||||
/**
|
||||
* Adds profiles to the debugger to help track certain game objects.
|
||||
* NOTE: This isn't the full list of profiles made, as sometimes they're made
|
||||
* on in various places in code for random debugging purposes!
|
||||
* Might be good to put them all here though!
|
||||
*/
|
||||
public static function initTrackers():Void
|
||||
{
|
||||
Tracker.addProfile(new TrackerProfile(Highscore, ["tallies"]));
|
||||
FlxG.console.registerClass(Highscore);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue