From 398b61a824e6a13bee4059767b0b114d78c23330 Mon Sep 17 00:00:00 2001 From: Frakist <90983918+Frakist@users.noreply.github.com> Date: Fri, 3 Nov 2023 00:39:07 +0300 Subject: [PATCH] half of multiple vocals support --- assets/data/notes/Dodge_Note copy 2.hx | 3 -- assets/data/notes/Dodge_Note copy 3.hx | 3 -- assets/data/notes/Dodge_Note copy 4.hx | 3 -- assets/data/notes/Dodge_Note copy 5.hx | 3 -- assets/data/notes/Dodge_Note copy.hx | 3 -- assets/data/notes/Dodge_Note.hx | 4 -- source/funkin/backend/assets/Paths.hx | 12 +++--- source/funkin/backend/chart/ChartData.hx | 1 + source/funkin/editors/charter/Charter.hx | 22 +++++++++- .../editors/charter/CharterStrumlineScreen.hx | 23 +++++++++- source/funkin/game/PlayState.hx | 42 ++++++++++++++++--- source/funkin/game/StrumLine.hx | 9 +++- 12 files changed, 94 insertions(+), 34 deletions(-) delete mode 100644 assets/data/notes/Dodge_Note copy 2.hx delete mode 100644 assets/data/notes/Dodge_Note copy 3.hx delete mode 100644 assets/data/notes/Dodge_Note copy 4.hx delete mode 100644 assets/data/notes/Dodge_Note copy 5.hx delete mode 100644 assets/data/notes/Dodge_Note copy.hx delete mode 100644 assets/data/notes/Dodge_Note.hx diff --git a/assets/data/notes/Dodge_Note copy 2.hx b/assets/data/notes/Dodge_Note copy 2.hx deleted file mode 100644 index fd73eb8d..00000000 --- a/assets/data/notes/Dodge_Note copy 2.hx +++ /dev/null @@ -1,3 +0,0 @@ -function onPlayerHit(event) { - trace(event.noteType); -} \ No newline at end of file diff --git a/assets/data/notes/Dodge_Note copy 3.hx b/assets/data/notes/Dodge_Note copy 3.hx deleted file mode 100644 index fd73eb8d..00000000 --- a/assets/data/notes/Dodge_Note copy 3.hx +++ /dev/null @@ -1,3 +0,0 @@ -function onPlayerHit(event) { - trace(event.noteType); -} \ No newline at end of file diff --git a/assets/data/notes/Dodge_Note copy 4.hx b/assets/data/notes/Dodge_Note copy 4.hx deleted file mode 100644 index fd73eb8d..00000000 --- a/assets/data/notes/Dodge_Note copy 4.hx +++ /dev/null @@ -1,3 +0,0 @@ -function onPlayerHit(event) { - trace(event.noteType); -} \ No newline at end of file diff --git a/assets/data/notes/Dodge_Note copy 5.hx b/assets/data/notes/Dodge_Note copy 5.hx deleted file mode 100644 index fd73eb8d..00000000 --- a/assets/data/notes/Dodge_Note copy 5.hx +++ /dev/null @@ -1,3 +0,0 @@ -function onPlayerHit(event) { - trace(event.noteType); -} \ No newline at end of file diff --git a/assets/data/notes/Dodge_Note copy.hx b/assets/data/notes/Dodge_Note copy.hx deleted file mode 100644 index fd73eb8d..00000000 --- a/assets/data/notes/Dodge_Note copy.hx +++ /dev/null @@ -1,3 +0,0 @@ -function onPlayerHit(event) { - trace(event.noteType); -} \ No newline at end of file diff --git a/assets/data/notes/Dodge_Note.hx b/assets/data/notes/Dodge_Note.hx deleted file mode 100644 index 7bd7dc64..00000000 --- a/assets/data/notes/Dodge_Note.hx +++ /dev/null @@ -1,4 +0,0 @@ -function onPlayerHit(event) { - trace(event.noteType); - trace(SONG.noteTypes); -} \ No newline at end of file diff --git a/source/funkin/backend/assets/Paths.hx b/source/funkin/backend/assets/Paths.hx index 495d5577..cb51cdce 100644 --- a/source/funkin/backend/assets/Paths.hx +++ b/source/funkin/backend/assets/Paths.hx @@ -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) diff --git a/source/funkin/backend/chart/ChartData.hx b/source/funkin/backend/chart/ChartData.hx index c142c2a1..8bbbd60c 100644 --- a/source/funkin/backend/chart/ChartData.hx +++ b/source/funkin/backend/chart/ChartData.hx @@ -40,6 +40,7 @@ typedef ChartStrumLine = { var ?strumPos:Array; var ?strumScale:Float; var ?scrollSpeed:Float; + var ?vocalsSuffix:String; var ?strumLinePos:Float; // Backwards compatability } diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index d2f19762..70859f59 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -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, state:Charter, suggestList:Array) { 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; } } diff --git a/source/funkin/editors/charter/CharterStrumlineScreen.hx b/source/funkin/editors/charter/CharterStrumlineScreen.hx index 364c5ad8..972afa8f 100644 --- a/source/funkin/editors/charter/CharterStrumlineScreen.hx +++ b/source/funkin/editors/charter/CharterStrumlineScreen.hx @@ -12,6 +12,7 @@ class CharterStrumlineScreen extends UISubstateWindow { public var charactersList:UIButtonList; 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); diff --git a/source/funkin/game/PlayState.hx b/source/funkin/game/PlayState.hx index 2d3a28bd..4462c36f 100644 --- a/source/funkin/game/PlayState.hx +++ b/source/funkin/game/PlayState.hx @@ -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) { diff --git a/source/funkin/game/StrumLine.hx b/source/funkin/game/StrumLine.hx index 7b951dd0..ec8060c9 100644 --- a/source/funkin/game/StrumLine.hx +++ b/source/funkin/game/StrumLine.hx @@ -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 { /** @@ -74,6 +75,10 @@ class StrumLine extends FlxTypedGroup { * 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 = []; @@ -89,7 +94,7 @@ class StrumLine extends FlxTypedGroup { private var startingPos:FlxPoint = FlxPoint.get(0,0); private var strumScale:Float = 1; - public function new(characters:Array, startingPos:FlxPoint, strumScale:Float, cpu:Bool = false, opponentSide:Bool = true, ?controls:Controls) { + public function new(characters:Array, 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 { 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) {