diff --git a/assets/preload/images/achievements/1000combo.png b/assets/preload/images/achievements/1000combo.png new file mode 100644 index 00000000..d99d20ac Binary files /dev/null and b/assets/preload/images/achievements/1000combo.png differ diff --git a/source/Main.hx b/source/Main.hx index a5065eae..3079d824 100644 --- a/source/Main.hx +++ b/source/Main.hx @@ -50,7 +50,7 @@ class Main extends Sprite public static var stage3D:AwayStage; #end - public static final PSYCH_ONLINE_VERSION:String = "0.8.2"; + public static final PSYCH_ONLINE_VERSION:String = "0.8.3"; public static final CLIENT_PROTOCOL:Float = 4; public static final GIT_COMMIT:String = online.Macros.getGitCommitHash(); diff --git a/source/backend/Achievements.hx b/source/backend/Achievements.hx index 1d1f4271..e990caff 100644 --- a/source/backend/Achievements.hx +++ b/source/backend/Achievements.hx @@ -17,7 +17,8 @@ class Achievements { ["Hyperactive", "Finish a Song without going Idle.", 'hype', false], ["Just the Two of Us", "Finish a Song pressing only two keys.", 'two_keys', false], ["Toaster Gamer", "Have you tried to run the game on a toaster?", 'toastie', false], - ["Debugger", "Beat the \"Test\" Stage from the Chart Editor.", 'debugger', true] + ["Debugger", "Beat the \"Test\" Stage from the Chart Editor.", 'debugger', true], + ["It's over 1000!", "Completed a Song with combo higher than 1000.", '1000combo', true] ]; public static var achievementsMap:Map = new Map(); diff --git a/source/objects/SustainSplash.hx b/source/objects/SustainSplash.hx index 8f4a0592..7eaf3a2e 100644 --- a/source/objects/SustainSplash.hx +++ b/source/objects/SustainSplash.hx @@ -13,6 +13,8 @@ class SustainSplash extends FlxSprite { public function new():Void { super(); + x = -50000; + var skin:String = defaultNoteHoldSplash + getSplashSkinPostfix(); frames = Paths.getSparrowAtlas(skin); if (frames == null) { @@ -28,9 +30,12 @@ class SustainSplash extends FlxSprite { super.update(elapsed); if (strumNote != null) { + setPosition(strumNote.x, strumNote.y); + visible = strumNote.visible; alpha = ClientPrefs.data.holdSplashAlpha - (1 - strumNote.alpha); if (animation.curAnim.name == "hold" && strumNote.animation.curAnim.name == "static") { + x = -50000; kill(); } } @@ -60,7 +65,6 @@ class SustainSplash extends FlxSprite { strumNote = strum; alpha = ClientPrefs.data.holdSplashAlpha - (1 - strumNote.alpha); - setPosition(strum.x, strum.y); offset.set(PlayState.isPixelStage ? 112.5 : 106.25, 100); if (timer != null) @@ -68,7 +72,7 @@ class SustainSplash extends FlxSprite { if (PlayState.isPlayerNote(tailEnd) && ClientPrefs.data.holdSplashAlpha != 0) timer = new FlxTimer().start(timeThingy, (idk:FlxTimer) -> { - if (!(daNote.isSustainNote ? daNote.parent.noteSplashData.disabled : daNote.noteSplashData.disabled)) { + if (!(daNote.isSustainNote ? daNote.parent.noteSplashData.disabled : daNote.noteSplashData.disabled)) { alpha = ClientPrefs.data.holdSplashAlpha - (1 - strumNote.alpha); animation.play('end', true, false, 0); animation.curAnim.looped = false; diff --git a/source/online/DownloadAlert.hx b/source/online/DownloadAlert.hx index 1c7813ba..af0e826a 100644 --- a/source/online/DownloadAlert.hx +++ b/source/online/DownloadAlert.hx @@ -82,6 +82,8 @@ class DownloadAlerts extends Sprite { alert.setStatus("Installing..."); else if (downloader.isDownloading) alert.updateProgress(downloader.gotContent, downloader.contentLength); + else + alert.setStatus(alert.newStatus); prevAlert = alert; i++; @@ -98,6 +100,8 @@ class DownloadAlert extends Sprite { public var cancelBg:Bitmap; public var cancelText:TextField; + public var newStatus:String = 'Initializing the Download...'; + public function new(id:String) { super(); @@ -139,7 +143,7 @@ class DownloadAlert extends Sprite { cancelText.defaultTextFormat = new TextFormat(Assets.getFont('assets/fonts/vcr.ttf').fontName, 13, 0xFFFFFFFF); addChild(cancelText); - setStatus("Initializing the download..."); + setStatus(newStatus); } public function updateProgress(loaded:Float, total:Float) { @@ -162,7 +166,7 @@ class DownloadAlert extends Sprite { } public function setStatus(string:String) { - if (text == null) + if (text == null || string == text.text) return; bar.visible = false; diff --git a/source/online/Downloader.hx b/source/online/Downloader.hx index 82f66756..3ddaf271 100644 --- a/source/online/Downloader.hx +++ b/source/online/Downloader.hx @@ -133,6 +133,7 @@ class Downloader { while (!cancelRequested) { tries++; + alert.newStatus = "Connecting to the server.."; try { socket.connect(new Host(urlFormat.domain), urlFormat.port); @@ -146,9 +147,7 @@ class Downloader { httpStatus = httpStatus.substr(httpStatus.indexOf(" ")).ltrim(); if (httpStatus == null || httpStatus.startsWith("4") || httpStatus.startsWith("5")) { - Waiter.put(() -> { - Alert.alert('Server Error - $httpStatus', 'Retrying ($tries)...'); - }); + alert.newStatus = 'Server Error: $httpStatus (Retry #$tries)...'; continue; } @@ -157,7 +156,9 @@ class Downloader { break; } catch (exc) { - if (tries >= 30) { + alert.newStatus = 'Failed to connect! (Retry #${tries})\n${exc.message}'; + + if (tries >= 10) { trace(id + ': ' + exc + "\n\n" + CallStack.toString(exc.stack)); Waiter.put(() -> { Alert.alert('Couldn\'t connect to the server after multiple tries!', '${urlFormat.domain + urlFormat.path}' + ': ' + exc + "\n\n" + CallStack.toString(exc.stack)); @@ -168,7 +169,7 @@ class Downloader { if (ClientPrefs.isDebug()) Sys.println("DHX: Retrying..."); - Sys.sleep(1); + Sys.sleep(5); } } @@ -177,6 +178,7 @@ class Downloader { return; } + alert.newStatus = "Reading server response headers..."; var gotHeaders:Map = new Map(); while (!cancelRequested) { var readLine:String = socket.input.readLine(); @@ -187,6 +189,8 @@ class Downloader { gotHeaders.set(splitHeader[0].toLowerCase(), splitHeader[1]); } + alert.newStatus = "Parsing server response headers..."; + if (ClientPrefs.isDebug()) Sys.println("DHX: Parsed response headers!"); diff --git a/source/psychlua/FunkinLua.hx b/source/psychlua/FunkinLua.hx index 8870e920..77e5f2ba 100644 --- a/source/psychlua/FunkinLua.hx +++ b/source/psychlua/FunkinLua.hx @@ -200,9 +200,6 @@ class FunkinLua { set('buildTarget', getBuildTarget()); - set('os', null); - set('require', null); - for (name => func in customFunctions) { if(func != null) diff --git a/source/psychlua/HScript.hx b/source/psychlua/HScript.hx index 46ab4453..dc3964ca 100644 --- a/source/psychlua/HScript.hx +++ b/source/psychlua/HScript.hx @@ -180,7 +180,7 @@ class HScript extends SScript { for(string in ['cpp', 'lib', 'reflect', 'cffi', 'process', 'lua', 'http']){ //Block some packages if(funcToRun.toLowerCase().contains(string) || funcToRun == null){ - trace("blacklisted keyword detected: " + string); + FunkinLua.luaTrace("Blacklisted keyword detected in: " + funcToRun, false, false, FlxColor.RED); return null; } } @@ -253,7 +253,7 @@ class HScript extends SScript #if HSCRIPT_ALLOWED for(string in ['cpp', 'lib', 'reflect', 'cffi', 'process', 'lua', 'http']){ //Block some packages if(funcToRun.toLowerCase().contains(string)){ - trace("blacklisted keyword detected: " + string); + FunkinLua.luaTrace("Blacklisted keyword detected in: " + funcToRun, false, false, FlxColor.RED); return null; } } @@ -275,7 +275,7 @@ class HScript extends SScript funk.addLocalCallback("addHaxeLibrary", function(libName:String, ?libPackage:String = '') { for(string in ['cpp', 'lib', 'reflect', 'cffi', 'process', 'lua', 'http']){ //Block some packages if(libName.toLowerCase().contains(string) || libPackage.toLowerCase().contains(string)){ - trace("blacklisted keyword detected: " + string); + FunkinLua.luaTrace("Blacklisted keyword detected in CL: " + libName + (libPackage != null ? " PKG: " + libPackage : ""), false, false, FlxColor.RED); return; } } diff --git a/source/states/FreeplayState.hx b/source/states/FreeplayState.hx index 7587e17c..b2c3e303 100644 --- a/source/states/FreeplayState.hx +++ b/source/states/FreeplayState.hx @@ -1,5 +1,6 @@ package states; +import flixel.tweens.misc.ShakeTween; import online.replay.ReplayPlayer; import online.replay.ReplayRecorder.ReplayData; import json2object.JsonParser; @@ -246,32 +247,68 @@ class FreeplayState extends MusicBeatState setDiffVisibility(true); - gainedText = new FlxText(0, 0, 0, '+ ${gainedPoints}FP'); - if (gainedPoints < 0) { - var aasss = '${gainedPoints}'.split(''); - aasss.insert(1, ' '); - gainedText.text = aasss.join('') + "FP"; - } - gainedText.setFormat(null, 40, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - gainedText.setPosition(FlxG.width - gainedText.width - 50, FlxG.height - gainedText.height - 50); - gainedText.visible = false; - gainedText.scrollFactor.set(); - add(gainedText); - + gainedText = new FlxText(0, 0, 0, '+ 0FP'); + // dead ass forgot about abs lmao + // if (gainedPoints < 0) { + // var aasss = '${gainedPoints}'.split(''); + // aasss.insert(1, ' '); + // gainedText.text = aasss.join('') + "FP"; + // } + var shakeTimer:ShakeTween = null; + var swagFP = null; + var endFP = gainedPoints; if (gainedPoints != 0) { - gainedText.visible = true; - if (gainedPoints > 0) { - FlxG.sound.play(Paths.sound('fap')); - if (ClientPrefs.data.flashing) - FlxFlicker.flicker(gainedText, 1, 0.03, true); - } + FlxG.sound.music.fadeOut(0.5, 0.2); + + FlxTween.num(0, endFP, 1 + (Math.abs(endFP) * 0.02), { + onComplete: (_) -> { + if (endFP > 0) { + FlxG.sound.play(Paths.sound('fap')); + + if (ClientPrefs.data.flashing) + FlxFlicker.flicker(gainedText, 1, 0.03, true); + } + + if (shakeTimer != null) + shakeTimer.cancel(); + + new FlxTimer().start(5, (t) -> { + FlxTween.tween(gainedText, {x: gainedText.x, y: FlxG.height, alpha: 0, angle: swagFP < 0 ? 90 : 0}, 1, {ease: FlxEase.quartOut}); + }); + + FlxG.sound.music.fadeIn(3, 0.2, 1); + }, + startDelay: 1, + ease: FlxEase.quadOut + }, (v) -> { + if (swagFP == Math.floor(v)) + return; - var prevGained = gainedPoints; + swagFP = Math.floor(v); + + if (swagFP < 0) { + gainedText.text = '- ${Math.abs(swagFP)}FP'; + var sound = FlxG.sound.play(Paths.sound('scrollMenu'), 0.2); + sound.pitch = 1 - Math.abs(swagFP) * 0.01; + } + else { + gainedText.text = '+ ${swagFP}FP'; + var sound = FlxG.sound.play(Paths.sound('scrollMenu'), 0.2); + sound.pitch = 1 + Math.abs(swagFP) * 0.01; + } - new FlxTimer().start(5, (t) -> { - FlxTween.tween(gainedText, {x: gainedText.x, y: FlxG.height, alpha: 0, angle: prevGained < 0 ? 90 : 0}, 1, {ease: FlxEase.quartOut}); + if (shakeTimer != null) + shakeTimer.cancel(); + shakeTimer = FlxTween.shake(gainedText, FlxMath.bound(swagFP * 0.002, 0, 0.05), 1); + + gainedText.setPosition(FlxG.width - gainedText.width - 50, FlxG.height - gainedText.height - 50); }); } + gainedText.setFormat(null, 40, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + gainedText.setPosition(FlxG.width - gainedText.width - 50, FlxG.height - gainedText.height - 50); + gainedText.visible = gainedPoints != 0; + gainedText.scrollFactor.set(); + add(gainedText); gainedPoints = 0; diff --git a/source/states/PlayState.hx b/source/states/PlayState.hx index 9caabcf8..8541d2f6 100644 --- a/source/states/PlayState.hx +++ b/source/states/PlayState.hx @@ -278,7 +278,14 @@ class PlayState extends MusicBeatState public var camLoading:FlxCamera; public var cameraSpeed:Float = 1; - public var songScore:Int = 0; + var _tempDiff:Float = 0; + public var songScore(default, set):Int = 0; + function set_songScore(v) { + _tempDiff = v - songScore; + _tempDiff *= 1 + (playbackRate - 1) * 0.1; + _tempDiff *= 1 + (songSpeed - PlayState.SONG.speed) * 0.1; + return songScore += Math.floor(_tempDiff); + } public var songHits:Int = 0; public var songMisses:Int = 0; public var songSicks:Int = 0; @@ -861,6 +868,7 @@ class PlayState extends MusicBeatState SustainSplash.frameRate = Math.floor(24 / 100 * SONG.bpm); var splash:SustainSplash = new SustainSplash(); grpHoldSplashes.add(splash); + splash.visible = true; splash.alpha = 0.0001; opponentStrums = new FlxTypedGroup(); @@ -3168,7 +3176,7 @@ class PlayState extends MusicBeatState else { var noMissWeek:String = WeekData.getWeekFileName() + '_nomiss'; - var achieve:String = checkForAchievement([noMissWeek, 'ur_bad', 'ur_good', 'hype', 'two_keys', 'toastie', 'debugger']); + var achieve:String = checkForAchievement([noMissWeek, 'ur_bad', 'ur_good', 'hype', 'two_keys', 'toastie', 'debugger', '1000combo']); if(achieve != null) { startAchievement(achieve); return false; @@ -4684,6 +4692,9 @@ class PlayState extends MusicBeatState case 'debugger': unlock = (Paths.formatToSongPath(SONG.song) == 'test' && !usedPractice); + + case '1000combo': + unlock = combo > 1000; } }