Merge branch 'FNF-CNE-Devs:main' into main

This commit is contained in:
Sword352
2023-07-04 08:23:13 +02:00
committed by GitHub
29 changed files with 748 additions and 167 deletions
+1
View File
@@ -4,5 +4,6 @@ latest/windows/obj/
latest/windows/haxe/
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
.haxelib/
mods/Baldi's Basics in Funkin'/
+32
View File
@@ -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)"
}
]
}
+3 -3
View File
@@ -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
Binary file not shown.

After

Width:  |  Height:  |  Size: 652 B

+11 -8
View File
@@ -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;
}
}
+4 -2
View File
@@ -8,7 +8,9 @@
<git name="hscript-improved" url="https://www.github.com/FNF-CNE-Devs/hscript-improved" ref="custom-classes" />
<git name="discord-rpc" url="https://github.com/Aidan63/linc_discord-rpc"/>
<git name="flxanimate" url="https://github.com/FNF-CNE-Devs/flxanimate/" />
<git name="hxCodec" url="https://github.com/polybiusproxy/hxCodec"/>
<git name="hxCodec" url="https://github.com/polybiusproxy/hxCodec" global="true"/>
<!-- this is to fix a weird haxe bug -->
<git name="hxCodec" url="https://github.com/polybiusproxy/hxCodec" global="false"/>
<!-- Documentation and other features -->
<lib name="dox"/>
@@ -20,4 +22,4 @@
<!-- OpenFL & Lime (Required for Flixel) -->
<lib name="openfl" />
<lib name="lime" />
</libraries>
</libraries>
+1 -1
View File
@@ -182,7 +182,7 @@
<haxedev set='webgl' />
<haxelib name="hscript-improved" />
<haxelib name="linc_discord-rpc" if="DISCORD_RPC"/>
<haxelib name="discord-rpc" if="DISCORD_RPC"/>
<haxelib name="markdown" />
@@ -34,7 +34,6 @@ class BaseGameParser {
position: "girlfriend",
notes: [],
visible: false,
strumLinePos: 0.5
});
}
+4 -1
View File
@@ -36,8 +36,11 @@ typedef ChartStrumLine = {
var type:ChartStrumLineType;
var notes:Array<ChartNote>;
var position:String;
var ?strumLinePos:Float; // 0.25 = default opponent pos, 0.75 = default boyfriend pos
var ?visible:Null<Bool>;
var ?strumPos:Array<Float>;
var ?strumScale:Float;
var ?strumLinePos:Float; // Backwards compatability
}
typedef ChartNote = {
@@ -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;
}
}
}
@@ -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;
+4
View File
@@ -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"));
}
}
@@ -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>):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<Bool> = [
@@ -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));
@@ -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();
});
@@ -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);
}
}
+47 -30
View File
@@ -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<CharterNote> = [];
@@ -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;
}
}
@@ -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);
@@ -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);
}
}
];
@@ -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)
);
}
}
@@ -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<HealthIcon> = [];
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<String>) {
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);
}
}
@@ -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,
+1 -1
View File
@@ -7,7 +7,7 @@ import funkin.backend.shaders.CustomShader;
// TODO: make UIWarningSubstate extend this
class UISubstateWindow extends MusicBeatSubstate {
var camShaders:Array<FlxCamera> = [];
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;
@@ -6,7 +6,7 @@ import funkin.backend.shaders.CustomShader;
class UIWarningSubstate extends MusicBeatSubstate {
var camShaders:Array<FlxCamera> = [];
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;
+104 -76
View File
@@ -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;
}
}
+8 -5
View File
@@ -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<Strum> {
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<Character>, strumOffset:Float = 0.25, cpu:Bool = false, opponentSide:Bool = true, ?controls:Controls) {
public function new(characters:Array<Character>, 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<Strum> {
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<Strum> {
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);
+1 -1
View File
@@ -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);
+1
View File
@@ -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;
@@ -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
}));
}
}
}
Regular → Executable
View File