diff --git a/Project.xml b/Project.xml index 3055cf457..192a2dc7d 100644 --- a/Project.xml +++ b/Project.xml @@ -126,6 +126,8 @@ <haxelib name="faxe" if='switch'/> <haxelib name="polymod"/> <haxelib name="hxcpp-debug-server" if="desktop debug"/> + <haxelib name="discord_rpc" if="desktop"/> + <!-- <haxelib name="hxcpp-debug-server" if="desktop"/> --> <!-- <haxelib name="markdown" /> --> <!-- <haxelib name="HtmlParser" /> --> diff --git a/source/Boyfriend.hx b/source/Boyfriend.hx index c9f87f9bf..3421367cb 100644 --- a/source/Boyfriend.hx +++ b/source/Boyfriend.hx @@ -16,6 +16,8 @@ class Boyfriend extends Character super(x, y, char, true); } + public var startedDeath:Bool = false; + override function update(elapsed:Float) { if (!debugMode) @@ -32,7 +34,7 @@ class Boyfriend extends Character playAnim('idle', true, false, 10); } - if (animation.curAnim.name == 'firstDeath' && animation.curAnim.finished) + if (animation.curAnim.name == 'firstDeath' && animation.curAnim.finished && startedDeath) { playAnim('deathLoop'); } diff --git a/source/Character.hx b/source/Character.hx index 965b89ab6..ef8c3d96b 100644 --- a/source/Character.hx +++ b/source/Character.hx @@ -33,7 +33,7 @@ class Character extends FlxSprite { case 'gf': // GIRLFRIEND CODE - tex = Paths.getSparrowAtlas('GF_assets'); + tex = Paths.getSparrowAtlas('characters/GF_assets'); frames = tex; animation.addByPrefix('cheer', 'GF Cheer', 24, false); animation.addByPrefix('singLEFT', 'GF left note', 24, false); @@ -47,19 +47,7 @@ class Character extends FlxSprite animation.addByIndices('hairFall', "GF Dancing Beat Hair Landing", [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "", 24, false); animation.addByPrefix('scared', 'GF FEAR', 24); - addOffset('cheer'); - addOffset('sad', -2, -21); - addOffset('danceLeft', 0, -9); - addOffset('danceRight', 0, -9); - - addOffset("singUP", 0, 4); - addOffset("singRIGHT", 0, -20); - addOffset("singLEFT", 0, -19); - addOffset("singDOWN", 0, -20); - addOffset('hairBlow', 45, -8); - addOffset('hairFall', 0, -9); - - addOffset('scared', -2, -17); + loadOffsetFile(curCharacter); playAnim('danceRight'); @@ -94,6 +82,26 @@ class Character extends FlxSprite playAnim('danceRight'); + case 'bf-holding-gf': + frames = Paths.getSparrowAtlas('characters/bfAndGF'); + quickAnimAdd('idle', 'BF idle dance'); + quickAnimAdd('singDOWN', 'BF NOTE DOWN0'); + quickAnimAdd('singLEFT', 'BF NOTE LEFT0'); + quickAnimAdd('singRIGHT', 'BF NOTE RIGHT0'); + quickAnimAdd('singUP', 'BF NOTE UP0'); + + quickAnimAdd('singDOWNmiss', 'BF NOTE DOWN MISS'); + quickAnimAdd('singLEFTmiss', 'BF NOTE LEFT MISS'); + quickAnimAdd('singRIGHTmiss', 'BF NOTE RIGHT MISS'); + quickAnimAdd('singUPmiss', 'BF NOTE UP MISS'); + quickAnimAdd('bfCatch', 'BF catches GF'); + + loadOffsetFile(curCharacter); + + playAnim('idle'); + + flipX = true; + case 'gf-car': tex = Paths.getSparrowAtlas('gfCar'); frames = tex; @@ -280,7 +288,7 @@ class Character extends FlxSprite playAnim('shoot1'); case 'bf': - var tex = Paths.getSparrowAtlas('BOYFRIEND'); + var tex = Paths.getSparrowAtlas('characters/BOYFRIEND'); frames = tex; animation.addByPrefix('idle', 'BF idle dance', 24, false); animation.addByPrefix('singUP', 'BF NOTE UP0', 24, false); @@ -299,25 +307,14 @@ class Character extends FlxSprite animation.addByPrefix('scared', 'BF idle shaking', 24); - addOffset('idle', -5); - addOffset("singUP", -29, 27); - addOffset("singRIGHT", -38, -7); - addOffset("singLEFT", 12, -6); - addOffset("singDOWN", -10, -50); - addOffset("singUPmiss", -29, 27); - addOffset("singRIGHTmiss", -30, 21); - addOffset("singLEFTmiss", 12, 24); - addOffset("singDOWNmiss", -11, -19); - addOffset("hey", 7, 4); - addOffset('firstDeath', 37, 11); - addOffset('deathLoop', 37, 5); - addOffset('deathConfirm', 37, 69); - addOffset('scared', -4); + loadOffsetFile(curCharacter); playAnim('idle'); flipX = true; + loadOffsetFile(curCharacter); + case 'bf-christmas': var tex = Paths.getSparrowAtlas('christmas/bfChristmas'); frames = tex; @@ -413,8 +410,8 @@ class Character extends FlxSprite animation.play('firstDeath'); addOffset('firstDeath'); - addOffset('deathLoop', -37); - addOffset('deathConfirm', -37); + addOffset('deathLoop', -30, -12); + addOffset('deathConfirm', -30, -12); playAnim('firstDeath'); // pixel bullshit setGraphicSize(Std.int(width * 6)); diff --git a/source/ColorpickSubstate.hx b/source/ColorpickSubstate.hx new file mode 100644 index 000000000..6123acc9b --- /dev/null +++ b/source/ColorpickSubstate.hx @@ -0,0 +1,63 @@ +package; + +import flixel.FlxG; +import flixel.group.FlxGroup.FlxTypedGroup; +import shaderslmfao.ColorSwap; + +class ColorpickSubstate extends MusicBeatSubstate +{ + var curSelected:Int = 0; + + var grpNotes:FlxTypedGroup<Note>; + + public function new() + { + super(); + + grpNotes = new FlxTypedGroup<Note>(); + add(grpNotes); + + for (i in 0...4) + { + var note:Note = new Note(0, i); + + note.x = (100 * i) + i; + note.screenCenter(Y); + + grpNotes.add(note); + } + } + + override function update(elapsed:Float) + { + if (controls.BACK) + { + FlxG.state.closeSubState(); + FlxG.state.openSubState(new OptionsSubState()); + } + + if (controls.RIGHT_P) + curSelected += 1; + if (controls.LEFT_P) + curSelected -= 1; + + if (curSelected < 0) + curSelected = grpNotes.members.length - 1; + if (curSelected >= grpNotes.members.length) + curSelected = 0; + + if (controls.UP) + { + grpNotes.members[curSelected].colorSwap.update(elapsed * 0.3); + Note.arrowColors[curSelected] += elapsed * 0.3; + } + + if (controls.DOWN) + { + grpNotes.members[curSelected].colorSwap.update(-elapsed * 0.3); + Note.arrowColors[curSelected] += -elapsed * 0.3; + } + + super.update(elapsed); + } +} diff --git a/source/DialogueBox.hx b/source/DialogueBox.hx index 929eb242e..ade30a8e3 100644 --- a/source/DialogueBox.hx +++ b/source/DialogueBox.hx @@ -60,6 +60,24 @@ class DialogueBox extends FlxSpriteGroup bgFade.alpha = 0.7; }, 5); + portraitLeft = new FlxSprite(-20, 40); + portraitLeft.frames = Paths.getSparrowAtlas('weeb/senpaiPortrait'); + portraitLeft.animation.addByPrefix('enter', 'Senpai Portrait Enter', 24, false); + portraitLeft.setGraphicSize(Std.int(portraitLeft.width * PlayState.daPixelZoom * 0.9)); + portraitLeft.updateHitbox(); + portraitLeft.scrollFactor.set(); + add(portraitLeft); + portraitLeft.visible = false; + + portraitRight = new FlxSprite(0, 40); + portraitRight.frames = Paths.getSparrowAtlas('weeb/bfPortrait'); + portraitRight.animation.addByPrefix('enter', 'Boyfriend portrait enter', 24, false); + portraitRight.setGraphicSize(Std.int(portraitRight.width * PlayState.daPixelZoom * 0.9)); + portraitRight.updateHitbox(); + portraitRight.scrollFactor.set(); + add(portraitRight); + portraitRight.visible = false; + box = new FlxSprite(-20, 45); var hasDialog = false; @@ -94,24 +112,6 @@ class DialogueBox extends FlxSpriteGroup if (!hasDialog) return; - portraitLeft = new FlxSprite(-20, 40); - portraitLeft.frames = Paths.getSparrowAtlas('weeb/senpaiPortrait'); - portraitLeft.animation.addByPrefix('enter', 'Senpai Portrait Enter', 24, false); - portraitLeft.setGraphicSize(Std.int(portraitLeft.width * PlayState.daPixelZoom * 0.9)); - portraitLeft.updateHitbox(); - portraitLeft.scrollFactor.set(); - add(portraitLeft); - portraitLeft.visible = false; - - portraitRight = new FlxSprite(0, 40); - portraitRight.frames = Paths.getSparrowAtlas('weeb/bfPortrait'); - portraitRight.animation.addByPrefix('enter', 'Boyfriend portrait enter', 24, false); - portraitRight.setGraphicSize(Std.int(portraitRight.width * PlayState.daPixelZoom * 0.9)); - portraitRight.updateHitbox(); - portraitRight.scrollFactor.set(); - add(portraitRight); - portraitRight.visible = false; - box.animation.play('normalOpen'); box.setGraphicSize(Std.int(box.width * PlayState.daPixelZoom * 0.9)); box.updateHitbox(); @@ -120,7 +120,10 @@ class DialogueBox extends FlxSpriteGroup box.screenCenter(X); portraitLeft.screenCenter(X); - handSelect = new FlxSprite(FlxG.width * 0.9, FlxG.height * 0.9).loadGraphic(Paths.image('weeb/pixelUI/hand_textbox')); + handSelect = new FlxSprite(1042, 590).loadGraphic(Paths.image('weeb/pixelUI/hand_textbox')); + handSelect.setGraphicSize(Std.int(handSelect.width * PlayState.daPixelZoom * 0.9)); + handSelect.updateHitbox(); + handSelect.visible = false; add(handSelect); @@ -199,6 +202,7 @@ class DialogueBox extends FlxSpriteGroup portraitLeft.visible = false; portraitRight.visible = false; swagDialogue.alpha -= 1 / 5; + handSelect.alpha -= 1 / 5; dropText.alpha = swagDialogue.alpha; }, 5); @@ -230,7 +234,13 @@ class DialogueBox extends FlxSpriteGroup // swagDialogue.text = ; swagDialogue.resetText(dialogueList[0]); - swagDialogue.start(0.04, true); + swagDialogue.start(0.04); + swagDialogue.completeCallback = function() + { + trace("dialogue finish"); + handSelect.visible = true; + }; + handSelect.visible = false; switch (curCharacter) { diff --git a/source/Discord.hx b/source/Discord.hx new file mode 100644 index 000000000..253a4f59a --- /dev/null +++ b/source/Discord.hx @@ -0,0 +1,82 @@ +package; + +import Sys.sleep; +import discord_rpc.DiscordRpc; + +using StringTools; + +class DiscordClient +{ + public function new() + { + trace("Discord Client starting..."); + DiscordRpc.start({ + clientID: "814588678700924999", + onReady: onReady, + onError: onError, + onDisconnected: onDisconnected + }); + trace("Discord Client started."); + + while (true) + { + DiscordRpc.process(); + sleep(2); + //trace("Discord Client Update"); + } + + DiscordRpc.shutdown(); + } + + static function onReady() + { + DiscordRpc.presence({ + details: "In the Menus", + state: null, + largeImageKey: 'icon', + largeImageText: "Friday Night Funkin'" + }); + } + + static function onError(_code:Int, _message:String) + { + trace('Error! $_code : $_message'); + } + + static function onDisconnected(_code:Int, _message:String) + { + trace('Disconnected! $_code : $_message'); + } + + public static function initialize() + { + var DiscordDaemon = sys.thread.Thread.create(() -> + { + new DiscordClient(); + }); + trace("Discord Client initialized"); + } + + public static function changePresence(details:String, state:Null<String>, ?smallImageKey : String, ?hasStartTimestamp : Bool, ?endTimestamp: Float) + { + var startTimestamp:Float = if(hasStartTimestamp) Date.now().getTime() else 0; + + if (endTimestamp > 0) + { + endTimestamp = startTimestamp + endTimestamp; + } + + DiscordRpc.presence({ + details: details, + state: state, + largeImageKey: 'icon', + largeImageText: "Friday Night Funkin'", + smallImageKey : smallImageKey, + // Obtained times are in milliseconds so they are divided so Discord can use it + startTimestamp : Std.int(startTimestamp / 1000), + endTimestamp : Std.int(endTimestamp / 1000) + }); + + //trace('Discord RPC Updated. Arguments: $details, $state, $smallImageKey, $hasStartTimestamp, $endTimestamp'); + } +} diff --git a/source/FreeplayState.hx b/source/FreeplayState.hx index bf0cc3dac..4c3e492e3 100644 --- a/source/FreeplayState.hx +++ b/source/FreeplayState.hx @@ -1,5 +1,8 @@ package; +#if desktop +import Discord.DiscordClient; +#end import flash.text.TextField; import flixel.FlxG; import flixel.FlxSprite; @@ -49,6 +52,11 @@ class FreeplayState extends MusicBeatState FlxG.sound.playMusic(Paths.music('freakyMenu')); } + #if desktop + // Updating Discord Rich Presence + DiscordClient.changePresence("In the Menus", null); + #end + var isDebug:Bool = false; #if debug @@ -59,7 +67,7 @@ class FreeplayState extends MusicBeatState addWeek(['Bopeebo', 'Fresh', 'Dadbattle'], 1, ['dad']); if (StoryMenuState.weekUnlocked[2] || isDebug) - addWeek(['Spookeez', 'South', 'Monster'], 2, ['spooky']); + addWeek(['Spookeez', 'South', 'Monster'], 2, ['spooky', 'spooky', 'monster']); if (StoryMenuState.weekUnlocked[3] || isDebug) addWeek(['Pico', 'Philly', 'Blammed'], 3, ['pico']); diff --git a/source/GameOverSubstate.hx b/source/GameOverSubstate.hx index 1d672dbf4..79e86c748 100644 --- a/source/GameOverSubstate.hx +++ b/source/GameOverSubstate.hx @@ -13,6 +13,7 @@ class GameOverSubstate extends MusicBeatSubstate var camFollow:FlxObject; var stageSuffix:String = ""; + var randomGameover:Int = 1; public function new(x:Float, y:Float) { @@ -49,8 +50,12 @@ class GameOverSubstate extends MusicBeatSubstate FlxG.camera.target = null; bf.playAnim('firstDeath'); + + randomGameover = FlxG.random.int(1, 25); } + var playingDeathSound:Bool = false; + override function update(elapsed:Float) { super.update(elapsed); @@ -75,9 +80,24 @@ class GameOverSubstate extends MusicBeatSubstate FlxG.camera.follow(camFollow, LOCKON, 0.01); } - if (bf.animation.curAnim.name == 'firstDeath' && bf.animation.curAnim.finished) + switch (PlayState.storyWeek) { - FlxG.sound.playMusic(Paths.music('gameOver' + stageSuffix)); + case 7: + if (bf.animation.curAnim.name == 'firstDeath' && bf.animation.curAnim.finished && !playingDeathSound) + { + playingDeathSound = true; + FlxG.sound.play(Paths.sound('jeffGameover/jeffGameover-' + randomGameover), 1, false, null, true, function() + { + bf.startedDeath = true; + coolStartDeath(); + }); + } + default: + if (bf.animation.curAnim.name == 'firstDeath' && bf.animation.curAnim.finished) + { + bf.startedDeath = true; + coolStartDeath(); + } } if (FlxG.sound.music.playing) @@ -86,6 +106,11 @@ class GameOverSubstate extends MusicBeatSubstate } } + private function coolStartDeath():Void + { + FlxG.sound.playMusic(Paths.music('gameOver' + stageSuffix)); + } + override function beatHit() { super.beatHit(); diff --git a/source/HealthIcon.hx b/source/HealthIcon.hx index c821a84b3..46adbcec3 100644 --- a/source/HealthIcon.hx +++ b/source/HealthIcon.hx @@ -2,6 +2,8 @@ package; import flixel.FlxSprite; +using StringTools; + class HealthIcon extends FlxSprite { /** @@ -9,36 +11,53 @@ class HealthIcon extends FlxSprite */ public var sprTracker:FlxSprite; + var char:String = 'bf'; + var isPlayer:Bool = false; + public function new(char:String = 'bf', isPlayer:Bool = false) { super(); - loadGraphic(Paths.image('iconGrid'), true, 150, 150); + this.isPlayer = isPlayer; + this.char = char; + + loadIcon(char); antialiasing = true; - animation.add('bf', [0, 1], 0, false, isPlayer); - animation.add('bf-car', [0, 1], 0, false, isPlayer); - animation.add('bf-christmas', [0, 1], 0, false, isPlayer); - animation.add('bf-pixel', [21, 21], 0, false, isPlayer); - animation.add('spooky', [2, 3], 0, false, isPlayer); - animation.add('pico', [4, 5], 0, false, isPlayer); - animation.add('pico-speaker', [4, 5], 0, false, isPlayer); - animation.add('mom', [6, 7], 0, false, isPlayer); - animation.add('mom-car', [6, 7], 0, false, isPlayer); - animation.add('tankman', [8, 9], 0, false, isPlayer); - animation.add('face', [10, 11], 0, false, isPlayer); - animation.add('dad', [12, 13], 0, false, isPlayer); - animation.add('senpai', [22, 22], 0, false, isPlayer); - animation.add('senpai-angry', [22, 22], 0, false, isPlayer); - animation.add('spirit', [23, 23], 0, false, isPlayer); - animation.add('bf-old', [14, 15], 0, false, isPlayer); - animation.add('gf', [16], 0, false, isPlayer); - animation.add('parents-christmas', [17], 0, false, isPlayer); - animation.add('monster', [19, 20], 0, false, isPlayer); - animation.add('monster-christmas', [19, 20], 0, false, isPlayer); - animation.play(char); scrollFactor.set(); } + public var isOldIcon:Bool = false; + + public function swapOldIcon():Void + { + isOldIcon = !isOldIcon; + + if (isOldIcon) + { + loadGraphic(Paths.image('icons/icon-bf-old'), true, 150, 150); + animation.add('bf-old', [0, 1], 0, false, isPlayer); + animation.play('bf-old'); + } + else + loadIcon(char); + } + + function loadIcon(char:String):Void + { + var realChar:String = ""; + switch (char) + { + case 'bf-pixel': + realChar = char; + default: + realChar = char.split('-')[0].trim(); + } + + loadGraphic(Paths.image('icons/icon-' + realChar), true, 150, 150); + animation.add(realChar, [0, 1], 0, false, isPlayer); + animation.play(realChar); + } + override function update(elapsed:Float) { super.update(elapsed); diff --git a/source/MainMenuState.hx b/source/MainMenuState.hx index 6c04e758d..58494cc47 100644 --- a/source/MainMenuState.hx +++ b/source/MainMenuState.hx @@ -1,6 +1,7 @@ package; import NGio; + import flixel.ui.FlxButton; import flixel.FlxG; import flixel.FlxObject; @@ -17,6 +18,10 @@ import flixel.util.FlxColor; import flixel.util.FlxTimer; import lime.app.Application; +#if desktop +import Discord.DiscordClient; +#end + #if newgrounds import io.newgrounds.NG; import ui.NgPrompt; @@ -38,6 +43,11 @@ class MainMenuState extends MusicBeatState override function create() { + #if desktop + // Updating Discord Rich Presence + DiscordClient.changePresence("In the Menus", null); + #end + transIn = FlxTransitionableState.defaultTransIn; transOut = FlxTransitionableState.defaultTransOut; diff --git a/source/ModdingSubstate.hx b/source/ModdingSubstate.hx index 57264a3b4..8dfc46016 100644 --- a/source/ModdingSubstate.hx +++ b/source/ModdingSubstate.hx @@ -91,10 +91,10 @@ class ModdingSubstate extends MusicBeatSubstate grpMods.remove(grpMods.members[0], true); } + #if desktop var modList = []; modFolders = []; - #if desktop for (file in FileSystem.readDirectory('./mods')) { if (FileSystem.isDirectory('./mods/' + file)) diff --git a/source/MusicBeatState.hx b/source/MusicBeatState.hx index 88c58a624..28660b160 100644 --- a/source/MusicBeatState.hx +++ b/source/MusicBeatState.hx @@ -9,9 +9,6 @@ import flixel.util.FlxTimer; class MusicBeatState extends FlxUIState { - private var lastBeat:Float = 0; - private var lastStep:Float = 0; - private var curStep:Int = 0; private var curBeat:Int = 0; private var controls(get, never):Controls; @@ -35,7 +32,7 @@ class MusicBeatState extends FlxUIState updateCurStep(); updateBeat(); - if (oldStep != curStep && curStep > 0) + if (oldStep != curStep && curStep >= 0) stepHit(); super.update(elapsed); diff --git a/source/MusicBeatSubstate.hx b/source/MusicBeatSubstate.hx index c6da0fb59..89c4458b2 100644 --- a/source/MusicBeatSubstate.hx +++ b/source/MusicBeatSubstate.hx @@ -11,9 +11,6 @@ class MusicBeatSubstate extends FlxSubState super(); } - private var lastBeat:Float = 0; - private var lastStep:Float = 0; - private var curStep:Int = 0; private var curBeat:Int = 0; private var controls(get, never):Controls; @@ -29,7 +26,7 @@ class MusicBeatSubstate extends FlxSubState updateCurStep(); curBeat = Math.floor(curStep / 4); - if (oldStep != curStep && curStep > 0) + if (oldStep != curStep && curStep >= 0) stepHit(); diff --git a/source/Note.hx b/source/Note.hx index 114a7ffbf..786a23e53 100644 --- a/source/Note.hx +++ b/source/Note.hx @@ -1,15 +1,19 @@ package; +import flixel.FlxG; import flixel.FlxSprite; import flixel.graphics.frames.FlxAtlasFrames; import flixel.math.FlxMath; import flixel.util.FlxColor; +import flixel.util.FlxTimer; +import shaderslmfao.ColorSwap; + +using StringTools; + #if polymod import polymod.format.ParseRules.TargetSignatureElement; #end -using StringTools; - class Note extends FlxSprite { public var strumTime:Float = 0; @@ -24,6 +28,7 @@ class Note extends FlxSprite public var sustainLength:Float = 0; public var isSustainNote:Bool = false; + public var colorSwap:ColorSwap; public var noteScore:Float = 1; public static var swagWidth:Float = 160 * 0.7; @@ -32,6 +37,8 @@ class Note extends FlxSprite public static var BLUE_NOTE:Int = 1; public static var RED_NOTE:Int = 3; + public static var arrowColors:Array<Float> = [1, 1, 1, 1]; + public function new(strumTime:Float, noteData:Int, ?prevNote:Note, ?sustainNote:Bool = false) { super(); @@ -82,10 +89,10 @@ class Note extends FlxSprite default: frames = Paths.getSparrowAtlas('NOTE_assets'); - animation.addByPrefix('greenScroll', 'green0'); - animation.addByPrefix('redScroll', 'red0'); - animation.addByPrefix('blueScroll', 'blue0'); - animation.addByPrefix('purpleScroll', 'purple0'); + animation.addByPrefix('greenScroll', 'green instance'); + animation.addByPrefix('redScroll', 'red instance'); + animation.addByPrefix('blueScroll', 'blue instance'); + animation.addByPrefix('purpleScroll', 'purple instance'); animation.addByPrefix('purpleholdend', 'pruple end hold'); animation.addByPrefix('greenholdend', 'green hold end'); @@ -100,13 +107,25 @@ class Note extends FlxSprite setGraphicSize(Std.int(width * 0.7)); updateHitbox(); antialiasing = true; + + // colorSwap.colorToReplace = 0xFFF9393F; + // colorSwap.newColor = 0xFF00FF00; + + // color = FlxG.random.color(); + // color.saturation *= 4; + // replaceColor(0xFFC1C1C1, FlxColor.RED); } + colorSwap = new ColorSwap(); + shader = colorSwap.shader; + updateColors(); + switch (noteData) { case 0: x += swagWidth * 0; animation.play('purpleScroll'); + case 1: x += swagWidth * 1; animation.play('blueScroll'); @@ -167,6 +186,11 @@ class Note extends FlxSprite } } + public function updateColors():Void + { + colorSwap.update(arrowColors[noteData]); + } + override function update(elapsed:Float) { super.update(elapsed); diff --git a/source/OptionsSubState.hx b/source/OptionsSubState.hx index 00ca548f1..ee27bdfc1 100644 --- a/source/OptionsSubState.hx +++ b/source/OptionsSubState.hx @@ -8,7 +8,7 @@ import flixel.util.FlxColor; class OptionsSubState extends MusicBeatSubstate { - var textMenuItems:Array<String> = ['Master Volume', 'Sound Volume', 'Controls']; + var textMenuItems:Array<String> = ['Master Volume', 'Sound Volume', 'Controls', 'Colors', 'Back']; var selector:FlxSprite; var curSelected:Int = 0; @@ -63,16 +63,24 @@ class OptionsSubState extends MusicBeatSubstate txt.color = FlxColor.YELLOW; }); + if (controls.BACK) + FlxG.switchState(new MainMenuState()); + if (controls.ACCEPT) { switch (textMenuItems[curSelected]) { + case "Colors": + FlxG.state.closeSubState(); + FlxG.state.openSubState(new ColorpickSubstate()); case "Controls": FlxG.state.closeSubState(); FlxG.state.openSubState(new ControlsSubState()); case "Mods": FlxG.state.closeSubState(); FlxG.state.openSubState(new ModdingSubstate()); + case "Back": + FlxG.switchState(new MainMenuState()); } } } diff --git a/source/PlayState.hx b/source/PlayState.hx index 44b56a0c4..610d50987 100644 --- a/source/PlayState.hx +++ b/source/PlayState.hx @@ -38,9 +38,14 @@ import lime.utils.Assets; import openfl.display.BlendMode; import openfl.display.StageQuality; import openfl.filters.ShaderFilter; +import shaderslmfao.ColorSwap; using StringTools; +#if desktop +import Discord.DiscordClient; +#end + class PlayState extends MusicBeatState { public static var curStage:String = ''; @@ -113,6 +118,8 @@ class PlayState extends MusicBeatState var bgGirls:BackgroundGirls; var wiggleShit:WiggleEffect = new WiggleEffect(); + var tankmanRun:FlxTypedGroup<TankmenBG>; + var talking:Bool = true; var songScore:Int = 0; var scoreTxt:FlxText; @@ -126,6 +133,15 @@ class PlayState extends MusicBeatState var inCutscene:Bool = false; + #if desktop + // Discord RPC variables + var storyDifficultyText:String = ""; + var iconRPC:String = ""; + var songLength:Float = 0; + var detailsText:String = ""; + var detailsPausedText:String = ""; + #end + override public function create() { if (FlxG.sound.music != null) @@ -179,6 +195,8 @@ class PlayState extends MusicBeatState dialogue = CoolUtil.coolTextFile(Paths.txt('thorns/thornsDialogue')); } + initDiscord(); + switch (SONG.song.toLowerCase()) { case 'spookeez' | 'monster' | 'south': @@ -499,6 +517,9 @@ class PlayState extends MusicBeatState var tankGround:BGSprite = new BGSprite('tankGround', -200, -20); add(tankGround); + tankmanRun = new FlxTypedGroup<TankmenBG>(); + add(tankmanRun); + var fgTank0:BGSprite = new BGSprite('tank0', -290, 400, 1.7, 1.5, ['fg']); foregroundSprites.add(fgTank0); @@ -619,6 +640,12 @@ class PlayState extends MusicBeatState boyfriend = new Boyfriend(770, 450, SONG.player1); + switch (SONG.player1) + { + case "bf-holding-gf": + boyfriend.y -= 140; + } + // REPOSITIONING PER STAGE switch (curStage) { @@ -805,6 +832,32 @@ class PlayState extends MusicBeatState super.create(); } + function initDiscord():Void + { + #if desktop + storyDifficultyText = CoolUtil.difficultyString(); + iconRPC = SONG.player2; + + // To avoid having duplicate images in Discord assets + switch (iconRPC) + { + case 'senpai-angry': + iconRPC = 'senpai'; + case 'monster-christmas': + iconRPC = 'monster'; + case 'mom-car': + iconRPC = 'mom'; + } + + // String that contains the mode defined here so it isn't necessary to call changePresence for each mode + detailsText = isStoryMode ? "Story Mode: Week " + storyWeek : "Freeplay"; + detailsPausedText = "Paused - " + detailsText; + + // Updating Discord Rich Presence. + DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconRPC); + #end + } + function schoolIntro(?dialogueBox:DialogueBox):Void { var black:FlxSprite = new FlxSprite(-100, -100).makeGraphic(FlxG.width * 2, FlxG.height * 2, FlxColor.BLACK); @@ -908,9 +961,18 @@ class PlayState extends MusicBeatState startTimer = new FlxTimer().start(Conductor.crochet / 1000, function(tmr:FlxTimer) { - dad.dance(); - gf.dance(); - boyfriend.playAnim('idle'); + // this just based on beatHit stuff but compact + if (swagCounter % gfSpeed == 0) + gf.dance(); + if (swagCounter % 2 == 0) + { + if (!boyfriend.animation.curAnim.name.startsWith("sing")) + boyfriend.playAnim('idle'); + if (!dad.animation.curAnim.name.startsWith("sing")) + dad.dance(); + } + else if (dad.curCharacter == 'spooky' && !dad.animation.curAnim.name.startsWith("sing")) + dad.dance(); var introAssets:Map<String, Array<String>> = new Map<String, Array<String>>(); introAssets.set('default', ['ready', "set", "go"]); @@ -1011,6 +1073,14 @@ class PlayState extends MusicBeatState FlxG.sound.playMusic(Paths.inst(PlayState.SONG.song), 1, false); FlxG.sound.music.onComplete = endSong; vocals.play(); + + #if desktop + // Song duration in a float, useful for the time left feature + songLength = FlxG.sound.music.length; + + // Updating Discord Rich Presence (with Time Left) + DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconRPC, true, songLength); + #end } var debugNum:Int = 0; @@ -1121,6 +1191,9 @@ class PlayState extends MusicBeatState { // FlxG.log.add(i); var babyArrow:FlxSprite = new FlxSprite(0, strumLine.y); + var colorswap:ColorSwap = new ColorSwap(); + babyArrow.shader = colorswap.shader; + colorswap.update(Note.arrowColors[i]); switch (curStage) { @@ -1173,22 +1246,22 @@ class PlayState extends MusicBeatState { case 0: babyArrow.x += Note.swagWidth * 0; - babyArrow.animation.addByPrefix('static', 'arrowLEFT'); + babyArrow.animation.addByPrefix('static', 'arrow static instance 1'); babyArrow.animation.addByPrefix('pressed', 'left press', 24, false); babyArrow.animation.addByPrefix('confirm', 'left confirm', 24, false); case 1: babyArrow.x += Note.swagWidth * 1; - babyArrow.animation.addByPrefix('static', 'arrowDOWN'); + babyArrow.animation.addByPrefix('static', 'arrow static instance 2'); babyArrow.animation.addByPrefix('pressed', 'down press', 24, false); babyArrow.animation.addByPrefix('confirm', 'down confirm', 24, false); case 2: babyArrow.x += Note.swagWidth * 2; - babyArrow.animation.addByPrefix('static', 'arrowUP'); + babyArrow.animation.addByPrefix('static', 'arrow static instance 4'); babyArrow.animation.addByPrefix('pressed', 'up press', 24, false); babyArrow.animation.addByPrefix('confirm', 'up confirm', 24, false); case 3: babyArrow.x += Note.swagWidth * 3; - babyArrow.animation.addByPrefix('static', 'arrowRIGHT'); + babyArrow.animation.addByPrefix('static', 'arrow static instance 3'); babyArrow.animation.addByPrefix('pressed', 'right press', 24, false); babyArrow.animation.addByPrefix('confirm', 'right confirm', 24, false); } @@ -1253,11 +1326,53 @@ class PlayState extends MusicBeatState if (!startTimer.finished) startTimer.active = true; paused = false; + + #if desktop + if (startTimer.finished) + { + DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconRPC, true, songLength - Conductor.songPosition); + } + else + { + DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconRPC); + } + #end } super.closeSubState(); } + override public function onFocus():Void + { + #if desktop + if (health > 0 && !paused) + { + if (Conductor.songPosition > 0.0) + { + DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconRPC, true, songLength - Conductor.songPosition); + } + else + { + DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconRPC); + } + } + #end + + super.onFocus(); + } + + override public function onFocusLost():Void + { + #if desktop + if (health > 0 && !paused) + { + DiscordClient.changePresence(detailsPausedText, SONG.song + " (" + storyDifficultyText + ")", iconRPC); + } + #end + + super.onFocusLost(); + } + function resyncVocals():Void { vocals.pause(); @@ -1279,11 +1394,39 @@ class PlayState extends MusicBeatState #end if (FlxG.keys.justPressed.NINE) + iconP1.swapOldIcon(); + + // do this BEFORE super.update() so songPosition is accurate + if (startingSong) { - if (iconP1.animation.curAnim.name == 'bf-old') - iconP1.animation.play(SONG.player1); - else - iconP1.animation.play('bf-old'); + if (startedCountdown) + { + Conductor.songPosition += FlxG.elapsed * 1000; + if (Conductor.songPosition >= 0) + startSong(); + } + } + else + { + // Conductor.songPosition = FlxG.sound.music.time; + Conductor.songPosition += FlxG.elapsed * 1000; + + if (!paused) + { + songTime += FlxG.game.ticks - previousFrameTime; + previousFrameTime = FlxG.game.ticks; + + // Interpolation type beat + if (Conductor.lastSongPos != Conductor.songPosition) + { + songTime = (songTime + Conductor.songPosition) / 2; + Conductor.lastSongPos = Conductor.songPosition; + // Conductor.songPosition += FlxG.elapsed * 1000; + // trace('MISSED FRAME'); + } + } + + // Conductor.lastSongPos = FlxG.sound.music.time; } switch (curStage) @@ -1306,7 +1449,7 @@ class PlayState extends MusicBeatState scoreTxt.text = "Score:" + songScore; - if (FlxG.keys.justPressed.ENTER && startedCountdown && canPause) + if (controls.PAUSE && startedCountdown && canPause) { persistentUpdate = false; persistentDraw = true; @@ -1326,11 +1469,19 @@ class PlayState extends MusicBeatState pauseSubState.camera = camHUD; boyfriendPos.put(); } + + #if desktop + DiscordClient.changePresence(detailsPausedText, SONG.song + " (" + storyDifficultyText + ")", iconRPC); + #end } if (FlxG.keys.justPressed.SEVEN) { FlxG.switchState(new ChartingState()); + + #if desktop + DiscordClient.changePresence("Chart Editor", null, null, true); + #end } // FlxG.watch.addQuick('VOL', vocals.amplitudeLeft); @@ -1368,38 +1519,6 @@ class PlayState extends MusicBeatState FlxG.switchState(new AnimationDebug(SONG.player2)); #end - if (startingSong) - { - if (startedCountdown) - { - Conductor.songPosition += FlxG.elapsed * 1000; - if (Conductor.songPosition >= 0) - startSong(); - } - } - else - { - // Conductor.songPosition = FlxG.sound.music.time; - Conductor.songPosition += FlxG.elapsed * 1000; - - if (!paused) - { - songTime += FlxG.game.ticks - previousFrameTime; - previousFrameTime = FlxG.game.ticks; - - // Interpolation type beat - if (Conductor.lastSongPos != Conductor.songPosition) - { - songTime = (songTime + Conductor.songPosition) / 2; - Conductor.lastSongPos = Conductor.songPosition; - // Conductor.songPosition += FlxG.elapsed * 1000; - // trace('MISSED FRAME'); - } - } - - // Conductor.lastSongPos = FlxG.sound.music.time; - } - if (generatedMusic && PlayState.SONG.notes[Std.int(curStep / 16)] != null) { if (curBeat % 4 == 0) @@ -1529,6 +1648,11 @@ class PlayState extends MusicBeatState openSubState(new GameOverSubstate(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y)); // FlxG.switchState(new GameOverState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y)); + + #if desktop + // Game Over doesn't get his own variable because it's only used here + DiscordClient.changePresence("Game Over - " + detailsText, SONG.song + " (" + storyDifficultyText + ")", iconRPC); + #end } if (unspawnNotes[0] != null) @@ -1893,8 +2017,11 @@ class PlayState extends MusicBeatState var controlArray:Array<Bool> = [leftP, downP, upP, rightP]; // FlxG.watch.addQuick('asdfa', upP); - if ((upP || rightP || downP || leftP) && !boyfriend.stunned && generatedMusic) + if ((upP || rightP || downP || leftP) && generatedMusic) { + // note to self, used to have stunned + // && !boyfriend.stunned + boyfriend.holdTimer = 0; var possibleNotes:Array<Note> = []; @@ -2213,8 +2340,7 @@ class PlayState extends MusicBeatState function trainStart():Void { trainMoving = true; - if (!trainSound.playing) - trainSound.play(true); + trainSound.play(true); } var startedMoving:Bool = false; @@ -2304,10 +2430,6 @@ class PlayState extends MusicBeatState } // else // Conductor.changeBPM(SONG.bpm); - - // Dad doesnt interupt his own notes - if (SONG.notes[Math.floor(curStep / 16)].mustHitSection) - dad.dance(); } // FlxG.log.add('change bpm' + SONG.notes[Std.int(curStep / 16)].changeBPM); wiggleShit.update(Conductor.crochet); @@ -2336,9 +2458,17 @@ class PlayState extends MusicBeatState gf.dance(); } - if (!boyfriend.animation.curAnim.name.startsWith("sing")) + if (curBeat % 2 == 0) { - boyfriend.playAnim('idle'); + if (!boyfriend.animation.curAnim.name.startsWith("sing")) + boyfriend.playAnim('idle'); + if (!dad.animation.curAnim.name.startsWith("sing")) + dad.dance(); + } + else if (dad.curCharacter == 'spooky') + { + if (!dad.animation.curAnim.name.startsWith("sing")) + dad.dance(); } if (curBeat % 8 == 7 && curSong == 'Bopeebo') @@ -2398,6 +2528,17 @@ class PlayState extends MusicBeatState } } + switch (curSong.toLowerCase()) + { + case 'stress': + if (FlxG.random.bool()) + { + var tank:TankmenBG = new TankmenBG(500, 200); + tank.strumTime = Conductor.songPosition + (Conductor.crochet * 4); + tankmanRun.add(tank); + } + } + if (isHalloween && FlxG.random.bool(10) && curBeat > lightningStrikeBeat + lightningOffset) { lightningStrikeShit(); diff --git a/source/StoryMenuState.hx b/source/StoryMenuState.hx index 90e854564..3c9d629ec 100644 --- a/source/StoryMenuState.hx +++ b/source/StoryMenuState.hx @@ -1,5 +1,8 @@ package; +#if desktop +import Discord.DiscordClient; +#end import flixel.FlxG; import flixel.FlxSprite; import flixel.addons.transition.FlxTransitionableState; @@ -109,6 +112,11 @@ class StoryMenuState extends MusicBeatState add(grpLocks); trace("Line 70"); + + #if desktop + // Updating Discord Rich Presence + DiscordClient.changePresence("In the Menus", null); + #end for (i in 0...weekData.length) { diff --git a/source/TankmenBG.hx b/source/TankmenBG.hx new file mode 100644 index 000000000..bdd56e8a3 --- /dev/null +++ b/source/TankmenBG.hx @@ -0,0 +1,76 @@ +package; + +import flixel.FlxG; +import flixel.FlxSprite; +import haxe.display.Display.Package; + +class TankmenBG extends FlxSprite +{ + public var strumTime:Float = 0; + public var goingRight:Bool = false; + public var tankSpeed:Float = 0.7; + + public var endingOffset:Float; + + public function new(x:Float, y:Float) + { + super(x, y); + + // makeGraphic(200, 200); + + frames = Paths.getSparrowAtlas('tankmanKilled1'); + antialiasing = true; + animation.addByPrefix('run', 'tankman running', 24, true); + animation.addByPrefix('shot', 'John', 24, false); + + animation.play('run'); + + y += FlxG.random.int(-40, 100); + + goingRight = FlxG.random.bool(); + endingOffset = FlxG.random.float(0, 120); + + tankSpeed = FlxG.random.float(0.65, 0.8); + + if (goingRight) + flipX = true; + } + + override function update(elapsed:Float) + { + super.update(elapsed); + + if (animation.curAnim.name == 'run') + { + var endDirection:Float = (FlxG.width * 0.74) + endingOffset; + + if (goingRight) + { + endDirection = (FlxG.width * 0.02) - endingOffset; + + x = (endDirection + (Conductor.songPosition - strumTime) * tankSpeed); + } + else + { + x = (endDirection - (Conductor.songPosition - strumTime) * tankSpeed); + } + } + + if (Conductor.songPosition > strumTime) + { + // kill(); + animation.play('shot'); + + if (goingRight) + { + offset.y = 200; + offset.x = 300; + } + } + + if (animation.curAnim.name == 'shot' && animation.curAnim.curFrame >= animation.curAnim.frames.length - 1) + { + kill(); + } + } +} diff --git a/source/TitleState.hx b/source/TitleState.hx index eff43f823..98c681e7d 100644 --- a/source/TitleState.hx +++ b/source/TitleState.hx @@ -16,9 +16,15 @@ import flixel.util.FlxColor; import flixel.util.FlxTimer; import lime.app.Application; import openfl.Assets; +import shaderslmfao.ColorSwap; using StringTools; +#if desktop +import Discord.DiscordClient; +import sys.thread.Thread; +#end + class TitleState extends MusicBeatState { static var initialized:Bool = false; @@ -33,12 +39,18 @@ class TitleState extends MusicBeatState var wackyImage:FlxSprite; + var lastBeat:Int = 0; + + var swagShader:ColorSwap; + override public function create():Void { #if polymod polymod.Polymod.init({modRoot: "mods", dirs: ['introMod'], framework: OPENFL}); #end + swagShader = new ColorSwap(); + FlxG.sound.muteKeys = [ZERO]; curWacky = FlxG.random.getObject(getIntroTextShit()); @@ -79,6 +91,10 @@ class TitleState extends MusicBeatState startIntro(); }); #end + + #if desktop + DiscordClient.initialize(); + #end } var logoBl:FlxSprite; @@ -122,6 +138,7 @@ class TitleState extends MusicBeatState // bg.antialiasing = true; // bg.setGraphicSize(Std.int(bg.width * 0.6)); // bg.updateHitbox(); + add(bg); logoBl = new FlxSprite(-150, -100); @@ -130,6 +147,10 @@ class TitleState extends MusicBeatState logoBl.animation.addByPrefix('bump', 'logo bumpin', 24); logoBl.animation.play('bump'); logoBl.updateHitbox(); + + logoBl.shader = swagShader.shader; + + // trace(); // logoBl.screenCenter(); // logoBl.color = FlxColor.BLACK; @@ -139,6 +160,9 @@ class TitleState extends MusicBeatState gfDance.animation.addByIndices('danceRight', 'gfDance', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false); gfDance.antialiasing = true; add(gfDance); + + gfDance.shader = swagShader.shader; + add(logoBl); titleText = new FlxSprite(100, FlxG.height * 0.8); @@ -300,11 +324,21 @@ class TitleState extends MusicBeatState // FlxG.sound.play(Paths.music('titleShoot'), 0.7); } - if (pressedEnter && !skippedIntro) + if (pressedEnter && !skippedIntro && initialized) { skipIntro(); } + if (controls.UI_LEFT) + { + swagShader.update(-elapsed * 0.1); + } + + if (controls.UI_RIGHT) + { + swagShader.update(elapsed * 0.1); + } + super.update(elapsed); } @@ -338,11 +372,14 @@ class TitleState extends MusicBeatState } } + var isRainbow:Bool = false; + override function beatHit() { super.beatHit(); - logoBl.animation.play('bump'); + logoBl.animation.play('bump', true); + danceLeft = !danceLeft; if (danceLeft) @@ -351,57 +388,65 @@ class TitleState extends MusicBeatState gfDance.animation.play('danceLeft'); FlxG.log.add(curBeat); - - switch (curBeat) + // if the user is draggin the window some beats will + // be missed so this is just to compensate + if (curBeat > lastBeat) { - case 1: - createCoolText(['ninjamuffin99', 'phantomArcade', 'kawaisprite', 'evilsk8er']); - // credTextShit.visible = true; - case 3: - addMoreText('present'); - // credTextShit.text += '\npresent...'; - // credTextShit.addText(); - case 4: - deleteCoolText(); - // credTextShit.visible = false; - // credTextShit.text = 'In association \nwith'; - // credTextShit.screenCenter(); - case 5: - createCoolText(['In association', 'with']); - case 7: - addMoreText('newgrounds'); - ngSpr.visible = true; - // credTextShit.text += '\nNewgrounds'; - case 8: - deleteCoolText(); - ngSpr.visible = false; - // credTextShit.visible = false; + for (i in lastBeat...curBeat) + { + switch (i + 1) + { + case 1: + createCoolText(['ninjamuffin99', 'phantomArcade', 'kawaisprite', 'evilsk8er']); + // credTextShit.visible = true; + case 3: + addMoreText('present'); + // credTextShit.text += '\npresent...'; + // credTextShit.addText(); + case 4: + deleteCoolText(); + // credTextShit.visible = false; + // credTextShit.text = 'In association \nwith'; + // credTextShit.screenCenter(); + case 5: + createCoolText(['In association', 'with']); + case 7: + addMoreText('newgrounds'); + ngSpr.visible = true; + // credTextShit.text += '\nNewgrounds'; + case 8: + deleteCoolText(); + ngSpr.visible = false; + // credTextShit.visible = false; - // credTextShit.text = 'Shoutouts Tom Fulp'; - // credTextShit.screenCenter(); - case 9: - createCoolText([curWacky[0]]); - // credTextShit.visible = true; - case 11: - addMoreText(curWacky[1]); - // credTextShit.text += '\nlmao'; - case 12: - deleteCoolText(); - // credTextShit.visible = false; - // credTextShit.text = "Friday"; - // credTextShit.screenCenter(); - case 13: - addMoreText('Friday'); - // credTextShit.visible = true; - case 14: - addMoreText('Night'); - // credTextShit.text += '\nNight'; - case 15: - addMoreText('Funkin'); // credTextShit.text += '\nFunkin'; + // credTextShit.text = 'Shoutouts Tom Fulp'; + // credTextShit.screenCenter(); + case 9: + createCoolText([curWacky[0]]); + // credTextShit.visible = true; + case 11: + addMoreText(curWacky[1]); + // credTextShit.text += '\nlmao'; + case 12: + deleteCoolText(); + // credTextShit.visible = false; + // credTextShit.text = "Friday"; + // credTextShit.screenCenter(); + case 13: + addMoreText('Friday'); + // credTextShit.visible = true; + case 14: + addMoreText('Night'); + // credTextShit.text += '\nNight'; + case 15: + addMoreText('Funkin'); // credTextShit.text += '\nFunkin'; - case 16: - skipIntro(); + case 16: + skipIntro(); + } + } } + lastBeat = curBeat; } var skippedIntro:Bool = false; diff --git a/source/shaderslmfao/ColorSwap.hx b/source/shaderslmfao/ColorSwap.hx new file mode 100644 index 000000000..1f57dc7a0 --- /dev/null +++ b/source/shaderslmfao/ColorSwap.hx @@ -0,0 +1,105 @@ +package shaderslmfao; + +import flixel.system.FlxAssets.FlxShader; +import flixel.util.FlxColor; + +class ColorSwap +{ + public var shader(default, null):ColorSwapShader; + public var colorToReplace(default, set):FlxColor; + public var newColor(default, set):FlxColor; + public var daTime(default, set):Float; + public var hueShit:Float = 0; + + public function new():Void + { + shader = new ColorSwapShader(); + shader.uTime.value = [0]; + shader.money.value = [0]; + } + + public function update(elapsed:Float):Void + { + shader.uTime.value[0] += elapsed; + hueShit += elapsed; + // trace(shader.money.value[0]); + } + + function set_colorToReplace(color:FlxColor):FlxColor + { + colorToReplace = color; + + return color; + } + + function set_daTime(daTime:Float):Float + { + return daTime; + } + + function set_newColor(color:FlxColor):FlxColor + { + newColor = color; + + return color; + } +} + +class ColorSwapShader extends FlxShader +{ + @:glFragmentSource(' + #pragma header + + uniform float uTime; + uniform float money; + + vec3 normalizeColor(vec3 color) + { + return vec3( + color[0] / 255.0, + color[1] / 255.0, + color[2] / 255.0 + ); + } + + vec3 rgb2hsv(vec3 c) + { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); + } + + vec3 hsv2rgb(vec3 c) + { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); + } + + void main() + { + vec4 color = flixel_texture2D(bitmap, openfl_TextureCoordv); + + vec4 swagColor = vec4(rgb2hsv(vec3(color[0], color[1], color[2])), color[3]); + + // [0] is the hue??? + swagColor[0] += uTime; + // swagColor[1] += uTime; + + // money += swagColor[0]; + + color = vec4(hsv2rgb(vec3(swagColor[0], swagColor[1], swagColor[2])), swagColor[3]); + + gl_FragColor = color; + } + + ') + public function new() + { + super(); + } +}