lotta changes
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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>;
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
@@ -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];
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user