diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md new file mode 100644 index 000000000..9eb93945f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -0,0 +1,32 @@ +--- +name: Bug Report +about: Report a bug or critical performance issue +title: 'Bug Report: ' +labels: bug +--- + +# Please check for duplicates or similar issues, as well performing simple troubleshooting steps (such as clearing cookies, clearing AppData, trying another browser) before submitting an issue. + +## Where are you playing the game? + +### Web +- [ ] [Newgrounds](https://www.newgrounds.com/portal/view/770371) +- [ ] [Itch.io](https://ninja-muffin24.itch.io/funkin) + +#### If you are using a web build, what browser are you using? +- [ ] Chrome, or a Chromium based broswer (Edge, Opera, etc.) +- [ ] Firefox, or a Gecko based broswer +- [ ] Safari +- [ ] Other, please specify: + +### Local +- [ ] Windows x86 +- [ ] Windows x86_64 +- [ ] Linux +- [ ] macOS + +## What version of the game are you using? Look in the bottom left corner of the main menu. + +## Have you identified any steps to reproduce the bug? If so, please describe them below. Use images if possible. + +## Please describe your issue. Provide extensive detail and images if possibe. diff --git a/.github/ISSUE_TEMPLATE/enhancement.md b/.github/ISSUE_TEMPLATE/enhancement.md new file mode 100644 index 000000000..c86b1a39a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/enhancement.md @@ -0,0 +1,10 @@ +--- +name: Enhancement +about: Suggest a new feature +title: 'Enhancement: ' +labels: enhancement +--- + +# Please check for duplicates or similar issues before creating this issue. + +## What is your suggestion, and why should it be implemented? diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md new file mode 100644 index 000000000..15f86824b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question.md @@ -0,0 +1,10 @@ +--- +name: Question +about: Ask a general question +title: 'Question: ' +labels: question +--- + +# Please check for duplicates or similar issues before asking your question. + +## What is your question? diff --git a/.github/PULL_REQUEST_TEMPLATE/bug.md b/.github/PULL_REQUEST_TEMPLATE/bug.md new file mode 100644 index 000000000..70d795633 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/bug.md @@ -0,0 +1,12 @@ +--- +name: Bug Fix +about: Fix a bug or critical performance issue +title: 'Bug Fix: ' +labels: bug +--- + +# Please check for duplicates or similar PRs before creating this issue. + +## Does this PR close any issue(s)? If so, link them below. + +## Breifly describe the issue(s) fixed. diff --git a/.github/PULL_REQUEST_TEMPLATE/enhancement.md b/.github/PULL_REQUEST_TEMPLATE/enhancement.md new file mode 100644 index 000000000..6af15f1b6 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/enhancement.md @@ -0,0 +1,12 @@ +--- +name: Enhancement +about: Add a new feature +title: 'Enhancement: ' +labels: enhancement +--- + +# Please check for duplicates or similar PRs before creating this issue. + +## Does this PR close any issue(s)? If so, link them below. + +## What do your change(s) add, and why should they be implemented? diff --git a/.github/workflows/superlinter.yml b/.github/workflows/superlinter.yml index 799adf821..7f2c82e13 100644 --- a/.github/workflows/superlinter.yml +++ b/.github/workflows/superlinter.yml @@ -1,10 +1,10 @@ -name: learn-github-actions -on: [push] jobs: - check-bats-version: - runs-on: ubuntu-latest + build: + runs-on: [ubuntu-latest, macos-latest] steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 - - run: npm install -g bats - - run: bats -v + - uses: krdlab/setup-haxe@v1 + with: + haxe-version: 4.0.5 + - run: | + haxe -version + haxelib install hxnodejs \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f39c89b3..c60647699 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,53 @@ All notable changes will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [UNRELEASED] +## [0.2.7] - 2021-02-02 +### Added +- PIXEL DAY UPDATE LOL 1 WEEK LATER +- 3 New songs by Kawaisprite! +- COOL CUTSCENES +- WEEK 6 YOYOYOYOY +- Swaggy pixel art by Moawling! +### Changed +- Made it so you lose sliiiightly more health when you miss a note. +- Removed the default HaxeFlixel pause screen when the game window loses focus, can get screenshots of the game easier hehehe ### Fixed +- Idle animation bug with BF christmas and BF hair blow sprites ([Thanks to Injourn for the Pull Request!](https://github.com/ninjamuffin99/Funkin/pull/237)) + +## [0.2.6] - 2021-01-20 +### Added +- 3 NEW CHRISTMAS SONGS. 2 BY KAWAISPRITE, 1 BY BASSETFILMS!!!!! BF WITH DRIP! SANTA HANGIN OUT! +- Enemy icons change when they you are winning a lot ([Thanks to pahaze for the Pull Request!](https://github.com/ninjamuffin99/Funkin/pull/138)) +- Holding CTRL in charting editor places notes on both sides +- Q and E changes sustain lengths in note editor +- Other charting editor workflow improvements +- More hair physics +- Heads appear at top of chart editor to help show which side ur charting for +### Changed +- Tweaked code relating to inputs, hopefully making notes that are close together more fair to hit +### Removed +- Removed APE +### Fixed +- Maybe fixed double notes / jump notes. Need to tweak it for balance, but should open things up for cooler charts in the future. +- Old Verison popup screen weirdness ([Thanks to gedehari for the Pull Request!](https://github.com/ninjamuffin99/Funkin/pull/155)) +- Song no longer loops when finishing the song. ([Thanks Injourn for the Pull Request!](https://github.com/ninjamuffin99/Funkin/pull/132)) +- Screen wipe being cut off in the limo/mom stage. Should fill the whole screen now. +- Boyfriend animations on hold notes, and pressing on repeating notes should behave differently + +## [0.2.5] - 2020-12-27 +### Added +- MOMMY GF, 3 NEW ASS SONGS BY KAWAISPRITE, NEW ART BY PHANTOMARCADE,WOOOOOOAH!!!! +- Different icons depending on which character you are against, art by EVILSK8R!! +- Autosave to chart editor +- Clear section button to note editor +- Swap button in note editor +- a new boot text or two +- automatic check for when you're on an old version of the game! +### Changed +- Made Spookeez on Normal easier. +- Mouse is now visible in note editor +### Fixed +- Crash when playing Week 3 and then playing a non-week 3 song - When pausing music at the start, it doesn't continue the song anyways. ([shoutouts gedehari for the Pull Request!](https://github.com/ninjamuffin99/Funkin/pull/48)) - IDK i think backing out of song menu should play main menu songs again hehe ([shoutouts gedehari for the Pull Request!](https://github.com/ninjamuffin99/Funkin/pull/48)) diff --git a/Modding.md b/Modding.md new file mode 100644 index 000000000..4b52fd8c5 --- /dev/null +++ b/Modding.md @@ -0,0 +1,13 @@ +# RIGHT NOW THE MODS FOLDER DOES NOT WORK ENTIRELY JUST YET!!! +## THIS IS WORK IN PROGRESS!!! + +# QUICK AND DIRTY MOD GUIDE + +With the 0.2.6 update, I added a bit of a slightly nicer mod support backend. + +It's POLYMOD, which is made by Lars Doucet: https://github.com/larsiusprime/polymod + +You may have noticed that there's a new folder in the assets. MODS. Within it you will see 2 files. modList.txt, and a folder called introMod. +modList.txt will load any folder into the game. Put the folder you want to load into a new line in modList.txt, and reboot the game. + +Now you may be wondering, what do I put in the folder? Well later down it'll get a bit more complicated, especially as I'll make the IN-GAME mod loader nicer. \ No newline at end of file diff --git a/Project.xml b/Project.xml index 21ed84198..498368897 100644 --- a/Project.xml +++ b/Project.xml @@ -2,7 +2,7 @@ - + @@ -24,7 +24,7 @@ - + @@ -42,6 +42,8 @@ + + @@ -52,12 +54,16 @@ - - - + + + @@ -67,6 +73,7 @@ + @@ -98,7 +105,7 @@ - + diff --git a/README.md b/README.md index 313730e50..8b70997e2 100644 --- a/README.md +++ b/README.md @@ -4,4 +4,89 @@ This is the repository for Friday Night Funkin, a game originally made for Ludum Play the Ludum Dare prototype here: https://ninja-muffin24.itch.io/friday-night-funkin Play the Newgrounds one here: https://www.newgrounds.com/portal/view/770371 -Support the project on the itch.io page: https://ninja-muffin24.itch.io/funkin \ No newline at end of file +Support the project on the itch.io page: https://ninja-muffin24.itch.io/funkin + +## Credits / shoutouts + +- [ninjamuffin99 (me!)](https://twitter.com/ninja_muffin99) - Programmer +- [PhantomArcade3K](https://twitter.com/phantomarcade3k) and [Evilsk8r](https://twitter.com/evilsk8r) - Art +- [Kawaisprite](https://twitter.com/kawaisprite) - Musician + +This game was made with love to Newgrounds and it's community. Extra love to Tom Fulp. + +## Build instructions + +THESE INSTRUCTIONS ARE FOR COMPILING THE GAME'S SOURCE CODE!!! + +IF YOU WANT TO JUST DOWNLOAD AND INSTALL AND PLAY THE GAME NORMALLY, GO TO ITCH.IO TO DOWNLOAD THE GAME FOR PC, MAC, AND LINUX!! + +https://ninja-muffin24.itch.io/friday-night-funkin + +IF YOU WANT TO COMPILE THE GAME YOURSELF, CONTINUE READING!!! + +### Installing shit + +First you need to install Haxe and HaxeFlixel. I'm too lazy to write and keep updated with that setup (which is pretty simple). +The link to that is on the [HaxeFlixel website](https://haxeflixel.com/documentation/getting-started/) + +Other installations you'd need is the additional libraries, a fully updated list will be in `Project.xml` in the project root, but here are the one's I'm using as of writing. + +``` +hscript +flixel-ui +newgrounds +``` + +So for each of those type `haxelib install [library]` so shit like `haxelib install newgrounds` + +You'll also need to install polymod. Do this with + +``` +haxelib git polymod https://github.com/larsiusprime/polymod.git +``` + +### Ignored files + +I gitignore the API keys for the game, so that no one can nab them and post fake highscores on the leaderboards. But because of that the game +doesn't compile without it. + +Just make a file in `/source` and call it `APIStuff.hx`, and copy paste this into it + +```haxe +package; + +class APIStuff +{ + public static var API:String = ""; + public static var EncKey:String = ""; +} + +``` + +and you should be good to go there. + +### Compiling game + +Once you have all those installed, it's pretty easy to compile the game. You just need to run 'lime test html5 -debug' in the root of the project to build and run the HTML5 version. (command prompt navigation guide can be found here: [https://ninjamuffin99.newgrounds.com/news/post/1090480](https://ninjamuffin99.newgrounds.com/news/post/1090480)) + +To run it from your desktop (Windows, Mac, Linux) it can be a bit more involved. For Linux, you only need to open a terminal in the project directory and run 'lime test linux -debug' and then run the executible file in export/release/linux/bin. For Windows, you need to install Visual Studio Community 2019. While installing VSC, don't click on any of the options to install workloads. Instead, go to the individual components tab and choose the following: +* MSVC v142 - VS 2019 C++ x64/x86 build tools +* Windows SDK (10.0.17763.0) +* C++ Profiling tools +* C++ CMake tools for windows +* C++ ATL for v142 build tools (x86 & x64) +* C++ MFC for v142 build tools (x86 & x64) +* C++/CLI support for v142 build tools (14.21) +* C++ Modules for v142 build tools (x64/x86) +* Clang Compiler for Windows +* Windows 10 SDK (10.0.17134.0) +* Windows 10 SDK (10.0.16299.0) +* MSVC v141 - VS 2017 C++ x64/x86 build tools +* MSVC v140 - VS 2015 C++ build tools (v14.00) + +This will install about 22GB of crap, but once that is done you can open up a command line in the project's directory and run `lime test windows -debug`. Once that command finishes (it takes forever even on a higher end PC), you can run FNF from the .exe file under export\release\windows\bin +As for Mac, 'lime test mac -debug' should work, if not the internet surely has a guide on how to compile Haxe stuff for Mac. + +### Additional guides + +- [Command line basics](https://ninjamuffin99.newgrounds.com/news/post/1090480) diff --git a/example_mods/introMod/_append/data/introText.txt b/example_mods/introMod/_append/data/introText.txt new file mode 100644 index 000000000..45e0c08ab --- /dev/null +++ b/example_mods/introMod/_append/data/introText.txt @@ -0,0 +1 @@ +swagshit--moneymoney \ No newline at end of file diff --git a/example_mods/modList.txt b/example_mods/modList.txt new file mode 100644 index 000000000..3e2492595 --- /dev/null +++ b/example_mods/modList.txt @@ -0,0 +1 @@ +introMod \ No newline at end of file diff --git a/example_mods/readme.txt b/example_mods/readme.txt new file mode 100644 index 000000000..f8d8f6e7e --- /dev/null +++ b/example_mods/readme.txt @@ -0,0 +1,2 @@ +THIS MOD FOLDER DOES NOT ENTIRELY WORK JUST YET!!! +DONT EXPECT MUCH OUT OF IT RIGHT NOW!!! \ No newline at end of file diff --git a/source/Alphabet.hx b/source/Alphabet.hx index a5e1d9396..f9bfe23d7 100644 --- a/source/Alphabet.hx +++ b/source/Alphabet.hx @@ -48,7 +48,6 @@ class Alphabet extends FlxSpriteGroup this.text = text; isBold = bold; - if (text != "") { if (typed) @@ -73,13 +72,13 @@ class Alphabet extends FlxSpriteGroup // { // } - if (character == " ") + if (character == " " || character == "-") { lastWasSpace = true; } if (AlphaCharacter.alphabet.indexOf(character.toLowerCase()) != -1) - //if (AlphaCharacter.alphabet.contains(character.toLowerCase())) + // if (AlphaCharacter.alphabet.contains(character.toLowerCase())) { if (lastSprite != null) { @@ -123,7 +122,6 @@ class Alphabet extends FlxSpriteGroup _finalText = text; doSplitWords(); - // trace(arrayShit); var loopNum:Int = 0; @@ -140,7 +138,6 @@ class Alphabet extends FlxSpriteGroup xPosResetted = true; xPos = 0; curRow += 1; - } if (splitWords[loopNum] == " ") @@ -157,7 +154,7 @@ class Alphabet extends FlxSpriteGroup #end if (AlphaCharacter.alphabet.indexOf(splitWords[loopNum].toLowerCase()) != -1 || isNumber || isSymbol) - //if (AlphaCharacter.alphabet.contains(splitWords[loopNum].toLowerCase()) || isNumber || isSymbol) + // if (AlphaCharacter.alphabet.contains(splitWords[loopNum].toLowerCase()) || isNumber || isSymbol) { if (lastSprite != null && !xPosResetted) @@ -248,7 +245,7 @@ class AlphaCharacter extends FlxSprite public function new(x:Float, y:Float) { super(x, y); - var tex = FlxAtlasFrames.fromSparrow(AssetPaths.alphabet__png, AssetPaths.alphabet__xml); + var tex = FlxAtlasFrames.fromSparrow('assets/images/alphabet.png', 'assets/images/alphabet.xml'); frames = tex; antialiasing = true; diff --git a/source/AnimationDebug.hx b/source/AnimationDebug.hx index e74b45c56..05b40d632 100644 --- a/source/AnimationDebug.hx +++ b/source/AnimationDebug.hx @@ -50,6 +50,7 @@ class AnimationDebug extends FlxState add(dad); char = dad; + dad.flipX = false; } else { @@ -59,6 +60,7 @@ class AnimationDebug extends FlxState add(bf); char = bf; + bf.flipX = false; } dumbTexts = new FlxTypedGroup(); diff --git a/source/AssetPaths.hx b/source/AssetPaths.hx deleted file mode 100644 index db7ef4445..000000000 --- a/source/AssetPaths.hx +++ /dev/null @@ -1,4 +0,0 @@ -package; - -@:build(flixel.system.FlxAssets.buildFileReferences("assets", true)) -class AssetPaths {} diff --git a/source/BackgroundDancer.hx b/source/BackgroundDancer.hx new file mode 100644 index 000000000..e88c01905 --- /dev/null +++ b/source/BackgroundDancer.hx @@ -0,0 +1,30 @@ +package; + +import flixel.FlxSprite; +import flixel.graphics.frames.FlxAtlasFrames; + +class BackgroundDancer extends FlxSprite +{ + public function new(x:Float, y:Float) + { + super(x, y); + + frames = FlxAtlasFrames.fromSparrow("assets/images/limo/limoDancer.png", "assets/images/limo/limoDancer.xml"); + animation.addByIndices('danceLeft', 'bg dancer sketch PINK', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false); + animation.addByIndices('danceRight', 'bg dancer sketch PINK', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false); + animation.play('danceLeft'); + antialiasing = true; + } + + var danceDir:Bool = false; + + public function dance():Void + { + danceDir = !danceDir; + + if (danceDir) + animation.play('danceRight', true); + else + animation.play('danceLeft', true); + } +} diff --git a/source/BackgroundGirls.hx b/source/BackgroundGirls.hx new file mode 100644 index 000000000..57739fbea --- /dev/null +++ b/source/BackgroundGirls.hx @@ -0,0 +1,39 @@ +package; + +import flixel.FlxSprite; +import flixel.graphics.frames.FlxAtlasFrames; + +class BackgroundGirls extends FlxSprite +{ + public function new(x:Float, y:Float) + { + super(x, y); + + // BG fangirls dissuaded + frames = FlxAtlasFrames.fromSparrow('assets/images/weeb/bgFreaks.png', 'assets/images/weeb/bgFreaks.xml'); + + animation.addByIndices('danceLeft', 'BG girls group', CoolUtil.numberArray(14), "", 24, false); + animation.addByIndices('danceRight', 'BG girls group', CoolUtil.numberArray(30, 15), "", 24, false); + + animation.play('danceLeft'); + } + + var danceDir:Bool = false; + + public function getScared():Void + { + animation.addByIndices('danceLeft', 'BG fangirls dissuaded', CoolUtil.numberArray(14), "", 24, false); + animation.addByIndices('danceRight', 'BG fangirls dissuaded', CoolUtil.numberArray(30, 15), "", 24, false); + dance(); + } + + public function dance():Void + { + danceDir = !danceDir; + + if (danceDir) + animation.play('danceRight', true); + else + animation.play('danceLeft', true); + } +} diff --git a/source/BlendModeEffect.hx b/source/BlendModeEffect.hx new file mode 100644 index 000000000..1c9038be7 --- /dev/null +++ b/source/BlendModeEffect.hx @@ -0,0 +1,34 @@ +package; + +import flixel.util.FlxColor; +import openfl.display.ShaderParameter; + +typedef BlendModeShader = +{ + var uBlendColor:ShaderParameter; +} + +class BlendModeEffect +{ + public var shader(default, null):BlendModeShader; + + @:isVar + public var color(default, set):FlxColor; + + public function new(shader:BlendModeShader, color:FlxColor):Void + { + shader.uBlendColor.value = []; + this.shader = shader; + this.color = color; + } + + function set_color(color:FlxColor):FlxColor + { + shader.uBlendColor.value[0] = color.redFloat; + shader.uBlendColor.value[1] = color.greenFloat; + shader.uBlendColor.value[2] = color.blueFloat; + shader.uBlendColor.value[3] = color.alphaFloat; + + return this.color = color; + } +} diff --git a/source/Boyfriend.hx b/source/Boyfriend.hx index a30805221..c9f87f9bf 100644 --- a/source/Boyfriend.hx +++ b/source/Boyfriend.hx @@ -11,28 +11,31 @@ class Boyfriend extends Character { public var stunned:Bool = false; - public function new(x:Float, y:Float) + public function new(x:Float, y:Float, ?char:String = 'bf') { - super(x, y); + super(x, y, char, true); } override function update(elapsed:Float) { - if (animation.curAnim.name.startsWith('sing')) + if (!debugMode) { - holdTimer += elapsed; - } - else - holdTimer = 0; + if (animation.curAnim.name.startsWith('sing')) + { + holdTimer += elapsed; + } + else + holdTimer = 0; - if (animation.curAnim.name.endsWith('miss') && animation.curAnim.finished && !debugMode) - { - playAnim('idle', true, false, 10); - } + if (animation.curAnim.name.endsWith('miss') && animation.curAnim.finished && !debugMode) + { + playAnim('idle', true, false, 10); + } - if (animation.curAnim.name == 'firstDeath' && animation.curAnim.finished) - { - playAnim('deathLoop'); + if (animation.curAnim.name == 'firstDeath' && animation.curAnim.finished) + { + playAnim('deathLoop'); + } } super.update(elapsed); diff --git a/source/Character.hx b/source/Character.hx index 51d683081..821c92898 100644 --- a/source/Character.hx +++ b/source/Character.hx @@ -31,7 +31,7 @@ class Character extends FlxSprite { case 'gf': // GIRLFRIEND CODE - tex = FlxAtlasFrames.fromSparrow(AssetPaths.GF_assets__png, AssetPaths.GF_assets__xml); + tex = FlxAtlasFrames.fromSparrow('assets/images/GF_assets.png', 'assets/images/GF_assets.xml'); frames = tex; animation.addByPrefix('cheer', 'GF Cheer', 24, false); animation.addByPrefix('singLEFT', 'GF left note', 24, false); @@ -61,24 +61,85 @@ class Character extends FlxSprite playAnim('danceRight'); + case 'gf-christmas': + tex = FlxAtlasFrames.fromSparrow('assets/images/christmas/gfChristmas.png', 'assets/images/christmas/gfChristmas.xml'); + frames = tex; + animation.addByPrefix('cheer', 'GF Cheer', 24, false); + animation.addByPrefix('singLEFT', 'GF left note', 24, false); + animation.addByPrefix('singRIGHT', 'GF Right Note', 24, false); + animation.addByPrefix('singUP', 'GF Up Note', 24, false); + animation.addByPrefix('singDOWN', 'GF Down Note', 24, false); + animation.addByIndices('sad', 'gf sad', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], "", 24, false); + animation.addByIndices('danceLeft', 'GF Dancing Beat', [30, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false); + animation.addByIndices('danceRight', 'GF Dancing Beat', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false); + animation.addByIndices('hairBlow', "GF Dancing Beat Hair blowing", [0, 1, 2, 3], "", 24); + 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, -2); + 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); + + playAnim('danceRight'); + + case 'gf-car': + tex = FlxAtlasFrames.fromSparrow('assets/images/gfCar.png', 'assets/images/gfCar.xml'); + frames = tex; + animation.addByIndices('singUP', 'GF Dancing Beat Hair blowing CAR', [0], "", 24, false); + animation.addByIndices('danceLeft', 'GF Dancing Beat Hair blowing CAR', [30, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false); + animation.addByIndices('danceRight', 'GF Dancing Beat Hair blowing CAR', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, + false); + + addOffset('danceLeft', 0); + addOffset('danceRight', 0); + + playAnim('danceRight'); + + case 'gf-pixel': + tex = FlxAtlasFrames.fromSparrow('assets/images/weeb/gfPixel.png', 'assets/images/weeb/gfPixel.xml'); + frames = tex; + animation.addByIndices('singUP', 'GF IDLE', [2], "", 24, false); + animation.addByIndices('danceLeft', 'GF IDLE', [30, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false); + animation.addByIndices('danceRight', 'GF IDLE', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false); + + addOffset('danceLeft', 0); + addOffset('danceRight', 0); + + playAnim('danceRight'); + + setGraphicSize(Std.int(width * PlayState.daPixelZoom)); + updateHitbox(); + antialiasing = false; + case 'dad': // DAD ANIMATION LOADING CODE - tex = FlxAtlasFrames.fromSparrow(AssetPaths.DADDY_DEAREST__png, AssetPaths.DADDY_DEAREST__xml); + tex = FlxAtlasFrames.fromSparrow('assets/images/DADDY_DEAREST.png', 'assets/images/DADDY_DEAREST.xml'); frames = tex; animation.addByPrefix('idle', 'Dad idle dance', 24); animation.addByPrefix('singUP', 'Dad Sing Note UP', 24); animation.addByPrefix('singRIGHT', 'Dad Sing Note RIGHT', 24); animation.addByPrefix('singDOWN', 'Dad Sing Note DOWN', 24); animation.addByPrefix('singLEFT', 'Dad Sing Note LEFT', 24); - playAnim('idle'); addOffset('idle'); addOffset("singUP", -6, 50); addOffset("singRIGHT", 0, 27); addOffset("singLEFT", -10, 10); addOffset("singDOWN", 0, -30); + + playAnim('idle'); case 'spooky': - tex = FlxAtlasFrames.fromSparrow(AssetPaths.spooky_kids_assets__png, AssetPaths.spooky_kids_assets__xml); + tex = FlxAtlasFrames.fromSparrow('assets/images/spooky_kids_assets.png', 'assets/images/spooky_kids_assets.xml'); frames = tex; animation.addByPrefix('singUP', 'spooky UP NOTE', 24, false); animation.addByPrefix('singDOWN', 'spooky DOWN note', 24, false); @@ -96,10 +157,49 @@ class Character extends FlxSprite addOffset("singDOWN", -50, -130); playAnim('danceRight'); - case 'monster': - tex = FlxAtlasFrames.fromSparrow(AssetPaths.Monster_Assets__png, AssetPaths.Monster_Assets__xml); + case 'mom': + tex = FlxAtlasFrames.fromSparrow('assets/images/Mom_Assets.png', 'assets/images/Mom_Assets.xml'); frames = tex; - animation.addByPrefix('idle', 'monster idle', 24); + + animation.addByPrefix('idle', "Mom Idle", 24, false); + animation.addByPrefix('singUP', "Mom Up Pose", 24, false); + animation.addByPrefix('singDOWN', "MOM DOWN POSE", 24, false); + animation.addByPrefix('singLEFT', 'Mom Left Pose', 24, false); + // ANIMATION IS CALLED MOM LEFT POSE BUT ITS FOR THE RIGHT + // CUZ DAVE IS DUMB! + animation.addByPrefix('singRIGHT', 'Mom Pose Left', 24, false); + + addOffset('idle'); + addOffset("singUP", 14, 71); + addOffset("singRIGHT", 10, -60); + addOffset("singLEFT", 250, -23); + addOffset("singDOWN", 20, -160); + + playAnim('idle'); + + case 'mom-car': + tex = FlxAtlasFrames.fromSparrow('assets/images/momCar.png', 'assets/images/momCar.xml'); + frames = tex; + + animation.addByPrefix('idle', "Mom Idle", 24, false); + animation.addByPrefix('singUP', "Mom Up Pose", 24, false); + animation.addByPrefix('singDOWN', "MOM DOWN POSE", 24, false); + animation.addByPrefix('singLEFT', 'Mom Left Pose', 24, false); + // ANIMATION IS CALLED MOM LEFT POSE BUT ITS FOR THE RIGHT + // CUZ DAVE IS DUMB! + animation.addByPrefix('singRIGHT', 'Mom Pose Left', 24, false); + + addOffset('idle'); + addOffset("singUP", 14, 71); + addOffset("singRIGHT", 10, -60); + addOffset("singLEFT", 250, -23); + addOffset("singDOWN", 20, -160); + + playAnim('idle'); + case 'monster': + tex = FlxAtlasFrames.fromSparrow('assets/images/Monster_Assets.png', 'assets/images/Monster_Assets.xml'); + frames = tex; + animation.addByPrefix('idle', 'monster idle', 24, false); animation.addByPrefix('singUP', 'monster up note', 24, false); animation.addByPrefix('singDOWN', 'monster down', 24, false); animation.addByPrefix('singLEFT', 'Monster left note', 24, false); @@ -111,8 +211,23 @@ class Character extends FlxSprite addOffset("singLEFT", -30); addOffset("singDOWN", -30, -40); playAnim('idle'); + case 'monster-christmas': + tex = FlxAtlasFrames.fromSparrow('assets/images/christmas/monsterChristmas.png', 'assets/images/christmas/monsterChristmas.xml'); + frames = tex; + animation.addByPrefix('idle', 'monster idle', 24, false); + animation.addByPrefix('singUP', 'monster up note', 24, false); + animation.addByPrefix('singDOWN', 'monster down', 24, false); + animation.addByPrefix('singLEFT', 'Monster left note', 24, false); + animation.addByPrefix('singRIGHT', 'Monster Right note', 24, false); + + addOffset('idle'); + addOffset("singUP", -20, 50); + addOffset("singRIGHT", -51); + addOffset("singLEFT", -30); + addOffset("singDOWN", -40, -94); + playAnim('idle'); case 'pico': - tex = FlxAtlasFrames.fromSparrow(AssetPaths.Pico_FNF_assetss__png, AssetPaths.Pico_FNF_assetss__xml); + tex = FlxAtlasFrames.fromSparrow('assets/images/Pico_FNF_assetss.png', 'assets/images/Pico_FNF_assetss.xml'); frames = tex; animation.addByPrefix('idle', "Pico Idle Dance", 24); animation.addByPrefix('singUP', 'pico Up note0', 24, false); @@ -136,7 +251,6 @@ class Character extends FlxSprite animation.addByPrefix('singUPmiss', 'pico Up note miss', 24); animation.addByPrefix('singDOWNmiss', 'Pico Down Note MISS', 24); - playAnim('idle'); addOffset('idle'); addOffset("singUP", -29, 27); addOffset("singRIGHT", -68, -7); @@ -147,11 +261,12 @@ class Character extends FlxSprite addOffset("singLEFTmiss", 62, 64); addOffset("singDOWNmiss", 210, -28); - if (!isPlayer) - flipX = true; + playAnim('idle'); + + flipX = true; case 'bf': - var tex = FlxAtlasFrames.fromSparrow(AssetPaths.BOYFRIEND__png, AssetPaths.BOYFRIEND__xml); + var tex = FlxAtlasFrames.fromSparrow('assets/images/BOYFRIEND.png', 'assets/images/BOYFRIEND.xml'); frames = tex; animation.addByPrefix('idle', 'BF idle dance', 24, false); animation.addByPrefix('singUP', 'BF NOTE UP0', 24, false); @@ -169,9 +284,6 @@ class Character extends FlxSprite animation.addByPrefix('deathConfirm', "BF Dead confirm", 24, false); animation.addByPrefix('scared', 'BF idle shaking', 24); - playAnim('idle'); - - antialiasing = true; addOffset('idle', -5); addOffset("singUP", -29, 27); @@ -187,12 +299,232 @@ class Character extends FlxSprite addOffset('deathLoop', 37, 5); addOffset('deathConfirm', 37, 69); addOffset('scared', -4); + + playAnim('idle'); + + flipX = true; + + case 'bf-christmas': + var tex = FlxAtlasFrames.fromSparrow('assets/images/christmas/bfChristmas.png', 'assets/images/christmas/bfChristmas.xml'); + frames = tex; + animation.addByPrefix('idle', 'BF idle dance', 24, false); + animation.addByPrefix('singUP', 'BF NOTE UP0', 24, false); + animation.addByPrefix('singLEFT', 'BF NOTE LEFT0', 24, false); + animation.addByPrefix('singRIGHT', 'BF NOTE RIGHT0', 24, false); + animation.addByPrefix('singDOWN', 'BF NOTE DOWN0', 24, false); + animation.addByPrefix('singUPmiss', 'BF NOTE UP MISS', 24, false); + animation.addByPrefix('singLEFTmiss', 'BF NOTE LEFT MISS', 24, false); + animation.addByPrefix('singRIGHTmiss', 'BF NOTE RIGHT MISS', 24, false); + animation.addByPrefix('singDOWNmiss', 'BF NOTE DOWN MISS', 24, false); + animation.addByPrefix('hey', 'BF HEY', 24, false); + + 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); + + playAnim('idle'); + + flipX = true; + case 'bf-car': + var tex = FlxAtlasFrames.fromSparrow('assets/images/bfCar.png', 'assets/images/bfCar.xml'); + frames = tex; + animation.addByPrefix('idle', 'BF idle dance', 24, false); + animation.addByPrefix('singUP', 'BF NOTE UP0', 24, false); + animation.addByPrefix('singLEFT', 'BF NOTE LEFT0', 24, false); + animation.addByPrefix('singRIGHT', 'BF NOTE RIGHT0', 24, false); + animation.addByPrefix('singDOWN', 'BF NOTE DOWN0', 24, false); + animation.addByPrefix('singUPmiss', 'BF NOTE UP MISS', 24, false); + animation.addByPrefix('singLEFTmiss', 'BF NOTE LEFT MISS', 24, false); + animation.addByPrefix('singRIGHTmiss', 'BF NOTE RIGHT MISS', 24, false); + animation.addByPrefix('singDOWNmiss', 'BF NOTE DOWN MISS', 24, false); + + 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); + playAnim('idle'); + + flipX = true; + case 'bf-pixel': + frames = FlxAtlasFrames.fromSparrow('assets/images/weeb/bfPixel.png', 'assets/images/weeb/bfPixel.xml'); + animation.addByPrefix('idle', 'BF IDLE', 24, false); + animation.addByPrefix('singUP', 'BF UP NOTE', 24, false); + animation.addByPrefix('singLEFT', 'BF LEFT NOTE', 24, false); + animation.addByPrefix('singRIGHT', 'BF RIGHT NOTE', 24, false); + animation.addByPrefix('singDOWN', 'BF DOWN NOTE', 24, false); + animation.addByPrefix('singUPmiss', 'BF UP MISS', 24, false); + animation.addByPrefix('singLEFTmiss', 'BF LEFT MISS', 24, false); + animation.addByPrefix('singRIGHTmiss', 'BF RIGHT MISS', 24, false); + animation.addByPrefix('singDOWNmiss', 'BF DOWN MISS', 24, false); + + addOffset('idle'); + addOffset("singUP"); + addOffset("singRIGHT"); + addOffset("singLEFT"); + addOffset("singDOWN"); + addOffset("singUPmiss"); + addOffset("singRIGHTmiss"); + addOffset("singLEFTmiss"); + addOffset("singDOWNmiss"); + + setGraphicSize(Std.int(width * 6)); + updateHitbox(); + + playAnim('idle'); + + width -= 100; + height -= 100; + + antialiasing = false; + + flipX = true; + case 'bf-pixel-dead': + frames = FlxAtlasFrames.fromSparrow('assets/images/weeb/bfPixelsDEAD.png', 'assets/images/weeb/bfPixelsDEAD.xml'); + animation.addByPrefix('singUP', "BF Dies pixel", 24, false); + animation.addByPrefix('firstDeath', "BF Dies pixel", 24, false); + animation.addByPrefix('deathLoop', "Retry Loop", 24, true); + animation.addByPrefix('deathConfirm', "RETRY CONFIRM", 24, false); + animation.play('firstDeath'); + + addOffset('firstDeath'); + addOffset('deathLoop', -37); + addOffset('deathConfirm', -37); + playAnim('firstDeath'); + // pixel bullshit + setGraphicSize(Std.int(width * 6)); + updateHitbox(); + antialiasing = false; + flipX = true; + + case 'senpai': + frames = FlxAtlasFrames.fromSparrow('assets/images/weeb/senpai.png', 'assets/images/weeb/senpai.xml'); + animation.addByPrefix('idle', 'Senpai Idle', 24, false); + animation.addByPrefix('singUP', 'SENPAI UP NOTE', 24, false); + animation.addByPrefix('singLEFT', 'SENPAI LEFT NOTE', 24, false); + animation.addByPrefix('singRIGHT', 'SENPAI RIGHT NOTE', 24, false); + animation.addByPrefix('singDOWN', 'SENPAI DOWN NOTE', 24, false); + + addOffset('idle'); + addOffset("singUP", 5, 37); + addOffset("singRIGHT"); + addOffset("singLEFT", 40); + addOffset("singDOWN", 14); + + playAnim('idle'); + + setGraphicSize(Std.int(width * 6)); + updateHitbox(); + + antialiasing = false; + case 'senpai-angry': + frames = FlxAtlasFrames.fromSparrow('assets/images/weeb/senpai.png', 'assets/images/weeb/senpai.xml'); + animation.addByPrefix('idle', 'Angry Senpai Idle', 24, false); + animation.addByPrefix('singUP', 'Angry Senpai UP NOTE', 24, false); + animation.addByPrefix('singLEFT', 'Angry Senpai LEFT NOTE', 24, false); + animation.addByPrefix('singRIGHT', 'Angry Senpai RIGHT NOTE', 24, false); + animation.addByPrefix('singDOWN', 'Angry Senpai DOWN NOTE', 24, false); + + addOffset('idle'); + addOffset("singUP", 5, 37); + addOffset("singRIGHT"); + addOffset("singLEFT", 40); + addOffset("singDOWN", 14); + playAnim('idle'); + + setGraphicSize(Std.int(width * 6)); + updateHitbox(); + + antialiasing = false; + + case 'spirit': + frames = FlxAtlasFrames.fromSpriteSheetPacker('assets/images/weeb/spirit.png', 'assets/images/weeb/spirit.txt'); + animation.addByPrefix('idle', "idle spirit_", 24, false); + animation.addByPrefix('singUP', "up_", 24, false); + animation.addByPrefix('singRIGHT', "right_", 24, false); + animation.addByPrefix('singLEFT', "left_", 24, false); + animation.addByPrefix('singDOWN', "spirit down_", 24, false); + + addOffset('idle', -220, -280); + addOffset('singUP', -220, -240); + addOffset("singRIGHT", -220, -280); + addOffset("singLEFT", -200, -280); + addOffset("singDOWN", 170, 110); + + setGraphicSize(Std.int(width * 6)); + updateHitbox(); + + playAnim('idle'); + + antialiasing = false; + + case 'parents-christmas': + frames = FlxAtlasFrames.fromSparrow('assets/images/christmas/mom_dad_christmas_assets.png', + 'assets/images/christmas/mom_dad_christmas_assets.xml'); + animation.addByPrefix('idle', 'Parent Christmas Idle', 24, false); + animation.addByPrefix('singUP', 'Parent Up Note Dad', 24, false); + animation.addByPrefix('singDOWN', 'Parent Down Note Dad', 24, false); + animation.addByPrefix('singLEFT', 'Parent Left Note Dad', 24, false); + animation.addByPrefix('singRIGHT', 'Parent Right Note Dad', 24, false); + + animation.addByPrefix('singUP-alt', 'Parent Up Note Mom', 24, false); + + animation.addByPrefix('singDOWN-alt', 'Parent Down Note Mom', 24, false); + animation.addByPrefix('singLEFT-alt', 'Parent Left Note Mom', 24, false); + animation.addByPrefix('singRIGHT-alt', 'Parent Right Note Mom', 24, false); + + addOffset('idle'); + addOffset("singUP", -47, 24); + addOffset("singRIGHT", -1, -23); + addOffset("singLEFT", -30, 16); + addOffset("singDOWN", -31, -29); + addOffset("singUP-alt", -47, 24); + addOffset("singRIGHT-alt", -1, -24); + addOffset("singLEFT-alt", -30, 15); + addOffset("singDOWN-alt", -30, -27); + + playAnim('idle'); + } + + dance(); + + if (isPlayer) + { + flipX = !flipX; + + // Doesn't flip for BF, since his are already in the right place??? + if (!curCharacter.startsWith('bf')) + { + // var animArray + var oldRight = animation.getByName('singRIGHT').frames; + animation.getByName('singRIGHT').frames = animation.getByName('singLEFT').frames; + animation.getByName('singLEFT').frames = oldRight; + + // IF THEY HAVE MISS ANIMATIONS?? + if (animation.getByName('singRIGHTmiss') != null) + { + var oldMiss = animation.getByName('singRIGHTmiss').frames; + animation.getByName('singRIGHTmiss').frames = animation.getByName('singLEFTmiss').frames; + animation.getByName('singLEFTmiss').frames = oldMiss; + } + } } } override function update(elapsed:Float) { - if (curCharacter != 'bf') + if (!curCharacter.startsWith('bf')) { if (animation.curAnim.name.startsWith('sing')) { @@ -227,34 +559,63 @@ class Character extends FlxSprite */ public function dance() { - switch (curCharacter) + if (!debugMode) { - case 'bf': + switch (curCharacter) + { + case 'gf': + if (!animation.curAnim.name.startsWith('hair')) + { + danced = !danced; - case 'gf': - if (!animation.curAnim.name.startsWith('hair')) - { + if (danced) + playAnim('danceRight'); + else + playAnim('danceLeft'); + } + + case 'gf-christmas': + if (!animation.curAnim.name.startsWith('hair')) + { + danced = !danced; + + if (danced) + playAnim('danceRight'); + else + playAnim('danceLeft'); + } + + case 'gf-car': + if (!animation.curAnim.name.startsWith('hair')) + { + danced = !danced; + + if (danced) + playAnim('danceRight'); + else + playAnim('danceLeft'); + } + case 'gf-pixel': + if (!animation.curAnim.name.startsWith('hair')) + { + danced = !danced; + + if (danced) + playAnim('danceRight'); + else + playAnim('danceLeft'); + } + + case 'spooky': danced = !danced; if (danced) playAnim('danceRight'); else playAnim('danceLeft'); - } - - case 'spooky': - danced = !danced; - - if (danced) - playAnim('danceRight'); - else - playAnim('danceLeft'); - case 'dad': - playAnim('idle'); - case 'monster': - playAnim('idle'); - case 'pico': - playAnim('idle'); + default: + playAnim('idle'); + } } } @@ -267,6 +628,8 @@ class Character extends FlxSprite { offset.set(daOffset[0], daOffset[1]); } + else + offset.set(0, 0); if (curCharacter == 'gf') { diff --git a/source/ChartingState.hx b/source/ChartingState.hx index 41ed16e9c..4ed3dd909 100644 --- a/source/ChartingState.hx +++ b/source/ChartingState.hx @@ -24,6 +24,7 @@ import flixel.ui.FlxButton; import flixel.ui.FlxSpriteButton; import flixel.util.FlxColor; import haxe.Json; +import lime.utils.Assets; import openfl.events.Event; import openfl.events.IOErrorEvent; import openfl.events.IOErrorEvent; @@ -46,6 +47,8 @@ class ChartingState extends MusicBeatState */ var curSection:Int = 0; + public static var lastSection:Int = 0; + var bpmTxt:FlxText; var strumLine:FlxSprite; @@ -76,11 +79,33 @@ class ChartingState extends MusicBeatState var vocals:FlxSound; + var leftIcon:HealthIcon; + var rightIcon:HealthIcon; + override function create() { + curSection = lastSection; + gridBG = FlxGridOverlay.create(GRID_SIZE, GRID_SIZE, GRID_SIZE * 8, GRID_SIZE * 16); add(gridBG); + leftIcon = new HealthIcon('bf'); + rightIcon = new HealthIcon('dad'); + leftIcon.scrollFactor.set(1, 1); + rightIcon.scrollFactor.set(1, 1); + + leftIcon.setGraphicSize(0, 45); + rightIcon.setGraphicSize(0, 45); + + add(leftIcon); + add(rightIcon); + + leftIcon.setPosition(0, -100); + rightIcon.setPosition(gridBG.width / 2, -100); + + var gridBlackLine:FlxSprite = new FlxSprite(gridBG.x + gridBG.width / 2).makeGraphic(2, Std.int(gridBG.height), FlxColor.BLACK); + add(gridBlackLine); + curRenderedNotes = new FlxTypedGroup(); curRenderedSustains = new FlxTypedGroup(); @@ -89,11 +114,11 @@ class ChartingState extends MusicBeatState else { _song = { - song: 'Monster', + song: 'Test', notes: [], - bpm: 95, + bpm: 150, sections: 0, - needsVoices: false, + needsVoices: true, player1: 'bf', player2: 'dad', sectionLengths: [], @@ -102,6 +127,9 @@ class ChartingState extends MusicBeatState }; } + FlxG.mouse.visible = true; + FlxG.save.bind('funkin', 'ninjamuffin99'); + tempBpm = _song.bpm; addSection(); @@ -152,14 +180,26 @@ class ChartingState extends MusicBeatState typingShit = UI_songTitle; var check_voices = new FlxUICheckBox(10, 25, null, null, "Has voice track", 100); - check_voices.checked = true; - _song.needsVoices = check_voices.checked; + check_voices.checked = _song.needsVoices; + // _song.needsVoices = check_voices.checked; check_voices.callback = function() { _song.needsVoices = check_voices.checked; trace('CHECKED!'); }; + var check_mute_inst = new FlxUICheckBox(10, 200, null, null, "Mute Instrumental (in editor)", 100); + check_mute_inst.checked = false; + check_mute_inst.callback = function() + { + var vol:Float = 1; + + if (check_mute_inst.checked) + vol = 0; + + FlxG.sound.music.volume = vol; + }; + var saveButton:FlxButton = new FlxButton(110, 8, "Save", function() { saveLevel(); @@ -175,15 +215,17 @@ class ChartingState extends MusicBeatState loadJson(_song.song.toLowerCase()); }); + var loadAutosaveBtn:FlxButton = new FlxButton(reloadSongJson.x, reloadSongJson.y + 30, 'load autosave', loadAutosave); + var stepperSpeed:FlxUINumericStepper = new FlxUINumericStepper(10, 80, 0.1, 1, 0.1, 10, 1); stepperSpeed.value = _song.speed; stepperSpeed.name = 'song_speed'; - var stepperBPM:FlxUINumericStepper = new FlxUINumericStepper(10, 65, 1, 1, 1, 250, 0); + var stepperBPM:FlxUINumericStepper = new FlxUINumericStepper(10, 65, 1, 1, 1, 339, 0); stepperBPM.value = Conductor.bpm; stepperBPM.name = 'song_bpm'; - var characters:Array = ["bf", 'dad', 'gf', 'spooky', 'monster', 'pico']; + var characters:Array = CoolUtil.coolTextFile('assets/data/characterList.txt'); var player1DropDown = new FlxUIDropDownMenu(10, 100, FlxUIDropDownMenu.makeStrIdLabelArray(characters, true), function(character:String) { @@ -203,9 +245,11 @@ class ChartingState extends MusicBeatState tab_group_song.add(UI_songTitle); tab_group_song.add(check_voices); + tab_group_song.add(check_mute_inst); tab_group_song.add(saveButton); tab_group_song.add(reloadSong); tab_group_song.add(reloadSongJson); + tab_group_song.add(loadAutosaveBtn); tab_group_song.add(stepperBPM); tab_group_song.add(stepperSpeed); tab_group_song.add(player1DropDown); @@ -221,6 +265,7 @@ class ChartingState extends MusicBeatState var check_mustHitSection:FlxUICheckBox; var check_changeBPM:FlxUICheckBox; var stepperSectionBPM:FlxUINumericStepper; + var check_altAnim:FlxUICheckBox; function addSectionUI():Void { @@ -235,18 +280,34 @@ class ChartingState extends MusicBeatState stepperSectionBPM.value = Conductor.bpm; stepperSectionBPM.name = 'section_bpm'; - var stepperCopy:FlxUINumericStepper = new FlxUINumericStepper(110, 30, 1, 1, -999, 999, 0); + var stepperCopy:FlxUINumericStepper = new FlxUINumericStepper(110, 130, 1, 1, -999, 999, 0); - var copyButton:FlxButton = new FlxButton(110, 8, "Copy last section", function() + var copyButton:FlxButton = new FlxButton(10, 130, "Copy last section", function() { copySection(Std.int(stepperCopy.value)); }); + var clearSectionButton:FlxButton = new FlxButton(10, 150, "Clear", clearSection); + + var swapSection:FlxButton = new FlxButton(10, 170, "Swap section", function() + { + for (i in 0..._song.notes[curSection].sectionNotes.length) + { + var note = _song.notes[curSection].sectionNotes[i]; + note[1] = (note[1] + 4) % 8; + _song.notes[curSection].sectionNotes[i] = note; + updateGrid(); + } + }); + check_mustHitSection = new FlxUICheckBox(10, 30, null, null, "Must hit section", 100); check_mustHitSection.name = 'check_mustHit'; check_mustHitSection.checked = true; // _song.needsVoices = check_mustHit.checked; + check_altAnim = new FlxUICheckBox(10, 400, null, null, "Alt Animation", 100); + check_altAnim.name = 'check_altAnim'; + check_changeBPM = new FlxUICheckBox(10, 60, null, null, 'Change BPM', 100); check_changeBPM.name = 'check_changeBPM'; @@ -254,8 +315,11 @@ class ChartingState extends MusicBeatState tab_group_section.add(stepperSectionBPM); tab_group_section.add(stepperCopy); tab_group_section.add(check_mustHitSection); + tab_group_section.add(check_altAnim); tab_group_section.add(check_changeBPM); tab_group_section.add(copyButton); + tab_group_section.add(clearSectionButton); + tab_group_section.add(swapSection); UI_box.addGroup(tab_group_section); } @@ -289,7 +353,7 @@ class ChartingState extends MusicBeatState FlxG.sound.playMusic('assets/music/' + daSong + "_Inst" + TitleState.soundExt, 0.6); - // WONT WORK FOR TUTORIAL! REDO LATER + // WONT WORK FOR TUTORIAL OR TEST SONG!!! REDO LATER vocals = new FlxSound().loadEmbedded("assets/music/" + daSong + "_Voices" + TitleState.soundExt); FlxG.sound.list.add(vocals); @@ -334,9 +398,14 @@ class ChartingState extends MusicBeatState { case 'Must hit section': _song.notes[curSection].mustHitSection = check.checked; + + updateHeads(); + case 'Change BPM': _song.notes[curSection].changeBPM = check.checked; FlxG.log.add('changed bpm shit'); + case "Alt Animation": + _song.notes[curSection].altAnim = check.checked; } } else if (id == FlxUINumericStepper.CHANGE_EVENT && (sender is FlxUINumericStepper)) @@ -459,12 +528,39 @@ class ChartingState extends MusicBeatState if (FlxG.keys.justPressed.ENTER) { + lastSection = curSection; + PlayState.SONG = _song; FlxG.sound.music.stop(); vocals.stop(); FlxG.switchState(new PlayState()); } + if (FlxG.keys.justPressed.E) + { + changeNoteSustain(Conductor.stepCrochet); + } + if (FlxG.keys.justPressed.Q) + { + changeNoteSustain(-Conductor.stepCrochet); + } + + if (FlxG.keys.justPressed.TAB) + { + if (FlxG.keys.pressed.SHIFT) + { + UI_box.selected_tab -= 1; + if (UI_box.selected_tab < 0) + UI_box.selected_tab = 2; + } + else + { + UI_box.selected_tab += 1; + if (UI_box.selected_tab >= 3) + UI_box.selected_tab = 0; + } + } + if (!typingShit.hasFocus) { if (FlxG.keys.justPressed.SPACE) @@ -484,27 +580,58 @@ class ChartingState extends MusicBeatState if (FlxG.keys.justPressed.R) { if (FlxG.keys.pressed.SHIFT) - changeSection(); + resetSection(true); else - changeSection(curSection); + resetSection(); } - if (FlxG.keys.pressed.W || FlxG.keys.pressed.S) + if (FlxG.mouse.wheel != 0) { FlxG.sound.music.pause(); vocals.pause(); - var daTime:Float = 700 * FlxG.elapsed; - - if (FlxG.keys.pressed.W) - { - FlxG.sound.music.time -= daTime; - } - else - FlxG.sound.music.time += daTime; - + FlxG.sound.music.time -= (FlxG.mouse.wheel * Conductor.stepCrochet * 0.4); vocals.time = FlxG.sound.music.time; } + + if (!FlxG.keys.pressed.SHIFT) + { + if (FlxG.keys.pressed.W || FlxG.keys.pressed.S) + { + FlxG.sound.music.pause(); + vocals.pause(); + + var daTime:Float = 700 * FlxG.elapsed; + + if (FlxG.keys.pressed.W) + { + FlxG.sound.music.time -= daTime; + } + else + FlxG.sound.music.time += daTime; + + vocals.time = FlxG.sound.music.time; + } + } + else + { + if (FlxG.keys.justPressed.W || FlxG.keys.justPressed.S) + { + FlxG.sound.music.pause(); + vocals.pause(); + + var daTime:Float = Conductor.stepCrochet * 2; + + if (FlxG.keys.justPressed.W) + { + FlxG.sound.music.time -= daTime; + } + else + FlxG.sound.music.time += daTime; + + vocals.time = FlxG.sound.music.time; + } + } } _song.bpm = tempBpm; @@ -517,9 +644,9 @@ class ChartingState extends MusicBeatState var shiftThing:Int = 1; if (FlxG.keys.pressed.SHIFT) shiftThing = 4; - if (FlxG.keys.justPressed.RIGHT) + if (FlxG.keys.justPressed.RIGHT || FlxG.keys.justPressed.D) changeSection(curSection + shiftThing); - if (FlxG.keys.justPressed.LEFT) + if (FlxG.keys.justPressed.LEFT || FlxG.keys.justPressed.A) changeSection(curSection - shiftThing); bpmTxt.text = bpmTxt.text = Std.string(FlxMath.roundDecimal(Conductor.songPosition / 1000, 2)) @@ -530,6 +657,21 @@ class ChartingState extends MusicBeatState super.update(elapsed); } + function changeNoteSustain(value:Float):Void + { + if (curSelectedNote != null) + { + if (curSelectedNote[2] != null) + { + curSelectedNote[2] += value; + curSelectedNote[2] = Math.max(curSelectedNote[2], 0); + } + } + + updateNoteUI(); + updateGrid(); + } + function recalculateSteps():Int { var steps:Int = 0; @@ -552,6 +694,29 @@ class ChartingState extends MusicBeatState return curStep; } + function resetSection(songBeginning:Bool = false):Void + { + updateGrid(); + + FlxG.sound.music.pause(); + vocals.pause(); + + // Basically old shit from changeSection??? + FlxG.sound.music.time = lengthBpmBullshit() * Conductor.stepCrochet * curSection; + + if (songBeginning) + { + FlxG.sound.music.time = 0; + curSection = 0; + } + + vocals.time = FlxG.sound.music.time; + updateCurStep(); + + updateGrid(); + updateSectionUI(); + } + function changeSection(sec:Int = 0, ?updateMusic:Bool = true):Void { trace('changing section' + sec); @@ -606,13 +771,31 @@ class ChartingState extends MusicBeatState stepperLength.value = sec.lengthInSteps; check_mustHitSection.checked = sec.mustHitSection; + check_altAnim.checked = sec.altAnim; check_changeBPM.checked = sec.changeBPM; stepperSectionBPM.value = sec.bpm; + + updateHeads(); + } + + function updateHeads():Void + { + if (check_mustHitSection.checked) + { + leftIcon.animation.play('bf'); + rightIcon.animation.play('dad'); + } + else + { + leftIcon.animation.play('dad'); + rightIcon.animation.play('bf'); + } } function updateNoteUI():Void { - stepperSusLength.value = curSelectedNote[2]; + if (curSelectedNote != null) + stepperSusLength.value = curSelectedNote[2]; } function updateGrid():Void @@ -684,7 +867,8 @@ class ChartingState extends MusicBeatState changeBPM: false, mustHitSection: true, sectionNotes: [], - typeOfSection: 0 + typeOfSection: 0, + altAnim: false }; _song.notes.push(sec); @@ -722,6 +906,13 @@ class ChartingState extends MusicBeatState updateGrid(); } + function clearSection():Void + { + _song.notes[curSection].sectionNotes = []; + + updateGrid(); + } + function clearSong():Void { for (daSection in 0..._song.notes.length) @@ -742,11 +933,18 @@ class ChartingState extends MusicBeatState curSelectedNote = _song.notes[curSection].sectionNotes[_song.notes[curSection].sectionNotes.length - 1]; + if (FlxG.keys.pressed.CONTROL) + { + _song.notes[curSection].sectionNotes.push([noteStrum, (noteData + 4) % 8, noteSus]); + } + trace(getStrumTime(dummyArrow.y) + (curSection * (Conductor.stepCrochet * lengthBpmBullshit()))); trace(curSection); updateGrid(); updateNoteUI(); + + autosaveSong(); } function getStrumTime(yPos:Float):Float @@ -807,11 +1005,21 @@ class ChartingState extends MusicBeatState FlxG.resetState(); } - var mp3File:Sound; - var waveForm:FlxSprite; - - function drawWave():Void + function loadAutosave():Void { + PlayState.SONG = Song.parseJSONshit(FlxG.save.data.autosave); + FlxG.resetState(); + } + + function autosaveSong():Void + { + FlxG.save.data.autosave = Json.stringify({ + "song": _song, + "bpm": Conductor.bpm, + "sections": _song.notes.length, + 'notes': _song.notes + }); + FlxG.save.flush(); } private function saveLevel() diff --git a/source/CoolUtil.hx b/source/CoolUtil.hx new file mode 100644 index 000000000..f49eeb071 --- /dev/null +++ b/source/CoolUtil.hx @@ -0,0 +1,30 @@ +package; + +import lime.utils.Assets; + +using StringTools; + +class CoolUtil +{ + public static function coolTextFile(path:String):Array + { + var daList:Array = Assets.getText(path).trim().split('\n'); + + for (i in 0...daList.length) + { + daList[i] = daList[i].trim(); + } + + return daList; + } + + public static function numberArray(max:Int, ?min = 0):Array + { + var dumbArray:Array = []; + for (i in min...max) + { + dumbArray.push(i); + } + return dumbArray; + } +} diff --git a/source/DialogueBox.hx b/source/DialogueBox.hx index 488fe35fd..f9c443952 100644 --- a/source/DialogueBox.hx +++ b/source/DialogueBox.hx @@ -2,38 +2,139 @@ package; import flixel.FlxG; import flixel.FlxSprite; +import flixel.addons.text.FlxTypeText; import flixel.graphics.frames.FlxAtlasFrames; import flixel.group.FlxSpriteGroup; import flixel.input.FlxKeyManager; +import flixel.text.FlxText; +import flixel.util.FlxColor; +import flixel.util.FlxTimer; + +using StringTools; class DialogueBox extends FlxSpriteGroup { var box:FlxSprite; + var curCharacter:String = ''; + var dialogue:Alphabet; var dialogueList:Array = []; + // SECOND DIALOGUE FOR THE PIXEL SHIT INSTEAD??? + var swagDialogue:FlxTypeText; + + var dropText:FlxText; + public var finishThing:Void->Void; + var portraitLeft:FlxSprite; + var portraitRight:FlxSprite; + + var handSelect:FlxSprite; + var bgFade:FlxSprite; + public function new(talkingRight:Bool = true, ?dialogueList:Array) { super(); - box = new FlxSprite(40); - box.frames = FlxAtlasFrames.fromSparrow(AssetPaths.speech_bubble_talking__png, AssetPaths.speech_bubble_talking__xml); - box.animation.addByPrefix('normalOpen', 'Speech Bubble Normal Open', 24, false); - box.animation.addByPrefix('normal', 'speech bubble normal', 24); + switch (PlayState.SONG.song.toLowerCase()) + { + case 'senpai': + FlxG.sound.playMusic('assets/music/Lunchbox' + TitleState.soundExt, 0); + FlxG.sound.music.fadeIn(1, 0, 0.8); + case 'thorns': + FlxG.sound.playMusic('assets/music/LunchboxScary' + TitleState.soundExt, 0); + FlxG.sound.music.fadeIn(1, 0, 0.8); + } + + bgFade = new FlxSprite(-200, -200).makeGraphic(Std.int(FlxG.width * 1.3), Std.int(FlxG.height * 1.3), 0xFFB3DFd8); + bgFade.scrollFactor.set(); + bgFade.alpha = 0; + add(bgFade); + + new FlxTimer().start(0.83, function(tmr:FlxTimer) + { + bgFade.alpha += (1 / 5) * 0.7; + if (bgFade.alpha > 0.7) + bgFade.alpha = 0.7; + }, 5); + + portraitLeft = new FlxSprite(-20, 40); + portraitLeft.frames = FlxAtlasFrames.fromSparrow('assets/images/weeb/senpaiPortrait.png', 'assets/images/weeb/senpaiPortrait.xml'); + 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 = FlxAtlasFrames.fromSparrow('assets/images/weeb/bfPortrait.png', 'assets/images/weeb/bfPortrait.xml'); + 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); + + switch (PlayState.SONG.song.toLowerCase()) + { + case 'senpai': + box.frames = FlxAtlasFrames.fromSparrow('assets/images/weeb/pixelUI/dialogueBox-pixel.png', + 'assets/images/weeb/pixelUI/dialogueBox-pixel.xml'); + box.animation.addByPrefix('normalOpen', 'Text Box Appear', 24, false); + box.animation.addByIndices('normal', 'Text Box Appear', [4], "", 24); + case 'roses': + FlxG.sound.play('assets/sounds/ANGRY_TEXT_BOX' + TitleState.soundExt); + + box.frames = FlxAtlasFrames.fromSparrow('assets/images/weeb/pixelUI/dialogueBox-senpaiMad.png', + 'assets/images/weeb/pixelUI/dialogueBox-senpaiMad.xml'); + box.animation.addByPrefix('normalOpen', 'SENPAI ANGRY IMPACT SPEECH', 24, false); + box.animation.addByIndices('normal', 'SENPAI ANGRY IMPACT SPEECH', [4], "", 24); + + case 'thorns': + box.frames = FlxAtlasFrames.fromSparrow('assets/images/weeb/pixelUI/dialogueBox-evil.png', 'assets/images/weeb/pixelUI/dialogueBox-evil.xml'); + box.animation.addByPrefix('normalOpen', 'Spirit Textbox spawn', 24, false); + box.animation.addByIndices('normal', 'Spirit Textbox spawn', [11], "", 24); + + var face:FlxSprite = new FlxSprite(320, 170).loadGraphic('assets/images/weeb/spiritFaceForward.png'); + face.setGraphicSize(Std.int(face.width * 6)); + add(face); + } + box.animation.play('normalOpen'); + box.setGraphicSize(Std.int(box.width * PlayState.daPixelZoom * 0.9)); + box.updateHitbox(); add(box); + handSelect = new FlxSprite(FlxG.width * 0.9, FlxG.height * 0.9).loadGraphic('assets/images/weeb/pixelUI/hand_textbox.png'); + add(handSelect); + + box.screenCenter(X); + portraitLeft.screenCenter(X); + if (!talkingRight) { - box.flipX = true; + // box.flipX = true; } + dropText = new FlxText(242, 502, Std.int(FlxG.width * 0.6), "", 32); + dropText.font = 'Pixel Arial 11 Bold'; + dropText.color = 0xFFD89494; + add(dropText); + + swagDialogue = new FlxTypeText(240, 500, Std.int(FlxG.width * 0.6), "", 32); + swagDialogue.font = 'Pixel Arial 11 Bold'; + swagDialogue.color = 0xFF3F2021; + swagDialogue.sounds = [FlxG.sound.load('assets/sounds/pixelText' + TitleState.soundExt, 0.6)]; + add(swagDialogue); + dialogue = new Alphabet(0, 80, "", false, true); // dialogue.x = 90; - add(dialogue); + // add(dialogue); this.dialogueList = dialogueList; } @@ -43,6 +144,18 @@ class DialogueBox extends FlxSpriteGroup override function update(elapsed:Float) { + // HARD CODING CUZ IM STUPDI + if (PlayState.SONG.song.toLowerCase() == 'roses') + portraitLeft.visible = false; + if (PlayState.SONG.song.toLowerCase() == 'thorns') + { + portraitLeft.color = FlxColor.BLACK; + swagDialogue.color = FlxColor.WHITE; + dropText.color = FlxColor.BLACK; + } + + dropText.text = swagDialogue.text; + if (box.animation.curAnim != null) { if (box.animation.curAnim.name == 'normalOpen' && box.animation.curAnim.finished) @@ -58,14 +171,37 @@ class DialogueBox extends FlxSpriteGroup dialogueStarted = true; } - if (FlxG.keys.justPressed.SPACE) + if (FlxG.keys.justPressed.ANY) { remove(dialogue); + FlxG.sound.play('assets/sounds/clickText' + TitleState.soundExt, 0.8); + if (dialogueList[1] == null) { - finishThing(); - kill(); + if (!isEnding) + { + isEnding = true; + + if (PlayState.SONG.song.toLowerCase() == 'senpai' || PlayState.SONG.song.toLowerCase() == 'thorns') + FlxG.sound.music.fadeOut(2.2, 0); + + new FlxTimer().start(0.2, function(tmr:FlxTimer) + { + box.alpha -= 1 / 5; + bgFade.alpha -= 1 / 5 * 0.7; + portraitLeft.visible = false; + portraitRight.visible = false; + swagDialogue.alpha -= 1 / 5; + dropText.alpha = swagDialogue.alpha; + }, 5); + + new FlxTimer().start(1.2, function(tmr:FlxTimer) + { + finishThing(); + kill(); + }); + } } else { @@ -77,10 +213,43 @@ class DialogueBox extends FlxSpriteGroup super.update(elapsed); } + var isEnding:Bool = false; + function startDialogue():Void { - var theDialog:Alphabet = new Alphabet(0, 70, dialogueList[0], false, true); - dialogue = theDialog; - add(theDialog); + cleanDialog(); + + // var theDialog:Alphabet = new Alphabet(0, 70, dialogueList[0], false, true); + // dialogue = theDialog; + // add(theDialog); + + // swagDialogue.text = ; + swagDialogue.resetText(dialogueList[0]); + swagDialogue.start(0.04, true); + + switch (curCharacter) + { + case 'dad': + portraitRight.visible = false; + if (!portraitLeft.visible) + { + portraitLeft.visible = true; + portraitLeft.animation.play('enter'); + } + case 'bf': + portraitLeft.visible = false; + if (!portraitRight.visible) + { + portraitRight.visible = true; + portraitRight.animation.play('enter'); + } + } + } + + function cleanDialog():Void + { + var splitName:Array = dialogueList[0].split(":"); + curCharacter = splitName[1]; + dialogueList[0] = dialogueList[0].substr(splitName[1].length + 2).trim(); } } diff --git a/source/FreeplayState.hx b/source/FreeplayState.hx index 7c45fb287..32373c354 100644 --- a/source/FreeplayState.hx +++ b/source/FreeplayState.hx @@ -10,9 +10,11 @@ import flixel.text.FlxText; import flixel.util.FlxColor; import lime.utils.Assets; +using StringTools; + class FreeplayState extends MusicBeatState { - var songs:Array = ["Bopeebo", "Dadbattle", "Fresh", "Tutorial"]; + var songs:Array = []; var selector:FlxText; var curSelected:Int = 0; @@ -28,6 +30,8 @@ class FreeplayState extends MusicBeatState override function create() { + songs = CoolUtil.coolTextFile('assets/data/freeplaySonglist.txt'); + /* if (FlxG.sound.music != null) { @@ -55,11 +59,33 @@ class FreeplayState extends MusicBeatState songs.push('Blammed'); } + if (StoryMenuState.weekUnlocked[4] || isDebug) + { + songs.push('Satin-Panties'); + songs.push('High'); + songs.push('Milf'); + } + + if (StoryMenuState.weekUnlocked[5] || isDebug) + { + songs.push('Cocoa'); + songs.push('Eggnog'); + songs.push('Winter-Horrorland'); + } + + if (StoryMenuState.weekUnlocked[6] || isDebug) + { + songs.push('Senpai'); + songs.push('Roses'); + songs.push('Thorns'); + // songs.push('Winter-Horrorland'); + } + // LOAD MUSIC // LOAD CHARACTERS - var bg:FlxSprite = new FlxSprite().loadGraphic(AssetPaths.menuBGBlue__png); + var bg:FlxSprite = new FlxSprite().loadGraphic('assets/images/menuBGBlue.png'); add(bg); grpSongs = new FlxTypedGroup(); diff --git a/source/GameOverState.hx b/source/GameOverState.hx index 064325478..ba7cb3472 100644 --- a/source/GameOverState.hx +++ b/source/GameOverState.hx @@ -24,7 +24,7 @@ class GameOverState extends FlxTransitionableState override function create() { /* var loser:FlxSprite = new FlxSprite(100, 100); - var loseTex = FlxAtlasFrames.fromSparrow(AssetPaths.lose__png, AssetPaths.lose__xml); + var loseTex = FlxAtlasFrames.fromSparrow(AssetPaths.lose.png, AssetPaths.lose.xml); loser.frames = loseTex; loser.animation.addByPrefix('lose', 'lose', 24, false); loser.animation.play('lose'); @@ -37,7 +37,7 @@ class GameOverState extends FlxTransitionableState FlxG.camera.follow(bf, LOCKON, 0.001); /* - var restart:FlxSprite = new FlxSprite(500, 50).loadGraphic(AssetPaths.restart__png); + var restart:FlxSprite = new FlxSprite(500, 50).loadGraphic(AssetPaths.restart.png); restart.setGraphicSize(Std.int(restart.width * 0.6)); restart.updateHitbox(); restart.alpha = 0; diff --git a/source/GameOverSubstate.hx b/source/GameOverSubstate.hx index 54df50cdd..58fecb58f 100644 --- a/source/GameOverSubstate.hx +++ b/source/GameOverSubstate.hx @@ -12,21 +12,35 @@ class GameOverSubstate extends MusicBeatSubstate var bf:Boyfriend; var camFollow:FlxObject; - // var + var stageSuffix:String = ""; public function new(x:Float, y:Float) { + var daStage = PlayState.curStage; + var daBf:String = ''; + switch (daStage) + { + case 'school': + stageSuffix = '-pixel'; + daBf = 'bf-pixel-dead'; + case 'schoolEvil': + stageSuffix = '-pixel'; + daBf = 'bf-pixel-dead'; + default: + daBf = 'bf'; + } + super(); Conductor.songPosition = 0; - bf = new Boyfriend(x, y); + bf = new Boyfriend(x, y, daBf); add(bf); camFollow = new FlxObject(bf.getGraphicMidpoint().x, bf.getGraphicMidpoint().y, 1, 1); add(camFollow); - FlxG.sound.play('assets/sounds/fnf_loss_sfx' + TitleState.soundExt); + FlxG.sound.play('assets/sounds/fnf_loss_sfx' + stageSuffix + TitleState.soundExt); Conductor.changeBPM(100); // FlxG.camera.followLerp = 1; @@ -63,7 +77,7 @@ class GameOverSubstate extends MusicBeatSubstate if (bf.animation.curAnim.name == 'firstDeath' && bf.animation.curAnim.finished) { - FlxG.sound.playMusic('assets/music/gameOver' + TitleState.soundExt); + FlxG.sound.playMusic('assets/music/gameOver' + stageSuffix + TitleState.soundExt); } if (FlxG.sound.music.playing) @@ -88,7 +102,7 @@ class GameOverSubstate extends MusicBeatSubstate isEnding = true; bf.playAnim('deathConfirm', true); FlxG.sound.music.stop(); - FlxG.sound.play('assets/music/gameOverEnd' + TitleState.soundExt); + FlxG.sound.play('assets/music/gameOverEnd' + stageSuffix + TitleState.soundExt); new FlxTimer().start(0.7, function(tmr:FlxTimer) { FlxG.camera.fade(FlxColor.BLACK, 2, false, function() diff --git a/source/HealthIcon.hx b/source/HealthIcon.hx new file mode 100644 index 000000000..b9810e95c --- /dev/null +++ b/source/HealthIcon.hx @@ -0,0 +1,35 @@ +package; + +import flixel.FlxSprite; + +class HealthIcon extends FlxSprite +{ + public function new(char:String = 'bf', isPlayer:Bool = false) + { + super(); + loadGraphic('assets/images/iconGrid.png', true, 150, 150); + + 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('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(); + } +} diff --git a/source/MainMenuState.hx b/source/MainMenuState.hx index 3446f4721..e1a1db228 100644 --- a/source/MainMenuState.hx +++ b/source/MainMenuState.hx @@ -10,8 +10,11 @@ import flixel.text.FlxText; import flixel.tweens.FlxEase; import flixel.tweens.FlxTween; import flixel.util.FlxColor; +import io.newgrounds.NG; import lime.app.Application; +using StringTools; + class MainMenuState extends MusicBeatState { var curSelected:Int = 0; @@ -36,7 +39,7 @@ class MainMenuState extends MusicBeatState persistentUpdate = persistentDraw = true; - var bg:FlxSprite = new FlxSprite(-80).loadGraphic(AssetPaths.menuBG__png); + var bg:FlxSprite = new FlxSprite(-80).loadGraphic('assets/images/menuBG.png'); bg.scrollFactor.x = 0; bg.scrollFactor.y = 0.18; bg.setGraphicSize(Std.int(bg.width * 1.1)); @@ -48,7 +51,7 @@ class MainMenuState extends MusicBeatState camFollow = new FlxObject(0, 0, 1, 1); add(camFollow); - magenta = new FlxSprite(-80).loadGraphic(AssetPaths.menuDesat__png); + magenta = new FlxSprite(-80).loadGraphic('assets/images/menuDesat.png'); magenta.scrollFactor.x = 0; magenta.scrollFactor.y = 0.18; magenta.setGraphicSize(Std.int(magenta.width * 1.1)); @@ -63,7 +66,7 @@ class MainMenuState extends MusicBeatState menuItems = new FlxTypedGroup(); add(menuItems); - var tex = FlxAtlasFrames.fromSparrow(AssetPaths.FNF_main_menu_assets__png, AssetPaths.FNF_main_menu_assets__xml); + var tex = FlxAtlasFrames.fromSparrow('assets/images/FNF_main_menu_assets.png', 'assets/images/FNF_main_menu_assets.xml'); for (i in 0...optionShit.length) { @@ -86,6 +89,8 @@ class MainMenuState extends MusicBeatState versionShit.setFormat("VCR OSD Mono", 16, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); add(versionShit); + // NG.core.calls.event.logEvent('swag').send(); + changeItem(); super.create(); diff --git a/source/MenuCharacter.hx b/source/MenuCharacter.hx index b550c330c..c8d50134d 100644 --- a/source/MenuCharacter.hx +++ b/source/MenuCharacter.hx @@ -13,7 +13,7 @@ class MenuCharacter extends FlxSprite this.character = character; - var tex = FlxAtlasFrames.fromSparrow(AssetPaths.campaign_menu_UI_characters__png, AssetPaths.campaign_menu_UI_characters__xml); + var tex = FlxAtlasFrames.fromSparrow('assets/images/campaign_menu_UI_characters.png', 'assets/images/campaign_menu_UI_characters.xml'); frames = tex; animation.addByPrefix('bf', "BF idle dance white", 24); @@ -22,6 +22,10 @@ class MenuCharacter extends FlxSprite animation.addByPrefix('dad', "Dad idle dance BLACK LINE", 24); animation.addByPrefix('spooky', "spooky dance idle BLACK LINES", 24); animation.addByPrefix('pico', "Pico Idle Dance", 24); + animation.addByPrefix('mom', "Mom Idle BLACK LINES", 24); + animation.addByPrefix('parents-christmas', "Parent Christmas Idle", 24); + animation.addByPrefix('senpai', "SENPAI idle Black Lines", 24); + // Parent Christmas Idle animation.play(character); updateHitbox(); diff --git a/source/MenuItem.hx b/source/MenuItem.hx index 32652114c..431e8ac77 100644 --- a/source/MenuItem.hx +++ b/source/MenuItem.hx @@ -14,7 +14,7 @@ class MenuItem extends FlxSpriteGroup { super(x, y); - var tex = FlxAtlasFrames.fromSparrow(AssetPaths.campaign_menu_UI_assets__png, AssetPaths.campaign_menu_UI_assets__xml); + var tex = FlxAtlasFrames.fromSparrow('assets/images/campaign_menu_UI_assets.png', 'assets/images/campaign_menu_UI_assets.xml'); week = new FlxSprite(); week.frames = tex; @@ -23,6 +23,9 @@ class MenuItem extends FlxSpriteGroup week.animation.addByPrefix('week1', "WEEK1 select", 24); week.animation.addByPrefix('week2', "week2 select", 24); week.animation.addByPrefix('week3', "Week 3 press", 24); + week.animation.addByPrefix('week4', "Week 4 press", 24); + week.animation.addByPrefix('week5', "week 5", 24); + week.animation.addByPrefix('week6', "Week 6", 24); add(week); week.animation.play('week' + weekNum); diff --git a/source/MusicBeatState.hx b/source/MusicBeatState.hx index 0d3862002..bda503128 100644 --- a/source/MusicBeatState.hx +++ b/source/MusicBeatState.hx @@ -3,6 +3,7 @@ package; import flixel.FlxG; import flixel.addons.transition.FlxTransitionableState; import flixel.addons.ui.FlxUIState; +import flixel.math.FlxRect; import flixel.util.FlxTimer; class MusicBeatState extends FlxUIState @@ -22,6 +23,9 @@ class MusicBeatState extends FlxUIState override function create() { + if (transIn != null) + trace('reg ' + transIn.region); + #if (!web) TitleState.soundExt = '.ogg'; #end diff --git a/source/NGio.hx b/source/NGio.hx index 2073c073b..96ced6257 100644 --- a/source/NGio.hx +++ b/source/NGio.hx @@ -2,11 +2,16 @@ package; import flixel.FlxG; import flixel.util.FlxSignal; +import flixel.util.FlxTimer; import io.newgrounds.NG; import io.newgrounds.components.ScoreBoardComponent.Period; import io.newgrounds.objects.Medal; import io.newgrounds.objects.Score; import io.newgrounds.objects.ScoreBoard; +import io.newgrounds.objects.events.Response; +import io.newgrounds.objects.events.Result.GetCurrentVersionResult; +import io.newgrounds.objects.events.Result.GetVersionResult; +import lime.app.Application; import openfl.display.Stage; /** @@ -22,6 +27,29 @@ class NGio public static var ngDataLoaded(default, null):FlxSignal = new FlxSignal(); public static var ngScoresLoaded(default, null):FlxSignal = new FlxSignal(); + public static var GAME_VER:String = ""; + public static var gotOnlineVer:Bool = false; + + public static function noLogin(api:String) + { + trace('INIT NOLOGIN'); + GAME_VER = "v" + Application.current.meta.get('version'); + + NG.create(api); + + new FlxTimer().start(2, function(tmr:FlxTimer) + { + var call = NG.core.calls.app.getCurrentVersion(GAME_VER).addDataHandler(function(response:Response) + { + GAME_VER = response.result.data.current_version; + trace('CURRENT NG VERSION: ' + GAME_VER); + gotOnlineVer = true; + }); + + call.send(); + }); + } + public function new(api:String, encKey:String, ?sessionId:String) { trace("connecting to newgrounds"); @@ -148,11 +176,8 @@ class NGio inline static public function logEvent(event:String) { - if (isLoggedIn) - { - NG.core.calls.event.logEvent(event); - trace('should have logged: ' + event); - } + NG.core.calls.event.logEvent(event).send(); + trace('should have logged: ' + event); } inline static public function unlockMedal(id:Int) diff --git a/source/Note.hx b/source/Note.hx index 06825e717..32e1b5c18 100644 --- a/source/Note.hx +++ b/source/Note.hx @@ -2,7 +2,11 @@ package; import flixel.FlxSprite; import flixel.graphics.frames.FlxAtlasFrames; +import flixel.math.FlxMath; import flixel.util.FlxColor; +import polymod.format.ParseRules.TargetSignatureElement; + +using StringTools; class Note extends FlxSprite { @@ -43,26 +47,84 @@ class Note extends FlxSprite this.noteData = noteData; - var tex = FlxAtlasFrames.fromSparrow(AssetPaths.NOTE_assets__png, AssetPaths.NOTE_assets__xml); - frames = tex; - animation.addByPrefix('greenScroll', 'green0'); - animation.addByPrefix('redScroll', 'red0'); - animation.addByPrefix('blueScroll', 'blue0'); - animation.addByPrefix('purpleScroll', 'purple0'); + var daStage:String = PlayState.curStage; - animation.addByPrefix('purpleholdend', 'pruple end hold'); - animation.addByPrefix('greenholdend', 'green hold end'); - animation.addByPrefix('redholdend', 'red hold end'); - animation.addByPrefix('blueholdend', 'blue hold end'); + switch (daStage) + { + case 'school': + loadGraphic('assets/images/weeb/pixelUI/arrows-pixels.png', true, 17, 17); - animation.addByPrefix('purplehold', 'purple hold piece'); - animation.addByPrefix('greenhold', 'green hold piece'); - animation.addByPrefix('redhold', 'red hold piece'); - animation.addByPrefix('bluehold', 'blue hold piece'); + animation.add('greenScroll', [6]); + animation.add('redScroll', [7]); + animation.add('blueScroll', [5]); + animation.add('purpleScroll', [4]); - setGraphicSize(Std.int(width * 0.7)); - updateHitbox(); - antialiasing = true; + if (isSustainNote) + { + loadGraphic('assets/images/weeb/pixelUI/arrowEnds.png', true, 7, 6); + + animation.add('purpleholdend', [4]); + animation.add('greenholdend', [6]); + animation.add('redholdend', [7]); + animation.add('blueholdend', [5]); + + animation.add('purplehold', [0]); + animation.add('greenhold', [2]); + animation.add('redhold', [3]); + animation.add('bluehold', [1]); + } + + setGraphicSize(Std.int(width * PlayState.daPixelZoom)); + updateHitbox(); + + case 'schoolEvil': // COPY PASTED CUZ I AM LAZY + loadGraphic('assets/images/weeb/pixelUI/arrows-pixels.png', true, 17, 17); + + animation.add('greenScroll', [6]); + animation.add('redScroll', [7]); + animation.add('blueScroll', [5]); + animation.add('purpleScroll', [4]); + + if (isSustainNote) + { + loadGraphic('assets/images/weeb/pixelUI/arrowEnds.png', true, 7, 6); + + animation.add('purpleholdend', [4]); + animation.add('greenholdend', [6]); + animation.add('redholdend', [7]); + animation.add('blueholdend', [5]); + + animation.add('purplehold', [0]); + animation.add('greenhold', [2]); + animation.add('redhold', [3]); + animation.add('bluehold', [1]); + } + + setGraphicSize(Std.int(width * PlayState.daPixelZoom)); + updateHitbox(); + + default: + frames = FlxAtlasFrames.fromSparrow('assets/images/NOTE_assets.png', 'assets/images/NOTE_assets.xml'); + + animation.addByPrefix('greenScroll', 'green0'); + animation.addByPrefix('redScroll', 'red0'); + animation.addByPrefix('blueScroll', 'blue0'); + animation.addByPrefix('purpleScroll', 'purple0'); + + animation.addByPrefix('purpleholdend', 'pruple end hold'); + animation.addByPrefix('greenholdend', 'green hold end'); + animation.addByPrefix('redholdend', 'red hold end'); + animation.addByPrefix('blueholdend', 'blue hold end'); + + animation.addByPrefix('purplehold', 'purple hold piece'); + animation.addByPrefix('greenhold', 'green hold piece'); + animation.addByPrefix('redhold', 'red hold piece'); + animation.addByPrefix('bluehold', 'blue hold piece'); + + setGraphicSize(Std.int(width * 0.7)); + updateHitbox(); + antialiasing = true; + } switch (noteData) { @@ -105,6 +167,9 @@ class Note extends FlxSprite x -= width / 2; + if (PlayState.curStage.startsWith('school')) + x += 30; + if (prevNote.isSustainNote) { switch (prevNote.noteData) @@ -120,7 +185,7 @@ class Note extends FlxSprite } prevNote.offset.y = -19; - prevNote.scale.y *= (2.25 * PlayState.SONG.speed); + prevNote.scale.y *= (2.25 * FlxMath.roundDecimal(PlayState.SONG.speed, 1)); // prevNote.setGraphicSize(); } } diff --git a/source/OptionsMenu.hx b/source/OptionsMenu.hx index c79c3ec70..299944af7 100644 --- a/source/OptionsMenu.hx +++ b/source/OptionsMenu.hx @@ -1,14 +1,30 @@ package; +import Controls.Control; +import flash.text.TextField; import flixel.FlxG; import flixel.FlxSprite; +import flixel.addons.display.FlxGridOverlay; +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.input.keyboard.FlxKey; +import flixel.math.FlxMath; +import flixel.text.FlxText; import flixel.util.FlxColor; +import lime.utils.Assets; class OptionsMenu extends MusicBeatState { + var selector:FlxText; + var curSelected:Int = 0; + + var controlsStrings:Array = []; + + private var grpControls:FlxTypedGroup; + override function create() { - var menuBG:FlxSprite = new FlxSprite().loadGraphic(AssetPaths.menuDesat__png); + var menuBG:FlxSprite = new FlxSprite().loadGraphic('assets/images/menuDesat.png'); + controlsStrings = CoolUtil.coolTextFile('assets/data/controls.txt'); menuBG.color = 0xFFea71fd; menuBG.setGraphicSize(Std.int(menuBG.width * 1.1)); menuBG.updateHitbox(); @@ -16,14 +32,97 @@ class OptionsMenu extends MusicBeatState menuBG.antialiasing = true; add(menuBG); + grpControls = new FlxTypedGroup(); + add(grpControls); + + for (i in 0...controlsStrings.length) + { + if (controlsStrings[i].indexOf('set') != -1) + { + var controlLabel:Alphabet = new Alphabet(0, (70 * i) + 30, controlsStrings[i].substring(3) + ': ' + controlsStrings[i + 1], true, false); + controlLabel.isMenuItem = true; + controlLabel.targetY = i; + grpControls.add(controlLabel); + } + // DONT PUT X IN THE FIRST PARAMETER OF new ALPHABET() !! + } + super.create(); } override function update(elapsed:Float) { - if (controls.BACK) - FlxG.switchState(new MainMenuState()); - super.update(elapsed); + + if (controls.ACCEPT) + { + changeBinding(); + } + + if (isSettingControl) + waitingInput(); + else + { + if (controls.BACK) + FlxG.switchState(new MainMenuState()); + if (controls.UP_P) + changeSelection(-1); + if (controls.DOWN_P) + changeSelection(1); + } + } + + function waitingInput():Void + { + if (FlxG.keys.getIsDown().length > 0) + { + PlayerSettings.player1.controls.replaceBinding(Control.LEFT, Keys, FlxG.keys.getIsDown()[0].ID, null); + } + // PlayerSettings.player1.controls.replaceBinding(Control) + } + + var isSettingControl:Bool = false; + + function changeBinding():Void + { + if (!isSettingControl) + { + isSettingControl = true; + } + } + + function changeSelection(change:Int = 0) + { + #if !switch + NGio.logEvent('Fresh'); + #end + + FlxG.sound.play('assets/sounds/scrollMenu' + TitleState.soundExt, 0.4); + + curSelected += change; + + if (curSelected < 0) + curSelected = grpControls.length - 1; + if (curSelected >= grpControls.length) + curSelected = 0; + + // selector.y = (70 * curSelected) + 30; + + var bullShit:Int = 0; + + for (item in grpControls.members) + { + item.targetY = bullShit - curSelected; + bullShit++; + + item.alpha = 0.6; + // item.setGraphicSize(Std.int(item.width * 0.8)); + + if (item.targetY == 0) + { + item.alpha = 1; + // item.setGraphicSize(Std.int(item.width)); + } + } } } diff --git a/source/OutdatedSubState.hx b/source/OutdatedSubState.hx new file mode 100644 index 000000000..962edd932 --- /dev/null +++ b/source/OutdatedSubState.hx @@ -0,0 +1,45 @@ +package; + +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.FlxSubState; +import flixel.text.FlxText; +import flixel.util.FlxColor; +import lime.app.Application; + +class OutdatedSubState extends MusicBeatState +{ + public static var leftState:Bool = false; + + override function create() + { + super.create(); + var bg:FlxSprite = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); + add(bg); + var ver = "v" + Application.current.meta.get('version'); + var txt:FlxText = new FlxText(0, 0, FlxG.width, + "HEY! You're running an outdated version of the game!\nCurrent version is " + + ver + + " while the most recent version is " + + NGio.GAME_VER + + "! Press Space to go to itch.io, or ESCAPE to ignore this!!", + 32); + txt.setFormat("VCR OSD Mono", 32, FlxColor.WHITE, CENTER); + txt.screenCenter(); + add(txt); + } + + override function update(elapsed:Float) + { + if (controls.ACCEPT) + { + FlxG.openURL("https://ninja-muffin24.itch.io/funkin"); + } + if (controls.BACK) + { + leftState = true; + FlxG.switchState(new MainMenuState()); + } + super.update(elapsed); + } +} diff --git a/source/OverlayShader.hx b/source/OverlayShader.hx new file mode 100644 index 000000000..4de9a555e --- /dev/null +++ b/source/OverlayShader.hx @@ -0,0 +1,33 @@ +package; + +import flixel.system.FlxAssets.FlxShader; + +class OverlayShader extends FlxShader +{ + @:glFragmentSource(' + #pragma header + uniform vec4 uBlendColor; + + vec3 blendLighten(base:Vec3, blend:Vec3) : Vec3 { + return mix( + 1.0 - 2.0 * (1.0 - base) * (1.0 - blend), + 2.0 * base * blend, + step( base, vec3(0.5) ) + ); + } + + vec4 blendLighten(vec4 base, vec4 blend, float opacity) + { + return (blendLighten(base, blend) * opacity + base * (1.0 - opacity)); + } + + void main() + { + vec4 base = texture2D(bitmap, openfl_TextureCoordv); + gl_FragColor = blendLighten(base, uBlendColor, uBlendColor.a); + }') + public function new() + { + super(); + } +} diff --git a/source/PauseSubState.hx b/source/PauseSubState.hx index 1c7297043..ac747dbca 100644 --- a/source/PauseSubState.hx +++ b/source/PauseSubState.hx @@ -46,7 +46,7 @@ class PauseSubState extends MusicBeatSubstate changeSelection(); - cameras = [FlxG.cameras.list[1]]; + cameras = [FlxG.cameras.list[FlxG.cameras.list.length - 1]]; } override function update(elapsed:Float) diff --git a/source/PlayState.hx b/source/PlayState.hx index 1a58bc483..cc869e5de 100644 --- a/source/PlayState.hx +++ b/source/PlayState.hx @@ -2,6 +2,7 @@ package; import Section.SwagSection; import Song.SwagSong; +import WiggleEffect.WiggleEffectType; import flixel.FlxBasic; import flixel.FlxCamera; import flixel.FlxG; @@ -11,12 +12,17 @@ import flixel.FlxSprite; import flixel.FlxState; import flixel.FlxSubState; import flixel.addons.display.FlxGridOverlay; +import flixel.addons.effects.FlxTrail; +import flixel.addons.effects.FlxTrailArea; +import flixel.addons.effects.chainable.FlxEffectSprite; +import flixel.addons.effects.chainable.FlxWaveEffect; import flixel.addons.transition.FlxTransitionableState; import flixel.graphics.atlas.FlxAtlas; import flixel.graphics.frames.FlxAtlasFrames; import flixel.group.FlxGroup.FlxTypedGroup; import flixel.math.FlxMath; import flixel.math.FlxPoint; +import flixel.math.FlxRect; import flixel.system.FlxSound; import flixel.text.FlxText; import flixel.tweens.FlxEase; @@ -29,12 +35,14 @@ import flixel.util.FlxStringUtil; import flixel.util.FlxTimer; import haxe.Json; import lime.utils.Assets; +import openfl.display.BlendMode; +import openfl.display.StageQuality; +import openfl.filters.ShaderFilter; using StringTools; class PlayState extends MusicBeatState { - public static var curLevel:String = 'Tutorial'; public static var curStage:String = ''; public static var SONG:SwagSong; public static var isStoryMode:Bool = false; @@ -57,6 +65,9 @@ class PlayState extends MusicBeatState private var curSection:Int = 0; private var camFollow:FlxObject; + + private static var prevCamFollow:FlxObject; + private var strumLineNotes:FlxTypedGroup; private var playerStrums:FlxTypedGroup; @@ -73,7 +84,8 @@ class PlayState extends MusicBeatState private var generatedMusic:Bool = false; private var startingSong:Bool = false; - private var healthHeads:FlxSprite; + private var iconP1:HealthIcon; + private var iconP2:HealthIcon; private var camHUD:FlxCamera; private var camGame:FlxCamera; @@ -86,12 +98,30 @@ class PlayState extends MusicBeatState var phillyTrain:FlxSprite; var trainSound:FlxSound; + var limo:FlxSprite; + var grpLimoDancers:FlxTypedGroup; + var fastCar:FlxSprite; + + var upperBoppers:FlxSprite; + var bottomBoppers:FlxSprite; + var santa:FlxSprite; + + var bgGirls:BackgroundGirls; + var wiggleShit:WiggleEffect = new WiggleEffect(); + var talking:Bool = true; var songScore:Int = 0; var scoreTxt:FlxText; public static var campaignScore:Int = 0; + var defaultCamZoom:Float = 1.05; + + // how big to stretch the pixel art assets + public static var daPixelZoom:Float = 6; + + var inCutscene:Bool = false; + override public function create() { // var gameCam:FlxCamera = FlxG.camera; @@ -108,7 +138,7 @@ class PlayState extends MusicBeatState persistentDraw = true; if (SONG == null) - SONG = Song.loadFromJson(curLevel); + SONG = Song.loadFromJson('tutorial'); Conductor.changeBPM(SONG.bpm); @@ -131,13 +161,20 @@ class PlayState extends MusicBeatState "If you can beat me here...", "Only then I will even CONSIDER letting you\ndate my daughter!" ]; + case 'senpai': + dialogue = CoolUtil.coolTextFile('assets/data/senpai/senpaiDialogue.txt'); + case 'roses': + dialogue = CoolUtil.coolTextFile('assets/data/roses/rosesDialogue.txt'); + case 'thorns': + dialogue = CoolUtil.coolTextFile('assets/data/thorns/thornsDialogue.txt'); } if (SONG.song.toLowerCase() == 'spookeez' || SONG.song.toLowerCase() == 'monster' || SONG.song.toLowerCase() == 'south') { + curStage = "spooky"; halloweenLevel = true; - var hallowTex = FlxAtlasFrames.fromSparrow(AssetPaths.halloween_bg__png, AssetPaths.halloween_bg__xml); + var hallowTex = FlxAtlasFrames.fromSparrow('assets/images/halloween_bg.png', 'assets/images/halloween_bg.xml'); halloweenBG = new FlxSprite(-200, -100); halloweenBG.frames = hallowTex; @@ -153,11 +190,11 @@ class PlayState extends MusicBeatState { curStage = 'philly'; - var bg:FlxSprite = new FlxSprite(-100).loadGraphic(AssetPaths.sky__png); + var bg:FlxSprite = new FlxSprite(-100).loadGraphic('assets/images/philly/sky.png'); bg.scrollFactor.set(0.1, 0.1); add(bg); - var city:FlxSprite = new FlxSprite(-10).loadGraphic(AssetPaths.city__png); + var city:FlxSprite = new FlxSprite(-10).loadGraphic('assets/images/philly/city.png'); city.scrollFactor.set(0.3, 0.3); city.setGraphicSize(Std.int(city.width * 0.85)); city.updateHitbox(); @@ -176,23 +213,277 @@ class PlayState extends MusicBeatState phillyCityLights.add(light); } - var streetBehind:FlxSprite = new FlxSprite(-40, 50).loadGraphic(AssetPaths.behindTrain__png); + var streetBehind:FlxSprite = new FlxSprite(-40, 50).loadGraphic('assets/images/philly/behindTrain.png'); add(streetBehind); - phillyTrain = new FlxSprite(2000, 360).loadGraphic(AssetPaths.train__png); + phillyTrain = new FlxSprite(2000, 360).loadGraphic('assets/images/philly/train.png'); add(phillyTrain); trainSound = new FlxSound().loadEmbedded('assets/sounds/train_passes' + TitleState.soundExt); FlxG.sound.list.add(trainSound); - // var cityLights:FlxSprite = new FlxSprite().loadGraphic(AssetPaths.win0__png); + // var cityLights:FlxSprite = new FlxSprite().loadGraphic(AssetPaths.win0.png); - var street:FlxSprite = new FlxSprite(-40, streetBehind.y).loadGraphic(AssetPaths.street__png); + var street:FlxSprite = new FlxSprite(-40, streetBehind.y).loadGraphic('assets/images/philly/street.png'); add(street); } + else if (SONG.song.toLowerCase() == 'milf' || SONG.song.toLowerCase() == 'satin-panties' || SONG.song.toLowerCase() == 'high') + { + curStage = 'limo'; + defaultCamZoom = 0.90; + + var skyBG:FlxSprite = new FlxSprite(-120, -50).loadGraphic('assets/images/limo/limoSunset.png'); + skyBG.scrollFactor.set(0.1, 0.1); + add(skyBG); + + var bgLimo:FlxSprite = new FlxSprite(-200, 480); + bgLimo.frames = FlxAtlasFrames.fromSparrow('assets/images/limo/bgLimo.png', 'assets/images/limo/bgLimo.xml'); + bgLimo.animation.addByPrefix('drive', "background limo pink", 24); + bgLimo.animation.play('drive'); + bgLimo.scrollFactor.set(0.4, 0.4); + add(bgLimo); + + grpLimoDancers = new FlxTypedGroup(); + add(grpLimoDancers); + + for (i in 0...5) + { + var dancer:BackgroundDancer = new BackgroundDancer((370 * i) + 130, bgLimo.y - 400); + dancer.scrollFactor.set(0.4, 0.4); + grpLimoDancers.add(dancer); + } + + var overlayShit:FlxSprite = new FlxSprite(-500, -600).loadGraphic('assets/images/limo/limoOverlay.png'); + overlayShit.alpha = 0.5; + // add(overlayShit); + + // var shaderBullshit = new BlendModeEffect(new OverlayShader(), FlxColor.RED); + + // FlxG.camera.setFilters([new ShaderFilter(cast shaderBullshit.shader)]); + + // overlayShit.shader = shaderBullshit; + + var limoTex = FlxAtlasFrames.fromSparrow('assets/images/limo/limoDrive.png', 'assets/images/limo/limoDrive.xml'); + + limo = new FlxSprite(-120, 550); + limo.frames = limoTex; + limo.animation.addByPrefix('drive', "Limo stage", 24); + limo.animation.play('drive'); + limo.antialiasing = true; + + fastCar = new FlxSprite(-300, 160).loadGraphic('assets/images/limo/fastCarLol.png'); + // add(limo); + } + else if (SONG.song.toLowerCase() == 'cocoa' || SONG.song.toLowerCase() == 'eggnog') + { + curStage = 'mall'; + + defaultCamZoom = 0.80; + + var bg:FlxSprite = new FlxSprite(-1000, -500).loadGraphic('assets/images/christmas/bgWalls.png'); + bg.antialiasing = true; + bg.scrollFactor.set(0.2, 0.2); + bg.active = false; + bg.setGraphicSize(Std.int(bg.width * 0.8)); + bg.updateHitbox(); + add(bg); + + upperBoppers = new FlxSprite(-240, -90); + upperBoppers.frames = FlxAtlasFrames.fromSparrow('assets/images/christmas/upperBop.png', 'assets/images/christmas/upperBop.xml'); + upperBoppers.animation.addByPrefix('bop', "Upper Crowd Bob", 24, false); + upperBoppers.antialiasing = true; + upperBoppers.scrollFactor.set(0.33, 0.33); + upperBoppers.setGraphicSize(Std.int(upperBoppers.width * 0.85)); + upperBoppers.updateHitbox(); + add(upperBoppers); + + var bgEscalator:FlxSprite = new FlxSprite(-1100, -600).loadGraphic('assets/images/christmas/bgEscalator.png'); + bgEscalator.antialiasing = true; + bgEscalator.scrollFactor.set(0.3, 0.3); + bgEscalator.active = false; + bgEscalator.setGraphicSize(Std.int(bgEscalator.width * 0.9)); + bgEscalator.updateHitbox(); + add(bgEscalator); + + var tree:FlxSprite = new FlxSprite(370, -250).loadGraphic('assets/images/christmas/christmasTree.png'); + tree.antialiasing = true; + tree.scrollFactor.set(0.40, 0.40); + add(tree); + + bottomBoppers = new FlxSprite(-300, 140); + bottomBoppers.frames = FlxAtlasFrames.fromSparrow('assets/images/christmas/bottomBop.png', 'assets/images/christmas/bottomBop.xml'); + bottomBoppers.animation.addByPrefix('bop', 'Bottom Level Boppers', 24, false); + bottomBoppers.antialiasing = true; + bottomBoppers.scrollFactor.set(0.9, 0.9); + bottomBoppers.setGraphicSize(Std.int(bottomBoppers.width * 1)); + bottomBoppers.updateHitbox(); + add(bottomBoppers); + + var fgSnow:FlxSprite = new FlxSprite(-600, 700).loadGraphic('assets/images/christmas/fgSnow.png'); + fgSnow.active = false; + fgSnow.antialiasing = true; + add(fgSnow); + + santa = new FlxSprite(-840, 150); + santa.frames = FlxAtlasFrames.fromSparrow('assets/images/christmas/santa.png', 'assets/images/christmas/santa.xml'); + santa.animation.addByPrefix('idle', 'santa idle in fear', 24, false); + santa.antialiasing = true; + add(santa); + } + else if (SONG.song.toLowerCase() == 'winter-horrorland') + { + curStage = 'mallEvil'; + var bg:FlxSprite = new FlxSprite(-400, -500).loadGraphic('assets/images/christmas/evilBG.png'); + bg.antialiasing = true; + bg.scrollFactor.set(0.2, 0.2); + bg.active = false; + bg.setGraphicSize(Std.int(bg.width * 0.8)); + bg.updateHitbox(); + add(bg); + + var evilTree:FlxSprite = new FlxSprite(300, -300).loadGraphic('assets/images/christmas/evilTree.png'); + evilTree.antialiasing = true; + evilTree.scrollFactor.set(0.2, 0.2); + add(evilTree); + + var evilSnow:FlxSprite = new FlxSprite(-200, 700).loadGraphic("assets/images/christmas/evilSnow.png"); + evilSnow.antialiasing = true; + add(evilSnow); + } + else if (SONG.song.toLowerCase() == 'senpai' || SONG.song.toLowerCase() == 'roses') + { + curStage = 'school'; + + // defaultCamZoom = 0.9; + + var bgSky = new FlxSprite().loadGraphic('assets/images/weeb/weebSky.png'); + bgSky.scrollFactor.set(0.1, 0.1); + add(bgSky); + + var repositionShit = -200; + + var bgSchool:FlxSprite = new FlxSprite(repositionShit, 0).loadGraphic('assets/images/weeb/weebSchool.png'); + bgSchool.scrollFactor.set(0.6, 0.90); + add(bgSchool); + + var bgStreet:FlxSprite = new FlxSprite(repositionShit).loadGraphic('assets/images/weeb/weebStreet.png'); + bgStreet.scrollFactor.set(0.95, 0.95); + add(bgStreet); + + var fgTrees:FlxSprite = new FlxSprite(repositionShit + 170, 130).loadGraphic('assets/images/weeb/weebTreesBack.png'); + fgTrees.scrollFactor.set(0.9, 0.9); + add(fgTrees); + + var bgTrees:FlxSprite = new FlxSprite(repositionShit - 380, -800); + var treetex = FlxAtlasFrames.fromSpriteSheetPacker('assets/images/weeb/weebTrees.png', 'assets/images/weeb/weebTrees.txt'); + bgTrees.frames = treetex; + bgTrees.animation.add('treeLoop', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], 12); + bgTrees.animation.play('treeLoop'); + bgTrees.scrollFactor.set(0.85, 0.85); + add(bgTrees); + + var treeLeaves:FlxSprite = new FlxSprite(repositionShit, -40); + treeLeaves.frames = FlxAtlasFrames.fromSparrow('assets/images/weeb/petals.png', 'assets/images/weeb/petals.xml'); + treeLeaves.animation.addByPrefix('leaves', 'PETALS ALL', 24, true); + treeLeaves.animation.play('leaves'); + treeLeaves.scrollFactor.set(0.85, 0.85); + add(treeLeaves); + + var widShit = Std.int(bgSky.width * 6); + + bgSky.setGraphicSize(widShit); + bgSchool.setGraphicSize(widShit); + bgStreet.setGraphicSize(widShit); + bgTrees.setGraphicSize(Std.int(widShit * 1.4)); + fgTrees.setGraphicSize(Std.int(widShit * 0.8)); + treeLeaves.setGraphicSize(widShit); + + fgTrees.updateHitbox(); + bgSky.updateHitbox(); + bgSchool.updateHitbox(); + bgStreet.updateHitbox(); + bgTrees.updateHitbox(); + treeLeaves.updateHitbox(); + + bgGirls = new BackgroundGirls(-100, 190); + bgGirls.scrollFactor.set(0.9, 0.9); + + if (SONG.song.toLowerCase() == 'roses') + { + bgGirls.getScared(); + } + + bgGirls.setGraphicSize(Std.int(bgGirls.width * daPixelZoom)); + bgGirls.updateHitbox(); + add(bgGirls); + } + else if (SONG.song.toLowerCase() == 'thorns') + { + curStage = 'schoolEvil'; + + var waveEffectBG = new FlxWaveEffect(FlxWaveMode.ALL, 2, -1, 3, 2); + var waveEffectFG = new FlxWaveEffect(FlxWaveMode.ALL, 2, -1, 5, 2); + + var posX = 400; + var posY = 200; + + var bg:FlxSprite = new FlxSprite(posX, posY); + bg.frames = FlxAtlasFrames.fromSparrow('assets/images/weeb/animatedEvilSchool.png', 'assets/images/weeb/animatedEvilSchool.xml'); + bg.animation.addByPrefix('idle', 'background 2', 24); + bg.animation.play('idle'); + bg.scrollFactor.set(0.8, 0.9); + bg.scale.set(6, 6); + add(bg); + + /* + var bg:FlxSprite = new FlxSprite(posX, posY).loadGraphic('assets/images/weeb/evilSchoolBG.png'); + bg.scale.set(6, 6); + // bg.setGraphicSize(Std.int(bg.width * 6)); + // bg.updateHitbox(); + add(bg); + + var fg:FlxSprite = new FlxSprite(posX, posY).loadGraphic('assets/images/weeb/evilSchoolFG.png'); + fg.scale.set(6, 6); + // fg.setGraphicSize(Std.int(fg.width * 6)); + // fg.updateHitbox(); + add(fg); + + wiggleShit.effectType = WiggleEffectType.DREAMY; + wiggleShit.waveAmplitude = 0.01; + wiggleShit.waveFrequency = 60; + wiggleShit.waveSpeed = 0.8; + */ + + // bg.shader = wiggleShit.shader; + // fg.shader = wiggleShit.shader; + + /* + var waveSprite = new FlxEffectSprite(bg, [waveEffectBG]); + var waveSpriteFG = new FlxEffectSprite(fg, [waveEffectFG]); + + // Using scale since setGraphicSize() doesnt work??? + waveSprite.scale.set(6, 6); + waveSpriteFG.scale.set(6, 6); + waveSprite.setPosition(posX, posY); + waveSpriteFG.setPosition(posX, posY); + + waveSprite.scrollFactor.set(0.7, 0.8); + waveSpriteFG.scrollFactor.set(0.9, 0.8); + + // waveSprite.setGraphicSize(Std.int(waveSprite.width * 6)); + // waveSprite.updateHitbox(); + // waveSpriteFG.setGraphicSize(Std.int(fg.width * 6)); + // waveSpriteFG.updateHitbox(); + + add(waveSprite); + add(waveSpriteFG); + */ + } else { - var bg:FlxSprite = new FlxSprite(-600, -200).loadGraphic(AssetPaths.stageback__png); + defaultCamZoom = 0.9; + curStage = 'stage'; + var bg:FlxSprite = new FlxSprite(-600, -200).loadGraphic('assets/images/stageback.png'); // bg.setGraphicSize(Std.int(bg.width * 2.5)); // bg.updateHitbox(); bg.antialiasing = true; @@ -200,7 +491,7 @@ class PlayState extends MusicBeatState bg.active = false; add(bg); - var stageFront:FlxSprite = new FlxSprite(-650, 600).loadGraphic(AssetPaths.stagefront__png); + var stageFront:FlxSprite = new FlxSprite(-650, 600).loadGraphic('assets/images/stagefront.png'); stageFront.setGraphicSize(Std.int(stageFront.width * 1.1)); stageFront.updateHitbox(); stageFront.antialiasing = true; @@ -208,7 +499,7 @@ class PlayState extends MusicBeatState stageFront.active = false; add(stageFront); - var stageCurtains:FlxSprite = new FlxSprite(-500, -300).loadGraphic(AssetPaths.stagecurtains__png); + var stageCurtains:FlxSprite = new FlxSprite(-500, -300).loadGraphic('assets/images/stagecurtains.png'); stageCurtains.setGraphicSize(Std.int(stageCurtains.width * 0.9)); stageCurtains.updateHitbox(); stageCurtains.antialiasing = true; @@ -218,13 +509,33 @@ class PlayState extends MusicBeatState add(stageCurtains); } - gf = new Character(400, 130, 'gf'); + var gfVersion:String = 'gf'; + + switch (curStage) + { + case 'limo': + gfVersion = 'gf-car'; + case 'mall': + gfVersion = 'gf-christmas'; + case 'mallEvil': + gfVersion = 'gf-christmas'; + case 'school': + gfVersion = 'gf-pixel'; + case 'schoolEvil': + gfVersion = 'gf-pixel'; + } + + if (curStage == 'limo') + gfVersion = 'gf-car'; + + gf = new Character(400, 130, gfVersion); gf.scrollFactor.set(0.95, 0.95); - gf.antialiasing = true; - add(gf); + + // Shitty layering but whatev it works LOL + if (curStage == 'limo') + add(limo); dad = new Character(100, 100, SONG.player2); - add(dad); var camPos:FlxPoint = new FlxPoint(dad.getGraphicMidpoint().x, dad.getGraphicMidpoint().y); @@ -243,19 +554,74 @@ class PlayState extends MusicBeatState dad.y += 200; case "monster": dad.y += 100; + case 'monster-christmas': + dad.y += 130; case 'dad': camPos.x += 400; case 'pico': camPos.x += 600; dad.y += 300; + case 'parents-christmas': + dad.x -= 500; + case 'senpai': + dad.x += 150; + dad.y += 360; + camPos.set(dad.getGraphicMidpoint().x + 300, dad.getGraphicMidpoint().y); + case 'senpai-angry': + dad.x += 150; + dad.y += 360; + camPos.set(dad.getGraphicMidpoint().x + 300, dad.getGraphicMidpoint().y); + case 'spirit': + dad.x -= 150; + dad.y += 100; + camPos.set(dad.getGraphicMidpoint().x + 300, dad.getGraphicMidpoint().y); } - boyfriend = new Boyfriend(770, 450); + boyfriend = new Boyfriend(770, 450, SONG.player1); + + // REPOSITIONING PER STAGE + switch (curStage) + { + case 'limo': + boyfriend.y -= 220; + boyfriend.x += 260; + + resetFastCar(); + add(fastCar); + + case 'mall': + boyfriend.x += 200; + + case 'mallEvil': + boyfriend.x += 320; + dad.y -= 80; + case 'school': + boyfriend.x += 200; + boyfriend.y += 220; + gf.x += 180; + gf.y += 300; + case 'schoolEvil': + // trailArea.scrollFactor.set(); + + var evilTrail = new FlxTrail(dad, null, 4, 24, 0.3, 0.069); + // evilTrail.changeValuesEnabled(false, false, false, false); + // evilTrail.changeGraphic() + add(evilTrail); + // evilTrail.scrollFactor.set(1.1, 1.1); + + boyfriend.x += 200; + boyfriend.y += 220; + gf.x += 180; + gf.y += 300; + } + + add(gf); + add(dad); add(boyfriend); var doof:DialogueBox = new DialogueBox(false, dialogue); // doof.x += 70; - doof.y = FlxG.height * 0.5; + // doof.y = FlxG.height * 0.5; doof.scrollFactor.set(); doof.finishThing = startCountdown; @@ -269,8 +635,6 @@ class PlayState extends MusicBeatState playerStrums = new FlxTypedGroup(); - startingSong = true; - // startCountdown(); generateSong(SONG.song); @@ -280,17 +644,25 @@ class PlayState extends MusicBeatState camFollow = new FlxObject(0, 0, 1, 1); camFollow.setPosition(camPos.x, camPos.y); + + if (prevCamFollow != null) + { + camFollow = prevCamFollow; + prevCamFollow = null; + } + add(camFollow); FlxG.camera.follow(camFollow, LOCKON, 0.04); // FlxG.camera.setScrollBounds(0, FlxG.width, 0, FlxG.height); - FlxG.camera.zoom = 1.05; + FlxG.camera.zoom = defaultCamZoom; + FlxG.camera.focusOn(camFollow.getPosition()); FlxG.worldBounds.set(0, 0, FlxG.width, FlxG.height); FlxG.fixedTimestep = false; - healthBarBG = new FlxSprite(0, FlxG.height * 0.9).loadGraphic(AssetPaths.healthBar__png); + healthBarBG = new FlxSprite(0, FlxG.height * 0.9).loadGraphic('assets/images/healthBar.png'); healthBarBG.screenCenter(X); healthBarBG.scrollFactor.set(); add(healthBarBG); @@ -307,31 +679,20 @@ class PlayState extends MusicBeatState scoreTxt.scrollFactor.set(); add(scoreTxt); - healthHeads = new FlxSprite(); - var headTex = FlxAtlasFrames.fromSparrow(AssetPaths.healthHeads__png, AssetPaths.healthHeads__xml); - healthHeads.frames = headTex; - healthHeads.animation.add('healthy', [0]); - healthHeads.animation.add('unhealthy', [1]); - healthHeads.y = healthBar.y - (healthHeads.height / 2); - healthHeads.scrollFactor.set(); - healthHeads.antialiasing = true; - add(healthHeads); + iconP1 = new HealthIcon(SONG.player1, true); + iconP1.y = healthBar.y - (iconP1.height / 2); + add(iconP1); - // healthBar.visible = healthHeads.visible = healthBarBG.visible = false; - if (isStoryMode) - { - // TEMP for now, later get rid of startCountdown() - // add(doof); - startCountdown(); - } - else - startCountdown(); + iconP2 = new HealthIcon(SONG.player2, false); + iconP2.y = healthBar.y - (iconP2.height / 2); + add(iconP2); strumLineNotes.cameras = [camHUD]; notes.cameras = [camHUD]; healthBar.cameras = [camHUD]; healthBarBG.cameras = [camHUD]; - healthHeads.cameras = [camHUD]; + iconP1.cameras = [camHUD]; + iconP2.cameras = [camHUD]; scoreTxt.cameras = [camHUD]; doof.cameras = [camHUD]; @@ -340,18 +701,153 @@ class PlayState extends MusicBeatState // UI_camera.zoom = 1; // cameras = [FlxG.cameras.list[1]]; + startingSong = true; - #if lime - trace("IT'S LIME"); - #end + if (isStoryMode) + { + switch (curSong.toLowerCase()) + { + case "winter-horrorland": + var blackScreen:FlxSprite = new FlxSprite(0, 0).makeGraphic(Std.int(FlxG.width * 2), Std.int(FlxG.height * 2), FlxColor.BLACK); + add(blackScreen); + blackScreen.scrollFactor.set(); + camHUD.visible = false; + + new FlxTimer().start(0.1, function(tmr:FlxTimer) + { + remove(blackScreen); + FlxG.sound.play('assets/sounds/Lights_Turn_On' + TitleState.soundExt); + camFollow.y = -2050; + camFollow.x += 200; + FlxG.camera.focusOn(camFollow.getPosition()); + FlxG.camera.zoom = 1.5; + + new FlxTimer().start(0.8, function(tmr:FlxTimer) + { + camHUD.visible = true; + remove(blackScreen); + FlxTween.tween(FlxG.camera, {zoom: defaultCamZoom}, 2.5, { + ease: FlxEase.quadInOut, + onComplete: function(twn:FlxTween) + { + startCountdown(); + } + }); + }); + }); + case 'senpai': + schoolIntro(doof); + case 'roses': + FlxG.sound.play('assets/sounds/ANGRY' + TitleState.soundExt); + schoolIntro(doof); + case 'thorns': + schoolIntro(doof); + default: + startCountdown(); + } + } + else + { + switch (curSong.toLowerCase()) + { + default: + startCountdown(); + } + } super.create(); } + function schoolIntro(?dialogueBox:DialogueBox):Void + { + var black:FlxSprite = new FlxSprite(-100, -100).makeGraphic(FlxG.width * 2, FlxG.height * 2, FlxColor.BLACK); + black.scrollFactor.set(); + add(black); + + var red:FlxSprite = new FlxSprite(-100, -100).makeGraphic(FlxG.width * 2, FlxG.height * 2, 0xFFff1b31); + red.scrollFactor.set(); + + var senpaiEvil:FlxSprite = new FlxSprite(); + senpaiEvil.frames = FlxAtlasFrames.fromSparrow('assets/images/weeb/senpaiCrazy.png', 'assets/images/weeb/senpaiCrazy.xml'); + senpaiEvil.animation.addByPrefix('idle', 'Senpai Pre Explosion', 24, false); + senpaiEvil.setGraphicSize(Std.int(senpaiEvil.width * 6)); + senpaiEvil.updateHitbox(); + senpaiEvil.screenCenter(); + + if (SONG.song.toLowerCase() == 'roses' || SONG.song.toLowerCase() == 'thorns') + { + remove(black); + + if (SONG.song.toLowerCase() == 'thorns') + { + add(red); + } + } + + new FlxTimer().start(0.3, function(tmr:FlxTimer) + { + black.alpha -= 0.15; + + if (black.alpha > 0) + { + tmr.reset(0.3); + } + else + { + if (dialogueBox != null) + { + inCutscene = true; + + if (SONG.song.toLowerCase() == 'thorns') + { + add(senpaiEvil); + senpaiEvil.alpha = 0; + new FlxTimer().start(0.3, function(swagTimer:FlxTimer) + { + senpaiEvil.alpha += 0.15; + if (senpaiEvil.alpha < 1) + { + swagTimer.reset(); + } + else + { + senpaiEvil.animation.play('idle'); + FlxG.sound.play('assets/sounds/Senpai_Dies' + TitleState.soundExt, 1, false, null, true, function() + { + remove(senpaiEvil); + remove(red); + FlxG.camera.fade(FlxColor.WHITE, 0.01, true, function() + { + add(dialogueBox); + }, true); + }); + new FlxTimer().start(3.2, function(deadTime:FlxTimer) + { + FlxG.camera.fade(FlxColor.WHITE, 1.6, false); + }); + } + }); + } + else + { + add(dialogueBox); + } + } + else + startCountdown(); + + remove(black); + } + }); + } + var startTimer:FlxTimer; + var perfectMode:Bool = false; function startCountdown():Void { + inCutscene = false; + generateStaticArrows(0); generateStaticArrows(1); @@ -368,13 +864,44 @@ class PlayState extends MusicBeatState gf.dance(); boyfriend.playAnim('idle'); + var introAssets:Map> = new Map>(); + introAssets.set('default', ['ready.png', "set.png", "go.png"]); + introAssets.set('school', [ + 'weeb/pixelUI/ready-pixel.png', + 'weeb/pixelUI/set-pixel.png', + 'weeb/pixelUI/date-pixel.png' + ]); + introAssets.set('schoolEvil', [ + 'weeb/pixelUI/ready-pixel.png', + 'weeb/pixelUI/set-pixel.png', + 'weeb/pixelUI/date-pixel.png' + ]); + + var introAlts:Array = introAssets.get('default'); + var altSuffix:String = ""; + + for (value in introAssets.keys()) + { + if (value == curStage) + { + introAlts = introAssets.get(value); + altSuffix = '-pixel'; + } + } + switch (swagCounter) + { case 0: - FlxG.sound.play('assets/sounds/intro3' + TitleState.soundExt, 0.6); + FlxG.sound.play('assets/sounds/intro3' + altSuffix + TitleState.soundExt, 0.6); case 1: - var ready:FlxSprite = new FlxSprite().loadGraphic('assets/images/ready.png'); + var ready:FlxSprite = new FlxSprite().loadGraphic('assets/images/' + introAlts[0]); ready.scrollFactor.set(); + ready.updateHitbox(); + + if (curStage.startsWith('school')) + ready.setGraphicSize(Std.int(ready.width * daPixelZoom)); + ready.screenCenter(); add(ready); FlxTween.tween(ready, {y: ready.y += 100, alpha: 0}, Conductor.crochet / 1000, { @@ -384,10 +911,14 @@ class PlayState extends MusicBeatState ready.destroy(); } }); - FlxG.sound.play('assets/sounds/intro2' + TitleState.soundExt, 0.6); + FlxG.sound.play('assets/sounds/intro2' + altSuffix + TitleState.soundExt, 0.6); case 2: - var set:FlxSprite = new FlxSprite().loadGraphic('assets/images/set.png'); + var set:FlxSprite = new FlxSprite().loadGraphic('assets/images/' + introAlts[1]); set.scrollFactor.set(); + + if (curStage.startsWith('school')) + set.setGraphicSize(Std.int(set.width * daPixelZoom)); + set.screenCenter(); add(set); FlxTween.tween(set, {y: set.y += 100, alpha: 0}, Conductor.crochet / 1000, { @@ -397,10 +928,16 @@ class PlayState extends MusicBeatState set.destroy(); } }); - FlxG.sound.play('assets/sounds/intro1' + TitleState.soundExt, 0.6); + FlxG.sound.play('assets/sounds/intro1' + altSuffix + TitleState.soundExt, 0.6); case 3: - var go:FlxSprite = new FlxSprite().loadGraphic('assets/images/go.png'); + var go:FlxSprite = new FlxSprite().loadGraphic('assets/images/' + introAlts[2]); go.scrollFactor.set(); + + if (curStage.startsWith('school')) + go.setGraphicSize(Std.int(go.width * daPixelZoom)); + + go.updateHitbox(); + go.screenCenter(); add(go); FlxTween.tween(go, {y: go.y += 100, alpha: 0}, Conductor.crochet / 1000, { @@ -410,7 +947,7 @@ class PlayState extends MusicBeatState go.destroy(); } }); - FlxG.sound.play('assets/sounds/introGo' + TitleState.soundExt, 0.6); + FlxG.sound.play('assets/sounds/introGo' + altSuffix + TitleState.soundExt, 0.6); case 4: } @@ -542,19 +1079,120 @@ class PlayState extends MusicBeatState { for (i in 0...4) { - FlxG.log.add(i); + // FlxG.log.add(i); var babyArrow:FlxSprite = new FlxSprite(0, strumLine.y); - var arrTex = FlxAtlasFrames.fromSparrow(AssetPaths.NOTE_assets__png, AssetPaths.NOTE_assets__xml); - babyArrow.frames = arrTex; - babyArrow.animation.addByPrefix('green', 'arrowUP'); - babyArrow.animation.addByPrefix('blue', 'arrowDOWN'); - babyArrow.animation.addByPrefix('purple', 'arrowLEFT'); - babyArrow.animation.addByPrefix('red', 'arrowRIGHT'); - babyArrow.scrollFactor.set(); - babyArrow.setGraphicSize(Std.int(babyArrow.width * 0.7)); + switch (curStage) + { + case 'school': + babyArrow.loadGraphic('assets/images/weeb/pixelUI/arrows-pixels.png', true, 17, 17); + babyArrow.animation.add('green', [6]); + babyArrow.animation.add('red', [7]); + babyArrow.animation.add('blue', [5]); + babyArrow.animation.add('purplel', [4]); + + babyArrow.setGraphicSize(Std.int(babyArrow.width * daPixelZoom)); + babyArrow.updateHitbox(); + babyArrow.antialiasing = false; + + switch (Math.abs(i)) + { + case 2: + babyArrow.x += Note.swagWidth * 2; + babyArrow.animation.add('static', [2]); + babyArrow.animation.add('pressed', [6, 10], 12, false); + babyArrow.animation.add('confirm', [14, 18], 12, false); + case 3: + babyArrow.x += Note.swagWidth * 3; + babyArrow.animation.add('static', [3]); + babyArrow.animation.add('pressed', [7, 11], 12, false); + babyArrow.animation.add('confirm', [15, 19], 24, false); + case 1: + babyArrow.x += Note.swagWidth * 1; + babyArrow.animation.add('static', [1]); + babyArrow.animation.add('pressed', [5, 9], 12, false); + babyArrow.animation.add('confirm', [13, 17], 24, false); + case 0: + babyArrow.x += Note.swagWidth * 0; + babyArrow.animation.add('static', [0]); + babyArrow.animation.add('pressed', [4, 8], 12, false); + babyArrow.animation.add('confirm', [12, 16], 24, false); + } + + case 'schoolEvil': + // ALL THIS IS COPY PASTED CUZ IM LAZY + + babyArrow.loadGraphic('assets/images/weeb/pixelUI/arrows-pixels.png', true, 17, 17); + babyArrow.animation.add('green', [6]); + babyArrow.animation.add('red', [7]); + babyArrow.animation.add('blue', [5]); + babyArrow.animation.add('purplel', [4]); + + babyArrow.setGraphicSize(Std.int(babyArrow.width * daPixelZoom)); + babyArrow.updateHitbox(); + babyArrow.antialiasing = false; + + switch (Math.abs(i)) + { + case 2: + babyArrow.x += Note.swagWidth * 2; + babyArrow.animation.add('static', [2]); + babyArrow.animation.add('pressed', [6, 10], 12, false); + babyArrow.animation.add('confirm', [14, 18], 12, false); + case 3: + babyArrow.x += Note.swagWidth * 3; + babyArrow.animation.add('static', [3]); + babyArrow.animation.add('pressed', [7, 11], 12, false); + babyArrow.animation.add('confirm', [15, 19], 24, false); + case 1: + babyArrow.x += Note.swagWidth * 1; + babyArrow.animation.add('static', [1]); + babyArrow.animation.add('pressed', [5, 9], 12, false); + babyArrow.animation.add('confirm', [13, 17], 24, false); + case 0: + babyArrow.x += Note.swagWidth * 0; + babyArrow.animation.add('static', [0]); + babyArrow.animation.add('pressed', [4, 8], 12, false); + babyArrow.animation.add('confirm', [12, 16], 24, false); + } + + default: + babyArrow.frames = FlxAtlasFrames.fromSparrow('assets/images/NOTE_assets.png', 'assets/images/NOTE_assets.xml'); + babyArrow.animation.addByPrefix('green', 'arrowUP'); + babyArrow.animation.addByPrefix('blue', 'arrowDOWN'); + babyArrow.animation.addByPrefix('purple', 'arrowLEFT'); + babyArrow.animation.addByPrefix('red', 'arrowRIGHT'); + + babyArrow.antialiasing = true; + babyArrow.setGraphicSize(Std.int(babyArrow.width * 0.7)); + + switch (Math.abs(i)) + { + case 2: + babyArrow.x += Note.swagWidth * 2; + babyArrow.animation.addByPrefix('static', 'arrowUP'); + 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('pressed', 'right press', 24, false); + babyArrow.animation.addByPrefix('confirm', 'right confirm', 24, false); + case 1: + babyArrow.x += Note.swagWidth * 1; + babyArrow.animation.addByPrefix('static', 'arrowDOWN'); + babyArrow.animation.addByPrefix('pressed', 'down press', 24, false); + babyArrow.animation.addByPrefix('confirm', 'down confirm', 24, false); + case 0: + babyArrow.x += Note.swagWidth * 0; + babyArrow.animation.addByPrefix('static', 'arrowLEFT'); + babyArrow.animation.addByPrefix('pressed', 'left press', 24, false); + babyArrow.animation.addByPrefix('confirm', 'left confirm', 24, false); + } + } + babyArrow.updateHitbox(); - babyArrow.antialiasing = true; + babyArrow.scrollFactor.set(); babyArrow.y -= 10; babyArrow.alpha = 0; @@ -567,30 +1205,6 @@ class PlayState extends MusicBeatState playerStrums.add(babyArrow); } - switch (Math.abs(i)) - { - case 2: - babyArrow.x += Note.swagWidth * 2; - babyArrow.animation.addByPrefix('static', 'arrowUP'); - 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('pressed', 'right press', 24, false); - babyArrow.animation.addByPrefix('confirm', 'right confirm', 24, false); - case 1: - babyArrow.x += Note.swagWidth * 1; - babyArrow.animation.addByPrefix('static', 'arrowDOWN'); - babyArrow.animation.addByPrefix('pressed', 'down press', 24, false); - babyArrow.animation.addByPrefix('confirm', 'down confirm', 24, false); - case 0: - babyArrow.x += Note.swagWidth * 0; - babyArrow.animation.addByPrefix('static', 'arrowLEFT'); - babyArrow.animation.addByPrefix('pressed', 'left press', 24, false); - babyArrow.animation.addByPrefix('confirm', 'left confirm', 24, false); - } - babyArrow.animation.play('static'); babyArrow.x += 50; babyArrow.x += ((FlxG.width / 2) * player); @@ -654,6 +1268,18 @@ class PlayState extends MusicBeatState override public function update(elapsed:Float) { + #if !debug + perfectMode = false; + #end + + if (FlxG.keys.justPressed.NINE) + { + if (iconP1.animation.curAnim.name == 'bf-old') + iconP1.animation.play(SONG.player1); + else + iconP1.animation.play('bf-old'); + } + switch (curStage) { case 'philly': @@ -667,7 +1293,6 @@ class PlayState extends MusicBeatState trainFrameTiming = 0; } } - // phillyCityLights.members[curLight].alpha -= (Conductor.crochet / 1000) * FlxG.elapsed; } @@ -692,17 +1317,29 @@ class PlayState extends MusicBeatState // FlxG.watch.addQuick('VOL', vocals.amplitudeLeft); // FlxG.watch.addQuick('VOLRight', vocals.amplitudeRight); - healthHeads.setGraphicSize(Std.int(FlxMath.lerp(150, healthHeads.width, 0.50))); - healthHeads.updateHitbox(); - healthHeads.x = healthBar.x + (healthBar.width * (FlxMath.remapToRange(healthBar.percent, 0, 100, 100, 0) * 0.01)) - (healthHeads.width / 2); + iconP1.setGraphicSize(Std.int(FlxMath.lerp(150, iconP1.width, 0.50))); + iconP2.setGraphicSize(Std.int(FlxMath.lerp(150, iconP2.width, 0.50))); + + iconP1.updateHitbox(); + iconP2.updateHitbox(); + + var iconOffset:Int = 26; + + iconP1.x = healthBar.x + (healthBar.width * (FlxMath.remapToRange(healthBar.percent, 0, 100, 100, 0) * 0.01) - iconOffset); + iconP2.x = healthBar.x + (healthBar.width * (FlxMath.remapToRange(healthBar.percent, 0, 100, 100, 0) * 0.01)) - (iconP2.width - iconOffset); if (health > 2) health = 2; if (healthBar.percent < 20) - healthHeads.animation.play('unhealthy'); + iconP1.animation.curAnim.curFrame = 1; else - healthHeads.animation.play('healthy'); + iconP1.animation.curAnim.curFrame = 0; + + if (healthBar.percent > 80) + iconP2.animation.curAnim.curFrame = 1; + else + iconP2.animation.curAnim.curFrame = 0; /* if (FlxG.keys.justPressed.NINE) FlxG.switchState(new Charting()); */ @@ -755,7 +1392,21 @@ class PlayState extends MusicBeatState { camFollow.setPosition(dad.getMidpoint().x + 150, dad.getMidpoint().y - 100); // camFollow.setPosition(lucky.getMidpoint().x - 120, lucky.getMidpoint().y + 210); - vocals.volume = 1; + + switch (dad.curCharacter) + { + case 'mom': + camFollow.y = dad.getMidpoint().y; + case 'senpai': + camFollow.y = dad.getMidpoint().y - 430; + camFollow.x = dad.getMidpoint().x - 100; + case 'senpai-angry': + camFollow.y = dad.getMidpoint().y - 430; + camFollow.x = dad.getMidpoint().x - 100; + } + + if (dad.curCharacter == 'mom') + vocals.volume = 1; if (SONG.song.toLowerCase() == 'tutorial') { @@ -767,6 +1418,20 @@ class PlayState extends MusicBeatState { camFollow.setPosition(boyfriend.getMidpoint().x - 100, boyfriend.getMidpoint().y - 100); + switch (curStage) + { + case 'limo': + camFollow.x = boyfriend.getMidpoint().x - 300; + case 'mall': + camFollow.y = boyfriend.getMidpoint().y - 200; + case 'school': + camFollow.x = boyfriend.getMidpoint().x - 200; + camFollow.y = boyfriend.getMidpoint().y - 200; + case 'schoolEvil': + camFollow.x = boyfriend.getMidpoint().x - 200; + camFollow.y = boyfriend.getMidpoint().y - 200; + } + if (SONG.song.toLowerCase() == 'tutorial') { FlxTween.tween(FlxG.camera, {zoom: 1}, (Conductor.stepCrochet * 4 / 1000), {ease: FlxEase.elasticInOut}); @@ -776,7 +1441,7 @@ class PlayState extends MusicBeatState if (camZooming) { - FlxG.camera.zoom = FlxMath.lerp(1.05, FlxG.camera.zoom, 0.95); + FlxG.camera.zoom = FlxMath.lerp(defaultCamZoom, FlxG.camera.zoom, 0.95); camHUD.zoom = FlxMath.lerp(1, camHUD.zoom, 0.95); } @@ -797,7 +1462,6 @@ class PlayState extends MusicBeatState gfSpeed = 1; case 163: // FlxG.sound.music.stop(); - // curLevel = 'Bopeebo'; // FlxG.switchState(new TitleState()); } } @@ -809,7 +1473,6 @@ class PlayState extends MusicBeatState case 128, 129, 130: vocals.volume = 0; // FlxG.sound.music.stop(); - // curLevel = 'Fresh'; // FlxG.switchState(new PlayState()); } } @@ -877,16 +1540,26 @@ class PlayState extends MusicBeatState if (SONG.song != 'Tutorial') camZooming = true; + var altAnim:String = ""; + + if (SONG.notes[Math.floor(curStep / 16)] != null) + { + if (SONG.notes[Math.floor(curStep / 16)].altAnim) + altAnim = '-alt'; + } + + trace("DA ALT THO?: " + SONG.notes[Math.floor(curStep / 16)].altAnim); + switch (Math.abs(daNote.noteData)) { case 2: - dad.playAnim('singUP', true); + dad.playAnim('singUP' + altAnim, true); case 3: - dad.playAnim('singRIGHT', true); + dad.playAnim('singRIGHT' + altAnim, true); case 1: - dad.playAnim('singDOWN', true); + dad.playAnim('singDOWN' + altAnim, true); case 0: - dad.playAnim('singLEFT', true); + dad.playAnim('singLEFT' + altAnim, true); } dad.holdTimer = 0; @@ -899,7 +1572,7 @@ class PlayState extends MusicBeatState daNote.destroy(); } - daNote.y = (strumLine.y - (Conductor.songPosition - daNote.strumTime) * (0.45 * PlayState.SONG.speed)); + daNote.y = (strumLine.y - (Conductor.songPosition - daNote.strumTime) * (0.45 * FlxMath.roundDecimal(PlayState.SONG.speed, 2))); // WIP interpolation shit? Need to fix the pause issue // daNote.y = (strumLine.y - (songTime - daNote.strumTime) * (0.45 * PlayState.SONG.speed)); @@ -908,7 +1581,7 @@ class PlayState extends MusicBeatState { if (daNote.tooLate || !daNote.wasGoodHit) { - health -= 0.045; + health -= 0.0475; vocals.volume = 0; } @@ -922,13 +1595,20 @@ class PlayState extends MusicBeatState }); } - keyShit(); + if (!inCutscene) + keyShit(); + + #if debug + if (FlxG.keys.justPressed.ONE) + endSong(); + #end } function endSong():Void { canPause = false; - + FlxG.sound.music.volume = 0; + vocals.volume = 0; if (SONG.validScore) { #if !switch @@ -973,12 +1653,36 @@ class PlayState extends MusicBeatState trace('LOADING NEXT SONG'); trace(PlayState.storyPlaylist[0].toLowerCase() + difficulty); + if (SONG.song.toLowerCase() == 'eggnog') + { + var blackShit:FlxSprite = new FlxSprite(-FlxG.width * FlxG.camera.zoom, + -FlxG.height * FlxG.camera.zoom).makeGraphic(FlxG.width * 3, FlxG.height * 3, FlxColor.BLACK); + blackShit.scrollFactor.set(); + add(blackShit); + camHUD.visible = false; + + FlxG.sound.play('assets/sounds/Lights_Shut_off' + TitleState.soundExt); + } + + if (SONG.song.toLowerCase() == 'senpai') + { + transIn = null; + transOut = null; + prevCamFollow = camFollow; + } + PlayState.SONG = Song.loadFromJson(PlayState.storyPlaylist[0].toLowerCase() + difficulty, PlayState.storyPlaylist[0]); + FlxG.sound.music.stop(); + FlxG.switchState(new PlayState()); + + transIn = FlxTransitionableState.defaultTransIn; + transOut = FlxTransitionableState.defaultTransOut; } } else { + trace('WENT BACK TO FREEPLAY??'); FlxG.switchState(new FreeplayState()); } } @@ -1028,29 +1732,49 @@ class PlayState extends MusicBeatState else if (combo > 4) daRating = 'bad'; */ - rating.loadGraphic('assets/images/' + daRating + ".png"); + + var pixelShitPart1:String = ""; + var pixelShitPart2:String = ''; + + if (curStage.startsWith('school')) + { + pixelShitPart1 = 'weeb/pixelUI/'; + pixelShitPart2 = '-pixel'; + } + + rating.loadGraphic('assets/images/' + pixelShitPart1 + daRating + pixelShitPart2 + ".png"); rating.screenCenter(); rating.x = coolText.x - 40; rating.y -= 60; rating.acceleration.y = 550; rating.velocity.y -= FlxG.random.int(140, 175); - rating.setGraphicSize(Std.int(rating.width * 0.7)); - rating.updateHitbox(); - rating.antialiasing = true; rating.velocity.x -= FlxG.random.int(0, 10); - var comboSpr:FlxSprite = new FlxSprite().loadGraphic(AssetPaths.combo__png); + var comboSpr:FlxSprite = new FlxSprite().loadGraphic('assets/images/' + pixelShitPart1 + 'combo' + pixelShitPart2 + '.png'); comboSpr.screenCenter(); comboSpr.x = coolText.x; comboSpr.acceleration.y = 600; - comboSpr.antialiasing = true; comboSpr.velocity.y -= 150; - comboSpr.setGraphicSize(Std.int(comboSpr.width * 0.7)); - comboSpr.updateHitbox(); + comboSpr.velocity.x += FlxG.random.int(1, 10); - // add(comboSpr); add(rating); + if (!curStage.startsWith('school')) + { + rating.setGraphicSize(Std.int(rating.width * 0.7)); + rating.antialiasing = true; + comboSpr.setGraphicSize(Std.int(comboSpr.width * 0.7)); + comboSpr.antialiasing = true; + } + else + { + rating.setGraphicSize(Std.int(rating.width * daPixelZoom * 0.7)); + comboSpr.setGraphicSize(Std.int(comboSpr.width * daPixelZoom * 0.7)); + } + + comboSpr.updateHitbox(); + rating.updateHitbox(); + var seperatedScore:Array = []; seperatedScore.push(Math.floor(combo / 100)); @@ -1060,13 +1784,22 @@ class PlayState extends MusicBeatState var daLoop:Int = 0; for (i in seperatedScore) { - var numScore:FlxSprite = new FlxSprite().loadGraphic('assets/images/num' + Std.int(i) + '.png'); + var numScore:FlxSprite = new FlxSprite().loadGraphic('assets/images/' + pixelShitPart1 + 'num' + Std.int(i) + pixelShitPart2 + '.png'); numScore.screenCenter(); numScore.x = coolText.x + (43 * daLoop) - 90; numScore.y += 80; - numScore.antialiasing = true; - numScore.setGraphicSize(Std.int(numScore.width * 0.5)); + + if (!curStage.startsWith('school')) + { + numScore.antialiasing = true; + numScore.setGraphicSize(Std.int(numScore.width * 0.5)); + } + else + { + numScore.setGraphicSize(Std.int(numScore.width * daPixelZoom)); + } numScore.updateHitbox(); + numScore.acceleration.y = FlxG.random.int(200, 300); numScore.velocity.y -= FlxG.random.int(140, 160); numScore.velocity.x = FlxG.random.float(-5, 5); @@ -1128,6 +1861,8 @@ class PlayState extends MusicBeatState var downR = controls.DOWN_R; var leftR = controls.LEFT_R; + var controlArray:Array = [leftP, downP, upP, rightP]; + // FlxG.watch.addQuick('asdfa', upP); if ((upP || rightP || downP || leftP) && !boyfriend.stunned && generatedMusic) { @@ -1135,18 +1870,71 @@ class PlayState extends MusicBeatState var possibleNotes:Array = []; + var ignoreList:Array = []; + notes.forEachAlive(function(daNote:Note) { if (daNote.canBeHit && daNote.mustPress && !daNote.tooLate) { + // the sorting probably doesn't need to be in here? who cares lol possibleNotes.push(daNote); + possibleNotes.sort((a, b) -> Std.int(a.strumTime - b.strumTime)); + + ignoreList.push(daNote.noteData); } }); if (possibleNotes.length > 0) { - for (daNote in possibleNotes) + var daNote = possibleNotes[0]; + + if (perfectMode) + noteCheck(true, daNote); + + // Jump notes + if (possibleNotes.length >= 2) { + if (possibleNotes[0].strumTime == possibleNotes[1].strumTime) + { + for (coolNote in possibleNotes) + { + if (controlArray[coolNote.noteData]) + goodNoteHit(coolNote); + else + { + var inIgnoreList:Bool = false; + for (shit in 0...ignoreList.length) + { + if (controlArray[ignoreList[shit]]) + inIgnoreList = true; + } + if (!inIgnoreList) + badNoteCheck(); + } + } + } + else if (possibleNotes[0].noteData == possibleNotes[1].noteData) + { + noteCheck(controlArray[daNote.noteData], daNote); + } + else + { + for (coolNote in possibleNotes) + { + noteCheck(controlArray[coolNote.noteData], coolNote); + } + } + } + else // regular notes? + { + noteCheck(controlArray[daNote.noteData], daNote); + } + /* + if (controlArray[daNote.noteData]) + goodNoteHit(daNote); + */ + // trace(daNote.noteData); + /* switch (daNote.noteData) { case 2: // NOTES YOU JUST PRESSED @@ -1162,13 +1950,12 @@ class PlayState extends MusicBeatState if (upP || rightP || downP || leftP) noteCheck(leftP, daNote); } - - if (daNote.wasGoodHit) - { - daNote.kill(); - notes.remove(daNote, true); - daNote.destroy(); - } + */ + if (daNote.wasGoodHit) + { + daNote.kill(); + notes.remove(daNote, true); + daNote.destroy(); } } else @@ -1187,16 +1974,16 @@ class PlayState extends MusicBeatState { // NOTES YOU ARE HOLDING case 2: - if (up && daNote.prevNote.wasGoodHit) + if (up) goodNoteHit(daNote); case 3: - if (right && daNote.prevNote.wasGoodHit) + if (right) goodNoteHit(daNote); case 1: - if (down && daNote.prevNote.wasGoodHit) + if (down) goodNoteHit(daNote); case 0: - if (left && daNote.prevNote.wasGoodHit) + if (left) goodNoteHit(daNote); } } @@ -1237,7 +2024,7 @@ class PlayState extends MusicBeatState spr.animation.play('static'); } - if (spr.animation.curAnim.name == 'confirm') + if (spr.animation.curAnim.name == 'confirm' && !curStage.startsWith('school')) { spr.centerOffsets(); spr.offset.x -= 13; @@ -1252,7 +2039,7 @@ class PlayState extends MusicBeatState { if (!boyfriend.stunned) { - health -= 0.035; + health -= 0.04; if (combo > 5) { gf.playAnim('sad'); @@ -1296,30 +2083,6 @@ class PlayState extends MusicBeatState var downP = controls.DOWN_P; var leftP = controls.LEFT_P; - var gamepad = FlxG.gamepads.lastActive; - if (gamepad != null) - { - if (gamepad.anyJustPressed(["DPAD_LEFT", "LEFT_STICK_DIGITAL_LEFT", X])) - { - leftP = true; - } - - if (gamepad.anyJustPressed(["DPAD_RIGHT", "LEFT_STICK_DIGITAL_RIGHT", B])) - { - rightP = true; - } - - if (gamepad.anyJustPressed(['DPAD_UP', "LEFT_STICK_DIGITAL_UP", Y])) - { - upP = true; - } - - if (gamepad.anyJustPressed(["DPAD_DOWN", "LEFT_STICK_DIGITAL_DOWN", A])) - { - downP = true; - } - } - if (leftP) noteMiss(0); if (upP) @@ -1335,7 +2098,9 @@ class PlayState extends MusicBeatState if (keyP) goodNoteHit(note); else + { badNoteCheck(); + } } function goodNoteHit(note:Note):Void @@ -1356,13 +2121,13 @@ class PlayState extends MusicBeatState switch (note.noteData) { case 2: - boyfriend.playAnim('singUP'); + boyfriend.playAnim('singUP', true); case 3: - boyfriend.playAnim('singRIGHT'); + boyfriend.playAnim('singRIGHT', true); case 1: - boyfriend.playAnim('singDOWN'); + boyfriend.playAnim('singDOWN', true); case 0: - boyfriend.playAnim('singLEFT'); + boyfriend.playAnim('singLEFT', true); } playerStrums.forEach(function(spr:FlxSprite) @@ -1382,6 +2147,28 @@ class PlayState extends MusicBeatState } } + var fastCarCanDrive:Bool = true; + + function resetFastCar():Void + { + fastCar.x = -12600; + fastCar.y = FlxG.random.int(140, 250); + fastCar.velocity.x = 0; + fastCarCanDrive = true; + } + + function fastCarDrive() + { + FlxG.sound.play('assets/sounds/carPass' + FlxG.random.int(0, 1) + TitleState.soundExt, 0.7); + + fastCar.velocity.x = (FlxG.random.int(170, 220) / FlxG.elapsed) * 3; + fastCarCanDrive = false; + new FlxTimer().start(2, function(tmr:FlxTimer) + { + resetFastCar(); + }); + } + var trainMoving:Bool = false; var trainFrameTiming:Float = 0; @@ -1471,6 +2258,7 @@ class PlayState extends MusicBeatState override function beatHit() { + wiggleShit.update(Conductor.crochet); super.beatHit(); if (generatedMusic) @@ -1494,14 +2282,24 @@ class PlayState extends MusicBeatState } // FlxG.log.add('change bpm' + SONG.notes[Std.int(curStep / 16)].changeBPM); + // HARDCODING FOR MILF ZOOMS! + if (curSong.toLowerCase() == 'milf' && curBeat >= 168 && curBeat <= 200 && camZooming && FlxG.camera.zoom < 1.35) + { + FlxG.camera.zoom += 0.015; + camHUD.zoom += 0.03; + } + if (camZooming && FlxG.camera.zoom < 1.35 && totalBeats % 4 == 0) { FlxG.camera.zoom += 0.015; camHUD.zoom += 0.03; } - healthHeads.setGraphicSize(Std.int(healthHeads.width + 30)); - healthHeads.updateHitbox(); + iconP1.setGraphicSize(Std.int(iconP1.width + 30)); + iconP2.setGraphicSize(Std.int(iconP2.width + 30)); + + iconP1.updateHitbox(); + iconP2.updateHitbox(); if (totalBeats % gfSpeed == 0) { @@ -1509,7 +2307,9 @@ class PlayState extends MusicBeatState } if (!boyfriend.animation.curAnim.name.startsWith("sing")) + { boyfriend.playAnim('idle'); + } if (totalBeats % 8 == 7 && curSong == 'Bopeebo') { @@ -1523,6 +2323,22 @@ class PlayState extends MusicBeatState switch (curStage) { + case 'school': + bgGirls.dance(); + + case 'mall': + upperBoppers.animation.play('bop', true); + bottomBoppers.animation.play('bop', true); + santa.animation.play('idle', true); + + case 'limo': + grpLimoDancers.forEach(function(dancer:BackgroundDancer) + { + dancer.dance(); + }); + + if (FlxG.random.bool(10) && fastCarCanDrive) + fastCarDrive(); case "philly": if (!trainMoving) trainCooldown += 1; diff --git a/source/Section.hx b/source/Section.hx index 19770b6ea..c859f6f31 100644 --- a/source/Section.hx +++ b/source/Section.hx @@ -8,6 +8,7 @@ typedef SwagSection = var mustHitSection:Bool; var bpm:Int; var changeBPM:Bool; + var altAnim:Bool; } class Section diff --git a/source/Song.hx b/source/Song.hx index 772652b94..55827e79b 100644 --- a/source/Song.hx +++ b/source/Song.hx @@ -58,10 +58,6 @@ class Song // LOL GOING THROUGH THE BULLSHIT TO CLEAN IDK WHATS STRANGE } - var swagShit:SwagSong = cast Json.parse(rawJson).song; - swagShit.validScore = true; - trace(swagShit.notes[0]); - // FIX THE CASTING ON WINDOWS/NATIVE // Windows??? // trace(songData); @@ -80,6 +76,13 @@ class Song daBpm = songData.bpm; daSectionLengths = songData.sectionLengths; */ + return parseJSONshit(rawJson); + } + + public static function parseJSONshit(rawJson:String):SwagSong + { + var swagShit:SwagSong = cast Json.parse(rawJson).song; + swagShit.validScore = true; return swagShit; } } diff --git a/source/StoryMenuState.hx b/source/StoryMenuState.hx index b881fa9cc..d5787c526 100644 --- a/source/StoryMenuState.hx +++ b/source/StoryMenuState.hx @@ -8,6 +8,7 @@ import flixel.group.FlxGroup; import flixel.math.FlxMath; import flixel.text.FlxText; import flixel.tweens.FlxTween; +import flixel.util.FlxColor; import flixel.util.FlxTimer; import lime.net.curl.CURLCode; @@ -21,18 +22,37 @@ class StoryMenuState extends MusicBeatState ['Tutorial'], ['Bopeebo', 'Fresh', 'Dadbattle'], ['Spookeez', 'South'], - ['Pico', 'Philly', "Blammed"] + ['Pico', 'Philly', "Blammed"], + ['Satin-Panties', "High", "Milf"], + ['Cocoa', 'Eggnog', 'Winter-Horrorland'], + ['Senpai', 'Roses', 'Thorns'] ]; var curDifficulty:Int = 1; - public static var weekUnlocked:Array = [true, true, false, false]; + public static var weekUnlocked:Array = [true, true, true, true, true, true, true]; var weekCharacters:Array = [ ['dad', 'bf', 'gf'], ['dad', 'bf', 'gf'], ['spooky', 'bf', 'gf'], - ['pico', 'bf', 'gf'] + ['pico', 'bf', 'gf'], + ['mom', 'bf', 'gf'], + ['parents-christmas', 'bf', 'gf'], + ['senpai', 'bf', 'gf'] ]; + + var weekNames:Array = [ + "", + "Daddy Dearest", + "Spooky Month", + "PICO", + "MOMMY MUST MURDER", + "RED SNOW", + "hating simulator ft. moawling" + ]; + + var txtWeekTitle:FlxText; + var curWeek:Int = 0; var txtTracklist:FlxText; @@ -60,18 +80,25 @@ class StoryMenuState extends MusicBeatState scoreText = new FlxText(10, 10, 0, "SCORE: 49324858", 36); scoreText.setFormat("VCR OSD Mono", 32); + txtWeekTitle = new FlxText(FlxG.width * 0.7, 10, 0, "", 32); + txtWeekTitle.setFormat("VCR OSD Mono", 32, FlxColor.WHITE, RIGHT); + txtWeekTitle.alpha = 0.7; + var rankText:FlxText = new FlxText(0, 10); rankText.text = 'RANK: GREAT'; rankText.setFormat("assets/fonts/vcr.ttf", 32); rankText.size = scoreText.size; rankText.screenCenter(X); - var ui_tex = FlxAtlasFrames.fromSparrow(AssetPaths.campaign_menu_UI_assets__png, AssetPaths.campaign_menu_UI_assets__xml); + var ui_tex = FlxAtlasFrames.fromSparrow('assets/images/campaign_menu_UI_assets.png', 'assets/images/campaign_menu_UI_assets.xml'); var yellowBG:FlxSprite = new FlxSprite(0, 56).makeGraphic(FlxG.width, 400, 0xFFF9CF51); grpWeekText = new FlxTypedGroup(); add(grpWeekText); + var blackBarThingie:FlxSprite = new FlxSprite().makeGraphic(FlxG.width, 56, FlxColor.BLACK); + add(blackBarThingie); + grpWeekCharacters = new FlxTypedGroup(); grpLocks = new FlxTypedGroup(); @@ -124,9 +151,10 @@ class StoryMenuState extends MusicBeatState weekCharacterThing.setGraphicSize(Std.int(weekCharacterThing.width * 0.5)); weekCharacterThing.updateHitbox(); case 'pico': - weekCharacterThing.y += 170; weekCharacterThing.flipX = true; - weekCharacterThing.x -= 40; + case 'parents-christmas': + weekCharacterThing.setGraphicSize(Std.int(weekCharacterThing.width * 0.9)); + weekCharacterThing.updateHitbox(); } grpWeekCharacters.add(weekCharacterThing); @@ -173,6 +201,7 @@ class StoryMenuState extends MusicBeatState add(txtTracklist); // add(rankText); add(scoreText); + add(txtWeekTitle); updateText(); @@ -187,6 +216,10 @@ class StoryMenuState extends MusicBeatState lerpScore = Math.floor(FlxMath.lerp(lerpScore, intendedScore, 0.5)); scoreText.text = "WEEK SCORE:" + lerpScore; + + txtWeekTitle.text = weekNames[curWeek].toUpperCase(); + txtWeekTitle.x = FlxG.width - (txtWeekTitle.width + 10); + // FlxG.watch.addQuick('font', scoreText.font); difficultySelectors.visible = weekUnlocked[curWeek]; @@ -360,6 +393,30 @@ class StoryMenuState extends MusicBeatState grpWeekCharacters.members[2].animation.play(weekCharacters[curWeek][2]); txtTracklist.text = "Tracks\n"; + switch (grpWeekCharacters.members[0].animation.curAnim.name) + { + case 'parents-christmas': + grpWeekCharacters.members[0].offset.set(200, 200); + grpWeekCharacters.members[0].setGraphicSize(Std.int(grpWeekCharacters.members[0].width * 0.99)); + + case 'senpai': + grpWeekCharacters.members[0].offset.set(130, 0); + grpWeekCharacters.members[0].setGraphicSize(Std.int(grpWeekCharacters.members[0].width * 1.4)); + + case 'mom': + grpWeekCharacters.members[0].offset.set(100, 200); + grpWeekCharacters.members[0].setGraphicSize(Std.int(grpWeekCharacters.members[0].width * 1)); + + case 'dad': + grpWeekCharacters.members[0].offset.set(120, 200); + grpWeekCharacters.members[0].setGraphicSize(Std.int(grpWeekCharacters.members[0].width * 1)); + + default: + grpWeekCharacters.members[0].offset.set(100, 100); + grpWeekCharacters.members[0].setGraphicSize(Std.int(grpWeekCharacters.members[0].width * 1)); + // grpWeekCharacters.members[0].updateHitbox(); + } + var stringThing:Array = weekData[curWeek]; for (i in stringThing) diff --git a/source/TitleState.hx b/source/TitleState.hx index 26bb4405b..53452e45c 100644 --- a/source/TitleState.hx +++ b/source/TitleState.hx @@ -20,7 +20,12 @@ import flixel.tweens.FlxEase; import flixel.tweens.FlxTween; import flixel.util.FlxColor; import flixel.util.FlxTimer; -import lime.utils.Assets; +import io.newgrounds.NG; +import lime.app.Application; +import openfl.Assets; +import polymod.Polymod; + +using StringTools; class TitleState extends MusicBeatState { @@ -39,6 +44,8 @@ class TitleState extends MusicBeatState override public function create():Void { + Polymod.init({modRoot: "mods", dirs: ['introMod']}); + #if (!web) TitleState.soundExt = '.ogg'; #end @@ -51,6 +58,8 @@ class TitleState extends MusicBeatState super.create(); + NGio.noLogin(APIStuff.API); + #if ng var ng:NGio = new NGio(APIStuff.API, APIStuff.EncKey); trace('NEWGROUNDS LOL'); @@ -62,7 +71,9 @@ class TitleState extends MusicBeatState if (FlxG.save.data.weekUnlocked != null) { - StoryMenuState.weekUnlocked = FlxG.save.data.weekUnlocked; + // FIX LATER!!! + // WEEK UNLOCK PROGRESSION!! + // StoryMenuState.weekUnlocked = FlxG.save.data.weekUnlocked; if (StoryMenuState.weekUnlocked.length < 4) StoryMenuState.weekUnlocked.insert(0, true); @@ -72,8 +83,10 @@ class TitleState extends MusicBeatState StoryMenuState.weekUnlocked[0] = true; } - #if SKIP_TO_PLAYSTATE - FlxG.switchState(new StoryMenuState()); + #if FREEPLAY + FlxG.switchState(new FreeplayState()); + #elseif CHARTING + FlxG.switchState(new ChartingState()); #else startIntro(); #end @@ -93,16 +106,17 @@ class TitleState extends MusicBeatState diamond.destroyOnNoUse = false; FlxTransitionableState.defaultTransIn = new TransitionData(FADE, FlxColor.BLACK, 1, new FlxPoint(0, -1), {asset: diamond, width: 32, height: 32}, - new FlxRect(0, 0, FlxG.width, FlxG.height)); + new FlxRect(-200, -200, FlxG.width * 1.4, FlxG.height * 1.4)); FlxTransitionableState.defaultTransOut = new TransitionData(FADE, FlxColor.BLACK, 0.7, new FlxPoint(0, 1), - {asset: diamond, width: 32, height: 32}, new FlxRect(0, 0, FlxG.width, FlxG.height)); - - FlxTransitionableState.defaultTransIn.tileData = {asset: diamond, width: 32, height: 32}; - FlxTransitionableState.defaultTransOut.tileData = {asset: diamond, width: 32, height: 32}; + {asset: diamond, width: 32, height: 32}, new FlxRect(-200, -200, FlxG.width * 1.4, FlxG.height * 1.4)); transIn = FlxTransitionableState.defaultTransIn; transOut = FlxTransitionableState.defaultTransOut; + // HAD TO MODIFY SOME BACKEND SHIT + // IF THIS PR IS HERE IF ITS ACCEPTED UR GOOD TO GO + // https://github.com/HaxeFlixel/flixel-addons/pull/348 + // var music:FlxSound = new FlxSound(); // music.loadStream('assets/music/freakyMenu' + TitleState.soundExt); // FlxG.sound.list.add(music); @@ -122,7 +136,7 @@ class TitleState extends MusicBeatState add(bg); logoBl = new FlxSprite(-150, -100); - logoBl.frames = FlxAtlasFrames.fromSparrow(AssetPaths.logoBumpin__png, AssetPaths.logoBumpin__xml); + logoBl.frames = FlxAtlasFrames.fromSparrow('assets/images/logoBumpin.png', 'assets/images/logoBumpin.xml'); logoBl.antialiasing = true; logoBl.animation.addByPrefix('bump', 'logo bumpin', 24); logoBl.animation.play('bump'); @@ -131,7 +145,7 @@ class TitleState extends MusicBeatState // logoBl.color = FlxColor.BLACK; gfDance = new FlxSprite(FlxG.width * 0.4, FlxG.height * 0.07); - gfDance.frames = FlxAtlasFrames.fromSparrow(AssetPaths.gfDanceTitle__png, AssetPaths.gfDanceTitle__xml); + gfDance.frames = FlxAtlasFrames.fromSparrow('assets/images/gfDanceTitle.png', 'assets/images/gfDanceTitle.xml'); gfDance.animation.addByIndices('danceLeft', 'gfDance', [30, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false); 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; @@ -139,7 +153,7 @@ class TitleState extends MusicBeatState add(logoBl); titleText = new FlxSprite(100, FlxG.height * 0.8); - titleText.frames = FlxAtlasFrames.fromSparrow(AssetPaths.titleEnter__png, AssetPaths.titleEnter__xml); + titleText.frames = FlxAtlasFrames.fromSparrow('assets/images/titleEnter.png', 'assets/images/titleEnter.xml'); titleText.animation.addByPrefix('idle', "Press Enter to Begin", 24); titleText.animation.addByPrefix('press', "ENTER PRESSED", 24); titleText.antialiasing = true; @@ -148,7 +162,7 @@ class TitleState extends MusicBeatState // titleText.screenCenter(X); add(titleText); - var logo:FlxSprite = new FlxSprite().loadGraphic(AssetPaths.logo__png); + var logo:FlxSprite = new FlxSprite().loadGraphic('assets/images/logo.png'); logo.screenCenter(); logo.antialiasing = true; // add(logo); @@ -170,7 +184,7 @@ class TitleState extends MusicBeatState credTextShit.visible = false; - ngSpr = new FlxSprite(0, FlxG.height * 0.52).loadGraphic(AssetPaths.newgrounds_logo__png); + ngSpr = new FlxSprite(0, FlxG.height * 0.52).loadGraphic('assets/images/newgrounds_logo.png'); add(ngSpr); ngSpr.visible = false; ngSpr.setGraphicSize(Std.int(ngSpr.width * 0.8)); @@ -252,7 +266,19 @@ class TitleState extends MusicBeatState new FlxTimer().start(2, function(tmr:FlxTimer) { - FlxG.switchState(new MainMenuState()); + // Check if version is outdated + + var version:String = "v" + Application.current.meta.get('version'); + + if (version.trim() != NGio.GAME_VER.trim() && !OutdatedSubState.leftState) + { + trace('OLD VERSION!'); + FlxG.switchState(new OutdatedSubState()); + } + else + { + FlxG.switchState(new MainMenuState()); + } }); // FlxG.sound.play('assets/music/titleShoot' + TitleState.soundExt, 0.7); } diff --git a/source/WiggleEffect.hx b/source/WiggleEffect.hx new file mode 100644 index 000000000..ac2bd3bbf --- /dev/null +++ b/source/WiggleEffect.hx @@ -0,0 +1,133 @@ +package; + +// STOLEN FROM HAXEFLIXEL DEMO LOL +import flixel.system.FlxAssets.FlxShader; + +enum WiggleEffectType +{ + DREAMY; + WAVY; + HEAT_WAVE_HORIZONTAL; + HEAT_WAVE_VERTICAL; + FLAG; +} + +class WiggleEffect +{ + public var shader(default, null):WiggleShader = new WiggleShader(); + public var effectType(default, set):WiggleEffectType = DREAMY; + public var waveSpeed(default, set):Float = 0; + public var waveFrequency(default, set):Float = 0; + public var waveAmplitude(default, set):Float = 0; + + public function new():Void + { + shader.uTime.value = [0]; + } + + public function update(elapsed:Float):Void + { + shader.uTime.value[0] += elapsed; + } + + function set_effectType(v:WiggleEffectType):WiggleEffectType + { + effectType = v; + shader.effectType.value = [WiggleEffectType.getConstructors().indexOf(Std.string(v))]; + return v; + } + + function set_waveSpeed(v:Float):Float + { + waveSpeed = v; + shader.uSpeed.value = [waveSpeed]; + return v; + } + + function set_waveFrequency(v:Float):Float + { + waveFrequency = v; + shader.uFrequency.value = [waveFrequency]; + return v; + } + + function set_waveAmplitude(v:Float):Float + { + waveAmplitude = v; + shader.uWaveAmplitude.value = [waveAmplitude]; + return v; + } +} + +class WiggleShader extends FlxShader +{ + @:glFragmentSource(' + #pragma header + //uniform float tx, ty; // x,y waves phase + uniform float uTime; + + const int EFFECT_TYPE_DREAMY = 0; + const int EFFECT_TYPE_WAVY = 1; + const int EFFECT_TYPE_HEAT_WAVE_HORIZONTAL = 2; + const int EFFECT_TYPE_HEAT_WAVE_VERTICAL = 3; + const int EFFECT_TYPE_FLAG = 4; + + uniform int effectType; + + /** + * How fast the waves move over time + */ + uniform float uSpeed; + + /** + * Number of waves over time + */ + uniform float uFrequency; + + /** + * How much the pixels are going to stretch over the waves + */ + uniform float uWaveAmplitude; + + vec2 sineWave(vec2 pt) + { + float x = 0.0; + float y = 0.0; + + if (effectType == EFFECT_TYPE_DREAMY) + { + float offsetX = sin(pt.y * uFrequency + uTime * uSpeed) * uWaveAmplitude; + pt.x += offsetX; // * (pt.y - 1.0); // <- Uncomment to stop bottom part of the screen from moving + } + else if (effectType == EFFECT_TYPE_WAVY) + { + float offsetY = sin(pt.x * uFrequency + uTime * uSpeed) * uWaveAmplitude; + pt.y += offsetY; // * (pt.y - 1.0); // <- Uncomment to stop bottom part of the screen from moving + } + else if (effectType == EFFECT_TYPE_HEAT_WAVE_HORIZONTAL) + { + x = sin(pt.x * uFrequency + uTime * uSpeed) * uWaveAmplitude; + } + else if (effectType == EFFECT_TYPE_HEAT_WAVE_VERTICAL) + { + y = sin(pt.y * uFrequency + uTime * uSpeed) * uWaveAmplitude; + } + else if (effectType == EFFECT_TYPE_FLAG) + { + y = sin(pt.y * uFrequency + 10.0 * pt.x + uTime * uSpeed) * uWaveAmplitude; + x = sin(pt.x * uFrequency + 5.0 * pt.y + uTime * uSpeed) * uWaveAmplitude; + } + + return vec2(pt.x + x, pt.y + y); + } + + void main() + { + vec2 uv = sineWave(openfl_TextureCoordv); + gl_FragColor = texture2D(bitmap, uv); + }') + public function new() + { + super(); + } +}