Skip to content

Commit

Permalink
feat: Sticker Registry
Browse files Browse the repository at this point in the history
  • Loading branch information
AbnormalPoof committed Jan 19, 2025
1 parent dfe02ec commit 3e19d29
Show file tree
Hide file tree
Showing 8 changed files with 281 additions and 80 deletions.
2 changes: 2 additions & 0 deletions source/funkin/InitState.hx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import funkin.data.freeplay.player.PlayerRegistry;
import funkin.data.freeplay.style.FreeplayStyleRegistry;
import funkin.data.notestyle.NoteStyleRegistry;
import funkin.data.song.SongRegistry;
import funkin.data.stickers.StickerRegistry;
import funkin.data.event.SongEventRegistry;
import funkin.data.stage.StageRegistry;
import funkin.data.story.level.LevelRegistry;
Expand Down Expand Up @@ -176,6 +177,7 @@ class InitState extends FlxState
FreeplayStyleRegistry.instance.loadEntries();
AlbumRegistry.instance.loadEntries();
StageRegistry.instance.loadEntries();
StickerRegistry.instance.loadEntries();

// TODO: CharacterDataParser doesn't use json2object, so it's way slower than the other parsers and more prone to syntax errors.
// Move it to use a BaseRegistry.
Expand Down
9 changes: 9 additions & 0 deletions source/funkin/data/stickers/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Sticker Set Data Schema Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.0.0]
Initial release.
39 changes: 39 additions & 0 deletions source/funkin/data/stickers/StickerData.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package funkin.data.stickers;

/**
* A type definition for a sticker set.
* It includes things like its name, the artist, and the stickers.
* @see https://lib.haxe.org/p/json2object/
*/
typedef StickerData =
{
/**
* Semantic version of the sticker set data.
*/
public var version:String;

/**
* Readable name of the sticker set.
*/
public var name:String;

/**
* The asset key for this sticker set.
*/
public var assetPath:String;

/**
* The artist of the sticker set.
*/
public var artist:String;

/**
* The stickers in the set.
*/
public var stickers:Map<String, Array<String>>;

/**
* The sticker packs in this set.
*/
public var stickerPacks:Map<String, Array<String>>;
}
84 changes: 84 additions & 0 deletions source/funkin/data/stickers/StickerRegistry.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package funkin.data.stickers;

import funkin.data.stickers.StickerSet;
import funkin.data.stickers.StickerData;
import funkin.ui.transition.ScriptedStickerSet;

class StickerRegistry extends BaseRegistry<StickerSet, StickerData>
{
/**
* The current version string for the sticker set data format.
* Handle breaking changes by incrementing this value
* and adding migration to the `migrateStickerData()` function.
*/
public static final STICKER_DATA_VERSION:thx.semver.Version = '1.0.0';

public static final STICKER_DATA_VERSION_RULE:thx.semver.VersionRule = '1.0.x';

public static final instance:StickerRegistry = new StickerRegistry();

public function new()
{
super('STICKER', 'stickersets', STICKER_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<StickerData>
{
// JsonParser does not take type parameters,
// otherwise this function would be in BaseRegistry.
var parser:json2object.JsonParser<StickerData> = new json2object.JsonParser<StickerData>();
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<StickerData>
{
var parser:json2object.JsonParser<StickerData> = new json2object.JsonParser<StickerData>();
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):StickerSet
{
return ScriptedStickerSet.init(clsName, 'unknown');
}

function getScriptedClassNames():Array<String>
{
return ScriptedStickerSet.listScriptClasses();
}
}
109 changes: 109 additions & 0 deletions source/funkin/data/stickers/StickerSet.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package funkin.data.stickers;

import funkin.data.stickers.StickerData;
import funkin.data.stickers.StickerRegistry;
import funkin.data.IRegistryEntry;
import funkin.graphics.FunkinSprite;

/**
* A class representing the data for a sticker set as displayed in the Sticker SubState.
*/
class StickerSet implements IRegistryEntry<StickerData>
{
/**
* The internal ID for this sticker set.
*/
public final id:String;

/**
* The full data for this sticker set.
*/
public final _data:StickerData;

public function new(id:String)
{
this.id = id;
this._data = _fetchData(id);

if (_data == null)
{
throw 'Could not parse sticker set data for id: $id';
}
}

/**
* Return the name of the sticker set.
* @return The name of the sticker set
*/
public function getStickerSetName():String
{
return _data.name;
}

/**
* Return the artist of the sticker set.
* @return The list of artists
*/
public function getStickerSetArtist():String
{
return _data.artist;
}

/**
* Get the asset key for the album art.
* @return The asset key
*/
public function getStickerSetAssetKey():String
{
return _data.assetPath;
}

/**
* Gets the stickers for a given sticker name.
* @param stickerName The name of the sticker to get.
* @return The sticker.
*/
public function getStickers(stickerName:String):Array<String>
{
return _data.stickers[stickerName];
}

/**
* Gets the sticker pack for a given pack name.
* @param packName The name of the pack to get.
* @return The sticker pack.
*/
public function getPack(packName:String):Array<String>
{
return _data.stickerPacks[packName];
}

public function toString():String
{
return 'StickerSet($id)';
}

public function destroy():Void {}

static function _fetchData(id:String):Null<StickerData>
{
return StickerRegistry.instance.parseEntryDataWithMigration(id, StickerRegistry.instance.fetchEntryVersion(id));
}
}

class StickerSprite extends FunkinSprite
{
public var timing:Float = 0;

public function new(x:Float, y:Float, filePath:String):Void
{
super(x, y);
if (!Assets.exists(Paths.image(filePath)))
{
throw 'File path does not exist! ($filePath)';
}
loadTexture(filePath);
updateHitbox();
scrollFactor.set();
}
}
17 changes: 15 additions & 2 deletions source/funkin/modding/PolymodHandler.hx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import funkin.play.notes.notekind.NoteKindManager;
import funkin.data.song.SongRegistry;
import funkin.data.freeplay.player.PlayerRegistry;
import funkin.data.stage.StageRegistry;
import funkin.data.stickers.StickerRegistry;
import funkin.data.freeplay.album.AlbumRegistry;
import funkin.modding.module.ModuleHandler;
import funkin.play.character.CharacterData.CharacterDataParser;
Expand Down Expand Up @@ -335,8 +336,19 @@ class PolymodHandler
{
return {
assetLibraryPaths: [
'default' => 'preload', 'shared' => 'shared', 'songs' => 'songs', 'videos' => 'videos', 'tutorial' => 'tutorial', 'week1' => 'week1',
'week2' => 'week2', 'week3' => 'week3', 'week4' => 'week4', 'week5' => 'week5', 'week6' => 'week6', 'week7' => 'week7', 'weekend1' => 'weekend1',
'default' => 'preload',
'shared' => 'shared',
'songs' => 'songs',
'videos' => 'videos',
'tutorial' => 'tutorial',
'week1' => 'week1',
'week2' => 'week2',
'week3' => 'week3',
'week4' => 'week4',
'week5' => 'week5',
'week6' => 'week6',
'week7' => 'week7',
'weekend1' => 'weekend1',
],
coreAssetRedirect: CORE_FOLDER,
}
Expand Down Expand Up @@ -427,6 +439,7 @@ class PolymodHandler
SpeakerRegistry.instance.loadEntries();
AlbumRegistry.instance.loadEntries();
StageRegistry.instance.loadEntries();
StickerRegistry.instance.loadEntries();

CharacterDataParser.loadCharacterCache(); // TODO: Migrate characters to BaseRegistry.
NoteKindManager.loadScripts();
Expand Down
8 changes: 8 additions & 0 deletions source/funkin/ui/transition/ScriptedStickerSet.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package funkin.ui.transition;

/**
* A script that can be tied to a StickerSet.
* Create a scripted class that extends StickerSet to use this.
*/
@:hscriptClass
class ScriptedStickerSet extends funkin.data.stickers.StickerSet implements polymod.hscript.HScriptedClass {}
Loading

0 comments on commit 3e19d29

Please sign in to comment.