Merge branch 'FNF-CNE-Devs:main' into main
This commit is contained in:
@@ -4,5 +4,6 @@ latest/windows/obj/
|
||||
latest/windows/haxe/
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
.haxelib/
|
||||
mods/Baldi's Basics in Funkin'/
|
||||
Vendored
+32
@@ -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)"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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 |
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user