mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2025-09-05 13:27:39 +00:00
Compare commits
16 commits
7dd9471beb
...
78c9ad0997
Author | SHA1 | Date | |
---|---|---|---|
|
78c9ad0997 | ||
|
b99a4b3e65 | ||
|
d72601094a | ||
|
38fcea6773 | ||
|
3bccce6070 | ||
|
a454bc7f50 | ||
|
18829b5b47 | ||
|
1ae149caed | ||
|
a8e76e5ec4 | ||
|
843f4d767f | ||
|
03df863ea7 | ||
|
63971f730f | ||
|
61b5fa0fe1 | ||
|
4b82af37ff | ||
|
6eb07d8b17 | ||
|
ab7bfb24d9 |
|
@ -330,10 +330,10 @@ class Project extends HXProject
|
||||||
static final FEATURE_HAPTICS:FeatureFlag = "FEATURE_HAPTICS";
|
static final FEATURE_HAPTICS:FeatureFlag = "FEATURE_HAPTICS";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `-DFEATURE_INPUT_OFFSETS`
|
* `-DFEATURE_LAG_ADJUSTMENT`
|
||||||
* If this flag is enabled, the input offsets menu will be available to configure your audio and visual offsets.
|
* If this flag is enabled, the input offsets menu will be available to configure your audio and visual offsets.
|
||||||
*/
|
*/
|
||||||
static final FEATURE_INPUT_OFFSETS:FeatureFlag = "FEATURE_INPUT_OFFSETS";
|
static final FEATURE_LAG_ADJUSTMENT:FeatureFlag = "FEATURE_LAG_ADJUSTMENT";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `-DFEATURE_LOG_TRACE`
|
* `-DFEATURE_LOG_TRACE`
|
||||||
|
@ -829,7 +829,7 @@ class Project extends HXProject
|
||||||
FEATURE_STAGE_EDITOR.apply(this, !(isWeb() || isMobile()));
|
FEATURE_STAGE_EDITOR.apply(this, !(isWeb() || isMobile()));
|
||||||
|
|
||||||
// Should be true except on web builds (some asset stuff breaks it)
|
// Should be true except on web builds (some asset stuff breaks it)
|
||||||
FEATURE_INPUT_OFFSETS.apply(this, !isWeb());
|
FEATURE_LAG_ADJUSTMENT.apply(this, !isWeb());
|
||||||
|
|
||||||
// Should be true except on web and mobile builds.
|
// Should be true except on web and mobile builds.
|
||||||
// Screenshots doesn't work there, and mobile has its own screenshots anyway.
|
// Screenshots doesn't work there, and mobile has its own screenshots anyway.
|
||||||
|
|
54
source/funkin/modding/ModStore.hx
Normal file
54
source/funkin/modding/ModStore.hx
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
package funkin.modding;
|
||||||
|
|
||||||
|
import haxe.ds.StringMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Temporary persistent data storage for mods to use.
|
||||||
|
*/
|
||||||
|
@:nullSafety
|
||||||
|
class ModStore
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* All registered stores for this session.
|
||||||
|
*/
|
||||||
|
public static final stores:StringMap<Dynamic> = new StringMap<Dynamic>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to register a new store with the given ID and return it.
|
||||||
|
* If a store with the same ID already exists, that store will be returned instead (discards `data`).
|
||||||
|
*
|
||||||
|
* @id The unique ID for this store.
|
||||||
|
* @data Optional initial data, uses an empty object by default.
|
||||||
|
* @return The store data at the given ID.
|
||||||
|
*/
|
||||||
|
public static function register(id:String, ?data:Dynamic):Dynamic
|
||||||
|
{
|
||||||
|
if (stores.exists(id)) return stores.get(id);
|
||||||
|
stores.set(id, data ??= {});
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to get a store by ID.
|
||||||
|
*
|
||||||
|
* @id The target ID of the store.
|
||||||
|
* @return The store data, or `null` if the store did not exist.
|
||||||
|
*/
|
||||||
|
public static function get(id:String):Null<Dynamic>
|
||||||
|
{
|
||||||
|
return stores.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to remove a store by ID and return it.
|
||||||
|
*
|
||||||
|
* @id The target ID of the store.
|
||||||
|
* @return The store data, or `null` if the store did not exist.
|
||||||
|
*/
|
||||||
|
public static function remove(id:String):Null<Dynamic>
|
||||||
|
{
|
||||||
|
var data:Null<Dynamic> = stores.get(id);
|
||||||
|
stores.remove(id);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
|
@ -444,7 +444,7 @@ class PauseSubState extends MusicBeatSubState
|
||||||
offsetText.y = FlxG.height - (offsetText.height + offsetText.height + 40);
|
offsetText.y = FlxG.height - (offsetText.height + offsetText.height + 40);
|
||||||
offsetTextInfo.y = offsetText.y + offsetText.height + 4;
|
offsetTextInfo.y = offsetText.y + offsetText.height + 4;
|
||||||
|
|
||||||
#if !mobile
|
#if (!mobile && FEATURE_LAG_ADJUSTMENT)
|
||||||
metadata.add(offsetText);
|
metadata.add(offsetText);
|
||||||
metadata.add(offsetTextInfo);
|
metadata.add(offsetTextInfo);
|
||||||
#end
|
#end
|
||||||
|
|
|
@ -1502,7 +1502,9 @@ class PlayState extends MusicBeatSubState
|
||||||
musicPausedBySubState = false;
|
musicPausedBySubState = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
forEachPausedSound((s) -> needsReset ? s.destroy() : s.resume());
|
// The logic here is that if this sound doesn't auto-destroy
|
||||||
|
// then it's gonna be reused somewhere, so we just stop it instead.
|
||||||
|
forEachPausedSound(s -> needsReset ? (s.autoDestroy ? s.destroy() : s.stop()) : s.resume());
|
||||||
|
|
||||||
// Resume camera tweens if we paused any.
|
// Resume camera tweens if we paused any.
|
||||||
for (camTween in cameraTweensPausedBySubState)
|
for (camTween in cameraTweensPausedBySubState)
|
||||||
|
|
|
@ -271,6 +271,12 @@ class CharSelectSubState extends MusicBeatSubState
|
||||||
nametag.midpointX += cutoutSize;
|
nametag.midpointX += cutoutSize;
|
||||||
add(nametag);
|
add(nametag);
|
||||||
|
|
||||||
|
@:privateAccess
|
||||||
|
{
|
||||||
|
nametag.midpointY += 200;
|
||||||
|
FlxTween.tween(nametag, {midpointY: nametag.midpointY - 200}, 1, {ease: FlxEase.expoOut});
|
||||||
|
}
|
||||||
|
|
||||||
nametag.scrollFactor.set();
|
nametag.scrollFactor.set();
|
||||||
|
|
||||||
FlxG.debugger.addTrackerProfile(new TrackerProfile(FlxSprite, ["x", "y", "alpha", "scale", "blend"]));
|
FlxG.debugger.addTrackerProfile(new TrackerProfile(FlxSprite, ["x", "y", "alpha", "scale", "blend"]));
|
||||||
|
@ -739,6 +745,7 @@ class CharSelectSubState extends MusicBeatSubState
|
||||||
FlxTween.tween(cursorConfirmed, {alpha: 0}, 0.8, {ease: FlxEase.expoOut});
|
FlxTween.tween(cursorConfirmed, {alpha: 0}, 0.8, {ease: FlxEase.expoOut});
|
||||||
|
|
||||||
FlxTween.tween(barthing, {y: barthing.y + 80}, 0.8, {ease: FlxEase.backIn});
|
FlxTween.tween(barthing, {y: barthing.y + 80}, 0.8, {ease: FlxEase.backIn});
|
||||||
|
FlxTween.tween(nametag, {y: nametag.y + 80}, 0.8, {ease: FlxEase.backIn});
|
||||||
FlxTween.tween(dipshitBacking, {y: dipshitBacking.y + 210}, 0.8, {ease: FlxEase.backIn});
|
FlxTween.tween(dipshitBacking, {y: dipshitBacking.y + 210}, 0.8, {ease: FlxEase.backIn});
|
||||||
FlxTween.tween(chooseDipshit, {y: chooseDipshit.y + 200}, 0.8, {ease: FlxEase.backIn});
|
FlxTween.tween(chooseDipshit, {y: chooseDipshit.y + 200}, 0.8, {ease: FlxEase.backIn});
|
||||||
FlxTween.tween(dipshitBlur, {y: dipshitBlur.y + 220}, 0.8, {ease: FlxEase.backIn});
|
FlxTween.tween(dipshitBlur, {y: dipshitBlur.y + 220}, 0.8, {ease: FlxEase.backIn});
|
||||||
|
|
|
@ -100,6 +100,7 @@ class DebugBoundingState extends FlxState
|
||||||
offsetAnimationDropdown = offsetEditorDialog.findComponent("animationDropdown", DropDown);
|
offsetAnimationDropdown = offsetEditorDialog.findComponent("animationDropdown", DropDown);
|
||||||
|
|
||||||
offsetEditorDialog.cameras = [hudCam];
|
offsetEditorDialog.cameras = [hudCam];
|
||||||
|
offsetEditorDialog.closable = false;
|
||||||
|
|
||||||
add(offsetEditorDialog);
|
add(offsetEditorDialog);
|
||||||
offsetEditorDialog.showDialog(false);
|
offsetEditorDialog.showDialog(false);
|
||||||
|
|
|
@ -94,6 +94,9 @@ import haxe.ui.components.Button;
|
||||||
import haxe.ui.components.DropDown;
|
import haxe.ui.components.DropDown;
|
||||||
import haxe.ui.components.Label;
|
import haxe.ui.components.Label;
|
||||||
import haxe.ui.components.Slider;
|
import haxe.ui.components.Slider;
|
||||||
|
import haxe.ui.containers.dialogs.Dialogs;
|
||||||
|
import haxe.ui.containers.dialogs.Dialog.DialogButton;
|
||||||
|
import haxe.ui.containers.dialogs.MessageBox.MessageBoxType;
|
||||||
import haxe.ui.containers.dialogs.CollapsibleDialog;
|
import haxe.ui.containers.dialogs.CollapsibleDialog;
|
||||||
import haxe.ui.containers.menus.Menu;
|
import haxe.ui.containers.menus.Menu;
|
||||||
import haxe.ui.containers.menus.MenuBar;
|
import haxe.ui.containers.menus.MenuBar;
|
||||||
|
@ -5599,7 +5602,18 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
|
||||||
@:nullSafety(Off)
|
@:nullSafety(Off)
|
||||||
function quitChartEditor():Void
|
function quitChartEditor():Void
|
||||||
{
|
{
|
||||||
autoSave();
|
if (saveDataDirty) {
|
||||||
|
Dialogs.messageBox("You are about to leave the editor without saving.\n\nAre you sure?", "Leave Editor", MessageBoxType.TYPE_YESNO, true, function(button:DialogButton) {
|
||||||
|
if (button == DialogButton.YES)
|
||||||
|
{
|
||||||
|
autoSave();
|
||||||
|
quitChartEditor();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
stopWelcomeMusic();
|
stopWelcomeMusic();
|
||||||
// TODO: PR Flixel to make onComplete nullable.
|
// TODO: PR Flixel to make onComplete nullable.
|
||||||
if (audioInstTrack != null) audioInstTrack.onComplete = null;
|
if (audioInstTrack != null) audioInstTrack.onComplete = null;
|
||||||
|
|
|
@ -192,7 +192,7 @@ class AssetDataHandler
|
||||||
|
|
||||||
for (daFrame in obj.frames.frames)
|
for (daFrame in obj.frames.frames)
|
||||||
{
|
{
|
||||||
xml += ' <SubTexture name="${daFrame.name}" x="${daFrame.frame.x}" y="${daFrame.frame.y}" width="${daFrame.frame.width}" height="${daFrame.frame.height}" frameX="${- daFrame.offset.x}" frameY="${- daFrame.offset.y}" frameWidth="${daFrame.sourceSize.x}" frameHeight="${daFrame.sourceSize.y}" flipX="${daFrame.flipX}" flipY="${daFrame.flipY}"/>\n';
|
xml += ' <SubTexture name="${daFrame.name}" x="${daFrame.frame.x}" y="${daFrame.frame.y}" width="${daFrame.frame.width}" height="${daFrame.frame.height}" frameX="${- daFrame.offset.x}" frameY="${- daFrame.offset.y}" frameWidth="${daFrame.sourceSize.x}" frameHeight="${daFrame.sourceSize.y}" flipX="${daFrame.flipX}" flipY="${daFrame.flipY}" rotated="${daFrame.angle == -90}"/>\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
xml += "</TextureAtlas>";
|
xml += "</TextureAtlas>";
|
||||||
|
|
|
@ -81,8 +81,6 @@ class FreeplayDJ extends FlxAtlasSprite
|
||||||
|
|
||||||
public override function update(elapsed:Float):Void
|
public override function update(elapsed:Float):Void
|
||||||
{
|
{
|
||||||
super.update(elapsed);
|
|
||||||
|
|
||||||
switch (currentState)
|
switch (currentState)
|
||||||
{
|
{
|
||||||
case Intro:
|
case Intro:
|
||||||
|
@ -185,6 +183,8 @@ class FreeplayDJ extends FlxAtlasSprite
|
||||||
default:
|
default:
|
||||||
// I shit myself.
|
// I shit myself.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
super.update(elapsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onFinishAnim(name:String):Void
|
function onFinishAnim(name:String):Void
|
||||||
|
|
|
@ -169,17 +169,6 @@ class FreeplayState extends MusicBeatSubState
|
||||||
return grpCapsules.members[curSelected];
|
return grpCapsules.members[curSelected];
|
||||||
}
|
}
|
||||||
|
|
||||||
var coolColors:Array<Int> = [
|
|
||||||
0xFF9271FD,
|
|
||||||
0xFF9271FD,
|
|
||||||
0xFF223344,
|
|
||||||
0xFF941653,
|
|
||||||
0xFFFC96D7,
|
|
||||||
0xFFA0D1FF,
|
|
||||||
0xFFFF78BF,
|
|
||||||
0xFFF6B604
|
|
||||||
];
|
|
||||||
|
|
||||||
var grpCapsules:FlxTypedGroup<SongMenuItem>;
|
var grpCapsules:FlxTypedGroup<SongMenuItem>;
|
||||||
|
|
||||||
var dj:Null<FreeplayDJ> = null;
|
var dj:Null<FreeplayDJ> = null;
|
||||||
|
@ -2179,7 +2168,7 @@ class FreeplayState extends MusicBeatSubState
|
||||||
*/
|
*/
|
||||||
function changeDiff(change:Int = 0, force:Bool = false, capsuleAnim:Bool = false):Void
|
function changeDiff(change:Int = 0, force:Bool = false, capsuleAnim:Bool = false):Void
|
||||||
{
|
{
|
||||||
if (!controls.active) return;
|
if (!controls.active && !force) return;
|
||||||
|
|
||||||
if (capsuleAnim)
|
if (capsuleAnim)
|
||||||
{
|
{
|
||||||
|
@ -2390,11 +2379,6 @@ class FreeplayState extends MusicBeatSubState
|
||||||
{
|
{
|
||||||
trace('RANDOM SELECTED');
|
trace('RANDOM SELECTED');
|
||||||
|
|
||||||
controls.active = false;
|
|
||||||
#if NO_FEATURE_TOUCH_CONTROLS
|
|
||||||
letterSort.inputEnabled = false;
|
|
||||||
#end
|
|
||||||
|
|
||||||
var availableSongCapsules:Array<SongMenuItem> = grpCapsules.members.filter(function(cap:SongMenuItem) {
|
var availableSongCapsules:Array<SongMenuItem> = grpCapsules.members.filter(function(cap:SongMenuItem) {
|
||||||
// Dead capsules are ones which were removed from the list when changing filters.
|
// Dead capsules are ones which were removed from the list when changing filters.
|
||||||
return cap.alive && cap.freeplayData != null;
|
return cap.alive && cap.freeplayData != null;
|
||||||
|
@ -2420,6 +2404,10 @@ class FreeplayState extends MusicBeatSubState
|
||||||
// Seeing if I can do an animation...
|
// Seeing if I can do an animation...
|
||||||
curSelected = grpCapsules.members.indexOf(targetSong);
|
curSelected = grpCapsules.members.indexOf(targetSong);
|
||||||
changeSelection(0); // Trigger an update.
|
changeSelection(0); // Trigger an update.
|
||||||
|
controls.active = false;
|
||||||
|
#if NO_FEATURE_TOUCH_CONTROLS
|
||||||
|
letterSort.inputEnabled = false;
|
||||||
|
#end
|
||||||
|
|
||||||
// Act like we hit Confirm on that song.
|
// Act like we hit Confirm on that song.
|
||||||
capsuleOnConfirmDefault(targetSong);
|
capsuleOnConfirmDefault(targetSong);
|
||||||
|
@ -2701,7 +2689,7 @@ class FreeplayState extends MusicBeatSubState
|
||||||
intendedCompletion = songScore == null ? 0.0 : ((songScore.tallies.sick +
|
intendedCompletion = songScore == null ? 0.0 : ((songScore.tallies.sick +
|
||||||
songScore.tallies.good - songScore.tallies.missed) / songScore.tallies.totalNotes);
|
songScore.tallies.good - songScore.tallies.missed) / songScore.tallies.totalNotes);
|
||||||
rememberedSongId = daSongCapsule.freeplayData.data.id;
|
rememberedSongId = daSongCapsule.freeplayData.data.id;
|
||||||
changeDiff();
|
changeDiff(0, true);
|
||||||
daSongCapsule.refreshDisplay((prepForNewRank == true) ? false : true);
|
daSongCapsule.refreshDisplay((prepForNewRank == true) ? false : true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2710,7 +2698,7 @@ class FreeplayState extends MusicBeatSubState
|
||||||
intendedCompletion = 0.0;
|
intendedCompletion = 0.0;
|
||||||
rememberedSongId = null;
|
rememberedSongId = null;
|
||||||
albumRoll.albumId = null;
|
albumRoll.albumId = null;
|
||||||
changeDiff();
|
changeDiff(0, true);
|
||||||
daSongCapsule.refreshDisplay();
|
daSongCapsule.refreshDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -148,18 +148,22 @@ class LetterSort extends FlxSpriteGroup
|
||||||
|
|
||||||
public function changeSelection(diff:Int = 0, playSound:Bool = true):Void
|
public function changeSelection(diff:Int = 0, playSound:Bool = true):Void
|
||||||
{
|
{
|
||||||
doLetterChangeAnims(diff);
|
@:privateAccess
|
||||||
|
if (instance.controls.active)
|
||||||
|
{
|
||||||
|
doLetterChangeAnims(diff);
|
||||||
|
|
||||||
var multiPosOrNeg:Float = diff > 0 ? 1 : -1;
|
var multiPosOrNeg:Float = diff > 0 ? 1 : -1;
|
||||||
|
|
||||||
// if we're moving left (diff < 0), we want control of the right arrow, and vice versa
|
// if we're moving left (diff < 0), we want control of the right arrow, and vice versa
|
||||||
var arrowToMove:FlxSprite = diff < 0 ? leftArrow : rightArrow;
|
var arrowToMove:FlxSprite = diff < 0 ? leftArrow : rightArrow;
|
||||||
arrowToMove.offset.x = 3 * multiPosOrNeg;
|
arrowToMove.offset.x = 3 * multiPosOrNeg;
|
||||||
|
|
||||||
new FlxTimer().start(2 / 24, function(_) {
|
new FlxTimer().start(2 / 24, function(_) {
|
||||||
arrowToMove.offset.x = 0;
|
arrowToMove.offset.x = 0;
|
||||||
});
|
});
|
||||||
if (playSound && diff != 0) FunkinSound.playOnce(Paths.sound('scrollMenu'), 0.4);
|
if (playSound && diff != 0) FunkinSound.playOnce(Paths.sound('scrollMenu'), 0.4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -268,10 +268,8 @@ class MainMenuState extends MusicBeatState
|
||||||
// reset camera when debug menu is closed
|
// reset camera when debug menu is closed
|
||||||
subStateClosed.add(_ -> resetCamStuff(false));
|
subStateClosed.add(_ -> resetCamStuff(false));
|
||||||
|
|
||||||
// TODO: Why does this specific function break with null safety?
|
|
||||||
@:nullSafety(Off)
|
|
||||||
subStateOpened.add((sub:FlxSubState) -> {
|
subStateOpened.add((sub:FlxSubState) -> {
|
||||||
if (Type.getClass(sub) == FreeplayState)
|
if (Std.isOfType(sub, FreeplayState))
|
||||||
{
|
{
|
||||||
new FlxTimer().start(0.5, _ -> {
|
new FlxTimer().start(0.5, _ -> {
|
||||||
magenta.visible = false;
|
magenta.visible = false;
|
||||||
|
|
|
@ -545,6 +545,7 @@ class OffsetMenu extends Page<OptionsState.OptionsMenuPageName>
|
||||||
if (FlxG.sound.music.time < _lastTime)
|
if (FlxG.sound.music.time < _lastTime)
|
||||||
{
|
{
|
||||||
localConductor.update(FlxG.sound.music.time, !calibrating);
|
localConductor.update(FlxG.sound.music.time, !calibrating);
|
||||||
|
b = localConductor.currentBeatTime;
|
||||||
|
|
||||||
// Update arrows to be the correct distance away from the receptor.
|
// Update arrows to be the correct distance away from the receptor.
|
||||||
var lastArrowBeat:Float = 0;
|
var lastArrowBeat:Float = 0;
|
||||||
|
@ -558,7 +559,7 @@ class OffsetMenu extends Page<OptionsState.OptionsMenuPageName>
|
||||||
}
|
}
|
||||||
if (calibrating)
|
if (calibrating)
|
||||||
{
|
{
|
||||||
arrowBeat = lastArrowBeat + 2;
|
arrowBeat = lastArrowBeat;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
arrowBeat = 4;
|
arrowBeat = 4;
|
||||||
|
@ -566,6 +567,10 @@ class OffsetMenu extends Page<OptionsState.OptionsMenuPageName>
|
||||||
testStrumline.clean();
|
testStrumline.clean();
|
||||||
testStrumline.noteData = [];
|
testStrumline.noteData = [];
|
||||||
testStrumline.nextNoteIndex = 0;
|
testStrumline.nextNoteIndex = 0;
|
||||||
|
trace('Restarting conductor');
|
||||||
|
|
||||||
|
_lastTime = FlxG.sound.music.time;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_lastBeat = b;
|
_lastBeat = b;
|
||||||
|
@ -608,7 +613,7 @@ class OffsetMenu extends Page<OptionsState.OptionsMenuPageName>
|
||||||
countText.text = 'Current Offset: ' + Std.int(appliedOffsetLerp) + 'ms';
|
countText.text = 'Current Offset: ' + Std.int(appliedOffsetLerp) + 'ms';
|
||||||
|
|
||||||
var toRemove:Array<ArrowData> = [];
|
var toRemove:Array<ArrowData> = [];
|
||||||
|
var _lastArrowBeat:Float = 0;
|
||||||
// Update arrows
|
// Update arrows
|
||||||
for (i in 0...arrows.length)
|
for (i in 0...arrows.length)
|
||||||
{
|
{
|
||||||
|
@ -629,12 +634,13 @@ class OffsetMenu extends Page<OptionsState.OptionsMenuPageName>
|
||||||
arrow.sprite.alpha -= elapsed * 5;
|
arrow.sprite.alpha -= elapsed * 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arrow.sprite.alpha <= 0)
|
if (arrow.beat == _lastArrowBeat || arrow.sprite.alpha <= 0)
|
||||||
{
|
{
|
||||||
toRemove.push(arrow);
|
toRemove.push(arrow);
|
||||||
arrow.sprite.kill();
|
arrow.sprite.kill();
|
||||||
// arrow.debugText.kill();
|
continue;
|
||||||
}
|
}
|
||||||
|
_lastArrowBeat = arrow.beat;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove arrows that are marked for removal.
|
// Remove arrows that are marked for removal.
|
||||||
|
|
|
@ -73,7 +73,7 @@ class OptionsState extends MusicBeatState
|
||||||
var options:OptionsMenu = optionsCodex.addPage(Options, new OptionsMenu(saveData));
|
var options:OptionsMenu = optionsCodex.addPage(Options, new OptionsMenu(saveData));
|
||||||
var preferences:PreferencesMenu = optionsCodex.addPage(Preferences, new PreferencesMenu());
|
var preferences:PreferencesMenu = optionsCodex.addPage(Preferences, new PreferencesMenu());
|
||||||
var controls:ControlsMenu = optionsCodex.addPage(Controls, new ControlsMenu());
|
var controls:ControlsMenu = optionsCodex.addPage(Controls, new ControlsMenu());
|
||||||
#if FEATURE_INPUT_OFFSETS
|
#if FEATURE_LAG_ADJUSTMENT
|
||||||
var offsets:OffsetMenu = optionsCodex.addPage(Offsets, new OffsetMenu());
|
var offsets:OffsetMenu = optionsCodex.addPage(Offsets, new OffsetMenu());
|
||||||
#end
|
#end
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ class OptionsState extends MusicBeatState
|
||||||
options.onExit.add(exitToMainMenu);
|
options.onExit.add(exitToMainMenu);
|
||||||
controls.onExit.add(exitControls);
|
controls.onExit.add(exitControls);
|
||||||
preferences.onExit.add(optionsCodex.switchPage.bind(Options));
|
preferences.onExit.add(optionsCodex.switchPage.bind(Options));
|
||||||
#if FEATURE_INPUT_OFFSETS
|
#if FEATURE_LAG_ADJUSTMENT
|
||||||
offsets.onExit.add(exitOffsets);
|
offsets.onExit.add(exitOffsets);
|
||||||
#end
|
#end
|
||||||
saveData.onExit.add(optionsCodex.switchPage.bind(Options));
|
saveData.onExit.add(optionsCodex.switchPage.bind(Options));
|
||||||
|
@ -174,8 +174,8 @@ class OptionsMenu extends Page<OptionsMenuPageName>
|
||||||
// createItem("CONTROL SCHEMES", function() {
|
// createItem("CONTROL SCHEMES", function() {
|
||||||
// FlxG.state.openSubState(new ControlsSchemeMenu());
|
// FlxG.state.openSubState(new ControlsSchemeMenu());
|
||||||
// });
|
// });
|
||||||
#if FEATURE_INPUT_OFFSETS
|
#if FEATURE_LAG_ADJUSTMENT
|
||||||
createItem("INPUT OFFSETS", function() {
|
createItem("LAG ADJUSTMENT", function() {
|
||||||
FlxG.sound.music.fadeOut(0.5, 0, function(tw) {
|
FlxG.sound.music.fadeOut(0.5, 0, function(tw) {
|
||||||
FunkinSound.playMusic('offsetsLoop',
|
FunkinSound.playMusic('offsetsLoop',
|
||||||
{
|
{
|
||||||
|
|
|
@ -65,7 +65,6 @@ class PreferencesMenu extends Page<OptionsState.OptionsMenuPageName>
|
||||||
createPrefDescription();
|
createPrefDescription();
|
||||||
|
|
||||||
camFollow = new FlxObject(FlxG.width / 2, 0, 140, 70);
|
camFollow = new FlxObject(FlxG.width / 2, 0, 140, 70);
|
||||||
if (items != null) camFollow.y = items.selectedItem.y;
|
|
||||||
|
|
||||||
menuCamera.follow(camFollow, null, 0.085);
|
menuCamera.follow(camFollow, null, 0.085);
|
||||||
var margin = 160;
|
var margin = 160;
|
||||||
|
@ -73,7 +72,6 @@ class PreferencesMenu extends Page<OptionsState.OptionsMenuPageName>
|
||||||
menuCamera.minScrollY = 0;
|
menuCamera.minScrollY = 0;
|
||||||
|
|
||||||
items.onChange.add(function(selected) {
|
items.onChange.add(function(selected) {
|
||||||
camFollow.y = selected.y;
|
|
||||||
itemDesc.text = preferenceDesc[items.selectedIndex];
|
itemDesc.text = preferenceDesc[items.selectedIndex];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -204,6 +202,9 @@ class PreferencesMenu extends Page<OptionsState.OptionsMenuPageName>
|
||||||
{
|
{
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
|
|
||||||
|
// Positions the camera to the selected item.
|
||||||
|
if (items != null) camFollow.y = items.selectedItem.y;
|
||||||
|
|
||||||
// Indent the selected item.
|
// Indent the selected item.
|
||||||
items.forEach(function(daItem:TextMenuItem) {
|
items.forEach(function(daItem:TextMenuItem) {
|
||||||
var thyOffset:Int = 0;
|
var thyOffset:Int = 0;
|
||||||
|
|
|
@ -228,11 +228,11 @@ class TitleState extends MusicBeatState
|
||||||
{
|
{
|
||||||
FlxG.bitmapLog.add(FlxG.camera.buffer);
|
FlxG.bitmapLog.add(FlxG.camera.buffer);
|
||||||
|
|
||||||
#if desktop
|
#if (desktop || android)
|
||||||
// Pressing BACK on the title screen should close the game.
|
// Pressing BACK on the title screen should close the game.
|
||||||
// This lets you exit without leaving fullscreen mode.
|
// This lets you exit without leaving fullscreen mode.
|
||||||
// Only applicable on desktop.
|
// Only applicable on desktop and Android.
|
||||||
if (controls.BACK)
|
if (#if android FlxG.android.justReleased.BACK || #end controls.BACK)
|
||||||
{
|
{
|
||||||
openfl.Lib.application.window.close();
|
openfl.Lib.application.window.close();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue