merge into master

This commit is contained in:
Kade M 2021-06-21 01:22:54 -07:00
parent e03475737d
commit ee21040835
31 changed files with 2300 additions and 431 deletions

128
source/Caching.hx Normal file
View File

@ -0,0 +1,128 @@
package;
import haxe.Exception;
import flixel.tweens.FlxEase;
import flixel.tweens.FlxTween;
import sys.FileSystem;
import sys.io.File;
import flixel.FlxG;
import flixel.FlxSprite;
import flixel.addons.transition.FlxTransitionSprite.GraphicTransTileDiamond;
import flixel.addons.transition.FlxTransitionableState;
import flixel.addons.transition.TransitionData;
import flixel.graphics.FlxGraphic;
import flixel.graphics.frames.FlxAtlasFrames;
import flixel.math.FlxPoint;
import flixel.math.FlxRect;
import flixel.util.FlxColor;
import flixel.util.FlxTimer;
import flixel.text.FlxText;
using StringTools;
class Caching extends MusicBeatState
{
var toBeDone = 0;
var done = 0;
var text:FlxText;
var kadeLogo:FlxSprite;
override function create()
{
FlxG.mouse.visible = false;
FlxG.worldBounds.set(0,0);
text = new FlxText(FlxG.width / 2, FlxG.height / 2 + 300,0,"Loading...");
text.size = 34;
text.alignment = FlxTextAlign.CENTER;
text.alpha = 0;
kadeLogo = new FlxSprite(FlxG.width / 2, FlxG.height / 2).loadGraphic(Paths.image('KadeEngineLogo'));
kadeLogo.x -= kadeLogo.width / 2;
kadeLogo.y -= kadeLogo.height / 2 + 100;
text.y -= kadeLogo.height / 2 - 125;
text.x -= 170;
kadeLogo.setGraphicSize(Std.int(kadeLogo.width * 0.6));
kadeLogo.alpha = 0;
add(kadeLogo);
add(text);
trace('starting caching..');
sys.thread.Thread.create(() -> {
cache();
});
super.create();
}
var calledDone = false;
override function update(elapsed)
{
if (toBeDone != 0 && done != toBeDone)
{
var alpha = HelperFunctions.truncateFloat(done / toBeDone * 100,2) / 100;
kadeLogo.alpha = alpha;
text.alpha = alpha;
text.text = "Loading... (" + done + "/" + toBeDone + ")";
}
super.update(elapsed);
}
function cache()
{
var images = [];
var music = [];
trace("caching images...");
for (i in FileSystem.readDirectory(FileSystem.absolutePath("assets/shared/images/characters")))
{
if (!i.endsWith(".png"))
continue;
images.push(i);
}
trace("caching music...");
for (i in FileSystem.readDirectory(FileSystem.absolutePath("assets/songs")))
{
music.push(i);
}
toBeDone = Lambda.count(images) + Lambda.count(music);
trace("LOADING: " + toBeDone + " OBJECTS.");
for (i in images)
{
var replaced = i.replace(".png","");
FlxG.bitmap.add(Paths.image("characters/" + replaced,"shared"));
trace("cached " + replaced);
done++;
}
for (i in music)
{
FlxG.sound.cache(Paths.inst(i));
FlxG.sound.cache(Paths.voices(i));
trace("cached " + i);
done++;
}
trace("Finished caching...");
FlxG.switchState(new TitleState());
}
}

View File

@ -1239,7 +1239,7 @@ class ChartingState extends MusicBeatState
var daStrumTime = i[0];
var daSus = i[2];
var note:Note = new Note(daStrumTime, daNoteInfo % 4);
var note:Note = new Note(daStrumTime, daNoteInfo % 4,null,false,true);
note.sustainLength = daSus;
note.setGraphicSize(GRID_SIZE, GRID_SIZE);
note.updateHitbox();

View File

@ -571,6 +571,7 @@ class Controls extends FlxActionSet
//trace(FlxKey.fromString(FlxG.save.data.upBind));
removeKeyboard();
KeyBinds.keyCheck();
inline bindKeys(Control.UP, [FlxKey.fromString(FlxG.save.data.upBind), FlxKey.UP]);
inline bindKeys(Control.DOWN, [FlxKey.fromString(FlxG.save.data.downBind), FlxKey.DOWN]);

View File

@ -6,11 +6,11 @@ using StringTools;
class CoolUtil
{
public static var difficultyArray:Array<String> = ['EASY', "NORMAL", "HARD"];
public static var difficultyArray:Array<String> = ['Easy', "Normal", "Hard"];
public static function difficultyString():String
public static function difficultyFromInt(difficulty:Int):String
{
return difficultyArray[PlayState.storyDifficulty];
return difficultyArray[difficulty];
}
public static function coolTextFile(path:String):Array<String>

View File

@ -26,9 +26,11 @@ class FreeplayState extends MusicBeatState
var curDifficulty:Int = 1;
var scoreText:FlxText;
var comboText:FlxText;
var diffText:FlxText;
var lerpScore:Int = 0;
var intendedScore:Int = 0;
var combo:String = '';
private var grpSongs:FlxTypedGroup<Alphabet>;
private var curPlaying:Bool = false;
@ -106,6 +108,10 @@ class FreeplayState extends MusicBeatState
diffText.font = scoreText.font;
add(diffText);
comboText = new FlxText(diffText.x + 100, diffText.y, 0, "", 24);
comboText.font = diffText.font;
add(comboText);
add(scoreText);
changeSelection();
@ -176,6 +182,7 @@ class FreeplayState extends MusicBeatState
lerpScore = intendedScore;
scoreText.text = "PERSONAL BEST:" + lerpScore;
comboText.text = combo + '\n';
var upP = controls.UP_P;
var downP = controls.DOWN_P;
@ -202,13 +209,20 @@ class FreeplayState extends MusicBeatState
if (accepted)
{
trace(StringTools.replace(songs[curSelected].songName," ", "-").toLowerCase());
// adjusting the song name to be compatible
var songFormat = StringTools.replace(songs[curSelected].songName, " ", "-");
switch (songFormat) {
case 'Dad-Battle': songFormat = 'Dadbattle';
case 'Philly-Nice': songFormat = 'Philly';
}
trace(songs[curSelected].songName);
var poop:String = Highscore.formatSong(StringTools.replace(songs[curSelected].songName," ", "-").toLowerCase(), curDifficulty);
var poop:String = Highscore.formatSong(songFormat, curDifficulty);
trace(poop);
PlayState.SONG = Song.loadFromJson(poop, StringTools.replace(songs[curSelected].songName," ", "-").toLowerCase());
PlayState.SONG = Song.loadFromJson(poop, songs[curSelected].songName);
PlayState.isStoryMode = false;
PlayState.storyDifficulty = curDifficulty;
PlayState.storyWeek = songs[curSelected].week;
@ -226,19 +240,19 @@ class FreeplayState extends MusicBeatState
if (curDifficulty > 2)
curDifficulty = 0;
// adjusting the highscore song name to be compatible (changeDiff)
var songHighscore = StringTools.replace(songs[curSelected].songName, " ", "-");
switch (songHighscore) {
case 'Dad-Battle': songHighscore = 'Dadbattle';
case 'Philly-Nice': songHighscore = 'Philly';
}
#if !switch
intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty);
intendedScore = Highscore.getScore(songHighscore, curDifficulty);
combo = Highscore.getCombo(songHighscore, curDifficulty);
#end
switch (curDifficulty)
{
case 0:
diffText.text = "EASY";
case 1:
diffText.text = 'NORMAL';
case 2:
diffText.text = "HARD";
}
diffText.text = CoolUtil.difficultyFromInt(curDifficulty).toUpperCase();
}
function changeSelection(change:Int = 0)
@ -258,9 +272,18 @@ class FreeplayState extends MusicBeatState
curSelected = 0;
// selector.y = (70 * curSelected) + 30;
// adjusting the highscore song name to be compatible (changeSelection)
// would read original scores if we didn't change packages
var songHighscore = StringTools.replace(songs[curSelected].songName, " ", "-");
switch (songHighscore) {
case 'Dad-Battle': songHighscore = 'Dadbattle';
case 'Philly-Nice': songHighscore = 'Philly';
}
#if !switch
intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty);
intendedScore = Highscore.getScore(songHighscore, curDifficulty);
combo = Highscore.getCombo(songHighscore, curDifficulty);
// lerpScore = 0;
#end

7
source/GameDimensions.hx Normal file
View File

@ -0,0 +1,7 @@
package;
class GameDimensions
{
public static var width:Int = 1280;
public static var height:Int = 720;
}

95
source/GlobalVideo.hx Normal file
View File

@ -0,0 +1,95 @@
package;
import openfl.Lib;
class GlobalVideo
{
private static var video:VideoHandler;
private static var webm:WebmHandler;
public static var isWebm:Bool = false;
public static var isAndroid:Bool = false;
public static var daAlpha1:Float = 0.2;
public static var daAlpha2:Float = 1;
public static function setVid(vid:VideoHandler):Void
{
video = vid;
}
public static function getVid():VideoHandler
{
return video;
}
public static function setWebm(vid:WebmHandler):Void
{
webm = vid;
isWebm = true;
}
public static function getWebm():WebmHandler
{
return webm;
}
public static function get():Dynamic
{
if (isWebm)
{
return getWebm();
} else {
return getVid();
}
}
public static function calc(ind:Int):Dynamic
{
var stageWidth:Int = Lib.current.stage.stageWidth;
var stageHeight:Int = Lib.current.stage.stageHeight;
var width:Float = GameDimensions.width;
var height:Float = GameDimensions.height;
//trace("AH: " + stageWidth);
//trace(width);
var ratioX:Float = height / width;
var ratioY:Float = width / height;
var appliedWidth:Float = stageHeight * ratioY;
var appliedHeight:Float = stageWidth * ratioX;
//trace(appliedWidth);
var remainingX:Float = stageWidth - appliedWidth;
var remainingY:Float = stageHeight - appliedHeight;
remainingX = remainingX / 2;
remainingY = remainingY / 2;
appliedWidth = Std.int(appliedWidth);
appliedHeight = Std.int(appliedHeight);
if (appliedHeight > stageHeight)
{
remainingY = 0;
appliedHeight = stageHeight;
}
if (appliedWidth > stageWidth)
{
remainingX = 0;
appliedWidth = stageWidth;
}
switch(ind)
{
case 0:
return remainingX;
case 1:
return remainingY;
case 2:
return appliedWidth;
case 3:
return appliedHeight;
}
return null;
}
}

View File

@ -1,3 +1,5 @@
import flixel.math.FlxMath;
class HelperFunctions
{
public static function truncateFloat( number : Float, precision : Int): Float {
@ -6,4 +8,8 @@ class HelperFunctions
num = Math.round( num ) / Math.pow(10, precision);
return num;
}
public static function GCD(a, b) {
return b == 0 ? FlxMath.absInt(a) : GCD(b, a % b);
}
}

View File

@ -2,12 +2,15 @@ package;
import flixel.FlxG;
using StringTools;
class Highscore
{
#if (haxe >= "4.0.0")
public static var songScores:Map<String, Int> = new Map();
public static var songCombos:Map<String, String> = new Map();
#else
public static var songScores:Map<String, Int> = new Map<String, Int>();
public static var songCombos:Map<String, String> = new Map<String, String>();
#end
@ -32,6 +35,23 @@ class Highscore
}else trace('BotPlay detected. Score saving is disabled.');
}
public static function saveCombo(song:String, combo:String, ?diff:Int = 0):Void
{
var daSong:String = formatSong(song, diff);
var finalCombo:String = combo.split(')')[0].replace('(', '');
if(!FlxG.save.data.botplay)
{
if (songCombos.exists(daSong))
{
if (getComboInt(songCombos.get(daSong)) < getComboInt(finalCombo))
setCombo(daSong, finalCombo);
}
else
setCombo(daSong, finalCombo);
}
}
public static function saveWeekScore(week:Int = 1, score:Int = 0, ?diff:Int = 0):Void
{
@ -64,6 +84,14 @@ class Highscore
FlxG.save.flush();
}
static function setCombo(song:String, combo:String):Void
{
// Reminder that I don't need to format this song, it should come formatted!
songCombos.set(song, combo);
FlxG.save.data.songCombos = songCombos;
FlxG.save.flush();
}
public static function formatSong(song:String, diff:Int):String
{
var daSong:String = song;
@ -76,6 +104,23 @@ class Highscore
return daSong;
}
static function getComboInt(combo:String):Int
{
switch(combo)
{
case 'SDCB':
return 1;
case 'FC':
return 2;
case 'GFC':
return 3;
case 'MFC':
return 4;
default:
return 0;
}
}
public static function getScore(song:String, diff:Int):Int
{
if (!songScores.exists(formatSong(song, diff)))
@ -84,6 +129,14 @@ class Highscore
return songScores.get(formatSong(song, diff));
}
public static function getCombo(song:String, diff:Int):String
{
if (!songCombos.exists(formatSong(song, diff)))
setCombo(formatSong(song, diff), '');
return songCombos.get(formatSong(song, diff));
}
public static function getWeekScore(week:Int, diff:Int):Int
{
if (!songScores.exists(formatSong('week' + week, diff)))
@ -98,5 +151,9 @@ class Highscore
{
songScores = FlxG.save.data.songScores;
}
if (FlxG.save.data.songCombos != null)
{
songCombos = FlxG.save.data.songCombos;
}
}
}
}

279
source/HitGraph.hx Normal file
View File

@ -0,0 +1,279 @@
import flixel.FlxG;
import openfl.display.Bitmap;
import openfl.display.BitmapData;
import openfl.text.TextFieldAutoSize;
import flixel.system.FlxAssets;
import openfl.text.TextFormat;
import flash.display.Graphics;
import flash.display.Shape;
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFormatAlign;
import flixel.math.FlxMath;
import flixel.util.FlxColor;
import flixel.util.FlxDestroyUtil;
/**
* stolen from https://github.com/HaxeFlixel/flixel/blob/master/flixel/system/debug/stats/StatsGraph.hx
*/
class HitGraph extends Sprite
{
static inline var AXIS_COLOR:FlxColor = 0xffffff;
static inline var AXIS_ALPHA:Float = 0.5;
inline static var HISTORY_MAX:Int = 30;
public var minLabel:TextField;
public var curLabel:TextField;
public var maxLabel:TextField;
public var avgLabel:TextField;
public var minValue:Float = -(Math.floor((PlayState.rep.replay.sf / 60) * 1000) + 95);
public var maxValue:Float = Math.floor((PlayState.rep.replay.sf / 60) * 1000) + 95;
public var showInput:Bool = FlxG.save.data.inputShow;
public var graphColor:FlxColor;
public var history:Array<Dynamic> = [];
public var bitmap:Bitmap;
var _axis:Shape;
var _width:Int;
var _height:Int;
var _unit:String;
var _labelWidth:Int;
var _label:String;
public function new(X:Int, Y:Int, Width:Int, Height:Int)
{
super();
x = X;
y = Y;
_width = Width;
_height = Height;
var bm = new BitmapData(Width,Height);
bm.draw(this);
bitmap = new Bitmap(bm);
_axis = new Shape();
_axis.x = _labelWidth + 10;
var ts = Math.floor((PlayState.rep.replay.sf / 60) * 1000) / 166;
var early = createTextField(10,10,FlxColor.WHITE,12);
var late = createTextField(10,_height - 20,FlxColor.WHITE,12);
early.text = "Early (" + -166 * ts + "ms)";
late.text = "Late (" + 166 * ts + "ms)";
addChild(early);
addChild(late);
addChild(_axis);
drawAxes();
}
/**
* Redraws the axes of the graph.
*/
function drawAxes():Void
{
var gfx = _axis.graphics;
gfx.clear();
gfx.lineStyle(1, AXIS_COLOR, AXIS_ALPHA);
// y-Axis
gfx.moveTo(0, 0);
gfx.lineTo(0, _height);
// x-Axis
gfx.moveTo(0, _height);
gfx.lineTo(_width, _height);
gfx.moveTo(0, _height / 2);
gfx.lineTo(_width, _height / 2);
}
public static function createTextField(X:Float = 0, Y:Float = 0, Color:FlxColor = FlxColor.WHITE, Size:Int = 12):TextField
{
return initTextField(new TextField(), X, Y, Color, Size);
}
public static function initTextField<T:TextField>(tf:T, X:Float = 0, Y:Float = 0, Color:FlxColor = FlxColor.WHITE, Size:Int = 12):T
{
tf.x = X;
tf.y = Y;
tf.multiline = false;
tf.wordWrap = false;
tf.embedFonts = true;
tf.selectable = false;
#if flash
tf.antiAliasType = AntiAliasType.NORMAL;
tf.gridFitType = GridFitType.PIXEL;
#end
tf.defaultTextFormat = new TextFormat("assets/fonts/vcr.ttf", Size, Color.to24Bit());
tf.alpha = Color.alphaFloat;
tf.autoSize = TextFieldAutoSize.LEFT;
return tf;
}
function drawJudgementLine(ms:Float):Void
{
var gfx:Graphics = graphics;
gfx.lineStyle(1, graphColor, 0.3);
var ts = Math.floor((PlayState.rep.replay.sf / 60) * 1000) / 166;
var range:Float = Math.max(maxValue - minValue, maxValue * 0.1);
var value = ((ms * ts) - minValue) / range;
var pointY = _axis.y + ((-value * _height - 1) + _height);
var graphX = _axis.x + 1;
if (ms == 45)
gfx.moveTo(graphX, _axis.y + pointY);
var graphX = _axis.x + 1;
gfx.drawRect(graphX,pointY, _width,1);
gfx.lineStyle(1, graphColor, 1);
}
/**
* Redraws the graph based on the values stored in the history.
*/
function drawGraph():Void
{
var gfx:Graphics = graphics;
gfx.clear();
gfx.lineStyle(1, graphColor, 1);
gfx.beginFill(0x00FF00);
drawJudgementLine(45);
gfx.endFill();
gfx.beginFill(0xFF0000);
drawJudgementLine(90);
gfx.endFill();
gfx.beginFill(0x8b0000);
drawJudgementLine(135);
gfx.endFill();
gfx.beginFill(0x580000);
drawJudgementLine(166);
gfx.endFill();
gfx.beginFill(0x00FF00);
drawJudgementLine(-45);
gfx.endFill();
gfx.beginFill(0xFF0000);
drawJudgementLine(-90);
gfx.endFill();
gfx.beginFill(0x8b0000);
drawJudgementLine(-135);
gfx.endFill();
gfx.beginFill(0x580000);
drawJudgementLine(-166);
gfx.endFill();
var range:Float = Math.max(maxValue - minValue, maxValue * 0.1);
var graphX = _axis.x + 1;
if (showInput)
{
for (i in 0...PlayState.rep.replay.ana.anaArray.length)
{
var ana = PlayState.rep.replay.ana.anaArray[i];
var value = (ana.key * 25 - minValue) / range;
if (ana.hit)
gfx.beginFill(0xFFFF00);
else
gfx.beginFill(0xC2B280);
if (ana.hitTime < 0)
continue;
var pointY = (-value * _height - 1) + _height;
gfx.drawRect(graphX + fitX(ana.hitTime), pointY,2,2);
gfx.endFill();
}
}
for (i in 0...history.length)
{
var value = (history[i][0] - minValue) / range;
var judge = history[i][1];
switch(judge)
{
case "sick":
gfx.beginFill(0x00FFFF);
case "good":
gfx.beginFill(0x00FF00);
case "bad":
gfx.beginFill(0xFF0000);
case "shit":
gfx.beginFill(0x8b0000);
case "miss":
gfx.beginFill(0x580000);
default:
gfx.beginFill(0xFFFFFF);
}
var pointY = (-value * _height - 1) + _height;
/*if (i == 0)
gfx.moveTo(graphX, _axis.y + pointY);*/
gfx.drawRect(graphX + fitX(history[i][2]), pointY,4,4);
gfx.endFill();
}
var bm = new BitmapData(_width,_height);
bm.draw(this);
bitmap = new Bitmap(bm);
}
public function fitX(x:Float)
{
return (x / FlxG.sound.music.length) * width;
}
public function addToHistory(diff:Float, judge:String, time:Float)
{
history.push([diff,judge, time]);
}
public function update():Void
{
drawGraph();
}
public function average():Float
{
var sum:Float = 0;
for (value in history)
sum += value;
return sum / history.length;
}
public function destroy():Void
{
_axis = FlxDestroyUtil.removeChild(this, _axis);
history = null;
}
}

View File

@ -81,6 +81,15 @@ class KadeEngineData
if (FlxG.save.data.customStrumLine == null)
FlxG.save.data.customStrumLine = 0;
if (FlxG.save.data.camzoom == null)
FlxG.save.data.camzoom = true;
if (FlxG.save.data.scoreScreen == null)
FlxG.save.data.scoreScreen = true;
if (FlxG.save.data.inputShow == null)
FlxG.save.data.inputShow = false;
Conductor.recalculateTimings();
PlayerSettings.player1.controls.loadKeyBinds();
KeyBinds.keyCheck();

View File

@ -54,7 +54,7 @@ class LoadReplayState extends MusicBeatState
var string:String = controlsStrings[i];
actualNames[i] = string;
var rep:Replay = Replay.LoadReplay(string);
controlsStrings[i] = string.split("time")[0] + " " + (rep.replay.songDiff == 2 ? "HARD" : rep.replay.songDiff == 1 ? "EASY" : "NORMAL");
controlsStrings[i] = string.split("time")[0] + " " + CoolUtil.difficultyFromInt(rep.replay.songDiff).toUpperCase();
}
if (controlsStrings.length == 0)
@ -80,7 +80,7 @@ class LoadReplayState extends MusicBeatState
}
versionShit = new FlxText(5, FlxG.height - 34, 0, "Replay Loader (ESCAPE TO GO BACK)\nNOTICE!!!! Replays are in a beta stage, and they are probably not 100% correct. expect misses and other stuff that isn't there!", 12);
versionShit = new FlxText(5, FlxG.height - 34, 0, "Replay Loader (ESCAPE TO GO BACK)\nNOTICE!!!! Replays are in a beta stage, and they are probably not 100% correct. expect misses and other stuff that isn't there!\n", 12);
versionShit.scrollFactor.set();
versionShit.setFormat("VCR OSD Mono", 16, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK);
add(versionShit);
@ -102,7 +102,7 @@ class LoadReplayState extends MusicBeatState
for (i in 0...songs.length)
{
var pog:FreeplayState.SongMetadata = songs[i];
if (pog.songName.toLowerCase() == songName)
if (pog.songName == songName)
week = pog.week;
}
return week;
@ -148,13 +148,32 @@ class LoadReplayState extends MusicBeatState
PlayState.loadRep = true;
var poop:String = Highscore.formatSong(PlayState.rep.replay.songName.toLowerCase(), PlayState.rep.replay.songDiff);
if (PlayState.rep.replay.replayGameVer == Replay.version)
{
PlayState.SONG = Song.loadFromJson(poop, PlayState.rep.replay.songName.toLowerCase());
PlayState.isStoryMode = false;
PlayState.storyDifficulty = PlayState.rep.replay.songDiff;
PlayState.storyWeek = getWeekNumbFromSong(PlayState.rep.replay.songName);
LoadingState.loadAndSwitchState(new PlayState());
// adjusting the song name to be compatible
var songFormat = StringTools.replace(PlayState.rep.replay.songName, " ", "-");
switch (songFormat) {
case 'Dad-Battle': songFormat = 'Dadbattle';
case 'Philly-Nice': songFormat = 'Philly';
// Replay v1.0 support
case 'dad-battle': songFormat = 'Dadbattle';
case 'philly-nice': songFormat = 'Philly';
}
var poop:String = Highscore.formatSong(songFormat, PlayState.rep.replay.songDiff);
PlayState.SONG = Song.loadFromJson(poop, PlayState.rep.replay.songName);
PlayState.isStoryMode = false;
PlayState.storyDifficulty = PlayState.rep.replay.songDiff;
PlayState.storyWeek = getWeekNumbFromSong(PlayState.rep.replay.songName);
LoadingState.loadAndSwitchState(new PlayState());
}
else
{
PlayState.rep = null;
PlayState.loadRep = false;
}
}
}
@ -177,7 +196,7 @@ class LoadReplayState extends MusicBeatState
var rep:Replay = Replay.LoadReplay(actualNames[curSelected]);
poggerDetails.text = "Replay Details - \nDate Created: " + rep.replay.timestamp + "\nSong: " + rep.replay.songName + "\nReplay Version: " + (rep.replay.replayGameVer != Replay.version ? "OUTDATED" : "Latest");
poggerDetails.text = "Replay Details - \nDate Created: " + rep.replay.timestamp + "\nSong: " + rep.replay.songName + "\nReplay Version: " + rep.replay.replayGameVer + ' (' + (rep.replay.replayGameVer != Replay.version ? "OUTDATED not useable!" : "Latest") + ')\n';
// selector.y = (70 * curSelected) + 30;

View File

@ -1,5 +1,7 @@
package;
import webm.WebmPlayer;
import openfl.display.BlendMode;
import openfl.text.TextFormat;
import openfl.display.Application;
@ -49,6 +51,8 @@ class Main extends Sprite
}
}
public static var webmHandler:WebmHandler;
private function init(?E:Event):Void
{
if (hasEventListener(Event.ADDED_TO_STAGE))
@ -73,14 +77,12 @@ class Main extends Sprite
gameHeight = Math.ceil(stageHeight / zoom);
}
#if !debug
initialState = TitleState;
#end
initialState = Caching;
game = new FlxGame(gameWidth, gameHeight, initialState, zoom, framerate, framerate, skipSplash, startFullscreen);
addChild(game);
#if !mobile
fpsCounter = new FPS(10, 3, 0xFFFFFF);
addChild(fpsCounter);

View File

@ -39,7 +39,7 @@ class MainMenuState extends MusicBeatState
public static var nightly:String = "";
public static var kadeEngineVer:String = "1.5.1" + nightly;
public static var kadeEngineVer:String = "1.5.3" + nightly;
public static var gameVer:String = "0.2.7.1";
var magenta:FlxSprite;
@ -165,7 +165,7 @@ class MainMenuState extends MusicBeatState
{
if (optionShit[curSelected] == 'donate')
{
fancyOpenURL("https://www.kickstarter.com/projects/funkin/friday-night-funkin-the-full-ass-game");
fancyOpenURL("https://ninja-muffin24.itch.io/funkin");
}
else
{

View File

@ -1,6 +1,7 @@
// this file is for modchart things, this is to declutter playstate.hx
// Lua
import openfl.display3D.textures.VideoTexture;
import flixel.graphics.FlxGraphic;
import flixel.graphics.frames.FlxAtlasFrames;
#if windows
@ -255,11 +256,18 @@ class ModchartState
function makeAnimatedLuaSprite(spritePath:String,names:Array<String>,prefixes:Array<String>,startAnim:String, id:String)
{
#if sys
var data:BitmapData = BitmapData.fromFile(Sys.getCwd() + "assets/data/" + PlayState.SONG.song.toLowerCase() + '/' + spritePath + ".png");
// pre lowercasing the song name (makeAnimatedLuaSprite)
var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase();
switch (songLowercase) {
case 'dad-battle': songLowercase = 'dadbattle';
case 'philly-nice': songLowercase = 'philly';
}
var data:BitmapData = BitmapData.fromFile(Sys.getCwd() + "assets/data/" + songLowercase + '/' + spritePath + ".png");
var sprite:FlxSprite = new FlxSprite(0,0);
sprite.frames = FlxAtlasFrames.fromSparrow(FlxGraphic.fromBitmapData(data), Sys.getCwd() + "assets/data/" + PlayState.SONG.song.toLowerCase() + "/" + spritePath + ".xml");
sprite.frames = FlxAtlasFrames.fromSparrow(FlxGraphic.fromBitmapData(data), Sys.getCwd() + "assets/data/" + songLowercase + "/" + spritePath + ".xml");
trace(sprite.frames.frames.length);
@ -282,7 +290,14 @@ class ModchartState
function makeLuaSprite(spritePath:String,toBeCalled:String, drawBehind:Bool)
{
#if sys
var data:BitmapData = BitmapData.fromFile(Sys.getCwd() + "assets/data/" + PlayState.SONG.song.toLowerCase() + '/' + spritePath + ".png");
// pre lowercasing the song name (makeLuaSprite)
var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase();
switch (songLowercase) {
case 'dad-battle': songLowercase = 'dadbattle';
case 'philly-nice': songLowercase = 'philly';
}
var data:BitmapData = BitmapData.fromFile(Sys.getCwd() + "assets/data/" + songLowercase + '/' + spritePath + ".png");
var sprite:FlxSprite = new FlxSprite(0,0);
var imgWidth:Float = FlxG.width / data.width;
@ -345,7 +360,14 @@ class ModchartState
//shaders = new Array<LuaShader>();
var result = LuaL.dofile(lua, Paths.lua(PlayState.SONG.song.toLowerCase() + "/modchart")); // execute le file
// pre lowercasing the song name (new)
var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase();
switch (songLowercase) {
case 'dad-battle': songLowercase = 'dadbattle';
case 'philly-nice': songLowercase = 'philly';
}
var result = LuaL.dofile(lua, Paths.lua(songLowercase + "/modchart")); // execute le file
if (result != 0)
{
@ -361,6 +383,8 @@ class ModchartState
setVar("scrollspeed", FlxG.save.data.scrollSpeed != 1 ? FlxG.save.data.scrollSpeed : PlayState.SONG.speed);
setVar("fpsCap", FlxG.save.data.fpsCap);
setVar("downscroll", FlxG.save.data.downscroll);
setVar("flashing", FlxG.save.data.flashing);
setVar("distractions", FlxG.save.data.distractions);
setVar("curStep", 0);
setVar("curBeat", 0);
@ -413,10 +437,43 @@ class ModchartState
PlayState.instance.removeObject(sprite);
return true;
});
// hud/camera
Lua_helper.add_callback(lua,"initBackgroundVideo", function(videoName:String) {
trace('playing assets/videos/' + videoName + '.webm');
PlayState.instance.backgroundVideo("assets/videos/" + videoName + ".webm");
});
Lua_helper.add_callback(lua,"pauseVideo", function() {
if (!GlobalVideo.get().paused)
GlobalVideo.get().pause();
});
Lua_helper.add_callback(lua,"resumeVideo", function() {
if (GlobalVideo.get().paused)
GlobalVideo.get().pause();
});
Lua_helper.add_callback(lua,"restartVideo", function() {
GlobalVideo.get().restart();
});
Lua_helper.add_callback(lua,"getVideoSpriteX", function() {
return PlayState.instance.videoSprite.x;
});
Lua_helper.add_callback(lua,"getVideoSpriteY", function() {
return PlayState.instance.videoSprite.y;
});
Lua_helper.add_callback(lua,"setVideoSpritePos", function(x:Int,y:Int) {
PlayState.instance.videoSprite.setPosition(x,y);
});
Lua_helper.add_callback(lua,"setVideoSpriteScale", function(scale:Float) {
PlayState.instance.videoSprite.setGraphicSize(Std.int(PlayState.instance.videoSprite.width * scale));
});
Lua_helper.add_callback(lua,"setHudAngle", function (x:Float) {
PlayState.instance.camHUD.angle = x;
@ -564,6 +621,18 @@ class ModchartState
getActorByName(id).x = x;
});
Lua_helper.add_callback(lua,"setActorAccelerationX", function(x:Int,id:String) {
getActorByName(id).acceleration.x = x;
});
Lua_helper.add_callback(lua,"setActorDragX", function(x:Int,id:String) {
getActorByName(id).drag.x = x;
});
Lua_helper.add_callback(lua,"setActorVelocityX", function(x:Int,id:String) {
getActorByName(id).velocity.x = x;
});
Lua_helper.add_callback(lua,"playActorAnimation", function(id:String,anim:String,force:Bool = false,reverse:Bool = false) {
getActorByName(id).playAnim(anim, force, reverse);
});
@ -575,7 +644,19 @@ class ModchartState
Lua_helper.add_callback(lua,"setActorY", function(y:Int,id:String) {
getActorByName(id).y = y;
});
Lua_helper.add_callback(lua,"setActorAccelerationY", function(y:Int,id:String) {
getActorByName(id).acceleration.y = y;
});
Lua_helper.add_callback(lua,"setActorDragY", function(y:Int,id:String) {
getActorByName(id).drag.y = y;
});
Lua_helper.add_callback(lua,"setActorVelocityY", function(y:Int,id:String) {
getActorByName(id).velocity.y = y;
});
Lua_helper.add_callback(lua,"setActorAngle", function(angle:Int,id:String) {
getActorByName(id).angle = angle;
});

View File

@ -37,7 +37,7 @@ class Note extends FlxSprite
public var rating:String = "shit";
public function new(strumTime:Float, noteData:Int, ?prevNote:Note, ?sustainNote:Bool = false)
public function new(strumTime:Float, noteData:Int, ?prevNote:Note, ?sustainNote:Bool = false, ?inCharter:Bool = false)
{
super();
@ -50,7 +50,10 @@ class Note extends FlxSprite
x += 50;
// MAKE SURE ITS DEFINITELY OFF SCREEN?
y -= 2000;
this.strumTime = strumTime;
if (inCharter)
this.strumTime = strumTime;
else
this.strumTime = Math.round(strumTime);
if (this.strumTime < 0 )
this.strumTime = 0;
@ -59,7 +62,14 @@ class Note extends FlxSprite
var daStage:String = PlayState.curStage;
switch (PlayState.SONG.noteStyle)
//defaults if no noteStyle was found in chart
var noteTypeCheck:String = 'normal';
if (PlayState.SONG.noteStyle == null) {
switch(PlayState.storyWeek) {case 6: noteTypeCheck = 'pixel';}
} else {noteTypeCheck = PlayState.SONG.noteStyle;}
switch (noteTypeCheck)
{
case 'pixel':
loadGraphic(Paths.image('weeb/pixelUI/arrows-pixels','week6'), true, 17, 17);

39
source/OFLSprite.hx Normal file
View File

@ -0,0 +1,39 @@
import flixel.util.FlxColor;
import openfl.display.Sprite;
import flixel.FlxSprite;
/**
* designed to draw a Open FL Sprite as a FlxSprite (to allow layering and auto sizing for haxe flixel cameras)
* Custom made for Kade Engine
*/
class OFLSprite extends FlxSprite
{
public var flSprite:Sprite;
public function new(x,y,width,height,Sprite:Sprite)
{
super(x,y);
makeGraphic(width,height,FlxColor.TRANSPARENT);
flSprite = Sprite;
pixels.draw(flSprite);
}
private var _frameCount:Int = 0;
override function update(elapsed:Float)
{
if (_frameCount != 2)
{
pixels.draw(flSprite);
_frameCount++;
}
}
public function updateDisplay()
{
pixels.draw(flSprite);
}
}

View File

@ -261,6 +261,27 @@ class FlashingLightsOption extends Option
}
}
class ShowInput extends Option
{
public function new(desc:String)
{
super();
description = desc;
}
public override function press():Bool
{
FlxG.save.data.inputShow = !FlxG.save.data.inputShow;
display = updateDisplay();
return true;
}
private override function updateDisplay():String
{
return (FlxG.save.data.inputShow ? "Extended Score Info" : "Minimalized Info");
}
}
class Judgement extends Option
{
@ -296,8 +317,8 @@ class Judgement extends Option
override function getValue():String {
return "Safe Frames: " + Conductor.safeFrames +
" - SIK: " + HelperFunctions.truncateFloat(45 * Conductor.timeScale, 0) +
"ms GD: " + HelperFunctions.truncateFloat(90 * Conductor.timeScale, 0) +
" - SIK: " + HelperFunctions.truncateFloat(22 * Conductor.timeScale, 0) +
"ms GD: " + HelperFunctions.truncateFloat(45 * Conductor.timeScale, 0) +
"ms BD: " + HelperFunctions.truncateFloat(135 * Conductor.timeScale, 0) +
"ms SHT: " + HelperFunctions.truncateFloat(155 * Conductor.timeScale, 0) +
"ms TOTAL: " + HelperFunctions.truncateFloat(Conductor.safeZoneOffset,0) + "ms";
@ -338,6 +359,27 @@ class FPSOption extends Option
}
}
class ScoreScreen extends Option
{
public function new(desc:String)
{
super();
description = desc;
}
public override function press():Bool
{
FlxG.save.data.scoreScreen = !FlxG.save.data.scoreScreen;
return true;
}
private override function updateDisplay():String
{
return (FlxG.save.data.scoreScreen ? "Show Score Screen" : "No Score Screen");
}
}
class FPSCapOption extends Option
@ -614,3 +656,23 @@ class BotPlay extends Option
private override function updateDisplay():String
return "BotPlay " + (FlxG.save.data.botplay ? "on" : "off");
}
class CamZoomOption extends Option
{
public function new(desc:String)
{
super();
description = desc;
}
public override function press():Bool
{
FlxG.save.data.camzoom = !FlxG.save.data.camzoom;
display = updateDisplay();
return true;
}
private override function updateDisplay():String
{
return "Camera Zoom " + (!FlxG.save.data.camzoom ? "off" : "on");
}
}

View File

@ -39,15 +39,14 @@ class OptionsMenu extends MusicBeatState
new CustomizeGameplay("Drag'n'Drop Gameplay Modules around to your preference")
]),
new OptionCategory("Appearance", [
#if desktop
new DistractionsAndEffectsOption("Toggle stage distractions that can hinder your gameplay."),
new CamZoomOption("Toggle the camera zoom in-game."),
#if desktop
new RainbowFPSOption("Make the FPS Counter Rainbow"),
new AccuracyOption("Display accuracy information."),
new NPSDisplayOption("Shows your current Notes Per Second."),
new SongPositionOption("Show the songs current position (as a bar)"),
new CpuStrums("CPU's strumline lights up when a note hits it."),
#else
new DistractionsAndEffectsOption("Toggle stage distractions that can hinder your gameplay.")
#end
]),
@ -58,7 +57,9 @@ class OptionsMenu extends MusicBeatState
#end
new FlashingLightsOption("Toggle flashing lights that can cause epileptic seizures and strain."),
new WatermarkOption("Enable and disable all watermarks from the engine."),
new BotPlay("Showcase your charts and mods with autoplay.")
new BotPlay("Showcase your charts and mods with autoplay."),
new ScoreScreen("Show the score screen after the end of a song"),
new ShowInput("Display every single input in the score screen.")
])
];
@ -130,14 +131,17 @@ class OptionsMenu extends MusicBeatState
isCat = false;
grpControls.clear();
for (i in 0...options.length)
{
var controlLabel:Alphabet = new Alphabet(0, (70 * i) + 30, options[i].getName(), true, false);
controlLabel.isMenuItem = true;
controlLabel.targetY = i;
grpControls.add(controlLabel);
// DONT PUT X IN THE FIRST PARAMETER OF new ALPHABET() !!
}
{
var controlLabel:Alphabet = new Alphabet(0, (70 * i) + 30, options[i].getName(), true, false);
controlLabel.isMenuItem = true;
controlLabel.targetY = i;
grpControls.add(controlLabel);
// DONT PUT X IN THE FIRST PARAMETER OF new ALPHABET() !!
}
curSelected = 0;
changeSelection(curSelected);
}
if (controls.UP_P)
changeSelection(-1);
@ -146,7 +150,6 @@ class OptionsMenu extends MusicBeatState
if (isCat)
{
if (currentSelectedCat.getOptions()[curSelected].getAccept())
{
if (FlxG.keys.pressed.SHIFT)
@ -166,7 +169,6 @@ class OptionsMenu extends MusicBeatState
}
else
{
if (FlxG.keys.pressed.SHIFT)
{
if (FlxG.keys.justPressed.RIGHT)
@ -179,7 +181,7 @@ class OptionsMenu extends MusicBeatState
else if (FlxG.keys.pressed.LEFT)
FlxG.save.data.offset -= 0.1;
versionShit.text = "Offset (Left, Right, Shift for slow): " + HelperFunctions.truncateFloat(FlxG.save.data.offset,2) + " - Description - " + currentDescription;
}
if (currentSelectedCat.getOptions()[curSelected].getAccept())
versionShit.text = currentSelectedCat.getOptions()[curSelected].getValue() + " - Description - " + currentDescription;
@ -189,16 +191,18 @@ class OptionsMenu extends MusicBeatState
else
{
if (FlxG.keys.pressed.SHIFT)
{
if (FlxG.keys.justPressed.RIGHT)
FlxG.save.data.offset += 0.1;
else if (FlxG.keys.justPressed.LEFT)
FlxG.save.data.offset -= 0.1;
}
else if (FlxG.keys.pressed.RIGHT)
{
if (FlxG.keys.justPressed.RIGHT)
FlxG.save.data.offset += 0.1;
else if (FlxG.keys.pressed.LEFT)
else if (FlxG.keys.justPressed.LEFT)
FlxG.save.data.offset -= 0.1;
}
else if (FlxG.keys.pressed.RIGHT)
FlxG.save.data.offset += 0.1;
else if (FlxG.keys.pressed.LEFT)
FlxG.save.data.offset -= 0.1;
versionShit.text = "Offset (Left, Right, Shift for slow): " + HelperFunctions.truncateFloat(FlxG.save.data.offset,2) + " - Description - " + currentDescription;
}
@ -231,6 +235,8 @@ class OptionsMenu extends MusicBeatState
}
curSelected = 0;
}
changeSelection(curSelected);
}
}
FlxG.save.flush();

View File

@ -97,14 +97,22 @@ class Paths
inline static public function voices(song:String)
{
song = StringTools.replace(song," ", "-");
return 'songs:assets/songs/${song.toLowerCase()}/Voices.$SOUND_EXT';
var songLowercase = StringTools.replace(song, " ", "-").toLowerCase();
switch (songLowercase) {
case 'dad-battle': songLowercase = 'dadbattle';
case 'philly-nice': songLowercase = 'philly';
}
return 'songs:assets/songs/${songLowercase}/Voices.$SOUND_EXT';
}
inline static public function inst(song:String)
{
song = StringTools.replace(song," ", "-");
return 'songs:assets/songs/${song.toLowerCase()}/Inst.$SOUND_EXT';
var songLowercase = StringTools.replace(song, " ", "-").toLowerCase();
switch (songLowercase) {
case 'dad-battle': songLowercase = 'dadbattle';
case 'philly-nice': songLowercase = 'philly';
}
return 'songs:assets/songs/${songLowercase}/Inst.$SOUND_EXT';
}
inline static public function image(key:String, ?library:String)

View File

@ -33,6 +33,13 @@ class PauseSubState extends MusicBeatSubstate
{
super();
if (PlayState.instance.useVideo)
{
menuItems.remove("Resume");
if (GlobalVideo.get().playing)
GlobalVideo.get().pause();
}
pauseMusic = new FlxSound().loadEmbedded(Paths.music('breakfast'), true, true);
pauseMusic.volume = 0;
pauseMusic.play(false, FlxG.random.int(0, Std.int(pauseMusic.length / 2)));
@ -52,7 +59,7 @@ class PauseSubState extends MusicBeatSubstate
add(levelInfo);
var levelDifficulty:FlxText = new FlxText(20, 15 + 32, 0, "", 32);
levelDifficulty.text += CoolUtil.difficultyString();
levelDifficulty.text += CoolUtil.difficultyFromInt(PlayState.storyDifficulty).toUpperCase();
levelDifficulty.scrollFactor.set();
levelDifficulty.setFormat(Paths.font('vcr.ttf'), 32);
levelDifficulty.updateHitbox();
@ -98,13 +105,23 @@ class PauseSubState extends MusicBeatSubstate
super.update(elapsed);
if (PlayState.instance.useVideo)
menuItems.remove('Resume');
var upP = controls.UP_P;
var downP = controls.DOWN_P;
var leftP = controls.LEFT_P;
var rightP = controls.RIGHT_P;
var accepted = controls.ACCEPT;
var oldOffset:Float = 0;
var songPath = 'assets/data/' + PlayState.SONG.song.toLowerCase() + '/';
// pre lowercasing the song name (update)
var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase();
switch (songLowercase) {
case 'dad-battle': songLowercase = 'dadbattle';
case 'philly-nice': songLowercase = 'philly';
}
var songPath = 'assets/data/' + songLowercase + '/';
if (upP)
{
@ -180,8 +197,20 @@ class PauseSubState extends MusicBeatSubstate
case "Resume":
close();
case "Restart Song":
if (PlayState.instance.useVideo)
{
GlobalVideo.get().stop();
PlayState.instance.remove(PlayState.instance.videoSprite);
PlayState.instance.removedVideo = true;
}
FlxG.resetState();
case "Exit to menu":
if (PlayState.instance.useVideo)
{
GlobalVideo.get().stop();
PlayState.instance.remove(PlayState.instance.videoSprite);
PlayState.instance.removedVideo = true;
}
if(PlayState.loadRep)
{
FlxG.save.data.botplay = false;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
class PlayStateChangeables
{
public static var useDownscroll:Bool;
public static var safeFrames:Int;
public static var scrollSpeed:Float;
public static var botPlay:Bool;
}

View File

@ -5,7 +5,7 @@ class Ratings
public static function GenerateLetterRank(accuracy:Float) // generate a letter ranking
{
var ranking:String = "N/A";
if(FlxG.save.data.botplay)
if(FlxG.save.data.botplay && !PlayState.loadRep)
ranking = "BotPlay";
if (PlayState.misses == 0 && PlayState.bads == 0 && PlayState.shits == 0 && PlayState.goods == 0) // Marvelous (SICK) Full Combo
@ -86,7 +86,7 @@ class Ratings
if (accuracy == 0)
ranking = "N/A";
else if(FlxG.save.data.botplay)
else if(FlxG.save.data.botplay && !PlayState.loadRep)
ranking = "BotPlay";
return ranking;
@ -107,35 +107,45 @@ class Ratings
// trace('Hit Info\nDifference: ' + noteDiff + '\nZone: ' + Conductor.safeZoneOffset * 1.5 + "\nTS: " + customTimeScale + "\nLate: " + 155 * customTimeScale);
if (FlxG.save.data.botplay)
return "good"; // FUNNY
if (noteDiff > 166 * customTimeScale) // so god damn early its a miss
return "miss";
if (noteDiff > 135 * customTimeScale) // way early
return "shit";
else if (noteDiff > 90 * customTimeScale) // early
return "bad";
else if (noteDiff > 45 * customTimeScale) // your kinda there
return "good";
else if (noteDiff < -45 * customTimeScale) // little late
return "good";
else if (noteDiff < -90 * customTimeScale) // late
return "bad";
else if (noteDiff < -135 * customTimeScale) // late as fuck
return "shit";
else if (noteDiff < -166 * customTimeScale) // so god damn late its a miss
return "miss";
return "sick";
if (FlxG.save.data.botplay && !PlayState.loadRep)
return "sick"; // FUNNY
var rating = checkRating(noteDiff,customTimeScale);
return rating;
}
public static function checkRating(ms:Float, ts:Float)
{
var rating = "sick";
if (ms <= 166 * ts && ms >= 135 * ts)
rating = "shit";
if (ms < 135 * ts && ms >= 90 * ts)
rating = "bad";
if (ms < 90 * ts && ms >= 45 * ts)
rating = "good";
if (ms < 45 * ts && ms >= -45 * ts)
rating = "sick";
if (ms > -90 * ts && ms <= -45 * ts)
rating = "good";
if (ms > -135 * ts && ms <= -90 * ts)
rating = "bad";
if (ms > -166 * ts && ms <= -135 * ts)
rating = "shit";
return rating;
}
public static function CalculateRanking(score:Int,scoreDef:Int,nps:Int,maxNPS:Int,accuracy:Float):String
{
return
(FlxG.save.data.npsDisplay ? "NPS: " + nps + " (Max " + maxNPS + ")" + (!FlxG.save.data.botplay ? " | " : "") : "") + (!FlxG.save.data.botplay ? // NPS Toggle
"Score:" + (Conductor.safeFrames != 10 ? score + " (" + scoreDef + ")" : "" + score) + // Score
" | Combo Breaks:" + PlayState.misses + // Misses/Combo Breaks
" | Accuracy:" + (FlxG.save.data.botplay ? "N/A" : HelperFunctions.truncateFloat(accuracy, 2) + " %") + // Accuracy
" | " + GenerateLetterRank(accuracy) : ""); // Letter Rank
return
(FlxG.save.data.npsDisplay ? // NPS Toggle
"NPS: " + nps + " (Max " + maxNPS + ")" + (!PlayStateChangeables.botPlay || PlayState.loadRep ? " | " : "") : "") + // NPS
(!PlayStateChangeables.botPlay || PlayState.loadRep ? "Score:" + (Conductor.safeFrames != 10 ? score + " (" + scoreDef + ")" : "" + score) + // Score
(FlxG.save.data.accuracyDisplay ? // Accuracy Toggle
" | Combo Breaks:" + PlayState.misses + // Misses/Combo Breaks
" | Accuracy:" + (PlayStateChangeables.botPlay && !PlayState.loadRep ? "N/A" : HelperFunctions.truncateFloat(accuracy, 2) + " %") + // Accuracy
" | " + GenerateLetterRank(accuracy) : "") : ""); // Letter Rank
}
}

View File

@ -11,81 +11,123 @@ import haxe.Json;
import flixel.input.keyboard.FlxKey;
import openfl.utils.Dictionary;
class Ana
{
public var hitTime:Float;
public var nearestNote:Array<Dynamic>;
public var hit:Bool;
public var hitJudge:String;
public var key:Int;
public function new(_hitTime:Float,_nearestNote:Array<Dynamic>,_hit:Bool,_hitJudge:String, _key:Int) {
hitTime = _hitTime;
nearestNote = _nearestNote;
hit = _hit;
hitJudge = _hitJudge;
key = _key;
}
}
class Analysis
{
public var anaArray:Array<Ana>;
public function new() {
anaArray = [];
}
}
typedef ReplayJSON =
{
public var replayGameVer:String;
public var timestamp:Date;
public var songName:String;
public var songDiff:Int;
public var songNotes:Array<Float>;
public var replayGameVer:String;
public var timestamp:Date;
public var songName:String;
public var songDiff:Int;
public var songNotes:Array<Dynamic>;
public var songJudgements:Array<String>;
public var noteSpeed:Float;
public var isDownscroll:Bool;
public var sf:Int;
public var ana:Analysis;
}
class Replay
{
public static var version:String = "1.0"; // replay file version
public static var version:String = "1.2"; // replay file version
public var path:String = "";
public var replay:ReplayJSON;
public function new(path:String)
{
this.path = path;
replay = {
songName: "Tutorial",
songDiff: 1,
public var path:String = "";
public var replay:ReplayJSON;
public function new(path:String)
{
this.path = path;
replay = {
songName: "No Song Found",
songDiff: 1,
noteSpeed: 1.5,
isDownscroll: false,
songNotes: [],
replayGameVer: version,
timestamp: Date.now()
};
}
replayGameVer: version,
timestamp: Date.now(),
sf: Conductor.safeFrames,
ana: new Analysis(),
songJudgements: []
};
}
public static function LoadReplay(path:String):Replay
public static function LoadReplay(path:String):Replay
{
var rep:Replay = new Replay(path);
var rep:Replay = new Replay(path);
rep.LoadFromJSON();
rep.LoadFromJSON();
trace('basic replay data:\nSong Name: ' + rep.replay.songName + '\nSong Diff: ' + rep.replay.songDiff + '\nNotes Length: ' + rep.replay.songNotes.length);
trace('basic replay data:\nSong Name: ' + rep.replay.songName + '\nSong Diff: ' + rep.replay.songDiff);
return rep;
}
return rep;
}
public function SaveReplay(notearray:Array<Float>)
{
var json = {
"songName": PlayState.SONG.song.toLowerCase(),
"songDiff": PlayState.storyDifficulty,
public function SaveReplay(notearray:Array<Dynamic>, judge:Array<String>, ana:Analysis)
{
var json = {
"songName": PlayState.SONG.song,
"songDiff": PlayState.storyDifficulty,
"noteSpeed": (FlxG.save.data.scrollSpeed > 1 ? FlxG.save.data.scrollSpeed : PlayState.SONG.speed),
"isDownscroll": FlxG.save.data.downscroll,
"songNotes": notearray,
"timestamp": Date.now(),
"replayGameVer": version
};
"songJudgements": judge,
"timestamp": Date.now(),
"replayGameVer": version,
"sf": Conductor.safeFrames,
"ana": ana
};
var data:String = Json.stringify(json);
var data:String = Json.stringify(json);
var time = Date.now().getTime();
#if sys
File.saveContent("assets/replays/replay-" + PlayState.SONG.song + "-time" + Date.now().getTime() + ".kadeReplay", data);
#end
}
#if sys
File.saveContent("assets/replays/replay-" + PlayState.SONG.song + "-time" + time + ".kadeReplay", data);
public function LoadFromJSON()
{
#if sys
trace('loading ' + Sys.getCwd() + 'assets/replays/' + path + ' replay...');
try
{
var repl:ReplayJSON = cast Json.parse(File.getContent(Sys.getCwd() + "assets/replays/" + path));
replay = repl;
}
catch(e)
{
trace('failed!\n' + e.message);
}
#end
}
path = "replay-" + PlayState.SONG.song + "-time" + time + ".kadeReplay"; // for score screen shit
LoadFromJSON();
replay.ana = ana;
#end
}
public function LoadFromJSON()
{
#if sys
trace('loading ' + Sys.getCwd() + 'assets/replays/' + path + ' replay...');
try
{
var repl:ReplayJSON = cast Json.parse(File.getContent(Sys.getCwd() + "assets/replays/" + path));
replay = repl;
}
catch(e)
{
trace('failed!\n' + e.message);
}
#end
}
}

252
source/ResultsScreen.hx Normal file
View File

@ -0,0 +1,252 @@
package;
import openfl.geom.Matrix;
import openfl.display.BitmapData;
import flixel.system.FlxSound;
import flixel.util.FlxAxes;
import flixel.FlxSubState;
import Options.Option;
import flixel.input.FlxInput;
import flixel.input.keyboard.FlxKey;
import flixel.FlxG;
import flixel.FlxObject;
import flixel.FlxSprite;
import flixel.effects.FlxFlicker;
import flixel.graphics.frames.FlxAtlasFrames;
import flixel.group.FlxGroup.FlxTypedGroup;
import flixel.text.FlxText;
import flixel.tweens.FlxEase;
import flixel.tweens.FlxTween;
import flixel.util.FlxColor;
import io.newgrounds.NG;
import lime.app.Application;
import lime.utils.Assets;
import flixel.math.FlxMath;
import flixel.text.FlxText;
import flixel.input.FlxKeyManager;
using StringTools;
class ResultsScreen extends FlxSubState
{
public var background:FlxSprite;
public var text:FlxText;
public var anotherBackground:FlxSprite;
public var graph:HitGraph;
public var graphSprite:OFLSprite;
public var comboText:FlxText;
public var contText:FlxText;
public var settingsText:FlxText;
public var music:FlxSound;
public var graphData:BitmapData;
public var ranking:String;
public var accuracy:String;
override function create()
{
background = new FlxSprite(0,0).makeGraphic(FlxG.width,FlxG.height,FlxColor.BLACK);
background.scrollFactor.set();
add(background);
music = new FlxSound().loadEmbedded(Paths.music('breakfast'), true, true);
music.volume = 0;
music.play(false, FlxG.random.int(0, Std.int(music.length / 2)));
background.alpha = 0;
text = new FlxText(20,-55,0,"Song Cleared!");
text.size = 34;
text.setBorderStyle(FlxTextBorderStyle.OUTLINE,FlxColor.BLACK,4,1);
text.color = FlxColor.WHITE;
text.scrollFactor.set();
add(text);
var score = PlayState.instance.songScore;
if (PlayState.isStoryMode)
{
score = PlayState.campaignScore;
text.text = "Week Cleared!";
}
comboText = new FlxText(20,-75,0,'Judgements:\nSicks - ${PlayState.sicks}\nGoods - ${PlayState.goods}\nBads - ${PlayState.bads}\n\nCombo Breaks: ${(PlayState.isStoryMode ? PlayState.campaignMisses : PlayState.misses)}\nHighest Combo: ${PlayState.highestCombo + 1}\n\nScore: ${PlayState.instance.songScore}\nAccuracy: ${HelperFunctions.truncateFloat(PlayState.instance.accuracy,2)}%\n\n${Ratings.GenerateLetterRank(PlayState.instance.accuracy)}\n\nF1 - View replay\nF2 - Replay song
');
comboText.size = 28;
comboText.setBorderStyle(FlxTextBorderStyle.OUTLINE,FlxColor.BLACK,4,1);
comboText.color = FlxColor.WHITE;
comboText.scrollFactor.set();
add(comboText);
contText = new FlxText(FlxG.width - 475,FlxG.height + 50,0,'Press ENTER to continue.');
contText.size = 28;
contText.setBorderStyle(FlxTextBorderStyle.OUTLINE,FlxColor.BLACK,4,1);
contText.color = FlxColor.WHITE;
contText.scrollFactor.set();
add(contText);
anotherBackground = new FlxSprite(FlxG.width - 500,45).makeGraphic(450,240,FlxColor.BLACK);
anotherBackground.scrollFactor.set();
anotherBackground.alpha = 0;
add(anotherBackground);
graph = new HitGraph(FlxG.width - 500,45,495,240);
graph.alpha = 0;
graphSprite = new OFLSprite(FlxG.width - 510,45,460,240,graph);
graphSprite.scrollFactor.set();
graphSprite.alpha = 0;
add(graphSprite);
var sicks = HelperFunctions.truncateFloat(PlayState.sicks / PlayState.goods,1);
var goods = HelperFunctions.truncateFloat(PlayState.goods / PlayState.bads,1);
if (sicks == Math.POSITIVE_INFINITY)
sicks = 0;
if (goods == Math.POSITIVE_INFINITY)
goods = 0;
var mean:Float = 0;
for (i in 0...PlayState.rep.replay.songNotes.length)
{
// 0 = time
// 1 = length
// 2 = type
// 3 = diff
var obj = PlayState.rep.replay.songNotes[i];
// judgement
var obj2 = PlayState.rep.replay.songJudgements[i];
var obj3 = obj[0];
var diff = obj[3];
var judge = obj2;
mean += diff;
if (obj[1] != -1)
graph.addToHistory(diff, judge, obj3);
}
graph.update();
mean = HelperFunctions.truncateFloat(mean / PlayState.rep.replay.songNotes.length,2);
settingsText = new FlxText(20,FlxG.height + 50,0,'SF: ${PlayState.rep.replay.sf} | Ratio (SA/GA): ${Math.round(sicks)}:1 ${Math.round(goods)}:1 | Mean: ${mean}ms | Played on ${PlayState.SONG.song} ${CoolUtil.difficultyFromInt(PlayState.storyDifficulty).toUpperCase()}');
settingsText.size = 16;
settingsText.setBorderStyle(FlxTextBorderStyle.OUTLINE,FlxColor.BLACK,2,1);
settingsText.color = FlxColor.WHITE;
settingsText.scrollFactor.set();
add(settingsText);
FlxTween.tween(background, {alpha: 0.5},0.5);
FlxTween.tween(text, {y:20},0.5,{ease: FlxEase.expoInOut});
FlxTween.tween(comboText, {y:145},0.5,{ease: FlxEase.expoInOut});
FlxTween.tween(contText, {y:FlxG.height - 45},0.5,{ease: FlxEase.expoInOut});
FlxTween.tween(settingsText, {y:FlxG.height - 35},0.5,{ease: FlxEase.expoInOut});
FlxTween.tween(anotherBackground, {alpha: 0.6},0.5, {onUpdate: function(tween:FlxTween) {
graph.alpha = FlxMath.lerp(0,1,tween.percent);
graphSprite.alpha = FlxMath.lerp(0,1,tween.percent);
}});
cameras = [FlxG.cameras.list[FlxG.cameras.list.length - 1]];
super.create();
}
var frames = 0;
override function update(elapsed:Float)
{
if (music.volume < 0.5)
music.volume += 0.01 * elapsed;
// keybinds
if (FlxG.keys.justPressed.ENTER)
{
music.fadeOut(0.3);
PlayState.loadRep = false;
PlayState.rep = null;
if (PlayState.isStoryMode)
{
FlxG.sound.playMusic(Paths.music('freakyMenu'));
FlxG.switchState(new MainMenuState());
}
else
FlxG.switchState(new FreeplayState());
}
if (FlxG.keys.justPressed.EIGHT)
{
graph.showInput = !graph.showInput;
graph.update();
}
if (FlxG.keys.justPressed.F1)
{
trace(PlayState.rep.path);
PlayState.rep = Replay.LoadReplay(PlayState.rep.path);
PlayState.loadRep = true;
var songFormat = StringTools.replace(PlayState.rep.replay.songName, " ", "-");
switch (songFormat) {
case 'Dad-Battle': songFormat = 'Dadbattle';
case 'Philly-Nice': songFormat = 'Philly';
// Replay v1.0 support
case 'dad-battle': songFormat = 'Dadbattle';
case 'philly-nice': songFormat = 'Philly';
}
var poop:String = Highscore.formatSong(songFormat, PlayState.rep.replay.songDiff);
music.fadeOut(0.3);
PlayState.SONG = Song.loadFromJson(poop, PlayState.rep.replay.songName);
PlayState.isStoryMode = false;
PlayState.storyDifficulty = PlayState.rep.replay.songDiff;
PlayState.storyWeek = 0;
LoadingState.loadAndSwitchState(new PlayState());
}
if (FlxG.keys.justPressed.F2 )
{
PlayState.rep = null;
PlayState.loadRep = false;
var songFormat = StringTools.replace(PlayState.SONG.song, " ", "-");
switch (songFormat) {
case 'Dad-Battle': songFormat = 'Dadbattle';
case 'Philly-Nice': songFormat = 'Philly';
case 'dad-battle': songFormat = 'Dadbattle';
case 'philly-nice': songFormat = 'Philly';
}
var poop:String = Highscore.formatSong(songFormat, PlayState.storyDifficulty);
music.fadeOut(0.3);
PlayState.SONG = Song.loadFromJson(poop, PlayState.SONG.song);
PlayState.isStoryMode = false;
PlayState.storyDifficulty = PlayState.storyDifficulty;
PlayState.storyWeek = 0;
LoadingState.loadAndSwitchState(new PlayState());
}
super.update(elapsed);
}
}

View File

@ -33,9 +33,9 @@ class Song
public var player1:String = 'bf';
public var player2:String = 'dad';
public var gfVersion:String = 'gf';
public var noteStyle:String = 'normal';
public var stage:String = 'stage';
public var gfVersion:String = '';
public var noteStyle:String = '';
public var stage:String = '';
public function new(song, notes, bpm)
{
@ -46,9 +46,18 @@ class Song
public static function loadFromJson(jsonInput:String, ?folder:String):SwagSong
{
trace('loading ' + folder.toLowerCase() + '/' + jsonInput.toLowerCase());
trace(jsonInput);
var rawJson = Assets.getText(Paths.json(folder.toLowerCase() + '/' + jsonInput.toLowerCase())).trim();
// pre lowercasing the folder name
var folderLowercase = StringTools.replace(folder, " ", "-").toLowerCase();
switch (folderLowercase) {
case 'dad-battle': folderLowercase = 'dadbattle';
case 'philly-nice': folderLowercase = 'philly';
}
trace('loading ' + folderLowercase + '/' + jsonInput.toLowerCase());
var rawJson = Assets.getText(Paths.json(folderLowercase + '/' + jsonInput.toLowerCase())).trim();
while (!rawJson.endsWith("}"))
{

View File

@ -285,19 +285,23 @@ class StoryMenuState extends MusicBeatState
PlayState.isStoryMode = true;
selectedWeek = true;
var diffic = "";
switch (curDifficulty)
{
case 0:
diffic = '-easy';
case 2:
diffic = '-hard';
}
PlayState.storyDifficulty = curDifficulty;
PlayState.SONG = Song.loadFromJson(StringTools.replace(PlayState.storyPlaylist[0]," ", "-").toLowerCase() + diffic, StringTools.replace(PlayState.storyPlaylist[0]," ", "-").toLowerCase());
// adjusting the song name to be compatible
var songFormat = StringTools.replace(PlayState.storyPlaylist[0], " ", "-");
switch (songFormat) {
case 'Dad-Battle': songFormat = 'Dadbattle';
case 'Philly-Nice': songFormat = 'Philly';
}
var poop:String = Highscore.formatSong(songFormat, curDifficulty);
PlayState.sicks = 0;
PlayState.bads = 0;
PlayState.shits = 0;
PlayState.goods = 0;
PlayState.campaignMisses = 0;
PlayState.SONG = Song.loadFromJson(poop, PlayState.storyPlaylist[0]);
PlayState.storyWeek = curWeek;
PlayState.campaignScore = 0;
new FlxTimer().start(1, function(tmr:FlxTimer)

View File

@ -163,14 +163,25 @@ class TitleState extends MusicBeatState
// bg.updateHitbox();
add(bg);
logoBl = new FlxSprite(-150, -100);
logoBl.frames = Paths.getSparrowAtlas('logoBumpin');
logoBl.antialiasing = true;
logoBl.animation.addByPrefix('bump', 'logo bumpin', 24);
logoBl.animation.play('bump');
logoBl.updateHitbox();
// logoBl.screenCenter();
// logoBl.color = FlxColor.BLACK;
if(Main.watermarks) {
logoBl = new FlxSprite(-150, -100);
logoBl.frames = Paths.getSparrowAtlas('KadeEngineLogoBumpin');
logoBl.antialiasing = true;
logoBl.animation.addByPrefix('bump', 'logo bumpin', 24);
logoBl.animation.play('bump');
logoBl.updateHitbox();
// logoBl.screenCenter();
// logoBl.color = FlxColor.BLACK;
} else {
logoBl = new FlxSprite(-150, -100);
logoBl.frames = Paths.getSparrowAtlas('logoBumpin');
logoBl.antialiasing = true;
logoBl.animation.addByPrefix('bump', 'logo bumpin', 24);
logoBl.animation.play('bump');
logoBl.updateHitbox();
// logoBl.screenCenter();
// logoBl.color = FlxColor.BLACK;
}
gfDance = new FlxSprite(FlxG.width * 0.4, FlxG.height * 0.07);
gfDance.frames = Paths.getSparrowAtlas('gfDanceTitle');

195
source/VideoHandler.hx Normal file
View File

@ -0,0 +1,195 @@
//This was made by GWebDev lol btw this uses actuate
package;
import motion.Actuate;
import openfl.display.Sprite;
import openfl.events.AsyncErrorEvent;
import openfl.events.MouseEvent;
import openfl.events.NetStatusEvent;
import openfl.media.Video;
import openfl.net.NetConnection;
import openfl.net.NetStream;
import flixel.FlxG;
using StringTools;
class VideoHandler
{
public var netStream:NetStream;
public var video:Video;
public var isReady:Bool = false;
public var addOverlay:Bool = false;
public var vidPath:String = "";
public var ignoreShit:Bool = false;
public function new()
{
isReady = false;
}
public function source(?vPath:String):Void
{
if (vPath != null && vPath.length > 0)
{
vidPath = vPath;
}
}
public function init1():Void
{
isReady = false;
video = new Video();
video.visible = false;
}
public function init2():Void
{
#if web
var netConnection = new NetConnection ();
netConnection.connect (null);
netStream = new NetStream (netConnection);
netStream.client = { onMetaData: client_onMetaData };
netStream.addEventListener (AsyncErrorEvent.ASYNC_ERROR, netStream_onAsyncError);
netConnection.addEventListener (NetStatusEvent.NET_STATUS, netConnection_onNetStatus);
netConnection.addEventListener (NetStatusEvent.NET_STATUS, onPlay);
netConnection.addEventListener (NetStatusEvent.NET_STATUS, onEnd);
#end
}
public function client_onMetaData (metaData:Dynamic) {
video.attachNetStream (netStream);
video.width = FlxG.width;
video.height = FlxG.height;
}
public function netStream_onAsyncError (event:AsyncErrorEvent):Void {
trace ("Error loading video");
}
public function netConnection_onNetStatus (event:NetStatusEvent):Void {
trace (event.info.code);
}
public function play():Void
{
#if web
ignoreShit = true;
netStream.close();
init2();
netStream.play(vidPath);
ignoreShit = false;
#end
trace(vidPath);
}
public function stop():Void
{
netStream.close();
onStop();
}
public function restart():Void
{
play();
onRestart();
}
public function update(elapsed:Float):Void
{
video.x = GlobalVideo.calc(0);
video.y = GlobalVideo.calc(1);
video.width = GlobalVideo.calc(2);
video.height = GlobalVideo.calc(3);
}
public var stopped:Bool = false;
public var restarted:Bool = false;
public var played:Bool = false;
public var ended:Bool = false;
public var paused:Bool = false;
public function pause():Void
{
netStream.pause();
paused = true;
}
public function resume():Void
{
netStream.resume();
paused = false;
}
public function togglePause():Void
{
if (paused)
{
resume();
} else {
pause();
}
}
public function clearPause():Void
{
paused = false;
}
public function onStop():Void
{
if (!ignoreShit)
{
stopped = true;
}
}
public function onRestart():Void
{
restarted = true;
}
public function onPlay(event:NetStatusEvent):Void
{
if (event.info.code == "NetStream.Play.Start")
{
played = true;
}
}
public function onEnd(event:NetStatusEvent):Void
{
if (event.info.code == "NetStream.Play.Complete")
{
ended = true;
}
}
public function alpha():Void
{
video.alpha = GlobalVideo.daAlpha1;
}
public function unalpha():Void
{
video.alpha = GlobalVideo.daAlpha2;
}
public function hide():Void
{
video.visible = false;
}
public function show():Void
{
video.visible = true;
}
}

169
source/WebmHandler.hx Normal file
View File

@ -0,0 +1,169 @@
package;
import flixel.FlxG;
import openfl.display.Sprite;
#if desktop
import webm.*;
#end
class WebmHandler
{
#if desktop
public var webm:WebmPlayer;
public var vidPath:String = "";
public var io:WebmIo;
public var initialized:Bool = false;
public function new()
{
}
public function source(?vPath:String):Void
{
if (vPath != null && vPath.length > 0)
{
vidPath = vPath;
}
}
public function makePlayer():Void
{
io = new WebmIoFile(vidPath);
webm = new WebmPlayer();
webm.fuck(io, false);
webm.addEventListener(WebmEvent.PLAY, function(e) {
onPlay();
});
webm.addEventListener(WebmEvent.COMPLETE, function(e) {
onEnd();
});
webm.addEventListener(WebmEvent.STOP, function(e) {
onStop();
});
webm.addEventListener(WebmEvent.RESTART, function(e) {
onRestart();
});
webm.visible = false;
initialized = true;
}
public function updatePlayer():Void
{
io = new WebmIoFile(vidPath);
webm.fuck(io, false);
}
public function play():Void
{
if (initialized)
{
webm.play();
}
}
public function stop():Void
{
if (initialized)
{
webm.stop();
}
}
public function restart():Void
{
if (initialized)
{
webm.restart();
}
}
public function update(elapsed:Float)
{
webm.x = GlobalVideo.calc(0);
webm.y = GlobalVideo.calc(1);
webm.width = GlobalVideo.calc(2);
webm.height = GlobalVideo.calc(3);
}
public var stopped:Bool = false;
public var restarted:Bool = false;
public var played:Bool = false;
public var ended:Bool = false;
public var paused:Bool = false;
public function pause():Void
{
webm.changePlaying(false);
paused = true;
}
public function resume():Void
{
webm.changePlaying(true);
paused = false;
}
public function togglePause():Void
{
if (paused)
{
resume();
} else {
pause();
}
}
public function clearPause():Void
{
paused = false;
webm.removePause();
}
public function onStop():Void
{
stopped = true;
}
public function onRestart():Void
{
restarted = true;
}
public function onPlay():Void
{
played = true;
}
public function onEnd():Void
{
trace("IT ENDED!");
ended = true;
}
public function alpha():Void
{
webm.alpha = GlobalVideo.daAlpha1;
}
public function unalpha():Void
{
webm.alpha = GlobalVideo.daAlpha2;
}
public function hide():Void
{
webm.visible = false;
}
public function show():Void
{
webm.visible = true;
}
#else
public var webm:Sprite;
public function new()
{
trace("THIS IS ANDROID! or some shit...");
}
#end
}