mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2024-11-30 18:53:35 +00:00
Merge branch 'rewrite/master' into rewrite/bugfix/chart-editor-various-fixes
This commit is contained in:
commit
6bf6b8ef11
|
@ -16,17 +16,18 @@ class PauseSubState extends MusicBeatSubState
|
|||
{
|
||||
var grpMenuShit:FlxTypedGroup<Alphabet>;
|
||||
|
||||
var pauseOptionsBase:Array<String> = [
|
||||
final pauseOptionsBase:Array<String> = [
|
||||
'Resume',
|
||||
'Restart Song',
|
||||
'Change Difficulty',
|
||||
'Toggle Practice Mode',
|
||||
'Exit to Menu'
|
||||
];
|
||||
final pauseOptionsCharting:Array<String> = ['Resume', 'Restart Song', 'Exit to Chart Editor'];
|
||||
|
||||
var pauseOptionsDifficulty:Array<String> = ['EASY', 'NORMAL', 'HARD', 'ERECT', 'BACK'];
|
||||
final pauseOptionsDifficultyBase:Array<String> = ['BACK'];
|
||||
|
||||
var pauseOptionsCharting:Array<String> = ['Resume', 'Restart Song', 'Exit to Chart Editor'];
|
||||
var pauseOptionsDifficulty:Array<String> = []; // AUTO-POPULATED
|
||||
|
||||
var menuItems:Array<String> = [];
|
||||
var curSelected:Int = 0;
|
||||
|
@ -48,6 +49,12 @@ class PauseSubState extends MusicBeatSubState
|
|||
this.isChartingMode = isChartingMode;
|
||||
|
||||
menuItems = this.isChartingMode ? pauseOptionsCharting : pauseOptionsBase;
|
||||
var difficultiesInVariation = PlayState.instance.currentSong.listDifficulties(PlayState.instance.currentChart.variation);
|
||||
trace('DIFFICULTIES: ${difficultiesInVariation}');
|
||||
|
||||
pauseOptionsDifficulty = difficultiesInVariation.map(function(item:String):String {
|
||||
return item.toUpperCase();
|
||||
}).concat(pauseOptionsDifficultyBase);
|
||||
|
||||
if (PlayStatePlaylist.campaignId == 'week6')
|
||||
{
|
||||
|
@ -201,18 +208,6 @@ class PauseSubState extends MusicBeatSubState
|
|||
menuItems = pauseOptionsDifficulty;
|
||||
regenMenu();
|
||||
|
||||
case 'EASY' | 'NORMAL' | 'HARD' | 'ERECT':
|
||||
PlayState.instance.currentSong = SongRegistry.instance.fetchEntry(PlayState.instance.currentSong.id.toLowerCase());
|
||||
|
||||
PlayState.instance.currentDifficulty = daSelected.toLowerCase();
|
||||
|
||||
PlayState.instance.needsReset = true;
|
||||
|
||||
close();
|
||||
case 'BACK':
|
||||
menuItems = this.isChartingMode ? pauseOptionsCharting : pauseOptionsBase;
|
||||
regenMenu();
|
||||
|
||||
case 'Toggle Practice Mode':
|
||||
PlayState.instance.isPracticeMode = true;
|
||||
practiceText.visible = PlayState.instance.isPracticeMode;
|
||||
|
@ -247,6 +242,30 @@ class PauseSubState extends MusicBeatSubState
|
|||
this.close();
|
||||
if (FlxG.sound.music != null) FlxG.sound.music.stop();
|
||||
PlayState.instance.close(); // This only works because PlayState is a substate!
|
||||
|
||||
case 'BACK':
|
||||
menuItems = this.isChartingMode ? pauseOptionsCharting : pauseOptionsBase;
|
||||
regenMenu();
|
||||
|
||||
default:
|
||||
if (pauseOptionsDifficulty.contains(daSelected))
|
||||
{
|
||||
PlayState.instance.currentSong = SongRegistry.instance.fetchEntry(PlayState.instance.currentSong.id.toLowerCase());
|
||||
|
||||
// Reset campaign score when changing difficulty
|
||||
// So if you switch difficulty on the last song of a week you get a really low overall score.
|
||||
PlayStatePlaylist.campaignScore = 0;
|
||||
PlayStatePlaylist.campaignDifficulty = daSelected.toLowerCase();
|
||||
PlayState.instance.currentDifficulty = PlayStatePlaylist.campaignDifficulty;
|
||||
|
||||
PlayState.instance.needsReset = true;
|
||||
|
||||
close();
|
||||
}
|
||||
else
|
||||
{
|
||||
trace('[WARN] Unhandled pause menu option: ${daSelected}');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -102,6 +102,9 @@ class GameOverSubState extends MusicBeatSubState
|
|||
cameraFollowPoint = new FlxObject(PlayState.instance.cameraFollowPoint.x, PlayState.instance.cameraFollowPoint.y, 1, 1);
|
||||
cameraFollowPoint.x = boyfriend.getGraphicMidpoint().x;
|
||||
cameraFollowPoint.y = boyfriend.getGraphicMidpoint().y;
|
||||
var offsets:Array<Float> = boyfriend.getDeathCameraOffsets();
|
||||
cameraFollowPoint.x += offsets[0];
|
||||
cameraFollowPoint.y += offsets[1];
|
||||
add(cameraFollowPoint);
|
||||
|
||||
FlxG.camera.target = null;
|
||||
|
|
|
@ -1641,7 +1641,7 @@ class PlayState extends MusicBeatSubState
|
|||
*/
|
||||
function onConversationComplete():Void
|
||||
{
|
||||
isInCutscene = true;
|
||||
isInCutscene = false;
|
||||
remove(currentConversation);
|
||||
currentConversation = null;
|
||||
|
||||
|
@ -2463,9 +2463,9 @@ class PlayState extends MusicBeatSubState
|
|||
accuracy: Highscore.tallies.totalNotesHit / Highscore.tallies.totalNotes,
|
||||
};
|
||||
|
||||
if (Save.get().isLevelHighScore(PlayStatePlaylist.campaignId, currentDifficulty, data))
|
||||
if (Save.get().isLevelHighScore(PlayStatePlaylist.campaignId, PlayStatePlaylist.campaignDifficulty, data))
|
||||
{
|
||||
Save.get().setLevelScore(PlayStatePlaylist.campaignId, currentDifficulty, data);
|
||||
Save.get().setLevelScore(PlayStatePlaylist.campaignId, PlayStatePlaylist.campaignDifficulty, data);
|
||||
#if newgrounds
|
||||
NGio.postScore(score, 'Level ${PlayStatePlaylist.campaignId}');
|
||||
#end
|
||||
|
@ -2513,7 +2513,7 @@ class PlayState extends MusicBeatSubState
|
|||
var nextPlayState:PlayState = new PlayState(
|
||||
{
|
||||
targetSong: targetSong,
|
||||
targetDifficulty: currentDifficulty,
|
||||
targetDifficulty: PlayStatePlaylist.campaignDifficulty,
|
||||
targetCharacter: currentPlayerId,
|
||||
});
|
||||
nextPlayState.previousCameraFollowPoint = new FlxSprite(cameraFollowPoint.x, cameraFollowPoint.y);
|
||||
|
@ -2529,7 +2529,7 @@ class PlayState extends MusicBeatSubState
|
|||
var nextPlayState:PlayState = new PlayState(
|
||||
{
|
||||
targetSong: targetSong,
|
||||
targetDifficulty: currentDifficulty,
|
||||
targetDifficulty: PlayStatePlaylist.campaignDifficulty,
|
||||
targetCharacter: currentPlayerId,
|
||||
});
|
||||
nextPlayState.previousCameraFollowPoint = new FlxSprite(cameraFollowPoint.x, cameraFollowPoint.y);
|
||||
|
@ -2655,7 +2655,12 @@ class PlayState extends MusicBeatSubState
|
|||
persistentUpdate = false;
|
||||
vocals.stop();
|
||||
camHUD.alpha = 1;
|
||||
var res:ResultState = new ResultState();
|
||||
var res:ResultState = new ResultState(
|
||||
{
|
||||
storyMode: PlayStatePlaylist.isStoryMode,
|
||||
title: PlayStatePlaylist.isStoryMode ? ('${PlayStatePlaylist.campaignTitle}') : ('${currentChart.songName} by ${currentChart.songArtist}'),
|
||||
tallies: Highscore.tallies,
|
||||
});
|
||||
res.camera = camHUD;
|
||||
openSubState(res);
|
||||
}
|
||||
|
|
|
@ -34,10 +34,7 @@ class PlayStatePlaylist
|
|||
*/
|
||||
public static var campaignId:String = 'unknown';
|
||||
|
||||
/**
|
||||
* The current difficulty selected for this level (as a named ID).
|
||||
*/
|
||||
public static var currentDifficulty(default, default):String = Constants.DEFAULT_DIFFICULTY;
|
||||
public static var campaignDifficulty:String = Constants.DEFAULT_DIFFICULTY;
|
||||
|
||||
/**
|
||||
* Resets the playlist to its default state.
|
||||
|
@ -49,6 +46,6 @@ class PlayStatePlaylist
|
|||
campaignScore = 0;
|
||||
campaignTitle = 'UNKNOWN';
|
||||
campaignId = 'unknown';
|
||||
currentDifficulty = Constants.DEFAULT_DIFFICULTY;
|
||||
campaignDifficulty = Constants.DEFAULT_DIFFICULTY;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,8 @@ import flxanimate.FlxAnimate.Settings;
|
|||
|
||||
class ResultState extends MusicBeatSubState
|
||||
{
|
||||
final params:ResultsStateParams;
|
||||
|
||||
var resultsVariation:ResultVariations;
|
||||
var songName:FlxBitmapText;
|
||||
var difficulty:FlxSprite;
|
||||
|
@ -29,13 +31,18 @@ class ResultState extends MusicBeatSubState
|
|||
var maskShaderSongName = new LeftMaskShader();
|
||||
var maskShaderDifficulty = new LeftMaskShader();
|
||||
|
||||
public function new(params:ResultsStateParams)
|
||||
{
|
||||
super();
|
||||
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
override function create():Void
|
||||
{
|
||||
if (Highscore.tallies.sick == Highscore.tallies.totalNotesHit
|
||||
&& Highscore.tallies.maxCombo == Highscore.tallies.totalNotesHit) resultsVariation = PERFECT;
|
||||
else if (Highscore.tallies.missed
|
||||
+ Highscore.tallies.bad
|
||||
+ Highscore.tallies.shit >= Highscore.tallies.totalNotes * 0.50)
|
||||
if (params.tallies.sick == params.tallies.totalNotesHit
|
||||
&& params.tallies.maxCombo == params.tallies.totalNotesHit) resultsVariation = PERFECT;
|
||||
else if (params.tallies.missed + params.tallies.bad + params.tallies.shit >= params.tallies.totalNotes * 0.50)
|
||||
resultsVariation = SHIT; // if more than half of your song was missed, bad, or shit notes, you get shit ending!
|
||||
else
|
||||
resultsVariation = NORMAL;
|
||||
|
@ -135,17 +142,7 @@ class ResultState extends MusicBeatSubState
|
|||
|
||||
var fontLetters:String = "AaBbCcDdEeFfGgHhiIJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz:1234567890";
|
||||
songName = new FlxBitmapText(FlxBitmapFont.fromMonospace(Paths.image("resultScreen/tardlingSpritesheet"), fontLetters, FlxPoint.get(49, 62)));
|
||||
|
||||
// stole this from PauseSubState, I think eric wrote it!!
|
||||
if (PlayState.instance.currentChart != null)
|
||||
{
|
||||
songName.text += '${PlayState.instance.currentChart.songName}:${PlayState.instance.currentChart.songArtist}';
|
||||
}
|
||||
else
|
||||
{
|
||||
songName.text += PlayState.instance.currentSong.id;
|
||||
}
|
||||
|
||||
songName.text = params.title;
|
||||
songName.letterSpacing = -15;
|
||||
songName.angle = -4.1;
|
||||
add(songName);
|
||||
|
@ -194,27 +191,27 @@ class ResultState extends MusicBeatSubState
|
|||
var ratingGrp:FlxTypedGroup<TallyCounter> = new FlxTypedGroup<TallyCounter>();
|
||||
add(ratingGrp);
|
||||
|
||||
var totalHit:TallyCounter = new TallyCounter(375, hStuf * 3, Highscore.tallies.totalNotesHit);
|
||||
var totalHit:TallyCounter = new TallyCounter(375, hStuf * 3, params.tallies.totalNotesHit);
|
||||
ratingGrp.add(totalHit);
|
||||
|
||||
var maxCombo:TallyCounter = new TallyCounter(375, hStuf * 4, Highscore.tallies.maxCombo);
|
||||
var maxCombo:TallyCounter = new TallyCounter(375, hStuf * 4, params.tallies.maxCombo);
|
||||
ratingGrp.add(maxCombo);
|
||||
|
||||
hStuf += 2;
|
||||
var extraYOffset:Float = 5;
|
||||
var tallySick:TallyCounter = new TallyCounter(230, (hStuf * 5) + extraYOffset, Highscore.tallies.sick, 0xFF89E59E);
|
||||
var tallySick:TallyCounter = new TallyCounter(230, (hStuf * 5) + extraYOffset, params.tallies.sick, 0xFF89E59E);
|
||||
ratingGrp.add(tallySick);
|
||||
|
||||
var tallyGood:TallyCounter = new TallyCounter(210, (hStuf * 6) + extraYOffset, Highscore.tallies.good, 0xFF89C9E5);
|
||||
var tallyGood:TallyCounter = new TallyCounter(210, (hStuf * 6) + extraYOffset, params.tallies.good, 0xFF89C9E5);
|
||||
ratingGrp.add(tallyGood);
|
||||
|
||||
var tallyBad:TallyCounter = new TallyCounter(190, (hStuf * 7) + extraYOffset, Highscore.tallies.bad, 0xffE6CF8A);
|
||||
var tallyBad:TallyCounter = new TallyCounter(190, (hStuf * 7) + extraYOffset, params.tallies.bad, 0xffE6CF8A);
|
||||
ratingGrp.add(tallyBad);
|
||||
|
||||
var tallyShit:TallyCounter = new TallyCounter(220, (hStuf * 8) + extraYOffset, Highscore.tallies.shit, 0xFFE68C8A);
|
||||
var tallyShit:TallyCounter = new TallyCounter(220, (hStuf * 8) + extraYOffset, params.tallies.shit, 0xFFE68C8A);
|
||||
ratingGrp.add(tallyShit);
|
||||
|
||||
var tallyMissed:TallyCounter = new TallyCounter(260, (hStuf * 9) + extraYOffset, Highscore.tallies.missed, 0xFFC68AE6);
|
||||
var tallyMissed:TallyCounter = new TallyCounter(260, (hStuf * 9) + extraYOffset, params.tallies.missed, 0xFFC68AE6);
|
||||
ratingGrp.add(tallyMissed);
|
||||
|
||||
for (ind => rating in ratingGrp.members)
|
||||
|
@ -275,7 +272,7 @@ class ResultState extends MusicBeatSubState
|
|||
}
|
||||
});
|
||||
|
||||
if (Highscore.tallies.isNewHighscore) trace("ITS A NEW HIGHSCORE!!!");
|
||||
if (params.tallies.isNewHighscore) trace("ITS A NEW HIGHSCORE!!!");
|
||||
|
||||
super.create();
|
||||
}
|
||||
|
@ -351,7 +348,7 @@ class ResultState extends MusicBeatSubState
|
|||
|
||||
if (controls.PAUSE)
|
||||
{
|
||||
if (PlayStatePlaylist.isStoryMode)
|
||||
if (params.storyMode)
|
||||
{
|
||||
FlxG.switchState(new StoryMenuState());
|
||||
}
|
||||
|
@ -372,3 +369,21 @@ enum abstract ResultVariations(String)
|
|||
var NORMAL;
|
||||
var SHIT;
|
||||
}
|
||||
|
||||
typedef ResultsStateParams =
|
||||
{
|
||||
/**
|
||||
* True if results are for a level, false if results are for a single song.
|
||||
*/
|
||||
var storyMode:Bool;
|
||||
|
||||
/**
|
||||
* Either "Song Name by Artist Name" or "Week Name"
|
||||
*/
|
||||
var title:String;
|
||||
|
||||
/**
|
||||
* The score, accuracy, and judgements.
|
||||
*/
|
||||
var tallies:Highscore.Tallies;
|
||||
};
|
||||
|
|
|
@ -188,6 +188,11 @@ class BaseCharacter extends Bopper
|
|||
shouldBop = false;
|
||||
}
|
||||
|
||||
public function getDeathCameraOffsets():Array<Float>
|
||||
{
|
||||
return _data.death?.cameraOffsets ?? [0.0, 0.0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of flipX from the character data.
|
||||
* `!getFlipX()` is the direction Boyfriend should face.
|
||||
|
@ -571,8 +576,7 @@ class BaseCharacter extends Bopper
|
|||
|
||||
public override function playAnimation(name:String, restart:Bool = false, ignoreOther:Bool = false, reversed:Bool = false):Void
|
||||
{
|
||||
FlxG.watch.addQuick('playAnim(${characterName})', name);
|
||||
// trace('playAnim(${characterName}): ${name}');
|
||||
// FlxG.watch.addQuick('playAnim(${characterName})', name);
|
||||
super.playAnimation(name, restart, ignoreOther, reversed);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,10 @@ class CharacterDataParser
|
|||
* The current version string for the stage data format.
|
||||
* Handle breaking changes by incrementing this value
|
||||
* and adding migration to the `migrateStageData()` function.
|
||||
*
|
||||
* - Version 1.0.1 adds `death.cameraOffsets`
|
||||
*/
|
||||
public static final CHARACTER_DATA_VERSION:String = '1.0.0';
|
||||
public static final CHARACTER_DATA_VERSION:String = '1.0.1';
|
||||
|
||||
/**
|
||||
* The current version rule check for the stage data format.
|
||||
|
@ -603,6 +605,8 @@ typedef CharacterData =
|
|||
*/
|
||||
var healthIcon:Null<HealthIconData>;
|
||||
|
||||
var death:Null<DeathData>;
|
||||
|
||||
/**
|
||||
* The global offset to the character's position, in pixels.
|
||||
* @default [0, 0]
|
||||
|
@ -695,3 +699,13 @@ typedef HealthIconData =
|
|||
*/
|
||||
var offsets:Null<Array<Float>>;
|
||||
}
|
||||
|
||||
typedef DeathData =
|
||||
{
|
||||
/**
|
||||
* The amount to offset the camera by while focusing on this character as they die.
|
||||
* Default value focuses on the character's graphic midpoint.
|
||||
* @default [0, 0]
|
||||
*/
|
||||
var ?cameraOffsets:Array<Float>;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package funkin.play.song;
|
||||
|
||||
import funkin.util.SortUtil;
|
||||
import flixel.sound.FlxSound;
|
||||
import openfl.utils.Assets;
|
||||
import funkin.modding.events.ScriptEvent;
|
||||
|
@ -56,8 +57,6 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry<SongMeta
|
|||
*/
|
||||
public var validScore:Bool = true;
|
||||
|
||||
var difficultyIds:Array<String>;
|
||||
|
||||
public var songName(get, never):String;
|
||||
|
||||
function get_songName():String
|
||||
|
@ -85,7 +84,6 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry<SongMeta
|
|||
this.id = id;
|
||||
|
||||
variations = [];
|
||||
difficultyIds = [];
|
||||
difficulties = new Map<String, SongDifficulty>();
|
||||
|
||||
_data = _fetchData(id);
|
||||
|
@ -127,8 +125,7 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry<SongMeta
|
|||
for (vari in variations)
|
||||
result.variations.push(vari);
|
||||
|
||||
result.difficultyIds.clear();
|
||||
|
||||
result.difficulties.clear();
|
||||
result.populateDifficulties();
|
||||
|
||||
for (variation => chartData in charts)
|
||||
|
@ -162,8 +159,6 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry<SongMeta
|
|||
// but all the difficulties in the metadata must be in the chart file.
|
||||
for (diffId in metadata.playData.difficulties)
|
||||
{
|
||||
difficultyIds.push(diffId);
|
||||
|
||||
var difficulty:SongDifficulty = new SongDifficulty(this, diffId, metadata.variation);
|
||||
|
||||
variations.push(metadata.variation);
|
||||
|
@ -237,19 +232,37 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry<SongMeta
|
|||
*/
|
||||
public inline function getDifficulty(?diffId:String):Null<SongDifficulty>
|
||||
{
|
||||
if (diffId == null) diffId = difficulties.keys().array()[0];
|
||||
if (diffId == null) diffId = listDifficulties()[0];
|
||||
|
||||
return difficulties.get(diffId);
|
||||
}
|
||||
|
||||
public function listDifficulties():Array<String>
|
||||
/**
|
||||
* List all the difficulties in this song.
|
||||
* @param variationId Optionally filter by variation.
|
||||
* @return The list of difficulties.
|
||||
*/
|
||||
public function listDifficulties(?variationId:String):Array<String>
|
||||
{
|
||||
return difficultyIds;
|
||||
if (variationId == '') variationId = null;
|
||||
|
||||
var diffFiltered:Array<String> = difficulties.keys().array().filter(function(diffId:String):Bool {
|
||||
if (variationId == null) return true;
|
||||
var difficulty:Null<SongDifficulty> = difficulties.get(diffId);
|
||||
if (difficulty == null) return false;
|
||||
return difficulty.variation == variationId;
|
||||
});
|
||||
|
||||
diffFiltered.sort(SortUtil.defaultsThenAlphabetically.bind(Constants.DEFAULT_DIFFICULTY_LIST));
|
||||
|
||||
return diffFiltered;
|
||||
}
|
||||
|
||||
public function hasDifficulty(diffId:String):Bool
|
||||
public function hasDifficulty(diffId:String, ?variationId:String):Bool
|
||||
{
|
||||
return difficulties.exists(diffId);
|
||||
if (variationId == '') variationId = null;
|
||||
var difficulty:Null<SongDifficulty> = difficulties.get(diffId);
|
||||
return variationId == null ? (difficulty != null) : (difficulty != null && difficulty.variation == variationId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -667,8 +667,6 @@ class ChartEditorDialogHandler
|
|||
timeChanges[0].bpm = event.value;
|
||||
}
|
||||
|
||||
Conductor.forceBPM(event.value);
|
||||
|
||||
newSongMetadata.timeChanges = timeChanges;
|
||||
};
|
||||
|
||||
|
@ -677,6 +675,8 @@ class ChartEditorDialogHandler
|
|||
dialogContinue.onClick = (_event) -> {
|
||||
state.songMetadata.set(targetVariation, newSongMetadata);
|
||||
|
||||
Conductor.mapTimeChanges(state.currentSongMetadata.timeChanges);
|
||||
|
||||
dialog.hideDialog(DialogButton.APPLY);
|
||||
}
|
||||
|
||||
|
@ -696,6 +696,8 @@ class ChartEditorDialogHandler
|
|||
|
||||
var charData:SongCharacterData = state.currentSongMetadata.playData.characters;
|
||||
|
||||
var hasClearedVocals:Bool = false;
|
||||
|
||||
charIdsForVocals.push(charData.player);
|
||||
charIdsForVocals.push(charData.opponent);
|
||||
|
||||
|
@ -715,6 +717,7 @@ class ChartEditorDialogHandler
|
|||
if (dialogNoVocals == null) throw 'Could not locate dialogNoVocals button in Upload Vocals dialog';
|
||||
dialogNoVocals.onClick = function(_event) {
|
||||
// Dismiss
|
||||
ChartEditorAudioHandler.stopExistingVocals(state);
|
||||
dialog.hideDialog(DialogButton.APPLY);
|
||||
};
|
||||
|
||||
|
@ -738,6 +741,12 @@ class ChartEditorDialogHandler
|
|||
trace('Selected file: $pathStr');
|
||||
var path:Path = new Path(pathStr);
|
||||
|
||||
if (!hasClearedVocals)
|
||||
{
|
||||
hasClearedVocals = true;
|
||||
ChartEditorAudioHandler.stopExistingVocals(state);
|
||||
}
|
||||
|
||||
if (ChartEditorAudioHandler.loadVocalsFromPath(state, path, charKey, instId))
|
||||
{
|
||||
// Tell the user the load was successful.
|
||||
|
@ -788,6 +797,11 @@ class ChartEditorDialogHandler
|
|||
if (selectedFile != null && selectedFile.bytes != null)
|
||||
{
|
||||
trace('Selected file: ' + selectedFile.name);
|
||||
if (!hasClearedVocals)
|
||||
{
|
||||
hasClearedVocals = true;
|
||||
ChartEditorAudioHandler.stopExistingVocals(state);
|
||||
}
|
||||
if (ChartEditorAudioHandler.loadVocalsFromBytes(state, selectedFile.bytes, charKey, instId))
|
||||
{
|
||||
// Tell the user the load was successful.
|
||||
|
|
|
@ -1898,6 +1898,16 @@ class ChartEditorState extends HaxeUIState
|
|||
handleViewKeybinds();
|
||||
handleTestKeybinds();
|
||||
handleHelpKeybinds();
|
||||
|
||||
#if debug
|
||||
handleQuickWatch();
|
||||
#end
|
||||
}
|
||||
|
||||
function handleQuickWatch():Void
|
||||
{
|
||||
FlxG.watch.addQuick('scrollPosInPixels', scrollPositionInPixels);
|
||||
FlxG.watch.addQuick('playheadPosInPixels', playheadPositionInPixels);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3140,6 +3150,7 @@ class ChartEditorState extends HaxeUIState
|
|||
function quitChartEditor():Void
|
||||
{
|
||||
autoSave();
|
||||
stopWelcomeMusic();
|
||||
FlxG.switchState(new MainMenuState());
|
||||
}
|
||||
|
||||
|
@ -3363,6 +3374,7 @@ class ChartEditorState extends HaxeUIState
|
|||
if (!isHaxeUIDialogOpen && !isCursorOverHaxeUI && FlxG.keys.justPressed.ENTER)
|
||||
{
|
||||
var minimal = FlxG.keys.pressed.SHIFT;
|
||||
ChartEditorToolboxHandler.hideAllToolboxes(this);
|
||||
testSongInPlayState(minimal);
|
||||
}
|
||||
}
|
||||
|
@ -4166,14 +4178,13 @@ class ChartEditorState extends HaxeUIState
|
|||
*/
|
||||
function moveSongToScrollPosition():Void
|
||||
{
|
||||
// Update the songPosition in the Conductor.
|
||||
var targetPos = scrollPositionInMs;
|
||||
Conductor.update(targetPos);
|
||||
|
||||
// Update the songPosition in the audio tracks.
|
||||
if (audioInstTrack != null) audioInstTrack.time = scrollPositionInMs + playheadPositionInMs;
|
||||
if (audioVocalTrackGroup != null) audioVocalTrackGroup.time = scrollPositionInMs + playheadPositionInMs;
|
||||
|
||||
// Update the songPosition in the Conductor.
|
||||
Conductor.update(audioInstTrack.time);
|
||||
|
||||
// We need to update the note sprites because we changed the scroll position.
|
||||
noteDisplayDirty = true;
|
||||
}
|
||||
|
|
|
@ -136,6 +136,18 @@ class ChartEditorToolboxHandler
|
|||
}
|
||||
}
|
||||
|
||||
public static function rememberOpenToolboxes(state:ChartEditorState):Void {}
|
||||
|
||||
public static function openRememberedToolboxes(state:ChartEditorState):Void {}
|
||||
|
||||
public static function hideAllToolboxes(state:ChartEditorState):Void
|
||||
{
|
||||
for (toolbox in state.activeToolboxes.values())
|
||||
{
|
||||
toolbox.hideDialog(DialogButton.CANCEL);
|
||||
}
|
||||
}
|
||||
|
||||
public static function minimizeToolbox(state:ChartEditorState, id:String):Void
|
||||
{
|
||||
var toolbox:Null<CollapsibleDialog> = state.activeToolboxes.get(id);
|
||||
|
@ -634,9 +646,9 @@ class ChartEditorToolboxHandler
|
|||
timeChanges[0].bpm = event.value;
|
||||
}
|
||||
|
||||
Conductor.forceBPM(event.value);
|
||||
|
||||
state.currentSongMetadata.timeChanges = timeChanges;
|
||||
|
||||
Conductor.mapTimeChanges(state.currentSongMetadata.timeChanges);
|
||||
};
|
||||
inputBPM.value = state.currentSongMetadata.timeChanges[0].bpm;
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package funkin.ui.story;
|
||||
|
||||
import funkin.util.SortUtil;
|
||||
import flixel.FlxSprite;
|
||||
import flixel.util.FlxColor;
|
||||
import funkin.play.song.Song;
|
||||
|
@ -155,6 +156,8 @@ class Level implements IRegistryEntry<LevelData>
|
|||
}
|
||||
}
|
||||
|
||||
difficulties.sort(SortUtil.defaultsThenAlphabetically.bind(Constants.DEFAULT_DIFFICULTY_LIST));
|
||||
|
||||
// Filter to only include difficulties that are present in all songs
|
||||
for (songIndex in 1...songList.length)
|
||||
{
|
||||
|
|
|
@ -523,6 +523,7 @@ class StoryMenuState extends MusicBeatState
|
|||
|
||||
PlayStatePlaylist.campaignId = currentLevel.id;
|
||||
PlayStatePlaylist.campaignTitle = currentLevel.getTitle();
|
||||
PlayStatePlaylist.campaignDifficulty = currentDifficultyId;
|
||||
|
||||
if (targetSong != null)
|
||||
{
|
||||
|
@ -538,7 +539,7 @@ class StoryMenuState extends MusicBeatState
|
|||
LoadingState.loadAndSwitchState(new PlayState(
|
||||
{
|
||||
targetSong: targetSong,
|
||||
targetDifficulty: currentDifficultyId,
|
||||
targetDifficulty: PlayStatePlaylist.campaignDifficulty,
|
||||
}), true);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -121,6 +121,11 @@ class Constants
|
|||
*/
|
||||
public static final DEFAULT_DIFFICULTY:String = 'normal';
|
||||
|
||||
/**
|
||||
* Default list of difficulties for charts.
|
||||
*/
|
||||
public static final DEFAULT_DIFFICULTY_LIST:Array<String> = ['easy', 'normal', 'hard'];
|
||||
|
||||
/**
|
||||
* Default player character for charts.
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue