half of multiple vocals support
This commit is contained in:
@@ -1,3 +0,0 @@
|
||||
function onPlayerHit(event) {
|
||||
trace(event.noteType);
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
function onPlayerHit(event) {
|
||||
trace(event.noteType);
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
function onPlayerHit(event) {
|
||||
trace(event.noteType);
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
function onPlayerHit(event) {
|
||||
trace(event.noteType);
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
function onPlayerHit(event) {
|
||||
trace(event.noteType);
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
function onPlayerHit(event) {
|
||||
trace(event.noteType);
|
||||
trace(SONG.noteTypes);
|
||||
}
|
||||
@@ -78,16 +78,16 @@ class Paths
|
||||
inline static public function music(key:String, ?library:String)
|
||||
return getPath('music/$key.$SOUND_EXT', library);
|
||||
|
||||
inline static public function voices(song:String, difficulty:String = "normal")
|
||||
inline static public function voices(song:String, difficulty:String = "normal", ?prefix:String = "")
|
||||
{
|
||||
var diff = getPath('songs/${song.toLowerCase()}/song/Voices-${difficulty.toLowerCase()}.$SOUND_EXT', null);
|
||||
return OpenFlAssets.exists(diff) ? diff : getPath('songs/${song.toLowerCase()}/song/Voices.$SOUND_EXT', null);
|
||||
var diff = getPath('songs/${song.toLowerCase()}/song/Voices$prefix-${difficulty.toLowerCase()}.$SOUND_EXT', null);
|
||||
return OpenFlAssets.exists(diff) ? diff : getPath('songs/${song.toLowerCase()}/song/Voices$prefix.$SOUND_EXT', null);
|
||||
}
|
||||
|
||||
inline static public function inst(song:String, difficulty:String = "normal")
|
||||
inline static public function inst(song:String, difficulty:String = "normal", ?prefix:String = "")
|
||||
{
|
||||
var diff = getPath('songs/${song.toLowerCase()}/song/Inst-${difficulty.toLowerCase()}.$SOUND_EXT', null);
|
||||
return OpenFlAssets.exists(diff) ? diff : getPath('songs/${song.toLowerCase()}/song/Inst.$SOUND_EXT', null);
|
||||
var diff = getPath('songs/${song.toLowerCase()}/song/Inst$prefix-${difficulty.toLowerCase()}.$SOUND_EXT', null);
|
||||
return OpenFlAssets.exists(diff) ? diff : getPath('songs/${song.toLowerCase()}/song/Inst$prefix.$SOUND_EXT', null);
|
||||
}
|
||||
|
||||
static public function image(key:String, ?library:String, checkForAtlas:Bool = false)
|
||||
|
||||
@@ -40,6 +40,7 @@ typedef ChartStrumLine = {
|
||||
var ?strumPos:Array<Float>;
|
||||
var ?strumScale:Float;
|
||||
var ?scrollSpeed:Float;
|
||||
var ?vocalsSuffix:String;
|
||||
|
||||
var ?strumLinePos:Float; // Backwards compatability
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ import funkin.editors.ui.UIState;
|
||||
import openfl.net.FileReference;
|
||||
|
||||
class Charter extends UIState {
|
||||
static var __song:String;
|
||||
public static var __song:String;
|
||||
static var __diff:String;
|
||||
static var __reload:Bool;
|
||||
|
||||
@@ -1444,6 +1444,8 @@ typedef SelectionDragChange = {
|
||||
class CharterNoteTypeButton extends UIButton {
|
||||
public var theType:String;
|
||||
public var textBox:UIAutoCompleteTextBox;
|
||||
public var deleteButton:UIButton;
|
||||
public var deleteIcon:FlxSprite;
|
||||
public function new(type:String, parent:UIButtonList<CharterNoteTypeButton>, state:Charter, suggestList:Array<String>) {
|
||||
theType = type;
|
||||
super(0,0,"" ,function() {
|
||||
@@ -1452,7 +1454,7 @@ class CharterNoteTypeButton extends UIButton {
|
||||
i.alpha = i == this ? 1 : 0.25;
|
||||
},296,30);
|
||||
if (suggestList != null && suggestList.length > 0) {
|
||||
members.push(textBox = new UIAutoCompleteTextBox((bWidth - 200) / 2, y + 4, theType, 200, bHeight - 8));
|
||||
members.push(textBox = new UIAutoCompleteTextBox((bWidth - 218) / 2, y + 4, theType, 200, bHeight - 8));
|
||||
textBox.suggestItems = suggestList;
|
||||
textBox.antialiasing = true;
|
||||
textBox.onChange = function(typer:String) {
|
||||
@@ -1464,13 +1466,29 @@ class CharterNoteTypeButton extends UIButton {
|
||||
if (state.curNoteType == theType) state.curNoteType = typer;
|
||||
theType = typer;
|
||||
}
|
||||
|
||||
deleteButton = new UIButton(textBox.x + 204, bHeight/2 - (28/2), "", function () {
|
||||
parent.remove(this);
|
||||
}, 28, 28);
|
||||
deleteButton.color = 0xFFFF0000;
|
||||
deleteButton.autoAlpha = false;
|
||||
members.push(deleteButton);
|
||||
|
||||
deleteIcon = new FlxSprite(deleteButton.x + (14/2), deleteButton.y + 5).loadGraphic(Paths.image('editors/character/delete-button'));
|
||||
deleteIcon.antialiasing = false;
|
||||
members.push(deleteIcon);
|
||||
}
|
||||
else field.text = type;
|
||||
autoAlpha = false;
|
||||
|
||||
}
|
||||
override function update(elapsed) {
|
||||
super.update(elapsed);
|
||||
if (textBox != null) textBox.y = y + 4;
|
||||
if (deleteButton != null) {
|
||||
deleteButton.y = y + bHeight / 2 - deleteButton.bHeight / 2;
|
||||
deleteIcon.x = deleteButton.x + (14/2); deleteIcon.y = deleteButton.y + 5;
|
||||
}
|
||||
//x = alpha == 0.25 ? -50 : 10;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ class CharterStrumlineScreen extends UISubstateWindow {
|
||||
|
||||
public var charactersList:UIButtonList<CharacterButton>;
|
||||
public var typeDropdown:UIDropDown;
|
||||
public var vocalsSuffixDropDown:UIDropDown;
|
||||
public var stagePositionDropdown:UIDropDown;
|
||||
public var hudScaleStepper:UINumericStepper;
|
||||
public var hudXStepper:UINumericStepper;
|
||||
@@ -135,6 +136,25 @@ class CharterStrumlineScreen extends UISubstateWindow {
|
||||
}, 125);
|
||||
add(closeButton);
|
||||
closeButton.color = 0xFFFF0000;
|
||||
|
||||
var suffixlist = ["NONE"];
|
||||
for (i in Paths.getFolderContent('songs/${Charter.__song.toLowerCase()}/song'))
|
||||
if (i.startsWith("Voices")) {
|
||||
i = haxe.io.Path.withoutExtension(i.substr("Voices".length));
|
||||
if (i == "") continue;
|
||||
for (j in PlayState.SONG.meta.difficulties) {
|
||||
if (i.endsWith('-${j.toLowerCase()}')) {
|
||||
if (suffixlist.contains(i.substring(0, i.length - j.length))) continue;
|
||||
else suffixlist.push(i.substring(0, i.length - j.length));
|
||||
}
|
||||
else if (!suffixlist.contains(i)) suffixlist.push(i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
vocalsSuffixDropDown = new UIDropDown(typeDropdown.x, hudScaleStepper.y + 128, 200, 32, suffixlist, suffixlist.indexOf(strumLine.vocalsSuffix));
|
||||
add(vocalsSuffixDropDown);
|
||||
addLabelOn(vocalsSuffixDropDown, "Vocal Suffix");
|
||||
}
|
||||
|
||||
function saveStrumline() {
|
||||
@@ -152,7 +172,8 @@ class CharterStrumlineScreen extends UISubstateWindow {
|
||||
visible: strumLine.visible,
|
||||
strumPos: [0, hudYStepper.value],
|
||||
strumLinePos: hudXStepper.value,
|
||||
strumScale: hudScaleStepper.value
|
||||
strumScale: hudScaleStepper.value,
|
||||
vocalsSuffix: vocalsSuffixDropDown.options[vocalsSuffixDropDown.index] != "NONE" ? vocalsSuffixDropDown.options[vocalsSuffixDropDown.index] : ""
|
||||
};
|
||||
if(!usesChartscrollSpeed.checked) newStrumLine.scrollSpeed = scrollSpeedStepper.value;
|
||||
if (onSave != null) onSave(newStrumLine);
|
||||
|
||||
@@ -633,16 +633,17 @@ class PlayState extends MusicBeatState
|
||||
var startingPos:FlxPoint = strumLine.strumPos == null ?
|
||||
FlxPoint.get((FlxG.width * strOffset) - ((Note.swagWidth * (strumLine.strumScale == null ? 1 : strumLine.strumScale)) * 2), this.strumLine.y) :
|
||||
FlxPoint.get(strumLine.strumPos[0] == 0 ? ((FlxG.width * strOffset) - ((Note.swagWidth * (strumLine.strumScale == null ? 1 : strumLine.strumScale)) * 2)) : strumLine.strumPos[0], strumLine.strumPos[1]);
|
||||
|
||||
var strLine = new StrumLine(chars,
|
||||
startingPos,
|
||||
strumLine.strumScale == null ? 1 : strumLine.strumScale,
|
||||
strumLine.type == 2 || (!coopMode && !((strumLine.type == 1 && !opponentMode) || (strumLine.type == 0 && opponentMode))),
|
||||
strumLine.type != 1, coopMode ? (strumLine.type == 1 ? controlsP1 : controlsP2) : controls
|
||||
strumLine.type != 1, coopMode ? (strumLine.type == 1 ? controlsP1 : controlsP2) : controls,
|
||||
strumLine.vocalsSuffix
|
||||
);
|
||||
strLine.cameras = [camHUD];
|
||||
strLine.data = strumLine;
|
||||
strLine.visible = (strumLine.visible != false);
|
||||
strLine.vocals.group = FlxG.sound.defaultMusicGroup;
|
||||
strLine.ID = i;
|
||||
strumLines.add(strLine);
|
||||
}
|
||||
@@ -890,7 +891,15 @@ class PlayState extends MusicBeatState
|
||||
|
||||
vocals.pause();
|
||||
inst.pause();
|
||||
for (strumLine in strumLines.members) {
|
||||
strumLine.vocals.play();
|
||||
strumLine.vocals.pause();
|
||||
}
|
||||
inst.time = vocals.time = (chartingMode && Charter.startHere) ? Charter.startTime : 0;
|
||||
for (strumLine in strumLines.members) {
|
||||
strumLine.vocals.time = vocals.time;
|
||||
strumLine.vocals.play();
|
||||
}
|
||||
vocals.play();
|
||||
inst.play();
|
||||
|
||||
@@ -903,6 +912,9 @@ class PlayState extends MusicBeatState
|
||||
scripts.call("destroy");
|
||||
for(g in __cachedGraphics)
|
||||
g.useCount--;
|
||||
@:privateAccess
|
||||
for (strumLine in strumLines.members)
|
||||
FlxG.sound.destroySound(strumLine.vocals);
|
||||
super.destroy();
|
||||
scripts = FlxDestroyUtil.destroy(scripts);
|
||||
@:privateAccess {
|
||||
@@ -973,6 +985,7 @@ class PlayState extends MusicBeatState
|
||||
{
|
||||
if (FlxG.sound.music != null)
|
||||
{
|
||||
for (strumLine in strumLines.members) strumLine.vocals.pause();
|
||||
FlxG.sound.music.pause();
|
||||
vocals.pause();
|
||||
}
|
||||
@@ -1031,6 +1044,7 @@ class PlayState extends MusicBeatState
|
||||
override public function onFocusLost():Void
|
||||
{
|
||||
if (!paused && FlxG.autoPause) {
|
||||
for (strumLine in strumLines.members) strumLine.vocals.pause();
|
||||
inst.pause();
|
||||
vocals.pause();
|
||||
}
|
||||
@@ -1043,10 +1057,15 @@ class PlayState extends MusicBeatState
|
||||
function resyncVocals():Void
|
||||
{
|
||||
vocals.pause();
|
||||
for (strumLine in strumLines.members) strumLine.vocals.pause();
|
||||
|
||||
FlxG.sound.music.play();
|
||||
Conductor.songPosition = FlxG.sound.music.time;
|
||||
vocals.time = Conductor.songPosition + Conductor.songOffset;
|
||||
for (strumLine in strumLines.members) {
|
||||
strumLine.vocals.time = vocals.time;
|
||||
strumLine.vocals.play();
|
||||
}
|
||||
vocals.play();
|
||||
scripts.call("onVocalsResync");
|
||||
}
|
||||
@@ -1139,7 +1158,9 @@ class PlayState extends MusicBeatState
|
||||
startSong();
|
||||
}
|
||||
} else {
|
||||
__vocalOffsetViolation = Math.max(0, __vocalOffsetViolation + (FlxG.sound.music.time != vocals.time ? elapsed : -elapsed / 2));
|
||||
var instTime = FlxG.sound.music.time;
|
||||
var isOffsync = vocals.time != instTime || [for(strumLine in strumLines.members) strumLine.vocals.time != instTime].contains(true);
|
||||
__vocalOffsetViolation = Math.max(0, __vocalOffsetViolation + (isOffsync ? elapsed : -elapsed / 2));
|
||||
if (__vocalOffsetViolation > 25) {
|
||||
resyncVocals();
|
||||
__vocalOffsetViolation = 0;
|
||||
@@ -1267,6 +1288,7 @@ class PlayState extends MusicBeatState
|
||||
vocals.stop();
|
||||
if (FlxG.sound.music != null)
|
||||
FlxG.sound.music.stop();
|
||||
for (strumLine in strumLines.members) strumLine.vocals.stop();
|
||||
|
||||
openSubState(new GameOverSubstate(event.x, event.y, event.deathCharID, event.isPlayer, event.gameOverSong, event.lossSFX, event.retrySFX));
|
||||
|
||||
@@ -1282,6 +1304,10 @@ class PlayState extends MusicBeatState
|
||||
canPause = false;
|
||||
inst.volume = 0;
|
||||
vocals.volume = 0;
|
||||
for (strumLine in strumLines.members) {
|
||||
strumLine.vocals.volume = 0;
|
||||
strumLine.vocals.pause();
|
||||
}
|
||||
inst.pause();
|
||||
vocals.pause();
|
||||
|
||||
@@ -1409,7 +1435,10 @@ class PlayState extends MusicBeatState
|
||||
|
||||
if (event.playMissSound) FlxG.sound.play(event.missSound, event.missVolume);
|
||||
|
||||
if (event.muteVocals) vocals.volume = 0;
|
||||
if (event.muteVocals) {
|
||||
vocals.volume = 0;
|
||||
strumLine.vocals.volume = 0;
|
||||
}
|
||||
|
||||
if (event.accuracy != null) {
|
||||
accuracyPressedNotes++;
|
||||
@@ -1512,7 +1541,10 @@ class PlayState extends MusicBeatState
|
||||
}
|
||||
}
|
||||
|
||||
if (event.unmuteVocals) vocals.volume = 1;
|
||||
if (event.unmuteVocals) {
|
||||
vocals.volume = 1;
|
||||
strumLine.vocals.volume = 1;
|
||||
}
|
||||
if (event.enableCamZooming) camZooming = true;
|
||||
if (event.autoHitLastSustain) {
|
||||
if (note.nextSustain != null && note.nextSustain.nextSustain == null) {
|
||||
|
||||
@@ -8,6 +8,7 @@ import funkin.backend.system.Conductor;
|
||||
import funkin.backend.chart.ChartData;
|
||||
import funkin.backend.system.Controls;
|
||||
import flixel.tweens.FlxTween;
|
||||
import flixel.sound.FlxSound;
|
||||
|
||||
class StrumLine extends FlxTypedGroup<Strum> {
|
||||
/**
|
||||
@@ -74,6 +75,10 @@ class StrumLine extends FlxTypedGroup<Strum> {
|
||||
* TODO: Write documention about this being a variable that can help when making multi key
|
||||
*/
|
||||
public var strumAnimPrefix = ["left", "down", "up", "right"];
|
||||
/**
|
||||
* Vocals sound (Vocals.ogg). Used for individual vocals per strumline.
|
||||
*/
|
||||
public var vocals:FlxSound;
|
||||
|
||||
public var extra:Map<String, Dynamic> = [];
|
||||
|
||||
@@ -89,7 +94,7 @@ class StrumLine extends FlxTypedGroup<Strum> {
|
||||
private var startingPos:FlxPoint = FlxPoint.get(0,0);
|
||||
private var strumScale:Float = 1;
|
||||
|
||||
public function new(characters:Array<Character>, startingPos:FlxPoint, strumScale:Float, cpu:Bool = false, opponentSide:Bool = true, ?controls:Controls) {
|
||||
public function new(characters:Array<Character>, startingPos:FlxPoint, strumScale:Float, cpu:Bool = false, opponentSide:Bool = true, ?controls:Controls, ?vocalPrefix:String = "") {
|
||||
super();
|
||||
this.characters = characters;
|
||||
this.startingPos = startingPos;
|
||||
@@ -98,6 +103,8 @@ class StrumLine extends FlxTypedGroup<Strum> {
|
||||
this.opponentSide = opponentSide;
|
||||
this.controls = controls;
|
||||
this.notes = new NoteGroup();
|
||||
vocals = vocalPrefix != "" ? FlxG.sound.load(Paths.voices(PlayState.SONG.meta.name, PlayState.difficulty, vocalPrefix)) : new FlxSound();
|
||||
vocals.persist = false;
|
||||
}
|
||||
|
||||
public function generate(strumLine:ChartStrumLine, ?startTime:Float) {
|
||||
|
||||
Reference in New Issue
Block a user