1
0
Fork 0
mirror of https://github.com/ninjamuffin99/Funkin.git synced 2024-12-27 07:27:12 +00:00
Funkin/source/funkin/ui/charSelect/CharSelectSubState.hx

967 lines
27 KiB
Haxe
Raw Normal View History

2024-06-15 04:59:58 +00:00
package funkin.ui.charSelect;
2024-09-09 06:23:46 +00:00
import openfl.filters.BitmapFilter;
2024-06-15 04:59:58 +00:00
import flixel.FlxObject;
2024-07-03 01:26:16 +00:00
import flixel.FlxSprite;
2024-06-15 04:59:58 +00:00
import flixel.group.FlxGroup;
import flixel.group.FlxGroup.FlxTypedGroup;
2024-06-15 04:59:58 +00:00
import flixel.group.FlxSpriteGroup;
import flixel.math.FlxPoint;
2024-06-15 04:59:58 +00:00
import flixel.sound.FlxSound;
import flixel.system.debug.watch.Tracker.TrackerProfile;
import flixel.text.FlxText;
import flixel.tweens.FlxEase;
import flixel.tweens.FlxTween;
import flixel.util.FlxTimer;
2024-06-15 04:59:58 +00:00
import funkin.audio.FunkinSound;
import funkin.data.freeplay.player.PlayerData;
import funkin.data.freeplay.player.PlayerRegistry;
import funkin.graphics.adobeanimate.FlxAtlasSprite;
2024-09-06 04:28:08 +00:00
import openfl.filters.DropShadowFilter;
2024-08-22 21:36:43 +00:00
import funkin.graphics.FunkinCamera;
2024-09-06 00:55:47 +00:00
import funkin.graphics.shaders.BlueFade;
2024-06-15 04:59:58 +00:00
import funkin.modding.events.ScriptEvent;
import funkin.modding.events.ScriptEventDispatcher;
import funkin.play.stage.Stage;
2024-09-06 00:55:47 +00:00
import funkin.save.Save;
import funkin.ui.freeplay.charselect.PlayableCharacter;
import funkin.ui.freeplay.FreeplayState;
import funkin.ui.PixelatedIcon;
2024-06-15 04:59:58 +00:00
import funkin.util.MathUtil;
2024-08-22 21:36:43 +00:00
import funkin.vis.dsp.SpectralAnalyzer;
import openfl.display.BlendMode;
2024-09-06 00:55:47 +00:00
import funkin.save.Save;
2024-08-23 12:36:00 +00:00
import openfl.filters.ShaderFilter;
2024-09-09 06:23:46 +00:00
import funkin.util.FramesJSFLParser;
import funkin.util.FramesJSFLParser.FramesJSFLInfo;
import funkin.util.FramesJSFLParser.FramesJSFLFrame;
2024-06-15 04:59:58 +00:00
class CharSelectSubState extends MusicBeatSubState
{
var cursor:FlxSprite;
var cursorBlue:FlxSprite;
var cursorDarkBlue:FlxSprite;
var grpCursors:FlxTypedGroup<FlxSprite>;
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;
2024-08-23 12:36:00 +00:00
var barthing:FlxAtlasSprite;
var dipshitBacking:FlxSprite;
var chooseDipshit:FlxSprite;
var dipshitBlur:FlxSprite;
var transitionGradient:FlxSprite;
2024-06-15 04:59:58 +00:00
var curChar(default, set):String = "pico";
var nametag:Nametag;
var camFollow:FlxObject;
2024-08-23 12:36:00 +00:00
var autoFollow:Bool = false;
2024-06-15 04:59:58 +00:00
var availableChars:Map<Int, String> = new Map<Int, String>();
var pressedSelect:Bool = false;
var selectTimer:FlxTimer = new FlxTimer();
var selectSound:FunkinSound;
var unlockSound:FunkinSound;
2024-06-15 04:59:58 +00:00
2024-08-22 21:36:43 +00:00
var charSelectCam:FunkinCamera;
2024-09-09 06:23:46 +00:00
var selectedBizz:Array<BitmapFilter> = [
new DropShadowFilter(0, 0, 0xFFFFFF, 1, 2, 2, 21, 1, false, false, false),
new DropShadowFilter(5, 45, 0x000000, 1, 2, 2, 1, 1, false, false, false)
];
var bopInfo:FramesJSFLInfo;
2024-06-15 04:59:58 +00:00
public function new()
{
super();
2024-08-28 10:09:14 +00:00
loadAvailableCharacters();
}
function loadAvailableCharacters():Void
{
var playerIds:Array<String> = PlayerRegistry.instance.listEntryIds();
for (playerId in playerIds)
{
var player:Null<PlayableCharacter> = PlayerRegistry.instance.fetchEntry(playerId);
if (player == null) continue;
var playerData = player.getCharSelectData();
if (playerData == null) continue;
2024-09-06 00:55:47 +00:00
trace(player.isUnlocked());
2024-08-28 10:09:14 +00:00
var targetPosition:Int = playerData.position ?? 0;
while (availableChars.exists(targetPosition))
{
targetPosition += 1;
}
trace('Placing player ${playerId} at position ${targetPosition}');
availableChars.set(targetPosition, playerId);
}
2024-06-15 04:59:58 +00:00
}
2024-08-23 12:36:00 +00:00
var fadeShader:BlueFade = new BlueFade();
2024-06-15 07:27:59 +00:00
override public function create():Void
2024-06-15 04:59:58 +00:00
{
super.create();
2024-09-09 06:23:46 +00:00
bopInfo = FramesJSFLParser.parse(Paths.file("images/charSelect/iconBopInfo/iconBopInfo.txt"));
2024-06-15 04:59:58 +00:00
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");
2024-09-01 07:22:34 +00:00
stageSpr.animation.addByPrefix("idle", "stage full instance 1", 24, true);
2024-06-15 04:59:58 +00:00
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);
2024-08-23 12:36:00 +00:00
barthing = new FlxAtlasSprite(0, 0, Paths.animateAtlas("charSelect/barThing"));
2024-06-15 04:59:58 +00:00
barthing.anim.play("");
barthing.blend = BlendMode.MULTIPLY;
barthing.scrollFactor.set(0, 0);
add(barthing);
2024-08-23 12:36:00 +00:00
barthing.y += 80;
FlxTween.tween(barthing, {y: barthing.y - 80}, 1.3, {ease: FlxEase.expoOut});
2024-06-15 04:59:58 +00:00
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);
playerChillOut = new CharSelectPlayer(0, 0);
playerChillOut.switchChar("bf");
add(playerChillOut);
2024-09-06 00:55:47 +00:00
playerChill = new CharSelectPlayer(0, 0);
playerChill.switchChar("bf");
add(playerChill);
2024-06-15 04:59:58 +00:00
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);
2024-08-23 12:36:00 +00:00
dipshitBlur = new FlxSprite(419, -65);
2024-06-15 04:59:58 +00:00
dipshitBlur.frames = Paths.getSparrowAtlas("charSelect/dipshitBlur");
2024-09-01 07:22:34 +00:00
dipshitBlur.animation.addByPrefix('idle', "CHOOSE vertical offset instance 1", 24, true);
2024-06-15 04:59:58 +00:00
dipshitBlur.blend = BlendMode.ADD;
dipshitBlur.animation.play("idle");
add(dipshitBlur);
2024-08-23 12:36:00 +00:00
dipshitBacking = new FlxSprite(423, -17);
2024-06-15 04:59:58 +00:00
dipshitBacking.frames = Paths.getSparrowAtlas("charSelect/dipshitBacking");
2024-09-01 07:22:34 +00:00
dipshitBacking.animation.addByPrefix('idle', "CHOOSE horizontal offset instance 1", 24, true);
2024-06-15 04:59:58 +00:00
dipshitBacking.blend = BlendMode.ADD;
dipshitBacking.animation.play("idle");
add(dipshitBacking);
2024-08-23 12:36:00 +00:00
dipshitBacking.y += 210;
FlxTween.tween(dipshitBacking, {y: dipshitBacking.y - 210}, 1.1, {ease: FlxEase.expoOut});
chooseDipshit = new FlxSprite(426, -13);
2024-06-15 04:59:58 +00:00
chooseDipshit.loadGraphic(Paths.image('charSelect/chooseDipshit'));
add(chooseDipshit);
2024-08-23 12:36:00 +00:00
chooseDipshit.y += 200;
FlxTween.tween(chooseDipshit, {y: chooseDipshit.y - 200}, 1, {ease: FlxEase.expoOut});
dipshitBlur.y += 220;
FlxTween.tween(dipshitBlur, {y: dipshitBlur.y - 220}, 1.2, {ease: FlxEase.expoOut});
2024-06-15 04:59:58 +00:00
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<FlxSprite>();
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");
2024-09-01 07:22:34 +00:00
cursorConfirmed.animation.addByPrefix("idle", "cursor ACCEPTED instance 1", 24, true);
2024-06-15 04:59:58 +00:00
cursorConfirmed.visible = false;
add(cursorConfirmed);
cursorDenied = new FlxSprite(0, 0);
cursorDenied.scrollFactor.set();
cursorDenied.frames = Paths.getSparrowAtlas("charSelect/charSelectorDenied");
2024-09-01 07:22:34 +00:00
cursorDenied.animation.addByPrefix("idle", "cursor DENIED instance 1", 24, false);
2024-06-15 04:59:58 +00:00
cursorDenied.visible = false;
add(cursorDenied);
grpCursors.add(cursorDarkBlue);
grpCursors.add(cursorBlue);
grpCursors.add(cursor);
selectSound = new FunkinSound();
selectSound.loadEmbedded(Paths.sound('CS_select'));
selectSound.pitch = 1;
selectSound.volume = 0.7;
FlxG.sound.defaultSoundGroup.add(selectSound);
unlockSound = new FunkinSound();
unlockSound.loadEmbedded(Paths.sound('CS_unlock'));
unlockSound.pitch = 1;
2024-09-09 06:23:46 +00:00
unlockSound.volume = 0;
unlockSound.play(true);
FlxG.sound.defaultSoundGroup.add(unlockSound);
2024-09-09 06:23:46 +00:00
// 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,
overrideExisting: true,
restartTrack: true,
});
2024-06-15 04:59:58 +00:00
initLocks();
2024-08-23 12:36:00 +00:00
for (index => member in grpIcons.members)
{
member.y += 300;
FlxTween.tween(member, {y: member.y - 300}, 1, {ease: FlxEase.expoOut});
}
2024-06-15 04:59:58 +00:00
cursor.scrollFactor.set();
cursorBlue.scrollFactor.set();
cursorDarkBlue.scrollFactor.set();
2024-08-27 20:13:52 +00:00
FlxTween.color(cursor, 0.2, 0xFFFFFF00, 0xFFFFCC00, {type: PINGPONG});
2024-06-15 04:59:58 +00:00
// FlxG.debugger.track(cursor);
FlxG.debugger.addTrackerProfile(new TrackerProfile(CharSelectSubState, ["curChar", "grpXSpread", "grpYSpread"]));
FlxG.debugger.track(this);
camFollow = new FlxObject(0, 0, 1, 1);
add(camFollow);
camFollow.screenCenter();
2024-08-23 12:36:00 +00:00
// FlxG.camera.follow(camFollow, LOCKON, 0.01);
FlxG.camera.follow(camFollow, LOCKON);
2024-06-15 04:59:58 +00:00
var temp:FlxSprite = new FlxSprite();
temp.loadGraphic(Paths.image('charSelect/placement'));
add(temp);
temp.alpha = 0.0;
2024-09-06 00:55:47 +00:00
2024-06-15 04:59:58 +00:00
Conductor.stepHit.add(spamOnStep);
// FlxG.debugger.track(temp, "tempBG");
2024-08-23 12:36:00 +00:00
transitionGradient = new FlxSprite(0, 0).loadGraphic(Paths.image('freeplay/transitionGradient'));
transitionGradient.scale.set(1280, 1);
transitionGradient.flipY = true;
transitionGradient.updateHitbox();
FlxTween.tween(transitionGradient, {y: -720}, 1, {ease: FlxEase.expoOut});
add(transitionGradient);
camFollow.screenCenter();
camFollow.y -= 150;
fadeShader.fade(0.0, 1.0, 0.8, {ease: FlxEase.quadOut});
FlxTween.tween(camFollow, {y: camFollow.y + 150}, 1.5,
{
ease: FlxEase.expoOut,
onComplete: function(_) {
autoFollow = true;
FlxG.camera.follow(camFollow, LOCKON, 0.01);
}
});
2024-06-15 04:59:58 +00:00
}
var grpIcons:FlxSpriteGroup;
var grpXSpread(default, set):Float = 107;
var grpYSpread(default, set):Float = 127;
2024-09-06 00:55:47 +00:00
var nonLocks = [];
2024-08-29 19:26:35 +00:00
function initLocks():Void
2024-06-15 04:59:58 +00:00
{
grpIcons = new FlxSpriteGroup();
add(grpIcons);
FlxG.debugger.addTrackerProfile(new TrackerProfile(FlxSpriteGroup, ["x", "y"]));
// FlxG.debugger.track(grpIcons, "iconGrp");
for (i in 0...9)
{
2024-09-06 00:55:47 +00:00
if (availableChars.exists(i) && Save.instance.charactersSeen.contains(availableChars[i]))
2024-06-15 04:59:58 +00:00
{
var path:String = availableChars.get(i);
2024-07-03 01:26:16 +00:00
var temp:PixelatedIcon = new PixelatedIcon(0, 0);
temp.setCharacter(path);
temp.setGraphicSize(128, 128);
temp.updateHitbox();
2024-06-15 04:59:58 +00:00
temp.ID = 0;
grpIcons.add(temp);
}
else
{
2024-09-06 00:55:47 +00:00
if (availableChars.exists(i)) nonLocks.push(i);
2024-09-04 18:08:38 +00:00
var temp:Lock = new Lock(0, 0, i);
2024-06-15 04:59:58 +00:00
temp.ID = 1;
2024-09-06 00:55:47 +00:00
temp.onAnimationComplete.add(function(anim) {
if (anim == "unlock") playerChill.playAnimation("unlock", true);
});
2024-06-15 04:59:58 +00:00
grpIcons.add(temp);
}
}
updateIconPositions();
grpIcons.scrollFactor.set();
2024-09-06 00:55:47 +00:00
2024-09-09 06:23:46 +00:00
if (nonLocks.length > 0) unLock();
else
FunkinSound.playMusic('stayFunky',
{
startingVolume: 1,
overrideExisting: true,
restartTrack: true,
onLoad: function() {
@:privateAccess
gfChill.analyzer = new SpectralAnalyzer(FlxG.sound.music._channel.__audioSource, 7, 0.1);
#if desktop
// On desktop it uses FFT stuff that isn't as optimized as the direct browser stuff we use on HTML5
// So we want to manually change it!
@:privateAccess
gfChill.analyzer.fftN = 512;
#end
}
});
2024-09-06 00:55:47 +00:00
}
function unLock()
{
var index = nonLocks[0];
var copy = 3;
var yThing = -1;
2024-09-06 00:55:47 +00:00
while ((index + 1) > copy)
2024-09-06 00:55:47 +00:00
{
yThing++;
copy += 3;
}
var xThing = (copy - index - 2) * -1;
// Look, I'd write better code but I had better aneurysms, my bad - Cheems
cursorY = yThing;
cursorX = xThing;
2024-09-06 00:55:47 +00:00
selectSound.play(true);
nonLocks.shift();
2024-09-06 00:55:47 +00:00
selectTimer.start(1, function(_) {
var lock:Lock = cast grpIcons.group.members[index];
lock.anim.getFrameLabel("unlockAnim").add(function() {
playerChillOut.playAnimation("death");
});
2024-09-06 00:55:47 +00:00
lock.playAnimation("unlock");
2024-09-09 06:23:46 +00:00
unlockSound.volume = 0.7;
unlockSound.play(true);
2024-09-06 00:55:47 +00:00
lock.onAnimationComplete.addOnce(function(_) {
2024-09-09 06:23:46 +00:00
var char = availableChars.get(index);
camera.flash(0xFFFFFFFF, 0.1);
2024-09-06 00:55:47 +00:00
playerChill.playAnimation("unlock");
playerChill.visible = true;
2024-09-09 06:23:46 +00:00
var id = grpIcons.members.indexOf(lock);
nametag.switchChar(char);
gfChill.switchGF(char);
var icon = new PixelatedIcon(0, 0);
icon.setCharacter(char);
icon.setGraphicSize(128, 128);
icon.updateHitbox();
grpIcons.insert(id, icon);
grpIcons.remove(lock, true);
icon.ID = 0;
bopPlay = true;
updateIconPositions();
if (nonLocks.length == 0)
{
2024-09-09 06:23:46 +00:00
playerChillOut.onAnimationComplete.addOnce((_) -> playerChillOut.switchChar(char));
@:bypassAccessor curChar = char;
Save.instance.addCharacterSeen(char);
FunkinSound.playMusic('stayFunky',
{
startingVolume: 1,
overrideExisting: true,
restartTrack: true,
onLoad: function() {
@:privateAccess
gfChill.analyzer = new SpectralAnalyzer(FlxG.sound.music._channel.__audioSource, 7, 0.1);
#if desktop
// On desktop it uses FFT stuff that isn't as optimized as the direct browser stuff we use on HTML5
// So we want to manually change it!
@:privateAccess
gfChill.analyzer.fftN = 512;
#end
}
});
}
else
playerChill.onAnimationComplete.addOnce((_) -> unLock());
2024-09-06 00:55:47 +00:00
});
playerChill.visible = false;
playerChill.switchChar(availableChars[index]);
playerChillOut.visible = true;
2024-09-06 00:55:47 +00:00
});
2024-06-15 04:59:58 +00:00
}
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;
}
}
function goToFreeplay():Void
2024-08-23 12:36:00 +00:00
{
autoFollow = false;
FlxTween.tween(cursor, {alpha: 0}, 0.8, {ease: FlxEase.expoOut});
FlxTween.tween(cursorBlue, {alpha: 0}, 0.8, {ease: FlxEase.expoOut});
FlxTween.tween(cursorDarkBlue, {alpha: 0}, 0.8, {ease: FlxEase.expoOut});
FlxTween.tween(cursorConfirmed, {alpha: 0}, 0.8, {ease: FlxEase.expoOut});
2024-08-23 12:36:00 +00:00
FlxTween.tween(barthing, {y: barthing.y + 80}, 0.8, {ease: FlxEase.backIn});
FlxTween.tween(dipshitBacking, {y: dipshitBacking.y + 210}, 0.8, {ease: FlxEase.backIn});
FlxTween.tween(chooseDipshit, {y: chooseDipshit.y + 200}, 0.8, {ease: FlxEase.backIn});
FlxTween.tween(dipshitBlur, {y: dipshitBlur.y + 220}, 0.8, {ease: FlxEase.backIn});
for (index => member in grpIcons.members)
{
// member.y += 300;
FlxTween.tween(member, {y: member.y + 300}, 0.8, {ease: FlxEase.backIn});
}
FlxG.camera.follow(camFollow, LOCKON);
FlxTween.tween(transitionGradient, {y: -150}, 0.8, {ease: FlxEase.backIn});
fadeShader.fade(1.0, 0, 0.8, {ease: FlxEase.quadIn});
FlxTween.tween(camFollow, {y: camFollow.y - 150}, 0.8,
{
ease: FlxEase.backIn,
onComplete: function(_) {
FlxG.switchState(FreeplayState.build(
{
{
character: curChar,
fromCharSelect: true
2024-08-23 12:36:00 +00:00
}
}));
}
});
}
2024-06-15 04:59:58 +00:00
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;
2024-06-15 07:27:59 +00:00
override public function update(elapsed:Float):Void
2024-06-15 04:59:58 +00:00
{
super.update(elapsed);
2024-06-15 07:27:59 +00:00
Conductor.instance.update();
2024-06-15 04:59:58 +00:00
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;
2024-09-06 00:55:47 +00:00
cursorDenied.visible = false;
2024-06-15 04:59:58 +00:00
holdTmrUp = 0;
selectSound.play(true);
}
if (controls.UI_DOWN_P)
{
cursorY += 1;
2024-09-06 00:55:47 +00:00
cursorDenied.visible = false;
2024-06-15 04:59:58 +00:00
holdTmrDown = 0;
selectSound.play(true);
}
if (controls.UI_LEFT_P)
{
cursorX -= 1;
2024-09-06 00:55:47 +00:00
cursorDenied.visible = false;
2024-06-15 04:59:58 +00:00
holdTmrLeft = 0;
selectSound.play(true);
}
if (controls.UI_RIGHT_P)
{
cursorX += 1;
2024-09-06 00:55:47 +00:00
cursorDenied.visible = false;
2024-06-15 04:59:58 +00:00
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;
}
2024-09-06 00:55:47 +00:00
if (availableChars.exists(getCurrentSelected()) && Save.instance.charactersSeen.contains(availableChars[getCurrentSelected()]))
2024-06-15 04:59:58 +00:00
{
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'));
2024-08-23 12:36:00 +00:00
FlxTween.tween(FlxG.sound.music, {pitch: 0.1}, 1, {ease: FlxEase.quadInOut});
FlxTween.tween(FlxG.sound.music, {volume: 0.0}, 1.5, {ease: FlxEase.quadInOut});
2024-06-15 04:59:58 +00:00
playerChill.playAnimation("select");
2024-08-22 21:36:43 +00:00
gfChill.playAnimation("confirm");
2024-06-15 04:59:58 +00:00
pressedSelect = true;
selectTimer.start(1.5, (_) -> {
pressedSelect = false;
2024-08-23 12:36:00 +00:00
// FlxG.switchState(FreeplayState.build(
// {
// {
// character: curChar
// }
// }));
goToFreeplay();
2024-06-15 04:59:58 +00:00
});
}
if (pressedSelect && controls.BACK)
{
cursorConfirmed.visible = false;
grpCursors.visible = true;
FlxTween.globalManager.cancelTweensOf(FlxG.sound.music);
2024-08-23 12:36:00 +00:00
FlxTween.tween(FlxG.sound.music, {pitch: 1.0, volume: 1.0}, 1, {ease: FlxEase.quartInOut});
2024-06-15 04:59:58 +00:00
playerChill.playAnimation("deselect");
2024-08-22 21:36:43 +00:00
gfChill.playAnimation("deselect");
FlxTween.tween(FlxG.sound.music, {pitch: 1.0}, 1,
{
ease: FlxEase.quartInOut,
onComplete: (_) -> {
2024-08-28 00:48:56 +00:00
playerChill.playAnimation("idle", true, false, true);
gfChill.playAnimation("idle", true, false, true);
2024-08-22 21:36:43 +00:00
}
});
2024-06-15 04:59:58 +00:00
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();
2024-08-23 12:36:00 +00:00
if (autoFollow == true)
{
camFollow.screenCenter();
camFollow.x += cursorX * 10;
camFollow.y += cursorY * 10;
}
2024-06-15 04:59:58 +00:00
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);
}
2024-09-09 06:23:46 +00:00
var bopTimer:Float = 0;
var delay = 1 / 24;
var bopFr = 0;
var bopPlay:Bool = false;
var bopRefX:Float = 0;
var bopRefY:Float = 0;
function doBop(icon:PixelatedIcon, elapsed:Float):Void
{
if (bopFr >= bopInfo.frames.length)
{
bopRefX = 0;
bopRefY = 0;
bopPlay = false;
bopFr = 0;
return;
}
bopTimer += elapsed;
if (bopTimer >= delay)
{
bopTimer -= bopTimer;
var refFrame = bopInfo.frames[bopInfo.frames.length - 1];
var curFrame = bopInfo.frames[bopFr];
var xDiff:Float = curFrame.x - refFrame.x;
var yDiff:Float = curFrame.y - refFrame.y;
var scaleXDiff:Float = curFrame.scaleX - refFrame.scaleX;
var scaleYDiff:Float = curFrame.scaleY - refFrame.scaleY;
icon.scale.set(2.6, 2.6);
icon.scale.add(scaleXDiff, scaleYDiff);
bopFr++;
}
}
2024-09-01 07:22:34 +00:00
public override function dispatchEvent(event:ScriptEvent):Void
{
// super.dispatchEvent(event) dispatches event to module scripts.
super.dispatchEvent(event);
// Dispatch events (like onBeatHit) to props
ScriptEventDispatcher.callEvent(playerChill, event);
ScriptEventDispatcher.callEvent(gfChill, event);
}
2024-06-15 04:59:58 +00:00
2024-06-15 07:27:59 +00:00
function spamOnStep():Void
2024-06-15 04:59:58 +00:00
{
if (spamUp || spamDown || spamLeft || spamRight)
{
2024-06-15 06:03:22 +00:00
// selectSound.changePitchBySemitone(1);
2024-06-15 04:59:58 +00:00
if (selectSound.pitch > 5) selectSound.pitch = 5;
selectSound.play(true);
2024-09-06 00:55:47 +00:00
cursorDenied.visible = false;
2024-06-15 04:59:58 +00:00
if (spamUp)
{
cursorY -= 1;
holdTmrUp = 0;
}
if (spamDown)
{
cursorY += 1;
holdTmrDown = 0;
}
if (spamLeft)
{
cursorX -= 1;
holdTmrLeft = 0;
}
if (spamRight)
{
cursorX += 1;
holdTmrRight = 0;
}
}
}
2024-06-15 07:27:59 +00:00
private function updateLockAnims():Void
2024-06-15 04:59:58 +00:00
{
for (index => member in grpIcons.group.members)
{
switch (member.ID)
{
case 1:
2024-09-04 18:08:38 +00:00
var lock:Lock = cast member;
2024-06-15 04:59:58 +00:00
if (index == getCurrentSelected())
{
2024-09-04 18:08:38 +00:00
switch (lock.getCurrentAnimation())
2024-06-15 04:59:58 +00:00
{
case "idle":
2024-09-04 18:08:38 +00:00
lock.playAnimation("selected");
2024-06-15 04:59:58 +00:00
case "selected" | "clicked":
2024-09-09 06:23:46 +00:00
if (controls.ACCEPT) lock.playAnimation("clicked", true);
2024-06-15 04:59:58 +00:00
}
}
else
{
2024-09-04 18:08:38 +00:00
lock.playAnimation("idle");
2024-06-15 04:59:58 +00:00
}
case 0:
2024-07-03 01:26:16 +00:00
var memb:PixelatedIcon = cast member;
2024-06-15 04:59:58 +00:00
if (index == getCurrentSelected())
{
// memb.pixels = memb.withDropShadow.clone();
2024-09-09 06:23:46 +00:00
memb.filters = selectedBizz;
if (bopPlay)
{
if (bopRefX == 0)
{
bopRefX = memb.x;
bopRefY = memb.y;
}
doBop(memb, FlxG.elapsed);
}
else
memb.scale.set(2.6, 2.6);
2024-07-03 01:26:16 +00:00
if (controls.ACCEPT) memb.animation.play("confirm");
2024-09-06 00:55:47 +00:00
if (memb.animation.curAnim.name == "confirm" && controls.BACK)
2024-08-22 21:36:43 +00:00
{
memb.animation.play("confirm", false, true);
member.animation.finishCallback = (_) -> {
member.animation.play("idle");
member.animation.finishCallback = null;
};
}
2024-06-15 04:59:58 +00:00
}
else
{
// memb.pixels = memb.noDropShadow.clone();
2024-09-09 06:23:46 +00:00
memb.filters = null;
2024-07-03 01:26:16 +00:00
memb.scale.set(2, 2);
2024-06-15 04:59:58 +00:00
}
}
}
}
2024-06-15 07:27:59 +00:00
function getCurrentSelected():Int
2024-06-15 04:59:58 +00:00
{
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;
2024-08-28 00:48:56 +00:00
playerChillOut.playAnimation("slideout");
var index = playerChillOut.anim.getFrameLabel("slideout").index;
playerChillOut.onAnimationFrame.add((_, frame:Int) -> {
2024-08-28 00:48:56 +00:00
if (frame == index + 1)
2024-06-15 04:59:58 +00:00
{
playerChill.visible = true;
playerChill.switchChar(value);
gfChill.switchGF(value);
}
2024-08-28 00:48:56 +00:00
if (frame == index + 2)
2024-06-15 04:59:58 +00:00
{
playerChillOut.switchChar(value);
playerChillOut.visible = false;
2024-08-28 00:48:56 +00:00
playerChillOut.onAnimationFrame.removeAll();
2024-06-15 04:59:58 +00:00
}
});
2024-08-28 00:48:56 +00:00
2024-06-15 04:59:58 +00:00
return value;
}
function set_grpXSpread(value:Float):Float
{
grpXSpread = value;
updateIconPositions();
return value;
}
function set_grpYSpread(value:Float):Float
{
grpYSpread = value;
updateIconPositions();
return value;
}
}