lotta changes

This commit is contained in:
Yoshman29
2023-04-13 17:29:16 +02:00
parent f85d8b1675
commit 64c11c32ac
11 changed files with 312 additions and 272 deletions
+1 -1
View File
@@ -358,7 +358,7 @@ class Charter extends UIState {
public function loadSong() {
if (__reload)
CoolUtil.loadSong(__song, __diff, false, false);
PlayState.loadSong(__song, __diff, false, false);
Conductor.setupSong(PlayState.SONG);
-100
View File
@@ -1,100 +0,0 @@
package funkin.game;
class Highscore
{
public static var songScores:Map<String, SongScore> = new Map();
public static var weekScores:Map<String, SongScore> = new Map();
public static function saveScore(song:String, score:SongScore, ?diff:String = "normal"):Void
{
prepareScore(score);
var daSong:String = formatSong(song, diff);
if (!songScores.exists(daSong) || songScores.get(daSong).score < score.score)
setScore(daSong, score);
}
public static function saveWeekScore(weekName:String, score:SongScore, ?diff:String = "normal"):Void
{
prepareScore(score);
var daWeek:String = formatSong(weekName, diff);
if (!weekScores.exists(daWeek) || weekScores.get(daWeek).score < score.score)
setWeekScore(daWeek, score);
}
static function setScore(song:String, score:SongScore):Void
{
if (score == null) return;
songScores.set(song, score);
save();
}
static function setWeekScore(song:String, score:SongScore):Void
{
if (score == null) return;
weekScores.set(song, score);
save();
}
public static function save() {
FlxG.save.data.songScores = songScores;
FlxG.save.data.weekScores = weekScores;
FlxG.save.flush();
}
public static function formatSong(song:String, diff:String):String
{
var daSong:String = song.toLowerCase();
diff = diff.toLowerCase();
if (diff != "normal")
daSong += '-$diff';
return daSong;
}
public static function getScore(song:String, diff:String):SongScore
{
var daSong = formatSong(song, diff);
if (!songScores.exists(daSong))
setScore(daSong, {});
return prepareScore(songScores.get(daSong));
}
public static function getWeekScore(week:String, diff:String):SongScore
{
var daWeek = formatSong(week, diff);
if (!weekScores.exists(daWeek))
setScore(daWeek, {});
return prepareScore(weekScores.get(daWeek));
}
public static function prepareScore(score:SongScore):SongScore {
if (score == null) score = {};
score.setFieldDefault('score', 0);
score.setFieldDefault('accuracy', 0);
score.setFieldDefault('misses', 0);
score.setFieldDefault('hits', new Map<String, Int>());
return score;
}
public static function load():Void
{
songScores = CoolUtil.getDefault(FlxG.save.data.songScores, new Map<String, SongScore>());
weekScores = CoolUtil.getDefault(FlxG.save.data.weekScores, new Map<String, SongScore>());
for(k=>e in songScores)
if (e is Int)
songScores.remove(k);
}
}
typedef SongScore = {
@:optional var score:Int;
@:optional var accuracy:Float;
@:optional var misses:Int;
@:optional var hits:Map<String, Int>;
}
+82 -9
View File
@@ -1,5 +1,6 @@
package funkin.game;
import funkin.savedata.FunkinSave;
import flixel.graphics.FlxGraphic;
import funkin.chart.Chart;
import funkin.chart.ChartData;
@@ -326,6 +327,19 @@ class PlayState extends MusicBeatState
*/
public static var campaignScore:Int = 0;
/**
* Misses for the current week.
*/
public static var campaignMisses:Int = 0;
/**
* Accuracy for the current week
*/
public static var campaignAccuracy(get, null):Float;
public static var campaignAccuracyTotal:Float = 0;
public static var campaignAccuracyCount:Float = 0;
/**
* Camera zoom at which the game lerps to.
*/
@@ -592,8 +606,7 @@ class PlayState extends MusicBeatState
}) : strumLine.position;
if (strumLine.characters != null) for(k=>charName in strumLine.characters) {
var char = new Character(0, 0, charName, stage.isCharFlipped(charPosName, strumLine.type == 1));
stage.applyCharStuff(char, charPosName);
char.x += k * 50;
stage.applyCharStuff(char, charPosName, k);
chars.push(char);
}
@@ -1211,11 +1224,13 @@ class PlayState extends MusicBeatState
if (validScore)
{
#if !switch
Highscore.saveScore(SONG.meta.name, {
FunkinSave.setSongHighscore(SONG.meta.name, difficulty, {
score: songScore,
misses: misses,
accuracy: accuracy
}, difficulty);
accuracy: accuracy,
hits: [],
date: Date.now().toString()
});
#end
}
@@ -1229,6 +1244,9 @@ class PlayState extends MusicBeatState
if (isStoryMode)
{
campaignScore += songScore;
campaignMisses += misses;
campaignAccuracyTotal += accuracy;
campaignAccuracyCount++;
storyPlaylist.shift();
if (storyPlaylist.length <= 0)
@@ -1238,9 +1256,13 @@ class PlayState extends MusicBeatState
if (validScore)
{
// TODO: more week info saving
Highscore.saveWeekScore(storyWeek.id, {
score: campaignScore
}, difficulty);
FunkinSave.setWeekHighscore(storyWeek.id, difficulty, {
score: campaignScore,
misses: campaignMisses,
accuracy: campaignAccuracy,
hits: [],
date: Date.now().toString()
});
}
FlxG.save.flush();
}
@@ -1253,7 +1275,7 @@ class PlayState extends MusicBeatState
FlxG.sound.music.stop();
CoolUtil.__loadSong(PlayState.storyPlaylist[0].toLowerCase(), difficulty);
PlayState.__loadSong(PlayState.storyPlaylist[0].toLowerCase(), difficulty);
FlxG.switchState(new PlayState());
}
@@ -1599,6 +1621,8 @@ class PlayState extends MusicBeatState
scripts.call("beatHit", [curBeat]);
}
// GETTERS & SETTERS
#if REGION
private inline function get_player():StrumLine
return playerStrums;
private inline function set_player(s:StrumLine):StrumLine
@@ -1650,6 +1674,55 @@ class PlayState extends MusicBeatState
strumLines[2].characters[0].danceInterval = v;
return v;
}
private inline static function get_campaignAccuracy()
return campaignAccuracyCount == 0 ? 0 : campaignAccuracyTotal / campaignAccuracyCount;
#end
/**
* Load a week into PlayState.
* @param weekData Week Data
* @param difficulty Week Difficulty
*/
public static function loadWeek(weekData:WeekData, difficulty:String = "normal") {
storyWeek = weekData;
storyPlaylist = [for(e in weekData.songs) e.name];
isStoryMode = true;
campaignScore = 0;
campaignMisses = 0;
campaignAccuracyTotal = 0;
campaignAccuracyCount = 0;
chartingMode = false;
opponentMode = coopMode = false;
__loadSong(storyPlaylist[0], difficulty);
}
/**
* Loads a song into PlayState
* @param name Song name
* @param difficulty Chart difficulty (if invalid, will load an empty chart)
* @param opponentMode Whenever opponent mode is on
* @param coopMode Whenever co-op mode is on.
*/
public static function loadSong(name:String, difficulty:String = "normal", opponentMode:Bool = false, coopMode:Bool = false) {
isStoryMode = false;
PlayState.opponentMode = opponentMode;
chartingMode = false;
PlayState.coopMode = coopMode;
__loadSong(name, difficulty);
}
/**
* (INTERNAL) Loads a song without resetting story mode/opponent mode/coop mode values.
* @param name Song name
* @param difficulty Song difficulty
*/
public static function __loadSong(name:String, difficulty:String) {
PlayState.difficulty = difficulty;
PlayState.SONG = Chart.parse(name, difficulty);
PlayState.fromMods = PlayState.SONG.fromMods;
}
}
class ComboRating {
+78 -66
View File
@@ -1,5 +1,6 @@
package funkin.game;
import flixel.math.FlxPoint;
import funkin.system.MusicBeatGroup;
import flixel.FlxState;
import haxe.xml.Access;
@@ -90,18 +91,21 @@ class Stage extends FlxBasic implements IBeatReceiver {
addCharPos("boyfriend", node, {
x: 770,
y: 100,
scroll: 1,
flip: true
});
case "girlfriend" | "gf":
addCharPos("girlfriend", node, {
x: 400,
y: 130,
scroll: 0.95,
flip: false
});
case "dad" | "opponent":
addCharPos("dad", node, {
x: 100,
y: 100,
scroll: 1,
flip: false
});
case "character":
@@ -128,6 +132,7 @@ class Stage extends FlxBasic implements IBeatReceiver {
addCharPos("girlfriend", null, {
x: 400,
y: 130,
scroll: 0.95,
flip: false
});
@@ -135,6 +140,7 @@ class Stage extends FlxBasic implements IBeatReceiver {
addCharPos("dad", null, {
x: 100,
y: 100,
scroll: 1,
flip: false
});
@@ -142,6 +148,7 @@ class Stage extends FlxBasic implements IBeatReceiver {
addCharPos("boyfriend", null, {
x: 770,
y: 100,
scroll: 1,
flip: true
});
@@ -153,75 +160,57 @@ class Stage extends FlxBasic implements IBeatReceiver {
PlayState.instance.scripts.add(stageScript);
}
public function getCharGroup(name:String) {
if (characterPoses[name] == null) return null;
return characterPoses[name].group;
}
public function addCharPos(name:String, node:Access, ?nonXMLInfo:StageCharPosInfo):StageCharPos {
var charPos = new StageCharPos();
charPos.visible = charPos.active = false;
public function addCharPos(name:String, node:Access, ?nonXMLInfo:StageCharPosInfo):MusicBeatGroup {
var group:MusicBeatGroup = new MusicBeatGroup();
state.add(group);
characterPoses[name] = {
node: node,
nonXMLInfo: nonXMLInfo,
group: group
};
return group;
}
public function isCharFlipped(posName:String, def:Bool = false) {
if (characterPoses[posName] != null) {
var charPos = characterPoses[posName];
if (charPos.node != null && charPos.node.has.flip)
return charPos.node.att.flip == "true";
if (charPos.nonXMLInfo != null)
return characterPoses[posName].nonXMLInfo.flip;
if (nonXMLInfo != null) {
charPos.setPosition(nonXMLInfo.x, nonXMLInfo.y);
charPos.scrollFactor.set(nonXMLInfo.scroll, nonXMLInfo.scroll);
charPos.flipX = nonXMLInfo.flip;
}
return def;
if (node != null) {
charPos.x = Std.parseFloat(node.getAtt("x")).getDefault(charPos.x);
charPos.y = Std.parseFloat(node.getAtt("y")).getDefault(charPos.y);
charPos.camxoffset = Std.parseFloat(node.getAtt("camxoffset")).getDefault(charPos.camxoffset);
charPos.camyoffset = Std.parseFloat(node.getAtt("camyoffset")).getDefault(charPos.camyoffset);
charPos.skewX = Std.parseFloat(node.getAtt("skewx")).getDefault(charPos.skewX);
charPos.skewY = Std.parseFloat(node.getAtt("skewy")).getDefault(charPos.skewY);
charPos.flipX = (node.has.flip || node.has.flipX) ? (node.getAtt("flip") == "true" || node.getAtt("flipX") == "true") : charPos.flipX;
var scale = Std.parseFloat(node.getAtt("scale")).getDefault(charPos.scale.x);
charPos.scale.set(scale, scale);
if (node.has.scroll) {
var scroll:Null<Float> = Std.parseFloat(node.att.scroll);
if (scroll != null) charPos.scrollFactor.set(scroll, scroll);
} else {
if (node.has.scrollx) {
var scroll:Null<Float> = Std.parseFloat(node.att.scrollx);
if (scroll != null) charPos.scrollFactor.x = scroll;
}
if (node.has.scrolly) {
var scroll:Null<Float> = Std.parseFloat(node.att.scrolly);
if (scroll != null) charPos.scrollFactor.y = scroll;
}
}
}
state.add(charPos);
return characterPoses[name] = charPos;
}
public function applyCharStuff(char:Character, posName:String) {
public inline function isCharFlipped(posName:String, def:Bool = false)
return characterPoses[posName] != null ? characterPoses[posName].flipX : def;
public function applyCharStuff(char:Character, posName:String, id:Float = 0) {
if (characterPoses[posName] == null)
state.add(char);
else {
var charPos = characterPoses[posName];
if (charPos.nonXMLInfo != null)
char.setPosition(charPos.nonXMLInfo.x, charPos.nonXMLInfo.y);
if (charPos.node != null)
doCharNodeShit(char, charPos.node);
charPos.group.add(char);
}
}
private static function doCharNodeShit(char:Character, node:Access) {
if (node.has.x) {
var x:Null<Float> = Std.parseFloat(node.att.x);
if (x != null) char.x = x;
}
if (node.has.y) {
var y:Null<Float> = Std.parseFloat(node.att.y);
if (y != null) char.y = y;
}
if (node.has.camxoffset) {
var x:Null<Float> = Std.parseFloat(node.att.camxoffset);
if (x != null) char.cameraOffset.x += x;
}
if (node.has.camyoffset) {
var y:Null<Float> = Std.parseFloat(node.att.camyoffset);
if (y != null) char.cameraOffset.y += y;
}
if (node.has.scroll) {
var scroll:Null<Float> = Std.parseFloat(node.att.scroll);
if (scroll != null) char.scrollFactor.set(scroll, scroll);
}
if (node.has.skewx) {
var skew:Null<Float> = Std.parseFloat(node.att.skewx);
if (skew != null) char.skew.x = skew;
}
if (node.has.skewy) {
var skew:Null<Float> = Std.parseFloat(node.att.skewy);
if (skew != null) char.skew.x = skew;
charPos.prepareCharacter(char, id);
state.insert(state.members.indexOf(charPos), char);
}
}
@@ -232,14 +221,37 @@ class Stage extends FlxBasic implements IBeatReceiver {
public function measureHit(curMeasure:Int) {}
}
typedef StageCharPos = {
var node:Access;
var group:MusicBeatGroup;
var ?nonXMLInfo:StageCharPosInfo;
}
class StageCharPos extends FlxObject {
public var charSpacingX:Float = 20;
public var charSpacingY:Float = 0;
public var camxoffset:Float = 0;
public var camyoffset:Float = 0;
public var skewX:Float = 0;
public var skewY:Float = 0;
public var flipX:Bool = false;
public var scale:FlxPoint = FlxPoint.get(1, 1);
public function new() {
super();
active = false;
visible = false;
}
public override function destroy() {
scale.put();
super.destroy();
}
public function prepareCharacter(char:Character, id:Float = 0) {
char.setPosition(x + (id * charSpacingX), y + (id * charSpacingY));
char.scrollFactor.set(scrollFactor.x, scrollFactor.y);
char.scale.x *= scale.x;
char.scale.y *= scale.y;
}
}
typedef StageCharPosInfo = {
var x:Float;
var y:Float;
var flip:Bool;
var scroll:Float;
}
+36 -17
View File
@@ -10,7 +10,7 @@ import flixel.text.FlxText;
import flixel.util.FlxColor;
import lime.utils.Assets;
import funkin.game.HealthIcon;
import funkin.game.Highscore;
import funkin.savedata.FunkinSave;
import haxe.Json;
import funkin.scripting.events.*;
@@ -256,32 +256,39 @@ class FreeplayState extends MusicBeatState
if (controls.ACCEPT && !dontPlaySongThisFrame)
select();
}
var __opponentMode:Bool = false;
var __coopMode:Bool = false;
function updateCoopModes() {
__opponentMode = false;
__coopMode = false;
if (songs[curSelected].coopAllowed && songs[curSelected].opponentModeAllowed) {
__opponentMode = curCoopMode % 2 == 1;
__coopMode = curCoopMode >= 2;
} else if (songs[curSelected].coopAllowed) {
__coopMode = curCoopMode == 1;
} else if (songs[curSelected].opponentModeAllowed) {
__opponentMode = curCoopMode == 1;
}
}
/**
* Selects the current song.
*/
public function select() {
var opponentMode:Bool = false;
var coopMode:Bool = false;
if (songs[curSelected].coopAllowed && songs[curSelected].opponentModeAllowed) {
opponentMode = curCoopMode % 2 == 1;
coopMode = curCoopMode >= 2;
} else if (songs[curSelected].coopAllowed) {
coopMode = curCoopMode == 1;
} else if (songs[curSelected].opponentModeAllowed) {
opponentMode = curCoopMode == 1;
}
updateCoopModes();
if (songs[curSelected].difficulties.length <= 0) return;
var event = event("onSelect", EventManager.get(FreeplaySongSelectEvent).recycle(songs[curSelected].name, songs[curSelected].difficulties[curDifficulty], opponentMode, coopMode));
var event = event("onSelect", EventManager.get(FreeplaySongSelectEvent).recycle(songs[curSelected].name, songs[curSelected].difficulties[curDifficulty], __opponentMode, __coopMode));
if (event.cancelled) return;
Options.freeplayLastSong = songs[curSelected].name;
Options.freeplayLastDifficulty = songs[curSelected].difficulties[curDifficulty];
CoolUtil.loadSong(event.song, event.difficulty, event.opponentMode, event.coopMode);
PlayState.loadSong(event.song, event.difficulty, event.opponentMode, event.coopMode);
FlxG.switchState(new PlayState());
}
@@ -308,9 +315,7 @@ class FreeplayState extends MusicBeatState
curDifficulty = event.value;
#if !switch
intendedScore = validDifficulties ? Highscore.getScore(curSong.name, curSong.difficulties[curDifficulty]).score : 0;
#end
updateScore();
if (curSong.difficulties.length > 1)
diffText.text = '< ${curSong.difficulties[curDifficulty]} >';
@@ -318,6 +323,19 @@ class FreeplayState extends MusicBeatState
diffText.text = validDifficulties ? curSong.difficulties[curDifficulty] : "-";
}
function updateScore() {
if (songs[curSelected].difficulties.length <= 0) {
intendedScore = 0;
return;
}
updateCoopModes();
var changes:Array<HighscoreChange> = [];
if (__coopMode) changes.push(CCoopMode);
if (__opponentMode) changes.push(COpponentMode);
var saveData = FunkinSave.getSongHighscore(songs[curSelected].name, songs[curSelected].difficulties[curDifficulty], changes);
intendedScore = saveData.score;
}
/**
* Array containing all labels for Co-Op / Opponent modes.
*/
@@ -342,8 +360,9 @@ class FreeplayState extends MusicBeatState
if (event.cancelled) return;
curCoopMode = event.value;
updateScore();
if (bothEnabled) {
coopText.text = coopLabels[curCoopMode];
+3 -3
View File
@@ -1,11 +1,11 @@
package funkin.menus;
import funkin.savedata.FunkinSave;
import haxe.io.Path;
import funkin.scripting.events.*;
import flixel.util.FlxTimer;
import flixel.math.FlxPoint;
import flixel.graphics.frames.FlxFramesCollection;
import funkin.game.Highscore;
import flixel.tweens.FlxTween;
import flixel.util.FlxColor;
import funkin.system.FunkinText;
@@ -201,7 +201,7 @@ class StoryMenuState extends MusicBeatState {
}
}
intendedScore = Highscore.getWeekScore(weeks[curWeek].name, weeks[curWeek].difficulties[curDifficulty]).score;
intendedScore = FunkinSave.getWeekHighscore(weeks[curWeek].name, weeks[curWeek].difficulties[curDifficulty]).score;
}
public function loadXMLs() {
@@ -336,7 +336,7 @@ class StoryMenuState extends MusicBeatState {
if (char.animation.exists("confirm"))
char.animation.play("confirm");
CoolUtil.loadWeek(weeks[curWeek], weeks[curWeek].difficulties[curDifficulty]);
PlayState.loadWeek(weeks[curWeek], weeks[curWeek].difficulties[curDifficulty]);
new FlxTimer().start(1, function(tmr:FlxTimer)
{
+109
View File
@@ -0,0 +1,109 @@
package funkin.savedata;
import openfl.Lib;
import flixel.util.FlxSave;
/**
* Class used for saves WITHOUT going through the struggle of type checks
* Just add your save variables the way you would do in the Options.hx file.
* The macro will automatically generate the `flush` and `load` functions.
*/
@:build(funkin.system.macros.FunkinSaveMacro.build("save", "flush", "load"))
class FunkinSave {
public static var highscores:Map<HighscoreEntry, SongScore> = [];
// STUFF
#if REGION
@:dox(hide) @:doNotSave
private static var __eventAdded = false;
@:doNotSave
public static var save:FlxSave;
public static function init() {
save = new FlxSave();
save.bind('save', #if sys 'YoshiCrafter29/CodenameEngine/save-default' #else 'save-default' #end);
load();
if (!__eventAdded) {
Lib.application.onExit.add(function(i:Int) {
trace("Saving savedata...");
flush();
});
__eventAdded = true;
}
}
/**
* Returns the high-score for a song.
* @param name Song name
* @param diff Song difficulty
* @param changes Changes made to that song in freeplay.
*/
public static inline function getSongHighscore(name:String, diff:String, ?changes:Array<HighscoreChange>) {
if (changes == null) changes = [];
return safeGetHighscore(HSongEntry(name.toLowerCase(), diff.toLowerCase(), changes));
}
public static inline function setSongHighscore(name:String, diff:String, highscore:SongScore, ?changes:Array<HighscoreChange>) {
if (changes == null) changes = [];
if (safeRegisterHighscore(HSongEntry(name.toLowerCase(), diff.toLowerCase(), changes), highscore)) {
flush();
return true;
}
return false;
}
public static inline function getWeekHighscore(name:String, diff:String)
return safeGetHighscore(HWeekEntry(name.toLowerCase(), diff.toLowerCase()));
public static inline function setWeekHighscore(name:String, diff:String, highscore:SongScore) {
if (safeRegisterHighscore(HWeekEntry(name.toLowerCase(), diff.toLowerCase()), highscore)) {
flush();
return true;
}
return false;
}
private static function safeGetHighscore(entry:HighscoreEntry):SongScore {
if (!highscores.exists(entry)) {
return {
score: 0,
accuracy: 0,
misses: 0,
hits: [],
date: null
};
}
return highscores.get(entry);
}
private static function safeRegisterHighscore(entry:HighscoreEntry, highscore:SongScore) {
var oldHigh = safeGetHighscore(entry);
if (oldHigh.date == null || oldHigh.score < highscore.score) {
highscores.set(entry, highscore);
return true;
}
return false;
}
#end
}
enum HighscoreEntry {
HWeekEntry(weekName:String, difficulty:String);
HSongEntry(songName:String, difficulty:String, changes:Array<HighscoreChange>);
}
enum HighscoreChange {
CCoopMode;
COpponentMode;
}
typedef SongScore = {
var score:Int;
var accuracy:Float;
var misses:Int;
var hits:Map<String, Int>;
var date:String;
}
-28
View File
@@ -1,28 +0,0 @@
package funkin.saves;
import flixel.util.FlxSave;
/**
* Class used for saves WITHOUT going through the struggle of type checks
* Just add your save variables the way you would do in the Options.hx file.
* The macro will automatically generate the `flush` and `load` functions.
*/
@:build(funkin.system.macros.FunkinSaveMacro.build("save", "flush", "load"))
class FunkinSave {
// STUFF
#if REGION
public static var save(get, null):FlxSave;
private static inline function get_save()
return FlxG.save;
public static function init() {
FlxG.save.bind('save', 'CodenameEngine');
load();
}
#end
public static var totalPlayedGames:Int = 0;
public static var variableOne:String = "";
public static var coins:Int = 0;
public static var coolColor:String = "penis";
}
+1 -1
View File
@@ -79,7 +79,7 @@ class Script extends FlxBasic implements IFlxDestroyable {
"Conductor" => funkin.system.Conductor,
"FunkinShader" => funkin.shaders.FunkinShader,
"CustomShader" => funkin.shaders.CustomShader,
"FunkinText" => funkin.menus.ui.FunkinText,
"FunkinText" => funkin.system.FunkinText,
"Alphabet" => funkin.menus.ui.Alphabet,
"CoolUtil" => funkin.utils.CoolUtil,
+1 -3
View File
@@ -9,7 +9,6 @@ import flixel.system.ui.FlxSoundTray;
import funkin.utils.NativeAPI;
import funkin.menus.BetaWarningState;
import funkin.menus.TitleState;
import funkin.game.Highscore;
import flixel.FlxGame;
import flixel.FlxState;
import openfl.Assets;
@@ -157,9 +156,8 @@ class Main extends Sprite
Assets.registerLibrary('default', lib);
funkin.options.PlayerSettings.init();
funkin.saves.FunkinSave.init();
funkin.savedata.FunkinSave.init();
Options.load();
Highscore.load();
FlxG.fixedTimestep = false;
+1 -44
View File
@@ -38,7 +38,7 @@ class CoolUtil
* @param defaultValue The default value
* @return The return value
*/
public static inline function getDefault<T>(v:Null<T>, defaultValue:T):Null<T> {
public static inline function getDefault<T>(v:Null<T>, defaultValue:T):T {
return (v == null || isNaN(v)) ? defaultValue : v;
}
@@ -409,49 +409,6 @@ class CoolUtil
}
}
/**
* Load a week into PlayState.
* @param weekData Week Data
* @param difficulty Week Difficulty
*/
public static function loadWeek(weekData:WeekData, difficulty:String = "normal") {
PlayState.storyWeek = weekData;
PlayState.storyPlaylist = [for(e in weekData.songs) e.name];
PlayState.isStoryMode = true;
PlayState.campaignScore = 0;
PlayState.chartingMode = false;
PlayState.opponentMode = PlayState.coopMode = false;
__loadSong(PlayState.storyPlaylist[0], difficulty);
}
/**
* Loads a song into PlayState
* @param name Song name
* @param difficulty Chart difficulty (if invalid, will load an empty chart)
* @param opponentMode Whenever opponent mode is on
* @param coopMode Whenever co-op mode is on.
*/
public static function loadSong(name:String, difficulty:String = "normal", opponentMode:Bool = false, coopMode:Bool = false) {
PlayState.campaignScore = 0;
PlayState.isStoryMode = false;
PlayState.opponentMode = opponentMode;
PlayState.chartingMode = false;
PlayState.coopMode = coopMode;
__loadSong(name, difficulty);
}
/**
* (INTERNAL) Loads a song without resetting story mode/opponent mode/coop mode values.
* @param name Song name
* @param difficulty Song difficulty
*/
public static function __loadSong(name:String, difficulty:String) {
PlayState.difficulty = difficulty;
PlayState.SONG = Chart.parse(name, difficulty);
PlayState.fromMods = PlayState.SONG.fromMods;
}
/**
* Equivalent of `setGraphicSize`, except that it can accept floats and automatically updates the hitbox.
* @param sprite Sprite to set the size of