Merge branch 'rewrite/master' into kade-github/pico-mix-bugfix
This commit is contained in:
@@ -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!
|
||||
We look forward to seeing your contributions to the game!
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
"name": "lime",
|
||||
"type": "git",
|
||||
"dir": null,
|
||||
"ref": "1e79c20a6ee13fa168535f9f76a368e3284ddc3a",
|
||||
"ref": "be81ad7e4e1a92c3482bcc009648a4ac892cfa35",
|
||||
"url": "https://github.com/FunkinCrew/lime"
|
||||
},
|
||||
{
|
||||
|
||||
+1
-1
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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> = [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<NoteSprite>;
|
||||
|
||||
/**
|
||||
* 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<SustainTrail>;
|
||||
|
||||
/**
|
||||
* A signal that is dispatched when a note is spawned and heading towards the strumline.
|
||||
*/
|
||||
public var onNoteIncoming:FlxTypedSignal<NoteSprite->Void>;
|
||||
|
||||
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<SongNoteData>):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;
|
||||
}
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -498,7 +498,7 @@ class CharSelectSubState extends MusicBeatSubState
|
||||
grpIcons.scrollFactor.set();
|
||||
}
|
||||
|
||||
function unLock()
|
||||
function unLock():Void
|
||||
{
|
||||
var index = nonLocks[0];
|
||||
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -53,7 +53,17 @@ class FileUtil
|
||||
* Paths which should not be deleted or modified by scripts.
|
||||
*/
|
||||
private static final PROTECTED_PATHS:Array<String> = [
|
||||
'', '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<String> = defaultFileName != null ? Path.extension(defaultFileName) : null;
|
||||
var fileDialog:FileDialog = new FileDialog();
|
||||
if (onSave != null)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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<Expr>
|
||||
{
|
||||
var result:Array<Expr> = [];
|
||||
var files:Array<String> = FileSystem.readDirectory(dataFilePath);
|
||||
var files:Array<String> = sys.FileSystem.readDirectory(dataFilePath);
|
||||
|
||||
for (file in files)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user