Merge branch 'main' into base-fnf-port-remake

This commit is contained in:
⍚~Nex
2024-09-14 16:19:13 +02:00
29 changed files with 129 additions and 96 deletions
+2 -2
View File
@@ -38,12 +38,12 @@ jobs:
- name: Tar files - name: Tar files
run: tar -zcvf CodenameEngine.tar.gz -C export/release/linux/bin . run: tar -zcvf CodenameEngine.tar.gz -C export/release/linux/bin .
- name: Uploading artifact (entire build) - name: Uploading artifact (entire build)
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v4
with: with:
name: Codename Engine name: Codename Engine
path: CodenameEngine.tar.gz path: CodenameEngine.tar.gz
# - name: Uploading artifact (executable) # - name: Uploading artifact (executable)
# uses: actions/upload-artifact@v2 # uses: actions/upload-artifact@v4
# with: # with:
# name: Update-Linux # name: Update-Linux
# path: export/release/linux/bin/CodenameEngine # path: export/release/linux/bin/CodenameEngine
+2 -2
View File
@@ -35,12 +35,12 @@ jobs:
- name: Tar files - name: Tar files
run: tar -zcvf CodenameEngine.tar.gz -C export/release/macos/bin . run: tar -zcvf CodenameEngine.tar.gz -C export/release/macos/bin .
- name: Uploading artifact (entire build) - name: Uploading artifact (entire build)
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v4
with: with:
name: Codename Engine name: Codename Engine
path: CodenameEngine.tar.gz path: CodenameEngine.tar.gz
# - name: Uploading artifact (executable) # - name: Uploading artifact (executable)
# uses: actions/upload-artifact@v2 # uses: actions/upload-artifact@v4
# with: # with:
# name: Update-Mac # name: Update-Mac
# path: export/release/macos/bin/CodenameEngine # path: export/release/macos/bin/CodenameEngine
+2 -2
View File
@@ -33,12 +33,12 @@ jobs:
run: | run: |
haxelib run lime build windows haxelib run lime build windows
- name: Uploading artifact (entire build) - name: Uploading artifact (entire build)
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v4
with: with:
name: Codename Engine name: Codename Engine
path: export/release/windows/bin path: export/release/windows/bin
# - name: Uploading artifact (executable) # - name: Uploading artifact (executable)
# uses: actions/upload-artifact@v2 # uses: actions/upload-artifact@v4
# with: # with:
# name: Update-Windows # name: Update-Windows
# path: export/release/windows/bin/CodenameEngine.exe # path: export/release/windows/bin/CodenameEngine.exe
+1 -1
View File
@@ -35,7 +35,7 @@ Shoutout to the people who stuck with us throughout the alpha and supported us!
- ### New Features - ### New Features
- Opponent & Co-op modes - Opponent & Co-op modes
- New volume change SFX (no more loud flixel beep, customizable) - 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 - (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 fixes audio on state change when you plug in/out your headphones.
- FNF auto applies dark titlebar - FNF auto applies dark titlebar
+1 -1
View File
@@ -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. - 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`. - 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 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) - Simple but advanced modding system (press TAB on main menu)
- **Windows only:** - **Windows only:**
- (Windows) FNF is no longer blurry on 125-150% DPI - (Windows) FNF is no longer blurry on 125-150% DPI
+4 -2
View File
@@ -163,16 +163,18 @@ function postUpdate(elapsed) {
if (enableCameraHacks) { if (enableCameraHacks) {
for(p in strumLines) for(p in strumLines)
p.notes.forEach(function(n) { p.notes.forEach(function(n) {
if(n.isSustainNote) return; // hacky fix for hold
n.y -= n.y % daPixelZoom; n.y -= n.y % daPixelZoom;
n.x -= n.x % daPixelZoom; n.x -= n.x % daPixelZoom;
}); });
} }
var zoom = 1 / daPixelZoom / Math.min(FlxG.scaleMode.scale.x, FlxG.scaleMode.scale.y);
for(e in pixellyCameras) { for(e in pixellyCameras) {
if (!e.exists) continue; 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) { for(e in pixellyShaders) {
e.pixelZoom = 1 / daPixelZoom / Math.min(FlxG.scaleMode.scale.x, FlxG.scaleMode.scale.y); e.pixelZoom = zoom;
} }
} }
+2 -1
View File
@@ -73,7 +73,8 @@ function confText(text) {
} }
function destroy() { function destroy() {
FlxG.cameras.remove(pauseCam); if(FlxG.cameras.list.contains(pauseCam))
FlxG.cameras.remove(pauseCam);
} }
var canDoShit = true; var canDoShit = true;
+1
View File
@@ -1,3 +1,4 @@
//
import funkin.game.PlayState; import funkin.game.PlayState;
// phillyTrain is automatically added by Stage.hx // phillyTrain is automatically added by Stage.hx
+7 -7
View File
@@ -18,17 +18,17 @@ void main() {
return; return;
vec4 color = getColor(camPos); vec4 color = getColor(camPos);
float fsteps = steps; float fsteps = float(steps);
for(float inside = 1.0; inside < stepsInside+1.0; inside++) { for(float inside = 1.0; inside < float(stepsInside)+1.0; inside++) {
for(int i = 0; i < steps; i++) { for(int i = 0; i < steps; i++) {
float fi = i; float fi = float(i);
color += getColor(camPos + vec2( color += getColor(camPos + vec2(
strength * (inside / stepsInside) * cos(fi / fsteps * (PI * 2.0)), strength * (inside / float(stepsInside)) * cos(fi / fsteps * (PI * 2.0)),
strength * (inside / stepsInside) * sin(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; gl_FragColor = color;
} }
+3
View File
@@ -153,6 +153,8 @@
<!-- Comment this out to disable dark mode windows --> <!-- Comment this out to disable dark mode windows -->
<define name="DARK_MODE_WINDOW"/> <define name="DARK_MODE_WINDOW"/>
<haxedef name="analyzer-optimize" />
<haxedef name="VIDEO_CUTSCENES" if="VIDEO_CUTSCENES" /> <haxedef name="VIDEO_CUTSCENES" if="VIDEO_CUTSCENES" />
<haxedef name="UPDATE_CHECKING" if="UPDATE_CHECKING" /> <haxedef name="UPDATE_CHECKING" if="UPDATE_CHECKING" />
<haxedef name="DISCORD_RPC" if="DISCORD_RPC" /> <haxedef name="DISCORD_RPC" if="DISCORD_RPC" />
@@ -200,6 +202,7 @@
<haxedef name="HXCPP_CHECK_POINTER" if="release" /> <haxedef name="HXCPP_CHECK_POINTER" if="release" />
<haxedef name="HXCPP_STACK_LINE" if="release" /> <haxedef name="HXCPP_STACK_LINE" if="release" />
<haxedef name="HXCPP_DEBUG_LINK" if="release" /> <haxedef name="HXCPP_DEBUG_LINK" if="release" />
<haxedef name="HXCPP_CATCH_SEGV" />
<haxedef name="hscriptPos" /> <!-- for logging --> <haxedef name="hscriptPos" /> <!-- for logging -->
</project> </project>
+7 -2
View File
@@ -103,7 +103,7 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
if (!debugMode && isAnimFinished()) { if (!debugMode && isAnimFinished()) {
var name = getAnimName() + '-loop'; var name = getAnimName() + '-loop';
if (hasAnimation(name)) 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 #if REGION
public var lastAnimContext:PlayAnimContext = DANCE; 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<Bool>, Context:PlayAnimContext = NONE, Reversed:Bool = false, Frame:Int = 0):Void
{ {
if (AnimName == null) if (AnimName == null)
return; return;
if (Force == null) {
var anim = animDatas.get(AnimName);
Force = anim != null && anim.forced;
}
if (animateAtlas != null) if (animateAtlas != null)
{ {
@:privateAccess @:privateAccess
+24 -7
View File
@@ -69,7 +69,11 @@ class EventsData {
hscriptInterp.variables.set("String", TString); hscriptInterp.variables.set("String", TString);
hscriptInterp.variables.set("StrumLine", TStrumLine); hscriptInterp.variables.set("StrumLine", TStrumLine);
hscriptInterp.variables.set("ColorWheel", TColorWheel); 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<Dynamic>):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("Character", TCharacter);
hscriptInterp.variables.set("Stage", TStage); hscriptInterp.variables.set("Stage", TStage);
@@ -77,11 +81,12 @@ class EventsData {
hscriptParser.allowJSON = hscriptParser.allowMetadata = false; hscriptParser.allowJSON = hscriptParser.allowMetadata = false;
for (file in Paths.getFolderContent('data/events/', true, BOTH)) { for (file in Paths.getFolderContent('data/events/', true, BOTH)) {
if (Path.extension(file) != "json" && Path.extension(file) != "pack") continue; var ext = Path.extension(file);
var eventName:String = Path.withoutExtension(Path.withoutDirectory(file)); if (ext != "json" && ext != "pack") continue;
var eventName:String = CoolUtil.getFilename(file);
var fileTxt:String = Assets.getText(file); var fileTxt:String = Assets.getText(file);
if (Path.extension(file) == "pack") { if (ext == "pack") {
var arr = fileTxt.split("________PACKSEP________"); var arr = fileTxt.split("________PACKSEP________");
eventName = Path.withoutExtension(arr[0]); eventName = Path.withoutExtension(arr[0]);
fileTxt = arr[2]; fileTxt = arr[2];
@@ -93,13 +98,17 @@ class EventsData {
eventsParams.set(eventName, []); eventsParams.set(eventName, []);
try { try {
var data:Dynamic = Json.parse(fileTxt); var data:EventInfoFile = cast Json.parse(fileTxt);
if (data == null || data.params == null) continue; if (data == null || data.params == null) continue;
var finalParams:Array<EventParamInfo> = []; var finalParams:Array<EventParamInfo> = [];
for (paramData in cast(data.params, Array<Dynamic>)) { for (paramData in data.params) {
try { 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);} } catch (e) {trace('Error parsing event param ${paramData.name} - ${eventName}: $e'); finalParams.push(null);}
} }
eventsParams.set(eventName, finalParams); 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 = { typedef EventInfo = {
var params:Array<EventParamInfo>; var params:Array<EventParamInfo>;
var paramValues:Array<Dynamic>; var paramValues:Array<Dynamic>;
@@ -26,7 +26,7 @@ final class DirectionAnimEvent extends CancellableEvent {
**/ **/
public var frame:Int; 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<Bool>;
} }
@@ -100,9 +100,9 @@ final class NoteHitEvent extends CancellableEvent {
*/ */
public var ratingAntialiasing:Bool = true; 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<Bool> = true;
/** /**
* Prevents the default sing animation from being played. * Prevents the default sing animation from being played.
@@ -29,9 +29,9 @@ final class NoteMissEvent extends CancellableEvent {
public var gfSadAnim:String; public var gfSadAnim:String;
public var forceGfAnim:Bool; 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<Bool>;
/** /**
* Suffix of the animation. "miss" for miss notes, "-alt" for alt notes, "" for normal ones. * Suffix of the animation. "miss" for miss notes, "-alt" for alt notes, "" for normal ones.
*/ */
@@ -7,9 +7,9 @@ final class PlayAnimEvent extends CancellableEvent {
public var animName:String; 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<Bool>;
/** /**
Whenever the animation will play in reverse or not Whenever the animation will play in reverse or not
@@ -125,9 +125,16 @@ class Framerate extends Sprite {
bgSprite.scaleX = width; bgSprite.scaleX = width;
bgSprite.scaleY = height; 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) { for(c in categories) {
c.title.selectable = c.text.selectable = selectable;
c.alpha = debugAlpha; c.alpha = debugAlpha;
c.x = FlxMath.lerp(-c.width - offset.x, 0, debugAlpha); c.x = FlxMath.lerp(-c.width - offset.x, 0, debugAlpha);
c.y = y; c.y = y;
@@ -29,6 +29,7 @@ class FramerateCategory extends Sprite {
label.x = 0; label.x = 0;
label.y = 0; label.y = 0;
label.defaultTextFormat = new TextFormat(Framerate.fontName, label == this.title ? 18 : 12, -1); label.defaultTextFormat = new TextFormat(Framerate.fontName, label == this.title ? 18 : 12, -1);
label.selectable = false;
addChild(label); addChild(label);
} }
this.title.text = title; this.title.text = title;
@@ -51,4 +52,4 @@ class FramerateCategory extends Sprite {
bgSprite.scaleX = width; bgSprite.scaleX = width;
bgSprite.scaleY = height; bgSprite.scaleY = height;
} }
} }
@@ -1,28 +1,17 @@
package funkin.backend.system.framerate; package funkin.backend.system.framerate;
import haxe.ds.Vector;
import openfl.display.Sprite; import openfl.display.Sprite;
import openfl.text.TextField; import openfl.text.TextField;
import openfl.text.TextFormat; import openfl.text.TextFormat;
inline final FRAME_TIME_HISTORY = 20;
class FramerateCounter extends Sprite { class FramerateCounter extends Sprite {
public var fpsNum:TextField; public var fpsNum:TextField;
public var fpsLabel:TextField; public var fpsLabel:TextField;
public var lastFPS:Float = 0;
public var fpsHistoryIndex:Int = 0;
public var fpsHistory:Vector<Float>;
public function new() { public function new() {
super(); 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(); fpsNum = new TextField();
fpsLabel = new TextField(); fpsLabel = new TextField();
@@ -33,6 +22,7 @@ class FramerateCounter extends Sprite {
label.text = "FPS"; label.text = "FPS";
label.multiline = label.wordWrap = false; label.multiline = label.wordWrap = false;
label.defaultTextFormat = new TextFormat(Framerate.fontName, label == fpsNum ? 18 : 12, -1); label.defaultTextFormat = new TextFormat(Framerate.fontName, label == fpsNum ? 18 : 12, -1);
label.selectable = false;
addChild(label); addChild(label);
} }
} }
@@ -43,21 +33,9 @@ class FramerateCounter extends Sprite {
if (alpha <= 0.05) return; if (alpha <= 0.05) return;
super.__enterFrame(t); super.__enterFrame(t);
// todo use gpu time lastFPS = CoolUtil.fpsLerp(lastFPS, FlxG.elapsed == 0 ? 0 : (1 / FlxG.elapsed), 0.25);
fpsHistory[fpsHistoryIndex] = FlxG.elapsed * 1000; fpsNum.text = Std.string(Math.floor(lastFPS));
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));
fpsLabel.x = fpsNum.x + fpsNum.width; fpsLabel.x = fpsNum.x + fpsNum.width;
fpsLabel.y = (fpsNum.y + fpsNum.height) - fpsLabel.height; fpsLabel.y = (fpsNum.y + fpsNum.height) - fpsLabel.height;
} }
} }
@@ -24,6 +24,7 @@ class MemoryCounter extends Sprite {
label.text = "FPS"; label.text = "FPS";
label.multiline = label.wordWrap = false; label.multiline = label.wordWrap = false;
label.defaultTextFormat = new TextFormat(Framerate.fontName, 12, -1); label.defaultTextFormat = new TextFormat(Framerate.fontName, 12, -1);
label.selectable = false;
addChild(label); addChild(label);
} }
memoryPeakText.alpha = 0.5; memoryPeakText.alpha = 0.5;
@@ -42,4 +43,4 @@ class MemoryCounter extends Sprite {
memoryPeakText.x = memoryText.x + memoryText.width; memoryPeakText.x = memoryText.x + memoryText.width;
} }
} }
+15 -2
View File
@@ -721,7 +721,7 @@ class CoolUtil
*/ */
@:noUsing public static inline function openURL(url:String) { @:noUsing public static inline function openURL(url:String) {
#if linux #if linux
Sys.command('/usr/bin/xdg-open', [url, "&"]); Sys.command('/usr/bin/xdg-open', [url]);
#else #else
FlxG.openURL(url); FlxG.openURL(url);
#end #end
@@ -906,6 +906,19 @@ class CoolUtil
return result.join(seperator); return result.join(seperator);
} }
public static function deepFlatten(arr:Array<Dynamic>, ?result:Array<Dynamic>):Array<Dynamic> {
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 CHECKED = 3;
var UNCHECKED = 4; var UNCHECKED = 4;
var WARNING = 5; var WARNING = 5;
} }
@@ -32,8 +32,8 @@ class FunkinParentDisabler extends FlxBasic {
FlxTimer.globalManager._timers = []; FlxTimer.globalManager._timers = [];
// cameras // cameras
__cameras = [for(c in FlxG.cameras.list) if (c.active) c]; __cameras = [for(c in FlxG.cameras.list) if (!c.paused) c];
for(c in __cameras) c.active = false; for(c in __cameras) c.paused = true;
// sounds // sounds
__sounds = [for(s in FlxG.sound.list) if (s.playing) s]; __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 override function draw() {}
public function reset() { public function reset() {
@@ -63,7 +60,7 @@ class FunkinParentDisabler extends FlxBasic {
for(t in __tweens) FlxTween.globalManager._tweens.push(t); for(t in __tweens) FlxTween.globalManager._tweens.push(t);
for(t in __timers) FlxTimer.globalManager._timers.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(); for(s in __sounds) s.play();
} }
} }
+11 -8
View File
@@ -4,6 +4,7 @@ import flixel.util.FlxColor;
import flixel.util.typeLimit.OneOfTwo; import flixel.util.typeLimit.OneOfTwo;
import funkin.backend.FunkinSprite.XMLAnimType; import funkin.backend.FunkinSprite.XMLAnimType;
import funkin.backend.FunkinSprite; import funkin.backend.FunkinSprite;
import funkin.game.Character;
import funkin.backend.system.ErrorCode; import funkin.backend.system.ErrorCode;
import funkin.backend.system.interfaces.IOffsetCompatible; import funkin.backend.system.interfaces.IOffsetCompatible;
import haxe.xml.Access; import haxe.xml.Access;
@@ -172,8 +173,7 @@ class XMLUtil {
animType: spr.spriteAnimType, animType: spr.spriteAnimType,
x: 0, x: 0,
y: 0, y: 0,
indices: [for(i in 0...spr.frames.frames.length) i], indices: [for(i in 0...spr.frames.frames.length) i]
forced: (node.has.forced && node.att.forced == "true") || (!node.has.forced && spr.spriteAnimType == BEAT)
}); });
} }
} }
@@ -199,8 +199,7 @@ class XMLUtil {
animType: animType, animType: animType,
x: 0, x: 0,
y: 0, y: 0,
indices: [], indices: []
forced: false,
}; };
if (anim.has.name) animData.name = anim.att.name; if (anim.has.name) animData.name = anim.att.name;
@@ -256,24 +255,28 @@ class XMLUtil {
if (sprite is FunkinSprite) { if (sprite is FunkinSprite) {
var xmlSpr = cast(sprite, FunkinSprite); var xmlSpr = cast(sprite, FunkinSprite);
var name = animData.name;
switch(animData.animType) { switch(animData.animType) {
case BEAT: case BEAT:
xmlSpr.beatAnims.push({ xmlSpr.beatAnims.push({
name: animData.name, name: name,
forced: animData.forced.getDefault(false) forced: animData.forced.getDefault(defaultForcedCheck(name, xmlSpr))
}); });
case LOOP: case LOOP:
xmlSpr.playAnim(animData.name, animData.forced.getDefault(false)); xmlSpr.playAnim(name, animData.forced.getDefault(defaultForcedCheck(name, xmlSpr)));
default: default:
// nothing // nothing
} }
xmlSpr.animDatas.set(animData.name, animData); xmlSpr.animDatas.set(name, animData);
} }
return OK; return OK;
} }
return MISSING_PROPERTY; 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) { public static inline function fixXMLText(text:String) {
var v:String; var v:String;
return [for(l in text.split("\n")) if ((v = l.trim()) != "") v].join("\n"); return [for(l in text.split("\n")) if ((v = l.trim()) != "") v].join("\n");
@@ -98,11 +98,7 @@ class SongCreationScreen extends UISubstateWindow {
voicesExplorer.uiElement = audioPlayer; voicesExplorer.uiElement = audioPlayer;
}); });
songDataGroup.add(voicesExplorer); songDataGroup.add(voicesExplorer);
addLabelOn(voicesExplorer, "Vocal Audio File");
voicesUIText = addLabelOn(voicesExplorer, "Vocal Audio File");
voicesUIText.applyMarkup(
"Vocal Audio File $* Required$",
[new FlxTextFormatMarkerPair(new FlxTextFormat(0xFFAD1212), "$")]);
var menuTitle:UIText; var menuTitle:UIText;
menuDataGroup.add(menuTitle = new UIText(windowSpr.x + 20, windowSpr.y + 30 + 16, 0, "Menus Data (Freeplay/Story)", 28)); menuDataGroup.add(menuTitle = new UIText(windowSpr.x + 20, windowSpr.y + 30 + 16, 0, "Menus Data (Freeplay/Story)", 28));
+3 -2
View File
@@ -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. * 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<Bool> = null, Reversed:Bool = false, Frame:Int = 0)
{ {
var event = EventManager.get(DirectionAnimEvent).recycle(getSingAnim(direction, suffix), direction, suffix, Context, Reversed, Frame, Force); var event = EventManager.get(DirectionAnimEvent).recycle(getSingAnim(direction, suffix), direction, suffix, Context, Reversed, Frame, Force);
script.call("onPlaySingAnim", [event]); 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); 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); var event = EventManager.get(PlayAnimEvent).recycle(AnimName, Force, Reversed, Frame, Context);
script.call("onPlayAnim", [event]); script.call("onPlayAnim", [event]);
if (event.cancelled) return; if (event.cancelled) return;
@@ -323,6 +323,7 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset
public inline function buildCharacter(xml:Access) { public inline function buildCharacter(xml:Access) {
this.xml = xml; // Modders wassup :D this.xml = xml; // Modders wassup :D
sprite = curCharacter; sprite = curCharacter;
spriteAnimType = BEAT;
if (xml.x.exists("isPlayer")) playerOffsets = (xml.x.get("isPlayer") == "true"); if (xml.x.exists("isPlayer")) playerOffsets = (xml.x.get("isPlayer") == "true");
if (xml.x.exists("x")) globalOffset.x = Std.parseFloat(xml.x.get("x")); if (xml.x.exists("x")) globalOffset.x = Std.parseFloat(xml.x.get("x"));
+7 -5
View File
@@ -675,10 +675,12 @@ class PlayState extends MusicBeatState
chars.push(char); chars.push(char);
} }
var strOffset:Float = strumLine.strumLinePos == null ? (strumLine.type == 1 ? 0.75 : 0.25) : strumLine.strumLinePos; var strOffset:Float = strumLine.strumLinePos != null ? strumLine.strumLinePos : (strumLine.type == 1 ? 0.75 : 0.25);
var startingPos:FlxPoint = strumLine.strumPos == null ? var strScale:Float = strumLine.strumScale != null ? strumLine.strumScale : 1;
FlxPoint.get((FlxG.width * strOffset) - ((Note.swagWidth * (strumLine.strumScale == null ? 1 : strumLine.strumScale)) * 2), this.strumLine.y) : var strXPos:Float = (FlxG.width * strOffset) - (Note.swagWidth * strScale * 2);
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 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, var strLine = new StrumLine(chars,
startingPos, startingPos,
strumLine.strumScale == null ? 1 : strumLine.strumScale, 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 percent:Float;
public var rating:String; public var rating:String;
public var color:FlxColor; public var color:FlxColor;
+6 -1
View File
@@ -152,7 +152,12 @@ class StrumLine extends FlxTypedGroup<Strum> {
var scrollSpeed = strumLine.scrollSpeed; var scrollSpeed = strumLine.scrollSpeed;
if(scrollSpeed == null) if (PlayState.instance != null) scrollSpeed = PlayState.instance.scrollSpeed; if(scrollSpeed == null) if (PlayState.instance != null) scrollSpeed = PlayState.instance.scrollSpeed;
if(scrollSpeed == null) scrollSpeed = 1; 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) { public override function update(elapsed:Float) {
@@ -97,7 +97,7 @@ class DialogueBox extends FunkinSprite {
dialogueBoxScript.call("postCreate"); 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); var event = EventManager.get(PlayAnimEvent).recycle(AnimName, Force, Reversed, Frame, Context);
dialogueBoxScript.call("onPlayAnim", [event]); dialogueBoxScript.call("onPlayAnim", [event]);
if(event.cancelled) return; if(event.cancelled) return;
@@ -62,7 +62,7 @@ class DialogueCharacter extends FunkinSprite {
dialogueCharScript.call("postCreate"); 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); var event = EventManager.get(PlayAnimEvent).recycle(AnimName, Force, Reversed, Frame, Context);
dialogueCharScript.call("playAnim", [event]); dialogueCharScript.call("playAnim", [event]);
if(event.cancelled) return; if(event.cancelled) return;