diff --git a/assets/data/scripts/pixel.hx b/assets/data/scripts/pixel.hx index 63eabca2..dc811ac7 100644 --- a/assets/data/scripts/pixel.hx +++ b/assets/data/scripts/pixel.hx @@ -1,9 +1,16 @@ +import flixel.FlxCamera.FlxCameraFollowStyle; + public var pixelNotesForBF = true; public var pixelNotesForDad = true; public var enablePixelUI = true; +public var enableCameraHacks = true; +public var enablePauseMenu = true; var daPixelZoom = 6; +/** + * UI + */ function onNoteCreation(event) { if (event.note.mustPress && !pixelNotesForBF) return; if (!event.note.mustPress && !pixelNotesForDad) return; @@ -51,4 +58,79 @@ function onCountdown(event) { case 2: 'stages/school/ui/set'; case 3: 'stages/school/ui/go'; }; +} + +/** + * CAMERA HACKS!! + */ +function createPost() { + if (enablePauseMenu) { + PauseSubState.script = 'data/scripts/week6-pause'; + } + if (enableCameraHacks) { + FlxG.camera.antialiasing = false; + FlxG.camera.pixelPerfectRender = true; + FlxG.game.stage.quality = 2; + + var newNoteCamera = new FlxCamera(); + newNoteCamera.bgColor = 0; // transparent + FlxG.cameras.add(newNoteCamera, false); + + var pixelSwagWidth = Note.swagWidth + (6 - (Note.swagWidth % 6)); + // TODO: multikey support?? + for(s in 0...4) { + var i = 0; + for(str in [cpuStrums.members[s], playerStrums.members[s]]) { + // TODO: middlescroll??? + str.x = (FlxG.width * (0.25 + (0.5 * i))) + (pixelSwagWidth * (s - 2)); + str.x -= str.x % 6; + str.cameras = [newNoteCamera]; + i++; + } + } + + iconP1.antialiasing = false; + iconP2.antialiasing = false; + + makeCameraPixely(camGame); + makeCameraPixely(newNoteCamera); + } +} + +/** + * Use this to make any camera pixelly (you wont be able to zoom with it anymore!) + */ +public function makeCameraPixely(cam) { + cam.pixelPerfectRender = true; + cam.zoom /= Math.min(FlxG.scaleMode.scale.x, FlxG.scaleMode.scale.y) * 6; + defaultCamZoom /= 6; + + var shad = new CustomShader('pixelZoomShader'); + cam.addShader(shad); + + pixellyCameras.push(cam); + pixellyShaders.push(shad); +} + +function pixelCam(cam) { + makeCameraPixely(cam); +} + +var pixellyCameras = []; +var pixellyShaders = []; + +function updatePost(elapsed) { + for(e in pixellyCameras) { + if (!e.exists) continue; + e.zoom = 1 / 6 / Math.min(FlxG.scaleMode.scale.x, FlxG.scaleMode.scale.y); + } + for(e in pixellyShaders) { + e.pixelZoom = 1 / 6 / Math.min(FlxG.scaleMode.scale.x, FlxG.scaleMode.scale.y); + } + + if (enableCameraHacks) { + notes.forEach(function(n) { + n.y -= n.y % 6; + }); + } } \ No newline at end of file diff --git a/assets/data/scripts/week6-pause.hx b/assets/data/scripts/week6-pause.hx new file mode 100644 index 00000000..2884cd34 --- /dev/null +++ b/assets/data/scripts/week6-pause.hx @@ -0,0 +1,109 @@ +import funkin.ui.FunkinText; +import flixel.text.FlxText; +import flixel.text.FlxTextBorderStyle; +import flixel.util.FlxAxes; + +var pixelScript:Script; +var pauseCam = new FlxCamera(); + +var bg:FlxSprite; +var hand:FlxSprite; + +var texts:Array = []; + +function create(event) { + // cancel default pause menu!! + event.cancel(); + event.music = "pixel/Lunchbox"; + + cameras = []; + + pixelScript = game.scripts.getByName("pixel.hx"); + pixelScript.call("pixelCam", [pauseCam]); + + FlxG.cameras.add(pauseCam, false); + + pauseCam.bgColor = 0x88FF99CC; + pauseCam.alpha = 0; + + bg = new FlxSprite(44 * 6, 14 * 6).loadGraphic(Paths.image('stages/school/pause/bg')); + bg.scale.set(6, 6); + bg.updateHitbox(); + bg.scale.y = 5; + bg.cameras = [pauseCam]; + add(bg); + + text = new FlxText(0, 22 * 6, 0, "Pause", 8, false); + confText(text); + add(text); + + var i = 2; + for(e in menuItems) { + text = new FlxText(0, (22 * 6) + (i * 9 * 6), 0, e, 8, false); + confText(text); + add(text); + texts.push(text); + i++; + } + + hand = new FlxSprite().loadGraphic(Paths.image('stages/school/ui/hand_textbox')); + hand.scale.set(6, 6); + hand.updateHitbox(); + add(hand); + + FlxTween.tween(bg, {"scale.y": 6}, 0.75, {ease: FlxEase.elasticOut}); + + cameras = [pauseCam]; + + FlxG.sound.play(Paths.sound('pixel/clickText')); +} + +function confText(text) { + text.scale.set(6, 6); + text.updateHitbox(); + text.screenCenter(FlxAxes.X); + text.borderStyle = FlxTextBorderStyle.OUTLINE; + text.borderColor = 0xFF953E3E; +} + +function createPost() { +} + +function destroy() { + FlxG.cameras.remove(pauseCam); +} + +function update(elapsed) { + pixelScript.call("updatePost", [elapsed]); + + pauseCam.alpha = lerp(pauseCam.alpha, 1, 0.25); + + var oldSec = curSelected; + if (controls.DOWN_P) + changeSelection(1, false); + if (controls.UP_P) + changeSelection(-1); + + if (oldSec != curSelected) { + FlxG.sound.play(Paths.sound('pixel/pixelText')); + } + + var curText = texts[curSelected]; + hand.setPosition(curText.x - hand.width - 12, curText.y + (text.height - hand.height) - 6); + hand.x -= hand.x % 6; + hand.y -= hand.y % 6; + + if (controls.ACCEPT) { + FlxG.sound.play(Paths.sound('pixel/clickText')); + selectOption(); + } +} + +function changeSelection(change) { + curSelected += change; + + if (curSelected < 0) + curSelected = menuItems.length - 1; + if (curSelected >= menuItems.length) + curSelected = 0; +} \ No newline at end of file diff --git a/assets/images/stages/school/pause/bg.png b/assets/images/stages/school/pause/bg.png new file mode 100644 index 00000000..b8151586 Binary files /dev/null and b/assets/images/stages/school/pause/bg.png differ diff --git a/assets/images/stages/school/pause/concept.pfi b/assets/images/stages/school/pause/concept.pfi new file mode 100644 index 00000000..4282c765 Binary files /dev/null and b/assets/images/stages/school/pause/concept.pfi differ diff --git a/assets/week6/music/Lunchbox.mp3 b/assets/music/pixel/Lunchbox.mp3 similarity index 100% rename from assets/week6/music/Lunchbox.mp3 rename to assets/music/pixel/Lunchbox.mp3 diff --git a/assets/week6/music/Lunchbox.ogg b/assets/music/pixel/Lunchbox.ogg similarity index 100% rename from assets/week6/music/Lunchbox.ogg rename to assets/music/pixel/Lunchbox.ogg diff --git a/assets/week6/music/LunchboxScary.mp3 b/assets/music/pixel/LunchboxScary.mp3 similarity index 100% rename from assets/week6/music/LunchboxScary.mp3 rename to assets/music/pixel/LunchboxScary.mp3 diff --git a/assets/week6/music/LunchboxScary.ogg b/assets/music/pixel/LunchboxScary.ogg similarity index 100% rename from assets/week6/music/LunchboxScary.ogg rename to assets/music/pixel/LunchboxScary.ogg diff --git a/assets/week6/music/gameOver-pixel.mp3 b/assets/music/pixel/gameOver-pixel.mp3 similarity index 100% rename from assets/week6/music/gameOver-pixel.mp3 rename to assets/music/pixel/gameOver-pixel.mp3 diff --git a/assets/week6/music/gameOver-pixel.ogg b/assets/music/pixel/gameOver-pixel.ogg similarity index 100% rename from assets/week6/music/gameOver-pixel.ogg rename to assets/music/pixel/gameOver-pixel.ogg diff --git a/assets/week6/music/gameOverEnd-pixel.mp3 b/assets/music/pixel/gameOverEnd-pixel.mp3 similarity index 100% rename from assets/week6/music/gameOverEnd-pixel.mp3 rename to assets/music/pixel/gameOverEnd-pixel.mp3 diff --git a/assets/week6/music/gameOverEnd-pixel.ogg b/assets/music/pixel/gameOverEnd-pixel.ogg similarity index 100% rename from assets/week6/music/gameOverEnd-pixel.ogg rename to assets/music/pixel/gameOverEnd-pixel.ogg diff --git a/assets/shaders/pixelZoomShader.frag b/assets/shaders/pixelZoomShader.frag new file mode 100644 index 00000000..17635ebf --- /dev/null +++ b/assets/shaders/pixelZoomShader.frag @@ -0,0 +1,11 @@ +#pragma header + +uniform float pixelZoom; +// zooms the game 6 times +void main() { + vec2 camPos = getCamPos(openfl_TextureCoordv); + + camPos = vec2(0.5, 0.5) + ((camPos - vec2(0.5, 0.5)) * pixelZoom); + + gl_FragColor = textureCam(bitmap, camPos); +} \ No newline at end of file diff --git a/assets/sounds/clickText.mp3 b/assets/sounds/pixel/clickText.mp3 similarity index 100% rename from assets/sounds/clickText.mp3 rename to assets/sounds/pixel/clickText.mp3 diff --git a/assets/sounds/clickText.ogg b/assets/sounds/pixel/clickText.ogg similarity index 100% rename from assets/sounds/clickText.ogg rename to assets/sounds/pixel/clickText.ogg diff --git a/assets/sounds/pixelText.mp3 b/assets/sounds/pixel/pixelText.mp3 similarity index 100% rename from assets/sounds/pixelText.mp3 rename to assets/sounds/pixel/pixelText.mp3 diff --git a/assets/sounds/pixelText.ogg b/assets/sounds/pixel/pixelText.ogg similarity index 100% rename from assets/sounds/pixelText.ogg rename to assets/sounds/pixel/pixelText.ogg diff --git a/buildnumber.txt b/buildnumber.txt index f44396cc..09486914 100644 --- a/buildnumber.txt +++ b/buildnumber.txt @@ -1 +1 @@ -1149 \ No newline at end of file +1155 \ No newline at end of file diff --git a/source/funkin/game/PlayState.hx b/source/funkin/game/PlayState.hx index c5108e4b..1d005218 100644 --- a/source/funkin/game/PlayState.hx +++ b/source/funkin/game/PlayState.hx @@ -153,6 +153,8 @@ class PlayState extends MusicBeatState override public function create() { instance = this; + PauseSubState.script = ""; + if (FlxG.sound.music != null) FlxG.sound.music.stop(); diff --git a/source/funkin/menus/PauseSubState.hx b/source/funkin/menus/PauseSubState.hx index 3ce161f1..21881d20 100644 --- a/source/funkin/menus/PauseSubState.hx +++ b/source/funkin/menus/PauseSubState.hx @@ -1,5 +1,8 @@ package funkin.menus; +import funkin.scripting.events.PauseCreationEvent; +import funkin.scripting.events.PauseSelectOptionEvent; +import funkin.scripting.Script; import flixel.FlxG; import flixel.FlxSprite; import flixel.FlxSubState; @@ -16,6 +19,8 @@ import funkin.options.keybinds.KeybindsOptions; class PauseSubState extends MusicBeatSubstate { + public static var script:String = ""; + var grpMenuShit:FlxTypedGroup; var menuItems:Array = ['Resume', 'Restart Song', 'Change Controls', 'Options','Exit to menu']; @@ -23,16 +28,33 @@ class PauseSubState extends MusicBeatSubstate var pauseMusic:FlxSound; + public var pauseScript:Script; + + public var game:PlayState = PlayState.instance; // shortcut + + private var __cancelDefault:Bool = false; + public function new(x:Float, y:Float) { super(); - pauseMusic = new FlxSound().loadEmbedded(Paths.music('breakfast'), true, true); + pauseScript = Script.create(Paths.script(script)); + pauseScript.setParent(this); + pauseScript.load(); + + var event = new PauseCreationEvent('breakfast', menuItems); + pauseScript.call('create', [event]); + + menuItems = event.options; + + + pauseMusic = new FlxSound().loadEmbedded(Paths.music(event.music), true, true); pauseMusic.volume = 0; pauseMusic.play(false, FlxG.random.int(0, Std.int(pauseMusic.length / 2))); - FlxG.sound.list.add(pauseMusic); + if (__cancelDefault = event.cancelled) return; + var bg:FlxSprite = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); bg.alpha = 0; bg.scrollFactor.set(); @@ -74,56 +96,58 @@ class PauseSubState extends MusicBeatSubstate changeSelection(); cameras = [FlxG.cameras.list[FlxG.cameras.list.length - 1]]; + + pauseScript.call("createPost"); } override function update(elapsed:Float) { + super.update(elapsed); + if (pauseMusic.volume < 0.5) pauseMusic.volume += 0.01 * elapsed; - super.update(elapsed); + pauseScript.call("update", [elapsed]); + + if (__cancelDefault) return; var upP = controls.UP_P; var downP = controls.DOWN_P; var accepted = controls.ACCEPT; if (upP) - { changeSelection(-1); - } if (downP) - { changeSelection(1); - } - if (accepted) - { - var daSelected:String = menuItems[curSelected]; - - switch (daSelected) - { - case "Resume": - close(); - case "Restart Song": - FlxG.resetState(); - case "Change Controls": - persistentDraw = false; - openSubState(new KeybindsOptions()); - case "Exit to menu": - FlxG.switchState(new MainMenuState()); - } - } - - if (FlxG.keys.justPressed.J) - { - // for reference later! - // PlayerSettings.player1.controls.replaceBinding(Control.LEFT, Keys, FlxKey.J, null); - } + selectOption(); } + public function selectOption() { + var event = new PauseSelectOptionEvent(menuItems[curSelected]); + pauseScript.call("onSelectOption", [event]); + + if (event.cancelled) return; + + var daSelected:String = event.name; + + switch (daSelected) + { + case "Resume": + close(); + case "Restart Song": + FlxG.resetState(); + case "Change Controls": + persistentDraw = false; + openSubState(new KeybindsOptions()); + case "Exit to menu": + FlxG.switchState(new MainMenuState()); + } + } override function destroy() { - pauseMusic.destroy(); + pauseScript.call("destroy"); + if (pauseMusic != null) pauseMusic.destroy(); super.destroy(); } diff --git a/source/funkin/scripting/Script.hx b/source/funkin/scripting/Script.hx index 8826e271..b310094f 100644 --- a/source/funkin/scripting/Script.hx +++ b/source/funkin/scripting/Script.hx @@ -59,6 +59,7 @@ class Script extends FlxBasic implements IFlxDestroyable { "Strum" => funkin.game.Strum, "Character" => funkin.game.Character, "Boyfriend" => funkin.game.Character, // for compatibility + "PauseSubstate" => funkin.menus.PauseSubState, "FreeplayState" => funkin.menus.FreeplayState, "MainMenuState" => funkin.menus.MainMenuState, "PauseSubState" => funkin.menus.PauseSubState, diff --git a/source/funkin/scripting/ScriptPack.hx b/source/funkin/scripting/ScriptPack.hx index 0ea425de..5e8fb394 100644 --- a/source/funkin/scripting/ScriptPack.hx +++ b/source/funkin/scripting/ScriptPack.hx @@ -20,6 +20,19 @@ class ScriptPack extends Script { super(name); } + public function getByPath(name:String) { + for(s in scripts) + if (s.path == name) + return s; + return null; + } + + public function getByName(name:String) { + for(s in scripts) + if (s.fileName == name) + return s; + return null; + } public function importScript(path:String):Script { var script = Script.create(Paths.script(path)); if (script is DummyScript) { diff --git a/source/funkin/scripting/events/PauseCreationEvent.hx b/source/funkin/scripting/events/PauseCreationEvent.hx new file mode 100644 index 00000000..5957462e --- /dev/null +++ b/source/funkin/scripting/events/PauseCreationEvent.hx @@ -0,0 +1,23 @@ +package funkin.scripting.events; + +/** + * CANCEL this event to prevent default behaviour! + */ +class PauseCreationEvent extends CancellableEvent { + /** + * Music that is going to be played + */ + public var music:String; + + /** + * All option names + */ + public var options:Array; + + public function new(music:String, options:Array) { + super(); + + this.music = music; + this.options = options; + } +} \ No newline at end of file diff --git a/source/funkin/scripting/events/PauseSelectOptionEvent.hx b/source/funkin/scripting/events/PauseSelectOptionEvent.hx new file mode 100644 index 00000000..603c5c53 --- /dev/null +++ b/source/funkin/scripting/events/PauseSelectOptionEvent.hx @@ -0,0 +1,13 @@ +package funkin.scripting.events; + +class PauseSelectOptionEvent extends CancellableEvent { + /** + * Option name thats going to be selected + */ + public var name:String; + + public function new(name:String) { + super(); + this.name = name; + } +} \ No newline at end of file