mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2024-12-25 22:47:52 +00:00
Finished song data loader
This commit is contained in:
parent
848874eaac
commit
3597b09a46
|
@ -139,17 +139,17 @@ class LatencyState extends MusicBeatSubstate
|
|||
super.create();
|
||||
}
|
||||
|
||||
override function stepHit()
|
||||
override function stepHit():Bool
|
||||
{
|
||||
if (curStep % 4 == 2)
|
||||
{
|
||||
blocks.members[((curBeat % 8) + 1) % 8].alpha = 0.5;
|
||||
}
|
||||
|
||||
super.stepHit();
|
||||
return super.stepHit();
|
||||
}
|
||||
|
||||
override function beatHit()
|
||||
override function beatHit():Bool
|
||||
{
|
||||
if (curBeat % 8 == 0)
|
||||
blocks.forEach(blok ->
|
||||
|
@ -160,7 +160,7 @@ class LatencyState extends MusicBeatSubstate
|
|||
blocks.members[curBeat % 8].alpha = 1;
|
||||
// block.visible = !block.visible;
|
||||
|
||||
super.beatHit();
|
||||
return super.beatHit();
|
||||
}
|
||||
|
||||
override function update(elapsed:Float)
|
||||
|
|
|
@ -335,11 +335,7 @@ class BaseCharacter extends Bopper
|
|||
var shouldStopSinging:Bool = (this.characterType == BF) ? !isHoldingNote() : true;
|
||||
|
||||
FlxG.watch.addQuick('singTimeMs-${characterId}', singTimeMs);
|
||||
<<<<<<< HEAD
|
||||
if (holdTimer > singTimeMs && shouldStopSinging) // && !getCurrentAnimation().endsWith("miss")
|
||||
=======
|
||||
if (holdTimer > singTimeMs && shouldStopSinging)
|
||||
>>>>>>> origin/note-redux
|
||||
{
|
||||
// trace('holdTimer reached ${holdTimer}sec (> ${singTimeMs}), stopping sing animation');
|
||||
holdTimer = 0;
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
package funkin.play.song;
|
||||
|
||||
import funkin.play.song.SongData.SongDataParser;
|
||||
import funkin.play.song.SongData.SongEventData;
|
||||
import funkin.play.song.SongData.SongMetadata;
|
||||
import funkin.play.song.SongData.SongNoteData;
|
||||
import funkin.play.song.SongData.SongPlayableChar;
|
||||
import funkin.play.song.SongData.SongTimeChange;
|
||||
import funkin.play.song.SongData.SongTimeFormat;
|
||||
|
||||
|
@ -20,12 +23,14 @@ class Song // implements IPlayStateScriptedClass
|
|||
|
||||
final _metadata:Array<SongMetadata>;
|
||||
|
||||
final variations:Array<String>;
|
||||
final difficulties:Map<String, SongDifficulty>;
|
||||
|
||||
public function new(id:String)
|
||||
{
|
||||
this.songId = id;
|
||||
|
||||
variations = [];
|
||||
difficulties = new Map<String, SongDifficulty>();
|
||||
|
||||
_metadata = SongDataParser.parseSongMetadata(songId);
|
||||
|
@ -35,6 +40,9 @@ class Song // implements IPlayStateScriptedClass
|
|||
}
|
||||
|
||||
populateFromMetadata();
|
||||
|
||||
// TODO: Disable later.
|
||||
cacheCharts();
|
||||
}
|
||||
|
||||
function populateFromMetadata()
|
||||
|
@ -46,6 +54,8 @@ class Song // implements IPlayStateScriptedClass
|
|||
{
|
||||
var difficulty = new SongDifficulty(diffId, metadata.variation);
|
||||
|
||||
variations.push(metadata.variation);
|
||||
|
||||
difficulty.songName = metadata.songName;
|
||||
difficulty.songArtist = metadata.artist;
|
||||
difficulty.timeFormat = metadata.timeFormat;
|
||||
|
@ -54,28 +64,48 @@ class Song // implements IPlayStateScriptedClass
|
|||
difficulty.loop = metadata.loop;
|
||||
difficulty.generatedBy = metadata.generatedBy;
|
||||
|
||||
difficulty.stage = metadata.playData.stage;
|
||||
// difficulty.noteSkin = metadata.playData.noteSkin;
|
||||
|
||||
difficulty.chars = new Map<String, SongPlayableChar>();
|
||||
for (charId in metadata.playData.playableChars.keys())
|
||||
{
|
||||
var char = metadata.playData.playableChars.get(charId);
|
||||
|
||||
difficulty.chars.set(charId, char);
|
||||
}
|
||||
|
||||
difficulties.set(diffId, difficulty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse and cache the chart for a specific difficulty.
|
||||
*/
|
||||
public function cacheChart(diffId:String)
|
||||
{
|
||||
getDifficulty(diffId).cacheChart();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse and cache the chart for all difficulties of this song.
|
||||
*/
|
||||
public function cacheCharts()
|
||||
{
|
||||
for (difficulty in difficulties)
|
||||
trace('Caching ${variations.length} chart files for song $songId');
|
||||
for (variation in variations)
|
||||
{
|
||||
difficulty.cacheChart();
|
||||
var chartData = SongDataParser.parseSongChartData(songId, variation);
|
||||
|
||||
for (diffId in chartData.notes.keys())
|
||||
{
|
||||
trace(' Difficulty $diffId');
|
||||
var difficulty = difficulties.get(diffId);
|
||||
if (difficulty == null)
|
||||
{
|
||||
trace('Could not find difficulty $diffId for song $songId');
|
||||
continue;
|
||||
}
|
||||
|
||||
difficulty.notes = chartData.notes.get(diffId);
|
||||
difficulty.scrollSpeed = chartData.scrollSpeed.get(diffId);
|
||||
difficulty.events = chartData.events;
|
||||
}
|
||||
}
|
||||
trace('Done caching charts.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -124,9 +154,13 @@ class SongDifficulty
|
|||
|
||||
public var timeChanges:Array<SongTimeChange> = [];
|
||||
|
||||
public var scrollSpeed(default, null):Float = SongValidator.DEFAULT_SCROLLSPEED;
|
||||
public var stage:String = SongValidator.DEFAULT_STAGE;
|
||||
public var chars:Map<String, SongPlayableChar> = null;
|
||||
|
||||
// public var notes(default, null):Array<;
|
||||
public var scrollSpeed:Float = SongValidator.DEFAULT_SCROLLSPEED;
|
||||
|
||||
public var notes:Array<SongNoteData>;
|
||||
public var events:Array<SongEventData>;
|
||||
|
||||
public function new(diffId:String, variation:String)
|
||||
{
|
||||
|
@ -134,13 +168,8 @@ class SongDifficulty
|
|||
this.variation = variation;
|
||||
}
|
||||
|
||||
public function cacheChart():Void
|
||||
{
|
||||
// TODO: Parse chart data
|
||||
}
|
||||
|
||||
public function clearChart():Void
|
||||
{
|
||||
// notes = null;
|
||||
notes = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -249,6 +249,231 @@ typedef RawSongPlayableChar =
|
|||
var i:String;
|
||||
}
|
||||
|
||||
typedef RawSongNoteData =
|
||||
{
|
||||
/**
|
||||
* The timestamp of the note. The timestamp is in the format of the song's time format.
|
||||
*/
|
||||
var t:Float;
|
||||
|
||||
/**
|
||||
* Data for the note. Represents the index on the strumline.
|
||||
* 0 = left, 1 = down, 2 = up, 3 = right
|
||||
* `floor(direction / strumlineSize)` specifies which strumline the note is on.
|
||||
* 0 = player, 1 = opponent, etc.
|
||||
*/
|
||||
var d:Int;
|
||||
|
||||
/**
|
||||
* Length of the note, if applicable.
|
||||
* Defaults to 0 for single notes.
|
||||
*/
|
||||
var l:Float;
|
||||
|
||||
/**
|
||||
* The kind of the note.
|
||||
* This can allow the note to include information used for custom behavior.
|
||||
* Defaults to blank or `"normal"`.
|
||||
*/
|
||||
var k:String;
|
||||
}
|
||||
|
||||
abstract SongNoteData(RawSongNoteData)
|
||||
{
|
||||
public function new(time:Float, data:Int, length:Float = 0, kind:String = "")
|
||||
{
|
||||
this = {
|
||||
t: time,
|
||||
d: data,
|
||||
l: length,
|
||||
k: kind
|
||||
};
|
||||
}
|
||||
|
||||
public var time(get, set):Float;
|
||||
|
||||
public function get_time():Float
|
||||
{
|
||||
return this.t;
|
||||
}
|
||||
|
||||
public function set_time(value:Float):Float
|
||||
{
|
||||
return this.t = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The raw data for the note.
|
||||
*/
|
||||
public var data(get, set):Int;
|
||||
|
||||
public function get_data():Int
|
||||
{
|
||||
return this.d;
|
||||
}
|
||||
|
||||
public function set_data(value:Int):Int
|
||||
{
|
||||
return this.d = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The direction of the note, if applicable.
|
||||
* Strips the strumline index from the data.
|
||||
*
|
||||
* 0 = left, 1 = down, 2 = up, 3 = right
|
||||
*/
|
||||
public inline function getDirection(strumlineSize:Int = 4):Int
|
||||
{
|
||||
return this.d % strumlineSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* The strumline index of the note, if applicable.
|
||||
* Strips the direction from the data.
|
||||
*
|
||||
* 0 = player, 1 = opponent, etc.
|
||||
*/
|
||||
public inline function getStrumlineIndex(strumlineSize:Int = 4):Int
|
||||
{
|
||||
return Math.floor(this.d / strumlineSize);
|
||||
}
|
||||
|
||||
public var length(get, set):Float;
|
||||
|
||||
public function get_length():Float
|
||||
{
|
||||
return this.l;
|
||||
}
|
||||
|
||||
public function set_length(value:Float):Float
|
||||
{
|
||||
return this.l = value;
|
||||
}
|
||||
|
||||
public var kind(get, set):String;
|
||||
|
||||
public function get_kind():String
|
||||
{
|
||||
if (this.k == null || this.k == '')
|
||||
return 'normal';
|
||||
|
||||
return this.k;
|
||||
}
|
||||
|
||||
public function set_kind(value:String):String
|
||||
{
|
||||
if (value == 'normal' || value == '')
|
||||
value = null;
|
||||
return this.k = value;
|
||||
}
|
||||
}
|
||||
|
||||
typedef RawSongEventData =
|
||||
{
|
||||
/**
|
||||
* The timestamp of the event. The timestamp is in the format of the song's time format.
|
||||
*/
|
||||
var t:Float;
|
||||
|
||||
/**
|
||||
* The kind of the event.
|
||||
* Examples include "FocusCamera" and "PlayAnimation"
|
||||
* Custom events can be added by scripts with the `ScriptedSongEvent` class.
|
||||
*/
|
||||
var e:String;
|
||||
|
||||
/**
|
||||
* The data for the event.
|
||||
* This can allow the event to include information used for custom behavior.
|
||||
* Data type depends on the event kind. It can be anything that's JSON serializable.
|
||||
*/
|
||||
var v:Dynamic;
|
||||
}
|
||||
|
||||
abstract SongEventData(RawSongEventData)
|
||||
{
|
||||
public function new(time:Float, event:String, value:Dynamic = null)
|
||||
{
|
||||
this = {
|
||||
t: time,
|
||||
e: event,
|
||||
v: value
|
||||
};
|
||||
}
|
||||
|
||||
public var time(get, set):Float;
|
||||
|
||||
public function get_time():Float
|
||||
{
|
||||
return this.t;
|
||||
}
|
||||
|
||||
public function set_time(value:Float):Float
|
||||
{
|
||||
return this.t = value;
|
||||
}
|
||||
|
||||
public var event(get, set):String;
|
||||
|
||||
public function get_event():String
|
||||
{
|
||||
return this.e;
|
||||
}
|
||||
|
||||
public function set_event(value:String):String
|
||||
{
|
||||
return this.e = value;
|
||||
}
|
||||
|
||||
public var value(get, set):Dynamic;
|
||||
|
||||
public function get_value():Dynamic
|
||||
{
|
||||
return this.v;
|
||||
}
|
||||
|
||||
public function set_value(value:Dynamic):Dynamic
|
||||
{
|
||||
return this.v = value;
|
||||
}
|
||||
|
||||
public inline function getBool():Bool
|
||||
{
|
||||
return cast this.v;
|
||||
}
|
||||
|
||||
public inline function getInt():Int
|
||||
{
|
||||
return cast this.v;
|
||||
}
|
||||
|
||||
public inline function getFloat():Float
|
||||
{
|
||||
return cast this.v;
|
||||
}
|
||||
|
||||
public inline function getString():String
|
||||
{
|
||||
return cast this.v;
|
||||
}
|
||||
|
||||
public inline function getArray():Array<Dynamic>
|
||||
{
|
||||
return cast this.v;
|
||||
}
|
||||
|
||||
public inline function getMap():DynamicAccess<Dynamic>
|
||||
{
|
||||
return cast this.v;
|
||||
}
|
||||
|
||||
public inline function getBoolArray():Array<Bool>
|
||||
{
|
||||
return cast this.v;
|
||||
}
|
||||
}
|
||||
|
||||
abstract SongPlayableChar(RawSongPlayableChar)
|
||||
{
|
||||
public function new(girlfriend:String, opponent:String, inst:String = "")
|
||||
|
@ -299,6 +524,12 @@ abstract SongPlayableChar(RawSongPlayableChar)
|
|||
|
||||
typedef SongChartData =
|
||||
{
|
||||
var version:Version;
|
||||
|
||||
var scrollSpeed:DynamicAccess<Float>;
|
||||
var events:Array<SongEventData>;
|
||||
var notes:DynamicAccess<Array<SongNoteData>>;
|
||||
var generatedBy:String;
|
||||
};
|
||||
|
||||
typedef RawSongTimeChange =
|
||||
|
|
|
@ -54,9 +54,9 @@ class SongMigrator
|
|||
{
|
||||
trace('[SONGDATA] Song (${songId}) chart version (${jsonData.version}) is valid and up-to-date.');
|
||||
|
||||
var songMetadata:SongMetadata = cast jsonData;
|
||||
var songChartData:SongChartData = cast jsonData;
|
||||
|
||||
return songMetadata;
|
||||
return songChartData;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -18,6 +18,7 @@ class SongValidator
|
|||
public static final DEFAULT_DIVISIONS:Int = -1;
|
||||
public static final DEFAULT_LOOP:Bool = false;
|
||||
public static final DEFAULT_GENERATEDBY:String = "Unknown";
|
||||
public static final DEFAULT_STAGE:String = "mainStage";
|
||||
public static final DEFAULT_SCROLLSPEED:Float = 1.0;
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,18 +1,14 @@
|
|||
package funkin.ui.stageBuildShit;
|
||||
|
||||
import flixel.FlxSprite;
|
||||
import flixel.input.mouse.FlxMouseEvent;
|
||||
import flixel.input.mouse.FlxMouseEventManager;
|
||||
import flixel.math.FlxPoint;
|
||||
import flixel.ui.FlxButton;
|
||||
import funkin.play.PlayState;
|
||||
import funkin.play.character.BaseCharacter;
|
||||
import funkin.play.stage.StageData.StageDataParser;
|
||||
import funkin.play.stage.StageData;
|
||||
import haxe.Json;
|
||||
import haxe.ui.ComponentBuilder;
|
||||
import haxe.ui.RuntimeComponentBuilder;
|
||||
import haxe.ui.Toolkit;
|
||||
import haxe.ui.components.Button;
|
||||
import haxe.ui.containers.HBox;
|
||||
import haxe.ui.containers.VBox;
|
||||
import haxe.ui.core.Component;
|
||||
import openfl.Assets;
|
||||
|
@ -46,7 +42,7 @@ class StageOffsetSubstate extends MusicBeatSubstate
|
|||
|
||||
for (thing in PlayState.instance.currentStage)
|
||||
{
|
||||
FlxMouseEventManager.add(thing, spr ->
|
||||
FlxMouseEvent.add(thing, spr ->
|
||||
{
|
||||
char = cast thing;
|
||||
trace("JUST PRESSED!");
|
||||
|
@ -94,7 +90,7 @@ class StageOffsetSubstate extends MusicBeatSubstate
|
|||
{
|
||||
for (thing in PlayState.instance.currentStage)
|
||||
{
|
||||
FlxMouseEventManager.remove(thing);
|
||||
FlxMouseEvent.remove(thing);
|
||||
thing.alpha = 1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue