diff --git a/assets/data/scripts/pixel.hx b/assets/data/scripts/pixel.hx
index d215176b..5539c1f4 100644
--- a/assets/data/scripts/pixel.hx
+++ b/assets/data/scripts/pixel.hx
@@ -170,16 +170,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 b382af35..6a4455cd 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/project.xml b/project.xml
index 8e87bdcd..7318589a 100644
--- a/project.xml
+++ b/project.xml
@@ -150,6 +150,8 @@
+
+
diff --git a/source/funkin/backend/FunkinSprite.hx b/source/funkin/backend/FunkinSprite.hx
index 94835653..9e64b5a4 100644
--- a/source/funkin/backend/FunkinSprite.hx
+++ b/source/funkin/backend/FunkinSprite.hx
@@ -105,16 +105,15 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
public override function update(elapsed:Float)
{
super.update(elapsed);
+ if (animateAtlas != null)
+ animateAtlas.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))
+ if (hasAnimation(name))
playAnim(name, false, lastAnimContext);
}
-
- if (animateAtlas != null)
- animateAtlas.update(elapsed);
}
public function loadSprite(path:String, Unique:Bool = false, Key:String = null)
diff --git a/source/funkin/backend/scripting/EventManager.hx b/source/funkin/backend/scripting/EventManager.hx
index f2eeb23f..90b67b4c 100644
--- a/source/funkin/backend/scripting/EventManager.hx
+++ b/source/funkin/backend/scripting/EventManager.hx
@@ -14,8 +14,9 @@ final class EventManager {
var index = eventKeys.indexOf(c);
if (index < 0) {
eventKeys.push(c);
- eventValues.push(Type.createInstance(c, []));
- return cast eventValues.last();
+ var ret;
+ eventValues.push(ret = Type.createInstance(c, []));
+ return cast ret;
}
return cast eventValues[index];
diff --git a/source/funkin/backend/scripting/ModState.hx b/source/funkin/backend/scripting/ModState.hx
index adc0a42c..94a6ac7b 100644
--- a/source/funkin/backend/scripting/ModState.hx
+++ b/source/funkin/backend/scripting/ModState.hx
@@ -1,10 +1,38 @@
package funkin.backend.scripting;
class ModState extends MusicBeatState {
+
+ /**
+ * Name of HScript file in assets/data/states.
+ */
public static var lastName:String = null;
- public function new(stateName:String) {
- if (stateName != null)
- lastName = stateName;
+ /**
+ * Last Optional extra data.
+ */
+ public static var lastData:Dynamic = null;
+
+ /**
+ * Optional extra data.
+ */
+ public var data:Dynamic = null;
+
+ /**
+ * ModState Constructor.
+ * Inherits from MusicBeatState and allows the execution of an HScript from assets/data/states passed via parameters.
+ *
+ * @param _stateName Name or path to a HScript file from assets/data/states.
+ * @param _data Optional extra Dynamic data passed from a previous state (JSON suggested).
+ */
+ public function new(_stateName:String, ?_data:Dynamic) {
+ if(_stateName != null && _stateName != lastName) {
+ lastName = _stateName;
+ lastData = null;
+ }
+
+ if(_data != null)
+ lastData = _data;
+
+ data = lastData;
super(true, lastName);
}
}
\ No newline at end of file
diff --git a/source/funkin/backend/scripting/ModSubState.hx b/source/funkin/backend/scripting/ModSubState.hx
index 5f06072c..acd90f62 100644
--- a/source/funkin/backend/scripting/ModSubState.hx
+++ b/source/funkin/backend/scripting/ModSubState.hx
@@ -1,10 +1,38 @@
package funkin.backend.scripting;
class ModSubState extends MusicBeatSubstate {
+
+ /**
+ * Name of HScript file in assets/data/states.
+ */
public static var lastName:String = null;
- public function new(stateName:String) {
- if (stateName != null)
- lastName = stateName;
+ /**
+ * Last Optional extra data.
+ */
+ public static var lastData:Dynamic = null;
+
+ /**
+ * Optional extra data.
+ */
+ public var data:Dynamic = null;
+
+ /**
+ * ModSubState Constructor.
+ * Inherits from MusicBeatSubstate and allows the execution of an HScript from assets/data/states passed via parameters.
+ *
+ * @param _stateName Name or path to a HScript file from assets/data/states.
+ * @param _data Optional extra Dynamic data passed from a previous state (JSON suggested).
+ */
+ public function new(_stateName:String, ?_data:Dynamic) {
+ if(_stateName != null && _stateName != lastName) {
+ lastName = _stateName;
+ lastData = null;
+ }
+
+ if(_data != null)
+ lastData = _data;
+
+ data = lastData;
super(true, lastName);
}
}
\ No newline at end of file
diff --git a/source/funkin/backend/system/Flags.hx b/source/funkin/backend/system/Flags.hx
new file mode 100644
index 00000000..fed62113
--- /dev/null
+++ b/source/funkin/backend/system/Flags.hx
@@ -0,0 +1,63 @@
+package funkin.backend.system;
+
+import lime.utils.AssetLibrary;
+import lime.utils.AssetType;
+
+import funkin.backend.assets.IModsAssetLibrary;
+import funkin.backend.assets.ScriptedAssetLibrary;
+
+/**
+ * A class that reads the `flags.ini` file, allowing to read settable Flags (customs too).
+ */
+@:build(funkin.backend.system.macros.FlagMacro.build())
+class Flags {
+ public static var SONGS_LIST_MOD_MODE:Allow<"prepend", "override", "append"> = "override";
+ public static var WEEKS_LIST_MOD_MODE:Allow<"prepend", "override", "append"> = "override";
+
+ // Internal stuff
+
+ @:bypass public static var customFlags:Map = [];
+
+ public static function load() {
+ var flags:Map = [];
+
+ final flagsPath = Paths.getPath("flags.ini");
+
+ for(lib in Paths.assetsTree.libraries) {
+ if(lib.exists(flagsPath, AssetType.TEXT)) {
+ var data:String = lib.getAsset(flagsPath, AssetType.TEXT);
+ var trimmed:String;
+ var splitContent = [for(e in data.split("\n")) if ((trimmed = e.trim()) != "") trimmed];
+
+ for(line in splitContent) {
+ if (line.startsWith(";")) continue;
+ if (line.startsWith("#")) continue;
+ if (line.startsWith("//")) continue;
+ if(line.length == 0) continue;
+ if(line.charAt(0) == "[" && line.charAt(line.length-1) == "]") continue;
+
+ var index = line.indexOf("=");
+ if(index == -1) continue;
+ var name = line.substr(0, index).trim();
+ var value = line.substr(index+1).trim();
+
+ if (value.length > 1 && value.charCodeAt(0) == '"'.code && value.charCodeAt(value.length-1) == '"'.code)
+ value = value.substr(1, value.length - 2);
+
+ if (value.length == 0 || name.length == 0)
+ continue;
+
+ if(!flags.exists(name))
+ flags[name] = value;
+ }
+ }
+ }
+
+ customFlags = [];
+ reset();
+ for(name=>value in flags)
+ if(!parse(name, value)) {
+ customFlags.set(name, value);
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/funkin/backend/system/MainState.hx b/source/funkin/backend/system/MainState.hx
index 657ae88a..7a354081 100644
--- a/source/funkin/backend/system/MainState.hx
+++ b/source/funkin/backend/system/MainState.hx
@@ -8,6 +8,7 @@ import funkin.backend.assets.ModsFolder;
import funkin.backend.chart.EventsData;
import funkin.menus.BetaWarningState;
import funkin.menus.TitleState;
+import funkin.backend.system.framerate.Framerate;
/**
* Simple state used for loading the game
@@ -56,11 +57,15 @@ class MainState extends FlxState {
Main.refreshAssets();
ModsFolder.onModSwitch.dispatch(ModsFolder.currentModFolder);
+ Flags.load();
DiscordUtil.init();
EventsData.reloadEvents();
ControlsUtil.loadCustomControls();
TitleState.initialized = false;
+ if(Framerate.isLoaded)
+ Framerate.instance.reload();
+
if (betaWarningShown)
FlxG.switchState(new TitleState());
else {
diff --git a/source/funkin/backend/system/framerate/CodenameBuildField.hx b/source/funkin/backend/system/framerate/CodenameBuildField.hx
index 3175a01e..5519f4d8 100644
--- a/source/funkin/backend/system/framerate/CodenameBuildField.hx
+++ b/source/funkin/backend/system/framerate/CodenameBuildField.hx
@@ -9,6 +9,9 @@ class CodenameBuildField extends TextField {
defaultTextFormat = Framerate.textFormat;
autoSize = LEFT;
multiline = wordWrap = false;
- text = 'Codename Engine ${Main.releaseCycle}\nCommit ${GitCommitMacro.commitNumber} (${GitCommitMacro.commitHash})';
+ reload();
}
+
+ public function reload()
+ text = 'Codename Engine ${Main.releaseCycle}\nCommit ${GitCommitMacro.commitNumber} (${GitCommitMacro.commitHash})';
}
diff --git a/source/funkin/backend/system/framerate/Framerate.hx b/source/funkin/backend/system/framerate/Framerate.hx
index 2f1f39e8..2a81b014 100644
--- a/source/funkin/backend/system/framerate/Framerate.hx
+++ b/source/funkin/backend/system/framerate/Framerate.hx
@@ -82,6 +82,16 @@ class Framerate extends Sprite {
#end
}
+ public function reload() {
+ for(c in categories)
+ c.reload();
+ #if SHOW_BUILD_ON_FPS
+ codenameBuildField.reload();
+ #end
+ memoryCounter.reload();
+ fpsCounter.reload();
+ }
+
private function __addCategory(category:FramerateCategory) {
categories.push(category);
__addToList(category);
diff --git a/source/funkin/backend/system/framerate/FramerateCategory.hx b/source/funkin/backend/system/framerate/FramerateCategory.hx
index f1125eb4..a862505c 100644
--- a/source/funkin/backend/system/framerate/FramerateCategory.hx
+++ b/source/funkin/backend/system/framerate/FramerateCategory.hx
@@ -39,6 +39,8 @@ class FramerateCategory extends Sprite {
this.text.y = this.title.y + this.title.height + 2;
}
+ public function reload() {}
+
public override function __enterFrame(t:Int) {
if (alpha <= 0.05) return;
super.__enterFrame(t);
diff --git a/source/funkin/backend/system/framerate/FramerateCounter.hx b/source/funkin/backend/system/framerate/FramerateCounter.hx
index e07a2e02..c5641ee3 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();
@@ -37,24 +26,14 @@ class FramerateCounter extends Sprite {
}
}
+ public function reload() {}
+
public override function __enterFrame(t:Int) {
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;
}
diff --git a/source/funkin/backend/system/framerate/MemoryCounter.hx b/source/funkin/backend/system/framerate/MemoryCounter.hx
index 33efff59..f38de1d8 100644
--- a/source/funkin/backend/system/framerate/MemoryCounter.hx
+++ b/source/funkin/backend/system/framerate/MemoryCounter.hx
@@ -29,6 +29,8 @@ class MemoryCounter extends Sprite {
memoryPeakText.alpha = 0.5;
}
+ public function reload() {}
+
public override function __enterFrame(t:Int) {
if (alpha <= 0.05) return;
super.__enterFrame(t);
diff --git a/source/funkin/backend/system/macros/FlagMacro.macro.hx b/source/funkin/backend/system/macros/FlagMacro.macro.hx
new file mode 100644
index 00000000..477512c0
--- /dev/null
+++ b/source/funkin/backend/system/macros/FlagMacro.macro.hx
@@ -0,0 +1,211 @@
+package funkin.backend.system.macros;
+
+import haxe.macro.Context;
+import haxe.macro.Expr;
+
+using StringTools;
+
+using haxe.macro.Tools;
+
+class FlagMacro {
+ public static function build():Array {
+ var fields = Context.getBuildFields();
+
+ var clRef = Context.getLocalClass();
+ if (clRef == null)
+ return fields;
+
+ var cl = clRef.get();
+
+ var resetExprs:Array = [];
+ var parserExprs:Array = [];
+
+ for (field in fields) {
+ var skip = false;
+ for(meta in field.meta) {
+ if(meta.name == ":bypass") {
+ skip = true;
+ break;
+ }
+ }
+
+ if(skip) continue;
+
+ switch (field.kind) {
+ case FVar(type, expr):
+ if(expr == null)
+ Context.error('Flag ' + field.name + ' must have a default value', field.pos);
+ switch(expr.expr) {
+ case EConst(CIdent("true")) | EConst(CIdent("false")):
+ type = macro: Bool;
+ default:
+ if(type == null)
+ Context.error('Flag ' + field.name + ' must have a type', field.pos);
+ }
+
+ var parser:Expr = null;
+ var customCheck:Expr = null;
+
+ switch(type) {
+ case macro: Array:
+ field.kind = FVar(macro: Array, expr);
+ parser = macro value.split(",").map((e) -> e.trim());
+ case macro: Array:
+ parser = macro value.split(",");
+ case macro: Array:
+ parser = macro value.split(",").map((e) -> {
+ e = e.trim();
+ e == "true" || e == "t" || e == "1";
+ });
+ case macro: Int:
+ parser = macro Std.parseInt(value);
+ case macro: String:
+ parser = macro value;
+ case macro: Bool:
+ parser = macro value == "true" || value == "t" || value == "1";
+ case TPath({name: "Allow", pack: [], params: params}):
+ final NONE = 0;
+ final STRING = 1;
+ final INT = 2;
+ var chosenType = NONE;
+
+ var values:Array = [];
+
+ for(param in params) {
+ switch(param) {
+ case TPExpr(e):
+ switch(e.expr) {
+ case EConst(CString(s, kind)):
+ if(chosenType != NONE && chosenType != STRING)
+ Context.error("Flag " + field.name + " Allow<> can only have one type", field.pos);
+ chosenType = STRING;
+
+ values.push(s);
+ case EConst(CInt(num)):
+ if(chosenType != NONE && chosenType != INT)
+ Context.error("Flag " + field.name + " Allow<> can only have one type", field.pos);
+ chosenType = INT;
+
+ values.push(num);
+ default:
+ Context.error("Flag " + field.name + " Allow<> unknown type", field.pos);
+ }
+ default:
+ Context.error("Flag " + field.name + " Unknown type when using Allow<>", field.pos);
+ }
+ }
+
+ var didFind = false;
+ for(v in values) {
+ switch(expr.expr) {
+ case EConst(CString(s, kind)):
+ if(v == s)
+ didFind = true;
+ case EConst(CInt(num)):
+ if(v == num)
+ didFind = true;
+ default:
+ }
+ }
+ if(!didFind)
+ Context.error("Flag " + field.name + "'s Allow<> must have a default value that is allowed, " + expr.toString() + " is not allowed", field.pos);
+
+ if(chosenType == NONE)
+ Context.error("Flag " + field.name + "'s Allow<> must have atleast one value", field.pos);
+
+ var errorMessage = 'Flag ${field.name} must be one of ${values.join(", ")}';
+
+ var checkExpr = macro value == $v{values.shift()};
+ for(v in values)
+ checkExpr = macro $checkExpr || value == $v{v};
+
+ if(chosenType == STRING) {
+ parser = macro value;
+ field.kind = FVar(macro: String, expr);
+ }
+ else if(chosenType == INT) {
+ parser = macro Std.parseInt(value);
+ field.kind = FVar(macro: Int, expr);
+ } else {
+ field.kind = FVar(macro: Any, expr);
+ }
+
+ customCheck = macro @:mergeBlock {
+ if(name == $v{field.name}) {
+ if($checkExpr)
+ $i{field.name} = $parser;
+ else
+ throw $v{errorMessage};
+ return true;
+ }
+ }
+
+ case TPath({name: "Array", pack: []}):
+ Context.error("Flag " + field.name + " cannot be an Array that isnt a String or Bool or TrimmedString", field.pos);
+ case TPath({name: "Map", pack: []}):
+ Context.error("Flag " + field.name + " cannot be a Map", field.pos);
+ default:
+ Context.error("Flag " + field.name + " must be either a Bool, Int, String, Array, Array or Array", field.pos);
+ }
+
+ if(parser == null) {
+ Context.error("Flag " + field.name + " must be either a Bool, Int, String, Array, Array or Array", field.pos);
+ continue;
+ }
+
+ resetExprs.push(macro $i{field.name} = ${expr});
+
+ // parse(name: String, value: String)
+
+ if(customCheck != null) {
+ parserExprs.push(customCheck);
+ } else {
+ parserExprs.push(macro @:mergeBlock {
+ if(name == $v{field.name}) {
+ $i{field.name} = $parser;
+ return true;
+ }
+ });
+ }
+ default:
+ // nothing
+ }
+ }
+
+ fields.push({
+ name: "reset",
+ access: [APublic, AStatic],
+ kind: FFun({
+ args: [],
+ expr: macro $b{resetExprs},
+ ret: macro: Void
+ }),
+ pos: Context.currentPos(),
+ doc: null,
+ meta: []
+ });
+
+ fields.push({
+ name: "parse",
+ access: [APublic, AStatic],
+ kind: FFun({
+ args: [{name: "name", type: macro: String}, {name: "value", type: macro: String}],
+ expr: macro {
+ @:mergeBlock $b{parserExprs};
+
+ return false;
+ },
+ ret: macro: Bool
+ }),
+ pos: Context.currentPos(),
+ doc: null,
+ meta: []
+ });
+
+ //var printer = new haxe.macro.Printer();
+ //trace(printer.printField(fields[fields.length - 2]));
+ //trace(printer.printField(fields[fields.length - 1]));
+
+ return fields;
+ }
+}
\ 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/IniUtil.hx b/source/funkin/backend/utils/IniUtil.hx
index 646a91b4..5901f57e 100644
--- a/source/funkin/backend/utils/IniUtil.hx
+++ b/source/funkin/backend/utils/IniUtil.hx
@@ -26,7 +26,7 @@ final class IniUtil {
var name = line.substr(0, index).trim();
var value = line.substr(index+1).trim();
- if (value.startsWith("\"") && value.endsWith("\""))
+ if (value.length > 1 && value.charCodeAt(0) == '"'.code && value.charCodeAt(value.length-1) == '"'.code)
value = value.substr(1, value.length - 2);
if (value.length == 0 || name.length == 0)
diff --git a/source/funkin/editors/charter/CharterEvent.hx b/source/funkin/editors/charter/CharterEvent.hx
index a1a660f0..3831d99a 100644
--- a/source/funkin/editors/charter/CharterEvent.hx
+++ b/source/funkin/editors/charter/CharterEvent.hx
@@ -48,10 +48,12 @@ class CharterEvent extends UISliceSprite implements ICharterSelectable {
var isBase64:Bool = false;
var path:String = Paths.image('editors/charter/event-icons/$name');
if (!Assets.exists(path)) path = Paths.image('editors/charter/event-icons/Unknown');
- if (Assets.exists(Paths.pack('events/$name'))) {
- var packimg = Assets.getText(Paths.pack('events/$name')).split('________PACKSEP________')[3];
+ var packPath = Paths.pack('events/$name');
+ if (Assets.exists(packPath)) {
+ var packText = Assets.getText(packPath).split('________PACKSEP________');
+ var packimg = packText[3];
if (isBase64 = (packimg != null))
- path = Assets.getText(Paths.pack('events/$name')).split('________PACKSEP________')[3];
+ path = packText[3];
}
var spr = new FlxSprite().loadGraphic(isBase64 ? openfl.display.BitmapData.fromBase64(path.trim(), 'UTF8') : path);
return spr;
diff --git a/source/funkin/editors/charter/SongCreationScreen.hx b/source/funkin/editors/charter/SongCreationScreen.hx
index 7915cae0..80549cf7 100644
--- a/source/funkin/editors/charter/SongCreationScreen.hx
+++ b/source/funkin/editors/charter/SongCreationScreen.hx
@@ -80,8 +80,6 @@ class SongCreationScreen extends UISubstateWindow {
stepsPerBeatStepper = new UINumericStepper(beatsPerMeasureStepper.x + 30 + 24, beatsPerMeasureStepper.y, 4, 1, 0, 1, null, 54);
songDataGroup.add(stepsPerBeatStepper);
- var voicesUIText:UIText = null;
-
instExplorer = new UIFileExplorer(songNameTextBox.x, songNameTextBox.y + 32 + 36, null, null, Paths.SOUND_EXT, function (res) {
var audioPlayer:UIAudioPlayer = new UIAudioPlayer(instExplorer.x + 8, instExplorer.y + 8, res);
instExplorer.members.push(audioPlayer);
@@ -98,11 +96,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/PlayState.hx b/source/funkin/game/PlayState.hx
index c356dea3..53de5ce5 100644
--- a/source/funkin/game/PlayState.hx
+++ b/source/funkin/game/PlayState.hx
@@ -362,7 +362,7 @@ class PlayState extends MusicBeatState
* Speed at which the game camera zoom lerps to.
*/
public var camGameZoomLerp:Float = 0.05;
-
+
/**
* Camera zoom at which the hud lerps to.
*/
@@ -653,14 +653,14 @@ class PlayState extends MusicBeatState
chars.push(char);
}
- var strOffset:Float = strumLine.strumLinePos == null ? (strumLine.type == 1 ? 0.75 : 0.25) : strumLine.strumLinePos;
- var strumScale:Float = (strumLine.strumScale == null ? 1 : strumLine.strumScale);
- var strumSpacing:Float = (strumLine.strumSpacing == null ? 1 : strumLine.strumSpacing);
- var keyCount:Int = (strumLine.keyCount == null ? 4 : strumLine.keyCount);
-
- var startingPos:FlxPoint = strumLine.strumPos == null ?
- FlxPoint.get(StrumLine.calculateStartingXPos(strOffset, strumScale, strumSpacing, keyCount), this.strumLine.y) :
- FlxPoint.get(strumLine.strumPos[0] == 0 ? StrumLine.calculateStartingXPos(strOffset, strumScale, strumSpacing, keyCount) : 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 strSpacing:Float = strumLine.strumSpacing == null ? 1 : strumLine.strumSpacing;
+ var keyCount:Int = strumLine.keyCount == null ? 4 : strumLine.keyCount;
+ var strXPos:Float = StrumLine.calculateStartingXPos(strOffset, strScale, strSpacing, keyCount);
+ 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,
diff --git a/source/funkin/game/StrumLine.hx b/source/funkin/game/StrumLine.hx
index 4cbec464..509b33e2 100644
--- a/source/funkin/game/StrumLine.hx
+++ b/source/funkin/game/StrumLine.hx
@@ -152,7 +152,8 @@ 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 = 1500 / scrollSpeed;
+ var limit = FlxG.height / 0.45;
+ notes.limit = limit / scrollSpeed;
}
public override function update(elapsed:Float) {
diff --git a/source/funkin/import.hx b/source/funkin/import.hx
index eca238fd..88a2efdb 100644
--- a/source/funkin/import.hx
+++ b/source/funkin/import.hx
@@ -22,6 +22,8 @@ import flixel.math.FlxMath;
import flixel.tweens.FlxEase;
import flixel.util.FlxDestroyUtil;
+import funkin.backend.system.Flags;
+
import funkin.menus.ui.Alphabet;
import flixel.group.FlxGroup.FlxTypedGroup;
import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup;
diff --git a/source/funkin/menus/FreeplayState.hx b/source/funkin/menus/FreeplayState.hx
index d29cd108..3c122494 100644
--- a/source/funkin/menus/FreeplayState.hx
+++ b/source/funkin/menus/FreeplayState.hx
@@ -465,8 +465,17 @@ class FreeplaySonglist {
public static function get(useTxt:Bool = true) {
var songList = new FreeplaySonglist();
- if (songList.getSongsFromSource(MODS, useTxt))
- songList.getSongsFromSource(SOURCE, useTxt);
+ switch(Flags.SONGS_LIST_MOD_MODE) {
+ case 'prepend':
+ songList.getSongsFromSource(MODS, useTxt);
+ songList.getSongsFromSource(SOURCE, useTxt);
+ case 'append':
+ songList.getSongsFromSource(SOURCE, useTxt);
+ songList.getSongsFromSource(MODS, useTxt);
+ default /*case 'override'*/:
+ if (songList.getSongsFromSource(MODS, useTxt))
+ songList.getSongsFromSource(SOURCE, useTxt);
+ }
return songList;
}
diff --git a/source/funkin/menus/StoryMenuState.hx b/source/funkin/menus/StoryMenuState.hx
index e8ab5c25..1ed7fa5b 100644
--- a/source/funkin/menus/StoryMenuState.hx
+++ b/source/funkin/menus/StoryMenuState.hx
@@ -199,14 +199,24 @@ class StoryMenuState extends MusicBeatState {
}
}
- intendedScore = FunkinSave.getWeekHighscore(weeks[curWeek].name, weeks[curWeek].difficulties[curDifficulty]).score;
+ intendedScore = FunkinSave.getWeekHighscore(weeks[curWeek].id, weeks[curWeek].difficulties[curDifficulty]).score;
}
public function loadXMLs() {
// CoolUtil.coolTextFile(Paths.txt('freeplaySonglist'));
var weeks:Array = [];
- if (getWeeksFromSource(weeks, MODS))
- getWeeksFromSource(weeks, SOURCE);
+
+ switch(Flags.WEEKS_LIST_MOD_MODE) {
+ case 'prepend':
+ getWeeksFromSource(weeks, MODS);
+ getWeeksFromSource(weeks, SOURCE);
+ case 'append':
+ getWeeksFromSource(weeks, SOURCE);
+ getWeeksFromSource(weeks, MODS);
+ default /*case 'override'*/:
+ if (getWeeksFromSource(weeks, MODS))
+ getWeeksFromSource(weeks, SOURCE);
+ }
for(k=>weekName in weeks) {
var week:Access = null;
@@ -344,8 +354,8 @@ class StoryMenuState extends MusicBeatState {
}
typedef WeekData = {
- var name:String;
- var id:String;
+ var name:String; // name SHOULD NOT be used for loading week highscores, its just the name on the right side of the week, remember that next time!! - Nex
+ var id:String; // id IS instead for saving and loading!! - Nex
var sprite:String;
var chars:Array;
var songs:Array;