diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml
index 4f1084dc..1efcfcfa 100644
--- a/.github/workflows/linux.yml
+++ b/.github/workflows/linux.yml
@@ -38,12 +38,12 @@ jobs:
- name: Tar files
run: tar -zcvf CodenameEngine.tar.gz -C export/release/linux/bin .
- name: Uploading artifact (entire build)
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v4
with:
name: Codename Engine
path: CodenameEngine.tar.gz
# - name: Uploading artifact (executable)
- # uses: actions/upload-artifact@v2
+ # uses: actions/upload-artifact@v4
# with:
# name: Update-Linux
# path: export/release/linux/bin/CodenameEngine
diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml
index c11a793f..cdd60670 100644
--- a/.github/workflows/macos.yml
+++ b/.github/workflows/macos.yml
@@ -35,12 +35,12 @@ jobs:
- name: Tar files
run: tar -zcvf CodenameEngine.tar.gz -C export/release/macos/bin .
- name: Uploading artifact (entire build)
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v4
with:
name: Codename Engine
path: CodenameEngine.tar.gz
# - name: Uploading artifact (executable)
- # uses: actions/upload-artifact@v2
+ # uses: actions/upload-artifact@v4
# with:
# name: Update-Mac
# path: export/release/macos/bin/CodenameEngine
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
index 3ec71f90..2986be18 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/windows.yml
@@ -33,12 +33,12 @@ jobs:
run: |
haxelib run lime build windows
- name: Uploading artifact (entire build)
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v4
with:
name: Codename Engine
path: export/release/windows/bin
# - name: Uploading artifact (executable)
- # uses: actions/upload-artifact@v2
+ # uses: actions/upload-artifact@v4
# with:
# name: Update-Windows
# path: export/release/windows/bin/CodenameEngine.exe
diff --git a/BETAMESSAGE.md b/BETAMESSAGE.md
index 38685be3..cf86b374 100644
--- a/BETAMESSAGE.md
+++ b/BETAMESSAGE.md
@@ -35,7 +35,7 @@ Shoutout to the people who stuck with us throughout the alpha and supported us!
- ### New Features
- Opponent & Co-op modes
- New volume change SFX (no more loud flixel beep, customizable)
- - New FPS counter allowing you to see advanced info by pressing F3.
+ - New FPS counter allowing you to see advanced info by pressing F3 (infos can be selected and copied too when in advanced).
- (Windows) FNF is no longer blurry on 125-150% DPI
- FNF auto fixes audio on state change when you plug in/out your headphones.
- FNF auto applies dark titlebar
diff --git a/FEATURES.md b/FEATURES.md
index 9d53fcaf..caa85417 100644
--- a/FEATURES.md
+++ b/FEATURES.md
@@ -17,7 +17,7 @@ _**QOL = Quality of Life**_
- Usage of [flxanimate](https://github.com/Dot-Stuff/flxanimate) on big sprites, such as Girlfriend to save memory.
- You can further optimize it on certain stages by enabling `Low Memory Mode` in `Options > Appearance`.
- New volume change SFX (no more loud flixel beep, customizable)
-- New FPS counter allowing you to see advanced info by pressing F3.
+- New FPS counter allowing you to see advanced info by pressing F3 (infos can be selected and copied too when in advanced).
- Simple but advanced modding system (press TAB on main menu)
- **Windows only:**
- (Windows) FNF is no longer blurry on 125-150% DPI
diff --git a/assets/data/scripts/pixel.hx b/assets/data/scripts/pixel.hx
index 0b3f0c59..8f1887c8 100644
--- a/assets/data/scripts/pixel.hx
+++ b/assets/data/scripts/pixel.hx
@@ -163,16 +163,18 @@ function postUpdate(elapsed) {
if (enableCameraHacks) {
for(p in strumLines)
p.notes.forEach(function(n) {
+ if(n.isSustainNote) return; // hacky fix for hold
n.y -= n.y % daPixelZoom;
n.x -= n.x % daPixelZoom;
});
}
+ var zoom = 1 / daPixelZoom / Math.min(FlxG.scaleMode.scale.x, FlxG.scaleMode.scale.y);
for(e in pixellyCameras) {
if (!e.exists) continue;
- e.zoom = 1 / daPixelZoom / Math.min(FlxG.scaleMode.scale.x, FlxG.scaleMode.scale.y);
+ e.zoom = zoom;
}
for(e in pixellyShaders) {
- e.pixelZoom = 1 / daPixelZoom / Math.min(FlxG.scaleMode.scale.x, FlxG.scaleMode.scale.y);
+ e.pixelZoom = zoom;
}
}
\ No newline at end of file
diff --git a/assets/data/scripts/week6-pause.hx b/assets/data/scripts/week6-pause.hx
index 9b93200c..f5fa3394 100644
--- a/assets/data/scripts/week6-pause.hx
+++ b/assets/data/scripts/week6-pause.hx
@@ -73,7 +73,8 @@ function confText(text) {
}
function destroy() {
- FlxG.cameras.remove(pauseCam);
+ if(FlxG.cameras.list.contains(pauseCam))
+ FlxG.cameras.remove(pauseCam);
}
var canDoShit = true;
diff --git a/assets/data/stages/philly.hx b/assets/data/stages/philly.hx
index 989b29b5..6b120b51 100644
--- a/assets/data/stages/philly.hx
+++ b/assets/data/stages/philly.hx
@@ -1,3 +1,4 @@
+//
import funkin.game.PlayState;
// phillyTrain is automatically added by Stage.hx
diff --git a/assets/shaders/engine/editorBlur.frag b/assets/shaders/engine/editorBlur.frag
index 937aa028..59b91c72 100644
--- a/assets/shaders/engine/editorBlur.frag
+++ b/assets/shaders/engine/editorBlur.frag
@@ -18,17 +18,17 @@ void main() {
return;
vec4 color = getColor(camPos);
- float fsteps = steps;
- for(float inside = 1.0; inside < stepsInside+1.0; inside++) {
+ float fsteps = float(steps);
+ for(float inside = 1.0; inside < float(stepsInside)+1.0; inside++) {
for(int i = 0; i < steps; i++) {
- float fi = i;
+ float fi = float(i);
color += getColor(camPos + vec2(
- strength * (inside / stepsInside) * cos(fi / fsteps * (PI * 2.0)),
- strength * (inside / stepsInside) * sin(fi / fsteps * (PI * 2.0))
+ strength * (inside / float(stepsInside)) * cos(fi / fsteps * (PI * 2.0)),
+ strength * (inside / float(stepsInside)) * sin(fi / fsteps * (PI * 2.0))
));
}
}
- color /= steps * stepsInside;
+ color /= vec4(steps * stepsInside);
gl_FragColor = color;
-}
\ No newline at end of file
+}
diff --git a/project.xml b/project.xml
index 5432e0f6..20d7d549 100644
--- a/project.xml
+++ b/project.xml
@@ -153,6 +153,8 @@
+
+
@@ -200,6 +202,7 @@
+
diff --git a/source/funkin/backend/FunkinSprite.hx b/source/funkin/backend/FunkinSprite.hx
index 881364a6..e287add6 100644
--- a/source/funkin/backend/FunkinSprite.hx
+++ b/source/funkin/backend/FunkinSprite.hx
@@ -103,7 +103,7 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
if (!debugMode && isAnimFinished()) {
var name = getAnimName() + '-loop';
if (hasAnimation(name))
- playAnim(name, false, lastAnimContext);
+ playAnim(name, null, lastAnimContext);
}
}
@@ -296,11 +296,16 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
#if REGION
public var lastAnimContext:PlayAnimContext = DANCE;
- public function playAnim(AnimName:String, Force:Bool = false, Context:PlayAnimContext = NONE, Reversed:Bool = false, Frame:Int = 0):Void
+ public function playAnim(AnimName:String, ?Force:Null, Context:PlayAnimContext = NONE, Reversed:Bool = false, Frame:Int = 0):Void
{
if (AnimName == null)
return;
+ if (Force == null) {
+ var anim = animDatas.get(AnimName);
+ Force = anim != null && anim.forced;
+ }
+
if (animateAtlas != null)
{
@:privateAccess
diff --git a/source/funkin/backend/chart/EventsData.hx b/source/funkin/backend/chart/EventsData.hx
index eff3fd8e..64b8ce93 100644
--- a/source/funkin/backend/chart/EventsData.hx
+++ b/source/funkin/backend/chart/EventsData.hx
@@ -69,7 +69,11 @@ class EventsData {
hscriptInterp.variables.set("String", TString);
hscriptInterp.variables.set("StrumLine", TStrumLine);
hscriptInterp.variables.set("ColorWheel", TColorWheel);
- hscriptInterp.variables.set("DropDown", Reflect.makeVarArgs((args) -> {return args.length > 0 ? TDropDown([for (arg in args) Std.string(arg)]) : TDropDown(["null"]);}));
+ hscriptInterp.variables.set("DropDown", Reflect.makeVarArgs(function(args:Array):EventParamType {
+ var flatArgs = CoolUtil.deepFlatten(args);
+ if(flatArgs.length == 0) return TDropDown(["null"]);
+ return TDropDown([for (arg in flatArgs) Std.string(arg)]);
+ }));
hscriptInterp.variables.set("Character", TCharacter);
hscriptInterp.variables.set("Stage", TStage);
@@ -77,11 +81,12 @@ class EventsData {
hscriptParser.allowJSON = hscriptParser.allowMetadata = false;
for (file in Paths.getFolderContent('data/events/', true, BOTH)) {
- if (Path.extension(file) != "json" && Path.extension(file) != "pack") continue;
- var eventName:String = Path.withoutExtension(Path.withoutDirectory(file));
+ var ext = Path.extension(file);
+ if (ext != "json" && ext != "pack") continue;
+ var eventName:String = CoolUtil.getFilename(file);
var fileTxt:String = Assets.getText(file);
- if (Path.extension(file) == "pack") {
+ if (ext == "pack") {
var arr = fileTxt.split("________PACKSEP________");
eventName = Path.withoutExtension(arr[0]);
fileTxt = arr[2];
@@ -93,13 +98,17 @@ class EventsData {
eventsParams.set(eventName, []);
try {
- var data:Dynamic = Json.parse(fileTxt);
+ var data:EventInfoFile = cast Json.parse(fileTxt);
if (data == null || data.params == null) continue;
var finalParams:Array = [];
- for (paramData in cast(data.params, Array)) {
+ for (paramData in data.params) {
try {
- finalParams.push({name: paramData.name, type: hscriptInterp.expr(hscriptParser.parseString(paramData.type)), defValue: paramData.defaultValue});
+ finalParams.push({
+ name: paramData.name,
+ type: hscriptInterp.expr(hscriptParser.parseString(paramData.type)),
+ defValue: paramData.defaultValue
+ });
} catch (e) {trace('Error parsing event param ${paramData.name} - ${eventName}: $e'); finalParams.push(null);}
}
eventsParams.set(eventName, finalParams);
@@ -110,6 +119,14 @@ class EventsData {
}
}
+typedef EventInfoFile = {
+ var params:Array<{
+ var name:String;
+ var type:String;
+ var defaultValue:Dynamic;
+ }>;
+}
+
typedef EventInfo = {
var params:Array;
var paramValues:Array;
diff --git a/source/funkin/backend/scripting/events/DirectionAnimEvent.hx b/source/funkin/backend/scripting/events/DirectionAnimEvent.hx
index a23626f4..dce2eaff 100644
--- a/source/funkin/backend/scripting/events/DirectionAnimEvent.hx
+++ b/source/funkin/backend/scripting/events/DirectionAnimEvent.hx
@@ -26,7 +26,7 @@ final class DirectionAnimEvent extends CancellableEvent {
**/
public var frame:Int;
/**
- Force the animation to replay even if it's already playing.
+ Force the animation to replay even if it's already playing (if it's null it will be forced based on the sprite's data xml, if it has one).
**/
- public var force:Bool = true;
+ public var force:Null;
}
diff --git a/source/funkin/backend/scripting/events/NoteHitEvent.hx b/source/funkin/backend/scripting/events/NoteHitEvent.hx
index d5f64dc3..4bac078e 100644
--- a/source/funkin/backend/scripting/events/NoteHitEvent.hx
+++ b/source/funkin/backend/scripting/events/NoteHitEvent.hx
@@ -100,9 +100,9 @@ final class NoteHitEvent extends CancellableEvent {
*/
public var ratingAntialiasing:Bool = true;
/**
- * Whenever the animation should be forced to play.
+ * Whenever the animation should be forced to play (if it's null it will be forced based on the sprite's data xml, if it has one).
*/
- public var forceAnim:Bool = true;
+ public var forceAnim:Null = true;
/**
* Prevents the default sing animation from being played.
diff --git a/source/funkin/backend/scripting/events/NoteMissEvent.hx b/source/funkin/backend/scripting/events/NoteMissEvent.hx
index e9475bb0..72f87ddd 100644
--- a/source/funkin/backend/scripting/events/NoteMissEvent.hx
+++ b/source/funkin/backend/scripting/events/NoteMissEvent.hx
@@ -29,9 +29,9 @@ final class NoteMissEvent extends CancellableEvent {
public var gfSadAnim:String;
public var forceGfAnim:Bool;
/**
- * Whenever the animation should be forced to play.
+ * Whenever the animation should be forced to play (if it's null it will be forced based on the sprite's data xml, if it has one).
*/
- public var forceAnim:Bool;
+ public var forceAnim:Null;
/**
* Suffix of the animation. "miss" for miss notes, "-alt" for alt notes, "" for normal ones.
*/
diff --git a/source/funkin/backend/scripting/events/PlayAnimEvent.hx b/source/funkin/backend/scripting/events/PlayAnimEvent.hx
index a555c3ed..f51c8243 100644
--- a/source/funkin/backend/scripting/events/PlayAnimEvent.hx
+++ b/source/funkin/backend/scripting/events/PlayAnimEvent.hx
@@ -7,9 +7,9 @@ final class PlayAnimEvent extends CancellableEvent {
public var animName:String;
/**
- Whenever the animation will be forced or not.
+ Whenever the animation will be forced or not (if it's null it will be forced based on the sprite's data xml, if it has one).
**/
- public var force:Bool;
+ public var force:Null;
/**
Whenever the animation will play in reverse or not
diff --git a/source/funkin/backend/system/framerate/Framerate.hx b/source/funkin/backend/system/framerate/Framerate.hx
index c321b1db..7e8e3f8e 100644
--- a/source/funkin/backend/system/framerate/Framerate.hx
+++ b/source/funkin/backend/system/framerate/Framerate.hx
@@ -125,9 +125,16 @@ class Framerate extends Sprite {
bgSprite.scaleX = width;
bgSprite.scaleY = height;
- var y:Float = height + 4;
+ var selectable = debugMode == 2;
+ { // idk i tried to make it more lookable:sob: - Nex
+ memoryCounter.memoryText.selectable = memoryCounter.memoryPeakText.selectable =
+ fpsCounter.fpsNum.selectable = fpsCounter.fpsLabel.selectable =
+ #if SHOW_BUILD_ON_FPS codenameBuildField.selectable = #end selectable;
+ }
+ var y:Float = height + 4;
for(c in categories) {
+ c.title.selectable = c.text.selectable = selectable;
c.alpha = debugAlpha;
c.x = FlxMath.lerp(-c.width - offset.x, 0, debugAlpha);
c.y = y;
diff --git a/source/funkin/backend/system/framerate/FramerateCategory.hx b/source/funkin/backend/system/framerate/FramerateCategory.hx
index a862505c..db89137f 100644
--- a/source/funkin/backend/system/framerate/FramerateCategory.hx
+++ b/source/funkin/backend/system/framerate/FramerateCategory.hx
@@ -29,6 +29,7 @@ class FramerateCategory extends Sprite {
label.x = 0;
label.y = 0;
label.defaultTextFormat = new TextFormat(Framerate.fontName, label == this.title ? 18 : 12, -1);
+ label.selectable = false;
addChild(label);
}
this.title.text = title;
@@ -51,4 +52,4 @@ class FramerateCategory extends Sprite {
bgSprite.scaleX = width;
bgSprite.scaleY = height;
}
-}
\ No newline at end of file
+}
diff --git a/source/funkin/backend/system/framerate/FramerateCounter.hx b/source/funkin/backend/system/framerate/FramerateCounter.hx
index 5658bd2b..d6ff4b67 100644
--- a/source/funkin/backend/system/framerate/FramerateCounter.hx
+++ b/source/funkin/backend/system/framerate/FramerateCounter.hx
@@ -1,28 +1,17 @@
package funkin.backend.system.framerate;
-import haxe.ds.Vector;
import openfl.display.Sprite;
import openfl.text.TextField;
import openfl.text.TextFormat;
-inline final FRAME_TIME_HISTORY = 20;
-
class FramerateCounter extends Sprite {
public var fpsNum:TextField;
public var fpsLabel:TextField;
-
- public var fpsHistoryIndex:Int = 0;
- public var fpsHistory:Vector;
+ public var lastFPS:Float = 0;
public function new() {
super();
- fpsHistory = new Vector(FRAME_TIME_HISTORY);
- // Initialize to 60 FPS, so that the initial estimation until we get enough data is always reasonable.
- for(i in 0...FRAME_TIME_HISTORY) {
- fpsHistory[i] = 1000.0 / 60.0;
- }
-
fpsNum = new TextField();
fpsLabel = new TextField();
@@ -33,6 +22,7 @@ class FramerateCounter extends Sprite {
label.text = "FPS";
label.multiline = label.wordWrap = false;
label.defaultTextFormat = new TextFormat(Framerate.fontName, label == fpsNum ? 18 : 12, -1);
+ label.selectable = false;
addChild(label);
}
}
@@ -43,21 +33,9 @@ class FramerateCounter extends Sprite {
if (alpha <= 0.05) return;
super.__enterFrame(t);
- // todo use gpu time
- fpsHistory[fpsHistoryIndex] = FlxG.elapsed * 1000;
- fpsHistoryIndex = (fpsHistoryIndex + 1) % FRAME_TIME_HISTORY;
-
- // Calculate average CPU time.
- // Code based on Godot's FPS counter.
- var cpuTime = 0.0;
- for(i in 0...FRAME_TIME_HISTORY) {
- cpuTime += fpsHistory[i];
- }
- cpuTime /= FRAME_TIME_HISTORY;
- cpuTime = Math.max(0.01, cpuTime); // Prevent unrealistically low values.
-
- fpsNum.text = Std.string(Math.floor(1000.0 / cpuTime));
+ lastFPS = CoolUtil.fpsLerp(lastFPS, FlxG.elapsed == 0 ? 0 : (1 / FlxG.elapsed), 0.25);
+ fpsNum.text = Std.string(Math.floor(lastFPS));
fpsLabel.x = fpsNum.x + fpsNum.width;
fpsLabel.y = (fpsNum.y + fpsNum.height) - fpsLabel.height;
}
-}
\ No newline at end of file
+}
diff --git a/source/funkin/backend/system/framerate/MemoryCounter.hx b/source/funkin/backend/system/framerate/MemoryCounter.hx
index f38de1d8..1c26a27d 100644
--- a/source/funkin/backend/system/framerate/MemoryCounter.hx
+++ b/source/funkin/backend/system/framerate/MemoryCounter.hx
@@ -24,6 +24,7 @@ class MemoryCounter extends Sprite {
label.text = "FPS";
label.multiline = label.wordWrap = false;
label.defaultTextFormat = new TextFormat(Framerate.fontName, 12, -1);
+ label.selectable = false;
addChild(label);
}
memoryPeakText.alpha = 0.5;
@@ -42,4 +43,4 @@ class MemoryCounter extends Sprite {
memoryPeakText.x = memoryText.x + memoryText.width;
}
-}
\ No newline at end of file
+}
diff --git a/source/funkin/backend/utils/CoolUtil.hx b/source/funkin/backend/utils/CoolUtil.hx
index 681b93fe..79563188 100644
--- a/source/funkin/backend/utils/CoolUtil.hx
+++ b/source/funkin/backend/utils/CoolUtil.hx
@@ -721,7 +721,7 @@ class CoolUtil
*/
@:noUsing public static inline function openURL(url:String) {
#if linux
- Sys.command('/usr/bin/xdg-open', [url, "&"]);
+ Sys.command('/usr/bin/xdg-open', [url]);
#else
FlxG.openURL(url);
#end
@@ -906,6 +906,19 @@ class CoolUtil
return result.join(seperator);
}
+
+ public static function deepFlatten(arr:Array, ?result:Array):Array {
+ if(arr == null) return [];
+ if(result == null) result = [];
+ for (e in arr) {
+ if (Std.isOfType(e, Array)) {
+ deepFlatten(e, result);
+ } else {
+ result.push(e);
+ }
+ }
+ return result;
+ }
}
/**
@@ -918,4 +931,4 @@ enum abstract CoolSfx(Int) from Int {
var CHECKED = 3;
var UNCHECKED = 4;
var WARNING = 5;
-}
\ No newline at end of file
+}
diff --git a/source/funkin/backend/utils/FunkinParentDisabler.hx b/source/funkin/backend/utils/FunkinParentDisabler.hx
index 07e71a2a..8e9554cc 100644
--- a/source/funkin/backend/utils/FunkinParentDisabler.hx
+++ b/source/funkin/backend/utils/FunkinParentDisabler.hx
@@ -32,8 +32,8 @@ class FunkinParentDisabler extends FlxBasic {
FlxTimer.globalManager._timers = [];
// cameras
- __cameras = [for(c in FlxG.cameras.list) if (c.active) c];
- for(c in __cameras) c.active = false;
+ __cameras = [for(c in FlxG.cameras.list) if (!c.paused) c];
+ for(c in __cameras) c.paused = true;
// sounds
__sounds = [for(s in FlxG.sound.list) if (s.playing) s];
@@ -41,9 +41,6 @@ class FunkinParentDisabler extends FlxBasic {
}
}
- public override function update(elapsed:Float) {
- @:privateAccess for(c in __cameras) c.updateFlashSpritePosition();
- }
public override function draw() {}
public function reset() {
@@ -63,7 +60,7 @@ class FunkinParentDisabler extends FlxBasic {
for(t in __tweens) FlxTween.globalManager._tweens.push(t);
for(t in __timers) FlxTimer.globalManager._timers.push(t);
}
- for(c in __cameras) c.active = true;
+ for(c in __cameras) c.paused = false;
for(s in __sounds) s.play();
}
}
diff --git a/source/funkin/backend/utils/XMLUtil.hx b/source/funkin/backend/utils/XMLUtil.hx
index 8f0ceb9d..b9fad85d 100644
--- a/source/funkin/backend/utils/XMLUtil.hx
+++ b/source/funkin/backend/utils/XMLUtil.hx
@@ -4,6 +4,7 @@ import flixel.util.FlxColor;
import flixel.util.typeLimit.OneOfTwo;
import funkin.backend.FunkinSprite.XMLAnimType;
import funkin.backend.FunkinSprite;
+import funkin.game.Character;
import funkin.backend.system.ErrorCode;
import funkin.backend.system.interfaces.IOffsetCompatible;
import haxe.xml.Access;
@@ -172,8 +173,7 @@ class XMLUtil {
animType: spr.spriteAnimType,
x: 0,
y: 0,
- indices: [for(i in 0...spr.frames.frames.length) i],
- forced: (node.has.forced && node.att.forced == "true") || (!node.has.forced && spr.spriteAnimType == BEAT)
+ indices: [for(i in 0...spr.frames.frames.length) i]
});
}
}
@@ -199,8 +199,7 @@ class XMLUtil {
animType: animType,
x: 0,
y: 0,
- indices: [],
- forced: false,
+ indices: []
};
if (anim.has.name) animData.name = anim.att.name;
@@ -256,24 +255,28 @@ class XMLUtil {
if (sprite is FunkinSprite) {
var xmlSpr = cast(sprite, FunkinSprite);
+ var name = animData.name;
switch(animData.animType) {
case BEAT:
xmlSpr.beatAnims.push({
- name: animData.name,
- forced: animData.forced.getDefault(false)
+ name: name,
+ forced: animData.forced.getDefault(defaultForcedCheck(name, xmlSpr))
});
case LOOP:
- xmlSpr.playAnim(animData.name, animData.forced.getDefault(false));
+ xmlSpr.playAnim(name, animData.forced.getDefault(defaultForcedCheck(name, xmlSpr)));
default:
// nothing
}
- xmlSpr.animDatas.set(animData.name, animData);
+ xmlSpr.animDatas.set(name, animData);
}
return OK;
}
return MISSING_PROPERTY;
}
+ public static inline function defaultForcedCheck(animName:String, sprite:FunkinSprite):Bool
+ return sprite is Character && (animName.startsWith("idle") || animName.startsWith("danceLeft") || animName.startsWith("danceRight")) ? false : sprite.spriteAnimType == BEAT;
+
public static inline function fixXMLText(text:String) {
var v:String;
return [for(l in text.split("\n")) if ((v = l.trim()) != "") v].join("\n");
diff --git a/source/funkin/editors/charter/SongCreationScreen.hx b/source/funkin/editors/charter/SongCreationScreen.hx
index e35744a5..82eadcd9 100644
--- a/source/funkin/editors/charter/SongCreationScreen.hx
+++ b/source/funkin/editors/charter/SongCreationScreen.hx
@@ -98,11 +98,7 @@ class SongCreationScreen extends UISubstateWindow {
voicesExplorer.uiElement = audioPlayer;
});
songDataGroup.add(voicesExplorer);
-
- voicesUIText = addLabelOn(voicesExplorer, "Vocal Audio File");
- voicesUIText.applyMarkup(
- "Vocal Audio File $* Required$",
- [new FlxTextFormatMarkerPair(new FlxTextFormat(0xFFAD1212), "$")]);
+ addLabelOn(voicesExplorer, "Vocal Audio File");
var menuTitle:UIText;
menuDataGroup.add(menuTitle = new UIText(windowSpr.x + 20, windowSpr.y + 30 + 16, 0, "Menus Data (Freeplay/Story)", 28));
diff --git a/source/funkin/game/Character.hx b/source/funkin/game/Character.hx
index d480f54c..7e0db93f 100644
--- a/source/funkin/game/Character.hx
+++ b/source/funkin/game/Character.hx
@@ -235,7 +235,7 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset
/**
* Like `playSingAnimUnsafe` but checks if the character has the animation with the suffix part, otherwise it plays the animation without the suffix part.
*/
- public function playSingAnim(direction:Int, suffix:String = "", Context:PlayAnimContext = SING, Force:Bool = true, Reversed:Bool = false, Frame:Int = 0)
+ public function playSingAnim(direction:Int, suffix:String = "", Context:PlayAnimContext = SING, ?Force:Null = null, Reversed:Bool = false, Frame:Int = 0)
{
var event = EventManager.get(DirectionAnimEvent).recycle(getSingAnim(direction, suffix), direction, suffix, Context, Reversed, Frame, Force);
script.call("onPlaySingAnim", [event]);
@@ -252,7 +252,7 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset
playAnim(event.animName, event.force, event.context, event.reversed, event.frame);
}
- public override function playAnim(AnimName:String, Force:Bool = false, Context:PlayAnimContext = NONE, Reversed:Bool = false, Frame:Int = 0) {
+ public override function playAnim(AnimName:String, ?Force:Bool, Context:PlayAnimContext = NONE, Reversed:Bool = false, Frame:Int = 0) {
var event = EventManager.get(PlayAnimEvent).recycle(AnimName, Force, Reversed, Frame, Context);
script.call("onPlayAnim", [event]);
if (event.cancelled) return;
@@ -323,6 +323,7 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset
public inline function buildCharacter(xml:Access) {
this.xml = xml; // Modders wassup :D
sprite = curCharacter;
+ spriteAnimType = BEAT;
if (xml.x.exists("isPlayer")) playerOffsets = (xml.x.get("isPlayer") == "true");
if (xml.x.exists("x")) globalOffset.x = Std.parseFloat(xml.x.get("x"));
diff --git a/source/funkin/game/PlayState.hx b/source/funkin/game/PlayState.hx
index 09acc704..28523240 100644
--- a/source/funkin/game/PlayState.hx
+++ b/source/funkin/game/PlayState.hx
@@ -675,10 +675,12 @@ class PlayState extends MusicBeatState
chars.push(char);
}
- var strOffset:Float = strumLine.strumLinePos == null ? (strumLine.type == 1 ? 0.75 : 0.25) : strumLine.strumLinePos;
- 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 strOffset:Float = strumLine.strumLinePos != null ? strumLine.strumLinePos : (strumLine.type == 1 ? 0.75 : 0.25);
+ var strScale:Float = strumLine.strumScale != null ? strumLine.strumScale : 1;
+ var strXPos:Float = (FlxG.width * strOffset) - (Note.swagWidth * strScale * 2);
+ var startingPos:FlxPoint = strumLine.strumPos != null ?
+ FlxPoint.get(strumLine.strumPos[0] == 0 ? strXPos : strumLine.strumPos[0], strumLine.strumPos[1]) :
+ FlxPoint.get(strXPos, this.strumLine.y);
var strLine = new StrumLine(chars,
startingPos,
strumLine.strumScale == null ? 1 : strumLine.strumScale,
@@ -1954,7 +1956,7 @@ class PlayState extends MusicBeatState
}
}
-class ComboRating {
+final class ComboRating {
public var percent:Float;
public var rating:String;
public var color:FlxColor;
diff --git a/source/funkin/game/StrumLine.hx b/source/funkin/game/StrumLine.hx
index 66985469..ffb5dac6 100644
--- a/source/funkin/game/StrumLine.hx
+++ b/source/funkin/game/StrumLine.hx
@@ -152,7 +152,12 @@ class StrumLine extends FlxTypedGroup {
var scrollSpeed = strumLine.scrollSpeed;
if(scrollSpeed == null) if (PlayState.instance != null) scrollSpeed = PlayState.instance.scrollSpeed;
if(scrollSpeed == null) scrollSpeed = 1;
- notes.limit = Constants.DEFAULT_NOTE_MS_LIMIT / scrollSpeed;
+
+ // TODO: Make this work by accounting zoom and scrollspeed changes - Nex
+ /*var limit = FlxG.height / 0.45;
+ notes.limit = limit / scrollSpeed;
+ OR
+ notes.limit = Constants.DEFAULT_NOTE_MS_LIMIT / scrollSpeed;*/
}
public override function update(elapsed:Float) {
diff --git a/source/funkin/game/cutscenes/dialogue/DialogueBox.hx b/source/funkin/game/cutscenes/dialogue/DialogueBox.hx
index 988562f3..a37143ef 100644
--- a/source/funkin/game/cutscenes/dialogue/DialogueBox.hx
+++ b/source/funkin/game/cutscenes/dialogue/DialogueBox.hx
@@ -97,7 +97,7 @@ class DialogueBox extends FunkinSprite {
dialogueBoxScript.call("postCreate");
}
- public override function playAnim(AnimName:String, Force:Bool = false, Context:PlayAnimContext = NONE, Reversed:Bool = false, Frame:Int = 0) {
+ public override function playAnim(AnimName:String, ?Force:Bool, Context:PlayAnimContext = NONE, Reversed:Bool = false, Frame:Int = 0) {
var event = EventManager.get(PlayAnimEvent).recycle(AnimName, Force, Reversed, Frame, Context);
dialogueBoxScript.call("onPlayAnim", [event]);
if(event.cancelled) return;
diff --git a/source/funkin/game/cutscenes/dialogue/DialogueCharacter.hx b/source/funkin/game/cutscenes/dialogue/DialogueCharacter.hx
index f59bef13..3fa06f54 100644
--- a/source/funkin/game/cutscenes/dialogue/DialogueCharacter.hx
+++ b/source/funkin/game/cutscenes/dialogue/DialogueCharacter.hx
@@ -62,7 +62,7 @@ class DialogueCharacter extends FunkinSprite {
dialogueCharScript.call("postCreate");
}
- public override function playAnim(AnimName:String, Force:Bool = false, Context:PlayAnimContext = NONE, Reversed:Bool = false, Frame:Int = 0) {
+ public override function playAnim(AnimName:String, ?Force:Bool, Context:PlayAnimContext = NONE, Reversed:Bool = false, Frame:Int = 0) {
var event = EventManager.get(PlayAnimEvent).recycle(AnimName, Force, Reversed, Frame, Context);
dialogueCharScript.call("playAnim", [event]);
if(event.cancelled) return;