mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2025-03-21 17:39:20 +00:00
WIP
This commit is contained in:
parent
7c88032551
commit
f790cd8fd6
source/funkin/play/song
8
source/funkin/play/song/ScriptedSong.hx
Normal file
8
source/funkin/play/song/ScriptedSong.hx
Normal file
|
@ -0,0 +1,8 @@
|
|||
package funkin.play.song;
|
||||
|
||||
import polymod.hscript.HScriptedClass;
|
||||
|
||||
@:hscriptClass
|
||||
class ScriptedSong extends Song implements HScriptedClass
|
||||
{
|
||||
}
|
38
source/funkin/play/song/Song.hx
Normal file
38
source/funkin/play/song/Song.hx
Normal file
|
@ -0,0 +1,38 @@
|
|||
package funkin.play.song;
|
||||
|
||||
/**
|
||||
* This is a data structure managing information about the current song.
|
||||
* This structure is created when the game starts, and includes all the data
|
||||
* from the `metadata.json` file.
|
||||
* It also includes the chart data, but only when this is the currently loaded song.
|
||||
*
|
||||
* It also receives script events; scripted classes which extend this class
|
||||
* can be used to perform custom gameplay behaviors only on specific songs.
|
||||
*/
|
||||
class Song implements IPlayStateScriptedClass
|
||||
{
|
||||
public var songId(default, null):String;
|
||||
|
||||
public var songName(get, null):String;
|
||||
|
||||
final _metadata:SongMetadata;
|
||||
final _chartData:SongChartData;
|
||||
|
||||
public function new(id:String)
|
||||
{
|
||||
this.songId = songId;
|
||||
|
||||
_metadata = SongDataParser.parseSongMetadata(this.songId);
|
||||
if (_metadata == null)
|
||||
{
|
||||
throw 'Could not find song data for songId: $songId';
|
||||
}
|
||||
}
|
||||
|
||||
function get_songName():String
|
||||
{
|
||||
if (_metadata == null)
|
||||
return null;
|
||||
return _metadata.name;
|
||||
}
|
||||
}
|
129
source/funkin/play/song/SongData.hx
Normal file
129
source/funkin/play/song/SongData.hx
Normal file
|
@ -0,0 +1,129 @@
|
|||
package funkin.play.song;
|
||||
|
||||
/**
|
||||
* Contains utilities for loading and parsing stage data.
|
||||
*/
|
||||
class SongDataParser
|
||||
{
|
||||
/**
|
||||
* The current version string for the stage data format.
|
||||
* Handle breaking changes by incrementing this value
|
||||
* and adding migration to the SongMigrator class.
|
||||
*/
|
||||
public static final CHART_VERSION:String = "2.0.0";
|
||||
|
||||
/**
|
||||
* A list containing all the songs available to the game.
|
||||
*/
|
||||
static final songCache:Map<String, Stage> = new Map<String, Stage>();
|
||||
|
||||
static final DEFAULT_SONG_ID = 'UNKNOWN';
|
||||
|
||||
/**
|
||||
* Parses and preloads the game's song metadata and scripts when the game starts.
|
||||
*
|
||||
* If you want to force song metadata to be reloaded, you can just call this function again.
|
||||
*/
|
||||
public static function loadSongCache():Void
|
||||
{
|
||||
clearSongCache();
|
||||
trace("[SONGDATA] Loading song cache...");
|
||||
|
||||
//
|
||||
// SCRIPTED SONGS
|
||||
//
|
||||
var scriptedSongClassNames:Array<String> = ScriptedSong.listScriptClasses();
|
||||
trace(' Instantiating ${scriptedSongClassNames.length} scripted songs...');
|
||||
for (songCls in scriptedSongClassNames)
|
||||
{
|
||||
var song:Song = ScriptedSong.init(songCls, DEFAULT_SONG_ID);
|
||||
if (song != null)
|
||||
{
|
||||
trace(' Loaded scripted song: ${song.songId}');
|
||||
songCache.set(song.songId, song);
|
||||
}
|
||||
else
|
||||
{
|
||||
trace(' Failed to instantiate scripted song class: ${songCls}');
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// UNSCRIPTED SONGS
|
||||
//
|
||||
var songIdList:Array<String> = DataAssets.listDataFilesInPath('songs/');
|
||||
var unscriptedSongIds:Array<String> = songIdList.filter(function(songId:String):Bool
|
||||
{
|
||||
return !songCache.exists(songId);
|
||||
});
|
||||
trace(' Instantiating ${unscriptedSongIds.length} non-scripted songs...');
|
||||
for (songId in unscriptedSongIds)
|
||||
{
|
||||
var song:Song;
|
||||
try
|
||||
{
|
||||
stage = new Song(songId);
|
||||
if (stage != null)
|
||||
{
|
||||
trace(' Loaded song data: ${song.songId}');
|
||||
songCache.set(song.songId, song);
|
||||
}
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
trace(' An error occurred while loading song data: ${songId}');
|
||||
// Assume error was already logged.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
trace(' Successfully loaded ${Lambda.count(songCache)} stages.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a particular song from the cache.
|
||||
*/
|
||||
public static function fetchStage(songId:String):Null<Song>
|
||||
{
|
||||
if (songCache.exists(songId))
|
||||
{
|
||||
var song:Song = songCache.get(songId);
|
||||
trace('[STAGEDATA] Successfully fetch song: ${songId}');
|
||||
return song;
|
||||
}
|
||||
else
|
||||
{
|
||||
trace('[STAGEDATA] Failed to fetch song, not found in cache: ${songId}');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static function clearSongCache():Void
|
||||
{
|
||||
if (songCache != null)
|
||||
{
|
||||
for (song in songCache)
|
||||
{
|
||||
song.destroy();
|
||||
}
|
||||
songCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public static function parseSongMetadata(songId:String):Null<SongMetadata>
|
||||
{
|
||||
}
|
||||
|
||||
static function loadSongMetadataFile(songPath:String, variant:String = ''):String
|
||||
{
|
||||
var songMetadataFilePath:String = Paths.json('stages/${stagePath}');
|
||||
var rawJson = Assets.getText(stageFilePath).trim();
|
||||
|
||||
while (!rawJson.endsWith("}"))
|
||||
{
|
||||
rawJson = rawJson.substr(0, rawJson.length - 1);
|
||||
}
|
||||
|
||||
return rawJson;
|
||||
}
|
||||
}
|
12
source/funkin/play/song/SongMitrator.hx
Normal file
12
source/funkin/play/song/SongMitrator.hx
Normal file
|
@ -0,0 +1,12 @@
|
|||
package funkin.play.song;
|
||||
|
||||
class SongMigrator
|
||||
{
|
||||
public static function migrateSongMetadata(song:Song, jsonData:Dynamic)
|
||||
{
|
||||
}
|
||||
|
||||
public static function migrateSongChart(song:Song, jsonData:Dynamic)
|
||||
{
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue