Added some more documentation

This commit is contained in:
Ne_Eo
2024-12-16 04:37:18 +01:00
parent a6c99754fd
commit aec73ab2b6
25 changed files with 298 additions and 12 deletions
+3 -3
View File
@@ -269,13 +269,13 @@ class Setup {
prettyPrint("Installing Microsoft Visual Studio Community (Dependency)");
// thanks to @crowplexus for these two lines! - Nex
Sys.command("curl -# -O https://download.visualstudio.microsoft.com/download/pr/3105fcfe-e771-41d6-9a1c-fc971e7d03a7/8eb13958dc429a6e6f7e0d6704d43a55f18d02a253608351b6bf6723ffdaf24e/vs_Community.exe");
Sys.command("vs_Community.exe --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --add Microsoft.VisualStudio.Component.Windows10SDK.19041 -p");
command("curl -# -O https://download.visualstudio.microsoft.com/download/pr/3105fcfe-e771-41d6-9a1c-fc971e7d03a7/8eb13958dc429a6e6f7e0d6704d43a55f18d02a253608351b6bf6723ffdaf24e/vs_Community.exe");
command("vs_Community.exe --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --add Microsoft.VisualStudio.Component.Windows10SDK.19041 -p");
FileSystem.deleteFile("vs_Community.exe");
prettyPrint('If it didn\'t say it before: Because of this component if you want to compile you have to restart the device.');
Sys.print("Do you wish to do it now [y/n]? ");
if(Sys.stdin().readLine().toLowerCase() == "y") Sys.command("shutdown /r /t 0 /f");
if(Sys.stdin().readLine().toLowerCase() == "y") command("shutdown /r /t 0 /f");
}
}
+3
View File
@@ -2,6 +2,9 @@ package funkin.backend;
import funkin.backend.system.interfaces.IBeatReceiver;
/**
* Group of FlxSprites, if the sprite implements `IBeatReceiver`, then beatHit, stepHit and measureHit will be called.
**/
class MusicBeatGroup extends FlxTypedSpriteGroup<FlxSprite> implements IBeatReceiver {
public function beatHit(curBeat:Int) {
for(e in members) if (e is IBeatReceiver) ({var _:IBeatReceiver = cast e;_;}).beatHit(curBeat);
+4
View File
@@ -13,6 +13,10 @@ import funkin.backend.system.framerate.Framerate;
import funkin.backend.system.interfaces.IBeatReceiver;
import funkin.options.PlayerSettings;
/**
* Base class for all the states.
* Handles the scripts, the transitions, and the beat and step events.
**/
class MusicBeatState extends FlxState implements IBeatReceiver
{
private var lastBeat:Float = 0;
@@ -11,6 +11,10 @@ import funkin.backend.system.Controls;
import funkin.backend.system.interfaces.IBeatReceiver;
import funkin.options.PlayerSettings;
/**
* Base class for all the sub states.
* Handles the scripts, the transitions, and the beat and step events.
**/
class MusicBeatSubstate extends FlxSubState implements IBeatReceiver
{
private var lastBeat:Float = 0;
@@ -3,6 +3,10 @@ package funkin.backend.chart;
import funkin.backend.chart.ChartData.ChartEvent;
import funkin.backend.system.Conductor;
/**
* Legacy FNF chart parser.
* This is for charts that that were made before v0.5.0.
**/
class FNFLegacyParser {
public static function parse(data:Dynamic, result:ChartData) {
// base fnf chart parsing
@@ -5,6 +5,10 @@ import funkin.backend.chart.FNFLegacyParser.SwagSection;
import funkin.backend.chart.FNFLegacyParser.SwagSong;
import funkin.backend.system.Conductor;
/**
* Parser for Psych Charts.
* Both for pre-v1.0.0 and v1.0.0 charts.
**/
class PsychParser {
// Already parsed in sections
public static var ignoreEvents:Array<String> = [
+19
View File
@@ -8,6 +8,7 @@ import lime.app.Application;
@:allow(funkin.backend.scripting.ScriptPack)
/**
* Class used for scripting.
* Use `Script.create` to create a script.
*/
class Script extends FlxBasic implements IFlxDestroyable {
/**
@@ -16,6 +17,9 @@ class Script extends FlxBasic implements IFlxDestroyable {
*/
public static var staticVariables:Map<String, Dynamic> = [];
/**
* Gets the default variables for a script.
*/
public static function getDefaultVariables(?script:Script):Map<String, Dynamic> {
return [
// Haxe related stuff
@@ -141,6 +145,10 @@ class Script extends FlxBasic implements IFlxDestroyable {
return redirects;
}
/**
* Gets the default defines for a script.
* Includes all of the defines that the build was compiled with.
*/
public static function getDefaultPreprocessors():Map<String, Dynamic> {
var defines = funkin.backend.system.macros.DefinesMacro.defines;
defines.set("CODENAME_ENGINE", true);
@@ -182,6 +190,10 @@ class Script extends FlxBasic implements IFlxDestroyable {
private var didLoad:Bool = false;
/**
* Remapped filenames.
* Used for trace messages, to show what mod the script is from.
*/
public var remappedNames:Map<String, String> = [];
/**
@@ -366,7 +378,14 @@ class Script extends FlxBasic implements IFlxDestroyable {
private function onCall(func:String, parameters:Array<Dynamic>):Dynamic {
return null;
}
/**
* Called when the script is created.
* @param path Path to the script
*/
public function onCreate(path:String) {}
/**
* Called when the script is loaded.
*/
public function onLoad() {}
}
+61 -1
View File
@@ -3,6 +3,9 @@ package funkin.backend.scripting;
import flixel.util.FlxStringUtil;
import funkin.backend.scripting.events.CancellableEvent;
/**
* Used to group multiple scripts together, and easily be able to call them.
**/
@:access(CancellableEvent)
class ScriptPack extends Script {
public var scripts:Array<Script> = [];
@@ -10,12 +13,19 @@ class ScriptPack extends Script {
public var publicVariables:Map<String, Dynamic> = [];
public var parent:Dynamic = null;
/**
* Loads all scripts in the pack.
**/
public override function load() {
for(e in scripts) {
e.load();
}
}
/**
* Checks if the script pack contains a script with a specific path.
* @param path Path to check
*/
public function contains(path:String) {
for(e in scripts)
if (e.path == path)
@@ -27,6 +37,10 @@ class ScriptPack extends Script {
super(name);
}
/**
* Gets a script by path.
* @param name Path to the script
**/
public function getByPath(name:String) {
for(s in scripts)
if (s.path == name)
@@ -34,12 +48,22 @@ class ScriptPack extends Script {
return null;
}
/**
* Gets a script by name.
* @param name Name of the script
**/
public function getByName(name:String) {
for(s in scripts)
if (s.fileName == name)
return s;
return null;
}
/**
* Imports a script by path.
* @param path Path to the script
* @throws Error if the script does not exist
**/
public function importScript(path:String):Script {
var script = Script.create(Paths.script(path));
if (script is DummyScript) {
@@ -51,6 +75,12 @@ class ScriptPack extends Script {
return script;
}
/**
* Calls a function on every single script.
* Only calls on scripts that are active.
* @param func Function to call
* @param parameters Parameters to pass to the function
**/
public override function call(func:String, ?parameters:Array<Dynamic>):Dynamic {
for(e in scripts)
if(e.active)
@@ -74,6 +104,10 @@ class ScriptPack extends Script {
return event;
}
/**
* Gets the first script that has a variable with a specific name.
* @param val Name of the variable
**/
public override function get(val:String):Dynamic {
for(e in scripts) {
var v = e.get(val);
@@ -82,40 +116,66 @@ class ScriptPack extends Script {
return null;
}
/**
* Reloads all scripts in the pack.
**/
public override function reload() {
for(e in scripts) e.reload();
}
/**
* Sets a variable in every script.
**/
public override function set(val:String, value:Dynamic) {
for(e in scripts) e.set(val, value);
}
/**
* Sets the parent/this of every script in the pack.
*/
public override function setParent(parent:Dynamic) {
this.parent = parent;
for(e in scripts) e.setParent(parent);
}
/**
* Destroys all scripts in the pack.
**/
public override function destroy() {
super.destroy();
for(e in scripts) e.destroy();
}
public override function onCreate(path:String) {}
@:dox(hide) public override function onCreate(path:String) {}
/**
* Adds a script to the pack, and sets the parent/this of the script.
**/
public function add(script:Script) {
scripts.push(script);
__configureNewScript(script);
}
/**
* Removes a script from the pack.
* Does not reset the parent/this.
**/
public function remove(script:Script) {
scripts.remove(script);
}
/**
* Inserts a script into the pack, and sets the parent/this of the script.
**/
public function insert(pos:Int, script:Script) {
scripts.insert(pos, script);
__configureNewScript(script);
}
/**
* Configures a new script.
* @param script Script to configure
**/
private function __configureNewScript(script:Script) {
if (parent != null) script.setParent(parent);
script.setPublicMap(publicVariables);
@@ -3,11 +3,13 @@ package funkin.backend.shaders;
import flixel.util.FlxColor;
import openfl.display.ShaderParameter;
@:dox(hide)
typedef BlendModeShader =
{
var uBlendColor:ShaderParameter<Float>;
}
@:dox(hide)
class BlendModeEffect
{
public var shader(default, null):BlendModeShader;
@@ -2,6 +2,7 @@ package funkin.backend.shaders;
import flixel.system.FlxAssets.FlxShader;
@:dox(hide)
class OverlayShader extends FlxShader
{
@:glFragmentSource('
@@ -3,6 +3,7 @@ package funkin.backend.shaders;
// STOLEN FROM HAXEFLIXEL DEMO LOL
import flixel.system.FlxAssets.FlxShader;
@:dox(hide)
enum WiggleEffectType
{
DREAMY;
@@ -12,6 +13,7 @@ enum WiggleEffectType
FLAG;
}
@:dox(hide)
class WiggleEffect
{
public var shader(default, null):WiggleShader = new WiggleShader();
@@ -59,6 +61,7 @@ class WiggleEffect
}
}
@:dox(hide)
class WiggleShader extends FlxShader
{
@:glFragmentSource('
+7
View File
@@ -2,7 +2,14 @@ package funkin.game;
import flixel.math.FlxPoint;
/**
* Camera meant for PlayState hud, allows for flipping the camera.
**/
class HudCamera extends FlxCamera {
/**
* Whenever the camera should flip the y axis.
* Keeps the sprites not flipped, but the positions are flipped.
*/
public var downscroll:Bool = false;
//public override function update(elapsed:Float) {
// super.update(elapsed);
+11 -1
View File
@@ -3,6 +3,10 @@ package funkin.game;
import flixel.util.FlxSort;
import funkin.backend.system.Conductor;
/**
* Group of notes, that handles updating and rendering only the visible notes.
* To only get the visible notes you gotta do `group.forEach()` or `group.forEachAlive()` instead of `group.members`.
**/
class NoteGroup extends FlxTypedGroup<Note> {
var __loopSprite:Note;
var i:Int = 0;
@@ -10,7 +14,7 @@ class NoteGroup extends FlxTypedGroup<Note> {
var __time:Float = -1.0;
/**
* How many ms it should show a note before it should be hit
* How many milliseconds it should show a note before it should be hit
**/
public var limit:Float = Flags.DEFAULT_NOTE_MS_LIMIT;
@@ -22,11 +26,17 @@ class NoteGroup extends FlxTypedGroup<Note> {
length = len;
}
/**
* Adds an array of notes to the group, and sorts them.
**/
public inline function addNotes(notes:Array<Note>) {
for(e in notes) add(e);
sortNotes();
}
/**
* Sorts the notes in the group.
**/
public inline function sortNotes() {
sort(function(i, n1, n2) {
if (n1.strumTime == n2.strumTime)
+31
View File
@@ -14,6 +14,9 @@ import haxe.xml.Access;
using StringTools;
/**
* A class that handles loading a stage and putting the sprites into the state.
**/
class Stage extends FlxBasic implements IBeatReceiver {
public var stageName:String = "";
public var stageXML:Access;
@@ -26,9 +29,15 @@ class Stage extends FlxBasic implements IBeatReceiver {
private var spritesParentFolder = "";
/**
* Gets a sprite from the stage.
**/
public function getSprite(name:String)
return stageSprites[name];
/**
* Sets the sprites in the script, so you can access them by the name.
**/
public function setStagesSprites(script:Script)
for (k=>e in stageSprites) script.set(k, e);
@@ -210,6 +219,12 @@ class Stage extends FlxBasic implements IBeatReceiver {
prepareInfos(node);
}
/**
* Adds a character position to the stage.
* @param name The name of the character
* @param node The XML node
* @param nonXMLInfo (Optional) Non-XML information
**/
public function addCharPos(name:String, node:Access, ?nonXMLInfo:StageCharPosInfo):StageCharPos {
var charPos = new StageCharPos();
charPos.visible = charPos.active = false;
@@ -252,9 +267,21 @@ class Stage extends FlxBasic implements IBeatReceiver {
return characterPoses[name] = charPos;
}
/**
* Checks if a character is flipped or not.
* @param posName The name of the character position
* @param def The default value
**/
public inline function isCharFlipped(posName:String, def:Bool = false)
return characterPoses[posName] != null ? characterPoses[posName].flipX : def;
/**
* Applies the character stuff to the character.
* Adds the character to the stage, or inserts it into the stage.
* @param char The character
* @param posName The name of the character position
* @param id The ID of the character
**/
public function applyCharStuff(char:Character, posName:String, id:Float = 0) {
var charPos = characterPoses[char.curCharacter] != null ? characterPoses[char.curCharacter] : characterPoses[posName];
if (charPos != null) {
@@ -271,6 +298,10 @@ class Stage extends FlxBasic implements IBeatReceiver {
public function measureHit(curMeasure:Int) {}
/**
* Gets a list of stages that are available to be used.
* @param mods Whenever only the mods folder should be checked
**/
public static function getList(?mods:Bool = false):Array<String> {
var list:Array<String> = [];
for (path in Paths.getFolderContent('data/stages/', true, mods ? MODS : BOTH))
+72 -5
View File
@@ -4,6 +4,9 @@ import flixel.math.FlxPoint;
import funkin.backend.system.Conductor;
class Strum extends FlxSprite {
/**
* Extra data that can be added to the strum.
**/
public var extra:Map<String, Dynamic> = [];
/**
@@ -11,21 +14,48 @@ class Strum extends FlxSprite {
*/
public var animSuffix:String = "";
public var cpu = false; // Unused
/**
* Whenever the strum should act as a CPU strum.
* WARNING: Unused.
**/
@:dox(hide) public var cpu:Bool = false; // Unused
/**
* The last time the note/confirm animation was hit.
**/
public var lastHit:Float = -5000;
public var strumLine = null;
/**
* The strum line that this strum belongs to.
**/
public var strumLine:StrumLine;
/**
* The scroll speed of the notes.
**/
public var scrollSpeed:Null<Float> = null; // custom scroll speed per strum
/**
* The direction of the notes.
* If you don't want angle of the strum to interfere with the direction the notes are going,
* you can set noteAngle to = 0, and then you can use the angle of the strum without it affecting the direction of the notes.
**/
public var noteAngle:Null<Float> = null;
public var lastDrawCameras(default, null):Array<FlxCamera> = [];
/**
* Whenever the strum is pressed.
**/
public var getPressed:StrumLine->Bool = null;
/**
* Whenever the strum was just pressed.
**/
public var getJustPressed:StrumLine->Bool = null;
/**
* Whenever the strum was just released.
**/
public var getJustReleased:StrumLine->Bool = null;
public inline function __getPressed(strumLine:StrumLine):Bool {
@:dox(hide) public inline function __getPressed(strumLine:StrumLine):Bool {
return getPressed != null ? getPressed(strumLine) : switch(ID) {
case 0: strumLine.controls.NOTE_LEFT;
case 1: strumLine.controls.NOTE_DOWN;
@@ -34,7 +64,7 @@ class Strum extends FlxSprite {
default: false;
}
}
public inline function __getJustPressed(strumLine:StrumLine) {
@:dox(hide) public inline function __getJustPressed(strumLine:StrumLine) {
return getJustPressed != null ? getJustPressed(strumLine) : switch(ID) {
case 0: strumLine.controls.NOTE_LEFT_P;
case 1: strumLine.controls.NOTE_DOWN_P;
@@ -43,7 +73,7 @@ class Strum extends FlxSprite {
default: false;
}
}
public inline function __getJustReleased(strumLine:StrumLine) {
@:dox(hide) public inline function __getJustReleased(strumLine:StrumLine) {
return getJustReleased != null ? getJustReleased(strumLine) : switch(ID) {
case 0: strumLine.controls.NOTE_LEFT_R;
case 1: strumLine.controls.NOTE_DOWN_R;
@@ -53,6 +83,10 @@ class Strum extends FlxSprite {
}
}
/**
* Gets the scroll speed of the notes.
* @param note (Optional) The note
**/
public inline function getScrollSpeed(?note:Note):Float {
if (note != null && note.scrollSpeed != null) return note.scrollSpeed;
if (scrollSpeed != null) return scrollSpeed;
@@ -60,6 +94,12 @@ class Strum extends FlxSprite {
return 1;
}
/**
* Gets the angle of the notes.
* If you don't want angle of the strum to interfere with the direction the notes are going,
* you can set noteAngle to = 0, and then you can use the angle of the strum without it affecting the direction of the notes.
* @param note (Optional) The note
**/
public inline function getNotesAngle(?note:Note):Float {
if (note != null && note.noteAngle != null) return note.noteAngle;
if (noteAngle != null) return noteAngle;
@@ -83,6 +123,10 @@ class Strum extends FlxSprite {
@:noCompletion public static final PIX180:Float = 565.4866776461628; // 180 * Math.PI
@:noCompletion public static final N_WIDTHDIV2:Float = Note.swagWidth / 2;
/**
* Updates the position of a note.
* @param daNote The note
**/
public function updateNotePosition(daNote:Note) {
if (!daNote.exists) return;
@@ -130,11 +174,21 @@ class Strum extends FlxSprite {
}
}
/**
* Updates a sustain note.
* @param daNote The note
**/
public inline function updateSustain(daNote:Note) {
if (!daNote.isSustainNote) return;
daNote.updateSustain(this);
}
/**
* Updates the animation state based on the player input.
* @param pressed Whenever the player is pressing the button
* @param justPressed Whenever the player just pressed the button
* @param justReleased Whenever the player just released the button
**/
public function updatePlayerInput(pressed:Bool, justPressed:Bool, justReleased:Bool) {
switch(getAnim()) {
case "confirm":
@@ -151,16 +205,29 @@ class Strum extends FlxSprite {
}
}
/**
* Plays the confirm animation.
* @param time The time
**/
public inline function press(time:Float) {
lastHit = time;
playAnim("confirm");
}
/**
* Plays an animation.
* @param anim The animation name
* @param force Whenever the animation should be forced to play
**/
public function playAnim(anim:String, force:Bool = true) {
animation.play(anim, force);
centerOffsets();
centerOrigin();
}
/**
* Gets the current animation name.
**/
public inline function getAnim() {
return animation.name;
}
+38 -2
View File
@@ -9,6 +9,10 @@ import funkin.backend.scripting.events.note.*;
import funkin.backend.system.Conductor;
import funkin.backend.system.Controls;
/**
* Group of strums, that contains the strums and notes.
* Used in PlayState.
**/
class StrumLine extends FlxTypedGroup<Strum> {
/**
* Signal that triggers whenever a note is hit. Similar to onPlayerHit and onDadHit, except strumline specific.
@@ -78,7 +82,9 @@ class StrumLine extends FlxTypedGroup<Strum> {
* Vocals sound (Vocals.ogg). Used for individual vocals per strumline.
*/
public var vocals:FlxSound;
/**
* Extra data that can be added to the strum line.
**/
public var extra:Map<String, Dynamic> = [];
private function get_ghostTapping() {
@@ -90,8 +96,14 @@ class StrumLine extends FlxTypedGroup<Strum> {
private inline function set_ghostTapping(b:Bool):Bool
return this.ghostTapping = b;
private var startingPos:FlxPoint = FlxPoint.get(0,0);
private var strumScale:Float = 1;
/**
* The scale of the strums.
* If called after generate, the strums wont be scaled.
* You can only change it in the Charter.
**/
public var strumScale:Float = 1;
public function new(characters:Array<Character>, startingPos:FlxPoint, strumScale:Float, cpu:Bool = false, opponentSide:Bool = true, ?controls:Controls, ?vocalPrefix:String = "") {
super();
@@ -106,6 +118,9 @@ class StrumLine extends FlxTypedGroup<Strum> {
vocals.persist = false;
}
/**
* Generates the notes for the strumline.
**/
public function generate(strumLine:ChartStrumLine, ?startTime:Float) {
// TODO: implement double generate call support if needed
@@ -171,6 +186,9 @@ class StrumLine extends FlxTypedGroup<Strum> {
notes.draw();
}
/**
* Updates the notes.
**/
public inline function updateNotes() {
__updateNote_songPos = Conductor.songPosition;
if(__updateNote_event == null) __updateNote_event = PlayState.instance.__updateNote_event;
@@ -180,6 +198,10 @@ class StrumLine extends FlxTypedGroup<Strum> {
var __updateNote_strum:Strum;
var __updateNote_songPos:Float;
var __updateNote_event:NoteUpdateEvent;
/**
* Updates a note.
* This updates the position, state, and handles the input.
**/
public function updateNote(daNote:Note) {
__updateNote_strum = members[daNote.noteData];
if (__updateNote_strum == null) return;
@@ -236,6 +258,11 @@ class StrumLine extends FlxTypedGroup<Strum> {
else if (note.strumTime < __notePerStrum[note.strumID].strumTime) __notePerStrum[note.strumID] = note;
}
}
/**
* Updates the input for the strumline, and handles the input.
* @param id The ID of the strum
**/
public function updateInput(id:Int = 0) {
updateNotes();
@@ -291,9 +318,18 @@ class StrumLine extends FlxTypedGroup<Strum> {
PlayState.instance.gameAndCharsCall("onPostInputUpdate");
}
/**
* Adds/removes health to/from the strumline.
* If the strumline is an opponent strumline, it will subtract the health, otherwise it will add the health.
* @param health The amount of health to add/remove
**/
public inline function addHealth(health:Float)
PlayState.instance.health += health * (opponentSide ? -1 : 1);
/**
* Generates strums, and adds them to the strumline.
* @param amount The amount of strums to generate (-1 for the default amount)
**/
public inline function generateStrums(amount:Int = -1) {
if(amount == -1) amount = Flags.DEFAULT_STRUM_AMOUNT;
for (i in 0...amount)
+4
View File
@@ -4,6 +4,10 @@ import flixel.input.keyboard.FlxKey;
import flixel.util.FlxSave;
import openfl.Lib;
/**
* The save data of the engine.
* Mod save data is stored in `FlxG.save.data`.
**/
@:build(funkin.backend.system.macros.OptionsMacro.build())
@:build(funkin.backend.system.macros.FunkinSaveMacro.build("__save", "__flush", "__load"))
class Options
@@ -1,5 +1,8 @@
package funkin.options.type;
/**
* Option type that allows you to select an array of options.
**/
class ArrayOption extends OptionType {
public var selectCallback:String->Void;
+3
View File
@@ -2,6 +2,9 @@ package funkin.options.type;
import flixel.math.FlxPoint;
/**
* Option type that allows you to toggle a checkbox.
**/
class Checkbox extends TextOption {
public var checkbox:FlxSprite;
+4
View File
@@ -2,6 +2,10 @@ package funkin.options.type;
import funkin.game.HealthIcon;
/**
* Option type that has an icon.
* Used for the credits menu.
**/
class IconOption extends TextOption {
public var iconSpr:HealthIcon;
+3
View File
@@ -3,6 +3,9 @@ package funkin.options.type;
import flixel.util.FlxColor;
import funkin.game.HealthIcon;
/**
* Option type that has a new button, and is green.
**/
class NewOption extends TextOption {
public var iconSpr:FlxSprite;
+3
View File
@@ -2,6 +2,9 @@ package funkin.options.type;
import flixel.effects.FlxFlicker;
/**
* Option type that allows stepping through a number.
**/
class NumOption extends OptionType {
public var selectCallback:Float->Void;
+4
View File
@@ -3,6 +3,10 @@ package funkin.options.type;
import flixel.group.FlxSpriteGroup;
import funkin.backend.system.Controls;
/**
* Base class for all option types.
* Used in OptionsMenu.
**/
class OptionType extends FlxSpriteGroup {
public var controls(get, never):Controls;
public var selected:Bool = false;
@@ -3,6 +3,10 @@ package funkin.options.type;
import flixel.graphics.FlxGraphic;
import funkin.backend.shaders.CustomShader;
/**
* Option type that has a portrait.
* Used in the credits menu.
**/
class PortraitOption extends TextOption {
public var portrait:FlxSprite = null;
+3
View File
@@ -2,6 +2,9 @@ package funkin.options.type;
import flixel.effects.FlxFlicker;
/**
* Option type that has text.
**/
class TextOption extends OptionType {
public var selectCallback:Void->Void;