Merge remote-tracking branch 'upstream/main'
@@ -1,12 +1,18 @@
|
||||
<!DOCTYPE codename-engine-character>
|
||||
<character isPlayer="true" flipX="true" x="0" y="350" icon="bf" camx="25" color="#31B0D1">
|
||||
<anim name="idle" anim="BF idle dance" fps="24" loop="false" x="-5" y="0"/>
|
||||
<anim name="singUP" anim="BF NOTE UP0" fps="24" loop="false" x="-29" y="27"/>
|
||||
<anim name="singLEFT" anim="BF NOTE LEFT0" fps="24" loop="false" x="12" y="-6"/>
|
||||
<anim name="singRIGHT" anim="BF NOTE RIGHT0" fps="24" loop="false" x="-38" y="-7"/>
|
||||
<anim name="singDOWN" anim="BF NOTE DOWN0" fps="24" loop="false" x="-10" y="-50"/>
|
||||
<anim name="singUPmiss" anim="BF NOTE UP MISS" fps="24" loop="false" x="-29" y="27"/>
|
||||
<anim name="singLEFTmiss" anim="BF NOTE LEFT MISS" fps="24" loop="false" x="12" y="24"/>
|
||||
<anim name="singRIGHTmiss" anim="BF NOTE RIGHT MISS" fps="24" loop="false" x="-30" y="21"/>
|
||||
<anim name="singDOWNmiss" anim="BF NOTE DOWN MISS" fps="24" loop="false" x="-11" y="-19"/>
|
||||
<anim name="idle" anim="BF idle dance" fps="24" loop="false" x="-5" y="0"/>
|
||||
<anim name="singUP" anim="BF NOTE UP0" fps="24" loop="false" x="-29" y="27"/>
|
||||
<anim name="singLEFT" anim="BF NOTE LEFT0" fps="24" loop="false" x="12" y="-6"/>
|
||||
<anim name="singRIGHT" anim="BF NOTE RIGHT0" fps="24" loop="false" x="-38" y="-7"/>
|
||||
<anim name="singDOWN" anim="BF NOTE DOWN0" fps="24" loop="false" x="-10" y="-50"/>
|
||||
<anim name="singUPmiss" anim="BF NOTE UP MISS" fps="24" loop="false" x="-29" y="27"/>
|
||||
<anim name="singLEFTmiss" anim="BF NOTE LEFT MISS" fps="24" loop="false" x="12" y="24"/>
|
||||
<anim name="singRIGHTmiss" anim="BF NOTE RIGHT MISS" fps="24" loop="false" x="-30" y="21"/>
|
||||
<anim name="singDOWNmiss" anim="BF NOTE DOWN MISS" fps="24" loop="false" x="-11" y="-19"/>
|
||||
<!-- funny loop -->
|
||||
<anim name="idle-loop" anim="BF idle dance" fps="24" loop="true" x="-5" y="0" indices="10,11,12,13"/>
|
||||
<anim name="singUP-loop" anim="BF NOTE UP0" fps="24" loop="true" x="-29" y="27" indices="11,12,13,14"/>
|
||||
<anim name="singLEFT-loop" anim="BF NOTE LEFT0" fps="24" loop="true" x="12" y="-6" indices="12,13,14,15"/>
|
||||
<anim name="singRIGHT-loop" anim="BF NOTE RIGHT0" fps="24" loop="true" x="-38" y="-7" indices="58,59,60,61"/>
|
||||
<anim name="singDOWN-loop" anim="BF NOTE DOWN0" fps="24" loop="true" x="-10" y="-50" indices="26,27,28,29"/>
|
||||
</character>
|
||||
@@ -1,8 +1,13 @@
|
||||
<!DOCTYPE codename-engine-character>
|
||||
<character isPlayer="false" flipX="false" holdTime="6.1" icon="dad" y="150" color="#AF66CE">
|
||||
<anim name="idle" anim="Dad idle dance" fps="24" loop="false" x="0" y="0"/>
|
||||
<anim name="singUP" anim="Dad Sing note UP" fps="24" loop="false" x="-2" y="50"/>
|
||||
<anim name="singLEFT" anim="dad sing note right" fps="24" loop="false" x="-2" y="10"/>
|
||||
<anim name="singRIGHT" anim="Dad Sing Note LEFT" fps="24" loop="false" x="-5" y="27"/>
|
||||
<anim name="singDOWN" anim="Dad Sing Note DOWN" fps="24" loop="false" x="0" y="-30"/>
|
||||
<anim name="idle" anim="Dad idle dance" fps="24" loop="false" x="0" y="0"/>
|
||||
<anim name="singUP" anim="Dad Sing note UP" fps="24" loop="false" x="-2" y="50"/>
|
||||
<anim name="singLEFT" anim="dad sing note right" fps="24" loop="false" x="-2" y="10"/>
|
||||
<anim name="singRIGHT" anim="Dad Sing Note LEFT" fps="24" loop="false" x="-5" y="27"/>
|
||||
<anim name="singDOWN" anim="Dad Sing Note DOWN" fps="24" loop="false" x="0" y="-30"/>
|
||||
<!-- funny loop -->
|
||||
<anim name="idle-loop" anim="Dad idle dance" fps="24" loop="true" x="0" y="0" indices="10,11,12,12"/>
|
||||
<anim name="singUP-loop" anim="Dad Sing note UP" fps="24" loop="true" x="-6" y="50" indices="56,57,58,59"/>
|
||||
<anim name="singLEFT-loop" anim="dad sing note right" fps="24" loop="true" x="-10" y="10" indices="12,13,14,15"/>
|
||||
<anim name="singRIGHT-loop" anim="Dad Sing Note LEFT" fps="24" loop="true" x="0" y="27" indices="15,16,17,18"/>
|
||||
</character>
|
||||
@@ -1,8 +1,13 @@
|
||||
<!DOCTYPE codename-engine-character>
|
||||
<character isPlayer="false" flipX="false" holdTime="6.1" color="#AF66CE">
|
||||
<anim name="idle" anim="Dad idle dance" fps="24" loop="false" x="0" y="0"/>
|
||||
<anim name="singUP" anim="Dad Sing note UP" fps="24" loop="false" x="-6" y="50"/>
|
||||
<anim name="singLEFT" anim="dad sing note right" fps="24" loop="false" x="-10" y="10"/>
|
||||
<anim name="singRIGHT" anim="Dad Sing Note LEFT" fps="24" loop="false" x="0" y="27"/>
|
||||
<anim name="singDOWN" anim="Dad Sing Note DOWN" fps="24" loop="false" x="0" y="-30"/>
|
||||
<anim name="idle" anim="Dad idle dance" fps="24" loop="false" x="0" y="0"/>
|
||||
<anim name="singUP" anim="Dad Sing note UP" fps="24" loop="false" x="-6" y="50"/>
|
||||
<anim name="singLEFT" anim="dad sing note right" fps="24" loop="false" x="-10" y="10"/>
|
||||
<anim name="singRIGHT" anim="Dad Sing Note LEFT" fps="24" loop="false" x="0" y="27"/>
|
||||
<anim name="singDOWN" anim="Dad Sing Note DOWN" fps="24" loop="false" x="0" y="-30"/>
|
||||
<!-- funny loop -->
|
||||
<anim name="idle-loop" anim="Dad idle dance" fps="24" loop="true" x="0" y="0" indices="10,11,12,12"/>
|
||||
<anim name="singUP-loop" anim="Dad Sing note UP" fps="24" loop="true" x="-6" y="50" indices="56,57,58,59"/>
|
||||
<anim name="singLEFT-loop" anim="dad sing note right" fps="24" loop="true" x="-10" y="10" indices="12,13,14,15"/>
|
||||
<anim name="singRIGHT-loop" anim="Dad Sing Note LEFT" fps="24" loop="true" x="0" y="27" indices="15,16,17,18"/>
|
||||
</character>
|
||||
@@ -1,10 +1,16 @@
|
||||
<!DOCTYPE codename-engine-character>
|
||||
<character isPlayer="false" flipX="false" icon="mom" color="#D8558E">
|
||||
<anim name="idle" anim="Mom Idle" fps="24" loop="false" />
|
||||
<anim name="singUP" anim="Mom Up Pose" fps="24" loop="false" x="14" y="71"/>
|
||||
<anim name="singDOWN" anim="MOM DOWN POSE" fps="24" loop="false" x="20" y="-160"/>
|
||||
<anim name="singLEFT" anim="Mom Left Pose" fps="24" loop="false" x="250" y="-23"/>
|
||||
<anim name="idle" anim="Mom Idle" fps="24" loop="false" />
|
||||
<anim name="singUP" anim="Mom Up Pose" fps="24" loop="false" x="14" y="71"/>
|
||||
<anim name="singDOWN" anim="MOM DOWN POSE" fps="24" loop="false" x="20" y="-160"/>
|
||||
<anim name="singLEFT" anim="Mom Left Pose" fps="24" loop="false" x="250" y="-23"/>
|
||||
<!-- ANIMATION IS CALLED MOM LEFT POSE BUT ITS FOR THE RIGHT -->
|
||||
<!-- CUZ DAVE IS DUMB! -->
|
||||
<anim name="singRIGHT" anim="Mom Pose Left" fps="24" loop="false" x="10" y="-60"/>
|
||||
<!-- funny loop -->
|
||||
<anim name="idle-loop" anim="Mom Idle" fps="24" loop="true" indices="10,11,12,13"/>
|
||||
<anim name="singUP-loop" anim="Mom Up Pose" fps="24" loop="true" x="14" y="71" indices="11,12,13,14"/>
|
||||
<anim name="singDOWN-loop" anim="MOM DOWN POSE" fps="24" loop="true" x="20" y="-160" indices="11,12,13,14"/>
|
||||
<anim name="singLEFT-loop" anim="Mom Left Pose" fps="24" loop="true" x="250" y="-23" indices="6,7,8,9"/>
|
||||
<anim name="singRIGHT-loop" anim="Mom Pose Left" fps="24" loop="true" x="10" y="-60" indices="6,7,8,9"/>
|
||||
</character>
|
||||
@@ -1,10 +1,16 @@
|
||||
<!DOCTYPE codename-engine-character>
|
||||
<character isPlayer="false" flipX="false" color="#D8558E">
|
||||
<anim name="idle" anim="Mom Idle" fps="24" loop="false" />
|
||||
<anim name="singUP" anim="Mom Up Pose" fps="24" loop="false" x="14" y="71"/>
|
||||
<anim name="singDOWN" anim="MOM DOWN POSE" fps="24" loop="false" x="20" y="-160"/>
|
||||
<anim name="singLEFT" anim="Mom Left Pose" fps="24" loop="false" x="250" y="-23"/>
|
||||
<anim name="idle" anim="Mom Idle" fps="24" loop="false" />
|
||||
<anim name="singUP" anim="Mom Up Pose" fps="24" loop="false" x="14" y="71"/>
|
||||
<anim name="singDOWN" anim="MOM DOWN POSE" fps="24" loop="false" x="20" y="-160"/>
|
||||
<anim name="singLEFT" anim="Mom Left Pose" fps="24" loop="false" x="250" y="-23"/>
|
||||
<!-- ANIMATION IS CALLED MOM LEFT POSE BUT ITS FOR THE RIGHT -->
|
||||
<!-- CUZ DAVE IS DUMB! -->
|
||||
<anim name="singRIGHT" anim="Mom Pose Left" fps="24" loop="false" x="10" y="-60"/>
|
||||
<anim name="singRIGHT" anim="Mom Pose Left" fps="24" loop="false" x="10" y="-60"/>
|
||||
<!-- funny loop -->
|
||||
<anim name="idle-loop" anim="Mom Idle" fps="24" loop="true" indices="10,11,12,13"/>
|
||||
<anim name="singUP-loop" anim="Mom Up Pose" fps="24" loop="true" x="14" y="71" indices="11,12,13,14"/>
|
||||
<anim name="singDOWN-loop" anim="MOM DOWN POSE" fps="24" loop="true" x="20" y="-160" indices="9,10,11,12"/>
|
||||
<anim name="singLEFT-loop" anim="Mom Left Pose" fps="24" loop="true" x="250" y="-23" indices="6,7,8,9"/>
|
||||
<anim name="singRIGHT-loop" anim="Mom Pose Left" fps="24" loop="true" x="10" y="-60" indices="6,7,8,9"/>
|
||||
</character>
|
||||
@@ -3,5 +3,5 @@
|
||||
<menu name="Mod Credits" desc="Modify mod credits here">
|
||||
<!-- \/ You can also set the portrait shader as false as you can see below in the github one -->
|
||||
<credit name="Credit Example" desc="Click me to know more about me!" icon="credit icon example" size="130" url="https://youtu.be/fugtxz1znVw"/>
|
||||
<github user="NexIsDumb" customName="Nex is Dumb" desc="The bitch who made these credits menus" size="100" portrait="false"/>
|
||||
<github user="NexIsDumb" customName="Nex is Dumb" desc="The bitch who made these credits menus" size="100" portrait="false" color="#808080"/>
|
||||
</menu>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
story mode
|
||||
freeplay
|
||||
options
|
||||
donate
|
||||
credits
|
||||
@@ -15,8 +15,9 @@
|
||||
<SubTexture name="MOM DOWN POSE0010" x="1246" y="0" width="403" height="600" frameX="0" frameY="-13" frameWidth="414" frameHeight="613"/>
|
||||
<SubTexture name="MOM DOWN POSE0011" x="1246" y="0" width="403" height="600" frameX="0" frameY="-13" frameWidth="414" frameHeight="613"/>
|
||||
<SubTexture name="MOM DOWN POSE0012" x="833" y="0" width="403" height="600" frameX="0" frameY="-13" frameWidth="414" frameHeight="613"/>
|
||||
<SubTexture name="MOM DOWN POSE0013" x="1659" y="0" width="403" height="600" frameX="0" frameY="-13" frameWidth="414" frameHeight="613"/>
|
||||
<SubTexture name="MOM DOWN POSE0014" x="1659" y="0" width="403" height="600" frameX="0" frameY="-13" frameWidth="414" frameHeight="613"/>
|
||||
<!-- commented out because she has no face -->
|
||||
<!-- <SubTexture name="MOM DOWN POSE0013" x="1659" y="0" width="403" height="600" frameX="0" frameY="-13" frameWidth="414" frameHeight="613"/>
|
||||
<SubTexture name="MOM DOWN POSE0014" x="1659" y="0" width="403" height="600" frameX="0" frameY="-13" frameWidth="414" frameHeight="613"/> -->
|
||||
<SubTexture name="Mom Idle0000" x="2072" y="0" width="386" height="826" frameX="-4" frameY="-2" frameWidth="390" frameHeight="829"/>
|
||||
<SubTexture name="Mom Idle0001" x="2072" y="0" width="386" height="826" frameX="-4" frameY="-2" frameWidth="390" frameHeight="829"/>
|
||||
<SubTexture name="Mom Idle0002" x="2468" y="0" width="386" height="815" frameX="-4" frameY="-14" frameWidth="390" frameHeight="829"/>
|
||||
|
||||
|
After Width: | Height: | Size: 24 KiB |
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Created with Funkin Packer v0.1.3 https://neeeoo.github.io/funkin-packer/
|
||||
-->
|
||||
<TextureAtlas imagePath="credits.png" width="522" height="905">
|
||||
<SubTexture name="credits white0001" x="1" y="1" width="520" height="172" frameX="-2" frameY="20" frameWidth="522" frameHeight="172"/>
|
||||
<SubTexture name="credits white0002" x="1" y="176" width="520" height="172" frameX="-0" frameY="20" frameWidth="522" frameHeight="172"/>
|
||||
<SubTexture name="credits white0003" x="1" y="351" width="519" height="172" frameX="-2" frameY="20" frameWidth="522" frameHeight="172"/>
|
||||
<SubTexture name="credits basic0001" x="1" y="526" width="439" height="124" frameX="-0" frameY="5" frameWidth="439" frameHeight="125"/>
|
||||
<SubTexture name="credits basic0002" x="1" y="526" width="439" height="124" frameX="-0" frameY="5" frameWidth="439" frameHeight="125"/>
|
||||
<SubTexture name="credits basic0003" x="1" y="526" width="439" height="124" frameX="-0" frameY="5" frameWidth="439" frameHeight="125"/>
|
||||
<SubTexture name="credits basic0004" x="1" y="653" width="439" height="124" frameX="-0" frameY="5" frameWidth="439" frameHeight="125"/>
|
||||
<SubTexture name="credits basic0005" x="1" y="653" width="439" height="124" frameX="-0" frameY="5" frameWidth="439" frameHeight="125"/>
|
||||
<SubTexture name="credits basic0006" x="1" y="653" width="439" height="124" frameX="-0" frameY="5" frameWidth="439" frameHeight="125"/>
|
||||
<SubTexture name="credits basic0007" x="1" y="780" width="439" height="124" frameX="-0" frameY="5" frameWidth="439" frameHeight="125"/>
|
||||
<SubTexture name="credits basic0008" x="1" y="780" width="439" height="124" frameX="-0" frameY="5" frameWidth="439" frameHeight="125"/>
|
||||
<SubTexture name="credits basic0009" x="1" y="780" width="439" height="124" frameX="-0" frameY="5" frameWidth="439" frameHeight="125"/>
|
||||
</TextureAtlas>
|
||||
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 29 KiB |
@@ -1,17 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextureAtlas imagePath="freeplay.png">
|
||||
<!-- Created with Adobe Animate version 21.0.1.37179 and edited by Nex_isDumb -->
|
||||
<!-- http://www.adobe.com/products/animate.html -->
|
||||
<SubTexture name="freeplay basic0000" x="2" y="2" width="484" height="122" pivotX="7.65" pivotY="10.55"/>
|
||||
<SubTexture name="freeplay basic0001" x="2" y="2" width="484" height="122"/>
|
||||
<SubTexture name="freeplay basic0002" x="2" y="2" width="484" height="122"/>
|
||||
<SubTexture name="freeplay basic0003" x="2" y="126" width="484" height="122"/>
|
||||
<SubTexture name="freeplay basic0004" x="2" y="126" width="484" height="122"/>
|
||||
<SubTexture name="freeplay basic0005" x="2" y="126" width="484" height="122"/>
|
||||
<SubTexture name="freeplay basic0006" x="2" y="250" width="484" height="122"/>
|
||||
<SubTexture name="freeplay basic0007" x="2" y="250" width="484" height="122"/>
|
||||
<SubTexture name="freeplay basic0008" x="2" y="250" width="484" height="122"/>
|
||||
<SubTexture name="freeplay white0000" x="2" y="374" width="627" height="169" pivotX="15" pivotY="17.15" frameX="0" frameY="20" frameWidth="635" frameHeight="174"/>
|
||||
<SubTexture name="freeplay white0001" x="2" y="545" width="632" height="170" frameX="-3" frameY="19" frameWidth="635" frameHeight="174"/>
|
||||
<SubTexture name="freeplay white0002" x="2" y="717" width="629" height="173" frameX="-4" frameY="19" frameWidth="635" frameHeight="174"/>
|
||||
</TextureAtlas>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Created with Funkin Packer v0.1.3 https://neeeoo.github.io/funkin-packer/
|
||||
-->
|
||||
<TextureAtlas imagePath="freeplay.png" width="634" height="894">
|
||||
<SubTexture name="freeplay basic0000" x="1" y="521" width="484" height="122" frameX="-0" frameY="-0" frameWidth="484" frameHeight="122"/>
|
||||
<SubTexture name="freeplay basic0001" x="1" y="521" width="484" height="122" frameX="-0" frameY="-0" frameWidth="484" frameHeight="122"/>
|
||||
<SubTexture name="freeplay basic0002" x="1" y="521" width="484" height="122" frameX="-0" frameY="-0" frameWidth="484" frameHeight="122"/>
|
||||
<SubTexture name="freeplay basic0003" x="1" y="646" width="484" height="122" frameX="-0" frameY="-0" frameWidth="484" frameHeight="122"/>
|
||||
<SubTexture name="freeplay basic0004" x="1" y="646" width="484" height="122" frameX="-0" frameY="-0" frameWidth="484" frameHeight="122"/>
|
||||
<SubTexture name="freeplay basic0005" x="1" y="646" width="484" height="122" frameX="-0" frameY="-0" frameWidth="484" frameHeight="122"/>
|
||||
<SubTexture name="freeplay basic0006" x="1" y="771" width="484" height="122" frameX="-0" frameY="-0" frameWidth="484" frameHeight="122"/>
|
||||
<SubTexture name="freeplay basic0007" x="1" y="771" width="484" height="122" frameX="-0" frameY="-0" frameWidth="484" frameHeight="122"/>
|
||||
<SubTexture name="freeplay basic0008" x="1" y="771" width="484" height="122" frameX="-0" frameY="-0" frameWidth="484" frameHeight="122"/>
|
||||
<SubTexture name="freeplay white0000" x="1" y="350" width="627" height="168" frameX="-0" frameY="20" frameWidth="635" frameHeight="174"/>
|
||||
<SubTexture name="freeplay white0001" x="1" y="1" width="632" height="170" frameX="-3" frameY="19" frameWidth="635" frameHeight="174"/>
|
||||
<SubTexture name="freeplay white0002" x="1" y="174" width="628" height="173" frameX="-4" frameY="19" frameWidth="635" frameHeight="174"/>
|
||||
</TextureAtlas>
|
||||
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
@@ -94,6 +94,14 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
public override function update(elapsed:Float)
|
||||
{
|
||||
super.update(elapsed);
|
||||
|
||||
// hate how it looks like but hey at least its optimized and fast - Nex
|
||||
if (!debugMode && isAnimFinished()) {
|
||||
var name = getAnimName() + '-loop';
|
||||
if (animation.exists(name))
|
||||
playAnim(name, false, lastAnimContext);
|
||||
}
|
||||
|
||||
if (animateAtlas != null)
|
||||
animateAtlas.update(elapsed);
|
||||
}
|
||||
@@ -328,6 +336,10 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
return (animateAtlas != null) ? atlasPlayingAnim : animation.name;
|
||||
}
|
||||
|
||||
public inline function isAnimReversed():Bool {
|
||||
return animateAtlas != null ? animateAtlas.anim.reversed : animation.curAnim != null ? animation.curAnim.reversed : false;
|
||||
}
|
||||
|
||||
public inline function removeAnimation(name:String) {
|
||||
if (animateAtlas != null)
|
||||
@:privateAccess animateAtlas.anim.animsMap.remove(name);
|
||||
|
||||
@@ -821,6 +821,91 @@ class CoolUtil
|
||||
var file = new haxe.io.Path(file);
|
||||
return file.file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string of "1..3,5,7..9,8..5" into an array of numbers like [1,2,3,5,7,8,9,8,7,6,5]
|
||||
* @param input String to parse
|
||||
* @return Array of numbers
|
||||
*/
|
||||
public static function parseNumberRange(input:String):Array<Int> {
|
||||
var result:Array<Int> = [];
|
||||
var parts:Array<String> = input.split(",");
|
||||
|
||||
for (part in parts) {
|
||||
part = part.trim();
|
||||
var idx = part.indexOf("..");
|
||||
if (idx != -1) {
|
||||
var start = Std.parseInt(part.substring(0, idx).trim());
|
||||
var end = Std.parseInt(part.substring(idx + 2).trim());
|
||||
|
||||
if(start == null || end == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (start < end) {
|
||||
for (j in start...end + 1) {
|
||||
result.push(j);
|
||||
}
|
||||
} else {
|
||||
for (j in end...start + 1) {
|
||||
result.push(start + end - j);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var num = Std.parseInt(part);
|
||||
if (num != null) {
|
||||
result.push(num);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an array of numbers into a string of ranges.
|
||||
* Example: [1,2,3,5,7,8,9,8,7,6,5] -> "1..3,5,7..9,8..5"
|
||||
* @param numbers Array of numbers
|
||||
* @return String representing the ranges
|
||||
*/
|
||||
public static function formatNumberRange(numbers:Array<Int>, seperator:String = ","):String {
|
||||
if (numbers.length == 0) return "";
|
||||
|
||||
var result:Array<String> = [];
|
||||
var i = 0;
|
||||
|
||||
while (i < numbers.length) {
|
||||
var start = numbers[i];
|
||||
var end = start;
|
||||
var direction = 0; // 0: no sequence, 1: increasing, -1: decreasing
|
||||
|
||||
if (i + 1 < numbers.length) { // detect direction of sequence
|
||||
if (numbers[i + 1] == end + 1) {
|
||||
direction = 1;
|
||||
} else if (numbers[i + 1] == end - 1) {
|
||||
direction = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if(direction != 0) {
|
||||
while (i + 1 < numbers.length && (numbers[i + 1] == end + direction)) {
|
||||
end = numbers[i + 1];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (start == end) { // no direction
|
||||
result.push('${start}');
|
||||
} else if (start + direction == end) { // 1 step increment
|
||||
result.push('${start},${end}');
|
||||
} else { // store as range
|
||||
result.push('${start}..${end}');
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return result.join(seperator);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -209,14 +209,7 @@ class XMLUtil {
|
||||
if (anim.has.y) animData.y = Std.parseFloat(anim.att.y).getDefault(animData.y);
|
||||
if (anim.has.loop) animData.loop = anim.att.loop == "true";
|
||||
if (anim.has.forced) animData.forced = anim.att.forced == "true";
|
||||
if (anim.has.indices) {
|
||||
var indicesSplit = anim.att.indices.split(",");
|
||||
for(indice in indicesSplit) {
|
||||
var i = Std.parseInt(indice.trim());
|
||||
if (i != null)
|
||||
animData.indices.push(i);
|
||||
}
|
||||
}
|
||||
if (anim.has.indices) animData.indices = CoolUtil.parseNumberRange(anim.att.indices);
|
||||
|
||||
return animData;
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ class CharacterAnimScreen extends UISubstateWindow {
|
||||
addLabelOn(loopedCheckbox, "Looping");
|
||||
loopedCheckbox.x += 8; loopedCheckbox.y += 6;
|
||||
|
||||
indicesTextBox = new UITextBox(nameTextBox.x, nameTextBox.y + 32 + 40, animData.indices.join(", "), 270);
|
||||
indicesTextBox = new UITextBox(nameTextBox.x, nameTextBox.y + 32 + 40, CoolUtil.formatNumberRange(animData.indices, ", "), 270);
|
||||
add(indicesTextBox);
|
||||
addLabelOn(indicesTextBox, "Indices");
|
||||
|
||||
@@ -109,14 +109,8 @@ class CharacterAnimScreen extends UISubstateWindow {
|
||||
animType: NONE,
|
||||
x: offsetXStepper.value,
|
||||
y: offsetYStepper.value,
|
||||
indices: []
|
||||
indices: CoolUtil.parseNumberRange(indicesTextBox.label.text)
|
||||
};
|
||||
var indicesSplit = indicesTextBox.label.text.split(",");
|
||||
for(indice in indicesSplit) {
|
||||
var i = Std.parseInt(indice.trim());
|
||||
if (i != null)
|
||||
animData.indices.push(i);
|
||||
}
|
||||
|
||||
if (onSave != null) onSave(animData);
|
||||
}
|
||||
|
||||
@@ -194,8 +194,10 @@ class CharacterInfoScreen extends UISubstateWindow {
|
||||
var offset:FlxPoint = character.getAnimOffset(anim.name);
|
||||
animXml.set("x", Std.string(offset.x));
|
||||
animXml.set("y", Std.string(offset.y));
|
||||
offset.put();
|
||||
|
||||
if (anim.indices.length > 0)
|
||||
animXml.set("indices", anim.indices.join(","));
|
||||
animXml.set("indices", CoolUtil.formatNumberRange(anim.indices));
|
||||
xml.addChild(animXml);
|
||||
}
|
||||
|
||||
|
||||
@@ -396,7 +396,7 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset
|
||||
offset.putWeak();
|
||||
|
||||
if (anim.indices.length > 0)
|
||||
animXml.set("indices", anim.indices.join(","));
|
||||
animXml.set("indices", CoolUtil.formatNumberRange(anim.indices));
|
||||
|
||||
xml.addChild(animXml);
|
||||
}
|
||||
|
||||
@@ -1261,7 +1261,7 @@ class PlayState extends MusicBeatState
|
||||
if (Conductor.songPosition >= 0)
|
||||
startSong();
|
||||
}
|
||||
} else {
|
||||
} else if (FlxG.sound.music != null) {
|
||||
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));
|
||||
|
||||
@@ -162,7 +162,7 @@ class MainMenuState extends MusicBeatState
|
||||
{
|
||||
case 'story mode': FlxG.switchState(new StoryMenuState());
|
||||
case 'freeplay': FlxG.switchState(new FreeplayState());
|
||||
case 'donate': FlxG.switchState(new CreditsMain());
|
||||
case 'donate', 'credits': FlxG.switchState(new CreditsMain()); // kept donate for not breaking scripts, if you dont want donate to bring you to the credits menu, thats easy softcodable - Nex
|
||||
case 'options': FlxG.switchState(new OptionsMenu());
|
||||
}
|
||||
});
|
||||
|
||||
@@ -4,9 +4,11 @@ import funkin.options.OptionsScreen;
|
||||
import funkin.options.TreeMenu;
|
||||
import funkin.options.type.*;
|
||||
import haxe.xml.Access;
|
||||
import flixel.util.FlxColor;
|
||||
|
||||
class CreditsMain extends TreeMenu {
|
||||
var bg:FlxSprite;
|
||||
var items:Array<OptionType> = [];
|
||||
|
||||
public override function create() {
|
||||
bg = new FlxSprite(-80).loadGraphic(Paths.image('menus/menuBGBlue'));
|
||||
@@ -18,7 +20,6 @@ class CreditsMain extends TreeMenu {
|
||||
bg.antialiasing = true;
|
||||
add(bg);
|
||||
|
||||
var selectables:Array<OptionType> = [];
|
||||
var xmlPath = Paths.xml('config/credits');
|
||||
for(source in [funkin.backend.assets.AssetsLibraryList.AssetSource.SOURCE, funkin.backend.assets.AssetsLibraryList.AssetSource.MODS]) {
|
||||
if (Paths.assetsTree.existsSpecific(xmlPath, "TEXT", source)) {
|
||||
@@ -31,17 +32,17 @@ class CreditsMain extends TreeMenu {
|
||||
|
||||
if (access != null)
|
||||
for(c in parseCreditsFromXML(access, source))
|
||||
selectables.push(c);
|
||||
items.push(c);
|
||||
}
|
||||
}
|
||||
selectables.push(new TextOption("Codename Engine >", "Select this to see all the contributors of the engine!", function() {
|
||||
items.push(new TextOption("Codename Engine >", "Select this to see all the contributors of the engine!", function() {
|
||||
optionsTree.add(Type.createInstance(CreditsCodename, []));
|
||||
}));
|
||||
selectables.push(new TextOption("Friday Night Funkin'", "Select this to open the itch.io page of the original game to donate!", function() {
|
||||
items.push(new TextOption("Friday Night Funkin'", "Select this to open the itch.io page of the original game to donate!", function() {
|
||||
CoolUtil.openURL("https://ninja-muffin24.itch.io/funkin");
|
||||
}));
|
||||
|
||||
main = new OptionsScreen('Credits', 'The people who made this possible!', selectables);
|
||||
main = new OptionsScreen('Credits', 'The people who made this possible!', items);
|
||||
super.create();
|
||||
|
||||
DiscordUtil.call("onMenuLoaded", ["Credits Menu"]);
|
||||
@@ -68,11 +69,13 @@ class CreditsMain extends TreeMenu {
|
||||
html_url: 'https://github.com/$username',
|
||||
avatar_url: 'https://github.com/$username.png'
|
||||
};
|
||||
|
||||
credsMenus.push(new GithubIconOption(user, desc, null,
|
||||
var opt:GithubIconOption = new GithubIconOption(user, desc, null,
|
||||
node.has.customName ? node.att.customName : null, node.has.size ? Std.parseInt(node.att.size) : 96,
|
||||
node.has.portrait ? node.att.portrait.toLowerCase() == "false" ? false : true : true
|
||||
));
|
||||
);
|
||||
if (node.has.color)
|
||||
@:privateAccess opt.__text.color = FlxColor.fromString(node.att.color);
|
||||
credsMenus.push(opt);
|
||||
} else {
|
||||
if (!node.has.name) {
|
||||
Logs.trace("[CreditsMain] A credit node requires a name attribute.", WARNING);
|
||||
@@ -82,11 +85,14 @@ class CreditsMain extends TreeMenu {
|
||||
|
||||
switch(node.name) {
|
||||
case "credit":
|
||||
credsMenus.push(new PortraitOption(name, desc, function() if(node.has.url) CoolUtil.openURL(node.att.url),
|
||||
var opt:PortraitOption = new PortraitOption(name, desc, function() if(node.has.url) CoolUtil.openURL(node.att.url),
|
||||
node.has.icon && Paths.assetsTree.existsSpecific(Paths.image('credits/${node.att.icon}'), "IMAGE", source) ?
|
||||
FlxG.bitmap.add(Paths.image('credits/${node.att.icon}')) : null, node.has.size ? Std.parseInt(node.att.size) : 96,
|
||||
node.has.portrait ? node.att.portrait.toLowerCase() == "false" ? false : true : true
|
||||
));
|
||||
);
|
||||
if (node.has.color)
|
||||
@:privateAccess opt.__text.color = FlxColor.fromString(node.att.color);
|
||||
credsMenus.push(opt);
|
||||
|
||||
case "menu":
|
||||
credsMenus.push(new TextOption(name + " >", desc, function() {
|
||||
@@ -98,4 +104,4 @@ class CreditsMain extends TreeMenu {
|
||||
|
||||
return credsMenus;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||