Merge branch 'main' of https://github.com/FNF-CNE-Devs/CodenameEngine-Dev
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
<!DOCTYPE codename-engine-dialogue-box>
|
<!DOCTYPE codename-engine-dialogue-box>
|
||||||
<dialoguebox scale="0.9" y="75">
|
<dialoguebox y="75">
|
||||||
<!--
|
<!--
|
||||||
Node containing all text settings
|
Node containing all text settings
|
||||||
-->
|
-->
|
||||||
<text font="vcr.ttf" x="107" y="206" width="1053" color="#000000" size="40"/>
|
<text font="vcr.ttf" x="107" y="206" width="1053" color="#000000" size="40"/>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
<!--
|
<!--
|
||||||
All animations for the dialogue box
|
All animations for the dialogue box
|
||||||
For example, if you wanna add an "angry" animation, add an animation named "angry" (box idle), and "angry-open" (not needed, for box apparition)
|
For example, if you wanna add an "angry" animation, add an animation named "angry" (box idle), and "angry-open" (not needed, for box apparition)
|
||||||
-->
|
-->
|
||||||
<anim name="normal" anim="speech bubble normal" fps="24" loop="true" x="-30"/>
|
<anim name="normal" anim="speech bubble normal" fps="24" loop="true" x="-30"/>
|
||||||
<anim name="normal-open" anim="Speech Bubble Normal Open" fps="24" />
|
<anim name="normal-open" anim="Speech Bubble Normal Open" fps="24" />
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<!DOCTYPE codename-engine-dialogue-box>
|
||||||
|
<dialoguebox sprite="pixel/dialogueBox" antialiasing="false" graphicSizex="1344" x="20" y="-215" textSound="pixel/pixelText" nextSound="pixel/clickText">
|
||||||
|
<!--
|
||||||
|
Node containing all text settings
|
||||||
|
-->
|
||||||
|
<text font="pixel.otf" x="242" y="218" width="768" color="#3f2021" size="32" antialiasing="false" borderSize="2" borderStyle="shadow" borderColor="#D89494" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
All positions for characters
|
||||||
|
-->
|
||||||
|
<charpos name="left" x="-500" y="184" />
|
||||||
|
<charpos name="middle" x="0" y="184" />
|
||||||
|
<charpos name="right" x="500" y="184" flipBubble="true" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
All animations for the dialogue box
|
||||||
|
For example, if you wanna add an "angry" animation, add an animation named "angry" (box idle), and "angry-open" (not needed, for box apparition)
|
||||||
|
-->
|
||||||
|
<anim name="normal" anim="Text Box Appear instance 10004" fps="24" loop="true" />
|
||||||
|
<anim name="normal-firstOpen" anim="Text Box Appear instance 10" fps="24" />
|
||||||
|
</dialoguebox>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<!DOCTYPE codename-engine-dialogue-character>
|
||||||
|
<character sprite="pixel/boyfriend" x="570" y="-599" graphicSizex="1334" antialiasing="false" >
|
||||||
|
<anim name="show" anim="Boyfriend portrait enter instance 10" fps="24" />
|
||||||
|
</character>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<!DOCTYPE codename-engine-dialogue-character>
|
||||||
|
<character sprite="pixel/senpai" x="-392" y="-599" graphicSizex="1334" antialiasing="false" >
|
||||||
|
<anim name="show" anim="Senpai Portrait Enter instance 10" fps="24" />
|
||||||
|
</character>
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 5.7 KiB |
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
Created with Funkin Packer v0.1.3 https://neeeoo.github.io/funkin-packer/
|
||||||
|
-->
|
||||||
|
<TextureAtlas imagePath="dialogueBox.png" width="207" height="158">
|
||||||
|
<SubTexture name="Text Box Appear instance 10000" x="1" y="143" width="202" height="14" frameX="-22" frameY="-62" frameWidth="249" frameHeight="144"/>
|
||||||
|
<SubTexture name="Text Box Appear instance 10001" x="1" y="111" width="204" height="29" frameX="-22" frameY="-64" frameWidth="249" frameHeight="144"/>
|
||||||
|
<SubTexture name="Text Box Appear instance 10002" x="1" y="62" width="204" height="46" frameX="-22" frameY="-65" frameWidth="249" frameHeight="144"/>
|
||||||
|
<SubTexture name="Text Box Appear instance 10003" x="1" y="1" width="205" height="58" frameX="-22" frameY="-66" frameWidth="249" frameHeight="144"/>
|
||||||
|
<SubTexture name="Text Box Appear instance 10004" x="1" y="1" width="205" height="58" frameX="-22" frameY="-66" frameWidth="249" frameHeight="144"/>
|
||||||
|
</TextureAtlas>
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 6.5 KiB |
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
Created with Funkin Packer v0.1.3 https://neeeoo.github.io/funkin-packer/
|
||||||
|
-->
|
||||||
|
<TextureAtlas imagePath="boyfriend.png" width="243" height="47">
|
||||||
|
<SubTexture name="Boyfriend portrait enter instance 10000" x="1" y="1" width="58" height="45" frameX="-157" frameY="-30" frameWidth="249" frameHeight="145"/>
|
||||||
|
<SubTexture name="Boyfriend portrait enter instance 10001" x="62" y="1" width="58" height="45" frameX="-150" frameY="-30" frameWidth="249" frameHeight="145"/>
|
||||||
|
<SubTexture name="Boyfriend portrait enter instance 10002" x="62" y="1" width="58" height="45" frameX="-150" frameY="-30" frameWidth="249" frameHeight="145"/>
|
||||||
|
<SubTexture name="Boyfriend portrait enter instance 10003" x="123" y="1" width="58" height="45" frameX="-144" frameY="-30" frameWidth="249" frameHeight="145"/>
|
||||||
|
<SubTexture name="Boyfriend portrait enter instance 10004" x="123" y="1" width="58" height="45" frameX="-144" frameY="-30" frameWidth="249" frameHeight="145"/>
|
||||||
|
<SubTexture name="Boyfriend portrait enter instance 10005" x="184" y="1" width="58" height="45" frameX="-143" frameY="-30" frameWidth="249" frameHeight="145"/>
|
||||||
|
<SubTexture name="Boyfriend portrait enter instance 10006" x="184" y="1" width="58" height="45" frameX="-143" frameY="-30" frameWidth="249" frameHeight="145"/>
|
||||||
|
<SubTexture name="Boyfriend portrait enter instance 10007" x="184" y="1" width="58" height="45" frameX="-143" frameY="-30" frameWidth="249" frameHeight="145"/>
|
||||||
|
<SubTexture name="Boyfriend portrait enter instance 10008" x="184" y="1" width="58" height="45" frameX="-143" frameY="-30" frameWidth="249" frameHeight="145"/>
|
||||||
|
</TextureAtlas>
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 9.4 KiB |
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
Created with Funkin Packer v0.1.3 https://neeeoo.github.io/funkin-packer/
|
||||||
|
-->
|
||||||
|
<TextureAtlas imagePath="senpai.png" width="53" height="239">
|
||||||
|
<SubTexture name="Senpai Portrait Enter instance 10000" x="1" y="1" width="51" height="57" frameX="-38" frameY="-17" frameWidth="249" frameHeight="145"/>
|
||||||
|
<SubTexture name="Senpai Portrait Enter instance 10001" x="1" y="61" width="51" height="57" frameX="-45" frameY="-17" frameWidth="249" frameHeight="145"/>
|
||||||
|
<SubTexture name="Senpai Portrait Enter instance 10002" x="1" y="61" width="51" height="57" frameX="-45" frameY="-17" frameWidth="249" frameHeight="145"/>
|
||||||
|
<SubTexture name="Senpai Portrait Enter instance 10003" x="1" y="121" width="51" height="57" frameX="-48" frameY="-17" frameWidth="249" frameHeight="145"/>
|
||||||
|
<SubTexture name="Senpai Portrait Enter instance 10004" x="1" y="121" width="51" height="57" frameX="-48" frameY="-17" frameWidth="249" frameHeight="145"/>
|
||||||
|
<SubTexture name="Senpai Portrait Enter instance 10005" x="1" y="181" width="51" height="57" frameX="-49" frameY="-17" frameWidth="249" frameHeight="145"/>
|
||||||
|
<SubTexture name="Senpai Portrait Enter instance 10006" x="1" y="181" width="51" height="57" frameX="-49" frameY="-17" frameWidth="249" frameHeight="145"/>
|
||||||
|
<SubTexture name="Senpai Portrait Enter instance 10007" x="1" y="181" width="51" height="57" frameX="-49" frameY="-17" frameWidth="249" frameHeight="145"/>
|
||||||
|
<SubTexture name="Senpai Portrait Enter instance 10008" x="1" y="181" width="51" height="57" frameX="-49" frameY="-17" frameWidth="249" frameHeight="145"/>
|
||||||
|
</TextureAtlas>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<!DOCTYPE codename-engine-dialogue>
|
||||||
|
<dialogue box="senpai">
|
||||||
|
<!-- All characters -->
|
||||||
|
<char name="senpai" char="senpai" position="left" />
|
||||||
|
<char name="pixelBf" char="pixelBf" position="right" />
|
||||||
|
|
||||||
|
<!-- Lines -->
|
||||||
|
<line char="senpai">
|
||||||
|
Not bad for an ugly worm.
|
||||||
|
</line>
|
||||||
|
<line char="senpai">
|
||||||
|
But this time I'll rip your nuts off right after your girlfriend finishes gargling mine.
|
||||||
|
</line>
|
||||||
|
<line char="pixelBf">
|
||||||
|
Bop beep be be skdoo bep
|
||||||
|
</line>
|
||||||
|
</dialogue>
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
static var roses_shouldPlayOnThorns = false;
|
|
||||||
var self = this;
|
var self = this;
|
||||||
__script__.setParent(PlayState.instance);
|
__script__.setParent(PlayState.instance);
|
||||||
|
|
||||||
@@ -36,10 +35,7 @@ function create() {
|
|||||||
FlxG.camera.followLerp = 0;
|
FlxG.camera.followLerp = 0;
|
||||||
FlxTween.tween(camGame.scroll, {x: -366, y: 192}, 3, {
|
FlxTween.tween(camGame.scroll, {x: -366, y: 192}, 3, {
|
||||||
ease: FlxEase.cubeInOut,
|
ease: FlxEase.cubeInOut,
|
||||||
onComplete: (_) -> {
|
onComplete: (_) -> {self.close();}
|
||||||
roses_shouldPlayOnThorns = true;
|
|
||||||
self.close();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<!DOCTYPE codename-engine-dialogue>
|
||||||
|
<dialogue box="senpai">
|
||||||
|
<!-- All characters -->
|
||||||
|
<char name="senpai" char="senpai" position="left" />
|
||||||
|
<char name="pixelBf" char="pixelBf" position="right" />
|
||||||
|
|
||||||
|
<!-- Lines -->
|
||||||
|
<line char="senpai">
|
||||||
|
Ah, a new fair maiden has come in search of true love!
|
||||||
|
</line>
|
||||||
|
<line char="senpai">
|
||||||
|
A serenade between gentlemen shall decide where her beautiful heart shall reside.
|
||||||
|
</line>
|
||||||
|
<line char="pixelBf">
|
||||||
|
Beep bo bop
|
||||||
|
</line>
|
||||||
|
</dialogue>
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<!DOCTYPE codename-engine-dialogue>
|
||||||
|
<dialogue box="senpai">
|
||||||
|
<!-- All characters -->
|
||||||
|
<char name="senpai" char="senpai" position="left" />
|
||||||
|
|
||||||
|
<!-- Lines -->
|
||||||
|
<line char="senpai">
|
||||||
|
Direct contact with real humans, after being trapped in here for so long...
|
||||||
|
</line>
|
||||||
|
<line char="senpai">
|
||||||
|
and HER of all people.
|
||||||
|
</line>
|
||||||
|
<line char="senpai">
|
||||||
|
I'll make her father pay for what he's done to me and all the others,,,,
|
||||||
|
</line>
|
||||||
|
<line char="senpai">
|
||||||
|
I'll beat you and make you take my place.
|
||||||
|
</line>
|
||||||
|
<line char="senpai">
|
||||||
|
You don't mind your bodies being borrowed right? It's only fair...
|
||||||
|
</line>
|
||||||
|
</dialogue>
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import flixel.addons.util.FlxSimplex;
|
import flixel.addons.util.FlxSimplex;
|
||||||
|
|
||||||
static var roses_shouldPlayOnThorns = false;
|
|
||||||
var self = this;
|
var self = this;
|
||||||
__script__.setParent(PlayState.instance);
|
__script__.setParent(PlayState.instance);
|
||||||
|
|
||||||
@@ -9,13 +8,6 @@ var senpaiEvil:FlxSprite;
|
|||||||
var dfx = 0;
|
var dfx = 0;
|
||||||
var dfy = 0;
|
var dfy = 0;
|
||||||
function create() {
|
function create() {
|
||||||
// Cutscene stuff
|
|
||||||
if(!roses_shouldPlayOnThorns) {
|
|
||||||
disableScript();
|
|
||||||
self.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
roses_shouldPlayOnThorns = false;
|
|
||||||
camHUD.visible = false;
|
camHUD.visible = false;
|
||||||
|
|
||||||
var red:FlxSprite = new FlxSprite().makeSolid(FlxG.width + 100, FlxG.height + 100, 0xFFff1b31);
|
var red:FlxSprite = new FlxSprite().makeSolid(FlxG.width + 100, FlxG.height + 100, 0xFFff1b31);
|
||||||
@@ -64,7 +56,7 @@ function create() {
|
|||||||
white.destroy();
|
white.destroy();
|
||||||
|
|
||||||
camHUD.visible = true;
|
camHUD.visible = true;
|
||||||
self.close();
|
self.startDialogue("songs/" + PlayState.instance.SONG.meta.name.toLowerCase() + "/creepyDialogue.xml", self.close);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,10 +1,9 @@
|
|||||||
package funkin.backend.utils;
|
package funkin.backend.utils;
|
||||||
|
|
||||||
import flixel.animation.FlxAnimation;
|
|
||||||
import funkin.backend.FunkinSprite;
|
import funkin.backend.FunkinSprite;
|
||||||
import funkin.backend.system.ErrorCode;
|
import funkin.backend.system.ErrorCode;
|
||||||
import funkin.backend.FunkinSprite.XMLAnimType;
|
import funkin.backend.FunkinSprite.XMLAnimType;
|
||||||
import funkin.backend.system.interfaces.IBeatReceiver;
|
import flixel.util.FlxColor;
|
||||||
import haxe.xml.Access;
|
import haxe.xml.Access;
|
||||||
import funkin.backend.system.interfaces.IOffsetCompatible;
|
import funkin.backend.system.interfaces.IOffsetCompatible;
|
||||||
|
|
||||||
@@ -61,16 +60,14 @@ class XMLUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new sprite based on a XML node.
|
* Overrides a sprite based on a XML node.
|
||||||
*/
|
*/
|
||||||
public static function createSpriteFromXML(node:Access, parentFolder:String = "", defaultAnimType:XMLAnimType = BEAT, ?cl:Class<FunkinSprite>):FunkinSprite {
|
public static function loadSpriteFromXML(spr:FunkinSprite, node:Access, parentFolder:String = "", defaultAnimType:XMLAnimType = BEAT):FunkinSprite {
|
||||||
if (parentFolder == null) parentFolder = "";
|
if (parentFolder == null) parentFolder = "";
|
||||||
|
|
||||||
var spr:FunkinSprite = cl != null ? Type.createInstance(cl, []) : new FunkinSprite();
|
|
||||||
spr.name = node.getAtt("name");
|
spr.name = node.getAtt("name");
|
||||||
spr.antialiasing = true;
|
spr.antialiasing = true;
|
||||||
|
spr.loadSprite(Paths.image('$parentFolder${node.getAtt("sprite").getDefault(spr.name)}', null, true));
|
||||||
spr.loadSprite(Paths.image('$parentFolder${node.getAtt("sprite")}', null, true));
|
|
||||||
|
|
||||||
spr.spriteAnimType = defaultAnimType;
|
spr.spriteAnimType = defaultAnimType;
|
||||||
if (node.has.type) {
|
if (node.has.type) {
|
||||||
@@ -88,15 +85,14 @@ class XMLUtil {
|
|||||||
if (node.has.scroll) {
|
if (node.has.scroll) {
|
||||||
var scroll:Null<Float> = Std.parseFloat(node.att.scroll);
|
var scroll:Null<Float> = Std.parseFloat(node.att.scroll);
|
||||||
if (scroll.isNotNull()) spr.scrollFactor.set(scroll, scroll);
|
if (scroll.isNotNull()) spr.scrollFactor.set(scroll, scroll);
|
||||||
} else {
|
}
|
||||||
if (node.has.scrollx) {
|
if (node.has.scrollx) {
|
||||||
var scroll:Null<Float> = Std.parseFloat(node.att.scrollx);
|
var scroll:Null<Float> = Std.parseFloat(node.att.scrollx);
|
||||||
if (scroll.isNotNull()) spr.scrollFactor.x = scroll;
|
if (scroll.isNotNull()) spr.scrollFactor.x = scroll;
|
||||||
}
|
}
|
||||||
if (node.has.scrolly) {
|
if (node.has.scrolly) {
|
||||||
var scroll:Null<Float> = Std.parseFloat(node.att.scrolly);
|
var scroll:Null<Float> = Std.parseFloat(node.att.scrolly);
|
||||||
if (scroll.isNotNull()) spr.scrollFactor.y = scroll;
|
if (scroll.isNotNull()) spr.scrollFactor.y = scroll;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (node.has.skewx) {
|
if (node.has.skewx) {
|
||||||
var skew:Null<Float> = Std.parseFloat(node.att.skewx);
|
var skew:Null<Float> = Std.parseFloat(node.att.skewx);
|
||||||
@@ -107,6 +103,14 @@ class XMLUtil {
|
|||||||
if (skew.isNotNull()) spr.skew.y = skew;
|
if (skew.isNotNull()) spr.skew.y = skew;
|
||||||
}
|
}
|
||||||
if (node.has.antialiasing) spr.antialiasing = node.att.antialiasing == "true";
|
if (node.has.antialiasing) spr.antialiasing = node.att.antialiasing == "true";
|
||||||
|
if (node.has.width) {
|
||||||
|
var width:Null<Float> = Std.parseFloat(node.att.width);
|
||||||
|
if (width.isNotNull()) spr.width = width;
|
||||||
|
}
|
||||||
|
if (node.has.height) {
|
||||||
|
var height:Null<Float> = Std.parseFloat(node.att.height);
|
||||||
|
if (height.isNotNull()) spr.height = height;
|
||||||
|
}
|
||||||
if (node.has.scale) {
|
if (node.has.scale) {
|
||||||
var scale:Null<Float> = Std.parseFloat(node.att.scale);
|
var scale:Null<Float> = Std.parseFloat(node.att.scale);
|
||||||
if (scale.isNotNull()) spr.scale.set(scale, scale);
|
if (scale.isNotNull()) spr.scale.set(scale, scale);
|
||||||
@@ -119,14 +123,29 @@ class XMLUtil {
|
|||||||
var scale:Null<Float> = Std.parseFloat(node.att.scaley);
|
var scale:Null<Float> = Std.parseFloat(node.att.scaley);
|
||||||
if (scale.isNotNull()) spr.scale.y = scale;
|
if (scale.isNotNull()) spr.scale.y = scale;
|
||||||
}
|
}
|
||||||
|
if (node.has.graphicSize) {
|
||||||
|
var graphicSize:Null<Int> = Std.parseInt(node.att.graphicSize);
|
||||||
|
if (graphicSize.isNotNull()) spr.setGraphicSize(graphicSize, graphicSize);
|
||||||
|
}
|
||||||
|
if (node.has.graphicSizex) {
|
||||||
|
var graphicSizex:Null<Int> = Std.parseInt(node.att.graphicSizex);
|
||||||
|
if (graphicSizex.isNotNull()) spr.setGraphicSize(graphicSizex);
|
||||||
|
}
|
||||||
|
if (node.has.graphicSizey) {
|
||||||
|
var graphicSizey:Null<Int> = Std.parseInt(node.att.graphicSizey);
|
||||||
|
if (graphicSizey.isNotNull()) spr.setGraphicSize(0, graphicSizey);
|
||||||
|
}
|
||||||
if (node.has.updateHitbox && node.att.updateHitbox == "true") spr.updateHitbox();
|
if (node.has.updateHitbox && node.att.updateHitbox == "true") spr.updateHitbox();
|
||||||
|
|
||||||
if(node.has.zoomfactor)
|
if (node.has.zoomfactor)
|
||||||
spr.zoomFactor = Std.parseFloat(node.getAtt("zoomfactor")).getDefault(spr.zoomFactor);
|
spr.zoomFactor = Std.parseFloat(node.getAtt("zoomfactor")).getDefault(spr.zoomFactor);
|
||||||
|
|
||||||
if (node.has.alpha)
|
if (node.has.alpha)
|
||||||
spr.alpha = Std.parseFloat(node.getAtt("alpha")).getDefault(spr.alpha);
|
spr.alpha = Std.parseFloat(node.getAtt("alpha")).getDefault(spr.alpha);
|
||||||
|
|
||||||
|
if(node.has.color)
|
||||||
|
spr.color = FlxColor.fromString(node.getAtt("color")).getDefault(0xFFFFFFFF);
|
||||||
|
|
||||||
if (node.has.playOnCountdown)
|
if (node.has.playOnCountdown)
|
||||||
spr.skipNegativeBeats = node.att.playOnCountdown == "true";
|
spr.skipNegativeBeats = node.att.playOnCountdown == "true";
|
||||||
if (node.has.beatInterval)
|
if (node.has.beatInterval)
|
||||||
@@ -156,6 +175,15 @@ class XMLUtil {
|
|||||||
return spr;
|
return spr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new sprite based on a XML node.
|
||||||
|
*/
|
||||||
|
public static inline function createSpriteFromXML(node:Access, parentFolder:String = "", defaultAnimType:XMLAnimType = BEAT, ?cl:Class<FunkinSprite>, ?args:Array<Dynamic>):FunkinSprite {
|
||||||
|
if(cl == null) cl = FunkinSprite;
|
||||||
|
if(args == null) args = [];
|
||||||
|
return loadSpriteFromXML(Type.createInstance(cl, args), node, parentFolder, defaultAnimType);
|
||||||
|
}
|
||||||
|
|
||||||
public static function extractAnimFromXML(anim:Access, animType:XMLAnimType = NONE, loop:Bool = false):AnimData {
|
public static function extractAnimFromXML(anim:Access, animType:XMLAnimType = NONE, loop:Bool = false):AnimData {
|
||||||
var animData:AnimData = {
|
var animData:AnimData = {
|
||||||
name: null,
|
name: null,
|
||||||
|
|||||||
@@ -71,6 +71,13 @@ class NoteGroup extends FlxTypedGroup<Note> {
|
|||||||
@:privateAccess FlxCamera._defaultCameras = oldDefaultCameras;
|
@:privateAccess FlxCamera._defaultCameras = oldDefaultCameras;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the correct order of notes
|
||||||
|
**/
|
||||||
|
public function get(id:Int) {
|
||||||
|
return members[length - 1 - id];
|
||||||
|
}
|
||||||
|
|
||||||
public override function forEach(noteFunc:Note->Void, recursive:Bool = false) {
|
public override function forEach(noteFunc:Note->Void, recursive:Bool = false) {
|
||||||
i = length-1;
|
i = length-1;
|
||||||
__loopSprite = null;
|
__loopSprite = null;
|
||||||
|
|||||||
@@ -801,7 +801,7 @@ class PlayState extends MusicBeatState
|
|||||||
*/
|
*/
|
||||||
public function startCutscene(prefix:String = "", ?cutsceneScriptPath:String, ?callback:Void->Void, checkSeen:Bool = false) {
|
public function startCutscene(prefix:String = "", ?cutsceneScriptPath:String, ?callback:Void->Void, checkSeen:Bool = false) {
|
||||||
if (callback == null) callback = startCountdown;
|
if (callback == null) callback = startCountdown;
|
||||||
if (checkSeen && seenCutscene) {
|
if ((checkSeen && seenCutscene) || !playCutscenes) {
|
||||||
callback();
|
callback();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -809,34 +809,31 @@ class PlayState extends MusicBeatState
|
|||||||
if (cutsceneScriptPath == null)
|
if (cutsceneScriptPath == null)
|
||||||
cutsceneScriptPath = Paths.script('songs/${SONG.meta.name.toLowerCase()}/${prefix}cutscene');
|
cutsceneScriptPath = Paths.script('songs/${SONG.meta.name.toLowerCase()}/${prefix}cutscene');
|
||||||
|
|
||||||
if (playCutscenes) {
|
inCutscene = true;
|
||||||
inCutscene = true;
|
var videoCutscene = Paths.video('${PlayState.SONG.meta.name.toLowerCase()}-${prefix}cutscene');
|
||||||
var videoCutscene = Paths.video('${PlayState.SONG.meta.name.toLowerCase()}-${prefix}cutscene');
|
var videoCutsceneAlt = Paths.file('songs/${PlayState.SONG.meta.name.toLowerCase()}/${prefix}cutscene.mp4');
|
||||||
var videoCutsceneAlt = Paths.file('songs/${PlayState.SONG.meta.name.toLowerCase()}/${prefix}cutscene.mp4');
|
var dialogue = Paths.file('songs/${PlayState.SONG.meta.name.toLowerCase()}/${prefix}dialogue.xml');
|
||||||
var dialogue = Paths.file('songs/${PlayState.SONG.meta.name.toLowerCase()}/${prefix}dialogue.xml');
|
persistentUpdate = true;
|
||||||
persistentUpdate = true;
|
var toCall:Void->Void = function() {
|
||||||
var toCall:Void->Void = function() {
|
if(checkSeen) seenCutscene = true;
|
||||||
if(checkSeen) seenCutscene = true;
|
callback();
|
||||||
callback();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (cutsceneScriptPath != null && Assets.exists(cutsceneScriptPath)) {
|
if (cutsceneScriptPath != null && Assets.exists(cutsceneScriptPath)) {
|
||||||
openSubState(new ScriptedCutscene(cutsceneScriptPath, toCall));
|
openSubState(new ScriptedCutscene(cutsceneScriptPath, toCall));
|
||||||
} else if (Assets.exists(dialogue)) {
|
} else if (Assets.exists(dialogue)) {
|
||||||
MusicBeatState.skipTransIn = true;
|
MusicBeatState.skipTransIn = true;
|
||||||
openSubState(new DialogueCutscene(dialogue, toCall));
|
openSubState(new DialogueCutscene(dialogue, toCall));
|
||||||
} else if (Assets.exists(videoCutsceneAlt)) {
|
} else if (Assets.exists(videoCutsceneAlt)) {
|
||||||
MusicBeatState.skipTransIn = true;
|
MusicBeatState.skipTransIn = true;
|
||||||
persistentUpdate = false;
|
persistentUpdate = false;
|
||||||
openSubState(new VideoCutscene(videoCutsceneAlt, toCall));
|
openSubState(new VideoCutscene(videoCutsceneAlt, toCall));
|
||||||
persistentDraw = false;
|
persistentDraw = false;
|
||||||
} else if (Assets.exists(videoCutscene)) {
|
} else if (Assets.exists(videoCutscene)) {
|
||||||
MusicBeatState.skipTransIn = true;
|
MusicBeatState.skipTransIn = true;
|
||||||
persistentUpdate = false;
|
persistentUpdate = false;
|
||||||
openSubState(new VideoCutscene(videoCutscene, toCall));
|
openSubState(new VideoCutscene(videoCutscene, toCall));
|
||||||
persistentDraw = false;
|
persistentDraw = false;
|
||||||
} else
|
|
||||||
callback();
|
|
||||||
} else
|
} else
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
@@ -1072,8 +1069,6 @@ class PlayState extends MusicBeatState
|
|||||||
public inline function getIconRPC():String
|
public inline function getIconRPC():String
|
||||||
return SONG.meta.icon;
|
return SONG.meta.icon;
|
||||||
|
|
||||||
var __songPlaying:Bool = false;
|
|
||||||
var __wasAutoPause:Bool = false;
|
|
||||||
@:dox(hide)
|
@:dox(hide)
|
||||||
override public function onFocus():Void
|
override public function onFocus():Void
|
||||||
{
|
{
|
||||||
@@ -1188,8 +1183,10 @@ class PlayState extends MusicBeatState
|
|||||||
function updateIconPositions() {
|
function updateIconPositions() {
|
||||||
var iconOffset:Int = 26;
|
var iconOffset:Int = 26;
|
||||||
|
|
||||||
iconP1.x = healthBar.x + (healthBar.width * (FlxMath.remapToRange(healthBar.percent, 0, 100, 1, 0)) - iconOffset);
|
var center:Float = healthBar.x + healthBar.width * FlxMath.remapToRange(healthBar.percent, 0, 100, 1, 0);
|
||||||
iconP2.x = healthBar.x + (healthBar.width * (FlxMath.remapToRange(healthBar.percent, 0, 100, 1, 0))) - (iconP2.width - iconOffset);
|
|
||||||
|
iconP1.x = center - iconOffset;
|
||||||
|
iconP2.x = center - (iconP2.width - iconOffset);
|
||||||
|
|
||||||
health = FlxMath.bound(health, 0, maxHealth);
|
health = FlxMath.bound(health, 0, maxHealth);
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import haxe.xml.Access;
|
|||||||
class DialogueBox extends FunkinSprite {
|
class DialogueBox extends FunkinSprite {
|
||||||
public var dialogueBoxData:Access;
|
public var dialogueBoxData:Access;
|
||||||
public var positions:Map<String, CharPosDef> = [];
|
public var positions:Map<String, CharPosDef> = [];
|
||||||
|
public var everPlayedAny:Bool = false;
|
||||||
|
|
||||||
public var textTypeSFX:String = Paths.sound('dialogue/text');
|
public var textTypeSFX:String = Paths.sound('dialogue/text');
|
||||||
public var nextSFX:String = Paths.sound('dialogue/next');
|
public var nextSFX:String = Paths.sound('dialogue/next');
|
||||||
@@ -18,12 +19,22 @@ class DialogueBox extends FunkinSprite {
|
|||||||
super();
|
super();
|
||||||
try {
|
try {
|
||||||
dialogueBoxData = new Access(Xml.parse(Assets.getText(Paths.xml('dialogue/boxes/$name'))).firstElement());
|
dialogueBoxData = new Access(Xml.parse(Assets.getText(Paths.xml('dialogue/boxes/$name'))).firstElement());
|
||||||
|
if(!dialogueBoxData.has.sprite) dialogueBoxData.x.set("sprite", name);
|
||||||
|
XMLUtil.loadSpriteFromXML(this, dialogueBoxData, "dialogue/boxes/", NONE);
|
||||||
|
visible = false;
|
||||||
|
|
||||||
loadSprite(Paths.image('dialogue/boxes/${dialogueBoxData.getAtt('sprite').getDefault(name)}'));
|
var preX:Float = x;
|
||||||
|
screenCenter(X); x += preX;
|
||||||
|
y += FlxG.height - height;
|
||||||
|
|
||||||
for(anim in dialogueBoxData.nodes.anim) {
|
if(dialogueBoxData.has.textSound) textTypeSFX = Paths.sound(dialogueBoxData.att.textSound);
|
||||||
if (!anim.has.name) continue;
|
if(dialogueBoxData.has.nextSound) nextSFX = Paths.sound(dialogueBoxData.att.nextSound);
|
||||||
XMLUtil.addXMLAnimation(this, anim);
|
|
||||||
|
animation.finishCallback = (name:String) -> {
|
||||||
|
if(name.endsWith("-open") || name.endsWith("-firstOpen")) {
|
||||||
|
playAnim(name.substr(0, name.length - 5));
|
||||||
|
setText(__nextText, __speed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(pos in dialogueBoxData.nodes.charpos) {
|
for(pos in dialogueBoxData.nodes.charpos) {
|
||||||
@@ -35,16 +46,6 @@ class DialogueBox extends FunkinSprite {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dialogueBoxData.has.textSound) textTypeSFX = Paths.sound(dialogueBoxData.att.textSound);
|
|
||||||
if (dialogueBoxData.has.nextSound) nextSFX = Paths.sound(dialogueBoxData.att.nextSound);
|
|
||||||
|
|
||||||
antialiasing = dialogueBoxData.getAtt("antialiasing").getDefault("true") == "true";
|
|
||||||
screenCenter(X);
|
|
||||||
y = FlxG.height - height;
|
|
||||||
if (dialogueBoxData.has.x) x += Std.parseFloat(dialogueBoxData.att.x).getDefault(0);
|
|
||||||
if (dialogueBoxData.has.y) y += Std.parseFloat(dialogueBoxData.att.y).getDefault(0);
|
|
||||||
visible = false;
|
|
||||||
|
|
||||||
var textNode = dialogueBoxData.node.text;
|
var textNode = dialogueBoxData.node.text;
|
||||||
if (textNode == null)
|
if (textNode == null)
|
||||||
throw "The dialog box XML requires one text element.";
|
throw "The dialog box XML requires one text element.";
|
||||||
@@ -57,6 +58,16 @@ class DialogueBox extends FunkinSprite {
|
|||||||
text.font = Paths.font('${textNode.getAtt("font").getDefault("vcr.ttf")}');
|
text.font = Paths.font('${textNode.getAtt("font").getDefault("vcr.ttf")}');
|
||||||
text.antialiasing = textNode.getAtt("antialiasing").getDefault("false") == "true";
|
text.antialiasing = textNode.getAtt("antialiasing").getDefault("false") == "true";
|
||||||
text.sounds = [FlxG.sound.load(textTypeSFX)];
|
text.sounds = [FlxG.sound.load(textTypeSFX)];
|
||||||
|
if(textNode.has.borderStyle) {
|
||||||
|
text.borderStyle = switch(textNode.att.borderStyle.trim().toLowerCase()) {
|
||||||
|
case "none": NONE;
|
||||||
|
case "shadow": SHADOW;
|
||||||
|
case "outline_fast": OUTLINE_FAST;
|
||||||
|
default: OUTLINE;
|
||||||
|
}
|
||||||
|
text.borderSize = Std.parseFloat(textNode.getAtt("borderSize")).getDefault(1);
|
||||||
|
text.borderColor = textNode.getAtt("borderColor").getColorFromDynamic().getDefault(0xFFFFFFFF);
|
||||||
|
}
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
active = false;
|
active = false;
|
||||||
Logs.trace('Couldn\'t load dialogue box "$name": ${e.toString()}', ERROR);
|
Logs.trace('Couldn\'t load dialogue box "$name": ${e.toString()}', ERROR);
|
||||||
@@ -80,13 +91,14 @@ class DialogueBox extends FunkinSprite {
|
|||||||
this.__speed = speed;
|
this.__speed = speed;
|
||||||
this.text.resetText(text);
|
this.text.resetText(text);
|
||||||
FlxG.sound.play(nextSFX);
|
FlxG.sound.play(nextSFX);
|
||||||
if (hasAnimation('$bubble-open'))
|
if(hasAnimation('$bubble-open')) playAnim('$bubble-open', true);
|
||||||
playAnim('$bubble-open', true);
|
else if(hasAnimation('$bubble-firstOpen') && !everPlayedAny) playAnim('$bubble-firstOpen', true);
|
||||||
else {
|
else {
|
||||||
playAnim(bubble);
|
playAnim(bubble);
|
||||||
setText(__nextText, __speed);
|
setText(__nextText, __speed);
|
||||||
}
|
}
|
||||||
visible = true;
|
visible = true;
|
||||||
|
everPlayedAny = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setText(text:String, speed:Float = 0.02) {
|
public function setText(text:String, speed:Float = 0.02) {
|
||||||
@@ -94,17 +106,6 @@ class DialogueBox extends FunkinSprite {
|
|||||||
this.text.start(speed, true);
|
this.text.start(speed, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function update(elapsed:Float) {
|
|
||||||
super.update(elapsed);
|
|
||||||
if (isAnimFinished()) {
|
|
||||||
var animName = getAnimName();
|
|
||||||
if (animName.endsWith("-open")) {
|
|
||||||
playAnim(animName.substr(0, animName.length - 5));
|
|
||||||
setText(__nextText, __speed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override function destroy() {
|
public override function destroy() {
|
||||||
super.destroy();
|
super.destroy();
|
||||||
positions = null;
|
positions = null;
|
||||||
|
|||||||
@@ -6,23 +6,30 @@ import haxe.xml.Access;
|
|||||||
class DialogueCharacter extends FunkinSprite {
|
class DialogueCharacter extends FunkinSprite {
|
||||||
public var charData:Access;
|
public var charData:Access;
|
||||||
public var curTween:FlxTween;
|
public var curTween:FlxTween;
|
||||||
public var curTweenContext:DialogueCharTweenContext = NONE;
|
public var curAnimContext:DialogueCharAnimContext = NONE;
|
||||||
public var positionName:String;
|
public var positionName:String;
|
||||||
|
public var finishCallback:String->Void = null;
|
||||||
|
|
||||||
public function new(name:String, position:String) {
|
public function new(name:String, position:String) {
|
||||||
super();
|
super();
|
||||||
this.positionName = position;
|
this.positionName = position;
|
||||||
try {
|
try {
|
||||||
charData = new Access(Xml.parse(Assets.getText(Paths.xml('dialogue/characters/$name'))).firstElement());
|
charData = new Access(Xml.parse(Assets.getText(Paths.xml('dialogue/characters/$name'))).firstElement());
|
||||||
loadSprite(Paths.image('dialogue/characters/${charData.getAtt('sprite').getDefault(name)}'));
|
if(!charData.has.sprite) charData.x.set("sprite", name);
|
||||||
antialiasing = charData.getAtt('antialiasing').getDefault('true') == 'true';
|
if(!charData.has.updateHitbox) charData.x.set("updateHitbox", "true");
|
||||||
scale.scale(charData.has.scale ? Std.parseFloat(charData.att.scale).getDefault(1) : 1);
|
XMLUtil.loadSpriteFromXML(this, charData, "dialogue/characters/", LOOP);
|
||||||
updateHitbox();
|
|
||||||
offset.set(
|
animation.finishCallback = (name:String) -> {
|
||||||
charData.has.x ? Std.parseFloat(charData.att.x).getDefault(0) : 0,
|
switch(name)
|
||||||
(charData.has.y ? Std.parseFloat(charData.att.y).getDefault(0) : 0) + this.height);
|
{
|
||||||
for(anim in charData.nodes.anim)
|
case 'show': hasAnimation('normal') ? playAnim('normal', true) : animation.stop();
|
||||||
XMLUtil.addXMLAnimation(this, anim, true);
|
case 'hide': alpha = 0;
|
||||||
|
}
|
||||||
|
if(finishCallback != null) finishCallback(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
offset.set(x, y + height);
|
||||||
|
x = 0; y = 0;
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
Logs.trace('Failed to load dialogue character $name: ${e.toString()}', ERROR);
|
Logs.trace('Failed to load dialogue character $name: ${e.toString()}', ERROR);
|
||||||
}
|
}
|
||||||
@@ -30,29 +37,34 @@ class DialogueCharacter extends FunkinSprite {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function show(x:Float, y:Float) {
|
public function show(x:Float, y:Float) {
|
||||||
if (curTweenContext != (curTweenContext = POPIN)) {
|
if (curAnimContext == (curAnimContext = POPIN)) return;
|
||||||
setPosition(x, y + 100);
|
|
||||||
if (curTween != null)
|
|
||||||
curTween.cancel();
|
|
||||||
|
|
||||||
|
visible = true;
|
||||||
|
if (hasAnimation('show')) {
|
||||||
|
playAnim('show', true);
|
||||||
|
setPosition(x, y);
|
||||||
|
alpha = 1;
|
||||||
|
} else {
|
||||||
|
setPosition(x, y + 100);
|
||||||
|
if(curTween != null) curTween.cancel();
|
||||||
|
playAnim('normal', true);
|
||||||
alpha = 0;
|
alpha = 0;
|
||||||
visible = true;
|
|
||||||
|
|
||||||
curTween = FlxTween.tween(this, {alpha: 1, y: y}, 0.2, {ease: FlxEase.quintOut});
|
curTween = FlxTween.tween(this, {alpha: 1, y: y}, 0.2, {ease: FlxEase.quintOut});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function hide() {
|
public function hide() {
|
||||||
if (curTweenContext != (curTweenContext = POPOUT)) {
|
if (curAnimContext == (curAnimContext = POPOUT)) return;
|
||||||
if (curTween != null)
|
|
||||||
curTween.cancel();
|
if(hasAnimation('hide')) playAnim('hide', true);
|
||||||
|
else {
|
||||||
|
if(curTween != null) curTween.cancel();
|
||||||
curTween = FlxTween.tween(this, {alpha: 0, y: y + 100}, 0.2, {ease: FlxEase.quintIn});
|
curTween = FlxTween.tween(this, {alpha: 0, y: y + 100}, 0.2, {ease: FlxEase.quintIn});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum abstract DialogueCharTweenContext(Int) {
|
enum abstract DialogueCharAnimContext(Int) {
|
||||||
var NONE = -1;
|
var NONE = -1;
|
||||||
var POPIN = 0;
|
var POPIN = 0;
|
||||||
var POPOUT = 1;
|
var POPOUT = 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user