diff --git a/.haxerc b/.haxerc deleted file mode 100644 index 714054662..000000000 --- a/.haxerc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "version": "4.2.5", - "resolveLibs": "scoped" -} \ No newline at end of file diff --git a/source/funkin/FreeplayState.hx b/source/funkin/FreeplayState.hx index 622625f16..8a635bfda 100644 --- a/source/funkin/FreeplayState.hx +++ b/source/funkin/FreeplayState.hx @@ -1,5 +1,6 @@ package funkin; +import funkin.ui.StickerSubState; import flash.text.TextField; import flixel.FlxCamera; import flixel.FlxGame; @@ -73,10 +74,35 @@ class FreeplayState extends MusicBeatSubstate var typing:FlxInputText; var exitMovers:Map, MoveData> = new Map(); - override function create() + var stickerSubState:StickerSubState; + + public function new(?stickers:StickerSubState = null) { + if (stickers != null) + { + stickerSubState = stickers; + } + + super(); + } + + override function create():Void + { + super.create(); + FlxTransitionableState.skipNextTransIn = true; + if (stickerSubState != null) + { + this.persistentUpdate = true; + this.persistentDraw = true; + + openSubState(stickerSubState); + stickerSubState.degenStickers(); + + // resetSubState(); + } + #if discord_rpc // Updating Discord Rich Presence DiscordClient.changePresence("In the Menus", null); @@ -429,8 +455,6 @@ class FreeplayState extends MusicBeatSubstate forEach(function(bs) { bs.cameras = [funnyCam]; }); - - super.create(); } public function generateSongList(?filterStuff:SongFilter, ?force:Bool = false) diff --git a/source/funkin/PauseSubState.hx b/source/funkin/PauseSubState.hx index ffba8f0c2..747335943 100644 --- a/source/funkin/PauseSubState.hx +++ b/source/funkin/PauseSubState.hx @@ -35,7 +35,7 @@ class PauseSubState extends MusicBeatSubstate var bg:FlxSprite; var metaDataGrp:FlxTypedGroup; - public function new(x:Float, y:Float) + public function new() { super(); @@ -222,21 +222,12 @@ class PauseSubState extends MusicBeatSubstate item.alpha = 0.6; } - FlxTween.tween(bg, {alpha: 1}, 0.4, - { - ease: FlxEase.quartInOut, - onComplete: function(_) - { - FlxTransitionableState.skipNextTransIn = true; - FlxTransitionableState.skipNextTransOut = true; + FlxTransitionableState.skipNextTransIn = true; + FlxTransitionableState.skipNextTransOut = true; - FlxG.cameras.list[1].alpha = 0; // bullshit for the UI camera??? - - if (PlayState.isStoryMode) FlxG.switchState(new StoryMenuState()); - else - FlxG.switchState(new FreeplayState()); - } - }); + if (PlayState.isStoryMode) openSubState(new funkin.ui.StickerSubState(null, STORY)); + else + openSubState(new funkin.ui.StickerSubState()); } } diff --git a/source/funkin/StoryMenuState.hx b/source/funkin/StoryMenuState.hx index 7e2be322d..d9640d620 100644 --- a/source/funkin/StoryMenuState.hx +++ b/source/funkin/StoryMenuState.hx @@ -15,6 +15,7 @@ import funkin.play.PlayState; import funkin.play.song.SongData.SongDataParser; import lime.net.curl.CURLCode; import openfl.Assets; +import funkin.ui.StickerSubState; #if discord_rpc import Discord.DiscordClient; #end @@ -86,6 +87,18 @@ class StoryMenuState extends MusicBeatState var yellowBG:FlxSprite; // not actually, yellow, lol! var targetColor:Int = 0xFFF9CF51; + var stickerSubState:StickerSubState; + + public function new(?stickers:StickerSubState = null) + { + if (stickers != null) + { + stickerSubState = stickers; + } + + super(); + } + override function create() { transIn = FlxTransitionableState.defaultTransIn; @@ -96,6 +109,17 @@ class StoryMenuState extends MusicBeatState if (!FlxG.sound.music.playing) FlxG.sound.playMusic(Paths.music('freakyMenu')); } + if (stickerSubState != null) + { + this.persistentUpdate = true; + this.persistentDraw = true; + + openSubState(stickerSubState); + stickerSubState.degenStickers(); + + // resetSubState(); + } + persistentUpdate = persistentDraw = true; scoreText = new FlxText(10, 10, 0, "SCORE: 49324858", 36); @@ -293,8 +317,7 @@ class StoryMenuState extends MusicBeatState difficultySelectors.visible = weekUnlocked[curWeek]; - grpLocks.forEach(function(lock:FlxSprite) - { + grpLocks.forEach(function(lock:FlxSprite) { lock.y = grpWeekText.members[lock.ID].y; }); @@ -380,8 +403,7 @@ class StoryMenuState extends MusicBeatState }; SongLoad.curDiff = PlayState.storyDifficulty_NEW; - new FlxTimer().start(1, function(tmr:FlxTimer) - { + new FlxTimer().start(1, function(tmr:FlxTimer) { LoadingState.loadAndSwitchState(new PlayState(), true); }); } diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 8e51db8a0..1f62b71ed 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -1512,7 +1512,7 @@ class PlayState extends MusicBeatState else { var boyfriendPos = currentStage.getBoyfriend().getScreenPosition(); - var pauseSubState = new PauseSubState(boyfriendPos.x, boyfriendPos.y); + var pauseSubState = new PauseSubState(); openSubState(pauseSubState); pauseSubState.camera = camHUD; boyfriendPos.put(); diff --git a/source/funkin/ui/StickerSubState.hx b/source/funkin/ui/StickerSubState.hx new file mode 100644 index 000000000..b300640a4 --- /dev/null +++ b/source/funkin/ui/StickerSubState.hx @@ -0,0 +1,358 @@ +package funkin.ui; + +import flixel.FlxSprite; +import haxe.Json; +import lime.utils.Assets; +// import flxtyped group +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.util.FlxTimer; +import flixel.FlxG; +import flixel.math.FlxMath; +import flixel.util.FlxSort; +import flixel.util.FlxSignal; +import flixel.addons.transition.FlxTransitionableState; +import openfl.display.BitmapData; +import openfl.geom.Matrix; +import openfl.display.Sprite; +import openfl.display.Bitmap; + +class StickerSubState extends MusicBeatSubstate +{ + public var grpStickers:FlxTypedGroup; + + // yes... a damn OpenFL sprite!!! + public var dipshit:Sprite; + + var nextState:NEXTSTATE = FREEPLAY; + + public function new(?oldStickers:Array, ?nextState:NEXTSTATE = FREEPLAY):Void + { + super(); + + this.nextState = nextState; + + grpStickers = new FlxTypedGroup(); + add(grpStickers); + + // makes the stickers on the most recent camera, which is more often than not... a UI camera!! + grpStickers.cameras = [FlxG.cameras.list[FlxG.cameras.list.length - 1]]; + + if (oldStickers != null) + { + for (sticker in oldStickers) + { + grpStickers.add(sticker); + trace(sticker); + } + + degenStickers(); + } + else + regenStickers(); + } + + public function degenStickers():Void + { + grpStickers.cameras = FlxG.cameras.list; + + if (dipshit != null) + { + FlxG.removeChild(dipshit); + dipshit = null; + } + + for (ind => sticker in grpStickers.members) + { + new FlxTimer().start(sticker.timing, _ -> { + sticker.visible = false; + + if (ind == grpStickers.members.length - 1) + { + switchingState = false; + close(); + } + }); + } + } + + function regenStickers():Void + { + if (grpStickers.members.length > 0) + { + grpStickers.clear(); + } + + var stickerInfo:StickerInfo = new StickerInfo('stickers-set-1'); + var stickers:Map> = new Map>(); + for (stickerSets in stickerInfo.getPack("all")) + { + stickers.set(stickerSets, stickerInfo.getStickers(stickerSets)); + + trace(stickers); + + // for (stickerShit in stickerInfo.getStickers(stickerSets)) + // { + // // for loop jus to repeat it easy easy easy + // for (i in 0...FlxG.random.int(1, 5)) + // { + // var sticky:StickerSprite = new StickerSprite(0, 0, stickerInfo.name, stickerShit); + // sticky.x -= sticky.width / 2; + // sticky.y -= sticky.height * 0.9; + + // // random location by default + // sticky.x += FlxG.random.float(0, FlxG.width); + // sticky.y += FlxG.random.float(0, FlxG.height); + + // sticky.visible = false; + // sticky.scrollFactor.set(); + // sticky.angle = FlxG.random.int(-60, 70); + // // sticky.flipX = FlxG.random.bool(); + // grpStickers.add(sticky); + + // sticky.timing = FlxG.random.float(0, 0.8); + // } + // } + } + + var xPos:Float = -100; + var yPos:Float = -100; + while (xPos <= FlxG.width) + { + var stickerSet:String = FlxG.random.getObject(stickers.keyValues()); + var sticker:String = FlxG.random.getObject(stickers.get(stickerSet)); + var sticky:StickerSprite = new StickerSprite(0, 0, stickerInfo.name, sticker); + sticky.visible = false; + + sticky.x = xPos; + sticky.y = yPos; + xPos += sticky.frameWidth * 0.5; + + if (xPos >= FlxG.width) + { + if (yPos <= FlxG.height) + { + xPos = -100; + yPos += FlxG.random.float(70, 120); + } + } + + sticky.angle = FlxG.random.int(-60, 70); + grpStickers.add(sticky); + } + + FlxG.random.shuffle(grpStickers.members); + + // var stickerCount:Int = 0; + + // for (w in 0...6) + // { + // var xPos:Float = FlxG.width * (w / 6); + // for (h in 0...6) + // { + // var yPos:Float = FlxG.height * (h / 6); + // var sticker = grpStickers.members[stickerCount]; + // xPos -= sticker.width / 2; + // yPos -= sticker.height * 0.9; + // sticker.x = xPos; + // sticker.y = yPos; + + // stickerCount++; + // } + // } + + // for (ind => sticker in grpStickers.members) + // { + // sticker.x = (ind % 8) * sticker.width; + // var yShit:Int = Math.floor(ind / 8); + // sticker.y += yShit * sticker.height; + // // scales it juuuust a smidge + // sticker.y += 20 * yShit; + // } + + // another damn for loop... apologies!!! + for (ind => sticker in grpStickers.members) + { + sticker.timing = FlxMath.remapToRange(ind, 0, grpStickers.members.length, 0, 0.9); + + new FlxTimer().start(sticker.timing, _ -> { + sticker.visible = true; + + var frameTimer:Int = FlxG.random.int(0, 2); + + // always make the last one POP + if (ind == grpStickers.members.length - 1) frameTimer = 2; + + new FlxTimer().start((1 / 24) * frameTimer, _ -> { + sticker.scale.x = sticker.scale.y = FlxG.random.float(0.97, 1.02); + + if (ind == grpStickers.members.length - 1) + { + switchingState = true; + FlxTransitionableState.skipNextTransIn = true; + FlxTransitionableState.skipNextTransOut = true; + + dipshit = new Sprite(); + var scrn:BitmapData = new BitmapData(FlxG.width, FlxG.height, true, 0x00000000); + var mat:Matrix = new Matrix(); + scrn.draw(grpStickers.cameras[0].canvas, mat); + + var bitmap:Bitmap = new Bitmap(scrn); + + dipshit.addChild(bitmap); + FlxG.addChildBelowMouse(dipshit); + + switch (nextState) + { + case FREEPLAY: + FlxG.switchState(new FreeplayState(this)); + case STORY: + FlxG.switchState(new StoryMenuState(this)); + default: + FlxG.switchState(new FreeplayState(this)); + } + } + + // sticky.angle *= FlxG.random.float(0, 0.05); + }); + }); + } + + grpStickers.sort((ord, a, b) -> { + return FlxSort.byValues(ord, a.timing, b.timing); + }); + + // centers the very last sticker + var lastOne:StickerSprite = grpStickers.members[grpStickers.members.length - 1]; + lastOne.updateHitbox(); + lastOne.angle = 0; + lastOne.screenCenter(); + } + + override public function update(elapsed:Float):Void + { + super.update(elapsed); + + if (FlxG.keys.justPressed.ANY) + { + regenStickers(); + } + } + + var switchingState:Bool = false; + + override public function close():Void + { + if (switchingState) return; + super.close(); + } + + override public function destroy():Void + { + if (switchingState) return; + super.destroy(); + } +} + +class StickerSprite extends FlxSprite +{ + public var timing:Float = 0; + + public function new(x:Float, y:Float, stickerSet:String, stickerName:String):Void + { + super(x, y); + loadGraphic(Paths.image('transitionSwag/' + stickerSet + '/' + stickerName)); + updateHitbox(); + antialiasing = true; + scrollFactor.set(); + } +} + +class StickerInfo +{ + public var name:String; + public var artist:String; + public var stickers:Map>; + public var stickerPacks:Map>; + + public function new(stickerSet:String):Void + { + var path = Paths.file('images/transitionSwag/' + stickerSet + '/stickers.json'); + var json = Json.parse(Assets.getText(path)); + trace(json); + + // doin this dipshit nonsense cuz i dunno how to deal with casting a json object with + // a dash in its name (sticker-packs) + var jsonInfo:StickerShit = cast json; + + this.name = jsonInfo.name; + this.artist = jsonInfo.artist; + + stickerPacks = new Map>(); + + for (field in Reflect.fields(json.stickerPacks)) + { + var stickerFunny = json.stickerPacks; + var stickerStuff = Reflect.field(stickerFunny, field); + + stickerPacks.set(field, cast stickerStuff); + + trace(field); + trace(Reflect.field(stickerFunny, field)); + } + + trace(stickerPacks); + + // creates a similar for loop as before but for the stickers + stickers = new Map>(); + + for (field in Reflect.fields(json.stickers)) + { + var stickerFunny = json.stickers; + var stickerStuff = Reflect.field(stickerFunny, field); + + stickers.set(field, cast stickerStuff); + + trace(field); + trace(Reflect.field(stickerFunny, field)); + } + + trace(stickers); + + // this.stickerPacks = cast jsonInfo.stickerPacks; + // this.stickers = cast jsonInfo.stickers; + + // trace(stickerPacks); + // trace(stickers); + + // for (packs in stickers) + // { + // // this.stickers.set(packs, Reflect.field(json, "sticker-packs")); + // trace(packs); + // } + } + + public function getStickers(stickerName:String):Array + { + return this.stickers[stickerName]; + } + + public function getPack(packName:String):Array + { + return this.stickerPacks[packName]; + } +} + +// somethin damn cute just for the json to cast to! +typedef StickerShit = +{ + name:String, + artist:String, + stickers:Map>, + stickerPacks:Map> +} + +enum abstract NEXTSTATE(String) +{ + var FREEPLAY = 'freeplay'; + var STORY = 'story'; +} diff --git a/source/funkin/ui/debug/DebugMenuSubState.hx b/source/funkin/ui/debug/DebugMenuSubState.hx index 476f0ae9d..5d00c03b8 100644 --- a/source/funkin/ui/debug/DebugMenuSubState.hx +++ b/source/funkin/ui/debug/DebugMenuSubState.hx @@ -15,9 +15,10 @@ class DebugMenuSubState extends MusicBeatSubstate */ var camFocusPoint:FlxObject; - override function create() + override function create():Void { super.create(); + bgColor = 0x00000000; // Create an object for the camera to track. camFocusPoint = new FlxObject(0, 0); @@ -46,6 +47,7 @@ class DebugMenuSubState extends MusicBeatSubstate onMenuChange(createItem("CHART EDITOR", openChartEditor)); createItem("ANIMATION EDITOR", openAnimationEditor); createItem("STAGE EDITOR", openStageEditor); + createItem("TEST STICKERS", testStickers); } function onMenuChange(selected:TextMenuItem) @@ -83,6 +85,12 @@ class DebugMenuSubState extends MusicBeatSubstate trace('Animation Editor'); } + function testStickers() + { + openSubState(new funkin.ui.StickerSubState()); + trace('opened stickers'); + } + function openStageEditor() { trace('Stage Editor'); diff --git a/source/funkin/util/tools/MapTools.hx b/source/funkin/util/tools/MapTools.hx index 296a818c7..daedb4aab 100644 --- a/source/funkin/util/tools/MapTools.hx +++ b/source/funkin/util/tools/MapTools.hx @@ -13,4 +13,9 @@ class MapTools { return [for (i in map.iterator()) i]; } + + public static function keyValues(map:Map):Array + { + return [for (i in map.keys()) i]; + } }