mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2024-09-12 05:07:06 +00:00
Remember difficulty when leaving story/freeplay menu.
This commit is contained in:
parent
2e56fdb026
commit
996f7b275e
2
assets
2
assets
|
@ -1 +1 @@
|
|||
Subproject commit d2b3dcab92f5cb4b11774a80cbe2e270972a9577
|
||||
Subproject commit 486ea1cdc37a1f1907ba9231b0a1946ff4051f27
|
|
@ -1,5 +1,6 @@
|
|||
package funkin;
|
||||
|
||||
import funkin.play.song.Song;
|
||||
import flash.text.TextField;
|
||||
import flixel.addons.display.FlxGridOverlay;
|
||||
import flixel.addons.transition.FlxTransitionableState;
|
||||
|
@ -48,10 +49,13 @@ import lime.utils.Assets;
|
|||
|
||||
class FreeplayState extends MusicBeatSubState
|
||||
{
|
||||
var songs:Array<FreeplaySongData> = [];
|
||||
var songs:Array<Null<FreeplaySongData>> = [];
|
||||
|
||||
var diffIdsCurrent:Array<String> = [];
|
||||
var diffIdsTotal:Array<String> = [];
|
||||
|
||||
var curSelected:Int = 0;
|
||||
var curDifficulty:Int = 1;
|
||||
var currentDifficulty:String = Constants.DEFAULT_DIFFICULTY;
|
||||
|
||||
var fp:FreeplayScore;
|
||||
var txtCompletion:FlxText;
|
||||
|
@ -60,7 +64,7 @@ class FreeplayState extends MusicBeatSubState
|
|||
var lerpScore:Float = 0;
|
||||
var intendedScore:Int = 0;
|
||||
|
||||
var grpDifficulties:FlxSpriteGroup;
|
||||
var grpDifficulties:FlxTypedSpriteGroup<DifficultySprite>;
|
||||
|
||||
var coolColors:Array<Int> = [
|
||||
0xff9271fd,
|
||||
|
@ -85,6 +89,10 @@ class FreeplayState extends MusicBeatSubState
|
|||
|
||||
var stickerSubState:StickerSubState;
|
||||
|
||||
//
|
||||
static var rememberedDifficulty:Null<String> = "normal";
|
||||
static var rememberedSongId:Null<String> = null;
|
||||
|
||||
public function new(?stickers:StickerSubState = null)
|
||||
{
|
||||
if (stickers != null)
|
||||
|
@ -130,14 +138,23 @@ class FreeplayState extends MusicBeatSubState
|
|||
songs.push(null);
|
||||
|
||||
// programmatically adds the songs via LevelRegistry and SongRegistry
|
||||
for (coolWeek in LevelRegistry.instance.listBaseGameLevelIds())
|
||||
for (levelId in LevelRegistry.instance.listBaseGameLevelIds())
|
||||
{
|
||||
for (songId in LevelRegistry.instance.parseEntryData(coolWeek).songs)
|
||||
for (songId in LevelRegistry.instance.parseEntryData(levelId).songs)
|
||||
{
|
||||
var metadata = SongRegistry.instance.parseEntryMetadata(songId);
|
||||
var char = metadata.playData.characters.opponent;
|
||||
var songName = metadata.songName;
|
||||
addSong(songId, songName, coolWeek, char);
|
||||
var song:Song = SongRegistry.instance.fetchEntry(songId);
|
||||
var songBaseDifficulty:SongDifficulty = song.getDifficulty(Constants.DEFAULT_DIFFICULTY);
|
||||
|
||||
var songName = songBaseDifficulty.songName;
|
||||
var songOpponent = songBaseDifficulty.characters.opponent;
|
||||
var songDifficulties = song.listDifficulties();
|
||||
|
||||
songs.push(new FreeplaySongData(songId, songName, levelId, songOpponent, songDifficulties));
|
||||
|
||||
for (difficulty in songDifficulties)
|
||||
{
|
||||
diffIdsTotal.pushUnique(difficulty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -283,7 +300,7 @@ class FreeplayState extends MusicBeatSubState
|
|||
grpCapsules = new FlxTypedGroup<SongMenuItem>();
|
||||
add(grpCapsules);
|
||||
|
||||
grpDifficulties = new FlxSpriteGroup(-300, 80);
|
||||
grpDifficulties = new FlxTypedSpriteGroup<DifficultySprite>(-300, 80);
|
||||
add(grpDifficulties);
|
||||
|
||||
exitMovers.set([grpDifficulties],
|
||||
|
@ -293,15 +310,22 @@ class FreeplayState extends MusicBeatSubState
|
|||
wait: 0
|
||||
});
|
||||
|
||||
grpDifficulties.add(new FlxSprite().loadGraphic(Paths.image('freeplay/freeplayEasy')));
|
||||
grpDifficulties.add(new FlxSprite().loadGraphic(Paths.image('freeplay/freeplayNorm')));
|
||||
grpDifficulties.add(new FlxSprite().loadGraphic(Paths.image('freeplay/freeplayHard')));
|
||||
for (diffId in diffIdsTotal)
|
||||
{
|
||||
var diffSprite:DifficultySprite = new DifficultySprite(diffId);
|
||||
diffSprite.difficultyId = diffId;
|
||||
grpDifficulties.add(diffSprite);
|
||||
}
|
||||
|
||||
grpDifficulties.group.forEach(function(spr) {
|
||||
spr.visible = false;
|
||||
});
|
||||
|
||||
grpDifficulties.group.members[curDifficulty].visible = true;
|
||||
for (diffSprite in grpDifficulties.group.members)
|
||||
{
|
||||
if (diffSprite == null) continue;
|
||||
if (diffSprite.difficultyId == currentDifficulty) diffSprite.visible = true;
|
||||
}
|
||||
|
||||
var albumArt:FlxAtlasSprite = new FlxAtlasSprite(640, 360, Paths.animateAtlas("freeplay/albumRoll"));
|
||||
albumArt.visible = false;
|
||||
|
@ -572,15 +596,12 @@ class FreeplayState extends MusicBeatSubState
|
|||
|
||||
FlxG.console.registerFunction("changeSelection", changeSelection);
|
||||
|
||||
rememberSelection();
|
||||
|
||||
changeSelection();
|
||||
changeDiff();
|
||||
}
|
||||
|
||||
public function addSong(songId:String, songName:String, levelId:String, songCharacter:String)
|
||||
{
|
||||
songs.push(new FreeplaySongData(songId, songName, levelId, songCharacter));
|
||||
}
|
||||
|
||||
var touchY:Float = 0;
|
||||
var touchX:Float = 0;
|
||||
var dxTouch:Float = 0;
|
||||
|
@ -850,28 +871,24 @@ class FreeplayState extends MusicBeatSubState
|
|||
{
|
||||
touchTimer = 0;
|
||||
|
||||
curDifficulty += change;
|
||||
var currentDifficultyIndex = diffIdsCurrent.indexOf(currentDifficulty);
|
||||
|
||||
if (curDifficulty < 0) curDifficulty = 2;
|
||||
if (curDifficulty > 2) curDifficulty = 0;
|
||||
if (currentDifficultyIndex == -1) currentDifficultyIndex = diffIdsCurrent.indexOf(Constants.DEFAULT_DIFFICULTY);
|
||||
|
||||
var targetDifficulty:String = switch (curDifficulty)
|
||||
{
|
||||
case 0:
|
||||
'easy';
|
||||
case 1:
|
||||
'normal';
|
||||
case 2:
|
||||
'hard';
|
||||
default: 'normal';
|
||||
};
|
||||
currentDifficultyIndex += change;
|
||||
|
||||
if (currentDifficultyIndex < 0) currentDifficultyIndex = diffIdsCurrent.length - 1;
|
||||
if (currentDifficultyIndex >= diffIdsCurrent.length) currentDifficultyIndex = 0;
|
||||
|
||||
currentDifficulty = diffIdsCurrent[currentDifficultyIndex];
|
||||
|
||||
var daSong = songs[curSelected];
|
||||
if (daSong != null)
|
||||
{
|
||||
var songScore:SaveScoreData = Save.get().getSongScore(songs[curSelected].songId, targetDifficulty);
|
||||
var songScore:SaveScoreData = Save.get().getSongScore(songs[curSelected].songId, currentDifficulty);
|
||||
intendedScore = songScore?.score ?? 0;
|
||||
intendedCompletion = songScore?.accuracy ?? 0.0;
|
||||
rememberedDifficulty = currentDifficulty;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -879,19 +896,31 @@ class FreeplayState extends MusicBeatSubState
|
|||
intendedCompletion = 0.0;
|
||||
}
|
||||
|
||||
grpDifficulties.group.forEach(function(spr) {
|
||||
spr.visible = false;
|
||||
grpDifficulties.group.forEach(function(diffSprite) {
|
||||
diffSprite.visible = false;
|
||||
});
|
||||
|
||||
var curShit:FlxSprite = grpDifficulties.group.members[curDifficulty];
|
||||
|
||||
curShit.visible = true;
|
||||
curShit.offset.y += 5;
|
||||
curShit.alpha = 0.5;
|
||||
new FlxTimer().start(1 / 24, function(swag) {
|
||||
curShit.alpha = 1;
|
||||
curShit.updateHitbox();
|
||||
});
|
||||
for (diffSprite in grpDifficulties.group.members)
|
||||
{
|
||||
if (diffSprite == null) continue;
|
||||
if (diffSprite.difficultyId == currentDifficulty)
|
||||
{
|
||||
if (change != 0)
|
||||
{
|
||||
diffSprite.visible = true;
|
||||
diffSprite.offset.y += 5;
|
||||
diffSprite.alpha = 0.5;
|
||||
new FlxTimer().start(1 / 24, function(swag) {
|
||||
diffSprite.alpha = 1;
|
||||
diffSprite.updateHitbox();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
diffSprite.visible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clears the cache of songs, frees up memory, they' ll have to be loaded in later tho function clearDaCache(actualSongTho:String)
|
||||
|
@ -899,6 +928,7 @@ class FreeplayState extends MusicBeatSubState
|
|||
{
|
||||
for (song in songs)
|
||||
{
|
||||
if (song == null) return;
|
||||
if (song.songName != actualSongTho)
|
||||
{
|
||||
trace('trying to remove: ' + song.songName);
|
||||
|
@ -913,22 +943,7 @@ class FreeplayState extends MusicBeatSubState
|
|||
|
||||
var songId:String = cap.songTitle.toLowerCase();
|
||||
var targetSong:Song = SongRegistry.instance.fetchEntry(songId);
|
||||
var targetDifficulty:String = switch (curDifficulty)
|
||||
{
|
||||
case 0:
|
||||
'easy';
|
||||
case 1:
|
||||
'normal';
|
||||
case 2:
|
||||
'hard';
|
||||
default: 'normal';
|
||||
};
|
||||
|
||||
// TODO: Implement additional difficulties into the interface properly.
|
||||
if (FlxG.keys.pressed.E)
|
||||
{
|
||||
targetDifficulty = 'erect';
|
||||
}
|
||||
var targetDifficulty:String = currentDifficulty;
|
||||
|
||||
// TODO: Implement Pico into the interface properly.
|
||||
var targetCharacter:String = 'bf';
|
||||
|
@ -957,6 +972,22 @@ class FreeplayState extends MusicBeatSubState
|
|||
});
|
||||
}
|
||||
|
||||
function rememberSelection():Void
|
||||
{
|
||||
if (rememberedSongId != null)
|
||||
{
|
||||
curSelected = songs.findIndex(function(song) {
|
||||
if (song == null) return false;
|
||||
return song.songId == rememberedSongId;
|
||||
});
|
||||
}
|
||||
|
||||
if (rememberedDifficulty != null)
|
||||
{
|
||||
currentDifficulty = rememberedDifficulty;
|
||||
}
|
||||
}
|
||||
|
||||
function changeSelection(change:Int = 0)
|
||||
{
|
||||
// NGio.logEvent('Fresh');
|
||||
|
@ -968,28 +999,19 @@ class FreeplayState extends MusicBeatSubState
|
|||
if (curSelected < 0) curSelected = grpCapsules.countLiving() - 1;
|
||||
if (curSelected >= grpCapsules.countLiving()) curSelected = 0;
|
||||
|
||||
var targetDifficulty:String = switch (curDifficulty)
|
||||
{
|
||||
case 0:
|
||||
'easy';
|
||||
case 1:
|
||||
'normal';
|
||||
case 2:
|
||||
'hard';
|
||||
default: 'normal';
|
||||
};
|
||||
|
||||
var daSong = songs[curSelected];
|
||||
if (daSong != null)
|
||||
{
|
||||
var songScore:SaveScoreData = Save.get().getSongScore(daSong.songId, targetDifficulty);
|
||||
intendedScore = songScore?.score ?? 0;
|
||||
intendedCompletion = songScore?.accuracy ?? 0.0;
|
||||
diffIdsCurrent = daSong.songDifficulties;
|
||||
rememberedSongId = daSong.songId;
|
||||
changeDiff();
|
||||
}
|
||||
else
|
||||
{
|
||||
intendedScore = 0;
|
||||
intendedCompletion = 0.0;
|
||||
rememberedSongId = null;
|
||||
rememberedDifficulty = null;
|
||||
}
|
||||
|
||||
for (index => capsule in grpCapsules.members)
|
||||
|
@ -1011,6 +1033,10 @@ class FreeplayState extends MusicBeatSubState
|
|||
FlxG.sound.playMusic(Paths.music('freeplay/freeplayRandom'), 0);
|
||||
FlxG.sound.music.fadeIn(2, 0, 0.8);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Try to stream the music?
|
||||
}
|
||||
grpCapsules.members[curSelected].selected = true;
|
||||
}
|
||||
}
|
||||
|
@ -1078,19 +1104,21 @@ enum abstract FilterType(String)
|
|||
|
||||
class FreeplaySongData
|
||||
{
|
||||
public var isFav:Bool = false;
|
||||
|
||||
public var songId:String = "";
|
||||
public var songName:String = "";
|
||||
public var levelId:String = "";
|
||||
public var songCharacter:String = "";
|
||||
public var isFav:Bool = false;
|
||||
public var songDifficulties:Array<String> = [];
|
||||
|
||||
public function new(songId:String, songName:String, levelId:String, songCharacter:String, isFav:Bool = false)
|
||||
public function new(songId:String, songName:String, levelId:String, songCharacter:String, songDifficulties:Array<String>)
|
||||
{
|
||||
this.songId = songId;
|
||||
this.songName = songName;
|
||||
this.levelId = levelId;
|
||||
this.songCharacter = songCharacter;
|
||||
this.isFav = isFav;
|
||||
this.songDifficulties = songDifficulties;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1101,3 +1129,17 @@ typedef MoveData =
|
|||
var ?speed:Float;
|
||||
var ?wait:Float;
|
||||
}
|
||||
|
||||
class DifficultySprite extends FlxSprite
|
||||
{
|
||||
public var difficultyId:String;
|
||||
|
||||
public function new(diffId:String)
|
||||
{
|
||||
super();
|
||||
|
||||
difficultyId = diffId;
|
||||
|
||||
loadGraphic(Paths.image('freeplay/freeplay' + diffId));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -162,7 +162,7 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry<SongMeta
|
|||
// but all the difficulties in the metadata must be in the chart file.
|
||||
for (diffId in metadata.playData.difficulties)
|
||||
{
|
||||
difficultyIds.push(diffId);
|
||||
difficultyIds.pushUnique(diffId);
|
||||
|
||||
var difficulty:SongDifficulty = new SongDifficulty(this, diffId, metadata.variation);
|
||||
|
||||
|
|
|
@ -99,6 +99,9 @@ class StoryMenuState extends MusicBeatState
|
|||
|
||||
var stickerSubState:StickerSubState;
|
||||
|
||||
static var rememberedLevelId:Null<String> = null;
|
||||
static var rememberedDifficulty:Null<String> = "normal";
|
||||
|
||||
public function new(?stickers:StickerSubState = null)
|
||||
{
|
||||
super();
|
||||
|
@ -133,6 +136,8 @@ class StoryMenuState extends MusicBeatState
|
|||
|
||||
updateData();
|
||||
|
||||
rememberSelection();
|
||||
|
||||
// Explicitly define the background color.
|
||||
this.bgColor = FlxColor.BLACK;
|
||||
|
||||
|
@ -185,6 +190,7 @@ class StoryMenuState extends MusicBeatState
|
|||
leftDifficultyArrow.animation.play('idle');
|
||||
add(leftDifficultyArrow);
|
||||
|
||||
buildDifficultySprite(Constants.DEFAULT_DIFFICULTY);
|
||||
buildDifficultySprite();
|
||||
|
||||
rightDifficultyArrow = new FlxSprite(difficultySprite.x + difficultySprite.width + 10, leftDifficultyArrow.y);
|
||||
|
@ -207,6 +213,18 @@ class StoryMenuState extends MusicBeatState
|
|||
#end
|
||||
}
|
||||
|
||||
function rememberSelection():Void
|
||||
{
|
||||
if (rememberedLevelId != null)
|
||||
{
|
||||
currentLevelId = rememberedLevelId;
|
||||
}
|
||||
if (rememberedDifficulty != null)
|
||||
{
|
||||
currentDifficultyId = rememberedDifficulty;
|
||||
}
|
||||
}
|
||||
|
||||
function playMenuMusic():Void
|
||||
{
|
||||
if (FlxG.sound.music == null || !FlxG.sound.music.playing)
|
||||
|
@ -228,34 +246,35 @@ class StoryMenuState extends MusicBeatState
|
|||
isLevelUnlocked = currentLevel == null ? false : currentLevel.isUnlocked();
|
||||
}
|
||||
|
||||
function buildDifficultySprite():Void
|
||||
function buildDifficultySprite(?diff:String):Void
|
||||
{
|
||||
if (diff == null) diff = currentDifficultyId;
|
||||
remove(difficultySprite);
|
||||
difficultySprite = difficultySprites.get(currentDifficultyId);
|
||||
difficultySprite = difficultySprites.get(diff);
|
||||
if (difficultySprite == null)
|
||||
{
|
||||
difficultySprite = new FlxSprite(leftDifficultyArrow.x + leftDifficultyArrow.width + 10, leftDifficultyArrow.y);
|
||||
|
||||
if (Assets.exists(Paths.file('images/storymenu/difficulties/${currentDifficultyId}.xml')))
|
||||
if (Assets.exists(Paths.file('images/storymenu/difficulties/${diff}.xml')))
|
||||
{
|
||||
difficultySprite.frames = Paths.getSparrowAtlas('storymenu/difficulties/${currentDifficultyId}');
|
||||
difficultySprite.frames = Paths.getSparrowAtlas('storymenu/difficulties/${diff}');
|
||||
difficultySprite.animation.addByPrefix('idle', 'idle0', 24, true);
|
||||
difficultySprite.animation.play('idle');
|
||||
}
|
||||
else
|
||||
{
|
||||
difficultySprite.loadGraphic(Paths.image('storymenu/difficulties/${currentDifficultyId}'));
|
||||
difficultySprite.loadGraphic(Paths.image('storymenu/difficulties/${diff}'));
|
||||
}
|
||||
|
||||
difficultySprites.set(currentDifficultyId, difficultySprite);
|
||||
difficultySprites.set(diff, difficultySprite);
|
||||
|
||||
difficultySprite.x += (difficultySprites.get('normal').width - difficultySprite.width) / 2;
|
||||
difficultySprite.x += (difficultySprites.get(Constants.DEFAULT_DIFFICULTY).width - difficultySprite.width) / 2;
|
||||
}
|
||||
difficultySprite.alpha = 0;
|
||||
|
||||
difficultySprite.y = leftDifficultyArrow.y - 15;
|
||||
var targetY:Float = leftDifficultyArrow.y + 10;
|
||||
targetY -= (difficultySprite.height - difficultySprites.get('normal').height) / 2;
|
||||
targetY -= (difficultySprite.height - difficultySprites.get(Constants.DEFAULT_DIFFICULTY).height) / 2;
|
||||
FlxTween.tween(difficultySprite, {y: targetY, alpha: 1}, 0.07);
|
||||
|
||||
add(difficultySprite);
|
||||
|
@ -399,6 +418,7 @@ class StoryMenuState extends MusicBeatState
|
|||
|
||||
var previousLevelId:String = currentLevelId;
|
||||
currentLevelId = levelList[currentIndex];
|
||||
rememberedLevelId = currentLevelId;
|
||||
|
||||
updateData();
|
||||
|
||||
|
@ -442,6 +462,7 @@ class StoryMenuState extends MusicBeatState
|
|||
|
||||
var hasChanged:Bool = currentDifficultyId != difficultyList[currentIndex];
|
||||
currentDifficultyId = difficultyList[currentIndex];
|
||||
rememberedDifficulty = currentDifficultyId;
|
||||
|
||||
if (difficultyList.length <= 1)
|
||||
{
|
||||
|
|
|
@ -23,6 +23,13 @@ class ArrayTools
|
|||
return result;
|
||||
}
|
||||
|
||||
public static function pushUnique<T>(array:Array<T>, element:T):Bool
|
||||
{
|
||||
if (array.contains(element)) return false;
|
||||
array.push(element);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first element of the array that satisfies the predicate, or null if none do.
|
||||
* @param input The array to search
|
||||
|
@ -38,6 +45,21 @@ class ArrayTools
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the index of the first element of the array that satisfies the predicate, or `-1` if none do.
|
||||
* @param input The array to search
|
||||
* @param predicate The predicate to call
|
||||
* @return The index of the result
|
||||
*/
|
||||
public static function findIndex<T>(input:Array<T>, predicate:T->Bool):Int
|
||||
{
|
||||
for (index in 0...input.length)
|
||||
{
|
||||
if (predicate(input[index])) return index;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all elements from the array, without creating a new array.
|
||||
* @param array The array to clear.
|
||||
|
|
Loading…
Reference in a new issue