diff --git a/assets/data/dialogue/characters/pixelBf.xml b/assets/data/dialogue/characters/pixelBf.xml index 5292d4de..1c071bb5 100644 --- a/assets/data/dialogue/characters/pixelBf.xml +++ b/assets/data/dialogue/characters/pixelBf.xml @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/assets/data/dialogue/characters/senpai.xml b/assets/data/dialogue/characters/senpai.xml index ffe5d244..855deb12 100644 --- a/assets/data/dialogue/characters/senpai.xml +++ b/assets/data/dialogue/characters/senpai.xml @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/assets/songs/roses/dialogue.xml b/assets/songs/roses/dialogue.xml index 904cf803..9995b7c3 100644 --- a/assets/songs/roses/dialogue.xml +++ b/assets/songs/roses/dialogue.xml @@ -5,7 +5,7 @@ - + Not bad for an ugly worm. diff --git a/assets/songs/senpai/dialogue.xml b/assets/songs/senpai/dialogue.xml index 5a0115c4..615c4f96 100644 --- a/assets/songs/senpai/dialogue.xml +++ b/assets/songs/senpai/dialogue.xml @@ -5,7 +5,7 @@ - + Ah, a new fair maiden has come in search of true love! diff --git a/assets/songs/thorns/creepyDialogue.xml b/assets/songs/thorns/creepyDialogue.xml index 75ee0d15..629eb492 100644 --- a/assets/songs/thorns/creepyDialogue.xml +++ b/assets/songs/thorns/creepyDialogue.xml @@ -4,7 +4,7 @@ - + Direct contact with real humans, after being trapped in here for so long... diff --git a/assets/sounds/ANGRY_TEXT_BOX.mp3 b/assets/sounds/pixel/ANGRY_TEXT_BOX.mp3 similarity index 100% rename from assets/sounds/ANGRY_TEXT_BOX.mp3 rename to assets/sounds/pixel/ANGRY_TEXT_BOX.mp3 diff --git a/assets/sounds/ANGRY_TEXT_BOX.ogg b/assets/sounds/pixel/ANGRY_TEXT_BOX.ogg similarity index 100% rename from assets/sounds/ANGRY_TEXT_BOX.ogg rename to assets/sounds/pixel/ANGRY_TEXT_BOX.ogg diff --git a/assets/sounds/pixel/type.mp3 b/assets/sounds/pixel/type.mp3 new file mode 100644 index 00000000..b7c76d21 Binary files /dev/null and b/assets/sounds/pixel/type.mp3 differ diff --git a/assets/sounds/pixel/type.wav b/assets/sounds/pixel/type.wav deleted file mode 100644 index f2cb831a..00000000 Binary files a/assets/sounds/pixel/type.wav and /dev/null differ diff --git a/source/funkin/game/cutscenes/DialogueCutscene.hx b/source/funkin/game/cutscenes/DialogueCutscene.hx index 6bb1d6a3..210bae26 100644 --- a/source/funkin/game/cutscenes/DialogueCutscene.hx +++ b/source/funkin/game/cutscenes/DialogueCutscene.hx @@ -17,8 +17,8 @@ class DialogueCutscene extends Cutscene { public var curLine:DialogueLine = null; public var dialogueBox:DialogueBox; - public var nextSFX:FlxSound; public var dialogueCamera:FlxCamera; + public var curMusic:FlxSound = null; public function new(dialoguePath:String, callback:Void->Void) { super(callback); @@ -42,22 +42,38 @@ class DialogueCutscene extends Cutscene { add(charMap[char.att.name] = new DialogueCharacter(char.att.name, char.getAtt('position').getDefault('default'))); } + var useDef:Bool = false; + if(dialogueData.has.forceBoxDefaultTxtSound && dialogueData.att.forceBoxDefaultTxtSound == "true") + useDef = true; + // Add lines for(node in dialogueData.nodes.line) { - dialogueLines.push({ + var line:DialogueLine = { text: XMLUtil.fixXMLText(node.innerHTML), char: node.getAtt('char').getDefault('boyfriend'), bubble: node.getAtt('bubble').getDefault('normal'), callback: node.getAtt('callback'), - speed: node.has.speed ? Std.parseFloat(node.att.speed).getDefault(0.05) : 0.05 - }); + speed: node.has.speed ? Std.parseFloat(node.att.speed).getDefault(0.05) : 0.05, + changeMusic: node.has.changeMusic ? FlxG.sound.load(Paths.music(node.getAtt('changeMusic')), 0.8, true) : null, + playSound: node.has.playSound ? FlxG.sound.load(Paths.sound(node.getAtt('playSound'))) : null, + nextSound: node.has.nextSound ? FlxG.sound.load(Paths.music(node.getAtt('nextSound'))) : null, + textSound: null + }; + + if(node.has.textSound) line.textSound = FlxG.sound.load(Paths.sound(node.getAtt('textSound'))); + else if(!useDef) { + var char:DialogueCharacter = charMap[line.char]; + if(char != null && char.charData != null && char.charData.has.textSound) + line.textSound = FlxG.sound.load(Paths.sound(char.charData.getAtt("textSound"))); + } + + dialogueLines.push(line); } // Add dialogue box dialogueBox = new DialogueBox(dialogueData.getAtt("box").getDefault("default")); add(dialogueBox); add(dialogueBox.text); - next(); } catch(e) { @@ -84,10 +100,19 @@ class DialogueCutscene extends Cutscene { if (charMap[curLine.char] != null) dialogueBox.popupChar(charMap[curLine.char]); - dialogueBox.playBubbleAnim(curLine.bubble, curLine.text, curLine.speed); + dialogueBox.playBubbleAnim(curLine.bubble, curLine.text, curLine.speed, curLine.nextSound, curLine.textSound != null ? [curLine.textSound] : null); + + if(curLine.playSound != null) curLine.playSound.play(); + if(curLine.changeMusic != null) { + if(curMusic != null) curMusic.destroy(); + curMusic = curLine.changeMusic; + curMusic.play(); + curMusic.fadeIn(1, 0, curMusic.volume); + } } public override function destroy() { + if(curMusic != null) curMusic.destroy(); super.destroy(); FlxG.cameras.remove(dialogueCamera); } @@ -99,4 +124,8 @@ typedef DialogueLine = { var bubble:String; var callback:String; var speed:Float; + var changeMusic:FlxSound; + var playSound:FlxSound; + var nextSound:FlxSound; + var textSound:FlxSound; } \ No newline at end of file diff --git a/source/funkin/game/cutscenes/dialogue/DialogueBox.hx b/source/funkin/game/cutscenes/dialogue/DialogueBox.hx index 4604b353..4502f9e9 100644 --- a/source/funkin/game/cutscenes/dialogue/DialogueBox.hx +++ b/source/funkin/game/cutscenes/dialogue/DialogueBox.hx @@ -1,5 +1,6 @@ package funkin.game.cutscenes.dialogue; +import flixel.sound.FlxSound; import flixel.addons.text.FlxTypeText; import flixel.text.FlxText; import flixel.math.FlxPoint; @@ -10,13 +11,15 @@ class DialogueBox extends FunkinSprite { public var positions:Map = []; public var everPlayedAny:Bool = false; - public var textTypeSFX:String = Paths.sound('dialogue/text'); public var nextSFX:String = Paths.sound('dialogue/next'); + public var defaultTextTypeSFX:Array; public var text:FlxTypeText; public function new(name:String) { super(); + var textTypeSFX:String = Paths.sound('dialogue/text'); + try { dialogueBoxData = new Access(Xml.parse(Assets.getText(Paths.xml('dialogue/boxes/$name'))).firstElement()); if(!dialogueBoxData.has.sprite) dialogueBoxData.x.set("sprite", name); @@ -31,9 +34,10 @@ class DialogueBox extends FunkinSprite { if(dialogueBoxData.has.nextSound) nextSFX = Paths.sound(dialogueBoxData.att.nextSound); animation.finishCallback = (name:String) -> { - if(name.endsWith("-open") || name.endsWith("-firstOpen")) { - playAnim(name.substr(0, name.length - 5)); - setText(__nextText, __speed); + var finalPt:String; + if(name.endsWith(finalPt = "-open") || name.endsWith(finalPt = "-firstOpen")) { + playAnim(name.substr(0, name.length - finalPt.length)); + setText(__nextText, __speed, __customTypeSFX); } } @@ -57,7 +61,6 @@ class DialogueBox extends FunkinSprite { text.size = Std.parseInt(textNode.att.size).getDefault(20); text.font = Paths.font('${textNode.getAtt("font").getDefault("vcr.ttf")}'); text.antialiasing = textNode.getAtt("antialiasing").getDefault("false") == "true"; - text.sounds = [FlxG.sound.load(textTypeSFX)]; if(textNode.has.borderStyle) { text.borderStyle = switch(textNode.att.borderStyle.trim().toLowerCase()) { case "none": NONE; @@ -72,8 +75,8 @@ class DialogueBox extends FunkinSprite { active = false; Logs.trace('Couldn\'t load dialogue box "$name": ${e.toString()}', ERROR); } + defaultTextTypeSFX = [FlxG.sound.load(textTypeSFX)]; FlxG.sound.cache(nextSFX); - FlxG.sound.cache(textTypeSFX); } public function popupChar(char:DialogueCharacter) { @@ -86,22 +89,25 @@ class DialogueBox extends FunkinSprite { private var __nextText:String; private var __speed:Float; - public function playBubbleAnim(bubble:String, text:String, speed:Float = 0.05) { + private var __customTypeSFX:Array; + public function playBubbleAnim(bubble:String, text:String, speed:Float = 0.05, ?customSFX:FlxSound, ?customTypeSFX:Array, ?playNext:Bool) { this.__nextText = text; this.__speed = speed; + this.__customTypeSFX = customTypeSFX; this.text.resetText(text); - FlxG.sound.play(nextSFX); + if(playNext || (playNext == null && everPlayedAny)) customSFX != null ? customSFX.play() : FlxG.sound.play(nextSFX); if(hasAnimation('$bubble-open')) playAnim('$bubble-open', true); else if(hasAnimation('$bubble-firstOpen') && !everPlayedAny) playAnim('$bubble-firstOpen', true); else { playAnim(bubble); - setText(__nextText, __speed); + setText(__nextText, __speed, __customTypeSFX); } visible = true; everPlayedAny = true; } - public function setText(text:String, speed:Float = 0.02) { + public function setText(text:String, speed:Float = 0.02, ?customTypeSFX:Array) { + this.text.sounds = customTypeSFX != null ? customTypeSFX : defaultTextTypeSFX; this.text.delay = speed; this.text.start(speed, true); }