From d686890f763bd7a4db1841464dd7e3559fac1d0f Mon Sep 17 00:00:00 2001 From: FabsTheFabs Date: Sat, 15 Jun 2024 05:59:58 +0100 Subject: [PATCH 01/10] most of the old code --- source/funkin/ui/charSelect/CharIcon.hx | 17 + .../funkin/ui/charSelect/CharIconCharacter.hx | 49 ++ source/funkin/ui/charSelect/CharIconLocked.hx | 3 + source/funkin/ui/charSelect/CharSelectGF.hx | 137 ++++ .../funkin/ui/charSelect/CharSelectPlayer.hx | 58 ++ .../ui/charSelect/CharSelectSubState.hx | 618 ++++++++++++++++++ source/funkin/ui/charSelect/Nametag.hx | 101 +++ source/funkin/ui/debug/DebugMenuSubState.hx | 6 + 8 files changed, 989 insertions(+) create mode 100644 source/funkin/ui/charSelect/CharIcon.hx create mode 100644 source/funkin/ui/charSelect/CharIconCharacter.hx create mode 100644 source/funkin/ui/charSelect/CharIconLocked.hx create mode 100644 source/funkin/ui/charSelect/CharSelectGF.hx create mode 100644 source/funkin/ui/charSelect/CharSelectPlayer.hx create mode 100644 source/funkin/ui/charSelect/CharSelectSubState.hx create mode 100644 source/funkin/ui/charSelect/Nametag.hx diff --git a/source/funkin/ui/charSelect/CharIcon.hx b/source/funkin/ui/charSelect/CharIcon.hx new file mode 100644 index 000000000..6d6274286 --- /dev/null +++ b/source/funkin/ui/charSelect/CharIcon.hx @@ -0,0 +1,17 @@ +package funkin.ui.charSelect; + +import flixel.FlxSprite; + +class CharIcon extends FlxSprite +{ + public var locked:Bool = false; + + public function new(x:Float, y:Float, locked:Bool = false) + { + super(x, y); + + this.locked = locked; + + makeGraphic(128, 128); + } +} diff --git a/source/funkin/ui/charSelect/CharIconCharacter.hx b/source/funkin/ui/charSelect/CharIconCharacter.hx new file mode 100644 index 000000000..7f7b5c212 --- /dev/null +++ b/source/funkin/ui/charSelect/CharIconCharacter.hx @@ -0,0 +1,49 @@ +package funkin.ui.charSelect; + +import openfl.display.BitmapData; +import openfl.filters.DropShadowFilter; +import openfl.filters.ConvolutionFilter; +import funkin.graphics.shaders.StrokeShader; + +class CharIconCharacter extends CharIcon +{ + public var dropShadowFilter:DropShadowFilter; + + var matrixFilter:Array = [ + 1, 1, 1, + 1, 1, 1, + 1, 1, 1 + ]; + + var divisor:Int = 1; + var bias:Int = 0; + var convolutionFilter:ConvolutionFilter; + + public var noDropShadow:BitmapData; + public var withDropShadow:BitmapData; + + var strokeShader:StrokeShader; + + public function new(path:String) + { + super(0, 0, false); + + loadGraphic(Paths.image('freeplay/icons/' + path + 'pixel')); + setGraphicSize(128, 128); + updateHitbox(); + antialiasing = false; + + strokeShader = new StrokeShader(); + // shader = strokeShader; + + // noDropShadow = pixels.clone(); + + // dropShadowFilter = new DropShadowFilter(5, 45, 0, 1, 0, 0); + // convolutionFilter = new ConvolutionFilter(3, 3, matrixFilter, divisor, bias); + // pixels.applyFilter(pixels, pixels.rect, new openfl.geom.Point(0, 0), dropShadowFilter); + // pixels.applyFilter(pixels, pixels.rect, new openfl.geom.Point(0, 0), convolutionFilter); + // withDropShadow = pixels.clone(); + + // pixels = noDropShadow.clone(); + } +} diff --git a/source/funkin/ui/charSelect/CharIconLocked.hx b/source/funkin/ui/charSelect/CharIconLocked.hx new file mode 100644 index 000000000..dbe84a6ce --- /dev/null +++ b/source/funkin/ui/charSelect/CharIconLocked.hx @@ -0,0 +1,3 @@ +package funkin.ui.charSelect; + +class CharIconLocked extends CharIcon {} diff --git a/source/funkin/ui/charSelect/CharSelectGF.hx b/source/funkin/ui/charSelect/CharSelectGF.hx new file mode 100644 index 000000000..6d8e3e657 --- /dev/null +++ b/source/funkin/ui/charSelect/CharSelectGF.hx @@ -0,0 +1,137 @@ +package funkin.ui.charSelect; + +import funkin.graphics.adobeanimate.FlxAtlasSprite; +import flixel.tweens.FlxTween; +import flixel.tweens.FlxEase; +import flixel.math.FlxMath; +import funkin.util.FramesJSFLParser; +import funkin.util.FramesJSFLParser.FramesJSFLInfo; +import funkin.util.FramesJSFLParser.FramesJSFLFrame; +import flixel.math.FlxMath; + +class CharSelectGF extends FlxAtlasSprite +{ + var fadeTimer:Float = 0; + var fadingStatus:FadeStatus = OFF; + var fadeAnimIndex:Int = 0; + + var animInInfo:FramesJSFLInfo; + var animOutInfo:FramesJSFLInfo; + + var intendedYPos:Float = 0; + var intendedAlpha:Float = 0; + + public function new() + { + super(0, 0, Paths.animateAtlas("charSelect/gfChill")); + anim.play(""); + switchGF("bf"); + } + + override public function update(elapsed:Float) + { + super.update(elapsed); + + switch (fadingStatus) + { + case OFF: + // do nothing if it's off! + // or maybe force position to be 0,0? + // maybe reset timers? + resetFadeAnimParams(); + case FADE_OUT: + doFade(animOutInfo); + case FADE_IN: + doFade(animInInfo); + default: + } + + if (FlxG.keys.justPressed.J) + { + alpha = 1; + x = y = 0; + fadingStatus = FADE_OUT; + } + if (FlxG.keys.justPressed.K) + { + alpha = 0; + fadingStatus = FADE_IN; + } + } + + /** + * @param animInfo Should not be confused with animInInfo! + * This is merely a local var for the function! + */ + function doFade(animInfo:FramesJSFLInfo) + { + fadeTimer += FlxG.elapsed; + if (fadeTimer >= 1 / 24) + { + fadeTimer = 0; + // only inc the index for the first frame, used for reference of where to "start" + if (fadeAnimIndex == 0) + { + fadeAnimIndex++; + return; + } + + var curFrame:FramesJSFLFrame = animInfo.frames[fadeAnimIndex]; + var prevFrame:FramesJSFLFrame = animInfo.frames[fadeAnimIndex - 1]; + + var xDiff:Float = curFrame.x - prevFrame.x; + var yDiff:Float = curFrame.y - prevFrame.y; + var alphaDiff:Float = curFrame.alpha - prevFrame.alpha; + alphaDiff /= 100; // flash exports alpha as a whole number + + alpha += alphaDiff; + alpha = FlxMath.bound(alpha, 0, 1); + x += xDiff; + y += yDiff; + + fadeAnimIndex++; + } + + if (fadeAnimIndex >= animInfo.frames.length) fadingStatus = OFF; + } + + function resetFadeAnimParams() + { + fadeTimer = 0; + fadeAnimIndex = 0; + } + + public function switchGF(str:String) + { + str = switch (str) + { + case "pico": + "nene"; + case "bf": + "gf"; + default: + "gf"; + } + + switch str + { + default: + loadAtlas(Paths.animateAtlas("charSelect/" + str + "Chill")); + } + + animInInfo = FramesJSFLParser.parse(Paths.file("images/charSelect/" + str + "AnimInfo/" + str + "In.txt")); + animOutInfo = FramesJSFLParser.parse(Paths.file("images/charSelect/" + str + "AnimInfo/" + str + "Out.txt")); + + anim.play(""); + playAnimation("idle", true, false, true); + + updateHitbox(); + } +} + +enum FadeStatus +{ + OFF; + FADE_OUT; + FADE_IN; +} diff --git a/source/funkin/ui/charSelect/CharSelectPlayer.hx b/source/funkin/ui/charSelect/CharSelectPlayer.hx new file mode 100644 index 000000000..9322369ba --- /dev/null +++ b/source/funkin/ui/charSelect/CharSelectPlayer.hx @@ -0,0 +1,58 @@ +package funkin.ui.charSelect; + +import flixel.FlxSprite; +import funkin.graphics.adobeanimate.FlxAtlasSprite; + +class CharSelectPlayer extends FlxAtlasSprite +{ + public function new(x:Float, y:Float) + { + super(x, y, Paths.animateAtlas("charSelect/bfChill")); + + onAnimationFinish.add(function(animLabel:String) { + switch (animLabel) + { + case "slidein": + if (hasAnimation("slidein idle point")) playAnimation("slidein idle point", true, false, false); + else + playAnimation("idle", true, false, true); + case "slidein idle point": + playAnimation("idle", true, false, true); + case "select": + anim.pause(); + case "deselect": + playAnimation("deselect loop start", true, false, true); + } + }); + } + + public function updatePosition(str:String) + { + switch (str) + { + case "bf": + x = 0; + y = 0; + case "pico": + x = 0; + y = 0; + case "random": + } + } + + public function switchChar(str:String) + { + switch str + { + default: + loadAtlas(Paths.animateAtlas("charSelect/" + str + "Chill")); + } + + anim.play(""); + playAnimation("slidein", true, false, false); + + updateHitbox(); + + updatePosition(str); + } +} diff --git a/source/funkin/ui/charSelect/CharSelectSubState.hx b/source/funkin/ui/charSelect/CharSelectSubState.hx new file mode 100644 index 000000000..a360328a2 --- /dev/null +++ b/source/funkin/ui/charSelect/CharSelectSubState.hx @@ -0,0 +1,618 @@ +package funkin.ui.charSelect; + +import flixel.text.FlxText; +import flixel.FlxSprite; +import flixel.system.debug.watch.Tracker.TrackerProfile; +import flixel.math.FlxPoint; +import flixel.tweens.FlxTween; +import openfl.display.BlendMode; +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.group.FlxSpriteGroup; +import funkin.play.stage.Stage; +import funkin.play.stage.StageData.StageDataParser; +import funkin.modding.events.ScriptEvent; +import funkin.modding.events.ScriptEventDispatcher; +import funkin.graphics.adobeanimate.FlxAtlasSprite; +import flixel.FlxObject; +import openfl.display.BlendMode; +import flixel.group.FlxGroup; +import funkin.util.MathUtil; +import flixel.util.FlxTimer; +import flixel.tweens.FlxEase; +import flixel.sound.FlxSound; +import funkin.audio.FunkinSound; + +class CharSelectSubState extends MusicBeatSubState +{ + var cursor:FlxSprite; + var cursorBlue:FlxSprite; + var cursorDarkBlue:FlxSprite; + + var grpCursors:FlxTypedGroup; + + var cursorConfirmed:FlxSprite; + var cursorDenied:FlxSprite; + + var cursorX:Int = 0; + var cursorY:Int = 0; + + var cursorFactor:Float = 110; + var cursorOffsetX:Float = -16; + var cursorOffsetY:Float = -48; + + var cursorLocIntended:FlxPoint = new FlxPoint(0, 0); + var lerpAmnt:Float = 0.95; + + var tmrFrames:Int = 60; + + var currentStage:Stage; + + var playerChill:CharSelectPlayer; + var playerChillOut:CharSelectPlayer; + var gfChill:CharSelectGF; + var gfChillOut:CharSelectGF; + + var curChar(default, set):String = "pico"; + var nametag:Nametag; + var camFollow:FlxObject; + + var availableChars:Map = new Map(); + var pressedSelect:Bool = false; + + var selectTimer:FlxTimer = new FlxTimer(); + var selectSound:FunkinSound; + + public function new() + { + super(); + + availableChars.set(4, "bf"); + availableChars.set(3, "pico"); + } + + override public function create() + { + super.create(); + + selectSound = new FunkinSound(); + selectSound.loadEmbedded(Paths.sound('CS_select')); + selectSound.pitch = 1; + selectSound.volume = 0.7; + FlxG.sound.defaultSoundGroup.add(selectSound); + + Conductor.forceBPM(90); + + var bg:FlxSprite = new FlxSprite(-153, -140); + bg.loadGraphic(Paths.image('charSelect/charSelectBG')); + bg.scrollFactor.set(0.1, 0.1); + add(bg); + + var crowd:FlxAtlasSprite = new FlxAtlasSprite(0, 0, Paths.animateAtlas("charSelect/crowd")); + crowd.anim.play(""); + crowd.scrollFactor.set(0.3, 0.3); + add(crowd); + + var stageSpr:FlxSprite = new FlxSprite(-40, 391); + stageSpr.frames = Paths.getSparrowAtlas("charSelect/charSelectStage"); + stageSpr.animation.addByPrefix("idle", "stage", 24, true); + stageSpr.animation.play("idle"); + add(stageSpr); + + var curtains:FlxSprite = new FlxSprite(-47, -49); + curtains.loadGraphic(Paths.image('charSelect/curtains')); + curtains.scrollFactor.set(1.4, 1.4); + add(curtains); + + var barthing:FlxAtlasSprite = new FlxAtlasSprite(0, 0, Paths.animateAtlas("charSelect/barThing")); + barthing.anim.play(""); + barthing.blend = BlendMode.MULTIPLY; + barthing.scrollFactor.set(0, 0); + add(barthing); + + var charLight:FlxSprite = new FlxSprite(800, 250); + charLight.loadGraphic(Paths.image('charSelect/charLight')); + add(charLight); + + var charLightGF:FlxSprite = new FlxSprite(180, 240); + charLightGF.loadGraphic(Paths.image('charSelect/charLight')); + add(charLightGF); + + gfChill = new CharSelectGF(); + gfChill.switchGF("bf"); + add(gfChill); + + playerChill = new CharSelectPlayer(0, 0); + playerChill.switchChar("bf"); + add(playerChill); + + playerChillOut = new CharSelectPlayer(0, 0); + playerChillOut.switchChar("bf"); + add(playerChillOut); + + var speakers:FlxAtlasSprite = new FlxAtlasSprite(0, 0, Paths.animateAtlas("charSelect/charSelectSpeakers")); + speakers.anim.play(""); + speakers.scrollFactor.set(1.8, 1.8); + add(speakers); + + var fgBlur:FlxSprite = new FlxSprite(-125, 170); + fgBlur.loadGraphic(Paths.image('charSelect/foregroundBlur')); + fgBlur.blend = openfl.display.BlendMode.MULTIPLY; + add(fgBlur); + + var dipshitBlur:FlxSprite = new FlxSprite(419, -65); + dipshitBlur.frames = Paths.getSparrowAtlas("charSelect/dipshitBlur"); + dipshitBlur.animation.addByPrefix('idle', "CHOOSE vertical", 24, true); + dipshitBlur.blend = BlendMode.ADD; + dipshitBlur.animation.play("idle"); + add(dipshitBlur); + + var dipshitBacking:FlxSprite = new FlxSprite(423, -17); + dipshitBacking.frames = Paths.getSparrowAtlas("charSelect/dipshitBacking"); + dipshitBacking.animation.addByPrefix('idle', "CHOOSE horizontal", 24, true); + dipshitBacking.blend = BlendMode.ADD; + dipshitBacking.animation.play("idle"); + add(dipshitBacking); + + var chooseDipshit:FlxSprite = new FlxSprite(426, -13); + chooseDipshit.loadGraphic(Paths.image('charSelect/chooseDipshit')); + add(chooseDipshit); + + chooseDipshit.scrollFactor.set(); + dipshitBacking.scrollFactor.set(); + dipshitBlur.scrollFactor.set(); + + nametag = new Nametag(); + add(nametag); + + nametag.scrollFactor.set(); + + FlxG.debugger.addTrackerProfile(new TrackerProfile(FlxSprite, ["x", "y", "alpha", "scale", "blend"])); + FlxG.debugger.addTrackerProfile(new TrackerProfile(FlxAtlasSprite, ["x", "y"])); + FlxG.debugger.addTrackerProfile(new TrackerProfile(FlxSound, ["pitch", "volume"])); + + // FlxG.debugger.track(crowd); + // FlxG.debugger.track(stageSpr, "stageSpr"); + // FlxG.debugger.track(bfChill, "bf chill"); + // FlxG.debugger.track(playerChill, "player"); + // FlxG.debugger.track(nametag, "nametag"); + FlxG.debugger.track(selectSound, "selectSound"); + // FlxG.debugger.track(chooseDipshit, "choose dipshit"); + // FlxG.debugger.track(barthing, "barthing"); + // FlxG.debugger.track(fgBlur, "fgBlur"); + // FlxG.debugger.track(dipshitBlur, "dipshitBlur"); + // FlxG.debugger.track(dipshitBacking, "dipshitBacking"); + // FlxG.debugger.track(charLightGF, "charLight"); + // FlxG.debugger.track(gfChill, "gfChill"); + + grpCursors = new FlxTypedGroup(); + add(grpCursors); + + cursor = new FlxSprite(0, 0); + cursor.loadGraphic(Paths.image('charSelect/charSelector')); + cursor.color = 0xFFFFFF00; + + // FFCC00 + + cursorBlue = new FlxSprite(0, 0); + cursorBlue.loadGraphic(Paths.image('charSelect/charSelector')); + cursorBlue.color = 0xFF3EBBFF; + + cursorDarkBlue = new FlxSprite(0, 0); + cursorDarkBlue.loadGraphic(Paths.image('charSelect/charSelector')); + cursorDarkBlue.color = 0xFF3C74F7; + + cursorBlue.blend = BlendMode.SCREEN; + cursorDarkBlue.blend = BlendMode.SCREEN; + + cursorConfirmed = new FlxSprite(0, 0); + cursorConfirmed.scrollFactor.set(); + cursorConfirmed.frames = Paths.getSparrowAtlas("charSelect/charSelectorConfirm"); + cursorConfirmed.animation.addByPrefix("idle", "cursor ACCEPTED", 24, true); + cursorConfirmed.visible = false; + add(cursorConfirmed); + + cursorDenied = new FlxSprite(0, 0); + cursorDenied.scrollFactor.set(); + cursorDenied.frames = Paths.getSparrowAtlas("charSelect/charSelectorDenied"); + cursorDenied.animation.addByPrefix("idle", "cursor DENIED", 24, false); + cursorDenied.visible = false; + add(cursorDenied); + + grpCursors.add(cursorDarkBlue); + grpCursors.add(cursorBlue); + grpCursors.add(cursor); + + initLocks(); + + cursor.scrollFactor.set(); + cursorBlue.scrollFactor.set(); + cursorDarkBlue.scrollFactor.set(); + + FlxTween.color(cursor, 0.2, 0xFFFFFF00, 0xFFFFCC00, {type: FlxTween.PINGPONG}); + + // FlxG.debugger.track(cursor); + + FlxG.debugger.addTrackerProfile(new TrackerProfile(CharSelectSubState, ["curChar", "grpXSpread", "grpYSpread"])); + FlxG.debugger.track(this); + + FlxG.sound.playMusic(Paths.music('charSelect/charSelectMusic')); + + camFollow = new FlxObject(0, 0, 1, 1); + add(camFollow); + camFollow.screenCenter(); + + FlxG.camera.follow(camFollow, LOCKON, 0.01); + + var temp:FlxSprite = new FlxSprite(); + temp.loadGraphic(Paths.image('charSelect/placement')); + add(temp); + temp.alpha = 0.0; + Conductor.stepHit.add(spamOnStep); + // FlxG.debugger.track(temp, "tempBG"); + } + + var grpIcons:FlxSpriteGroup; + + var grpXSpread(default, set):Float = 107; + var grpYSpread(default, set):Float = 127; + + function initLocks() + { + grpIcons = new FlxSpriteGroup(); + add(grpIcons); + + FlxG.debugger.addTrackerProfile(new TrackerProfile(FlxSpriteGroup, ["x", "y"])); + // FlxG.debugger.track(grpIcons, "iconGrp"); + + for (i in 0...9) + { + if (availableChars.exists(i)) + { + var path:String = availableChars.get(i); + var temp:CharIconCharacter = new CharIconCharacter(path); + temp.ID = 0; + + var idleAnimPrefix:String = switch (path) + { + case "pico": + "Pico Icon"; + case "bf": + "boyfriend icon instance 1"; + case _: + "Pico Icon"; + }; + + // temp.animation.addByPrefix("idle", idleAnimPrefix, 0, false); + // temp.animation.play("idle"); + grpIcons.add(temp); + } + else + { + var temp:FlxSprite = new FlxSprite(); + temp.ID = 1; + temp.frames = Paths.getSparrowAtlas("charSelect/locks"); + + var lockIndex:Int = i + 1; + + if (i == 3) lockIndex = 3; + + if (i >= 4) lockIndex = i - 2; + + temp.animation.addByIndices("idle", "LOCK FULL " + lockIndex + " instance 1", [0], "", 24); + temp.animation.addByIndices("selected", "LOCK FULL " + lockIndex + " instance 1", [3, 4, 5], "", 24, false); + temp.animation.addByIndices("clicked", "LOCK FULL " + lockIndex + " instance 1", [9, 10, 11, 12, 13, 14, 15], "", 24, false); + + temp.animation.play("idle"); + + grpIcons.add(temp); + } + } + + updateIconPositions(); + + grpIcons.scrollFactor.set(); + } + + function updateIconPositions() + { + grpIcons.x = 450; + grpIcons.y = 120; + for (index => member in grpIcons.members) + { + var posX:Float = (index % 3); + var posY:Float = Math.floor(index / 3); + + member.x = posX * grpXSpread; + member.y = posY * grpYSpread; + + member.x += grpIcons.x; + member.y += grpIcons.y; + } + } + + var holdTmrUp:Float = 0; + var holdTmrDown:Float = 0; + var holdTmrLeft:Float = 0; + var holdTmrRight:Float = 0; + var spamUp:Bool = false; + var spamDown:Bool = false; + var spamLeft:Bool = false; + var spamRight:Bool = false; + + override public function update(elapsed:Float) + { + super.update(elapsed); + + Conductor.update(); + + if (controls.UI_UP_R || controls.UI_DOWN_R || controls.UI_LEFT_R || controls.UI_RIGHT_R) selectSound.pitch = 1; + + if (controls.UI_UP) holdTmrUp += elapsed; + if (controls.UI_UP_R) + { + holdTmrUp = 0; + spamUp = false; + } + + if (controls.UI_DOWN) holdTmrDown += elapsed; + if (controls.UI_DOWN_R) + { + holdTmrDown = 0; + spamDown = false; + } + + if (controls.UI_LEFT) holdTmrLeft += elapsed; + if (controls.UI_LEFT_R) + { + holdTmrLeft = 0; + spamLeft = false; + } + + if (controls.UI_RIGHT) holdTmrRight += elapsed; + if (controls.UI_RIGHT_R) + { + holdTmrRight = 0; + spamRight = false; + } + + var initSpam = 0.5; + + if (holdTmrUp >= initSpam) spamUp = true; + if (holdTmrDown >= initSpam) spamDown = true; + if (holdTmrLeft >= initSpam) spamLeft = true; + if (holdTmrRight >= initSpam) spamRight = true; + + if (controls.UI_UP_P) + { + cursorY -= 1; + holdTmrUp = 0; + + selectSound.play(true); + } + if (controls.UI_DOWN_P) + { + cursorY += 1; + holdTmrDown = 0; + selectSound.play(true); + } + if (controls.UI_LEFT_P) + { + cursorX -= 1; + holdTmrLeft = 0; + selectSound.play(true); + } + if (controls.UI_RIGHT_P) + { + cursorX += 1; + holdTmrRight = 0; + selectSound.play(true); + } + + if (cursorX < -1) + { + cursorX = 1; + } + if (cursorX > 1) + { + cursorX = -1; + } + if (cursorY < -1) + { + cursorY = 1; + } + if (cursorY > 1) + { + cursorY = -1; + } + + if (availableChars.exists(getCurrentSelected())) + { + curChar = availableChars.get(getCurrentSelected()); + + if (controls.ACCEPT) + { + cursorConfirmed.visible = true; + cursorConfirmed.x = cursor.x - 2; + cursorConfirmed.y = cursor.y - 4; + cursorConfirmed.animation.play("idle", true); + + grpCursors.visible = false; + + FlxG.sound.play(Paths.sound('CS_confirm')); + + FlxTween.tween(FlxG.sound.music, {pitch: 0.1}, 1.5, {ease: FlxEase.quadInOut}); + playerChill.playAnimation("select"); + pressedSelect = true; + selectTimer.start(1.5, (_) -> { + pressedSelect = false; + close(); + }); + } + + if (pressedSelect && controls.BACK) + { + cursorConfirmed.visible = false; + grpCursors.visible = true; + + FlxTween.globalManager.cancelTweensOf(FlxG.sound.music); + FlxTween.tween(FlxG.sound.music, {pitch: 1.0}, 1, {ease: FlxEase.quartInOut}); + playerChill.playAnimation("deselect"); + pressedSelect = false; + selectTimer.cancel(); + } + } + else + { + curChar = "locked"; + + if (controls.ACCEPT) + { + cursorDenied.visible = true; + cursorDenied.x = cursor.x - 2; + cursorDenied.y = cursor.y - 4; + cursorDenied.animation.play("idle", true); + cursorDenied.animation.finishCallback = (_) -> { + cursorDenied.visible = false; + }; + } + } + + updateLockAnims(); + + camFollow.screenCenter(); + camFollow.x += cursorX * 10; + camFollow.y += cursorY * 10; + + cursorLocIntended.x = (cursorFactor * cursorX) + (FlxG.width / 2) - cursor.width / 2; + cursorLocIntended.y = (cursorFactor * cursorY) + (FlxG.height / 2) - cursor.height / 2; + + cursorLocIntended.x += cursorOffsetX; + cursorLocIntended.y += cursorOffsetY; + + cursor.x = MathUtil.coolLerp(cursor.x, cursorLocIntended.x, lerpAmnt); + cursor.y = MathUtil.coolLerp(cursor.y, cursorLocIntended.y, lerpAmnt); + + cursorBlue.x = MathUtil.coolLerp(cursorBlue.x, cursor.x, lerpAmnt * 0.4); + cursorBlue.y = MathUtil.coolLerp(cursorBlue.y, cursor.y, lerpAmnt * 0.4); + + cursorDarkBlue.x = MathUtil.coolLerp(cursorDarkBlue.x, cursorLocIntended.x, lerpAmnt * 0.2); + cursorDarkBlue.y = MathUtil.coolLerp(cursorDarkBlue.y, cursorLocIntended.y, lerpAmnt * 0.2); + } + + function spamOnStep() + { + if (spamUp || spamDown || spamLeft || spamRight) + { + selectSound.changePitchBySemitone(1); + if (selectSound.pitch > 5) selectSound.pitch = 5; + selectSound.play(true); + + if (spamUp) + { + cursorY -= 1; + holdTmrUp = 0; + } + if (spamDown) + { + cursorY += 1; + holdTmrDown = 0; + } + if (spamLeft) + { + cursorX -= 1; + holdTmrLeft = 0; + } + if (spamRight) + { + cursorX += 1; + holdTmrRight = 0; + } + } + } + + private function updateLockAnims() + { + for (index => member in grpIcons.group.members) + { + switch (member.ID) + { + case 1: + if (index == getCurrentSelected()) + { + switch (member.animation.curAnim.name) + { + case "idle": + member.animation.play("selected"); + case "selected" | "clicked": + if (controls.ACCEPT) member.animation.play("clicked", true); + } + } + else + { + member.animation.play("idle"); + } + case 0: + var memb:CharIconCharacter = cast member; + + if (index == getCurrentSelected()) + { + // memb.pixels = memb.withDropShadow.clone(); + memb.setGraphicSize(128 * 1.3); + } + else + { + // memb.pixels = memb.noDropShadow.clone(); + memb.setGraphicSize(128); + } + } + } + } + + function getCurrentSelected() + { + var tempX:Int = cursorX + 1; + var tempY:Int = cursorY + 1; + var gridPosition:Int = tempX + tempY * 3; + return gridPosition; + } + + function set_curChar(value:String):String + { + if (curChar == value) return value; + + curChar = value; + + nametag.switchChar(value); + playerChill.visible = false; + playerChillOut.visible = true; + playerChillOut.anim.goToFrameLabel("slideout"); + playerChillOut.anim.callback = (_, frame:Int) -> { + if (frame == playerChillOut.anim.getFrameLabel("slideout").index + 1) + { + playerChill.visible = true; + playerChill.switchChar(value); + gfChill.switchGF(value); + } + if (frame == playerChillOut.anim.getFrameLabel("slideout").index + 2) + { + playerChillOut.switchChar(value); + playerChillOut.visible = false; + } + }; + return value; + } + + function set_grpXSpread(value:Float):Float + { + grpXSpread = value; + updateIconPositions(); + return value; + } + + function set_grpYSpread(value:Float):Float + { + grpYSpread = value; + updateIconPositions(); + return value; + } +} diff --git a/source/funkin/ui/charSelect/Nametag.hx b/source/funkin/ui/charSelect/Nametag.hx new file mode 100644 index 000000000..b6cedb0c7 --- /dev/null +++ b/source/funkin/ui/charSelect/Nametag.hx @@ -0,0 +1,101 @@ +package funkin.ui.charSelect; + +import flixel.FlxSprite; +import funkin.graphics.shaders.MosaicEffect; +import flixel.util.FlxTimer; + +class Nametag extends FlxSprite +{ + var midpointX(default, set):Float = 1008; + var midpointY(default, set):Float = 100; + var mosaicShader:MosaicEffect; + + public function new(?x:Float = 0, ?y:Float = 0) + { + super(x, y); + + mosaicShader = new MosaicEffect(); + shader = mosaicShader; + + switchChar("bf"); + + FlxG.debugger.addTrackerProfile(new TrackerProfile(Nametag, ["midpointX", "midpointY"])); + FlxG.debugger.track(this, "Nametag"); + } + + public function updatePosition():Void + { + var offsetX:Float = getMidpoint().x - midpointX; + var offsetY:Float = getMidpoint().y - midpointY; + + x -= offsetX; + y -= offsetY; + } + + public function switchChar(str:String):Void + { + shaderEffect(); + + new FlxTimer().start(4 / 30, _ -> { + var path:String = str; + switch str + { + case "bf": + path = "boyfriend"; + } + + loadGraphic(Paths.image('charSelect/' + path + "Nametag")); + updateHitbox(); + scale.x = scale.y = 0.77; + + updatePosition(); + shaderEffect(true); + }); + } + + function shaderEffect(fadeOut:Bool = false):Void + { + if (fadeOut) + { + setBlockTimer(0, 1, 1); + setBlockTimer(1, width / 27, height / 26); + setBlockTimer(2, width / 10, height / 10); + + setBlockTimer(3, 1, 1); + } + else + { + setBlockTimer(0, (width / 10), (height / 10)); + setBlockTimer(1, width / 73, height / 6); + setBlockTimer(2, width / 10, height / 10); + } + } + + function setBlockTimer(frame:Int, ?forceX:Float, ?forceY:Float) + { + var daX:Float = 10 * FlxG.random.int(1, 4); + var daY:Float = 10 * FlxG.random.int(1, 4); + + if (forceX != null) daX = forceX; + + if (forceY != null) daY = forceY; + + new FlxTimer().start(frame / 30, _ -> { + mosaicShader.setBlockSize(daX, daY); + }); + } + + function set_midpointX(val:Float):Float + { + this.midpointX = val; + updatePosition(); + return val; + } + + function set_midpointY(val:Float):Float + { + this.midpointY = val; + updatePosition(); + return val; + } +} diff --git a/source/funkin/ui/debug/DebugMenuSubState.hx b/source/funkin/ui/debug/DebugMenuSubState.hx index f8b1be9d2..22dc5dba6 100644 --- a/source/funkin/ui/debug/DebugMenuSubState.hx +++ b/source/funkin/ui/debug/DebugMenuSubState.hx @@ -56,6 +56,7 @@ class DebugMenuSubState extends MusicBeatSubState // Call onMenuChange when the first item is created to move the camera . onMenuChange(createItem("CHART EDITOR", openChartEditor)); // createItem("Input Offset Testing", openInputOffsetTesting); + createItem("CHARACTER SELECT", openCharSelect, true); createItem("ANIMATION EDITOR", openAnimationEditor); // createItem("STAGE EDITOR", openStageEditor); // createItem("TEST STICKERS", testStickers); @@ -102,6 +103,11 @@ class DebugMenuSubState extends MusicBeatSubState trace('Input Offset Testing'); } + function openCharSelect() + { + FlxG.switchState(new funkin.ui.charSelect.CharSelectSubState()); + } + function openAnimationEditor() { FlxG.switchState(() -> new funkin.ui.debug.anim.DebugBoundingState()); From be4ca0f47d2b6736984d4d7933d8e80f264b676a Mon Sep 17 00:00:00 2001 From: FabsTheFabs Date: Sat, 15 Jun 2024 06:00:13 +0100 Subject: [PATCH 02/10] assets..... submod... --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 0dbd2e96c..83f658fcd 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 0dbd2e96ca25ab5966cef05db6c76fe7fb145abf +Subproject commit 83f658fcd87de54ff9c1f7a497b916239d53a491 From 28068b1a86f46e7ff2dacaa18c426b6644bb6767 Mon Sep 17 00:00:00 2001 From: FabsTheFabs Date: Sat, 15 Jun 2024 06:08:55 +0100 Subject: [PATCH 03/10] updating more stuff --- .../funkin/graphics/shaders/MosaicEffect.hx | 23 +++++++++ .../ui/charSelect/CharSelectSubState.hx | 1 - source/funkin/util/FramesJSFLParser.hx | 48 +++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 source/funkin/graphics/shaders/MosaicEffect.hx create mode 100644 source/funkin/util/FramesJSFLParser.hx diff --git a/source/funkin/graphics/shaders/MosaicEffect.hx b/source/funkin/graphics/shaders/MosaicEffect.hx new file mode 100644 index 000000000..fc3737aff --- /dev/null +++ b/source/funkin/graphics/shaders/MosaicEffect.hx @@ -0,0 +1,23 @@ +package funkin.graphics.shaders; + +import flixel.addons.display.FlxRuntimeShader; +import openfl.utils.Assets; +import funkin.Paths; +import flixel.math.FlxPoint; + +class MosaicEffect extends FlxRuntimeShader +{ + public var blockSize:FlxPoint = FlxPoint.get(1.0, 1.0); + + public function new() + { + super(Assets.getText(Paths.frag('mosaic'))); + setBlockSize(1.0, 1.0); + } + + public function setBlockSize(w:Float, h:Float) + { + blockSize.set(w, h); + setFloatArray("uBlocksize", [w, h]); + } +} diff --git a/source/funkin/ui/charSelect/CharSelectSubState.hx b/source/funkin/ui/charSelect/CharSelectSubState.hx index a360328a2..40fa874f3 100644 --- a/source/funkin/ui/charSelect/CharSelectSubState.hx +++ b/source/funkin/ui/charSelect/CharSelectSubState.hx @@ -9,7 +9,6 @@ import openfl.display.BlendMode; import flixel.group.FlxGroup.FlxTypedGroup; import flixel.group.FlxSpriteGroup; import funkin.play.stage.Stage; -import funkin.play.stage.StageData.StageDataParser; import funkin.modding.events.ScriptEvent; import funkin.modding.events.ScriptEventDispatcher; import funkin.graphics.adobeanimate.FlxAtlasSprite; diff --git a/source/funkin/util/FramesJSFLParser.hx b/source/funkin/util/FramesJSFLParser.hx new file mode 100644 index 000000000..33bcf9d9d --- /dev/null +++ b/source/funkin/util/FramesJSFLParser.hx @@ -0,0 +1,48 @@ +package funkin.util; + +import openfl.Assets; + +/** + * See `funScripts/jsfl/frames.jsfl` for more information in the art repo/folder! + * Homemade dipshit proprietary format to get simple animation info out of flash! + * Pure convienience! + */ +class FramesJSFLParser +{ + public static function parse(path:String):FramesJSFLInfo + { + var text:String = Assets.getText(path); + + // TODO: error handle if text is null + + var output:FramesJSFLInfo = {frames: []}; + + var frames:Array = text.split("\n"); + + for (frame in frames) + { + var frameInfo:Array = frame.split(" "); + + var x:Float = Std.parseFloat(frameInfo[0]); + var y:Float = Std.parseFloat(frameInfo[1]); + var alpha:Float = Std.parseFloat(frameInfo[2]); + + var shit:FramesJSFLFrame = {x: x, y: y, alpha: alpha}; + output.frames.push(shit); + } + + return output; + } +} + +typedef FramesJSFLInfo = +{ + var frames:Array; +} + +typedef FramesJSFLFrame = +{ + var x:Float; + var y:Float; + var alpha:Float; +} From b1b7a032bec5cbd43149b8da971a17a9539b2a7f Mon Sep 17 00:00:00 2001 From: FabsTheFabs Date: Sat, 15 Jun 2024 07:03:22 +0100 Subject: [PATCH 04/10] music updates --- source/funkin/ui/charSelect/CharSelectSubState.hx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/source/funkin/ui/charSelect/CharSelectSubState.hx b/source/funkin/ui/charSelect/CharSelectSubState.hx index 40fa874f3..19f00dc92 100644 --- a/source/funkin/ui/charSelect/CharSelectSubState.hx +++ b/source/funkin/ui/charSelect/CharSelectSubState.hx @@ -79,7 +79,12 @@ class CharSelectSubState extends MusicBeatSubState selectSound.volume = 0.7; FlxG.sound.defaultSoundGroup.add(selectSound); - Conductor.forceBPM(90); + FunkinSound.playMusic('charSelect', + { + startingVolume: 0.0, + overrideExisting: true, + restartTrack: true + }); var bg:FlxSprite = new FlxSprite(-153, -140); bg.loadGraphic(Paths.image('charSelect/charSelectBG')); @@ -342,7 +347,7 @@ class CharSelectSubState extends MusicBeatSubState { super.update(elapsed); - Conductor.update(); + // Conductor.update(); if (controls.UI_UP_R || controls.UI_DOWN_R || controls.UI_LEFT_R || controls.UI_RIGHT_R) selectSound.pitch = 1; @@ -502,7 +507,7 @@ class CharSelectSubState extends MusicBeatSubState { if (spamUp || spamDown || spamLeft || spamRight) { - selectSound.changePitchBySemitone(1); + // selectSound.changePitchBySemitone(1); if (selectSound.pitch > 5) selectSound.pitch = 5; selectSound.play(true); From 8dfd36d227d9c9cbf736bff713762ffeb36f0d0f Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Sat, 15 Jun 2024 03:27:59 -0400 Subject: [PATCH 05/10] menu spam fixie --- checkstyle.json | 3 ++- source/funkin/ui/charSelect/CharSelectSubState.hx | 14 ++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/checkstyle.json b/checkstyle.json index 41f0a7998..6c463f75a 100644 --- a/checkstyle.json +++ b/checkstyle.json @@ -327,7 +327,8 @@ "INLINE", "DYNAMIC", "FINAL" - ] + ], + "severity": "IGNORE" }, "type": "ModifierOrder" }, diff --git a/source/funkin/ui/charSelect/CharSelectSubState.hx b/source/funkin/ui/charSelect/CharSelectSubState.hx index 19f00dc92..022db2909 100644 --- a/source/funkin/ui/charSelect/CharSelectSubState.hx +++ b/source/funkin/ui/charSelect/CharSelectSubState.hx @@ -69,7 +69,7 @@ class CharSelectSubState extends MusicBeatSubState availableChars.set(3, "pico"); } - override public function create() + override public function create():Void { super.create(); @@ -79,6 +79,8 @@ class CharSelectSubState extends MusicBeatSubState selectSound.volume = 0.7; FlxG.sound.defaultSoundGroup.add(selectSound); + Conductor.instance.forceBPM(90); + FunkinSound.playMusic('charSelect', { startingVolume: 0.0, @@ -343,11 +345,11 @@ class CharSelectSubState extends MusicBeatSubState var spamLeft:Bool = false; var spamRight:Bool = false; - override public function update(elapsed:Float) + override public function update(elapsed:Float):Void { super.update(elapsed); - // Conductor.update(); + Conductor.instance.update(); if (controls.UI_UP_R || controls.UI_DOWN_R || controls.UI_LEFT_R || controls.UI_RIGHT_R) selectSound.pitch = 1; @@ -503,7 +505,7 @@ class CharSelectSubState extends MusicBeatSubState cursorDarkBlue.y = MathUtil.coolLerp(cursorDarkBlue.y, cursorLocIntended.y, lerpAmnt * 0.2); } - function spamOnStep() + function spamOnStep():Void { if (spamUp || spamDown || spamLeft || spamRight) { @@ -534,7 +536,7 @@ class CharSelectSubState extends MusicBeatSubState } } - private function updateLockAnims() + private function updateLockAnims():Void { for (index => member in grpIcons.group.members) { @@ -572,7 +574,7 @@ class CharSelectSubState extends MusicBeatSubState } } - function getCurrentSelected() + function getCurrentSelected():Int { var tempX:Int = cursorX + 1; var tempY:Int = cursorY + 1; From 3fa9b2a635b54a4c94ebbfc2ff4a5a1c20584101 Mon Sep 17 00:00:00 2001 From: FabsTheFabs Date: Thu, 20 Jun 2024 02:40:50 +0100 Subject: [PATCH 06/10] new music --- .../funkin/ui/charSelect/CharSelectSubState.hx | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/source/funkin/ui/charSelect/CharSelectSubState.hx b/source/funkin/ui/charSelect/CharSelectSubState.hx index 022db2909..0e8bdd1bb 100644 --- a/source/funkin/ui/charSelect/CharSelectSubState.hx +++ b/source/funkin/ui/charSelect/CharSelectSubState.hx @@ -79,14 +79,23 @@ class CharSelectSubState extends MusicBeatSubState selectSound.volume = 0.7; FlxG.sound.defaultSoundGroup.add(selectSound); - Conductor.instance.forceBPM(90); - - FunkinSound.playMusic('charSelect', + // playing it here to preload it. not doing this makes a super awkward pause at the end of the intro + // TODO: probably make an intro thing for funkinSound itself that preloads the next audio? + FunkinSound.playMusic('stayFunky', { - startingVolume: 0.0, + startingVolume: 0, overrideExisting: true, restartTrack: true }); + var introMusic:String = Paths.music('stayFunky/stayFunky-intro'); + FunkinSound.load(introMusic, 1.0, false, true, true, () -> { + FunkinSound.playMusic('stayFunky', + { + startingVolume: 1, + overrideExisting: true, + restartTrack: true + }); + }); var bg:FlxSprite = new FlxSprite(-153, -140); bg.loadGraphic(Paths.image('charSelect/charSelectBG')); From 105e3dccba49897e594e8d6c9a23cc2768fd596b Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 2 Jul 2024 21:26:16 -0400 Subject: [PATCH 07/10] spritesheet fixins for char select --- .gitignore | 1 + source/funkin/ui/PixelatedIcon.hx | 79 ++++++++++++++++++ .../ui/charSelect/CharSelectSubState.hx | 29 +++---- source/funkin/ui/freeplay/SongMenuItem.hx | 81 +------------------ 4 files changed, 95 insertions(+), 95 deletions(-) create mode 100644 source/funkin/ui/PixelatedIcon.hx diff --git a/.gitignore b/.gitignore index 84585eee0..ae402bdee 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ shitAudio/ node_modules/ package.json package-lock.json +.aider* diff --git a/source/funkin/ui/PixelatedIcon.hx b/source/funkin/ui/PixelatedIcon.hx new file mode 100644 index 000000000..8d9b97d9c --- /dev/null +++ b/source/funkin/ui/PixelatedIcon.hx @@ -0,0 +1,79 @@ +package funkin.ui; + +import flixel.FlxSprite; + +/** + * The icon that gets used for Freeplay capsules and char select + * NOT to be confused with the CharIcon class, which is for the in-game icons + */ +class PixelatedIcon extends FlxSprite +{ + public function new(x:Float, y:Float) + { + super(x, y); + this.makeGraphic(32, 32, 0x00000000); + this.antialiasing = false; + this.active = false; + } + + public function setCharacter(char:String):Void + { + var charPath:String = "freeplay/icons/"; + + switch (char) + { + case 'monster-christmas': + charPath += 'monsterpixel'; + case 'mom-car': + charPath += 'mommypixel'; + case 'darnell-blazin': + charPath += 'darnellpixel'; + case 'senpai-angry': + charPath += 'senpaipixel'; + default: + charPath += '${char}pixel'; + } + + if (!openfl.utils.Assets.exists(Paths.image(charPath))) + { + trace('[WARN] Character ${char} has no freeplay icon.'); + return; + } + + var isAnimated = openfl.utils.Assets.exists(Paths.file('images/$charPath.xml')); + + if (isAnimated) + { + this.frames = Paths.getSparrowAtlas(charPath); + } + else + { + this.loadGraphic(Paths.image(charPath)); + } + + this.scale.x = this.scale.y = 2; + + switch (char) + { + case 'parents-christmas': + this.origin.x = 140; + default: + this.origin.x = 100; + } + + if (isAnimated) + { + this.active = true; + this.animation.addByPrefix('idle', 'idle0', 10, true); + this.animation.addByPrefix('confirm', 'confirm0', 10, false); + this.animation.addByPrefix('confirm-hold', 'confirm-hold0', 10, true); + + this.animation.finishCallback = function(name:String):Void { + trace('Finish pixel animation: ${name}'); + if (name == 'confirm') this.animation.play('confirm-hold'); + }; + + this.animation.play('idle'); + } + } +} diff --git a/source/funkin/ui/charSelect/CharSelectSubState.hx b/source/funkin/ui/charSelect/CharSelectSubState.hx index 0e8bdd1bb..d73366390 100644 --- a/source/funkin/ui/charSelect/CharSelectSubState.hx +++ b/source/funkin/ui/charSelect/CharSelectSubState.hx @@ -1,12 +1,13 @@ package funkin.ui.charSelect; import flixel.text.FlxText; -import flixel.FlxSprite; +import funkin.ui.PixelatedIcon; import flixel.system.debug.watch.Tracker.TrackerProfile; import flixel.math.FlxPoint; import flixel.tweens.FlxTween; import openfl.display.BlendMode; import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.FlxSprite; import flixel.group.FlxSpriteGroup; import funkin.play.stage.Stage; import funkin.modding.events.ScriptEvent; @@ -284,21 +285,11 @@ class CharSelectSubState extends MusicBeatSubState if (availableChars.exists(i)) { var path:String = availableChars.get(i); - var temp:CharIconCharacter = new CharIconCharacter(path); + var temp:PixelatedIcon = new PixelatedIcon(0, 0); + temp.setCharacter(path); + temp.setGraphicSize(128, 128); + temp.updateHitbox(); temp.ID = 0; - - var idleAnimPrefix:String = switch (path) - { - case "pico": - "Pico Icon"; - case "bf": - "boyfriend icon instance 1"; - case _: - "Pico Icon"; - }; - - // temp.animation.addByPrefix("idle", idleAnimPrefix, 0, false); - // temp.animation.play("idle"); grpIcons.add(temp); } else @@ -567,17 +558,19 @@ class CharSelectSubState extends MusicBeatSubState member.animation.play("idle"); } case 0: - var memb:CharIconCharacter = cast member; + var memb:PixelatedIcon = cast member; if (index == getCurrentSelected()) { // memb.pixels = memb.withDropShadow.clone(); - memb.setGraphicSize(128 * 1.3); + memb.scale.set(2.6, 2.6); + + if (controls.ACCEPT) memb.animation.play("confirm"); } else { // memb.pixels = memb.noDropShadow.clone(); - memb.setGraphicSize(128); + memb.scale.set(2, 2); } } } diff --git a/source/funkin/ui/freeplay/SongMenuItem.hx b/source/funkin/ui/freeplay/SongMenuItem.hx index 68525a5f7..2eec83223 100644 --- a/source/funkin/ui/freeplay/SongMenuItem.hx +++ b/source/funkin/ui/freeplay/SongMenuItem.hx @@ -24,12 +24,13 @@ import funkin.play.scoring.Scoring.ScoringRank; import funkin.save.Save; import funkin.save.Save.SaveScoreData; import flixel.util.FlxColor; +import funkin.ui.PixelatedIcon; class SongMenuItem extends FlxSpriteGroup { public var capsule:FlxSprite; - var pixelIcon:FlxSprite; + var pixelIcon:PixelatedIcon; /** * Modify this by calling `init()` @@ -201,11 +202,7 @@ class SongMenuItem extends FlxSpriteGroup // TODO: Use value from metadata instead of random. updateDifficultyRating(FlxG.random.int(0, 20)); - pixelIcon = new FlxSprite(160, 35); - - pixelIcon.makeGraphic(32, 32, 0x00000000); - pixelIcon.antialiasing = false; - pixelIcon.active = false; + pixelIcon = new PixelatedIcon(160, 35); add(pixelIcon); grpHide.add(pixelIcon); @@ -512,7 +509,7 @@ class SongMenuItem extends FlxSpriteGroup // Update capsule text. songText.text = songData?.songName ?? 'Random'; // Update capsule character. - if (songData?.songCharacter != null) setCharacter(songData.songCharacter); + if (songData?.songCharacter != null) pixelIcon.setCharacter(songData.songCharacter); updateBPM(Std.int(songData?.songStartingBpm) ?? 0); updateDifficultyRating(songData?.difficultyRating ?? 0); updateScoringRank(songData?.scoringRank); @@ -526,76 +523,6 @@ class SongMenuItem extends FlxSpriteGroup checkWeek(songData?.songId); } - /** - * Set the character displayed next to this song in the freeplay menu. - * @param char The character ID used by this song. - * If the character has no freeplay icon, a warning will be thrown and nothing will display. - */ - public function setCharacter(char:String):Void - { - var charPath:String = "freeplay/icons/"; - - // TODO: Put this in the character metadata where it belongs. - // TODO: Also, can use CharacterDataParser.getCharPixelIconAsset() - switch (char) - { - case 'monster-christmas': - charPath += 'monsterpixel'; - case 'mom-car': - charPath += 'mommypixel'; - case 'darnell-blazin': - charPath += 'darnellpixel'; - case 'senpai-angry': - charPath += 'senpaipixel'; - default: - charPath += '${char}pixel'; - } - - if (!openfl.utils.Assets.exists(Paths.image(charPath))) - { - trace('[WARN] Character ${char} has no freeplay icon.'); - return; - } - - var isAnimated = openfl.utils.Assets.exists(Paths.file('images/$charPath.xml')); - - if (isAnimated) - { - pixelIcon.frames = Paths.getSparrowAtlas(charPath); - } - else - { - pixelIcon.loadGraphic(Paths.image(charPath)); - } - - pixelIcon.scale.x = pixelIcon.scale.y = 2; - - switch (char) - { - case 'parents-christmas': - pixelIcon.origin.x = 140; - default: - pixelIcon.origin.x = 100; - } - // pixelIcon.origin.x = capsule.origin.x; - // pixelIcon.offset.x -= pixelIcon.origin.x; - - if (isAnimated) - { - pixelIcon.active = true; - - pixelIcon.animation.addByPrefix('idle', 'idle0', 10, true); - pixelIcon.animation.addByPrefix('confirm', 'confirm0', 10, false); - pixelIcon.animation.addByPrefix('confirm-hold', 'confirm-hold0', 10, true); - - pixelIcon.animation.finishCallback = function(name:String):Void { - trace('Finish pixel animation: ${name}'); - if (name == 'confirm') pixelIcon.animation.play('confirm-hold'); - }; - - pixelIcon.animation.play('idle'); - } - } var frameInTicker:Float = 0; var frameInTypeBeat:Int = 0; From d7105e8b8e26e2fe1337c14862f7968f5dcd7893 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Mon, 8 Jul 2024 16:22:38 -0400 Subject: [PATCH 08/10] change debug menu and add key for freeplay --- source/funkin/ui/debug/DebugMenuSubState.hx | 2 ++ source/funkin/ui/freeplay/FreeplayState.hx | 5 +++++ source/funkin/ui/mainmenu/MainMenuState.hx | 4 +--- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/source/funkin/ui/debug/DebugMenuSubState.hx b/source/funkin/ui/debug/DebugMenuSubState.hx index 22dc5dba6..590cce88b 100644 --- a/source/funkin/ui/debug/DebugMenuSubState.hx +++ b/source/funkin/ui/debug/DebugMenuSubState.hx @@ -54,7 +54,9 @@ class DebugMenuSubState extends MusicBeatSubState // Create each menu item. // Call onMenuChange when the first item is created to move the camera . + #if CHART_EDITOR_SUPPORTED onMenuChange(createItem("CHART EDITOR", openChartEditor)); + #end // createItem("Input Offset Testing", openInputOffsetTesting); createItem("CHARACTER SELECT", openCharSelect, true); createItem("ANIMATION EDITOR", openAnimationEditor); diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 3b003cf89..4b0ae7839 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -1206,6 +1206,11 @@ class FreeplayState extends MusicBeatSubState // } #end + if (FlxG.keys.justPressed.TAB) + { + FlxG.switchState(new funkin.ui.charSelect.CharSelectSubState()); + } + if (controls.FREEPLAY_FAVORITE && !busy) { var targetSong = grpCapsules.members[curSelected]?.songData; diff --git a/source/funkin/ui/mainmenu/MainMenuState.hx b/source/funkin/ui/mainmenu/MainMenuState.hx index 2eba406d9..eab116c86 100644 --- a/source/funkin/ui/mainmenu/MainMenuState.hx +++ b/source/funkin/ui/mainmenu/MainMenuState.hx @@ -341,17 +341,15 @@ class MainMenuState extends MusicBeatState } } + #if (debug || FORCE_DEBUG_VERSION) // Open the debug menu, defaults to ` / ~ - #if CHART_EDITOR_SUPPORTED if (controls.DEBUG_MENU) { persistentUpdate = false; FlxG.state.openSubState(new DebugMenuSubState()); } - #end - #if (debug || FORCE_DEBUG_VERSION) if (FlxG.keys.pressed.CONTROL && FlxG.keys.pressed.ALT && FlxG.keys.pressed.SHIFT && FlxG.keys.justPressed.W) { // Give the user a score of 1 point on Weekend 1 story mode. From 57c995e19d0024335c2244c5868e355847e70872 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Mon, 8 Jul 2024 16:30:17 -0400 Subject: [PATCH 09/10] char select screen controls stuff --- source/funkin/ui/charSelect/CharSelectSubState.hx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source/funkin/ui/charSelect/CharSelectSubState.hx b/source/funkin/ui/charSelect/CharSelectSubState.hx index d73366390..14a5b36e0 100644 --- a/source/funkin/ui/charSelect/CharSelectSubState.hx +++ b/source/funkin/ui/charSelect/CharSelectSubState.hx @@ -1,5 +1,6 @@ package funkin.ui.charSelect; +import funkin.ui.freeplay.FreeplayState; import flixel.text.FlxText; import funkin.ui.PixelatedIcon; import flixel.system.debug.watch.Tracker.TrackerProfile; @@ -451,7 +452,12 @@ class CharSelectSubState extends MusicBeatSubState pressedSelect = true; selectTimer.start(1.5, (_) -> { pressedSelect = false; - close(); + FlxG.switchState(FreeplayState.build( + { + { + character: curChar + } + })); }); } From 3a37b79a55e0ddb940f18988372b77e11a03a010 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Mon, 8 Jul 2024 16:40:10 -0400 Subject: [PATCH 10/10] add TAB to controls stuff --- source/funkin/input/Controls.hx | 16 ++++++++++++++++ source/funkin/ui/freeplay/FreeplayState.hx | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/source/funkin/input/Controls.hx b/source/funkin/input/Controls.hx index f6c881f6d..6b8e9aa3e 100644 --- a/source/funkin/input/Controls.hx +++ b/source/funkin/input/Controls.hx @@ -64,6 +64,7 @@ class Controls extends FlxActionSet var _freeplay_favorite = new FunkinAction(Action.FREEPLAY_FAVORITE); var _freeplay_left = new FunkinAction(Action.FREEPLAY_LEFT); var _freeplay_right = new FunkinAction(Action.FREEPLAY_RIGHT); + var _freeplay_char_select = new FunkinAction(Action.FREEPLAY_CHAR_SELECT); var _cutscene_advance = new FunkinAction(Action.CUTSCENE_ADVANCE); var _debug_menu = new FunkinAction(Action.DEBUG_MENU); var _debug_chart = new FunkinAction(Action.DEBUG_CHART); @@ -262,6 +263,11 @@ class Controls extends FlxActionSet inline function get_FREEPLAY_RIGHT() return _freeplay_right.check(); + public var FREEPLAY_CHAR_SELECT(get, never):Bool; + + inline function get_FREEPLAY_CHAR_SELECT() + return _freeplay_char_select.check(); + public var CUTSCENE_ADVANCE(get, never):Bool; inline function get_CUTSCENE_ADVANCE() @@ -318,6 +324,7 @@ class Controls extends FlxActionSet add(_freeplay_favorite); add(_freeplay_left); add(_freeplay_right); + add(_freeplay_char_select); add(_cutscene_advance); add(_debug_menu); add(_debug_chart); @@ -424,6 +431,7 @@ class Controls extends FlxActionSet case FREEPLAY_FAVORITE: _freeplay_favorite; case FREEPLAY_LEFT: _freeplay_left; case FREEPLAY_RIGHT: _freeplay_right; + case FREEPLAY_CHAR_SELECT: _freeplay_char_select; case CUTSCENE_ADVANCE: _cutscene_advance; case DEBUG_MENU: _debug_menu; case DEBUG_CHART: _debug_chart; @@ -500,6 +508,8 @@ class Controls extends FlxActionSet func(_freeplay_left, JUST_PRESSED); case FREEPLAY_RIGHT: func(_freeplay_right, JUST_PRESSED); + case FREEPLAY_CHAR_SELECT: + func(_freeplay_char_select, JUST_PRESSED); case CUTSCENE_ADVANCE: func(_cutscene_advance, JUST_PRESSED); case DEBUG_MENU: @@ -721,6 +731,7 @@ class Controls extends FlxActionSet bindKeys(Control.FREEPLAY_FAVORITE, getDefaultKeybinds(scheme, Control.FREEPLAY_FAVORITE)); bindKeys(Control.FREEPLAY_LEFT, getDefaultKeybinds(scheme, Control.FREEPLAY_LEFT)); bindKeys(Control.FREEPLAY_RIGHT, getDefaultKeybinds(scheme, Control.FREEPLAY_RIGHT)); + bindKeys(Control.FREEPLAY_CHAR_SELECT, getDefaultKeybinds(scheme, Control.FREEPLAY_CHAR_SELECT)); bindKeys(Control.CUTSCENE_ADVANCE, getDefaultKeybinds(scheme, Control.CUTSCENE_ADVANCE)); bindKeys(Control.DEBUG_MENU, getDefaultKeybinds(scheme, Control.DEBUG_MENU)); bindKeys(Control.DEBUG_CHART, getDefaultKeybinds(scheme, Control.DEBUG_CHART)); @@ -756,6 +767,7 @@ class Controls extends FlxActionSet case Control.FREEPLAY_FAVORITE: return [F]; // Favorite a song on the menu case Control.FREEPLAY_LEFT: return [Q]; // Switch tabs on the menu case Control.FREEPLAY_RIGHT: return [E]; // Switch tabs on the menu + case Control.FREEPLAY_CHAR_SELECT: return [TAB]; case Control.CUTSCENE_ADVANCE: return [Z, ENTER]; case Control.DEBUG_MENU: return [GRAVEACCENT]; case Control.DEBUG_CHART: return []; @@ -784,6 +796,7 @@ class Controls extends FlxActionSet case Control.FREEPLAY_FAVORITE: return [F]; // Favorite a song on the menu case Control.FREEPLAY_LEFT: return [Q]; // Switch tabs on the menu case Control.FREEPLAY_RIGHT: return [E]; // Switch tabs on the menu + case Control.FREEPLAY_CHAR_SELECT: return [TAB]; case Control.CUTSCENE_ADVANCE: return [G, Z]; case Control.DEBUG_MENU: return [GRAVEACCENT]; case Control.DEBUG_CHART: return []; @@ -812,6 +825,7 @@ class Controls extends FlxActionSet case Control.FREEPLAY_FAVORITE: return []; case Control.FREEPLAY_LEFT: return []; case Control.FREEPLAY_RIGHT: return []; + case Control.FREEPLAY_CHAR_SELECT: return []; case Control.CUTSCENE_ADVANCE: return [ENTER]; case Control.DEBUG_MENU: return []; case Control.DEBUG_CHART: return []; @@ -1548,6 +1562,7 @@ enum Control FREEPLAY_FAVORITE; FREEPLAY_LEFT; FREEPLAY_RIGHT; + FREEPLAY_CHAR_SELECT; // WINDOW WINDOW_SCREENSHOT; WINDOW_FULLSCREEN; @@ -1602,6 +1617,7 @@ enum abstract Action(String) to String from String var FREEPLAY_FAVORITE = "freeplay_favorite"; var FREEPLAY_LEFT = "freeplay_left"; var FREEPLAY_RIGHT = "freeplay_right"; + var FREEPLAY_CHAR_SELECT = "freeplay_char_select"; // VOLUME var VOLUME_UP = "volume_up"; var VOLUME_DOWN = "volume_down"; diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index eef5d9e68..dc42bd651 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -1232,7 +1232,7 @@ class FreeplayState extends MusicBeatSubState // } #end - if (FlxG.keys.justPressed.TAB) + if (controls.FREEPLAY_CHAR_SELECT && !busy) { FlxG.switchState(new funkin.ui.charSelect.CharSelectSubState()); }