mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2024-11-15 11:22:55 +00:00
Implemented instrumental select (you need to beat the song as Pico first)!
This commit is contained in:
parent
0110936a3e
commit
1515719a0f
2
assets
2
assets
|
@ -1 +1 @@
|
|||
Subproject commit c7589a95af2709d240e1b1a2994e68a04565b00a
|
||||
Subproject commit 8af9bd2cf7122a5ad4dd2ca3939db75b11a5b239
|
|
@ -114,7 +114,7 @@ class ZoomCameraSongEvent extends SongEvent
|
|||
name: 'zoom',
|
||||
title: 'Zoom Level',
|
||||
defaultValue: 1.0,
|
||||
step: 0.1,
|
||||
step: 0.05,
|
||||
type: SongEventFieldType.FLOAT,
|
||||
units: 'x'
|
||||
},
|
||||
|
|
|
@ -514,6 +514,28 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry<SongMeta
|
|||
return variation.playData.difficulties.contains(diffId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of available alternate instrumentals.
|
||||
* Scripts can override this, fun.
|
||||
* @param variationId
|
||||
* @param difficultyId
|
||||
*/
|
||||
public function listAltInstrumentalIds(difficultyId:String, variationId:String):Array<String>
|
||||
{
|
||||
var targetDifficulty:Null<SongDifficulty> = getDifficulty(difficultyId, variationId);
|
||||
if (targetDifficulty == null) return [];
|
||||
|
||||
return targetDifficulty?.characters?.altInstrumentals ?? [];
|
||||
}
|
||||
|
||||
public function getBaseInstrumentalId(difficultyId:String, variationId:String):String
|
||||
{
|
||||
var targetDifficulty:Null<SongDifficulty> = getDifficulty(difficultyId, variationId);
|
||||
if (targetDifficulty == null) return '';
|
||||
|
||||
return targetDifficulty?.characters?.instrumental ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Purge the cached chart data for each difficulty of this song.
|
||||
*/
|
||||
|
|
|
@ -190,8 +190,8 @@ class ChartEditorEventDataToolbox extends ChartEditorBaseToolbox
|
|||
var numberStepper:NumberStepper = new NumberStepper();
|
||||
numberStepper.id = field.name;
|
||||
numberStepper.step = field.step ?? 1.0;
|
||||
numberStepper.min = field.min ?? 0.0;
|
||||
numberStepper.max = field.max ?? 10.0;
|
||||
if (field.min != null) numberStepper.min = field.min;
|
||||
if (field.max != null) numberStepper.max = field.max;
|
||||
if (field.defaultValue != null) numberStepper.value = field.defaultValue;
|
||||
input = numberStepper;
|
||||
case FLOAT:
|
||||
|
|
176
source/funkin/ui/freeplay/CapsuleOptionsMenu.hx
Normal file
176
source/funkin/ui/freeplay/CapsuleOptionsMenu.hx
Normal file
|
@ -0,0 +1,176 @@
|
|||
package funkin.ui.freeplay;
|
||||
|
||||
import funkin.graphics.shaders.PureColor;
|
||||
import funkin.input.Controls;
|
||||
import flixel.group.FlxSpriteGroup;
|
||||
import funkin.graphics.FunkinSprite;
|
||||
import flixel.util.FlxColor;
|
||||
import flixel.util.FlxTimer;
|
||||
import flixel.text.FlxText;
|
||||
import flixel.text.FlxText.FlxTextAlign;
|
||||
|
||||
@:nullSafety
|
||||
class CapsuleOptionsMenu extends FlxSpriteGroup
|
||||
{
|
||||
var capsuleMenuBG:FunkinSprite;
|
||||
var parent:FreeplayState;
|
||||
|
||||
var queueDestroy:Bool = false;
|
||||
|
||||
var instrumentalIds:Array<String> = [''];
|
||||
var currentInstrumentalIndex:Int = 0;
|
||||
|
||||
var currentInstrumental:FlxText;
|
||||
|
||||
public function new(parent:FreeplayState, x:Float = 0, y:Float = 0, instIds:Array<String>):Void
|
||||
{
|
||||
super(x, y);
|
||||
|
||||
this.parent = parent;
|
||||
this.instrumentalIds = instIds;
|
||||
|
||||
capsuleMenuBG = FunkinSprite.createSparrow(0, 0, 'freeplay/instBox/instBox');
|
||||
|
||||
capsuleMenuBG.animation.addByPrefix('open', 'open0', 24, false);
|
||||
capsuleMenuBG.animation.addByPrefix('idle', 'idle0', 24, true);
|
||||
capsuleMenuBG.animation.addByPrefix('open', 'open0', 24, false);
|
||||
|
||||
currentInstrumental = new FlxText(0, 36, capsuleMenuBG.width, '');
|
||||
currentInstrumental.setFormat('VCR OSD Mono', 40, FlxTextAlign.CENTER, true);
|
||||
|
||||
final PAD = 4;
|
||||
var leftArrow = new InstrumentalSelector(parent, PAD, 30, false, parent.getControls());
|
||||
var rightArrow = new InstrumentalSelector(parent, capsuleMenuBG.width - leftArrow.width - PAD, 30, true, parent.getControls());
|
||||
|
||||
var label:FlxText = new FlxText(0, 5, capsuleMenuBG.width, 'INSTRUMENTAL');
|
||||
label.setFormat('VCR OSD Mono', 24, FlxTextAlign.CENTER, true);
|
||||
|
||||
add(capsuleMenuBG);
|
||||
add(leftArrow);
|
||||
add(rightArrow);
|
||||
add(label);
|
||||
add(currentInstrumental);
|
||||
|
||||
capsuleMenuBG.animation.finishCallback = function(_) {
|
||||
capsuleMenuBG.animation.play('idle', true);
|
||||
};
|
||||
capsuleMenuBG.animation.play('open', true);
|
||||
}
|
||||
|
||||
public override function update(elapsed:Float):Void
|
||||
{
|
||||
super.update(elapsed);
|
||||
|
||||
if (queueDestroy)
|
||||
{
|
||||
destroy();
|
||||
return;
|
||||
}
|
||||
@:privateAccess
|
||||
if (parent.controls.BACK)
|
||||
{
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
var changedInst = false;
|
||||
if (parent.getControls().UI_LEFT_P)
|
||||
{
|
||||
currentInstrumentalIndex = (currentInstrumentalIndex + 1) % instrumentalIds.length;
|
||||
changedInst = true;
|
||||
}
|
||||
if (parent.getControls().UI_RIGHT_P)
|
||||
{
|
||||
currentInstrumentalIndex = (currentInstrumentalIndex - 1 + instrumentalIds.length) % instrumentalIds.length;
|
||||
changedInst = true;
|
||||
}
|
||||
if (!changedInst && currentInstrumental.text == '') changedInst = true;
|
||||
|
||||
if (changedInst)
|
||||
{
|
||||
currentInstrumental.text = instrumentalIds[currentInstrumentalIndex].toTitleCase() ?? '';
|
||||
if (currentInstrumental.text == '') currentInstrumental.text = 'Default';
|
||||
}
|
||||
|
||||
if (parent.getControls().ACCEPT)
|
||||
{
|
||||
onConfirm(instrumentalIds[currentInstrumentalIndex] ?? '');
|
||||
}
|
||||
}
|
||||
|
||||
public function close():Void
|
||||
{
|
||||
// Play in reverse.
|
||||
capsuleMenuBG.animation.play('open', true, true);
|
||||
capsuleMenuBG.animation.finishCallback = function(_) {
|
||||
parent.cleanupCapsuleOptionsMenu();
|
||||
queueDestroy = true;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this with `capsuleOptionsMenu.onConfirm = myFunction;`
|
||||
*/
|
||||
public dynamic function onConfirm(targetInstId:String):Void
|
||||
{
|
||||
throw 'onConfirm not implemented!';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The difficulty selector arrows to the left and right of the difficulty.
|
||||
*/
|
||||
class InstrumentalSelector extends FunkinSprite
|
||||
{
|
||||
var controls:Controls;
|
||||
var whiteShader:PureColor;
|
||||
|
||||
var parent:FreeplayState;
|
||||
|
||||
var baseScale:Float = 0.6;
|
||||
|
||||
public function new(parent:FreeplayState, x:Float, y:Float, flipped:Bool, controls:Controls)
|
||||
{
|
||||
super(x, y);
|
||||
|
||||
this.parent = parent;
|
||||
|
||||
this.controls = controls;
|
||||
|
||||
frames = Paths.getSparrowAtlas('freeplay/freeplaySelector');
|
||||
animation.addByPrefix('shine', 'arrow pointer loop', 24);
|
||||
animation.play('shine');
|
||||
|
||||
whiteShader = new PureColor(FlxColor.WHITE);
|
||||
|
||||
shader = whiteShader;
|
||||
|
||||
flipX = flipped;
|
||||
|
||||
scale.x = scale.y = 1 * baseScale;
|
||||
updateHitbox();
|
||||
}
|
||||
|
||||
override function update(elapsed:Float):Void
|
||||
{
|
||||
if (flipX && controls.UI_RIGHT_P) moveShitDown();
|
||||
if (!flipX && controls.UI_LEFT_P) moveShitDown();
|
||||
|
||||
super.update(elapsed);
|
||||
}
|
||||
|
||||
function moveShitDown():Void
|
||||
{
|
||||
offset.y -= 5;
|
||||
|
||||
whiteShader.colorSet = true;
|
||||
|
||||
scale.x = scale.y = 0.5 * baseScale;
|
||||
|
||||
new FlxTimer().start(2 / 24, function(tmr) {
|
||||
scale.x = scale.y = 1 * baseScale;
|
||||
whiteShader.colorSet = false;
|
||||
updateHitbox();
|
||||
});
|
||||
}
|
||||
}
|
|
@ -645,8 +645,8 @@ class FreeplayState extends MusicBeatSubState
|
|||
speed: 0.3
|
||||
});
|
||||
|
||||
var diffSelLeft:DifficultySelector = new DifficultySelector(20, grpDifficulties.y - 10, false, controls);
|
||||
var diffSelRight:DifficultySelector = new DifficultySelector(325, grpDifficulties.y - 10, true, controls);
|
||||
var diffSelLeft:DifficultySelector = new DifficultySelector(this, 20, grpDifficulties.y - 10, false, controls);
|
||||
var diffSelRight:DifficultySelector = new DifficultySelector(this, 325, grpDifficulties.y - 10, true, controls);
|
||||
diffSelLeft.visible = false;
|
||||
diffSelRight.visible = false;
|
||||
add(diffSelLeft);
|
||||
|
@ -822,7 +822,7 @@ class FreeplayState extends MusicBeatSubState
|
|||
|
||||
funnyMenu.init(FlxG.width, 0, tempSong);
|
||||
funnyMenu.onConfirm = function() {
|
||||
capsuleOnConfirmDefault(funnyMenu);
|
||||
capsuleOnOpenDefault(funnyMenu);
|
||||
};
|
||||
funnyMenu.y = funnyMenu.intendedY(i + 1) + 10;
|
||||
funnyMenu.targetPos.x = funnyMenu.x;
|
||||
|
@ -1203,7 +1203,7 @@ class FreeplayState extends MusicBeatSubState
|
|||
/**
|
||||
* If true, disable interaction with the interface.
|
||||
*/
|
||||
var busy:Bool = false;
|
||||
public var busy:Bool = false;
|
||||
|
||||
var originalPos:FlxPoint = new FlxPoint();
|
||||
|
||||
|
@ -1223,16 +1223,6 @@ class FreeplayState extends MusicBeatSubState
|
|||
});
|
||||
}
|
||||
|
||||
if (FlxG.keys.justPressed.P)
|
||||
{
|
||||
FlxG.switchState(FreeplayState.build(
|
||||
{
|
||||
{
|
||||
character: currentCharacterId == "pico" ? Constants.DEFAULT_CHARACTER : "pico",
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
// if (FlxG.keys.justPressed.H)
|
||||
// {
|
||||
// rankDisplayNew(fromResultsParams);
|
||||
|
@ -1496,7 +1486,7 @@ class FreeplayState extends MusicBeatSubState
|
|||
generateSongList(currentFilter, true);
|
||||
}
|
||||
|
||||
if (controls.BACK)
|
||||
if (controls.BACK && !busy)
|
||||
{
|
||||
busy = true;
|
||||
FlxTween.globalManager.clear();
|
||||
|
@ -1749,7 +1739,86 @@ class FreeplayState extends MusicBeatSubState
|
|||
capsuleOnConfirmDefault(targetSong);
|
||||
}
|
||||
|
||||
function capsuleOnConfirmDefault(cap:SongMenuItem):Void
|
||||
/**
|
||||
* Called when hitting ENTER to open the instrumental list.
|
||||
*/
|
||||
function capsuleOnOpenDefault(cap:SongMenuItem):Void
|
||||
{
|
||||
var targetSongId:String = cap?.songData?.songId ?? 'unknown';
|
||||
var targetSongNullable:Null<Song> = SongRegistry.instance.fetchEntry(targetSongId);
|
||||
if (targetSongNullable == null)
|
||||
{
|
||||
FlxG.log.warn('WARN: could not find song with id (${targetSongId})');
|
||||
return;
|
||||
}
|
||||
var targetSong:Song = targetSongNullable;
|
||||
var targetDifficultyId:String = currentDifficulty;
|
||||
var targetVariation:Null<String> = targetSong.getFirstValidVariation(targetDifficultyId, currentCharacter);
|
||||
var targetLevelId:Null<String> = cap?.songData?.levelId;
|
||||
PlayStatePlaylist.campaignId = targetLevelId ?? null;
|
||||
|
||||
var targetDifficulty:Null<SongDifficulty> = targetSong.getDifficulty(targetDifficultyId, targetVariation);
|
||||
if (targetDifficulty == null)
|
||||
{
|
||||
FlxG.log.warn('WARN: could not find difficulty with id (${targetDifficultyId})');
|
||||
return;
|
||||
}
|
||||
|
||||
trace('target difficulty: ${targetDifficultyId}');
|
||||
trace('target variation: ${targetDifficulty?.variation ?? Constants.DEFAULT_VARIATION}');
|
||||
|
||||
var baseInstrumentalId:String = targetSong.getBaseInstrumentalId(targetDifficultyId, targetDifficulty?.variation ?? Constants.DEFAULT_VARIATION) ?? '';
|
||||
var altInstrumentalIds:Array<String> = targetSong.listAltInstrumentalIds(targetDifficultyId,
|
||||
targetDifficulty?.variation ?? Constants.DEFAULT_VARIATION) ?? [];
|
||||
|
||||
if (altInstrumentalIds.length > 0)
|
||||
{
|
||||
var instrumentalIds = [baseInstrumentalId].concat(altInstrumentalIds);
|
||||
openInstrumentalList(cap, instrumentalIds);
|
||||
}
|
||||
else
|
||||
{
|
||||
trace('NO ALTS');
|
||||
capsuleOnConfirmDefault(cap);
|
||||
}
|
||||
}
|
||||
|
||||
public function getControls():Controls
|
||||
{
|
||||
return controls;
|
||||
}
|
||||
|
||||
function openInstrumentalList(cap:SongMenuItem, instrumentalIds:Array<String>):Void
|
||||
{
|
||||
busy = true;
|
||||
|
||||
capsuleOptionsMenu = new CapsuleOptionsMenu(this, cap.x + 175, cap.y + 115, instrumentalIds);
|
||||
capsuleOptionsMenu.cameras = [funnyCam];
|
||||
capsuleOptionsMenu.zIndex = 10000;
|
||||
add(capsuleOptionsMenu);
|
||||
|
||||
capsuleOptionsMenu.onConfirm = function(targetInstId:String) {
|
||||
capsuleOnConfirmDefault(cap, targetInstId);
|
||||
};
|
||||
}
|
||||
|
||||
var capsuleOptionsMenu:Null<CapsuleOptionsMenu> = null;
|
||||
|
||||
public function cleanupCapsuleOptionsMenu():Void
|
||||
{
|
||||
this.busy = false;
|
||||
|
||||
if (capsuleOptionsMenu != null)
|
||||
{
|
||||
remove(capsuleOptionsMenu);
|
||||
capsuleOptionsMenu = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when hitting ENTER to play the song.
|
||||
*/
|
||||
function capsuleOnConfirmDefault(cap:SongMenuItem, ?targetInstId:String):Void
|
||||
{
|
||||
busy = true;
|
||||
letterSort.inputEnabled = false;
|
||||
|
@ -1776,18 +1845,11 @@ class FreeplayState extends MusicBeatSubState
|
|||
return;
|
||||
}
|
||||
|
||||
var baseInstrumentalId:String = targetDifficulty?.characters?.instrumental ?? '';
|
||||
var altInstrumentalIds:Array<String> = targetDifficulty?.characters?.altInstrumentals ?? [];
|
||||
var baseInstrumentalId:String = targetSong?.getBaseInstrumentalId(targetDifficultyId, targetDifficulty.variation ?? Constants.DEFAULT_VARIATION) ?? '';
|
||||
var altInstrumentalIds:Array<String> = targetSong?.listAltInstrumentalIds(targetDifficultyId,
|
||||
targetDifficulty.variation ?? Constants.DEFAULT_VARIATION) ?? [];
|
||||
|
||||
var targetInstId:String = baseInstrumentalId;
|
||||
|
||||
// TODO: Make this a UI element.
|
||||
#if (debug || FORCE_DEBUG_VERSION)
|
||||
if (altInstrumentalIds.length > 0 && FlxG.keys.pressed.CONTROL)
|
||||
{
|
||||
targetInstId = altInstrumentalIds[0];
|
||||
}
|
||||
#end
|
||||
if (targetInstId == null) targetInstId = baseInstrumentalId;
|
||||
|
||||
// Visual and audio effects.
|
||||
FunkinSound.playOnce(Paths.sound('confirmMenu'));
|
||||
|
@ -1942,10 +2004,12 @@ class FreeplayState extends MusicBeatSubState
|
|||
if (previewSongId == null) return;
|
||||
|
||||
var previewSong:Null<Song> = SongRegistry.instance.fetchEntry(previewSongId);
|
||||
var songDifficulty = previewSong?.getDifficulty(currentDifficulty,
|
||||
previewSong?.getVariationsByCharacter(currentCharacter) ?? Constants.DEFAULT_VARIATION_LIST);
|
||||
var baseInstrumentalId:String = songDifficulty?.characters?.instrumental ?? '';
|
||||
var altInstrumentalIds:Array<String> = songDifficulty?.characters?.altInstrumentals ?? [];
|
||||
var currentVariation = previewSong?.getVariationsByCharacter(currentCharacter) ?? Constants.DEFAULT_VARIATION_LIST;
|
||||
var songDifficulty = previewSong?.getDifficulty(currentDifficulty, currentVariation);
|
||||
|
||||
var baseInstrumentalId:String = previewSong?.getBaseInstrumentalId(currentDifficulty, songDifficulty?.variation ?? Constants.DEFAULT_VARIATION) ?? '';
|
||||
var altInstrumentalIds:Array<String> = previewSong?.listAltInstrumentalIds(currentDifficulty,
|
||||
songDifficulty?.variation ?? Constants.DEFAULT_VARIATION) ?? [];
|
||||
|
||||
var instSuffix:String = baseInstrumentalId;
|
||||
|
||||
|
@ -2008,10 +2072,14 @@ class DifficultySelector extends FlxSprite
|
|||
var controls:Controls;
|
||||
var whiteShader:PureColor;
|
||||
|
||||
public function new(x:Float, y:Float, flipped:Bool, controls:Controls)
|
||||
var parent:FreeplayState;
|
||||
|
||||
public function new(parent:FreeplayState, x:Float, y:Float, flipped:Bool, controls:Controls)
|
||||
{
|
||||
super(x, y);
|
||||
|
||||
this.parent = parent;
|
||||
|
||||
this.controls = controls;
|
||||
|
||||
frames = Paths.getSparrowAtlas('freeplay/freeplaySelector');
|
||||
|
@ -2027,8 +2095,8 @@ class DifficultySelector extends FlxSprite
|
|||
|
||||
override function update(elapsed:Float):Void
|
||||
{
|
||||
if (flipX && controls.UI_RIGHT_P) moveShitDown();
|
||||
if (!flipX && controls.UI_LEFT_P) moveShitDown();
|
||||
if (flipX && controls.UI_RIGHT_P && !parent.busy) moveShitDown();
|
||||
if (!flipX && controls.UI_LEFT_P && !parent.busy) moveShitDown();
|
||||
|
||||
super.update(elapsed);
|
||||
}
|
||||
|
|
|
@ -117,13 +117,7 @@ class MainMenuState extends MusicBeatState
|
|||
FlxTransitionableState.skipNextTransIn = true;
|
||||
FlxTransitionableState.skipNextTransOut = true;
|
||||
|
||||
openSubState(new FreeplayState(
|
||||
{
|
||||
#if debug
|
||||
// If SHIFT is held, toggle the selected character, else use the remembered character
|
||||
character: (FlxG.keys.pressed.SHIFT) ? (FreeplayState.rememberedCharacterId == Constants.DEFAULT_CHARACTER ? 'pico' : 'bf') : null,
|
||||
#end
|
||||
}));
|
||||
openSubState(new FreeplayState());
|
||||
});
|
||||
|
||||
#if CAN_OPEN_LINKS
|
||||
|
|
Loading…
Reference in a new issue