From 35eee013d5568f0bf1cd8bba291a08beb896625f Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Fri, 6 Nov 2020 01:57:00 -0800 Subject: [PATCH 01/35] balanced normal, and usin newgrounds haxelib --- CHANGELOG.md | 36 +- Project.xml | 11 +- source/ChartingState.hx | 9 + source/FreeplayState.hx | 56 ++- source/Highscore.hx | 62 +++ source/MainMenuState.hx | 15 +- source/MusicBeatSubstate.hx | 1 + source/NGio.hx | 9 + source/OptionsMenu.hx | 29 ++ source/OptionsSubState.hx | 11 + source/PlayState.hx | 16 +- source/StoryMenuState.hx | 11 +- source/TitleState.hx | 37 +- source/io/newgrounds/Call.hx | 227 --------- source/io/newgrounds/NG.hx | 475 ------------------ source/io/newgrounds/NGLite.hx | 287 ----------- .../io/newgrounds/components/AppComponent.hx | 44 -- source/io/newgrounds/components/Component.hx | 13 - .../io/newgrounds/components/ComponentList.hx | 25 - .../newgrounds/components/EventComponent.hx | 16 - .../newgrounds/components/GatewayComponent.hx | 25 - .../newgrounds/components/LoaderComponent.hx | 44 -- .../newgrounds/components/MedalComponent.hx | 21 - .../components/ScoreBoardComponent.hx | 114 ----- source/io/newgrounds/crypto/Cipher.hx | 8 - .../io/newgrounds/crypto/EncryptionFormat.hx | 7 - source/io/newgrounds/crypto/Rc4.hx | 68 --- source/io/newgrounds/objects/Error.hx | 20 - source/io/newgrounds/objects/Medal.hx | 118 ----- source/io/newgrounds/objects/Object.hx | 33 -- source/io/newgrounds/objects/Score.hx | 17 - source/io/newgrounds/objects/ScoreBoard.hx | 76 --- source/io/newgrounds/objects/Session.hx | 65 --- source/io/newgrounds/objects/User.hx | 19 - source/io/newgrounds/objects/UserIcons.hx | 14 - .../io/newgrounds/objects/events/Response.hx | 43 -- source/io/newgrounds/objects/events/Result.hx | 109 ---- source/io/newgrounds/swf/LoadingBar.hx | 23 - source/io/newgrounds/swf/MedalPopup.hx | 151 ------ source/io/newgrounds/swf/ScoreBrowser.hx | 250 --------- source/io/newgrounds/swf/common/BaseAsset.hx | 35 -- source/io/newgrounds/swf/common/Button.hx | 151 ------ source/io/newgrounds/swf/common/DropDown.hx | 88 ---- source/io/newgrounds/utils/AsyncHttp.hx | 203 -------- source/io/newgrounds/utils/Dispatcher.hx | 118 ----- 45 files changed, 257 insertions(+), 2953 deletions(-) create mode 100644 source/Highscore.hx create mode 100644 source/OptionsMenu.hx create mode 100644 source/OptionsSubState.hx delete mode 100644 source/io/newgrounds/Call.hx delete mode 100644 source/io/newgrounds/NG.hx delete mode 100644 source/io/newgrounds/NGLite.hx delete mode 100644 source/io/newgrounds/components/AppComponent.hx delete mode 100644 source/io/newgrounds/components/Component.hx delete mode 100644 source/io/newgrounds/components/ComponentList.hx delete mode 100644 source/io/newgrounds/components/EventComponent.hx delete mode 100644 source/io/newgrounds/components/GatewayComponent.hx delete mode 100644 source/io/newgrounds/components/LoaderComponent.hx delete mode 100644 source/io/newgrounds/components/MedalComponent.hx delete mode 100644 source/io/newgrounds/components/ScoreBoardComponent.hx delete mode 100644 source/io/newgrounds/crypto/Cipher.hx delete mode 100644 source/io/newgrounds/crypto/EncryptionFormat.hx delete mode 100644 source/io/newgrounds/crypto/Rc4.hx delete mode 100644 source/io/newgrounds/objects/Error.hx delete mode 100644 source/io/newgrounds/objects/Medal.hx delete mode 100644 source/io/newgrounds/objects/Object.hx delete mode 100644 source/io/newgrounds/objects/Score.hx delete mode 100644 source/io/newgrounds/objects/ScoreBoard.hx delete mode 100644 source/io/newgrounds/objects/Session.hx delete mode 100644 source/io/newgrounds/objects/User.hx delete mode 100644 source/io/newgrounds/objects/UserIcons.hx delete mode 100644 source/io/newgrounds/objects/events/Response.hx delete mode 100644 source/io/newgrounds/objects/events/Result.hx delete mode 100644 source/io/newgrounds/swf/LoadingBar.hx delete mode 100644 source/io/newgrounds/swf/MedalPopup.hx delete mode 100644 source/io/newgrounds/swf/ScoreBrowser.hx delete mode 100644 source/io/newgrounds/swf/common/BaseAsset.hx delete mode 100644 source/io/newgrounds/swf/common/Button.hx delete mode 100644 source/io/newgrounds/swf/common/DropDown.hx delete mode 100644 source/io/newgrounds/utils/AsyncHttp.hx delete mode 100644 source/io/newgrounds/utils/Dispatcher.hx diff --git a/CHANGELOG.md b/CHANGELOG.md index 875bc460f..7b599ea70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,16 +1,32 @@ # Changelog All notable changes will be documented in this file. -## [1.1.0] -### Added -- 32bit support -- Controller (dancepads) support -- Pause screen -- Main Menu overhaul -- Cool intro screen thing -- Uh lots of bullshit -- Remind me to actually add this later lmaooo +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [1.0.0] - 2020-10-05 +## [Unreleased] +### Added + + +## [0.2.1] - 2020-11-06 +### Added +- Scores to the freeplay menu +- A few new intro boot messages. +- Lightning effect in Spooky stages +- Campaign scores, can now compete on scoreboards for campaign! +- Can now change difficulties in + +### Changed +- Balanced out Normal mode for all songs. Should be much easier all around. +- Put tutorial in it's own 'week', so that if you want to play week 1, you don't have to play the tutorial. + +### Fixed +- One of the charting bits on South and Spookeez during the intro. + +## [0.2.0] - 2020-11-01 +### Added +- Uhh Newgrounds release lolol I always lose track of shit. + +## [0.1.0] - 2020-10-05 ### Added - Uh, everything. This the game's initial gamejam release. We put it out \ No newline at end of file diff --git a/Project.xml b/Project.xml index d7c38fa32..673afa4ed 100644 --- a/Project.xml +++ b/Project.xml @@ -2,7 +2,7 @@ - + @@ -44,6 +44,8 @@ + + @@ -57,6 +59,9 @@ + + + @@ -98,8 +103,8 @@ - - + + diff --git a/source/ChartingState.hx b/source/ChartingState.hx index 070d55597..deeb34924 100644 --- a/source/ChartingState.hx +++ b/source/ChartingState.hx @@ -28,7 +28,9 @@ import openfl.events.Event; import openfl.events.IOErrorEvent; import openfl.events.IOErrorEvent; import openfl.events.IOErrorEvent; +import openfl.media.Sound; import openfl.net.FileReference; +import openfl.utils.ByteArray; using StringTools; @@ -762,6 +764,13 @@ class ChartingState extends MusicBeatState FlxG.resetState(); } + var mp3File:Sound; + var waveForm:FlxSprite; + + function drawWave():Void + { + } + private function saveLevel() { var json = { diff --git a/source/FreeplayState.hx b/source/FreeplayState.hx index 193744704..f906e8f07 100644 --- a/source/FreeplayState.hx +++ b/source/FreeplayState.hx @@ -1,10 +1,15 @@ package; +import flash.text.TextField; import flixel.FlxG; import flixel.FlxSprite; import flixel.addons.display.FlxGridOverlay; import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.math.FlxMath; import flixel.text.FlxText; +import flixel.util.FlxColor; +import htmlparser.HtmlDocument; +import lime.utils.Assets; class FreeplayState extends MusicBeatState { @@ -13,12 +18,19 @@ class FreeplayState extends MusicBeatState var selector:FlxText; var curSelected:Int = 0; + var scoreText:FlxText; + var lerpScore:Int = 0; + var intendedScore:Int = 0; + private var grpSongs:FlxTypedGroup; override function create() { - if (!FlxG.sound.music.playing) - FlxG.sound.playMusic('assets/music/freakyMenu' + TitleState.soundExt); + if (FlxG.sound.music != null) + { + if (!FlxG.sound.music.playing) + FlxG.sound.playMusic('assets/music/freakyMenu' + TitleState.soundExt); + } var isDebug:Bool = false; @@ -53,6 +65,17 @@ class FreeplayState extends MusicBeatState // songText.screenCenter(X); } + scoreText = new FlxText(FlxG.width * 0.7, 5, 0, "", 32); + // scoreText.autoSize = false; + scoreText.setFormat("assets/fonts/vcr.ttf", 32, FlxColor.WHITE, RIGHT); + // scoreText.alignment = RIGHT; + + var scoreBG:FlxSprite = new FlxSprite(scoreText.x - 6, 0).makeGraphic(Std.int(FlxG.width * 0.35), 40, 0xFF000000); + scoreBG.alpha = 0.6; + add(scoreBG); + + add(scoreText); + changeSelection(); // FlxG.sound.playMusic('assets/music/title' + TitleState.soundExt, 0); @@ -65,12 +88,33 @@ class FreeplayState extends MusicBeatState var swag:Alphabet = new Alphabet(1, 0, "swag"); + // JUST DOIN THIS SHIT FOR TESTING!!! + /* + var md:String = Markdown.markdownToHtml(Assets.getText('CHANGELOG.md')); + + var texFel:TextField = new TextField(); + texFel.width = FlxG.width; + texFel.height = FlxG.height; + // texFel. + texFel.htmlText = md; + + FlxG.stage.addChild(texFel); + + // scoreText.textField.htmlText = md; + + trace(md); + */ + super.create(); } override function update(elapsed:Float) { super.update(elapsed); + + lerpScore = Math.floor(FlxMath.lerp(lerpScore, intendedScore, 0.4)); + scoreText.text = "PERSONAL BEST:" + lerpScore; + var upP = controls.UP_P; var downP = controls.DOWN_P; var accepted = controls.ACCEPT; @@ -94,12 +138,15 @@ class FreeplayState extends MusicBeatState PlayState.SONG = Song.loadFromJson(songs[curSelected].toLowerCase(), songs[curSelected].toLowerCase()); PlayState.isStoryMode = false; FlxG.switchState(new PlayState()); - FlxG.sound.music.stop(); + if (FlxG.sound.music != null) + FlxG.sound.music.stop(); } } function changeSelection(change:Int = 0) { + NGio.logEvent('Fresh'); + curSelected += change; if (curSelected < 0) @@ -109,6 +156,9 @@ class FreeplayState extends MusicBeatState // selector.y = (70 * curSelected) + 30; + intendedScore = Highscore.getScore(songs[curSelected], 1); + // lerpScore = 0; + var bullShit:Int = 0; for (item in grpSongs.members) diff --git a/source/Highscore.hx b/source/Highscore.hx new file mode 100644 index 000000000..f587a3a17 --- /dev/null +++ b/source/Highscore.hx @@ -0,0 +1,62 @@ +package; + +import flixel.FlxG; + +class Highscore +{ + public static var songScores:Map = new Map(); + + public static function saveScore(song:String, score:Int = 0, ?diff:Int = 0):Void + { + var daSong:String = formatSong(song, diff); + + NGio.postScore(score, song); + + if (songScores.exists(daSong)) + { + if (songScores.get(daSong) < score) + setScore(daSong, score); + } + else + setScore(daSong, score); + } + + /** + * YOU SHOULD FORMAT SONG WITH formatSong() BEFORE TOSSING IN SONG VARIABLE + */ + static function setScore(song:String, score:Int):Void + { + // Reminder that I don't need to format this song, it should come formatted! + songScores.set(song, score); + FlxG.save.data.songScores = songScores; + FlxG.save.flush(); + } + + public static function formatSong(song:String, diff:Int):String + { + var daSong:String = song; + + if (diff == 0) + daSong += '-easy'; + else if (diff == 2) + daSong += '-hard'; + + return daSong; + } + + public static function getScore(song:String, diff:Int):Int + { + if (!songScores.exists(formatSong(song, diff))) + setScore(formatSong(song, diff), 0); + + return songScores.get(formatSong(song, diff)); + } + + public static function load():Void + { + if (FlxG.save.data.songScores != null) + { + songScores = FlxG.save.data.songScores; + } + } +} diff --git a/source/MainMenuState.hx b/source/MainMenuState.hx index 19ddb46bb..cdabcbbcb 100644 --- a/source/MainMenuState.hx +++ b/source/MainMenuState.hx @@ -6,8 +6,11 @@ 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 lime.app.Application; class MainMenuState extends MusicBeatState { @@ -15,7 +18,7 @@ class MainMenuState extends MusicBeatState var menuItems:FlxTypedGroup; - var optionShit:Array = ['story mode', 'freeplay', 'donate']; + var optionShit:Array = ['story mode', 'freeplay', 'options', 'donate']; var magenta:FlxSprite; var camFollow:FlxObject; @@ -36,7 +39,7 @@ class MainMenuState extends MusicBeatState camFollow = new FlxObject(0, 0, 1, 1); add(camFollow); - magenta = new FlxSprite(-80).loadGraphic(AssetPaths.menuBGMagenta__png); + magenta = new FlxSprite(-80).loadGraphic(AssetPaths.menuDesat__png); magenta.scrollFactor.x = 0; magenta.scrollFactor.y = 0.18; magenta.setGraphicSize(Std.int(magenta.width * 1.1)); @@ -44,6 +47,7 @@ class MainMenuState extends MusicBeatState magenta.screenCenter(); magenta.visible = false; magenta.antialiasing = true; + magenta.color = 0xFFfd719b; add(magenta); // magenta.scrollFactor.set(); @@ -68,6 +72,11 @@ class MainMenuState extends MusicBeatState FlxG.camera.follow(camFollow, null, 0.06); + var versionShit:FlxText = new FlxText(5, FlxG.height - 18, 0, "v" + Application.current.meta.get('version')); + versionShit.scrollFactor.set(); + versionShit.setFormat("VCR OSD Mono", 16, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + add(versionShit); + changeItem(); super.create(); @@ -133,6 +142,8 @@ class MainMenuState extends MusicBeatState FlxG.switchState(new StoryMenuState()); case 'freeplay': FlxG.switchState(new FreeplayState()); + case 'options': + FlxG.switchState(new OptionsMenu()); } }); } diff --git a/source/MusicBeatSubstate.hx b/source/MusicBeatSubstate.hx index 0e452e9cd..511f597a7 100644 --- a/source/MusicBeatSubstate.hx +++ b/source/MusicBeatSubstate.hx @@ -1,5 +1,6 @@ package; +import flixel.FlxG; import flixel.FlxSubState; class MusicBeatSubstate extends FlxSubState diff --git a/source/NGio.hx b/source/NGio.hx index f90bca4c4..2073c073b 100644 --- a/source/NGio.hx +++ b/source/NGio.hx @@ -146,6 +146,15 @@ class NGio // NGio.scoreboardArray = NG.core.scoreBoards.get(8004).scores; } + inline static public function logEvent(event:String) + { + if (isLoggedIn) + { + NG.core.calls.event.logEvent(event); + trace('should have logged: ' + event); + } + } + inline static public function unlockMedal(id:Int) { if (isLoggedIn) diff --git a/source/OptionsMenu.hx b/source/OptionsMenu.hx new file mode 100644 index 000000000..c79c3ec70 --- /dev/null +++ b/source/OptionsMenu.hx @@ -0,0 +1,29 @@ +package; + +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.util.FlxColor; + +class OptionsMenu extends MusicBeatState +{ + override function create() + { + var menuBG:FlxSprite = new FlxSprite().loadGraphic(AssetPaths.menuDesat__png); + menuBG.color = 0xFFea71fd; + menuBG.setGraphicSize(Std.int(menuBG.width * 1.1)); + menuBG.updateHitbox(); + menuBG.screenCenter(); + menuBG.antialiasing = true; + add(menuBG); + + super.create(); + } + + override function update(elapsed:Float) + { + if (controls.BACK) + FlxG.switchState(new MainMenuState()); + + super.update(elapsed); + } +} diff --git a/source/OptionsSubState.hx b/source/OptionsSubState.hx new file mode 100644 index 000000000..1995b868a --- /dev/null +++ b/source/OptionsSubState.hx @@ -0,0 +1,11 @@ +package; + +class OptionsSubState extends MusicBeatSubstate +{ + var textMenuItems:Array = ['Master Volume', 'Sound Volume']; + + public function new() + { + super(); + } +} diff --git a/source/PlayState.hx b/source/PlayState.hx index 0163efc84..9ca8723a5 100644 --- a/source/PlayState.hx +++ b/source/PlayState.hx @@ -562,7 +562,7 @@ class PlayState extends MusicBeatState { if (FlxG.sound.music != null) { - vocals.time = FlxG.sound.music.time; + vocals.time = Conductor.songPosition; FlxG.sound.music.play(); vocals.play(); @@ -595,9 +595,9 @@ class PlayState extends MusicBeatState openSubState(new PauseSubState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y)); } - if (FlxG.keys.justPressed.ESCAPE) + if (FlxG.keys.justPressed.SEVEN) { - // FlxG.switchState(new ChartingState()); + FlxG.switchState(new ChartingState()); } // FlxG.watch.addQuick('VOL', vocals.amplitudeLeft); @@ -792,6 +792,7 @@ class PlayState extends MusicBeatState } daNote.y = (strumLine.y - (Conductor.songPosition - daNote.strumTime) * (0.45 * PlayState.SONG.speed)); + // WIP interpolation shit? Need to fix the pause issue // daNote.y = (strumLine.y - (songTime - daNote.strumTime) * (0.45 * PlayState.SONG.speed)); @@ -820,11 +821,7 @@ class PlayState extends MusicBeatState { trace('SONG DONE' + isStoryMode); - - #if !switch - NGio.postScore(songScore, SONG.song); - #end - + Highscore.saveScore(SONG.song, songScore, storyDifficulty); if (isStoryMode) { @@ -838,10 +835,7 @@ class PlayState extends MusicBeatState StoryMenuState.weekUnlocked[1] = true; - #if !switch NGio.unlockMedal(60961); - #end - FlxG.save.data.weekUnlocked = StoryMenuState.weekUnlocked; FlxG.save.flush(); diff --git a/source/StoryMenuState.hx b/source/StoryMenuState.hx index d88ab4833..ca6ba28f7 100644 --- a/source/StoryMenuState.hx +++ b/source/StoryMenuState.hx @@ -38,8 +38,11 @@ class StoryMenuState extends MusicBeatState override function create() { - if (!FlxG.sound.music.playing) - FlxG.sound.playMusic('assets/music/freakyMenu' + TitleState.soundExt); + if (FlxG.sound.music != null) + { + if (!FlxG.sound.music.playing) + FlxG.sound.playMusic('assets/music/freakyMenu' + TitleState.soundExt); + } persistentUpdate = persistentDraw = true; @@ -300,6 +303,10 @@ class StoryMenuState extends MusicBeatState for (item in grpWeekText.members) { item.targetY = bullShit - curWeek; + if (item.targetY == Std.int(0)) + item.alpha = 1; + else + item.alpha = 0.6; bullShit++; } diff --git a/source/TitleState.hx b/source/TitleState.hx index 172e8fed4..003563583 100644 --- a/source/TitleState.hx +++ b/source/TitleState.hx @@ -36,13 +36,13 @@ class TitleState extends MusicBeatState ['Ritz dx', 'rest in peace'], ['rate five', 'pls no blam'], ['rhythm gaming', 'ultimate'], ['game of the year', 'forever'], ['you already know', 'we really out here'], ['rise and grind', 'love to luis'], ['like parappa', 'but cooler'], ['album of the year', 'chuckie finster'], ["free gitaroo man", "with love to wandaboy"], ['better than geometry dash', 'fight me robtop'], - ['kiddbrute for president', 'vote now']]; + ['kiddbrute for president', 'vote now'], ['play dead estate', 'on newgrounds'], ['this is a god damn prototype', 'we workin on it okay'], + ['WOMEN ARE real', 'this is official']]; var curWacky:Array = []; var wackyImage:FlxSprite; - override public function create():Void { #if (!web) @@ -57,16 +57,21 @@ class TitleState extends MusicBeatState super.create(); - #if (!switch && !debug && NG_LOGIN) - var ng:NGio = new NGio(APIStuff.API, APIStuff.EncKey); #end + FlxG.save.bind('funkin', 'ninjamuffin99'); + + Highscore.load(); + + if (FlxG.save.data.weekUnlocked != null) + { + StoryMenuState.weekUnlocked = FlxG.save.data.weekUnlocked; + } + #if SKIP_TO_PLAYSTATE - - FlxG.switchState(new StoryMenuState()); - + FlxG.switchState(new FreeplayState()); #else startIntro(); #end @@ -99,13 +104,6 @@ class TitleState extends MusicBeatState FlxG.sound.playMusic('assets/music/freakyMenu' + TitleState.soundExt, 0); FlxG.sound.music.fadeIn(4, 0, 0.7); - - FlxG.save.bind('funkin', 'ninjamuffin99'); - - if (FlxG.save.data.weekUnlocked != null) - { - StoryMenuState.weekUnlocked = FlxG.save.data.weekUnlocked; - } } Conductor.changeBPM(102); @@ -191,6 +189,12 @@ class TitleState extends MusicBeatState override function update(elapsed:Float) { Conductor.songPosition = FlxG.sound.music.time; + // FlxG.watch.addQuick('amp', FlxG.sound.music.amplitude); + + if (FlxG.keys.justPressed.F) + { + FlxG.fullscreen = !FlxG.fullscreen; + } var pressedEnter:Bool = FlxG.keys.justPressed.ENTER; @@ -204,9 +208,12 @@ class TitleState extends MusicBeatState if (pressedEnter && !transitioning && skippedIntro) { - #if !switch NGio.unlockMedal(60960); + + // If it's Friday according to da clock + if (Date.now().getDay() == 5) + NGio.unlockMedal(61034); #end titleText.animation.play('press'); diff --git a/source/io/newgrounds/Call.hx b/source/io/newgrounds/Call.hx deleted file mode 100644 index bd5d7acaf..000000000 --- a/source/io/newgrounds/Call.hx +++ /dev/null @@ -1,227 +0,0 @@ -package io.newgrounds; - -import io.newgrounds.utils.Dispatcher; -import io.newgrounds.utils.AsyncHttp; -import io.newgrounds.objects.Error; -import io.newgrounds.objects.events.Result; -import io.newgrounds.objects.events.Result.ResultBase; -import io.newgrounds.objects.events.Response; - -import haxe.ds.StringMap; -import haxe.Json; - -/** A generic way to handle calls agnostic to their type */ -interface ICallable { - - public var component(default, null):String; - - public function send():Void; - public function queue():Void; - public function destroy():Void; -} - -class Call - implements ICallable { - - public var component(default, null):String; - - var _core:NGLite; - var _properties:StringMap; - var _parameters:StringMap; - var _requireSession:Bool; - var _isSecure:Bool; - - // --- BASICALLY SIGNALS - var _dataHandlers:TypedDispatcher>; - var _successHandlers:Dispatcher; - var _httpErrorHandlers:TypedDispatcher; - var _statusHandlers:TypedDispatcher; - - public function new (core:NGLite, component:String, requireSession:Bool = false, isSecure:Bool = false) { - - _core = core; - this.component = component; - _requireSession = requireSession; - _isSecure = isSecure && core.encryptionHandler != null; - } - - /** adds a property to the input's object. **/ - public function addProperty(name:String, value:Dynamic):Call { - - if (_properties == null) - _properties = new StringMap(); - - _properties.set(name, value); - - return this; - } - - /** adds a parameter to the call's component object. **/ - public function addComponentParameter(name:String, value:Dynamic, defaultValue:Dynamic = null):Call { - - if (value == defaultValue)//TODO?: allow sending null value - return this; - - if (_parameters == null) - _parameters = new StringMap(); - - _parameters.set(name, value); - - return this; - } - - /** Handy callback setter for chained call modifiers. Called when ng.io replies successfully */ - public function addDataHandler(handler:Response->Void):Call { - - if (_dataHandlers == null) - _dataHandlers = new TypedDispatcher>(); - - _dataHandlers.add(handler); - return this; - } - - /** Handy callback setter for chained call modifiers. Called when ng.io replies successfully */ - public function addSuccessHandler(handler:Void->Void):Call { - - if (_successHandlers == null) - _successHandlers = new Dispatcher(); - - _successHandlers.add(handler); - return this; - } - - /** Handy callback setter for chained call modifiers. Called when ng.io does not reply for any reason */ - public function addErrorHandler(handler:Error->Void):Call { - - if (_httpErrorHandlers == null) - _httpErrorHandlers = new TypedDispatcher(); - - _httpErrorHandlers.add(handler); - return this; - } - - /** Handy callback setter for chained call modifiers. No idea when this is called; */ - public function addStatusHandler(handler:Int->Void):Call {//TODO:learn what this is for - - if (_statusHandlers == null) - _statusHandlers = new TypedDispatcher(); - - _statusHandlers.add(handler); - return this; - } - - /** - * Sends the call to the server, do not modify this object after calling this - * @param secure If encryption is enabled, it will encrypt the call. - **/ - public function send():Void { - - var data:Dynamic = {}; - data.app_id = _core.appId; - data.call = {}; - data.call.component = component; - - if (_core.debug) - addProperty("debug", true); - - if (_properties == null || !_properties.exists("session_id")) { - // --- HAS NO SESSION ID - - if (_core.sessionId != null) { - // --- AUTO ADD SESSION ID - - addProperty("session_id", _core.sessionId); - - } else if (_requireSession){ - - _core.logError(new Error('cannot send "$component" call without a sessionId')); - return; - } - } - - if (_properties != null) { - - for (field in _properties.keys()) - Reflect.setField(data, field, _properties.get(field)); - } - - if (_parameters != null) { - - data.call.parameters = {}; - - for (field in _parameters.keys()) - Reflect.setField(data.call.parameters, field, _parameters.get(field)); - } - - _core.logVerbose('Post - ${Json.stringify(data)}'); - - if (_isSecure) { - - var secureData = _core.encryptionHandler(Json.stringify(data.call)); - data.call = {}; - data.call.secure = secureData; - - _core.logVerbose(' secure - $secureData'); - } - - _core.markCallPending(this); - - AsyncHttp.send(_core, Json.stringify(data), onData, onHttpError, onStatus); - } - - /** Adds the call to the queue */ - public function queue():Void { - - _core.queueCall(this); - } - - function onData(reply:String):Void { - - _core.logVerbose('Reply - $reply'); - - if (_dataHandlers == null && _successHandlers == null) - return; - - var response = new Response(_core, reply); - - if (_dataHandlers != null) - _dataHandlers.dispatch(response); - - if (response.success && response.result.success && _successHandlers != null) - _successHandlers.dispatch(); - - destroy(); - } - - function onHttpError(message:String):Void { - - _core.logError(message); - - if (_httpErrorHandlers == null) - return; - - var error = new Error(message); - _httpErrorHandlers.dispatch(error); - } - - function onStatus(status:Int):Void { - - if (_statusHandlers == null) - return; - - _statusHandlers.dispatch(status); - } - - public function destroy():Void { - - _core = null; - - _properties = null; - _parameters = null; - - _dataHandlers = null; - _successHandlers = null; - _httpErrorHandlers = null; - _statusHandlers = null; - } -} \ No newline at end of file diff --git a/source/io/newgrounds/NG.hx b/source/io/newgrounds/NG.hx deleted file mode 100644 index 3445443ee..000000000 --- a/source/io/newgrounds/NG.hx +++ /dev/null @@ -1,475 +0,0 @@ -package io.newgrounds; - -#if ng_lite -typedef NG = NGLite; //TODO: test and make lite UI -#else -import io.newgrounds.utils.Dispatcher; -import io.newgrounds.objects.Error; -import io.newgrounds.objects.events.Result.SessionResult; -import io.newgrounds.objects.events.Result.MedalListResult; -import io.newgrounds.objects.events.Result.ScoreBoardResult; -import io.newgrounds.objects.events.Response; -import io.newgrounds.objects.User; -import io.newgrounds.objects.Medal; -import io.newgrounds.objects.Session; -import io.newgrounds.objects.ScoreBoard; - -import haxe.ds.IntMap; -import haxe.Timer; - -/** - * The Newgrounds API for Haxe. - * Contains many things ripped from MSGhero - * - https://github.com/MSGhero/NG.hx - * @author GeoKureli - */ -class NG extends NGLite { - - static public var core(default, null):NG; - static public var onCoreReady(default, null):Dispatcher = new Dispatcher(); - - // --- DATA - - /** The logged in user */ - public var user(get, never):User; - function get_user():User { - - if (_session == null) - return null; - - return _session.user; - } - public var passportUrl(get, never):String; - function get_passportUrl():String { - - if (_session == null || _session.status != SessionStatus.REQUEST_LOGIN) - return null; - - return _session.passportUrl; - } - public var medals(default, null):IntMap; - public var scoreBoards(default, null):IntMap; - - // --- EVENTS - - public var onLogin(default, null):Dispatcher; - public var onLogOut(default, null):Dispatcher; - public var onMedalsLoaded(default, null):Dispatcher; - public var onScoreBoardsLoaded(default, null):Dispatcher; - - // --- MISC - - public var loggedIn(default, null):Bool; - public var attemptingLogin(default, null):Bool; - - var _loginCancelled:Bool; - var _passportCallback:Void->Void; - - var _session:Session; - - /** - * Iniitializes the API, call before utilizing any other component - * @param appId The unique ID of your app as found in the 'API Tools' tab of your Newgrounds.com project. - * @param sessionId A unique session id used to identify the active user. - **/ - public function new(appId = "test", sessionId:String = null, ?onSessionFail:Error->Void) { - - _session = new Session(this); - onLogin = new Dispatcher(); - onLogOut = new Dispatcher(); - onMedalsLoaded = new Dispatcher(); - onScoreBoardsLoaded = new Dispatcher(); - - attemptingLogin = sessionId != null; - - super(appId, sessionId, onSessionFail); - } - - /** - * Creates NG.core, the heart and soul of the API. This is not the only way to create an instance, - * nor is NG a forced singleton, but it's the only way to set the static NG.core. - **/ - static public function create(appId = "test", sessionId:String = null, ?onSessionFail:Error->Void):Void { - - core = new NG(appId, sessionId, onSessionFail); - - onCoreReady.dispatch(); - } - - /** - * Creates NG.core, and tries to create a session. This is not the only way to create an instance, - * nor is NG a forced singleton, but it's the only way to set the static NG.core. - **/ - static public function createAndCheckSession - ( appId = "test" - , backupSession:String = null - , ?onSessionFail:Error->Void - ):Void { - - var session = NGLite.getSessionId(); - if (session == null) - session = backupSession; - - create(appId, session, onSessionFail); - - core.host = getHost(); - if (core.sessionId != null) - core.attemptingLogin = true; - } - - // ------------------------------------------------------------------------------------------- - // APP - // ------------------------------------------------------------------------------------------- - - override function checkInitialSession(failHandler:Error->Void, response:Response):Void { - - onSessionReceive(response, null, null, failHandler); - } - - /** - * Begins the login process - * - * @param onSuccess Called when the login is a success - * @param onPending Called when the passportUrl has been identified, call NG.core.openPassportLink - * to open the link continue the process. Leave as null to open the url automatically - * NOTE: Browser games must open links on click events or else it will be blocked by - * the popup blocker. - * @param onFail - * @param onCancel Called when the user denies the passport connection. - */ - public function requestLogin - ( onSuccess:Void->Void = null - , onPending:Void->Void = null - , onFail :Error->Void = null - , onCancel :Void->Void = null - ):Void { - - if (attemptingLogin) { - - logError("cannot request another login until the previous attempt is complete"); - return; - } - - if (loggedIn) { - - logError("cannot log in, already logged in"); - return; - } - - attemptingLogin = true; - _loginCancelled = false; - _passportCallback = null; - - var call = calls.app.startSession(true) - .addDataHandler(onSessionReceive.bind(_, onSuccess, onPending, onFail, onCancel)); - - if (onFail != null) - call.addErrorHandler(onFail); - - call.send(); - } - - function onSessionReceive - ( response :Response - , onSuccess:Void->Void = null - , onPending:Void->Void = null - , onFail :Error->Void = null - , onCancel :Void->Void = null - ):Void { - - if (!response.success || !response.result.success) { - - sessionId = null; - endLoginAndCall(null); - - if (onFail != null) - onFail(!response.success ? response.error : response.result.error); - - return; - } - - _session.parse(response.result.data.session); - sessionId = _session.id; - - logVerbose('session started - status: ${_session.status}'); - - if (_session.status == SessionStatus.REQUEST_LOGIN) { - - _passportCallback = checkSession.bind(null, onSuccess, onCancel); - if (onPending != null) - onPending(); - else - openPassportUrl(); - - } else - checkSession(null, onSuccess, onCancel); - } - - /** - * Call this once the passport link is established and it will load the passport URL and - * start checking for session connect periodically - */ - public function openPassportUrl():Void { - - if (passportUrl != null) { - - logVerbose('loading passport: ${passportUrl}'); - openPassportHelper(passportUrl); - onPassportUrlOpen(); - - } else - logError("Cannot open passport"); - } - - - static function openPassportHelper(url:String):Void { - var window = "_blank"; - - #if flash - flash.Lib.getURL(new flash.net.URLRequest(url), window); - #elseif (js && html5) - js.Browser.window.open(url, window); - #elseif desktop - - #if (sys && windows) - Sys.command("start", ["", url]); - #elseif mac - Sys.command("/usr/bin/open", [url]); - #elseif linux - Sys.command("/usr/bin/xdg-open", [path, "&"]); - #end - - #elseif android - JNI.createStaticMethod - ( "org/haxe/lime/GameActivity" - , "openURL" - , "(Ljava/lang/String;Ljava/lang/String;)V" - ) (url, window); - #end - } - - /** - * Call this once the passport link is established and it will start checking for session connect periodically - */ - public function onPassportUrlOpen():Void { - - if (_passportCallback != null) - _passportCallback(); - - _passportCallback = null; - } - - function checkSession(response:Response, onSucceess:Void->Void, onCancel:Void->Void):Void { - - if (response != null) { - - if (!response.success || !response.result.success) { - - log("login cancelled via passport"); - - endLoginAndCall(onCancel); - return; - } - - _session.parse(response.result.data.session); - } - - if (_session.status == SessionStatus.USER_LOADED) { - - loggedIn = true; - endLoginAndCall(onSucceess); - onLogin.dispatch(); - - } else if (_session.status == SessionStatus.REQUEST_LOGIN){ - - var call = calls.app.checkSession() - .addDataHandler(checkSession.bind(_, onSucceess, onCancel)); - - // Wait 3 seconds and try again - timer(3.0, - function():Void { - - // Check if cancelLoginRequest was called - if (!_loginCancelled) - call.send(); - else { - - log("login cancelled via cancelLoginRequest"); - endLoginAndCall(onCancel); - } - } - ); - - } else - // The user cancelled the passport - endLoginAndCall(onCancel); - } - - public function cancelLoginRequest():Void { - - if (attemptingLogin) - _loginCancelled = true; - } - - function endLoginAndCall(callback:Void->Void):Void { - - attemptingLogin = false; - _loginCancelled = false; - - if (callback != null) - callback(); - } - - public function logOut(onComplete:Void->Void = null):Void { - - var call = calls.app.endSession() - .addSuccessHandler(onLogOutSuccessful); - - if (onComplete != null) - call.addSuccessHandler(onComplete); - - call.addSuccessHandler(onLogOut.dispatch) - .send(); - } - - function onLogOutSuccessful():Void { - - _session.expire(); - sessionId = null; - loggedIn = false; - } - - // ------------------------------------------------------------------------------------------- - // MEDALS - // ------------------------------------------------------------------------------------------- - - public function requestMedals(onSuccess:Void->Void = null, onFail:Error->Void = null):Void { - - var call = calls.medal.getList() - .addDataHandler(onMedalsReceived); - - if (onSuccess != null) - call.addSuccessHandler(onSuccess); - - if (onFail != null) - call.addErrorHandler(onFail); - - call.send(); - } - - function onMedalsReceived(response:Response):Void { - - if (!response.success || !response.result.success) - return; - - var idList:Array = new Array(); - - if (medals == null) { - - medals = new IntMap(); - - for (medalData in response.result.data.medals) { - - var medal = new Medal(this, medalData); - medals.set(medal.id, medal); - idList.push(medal.id); - } - } else { - - for (medalData in response.result.data.medals) { - - medals.get(medalData.id).parse(medalData); - idList.push(medalData.id); - } - } - - logVerbose('${response.result.data.medals.length} Medals received [${idList.join(", ")}]'); - - onMedalsLoaded.dispatch(); - } - - // ------------------------------------------------------------------------------------------- - // SCOREBOARDS - // ------------------------------------------------------------------------------------------- - - public function requestScoreBoards(onSuccess:Void->Void = null, onFail:Error->Void = null):Void { - - if (scoreBoards != null) { - - log("aborting scoreboard request, all scoreboards are loaded"); - - if (onSuccess != null) - onSuccess(); - - return; - } - - var call = calls.scoreBoard.getBoards() - .addDataHandler(onBoardsReceived); - - if (onSuccess != null) - call.addSuccessHandler(onSuccess); - - if (onFail != null) - call.addErrorHandler(onFail); - - call.send(); - } - - function onBoardsReceived(response:Response):Void { - - if (!response.success || !response.result.success) - return; - - var idList:Array = new Array(); - - if (scoreBoards == null) { - - scoreBoards = new IntMap(); - - for (boardData in response.result.data.scoreboards) { - - var board = new ScoreBoard(this, boardData); - scoreBoards.set(board.id, board); - idList.push(board.id); - } - } - - logVerbose('${response.result.data.scoreboards.length} ScoreBoards received [${idList.join(", ")}]'); - - onScoreBoardsLoaded.dispatch(); - } - - // ------------------------------------------------------------------------------------------- - // HELPERS - // ------------------------------------------------------------------------------------------- - - function timer(delay:Float, callback:Void->Void):Void { - - var timer = new Timer(Std.int(delay * 1000)); - timer.run = function func():Void { - - timer.stop(); - callback(); - } - } - - static var urlParser:EReg = ~/^(?:http[s]?:\/\/)?([^:\/\s]+)(:[0-9]+)?((?:\/\w+)*\/)([\w\-\.]+[^#?\s]+)([^#\s]*)?(#[\w\-]+)?$/i;//TODO:trim - /** Used to get the current web host of your game. */ - static public function getHost():String { - - var url = NGLite.getUrl(); - - if (url == null || url == "") - return ""; - - if (url.indexOf("file") == 0) - return ""; - - if (urlParser.match(url)) - return urlParser.matched(1); - - return ""; - } -} -#end \ No newline at end of file diff --git a/source/io/newgrounds/NGLite.hx b/source/io/newgrounds/NGLite.hx deleted file mode 100644 index 0c9d5bdf5..000000000 --- a/source/io/newgrounds/NGLite.hx +++ /dev/null @@ -1,287 +0,0 @@ -package io.newgrounds; - -import haxe.crypto.Base64; -import haxe.io.Bytes; -import haxe.PosInfos; - -import io.newgrounds.Call.ICallable; -import io.newgrounds.components.ComponentList; -import io.newgrounds.crypto.EncryptionFormat; -import io.newgrounds.crypto.Cipher; -import io.newgrounds.crypto.Rc4; -import io.newgrounds.objects.Error; -import io.newgrounds.objects.events.Response; -import io.newgrounds.objects.events.Result.ResultBase; -import io.newgrounds.objects.events.Result.SessionResult; -import io.newgrounds.utils.Dispatcher; - -#if !(html5 || flash || desktop || neko) - #error "Target not supported, use: Flash, JS/HTML5, cpp or maybe neko"; -#end - -/** - * The barebones NG.io API. Allows API calls with code completion - * and retrieves server data via strongly typed Objects - * - * Contains many things ripped from MSGhero's repo - * - https://github.com/MSGhero/NG.hx - * - * @author GeoKureli - */ -class NGLite { - - static public var core(default, null):NGLite; - static public var onCoreReady(default, null):Dispatcher = new Dispatcher(); - - /** Enables verbose logging */ - public var verbose:Bool; - public var debug:Bool; - /** The unique ID of your app as found in the 'API Tools' tab of your Newgrounds.com project. */ - public var appId(default, null):String; - /** The name of the host the game is being played on */ - public var host:String; - - @:isVar - public var sessionId(default, set):String; - function set_sessionId(value:String):String { - - return this.sessionId = value == "" ? null : value; - } - - /** Components used to call the NG server directly */ - public var calls(default, null):ComponentList; - - /** - * Converts an object to an encrypted string that can be decrypted by the server. - * Set your preffered encrypter here, - * or just call setDefaultEcryptionHandler with your app's encryption settings - **/ - public var encryptionHandler:String->String; - - /** - * Iniitializes the API, call before utilizing any other component - * @param appId The unique ID of your app as found in the 'API Tools' tab of your Newgrounds.com project. - * @param sessionId A unique session id used to identify the active user. - **/ - public function new(appId = "test", sessionId:String = null, ?onSessionFail:Error->Void) { - - this.appId = appId; - this.sessionId = sessionId; - - calls = new ComponentList(this); - - if (this.sessionId != null) { - - calls.app.checkSession() - .addDataHandler(checkInitialSession.bind(onSessionFail)) - .addErrorHandler(initialSessionFail.bind(onSessionFail)) - .send(); - } - } - - function checkInitialSession(onFail:Error->Void, response:Response):Void { - - if (!response.success || !response.result.success || response.result.data.session.expired) { - - initialSessionFail(onFail, response.success ? response.result.error : response.error); - } - } - - function initialSessionFail(onFail:Error->Void, error:Error):Void { - - sessionId = null; - - if (onFail != null) - onFail(error); - } - - /** - * Creates NG.core, the heart and soul of the API. This is not the only way to create an instance, - * nor is NG a forced singleton, but it's the only way to set the static NG.core. - **/ - static public function create(appId = "test", sessionId:String = null, ?onSessionFail:Error->Void):Void { - - core = new NGLite(appId, sessionId, onSessionFail); - - onCoreReady.dispatch(); - } - - /** - * Creates NG.core, and tries to create a session. This is not the only way to create an instance, - * nor is NG a forced singleton, but it's the only way to set the static NG.core. - **/ - static public function createAndCheckSession - ( appId = "test" - , backupSession:String = null - , ?onSessionFail:Error->Void - ):Void { - - var session = getSessionId(); - if (session == null) - session = backupSession; - - create(appId, session, onSessionFail); - } - - inline static public function getUrl():String { - - #if html5 - return js.Browser.document.location.href; - #elseif flash - return flash.Lib.current.stage.loaderInfo != null - ? flash.Lib.current.stage.loaderInfo.url - : null; - #else - return null; - #end - } - - static public function getSessionId():String { - - #if html5 - - var url = getUrl(); - - // Check for URL params - var index = url.indexOf("?"); - if (index != -1) { - - // Check for session ID in params - for (param in url.substr(index + 1).split("&")) { - - index = param.indexOf("="); - if (index != -1 && param.substr(0, index) == "ngio_session_id") - return param.substr(index + 1); - } - } - - #elseif flash - - if (flash.Lib.current.stage.loaderInfo != null - && Reflect.hasField(flash.Lib.current.stage.loaderInfo.parameters, "ngio_session_id")) - return Reflect.field(flash.Lib.current.stage.loaderInfo.parameters, "ngio_session_id"); - - #end - - return null; - - // --- EXAMPLE LOADER PARAMS - //{ "1517703669" : "" - //, "ng_username" : "GeoKureli" - //, "NewgroundsAPI_SessionID" : "F1LusbG6P8Qf91w7zeUE37c1752563f366688ac6153996d12eeb111a2f60w2xn" - //, "NewgroundsAPI_PublisherID" : 1 - //, "NewgroundsAPI_UserID" : 488329 - //, "NewgroundsAPI_SandboxID" : "5a76520e4ae1e" - //, "ngio_session_id" : "0c6c4e02567a5116734ba1a0cd841dac28a42e79302290" - //, "NewgroundsAPI_UserName" : "GeoKureli" - //} - } - - // ------------------------------------------------------------------------------------------- - // CALLS - // ------------------------------------------------------------------------------------------- - - var _queuedCalls:Array = new Array(); - var _pendingCalls:Array = new Array(); - - @:allow(io.newgrounds.Call) - @:generic - function queueCall(call:Call):Void { - - logVerbose('queued - ${call.component}'); - - _queuedCalls.push(call); - checkQueue(); - } - - @:allow(io.newgrounds.Call) - @:generic - function markCallPending(call:Call):Void { - - _pendingCalls.push(call); - - call.addDataHandler(function (_):Void { onCallComplete(call); }); - call.addErrorHandler(function (_):Void { onCallComplete(call); }); - } - - function onCallComplete(call:ICallable):Void { - - _pendingCalls.remove(call); - checkQueue(); - } - - function checkQueue():Void { - - if (_pendingCalls.length == 0 && _queuedCalls.length > 0) - _queuedCalls.shift().send(); - } - - // ------------------------------------------------------------------------------------------- - // LOGGING / ERRORS - // ------------------------------------------------------------------------------------------- - - /** Called internally, set this to your preferred logging method */ - dynamic public function log(any:Dynamic, ?pos:PosInfos):Void {//TODO: limit access via @:allow - - haxe.Log.trace('[Newgrounds API] :: ${any}', pos); - } - - /** used internally, logs if verbose is true */ - inline public function logVerbose(any:Dynamic, ?pos:PosInfos):Void {//TODO: limit access via @:allow - - if (verbose) - log(any, pos); - } - - /** Used internally. Logs by default, set this to your preferred error handling method */ - dynamic public function logError(any:Dynamic, ?pos:PosInfos):Void {//TODO: limit access via @:allow - - log('Error: $any', pos); - } - - /** used internally, calls log error if the condition is false. EX: if (assert(data != null, "null data")) */ - inline public function assert(condition:Bool, msg:Dynamic, ?pos:PosInfos):Bool {//TODO: limit access via @:allow - if (!condition) - logError(msg, pos); - - return condition; - } - - // ------------------------------------------------------------------------------------------- - // ENCRYPTION - // ------------------------------------------------------------------------------------------- - - /** Sets */ - public function initEncryption - ( key :String - , cipher:Cipher = Cipher.RC4 - , format:EncryptionFormat = EncryptionFormat.BASE_64 - ):Void { - - if (cipher == Cipher.NONE) - encryptionHandler = null; - else if (cipher == Cipher.RC4) - encryptionHandler = encryptRc4.bind(key, format); - else - throw "aes not yet implemented"; - } - - function encryptRc4(key:String, format:EncryptionFormat, data:String):String { - - if (format == EncryptionFormat.HEX) - throw "hex format not yet implemented"; - - var keyBytes:Bytes; - if (format == EncryptionFormat.BASE_64) - keyBytes = Base64.decode(key); - else - keyBytes = null;//TODO - - var dataBytes = new Rc4(keyBytes).crypt(Bytes.ofString(data)); - - if (format == EncryptionFormat.BASE_64) - return Base64.encode(dataBytes); - - return null; - } -} \ No newline at end of file diff --git a/source/io/newgrounds/components/AppComponent.hx b/source/io/newgrounds/components/AppComponent.hx deleted file mode 100644 index 1ea5b8b16..000000000 --- a/source/io/newgrounds/components/AppComponent.hx +++ /dev/null @@ -1,44 +0,0 @@ -package io.newgrounds.components; - -import io.newgrounds.objects.events.Result; -import io.newgrounds.objects.events.Result.SessionResult; -import io.newgrounds.NGLite; - -class AppComponent extends Component { - - public function new (core:NGLite) { super(core); } - - public function startSession(force:Bool = false):Call { - - return new Call(_core, "App.startSession") - .addComponentParameter("force", force, false); - } - - public function checkSession():Call { - - return new Call(_core, "App.checkSession", true); - } - - public function endSession():Call { - - return new Call(_core, "App.endSession", true); - } - - public function getCurrentVersion(version:String):Call { - - return new Call(_core, "App.getCurrentVersion") - .addComponentParameter("version", version); - } - - public function getHostLicense():Call { - - return new Call(_core, "App.getHostLicense") - .addComponentParameter("host", _core.host); - } - - public function logView():Call { - - return new Call(_core, "App.logView") - .addComponentParameter("host", _core.host); - } -} \ No newline at end of file diff --git a/source/io/newgrounds/components/Component.hx b/source/io/newgrounds/components/Component.hx deleted file mode 100644 index 3c588ff19..000000000 --- a/source/io/newgrounds/components/Component.hx +++ /dev/null @@ -1,13 +0,0 @@ -package io.newgrounds.components; - -import io.newgrounds.NGLite; - -class Component { - - var _core:NGLite; - - public function new(core:NGLite) { - - this._core = core; - } -} \ No newline at end of file diff --git a/source/io/newgrounds/components/ComponentList.hx b/source/io/newgrounds/components/ComponentList.hx deleted file mode 100644 index 315abf4ed..000000000 --- a/source/io/newgrounds/components/ComponentList.hx +++ /dev/null @@ -1,25 +0,0 @@ -package io.newgrounds.components; -class ComponentList { - - var _core:NGLite; - - // --- COMPONENTS - public var medal : MedalComponent; - public var app : AppComponent; - public var event : EventComponent; - public var scoreBoard: ScoreBoardComponent; - public var loader : LoaderComponent; - public var gateway : GatewayComponent; - - public function new(core:NGLite) { - - _core = core; - - medal = new MedalComponent (_core); - app = new AppComponent (_core); - event = new EventComponent (_core); - scoreBoard = new ScoreBoardComponent(_core); - loader = new LoaderComponent (_core); - gateway = new GatewayComponent (_core); - } -} diff --git a/source/io/newgrounds/components/EventComponent.hx b/source/io/newgrounds/components/EventComponent.hx deleted file mode 100644 index 2e631773e..000000000 --- a/source/io/newgrounds/components/EventComponent.hx +++ /dev/null @@ -1,16 +0,0 @@ -package io.newgrounds.components; - -import io.newgrounds.objects.events.Result.LogEventResult; -import io.newgrounds.NGLite; - -class EventComponent extends Component { - - public function new (core:NGLite){ super(core); } - - public function logEvent(eventName:String):Call { - - return new Call(_core, "Event.logEvent") - .addComponentParameter("event_name", eventName) - .addComponentParameter("host", _core.host); - } -} \ No newline at end of file diff --git a/source/io/newgrounds/components/GatewayComponent.hx b/source/io/newgrounds/components/GatewayComponent.hx deleted file mode 100644 index 4f0ece617..000000000 --- a/source/io/newgrounds/components/GatewayComponent.hx +++ /dev/null @@ -1,25 +0,0 @@ -package io.newgrounds.components; - -import io.newgrounds.objects.events.Result; -import io.newgrounds.NGLite; - -class GatewayComponent extends Component { - - public function new (core:NGLite){ super(core); } - - public function getDatetime():Call { - - return new Call(_core, "Gateway.getDatetime"); - } - - public function getVersion():Call { - - return new Call(_core, "Gateway.getVersion"); - } - - public function ping():Call { - - return new Call(_core, "Gateway.ping"); - } - -} \ No newline at end of file diff --git a/source/io/newgrounds/components/LoaderComponent.hx b/source/io/newgrounds/components/LoaderComponent.hx deleted file mode 100644 index 717cc2eb2..000000000 --- a/source/io/newgrounds/components/LoaderComponent.hx +++ /dev/null @@ -1,44 +0,0 @@ -package io.newgrounds.components; - -import io.newgrounds.objects.events.Result; -import io.newgrounds.NGLite; - -class LoaderComponent extends Component { - - public function new (core:NGLite){ super(core); } - - public function loadAuthorUrl(redirect:Bool = false):Call { - - return new Call(_core, "Loader.loadAuthorUrl") - .addComponentParameter("host", _core.host) - .addComponentParameter("redirect", redirect, true); - } - - public function loadMoreGames(redirect:Bool = false):Call { - - return new Call(_core, "Loader.loadMoreGames") - .addComponentParameter("host", _core.host) - .addComponentParameter("redirect", redirect, true); - } - - public function loadNewgrounds(redirect:Bool = false):Call { - - return new Call(_core, "Loader.loadNewgrounds") - .addComponentParameter("host", _core.host) - .addComponentParameter("redirect", redirect, true); - } - - public function loadOfficialUrl(redirect:Bool = false):Call { - - return new Call(_core, "Loader.loadOfficialUrl") - .addComponentParameter("host", _core.host) - .addComponentParameter("redirect", redirect, true); - } - - public function loadReferral(redirect:Bool = false):Call { - - return new Call(_core, "Loader.loadReferral") - .addComponentParameter("host", _core.host) - .addComponentParameter("redirect", redirect, true); - } -} \ No newline at end of file diff --git a/source/io/newgrounds/components/MedalComponent.hx b/source/io/newgrounds/components/MedalComponent.hx deleted file mode 100644 index 7e56621c4..000000000 --- a/source/io/newgrounds/components/MedalComponent.hx +++ /dev/null @@ -1,21 +0,0 @@ -package io.newgrounds.components; - -import io.newgrounds.objects.events.Result; -import io.newgrounds.Call; -import io.newgrounds.NGLite; - -class MedalComponent extends Component { - - public function new(core:NGLite):Void { super(core); } - - public function unlock(id:Int):Call { - - return new Call(_core, "Medal.unlock", true, true) - .addComponentParameter("id", id); - } - - public function getList():Call { - - return new Call(_core, "Medal.getList"); - } -} \ No newline at end of file diff --git a/source/io/newgrounds/components/ScoreBoardComponent.hx b/source/io/newgrounds/components/ScoreBoardComponent.hx deleted file mode 100644 index 7417e67c6..000000000 --- a/source/io/newgrounds/components/ScoreBoardComponent.hx +++ /dev/null @@ -1,114 +0,0 @@ -package io.newgrounds.components; - -import io.newgrounds.objects.User; -import io.newgrounds.objects.events.Response; -import io.newgrounds.objects.events.Result; -import io.newgrounds.objects.events.Result.ScoreBoardResult; -import io.newgrounds.objects.events.Result.ScoreResult; -import io.newgrounds.NGLite; -import io.newgrounds.objects.ScoreBoard; - -import haxe.ds.IntMap; - -class ScoreBoardComponent extends Component { - - public var allById:IntMap; - - public function new (core:NGLite){ super(core); } - - // ------------------------------------------------------------------------------------------- - // GET SCORES - // ------------------------------------------------------------------------------------------- - - public function getBoards():Call { - - return new Call(_core, "ScoreBoard.getBoards"); - } - - /*function onBoardsReceive(response:Response):Void { - - if (!response.result.success) - return; - - allById = new IntMap(); - - for (boardData in response.result.scoreboards) - createBoard(boardData); - - _core.log('${response.result.scoreboards.length} ScoreBoards loaded'); - }*/ - - // ------------------------------------------------------------------------------------------- - // GET SCORES - // ------------------------------------------------------------------------------------------- - - public function getScores - ( id :Int - , limit :Int = 10 - , skip :Int = 0 - , period:Period = Period.DAY - , social:Bool = false - , tag :String = null - , user :Dynamic = null - ):Call { - - if (user != null && !Std.is(user, String) && !Std.is(user, Int)) - user = user.id; - - return new Call(_core, "ScoreBoard.getScores") - .addComponentParameter("id" , id ) - .addComponentParameter("limit" , limit , 10) - .addComponentParameter("skip" , skip , 0) - .addComponentParameter("period", period, Period.DAY) - .addComponentParameter("social", social, false) - .addComponentParameter("tag" , tag , null) - .addComponentParameter("user" , user , null); - } - - // ------------------------------------------------------------------------------------------- - // POST SCORE - // ------------------------------------------------------------------------------------------- - - public function postScore(id:Int, value:Int, tag:String = null):Call { - - return new Call(_core, "ScoreBoard.postScore", true, true) - .addComponentParameter("id" , id) - .addComponentParameter("value", value) - .addComponentParameter("tag" , tag , null); - } - - /*function onScorePosted(response:Response):Void { - - if (!response.result.success) - return; - - allById = new IntMap(); - - //createBoard(data.data.scoreBoard).parseScores(data.data.scores); - }*/ - - inline function createBoard(data:Dynamic):ScoreBoard { - - var board = new ScoreBoard(_core, data); - _core.logVerbose('created $board'); - - allById.set(board.id, board); - - return board; - } -} - -@:enum -abstract Period(String) to String from String{ - - /** Indicates scores are from the current day. */ - var DAY = "D"; - /** Indicates scores are from the current week. */ - var WEEK = "W"; - /** Indicates scores are from the current month. */ - var MONTH = "M"; - /** Indicates scores are from the current year. */ - var YEAR = "Y"; - /** Indicates scores are from all-time. */ - var ALL = "A"; -} \ No newline at end of file diff --git a/source/io/newgrounds/crypto/Cipher.hx b/source/io/newgrounds/crypto/Cipher.hx deleted file mode 100644 index 2f4c00753..000000000 --- a/source/io/newgrounds/crypto/Cipher.hx +++ /dev/null @@ -1,8 +0,0 @@ -package io.newgrounds.crypto; - -@:enum -abstract Cipher(String) to String{ - var NONE = "none"; - var AES_128 = "aes128"; - var RC4 = "rc4"; -} \ No newline at end of file diff --git a/source/io/newgrounds/crypto/EncryptionFormat.hx b/source/io/newgrounds/crypto/EncryptionFormat.hx deleted file mode 100644 index 6e8f17fd6..000000000 --- a/source/io/newgrounds/crypto/EncryptionFormat.hx +++ /dev/null @@ -1,7 +0,0 @@ -package io.newgrounds.crypto; - -@:enum -abstract EncryptionFormat(String) to String { - var BASE_64 = "base64"; - var HEX = "hex"; -} \ No newline at end of file diff --git a/source/io/newgrounds/crypto/Rc4.hx b/source/io/newgrounds/crypto/Rc4.hx deleted file mode 100644 index 54dafa74b..000000000 --- a/source/io/newgrounds/crypto/Rc4.hx +++ /dev/null @@ -1,68 +0,0 @@ -package io.newgrounds.crypto; - -import haxe.io.Bytes; - -/** - * The following was straight-up ganked from https://github.com/iskolbin/rc4hx - * - * You da real MVP iskolbin... - * - * The MIT License (MIT) - * - * Copyright (c) 2015 iskolbin - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. -**/ -class Rc4 { - var perm = Bytes.alloc( 256 ); - var index1: Int = 0; - var index2: Int = 0; - - public function new( key: Bytes ) { - for ( i in 0...256 ) { - perm.set( i, i ); - } - - var j: Int = 0; - for ( i in 0...256 ) { - j = ( j + perm.get( i ) + key.get( i % key.length )) % 256; - swap( i, j ); - } - } - - inline function swap( i: Int, j: Int ): Void { - var temp = perm.get( i ); - perm.set( i, perm.get( j )); - perm.set( j, temp ); - } - - public function crypt( input: Bytes ): Bytes { - var output = Bytes.alloc( input.length ); - - for ( i in 0...input.length ) { - index1 = ( index1 + 1 ) % 256; - index2 = ( index2 + perm.get( index1 )) % 256; - swap( index1, index2 ); - var j = ( perm.get( index1 ) + perm.get( index2 )) % 256; - output.set( i, input.get( i ) ^ perm.get( j )); - } - - return output; - } -} \ No newline at end of file diff --git a/source/io/newgrounds/objects/Error.hx b/source/io/newgrounds/objects/Error.hx deleted file mode 100644 index 6e82e4e2e..000000000 --- a/source/io/newgrounds/objects/Error.hx +++ /dev/null @@ -1,20 +0,0 @@ -package io.newgrounds.objects; -class Error { - - public var code(default, null):Int; - public var message(default, null):String; - - public function new (message:String, code:Int = 0) { - - this.message = message; - this.code = code; - } - - public function toString():String { - - if (code > 0) - return '#$code - $message'; - - return message; - } -} diff --git a/source/io/newgrounds/objects/Medal.hx b/source/io/newgrounds/objects/Medal.hx deleted file mode 100644 index 3cecc7a6b..000000000 --- a/source/io/newgrounds/objects/Medal.hx +++ /dev/null @@ -1,118 +0,0 @@ -package io.newgrounds.objects; - -import io.newgrounds.objects.events.Response; -import io.newgrounds.objects.events.Result.MedalUnlockResult; -import io.newgrounds.utils.Dispatcher; -import io.newgrounds.NGLite; - -class Medal extends Object { - - inline static public var EASY :Int = 1; - inline static public var MODERATE :Int = 2; - inline static public var CHALLENGING:Int = 3; - inline static public var DIFFICULT :Int = 4; - inline static public var BRUTAL :Int = 5; - - static var difficultyNames:Array = - [ "Easy" - , "Moderate" - , "Challenging" - , "Difficult" - , "Brutal" - ]; - // --- FROM SERVER - public var id (default, null):Int; - public var name (default, null):String; - public var description(default, null):String; - public var icon (default, null):String; - public var value (default, null):Int; - public var difficulty (default, null):Int; - public var secret (default, null):Bool; - public var unlocked (default, null):Bool; - // --- HELPERS - public var difficultyName(get, never):String; - - public var onUnlock:Dispatcher; - - public function new(core:NGLite, data:Dynamic = null):Void { - - onUnlock = new Dispatcher(); - - super(core, data); - } - - @:allow(io.newgrounds.NG) - override function parse(data:Dynamic):Void { - - var wasLocked = !unlocked; - - id = data.id; - name = data.name; - description = data.description; - icon = data.icon; - value = data.value; - difficulty = data.difficulty; - secret = data.secret == 1; - unlocked = data.unlocked; - - super.parse(data); - - if (wasLocked && unlocked) - onUnlock.dispatch(); - - } - - public function sendUnlock():Void { - - if (_core.sessionId == null) { - // --- Unlock regardless, show medal popup to encourage NG signup - unlocked = true; - onUnlock.dispatch(); - //TODO: save unlock in local save - } - - _core.calls.medal.unlock(id) - .addDataHandler(onUnlockResponse) - .send(); - } - - function onUnlockResponse(response:Response):Void { - - if (response.success && response.result.success) { - - parse(response.result.data.medal); - - // --- Unlock response doesn't include unlock=true, so parse won't change it. - if (!unlocked) { - - unlocked = true; - onUnlock.dispatch(); - } - } - } - - /** Locks the medal on the client and sends an unlock request, Server responds the same either way. */ - public function sendDebugUnlock():Void { - - if (NG.core.sessionId == null) { - - onUnlock.dispatch(); - - } else { - - unlocked = false; - - sendUnlock(); - } - } - - public function get_difficultyName():String { - - return difficultyNames[difficulty - 1]; - } - - public function toString():String { - - return 'Medal: $id@$name (${unlocked ? "unlocked" : "locked"}, $value pts, $difficultyName).'; - } -} \ No newline at end of file diff --git a/source/io/newgrounds/objects/Object.hx b/source/io/newgrounds/objects/Object.hx deleted file mode 100644 index 32abd0fe5..000000000 --- a/source/io/newgrounds/objects/Object.hx +++ /dev/null @@ -1,33 +0,0 @@ -package io.newgrounds.objects; - -import io.newgrounds.utils.Dispatcher; -import io.newgrounds.NGLite; - -class Object { - - var _core:NGLite; - - public var onUpdate(default, null):Dispatcher; - - public function new(core:NGLite, data:Dynamic = null) { - - this._core = core; - - onUpdate = new Dispatcher(); - - if (data != null) - parse(data); - } - - @:allow(io.newgrounds.NGLite) - function parse(data:Dynamic):Void { - - onUpdate.dispatch(); - } - - - public function destroy():Void { - - _core = null; - } -} \ No newline at end of file diff --git a/source/io/newgrounds/objects/Score.hx b/source/io/newgrounds/objects/Score.hx deleted file mode 100644 index 0eb698267..000000000 --- a/source/io/newgrounds/objects/Score.hx +++ /dev/null @@ -1,17 +0,0 @@ -package io.newgrounds.objects; - -/** We don't want to serialize scores since there's a bajillion of them. */ -typedef Score = { - - /** The value value in the format selected in your scoreboard settings. */ - var formatted_value:String; - - /** The tag attached to this value (if any). */ - var tag:String; - - /** The user who earned value. If this property is absent, the value belongs to the active user. */ - var user:User; - - /** The integer value of the value. */ - var value:Int; -} \ No newline at end of file diff --git a/source/io/newgrounds/objects/ScoreBoard.hx b/source/io/newgrounds/objects/ScoreBoard.hx deleted file mode 100644 index 1859b0808..000000000 --- a/source/io/newgrounds/objects/ScoreBoard.hx +++ /dev/null @@ -1,76 +0,0 @@ -package io.newgrounds.objects; - -import io.newgrounds.components.ScoreBoardComponent.Period; -import io.newgrounds.objects.events.Response; -import io.newgrounds.objects.events.Result; -import io.newgrounds.objects.events.Result.ScoreResult; -import io.newgrounds.NGLite; - -class ScoreBoard extends Object { - - public var scores(default, null):Array; - - /** The numeric ID of the scoreboard.*/ - public var id(default, null):Int; - - /** The name of the scoreboard. */ - public var name(default, null):String; - - public function new(core:NGLite, data:Dynamic):Void {super(core, data); } - - override function parse(data:Dynamic):Void { - - id = data.id; - name = data.name; - - super.parse(data); - } - - /** - * Fetches score data from the server, this removes all of the existing scores cached - * - * We don't unify the old and new scores because a user's rank or score may change between requests - */ - public function requestScores - ( limit :Int = 10 - , skip :Int = 0 - , period:Period = Period.ALL - , social:Bool = false - , tag :String = null - , user :Dynamic = null - ):Void { - - _core.calls.scoreBoard.getScores(id, limit, skip, period, social, tag, user) - .addDataHandler(onScoresReceived) - .send(); - } - - function onScoresReceived(response:Response):Void { - - if (!response.success || !response.result.success) - return; - - scores = response.result.data.scores; - _core.logVerbose('received ${scores.length} scores'); - - onUpdate.dispatch(); - } - - public function postScore(value :Int, tag:String = null):Void { - - _core.calls.scoreBoard.postScore(id, value, tag) - .addDataHandler(onScorePosted) - .send(); - } - - function onScorePosted(response:Response):Void { - - - } - - public function toString():String { - - return 'ScoreBoard: $id@$name'; - } - -} \ No newline at end of file diff --git a/source/io/newgrounds/objects/Session.hx b/source/io/newgrounds/objects/Session.hx deleted file mode 100644 index 887df7927..000000000 --- a/source/io/newgrounds/objects/Session.hx +++ /dev/null @@ -1,65 +0,0 @@ -package io.newgrounds.objects; - -class Session extends Object { - - /** If true, the session_id is expired. Use App.startSession to get a new one.*/ - public var expired(default, null):Bool; - - /** A unique session identifier */ - public var id(default, null):String; - - /** If the session has no associated user but is not expired, this property will provide a URL that can be used to sign the user in. */ - public var passportUrl(default, null):String; - - /** If true, the user would like you to remember their session id. */ - public var remember(default, null):Bool; - - /** If the user has not signed in, or granted access to your app, this will be null */ - public var user(default, null):User; - - //TODO:desciption - public var status(get, never):SessionStatus; - - public function new(core:NGLite, data:Dynamic = null) { super(core, data); } - - override public function parse(data:Dynamic):Void { - - id = data.id; - expired = data.expired; - passportUrl = data.passport_url; - remember = data.remember; - - // --- KEEP THE SAME INSTANCE - if (user == null) - user = data.user; - // TODO?: update original user instance with new data. (probly not) - - super.parse(data); - } - - public function get_status():SessionStatus { - - if (expired || id == null || id == "") - return SessionStatus.SESSION_EXPIRED; - - if (user != null && user.name != null && user.name != "") - return SessionStatus.USER_LOADED; - - return SessionStatus.REQUEST_LOGIN; - } - - public function expire():Void { - - expired = true; - id = null; - user = null; - } -} - -@:enum -abstract SessionStatus(String) { - - var SESSION_EXPIRED = "session-expired"; - var REQUEST_LOGIN = "request-login"; - var USER_LOADED = "user-loaded"; -} \ No newline at end of file diff --git a/source/io/newgrounds/objects/User.hx b/source/io/newgrounds/objects/User.hx deleted file mode 100644 index 1ff7ce00c..000000000 --- a/source/io/newgrounds/objects/User.hx +++ /dev/null @@ -1,19 +0,0 @@ -package io.newgrounds.objects; - -typedef User = { - - /** The user's icon images. */ - var icons:UserIcons; - - /** The user's numeric ID. */ - var id:Int; - - /** The user's textual name. */ - var name:String; - - /** Returns true if the user has a Newgrounds Supporter upgrade. */ - var supporter:Bool; - - /** The user's NG profile url. */ - var url:String; -} diff --git a/source/io/newgrounds/objects/UserIcons.hx b/source/io/newgrounds/objects/UserIcons.hx deleted file mode 100644 index b5e56b22a..000000000 --- a/source/io/newgrounds/objects/UserIcons.hx +++ /dev/null @@ -1,14 +0,0 @@ -package io.newgrounds.objects; - -typedef UserIcons = { - - /**The URL of the user's large icon. */ - var large:String; - - /** The URL of the user's medium icon. */ - var medium:String; - - /** The URL of the user's small icon. */ - var small:String; -} - diff --git a/source/io/newgrounds/objects/events/Response.hx b/source/io/newgrounds/objects/events/Response.hx deleted file mode 100644 index 107dc2be3..000000000 --- a/source/io/newgrounds/objects/events/Response.hx +++ /dev/null @@ -1,43 +0,0 @@ -package io.newgrounds.objects.events; - -import io.newgrounds.objects.events.Result.ResultBase; -import haxe.Json; -import io.newgrounds.objects.Error; - -typedef DebugResponse = { - - var exec_time:Int; - var input:Dynamic; -} - -class Response { - - public var success(default, null):Bool; - public var error(default, null):Error; - public var debug(default, null):DebugResponse; - public var result(default, null):Result; - - public function new (core:NGLite, reply:String) { - - var data:Dynamic; - - try { - data = Json.parse(reply); - - } catch (e:Dynamic) { - - data = Json.parse('{"success":false,"error":{"message":"${Std.string(reply)}","code":0}}'); - } - - success = data.success; - debug = data.debug; - - if (!success) { - error = new Error(data.error.message, data.error.code); - core.logError('Call unseccessful: $error'); - return; - } - - result = new Result(core, data.result); - } -} diff --git a/source/io/newgrounds/objects/events/Result.hx b/source/io/newgrounds/objects/events/Result.hx deleted file mode 100644 index eaf872616..000000000 --- a/source/io/newgrounds/objects/events/Result.hx +++ /dev/null @@ -1,109 +0,0 @@ -package io.newgrounds.objects.events; - -class Result { - - public var echo(default, null):String; - public var component(default, null):String; - - public var data(default, null):T; - public var success(default, null):Bool; - public var debug(default, null):Bool; - public var error(default, null):Error; - - public function new(core:NGLite, data:Dynamic) { - - echo = data.echo; - component = data.component; - - data = data.data; - success = data.success; - debug = data.debug; - - if(!data.success) { - - error = new Error(data.error.message, data.error.code); - core.logError('$component fail: $error'); - - } else - this.data = data; - } -} - -typedef ResultBase = { }; - -typedef SessionResult = { - > ResultBase, - - var session:Dynamic; -} - -typedef GetHostResult = { - > ResultBase, - - var host_approved:Bool; -} - -typedef GetCurrentVersionResult = { - > ResultBase, - - var current_version:String; - var client_deprecated:Bool; -} - -typedef LogEventResult = { - > ResultBase, - - var event_name:String; -} - -typedef GetDateTimeResult = { - > ResultBase, - - var datetime:String; -} - -typedef GetVersionResult = { - > ResultBase, - - var version:String; -} - -typedef PingResult = { - > ResultBase, - - var pong:String; -} - -typedef MedalListResult = { - > ResultBase, - - var medals:Array; -} - -typedef MedalUnlockResult = { - > ResultBase, - - var medal_score:String; - var medal:Dynamic; -} - -typedef ScoreBoardResult = { - > ResultBase, - - var scoreboards:Array; -} - -typedef ScoreResult = { - > ResultBase, - - var scores:Array; - var scoreboard:Dynamic; -} - -typedef PostScoreResult = { - > ResultBase, - - var tag:String; - var scoreboard:Dynamic; - var score:Score; -} \ No newline at end of file diff --git a/source/io/newgrounds/swf/LoadingBar.hx b/source/io/newgrounds/swf/LoadingBar.hx deleted file mode 100644 index 9c7c590a8..000000000 --- a/source/io/newgrounds/swf/LoadingBar.hx +++ /dev/null @@ -1,23 +0,0 @@ -package io.newgrounds.swf; - -import openfl.display.MovieClip; - -class LoadingBar extends MovieClip { - - public var bar(default, null):MovieClip; - - public function new() { - super(); - - setProgress(0.0); - } - - /** - * - * @param value The ratio of bytes loaded to bytes total - */ - public function setProgress(value:Float):Void { - - bar.gotoAndStop(1 + Std.int(value * (bar.totalFrames - 1))); - } -} diff --git a/source/io/newgrounds/swf/MedalPopup.hx b/source/io/newgrounds/swf/MedalPopup.hx deleted file mode 100644 index f55ef4266..000000000 --- a/source/io/newgrounds/swf/MedalPopup.hx +++ /dev/null @@ -1,151 +0,0 @@ -package io.newgrounds.swf; - -import io.newgrounds.swf.common.BaseAsset; -import io.newgrounds.objects.Medal; - -import openfl.text.TextFieldAutoSize; -import openfl.text.TextField; -import openfl.display.DisplayObject; -import openfl.display.Loader; -import openfl.display.MovieClip; -import openfl.net.URLRequest; -import openfl.events.Event; - -class MedalPopup extends BaseAsset { - - static inline var FRAME_HIDDEN:String = "hidden"; - static inline var FRAME_MEDAL_UNLOCKED:String = "medalUnlocked"; - static inline var FRAME_INTRO_COMPLETE:String = "introComplete"; - static inline var FRAME_UNLOCK_COMPLETE:String = "unlockComplete"; - static inline var MIN_TEXT_SIZE:Int = 12; - - public var medalIcon(default, null):MovieClip; - public var medalName(default, null):MovieClip; - public var medalPoints(default, null):MovieClip; - - public var alwaysOnTop:Bool; - #if !ng_lite - public var requiresSession:Bool; - #end - - var _animQueue = new ArrayVoid>(); - var _scrollSpeed:Float; - - public function new() { - super(); - - mouseEnabled = false; - mouseChildren = false; - - hide(); - addFrameScript(totalFrames - 1, onUnlockAnimComplete); - } - - function hide():Void { - - visible = false; - gotoAndStop(FRAME_HIDDEN); - } - - #if !ng_lite - override function onReady():Void { - super.onReady(); - - if (NG.core.medals != null) - onMedalsLoaded(); - else - NG.core.onLogin.addOnce(NG.core.requestMedals.bind(onMedalsLoaded)); - } - - function onMedalsLoaded():Void { - - for (medal in NG.core.medals) - medal.onUnlock.add(onMedalOnlock.bind(medal)); - } - - function onMedalOnlock(medal:Medal):Void { - - if (requiresSession && !NG.core.loggedIn) - return; - - var loader = new Loader(); - loader.load(new URLRequest(medal.icon)); - - playAnim(loader, medal.name, medal.value); - } - - #end - - public function playAnim(icon:DisplayObject, name:String, value:Int):Void { - - if (currentLabel == FRAME_HIDDEN) - playNextAnim(icon, name, value); - else - _animQueue.push(playNextAnim.bind(icon, name, value)); - } - - function playNextAnim(icon:DisplayObject, name:String, value:Int):Void { - - visible = true; - gotoAndPlay(FRAME_MEDAL_UNLOCKED); - - if (alwaysOnTop && parent != null) { - - parent.setChildIndex(this, parent.numChildren - 1); - } - - while(medalIcon.numChildren > 0) - medalIcon.removeChildAt(0); - - cast(medalPoints.getChildByName("field"), TextField).text = Std.string(value); - - var field:TextField = cast medalName.getChildByName("field"); - field.autoSize = TextFieldAutoSize.LEFT; - field.x = 0; - field.text = ""; - var oldWidth = medalName.width; - field.text = name; - - _scrollSpeed = 0; - if (field.width > oldWidth + 4) { - - field.x = oldWidth + 4; - initScroll(field); - } - - medalIcon.addChild(icon); - } - - function initScroll(field:TextField):Void { - //TODO: Find out why scrollrect didn't work - - var animDuration = 0; - - for (frame in currentLabels){ - - if (frame.name == FRAME_INTRO_COMPLETE ) - animDuration -= frame.frame; - else if (frame.name == FRAME_UNLOCK_COMPLETE) - animDuration += frame.frame; - } - - _scrollSpeed = (field.width + field.x + 4) / animDuration; - field.addEventListener(Event.ENTER_FRAME, updateScroll); - } - - function updateScroll(e:Event):Void{ - - if (currentLabel == FRAME_INTRO_COMPLETE) - cast (e.currentTarget, TextField).x -= _scrollSpeed; - } - - function onUnlockAnimComplete():Void { - - cast (medalName.getChildByName("field"), TextField).removeEventListener(Event.ENTER_FRAME, updateScroll); - - if (_animQueue.length == 0) - hide(); - else - (_animQueue.shift())(); - } -} diff --git a/source/io/newgrounds/swf/ScoreBrowser.hx b/source/io/newgrounds/swf/ScoreBrowser.hx deleted file mode 100644 index c4232c22b..000000000 --- a/source/io/newgrounds/swf/ScoreBrowser.hx +++ /dev/null @@ -1,250 +0,0 @@ -package io.newgrounds.swf; - -import openfl.events.Event; -import io.newgrounds.swf.common.DropDown; -import io.newgrounds.objects.Score; -import io.newgrounds.objects.events.Result.ScoreBoardResult; -import io.newgrounds.objects.events.Result.ScoreResult; -import io.newgrounds.objects.events.Response; -import io.newgrounds.swf.common.BaseAsset; -import io.newgrounds.swf.common.Button; -import io.newgrounds.components.ScoreBoardComponent.Period; - -import openfl.display.MovieClip; -import openfl.text.TextField; - -class ScoreBrowser extends BaseAsset { - - public var prevButton (default, null):MovieClip; - public var nextButton (default, null):MovieClip; - public var reloadButton (default, null):MovieClip; - public var listBox (default, null):MovieClip; - public var loadingIcon (default, null):MovieClip; - public var errorIcon (default, null):MovieClip; - public var scoreContainer(default, null):MovieClip; - public var titleField (default, null):TextField; - public var pageField (default, null):TextField; - - public var period(get, set):Period; - function get_period():Period { return _periodDropDown.value; } - function set_period(value:Period):Period { return _periodDropDown.value = value; } - - public var title(get, set):String; - function get_title():String { return titleField.text; } - function set_title(value:String):String { return titleField.text = value; } - - public var tag(default, set):String; - function set_tag(value:String):String { - - if (this.tag != value) { - - this.tag = value; - delayReload(); - } - - return value; - } - - public var social(default, set):Bool; - function set_social(value:Bool):Bool { - - if (this.social != value) { - - this.social = value; - delayReload(); - } - - return value; - } - - public var boardId(default, set):Int; - function set_boardId(value:Int):Int { - - _boardIDSet = true; - - if (this.boardId != value) { - - this.boardId = value; - delayReload(); - } - - return value; - } - - public var page(default, set):Int; - function set_page(value:Int):Int { - - if (this.page != value) { - - this.page = value; - delayReload(); - } - - return value; - } - - var _scores:Array; - var _limit:Int = 0; - var _periodDropDown:DropDown; - var _boardIDSet:Bool; - - public function new() { super(); } - - override function setDefaults():Void { - super.setDefaults(); - - boardId = -1; - _boardIDSet = false; - - scoreContainer.visible = false; - loadingIcon.visible = false; - reloadButton.visible = false; - errorIcon.visible = false; - errorIcon.addFrameScript(errorIcon.totalFrames - 1, errorIcon.stop); - - //TODO: prevent memory leaks? - new Button(prevButton, onPrevClick); - new Button(nextButton, onNextClick); - new Button(reloadButton, reload); - _periodDropDown = new DropDown(listBox, delayReload); - _periodDropDown.addItem("Current day" , Period.DAY ); - _periodDropDown.addItem("Current week" , Period.WEEK ); - _periodDropDown.addItem("Current month", Period.MONTH); - _periodDropDown.addItem("Current year" , Period.YEAR ); - _periodDropDown.addItem("All time" , Period.ALL ); - _periodDropDown.value = Period.ALL; - - _scores = new Array(); - while(true) { - - var score:MovieClip = cast scoreContainer.getChildByName('score${_scores.length}'); - if (score == null) - break; - - new Button(score); - _scores.push(score); - } - - _limit = _scores.length; - } - - override function onReady():Void { - super.onReady(); - - if (boardId == -1 && !_boardIDSet) { - - #if ng_lite - NG.core.calls.scoreBoard.getBoards() - .addDataHandler(onBoardsRecieved) - .queue(); - #else - if (NG.core.scoreBoards != null) - onBoardsLoaded(); - else - NG.core.requestScoreBoards(onBoardsLoaded); - #end - } - - reload(); - } - - #if ng_lite - function onBoardsRecieved(response:Response):Void { - - if (response.success && response.result.success) { - - for (board in response.result.data.scoreboards) { - - NG.core.log('No boardId specified defaulting to ${board.name}'); - boardId = board.id; - return; - } - } - } - #else - function onBoardsLoaded():Void { - - for (board in NG.core.scoreBoards) { - - NG.core.log('No boardId specified defaulting to ${board.name}'); - boardId = board.id; - return; - } - } - #end - - /** Used internally to avoid multiple server requests from various property changes in a small time-frame. **/ - function delayReload():Void { - - addEventListener(Event.EXIT_FRAME, onDelayComplete); - } - - function onDelayComplete(e:Event):Void { reload(); } - - public function reload():Void { - removeEventListener(Event.EXIT_FRAME, onDelayComplete); - - errorIcon.visible = false; - scoreContainer.visible = false; - pageField.text = 'page ${page + 1}'; - - if (_coreReady && boardId != -1 && _limit > 0 && period != null) { - - loadingIcon.visible = true; - - NG.core.calls.scoreBoard.getScores(boardId, _limit, _limit * page, period, social, tag) - .addDataHandler(onScoresReceive) - .send(); - } - } - - function onScoresReceive(response:Response):Void { - - loadingIcon.visible = false; - - if (response.success && response.result.success) { - - scoreContainer.visible = true; - - var i = _limit; - while(i > 0) { - i--; - - if (i < response.result.data.scores.length) - drawScore(i, response.result.data.scores[i], _scores[i]); - else - drawScore(i, null, _scores[i]); - } - - } else { - - errorIcon.visible = true; - errorIcon.gotoAndPlay(1); - reloadButton.visible = true; - } - } - - inline function drawScore(rank:Int, score:Score, asset:MovieClip):Void { - - if (score == null) - asset.visible = false; - else { - - asset.visible = true; - cast (asset.getChildByName("nameField" ), TextField).text = score.user.name; - cast (asset.getChildByName("scoreField"), TextField).text = score.formatted_value; - cast (asset.getChildByName("rankField" ), TextField).text = Std.string(rank + 1); - } - } - - function onPrevClick():Void { - - if (page > 0) - page--; - } - - function onNextClick():Void { - - page++; - } -} diff --git a/source/io/newgrounds/swf/common/BaseAsset.hx b/source/io/newgrounds/swf/common/BaseAsset.hx deleted file mode 100644 index da1f6126f..000000000 --- a/source/io/newgrounds/swf/common/BaseAsset.hx +++ /dev/null @@ -1,35 +0,0 @@ -package io.newgrounds.swf.common; - -import openfl.events.Event; -import openfl.display.MovieClip; - -class BaseAsset extends MovieClip { - - var _coreReady:Bool = false; - - public function new() { - super(); - - setDefaults(); - - if (stage != null) - onAdded(null); - else - addEventListener(Event.ADDED_TO_STAGE, onAdded); - } - - function setDefaults():Void { } - - function onAdded(e:Event):Void { - - if (NG.core != null) - onReady(); - else - NG.onCoreReady.add(onReady); - } - - function onReady():Void { - - _coreReady = true; - } -} diff --git a/source/io/newgrounds/swf/common/Button.hx b/source/io/newgrounds/swf/common/Button.hx deleted file mode 100644 index 5f4617528..000000000 --- a/source/io/newgrounds/swf/common/Button.hx +++ /dev/null @@ -1,151 +0,0 @@ -package io.newgrounds.swf.common; - -import openfl.display.Stage; -import openfl.events.Event; -import openfl.events.MouseEvent; -import openfl.display.MovieClip; - -class Button { - - var _enabled:Bool; - public var enabled(get, set):Bool; - function get_enabled():Bool { return _enabled; } - function set_enabled(value:Bool):Bool { - - if (value != _enabled) { - - _enabled = value; - updateEnabled(); - } - - return value; - } - - public var onClick:Void->Void; - public var onOver:Void->Void; - public var onOut:Void->Void; - - var _target:MovieClip; - var _down:Bool; - var _over:Bool; - var _foundLabels:Array; - - public function new(target:MovieClip, onClick:Void->Void = null, onOver:Void->Void = null, onOut:Void->Void = null) { - - _target = target; - this.onClick = onClick; - this.onOver = onOver; - this.onOut = onOut; - - _foundLabels = new Array(); - for (label in _target.currentLabels) - _foundLabels.push(label.name); - - _target.stop(); - _target.addEventListener(Event.ADDED_TO_STAGE, onAdded); - if (target.stage != null) - onAdded(null); - - enabled = true; - } - - function onAdded(e:Event):Void { - - var stage = _target.stage; - stage.addEventListener(MouseEvent.MOUSE_UP, mouseHandler); - _target.addEventListener(MouseEvent.MOUSE_OVER, mouseHandler); - _target.addEventListener(MouseEvent.MOUSE_OUT, mouseHandler); - _target.addEventListener(MouseEvent.MOUSE_DOWN, mouseHandler); - _target.addEventListener(MouseEvent.CLICK, mouseHandler); - - function selfRemoveEvent(e:Event):Void { - - _target.removeEventListener(Event.REMOVED_FROM_STAGE, selfRemoveEvent); - onRemove(e, stage); - } - _target.addEventListener(Event.REMOVED_FROM_STAGE, selfRemoveEvent); - } - - function onRemove(e:Event, stage:Stage):Void { - - stage.removeEventListener(MouseEvent.MOUSE_UP, mouseHandler); - _target.removeEventListener(MouseEvent.MOUSE_OVER, mouseHandler); - _target.removeEventListener(MouseEvent.MOUSE_OUT, mouseHandler); - _target.removeEventListener(MouseEvent.MOUSE_DOWN, mouseHandler); - _target.removeEventListener(MouseEvent.CLICK, mouseHandler); - } - - function mouseHandler(event:MouseEvent):Void { - - switch(event.type) { - - case MouseEvent.MOUSE_OVER: - - _over = true; - - if (onOver != null) - onOver(); - - case MouseEvent.MOUSE_OUT: - - _over = false; - - if (onOut != null) - onOut(); - - case MouseEvent.MOUSE_DOWN: - - _down = true; - - case MouseEvent.MOUSE_UP: - - _down = false; - - case MouseEvent.CLICK: - - if (enabled && onClick != null) - onClick(); - } - updateState(); - } - - function updateEnabled():Void { - - updateState(); - - _target.useHandCursor = enabled; - _target.buttonMode = enabled; - } - - function updateState():Void { - - var state = determineState(); - - if (_target.currentLabel != state && _foundLabels.indexOf(state) != -1) - _target.gotoAndStop(state); - } - - function determineState():String { - - if (enabled) { - - if (_over) - return _down ? "down" : "over"; - - return "up"; - - } - return "disabled"; - } - - public function destroy():Void { - - _target.removeEventListener(Event.ADDED_TO_STAGE, onAdded); - - _target = null; - onClick = null; - onOver = null; - onOut = null; - _foundLabels = null; - } -} diff --git a/source/io/newgrounds/swf/common/DropDown.hx b/source/io/newgrounds/swf/common/DropDown.hx deleted file mode 100644 index a882cf39b..000000000 --- a/source/io/newgrounds/swf/common/DropDown.hx +++ /dev/null @@ -1,88 +0,0 @@ -package io.newgrounds.swf.common; - - -import haxe.ds.StringMap; - -import openfl.display.MovieClip; -import openfl.display.Sprite; -import openfl.text.TextField; - -class DropDown { - - public var value(default, set):String; - function set_value(v:String):String { - - if (this.value == v) - return v; - - this.value = v; - _selectedLabel.text = _values.get(v); - - if (_onChange != null) - _onChange(); - - return v; - } - - var _choiceContainer:Sprite; - var _selectedLabel:TextField; - var _onChange:Void->Void; - var _values:StringMap; - var _unusedChoices:Array; - - public function new(target:MovieClip, label:String = "", onChange:Void->Void = null) { - - _onChange = onChange; - - _selectedLabel = cast cast(target.getChildByName("currentItem"), MovieClip).getChildByName("label"); - _selectedLabel.text = label; - - _values = new StringMap(); - - new Button(cast target.getChildByName("button"), onClickExpand); - new Button(cast target.getChildByName("currentItem"), onClickExpand); - _choiceContainer = new Sprite(); - _choiceContainer.visible = false; - target.addChild(_choiceContainer); - - _unusedChoices = new Array(); - while(true) { - - var item:MovieClip = cast target.getChildByName('item${_unusedChoices.length}'); - if (item == null) - break; - - target.removeChild(item); - _unusedChoices.push(item); - } - } - - public function addItem(name:String, value:String):Void { - - _values.set(value, name); - - if (_unusedChoices.length == 0) { - - NG.core.logError('cannot create another dropBox item max=${_choiceContainer.numChildren}'); - return; - } - - var button = _unusedChoices.shift(); - cast(button.getChildByName("label"), TextField).text = name; - _choiceContainer.addChild(button); - - new Button(button, onChoiceClick.bind(value)); - } - - function onClickExpand():Void { - - _choiceContainer.visible = !_choiceContainer.visible; - } - - function onChoiceClick(name:String):Void { - - value = name; - - _choiceContainer.visible = false; - } -} \ No newline at end of file diff --git a/source/io/newgrounds/utils/AsyncHttp.hx b/source/io/newgrounds/utils/AsyncHttp.hx deleted file mode 100644 index 4fbe14388..000000000 --- a/source/io/newgrounds/utils/AsyncHttp.hx +++ /dev/null @@ -1,203 +0,0 @@ -package io.newgrounds.utils; - -import io.newgrounds.NGLite; - -import haxe.Http; -import haxe.Timer; - -#if neko -import neko.vm.Thread; -#elseif java -import java.vm.Thread; -#elseif cpp -import cpp.vm.Thread; -#end - -/** - * Uses Threading to turn hxcpp's synchronous http requests into asynchronous processes - * - * @author GeoKureli - */ -class AsyncHttp { - - inline static var PATH:String = "https://newgrounds.io/gateway_v3.php"; - - static public function send - ( core:NGLite - , data:String - , onData:String->Void - , onError:String->Void - , onStatus:Int->Void - ) { - - core.logVerbose('sending: $data'); - - #if (neko || java || cpp) - sendAsync(core, data, onData, onError, onStatus); - #else - sendSync(core, data, onData, onError, onStatus); - #end - } - - static function sendSync - ( core:NGLite - , data:String - , onData:String->Void - , onError:String->Void - , onStatus:Int->Void - ):Void { - - var http = new Http(PATH); - http.setParameter("input", data); - http.onData = onData; - http.onError = onError; - http.onStatus = onStatus; - // #if js http.async = async; #end - http.request(true); - } - - #if (neko || java || cpp) - static var _deadPool:Array = []; - static var _livePool:Array = []; - static var _map:Map = new Map(); - static var _timer:Timer; - - static var _count:Int = 0; - - var _core:NGLite; - var _key:Int; - var _onData:String->Void; - var _onError:String->Void; - var _onStatus:Int->Void; - var _worker:Thread; - - public function new (core:NGLite) { - - _core = core; - _worker = Thread.create(sendThreaded); - _key = _count++; - _map[_key] = this; - _core.logVerbose('async http created: $_key'); - } - - function start(data:String, onData:String->Void, onError:String->Void, onStatus:Int->Void) { - - _core.logVerbose('async http started: $_key'); - - if (_livePool.length == 0) - startTimer(); - - _deadPool.remove(this); - _livePool.push(this); - - _onData = onData; - _onError = onError; - _onStatus = onStatus; - _worker.sendMessage({ source:Thread.current(), args:data, key:_key, core:_core }); - } - - function handleMessage(data:ReplyData):Void { - - _core.logVerbose('handling message: $_key'); - - if (data.status != null) { - - _core.logVerbose('\t- status: ${data.status}'); - _onStatus(cast data.status); - return; - } - - var tempFunc:Void->Void; - if (data.data != null) { - - _core.logVerbose('\t- data'); - tempFunc = _onData.bind(data.data); - - } else { - - _core.logVerbose('\t- error'); - tempFunc = _onError.bind(data.error); - } - - cleanUp(); - // Delay the call until destroy so that we're more likely to use a single - // thread on daisy-chained calls - tempFunc(); - } - - inline function cleanUp():Void { - - _onData = null; - _onError = null; - - _deadPool.push(this); - _livePool.remove(this); - - if (_livePool.length == 0) - stopTimer(); - } - - static function sendAsync - ( core:NGLite - , data:String - , onData:String->Void - , onError:String->Void - , onStatus:Int->Void - ):Void { - - var http:AsyncHttp; - if (_deadPool.length == 0) - http = new AsyncHttp(core); - else - http = _deadPool[0]; - - http.start(data, onData, onError, onStatus); - } - - static function startTimer():Void { - - if (_timer != null) - return; - - _timer = new Timer(1000 / 60.0); - _timer.run = update; - } - - static function stopTimer():Void { - - _timer.stop(); - _timer = null; - } - - static public function update():Void { - - var message:ReplyData = cast Thread.readMessage(false); - if (message != null) - _map[message.key].handleMessage(message); - } - - static function sendThreaded():Void { - - while(true) { - - var data:LoaderData = cast Thread.readMessage(true); - data.core.logVerbose('start message received: ${data.key}'); - - sendSync - ( data.core - , data.args - , function(reply ) { data.source.sendMessage({ key:data.key, data :reply }); } - , function(error ) { data.source.sendMessage({ key:data.key, error :error }); } - , function(status) { data.source.sendMessage({ key:data.key, status:status }); } - ); - } - } - - #end -} - - -#if (neko || java || cpp) -typedef LoaderData = { source:Thread, key:Int, args:String, core:NGLite }; -typedef ReplyData = { key:Int, ?data:String, ?error:String, ?status:Null }; -#end \ No newline at end of file diff --git a/source/io/newgrounds/utils/Dispatcher.hx b/source/io/newgrounds/utils/Dispatcher.hx deleted file mode 100644 index 699da01da..000000000 --- a/source/io/newgrounds/utils/Dispatcher.hx +++ /dev/null @@ -1,118 +0,0 @@ -package io.newgrounds.utils; - -/** - * Basically shitty signals, but I didn't want to have external references. -**/ -class Dispatcher { - - var _list:ArrayVoid>; - var _once:ArrayVoid>; - - public function new() { - - _list = new ArrayVoid>(); - _once = new ArrayVoid>(); - } - - public function add(handler:Void->Void, once:Bool = false):Bool { - - if (_list.indexOf(handler) != -1) { - - // ---- REMOVE ONCE - if (!once && _once.indexOf(handler) != -1) - _once.remove(handler); - - return false; - } - - _list.unshift(handler); - if (once) - _once.unshift(handler); - - return true; - } - - inline public function addOnce(handler:Void->Void):Bool { - - return add(handler, true); - } - - public function remove(handler:Void->Void):Bool { - - _once.remove(handler); - return _list.remove(handler); - } - - public function dispatch():Void { - - var i = _list.length - 1; - while(i >= 0) { - - var handler = _list[i]; - - if (_once.remove(handler)) - _list.remove(handler); - - handler(); - - i--; - } - } -} - -class TypedDispatcher { - - var _list:ArrayVoid>; - var _once:ArrayVoid>; - - public function new() { - - _list = new ArrayVoid>(); - _once = new ArrayVoid>(); - } - - public function add(handler:T->Void, once:Bool = false):Bool { - - if (_list.indexOf(handler) != -1) { - - // ---- REMOVE ONCE - if (!once && _once.indexOf(handler) != -1) - _once.remove(handler); - - return false; - } - - _list.unshift(handler); - if (once) - _once.unshift(handler); - - return true; - } - - inline public function addOnce(handler:T->Void):Bool { - - return add(handler, true); - } - - public function remove(handler:T->Void):Bool { - - _once.remove(handler); - return _list.remove(handler); - } - - public function dispatch(arg:T):Void { - - var i = _list.length - 1; - while(i >= 0) { - - var handler = _list[i]; - - if (_once.remove(handler)) - _list.remove(handler); - - handler(arg); - - i--; - } - } -} \ No newline at end of file From 36361ff0a40c52386a6a06663c363b6f274f9951 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Fri, 6 Nov 2020 02:21:29 -0800 Subject: [PATCH 02/35] Seperated tutorials --- source/FreeplayState.hx | 12 ++++++++++++ source/MenuItem.hx | 13 +++++-------- source/StoryMenuState.hx | 18 +++++++----------- source/TitleState.hx | 3 +++ 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/source/FreeplayState.hx b/source/FreeplayState.hx index f906e8f07..6d010f2a5 100644 --- a/source/FreeplayState.hx +++ b/source/FreeplayState.hx @@ -17,6 +17,7 @@ class FreeplayState extends MusicBeatState var selector:FlxText; var curSelected:Int = 0; + var curDifficulty:Int = 1; var scoreText:FlxText; var lerpScore:Int = 0; @@ -77,6 +78,7 @@ class FreeplayState extends MusicBeatState add(scoreText); changeSelection(); + changeDiff(); // FlxG.sound.playMusic('assets/music/title' + TitleState.soundExt, 0); // FlxG.sound.music.fadeIn(2, 0, 0.8); @@ -143,6 +145,16 @@ class FreeplayState extends MusicBeatState } } + function changeDiff(change:Int = 0) + { + curDifficulty += change; + + if (curDifficulty < 0) + curDifficulty = 2; + if (curDifficulty > 2) + curDifficulty = 0; + } + function changeSelection(change:Int = 0) { NGio.logEvent('Fresh'); diff --git a/source/MenuItem.hx b/source/MenuItem.hx index 5aae4ee28..e5bf62c9e 100644 --- a/source/MenuItem.hx +++ b/source/MenuItem.hx @@ -10,7 +10,7 @@ class MenuItem extends FlxSpriteGroup public var targetY:Float = 0; public var week:FlxSprite; - public function new(x:Float, y:Float, weekNum:Int = 0, unlocked:Bool = false) + public function new(x:Float, y:Float, weekNum:Int = 0) { super(x, y); @@ -18,18 +18,15 @@ class MenuItem extends FlxSpriteGroup week = new FlxSprite(); week.frames = tex; - week.animation.addByPrefix('week0', "WEEK1 select", 24); - week.animation.addByPrefix('week1', "week2 select", 24); + // TUTORIAL IS WEEK 0 + week.animation.addByPrefix('week0', 'tutorial selected', 24); + week.animation.addByPrefix('week1', "WEEK1 select", 24); + week.animation.addByPrefix('week2', "week2 select", 24); add(week); week.animation.play('week' + weekNum); week.animation.pause(); week.updateHitbox(); - - if (!unlocked) - { - week.alpha = 0.6; - } } override function update(elapsed:Float) diff --git a/source/StoryMenuState.hx b/source/StoryMenuState.hx index ca6ba28f7..a12af46f0 100644 --- a/source/StoryMenuState.hx +++ b/source/StoryMenuState.hx @@ -16,12 +16,12 @@ class StoryMenuState extends MusicBeatState { var scoreText:FlxText; - var weekData:Array = [['Tutorial', 'Bopeebo', 'Fresh', 'Dadbattle'], ['Spookeez', 'South']]; + var weekData:Array = [['Tutorial'], ['Bopeebo', 'Fresh', 'Dadbattle'], ['Spookeez', 'South']]; var curDifficulty:Int = 1; - public static var weekUnlocked:Array = [true, false]; + public static var weekUnlocked:Array = [true, true, false]; - var weekCharacters:Array = [['dad', 'bf', 'gf'], ['spooky', 'bf', 'gf']]; + var weekCharacters:Array = [['dad', 'bf', 'gf'], ['dad', 'bf', 'gf'], ['spooky', 'bf', 'gf']]; var curWeek:Int = 0; var txtTracklist:FlxText; @@ -68,12 +68,7 @@ class StoryMenuState extends MusicBeatState for (i in 0...weekData.length) { - var unlocked:Bool = true; - - if (i == 1) - unlocked = false; - - var weekThing:MenuItem = new MenuItem(0, yellowBG.y + yellowBG.height + 10, i, unlocked); + var weekThing:MenuItem = new MenuItem(0, yellowBG.y + yellowBG.height + 10, i); weekThing.y += ((weekThing.height + 20) * i); weekThing.targetY = i; grpWeekText.add(weekThing); @@ -82,6 +77,7 @@ class StoryMenuState extends MusicBeatState weekThing.antialiasing = true; // weekThing.updateHitbox(); + // Needs an offset thingie if (!weekUnlocked[i]) { var lock:FlxSprite = new FlxSprite(weekThing.width + 10 + weekThing.x); @@ -120,7 +116,7 @@ class StoryMenuState extends MusicBeatState difficultySelectors = new FlxGroup(); add(difficultySelectors); - leftArrow = new FlxSprite(grpWeekText.members[0].x + 370, grpWeekText.members[0].y + 10); + leftArrow = new FlxSprite(grpWeekText.members[0].x + grpWeekText.members[0].width + 10, grpWeekText.members[0].y + 10); leftArrow.frames = ui_tex; leftArrow.animation.addByPrefix('idle', "arrow left"); leftArrow.animation.addByPrefix('press', "arrow push left"); @@ -303,7 +299,7 @@ class StoryMenuState extends MusicBeatState for (item in grpWeekText.members) { item.targetY = bullShit - curWeek; - if (item.targetY == Std.int(0)) + if (item.targetY == Std.int(0) && weekUnlocked[curWeek]) item.alpha = 1; else item.alpha = 0.6; diff --git a/source/TitleState.hx b/source/TitleState.hx index 003563583..b3d81eac7 100644 --- a/source/TitleState.hx +++ b/source/TitleState.hx @@ -68,6 +68,9 @@ class TitleState extends MusicBeatState if (FlxG.save.data.weekUnlocked != null) { StoryMenuState.weekUnlocked = FlxG.save.data.weekUnlocked; + + if (StoryMenuState.weekUnlocked.length < 3) + StoryMenuState.weekUnlocked.insert(0, true); } #if SKIP_TO_PLAYSTATE From 4a715a86a00c84ab7b95203323d57f291c87c53c Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Fri, 6 Nov 2020 02:31:33 -0800 Subject: [PATCH 03/35] difficulty selecting --- CHANGELOG.md | 6 ++---- source/FreeplayState.hx | 30 +++++++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b599ea70..fd6e4c902 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] -### Added - ## [0.2.1] - 2020-11-06 ### Added @@ -14,10 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - A few new intro boot messages. - Lightning effect in Spooky stages - Campaign scores, can now compete on scoreboards for campaign! -- Can now change difficulties in +- Can now change difficulties in Freeplay mode ### Changed -- Balanced out Normal mode for all songs. Should be much easier all around. +- Balanced out Normal mode for the harder songs. Should be much easier all around. - Put tutorial in it's own 'week', so that if you want to play week 1, you don't have to play the tutorial. ### Fixed diff --git a/source/FreeplayState.hx b/source/FreeplayState.hx index 6d010f2a5..50a248ae0 100644 --- a/source/FreeplayState.hx +++ b/source/FreeplayState.hx @@ -20,6 +20,7 @@ class FreeplayState extends MusicBeatState var curDifficulty:Int = 1; var scoreText:FlxText; + var diffText:FlxText; var lerpScore:Int = 0; var intendedScore:Int = 0; @@ -71,10 +72,14 @@ class FreeplayState extends MusicBeatState scoreText.setFormat("assets/fonts/vcr.ttf", 32, FlxColor.WHITE, RIGHT); // scoreText.alignment = RIGHT; - var scoreBG:FlxSprite = new FlxSprite(scoreText.x - 6, 0).makeGraphic(Std.int(FlxG.width * 0.35), 40, 0xFF000000); + var scoreBG:FlxSprite = new FlxSprite(scoreText.x - 6, 0).makeGraphic(Std.int(FlxG.width * 0.35), 66, 0xFF000000); scoreBG.alpha = 0.6; add(scoreBG); + diffText = new FlxText(scoreText.x, scoreText.y + 36, 0, "", 24); + diffText.font = scoreText.font; + add(diffText); + add(scoreText); changeSelection(); @@ -130,6 +135,11 @@ class FreeplayState extends MusicBeatState changeSelection(1); } + if (controls.LEFT_P) + changeDiff(-1); + if (controls.RIGHT_P) + changeDiff(1); + if (controls.BACK) { FlxG.switchState(new MainMenuState()); @@ -137,7 +147,9 @@ class FreeplayState extends MusicBeatState if (accepted) { - PlayState.SONG = Song.loadFromJson(songs[curSelected].toLowerCase(), songs[curSelected].toLowerCase()); + var poop:String = Highscore.formatSong(songs[curSelected].toLowerCase(), curDifficulty); + + PlayState.SONG = Song.loadFromJson(poop, songs[curSelected].toLowerCase()); PlayState.isStoryMode = false; FlxG.switchState(new PlayState()); if (FlxG.sound.music != null) @@ -153,6 +165,18 @@ class FreeplayState extends MusicBeatState curDifficulty = 2; if (curDifficulty > 2) curDifficulty = 0; + + intendedScore = Highscore.getScore(songs[curSelected], curDifficulty); + + switch (curDifficulty) + { + case 0: + diffText.text = "EASY"; + case 1: + diffText.text = 'NORMAL'; + case 2: + diffText.text = "HARD"; + } } function changeSelection(change:Int = 0) @@ -168,7 +192,7 @@ class FreeplayState extends MusicBeatState // selector.y = (70 * curSelected) + 30; - intendedScore = Highscore.getScore(songs[curSelected], 1); + intendedScore = Highscore.getScore(songs[curSelected], curDifficulty); // lerpScore = 0; var bullShit:Int = 0; From c2b17d4e3ec380fef272dbbc1d7e457a0c4c5845 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Fri, 6 Nov 2020 02:56:45 -0800 Subject: [PATCH 04/35] WEEK SCORE SHIT --- source/Highscore.hx | 23 +++++++++++++++++++++++ source/PlayState.hx | 6 ++++++ source/StoryMenuState.hx | 14 ++++++++++++-- source/TitleState.hx | 2 +- 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/source/Highscore.hx b/source/Highscore.hx index f587a3a17..b57870518 100644 --- a/source/Highscore.hx +++ b/source/Highscore.hx @@ -21,6 +21,21 @@ class Highscore setScore(daSong, score); } + public static function saveWeekScore(week:Int = 1, score:Int = 0, ?diff:Int = 0):Void + { + NGio.postScore(score, "Week " + week); + + var daWeek:String = formatSong('week' + week, diff); + + if (songScores.exists(daWeek)) + { + if (songScores.get(daWeek) < score) + setScore(daWeek, score); + } + else + setScore(daWeek, score); + } + /** * YOU SHOULD FORMAT SONG WITH formatSong() BEFORE TOSSING IN SONG VARIABLE */ @@ -52,6 +67,14 @@ class Highscore return songScores.get(formatSong(song, diff)); } + public static function getWeekScore(week:Int, diff:Int):Int + { + if (!songScores.exists(formatSong('week' + week, diff))) + setScore(formatSong('week' + week, diff), 0); + + return songScores.get(formatSong('week' + week, diff)); + } + public static function load():Void { if (FlxG.save.data.songScores != null) diff --git a/source/PlayState.hx b/source/PlayState.hx index 9ca8723a5..f22548a7e 100644 --- a/source/PlayState.hx +++ b/source/PlayState.hx @@ -37,6 +37,7 @@ class PlayState extends MusicBeatState public static var curLevel:String = 'Tutorial'; public static var SONG:SwagSong; public static var isStoryMode:Bool = false; + public static var storyWeek:Int = 0; public static var storyPlaylist:Array = []; public static var storyDifficulty:Int = 1; @@ -83,6 +84,8 @@ class PlayState extends MusicBeatState var talking:Bool = true; var songScore:Int = 0; + public static var campaignScore:Int = 0; + override public function create() { // var gameCam:FlxCamera = FlxG.camera; @@ -825,6 +828,8 @@ class PlayState extends MusicBeatState if (isStoryMode) { + campaignScore += songScore; + storyPlaylist.remove(storyPlaylist[0]); if (storyPlaylist.length <= 0) @@ -836,6 +841,7 @@ class PlayState extends MusicBeatState StoryMenuState.weekUnlocked[1] = true; NGio.unlockMedal(60961); + Highscore.saveWeekScore(storyWeek, campaignScore, storyDifficulty); FlxG.save.data.weekUnlocked = StoryMenuState.weekUnlocked; FlxG.save.flush(); diff --git a/source/StoryMenuState.hx b/source/StoryMenuState.hx index a12af46f0..1a0c50c5d 100644 --- a/source/StoryMenuState.hx +++ b/source/StoryMenuState.hx @@ -5,6 +5,7 @@ import flixel.FlxSprite; import flixel.graphics.frames.FlxAtlasFrames; import flixel.group.FlxGroup.FlxTypedGroup; import flixel.group.FlxGroup; +import flixel.math.FlxMath; import flixel.text.FlxText; import flixel.tweens.FlxTween; import flixel.util.FlxTimer; @@ -149,7 +150,7 @@ class StoryMenuState extends MusicBeatState txtTracklist.color = 0xFFe55777; add(txtTracklist); // add(rankText); - // add(scoreText); + add(scoreText); updateText(); @@ -159,7 +160,9 @@ class StoryMenuState extends MusicBeatState override function update(elapsed:Float) { // scoreText.setFormat('VCR OSD Mono', 32); - // scoreText.text = "Score SHIT"; + lerpScore = Math.floor(FlxMath.lerp(lerpScore, intendedScore, 0.5)); + + scoreText.text = "WEEK SCORE:" + lerpScore; // FlxG.watch.addQuick('font', scoreText.font); difficultySelectors.visible = weekUnlocked[curWeek]; @@ -244,6 +247,7 @@ class StoryMenuState extends MusicBeatState PlayState.storyDifficulty = curDifficulty; PlayState.SONG = Song.loadFromJson(PlayState.storyPlaylist[0].toLowerCase() + diffic, PlayState.storyPlaylist[0].toLowerCase()); + PlayState.storyWeek = curWeek; new FlxTimer().start(1, function(tmr:FlxTimer) { if (FlxG.sound.music != null) @@ -281,10 +285,14 @@ class StoryMenuState extends MusicBeatState // USING THESE WEIRD VALUES SO THAT IT DOESNT FLOAT UP sprDifficulty.y = leftArrow.y - 15; + intendedScore = Highscore.getWeekScore(curWeek, curDifficulty); FlxTween.tween(sprDifficulty, {y: leftArrow.y + 15, alpha: 1}, 0.07); } + var lerpScore:Int = 0; + var intendedScore:Int = 0; + function changeWeek(change:Int = 0):Void { curWeek += change; @@ -329,5 +337,7 @@ class StoryMenuState extends MusicBeatState txtTracklist.screenCenter(X); txtTracklist.x -= FlxG.width * 0.35; + + intendedScore = Highscore.getWeekScore(curWeek, curDifficulty); } } diff --git a/source/TitleState.hx b/source/TitleState.hx index b3d81eac7..0c7a870e8 100644 --- a/source/TitleState.hx +++ b/source/TitleState.hx @@ -74,7 +74,7 @@ class TitleState extends MusicBeatState } #if SKIP_TO_PLAYSTATE - FlxG.switchState(new FreeplayState()); + FlxG.switchState(new StoryMenuState()); #else startIntro(); #end From 48c482440c70c387115598322edef9b21bb282c0 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Fri, 6 Nov 2020 03:17:40 -0800 Subject: [PATCH 05/35] clarified changelog --- CHANGELOG.md | 2 +- Project.xml | 2 +- source/MainMenuState.hx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd6e4c902..f6c3d4013 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Can now change difficulties in Freeplay mode ### Changed -- Balanced out Normal mode for the harder songs. Should be much easier all around. +- Balanced out Normal mode for the harder songs(Dadbattle and Spookeez, not South yet). Should be much easier all around. - Put tutorial in it's own 'week', so that if you want to play week 1, you don't have to play the tutorial. ### Fixed diff --git a/Project.xml b/Project.xml index 673afa4ed..5e01c8f0c 100644 --- a/Project.xml +++ b/Project.xml @@ -103,7 +103,7 @@ - + diff --git a/source/MainMenuState.hx b/source/MainMenuState.hx index cdabcbbcb..305508b4f 100644 --- a/source/MainMenuState.hx +++ b/source/MainMenuState.hx @@ -18,7 +18,7 @@ class MainMenuState extends MusicBeatState var menuItems:FlxTypedGroup; - var optionShit:Array = ['story mode', 'freeplay', 'options', 'donate']; + var optionShit:Array = ['story mode', 'freeplay', 'donate']; var magenta:FlxSprite; var camFollow:FlxObject; From 4ba3cfbfdb8d775b6bd95ad4dbf4160a8945a628 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Fri, 6 Nov 2020 11:56:41 -0800 Subject: [PATCH 06/35] hotfix for da week 2 unlock --- CHANGELOG.md | 4 +++- Project.xml | 2 +- source/PlayState.hx | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6c3d4013..c7576acbe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,9 @@ All notable changes will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [0.2.1.1] - 2020-11-06 +### Fixed +- Week 2 not unlocking properly ## [0.2.1] - 2020-11-06 ### Added diff --git a/Project.xml b/Project.xml index 5e01c8f0c..fb5457ab1 100644 --- a/Project.xml +++ b/Project.xml @@ -2,7 +2,7 @@ - + diff --git a/source/PlayState.hx b/source/PlayState.hx index f22548a7e..8b9de9971 100644 --- a/source/PlayState.hx +++ b/source/PlayState.hx @@ -838,7 +838,7 @@ class PlayState extends MusicBeatState FlxG.switchState(new StoryMenuState()); - StoryMenuState.weekUnlocked[1] = true; + StoryMenuState.weekUnlocked[2] = true; NGio.unlockMedal(60961); Highscore.saveWeekScore(storyWeek, campaignScore, storyDifficulty); From 5ed65c5ee53bc797a9bbeefaba438d99d68ce54b Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Fri, 6 Nov 2020 13:51:11 -0800 Subject: [PATCH 07/35] score shit --- CHANGELOG.md | 5 +++++ Project.xml | 4 ++-- source/FreeplayState.hx | 3 +++ source/PlayState.hx | 9 +-------- source/StoryMenuState.hx | 1 + 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7576acbe..a2b6aac5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,13 @@ All notable changes will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.1.2] - 2020-11-06 +### Fixed +- Story mode scores not properly resetting, leading to VERY inflated highscores on the leaderboards. This also requires me to clear the scores that are on the leaderboard right now, sorry! + ## [0.2.1.1] - 2020-11-06 ### Fixed +- Difficulty on storymode and in freeplay scores - Week 2 not unlocking properly ## [0.2.1] - 2020-11-06 diff --git a/Project.xml b/Project.xml index fb5457ab1..1c148e2ff 100644 --- a/Project.xml +++ b/Project.xml @@ -2,7 +2,7 @@ - + @@ -104,7 +104,7 @@ - + diff --git a/source/FreeplayState.hx b/source/FreeplayState.hx index 50a248ae0..ad336ce8a 100644 --- a/source/FreeplayState.hx +++ b/source/FreeplayState.hx @@ -149,8 +149,11 @@ class FreeplayState extends MusicBeatState { var poop:String = Highscore.formatSong(songs[curSelected].toLowerCase(), curDifficulty); + trace(poop); + PlayState.SONG = Song.loadFromJson(poop, songs[curSelected].toLowerCase()); PlayState.isStoryMode = false; + PlayState.storyDifficulty = curDifficulty; FlxG.switchState(new PlayState()); if (FlxG.sound.music != null) FlxG.sound.music.stop(); diff --git a/source/PlayState.hx b/source/PlayState.hx index 8b9de9971..ab548604a 100644 --- a/source/PlayState.hx +++ b/source/PlayState.hx @@ -463,7 +463,7 @@ class PlayState extends MusicBeatState daBeats += 1; } - trace(unspawnNotes.length); + // trace(unspawnNotes.length); // playerCounter += 1; unspawnNotes.sort(sortByShit); @@ -586,9 +586,6 @@ class PlayState extends MusicBeatState { super.update(elapsed); - // trace("SONG POS: " + Conductor.songPosition); - // FlxG.sound.music.pitch = 2; - if (FlxG.keys.justPressed.ENTER && startedCountdown) { persistentUpdate = false; @@ -822,8 +819,6 @@ class PlayState extends MusicBeatState function endSong():Void { - trace('SONG DONE' + isStoryMode); - Highscore.saveScore(SONG.song, songScore, storyDifficulty); if (isStoryMode) @@ -1021,7 +1016,6 @@ class PlayState extends MusicBeatState if (daNote.canBeHit && daNote.mustPress && !daNote.tooLate) { possibleNotes.push(daNote); - trace('NOTE-' + daNote.strumTime + ' ADDED'); } }); @@ -1214,7 +1208,6 @@ class PlayState extends MusicBeatState function noteCheck(keyP:Bool, note:Note):Void { - trace(note.noteData + ' note check here ' + keyP); if (keyP) goodNoteHit(note); else diff --git a/source/StoryMenuState.hx b/source/StoryMenuState.hx index 1a0c50c5d..0f4b5c018 100644 --- a/source/StoryMenuState.hx +++ b/source/StoryMenuState.hx @@ -248,6 +248,7 @@ class StoryMenuState extends MusicBeatState PlayState.SONG = Song.loadFromJson(PlayState.storyPlaylist[0].toLowerCase() + diffic, PlayState.storyPlaylist[0].toLowerCase()); PlayState.storyWeek = curWeek; + PlayState.campaignScore = 0; new FlxTimer().start(1, function(tmr:FlxTimer) { if (FlxG.sound.music != null) From a93914acd1a5cacd97f76a50bf24f2d18b1c09a0 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Fri, 6 Nov 2020 13:51:28 -0800 Subject: [PATCH 08/35] changelog --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2b6aac5a..0e690df3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,10 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.2.1.2] - 2020-11-06 ### Fixed - Story mode scores not properly resetting, leading to VERY inflated highscores on the leaderboards. This also requires me to clear the scores that are on the leaderboard right now, sorry! - +- Difficulty on storymode and in freeplay scores ## [0.2.1.1] - 2020-11-06 ### Fixed -- Difficulty on storymode and in freeplay scores - Week 2 not unlocking properly ## [0.2.1] - 2020-11-06 From 08a7b2ae02952499466d272ae0ada5cffc2b82b1 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Fri, 6 Nov 2020 18:14:13 -0800 Subject: [PATCH 09/35] dont need markdown shitlolol --- Project.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Project.xml b/Project.xml index 1c148e2ff..961a5f09c 100644 --- a/Project.xml +++ b/Project.xml @@ -60,8 +60,8 @@ - - + + From 3979fab6b9101d8d9b31cf74a4868e9cbb8bd19a Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Fri, 6 Nov 2020 19:39:21 -0800 Subject: [PATCH 10/35] hard mode lol --- CHANGELOG.md | 1 + Project.xml | 6 ++++-- source/FreeplayState.hx | 1 - source/PlayState.hx | 5 ++++- source/TitleState.hx | 6 ++++++ 5 files changed, 15 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e690df3a..aae8fa867 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Story mode scores not properly resetting, leading to VERY inflated highscores on the leaderboards. This also requires me to clear the scores that are on the leaderboard right now, sorry! - Difficulty on storymode and in freeplay scores +- Hard mode difficulty on campaign levels have been fixed ## [0.2.1.1] - 2020-11-06 ### Fixed - Week 2 not unlocking properly diff --git a/Project.xml b/Project.xml index 961a5f09c..3487d181f 100644 --- a/Project.xml +++ b/Project.xml @@ -39,8 +39,10 @@ - - + + + + diff --git a/source/FreeplayState.hx b/source/FreeplayState.hx index ad336ce8a..b402456ba 100644 --- a/source/FreeplayState.hx +++ b/source/FreeplayState.hx @@ -8,7 +8,6 @@ import flixel.group.FlxGroup.FlxTypedGroup; import flixel.math.FlxMath; import flixel.text.FlxText; import flixel.util.FlxColor; -import htmlparser.HtmlDocument; import lime.utils.Assets; class FreeplayState extends MusicBeatState diff --git a/source/PlayState.hx b/source/PlayState.hx index ab548604a..1eebd82f6 100644 --- a/source/PlayState.hx +++ b/source/PlayState.hx @@ -849,7 +849,10 @@ class PlayState extends MusicBeatState difficulty = '-easy'; if (storyDifficulty == 2) - difficulty == '-hard'; + difficulty = '-hard'; + + trace('LOADING NEXT SONG'); + trace(PlayState.storyPlaylist[0].toLowerCase() + difficulty); PlayState.SONG = Song.loadFromJson(PlayState.storyPlaylist[0].toLowerCase() + difficulty, PlayState.storyPlaylist[0]); FlxG.switchState(new PlayState()); diff --git a/source/TitleState.hx b/source/TitleState.hx index 0c7a870e8..a9b93c05c 100644 --- a/source/TitleState.hx +++ b/source/TitleState.hx @@ -13,6 +13,8 @@ import flixel.group.FlxGroup; import flixel.input.gamepad.FlxGamepad; import flixel.math.FlxPoint; import flixel.math.FlxRect; +import flixel.system.FlxSound; +import flixel.system.ui.FlxSoundTray; import flixel.text.FlxText; import flixel.tweens.FlxEase; import flixel.tweens.FlxTween; @@ -104,6 +106,10 @@ class TitleState extends MusicBeatState transIn = FlxTransitionableState.defaultTransIn; transOut = FlxTransitionableState.defaultTransOut; + // var music:FlxSound = new FlxSound(); + // music.loadStream('assets/music/freakyMenu' + TitleState.soundExt); + // FlxG.sound.list.add(music); + // music.play(); FlxG.sound.playMusic('assets/music/freakyMenu' + TitleState.soundExt, 0); FlxG.sound.music.fadeIn(4, 0, 0.7); From e4b9be1f2a0eac49d6d77a8bef3b7a21c3d33a7e Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Sat, 7 Nov 2020 22:26:05 -0800 Subject: [PATCH 11/35] funny music :) --- Project.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Project.xml b/Project.xml index 3487d181f..e87c97ed4 100644 --- a/Project.xml +++ b/Project.xml @@ -40,9 +40,9 @@ - - - + + + From aae3bf37e14f376caaf1410c4c725d4cf79ea889 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Mon, 9 Nov 2020 15:26:10 -0800 Subject: [PATCH 12/35] fixed freeplay score offset shit --- source/FreeplayState.hx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/FreeplayState.hx b/source/FreeplayState.hx index b402456ba..5002fff57 100644 --- a/source/FreeplayState.hx +++ b/source/FreeplayState.hx @@ -119,6 +119,10 @@ class FreeplayState extends MusicBeatState super.update(elapsed); lerpScore = Math.floor(FlxMath.lerp(lerpScore, intendedScore, 0.4)); + + if (Math.abs(lerpScore - intendedScore) <= 10) + lerpScore = intendedScore; + scoreText.text = "PERSONAL BEST:" + lerpScore; var upP = controls.UP_P; From 33a92a0a871671624b30879c789e07f5c00c7c5f Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 10 Nov 2020 18:07:56 -0800 Subject: [PATCH 13/35] south chart, and maybe note flicker? --- CHANGELOG.md | 4 ++++ source/Note.hx | 2 ++ 2 files changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index aae8fa867..767060dc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] +### Fixed +- Cleaned up some charting on South on hard mode + ## [0.2.1.2] - 2020-11-06 ### Fixed - Story mode scores not properly resetting, leading to VERY inflated highscores on the leaderboards. This also requires me to clear the scores that are on the leaderboard right now, sorry! diff --git a/source/Note.hx b/source/Note.hx index 748cbe185..06825e717 100644 --- a/source/Note.hx +++ b/source/Note.hx @@ -37,6 +37,8 @@ class Note extends FlxSprite isSustainNote = sustainNote; x += 50; + // MAKE SURE ITS DEFINITELY OFF SCREEN? + y -= 2000; this.strumTime = strumTime; this.noteData = noteData; From ce2dc758393e8629b3a25e0c1aae76896439a79e Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 10 Nov 2020 19:09:48 -0800 Subject: [PATCH 14/35] some animation touchups --- CHANGELOG.md | 1 + source/Boyfriend.hx | 8 ++++++++ source/Character.hx | 27 +++++++++++++++++++++++++++ source/PlayState.hx | 8 ++++++-- source/TitleState.hx | 2 +- 5 files changed, 43 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 767060dc7..2944f1b8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Fixed - Cleaned up some charting on South on hard mode +- Fixed some animation timings, should feel both better to play, and watch. ## [0.2.1.2] - 2020-11-06 ### Fixed diff --git a/source/Boyfriend.hx b/source/Boyfriend.hx index 1a8c6cf07..5efc70987 100644 --- a/source/Boyfriend.hx +++ b/source/Boyfriend.hx @@ -3,6 +3,7 @@ package; import flixel.FlxG; import flixel.FlxSprite; import flixel.graphics.frames.FlxAtlasFrames; +import flixel.util.FlxTimer; using StringTools; @@ -54,6 +55,13 @@ class Boyfriend extends Character override function update(elapsed:Float) { + if (animation.curAnim.name.startsWith('sing')) + { + holdTimer += elapsed; + } + else + holdTimer = 0; + if (animation.curAnim.name.endsWith('miss') && animation.curAnim.finished && !debugMode) { playAnim('idle', true, false, 10); diff --git a/source/Character.hx b/source/Character.hx index 937fd310c..0a4efb038 100644 --- a/source/Character.hx +++ b/source/Character.hx @@ -3,6 +3,8 @@ package; import flixel.FlxSprite; import flixel.graphics.frames.FlxAtlasFrames; +using StringTools; + class Character extends FlxSprite { public var animOffsets:Map>; @@ -11,6 +13,8 @@ class Character extends FlxSprite public var isPlayer:Bool = false; public var curCharacter:String = 'bf'; + public var holdTimer:Float = 0; + public function new(x:Float, y:Float, ?character:String = "bf", ?isPlayer:Bool = false) { animOffsets = new Map>(); @@ -106,6 +110,29 @@ class Character extends FlxSprite } } + override function update(elapsed:Float) + { + if (curCharacter != 'bf') + { + if (animation.curAnim.name.startsWith('sing')) + { + holdTimer += elapsed; + } + + var dadVar:Float = 4; + + if (curCharacter == 'dad') + dadVar = 6.1; + if (holdTimer >= Conductor.stepCrochet * dadVar * 0.001) + { + dance(); + holdTimer = 0; + } + } + + super.update(elapsed); + } + private var danced:Bool = false; /** diff --git a/source/PlayState.hx b/source/PlayState.hx index 1eebd82f6..7d561b7e1 100644 --- a/source/PlayState.hx +++ b/source/PlayState.hx @@ -783,6 +783,8 @@ class PlayState extends MusicBeatState dad.playAnim('singLEFT', true); } + dad.holdTimer = 0; + if (SONG.needsVoices) vocals.volume = 1; @@ -1012,6 +1014,8 @@ class PlayState extends MusicBeatState // FlxG.watch.addQuick('asdfa', upP); if ((upP || rightP || downP || leftP) && !boyfriend.stunned && generatedMusic) { + boyfriend.holdTimer = 0; + var possibleNotes:Array = []; notes.forEachAlive(function(daNote:Note) @@ -1082,9 +1086,9 @@ class PlayState extends MusicBeatState }); } - if (upR || leftR || rightR || downR) + if (boyfriend.holdTimer > Conductor.stepCrochet * 4 * 0.001 && !up && !down && !right && !left) { - if (boyfriend.animation.curAnim.name.startsWith('sing')) + if (boyfriend.animation.curAnim.name.startsWith('sing') && !boyfriend.animation.curAnim.name.endsWith('miss')) { boyfriend.playAnim('idle'); } diff --git a/source/TitleState.hx b/source/TitleState.hx index a9b93c05c..f783a9b18 100644 --- a/source/TitleState.hx +++ b/source/TitleState.hx @@ -38,7 +38,7 @@ class TitleState extends MusicBeatState ['Ritz dx', 'rest in peace'], ['rate five', 'pls no blam'], ['rhythm gaming', 'ultimate'], ['game of the year', 'forever'], ['you already know', 'we really out here'], ['rise and grind', 'love to luis'], ['like parappa', 'but cooler'], ['album of the year', 'chuckie finster'], ["free gitaroo man", "with love to wandaboy"], ['better than geometry dash', 'fight me robtop'], - ['kiddbrute for president', 'vote now'], ['play dead estate', 'on newgrounds'], ['this is a god damn prototype', 'we workin on it okay'], + ['kiddbrute for president', 'vote now'], ['play dead estate', 'on newgrounds'], ['this a god damn prototype', 'we workin on it okay'], ['WOMEN ARE real', 'this is official']]; var curWacky:Array = []; From 5ecacb5a701219bc6ff85383058072902a742555 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Fri, 13 Nov 2020 14:37:58 -0800 Subject: [PATCH 15/35] moved the intro texts to a txt file --- CHANGELOG.md | 1 + Project.xml | 2 +- source/TitleState.hx | 27 +++++++++++++++++---------- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2944f1b8c..cdc98523c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Cleaned up some charting on South on hard mode - Fixed some animation timings, should feel both better to play, and watch. +- Maaaybe fixed notes popping up randomly at the top of the screen for a frame or two? If this isn't fixed, uhh yall shout at me lolol ## [0.2.1.2] - 2020-11-06 ### Fixed diff --git a/Project.xml b/Project.xml index e87c97ed4..e155283d0 100644 --- a/Project.xml +++ b/Project.xml @@ -2,7 +2,7 @@ - + diff --git a/source/TitleState.hx b/source/TitleState.hx index f783a9b18..519d92bf2 100644 --- a/source/TitleState.hx +++ b/source/TitleState.hx @@ -20,6 +20,7 @@ import flixel.tweens.FlxEase; import flixel.tweens.FlxTween; import flixel.util.FlxColor; import flixel.util.FlxTimer; +import lime.utils.Assets; class TitleState extends MusicBeatState { @@ -32,15 +33,6 @@ class TitleState extends MusicBeatState var textGroup:FlxGroup; var ngSpr:FlxSprite; - var wackyIntros:Array> = [ - ['Shoutouts to tom fulp', 'lmao'], ["Ludum dare", "extraordinaire"], ['Cyberzone', 'coming soon'], ['love to thriftman', 'swag'], - ['ULTIMATE RHYTHM GAMING', 'probably'], ['DOPE ASS GAME', 'playstation magazine'], ['in loving memory of', 'henryeyes'], ['dancin', 'forever'], - ['Ritz dx', 'rest in peace'], ['rate five', 'pls no blam'], ['rhythm gaming', 'ultimate'], ['game of the year', 'forever'], - ['you already know', 'we really out here'], ['rise and grind', 'love to luis'], ['like parappa', 'but cooler'], - ['album of the year', 'chuckie finster'], ["free gitaroo man", "with love to wandaboy"], ['better than geometry dash', 'fight me robtop'], - ['kiddbrute for president', 'vote now'], ['play dead estate', 'on newgrounds'], ['this a god damn prototype', 'we workin on it okay'], - ['WOMEN ARE real', 'this is official']]; - var curWacky:Array = []; var wackyImage:FlxSprite; @@ -53,7 +45,7 @@ class TitleState extends MusicBeatState PlayerSettings.init(); - curWacky = FlxG.random.getObject(wackyIntros); + curWacky = FlxG.random.getObject(getIntroTextShit()); // DEBUG BULLSHIT @@ -193,6 +185,21 @@ class TitleState extends MusicBeatState // credGroup.add(credTextShit); } + function getIntroTextShit():Array> + { + var fullText:String = Assets.getText('assets/data/introText.txt'); + + var firstArray:Array = fullText.split('\n'); + var swagGoodArray:Array> = []; + + for (i in firstArray) + { + swagGoodArray.push(i.split('--')); + } + + return swagGoodArray; + } + var transitioning:Bool = false; override function update(elapsed:Float) From ca629dd03eb9d2bb6632e519a8ad11db6a80019c Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Fri, 13 Nov 2020 14:39:28 -0800 Subject: [PATCH 16/35] changelog update --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cdc98523c..54627367c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Changed +- Moved all the intro texts to its own txt file instead of being hardcoded, this allows for much easier customization. File is in the data folder, called "introText.txt", follow the format in there and you're probably good to go! ### Fixed - Cleaned up some charting on South on hard mode - Fixed some animation timings, should feel both better to play, and watch. From c883f958b1783b72c5b76d93757767ae7ed50f60 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Fri, 13 Nov 2020 18:49:20 -0800 Subject: [PATCH 17/35] WIP shit for nicer charting hehe --- source/ChartingState.hx | 24 ++++++++++++++++-------- source/MusicBeatState.hx | 2 +- source/TitleState.hx | 2 +- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/source/ChartingState.hx b/source/ChartingState.hx index deeb34924..dac457586 100644 --- a/source/ChartingState.hx +++ b/source/ChartingState.hx @@ -374,16 +374,24 @@ class ChartingState extends MusicBeatState var updatedSection:Bool = false; + function lengthBpmBullshit():Float + { + if (_song.notes[curSection].changeBPM) + return _song.notes[curSection].lengthInSteps * (_song.notes[curSection].bpm / _song.bpm); + else + return _song.notes[curSection].lengthInSteps; + } + override function update(elapsed:Float) { Conductor.songPosition = FlxG.sound.music.time; _song.song = typingShit.text; - strumLine.y = getYfromStrum(Conductor.songPosition % (Conductor.stepCrochet * _song.notes[curSection].lengthInSteps)); + strumLine.y = getYfromStrum(Conductor.songPosition % (Conductor.stepCrochet * lengthBpmBullshit())); if (curBeat % 4 == 0) { - if (curStep > (_song.notes[curSection].lengthInSteps) * (curSection + 1)) + if (curStep > lengthBpmBullshit() * (curSection + 1)) { trace(curStep); trace((_song.notes[curSection].lengthInSteps) * (curSection + 1)); @@ -525,14 +533,14 @@ class ChartingState extends MusicBeatState vocals.pause(); var daNum:Int = 0; - var daLength:Int = 0; + var daLength:Float = 0; while (daNum <= sec) { - daLength += _song.notes[daNum].lengthInSteps; + daLength += lengthBpmBullshit(); daNum++; } - FlxG.sound.music.time = (daLength - (_song.notes[sec].lengthInSteps)) * Conductor.stepCrochet; + FlxG.sound.music.time = (daLength - lengthBpmBullshit()) * Conductor.stepCrochet; vocals.time = FlxG.sound.music.time; updateCurStep(); } @@ -620,7 +628,7 @@ class ChartingState extends MusicBeatState note.setGraphicSize(GRID_SIZE, GRID_SIZE); note.updateHitbox(); note.x = Math.floor(daNoteInfo * GRID_SIZE); - note.y = getYfromStrum(daStrumTime) % gridBG.height; + note.y = Math.floor(getYfromStrum(daStrumTime)) % gridBG.height; curRenderedNotes.add(note); @@ -691,7 +699,7 @@ class ChartingState extends MusicBeatState private function addNote():Void { - var noteStrum = Math.round(getStrumTime(dummyArrow.y) + (curSection * (Conductor.stepCrochet * 16))); + var noteStrum = getStrumTime(dummyArrow.y) + (curSection * (Conductor.stepCrochet * lengthBpmBullshit())); var noteData = Math.floor(FlxG.mouse.x / GRID_SIZE); var noteSus = 0; @@ -699,7 +707,7 @@ class ChartingState extends MusicBeatState curSelectedNote = _song.notes[curSection].sectionNotes[_song.notes[curSection].sectionNotes.length - 1]; - trace(getStrumTime(dummyArrow.y) + (curSection * (Conductor.stepCrochet * 16))); + trace(getStrumTime(dummyArrow.y) + (curSection * (Conductor.stepCrochet * lengthBpmBullshit())))); trace(curSection); updateGrid(); diff --git a/source/MusicBeatState.hx b/source/MusicBeatState.hx index 791cd95c7..0d9da14a5 100644 --- a/source/MusicBeatState.hx +++ b/source/MusicBeatState.hx @@ -34,7 +34,7 @@ class MusicBeatState extends FlxUIState everyStep(); updateCurStep(); - curBeat = Math.round(curStep / 4); + curBeat = Math.floor(curStep / 4); super.update(elapsed); } diff --git a/source/TitleState.hx b/source/TitleState.hx index 519d92bf2..f2f1fff33 100644 --- a/source/TitleState.hx +++ b/source/TitleState.hx @@ -68,7 +68,7 @@ class TitleState extends MusicBeatState } #if SKIP_TO_PLAYSTATE - FlxG.switchState(new StoryMenuState()); + FlxG.switchState(new ChartingState()); #else startIntro(); #end From 176e00b1179fca2a695931d0b99e0120e618faa1 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Fri, 13 Nov 2020 18:51:03 -0800 Subject: [PATCH 18/35] oop fix eheh --- source/ChartingState.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ChartingState.hx b/source/ChartingState.hx index dac457586..1dd6eb0b6 100644 --- a/source/ChartingState.hx +++ b/source/ChartingState.hx @@ -707,7 +707,7 @@ class ChartingState extends MusicBeatState curSelectedNote = _song.notes[curSection].sectionNotes[_song.notes[curSection].sectionNotes.length - 1]; - trace(getStrumTime(dummyArrow.y) + (curSection * (Conductor.stepCrochet * lengthBpmBullshit())))); + trace(getStrumTime(dummyArrow.y) + (curSection * (Conductor.stepCrochet * lengthBpmBullshit()))); trace(curSection); updateGrid(); From dcb69d2a612064dc41f5efc28bb6dcf1d616422e Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 17 Nov 2020 16:22:29 -0800 Subject: [PATCH 19/35] freeplay sounds --- CHANGELOG.md | 3 +++ source/ChartingState.hx | 7 +++++-- source/FreeplayState.hx | 23 +++++++++++++++++------ source/TitleState.hx | 2 +- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54627367c..017b82294 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added +- Music playing on the freeplay menu. +- UI sounds on freeplay menu ### Changed - Moved all the intro texts to its own txt file instead of being hardcoded, this allows for much easier customization. File is in the data folder, called "introText.txt", follow the format in there and you're probably good to go! ### Fixed diff --git a/source/ChartingState.hx b/source/ChartingState.hx index 1dd6eb0b6..08e16730e 100644 --- a/source/ChartingState.hx +++ b/source/ChartingState.hx @@ -391,7 +391,7 @@ class ChartingState extends MusicBeatState if (curBeat % 4 == 0) { - if (curStep > lengthBpmBullshit() * (curSection + 1)) + if (curStep > 16 * (curSection + 1)) { trace(curStep); trace((_song.notes[curSection].lengthInSteps) * (curSection + 1)); @@ -406,6 +406,9 @@ class ChartingState extends MusicBeatState } } + FlxG.watch.addQuick('daBeat', curBeat); + FlxG.watch.addQuick('daStep', curStep); + if (FlxG.mouse.justPressed) { if (FlxG.mouse.overlaps(curRenderedNotes)) @@ -699,7 +702,7 @@ class ChartingState extends MusicBeatState private function addNote():Void { - var noteStrum = getStrumTime(dummyArrow.y) + (curSection * (Conductor.stepCrochet * lengthBpmBullshit())); + var noteStrum = getStrumTime(dummyArrow.y) + (curSection * (Conductor.stepCrochet * 16)); var noteData = Math.floor(FlxG.mouse.x / GRID_SIZE); var noteSus = 0; diff --git a/source/FreeplayState.hx b/source/FreeplayState.hx index 5002fff57..f3bfe4b7d 100644 --- a/source/FreeplayState.hx +++ b/source/FreeplayState.hx @@ -24,14 +24,17 @@ class FreeplayState extends MusicBeatState var intendedScore:Int = 0; private var grpSongs:FlxTypedGroup; + private var curPlaying:Bool = false; override function create() { - if (FlxG.sound.music != null) - { - if (!FlxG.sound.music.playing) - FlxG.sound.playMusic('assets/music/freakyMenu' + TitleState.soundExt); - } + /* + if (FlxG.sound.music != null) + { + if (!FlxG.sound.music.playing) + FlxG.sound.playMusic('assets/music/freakyMenu' + TitleState.soundExt); + } + */ var isDebug:Bool = false; @@ -118,6 +121,11 @@ class FreeplayState extends MusicBeatState { super.update(elapsed); + if (FlxG.sound.music.volume < 0.7) + { + FlxG.sound.music.volume += 0.5 * FlxG.elapsed; + } + lerpScore = Math.floor(FlxMath.lerp(lerpScore, intendedScore, 0.4)); if (Math.abs(lerpScore - intendedScore) <= 10) @@ -187,7 +195,8 @@ class FreeplayState extends MusicBeatState function changeSelection(change:Int = 0) { - NGio.logEvent('Fresh'); + // NGio.logEvent('Fresh'); + FlxG.sound.play('assets/sounds/scrollMenu' + TitleState.soundExt, 0.4); curSelected += change; @@ -201,6 +210,8 @@ class FreeplayState extends MusicBeatState intendedScore = Highscore.getScore(songs[curSelected], curDifficulty); // lerpScore = 0; + FlxG.sound.playMusic('assets/music/' + songs[curSelected] + "_Inst" + TitleState.soundExt, 0); + var bullShit:Int = 0; for (item in grpSongs.members) diff --git a/source/TitleState.hx b/source/TitleState.hx index f2f1fff33..f93f061ec 100644 --- a/source/TitleState.hx +++ b/source/TitleState.hx @@ -68,7 +68,7 @@ class TitleState extends MusicBeatState } #if SKIP_TO_PLAYSTATE - FlxG.switchState(new ChartingState()); + FlxG.switchState(new FreeplayState()); #else startIntro(); #end From acc1382023855bf2dc5497b3d7a182f73660676b Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 17 Nov 2020 17:32:38 -0800 Subject: [PATCH 20/35] score on song --- CHANGELOG.md | 2 ++ source/PlayState.hx | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 017b82294..32f3c3029 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Music playing on the freeplay menu. - UI sounds on freeplay menu +- Score now shows mid-song. + ### Changed - Moved all the intro texts to its own txt file instead of being hardcoded, this allows for much easier customization. File is in the data folder, called "introText.txt", follow the format in there and you're probably good to go! ### Fixed diff --git a/source/PlayState.hx b/source/PlayState.hx index 7d561b7e1..71297289e 100644 --- a/source/PlayState.hx +++ b/source/PlayState.hx @@ -83,6 +83,7 @@ class PlayState extends MusicBeatState var talking:Bool = true; var songScore:Int = 0; + var scoreTxt:FlxText; public static var campaignScore:Int = 0; @@ -252,6 +253,11 @@ class PlayState extends MusicBeatState // healthBar add(healthBar); + scoreTxt = new FlxText(healthBarBG.x + healthBarBG.width - 190, healthBarBG.y + 30, 0, "", 20); + scoreTxt.setFormat("assets/fonts/vcr.ttf", 16, FlxColor.WHITE, RIGHT); + scoreTxt.scrollFactor.set(); + add(scoreTxt); + healthHeads = new FlxSprite(); var headTex = FlxAtlasFrames.fromSparrow(AssetPaths.healthHeads__png, AssetPaths.healthHeads__xml); healthHeads.frames = headTex; @@ -277,6 +283,7 @@ class PlayState extends MusicBeatState healthBar.cameras = [camHUD]; healthBarBG.cameras = [camHUD]; healthHeads.cameras = [camHUD]; + scoreTxt.cameras = [camHUD]; doof.cameras = [camHUD]; // if (SONG.song == 'South') @@ -586,6 +593,8 @@ class PlayState extends MusicBeatState { super.update(elapsed); + scoreTxt.text = "Score:" + songScore; + if (FlxG.keys.justPressed.ENTER && startedCountdown) { persistentUpdate = false; From 2462ae555e383c58fa48d7967df8673f9f61b66b Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 17 Nov 2020 17:50:09 -0800 Subject: [PATCH 21/35] pause menu in progress --- source/PauseSubState.hx | 84 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 74 insertions(+), 10 deletions(-) diff --git a/source/PauseSubState.hx b/source/PauseSubState.hx index dbf232b6d..2fdbefbf7 100644 --- a/source/PauseSubState.hx +++ b/source/PauseSubState.hx @@ -4,11 +4,17 @@ import Controls.Control; import flixel.FlxG; import flixel.FlxSprite; import flixel.FlxSubState; +import flixel.group.FlxGroup.FlxTypedGroup; import flixel.input.keyboard.FlxKey; import flixel.util.FlxColor; -class PauseSubState extends FlxSubState +class PauseSubState extends MusicBeatSubstate { + var grpMenuShit:FlxTypedGroup; + + var menuItems:Array = ['Resume', 'Restart Song', 'Exit to menu']; + var curSelected:Int = 0; + public function new(x:Float, y:Float) { super(); @@ -17,25 +23,83 @@ class PauseSubState extends FlxSubState bg.scrollFactor.set(); add(bg); - var bf:Boyfriend = new Boyfriend(x, y); - bf.scrollFactor.set(); - // add(bf); + grpMenuShit = new FlxTypedGroup(); + add(grpMenuShit); - bf.playAnim('firstDeath'); + for (i in 0...menuItems.length) + { + var songText:Alphabet = new Alphabet(0, (70 * i) + 30, menuItems[i], true, false); + songText.isMenuItem = true; + songText.targetY = i; + grpMenuShit.add(songText); + } - bg.cameras = [FlxG.cameras.list[1]]; + changeSelection(); + + cameras = [FlxG.cameras.list[1]]; } override function update(elapsed:Float) { super.update(elapsed); - if (FlxG.keys.justPressed.J) + var upP = controls.UP_P; + var downP = controls.DOWN_P; + var accepted = controls.ACCEPT; + + if (upP) { - PlayerSettings.player1.controls.replaceBinding(Control.LEFT, Keys, FlxKey.J, null); + changeSelection(-1); + } + if (downP) + { + changeSelection(1); } - if (FlxG.keys.justPressed.ENTER) - close(); + if (accepted) + { + var daSelected:String = menuItems[curSelected]; + + switch (daSelected) + { + case "Resume": + close(); + case "Exit to menu": + FlxG.switchState(new MainMenuState()); + } + } + + if (FlxG.keys.justPressed.J) + { + // for reference later! + // PlayerSettings.player1.controls.replaceBinding(Control.LEFT, Keys, FlxKey.J, null); + } + } + + function changeSelection(change:Int = 0):Void + { + curSelected += change; + + if (curSelected < 0) + curSelected = menuItems.length - 1; + if (curSelected >= menuItems.length) + curSelected = 0; + + var bullShit:Int = 0; + + for (item in grpMenuShit.members) + { + item.targetY = bullShit - curSelected; + bullShit++; + + item.alpha = 0.6; + // item.setGraphicSize(Std.int(item.width * 0.8)); + + if (item.targetY == 0) + { + item.alpha = 1; + // item.setGraphicSize(Std.int(item.width)); + } + } } } From 3a1a410fe2b66977c6fb925846548c69a7aba501 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 17 Nov 2020 18:20:27 -0800 Subject: [PATCH 22/35] restart on pause menu --- source/PauseSubState.hx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/PauseSubState.hx b/source/PauseSubState.hx index 2fdbefbf7..efc9a716c 100644 --- a/source/PauseSubState.hx +++ b/source/PauseSubState.hx @@ -64,6 +64,8 @@ class PauseSubState extends MusicBeatSubstate { case "Resume": close(); + case "Restart Song": + FlxG.resetState(); case "Exit to menu": FlxG.switchState(new MainMenuState()); } From a0d99945df4e59bc0e851a5b9a83257726440694 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 17 Nov 2020 18:31:59 -0800 Subject: [PATCH 23/35] fix for #12 --- source/MusicBeatState.hx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/MusicBeatState.hx b/source/MusicBeatState.hx index 0d9da14a5..23d2b6b91 100644 --- a/source/MusicBeatState.hx +++ b/source/MusicBeatState.hx @@ -64,6 +64,13 @@ class MusicBeatState extends FlxUIState totalSteps += 1; lastStep += Conductor.stepCrochet; + // If the song is at least 3 steps behind + if (Conductor.songPosition > lastStep + (Conductor.stepCrochet * 3)) + { + lastStep = Conductor.songPosition; + totalSteps = Math.round(lastStep / Conductor.stepCrochet); + } + if (totalSteps % 4 == 0) beatHit(); } From 566e15e4af25512ec5d4bfc37dbddbb46a042871 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 17 Nov 2020 22:27:04 -0800 Subject: [PATCH 24/35] good website --- CHANGELOG.md | 1 + docs/index.html | 16 +++++++++++----- docs/styles.css | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 docs/styles.css diff --git a/CHANGELOG.md b/CHANGELOG.md index 32f3c3029..46b8e2b42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Cleaned up some charting on South on hard mode - Fixed some animation timings, should feel both better to play, and watch. - Maaaybe fixed notes popping up randomly at the top of the screen for a frame or two? If this isn't fixed, uhh yall shout at me lolol +- Animation issue where GF would freak out on the title screen if you returned to it. ## [0.2.1.2] - 2020-11-06 ### Fixed diff --git a/docs/index.html b/docs/index.html index b6ec87fd2..0ab3d9706 100644 --- a/docs/index.html +++ b/docs/index.html @@ -13,7 +13,7 @@ Friday Night Funkin' - + @@ -22,13 +22,19 @@
- Friday Night Funkin + Friday Night Funkin
- -

Friday Night Funkin the video game

- +

Friday Night Funkin' - Rhythm game extraordinaire

+ +
+ +

Friday Night Funkin' is a dope ass rhythm game.

+
+
\ No newline at end of file diff --git a/docs/styles.css b/docs/styles.css new file mode 100644 index 000000000..185734193 --- /dev/null +++ b/docs/styles.css @@ -0,0 +1,38 @@ +.coolBox { + background: #1a1a1a; + margin: 40px 4vw; + padding: 25px; + font-size: 120%; + border-radius: 10px; +} + +#wrapper +{ + padding: 25px; + margin: auto; +} + +marquee { + margin: auto; + text-align: center; +} + +h1 { + text-align: center; +} + +iframe { + margin: auto; + width: 40%; + display:block; +} + +body { + background-image: url('http://img.ngfiles.com/themes/000/skin-funkin-cardbordtoast.jpg?1605135609'); + background-repeat: no-repeat; + background-attachment: fixed; + background-size: cover; + background-size: 100% 130%; + color:white; + background-color: #000; +} \ No newline at end of file From 654ceb99e019b9501cf4f2e20c5435f0fd838dc9 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 17 Nov 2020 23:31:37 -0800 Subject: [PATCH 25/35] cool website colors --- docs/index.html | 9 ++++++++- docs/styles.css | 37 ++++++++++++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/docs/index.html b/docs/index.html index 0ab3d9706..a4ab1f179 100644 --- a/docs/index.html +++ b/docs/index.html @@ -31,9 +31,16 @@ allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen>
-

Friday Night Funkin' is a dope ass rhythm game.

+ + + + diff --git a/docs/styles.css b/docs/styles.css index 185734193..3c159f8f9 100644 --- a/docs/styles.css +++ b/docs/styles.css @@ -1,5 +1,5 @@ .coolBox { - background: #1a1a1a; + background: #1a1a1aCC; margin: 40px 4vw; padding: 25px; font-size: 120%; @@ -23,7 +23,6 @@ h1 { iframe { margin: auto; - width: 40%; display:block; } @@ -35,4 +34,36 @@ body { background-size: 100% 130%; color:white; background-color: #000; -} \ No newline at end of file + font-family: Arial, Helvetica, sans-serif; + +} + +a { color:inherit; + text-decoration: none;} + +.linktext { + text-align: center; + display:block; + font-size: 130%; + +} + +.linktext a { + font-weight: bold; + color:white; + text-shadow: 0px 0px #00000077; + transition: color 1s, text-shadow 1s; + +} + +.linktext a:hover { + + border-radius: 5px; + text-shadow: 2px 2px #00000077; + color: #ffb50e; +} + +#itch a:hover +{ + color: #fa5c5c; +} From ea047db8d1bf4fd10ce3de18f60b9edc7c09e946 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 18 Nov 2020 02:58:19 -0800 Subject: [PATCH 26/35] better image? --- docs/img/skin-funkin-cardbordtoast.jpg | Bin 0 -> 237156 bytes docs/styles.css | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 docs/img/skin-funkin-cardbordtoast.jpg diff --git a/docs/img/skin-funkin-cardbordtoast.jpg b/docs/img/skin-funkin-cardbordtoast.jpg new file mode 100644 index 0000000000000000000000000000000000000000..dd0e96e606b5fcf83f912e0a4e43bc05a9f92364 GIT binary patch literal 237156 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 B%Deyo literal 0 HcmV?d00001 diff --git a/docs/styles.css b/docs/styles.css index 3c159f8f9..42d86e7e3 100644 --- a/docs/styles.css +++ b/docs/styles.css @@ -27,7 +27,7 @@ iframe { } body { - background-image: url('http://img.ngfiles.com/themes/000/skin-funkin-cardbordtoast.jpg?1605135609'); + background-image: url('img/skin-funkin-cardbordtoast.jpg'); background-repeat: no-repeat; background-attachment: fixed; background-size: cover; From b9011bdcfb3fb7f3b8719df1d1bfceb6f16cc21d Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 18 Nov 2020 15:35:28 -0800 Subject: [PATCH 27/35] fluid video --- docs/index.html | 13 ++++++++++--- docs/styles.css | 30 +++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/docs/index.html b/docs/index.html index a4ab1f179..fd6d7440f 100644 --- a/docs/index.html +++ b/docs/index.html @@ -27,9 +27,16 @@

Friday Night Funkin' - Rhythm game extraordinaire

- + +
+
+ +
+
+ +

Friday Night Funkin' is a dope ass rhythm game.

diff --git a/docs/styles.css b/docs/styles.css index 42d86e7e3..3d6536204 100644 --- a/docs/styles.css +++ b/docs/styles.css @@ -8,7 +8,7 @@ #wrapper { - padding: 25px; + padding: 20px; margin: auto; } @@ -21,17 +21,11 @@ h1 { text-align: center; } -iframe { - margin: auto; - display:block; -} - body { background-image: url('img/skin-funkin-cardbordtoast.jpg'); background-repeat: no-repeat; background-attachment: fixed; background-size: cover; - background-size: 100% 130%; color:white; background-color: #000; font-family: Arial, Helvetica, sans-serif; @@ -67,3 +61,25 @@ a { color:inherit; { color: #fa5c5c; } + +#coolervidwrapper { + padding-left: min(12em, 75%); + padding-right: min(12em, 75%); + min-width: 30%; +} + +.videoWrapper { + position: relative; + padding-bottom: 56.25%; /* 16:9 */ + height: 0; + + max-block-size: 1400px; +} +.videoWrapper iframe { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + +} From a8392e2554c78f1f8a97cd4e468e47cf75b89148 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 18 Nov 2020 15:36:44 -0800 Subject: [PATCH 28/35] padding fix --- docs/styles.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/styles.css b/docs/styles.css index 3d6536204..77178040c 100644 --- a/docs/styles.css +++ b/docs/styles.css @@ -39,7 +39,7 @@ a { color:inherit; text-align: center; display:block; font-size: 130%; - + padding-bottom: 10px; } .linktext a { From 3451d1ce5bba4f36b3958bec681887081f731bed Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 18 Nov 2020 15:51:43 -0800 Subject: [PATCH 29/35] icon, and credits --- docs/index.html | 14 ++++++++++---- docs/styles.css | 28 ++++++++++++++++++++-------- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/docs/index.html b/docs/index.html index fd6d7440f..11137c674 100644 --- a/docs/index.html +++ b/docs/index.html @@ -15,6 +15,7 @@ + @@ -22,11 +23,12 @@
- Friday Night Funkin + Friday Night Funkin

Friday Night Funkin' - Rhythm game extraordinaire

+
@@ -37,15 +39,19 @@
-
+

Friday Night Funkin' is a dope ass rhythm game.

+

It is made by ninjamuffin99 (programmer), PhantomArcade (animator), evilsk8r (artist), + and Kawaisprite (musician) originally for Ludum Dare 47.

-
+ -
+ diff --git a/docs/styles.css b/docs/styles.css index 77178040c..5ee1062fb 100644 --- a/docs/styles.css +++ b/docs/styles.css @@ -15,6 +15,7 @@ marquee { margin: auto; text-align: center; + display: inline-block; } h1 { @@ -35,6 +36,19 @@ body { a { color:inherit; text-decoration: none;} + +.hovertext a{ + color:white; + text-shadow: 0px 0px #00000077; + transition: color 1s, text-shadow 1s; +} + +.hovertext a:hover +{ + text-shadow: 2px 2px #00000077; + color: #ffb50e; +} + .linktext { text-align: center; display:block; @@ -43,24 +57,22 @@ a { color:inherit; } .linktext a { - font-weight: bold; - color:white; - text-shadow: 0px 0px #00000077; - transition: color 1s, text-shadow 1s; - + font-weight: bold; } .linktext a:hover { - border-radius: 5px; - text-shadow: 2px 2px #00000077; - color: #ffb50e; } #itch a:hover { color: #fa5c5c; } +#twitter a:hover +{ + color: #00acee; +} + #coolervidwrapper { padding-left: min(12em, 75%); From 36b0302ac42d5c734af20f23dd9da61409d844d8 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Fri, 20 Nov 2020 04:21:04 -0800 Subject: [PATCH 30/35] cool pause music --- source/MusicBeatState.hx | 5 +++-- source/PauseSubState.hx | 20 ++++++++++++++++++++ source/PlayState.hx | 5 ++++- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/source/MusicBeatState.hx b/source/MusicBeatState.hx index 23d2b6b91..029a495b8 100644 --- a/source/MusicBeatState.hx +++ b/source/MusicBeatState.hx @@ -34,7 +34,8 @@ class MusicBeatState extends FlxUIState everyStep(); updateCurStep(); - curBeat = Math.floor(curStep / 4); + // Needs to be ROUNED, rather than ceil or floor + curBeat = Math.round(curStep / 4); super.update(elapsed); } @@ -68,7 +69,7 @@ class MusicBeatState extends FlxUIState if (Conductor.songPosition > lastStep + (Conductor.stepCrochet * 3)) { lastStep = Conductor.songPosition; - totalSteps = Math.round(lastStep / Conductor.stepCrochet); + totalSteps = Math.ceil(lastStep / Conductor.stepCrochet); } if (totalSteps % 4 == 0) diff --git a/source/PauseSubState.hx b/source/PauseSubState.hx index efc9a716c..1c7297043 100644 --- a/source/PauseSubState.hx +++ b/source/PauseSubState.hx @@ -6,6 +6,7 @@ import flixel.FlxSprite; import flixel.FlxSubState; import flixel.group.FlxGroup.FlxTypedGroup; import flixel.input.keyboard.FlxKey; +import flixel.system.FlxSound; import flixel.util.FlxColor; class PauseSubState extends MusicBeatSubstate @@ -15,9 +16,18 @@ class PauseSubState extends MusicBeatSubstate var menuItems:Array = ['Resume', 'Restart Song', 'Exit to menu']; var curSelected:Int = 0; + var pauseMusic:FlxSound; + public function new(x:Float, y:Float) { super(); + + pauseMusic = new FlxSound().loadEmbedded('assets/music/breakfast' + TitleState.soundExt, true, true); + pauseMusic.volume = 0; + pauseMusic.play(false, FlxG.random.int(0, Std.int(pauseMusic.length / 2))); + + FlxG.sound.list.add(pauseMusic); + var bg:FlxSprite = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); bg.alpha = 0.6; bg.scrollFactor.set(); @@ -41,6 +51,9 @@ class PauseSubState extends MusicBeatSubstate override function update(elapsed:Float) { + if (pauseMusic.volume < 0.5) + pauseMusic.volume += 0.01 * elapsed; + super.update(elapsed); var upP = controls.UP_P; @@ -78,6 +91,13 @@ class PauseSubState extends MusicBeatSubstate } } + override function destroy() + { + pauseMusic.destroy(); + + super.destroy(); + } + function changeSelection(change:Int = 0):Void { curSelected += change; diff --git a/source/PlayState.hx b/source/PlayState.hx index 71297289e..0aaba0112 100644 --- a/source/PlayState.hx +++ b/source/PlayState.hx @@ -588,6 +588,7 @@ class PlayState extends MusicBeatState private var paused:Bool = false; var startedCountdown:Bool = false; + var canPause:Bool = true; override public function update(elapsed:Float) { @@ -595,7 +596,7 @@ class PlayState extends MusicBeatState scoreTxt.text = "Score:" + songScore; - if (FlxG.keys.justPressed.ENTER && startedCountdown) + if (FlxG.keys.justPressed.ENTER && startedCountdown && canPause) { persistentUpdate = false; persistentDraw = true; @@ -830,6 +831,8 @@ class PlayState extends MusicBeatState function endSong():Void { + canPause = false; + Highscore.saveScore(SONG.song, songScore, storyDifficulty); if (isStoryMode) From 02efb588b798c8478ec7e2bb2cc00cc3b66f3e00 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Fri, 20 Nov 2020 04:21:54 -0800 Subject: [PATCH 31/35] Updated Changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 46b8e2b42..007397f58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Music playing on the freeplay menu. - UI sounds on freeplay menu - Score now shows mid-song. +- Menu on pause screen! Can resume, and restart song, or go back to main menu. +- New music made for pause menu! ### Changed - Moved all the intro texts to its own txt file instead of being hardcoded, this allows for much easier customization. File is in the data folder, called "introText.txt", follow the format in there and you're probably good to go! From 4e9afb528cd42a356175de4855da3b2f1148f8db Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Fri, 20 Nov 2020 04:33:07 -0800 Subject: [PATCH 32/35] changelog shoutsouts --- CHANGELOG.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 007397f58..22f91206c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [0.2.2] - 2020-11-20 ### Added - Music playing on the freeplay menu. - UI sounds on freeplay menu @@ -15,10 +15,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Moved all the intro texts to its own txt file instead of being hardcoded, this allows for much easier customization. File is in the data folder, called "introText.txt", follow the format in there and you're probably good to go! ### Fixed +- Fixed soft lock when pausing on song finish ([shoutouts gedehari](https://github.com/ninjamuffin99/Funkin/issues/15)) +- Think I fixed issue that led to in-game scores being off by 2 ([shoutouts Mike](https://github.com/ninjamuffin99/Funkin/issues/4)) +- Should have fixed the 1 frame note appearance thing. ([shoutouts Mike](https://github.com/ninjamuffin99/Funkin/issues/6)) - Cleaned up some charting on South on hard mode -- Fixed some animation timings, should feel both better to play, and watch. -- Maaaybe fixed notes popping up randomly at the top of the screen for a frame or two? If this isn't fixed, uhh yall shout at me lolol -- Animation issue where GF would freak out on the title screen if you returned to it. +- Fixed some animation timings, should feel both better to play, and watch. (shoutouts Dave/Ivan lol) +- Animation issue where GF would freak out on the title screen if you returned to it([shoutouts MultiXIII](https://github.com/ninjamuffin99/Funkin/issues/12)). ## [0.2.1.2] - 2020-11-06 ### Fixed From 3529fbd25fca987698a63ef46c9dfa2ef4cbc9c7 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Sat, 21 Nov 2020 02:43:04 -0800 Subject: [PATCH 33/35] MAYBE DOIN CHART SHIT? --- source/ChartingState.hx | 24 ++++++++++++++++++++++++ source/MusicBeatState.hx | 7 ++++++- source/TitleState.hx | 2 +- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/source/ChartingState.hx b/source/ChartingState.hx index 08e16730e..f83eae315 100644 --- a/source/ChartingState.hx +++ b/source/ChartingState.hx @@ -384,6 +384,8 @@ class ChartingState extends MusicBeatState override function update(elapsed:Float) { + curStep = recalculateSteps(); + Conductor.songPosition = FlxG.sound.music.time; _song.song = typingShit.text; @@ -520,6 +522,28 @@ class ChartingState extends MusicBeatState super.update(elapsed); } + function recalculateSteps():Int + { + var steps:Int = 0; + var timeShit:Float = 0; + + for (i in 0...curSection) + { + steps += 16; + + if (_song.notes[i].changeBPM) + timeShit += (((60 / _song.notes[i].bpm) * 1000) / 4) * 16; + else + timeShit += (((60 / _song.bpm) * 1000) / 4) * 16; + } + + steps += Math.floor((FlxG.sound.music.time - timeShit) / Conductor.stepCrochet); + curStep = steps; + updateBeat(); + + return curStep; + } + function changeSection(sec:Int = 0, ?updateMusic:Bool = true):Void { trace('changing section' + sec); diff --git a/source/MusicBeatState.hx b/source/MusicBeatState.hx index 029a495b8..0d3862002 100644 --- a/source/MusicBeatState.hx +++ b/source/MusicBeatState.hx @@ -35,11 +35,16 @@ class MusicBeatState extends FlxUIState updateCurStep(); // Needs to be ROUNED, rather than ceil or floor - curBeat = Math.round(curStep / 4); + updateBeat(); super.update(elapsed); } + private function updateBeat():Void + { + curBeat = Math.round(curStep / 4); + } + /** * CHECKS EVERY FRAME */ diff --git a/source/TitleState.hx b/source/TitleState.hx index f93f061ec..f2f1fff33 100644 --- a/source/TitleState.hx +++ b/source/TitleState.hx @@ -68,7 +68,7 @@ class TitleState extends MusicBeatState } #if SKIP_TO_PLAYSTATE - FlxG.switchState(new FreeplayState()); + FlxG.switchState(new ChartingState()); #else startIntro(); #end From 6f79dd445a862e9bc64a2cb125d76475cfedb88c Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Sun, 22 Nov 2020 12:39:32 -0800 Subject: [PATCH 34/35] fixed URL thing for linux --- source/MainMenuState.hx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/MainMenuState.hx b/source/MainMenuState.hx index 305508b4f..d4db472ee 100644 --- a/source/MainMenuState.hx +++ b/source/MainMenuState.hx @@ -109,7 +109,14 @@ class MainMenuState extends MusicBeatState { if (optionShit[curSelected] == 'donate') { + #if linux + Sys.command('/usr/bin/xdg-open", [url, "&"]); + #else + + FlxG.openURL('https://ninja-muffin24.itch.io/funkin'); + #end + } else { From 7d975293b2a9ec017ba5efc37e714f514a36ae9b Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Sun, 22 Nov 2020 12:52:09 -0800 Subject: [PATCH 35/35] fixed quotation mark lol --- source/MainMenuState.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/MainMenuState.hx b/source/MainMenuState.hx index d4db472ee..518181675 100644 --- a/source/MainMenuState.hx +++ b/source/MainMenuState.hx @@ -110,7 +110,7 @@ class MainMenuState extends MusicBeatState if (optionShit[curSelected] == 'donate') { #if linux - Sys.command('/usr/bin/xdg-open", [url, "&"]); + Sys.command('/usr/bin/xdg-open', ["https://ninja-muffin24.itch.io/funkin", "&"]); #else