diff --git a/.gitignore b/.gitignore
index 43d2c37c..7b2a0583 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,5 +4,6 @@ latest/windows/obj/
latest/windows/haxe/
.vscode/*
!.vscode/settings.json
+!.vscode/tasks.json
.haxelib/
mods/Baldi's Basics in Funkin'/
\ No newline at end of file
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
new file mode 100644
index 00000000..6f963b57
--- /dev/null
+++ b/.vscode/tasks.json
@@ -0,0 +1,32 @@
+{
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "type": "lime",
+ "command": "test",
+ "problemMatcher": [
+ "$haxe-absolute",
+ "$haxe",
+ "$haxe-error",
+ "$haxe-trace"
+ ],
+ "group": {
+ "kind": "build",
+ "isDefault": true
+ },
+ "label": "lime: test (active configuration)"
+ },
+ {
+ "type": "lime",
+ "command": "build",
+ "problemMatcher": [
+ "$haxe-absolute",
+ "$haxe",
+ "$haxe-error",
+ "$haxe-trace"
+ ],
+ "group": "build",
+ "label": "lime: build (active configuration)"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 3b8538b9..f9e52824 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@
# Friday Night Funkin' - Codename Engine (WIP)
-## PLEASE NOTE - THIS IS STILL IN A BETA STATE
-### Mods created with beta versions of Codename may not be compatible with the release version
-Known issues in the beta:
+## PLEASE NOTE - THIS IS STILL IN A ALPHA STATE
+### Mods created with alpha versions of Codename may not be compatible with the release version
+Known issues in the alpha:
- Some options are missing
- Week 5 has no monster animation
- Week 6 still have no dialogue
diff --git a/assets/images/editors/charter/add-strumline.png b/assets/images/editors/charter/add-strumline.png
new file mode 100644
index 00000000..d205c17e
Binary files /dev/null and b/assets/images/editors/charter/add-strumline.png differ
diff --git a/commandline/commands/Update.hx b/commandline/commands/Update.hx
index 6404ab35..f829131f 100644
--- a/commandline/commands/Update.hx
+++ b/commandline/commands/Update.hx
@@ -22,6 +22,7 @@ class Update {
name: libNode.att.name,
type: libNode.name
};
+ if (libNode.has.global) lib.global = libNode.att.global;
switch (lib.type) {
case "lib":
if (libNode.has.version) lib.version = libNode.att.version;
@@ -34,16 +35,17 @@ class Update {
for(lib in libs) {
// install libs
+ var globalism = lib.global == "true" ? "--global" : "";
switch(lib.type) {
case "lib":
- prettyPrint('Installing "${lib.name}"...');
- Sys.command('haxelib install ${lib.name} ${lib.version != null ? " " + lib.version : " "}');
+ prettyPrint((lib.global == "true" ? "Globally installing" : "Locally installing") + ' "${lib.name}"...');
+ Sys.command('haxelib $globalism install ${lib.name} ${lib.version != null ? " " + lib.version : " "}');
case "git":
- prettyPrint('Installing "${lib.name}" from git url "${lib.url}"');
- if (lib.ref != null)
- Sys.command('haxelib git ${lib.name} ${lib.url} ${lib.ref}');
- else
- Sys.command('haxelib git ${lib.name} ${lib.url}');
+ prettyPrint((lib.global == "true" ? "Globally installing" : "Locally installing") + ' "${lib.name}" from git url "${lib.url}"');
+ if (lib.ref != null)
+ Sys.command('haxelib $globalism git ${lib.name} ${lib.url} ${lib.ref}');
+ else
+ Sys.command('haxelib $globalism git ${lib.name} ${lib.url}');
default:
prettyPrint('Cannot resolve library of type "${lib.type}"');
}
@@ -90,7 +92,8 @@ class Update {
typedef Library = {
var name:String;
var type:String;
+ var ?global:String;
var ?version:String;
var ?ref:String;
var ?url:String;
-}
\ No newline at end of file
+}
diff --git a/libs.xml b/libs.xml
index 3ee3beeb..f3a63710 100644
--- a/libs.xml
+++ b/libs.xml
@@ -8,7 +8,9 @@
-
+
+
+
@@ -20,4 +22,4 @@
-
\ No newline at end of file
+
diff --git a/project.xml b/project.xml
index 327e5bd7..83f5b817 100644
--- a/project.xml
+++ b/project.xml
@@ -182,7 +182,7 @@
-
+
diff --git a/source/funkin/backend/chart/BaseGameParser.hx b/source/funkin/backend/chart/BaseGameParser.hx
index e157d186..b8d2d6b9 100644
--- a/source/funkin/backend/chart/BaseGameParser.hx
+++ b/source/funkin/backend/chart/BaseGameParser.hx
@@ -34,7 +34,6 @@ class BaseGameParser {
position: "girlfriend",
notes: [],
visible: false,
- strumLinePos: 0.5
});
}
diff --git a/source/funkin/backend/chart/ChartData.hx b/source/funkin/backend/chart/ChartData.hx
index e81589e7..14eee4be 100644
--- a/source/funkin/backend/chart/ChartData.hx
+++ b/source/funkin/backend/chart/ChartData.hx
@@ -36,8 +36,11 @@ typedef ChartStrumLine = {
var type:ChartStrumLineType;
var notes:Array;
var position:String;
- var ?strumLinePos:Float; // 0.25 = default opponent pos, 0.75 = default boyfriend pos
var ?visible:Null;
+ var ?strumPos:Array;
+ var ?strumScale:Float;
+
+ var ?strumLinePos:Float; // Backwards compatability
}
typedef ChartNote = {
diff --git a/source/funkin/backend/scripting/events/NoteHitEvent.hx b/source/funkin/backend/scripting/events/NoteHitEvent.hx
index 4a42733f..e3c8bbc0 100644
--- a/source/funkin/backend/scripting/events/NoteHitEvent.hx
+++ b/source/funkin/backend/scripting/events/NoteHitEvent.hx
@@ -16,9 +16,13 @@ final class NoteHitEvent extends CancellableEvent {
*/
public var misses:Bool = true;
/**
- * Whenever a miss should be added.
+ * Whether this hit increases combo.
*/
public var countAsCombo:Bool = true;
+ /**
+ * Whether this hit increases the score
+ */
+ public var countScore:Bool = true;
/**
* Whenever ratings should be shown or not.
*/
@@ -170,4 +174,4 @@ final class NoteHitEvent extends CancellableEvent {
characters = [char];
return char;
}
-}
\ No newline at end of file
+}
diff --git a/source/funkin/backend/system/framerate/SystemInfo.hx b/source/funkin/backend/system/framerate/SystemInfo.hx
index 974b578b..e4c8c389 100644
--- a/source/funkin/backend/system/framerate/SystemInfo.hx
+++ b/source/funkin/backend/system/framerate/SystemInfo.hx
@@ -18,10 +18,43 @@ class SystemInfo extends FramerateCategory {
static var __formattedSysText:String = "";
public static inline function init() {
+ #if linux
+ var process = new HiddenProcess("cat", ["/etc/os-release"]);
+ if (process.exitCode() != 0) Logs.trace('Unable to grab OS Label', ERROR, RED);
+ else {
+ var osName = "";
+ var osVersion = "";
+ for (line in process.stdout.readAll().toString().split("\n")) {
+ if (line.startsWith("PRETTY_NAME=")) {
+ var index = line.indexOf('"');
+ if (index != -1)
+ osName = line.substring(index + 1, line.lastIndexOf('"'));
+ else {
+ var arr = line.split("=");
+ arr.shift();
+ osName = arr.join("=");
+ }
+ }
+ if (line.startsWith("VERSION=")) {
+ var index = line.indexOf('"');
+ if (index != -1)
+ osVersion = line.substring(index + 1, line.lastIndexOf('"'));
+ else {
+ var arr = line.split("=");
+ arr.shift();
+ osVersion = arr.join("=");
+ }
+ }
+ }
+ if (osName != "")
+ osInfo = '${osName} ${osVersion}'.trim();
+ }
+ #else
if (lime.system.System.platformLabel != null && lime.system.System.platformLabel != "" && lime.system.System.platformVersion != null && lime.system.System.platformVersion != "")
osInfo = '${lime.system.System.platformLabel.replace(lime.system.System.platformVersion, "").trim()} ${lime.system.System.platformVersion}';
else
Logs.trace('Unable to grab OS Label', ERROR, RED);
+ #end
try {
#if windows
@@ -38,7 +71,7 @@ class SystemInfo extends FramerateCategory {
var process = new HiddenProcess("cat", ["/proc/cpuinfo"]);
if (process.exitCode() != 0) throw 'Could not fetch CPU information';
- for (line in process.stdout.readAll().toString().split("\n")) {
+ for (line in process.stdout.readAll().toString().split("\n")) {
if (line.indexOf("model name") == 0) {
cpuName = line.substring(line.indexOf(":") + 2);
break;
diff --git a/source/funkin/editors/DebugOptions.hx b/source/funkin/editors/DebugOptions.hx
index 734342c4..b704feac 100644
--- a/source/funkin/editors/DebugOptions.hx
+++ b/source/funkin/editors/DebugOptions.hx
@@ -44,5 +44,9 @@ class DebugOptionsScreen extends OptionsScreen {
"Resizable Editors",
"If checked, editors will be resizable and extensible like other programs instead of zooming in upon maximization.",
"resizableEditors"));
+ add(new Checkbox(
+ "Intensive Blur",
+ "If checked, will use more intensive blur that may be laggier but look better.",
+ "intensiveBlur"));
}
}
\ No newline at end of file
diff --git a/source/funkin/editors/character/CharacterEditor.hx b/source/funkin/editors/character/CharacterEditor.hx
index 22bbd600..2fbaab43 100644
--- a/source/funkin/editors/character/CharacterEditor.hx
+++ b/source/funkin/editors/character/CharacterEditor.hx
@@ -38,8 +38,13 @@ class CharacterEditor extends UIState
public var curAnim:Int = 0;
public var playingAnim:UIText;
+ public var currentChar:UIText;
public var movingCamText:UIText;
+ //Healthbar
+ public var healthBarBG:FlxSprite;
+ public var icon:FlxSprite;
+
public var camZoom(default, set):Float = 1;
public function new(charName:String)
@@ -85,16 +90,49 @@ class CharacterEditor extends UIState
// UI
loadUI();
- playingAnim = new UIText((FlxG.width / 2), 30, -1, 'Animation:\n${char.characterData.animations[curAnim].name}', 24);
+ playingAnim = new UIText(846.62, 64.23, 0, 'Animation: ${char.characterData.animations[curAnim].name}', 24);
+ playingAnim.alignment = LEFT;
playingAnim.cameras = [uiCamera];
+ currentChar = new UIText(846.62, 30.23, 0, 'Character: ${char.curCharacter}', 24);
+ currentChar.alignment = LEFT;
+ currentChar.cameras = [uiCamera];
+
movingCamText = new UIText((FlxG.width / 4) - 310, (FlxG.height / 2), -1,
"Press the left mouse button anywhere on this stage to set the character's camera position.", 24);
movingCamText.cameras = [uiCamera];
movingCamText.visible = false;
+ //Health Bar
+ healthBarBG = new FlxSprite(747, 102).loadGraphic(Paths.image('game/healthBar'));
+ healthBarBG.setGraphicSize(399,13);
+ healthBarBG.scrollFactor.set();
+ healthBarBG.cameras = [uiCamera];
+
+
+ var charData:CharacterData;
+ charData = char.characterData;
+
+ var path = Paths.image('icons/${charData.icon}');
+ if (!Assets.exists(path)) path = Paths.image('icons/face');
+
+ //Show both Losing Normal Icons
+ icon = new FlxSprite(754, 86).loadGraphic(path);
+ icon.scale.set(0.5,0.5);
+ icon.scrollFactor.set();
+ icon.cameras = [uiCamera];
+
+
+
+
+
+ healthBarBG.color = charData.iconColor;
+
// Top Menu
+ add(currentChar);
add(playingAnim);
+ add(icon);
+ add(healthBarBG);
add(movingCamText);
add(topMenuSpr);
add(uiGroup);
@@ -108,11 +146,22 @@ class CharacterEditor extends UIState
changeAnim();
moveCharPos();
detectCamClick();
+ mouseControl();
ghostChar.setPosition(char.x, char.y);
super.update(elapsed);
}
+ public function reloadIcon()
+ {
+ var charData:CharacterData;
+ charData = char.characterData;
+
+ var path = Paths.image('icons/${charData.icon}');
+ if (!Assets.exists(path)) path = Paths.image('icons/face');
+ icon.loadGraphic(path);
+ }
+
public function searchAnim(name:String, ?array:Array):AnimData
{
if (array == null)
@@ -186,6 +235,13 @@ class CharacterEditor extends UIState
animAtlas = (char.animateAtlas != null ? char.animateAtlas : null);
+ currentChar.text = 'Character: ${char.curCharacter}';
+ healthBarBG.color = charData.iconColor;
+ reloadIcon();
+
+
+ trace(charData.iconColor);
+
updateCharPos(charData.offsetX, charData.offsetY);
updatePointerPos();
mixDataToChar(char, charData);
@@ -255,7 +311,8 @@ class CharacterEditor extends UIState
label: "File",
childs: [
{
- label: "New"
+ label: "New",
+ onSelect: new_character
},
null,
{
@@ -509,6 +566,18 @@ class CharacterEditor extends UIState
ghostChar.playAnim(char.characterData.animations[curAnim].name, true);
}
+ public function mouseControl()
+ {
+ if (FlxG.mouse.justReleasedRight) {
+ closeCurrentContextMenu();
+ openContextMenu(topMenu[1].childs);
+ }
+
+ if (FlxG.mouse.wheel != 0) {
+ camZoom += (FlxG.mouse.wheel / 10);
+ }
+ }
+
function controlCharacter()
{
var controlArray:Array = [
@@ -607,6 +676,10 @@ class CharacterEditor extends UIState
if (camZoom < 0.1)
camZoom = 0.1;
}
+
+
+
+
}
function changeAnim()
@@ -624,7 +697,7 @@ class CharacterEditor extends UIState
trace(char.characterData.animations[curAnim]);
char.playAnim(char.characterData.animations[curAnim].name, false);
- playingAnim.text = 'Animation:\n${char.characterData.animations[curAnim].name}';
+ playingAnim.text = 'Animation: ${char.characterData.animations[curAnim].name}';
}
if (space)
@@ -659,6 +732,10 @@ class CharacterEditor extends UIState
super.destroy();
}
+ function new_character(_)
+ FlxG.state.openSubState(new NewCharacter(char, ghostChar, this));
+
+
function edit_properties_window(_)
FlxG.state.openSubState(new CharacterProperties(char, ghostChar, this));
diff --git a/source/funkin/editors/character/HelpControls.hx b/source/funkin/editors/character/HelpControls.hx
index a2d6855e..41d6a991 100644
--- a/source/funkin/editors/character/HelpControls.hx
+++ b/source/funkin/editors/character/HelpControls.hx
@@ -14,7 +14,8 @@ class HelpControls extends UISubstateWindow
super.create();
- var helpText = new UIText(windowSpr.x + 25, windowSpr.y + 240, -1, "Left/Right/Up/Down Arrow: To change the offset of the current\nplaying animation.\n
+ var helpText = new UIText(windowSpr.x + 25, windowSpr.y + 45, -1, "Left/Right/Up/Down Arrow: To change the offset of the current\nplaying animation.\n
+W/A/S/D: To move the camera.\n
Left mouse button on the character: Change character's position.\nK to change to prev anim, L to change to new anim
Space to play animation
@@ -22,7 +23,7 @@ I to zoom in
O to zoom out", 24);
add(helpText);
- var closeButton = new UIButton(helpText.x, helpText.y + 160, "Close", function()
+ var closeButton = new UIButton(helpText.x, windowSpr.y + 500, "Close", function()
{
close();
});
diff --git a/source/funkin/editors/character/NewCharacter.hx b/source/funkin/editors/character/NewCharacter.hx
new file mode 100644
index 00000000..1a729a12
--- /dev/null
+++ b/source/funkin/editors/character/NewCharacter.hx
@@ -0,0 +1,172 @@
+package funkin.editors.character;
+
+import flixel.util.FlxColor;
+import flixel.math.FlxPoint;
+import funkin.backend.utils.XMLUtil.AnimData;
+import funkin.game.Character;
+import funkin.editors.character.DeleteAnimScreen;
+
+class NewCharacter extends UISubstateWindow
+{
+ public var char:Character;
+ public var ghostChar:Character;
+ public var charData:CharacterData;
+
+ public var applyButton:UIButton;
+ public var nextButton:UIButton;
+ public var cancelButton:UIButton;
+ public var editor:CharacterEditor;
+
+ public var curAnimData:AnimData;
+
+ public var spriteFile:UITextBox;
+ public var gameOverChar:UITextBox;
+ public var healthIcon:UITextBox;
+ public var iconColor:UITextBox;
+ public var flipX:UICheckbox;
+ public var isPlayer:UICheckbox;
+ public var isGF:UICheckbox;
+ public var antialiasing:UICheckbox;
+ public var scale:UITextBox;
+ public var holdTime:UITextBox;
+
+ public function new(char:Character, ghostChar, editor:CharacterEditor)
+ {
+ super();
+ this.char = char;
+ this.ghostChar = ghostChar;
+ this.charData = char.characterData;
+ this.editor = editor;
+
+ //TO DO: Generate and Save
+ //----
+
+
+ //Delete old Animaitons
+ }
+
+ public override function create()
+ {
+ winTitle = 'Create New Character';
+ winWidth = 960;
+
+ super.create();
+
+ // Offsets
+ var y_ofs = 60;
+ var x_ofs = 60;
+ var y_text_ofs = 20;
+
+ // Character Properties
+ spriteFile = new UITextBox(windowSpr.x + 50, windowSpr.y + 10 + y_ofs, charData.sprite);
+ add(spriteFile);
+ add(new UIText(spriteFile.x, spriteFile.y - y_text_ofs, -1, "Image/Atlas file: "));
+
+ gameOverChar = new UITextBox(spriteFile.x + spriteFile.bWidth + x_ofs, spriteFile.y, charData.gameOverChar);
+ add(gameOverChar);
+ add(new UIText(gameOverChar.x, gameOverChar.y - y_text_ofs, -1, "Game Over character: "));
+
+ healthIcon = new UITextBox(spriteFile.x, spriteFile.y + y_ofs, charData.icon);
+ add(healthIcon);
+ add(new UIText(healthIcon.x, healthIcon.y - y_text_ofs, -1, "Health Icon: "));
+
+ iconColor = new UITextBox(healthIcon.x + healthIcon.bWidth + x_ofs, healthIcon.y, CharacterConfig.rgbToString(charData.iconColor));
+ add(iconColor);
+ add(new UIText(iconColor.x, iconColor.y - y_text_ofs, -1, "Icon color (RGB): "));
+
+ flipX = new UICheckbox(healthIcon.x, healthIcon.y + y_ofs, "Flip X", charData.flipX);
+ add(flipX);
+
+ antialiasing = new UICheckbox(flipX.x + flipX.field.width + x_ofs, flipX.y, "Antialiasing", charData.antialiasing);
+ add(antialiasing);
+
+ isPlayer = new UICheckbox(flipX.x, flipX.y + y_ofs, "Playable Character", charData.isPlayer);
+ add(isPlayer);
+
+ isGF = new UICheckbox(isPlayer.x + isPlayer.field.width + x_ofs, isPlayer.y, "GF Character", charData.isGF);
+ add(isGF);
+
+ scale = new UITextBox(isPlayer.x, isPlayer.y + y_ofs, Std.string(charData.scale));
+ add(scale);
+ add(new UIText(scale.x, scale.y - y_text_ofs, -1, "Scale: "));
+
+ holdTime = new UITextBox(scale.x + scale.bWidth + y_ofs, scale.y, Std.string(charData.holdTime));
+ add(holdTime);
+ add(new UIText(holdTime.x, holdTime.y - y_text_ofs, -1, "Hold time: "));
+
+ // Apply / Cancel buttons
+
+
+ applyButton = new UIButton(windowSpr.x - x_ofs - 70, windowSpr.y, "Apply", function()
+ {
+
+ updateProperties(spriteFile.label.text, healthIcon.label.text, CharacterConfig.stringToRGB(healthIcon.label.text), flipX.checked,
+ antialiasing.checked, isPlayer.checked, isGF.checked, Std.parseFloat(scale.label.text), Std.parseFloat(holdTime.label.text), gameOverChar.label.text);
+
+ //TO DO: Add a Animation
+ });
+ add(applyButton);
+
+ cancelButton = new UIButton(applyButton.x, applyButton.y + y_ofs, "Cancel", function()
+ {
+ close();
+ });
+ add(cancelButton);
+ }
+
+ public function updateProperties(sprite:String, healthIcon:String, iconColor:FlxColor, flipX:Bool, antialiasing:Bool, isPlayer:Bool, isGF:Bool,
+ scale:Float, holdTime:Float, gameOverChar:String)
+ {
+ // Character Data
+ charData.sprite = sprite;
+ charData.icon = healthIcon;
+ charData.iconColor = iconColor;
+ charData.flipX = flipX;
+ charData.antialiasing = antialiasing;
+ charData.isPlayer = isPlayer;
+ charData.isGF = isGF;
+ charData.scale = scale;
+ charData.holdTime = holdTime;
+ charData.gameOverChar = gameOverChar;
+
+ //Bring Player Char to Default Position for User
+ if(isPlayer)
+ {
+ charData.offsetX = 770;
+ charData.offsetY = 410;
+ }
+ else if(isGF)
+ {
+ charData.offsetX = 400;
+ charData.offsetY = 330;
+ }
+ else
+ {
+ charData.offsetX = 100;
+ charData.offsetY = 410;
+ }
+
+
+
+
+ editor.reloadChar(!char.isPlayer, charData);
+ editor.reloadStage();
+ editor.loadCross();
+
+
+
+ }
+
+ public function removeAnimation(anim:AnimData)
+ {
+ var refreshAnim:Bool = false;
+ if (char.animation.curAnim != null && anim.name == char.animation.curAnim.name)
+ refreshAnim = true;
+
+ if (char.animation.getByName(anim.name) != null)
+ char.animation.remove(anim.name);
+ if (char.animOffsets.exists(anim.name))
+ char.animOffsets.remove(anim.name);
+ char.characterData.animations.remove(anim);
+ }
+}
diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx
index 748d0922..96057a43 100644
--- a/source/funkin/editors/charter/Charter.hx
+++ b/source/funkin/editors/charter/Charter.hx
@@ -54,6 +54,7 @@ class Charter extends UIState {
public var topLimit:FlxSprite;
public var strumlineInfoBG:FlxSprite;
+ public var strumlineAddButton:CharterStrumlineExtraButton;
public var hitsound:FlxSound;
public var metronome:FlxSound;
@@ -114,7 +115,7 @@ class Charter extends UIState {
},
null,
{
- label: "Save Mata",
+ label: "Save Meta",
keybind: [CONTROL, ALT, S],
onSelect: _file_meta_save,
},
@@ -203,22 +204,6 @@ class Charter extends UIState {
}
]
},
- {
- label: "Strumline",
- childs: [
- {
- label: "Create Strumline",
- onSelect: function (_) {
- createStrumline(strumLines.members.length, {
- characters: [],
- type: ADDITIONAL,
- notes: [],
- position: "girlfriend"
- });
- }
- },
- ]
- },
{
label: "Note",
childs: [
@@ -403,6 +388,10 @@ class Charter extends UIState {
strumlineInfoBG.y = 23;
strumlineInfoBG.scrollFactor.set();
+ strumlineAddButton = new CharterStrumlineExtraButton("editors/charter/add-strumline", "Add New");
+ strumlineAddButton.onClick = createStrumWithUI;
+
+ strumlineAddButton.cameras = [charterCamera];
strumlineInfoBG.cameras = [charterCamera];
strumLines.cameras = [charterCamera];
@@ -422,6 +411,7 @@ class Charter extends UIState {
add(conductorFollowerSpr);
add(selectionBox);
add(strumlineInfoBG);
+ add(strumlineAddButton);
add(strumLines);
// add the top menu last OUT of the ui group so that it stays on top
add(topMenuSpr);
@@ -448,13 +438,6 @@ class Charter extends UIState {
for(strL in PlayState.SONG.strumLines)
createStrumline(strumLines.members.length, strL, false);
- trace("sorting notes...");
- notesGroup.sort(function(i, n1, n2) {
- if (n1.step == n2.step)
- return FlxSort.byValues(FlxSort.ASCENDING, n1.id, n2.id);
- return FlxSort.byValues(FlxSort.ASCENDING, n1.step, n2.step);
- });
-
trace("generating events...");
var __last:CharterEvent = null;
var __lastTime:Float = Math.NaN;
@@ -695,8 +678,6 @@ class Charter extends UIState {
// STRUMLINE DELETION/CREATION
public function createStrumline(strumLineID:Int, strL:ChartStrumLine, addToUndo:Bool = true) {
- selection = []; // dont fuck with selected notes
-
var cStr = new CharterStrumline(strL);
strumLines.insert(strumLineID, cStr);
@@ -719,9 +700,10 @@ class Charter extends UIState {
}
public function deleteStrumline(strumLineID:Int, addToUndo:Bool = true) {
- selection = []; // dont fuck with selected notes
+ removeStrumlineFromSelection(strumLineID);
var strL = strumLines.members[strumLineID].strumLine;
+ strumLines.members[strumLineID].destroy();
strumLines.members.remove(strumLines.members[strumLineID]);
var deletedstrumNotes:Array = [];
@@ -769,6 +751,33 @@ class Charter extends UIState {
return -1;
}
+ public function createStrumWithUI() {
+ FlxG.state.openSubState(new CharterStrumlineScreen(strumLines.members.length, null, (_) -> {
+ if (_ != null) createStrumline(strumLines.members.length, _);
+ }));
+ }
+
+ public inline function deleteStrumlineFromData(strL:ChartStrumLine)
+ deleteStrumline(getStrumlineID(strL));
+
+ public inline function editStrumline(strL:ChartStrumLine) {
+ var strID = getStrumlineID(strL);
+ FlxG.state.openSubState(new CharterStrumlineScreen(strID, strL, (_) -> {
+ strumLines.members[strID].strumLine = _;
+ strumLines.members[strID].updateInfo();
+ }));
+ }
+
+ public inline function removeStrumlineFromSelection(strumLineID:Int) {
+ var i = 0;
+ while(i < selection.length) {
+ var note = selection[i];
+ if (Std.int(note.id / 4) == strumLineID)
+ selection.remove(note);
+ else i++;
+ }
+ }
+
// UNDO/REDO LOGIC
#if REGION
public inline function addToUndo(c:CharterChange) {
@@ -779,8 +788,13 @@ class Charter extends UIState {
}
#end
- public inline function sortNotes()
- notesGroup.sort((i, c1, c2) -> FlxSort.byValues(i, c1.step, c2.step), FlxSort.ASCENDING);
+ public inline function sortNotes() {
+ notesGroup.sort(function(i, n1, n2) {
+ if (n1.step == n2.step)
+ return FlxSort.byValues(FlxSort.ASCENDING, n1.id, n2.id);
+ return FlxSort.byValues(FlxSort.ASCENDING, n1.step, n2.step);
+ });
+ }
#end
var __crochet:Float;
@@ -865,6 +879,9 @@ class Charter extends UIState {
str.x = id * 40 * 4;
str.y = strumlineInfoBG.y;
}
+
+ strumlineAddButton.x = strumLines.members.length * (40 * 4);
+ strumlineAddButton.y = strumlineInfoBG.y;
}
var zoom(default, set):Float = 0;
@@ -1213,4 +1230,4 @@ enum abstract CharterGridActionType(Int) {
var BOX = 1;
var DRAG = 2;
var INVALID_DRAG = 3;
-}
\ No newline at end of file
+}
diff --git a/source/funkin/editors/charter/CharterEventScreen.hx b/source/funkin/editors/charter/CharterEventScreen.hx
index 3ccb6ff0..8859738e 100644
--- a/source/funkin/editors/charter/CharterEventScreen.hx
+++ b/source/funkin/editors/charter/CharterEventScreen.hx
@@ -34,6 +34,7 @@ class CharterEventScreen extends UISubstateWindow {
super.create();
FlxG.sound.music.pause(); // prevent the song from continuing
+ Charter.instance.vocals.pause();
var bg:FlxSprite = new FlxSprite(windowSpr.x + 1, windowSpr.y + 31, Paths.image('editors/ui/scrollbar-bg'));
bg.setGraphicSize(30, windowSpr.bHeight - 32);
diff --git a/source/funkin/editors/charter/CharterStrumline.hx b/source/funkin/editors/charter/CharterStrumline.hx
index 4ee75ebf..e2b746a9 100644
--- a/source/funkin/editors/charter/CharterStrumline.hx
+++ b/source/funkin/editors/charter/CharterStrumline.hx
@@ -39,13 +39,23 @@ class CharterStrumline extends UISprite {
}
public override function update(elapsed:Float) {
- healthIcon.follow(this, ((40 * 4) - healthIcon.width) / 2, 0);
+ if (healthIcon != null)
+ healthIcon.follow(this, ((40 * 4) - healthIcon.width) / 2, 0);
button.follow(this, 0, 95);
super.update(elapsed);
}
public function updateInfo() {
- // todo
+ members.remove(healthIcon);
+ healthIcon.destroy();
+
+ var icon = Character.getIconFromCharName(strumLine.characters != null ? strumLine.characters[0] : null);
+
+ healthIcon = new HealthIcon(icon);
+ healthIcon.scale.set(80 / 150, 80 / 150);
+ healthIcon.updateHitbox();
+ healthIcon.alpha = strumLine.visible ? 1 : 0.4;
+ members.push(healthIcon);
}
}
@@ -65,28 +75,6 @@ class CharterStrumlineButton extends UITopMenuButton {
public override function openContextMenu() {
contextMenu = [
- {
- label: "Player",
- onSelect: function(_) {
- strLine.strumLine.type = PLAYER;
- },
- icon: strLine.strumLine.type == PLAYER ? 1 : 0
- },
- {
- label: "Opponent",
- onSelect: function(_) {
- strLine.strumLine.type = OPPONENT;
- },
- icon: strLine.strumLine.type == OPPONENT ? 1 : 0
- },
- {
- label: "Additional",
- onSelect: function(_) {
- strLine.strumLine.type = ADDITIONAL;
- },
- icon: strLine.strumLine.type == ADDITIONAL ? 1 : 0
- },
- null,
{
label: "Visible",
onSelect: function(_) {
@@ -105,9 +93,15 @@ class CharterStrumlineButton extends UITopMenuButton {
},
null,
{
- label: "Delete",
+ label: "Edit",
onSelect: function (_) {
- Charter.instance.deleteStrumline(Charter.instance.getStrumlineID(strLine.strumLine));
+ Charter.instance.editStrumline(strLine.strumLine);
+ }
+ },
+ {
+ label: "Delete",
+ onSelect: function (_) {
+ Charter.instance.deleteStrumlineFromData(strLine.strumLine);
}
}
];
diff --git a/source/funkin/editors/charter/CharterStrumlineExtraButton.hx b/source/funkin/editors/charter/CharterStrumlineExtraButton.hx
new file mode 100644
index 00000000..b1fc7ad3
--- /dev/null
+++ b/source/funkin/editors/charter/CharterStrumlineExtraButton.hx
@@ -0,0 +1,52 @@
+package funkin.editors.charter;
+
+import flixel.math.FlxPoint;
+
+class CharterStrumlineExtraButton extends UISprite {
+ public var button:UISprite;
+ public var text:UIText;
+
+ public var onClick:Void->Void;
+
+ public override function new(imagePath:String, text:String) {
+ super();
+
+ scrollFactor.set(1, 0);
+ alpha = 0;
+
+ button = new UISprite();
+ button.loadGraphic(Paths.image(imagePath));
+ button.scale.set(0.75,0.75);
+ button.updateHitbox();
+ button.antialiasing = false;
+ members.push(button);
+
+ this.text = new UIText(0,0, 160, text);
+ this.text.alignment = CENTER;
+ members.push(this.text);
+ }
+
+ var buttonScale:FlxPoint = FlxPoint.get(0,0);
+
+ public override function update(elapsed:Float) {
+ button.follow(this, ((40 * 4) - button.width) / 2, 18);
+ text.follow(this, 0, 84);
+
+ super.update(elapsed);
+
+ button.__rect.x = button.x;
+ button.__rect.y = button.y;
+ button.__rect.width = button.width;
+ button.__rect.height = button.height;
+ if(UIState.state.isOverlapping(button, button.__rect)) {
+ buttonScale.set(0.85, 0.85);
+ if (FlxG.mouse.justReleased && onClick != null) onClick();
+ }
+ else buttonScale.set(0.75, 0.75);
+
+ button.scale.set(
+ FlxMath.lerp(button.scale.x, buttonScale.x, 1/6),
+ FlxMath.lerp(button.scale.y, buttonScale.y, 1/6)
+ );
+ }
+}
\ No newline at end of file
diff --git a/source/funkin/editors/charter/CharterStrumlineScreen.hx b/source/funkin/editors/charter/CharterStrumlineScreen.hx
new file mode 100644
index 00000000..b67d40a7
--- /dev/null
+++ b/source/funkin/editors/charter/CharterStrumlineScreen.hx
@@ -0,0 +1,149 @@
+package funkin.editors.charter;
+
+import flixel.math.FlxPoint;
+import funkin.game.Note;
+import funkin.game.Character;
+import funkin.game.HealthIcon;
+import funkin.backend.chart.ChartData.ChartStrumLine;
+
+class CharterStrumlineScreen extends UISubstateWindow {
+ public var strumLineID:Int = -1;
+ public var strumLine:ChartStrumLine;
+
+ public var charactersTextBox:UITextBox;
+ public var typeDropdown:UIDropDown;
+ public var stagePositionDropdown:UIDropDown;
+ public var hudScaleStepper:UINumericStepper;
+ public var hudXStepper:UINumericStepper;
+ public var hudYStepper:UINumericStepper;
+
+ public var characterIcons:Array = [];
+
+ public var saveButton:UIButton;
+ public var closeButton:UIButton;
+
+ private var onSave:ChartStrumLine -> Void = null;
+
+ public function new(strumLineID:Int, strumLine:ChartStrumLine, ?onSave:ChartStrumLine->Void) {
+ super();
+ this.strumLineID = strumLineID;
+ this.strumLine = strumLine;
+ if (onSave != null) this.onSave = onSave;
+ }
+
+ public override function create() {
+ var creatingStrumLine:Bool = strumLine == null;
+
+ if (creatingStrumLine)
+ strumLine = {
+ characters: ["dad"],
+ type: OPPONENT,
+ notes: [],
+ position: "dad",
+ visible: true
+ };
+
+ winTitle = creatingStrumLine ? 'Creating Strumline #$strumLineID' : 'Strumline #$strumLineID properties';
+ winWidth = 690; winHeight = 334;
+
+ FlxG.sound.music.pause();
+ Charter.instance.vocals.pause();
+
+ super.create();
+
+ function addLabelOn(ui:UISprite, text:String)
+ add(new UIText(ui.x, ui.y - 24, 0, text));
+
+ var title:UIText;
+ add(title = new UIText(windowSpr.x + 20, windowSpr.y + 30 + 16, 0, creatingStrumLine ? "Create New Strumline" : "Edit Strumline Properties", 28));
+
+ charactersTextBox = new UITextBox(title.x, title.y + title.height + 38, strumLine.characters.join(", "));
+ charactersTextBox.onChange = (newChars:String) -> {
+ updateCharacterIcons([for (char in newChars.split(",")) char.trim()]);
+ };
+ add(charactersTextBox);
+ addLabelOn(charactersTextBox, "Characters");
+
+ updateCharacterIcons(strumLine.characters);
+
+ typeDropdown = new UIDropDown(charactersTextBox.x, charactersTextBox.y + 32 + 58, 200, 32, ["OPPONENT", "PLAYER", "ADDITIONAL"], strumLine.type);
+ add(typeDropdown);
+ addLabelOn(typeDropdown, "Type");
+
+ var stagePositionI = strumLine.position == null ? strumLine.type : ["DAD", "BOYFRIEND", "GIRLFRIEND"].indexOf(strumLine.position.toUpperCase());
+
+ stagePositionDropdown = new UIDropDown(typeDropdown.x + 200 - 32 + 26, typeDropdown.y, 200, 32, ["DAD", "BOYFRIEND", "GIRLFRIEND"], stagePositionI);
+ add(stagePositionDropdown);
+ addLabelOn(stagePositionDropdown, "Stage Position");
+
+ hudScaleStepper = new UINumericStepper(stagePositionDropdown.x + 200 - 32 + 26, stagePositionDropdown.y, strumLine.strumScale == null ? 1 : strumLine.strumScale, 0.001, 2, null, null, 74);
+ add(hudScaleStepper);
+ addLabelOn(hudScaleStepper, "Scale");
+
+ 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), 50) :
+ FlxPoint.get(strumLine.strumPos[0], strumLine.strumPos[1]);
+
+ hudXStepper = new UINumericStepper(hudScaleStepper.x + 80 - 32 + 26, hudScaleStepper.y, startingPos.x, 0.001, 2, null, null, 84);
+ add(hudXStepper);
+ addLabelOn(hudXStepper, "Hud Position (X,Y)");
+
+ add(new UIText(hudXStepper.x + 84 - 32 + 0, hudXStepper.y + 9, 0, ",", 22));
+
+ hudYStepper = new UINumericStepper(hudXStepper.x + 84 - 32 + 26, hudXStepper.y, startingPos.y, 0.001, 2, null, null, 84);
+ add(hudYStepper);
+
+ saveButton = new UIButton(windowSpr.x + windowSpr.bWidth - 20 - 125, windowSpr.y + windowSpr.bHeight - 16 - 32, "Save & Close", function() {
+ saveStrumline();
+ close();
+ }, 125);
+ add(saveButton);
+
+ closeButton = new UIButton(saveButton.x - 20, saveButton.y, creatingStrumLine ? "Cancel" : "Close", function() {
+ if (creatingStrumLine) onSave(null);
+ close();
+ }, 125);
+ add(closeButton);
+ closeButton.x -= closeButton.bWidth;
+ }
+
+ function updateCharacterIcons(characters:Array) {
+ for (icon in characterIcons) {
+ remove(icon);
+ icon.destroy();
+ }
+ characterIcons = [];
+
+ for (i => char in characters) {
+ var iconSprite = new HealthIcon(Character.getIconFromCharName(char));
+ iconSprite.scrollFactor.set(1,1);
+ iconSprite.scale.set(0.5, 0.5);
+ iconSprite.updateHitbox();
+
+ iconSprite.setPosition(
+ charactersTextBox.x + 320 + 8 + ((iconSprite.width + 4) * i),
+ (charactersTextBox.y + 16) - (iconSprite.height/2)
+ );
+ add(iconSprite);
+ characterIcons.push(iconSprite);
+ }
+ }
+
+ function saveStrumline() {
+ for (stepper in [hudXStepper, hudYStepper, hudScaleStepper])
+ @:privateAccess stepper.__onChange(stepper.label.text);
+
+ strumLine = {
+ characters: [for (char in charactersTextBox.label.text.split(",")) char.trim()],
+ type: typeDropdown.index,
+ notes: strumLine.notes,
+ position: ["DAD", "BOYFRIEND", "GIRLFRIEND"][stagePositionDropdown.index].toLowerCase(),
+ visible: strumLine.visible,
+ strumPos: [hudXStepper.value, hudYStepper.value],
+ strumScale: hudScaleStepper.value
+ };
+ if (onSave != null) onSave(strumLine);
+ }
+}
\ No newline at end of file
diff --git a/source/funkin/editors/charter/MetaDataScreen.hx b/source/funkin/editors/charter/MetaDataScreen.hx
index 66004ac5..c13d928e 100644
--- a/source/funkin/editors/charter/MetaDataScreen.hx
+++ b/source/funkin/editors/charter/MetaDataScreen.hx
@@ -35,7 +35,9 @@ class MetaDataScreen extends UISubstateWindow {
winWidth = 748 - 32 + 40;
super.create();
+
FlxG.sound.music.pause();
+ Charter.instance.vocals.pause();
function addLabelOn(ui:UISprite, text:String)
add(new UIText(ui.x, ui.y - 24, 0, text));
@@ -132,6 +134,9 @@ class MetaDataScreen extends UISubstateWindow {
}
public function saveMeta() {
+ for (stepper in [bpmStepper, stepsPerBeatStepper, beatsPerMesureStepper])
+ @:privateAccess stepper.__onChange(stepper.label.text);
+
PlayState.SONG.meta = {
name: songNameTextBox.label.text,
bpm: bpmStepper.value,
diff --git a/source/funkin/editors/ui/UISubstateWindow.hx b/source/funkin/editors/ui/UISubstateWindow.hx
index ed87456e..95d02abf 100644
--- a/source/funkin/editors/ui/UISubstateWindow.hx
+++ b/source/funkin/editors/ui/UISubstateWindow.hx
@@ -7,7 +7,7 @@ import funkin.backend.shaders.CustomShader;
// TODO: make UIWarningSubstate extend this
class UISubstateWindow extends MusicBeatSubstate {
var camShaders:Array = [];
- var blurShader:CustomShader = new CustomShader("engine/editorBlurFast");
+ var blurShader:CustomShader = Options.intensiveBlur ? new CustomShader("engine/editorBlur") : new CustomShader("engine/editorBlurFast");
var titleSpr:UIText;
var messageSpr:UIText;
diff --git a/source/funkin/editors/ui/UIWarningSubstate.hx b/source/funkin/editors/ui/UIWarningSubstate.hx
index 88948721..2cf765f4 100644
--- a/source/funkin/editors/ui/UIWarningSubstate.hx
+++ b/source/funkin/editors/ui/UIWarningSubstate.hx
@@ -6,7 +6,7 @@ import funkin.backend.shaders.CustomShader;
class UIWarningSubstate extends MusicBeatSubstate {
var camShaders:Array = [];
- var blurShader:CustomShader = new CustomShader("engine/editorBlur");
+ var blurShader:CustomShader = Options.intensiveBlur ? new CustomShader("engine/editorBlur") : new CustomShader("engine/editorBlurFast");
var title:String;
var message:String;
diff --git a/source/funkin/game/PlayState.hx b/source/funkin/game/PlayState.hx
index 2e582599..80ecc19e 100644
--- a/source/funkin/game/PlayState.hx
+++ b/source/funkin/game/PlayState.hx
@@ -623,7 +623,17 @@ class PlayState extends MusicBeatState
}
var strOffset:Float = strumLine.strumLinePos == null ? (strumLine.type == 1 ? 0.75 : 0.25) : strumLine.strumLinePos;
- var strLine = new StrumLine(chars, strOffset, strumLine.type == 2 || (!coopMode && !((strumLine.type == 1 && !opponentMode) || (strumLine.type == 0 && opponentMode))), strumLine.type != 1, coopMode ? (strumLine.type == 1 ? controlsP1 : controlsP2) : controls);
+
+ 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], strumLine.strumPos[1]);
+
+ var strLine = new StrumLine(chars,
+ startingPos,
+ strumLine.strumScale == null ? 1 : strumLine.strumScale,
+ strumLine.type == 2 || (!coopMode && !((strumLine.type == 1 && !opponentMode) || (strumLine.type == 0 && opponentMode))),
+ strumLine.type != 1, coopMode ? (strumLine.type == 1 ? controlsP1 : controlsP2) : controls
+ );
strLine.cameras = [camHUD];
strLine.data = strumLine;
strLine.visible = (strumLine.visible != false);
@@ -1447,81 +1457,21 @@ class PlayState extends MusicBeatState
scripts.event("onNoteHit", event);
if (!event.cancelled) {
- if (event.accuracy != null) {
- accuracyPressedNotes++;
- totalAccuracyAmount += event.accuracy;
-
- updateRating();
- }
- if (event.countAsCombo) combo++;
-
- if (event.showRating || (event.showRating == null && event.player && !note.isSustainNote))
- {
- songScore += score;
-
- var separatedScore:String = Std.string(combo).addZeros(3);
-
- if (combo == 0 || combo >= 10) {
- if (combo >= 10) {
- var comboSpr:FlxSprite = comboGroup.recycleLoop(FlxSprite).loadAnimatedGraphic(Paths.image('${event.ratingPrefix}combo${event.ratingSuffix}'));
- comboSpr.resetSprite(comboGroup.x, comboGroup.y);
- comboSpr.acceleration.y = 600;
- comboSpr.velocity.y -= 150;
- comboSpr.velocity.x += FlxG.random.int(1, 10);
-
- comboSpr.scale.set(event.ratingScale, event.ratingScale);
- comboSpr.antialiasing = event.ratingAntialiasing;
-
- comboSpr.updateHitbox();
-
- FlxTween.tween(comboSpr, {alpha: 0}, 0.2, {
- onComplete: function(tween:FlxTween)
- {
- comboSpr.visible = comboSpr.active = false;
- },
- startDelay: Conductor.crochet * 0.001
- });
- }
- for (i in 0...separatedScore.length)
- {
- var numScore:FlxSprite = comboGroup.recycleLoop(FlxSprite).loadAnimatedGraphic(Paths.image('${event.ratingPrefix}num${separatedScore.charAt(i)}${event.ratingSuffix}'));
- numScore.resetSprite(comboGroup.x + (43 * i) - 90, comboGroup.y + 80);
- numScore.antialiasing = event.numAntialiasing;
- numScore.scale.set(event.numScale, event.numScale);
- numScore.updateHitbox();
-
- numScore.acceleration.y = FlxG.random.int(200, 300);
- numScore.velocity.y -= FlxG.random.int(140, 160);
- numScore.velocity.x = FlxG.random.float(-5, 5);
-
- FlxTween.tween(numScore, {alpha: 0}, 0.2, {
- onComplete: function(tween:FlxTween)
- {
- numScore.visible = numScore.active = false;
- },
- startDelay: Conductor.crochet * 0.002
- });
- }
+ if (!note.isSustainNote) {
+ if (event.countScore) songScore += event.score;
+ if (event.accuracy != null) {
+ accuracyPressedNotes++;
+ totalAccuracyAmount += event.accuracy;
+ updateRating();
+ }
+ if (event.countAsCombo) combo++;
+
+ if (event.showRating || (event.showRating == null && event.player))
+ {
+ displayCombo(event);
+ displayRating(daRating, event);
+ ratingNum += 1;
}
-
- var rating:FlxSprite = comboGroup.recycleLoop(FlxSprite);
- rating.resetSprite(comboGroup.x + -40, comboGroup.y + -60);
- rating.loadAnimatedGraphic(Paths.image('${event.ratingPrefix}$daRating${event.ratingSuffix}'));
- rating.acceleration.y = 550;
- rating.velocity.y -= FlxG.random.int(140, 175);
- rating.velocity.x -= FlxG.random.int(0, 10);
- rating.scale.set(event.ratingScale, event.ratingScale);
- rating.antialiasing = event.ratingAntialiasing;
- rating.updateHitbox();
-
- FlxTween.tween(rating, {alpha: 0}, 0.2, {
- startDelay: Conductor.crochet * 0.001,
- onComplete: function(tween:FlxTween) {
- rating.visible = rating.active = false;
- }
- });
-
- ratingNum += 1;
}
if (strumLine != null) strumLine.addHealth(event.healthGain);
@@ -1549,6 +1499,84 @@ class PlayState extends MusicBeatState
if (event.deleteNote && !note.isSustainNote) strumLine.deleteNote(note);
}
+ public function displayRating(myRating:String, ?evt:NoteHitEvent = null):Void {
+ var pre:String = evt != null ? evt.ratingPrefix : "";
+ var suf:String = evt != null ? evt.ratingSuffix : "";
+
+ var rating:FlxSprite = comboGroup.recycleLoop(FlxSprite);
+ rating.resetSprite(comboGroup.x + -40, comboGroup.y + -60);
+ rating.loadAnimatedGraphic(Paths.image('${pre}${myRating}${suf}'));
+ rating.acceleration.y = 550;
+ rating.velocity.y -= FlxG.random.int(140, 175);
+ rating.velocity.x -= FlxG.random.int(0, 10);
+ if (evt != null) {
+ rating.scale.set(evt.ratingScale,evt.ratingScale);
+ rating.antialiasing = evt.ratingAntialiasing;
+ }
+ rating.updateHitbox();
+
+ FlxTween.tween(rating, {alpha: 0}, 0.2, {
+ startDelay: Conductor.crochet * 0.001,
+ onComplete: function(tween:FlxTween) {
+ rating.kill();
+ }
+ });
+ }
+
+ public function displayCombo(?evt:NoteHitEvent = null):Void {
+ var pre:String = evt != null ? evt.ratingPrefix : "";
+ var suf:String = evt != null ? evt.ratingSuffix : "";
+
+ var separatedScore:String = Std.string(combo).addZeros(3);
+
+ if (combo == 0 || combo >= 10) {
+ if (combo >= 10) {
+ var comboSpr:FlxSprite = comboGroup.recycleLoop(FlxSprite).loadAnimatedGraphic(Paths.image('${pre}combo${suf}'));
+ comboSpr.resetSprite(comboGroup.x, comboGroup.y);
+ comboSpr.acceleration.y = 600;
+ comboSpr.velocity.y -= 150;
+ comboSpr.velocity.x += FlxG.random.int(1, 10);
+
+ if (evt != null) {
+ comboSpr.scale.set(evt.ratingScale, evt.ratingScale);
+ comboSpr.antialiasing = evt.ratingAntialiasing;
+ }
+ comboSpr.updateHitbox();
+
+ FlxTween.tween(comboSpr, {alpha: 0}, 0.2, {
+ onComplete: function(tween:FlxTween)
+ {
+ comboSpr.kill();
+ },
+ startDelay: Conductor.crochet * 0.001
+ });
+ }
+
+ for (i in 0...separatedScore.length)
+ {
+ var numScore:FlxSprite = comboGroup.recycleLoop(FlxSprite).loadAnimatedGraphic(Paths.image('${pre}num${separatedScore.charAt(i)}${suf}'));
+ numScore.resetSprite(comboGroup.x + (43 * i) - 90, comboGroup.y + 80);
+ if (evt != null) {
+ numScore.antialiasing = evt.numAntialiasing;
+ numScore.scale.set(evt.numScale, evt.numScale);
+ }
+ numScore.updateHitbox();
+
+ numScore.acceleration.y = FlxG.random.int(200, 300);
+ numScore.velocity.y -= FlxG.random.int(140, 160);
+ numScore.velocity.x = FlxG.random.float(-5, 5);
+
+ FlxTween.tween(numScore, {alpha: 0}, 0.2, {
+ onComplete: function(tween:FlxTween)
+ {
+ numScore.kill();
+ },
+ startDelay: Conductor.crochet * 0.002
+ });
+ }
+ }
+ }
+
public inline function deleteNote(note:Note)
if (note.strumLine != null)
note.strumLine.deleteNote(note);
@@ -1717,4 +1745,4 @@ typedef PlayStateTransitionData = {
var camFollowX:Float;
var camFollowY:Float;
var camZoom:Float;
-}
\ No newline at end of file
+}
diff --git a/source/funkin/game/StrumLine.hx b/source/funkin/game/StrumLine.hx
index 6e8c23a6..2f0c6ebd 100644
--- a/source/funkin/game/StrumLine.hx
+++ b/source/funkin/game/StrumLine.hx
@@ -1,5 +1,6 @@
package funkin.game;
+import flixel.math.FlxPoint;
import flixel.util.FlxSignal.FlxTypedSignal;
import funkin.backend.scripting.events.*;
@@ -81,12 +82,14 @@ class StrumLine extends FlxTypedGroup {
private inline function set_ghostTapping(b:Bool):Bool
return this.ghostTapping = b;
- private var strumOffset:Float = 0.25;
+ private var startingPos:FlxPoint = FlxPoint.get(0,0);
+ private var strumScale:Float = 1;
- public function new(characters:Array, strumOffset:Float = 0.25, cpu:Bool = false, opponentSide:Bool = true, ?controls:Controls) {
+ public function new(characters:Array, startingPos:FlxPoint, strumScale:Float, cpu:Bool = false, opponentSide:Bool = true, ?controls:Controls) {
super();
this.characters = characters;
- this.strumOffset = strumOffset;
+ this.startingPos = startingPos;
+ this.strumScale = strumScale;
this.cpu = cpu;
this.opponentSide = opponentSide;
this.controls = controls;
@@ -253,7 +256,7 @@ class StrumLine extends FlxTypedGroup {
public function createStrum(i:Int, ?animPrefix:String) {
if (animPrefix == null)
animPrefix = strumAnimPrefix[i % strumAnimPrefix.length];
- var babyArrow:Strum = new Strum((FlxG.width * strumOffset) + (Note.swagWidth * (i - 2)), PlayState.instance.strumLine.y);
+ var babyArrow:Strum = new Strum(startingPos.x + ((Note.swagWidth * strumScale) * i), startingPos.y);
babyArrow.ID = i;
var event = PlayState.instance.scripts.event("onStrumCreation", EventManager.get(StrumCreationEvent).recycle(babyArrow, PlayState.instance.strumLines.members.indexOf(this), i, animPrefix));
@@ -266,7 +269,7 @@ class StrumLine extends FlxTypedGroup {
babyArrow.animation.addByPrefix('red', 'arrowRIGHT');
babyArrow.antialiasing = true;
- babyArrow.setGraphicSize(Std.int(babyArrow.width * 0.7));
+ babyArrow.setGraphicSize(Std.int((babyArrow.width * 0.7) * strumScale));
babyArrow.animation.addByPrefix('static', 'arrow${event.animPrefix.toUpperCase()}');
babyArrow.animation.addByPrefix('pressed', '${event.animPrefix} press', 24, false);
diff --git a/source/funkin/menus/MainMenuState.hx b/source/funkin/menus/MainMenuState.hx
index bbb850c5..9b22383c 100644
--- a/source/funkin/menus/MainMenuState.hx
+++ b/source/funkin/menus/MainMenuState.hx
@@ -76,7 +76,7 @@ class MainMenuState extends MusicBeatState
FlxG.camera.follow(camFollow, null, 0.06);
- var versionShit:FunkinText = new FunkinText(5, FlxG.height - 2, 0, 'Codename Engine v${Application.current.meta.get('version')}\nBeta: Commit ${funkin.backend.system.macros.GitCommitMacro.commitNumber} (${funkin.backend.system.macros.GitCommitMacro.commitHash})\n[TAB] Open Mods menu\n');
+ var versionShit:FunkinText = new FunkinText(5, FlxG.height - 2, 0, 'Codename Engine v${Application.current.meta.get('version')}\nAlpha: Commit ${funkin.backend.system.macros.GitCommitMacro.commitNumber} (${funkin.backend.system.macros.GitCommitMacro.commitHash})\n[TAB] Open Mods menu\n');
versionShit.scrollFactor.set();
versionShit.y -= versionShit.height;
add(versionShit);
diff --git a/source/funkin/options/Options.hx b/source/funkin/options/Options.hx
index a4b38c30..8ac2f947 100644
--- a/source/funkin/options/Options.hx
+++ b/source/funkin/options/Options.hx
@@ -39,6 +39,7 @@ class Options
/**
* EDITORS SETTINGS
*/
+ public static var intensiveBlur:Bool = true;
public static var editorSFX:Bool = true;
public static var resizableEditors:Bool = true;
public static var maxUndos:Int = 120;
diff --git a/source/funkin/options/categories/MiscOptions.hx b/source/funkin/options/categories/MiscOptions.hx
index 374826d0..84605c2d 100644
--- a/source/funkin/options/categories/MiscOptions.hx
+++ b/source/funkin/options/categories/MiscOptions.hx
@@ -6,8 +6,8 @@ class MiscOptions extends OptionsScreen {
super("Miscellaneous", "Use this menu to reset save data or engine settings.");
#if UPDATE_CHECKING
add(new Checkbox(
- "Enable Beta Updates",
- "If checked, will also include beta (prereleases) updates in the update checking.",
+ "Enable Nightly Updates",
+ "If checked, will also include nightly builds in the update checking.",
"betaUpdates"));,
add(new TextOption(
"Check for Updates",
@@ -29,4 +29,4 @@ class MiscOptions extends OptionsScreen {
// TODO: SAVE DATA RESETTING
}));
}
-}
\ No newline at end of file
+}
diff --git a/update.sh b/update.sh
old mode 100644
new mode 100755