freeplay style code

This commit is contained in:
FabsTheFabs 2024-08-30 00:55:24 +01:00
parent 9e1d328a0f
commit a4f3c2cb84
5 changed files with 264 additions and 0 deletions

View file

@ -19,6 +19,7 @@ import funkin.play.PlayStatePlaylist;
import openfl.display.BitmapData;
import funkin.data.story.level.LevelRegistry;
import funkin.data.notestyle.NoteStyleRegistry;
import funkin.data.freeplay.style.FreeplayStyleRegistry;
import funkin.data.event.SongEventRegistry;
import funkin.data.stage.StageRegistry;
import funkin.data.dialogue.conversation.ConversationRegistry;
@ -170,6 +171,7 @@ class InitState extends FlxState
ConversationRegistry.instance.loadEntries();
DialogueBoxRegistry.instance.loadEntries();
SpeakerRegistry.instance.loadEntries();
FreeplayStyleRegistry.instance.loadEntries();
AlbumRegistry.instance.loadEntries();
StageRegistry.instance.loadEntries();

View file

@ -0,0 +1,48 @@
package funkin.data.freeplay.style;
import funkin.data.animation.AnimationData;
/**
* A type definition for the data for an album of songs.
* It includes things like what graphics to display in Freeplay.
* @see https://lib.haxe.org/p/json2object/
*/
typedef FreeplayStyleData =
{
/**
* Semantic version for style data.
*/
public var version:String;
/**
* Asset key for the background image.
*/
public var bgAsset:String;
/**
* Asset key for the difficulty selector image.
*/
public var selectorAsset:String;
/**
* Asset key for the numbers shown at the top right of the screen.
*/
public var numbersAsset:String;
/**
* Asset key for the freeplay capsules.
*/
public var capsuleAsset:String;
/**
* Color data for the capsule text outline.
* the order of this array goes as follows: [DESELECTED, SELECTED]
*/
public var capsuleTextColors:Array<String>;
/**
* Delay time after confirming a song selection, before entering PlayState.
* Useful for letting longer animations play out.
*/
public var startDelay:Float;
}

View file

@ -0,0 +1,84 @@
package funkin.data.freeplay.style;
import funkin.ui.freeplay.FreeplayStyle;
import funkin.data.freeplay.style.FreeplayStyleData;
import funkin.ui.freeplay.ScriptedFreeplayStyle;
class FreeplayStyleRegistry extends BaseRegistry<FreeplayStyle, FreeplayStyleData>
{
/**
* The current version string for the style data format.
* Handle breaking changes by incrementing this value
* and adding migration to the `migrateStyleData()` function.
*/
public static final FREEPLAYSTYLE_DATA_VERSION:thx.semver.Version = '1.0.0';
public static final FREEPLAYSTYLE_DATA_VERSION_RULE:thx.semver.VersionRule = '1.0.x';
public static final instance:FreeplayStyleRegistry = new FreeplayStyleRegistry();
public function new()
{
super('FREEPLAYSTYLE', 'ui/freeplay/styles', FREEPLAYSTYLE_DATA_VERSION_RULE);
}
/**
* Read, parse, and validate the JSON data and produce the corresponding data object.
* @param id The ID of the entry to load.
* @return The parsed data object.
*/
public function parseEntryData(id:String):Null<FreeplayStyleData>
{
// JsonParser does not take type parameters,
// otherwise this function would be in BaseRegistry.
var parser:json2object.JsonParser<FreeplayStyleData> = new json2object.JsonParser<FreeplayStyleData>();
parser.ignoreUnknownVariables = false;
switch (loadEntryFile(id))
{
case {fileName: fileName, contents: contents}:
parser.fromJson(contents, fileName);
default:
return null;
}
if (parser.errors.length > 0)
{
printErrors(parser.errors, id);
return null;
}
return parser.value;
}
/**
* Parse and validate the JSON data and produce the corresponding data object.
*
* NOTE: Must be implemented on the implementation class.
* @param contents The JSON as a string.
* @param fileName An optional file name for error reporting.
* @return The parsed data object.
*/
public function parseEntryDataRaw(contents:String, ?fileName:String):Null<FreeplayStyleData>
{
var parser:json2object.JsonParser<FreeplayStyleData> = new json2object.JsonParser<FreeplayStyleData>();
parser.ignoreUnknownVariables = false;
parser.fromJson(contents, fileName);
if (parser.errors.length > 0)
{
printErrors(parser.errors, fileName);
return null;
}
return parser.value;
}
function createScriptedEntry(clsName:String):FreeplayStyle
{
return ScriptedFreeplayStyle.init(clsName, 'unknown');
}
function getScriptedClassNames():Array<String>
{
return ScriptedFreeplayStyle.listScriptClasses();
}
}

View file

@ -0,0 +1,121 @@
package funkin.ui.freeplay;
import funkin.data.freeplay.style.FreeplayStyleData;
import funkin.data.freeplay.style.FreeplayStyleRegistry;
import funkin.data.animation.AnimationData;
import funkin.data.IRegistryEntry;
import flixel.graphics.FlxGraphic;
import flixel.util.FlxColor;
/**
* A class representing the data for a style of the Freeplay menu.
*/
class FreeplayStyle implements IRegistryEntry<FreeplayStyleData>
{
/**
* The internal ID for this freeplay style.
*/
public final id:String;
/**
* The full data for a freeplay style.
*/
public final _data:FreeplayStyleData;
public function new(id:String)
{
this.id = id;
this._data = _fetchData(id);
if (_data == null)
{
throw 'Could not parse album data for id: $id';
}
}
/**
* Get the background art as a graphic, ready to apply to a sprite.
* @return The built graphic
*/
public function getBgAssetGraphic():FlxGraphic
{
return FlxG.bitmap.add(Paths.image(getBgAssetKey()));
}
/**
* Get the asset key for the background.
* @return The asset key
*/
public function getBgAssetKey():String
{
return _data.bgAsset;
}
/**
* Get the asset key for the background.
* @return The asset key
*/
public function getSelectorAssetKey():String
{
return _data.selectorAsset;
}
/**
* Get the asset key for the number assets.
* @return The asset key
*/
public function getCapsuleAssetKey():String
{
return _data.capsuleAsset;
}
/**
* Get the asset key for the capsule art.
* @return The asset key
*/
public function getNumbersAssetKey():String
{
return _data.numbersAsset;
}
/**
* Return the deselected color of the text outline
* for freeplay capsules.
* @return The deselected color
*/
public function getCapsuleDeselCol():FlxColor
{
return FlxColor.fromString(_data.capsuleTextColors[0]);
}
/**
* Return the song selection transition delay.
* @return The start delay
*/
public function getStartDelay():Float
{
return _data.startDelay;
}
public function toString():String
{
return 'Style($id)';
}
/**
* Return the selected color of the text outline
* for freeplay capsules.
* @return The selected color
*/
public function getCapsuleSelCol():FlxColor
{
return FlxColor.fromString(_data.capsuleTextColors[1]);
}
public function destroy():Void {}
static function _fetchData(id:String):Null<FreeplayStyleData>
{
return FreeplayStyleRegistry.instance.parseEntryDataWithMigration(id, FreeplayStyleRegistry.instance.fetchEntryVersion(id));
}
}

View file

@ -0,0 +1,9 @@
package funkin.ui.freeplay;
/**
* A script that can be tied to a Freeplay style.
* Create a scripted class that extends FreeplayStyle to use this.
* This allows you to customize how a specific style works.
*/
@:hscriptClass
class ScriptedFreeplayStyle extends funkin.ui.freeplay.FreeplayStyle implements polymod.hscript.HScriptedClass {}