Merge branch 'rewrite/master' into bugfix/chart-editor-vocal-crash

This commit is contained in:
Eric 2024-03-04 23:00:38 -05:00 committed by GitHub
commit 3aa4c23340
10 changed files with 162 additions and 94 deletions

View File

@ -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",

View File

@ -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"
}
}

View File

@ -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;
}

View File

@ -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!

View File

@ -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
{

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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;

View 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);
}
}