Fix a bunch of merge bugs.

This commit is contained in:
EliteMasterEric 2024-03-23 15:34:37 -04:00
parent 831d6aae71
commit dc638a1303
40 changed files with 216 additions and 181 deletions

View File

@ -233,26 +233,26 @@ class Conductor
function get_inputOffset():Int
{
return Save.get().options.inputOffset;
return Save.instance.options.inputOffset;
}
function set_inputOffset(value:Int):Int
{
Save.get().options.inputOffset = value;
Save.get().flush();
return Save.get().options.inputOffset;
Save.instance.options.inputOffset = value;
Save.instance.flush();
return Save.instance.options.inputOffset;
}
function get_audioVisualOffset():Int
{
return Save.get().options.audioVisualOffset;
return Save.instance.options.audioVisualOffset;
}
function set_audioVisualOffset(value:Int):Int
{
Save.get().options.audioVisualOffset = value;
Save.get().flush();
return Save.get().options.audioVisualOffset;
Save.instance.options.audioVisualOffset = value;
Save.instance.flush();
return Save.instance.options.audioVisualOffset;
}
/**

View File

@ -16,14 +16,14 @@ import funkin.util.macro.MacroUtil;
import funkin.util.WindowUtil;
import funkin.play.PlayStatePlaylist;
import openfl.display.BitmapData;
import funkin.data.level.LevelRegistry;
import funkin.data.story.level.LevelRegistry;
import funkin.data.notestyle.NoteStyleRegistry;
import funkin.data.event.SongEventRegistry;
import funkin.data.stage.StageRegistry;
import funkin.data.dialogue.ConversationRegistry;
import funkin.data.dialogue.DialogueBoxRegistry;
import funkin.data.dialogue.SpeakerRegistry;
import funkin.data.freeplay.AlbumRegistry;
import funkin.data.dialogue.conversation.ConversationRegistry;
import funkin.data.dialogue.dialoguebox.DialogueBoxRegistry;
import funkin.data.dialogue.speaker.SpeakerRegistry;
import funkin.data.freeplay.album.AlbumRegistry;
import funkin.data.song.SongRegistry;
import funkin.play.character.CharacterData.CharacterDataParser;
import funkin.modding.module.ModuleHandler;
@ -275,7 +275,7 @@ class InitState extends FlxState
*/
function startLevel(levelId:String, difficultyId:String = 'normal'):Void
{
var currentLevel:funkin.ui.story.Level = funkin.data.level.LevelRegistry.instance.fetchEntry(levelId);
var currentLevel:funkin.ui.story.Level = funkin.data.story.level.LevelRegistry.instance.fetchEntry(levelId);
if (currentLevel == null)
{

View File

@ -120,7 +120,7 @@ class DataParse
}
}
public static function backdropData(json:Json, name:String):funkin.data.dialogue.ConversationData.BackdropData
public static function backdropData(json:Json, name:String):funkin.data.dialogue.conversation.ConversationData.BackdropData
{
switch (json.value)
{
@ -152,7 +152,7 @@ class DataParse
}
}
public static function outroData(json:Json, name:String):Null<funkin.data.dialogue.ConversationData.OutroData>
public static function outroData(json:Json, name:String):Null<funkin.data.dialogue.conversation.ConversationData.OutroData>
{
switch (json.value)
{

View File

@ -0,0 +1,9 @@
# Dialogue Conversation 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.

View File

@ -1,4 +1,4 @@
package funkin.data.dialogue;
package funkin.data.dialogue.conversation;
import funkin.data.animation.AnimationData;

View File

@ -1,7 +1,7 @@
package funkin.data.dialogue;
package funkin.data.dialogue.conversation;
import funkin.play.cutscene.dialogue.Conversation;
import funkin.data.dialogue.ConversationData;
import funkin.data.dialogue.conversation.ConversationData;
import funkin.play.cutscene.dialogue.ScriptedConversation;
class ConversationRegistry extends BaseRegistry<Conversation, ConversationData>

View File

@ -0,0 +1,13 @@
# Dialogue Box 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.1.0]
### Added
- Added an option to specify the font used by the dialogue box. Defaults to `Arial` if unspecified.
## [1.0.0]
Initial release.

View File

@ -1,4 +1,4 @@
package funkin.data.dialogue;
package funkin.data.dialogue.dialoguebox;
import funkin.data.animation.AnimationData;

View File

@ -1,7 +1,7 @@
package funkin.data.dialogue;
package funkin.data.dialogue.dialoguebox;
import funkin.play.cutscene.dialogue.DialogueBox;
import funkin.data.dialogue.DialogueBoxData;
import funkin.data.dialogue.dialoguebox.DialogueBoxData;
import funkin.play.cutscene.dialogue.ScriptedDialogueBox;
class DialogueBoxRegistry extends BaseRegistry<DialogueBox, DialogueBoxData>

View File

@ -0,0 +1,9 @@
# Dialogue Speaker 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.

View File

@ -1,4 +1,4 @@
package funkin.data.dialogue;
package funkin.data.dialogue.speaker;
import funkin.data.animation.AnimationData;

View File

@ -1,7 +1,7 @@
package funkin.data.dialogue;
package funkin.data.dialogue.speaker;
import funkin.play.cutscene.dialogue.Speaker;
import funkin.data.dialogue.SpeakerData;
import funkin.data.dialogue.speaker.SpeakerData;
import funkin.play.cutscene.dialogue.ScriptedSpeaker;
class SpeakerRegistry extends BaseRegistry<Speaker, SpeakerData>

View File

@ -1,4 +1,4 @@
package funkin.data.freeplay;
package funkin.data.freeplay.album;
/**
* A type definition for the data for an album of songs.

View File

@ -1,7 +1,7 @@
package funkin.data.freeplay;
package funkin.data.freeplay.album;
import funkin.ui.freeplay.Album;
import funkin.data.freeplay.AlbumData;
import funkin.data.freeplay.album.AlbumData;
import funkin.ui.freeplay.ScriptedAlbum;
class AlbumRegistry extends BaseRegistry<Album, AlbumData>

View File

@ -0,0 +1,9 @@
# Freeplay Album 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.

View File

@ -0,0 +1,36 @@
# Song Chart 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).
## [2.2.2]
### Added
- Added `playData.previewStart` and `playData.previewEnd` fields to specify when in the song should the song's audio should be played as a preview in Freeplay.
## [2.2.1]
### Added
- Added `playData.offsets` field to specify instrumental and vocal offsets.
## [2.2.0]
### Added
- Added `playData.album` to specify the album art to display in Freeplay.
- Added `playData.ratings` for difficulty ratings displayed in Freeplay.
### Changed
- Renamed `playData.noteSkin` to `playData.noteStyle`.
## [2.1.0]
### Changed
- Rearranged the `playData` field.
- Refactored the `playableChars`
### Removed
- Removed the `variation` field.
## [2.0.0]
Full refactor of the chart format for improved structure.
### Added
- Added a semantic version field for migration tracking.
## [1.0.0]
Initial version from 2020.

View File

@ -0,0 +1,14 @@
# Story Mode Level 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.1]
### Added
- Added the ability to specify a hexadecimal color in the `assetPath` field instead of a texture key.
- In this case, the `scale` property will be used to determine the size of the rectangle in pixels.
## [1.0.0]
Initial release.

View File

@ -11,7 +11,7 @@ class StageRegistry extends BaseRegistry<Stage, StageData>
* Handle breaking changes by incrementing this value
* and adding migration to the `migrateStageData()` function.
*/
public static final STAGE_DATA_VERSION:thx.semver.Version = "1.0.1";
public static final STAGE_DATA_VERSION:thx.semver.Version = "1.0.0";
public static final STAGE_DATA_VERSION_RULE:thx.semver.VersionRule = "1.0.x";

View File

@ -0,0 +1,9 @@
# Story Mode Level 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.

View File

@ -1,4 +1,4 @@
package funkin.data.level;
package funkin.data.story.level;
import funkin.data.animation.AnimationData;
@ -13,7 +13,7 @@ typedef LevelData =
* When making changes to the level data format, this should be incremented,
* and a migration function should be added to LevelDataParser to handle old versions.
*/
@:default(funkin.data.level.LevelRegistry.LEVEL_DATA_VERSION)
@:default(funkin.data.story.level.LevelRegistry.LEVEL_DATA_VERSION)
var version:String;
/**

View File

@ -1,7 +1,7 @@
package funkin.data.level;
package funkin.data.story.level;
import funkin.ui.story.Level;
import funkin.data.level.LevelData;
import funkin.data.story.level.LevelData;
import funkin.ui.story.ScriptedLevel;
class LevelRegistry extends BaseRegistry<Level, LevelData>

View File

@ -1,14 +1,14 @@
package funkin.modding;
import funkin.data.dialogue.ConversationRegistry;
import funkin.data.dialogue.DialogueBoxRegistry;
import funkin.data.dialogue.SpeakerRegistry;
import funkin.data.dialogue.conversation.ConversationRegistry;
import funkin.data.dialogue.dialoguebox.DialogueBoxRegistry;
import funkin.data.dialogue.speaker.SpeakerRegistry;
import funkin.data.event.SongEventRegistry;
import funkin.data.level.LevelRegistry;
import funkin.data.story.level.LevelRegistry;
import funkin.data.notestyle.NoteStyleRegistry;
import funkin.data.song.SongRegistry;
import funkin.data.stage.StageRegistry;
import funkin.data.freeplay.AlbumRegistry;
import funkin.data.freeplay.album.AlbumRegistry;
import funkin.modding.module.ModuleHandler;
import funkin.play.character.CharacterData.CharacterDataParser;
import funkin.save.Save;

View File

@ -24,7 +24,7 @@ import flixel.util.FlxTimer;
import funkin.api.newgrounds.NGio;
import funkin.audio.VoicesGroup;
import funkin.audio.VoicesGroup;
import funkin.data.dialogue.ConversationRegistry;
import funkin.data.dialogue.conversation.ConversationRegistry;
import funkin.data.event.SongEventRegistry;
import funkin.data.notestyle.NoteStyleData;
import funkin.data.notestyle.NoteStyleRegistry;
@ -2011,10 +2011,10 @@ class PlayState extends MusicBeatSubState
{
if (note == null) continue;
// TODO: Does this properly account for offsets?
var hitWindowStart = note.strumTime - Constants.HIT_WINDOW_MS;
var hitWindowCenter = note.strumTime;
var hitWindowEnd = note.strumTime + Constants.HIT_WINDOW_MS;
// TODO: Are offsets being accounted for in the correct direction?
var hitWindowStart = note.strumTime + Conductor.instance.inputOffset - Constants.HIT_WINDOW_MS;
var hitWindowCenter = note.strumTime + Conductor.instance.inputOffset;
var hitWindowEnd = note.strumTime + Conductor.instance.inputOffset + Constants.HIT_WINDOW_MS;
if (Conductor.instance.songPosition > hitWindowEnd)
{

View File

@ -16,13 +16,13 @@ import funkin.play.cutscene.dialogue.DialogueBox;
import funkin.modding.IScriptedClass.IDialogueScriptedClass;
import funkin.modding.events.ScriptEventDispatcher;
import flixel.addons.display.FlxPieDial;
import funkin.data.dialogue.ConversationData;
import funkin.data.dialogue.ConversationData.DialogueEntryData;
import funkin.data.dialogue.ConversationRegistry;
import funkin.data.dialogue.SpeakerData;
import funkin.data.dialogue.SpeakerRegistry;
import funkin.data.dialogue.DialogueBoxData;
import funkin.data.dialogue.DialogueBoxRegistry;
import funkin.data.dialogue.conversation.ConversationData;
import funkin.data.dialogue.conversation.ConversationData.DialogueEntryData;
import funkin.data.dialogue.conversation.ConversationRegistry;
import funkin.data.dialogue.speaker.SpeakerData;
import funkin.data.dialogue.speaker.SpeakerRegistry;
import funkin.data.dialogue.dialoguebox.DialogueBoxData;
import funkin.data.dialogue.dialoguebox.DialogueBoxRegistry;
/**
* A high-level handler for dialogue.

View File

@ -11,8 +11,8 @@ import funkin.modding.events.ScriptEvent;
import funkin.audio.FunkinSound;
import funkin.modding.IScriptedClass.IDialogueScriptedClass;
import flixel.util.FlxColor;
import funkin.data.dialogue.DialogueBoxData;
import funkin.data.dialogue.DialogueBoxRegistry;
import funkin.data.dialogue.dialoguebox.DialogueBoxData;
import funkin.data.dialogue.dialoguebox.DialogueBoxRegistry;
class DialogueBox extends FlxSpriteGroup implements IDialogueScriptedClass implements IRegistryEntry<DialogueBoxData>
{

View File

@ -6,8 +6,8 @@ import funkin.modding.events.ScriptEvent;
import flixel.graphics.frames.FlxFramesCollection;
import funkin.util.assets.FlxAnimationUtil;
import funkin.modding.IScriptedClass.IDialogueScriptedClass;
import funkin.data.dialogue.SpeakerData;
import funkin.data.dialogue.SpeakerRegistry;
import funkin.data.dialogue.speaker.SpeakerData;
import funkin.data.dialogue.speaker.SpeakerRegistry;
/**
* The character sprite which displays during dialogue.

View File

@ -50,7 +50,20 @@ class Strumline extends FlxSpriteGroup
* Usually you want to keep this as is, but if you are using a Strumline and
* playing a sound that has it's own conductor, set this (LatencyState for example)
*/
public var conductorInUse:Conductor = Conductor.instance;
public var conductorInUse(get, set):Conductor;
var _conductorInUse:Null<Conductor>;
function get_conductorInUse():Conductor
{
if (_conductorInUse == null) return Conductor.instance;
return _conductorInUse;
}
function set_conductorInUse(value:Conductor):Conductor
{
return _conductorInUse = value;
}
/**
* The notes currently being rendered on the strumline.
@ -159,103 +172,9 @@ class Strumline extends FlxSpriteGroup
}
/**
* Process the notes in this strumline.
* @param onNoteMiss
* @param dispatchEvent TODO: better way to do this? Maybe passing in current dispatchEvent function from current state?
* Return notes that are within `Constants.HIT_WINDOW` ms of the strumline.
* @return An array of `NoteSprite` objects.
*/
public function processNotes(?onNoteMiss:NoteSprite->Void, ?dispatchEvent:ScriptEvent->Void)
{
for (note in notes.members)
{
if (note == null || (isPlayer && note.hasBeenHit)) continue;
var hitWindowStart = note.strumTime - Constants.HIT_WINDOW_MS;
var hitWindowCenter = note.strumTime;
var hitWindowEnd = note.strumTime + Constants.HIT_WINDOW_MS;
if (conductorInUse.songPosition > hitWindowEnd)
{
if (!isPlayer && note.hasMissed) continue;
note.tooEarly = false;
note.mayHit = false;
note.hasMissed = true;
if (note.holdNoteSprite != null) note.holdNoteSprite.missedNote = true;
}
else if (conductorInUse.songPosition > hitWindowCenter)
{
// only run this on opponent strumlines!
if (!isPlayer) continue;
// Call an event to allow canceling the note hit.
// NOTE: This is what handles the character animations!
var event:NoteScriptEvent = new NoteScriptEvent(NOTE_HIT, note, 0, true);
if (dispatchEvent != null) dispatchEvent(event);
// Calling event.cancelEvent() skips all other logic! Neat!
if (event.eventCanceled) continue;
// Command the opponent to hit the note on time.
// NOTE: This is what handles the strumline and cleaning up the note itself!
hitNote(note);
if (note.holdNoteSprite != null)
{
playNoteHoldCover(note.holdNoteSprite);
}
}
else if (conductorInUse.songPosition > hitWindowStart)
{
if (!isPlayer && (note.hasBeenHit || note.hasMissed)) continue;
note.tooEarly = false;
note.mayHit = true;
note.hasMissed = false;
if (note.holdNoteSprite != null) note.holdNoteSprite.missedNote = false;
}
else
{
note.tooEarly = true;
note.mayHit = false;
note.hasMissed = false;
if (note.holdNoteSprite != null) note.holdNoteSprite.missedNote = false;
}
if (note.hasMissed && !note.handledMiss)
{
var event:NoteScriptEvent = new NoteScriptEvent(NOTE_MISS, note, 0, true);
if (dispatchEvent != null) dispatchEvent(event);
if (event.eventCanceled) continue;
if (onNoteMiss != null) onNoteMiss(note);
note.handledMiss = true;
}
}
}
var frameMax:Int;
var animFinishedEver:Bool;
/**
* Get a list of notes within + or - the given strumtime.
* @param strumTime The current time.
* @param hitWindow The hit window to check.
*/
public function getNotesInRange(strumTime:Float, hitWindow:Float):Array<NoteSprite>
{
var hitWindowStart:Float = strumTime - hitWindow;
var hitWindowEnd:Float = strumTime + hitWindow;
return notes.members.filter(function(note:NoteSprite) {
return note != null && note.alive && !note.hasBeenHit && note.strumTime >= hitWindowStart && note.strumTime <= hitWindowEnd;
});
}
public function getNotesMayHit():Array<NoteSprite>
{
return notes.members.filter(function(note:NoteSprite) {
@ -263,6 +182,10 @@ class Strumline extends FlxSpriteGroup
});
}
/**
* Return hold notes that are within `Constants.HIT_WINDOW` ms of the strumline.
* @return An array of `SustainTrail` objects.
*/
public function getHoldNotesHitOrMissed():Array<SustainTrail>
{
return holdNotes.members.filter(function(holdNote:SustainTrail) {
@ -270,19 +193,6 @@ class Strumline extends FlxSpriteGroup
});
}
public function getHoldNotesInRange(strumTime:Float, hitWindow:Float):Array<SustainTrail>
{
var hitWindowStart:Float = strumTime - hitWindow;
var hitWindowEnd:Float = strumTime + hitWindow;
return holdNotes.members.filter(function(note:SustainTrail) {
return note != null
&& note.alive
&& note.strumTime >= hitWindowStart
&& (note.strumTime + note.fullSustainLength) <= hitWindowEnd;
});
}
public function getNoteSprite(noteData:SongNoteData):NoteSprite
{
if (noteData == null) return null;
@ -382,6 +292,9 @@ class Strumline extends FlxSpriteGroup
{
if (noteData.length == 0) return;
// Ensure note data gets reset if the song happens to loop.
if (conductorInUse.currentStep == 0) nextNoteIndex = 0;
var songStart:Float = PlayState.instance?.startTimestamp ?? 0.0;
var hitWindowStart:Float = conductorInUse.songPosition - Constants.HIT_WINDOW_MS;
var renderWindowStart:Float = conductorInUse.songPosition + RENDER_DISTANCE_MS;

View File

@ -27,7 +27,21 @@ class MusicBeatState extends FlxTransitionableState implements IEventHandler
public var leftWatermarkText:FlxText = null;
public var rightWatermarkText:FlxText = null;
public var conductorInUse:Conductor = Conductor.instance;
public var conductorInUse(get, set):Conductor;
var _conductorInUse:Null<Conductor>;
function get_conductorInUse():Conductor
{
if (_conductorInUse == null) return Conductor.instance;
return _conductorInUse;
}
function set_conductorInUse(value:Conductor):Conductor
{
return _conductorInUse = value;
}
public function new()
{

View File

@ -21,7 +21,7 @@ class MusicBeatSubState extends FlxSubState implements IEventHandler
public var leftWatermarkText:FlxText = null;
public var rightWatermarkText:FlxText = null;
public var conductorInUse(get, default):Conductor;
public var conductorInUse(get, set):Conductor;
var _conductorInUse:Null<Conductor>;
@ -31,6 +31,11 @@ class MusicBeatSubState extends FlxSubState implements IEventHandler
return _conductorInUse;
}
function set_conductorInUse(value:Conductor):Conductor
{
return _conductorInUse = value;
}
public function new(bgColor:FlxColor = FlxColor.TRANSPARENT)
{
super();

View File

@ -5,13 +5,13 @@ import funkin.modding.events.ScriptEventDispatcher;
import funkin.modding.events.ScriptEvent;
import flixel.util.FlxColor;
import funkin.ui.MusicBeatState;
import funkin.data.dialogue.ConversationData;
import funkin.data.dialogue.ConversationRegistry;
import funkin.data.dialogue.DialogueBoxData;
import funkin.data.dialogue.DialogueBoxRegistry;
import funkin.data.dialogue.SpeakerData;
import funkin.data.dialogue.SpeakerRegistry;
import funkin.data.freeplay.AlbumRegistry;
import funkin.data.dialogue.conversation.ConversationData;
import funkin.data.dialogue.conversation.ConversationRegistry;
import funkin.data.dialogue.dialoguebox.DialogueBoxData;
import funkin.data.dialogue.dialoguebox.DialogueBoxRegistry;
import funkin.data.dialogue.speaker.SpeakerData;
import funkin.data.dialogue.speaker.SpeakerRegistry;
import funkin.data.freeplay.album.AlbumRegistry;
import funkin.play.cutscene.dialogue.Conversation;
import funkin.play.cutscene.dialogue.DialogueBox;
import funkin.play.cutscene.dialogue.Speaker;

View File

@ -1,7 +1,7 @@
package funkin.ui.freeplay;
import funkin.data.freeplay.AlbumData;
import funkin.data.freeplay.AlbumRegistry;
import funkin.data.freeplay.album.AlbumData;
import funkin.data.freeplay.album.AlbumRegistry;
import funkin.data.IRegistryEntry;
import flixel.graphics.FlxGraphic;

View File

@ -6,7 +6,7 @@ import flixel.util.FlxSort;
import flixel.tweens.FlxTween;
import flixel.util.FlxTimer;
import flixel.tweens.FlxEase;
import funkin.data.freeplay.AlbumRegistry;
import funkin.data.freeplay.album.AlbumRegistry;
import funkin.graphics.FunkinSprite;
import funkin.util.SortUtil;
import openfl.utils.Assets;

View File

@ -18,7 +18,7 @@ import flixel.util.FlxColor;
import flixel.util.FlxSpriteUtil;
import flixel.util.FlxTimer;
import funkin.audio.FunkinSound;
import funkin.data.level.LevelRegistry;
import funkin.data.story.level.LevelRegistry;
import funkin.data.song.SongRegistry;
import funkin.graphics.FunkinCamera;
import funkin.graphics.FunkinSprite;

View File

@ -1,5 +1,6 @@
package funkin.ui.options;
import funkin.ui.debug.latency.LatencyState;
import flixel.FlxSprite;
import flixel.FlxSubState;
import flixel.addons.transition.FlxTransitionableState;
@ -182,6 +183,9 @@ class OptionsMenu extends Page
add(items = new TextMenuList());
createItem("PREFERENCES", function() switchPage(Preferences));
createItem("CONTROLS", function() switchPage(Controls));
createItem("INPUT OFFSETS", function() {
FlxG.state.openSubState(new LatencyState());
});
#if newgrounds
if (NGio.isLoggedIn) createItem("LOGOUT", selectLogout);

View File

@ -6,8 +6,8 @@ import flixel.util.FlxColor;
import funkin.play.song.Song;
import funkin.data.IRegistryEntry;
import funkin.data.song.SongRegistry;
import funkin.data.level.LevelRegistry;
import funkin.data.level.LevelData;
import funkin.data.story.level.LevelRegistry;
import funkin.data.story.level.LevelData;
/**
* An object used to retrieve data about a story mode level (also known as "weeks").

View File

@ -2,7 +2,7 @@ package funkin.ui.story;
import funkin.play.stage.Bopper;
import funkin.util.assets.FlxAnimationUtil;
import funkin.data.level.LevelData;
import funkin.data.story.level.LevelData;
class LevelProp extends Bopper
{

View File

@ -9,7 +9,7 @@ import flixel.tweens.FlxTween;
import flixel.util.FlxColor;
import flixel.util.FlxTimer;
import funkin.audio.FunkinSound;
import funkin.data.level.LevelRegistry;
import funkin.data.story.level.LevelRegistry;
import funkin.data.song.SongRegistry;
import funkin.graphics.FunkinSprite;
import funkin.modding.events.ScriptEvent;