diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 0f1985fab..b03d67fc0 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -60,7 +60,7 @@ This section provides guidelines to follow when [opening an issue](https://githu ## Requirements Make sure you're playing: -- the latest version of the game (currently v0.6.2) +- the latest version of the game (currently v0.6.3) - without any mods - on [Newgrounds](https://www.newgrounds.com/portal/view/770371) or downloaded from [itch.io](https://ninja-muffin24.itch.io/funkin) @@ -412,4 +412,4 @@ If your PR is accepted, you will be credited as a GitHub contributor (but not as # Closing Thank you for reading the Contributing Guide. -We look forward to seeing your contributions to the game! \ No newline at end of file +We look forward to seeing your contributions to the game! diff --git a/hmm.json b/hmm.json index 41624948c..406a2a1d7 100644 --- a/hmm.json +++ b/hmm.json @@ -143,7 +143,7 @@ "name": "lime", "type": "git", "dir": null, - "ref": "1e79c20a6ee13fa168535f9f76a368e3284ddc3a", + "ref": "be81ad7e4e1a92c3482bcc009648a4ac892cfa35", "url": "https://github.com/FunkinCrew/lime" }, { diff --git a/project.hxp b/project.hxp index 43666b3b5..858cdbdf6 100644 --- a/project.hxp +++ b/project.hxp @@ -25,7 +25,7 @@ class Project extends HXProject { * REMEMBER TO CHANGE THIS WHEN THE GAME UPDATES! * You only have to change it here, the rest of the game will query this value. */ - static final VERSION:String = "0.6.2"; + static final VERSION:String = "0.6.3"; /** * The game's name. Used as the default window title. diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 642d3ced9..e4b7d7ad3 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -875,6 +875,10 @@ class PlayState extends MusicBeatSubState // Delete all notes and reset the arrays. regenNoteData(); + // so the song doesn't start too early :D + Conductor.instance.update(-5000, false); + + // Reset camera zooming cameraBopIntensity = Constants.DEFAULT_BOP_INTENSITY; hudCameraZoomIntensity = (cameraBopIntensity - 1.0) * 2.0; @@ -883,11 +887,27 @@ class PlayState extends MusicBeatSubState health = Constants.HEALTH_STARTING; songScore = 0; Highscore.tallies.combo = 0; - Countdown.performCountdown(); + // timer for vwoosh + var vwooshTimer = new FlxTimer(); + vwooshTimer.start(0.5, function(t:FlxTimer) { + Conductor.instance.update(startTimestamp - Conductor.instance.combinedOffset, false); + if (playerStrumline.notes.length == 0) playerStrumline.updateNotes(); + if (opponentStrumline.notes.length == 0) opponentStrumline.updateNotes(); + playerStrumline.vwooshInNotes(); + opponentStrumline.vwooshInNotes(); + Countdown.performCountdown(); + }); + // Reset the health icons. + if (currentStage.getBoyfriend() != null) + { currentStage.getBoyfriend().initHealthIcon(false); + } + if (currentStage.getDad() != null) + { currentStage.getDad().initHealthIcon(true); + } needsReset = false; } diff --git a/source/funkin/play/notes/NoteSprite.hx b/source/funkin/play/notes/NoteSprite.hx index 4fa0a4052..509bfc3e6 100644 --- a/source/funkin/play/notes/NoteSprite.hx +++ b/source/funkin/play/notes/NoteSprite.hx @@ -104,6 +104,11 @@ class NoteSprite extends FunkinSprite return noteData.length > 0; } + /** + * The Y Offset of the note. + */ + public var yOffset:Float = 0.0; + /** * Set this flag to true when hitting the note to avoid scoring it multiple times. */ diff --git a/source/funkin/play/notes/Strumline.hx b/source/funkin/play/notes/Strumline.hx index 2c941d31d..50c85b733 100644 --- a/source/funkin/play/notes/Strumline.hx +++ b/source/funkin/play/notes/Strumline.hx @@ -1,5 +1,6 @@ package funkin.play.notes; +import flixel.math.FlxPoint; import flixel.util.FlxSignal.FlxTypedSignal; import flixel.FlxG; import funkin.play.notes.notestyle.NoteStyle; @@ -18,35 +19,46 @@ import funkin.play.notes.notekind.NoteKindManager; */ class Strumline extends FlxSpriteGroup { + /** + * The directions of the notes on the strumline, in order. + */ public static final DIRECTIONS:Array = [NoteDirection.LEFT, NoteDirection.DOWN, NoteDirection.UP, NoteDirection.RIGHT]; + + /** + * A magic number for the size of the strumline, in pixels. + */ public static final STRUMLINE_SIZE:Int = 104; + + /** + * The spacing between notes on the strumline, in pixels. + */ public static final NOTE_SPACING:Int = STRUMLINE_SIZE + 8; // Positional fixes for new strumline graphics. - static final INITIAL_OFFSET = -0.275 * STRUMLINE_SIZE; + static final INITIAL_OFFSET:Float = -0.275 * STRUMLINE_SIZE; static final NUDGE:Float = 2.0; static final KEY_COUNT:Int = 4; static final NOTE_SPLASH_CAP:Int = 6; - static var RENDER_DISTANCE_MS(get, never):Float; + var renderDistanceMs(get, never):Float; /** * The custom render distance for the strumline. * This should be in miliseconds only! Not pixels. */ - public static var CUSTOM_RENDER_DISTANCE_MS:Float = 0.0; + public var customRenderDistanceMs:Float = 0.0; /** * Whether to use the custom render distance. * If false, the render distance will be calculated based on the screen height. */ - public static var USE_CUSTOM_RENDER_DISTANCE:Bool = false; + public var useCustomRenderDistance:Bool = false; - static function get_RENDER_DISTANCE_MS():Float + function get_renderDistanceMs():Float { - if (USE_CUSTOM_RENDER_DISTANCE) return CUSTOM_RENDER_DISTANCE_MS; - return FlxG.height / Constants.PIXELS_PER_MS; + if (useCustomRenderDistance) return customRenderDistanceMs; + return FlxG.height / Constants.PIXELS_PER_MS / scrollSpeed; } /** @@ -71,6 +83,9 @@ class Strumline extends FlxSpriteGroup // Used in-game to control the scroll speed within a song public var scrollSpeed:Float = 1.0; + /** + * Reset the scroll speed to the current chart's scroll speed. + */ public function resetScrollSpeed():Void { scrollSpeed = PlayState.instance?.currentChart?.scrollSpeed ?? 1.0; @@ -101,8 +116,16 @@ class Strumline extends FlxSpriteGroup */ public var notes:FlxTypedSpriteGroup; + /** + * The hold notes currently being rendered on the strumline. + * This group iterates over this every frame to update hold note positions. + * The PlayState also iterates over this to calculate user inputs. + */ public var holdNotes:FlxTypedSpriteGroup; + /** + * A signal that is dispatched when a note is spawned and heading towards the strumline. + */ public var onNoteIncoming:FlxTypedSignalVoid>; var background:FunkinSprite; @@ -218,6 +241,9 @@ class Strumline extends FlxSpriteGroup return value; } + /** + * Refresh the strumline, sorting its children by z-index. + */ public function refresh():Void { sort(SortUtil.byZIndex, FlxSort.ASCENDING); @@ -241,7 +267,7 @@ class Strumline extends FlxSpriteGroup #if FEATURE_GHOST_TAPPING /** - * Returns `true` if no notes are in range of the strumline and the player can spam without penalty. + * @return `true` if no notes are in range of the strumline and the player can spam without penalty. */ public function mayGhostTap():Bool { @@ -286,31 +312,41 @@ class Strumline extends FlxSpriteGroup }); } - public function getNoteSprite(noteData:SongNoteData):NoteSprite + /** + * Get a note sprite corresponding to the given note data. + * @param target The note data for the note sprite. + * @return The note sprite. + */ + public function getNoteSprite(target:SongNoteData):NoteSprite { - if (noteData == null) return null; + if (target == null) return null; for (note in notes.members) { if (note == null) continue; if (note.alive) continue; - if (note.noteData == noteData) return note; + if (note.noteData == target) return note; } return null; } - public function getHoldNoteSprite(noteData:SongNoteData):SustainTrail + /** + * Get a hold note sprite corresponding to the given note data. + * @param target The note data for the hold note. + * @return The hold note sprite. + */ + public function getHoldNoteSprite(target:SongNoteData):SustainTrail { - if (noteData == null || ((noteData.length ?? 0.0) <= 0.0)) return null; + if (target == null || ((target.length ?? 0.0) <= 0.0)) return null; for (holdNote in holdNotes.members) { if (holdNote == null) continue; if (holdNote.alive) continue; - if (holdNote.noteData == noteData) return holdNote; + if (holdNote.noteData == target) return holdNote; } return null; @@ -321,6 +357,8 @@ class Strumline extends FlxSpriteGroup */ public function vwooshNotes():Void { + var vwooshTime:Float = 0.5; + for (note in notes.members) { if (note == null) continue; @@ -331,7 +369,7 @@ class Strumline extends FlxSpriteGroup var targetY:Float = FlxG.height + note.y; if (Preferences.downscroll) targetY = 0 - note.height; - FlxTween.tween(note, {y: targetY}, 0.5, + FlxTween.tween(note, {y: targetY}, vwooshTime, { ease: FlxEase.expoIn, onComplete: function(twn) { @@ -352,7 +390,7 @@ class Strumline extends FlxSpriteGroup var targetY:Float = FlxG.height + holdNote.y; if (Preferences.downscroll) targetY = 0 - holdNote.height; - FlxTween.tween(holdNote, {y: targetY}, 0.5, + FlxTween.tween(holdNote, {y: targetY}, vwooshTime, { ease: FlxEase.expoIn, onComplete: function(twn) { @@ -365,23 +403,65 @@ class Strumline extends FlxSpriteGroup } /** - * For a note's strumTime, calculate its Y position relative to the strumline. - * NOTE: Assumes Conductor and PlayState are both initialized. - * @param strumTime - * @return Float + * Reverse of vwooshNotes, we bring the notes IN (by their offsets) */ - public function calculateNoteYPos(strumTime:Float, vwoosh:Bool = true):Float + public function vwooshInNotes():Void { - // Make the note move faster visually as it moves offscreen. - // var vwoosh:Float = (strumTime < Conductor.songPosition) && vwoosh ? 2.0 : 1.0; - // ^^^ commented this out... do NOT make it move faster as it moves offscreen! - var vwoosh:Float = 1.0; + var vwooshTime:Float = 0.5; - return - Constants.PIXELS_PER_MS * (conductorInUse.songPosition - strumTime - Conductor.instance.inputOffset) * scrollSpeed * vwoosh * (Preferences.downscroll ? 1 : -1); + for (note in notes.members) + { + if (note == null) continue; + if (!note.alive) continue; + + note.yOffset = 200; + if (Preferences.downscroll) + { + note.yOffset = -200; + } + FlxTween.tween(note, {yOffset: 0}, vwooshTime, + { + ease: FlxEase.expoOut, + onComplete: function(twn) { + note.yOffset = 0; + } + }); + } + + for (holdNote in holdNotes.members) + { + if (holdNote == null) continue; + if (!holdNote.alive) continue; + + holdNote.yOffset = 200; + if (Preferences.downscroll) + { + holdNote.yOffset = -200; + } + FlxTween.tween(holdNote, {yOffset: 0}, vwooshTime, + { + ease: FlxEase.expoOut, + onComplete: function(twn) { + holdNote.yOffset = 0; + } + }); + } } - function updateNotes():Void + + /** + * For a note's strumTime, calculate its Y position relative to the strumline. + * NOTE: Assumes Conductor and PlayState are both initialized. + * @param strumTime The strumtime of the note. + * @return The Y position of the note. + */ + public function calculateNoteYPos(strumTime:Float):Float + { + return + Constants.PIXELS_PER_MS * (conductorInUse.songPosition - strumTime - Conductor.instance.inputOffset) * scrollSpeed * (Preferences.downscroll ? 1 : -1); + } + + public function updateNotes():Void { if (noteData.length == 0) return; @@ -392,7 +472,7 @@ class Strumline extends FlxSpriteGroup 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; + var renderWindowStart:Float = conductorInUse.songPosition + renderDistanceMs; for (noteIndex in nextNoteIndex...noteData.length) { @@ -407,7 +487,7 @@ class Strumline extends FlxSpriteGroup } if (note.time > renderWindowStart) break; // Note is too far ahead to render - var noteSprite = buildNoteSprite(note); + var noteSprite:NoteSprite = buildNoteSprite(note); if (note.length > 0) { @@ -424,12 +504,11 @@ class Strumline extends FlxSpriteGroup { if (note == null || !note.alive) continue; - var vwoosh:Bool = note.holdNoteSprite == null; // Set the note's position. - if (!customPositionData) note.y = this.y - INITIAL_OFFSET + calculateNoteYPos(note.strumTime, vwoosh); + if (!customPositionData) note.y = this.y - INITIAL_OFFSET + calculateNoteYPos(note.strumTime) + note.yOffset; // If the note is miss - var isOffscreen = Preferences.downscroll ? note.y > FlxG.height : note.y < -note.height; + var isOffscreen:Bool = Preferences.downscroll ? note.y > FlxG.height : note.y < -note.height; if (note.handledMiss && isOffscreen) { killNote(note); @@ -453,7 +532,8 @@ class Strumline extends FlxSpriteGroup } } - var renderWindowEnd = holdNote.strumTime + holdNote.fullSustainLength + Constants.HIT_WINDOW_MS + RENDER_DISTANCE_MS / 8; + final magicNumberIGuess:Float = 8; + var renderWindowEnd:Float = holdNote.strumTime + holdNote.fullSustainLength + Constants.HIT_WINDOW_MS + (renderDistanceMs / magicNumberIGuess); if (holdNote.missedNote && conductorInUse.songPosition >= renderWindowEnd) { @@ -494,17 +574,20 @@ class Strumline extends FlxSpriteGroup var yOffset:Float = (holdNote.fullSustainLength - holdNote.sustainLength) * Constants.PIXELS_PER_MS; - var vwoosh:Bool = false; - if (!customPositionData) { if (Preferences.downscroll) { - holdNote.y = this.y - INITIAL_OFFSET + calculateNoteYPos(holdNote.strumTime, vwoosh) - holdNote.height + STRUMLINE_SIZE / 2; + holdNote.y = this.y + - INITIAL_OFFSET + + calculateNoteYPos(holdNote.strumTime) + - holdNote.height + + STRUMLINE_SIZE / 2 + + holdNote.yOffset; } else { - holdNote.y = this.y - INITIAL_OFFSET + calculateNoteYPos(holdNote.strumTime, vwoosh) + yOffset + STRUMLINE_SIZE / 2; + holdNote.y = this.y - INITIAL_OFFSET + calculateNoteYPos(holdNote.strumTime) + yOffset + STRUMLINE_SIZE / 2 + holdNote.yOffset; } } @@ -544,17 +627,21 @@ class Strumline extends FlxSpriteGroup { // Hold note is new, render it normally. holdNote.visible = true; - var vwoosh:Bool = false; if (!customPositionData) { if (Preferences.downscroll) { - holdNote.y = this.y - INITIAL_OFFSET + calculateNoteYPos(holdNote.strumTime, vwoosh) - holdNote.height + STRUMLINE_SIZE / 2; + holdNote.y = this.y + - INITIAL_OFFSET + + calculateNoteYPos(holdNote.strumTime) + - holdNote.height + + STRUMLINE_SIZE / 2 + + holdNote.yOffset; } else { - holdNote.y = this.y - INITIAL_OFFSET + calculateNoteYPos(holdNote.strumTime, vwoosh) + STRUMLINE_SIZE / 2; + holdNote.y = this.y - INITIAL_OFFSET + calculateNoteYPos(holdNote.strumTime) + STRUMLINE_SIZE / 2 + holdNote.yOffset; } } } @@ -607,6 +694,9 @@ class Strumline extends FlxSpriteGroup nextNoteIndex = 0; } + /** + * Called on each beat of the song. + */ public function onBeatHit():Void { if (notes.members.length > 1) notes.members.insertionSort(compareNoteSprites.bind(FlxSort.ASCENDING)); @@ -614,16 +704,29 @@ class Strumline extends FlxSpriteGroup if (holdNotes.members.length > 1) holdNotes.members.insertionSort(compareHoldNoteSprites.bind(FlxSort.ASCENDING)); } + /** + * Called when a key is pressed. + * @param dir The direction of the key that was pressed. + */ public function pressKey(dir:NoteDirection):Void { heldKeys[dir] = true; } + /** + * Called when a key is released. + * @param dir The direction of the key that was released. + */ public function releaseKey(dir:NoteDirection):Void { heldKeys[dir] = false; } + /** + * Check if a key is held down. + * @param dir The direction of the key to check. + * @return `true` if the key is held down, `false` otherwise. + */ public function isKeyHeld(dir:NoteDirection):Bool { return heldKeys[dir]; @@ -673,6 +776,11 @@ class Strumline extends FlxSpriteGroup #end } + /** + * Apply note data from a chart to this strumline. + * Note data should be valid and apply only to this strumline. + * @param data The note data to apply. + */ public function applyNoteData(data:Array):Void { this.notes.clear(); @@ -685,6 +793,7 @@ class Strumline extends FlxSpriteGroup } /** + * Hit a note. * @param note The note to hit. * @param removeNote True to remove the note immediately, false to make it transparent and let it move offscreen. */ @@ -716,6 +825,10 @@ class Strumline extends FlxSpriteGroup #end } + /** + * Kill a note heading towards the strumline. + * @param note The note to kill. Gets recycled and reused for performance. + */ public function killNote(note:NoteSprite):Void { if (note == null) return; @@ -730,41 +843,76 @@ class Strumline extends FlxSpriteGroup } } + /** + * Get a strumline note sprite by its index. + * @param index The index of the note to get. + * @return The note. + */ public function getByIndex(index:Int):StrumlineNote { return this.strumlineNotes.members[index]; } + /** + * Get a strumline note sprite by its direction. + * @param direction The direction of the note to get. + * @return The note. + */ public function getByDirection(direction:NoteDirection):StrumlineNote { return getByIndex(DIRECTIONS.indexOf(direction)); } + /** + * Play a static animation for a given direction. + * @param direction The direction of the note to play the static animation for. + */ public function playStatic(direction:NoteDirection):Void { getByDirection(direction).playStatic(); } + /** + * Play a press animation for a given direction. + * @param direction The direction of the note to play the press animation for. + */ public function playPress(direction:NoteDirection):Void { getByDirection(direction).playPress(); } + /** + * Play a confirm animation for a given direction. + * @param direction The direction of the note to play the confirm animation for. + */ public function playConfirm(direction:NoteDirection):Void { getByDirection(direction).playConfirm(); } + /** + * Play a confirm animation for a hold note. + * @param direction The direction of the note to play the confirm animation for. + */ public function holdConfirm(direction:NoteDirection):Void { getByDirection(direction).holdConfirm(); } + /** + * Check if a given direction is playing the confirm animation. + * @param direction The direction of the note to check. + * @return `true` if the note is playing the confirm animation, `false` otherwise. + */ public function isConfirm(direction:NoteDirection):Bool { return getByDirection(direction).isConfirm(); } + /** + * Play a note splash for a given direction. + * @param direction The direction of the note to play the splash animation for. + */ public function playNoteSplash(direction:NoteDirection):Void { if (!showNotesplash) return; @@ -787,6 +935,10 @@ class Strumline extends FlxSpriteGroup } } + /** + * Play a note hold cover for a given hold note. + * @param holdNote The hold note to play the cover animation for. + */ public function playNoteHoldCover(holdNote:SustainTrail):Void { if (!showNotesplash) return; @@ -817,6 +969,11 @@ class Strumline extends FlxSpriteGroup } } + /** + * Build a note sprite for a given note data. + * @param note The note data to build the note sprite for. + * @return The note sprite. Will recycle a note sprite from the pool if available for performance. + */ public function buildNoteSprite(note:SongNoteData):NoteSprite { var noteSprite:NoteSprite = constructNoteSprite(); @@ -833,13 +990,17 @@ class Strumline extends FlxSpriteGroup noteSprite.x += getXPos(DIRECTIONS[note.getDirection() % KEY_COUNT]); noteSprite.x -= (noteSprite.width - Strumline.STRUMLINE_SIZE) / 2; // Center it noteSprite.x -= NUDGE; - // noteSprite.x += INITIAL_OFFSET; noteSprite.y = -9999; } return noteSprite; } + /** + * Build a hold note sprite for a given note data. + * @param note The note data to build the hold note sprite for. + * @return The hold note sprite. Will recycle a hold note sprite from the pool if available for performance. + */ public function buildHoldNoteSprite(note:SongNoteData):SustainTrail { var holdNoteSprite:SustainTrail = constructHoldNoteSprite(); @@ -874,7 +1035,7 @@ class Strumline extends FlxSpriteGroup } /** - * Custom recycling behavior. + * Custom recycling behavior for note splashes. */ function constructNoteSplash():NoteSplash { @@ -908,7 +1069,7 @@ class Strumline extends FlxSpriteGroup } /** - * Custom recycling behavior. + * Custom recycling behavior for note hold covers. */ function constructNoteHoldCover():NoteHoldCover { @@ -942,7 +1103,7 @@ class Strumline extends FlxSpriteGroup } /** - * Custom recycling behavior. + * Custom recycling behavior for note sprites. */ function constructNoteSprite():NoteSprite { @@ -968,7 +1129,7 @@ class Strumline extends FlxSpriteGroup } /** - * Custom recycling behavior. + * Custom recycling behavior for hold note sprites. */ function constructHoldNoteSprite():SustainTrail { @@ -1020,6 +1181,10 @@ class Strumline extends FlxSpriteGroup FlxTween.tween(arrow, {y: arrow.y + 10, alpha: 1}, 1, {ease: FlxEase.circOut, startDelay: 0.5 + (0.2 * index)}); } + /** + * Play a fade in animation on all arrows in the strumline. + * Used when starting a song in Freeplay mode. + */ public function fadeInArrows():Void { for (index => arrow in this.strumlineNotes.members.keyValueIterator()) @@ -1028,24 +1193,50 @@ class Strumline extends FlxSpriteGroup } } + /** + * Compare two note data objects by their strumtime. + * @param order The order to sort the notes in. + * @param a The first note data object. + * @param b The second note data object. + * @return The comparison result, based on the time of the notes. + */ function compareNoteData(order:Int, a:SongNoteData, b:SongNoteData):Int { return FlxSort.byValues(order, a.time, b.time); } + /** + * Compare two note sprites by their strumtime. + * @param order The order to sort the notes in. + * @param a The first note sprite. + * @param b The second note sprite. + * @return The comparison result, based on the time of the notes. + */ function compareNoteSprites(order:Int, a:NoteSprite, b:NoteSprite):Int { return FlxSort.byValues(order, a?.strumTime, b?.strumTime); } + /** + * Compare two hold note sprites by their strumtime. + * @param order The order to sort the notes in. + * @param a The first hold note sprite. + * @param b The second hold note sprite. + * @return The comparison result, based on the time of the notes. + */ function compareHoldNoteSprites(order:Int, a:SustainTrail, b:SustainTrail):Int { return FlxSort.byValues(order, a?.strumTime, b?.strumTime); } - override function findMinYHelper() + /** + * Find the minimum Y position of the strumline. + * Ignores the background to ensure the strumline is positioned correctly. + * @return The minimum Y position of the strumline. + */ + override function findMinYHelper():Float { - var value = Math.POSITIVE_INFINITY; + var value:Float = Math.POSITIVE_INFINITY; for (member in group.members) { if (member == null) continue; @@ -1053,18 +1244,28 @@ class Strumline extends FlxSpriteGroup if (member == this.background) continue; var minY:Float; - if (member.flixelType == SPRITEGROUP) minY = (cast member : FlxSpriteGroup).findMinY(); + if (member.flixelType == SPRITEGROUP) + { + minY = (cast member : FlxSpriteGroup).findMinY(); + } else + { minY = member.y; + } if (minY < value) value = minY; } return value; } - override function findMaxYHelper() + /** + * Find the maximum Y position of the strumline. + * Ignores the background to ensure the strumline is positioned correctly. + * @return The maximum Y position of the strumline. + */ + override function findMaxYHelper():Float { - var value = Math.NEGATIVE_INFINITY; + var value:Float = Math.NEGATIVE_INFINITY; for (member in group.members) { if (member == null) continue; @@ -1072,9 +1273,14 @@ class Strumline extends FlxSpriteGroup if (member == this.background) continue; var maxY:Float; - if (member.flixelType == SPRITEGROUP) maxY = (cast member : FlxSpriteGroup).findMaxY(); + if (member.flixelType == SPRITEGROUP) + { + maxY = (cast member : FlxSpriteGroup).findMaxY(); + } else + { maxY = member.y + member.height; + } if (maxY > value) value = maxY; } diff --git a/source/funkin/play/notes/StrumlineNote.hx b/source/funkin/play/notes/StrumlineNote.hx index 03b782485..324234cc4 100644 --- a/source/funkin/play/notes/StrumlineNote.hx +++ b/source/funkin/play/notes/StrumlineNote.hx @@ -26,6 +26,11 @@ class StrumlineNote extends FunkinSprite return this.direction; } + /** + * The Y Offset of the note. + */ + public var yOffset:Float = 0.0; + /** * Set this flag to `true` to disable performance optimizations that cause * the Strumline note sprite to ignore `velocity` and `acceleration`. diff --git a/source/funkin/play/notes/SustainTrail.hx b/source/funkin/play/notes/SustainTrail.hx index 937bc0ceb..36dc3bfab 100644 --- a/source/funkin/play/notes/SustainTrail.hx +++ b/source/funkin/play/notes/SustainTrail.hx @@ -33,6 +33,11 @@ class SustainTrail extends FlxSprite public var cover:NoteHoldCover = null; + /** + * The Y Offset of the note. + */ + public var yOffset:Float = 0.0; + /** * Set to `true` if the user hit the note and is currently holding the sustain. * Should display associated effects. diff --git a/source/funkin/ui/charSelect/CharSelectSubState.hx b/source/funkin/ui/charSelect/CharSelectSubState.hx index 48a88be33..87f08960c 100644 --- a/source/funkin/ui/charSelect/CharSelectSubState.hx +++ b/source/funkin/ui/charSelect/CharSelectSubState.hx @@ -498,7 +498,7 @@ class CharSelectSubState extends MusicBeatSubState grpIcons.scrollFactor.set(); } - function unLock() + function unLock():Void { var index = nonLocks[0]; diff --git a/source/funkin/ui/charSelect/Nametag.hx b/source/funkin/ui/charSelect/Nametag.hx index b6cedb0c7..5bdb0e7e8 100644 --- a/source/funkin/ui/charSelect/Nametag.hx +++ b/source/funkin/ui/charSelect/Nametag.hx @@ -18,9 +18,6 @@ class Nametag extends FlxSprite shader = mosaicShader; switchChar("bf"); - - FlxG.debugger.addTrackerProfile(new TrackerProfile(Nametag, ["midpointX", "midpointY"])); - FlxG.debugger.track(this, "Nametag"); } public function updatePosition():Void @@ -71,16 +68,12 @@ class Nametag extends FlxSprite } } - function setBlockTimer(frame:Int, ?forceX:Float, ?forceY:Float) + function setBlockTimer(frame:Int, ?forceX:Float, ?forceY:Float):Void { - var daX:Float = 10 * FlxG.random.int(1, 4); - var daY:Float = 10 * FlxG.random.int(1, 4); + var daX:Float = forceX ?? 10 * FlxG.random.int(1, 4); + var daY:Float = forceY ?? 10 * FlxG.random.int(1, 4); - if (forceX != null) daX = forceX; - - if (forceY != null) daY = forceY; - - new FlxTimer().start(frame / 30, _ -> { + FlxTimer.wait(frame / 30, () -> { mosaicShader.setBlockSize(daX, daY); }); } diff --git a/source/funkin/util/FileUtil.hx b/source/funkin/util/FileUtil.hx index a5eda796b..cf9109bcf 100644 --- a/source/funkin/util/FileUtil.hx +++ b/source/funkin/util/FileUtil.hx @@ -53,7 +53,17 @@ class FileUtil * Paths which should not be deleted or modified by scripts. */ private static final PROTECTED_PATHS:Array = [ - '', 'assets', 'manifest', 'manifest/*', 'plugins', 'plugins/*', 'Funkin.exe', 'Funkin', 'libvlc.dll', 'libvlccore.dll', 'lime.ndll' + '', + 'assets', + 'manifest', + 'manifest/*', + 'plugins', + 'plugins/*', + 'Funkin.exe', + 'Funkin', + 'libvlc.dll', + 'libvlccore.dll', + 'lime.ndll' ]; /** @@ -269,7 +279,7 @@ class FileUtil return true; #elseif html5 - var filter:String = defaultFileName != null ? Path.extension(defaultFileName) : null; + var filter:Null = defaultFileName != null ? Path.extension(defaultFileName) : null; var fileDialog:FileDialog = new FileDialog(); if (onSave != null) { diff --git a/source/funkin/util/WindowUtil.hx b/source/funkin/util/WindowUtil.hx index 665512e5b..c6d8bee6a 100644 --- a/source/funkin/util/WindowUtil.hx +++ b/source/funkin/util/WindowUtil.hx @@ -69,6 +69,9 @@ class WindowUtil */ public static function openFolder(targetPath:String):Void { + #if html5 + throw 'Cannot open URLs on this platform.'; + #else if (!sys.FileSystem.exists(targetPath) || !sys.FileSystem.isDirectory(targetPath)) throw 'openFolder should only be used to open existing folders.'; #if FEATURE_OPEN_URL #if windows @@ -81,6 +84,7 @@ class WindowUtil #else throw 'Cannot open URLs on this platform.'; #end + #end } /** @@ -89,6 +93,9 @@ class WindowUtil */ public static function openSelectFile(targetPath:String):Void { + #if html5 + throw 'Cannot open URLs on this platform.'; + #else #if FEATURE_OPEN_URL #if windows Sys.command('explorer', ['/select,' + targetPath.replace('/', '\\')]); @@ -101,6 +108,7 @@ class WindowUtil #else throw 'Cannot open URLs on this platform.'; #end + #end } /** diff --git a/source/funkin/util/macro/RegistryMacro.hx b/source/funkin/util/macro/RegistryMacro.hx index bc16e92be..e7c0d401e 100644 --- a/source/funkin/util/macro/RegistryMacro.hx +++ b/source/funkin/util/macro/RegistryMacro.hx @@ -8,7 +8,6 @@ import haxe.macro.Expr.TypeDefKind; import haxe.macro.Expr.MetadataEntry; import haxe.macro.Type; import haxe.macro.Type.ClassType; -import sys.FileSystem; using Lambda; using haxe.macro.ExprTools; @@ -362,7 +361,7 @@ class RegistryMacro static function listBaseGameEntryIds(dataFilePath:String):Array { var result:Array = []; - var files:Array = FileSystem.readDirectory(dataFilePath); + var files:Array = sys.FileSystem.readDirectory(dataFilePath); for (file in files) {