Restructred note kinds a bit to add hard-coded note kinds, then implemented the "noanim" note kind into the chart editor.

This commit is contained in:
EliteMasterEric
2025-09-25 16:45:50 +08:00
committed by Hundrec
parent 618e093e1c
commit 666aaf4428
8 changed files with 95 additions and 25 deletions
+1 -1
View File
@@ -267,7 +267,7 @@ class InitState extends FlxState
// Move it to use a BaseRegistry.
CharacterDataParser.loadCharacterCache();
NoteKindManager.loadScripts();
NoteKindManager.initialize();
ModuleHandler.buildModuleCallbacks();
ModuleHandler.loadModuleCache();
@@ -13,7 +13,7 @@ class SongEventRegistry
{
/**
* Every built-in event class must be added to this list.
* Thankfully, with the power of `SongEventMacro`, this is done automatically.
* Thankfully, with the power of `ClassMacro`, this is done automatically.
*/
static final BUILTIN_EVENTS:List<Class<SongEvent>> = ClassMacro.listSubclassesOf(SongEvent);
+1 -1
View File
@@ -587,7 +587,7 @@ class PolymodHandler
FreeplayStyleRegistry.instance.loadEntries();
CharacterDataParser.loadCharacterCache(); // TODO: Migrate characters to BaseRegistry.
NoteKindManager.loadScripts();
NoteKindManager.initialize();
ModuleHandler.loadModuleCache();
ModuleHandler.callOnCreate();
}
@@ -7,6 +7,8 @@ import funkin.data.character.CharacterData.CharacterDataParser;
import funkin.data.character.CharacterData.CharacterRenderType;
import funkin.play.stage.Bopper;
import funkin.play.notes.NoteDirection;
import funkin.play.notes.notekind.NoteKind;
import funkin.play.notes.notekind.NoteKindManager;
/**
* A Character is a stage prop which bops to the music as well as controlled by the strumlines.
@@ -0,0 +1,14 @@
package funkin.play.notes.notekind;
/**
* A custom note kind which has custom functionality, preventing singing animations from playing.
*/
class NoAnimNoteKind extends NoteKind
{
static final DISABLE_ANIMATIONS:Bool = true;
public function new()
{
super("noanim", "Disables singing animations", null, [], DISABLE_ANIMATIONS, null);
}
}
@@ -45,13 +45,13 @@ class NoteKind implements INoteScriptedClass
*/
public var scoreable:Bool = true;
public function new(noteKind:String, description:String = "", ?noteStyleId:String, ?params:Array<NoteKindParam>, ?anim:Bool, ?suffix:String)
public function new(noteKind:String, description:String = "", ?noteStyleId:String, ?params:Array<NoteKindParam>, ?noanim:Bool, ?suffix:String)
{
this.noteKind = noteKind;
this.description = description;
this.noteStyleId = noteStyleId;
this.params = params ?? [];
this.noanim = anim ?? false;
this.noanim = noanim ?? false;
this.suffix = suffix ?? '';
}
@@ -8,9 +8,16 @@ import funkin.data.notestyle.NoteStyleRegistry;
import funkin.play.notes.notestyle.NoteStyle;
import funkin.play.notes.notekind.ScriptedNoteKind;
import funkin.play.notes.notekind.NoteKind.NoteKindParam;
import funkin.util.macro.ClassMacro;
class NoteKindManager
{
/**
* Every built-in note kind class must be added to this list.
* Thankfully, with the power of `ClassMacro`, this is done automatically.
*/
static final BUILTIN_KINDS:List<Class<NoteKind>> = ClassMacro.listSubclassesOf(NoteKind);
/**
* A map of all note kinds, keyed by their name.
* This is used to retrieve note kinds by their name.
@@ -22,12 +29,56 @@ class NoteKindManager
* @param noteKind The name of the note kind.
* @return The note kind, or null if it doesn't exist.
*/
public static function getNoteKind(noteKind:String):Null<NoteKind>
public static function getNoteKind(?noteKind:String):Null<NoteKind>
{
if (noteKind == null) return null;
return noteKinds.get(noteKind);
}
public static function loadScripts():Void
/**
* Initialize custom behavior for note kinds.
*/
public static function initialize():Void
{
clearNoteKindCache();
//
// BASE GAME EVENTS
//
registerBaseNoteKinds();
registerScriptedNoteKinds();
}
/**
* Register the hard-coded note kinds.
*/
public static function registerBaseNoteKinds():Void
{
trace('Instantiating ${BUILTIN_KINDS.length} built-in note kinds...');
for (noteKindCls in BUILTIN_KINDS)
{
var noteKindClsName:String = Type.getClassName(noteKindCls);
if (noteKindClsName == 'funkin.play.notes.notekind.NoteKind'
|| noteKindClsName == 'funkin.play.notes.notekind.ScriptedNoteKind') continue;
var kind:NoteKind = Type.createInstance(noteKindCls, ["UNKNOWN"]);
if (kind != null)
{
trace(' Loaded built-in note kind: ${kind.noteKind}');
noteKinds.set(kind.noteKind, kind);
}
else
{
trace(' Failed to load built-in note kind: ${noteKindClsName}');
}
}
}
/**
* Register the scripted note kinds provided by mods.
*/
public static function registerScriptedNoteKinds():Void
{
var scriptedClassName:Array<String> = ScriptedNoteKind.listScriptClasses();
if (scriptedClassName.length > 0)
@@ -97,12 +148,22 @@ class NoteKindManager
return NoteStyleRegistry.instance.fetchEntry(noteStyleId);
}
public static function listNoteStyles(songNoteDatas:Array<SongNoteData>):Array<NoteStyle>
/**
* Get a list of all the note styles used by the given notes.
* Great for preloading.
* @param songNoteDatas The notes to query for note styles.
* @return The note styles to load.
*/
public static function listNoteStylesByNoteData(songNoteDatas:Array<SongNoteData>):Array<NoteStyle>
{
var results:Array<NoteStyle> = [];
for (songNoteData in songNoteDatas)
{
var noteStyle:NoteStyle = getNoteStyle(songNoteData.kind, null);
if (noteStyle != null && !results.contains(noteStyle))
{
results.push(noteStyle);
}
}
return results;
}
@@ -129,23 +190,6 @@ class NoteKindManager
return noteStyleId;
}
/**
* Retrieve custom params of the given note kind
* @param noteKind Name of the note kind
* @return Array<NoteKindParam>
*/
public static function getNoteKind(noteKind:Null<String>):Null<NoteKind>
{
if (noteKind == null)
{
return null;
}
else
{
return noteKinds.get(noteKind);
}
}
/**
* Retrive custom params of the given note kind
* @param noteKind Name of the note kind
@@ -160,4 +204,13 @@ class NoteKindManager
return noteKinds.get(noteKind)?.params ?? [];
}
/**
* Clear the note kind cache.
* Be sure to register the note kinds again before trying to use them.
*/
public static function clearNoteKindCache():Void
{
noteKinds.clear();
}
}
@@ -157,6 +157,7 @@ class ChartEditorDropdowns
// Base
"" => "Default",
"~CUSTOM~" => "Custom",
"noanim" => "No Animation",
// Weeks 1-7
"censor" => "[UH-OH!] Censor Bar",
"mom" => "Mom Sings (Week 5)",