diff --git a/assets/data/scripts/week6-pause.hx b/assets/data/scripts/week6-pause.hx index b382af35..9b93200c 100644 --- a/assets/data/scripts/week6-pause.hx +++ b/assets/data/scripts/week6-pause.hx @@ -17,7 +17,7 @@ function create(event) { // cancel default pause menu!! event.cancel(); - event.music = isThorns ? "pixel/LunchboxScary" : "pixel/Lunchbox"; + event.music = isThorns ? "pixel/LunchboxScary" : "pixel/breakfast"; cameras = []; diff --git a/assets/data/weeks/characters/bf.xml b/assets/data/weeks/characters/bf.xml index 20e9176d..1f3fa299 100644 --- a/assets/data/weeks/characters/bf.xml +++ b/assets/data/weeks/characters/bf.xml @@ -1,5 +1,5 @@ - - - + + + \ No newline at end of file diff --git a/assets/data/weeks/characters/dad.xml b/assets/data/weeks/characters/dad.xml index dfda66e7..2b1cd842 100644 --- a/assets/data/weeks/characters/dad.xml +++ b/assets/data/weeks/characters/dad.xml @@ -1,2 +1,2 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/data/weeks/characters/gf.xml b/assets/data/weeks/characters/gf.xml index 1af08c30..3ac59136 100644 --- a/assets/data/weeks/characters/gf.xml +++ b/assets/data/weeks/characters/gf.xml @@ -1,2 +1,2 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/data/weeks/characters/mom.xml b/assets/data/weeks/characters/mom.xml index 338e2825..78682a7d 100644 --- a/assets/data/weeks/characters/mom.xml +++ b/assets/data/weeks/characters/mom.xml @@ -1,2 +1,2 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/data/weeks/characters/parents-christmas.xml b/assets/data/weeks/characters/parents-christmas.xml index 44070ced..18f95ffb 100644 --- a/assets/data/weeks/characters/parents-christmas.xml +++ b/assets/data/weeks/characters/parents-christmas.xml @@ -1,2 +1,2 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/data/weeks/characters/pico-player.xml b/assets/data/weeks/characters/pico-player.xml new file mode 100644 index 00000000..709ea008 --- /dev/null +++ b/assets/data/weeks/characters/pico-player.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/assets/data/weeks/characters/pico.xml b/assets/data/weeks/characters/pico.xml index f4f32242..db4f592e 100644 --- a/assets/data/weeks/characters/pico.xml +++ b/assets/data/weeks/characters/pico.xml @@ -1,2 +1,4 @@ - \ No newline at end of file + + + \ No newline at end of file diff --git a/assets/data/weeks/characters/spooky.xml b/assets/data/weeks/characters/spooky.xml index 2466bbbb..e4955b1f 100644 --- a/assets/data/weeks/characters/spooky.xml +++ b/assets/data/weeks/characters/spooky.xml @@ -1,2 +1,2 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/images/menus/storymenu/characters/pico.png b/assets/images/menus/storymenu/characters/pico.png index 46a4e375..bae0afa3 100644 Binary files a/assets/images/menus/storymenu/characters/pico.png and b/assets/images/menus/storymenu/characters/pico.png differ diff --git a/assets/images/menus/storymenu/characters/pico.xml b/assets/images/menus/storymenu/characters/pico.xml index 9e6832cd..04cfe8e6 100644 --- a/assets/images/menus/storymenu/characters/pico.xml +++ b/assets/images/menus/storymenu/characters/pico.xml @@ -1,19 +1,46 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/music/pixel/breakfast.mp3 b/assets/music/pixel/breakfast.mp3 new file mode 100644 index 00000000..9868a89f Binary files /dev/null and b/assets/music/pixel/breakfast.mp3 differ diff --git a/assets/music/pixel/breakfast.ogg b/assets/music/pixel/breakfast.ogg new file mode 100644 index 00000000..7227bea6 Binary files /dev/null and b/assets/music/pixel/breakfast.ogg differ diff --git a/source/funkin/backend/FunkinSprite.hx b/source/funkin/backend/FunkinSprite.hx index 1e36b52e..33a2fe71 100644 --- a/source/funkin/backend/FunkinSprite.hx +++ b/source/funkin/backend/FunkinSprite.hx @@ -128,7 +128,7 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I private var countedBeat = 0; public function beatHit(curBeat:Int) { - if (beatAnims.length > 0 && (curBeat + beatOffset) % beatInterval == 0) + if (lastAnimContext != LOCK && beatAnims.length > 0 && (curBeat + beatOffset) % beatInterval == 0) { if(skipNegativeBeats && curBeat < 0) return; // TODO: find a solution without countedBeat diff --git a/source/funkin/backend/scripting/events/soundTray/SoundTrayShowEvent.hx b/source/funkin/backend/scripting/events/soundTray/SoundTrayShowEvent.hx new file mode 100644 index 00000000..a363e790 --- /dev/null +++ b/source/funkin/backend/scripting/events/soundTray/SoundTrayShowEvent.hx @@ -0,0 +1,6 @@ +package funkin.backend.scripting.events.soundTray; + +final class SoundTrayShowEvent extends CancellableEvent +{ + public var up:Bool; +} \ No newline at end of file diff --git a/source/funkin/backend/scripting/events/soundTray/SoundTrayTextEvent.hx b/source/funkin/backend/scripting/events/soundTray/SoundTrayTextEvent.hx new file mode 100644 index 00000000..3f8d23a0 --- /dev/null +++ b/source/funkin/backend/scripting/events/soundTray/SoundTrayTextEvent.hx @@ -0,0 +1,12 @@ +package funkin.backend.scripting.events.soundTray; + +final class SoundTrayTextEvent extends CancellableEvent +{ + public var checkIfNull:Bool; + + public var reloadDefaultTextFormat:Bool; + + public var displayTxt:String; + + public var y:Float; +} \ No newline at end of file diff --git a/source/funkin/backend/system/Main.hx b/source/funkin/backend/system/Main.hx index 7ff01ee7..649a09d9 100644 --- a/source/funkin/backend/system/Main.hx +++ b/source/funkin/backend/system/Main.hx @@ -166,13 +166,19 @@ class Main extends Sprite initTransition(); } - public static function refreshAssets() { - FlxSoundTray.volumeChangeSFX = Paths.sound('menu/volume'); - FlxSoundTray.volumeUpChangeSFX = null; - FlxSoundTray.volumeDownChangeSFX = null; + public static function refreshAssets() @:privateAccess { + var game = FlxG.game; var daSndTray = Type.createInstance(game._customSoundTray = funkin.menus.ui.FunkinSoundTray, []); + var index:Int = game.numChildren - 1; - if (FlxG.game.soundTray != null) - FlxG.game.soundTray.text.setTextFormat(new TextFormat(Paths.font("vcr.ttf"))); + if(game.soundTray != null) + { + var newIndex:Int = game.getChildIndex(game.soundTray); + if(newIndex != -1) index = newIndex; + game.removeChild(game.soundTray); + game.soundTray.__cleanup(); + } + + game.addChildAt(game.soundTray = daSndTray, index); } public static function initTransition() { diff --git a/source/funkin/backend/utils/XMLUtil.hx b/source/funkin/backend/utils/XMLUtil.hx index 335a9fbc..8f0ceb9d 100644 --- a/source/funkin/backend/utils/XMLUtil.hx +++ b/source/funkin/backend/utils/XMLUtil.hx @@ -139,6 +139,8 @@ class XMLUtil { var graphicSizey:Null = Std.parseInt(node.att.graphicSizey); if (graphicSizey.isNotNull()) spr.setGraphicSize(0, graphicSizey); } + + if (node.has.flipX && node.att.flipX == "true") spr.flipX = true; if (node.has.updateHitbox && node.att.updateHitbox == "true") spr.updateHitbox(); if (node.has.zoomfactor) diff --git a/source/funkin/menus/StoryMenuState.hx b/source/funkin/menus/StoryMenuState.hx index e8ab5c25..fa9387d2 100644 --- a/source/funkin/menus/StoryMenuState.hx +++ b/source/funkin/menus/StoryMenuState.hx @@ -12,7 +12,7 @@ import haxe.io.Path; import haxe.xml.Access; class StoryMenuState extends MusicBeatState { - public var characters:Map = []; + public var characters:Map = []; public var weeks:Array = []; public var scoreText:FlxText; @@ -23,18 +23,21 @@ class StoryMenuState extends MusicBeatState { public var curWeek:Int = 0; public var difficultySprites:Map = []; - public var weekBG:FlxSprite; public var leftArrow:FlxSprite; public var rightArrow:FlxSprite; public var blackBar:FlxSprite; + public var weekBG:FlxSprite; + public var defColor:String = "#F9CF51"; + public var interpColor:FlxInterpolateColor; + public var lerpScore:Float = 0; public var intendedScore:Int = 0; public var canSelect:Bool = true; public var weekSprites:FlxTypedGroup; - public var characterSprites:FlxTypedGroup; + public var characterSprites:FlxTypedGroup; //public var charFrames:Map = []; @@ -56,7 +59,7 @@ class StoryMenuState extends MusicBeatState { weekTitle.alpha = 0.7; weekBG = new FlxSprite(0, 56).makeSolid(FlxG.width, 400, 0xFFFFFFFF); - weekBG.color = 0xFFF9CF51; + weekBG.color = weeks.length > 0 ? weeks[0].bgColor : FlxColor.fromString(defColor); weekBG.updateHitbox(); weekSprites = new FlxTypedGroup(); @@ -85,15 +88,12 @@ class StoryMenuState extends MusicBeatState { add(weekSprites); for(e in [blackBar, scoreText, weekTitle, weekBG, tracklist]) { + e.antialiasing = true; e.scrollFactor.set(); add(e); } - characterSprites = new FlxTypedGroup(); - for(i in 0...3) { - characterSprites.add(new MenuCharacterSprite(i)); - } - add(characterSprites); + add(characterSprites = new FlxTypedGroup()); for(i=>week in weeks) { var spr:MenuItem = new MenuItem(0, (i * 120) + 480, 'menus/storymenu/weeks/${week.sprite}'); @@ -114,6 +114,7 @@ class StoryMenuState extends MusicBeatState { } } + interpColor = new FlxInterpolateColor(weekBG.color); changeWeek(0, true); DiscordUtil.call("onMenuLoaded", ["Story Menu"]); @@ -145,6 +146,9 @@ class StoryMenuState extends MusicBeatState { if (e != null && e.exists) e.animation.play('idle'); } + + interpColor.fpsLerpTo(weeks[curWeek].bgColor, 0.0625); + weekBG.color = interpColor.color; } public function goBack() { @@ -164,17 +168,41 @@ class StoryMenuState extends MusicBeatState { for(k=>e in weekSprites.members) { e.targetY = k - curWeek; } - tracklist.text = 'TRACKS\n\n${[for(e in weeks[curWeek].songs) if (!e.hide) e.name.toUpperCase()].join('\n')}'; + tracklist.text = 'TRACKS\n\n${[for(e in weeks[curWeek].songs) if (!e.hide) e.name].join('\n')}'; weekTitle.text = weeks[curWeek].name.getDefault(""); - for(i in 0...3) - characterSprites.members[i].changeCharacter(characters[weeks[curWeek].chars[i]]); + if(characterSprites != null) for(i in 0...3) { + var curChar:FunkinSprite; var newChar:Access = characters[weeks[curWeek].chars[i]]; + if(newChar == null) modifyCharacterAt(i); + else if((curChar = characterSprites.members[i]) == null || newChar.getAtt("name") != curChar.name) modifyCharacterAt(i, newChar); + } changeDifficulty(0, true); MemoryUtil.clearMinor(); } + public function modifyCharacterAt(i:Int, ?node:Access):FunkinSprite { + var old = characterSprites.members[i]; + if(old != null) { + characterSprites.remove(old); + old.destroy(); + } + + if(node == null) return null; + var curChar:FunkinSprite = XMLUtil.createSpriteFromXML(node, "", BEAT); + curChar.offset.x += curChar.x; curChar.offset.y += curChar.y; + curChar.setPosition((FlxG.width * 0.25) * (1 + i) - 150, 70); + if(characterSprites != null) characterSprites.insert(i, curChar); // Making so many null checks abt this group just in case if mods destroy it - Nex + curChar.playAnim("idle", true, DANCE); + return curChar; + } + + public override function beatHit(curBeat:Int) { + super.beatHit(curBeat); + if(characterSprites != null) characterSprites.forEachAlive(function(spr) spr.beatHit(curBeat)); + } + var __oldDiffName = null; public function changeDifficulty(change:Int, force:Bool = false) { if (change == 0 && !force) return; @@ -228,7 +256,8 @@ class StoryMenuState extends MusicBeatState { sprite: week.getAtt('sprite').getDefault(weekName), chars: [null, null, null], songs: [], - difficulties: ['easy', 'normal', 'hard'] + difficulties: ['easy', 'normal', 'hard'], + bgColor: FlxColor.fromString(week.getAtt("bgColor").getDefault(defColor)) }; var diffNodes = week.nodes.difficulty; @@ -282,19 +311,14 @@ class StoryMenuState extends MusicBeatState { } catch(e) { Logs.trace('Story Menu: Cannot parse character "$charName.xml": ${Std.string(e)}`', ERROR); } - if (char == null) return; - if (characters[charName] != null) return; - var charObj:MenuCharacter = { - spritePath: Paths.image(char.getAtt('sprite').getDefault('menus/storymenu/characters/${charName}')), - scale: Std.parseFloat(char.getAtt('scale')).getDefault(1), - xml: char, - offset: FlxPoint.get( - Std.parseFloat(char.getAtt('x')).getDefault(0), - Std.parseFloat(char.getAtt('y')).getDefault(0) - ) - }; - characters[charName] = charObj; + if(char != null && characters[charName] == null) { + if(!char.x.exists("name")) char.x.set("name", charName); + if(!char.x.exists("sprite")) char.x.set("sprite", 'menus/storymenu/characters/${charName}'); + if(!char.x.exists("beatInterval")) char.x.set("beatInterval", "1"); + if(!char.x.exists("updateHitbox")) char.x.set("updateHitbox", "true"); + characters[charName] = char; + } } public function getWeeksFromSource(weeks:Array, source:funkin.backend.assets.AssetsLibraryList.AssetSource) { @@ -315,13 +339,6 @@ class StoryMenuState extends MusicBeatState { return true; } - public override function destroy() { - super.destroy(); - for(e in characters) - if (e != null && e.offset != null) - e.offset.put(); - } - public function selectWeek() { var event = event("onWeekSelect", EventManager.get(WeekSelectEvent).recycle(weeks[curWeek], weeks[curWeek].difficulties[curDifficulty], curWeek, curDifficulty)); if (event.cancelled) return; @@ -329,9 +346,8 @@ class StoryMenuState extends MusicBeatState { canSelect = false; CoolUtil.playMenuSFX(CONFIRM); - for(char in characterSprites) - if (char.animation.exists("confirm")) - char.animation.play("confirm"); + if(characterSprites != null) + characterSprites.forEachAlive(function(spr) spr.playAnim("confirm", true, LOCK)); PlayState.loadWeek(weeks[curWeek], weeks[curWeek].difficulties[curDifficulty]); @@ -350,6 +366,7 @@ typedef WeekData = { var chars:Array; var songs:Array; var difficulties:Array; + var bgColor:FlxColor; } typedef WeekSong = { @@ -357,52 +374,6 @@ typedef WeekSong = { var hide:Bool; } -typedef MenuCharacter = { - var spritePath:String; - var xml:Access; - var scale:Float; - var offset:FlxPoint; - // var frames:FlxFramesCollection; -} - -class MenuCharacterSprite extends FlxSprite -{ - public var character:String; - - var pos:Int; - - public function new(pos:Int) { - super(0, 70); - this.pos = pos; - visible = false; - antialiasing = true; - } - - public var oldChar:MenuCharacter = null; - - public function changeCharacter(data:MenuCharacter) { - visible = (data != null); - if (!visible) - return; - - if (oldChar != (oldChar = data)) { - CoolUtil.loadAnimatedGraphic(this, data.spritePath); - for(e in data.xml.nodes.anim) { - if (e.getAtt("name") == "idle") - animation.remove("idle"); - - XMLUtil.addXMLAnimation(this, e); - } - animation.play("idle"); - scale.set(data.scale, data.scale); - updateHitbox(); - offset.x += data.offset.x; - offset.y += data.offset.y; - - x = (FlxG.width * 0.25) * (1 + pos) - 150; - } - } -} class MenuItem extends FlxSprite { public var targetY:Float = 0; diff --git a/source/funkin/menus/credits/CreditsMain.hx b/source/funkin/menus/credits/CreditsMain.hx index 916066eb..e2df9c6e 100644 --- a/source/funkin/menus/credits/CreditsMain.hx +++ b/source/funkin/menus/credits/CreditsMain.hx @@ -59,7 +59,7 @@ class CreditsMain extends TreeMenu { if (node.name == "github") { if (!node.has.user) { - Logs.trace("[CreditsMain] A github node requires a user attribute.", WARNING); + Logs.trace("A github node requires a user attribute.", WARNING); continue; } @@ -78,7 +78,7 @@ class CreditsMain extends TreeMenu { credsMenus.push(opt); } else { if (!node.has.name) { - Logs.trace("[CreditsMain] A credit node requires a name attribute.", WARNING); + Logs.trace("A credit node requires a name attribute.", WARNING); continue; } var name = node.getAtt("name"); diff --git a/source/funkin/menus/ui/FunkinSoundTray.hx b/source/funkin/menus/ui/FunkinSoundTray.hx new file mode 100644 index 00000000..bd89e2d1 --- /dev/null +++ b/source/funkin/menus/ui/FunkinSoundTray.hx @@ -0,0 +1,118 @@ +package funkin.menus.ui; + +import funkin.backend.scripting.events.CancellableEvent; +import funkin.backend.scripting.events.soundTray.*; +import funkin.backend.scripting.Script; +import flixel.system.ui.FlxSoundTray; +import openfl.text.TextFormat; + +class FunkinSoundTray extends FlxSoundTray +{ + public var script:Script; + + // Neeo wanted them since it would reduce lags for some people if activated - Nex + public var callsUpdate:Bool = true; + public var callsPostUpdate:Bool = true; + + public function new() + { + script = Script.create(Paths.script('data/soundTray')); + script.setParent(this); + script.load(); + + script.call("create"); + super(); + + FlxSoundTray.volumeChangeSFX = Paths.sound('menu/volume'); + FlxSoundTray.volumeUpChangeSFX = null; + FlxSoundTray.volumeDownChangeSFX = null; + FlxSoundTray.volumeMaxChangeSFX = null; + text.setTextFormat(new TextFormat(Paths.font("vcr.ttf"))); + + script.call("postCreate"); + } + + public override function reloadText(checkIfNull:Bool = true, reloadDefaultTextFormat:Bool = true, displayTxt:String = "VOLUME", y:Float = 16) + { + var event = EventManager.get(SoundTrayTextEvent).recycle(checkIfNull, reloadDefaultTextFormat, displayTxt, y); + script.call("reloadText", [event]); + if (event.cancelled) return; + + super.reloadText(event.checkIfNull, event.reloadDefaultTextFormat, event.displayTxt, event.y); + script.call("postReloadText", [event]); + } + + public override function reloadDtf() + { + var event = new CancellableEvent(); + script.call("reloadDtf", [event]); + if (event.cancelled) return; + + super.reloadDtf(); + script.call("postReloadDtf"); + } + + public override function regenerateBarsArray() + { + var event = new CancellableEvent(); + script.call("regenerateBarsArray", [event]); + if (event.cancelled) return; + + super.regenerateBarsArray(); + script.call("postRegenerateBarsArray"); + } + + public override function regenerateBars() + { + var event = new CancellableEvent(); + script.call("regenerateBars", [event]); + if (event.cancelled) return; + + super.regenerateBars(); + script.call("postRegenerateBars"); + } + + public override function update(elapsed:Float) + { + if (callsUpdate) script.call("update", [elapsed]); + super.update(elapsed); + if (callsPostUpdate) script.call("postUpdate", [elapsed]); + } + + public override function saveSoundPreferences() + { + var event = new CancellableEvent(); + script.call("saveSoundPreferences", [event]); + if (event.cancelled) return; + + super.saveSoundPreferences(); + script.call("postSaveSoundPreferences"); + } + + public override function show(up:Bool = false) + { + var event = EventManager.get(SoundTrayShowEvent).recycle(up); + script.call("show", [event]); + if (event.cancelled) return; + + super.show(event.up); + script.call("postShow", [event]); + } + + public override function screenCenter() + { + var event = new CancellableEvent(); + script.call("screenCenter", [event]); + if (event.cancelled) return; + + super.screenCenter(); + script.call("postScreenCenter"); + } + + private override function __cleanup() + { + script.call("destroy"); + script.destroy(); + super.__cleanup(); + } +} \ No newline at end of file