diff --git a/.github/ISSUE_TEMPLATE/bugs.yml b/.github/ISSUE_TEMPLATE/bugs.yml deleted file mode 100644 index 092d2d612..000000000 --- a/.github/ISSUE_TEMPLATE/bugs.yml +++ /dev/null @@ -1,50 +0,0 @@ -name: Bug report -description: Report bugs with the engine here -labels: [bug] -body: - - type: textarea - id: description - attributes: - label: "Describe your bug here." - validations: - required: true - - - type: textarea - id: terminal - attributes: - label: "Command Prompt/Terminal logs (if existing)" - render: bash - validations: - required: false - - - type: dropdown - id: modding - attributes: - label: "Are you modding a build from source or with Lua?" - options: - - Lua - - Source - validations: - required: true - - - type: dropdown - id: btarget - attributes: - label: "What is your build target?" - options: - - "Windows" - - "Linux" - - "Mac" - - "HTML5" - - "Flash/Air-based target" - - "Neko, HashLink, or other build system" - validations: - required: true - - - type: input - id: buildsummary - attributes: - label: "Did you edit anything in this build? If so, mention or summarize your changes." - placeholder: "Yes, I edited ClientPrefs.hx and tried to add a new setting" - validations: - required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index 8e9f9162b..000000000 --- a/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,2 +0,0 @@ -blank_issues_enabled: false -contact_links: [] \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml deleted file mode 100644 index 009462b59..000000000 --- a/.github/ISSUE_TEMPLATE/feature-request.yml +++ /dev/null @@ -1,9 +0,0 @@ -name: Feature Request -description: No, i won't add 6K/etc to the engine or winning icons, stop asking for it. REQUESTING FOR A STAGE EDITOR WILL RESULT IN A BAN, I ALREADY SAID I WILL DO IT LATER GOD DAMN IT. -labels: [enhancement] -body: - - type: textarea - attributes: - label: What feature do you want to get added on the base engine? - validations: - required: true diff --git a/.github/ISSUE_TEMPLATE/help.yml b/.github/ISSUE_TEMPLATE/help.yml deleted file mode 100644 index f3265307d..000000000 --- a/.github/ISSUE_TEMPLATE/help.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Help me! -description: If you need help using the engine. -labels: [help wanted] -body: - - type: textarea - id: description - attributes: - label: "Describe your problem here." - validations: - required: true - - - type: dropdown - id: modding - attributes: - label: "Are you modding a build from source or with Lua?" - options: - - Lua - - Source - validations: - required: true - - - type: dropdown - id: btarget - attributes: - label: "What is your build target?" - options: - - "Windows x64" - - "Windows x86/x32" - - "Linux" - - "Mac" - - "HTML5/Browser" - - "Flash/Air-based target" - - "Neko, HashLink, or other build system" - validations: - required: true - - - type: input - id: buildsummary - attributes: - label: "Did you edit anything in this build? If so, mention or summarize your changes." - placeholder: "Yes, I edited ClientPrefs.hx and tried to add a new setting" - validations: - required: false diff --git a/.github/ISSUE_TEMPLATE/missing-docs.yml b/.github/ISSUE_TEMPLATE/missing-docs.yml deleted file mode 100644 index ab8ae2b74..000000000 --- a/.github/ISSUE_TEMPLATE/missing-docs.yml +++ /dev/null @@ -1,10 +0,0 @@ -name: Missing Documentation -description: Ask for documentation if something is missing. -labels: [documentation] -body: - - type: textarea - attributes: - label: What needs to be documented? - description: 'For example: "There is no page explaining how to create an Achievement!"' - validations: - required: true \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml deleted file mode 100644 index 8e04906bd..000000000 --- a/.github/ISSUE_TEMPLATE/question.yml +++ /dev/null @@ -1,9 +0,0 @@ -name: Question -description: Ask about something here. -labels: [question] -body: - - type: textarea - attributes: - label: What is your question? - validations: - required: true \ No newline at end of file diff --git a/.github/workflows/Android.yml b/.github/workflows/Android.yml deleted file mode 100644 index ce316c36f..000000000 --- a/.github/workflows/Android.yml +++ /dev/null @@ -1,77 +0,0 @@ -# This is a basic workflow to help you get started with Actions - -name: Android Build CI - -# Controls when the workflow will run -on: [push, pull_request, workflow_dispatch] - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "build" - build: - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - - uses: krdlab/setup-haxe@v1 - with: - haxe-version: 4.2.3 - - - name: Cache haxelib path - uses: actions/cache@v2 - with: - path: | - %HAXELIB_ROOT% - key: ${{ runner.os }}-android - - - name: Setup Android SDK Tools - uses: android-actions/setup-android@v2.0.2 - - - name: Setup Java JDK - uses: actions/setup-java@v2.3.1 - with: - distribution: 'zulu' - java-version: '11' - - - uses: nttld/setup-ndk@v1 - with: - ndk-version: r15c - - # Runs a set of commands using the runners shell - - name: script run line haha - run: | - mkdir -p "%HAXELIB_ROOT%" - haxelib setup "%HAXELIB_ROOT%" - haxelib install lime 7.9.0 --quiet - haxelib install openfl --quiet - haxelib install flixel 4.9.0 --quiet - haxelib install hxcpp --quiet - haxelib run lime setup - haxelib run lime config ANDROID_SDK $ANDROID_SDK_ROOT - haxelib run lime config ANDROID_NDK_ROOT $ANDROID_NDK_ROOT - haxelib run lime config JAVA_HOME $JAVA_HOME - haxelib run lime config ANDROID_SETUP true - haxelib install flixel-tools --quiet - haxelib install flixel-ui --quiet - haxelib install flixel-addons 2.10.0 --quiet - haxelib install hscript --quiet - haxelib git faxe https://github.com/uhrobots/faxe --quiet - haxelib git polymod https://github.com/MasterEric/polymod.git --quiet - haxelib git discord_rpc https://github.com/Aidan63/linc_discord-rpc --quiet - haxelib git extension-webm https://github.com/jigsaw-4277821/extension-webm --quiet - haxelib git linc_luajit https://github.com/Daninnocent/linc_luajit.git --quiet - haxelib install actuate - haxelib list - - - name: Build Log - run: | - haxelib run lime setup android - haxelib run lime build android -final - - - uses: actions/upload-artifact@v2 - with: - name: Android Build - path: export/release/android/bin/app/build/outputs/apk/debug diff --git a/.github/workflows/main.apk b/.github/workflows/main.apk new file mode 100644 index 000000000..18a6a3e3d --- /dev/null +++ b/.github/workflows/main.apk @@ -0,0 +1,36 @@ +# This is a basic workflow to help you get started with Actions + +name: CI + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the "main" branch + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v3 + + # Runs a single command using the runners shell + - name: Run a one-line script + run: echo Hello, world! + + # Runs a set of commands using the runners shell + - name: Run a multi-line script + run: | + echo Add other actions to build, + echo test, and deploy your project. diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index 58869ff7a..000000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,141 +0,0 @@ -# This is a basic workflow to help you get started with Actions - -name: Build - -# Controls when the action will run. -on: - # Triggers the workflow on push or pull request events but only for the master branch - push: - branches: [ main ] - pull_request: - branches: [ main ] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "build" - buildLinux: - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - - - uses: krdlab/setup-haxe@master - with: - haxe-version: 4.2.0 - # Runs a set of commands using the runners shell - - name: Install Haxelib - run: | - haxelib setup ~/haxelib - haxelib install hxcpp > /dev/null - haxelib install lime - haxelib install openfl - haxelib --never install flixel - haxelib run lime setup flixel - haxelib run lime setup - haxelib install flixel-tools - haxelib install flixel-ui - haxelib install flixel-addons - haxelib install tjson - haxelib install hxjsonast - haxelib install linc_luajit - haxelib install hscript - haxelib git hscript-ex https://github.com/ianharrigan/hscript-ex - haxelib git discord_rpc https://github.com/Aidan63/linc_discord-rpc - haxelib install hxcpp-debug-server - haxelib list - - name: Create Version Tag - run: echo "${{github.run_id}}" > VERSION - - name: Compile - run: haxelib run lime build Project.xml linux --app-version="4.0.0-${{ github.run_id}}" - - name: Publish Artifact - uses: actions/upload-artifact@v2.2.4 - with: - name: linuxBuild - path: 'export/release/linux/bin' - buildWindows: - runs-on: windows-latest - - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2.3.0 - - - uses: krdlab/setup-haxe@master - with: - haxe-version: 4.2.0 - # Runs a set of commands using the runners shell - - name: Install Haxelib - run: | - haxelib setup C:/haxelib - haxelib install hxcpp > nul - haxelib install lime - haxelib install openfl - haxelib --never install flixel - haxelib run lime setup flixel - haxelib run lime setup - haxelib install flixel-tools - haxelib install flixel-ui - haxelib install flixel-addons - haxelib install tjson - haxelib install hxjsonast - haxelib install linc_luajit - haxelib install hscript - haxelib git hscript-ex https://github.com/ianharrigan/hscript-ex - haxelib git discord_rpc https://github.com/Aidan63/linc_discord-rpc - haxelib install hxcpp-debug-server - haxelib list - shell: cmd - - name: Create Version Tag - run: echo "${{github.run_id}}" > VERSION - - name: Compile - run: haxelib run lime build windows --app-version="4.0.0-${{ github.run_id}}" - - name: Publish Artifact - uses: actions/upload-artifact@v2.2.4 - with: - name: windowsBuild - path: export/release/windows/bin - buildMac: - runs-on: macos-latest - - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - - - uses: krdlab/setup-haxe@master - with: - haxe-version: 4.2.0 - # Runs a set of commands using the runners shell - - name: Install Haxelib - run: | - haxelib setup ~/haxelib - haxelib install hxcpp > /dev/null - haxelib install lime - haxelib install openfl - haxelib --never install flixel - haxelib run lime setup flixel - haxelib run lime setup - haxelib install flixel-tools - haxelib install flixel-ui - haxelib install flixel-addons - haxelib install tjson - haxelib install hxjsonast - haxelib install linc_luajit - haxelib install hscript - haxelib git hscript-ex https://github.com/ianharrigan/hscript-ex - haxelib git discord_rpc https://github.com/Aidan63/linc_discord-rpc - haxelib install hxcpp-debug-server - haxelib list - - name: Create Version Tag - run: echo "${{github.run_id}}" > VERSION - - name: Compile - run: haxelib run lime build mac --app-version="4.0.0-${{ github.run_id}}" - - name: Publish Artifact - uses: actions/upload-artifact@v2.2.4 - with: - name: macBuild - path: export/release/macos/bin diff --git a/MainMenuState.hx b/MainMenuState.hx new file mode 100644 index 000000000..f54d97b5b --- /dev/null +++ b/MainMenuState.hx @@ -0,0 +1,361 @@ +package; + +import flixel.input.gamepad.FlxGamepad; +import Controls.KeyboardScheme; +import flixel.FlxG; +import flixel.FlxObject; +import flixel.FlxSprite; +import flixel.effects.FlxFlicker; +import flixel.graphics.frames.FlxAtlasFrames; +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.text.FlxText; +import flixel.tweens.FlxEase; +import flixel.tweens.FlxTween; +import flixel.util.FlxColor; +import flixel.util.FlxTimer; +import io.newgrounds.NG; +import lime.app.Application; + +#if windows +import Discord.DiscordClient; +#end + +using StringTools; + +class MainMenuState extends MusicBeatState +{ + var curSelected:Int = 0; + + var xval:Int = 100; + + var arrows:FlxSprite; + + var canTween:Bool = true; + + var menuItems:FlxTypedGroup; + + var soundCooldown:Bool = true; + + #if !switch + var optionShit:Array = ['story mode', 'freeplay', 'options', 'sound test']; + #else + var optionShit:Array = ['story mode', 'freeplay']; + #end + + var newGaming:FlxText; + var newGaming2:FlxText; + public static var firstStart:Bool = true; + + public static var nightly:String = ""; + + //public static var kadeEngineVer:String = "1.5.4" + nightly; + //public static var gameVer:String = "0.2.7.1"; + + var bgdesat:FlxSprite; + var camFollow:FlxObject; + public static var finishedFunnyMove:Bool = false; + + var spikeUp:FlxSprite; + var spikeDown:FlxSprite; + + override function create() + { + #if windows + // Updating Discord Rich Presence + DiscordClient.changePresence("In the Menus", null); + #end + + //PlayStateChangeables.nocheese = true; + + //if (!FlxG.sound.music.playing) + //{ + // FlxG.sound.playMusic(Paths.music('MainMenuMusic')); + //} + + if (!FlxG.sound.music.playing) + { + FlxG.sound.playMusic(Paths.music('freakyMenu')); + } + + persistentUpdate = persistentDraw = true; + + var bg:FlxSprite = new FlxSprite(-100).loadGraphic(Paths.image('backgroundlool')); + bg.scrollFactor.x = 0; + bg.scrollFactor.y = 0; + bg.setGraphicSize(Std.int(bg.width * .5)); + bg.updateHitbox(); + bg.screenCenter(); + bg.antialiasing = true; + add(bg); + + bgdesat = new FlxSprite(-80).loadGraphic(Paths.image('backgroundlool2')); + bgdesat.scrollFactor.x = 0; + bgdesat.scrollFactor.y = 0; + bgdesat.setGraphicSize(Std.int(bgdesat.width * .5)); + bgdesat.updateHitbox(); + bgdesat.screenCenter(); + bgdesat.visible = false; + bgdesat.antialiasing = true; + bgdesat.color = 0xFFfd719b; + add(bgdesat); + // bgdesat.scrollFactor.set(); + + arrows = new FlxSprite(92, 182).loadGraphic(Paths.image('funniArrows')); + arrows.scrollFactor.set(); + arrows.antialiasing = true; + arrows.updateHitbox(); + add(arrows); + FlxTween.tween(arrows, {y: arrows.y - 50}, 1, {ease: FlxEase.quadInOut, type: PINGPONG}); + + spikeUp = new FlxSprite(0, -65).loadGraphic(Paths.image('spikeUp')); + spikeUp.scrollFactor.x = 0; + spikeUp.scrollFactor.y = 0; + spikeUp.updateHitbox(); + spikeUp.antialiasing = true; + + + spikeDown = new FlxSprite(-60 , 630).loadGraphic(Paths.image('spikeDown')); + spikeDown.scrollFactor.x = 0; + spikeDown.scrollFactor.y = 0; + spikeDown.updateHitbox(); + spikeDown.antialiasing = true; + + camFollow = new FlxObject(0, 0, 1, 1); + add(camFollow); + + + + menuItems = new FlxTypedGroup(); + add(menuItems); + + var tex = Paths.getSparrowAtlas('FNF_main_menu_assets'); + + for (i in 0...optionShit.length) + { + var menuItem:FlxSprite = new FlxSprite(xval, 40 + (i * 140)); + if (i % 2 == 0) menuItem.x -= 600 + i * 400; + else menuItem.x += 600 + i * 400; + + FlxG.log.add(menuItem.x); + menuItem.frames = tex; + menuItem.animation.addByPrefix('idle', optionShit[i] + " basic", 24); + menuItem.animation.addByPrefix('selected', optionShit[i] + " white", 24); + menuItem.animation.play('idle'); + menuItem.ID = i; + menuItems.add(menuItem); + menuItem.scrollFactor.set(); + menuItem.antialiasing = true; + if (firstStart) + FlxTween.tween(menuItem,{x: xval},1 + (i * 0.25) ,{ease: FlxEase.expoInOut, onComplete: function(flxTween:FlxTween) + { + if(i == optionShit.length - 1) + { + finishedFunnyMove = true; + changeItem(); + } + }}); + else + menuItem.x = xval; + + xval = xval + 220; + } + + add(spikeUp); + add(spikeDown); + + firstStart = false; + + FlxG.camera.follow(camFollow, null, 0.60 * (60 / FlxG.save.data.fpsCap)); + + var versionShit:FlxText = new FlxText(5, FlxG.height - 36, 0, "Game version:" + Application.current.meta.get('version') , 12); + versionShit.scrollFactor.set(); + versionShit.setFormat("VCR OSD Mono", 16, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + add(versionShit); + + var engineVersionShit:FlxText = new FlxText(5, FlxG.height - 18, 0, "Tr1NgleEngine version: 1.6.0", 12); + engineVersionShit.scrollFactor.set(); + engineVersionShit.setFormat("VCR OSD Mono", 16, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + add(engineVersionShit); + + // NG.core.calls.event.logEvent('swag').send(); + + + changeItem(); + + super.create(); + } + + var selectedSomethin:Bool = false; + + override function update(elapsed:Float) + { + + if (canTween) + { + canTween = false; + FlxTween.tween(spikeUp, {x: spikeUp.x - 60}, 1, { + onComplete: function(twn:FlxTween) + { + spikeUp.x = 0; + canTween = true; + } + }); + FlxTween.tween(spikeDown, {x: spikeDown.x + 60}, 1, { + onComplete: function(twn:FlxTween) + { + spikeDown.x = -60; + } + }); + } + + //if (FlxG.sound.music.volume < 0.8) + //{ + // FlxG.sound.music.volume += 0.5 * FlxG.elapsed; + //} + + if (!selectedSomethin && finishedFunnyMove) + { + var gamepad:FlxGamepad = FlxG.gamepads.lastActive; + + if (gamepad != null) + { + if (gamepad.justPressed.DPAD_UP) + { + FlxG.sound.play(Paths.sound('scrollMenu')); + changeItem(-1); + } + if (gamepad.justPressed.DPAD_DOWN) + { + FlxG.sound.play(Paths.sound('scrollMenu')); + changeItem(1); + } + } + + if (FlxG.keys.justPressed.UP || FlxG.keys.justPressed.W) + { + FlxG.sound.play(Paths.sound('scrollMenu')); + changeItem(-1); + } + + if (FlxG.keys.justPressed.DOWN || FlxG.keys.justPressed.S) + { + FlxG.sound.play(Paths.sound('scrollMenu')); + changeItem(1); + } + + if (controls.BACK) + { + FlxG.switchState(new TitleState()); + + } + + + if (controls.ACCEPT) + { + if (optionShit[curSelected] == 'donate') + { + //fancyOpenURL("https://ninja-muffin24.itch.io/funkin"); + } + else + { + selectedSomethin = true; + FlxG.sound.play(Paths.sound('confirmMenu')); + + if (FlxG.save.data.flashing) + FlxFlicker.flicker(bgdesat, 1.1, 0.15, false); + + menuItems.forEach(function(spr:FlxSprite) + { + if (curSelected != spr.ID) + { + FlxTween.tween(spr, {alpha: 0}, .3, { + ease: FlxEase.expoOut, + onComplete: function(twn:FlxTween) + { + spr.kill(); + } + }); + } + else + { + //FlxTween.tween(spr, {x: 465, y: 280}, .4); + FlxTween.tween(FlxG.camera, {zoom: 1.1}, 2, {ease: FlxEase.expoOut}); + if (FlxG.save.data.flashing) + { + FlxFlicker.flicker(spr, 1, 0.06, false, false, function(flick:FlxFlicker) + { + goToState(); + }); + } + else + { + new FlxTimer().start(1, function(tmr:FlxTimer) + { + goToState(); + }); + } + } + }); + } + } + } + + super.update(elapsed); + } + + function goToState() + { + var daChoice:String = optionShit[curSelected]; + + switch (daChoice) + { + case 'story mode': + FlxG.switchState(new StoryMenuState()); + trace("Story Menu Selected"); + case 'freeplay': + FlxG.switchState(new FreeplayState()); + + trace("Freeplay Menu Selected"); + + case 'options': + FlxG.switchState(new OptionsMenu()); + trace("going to da options"); + case 'sound test': + FlxG.switchState(new CreditsState()); + trace("going to da sound test menu"); + } + } + + function changeItem(huh:Int = 0) + { + if (finishedFunnyMove) + { + curSelected += huh; + + if (curSelected >= menuItems.length) + curSelected = 0; + if (curSelected < 0) + curSelected = menuItems.length - 1; + } + menuItems.forEach(function(spr:FlxSprite) + { + spr.animation.play('idle'); + + /* + if (huh != 0) + { + FlxTween.cancelTweensOf(spr); + } + FlxTween.tween(spr, {x: 100 + ((curSelected * -1 + spr.ID + 1) * 220) , y: 40 + ((curSelected * -1 + spr.ID + 1) * 140)}, 0.2); + */ + + if (spr.ID == curSelected && finishedFunnyMove) + { + spr.animation.play('selected'); + camFollow.setPosition(spr.getGraphicMidpoint().x, spr.getGraphicMidpoint().y); + } + + spr.updateHitbox(); + }); + } +} \ No newline at end of file diff --git a/Project.xml b/Project.xml index 2b79e124a..879c3eb14 100644 --- a/Project.xml +++ b/Project.xml @@ -2,7 +2,7 @@ - + @@ -119,7 +119,7 @@ - + @@ -127,6 +127,10 @@ + + + + diff --git a/assets/preload/images/credits/majigsaw.png b/assets/preload/images/credits/majigsaw.png index 614ca6a53..b7abadab5 100644 Binary files a/assets/preload/images/credits/majigsaw.png and b/assets/preload/images/credits/majigsaw.png differ diff --git a/source/APIStuff.hx b/source/APIStuff.hx new file mode 100644 index 000000000..f05fa0655 --- /dev/null +++ b/source/APIStuff.hx @@ -0,0 +1,7 @@ +package; + +class APIStuff +{ + public static var API:String = ""; + public static var EncKey:String = ""; +} diff --git a/source/Achievements.hx b/source/Achievements.hx index 9a70d6e07..8c06fde6e 100644 --- a/source/Achievements.hx +++ b/source/Achievements.hx @@ -1,3 +1,4 @@ +import flixel.graphics.FlxGraphic; import flixel.FlxG; import flixel.FlxSprite; import flixel.FlxCamera; @@ -6,29 +7,53 @@ import flixel.tweens.FlxTween; import flixel.group.FlxSpriteGroup; import flixel.util.FlxColor; import flixel.text.FlxText; +#if MODS_ALLOWED +import sys.FileSystem; +import sys.io.File; +#end +import haxe.Json; +import lime.utils.Assets; +import openfl.utils.Assets as OpenFlAssets; using StringTools; +typedef AchievementFile = +{ + var unlocksAfter:String; + var icon:String; + var name:String; + var description:String; + var hidden:Bool; + var customGoal:Bool; +} + class Achievements { - public static var achievementsStuff:Array = [ //Name, Description, Achievement save tag, Hidden achievement - ["Freaky on a Friday Night", "Play on a Friday... Night.", 'friday_night_play', true], - ["She Calls Me Daddy Too", "Beat Week 1 on Hard with no Misses.", 'week1_nomiss', false], - ["No More Tricks", "Beat Week 2 on Hard with no Misses.", 'week2_nomiss', false], - ["Call Me The Hitman", "Beat Week 3 on Hard with no Misses.", 'week3_nomiss', false], - ["Lady Killer", "Beat Week 4 on Hard with no Misses.", 'week4_nomiss', false], - ["Missless Christmas", "Beat Week 5 on Hard with no Misses.", 'week5_nomiss', false], - ["Highscore!!", "Beat Week 6 on Hard with no Misses.", 'week6_nomiss', false], - ["You'll Pay For That...", "Beat Week 7 on Hard with no Misses.", 'week7_nomiss', true], - ["What a Funkin' Disaster!", "Complete a Song with a rating lower than 20%.", 'ur_bad', false], - ["Perfectionist", "Complete a Song with a rating of 100%.", 'ur_good', false], - ["Roadkill Enthusiast", "Watch the Henchmen die over 100 times.", 'roadkill_enthusiast', false], - ["Oversinging Much...?", "Hold down a note for 10 seconds.", 'oversinging', false], - ["Hyperactive", "Finish a Song without going Idle.", 'hype', false], - ["Just the Two of Us", "Finish a Song pressing only two keys.", 'two_keys', false], - ["Toaster Gamer", "Have you tried to run the game on a toaster?", 'toastie', false], - ["Debugger", "Beat the \"Test\" Stage from the Chart Editor.", 'debugger', true] + public static var achievementShits:Array = [//Name, Description, Achievement save tag, Unlocks after, Hidden achievement + //Set unlock after to "null" if it doesnt unlock after a week!! + ["Freaky on a Friday Night", "Play on a Friday... Night.", 'friday_night_play', null, true], + ["She Calls Me Daddy Too", "Beat Week 1 on Hard with no Misses.", 'week1_nomiss', 'week1', false], + ["No More Tricks", "Beat Week 2 on Hard with no Misses.", 'week2_nomiss', 'week2', false], + ["Call Me The Hitman", "Beat Week 3 on Hard with no Misses.", 'week3_nomiss', 'week3', false], + ["Lady Killer", "Beat Week 4 on Hard with no Misses.", 'week4_nomiss', 'week4', false], + ["Missless Christmas", "Beat Week 5 on Hard with no Misses.", 'week5_nomiss', 'week5', false], + ["Highscore!!", "Beat Week 6 on Hard with no Misses.", 'week6_nomiss', 'week6', false], + ["You'll Pay For That...", "Beat Week 7 on Hard with no Misses.", 'week7_nomiss', 'week7', true], + ["What a Funkin' Disaster!", "Complete a Song with a rating lower than 20%.", 'ur_bad', null, false], + ["Perfectionist", "Complete a Song with a rating of 100%.", 'ur_good', null, false], + ["Roadkill Enthusiast", "Watch the Henchmen die over 100 times.", 'roadkill_enthusiast', null, false], + ["Oversinging Much...?", "Hold down a note for 10 seconds.", 'oversinging', null, false], + ["Hyperactive", "Finish a Song without going Idle.", 'hype', null, false], + ["Just the Two of Us", "Finish a Song pressing only two keys.", 'two_keys', null, false], + ["Toaster Gamer", "Have you tried to run the game on a toaster?", 'toastie', null, false], + ["Debugger", "Beat the \"Test\" Stage from the Chart Editor.", 'debugger', null, true] + ]; + + public static var achievementsStuff:Array = [ + //Gets filled when loading achievements ]; + public static var achievementsMap:Map = new Map(); + public static var loadedAchievements:Map = new Map(); public static var henchmenDeath:Int = 0; public static function unlockAchievement(name:String):Void { @@ -38,8 +63,8 @@ class Achievements { } public static function isAchievementUnlocked(name:String) { - if(achievementsMap.exists(name) && achievementsMap.get(name)) { - return true; + if(achievementsMap.exists(name)) { + return achievementsMap.get(name); } return false; } @@ -54,6 +79,13 @@ class Achievements { } public static function loadAchievements():Void { + achievementsStuff = []; + achievementsStuff = achievementShits; + + #if MODS_ALLOWED + //reloadAchievements(); //custom achievements do not work. will add once it doesn't do the duplication bug -bb + #end + if(FlxG.save.data != null) { if(FlxG.save.data.achievementsMap != null) { achievementsMap = FlxG.save.data.achievementsMap; @@ -84,6 +116,103 @@ class Achievements { // EDIT 2: Uhh this is weird, this message was written for MInd Games, so it doesn't apply logically for Psych Engine LOL } + + public static function reloadAchievements() { //Achievements in game are hardcoded, no need to make a folder for them + loadedAchievements.clear(); + + #if MODS_ALLOWED //Based on WeekData.hx + var disabledMods:Array = []; + var modsListPath:String = 'modsList.txt'; + var directories:Array = [Paths.mods()]; + if(FileSystem.exists(modsListPath)) + { + var stuff:Array = CoolUtil.coolTextFile(modsListPath); + for (i in 0...stuff.length) + { + var splitName:Array = stuff[i].trim().split('|'); + if(splitName[1] == '0') // Disable mod + { + disabledMods.push(splitName[0]); + } + else // Sort mod loading order based on modsList.txt file + { + var path = haxe.io.Path.join([Paths.mods(), splitName[0]]); + //trace('trying to push: ' + splitName[0]); + if (sys.FileSystem.isDirectory(path) && !Paths.ignoreModFolders.contains(splitName[0]) && !disabledMods.contains(splitName[0]) && !directories.contains(path + '/')) + { + directories.push(path + '/'); + //trace('pushed Directory: ' + splitName[0]); + } + } + } + } + + var modsDirectories:Array = Paths.getModDirectories(); + for (folder in modsDirectories) + { + var pathThing:String = haxe.io.Path.join([Paths.mods(), folder]) + '/'; + if (!disabledMods.contains(folder) && !directories.contains(pathThing)) + { + directories.push(pathThing); + //trace('pushed Directory: ' + folder); + } + } + + for (i in 0...directories.length) { + var directory:String = directories[i] + 'achievements/'; + + //trace(directory); + if (FileSystem.exists(directory)) { + + var listOfAchievements:Array = CoolUtil.coolTextFile(directory + 'achievementList.txt'); + + for (achievement in listOfAchievements) { + var path:String = directory + achievement + '.json'; + + if (FileSystem.exists(path) && !loadedAchievements.exists(achievement) && achievement != PlayState.othersCodeName) { + loadedAchievements.set(achievement, getAchievementInfo(path)); + } + + //trace(path); + } + + for (file in FileSystem.readDirectory(directory)) { + var path = haxe.io.Path.join([directory, file]); + + var cutName:String = file.substr(0, file.length - 5); + if (!FileSystem.isDirectory(path) && file.endsWith('.json') && !loadedAchievements.exists(cutName) && cutName != PlayState.othersCodeName) { + loadedAchievements.set(cutName, getAchievementInfo(path)); + } + + //trace(file); + } + } + } + + for (json in loadedAchievements) { + //trace(json); + achievementsStuff.push([json.name, json.description, json.icon, json.unlocksAfter, json.hidden]); + } + #end + } + + private static function getAchievementInfo(path:String):AchievementFile { + var rawJson:String = null; + #if MODS_ALLOWED + if (FileSystem.exists(path)) { + rawJson = File.getContent(path); + } + #else + if(OpenFlAssets.exists(path)) { + rawJson = Assets.getText(path); + } + #end + + if(rawJson != null && rawJson.length > 0) { + return cast Json.parse(rawJson); + } + return null; + } } class AttachedAchievement extends FlxSprite { @@ -103,8 +232,21 @@ class AttachedAchievement extends FlxSprite { public function reloadAchievementImage() { if(Achievements.isAchievementUnlocked(tag)) { - loadGraphic(Paths.image('achievementgrid'), true, 150, 150); - animation.add('icon', [Achievements.getAchievementIndex(tag)], 0, false, false); + var imagePath:FlxGraphic = Paths.image('achievementgrid'); + var isModIcon:Bool = false; + + if (Achievements.loadedAchievements.exists(tag)) { + isModIcon = true; + imagePath = Paths.image(Achievements.loadedAchievements.get(tag).icon); + } + + var index:Int = Achievements.getAchievementIndex(tag); + if (isModIcon) index = 0; + + trace(imagePath); + + loadGraphic(imagePath, true, 150, 150); + animation.add('icon', [index], 0, false, false); animation.play('icon'); } else { loadGraphic(Paths.image('lockedachievement')); @@ -130,22 +272,47 @@ class AchievementObject extends FlxSpriteGroup { ClientPrefs.saveSettings(); var id:Int = Achievements.getAchievementIndex(name); + var achieveName:String = Achievements.achievementsStuff[id][0]; + var text:String = Achievements.achievementsStuff[id][1]; + + if(Achievements.loadedAchievements.exists(name)) { + id = 0; + achieveName = Achievements.loadedAchievements.get(name).name; + text = Achievements.loadedAchievements.get(name).description; + } + var achievementBG:FlxSprite = new FlxSprite(60, 50).makeGraphic(420, 120, FlxColor.BLACK); achievementBG.scrollFactor.set(); - var achievementIcon:FlxSprite = new FlxSprite(achievementBG.x + 10, achievementBG.y + 10).loadGraphic(Paths.image('achievementgrid'), true, 150, 150); - achievementIcon.animation.add('icon', [id], 0, false, false); + var imagePath = Paths.image('achievementgrid'); + var modsImage = null; + var isModIcon:Bool = false; + + //fucking hell bro + /*if (Achievements.loadedAchievements.exists(name)) { + isModIcon = true; + modsImage = Paths.image(Achievements.loadedAchievements.get(name).icon); + }*/ + + var index:Int = Achievements.getAchievementIndex(name); + if (isModIcon) index = 0; + + //trace(imagePath); + //trace(modsImage); + + var achievementIcon:FlxSprite = new FlxSprite(achievementBG.x + 10, achievementBG.y + 10).loadGraphic((isModIcon ? modsImage : imagePath), true, 150, 150); + achievementIcon.animation.add('icon', [index], 0, false, false); achievementIcon.animation.play('icon'); achievementIcon.scrollFactor.set(); achievementIcon.setGraphicSize(Std.int(achievementIcon.width * (2 / 3))); achievementIcon.updateHitbox(); achievementIcon.antialiasing = ClientPrefs.globalAntialiasing; - var achievementName:FlxText = new FlxText(achievementIcon.x + achievementIcon.width + 20, achievementIcon.y + 16, 280, Achievements.achievementsStuff[id][0], 16); + var achievementName:FlxText = new FlxText(achievementIcon.x + achievementIcon.width + 20, achievementIcon.y + 16, 280, achieveName, 16); achievementName.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, LEFT); achievementName.scrollFactor.set(); - var achievementText:FlxText = new FlxText(achievementName.x, achievementName.y + 32, 280, Achievements.achievementsStuff[id][1], 16); + var achievementText:FlxText = new FlxText(achievementName.x, achievementName.y + 32, 280, text, 16); achievementText.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, LEFT); achievementText.scrollFactor.set(); diff --git a/source/AchievementsMenuState.hx b/source/AchievementsMenuState.hx index 0fe71238c..16cdb52c5 100644 --- a/source/AchievementsMenuState.hx +++ b/source/AchievementsMenuState.hx @@ -19,6 +19,7 @@ using StringTools; class AchievementsMenuState extends MusicBeatState { + #if ACHIEVEMENTS_ALLOWED var options:Array = []; private var grpOptions:FlxTypedGroup; private static var curSelected:Int = 0; @@ -41,8 +42,9 @@ class AchievementsMenuState extends MusicBeatState grpOptions = new FlxTypedGroup(); add(grpOptions); + Achievements.loadAchievements(); for (i in 0...Achievements.achievementsStuff.length) { - if(!Achievements.achievementsStuff[i][3] || Achievements.achievementsMap.exists(Achievements.achievementsStuff[i][2])) { + if(!Achievements.achievementsStuff[i][4] || Achievements.achievementsMap.exists(Achievements.achievementsStuff[i][2])) { options.push(Achievements.achievementsStuff[i]); achievementIndex.push(i); } @@ -70,10 +72,6 @@ class AchievementsMenuState extends MusicBeatState add(descText); changeSelection(); - #if mobileC - addVirtualPad(UP_DOWN, B); - #end - super.create(); } @@ -119,5 +117,7 @@ class AchievementsMenuState extends MusicBeatState } } descText.text = Achievements.achievementsStuff[achievementIndex[curSelected]][1]; + FlxG.sound.play(Paths.sound('scrollMenu'), 0.4); } + #end } diff --git a/source/Alphabet.hx b/source/Alphabet.hx index 987438371..9e7c53379 100644 --- a/source/Alphabet.hx +++ b/source/Alphabet.hx @@ -76,6 +76,7 @@ class Alphabet extends FlxSpriteGroup { for (i in 0...lettersArray.length) { var letter = lettersArray[0]; + letter.destroy(); remove(letter); lettersArray.remove(letter); } @@ -121,7 +122,7 @@ class Alphabet extends FlxSpriteGroup // { // } - var spaceChar:Bool = (character == " " || (isBold && character == "_")); + var spaceChar:Bool = (character == " " || (isBold && character == "-")); if (spaceChar) { consecutiveSpaces++; @@ -377,7 +378,7 @@ class AlphaCharacter extends FlxSprite setGraphicSize(Std.int(width * textSize)); updateHitbox(); this.textSize = textSize; - antialiasing = ClientPrefs.globalAntialiasing; + antialiasing = true; } public function createBoldLetter(letter:String) diff --git a/source/AnimationDebug.hx b/source/AnimationDebug.hx new file mode 100644 index 000000000..454f28208 --- /dev/null +++ b/source/AnimationDebug.hx @@ -0,0 +1,452 @@ +package; + +import flixel.FlxG; +import flixel.FlxObject; +import flixel.FlxSprite; +import flixel.FlxState; +import flixel.FlxCamera; +import flixel.addons.display.FlxGridOverlay; +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.addons.ui.FlxInputText; +import flixel.addons.ui.FlxUI9SliceSprite; +import flixel.addons.ui.FlxUI; +import flixel.addons.ui.FlxUIGroup; +import flixel.addons.ui.FlxUICheckBox; +import flixel.addons.ui.FlxUIDropDownMenu; +import flixel.addons.ui.FlxUIInputText; +import flixel.addons.ui.FlxUINumericStepper; +import flixel.addons.ui.FlxUITabMenu; +import flixel.addons.ui.FlxUITooltip.FlxUITooltipStyle; +import openfl.net.FileReference; +import openfl.events.Event; +import openfl.events.IOErrorEvent; +import flixel.text.FlxText; +import flixel.util.FlxColor; +import flixel.ui.FlxButton; +import flixel.ui.FlxSpriteButton; +using StringTools; +/** + *DEBUG MODE + */ +class AnimationDebug extends FlxState +{ + var UI_box:FlxUITabMenu; + var bf:Boyfriend; + var dad:Character; + var char:Character; + var textAnim:FlxText; + var dumbTexts:FlxTypedGroup; + var layeringbullshit:FlxTypedGroup; + var animList:Array = []; + var curAnim:Int = 0; + var daAnim:String = 'spooky'; + var camFollow:FlxObject; + var camHUD:FlxCamera; + var camGame:FlxCamera; + var player:FlxUICheckBox; + var _file:FileReference; + var ghostBF:Character; + public static var isBF:Bool = false; + public static var isDad:Bool = false; + + var characterTab:FlxUI; + var cumfart:FlxUIDropDownMenu; + + private function saveLevel() + { + var data:String = ''; + for(anim in animList){ + if(anim!="dischargeScared") + data+=anim+" "+char.animOffsets.get(anim)[0] + " "+char.animOffsets.get(anim)[1]+"\n"; + } + + if ((data != null) && (data.length > 0)) + { + _file = new FileReference(); + _file.addEventListener(Event.COMPLETE, onSaveComplete); + _file.addEventListener(Event.CANCEL, onSaveCancel); + _file.addEventListener(IOErrorEvent.IO_ERROR, onSaveError); + + if (isBF) + _file.save(data.trim(), char.curCharacter + "PlayerOffsets.txt"); + else + _file.save(data.trim(), char.curCharacter + "Offsets.txt"); + } + } + + function onSaveComplete(_):Void + { + _file.removeEventListener(Event.COMPLETE, onSaveComplete); + _file.removeEventListener(Event.CANCEL, onSaveCancel); + _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); + _file = null; + FlxG.log.notice("Successfully saved LEVEL DATA."); + } + + function onSaveCancel(_):Void + { + _file.removeEventListener(Event.COMPLETE, onSaveComplete); + _file.removeEventListener(Event.CANCEL, onSaveCancel); + _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); + _file = null; + } + + function onSaveError(_):Void + { + _file.removeEventListener(Event.COMPLETE, onSaveComplete); + _file.removeEventListener(Event.CANCEL, onSaveCancel); + _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); + _file = null; + FlxG.log.error("Problem saving Level data"); + } + + public function new(daAnim:String = 'spooky') + { + super(); + this.daAnim = daAnim; + } + + var ghostAnim:FlxUIInputText; + var typingShit:FlxInputText; + + override function create() + { + FlxG.mouse.visible = true; + FlxG.sound.music.stop(); + var gridBG:FlxSprite = FlxGridOverlay.create(10, 10); + gridBG.scrollFactor.set(0, 0); + add(gridBG); + + camHUD = new FlxCamera(); + camHUD.bgColor.alpha = 0; + camGame = new FlxCamera(); + + FlxG.cameras.add(camGame); + FlxG.cameras.add(camHUD); + FlxCamera.defaultCameras = [camGame]; + + layeringbullshit = new FlxTypedGroup(); + add(layeringbullshit); + + UI_box = new FlxUITabMenu(null,[{name:"Character",label:"Character"}],false); + UI_box.cameras = [camHUD]; + UI_box.resize(300, 200); + UI_box.x = (FlxG.width / 2) + 250; + UI_box.y = 20; + add(UI_box); + + characterTab = new FlxUI(null, UI_box); + characterTab.name = "Character"; + + var characters:Array = CoolUtil.coolTextFile(Paths.txt('characterList')); + + ghostAnim = new FlxUIInputText(50, 80, 70, "", 8); + typingShit = ghostAnim; + + cumfart = new FlxUIDropDownMenu(50, 50, FlxUIDropDownMenu.makeStrIdLabelArray(characters, true), function(character:String) + { + daAnim =characters[Std.parseInt(character)]; + displayCharacter(daAnim); + }); + cumfart.selectedLabel = daAnim; + + player = new FlxUICheckBox(175, 50, null, null, "flipX", 100); + player.checked = false; + player.callback = function() + { + char.flipX= player.checked; + }; + + var saveButton:FlxButton = new FlxButton(50, 125, "Save", function() + { + saveLevel(); + }); + + var regenButton:FlxButton = new FlxButton(150, 125, "Regen List", function() + { + regenerateCharacterList(); + }); + + var changeButton:FlxButton = new FlxButton(150, 80, "Change Ghost Anim", function() + { + changeAnim(); + }); + + characterTab.add(cumfart); + characterTab.add(player); + characterTab.add(regenButton); + characterTab.add(saveButton); + characterTab.add(ghostAnim); + characterTab.add(changeButton); + UI_box.addGroup(characterTab); + dumbTexts = new FlxTypedGroup(); + dumbTexts.cameras = [camHUD]; + add(dumbTexts); + + textAnim = new FlxText(300, 16); + textAnim.size = 26; + textAnim.scrollFactor.set(); + add(textAnim); + + camFollow = new FlxObject(0, 0, 2, 2); + camFollow.screenCenter(); + add(camFollow); + camGame.follow(camFollow); + + var lolText = new FlxText(0, 0, 0, (isDad ? "Opponent" : "Player") + " Mode", 32); + lolText.font = 'Pixel Arial 11 Bold'; + lolText.color = 0xFFFFFFFF; + lolText.borderColor = FlxColor.BLACK; + lolText.borderSize = 3; + lolText.borderStyle = FlxTextBorderStyle.OUTLINE; + lolText.cameras = [camHUD]; + lolText.screenCenter(); + lolText.alignment = LEFT; + lolText.x -= FlxG.width / 2 - 150; + lolText.y += FlxG.height / 2 - 50; + add(lolText); + + displayCharacter(daAnim); + + super.create(); + } + + function changeAnim() + { + if (ghostBF.animOffsets.exists(typingShit.text)) + ghostBF.playAnim(typingShit.text); + else + trace('no anim called ' + typingShit.text); + } + + function regenerateCharacterList() + { + characterTab.remove(cumfart); + + var characters:Array = CoolUtil.coolTextFile(Paths.txt('characterList')); + + cumfart = new FlxUIDropDownMenu(50, 50, FlxUIDropDownMenu.makeStrIdLabelArray(characters, true), function(character:String) + { + daAnim =characters[Std.parseInt(character)]; + displayCharacter(daAnim); + }); + cumfart.selectedLabel = daAnim; + + characterTab.add(cumfart); + } + + function displayCharacter(daAnim:String){ + + var daPath:String = ""; + + dumbTexts.forEach(function(text:FlxText) + { + dumbTexts.remove(text,true); + }); + dumbTexts.clear(); + + animList=[]; + + if(dad!=null) + { + daPath = dad.charPath; + layeringbullshit.remove(dad); + dad.destroy(); + } + + + if(bf!=null) + { + daPath = bf.charPath; + layeringbullshit.remove(bf); + bf.destroy(); + } + + if(ghostBF!=null) + layeringbullshit.remove(ghostBF); + + ghostBF = new Character(0, 0, daAnim); + ghostBF.alpha = .5; + ghostBF.screenCenter(); + ghostBF.debugMode = true; + + layeringbullshit.add(ghostBF); + + if (isDad) + { + dad = new Character(0, 0, daAnim); + dad.screenCenter(); + dad.debugMode = true; + layeringbullshit.add(dad); + + char = dad; + dad.flipX = player.checked; + } + else if (isBF) + { + bf = new Boyfriend(0, 0, daAnim); + bf.screenCenter(); + bf.debugMode = true; + layeringbullshit.add(bf); + + char = bf; + bf.flipX = player.checked; + } + + genBoyOffsets(); + } + + function genBoyOffsets(pushList:Bool = true):Void + { + var daLoop:Int = 0; + + for (anim => offsets in char.animOffsets) + { + var text:FlxText = new FlxText(10, 20 + (18 * daLoop), 0, anim + ": " + offsets, 15); + text.scrollFactor.set(); + text.color = FlxColor.BLUE; + dumbTexts.add(text); + + if (pushList) + animList.push(anim); + + daLoop++; + } + } + + function updateTexts():Void + { + dumbTexts.forEach(function(text:FlxText) + { + text.kill(); + dumbTexts.remove(text, true); + }); + dumbTexts.clear(); + + } + + override function update(elapsed:Float) + { + textAnim.text = char.animation.curAnim.name; + ghostBF.flipX = char.flipX; + + if (FlxG.keys.justPressed.ENTER) + { + FlxG.mouse.visible = false; + LoadingState.loadAndSwitchState(new PlayState()); + } + + if (FlxG.keys.justPressed.FOUR) + { + FlxG.mouse.visible = false; + FlxG.switchState(new PositionDebug((isDad ? dad.curCharacter : bf.curCharacter))); + PositionDebug.isDad = isDad; + PositionDebug.isBF = isBF; + } + + if (FlxG.keys.justPressed.THREE) + { + FlxG.switchState(new AnimationDebug((isDad ? dad.curCharacter : bf.curCharacter))); + AnimationDebug.isBF = isDad; + AnimationDebug.isDad = !isDad; + } + + if (FlxG.keys.justPressed.X) + { + if(isDad) + dad.flipX = !dad.flipX; + else + bf.flipX = !bf.flipX; + } + + if (FlxG.keys.justPressed.E) + camGame.zoom += 0.25; + if (FlxG.keys.justPressed.Q) + camGame.zoom -= 0.25; + + if (FlxG.keys.pressed.I || FlxG.keys.pressed.J || FlxG.keys.pressed.K || FlxG.keys.pressed.L) + { + if (FlxG.keys.pressed.I) + camFollow.velocity.y = -90; + else if (FlxG.keys.pressed.K) + camFollow.velocity.y = 90; + else + camFollow.velocity.y = 0; + + if (FlxG.keys.pressed.J) + camFollow.velocity.x = -90; + else if (FlxG.keys.pressed.L) + camFollow.velocity.x = 90; + else + camFollow.velocity.x = 0; + } + else + { + camFollow.velocity.set(); + } + + if (FlxG.keys.justPressed.W) + { + curAnim -= 1; + } + + if (FlxG.keys.justPressed.S) + { + curAnim += 1; + } + + if (curAnim < 0) + curAnim = animList.length - 1; + + if (curAnim >= animList.length) + curAnim = 0; + + if (FlxG.keys.justPressed.S || FlxG.keys.justPressed.W || FlxG.keys.justPressed.SPACE) + { + char.playAnim(animList[curAnim]); + if (ghostBF.animOffsets.exists('danceLeft')) + ghostBF.playAnim('danceLeft'); + else + ghostBF.playAnim('idle'); + updateTexts(); + genBoyOffsets(false); + } + + var upP = FlxG.keys.anyJustPressed([UP]); + var rightP = FlxG.keys.anyJustPressed([RIGHT]); + var downP = FlxG.keys.anyJustPressed([DOWN]); + var leftP = FlxG.keys.anyJustPressed([LEFT]); + + var holdShift = FlxG.keys.pressed.SHIFT; + var holdAlt = FlxG.keys.pressed.ALT; + var multiplier = 1; + if (holdShift) + multiplier = 10; + if (holdShift && holdAlt) + multiplier = 50; + + if (upP || rightP || downP || leftP) + { + updateTexts(); + if (upP) + char.animOffsets.get(animList[curAnim])[1] += 1 * multiplier; + if (downP) + char.animOffsets.get(animList[curAnim])[1] -= 1 * multiplier; + if (leftP) + char.animOffsets.get(animList[curAnim])[0] += 1 * multiplier; + if (rightP) + char.animOffsets.get(animList[curAnim])[0] -= 1 * multiplier; + + updateTexts(); + genBoyOffsets(false); + char.playAnim(animList[curAnim]); + + if (ghostBF.animOffsets.exists('danceLeft')) + ghostBF.playAnim('danceLeft'); + else + ghostBF.playAnim('idle'); + } + + super.update(elapsed); + } +} \ No newline at end of file diff --git a/source/AnimationDebugOld.hx b/source/AnimationDebugOld.hx new file mode 100644 index 000000000..2e28dcab7 --- /dev/null +++ b/source/AnimationDebugOld.hx @@ -0,0 +1,226 @@ +package; + +import flixel.FlxG; +import flixel.FlxObject; +import flixel.FlxSprite; +import flixel.FlxState; +import flixel.addons.display.FlxGridOverlay; +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.text.FlxText; +import flixel.util.FlxColor; + +/** + *DEBUG MODE + */ +class AnimationDebug extends FlxState +{ + var bf:Boyfriend; + var dad:Character; + var char:Character; + var textAnim:FlxText; + var dumbTexts:FlxTypedGroup; + var animList:Array = []; + var curAnim:Int = 0; + var daAnim:String = 'spooky'; + var camFollow:FlxObject; + public static var isBF:Bool = false; + public static var isDad:Bool = false; + + public function new(daAnim:String = 'spooky') + { + super(); + this.daAnim = daAnim; + } + + override function create() + { + FlxG.sound.music.stop(); + + var gridBG:FlxSprite = FlxGridOverlay.create(10, 10); + gridBG.scrollFactor.set(0.5, 0.5); + add(gridBG); + + if (isBF) + { + bf = new Boyfriend(0, 0, daAnim); + bf.screenCenter(); + bf.debugMode = true; + add(bf); + + char = bf; + bf.flipX = false; + } + else + { + dad = new Character(0, 0, daAnim); + dad.screenCenter(); + dad.debugMode = true; + add(dad); + + char = dad; + dad.flipX = false; + } + + dumbTexts = new FlxTypedGroup(); + add(dumbTexts); + + textAnim = new FlxText(300, 16); + textAnim.size = 26; + textAnim.scrollFactor.set(); + add(textAnim); + + genBoyOffsets(); + + camFollow = new FlxObject(0, 0, 2, 2); + camFollow.screenCenter(); + add(camFollow); + + FlxG.camera.follow(camFollow); + + super.create(); + } + + function genBoyOffsets(pushList:Bool = true):Void + { + var daLoop:Int = 0; + + for (anim => offsets in char.animOffsets) + { + var text:FlxText = new FlxText(10, 20 + (18 * daLoop), 0, anim + ": " + offsets, 15); + text.scrollFactor.set(); + text.color = FlxColor.BLUE; + dumbTexts.add(text); + + if (pushList) + animList.push(anim); + + daLoop++; + } + } + + function genPlayerOffsets(pushList:Bool = true):Void + { + var daLoop:Int = 0; + + for (anim => offsets in char.animOffsets) + { + var text:FlxText = new FlxText(10, 20 + (18 * daLoop), 0, anim + ": " + offsets, 15); + text.scrollFactor.set(); + text.color = FlxColor.BLUE; + dumbTexts.add(text); + + if (pushList) + animList.push(anim); + + daLoop++; + } + } + + function updateTexts():Void + { + dumbTexts.forEach(function(text:FlxText) + { + text.kill(); + dumbTexts.remove(text, true); + }); + } + + override function update(elapsed:Float) + { + textAnim.text = char.animation.curAnim.name; + + if (FlxG.keys.justPressed.E) + FlxG.camera.zoom += 0.25; + if (FlxG.keys.justPressed.Q) + FlxG.camera.zoom -= 0.25; + + if (FlxG.keys.justPressed.X) + if(isDad) + dad.flipX = !dad.flipX; + else + bf.flipX = !bf.flipX; + + if (FlxG.keys.justPressed.ENTER) + { + PlayState.SONG = PlayState.SONG; + LoadingState.loadAndSwitchState(new PlayState()); + } + + if (FlxG.keys.pressed.I || FlxG.keys.pressed.J || FlxG.keys.pressed.K || FlxG.keys.pressed.L) + { + if (FlxG.keys.pressed.I) + camFollow.velocity.y = -90; + else if (FlxG.keys.pressed.K) + camFollow.velocity.y = 90; + else + camFollow.velocity.y = 0; + + if (FlxG.keys.pressed.J) + camFollow.velocity.x = -90; + else if (FlxG.keys.pressed.L) + camFollow.velocity.x = 90; + else + camFollow.velocity.x = 0; + } + else + { + camFollow.velocity.set(); + } + + if (FlxG.keys.justPressed.W) + { + curAnim -= 1; + } + + if (FlxG.keys.justPressed.S) + { + curAnim += 1; + } + + if (curAnim < 0) + curAnim = animList.length - 1; + + if (curAnim >= animList.length) + curAnim = 0; + + if (FlxG.keys.justPressed.S || FlxG.keys.justPressed.W || FlxG.keys.justPressed.SPACE) + { + char.playAnim(animList[curAnim]); + + updateTexts(); + genBoyOffsets(false); + } + + var upP = FlxG.keys.anyJustPressed([UP]); + var rightP = FlxG.keys.anyJustPressed([RIGHT]); + var downP = FlxG.keys.anyJustPressed([DOWN]); + var leftP = FlxG.keys.anyJustPressed([LEFT]); + + var holdShift = FlxG.keys.pressed.SHIFT; + var holdAlt = FlxG.keys.pressed.ALT; + var multiplier = 1; + if (holdShift) + multiplier = 10; + if (holdShift && holdAlt) + multiplier = 50; + + if (upP || rightP || downP || leftP) + { + updateTexts(); + if (upP) + char.animOffsets.get(animList[curAnim])[1] += 1 * multiplier; + if (downP) + char.animOffsets.get(animList[curAnim])[1] -= 1 * multiplier; + if (leftP) + char.animOffsets.get(animList[curAnim])[0] += 1 * multiplier; + if (rightP) + char.animOffsets.get(animList[curAnim])[0] -= 1 * multiplier; + + updateTexts(); + genBoyOffsets(false); + char.playAnim(animList[curAnim]); + } + + super.update(elapsed); + } +} diff --git a/source/AtlasFrameMaker.hx b/source/AtlasFrameMaker.hx new file mode 100644 index 000000000..2c845216b --- /dev/null +++ b/source/AtlasFrameMaker.hx @@ -0,0 +1,158 @@ +package; +import openfl.display.PixelSnapping; +import openfl.display.Bitmap; +import flixel.math.FlxPoint; +import flixel.math.FlxRect; +import sys.io.File; + +import openfl.Assets; +import haxe.Json; +import openfl.display.BitmapData; +import animateatlas.JSONData.AtlasData; +import animateatlas.JSONData.AnimationData; +import animateatlas.displayobject.SpriteAnimationLibrary; +import animateatlas.displayobject.SpriteMovieClip; +import flixel.graphics.FlxGraphic; +import flixel.graphics.frames.FlxFramesCollection; +import flixel.graphics.frames.FlxFrame; + +//this is cool and all but uses a lil more memory. I can't do that. +class AtlasFrameMaker extends FlxFramesCollection{ + + + public static var widthoffset:Int = 0; + public static var heightoffset:Int = 0; + public static var excludeArray:Array; + /** + Turns all TextureAtlas frames into bitmaps, to give it directly to the braindead Flixel animation system.(THIS IS AN EARLY EARLY EARLY SUPER FUCKING EARLY BUILD MORE SHIT AND FIXES SOON!) + This is early as shit im just sayin! + + + **/ + + public static function construct(key:String,_widthoffset:Int = 0,_heightoffset:Int = 0,_excludeArray:Array = null):FlxFramesCollection{ + + widthoffset = _widthoffset; + heightoffset = _heightoffset; + if(_excludeArray == null){ + _excludeArray = []; + } + excludeArray = _excludeArray; + + var frameCollection:FlxFramesCollection; + var frameArray:Array> = []; + #if desktop + var animationData:AnimationData = Json.parse(File.getContent(key + "/Animation.json")); + var atlasData:AtlasData = Json.parse(File.getContent(key + "/spritemap.json")); + var bitmapData:BitmapData = BitmapData.fromFile(key + "/spritemap.png"); + + #else + var animationData:AnimationData = Json.parse(Assets.getText(key + "/Animation.json")); + var atlasData:AtlasData = Json.parse(Assets.getText(key + "/spritemap.json")); + var bitmapData:BitmapData = Assets.getBitmapData(key + "/spritemap.png"); + + + + + #end + var ss = new SpriteAnimationLibrary(animationData, atlasData, bitmapData); + var t = ss.createAnimation(); + frameCollection = new FlxFramesCollection(FlxGraphic.fromBitmapData(bitmapData),FlxFrameCollectionType.IMAGE); + + + for(x in t.getFrameLabels()){ + + frameArray.push(getFramesArray(t, x)); + + + } + + for(x in frameArray){ + for(y in x){ + frameCollection.pushFrame(y); + } + } + + + return frameCollection; + + } + + static function getFramesArray(t:SpriteMovieClip,animation:String):Array + { + t.currentLabel = animation; + var bitMapArray:Array = []; + var daFramez:Array = []; + var firstPass = true; + var frameSize:FlxPoint = new FlxPoint(0,0); + trace('Excluding frames: ' + excludeArray); + + + + for (i in 0...t.numFrames){ + t.currentFrame = i; + if (t.currentLabel == animation){ + if (!excludeArray.contains(animation)){ + //trace('creating frames for: ' + animation); + var bitmapShit:BitmapData = new BitmapData(Std.int(t.width + widthoffset),Std.int(t.height + heightoffset),true,0); + bitmapShit.draw(t, null, null, null, null, true); + bitMapArray.push(bitmapShit); + if (firstPass){ + frameSize.set(bitmapShit.width - widthoffset,bitmapShit.height - heightoffset); + firstPass = false; + } + } + } + } + //trace(bitMapArray); + + for (i in 0...bitMapArray.length){ + var theFrame = new FlxFrame(FlxGraphic.fromBitmapData(bitMapArray[i])); + theFrame.parent = FlxGraphic.fromBitmapData(bitMapArray[i]); + theFrame.name = animation + i; + theFrame.sourceSize.set(frameSize.x,frameSize.y); + theFrame.frame = new FlxRect(0, 0, bitMapArray[i].width, bitMapArray[i].height); + theFrame.offset.x = 0; + theFrame.offset.y = 0; + daFramez.push(theFrame); + + //trace(daFramez); + } + + return daFramez; + } + + /*public static function renderTest(key:String, animation:String, ?frame:Int = 0):Void + { + var animationData:AnimationData = Json.parse(Assets.getText(key + "/Animation.json")); + var atlasData:AtlasData = Json.parse(Assets.getText(key + "/spritemap.json")); + var bitmapData:BitmapData = Assets.getBitmapData(key + "/spritemap.png"); + var ss = new SpriteAnimationLibrary(animationData, atlasData, bitmapData); + var t = ss.createAnimation(); + var bitMapArray:Array = []; + + for (i in 0...t.numFrames){ + t.currentFrame = i; + if (t.currentLabel == animation){ + //trace(t.currentFrame); + var bitmapShit:BitmapData = new BitmapData(Std.int(t.width),Std.int(t.height),true,0); + //bitmapShit.drawWithQuality(t,null,null,null,null,true); + bitmapShit.draw(t, new Matrix(1, 0, 0, 1, t.width/2, t.height/2), null, null, null, false); + bitMapArray.push(bitmapShit); + } + } + + saveImage(bitMapArray[frame]); + + } + + public static function saveImage(bitmapData:BitmapData) + { + var b:ByteArray = new ByteArray(); + b = bitmapData.encode(bitmapData.rect, new PNGEncoderOptions(true), b); + new FileDialog().save(b, "png", null, "file"); + } + */ + + +} diff --git a/source/AttachedSprite.hx b/source/AttachedSprite.hx index 4184c7b01..c39dd5a0b 100644 --- a/source/AttachedSprite.hx +++ b/source/AttachedSprite.hx @@ -1,6 +1,7 @@ package; import flixel.FlxSprite; +import flixel.FlxG; using StringTools; @@ -26,7 +27,7 @@ class AttachedSprite extends FlxSprite } else if(file != null) { loadGraphic(Paths.image(file)); } - antialiasing = ClientPrefs.globalAntialiasing; + antialiasing = FlxG.save.data.antialiasing; scrollFactor.set(); } diff --git a/source/BETADCIUSecretState.hx b/source/BETADCIUSecretState.hx new file mode 100644 index 000000000..5cdcadb12 --- /dev/null +++ b/source/BETADCIUSecretState.hx @@ -0,0 +1,316 @@ +package; + +import flash.text.TextField; +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.addons.display.FlxGridOverlay; +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.math.FlxMath; +import flixel.text.FlxText; +import flixel.util.FlxColor; +import lime.utils.Assets; +import flixel.effects.FlxFlicker; +import flixel.tweens.FlxTween; + +#if desktop +import Discord.DiscordClient; +#end + +using StringTools; + +class BETADCIUSecretState extends MusicBeatState +{ + var songs:Array = []; + + var selector:FlxText; + var curSelected:Int = 0; + var curDifficulty:Int = 2; + + var scoreText:FlxText; + var diffText:FlxText; + var comboText:FlxText; + var lerpScore:Int = 0; + var intendedScore:Int = 0; + var combo:String = ''; + + private var grpSongs:FlxTypedGroup; + private var curPlaying:Bool = false; + public static var downscroll:Bool = false; + + private var iconArray:Array = []; + + override function create() + { + FlxG.mouse.visible = false; + + MainMenuState.mainMusic = false; + + if (FlxG.sound.music != null) + { + FlxG.sound.music.fadeIn(2, 0, 0.8); + FlxG.sound.playMusic(Paths.music('haachama'), 0); + } + + #if desktop + // Updating Discord Rich Presence + DiscordClient.changePresence("In BETADCIU Secret Menu", null); + #end + + var isDebug:Bool = false; + + #if debug + isDebug = true; + #end + + addWeek(['Treasure-Trove-Cove', 'Bopeebo Rumble', 'Friends'], 1, ['mom', 'hd-monika', 'bf-sonic']); + + // LOAD MUSIC + + // LOAD CHARACTERS + + var bg:FlxSprite = new FlxSprite().loadGraphic(Paths.image('menuBG')); + add(bg); + + grpSongs = new FlxTypedGroup(); + add(grpSongs); + + for (i in 0...songs.length) + { + var songText:Alphabet = new Alphabet(0, (70 * i) + 30, songs[i].songName, true, false); + songText.isMenuItem = true; + songText.targetY = i; + grpSongs.add(songText); + + var icon:HealthIcon = new HealthIcon(songs[i].songCharacter); + icon.sprTracker = songText; + + // using a FlxGroup is too much fuss! + iconArray.push(icon); + add(icon); + + // songText.x += 40; + // DONT PUT X IN THE FIRST PARAMETER OF new ALPHABET() !! + // songText.screenCenter(X); + } + + scoreText = new FlxText(FlxG.width * 0.7, 5, 0, "", 32); + // scoreText.autoSize = false; + scoreText.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, RIGHT); + // scoreText.alignment = RIGHT; + + var scoreBG:FlxSprite = new FlxSprite(scoreText.x - 6, 0).makeGraphic(Std.int(FlxG.width * 0.35), 66, 0xFF000000); + scoreBG.alpha = 0.6; + add(scoreBG); + + diffText = new FlxText(scoreText.x, scoreText.y + 36, 0, "", 24); + diffText.font = scoreText.font; + add(diffText); + + comboText = new FlxText(diffText.x + 100, diffText.y, 0, "", 24); + comboText.font = diffText.font; + add(comboText); + + add(scoreText); + + changeSelection(); + + // FlxG.sound.playMusic(Paths.music('title'), 0); + // FlxG.sound.music.fadeIn(2, 0, 0.8); + selector = new FlxText(); + + selector.size = 40; + selector.text = ">"; + // add(selector); + + var swag:Alphabet = new Alphabet(1, 0, "swag"); + + // JUST DOIN THIS SHIT FOR TESTING!!! + /* + var md:String = Markdown.markdownToHtml(Assets.getText('CHANGELOG.md')); + + var texFel:TextField = new TextField(); + texFel.width = FlxG.width; + texFel.height = FlxG.height; + // texFel. + texFel.htmlText = md; + + FlxG.stage.addChild(texFel); + + // scoreText.textField.htmlText = md; + + trace(md); + */ + + super.create(); + } + + public function addSong(songName:String, weekNum:Int, songCharacter:String) + { + songs.push(new SongMetadata4(songName, weekNum, songCharacter)); + } + + public function addWeek(songs:Array, weekNum:Int, ?songCharacters:Array) + { + if (songCharacters == null) + songCharacters = ['bf']; + + var num:Int = 0; + for (song in songs) + { + addSong(song, weekNum, songCharacters[num]); + + if (songCharacters.length != 1) + num++; + } + } + + override function update(elapsed:Float) + { + super.update(elapsed); + + if (FlxG.sound.music.volume < 0.7) + { + FlxG.sound.music.volume += 0.5 * FlxG.elapsed; + } + + lerpScore = Math.floor(FlxMath.lerp(lerpScore, intendedScore, 0.4)); + + if (Math.abs(lerpScore - intendedScore) <= 10) + lerpScore = intendedScore; + + scoreText.text = "PERSONAL BEST:" + lerpScore; + comboText.text = combo + '\n'; + + var upP = controls.UP_P; + var downP = controls.DOWN_P; + var accepted = controls.ACCEPT; + + if (upP) + { + changeSelection(-1); + } + if (downP) + { + changeSelection(1); + } + + if (controls.BACK) + { + FlxG.sound.music.stop(); + FlxG.switchState(new MainMenuState()); + } + + if (accepted) + { + var poop:String = Highscore.formatSong(songs[curSelected].songName.toLowerCase(), curDifficulty); + + trace(poop); + + PlayState.SONG = Song.loadFromJson(poop, songs[curSelected].songName.toLowerCase()); + PlayState.isStoryMode = false; + PlayState.isBETADCIU = false; + PlayState.isNeonight = false; + PlayState.isVitor = false; + PlayState.isBonus = true; + PlayState.storyDifficulty = curDifficulty; + + PlayState.storyWeek = songs[curSelected].week; + trace('CUR WEEK' + PlayState.storyWeek); + var llll = FlxG.sound.play(Paths.sound('confirmMenu')).length; + grpSongs.forEach(function(e:Alphabet){ + if (e.text != songs[curSelected].songName){ + FlxTween.tween(e, {x: -6000}, llll / 1000,{onComplete:function(e:FlxTween){ + + if (FlxG.keys.pressed.ALT){ + FlxG.switchState(new ChartingState()); + }else{ + LoadingState.loadAndSwitchState(new PlayState()); + } + }}); + }else{ + FlxFlicker.flicker(e); + trace(curSelected); + FlxTween.tween(e, {x: e.x + 20}, llll/1000); + } + }); + } + + #if !switch + intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty); + combo = Highscore.getCombo(songs[curSelected].songName, curDifficulty); + #end + + switch (curDifficulty) + { + case 0: + diffText.text = "EASY"; + case 1: + diffText.text = 'NORMAL'; + case 2: + diffText.text = "HARD"; + } + } + + function changeSelection(change:Int = 0) + { + #if !switch + // NGio.logEvent('Fresh'); + #end + + // NGio.logEvent('Fresh'); + FlxG.sound.play(Paths.sound('scrollMenu'), 0.4); + + curSelected += change; + + if (curSelected < 0) + curSelected = songs.length - 1; + if (curSelected >= songs.length) + curSelected = 0; + + // selector.y = (70 * curSelected) + 30; + + #if !switch + intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty); + combo = Highscore.getCombo(songs[curSelected].songName, curDifficulty); + // lerpScore = 0; + #end + + var bullShit:Int = 0; + + for (i in 0...iconArray.length) + { + iconArray[i].alpha = 0.6; + } + + iconArray[curSelected].alpha = 1; + + for (item in grpSongs.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)); + } + } + } +} + +class SongMetadata4 +{ + public var songName:String = ""; + public var week:Int = 0; + public var songCharacter:String = ""; + + public function new(song:String, week:Int, songCharacter:String) + { + this.songName = song; + this.week = week; + this.songCharacter = songCharacter; + } +} diff --git a/source/BETADCIUState.hx b/source/BETADCIUState.hx new file mode 100644 index 000000000..e2e40d4ad --- /dev/null +++ b/source/BETADCIUState.hx @@ -0,0 +1,602 @@ +package; + +import flash.text.TextField; +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.addons.display.FlxGridOverlay; +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.math.FlxMath; +import flixel.text.FlxText; +import flixel.util.FlxColor; +import lime.utils.Assets; +import flixel.effects.FlxFlicker; +import flixel.tweens.FlxTween; +import flixel.addons.ui.FlxInputText; +import flixel.util.FlxTimer; + +#if desktop +import Discord.DiscordClient; +#end + +using StringTools; + +class BETADCIUState extends MusicBeatState +{ + var songs:Array = []; + + var selector:FlxText; + var curSelected:Int = 0; + var curDifficulty:Int = 2; + + var scoreText:FlxText; + var enterText:FlxText; + var diffText:FlxText; + var comboText:FlxText; + var passwordText:FlxInputText; + var lerpScore:Int = 0; + var intendedScore:Int = 0; + var combo:String = ''; + + private var grpSongs:FlxTypedGroup; + private var curPlaying:Bool = false; + public static var downscroll:Bool = false; + public static var inMain:Bool = true; + public static var canMove:Bool = true; + public var warning:Bool = false; + var extras:FlxSprite; + var blackScreen:FlxSprite; + + var bg:FlxSprite; + var bgManifest:FlxSprite; + var bgStorm:FlxSprite; + + private var iconArray:Array = []; + + var intendedColor:Int; + var colorTween:FlxTween; + + override function create() + { + Paths.clearStoredMemory(); + Paths.clearUnusedMemory(); + WeekData.reloadWeekFiles(false, 1); + + for (i in 0...WeekData.weeksList.length) { + var leWeek:WeekData = WeekData.weeksLoaded.get(WeekData.weeksList[i]); + var leSongs:Array = []; + var leChars:Array = []; + for (j in 0...leWeek.songs.length) + { + leSongs.push(leWeek.songs[j][0]); + leChars.push(leWeek.songs[j][1]); + } + + WeekData.setDirectoryFromWeek(leWeek); + for (song in leWeek.songs) + { + var colors:Array = song[2]; + if(colors == null || colors.length < 3) + { + colors = [146, 113, 253]; + } + addSong(song[0], i, song[1], FlxColor.fromRGB(colors[0], colors[1], colors[2])); + } + } + + if (songs.length < 1) + { + addSong('Placeholder', 0, 'face', 0xFFFFFFFF); + warning = true; + trace('warn em bro!'); + } + + WeekData.setDirectoryFromWeek(); + + if (FlxG.sound.music.volume == 0 || !FlxG.sound.music.playing) + { + FlxG.sound.music.volume = 1; + FlxG.sound.playMusic(Paths.music('freakyMenu')); + } + + Main.isMegalo = false; + + #if desktop + // Updating Discord Rich Presence + DiscordClient.changePresence("In BETADCIU Menu", null); + #end + + var isDebug:Bool = false; + + FlxG.mouse.visible = true; + inMain = true; + canMove = true; + + #if debug + isDebug = true; + #end + + // LOAD MUSIC + + // LOAD CHARACTERS + + bg = new FlxSprite().loadGraphic(Paths.image('menuDesat')); + bg.scrollFactor.x = 0; + add(bg); + + bgManifest = new FlxSprite().loadGraphic(Paths.image('menuBGManifest')); + bgManifest.scrollFactor.x = 0; + bgManifest.alpha = 0; + add(bgManifest); + + bgStorm = new FlxSprite().loadGraphic(Paths.image('menuBGStorm')); + bgStorm.scrollFactor.x = 0; + bgStorm.alpha = 0; + add(bgStorm); + + grpSongs = new FlxTypedGroup(); + add(grpSongs); + + for (i in 0...songs.length) + { + var songText:Alphabet = new Alphabet(0, (70 * i) + 30, songs[i].songName, true, false); + songText.isMenuItem = true; + songText.targetY = i; + grpSongs.add(songText); + + Paths.currentModDirectory = songs[i].folder; + var icon:HealthIcon = new HealthIcon(songs[i].songCharacter); + icon.sprTracker = songText; + + // using a FlxGroup is too much fuss! + iconArray.push(icon); + add(icon); + + // songText.x += 40; + // DONT PUT X IN THE FIRST PARAMETER OF new ALPHABET() !! + // songText.screenCenter(X); + } + + WeekData.setDirectoryFromWeek(); + + scoreText = new FlxText(FlxG.width * 0.7, 5, 0, "", 32); + // scoreText.autoSize = false; + scoreText.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, RIGHT); + // scoreText.alignment = RIGHT; + + var scoreBG:FlxSprite = new FlxSprite(scoreText.x - 6, 0).makeGraphic(Std.int(FlxG.width * 0.35), 66, 0xFF000000); + scoreBG.alpha = 0.6; + add(scoreBG); + + diffText = new FlxText(scoreText.x, scoreText.y + 36, 0, "", 24); + diffText.font = scoreText.font; + add(diffText); + + comboText = new FlxText(diffText.x + 100, diffText.y, 0, "", 24); + comboText.font = diffText.font; + add(comboText); + + add(scoreText); + + if(curSelected >= songs.length) curSelected = 0; + bg.color = songs[curSelected].color; + intendedColor = bg.color; + + changeSelection(); + + extras = new FlxSprite(scoreText.x + 50, 600).loadGraphic(Paths.image('extras'), true, 360, 110); + extras.animation.add('idle', [0]); + extras.animation.add('hover', [1]); + extras.scrollFactor.set(); + extras.setGraphicSize(Std.int(extras.width * 0.8)); + extras.updateHitbox(); + add(extras); + + blackScreen = new FlxSprite(-100, -100).makeGraphic(Std.int(FlxG.width * 0.5), Std.int(FlxG.height * 0.5), FlxColor.BLACK); + blackScreen.screenCenter(); + blackScreen.scrollFactor.set(); + blackScreen.visible = false; + add(blackScreen); + + enterText = new FlxText(0, 0, 0, "Enter Password:", 48); + enterText.setFormat('Pixel Arial 11 Bold', 48, FlxColor.WHITE, CENTER); + enterText.screenCenter(); + enterText.y -= 100; + enterText.visible = false; + add(enterText); + + passwordText = new FlxInputText(0, 300, 550, '', 36, FlxColor.WHITE, FlxColor.BLACK); + passwordText.fieldBorderColor = FlxColor.WHITE; + passwordText.fieldBorderThickness = 3; + passwordText.maxLength = 20; + passwordText.screenCenter(X); + passwordText.y += 75; + passwordText.visible = false; + add(passwordText); + + // FlxG.sound.playMusic(Paths.music('title'), 0); + // FlxG.sound.music.fadeIn(2, 0, 0.8); + selector = new FlxText(); + + selector.size = 40; + selector.text = ">"; + // add(selector); + + var swag:Alphabet = new Alphabet(1, 0, "swag"); + + // JUST DOIN THIS SHIT FOR TESTING!!! + /* + var md:String = Markdown.markdownToHtml(Assets.getText('CHANGELOG.md')); + + var texFel:TextField = new TextField(); + texFel.width = FlxG.width; + texFel.height = FlxG.height; + // texFel. + texFel.htmlText = md; + + FlxG.stage.addChild(texFel); + + // scoreText.textField.htmlText = md; + + trace(md); + */ + + changeBGColor(); + + if (warning) + { + blackScreen.visible = true; + canMove = false; + inMain = false; + + var daText = new FlxText(0, 0, 0, "No BETADCIUs Detected! \n Press enter to return to main menu.", 48); + daText.setFormat(Paths.font("vcr.ttf"), 48, FlxColor.WHITE, CENTER); + daText.screenCenter(); + daText.x += 20; + daText.y -= 100; + add(daText); + + var daText2 = new FlxText(0, 0, Std.int(FlxG.width * 0.45), "Press enter to return to the main menu.", 44); + daText2.setFormat(Paths.font("vcr.ttf"), 44, FlxColor.WHITE, CENTER); + daText2.screenCenter(); + daText2.y += 100; + add(daText2); + } + + super.create(); + } + + public function addSong(songName:String, weekNum:Int, songCharacter:String, color:Int) + { + songs.push(new FreeplayState.SongMetadata(songName, weekNum, songCharacter, color)); + } + + public function changeBGColor():Void + { + if (songs[curSelected].songName.toLowerCase() == 'manifest' || songs[curSelected].songName.toLowerCase() == 'storm') + { + if (songs[curSelected].songName.toLowerCase() == 'manifest') + FlxTween.tween(bgManifest, {alpha: 1}, 0.5); + if (songs[curSelected].songName.toLowerCase() == 'storm') + FlxTween.tween(bgStorm, {alpha: 1}, 0.5); + } + else + { + var newColor:Int = songs[curSelected].color; + if(newColor != intendedColor) { + if(colorTween != null) { + colorTween.cancel(); + } + intendedColor = newColor; + colorTween = FlxTween.color(bg, 0.5, bg.color, intendedColor, { + onComplete: function(twn:FlxTween) { + colorTween = null; + } + }); + } + + if (bgManifest.alpha > 0) + FlxTween.tween(bgManifest, {alpha: 0}, 0.5); + if (bgStorm.alpha > 0) + FlxTween.tween(bgStorm, {alpha: 0}, 0.5); + + /*switch (songs[curSelected].songName.toLowerCase()) + { + case 'city-funk': + songCol = 0xFF4343AF; + case 'shotgun-shell': + songCol = 0xFFBA1E24; + case 'safety-lullaby': + songCol = 0xFFF9DF44; + case 'for-hire': + songCol = 0xFF0033FF; + case 'triple-trouble' | 'four-way-fracture': + songCol = 0xFF2A0576; + default: + songCol = CoolUtil.dominantColor(iconArray[curSelected]); + }*/ + } + } + + /*public function addWeek(songs:Array, weekNum:Int, ?songCharacters:Array) + { + if (songCharacters == null) + songCharacters = ['bf']; + + var num:Int = 0; + for (song in songs) + { + addSong(song, weekNum, songCharacters[num]); + + if (songCharacters.length != 1) + num++; + } + }*/ + + function isOnBtt(xx:Float, yy:Float, dis:Float) + { + var xDis = xx - FlxG.mouse.x; + var yDis = yy - FlxG.mouse.y; + if (Math.sqrt(Math.pow(xDis, 2) + Math.pow(yDis, 2)) < dis) + { + return(true); + } + else return(false); + } + + override function update(elapsed:Float) + { + super.update(elapsed); + + if (FlxG.sound.music.volume < 0.7) + { + FlxG.sound.music.volume += 0.5 * FlxG.elapsed; + } + + if (FlxG.mouse.overlaps(extras)) + { + extras.animation.play('hover'); + if (FlxG.mouse.justPressed && canMove) + { + blackScreen.visible = true; + enterText.visible = true; + passwordText.visible = true; + canMove = false; + } + } + else if (!FlxG.mouse.overlaps(extras)) + { + extras.animation.play('idle'); + } + + if (passwordText.visible == true) + inMain = false; + + lerpScore = Math.floor(FlxMath.lerp(lerpScore, intendedScore, 0.4)); + + if (Math.abs(lerpScore - intendedScore) <= 10) + lerpScore = intendedScore; + + scoreText.text = "PERSONAL BEST:" + lerpScore; + comboText.text = combo + '\n'; + + var upP = controls.UP_P; + var downP = controls.DOWN_P; + var accepted = controls.ACCEPT; + + if (warning && accepted) + FlxG.switchState(new MainMenuState()); + + var shiftMult:Int = 1; + if(FlxG.keys.pressed.SHIFT) shiftMult = 3; + + if (upP && inMain && canMove) + changeSelection(-shiftMult); + if (downP && inMain && canMove) + changeSelection(shiftMult); + + if (controls.BACK && inMain && canMove) + { + //unloadAssets(); + FlxG.switchState(new MainMenuState()); + } + + if (accepted && inMain && canMove) + { + if (FlxG.random.bool(20) && songs[curSelected].songName.toLowerCase() == 'hill-of-the-void') + { + curDifficulty = 1; + Main.isMegalo = true; + trace ('sans'); + } + + PlayState.isBETADCIU = true; //gotta move this cuz of the format thing + + var poop:String = Highscore.formatSong(songs[curSelected].songName.toLowerCase(), curDifficulty); + + trace(poop); + + PlayState.SONG = Song.loadFromJson(poop, songs[curSelected].songName.toLowerCase()); + PlayState.isStoryMode = false; + PlayState.isNeonight = false; + PlayState.isVitor = false; + PlayState.isBonus = false; + PlayState.storyDifficulty = curDifficulty; + canMove = false; + + PlayState.storyWeek = songs[curSelected].week; + trace('CUR WEEK' + PlayState.storyWeek); + var llll = FlxG.sound.play(Paths.sound('confirmMenu')).length; + + if (songs.length < 2) // the tween doesn't finish if it's just one song + { + new FlxTimer().start(llll/1000, function(tmr:FlxTimer) + { + if (FlxG.keys.pressed.ALT){ + FlxG.switchState(new ChartingState()); + }else{ + if (Main.hiddenSongs.contains(songs[curSelected].songName.toLowerCase()) && !Main.isHidden || PlayState.SONG.song == 'Restore' && !Main.restoreUnlocked || PlayState.SONG.song == 'Deathmatch-Holo' && !Main.deathHolo) + LoadingState.loadAndSwitchState(new GoFindTheSecretState()); + else + LoadingState.loadAndSwitchState(new CustomLoading()); + } + }); + } + + grpSongs.forEach(function(e:Alphabet){ + if (e.text != songs[curSelected].songName){ + FlxTween.tween(e, {x: -6000}, llll / 1000,{onComplete:function(e:FlxTween){ + + if (FlxG.keys.pressed.ALT){ + FlxG.switchState(new ChartingState()); + }else{ + if (Main.hiddenSongs.contains(songs[curSelected].songName.toLowerCase()) && !Main.isHidden || PlayState.SONG.song == 'Restore' && !Main.restoreUnlocked || PlayState.SONG.song == 'Deathmatch-Holo' && !Main.deathHolo) + LoadingState.loadAndSwitchState(new GoFindTheSecretState()); + else + LoadingState.loadAndSwitchState(new CustomLoading()); + } + }}); + }else{ + FlxFlicker.flicker(e); + trace(curSelected); + FlxTween.tween(e, {x: e.x + 20}, llll/1000); + } + }); + } + + #if debug + if (FlxG.keys.justPressed.FIVE) + { + Main.isHidden = !Main.isHidden; + } + #end + + if (FlxG.keys.justPressed.ESCAPE && !inMain && !warning) + { + blackScreen.visible = false; + enterText.visible = false; + passwordText.visible = false; + passwordText.text = ''; + inMain = true; + canMove = true; + } + + var wrongPass:Bool = false; + + // i like don't care anymore. I don't even know how funkipedia managed to find them all... just uh good job i guess. + if (passwordText.text != "" && FlxG.keys.justPressed.ENTER) + { + switch (passwordText.text) + { + case 'dont overwork': startSong('Hunger'); + case 'osu mania': startSong('Diva'); + case 'double trouble': startSong('Shinkyoku'); + case 'norway when': startSong('Norway'); + case 'holofunk yeah': startSong('Sorrow'); + case 'good night': startSong('Safety-Lullaby'); + default: wrongPass = true; + } + } + + if (wrongPass && !inMain) + { + FlxG.sound.play(Paths.soundRandom('missnote', 1, 3, 'shared')); + passwordText.text = ''; + wrongPass = false; + } + + #if !switch + intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty); + combo = Highscore.getCombo(songs[curSelected].songName, curDifficulty); + #end + + switch (curDifficulty) + { + case 0: + diffText.text = "EASY"; + case 1: + diffText.text = 'SANS'; + case 2: + diffText.text = "HARD"; + } + } + + function startSong(songName:String):Void + { + FlxG.sound.music.stop(); + FlxG.sound.play(Paths.sound('ANGRY_TEXT_BOX', 'shared')); + Main.isHidden = true; + + var songFormat = StringTools.replace(songName, " ", "-"); + switch (songFormat) { + case 'Dad-Battle': songFormat = 'Dadbattle'; + case 'Philly-Nice': songFormat = 'Philly'; + case 'Scary-Swings': songFormat = 'Scary Swings'; + } + + var poop:String = Highscore.formatSong(songFormat, curDifficulty); + + PlayState.SONG = Song.loadFromJson(poop, songName); + PlayState.isStoryMode = false; + PlayState.isBETADCIU = true; + PlayState.isBonus = false; + PlayState.isVitor = false; + PlayState.isNeonight = false; + PlayState.storyDifficulty = curDifficulty; + PlayState.storyWeek = 8; + trace('CUR WEEK: EXTRA WEEK'); + LoadingState.loadAndSwitchState(new PlayState()); + } + + function changeSelection(change:Int = 0) + { + #if !switch + // NGio.logEvent('Fresh'); + #end + + // NGio.logEvent('Fresh'); + FlxG.sound.play(Paths.sound('scrollMenu'), 0.4); + + curSelected += change; + + if (curSelected < 0) + curSelected = songs.length - 1; + if (curSelected >= songs.length) + curSelected = 0; + + // selector.y = (70 * curSelected) + 30; + + #if !switch + intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty); + combo = Highscore.getCombo(songs[curSelected].songName, curDifficulty); + // lerpScore = 0; + #end + + var bullShit:Int = 0; + + for (i in 0...iconArray.length) + { + iconArray[i].alpha = 0.6; + } + + iconArray[curSelected].alpha = 1; + + for (item in grpSongs.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)); + } + } + + Paths.currentModDirectory = songs[curSelected].folder; + + changeBGColor(); + } +} \ No newline at end of file diff --git a/source/BGElement.hx b/source/BGElement.hx new file mode 100644 index 000000000..cc665963e --- /dev/null +++ b/source/BGElement.hx @@ -0,0 +1,40 @@ +package; + +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.animation.FlxBaseAnimation; +import flixel.graphics.frames.FlxAtlasFrames; + +using StringTools; + +//could just convert to flxsprite but i'm lazy. +class BGElement extends FlxSprite +{ + + var sc:Float = 1; + var sz:Float = 1; + var movID:Int = 0; + var imgName:String = 'none'; + + var time:Float = 0; + public function new(image:String, sX:Float, sY:Float, scroll:Float, size:Float, movid:Int) + { + movID = movid; + x = sX; + y = sY; + super(x, y); + sc = scroll; + imgName = image; + loadGraphic(Paths.image(imgName)); + scrollFactor.set(sc, sc); + antialiasing = true; + setGraphicSize(Std.int(width * (size))); + + updateHitbox(); + } + + override function update(elapsed:Float) + { + super.update(elapsed); + } +} diff --git a/source/BGSprite.hx b/source/BGSprite.hx index 5e357c512..b816aeb74 100644 --- a/source/BGSprite.hx +++ b/source/BGSprite.hx @@ -3,6 +3,7 @@ package; import flixel.FlxSprite; import flixel.graphics.frames.FlxAtlasFrames; +//could just convert to flxsprite but i'm lazy. class BGSprite extends FlxSprite { private var idleAnim:String; @@ -26,7 +27,6 @@ class BGSprite extends FlxSprite active = false; } scrollFactor.set(scrollX, scrollY); - antialiasing = ClientPrefs.globalAntialiasing; } public function dance(?forceplay:Bool = false) { diff --git a/source/BackgroundDancer.hx b/source/BackgroundDancer.hx index 733c340db..c572c1ecd 100644 --- a/source/BackgroundDancer.hx +++ b/source/BackgroundDancer.hx @@ -9,11 +9,11 @@ class BackgroundDancer extends FlxSprite { super(x, y); - frames = Paths.getSparrowAtlas("limo/limoDancer"); + frames = Paths.getSparrowAtlas("limo/limoDancer",'week4'); 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 = ClientPrefs.globalAntialiasing; + antialiasing = true; } var danceDir:Bool = false; diff --git a/source/BackgroundDancerHolo.hx b/source/BackgroundDancerHolo.hx new file mode 100644 index 000000000..efa67ec06 --- /dev/null +++ b/source/BackgroundDancerHolo.hx @@ -0,0 +1,30 @@ +package; + +import flixel.FlxSprite; +import flixel.graphics.frames.FlxAtlasFrames; + +class BackgroundDancerHolo extends FlxSprite +{ + public function new(x:Float, y:Float) + { + super(x, y); + + frames = Paths.getSparrowAtlas("holofunk/limoholo/limoDancer"); + 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 index 9109bf19c..8a84699c2 100644 --- a/source/BackgroundGirls.hx +++ b/source/BackgroundGirls.hx @@ -5,31 +5,25 @@ import flixel.graphics.frames.FlxAtlasFrames; class BackgroundGirls extends FlxSprite { - var isPissed:Bool = true; public function new(x:Float, y:Float) { super(x, y); // BG fangirls dissuaded - frames = Paths.getSparrowAtlas('weeb/bgFreaks'); + frames = Paths.getSparrowAtlas('weeb/bgFreaks','week6'); - swapDanceType(); + 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 swapDanceType():Void + public function getScared():Void { - isPissed = !isPissed; - if(!isPissed) { //Gets unpissed - animation.addByIndices('danceLeft', 'BG girls group', CoolUtil.numberArray(14), "", 24, false); - animation.addByIndices('danceRight', 'BG girls group', CoolUtil.numberArray(30, 15), "", 24, false); - } else { //Pisses - animation.addByIndices('danceLeft', 'BG fangirls dissuaded', CoolUtil.numberArray(14), "", 24, false); - animation.addByIndices('danceRight', 'BG fangirls dissuaded', CoolUtil.numberArray(30, 15), "", 24, false); - } + animation.addByIndices('danceLeft', 'BG fangirls dissuaded', CoolUtil.numberArray(14), "", 24, false); + animation.addByIndices('danceRight', 'BG fangirls dissuaded', CoolUtil.numberArray(30, 15), "", 24, false); dance(); } diff --git a/source/BackgroundGirlsSwitch.hx b/source/BackgroundGirlsSwitch.hx new file mode 100644 index 000000000..a51d95934 --- /dev/null +++ b/source/BackgroundGirlsSwitch.hx @@ -0,0 +1,46 @@ +package; + +import flixel.FlxSprite; +import flixel.graphics.frames.FlxAtlasFrames; + +class BackgroundGirlsSwitch extends FlxSprite +{ + public function new(x:Float, y:Float, path:String) + { + super(x, y); + + // BG fangirls dissuaded + frames = Paths.getSparrowAtlas(path); + + 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 getNormal():Void + { + animation.addByIndices('danceLeft', 'BG girls group', CoolUtil.numberArray(14), "", 24, false); + animation.addByIndices('danceRight', 'BG girls group', 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/BonusSongsState.hx b/source/BonusSongsState.hx new file mode 100644 index 000000000..21f9e33a3 --- /dev/null +++ b/source/BonusSongsState.hx @@ -0,0 +1,557 @@ + package; + +import flash.text.TextField; +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.addons.display.FlxGridOverlay; +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.math.FlxMath; +import flixel.text.FlxText; +import flixel.util.FlxColor; +import lime.utils.Assets; +import flixel.effects.FlxFlicker; +import flixel.tweens.FlxTween; +import flixel.util.FlxTimer; + +#if windows +import Sys; +import sys.FileSystem; +import sys.io.File; +#end + +#if desktop +import Discord.DiscordClient; +#end + +using StringTools; + +class BonusSongsState extends MusicBeatState +{ + var songs:Array = []; + + var selector:FlxText; + var curSelected:Int = 0; + var curDifficulty:Int = 1; + + var scoreText:FlxText; + var infoText:FlxText; + var diffText:FlxText; + var comboText:FlxText; + var copyrightText:FlxText; + var lerpScore:Int = 0; + var intendedScore:Int = 0; + var combo:String = ''; + + private var grpSongs:FlxTypedGroup; + private var curPlaying:Bool = false; + + var bgPixel:FlxSprite; + var infoBG:FlxSprite; + + var blackScreen:FlxSprite; + var enterText:Alphabet; + var otherText:FlxText; + + var inUnlockMenu:Bool; + public static var canMove:Bool; + public var warning:Bool = false; + + private var iconArray:Array = []; + + override function create() + { + Paths.clearStoredMemory(); + Paths.clearUnusedMemory(); + WeekData.reloadWeekFiles(false, 2); + + for (i in 0...WeekData.weeksList.length) { + var leWeek:WeekData = WeekData.weeksLoaded.get(WeekData.weeksList[i]); + var leSongs:Array = []; + var leChars:Array = []; + for (j in 0...leWeek.songs.length) + { + leSongs.push(leWeek.songs[j][0]); + leChars.push(leWeek.songs[j][1]); + } + + WeekData.setDirectoryFromWeek(leWeek); + for (song in leWeek.songs) + { + var colors:Array = song[2]; + if(colors == null || colors.length < 3) + { + colors = [146, 113, 253]; + } + addSong(song[0], i, song[1]); + } + } + WeekData.setDirectoryFromWeek(); + + if (songs.length < 1) + { + addSong('Placeholder', 0, 'face'); + warning = true; + trace('warn em bro!'); + } + + if (FlxG.sound.music.volume == 0 || !FlxG.sound.music.playing) + { + FlxG.sound.music.volume = 1; + FlxG.sound.playMusic(Paths.music('freakyMenu')); + } + + inUnlockMenu = false; + canMove = true; + + FlxG.sound.cache(Paths.sound("unlock", 'shared')); + + #if desktop + // Updating Discord Rich Presence + DiscordClient.changePresence("In Bonus Song Menu", null); + #end + + var isDebug:Bool = false; + + #if debug + isDebug = true; + #end + + var lamentCombo:String = ''; + var rootsCombo:String = ''; + var spookyCombo:String = ''; + var ughCombo:String = ''; + var argumentCombo:String = ''; + var unholyCombo:String = ''; + + #if !switch + lamentCombo = Highscore.getCombo('Lament', 2); + rootsCombo = Highscore.getCombo('Roots', 2); + spookyCombo = Highscore.getCombo('Spooky-Fight', 2); + ughCombo = Highscore.getCombo('Ugh', 2); + argumentCombo = Highscore.getCombo('Argument', 2); + unholyCombo = Highscore.getCombo('Unholy-Worship', 2); + #end + + if (TitleState.curWacky[1].contains('uncorruption') && Main.seenMessage) + addSong('Restore', 6, 'senpai-glitch'); + + // LOAD MUSIC + + // LOAD CHARACTERS + + var bg:FlxSprite = new FlxSprite().loadGraphic(Paths.image('menuDesat')); + bg.color = FlxColor.fromRGB(112,167,240); + add(bg); + + grpSongs = new FlxTypedGroup(); + add(grpSongs); + + for (i in 0...songs.length) + { + var songText:Alphabet = new Alphabet(0, (70 * i) + 30, songs[i].songName, true, false); + songText.isMenuItem = true; + songText.targetY = i; + grpSongs.add(songText); + + Paths.currentModDirectory = songs[i].folder; + var icon:HealthIcon = new HealthIcon(songs[i].songCharacter); + icon.sprTracker = songText; + + // using a FlxGroup is too much fuss! + iconArray.push(icon); + add(icon); + + // songText.x += 40; + // DONT PUT X IN THE FIRST PARAMETER OF new ALPHABET() !! + // songText.screenCenter(X); + } + + WeekData.setDirectoryFromWeek(); + + scoreText = new FlxText(FlxG.width * 0.7, 5, 0, "", 32); + // scoreText.autoSize = false; + scoreText.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, RIGHT); + // scoreText.alignment = RIGHT; + + var scoreBG:FlxSprite = new FlxSprite(scoreText.x - 6, 0).makeGraphic(Std.int(FlxG.width * 0.35), 66, 0xFF000000); + scoreBG.alpha = 0.6; + add(scoreBG); + + diffText = new FlxText(scoreText.x, scoreText.y + 36, 0, "", 24); + diffText.font = scoreText.font; + add(diffText); + + comboText = new FlxText(diffText.x + 100, diffText.y, 0, "", 24); + comboText.font = diffText.font; + add(comboText); + + add(scoreText); + + infoText = new FlxText(FlxG.width * 0.7, 105, FlxG.height, "", 20); + infoText.setFormat(Paths.font("vcr.ttf"), 20, FlxColor.WHITE, LEFT); + infoText.text = 'This song contains copyrighted' + + '\ncontent. Press P for Alternate' + + '\nInst.'; + + copyrightText = new FlxText(FlxG.width * 0.7, 155, FlxG.height, "", 32); + copyrightText.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, LEFT); + if (!Main.noCopyright) + copyrightText.text = '\nAlternate Inst: Off'; + else + copyrightText.text = '\nAlternate Inst: On'; + + infoBG = new FlxSprite(scoreText.x - 6, 100).makeGraphic(Std.int(FlxG.width * 0.35), 132, 0xFF000000); + infoBG.alpha = 0.6; + add(infoBG); + + add(infoText); + add(copyrightText); + + blackScreen = new FlxSprite(-100, -100).makeGraphic(Std.int(FlxG.width * 0.9), Std.int(FlxG.height * 0.5), FlxColor.BLACK); + blackScreen.screenCenter(); + blackScreen.scrollFactor.set(); + blackScreen.alpha = 0.9; + blackScreen.visible = false; + add(blackScreen); + + var daSong:String = 'Deathmatch'; + + if (!FlxG.save.data.deathHoloUnlocked) + daSong = 'Deathmatch'; + else + daSong = 'Deathmatch Holo\n'; + + enterText = new Alphabet(0, 0, daSong + " Unlocked", true); + enterText.screenCenter(); + enterText.y -= 100; + enterText.visible = false; + add(enterText); + + otherText = new FlxText(0, 0, FlxG.width, "" , 44); + otherText.setFormat('Pixel Arial 11 Bold', 44, FlxColor.WHITE, CENTER); + if (!FlxG.save.data.deathHoloUnlocked) + { + otherText.text = "Asset Password:" + + "\nsenpaiandtankman11"; + } + else + { + otherText.text = "No locked assets." + + "\nPress Enter to Continue"; + } + + otherText.screenCenter(); + otherText.y += 50; + otherText.visible = false; + add(otherText); + + changeSelection(); + changeDiff(); + + // FlxG.sound.playMusic(Paths.music('title'), 0); + // FlxG.sound.music.fadeIn(2, 0, 0.8); + selector = new FlxText(); + + selector.size = 40; + selector.text = ">"; + // add(selector); + + var swag:Alphabet = new Alphabet(1, 0, "swag"); + + if (FlxG.save.data.deathUnlocked && !FlxG.save.data.seenDeathPassword) + { + FlxG.sound.play(Paths.sound('unlock', 'shared')); + blackScreen.visible = true; + enterText.visible = true; + otherText.visible = true; + inUnlockMenu = true; + FlxG.save.data.seenDeathPassword = true; + } + + if (FlxG.save.data.deathHoloUnlocked && !FlxG.save.data.seenDeathHoloPassword) + { + FlxG.sound.play(Paths.sound('unlock', 'shared')); + blackScreen.visible = true; + enterText.visible = true; + otherText.visible = true; + inUnlockMenu = true; + FlxG.save.data.seenDeathHoloPassword = true; + } + + if (warning) + { + var blackScreen = new FlxSprite(-100, -100).makeGraphic(Std.int(FlxG.width * 0.5), Std.int(FlxG.height * 0.5), FlxColor.BLACK); + blackScreen.screenCenter(); + blackScreen.scrollFactor.set(); + blackScreen.visible = false; + add(blackScreen); + + blackScreen.visible = true; + canMove = false; + + var daText = new FlxText(0, 0, 0, "No Bonus Songs Detected! \n Press enter to return to main menu.", 48); + daText.setFormat(Paths.font("vcr.ttf"), 48, FlxColor.WHITE, CENTER); + daText.screenCenter(); + daText.x += 20; + daText.y -= 100; + add(daText); + + var daText2 = new FlxText(0, 0, Std.int(FlxG.width * 0.45), "Press enter to return to the main menu.", 44); + daText2.setFormat(Paths.font("vcr.ttf"), 44, FlxColor.WHITE, CENTER); + daText2.screenCenter(); + daText2.y += 100; + add(daText2); + } + + super.create(); + } + + public function addSong(songName:String, weekNum:Int, songCharacter:String) + { + songs.push(new FreeplayState.SongMetadata(songName, weekNum, songCharacter)); + } + + public function addWeek(songs:Array, weekNum:Int, ?songCharacters:Array) + { + if (songCharacters == null) + songCharacters = ['bf']; + + var num:Int = 0; + for (song in songs) + { + addSong(song, weekNum, songCharacters[num]); + + if (songCharacters.length != 1) + num++; + } + } + + override function update(elapsed:Float) + { + super.update(elapsed); + + if (FlxG.sound.music.volume < 0.7) + { + FlxG.sound.music.volume += 0.5 * FlxG.elapsed; + } + + lerpScore = Math.floor(FlxMath.lerp(lerpScore, intendedScore, 0.4)); + + if (Math.abs(lerpScore - intendedScore) <= 10) + lerpScore = intendedScore; + + if (inUnlockMenu) + canMove = false; + + if (inUnlockMenu && FlxG.keys.justPressed.ENTER) + { + FlxTween.tween(enterText, {alpha: 0}, 0.5); + FlxTween.tween(otherText, {alpha: 0}, 0.5); + FlxTween.tween(blackScreen, {alpha: 0}, 0.5); + + new FlxTimer().start(0.75, function(tmr:FlxTimer) + { + inUnlockMenu = false; + canMove = true; + }); + } + + scoreText.text = "PERSONAL BEST:" + lerpScore; + comboText.text = combo + '\n'; + + var upP = controls.UP_P; + var downP = controls.DOWN_P; + var accepted = controls.ACCEPT; + + var shiftMult:Int = 1; + if(FlxG.keys.pressed.SHIFT) shiftMult = 3; + + if (warning && accepted) + FlxG.switchState(new MainMenuState()); + + if (upP && canMove) + changeSelection(-shiftMult); + if (downP && canMove) + changeSelection(shiftMult); + + if (controls.LEFT_P && canMove) + changeDiff(-1); + if (controls.RIGHT_P && canMove) + changeDiff(1); + + if (controls.BACK && canMove) + FlxG.switchState(new MainMenuState()); + + if (accepted && canMove) + { + var daText:String = ""; + switch (curDifficulty) + { + case 0: daText = "-EASY"; + case 2: daText = "-HARD"; + } + + if (!FileSystem.exists(Paths.json(songs[curSelected].songName.toLowerCase()+'/'+songs[curSelected].songName.toLowerCase()+daText.toLowerCase())) && !FileSystem.exists(Paths.modFolders('data/'+songs[curSelected].songName.toLowerCase()+'/'+songs[curSelected].songName.toLowerCase()+daText.toLowerCase() + '.json'))) + { + trace('no ' + daText.toLowerCase() + ' mode'); + curDifficulty = 2; + } + + PlayState.isStoryMode = false; + PlayState.isBETADCIU = false; + PlayState.isNeonight = false; + PlayState.isVitor = false; + PlayState.isBonus = true; + PlayState.storyDifficulty = curDifficulty; + canMove = false; + + var poop:String = Highscore.formatSong(songs[curSelected].songName.toLowerCase(), curDifficulty); + + trace(poop); + + PlayState.SONG = Song.loadFromJson(poop, songs[curSelected].songName.toLowerCase()); + + PlayState.storyWeek = songs[curSelected].week; + trace('CUR WEEK' + PlayState.storyWeek); + var llll = FlxG.sound.play(Paths.sound('confirmMenu')).length; + + if (songs.length < 2) // the tween doesn't finish if it's just one song + { + new FlxTimer().start(llll/1000, function(tmr:FlxTimer) + { + if (FlxG.keys.pressed.ALT){ + FlxG.switchState(new ChartingState()); + }else{ + if (Main.hiddenSongs.contains(songs[curSelected].songName.toLowerCase()) && !Main.isHidden || PlayState.SONG.song == 'Restore' && !Main.restoreUnlocked || PlayState.SONG.song == 'Deathmatch-Holo' && !Main.deathHolo) + LoadingState.loadAndSwitchState(new GoFindTheSecretState()); + else + LoadingState.loadAndSwitchState(new CustomLoading()); + } + }); + } + + grpSongs.forEach(function(e:Alphabet){ + if (e.text != songs[curSelected].songName){ + FlxTween.tween(e, {x: -6000}, llll / 1000,{onComplete:function(e:FlxTween){ + + if (FlxG.keys.pressed.ALT){ + FlxG.switchState(new ChartingState()); + }else{ + if (Main.hiddenSongs.contains(songs[curSelected].songName.toLowerCase()) && !Main.isHidden || PlayState.SONG.song == 'Restore' && !Main.restoreUnlocked) + LoadingState.loadAndSwitchState(new GoFindTheSecretState()); + else + LoadingState.loadAndSwitchState(new PlayState()); + } + }}); + }else{ + FlxFlicker.flicker(e); + trace(curSelected); + FlxTween.tween(e, {x: e.x + 20}, llll/1000); + } + }); + } + + if (songs[curSelected].songName.toLowerCase() == 'sharkventure') + { + infoBG.visible = true; + infoText.visible = true; + copyrightText.visible = true; + } + else if (songs[curSelected].songName.toLowerCase() != 'sharkventure') + { + infoBG.visible = false; + infoText.visible = false; + copyrightText.visible = false; + } + + if (infoText.visible == true && FlxG.keys.justPressed.P) + { + Main.noCopyright = !Main.noCopyright; + if (!Main.noCopyright) + { + FlxG.sound.play(Paths.sound('cancelMenu')); + copyrightText.text = '\nAlternate Inst: Off'; + } + else + { + FlxG.sound.play(Paths.sound('confirmMenu')); + copyrightText.text = '\nAlternate Inst: On'; + } + } + } + + function changeDiff(change:Int = 0) + { + curDifficulty += change; + + if (curDifficulty < 0) + curDifficulty = 2; + if (curDifficulty > 2) + curDifficulty = 0; + + #if !switch + intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty); + combo = Highscore.getCombo(songs[curSelected].songName, curDifficulty); + #end + + switch (curDifficulty) + { + case 0: + diffText.text = "EASY"; + case 1: + diffText.text = 'NORMAL'; + case 2: + diffText.text = "HARD"; + } + } + + function changeSelection(change:Int = 0) + { + #if !switch + // NGio.logEvent('Fresh'); + #end + + // NGio.logEvent('Fresh'); + FlxG.sound.play(Paths.sound('scrollMenu'), 0.4); + + curSelected += change; + + if (curSelected < 0) + curSelected = songs.length - 1; + if (curSelected >= songs.length) + curSelected = 0; + + // selector.y = (70 * curSelected) + 30; + + #if !switch + intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty); + combo = Highscore.getCombo(songs[curSelected].songName, curDifficulty); + // lerpScore = 0; + #end + + var bullShit:Int = 0; + + for (i in 0...iconArray.length) + { + iconArray[i].alpha = 0.6; + } + + Paths.currentModDirectory = songs[curSelected].folder; + iconArray[curSelected].alpha = 1; + + for (item in grpSongs.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)); + } + } + } +} \ No newline at end of file diff --git a/source/BopeeboRumble.hx b/source/BopeeboRumble.hx new file mode 100644 index 000000000..df55d8969 --- /dev/null +++ b/source/BopeeboRumble.hx @@ -0,0 +1,746 @@ +package; + +import GroovinClasses.ModWeekData; +import GroovinShaders.PlaneRaymarcher; +import Song.SwagSong; +import WiggleEffect.WiggleEffectType; +import flixel.FlxCamera; +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.math.FlxMath; +import flixel.tweens.FlxEase; +import flixel.tweens.FlxTween; +import flixel.util.FlxTimer; +import lime.app.Application; +import openfl.filters.ShaderFilter; +import openfl.utils.Function; + +class BRStageEvent +{ + public var callback:Function; + public var time:Float; + public var dirty:Bool; + + public function new(callback:Function, time:Float) + { + this.callback = callback; + this.time = time; + } +} + +class BopeeboRumbleModInstance +{ + public var vinceKaichan:FlxSprite; + public var kawaiSprite:FlxSprite; + public var me:FlxSprite; + public var ps:PlayState; + public var heyEvents:List; + public var camFake:FlxCamera; + public var camArrows:FlxCamera; + public var camSus:FlxCamera; + public var bounceCam:Bool; + public var tempSwagCounter:Int = 0; + public var wobble:Float = 0; + public var spin:Float = 1; + public var staticArrowWave:Float = 0; + public var spinAmp:Float = 1; + public var spinOff:Float = 1; + public var doSpin:Bool = false; + public var staticArrows:Array = new Array(); + public var susWiggleEffect:WiggleEffect; + public var planeRaymarcher:PlaneRaymarcher; + + public function new() {} +} + +class BopeeboRumbleMod extends Mod +{ + public function new() {} + + var i:BopeeboRumbleModInstance; + + function StageName():String + { + return PlayState.curStage; + } + + override function ShouldRun():Bool + { + if (Type.getClass(FlxG.state) == PlayState) + { + return PlayState.curMod == this && PlayState.isModdedStage; + } + return false; + } + + function AddEvent(callback:Function, time:Float) + { + i.heyEvents.add(new BRStageEvent(callback, time * 1000)); + } + + function AddHey(time:Float) + { + AddEvent((state:PlayState) -> + { + trace("HEY"); + state.boyfriend.playAnim('hey', true); + }, time + 0.02); + // 20 ms ahead to go after idle play + } + + function AddHeys() + { + AddHey(9.12); + AddHey(16.8); + AddHey(32.16); + AddHey(39.84); + AddHey(47.52); + AddHey(93.6); + AddHey(93.84); + } + + public function DebugModCall(s:String, args:Array) + { + switch (s) + { + case "RefreshEvents": + for (event in i.heyEvents) + { + if (event.time > args[0] && event.dirty) + { + Conductor.songPosition = args[0]; + i.ps.vocals.time = Conductor.songPosition; + event.dirty = false; + trace(event, args[0]); + } + } + } + } + + override function GetName():String + { + return Type.getClassName(Type.getClass(this)); + } + + function Credits() + { + var state = i.ps; + var origVisibility:Bool; + AddEvent(() -> + { + origVisibility = FlxG.mouse.visible; + FlxG.mouse.visible = true; + i.vinceKaichan = new FlxSprite().loadGraphic('modweeks:mod_assets/weeks/${GetName()}/bopeebo rumble/images/vincekaichan.png'); + i.kawaiSprite = new FlxSprite().loadGraphic('modweeks:mod_assets/weeks/${GetName()}/bopeebo rumble/images/kawaisprite.png'); + i.me = new FlxSprite().loadGraphic('modweeks:mod_assets/weeks/${GetName()}/bopeebo rumble/images/me.png'); + i.vinceKaichan.updateHitbox(); + i.kawaiSprite.updateHitbox(); + i.me.updateHitbox(); + i.vinceKaichan.cameras = [state.camHUD]; + i.kawaiSprite.cameras = [state.camHUD]; + i.me.cameras = [state.camHUD]; + i.vinceKaichan.setPosition(-i.vinceKaichan.width, 405); + i.kawaiSprite.setPosition(FlxG.width, 497); + i.me.setPosition(-i.me.width, 497); + state.add(i.vinceKaichan); + state.add(i.kawaiSprite); + state.add(i.me); + FlxTween.tween(i.vinceKaichan, {x: 0}, 0.5, {ease: FlxEase.sineOut}); + FlxTween.tween(i.kawaiSprite, {x: FlxG.width - i.kawaiSprite.width}, 0.5, {ease: FlxEase.sineOut}); + FlxTween.tween(i.me, {x: 0}, 0.5, {ease: FlxEase.sineOut}); + }, -2); + AddEvent(() -> + { + FlxG.mouse.visible = origVisibility; + FlxTween.tween(i.vinceKaichan, {x: -i.vinceKaichan.width}, 0.5, {ease: FlxEase.sineInOut}); + FlxTween.tween(i.me, {x: -i.me.width}, 0.5, {ease: FlxEase.sineInOut}); + FlxTween.tween(i.kawaiSprite, {x: FlxG.width}, 0.5, { + ease: FlxEase.sineInOut, + onComplete: (t) -> + { + state.remove(i.vinceKaichan); + state.remove(i.kawaiSprite); + state.remove(i.me); + } + }); + }, 1.82); + } + + override function OverrideCountdown(state:PlayState):Bool + { + state.dad.dance(); + state.gf.dance(); + state.boyfriend.playAnim('idle'); + + var introAssets:Map> = new Map>(); + introAssets.set('default', ['ready', "set", "go"]); + + switch (i.tempSwagCounter) + { + case 0: + FlxG.sound.play(Paths.sound('intro3'), 0.6); + case 1: + var ready:FlxSprite = new FlxSprite().loadGraphic(Paths.image("ready")); + ready.scrollFactor.set(); + ready.updateHitbox(); + ready.screenCenter(); + ready.cameras = [i.camArrows]; + state.add(ready); + FlxTween.tween(ready, {y: ready.y += 100, alpha: 0}, Conductor.crochet / 1000, { + ease: FlxEase.cubeInOut, + onComplete: function(twn:FlxTween) + { + ready.destroy(); + } + }); + FlxG.sound.play(Paths.sound('intro2'), 0.6); + case 2: + var set:FlxSprite = new FlxSprite().loadGraphic(Paths.image("set")); + set.scrollFactor.set(); + set.updateHitbox(); + set.screenCenter(); + set.cameras = [i.camArrows]; + state.add(set); + FlxTween.tween(set, {y: set.y += 100, alpha: 0}, Conductor.crochet / 1000, { + ease: FlxEase.cubeInOut, + onComplete: function(twn:FlxTween) + { + set.destroy(); + } + }); + FlxG.sound.play(Paths.sound('intro1'), 0.6); + case 3: + var go:FlxSprite = new FlxSprite().loadGraphic(Paths.image("go")); + go.scrollFactor.set(); + go.updateHitbox(); + go.screenCenter(); + go.cameras = [i.camArrows]; + state.add(go); + FlxTween.tween(go, {y: go.y += 100, alpha: 0}, Conductor.crochet / 1000, { + ease: FlxEase.cubeInOut, + onComplete: function(twn:FlxTween) + { + go.destroy(); + } + }); + FlxG.sound.play(Paths.sound('introGo'), 0.6); + case 4: + } + + i.tempSwagCounter += 1; + return true; + } + + function ScreenRotates() + { + AddEvent(() -> + { + FlxTween.tween(i.camFake, {angle: -30}, 0.5, {ease: FlxEase.sineInOut}); + FlxTween.tween(i.camArrows, {angle: 30}, 0.5, {ease: FlxEase.sineInOut}); + }, 78.2); + AddEvent(() -> + { + FlxTween.tween(i.ps.camera, {zoom: 2}, 0.1, {ease: FlxEase.sineOut}); + FlxTween.tween(i.camFake, {angle: 360 * 4}, 3.7, {ease: FlxEase.sineOut}); + FlxTween.tween(i.camArrows, {angle: -360 * 4}, 3.7, { + ease: FlxEase.sineOut, + onComplete: (t) -> + { + i.camFake.angle = 0; + i.camArrows.angle = 0; + } + }); + }, 78.72); + AddEvent(() -> + { + FlxTween.tween(i.ps.camera, {zoom: 1}, 3, { + ease: FlxEase.sineInOut + }); + }, 78.92); + } + + function TheFunny() + { + var funny; + } + + function Wobbles() + { + for (e in 0...32) + { + var negate = (e % 2 == 0) ? 1 : -1; + var start = 33.12; + var sync = -0.03; + AddEvent(() -> + { + FlxTween.tween(i, {wobble: 250 * negate}, 0.05, {ease: FlxEase.circIn}); + }, start + sync + 0.96 * e); + AddEvent(() -> + { + FlxTween.tween(i, {wobble: 0}, 0.8, {ease: FlxEase.circOut}); + }, start + sync + 0.06 + 0.96 * e); + } + for (e in 0...32) + { + var negate = (e % 2 == 0) ? 1 : -1; + var start = 63.84; + var sync = -0.03; + AddEvent(() -> + { + FlxTween.tween(i, {wobble: 250 * negate}, 0.05, {ease: FlxEase.circIn}); + }, start + sync + 0.96 * e); + AddEvent(() -> + { + FlxTween.tween(i, {wobble: 0}, 0.8, {ease: FlxEase.circOut}); + }, start + sync + 0.06 + 0.96 * e); + } + } + + function TwistsAndShifts() + { + function TweenPlayfield(x:Float, t:Float) + { + AddEvent(() -> + { + FlxTween.tween(i.camArrows, {x: x}, 0.2, {ease: FlxEase.circOut}); + }, t); + } + for (b in 0...2) + { + for (a in 0...2) + { + var nextMeasure = a * 3.84 + b * 30.72; + TweenPlayfield(-100, 11.76 + nextMeasure); + TweenPlayfield(100, 12.00 + nextMeasure); + TweenPlayfield(-100, 12.24 + nextMeasure); + TweenPlayfield(0, 12.48 + nextMeasure); + } + } + for (b in 0...2) + { + for (a in 0...2) + { + var nextMeasure = a * 7.68 + b * 30.72; + AddEvent(() -> + { + FlxTween.tween(i, {spin: 0.8}, 0.2, {ease: FlxEase.circOut}); + FlxTween.tween(i.camFake, {angle: -10}, 0.2, {ease: FlxEase.circOut}); + FlxTween.tween(i.camArrows, {angle: 10}, 0.2, {ease: FlxEase.circOut}); + }, 20.40 + nextMeasure); + AddEvent(() -> + { + FlxTween.tween(i, {spin: 1.1}, 0.2, {ease: FlxEase.circInOut}); + FlxTween.tween(i.camFake, {angle: 10}, 0.2, {ease: FlxEase.circInOut}); + FlxTween.tween(i.camArrows, {angle: -10}, 0.2, {ease: FlxEase.circInOut}); + }, 20.64 + nextMeasure); + AddEvent(() -> + { + FlxTween.tween(i, {spin: 0.8}, 0.2, {ease: FlxEase.circInOut}); + FlxTween.tween(i.camFake, {angle: -10}, 0.2, {ease: FlxEase.circInOut}); + FlxTween.tween(i.camArrows, {angle: 10}, 0.2, {ease: FlxEase.circInOut}); + }, 20.88 + nextMeasure); + AddEvent(() -> + { + FlxTween.tween(i, {spin: 1}, 0.2, {ease: FlxEase.circOut}); + FlxTween.tween(i.camFake, {angle: 0}, 0.2, {ease: FlxEase.circOut}); + FlxTween.tween(i.camArrows, {angle: 0}, 0.2, {ease: FlxEase.circOut}); + }, 21.12 + nextMeasure); + } + } + } + + function IntroPerc() + { + function TweenReceptors(invFreq:Float, amp:Float, t:Float) + { + AddEvent(() -> + { + for (staticArrow in i.staticArrows) + { + staticArrow.y = i.ps.strumLine.y + Math.sin(staticArrow.x / invFreq) * amp; + FlxTween.tween(staticArrow, {y: i.ps.strumLine.y}, 0.2, {ease: FlxEase.circOut}); + } + }, t); + } + function SetReceptors(invFreq:Float, off:Float, amp:Float, t:Float) + { + AddEvent(() -> + { + for (staticArrow in i.staticArrows) + { + staticArrow.y = i.ps.strumLine.y + Math.sin(staticArrow.x / invFreq + off) * amp; + } + }, t); + } + TweenReceptors(100, 50, 0); + TweenReceptors(100, 50, .36); + TweenReceptors(100, 50, .72); + SetReceptors(80, 1, 30, .96); + SetReceptors(60, 2, -30, 1.08); + SetReceptors(50, 3, 30, 1.2); + SetReceptors(40, 4, -30, 1.44); + + for (z in 0...4) + { + AddEvent(() -> + { + var alt = z % 2 == 0 ? 1 : -1; + for (staticArrow in i.staticArrows) + { + staticArrow.y = i.ps.strumLine.y + Math.sin(staticArrow.x / 50 + 5 + z) * 40 * alt; + } + }, 1.68 + z * 0.06); + } + AddEvent(() -> + { + for (staticArrow in i.staticArrows) + { + FlxTween.tween(staticArrow, {y: i.ps.strumLine.y}, 0.2, {ease: FlxEase.circOut}); + } + }, 1.92); + } + + function AddModEvents() + { + TheFunny(); + Credits(); + IntroPerc(); + AddEvent(() -> + { + i.bounceCam = true; + }, 1.92); + TwistsAndShifts(); + Wobbles(); + AddEvent(() -> + { + i.spinAmp = 0; + FlxTween.tween(i, {spinAmp: 1}, 0.5, {ease: FlxEase.sineInOut}); + FlxTween.tween(i, {spinOff: 0}, 0.5, {ease: FlxEase.sineInOut}); + i.doSpin = true; + }, 63.36); + AddEvent(() -> + { + FlxTween.tween(i, {spinAmp: 0}, 0.5, {ease: FlxEase.sineInOut}); + FlxTween.tween(i, {spinOff: 1}, 0.5, {ease: FlxEase.sineInOut}); + }, 72.72); + AddEvent(() -> + { + i.doSpin = false; + }, 73.22); + ScreenRotates(); + ChorusTwists(); + } + + function ChorusTwists() + { + for (x in 0...8) + { + var off = 1.92 * x; + AddEvent(() -> + { + i.staticArrowWave = 90; + i.camFake.angle = -10; + i.camArrows.angle = 10; + FlxTween.tween(i, {staticArrowWave: 0}, 0.7, {ease: FlxEase.circOut}); + FlxTween.tween(i.camFake, {angle: 0}, 0.5, {ease: FlxEase.circOut}); + FlxTween.tween(i.camArrows, {angle: 0}, 0.5, {ease: FlxEase.circOut}); + }, 63.36 + off); + AddEvent(() -> + { + i.staticArrowWave = 90; + i.camFake.angle = 10; + i.camArrows.angle = -10; + FlxTween.tween(i, {staticArrowWave: 0}, 0.3, {ease: FlxEase.circOut}); + FlxTween.tween(i.camFake, {angle: 0}, 0.5, {ease: FlxEase.circOut}); + FlxTween.tween(i.camArrows, {angle: 0}, 0.5, {ease: FlxEase.circOut}); + }, 64.56 + off); + } + for (x in 0...8) + { + var off = 1.92 * x; + AddEvent(() -> + { + i.staticArrowWave = 90; + i.camFake.angle = -10; + i.camArrows.angle = 10; + FlxTween.tween(i, {staticArrowWave: 0}, 0.7, {ease: FlxEase.circOut}); + FlxTween.tween(i.camFake, {angle: 0}, 0.5, {ease: FlxEase.circOut}); + FlxTween.tween(i.camArrows, {angle: 0}, 0.5, {ease: FlxEase.circOut}); + }, 82.56 + off); + AddEvent(() -> + { + i.staticArrowWave = 90; + i.camFake.angle = 10; + i.camArrows.angle = -10; + FlxTween.tween(i, {staticArrowWave: 0}, 0.3, {ease: FlxEase.circOut}); + FlxTween.tween(i.camFake, {angle: 0}, 0.5, {ease: FlxEase.circOut}); + FlxTween.tween(i.camArrows, {angle: 0}, 0.5, {ease: FlxEase.circOut}); + }, 83.76 + off); + } + } + + function UpdateEvents(elapsed:Float, list:List) + { + for (event in list) + { + if (Conductor.songPosition >= event.time && !event.dirty) + { + event.callback(i.ps); + event.dirty = true; + } + } + } + + function UpdateButton(elapsed:Float) + { + if (FlxG.mouse.justPressed && i.me != null) + { + if (FlxG.mouse.overlaps(i.vinceKaichan)) + { + FlxG.openURL('https://soundcloud.com/vincmg'); + } + else if (FlxG.mouse.overlaps(i.kawaiSprite)) + { + FlxG.openURL('https://open.spotify.com/artist/19nnKeOt6Vo1g0ijPcFxdu'); + } + else if (FlxG.mouse.overlaps(i.me)) + { + FlxG.openURL('https://www.youtube.com/channel/UCez-Erpr0oqmC71vnDrM9yA'); + } + } + } + + override function Update(elapsed:Float) + { + UpdateEvents(elapsed, i.heyEvents); + UpdateCamera(elapsed); + UpdateStaticArrows(elapsed); + } + + function UpdateStaticArrows(elapsed:Float) + { + if (i.doSpin) + { + i.spin = Math.sin(Conductor.songPosition / Conductor.crochet * Math.PI) * i.spinAmp + i.spinOff; + } + var staticNoteNum = 0; + i.ps.strumLineNotes.forEach((staticNote) -> + { + // For convenience + i.staticArrows[staticNoteNum] = staticNote; + + var player:Int = staticNoteNum >= 4 ? 1 : 0; + staticNote.x = staticNoteNum % 4 * Note.swagWidth + FlxG.width / 2 * player + 80; + if (i.staticArrowWave != 0) + { + staticNote.y = i.ps.strumLine.y + + Math.sin(Conductor.songPosition / Conductor.crochet + staticNote.x) * i.staticArrowWave + + i.staticArrowWave * 0.5; + } + var center = FlxG.width / 2 - Note.swagWidth / 2; + var distFromCenter = staticNote.x - center; + staticNote.x = center + distFromCenter * i.spin; + staticNoteNum++; + }); + } + + override function ModWeekData():Array + { + return [ + new ModWeekData(["Bopeebo Rumble"], "clearly you've never played NotITG", ["dad", "bf", "gf"]) + ]; + } + + override function GetDisplayName():String + { + return "Bopeebo Rumble (Demo) by 4mbr0s3 2"; + } + + // After camera is tracked to camFollow + override function PreUI(state:PlayState) + { + i.camFake.targetOffset.set(-FlxG.width / 2, -FlxG.height / 2); + i.camFake.follow(state.camFollow, LOCKON, 0.04); + state.add(i.camFake); + + // After strumLine is defined + i.susWiggleEffect = new WiggleEffect(); + i.susWiggleEffect.effectType = WiggleEffectType.DREAMY; + i.susWiggleEffect.waveSpeed = 1; + // Subtract 4 x note width phase shift cuz sine ain't 0 at strumLine for some reason?? + + var downscrollNegator = ModHooks.mods.filter(e -> e.GetName() == "KadeDownscroll").length > 0; + + i.susWiggleEffect.shader.uTime.value = [(-state.strumLine.y - Note.swagWidth * 0.5) / FlxG.height]; + if (downscrollNegator) + { + i.susWiggleEffect.shader.uTime.value = [(-state.strumLine.y - Note.swagWidth * 10.3) / FlxG.height]; + } + i.susWiggleEffect.waveFrequency = Math.PI * 3; + + i.planeRaymarcher = new PlaneRaymarcher(); + i.camArrows.setFilters([new ShaderFilter(i.planeRaymarcher.shader),]); + i.camSus.setFilters([ + new ShaderFilter(i.susWiggleEffect.shader), + new ShaderFilter(i.planeRaymarcher.shader) + ]); + } + + function UpdateCamera(elapsed:Float) + { + i.ps.camGame.angle = i.camFake.angle; + if (i.bounceCam) + { + i.ps.camGame.scroll.set(i.camFake.scroll.x, i.camFake.scroll.y + -Math.abs(Math.sin(Conductor.songPosition / Conductor.crochet * Math.PI) * 30)); + i.camArrows.setPosition(i.camArrows.x, Math.abs(Math.sin(Conductor.songPosition / Conductor.crochet * Math.PI) * 50)); + } + i.camSus.scroll = i.camArrows.scroll; + i.camSus.setPosition(i.camArrows.x, i.camArrows.y); + i.camSus.angle = i.camArrows.angle; + + i.susWiggleEffect.waveAmplitude = i.wobble / FlxG.width; + + i.planeRaymarcher.update(elapsed); + } + + override function PostNotePosition(state:PlayState, strumLine:FlxSprite, daNote:Note, SONG:SwagSong) + { + // daNote.y = (state.strumLine.y - (Conductor.songPosition - daNote.strumTime) * (0.45 * FlxMath.roundDecimal(SONG.speed, 2))); + var columnX = 50 + + daNote.noteData * Note.swagWidth + + (daNote.mustPress ? (FlxG.width / 2) : 0) + + (daNote.isSustainNote ? Note.swagWidth / 2 - daNote.width / 2 : 0); + + var firstFourDad = 0; + if (!daNote.mustPress) + { + state.strumLineNotes.forEach((staticNote) -> + { + firstFourDad++; + if (firstFourDad > 4) + return; + if (daNote.noteData == staticNote.ID) + { + columnX = staticNote.x; + daNote.y += staticNote.y - state.strumLine.y; + return; + } + }); + } + else + { + state.playerStrums.forEach((staticNote) -> + { + if (daNote.mustPress && daNote.noteData == staticNote.ID) + { + columnX = staticNote.x; + daNote.y += staticNote.y - state.strumLine.y; + return; + } + }); + } + columnX += (daNote.isSustainNote ? Note.swagWidth / 2 - daNote.width / 2 : 0); + var time = (Conductor.songPosition - daNote.strumTime) * (0.45 * FlxMath.roundDecimal(SONG.speed, 2)) / FlxG.height; + daNote.x = columnX; + if (!daNote.isSustainNote) + { + daNote.x = columnX + Math.sin(time * Math.PI * 3) * i.wobble; + } + } + + override function Initialize() + { + trace("Successfully initialized Bopeebo Rumble mod! Switching to Freeplay..."); + var fp = new BonusSongsState(); + // new FlxTimer().start(1, function(tmr:FlxTimer) + // { + // fp.curSelected = fp.songs.length - 1; + // FlxG.switchState(fp); + // }); + } + + override function PreCameras(state:PlayState) + { + i = new BopeeboRumbleModInstance(); + + i.camFake = new FlxCamera(); + + i.ps = state; + i.heyEvents = new List(); + + i.camSus = new FlxCamera(); + i.camSus.bgColor.alpha = 0; + + i.camArrows = new FlxCamera(); + i.camArrows.bgColor.alpha = 0; + + AddHeys(); + AddModEvents(); + } + + override function PostUI(state:PlayState) + { + state.strumLineNotes.cameras = [i.camArrows]; + } + + override function AfterCameras(camGame:FlxCamera, camHUD:FlxCamera) + { + camGame.width = FlxG.width * 2; + camGame.height = FlxG.height * 2; + camGame.setPosition(-FlxG.width / 2, -FlxG.height / 2); + FlxG.cameras.add(i.camSus); + FlxG.cameras.add(i.camArrows); + } + + override function OnSpawnNote(state:PlayState, note:Note) + { + if (note.isSustainNote) + { + note.cameras = [i.camSus]; + } + else + { + note.cameras = [i.camArrows]; + } + } + + override function SetupStage(stageName:String) + { + i.ps.transIn = null; + i.ps.transOut = null; + AddBackground(); + } + + function AddBackground() + { + i.ps.defaultCamZoom = 0.9; + PlayState.curStage = 'stage'; + var bg:FlxSprite = new FlxSprite(-600, -200).loadGraphic(Paths.image('stageback')); + bg.antialiasing = true; + bg.scrollFactor.set(0.9, 0.9); + bg.active = false; + i.ps.add(bg); + + var stageFront:FlxSprite = new FlxSprite(-650, 600).loadGraphic(Paths.image('stagefront')); + stageFront.setGraphicSize(Std.int(stageFront.width * 1.1)); + stageFront.updateHitbox(); + stageFront.antialiasing = true; + stageFront.scrollFactor.set(0.9, 0.9); + stageFront.active = false; + i.ps.add(stageFront); + + var stageCurtains:FlxSprite = new FlxSprite(-500, -300).loadGraphic(Paths.image('stagecurtains')); + stageCurtains.setGraphicSize(Std.int(stageCurtains.width * 0.9)); + stageCurtains.updateHitbox(); + stageCurtains.antialiasing = true; + stageCurtains.scrollFactor.set(1.3, 1.3); + stageCurtains.active = false; + + i.ps.add(stageCurtains); + } + + override function AddToBonus(addWeek:(Array, Int, Array) -> Void, weekNum:Int) + { + addWeek(["Bopeebo Rumble"], weekNum, ['dad']); + } +} \ No newline at end of file diff --git a/source/Boyfriend.hx b/source/Boyfriend.hx index 85832eba9..0f1fec9b3 100644 --- a/source/Boyfriend.hx +++ b/source/Boyfriend.hx @@ -9,16 +9,16 @@ using StringTools; class Boyfriend extends Character { - public var startedDeath:Bool = false; + public var stunned:Bool = false; - public function new(x:Float, y:Float, ?char:String = 'bf') + public function new(x:Float, y:Float, ?char:String = 'bf', ?isPlayer:Bool = true) { - super(x, y, char, true); + super(x, y, char, isPlayer); } override function update(elapsed:Float) { - if (!debugMode && animation.curAnim != null) + if (!debugMode) { if (animation.curAnim.name.startsWith('sing')) { @@ -29,10 +29,18 @@ class Boyfriend extends Character if (animation.curAnim.name.endsWith('miss') && animation.curAnim.finished && !debugMode) { - playAnim('idle', true, false, 10); + if (!animOffsets.exists('idle')) + { + dance(); + } + + else + { + playAnim('idle', true, false, 10); + } } - if (animation.curAnim.name == 'firstDeath' && animation.curAnim.finished && startedDeath) + if (animation.curAnim.name == 'firstDeath' && animation.curAnim.finished) { playAnim('deathLoop'); } diff --git a/source/Bright.hx b/source/Bright.hx new file mode 100644 index 000000000..d17333af4 --- /dev/null +++ b/source/Bright.hx @@ -0,0 +1,26 @@ +package; + +import flixel.system.FlxAssets.FlxShader; + +class Bright extends FlxShader +{ + @:glFragmentSource(' + #pragma header + + uniform float brightness; + uniform float contrast; + + void main() + { + vec4 fUse = texture2D(bitmap, openfl_TextureCoordv); + vec3 contrasted = fUse.rgb * contrast; + vec3 finalUse = contrasted + vec3(brightness, brightness, brightness); + fUse.rgb = finalUse; + + gl_FragColor = fUse; + }') + public function new() + { + super(); + } +} diff --git a/source/BrowserVideoPlayer.hx b/source/BrowserVideoPlayer.hx new file mode 100644 index 000000000..e53ad48f5 --- /dev/null +++ b/source/BrowserVideoPlayer.hx @@ -0,0 +1,45 @@ +package; + +import flixel.text.FlxText; +import flixel.FlxG; +import flixel.FlxBasic; + +import extension.webview.WebView; + +using StringTools; + +class BrowserVideoPlayer extends FlxBasic +{ + public static var androidPath:String = 'file://';//ok + public var finishCallback:Void->Void = null; + + public function new(path:String) + { + super(); + + WebView.onClose = onClose; + WebView.onURLChanging= onURLChanging; + + WebView.open(androidPath + path, false, null, ['http://exitme(.*)']); + } + + public override function update(dt:Float) + { + super.update(dt); + } + + function onClose() + { + if (finishCallback != null) + { + finishCallback(); + } + } + + function onURLChanging(url:String) + { + if (url == 'http://exitme/') + onClose(); // drity hack lol + trace("WebView is about to open: "+url); + } +} diff --git a/source/Caching.hx b/source/Caching.hx new file mode 100644 index 000000000..1bbdf50d8 --- /dev/null +++ b/source/Caching.hx @@ -0,0 +1,188 @@ +package; + +import lime.app.Application; +#if windows +import Discord.DiscordClient; +#end +import openfl.display.BitmapData; +import openfl.utils.Assets; +import flixel.ui.FlxBar; +import haxe.Exception; +import flixel.tweens.FlxEase; +import flixel.tweens.FlxTween; +import sys.FileSystem; +import sys.io.File; +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.addons.transition.FlxTransitionSprite.GraphicTransTileDiamond; +import flixel.addons.transition.FlxTransitionableState; +import flixel.addons.transition.TransitionData; +import flixel.graphics.FlxGraphic; +import flixel.graphics.frames.FlxAtlasFrames; +import flixel.math.FlxPoint; +import flixel.math.FlxRect; +import flixel.util.FlxColor; +import flixel.util.FlxTimer; +import flixel.text.FlxText; + +using StringTools; + +class Caching extends MusicBeatState +{ + var toBeDone = 0; + var done = 0; + + var loaded = false; + + var text:FlxText; + var kadeLogo:FlxSprite; + + public static var bitmapData:Map; + + var images = []; + var music = []; + var charts = []; + + + override function create() + { + FlxG.mouse.visible = false; + + FlxG.worldBounds.set(0,0); + + bitmapData = new Map(); + + text = new FlxText(FlxG.width / 2, FlxG.height / 2 + 300,0,"Loading..."); + text.size = 34; + text.alignment = FlxTextAlign.CENTER; + text.alpha = 0; + + kadeLogo = new FlxSprite(FlxG.width / 2, FlxG.height / 2).loadGraphic(Paths.image('KadeEngineLogo')); + kadeLogo.x -= kadeLogo.width / 2; + kadeLogo.y -= kadeLogo.height / 2 + 100; + text.y -= kadeLogo.height / 2 - 125; + text.x -= 170; + kadeLogo.setGraphicSize(Std.int(kadeLogo.width * 0.6)); + + kadeLogo.alpha = 0; + + PlayerSettings.init(); + + #if windows + DiscordClient.initialize(); + + Application.current.onExit.add (function (exitCode) { + DiscordClient.shutdown(); + }); + + #end + + + Highscore.load(); + + FlxG.save.bind('funkin', 'ninjamuffin99'); + + KadeEngineData.initSave(); + + + if (FlxG.save.data.cacheImages) + { + trace("caching images..."); + + for (i in FileSystem.readDirectory(FileSystem.absolutePath("assets/shared/images/characters"))) + { + if (!i.endsWith(".png")) + continue; + images.push(i); + } + } + + trace("caching music..."); + + for (i in FileSystem.readDirectory(FileSystem.absolutePath("assets/songs"))) + { + music.push(i); + } + + + toBeDone = Lambda.count(images) + Lambda.count(music); + + var bar = new FlxBar(10,FlxG.height - 50,FlxBarFillDirection.LEFT_TO_RIGHT,FlxG.width,40,null,"done",0,toBeDone); + bar.color = FlxColor.PURPLE; + + add(bar); + + add(kadeLogo); + add(text); + + trace('starting caching..'); + + // update thread + + sys.thread.Thread.create(() -> { + while(!loaded) + { + if (toBeDone != 0 && done != toBeDone) + { + var alpha = HelperFunctions.truncateFloat(done / toBeDone * 100,2) / 100; + kadeLogo.alpha = alpha; + text.alpha = alpha; + text.text = "Loading... (" + done + "/" + toBeDone + ")"; + } + } + + }); + + // cache thread + + sys.thread.Thread.create(() -> { + cache(); + }); + + super.create(); + } + + var calledDone = false; + + override function update(elapsed) + { + super.update(elapsed); + } + + + function cache() + { + + trace("LOADING: " + toBeDone + " OBJECTS."); + + for (i in images) + { + var replaced = i.replace(".png",""); + var data:BitmapData = BitmapData.fromFile("assets/shared/images/characters/" + i); + trace('id ' + replaced + ' file - assets/shared/images/characters/' + i + ' ${data.width}'); + var graph = FlxGraphic.fromBitmapData(data); + graph.persist = true; + graph.destroyOnNoUse = false; + bitmapData.set(replaced,graph); + done++; + } + + for (i in music) + { + FlxG.sound.cache(Paths.inst(i)); + FlxG.sound.cache(Paths.voices(i)); + trace("cached " + i); + done++; + } + + + trace("Finished caching..."); + + loaded = true; + + trace(Assets.cache.hasBitmapData('GF_assets')); + + FlxG.switchState(new TitleState()); + } + +} \ No newline at end of file diff --git a/source/Character.hx b/source/Character.hx index 05aa021f2..9c5e50fcf 100644 --- a/source/Character.hx +++ b/source/Character.hx @@ -1,314 +1,1945 @@ -package; - -import flixel.FlxG; -import flixel.FlxSprite; -import flixel.animation.FlxBaseAnimation; -import flixel.graphics.frames.FlxAtlasFrames; -import flixel.tweens.FlxTween; -import flixel.util.FlxSort; -import Section.SwagSection; -#if MODS_ALLOWED -import sys.io.File; -import sys.FileSystem; -#end -import openfl.utils.Assets; -import haxe.Json; -import haxe.format.JsonParser; - -using StringTools; - -typedef CharacterFile = { - var animations:Array; - var image:String; - var scale:Float; - var sing_duration:Float; - var healthicon:String; - - var position:Array; - var camera_position:Array; - - var flip_x:Bool; - var no_antialiasing:Bool; - var healthbar_colors:Array; -} - -typedef AnimArray = { - var anim:String; - var name:String; - var fps:Int; - var loop:Bool; - var indices:Array; - var offsets:Array; -} - -class Character extends FlxSprite -{ - public var animOffsets:Map>; - public var debugMode:Bool = false; - - public var isPlayer:Bool = false; - public var curCharacter:String = DEFAULT_CHARACTER; - - public var colorTween:FlxTween; - public var holdTimer:Float = 0; - public var heyTimer:Float = 0; - public var specialAnim:Bool = false; - public var animationNotes:Array = []; - public var stunned:Bool = false; - public var singDuration:Float = 4; //Multiplier of how long a character holds the sing pose - public var idleSuffix:String = ''; - public var danceIdle:Bool = false; //Character use "danceLeft" and "danceRight" instead of "idle" - - public var healthIcon:String = 'face'; - public var animationsArray:Array = []; - - public var positionArray:Array = [0, 0]; - public var cameraPosition:Array = [0, 0]; - - public var hasMissAnimations:Bool = false; - - //Used on Character Editor - public var imageFile:String = ''; - public var jsonScale:Float = 1; - public var noAntialiasing:Bool = false; - public var originalFlipX:Bool = false; - public var healthColorArray:Array = [255, 0, 0]; - public var alreadyLoaded:Bool = true; //Used by "Change Character" event - - public static var DEFAULT_CHARACTER:String = 'bf'; //In case a character is missing, it will use BF on its place - public function new(x:Float, y:Float, ?character:String = 'bf', ?isPlayer:Bool = false) - { - super(x, y); - - #if (haxe >= "4.0.0") - animOffsets = new Map(); - #else - animOffsets = new Map>(); - #end - curCharacter = character; - this.isPlayer = isPlayer; - antialiasing = ClientPrefs.globalAntialiasing; - - var library:String = null; - switch (curCharacter) - { - //case 'your character name in case you want to hardcode him instead': - - default: - var characterPath:String = 'characters/' + curCharacter + '.json'; - var path:String = Paths.modFolders(characterPath); - if (!FileSystem.exists(path)) { - path = Main.getDataPath() + Paths.getPreloadPath(characterPath); - } - - if (!FileSystem.exists(path)) - { - path = Main.getDataPath() + Paths.getPreloadPath('characters/' + DEFAULT_CHARACTER + '.json'); //If a character couldn't be found, change him to BF just to prevent a crash - } - - var rawJson = File.getContent(path); - - var json:CharacterFile = cast Json.parse(rawJson); - var txtToFind:String = Paths.getPath('images/' + json.image + '.txt', TEXT); - if(FileSystem.exists(txtToFind) || Assets.exists(txtToFind)) - { - //bozo forgot about the packer shits : P - frames = Paths.getPackerAtlas(json.image); - } - else - { - frames = Paths.getSparrowAtlas(json.image); - } - imageFile = json.image; - - if(json.scale != 1) { - jsonScale = json.scale; - setGraphicSize(Std.int(width * jsonScale)); - updateHitbox(); - } - - positionArray = json.position; - cameraPosition = json.camera_position; - - healthIcon = json.healthicon; - singDuration = json.sing_duration; - flipX = !!json.flip_x; - if(json.no_antialiasing) { - antialiasing = false; - noAntialiasing = true; - } - - if(json.healthbar_colors != null && json.healthbar_colors.length > 2) - healthColorArray = json.healthbar_colors; - - antialiasing = !noAntialiasing; - if(!ClientPrefs.globalAntialiasing) antialiasing = false; - - animationsArray = json.animations; - if(animationsArray != null && animationsArray.length > 0) { - for (anim in animationsArray) { - var animAnim:String = '' + anim.anim; - var animName:String = '' + anim.name; - var animFps:Int = anim.fps; - var animLoop:Bool = !!anim.loop; //Bruh - var animIndices:Array = anim.indices; - if(animIndices != null && animIndices.length > 0) { - animation.addByIndices(animAnim, animName, animIndices, "", animFps, animLoop); - } else { - animation.addByPrefix(animAnim, animName, animFps, animLoop); - } - - if(anim.offsets != null && anim.offsets.length > 1) { - addOffset(anim.anim, anim.offsets[0], anim.offsets[1]); - } - } - } else { - quickAnimAdd('idle', 'BF idle dance'); - } - //trace('Loaded file to character ' + curCharacter); - } - originalFlipX = flipX; - - if(animOffsets.exists('singLEFTmiss') || animOffsets.exists('singDOWNmiss') || animOffsets.exists('singUPmiss') || animOffsets.exists('singRIGHTmiss')) hasMissAnimations = true; - recalculateDanceIdle(); - dance(); - - if (isPlayer) - { - flipX = !flipX; - - /*// Doesn't flip for BF, since his are already in the right place??? - if (!curCharacter.startsWith('bf')) - { - // var animArray - if(animation.getByName('singLEFT') != null && animation.getByName('singRIGHT') != null) - { - 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('singLEFTmiss') != null && 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(!debugMode && animation.curAnim != null) - { - if(heyTimer > 0) - { - heyTimer -= elapsed; - if(heyTimer <= 0) - { - if(specialAnim && animation.curAnim.name == 'hey' || animation.curAnim.name == 'cheer') - { - specialAnim = false; - dance(); - } - heyTimer = 0; - } - } else if(specialAnim && animation.curAnim.finished) - { - specialAnim = false; - dance(); - } - - if (!isPlayer) - { - if (animation.curAnim.name.startsWith('sing')) - { - holdTimer += elapsed; - } - - if (holdTimer >= Conductor.stepCrochet * 0.001 * singDuration) - { - dance(); - holdTimer = 0; - } - } - - if(animation.curAnim.finished && animation.getByName(animation.curAnim.name + '-loop') != null) - { - playAnim(animation.curAnim.name + '-loop'); - } - } - super.update(elapsed); - } - - public var danced:Bool = false; - - /** - * FOR GF DANCING SHIT - */ - public function dance() - { - if (!debugMode && !specialAnim) - { - if(danceIdle) - { - danced = !danced; - - if (danced) - playAnim('danceRight' + idleSuffix); - else - playAnim('danceLeft' + idleSuffix); - } - else if(animation.getByName('idle' + idleSuffix) != null) { - playAnim('idle' + idleSuffix); - } - } - } - - public function playAnim(AnimName:String, Force:Bool = false, Reversed:Bool = false, Frame:Int = 0):Void - { - specialAnim = false; - animation.play(AnimName, Force, Reversed, Frame); - - var daOffset = animOffsets.get(AnimName); - if (animOffsets.exists(AnimName)) - { - offset.set(daOffset[0], daOffset[1]); - } - else - offset.set(0, 0); - - if (curCharacter.startsWith('gf')) - { - if (AnimName == 'singLEFT') - { - danced = true; - } - else if (AnimName == 'singRIGHT') - { - danced = false; - } - - if (AnimName == 'singUP' || AnimName == 'singDOWN') - { - danced = !danced; - } - } - } - - public function recalculateDanceIdle() { - danceIdle = (animation.getByName('danceLeft' + idleSuffix) != null && animation.getByName('danceRight' + idleSuffix) != null); - } - - public function addOffset(name:String, x:Float = 0, y:Float = 0) - { - animOffsets[name] = [x, y]; - } - - public function quickAnimAdd(name:String, anim:String) - { - animation.addByPrefix(name, anim, 24, false); - } -} +package; + +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.animation.FlxBaseAnimation; +import flixel.graphics.frames.FlxAtlasFrames; +import flixel.util.FlxColor; +import lime.app.Application; +import flash.display.BitmapData; +import flixel.graphics.FlxGraphic; +import haxe.xml.Fast; + +#if desktop +import Sys; +import sys.FileSystem; +import sys.io.File; +#end + +import openfl.net.FileReference; +import openfl.events.Event; +import openfl.events.IOErrorEvent; + +import haxe.Json; +import haxe.format.JsonParser; +import lime.utils.Assets; +import flixel.text.FlxText; +import haxe.xml.Access; +import flixel.math.FlxMath; + +using StringTools; + +typedef CharacterFile = { + var animations:Array; + var playerAnimations:Array; //bcuz garcello + var image:String; + var scale:Float; + var sing_duration:Float; + var healthicon:String; + + var position:Array; + var playerposition:Array; //bcuz dammit some of em don't exactly flip right + var camera_position:Array; + var player_camera_position:Array; + + var flip_x:Bool; + var no_antialiasing:Bool; + var healthbar_colors:Array; + var noteSkin:String; + var isPlayerChar:Bool; +} + +typedef AnimArray = { + var anim:String; + var name:String; + var fps:Int; + var loop:Bool; + var indices:Array; + var offsets:Array; + var playerOffsets:Array; +} + +class Character extends FlxSprite +{ + public var animOffsets:Map>; + public var animPlayerOffsets:Map>; //for saving as jsons lol + public var debugMode:Bool = false; + + public var isPlayer:Bool = false; + public var curCharacter:String = 'bf'; + public var heyTimer:Float = 0; + public var specialAnim:Bool = false; + public var isCustom:Bool = false; + public var altAnim:String = ''; + public var bfAltAnim:String = ''; + public var danceIdle:Bool = false; //Character use "danceLeft" and "danceRight" instead of "idle" "-- why didn't i think of this?" + + public var isPixel:Bool = false; + public var noteSkin:String; + public var isPsychPlayer:Bool; + public var healthIcon:String = 'bf'; + public var doMissThing:Bool = false; + public var iconColor:String; + public var trailColor:String; + + public var holdTimer:Float = 0; + + public var daZoom:Float = 1; + + public var tex:FlxAtlasFrames; + public var exSpikes:FlxSprite; + public var charPath:String; + + public static var colorPreString:FlxColor; + public static var colorPreCut:String; + var weZoomed:Bool = false; + public var flipMode:Bool = false; + + var pre:String = ""; + + //psych method. yay! + public var imageFile:String = ''; + public var jsonScale:Float = 1; + public var noAntialiasing:Bool = false; + public var originalFlipX:Bool = false; + public var healthColorArray:Array = [255, 0, 0]; + public var positionArray:Array = [0, 0]; + public var playerPositionArray:Array = [0, 0]; + public var cameraPosition:Array = [0, 0]; + public var playerCameraPosition:Array = [0, 0]; + public var singDuration:Float = 4; //Multiplier of how long a character holds the sing pose + public var animationsArray:Array = []; + public var stopIdle:Bool = false; + + public function new(x:Float, y:Float, ?character:String = "bf", ?isPlayer:Bool = false) + { + super(x, y); + + animOffsets = new Map>(); + animPlayerOffsets = new Map>(); + curCharacter = character; + healthIcon = character; + this.isPlayer = isPlayer; + iconColor = isPlayer ? 'FF66FF33' : 'FFFF0000'; + trailColor = isPlayer ? "FF0026FF" : "FFAA0044"; + + antialiasing = true; + isCustom = false; + pre = ""; + noteSkin = PlayState.SONG.noteStyle; + + switch (curCharacter) + { + case 'gf-special' | 'gf-demon' | 'gf-bw' | 'gf-hex' | 'gf-pico' | 'gf-cassandra-bw' | 'gf-alya-bw' | 'gf-pico-bw' | 'gf-monika-bw' + | 'madgf-christmas' | 'gf-arcade' | 'gf-b3' | 'gf-aloe' | 'gf-pelo-spooky' | 'gf-bf' | 'gf-bf-bw' | 'gf-demona' | 'gf-bw2' | 'gf-mii' | 'gfHalloween' | 'gf-kaguya': + // GIRLFRIEND CODE + switch (curCharacter) + { + case 'gf-demon': frames = getCharPath('characters/GF_demon_assets'); + case 'gf-arcade': frames = getCharPath('characters/GF_arcade_assets'); + case 'gf-special': frames = getCharPath('characters/GF_Special'); + case 'madgf-christmas': frames = getCharPath('characters/madgfChristmas'); + case 'gf-hex': frames = getCharPath('characters/GF_Hex_assets'); + case 'gf-pico': frames = getCharPath('characters/GF_Pico_assets'); + case 'gf-cassandra-bw': frames = getCharPath('characters/bw/Cassandra_GF_assets'); + case 'gf-alya-bw': frames = getCharPath('characters/bw/GF_Alya_assets'); + case 'gf-pico-bw': frames = getCharPath('characters/bw/GF_Pico_assets'); + case 'gf-monika-bw': frames = getCharPath('characters/bw/Monika_GF_assets'); + case 'gf-b3': frames = getCharPath('characters/b3/GF_assets'); + case 'gf-aloe': frames = getCharPath('characters/GF_Aloe_assets'); + case 'gf-pelo-spooky': frames = getCharPath('characters/GF_assets_pelo_spooky'); + case 'gf-bf': frames = getCharPath('characters/GF_BF_assets'); + case 'gf-bf-bw': frames = getCharPath('characters/bw/GF_BF_assets'); + case 'gf-demona': frames = getCharPath('characters/demona'); + case 'gfHalloween': frames = getCharPath('characters/GF_assets_halloween'); + case 'gf-kaguya': frames = getCharPath('characters/Kaguya_GF_assets'); + case 'gf-mii': frames = getCharPath('characters/GF_MII_assets'); + case 'gf-bw' | 'gf-bw2': + if (curCharacter == 'gf-bw2') pre = '_2'; + frames = getCharPath('characters/bw/GF_assets'+pre); + } + + addAnimationByPrefix('cheer', 'GF Cheer', 24, false); + addAnimationByPrefix('singLEFT', 'GF left note', 24, false); + addAnimationByPrefix('singRIGHT', 'GF Right Note', 24, false); + addAnimationByPrefix('singUP', 'GF Up Note', 24, false); + addAnimationByPrefix('singDOWN', 'GF Down Note', 24, false); + addAnimationByIndices('sad', 'gf sad', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], "", 24, false); + addAnimationByIndices('danceLeft', 'GF Dancing Beat', [30, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false); + addAnimationByIndices('danceRight', 'GF Dancing Beat', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false); + addAnimationByIndices('hairBlow', "GF Dancing Beat Hair blowing", [0, 1, 2, 3], "", 24); + addAnimationByIndices('hairFall', "GF Dancing Beat Hair Landing", [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "", 24, false); + addAnimationByPrefix('scared', 'GF FEAR', 24); + addAnimationByPrefix('transform', 'GF Transform', 24, false); + + loadOffsetFile('gf'); + + playAnim('danceRight'); + + case 'gf-tankman-pixel' | 'gf-pixel-mario' | 'amy-pixel-mario' | 'piper-pixel-mario' | 'piper-pixeld2' | 'gf-pixel-neon' | 'gf-playtime' | 'nogf-pixel' | 'gf-edgeworth-pixel' | 'gf-flowey' + | 'gf-tea-pixel': + switch (curCharacter) + { + case 'gf-tankman-pixel': + frames = getCharPath('characters/gfTankmanPixel'); + case 'gf-pixel-mario': + frames = getCharPath('characters/gfPixelMario'); + case 'amy-pixel-mario': + frames = getCharPath('characters/amyPixelMario'); + case 'piper-pixel-mario': + frames = getCharPath('characters/piperPixelMario'); + case 'piper-pixeld2': + frames = getCharPath('characters/piperPixeld2'); + case 'gf-pixel-neon': + frames = getCharPath('characters/gfPixelNeon'); + case 'gf-playtime': + frames = getCharPath('characters/gfPlaytime'); + case 'nogf-pixel': + frames = getCharPath('characters/nogfPixel'); + case 'gf-edgeworth-pixel': + frames = getCharPath('characters/gfEdgeworthPixel'); + case 'gf-tea-pixel': + frames = getCharPath('characters/gfTeaPixel'); + case 'gf-flowey': + frames = getCharPath('characters/gfFlowey'); + } + + + addAnimationByIndices('singUP', 'GF IDLE', [2], "", 24, false); + addAnimationByIndices('danceLeft', 'GF IDLE', [30, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false); + addAnimationByIndices('danceRight', 'GF IDLE', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false); + + loadOffsetFile('no-gf'); + + playAnim('danceRight'); + + setGraphicSize(Std.int(width * PlayState.daPixelZoom)); + updateHitbox(); + antialiasing = false; + + case 'gf-edd': + frames = getCharPath('tord/gfEdd'); + + addAnimationByIndices('singUP', 'GF IDLE', [2], "", 24, false); + addAnimationByIndices('danceLeft', 'GF IDLE', [12, 0, 1, 2, 3, 4, 5], "", 24, false); + addAnimationByIndices('danceRight', 'GF IDLE', [6, 7, 8, 9, 10, 11], "", 24, false); + + loadOffsetFile('no-gf'); + + playAnim('danceRight'); + + setGraphicSize(Std.int(width * PlayState.daPixelZoom)); + updateHitbox(); + antialiasing = false; + + case 'gf-pixeld4' | 'gf-pixeld4BSide': + switch (curCharacter) + { + case 'gf-pixeld4': + frames = getCharPath('characters/gfPixeld4'); + case 'gf-pixeld4BSide': + frames = getCharPath('characters/gfPixeld4BSide'); + } + + addAnimationByIndices('singUP', 'GF IDLE', [2], "", 24, false); + addAnimationByPrefix('switch', 'GF SWITCH', 24, false); + addAnimationByIndices('danceLeft', 'GF IDLE', [30, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false); + addAnimationByIndices('danceRight', 'GF IDLE', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false); + + loadOffsetFile('no-gf'); + + playAnim('danceRight'); + + setGraphicSize(Std.int(width * PlayState.daPixelZoom)); + updateHitbox(); + antialiasing = false; + + case 'dad-mad': + // DAD ANIMATION LOADING CODE + frames = getCharPath('characters/DADDY_DEAREST_D3'); + + addAnimationByPrefix('idle', 'Dad idle dance', 24, false); + addAnimationByPrefix('singUP', 'Dad Sing Note UP0', 24, false); + addAnimationByPrefix('singRIGHT', 'Dad Sing Note RIGHT0', 24, false); + addAnimationByPrefix('singDOWN', 'Dad Sing Note DOWN0', 24, false); + addAnimationByPrefix('singLEFT', 'Dad Sing Note LEFT0', 24, false); + + if (isPlayer) + { + addOffset('idle'); + addOffset("singUP", -12, 50); + addOffset("singRIGHT", -40, 10); + addOffset("singLEFT", 40, 27); + addOffset("singDOWN", 40, -30); + } + else + { + addOffset('idle'); + addOffset("singUP", -1, 52); + addOffset("singRIGHT", -1, 13); + addOffset("singLEFT", 61, 20); + addOffset("singDOWN", 5, -29); + } + + playAnim('idle'); + + case 'dad-sad'| 'dad-sad-pixel': + switch (curCharacter) + { + case 'dad-sad': + frames = getCharPath('characters/DADDY_DEAREST_D3_Sad'); + case 'dad-sad-pixel': + frames = getCharPath('characters/DADDY_DEAREST_D3_Sad_Pixel'); + } + + addAnimationByPrefix('idle', 'Dad idle dance', 24, false); + + addAnimationByPrefix('singUP', 'Dad Sing Note UP0', 24, false); + addAnimationByPrefix('singRIGHT', 'Dad Sing Note RIGHT0', 24, false); + addAnimationByPrefix('singDOWN', 'Dad Sing Note DOWN0', 24, false); + addAnimationByPrefix('singLEFT', 'Dad Sing Note LEFT0', 24, false); + + if (curCharacter == 'dad-sad-pixel') + { + addAnimationByPrefix('idle-alt', 'Dad idle dance', 24, false); + addAnimationByPrefix('singDOWN-alt', 'Dad Alt Sing Note DOWN0', 24, false); + } + + addOffset('idle'); + + if (isPlayer) + { + addOffset("singUP", -12, 50); + addOffset("singRIGHT", -40, 10); + addOffset("singLEFT", 40, 27); + addOffset("singDOWN", 40, -30); + } + else + { + addOffset('idle'); + addOffset("singUP", 1, 58); + addOffset("singRIGHT", -4, 38); + addOffset("singLEFT", 42, 19); + addOffset("singDOWN", -1, -20); + if (curCharacter == 'dad-sad-pixel') + addOffset("singDOWN-alt", -1, -20); + } + + playAnim('idle'); + + case 'hd-senpai-giddy-old': + switch (curCharacter) + { + case 'hd-senpai-giddy-old': + frames = getCharPath('characters/HD_SENPAI_GIDDY'); + iconColor = 'FFFFAA6F'; + } + + addAnimationByPrefix('idle', 'Dad idle dance', 24, false); + addAnimationByPrefix('singUP', 'Dad Sing Note UP', 24, false); + addAnimationByPrefix('singRIGHT', 'Dad Sing Note RIGHT', 24, false); + addAnimationByPrefix('singDOWN', 'Dad Sing Note DOWN', 24, false); + addAnimationByPrefix('singLEFT', 'Dad Sing Note LEFT', 24, false); + addAnimationByPrefix('singDOWN-alt', 'Dad Die', 24, false); + addAnimationByPrefix('singLEFT-alt', 'Dad UGH', 24, false); + + loadOffsetFile('hd-senpai-giddy'); + + playAnim('idle'); + + case 'hd-senpai-angry-old': + switch (curCharacter) + { + case 'hd-senpai-angry-old': + frames = getCharPath('characters/HD_SENPAI_ANGRY'); + iconColor = 'FFFFAA6F'; + healthIcon = 'hd-senpai'; + } + addAnimationByPrefix('idle', 'Dad idle dance', 24, false); + addAnimationByPrefix('singUP', 'Dad Sing Note UP', 24, false); + addAnimationByPrefix('singRIGHT', 'Dad Sing Note RIGHT', 24, false); + addAnimationByPrefix('singDOWN', 'Dad Sing Note DOWN', 24, false); + addAnimationByPrefix('singLEFT', 'Dad Sing Note LEFT', 24, false); + + loadOffsetFile('hd-senpai-angry'); + + playAnim('idle'); + + case 'hd-monika' | 'hd-monika-angry': + switch (curCharacter) + { + case 'hd-monika': + frames = getCharPath('characters/HD_MONIKA'); + case 'hd-monika-angry': + frames = getCharPath('characters/HD_MONIKA_ANGRY'); + } + iconColor = 'FFFFB8E3'; + addAnimationByPrefix('idle', 'Dad idle dance', 24, false); + addAnimationByPrefix('singUP', 'Dad Sing Note UP', 24, false); + addAnimationByPrefix('singRIGHT', 'Dad Sing Note RIGHT', 24, false); + addAnimationByPrefix('singDOWN', 'Dad Sing Note DOWN', 24, false); + addAnimationByPrefix('singLEFT', 'Dad Sing Note LEFT', 24, false); + + loadOffsetFile('hd-monika'); + + playAnim('idle'); + + case 'bf-senpai-worried' | 'bf-hd-senpai-angry' | 'bf-hd-senpai-giddy' | 'bf-hd-senpai-angry-night' | 'bf-hd-senpai-dark': + switch (curCharacter) + { + case 'bf-hd-senpai-dark': + frames = getCharPath('characters/BF_HD_SENPAI_DARK'); + healthIcon = 'hd-senpai-dark'; + case 'bf-hd-senpai-angry': + frames = getCharPath('characters/BF_HD_SENPAI_ANGRY'); + healthIcon = 'hd-senpai'; + case 'bf-hd-senpai-angry-night': + frames = getCharPath('characters/BF_HD_SENPAI_ANGRY_NIGHT'); + healthIcon = 'hd-senpai'; + case 'bf-hd-senpai-giddy': + frames = getCharPath('characters/BF_HD_SENPAI_GIDDY'); + healthIcon = 'hd-senpai-giddy'; + case 'bf-senpai-worried': + frames = getCharPath('characters/HD_SENPAI_WORRIED'); + healthIcon = 'hd-senpai-worried'; + } + + iconColor = 'FFFFAA6F'; + addAnimationByPrefix('idle', 'Dad idle dance', 24, false); + addAnimationByPrefix('singUP', 'Dad Sing Note UP', 24, false); + addAnimationByPrefix('singRIGHT', 'Dad Sing Note RIGHT', 24, false); + addAnimationByPrefix('singDOWN', 'Dad Sing Note DOWN', 24, false); + addAnimationByPrefix('singLEFT', 'Dad Sing Note LEFT', 24, false); + + loadOffsetFile('bf-hd-senpai-angry'); + + playAnim('idle'); + + flipX = true; + + case 'spooky-pixel': + frames = getCharPath('characters/spooky_pixel'); + iconColor = 'FFD57E00'; + addAnimationByPrefix('singUP', 'spooky UP NOTE', 24, false); + addAnimationByPrefix('singDOWN', 'spooky DOWN note', 24, false); + addAnimationByPrefix('singLEFT', 'note sing left', 24, false); + addAnimationByPrefix('singRIGHT', 'spooky sing right', 24, false); + addAnimationByIndices('danceLeft', 'spooky dance idle', [0, 2, 6], "", 12, false); + addAnimationByIndices('danceRight', 'spooky dance idle', [8, 10, 12, 14], "", 12, false); + + loadOffsetFile(curCharacter); + + playAnim('danceRight'); + + antialiasing = false; + + case 'sarvente-transform': //this one's gotta stay for now since it uses textureatlas + frames = Paths.getTextureAtlas('sacredmass/churchgospel/pegMePlease'); + healthIcon = 'sarvente-lucifer'; + iconColor = 'FFDA317D'; + + addAnimationByPrefix('idle', 'SarvTransAnim', 24, false); + addAnimationByPrefix('transform', 'SarvTransAnim', 24, false); + addAnimationByPrefix('singUP', 'SarvTransAnim', 24, false); + addAnimationByPrefix('singDOWN', 'SarvTransAnim', 24, false); + addAnimationByPrefix('singLEFT', 'SarvTransAnim', 24, false); + addAnimationByPrefix('singRIGHT', 'SarvTransAnim', 24, false); + + loadOffsetFile('no'); + + /*case 'bf-pump' | 'bf-ex-night' | 'bf-ghost' | 'bf-b3' | 'bf-frisk' | 'bf-kitty' + | 'bf-sticky-scream' | 'bfHalloween' | 'bf-spongebob' | 'bf-jabibi' + | 'bf-cryingchild' | 'bf-frisk-bw': + switch (curCharacter) + { + case 'bf-pump': + frames = getCharPath('characters/PUMP'); + iconColor = 'FFD57E00'; + case 'bf-ex-night': + frames = getCharPath('characters/BoyFriend_Assets_EX_night', 'shared'); + noteSkin = 'bf-b&b'; + iconColor = 'FF0EAEFE'; + case 'bf-ghost': + frames = getCharPath('characters/bfghost'); + noteSkin = 'normal'; + healthIcon = 'bf'; + iconColor = 'FF0EAEFE'; + case 'bf-b3': + frames = getCharPath('characters/b3/BOYFRIEND'); + iconColor = 'FF66FF33'; + case 'bf-frisk' | 'bf-frisk-bw': + if (curCharacter == 'bf-frisk-bw') pre = 'bw/'; + frames = getCharPath('characters/'+pre+'frisk'); + iconColor = 'FF5691D8'; + case 'bf-kitty': + frames = getCharPath('characters/KITTY_KEAREST'); + iconColor = 'FFA30016'; + case 'bf-sticky-scream': + frames = getCharPath('characters/STICKY'); + iconColor = 'FFFFF29E'; + healthIcon = 'bf-sticky'; + case 'bfHalloween': + frames = getCharPath('characters/BOYFRIEND_halloween'); + iconColor = 'FF0EAEFE'; + healthIcon = 'bf'; + case 'bf-spongebob': + frames = getCharPath('characters/SPONGEBOB'); + iconColor = 'FFE9D752'; + case 'bf-jabibi': + frames = getCharPath('characters/jabibi'); + iconColor = 'FFFF77F4'; + case 'bf-cryingchild': + frames = getCharPath('characters/CRYINGCHILD'); + iconColor = 'FFFFFFFF'; + } + + addAnimationByPrefix('idle', 'BF idle dance', 24, false); + addAnimationByPrefix('singUP', 'BF NOTE UP0', 24, false); + addAnimationByPrefix('singDOWN', 'BF NOTE DOWN0', 24, false); + addAnimationByPrefix('singUPmiss', 'BF NOTE UP MISS', 24, false); + addAnimationByPrefix('singDOWNmiss', 'BF NOTE DOWN MISS', 24, false); + addAnimationByPrefix('hey', 'BF HEY', 24, false); + + if (curCharacter != 'bf-sticky') + addAnimationByPrefix('singUP-alt', 'BF HEY', 24, false); + + addAnimationByPrefix('firstDeath', "BF dies", 24, false); + addAnimationByPrefix('deathLoop', "BF Dead Loop", 24, true); + addAnimationByPrefix('deathConfirm', "BF Dead confirm", 24, false); + + addAnimationByPrefix('scared', 'BF idle shaking', 24); + addAnimationByPrefix('singLEFT', 'BF NOTE LEFT0', 24, false); + addAnimationByPrefix('singRIGHT', 'BF NOTE RIGHT0', 24, false); + addAnimationByPrefix('singLEFTmiss', 'BF NOTE LEFT MISS', 24, false); + addAnimationByPrefix('singRIGHTmiss', 'BF NOTE RIGHT MISS', 24, false); + + + if (curCharacter == 'bf-sticky-scream') + { + addAnimationByPrefix('singUP-alt', 'boyfriend dodge', 24, false); + addAnimationByPrefix('singLEFT-alt', 'boyfriend dodge', 24, false); + addAnimationByPrefix('singDOWN-alt', 'boyfriend dodge', 24, false); + addAnimationByPrefix('singRIGHT-alt', 'boyfriend dodge', 24, false); + } + + var loadSelfOffsets:Array = ['bf-b3', 'bf-nene', 'bf-nene-scream', 'bf-sans-new', 'bfHalloween', 'bf-six', 'bf-shirogane']; + + if (loadSelfOffsets.contains(curCharacter)) + loadOffsetFile(curCharacter); + else if (curCharacter == 'bf-sticky-scream') + loadOffsetFile('bf-sticky'); + else + loadOffsetFile('bf'); + + playAnim('idle'); + + flipX = true;*/ + + case 'bf-demoncesar-bw' | 'bf-demoncesar-trollge' | 'bf-demoncesar-cas': + switch (curCharacter) + { + case 'bf-demoncesar': + frames = getCharPath('characters/demonCesar'); + iconColor = 'FFE353C8'; + case 'bf-demoncesar-bw': + frames = getCharPath('characters/bw/demonCesar'); + iconColor = 'FFE1E1E1'; + case 'bf-demoncesar-trollge': + frames = getCharPath('characters/demonCesar_trollge'); + iconColor = 'FFB76FA9'; + case 'bf-demoncesar-cas': + frames = getCharPath('characters/casDEMON'); + iconColor = 'FFE353C8'; + healthIcon = 'bf-demoncesar'; + } + + if (curCharacter.contains('cas')) + noteSkin = 'fever'; + else + { + switch (PlayState.curStage) + { + case 'takiStage': + noteSkin = 'taki'; + case 'ripdiner': + noteSkin = 'party-crasher'; + default: + noteSkin = PlayState.SONG.noteStyle; + } + } + + addAnimationByPrefix('idle', 'BF idle dance', 24, false); + addAnimationByPrefix('singUP', 'BF NOTE UP0', 24, false); + addAnimationByPrefix('singLEFT', 'BF NOTE LEFT0', 24, false); + addAnimationByPrefix('singRIGHT', 'BF NOTE RIGHT0', 24, false); + addAnimationByPrefix('singDOWN', 'BF NOTE DOWN0', 24, false); + addAnimationByPrefix('singUPmiss', 'BF NOTE UP MISS', 24, false); + addAnimationByPrefix('singLEFTmiss', 'BF NOTE LEFT MISS', 24, false); + addAnimationByPrefix('singRIGHTmiss', 'BF NOTE RIGHT MISS', 24, false); + addAnimationByPrefix('singDOWNmiss', 'BF NOTE DOWN MISS', 24, false); + addAnimationByPrefix('hey', 'BF HEY', 24, false); + addAnimationByPrefix('scared', 'BF idle shaking', 24); + + if (!curCharacter.contains('cas')) + { + addAnimationByPrefix('dodge', 'boyfriend dodge', 24, false); + loadOffsetFile('bf-demoncesar'); + } + + if (curCharacter.contains('cas')) + { + addAnimationByPrefix('firstDeath', "BF dies", 24, false); + addAnimationByPrefix('deathLoop', "BF Dead Loop", 24, true); + addAnimationByPrefix('deathConfirm', "BF Dead confirm", 24, false); + loadOffsetFile(curCharacter); + } + + playAnim('idle'); + + flipX = true; + + /*case 'bf-pixel-neon' | 'bf-senpai-pixel-angry' | 'bf-senpai-pixel' | 'bf-wright-pixel' | 'bf-pico-pixel' | 'bf-rico-pixel' | 'bf-sonic-pixel' + | 'bf-tom-pixel' | 'bf-sans-pixel' | 'bf-kapi-pixel' | 'bf-demoncesar-pixel' | 'bf-sky-pixel' | 'bf-glitch-pixel': + switch (curCharacter) + { + case 'bf-kapi-pixel': + frames = getCharPath('characters/bf-kapiPixel'); + iconColor = 'FF3483E3'; + case 'bf-pixel-neon': + frames = getCharPath('characters/bfPixelNeon'); + iconColor = 'FF4674EE'; + noteSkin = 'neon'; + case 'bf-senpai-pixel-angry': + frames = getCharPath('characters/bfSenpaiPixelangry'); + iconColor = 'FFFFAA6F'; + noteSkin = 'pixel'; + healthIcon = 'senpai-angry'; + case 'bf-senpai-pixel': + frames = getCharPath('characters/bfSenpaiPixel'); + iconColor = 'FFFFAA6F'; + healthIcon = 'senpai'; + case 'bf-wright-pixel': + frames = getCharPath('characters/bf-wrightPixel'); + iconColor = 'FF2D415C'; + case 'bf-pico-pixel': + frames = getCharPath('characters/bf-picoPixel'); + iconColor = 'FFB7D855'; + case 'bf-rico-pixel': + frames = getCharPath('characters/bf-ricoPixel'); + iconColor = 'FF7B59E5'; + case 'bf-sonic-pixel': + frames = getCharPath('characters/bf-sonicPixel'); + iconColor = 'FF7BD6F6'; + case 'bf-tom-pixel': + frames = getCharPath('characters/bf-tomPixel'); + iconColor = 'FF265D86'; + case 'bf-sans-pixel': + frames = getCharPath('characters/bf-sansPixel'); + iconColor = 'FF7484E5'; + case 'bf-demoncesar-pixel': + frames = getCharPath('characters/demonCesarPixel'); + iconColor = 'FFE353C8'; + case 'bf-sky-pixel': + frames = getCharPath('characters/bf-skyPixel'); + iconColor = 'FFE353C8'; + case 'bf-glitch-pixel': + frames = getCharPath('characters/bfGlitch'); + iconColor = 'FF32304C'; + default: + frames = getCharPath('characters/bfPixel'); + iconColor = 'FF0EAEFE'; + } + + if (curCharacter == 'bf-sky-pixel') + { + addAnimationByIndices('danceLeft', 'BF IDLE', [0, 2, 4], "", 5, false); + addAnimationByIndices('danceRight', 'BF IDLE', [6, 8], "", 5, false); + addOffset('danceLeft'); + addOffset('danceRight'); + } + + addAnimationByPrefix('idle', 'BF IDLE', 24, false); + addAnimationByPrefix('singUP', 'BF UP NOTE', 24, false); + addAnimationByPrefix('singDOWN', 'BF DOWN NOTE', 24, false); + addAnimationByPrefix('singUPmiss', 'BF UP MISS', 24, false); + addAnimationByPrefix('singDOWNmiss', 'BF DOWN MISS', 24, false); + addAnimationByPrefix('singLEFT', 'BF LEFT NOTE', 24, false); + addAnimationByPrefix('singRIGHT', 'BF RIGHT NOTE', 24, false); + addAnimationByPrefix('singLEFTmiss', 'BF LEFT MISS', 24, false); + addAnimationByPrefix('singRIGHTmiss', 'BF RIGHT MISS', 24, false); + + loadOffsetFile('no'); + + setGraphicSize(Std.int(width * 6)); + updateHitbox(); + + if (curCharacter == 'bf-sky-pixel') + playAnim('danceLeft'); + else + playAnim('idle'); + + width -= 100; + height -= 100; + + antialiasing = false; + + flipX = true; + + case 'bf-tankman-pixel-dead' | 'bf-pico-pixel-dead' | 'bf-rico-pixel-dead' | 'bf-sans-pixel-dead' | 'bf-gf-pixel-dead' | 'bf-sonic-pixel-dead' + | 'bf-tom-pixel-dead' | 'bf-wright-pixel-dead' | 'bf-demoncesar-pixel-dead': + var name:String = 'bf'; + name = curCharacter.substr(0, curCharacter.length - 11); + frames = getCharPath('characters/'+name+'PixelsDEAD'); + + addAnimationByPrefix('singUP', "BF Dies pixel", 24, false); + addAnimationByPrefix('firstDeath', "BF Dies pixel", 24, false); + addAnimationByPrefix('deathLoop', "Retry Loop", 24, true); + addAnimationByPrefix('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 'lane-pixel': + frames = getCharPath('characters/Lane_Pixel_assets'); + iconColor = "FF1F7EFF"; + addAnimationByPrefix('idle', 'Lane Pixel Idle', 24, false); + addAnimationByPrefix('singUP', 'Lane Pixel Up', 24, false); + addAnimationByPrefix('singDOWN', 'Lane Pixel Down', 24, false); + addAnimationByPrefix('singLEFT', 'Lane Pixel Left', 24, false); + addAnimationByPrefix('singRIGHT', 'Lane Pixel Right', 24, false); + + loadOffsetFile(curCharacter); + + setGraphicSize(Std.int(width * 5)); + updateHitbox(); + + playAnim('idle'); + + antialiasing = false; + + case 'monika-finale': + frames = getCharPath('characters/Monika_Finale'); + iconColor = 'FFFFB8E3'; + addAnimationByPrefix('idle', 'MONIKA IDLE', 24, false); + addAnimationByPrefix('singUP', 'MONIKA UP NOTE', 24, false); + addAnimationByPrefix('singLEFT', 'MONIKA LEFT NOTE', 24, false); + addAnimationByPrefix('singRIGHT', 'MONIKA RIGHT NOTE', 24, false); + addAnimationByPrefix('singDOWN', 'MONIKA DOWN NOTE', 24, false); + + addAnimationByPrefix('singUP-alt', 'MONIKA UP GLITCH', 24, false); + addAnimationByPrefix('singLEFT-alt', 'MONIKA LEFT GLITCH', 24, false); + addAnimationByPrefix('singRIGHT-alt', 'MONIKA RIGHT GLITCH', 24, false); + addAnimationByPrefix('singDOWN-alt', 'MONIKA DOWN GLITCH', 24, false); + + loadOffsetFile(curCharacter); + + playAnim('idle'); + + setGraphicSize(Std.int(width * 6)); + updateHitbox(); + + antialiasing = false; + + case 'bf-botan-pixel': + frames = getCharPath('characters/bf-botanPixel'); + iconColor = 'FF7DA8C5'; + addAnimationByPrefix('idle', 'Pico Pixel Idle', 24, false); + addAnimationByPrefix('singUP', 'Pico Pixel Up0', 24, false); + addAnimationByPrefix('singDOWN', 'Pico Pixel Down0', 24, false); + addAnimationByPrefix('singUPmiss', 'Pico Pixel Up Miss', 24, false); + addAnimationByPrefix('singDOWNmiss', 'Pico Pixel Down Miss', 24, false); + addAnimationByPrefix('singLEFT', 'Pico Pixel Left0', 24, false); + addAnimationByPrefix('singRIGHT', 'Pico Pixel Right0', 24, false); + addAnimationByPrefix('singLEFTmiss', 'Pico Pixel Left Miss', 24, false); + addAnimationByPrefix('singRIGHTmiss', 'Pico Pixel Right Miss', 24, false); + + loadOffsetFile(curCharacter); + + setGraphicSize(Std.int(width * 4.5)); + updateHitbox(); + + playAnim('idle'); + + antialiasing = false; + + flipX = true; + + case 'bf-whitty-pixel': + frames = getCharPath('characters/whitty-pixel'); + iconColor = 'FF1D1E35'; + addAnimationByPrefix('idle', 'Whitty Pixel Idle', 24, false); + addAnimationByPrefix('singUP', 'Whitty Pixel Up0', 24, false); + addAnimationByPrefix('singDOWN', 'Whitty Pixel Down0', 24, false); + addAnimationByPrefix('singLEFT', 'Whitty Pixel Left0', 24, false); + addAnimationByPrefix('singRIGHT', 'Whitty Pixel Right0', 24, false); + + loadOffsetFile(curCharacter); + + setGraphicSize(Std.int(width * 4.5)); + updateHitbox(); + + playAnim('idle'); + + antialiasing = false; + + flipX = true; + + case 'bf-gf-pixel': + frames = getCharPath('characters/bf-gfPixel'); + iconColor = 'FF9A1652'; + addAnimationByPrefix('idle', 'BF IDLE', 24, false); + addAnimationByPrefix('singUP', 'BF UP NOTE', 24, false); + addAnimationByPrefix('singDOWN', 'BF DOWN NOTE', 24, false); + addAnimationByPrefix('singUPmiss', 'BF UP MISS', 24, false); + addAnimationByPrefix('singLEFTmiss', 'BF LEFT MISS', 24, false); + addAnimationByPrefix('singRIGHTmiss', 'BF RIGHT MISS', 24, false); + addAnimationByPrefix('singDOWNmiss', 'BF DOWN MISS', 24, false); + addAnimationByPrefix('singLEFT', 'BF LEFT NOTE', 24, false); + addAnimationByPrefix('singRIGHT', 'BF RIGHT NOTE', 24, false); + addAnimationByPrefix('singLEFTmiss', 'BF LEFT MISS', 24, false); + addAnimationByPrefix('singRIGHTmiss', 'BF RIGHT MISS', 24, false); + + loadOffsetFile('no'); + + if (!isPlayer) + { + addOffset("singRIGHT", -30, 0); + addOffset("singLEFT", 30, 0); + } + else + { + addOffset("singRIGHT", -30, 0); + addOffset("singLEFT", 30, 0); + } + + setGraphicSize(Std.int(width * 6)); + updateHitbox(); + + playAnim('idle'); + + width -= 100; + height -= 100; + + antialiasing = false; + + flipX = true; + + case 'bf-tankman-pixel' | 'bf-tankman-pixel-happy': + frames = getCharPath('characters/bf-tankmanPixel'); + iconColor = 'FF2C2D41'; + healthIcon = 'bf-tankman-pixel'; + + addAnimationByPrefix('idle', 'BF IDLE', 24, false); + addAnimationByPrefix('idle-alt', 'BF ALT IDLE', 24, false); + addAnimationByPrefix('singUP', 'BF UP NOTE', 24, false); + addAnimationByPrefix('singLEFT', 'BF LEFT NOTE', 24, false); + addAnimationByPrefix('singRIGHT', 'BF RIGHT NOTE', 24, false); + addAnimationByPrefix('singDOWN', 'BF DOWN NOTE', 24, false); + addAnimationByPrefix('singUP-alt', 'BF UGH', 24, false); + addAnimationByPrefix('singUPmiss', 'BF UP MISS', 24, false); + addAnimationByPrefix('singLEFTmiss', 'BF LEFT MISS', 24, false); + addAnimationByPrefix('singRIGHTmiss', 'BF RIGHT MISS', 24, false); + addAnimationByPrefix('singDOWNmiss', 'BF DOWN MISS', 24, false); + + if (curCharacter == 'bf-tankman-pixel-happy') + addAnimationByPrefix('idle-alt', 'BF ALT IDLE', 24, false); + + loadOffsetFile('bf-tankman-pixel'); + + setGraphicSize(Std.int(width * 6)); + updateHitbox(); + + playAnim('idle-alt'); + + width -= 100; + height -= 100; + + antialiasing = false; + + flipX = true; + + case 'bf-pixeld3' | 'bf-pixeld3BSide': + var normShit:String = ""; + var altShit:String = ""; + + switch (curCharacter) + { + case 'bf-pixeld3': + frames = getCharPath('characters/bfPixeld4'); + normShit = ""; + altShit = " ALT"; + + case 'bf-pixeld3BSide': + frames = getCharPath('characters/bfPixeld4'); + normShit = " ALT"; + altShit = ""; + } + + addAnimationByPrefix('idle', 'BF'+normShit+' IDLE', 24, false); + addAnimationByPrefix('idle-alt', 'BF'+altShit+' IDLE', 24, false); + addAnimationByPrefix('singUP', 'BF'+normShit+' UP NOTE', 24, false); + addAnimationByPrefix('singLEFT', 'BF'+normShit+' LEFT NOTE', 24, false); + addAnimationByPrefix('singRIGHT', 'BF'+normShit+' RIGHT NOTE', 24, false); + addAnimationByPrefix('singDOWN', 'BF'+normShit+' DOWN NOTE', 24, false); + addAnimationByPrefix('singUP-alt', 'BF'+altShit+' UP NOTE', 24, false); + addAnimationByPrefix('singLEFT-alt', 'BF'+altShit+' LEFT NOTE', 24, false); + addAnimationByPrefix('singRIGHT-alt', 'BF'+altShit+' RIGHT NOTE', 24, false); + addAnimationByPrefix('singDOWN-alt', 'BF'+altShit+' DOWN NOTE', 24, false); + addAnimationByPrefix('singUPmiss', 'BF UP MISS', 24, false); + addAnimationByPrefix('singLEFTmiss', 'BF LEFT MISS', 24, false); + addAnimationByPrefix('singRIGHTmiss', 'BF RIGHT MISS', 24, false); + addAnimationByPrefix('singDOWNmiss', 'BF DOWN MISS', 24, false); + + loadOffsetFile('no'); + + setGraphicSize(Std.int(width * 6)); + updateHitbox(); + + playAnim('idle'); + + width -= 100; + height -= 100; + + antialiasing = false; + + flipX = true; + + case 'bf-senpai-tankman-dead' | 'bf-senpai-pixel-dead': + switch (curCharacter) + { + case 'bf-senpai-tankman-dead': + frames = getCharPath('characters/bf-senpai-tankman-dead'); + case 'bf-senpai-pixel-dead': + frames = getCharPath('characters/bf-senpai-pixel-dead'); + } + + addAnimationByPrefix('singUP', "BF Dies pixel", 24, false); + addAnimationByPrefix('firstDeath', "BF Dies pixel", 24, false); + addAnimationByPrefix('deathLoop', "senpai retry", 24, true); + addAnimationByPrefix('deathConfirm', "RETRY CONFIRM", 24, false); + + addOffset('firstDeath', -50, 150); + addOffset('deathLoop', -50, 150); + addOffset('deathConfirm', -50, 150); + + setGraphicSize(Std.int(width * 6)); + updateHitbox(); + + flipX = true; + + playAnim('idle'); + + antialiasing = false; + + case 'neon' | 'miku-pixel' | 'monster-pixel' | 'monika' | 'colt' | 'neon-bigger' | 'glitch' | 'josuke': + switch (curCharacter) + { + case 'glitch': + frames = getCharPath('characters/glitch'); + iconColor = 'FF0DA554'; + healthIcon = 'glitch'; + case 'neon' | 'neon-bigger': + frames = getCharPath('characters/neon'); + iconColor = "FF06D22A"; + noteSkin = 'neon'; + healthIcon = 'neon'; + case 'miku-pixel': + frames = getCharPath('characters/bitmiku'); + iconColor = 'FF32CDCC'; + case 'monster-pixel': + frames = getCharPath('characters/monsterPixel'); + iconColor = 'FFF3FF6E'; + if (PlayState.SONG.song.toLowerCase() == 'dead-pixel') + healthIcon = 'monster-pixel-look'; + else + healthIcon = 'monster-pixel'; + case 'monika': + frames = getCharPath('characters/monika'); + iconColor = 'FFFFB8E3'; + case 'colt': + frames = getCharPath('characters/colt'); + iconColor = 'FF584190'; + case 'josuke': + frames = getCharPath('characters/josuke'); + iconColor = 'FFED7F98'; + + } + addAnimationByPrefix('idle', 'Senpai Idle', 24, false); + addAnimationByPrefix('singUP', 'SENPAI UP NOTE', 24, false); + addAnimationByPrefix('singLEFT', 'SENPAI LEFT NOTE', 24, false); + addAnimationByPrefix('singRIGHT', 'SENPAI RIGHT NOTE', 24, false); + addAnimationByPrefix('singDOWN', 'SENPAI DOWN NOTE', 24, false); + + var loadSelfOffsets = ['senpai', 'monika', 'colt', 'neon', 'neon-bigger', 'miku-pixel']; + + if (loadSelfOffsets.contains(curCharacter)) + { + if (curCharacter == 'senpai') + loadOffsetFile('senpai-angry'); + else + loadOffsetFile(curCharacter); + } + + else + loadOffsetFile('senpai'); + + playAnim('idle'); + + if (curCharacter == 'neon') + setGraphicSize(Std.int(width * 5)); + else + setGraphicSize(Std.int(width * 6)); + + updateHitbox(); + + antialiasing = false; + + case 'monika-angry': + frames = getCharPath('characters/monika'); + iconColor = 'FFFFB8E3'; + + addAnimationByPrefix('idle', 'Angry Senpai Idle', 24, false); + addAnimationByPrefix('singUP', 'Angry Senpai UP NOTE', 24, false); + addAnimationByPrefix('singLEFT', 'Angry Senpai LEFT NOTE', 24, false); + addAnimationByPrefix('singRIGHT', 'Angry Senpai RIGHT NOTE', 24, false); + addAnimationByPrefix('singDOWN', 'Angry Senpai DOWN NOTE', 24, false); + addAnimationByPrefix('idle-alt', 'Green Senpai Idle', 24, false); + addAnimationByPrefix('singUP-alt', 'Green Senpai UP NOTE', 24, false); + addAnimationByPrefix('singLEFT-alt', 'Green Senpai LEFT NOTE', 24, false); + addAnimationByPrefix('singRIGHT-alt', 'Green Senpai RIGHT NOTE', 24, false); + addAnimationByPrefix('singDOWN-alt', 'Green Senpai DOWN NOTE', 24, false); + + loadOffsetFile(curCharacter); + + playAnim('idle'); + + setGraphicSize(Std.int(width * 6)); + updateHitbox(); + + antialiasing = false; + + case 'green-monika': + frames = getCharPath('characters/monika'); + iconColor = 'FFFFB8E3'; + addAnimationByPrefix('idle', 'Green Senpai Idle', 24, false); + addAnimationByPrefix('singUP', 'Green Senpai UP NOTE', 24, false); + addAnimationByPrefix('singLEFT', 'Green Senpai LEFT NOTE', 24, false); + addAnimationByPrefix('singRIGHT', 'Green Senpai RIGHT NOTE', 24, false); + addAnimationByPrefix('singDOWN', 'Green Senpai DOWN NOTE', 24, false); + + loadOffsetFile('monika'); + + playAnim('idle'); + + setGraphicSize(Std.int(width * 6)); + updateHitbox(); + + antialiasing = false; + + case 'glitch-angry' | 'kristoph-angry' | 'chara-pixel' | 'jackson' | 'mario-angry' | 'matt-angry' | 'mangle-angry' | 'baldi-angry-pixel' | 'colt-angry' + | 'colt-angryd2' | 'senpai-giddy' | 'blantad-pixel' | 'tricky-pixel': + switch (curCharacter) + { + case 'kristoph-angry': + frames = getCharPath('characters/kristoph'); + iconColor = 'FF9284AD'; + case 'glitch-angry': + frames = getCharPath('characters/glitch'); + iconColor = 'FF0DA554'; + case 'chara-pixel': + frames = getCharPath('characters/chara_pixel'); + iconColor = 'FFFF0000'; + case 'jackson': + frames = getCharPath('characters/jackson'); + iconColor = 'FFC05D68'; + case 'mario-angry': + frames = getCharPath('characters/mario'); + iconColor = 'FFCC0000'; + case 'matt-angry': + frames = getCharPath('characters/matt'); + iconColor = 'FFA55BA0'; + healthIcon = 'matt-ew-pixel'; + case 'mangle-angry': + frames = getCharPath('characters/mangle'); + iconColor = 'FFDA47AD'; + case 'baldi-angry-pixel': + frames = getCharPath('characters/baldi_pixel'); + iconColor = 'FF18E416'; + healthIcon = 'baldi-pixel'; + case 'colt-angry': + frames = getCharPath('characters/colt'); + iconColor = 'FF584190'; + healthIcon = 'colt'; + case 'colt-angryd2': + frames = getCharPath('characters/coltd2'); + iconColor = 'FF584190'; + healthIcon = 'colt'; + case 'senpai-giddy': + frames = getCharPath('characters/senpaigiddy'); + iconColor = 'FFFFAA6F'; + case 'blantad-pixel': + frames = getCharPath('characters/blantad-pixel'); + iconColor = 'FF64B3FE'; + case 'tricky-pixel': + frames = getCharPath('characters/tricky-pixel'); + iconColor = 'FF396357'; + } + + addAnimationByPrefix('idle', 'Angry Senpai Idle', 24, false); + addAnimationByPrefix('singUP', 'Angry Senpai UP NOTE', 24, false); + addAnimationByPrefix('singLEFT', 'Angry Senpai LEFT NOTE', 24, false); + addAnimationByPrefix('singRIGHT', 'Angry Senpai RIGHT NOTE', 24, false); + addAnimationByPrefix('singDOWN', 'Angry Senpai DOWN NOTE', 24, false); + + addAnimationByPrefix('idle-alt', 'Senpai Idle', 24, false); + addAnimationByPrefix('singUP-alt', 'SENPAI UP NOTE', 24, false); + addAnimationByPrefix('singLEFT-alt', 'SENPAI LEFT NOTE', 24, false); + addAnimationByPrefix('singRIGHT-alt', 'SENPAI RIGHT NOTE', 24, false); + addAnimationByPrefix('singDOWN-alt', 'SENPAI DOWN NOTE', 24, false); + + var loadSelfOffsets:Array = ['senpai-giddy', 'senpai-angry', 'colt-angry', 'tricky-pixel']; + + if (loadSelfOffsets.contains(curCharacter)) + { + var name = curCharacter.substr(0, curCharacter.length - 6); + + if (curCharacter == 'tricky-pixel') name = curCharacter; + + if (curCharacter.contains('senpai')) + loadOffsetFile('senpai-angry'); + else + loadOffsetFile(name); + } + else + loadOffsetFile('senpai'); + + playAnim('idle'); + + setGraphicSize(Std.int(width * 6)); + updateHitbox(); + + antialiasing = false; + + case 'colt-angryd2corrupted': + frames = getCharPath('characters/coltd2'); + iconColor = 'FF584190'; + healthIcon = 'colt'; + + addAnimationByPrefix('idle', 'Corrupt Senpai Idle', 24, false); + addAnimationByPrefix('singUP', 'Corrupt Senpai UP NOTE', 24, false); + addAnimationByPrefix('singLEFT', 'Corrupt Senpai LEFT NOTE', 24, false); + addAnimationByPrefix('singRIGHT', 'Corrupt Senpai RIGHT NOTE', 24, false); + addAnimationByPrefix('singDOWN', 'Corrupt Senpai DOWN NOTE', 24, false); + + loadOffsetFile('colt'); + + playAnim('idle'); + + setGraphicSize(Std.int(width * 6)); + updateHitbox(); + + antialiasing = false; + + case 'bitdadcrazy': + // DAD ANIMATION LOADING CODE + frames = getCharPath('characters/BitDadCrazy'); + + addAnimationByPrefix('idle', 'Dad idle dance', 24, false); + addAnimationByPrefix('singUP', 'Dad Sing Note UP', 24, false); + addAnimationByPrefix('singRIGHT', 'Dad Sing Note RIGHT', 24, false); + addAnimationByPrefix('singDOWN', 'Dad Sing Note DOWN', 24, false); + addAnimationByPrefix('singLEFT', 'Dad Sing Note LEFT', 24, false); + + addOffset('idle'); + addOffset("singUP", -6, 50); + addOffset("singRIGHT", 0, 27); + addOffset("singLEFT", -10, 10); + addOffset("singDOWN", 0, -30); + playAnim('idle'); + + setGraphicSize(Std.int(width * 0.85)); + updateHitbox(); + + antialiasing = false; + + case 'bitdad' | 'bitdadBSide': + switch (curCharacter) + { + case 'bitdad': + frames = getCharPath('characters/BitDad'); + case 'bitdadBSide': + frames = getCharPath('characters/BitDadBSide'); + } + + addAnimationByPrefix('idle', 'Dad idle dance', 24, false); + addAnimationByPrefix('switch', 'Dad version switch', 24, false); + addAnimationByPrefix('singUP', 'Dad Sing Note UP', 24, false); + addAnimationByPrefix('singRIGHT', 'Dad Sing Note RIGHT', 24, false); + addAnimationByPrefix('singDOWN', 'Dad Sing Note DOWN', 24, false); + addAnimationByPrefix('singLEFT', 'Dad Sing Note LEFT', 24, false); + + addOffset('idle'); + addOffset('switch'); + addOffset("singUP", 1, 58); + addOffset("singRIGHT", -4, 38); + addOffset("singLEFT", 42, 19); + addOffset("singDOWN", -1, -20); + playAnim('idle'); + + setGraphicSize(Std.int(width * 1)); + updateHitbox(); + + antialiasing = false; + + case 'matt-ew-pixel': + frames = getCharPath('characters/matt'); + iconColor = 'FFA55BA0'; + addAnimationByPrefix('idle', 'Senpai Idle', 24, false); + addAnimationByPrefix('singUP', 'SENPAI UP NOTE', 24, false); + addAnimationByPrefix('singLEFT', 'SENPAI LEFT NOTE', 24, false); + addAnimationByPrefix('singRIGHT', 'SENPAI RIGHT NOTE', 24, false); + addAnimationByPrefix('singDOWN', 'SENPAI DOWN NOTE', 24, false); + + loadOffsetFile(curCharacter); + + playAnim('idle'); + + setGraphicSize(Std.int(width * 6)); + updateHitbox(); + + antialiasing = false; + + //using the psych method instead of modding plus. main reason is to make it easier for me to port them here + default: + isCustom = true; + + if (curCharacter == 'exTricky') + { + exSpikes = new FlxSprite(-250, -70); + exSpikes.frames = Paths.getSparrowAtlas('characters/FloorSpikes', 'shared'); + exSpikes.visible = false; + exSpikes.animation.addByPrefix('spike','Floor Spikes', 24, false); + } + + if (curCharacter.contains('hd-senpai')) + curCharacter = StringTools.replace(curCharacter, 'hd', '2vplus'); + + if (curCharacter == 'twinstwo' || curCharacter == 'twinsone') + alpha = 0.78; + + var characterPath:String = 'images/characters/jsons/' + curCharacter; + + var path:String = Paths.jsonNew(characterPath); + + #if desktop + if (FileSystem.exists(Paths.modFolders('characters/'+curCharacter+'.json'))) + { + path = Paths.modFolders('characters/'+curCharacter+'.json'); + } + #end + + if (!FileSystem.exists(path) && !Assets.exists(path)) + { + trace('oh no missingno'); + path = Paths.jsonNew('images/characters/jsons/bf'); //If a character couldn't be found, change to bf just to prevent a crash + curCharacter = 'bf'; + } + + var rawJson:Dynamic; + + if (FileSystem.exists(path)) + rawJson = File.getContent(path); + else + rawJson = Assets.getText(path); + + var json:CharacterFile = cast Json.parse(rawJson); + + if (json.noteSkin != null) + noteSkin = json.noteSkin; + + if (json.isPlayerChar) + isPsychPlayer = json.isPlayerChar; + + if (noteSkin == "" || noteSkin == 'normal' || noteSkin == 'default') + noteSkin = PlayState.SONG.noteStyle; + + var imagePath = Paths.image(json.image); + + if (Assets.exists(imagePath) && !FileSystem.exists(imagePath) && !FileSystem.exists(Paths.modsImages(imagePath))) + { + txtToFind = Paths.txtNew('images/' + json.image); + + if (!Paths.currentTrackedAssets.exists(json.image)) + Paths.cacheImage(json.image, 'shared'); + + rawPic = Paths.currentTrackedAssets.get(json.image); + + charPath = json.image + '.png'; //cuz we only use pngs anyway + imageFile = json.image; //psych + + if(Assets.exists(txtToFind)) + frames = Paths.getPackerAtlas(json.image); + else + { + rawXml = Assets.getText(Paths.xmlNew('images/' + json.image)); + + if(FlxG.save.data.poltatoPC && curCharacter != 'senpai-christmas' && json.scale != 6) + { + rawXml = resizeXML(rawXml, 0.5); + + json.scale *= 2; + + if (isPlayer && json.playerposition != null) + json.playerposition = [json.playerposition[0] + 100, json.playerposition[1] + 170]; + else + json.position = [json.position[0] + 100, json.position[1] + 170]; + + if (height < 410) + json.position[1] -= 100; + } + + frames = FlxAtlasFrames.fromSparrow(rawPic,rawXml); + } + } + else //if it's a character added after compiling + { + txtToFind= Paths.txtNew('images/' + json.image); + var modTxtToFind:String = Paths.modsTxt(json.image); + + if (!Paths.currentTrackedAssets.exists(json.image)) + Paths.cacheImage(json.image, 'preload'); + + rawPic = Paths.currentTrackedAssets.get(json.image); + + charPath = json.image + '.png'; //cuz we only use pngs anyway + imageFile = json.image; //psych + + if(FileSystem.exists(txtToFind)) + { + rawXml = File.getContent(txtToFind); + frames = FlxAtlasFrames.fromSpriteSheetPacker(rawPic,rawXml); + } + else + { + if (FileSystem.exists(Paths.modsXml(json.image))) + rawXml = File.getContent(Paths.modsXml(json.image)); + else if (FileSystem.exists(FileSystem.absolutePath("assets/shared/images/"+json.image+".xml"))) + rawXml = File.getContent(FileSystem.absolutePath("assets/shared/images/"+json.image+".xml")); + else + rawXml = File.getContent(Paths.xmlNew('images/' + json.image)); + + //this took my dumbass 2 hours to figure out. + if(FlxG.save.data.poltatoPC && curCharacter != 'senpai-christmas' && json.scale != 6) + { + rawXml = resizeXML(rawXml, 0.5); + + json.scale *= 2; + + if (isPlayer && json.playerposition != null) + json.playerposition = [json.playerposition[0] + 230, json.playerposition[1] + 230]; + else + json.position = [json.position[0] + 230, json.position[1] + 230]; + } + + frames = FlxAtlasFrames.fromSparrow(rawPic,rawXml); + } + } + + if(json.scale != 1) { + jsonScale = json.scale; + setGraphicSize(Std.int(width * jsonScale)); + updateHitbox(); + } + + healthIcon = json.healthicon; + + if (isPlayer && json.playerposition != null) + positionArray = json.playerposition; + else + positionArray = json.position; + + if (json.playerposition != null) + playerPositionArray = json.playerposition; + else + playerPositionArray = json.position; + + if (isPlayer && json.player_camera_position != null) + cameraPosition = json.player_camera_position; + else + cameraPosition = json.camera_position; + + if (json.player_camera_position != null) + playerCameraPosition = json.player_camera_position; + else + playerCameraPosition = json.camera_position; + + singDuration = json.sing_duration; + flipX = !!json.flip_x; + if(json.no_antialiasing) { + antialiasing = false; + noAntialiasing = true; + } + + if(json.healthbar_colors != null && json.healthbar_colors.length > 2) + healthColorArray = json.healthbar_colors; + + //cuz the way bar colors are calculated here is like in B&B + colorPreString = FlxColor.fromRGB(healthColorArray[0], healthColorArray[1], healthColorArray[2]); + colorPreCut = colorPreString.toHexString(); + + iconColor = colorPreCut.substring(2); + + antialiasing = !noAntialiasing; + + animationsArray = json.animations; + + if (isPlayer && json.playerAnimations != null) + animationsArray = json.playerAnimations; + + if(animationsArray != null && animationsArray.length > 0) { + for (anim in animationsArray) { + var animAnim:String = '' + anim.anim; + var animName:String = '' + anim.name; + var animFps:Int = anim.fps; + var animLoop:Bool = !!anim.loop; //Bruh + var animIndices:Array = anim.indices; + if(animIndices != null && animIndices.length > 0) { + animation.addByIndices(animAnim, animName, animIndices, "", animFps, animLoop); + } else { + animation.addByPrefix(animAnim, animName, animFps, animLoop); + } + + if (isPlayer) + { + if(anim.playerOffsets != null && anim.playerOffsets.length > 1) { + addOffset(anim.anim, anim.playerOffsets[0], anim.playerOffsets[1]); + } + else if(anim.offsets != null && anim.offsets.length > 1) { + addOffset(anim.anim, anim.offsets[0], anim.offsets[1]); + } + } + else + { + if(anim.offsets != null && anim.offsets.length > 1) { + addOffset(anim.anim, anim.offsets[0], anim.offsets[1]); + } + } + + if(anim.playerOffsets != null && anim.playerOffsets.length > 1) { + addPlayerOffset(anim.anim, anim.playerOffsets[0], anim.playerOffsets[1]); + } + + } + } else { + quickAnimAdd('idle', 'BF idle dance'); + quickAnimAdd('singUP', 'BF idle dance'); + quickAnimAdd('singDOWN', 'BF idle dance'); + quickAnimAdd('singLEFT', 'BF idle dance'); + quickAnimAdd('singRIGHT', 'BF idle dance'); + } + + if (animOffsets.exists('danceRight')) + playAnim('danceRight'); + else + playAnim('idle'); + } + + if(animation.getByName('danceLeft') != null && animation.getByName('danceRight') != null) + danceIdle = true; + + if(animation.getByName('singUPmiss') == null) + doMissThing = true; //if for some reason you only have an up miss, why? + + originalFlipX = flipX; + + if (curCharacter.contains('dad')) + singDuration = 6.1; + + dance(); + + if (isPlayer) + { + flipX = !flipX; + + // Doesn't flip for BF, since his are already in the right place??? + if (!curCharacter.startsWith('bf') && !isPsychPlayer) + flipAnims(); + } + + if (!isPlayer) + { + // Flip for just bf + if (curCharacter.startsWith('bf') || isPsychPlayer) + flipAnims(); + } + } + + var txtToFind:String; + var rawPic:Dynamic; + var rawXml:String; + + override function update(elapsed:Float) + { + if (!debugMode && animation.curAnim != null) + { + if(heyTimer > 0) + { + heyTimer -= elapsed; + if(heyTimer <= 0) + { + if(specialAnim && animation.curAnim.name == 'hey' || animation.curAnim.name == 'cheer') + { + specialAnim = false; + dance(); + } + heyTimer = 0; + } + } else if(specialAnim && animation.curAnim.finished) + { + specialAnim = false; + dance(); + } + + if (flipMode) + { + if (isPlayer) + { + if (animation.curAnim.name.startsWith('sing')) + holdTimer += elapsed; + + if (holdTimer >= Conductor.stepCrochet * singDuration * 0.001) + { + dance(); + holdTimer = 0; + } + } + } + else + { + if (!isPlayer) + { + if (animation.curAnim.name.startsWith('sing')) + holdTimer += elapsed; + + if (holdTimer >= Conductor.stepCrochet * singDuration * 0.001) + { + dance(); + holdTimer = 0; + } + } + } + + if (curCharacter.startsWith('gf') && animation.curAnim.name == 'hairFall' && animation.curAnim.finished) + playAnim('danceRight'); + } + + super.update(elapsed); + } + + private var danced:Bool = false; + + /** + * FOR GF DANCING SHIT + */ + + public function dance() + { + if (!debugMode && !specialAnim) + { + switch (curCharacter) + { + /*case 'bf-bigmonika-dead': + if (animation.curAnim.name != 'crashDeath2') + { + if (isPlayer) + playAnim('idle' + bfAltAnim); + else + playAnim('idle' + altAnim); + } + case 'tankman': + if (animation.curAnim.name != 'singDOWN-alt' && animation.curAnim.name != 'singLEFT-alt' && !stopIdle) + { + if (isPlayer) + playAnim('idle' + bfAltAnim); + else + playAnim('idle' + altAnim); + } + case 'oswald-happy': + if (animation.curAnim.name != 'oldtimey' && animation.curAnim.name != 'lucky') + { + danced = !danced; + + if (isPlayer) + { + if (danced) + playAnim('danceRight' + bfAltAnim); + else + playAnim('danceLeft' + bfAltAnim); + } + else + { + if (danced) + playAnim('danceRight' + altAnim); + else + playAnim('danceLeft' + altAnim); + } + } + case 'oswald-angry': + if (animation.curAnim.name != 'hah' && animation.curAnim.name != 'notold') + { + danced = !danced; + + if (isPlayer) + { + if (danced) + playAnim('danceRight' + bfAltAnim); + else + playAnim('danceLeft' + bfAltAnim); + } + else + { + if (danced) + playAnim('danceRight' + altAnim); + else + playAnim('danceLeft' + altAnim); + } + } + case 'gf-judgev2': + if (animation.curAnim.name != 'spooked') + { + danced = !danced; + + if (isPlayer) + { + if (danced) + playAnim('danceRight' + bfAltAnim); + else + playAnim('danceLeft' + bfAltAnim); + } + else + { + if (danced) + playAnim('danceRight' + altAnim); + else + playAnim('danceLeft' + altAnim); + } + } + case 'bigmonika': + if (animation.curAnim.name != 'lastNOTE') + { + if (isPlayer) + playAnim('idle' + bfAltAnim); + else + playAnim('idle' + altAnim); + } + case 'amor-ex': + if (animation.curAnim.name != 'drop') + { + if (isPlayer) + playAnim('idle' + bfAltAnim); + else + playAnim('idle' + altAnim); + } + case 'sarvente-transform': + //she dont' dance bro*/ + default: + if (danceIdle) + { + if (!stopIdle) + { + danced = !danced; + + if (isPlayer) + { + if (danced) + playAnim('danceRight' + bfAltAnim); + else + playAnim('danceLeft' + bfAltAnim); + } + else + { + if (danced) + playAnim('danceRight' + altAnim); + else + playAnim('danceLeft' + altAnim); + } + } + } + else + { + if (!stopIdle) + { + if (isPlayer) + playAnim('idle' + bfAltAnim); + else + playAnim('idle' + altAnim); + } + } + } + + if (color != FlxColor.WHITE && doMissThing) + color = FlxColor.WHITE; + } + } + + public function setZoom(?toChange:Float = 1, ?isPixel:Bool = false):Void + { + daZoom = toChange; + + var daMulti:Float = 1; + + if (isPixel && !isCustom) + daMulti = 6; + + if (isCustom) + daMulti = jsonScale; + + var daValue:Float = toChange * daMulti; + scale.set(daValue, daValue); + } + + public function loadOffsetFile(character:String) + { + var offset:Array; + + if (isPlayer) + { + if (Assets.exists(Paths.txtNew('images/characters/offsets/' + character + "PlayerOffsets", 'shared'))) + offset = CoolUtil.coolTextFile(Paths.txtNew('images/characters/offsets/' + character + "PlayerOffsets", 'shared')); + else if (Assets.exists(Paths.txtNew('images/characters/offsets/' + character + "Offsets", 'shared'))) + offset = CoolUtil.coolTextFile(Paths.txtNew('images/characters/offsets/' + character + "Offsets", 'shared')); + else + offset = CoolUtil.coolTextFile(Paths.txtNew('images/characters/offsets/noOffsets', 'shared')); + } + else + { + if (Assets.exists(Paths.txtNew('images/characters/offsets/' + character + "Offsets", 'shared'))) + offset = CoolUtil.coolTextFile(Paths.txtNew('images/characters/offsets/' + character + "Offsets", 'shared')); + else if (Assets.exists(Paths.txtNew('images/characters/offsets/' + character + "PlayerOffsets", 'shared'))) + offset = CoolUtil.coolTextFile(Paths.txtNew('images/characters/offsets/' + character + "PlayerOffsets", 'shared')); + else + offset = CoolUtil.coolTextFile(Paths.txtNew('images/characters/offsets/noOffsets', 'shared')); + } + + for (i in 0...offset.length) + { + var data:Array = offset[i].split(' '); + addOffset(data[0], Std.parseInt(data[1]), Std.parseInt(data[2])); + } + + //for saving playerOffsets in jsons + if (Assets.exists(Paths.txtNew('images/characters/offsets/' + character + "PlayerOffsets", 'shared'))) + { + var playerOffset:Array; + + playerOffset = CoolUtil.coolTextFile(Paths.txtNew('images/characters/offsets/' + character + "PlayerOffsets", 'shared')); + + for (i in 0...playerOffset.length) + { + var data:Array = playerOffset[i].split(' '); + addPlayerOffset(data[0], Std.parseInt(data[1]), Std.parseInt(data[2])); + } + } + else + { + for (i in 0...offset.length) + { + var data:Array = offset[i].split(' '); + addPlayerOffset(data[0], Std.parseInt(data[1]), Std.parseInt(data[2])); + } + } + } + + var missed:Bool = false; + + public function playAnim(AnimName:String, Force:Bool = false, Reversed:Bool = false, Frame:Int = 0):Void + { + specialAnim = false; + missed = false; + + if (AnimName.endsWith('alt') && animation.getByName(AnimName) == null) + AnimName = AnimName.split('-')[0]; + + if (AnimName == 'laugh' && animation.getByName(AnimName) == null) + AnimName = 'singUP'; + + if (AnimName.endsWith('2') && animation.getByName(AnimName) == null && curCharacter == 'hex-9key') + AnimName = AnimName.substr(0, AnimName.length - 1); + + if (AnimName.endsWith('miss') && animation.getByName(AnimName) == null) + { + AnimName = AnimName.substr(0, AnimName.length - 4); + + if (doMissThing) + missed = true; + } + + if (AnimName.endsWith('miss') && curCharacter == 'bf-sky' && doMissThing) + missed = true; + + if (animation.getByName(AnimName) == null) // if it's STILL null, just play idle + { + if(danceIdle) + AnimName = 'danceRight'; + else + AnimName = 'idle'; + } + + animation.play(AnimName, Force, Reversed, Frame); + + + if (missed) + color = 0xCFAFFF; + else if (color != FlxColor.WHITE && doMissThing) + color = FlxColor.WHITE; + + var daOffset = animOffsets.get(AnimName); + + if (debugMode && isPlayer) + daOffset = animPlayerOffsets.get(AnimName); + + if (debugMode) + { + if (animOffsets.exists(AnimName) && !isPlayer || animPlayerOffsets.exists(AnimName) && isPlayer) + offset.set(daOffset[0] * daZoom, daOffset[1] * daZoom); + else + offset.set(0, 0); + } + else + { + if (animOffsets.exists(AnimName)) + offset.set(daOffset[0] * daZoom, daOffset[1] * daZoom); + else + offset.set(0, 0); + } + + if (curCharacter.startsWith('gf') && animOffsets.exists('singLEFT')) + { + if (AnimName == 'singLEFT') + danced = true; + else if (AnimName == 'singRIGHT') + danced = false; + + if (AnimName == 'singUP' || AnimName == 'singDOWN') + danced = !danced; + } + } + + public function addOffset(name:String, x:Float = 0, y:Float = 0) + { + animOffsets[name] = [x, y]; + } + + public function addPlayerOffset(name:String, x:Float = 0, y:Float = 0) + { + animPlayerOffsets[name] = [x, y]; + } + + public function quickAnimAdd(name:String, anim:String) + { + addAnimationByPrefix(name, anim, 24, false); + } + + public function getCharPath(path:String, ?library:String) + { + charPath = path + '.png'; //cuz we only use pngs anyway + imageFile = path; //psych + + return Paths.getSparrowAtlas(path, library); + } + + //so that I can convert em to psych faster + public function addAnimationByPrefix(name:String, prefix:String, framerate:Int = 24, loop:Bool = false) + { + var newAnim:AnimArray = { + anim: name, + name: prefix, + fps: Math.round(framerate), + loop: loop, + indices: [], + offsets: [0, 0], + playerOffsets: [0, 0] + }; + + animation.addByPrefix(name, prefix, framerate, loop); + animationsArray.push(newAnim); + } + + public function addAnimationByIndices(name:String, prefix:String, indices:Array, string:String, framerate:Int = 24, loop:Bool = false) + { + //string isn't used. just placed for easy conversion. + var newAnim:AnimArray = { + anim: name, + name: prefix, + fps: Math.round(framerate), + loop: loop, + indices: indices, + offsets: [0, 0], + playerOffsets: [0, 0] + }; + + animation.addByIndices(name, prefix, indices, "", framerate, loop); + animationsArray.push(newAnim); + } + + public function resizeXML(rawXml:String, factor:Float) + { + var daXml:Xml = Xml.parse(rawXml); + var fast = new haxe.xml.Access(daXml); + var users = fast.node.TextureAtlas; + for (SubTexture in users.nodes.SubTexture) { + SubTexture.att.x = Std.string(Std.parseInt(SubTexture.att.x) * factor); + SubTexture.att.y = Std.string(Std.parseInt(SubTexture.att.y) * factor); + SubTexture.att.width = Std.string(Std.parseInt(SubTexture.att.width) * factor); + SubTexture.att.height = Std.string(Std.parseInt(SubTexture.att.height) * factor); + + if (SubTexture.has.frameX) + { + SubTexture.att.frameX = Std.string(Std.parseInt(SubTexture.att.frameX) * factor); + SubTexture.att.frameY = Std.string(Std.parseInt(SubTexture.att.frameY) * factor); + SubTexture.att.frameWidth = Std.string(Std.parseInt(SubTexture.att.frameWidth) * factor); + SubTexture.att.frameHeight = Std.string(Std.parseInt(SubTexture.att.frameHeight) * factor); + } + } + return Std.string(daXml); + } + + public function flipAnims() + { + if (animation.getByName('singRIGHT') != null && animation.getByName('singLEFT') != null) + { + 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 && animation.getByName('singLEFTmiss') != null) + { + var oldMiss = animation.getByName('singRIGHTmiss').frames; + animation.getByName('singRIGHTmiss').frames = animation.getByName('singLEFTmiss').frames; + animation.getByName('singLEFTmiss').frames = oldMiss; + } + if (animation.getByName('singRIGHT-alt') != null && animation.getByName('singLEFT-alt') != null) + { + var oldAlt = animation.getByName('singRIGHT-alt').frames; + animation.getByName('singRIGHT-alt').frames = animation.getByName('singLEFT-alt').frames; + animation.getByName('singLEFT-alt').frames = oldAlt; + } + + if (curCharacter.contains('9key')) + { + var oldRight = animation.getByName('singRIGHT2').frames; + animation.getByName('singRIGHT2').frames = animation.getByName('singLEFT2').frames; + animation.getByName('singLEFT2').frames = oldRight; + } + } +} \ No newline at end of file diff --git a/source/CharacterEditorState.hx b/source/CharacterEditorState.hx new file mode 100644 index 000000000..75146b549 --- /dev/null +++ b/source/CharacterEditorState.hx @@ -0,0 +1,1560 @@ +package; + +#if desktop +import Discord.DiscordClient; +#end +import flixel.FlxG; +import flixel.FlxObject; +import flixel.FlxSprite; +import flixel.FlxState; +import flixel.FlxCamera; +import flixel.input.keyboard.FlxKey; +import flixel.addons.display.FlxGridOverlay; +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.graphics.FlxGraphic; +import flixel.text.FlxText; +import flixel.util.FlxColor; +import flixel.addons.ui.FlxInputText; +import flixel.addons.ui.FlxUI9SliceSprite; +import flixel.addons.ui.FlxUI; +import flixel.addons.ui.FlxUICheckBox; +import flixel.addons.ui.FlxUIInputText; +import flixel.addons.ui.FlxUINumericStepper; +import flixel.addons.ui.FlxUITabMenu; +import flixel.addons.ui.FlxUITooltip.FlxUITooltipStyle; +import flixel.ui.FlxButton; +import flixel.ui.FlxSpriteButton; +import openfl.net.FileReference; +import openfl.events.Event; +import openfl.events.IOErrorEvent; +import haxe.Json; +import Character; +import flixel.system.debug.interaction.tools.Pointer.GraphicCursorCross; +import lime.system.Clipboard; +import flixel.animation.FlxAnimation; +import lime.utils.Assets; +import flixel.graphics.frames.FlxAtlasFrames; + +#if desktop +import Sys; +import sys.FileSystem; +import sys.io.File; +#end + +using StringTools; + +/** + *DEBUG MODE + */ +class CharacterEditorState extends MusicBeatState +{ + var char:Character; + var ghostChar:Character; + var positioningChar:Character; + var textAnim:FlxText; + var bgLayer:FlxTypedGroup; + var charLayer:FlxTypedGroup; + var dumbTexts:FlxTypedGroup; + //var animList:Array = []; + var curAnim:Int = 0; + var daAnim:String = 'spooky'; + var goToPlayState:Bool = true; + var camFollow:FlxObject; + + public function new(daAnim:String = 'spooky', goToPlayState:Bool = true) + { + super(); + this.daAnim = daAnim; + this.goToPlayState = goToPlayState; + } + + var UI_box:FlxUITabMenu; + var UI_characterbox:FlxUITabMenu; + + private var camEditor:FlxCamera; + private var camHUD:FlxCamera; + private var camMenu:FlxCamera; + + var changeBGbutton:FlxButton; + var leHealthIcon:HealthIcon; + var characterList:Array = []; + + var cameraFollowPointer:FlxSprite; + var healthBarBG:FlxSprite; + + override function create() + { + FlxG.sound.playMusic(Paths.music('kawaruslow'), 0.7); + + camEditor = new FlxCamera(); + camHUD = new FlxCamera(); + camHUD.bgColor.alpha = 0; + camMenu = new FlxCamera(); + camMenu.bgColor.alpha = 0; + + FlxG.cameras.reset(camEditor); + FlxG.cameras.add(camHUD); + FlxG.cameras.add(camMenu); + FlxCamera.defaultCameras = [camEditor]; + + bgLayer = new FlxTypedGroup(); + add(bgLayer); + charLayer = new FlxTypedGroup(); + add(charLayer); + + var pointer:FlxGraphic = FlxGraphic.fromClass(GraphicCursorCross); + cameraFollowPointer = new FlxSprite().loadGraphic(pointer); + cameraFollowPointer.setGraphicSize(40, 40); + cameraFollowPointer.updateHitbox(); + cameraFollowPointer.color = FlxColor.WHITE; + add(cameraFollowPointer); + + changeBGbutton = new FlxButton(FlxG.width - 360, 25, "", function() + { + onPixelBG = !onPixelBG; + reloadBGs(); + }); + changeBGbutton.cameras = [camMenu]; + + loadChar(!daAnim.startsWith('bf'), false); + + healthBarBG = new FlxSprite(30, FlxG.height - 75).loadGraphic(Paths.image('healthBar')); + healthBarBG.scrollFactor.set(); + add(healthBarBG); + healthBarBG.cameras = [camHUD]; + + leHealthIcon = new HealthIcon(char.healthIcon, false); + leHealthIcon.y = FlxG.height - 150; + add(leHealthIcon); + leHealthIcon.cameras = [camHUD]; + + dumbTexts = new FlxTypedGroup(); + add(dumbTexts); + dumbTexts.cameras = [camHUD]; + + textAnim = new FlxText(300, 16); + textAnim.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + textAnim.borderSize = 1; + textAnim.size = 32; + textAnim.scrollFactor.set(); + textAnim.cameras = [camHUD]; + add(textAnim); + + genBoyOffsets(); + + camFollow = new FlxObject(0, 0, 2, 2); + camFollow.screenCenter(); + add(camFollow); + + var tipText:FlxText = new FlxText(FlxG.width - 20, FlxG.height, 0, + "E/Q - Camera Zoom In/Out + \nJKLI - Move Camera + \nW/S - Previous/Next Animation + \nSpace - Play Animation + \nArrow Keys - Move Character Offset + \nR - Reset Current Offset + \nHold Shift to Move 10x faster\n", 12); + tipText.cameras = [camHUD]; + tipText.setFormat(null, 12, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + tipText.scrollFactor.set(); + tipText.borderSize = 1; + tipText.x -= tipText.width; + tipText.y -= tipText.height - 10; + add(tipText); + + FlxG.camera.follow(camFollow); + + var tabs = [ + //{name: 'Offsets', label: 'Offsets'}, + {name: 'Settings', label: 'Settings'}, + ]; + + UI_box = new FlxUITabMenu(null, tabs, true); + UI_box.cameras = [camMenu]; + + UI_box.resize(250, 120); + UI_box.x = FlxG.width - 275; + UI_box.y = 25; + UI_box.scrollFactor.set(); + + var tabs = [ + {name: 'Character', label: 'Character'}, + {name: 'Animations', label: 'Animations'}, + ]; + UI_characterbox = new FlxUITabMenu(null, tabs, true); + UI_characterbox.cameras = [camMenu]; + + UI_characterbox.resize(350, 350); + UI_characterbox.x = UI_box.x - 100; + UI_characterbox.y = UI_box.y + UI_box.height; + UI_characterbox.scrollFactor.set(); + add(UI_characterbox); + add(UI_box); + add(changeBGbutton); + + //addOffsetsUI(); + addSettingsUI(); + + addCharacterUI(); + addAnimationsUI(); + UI_characterbox.selected_tab_id = 'Character'; + + FlxG.mouse.visible = true; + reloadCharacterOptions(); + + super.create(); + } + + var onPixelBG:Bool = false; + var OFFSET_X:Float = 300; + function reloadBGs() { + var i:Int = bgLayer.members.length-1; + while(i >= 0) { + var memb:FlxSprite = bgLayer.members[i]; + if(memb != null) { + memb.kill(); + bgLayer.remove(memb); + memb.destroy(); + } + --i; + } + bgLayer.clear(); + var playerXDifference = 0; + if(char.isPlayer) playerXDifference = 670; + + if(onPixelBG) { + var playerYDifference:Float = 0; + if(char.isPlayer) { + playerXDifference += 200; + playerYDifference = 220; + } + + var bgSky:BGSprite = new BGSprite('weeb/weebSky', OFFSET_X - (playerXDifference / 2) - 300, 0 - playerYDifference, 0.1, 0.1); + bgLayer.add(bgSky); + bgSky.antialiasing = false; + + var repositionShit = -200 + OFFSET_X - playerXDifference; + + var bgSchool:BGSprite = new BGSprite('weeb/weebSchool', repositionShit, -playerYDifference + 6, 0.6, 0.90); + bgLayer.add(bgSchool); + bgSchool.antialiasing = false; + + var bgStreet:BGSprite = new BGSprite('weeb/weebStreet', repositionShit, -playerYDifference, 0.95, 0.95); + bgLayer.add(bgStreet); + bgStreet.antialiasing = false; + + var widShit = Std.int(bgSky.width * 6); + var bgTrees:FlxSprite = new FlxSprite(repositionShit - 380, -800 - playerYDifference); + bgTrees.frames = Paths.getPackerAtlas('weeb/weebTrees'); + 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); + bgLayer.add(bgTrees); + bgTrees.antialiasing = false; + + bgSky.setGraphicSize(widShit); + bgSchool.setGraphicSize(widShit); + bgStreet.setGraphicSize(widShit); + bgTrees.setGraphicSize(Std.int(widShit * 1.4)); + + bgSky.updateHitbox(); + bgSchool.updateHitbox(); + bgStreet.updateHitbox(); + bgTrees.updateHitbox(); + changeBGbutton.text = "Regular BG"; + } else { + var bg:BGSprite = new BGSprite('stageback', -600 + OFFSET_X - playerXDifference, -300, 0.9, 0.9); + bgLayer.add(bg); + + var stageFront:BGSprite = new BGSprite('stagefront', -650 + OFFSET_X - playerXDifference, 500, 0.9, 0.9); + stageFront.setGraphicSize(Std.int(stageFront.width * 1.1)); + stageFront.updateHitbox(); + bgLayer.add(stageFront); + + positioningChar = new Character(100 + OFFSET_X, 350, 'bf-placement', false); + positioningChar.debugMode = true; + positioningChar.alpha = 0.4; + positioningChar.flipX = !char.isPlayer; + positioningChar.dance(); + bgLayer.add(positioningChar); + + changeBGbutton.text = "Pixel BG"; + } + } + + function fixTheDamnOffsets() + { + if (!char.isCustom) + { + for (i in 0...char.animationsArray.length) + { + if (char.animOffsets.get(char.animationsArray[i].anim) != null) + { + var daOffset = char.animOffsets.get(char.animationsArray[i].anim); + char.animationsArray[i].offsets = [Std.int(daOffset[0]), Std.int(daOffset[1])]; + } + + if (char.animPlayerOffsets.get(char.animationsArray[i].anim) != null) + { + var daPlayerOffset = char.animPlayerOffsets.get(char.animationsArray[i].anim); + char.animationsArray[i].playerOffsets = [Std.int(daPlayerOffset[0]), Std.int(daPlayerOffset[1])]; + } + } + } + } + + /*var animationInputText:FlxUIInputText; + function addOffsetsUI() { + var tab_group = new FlxUI(null, UI_box); + tab_group.name = "Offsets"; + + animationInputText = new FlxUIInputText(15, 30, 100, 'idle', 8); + + var addButton:FlxButton = new FlxButton(animationInputText.x + animationInputText.width + 23, animationInputText.y - 2, "Add", function() + { + var theText:String = animationInputText.text; + if(theText != '') { + var alreadyExists:Bool = false; + for (i in 0...animList.length) { + if(animList[i] == theText) { + alreadyExists = true; + break; + } + } + + if(!alreadyExists) { + char.animOffsets.set(theText, [0, 0]); + animList.push(theText); + } + } + }); + + var removeButton:FlxButton = new FlxButton(animationInputText.x + animationInputText.width + 23, animationInputText.y + 20, "Remove", function() + { + var theText:String = animationInputText.text; + if(theText != '') { + for (i in 0...animList.length) { + if(animList[i] == theText) { + if(char.animOffsets.exists(theText)) { + char.animOffsets.remove(theText); + } + + animList.remove(theText); + if(char.animation.curAnim.name == theText && animList.length > 0) { + char.playAnim(animList[0], true); + } + break; + } + } + } + }); + + var saveButton:FlxButton = new FlxButton(animationInputText.x, animationInputText.y + 35, "Save Offsets", function() + { + saveOffsets(); + }); + + tab_group.add(new FlxText(10, animationInputText.y - 18, 0, 'Add/Remove Animation:')); + tab_group.add(addButton); + tab_group.add(removeButton); + tab_group.add(saveButton); + tab_group.add(animationInputText); + UI_box.addGroup(tab_group); + }*/ + + var TemplateCharacter:String = '{ + "animations": [ + { + "loop": false, + "offsets": [ + 0, + 0 + ], + "fps": 24, + "anim": "idle", + "indices": [], + "name": "Dad idle dance" + }, + { + "offsets": [ + 0, + 0 + ], + "indices": [], + "fps": 24, + "anim": "singLEFT", + "loop": false, + "name": "Dad Sing Note LEFT" + }, + { + "offsets": [ + 0, + 0 + ], + "indices": [], + "fps": 24, + "anim": "singDOWN", + "loop": false, + "name": "Dad Sing Note DOWN" + }, + { + "offsets": [ + 0, + 0 + ], + "indices": [], + "fps": 24, + "anim": "singUP", + "loop": false, + "name": "Dad Sing Note UP" + }, + { + "offsets": [ + 0, + 0 + ], + "indices": [], + "fps": 24, + "anim": "singRIGHT", + "loop": false, + "name": "Dad Sing Note RIGHT" + } + ], + "no_antialiasing": false, + "image": "characters/DADDY_DEAREST", + "position": [ + 0, + 0 + ], + "playerposition": [ + 0, + 0 + ], + "healthicon": "face", + "flip_x": false, + "healthbar_colors": [ + 161, + 161, + 161 + ], + "camera_position": [ + 0, + 0 + ], + "player_camera_position": [ + 0, + 0 + ], + "sing_duration": 4, + "scale": 1 + }'; + + var charDropDown:FlxUIDropDownMenuCustom; + function addSettingsUI() { + var tab_group = new FlxUI(null, UI_box); + tab_group.name = "Settings"; + + var check_player = new FlxUICheckBox(10, 60, null, null, "Playable Character", 100); + check_player.checked = daAnim.startsWith('bf'); + check_player.callback = function() + { + char.isPlayer = !char.isPlayer; + char.flipX = !char.flipX; + updatePointerPos(); + reloadBGs(); + char.flipAnims(); + ghostChar.flipX = char.flipX; + + if (char.isPlayer) + char.setPosition(char.playerPositionArray[0] + OFFSET_X + 100, char.playerPositionArray[1]); + else + char.setPosition(char.positionArray[0] + OFFSET_X + 100, char.positionArray[1]); + }; + + charDropDown = new FlxUIDropDownMenuCustom(10, 30, FlxUIDropDownMenuCustom.makeStrIdLabelArray([''], true), function(character:String) + { + daAnim = characterList[Std.parseInt(character)]; + check_player.checked = daAnim.startsWith('bf'); + loadChar(!check_player.checked); + updatePresence(); + reloadCharacterDropDown(); + }); + charDropDown.selectedLabel = daAnim; + reloadCharacterDropDown(); + + var reloadCharacter:FlxButton = new FlxButton(140, 20, "Reload Char", function() + { + loadChar(!check_player.checked); + reloadCharacterDropDown(); + }); + + var templateCharacter:FlxButton = new FlxButton(140, 50, "Load Template", function() + { + var parsedJson:CharacterFile = cast Json.parse(TemplateCharacter); + var characters:Array = [char, ghostChar]; + for (character in characters) + { + character.animOffsets.clear(); + character.animationsArray = parsedJson.animations; + for (anim in character.animationsArray) + { + character.addOffset(anim.anim, anim.offsets[0], anim.offsets[1]); + } + if(character.animationsArray[0] != null) { + character.playAnim(character.animationsArray[0].anim, true); + } + + character.singDuration = parsedJson.sing_duration; + character.positionArray = parsedJson.position; + character.cameraPosition = parsedJson.camera_position; + character.playerCameraPosition = parsedJson.player_camera_position; + + character.charPath = parsedJson.image + '.png'; + character.imageFile = parsedJson.image; + character.jsonScale = parsedJson.scale; + character.noAntialiasing = parsedJson.no_antialiasing; + character.originalFlipX = parsedJson.flip_x; + character.healthIcon = parsedJson.healthicon; + character.healthColorArray = parsedJson.healthbar_colors; + character.setPosition(character.positionArray[0] + OFFSET_X + 100, character.positionArray[1]); + } + + reloadCharacterImage(); + reloadCharacterDropDown(); + reloadCharacterOptions(); + resetHealthBarColor(); + updatePointerPos(); + genBoyOffsets(); + }); + templateCharacter.color = FlxColor.RED; + templateCharacter.label.color = FlxColor.WHITE; + + tab_group.add(new FlxText(charDropDown.x, charDropDown.y - 18, 0, 'Character:')); + tab_group.add(check_player); + tab_group.add(reloadCharacter); + tab_group.add(charDropDown); + tab_group.add(reloadCharacter); + tab_group.add(templateCharacter); + UI_box.addGroup(tab_group); + } + + var imageInputText:FlxUIInputText; + var healthIconInputText:FlxUIInputText; + var noteSkinInputText:FlxUIInputText; + + var singDurationStepper:FlxUINumericStepper; + var scaleStepper:FlxUINumericStepper; + var positionXStepper:FlxUINumericStepper; + var positionYStepper:FlxUINumericStepper; + var playerPositionXStepper:FlxUINumericStepper; + var playerPositionYStepper:FlxUINumericStepper; + var positionCameraXStepper:FlxUINumericStepper; + var positionCameraYStepper:FlxUINumericStepper; + + var positionPlayerCameraXStepper:FlxUINumericStepper; + var positionPlayerCameraYStepper:FlxUINumericStepper; + + var flipXCheckBox:FlxUICheckBox; + var noAntialiasingCheckBox:FlxUICheckBox; + var psychPlayerCheckBox:FlxUICheckBox; + + var healthColorStepperR:FlxUINumericStepper; + var healthColorStepperG:FlxUINumericStepper; + var healthColorStepperB:FlxUINumericStepper; + + function addCharacterUI() { + var tab_group = new FlxUI(null, UI_box); + tab_group.name = "Character"; + + imageInputText = new FlxUIInputText(15, 30, 200, 'characters/BOYFRIEND', 8); + var reloadImage:FlxButton = new FlxButton(imageInputText.x + 210, imageInputText.y - 3, "Reload Image", function() + { + char.imageFile = imageInputText.text; + reloadCharacterImage(); + if(char.animation.curAnim != null) { + char.playAnim(char.animation.curAnim.name, true); + } + }); + + var decideIconColor:FlxButton = new FlxButton(reloadImage.x, reloadImage.y + 30, "Get Icon Color", function() + { + var coolColor = FlxColor.fromInt(CoolUtil.dominantColor(leHealthIcon)); + healthColorStepperR.value = coolColor.red; + healthColorStepperG.value = coolColor.green; + healthColorStepperB.value = coolColor.blue; + getEvent(FlxUINumericStepper.CHANGE_EVENT, healthColorStepperR, null); + getEvent(FlxUINumericStepper.CHANGE_EVENT, healthColorStepperG, null); + getEvent(FlxUINumericStepper.CHANGE_EVENT, healthColorStepperB, null); + }); + + var copyOffset:FlxButton = new FlxButton(reloadImage.x - 100, reloadImage.y + 30, "Copy Offsets", function() + { + for (i in 0...char.animationsArray.length) + { + char.animationsArray[i].playerOffsets = char.animationsArray[i].offsets; + + if (char.isPlayer && char.animationsArray[i].playerOffsets != null && char.animationsArray[i].name == 'singLEFT') + { + + } + } + }); + + healthIconInputText = new FlxUIInputText(15, imageInputText.y + 35, 75, leHealthIcon.getCharacter(), 8); + + singDurationStepper = new FlxUINumericStepper(15, healthIconInputText.y + 45, 0.1, 4, 0, 999, 1); + + scaleStepper = new FlxUINumericStepper(15, singDurationStepper.y + 40, 0.05, 1, 0.05, 10, 2); + + flipXCheckBox = new FlxUICheckBox(singDurationStepper.x + 80, singDurationStepper.y, null, null, "Flip X", 50); + flipXCheckBox.checked = char.flipX; + if(char.isPlayer) flipXCheckBox.checked = !flipXCheckBox.checked; + flipXCheckBox.callback = function() { + char.originalFlipX = !char.originalFlipX; + char.flipX = char.originalFlipX; + if(char.isPlayer) char.flipX = !char.flipX; + + ghostChar.flipX = char.flipX; + }; + + noAntialiasingCheckBox = new FlxUICheckBox(flipXCheckBox.x, flipXCheckBox.y + 40, null, null, "No Antialiasing", 80); + noAntialiasingCheckBox.checked = char.noAntialiasing; + noAntialiasingCheckBox.callback = function() { + char.antialiasing = !noAntialiasingCheckBox.checked; + char.noAntialiasing = noAntialiasingCheckBox.checked; + }; + + psychPlayerCheckBox = new FlxUICheckBox(flipXCheckBox.x, noAntialiasingCheckBox.y + 40, null, null, "Psych Player Char", 80); + psychPlayerCheckBox.checked = char.isPsychPlayer; + psychPlayerCheckBox.callback = function() { + char.isPsychPlayer = psychPlayerCheckBox.checked; + }; + + positionXStepper = new FlxUINumericStepper(flipXCheckBox.x + 110, flipXCheckBox.y, 10, char.positionArray[0], -9000, 9000, 0); + positionYStepper = new FlxUINumericStepper(positionXStepper.x + 60, positionXStepper.y, 10, char.positionArray[1], -9000, 9000, 0); + + positionCameraXStepper = new FlxUINumericStepper(positionXStepper.x, positionXStepper.y + 40, 10, char.cameraPosition[0], -9000, 9000, 0); + positionCameraYStepper = new FlxUINumericStepper(positionYStepper.x, positionYStepper.y + 40, 10, char.cameraPosition[1], -9000, 9000, 0); + + playerPositionXStepper = new FlxUINumericStepper(positionXStepper.x, positionCameraXStepper.y + 40, 10, char.playerPositionArray[0], -9000, 9000, 0); + playerPositionYStepper = new FlxUINumericStepper(positionXStepper.x + 60, positionCameraYStepper.y + 40, 10, char.playerPositionArray[1], -9000, 9000, 0); + + positionPlayerCameraXStepper = new FlxUINumericStepper(playerPositionXStepper.x, playerPositionXStepper.y + 40, 10, char.playerCameraPosition[0], -9000, 9000, 0); + positionPlayerCameraYStepper = new FlxUINumericStepper(playerPositionYStepper.x, playerPositionYStepper.y + 40, 10, char.playerCameraPosition[1], -9000, 9000, 0); + + noteSkinInputText = new FlxUIInputText(15, playerPositionXStepper.y, 75, 'normal', 8); + + var saveCharacterButton:FlxButton = new FlxButton(reloadImage.x, noAntialiasingCheckBox.y + 140, "Save Character", function() { + saveCharacter(); + }); + + healthColorStepperR = new FlxUINumericStepper(singDurationStepper.x, saveCharacterButton.y, 20, char.healthColorArray[0], 0, 255, 0); + healthColorStepperG = new FlxUINumericStepper(singDurationStepper.x + 65, saveCharacterButton.y, 20, char.healthColorArray[1], 0, 255, 0); + healthColorStepperB = new FlxUINumericStepper(singDurationStepper.x + 130, saveCharacterButton.y, 20, char.healthColorArray[2], 0, 255, 0); + + tab_group.add(new FlxText(15, imageInputText.y - 18, 0, 'Image file name:')); + tab_group.add(new FlxText(15, healthIconInputText.y - 18, 0, 'Health icon name:')); + tab_group.add(new FlxText(15, noteSkinInputText.y - 18, 0, 'Noteskin:')); + tab_group.add(new FlxText(15, singDurationStepper.y - 18, 0, 'Sing Animation length:')); + tab_group.add(new FlxText(15, scaleStepper.y - 18, 0, 'Scale:')); + tab_group.add(new FlxText(positionXStepper.x, positionXStepper.y - 18, 0, 'Character X/Y:')); + tab_group.add(new FlxText(playerPositionXStepper.x, playerPositionXStepper.y - 18, 0, 'Character Player X/Y:')); + tab_group.add(new FlxText(positionCameraXStepper.x, positionCameraXStepper.y - 18, 0, 'Camera X/Y:')); + tab_group.add(new FlxText(positionPlayerCameraXStepper.x, positionPlayerCameraXStepper.y - 18, 0, 'Player Camera X/Y:')); + tab_group.add(new FlxText(healthColorStepperR.x, healthColorStepperR.y - 18, 0, 'Health bar R/G/B:')); + tab_group.add(imageInputText); + tab_group.add(reloadImage); + tab_group.add(copyOffset); + tab_group.add(decideIconColor); + tab_group.add(healthIconInputText); + tab_group.add(noteSkinInputText); + tab_group.add(singDurationStepper); + tab_group.add(scaleStepper); + tab_group.add(flipXCheckBox); + tab_group.add(noAntialiasingCheckBox); + tab_group.add(psychPlayerCheckBox); + tab_group.add(positionXStepper); + tab_group.add(positionYStepper); + tab_group.add(playerPositionXStepper); + tab_group.add(playerPositionYStepper); + tab_group.add(positionCameraXStepper); + tab_group.add(positionCameraYStepper); + tab_group.add(positionPlayerCameraXStepper); + tab_group.add(positionPlayerCameraYStepper); + tab_group.add(healthColorStepperR); + tab_group.add(healthColorStepperG); + tab_group.add(healthColorStepperB); + tab_group.add(saveCharacterButton); + UI_characterbox.addGroup(tab_group); + } + + var ghostDropDown:FlxUIDropDownMenuCustom; + var animationDropDown:FlxUIDropDownMenuCustom; + var animationInputText:FlxUIInputText; + var animationNameInputText:FlxUIInputText; + var animationIndicesInputText:FlxUIInputText; + var animationNameFramerate:FlxUINumericStepper; + var animationLoopCheckBox:FlxUICheckBox; + function addAnimationsUI() { + var tab_group = new FlxUI(null, UI_box); + tab_group.name = "Animations"; + + animationInputText = new FlxUIInputText(15, 85, 80, '', 8); + animationNameInputText = new FlxUIInputText(animationInputText.x, animationInputText.y + 35, 150, '', 8); + animationIndicesInputText = new FlxUIInputText(animationNameInputText.x, animationNameInputText.y + 40, 250, '', 8); + animationNameFramerate = new FlxUINumericStepper(animationInputText.x + 170, animationInputText.y, 1, 24, 0, 240, 0); + animationLoopCheckBox = new FlxUICheckBox(animationNameInputText.x + 170, animationNameInputText.y - 1, null, null, "Should it Loop?", 100); + + animationDropDown = new FlxUIDropDownMenuCustom(15, animationInputText.y - 55, FlxUIDropDownMenuCustom.makeStrIdLabelArray([''], true), function(pressed:String) { + var selectedAnimation:Int = Std.parseInt(pressed); + var anim:AnimArray = char.animationsArray[selectedAnimation]; + animationInputText.text = anim.anim; + animationNameInputText.text = anim.name; + animationLoopCheckBox.checked = anim.loop; + animationNameFramerate.value = anim.fps; + + var indicesStr:String = anim.indices.toString(); + animationIndicesInputText.text = indicesStr.substr(1, indicesStr.length - 2); + }); + + ghostDropDown = new FlxUIDropDownMenuCustom(animationDropDown.x + 150, animationDropDown.y, FlxUIDropDownMenuCustom.makeStrIdLabelArray([''], true), function(pressed:String) { + var selectedAnimation:Int = Std.parseInt(pressed); + ghostChar.visible = false; + char.alpha = 1; + if(selectedAnimation > 0) { + ghostChar.visible = true; + ghostChar.playAnim(ghostChar.animationsArray[selectedAnimation-1].anim, true); + char.alpha = 0.85; + } + }); + + var addUpdateButton:FlxButton = new FlxButton(70, animationIndicesInputText.y + 130, "Add/Update", function() { + var indices:Array = []; + var indicesStr:Array = animationIndicesInputText.text.trim().split(','); + if(indicesStr.length > 1) { + for (i in 0...indicesStr.length) { + var index:Int = Std.parseInt(indicesStr[i]); + if(indicesStr[i] != null && indicesStr[i] != '' && !Math.isNaN(index) && index > -1) { + indices.push(index); + } + } + } + + var lastAnim:String = ''; + if(char.animationsArray[curAnim] != null) { + lastAnim = char.animationsArray[curAnim].anim; + } + + var lastOffsets:Array = [0, 0]; + for (anim in char.animationsArray) { + if(animationInputText.text == anim.anim) { + + lastOffsets = anim.offsets; + + if(char.animation.getByName(animationInputText.text) != null) { + char.animation.remove(animationInputText.text); + } + char.animationsArray.remove(anim); + } + } + + var lastPlayerOffsets:Array = [0, 0]; + for (anim in char.animationsArray) { + if(animationInputText.text == anim.anim) { + + if(anim.playerOffsets != null && anim.playerOffsets.length > 1) + lastPlayerOffsets = anim.playerOffsets; + else if(anim.offsets != null && anim.offsets.length > 1) + lastPlayerOffsets = anim.offsets; + + if(char.animation.getByName(animationInputText.text) != null) { + char.animation.remove(animationInputText.text); + } + char.animationsArray.remove(anim); + } + } + + var newAnim:AnimArray = { + anim: animationInputText.text, + name: animationNameInputText.text, + fps: Math.round(animationNameFramerate.value), + loop: animationLoopCheckBox.checked, + indices: indices, + offsets: lastOffsets, + playerOffsets: lastPlayerOffsets + }; + if(indices != null && indices.length > 0) { + char.animation.addByIndices(newAnim.anim, newAnim.name, newAnim.indices, "", newAnim.fps, newAnim.loop); + } else { + char.animation.addByPrefix(newAnim.anim, newAnim.name, newAnim.fps, newAnim.loop); + } + + if(!char.animOffsets.exists(newAnim.anim)) { + char.addOffset(newAnim.anim, 0, 0); + } + char.animationsArray.push(newAnim); + + if(lastAnim == animationInputText.text) { + var leAnim:FlxAnimation = char.animation.getByName(lastAnim); + if(leAnim != null && leAnim.frames.length > 0) { + char.playAnim(lastAnim, true); + } else { + for(i in 0...char.animationsArray.length) { + if(char.animationsArray[i] != null) { + leAnim = char.animation.getByName(char.animationsArray[i].anim); + if(leAnim != null && leAnim.frames.length > 0) { + char.playAnim(char.animationsArray[i].anim, true); + curAnim = i; + break; + } + } + } + } + } + + reloadAnimationDropDown(); + genBoyOffsets(); + trace('Added/Updated animation: ' + animationInputText.text); + }); + + var removeButton:FlxButton = new FlxButton(180, animationIndicesInputText.y + 130, "Remove", function() { + for (anim in char.animationsArray) { + if(animationInputText.text == anim.anim) { + var resetAnim:Bool = false; + if(char.animation.curAnim != null && anim.anim == char.animation.curAnim.name) resetAnim = true; + + if(char.animation.getByName(anim.anim) != null) { + char.animation.remove(anim.anim); + } + if(char.animOffsets.exists(anim.anim)) { + char.animOffsets.remove(anim.anim); + } + char.animationsArray.remove(anim); + + if(resetAnim && char.animationsArray.length > 0) { + char.playAnim(char.animationsArray[0].anim, true); + } + reloadAnimationDropDown(); + genBoyOffsets(); + trace('Removed animation: ' + animationInputText.text); + break; + } + } + }); + + tab_group.add(new FlxText(animationDropDown.x, animationDropDown.y - 18, 0, 'Animations:')); + tab_group.add(new FlxText(ghostDropDown.x, ghostDropDown.y - 18, 0, 'Animation Ghost:')); + tab_group.add(new FlxText(animationInputText.x, animationInputText.y - 18, 0, 'Animation name:')); + tab_group.add(new FlxText(animationNameFramerate.x, animationNameFramerate.y - 18, 0, 'Framerate:')); + tab_group.add(new FlxText(animationNameInputText.x, animationNameInputText.y - 18, 0, 'Animation on .XML/.TXT file:')); + tab_group.add(new FlxText(animationIndicesInputText.x, animationIndicesInputText.y - 18, 0, 'ADVANCED - Animation Indices:')); + + tab_group.add(animationInputText); + tab_group.add(animationNameInputText); + tab_group.add(animationIndicesInputText); + tab_group.add(animationNameFramerate); + tab_group.add(animationLoopCheckBox); + tab_group.add(addUpdateButton); + tab_group.add(removeButton); + tab_group.add(ghostDropDown); + tab_group.add(animationDropDown); + UI_characterbox.addGroup(tab_group); + } + + override function getEvent(id:String, sender:Dynamic, data:Dynamic, ?params:Array) { + if(id == FlxUIInputText.CHANGE_EVENT && (sender is FlxUIInputText)) { + if(sender == healthIconInputText) { + leHealthIcon.changeIcon(healthIconInputText.text); + char.healthIcon = healthIconInputText.text; + updatePresence(); + } + else if(sender == noteSkinInputText) { + char.noteSkin = noteSkinInputText.text; + } + else if(sender == imageInputText) { + char.imageFile = imageInputText.text; + } + } else if(id == FlxUINumericStepper.CHANGE_EVENT && (sender is FlxUINumericStepper)) { + if (sender == scaleStepper) + { + reloadCharacterImage(); + char.jsonScale = sender.value; + char.setGraphicSize(Std.int(char.width * char.jsonScale)); + char.updateHitbox(); + reloadGhost(); + updatePointerPos(); + + if(char.animation.curAnim != null) { + char.playAnim(char.animation.curAnim.name, true); + } + } + else if(sender == positionXStepper) + { + char.positionArray[0] = positionXStepper.value; + if (!char.isPlayer) + char.x = char.positionArray[0] + OFFSET_X + 100; + updatePointerPos(); + } + else if(sender == singDurationStepper) + { + char.singDuration = singDurationStepper.value;//ermm you forgot this?? + } + else if(sender == positionYStepper) + { + char.positionArray[1] = positionYStepper.value; + if (!char.isPlayer) + char.y = char.positionArray[1]; + updatePointerPos(); + } + else if(sender == playerPositionXStepper) + { + char.playerPositionArray[0] = playerPositionXStepper.value; + if (char.isPlayer) + char.x = char.playerPositionArray[0] + OFFSET_X + 100; + updatePointerPos(); + } + else if(sender == playerPositionYStepper) + { + char.playerPositionArray[1] = playerPositionYStepper.value; + if (char.isPlayer) + char.y = char.playerPositionArray[1]; + updatePointerPos(); + } + else if(sender == positionCameraXStepper) + { + char.cameraPosition[0] = positionCameraXStepper.value; + updatePointerPos(); + } + else if(sender == positionCameraYStepper) + { + char.cameraPosition[1] = positionCameraYStepper.value; + updatePointerPos(); + } + else if(sender == positionPlayerCameraXStepper) + { + char.playerCameraPosition[0] = positionPlayerCameraXStepper.value; + updatePointerPos(); + } + else if(sender == positionPlayerCameraYStepper) + { + char.playerCameraPosition[1] = positionPlayerCameraYStepper.value; + updatePointerPos(); + } + else if(sender == healthColorStepperR) + { + char.healthColorArray[0] = Math.round(healthColorStepperR.value); + healthBarBG.color = FlxColor.fromRGB(char.healthColorArray[0], char.healthColorArray[1], char.healthColorArray[2]); + } + else if(sender == healthColorStepperG) + { + char.healthColorArray[1] = Math.round(healthColorStepperG.value); + healthBarBG.color = FlxColor.fromRGB(char.healthColorArray[0], char.healthColorArray[1], char.healthColorArray[2]); + } + else if(sender == healthColorStepperB) + { + char.healthColorArray[2] = Math.round(healthColorStepperB.value); + healthBarBG.color = FlxColor.fromRGB(char.healthColorArray[0], char.healthColorArray[1], char.healthColorArray[2]); + } + } + } + + function reloadCharacterImage() { + var lastAnim:String = ''; + if(char.animation.curAnim != null) { + lastAnim = char.animation.curAnim.name; + } + + var daPath:String = char.imageFile; + + var anims:Array = char.animationsArray.copy(); + if(Paths.fileExists('images/' + daPath + '.txt', TEXT)) { + char.frames = Paths.getPackerAtlas(daPath); + } else { + + if (Assets.exists(Paths.image(daPath))) + char.frames = Paths.getSparrowAtlas(daPath); + else + { + if (!Paths.currentTrackedAssets.exists(daPath)) + Paths.cacheImage(daPath, 'preload'); + + var rawPic = Paths.currentTrackedAssets.get(daPath); + var rawXml:String; + + if (FileSystem.exists(FileSystem.absolutePath("assets/shared/images/"+daPath+".xml"))) + rawXml = File.getContent(FileSystem.absolutePath("assets/shared/images/"+daPath+".xml")); + else if (FileSystem.exists(Paths.modsXml(daPath))) + rawXml = File.getContent(Paths.modsXml(daPath)); + else + rawXml = File.getContent(Paths.xmlNew('images/' + daPath)); + + char.frames = FlxAtlasFrames.fromSparrow(rawPic,rawXml); + } + } + + if(char.animationsArray != null && char.animationsArray.length > 0) { + for (anim in char.animationsArray) { + var animAnim:String = '' + anim.anim; + var animName:String = '' + anim.name; + var animFps:Int = anim.fps; + var animLoop:Bool = !!anim.loop; //Bruh + var animIndices:Array = anim.indices; + if(animIndices != null && animIndices.length > 0) { + char.animation.addByIndices(animAnim, animName, animIndices, "", animFps, animLoop); + } else { + char.animation.addByPrefix(animAnim, animName, animFps, animLoop); + } + } + } else { + char.quickAnimAdd('idle', 'BF idle dance'); + } + + if(lastAnim != '') { + char.playAnim(lastAnim, true); + } else { + char.dance(); + } + ghostDropDown.selectedLabel = ''; + reloadGhost(); + } + + function genBoyOffsets():Void + { + var daLoop:Int = 0; + + var i:Int = dumbTexts.members.length-1; + while(i >= 0) { + var memb:FlxText = dumbTexts.members[i]; + if(memb != null) { + memb.kill(); + dumbTexts.remove(memb); + memb.destroy(); + } + --i; + } + dumbTexts.clear(); + + var text:FlxText = new FlxText(10, 20 + (18 * daLoop), 0, 'Offsets:', 15); + text.setFormat(null, 16, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + text.scrollFactor.set(); + text.borderSize = 1; + dumbTexts.add(text); + text.cameras = [camHUD]; + daLoop++; + + for (anim => offsets in char.animOffsets) + { + var text:FlxText = new FlxText(10, 20 + (18 * daLoop), 0, anim + ": " + offsets, 15); + text.setFormat(null, 16, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + text.scrollFactor.set(); + text.borderSize = 1; + dumbTexts.add(text); + text.cameras = [camHUD]; + + daLoop++; + } + + if (char.animPlayerOffsets != null) + { + daLoop++; + + var text:FlxText = new FlxText(10, 20 + (18 * daLoop), 0, 'Player Offsets:', 15); + text.setFormat(null, 16, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + text.scrollFactor.set(); + text.borderSize = 1; + dumbTexts.add(text); + text.cameras = [camHUD]; + daLoop++; + + for (anim => playerOffsets in char.animPlayerOffsets) + { + var text:FlxText = new FlxText(10, 20 + (18 * daLoop), 0, anim + ": " + playerOffsets, 15); + text.setFormat(null, 16, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + text.scrollFactor.set(); + text.borderSize = 1; + dumbTexts.add(text); + text.cameras = [camHUD]; + + daLoop++; + } + } + + textAnim.visible = true; + if(dumbTexts.length < 1) { + var text:FlxText = new FlxText(10, 38, 0, "ERROR! No animations found.", 15); + text.scrollFactor.set(); + text.borderSize = 1; + dumbTexts.add(text); + textAnim.visible = false; + } + } + + function loadChar(isDad:Bool, blahBlahBlah:Bool = true) { + var i:Int = charLayer.members.length-1; + while(i >= 0) { + var memb:Character = charLayer.members[i]; + if(memb != null) { + memb.kill(); + charLayer.remove(memb); + memb.destroy(); + } + --i; + } + charLayer.clear(); + ghostChar = new Character(0, 0, daAnim, !isDad); + ghostChar.debugMode = true; + ghostChar.alpha = 0.6; + + char = new Character(0, 0, daAnim, !isDad); + if(char.animationsArray[0] != null) { + char.playAnim(char.animationsArray[0].anim, true); + } + char.debugMode = true; + + charLayer.add(ghostChar); + charLayer.add(char); + + if (!char.isCustom) + { + var offset = new CharacterOffsets(daAnim, false); + char.positionArray[0] = offset.daOffsetArray[0]; + char.positionArray[1] = offset.daOffsetArray[1]; + + var daOffset = new CharacterOffsets(daAnim, true); + char.playerPositionArray[0] = daOffset.daOffsetArray[0]; + + if (daOffset.hasOffsets) + char.playerPositionArray[1] = daOffset.daOffsetArray[1] + 350; + + fixTheDamnOffsets(); + } + + char.setPosition(char.positionArray[0] + OFFSET_X + 100, char.positionArray[1]); + + /* THIS FUNCTION WAS USED TO PUT THE .TXT OFFSETS INTO THE .JSON + + for (anim => offset in char.animOffsets) { + var leAnim:AnimArray = findAnimationByName(anim); + if(leAnim != null) { + leAnim.offsets = [offset[0], offset[1]]; + } + }*/ + + if(blahBlahBlah) { + genBoyOffsets(); + } + reloadCharacterOptions(); + reloadBGs(); + updatePointerPos(); + } + + function updatePointerPos() { + var x:Float = char.getMidpoint().x; + var y:Float = char.getMidpoint().y; + if(!char.isPlayer) { + x += 150 + char.cameraPosition[0]; + y -= 100 - char.cameraPosition[1]; + } else { + x -= 100 + char.playerCameraPosition[0]; + y -= 100 - char.playerCameraPosition[1]; + } + + x -= cameraFollowPointer.width / 2; + y -= cameraFollowPointer.height / 2; + cameraFollowPointer.setPosition(x, y); + } + + function findAnimationByName(name:String):AnimArray { + for (anim in char.animationsArray) { + if(anim.anim == name) { + return anim; + } + } + return null; + } + + function reloadCharacterOptions() { + if(UI_characterbox != null) { + + imageInputText.text = char.imageFile; + + healthIconInputText.text = char.healthIcon; + noteSkinInputText.text = char.noteSkin; + singDurationStepper.value = char.singDuration; + scaleStepper.value = char.jsonScale; + flipXCheckBox.checked = char.originalFlipX; + noAntialiasingCheckBox.checked = char.noAntialiasing; + resetHealthBarColor(); + leHealthIcon.changeIcon(healthIconInputText.text); + positionXStepper.value = char.positionArray[0]; + positionYStepper.value = char.positionArray[1]; + playerPositionXStepper.value = char.playerPositionArray[0]; + playerPositionYStepper.value = char.playerPositionArray[1]; + positionCameraXStepper.value = char.cameraPosition[0]; + positionCameraYStepper.value = char.cameraPosition[1]; + positionPlayerCameraXStepper.value = char.playerCameraPosition[0]; + positionPlayerCameraYStepper.value = char.playerCameraPosition[1]; + reloadAnimationDropDown(); + updatePresence(); + } + } + + function reloadAnimationDropDown() { + var anims:Array = []; + var ghostAnims:Array = ['']; + for (anim in char.animationsArray) { + if (anim.playerOffsets == null && anim.offsets != null) + anim.playerOffsets = anim.offsets; + anims.push(anim.anim); + ghostAnims.push(anim.anim); + } + if(anims.length < 1) anims.push('NO ANIMATIONS'); //Prevents crash + + animationDropDown.setData(FlxUIDropDownMenuCustom.makeStrIdLabelArray(anims, true)); + ghostDropDown.setData(FlxUIDropDownMenuCustom.makeStrIdLabelArray(ghostAnims, true)); + reloadGhost(); + } + + function reloadGhost() { + ghostChar.frames = char.frames; + for (anim in char.animationsArray) { + var animAnim:String = '' + anim.anim; + var animName:String = '' + anim.name; + var animFps:Int = anim.fps; + var animLoop:Bool = !!anim.loop; //Bruh + var animIndices:Array = anim.indices; + if(animIndices != null && animIndices.length > 0) { + ghostChar.animation.addByIndices(animAnim, animName, animIndices, "", animFps, animLoop); + } else { + ghostChar.animation.addByPrefix(animAnim, animName, animFps, animLoop); + } + + if(anim.offsets != null && anim.offsets.length > 1) { + ghostChar.addOffset(anim.anim, anim.offsets[0], anim.offsets[1]); + } + + if(anim.playerOffsets != null && anim.playerOffsets.length > 1) { + ghostChar.addPlayerOffset(anim.anim, anim.playerOffsets[0], anim.playerOffsets[1]); + } + } + + char.alpha = 0.85; + ghostChar.visible = true; + if(ghostDropDown.selectedLabel == '') { + ghostChar.visible = false; + char.alpha = 1; + } + ghostChar.color = 0xFF666688; + + ghostChar.setGraphicSize(Std.int(ghostChar.width * char.jsonScale)); + ghostChar.updateHitbox(); + } + + function reloadCharacterDropDown() { + var charsLoaded:Map = new Map(); + + #if MODS_ALLOWED + characterList = []; + /* //I don't like this. It's good for everything that ISN'T BETADCIU. + var directories:Array = [Paths.mods('characters/'), Paths.mods(Paths.currentModDirectory + '/characters/'), Paths.getPreloadPath('characters/')]; + for (i in 0...directories.length) { + var directory:String = directories[i]; + if(FileSystem.exists(directory)) { + for (file in FileSystem.readDirectory(directory)) { + var path = haxe.io.Path.join([directory, file]); + if (!sys.FileSystem.isDirectory(path) && file.endsWith('.json')) { + var charToCheck:String = file.substr(0, file.length - 5); + if(!charsLoaded.exists(charToCheck)) { + characterList.push(charToCheck); + charsLoaded.set(charToCheck, true); + } + } + } + } + }*/ + + //so I'll use this instead + if (FileSystem.exists(Paths.modFolders('data/characterList.txt'))) + characterList = CoolUtil.coolTextFile2(Paths.modFolders('data/characterList.txt')); + else + characterList = CoolUtil.coolTextFile(Paths.txt('characterList')); + #else + characterList = CoolUtil.coolTextFile(Paths.txt('characterList')); + #end + + charDropDown.setData(FlxUIDropDownMenuCustom.makeStrIdLabelArray(characterList, true)); + charDropDown.selectedLabel = daAnim; + } + + function runColorConversion() + { + var coolColor = FlxColor.fromString('#' + char.iconColor); + + char.healthColorArray[0] = coolColor.red; + char.healthColorArray[1] = coolColor.green; + char.healthColorArray[2] = coolColor.blue; + } + function resetHealthBarColor() { + + if (!char.isCustom) + runColorConversion(); + + healthColorStepperR.value = char.healthColorArray[0]; + healthColorStepperG.value = char.healthColorArray[1]; + healthColorStepperB.value = char.healthColorArray[2]; + healthBarBG.color = FlxColor.fromRGB(char.healthColorArray[0], char.healthColorArray[1], char.healthColorArray[2]); + } + + function updatePresence() { + #if desktop + // Updating Discord Rich Presence + DiscordClient.changePresence("Character Editor", "Character: " + daAnim, leHealthIcon.getCharacter()); + #end + } + + override function update(elapsed:Float) + { + if(char.animationsArray[curAnim] != null) { + textAnim.text = char.animationsArray[curAnim].anim; + + var curAnim:FlxAnimation = char.animation.getByName(char.animationsArray[curAnim].anim); + if(curAnim == null || curAnim.frames.length < 1) { + textAnim.text += ' (ERROR!)'; + } + } else { + textAnim.text = ''; + } + + var inputTexts:Array = [animationInputText, imageInputText, healthIconInputText, noteSkinInputText, animationNameInputText, animationIndicesInputText]; + for (i in 0...inputTexts.length) { + if(inputTexts[i].hasFocus) { + if(FlxG.keys.pressed.CONTROL && FlxG.keys.justPressed.V && Clipboard.text != null) { //Copy paste + inputTexts[i].text = ClipboardAdd(inputTexts[i].text); + inputTexts[i].caretIndex = inputTexts[i].text.length; + getEvent(FlxUIInputText.CHANGE_EVENT, inputTexts[i], null, []); + } + if(FlxG.keys.justPressed.ENTER) { + inputTexts[i].hasFocus = false; + } + super.update(elapsed); + return; + } + } + + if(!charDropDown.dropPanel.visible) { + if (FlxG.keys.justPressed.ESCAPE) { + FlxG.switchState(new PlayState()); + FlxG.mouse.visible = false; + return; + } + + if (FlxG.keys.justPressed.R) { + FlxG.camera.zoom = 1; + } + + if (FlxG.keys.pressed.E && FlxG.camera.zoom < 3) { + FlxG.camera.zoom += elapsed * FlxG.camera.zoom; + if(FlxG.camera.zoom > 3) FlxG.camera.zoom = 3; + } + if (FlxG.keys.pressed.Q && FlxG.camera.zoom > 0.1) { + FlxG.camera.zoom -= elapsed * FlxG.camera.zoom; + if(FlxG.camera.zoom < 0.1) FlxG.camera.zoom = 0.1; + } + + if (FlxG.keys.pressed.I || FlxG.keys.pressed.J || FlxG.keys.pressed.K || FlxG.keys.pressed.L) + { + var addToCam:Float = 500 * elapsed; + if (FlxG.keys.pressed.SHIFT) + addToCam *= 4; + + if (FlxG.keys.pressed.I) + camFollow.y -= addToCam; + else if (FlxG.keys.pressed.K) + camFollow.y += addToCam; + + if (FlxG.keys.pressed.J) + camFollow.x -= addToCam; + else if (FlxG.keys.pressed.L) + camFollow.x += addToCam; + } + + if(char.animationsArray.length > 0) { + if (FlxG.keys.justPressed.W) + { + curAnim -= 1; + } + + if (FlxG.keys.justPressed.S) + { + curAnim += 1; + } + + if (curAnim < 0) + curAnim = char.animationsArray.length - 1; + + if (curAnim >= char.animationsArray.length) + curAnim = 0; + + if (FlxG.keys.justPressed.S || FlxG.keys.justPressed.W || FlxG.keys.justPressed.SPACE) + { + char.playAnim(char.animationsArray[curAnim].anim, true); + genBoyOffsets(); + } + + if (FlxG.keys.justPressed.R) + { + if (char.isPlayer) + { + char.animationsArray[curAnim].playerOffsets = [0, 0]; + char.addPlayerOffset(char.animationsArray[curAnim].anim, char.animationsArray[curAnim].playerOffsets[0], char.animationsArray[curAnim].playerOffsets[1]); + ghostChar.addPlayerOffset(char.animationsArray[curAnim].anim, char.animationsArray[curAnim].playerOffsets[0], char.animationsArray[curAnim].playerOffsets[1]); + genBoyOffsets(); + } + else + { + char.animationsArray[curAnim].offsets = [0, 0]; + + char.addOffset(char.animationsArray[curAnim].anim, char.animationsArray[curAnim].offsets[0], char.animationsArray[curAnim].offsets[1]); + ghostChar.addOffset(char.animationsArray[curAnim].anim, char.animationsArray[curAnim].offsets[0], char.animationsArray[curAnim].offsets[1]); + genBoyOffsets(); + } + } + + var controlArray:Array = [FlxG.keys.justPressed.LEFT, FlxG.keys.justPressed.RIGHT, FlxG.keys.justPressed.UP, FlxG.keys.justPressed.DOWN]; + + + + for (i in 0...controlArray.length) { + if(controlArray[i]) { + var holdShift = FlxG.keys.pressed.SHIFT; + var multiplier = 1; + if (holdShift) + multiplier = 10; + if (FlxG.keys.pressed.ALT) + multiplier = 50; + + var arrayVal = 0; + if(i > 1) arrayVal = 1; + + var negaMult:Int = 1; + if(i % 2 == 1) negaMult = -1; + + if (char.isPlayer) + { + char.animationsArray[curAnim].playerOffsets[arrayVal] += negaMult * multiplier; + char.addPlayerOffset(char.animationsArray[curAnim].anim, char.animationsArray[curAnim].playerOffsets[0], char.animationsArray[curAnim].playerOffsets[1]); + ghostChar.addPlayerOffset(char.animationsArray[curAnim].anim, char.animationsArray[curAnim].playerOffsets[0], char.animationsArray[curAnim].playerOffsets[1]); + } + else + { + char.animationsArray[curAnim].offsets[arrayVal] += negaMult * multiplier; + char.addOffset(char.animationsArray[curAnim].anim, char.animationsArray[curAnim].offsets[0], char.animationsArray[curAnim].offsets[1]); + ghostChar.addOffset(char.animationsArray[curAnim].anim, char.animationsArray[curAnim].offsets[0], char.animationsArray[curAnim].offsets[1]); + } + + char.playAnim(char.animationsArray[curAnim].anim, false); + if(ghostChar.animation.curAnim != null && char.animation.curAnim != null && char.animation.curAnim.name == ghostChar.animation.curAnim.name) { + ghostChar.playAnim(char.animation.curAnim.name, false); + } + genBoyOffsets(); + } + } + } + } + camMenu.zoom = FlxG.camera.zoom; + ghostChar.setPosition(char.x, char.y); + super.update(elapsed); + } + + var _file:FileReference; + /*private function saveOffsets() + { + var data:String = ''; + for (anim => offsets in char.animOffsets) { + data += anim + ' ' + offsets[0] + ' ' + offsets[1] + '\n'; + } + + if (data.length > 0) + { + _file = new FileReference(); + _file.addEventListener(Event.COMPLETE, onSaveComplete); + _file.addEventListener(Event.CANCEL, onSaveCancel); + _file.addEventListener(IOErrorEvent.IO_ERROR, onSaveError); + _file.save(data, daAnim + "Offsets.txt"); + } + }*/ + + function onSaveComplete(_):Void + { + _file.removeEventListener(Event.COMPLETE, onSaveComplete); + _file.removeEventListener(Event.CANCEL, onSaveCancel); + _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); + _file = null; + FlxG.log.notice("Successfully saved file."); + } + + /** + * Called when the save file dialog is cancelled. + */ + function onSaveCancel(_):Void + { + _file.removeEventListener(Event.COMPLETE, onSaveComplete); + _file.removeEventListener(Event.CANCEL, onSaveCancel); + _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); + _file = null; + } + + /** + * Called if there is an error while saving the gameplay recording. + */ + function onSaveError(_):Void + { + _file.removeEventListener(Event.COMPLETE, onSaveComplete); + _file.removeEventListener(Event.CANCEL, onSaveCancel); + _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); + _file = null; + FlxG.log.error("Problem saving file"); + } + + function saveCharacter() { + var json = { + "animations": char.animationsArray, + "image": char.imageFile, + "scale": char.jsonScale, + "sing_duration": char.singDuration, + "healthicon": char.healthIcon, + + "position": char.positionArray, + "playerposition": char.playerPositionArray, + "camera_position": char.cameraPosition, + "player_camera_position": char.playerCameraPosition, + "noteSkin": char.noteSkin, + + "flip_x": char.originalFlipX, + "no_antialiasing": char.noAntialiasing, + "isPlayerChar": char.isPsychPlayer, + "healthbar_colors": char.healthColorArray + }; + + var data:String = Json.stringify(json, "\t"); + + if (data.length > 0) + { + _file = new FileReference(); + _file.addEventListener(Event.COMPLETE, onSaveComplete); + _file.addEventListener(Event.CANCEL, onSaveCancel); + _file.addEventListener(IOErrorEvent.IO_ERROR, onSaveError); + _file.save(data, daAnim + ".json"); + } + } + + function ClipboardAdd(prefix:String = ''):String { + if(prefix.toLowerCase().endsWith('v')) //probably copy paste attempt + { + prefix = prefix.substring(0, prefix.length-1); + } + + var text:String = prefix + Clipboard.text.replace('\n', ''); + return text; + } +} diff --git a/source/CharacterOffsets.hx b/source/CharacterOffsets.hx new file mode 100644 index 000000000..1ebae2c82 --- /dev/null +++ b/source/CharacterOffsets.hx @@ -0,0 +1,579 @@ +package; + +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.animation.FlxBaseAnimation; +import flixel.graphics.frames.FlxAtlasFrames; +import flixel.util.FlxColor; +import lime.app.Application; + +using StringTools; + +//bcuz god damn it. those offset things in playstate take up a bunch of space + +class CharacterOffsets +{ + public var daOffsetArray:Array = [0, 0, 0, 0, 0, 0]; + public var hasOffsets:Bool = true; + + public function new(curCharacter:String = 'dad', isPlayer:Bool = false, ?isGF:Bool = false) + { + //in order this is +x, +y, +camPosX, +camPosY, +camPosX from midpoint, +camPosY from midpoint. + daOffsetArray = [0, 0, 0, 0, 0, 0]; + + if (isGF) + { + switch(curCharacter) + { + case 'gf-peri-whitty': daOffsetArray = [-230, -80, 0, 0, 0, 0]; + case 'gf-tea-tankmen': daOffsetArray = [-200, -80, 0, 0, 0, 0]; + case 'gf-sarv': daOffsetArray = [105, 15, 0, 0, 0, 0]; + case 'gf-bf-radio': daOffsetArray = [-20, 0, 0, 0, 0, 0]; + case 'gf-edd': + if (!PlayState.curStage.contains('school')) + daOffsetArray = [100, 300, 0, 0, 0, 0]; + case 'gf-judgev2': daOffsetArray = [50, 80, 0, 0, 0, 0]; + case 'gf-christmas': daOffsetArray = [-50, 0, 0, 0, 0, 0]; + } + return; + } + if (!isPlayer) + { + switch (curCharacter) + { + case 'spooky-pelo' | 'tankman' | 'tankman-animations': + daOffsetArray = [0, 200, 0, 0, 0, 0]; + case 'matt': + daOffsetArray = [20, 310, 0, 0, 0, 0]; + case 'spooky' | 'gura-amelia' | 'gura-amelia-bw' | 'amesame-shutup': + daOffsetArray = [-100, 190, 0, 0, 0, 0]; + if (curCharacter == 'spooky') daOffsetArray[1] = 200; + case 'void': + daOffsetArray = [-350, -30, 0, 0, 0, 0]; + case 'pompom-mad': + daOffsetArray = [0, 255, 0, 0, 0, 0]; + case 'hallow': + daOffsetArray = [-120, 50, 0, 0, 0, 0]; + case 'bf-sans-new': + daOffsetArray = [-120, 250, 0, 0, 0, 0]; + case 'bf' | 'bf-confused': + daOffsetArray = [0, 350, 0, 0, 0, 0]; + case 'taki': + daOffsetArray = [-90, -100, 0, 0, 0, 0]; + case 'oswald-happy' | 'oswald-angry': + daOffsetArray = [-90, 240, 0, 0, 0, 0]; + case 'mia' | 'mia-lookstraight' | 'mia-wire': + daOffsetArray = [80, 140, 0, 0, 250, -100]; + case 'sayori': + daOffsetArray = [0, 110, 400, 0, 0, 0]; + case 'natsuki': + daOffsetArray = [60, 170, 400, 0, 0, 0]; + case 'yuri-crazy' | 'yuri-crazy-bw': + daOffsetArray = [20, 112, 400, 0, 0, 0]; + case 'yuri': + daOffsetArray = [20, 0, 400, 0, 0, 0]; + case 'monika-real': + daOffsetArray = [-80, -10, 400, 0, 0, 0]; + case 'bigmonika': + daOffsetArray = [0, 0, 0, 0, -100, -200]; + case 'yukichi-police': + daOffsetArray = [-70, 130, 0, 0, 0, 0]; + case 'exe' | 'exe-bw': + daOffsetArray = [100, 175, 0, 0, 0, 0]; + case 'duet-sm': + daOffsetArray = [150, 380, 0, 0, 300, 0]; + case 'sunky': + daOffsetArray = [-210, 130, 0, 0, 0, 0]; + case 'cj-ruby' | 'cj-ruby-both': + daOffsetArray = [-50, 0, 0, 0, 0, 0]; + case 'bosip' | 'demoncass': + daOffsetArray = [0, -50, 0, 0, 0, 0]; + case 'hex-virus' | 'agoti-wire' | 'agoti-glitcher' | 'agoti-mad' | 'haachama' | 'haachama-blue': + daOffsetArray = [0, 100, 0, 0, 0, 0]; + case 'whittyCrazy' | 'whittyCrazy-9key': + daOffsetArray = [-105, 20, 400, 0, 0, 0]; + case 'ruv': + daOffsetArray = [0, -70, 0, 0, 0, 0]; + case 'sarvente' | 'sarvente-dark' | 'sarvente-worried' | 'sarvente-worried-blue': + daOffsetArray = [-85, -25, 0, 0, 0, 0]; + case 'monster-christmas' | 'monster': + daOffsetArray = [-60, 90, 0, 0, 0, 0]; + if (curCharacter == 'monster-christmas') daOffsetArray[1] = 50; + case 'dad' | 'shaggy' | 'lila' | 'kapi' | 'kapi-angry': + daOffsetArray = [0, -10, 400, 0, 0, 0]; + if (curCharacter == 'kapi') daOffsetArray[1] = -40; + case 'whitty' | 'whitty-b3': + daOffsetArray = [20, 10, 400, 0, 0, 0]; + case 'midas' | 'midas-double' | 'midas-r': + daOffsetArray = [20, -10, 400, 0, 0, 0]; + case 'beepie': + daOffsetArray = [-25, 215, 0, 0, 0, 0]; + case 'dad-mad': + daOffsetArray = [-30, -10, 400, 0, 0, 0]; + case 'bf-blantad': + daOffsetArray = [0, -75, 0, 0, 0, 0]; + case 'annie-bw' | 'phil' | 'alya': + daOffsetArray = [0, 350, 600, 0, 150, -100]; + case 'pico' | 'picoCrazy': + daOffsetArray = [-40, 300, 600, 0, 150, -100]; + case 'bob2' | 'peri': + daOffsetArray = [70, 50, 0, 0, 0, 0]; + if (curCharacter == 'peri') daOffsetArray[0] = -50; + case 'botan': + daOffsetArray = [-135, 245, 0, 0, 0, 0]; + case 'neko-crazy': + daOffsetArray = [-50, 230, 0, 0, 300, 0]; + case 'nene' | 'liz': + daOffsetArray = [0, 300, 600, 0, 0, 0]; + case 'bf-carol': + daOffsetArray = [-50, 340, 600, 0, 0, 0]; + case 'kou': + daOffsetArray = [-20, 270, 600, 0, 0, 0]; + case 'bf-annie': + daOffsetArray = [-50, 350, 600, 0, 0, 0]; + case 'bf-frisk' | 'bf-gf' | 'bf-aloe' | 'bf-kaity' | 'bf-six' | 'bf-aloe-deathless': + daOffsetArray = [-30, 350, 600, 0, 0, 0]; + case 'mario': + daOffsetArray = [70, 200, 0, 0, 0, 0]; + case 'little-man': + daOffsetArray = [150, 640, 0, 0, 0, 0]; + case 'retro': + daOffsetArray = [35, -80, 600, 0, 0, 0]; + case 'bf-sonic': + daOffsetArray = [-100, 350, 0, 0, 0, 0]; + case 'bico-christmas': + daOffsetArray = [-500, 100, 0, 0, 0, 0]; + case 'senpai' | 'monika' | 'senpai-angry' | 'kristoph-angry' | 'senpai-giddy' | 'baldi-angry-pixel' | 'mangle-angry' | 'monika-angry' | 'green-monika' | 'neon' + | 'matt-angry' | 'jackson' | 'mario-angry' | 'colt-angryd2' | 'colt-angryd2corrupted' | 'miku-pixel' | 'josuke': + if (PlayState.curStage.contains('school')) + daOffsetArray = [150, 360, 0, 0, 300, 0]; + else + daOffsetArray = [160, 260, 0, 0, 300, 0]; + case 'monika-finale': + daOffsetArray = [15, 460, 0, 0, 300, 0]; + case 'lane-pixel': + daOffsetArray = [210, 490, 0, 0, 300, -200]; + case 'bf-gf-pixel' | 'bf-pixel' | 'bf-botan-pixel': + daOffsetArray = [150, 460, 0, 0, 300, 0]; + case 'bf-sky': + daOffsetArray = [50, 230, 0, 0, 300, 0]; + case 'bf-whitty-pixel': + daOffsetArray = [150, 400, 0, 0, 300, 0]; + case 'gura-amelia-pixel': + daOffsetArray = [140, 400, 0, 0, 300, 0]; + case 'bitdad' | 'bitdadBSide' | 'bitdadcrazy': + daOffsetArray = [0, 75, 0, 0, 300, 0]; + case 'spirit' | 'spirit-glitchy': + daOffsetArray = [-150, 100, 0, 0, 300, 200]; + case 'sky-annoyed': + daOffsetArray = [-130, 120, 0, 0, 0, 0]; + case 'sky-happy': + daOffsetArray = [30, 230, 0, 0, 0, 0]; + case 'impostor' | 'impostor2': + daOffsetArray = [-150, 400, 400, -200, 0, 0]; + if (curCharacter == 'impostor2') + daOffsetArray[0] = -70; + case 'bob' | 'angrybob': + daOffsetArray = [-40, 280, 600, 0, 0, 0]; + case 'glitched-bob': + daOffsetArray = [-20, 285, 600, 0, 0, 0]; + case 'austin': + daOffsetArray = [-40, -130, 0, 0, 0, 0]; + case 'cjClone' | 'cj' | 'cj-new': + if (PlayState.SONG.song.toLowerCase() == 'expurgation') + daOffsetArray = [-250, -150, 0, 0, 0, 0]; + else + daOffsetArray = [0, 0, 0, 0, 0, 0]; + case 'exTricky': + daOffsetArray = [-250, -365, 0, 0, 0, 0]; + case 'momi': + daOffsetArray = [-90, 60, 0, 0, 300, 0]; + case 'sh-carol' | 'sarvente-lucifer': + daOffsetArray = [-65, -15, 0, 0, 0, 0]; + case 'roro': + daOffsetArray = [-200, 0, 0, 0, 0, 0]; + case 'rosie' | 'rosie-angry' | 'rosie-furious': + daOffsetArray = [-50, 100, 0, 0, 0, 0]; + case 'brody': + daOffsetArray = [0, 110, 0, 0, 300, 0]; + case 'selever' | 'teto': + daOffsetArray = [-50, -65, 0, 0, 300, 0]; + if (curCharacter == 'teto') daOffsetArray[1] == -50; + case 'camellia' | 'camelliahalloween': + daOffsetArray = [-300, -50, 0, 0, 0, 0]; + case 'exe-front': + daOffsetArray = [-120, 50, 0, 0, 0, 0]; + case 'bf-pixeld4BSide' | 'bf-pixeld4' | 'bf-demoncesar-pixel': + if (!PlayState.curStage.contains('school')) + daOffsetArray = [300, 150, 0, 0, 0, 0]; + case 'rebecca': + daOffsetArray = [-20, 0, 0, 500, 150, 100]; + if (!PlayState.curStage.contains('hungryhippo')) + daOffsetArray[1] = -50; + case 'baldi-angry': + daOffsetArray = [10, -70, 0, 500, 150, 100]; + case 'betty' | 'betty-bw': + daOffsetArray = [0, 200, 0, 0, 0, 0]; + case 'woody': + daOffsetArray = [65, 430, 0, 0, 0, 0]; + case 'twinsone' | 'twinstwo': + daOffsetArray = [-160, -50, 0, 0, 0, 0]; + case 'neonight': + daOffsetArray = [-110, 110, 0, 0, 0, 0]; + case 'arch': + daOffsetArray = [-155, -280, 0, 0, 0, 0]; + case 'hd-spirit-drip' | 'hd-spirit': + daOffsetArray = [-30, 0, 0, 0, 0, 0]; + case 'geese': + daOffsetArray = [-21, -15, 0, 0, 0, 0]; + case 'exe-revie': + daOffsetArray = [20, -30, 0, 0, 0, 0]; + case 'faker-transform': + daOffsetArray = [-110, -40, 0, 0, 0, 0]; + case 'faker': + daOffsetArray = [-30, 120, 0, 0, 0, 0]; + case 'taeyai': + daOffsetArray = [-105, -50, 0, 0, 0, 0]; + case 'tom2' | 'matt2' | 'edd2' | 'garcellotired' | 'garcellodead': + daOffsetArray = [-115, 0, 0, 0, 0, 0]; + case 'kalisa': + daOffsetArray = [-180, 145, 0, 0, 0, 0]; + case 'sunday': + daOffsetArray = [55, 255, 0, 0, 0, 0]; + case 'sunday-guitar': + daOffsetArray = [70, 260, 0, 0, 0, 0]; + case 'calli': + daOffsetArray = [10, -10, 0, 0, 0, 0]; + case 'kazuki': + daOffsetArray = [-40, 20, 0, 0, 0, 0]; + case 'sakuroma': + daOffsetArray = [-240, -260, 0, 0, 0, 0]; + case 'cg5' | 'exgf': + daOffsetArray = [50, 10, 0, 0, 0, 0]; + if (curCharacter == 'exgf') daOffsetArray[1] == -30; + case 'richard2' | 'richard1': + daOffsetArray = [-130, 40, 0, 0, 0, 0]; + case 'chara': + daOffsetArray = [-5, 300, 0, 0, 0, 0]; + case 'happymouse2' | 'happymouse2-bw' | 'happymouse' | 'happymouse-bw': + daOffsetArray = [-75, 60, 0, 0, 0, 0]; + case 'soul-tails' | 'soul-tails-bw': + daOffsetArray = [70, 265, 0, 0, 0, 0]; + case 'cablecrow': + daOffsetArray = [-240, -160, 0, 0, 0, 0]; + case 'tabi-crazy': + daOffsetArray = [-30, 50, 0, 0, 0, 0]; + case 'sonic' | 'sonic-forced' | 'sonic-mad': + daOffsetArray = [-150, 180, 0, 0, 0, 0]; + if (curCharacter == 'sonic-mad') daOffsetArray[0] == -120; + case 'auditor': + daOffsetArray = [-250, -50, 0, 0, 0, 0]; + case 'shadowbonnie-pixel': + daOffsetArray = [70, -90, 0, 0, 0, 0]; + case 'beast-sonic': + daOffsetArray = [-100, -80, 0, 0, 0, 0]; + case 'TDoll' | 'TDollAlt' | 'snow': + daOffsetArray = [-80, 120, 0, 0, 0, 0]; + if (curCharacter == 'snow') daOffsetArray[0] = -70; + case 'mami-holy': + daOffsetArray = [-230, -50, 0, 0, 0, 0]; + case 'daidem': + daOffsetArray = [-20, -150, 0, 0, 0, 0]; + case 'cassandra': + daOffsetArray = [-10, 40, 0, 0, 0, 0]; + case 'sarvente-transform': + daOffsetArray = [-200, -200, 0, 0, 0, 0]; + case 'sky-mad': + daOffsetArray = [-50, 170, 0, 0, 0, 0]; + case 'ace' | 'kadedev' | 'parents-christmas' | 'parents-christmas-angel' | 'daisysoul' | 'fujiwara' | 'miku' | 'bana' | 'bana-wire' | 'mackiepom' | 'updike': //for characters who literally change one value + daOffsetArray = [0, 0, 0, 0, 0, 0]; + switch (curCharacter) + { + case 'ace': daOffsetArray[1] = 25; + case 'kadedev': daOffsetArray[0] = 60; + case 'parents-christmas' | 'parents-christmas-angel': daOffsetArray[0] = -500; + case 'daisysoul': daOffsetArray[0] = -25; + case 'fujiwara' | 'mackiepom': daOffsetArray[1] = -20; + case 'miku': daOffsetArray[0] = -40; + case 'bana' | 'bana-wire': daOffsetArray[1] = 30; + case 'updike': daOffsetArray[0] = -100; + } + case 'tricky' | 'lord-x': + daOffsetArray = [-90, 100, 0, 0, 0, 0]; + if (curCharacter == 'lord-x') daOffsetArray[1] = 30; + case 'bf-sticky-scream': + daOffsetArray = [80, 365, 0, 0, 0, 0]; + case 'herobrine': + daOffsetArray = [100, 200, 0, 0, 0, 0]; + case 'cc': + daOffsetArray = [20, 170, 0, 0, 0, 0]; + case 'henry-angry': + daOffsetArray = [90, 300, 0, 0, 0, 0]; + case 'lexi' | 'lexi-b3': + daOffsetArray = [30, 160, 0, 0, 0, 0]; + case 'alucard': + daOffsetArray = [-20, 0, 0, 0, 0, 0]; + case 'bf-sky-pixel': + daOffsetArray = [80, 500, 0, 0, 0, 0]; + case 'bf-glitch-pixel': + daOffsetArray = [150, 450, 0, 0, 0, 0]; + case 'foks': + daOffsetArray = [0, 350, 0, 0, 0, 0]; + case 'agoti': + daOffsetArray = [-70, -80, 0, 0, 0, 0]; + case 'freddy': + daOffsetArray = [40, -40, 0, 0, 0, 0]; + case 'mel': + daOffsetArray = [-80, 0, 0, 0, 0, 0]; + case 'neon-bigger': + daOffsetArray = [100, 230, 0, 0, 0, 0]; + case 'opheebop': + daOffsetArray = [-40, 120, 0, 0, 0, 0]; + case 'zardy': + daOffsetArray = [-180, -30, 0, 0, 0, 240]; + case 'maijin-new' | 'majin-new-b3' | 'majin-new': + daOffsetArray = [-30, 150, 0, 0, 0, 0]; + case 'tornsketchy': + daOffsetArray = [-110, 150, 0, 0, 0, 0]; + case 'starecrown': + daOffsetArray = [-140, -70, 0, 0, 0, 0]; + case 'yukichi-mad-city' | 'yukichi-mad': + daOffsetArray = [-50, 0, 0, 0, 0, 0]; + case 'anders' | 'cyrix' | 'papyrus': + daOffsetArray = [0, 0, 0, 0, 0, 0]; + case 'pompom': + daOffsetArray = [30, 190, 0, 0, 0, 0]; + case 'hubert': + daOffsetArray = [80, -20, 0, 0, 0, 0]; + case 'jevil': daOffsetArray = [50, 180, 0, 0, 0, 0]; + case 'jester': daOffsetArray = [-30, 210, 0, 0, 0, 0]; + case 'dr-springheel': daOffsetArray = [40, -90, 0, 0, 0, 0]; + case 'glitch-angry': daOffsetArray = [190, 270, 0, 0, 0, 0]; + default: + daOffsetArray = [0, 0, 0, 0, 0, 0]; + hasOffsets = false; + } + } + else if (isPlayer) + { + switch (curCharacter) + { + case 'mia' | 'mia-lookstraight' | 'mia-wire': daOffsetArray = [20, -220, 0, 0, 0, 0]; + case 'jevil': daOffsetArray = [-20, -170, 0, 0, 0, 0]; + case 'jester': daOffsetArray = [30, -140, 0, 0, 0, 0]; + case 'henry-angry': daOffsetArray = [150, -80, 0, 0, 0, 0]; + case 'taki': daOffsetArray = [-190, -450, 0, 0, 0, 0]; + case 'oswald-angry': daOffsetArray = [60, -110, 0, 0, 0, 0]; + case 'dr-springheel': daOffsetArray = [-120, -440, 0, 0, 0, 0]; + + case 'updike' | 'bf-annie': + daOffsetArray = [-50, 0, 0, 0, 0, 0]; + if (curCharacter == 'bf-annie') daOffsetArray[1] = -20; + case 'void': + daOffsetArray = [-150, -380, 0, 0, 0, 0]; + case 'cg5' | 'exgf': + daOffsetArray = [-20, -340, 0, 0, 0, 0]; + case 'hallow': + daOffsetArray = [-200, -300, 0, 0, 0, 0]; + case 'bomberman': + daOffsetArray = [20, -170, 0, 0, 0, 0]; + case 'drunk-annie': + daOffsetArray = [-230, -310, 0, 0, 0, 0]; + case 'twinsone' | 'twinstwo': + daOffsetArray = [-120, -400, 0, 0, 0, 0]; + case 'makocorrupt': + daOffsetArray = [-270, -450, 0, 0, 0, 0]; + case 'zipper': + daOffsetArray = [-250, -340, 0, 0, 0, 0]; + case 'kazuki': + daOffsetArray = [60, -310, 0, 0, 0, 0]; + case 'sakuroma': + daOffsetArray = [-140, -620, 0, 0, 0, 0]; + case 'baldi-angry': + daOffsetArray = [-300, -420, 0, 500, 150, 100]; + case 'hex-virus' | 'hex-wire' | 'hex-virus-shaded': + daOffsetArray = [-50, -220, 0, 0, 0, 0]; + case 'alya': + daOffsetArray = [30, -10, 0, 0, 0, 0]; + case 'monika-real' | 'monika-real-sad-blue': + daOffsetArray = [-155, -355, 0, 0, 0, 0]; + case 'cc': + daOffsetArray = [-80, -180, 0, 0, 0, 0]; + case 'herobrine': + daOffsetArray = [-750, 200, 0, 0, 0, 0]; + case 'hank': + daOffsetArray = [-10, -170, 0, 0, 0, 0]; + case 'gold-side' | 'gold-side-blue': + daOffsetArray = [30, -250, 0, 0, 0, 0]; + case 'auditor': + daOffsetArray = [-130, -420, 0, 0, 0, 0]; + case 'sayori': + daOffsetArray = [-50, -280, -400, 0, 0, 0]; + case 'retro' | 'sanford': + daOffsetArray = [-60, -450, -400, 0, 0, 0]; + if (curCharacter == 'sanford') daOffsetArray[1] = -50; + case 'natsuki': + daOffsetArray = [0, -180, -400, 0, 0, 0]; + case 'impostor' | 'impostor2': + daOffsetArray = [-170, 40, 0, 0, 0, 0]; + case 'yuri' | 'yuri-crazy' | 'yuri-crazy-bw': + daOffsetArray = [-30, -238, -400, 0, 0, 0]; + case 'crazygf' | 'crazygf-bw': + daOffsetArray = [50, -80, 0, 0, 0, 0]; + case 'bf-nene' | 'bf-nene-scream': + daOffsetArray = [0, -70, 0, 0, 0, 0]; + case 'pico' | 'annie-bw' | 'phil' | 'nene' | 'ridzak': + daOffsetArray = [0, -50, 0, 0, 0, 0]; + if (curCharacter == 'ridzak') daOffsetArray[0] = 60; + case 'kou': + daOffsetArray = [10, -80, 0, 0, 0, 0]; + case 'nene2': + daOffsetArray = [-40, -40, 0, 0, 0, 0]; + case 'bf-demoncesar' | 'bf-demoncesar-trollge' | 'bf-demoncesar-bw' | 'bf-trollge-cas': + daOffsetArray = [0, -50, 0, 0, 0, 0]; + case 'demongf' | 'demongf-city': + daOffsetArray = [100, -100, 0, 0, 0, 0]; + case 'bf-cesar': + daOffsetArray = [105, -50, 0, 0, 0, 0]; + case 'sunday': + daOffsetArray = [55, -100, 0, 0, 0, 0]; + case 'monster' | 'monster-christmas': + daOffsetArray = [20, -260, 0, 0, -100, -100]; + if (curCharacter == 'monster-christmas') daOffsetArray[1] = -300; + case 'haachama': + daOffsetArray = [20, -250, 0, 0, 0, 0]; + case 'opheebop': + daOffsetArray = [-20, -230, 0, 0, 0, 0]; + case 'maijin-new' | 'majin-new-b3' | 'majin-new': + daOffsetArray = [-150, -200, 0, 0, 0, 0]; + case 'senpai' | 'monika' | 'senpai-angry' | 'kristoph-angry' | 'senpai-giddy' | 'baldi-angry-pixel' | 'mangle-angry' | 'monika-angry' | 'green-monika' | 'neon' + | 'matt-angry' | 'jackson' | 'mario-angry' | 'colt-angryd2corrupted' | 'miku-pixel' | 'colt-angry-d2' | 'tricky-pixel' | 'blantad-pixel': + if (PlayState.curStage.contains('school')) + daOffsetArray = [0, -200, 0, 0, 0, 0]; + else + daOffsetArray = [120, -70, 0, 0, 0, 0]; + case 'glitch-angry': daOffsetArray = [120, -80, 0, 0, 0, 0]; + case 'colt-angry': + daOffsetArray = [120, -90, 0, 0, 0, 0]; + case 'bf-whitty-pixel': + daOffsetArray = [0, -170, 0, 0, 0, 0]; + case 'gura-amelia' | 'spooky' | 'amesame-shutup': + daOffsetArray = [10, -145, 0, 0, 0, 0]; + case 'bana' | 'bana-wire': + daOffsetArray = [-100, -270, 0, 0, 0, 0]; + case 'cassandra': + daOffsetArray = [0, -330, 0, 0, 0, 0]; + case 'tom2' | 'matt2' | 'edd2' | 'garcellotired' | 'garcellodead': + daOffsetArray = [-270, -350, 0, 0, 0, 0]; + case 'bf-exgf': + daOffsetArray = [-140, -410, 0, 0, 0, 0]; + case 'bf-blantad' | 'bb' | 'anchor' | 'agoti': + daOffsetArray = [0, -400, 0, 0, 0, 0]; + if (curCharacter == 'anchor') daOffsetArray[0] = -90; + case 'dad' | 'hex' | 'bf-senpai-worried' | 'parents-christmas' | 'henry-blue' | 'whitty' | 'miku' + | 'lila' | 'lila-pelo' | 'myra' | 'blantad-new' | 'blantad-watch' | 'blantad-blue' | 'blantad-scream' | 'bf-hd-senpai-angry' | 'bf-hd-senpai-dark' + | 'tabi-wire' | 'tabi-glitcher' | 'tabi' | 'ruv' | 'cj-ruby': + daOffsetArray = [0, -350, 0, 0, 0, 0]; + if (curCharacter == 'ruv') daOffsetArray[1] = -420; + case 'sarvente' | 'sarvente-dark' | 'sarvente-worried-blue': + daOffsetArray = [-20, -375, 0, 0, 0, 0]; + case 'mom-car' | 'mom' | 'bf-mom-car' | 'bf-mom' | 'coco' | 'coco-car': + daOffsetArray = [10, -380, 0, 0, 0, 0]; + if (curCharacter.contains('coco'))daOffsetArray[1] = -400; + case 'sarv-ruv' | 'sarv-ruv-both': + daOffsetArray = [-100, -350, 0, 0, 0, 0]; + case 'sky-mad' | 'sky-pissed': + daOffsetArray = [-50, -180, 0, 0, 0, 0]; + case 'botan': + daOffsetArray = [50, -95, 0, 0, 0, 0]; + case 'bob': + daOffsetArray = [-170, -70, 0, 0, 0, 0]; + case 'bosip': + daOffsetArray = [0, -400, 0, 0, 0, 0]; + case 'bf-botan-pixel': + daOffsetArray = [40, -90, 0, 0, 0, 0]; + case 'liz': + daOffsetArray = [-50, -45, 0, 0, 0, 0]; + case 'selever': + daOffsetArray = [40, -375, 0, 0, -100, -100]; + case 'bf-pump': + daOffsetArray = [0, 50, 0, 0, 0, 0]; + case 'tord' | 'tom': + daOffsetArray = [10, -250, 0, 0, 0, 0]; + case 'tankman' | 'bf-senpai-tankman': + daOffsetArray = [0, -150, 0, 0, 0, 0]; + case 'ruby' | 'ruby-worried-night' | 'ruby-worried': + daOffsetArray = [30, -370, 0, 0, 0, 0]; + case 'sh-carol' | 'sarvente-lucifer': + daOffsetArray = [0, -625, 0, 0, 0, 0]; + case 'skye-r': + daOffsetArray = [-100, -350, 0, 0, 0, 0]; + case 'taeyai': + daOffsetArray = [0, -350, 0, 0, 0, 0]; + case 'bf-bbpanzu': + daOffsetArray = [-30, -190, 0, 0, 0, 0]; + case 'bf-sky': + daOffsetArray = [60, -110, 0, 0, 0, 0]; + case 'bf-tc': + daOffsetArray = [30, -230, 0, 0, 0, 0]; + case 'ghostbros': + daOffsetArray = [30, -100, 0, 0, 0, 0]; + case 'bf-sticky-scream': + daOffsetArray = [-30, 5, 0, 0, 0, 0]; + case 'neonight': + daOffsetArray = [-110, -250, 0, 0, 0, 0]; + case 'bf-aloe' | 'bf-aloe-confused' | 'bf-aloe-corrupt' | 'bf-aloe-bw' | 'bf-aloe-past' | 'bf-aloe-deathless': + daOffsetArray = [30, -20, 0, 0, 0, 0]; + case 'macy': + daOffsetArray = [20, -295, 0, 0, 0, 0]; + case 'ace': + daOffsetArray = [-40, -315, 0, 0, 0, 0]; + case 'ron': + daOffsetArray = [20, -90, 0, 0, 0, 0]; + case 'ash': + daOffsetArray = [-30, -305, 0, 0, 0, 0]; + case 'jack': + daOffsetArray = [75, -120, 0, 0, 0, 0]; + case 'tabi-crazy': + daOffsetArray = [-80, -290, 0, 0, 0, 0]; + case 'nonsense' | 'nonsense-pissed' | 'nonsense-mad': + daOffsetArray = [40, -220, 0, 0, 0, 0]; + case 'dust-sans': + daOffsetArray = [-230, -360, 0, 0, 0, 0]; + case 'tails': + daOffsetArray = [-110, -200, 0, 0, 0, 0]; + case 'bf-aloe-b3': + daOffsetArray = [30, -20, 0, 0, 0, 0]; + case 'starecrown': + daOffsetArray = [-240, -420, 0, 0, 0, 0]; + case 'henry': + daOffsetArray = [-30, -470, 0, 0, 0, 0]; + case 'bf-pixeld4BSide' | 'bf-pixeld4' | 'bf-demoncesar-pixel' | 'bf-pixel' | 'bf-sonic-pixel' | 'bf-tankman-pixel' | 'bf-tankman-pixel-happy' | 'bf-senpai-pixel': + if (!PlayState.curStage.contains('school')) + { + daOffsetArray = [190, 150, 0, 0, 0, 0]; + if (curCharacter.contains('tankman')) + { + daOffsetArray[0] -= 20; + daOffsetArray[1] -= 20; + } + } + case 'bf-carol': + daOffsetArray = [-50, -10, 0, 0, 0, 0]; + case 'bf-gf' | 'bf-gf-demon': + daOffsetArray = [60, -30, 0, 0, 0, 0]; + case 'trollge': + daOffsetArray = [30, -315, 0, 0, 0, 0]; + case 'cyrix-crazy' | 'bf-dad': + daOffsetArray = [0, -350, 0, 0, 0, 0]; + case 'yukichi-mad-city' | 'yukichi-mad': + daOffsetArray = [-150, -350, 0, 0, 0, 0]; + case 'cj': + daOffsetArray = [0, -350, 0, 0, 0, 0]; + default: + daOffsetArray = [0, 0, 0, 0, 0, 0]; + hasOffsets = false; + } + } + } +} \ No newline at end of file diff --git a/source/ChartingState.hx b/source/ChartingState.hx new file mode 100644 index 000000000..186532062 --- /dev/null +++ b/source/ChartingState.hx @@ -0,0 +1,1897 @@ +package; + +import flixel.addons.ui.FlxUIText; +import haxe.zip.Writer; +import Conductor.BPMChangeEvent; +import Section.SwagSection; +import Song.SwagSong; +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.addons.display.FlxGridOverlay; +import flixel.addons.ui.FlxInputText; +import flixel.addons.ui.FlxUI9SliceSprite; +import flixel.addons.ui.FlxUI; +import flixel.addons.ui.FlxUICheckBox; +import flixel.addons.ui.FlxUIDropDownMenu; +import flixel.addons.ui.FlxUIInputText; +import flixel.addons.ui.FlxUINumericStepper; +import flixel.addons.ui.FlxUITabMenu; +import flixel.addons.ui.FlxUITooltip.FlxUITooltipStyle; +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.group.FlxGroup; +import flixel.math.FlxMath; +import flixel.math.FlxPoint; +import flixel.system.FlxSound; +import flixel.text.FlxText; +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; +import openfl.events.IOErrorEvent; +import openfl.media.Sound; +import openfl.net.FileReference; +import openfl.utils.ByteArray; +import lime.media.AudioBuffer; +import haxe.io.Bytes; +import flash.geom.Rectangle; + +#if desktop +import Sys; +import sys.FileSystem; +#end + +using StringTools; + +class ChartingState extends MusicBeatState +{ + public static var noteTypeList:Array = //Used for backwards compatibility with 0.1 - 0.3.2 charts, though, you should add your hardcoded custom note types here too. + [ + '', + 'Alt Animation', + 'Hey!', + 'Hurt Note', + 'Auditor Note',//'GF Sing', + 'Static Note', + 'blah', + 'blah', + 'Haato Note', + 'Scythe Note', + 'Phantom Note' + ]; + private var noteTypeIntMap:Map = new Map(); + private var noteTypeMap:Map> = new Map>(); + var curRenderedNoteType:FlxTypedGroup = new FlxTypedGroup(); + + var _file:FileReference; + + var UI_box:FlxUITabMenu; + + /** + * Array of notes showing when each section STARTS in STEPS + * Usually rounded up?? + */ + var curSection:Int = 0; + + public static var lastSection:Int = 0; + + var bpmTxt:FlxText; + + var strumLine:FlxSprite; + var curSong:String = 'Dad Battle'; + var amountSteps:Int = 0; + var bullshitUI:FlxGroup; + var writingNotesText:FlxText; + var highlight:FlxSprite; + + var GRID_SIZE:Int = 40; + + var dummyArrow:FlxSprite; + + var curRenderedNotes:FlxTypedGroup; + var curRenderedSustains:FlxTypedGroup; + + var hiddenSongs:Array =['norway', 'haachama', 'high-school-conflict', 'hunger', 'sorrow']; + + var gridBG:FlxSprite; + + var _song:SwagSong; + + var typingShit:FlxInputText; + /* + * WILL BE THE CURRENT / LAST PLACED NOTE + **/ + var curSelectedNote:Array = null; + + var tempBpm:Float = 0; + var gridBlackLine:FlxSprite; + var vocals:FlxSound; + + var leftIcon:HealthIcon; + var rightIcon:HealthIcon; + var currentType:Int = 0; + + var waveformSprite:FlxSprite; + + private var lastNote:Note; + + override function create() + { + curSection = lastSection; + + if (PlayState.SONG != null) + _song = PlayState.SONG; + else + { + _song = { + song: 'Test', + notes: [], + bpm: 150, + needsVoices: true, + player1: 'bf', + player2: 'dad', + gfVersion: 'gf', + noteStyle: 'normal', + dadNoteStyle: 'normal', + bfNoteStyle: 'normal', + stage: 'stage', + mania: 0, + speed: 1, + validScore: false + }; + } + + if (PlayState.triggeredFlip) + { + FlxG.save.data.downScroll = !FlxG.save.data.downScroll; + PlayState.triggeredFlip = false; + } + + var bg:FlxSprite = new FlxSprite().loadGraphic(Paths.image('menuDesat')); + bg.scrollFactor.set(); + bg.color = 0xFF222222; + add(bg); + + gridBG = FlxGridOverlay.create(GRID_SIZE, GRID_SIZE, GRID_SIZE * 8, GRID_SIZE * 16); + add(gridBG); + + gridBlackLine = new FlxSprite(gridBG.x + gridBG.width / 2).makeGraphic(2, Std.int(gridBG.height), FlxColor.BLACK); + add(gridBlackLine); + + waveformSprite = new FlxSprite(GRID_SIZE, 0).makeGraphic(FlxG.width, FlxG.height, 0x00FFFFFF); + add(waveformSprite); + + curRenderedNotes = new FlxTypedGroup(); + curRenderedSustains = new FlxTypedGroup(); + + FlxG.mouse.visible = true; + FlxG.save.bind('funkin', 'ninjamuffin99'); + + tempBpm = _song.bpm; + + addSection(); + + loadAudioBuffer(); + // sections = _song.notes; + + updateGrid(); + + loadSong(_song.song); + Conductor.changeBPM(_song.bpm); + Conductor.mapBPMChanges(_song); + + leftIcon = new HealthIcon(_song.player1); + rightIcon = new HealthIcon(_song.player2); + + if (leftIcon.animation.name == 'face') + leftIcon.useOldSystem('bf'); + if (rightIcon.animation.name == 'face') + rightIcon.useOldSystem('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); + + bpmTxt = new FlxText(1000, 50, 0, "", 16); + bpmTxt.scrollFactor.set(); + add(bpmTxt); + + strumLine = new FlxSprite(0, 50).makeGraphic(Std.int(FlxG.width / 2), 4); + add(strumLine); + + dummyArrow = new FlxSprite().makeGraphic(GRID_SIZE, GRID_SIZE); + add(dummyArrow); + + var tabs = [ + {name: "Song", label: 'Song'}, + {name: "Section", label: 'Section'}, + {name: "Note", label: 'Note'}, + {name: "Charting", label: 'Charting'} + ]; + + UI_box = new FlxUITabMenu(null, tabs, true); + + UI_box.resize(300, 400); + UI_box.x = FlxG.width / 2; + UI_box.y = 20; + add(UI_box); + + addChartingUI(); + addSongUI(); + addSectionUI(); + addNoteUI(); + updateWaveform(); + + add(curRenderedNotes); + add(curRenderedSustains); + add(curRenderedNoteType); + + super.create(); + } + + //so i don't have to rechart any special notes. i'll just use this + + function reloadSpecificNotes() + { + /*for (ii in 0..._song.notes.length) + { + for (i in 0..._song.notes[ii].sectionNotes.length) + { + var note = _song.notes[ii].sectionNotes[i]; + + if (PlayState.curStage == 'auditorHell' && note[1] > 7) + { + note[3] = 4; + note[1] = note[1] - 8; + _song.notes[ii].sectionNotes[i] = note; + } + + updateGrid(); + } + } + + for (i in 0..._song.notes[curSection].sectionNotes.length) + { + var note = _song.notes[curSection].sectionNotes[i]; + + note[3] = "D Type Note"; + _song.notes[curSection].sectionNotes[i] = note; + + updateGrid(); + }*/ + + for (ii in 0..._song.notes.length) + { + for (note in _song.notes[ii].sectionNotes) + { + if(!Std.isOfType(note[3], String)) //idk if this works + { + note[3] = noteTypeIntMap.get(note[3]); + note.noteType = note[3]; + } + + updateGrid(); + } + } + } + + #if desktop + var waveformEnabled:FlxUICheckBox; + var waveformUseInstrumental:FlxUICheckBox; + #end + + function addChartingUI():Void + { + var tab_group_chart = new FlxUI(null, UI_box); + tab_group_chart.name = "Charting"; + + #if desktop + waveformEnabled = new FlxUICheckBox(10, 90, null, null, "Visible Waveform", 100); + if (FlxG.save.data.chart_waveform == null) FlxG.save.data.chart_waveform = false; + waveformEnabled.checked = FlxG.save.data.chart_waveform; + waveformEnabled.callback = function() + { + FlxG.save.data.chart_waveform = waveformEnabled.checked; + updateWaveform(); + }; + + waveformUseInstrumental = new FlxUICheckBox(waveformEnabled.x + 120, waveformEnabled.y, null, null, "Waveform for Instrumental", 100); + waveformUseInstrumental.checked = false; + waveformUseInstrumental.callback = function() + { + updateWaveform(); + }; + #end + + var check_mute_inst = new FlxUICheckBox(10, 310, 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 check_mute_vocals = new FlxUICheckBox(check_mute_inst.x + 120, check_mute_inst.y, null, null, "Mute Vocals (in editor)", 100); + check_mute_vocals.checked = false; + check_mute_vocals.callback = function() + { + if(vocals != null) { + var vol:Float = 1; + + if (check_mute_vocals.checked) + vol = 0; + + vocals.volume = vol; + } + }; + + var instVolume:FlxUINumericStepper = new FlxUINumericStepper(15, 270, 0.1, 1, 0.1, 10, 1); + instVolume.value = FlxG.sound.music.volume; + instVolume.name = 'song_instvol'; + + var voicesVolume:FlxUINumericStepper = new FlxUINumericStepper(instVolume.x + 100, instVolume.y, 0.1, 1, 0.1, 10, 1); + voicesVolume.value = vocals.volume; + voicesVolume.name = 'song_vocalvol'; + + tab_group_chart.add(new FlxText(instVolume.x, instVolume.y - 15, 0, 'Inst Volume')); + tab_group_chart.add(new FlxText(voicesVolume.x, voicesVolume.y - 15, 0, 'Voices Volume')); + + tab_group_chart.add(check_mute_inst); + tab_group_chart.add(instVolume); + tab_group_chart.add(voicesVolume); + tab_group_chart.add(check_mute_inst); + tab_group_chart.add(check_mute_vocals); + #if desktop + tab_group_chart.add(waveformEnabled); + tab_group_chart.add(waveformUseInstrumental); + #end + + UI_box.addGroup(tab_group_chart); + } + + function addSongUI():Void + { + var UI_songTitle = new FlxUIInputText(10, 10, 70, _song.song, 8); + typingShit = UI_songTitle; + + var check_voices = new FlxUICheckBox(10, 25, null, null, "Has voice track", 100); + check_voices.checked = _song.needsVoices; + // _song.needsVoices = check_voices.checked; + check_voices.callback = function() + { + _song.needsVoices = check_voices.checked; + trace('CHECKED!'); + }; + + var saveButton:FlxButton = new FlxButton(110, 8, "Save", function() + { + saveLevel(); + }); + + var reloadSong:FlxButton = new FlxButton(saveButton.x + 90, saveButton.y, "Reload Audio", function() + { + loadSong(_song.song); + loadAudioBuffer(); + updateWaveform(); + }); + + var reloadSongJson:FlxButton = new FlxButton(reloadSong.x, saveButton.y + 30, "Reload JSON", function() + { + loadJson(_song.song.toLowerCase()); + }); + + var loadAutosaveBtn:FlxButton = new FlxButton(reloadSongJson.x, reloadSongJson.y + 30, 'load autosave', loadAutosave); + + + var clear_notes:FlxButton = new FlxButton(320, 340, 'Clear notes', function() + { + for (sec in 0..._song.notes.length) { + _song.notes[sec].sectionNotes = []; + } + updateGrid(); + }); + clear_notes.color = FlxColor.RED; + clear_notes.label.color = FlxColor.WHITE; + + var stepperBPM:FlxUINumericStepper = new FlxUINumericStepper(10, 70, 0.1, 1, 1.0, 5000.0, 1); + stepperBPM.value = Conductor.bpm; + stepperBPM.name = 'song_bpm'; + + var stepperSpeed:FlxUINumericStepper = new FlxUINumericStepper(10, stepperBPM.y + 35, 0.1, 1, 0.1, 10, 1); + stepperSpeed.value = _song.speed; + stepperSpeed.name = 'song_speed'; + + var stepperMania:FlxUINumericStepper = new FlxUINumericStepper(stepperSpeed.x + 105, stepperSpeed.y, 1, 0, 0, 3, 0); + stepperMania.value = _song.mania; + stepperMania.name = 'song_mania'; + + var characters:Array = CoolUtil.coolTextFile(Paths.txt('characterList')); + var gfVersions:Array = CoolUtil.coolTextFile(Paths.txt('gfVersionList')); + var stages:Array = CoolUtil.coolTextFile(Paths.txt('stageList')); + var noteStyles:Array = CoolUtil.coolTextFile(Paths.txt('noteStyleList')); + + var player1DropDown = new FlxUIDropDownMenuCustom(10, stepperSpeed.y + 45, FlxUIDropDownMenuCustom.makeStrIdLabelArray(characters, true), function(character:String) + { + _song.player1 = characters[Std.parseInt(character)]; + }); + player1DropDown.selectedLabel = _song.player1; + + var gfVersionDropDown = new FlxUIDropDownMenuCustom(player1DropDown.x, player1DropDown.y + 40, FlxUIDropDownMenuCustom.makeStrIdLabelArray(gfVersions, true), function(gfVersion:String) + { + _song.gfVersion = gfVersions[Std.parseInt(gfVersion)]; + }); + gfVersionDropDown.selectedLabel = _song.gfVersion; + + var player2DropDown = new FlxUIDropDownMenuCustom(player1DropDown.x, gfVersionDropDown.y + 40, FlxUIDropDownMenuCustom.makeStrIdLabelArray(characters, true), function(character:String) + { + _song.player2 = characters[Std.parseInt(character)]; + }); + player2DropDown.selectedLabel = _song.player2; + + var stageDropDown = new FlxUIDropDownMenuCustom(player1DropDown.x + 140, player1DropDown.y, FlxUIDropDownMenuCustom.makeStrIdLabelArray(stages, true), function(stage:String) + { + _song.stage = stages[Std.parseInt(stage)]; + }); + stageDropDown.selectedLabel = _song.stage; + + var noteStyleDropDown = new FlxUIDropDownMenuCustom(player1DropDown.x + 140, gfVersionDropDown.y, FlxUIDropDownMenuCustom.makeStrIdLabelArray(noteStyles, true), function(noteStyle:String) + { + _song.noteStyle = noteStyles[Std.parseInt(noteStyle)]; + }); + noteStyleDropDown.selectedLabel = _song.noteStyle; + + var tab_group_song = new FlxUI(null, UI_box); + tab_group_song.name = "Song"; + tab_group_song.add(UI_songTitle); + + tab_group_song.add(new FlxText(stepperBPM.x, stepperBPM.y - 15, 0, 'Song BPM:')); + tab_group_song.add(new FlxText(stepperSpeed.x, stepperSpeed.y - 15, 0, 'Song Speed:')); + tab_group_song.add(new FlxText(stepperMania.x, stepperMania.y - 15, 0, 'Song Mania:')); + tab_group_song.add(new FlxText(player2DropDown.x, player2DropDown.y - 15, 0, 'Opponent:')); + tab_group_song.add(new FlxText(gfVersionDropDown.x, gfVersionDropDown.y - 15, 0, 'Girlfriend:')); + tab_group_song.add(new FlxText(player1DropDown.x, player1DropDown.y - 15, 0, 'Player:')); + tab_group_song.add(new FlxText(stageDropDown.x, stageDropDown.y - 15, 0, 'Stage:')); + tab_group_song.add(new FlxText(noteStyleDropDown.x, noteStyleDropDown.y - 15, 0, 'Note Style:')); + + tab_group_song.add(check_voices); + tab_group_song.add(clear_notes); + 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(stepperMania); + tab_group_song.add(noteStyleDropDown); + tab_group_song.add(stageDropDown); + tab_group_song.add(player2DropDown); + tab_group_song.add(gfVersionDropDown); + tab_group_song.add(player1DropDown); + + + UI_box.addGroup(tab_group_song); + UI_box.scrollFactor.set(); + + FlxG.camera.follow(strumLine); + } + + var stepperLength:FlxUINumericStepper; + var check_mustHitSection:FlxUICheckBox; + var check_changeBPM:FlxUICheckBox; + var stepperSectionBPM:FlxUINumericStepper; + var check_altAnim:FlxUICheckBox; + var check_bfAltAnim:FlxUICheckBox; + var check_dadCrossfade:FlxUICheckBox; + var check_bfCrossfade:FlxUICheckBox; + var check_isPixel:FlxUICheckBox; + var stepperType:FlxUINumericStepper; + var stepperDType:FlxUINumericStepper; + + var typeNameTxt:FlxText; + var typeNames:Array = ['Normal', 'Alt Anim', 'Markov', 'Danger', 'Tricky', 'EXE', 'Bomb', 'Rushia', 'Haato', 'Scythe', 'Phantom', 'D Type']; + + var sectionToCopy:Int = 0; + var notesCopied:Array; + + function addSectionUI():Void + { + var tab_group_section = new FlxUI(null, UI_box); + tab_group_section.name = 'Section'; + + stepperLength = new FlxUINumericStepper(10, 10, 4, 0, 0, 999, 0); + stepperLength.value = _song.notes[curSection].lengthInSteps; + stepperLength.name = "section_length"; + + check_mustHitSection = new FlxUICheckBox(10, 30, null, null, "Camera Points to P1?", 100); + check_mustHitSection.name = 'check_mustHit'; + check_mustHitSection.checked = true; + // _song.needsVoices = check_mustHit.checked; + + check_altAnim = new FlxUICheckBox(10, 60, null, null, "Alt Animation", 100); + check_altAnim.name = 'check_altAnim'; + + check_bfAltAnim = new FlxUICheckBox(check_altAnim.x + 120, check_altAnim.y, null, null, "Player Alt Animation", 100); + check_bfAltAnim.name = 'check_bfAltAnim'; + + check_dadCrossfade = new FlxUICheckBox(check_bfAltAnim.x, 150, null, null, "Opponent Crossfade", 100); + check_dadCrossfade.name = 'check_dadCrossfade'; + + check_bfCrossfade = new FlxUICheckBox(check_bfAltAnim.x, 180, null, null, "Player Crossfade", 100); + check_bfCrossfade.name = 'check_bfCrossfade'; + + check_changeBPM = new FlxUICheckBox(10, 90, null, null, 'Change BPM', 100); + check_changeBPM.name = 'check_changeBPM'; + + stepperSectionBPM = new FlxUINumericStepper(10, 120, 1, Conductor.bpm, 0, 999, 0); + stepperSectionBPM.value = Conductor.bpm; + stepperSectionBPM.name = 'section_bpm'; + + stepperDType = new FlxUINumericStepper(130, 120, 1, 0, 0, 9, 0); + stepperDType.value = 0; + stepperDType.name = 'section_dtype'; + + typeNameTxt = new FlxText(50, 370, 0, 'Normal Notes', 18); + typeNameTxt.scrollFactor.set(); + typeNameTxt.color = 0xFFFFFFFF; + add(typeNameTxt); + + var copyButton:FlxButton = new FlxButton(10, 150, "Copy Section", function() + { + notesCopied = []; + sectionToCopy = curSection; + for (i in 0..._song.notes[curSection].sectionNotes.length) + { + var note:Array = _song.notes[curSection].sectionNotes[i]; + notesCopied.push(note); + } + + var startThing:Float = sectionStartTime(); + var endThing:Float = sectionStartTime(1); + }); + + var pasteButton:FlxButton = new FlxButton(10, 180, "Paste Section", function() + { + if(notesCopied == null || notesCopied.length < 1) + { + return; + } + + var addToTime:Float = Conductor.stepCrochet * (_song.notes[curSection].lengthInSteps * (curSection - sectionToCopy)); + //trace('Time to add: ' + addToTime); + + for (note in notesCopied) + { + var copiedNote:Array = []; + var newStrumTime:Float = note[0] + addToTime; + if(note[1] < 0) + { + /*var copiedEventArray:Array = []; + for (i in 0...note[2].length) + { + var eventToPush:Array = note[2][i]; + copiedEventArray.push([eventToPush[0], eventToPush[1], eventToPush[2]]); + } + _song.events.push([newStrumTime, copiedEventArray]);*/ + } + else + { + if(note[4] != null) { + copiedNote = [newStrumTime, note[1], note[2], note[3], note[4]]; + } else { + copiedNote = [newStrumTime, note[1], note[2], note[3]]; + } + _song.notes[curSection].sectionNotes.push(copiedNote); + } + } + updateGrid(); + }); + + var clearSectionButton:FlxButton = new FlxButton(10, 210, "Clear Section", clearSection); + + var swapSection:FlxButton = new FlxButton(10, 240, "Swap Section", function() + { + for (i in 0..._song.notes[curSection].sectionNotes.length) + { + var note = _song.notes[curSection].sectionNotes[i]; + + var half = Main.keyAmmo[_song.mania]; + note[1] = (note[1] + half) % (half * 2); + _song.notes[curSection].sectionNotes[i] = note; + updateGrid(); + } + }); + + var stepperCopyLast:FlxUINumericStepper = new FlxUINumericStepper(110, 276, 1, 1, -999, 999, 0); + + var copyLastButton:FlxButton = new FlxButton(10, 270, "Copy last section", function() + { + copySection(Std.int(stepperCopyLast.value)); + }); + + check_isPixel = new FlxUICheckBox(10, 460, null, null, "Pixel Notes", 100); + check_isPixel.name = 'check_isPixel'; + + copyLastButton.setGraphicSize(80, 30); + copyLastButton.updateHitbox(); + + tab_group_section.add(stepperLength); + tab_group_section.add(new FlxText(75,10,'Section Length (in steps)')); + tab_group_section.add(new FlxText(180,120,'Section dType')); + tab_group_section.add(stepperSectionBPM); + tab_group_section.add(stepperDType); + tab_group_section.add(stepperCopyLast); + tab_group_section.add(new FlxText(174,276,'sections back')); + tab_group_section.add(check_mustHitSection); + tab_group_section.add(check_altAnim); + tab_group_section.add(check_bfAltAnim); + // tab_group_section.add(check_isPixel); + tab_group_section.add(check_dadCrossfade); + tab_group_section.add(check_bfCrossfade); + tab_group_section.add(check_changeBPM); + tab_group_section.add(copyButton); + tab_group_section.add(copyLastButton); + tab_group_section.add(pasteButton); + tab_group_section.add(clearSectionButton); + tab_group_section.add(swapSection); + add(stepperType); + + UI_box.addGroup(tab_group_section); + } + + var stepperSusLength:FlxUINumericStepper; + var stepperNoteType:FlxUINumericStepper; + var strumTimeInputText:FlxUIInputText; + + var tab_group_note:FlxUI; + var noteTypeDropDown:FlxUIDropDownMenuCustom; + + function addNoteUI():Void + { + tab_group_note = new FlxUI(null, UI_box); + tab_group_note.name = 'Note'; + + writingNotesText = new FlxUIText(20,100, 0, ""); + writingNotesText.setFormat("Arial",20,FlxColor.WHITE,FlxTextAlign.LEFT,FlxTextBorderStyle.OUTLINE,FlxColor.BLACK); + + stepperSusLength = new FlxUINumericStepper(10, 25, Conductor.stepCrochet / 2, 0, 0, Conductor.stepCrochet * _song.notes[curSection].lengthInSteps * 4); + stepperSusLength.value = 0; + stepperSusLength.name = 'note_susLength'; + + strumTimeInputText = new FlxUIInputText(10, 65, 180, "0"); + + var key:Int = 0; + var displayNameList:Array = []; + while (key < noteTypeList.length) { + displayNameList.push(noteTypeList[key]); + noteTypeMap.set(noteTypeList[key], key); + noteTypeIntMap.set(key, noteTypeList[key]); + key++; + } + + #if desktop + var directories:Array = [Paths.mods('custom_notetypes/'), Paths.mods(Paths.currentModDirectory + '/custom_notetypes/')]; + for (i in 0...directories.length) { + var directory:String = directories[i]; + if(FileSystem.exists(directory)) { + for (file in FileSystem.readDirectory(directory)) { + var path = haxe.io.Path.join([directory, file]); + if (!FileSystem.isDirectory(path) && file.endsWith('.lua')) { + var fileToCheck:String = file.substr(0, file.length - 4); + if(!noteTypeMap.exists(fileToCheck)) { + displayNameList.push(fileToCheck); + noteTypeMap.set(fileToCheck, key); + noteTypeIntMap.set(key, fileToCheck); + key++; + } + } + } + } + } + #end + + for (i in 1...displayNameList.length) { + displayNameList[i] = i + '. ' + displayNameList[i]; + } + + noteTypeDropDown = new FlxUIDropDownMenuCustom(10, 105, FlxUIDropDownMenuCustom.makeStrIdLabelArray(displayNameList, true), function(character:String) + { + currentType = Std.parseInt(character); + if(curSelectedNote != null && curSelectedNote[1] > -1) { + curSelectedNote[3] = noteTypeIntMap.get(currentType); + updateGrid(); + } + }); + + tab_group_note.add(writingNotesText); + tab_group_note.add(new FlxText(10, 10, 0, 'Sustain length:')); + tab_group_note.add(new FlxText(10, 50, 0, 'Strum time (in miliseconds):')); + tab_group_note.add(new FlxText(10, 90, 0, 'Note type:')); + tab_group_note.add(stepperSusLength); + tab_group_note.add(strumTimeInputText); + tab_group_note.add(noteTypeDropDown); + UI_box.addGroup(tab_group_note); + } + + function loadSong(daSong:String):Void + { + if (FlxG.sound.music != null) + { + FlxG.sound.music.stop(); + // vocals.stop(); + } + + if (FileSystem.exists(Paths.inst2(daSong))) + FlxG.sound.playMusic(Sound.fromFile(Paths.inst2(daSong)), 0.6); + else + FlxG.sound.playMusic(Paths.inst(daSong), 0.6); + + // WONT WORK FOR TUTORIAL OR TEST SONG!!! REDO LATER + if (FileSystem.exists(Paths.voices2(daSong))) + vocals = new FlxSound().loadEmbedded(Sound.fromFile(Paths.voices2(daSong))); + else + vocals = new FlxSound().loadEmbedded(Paths.voices(daSong)); + + FlxG.sound.list.add(vocals); + + FlxG.sound.music.pause(); + vocals.pause(); + + FlxG.sound.music.onComplete = function() + { + vocals.pause(); + vocals.time = 0; + FlxG.sound.music.pause(); + FlxG.sound.music.time = 0; + changeSection(); + }; + } + + function generateUI():Void + { + while (bullshitUI.members.length > 0) + { + bullshitUI.remove(bullshitUI.members[0], true); + } + + // general shit + var title:FlxText = new FlxText(UI_box.x + 20, UI_box.y + 20, 0); + bullshitUI.add(title); + /* + var loopCheck = new FlxUICheckBox(UI_box.x + 10, UI_box.y + 50, null, null, "Loops", 100, ['loop check']); + loopCheck.checked = curNoteSelected.doesLoop; + tooltips.add(loopCheck, {title: 'Section looping', body: "Whether or not it's a simon says style section", style: tooltipType}); + bullshitUI.add(loopCheck); + + */ + } + + override function getEvent(id:String, sender:Dynamic, data:Dynamic, ?params:Array) + { + if (id == FlxUICheckBox.CLICK_EVENT) + { + var check:FlxUICheckBox = cast sender; + var label = check.getLabel().text; + switch (label) + { + case 'Camera Points to P1?': + _song.notes[curSection].mustHitSection = check.checked; + case 'Change BPM': + _song.notes[curSection].changeBPM = check.checked; + FlxG.log.add('changed bpm shit'); + case "Alt Animation": + _song.notes[curSection].altAnim = check.checked; + case "Player Alt Animation": + _song.notes[curSection].bfAltAnim = check.checked; + case "Pixel Notes": + _song.notes[curSection].isPixel = check.checked; + case "Opponent Crossfade": + _song.notes[curSection].dadCrossfade = check.checked; + case "Player Crossfade": + _song.notes[curSection].bfCrossfade = check.checked; + } + } + else if (id == FlxUINumericStepper.CHANGE_EVENT && (sender is FlxUINumericStepper)) + { + var nums:FlxUINumericStepper = cast sender; + var wname = nums.name; + FlxG.log.add(wname); + if (wname == 'section_length') + { + if (nums.value <= 4) + nums.value = 4; + _song.notes[curSection].lengthInSteps = Std.int(nums.value); + updateGrid(); + } + else if (wname == 'song_speed') + { + if (nums.value <= 0) + nums.value = 0; + _song.speed = nums.value; + } + else if (wname == 'song_bpm') + { + if (nums.value <= 0) + nums.value = 1; + tempBpm = Std.int(nums.value); + Conductor.mapBPMChanges(_song); + Conductor.changeBPM(Std.int(nums.value)); + } + else if (wname == 'song_mania') + { + if (nums.value <= 0) + nums.value = 0; + _song.mania = Std.int(nums.value); + } + else if (wname == 'note_susLength') + { + if (curSelectedNote == null) + return; + + if (nums.value <= 0) + nums.value = 0; + curSelectedNote[2] = nums.value; + updateGrid(); + } + else if (wname == 'section_bpm') + { + if (nums.value <= 0.1) + nums.value = 0.1; + _song.notes[curSection].bpm = Std.int(nums.value); + updateGrid(); + }else if (wname == 'song_vocalvol') + { + if (nums.value <= 0.1) + nums.value = 0.1; + vocals.volume = nums.value; + } + else if (wname == 'section_dtype') + { + _song.notes[curSection].dType = Std.int(nums.value); + updateGrid(); + }else if (wname == 'song_instvol') + { + if (nums.value <= 0.1) + nums.value = 0.1; + FlxG.sound.music.volume = nums.value; + } + } + else if(id == FlxUIInputText.CHANGE_EVENT && (sender is FlxUIInputText)) { + if(curSelectedNote != null) + { + if(sender == strumTimeInputText) { + var value:Float = Std.parseFloat(strumTimeInputText.text); + if(Math.isNaN(value)) value = 0; + curSelectedNote[0] = value; + updateGrid(); + } + } + } + + // FlxG.log.add(id + " WEED " + sender + " WEED " + data + " WEED " + params); + } + + var updatedSection:Bool = false; + + /* this function got owned LOL + function lengthBpmBullshit():Float + { + if (_song.notes[curSection].changeBPM) + return _song.notes[curSection].lengthInSteps * (_song.notes[curSection].bpm / _song.bpm); + else + return _song.notes[curSection].lengthInSteps; + }*/ + function stepStartTime(step):Float + { + return _song.bpm / (step / 4) / 60; + } + + function sectionStartTime(?add:Int = 0):Float + { + var daBPM:Float = _song.bpm; + var daPos:Float = 0; + for (i in 0...curSection + add) + { + if (_song.notes[i].changeBPM) + { + daBPM = _song.notes[i].bpm; + } + daPos += 4 * (1000 * 60 / daBPM); + } + return daPos; + } + + var writingNotes:Bool = false; + + override function update(elapsed:Float) + { + updateHeads(); + + if (FlxG.keys.justPressed.FIVE) + reloadSpecificNotes(); + + if (FlxG.keys.justPressed.ESCAPE) + { + autosaveSong(); + LoadingState.loadAndSwitchState(new EditorPlayState(sectionStartTime())); + } + + curStep = recalculateSteps(); + + if (_song.mania != 0) + { + UI_box.x = FlxG.width / 2 + 160; + UI_box.y = 100; + } + else + { + UI_box.x = FlxG.width / 2; + UI_box.y = 20; + } + + //i like... never use this. also it's annoying when doing alt+tab to check something else + /*if (FlxG.keys.justPressed.ALT && !FlxG.keys.justPressed.ENTER && UI_box.selected_tab == 0) + { + writingNotes = !writingNotes; + }*/ + + if (writingNotes) + writingNotesText.text = "WRITING NOTES"; + else + writingNotesText.text = ""; + + Conductor.songPosition = FlxG.sound.music.time; + _song.song = typingShit.text; + + var upP = controls.UP_P; + var rightP = controls.RIGHT_P; + var downP = controls.DOWN_P; + var leftP = controls.LEFT_P; + + var controlArray:Array = [leftP, downP, upP, rightP]; + + if ((upP || rightP || downP || leftP) && writingNotes) + { + for(i in 0...controlArray.length) + { + if (controlArray[i]) + { + for (n in 0..._song.notes[curSection].sectionNotes.length) + { + var note = _song.notes[curSection].sectionNotes[n]; + if (note == null) + continue; + if (note[0] == Conductor.songPosition && note[1] % (Main.keyAmmo[_song.mania]) == i) + { + trace('GAMING'); + _song.notes[curSection].sectionNotes.remove(note); + } + } + trace('adding note'); + _song.notes[curSection].sectionNotes.push([Conductor.songPosition, i, 0]); + updateGrid(); + } + } + + } + + strumLine.y = getYfromStrum((Conductor.songPosition - sectionStartTime()) % (Conductor.stepCrochet * _song.notes[curSection].lengthInSteps)); + strumLine.x = 0; + + if (curBeat % 4 == 0 && curStep >= 16 * (curSection + 1)) + { + trace(curStep); + trace((_song.notes[curSection].lengthInSteps) * (curSection + 1)); + trace('DUMBSHIT'); + + if (_song.notes[curSection + 1] == null) + { + addSection(); + } + + changeSection(curSection + 1, false); + } + + FlxG.watch.addQuick('daBeat', curBeat); + FlxG.watch.addQuick('daStep', curStep); + + if (FlxG.mouse.justPressed) + { + if (FlxG.mouse.overlaps(curRenderedNotes)) + { + curRenderedNotes.forEachAlive(function(note:Note) + { + if (FlxG.mouse.overlaps(note)) + { + if (FlxG.keys.pressed.CONTROL) + { + selectNote(note); + } + else + { + //trace('tryin to delete note...'); + deleteNote(note); + } + } + }); + } + else + { + if (FlxG.mouse.x > gridBG.x + && FlxG.mouse.x < gridBG.x + gridBG.width + && FlxG.mouse.y > gridBG.y + && FlxG.mouse.y < gridBG.y + (GRID_SIZE * _song.notes[curSection].lengthInSteps)) + { + FlxG.log.add('added note'); + addNote(); + } + } + } + + if (FlxG.mouse.x > gridBG.x + && FlxG.mouse.x < gridBG.x + gridBG.width + && FlxG.mouse.y > gridBG.y + && FlxG.mouse.y < gridBG.y + (GRID_SIZE * _song.notes[curSection].lengthInSteps)) + { + var arX = Math.floor(FlxG.mouse.x / GRID_SIZE) * GRID_SIZE; + dummyArrow.x = arX; + + if (FlxG.keys.pressed.SHIFT) + dummyArrow.y = FlxG.mouse.y; + else + dummyArrow.y = Math.floor(FlxG.mouse.y / GRID_SIZE) * GRID_SIZE; + } + + if (FlxG.keys.justPressed.ENTER) + { + lastSection = curSection; + + PlayState.SONG = _song; + FlxG.sound.music.stop(); + vocals.stop(); + LoadingState.loadAndSwitchState(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.pressed.CONTROL) + { + if (FlxG.keys.justPressed.Z && lastNote != null) + { + trace(curRenderedNotes.members.contains(lastNote) ? "delete note" : "add note"); + if (curRenderedNotes.members.contains(lastNote)) + deleteNote(lastNote); + else + addNote(lastNote); + } + }*/ + + var shiftThing:Int = 1; + if (FlxG.keys.pressed.SHIFT) + shiftThing = 4; + if (FlxG.keys.pressed.ALT) + shiftThing = 32; + + if (!writingNotes) + { + if (FlxG.keys.justPressed.RIGHT || FlxG.keys.justPressed.D) + changeSection(curSection + shiftThing); + if (FlxG.keys.justPressed.LEFT || FlxG.keys.justPressed.A) + changeSection(curSection - shiftThing); + } + if (FlxG.keys.justPressed.SPACE) + { + if (FlxG.sound.music.playing) + { + FlxG.sound.music.pause(); + vocals.pause(); + } + else + { + vocals.play(); + FlxG.sound.music.play(); + } + } + + if (FlxG.keys.justPressed.R) + { + if (FlxG.keys.pressed.SHIFT) + resetSection(true); + else + resetSection(); + } + + if (FlxG.mouse.wheel != 0) + { + FlxG.sound.music.pause(); + vocals.pause(); + + 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; + + /* if (FlxG.keys.justPressed.UP) + Conductor.changeBPM(Conductor.bpm + 1); + if (FlxG.keys.justPressed.DOWN) + Conductor.changeBPM(Conductor.bpm - 1); */ + + bpmTxt.text = bpmTxt.text = Std.string(FlxMath.roundDecimal(Conductor.songPosition / 1000, 2)) + + " / " + + Std.string(FlxMath.roundDecimal(FlxG.sound.music.length / 1000, 2)) + + "\nSection: " + + curSection + + "\nCurStep: " + + curStep + + "\nCurBeat: " + + curBeat; + 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(); + } + + override function beatHit() + { + trace('beat'); + + super.beatHit(); + } + + function recalculateSteps():Int + { + var lastChange:BPMChangeEvent = { + stepTime: 0, + songTime: 0, + bpm: 0 + } + for (i in 0...Conductor.bpmChangeMap.length) + { + if (FlxG.sound.music.time > Conductor.bpmChangeMap[i].songTime) + lastChange = Conductor.bpmChangeMap[i]; + } + + curStep = lastChange.stepTime + Math.floor((FlxG.sound.music.time - lastChange.songTime) / Conductor.stepCrochet); + updateBeat(); + + return curStep; + } + + function resetSection(songBeginning:Bool = false):Void + { + updateGrid(); + + FlxG.sound.music.pause(); + vocals.pause(); + + // Basically old shit from changeSection??? + FlxG.sound.music.time = sectionStartTime(); + + if (songBeginning) + { + FlxG.sound.music.time = 0; + curSection = 0; + } + + vocals.time = FlxG.sound.music.time; + updateCurStep(); + + updateGrid(); + updateSectionUI(); + updateWaveform(); + } + + function changeSection(sec:Int = 0, ?updateMusic:Bool = true):Void + { + trace('changing section' + sec); + + if (_song.notes[sec] != null) + { + curSection = sec; + + updateGrid(); + + if (updateMusic) + { + FlxG.sound.music.pause(); + vocals.pause(); + + /*var daNum:Int = 0; + var daLength:Float = 0; + while (daNum <= sec) + { + daLength += lengthBpmBullshit(); + daNum++; + }*/ + + FlxG.sound.music.time = sectionStartTime(); + vocals.time = FlxG.sound.music.time; + updateCurStep(); + } + + updateGrid(); + updateSectionUI(); + updateWaveform(); + } + else + trace('bro wtf I AM NULL'); + } + + function copySection(?sectionNum:Int = 1) + { + var daSec = FlxMath.maxInt(curSection, sectionNum); + + for (note in _song.notes[daSec - sectionNum].sectionNotes) + { + var strum = note[0] + Conductor.stepCrochet * (_song.notes[daSec].lengthInSteps * sectionNum); + + var copiedNote:Array = [strum, note[1], note[2], note[3]]; + _song.notes[daSec].sectionNotes.push(copiedNote); + } + + updateGrid(); + } + + function updateSectionUI():Void + { + var sec = _song.notes[curSection]; + + stepperLength.value = sec.lengthInSteps; + check_mustHitSection.checked = sec.mustHitSection; + check_altAnim.checked = sec.altAnim; + check_bfAltAnim.checked = sec.bfAltAnim; + check_dadCrossfade.checked = sec.dadCrossfade; + check_bfCrossfade.checked = sec.bfCrossfade; + check_isPixel.checked = sec.isPixel; + stepperDType.value = sec.dType; + check_changeBPM.checked = sec.changeBPM; + stepperSectionBPM.value = sec.bpm; + } + + function updateHeads():Void + { + if (check_mustHitSection.checked) + { + leftIcon.useOldSystem(_song.player1); + rightIcon.useOldSystem(_song.player2); + + if (leftIcon.animation.name == 'face') + leftIcon.useOldSystem('bf'); + if (rightIcon.animation.name == 'face') + rightIcon.useOldSystem('dad'); + } + else + { + leftIcon.useOldSystem(_song.player2); + rightIcon.useOldSystem(_song.player1); + + if (leftIcon.animation.name == 'face') + leftIcon.useOldSystem('dad'); + if (rightIcon.animation.name == 'face') + rightIcon.useOldSystem('bf'); + } + } + + function updateNoteUI():Void + { + if (curSelectedNote != null) + { + if(curSelectedNote[2] != null) + stepperSusLength.value = curSelectedNote[2]; + + if(curSelectedNote[3] != null) { + currentType = noteTypeMap.get(curSelectedNote[3]); + if(currentType <= 0) { + noteTypeDropDown.selectedLabel = ''; + } else { + noteTypeDropDown.selectedLabel = currentType + '. ' + curSelectedNote[3]; + } + } + + strumTimeInputText.text = '' + curSelectedNote[0]; + } + } + + function setupNoteData(i:Array, isNextSection:Bool):Note + { + var daNoteInfo = i[1]; + var daStrumTime = i[0]; + var daSus:Dynamic = i[2]; + + var note:Note = new Note(daStrumTime, daNoteInfo % Main.keyAmmo[_song.mania], null, null, "", _song.noteStyle); + if(daSus != null) { //Common note + if(!Std.isOfType(i[3], String)) //Convert old note type to new note type format + { + i[3] = noteTypeIntMap.get(i[3]); + } + if(i.length > 3 && (i[3] == null || i[3].length < 1)) + { + //i.remove(i[3]); + } + note.sustainLength = daSus; + note.noteType = i[3]; + } else { //Event note. I'll add this later + /*note.loadGraphic(Paths.image('eventArrow')); + note.eventName = getEventName(i[1]); + note.eventLength = i[1].length; + if(i[1].length < 2) + { + note.eventVal1 = i[1][0][1]; + note.eventVal2 = i[1][0][2]; + } + note.noteData = -1; + daNoteInfo = -1;*/ + } + + note.setGraphicSize(GRID_SIZE, GRID_SIZE); + note.updateHitbox(); + note.x = Math.floor(daNoteInfo * GRID_SIZE); + + note.y = (GRID_SIZE * (isNextSection ? 16 : 0)) * _song.notes[curSection].lengthInSteps + Math.floor(getYfromStrum((daStrumTime - sectionStartTime(isNextSection ? 1 : 0)) % (Conductor.stepCrochet * _song.notes[curSection].lengthInSteps), false)); + return note; + } + + var waveformPrinted:Bool = true; + var audioBuffers:Array = [null, null]; + + function loadAudioBuffer() { + if(audioBuffers[0] != null) { + audioBuffers[0].dispose(); + } + audioBuffers[0] = null; + #if desktop + if(FileSystem.exists(FileSystem.absolutePath('songs/' + _song.song.toLowerCase() + '/Inst.ogg'))) { + audioBuffers[0] = AudioBuffer.fromFile(FileSystem.absolutePath('songs/' + _song.song.toLowerCase() + '/Inst.ogg')); + //trace('Custom vocals found'); + } + else { #end + var leVocals:String = Paths.getPath(_song.song.toLowerCase() + '/Inst.' + Paths.SOUND_EXT, SOUND, 'songs'); + if (Assets.exists(leVocals)) { //Vanilla inst + audioBuffers[0] = AudioBuffer.fromFile('./' + leVocals.substr(6)); + //trace('Inst found'); + } + #if desktop + } + #end + + if(audioBuffers[1] != null) { + audioBuffers[1].dispose(); + } + audioBuffers[1] = null; + #if desktop + if(FileSystem.exists(FileSystem.absolutePath('songs/' + _song.song.toLowerCase() + '/Voices.ogg'))) { + audioBuffers[0] = AudioBuffer.fromFile(FileSystem.absolutePath('songs/' + _song.song.toLowerCase() + '/Voices.ogg')); + //trace('Custom vocals found'); + } else { #end + var leVocals:String = Paths.getPath(_song.song.toLowerCase() + '/Voices.' + Paths.SOUND_EXT, SOUND, 'songs'); + if (Assets.exists(leVocals)) { //Vanilla voices + audioBuffers[1] = AudioBuffer.fromFile('./' + leVocals.substr(6)); + //trace('Voices found, LETS FUCKING GOOOO'); + } + #if desktop + } + #end + } + + function updateWaveform() { + #if desktop + if(waveformPrinted) { + waveformSprite.makeGraphic(Std.int(GRID_SIZE * 8), Std.int(gridBG.height), 0x00FFFFFF); + waveformSprite.pixels.fillRect(new Rectangle(0, 0, gridBG.width, gridBG.height), 0x00FFFFFF); + } + waveformPrinted = false; + + var checkForVoices:Int = 1; + if(waveformUseInstrumental.checked) checkForVoices = 0; + + if(!waveformEnabled.checked || audioBuffers[checkForVoices] == null) { + //trace('Epic fail on the waveform lol'); + return; + } + + var sampleMult:Float = audioBuffers[checkForVoices].sampleRate / 44100; + var index:Int = Std.int(sectionStartTime() * 44.0875 * sampleMult); + var drawIndex:Int = 0; + + var steps:Int = _song.notes[curSection].lengthInSteps; + if(Math.isNaN(steps) || steps < 1) steps = 16; + var samplesPerRow:Int = Std.int(((Conductor.stepCrochet * steps * 1.1 * sampleMult) / 16) / _song.notes[curSection].lengthInSteps); + if(samplesPerRow < 1) samplesPerRow = 1; + var waveBytes:Bytes = audioBuffers[checkForVoices].data.toBytes(); + + var min:Float = 0; + var max:Float = 0; + while (index < (waveBytes.length - 1)) + { + var byte:Int = waveBytes.getUInt16(index * 4); + + if (byte > 65535 / 2) + byte -= 65535; + + var sample:Float = (byte / 65535); + + if (sample > 0) + { + if (sample > max) + max = sample; + } + else if (sample < 0) + { + if (sample < min) + min = sample; + } + + if ((index % samplesPerRow) == 0) + { + // trace("min: " + min + ", max: " + max); + + /*if (drawIndex > gridBG.height) + { + drawIndex = 0; + }*/ + + var pixelsMin:Float = Math.abs(min * (GRID_SIZE * 8)); + var pixelsMax:Float = max * (GRID_SIZE * 8); + waveformSprite.pixels.fillRect(new Rectangle(Std.int((GRID_SIZE * 4) - pixelsMin), drawIndex, pixelsMin + pixelsMax, 1), FlxColor.BLUE); + drawIndex++; + + min = 0; + max = 0; + + if(drawIndex > gridBG.height) break; + } + + index++; + } + waveformPrinted = true; + #end + } + + function updateGrid():Void + { + curRenderedNoteType.clear(); + + var keys:Int = 4; + switch (_song.mania) + { + case 0: + keys = 4; + case 1: + keys = 6; + case 2: + keys = 9; + case 3: + keys = 5; + case 4: + keys = 7; + } + + #if desktop + if(waveformEnabled != null) { + updateWaveform(); + } + #end + + remove(gridBG); + gridBG = FlxGridOverlay.create(GRID_SIZE, GRID_SIZE, GRID_SIZE * (keys * 2), GRID_SIZE * _song.notes[curSection].lengthInSteps); + add(gridBG); + + remove(gridBlackLine); + gridBlackLine = new FlxSprite(gridBG.x + gridBG.width / 2).makeGraphic(2, Std.int(gridBG.height), FlxColor.BLACK); + add(gridBlackLine); + + while (curRenderedNotes.members.length > 0) + { + curRenderedNotes.remove(curRenderedNotes.members[0], true); + } + + while (curRenderedSustains.members.length > 0) + { + curRenderedSustains.remove(curRenderedSustains.members[0], true); + } + + var sectionInfo:Array = _song.notes[curSection].sectionNotes; + + if (_song.notes[curSection].changeBPM && _song.notes[curSection].bpm > 0) + { + Conductor.changeBPM(_song.notes[curSection].bpm); + FlxG.log.add('CHANGED BPM!'); + } + else + { + // get last bpm + var daBPM:Float = _song.bpm; + for (i in 0...curSection) + if (_song.notes[i].changeBPM) + daBPM = _song.notes[i].bpm; + Conductor.changeBPM(daBPM); + } + + /* // PORT BULLSHIT, INCASE THERE'S NO SUSTAIN DATA FOR A NOTE + for (sec in 0..._song.notes.length) + { + for (notesse in 0..._song.notes[sec].sectionNotes.length) + { + if (_song.notes[sec].sectionNotes[notesse][2] == null) + { + trace('SUS NULL'); + _song.notes[sec].sectionNotes[notesse][2] = 0; + } + } + } + */ + + for (i in sectionInfo) + { + var daNoteInfo = i[1]; + var daStrumTime = i[0]; + var daSus = i[2]; + var daType = i[3]; + + var note:Note = setupNoteData(i, false); + curRenderedNotes.add(note); + + if(i[3] != null && note.noteType != null && note.noteType.length > 0) { + var typeInt:Null = noteTypeMap.get(i[3]); + var theType:String = '' + typeInt; + if(typeInt == null) theType = '?'; + + var daText:AttachedFlxText = new AttachedFlxText(0, 0, 100, theType, 24); + daText.setFormat(Paths.font("vcr.ttf"), 24, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + daText.xAdd = -32; + daText.yAdd = 6; + daText.borderSize = 1; + curRenderedNoteType.add(daText); + daText.sprTracker = note; + } + + if (daSus > 0) + { + var sustainVis:FlxSprite = new FlxSprite(note.x + (GRID_SIZE / 2), + note.y + GRID_SIZE).makeGraphic(8, Math.floor(FlxMath.remapToRange(daSus, 0, Conductor.stepCrochet * _song.notes[curSection].lengthInSteps, 0, gridBG.height))); + curRenderedSustains.add(sustainVis); + } + } + } + + private function addSection(lengthInSteps:Int = 16):Void + { + var sec:SwagSection = { + lengthInSteps: lengthInSteps, + bpm: _song.bpm, + changeBPM: false, + mustHitSection: true, + sectionNotes: [], + typeOfSection: 0, + altAnim: false, + bfAltAnim: false, + isPixel: false, + dadCrossfade: false, + bfCrossfade: false, + dType: 0 + }; + + _song.notes.push(sec); + } + + function selectNote(note:Note):Void + { + for (i in _song.notes[curSection].sectionNotes) + { + if(i != curSelectedNote && i[0] == note.strumTime) + { + curSelectedNote = i; + trace('we found da note!'); + break; + } + } + + updateGrid(); + updateNoteUI(); + } + + + function deleteNote(note:Note):Void + { + lastNote = note; + for (i in _song.notes[curSection].sectionNotes) + { + if (i[0] == note.strumTime && i[1] % (Main.keyAmmo[_song.mania]) == note.noteData) + { + if(i == curSelectedNote) curSelectedNote = null; + _song.notes[curSection].sectionNotes.remove(i); + break; + } + } + + updateGrid(); + } + + function clearSection():Void + { + _song.notes[curSection].sectionNotes = []; + + updateGrid(); + } + + function clearSong():Void + { + for (daSection in 0..._song.notes.length) + { + _song.notes[daSection].sectionNotes = []; + } + + updateGrid(); + } + + private function addNote(?n:Note):Void + { + var noteStrum = getStrumTime(dummyArrow.y) + sectionStartTime(); + //Very rough way of adding burning notes, if Kade wants to make this better, go ahead. + var noteData = Math.floor(FlxG.mouse.x / GRID_SIZE) + (FlxG.keys.pressed.ALT ? 8 : 0); + + var noteSus = 0; + var noteType = currentType; + + _song.notes[curSection].sectionNotes.push([noteStrum, noteData, noteSus, noteTypeIntMap.get(noteType)]); + + curSelectedNote = _song.notes[curSection].sectionNotes[_song.notes[curSection].sectionNotes.length - 1]; + trace(curSelectedNote[3]); + + if (FlxG.keys.pressed.CONTROL) + { + //_song.notes[curSection].sectionNotes.push([noteStrum, (noteData + 4) % 8, noteSus]); + } + + updateGrid(); + updateNoteUI(); + + autosaveSong(); + } + + function getStrumTime(yPos:Float):Float + { + return FlxMath.remapToRange(yPos, gridBG.y, gridBG.y + gridBG.height, 0, 16 * Conductor.stepCrochet); + } + + function getYfromStrum(strumTime:Float, ?doZoomCalc:Bool = false):Float + { + return FlxMath.remapToRange(strumTime, 0, 16 * Conductor.stepCrochet, gridBG.y, gridBG.y + gridBG.height); + } + + /* + function calculateSectionLengths(?sec:SwagSection):Int + { + var daLength:Int = 0; + + for (i in _song.notes) + { + var swagLength = i.lengthInSteps; + + if (i.typeOfSection == Section.COPYCAT) + swagLength * 2; + + daLength += swagLength; + + if (sec != null && sec == i) + { + trace('swag loop??'); + break; + } + } + + return daLength; + }*/ + private var daSpacing:Float = 0.3; + + function loadLevel():Void + { + trace(_song.notes); + } + + function getNotes():Array + { + var noteData:Array = []; + + for (i in _song.notes) + { + noteData.push(i.sectionNotes); + } + + return noteData; + } + + function loadJson(song:String):Void + { + if (CoolUtil.difficultyArray[PlayState.storyDifficulty] != "Normal"){ + PlayState.SONG = Song.loadFromJson(song.toLowerCase()+"-"+CoolUtil.difficultyArray[PlayState.storyDifficulty], song.toLowerCase()); + + }else{ + PlayState.SONG = Song.loadFromJson(song.toLowerCase(), song.toLowerCase()); + } + + if (Main.hiddenSongs.contains(song.toLowerCase()) && !Main.isHidden || song.toLowerCase() == 'restore' && !Main.restoreUnlocked || song.toLowerCase() == 'deathmatch-holo' && !Main.deathHolo) + LoadingState.loadAndSwitchState(new GoFindTheSecretState()); + else + LoadingState.loadAndSwitchState(new ChartingState()); + } + + function loadAutosave():Void + { + PlayState.SONG = Song.parseJSONshit(FlxG.save.data.autosave); + LoadingState.loadAndSwitchState(new ChartingState()); + } + + function autosaveSong():Void + { + FlxG.save.data.autosave = Json.stringify({ + "song": _song + }); + FlxG.save.flush(); + } + + private function saveLevel() + { + var json = { + "song": _song + }; + + var data:String = Json.stringify(json); + + if ((data != null) && (data.length > 0)) + { + _file = new FileReference(); + _file.addEventListener(Event.COMPLETE, onSaveComplete); + _file.addEventListener(Event.CANCEL, onSaveCancel); + _file.addEventListener(IOErrorEvent.IO_ERROR, onSaveError); + _file.save(data.trim(), _song.song.toLowerCase() + ".json"); + } + } + + function onSaveComplete(_):Void + { + _file.removeEventListener(Event.COMPLETE, onSaveComplete); + _file.removeEventListener(Event.CANCEL, onSaveCancel); + _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); + _file = null; + FlxG.log.notice("Successfully saved LEVEL DATA."); + } + + /** + * Called when the save file dialog is cancelled. + */ + function onSaveCancel(_):Void + { + _file.removeEventListener(Event.COMPLETE, onSaveComplete); + _file.removeEventListener(Event.CANCEL, onSaveCancel); + _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); + _file = null; + } + + /** + * Called if there is an error while saving the gameplay recording. + */ + function onSaveError(_):Void + { + _file.removeEventListener(Event.COMPLETE, onSaveComplete); + _file.removeEventListener(Event.CANCEL, onSaveCancel); + _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); + _file = null; + FlxG.log.error("Problem saving Level data"); + } +} + +class AttachedFlxText extends FlxText +{ + public var sprTracker:FlxSprite; + public var xAdd:Float = 0; + public var yAdd:Float = 0; + + public function new(X:Float = 0, Y:Float = 0, FieldWidth:Float = 0, ?Text:String, Size:Int = 8, EmbeddedFont:Bool = true) { + super(X, Y, FieldWidth, Text, Size, EmbeddedFont); + } + + override function update(elapsed:Float) + { + super.update(elapsed); + + if (sprTracker != null) { + setPosition(sprTracker.x + xAdd, sprTracker.y + yAdd); + angle = sprTracker.angle; + alpha = sprTracker.alpha; + } + } +} \ No newline at end of file diff --git a/source/ChromaticAberration.hx b/source/ChromaticAberration.hx new file mode 100644 index 000000000..843f5f00e --- /dev/null +++ b/source/ChromaticAberration.hx @@ -0,0 +1,31 @@ +package; + +import flixel.system.FlxAssets.FlxShader; + +class ChromaticAberration extends FlxShader +{ + @:glFragmentSource(' + #pragma header + + uniform float rOffset; + uniform float gOffset; + uniform float bOffset; + + void main() + { + vec4 col1 = texture2D(bitmap, openfl_TextureCoordv.st - vec2(rOffset, 0.0)); + vec4 col2 = texture2D(bitmap, openfl_TextureCoordv.st - vec2(gOffset, 0.0)); + vec4 col3 = texture2D(bitmap, openfl_TextureCoordv.st - vec2(bOffset, 0.0)); + vec4 toUse = texture2D(bitmap, openfl_TextureCoordv); + toUse.r = col1.r; + toUse.g = col2.g; + toUse.b = col3.b; + //float someshit = col4.r + col4.g + col4.b; + + gl_FragColor = toUse; + }') + public function new() + { + super(); + } +} diff --git a/source/ClientPrefs.hx b/source/ClientPrefs.hx index 9cc7bad7a..b8443203e 100644 --- a/source/ClientPrefs.hx +++ b/source/ClientPrefs.hx @@ -20,20 +20,26 @@ class ClientPrefs { public static var camZooms:Bool = true; public static var hideHud:Bool = false; public static var noteOffset:Int = 0; - public static var arrowHSV:Array> = [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]; + public static var arrowHSV:Array> = [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]; public static var imagesPersist:Bool = false; public static var ghostTapping:Bool = true; public static var timeBarType:String = 'Time Left'; public static var scoreZoom:Bool = true; public static var noReset:Bool = false; public static var healthBarAlpha:Float = 1; - #if mobile - public static var controllerMode:Bool = true; - #else public static var controllerMode:Bool = false; - #end public static var gameplaySettings:Map = [ 'scrollspeed' => 1.0, + 'scrolltype' => 'multiplicative', + // anyone reading this, amod is multiplicative speed mod, cmod is constant speed mod, and xmod is bpm based speed mod. + // an amod example would be chartSpeed * multiplier + // cmod would just be constantSpeed = chartSpeed + // and xmod basically works by basing the speed on the bpm. + // iirc (beatsPerSecond * (conductorToNoteDifference / 1000)) * noteSize (110 or something like that depending on it, prolly just use note.height) + // bps is calculated by bpm / 60 + // oh yeah and you'd have to actually convert the difference to seconds which I already do, because this is based on beats and stuff. but it should work + // just fine. but I wont implement it because I don't know how you handle sustains and other stuff like that. + // oh yeah when you calculate the bps divide it by the songSpeed or rate because it wont scroll correctly when speeds exist. 'songspeed' => 1.0, 'healthgain' => 1.0, 'healthloss' => 1.0, @@ -42,10 +48,10 @@ class ClientPrefs { 'botplay' => false, 'opponentplay' => false ]; + public static var inputSystem:String = 'Native'; public static var comboOffset:Array = [0, 0, 0, 0]; - public static var keSustains:Bool = false; //i was bored, okay? - + public static var noAntimash:Bool = false; public static var ratingOffset:Int = 0; public static var sickWindow:Int = 45; public static var goodWindow:Int = 90; @@ -55,10 +61,82 @@ class ClientPrefs { //Every key has two binds, add your key bind down here and then add your control on options/ControlsSubState.hx and Controls.hx public static var keyBinds:Map> = [ //Key Bind, Name for ControlsSubState + 'note_one1' => [SPACE, NONE], + + 'note_two1' => [D, NONE], + 'note_two2' => [K, NONE], + + 'note_three1' => [D, NONE], + 'note_three2' => [SPACE, NONE], + 'note_three3' => [K, NONE], + 'note_left' => [A, LEFT], 'note_down' => [S, DOWN], 'note_up' => [W, UP], 'note_right' => [D, RIGHT], + + 'note_five1' => [D, NONE], + 'note_five2' => [F, NONE], + 'note_five3' => [SPACE, NONE], + 'note_five4' => [J, NONE], + 'note_five5' => [K, NONE], + + 'note_six1' => [S, NONE], + 'note_six2' => [D, NONE], + 'note_six3' => [F, NONE], + 'note_six4' => [J, NONE], + 'note_six5' => [K, NONE], + 'note_six6' => [L, NONE], + + 'note_seven1' => [S, NONE], + 'note_seven2' => [D, NONE], + 'note_seven3' => [F, NONE], + 'note_seven4' => [SPACE, NONE], + 'note_seven5' => [J, NONE], + 'note_seven6' => [K, NONE], + 'note_seven7' => [L, NONE], + + 'note_eight1' => [A, NONE], + 'note_eight2' => [S, NONE], + 'note_eight3' => [D, NONE], + 'note_eight4' => [F, NONE], + 'note_eight5' => [H, NONE], + 'note_eight6' => [J, NONE], + 'note_eight7' => [K, NONE], + 'note_eight8' => [L, NONE], + + 'note_nine1' => [A, NONE], + 'note_nine2' => [S, NONE], + 'note_nine3' => [D, NONE], + 'note_nine4' => [F, NONE], + 'note_nine5' => [SPACE, NONE], + 'note_nine6' => [H, NONE], + 'note_nine7' => [J, NONE], + 'note_nine8' => [K, NONE], + 'note_nine9' => [L, NONE], + + 'note_ten1' => [A, NONE], + 'note_ten2' => [S, NONE], + 'note_ten3' => [D, NONE], + 'note_ten4' => [F, NONE], + 'note_ten5' => [G, NONE], + 'note_ten6' => [SPACE, NONE], + 'note_ten7' => [H, NONE], + 'note_ten8' => [J, NONE], + 'note_ten9' => [K, NONE], + 'note_ten10' => [L, NONE], + + 'note_elev1' => [A, NONE], + 'note_elev2' => [S, NONE], + 'note_elev3' => [D, NONE], + 'note_elev4' => [F, NONE], + 'note_elev5' => [G, NONE], + 'note_elev6' => [SPACE, NONE], + 'note_elev7' => [H, NONE], + 'note_elev8' => [J, NONE], + 'note_elev9' => [K, NONE], + 'note_elev10' => [L, NONE], + 'note_elev11' => [PERIOD, NONE], 'ui_left' => [A, LEFT], 'ui_down' => [S, DOWN], @@ -98,7 +176,7 @@ class ClientPrefs { FlxG.save.data.camZooms = camZooms; FlxG.save.data.noteOffset = noteOffset; FlxG.save.data.hideHud = hideHud; - FlxG.save.data.arrowHSV = arrowHSV; + FlxG.save.data.hsv11 = arrowHSV; FlxG.save.data.imagesPersist = imagesPersist; FlxG.save.data.ghostTapping = ghostTapping; FlxG.save.data.timeBarType = timeBarType; @@ -108,13 +186,14 @@ class ClientPrefs { FlxG.save.data.comboOffset = comboOffset; FlxG.save.data.achievementsMap = Achievements.achievementsMap; FlxG.save.data.henchmenDeath = Achievements.henchmenDeath; - + FlxG.save.data.noAntimash = noAntimash; FlxG.save.data.ratingOffset = ratingOffset; FlxG.save.data.sickWindow = sickWindow; FlxG.save.data.goodWindow = goodWindow; FlxG.save.data.badWindow = badWindow; FlxG.save.data.safeFrames = safeFrames; FlxG.save.data.gameplaySettings = gameplaySettings; + FlxG.save.data.inputSystem = inputSystem; FlxG.save.data.controllerMode = controllerMode; FlxG.save.flush(); @@ -176,13 +255,12 @@ class ClientPrefs { if(FlxG.save.data.noteOffset != null) { noteOffset = FlxG.save.data.noteOffset; } - if(FlxG.save.data.arrowHSV != null) { - arrowHSV = FlxG.save.data.arrowHSV; - } - if(FlxG.save.data.imagesPersist != null) { - imagesPersist = FlxG.save.data.imagesPersist; - FlxGraphic.defaultPersist = ClientPrefs.imagesPersist; + if(FlxG.save.data.hsv11 != null) { + arrowHSV = FlxG.save.data.hsv11; } + if (FlxG.save.data.inputSystem != null) { + inputSystem = FlxG.save.data.inputSystem; + } if(FlxG.save.data.ghostTapping != null) { ghostTapping = FlxG.save.data.ghostTapping; } @@ -239,6 +317,11 @@ class ClientPrefs { FlxG.sound.muted = FlxG.save.data.mute; } + if (FlxG.save.data.noAntimash != null) + { + noAntimash = FlxG.save.data.noAntimash; + } + var save:FlxSave = new FlxSave(); save.bind('controls_v2', 'ninjamuffin99'); if(save != null && save.data.customControls != null) { @@ -264,7 +347,6 @@ class ClientPrefs { FlxG.sound.volumeDownKeys = TitleState.volumeDownKeys; FlxG.sound.volumeUpKeys = TitleState.volumeUpKeys; } - public static function copyKey(arrayToCopy:Array):Array { var copiedArray:Array = arrayToCopy.copy(); var i:Int = 0; diff --git a/source/Cloud.hx b/source/Cloud.hx new file mode 100644 index 000000000..3e98ef785 --- /dev/null +++ b/source/Cloud.hx @@ -0,0 +1,30 @@ +package; + +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.system.FlxAssets.FlxGraphicAsset; + +class Cloud extends FlxSprite +{ + public function new() + { + super(Paths.image("holofunk/limoholo/cloud")); + super.setGraphicSize(Std.int(super.width * 0.8)); + kill(); + } + + override public function revive() + { + x = -width * 1.3; + y = FlxG.random.int(-8600, -9200); + velocity.x = 1400; + super.revive(); + } + + override public function update(elapsed:Float) + { + if (x > FlxG.width * 20) + kill(); + super.update(elapsed); + } +} \ No newline at end of file diff --git a/source/Cloud2.hx b/source/Cloud2.hx new file mode 100644 index 000000000..217bb3915 --- /dev/null +++ b/source/Cloud2.hx @@ -0,0 +1,30 @@ +package; + +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.system.FlxAssets.FlxGraphicAsset; + +class Cloud2 extends FlxSprite +{ + public function new() + { + super(Paths.image("holofunk/limoholo/cloud")); + super.setGraphicSize(Std.int(super.width * 0.65)); + kill(); + } + + override public function revive() + { + x = -width * 1.3; + y = FlxG.random.int(-8850, -9250); + velocity.x = 700; + super.revive(); + } + + override public function update(elapsed:Float) + { + if (x > FlxG.width * 20) + kill(); + super.update(elapsed); + } +} \ No newline at end of file diff --git a/source/ColorTweenCustom.hx b/source/ColorTweenCustom.hx new file mode 100644 index 000000000..532065807 --- /dev/null +++ b/source/ColorTweenCustom.hx @@ -0,0 +1,68 @@ +package; + +import flixel.FlxSprite; +import flixel.tweens.FlxTween; +import flixel.util.FlxColor; + +/** + * Tweens a color's red, green, and blue properties + * independently. Can also tween an alpha value. + */ +class ColorTweenCustom extends FlxTween +{ + public var color(default, null):FlxColor; + + var startColor:FlxColor; + var endColor:FlxColor; + public static var instance:ColorTweenCustom = null; + + /** + * Optional sprite object whose color to tween + */ + public var sprite(default, null):FlxSprite; + + /** + * Clean up references + */ + override public function destroy() + { + super.destroy(); + sprite = null; + } + + /** + * Tweens the color to a new color and an alpha to a new alpha. + * + * @param Duration Duration of the tween. + * @param FromColor Start color. + * @param ToColor End color. + * @param Sprite Optional sprite object whose color to tween. + * @return The ColorTween. + */ + public function tween(Duration:Float, FromColor:FlxColor, ToColor:FlxColor, ?Sprite:FlxSprite):ColorTweenCustom + { + color = startColor = FromColor; + endColor = ToColor; + duration = Duration; + sprite = Sprite; + start(); + return this; + } + + override function update(elapsed:Float):Void + { + super.update(elapsed); + color = FlxColor.interpolate(startColor, endColor, scale); + + if (sprite != null) + { + sprite.color = color; + sprite.alpha = color.alphaFloat; + } + } + + override function isTweenOf(object:Dynamic, ?field:String):Bool + { + return sprite == object && (field == null || field == "color"); + } +} diff --git a/source/Conductor.hx b/source/Conductor.hx index 471a10ce6..03847d133 100644 --- a/source/Conductor.hx +++ b/source/Conductor.hx @@ -1,6 +1,7 @@ package; import Song.SwagSong; +import flixel.FlxG; /** * ... @@ -23,8 +24,9 @@ class Conductor public static var lastSongPos:Float; public static var offset:Float = 0; - //public static var safeFrames:Int = 10; - public static var safeZoneOffset:Float = (ClientPrefs.safeFrames / 60) * 1000; // is calculated in create(), is safeFrames in milliseconds + public static var safeFrames:Int = 10; + public static var safeZoneOffset:Float = Math.floor((safeFrames / 60) * 1000); // is calculated in create(), is safeFrames in milliseconds + public static var timeScale:Float = Conductor.safeZoneOffset / 166; public static var bpmChangeMap:Array = []; @@ -32,22 +34,13 @@ class Conductor { } - public static function judgeNote(note:Note, diff:Float=0) //STOLEN FROM KADE ENGINE (bbpanzu) - I had to rewrite it later anyway after i added the custom hit windows lmao (Shadow Mario) + public static function recalculateTimings() { - //tryna do MS based judgment due to popular demand - var timingWindows:Array = [ClientPrefs.sickWindow, ClientPrefs.goodWindow, ClientPrefs.badWindow]; - var windowNames:Array = ['sick', 'good', 'bad']; - - // var diff = Math.abs(note.strumTime - Conductor.songPosition) / (PlayState.songMultiplier >= 1 ? PlayState.songMultiplier : 1); - for(i in 0...timingWindows.length) // based on 4 timing windows, will break with anything else - { - if (diff <= timingWindows[Math.round(Math.min(i, timingWindows.length - 1))]) - { - return windowNames[i]; - } - } - return 'shit'; + Conductor.safeFrames = FlxG.save.data.frames; + Conductor.safeZoneOffset = Math.floor((Conductor.safeFrames / 60) * 1000); + Conductor.timeScale = Conductor.safeZoneOffset / 166; } + public static function mapBPMChanges(song:SwagSong) { bpmChangeMap = []; @@ -82,4 +75,4 @@ class Conductor crochet = ((60 / bpm) * 1000); stepCrochet = crochet / 4; } -} +} \ No newline at end of file diff --git a/source/Controls.hx b/source/Controls.hx index 12e1a584e..2472fd133 100644 --- a/source/Controls.hx +++ b/source/Controls.hx @@ -10,75 +10,235 @@ import flixel.input.actions.FlxActionSet; import flixel.input.gamepad.FlxGamepadButton; import flixel.input.gamepad.FlxGamepadInputID; import flixel.input.keyboard.FlxKey; -import flixel.group.FlxGroup; -import ui.Hitbox; -import ui.FlxVirtualPad; -import flixel.ui.FlxButton; #if (haxe >= "4.0.0") enum abstract Action(String) to String from String { - var UI_UP = "ui_up"; - var UI_LEFT = "ui_left"; - var UI_RIGHT = "ui_right"; - var UI_DOWN = "ui_down"; - var UI_UP_P = "ui_up-press"; - var UI_LEFT_P = "ui_left-press"; - var UI_RIGHT_P = "ui_right-press"; - var UI_DOWN_P = "ui_down-press"; - var UI_UP_R = "ui_up-release"; - var UI_LEFT_R = "ui_left-release"; - var UI_RIGHT_R = "ui_right-release"; - var UI_DOWN_R = "ui_down-release"; - var NOTE_UP = "note_up"; - var NOTE_LEFT = "note_left"; - var NOTE_RIGHT = "note_right"; - var NOTE_DOWN = "note_down"; - var NOTE_UP_P = "note_up-press"; - var NOTE_LEFT_P = "note_left-press"; - var NOTE_RIGHT_P = "note_right-press"; - var NOTE_DOWN_P = "note_down-press"; - var NOTE_UP_R = "note_up-release"; - var NOTE_LEFT_R = "note_left-release"; - var NOTE_RIGHT_R = "note_right-release"; - var NOTE_DOWN_R = "note_down-release"; + var UP = "up"; + var LEFT = "left"; + var RIGHT = "right"; + var DOWN = "down"; + var UP_P = "up-press"; + var LEFT_P = "left-press"; + var RIGHT_P = "right-press"; + var DOWN_P = "down-press"; + var UP_R = "up-release"; + var LEFT_R = "left-release"; + var RIGHT_R = "right-release"; + var DOWN_R = "down-release"; var ACCEPT = "accept"; var BACK = "back"; var PAUSE = "pause"; var RESET = "reset"; + var CHEAT = "cheat"; + + var S1 = "s1"; + var S2 = "s2"; + var S3 = "s3"; + var S4 = "s4"; + var S5 = "s5"; + var S6 = "s6"; + + var S1_P = "s1-press"; + var S2_P = "s2-press"; + var S3_P = "s3-press"; + var S4_P = "s4-press"; + var S5_P = "s5-press"; + var S6_P = "s6-press"; + + var S1_R = "s1_release"; + var S2_R = "s2_release"; + var S3_R = "s3_release"; + var S4_R = "s4_release"; + var S5_R = "s5_release"; + var S6_R = "s6_release"; + + var T1 = "t1"; + var T2 = "t2"; + var T3 = "t3"; + var T4 = "t4"; + var T5 = "t5"; + + var T1_P = "t1-press"; + var T2_P = "t2-press"; + var T3_P = "t3-press"; + var T4_P = "t4-press"; + var T5_P = "t5-press"; + + var T1_R = "t1_release"; + var T2_R = "t2_release"; + var T3_R = "t3_release"; + var T4_R = "t4_release"; + var T5_R = "t5_release"; + + var N0 = "n0"; + var N1 = "n1"; + var N2 = "n2"; + var N3 = "n3"; + var N4 = "n4"; + var N5 = "n5"; + var N6 = "n6"; + var N7 = "n7"; + var N8 = "n8"; + + var N0_P = "n0-press"; + var N1_P = "n1-press"; + var N2_P = "n2-press"; + var N3_P = "n3-press"; + var N4_P = "n4-press"; + var N5_P = "n5-press"; + var N6_P = "n6-press"; + var N7_P = "n7-press"; + var N8_P = "n8-press"; + + var N0_R = "n0-release"; + var N1_R = "n1-release"; + var N2_R = "n2-release"; + var N3_R = "n3-release"; + var N4_R = "n4-release"; + var N5_R = "n5-release"; + var N6_R = "n6-release"; + var N7_R = "n7-release"; + var N8_R = "n8-release"; + + var U1 = "u1"; + var U2 = "u2"; + var U3 = "u3"; + var U4 = "u4"; + var U5 = "u5"; + var U6 = "u6"; + var U7 = "u7"; + + var U1_P = "u1-press"; + var U2_P = "u2-press"; + var U3_P = "u3-press"; + var U4_P = "u4-press"; + var U5_P = "u5-press"; + var U6_P = "u6-press"; + var U7_P = "u7-press"; + + var U1_R = "u1_release"; + var U2_R = "u2_release"; + var U3_R = "u3_release"; + var U4_R = "u4_release"; + var U5_R = "u5-release"; + var U6_R = "u6-release"; + var U7_R = "u7-release"; } #else @:enum abstract Action(String) to String from String { - var UI_UP = "ui_up"; - var UI_LEFT = "ui_left"; - var UI_RIGHT = "ui_right"; - var UI_DOWN = "ui_down"; - var UI_UP_P = "ui_up-press"; - var UI_LEFT_P = "ui_left-press"; - var UI_RIGHT_P = "ui_right-press"; - var UI_DOWN_P = "ui_down-press"; - var UI_UP_R = "ui_up-release"; - var UI_LEFT_R = "ui_left-release"; - var UI_RIGHT_R = "ui_right-release"; - var UI_DOWN_R = "ui_down-release"; - var NOTE_UP = "note_up"; - var NOTE_LEFT = "note_left"; - var NOTE_RIGHT = "note_right"; - var NOTE_DOWN = "note_down"; - var NOTE_UP_P = "note_up-press"; - var NOTE_LEFT_P = "note_left-press"; - var NOTE_RIGHT_P = "note_right-press"; - var NOTE_DOWN_P = "note_down-press"; - var NOTE_UP_R = "note_up-release"; - var NOTE_LEFT_R = "note_left-release"; - var NOTE_RIGHT_R = "note_right-release"; - var NOTE_DOWN_R = "note_down-release"; + var UP = "up"; + var LEFT = "left"; + var RIGHT = "right"; + var DOWN = "down"; + var UP_P = "up-press"; + var LEFT_P = "left-press"; + var RIGHT_P = "right-press"; + var DOWN_P = "down-press"; + var UP_R = "up-release"; + var LEFT_R = "left-release"; + var RIGHT_R = "right-release"; + var DOWN_R = "down-release"; var ACCEPT = "accept"; var BACK = "back"; var PAUSE = "pause"; var RESET = "reset"; + var CHEAT = "cheat"; + + var S1 = "s1"; + var S2 = "s2"; + var S3 = "s3"; + var S4 = "s4"; + var S5 = "s5"; + var S6 = "s6"; + + var S1_P = "s1-press"; + var S2_P = "s2-press"; + var S3_P = "s3-press"; + var S4_P = "s4-press"; + var S5_P = "s5-press"; + var S6_P = "s6-press"; + + var S1_R = "s1_release"; + var S2_R = "s2_release"; + var S3_R = "s3_release"; + var S4_R = "s4_release"; + var S5_R = "s5_release"; + var S6_R = "s6_release"; + + var T1 = "t1"; + var T2 = "t2"; + var T3 = "t3"; + var T4 = "t4"; + var T5 = "t5"; + + var T1_P = "t1-press"; + var T2_P = "t2-press"; + var T3_P = "t3-press"; + var T4_P = "t4-press"; + var T5_P = "t5-press"; + + var T1_R = "t1_release"; + var T2_R = "t2_release"; + var T3_R = "t3_release"; + var T4_R = "t4_release"; + var T5_R = "t5_release"; + + var N0 = "n0"; + var N1 = "n1"; + var N2 = "n2"; + var N3 = "n3"; + var N4 = "n4"; + var N5 = "n5"; + var N6 = "n6"; + var N7 = "n7"; + var N8 = "n8"; + + var N0_P = "n0-press"; + var N1_P = "n1-press"; + var N2_P = "n2-press"; + var N3_P = "n3-press"; + var N4_P = "n4-press"; + var N5_P = "n5-press"; + var N6_P = "n6-press"; + var N7_P = "n7-press"; + var N8_P = "n8-press"; + + var N0_R = "n0-release"; + var N1_R = "n1-release"; + var N2_R = "n2-release"; + var N3_R = "n3-release"; + var N4_R = "n4-release"; + var N5_R = "n5-release"; + var N6_R = "n6-release"; + var N7_R = "n7-release"; + var N8_R = "n8-release"; + + var U1 = "u1"; + var U2 = "u2"; + var U3 = "u3"; + var U4 = "u4"; + var U5 = "u5"; + var U6 = "u6"; + var U7 = "u7"; + + var U1_P = "u1-press"; + var U2_P = "u2-press"; + var U3_P = "u3-press"; + var U4_P = "u4-press"; + var U5_P = "u5-press"; + var U6_P = "u6-press"; + var U7_P = "u7-press"; + + var U1_R = "u1_release"; + var U2_R = "u2_release"; + var U3_R = "u3_release"; + var U4_R = "u4_release"; + var U5_P = "u5-release"; + var U6_P = "u6-release"; + var U7_P = "u7-release"; } #end @@ -95,18 +255,42 @@ enum Device */ enum Control { - UI_UP; - UI_LEFT; - UI_RIGHT; - UI_DOWN; - NOTE_UP; - NOTE_LEFT; - NOTE_RIGHT; - NOTE_DOWN; + UP; + LEFT; + RIGHT; + DOWN; RESET; ACCEPT; BACK; PAUSE; + CHEAT; + S1; + S2; + S3; + S4; + S5; + S6; + T1; + T2; + T3; + T4; + T5; + N0; + N1; + N2; + N3; + N4; + N5; + N6; + N7; + N8; + U1; + U2; + U3; + U4; + U5; + U6; + U7; } enum KeyboardScheme @@ -123,34 +307,121 @@ enum KeyboardScheme */ class Controls extends FlxActionSet { - var _ui_up = new FlxActionDigital(Action.UI_UP); - var _ui_left = new FlxActionDigital(Action.UI_LEFT); - var _ui_right = new FlxActionDigital(Action.UI_RIGHT); - var _ui_down = new FlxActionDigital(Action.UI_DOWN); - var _ui_upP = new FlxActionDigital(Action.UI_UP_P); - var _ui_leftP = new FlxActionDigital(Action.UI_LEFT_P); - var _ui_rightP = new FlxActionDigital(Action.UI_RIGHT_P); - var _ui_downP = new FlxActionDigital(Action.UI_DOWN_P); - var _ui_upR = new FlxActionDigital(Action.UI_UP_R); - var _ui_leftR = new FlxActionDigital(Action.UI_LEFT_R); - var _ui_rightR = new FlxActionDigital(Action.UI_RIGHT_R); - var _ui_downR = new FlxActionDigital(Action.UI_DOWN_R); - var _note_up = new FlxActionDigital(Action.NOTE_UP); - var _note_left = new FlxActionDigital(Action.NOTE_LEFT); - var _note_right = new FlxActionDigital(Action.NOTE_RIGHT); - var _note_down = new FlxActionDigital(Action.NOTE_DOWN); - var _note_upP = new FlxActionDigital(Action.NOTE_UP_P); - var _note_leftP = new FlxActionDigital(Action.NOTE_LEFT_P); - var _note_rightP = new FlxActionDigital(Action.NOTE_RIGHT_P); - var _note_downP = new FlxActionDigital(Action.NOTE_DOWN_P); - var _note_upR = new FlxActionDigital(Action.NOTE_UP_R); - var _note_leftR = new FlxActionDigital(Action.NOTE_LEFT_R); - var _note_rightR = new FlxActionDigital(Action.NOTE_RIGHT_R); - var _note_downR = new FlxActionDigital(Action.NOTE_DOWN_R); + var _up = new FlxActionDigital(Action.UP); + var _left = new FlxActionDigital(Action.LEFT); + var _right = new FlxActionDigital(Action.RIGHT); + var _down = new FlxActionDigital(Action.DOWN); + var _upP = new FlxActionDigital(Action.UP_P); + var _leftP = new FlxActionDigital(Action.LEFT_P); + var _rightP = new FlxActionDigital(Action.RIGHT_P); + var _downP = new FlxActionDigital(Action.DOWN_P); + var _upR = new FlxActionDigital(Action.UP_R); + var _leftR = new FlxActionDigital(Action.LEFT_R); + var _rightR = new FlxActionDigital(Action.RIGHT_R); + var _downR = new FlxActionDigital(Action.DOWN_R); var _accept = new FlxActionDigital(Action.ACCEPT); var _back = new FlxActionDigital(Action.BACK); var _pause = new FlxActionDigital(Action.PAUSE); var _reset = new FlxActionDigital(Action.RESET); + var _cheat = new FlxActionDigital(Action.CHEAT); + + var _s1 = new FlxActionDigital(Action.S1); + var _s1P = new FlxActionDigital(Action.S1_P); + var _s1R = new FlxActionDigital(Action.S1_R); + + var _s2 = new FlxActionDigital(Action.S2); + var _s2P = new FlxActionDigital(Action.S2_P); + var _s2R = new FlxActionDigital(Action.S2_R); + + var _s3 = new FlxActionDigital(Action.S3); + var _s3P = new FlxActionDigital(Action.S3_P); + var _s3R = new FlxActionDigital(Action.S3_R); + + var _s4 = new FlxActionDigital(Action.S4); + var _s4P = new FlxActionDigital(Action.S4_P); + var _s4R = new FlxActionDigital(Action.S4_R); + + var _s5 = new FlxActionDigital(Action.S5); + var _s5P = new FlxActionDigital(Action.S5_P); + var _s5R = new FlxActionDigital(Action.S5_R); + + var _s6 = new FlxActionDigital(Action.S6); + var _s6P = new FlxActionDigital(Action.S6_P); + var _s6R = new FlxActionDigital(Action.S6_R); + + var _t1 = new FlxActionDigital(Action.T1); + var _t1P = new FlxActionDigital(Action.T1_P); + var _t1R = new FlxActionDigital(Action.T1_R); + + var _t2 = new FlxActionDigital(Action.T2); + var _t2P = new FlxActionDigital(Action.T2_P); + var _t2R = new FlxActionDigital(Action.T2_R); + + var _t3 = new FlxActionDigital(Action.T3); + var _t3P = new FlxActionDigital(Action.T3_P); + var _t3R = new FlxActionDigital(Action.T3_R); + + var _t4 = new FlxActionDigital(Action.T4); + var _t4P = new FlxActionDigital(Action.T4_P); + var _t4R = new FlxActionDigital(Action.T4_R); + + var _t5 = new FlxActionDigital(Action.T5); + var _t5P = new FlxActionDigital(Action.T5_P); + var _t5R = new FlxActionDigital(Action.T5_R); + + var _n0 = new FlxActionDigital(Action.N0); + var _n1 = new FlxActionDigital(Action.N1); + var _n2 = new FlxActionDigital(Action.N2); + var _n3 = new FlxActionDigital(Action.N3); + var _n4 = new FlxActionDigital(Action.N4); + var _n5 = new FlxActionDigital(Action.N5); + var _n6 = new FlxActionDigital(Action.N6); + var _n7 = new FlxActionDigital(Action.N7); + var _n8 = new FlxActionDigital(Action.N8); + + var _n0P = new FlxActionDigital(Action.N0_P); + var _n1P = new FlxActionDigital(Action.N1_P); + var _n2P = new FlxActionDigital(Action.N2_P); + var _n3P = new FlxActionDigital(Action.N3_P); + var _n4P = new FlxActionDigital(Action.N4_P); + var _n5P = new FlxActionDigital(Action.N5_P); + var _n6P = new FlxActionDigital(Action.N6_P); + var _n7P = new FlxActionDigital(Action.N7_P); + var _n8P = new FlxActionDigital(Action.N8_P); + + var _n0R = new FlxActionDigital(Action.N0_R); + var _n1R = new FlxActionDigital(Action.N1_R); + var _n2R = new FlxActionDigital(Action.N2_R); + var _n3R = new FlxActionDigital(Action.N3_R); + var _n4R = new FlxActionDigital(Action.N4_R); + var _n5R = new FlxActionDigital(Action.N5_R); + var _n6R = new FlxActionDigital(Action.N6_R); + var _n7R = new FlxActionDigital(Action.N7_R); + var _n8R = new FlxActionDigital(Action.N8_R); + + var _u1 = new FlxActionDigital(Action.U1); + var _u2 = new FlxActionDigital(Action.U2); + var _u3 = new FlxActionDigital(Action.U3); + var _u4 = new FlxActionDigital(Action.U4); + var _u5 = new FlxActionDigital(Action.U5); + var _u6 = new FlxActionDigital(Action.U6); + var _u7 = new FlxActionDigital(Action.U7); + + var _u1P = new FlxActionDigital(Action.U1_P); + var _u2P = new FlxActionDigital(Action.U2_P); + var _u3P = new FlxActionDigital(Action.U3_P); + var _u4P = new FlxActionDigital(Action.U4_P); + var _u5P = new FlxActionDigital(Action.U5_P); + var _u6P = new FlxActionDigital(Action.U6_P); + var _u7P = new FlxActionDigital(Action.U7_P); + + var _u1R = new FlxActionDigital(Action.U1_R); + var _u2R = new FlxActionDigital(Action.U2_R); + var _u3R = new FlxActionDigital(Action.U3_R); + var _u4R = new FlxActionDigital(Action.U4_R); + var _u5R = new FlxActionDigital(Action.U5_R); + var _u6R = new FlxActionDigital(Action.U6_R); + var _u7R = new FlxActionDigital(Action.U7_R); #if (haxe >= "4.0.0") var byName:Map = []; @@ -161,125 +432,65 @@ class Controls extends FlxActionSet public var gamepadsAdded:Array = []; public var keyboardScheme = KeyboardScheme.None; - public var UI_UP(get, never):Bool; - - inline function get_UI_UP() - return _ui_up.check(); - - public var UI_LEFT(get, never):Bool; - - inline function get_UI_LEFT() - return _ui_left.check(); - - public var UI_RIGHT(get, never):Bool; - - inline function get_UI_RIGHT() - return _ui_right.check(); - - public var UI_DOWN(get, never):Bool; - - inline function get_UI_DOWN() - return _ui_down.check(); - - public var UI_UP_P(get, never):Bool; - - inline function get_UI_UP_P() - return _ui_upP.check(); - - public var UI_LEFT_P(get, never):Bool; - - inline function get_UI_LEFT_P() - return _ui_leftP.check(); - - public var UI_RIGHT_P(get, never):Bool; - - inline function get_UI_RIGHT_P() - return _ui_rightP.check(); - - public var UI_DOWN_P(get, never):Bool; + public var UP(get, never):Bool; - inline function get_UI_DOWN_P() - return _ui_downP.check(); + inline function get_UP() + return _up.check(); - public var UI_UP_R(get, never):Bool; + public var LEFT(get, never):Bool; - inline function get_UI_UP_R() - return _ui_upR.check(); + inline function get_LEFT() + return _left.check(); - public var UI_LEFT_R(get, never):Bool; + public var RIGHT(get, never):Bool; - inline function get_UI_LEFT_R() - return _ui_leftR.check(); + inline function get_RIGHT() + return _right.check(); - public var UI_RIGHT_R(get, never):Bool; + public var DOWN(get, never):Bool; - inline function get_UI_RIGHT_R() - return _ui_rightR.check(); + inline function get_DOWN() + return _down.check(); - public var UI_DOWN_R(get, never):Bool; + public var UP_P(get, never):Bool; - inline function get_UI_DOWN_R() - return _ui_downR.check(); + inline function get_UP_P() + return _upP.check(); - public var NOTE_UP(get, never):Bool; + public var LEFT_P(get, never):Bool; - inline function get_NOTE_UP() - return _note_up.check(); + inline function get_LEFT_P() + return _leftP.check(); - public var NOTE_LEFT(get, never):Bool; + public var RIGHT_P(get, never):Bool; - inline function get_NOTE_LEFT() - return _note_left.check(); + inline function get_RIGHT_P() + return _rightP.check(); - public var NOTE_RIGHT(get, never):Bool; + public var DOWN_P(get, never):Bool; - inline function get_NOTE_RIGHT() - return _note_right.check(); + inline function get_DOWN_P() + return _downP.check(); - public var NOTE_DOWN(get, never):Bool; + public var UP_R(get, never):Bool; - inline function get_NOTE_DOWN() - return _note_down.check(); + inline function get_UP_R() + return _upR.check(); - public var NOTE_UP_P(get, never):Bool; + public var LEFT_R(get, never):Bool; - inline function get_NOTE_UP_P() - return _note_upP.check(); + inline function get_LEFT_R() + return _leftR.check(); - public var NOTE_LEFT_P(get, never):Bool; + public var RIGHT_R(get, never):Bool; - inline function get_NOTE_LEFT_P() - return _note_leftP.check(); + inline function get_RIGHT_R() + return _rightR.check(); - public var NOTE_RIGHT_P(get, never):Bool; + public var DOWN_R(get, never):Bool; - inline function get_NOTE_RIGHT_P() - return _note_rightP.check(); - - public var NOTE_DOWN_P(get, never):Bool; - - inline function get_NOTE_DOWN_P() - return _note_downP.check(); - - public var NOTE_UP_R(get, never):Bool; - - inline function get_NOTE_UP_R() - return _note_upR.check(); - - public var NOTE_LEFT_R(get, never):Bool; - - inline function get_NOTE_LEFT_R() - return _note_leftR.check(); - - public var NOTE_RIGHT_R(get, never):Bool; - - inline function get_NOTE_RIGHT_R() - return _note_rightR.check(); - - public var NOTE_DOWN_R(get, never):Bool; - - inline function get_NOTE_DOWN_R() - return _note_downR.check(); + inline function get_DOWN_R() + return _downR.check(); public var ACCEPT(get, never):Bool; @@ -301,39 +512,314 @@ class Controls extends FlxActionSet inline function get_RESET() return _reset.check(); + public var CHEAT(get, never):Bool; + + inline function get_CHEAT() + return _cheat.check(); + + public var S1(get, never):Bool; + public var S2(get, never):Bool; + public var S3(get, never):Bool; + public var S4(get, never):Bool; + public var S5(get, never):Bool; + public var S6(get, never):Bool; + + public var S1_P(get, never):Bool; + public var S2_P(get, never):Bool; + public var S3_P(get, never):Bool; + public var S4_P(get, never):Bool; + public var S5_P(get, never):Bool; + public var S6_P(get, never):Bool; + + public var S1_R(get, never):Bool; + public var S2_R(get, never):Bool; + public var S3_R(get, never):Bool; + public var S4_R(get, never):Bool; + public var S5_R(get, never):Bool; + public var S6_R(get, never):Bool; + + inline function get_S1() return _s1.check(); + inline function get_S2() return _s2.check(); + inline function get_S3() return _s3.check(); + inline function get_S4() return _s4.check(); + inline function get_S5() return _s5.check(); + inline function get_S6() return _s6.check(); + + inline function get_S1_P() return _s1P.check(); + inline function get_S2_P() return _s2P.check(); + inline function get_S3_P() return _s3P.check(); + inline function get_S4_P() return _s4P.check(); + inline function get_S5_P() return _s5P.check(); + inline function get_S6_P() return _s6P.check(); + + inline function get_S1_R() return _s1R.check(); + inline function get_S2_R() return _s2R.check(); + inline function get_S3_R() return _s3R.check(); + inline function get_S4_R() return _s4R.check(); + inline function get_S5_R() return _s5R.check(); + inline function get_S6_R() return _s6R.check(); + + public var T1(get, never):Bool; + public var T2(get, never):Bool; + public var T3(get, never):Bool; + public var T4(get, never):Bool; + public var T5(get, never):Bool; + + public var T1_P(get, never):Bool; + public var T2_P(get, never):Bool; + public var T3_P(get, never):Bool; + public var T4_P(get, never):Bool; + public var T5_P(get, never):Bool; + + public var T1_R(get, never):Bool; + public var T2_R(get, never):Bool; + public var T3_R(get, never):Bool; + public var T4_R(get, never):Bool; + public var T5_R(get, never):Bool; + + inline function get_T1() return _t1.check(); + inline function get_T2() return _t2.check(); + inline function get_T3() return _t3.check(); + inline function get_T4() return _t4.check(); + inline function get_T5() return _t5.check(); + + inline function get_T1_P() return _t1P.check(); + inline function get_T2_P() return _t2P.check(); + inline function get_T3_P() return _t3P.check(); + inline function get_T4_P() return _t4P.check(); + inline function get_T5_P() return _t5P.check(); + + inline function get_T1_R() return _t1R.check(); + inline function get_T2_R() return _t2R.check(); + inline function get_T3_R() return _t3R.check(); + inline function get_T4_R() return _t4R.check(); + inline function get_T5_R() return _t5R.check(); + + public var N0(get, never):Bool; + public var N1(get, never):Bool; + public var N2(get, never):Bool; + public var N3(get, never):Bool; + public var N4(get, never):Bool; + public var N5(get, never):Bool; + public var N6(get, never):Bool; + public var N7(get, never):Bool; + public var N8(get, never):Bool; + + public var N0_P(get, never):Bool; + public var N1_P(get, never):Bool; + public var N2_P(get, never):Bool; + public var N3_P(get, never):Bool; + public var N4_P(get, never):Bool; + public var N5_P(get, never):Bool; + public var N6_P(get, never):Bool; + public var N7_P(get, never):Bool; + public var N8_P(get, never):Bool; + + public var N0_R(get, never):Bool; + public var N1_R(get, never):Bool; + public var N2_R(get, never):Bool; + public var N3_R(get, never):Bool; + public var N4_R(get, never):Bool; + public var N5_R(get, never):Bool; + public var N6_R(get, never):Bool; + public var N7_R(get, never):Bool; + public var N8_R(get, never):Bool; + + inline function get_N0() return _n0.check(); + inline function get_N1() return _n1.check(); + inline function get_N2() return _n2.check(); + inline function get_N3() return _n3.check(); + inline function get_N4() return _n4.check(); + inline function get_N5() return _n5.check(); + inline function get_N6() return _n6.check(); + inline function get_N7() return _n7.check(); + inline function get_N8() return _n8.check(); + + inline function get_N0_P() return _n0P.check(); + inline function get_N1_P() return _n1P.check(); + inline function get_N2_P() return _n2P.check(); + inline function get_N3_P() return _n3P.check(); + inline function get_N4_P() return _n4P.check(); + inline function get_N5_P() return _n5P.check(); + inline function get_N6_P() return _n6P.check(); + inline function get_N7_P() return _n7P.check(); + inline function get_N8_P() return _n8P.check(); + + inline function get_N0_R() return _n0R.check(); + inline function get_N1_R() return _n1R.check(); + inline function get_N2_R() return _n2R.check(); + inline function get_N3_R() return _n3R.check(); + inline function get_N4_R() return _n4R.check(); + inline function get_N5_R() return _n5R.check(); + inline function get_N6_R() return _n6R.check(); + inline function get_N7_R() return _n7R.check(); + inline function get_N8_R() return _n8R.check(); + + + public var U1(get, never):Bool; + public var U2(get, never):Bool; + public var U3(get, never):Bool; + public var U4(get, never):Bool; + public var U5(get, never):Bool; + public var U6(get, never):Bool; + public var U7(get, never):Bool; + + public var U1_P(get, never):Bool; + public var U2_P(get, never):Bool; + public var U3_P(get, never):Bool; + public var U4_P(get, never):Bool; + public var U5_P(get, never):Bool; + public var U6_P(get, never):Bool; + public var U7_P(get, never):Bool; + + public var U1_R(get, never):Bool; + public var U2_R(get, never):Bool; + public var U3_R(get, never):Bool; + public var U4_R(get, never):Bool; + public var U5_R(get, never):Bool; + public var U6_R(get, never):Bool; + public var U7_R(get, never):Bool; + + inline function get_U1() return _u1.check(); + inline function get_U2() return _u2.check(); + inline function get_U3() return _u3.check(); + inline function get_U4() return _u4.check(); + inline function get_U5() return _u5.check(); + inline function get_U6() return _u6.check(); + inline function get_U7() return _u7.check(); + + inline function get_U1_P() return _u1P.check(); + inline function get_U2_P() return _u2P.check(); + inline function get_U3_P() return _u3P.check(); + inline function get_U4_P() return _u4P.check(); + inline function get_U5_P() return _u5P.check(); + inline function get_U6_P() return _u6P.check(); + inline function get_U7_P() return _u7P.check(); + + inline function get_U1_R() return _u1R.check(); + inline function get_U2_R() return _u2R.check(); + inline function get_U3_R() return _u3R.check(); + inline function get_U4_R() return _u4R.check(); + inline function get_U5_R() return _u5R.check(); + inline function get_U6_R() return _u6R.check(); + inline function get_U7_R() return _u7R.check(); + #if (haxe >= "4.0.0") public function new(name, scheme = None) { super(name); - add(_ui_up); - add(_ui_left); - add(_ui_right); - add(_ui_down); - add(_ui_upP); - add(_ui_leftP); - add(_ui_rightP); - add(_ui_downP); - add(_ui_upR); - add(_ui_leftR); - add(_ui_rightR); - add(_ui_downR); - add(_note_up); - add(_note_left); - add(_note_right); - add(_note_down); - add(_note_upP); - add(_note_leftP); - add(_note_rightP); - add(_note_downP); - add(_note_upR); - add(_note_leftR); - add(_note_rightR); - add(_note_downR); + add(_up); + add(_left); + add(_right); + add(_down); + add(_upP); + add(_leftP); + add(_rightP); + add(_downP); + add(_upR); + add(_leftR); + add(_rightR); + add(_downR); add(_accept); add(_back); add(_pause); add(_reset); + add(_cheat); + + add(_s1); + add(_s2); + add(_s3); + add(_s4); + add(_s5); + add(_s6); + + add(_s1P); + add(_s2P); + add(_s3P); + add(_s4P); + add(_s5P); + add(_s6P); + + add(_s1R); + add(_s2R); + add(_s3R); + add(_s4R); + add(_s5R); + add(_s6R); + + add(_t1); + add(_t2); + add(_t3); + add(_t4); + add(_t5); + + add(_t1P); + add(_t2P); + add(_t3P); + add(_t4P); + add(_t5P); + + add(_t1R); + add(_t2R); + add(_t3R); + add(_t4R); + add(_t5R); + + add(_n0); + add(_n1); + add(_n2); + add(_n3); + add(_n4); + add(_n5); + add(_n6); + add(_n7); + add(_n8); + + add(_n0P); + add(_n1P); + add(_n2P); + add(_n3P); + add(_n4P); + add(_n5P); + add(_n6P); + add(_n7P); + add(_n8P); + + add(_n0R); + add(_n1R); + add(_n2R); + add(_n3R); + add(_n4R); + add(_n5R); + add(_n6R); + add(_n7R); + add(_n8R); + + + add(_u1); + add(_u2); + add(_u3); + add(_u4); + add(_u5); + add(_u6); + add(_u7); + + add(_u1P); + add(_u2P); + add(_u3P); + add(_u4P); + add(_u5P); + add(_u6P); + add(_u7P); + + add(_u1R); + add(_u2R); + add(_u3R); + add(_u4R); + add(_u5R); + add(_u6R); + add(_u7R); for (action in digitalActions) byName[action.name] = action; @@ -345,34 +831,123 @@ class Controls extends FlxActionSet { super(name); - add(_ui_up); - add(_ui_left); - add(_ui_right); - add(_ui_down); - add(_ui_upP); - add(_ui_leftP); - add(_ui_rightP); - add(_ui_downP); - add(_ui_upR); - add(_ui_leftR); - add(_ui_rightR); - add(_ui_downR); - add(_note_up); - add(_note_left); - add(_note_right); - add(_note_down); - add(_note_upP); - add(_note_leftP); - add(_note_rightP); - add(_note_downP); - add(_note_upR); - add(_note_leftR); - add(_note_rightR); - add(_note_downR); + add(_up); + add(_left); + add(_right); + add(_down); + add(_upP); + add(_leftP); + add(_rightP); + add(_downP); + add(_upR); + add(_leftR); + add(_rightR); + add(_downR); add(_accept); add(_back); add(_pause); add(_reset); + add(_cheat); + + add(_s1); + add(_s2); + add(_s3); + add(_s4); + add(_s5); + add(_s6); + + add(_s1P); + add(_s2P); + add(_s3P); + add(_s4P); + add(_s5P); + add(_s6P); + + add(_s1R); + add(_s2R); + add(_s3R); + add(_s4R); + add(_s5R); + add(_s6R); + + add(_t1); + add(_t2); + add(_t3); + add(_t4); + add(_t5); + + add(_t1P); + add(_t2P); + add(_t3P); + add(_t4P); + add(_t5P); + + add(_t1R); + add(_t2R); + add(_t3R); + add(_t4R); + add(_t5R); + + add(_n0); + add(_n1); + add(_n2); + add(_n3); + add(_n4); + add(_n5); + add(_n6); + add(_n7); + add(_n8); + + add(_n0P); + add(_n1P); + add(_n2P); + add(_n3P); + add(_n4P); + add(_n5P); + add(_n6P); + add(_n7P); + add(_n8P); + + add(_n0R); + add(_n1R); + add(_n2R); + add(_n3R); + add(_n4R); + add(_n5R); + add(_n6R); + add(_n7R); + add(_n8R); + + + add(_u0); + add(_u1); + add(_u2); + add(_u3); + add(_u4); + add(_u5); + add(_u6); + add(_u7); + add(_u8); + + add(_u0P); + add(_u1P); + add(_u2P); + add(_u3P); + add(_u4P); + add(_u5P); + add(_u6P); + add(_u7P); + add(_u8P); + + add(_u0R); + add(_u1R); + add(_u2R); + add(_u3R); + add(_u4R); + add(_u5R); + add(_u6R); + add(_u7R); + add(_u8R); for (action in digitalActions) byName[action.name] = action; @@ -383,173 +958,6 @@ class Controls extends FlxActionSet } #end - public var trackedinputsUI:Array = []; - public var trackedinputsNOTES:Array = []; - - public function addbuttonuNOTES(action:FlxActionDigital, button:FlxButton, state:FlxInputState) - { - var input = new FlxActionInputDigitalIFlxInput(button, state); - trackedinputsNOTES.push(input); - - action.add(input); - } - - public function setHitBoxNOTES(hitbox:Hitbox) - { - inline forEachBound(Control.NOTE_UP, (action, state) -> addbuttonuNOTES(action, hitbox.buttonUp, state)); - inline forEachBound(Control.NOTE_DOWN, (action, state) -> addbuttonuNOTES(action, hitbox.buttonDown, state)); - inline forEachBound(Control.NOTE_LEFT, (action, state) -> addbuttonuNOTES(action, hitbox.buttonLeft, state)); - inline forEachBound(Control.NOTE_RIGHT, (action, state) -> addbuttonuNOTES(action, hitbox.buttonRight, state)); - } - - public function setVirtualPadNOTES(virtualPad:FlxVirtualPad, ?DPad:FlxDPadMode, ?Action:FlxActionMode) - { - if (DPad == null) - DPad = NONE; - if (Action == null) - Action = NONE; - - switch (DPad) - { - case UP_DOWN: - inline forEachBound(Control.NOTE_UP, (action, state) -> addbuttonuNOTES(action, virtualPad.buttonUp, state)); - inline forEachBound(Control.NOTE_DOWN, (action, state) -> addbuttonuNOTES(action, virtualPad.buttonDown, state)); - case LEFT_RIGHT: - inline forEachBound(Control.NOTE_LEFT, (action, state) -> addbuttonuNOTES(action, virtualPad.buttonLeft, state)); - inline forEachBound(Control.NOTE_RIGHT, (action, state) -> addbuttonuNOTES(action, virtualPad.buttonRight, state)); - case UP_LEFT_RIGHT: - inline forEachBound(Control.NOTE_UP, (action, state) -> addbuttonuNOTES(action, virtualPad.buttonUp, state)); - inline forEachBound(Control.NOTE_LEFT, (action, state) -> addbuttonuNOTES(action, virtualPad.buttonLeft, state)); - inline forEachBound(Control.NOTE_RIGHT, (action, state) -> addbuttonuNOTES(action, virtualPad.buttonRight, state)); - case FULL | RIGHT_FULL: - inline forEachBound(Control.NOTE_UP, (action, state) -> addbuttonuNOTES(action, virtualPad.buttonUp, state)); - inline forEachBound(Control.NOTE_DOWN, (action, state) -> addbuttonuNOTES(action, virtualPad.buttonDown, state)); - inline forEachBound(Control.NOTE_LEFT, (action, state) -> addbuttonuNOTES(action, virtualPad.buttonLeft, state)); - inline forEachBound(Control.NOTE_RIGHT, (action, state) -> addbuttonuNOTES(action, virtualPad.buttonRight, state)); - - case NONE: - } - - switch (Action) - { - case A: - inline forEachBound(Control.ACCEPT, (action, state) -> addbuttonuNOTES(action, virtualPad.buttonA, state)); - case B: - inline forEachBound(Control.BACK, (action, state) -> addbuttonuUI(action, virtualPad.buttonB, state)); - case D: - //nothing - case A_B: - inline forEachBound(Control.ACCEPT, (action, state) -> addbuttonuNOTES(action, virtualPad.buttonA, state)); - inline forEachBound(Control.BACK, (action, state) -> addbuttonuNOTES(action, virtualPad.buttonB, state)); - case A_B_C: - inline forEachBound(Control.ACCEPT, (action, state) -> addbuttonuNOTES(action, virtualPad.buttonA, state)); - inline forEachBound(Control.BACK, (action, state) -> addbuttonuNOTES(action, virtualPad.buttonB, state)); - case A_B_7: - inline forEachBound(Control.ACCEPT, (action, state) -> addbuttonuNOTES(action, virtualPad.buttonA, state)); - inline forEachBound(Control.BACK, (action, state) -> addbuttonuNOTES(action, virtualPad.buttonB, state)); - case A_B_X_Y_D: - inline forEachBound(Control.ACCEPT, (action, state) -> addbuttonuNOTES(action, virtualPad.buttonA, state)); - inline forEachBound(Control.BACK, (action, state) -> addbuttonuNOTES(action, virtualPad.buttonB, state)); - case A_B_X_Y_C_D: - //nothing - case A_B_X_Y: - inline forEachBound(Control.ACCEPT, (action, state) -> addbuttonuNOTES(action, virtualPad.buttonA, state)); - inline forEachBound(Control.BACK, (action, state) -> addbuttonuNOTES(action, virtualPad.buttonB, state)); - case NONE: - } - } - - - public function addbuttonuUI(action:FlxActionDigital, button:FlxButton, state:FlxInputState) { - var input = new FlxActionInputDigitalIFlxInput(button, state); - trackedinputsUI.push(input); - - action.add(input); - } - - public function setHitBoxUI(hitbox:Hitbox) - { - inline forEachBound(Control.UI_UP, (action, state) -> addbuttonuUI(action, hitbox.buttonUp, state)); - inline forEachBound(Control.UI_DOWN, (action, state) -> addbuttonuUI(action, hitbox.buttonDown, state)); - inline forEachBound(Control.UI_LEFT, (action, state) -> addbuttonuUI(action, hitbox.buttonLeft, state)); - inline forEachBound(Control.UI_RIGHT, (action, state) -> addbuttonuUI(action, hitbox.buttonRight, state)); - } - - public function setVirtualPadUI(virtualPad:FlxVirtualPad, ?DPad:FlxDPadMode, ?Action:FlxActionMode) - { - if (DPad == null) - DPad = NONE; - if (Action == null) - Action = NONE; - - switch (DPad) - { - case UP_DOWN: - inline forEachBound(Control.UI_UP, (action, state) -> addbuttonuUI(action, virtualPad.buttonUp, state)); - inline forEachBound(Control.UI_DOWN, (action, state) -> addbuttonuUI(action, virtualPad.buttonDown, state)); - case LEFT_RIGHT: - inline forEachBound(Control.UI_LEFT, (action, state) -> addbuttonuUI(action, virtualPad.buttonLeft, state)); - inline forEachBound(Control.UI_RIGHT, (action, state) -> addbuttonuUI(action, virtualPad.buttonRight, state)); - case UP_LEFT_RIGHT: - inline forEachBound(Control.UI_UP, (action, state) -> addbuttonuUI(action, virtualPad.buttonUp, state)); - inline forEachBound(Control.UI_LEFT, (action, state) -> addbuttonuUI(action, virtualPad.buttonLeft, state)); - inline forEachBound(Control.UI_RIGHT, (action, state) -> addbuttonuUI(action, virtualPad.buttonRight, state)); - case FULL | RIGHT_FULL: - inline forEachBound(Control.UI_UP, (action, state) -> addbuttonuUI(action, virtualPad.buttonUp, state)); - inline forEachBound(Control.UI_DOWN, (action, state) -> addbuttonuUI(action, virtualPad.buttonDown, state)); - inline forEachBound(Control.UI_LEFT, (action, state) -> addbuttonuUI(action, virtualPad.buttonLeft, state)); - inline forEachBound(Control.UI_RIGHT, (action, state) -> addbuttonuUI(action, virtualPad.buttonRight, state)); - - case NONE: - } - - switch (Action) - { - case A: - inline forEachBound(Control.ACCEPT, (action, state) -> addbuttonuUI(action, virtualPad.buttonA, state)); - case B: - inline forEachBound(Control.BACK, (action, state) -> addbuttonuUI(action, virtualPad.buttonB, state)); - case D: - //nothing - case A_B: - inline forEachBound(Control.ACCEPT, (action, state) -> addbuttonuUI(action, virtualPad.buttonA, state)); - inline forEachBound(Control.BACK, (action, state) -> addbuttonuUI(action, virtualPad.buttonB, state)); - case A_B_7: - inline forEachBound(Control.ACCEPT, (action, state) -> addbuttonuUI(action, virtualPad.buttonA, state)); - inline forEachBound(Control.BACK, (action, state) -> addbuttonuUI(action, virtualPad.buttonB, state)); - case A_B_C: - inline forEachBound(Control.ACCEPT, (action, state) -> addbuttonuNOTES(action, virtualPad.buttonA, state)); - inline forEachBound(Control.BACK, (action, state) -> addbuttonuNOTES(action, virtualPad.buttonB, state)); - case A_B_X_Y_D: - inline forEachBound(Control.ACCEPT, (action, state) -> addbuttonuUI(action, virtualPad.buttonA, state)); - inline forEachBound(Control.BACK, (action, state) -> addbuttonuUI(action, virtualPad.buttonB, state)); - case A_B_X_Y_C_D: - //nothing - case A_B_X_Y: - inline forEachBound(Control.ACCEPT, (action, state) -> addbuttonuUI(action, virtualPad.buttonA, state)); - inline forEachBound(Control.BACK, (action, state) -> addbuttonuUI(action, virtualPad.buttonB, state)); - case NONE: - } - } - - - public function removeFlxInput(Tinputs) { - for (action in this.digitalActions) - { - var i = action.inputs.length; - - while (i-- > 0) - { - var input = action.inputs[i]; - - var x = Tinputs.length; - while (x-- > 0) - if (Tinputs[x] == input) - action.remove(input); - } - } - } - override function update() { super.update(); @@ -585,18 +993,46 @@ class Controls extends FlxActionSet { return switch (control) { - case UI_UP: _ui_up; - case UI_DOWN: _ui_down; - case UI_LEFT: _ui_left; - case UI_RIGHT: _ui_right; - case NOTE_UP: _note_up; - case NOTE_DOWN: _note_down; - case NOTE_LEFT: _note_left; - case NOTE_RIGHT: _note_right; + case UP: _up; + case DOWN: _down; + case LEFT: _left; + case RIGHT: _right; case ACCEPT: _accept; case BACK: _back; case PAUSE: _pause; case RESET: _reset; + case CHEAT: _cheat; + + case S1: _s1; + case S2: _s2; + case S3: _s3; + case S4: _s4; + case S5: _s5; + case S6: _s6; + + case T1: _t1; + case T2: _t2; + case T3: _t3; + case T4: _t4; + case T5: _t5; + + case N0: _n0; + case N1: _n1; + case N2: _n2; + case N3: _n3; + case N4: _n4; + case N5: _n5; + case N6: _n6; + case N7: _n7; + case N8: _n8; + + case U1: _u1; + case U2: _u2; + case U3: _u3; + case U4: _u4; + case U5: _u5; + case U6: _u6; + case U7: _u7; } } @@ -616,38 +1052,22 @@ class Controls extends FlxActionSet { switch (control) { - case UI_UP: - func(_ui_up, PRESSED); - func(_ui_upP, JUST_PRESSED); - func(_ui_upR, JUST_RELEASED); - case UI_LEFT: - func(_ui_left, PRESSED); - func(_ui_leftP, JUST_PRESSED); - func(_ui_leftR, JUST_RELEASED); - case UI_RIGHT: - func(_ui_right, PRESSED); - func(_ui_rightP, JUST_PRESSED); - func(_ui_rightR, JUST_RELEASED); - case UI_DOWN: - func(_ui_down, PRESSED); - func(_ui_downP, JUST_PRESSED); - func(_ui_downR, JUST_RELEASED); - case NOTE_UP: - func(_note_up, PRESSED); - func(_note_upP, JUST_PRESSED); - func(_note_upR, JUST_RELEASED); - case NOTE_LEFT: - func(_note_left, PRESSED); - func(_note_leftP, JUST_PRESSED); - func(_note_leftR, JUST_RELEASED); - case NOTE_RIGHT: - func(_note_right, PRESSED); - func(_note_rightP, JUST_PRESSED); - func(_note_rightR, JUST_RELEASED); - case NOTE_DOWN: - func(_note_down, PRESSED); - func(_note_downP, JUST_PRESSED); - func(_note_downR, JUST_RELEASED); + case UP: + func(_up, PRESSED); + func(_upP, JUST_PRESSED); + func(_upR, JUST_RELEASED); + case LEFT: + func(_left, PRESSED); + func(_leftP, JUST_PRESSED); + func(_leftR, JUST_RELEASED); + case RIGHT: + func(_right, PRESSED); + func(_rightP, JUST_PRESSED); + func(_rightR, JUST_RELEASED); + case DOWN: + func(_down, PRESSED); + func(_downP, JUST_PRESSED); + func(_downR, JUST_RELEASED); case ACCEPT: func(_accept, JUST_PRESSED); case BACK: @@ -656,6 +1076,119 @@ class Controls extends FlxActionSet func(_pause, JUST_PRESSED); case RESET: func(_reset, JUST_PRESSED); + case CHEAT: + func(_cheat, JUST_PRESSED); + + case S1: + func(_s1, PRESSED); + func(_s1P, JUST_PRESSED); + func(_s1R, JUST_RELEASED); + case S2: + func(_s2, PRESSED); + func(_s2P, JUST_PRESSED); + func(_s2R, JUST_RELEASED); + case S3: + func(_s3, PRESSED); + func(_s3P, JUST_PRESSED); + func(_s3R, JUST_RELEASED); + case S4: + func(_s4, PRESSED); + func(_s4P, JUST_PRESSED); + func(_s4R, JUST_RELEASED); + case S5: + func(_s5, PRESSED); + func(_s5P, JUST_PRESSED); + func(_s5R, JUST_RELEASED); + case S6: + func(_s6, PRESSED); + func(_s6P, JUST_PRESSED); + func(_s6R, JUST_RELEASED); + + case T1: + func(_t1, PRESSED); + func(_t1P, JUST_PRESSED); + func(_t1R, JUST_RELEASED); + case T2: + func(_t2, PRESSED); + func(_t2P, JUST_PRESSED); + func(_t2R, JUST_RELEASED); + case T3: + func(_t3, PRESSED); + func(_t3P, JUST_PRESSED); + func(_t3R, JUST_RELEASED); + case T4: + func(_t4, PRESSED); + func(_t4P, JUST_PRESSED); + func(_t4R, JUST_RELEASED); + case T5: + func(_t5, PRESSED); + func(_t5P, JUST_PRESSED); + func(_t5R, JUST_RELEASED); + + case N0: + func(_n0, PRESSED); + func(_n0P, JUST_PRESSED); + func(_n0R, JUST_RELEASED); + case N1: + func(_n1, PRESSED); + func(_n1P, JUST_PRESSED); + func(_n1R, JUST_RELEASED); + case N2: + func(_n2, PRESSED); + func(_n2P, JUST_PRESSED); + func(_n2R, JUST_RELEASED); + case N3: + func(_n3, PRESSED); + func(_n3P, JUST_PRESSED); + func(_n3R, JUST_RELEASED); + case N4: + func(_n4, PRESSED); + func(_n4P, JUST_PRESSED); + func(_n4R, JUST_RELEASED); + case N5: + func(_n5, PRESSED); + func(_n5P, JUST_PRESSED); + func(_n5R, JUST_RELEASED); + case N6: + func(_n6, PRESSED); + func(_n6P, JUST_PRESSED); + func(_n6R, JUST_RELEASED); + case N7: + func(_n7, PRESSED); + func(_n7P, JUST_PRESSED); + func(_n7R, JUST_RELEASED); + case N8: + func(_n8, PRESSED); + func(_n8P, JUST_PRESSED); + func(_n8R, JUST_RELEASED); + case U1: + func(_u1, PRESSED); + func(_u1P, JUST_PRESSED); + func(_u1R, JUST_RELEASED); + case U2: + func(_u2, PRESSED); + func(_u2P, JUST_PRESSED); + func(_u2R, JUST_RELEASED); + case U3: + func(_u3, PRESSED); + func(_u3P, JUST_PRESSED); + func(_u3R, JUST_RELEASED); + case U4: + func(_u4, PRESSED); + func(_u4P, JUST_PRESSED); + func(_u4R, JUST_RELEASED); + case U5: + func(_u5, PRESSED); + func(_u5P, JUST_PRESSED); + func(_u5R, JUST_RELEASED); + case U6: + func(_u6, PRESSED); + func(_u6P, JUST_PRESSED); + func(_u6R, JUST_RELEASED); + case U7: + func(_u7, PRESSED); + func(_u7P, JUST_PRESSED); + func(_u7R, JUST_RELEASED); } } @@ -745,61 +1278,36 @@ class Controls extends FlxActionSet } } - #if desktop - public function bindKeys(control:Control, keys:Array) - { - var copyKeys:Array = keys.copy(); - for (i in 0...copyKeys.length) { - if(i == NONE) copyKeys.remove(i); - } - - #if (haxe >= "4.0.0") - inline forEachBound(control, (action, state) -> addKeys(action, copyKeys, state)); - #else - forEachBound(control, function(action, state) addKeys(action, copyKeys, state)); - #end - } - - public function unbindKeys(control:Control, keys:Array) - { - var copyKeys:Array = keys.copy(); - for (i in 0...copyKeys.length) { - if(i == NONE) copyKeys.remove(i); - } - - #if (haxe >= "4.0.0") - inline forEachBound(control, (action, _) -> removeKeys(action, copyKeys)); - #else - forEachBound(control, function(action, _) removeKeys(action, copyKeys)); - #end - } - - #else - + /** + * Sets all actions that pertain to the binder to trigger when the supplied keys are used. + * If binder is a literal you can inline this + */ public function bindKeys(control:Control, keys:Array) { #if (haxe >= "4.0.0") inline forEachBound(control, (action, state) -> addKeys(action, keys, state)); #else forEachBound(control, function(action, state) addKeys(action, keys, state)); - #end + #end } + /** + * Sets all actions that pertain to the binder to trigger when the supplied keys are used. + * If binder is a literal you can inline this + */ public function unbindKeys(control:Control, keys:Array) { #if (haxe >= "4.0.0") inline forEachBound(control, (action, _) -> removeKeys(action, keys)); #else forEachBound(control, function(action, _) removeKeys(action, keys)); - #end - } - #end + #end + } inline static function addKeys(action:FlxActionDigital, keys:Array, state:FlxInputState) { for (key in keys) - if(key != NONE) - action.addKey(key, state); + action.addKey(key, state); } static function removeKeys(action:FlxActionDigital, keys:Array) @@ -815,104 +1323,56 @@ class Controls extends FlxActionSet public function setKeyboardScheme(scheme:KeyboardScheme, reset = true) { - if (reset) - removeKeyboard(); + loadKeyBinds(); + + inline bindKeys(Control.N0, [A]); + inline bindKeys(Control.N1, [S]); + inline bindKeys(Control.N2, [D]); + inline bindKeys(Control.N3, [F]); + inline bindKeys(Control.N4, [FlxKey.SPACE]); + inline bindKeys(Control.N5, [H]); + inline bindKeys(Control.N6, [J]); + inline bindKeys(Control.N7, [K]); + inline bindKeys(Control.N8, [L]); + + inline bindKeys(Control.S1, [S]); + inline bindKeys(Control.S2, [D]); + inline bindKeys(Control.S3, [F]); + inline bindKeys(Control.S4, [J]); + inline bindKeys(Control.S5, [K]); + inline bindKeys(Control.S6, [L]); + + inline bindKeys(Control.T1, [D]); + inline bindKeys(Control.T2, [F]); + inline bindKeys(Control.T3, [FlxKey.SPACE]); + inline bindKeys(Control.T4, [J]); + inline bindKeys(Control.T5, [K]); + + inline bindKeys(Control.U1, [S]); + inline bindKeys(Control.U2, [D]); + inline bindKeys(Control.U3, [F]); + inline bindKeys(Control.U4, [FlxKey.SPACE]); + inline bindKeys(Control.U5, [J]); + inline bindKeys(Control.U6, [K]); + inline bindKeys(Control.U7, [L]); + } - keyboardScheme = scheme; - var keysMap = ClientPrefs.keyBinds; - - #if (haxe >= "4.0.0") - switch (scheme) - { - case Solo: - inline bindKeys(Control.UI_UP, keysMap.get('ui_up')); - inline bindKeys(Control.UI_DOWN, keysMap.get('ui_down')); - inline bindKeys(Control.UI_LEFT, keysMap.get('ui_left')); - inline bindKeys(Control.UI_RIGHT, keysMap.get('ui_right')); - inline bindKeys(Control.NOTE_UP, keysMap.get('note_up')); - inline bindKeys(Control.NOTE_DOWN, keysMap.get('note_down')); - inline bindKeys(Control.NOTE_LEFT, keysMap.get('note_left')); - inline bindKeys(Control.NOTE_RIGHT, keysMap.get('note_right')); - - inline bindKeys(Control.ACCEPT, keysMap.get('accept')); - inline bindKeys(Control.BACK, keysMap.get('back')); - inline bindKeys(Control.PAUSE, keysMap.get('pause')); - inline bindKeys(Control.RESET, keysMap.get('reset')); - case Duo(true): - inline bindKeys(Control.UI_UP, [W]); - inline bindKeys(Control.UI_DOWN, [S]); - inline bindKeys(Control.UI_LEFT, [A]); - inline bindKeys(Control.UI_RIGHT, [D]); - inline bindKeys(Control.NOTE_UP, [W]); - inline bindKeys(Control.NOTE_DOWN, [S]); - inline bindKeys(Control.NOTE_LEFT, [A]); - inline bindKeys(Control.NOTE_RIGHT, [D]); - inline bindKeys(Control.ACCEPT, [G, Z]); - inline bindKeys(Control.BACK, [H, X]); - inline bindKeys(Control.PAUSE, [ONE]); - inline bindKeys(Control.RESET, [R]); - case Duo(false): - inline bindKeys(Control.UI_UP, [FlxKey.UP]); - inline bindKeys(Control.UI_DOWN, [FlxKey.DOWN]); - inline bindKeys(Control.UI_LEFT, [FlxKey.LEFT]); - inline bindKeys(Control.UI_RIGHT, [FlxKey.RIGHT]); - inline bindKeys(Control.NOTE_UP, [FlxKey.UP]); - inline bindKeys(Control.NOTE_DOWN, [FlxKey.DOWN]); - inline bindKeys(Control.NOTE_LEFT, [FlxKey.LEFT]); - inline bindKeys(Control.NOTE_RIGHT, [FlxKey.RIGHT]); - inline bindKeys(Control.ACCEPT, [O]); - inline bindKeys(Control.BACK, [P]); - inline bindKeys(Control.PAUSE, [ENTER]); - inline bindKeys(Control.RESET, [BACKSPACE]); - case None: // nothing - case Custom: // nothing - } - #else - switch (scheme) - { - case Solo: - bindKeys(Control.UI_UP, [W, FlxKey.UP]); - bindKeys(Control.UI_DOWN, [S, FlxKey.DOWN]); - bindKeys(Control.UI_LEFT, [A, FlxKey.LEFT]); - bindKeys(Control.UI_RIGHT, [D, FlxKey.RIGHT]); - bindKeys(Control.NOTE_UP, [W, FlxKey.UP]); - bindKeys(Control.NOTE_DOWN, [S, FlxKey.DOWN]); - bindKeys(Control.NOTE_LEFT, [A, FlxKey.LEFT]); - bindKeys(Control.NOTE_RIGHT, [D, FlxKey.RIGHT]); - bindKeys(Control.ACCEPT, [Z, SPACE, ENTER]); - bindKeys(Control.BACK, [BACKSPACE, ESCAPE]); - bindKeys(Control.PAUSE, [P, ENTER, ESCAPE]); - bindKeys(Control.RESET, [R]); - case Duo(true): - bindKeys(Control.UI_UP, [W]); - bindKeys(Control.UI_DOWN, [S]); - bindKeys(Control.UI_LEFT, [A]); - bindKeys(Control.UI_RIGHT, [D]); - bindKeys(Control.NOTE_UP, [W]); - bindKeys(Control.NOTE_DOWN, [S]); - bindKeys(Control.NOTE_LEFT, [A]); - bindKeys(Control.NOTE_RIGHT, [D]); - bindKeys(Control.ACCEPT, [G, Z]); - bindKeys(Control.BACK, [H, X]); - bindKeys(Control.PAUSE, [ONE]); - bindKeys(Control.RESET, [R]); - case Duo(false): - bindKeys(Control.UI_UP, [FlxKey.UP]); - bindKeys(Control.UI_DOWN, [FlxKey.DOWN]); - bindKeys(Control.UI_LEFT, [FlxKey.LEFT]); - bindKeys(Control.UI_RIGHT, [FlxKey.RIGHT]); - bindKeys(Control.NOTE_UP, [FlxKey.UP]); - bindKeys(Control.NOTE_DOWN, [FlxKey.DOWN]); - bindKeys(Control.NOTE_LEFT, [FlxKey.LEFT]); - bindKeys(Control.NOTE_RIGHT, [FlxKey.RIGHT]); - bindKeys(Control.ACCEPT, [O]); - bindKeys(Control.BACK, [P]); - bindKeys(Control.PAUSE, [ENTER]); - bindKeys(Control.RESET, [BACKSPACE]); - case None: // nothing - case Custom: // nothing - } - #end + public function loadKeyBinds() + { + + //trace(FlxKey.fromString(FlxG.save.data.upBind)); + + removeKeyboard(); + KeyBinds.keyCheck(); + + inline bindKeys(Control.UP, [FlxKey.fromString(FlxG.save.data.upBind), FlxKey.UP]); + inline bindKeys(Control.DOWN, [FlxKey.fromString(FlxG.save.data.downBind), FlxKey.DOWN]); + inline bindKeys(Control.LEFT, [FlxKey.fromString(FlxG.save.data.leftBind), FlxKey.LEFT]); + inline bindKeys(Control.RIGHT, [FlxKey.fromString(FlxG.save.data.rightBind), FlxKey.RIGHT]); + inline bindKeys(Control.ACCEPT, [Z, SPACE, ENTER]); + inline bindKeys(Control.BACK, [BACKSPACE, ESCAPE]); + inline bindKeys(Control.PAUSE, [P, ENTER, ESCAPE]); + inline bindKeys(Control.RESET, [FlxKey.fromString(FlxG.save.data.killBind)]); } function removeKeyboard() @@ -975,34 +1435,28 @@ class Controls extends FlxActionSet { #if !switch addGamepadLiteral(id, [ - Control.ACCEPT => [A, START], + Control.ACCEPT => [A], Control.BACK => [B], - Control.UI_UP => [DPAD_UP, LEFT_STICK_DIGITAL_UP], - Control.UI_DOWN => [DPAD_DOWN, LEFT_STICK_DIGITAL_DOWN], - Control.UI_LEFT => [DPAD_LEFT, LEFT_STICK_DIGITAL_LEFT], - Control.UI_RIGHT => [DPAD_RIGHT, LEFT_STICK_DIGITAL_RIGHT], - Control.NOTE_UP => [DPAD_UP, LEFT_STICK_DIGITAL_UP, RIGHT_STICK_DIGITAL_UP, Y], - Control.NOTE_DOWN => [DPAD_DOWN, LEFT_STICK_DIGITAL_DOWN, RIGHT_STICK_DIGITAL_DOWN, A], - Control.NOTE_LEFT => [DPAD_LEFT, LEFT_STICK_DIGITAL_LEFT, RIGHT_STICK_DIGITAL_LEFT, X], - Control.NOTE_RIGHT => [DPAD_RIGHT, LEFT_STICK_DIGITAL_RIGHT, RIGHT_STICK_DIGITAL_RIGHT, B], + Control.UP => [DPAD_UP, LEFT_STICK_DIGITAL_UP], + Control.DOWN => [DPAD_DOWN, LEFT_STICK_DIGITAL_DOWN], + Control.LEFT => [DPAD_LEFT, LEFT_STICK_DIGITAL_LEFT], + Control.RIGHT => [DPAD_RIGHT, LEFT_STICK_DIGITAL_RIGHT], Control.PAUSE => [START], - Control.RESET => [8] + Control.RESET => [Y] ]); #else addGamepadLiteral(id, [ //Swap A and B for switch - Control.ACCEPT => [B, START], + Control.ACCEPT => [B], Control.BACK => [A], - Control.UI_UP => [DPAD_UP, LEFT_STICK_DIGITAL_UP, RIGHT_STICK_DIGITAL_UP], - Control.UI_DOWN => [DPAD_DOWN, LEFT_STICK_DIGITAL_DOWN, RIGHT_STICK_DIGITAL_DOWN], - Control.UI_LEFT => [DPAD_LEFT, LEFT_STICK_DIGITAL_LEFT, RIGHT_STICK_DIGITAL_LEFT], - Control.UI_RIGHT => [DPAD_RIGHT, LEFT_STICK_DIGITAL_RIGHT, RIGHT_STICK_DIGITAL_RIGHT], - Control.NOTE_UP => [DPAD_UP, LEFT_STICK_DIGITAL_UP, RIGHT_STICK_DIGITAL_UP, X], - Control.NOTE_DOWN => [DPAD_DOWN, LEFT_STICK_DIGITAL_DOWN, RIGHT_STICK_DIGITAL_DOWN, B], - Control.NOTE_LEFT => [DPAD_LEFT, LEFT_STICK_DIGITAL_LEFT, RIGHT_STICK_DIGITAL_LEFT, Y], - Control.NOTE_RIGHT => [DPAD_RIGHT, LEFT_STICK_DIGITAL_RIGHT, RIGHT_STICK_DIGITAL_RIGHT, A], + Control.UP => [DPAD_UP, LEFT_STICK_DIGITAL_UP, RIGHT_STICK_DIGITAL_UP], + Control.DOWN => [DPAD_DOWN, LEFT_STICK_DIGITAL_DOWN, RIGHT_STICK_DIGITAL_DOWN], + Control.LEFT => [DPAD_LEFT, LEFT_STICK_DIGITAL_LEFT, RIGHT_STICK_DIGITAL_LEFT], + Control.RIGHT => [DPAD_RIGHT, LEFT_STICK_DIGITAL_RIGHT, RIGHT_STICK_DIGITAL_RIGHT], Control.PAUSE => [START], - Control.RESET => [8], + //Swap Y and X for switch + Control.RESET => [Y], + Control.CHEAT => [X] ]); #end } @@ -1097,4 +1551,4 @@ class Controls extends FlxActionSet { return input.device == GAMEPAD && (deviceID == FlxInputDeviceID.ALL || input.deviceID == deviceID); } -} \ No newline at end of file +} diff --git a/source/ControlsSubState.hx b/source/ControlsSubState.hx new file mode 100644 index 000000000..f35d74cc8 --- /dev/null +++ b/source/ControlsSubState.hx @@ -0,0 +1,12 @@ +package; + +import flixel.FlxSprite; +import flixel.FlxSubState; + +class ControlsSubState extends FlxSubState +{ + public function new() + { + super(); + } +} diff --git a/source/ConvertScore.hx b/source/ConvertScore.hx new file mode 100644 index 000000000..9eba969fe --- /dev/null +++ b/source/ConvertScore.hx @@ -0,0 +1,21 @@ +class ConvertScore +{ + public static function convertScore(noteDiff:Float):Int + { + var daRating:String = Ratings.CalculateRating(noteDiff, 166); + + switch(daRating) + { + case 'shit': + return -300; + case 'bad': + return 0; + case 'good': + return 200; + case 'sick': + return 350; + } + return 0; + } + +} \ No newline at end of file diff --git a/source/CoolUtil.hx b/source/CoolUtil.hx index 23c5d7662..0c3da9f4c 100644 --- a/source/CoolUtil.hx +++ b/source/CoolUtil.hx @@ -1,21 +1,28 @@ package; +import flash.display.BitmapData; +import lime.utils.Assets; +import tjson.TJSON; +import lime.app.Application; +import openfl.display.BitmapData; +#if sys +import sys.io.File; +import sys.FileSystem; +#end + import flixel.FlxG; import openfl.utils.Assets; -import lime.utils.Assets as LimeAssets; import lime.utils.AssetLibrary; import lime.utils.AssetManifest; -#if sys -import sys.io.File; -import sys.FileSystem; -#else import openfl.utils.Assets; -#end using StringTools; class CoolUtil { + public static var difficultyArray:Array = ['Easy', "Normal", "Hard", "Neonight", "Vitor0502", ""]; + public static var guestArray:Array = ['Snow The Fox', "spres", 'AjTheFunky', "LiterallyNoOne", 'Lylace', 'Tactical Cupcakes', 'Chxwy', 'Mewrk']; + public static var defaultDifficulties:Array = [ 'Easy', 'Normal', @@ -41,20 +48,43 @@ class CoolUtil return Paths.formatToSongPath(fileSuffix); } - public static function difficultyString():String + public static function difficultyString2():String { return difficulties[PlayState.storyDifficulty].toUpperCase(); } - inline public static function boundTo(value:Float, min:Float, max:Float):Float { - return Math.max(min, Math.min(max, value)); + public static function difficultyString():String + { + var guestNumber:Int = 0; + + if (PlayState.storyDifficulty == 5) + { + switch (PlayState.SONG.song.toLowerCase()) + { + case 'epiphany' | 'bonedoggle': guestNumber = 0; + case "rabbit's-luck": guestNumber = 1; + case "arch": guestNumber = 2; + case 'ghost-vip': guestNumber = 3; + case 'you-cant-run': guestNumber = 4; + case "its-complicated": guestNumber = 5; + case "buildstroll": guestNumber = 6; + case 'ballistic': guestNumber = 7; + } + + return guestArray[guestNumber]; + } + else + return difficultyArray[PlayState.storyDifficulty]; } public static function coolTextFile(path:String):Array { var daList:Array = []; - + #if sys if(FileSystem.exists(path)) daList = File.getContent(path).trim().split('\n'); + #else + if(Assets.exists(path)) daList = Assets.getText(path).trim().split('\n'); + #end for (i in 0...daList.length) { @@ -63,18 +93,11 @@ class CoolUtil return daList; } - public static function listFromString(string:String):Array - { - var daList:Array = []; - daList = string.trim().split('\n'); - for (i in 0...daList.length) - { - daList[i] = daList[i].trim(); - } - - return daList; + inline public static function boundTo(value:Float, min:Float, max:Float):Float { + return Math.max(min, Math.min(max, value)); } + public static function dominantColor(sprite:flixel.FlxSprite):Int{ var countByColor:Map = []; for(col in 0...sprite.frameWidth){ @@ -101,6 +124,30 @@ class CoolUtil return maxKey; } + public static function coolTextFile2(path:String):Array + { + var daList:Array = File.getContent(path).trim().split('\n'); + + for (i in 0...daList.length) + { + daList[i] = daList[i].trim(); + } + + return daList; + } + + public static function coolStringFile(path:String):Array + { + var daList:Array = 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 = []; @@ -111,18 +158,9 @@ class CoolUtil return dumbArray; } - //uhhhh does this even work at all? i'm starting to doubt - public static function precacheSound(sound:String, ?library:String = null):Void { - if(!Assets.cache.hasSound(Paths.sound(sound, library))) { - FlxG.sound.cache(Paths.sound(sound, library)); - } - } + public static function parseJson(json:String):Dynamic { + // the reason we do this is to make it easy to swap out json parsers - public static function browserLoad(site:String) { - #if linux - Sys.command('/usr/bin/xdg-open', [site]); - #else - FlxG.openURL(site); - #end + return TJSON.parse(json); } } diff --git a/source/CreditsState.hx b/source/CreditsState.hx index 97128ece7..945de47ca 100644 --- a/source/CreditsState.hx +++ b/source/CreditsState.hx @@ -42,7 +42,8 @@ class CreditsState extends MusicBeatState bg = new FlxSprite().loadGraphic(Paths.image('menuDesat')); add(bg); - + bg.screenCenter(); + grpOptions = new FlxTypedGroup(); add(grpOptions); @@ -62,17 +63,28 @@ class CreditsState extends MusicBeatState } creditsStuff.push(['']); } - } + }; + var folder = ""; + var creditsFile:String = Paths.mods('data/credits.txt'); + if (FileSystem.exists(creditsFile)) + { + var firstarray:Array = File.getContent(creditsFile).split('\n'); + for(i in firstarray) + { + var arr:Array = i.replace('\\n', '\n').split("::"); + if(arr.length >= 5) arr.push(folder); + creditsStuff.push(arr); + } + creditsStuff.push(['']); + } #end var pisspoop:Array> = [ //Name - Icon name - Description - Link - BG Color - ['Psych Engine Android'], - ['M.A. Jigsaw', 'majigsaw', 'Main Coder of The Port', 'https://www.youtube.com/channel/UC2Sk7vtPzOvbVzdVTWrribQ', 'F73838'], - ['Sirox', 'sirox', 'Fixed a lot of shit, added videoBG, help with editors', 'https://www.youtube.com/channel/UCqp6FttWJlp67vHT8n-_uKw', '261EA9'], - ['ELfox', 'elfox', 'Created The Method To Port Modding Features', 'https://t.me/ELfox513', '53E52C'], + ['Psych Engine Extra Keys'], + ['tposejank', 'unknown', 'Main programmer of ~~the keys~~', 'https://twitter.com/tpose_jank', '000000'], [''], ['Psych Engine Team'], - ['Shadow Mario', 'shadowmario', 'Main Programmer of Psych Engine', 'https://twitter.com/Shadow_Mario_', 'FFDD33'], + ['Shadow Mario', 'shadowmario', 'Main Programmer of Psych Engine', 'https://twitter.com/Shadow_Mario_', '444444'], ['RiverOaken', 'riveroaken', 'Main Artist/Animator of Psych Engine', 'https://twitter.com/river_oaken', 'C30085'], ['bb-panzu', 'bb-panzu', 'Additional Programmer of Psych Engine', 'https://twitter.com/bbsub3', '389A58'], [''], @@ -82,6 +94,8 @@ class CreditsState extends MusicBeatState ['iFlicky', 'iflicky', 'Delay/Combo Menu Song Composer\nand Dialogue Sounds', 'https://twitter.com/flicky_i', 'C549DB'], ['PolybiusProxy', 'polybiusproxy', '.MP4 Video Loader Extension', 'https://twitter.com/polybiusproxy', 'FFEAA6'], ['Keoiki', 'keoiki', 'Note Splash Animations', 'https://twitter.com/Keoiki_', 'FFFFFF'], + ['Smokey', 'smokey', 'Spritemap Texture Support', 'https://twitter.com/Smokey_5_', '0033CC'], + [''], [''], ["Funkin' Crew"], ['ninjamuffin99', 'ninjamuffin99', "Programmer of Friday Night Funkin'", 'https://twitter.com/ninja_muffin99', 'F73838'], @@ -137,11 +151,6 @@ class CreditsState extends MusicBeatState bg.color = getCurrentBGColor(); intendedColor = bg.color; changeSelection(); - - #if mobileC - addVirtualPad(UP_DOWN, A_B); - #end - super.create(); } diff --git a/source/CustomFadeTransition.hx b/source/CustomFadeTransition.hx index 6351faee1..60e0221db 100644 --- a/source/CustomFadeTransition.hx +++ b/source/CustomFadeTransition.hx @@ -82,11 +82,6 @@ class CustomFadeTransition extends MusicBeatSubstate { override function destroy() { if(leTween != null) { - #if MODS_ALLOWED - if(isTransIn) { - Paths.destroyLoadedImages(); - } - #end finishCallback(); leTween.cancel(); } diff --git a/source/CustomLoading.hx b/source/CustomLoading.hx new file mode 100644 index 000000000..5da3a605f --- /dev/null +++ b/source/CustomLoading.hx @@ -0,0 +1,214 @@ +package; + +import lime.app.Application; +#if windows +import Discord.DiscordClient; +#end +import openfl.display.BitmapData; +import openfl.utils.Assets; +import flixel.ui.FlxBar; +import haxe.Exception; +import flixel.tweens.FlxEase; +import flixel.tweens.FlxTween; +import sys.FileSystem; +import sys.io.File; +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.addons.transition.FlxTransitionSprite.GraphicTransTileDiamond; +import flixel.addons.transition.FlxTransitionableState; +import flixel.addons.transition.TransitionData; +import flixel.graphics.FlxGraphic; +import flixel.graphics.frames.FlxAtlasFrames; +import flixel.math.FlxPoint; +import flixel.math.FlxRect; +import flixel.util.FlxColor; +import flixel.util.FlxTimer; +import flixel.text.FlxText; + + + +using StringTools; + +//haven't started this yet +class CustomLoading extends MusicBeatState +{ + var toBeDone = 0; + var done = 0; + + var loaded = false; + + var text:FlxText; + var kadeLogo:FlxSprite; + + public static var bitmapData:Map; + + var images = []; + var music = []; + var charts = []; + var character:Character; + var iconP1:HealthIcon; + var stage:PreloadStage; + var suf:String = ''; + var bar:FlxBar; + + var bg:FlxSprite; + + override function create() + { + FlxG.mouse.visible = false; + + FlxG.worldBounds.set(0,0); + + bg = new FlxSprite().loadGraphic(Paths.image('menuBGTemplate2')); + bg.color = FlxG.random.color(); + add(bg); + + var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase(); + switch (songLowercase) { + case 'dad-battle': songLowercase = 'dadbattle'; + case 'philly-nice': songLowercase = 'philly'; + case 'scary-swings': songLowercase = 'scary swings'; + case 'my-sweets': songLowercase = 'my sweets'; + } + + PlayState.customLoaded = true; + + // the suffixes. will add more later + if (PlayState.isBETADCIU && FileSystem.exists(Paths.lua(songLowercase + "/modchart-betadciu"))) + suf = '-betadciu'; + + if (PlayState.isNeonight) + { + if (!FlxG.save.data.stageChange) + suf = '-neo-noStage'; + else + suf = '-neo'; + } + + if (PlayState.isVitor) + suf = '-vitor'; + + if (PlayState.isBETADCIU && PlayState.storyDifficulty == 5) + { + if (!FlxG.save.data.stageChange && FileSystem.exists(Paths.lua(PlayState.SONG.song.toLowerCase() + "/modchart-guest-noStage"))) + suf = '-guest-noStage'; + else + suf = '-guest'; + } + + text = new FlxText(25, FlxG.height / 2 + 275,0,"Loading "+ PlayState.SONG.song + " BETADCIU..."); + text.size = 48; + text.alignment = FlxTextAlign.LEFT; + text.borderColor = FlxColor.BLACK; + text.borderSize = 4; + text.borderStyle = FlxTextBorderStyle.OUTLINE; + + kadeLogo = new FlxSprite(FlxG.width / 2, FlxG.height / 2).loadGraphic(Paths.image('KadeEngineLogo')); + kadeLogo.x -= kadeLogo.width / 2 - 200; + kadeLogo.y -= kadeLogo.height / 2 + 100; + kadeLogo.setGraphicSize(Std.int(kadeLogo.width * 0.8)); + kadeLogo.x += 100; + + // kadeLogo.alpha = 0; + + //trace("caching music..."); + + toBeDone = 0; + + if (FileSystem.exists(Paths.txt(songLowercase + "/preload" + suf))) + { + var characters:Array = CoolUtil.coolTextFile2(Paths.txt(songLowercase + "/preload" + suf)); + toBeDone += characters.length; + } + + if (FileSystem.exists(Paths.txt(songLowercase + "/preload-stage" + suf))) + { + var characters:Array = CoolUtil.coolTextFile2(Paths.txt(songLowercase + "/preload-stage" + suf)); + toBeDone += characters.length; + } + + + add(kadeLogo); + add(text); + + new FlxTimer().start(2, function(tmr:FlxTimer) + { + cache(); + }); + + trace('starting caching..'); + + // update thread + + sys.thread.Thread.create(() -> { + // + }); + + // cache thread + + super.create(); + } + + var calledDone = false; + + override function update(elapsed) + { + super.update(elapsed); + + if (FlxG.keys.justPressed.ESCAPE) + LoadingState.loadAndSwitchState(new PlayState()); + } + + + function cache() + { + var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase(); + switch (songLowercase) { + case 'dad-battle': songLowercase = 'dadbattle'; + case 'philly-nice': songLowercase = 'philly'; + case 'scary-swings': songLowercase = 'scary swings'; + case 'my-sweets': songLowercase = 'my sweets'; + } + + if (FileSystem.exists(Paths.txt(songLowercase + "/preload" + suf))) + { + var characters:Array = CoolUtil.coolTextFile2(Paths.txt(songLowercase + "/preload" + suf)); + for (i in 0...characters.length) + { + var data:Array = characters[i].split(' '); + character = new Character (0, 0, data[0]); + + var luaFile:String = 'images/characters/luas/' + data[0]; + + if (FileSystem.exists(Paths.modFolders('characters/'+data[0]+'.lua')) || FileSystem.exists(FileSystem.absolutePath("assets/shared/"+luaFile+'.lua')) || FileSystem.exists(Paths.lua2(luaFile))) + PlayState.startCharLuas.push(data[0]); + + trace ('found ' + data[0]); + done++; + } + } + + if (FileSystem.exists(Paths.txt(songLowercase + "/preload-stage"+suf)) && FlxG.save.data.stageChange) + { + var characters:Array = CoolUtil.coolTextFile2(Paths.txt(songLowercase + "/preload-stage"+suf)); + + for (i in 0...characters.length) + { + var data:Array = characters[i].split(' '); + stage = new PreloadStage(data[0], true); + trace ('stages are ' + data[0]); + } + + PlayState.curStage = PlayState.SONG.stage; + } + + Assets.cache.clear("shared:assets/shared/images/characters/jsons"); //it doesn't take that much time to read from the json anyway. + + trace("Finished caching..."); + + loaded = true; + + LoadingState.loadAndSwitchState(new PlayState()); + } + +} \ No newline at end of file diff --git a/source/DeltaTrail.hx b/source/DeltaTrail.hx new file mode 100644 index 000000000..e24ac374b --- /dev/null +++ b/source/DeltaTrail.hx @@ -0,0 +1,129 @@ +package; + +import flixel.addons.effects.FlxTrail; +import flixel.animation.FlxAnimation; +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.group.FlxGroup; +import flixel.group.FlxSpriteGroup; +import flixel.system.FlxAssets; +import flixel.util.FlxArrayUtil; +import flixel.util.FlxDestroyUtil; +import flixel.math.FlxPoint; + +/** + * FlxTrail but it uses delta time. + * @author Rozebud :] + */ +class DeltaTrail extends FlxTrail +{ + + var _timer:Float = 0; + var timerMax:Float; + + public function new(Target:FlxSprite, ?Graphic:FlxGraphicAsset, Length:Int = 10, Delay:Float = 3 / 60, Alpha:Float = 0.4, Diff:Float = 0.05):Void + { + super(Target, Graphic, Length, 0, Alpha, Diff); + timerMax = Delay; + } + + override public function update(elapsed:Float):Void + { + // Count the frames + _timer += elapsed; + + // Update the trail in case the intervall and there actually is one. + if (_timer >= timerMax && _trailLength >= 1) + { + _timer = 0; + + // Push the current position into the positons array and drop one. + var spritePosition:FlxPoint = null; + if (_recentPositions.length == _trailLength) + { + spritePosition = _recentPositions.pop(); + } + else + { + spritePosition = FlxPoint.get(); + } + + if (target.exists) + { + spritePosition.set(target.x - target.offset.x, target.y - target.offset.y); + _recentPositions.unshift(spritePosition); + + // Also do the same thing for the Sprites angle if rotationsEnabled + if (rotationsEnabled) + { + cacheValue(_recentAngles, target.angle); + } + + // Again the same thing for Sprites scales if scalesEnabled + if (scalesEnabled) + { + var spriteScale:FlxPoint = null; // sprite.scale; + if (_recentScales.length == _trailLength) + { + spriteScale = _recentScales.pop(); + } + else + { + spriteScale = FlxPoint.get(); + } + + spriteScale.set(target.scale.x, target.scale.y); + _recentScales.unshift(spriteScale); + } + + // Again the same thing for Sprites frames if framesEnabled + if (framesEnabled && _graphic == null) + { + cacheValue(_recentFrames, target.animation.frameIndex); + cacheValue(_recentFlipX, target.flipX); + cacheValue(_recentFlipY, target.flipY); + cacheValue(_recentAnimations, target.animation.curAnim); + } + + // Now we need to update the all the Trailsprites' values + var trailSprite:FlxSprite; + + for (i in 0..._recentPositions.length) + { + trailSprite = members[i]; + trailSprite.x = _recentPositions[i].x; + trailSprite.y = _recentPositions[i].y; + + // And the angle... + if (rotationsEnabled) + { + trailSprite.angle = _recentAngles[i]; + trailSprite.origin.x = _spriteOrigin.x; + trailSprite.origin.y = _spriteOrigin.y; + } + + // the scale... + if (scalesEnabled) + { + trailSprite.scale.x = _recentScales[i].x; + trailSprite.scale.y = _recentScales[i].y; + } + + // and frame... + if (framesEnabled && _graphic == null) + { + trailSprite.animation.frameIndex = _recentFrames[i]; + trailSprite.flipX = _recentFlipX[i]; + trailSprite.flipY = _recentFlipY[i]; + + trailSprite.animation.curAnim = _recentAnimations[i]; + } + + // Is the trailsprite even visible? + trailSprite.exists = true; + } + } + } + //super.update(elapsed); + } +} diff --git a/source/DialogueBox.hx b/source/DialogueBox.hx index 3bddd4369..68277a251 100644 --- a/source/DialogueBox.hx +++ b/source/DialogueBox.hx @@ -10,43 +10,80 @@ import flixel.text.FlxText; import flixel.util.FlxColor; import flixel.util.FlxTimer; +#if windows +import Sys; +import sys.FileSystem; +import sys.io.File; +#end + +//from senpai and tankman mod. old system was messy but didn't want to use psych's dialogue system since well... this engine is for BETADCIUs not story stuff. + using StringTools; class DialogueBox extends FlxSpriteGroup { var box:FlxSprite; + var animName:String; + var realCharacter:String; - var curCharacter:String = ''; + public static var curCharacter:String = ''; + public static var oldCharacter:String = ''; var dialogue:Alphabet; var dialogueList:Array = []; // SECOND DIALOGUE FOR THE PIXEL SHIT INSTEAD??? var swagDialogue:FlxTypeText; + public static var detectDialogue:FlxText; //for those switch character commands var dropText:FlxText; public var finishThing:Void->Void; - public var nextDialogueThing:Void->Void = null; - public var skipDialogueThing:Void->Void = null; var portraitLeft:FlxSprite; var portraitRight:FlxSprite; + var portraitLeftPixel:FlxSprite; + var portraitRightPixel:FlxSprite; + var isPixelBox:Bool; + var tex:FlxAtlasFrames; var handSelect:FlxSprite; var bgFade:FlxSprite; + public static var curEmotion:String = 'normal'; + public static var emotion:String = ''; + public static var oldEmotion:String = ''; + public static var isLeft:Bool = false; + public static var isRight:Bool = false; + public static var isLeftPixel:Bool = false; + public static var isRightPixel:Bool = false; + var curFlip:String = 'false'; + var canFlip:Bool = false; + public function new(talkingRight:Bool = true, ?dialogueList:Array) { super(); + isPixelBox = false; + canFlip = false; + isLeft = false; + isRight = false; + isLeftPixel = false; + isRightPixel = false; + switch (PlayState.SONG.song.toLowerCase()) { - case 'senpai': - FlxG.sound.playMusic(Paths.music('Lunchbox'), 0); + case 'senpai-medley' | 'high-school-conflict' | 'monika': + FlxG.sound.playMusic(Paths.music('Lunchbox', 'week6'), 0); FlxG.sound.music.fadeIn(1, 0, 0.8); case 'thorns': - FlxG.sound.playMusic(Paths.music('LunchboxScary'), 0); + FlxG.sound.playMusic(Paths.music('LunchboxScary', 'week6'), 0); + FlxG.sound.music.fadeIn(1, 0, 0.8); + case 'fading-senpai': + FlxG.sound.playMusic(Paths.music('city_ambience'), 0); + FlxG.sound.music.fadeIn(1, 0, 0.8); + case 'whittyvssarv' | 'gun-buddies': + FlxG.sound.playMusic(Paths.music('gunsDialogue'), 0); FlxG.sound.music.fadeIn(1, 0, 0.8); } @@ -67,28 +104,67 @@ class DialogueBox extends FlxSpriteGroup var hasDialog = false; switch (PlayState.SONG.song.toLowerCase()) { - case 'senpai': + case 'senpai-medley': hasDialog = true; + isPixelBox = true; + FlxG.sound.play(Paths.sound('HAPPY_TEXT_BOX')); box.frames = Paths.getSparrowAtlas('weeb/pixelUI/dialogueBox-pixel'); box.animation.addByPrefix('normalOpen', 'Text Box Appear', 24, false); - box.animation.addByIndices('normal', 'Text Box Appear instance 1', [4], "", 24); - case 'roses': + box.animation.addByIndices('normal', 'Text Box Appear', [4], "", 24); + case 'your-reality' | 'monika': hasDialog = true; + isPixelBox = true; + box.frames = Paths.getSparrowAtlas('weeb/pixelUI/dialogueBox-pixel'); + box.animation.addByPrefix('normalOpen', 'Text Box Appear', 24, false); + box.animation.addByIndices('normal', 'Text Box Appear', [4], "", 24); + case 'high-school-conflict' | 'bara-no-yume' | 'shinkyoku' | 'your-demise' | 'roots': + hasDialog = true; + isPixelBox = true; + box.frames = Paths.getSparrowAtlas('weeb/pixelUI/dialogueBox-monika'); + box.animation.addByPrefix('normalOpen', 'Text Box Appear', 24, false); + box.animation.addByIndices('normal', 'Text Box Appear', [4], "", 24); + if (PlayState.SONG.song.toLowerCase() == 'shinkyoku' || PlayState.SONG.song.toLowerCase() == 'bara-no-yume') + FlxG.sound.play(Paths.sound('ANGRY_TEXT_BOX')); + case 'ugh': + hasDialog = true; + isPixelBox = true; FlxG.sound.play(Paths.sound('ANGRY_TEXT_BOX')); box.frames = Paths.getSparrowAtlas('weeb/pixelUI/dialogueBox-senpaiMad'); box.animation.addByPrefix('normalOpen', 'SENPAI ANGRY IMPACT SPEECH', 24, false); - box.animation.addByIndices('normal', 'SENPAI ANGRY IMPACT SPEECH instance 1', [4], "", 24); + box.animation.addByIndices('normal', 'SENPAI ANGRY IMPACT SPEECH', [4], "", 24); case 'thorns': hasDialog = true; + isPixelBox = true; box.frames = Paths.getSparrowAtlas('weeb/pixelUI/dialogueBox-evil'); box.animation.addByPrefix('normalOpen', 'Spirit Textbox spawn', 24, false); - box.animation.addByIndices('normal', 'Spirit Textbox spawn instance 1', [11], "", 24); + box.animation.addByIndices('normal', 'Spirit Textbox spawn', [11], "", 24); var face:FlxSprite = new FlxSprite(320, 170).loadGraphic(Paths.image('weeb/spiritFaceForward')); face.setGraphicSize(Std.int(face.width * 6)); add(face); + case 'fading-senpai' | 'keep-going' | 'ectospasm' | 'checking': + hasDialog = true; + isPixelBox = true; + box.frames = Paths.getSparrowAtlas('garBox'); + box.animation.addByPrefix('normalOpen', 'Spirit Textbox spawn', 24, false); + box.animation.addByIndices('normal', 'Spirit Textbox spawn', [11], "", 24); + if (PlayState.SONG.song.toLowerCase() == 'checking') + FlxG.sound.play(Paths.sound('ANGRY_TEXT_BOX')); + default: + hasDialog = true; + canFlip = true; + box.frames = Paths.getSparrowAtlas('speech_bubble_talking'); + box.animation.addByPrefix('normalOpen', 'Speech Bubble Normal Open', 24, false); + box.animation.addByPrefix('normal', 'speech bubble normal', 24, true); + } + + if (!isPixelBox) + { + box.y += 320; + box.x += 500; + box.antialiasing = true; } this.dialogueList = dialogueList; @@ -96,38 +172,72 @@ class DialogueBox extends FlxSpriteGroup if (!hasDialog) return; - portraitLeft = new FlxSprite(-20, 40); - portraitLeft.frames = Paths.getSparrowAtlas('weeb/senpaiPortrait'); - portraitLeft.animation.addByPrefix('enter', 'Senpai Portrait Enter', 24, false); - portraitLeft.setGraphicSize(Std.int(portraitLeft.width * PlayState.daPixelZoom * 0.9)); - portraitLeft.updateHitbox(); + portraitLeftPixel = new FlxSprite(-20, 40); + portraitLeftPixel.frames = Paths.getSparrowAtlas('dialogue/senpaiPort'); + portraitLeftPixel.animation.addByPrefix('normal', 'normal', 24, false); + portraitLeftPixel.setGraphicSize(Std.int(portraitLeftPixel.width * PlayState.daPixelZoom * 0.9)); + portraitLeftPixel.updateHitbox(); + portraitLeftPixel.scrollFactor.set(); + add(portraitLeftPixel); + portraitLeftPixel.visible = false; + + portraitRightPixel = new FlxSprite(0, 40); + portraitRightPixel.frames = Paths.getSparrowAtlas('dialogue/bfPixelPort'); + portraitRightPixel.animation.addByPrefix('normal', 'normal', 24, false); + portraitRightPixel.setGraphicSize(Std.int(portraitRightPixel.width * PlayState.daPixelZoom * 0.9)); + portraitRightPixel.updateHitbox(); + portraitRightPixel.scrollFactor.set(); + add(portraitRightPixel); + portraitRightPixel.visible = false; + + portraitLeft = new FlxSprite(-40, 20); + portraitLeft.frames = Paths.getSparrowAtlas('dialogue/picoPort'); + portraitLeft.animation.addByPrefix('normal', 'normal', 24, false); portraitLeft.scrollFactor.set(); + portraitLeft.antialiasing = true; add(portraitLeft); portraitLeft.visible = false; - portraitRight = new FlxSprite(0, 40); - portraitRight.frames = Paths.getSparrowAtlas('weeb/bfPortrait'); - portraitRight.animation.addByPrefix('enter', 'Boyfriend portrait enter', 24, false); - portraitRight.setGraphicSize(Std.int(portraitRight.width * PlayState.daPixelZoom * 0.9)); - portraitRight.updateHitbox(); + portraitRight = new FlxSprite(-60, 20); + portraitRight.frames = Paths.getSparrowAtlas('dialogue/tankmanPort'); + portraitRight.animation.addByPrefix('normal', 'normal', 24, false); portraitRight.scrollFactor.set(); + portraitRight.antialiasing = true; add(portraitRight); portraitRight.visible = false; box.animation.play('normalOpen'); - box.setGraphicSize(Std.int(box.width * PlayState.daPixelZoom * 0.9)); + if (isPixelBox) + { + box.setGraphicSize(Std.int(box.width * PlayState.daPixelZoom * 0.9)); + } box.updateHitbox(); add(box); box.screenCenter(X); - portraitLeft.screenCenter(X); + if (PlayState.curStage.contains('school') || PlayState.curStage.contains('garStage')) + { + trace('DONT MOVE IT'); + } + else + box.x += 50; + + portraitLeftPixel.screenCenter(X); + + var imagePath:Array; - handSelect = new FlxSprite(1042, 590).loadGraphic(Paths.getPath('images/weeb/pixelUI/hand_textbox.png', IMAGE)); - handSelect.setGraphicSize(Std.int(handSelect.width * PlayState.daPixelZoom * 0.9)); - handSelect.updateHitbox(); - handSelect.visible = false; + switch (PlayState.SONG.song.toLowerCase()) + { + case 'fading-senpai' | 'keep-going' | 'ectospasm' | 'checking': + imagePath = ['garcello/hand_textbox', '']; + default: + imagePath = ['weeb/pixelUI/hand_textbox', 'week6']; + } + handSelect = new FlxSprite(FlxG.width * 0.9, FlxG.height * 0.9).loadGraphic(Paths.image(imagePath[0])); add(handSelect); + if (imagePath[0] != 'weeb/pixelUI/hand_textbox') + handSelect.antialiasing = true; if (!talkingRight) { @@ -139,6 +249,11 @@ class DialogueBox extends FlxSpriteGroup dropText.color = 0xFFD89494; add(dropText); + detectDialogue = new FlxText(242, 502, Std.int(FlxG.width * 0.6), "", 32); + detectDialogue.font = 'Pixel Arial 11 Bold'; + detectDialogue.color = 0xFFD89494; + detectDialogue.alpha = 0; + swagDialogue = new FlxTypeText(240, 500, Std.int(FlxG.width * 0.6), "", 32); swagDialogue.font = 'Pixel Arial 11 Bold'; swagDialogue.color = 0xFF3F2021; @@ -152,22 +267,30 @@ class DialogueBox extends FlxSpriteGroup var dialogueOpened:Bool = false; var dialogueStarted:Bool = false; - var dialogueEnded:Bool = false; override function update(elapsed:Float) { + detectDialogue.text = dialogueList[0]; + // HARD CODING CUZ IM STUPDI - if (PlayState.SONG.song.toLowerCase() == 'roses') - portraitLeft.visible = false; - if (PlayState.SONG.song.toLowerCase() == 'thorns') + switch (PlayState.SONG.song.toLowerCase()) { - portraitLeft.visible = false; - swagDialogue.color = FlxColor.WHITE; - dropText.color = FlxColor.BLACK; + case 'roses' | 'ugh': + portraitLeftPixel.visible = false; + case 'thorns': + portraitLeftPixel.color = FlxColor.BLACK; + swagDialogue.color = FlxColor.WHITE; + dropText.color = FlxColor.BLACK; + case 'keep-going': + swagDialogue.color = FlxColor.WHITE; + dropText.color = FlxColor.BLACK; + case 'fading-senpai' | 'checking' | 'ectospasm': + swagDialogue.color = 0xFF0DF07E; + dropText.color = FlxColor.BLACK; } dropText.text = swagDialogue.text; - + if (box.animation.curAnim != null) { if (box.animation.curAnim.name == 'normalOpen' && box.animation.curAnim.finished) @@ -183,67 +306,44 @@ class DialogueBox extends FlxSpriteGroup dialogueStarted = true; } - #if mobile - var justTouched:Bool = false; - - for (touch in FlxG.touches.list) - { - justTouched = false; - - if (touch.justPressed){ - justTouched = true; - } - } - #end - - if(PlayerSettings.player1.controls.ACCEPT#if mobile || justTouched #end) + if (FlxG.keys.justPressed.ANY && dialogueStarted == true) { - if (dialogueEnded) + remove(dialogue); + + FlxG.sound.play(Paths.sound('clickText'), 0.8); + + if (dialogueList[1] == null && dialogueList[0] != null || FlxG.keys.justPressed.ESCAPE) { - remove(dialogue); - if (dialogueList[1] == null && dialogueList[0] != null) + if (!isEnding) { - 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) { - isEnding = true; - FlxG.sound.play(Paths.sound('clickText'), 0.8); - - if (PlayState.SONG.song.toLowerCase() == 'senpai' || PlayState.SONG.song.toLowerCase() == 'thorns') - FlxG.sound.music.fadeOut(1.5, 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; - handSelect.alpha -= 1 / 5; - dropText.alpha = swagDialogue.alpha; - }, 5); - - new FlxTimer().start(1.5, function(tmr:FlxTimer) - { - finishThing(); - kill(); - }); - } - } - else - { - dialogueList.remove(dialogueList[0]); - startDialogue(); - FlxG.sound.play(Paths.sound('clickText'), 0.8); + box.alpha -= 1 / 5; + bgFade.alpha -= 1 / 5 * 0.7; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + 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 if (dialogueStarted) + else { - FlxG.sound.play(Paths.sound('clickText'), 0.8); - swagDialogue.skip(); - - if(skipDialogueThing != null) { - skipDialogueThing(); - } + dialogueList.remove(dialogueList[0]); + startDialogue(); } } @@ -252,6 +352,43 @@ class DialogueBox extends FlxSpriteGroup var isEnding:Bool = false; + function sideCheck():Void + { + var leftCharacters:Array = ['hdSenpai', 'hdSpirit', 'shaggy', 'pico', 'botan', 'blantad', '016', 'selever', 'tea', 'dad']; + var rightCharacters:Array = ['aloe', 'nene', 'tankman', 'gf', 'fever']; + var leftPixelCharacters:Array = ['monika', 'senpai']; + var rightPixelCharacters:Array = ['bfPixel', 'tankmanPixel']; + + if (leftCharacters.contains(curCharacter)) + { + isLeft = true; + isRight = false; + isLeftPixel = false; + isRightPixel = false; + } + if (rightCharacters.contains(curCharacter)) + { + isLeft = false; + isRight = true; + isLeftPixel = false; + isRightPixel = false; + } + if (leftPixelCharacters.contains(curCharacter)) + { + isLeft = false; + isRight = false; + isLeftPixel = true; + isRightPixel = false; + } + if (rightPixelCharacters.contains(curCharacter)) + { + isLeft = false; + isRight = false; + isLeftPixel = false; + isRightPixel = true; + } + } + function startDialogue():Void { cleanDialog(); @@ -262,39 +399,288 @@ class DialogueBox extends FlxSpriteGroup // swagDialogue.text = ; swagDialogue.resetText(dialogueList[0]); swagDialogue.start(0.04, true); - swagDialogue.completeCallback = function() { - handSelect.visible = true; - dialogueEnded = true; - }; - - handSelect.visible = false; - dialogueEnded = false; - switch (curCharacter) + + sideCheck(); + + var portPath:String = 'dialogue/'+curCharacter+'Port'; + + if (FileSystem.exists(Paths.modsImages(portPath))) + { + if (!Paths.currentTrackedAssets.exists(portPath)) + Paths.cacheImage(portPath); + + tex = FlxAtlasFrames.fromSparrow(Paths.currentTrackedAssets.get(portPath), File.getContent(Paths.modsXml(portPath))); + } + else + tex = Paths.getSparrowAtlas(portPath); + + //da actual code + if (isLeft) { - case 'dad': - portraitRight.visible = false; - if (!portraitLeft.visible) + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + portraitRight.visible = false; + + if (canFlip) + box.flipX = true; + + if (curFlip == 'true') + { + portraitLeft.flipX = true; + if (canFlip) + box.flipX = false; + } + else + { + portraitLeft.flipX = false; + if (canFlip) + box.flipX = true; + } + + switch (curCharacter) + { + case 'pico' | 'botan': + portraitLeft.y = FlxG.height - 600; + if (curFlip == 'true') + portraitLeft.x = 725; + else + portraitLeft.x = 100; + case 'selever': + portraitLeft.y = FlxG.height - 575; + if (curFlip == 'true') + portraitLeft.x = 800; + else + portraitLeft.x = 200; + default: + portraitLeft.y = FlxG.height - 690; + if (curFlip == 'true') + portraitLeft.x = 725; + else + { + portraitLeft.x = (curCharacter != '016' ? 100 : 0); + } + } + + if (curEmotion != null) + emotion = curEmotion; + else + emotion = 'normal'; + + if (curCharacter != oldCharacter || curEmotion != oldEmotion) + { + portraitLeft.visible = true; + portraitLeft.alpha = 0; + new FlxTimer().start(0.08, function(tmr:FlxTimer) { - if (PlayState.SONG.song.toLowerCase() == 'senpai') portraitLeft.visible = true; - portraitLeft.animation.play('enter'); - } - case 'bf': - portraitLeft.visible = false; - if (!portraitRight.visible) + portraitLeft.alpha += 1 / 4; + }, 4); + portraitLeft.frames = tex; + portraitLeft.antialiasing = true; + portraitLeft.animation.addByPrefix(emotion, emotion, 24, (emotion == 'speaking' ? true : false)); + portraitLeft.animation.play(emotion); + } + + swagDialogue.completeCallback = function() + { + if (emotion == 'speaking') + portraitLeft.animation.play('normal'); + } + } + if (isRight) + { + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + portraitLeft.visible = false; + + if (canFlip) + box.flipX = false; + + if (curFlip == 'true') + { + portraitRight.flipX = true; + if (canFlip) + box.flipX = true; + } + else + { + portraitRight.flipX = false; + if (canFlip) + box.flipX = false; + } + + switch (curCharacter) + { + case 'tankman': + portraitRight.y = FlxG.height - 690; + if (curFlip == 'true') + portraitRight.x = 100; + else + portraitRight.x = 725; + default: + portraitRight.y = FlxG.height - 600; + if (curFlip == 'true') + portraitRight.x = 100; + else + portraitRight.x = (curCharacter != 'gf' ? 725 : 800); + } + + if (curEmotion != null) + emotion = curEmotion; + else + emotion = 'normal'; + + if (curCharacter != oldCharacter || curEmotion != oldEmotion) + { + portraitRight.visible = true; + portraitRight.alpha = 0; + new FlxTimer().start(0.08, function(tmr:FlxTimer) { - portraitRight.visible = true; - portraitRight.animation.play('enter'); + portraitRight.alpha += 1 / 4; + }, 4); + portraitRight.frames = tex; + portraitRight.antialiasing = true; + portraitRight.animation.addByPrefix(emotion, emotion, 24, false); + portraitRight.animation.play(emotion); + } + } + if (isLeftPixel) + { + portraitRightPixel.visible = false; + portraitRight.visible = false; + portraitLeft.visible = false; + + if (canFlip) + box.flipX = true; + + if (curFlip == 'true') + { + if (!curCharacter.contains('monika')) + portraitLeftPixel.flipX = true; + if (canFlip) + box.flipX = false; + } + else + { + portraitLeftPixel.flipX = false; + if (canFlip) + box.flipX = true; + } + + if (curEmotion != null) + emotion = curEmotion; + else + emotion = 'normal'; + + switch (curCharacter) + { + default: + portraitLeftPixel.y = (isPixelBox ? 35 : 45); + if (curFlip == 'true') + portraitLeftPixel.x = 750; + else + portraitLeftPixel.x = (isPixelBox ? 190 : 140); + } + + if (curCharacter != oldCharacter || curEmotion != oldEmotion) + { + portraitLeftPixel.visible = true; + portraitLeftPixel.alpha = 0; + new FlxTimer().start(0.08, function(tmr:FlxTimer) + { + portraitLeftPixel.alpha += 1 / 4; + }, 4); + portraitLeftPixel.frames = tex; + + if (emotion == 'speaking') + portraitLeftPixel.animation.addByPrefix('idle', 'idle', 24, false); + + portraitLeftPixel.animation.addByPrefix(emotion, emotion, 24, (emotion == 'speaking' ? true : false)); + portraitLeftPixel.animation.play(emotion); + } + + swagDialogue.completeCallback = function() + { + if (emotion == 'speaking') + { + trace('should now play idle'); + portraitLeftPixel.animation.play('idle', true); } + } } - if(nextDialogueThing != null) { - nextDialogueThing(); + if (isRightPixel) + { + portraitLeftPixel.visible = false; + portraitRight.visible = false; + portraitLeft.visible = false; + + if (canFlip) + box.flipX = true; + + if (curFlip == 'true') + { + portraitRightPixel.flipX = true; + if (canFlip) + box.flipX = false; + } + else + { + portraitRightPixel.flipX = false; + if (canFlip) + box.flipX = true; + } + + switch (curCharacter) + { + default: + portraitRightPixel.y = 35; + if (curFlip == 'true') + portraitRightPixel.x = 190; + else + portraitRightPixel.x = 750; + } + + if (curEmotion != null) + emotion = curEmotion; + else + emotion = 'normal'; + + if (curCharacter != oldCharacter || curEmotion != oldEmotion) + { + portraitRightPixel.visible = true; + portraitRightPixel.alpha = 0; + new FlxTimer().start(0.08, function(tmr:FlxTimer) + { + portraitRightPixel.alpha += 1 / 4; + }, 4); + portraitRightPixel.frames = tex; + portraitRightPixel.animation.addByPrefix(emotion, emotion, 24, false); + portraitRightPixel.animation.play(emotion); + } } } + var splitData:Array; + function cleanDialog():Void { - var splitName:Array = dialogueList[0].split(":"); - curCharacter = splitName[1]; - dialogueList[0] = dialogueList[0].substr(splitName[1].length + 2).trim(); + splitData = dialogueList[0].split(":"); + oldCharacter = curCharacter; + curCharacter = splitData[1]; + dialogueList[0] = dialogueList[0].substr(splitData[1].length + 2).trim(); + + splitData = dialogueList[0].split("|"); + oldEmotion = curEmotion; + curEmotion = splitData[1]; + if (splitData[1] != null) + { + dialogueList[0] = dialogueList[0].substr(splitData[1].length + 2).trim(); + } + + splitData = dialogueList[0].split("--"); + curFlip = splitData[1]; + if (splitData[1] != null) + dialogueList[0] = dialogueList[0].substr(splitData[1].length + 4).trim(); + if (splitData[1] == null) + curFlip = 'false'; } } diff --git a/source/DialogueBoxOld.hx b/source/DialogueBoxOld.hx new file mode 100644 index 000000000..23dfd6ee2 --- /dev/null +++ b/source/DialogueBoxOld.hx @@ -0,0 +1,1967 @@ +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; +import flixel.tweens.FlxEase; +import flixel.tweens.FlxTween; + +using StringTools; + +class DialogueBox extends FlxSpriteGroup +{ + var box:FlxSprite; + + public static var curCharacter:String = ''; + public var direction: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 portraitSenpai:FlxSprite; + var portraitBFPixel:FlxSprite; + var portraitHDSenpai:FlxSprite; + var portraitHDSenpaiLeft:FlxSprite; + var portraitTankman:FlxSprite; + var portraitTankmanHappy:FlxSprite; + var portraitTankmanSmile:FlxSprite; + var portraitWhitty:FlxSprite; + var portraitPico:FlxSprite; + var portraitBotan:FlxSprite; + var portraitSarv:FlxSprite; + var portraitGF:FlxSprite; + var portraitSelever:FlxSprite; + var portraitZero:FlxSprite; + var portraitMonika:FlxSprite; + var portraitLeft:FlxSprite; + var portraitRight:FlxSprite; + var portraitLeftPixel:FlxSprite; + var portraitRightPixel:FlxSprite; + var fever:FlxSprite; + var tea:FlxSprite; + + var gasp:Bool = false; + var norm:Bool = false; + + var handSelect:FlxSprite; + var bgFade:FlxSprite; + + var gunShit:String = ''; + + public function new(talkingRight:Bool = true, ?dialogueList:Array) + { + super(); + + switch (PlayState.SONG.song.toLowerCase()) + { + case 'whittyvssarv' | 'gun-buddies': + FlxG.sound.playMusic(Paths.music('gunsDialogue'), 0); + FlxG.sound.music.fadeIn(1, 0, 0.8); + case 'senpai': + FlxG.sound.playMusic(Paths.music('Lunchbox'), 0); + FlxG.sound.music.fadeIn(1, 0, 0.8); + case 'thorns': + FlxG.sound.playMusic(Paths.music('LunchboxScary'), 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); + + box = new FlxSprite(-20, 45); + + var hasDialog = false; + switch (PlayState.SONG.song.toLowerCase()) + { + case 'senpai': + hasDialog = true; + box.frames = Paths.getSparrowAtlas('weeb/pixelUI/dialogueBox-pixel'); + box.animation.addByPrefix('normalOpen', 'Text Box Appear', 24, false); + box.animation.addByIndices('normal', 'Text Box Appear', [4], "", 24); + + case 'roses' | 'roses-remix' | 'roses-remix-senpai': + hasDialog = true; + FlxG.sound.play(Paths.sound('ANGRY_TEXT_BOX')); + + box.frames = Paths.getSparrowAtlas('weeb/pixelUI/dialogueBox-senpaiMad'); + box.animation.addByPrefix('normalOpen', 'SENPAI ANGRY IMPACT SPEECH', 24, false); + box.animation.addByIndices('normal', 'SENPAI ANGRY IMPACT SPEECH', [4], "", 24); + + case 'thorns': + hasDialog = true; + box.frames = Paths.getSparrowAtlas('weeb/pixelUI/dialogueBox-evil'); + 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(Paths.image('weeb/spiritFaceForward')); + face.setGraphicSize(Std.int(face.width * 6)); + add(face); + + case 'whittyvssarv': + hasDialog = true; + box.frames = Paths.getSparrowAtlas('speech_bubble_talking'); + box.animation.addByPrefix('normalOpen', 'Speech Bubble Normal Open', 24, false); + box.animation.addByPrefix('normal', 'speech bubble normal', 24, true); + + case 'dialogue': + hasDialog = true; + box.frames = Paths.getSparrowAtlas('speech_bubble_talking'); + box.animation.addByPrefix('normalOpen', 'Speech Bubble Normal Open', 24, false); + box.animation.addByPrefix('normal', 'speech bubble normal', 24, true); + + default: + hasDialog = true; + box.frames = Paths.getSparrowAtlas('speech_bubble_talking'); + box.animation.addByPrefix('normalOpen', 'Speech Bubble Normal Open', 24, false); + box.animation.addByPrefix('normal', 'speech bubble normal', 24, true); + + } + + if (!PlayState.curStage.startsWith('school')) + { + box.y += 320; + box.x += 500; + } + + this.dialogueList = dialogueList; + + if (!hasDialog) + return; + + portraitSenpai = new FlxSprite(-20, 40); + portraitSenpai.frames = Paths.getSparrowAtlas('portraits/senpaiPortrait'); + portraitSenpai.animation.addByPrefix('enter', 'Senpai Portrait Enter', 24, false); + portraitSenpai.setGraphicSize(Std.int(portraitSenpai.width * PlayState.daPixelZoom * 0.9)); + portraitSenpai.updateHitbox(); + portraitSenpai.scrollFactor.set(); + add(portraitSenpai); + portraitSenpai.visible = false; + + portraitWhitty = new FlxSprite(100, FlxG.height - 575); + portraitWhitty.frames = Paths.getSparrowAtlas('portraits/whittyPort'); + portraitWhitty.animation.addByPrefix('enter', 'Whitty Portrait Normal', 24, false); + portraitWhitty.animation.addByPrefix('agitated', 'Whitty Portrait Agitated', 24, false); + portraitWhitty.animation.addByPrefix('crazy', 'Whitty Portrait Crazy', 24, false); + portraitWhitty.scrollFactor.set(); + add(portraitWhitty); + portraitWhitty.visible = false; + + portraitPico = new FlxSprite(100, FlxG.height - 550); + portraitPico.frames = Paths.getSparrowAtlas('portraits/picoPort'); + portraitPico.animation.addByPrefix('enter', 'Pico Portrait Normal', 24, false); + portraitPico.animation.addByPrefix('angry', 'Pico Portrait Angry', 24, false); + portraitPico.animation.addByPrefix('dark', 'Pico Portrait Dark', 24, false); + portraitPico.animation.addByPrefix('speakdark', 'Pico Portrait Speak Dark', 24, false); + portraitPico.animation.addByPrefix('shoutdark', 'Pico Portrait Shout Dark', 24, false); + portraitPico.animation.addByPrefix('happydark', 'Pico Portrait Happy Dark', 24, false); + portraitPico.animation.addByPrefix('threat', 'Pico Portrait Threat', 24, false); + portraitPico.animation.addByPrefix('speakdark-gunless', 'Pico Portrait Gunless Speak Dark', 24, false); + portraitPico.animation.addByPrefix('dark-gunless', 'Pico Portrait Gunless Dark', 24, false); + portraitPico.animation.addByPrefix('happydark-gunless', 'Pico Portrait Gunless Happy Dark', 24, false); + portraitPico.scrollFactor.set(); + add(portraitPico); + portraitPico.visible = false; + + portraitBotan = new FlxSprite(100, FlxG.height - 600); + portraitBotan.frames = Paths.getSparrowAtlas('portraits/botanPort'); + portraitBotan.animation.addByPrefix('enter', 'Botan Portrait Normal', 24, false); + portraitBotan.animation.addByPrefix('smirk', 'Botan Portrait Smirk', 24, false); + portraitBotan.animation.addByPrefix('worried', 'Botan Portrait Worried', 24, false); + portraitBotan.animation.addByPrefix('smile', 'Botan Portrait Smile', 24, false); + portraitBotan.animation.addByPrefix('speak', 'Botan Portrait Speak', 24, false); + portraitBotan.animation.addByPrefix('angry', 'Botan Portrait Angry', 24, false); + portraitBotan.animation.addByPrefix('blush', 'Botan Portrait Blush', 24, false); + portraitBotan.animation.addByPrefix('enter-gun', 'Botan Gun Portrait Normal', 24, false); + portraitBotan.animation.addByPrefix('smirk-gun', 'Botan Gun Portrait Smirk', 24, false); + portraitBotan.animation.addByPrefix('worried-gun', 'Botan Gun Portrait Worried', 24, false); + portraitBotan.animation.addByPrefix('smile-gun', 'Botan Gun Portrait Smile', 24, false); + portraitBotan.animation.addByPrefix('speak-gun', 'Botan Gun Portrait Speak', 24, false); + portraitBotan.animation.addByPrefix('blush-gun', 'Botan Gun Portrait Blush', 24, false); + portraitBotan.scrollFactor.set(); + add(portraitBotan); + portraitBotan.visible = false; + + portraitMonika = new FlxSprite(-20, 40); + portraitMonika.frames = Paths.getSparrowAtlas('portraits/monika'); + portraitMonika.animation.addByPrefix('enter', 'Portrait Enter instance', 24, false); + portraitMonika.setGraphicSize(Std.int(portraitMonika.width * PlayState.daPixelZoom * 0.9)); + portraitMonika.updateHitbox(); + portraitMonika.scrollFactor.set(); + add(portraitMonika); + portraitMonika.visible = false; + + portraitZero = new FlxSprite(-300, 20); + portraitZero.frames = Paths.getSparrowAtlas('portraits/016portrait'); + portraitZero.animation.addByPrefix('enter', 'Portrait Enter instance', 24, false); + portraitZero.scrollFactor.set(); + add(portraitZero); + portraitZero.visible = false; + + portraitSelever = new FlxSprite(200, FlxG.height - 575); + portraitSelever.frames = Paths.getSparrowAtlas('portraits/mfmportraits'); + portraitSelever.animation.addByPrefix('happy', 'SelHappy', 24, false); + portraitSelever.animation.addByPrefix('smile', 'SelSmile', 24, false); + portraitSelever.animation.addByPrefix('XD', 'SelXD', 24, false); + portraitSelever.animation.addByPrefix('angry', 'SelAngery', 24, false); + portraitSelever.animation.addByPrefix('upset', 'SelUpset', 24, false); + portraitSelever.animation.addByPrefix('tf', 'SelTF', 24, false); + portraitSelever.scrollFactor.set(); + add(portraitSelever); + portraitSelever.visible = false; + + portraitBFPixel = new FlxSprite(0, 40); + portraitBFPixel.frames = Paths.getSparrowAtlas('portraits/bfPortrait'); + portraitBFPixel.animation.addByPrefix('enter', 'Boyfriend portrait enter', 24, false); + portraitBFPixel.setGraphicSize(Std.int(portraitBFPixel.width * PlayState.daPixelZoom * 0.9)); + portraitBFPixel.updateHitbox(); + portraitBFPixel.scrollFactor.set(); + add(portraitBFPixel); + portraitBFPixel.visible = false; + + portraitSarv = new FlxSprite(200, FlxG.height - 550); + portraitSarv.frames = Paths.getSparrowAtlas('portraits/mfmportraits'); + portraitSarv.animation.addByPrefix('happy', 'SarvHappy', 24, false); + portraitSarv.animation.addByPrefix('sad', 'SarvSad', 24, false); + portraitSarv.animation.addByPrefix('upset', 'SarvUpset', 24, false); + portraitSarv.animation.addByPrefix('angry', 'SarvAngery', 24, false); + portraitSarv.animation.addByPrefix('smile', 'SarvSmile', 24, false); + portraitSarv.animation.addByPrefix('devil', 'SarvDevil', 24, false); + portraitSarv.scrollFactor.set(); + add(portraitSarv); + portraitSarv.visible = false; + + portraitGF = new FlxSprite(0, 20); + portraitGF.frames = Paths.getSparrowAtlas('portraits/gfPort'); + portraitGF.animation.addByPrefix('enter', 'GF Portrait Normal', 24, false); + portraitGF.animation.addByPrefix('cry', 'GF Portrait Cry', 24, false); + portraitGF.scrollFactor.set(); + add(portraitGF); + portraitGF.visible = false; + + portraitLeft = new FlxSprite(-40, 20); + portraitLeft.frames = Paths.getSparrowAtlas('portraits/gfPort'); + portraitLeft.animation.addByPrefix('enter', 'GF Portrait Normal', 24, false); + portraitLeft.scrollFactor.set(); + add(portraitLeft); + portraitLeft.visible = false; + + portraitRight = new FlxSprite(0, 20); + portraitRight.frames = Paths.getSparrowAtlas('portraits/gfPort'); + portraitRight.animation.addByPrefix('enter', 'GF Portrait Normal', 24, false); + portraitRight.scrollFactor.set(); + add(portraitRight); + portraitRight.visible = false; + + portraitLeftPixel = new FlxSprite(-20, 40); + portraitLeftPixel.frames = Paths.getSparrowAtlas('portraits/senpaiPortrait'); + portraitLeftPixel.animation.addByPrefix('enter', 'Senpai Portrait Enter', 24, false); + portraitLeftPixel.setGraphicSize(Std.int(portraitLeftPixel.width * PlayState.daPixelZoom * 0.9)); + portraitLeftPixel.updateHitbox(); + portraitLeftPixel.scrollFactor.set(); + add(portraitLeftPixel); + portraitLeftPixel.visible = false; + + portraitRightPixel = new FlxSprite(0, 40); + portraitRightPixel.frames = Paths.getSparrowAtlas('portraits/bfPortrait'); + portraitRightPixel.animation.addByPrefix('enter', 'Boyfriend portrait enter', 24, false); + portraitRightPixel.setGraphicSize(Std.int(portraitRightPixel.width * PlayState.daPixelZoom * 0.9)); + portraitRightPixel.updateHitbox(); + portraitRightPixel.scrollFactor.set(); + add(portraitRightPixel); + portraitRightPixel.visible = false; + + fever = new FlxSprite(830, 40); + fever.frames = Paths.getSparrowAtlas('portraits/feversprites'); + fever.animation.addByPrefix('point', 'feverpoint', 24, false); + fever.animation.addByPrefix('silly', 'feversilly', 24, false); + fever.animation.addByPrefix('worry', 'feverworry', 24, false); + fever.animation.addByPrefix('flirt', 'feverflirt', 24, false); + fever.animation.addByPrefix('scared', 'feverscared', 24, false); + fever.animation.addByPrefix('confuse', 'feverconfuse', 24, false); + fever.animation.addByPrefix('tired', 'fevertired', 24, false); + fever.animation.addByPrefix('fine', 'feverfine', 24, false); + fever.animation.addByPrefix('annoyed', 'feverannoyed', 24, false); + fever.animation.addByPrefix('smile', 'feversmile', 24, false); + fever.setGraphicSize(Std.int(fever.width * 0.8)); + fever.updateHitbox(); + fever.scrollFactor.set(); + add(fever); + fever.visible = false; + + tea = new FlxSprite(40, 40); + tea.frames = Paths.getSparrowAtlas('portraits/teaSprites'); + tea.animation.addByPrefix('smile', 'teaSmile', 24, false); + tea.animation.addByPrefix('neutral', 'teaNeutral', 24, false); + tea.animation.addByPrefix('worry', 'teaWorry', 24, false); + tea.animation.addByPrefix('blush', 'teaBlush', 24, false); + tea.animation.addByPrefix('annoy', 'teaAnnoy', 0, false); + tea.animation.addByPrefix('annoytwo', 'teaAnnoy2', 24, false); + tea.animation.addByPrefix('think', 'teaThink', 24, false); + tea.animation.addByPrefix('angry', 'teaAngry', 24, false); + tea.setGraphicSize(Std.int(tea.width * 0.8)); + tea.updateHitbox(); + tea.scrollFactor.set(); + add(tea); + tea.visible = false; + + + box.animation.play('normalOpen'); + if (PlayState.SONG.song.toLowerCase() == 'senpai' || PlayState.SONG.song.toLowerCase() == 'thorns' || PlayState.SONG.song.toLowerCase() == 'roses') + { + box.setGraphicSize(Std.int(box.width * PlayState.daPixelZoom * 0.9)); + } + + box.updateHitbox(); + add(box); + + box.screenCenter(X); + if (PlayState.curStage.contains('school')) + { + trace('IS IN SENPAI STAGE'); + } + else + box.x += 50; + portraitSenpai.screenCenter(X); + + if (!PlayState.curStage.startsWith('school')) + { + portraitSenpai.x -= 50; + portraitSenpai.y += 20; + portraitBFPixel.x += 50; + portraitBFPixel.y += 20; + portraitMonika.x -= 50; + portraitMonika.y += 20; + portraitLeftPixel.x -= 50; + portraitLeftPixel.y += 20; + portraitRightPixel.x += 50; + portraitRightPixel.y += 20; + } + + handSelect = new FlxSprite(FlxG.width * 0.9, FlxG.height * 0.9).loadGraphic(Paths.image('weeb/pixelUI/hand_textbox')); + add(handSelect); + + + if (!talkingRight) + { + // 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(Paths.sound('pixelText'), 0.6)]; + add(swagDialogue); + + dialogue = new Alphabet(0, 80, "", false, true); + // dialogue.x = 90; + // add(dialogue); + } + + var dialogueOpened:Bool = false; + var dialogueStarted:Bool = false; + + override function update(elapsed:Float) + { + // HARD CODING CUZ IM STUPDI + if (PlayState.SONG.song.toLowerCase() == 'roses') + portraitSenpai.visible = false; + if (PlayState.SONG.song.toLowerCase() == 'thorns') + { + portraitSenpai.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) + { + box.animation.play('normal'); + dialogueOpened = true; + } + } + + if (swagDialogue.text == '...' && curCharacter == 'pico-dark') + { + PlayState.instance.dad.playAnim('mad', true); + } + + if (curCharacter == 'pico-happydark') + { + PlayState.instance.dad.playAnim('huh', true, false); + } + + if (curCharacter == 'pico-threat') + { + PlayState.instance.dad.playAnim('idle', true, false, 15); + } + + if (dialogueOpened && !dialogueStarted) + { + startDialogue(); + dialogueStarted = true; + } + + if (FlxG.keys.justPressed.ANY && dialogueStarted == true) + { + remove(dialogue); + + FlxG.sound.play(Paths.sound('clickText'), 0.8); + + if (dialogueList[1] == null && dialogueList[0] != null) + { + if (!isEnding) + { + isEnding = true; + + if (PlayState.SONG.song.toLowerCase() == 'senpai' || PlayState.SONG.song.toLowerCase() == 'thorns' || PlayState.SONG.song.toLowerCase() == 'whittyvssarv') + 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; + portraitSenpai.visible = false; + portraitBFPixel.visible = false; + portraitWhitty.visible = false; + portraitSarv.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitMonika.visible = false; + portraitGF.visible = false; + portraitRight.visible = false; + portraitLeft.visible = false; + portraitPico.visible = false; + fever.visible = false; + tea.visible = false; + swagDialogue.alpha -= 1 / 5; + dropText.alpha = swagDialogue.alpha; + }, 5); + + new FlxTimer().start(1.2, function(tmr:FlxTimer) + { + finishThing(); + kill(); + }); + } + } + else + { + dialogueList.remove(dialogueList[0]); + startDialogue(); + } + } + + super.update(elapsed); + } + + /*function tweenShit(id:String):Void + { + alpha = 0; + new FlxTimer().start(0.1, function(tmr:FlxTimer) + { + alpha += 0.1; + + if (direction == 'right') + { + FlxTween.tween(id, {y: y - 100}, 1); + } + else + { + FlxTween.tween(id, {y: y + 100}, 1); + } + + if (alpha < 1) + { + tmr.reset(0.1); + } + }); + }*/ + + /*function visibilityShit():Void + { + portraitSenpai.visible = false; + portraitBFPixel.visible = false; + portraitWhitty.visible = false; + portraitSarv.visible = false; + portraitGF.visible = false; + portraitZero.visible = false; + portraitMonika.visible = false; + portraitSelever.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + }*/ + + var isEnding:Bool = false; + + function startDialogue():Void + { + 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 'senpai': + portraitBFPixel.visible = false; + portraitWhitty.visible = false; + portraitSarv.visible = false; + portraitGF.visible = false; + portraitZero.visible = false; + portraitMonika.visible = false; + portraitSelever.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + if (!portraitSenpai.visible || (portraitSenpai.visible && portraitSenpai.frames != Paths.getSparrowAtlas('portraits/senpaiPortrait'))) + { + portraitSenpai.visible = true; + portraitSenpai.frames = Paths.getSparrowAtlas('portraits/senpaiPortrait'); + portraitSenpai.animation.addByPrefix('enter', 'Senpai Portrait Enter', 24, false); + portraitSenpai.animation.play('enter'); + } + + case 'senpai-angry': + portraitBFPixel.visible = false; + portraitWhitty.visible = false; + portraitSarv.visible = false; + portraitGF.visible = false; + portraitZero.visible = false; + portraitMonika.visible = false; + portraitSelever.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + if (!portraitSenpai.visible|| (portraitSenpai.visible && portraitSenpai.frames != Paths.getSparrowAtlas('portraits/senpai_angry'))) + { + portraitSenpai.visible = true; + portraitSenpai.frames = Paths.getSparrowAtlas('portraits/senpai_angry'); + portraitSenpai.animation.addByPrefix('enter', 'Portrait Enter instance', 24, false); + portraitSenpai.animation.play('enter'); + } + + case 'whitty': + portraitSenpai.visible = false; + portraitBFPixel.visible = false; + portraitSarv.visible = false; + portraitGF.visible = false; + portraitZero.visible = false; + portraitMonika.visible = false; + portraitSelever.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + if (!portraitWhitty.visible|| portraitWhitty.animation.curAnim.name != 'enter') + { + portraitWhitty.visible = true; + portraitWhitty.animation.play('enter'); + } + + case 'whitty-mad': + portraitSenpai.visible = false; + portraitBFPixel.visible = false; + portraitSarv.visible = false; + portraitGF.visible = false; + portraitZero.visible = false; + portraitMonika.visible = false; + portraitSelever.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + if (!portraitWhitty.visible || portraitWhitty.animation.curAnim.name != 'agitated') + { + portraitWhitty.visible = true; + portraitWhitty.animation.play('agitated'); + } + + case 'sarv': + portraitSenpai.visible = false; + portraitBFPixel.visible = false; + portraitWhitty.visible = false; + portraitGF.visible = false; + portraitZero.visible = false; + portraitMonika.visible = false; + portraitSelever.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + if (!portraitSarv.visible || portraitSarv.animation.curAnim.name != 'happy') + { + portraitSarv.visible = true; + portraitSarv.animation.play('happy'); + } + + case 'gf-gunpoint': + portraitSenpai.visible = false; + portraitBFPixel.visible = false; + portraitWhitty.visible = false; + portraitSarv.visible = false; + portraitZero.visible = false; + portraitMonika.visible = false; + portraitSelever.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + portraitPico.visible = false; + portraitBotan.visible = false; + if (!portraitGF.visible || portraitGF.animation.curAnim.name != 'enter') + { + portraitGF.visible = true; + portraitGF.animation.play('enter'); + } + + case 'gf-cry-gunpoint': + portraitSenpai.visible = false; + portraitBFPixel.visible = false; + portraitWhitty.visible = false; + portraitSarv.visible = false; + portraitZero.visible = false; + portraitMonika.visible = false; + portraitSelever.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + portraitPico.visible = false; + portraitBotan.visible = false; + if (!portraitGF.visible || portraitGF.animation.curAnim.name != 'cry') + { + portraitGF.visible = true; + portraitGF.animation.play('cry'); + } + + case 'shadowman': + portraitSenpai.visible = false; + portraitBFPixel.visible = false; + portraitGF.visible = false; + portraitWhitty.visible = false; + portraitSarv.visible = false; + portraitZero.visible = false; + portraitMonika.visible = false; + portraitSelever.visible = false; + portraitLeft.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + if (!portraitRight.visible || (portraitRight.visible && portraitRight.frames != Paths.getSparrowAtlas('portraits/WhoDisBlanta'))) + { + portraitRight.visible = true; + portraitRight.frames = Paths.getSparrowAtlas('portraits/WhoDisBlanta'); + portraitRight.animation.addByPrefix('enter', 'Portrait Enter instance', 24, false); + portraitRight.animation.play('enter'); + } + + case 'sarv-smile': + portraitSenpai.visible = false; + portraitBFPixel.visible = false; + portraitWhitty.visible = false; + portraitGF.visible = false; + portraitZero.visible = false; + portraitMonika.visible = false; + portraitSelever.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + if (!portraitSarv.visible || portraitSarv.animation.curAnim.name != 'smile') + { + portraitSarv.visible = true; + portraitSarv.animation.play('smile'); + } + + case 'zero': + portraitSenpai.visible = false; + portraitBFPixel.visible = false; + portraitWhitty.visible = false; + portraitSarv.visible = false; + portraitGF.visible = false; + portraitMonika.visible = false; + portraitSelever.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + if (!portraitZero.visible || (portraitZero.visible && portraitZero.frames != Paths.getSparrowAtlas('portraits/016portrait'))) + { + portraitZero.visible = true; + portraitZero.frames = Paths.getSparrowAtlas('portraits/016portrait'); + portraitZero.animation.addByPrefix('enter', 'Portrait Enter instance', 24, false); + portraitZero.animation.play('enter'); + } + + case 'zerohuh': + portraitSenpai.visible = false; + portraitBFPixel.visible = false; + portraitWhitty.visible = false; + portraitSarv.visible = false; + portraitGF.visible = false; + portraitMonika.visible = false; + portraitSelever.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + if (!portraitZero.visible || (portraitZero.visible && portraitZero.frames != Paths.getSparrowAtlas('portraits/016huh'))) + { + portraitZero.visible = true; + portraitZero.frames = Paths.getSparrowAtlas('portraits/016huh'); + portraitZero.animation.addByPrefix('enter', 'Portrait Enter instance', 24, false); + portraitZero.animation.play('enter'); + } + + case 'zerosmile': + portraitSenpai.visible = false; + portraitBFPixel.visible = false; + portraitWhitty.visible = false; + portraitSarv.visible = false; + portraitGF.visible = false; + portraitMonika.visible = false; + portraitSelever.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + if (!portraitZero.visible || (portraitZero.visible && portraitZero.frames != Paths.getSparrowAtlas('portraits/016smile'))) + { + portraitZero.visible = true; + portraitZero.frames = Paths.getSparrowAtlas('portraits/016smile'); + portraitZero.animation.addByPrefix('enter', 'Portrait Enter instance', 24, false); + portraitZero.animation.play('enter'); + } + + case 'monika': + portraitSenpai.visible = false; + portraitBFPixel.visible = false; + portraitWhitty.visible = false; + portraitSarv.visible = false; + portraitGF.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + if (!portraitMonika.visible || (portraitMonika.visible && portraitMonika.frames != Paths.getSparrowAtlas('portraits/monika'))) + { + portraitMonika.visible = true; + portraitMonika.frames = Paths.getSparrowAtlas('portraits/monika'); + portraitMonika.animation.addByPrefix('enter', 'Portrait Enter instance', 24, false); + portraitMonika.animation.play('enter'); + } + + case 'monikaright': + portraitSenpai.visible = false; + portraitBFPixel.visible = false; + portraitWhitty.visible = false; + portraitSarv.visible = false; + portraitGF.visible = false; + portraitZero.visible = false; + portraitMonika.visible = false; + portraitSelever.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + if (!portraitRightPixel.visible || (portraitRightPixel.visible && portraitRightPixel.frames != Paths.getSparrowAtlas('portraits/monikaright'))) + { + portraitRightPixel.visible = true; + portraitRightPixel.frames = Paths.getSparrowAtlas('portraits/monikaright'); + portraitRightPixel.animation.addByPrefix('enter', 'Portrait Enter instance', 24, false); + portraitRightPixel.animation.play('enter'); + } + + case 'monikaangry': + portraitSenpai.visible = false; + portraitBFPixel.visible = false; + portraitWhitty.visible = false; + portraitSarv.visible = false; + portraitGF.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + if (!portraitMonika.visible || (portraitMonika.visible && portraitMonika.frames != Paths.getSparrowAtlas('portraits/monikaangry'))) + { + portraitMonika.visible = true; + portraitMonika.frames = Paths.getSparrowAtlas('portraits/monikaangry'); + portraitMonika.animation.addByPrefix('enter', 'Portrait Enter instance', 24, false); + portraitMonika.animation.play('enter'); + } + + case 'monikaangryright': + portraitSenpai.visible = false; + portraitBFPixel.visible = false; + portraitWhitty.visible = false; + portraitSarv.visible = false; + portraitGF.visible = false; + portraitZero.visible = false; + portraitMonika.visible = false; + portraitSelever.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + if (!portraitRightPixel.visible || (portraitRightPixel.visible && portraitRightPixel.frames != Paths.getSparrowAtlas('portraits/monikaangryright'))) + { + portraitRightPixel.visible = true; + portraitRightPixel.frames = Paths.getSparrowAtlas('portraits/monikaangryright'); + portraitRightPixel.animation.addByPrefix('enter', 'Portrait Enter instance', 24, false); + portraitRightPixel.animation.play('enter'); + } + + case 'monikagasp': + portraitSenpai.visible = false; + portraitBFPixel.visible = false; + portraitWhitty.visible = false; + portraitSarv.visible = false; + portraitGF.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + if (!portraitMonika.visible || (portraitMonika.visible && portraitMonika.frames != Paths.getSparrowAtlas('portraits/monikagaspleft'))) + { + portraitMonika.visible = true; + portraitMonika.frames = Paths.getSparrowAtlas('portraits/monikagaspleft'); + portraitMonika.animation.addByPrefix('enter', 'Portrait Enter instance', 24, false); + portraitMonika.animation.play('enter'); + } + + case 'monikagaspright': + portraitSenpai.visible = false; + portraitBFPixel.visible = false; + portraitWhitty.visible = false; + portraitSarv.visible = false; + portraitGF.visible = false; + portraitZero.visible = false; + portraitMonika.visible = false; + portraitSelever.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + if (!portraitRightPixel.visible || (portraitRightPixel.visible && portraitRightPixel.frames != Paths.getSparrowAtlas('portraits/monikagasp'))) + { + portraitRightPixel.visible = true; + portraitRightPixel.frames = Paths.getSparrowAtlas('portraits/monikagasp'); + portraitRightPixel.animation.addByPrefix('enter', 'Portrait Enter instance', 24, false); + portraitRightPixel.animation.play('enter'); + } + + case 'monikahappy': + portraitSenpai.visible = false; + portraitBFPixel.visible = false; + portraitWhitty.visible = false; + portraitSarv.visible = false; + portraitGF.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + if (!portraitMonika.visible || (portraitMonika.visible && portraitMonika.frames != Paths.getSparrowAtlas('portraits/monikahappy'))) + { + portraitMonika.visible = true; + portraitMonika.frames = Paths.getSparrowAtlas('portraits/monikahappy'); + portraitMonika.animation.addByPrefix('enter', 'Portrait Enter instance', 24, false); + portraitMonika.animation.play('enter'); + } + + case 'monikahappyright': + portraitSenpai.visible = false; + portraitBFPixel.visible = false; + portraitWhitty.visible = false; + portraitSarv.visible = false; + portraitGF.visible = false; + portraitZero.visible = false; + portraitMonika.visible = false; + portraitSelever.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + if (!portraitRightPixel.visible || (portraitRightPixel.visible && portraitRightPixel.frames != Paths.getSparrowAtlas('portraits/monikahappyright'))) + { + portraitRightPixel.visible = true; + portraitRightPixel.frames = Paths.getSparrowAtlas('portraits/monikahappyright'); + portraitRightPixel.animation.addByPrefix('enter', 'Portrait Enter instance', 24, false); + portraitRightPixel.animation.play('enter'); + } + + case 'monikahmm': + portraitSenpai.visible = false; + portraitBFPixel.visible = false; + portraitWhitty.visible = false; + portraitSarv.visible = false; + portraitGF.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + if (!portraitMonika.visible || (portraitMonika.visible && portraitMonika.frames != Paths.getSparrowAtlas('portraits/monikahmm'))) + { + portraitMonika.visible = true; + portraitMonika.frames = Paths.getSparrowAtlas('portraits/monikahmm'); + portraitMonika.animation.addByPrefix('enter', 'Portrait Enter instance', 24, false); + portraitMonika.animation.play('enter'); + } + + case 'bf-pixel': + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitSarv.visible = false; + portraitGF.visible = false; + portraitZero.visible = false; + portraitMonika.visible = false; + portraitSelever.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + if (!portraitBFPixel.visible) + { + portraitBFPixel.visible = true; + portraitBFPixel.animation.play('enter'); + } + + case 'sel': + portraitSenpai.visible = false; + portraitBFPixel.visible = false; + portraitWhitty.visible = false; + portraitSarv.visible = false; + portraitGF.visible = false; + portraitZero.visible = false; + portraitMonika.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + if (!portraitSelever.visible || (portraitSelever.visible && portraitSelever.animation.curAnim.name != ('happy'))) + { + portraitSelever.visible = true; + portraitSelever.animation.play('happy'); + } + + case 'selsmile': + portraitSenpai.visible = false; + portraitBFPixel.visible = false; + portraitWhitty.visible = false; + portraitSarv.visible = false; + portraitGF.visible = false; + portraitZero.visible = false; + portraitMonika.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + if (!portraitSelever.visible || (portraitSelever.visible && portraitSelever.animation.curAnim.name != ('smile'))) + { + portraitSelever.visible = true; + portraitSelever.animation.play('smile'); + } + + case 'selupset': + portraitSenpai.visible = false; + portraitBFPixel.visible = false; + portraitWhitty.visible = false; + portraitSarv.visible = false; + portraitGF.visible = false; + portraitZero.visible = false; + portraitMonika.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + if (!portraitSelever.visible || (portraitSelever.visible && portraitSelever.animation.curAnim.name != ('upset'))) + { + portraitSelever.visible = true; + portraitSelever.animation.play('upset'); + } + + case 'selxd': + portraitSenpai.visible = false; + portraitBFPixel.visible = false; + portraitWhitty.visible = false; + portraitSarv.visible = false; + portraitGF.visible = false; + portraitZero.visible = false; + portraitMonika.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + if (!portraitSelever.visible || (portraitSelever.visible && portraitSelever.animation.curAnim.name != ('XD'))) + { + portraitSelever.visible = true; + portraitSelever.animation.play('XD'); + } + + case 'selangry': + portraitSenpai.visible = false; + portraitBFPixel.visible = false; + portraitWhitty.visible = false; + portraitSarv.visible = false; + portraitGF.visible = false; + portraitZero.visible = false; + portraitMonika.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + if (!portraitSelever.visible || (portraitSelever.visible && portraitSelever.animation.curAnim.name != ('angry'))) + { + portraitSelever.visible = true; + portraitSelever.animation.play('angry'); + } + + case 'seltf': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + if (!portraitSelever.visible || (portraitSelever.visible && portraitSelever.animation.curAnim.name != ('tf'))) + { + portraitSelever.visible = true; + portraitSelever.animation.play('tf'); + } + + case 'pico': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitBotan.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + fever.visible = false; + tea.visible = false; + if (!portraitPico.visible || (portraitPico.visible && portraitPico.animation.curAnim.name != 'enter')) + { + portraitPico.visible = true; + portraitPico.animation.play('enter'); + } + + case 'pico-angry': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitBotan.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + fever.visible = false; + tea.visible = false; + if (!portraitPico.visible || (portraitPico.visible && portraitPico.animation.curAnim.name != 'angry')) + { + portraitPico.visible = true; + portraitPico.animation.play('angry'); + } + + case 'pico-dark' | 'pico-gunless-dark': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitBotan.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + fever.visible = false; + tea.visible = false; + + if (curCharacter.contains('gunless')) + { + gunShit ='-gunless'; + } + else + { + gunShit = ''; + } + + if (!portraitPico.visible || (portraitPico.visible && portraitPico.animation.curAnim.name != ('dark' + gunShit))) + { + portraitPico.visible = true; + portraitPico.animation.play('dark'+ gunShit); + } + + case 'pico-speakdark' | 'pico-gunless-speakdark': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitBotan.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + fever.visible = false; + tea.visible = false; + + if (curCharacter.contains('gunless')) + { + gunShit ='-gunless'; + } + else + { + gunShit = ''; + } + + if (!portraitPico.visible || (portraitPico.visible && portraitPico.animation.curAnim.name != ('speakdark' + gunShit))) + { + portraitPico.visible = true; + portraitPico.animation.play('speakdark' + gunShit); + } + + case 'pico-shoutdark': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitBotan.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + fever.visible = false; + tea.visible = false; + if (!portraitPico.visible || (portraitPico.visible && portraitPico.animation.curAnim.name != 'shoutdark')) + { + portraitPico.visible = true; + portraitPico.animation.play('shoutdark'); + } + + case 'pico-threat': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitBotan.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + fever.visible = false; + tea.visible = false; + if (!portraitPico.visible || (portraitPico.visible && portraitPico.animation.curAnim.name != 'threat')) + { + portraitPico.visible = true; + portraitPico.animation.play('threat'); + } + + case 'pico-happydark' | 'pico-gunless-happydark': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitBotan.visible = false; + portraitLeft.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + fever.visible = false; + tea.visible = false; + + if (curCharacter.contains('gunless')) + { + gunShit ='-gunless'; + } + else + { + gunShit = ''; + } + + if (!portraitPico.visible || (portraitPico.visible && portraitPico.animation.curAnim.name != ('happydark' + gunShit))) + { + portraitPico.visible = true; + portraitPico.animation.play('happydark' + gunShit); + } + + case 'botan-smirk' | 'botan-gun-smirk': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + portraitPico.visible = false; + tea.visible = false; + fever.visible = false; + + if (curCharacter.contains('gun')) + { + gunShit ='-gun'; + } + else + { + gunShit = ''; + } + + if (!portraitBotan.visible || (portraitBotan.visible && portraitBotan.animation.curAnim.name != ('smirk' + gunShit))) + { + portraitBotan.visible = true; + portraitBotan.animation.play('smirk' + gunShit); + } + + case 'botan-smile' | 'botan-gun-smile': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + portraitPico.visible = false; + tea.visible = false; + fever.visible = false; + + if (curCharacter.contains('gun')) + { + gunShit ='-gun'; + } + else + { + gunShit = ''; + } + + if (!portraitBotan.visible || (portraitBotan.visible && portraitBotan.animation.curAnim.name != ('smile' + gunShit))) + { + portraitBotan.visible = true; + portraitBotan.animation.play('smile' + gunShit); + } + + case 'botan-worried' | 'botan-gun-worried': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + portraitPico.visible = false; + tea.visible = false; + fever.visible = false; + + if (curCharacter.contains('gun')) + { + gunShit ='-gun'; + } + else + { + gunShit = ''; + } + + if (!portraitBotan.visible || (portraitBotan.visible && portraitBotan.animation.curAnim.name != ('worried' + gunShit))) + { + portraitBotan.visible = true; + portraitBotan.animation.play('worried' + gunShit); + } + + case 'botan-angry' | 'botan-gun-angry': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + portraitPico.visible = false; + tea.visible = false; + fever.visible = false; + + if (curCharacter.contains('gun')) + { + gunShit ='-gun'; + } + else + { + gunShit = ''; + } + + if (!portraitBotan.visible || (portraitBotan.visible && portraitBotan.animation.curAnim.name != ('angry' + gunShit))) + { + portraitBotan.visible = true; + portraitBotan.animation.play('angry' + gunShit); + } + + case 'botan' | 'botan-gun': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + portraitPico.visible = false; + tea.visible = false; + fever.visible = false; + + if (curCharacter.contains('gun')) + { + gunShit ='-gun'; + } + else + { + gunShit = ''; + } + + if (!portraitBotan.visible || (portraitBotan.visible && portraitBotan.animation.curAnim.name != ('enter' + gunShit))) + { + portraitBotan.visible = true; + portraitBotan.animation.play('enter' + gunShit); + } + + case 'botan-blush' | 'botan-gun-blush': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + portraitPico.visible = false; + tea.visible = false; + fever.visible = false; + + if (curCharacter.contains('gun')) + { + gunShit ='-gun'; + } + else + { + gunShit = ''; + } + + if (!portraitBotan.visible || (portraitBotan.visible && portraitBotan.animation.curAnim.name != ('blush' + gunShit))) + { + portraitBotan.visible = true; + portraitBotan.animation.play('blush' + gunShit); + } + + case 'fever-smile': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + portraitLeft.visible = false; + portraitPico.visible = false; + tea.visible = false; + portraitBotan.visible = false; + if (!fever.visible || (fever.visible && fever.animation.curAnim.name != ('smile'))) + { + fever.visible = true; + fever.animation.play('smile'); + } + + case 'fever-worried': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + portraitLeft.visible = false; + portraitPico.visible = false; + tea.visible = false; + portraitBotan.visible = false; + if (!fever.visible || (fever.visible && fever.animation.curAnim.name != ('worry'))) + { + fever.visible = true; + fever.animation.play('worry'); + } + + case 'fever-annoyed': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + portraitLeft.visible = false; + portraitPico.visible = false; + tea.visible = false; + portraitBotan.visible = false; + if (!fever.visible || (fever.visible && fever.animation.curAnim.name != ('annoyed'))) + { + fever.visible = true; + fever.animation.play('annoyed'); + } + + case 'fever-scared': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + portraitLeft.visible = false; + portraitPico.visible = false; + tea.visible = false; + portraitBotan.visible = false; + if (!fever.visible || (fever.visible && fever.animation.curAnim.name != ('scared'))) + { + fever.visible = true; + fever.animation.play('scared'); + } + + case 'fever-confused': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + portraitLeft.visible = false; + portraitPico.visible = false; + tea.visible = false; + portraitBotan.visible = false; + if (!fever.visible || (fever.visible && fever.animation.curAnim.name != ('confuse'))) + { + fever.visible = true; + fever.animation.play('confuse'); + } + + case 'fever-tired': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + portraitLeft.visible = false; + portraitPico.visible = false; + tea.visible = false; + portraitBotan.visible = false; + if (!fever.visible || (fever.visible && fever.animation.curAnim.name != ('tired'))) + { + fever.visible = true; + fever.animation.play('tired'); + } + + case 'fever-fine': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + portraitLeft.visible = false; + portraitPico.visible = false; + tea.visible = false; + portraitBotan.visible = false; + if (!fever.visible || (fever.visible && fever.animation.curAnim.name != ('fine'))) + { + fever.visible = true; + fever.animation.play('fine'); + } + + case 'tea-smile': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + portraitLeft.visible = false; + portraitPico.visible = false; + fever.visible = false; + portraitBotan.visible = false; + if (!tea.visible || (tea.visible && tea.animation.curAnim.name != ('smile'))) + { + tea.visible = true; + tea.animation.play('smile'); + } + + case 'tea': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + portraitLeft.visible = false; + portraitPico.visible = false; + fever.visible = false; + portraitBotan.visible = false; + if (!tea.visible || (tea.visible && tea.animation.curAnim.name != ('neutral'))) + { + tea.visible = true; + tea.animation.play('neutral'); + } + + case 'tea-worried': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + portraitLeft.visible = false; + portraitPico.visible = false; + fever.visible = false; + portraitBotan.visible = false; + if (!tea.visible || (tea.visible && tea.animation.curAnim.name != ('worry'))) + { + tea.visible = true; + tea.animation.play('worry'); + } + + case 'tea-think': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + portraitLeft.visible = false; + portraitPico.visible = false; + fever.visible = false; + portraitBotan.visible = false; + if (!tea.visible || (tea.visible && tea.animation.curAnim.name != ('think'))) + { + tea.visible = true; + tea.animation.play('think'); + } + + case 'tea-angry': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + portraitLeft.visible = false; + portraitPico.visible = false; + fever.visible = false; + portraitBotan.visible = false; + if (!tea.visible || (tea.visible && tea.animation.curAnim.name != ('angry'))) + { + tea.visible = true; + tea.animation.play('angry'); + } + + case 'tea-annoy': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + portraitLeft.visible = false; + portraitPico.visible = false; + fever.visible = false; + portraitBotan.visible = false; + if (!tea.visible || (tea.visible && tea.animation.curAnim.name != ('annoy'))) + { + tea.visible = true; + tea.animation.play('annoy'); + } + + case 'tea-annoy2': + portraitSarv.visible = false; + portraitGF.visible = false; + portraitSenpai.visible = false; + portraitWhitty.visible = false; + portraitBFPixel.visible = false; + portraitMonika.visible = false; + portraitZero.visible = false; + portraitSelever.visible = false; + portraitRight.visible = false; + portraitLeftPixel.visible = false; + portraitRightPixel.visible = false; + portraitLeft.visible = false; + portraitPico.visible = false; + fever.visible = false; + portraitBotan.visible = false; + if (!tea.visible || (tea.visible && tea.animation.curAnim.name != ('annoy2'))) + { + tea.visible = true; + tea.animation.play('annoy2'); + } + } + + switch (direction) + { + case 'faceright': + if (portraitZero.flipX == false) + { + portraitZero.animation.play('enter'); + portraitZero.flipX = true; + } + + if (portraitBFPixel.flipX == true) + { + portraitBFPixel.animation.play('enter'); + portraitBFPixel.flipX = false; + } + + if (portraitSenpai.flipX == false) + { + portraitSenpai.animation.play('enter'); + portraitSenpai.flipX = true; + } + + if (portraitRightPixel.flipX == true) + { + portraitRightPixel.animation.play('enter'); + portraitRightPixel.flipX = false; + } + + if (portraitLeftPixel.flipX == true) + { + portraitRightPixel.animation.play('enter'); + portraitRightPixel.flipX = false; + } + + if (portraitLeftPixel.flipX == false) + { + portraitLeftPixel.animation.play('enter'); + portraitLeftPixel.flipX = true; + } + + portraitSarv.flipX = true; + portraitLeft.flipX = true; + portraitPico.flipX = true; + portraitGF.flipX = true; + portraitWhitty.flipX = true; + portraitMonika.flipX = false; + portraitSelever.flipX = true; + + + portraitZero.x = 50; + portraitLeft.x = 30; + portraitBFPixel.x = 0; + portraitGF.x = 0; + portraitSenpai.x = 0; + portraitMonika.x = 0; + portraitSarv.x = 850; + portraitSelever.x = 800; + portraitWhitty.x = 0; + portraitPico.x = 800; + portraitLeftPixel.x = 0; + portraitRightPixel.x = 0; + + if (!PlayState.curStage.contains('school')) + { + box.flipX = false; + } + + case 'faceleft': + if (portraitZero.flipX == true) + { + portraitZero.animation.play('enter'); + portraitZero.flipX = false; + } + + if (portraitLeft.flipX == true) + { + portraitLeft.animation.play('enter'); + portraitLeft.flipX = false; + } + + if (portraitBFPixel.flipX == false) + { + portraitBFPixel.animation.play('enter'); + portraitBFPixel.flipX = true; + } + + if (portraitSenpai.flipX == true) + { + portraitSenpai.animation.play('enter'); + portraitSenpai.flipX = false; + } + + if (portraitRightPixel.flipX == false) + { + portraitRightPixel.animation.play('enter'); + portraitRightPixel.flipX = true; + } + + if (portraitLeftPixel.flipX == true) + { + portraitLeftPixel.animation.play('enter'); + portraitLeftPixel.flipX = false; + } + + portraitSarv.flipX = false; + portraitGF.flipX = false; + portraitWhitty.flipX = false; + portraitMonika.flipX = false; + portraitSelever.flipX = false; + + portraitZero.x = -300; + portraitLeft.x = -40; + portraitBFPixel.x = -20; + portraitGF.x = 0; + portraitSenpai.x = -20; + portraitMonika.x = -20; + portraitSarv.x = 200; + portraitSelever.x = 200; + portraitWhitty.x = -100; + portraitLeftPixel.x = -20; + portraitRightPixel.x = -20; + + if (!PlayState.curStage.contains('school')) + { + box.flipX = true; + } + + case 'default': + if (portraitZero.flipX == true) + { + portraitZero.animation.play('enter'); + portraitZero.flipX = false; + } + + if (portraitBFPixel.flipX == true) + { + portraitBFPixel.animation.play('enter'); + portraitBFPixel.flipX = false; + } + + if (portraitSenpai.flipX == true) + { + portraitSenpai.animation.play('enter'); + portraitSenpai.flipX = false; + } + + if (portraitRightPixel.flipX == true) + { + portraitRightPixel.animation.play('enter'); + portraitRightPixel.flipX = false; + } + + if (portraitLeftPixel.flipX == true) + { + portraitLeftPixel.animation.play('enter'); + portraitLeftPixel.flipX = false; + } + + portraitSarv.flipX = false; + portraitLeft.flipX = false; + portraitPico.flipX = false; + portraitGF.flipX = false; + portraitWhitty.flipX = false; + portraitMonika.flipX = false; + portraitSelever.flipX = false; + + portraitZero.x = -300; + portraitBFPixel.x = 0; + portraitGF.x = 0; + portraitSenpai.x = -20; + portraitMonika.x = -20; + portraitSarv.x = 200; + portraitSelever.x = 200; + portraitWhitty.x = 100; + portraitPico.x = 100; + portraitLeft.x = -70; + portraitLeftPixel.x = -20; + portraitRightPixel.x = 0; + + if (!PlayState.curStage.contains('school')) + { + if (curCharacter.contains('gf') || curCharacter.contains('right') || curCharacter.contains('shadowman') || curCharacter.contains('fever')) + { + box.flipX = false; + } + else + { + box.flipX = true; + } + } + } + + } + + function cleanDialog():Void + { + var splitName:Array = dialogueList[0].split(":"); + curCharacter = splitName[1]; + direction = splitName[2]; + + if (splitName[2] == 'faceright' || splitName[2] == 'faceleft') + { + dialogueList[0] = dialogueList[0].substr(splitName[1].length + splitName[2].length + 3).trim(); + } + else + { + direction = 'default'; + dialogueList[0] = dialogueList[0].substr(splitName[1].length + 2).trim(); + } + } +} diff --git a/source/DialogueBoxPsych.hx b/source/DialogueBoxPsych.hx index 4f84972db..9381ab308 100644 --- a/source/DialogueBoxPsych.hx +++ b/source/DialogueBoxPsych.hx @@ -90,11 +90,11 @@ class DialogueCharacter extends FlxSprite #if MODS_ALLOWED var path:String = Paths.modFolders(characterPath); if (!FileSystem.exists(path)) { - path = Main.getDataPath() + Paths.getPreloadPath(characterPath); + path = Paths.getPreloadPath(characterPath); } if(!FileSystem.exists(path)) { - path = Main.getDataPath() + Paths.getPreloadPath('images/dialogue/' + DEFAULT_CHARACTER + '.json'); + path = Paths.getPreloadPath('images/dialogue/' + DEFAULT_CHARACTER + '.json'); } rawJson = File.getContent(path); @@ -177,6 +177,8 @@ class DialogueBoxPsych extends FlxSpriteGroup var offsetPos:Float = -600; var textBoxTypes:Array = ['normal', 'angry']; + + var curCharacter:String = ""; //var charPositionList:Array = ['left', 'center', 'right']; public function new(dialogueList:DialogueFile, ?song:String = null) @@ -244,7 +246,6 @@ class DialogueBoxPsych extends FlxSpriteGroup var x:Float = LEFT_CHAR_X; var y:Float = DEFAULT_CHAR_Y; var char:DialogueCharacter = new DialogueCharacter(x + offsetPos, y, individualChar); - char.setGraphicSize(Std.int(char.width * DialogueCharacter.DEFAULT_SCALE * char.jsonFile.scale)); char.updateHitbox(); char.antialiasing = ClientPrefs.globalAntialiasing; @@ -290,20 +291,7 @@ class DialogueBoxPsych extends FlxSpriteGroup bgFade.alpha += 0.5 * elapsed; if(bgFade.alpha > 0.5) bgFade.alpha = 0.5; - #if mobile - var justTouched:Bool = false; - - for (touch in FlxG.touches.list) - { - justTouched = false; - - if (touch.justPressed){ - justTouched = true; - } - } - #end - - if(PlayerSettings.player1.controls.ACCEPT#if mobile || justTouched #end) { + if(PlayerSettings.player1.controls.ACCEPT) { if(!daText.finishedText) { if(daText != null) { daText.killTheTimer(); diff --git a/source/DirectionalBlur.hx b/source/DirectionalBlur.hx new file mode 100644 index 000000000..c41d21e8b --- /dev/null +++ b/source/DirectionalBlur.hx @@ -0,0 +1,59 @@ +package; + +import flixel.*; +import flixel.system.FlxAssets.FlxShader; +/** + * ... + * @author bbpanzu + */ +class DirectionalBlur extends FlxShader +{ + + @:glFragmentSource(' + + #pragma header + uniform float angle = 90.0; + uniform float strength = 0.01; + vec4 color = texture2D(bitmap, openfl_TextureCoordv); + //looks good @50, can go pretty high tho + vec2 uv = openfl_TextureCoordv.xy; + + const int samples = 20; + + + void main() + { + + + + float r = radians(angle); + vec2 direction = vec2(sin(r), cos(r)); + + + vec2 ang = strength * direction; + + + vec3 acc = vec3(0); + + const float delta = 2.0 / float(samples); + + for(float i = -1.0; i <= 1.0; i += delta) + { + acc += texture2D(bitmap, uv - vec2(ang.x * i, ang.y * i)).rgb; + } + + + + gl_FragColor = vec4(delta * acc, 0);//dirBlur(bitmap, uv, strength*direction); + } + + + + ') + + public function new() + { + super(); + } + +} \ No newline at end of file diff --git a/source/Discord.hx b/source/Discord.hx index d263db25e..00018e78e 100644 --- a/source/Discord.hx +++ b/source/Discord.hx @@ -1,14 +1,9 @@ -#if desktop package; +#if windows import Sys.sleep; import discord_rpc.DiscordRpc; -#if LUA_ALLOWED -import llua.Lua; -import llua.State; -#end - using StringTools; class DiscordClient @@ -17,7 +12,7 @@ class DiscordClient { trace("Discord Client starting..."); DiscordRpc.start({ - clientID: "863222024192262205", + clientID: "557069829501091850", // change this to what ever the fuck you want lol onReady: onReady, onError: onError, onDisconnected: onDisconnected @@ -33,19 +28,19 @@ class DiscordClient DiscordRpc.shutdown(); } - + public static function shutdown() { DiscordRpc.shutdown(); } - + static function onReady() { DiscordRpc.presence({ details: "In the Menus", state: null, largeImageKey: 'icon', - largeImageText: "Psych Engine" + largeImageText: "fridaynightfunkin" }); } @@ -81,7 +76,7 @@ class DiscordClient details: details, state: state, largeImageKey: 'icon', - largeImageText: "Engine Version: " + MainMenuState.psychEngineVersion, + largeImageText: "fridaynightfunkin", smallImageKey : smallImageKey, // Obtained times are in milliseconds so they are divided so Discord can use it startTimestamp : Std.int(startTimestamp / 1000), @@ -90,13 +85,5 @@ class DiscordClient //trace('Discord RPC Updated. Arguments: $details, $state, $smallImageKey, $hasStartTimestamp, $endTimestamp'); } - - #if LUA_ALLOWED - public static function addLuaCallbacks(lua:State) { - Lua_helper.add_callback(lua, "changePresence", function(details:String, state:Null, ?smallImageKey:String, ?hasStartTimestamp:Bool, ?endTimestamp:Float) { - changePresence(details, state, smallImageKey, hasStartTimestamp, endTimestamp); - }); - } - #end } -#end +#end \ No newline at end of file diff --git a/source/EditorPlayState.hx b/source/EditorPlayState.hx new file mode 100644 index 000000000..ff2c0b863 --- /dev/null +++ b/source/EditorPlayState.hx @@ -0,0 +1,1060 @@ +package; + +import Section.SwagSection; +import Song.SwagSong; +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.addons.transition.FlxTransitionableState; +import flixel.util.FlxColor; +import flixel.FlxSprite; +import flixel.FlxG; +import flixel.text.FlxText; +import flixel.tweens.FlxEase; +import flixel.tweens.FlxTween; +import flixel.math.FlxMath; +import flixel.math.FlxPoint; +import flixel.math.FlxRect; +import flixel.system.FlxSound; +import flixel.util.FlxSort; +import flixel.util.FlxTimer; +import flixel.input.keyboard.FlxKey; +import openfl.events.KeyboardEvent; +import ModchartState; +import lime.utils.Assets; + +#if sys +import lime.media.AudioBuffer; +import flash.media.Sound; +#end + +using StringTools; + +class EditorPlayState extends MusicBeatState +{ + // Yes, this is mostly a copy of PlayState, it's kinda dumb to make a direct copy of it but... ehhh + private var strumLine:FlxSprite; + private var comboGroup:FlxTypedGroup; + public var strumLineNotes:FlxTypedGroup; + public var opponentStrums:FlxTypedGroup; + public var playerStrums:FlxTypedGroup; + public var grpNoteSplashes:FlxTypedGroup; + + public static var keyBinds:Map> = [ + //Key Bind, Name for ControlsSubState + 'note_left' => [A, LEFT], + 'note_down' => [S, DOWN], + 'note_up' => [W, UP], + 'note_right' => [D, RIGHT], + + 'ui_left' => [A, LEFT], + 'ui_down' => [S, DOWN], + 'ui_up' => [W, UP], + 'ui_right' => [D, RIGHT], + + 'accept' => [SPACE, ENTER], + 'back' => [BACKSPACE, ESCAPE], + 'pause' => [ENTER, ESCAPE], + 'reset' => [R, NONE], + + 'volume_mute' => [ZERO, NONE], + 'volume_up' => [NUMPADPLUS, PLUS], + 'volume_down' => [NUMPADMINUS, MINUS], + + 'debug_1' => [SEVEN, NONE], + 'debug_2' => [EIGHT, NONE] + ]; + + public var notes:FlxTypedGroup; + public var unspawnNotes:Array = []; + var isPixel:Bool = false; + + var generatedMusic:Bool = false; + var vocals:FlxSound; + + var startOffset:Float = 0; + var startPos:Float = 0; + + public function new(startPos:Float) { + this.startPos = startPos; + Conductor.songPosition = startPos - startOffset; + + startOffset = Conductor.crochet; + timerToStart = startOffset; + super(); + } + + var scoreTxt:FlxText; + var stepTxt:FlxText; + var beatTxt:FlxText; + + var timerToStart:Float = 0; + private var noteTypeMap:Map = new Map(); + + // Less laggy controls + private var keysArray:Array; + + public static var instance:EditorPlayState; + + override function create() + { + instance = this; + + var bg:FlxSprite = new FlxSprite().loadGraphic(Paths.image('menuDesat')); + bg.scrollFactor.set(); + bg.color = FlxColor.fromHSB(FlxG.random.int(0, 359), FlxG.random.float(0, 0.8), FlxG.random.float(0.3, 1)); + add(bg); + + keysArray = [ + copyKey(keyBinds.get('note_left')), + copyKey(keyBinds.get('note_down')), + copyKey(keyBinds.get('note_up')), + copyKey(keyBinds.get('note_right')) + ]; + + strumLine = new FlxSprite(42, 50).makeGraphic(FlxG.width, 10); + if(FlxG.save.data.downscroll) strumLine.y = FlxG.height - 150; + strumLine.scrollFactor.set(); + + comboGroup = new FlxTypedGroup(); + add(comboGroup); + + strumLineNotes = new FlxTypedGroup(); + opponentStrums = new FlxTypedGroup(); + playerStrums = new FlxTypedGroup(); + add(strumLineNotes); + + generateStaticArrows(0); + generateStaticArrows(1); + /*if(ClientPrefs.middleScroll) { + opponentStrums.forEachAlive(function (note:StrumNote) { + note.visible = false; + }); + }*/ + + grpNoteSplashes = new FlxTypedGroup(); + add(grpNoteSplashes); + + var splash:NoteSplash = new NoteSplash(100, 100, 0); + grpNoteSplashes.add(splash); + splash.alpha = 0.0; + + if (PlayState.SONG.needsVoices) + { + if (!Assets.exists(Paths.voices(PlayState.SONG.song))) + { + if (Paths.currentTrackedSounds.exists(Paths.voices2(PlayState.SONG.song))) + vocals = new FlxSound().loadEmbedded(Paths.currentTrackedSounds.get(Paths.voices2(PlayState.SONG.song))); + else + vocals = new FlxSound().loadEmbedded(Sound.fromFile(Paths.voices2(PlayState.SONG.song))); + } + else + vocals = new FlxSound().loadEmbedded(Paths.voices(PlayState.SONG.song)); + } + else + vocals = new FlxSound(); + + generateSong(PlayState.SONG.song); + /*#if LUA_ALLOWED + for (notetype in noteTypeMap.keys()) { + var luaToLoad:String = Paths.modFolders('custom_notetypes/' + notetype + '.lua'); + if(sys.FileSystem.exists(luaToLoad)) { + var lua:editors.EditorLua = new editors.EditorLua(luaToLoad); + new FlxTimer().start(0.1, function (tmr:FlxTimer) { + lua.stop(); + lua = null; + }); + } + } + #end + noteTypeMap.clear(); + noteTypeMap = null;*/ + + scoreTxt = new FlxText(0, FlxG.height - 50, FlxG.width, "Hits: 0 | Misses: 0", 20); + scoreTxt.setFormat(Paths.font("vcr.ttf"), 20, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + scoreTxt.scrollFactor.set(); + scoreTxt.borderSize = 1.25; + //scoreTxt.visible = !ClientPrefs.hideHud; + add(scoreTxt); + + beatTxt = new FlxText(10, 610, FlxG.width, "Beat: 0", 20); + beatTxt.setFormat(Paths.font("vcr.ttf"), 20, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + beatTxt.scrollFactor.set(); + beatTxt.borderSize = 1.25; + add(beatTxt); + + stepTxt = new FlxText(10, 640, FlxG.width, "Step: 0", 20); + stepTxt.setFormat(Paths.font("vcr.ttf"), 20, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + stepTxt.scrollFactor.set(); + stepTxt.borderSize = 1.25; + add(stepTxt); + + var tipText:FlxText = new FlxText(10, FlxG.height - 24, 0, 'Press ESC to Go Back to Chart Editor', 16); + tipText.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + tipText.borderSize = 2; + tipText.scrollFactor.set(); + add(tipText); + FlxG.mouse.visible = false; + + //sayGo(); + /*if(!ClientPrefs.controllerMode) + { + FlxG.stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyPress); + FlxG.stage.addEventListener(KeyboardEvent.KEY_UP, onKeyRelease); + }*/ + super.create(); + } + + function sayGo() { + var go:FlxSprite = new FlxSprite().loadGraphic(Paths.image('go')); + go.scrollFactor.set(); + + go.updateHitbox(); + + go.screenCenter(); + //go.antialiasing = ClientPrefs.globalAntialiasing; + add(go); + FlxTween.tween(go, {y: go.y += 100, alpha: 0}, Conductor.crochet / 1000, { + ease: FlxEase.cubeInOut, + onComplete: function(twn:FlxTween) + { + go.destroy(); + } + }); + FlxG.sound.play(Paths.sound('introGo'), 0.6); + } + + //var songScore:Int = 0; + var songHits:Int = 0; + var songMisses:Int = 0; + var startingSong:Bool = true; + private function generateSong(dataPath:String):Void + { + if (!Assets.exists(Paths.inst(PlayState.SONG.song))) + { + if (Paths.currentTrackedSounds.exists(Paths.inst2(PlayState.SONG.song))) + FlxG.sound.playMusic(Paths.currentTrackedSounds.get(Paths.inst2(PlayState.SONG.song)), 1, false); + else + FlxG.sound.playMusic(Sound.fromFile(Paths.inst2(PlayState.SONG.song)), 1, false); + } + else + FlxG.sound.playMusic(Paths.inst(PlayState.SONG.song), 1, false); + + FlxG.sound.music.pause(); + FlxG.sound.music.onComplete = endSong; + vocals.pause(); + vocals.volume = 0; + + var songData = PlayState.SONG; + Conductor.changeBPM(songData.bpm); + + notes = new FlxTypedGroup(); + add(notes); + + var noteData:Array; + + // NEW SHIT + noteData = songData.notes; + + var playerCounter:Int = 0; + + var daBeats:Int = 0; // Not exactly representative of 'daBeats' lol, just how much it has looped + + for (section in noteData) + { + for (songNotes in section.sectionNotes) + { + if(songNotes[1] > -1) { //Real notes + var daStrumTime:Float = songNotes[0]; + if(daStrumTime >= startPos) { + var daNoteData:Int = Std.int(songNotes[1] % 4); + + var gottaHitNote:Bool = section.mustHitSection; + + if (songNotes[1] > 3) + { + gottaHitNote = !section.mustHitSection; + } + + var oldNote:Note; + if (unspawnNotes.length > 0) + oldNote = unspawnNotes[Std.int(unspawnNotes.length - 1)]; + else + oldNote = null; + + var swagNote:Note = new Note(daStrumTime, daNoteData, oldNote); + swagNote.mustPress = gottaHitNote; + swagNote.sustainLength = songNotes[2]; + swagNote.noteType = songNotes[3]; + if(!Std.isOfType(songNotes[3], String)) swagNote.noteType = ChartingState.noteTypeList[songNotes[3]]; //Backward compatibility + compatibility with Week 7 charts + swagNote.scrollFactor.set(); + + var susLength:Float = swagNote.sustainLength; + + susLength = susLength / Conductor.stepCrochet; + unspawnNotes.push(swagNote); + + var floorSus:Int = Math.floor(susLength); + if(floorSus > 0) { + for (susNote in 0...floorSus+1) + { + oldNote = unspawnNotes[Std.int(unspawnNotes.length - 1)]; + + var sustainNote:Note = new Note(daStrumTime + (Conductor.stepCrochet * susNote) + (Conductor.stepCrochet / FlxMath.roundDecimal(PlayState.SONG.speed, 2)), daNoteData, oldNote, true); + sustainNote.mustPress = gottaHitNote; + sustainNote.noteType = swagNote.noteType; + sustainNote.scrollFactor.set(); + unspawnNotes.push(sustainNote); + + if (sustainNote.mustPress) + { + sustainNote.x += FlxG.width / 2; // general offset + } + } + } + + if (swagNote.mustPress) + { + swagNote.x += FlxG.width / 2; // general offset + } + + if(!noteTypeMap.exists(swagNote.noteType)) { + noteTypeMap.set(swagNote.noteType, true); + } + } + } + } + daBeats += 1; + } + + unspawnNotes.sort(sortByShit); + generatedMusic = true; + } + + function startSong():Void + { + startingSong = false; + FlxG.sound.music.time = startPos; + FlxG.sound.music.play(); + FlxG.sound.music.volume = 1; + vocals.volume = 1; + vocals.time = startPos; + vocals.play(); + } + + function sortByShit(Obj1:Note, Obj2:Note):Int + { + return FlxSort.byValues(FlxSort.ASCENDING, Obj1.strumTime, Obj2.strumTime); + } + + private function endSong() { + LoadingState.loadAndSwitchState(new ChartingState()); + } + + override function update(elapsed:Float) { + if (FlxG.keys.justPressed.ESCAPE) + { + FlxG.sound.music.pause(); + vocals.pause(); + LoadingState.loadAndSwitchState(new ChartingState()); + } + + if (startingSong) { + timerToStart -= elapsed * 1000; + Conductor.songPosition = startPos - timerToStart; + if(timerToStart < 0) { + startSong(); + } + } else { + Conductor.songPosition += elapsed * 1000; + } + + var roundedSpeed:Float = FlxMath.roundDecimal(PlayState.SONG.speed, 2); + if (unspawnNotes[0] != null) + { + var time:Float = 1500; + if(roundedSpeed < 1) time /= roundedSpeed; + + while (unspawnNotes.length > 0 && unspawnNotes[0].strumTime - Conductor.songPosition < time) + { + var dunceNote:Note = unspawnNotes[0]; + notes.insert(0, dunceNote); + + var index:Int = unspawnNotes.indexOf(dunceNote); + unspawnNotes.splice(index, 1); + } + } + + if (generatedMusic) + { + var fakeCrochet:Float = (60 / PlayState.SONG.bpm) * 1000; + notes.forEachAlive(function(daNote:Note) + { + /*if (daNote.y > FlxG.height) + { + daNote.active = false; + daNote.visible = false; + } + else + { + daNote.visible = true; + daNote.active = true; + }*/ + + // i am so fucking sorry for this if condition + var strumX:Float = 0; + var strumY:Float = 0; + if(daNote.mustPress) { + strumX = playerStrums.members[daNote.noteData].x; + strumY = playerStrums.members[daNote.noteData].y; + } else { + strumX = opponentStrums.members[daNote.noteData].x; + strumY = opponentStrums.members[daNote.noteData].y; + } + + strumX += daNote.offsetX; + strumY += daNote.offsetY; + var center:Float = strumY + Note.swagWidth / 2; + + //if(daNote.copyX) { + daNote.x = strumX; + //} + //if(daNote.copyY) { + if (FlxG.save.data.downscroll) { + daNote.y = (strumY + 0.45 * (Conductor.songPosition - daNote.strumTime) * roundedSpeed); + if (daNote.isSustainNote) { + //Jesus fuck this took me so much mother fucking time AAAAAAAAAA + if (daNote.animation.curAnim.name.endsWith('end')) { + daNote.y += 10.5 * (fakeCrochet / 400) * 1.5 * roundedSpeed + (46 * (roundedSpeed - 1)); + daNote.y -= 46 * (1 - (fakeCrochet / 600)) * roundedSpeed; + if(isPixel) { + daNote.y += 8; + } else { + daNote.y -= 19; + } + } + daNote.y += (Note.swagWidth / 2) - (60.5 * (roundedSpeed - 1)); + daNote.y += 27.5 * ((PlayState.SONG.bpm / 100) - 1) * (roundedSpeed - 1); + + if(daNote.mustPress || !daNote.ignoreNote) + { + if(daNote.y - daNote.offset.y * daNote.scale.y + daNote.height >= center + && (!daNote.mustPress || (daNote.wasGoodHit || (daNote.prevNote.wasGoodHit && !daNote.canBeHit)))) + { + var swagRect = new FlxRect(0, 0, daNote.frameWidth, daNote.frameHeight); + swagRect.height = (center - daNote.y) / daNote.scale.y; + swagRect.y = daNote.frameHeight - swagRect.height; + + daNote.clipRect = swagRect; + } + } + } + } else { + daNote.y = (strumY - 0.45 * (Conductor.songPosition - daNote.strumTime) * roundedSpeed); + + if(daNote.mustPress || !daNote.ignoreNote) + { + if (daNote.isSustainNote + && daNote.y + daNote.offset.y * daNote.scale.y <= center + && (!daNote.mustPress || (daNote.wasGoodHit || (daNote.prevNote.wasGoodHit && !daNote.canBeHit)))) + { + var swagRect = new FlxRect(0, 0, daNote.width / daNote.scale.x, daNote.height / daNote.scale.y); + swagRect.y = (center - daNote.y) / daNote.scale.y; + swagRect.height -= swagRect.y; + + daNote.clipRect = swagRect; + } + } + } + ///} + + if (!daNote.mustPress && daNote.wasGoodHit && !daNote.ignoreNote) + { + if (PlayState.SONG.needsVoices) + vocals.volume = 1; + + var time:Float = 0.15; + if(daNote.isSustainNote && !daNote.animation.curAnim.name.endsWith('end')) { + time += 0.15; + } + StrumPlayAnim(true, Std.int(Math.abs(daNote.noteData)) % 4, time); + + if (!daNote.isSustainNote) + { + daNote.kill(); + notes.remove(daNote, true); + daNote.destroy(); + } + } + + var doKill:Bool = daNote.y < -daNote.height; + if(FlxG.save.data.downscroll) doKill = daNote.y > FlxG.height; + + if (doKill) + { + if (daNote.mustPress) + { + if (daNote.tooLate || !daNote.wasGoodHit) + { + //Dupe note remove + notes.forEachAlive(function(note:Note) { + if (daNote != note && daNote.mustPress && daNote.noteData == note.noteData && daNote.isSustainNote == note.isSustainNote && Math.abs(daNote.strumTime - note.strumTime) < 10) { + note.kill(); + notes.remove(note, true); + note.destroy(); + } + }); + + if(!daNote.ignoreNote) { + songMisses++; + vocals.volume = 0; + } + } + } + + daNote.active = false; + daNote.visible = false; + + daNote.kill(); + notes.remove(daNote, true); + daNote.destroy(); + } + }); + } + + keyShit(); + scoreTxt.text = 'Hits: ' + songHits + ' | Misses: ' + songMisses; + beatTxt.text = 'Beat: ' + curBeat; + stepTxt.text = 'Step: ' + curStep; + super.update(elapsed); + } + + override public function onFocus():Void + { + vocals.play(); + + super.onFocus(); + } + + override public function onFocusLost():Void + { + vocals.pause(); + + super.onFocusLost(); + } + + override function beatHit() + { + super.beatHit(); + + if (generatedMusic) + { + notes.sort(FlxSort.byY, FlxG.save.data.downscroll ? FlxSort.ASCENDING : FlxSort.DESCENDING); + } + } + + override function stepHit() + { + super.stepHit(); + if (FlxG.sound.music.time > Conductor.songPosition + 20 || FlxG.sound.music.time < Conductor.songPosition - 20) + { + resyncVocals(); + } + } + + function resyncVocals():Void + { + vocals.pause(); + + FlxG.sound.music.play(); + Conductor.songPosition = FlxG.sound.music.time; + vocals.time = Conductor.songPosition; + vocals.play(); + } + private function onKeyPress(event:KeyboardEvent):Void + { + var eventKey:FlxKey = event.keyCode; + var key:Int = getKeyFromEvent(eventKey); + //trace('Pressed: ' + eventKey); + + if (key > -1 && (FlxG.keys.checkStatus(eventKey, JUST_PRESSED))) + { + if(generatedMusic) + { + //more accurate hit time for the ratings? + var lastTime:Float = Conductor.songPosition; + Conductor.songPosition = FlxG.sound.music.time; + + var canMiss:Bool = !FlxG.save.data.ghost; + + // heavily based on my own code LOL if it aint broke dont fix it + var pressNotes:Array = []; + //var notesDatas:Array = []; + var notesStopped:Bool = false; + + trace('test!'); + var sortedNotesList:Array = []; + notes.forEachAlive(function(daNote:Note) + { + if (daNote.canBeHit && daNote.mustPress && !daNote.tooLate && !daNote.wasGoodHit) + { + if(daNote.noteData == key && !daNote.isSustainNote) + { + trace('pushed note!'); + sortedNotesList.push(daNote); + //notesDatas.push(daNote.noteData); + } + canMiss = true; + } + }); + sortedNotesList.sort((a, b) -> Std.int(a.strumTime - b.strumTime)); + + if (sortedNotesList.length > 0) { + for (epicNote in sortedNotesList) + { + for (doubleNote in pressNotes) { + if (Math.abs(doubleNote.strumTime - epicNote.strumTime) < 1) { + doubleNote.kill(); + notes.remove(doubleNote, true); + doubleNote.destroy(); + } else + notesStopped = true; + } + + // eee jack detection before was not super good + if (!notesStopped) { + goodNoteHit(epicNote); + pressNotes.push(epicNote); + } + + } + } + else if (canMiss && !FlxG.save.data.ghost) { + noteMiss(key); + } + + //more accurate hit time for the ratings? part 2 (Now that the calculations are done, go back to the time it was before for not causing a note stutter) + Conductor.songPosition = lastTime; + } + + var spr:StrumNote = playerStrums.members[key]; + if(spr != null && spr.animation.curAnim.name != 'confirm') + { + spr.playAnim('pressed'); + spr.resetAnim = 0; + } + } + } + + private function onKeyRelease(event:KeyboardEvent):Void + { + var eventKey:FlxKey = event.keyCode; + var key:Int = getKeyFromEvent(eventKey); + if(key > -1) + { + var spr:StrumNote = playerStrums.members[key]; + if(spr != null) + { + spr.playAnim('static'); + spr.resetAnim = 0; + } + } + //trace('released: ' + controlArray); + } + + public static function copyKey(arrayToCopy:Array):Array { + var copiedArray:Array = arrayToCopy.copy(); + var i:Int = 0; + var len:Int = copiedArray.length; + + while (i < len) { + if(copiedArray[i] == NONE) { + copiedArray.remove(NONE); + --i; + } + i++; + len = copiedArray.length; + } + return copiedArray; + } + + private function getKeyFromEvent(key:FlxKey):Int + { + if(key != NONE) + { + for (i in 0...keysArray.length) + { + for (j in 0...keysArray[i].length) + { + if(key == keysArray[i][j]) + { + return i; + } + } + } + } + return -1; + } + + private function keyShit():Void + { + // HOLDING + + var up = controls.UP; + var right = controls.RIGHT; + var down = controls.DOWN; + var left = controls.LEFT; + var controlHoldArray:Array = [left, down, up, right]; + + // TO DO: Find a better way to handle controller inputs, this should work for now + /*if(ClientPrefs.controllerMode) + { + var controlArray:Array = [controls.NOTE_LEFT_P, controls.NOTE_DOWN_P, controls.NOTE_UP_P, controls.NOTE_RIGHT_P]; + if(controlArray.contains(true)) + { + for (i in 0...controlArray.length) + { + if(controlArray[i]) + onKeyPress(new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, true, -1, keysArray[i][0])); + } + } + }*/ + + // FlxG.watch.addQuick('asdfa', upP); + if (generatedMusic) + { + // rewritten inputs??? + notes.forEachAlive(function(daNote:Note) + { + // hold note functions + if (daNote.isSustainNote && controlHoldArray[daNote.noteData] && daNote.canBeHit + && daNote.mustPress && !daNote.tooLate && !daNote.wasGoodHit) { + goodNoteHit(daNote); + } + }); + } + + // TO DO: Find a better way to handle controller inputs, this should work for now + /*if(ClientPrefs.controllerMode) + { + var controlArray:Array = [controls.NOTE_LEFT_R, controls.NOTE_DOWN_R, controls.NOTE_UP_R, controls.NOTE_RIGHT_R]; + if(controlArray.contains(true)) + { + for (i in 0...controlArray.length) + { + if(controlArray[i]) + onKeyRelease(new KeyboardEvent(KeyboardEvent.KEY_UP, true, true, -1, keysArray[i][0])); + } + } + }*/ + } + + var combo:Int = 0; + function goodNoteHit(note:Note):Void + { + if (!note.wasGoodHit) + { + switch(note.noteType) { + case 'Hurt Note': //Hurt note + noteMiss(note.noteData); + --songMisses; + if(!note.isSustainNote) { + //if(!note.noteSplashDisabled) { + spawnNoteSplashOnNote(note); + //} + } + + note.wasGoodHit = true; + vocals.volume = 0; + + if (!note.isSustainNote) + { + note.kill(); + notes.remove(note, true); + note.destroy(); + } + return; + } + + if (!note.isSustainNote) + { + popUpScore(note); + combo += 1; + songHits++; + if(combo > 9999) combo = 9999; + } + + playerStrums.forEach(function(spr:StrumNote) + { + if (Math.abs(note.noteData) == spr.ID) + { + spr.playAnim('confirm', true); + } + }); + + note.wasGoodHit = true; + vocals.volume = 1; + + if (!note.isSustainNote) + { + note.kill(); + notes.remove(note, true); + note.destroy(); + } + } + } + + function noteMiss(direction:Int = 1):Void + { + combo = 0; + + //songScore -= 10; + songMisses++; + + FlxG.sound.play(Paths.soundRandom('missnote', 1, 3), FlxG.random.float(0.1, 0.2)); + vocals.volume = 0; + } + + var COMBO_X:Float = 400; + var COMBO_Y:Float = 340; + private function popUpScore(note:Note = null):Void + { + var noteDiff:Float = Math.abs(note.strumTime - Conductor.songPosition); + + vocals.volume = 1; + + var placement:String = Std.string(combo); + + var coolText:FlxText = new FlxText(0, 0, 0, placement, 32); + coolText.x = COMBO_X; + coolText.y = COMBO_Y; + // + + var rating:FlxSprite = new FlxSprite(); + //var score:Int = 350; + + var daRating:String = "sick"; + + if (noteDiff > Conductor.safeZoneOffset * 0.75) + { + daRating = 'shit'; + //score = 50; + } + else if (noteDiff > Conductor.safeZoneOffset * 0.5) + { + daRating = 'bad'; + //score = 100; + } + else if (noteDiff > Conductor.safeZoneOffset * 0.25) + { + daRating = 'good'; + //score = 200; + } + + if(daRating == 'sick') + { + spawnNoteSplashOnNote(note); + } + //songScore += score; + + /* if (combo > 60) + daRating = 'sick'; + else if (combo > 12) + daRating = 'good' + else if (combo > 4) + daRating = 'bad'; + */ + + var pixelShitPart1:String = ""; + var pixelShitPart2:String = ''; + + if (isPixel) + { + pixelShitPart1 = 'pixelUI/'; + pixelShitPart2 = '-pixel'; + } + + rating.loadGraphic(Paths.image(pixelShitPart1 + daRating + pixelShitPart2)); + rating.screenCenter(); + rating.x = coolText.x - 40; + rating.y -= 60; + rating.acceleration.y = 550; + rating.velocity.y -= FlxG.random.int(140, 175); + rating.velocity.x -= FlxG.random.int(0, 10); + + var comboSpr:FlxSprite = new FlxSprite().loadGraphic(Paths.image(pixelShitPart1 + 'combo' + pixelShitPart2)); + comboSpr.screenCenter(); + comboSpr.x = coolText.x; + comboSpr.acceleration.y = 600; + comboSpr.velocity.y -= 150; + + comboSpr.velocity.x += FlxG.random.int(1, 10); + comboGroup.add(rating); + + if (!isPixel) + { + rating.setGraphicSize(Std.int(rating.width * 0.7)); + comboSpr.setGraphicSize(Std.int(comboSpr.width * 0.7)); + } + else + { + rating.setGraphicSize(Std.int(rating.width * PlayState.daPixelZoom * 0.85)); + comboSpr.setGraphicSize(Std.int(comboSpr.width * PlayState.daPixelZoom * 0.85)); + } + + comboSpr.updateHitbox(); + rating.updateHitbox(); + + var seperatedScore:Array = []; + + if(combo >= 1000) { + seperatedScore.push(Math.floor(combo / 1000) % 10); + } + seperatedScore.push(Math.floor(combo / 100) % 10); + seperatedScore.push(Math.floor(combo / 10) % 10); + seperatedScore.push(combo % 10); + + var daLoop:Int = 0; + for (i in seperatedScore) + { + var numScore:FlxSprite = new FlxSprite().loadGraphic(Paths.image(pixelShitPart1 + 'num' + Std.int(i) + pixelShitPart2)); + numScore.screenCenter(); + numScore.x = coolText.x + (43 * daLoop) - 90; + numScore.y += 80; + + if (!isPixel) + { + numScore.setGraphicSize(Std.int(numScore.width * 0.5)); + } + else + { + numScore.setGraphicSize(Std.int(numScore.width * PlayState.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); + + if (combo >= 10 || combo == 0) + insert(members.indexOf(strumLineNotes), numScore); + + FlxTween.tween(numScore, {alpha: 0}, 0.2, { + onComplete: function(tween:FlxTween) + { + numScore.destroy(); + }, + startDelay: Conductor.crochet * 0.002 + }); + + daLoop++; + } + /* + trace(combo); + trace(seperatedScore); + */ + + coolText.text = Std.string(seperatedScore); + // comboGroup.add(coolText); + + FlxTween.tween(rating, {alpha: 0}, 0.2, { + startDelay: Conductor.crochet * 0.001 + }); + + FlxTween.tween(comboSpr, {alpha: 0}, 0.2, { + onComplete: function(tween:FlxTween) + { + coolText.destroy(); + comboSpr.destroy(); + + rating.destroy(); + }, + startDelay: Conductor.crochet * 0.001 + }); + } + + private function generateStaticArrows(player:Int):Void + { + for (i in 0...4) + { + // FlxG.log.add(i); + var targetAlpha:Float = 1; + // if (player < 1 && ClientPrefs.middleScroll) targetAlpha = 0.35; + + var babyArrow:StrumNote = new StrumNote(42, strumLine.y, i, player, PlayState.SONG.noteStyle); + babyArrow.alpha = targetAlpha; + + if (babyArrow.pixelNotes.contains(babyArrow.daStyle)) + isPixel = false; + + if (player == 1) + { + playerStrums.add(babyArrow); + } + else + { + opponentStrums.add(babyArrow); + } + + strumLineNotes.add(babyArrow); + babyArrow.postAddedToGroup(); + } + } + + + // For Opponent's notes glow + function StrumPlayAnim(isDad:Bool, id:Int, time:Float) { + var spr:StrumNote = null; + if(isDad) { + spr = strumLineNotes.members[id]; + } else { + spr = playerStrums.members[id]; + } + + if(spr != null) { + spr.playAnim('confirm', true); + spr.resetAnim = time; + } + } + + + // Note splash shit, duh + function spawnNoteSplashOnNote(note:Note) { + if(note != null) { + var strum:StrumNote = playerStrums.members[note.noteData]; + if(strum != null) { + spawnNoteSplash(strum.x, strum.y, note.noteData, note); + } + } + } + + function spawnNoteSplash(x:Float, y:Float, data:Int, ?note:Note = null) { + var skin:String = ''; + /*if(PlayState.SONG.splashSkin != null && PlayState.SONG.splashSkin.length > 0) skin = PlayState.SONG.splashSkin; + + var hue:Float = ClientPrefs.arrowHSV[data % 4][0] / 360; + var sat:Float = ClientPrefs.arrowHSV[data % 4][1] / 100; + var brt:Float = ClientPrefs.arrowHSV[data % 4][2] / 100; + if(note != null) { + skin = note.noteSplashTexture; + hue = note.noteSplashHue; + sat = note.noteSplashSat; + brt = note.noteSplashBrt; + }*/ + + var splash:NoteSplash = grpNoteSplashes.recycle(NoteSplash); + splash.setupNoteSplash(x, y, data, skin); + grpNoteSplashes.add(splash); + } + + override function destroy() { + FlxG.sound.music.stop(); + vocals.stop(); + vocals.destroy(); + + /*if(!ClientPrefs.controllerMode) + { + FlxG.stage.removeEventListener(KeyboardEvent.KEY_DOWN, onKeyPress); + FlxG.stage.removeEventListener(KeyboardEvent.KEY_UP, onKeyRelease); + }*/ + super.destroy(); + } +} diff --git a/source/EtternaFunctions.hx b/source/EtternaFunctions.hx new file mode 100644 index 000000000..9fcfbaea9 --- /dev/null +++ b/source/EtternaFunctions.hx @@ -0,0 +1,84 @@ +class EtternaFunctions +{ + // erf constants + public static var a1 = 0.254829592; + public static var a2 = -0.284496736; + public static var a3 = 1.421413741; + public static var a4 = -1.453152027; + public static var a5 = 1.061405429; + public static var p = 0.3275911; + + public static function erf(x:Float):Float + { + // Save the sign of x + var sign = 1; + if (x < 0) + sign = -1; + x = Math.abs(x); + + // A&S formula 7.1.26 + var t = 1.0/(1.0 + p*x); + var y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*Math.exp(-x*x); + + return sign*y; + } + + public static function getNotes():Int + { + var notes:Int = 0; + for (i in 0...PlayState.SONG.notes.length) + { + for (ii in 0...PlayState.SONG.notes[i].sectionNotes.length) + { + var n = PlayState.SONG.notes[i].sectionNotes[ii]; + if (n[1] <= 0) + notes++; + } + } + return notes; + } + + public static function getHolds():Int + { + var notes:Int = 0; + for (i in 0...PlayState.SONG.notes.length) + { + trace(PlayState.SONG.notes[i]); + for (ii in 0...PlayState.SONG.notes[i].sectionNotes.length) + { + var n = PlayState.SONG.notes[i].sectionNotes[ii]; + trace(n); + if (n[1] > 0) + notes++; + } + } + return notes; + } + + public static function getMapMaxScore():Int + { + return (getNotes() * 350); + } + + public static function wife3(maxms:Float, ts:Float) + { + var max_points = 1.0; + var miss_weight = -5.5; + var ridic= 5 * ts; + var max_boo_weight = 180 * ts; + var ts_pow = 0.75; + var zero = 65 * (Math.pow(ts,ts_pow)); + var power = 2.5; + var dev = 22.7 * (Math.pow(ts,ts_pow)); + + if (maxms <= ridic) // anything below this (judge scaled) threshold is counted as full pts + return max_points; + else if (maxms <= zero) // ma/pa region, exponential + return max_points * erf((zero - maxms) / dev); + else if (maxms <= max_boo_weight)// cb region, linear + return (maxms - zero) * miss_weight / (max_boo_weight - zero); + else + return miss_weight; + } + +} \ No newline at end of file diff --git a/source/FlashingState.hx b/source/FlashingState.hx index 70c073522..8c5017b6a 100644 --- a/source/FlashingState.hx +++ b/source/FlashingState.hx @@ -33,10 +33,6 @@ class FlashingState extends MusicBeatState warnText.setFormat("VCR OSD Mono", 32, FlxColor.WHITE, CENTER); warnText.screenCenter(Y); add(warnText); - - #if mobileC - addVirtualPad(NONE, A_B); - #end } override function update(elapsed:Float) diff --git a/source/FlxVideo.hx b/source/FlxVideo.hx index 9149a78da..4281fb074 100644 --- a/source/FlxVideo.hx +++ b/source/FlxVideo.hx @@ -1,17 +1,27 @@ +#if web import openfl.net.NetConnection; import openfl.net.NetStream; import openfl.events.NetStatusEvent; import openfl.media.Video; +#else +import openfl.events.Event; +import vlc.VlcBitmap; +#end import flixel.FlxBasic; import flixel.FlxG; -class FlxVideo extends FlxBasic -{ +class FlxVideo extends FlxBasic { + #if VIDEOS_ALLOWED public var finishCallback:Void->Void = null; + + #if desktop + public static var vlcBitmap:VlcBitmap; + #end public function new(name:String) { super(); + #if web var player:Video = new Video(); player.x = 0; player.y = 0; @@ -35,5 +45,89 @@ class FlxVideo extends FlxBasic } }); netStream.play(name); + + #elseif desktop + // by Polybius, check out PolyEngine! https://github.com/polybiusproxy/PolyEngine + + vlcBitmap = new VlcBitmap(); + vlcBitmap.set_height(FlxG.stage.stageHeight); + vlcBitmap.set_width(FlxG.stage.stageHeight * (16 / 9)); + + vlcBitmap.onComplete = onVLCComplete; + vlcBitmap.onError = onVLCError; + + FlxG.stage.addEventListener(Event.ENTER_FRAME, fixVolume); + vlcBitmap.repeat = 0; + vlcBitmap.inWindow = false; + vlcBitmap.fullscreen = false; + fixVolume(null); + + FlxG.addChildBelowMouse(vlcBitmap); + vlcBitmap.play(checkFile(name)); + #end + } + + #if desktop + function checkFile(fileName:String):String + { + var pDir = ""; + var appDir = "file:///" + Sys.getCwd() + "/"; + + if (fileName.indexOf(":") == -1) // Not a path + pDir = appDir; + else if (fileName.indexOf("file://") == -1 || fileName.indexOf("http") == -1) // C:, D: etc? ..missing "file:///" ? + pDir = "file:///"; + + return pDir + fileName; + } + + public static function onFocus() { + if(vlcBitmap != null) { + vlcBitmap.resume(); + } } + + public static function onFocusLost() { + if(vlcBitmap != null) { + vlcBitmap.pause(); + } + } + + function fixVolume(e:Event) + { + // shitty volume fix + vlcBitmap.volume = 0; + if(!FlxG.sound.muted && FlxG.sound.volume > 0.01) { //Kind of fixes the volume being too low when you decrease it + vlcBitmap.volume = FlxG.sound.volume * 0.5 + 0.5; + } + } + + public function onVLCComplete() + { + vlcBitmap.stop(); + + // Clean player, just in case! + vlcBitmap.dispose(); + + if (FlxG.game.contains(vlcBitmap)) + { + FlxG.game.removeChild(vlcBitmap); + } + + if (finishCallback != null) + { + finishCallback(); + } + } + + + function onVLCError() + { + trace("An error has occured while trying to load the video.\nPlease, check if the file you're loading exists."); + if (finishCallback != null) { + finishCallback(); + } + } + #end + #end } \ No newline at end of file diff --git a/source/FreeplayState.hx b/source/FreeplayState.hx index 977e87009..c88c52dff 100644 --- a/source/FreeplayState.hx +++ b/source/FreeplayState.hx @@ -1,27 +1,29 @@ package; -#if desktop -import Discord.DiscordClient; -#end -import editors.ChartingState; import flash.text.TextField; import flixel.FlxG; import flixel.FlxSprite; import flixel.addons.display.FlxGridOverlay; -import flixel.addons.transition.FlxTransitionableState; import flixel.group.FlxGroup.FlxTypedGroup; import flixel.math.FlxMath; import flixel.text.FlxText; import flixel.util.FlxColor; -import flixel.tweens.FlxTween; import lime.utils.Assets; -import flixel.system.FlxSound; -import openfl.utils.Assets as OpenFlAssets; + + +#if windows +import Discord.DiscordClient; +#end + import WeekData; -#if MODS_ALLOWED +#if desktop import sys.FileSystem; #end +import flixel.effects.FlxFlicker; +import flixel.tweens.FlxTween; +import flixel.util.FlxTimer; + using StringTools; class FreeplayState extends MusicBeatState @@ -29,17 +31,15 @@ class FreeplayState extends MusicBeatState var songs:Array = []; var selector:FlxText; - private static var curSelected:Int = 0; + var curSelected:Int = 0; var curDifficulty:Int = -1; - private static var lastDifficultyName:String = ''; - var scoreBG:FlxSprite; var scoreText:FlxText; + var comboText:FlxText; var diffText:FlxText; var lerpScore:Int = 0; - var lerpRating:Float = 0; var intendedScore:Int = 0; - var intendedRating:Float = 0; + var combo:String = ''; private var grpSongs:FlxTypedGroup; private var curPlaying:Bool = false; @@ -49,20 +49,17 @@ class FreeplayState extends MusicBeatState var bg:FlxSprite; var intendedColor:Int; var colorTween:FlxTween; + public var canMove:Bool; + private static var lastDifficultyName:String = ''; override function create() { - #if MODS_ALLOWED - Paths.destroyLoadedImages(); - #end - - PlayState.isStoryMode = false; - WeekData.reloadWeekFiles(false); + Paths.clearStoredMemory(); + Paths.clearUnusedMemory(); + WeekData.reloadWeekFiles(false, 0); + canMove = true; - #if desktop - // Updating Discord Rich Presence - DiscordClient.changePresence("In the Menus", null); - #end + PlayState.isStoryMode = false; for (i in 0...WeekData.weeksList.length) { var leWeek:WeekData = WeekData.weeksLoaded.get(WeekData.weeksList[i]); @@ -87,27 +84,57 @@ class FreeplayState extends MusicBeatState } WeekData.setDirectoryFromWeek(); - /* //KIND OF BROKEN NOW AND ALSO PRETTY USELESS// + /*var initSonglist = CoolUtil.coolTextFile(Paths.txt('freeplaySonglist')); - var initSonglist = CoolUtil.coolTextFile(Main.getDataPath() + Paths.txt('freeplaySonglist')); for (i in 0...initSonglist.length) { - if(initSonglist[i] != null && initSonglist[i].length > 0) { - var songArray:Array = initSonglist[i].split(":"); - addSong(songArray[0], 0, songArray[1], Std.parseInt(songArray[2])); + var data:Array = initSonglist[i].split(':'); + songs.push(new SongMetadata(data[0], Std.parseInt(data[2]), data[1])); + } + + if (FlxG.sound.music != null) + { + if (!FlxG.sound.music.playing) + FlxG.sound.playMusic(Paths.music('freakyMenu')); } - }*/ + */ + + if (FlxG.sound.music.volume == 0) + { + FlxG.sound.music.volume = 1; + FlxG.sound.playMusic(Paths.music('freakyMenu')); + } + + #if windows + // Updating Discord Rich Presence + DiscordClient.changePresence("In the Freeplay Menu", null); + #end + + var isDebug:Bool = false; + + #if debug + isDebug = true; + #end + + // LOAD MUSIC + + // LOAD CHARACTERS bg = new FlxSprite().loadGraphic(Paths.image('menuDesat')); - bg.antialiasing = ClientPrefs.globalAntialiasing; add(bg); grpSongs = new FlxTypedGroup(); add(grpSongs); + if (songs.length < 1) + { + addSong('tutorial', 0, 'gf', FlxColor.WHITE); + trace('fuck'); + } + for (i in 0...songs.length) { - var songText:Alphabet = new Alphabet(0, (70 * i) + 30, songs[i].songName, true, false); + var songText:Alphabet = new Alphabet(0, (70 * i) + 30, songs[i].songName, true); songText.isMenuItem = true; songText.targetY = i; grpSongs.add(songText); @@ -124,12 +151,15 @@ class FreeplayState extends MusicBeatState // DONT PUT X IN THE FIRST PARAMETER OF new ALPHABET() !! // songText.screenCenter(X); } + WeekData.setDirectoryFromWeek(); scoreText = new FlxText(FlxG.width * 0.7, 5, 0, "", 32); + // scoreText.autoSize = false; scoreText.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, RIGHT); + // scoreText.alignment = RIGHT; - scoreBG = new FlxSprite(scoreText.x - 6, 0).makeGraphic(1, 66, 0xFF000000); + var scoreBG:FlxSprite = new FlxSprite(scoreText.x - 6, 0).makeGraphic(Std.int(FlxG.width * 0.35), 66, 0xFF000000); scoreBG.alpha = 0.6; add(scoreBG); @@ -137,6 +167,10 @@ class FreeplayState extends MusicBeatState diffText.font = scoreText.font; add(diffText); + comboText = new FlxText(diffText.x + 100, diffText.y, 0, "", 24); + comboText.font = diffText.font; + add(comboText); + add(scoreText); if(curSelected >= songs.length) curSelected = 0; @@ -148,10 +182,18 @@ class FreeplayState extends MusicBeatState lastDifficultyName = CoolUtil.defaultDifficulty; } curDifficulty = Math.round(Math.max(0, CoolUtil.defaultDifficulties.indexOf(lastDifficultyName))); - + changeSelection(); changeDiff(); + // FlxG.sound.playMusic(Paths.music('title'), 0); + // FlxG.sound.music.fadeIn(2, 0, 0.8); + selector = new FlxText(); + + selector.size = 40; + selector.text = ">"; + // add(selector); + var swag:Alphabet = new Alphabet(1, 0, "swag"); // JUST DOIN THIS SHIT FOR TESTING!!! @@ -171,206 +213,122 @@ class FreeplayState extends MusicBeatState trace(md); */ - var textBG:FlxSprite = new FlxSprite(0, FlxG.height - 26).makeGraphic(FlxG.width, 26, 0xFF000000); - textBG.alpha = 0.6; - add(textBG); - - #if desktop - #if PRELOAD_ALL - var leText:String = "Press SPACE to listen to the Song / Press CTRL to open the Gameplay Changers Menu / Press RESET to Reset your Score and Accuracy."; - var size:Int = 16; - #else - var leText:String = "Press CTRL to open the Gameplay Changers Menu / Press RESET to Reset your Score and Accuracy."; - var size:Int = 18; - #end - #else - #if PRELOAD_ALL - var leText:String = "Press X to listen to the Song / Press RED to open the Gameplay Changers Menu / Press Y to Reset your Score and Accuracy."; - var size:Int = 16; - #else - var leText:String = "Press RED to open the Gameplay Changers Menu / Press Y to Reset your Score and Accuracy."; - var size:Int = 18; - #end - #end - - var text:FlxText = new FlxText(textBG.x, textBG.y + 4, FlxG.width, leText, size); - text.setFormat(Paths.font("vcr.ttf"), size, FlxColor.WHITE, RIGHT); - text.scrollFactor.set(); - add(text); - - #if mobileC - addVirtualPad(FULL, A_B_X_Y_D); - #end - super.create(); } - override function closeSubState() { - changeSelection(0, false); - super.closeSubState(); - } - public function addSong(songName:String, weekNum:Int, songCharacter:String, color:Int) { songs.push(new SongMetadata(songName, weekNum, songCharacter, color)); } - /*public function addWeek(songs:Array, weekNum:Int, weekColor:Int, ?songCharacters:Array) + /*public function addWeek(songs:Array, weekNum:Int, ?songCharacters:Array) { if (songCharacters == null) - songCharacters = ['bf']; + songCharacters = ['dad']; var num:Int = 0; for (song in songs) { addSong(song, weekNum, songCharacters[num]); - this.songs[this.songs.length-1].color = weekColor; if (songCharacters.length != 1) num++; } }*/ - var instPlaying:Int = -1; - private static var vocals:FlxSound = null; override function update(elapsed:Float) { + super.update(elapsed); + if (FlxG.sound.music.volume < 0.7) { FlxG.sound.music.volume += 0.5 * FlxG.elapsed; } - lerpScore = Math.floor(FlxMath.lerp(lerpScore, intendedScore, CoolUtil.boundTo(elapsed * 24, 0, 1))); - lerpRating = FlxMath.lerp(lerpRating, intendedRating, CoolUtil.boundTo(elapsed * 12, 0, 1)); + lerpScore = Math.floor(FlxMath.lerp(lerpScore, intendedScore, 0.4)); if (Math.abs(lerpScore - intendedScore) <= 10) lerpScore = intendedScore; - if (Math.abs(lerpRating - intendedRating) <= 0.01) - lerpRating = intendedRating; - - var ratingSplit:Array = Std.string(Highscore.floorDecimal(lerpRating * 100, 2)).split('.'); - if(ratingSplit.length < 2) { //No decimals, add an empty space - ratingSplit.push(''); - } - - while(ratingSplit[1].length < 2) { //Less than 2 decimals in it, add decimals then - ratingSplit[1] += '0'; - } - scoreText.text = 'PERSONAL BEST: ' + lerpScore + ' (' + ratingSplit.join('.') + '%)'; - positionHighscore(); + scoreText.text = "PERSONAL BEST:" + lerpScore; + comboText.text = combo + '\n'; - var upP = controls.UI_UP_P; - var downP = controls.UI_DOWN_P; + var upP = controls.UP_P; + var downP = controls.DOWN_P; var accepted = controls.ACCEPT; - var space = FlxG.keys.justPressed.SPACE#if mobileC || _virtualpad.buttonX.justPressed #end; - var ctrl = FlxG.keys.justPressed.CONTROL#if mobileC || _virtualpad.buttonD.justPressed #end; var shiftMult:Int = 1; if(FlxG.keys.pressed.SHIFT) shiftMult = 3; - if (upP) - { + if (upP && canMove) changeSelection(-shiftMult); - } - if (downP) - { + if (downP && canMove) changeSelection(shiftMult); - } - if (controls.UI_LEFT_P) + if (controls.LEFT_P && canMove) changeDiff(-1); - else if (controls.UI_RIGHT_P) + if (controls.RIGHT_P && canMove) changeDiff(1); - else if (upP || downP) changeDiff(); if (controls.BACK) { if(colorTween != null) { colorTween.cancel(); } - FlxG.sound.play(Paths.sound('cancelMenu')); - MusicBeatState.switchState(new MainMenuState()); + FlxG.switchState(new MainMenuState()); } - if(ctrl) - { - openSubState(new GameplayChangersSubstate()); - } - else if(space) + if (accepted && canMove) { - if(instPlaying != curSelected) - { - #if PRELOAD_ALL - destroyFreeplayVocals(); - FlxG.sound.music.volume = 0; - Paths.currentModDirectory = songs[curSelected].folder; - var poop:String = Highscore.formatSong(songs[curSelected].songName.toLowerCase(), curDifficulty); - PlayState.SONG = Song.loadFromJson(poop, songs[curSelected].songName.toLowerCase()); - if (PlayState.SONG.needsVoices) - vocals = new FlxSound().loadEmbedded(Paths.voices(PlayState.SONG.song)); - else - vocals = new FlxSound(); - - FlxG.sound.list.add(vocals); - FlxG.sound.playMusic(Paths.inst(PlayState.SONG.song), 0.7); - vocals.play(); - vocals.persist = true; - vocals.looped = true; - vocals.volume = 0.7; - instPlaying = curSelected; - #end + canMove = false; + + // adjusting the song name to be compatible + var songFormat = StringTools.replace(songs[curSelected].songName, " ", "-"); + switch (songFormat) { + case 'Dad-Battle': songFormat = 'Dadbattle'; + case 'Philly-Nice': songFormat = 'Philly'; } - } + + trace(songs[curSelected].songName); - else if (accepted) - { - var songLowercase:String = Paths.formatToSongPath(songs[curSelected].songName); - var poop:String = Highscore.formatSong(songLowercase, curDifficulty); - /*#if MODS_ALLOWED - if(!sys.FileSystem.exists(Paths.modsJson(songLowercase + '/' + poop)) && !sys.FileSystem.exists(Paths.json(songLowercase + '/' + poop))) { - #else - if(!OpenFlAssets.exists(Paths.json(songLowercase + '/' + poop))) { - #end - poop = songLowercase; - curDifficulty = 1; - trace('Couldnt find file'); - }*/ - trace(poop); + var poop:String = Highscore.formatSong(songFormat, curDifficulty); - PlayState.SONG = Song.loadFromJson(poop, songLowercase); + trace(poop); + + PlayState.SONG = Song.loadFromJson(poop, songs[curSelected].songName); PlayState.isStoryMode = false; + PlayState.isBETADCIU = false; + PlayState.isBonus = false; + PlayState.isVitor = false; + PlayState.isNeonight = false; PlayState.storyDifficulty = curDifficulty; - - trace('CURRENT WEEK: ' + WeekData.getWeekFileName()); + PlayState.storyWeek = songs[curSelected].week; + trace('CUR WEEK' + PlayState.storyWeek); if(colorTween != null) { colorTween.cancel(); } - - if (FlxG.keys.pressed.SHIFT){ - LoadingState.loadAndSwitchState(new ChartingState()); - }else{ - LoadingState.loadAndSwitchState(new PlayState()); - } - FlxG.sound.music.volume = 0; + var llll = FlxG.sound.play(Paths.sound('confirmMenu')).length; + grpSongs.forEach(function(e:Alphabet){ + if (e.text != songs[curSelected].songName){ + FlxTween.tween(e, {x: -6000}, llll / 1000,{onComplete:function(e:FlxTween){ - destroyFreeplayVocals(); - } - else if(controls.RESET #if mobileC || _virtualpad.buttonY.justPressed #end) - { - openSubState(new ResetScoreSubState(songs[curSelected].songName, curDifficulty, songs[curSelected].songCharacter)); - FlxG.sound.play(Paths.sound('scrollMenu')); - } - super.update(elapsed); - } - - public static function destroyFreeplayVocals() { - if(vocals != null) { - vocals.stop(); - vocals.destroy(); + if (FlxG.keys.pressed.ALT){ + FlxG.switchState(new ChartingState()); + }else{ + if (Main.hiddenSongs.contains(songs[curSelected].songName.toLowerCase()) && !Main.isHidden || PlayState.SONG.song == 'Restore' && !Main.restoreUnlocked || PlayState.SONG.song == 'Deathmatch-Holo' && !Main.deathHolo) + LoadingState.loadAndSwitchState(new GoFindTheSecretState()); + else + LoadingState.loadAndSwitchState(new PlayState()); + } + }}); + }else{ + FlxFlicker.flicker(e); + trace(curSelected); + FlxTween.tween(e, {x: e.x + 20}, llll/1000); + } + }); } - vocals = null; } function changeDiff(change:Int = 0) @@ -384,19 +342,31 @@ class FreeplayState extends MusicBeatState lastDifficultyName = CoolUtil.difficulties[curDifficulty]; + // adjusting the highscore song name to be compatible (changeDiff) + var songHighscore = StringTools.replace(songs[curSelected].songName, " ", "-"); + switch (songHighscore) { + case 'Dad-Battle': songHighscore = 'Dadbattle'; + case 'Philly-Nice': songHighscore = 'Philly'; + } + + #if !switch - intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty); - intendedRating = Highscore.getRating(songs[curSelected].songName, curDifficulty); + intendedScore = Highscore.getScore(songHighscore, curDifficulty); + combo = Highscore.getCombo(songHighscore, curDifficulty); #end PlayState.storyDifficulty = curDifficulty; - diffText.text = '< ' + CoolUtil.difficultyString() + ' >'; - positionHighscore(); + diffText.text = '< ' + CoolUtil.difficultyString2() + ' >'; } - function changeSelection(change:Int = 0, playSound:Bool = true) + function changeSelection(change:Int = 0) { - if(playSound) FlxG.sound.play(Paths.sound('scrollMenu'), 0.4); + #if !switch + // NGio.logEvent('Fresh'); + #end + + // NGio.logEvent('Fresh'); + FlxG.sound.play(Paths.sound('scrollMenu'), 0.4); curSelected += change; @@ -404,25 +374,21 @@ class FreeplayState extends MusicBeatState curSelected = songs.length - 1; if (curSelected >= songs.length) curSelected = 0; - - var newColor:Int = songs[curSelected].color; - if(newColor != intendedColor) { - if(colorTween != null) { - colorTween.cancel(); - } - intendedColor = newColor; - colorTween = FlxTween.color(bg, 1, bg.color, intendedColor, { - onComplete: function(twn:FlxTween) { - colorTween = null; - } - }); - } // selector.y = (70 * curSelected) + 30; + + // adjusting the highscore song name to be compatible (changeSelection) + // would read original scores if we didn't change packages + var songHighscore = StringTools.replace(songs[curSelected].songName, " ", "-"); + switch (songHighscore) { + case 'Dad-Battle': songHighscore = 'Dadbattle'; + case 'Philly-Nice': songHighscore = 'Philly'; + } #if !switch - intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty); - intendedRating = Highscore.getRating(songs[curSelected].songName, curDifficulty); + intendedScore = Highscore.getScore(songHighscore, curDifficulty); + combo = Highscore.getCombo(songHighscore, curDifficulty); + // lerpScore = 0; #end var bullShit:Int = 0; @@ -448,10 +414,9 @@ class FreeplayState extends MusicBeatState // item.setGraphicSize(Std.int(item.width)); } } - - Paths.currentModDirectory = songs[curSelected].folder; - PlayState.storyWeek = songs[curSelected].week; + Paths.currentModDirectory = songs[curSelected].folder; + CoolUtil.difficulties = CoolUtil.defaultDifficulties.copy(); var diffStr:String = WeekData.getCurrentWeek().difficulties; if(diffStr != null) diffStr = diffStr.trim(); //Fuck you HTML5 @@ -483,15 +448,19 @@ class FreeplayState extends MusicBeatState { curDifficulty = newPos; } - } - private function positionHighscore() { - scoreText.x = FlxG.width - scoreText.width - 6; - - scoreBG.scale.x = FlxG.width - scoreText.x + 6; - scoreBG.x = FlxG.width - (scoreBG.scale.x / 2); - diffText.x = Std.int(scoreBG.x + (scoreBG.width / 2)); - diffText.x -= diffText.width / 2; + var newColor:Int = songs[curSelected].color; + if(newColor != intendedColor) { + if(colorTween != null) { + colorTween.cancel(); + } + intendedColor = newColor; + colorTween = FlxTween.color(bg, 1, bg.color, intendedColor, { + onComplete: function(twn:FlxTween) { + colorTween = null; + } + }); + } } } @@ -503,7 +472,7 @@ class SongMetadata public var color:Int = -7179779; public var folder:String = ""; - public function new(song:String, week:Int, songCharacter:String, color:Int) + public function new(song:String, week:Int, songCharacter:String, ?color:Int) { this.songName = song; this.week = week; @@ -512,4 +481,4 @@ class SongMetadata this.folder = Paths.currentModDirectory; if(this.folder == null) this.folder = ''; } -} \ No newline at end of file +} diff --git a/source/FunkinLua.hx b/source/FunkinLua.hx index 98b5cf4bd..7b6fdb474 100644 --- a/source/FunkinLua.hx +++ b/source/FunkinLua.hx @@ -5,7 +5,9 @@ import llua.State; import llua.Convert; #end +import animateatlas.AtlasFrameMaker; import flixel.FlxG; +import flixel.addons.effects.FlxTrail; import flixel.input.keyboard.FlxKey; import flixel.tweens.FlxTween; import flixel.tweens.FlxEase; @@ -20,9 +22,12 @@ import flixel.util.FlxColor; import flixel.FlxBasic; import flixel.FlxObject; import flixel.FlxSprite; +import openfl.Lib; import openfl.display.BlendMode; import openfl.utils.Assets; import flixel.math.FlxMath; +import Shaders; +import flixel.addons.transition.FlxTransitionableState; #if sys import sys.FileSystem; import sys.io.File; @@ -38,8 +43,8 @@ import Discord; using StringTools; class FunkinLua { - public static var Function_Stop = "Function_Stop"; - public static var Function_Continue = "Function_Continue"; + public static var Function_Stop = 1; + public static var Function_Continue = 0; #if LUA_ALLOWED public var lua:State = null; @@ -76,8 +81,8 @@ class FunkinLua { #end // Lua shit - set('Function_Stop', "Function_Stop"); - set('Function_Continue', "Function_Continue"); + set('Function_Stop', Function_Stop); + set('Function_Continue', Function_Continue); set('luaDebugMode', false); set('luaDeprecatedWarnings', true); set('inChartEditor', false); @@ -97,6 +102,11 @@ class FunkinLua { set('weekRaw', PlayState.storyWeek); set('week', WeekData.weeksList[PlayState.storyWeek]); set('seenCutscene', PlayState.seenCutscene); + + + // Block require and os, Should probably have a proper function but this should be good enough for now until someone smarter comes along and recreates a safe version of the OS library + set('require', false); + set('os', false); // Camera poo set('cameraX', 0); @@ -173,7 +183,7 @@ class FunkinLua { cervix = Paths.modFolders(cervix); doPush = true; } else { - cervix = Main.getDataPath() + Paths.getPreloadPath(cervix); + cervix = Paths.getPreloadPath(cervix); if(FileSystem.exists(cervix)) { doPush = true; } @@ -197,45 +207,67 @@ class FunkinLua { } luaTrace("Script doesn't exist!"); }); + Lua_helper.add_callback(lua, "removeLuaScript", function(luaFile:String, ?ignoreAlreadyRunning:Bool = false) { //would be dope asf. + var cervix = luaFile + ".lua"; + var doPush = false; + if(FileSystem.exists(Paths.modFolders(cervix))) { + cervix = Paths.modFolders(cervix); + doPush = true; + } else { + cervix = Paths.getPreloadPath(cervix); + if(FileSystem.exists(cervix)) { + doPush = true; + } + } + + if(doPush) + { + if(!ignoreAlreadyRunning) + { + for (luaInstance in PlayState.instance.luaArray) + { + if(luaInstance.scriptName == cervix) + { + //luaTrace('The script "' + cervix + '" is already running!'); + + PlayState.instance.luaArray.remove(luaInstance); + return; + } + } + } + return; + } + luaTrace("Script doesn't exist!"); + }); //stuff 4 noobz like you B) - + + Lua_helper.add_callback(lua, "loadGraphic", function(variable:String, image:String) { + var spr:FlxSprite = getObjectDirectly(variable); + if(spr != null && image != null && image.length > 0) + { + spr.loadGraphic(Paths.image(image)); + } + }); + Lua_helper.add_callback(lua, "loadFrames", function(variable:String, image:String, spriteType:String = "sparrow") { + var spr:FlxSprite = getObjectDirectly(variable); + if(spr != null && image != null && image.length > 0) + { + loadFrames(spr, image, spriteType); + } + }); Lua_helper.add_callback(lua, "getProperty", function(variable:String) { var killMe:Array = variable.split('.'); if(killMe.length > 1) { - var coverMeInPiss:Dynamic = null; - if(PlayState.instance.modchartSprites.exists(killMe[0])) { - coverMeInPiss = PlayState.instance.modchartSprites.get(killMe[0]); - } else if(PlayState.instance.modchartTexts.exists(killMe[0])) { - coverMeInPiss = PlayState.instance.modchartTexts.get(killMe[0]); - } else { - coverMeInPiss = Reflect.getProperty(getInstance(), killMe[0]); - } - - for (i in 1...killMe.length-1) { - coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); - } - return Reflect.getProperty(coverMeInPiss, killMe[killMe.length-1]); + return Reflect.getProperty(getPropertyLoopThingWhatever(killMe), killMe[killMe.length-1]); } return Reflect.getProperty(getInstance(), variable); }); Lua_helper.add_callback(lua, "setProperty", function(variable:String, value:Dynamic) { var killMe:Array = variable.split('.'); if(killMe.length > 1) { - var coverMeInPiss:Dynamic = null; - if(PlayState.instance.modchartSprites.exists(killMe[0])) { - coverMeInPiss = PlayState.instance.modchartSprites.get(killMe[0]); - } else if(PlayState.instance.modchartTexts.exists(killMe[0])) { - coverMeInPiss = PlayState.instance.modchartTexts.get(killMe[0]); - } else { - coverMeInPiss = Reflect.getProperty(getInstance(), killMe[0]); - } - - for (i in 1...killMe.length-1) { - coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); - } - return Reflect.setProperty(coverMeInPiss, killMe[killMe.length-1], value); + return Reflect.setProperty(getPropertyLoopThingWhatever(killMe), killMe[killMe.length-1], value); } return Reflect.setProperty(getInstance(), variable, value); }); @@ -465,6 +497,34 @@ class FunkinLua { })); } }); + Lua_helper.add_callback(lua, "noteTweenAngle", function(tag:String, note:Int, value:Dynamic, duration:Float, ease:String) { + cancelTween(tag); + if(note < 0) note = 0; + var testicle:StrumNote = PlayState.instance.strumLineNotes.members[note % PlayState.instance.strumLineNotes.length]; + + if(testicle != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(testicle, {angle: value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } + }); + Lua_helper.add_callback(lua, "noteTweenDirection", function(tag:String, note:Int, value:Dynamic, duration:Float, ease:String) { + cancelTween(tag); + if(note < 0) note = 0; + var testicle:StrumNote = PlayState.instance.strumLineNotes.members[note % PlayState.instance.strumLineNotes.length]; + + if(testicle != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(testicle, {direction: value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } + }); Lua_helper.add_callback(lua, "mouseClicked", function(button:String) { var boobs = FlxG.mouse.justPressed; switch(button){ @@ -662,13 +722,14 @@ class FunkinLua { PlayState.instance.addCharacterToList(name, charType); }); Lua_helper.add_callback(lua, "precacheImage", function(name:String) { - #if MODS_ALLOWED - Paths.addCustomGraphic(name); - #end + Paths.returnGraphic(name); }); Lua_helper.add_callback(lua, "precacheSound", function(name:String) { CoolUtil.precacheSound(name); }); + Lua_helper.add_callback(lua, "precacheMusic", function(name:String) { + CoolUtil.precacheMusic(name); + }); Lua_helper.add_callback(lua, "triggerEvent", function(name:String, arg1:Dynamic, arg2:Dynamic) { var value1:String = arg1; var value2:String = arg2; @@ -683,6 +744,32 @@ class FunkinLua { PlayState.instance.KillNotes(); PlayState.instance.endSong(); }); + Lua_helper.add_callback(lua, "restartSong", function(skipTransition:Bool) { + PlayState.instance.persistentUpdate = false; + PauseSubState.restartSong(skipTransition); + }); + Lua_helper.add_callback(lua, "exitSong", function(skipTransition:Bool) { + if(skipTransition) + { + FlxTransitionableState.skipNextTransIn = true; + FlxTransitionableState.skipNextTransOut = true; + } + + PlayState.cancelMusicFadeTween(); + CustomFadeTransition.nextCamera = PlayState.instance.camOther; + if(FlxTransitionableState.skipNextTransIn) + CustomFadeTransition.nextCamera = null; + + if(PlayState.isStoryMode) + MusicBeatState.switchState(new StoryMenuState()); + else + MusicBeatState.switchState(new FreeplayState()); + + FlxG.sound.playMusic(Paths.music('freakyMenu')); + PlayState.changedDifficulty = false; + PlayState.chartingMode = false; + PlayState.instance.transitioning = true; + }); Lua_helper.add_callback(lua, "getSongPosition", function() { return Conductor.songPosition; }); @@ -737,6 +824,17 @@ class FunkinLua { Lua_helper.add_callback(lua, "cameraShake", function(camera:String, intensity:Float, duration:Float) { cameraFromString(camera).shake(intensity, duration); }); + + Lua_helper.add_callback(lua, "cameraFlash", function(camera:String, color:String, duration:Float,forced:Bool) { + var colorNum:Int = Std.parseInt(color); + if(!color.startsWith('0x')) colorNum = Std.parseInt('0xff' + color); + cameraFromString(camera).flash(colorNum, duration,null,forced); + }); + Lua_helper.add_callback(lua, "cameraFade", function(camera:String, color:String, duration:Float,forced:Bool) { + var colorNum:Int = Std.parseInt(color); + if(!color.startsWith('0x')) colorNum = Std.parseInt('0xff' + color); + cameraFromString(camera).fade(colorNum, duration,false,null,forced); + }); Lua_helper.add_callback(lua, "setRatingPercent", function(value:Float) { PlayState.instance.ratingPercent = value; }); @@ -779,18 +877,20 @@ class FunkinLua { tag = tag.replace('.', ''); resetSpriteTag(tag); var leSprite:ModchartSprite = new ModchartSprite(x, y); - if(image != null && image.length > 0) { + if(image != null && image.length > 0) + { leSprite.loadGraphic(Paths.image(image)); } leSprite.antialiasing = ClientPrefs.globalAntialiasing; PlayState.instance.modchartSprites.set(tag, leSprite); leSprite.active = true; }); - Lua_helper.add_callback(lua, "makeAnimatedLuaSprite", function(tag:String, image:String, x:Float, y:Float) { + Lua_helper.add_callback(lua, "makeAnimatedLuaSprite", function(tag:String, image:String, x:Float, y:Float, ?spriteType:String = "sparrow") { tag = tag.replace('.', ''); resetSpriteTag(tag); var leSprite:ModchartSprite = new ModchartSprite(x, y); - leSprite.frames = Paths.getSparrowAtlas(image); + + loadFrames(leSprite, image, spriteType); leSprite.antialiasing = ClientPrefs.globalAntialiasing; PlayState.instance.modchartSprites.set(tag, leSprite); }); @@ -950,6 +1050,13 @@ class FunkinLua { } luaTrace('Couldnt find object: ' + obj); }); + Lua_helper.add_callback(lua, "updateHitboxFromGroup", function(group:String, index:Int) { + if(Std.isOfType(Reflect.getProperty(getInstance(), group), FlxTypedGroup)) { + Reflect.getProperty(getInstance(), group).members[index].updateHitbox(); + return; + } + Reflect.getProperty(getInstance(), group)[index].updateHitbox(); + }); Lua_helper.add_callback(lua, "removeLuaSprite", function(tag:String, destroy:Bool = true) { if(!PlayState.instance.modchartSprites.exists(tag)) { return; @@ -1030,6 +1137,45 @@ class FunkinLua { } luaTrace("Object " + obj + " doesn't exist!"); }); + Lua_helper.add_callback(lua, "isColliding", function(obj1:String, obj2:String) { + var namesArray:Array = [obj1, obj2]; + var objectsArray:Array = []; + for (i in 0...namesArray.length) + { + if(PlayState.instance.modchartSprites.exists(namesArray[i])) { + objectsArray.push(PlayState.instance.modchartSprites.get(namesArray[i])); + } + else if(PlayState.instance.modchartTexts.exists(namesArray[i])) { + objectsArray.push(PlayState.instance.modchartTexts.get(namesArray[i])); + } + else { + objectsArray.push(Reflect.getProperty(getInstance(), namesArray[i])); + } + } + + if(!objectsArray.contains(null)) + { + return FlxG.collide(objectsArray[0], objectsArray[1]); + } + return false; + }); + Lua_helper.add_callback(lua, "getPixelColor", function(obj:String, x:Int, y:Int) { + var spr:FlxSprite = null; + if(PlayState.instance.modchartSprites.exists(obj)) { + spr = PlayState.instance.modchartSprites.get(obj); + } else if(PlayState.instance.modchartTexts.exists(obj)) { + spr = PlayState.instance.modchartTexts.get(obj); + } else { + spr = Reflect.getProperty(getInstance(), obj); + } + + if(spr != null) + { + if(spr.framePixels != null) spr.framePixels.getPixel32(x, y); + return spr.pixels.getPixel32(x, y); + } + return 0; + }); Lua_helper.add_callback(lua, "getRandomInt", function(min:Int, max:Int = FlxMath.MAX_VALUE_INT, exclude:String = '') { var excludeArray:Array = exclude.split(','); var toExclude:Array = []; @@ -1076,19 +1222,19 @@ class FunkinLua { } }); Lua_helper.add_callback(lua, "startVideo", function(videoFile:String) { + #if VIDEOS_ALLOWED if(FileSystem.exists(Paths.video(videoFile))) { PlayState.instance.startVideo(videoFile); } else { luaTrace('Video file not found: ' + videoFile); } - }); - - Lua_helper.add_callback(lua, "videoBG", function(videoFile:String) { //shit for videobg in luas (sirox) - if(FileSystem.exists(Paths.video(videoFile))) { - PlayState.instance.videoBG(videoFile); + #else + if(PlayState.instance.endingSong) { + PlayState.instance.endSong(); } else { - luaTrace('Video file not found: ' + videoFile); + PlayState.instance.startCountdown(); } + #end }); Lua_helper.add_callback(lua, "playMusic", function(sound:String, volume:Float = 1, loop:Bool = false) { @@ -1200,11 +1346,9 @@ class FunkinLua { Lua_helper.add_callback(lua, "close", function(printMessage:Bool) { if(!gonnaClose) { if(printMessage) { - luaTrace('Stopping lua script in 100ms: ' + scriptName); + luaTrace('Stopping lua script: ' + scriptName); } - new FlxTimer().start(0.1, function(tmr:FlxTimer) { - stop(); - }); + PlayState.instance.closeLuas.push(this); } gonnaClose = true; }); @@ -1463,10 +1607,81 @@ class FunkinLua { FlxG.sound.music.fadeOut(duration, toValue); luaTrace('musicFadeOut is deprecated! Use soundFadeOut instead.', false, true); }); - - #if desktop + + + + //SHADER SHIT + + Lua_helper.add_callback(lua, "addChromaticAbberationEffect", function(camera:String,chromeOffset:Float = 0.005) { + + PlayState.instance.addShaderToCamera(camera, new ChromaticAberrationEffect(chromeOffset)); + + }); + + Lua_helper.add_callback(lua, "addScanlineEffect", function(camera:String,lockAlpha:Bool=false) { + + PlayState.instance.addShaderToCamera(camera, new ScanlineEffect(lockAlpha)); + + }); + Lua_helper.add_callback(lua, "addGrainEffect", function(camera:String,grainSize:Float,lumAmount:Float,lockAlpha:Bool=false) { + + PlayState.instance.addShaderToCamera(camera, new GrainEffect(grainSize,lumAmount,lockAlpha)); + + }); + Lua_helper.add_callback(lua, "addTiltshiftEffect", function(camera:String,blurAmount:Float,center:Float) { + + PlayState.instance.addShaderToCamera(camera, new TiltshiftEffect(blurAmount,center)); + + }); + Lua_helper.add_callback(lua, "addVCREffect", function(camera:String,glitchFactor:Float = 0.0,distortion:Bool=true,perspectiveOn:Bool=true,vignetteMoving:Bool=true) { + + PlayState.instance.addShaderToCamera(camera, new VCRDistortionEffect(glitchFactor,distortion,perspectiveOn,vignetteMoving)); + + }); + Lua_helper.add_callback(lua, "addGlitchEffect", function(camera:String,waveSpeed:Float = 0.1,waveFrq:Float = 0.1,waveAmp:Float = 0.1) { + + PlayState.instance.addShaderToCamera(camera, new GlitchEffect(waveSpeed,waveFrq,waveAmp)); + + }); + Lua_helper.add_callback(lua, "addPulseEffect", function(camera:String,waveSpeed:Float = 0.1,waveFrq:Float = 0.1,waveAmp:Float = 0.1) { + + PlayState.instance.addShaderToCamera(camera, new PulseEffect(waveSpeed,waveFrq,waveAmp)); + + }); + Lua_helper.add_callback(lua, "addDistortionEffect", function(camera:String,waveSpeed:Float = 0.1,waveFrq:Float = 0.1,waveAmp:Float = 0.1) { + + PlayState.instance.addShaderToCamera(camera, new DistortBGEffect(waveSpeed,waveFrq,waveAmp)); + + }); + Lua_helper.add_callback(lua, "addInvertEffect", function(camera:String,lockAlpha:Bool=false) { + + PlayState.instance.addShaderToCamera(camera, new InvertColorsEffect(lockAlpha)); + + }); + Lua_helper.add_callback(lua, "addGreyscaleEffect", function(camera:String) { //for dem funkies + + PlayState.instance.addShaderToCamera(camera, new GreyscaleEffect()); + + }); + Lua_helper.add_callback(lua, "addGrayscaleEffect", function(camera:String) { //for dem funkies + + PlayState.instance.addShaderToCamera(camera, new GreyscaleEffect()); + + }); + Lua_helper.add_callback(lua, "add3DEffect", function(camera:String,xrotation:Float=0,yrotation:Float=0,zrotation:Float=0,depth:Float=0) { //for dem funkies + + PlayState.instance.addShaderToCamera(camera, new ThreeDEffect(xrotation,yrotation,zrotation,depth)); + + }); + Lua_helper.add_callback(lua, "addBloomEffect", function(camera:String,intensity:Float = 0.35,blurSize:Float=1.0) { + + PlayState.instance.addShaderToCamera(camera, new BloomEffect(blurSize/512.0,intensity)); + + }); + Lua_helper.add_callback(lua, "clearEffects", function(camera:String) { + PlayState.instance.clearShaderFromCamera(camera); + }); Discord.DiscordClient.addLuaCallbacks(lua); - #end call('onCreate', []); #end @@ -1489,6 +1704,21 @@ class FunkinLua { return Reflect.getProperty(leArray, variable); } + function loadFrames(spr:FlxSprite, image:String, spriteType:String) + { + switch(spriteType.toLowerCase().trim()) + { + case "texture" | "textureatlas" | "tex": + spr.frames = AtlasFrameMaker.construct(image); + + case "packer" | "packeratlas" | "pac": + spr.frames = Paths.getPackerAtlas(image); + + default: + spr.frames = Paths.getSparrowAtlas(image); + } + } + function setGroupStuff(leArray:Dynamic, variable:String, value:Dynamic) { var killMe:Array = variable.split('.'); if(killMe.length > 1) { @@ -1537,7 +1767,7 @@ class FunkinLua { PlayState.instance.modchartTweens.remove(tag); } } - + function tweenShit(tag:String, vars:String) { cancelTween(tag); var variables:Array = vars.replace(' ', '').split('.'); @@ -1635,6 +1865,14 @@ class FunkinLua { return PlayState.instance.camGame; } + function shaderFromString(cam:String) { + //switch(cam.toLowerCase()) { + // case 'chromaticAbberation' | 'ca': + // + //} + return (new ChromaticAberrationEffect()); + } + public function luaTrace(text:String, ignoreCheck:Bool = false, deprecated:Bool = false) { #if LUA_ALLOWED if(ignoreCheck || getBool('luaDebugMode')) { @@ -1679,6 +1917,28 @@ class FunkinLua { return Function_Continue; } + function getPropertyLoopThingWhatever(killMe:Array, ?checkForTextsToo:Bool = true):Dynamic + { + var coverMeInPiss:Dynamic = getObjectDirectly(killMe[0], checkForTextsToo); + for (i in 1...killMe.length-1) { + coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); + } + return coverMeInPiss; + } + + function getObjectDirectly(objectName:String, ?checkForTextsToo:Bool = true):Dynamic + { + var coverMeInPiss:Dynamic = null; + if(PlayState.instance.modchartSprites.exists(objectName)) { + coverMeInPiss = PlayState.instance.modchartSprites.get(objectName); + } else if(checkForTextsToo && PlayState.instance.modchartTexts.exists(objectName)) { + coverMeInPiss = PlayState.instance.modchartTexts.get(objectName); + } else { + coverMeInPiss = Reflect.getProperty(getInstance(), objectName); + } + return coverMeInPiss; + } + #if LUA_ALLOWED function resultIsAllowed(leLua:State, leResult:Null) { //Makes it ignore warnings switch(Lua.type(leLua, leResult)) { @@ -1726,7 +1986,7 @@ class FunkinLua { if(accessedProps != null) { accessedProps.clear(); } - //PlayState.instance.removeLua(this); + Lua.close(lua); lua = null; #end @@ -1779,4 +2039,5 @@ class DebugLuaText extends FlxText } else if(disableTime < 1) alpha = disableTime; } + } diff --git a/source/GameDimensions.hx b/source/GameDimensions.hx new file mode 100644 index 000000000..db4a62af3 --- /dev/null +++ b/source/GameDimensions.hx @@ -0,0 +1,7 @@ +package; + +class GameDimensions +{ + public static var width:Int = 1280; + public static var height:Int = 720; +} \ No newline at end of file diff --git a/source/GameOverState.hx b/source/GameOverState.hx new file mode 100644 index 000000000..654cc6019 --- /dev/null +++ b/source/GameOverState.hx @@ -0,0 +1,83 @@ +package; + +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.addons.transition.FlxTransitionableState; +import flixel.graphics.frames.FlxAtlasFrames; +import flixel.input.gamepad.FlxGamepad; +import flixel.tweens.FlxEase; +import flixel.tweens.FlxTween; + +class GameOverState extends FlxTransitionableState +{ + var bfX:Float = 0; + var bfY:Float = 0; + + public function new(x:Float, y:Float) + { + super(); + + bfX = x; + bfY = y; + } + + override function create() + { + var loser:FlxSprite = new FlxSprite(100, 100); + var loseTex = Paths.getSparrowAtlas('lose'); + loser.frames = loseTex; + loser.animation.addByPrefix('lose', 'lose', 24, false); + loser.animation.play('lose'); + add(loser); + + var bf:Boyfriend = new Boyfriend(bfX, bfY); + // bf.scrollFactor.set(); + add(bf); + bf.playAnim('firstDeath'); + + FlxG.camera.follow(bf, LOCKON, 0.001); + + var restart:FlxSprite = new FlxSprite(500, 50).loadGraphic(Paths.image('restart')); + restart.setGraphicSize(Std.int(restart.width * 0.6)); + restart.updateHitbox(); + restart.alpha = 0; + restart.antialiasing = true; + add(restart); + + FlxG.sound.music.fadeOut(2, FlxG.sound.music.volume * 0.6); + + FlxTween.tween(restart, {alpha: 1}, 1, {ease: FlxEase.quartInOut}); + FlxTween.tween(restart, {y: restart.y + 40}, 7, {ease: FlxEase.quartInOut, type: PINGPONG}); + + super.create(); + } + + private var fading:Bool = false; + + override function update(elapsed:Float) + { + var pressed:Bool = FlxG.keys.justPressed.ANY; + + var gamepad:FlxGamepad = FlxG.gamepads.lastActive; + + if (gamepad != null) + { + if (gamepad.justPressed.ANY) + pressed = true; + } + + pressed = false; + + if (pressed && !fading) + { + fading = true; + PlayState.isPixel = false; + FlxG.sound.music.fadeOut(0.5, 0, function(twn:FlxTween) + { + FlxG.sound.music.stop(); + LoadingState.loadAndSwitchState(new PlayState()); + }); + } + super.update(elapsed); + } +} diff --git a/source/GameOverSubstate.hx b/source/GameOverSubstate.hx index 417998f5e..ccb07b186 100644 --- a/source/GameOverSubstate.hx +++ b/source/GameOverSubstate.hx @@ -3,95 +3,175 @@ package; import flixel.FlxG; import flixel.FlxObject; import flixel.FlxSubState; -import flixel.math.FlxMath; import flixel.math.FlxPoint; import flixel.util.FlxColor; import flixel.util.FlxTimer; -import flixel.tweens.FlxEase; import flixel.tweens.FlxTween; -import flixel.FlxCamera; +import flixel.util.FlxDestroyUtil; +import flixel.tweens.FlxEase; +import sys.io.File; +import sys.FileSystem; +import lime.utils.Assets; + +using Lambda; class GameOverSubstate extends MusicBeatSubstate { - public var boyfriend:Boyfriend; - var camFollow:FlxPoint; - var camFollowPos:FlxObject; - var updateCamera:Bool = false; - - var stageSuffix:String = ""; - - public static var characterName:String = 'bf'; + var bf:Boyfriend; + var camFollow:FlxObject; + + public var stageSuffix:String = ""; + var isSenpai:Bool = false; + var isCorrupt:Bool = false; + var noDeathAnim:Bool = false; + var red = 51; + var green = 51; + var blue = 204; + var deathTimer:FlxTimer = new FlxTimer(); + + public static var characterName:String = 'bf-dead'; public static var deathSoundName:String = 'fnf_loss_sfx'; public static var loopSoundName:String = 'gameOver'; public static var endSoundName:String = 'gameOverEnd'; + public var doIdle:Bool = false; + public var startedMusic:Bool = false; public static var instance:GameOverSubstate; - public static function resetVariables() { - characterName = 'bf'; - deathSoundName = 'fnf_loss_sfx'; - loopSoundName = 'gameOver'; - endSoundName = 'gameOverEnd'; - } - - override function create() + public function new(x:Float, y:Float) { instance = this; PlayState.instance.callOnLuas('onGameOverStart', []); - super.create(); - } + var daCharacter = PlayState.instance.boyfriend.curCharacter; + var daBf:String = ''; - public function new(x:Float, y:Float, camX:Float, camY:Float) - { - super(); + isCorrupt = false; + isSenpai = false; + startedMusic = false; + + if (PlayState.triggeredFlip) + { + FlxG.save.data.downScroll = !FlxG.save.data.downScroll; + PlayState.triggeredFlip = false; + } + + switch (daCharacter) + { + /*case 'bf-pixel' | 'bf-pixeld4' | 'bf-pixeld4BSide': + stageSuffix = '-pixel'; + daBf = 'bf-pixel-dead'; + case 'bf-tankman-pixel' | 'bf-pico-pixel' | 'bf-rico-pixel' | 'bf-tom-pixel' | 'bf-sonic-pixel' | 'bf-gf-pixel' | 'bf-wright-pixel' | 'bf-sans-pixel': + stageSuffix = '-pixel'; + daBf = daCharacter + '-dead'; + case 'bf-aloe' | 'bf-aloe-confused' | 'bf-aloe-car' | 'bf1' | 'bf-aloe-past' | 'bf-aloe-deathless': + daBf = 'bf-aloe'; + case 'bf-aloe-corrupt': + daBf = daCharacter; + isCorrupt = true; + case 'bf-nene' | 'bf-nene-scream': + daBf = 'bf-nene'; + case 'bf-pixel-neon': + stageSuffix = '-pixel'; + daBf = 'bf-pixel-dead'; + case 'bf-demoncesar' | 'bf-demoncesar-trollge': + daBf = 'bf-cesar'; + case 'bf-gf' | 'bf-gf-demon': + daBf = 'bf-gf'; + case 'bf-senpai-pixel' | 'bf-senpai-angry-pixel': + stageSuffix = '-senpai'; + daBf = 'bf-senpai-pixel-dead'; + isSenpai = true; + case 'bf-senpai-tankman': + stageSuffix = '-senpaitankman'; + daBf = 'bf-senpai-tankman-pixel-dead'; + isSenpai = true;*/ + default: + { + if (characterName != 'bf-dead') + daBf = characterName; + else + daBf = deathSpritesCheck(daCharacter); + } + } - PlayState.instance.setOnLuas('inGameOver', true); + super(); Conductor.songPosition = 0; - boyfriend = new Boyfriend(x, y, characterName); - boyfriend.x += boyfriend.positionArray[0]; - boyfriend.y += boyfriend.positionArray[1]; - add(boyfriend); + bf = new Boyfriend(x, y, daBf); + add(bf); - camFollow = new FlxPoint(boyfriend.getGraphicMidpoint().x, boyfriend.getGraphicMidpoint().y); + if (isSenpai) + camFollow = new FlxObject(bf.getMidpoint().x - 300, bf.getMidpoint().y - 500, 1, 1); + else + camFollow = new FlxObject(bf.getGraphicMidpoint().x, bf.getGraphicMidpoint().y, 1, 1); - FlxG.sound.play(Paths.sound(deathSoundName)); + add(camFollow); + + FlxG.sound.play(Paths.sound('fnf_loss_sfx' + stageSuffix)); Conductor.changeBPM(100); + // FlxG.camera.followLerp = 1; // FlxG.camera.focusOn(FlxPoint.get(FlxG.width / 2, FlxG.height / 2)); FlxG.camera.scroll.set(); FlxG.camera.target = null; - boyfriend.playAnim('firstDeath'); + if (bf.animation.getByName('firstDeath') != null) + { + noDeathAnim = false; + bf.playAnim('firstDeath'); + } + else + { + noDeathAnim = true; + bf.animation.pause(); + } - var exclude:Array = []; + deathTimer.start(2.375, function(tmr:FlxTimer) + { + if (!startedMusic) + { + startedMusic = true; + + if (!isCorrupt) + FlxG.sound.playMusic(Paths.music('gameOver' + stageSuffix)); + + if (noDeathAnim) + doIdle = true; + } + }); + } + + function deathSpritesCheck(char:String) + { + //a simple check to see if a dead spritesheet exists. + var daChar:String = char; - camFollowPos = new FlxObject(0, 0, 1, 1); - camFollowPos.setPosition(FlxG.camera.scroll.x + (FlxG.camera.width / 2), FlxG.camera.scroll.y + (FlxG.camera.height / 2)); - add(camFollowPos); + //in case you have two or more dashes like bf-aloe-confused. ok this really only works with two dashes but whatever. + var dashCount:Int = daChar.indexOf('-'); - #if mobileC - addVirtualPad(NONE, A_B); - - var camcontrol = new FlxCamera(); - FlxG.cameras.add(camcontrol); - camcontrol.bgColor.alpha = 0; - _virtualpad.cameras = [camcontrol]; - #end + if (dashCount >= 2) + { + daChar = char.split('-')[0]; + + for (i in 1...dashCount) + daChar = daChar + '-' + char.split('-')[i]; + } + + if (FileSystem.exists(Paths.jsonNew('characters/'+daChar+'-dead')) || Assets.exists(Paths.jsonNew('characters/jsons/'+daChar+'-dead'))) + return daChar+'-dead'; + + if (FileSystem.exists(Paths.jsonNew('characters/'+char+'-dead')) || Assets.exists(Paths.jsonNew('characters/jsons/'+char+'-dead'))) + return char+'-dead'; + + return char; } override function update(elapsed:Float) { super.update(elapsed); - PlayState.instance.callOnLuas('onUpdate', [elapsed]); - if(updateCamera) { - var lerpVal:Float = CoolUtil.boundTo(elapsed * 0.6, 0, 1); - camFollowPos.setPosition(FlxMath.lerp(camFollowPos.x, camFollow.x, lerpVal), FlxMath.lerp(camFollowPos.y, camFollow.y, lerpVal)); - } - if (controls.ACCEPT) { endBullshit(); @@ -100,70 +180,87 @@ class GameOverSubstate extends MusicBeatSubstate if (controls.BACK) { FlxG.sound.music.stop(); - PlayState.deathCounter = 0; - PlayState.seenCutscene = false; + + if (PlayState.isPixel) + { + PlayState.isPixel = false; + } if (PlayState.isStoryMode) - MusicBeatState.switchState(new StoryMenuState()); + FlxG.switchState(new StoryMenuState()); + else if (PlayState.isBETADCIU) + if (PlayState.storyDifficulty == 5) + FlxG.switchState(new GuestBETADCIUState()); + else + FlxG.switchState(new BETADCIUState()); + else if (PlayState.isBonus) + FlxG.switchState(new BonusSongsState()); + else if (PlayState.isNeonight) + FlxG.switchState(new NeonightState()); + else if (PlayState.isVitor) + FlxG.switchState(new VitorState()); else - MusicBeatState.switchState(new FreeplayState()); - - FlxG.sound.playMusic(Paths.music('freakyMenu')); - PlayState.instance.callOnLuas('onGameOverConfirm', [false]); + FlxG.switchState(new FreeplayState()); + PlayState.loadRep = false; } - if (boyfriend.animation.curAnim.name == 'firstDeath') + new FlxTimer().start(0.5, function(tmr:FlxTimer) { - if(boyfriend.animation.curAnim.curFrame == 12) - { - FlxG.camera.follow(camFollowPos, LOCKON, 1); - updateCamera = true; - } - - if (boyfriend.animation.curAnim.finished) - { - coolStartDeath(); - boyfriend.startedDeath = true; - } - } + FlxG.camera.follow(camFollow, LOCKON, 0.01); + }); if (FlxG.sound.music.playing) { Conductor.songPosition = FlxG.sound.music.time; } - PlayState.instance.callOnLuas('onUpdatePost', [elapsed]); + + if (noDeathAnim && bf != null) + bf.setColorTransform(0, 0, 0, 1, red, green, blue); } override function beatHit() { super.beatHit(); - //FlxG.log.add('beat'); + if (doIdle) + bf.dance(); + + FlxG.log.add('beat'); } var isEnding:Bool = false; - function coolStartDeath(?volume:Float = 1):Void - { - FlxG.sound.playMusic(Paths.music(loopSoundName), volume); - } - function endBullshit():Void { if (!isEnding) { isEnding = true; - boyfriend.playAnim('deathConfirm', true); + deathTimer.destroy(); + + if (bf.animation.getByName('deathConfirm') != null) + bf.playAnim('deathConfirm', true); + + if (noDeathAnim) + { + doIdle = false; + FlxTween.tween(this, {'red': 255, 'blue': 255, 'green': 255}, 0.08); + bf.animation.pause(); + } + FlxG.sound.music.stop(); - FlxG.sound.play(Paths.music(endSoundName)); + FlxG.sound.play(Paths.music('gameOverEnd' + stageSuffix)); + + if (PlayState.isPixel) + { + PlayState.isPixel = false; + } new FlxTimer().start(0.7, function(tmr:FlxTimer) { FlxG.camera.fade(FlxColor.BLACK, 2, false, function() { - MusicBeatState.resetState(); + LoadingState.loadAndSwitchState(new PlayState()); }); }); - PlayState.instance.callOnLuas('onGameOverConfirm', [true]); } } } diff --git a/source/GameplayChangersSubstate.hx b/source/GameplayChangersSubstate.hx index d99fa60df..15ebe4d34 100644 --- a/source/GameplayChangersSubstate.hx +++ b/source/GameplayChangersSubstate.hx @@ -23,7 +23,6 @@ import flixel.tweens.FlxTween; import flixel.util.FlxTimer; import flixel.input.keyboard.FlxKey; import flixel.graphics.FlxGraphic; -import flixel.FlxCamera; import Controls; using StringTools; @@ -40,12 +39,23 @@ class GameplayChangersSubstate extends MusicBeatSubstate function getOptions() { + var goption:GameplayOption = new GameplayOption('Scroll Type', 'scrolltype', 'string', 'multiplicative', ["multiplicative", "constant"]); + optionsArray.push(goption); + var option:GameplayOption = new GameplayOption('Scroll Speed', 'scrollspeed', 'float', 1); option.scrollSpeed = 1.5; option.minValue = 0.5; - option.maxValue = 3; option.changeValue = 0.1; - option.displayFormat = '%vX'; + if (goption.getValue() != "constant") + { + option.displayFormat = '%vX'; + option.maxValue = 3; + } + else + { + option.displayFormat = "%v"; + option.maxValue = 6; + } optionsArray.push(option); /*var option:GameplayOption = new GameplayOption('Playback Rate', 'songspeed', 'float', 1); @@ -82,6 +92,17 @@ class GameplayChangersSubstate extends MusicBeatSubstate optionsArray.push(option); } + public function getOptionByName(name:String) + { + for(i in optionsArray) + { + var opt:GameplayOption = i; + if (opt.name == name) + return opt; + } + return null; + } + public function new() { super(); @@ -133,15 +154,6 @@ class GameplayChangersSubstate extends MusicBeatSubstate changeSelection(); reloadCheckboxes(); - - #if mobileC - addVirtualPad(FULL, A_B); - - var camcontrol = new FlxCamera(); - FlxG.cameras.add(camcontrol); - camcontrol.bgColor.alpha = 0; - _virtualpad.cameras = [camcontrol]; - #end } var nextAccept:Int = 5; @@ -159,9 +171,9 @@ class GameplayChangersSubstate extends MusicBeatSubstate } if (controls.BACK) { + close(); ClientPrefs.saveSettings(); FlxG.sound.play(Paths.sound('cancelMenu')); - MusicBeatState.resetState(); } if(nextAccept <= 0) @@ -222,6 +234,26 @@ class GameplayChangersSubstate extends MusicBeatSubstate curOption.curOption = num; curOption.setValue(curOption.options[num]); //lol + + if (curOption.name == "Scroll Type") + { + var oOption:GameplayOption = getOptionByName("Scroll Speed"); + if (oOption != null) + { + if (curOption.getValue() == "constant") + { + oOption.displayFormat = "%v"; + oOption.maxValue = 6; + } + else + { + oOption.displayFormat = "%vX"; + oOption.maxValue = 3; + if(oOption.getValue() > 3) oOption.setValue(3); + } + updateTextFrom(oOption); + } + } //trace(curOption.options[num]); } updateTextFrom(curOption); @@ -267,6 +299,17 @@ class GameplayChangersSubstate extends MusicBeatSubstate } updateTextFrom(leOption); } + + if(leOption.name == 'Scroll Speed') + { + leOption.displayFormat = "%vX"; + leOption.maxValue = 3; + if(leOption.getValue() > 3) + { + leOption.setValue(3); + } + updateTextFrom(leOption); + } leOption.change(); } FlxG.sound.play(Paths.sound('cancelMenu')); diff --git a/source/GirlfriendBG.hx b/source/GirlfriendBG.hx new file mode 100644 index 000000000..d8f3cd017 --- /dev/null +++ b/source/GirlfriendBG.hx @@ -0,0 +1,44 @@ +package; + +import flixel.FlxSprite; +import flixel.graphics.frames.FlxAtlasFrames; + +class GirlfriendBG extends FlxSprite +{ + public function new(x:Float, y:Float, path:String, prefix:String) + { + super(x, y); + + frames = Paths.getSparrowAtlas(path); + animation.addByIndices('danceLeft', prefix, [30, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false); + animation.addByIndices('danceRight', prefix, [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false); + + animation.play('danceRight'); + } + + var danceDir:Bool = false; + + public function gone():Void + { + animation.addByIndices('danceLeft', 'GF Dancing Beat Gone', [30, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false); + animation.addByIndices('danceRight', 'GF Dancing Beat Gone', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false); + dance(); + } + + public function goBack():Void + { + 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); + dance(); + } + + public function dance():Void + { + danceDir = !danceDir; + + if (danceDir) + animation.play('danceRight', true); + else + animation.play('danceLeft', true); + } +} diff --git a/source/GitarooPause.hx b/source/GitarooPause.hx index f46b6d7d6..cb9705c55 100644 --- a/source/GitarooPause.hx +++ b/source/GitarooPause.hx @@ -52,24 +52,18 @@ class GitarooPause extends MusicBeatState override function update(elapsed:Float) { - if (controls.UI_LEFT_P || controls.UI_RIGHT_P) + if (controls.LEFT_P || controls.RIGHT_P) changeThing(); if (controls.ACCEPT) { if (replaySelect) { - MusicBeatState.switchState(new PlayState()); + FlxG.switchState(new PlayState()); } else { - PlayState.usedPractice = false; - PlayState.changedDifficulty = false; - PlayState.seenCutscene = false; - PlayState.deathCounter = 0; - PlayState.cpuControlled = false; - MusicBeatState.switchState(new MainMenuState()); - FlxG.sound.playMusic(Paths.music('freakyMenu')); + FlxG.switchState(new MainMenuState()); } } diff --git a/source/GoFindTheSecretState.hx b/source/GoFindTheSecretState.hx new file mode 100644 index 000000000..7bb656807 --- /dev/null +++ b/source/GoFindTheSecretState.hx @@ -0,0 +1,113 @@ +package; + +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.FlxState; +import flixel.addons.display.FlxGridOverlay; +import flixel.addons.transition.FlxTransitionSprite.GraphicTransTileDiamond; +import flixel.addons.transition.FlxTransitionableState; +import flixel.addons.transition.TransitionData; +import flixel.graphics.FlxGraphic; +import flixel.graphics.frames.FlxAtlasFrames; +import flixel.group.FlxGroup; +import flixel.input.gamepad.FlxGamepad; +import flixel.math.FlxPoint; +import flixel.math.FlxRect; +import flixel.system.FlxSound; +import flixel.system.ui.FlxSoundTray; +import flixel.text.FlxText; +import flixel.tweens.FlxEase; +import flixel.tweens.FlxTween; +import flixel.util.FlxColor; +import flixel.util.FlxTimer; +import io.newgrounds.NG; +import lime.app.Application; +import openfl.Assets; + +#if windows +import Discord.DiscordClient; +#end + +#if cpp +import sys.thread.Thread; +#end + +using StringTools; + +class GoFindTheSecretState extends MusicBeatState +{ + static var initialized:Bool = false; + + var blackScreen:FlxSprite; + var lolText:FlxText; + var lolText2:FlxText; + var sonicBG:FlxSprite; + + override public function create():Void + { + FlxG.sound.playMusic(Paths.music('nexus_bf')); + + sonicBG = new FlxSprite(-100, -100).loadGraphic(Paths.image('sonic/exe/sonicBG')); + sonicBG.setGraphicSize(Std.int(sonicBG.width * 1)); + add(sonicBG); + + lolText = new FlxText(0, 0, FlxG.width, 48); + lolText.setFormat(Paths.font("vcr.ttf"), 48, FlxColor.WHITE, CENTER); + lolText.text = 'You are here because you tried to access one' + + '\n of the hidden songs without first finding the hidden menu! Go find the menu if you wanna play these songs!'; + lolText.borderColor = FlxColor.BLACK; + lolText.borderSize = 4; + lolText.borderStyle = FlxTextBorderStyle.OUTLINE; + lolText.screenCenter(); + add(lolText); + + lolText2 = new FlxText(0, 200, FlxG.width, 32); + lolText2.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, CENTER); + lolText2.text = '\n \n \n \n \n \n \n \n \nPress Enter to go back to the Main Menu.'; + lolText2.borderColor = FlxColor.BLACK; + lolText2.borderSize = 3; + lolText2.borderStyle = FlxTextBorderStyle.OUTLINE; + lolText2.screenCenter(); + add(lolText2); + + blackScreen = new FlxSprite(-100, -100).makeGraphic(Std.int(FlxG.width * 100), Std.int(FlxG.height * 100), FlxColor.BLACK); + blackScreen.scrollFactor.set(); + add(blackScreen); + + new FlxTimer().start(1, function(tmr:FlxTimer) + { + blackScreen.alpha -= 0.05; + + if (blackScreen.alpha > 0) + { + tmr.reset(0.03); + } + }); + } + + override function update(elapsed:Float) + { + super.update(elapsed); + + if (FlxG.keys.justPressed.ENTER) + { + FlxG.sound.music.stop(); + FlxG.sound.playMusic(Paths.music('freakyMenu')); + FlxG.switchState(new MainMenuState()); + } + } + + override function beatHit() + { + super.beatHit(); + + if(curBeat % 2 == 1) + { + lolText2.alpha = 0; + } + else if(curBeat % 2 == 2) + { + lolText2.alpha = 1; + } + } +} diff --git a/source/GuestBETADCIUState.hx b/source/GuestBETADCIUState.hx new file mode 100644 index 000000000..134b72063 --- /dev/null +++ b/source/GuestBETADCIUState.hx @@ -0,0 +1,562 @@ +package; + +import flash.text.TextField; +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.addons.display.FlxGridOverlay; +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.math.FlxMath; +import flixel.text.FlxText; +import flixel.util.FlxColor; +import lime.utils.Assets; +import flixel.effects.FlxFlicker; +import flixel.tweens.FlxTween; +import sys.FileSystem; +import flixel.util.FlxTimer; + +import haxe.xml.Access; +import haxe.xml.Fast; + +#if desktop +import Discord.DiscordClient; +#end + +#if desktop +import Sys; +import sys.FileSystem; +import sys.io.File; +#end + +using StringTools; + +class GuestBETADCIUState extends MusicBeatState +{ + var songs:Array = []; + + var selector:FlxText; + var curSelected:Int = 0; + var curDifficulty:Int = 5; + + var scoreText:FlxText; + var diffText:FlxText; + var comboText:FlxText; + var text2:FlxText; + var text3:FlxText; + var lerpScore:Int = 0; + var intendedScore:Int = 0; + var combo:String = ''; + var canMove:Bool = true; + public var warning:Bool = false; + + private var grpSongs:FlxTypedGroup; + private var curPlaying:Bool = false; + public static var downscroll:Bool = false; + + private var iconArray:Array = []; + + public var ytIcon:FlxSprite; + + override function create() + { + Paths.clearStoredMemory(); + Paths.clearUnusedMemory(); + WeekData.reloadWeekFiles(false, 5); + + for (i in 0...WeekData.weeksList.length) { + var leWeek:WeekData = WeekData.weeksLoaded.get(WeekData.weeksList[i]); + var leSongs:Array = []; + var leChars:Array = []; + for (j in 0...leWeek.songs.length) + { + leSongs.push(leWeek.songs[j][0]); + leChars.push(leWeek.songs[j][1]); + } + + WeekData.setDirectoryFromWeek(leWeek); + for (song in leWeek.songs) + { + var colors:Array = song[2]; + if(colors == null || colors.length < 3) + { + colors = [146, 113, 253]; + } + addSong(song[0], i, song[1], leWeek.ytInfo[0], leWeek.ytInfo[1], leWeek.ytInfo[2], leWeek.ytInfo[3]); + } + } + WeekData.setDirectoryFromWeek(); + + if (songs.length < 1) + { + addSong('Placeholder', 0, 'face', 'Snow The Fox', "https://www.youtube.com/c/SnowTheFox", 'snow', 0xFFB94545); + warning = true; + trace('warn em bro!'); + } + + FlxG.mouse.visible = true; + + if (FlxG.sound.music != null) + { + FlxG.sound.music.fadeIn(2, 0, 0.8); + FlxG.sound.playMusic(Paths.music('guest'), 0); + } + + #if desktop + // Updating Discord Rich Presence + DiscordClient.changePresence("In Guest BETADCIU Menu", null); + #end + + var isDebug:Bool = false; + + MainMenuState.mainMusic = false; + canMove = true; + + #if debug + isDebug = true; + #end + + // LOAD MUSIC + + // LOAD CHARACTERS + + var bg:FlxSprite = new FlxSprite().loadGraphic(Paths.image('menuDesat')); + bg.color = 0xFFfd719b; + add(bg); + + grpSongs = new FlxTypedGroup(); + add(grpSongs); + + for (i in 0...songs.length) + { + var songText:Alphabet = new Alphabet(0, (70 * i) + 30, songs[i].songName, true, false); + songText.isMenuItem = true; + songText.targetY = i; + grpSongs.add(songText); + + Paths.currentModDirectory = songs[i].folder; + var icon:HealthIcon = new HealthIcon(songs[i].songCharacter); + icon.sprTracker = songText; + + // using a FlxGroup is too much fuss! + iconArray.push(icon); + add(icon); + + // songText.x += 40; + // DONT PUT X IN THE FIRST PARAMETER OF new ALPHABET() !! + // songText.screenCenter(X); + } + + WeekData.setDirectoryFromWeek(); + + scoreText = new FlxText(FlxG.width * 0.7, 5, 0, "", 32); + // scoreText.autoSize = false; + scoreText.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, RIGHT); + // scoreText.alignment = RIGHT; + + var scoreBG:FlxSprite = new FlxSprite(scoreText.x - 6, 0).makeGraphic(Std.int(FlxG.width * 0.35), 66, 0xFF000000); + scoreBG.alpha = 0.6; + add(scoreBG); + + diffText = new FlxText(scoreText.x, scoreText.y + 36, 0, "", 24); + diffText.font = scoreText.font; + add(diffText); + + comboText = new FlxText(diffText.x + 100, diffText.y, 0, "", 24); + comboText.font = diffText.font; + add(comboText); + + add(scoreText); + + ytIcon = new FlxSprite(); + ytIcon.frames = Paths.getSparrowAtlas('extraIcons'); + readXML(File.getContent(Paths.xmlNew('images/extraIcons'))); + + if (daNames.length > 0) + { + for (i in 0...daNames.length) + ytIcon.animation.addByPrefix(daNames[i], daNames[i], 0, false); + } + + ytIcon.setGraphicSize(Std.int(ytIcon.width * 1.2)); + ytIcon.screenCenter(); + ytIcon.x += 350; + ytIcon.y -= 50; + + ytIcon.animation.play('snow'); + add(ytIcon); + + var text1 = new FlxText(ytIcon.x - 150, ytIcon.y + 220, 0, "This BETADCIU was made by:", 32); + text1.setFormat(Paths.font("Aller_Rg.ttf"), 36, FlxColor.WHITE, CENTER); + text1.borderColor = FlxColor.BLACK; + text1.borderSize = 3; + text1.borderStyle = FlxTextBorderStyle.OUTLINE; + text1.bold = true; + add(text1); + + text2 = new FlxText(ytIcon.x - 150, text1.y + 60, 0, "", 36); + text2.setFormat('Pixel Arial 11 Bold', 36, FlxColor.RED, CENTER); + text2.borderColor = FlxColor.BLACK; + text2.borderSize = 3; + text2.borderStyle = FlxTextBorderStyle.OUTLINE; + text2.bold = true; + add(text2); + + text3 = new FlxText(ytIcon.x - 110, text2.y + 65, 0, "Link to their channel!", 40); + text3.setFormat(Paths.font("Aller_Rg.ttf"), 40, FlxColor.fromString('#FF0078D4'), CENTER); + text3.borderColor = FlxColor.BLACK; + text3.borderSize = 3; + text3.borderStyle = FlxTextBorderStyle.OUTLINE; + text3.bold = true; + add(text3); + + changeSelection(); + + // FlxG.sound.playMusic(Paths.music('title'), 0); + // FlxG.sound.music.fadeIn(2, 0, 0.8); + selector = new FlxText(); + + selector.size = 40; + selector.text = ">"; + // add(selector); + + var swag:Alphabet = new Alphabet(1, 0, "swag"); + + if (warning) + { + var blackScreen = new FlxSprite(-100, -100).makeGraphic(Std.int(FlxG.width * 0.5), Std.int(FlxG.height * 0.5), FlxColor.BLACK); + blackScreen.screenCenter(); + blackScreen.scrollFactor.set(); + blackScreen.visible = false; + add(blackScreen); + + blackScreen.visible = true; + canMove = false; + + var daText = new FlxText(0, 0, 0, "No BETADCIUs Detected! \n Press enter to return to main menu.", 48); + daText.setFormat(Paths.font("vcr.ttf"), 48, FlxColor.WHITE, CENTER); + daText.screenCenter(); + daText.x += 20; + daText.y -= 100; + add(daText); + + var daText2 = new FlxText(0, 0, Std.int(FlxG.width * 0.45), "Press enter to return to the main menu.", 44); + daText2.setFormat(Paths.font("vcr.ttf"), 44, FlxColor.WHITE, CENTER); + daText2.screenCenter(); + daText2.y += 100; + add(daText2); + } + + super.create(); + } + + public function readXML(rawXml:String) + { + //i swear this is gonna take me another five hours... wait it only took 10 minutes? neat. + var daXml:Xml = Xml.parse(rawXml); + var fast = new haxe.xml.Access(daXml); + var users = fast.node.TextureAtlas; + for (SubTexture in users.nodes.SubTexture) { + var name = Std.string(SubTexture.att.name); + var nameCut = name.substr(0, name.length - 4); + daNames.push(nameCut); + } + } + + var daNames:Array = []; + + public function addSong(songName:String, weekNum:Int, songCharacter:String, ytName:String, link:String, iconName:String, textColor:Int) + { + songs.push(new SongMetadata2(songName, weekNum, songCharacter, ytName, link, iconName, textColor)); + } + + /*public function addWeek(songs:Array, weekNum:Int, ?songCharacters:Array) + { + if (songCharacters == null) + songCharacters = ['bf']; + + var num:Int = 0; + for (song in songs) + { + addSong(song, weekNum, songCharacters[num]); + + if (songCharacters.length != 1) + num++; + } + }*/ + + override function update(elapsed:Float) + { + super.update(elapsed); + + if (FlxG.sound.music.volume < 0.7) + { + FlxG.sound.music.volume += 0.5 * FlxG.elapsed; + } + + if (FlxG.mouse.overlaps(text3)) //this is like... way easier than that isOnBtt stuff + { + text3.color = 0xFF77BDFF; + if (FlxG.mouse.justPressed && canMove) + { + if (songs[curSelected].link.startsWith('https://www.youtube.com')) + fancyOpenURL(songs[curSelected].link); + else + trace('invalid link'); + + /*switch (songs[curSelected].songName.toLowerCase("")) + { + case 'epiphany' | 'bonedoggle': + fancyOpenURL("https://www.youtube.com/channel/UCCAE5-m4RfHeVOQq5OY02AQ"); + case "rabbit's-luck": + fancyOpenURL("https://www.youtube.com/c/spres"); + case 'arch': + fancyOpenURL("https://www.youtube.com/c/ajthefunky"); + case 'ghost-vip': + fancyOpenURL("https://www.youtube.com/channel/UCtpdsQyTqsGGWmMFODgaUrQ"); + case 'you-cant-run': + fancyOpenURL("https://www.youtube.com/c/lylace"); + }*/ + } + } + else if (!FlxG.mouse.overlaps(text3)) + text3.color = 0xFF0078D4; + + lerpScore = Math.floor(FlxMath.lerp(lerpScore, intendedScore, 0.4)); + + if (Math.abs(lerpScore - intendedScore) <= 10) + lerpScore = intendedScore; + + scoreText.text = "PERSONAL BEST:" + lerpScore; + comboText.text = combo + '\n'; + + var upP = controls.UP_P; + var downP = controls.DOWN_P; + var accepted = controls.ACCEPT; + + if (warning && accepted) + FlxG.switchState(new MainMenuState()); + + if (upP && canMove) + { + changeSelection(-1); + } + if (downP && canMove) + { + changeSelection(1); + } + + if (controls.BACK && canMove) + { + FlxG.switchState(new MainMenuState()); + } + + if (accepted && canMove) + { + var poop:String = Highscore.formatSong(songs[curSelected].songName.toLowerCase(), curDifficulty); + + trace(poop); + + PlayState.SONG = Song.loadFromJson(poop, songs[curSelected].songName.toLowerCase()); + PlayState.isStoryMode = false; + PlayState.isNeonight = false; + PlayState.isVitor = false; + PlayState.isBETADCIU = true; + PlayState.isBonus = false; + PlayState.storyDifficulty = curDifficulty; + canMove = false; + + PlayState.storyWeek = songs[curSelected].week; + trace('CUR WEEK' + PlayState.storyWeek); + var llll = FlxG.sound.play(Paths.sound('confirmMenu')).length; + + if (songs.length < 2) // the tween doesn't finish if it's just one song + { + new FlxTimer().start(llll/1000, function(tmr:FlxTimer) + { + if (FlxG.keys.pressed.ALT){ + FlxG.switchState(new ChartingState()); + }else{ + if (Main.hiddenSongs.contains(songs[curSelected].songName.toLowerCase()) && !Main.isHidden || PlayState.SONG.song == 'Restore' && !Main.restoreUnlocked || PlayState.SONG.song == 'Deathmatch-Holo' && !Main.deathHolo) + LoadingState.loadAndSwitchState(new GoFindTheSecretState()); + else + LoadingState.loadAndSwitchState(new CustomLoading()); + } + }); + } + + grpSongs.forEach(function(e:Alphabet){ + if (e.text != songs[curSelected].songName){ + FlxTween.tween(e, {x: -6000}, llll / 1000,{onComplete:function(e:FlxTween){ + + if (FlxG.keys.pressed.ALT){ + FlxG.switchState(new ChartingState()); + }else{ + if (Main.hiddenSongs.contains(songs[curSelected].songName.toLowerCase()) && !Main.isHidden || PlayState.SONG.song == 'Restore' && !Main.restoreUnlocked || PlayState.SONG.song == 'Deathmatch-Holo' && !Main.deathHolo) + LoadingState.loadAndSwitchState(new GoFindTheSecretState()); + else + LoadingState.loadAndSwitchState(new CustomLoading()); + } + }}); + }else{ + FlxFlicker.flicker(e); + trace(curSelected); + FlxTween.tween(e, {x: e.x + 20}, llll/1000); + } + }); + } + + #if !switch + intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty); + combo = Highscore.getCombo(songs[curSelected].songName, curDifficulty); + #end + + switch (curDifficulty) + { + case 5: + diffText.text = "HARD"; + } + } + + public function changeIcon():Void + { + ytIcon.animation.play(songs[curSelected].iconName); + /*switch (songs[curSelected].songName.toLowerCase()) + { + case 'epiphany' | 'bonedoggle': + { + ytIcon.animation.play('snow'); + text2.text = "Snow The Fox"; + text2.color = 0xFFB94545; + text2.x = 790; + } + case "rabbit's-luck": + { + ytIcon.animation.play('spres'); + text2.text = 'spres'; + text2.color = 0xFF3F47CC; + text2.x = 910; + } + case 'arch': + { + ytIcon.animation.play('aj'); + text2.text = "AjTheFunky"; + text2.color = 0xFFFF7FB8; + text2.x = 840; + } + case 'ghost-vip': + { + ytIcon.animation.play('lno'); + text2.text = "LiterallyNoOne"; + text2.color = 0xFF444561; + text2.x = 790; + } + case 'you-cant-run': + { + ytIcon.animation.play('lylace'); + text2.text = "Lylace"; + text2.color = 0xFF691A6B; + text2.x = 900; + } + case "its-complicated": + { + ytIcon.animation.play('tc'); + text2.text = 'Tactical Cupcakes'; + text2.color = 0xB8076F; + text2.x = 790; + } + case 'buildstroll': + { + ytIcon.animation.play('chxwy'); + text2.text = "Chxwy"; + text2.color = 0xFF3D026C; + text2.x = 910; + } + case 'ballistic': + { + ytIcon.animation.play('mewrk'); + text2.text = "Mewrk"; + text2.color = 0xFF444561; + text2.x = 790; + } + }*/ + } + + function changeSelection(change:Int = 0) + { + #if !switch + // NGio.logEvent('Fresh'); + #end + + // NGio.logEvent('Fresh'); + FlxG.sound.play(Paths.sound('scrollMenu'), 0.4); + + curSelected += change; + + if (curSelected < 0) + curSelected = songs.length - 1; + if (curSelected >= songs.length) + curSelected = 0; + + changeIcon(); + + // selector.y = (70 * curSelected) + 30; + + #if !switch + intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty); + combo = Highscore.getCombo(songs[curSelected].songName, curDifficulty); + // lerpScore = 0; + #end + + var bullShit:Int = 0; + + for (i in 0...iconArray.length) + { + iconArray[i].alpha = 0.6; + } + + iconArray[curSelected].alpha = 1; + Paths.currentModDirectory = songs[curSelected].folder; + + for (item in grpSongs.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)); + } + } + } +} + +class SongMetadata2 +{ + public var songName:String = ""; + public var week:Int = 0; + public var songCharacter:String = ""; + public var folder:String = ""; + + public var ytName:String = ""; + public var link:String = ""; + public var iconName:String = ""; + public var textColor:Int = -7179779; + + public function new(song:String, week:Int, songCharacter:String, ytName:String, link:String, iconName:String, textColor:Int) + { + this.songName = song; + this.week = week; + this.songCharacter = songCharacter; + + this.ytName = ytName; + this.link = link; + this.iconName = iconName; + this.textColor = textColor; + + this.folder = Paths.currentModDirectory; + if(this.folder == null) this.folder = ''; + } +} diff --git a/source/HealthIcon.hx b/source/HealthIcon.hx index db109ae06..f22e2aa3c 100644 --- a/source/HealthIcon.hx +++ b/source/HealthIcon.hx @@ -1,72 +1,137 @@ package; import flixel.FlxSprite; + +#if windows +import Sys; +import sys.FileSystem; +#end + +#if sys +import sys.io.File; +import haxe.io.Path; +import openfl.utils.ByteArray; +import flash.display.BitmapData; +import sys.FileSystem; import openfl.utils.Assets as OpenFlAssets; +import lime.utils.Assets; +#end using StringTools; class HealthIcon extends FlxSprite { + /** + * Used for FreeplayState! If you use it elsewhere, prob gonna annoying + */ public var sprTracker:FlxSprite; - private var isOldIcon:Bool = false; - private var isPlayer:Bool = false; - private var char:String = ''; - public function new(char:String = 'bf', isPlayer:Bool = false) + public var char:String = 'bf'; + public var isPlayer:Bool = false; + public var isOldIcon:Bool = false; + public var hasWinning:Bool = false; + + public function new(?char:String = 'bf', ?isPlayer:Bool = false) { super(); - isOldIcon = (char == 'bf-old'); + + this.char = char; this.isPlayer = isPlayer; - changeIcon(char); + + useOldSystem(char); scrollFactor.set(); } - override function update(elapsed:Float) + public function changeIcon(char:String) { - super.update(elapsed); + if (!FileSystem.exists(Paths.image('icons/icon-' + char)) && !FileSystem.exists(Paths.modsImages('icons/icon-' + char))) + char = 'face'; - if (sprTracker != null) - setPosition(sprTracker.x + sprTracker.width + 10, sprTracker.y - 30); - } + var rawPic = BitmapData.fromFile(Paths.image('icons/icon-'+char)); - public function swapOldIcon() { - if(isOldIcon = !isOldIcon) changeIcon('bf-old'); - else changeIcon('bf'); - } + if (FileSystem.exists(Paths.modsImages('icons/icon-' + char))) + rawPic = BitmapData.fromFile(Paths.modsImages('icons/icon-' + char)); - private var iconOffsets:Array = [0, 0]; - public function changeIcon(char:String) { - if(this.char != char) { - var name:String = 'icons/' + char; - if(!Paths.fileExists('images/' + name + '.png', IMAGE)) name = 'icons/icon-' + char; //Older versions of psych engine's support - if(!Paths.fileExists('images/' + name + '.png', IMAGE)) name = 'icons/icon-face'; //Prevents crash from missing icon - var file:Dynamic = Paths.image(name); + loadGraphic(rawPic, true, 150, 150); - loadGraphic(file); //Load stupidly first for getting the file size - loadGraphic(file, true, Math.floor(width / 2), Math.floor(height)); //Then load it fr - iconOffsets[0] = (width - 150) / 2; - iconOffsets[1] = (width - 150) / 2; - updateHitbox(); + if (char.startsWith('senpai') || char.contains('pixel') || char.startsWith('spirit') || char.startsWith('monika') && char != 'monika-real' && !char.contains('hd')) + antialiasing = false; + else + antialiasing = true; + if (rawPic.width == 450) + { + animation.add(char, [0, 1, 2], 0, false, isPlayer); + hasWinning = true; + } + else + { animation.add(char, [0, 1], 0, false, isPlayer); - animation.play(char); - this.char = char; + hasWinning = false; + } + + animation.play(char); + } - antialiasing = ClientPrefs.globalAntialiasing; - if(char.endsWith('-pixel')) { + public function swapOldIcon(char:String) + { + var curChar:String = char; + + if (!FileSystem.exists(Paths.image('icons/icon-' + char + '-old'))) + char = 'bf'; + + if (isOldIcon) + char = curChar; + + if(isOldIcon = !isOldIcon) changeIcon(char+'-old'); + else useOldSystem(char); + } + + public function useOldSystem(char:String) + { + //is exactly the same as changeicon except it uses the hardcoded paths instead of bitmapdata. + if (!OpenFlAssets.exists(Paths.image('icons/icon-' + char)) || FileSystem.exists(Paths.modsImages('icons/icon-' + char))) + changeIcon(char); + else + { + var file:Dynamic = Paths.image('icons/icon-'+char); + var fileSize:FlxSprite = new FlxSprite().loadGraphic(file); + + loadGraphic(file, true, 150, 150); + + if (char.startsWith('senpai') || char.contains('pixel') || char.startsWith('spirit') || char.startsWith('monika') && char != 'monika-real' && !char.contains('hd')) antialiasing = false; + else + antialiasing = true; + + if (fileSize.width == 450) //now with winning icon support + { + animation.add(char, [0, 1, 2], 0, false, isPlayer); + hasWinning = true; } - } + else + { + if (fileSize.width == 150) + animation.add(char, [0], 0, false, isPlayer); + else + animation.add(char, [0, 1], 0, false, isPlayer); + + hasWinning = false; + } + + animation.play(char); + } } - override function updateHitbox() + override function update(elapsed:Float) { - super.updateHitbox(); - offset.x = iconOffsets[0]; - offset.y = iconOffsets[1]; + super.update(elapsed); + + if (sprTracker != null) + setPosition(sprTracker.x + sprTracker.width + 10, sprTracker.y - 30); } - public function getCharacter():String { + public function getCharacter():String { //idk what this does return char; } } diff --git a/source/HelperFunctions.hx b/source/HelperFunctions.hx new file mode 100644 index 000000000..8f6c6fca4 --- /dev/null +++ b/source/HelperFunctions.hx @@ -0,0 +1,9 @@ +class HelperFunctions +{ + public static function truncateFloat( number : Float, precision : Int): Float { + var num = number; + num = num * Math.pow(10, precision); + num = Math.round( num ) / Math.pow(10, precision); + return num; + } +} \ No newline at end of file diff --git a/source/Highscore.hx b/source/Highscore.hx index a77efadf0..db2e6e7e9 100644 --- a/source/Highscore.hx +++ b/source/Highscore.hx @@ -3,31 +3,74 @@ package; import flixel.FlxG; using StringTools; - class Highscore { #if (haxe >= "4.0.0") - public static var weekScores:Map = new Map(); public static var songScores:Map = new Map(); - public static var songRating:Map = new Map(); + public static var songCombos:Map = new Map(); #else - public static var weekScores:Map = new Map(); public static var songScores:Map = new Map(); - public static var songRating:Map = new Map(); + public static var songCombos:Map = new Map(); #end - public static function resetSong(song:String, diff:Int = 0):Void + public static function saveScore(song:String, score:Int = 0, ?diff:Int = 0):Void { var daSong:String = formatSong(song, diff); - setScore(daSong, 0); - setRating(daSong, 0); + + + #if !switch + NGio.postScore(score, song); + #end + + if(!FlxG.save.data.botplay) + { + if (songScores.exists(daSong)) + { + if (songScores.get(daSong) < score) + setScore(daSong, score); + } + else + setScore(daSong, score); + }else trace('BotPlay detected. Score saving is disabled.'); } - public static function resetWeek(week:String, diff:Int = 0):Void + public static function saveCombo(song:String, combo:String, ?diff:Int = 0):Void { - var daWeek:String = formatSong(week, diff); - setWeekScore(daWeek, 0); + var daSong:String = formatSong(song, diff); + var finalCombo:String = combo.split(')')[0].replace('(', ''); + + if(!FlxG.save.data.botplay) + { + if (songCombos.exists(daSong)) + { + if (getComboInt(songCombos.get(daSong)) < getComboInt(finalCombo)) + setCombo(daSong, finalCombo); + } + else + setCombo(daSong, finalCombo); + } + } + + public static function saveWeekScore(week:Int = 1, score:Int = 0, ?diff:Int = 0):Void + { + + #if !switch + NGio.postScore(score, "Week " + week); + #end + + if(!FlxG.save.data.botplay) + { + var daWeek:String = formatSong('week' + week, diff); + + if (songScores.exists(daWeek)) + { + if (songScores.get(daWeek) < score) + setScore(daWeek, score); + } + else + setScore(daWeek, score); + }else trace('BotPlay detected. Score saving is disabled.'); } public static function floorDecimal(value:Float, decimals:Int):Float @@ -46,35 +89,6 @@ class Highscore return newValue / tempMult; } - public static function saveScore(song:String, score:Int = 0, ?diff:Int = 0, ?rating:Float = -1):Void - { - var daSong:String = formatSong(song, diff); - - if (songScores.exists(daSong)) { - if (songScores.get(daSong) < score) { - setScore(daSong, score); - if(rating >= 0) setRating(daSong, rating); - } - } - else { - setScore(daSong, score); - if(rating >= 0) setRating(daSong, rating); - } - } - - public static function saveWeekScore(week:String, score:Int = 0, ?diff:Int = 0):Void - { - var daWeek:String = formatSong(week, diff); - - if (weekScores.exists(daWeek)) - { - if (weekScores.get(daWeek) < score) - setWeekScore(daWeek, score); - } - else - setWeekScore(daWeek, score); - } - /** * YOU SHOULD FORMAT SONG WITH formatSong() BEFORE TOSSING IN SONG VARIABLE */ @@ -85,67 +99,88 @@ class Highscore FlxG.save.data.songScores = songScores; FlxG.save.flush(); } - static function setWeekScore(week:String, score:Int):Void + + static function setCombo(song:String, combo:String):Void { // Reminder that I don't need to format this song, it should come formatted! - weekScores.set(week, score); - FlxG.save.data.weekScores = weekScores; + songCombos.set(song, combo); + FlxG.save.data.songCombos = songCombos; FlxG.save.flush(); } - static function setRating(song:String, rating:Float):Void + public static function formatSong(song:String, diff:Int):String { - // Reminder that I don't need to format this song, it should come formatted! - songRating.set(song, rating); - FlxG.save.data.songRating = songRating; - FlxG.save.flush(); + var daSong:String = song; + + if (diff == 0) + daSong += '-easy'; + else if (diff == 2) + { + if (PlayState.isBETADCIU && song == 'triple-trouble') + daSong += '-betadciu'; + else + daSong += '-hard'; + } + else if (diff == 3) + daSong += '-neo'; + else if (diff == 4) + daSong += '-vitor'; + else if (diff == 5) + daSong += '-guest'; + + return daSong; } - public static function formatSong(song:String, diff:Int):String + static function getComboInt(combo:String):Int { - return Paths.formatToSongPath(song) + CoolUtil.getDifficultyFilePath(diff); + switch(combo) + { + case 'SDCB': + return 1; + case 'FC': + return 2; + case 'GFC': + return 3; + case 'MFC': + return 4; + default: + return 0; + } } public static function getScore(song:String, diff:Int):Int { - var daSong:String = formatSong(song, diff); - if (!songScores.exists(daSong)) - setScore(daSong, 0); + if (!songScores.exists(formatSong(song, diff))) + setScore(formatSong(song, diff), 0); - return songScores.get(daSong); + return songScores.get(formatSong(song, diff)); } - public static function getRating(song:String, diff:Int):Float + public static function getCombo(song:String, diff:Int):String { - var daSong:String = formatSong(song, diff); - if (!songRating.exists(daSong)) - setRating(daSong, 0); + if (!songCombos.exists(formatSong(song, diff))) + setCombo(formatSong(song, diff), ''); - return songRating.get(daSong); + return songCombos.get(formatSong(song, diff)); } - public static function getWeekScore(week:String, diff:Int):Int + public static function getWeekScore(week:Int, diff:Int):Int { - var daWeek:String = formatSong(week, diff); - if (!weekScores.exists(daWeek)) - setWeekScore(daWeek, 0); + if (!songScores.exists(formatSong('week' + week, diff))) + setScore(formatSong('week' + week, diff), 0); - return weekScores.get(daWeek); + return songScores.get(formatSong('week' + week, diff)); } public static function load():Void { - if (FlxG.save.data.weekScores != null) - { - weekScores = FlxG.save.data.weekScores; - } if (FlxG.save.data.songScores != null) { songScores = FlxG.save.data.songScores; } - if (FlxG.save.data.songRating != null) + if (FlxG.save.data.songCombos != null) { - songRating = FlxG.save.data.songRating; + songCombos = FlxG.save.data.songCombos; } } } \ No newline at end of file diff --git a/source/KadeEngineData.hx b/source/KadeEngineData.hx new file mode 100644 index 000000000..39275f318 --- /dev/null +++ b/source/KadeEngineData.hx @@ -0,0 +1,95 @@ +import openfl.Lib; +import flixel.FlxG; + +class KadeEngineData +{ + public static function initSave() + { + if (FlxG.save.data.newInput == null) + FlxG.save.data.newInput = true; + + if (FlxG.save.data.downscroll == null) + FlxG.save.data.downscroll = false; + + if (FlxG.save.data.dfjk == null) + FlxG.save.data.dfjk = false; + + if (FlxG.save.data.accuracyDisplay == null) + FlxG.save.data.accuracyDisplay = true; + + if (FlxG.save.data.offset == null) + FlxG.save.data.offset = 0; + + if (FlxG.save.data.songPosition == null) + FlxG.save.data.songPosition = false; + + if (FlxG.save.data.fps == null) + FlxG.save.data.fps = false; + + if (FlxG.save.data.changedHit == null) + { + FlxG.save.data.changedHitX = -1; + FlxG.save.data.changedHitY = -1; + FlxG.save.data.changedHit = false; + } + + if (FlxG.save.data.fpsRain == null) + FlxG.save.data.fpsRain = false; + + if (FlxG.save.data.fpsCap == null) + FlxG.save.data.fpsCap = 120; + + if (FlxG.save.data.fpsCap > 285 || FlxG.save.data.fpsCap < 60) + FlxG.save.data.fpsCap = 120; // baby proof so you can't hard lock ur copy of kade engine + + if (FlxG.save.data.scrollSpeed == null) + FlxG.save.data.scrollSpeed = 1; + + if (FlxG.save.data.npsDisplay == null) + FlxG.save.data.npsDisplay = false; + + if (FlxG.save.data.frames == null) + FlxG.save.data.frames = 10; + + if (FlxG.save.data.accuracyMod == null) + FlxG.save.data.accuracyMod = 1; + + if (FlxG.save.data.watermark == null) + FlxG.save.data.watermark = true; + + if (FlxG.save.data.ghost == null) + FlxG.save.data.ghost = true; + + if (FlxG.save.data.distractions == null) + FlxG.save.data.distractions = true; + + if (FlxG.save.data.flashing == null) + FlxG.save.data.flashing = true; + + if (FlxG.save.data.resetButton == null) + FlxG.save.data.resetButton = false; + + if (FlxG.save.data.botplay == null) + FlxG.save.data.botplay = false; + + if (FlxG.save.data.cpuStrums == null) + FlxG.save.data.cpuStrums = false; + + if (FlxG.save.data.strumline == null) + FlxG.save.data.strumline = false; + + if (FlxG.save.data.customStrumLine == null) + FlxG.save.data.customStrumLine = 0; + + if (FlxG.save.data.camzoom == null) + FlxG.save.data.camzoom = true; + + Conductor.recalculateTimings(); + PlayerSettings.player1.controls.loadKeyBinds(); + KeyBinds.keyCheck(); + + Main.watermarks = FlxG.save.data.watermark; + + (cast (Lib.current.getChildAt(0), Main)).setFPSCap(FlxG.save.data.fpsCap); + } +} \ No newline at end of file diff --git a/source/KeyBindMenu.hx b/source/KeyBindMenu.hx new file mode 100644 index 000000000..1d3f6e4e3 --- /dev/null +++ b/source/KeyBindMenu.hx @@ -0,0 +1,262 @@ +package; + +/// Code created by Rozebud for FPS Plus (thanks rozebud) +// modified by KadeDev for use in Kade Engine/Tricky + +import flixel.util.FlxAxes; +import flixel.FlxSubState; +import Options.Option; +import flixel.input.FlxInput; +import flixel.input.keyboard.FlxKey; +import flixel.FlxG; +import flixel.FlxObject; +import flixel.FlxSprite; +import flixel.effects.FlxFlicker; +import flixel.graphics.frames.FlxAtlasFrames; +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.text.FlxText; +import flixel.tweens.FlxEase; +import flixel.tweens.FlxTween; +import flixel.util.FlxColor; +import io.newgrounds.NG; +import lime.app.Application; +import lime.utils.Assets; +import flixel.math.FlxMath; +import flixel.text.FlxText; +import flixel.input.FlxKeyManager; + + +using StringTools; + +class KeyBindMenu extends FlxSubState +{ + + var keyTextDisplay:FlxText; + var keyWarning:FlxText; + var warningTween:FlxTween; + var keyText:Array = ["LEFT", "DOWN", "UP", "RIGHT"]; + var defaultKeys:Array = ["A", "S", "W", "D", "R"]; + var curSelected:Int = 0; + + var keys:Array = [FlxG.save.data.leftBind, + FlxG.save.data.downBind, + FlxG.save.data.upBind, + FlxG.save.data.rightBind]; + + var tempKey:String = ""; + var blacklist:Array = ["ESCAPE", "ENTER", "BACKSPACE", "SPACE"]; + + var blackBox:FlxSprite; + var infoText:FlxText; + + var state:String = "select"; + + override function create() + { + + for (i in 0...keys.length) + { + var k = keys[i]; + if (k == null) + keys[i] = defaultKeys[i]; + } + + //FlxG.sound.playMusic('assets/music/configurator' + TitleState.soundExt); + + persistentUpdate = persistentDraw = true; + + keyTextDisplay = new FlxText(-10, 0, 1280, "", 72); + keyTextDisplay.scrollFactor.set(0, 0); + keyTextDisplay.setFormat("VCR OSD Mono", 42, FlxColor.WHITE, FlxTextAlign.CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + keyTextDisplay.borderSize = 2; + keyTextDisplay.borderQuality = 3; + + blackBox = new FlxSprite(0,0).makeGraphic(FlxG.width,FlxG.height,FlxColor.BLACK); + add(blackBox); + + infoText = new FlxText(-10, 580, 1280, "(Escape to save, backspace to leave without saving)", 72); + infoText.scrollFactor.set(0, 0); + infoText.setFormat("VCR OSD Mono", 24, FlxColor.WHITE, FlxTextAlign.CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + infoText.borderSize = 2; + infoText.borderQuality = 3; + infoText.alpha = 0; + infoText.screenCenter(FlxAxes.X); + add(infoText); + add(keyTextDisplay); + + blackBox.alpha = 0; + keyTextDisplay.alpha = 0; + + FlxTween.tween(keyTextDisplay, {alpha: 1}, 1, {ease: FlxEase.expoInOut}); + FlxTween.tween(infoText, {alpha: 1}, 1.4, {ease: FlxEase.expoInOut}); + FlxTween.tween(blackBox, {alpha: 0.7}, 1, {ease: FlxEase.expoInOut}); + + OptionsMenu.instance.acceptInput = false; + + textUpdate(); + + super.create(); + } + + override function update(elapsed:Float) + { + + switch(state){ + + case "select": + if (FlxG.keys.justPressed.UP) + { + FlxG.sound.play(Paths.sound('scrollMenu')); + changeItem(-1); + } + + if (FlxG.keys.justPressed.DOWN) + { + FlxG.sound.play(Paths.sound('scrollMenu')); + changeItem(1); + } + + if (FlxG.keys.justPressed.ENTER){ + FlxG.sound.play(Paths.sound('scrollMenu')); + state = "input"; + } + else if(FlxG.keys.justPressed.ESCAPE){ + quit(); + } + else if (FlxG.keys.justPressed.BACKSPACE){ + reset(); + } + + case "input": + tempKey = keys[curSelected]; + keys[curSelected] = "?"; + textUpdate(); + state = "waiting"; + + case "waiting": + if(FlxG.keys.justPressed.ESCAPE){ + keys[curSelected] = tempKey; + state = "select"; + FlxG.sound.play(Paths.sound('confirmMenu')); + } + else if(FlxG.keys.justPressed.ENTER){ + addKey(defaultKeys[curSelected]); + save(); + state = "select"; + } + else if(FlxG.keys.justPressed.ANY){ + addKey(FlxG.keys.getIsDown()[0].ID.toString()); + save(); + state = "select"; + } + + + case "exiting": + + + default: + state = "select"; + + } + + if(FlxG.keys.justPressed.ANY) + textUpdate(); + + super.update(elapsed); + + } + + function textUpdate(){ + + keyTextDisplay.text = "\n\n"; + + for(i in 0...4){ + + var textStart = (i == curSelected) ? "> " : " "; + keyTextDisplay.text += textStart + keyText[i] + ": " + ((keys[i] != keyText[i]) ? (keys[i] + " / ") : "" ) + keyText[i] + " ARROW\n"; + + } + + keyTextDisplay.screenCenter(); + + } + + function save(){ + + FlxG.save.data.upBind = keys[2]; + FlxG.save.data.downBind = keys[1]; + FlxG.save.data.leftBind = keys[0]; + FlxG.save.data.rightBind = keys[3]; + + FlxG.save.flush(); + + PlayerSettings.player1.controls.loadKeyBinds(); + + } + + function reset(){ + + for(i in 0...5){ + keys[i] = defaultKeys[i]; + } + quit(); + + } + + function quit(){ + + state = "exiting"; + + save(); + + OptionsMenu.instance.acceptInput = true; + + FlxTween.tween(keyTextDisplay, {alpha: 0}, 1, {ease: FlxEase.expoInOut}); + FlxTween.tween(blackBox, {alpha: 0}, 1.1, {ease: FlxEase.expoInOut, onComplete: function(flx:FlxTween){close();}}); + FlxTween.tween(infoText, {alpha: 0}, 1, {ease: FlxEase.expoInOut}); + } + + + function addKey(r:String){ + + var shouldReturn:Bool = true; + + var notAllowed:Array = []; + + for(x in blacklist){notAllowed.push(x);} + + trace(notAllowed); + + for(x in 0...keys.length) + { + var oK = keys[x]; + if(oK == r) + keys[x] = null; + if (notAllowed.contains(oK)) + return; + } + + if(shouldReturn){ + keys[curSelected] = r; + FlxG.sound.play(Paths.sound('scrollMenu')); + } + else{ + keys[curSelected] = tempKey; + FlxG.sound.play(Paths.sound('scrollMenu')); + keyWarning.alpha = 1; + warningTween.cancel(); + warningTween = FlxTween.tween(keyWarning, {alpha: 0}, 0.5, {ease: FlxEase.circOut, startDelay: 2}); + } + + } + + function changeItem(_amount:Int = 0) + { + curSelected += _amount; + + if (curSelected > 3) + curSelected = 0; + if (curSelected < 0) + curSelected = 3; + } +} diff --git a/source/KeyBinds.hx b/source/KeyBinds.hx new file mode 100644 index 000000000..facd1adb3 --- /dev/null +++ b/source/KeyBinds.hx @@ -0,0 +1,50 @@ +import flixel.FlxG; +import flixel.input.FlxInput; +import flixel.input.actions.FlxAction; +import flixel.input.actions.FlxActionInput; +import flixel.input.actions.FlxActionInputDigital; +import flixel.input.actions.FlxActionManager; +import flixel.input.actions.FlxActionSet; +import flixel.input.gamepad.FlxGamepadButton; +import flixel.input.gamepad.FlxGamepadInputID; +import flixel.input.keyboard.FlxKey; + +class KeyBinds +{ + + public static function resetBinds():Void{ + + FlxG.save.data.upBind = "W"; + FlxG.save.data.downBind = "S"; + FlxG.save.data.leftBind = "A"; + FlxG.save.data.rightBind = "D"; + FlxG.save.data.killBind = "R"; + PlayerSettings.player1.controls.loadKeyBinds(); + + } + + public static function keyCheck():Void + { + if(FlxG.save.data.upBind == null){ + FlxG.save.data.upBind = "W"; + trace("No UP"); + } + if(FlxG.save.data.downBind == null){ + FlxG.save.data.downBind = "S"; + trace("No DOWN"); + } + if(FlxG.save.data.leftBind == null){ + FlxG.save.data.leftBind = "A"; + trace("No LEFT"); + } + if(FlxG.save.data.rightBind == null){ + FlxG.save.data.rightBind = "D"; + trace("No RIGHT"); + } + if(FlxG.save.data.killBind == null){ + FlxG.save.data.killBind = "R"; + trace("No KILL"); + } + } + +} \ No newline at end of file diff --git a/source/Keybinds.hx b/source/Keybinds.hx new file mode 100644 index 000000000..3403810f3 --- /dev/null +++ b/source/Keybinds.hx @@ -0,0 +1,96 @@ +class Keybinds +{ + public static function fill():Array> + { + return [ + [ + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_one1')) + ], + [ + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_two1')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_two2')) + ], + [ + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_three1')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_three2')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_three3')) + ], + [ + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_left')), //SWAGGER SOULS?? + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_down')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_up')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_right')) + ], + [ + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_five1')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_five2')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_five3')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_five4')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_five5')) + ], + [ + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_six1')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_six2')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_six3')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_six4')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_six5')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_six6')) + ], + [ + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_seven1')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_seven2')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_seven3')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_seven4')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_seven5')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_seven6')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_seven7')) + ], + [ + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_eight1')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_eight2')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_eight3')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_eight4')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_eight5')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_eight6')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_eight7')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_eight8')) + ], + [ + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_nine1')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_nine2')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_nine3')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_nine4')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_nine5')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_nine6')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_nine7')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_nine8')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_nine9')) + ], + [ + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_ten1')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_ten2')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_ten3')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_ten4')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_ten5')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_ten6')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_ten7')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_ten8')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_ten9')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_ten10')) + ], + [ + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_elev1')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_elev2')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_elev3')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_elev4')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_elev5')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_elev6')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_elev7')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_elev8')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_elev9')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_elev10')), + ClientPrefs.copyKey(ClientPrefs.keyBinds.get('note_elev11')) + ] + ]; + } +} \ No newline at end of file diff --git a/source/LoadReplayState.hx b/source/LoadReplayState.hx new file mode 100644 index 000000000..da9d39109 --- /dev/null +++ b/source/LoadReplayState.hx @@ -0,0 +1,211 @@ +package; + +import Controls.KeyboardScheme; +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; +#if sys +import sys.io.File; +#end + +class LoadReplayState extends MusicBeatState +{ + var selector:FlxText; + var curSelected:Int = 0; + + var songs:Array = []; + + var controlsStrings:Array = []; + var actualNames:Array = []; + + private var grpControls:FlxTypedGroup; + var versionShit:FlxText; + var poggerDetails:FlxText; + override function create() + { + var menuBG:FlxSprite = new FlxSprite().loadGraphic(Paths.image('menuDesat')); + #if sys + controlsStrings = sys.FileSystem.readDirectory(Sys.getCwd() + "/assets/replays/"); + #end + trace(controlsStrings); + + controlsStrings.sort(Reflect.compare); + + addWeek(['Bopeebo', 'Fresh', 'Dadbattle'], 1, ['dad']); + addWeek(['Spookeez', 'South', 'Monster'], 2, ['spooky']); + addWeek(['Pico', 'Philly', 'Blammed'], 3, ['pico']); + + addWeek(['Satin-Panties', 'High', 'Milf'], 4, ['mom']); + addWeek(['Cocoa', 'Eggnog', 'Winter-Horrorland'], 5, ['parents-christmas', 'parents-christmas', 'monster-christmas']); + + addWeek(['Senpai', 'Roses', 'Thorns'], 6, ['senpai', 'senpai', 'spirit']); + + + for(i in 0...controlsStrings.length) + { + var string:String = controlsStrings[i]; + actualNames[i] = string; + var rep:Replay = Replay.LoadReplay(string); + controlsStrings[i] = string.split("time")[0] + " " + (rep.replay.songDiff == 2 ? "HARD" : rep.replay.songDiff == 1 ? "EASY" : "NORMAL"); + } + + if (controlsStrings.length == 0) + controlsStrings.push("No Replays..."); + + menuBG.color = 0xFFea71fd; + menuBG.setGraphicSize(Std.int(menuBG.width * 1.1)); + menuBG.updateHitbox(); + menuBG.screenCenter(); + menuBG.antialiasing = true; + add(menuBG); + + grpControls = new FlxTypedGroup(); + add(grpControls); + + for (i in 0...controlsStrings.length) + { + var controlLabel:Alphabet = new Alphabet(0, (70 * i) + 30, controlsStrings[i], true, false); + controlLabel.isMenuItem = true; + controlLabel.targetY = i; + grpControls.add(controlLabel); + // DONT PUT X IN THE FIRST PARAMETER OF new ALPHABET() !! + } + + + versionShit = new FlxText(5, FlxG.height - 34, 0, "Replay Loader (ESCAPE TO GO BACK)\nNOTICE!!!! Replays are in a beta stage, and they are probably not 100% correct. expect misses and other stuff that isn't there!\n", 12); + versionShit.scrollFactor.set(); + versionShit.setFormat("VCR OSD Mono", 16, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + add(versionShit); + + + poggerDetails = new FlxText(5, 34, 0, "Replay Details - \nnone", 12); + poggerDetails.scrollFactor.set(); + poggerDetails.setFormat("VCR OSD Mono", 16, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + add(poggerDetails); + + changeSelection(0); + + super.create(); + } + + public function getWeekNumbFromSong(songName:String):Int + { + var week:Int = 0; + for (i in 0...songs.length) + { + var pog:FreeplayState.SongMetadata = songs[i]; + if (pog.songName == songName) + week = pog.week; + } + return week; + } + + public function addSong(songName:String, weekNum:Int, songCharacter:String, color:Int) + { + songs.push(new FreeplayState.SongMetadata(songName, weekNum, songCharacter, color)); + } + + public function addWeek(songs:Array, weekNum:Int, ?songCharacters:Array) + { + if (songCharacters == null) + songCharacters = ['bf']; + + var num:Int = 0; + for (song in songs) + { + addSong(song, weekNum, songCharacters[num], FlxColor.WHITE); + + if (songCharacters.length != 1) + num++; + } + } + + + override function update(elapsed:Float) + { + super.update(elapsed); + + if (controls.BACK) + FlxG.switchState(new OptionsMenu()); + if (controls.UP_P) + changeSelection(-1); + if (controls.DOWN_P) + changeSelection(1); + + + if (controls.ACCEPT && grpControls.members[curSelected].text != "No Replays...") + { + trace('loading ' + actualNames[curSelected]); + PlayState.rep = Replay.LoadReplay(actualNames[curSelected]); + + PlayState.loadRep = true; + + // adjusting the song name to be compatible + var songFormat = StringTools.replace(PlayState.rep.replay.songName, " ", "-"); + switch (songFormat) { + case 'Dad-Battle': songFormat = 'Dadbattle'; + case 'Philly-Nice': songFormat = 'Philly'; + // Replay v1.0 support + case 'dad-battle': songFormat = 'Dadbattle'; + case 'philly-nice': songFormat = 'Philly'; + } + + var poop:String = Highscore.formatSong(songFormat, PlayState.rep.replay.songDiff); + + PlayState.SONG = Song.loadFromJson(poop, PlayState.rep.replay.songName); + PlayState.isStoryMode = false; + PlayState.storyDifficulty = PlayState.rep.replay.songDiff; + PlayState.storyWeek = getWeekNumbFromSong(PlayState.rep.replay.songName); + LoadingState.loadAndSwitchState(new PlayState()); + } + } + + var isSettingControl:Bool = false; + + function changeSelection(change:Int = 0) + { + #if !switch + // NGio.logEvent('Fresh'); + #end + + FlxG.sound.play(Paths.sound('scrollMenu'), 0.4); + + curSelected += change; + + if (curSelected < 0) + curSelected = grpControls.length - 1; + if (curSelected >= grpControls.length) + curSelected = 0; + + var rep:Replay = Replay.LoadReplay(actualNames[curSelected]); + + poggerDetails.text = "Replay Details - \nDate Created: " + rep.replay.timestamp + "\nSong: " + rep.replay.songName + "\nReplay Version: " + rep.replay.replayGameVer + ' (' + (rep.replay.replayGameVer != Replay.version ? "OUTDATED but still usable" : "Latest") + ')\n'; + + // 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/LoadingState.hx b/source/LoadingState.hx index 0e49eb85b..23bce2e68 100644 --- a/source/LoadingState.hx +++ b/source/LoadingState.hx @@ -7,7 +7,6 @@ import flixel.FlxState; import flixel.FlxSprite; import flixel.graphics.frames.FlxAtlasFrames; import flixel.util.FlxTimer; -import flixel.math.FlxMath; import openfl.utils.Assets; import lime.utils.Assets as LimeAssets; @@ -19,45 +18,40 @@ import haxe.io.Path; class LoadingState extends MusicBeatState { inline static var MIN_TIME = 1.0; - - // Browsers will load create(), you can make your song load a custom directory there - // If you're compiling to desktop (or something that doesn't use NO_PRELOAD_ALL), search for getNextState instead - // I'd recommend doing it on both actually lol - - // TO DO: Make this easier var target:FlxState; var stopMusic = false; - var directory:String; var callbacks:MultiCallback; - var targetShit:Float = 0; - - function new(target:FlxState, stopMusic:Bool, directory:String) + + var logo:FlxSprite; + var gfDance:FlxSprite; + var danceLeft = false; + + function new(target:FlxState, stopMusic:Bool) { super(); this.target = target; this.stopMusic = stopMusic; - this.directory = directory; } - - var funkay:FlxSprite; - var loadBar:FlxSprite; + override function create() { - var bg:FlxSprite = new FlxSprite(0, 0).makeGraphic(FlxG.width, FlxG.height, 0xffcaff4d); - add(bg); - funkay = new FlxSprite(0, 0).loadGraphic(Paths.getPath('images/funkay.png', IMAGE)); - funkay.setGraphicSize(0, FlxG.height); - funkay.updateHitbox(); - funkay.antialiasing = ClientPrefs.globalAntialiasing; - add(funkay); - funkay.scrollFactor.set(); - funkay.screenCenter(); + logo = new FlxSprite(-150, -100); + logo.frames = Paths.getSparrowAtlas('logoBumpin'); + logo.antialiasing = true; + logo.animation.addByPrefix('bump', 'logo bumpin', 24); + logo.animation.play('bump'); + logo.updateHitbox(); + // logoBl.screenCenter(); + // logoBl.color = FlxColor.BLACK; - loadBar = new FlxSprite(0, FlxG.height - 20).makeGraphic(FlxG.width, 10, 0xffff16d2); - loadBar.screenCenter(X); - loadBar.antialiasing = ClientPrefs.globalAntialiasing; - add(loadBar); + gfDance = new FlxSprite(FlxG.width * 0.4, FlxG.height * 0.07); + gfDance.frames = Paths.getSparrowAtlas('gfDanceTitle'); + 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; + add(gfDance); + add(logo); initSongsManifest().onComplete ( @@ -65,16 +59,15 @@ class LoadingState extends MusicBeatState { callbacks = new MultiCallback(onLoad); var introComplete = callbacks.add("introComplete"); - if (PlayState.SONG != null) { - checkLoadSong(getSongPath()); - if (PlayState.SONG.needsVoices) - checkLoadSong(getVocalPath()); - } + checkLoadSong(getSongPath()); + if (PlayState.SONG.needsVoices) + checkLoadSong(getVocalPath()); checkLibrary("shared"); - if(directory != null && directory.length > 0 && directory != 'shared') { - checkLibrary(directory); - } - + if (PlayState.storyWeek > 0) + checkLibrary("week" + PlayState.storyWeek); + else + checkLibrary("tutorial"); + var fadeTime = 0.5; FlxG.camera.fade(FlxG.camera.bgColor, fadeTime, true); new FlxTimer().start(fadeTime + MIN_TIME, function(_) introComplete()); @@ -97,34 +90,40 @@ class LoadingState extends MusicBeatState } } - function checkLibrary(library:String) { + function checkLibrary(library:String) + { trace(Assets.hasLibrary(library)); if (Assets.getLibrary(library) == null) { @:privateAccess if (!LimeAssets.libraryPaths.exists(library)) throw "Missing library: " + library; - + var callback = callbacks.add("library:" + library); Assets.loadLibrary(library).onComplete(function (_) { callback(); }); } } + override function beatHit() + { + super.beatHit(); + + logo.animation.play('bump'); + danceLeft = !danceLeft; + + if (danceLeft) + gfDance.animation.play('danceRight'); + else + gfDance.animation.play('danceLeft'); + } + override function update(elapsed:Float) { super.update(elapsed); - funkay.setGraphicSize(Std.int(0.88 * FlxG.width + 0.9 * (funkay.width - 0.88 * FlxG.width))); - funkay.updateHitbox(); - if(controls.ACCEPT) - { - funkay.setGraphicSize(Std.int(funkay.width + 60)); - funkay.updateHitbox(); - } - - if(callbacks != null) { - targetShit = FlxMath.remapToRange(callbacks.numRemaining / callbacks.length, 1, 0, 0, 1); - loadBar.scale.x += 0.5 * (targetShit - loadBar.scale.x); - } + #if debug + if (FlxG.keys.justPressed.SPACE) + trace('fired: ' + callbacks.getFired() + " unfired:" + callbacks.getUnfired()); + #end } function onLoad() @@ -132,7 +131,7 @@ class LoadingState extends MusicBeatState if (stopMusic && FlxG.sound.music != null) FlxG.sound.music.stop(); - MusicBeatState.switchState(target); + FlxG.switchState(target); } static function getSongPath() @@ -147,28 +146,19 @@ class LoadingState extends MusicBeatState inline static public function loadAndSwitchState(target:FlxState, stopMusic = false) { - MusicBeatState.switchState(getNextState(target, stopMusic)); + FlxG.switchState(getNextState(target, stopMusic)); } static function getNextState(target:FlxState, stopMusic = false):FlxState { - var directory:String = 'shared'; - var weekDir:String = StageData.forceNextDirectory; - StageData.forceNextDirectory = null; - - if(weekDir != null && weekDir.length > 0 && weekDir != '') directory = weekDir; - - Paths.setCurrentLevel(directory); - trace('Setting asset folder to ' + directory); - + Paths.setCurrentLevel("week" + PlayState.storyWeek); #if NO_PRELOAD_ALL - var loaded:Bool = false; - if (PlayState.SONG != null) { - loaded = isSoundLoaded(getSongPath()) && (!PlayState.SONG.needsVoices || isSoundLoaded(getVocalPath())) && isLibraryLoaded("shared") && isLibraryLoaded(directory); - } + var loaded = isSoundLoaded(getSongPath()) + && (!PlayState.SONG.needsVoices || isSoundLoaded(getVocalPath())) + && isLibraryLoaded("shared"); if (!loaded) - return new LoadingState(target, stopMusic, directory); + return new LoadingState(target, stopMusic); #end if (stopMusic && FlxG.sound.music != null) FlxG.sound.music.stop(); diff --git a/source/LuaClass.hx b/source/LuaClass.hx new file mode 100644 index 000000000..2180dc0f0 --- /dev/null +++ b/source/LuaClass.hx @@ -0,0 +1,1884 @@ +#if desktop +import flixel.FlxG; +import llua.Convert; +import llua.Lua; +import llua.State; +import llua.LuaL; +import flixel.util.FlxAxes; +import flixel.FlxSprite; +import lime.app.Application; +import openfl.Lib; + +#if desktop +import sys.io.File; +import sys.FileSystem; +#end + +import flash.display.BitmapData; +import flixel.graphics.frames.FlxAtlasFrames; +import flixel.FlxCamera; +import flixel.tweens.FlxEase; +import flixel.tweens.FlxTween; +import haxe.DynamicAccess; + +// completely yoinked from andromeda (thats what you get for stealing my callback inputs you fuckers /j) + +typedef LuaProperty = +{ + var defaultValue:Any; + var getter:(State, Any) -> Int; + var setter:State->Int; +} + +class LuaStorage +{ + public static var ListOfCameras:Array = []; + public static var objectProperties:Map> = []; + public static var objects:Map = []; +} + +class LuaClass +{ + public var properties:Map = []; + public var methods:MapInt>> = []; + public var className:String = "BaseClass"; + + private static var state:State; + + public var addToGlobal:Bool = true; + + public function Register(l:State) + { + Lua.newtable(l); + state = l; + LuaStorage.objectProperties[className] = this.properties; + + var classIdx = Lua.gettop(l); + Lua.pushvalue(l, classIdx); + if (addToGlobal) + Lua.setglobal(l, className); + + for (k in methods.keys()) + { + Lua.pushcfunction(l, methods[k]); + Lua.setfield(l, classIdx, k); + } + + LuaL.newmetatable(l, className + "Metatable"); + var mtIdx = Lua.gettop(l); + Lua.pushstring(l, "__index"); + Lua.pushcfunction(l, cpp.Callable.fromStaticFunction(index)); + Lua.settable(l, mtIdx); + + Lua.pushstring(l, "__newindex"); + Lua.pushcfunction(l, cpp.Callable.fromStaticFunction(newindex)); + Lua.settable(l, mtIdx); + + for (k in properties.keys()) + { + Lua.pushstring(l, k + "PropertyData"); + Convert.toLua(l, properties[k].defaultValue); + Lua.settable(l, mtIdx); + } + Lua.pushstring(l, "_CLASSNAME"); + Lua.pushstring(l, className); + Lua.settable(l, mtIdx); + + Lua.pushstring(l, "__metatable"); + Lua.pushstring(l, "This metatable is locked."); + Lua.settable(l, mtIdx); + + Lua.setmetatable(l, classIdx); + }; + + public static function index(l:StatePointer):Int + { + var l = state; + var index = Lua.tostring(l, -1); + if (Lua.getmetatable(l, -2) != 0) + { + var mtIdx = Lua.gettop(l); + Lua.pushstring(l, index + "PropertyData"); + Lua.rawget(l, mtIdx); + var data:Any = Convert.fromLua(l, -1); + if (data != null) + { + Lua.pushstring(l, "_CLASSNAME"); + Lua.rawget(l, mtIdx); + var clName = Lua.tostring(l, -1); + if (LuaStorage.objectProperties[clName] != null && LuaStorage.objectProperties[clName][index] != null) + { + return LuaStorage.objectProperties[clName][index].getter(l, data); + } + }; + } + else + { + // TODO: throw an error! + }; + return 0; + } + + public static function newindex(l:StatePointer):Int + { + var l = state; + var index = Lua.tostring(l, 2); + if (Lua.getmetatable(l, 1) != 0) + { + var mtIdx = Lua.gettop(l); + Lua.pushstring(l, index + "PropertyData"); + Lua.rawget(l, mtIdx); + var data:Any = Convert.fromLua(l, -1); + if (data != null) + { + Lua.pushstring(l, "_CLASSNAME"); + Lua.rawget(l, mtIdx); + var clName = Lua.tostring(l, -1); + if (LuaStorage.objectProperties[clName] != null && LuaStorage.objectProperties[clName][index] != null) + { + Lua.pop(l, 2); + return LuaStorage.objectProperties[clName][index].setter(l); + } + }; + } + else + { + // TODO: throw an error! + }; + return 0; + } + + public static function SetProperty(l:State, tableIndex:Int, key:String, value:Any) + { + Lua.pushstring(l, key + "PropertyData"); + Convert.toLua(l, value); + Lua.settable(l, tableIndex); + + Lua.pop(l, 2); + } + + public static function DefaultSetter(l:State) + { + var key = Lua.tostring(l, 2); + + Lua.pushstring(l, key + "PropertyData"); + Lua.pushvalue(l, 3); + Lua.settable(l, 4); + + Lua.pop(l, 2); + }; + + public function new() + { + } +} + +class LuaNote extends LuaClass +{ // again, stolen from andromeda but improved a lot for better thinking interoperability (I made that up) + private static var state:State; + + public var note:Note; + + public function new(connectedNote:Note, index:Int) + { + super(); + className = "note_" + index; + + note = connectedNote; + + properties = [ + "alpha" => { + defaultValue: 1, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, connectedNote.alpha); + return 1; + }, + setter: SetNumProperty + }, + + "angle" => { + defaultValue: 1, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, connectedNote.angle); + return 1; + }, + setter: function(l:State):Int + { + // 1 = self + // 2 = key + // 3 = value + // 4 = metatable + if (Lua.type(l, 3) != Lua.LUA_TNUMBER) + { + LuaL.error(l, "invalid argument #3 (number expected, got " + Lua.typename(l, Lua.type(l, 3)) + ")"); + return 0; + } + + var angle = Lua.tonumber(l, 3); + connectedNote.modAngle = angle; + + LuaClass.DefaultSetter(l); + return 0; + } + }, + + "strumTime" => { + defaultValue: 1, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, connectedNote.strumTime); + return 1; + }, + setter: function(l:State):Int + { + // 1 = self + // 2 = key + // 3 = value + // 4 = metatable + // mf you can't modify this shit + return 0; + } + }, + + "data" => { + defaultValue: 1, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, connectedNote.noteData); + return 1; + }, + setter: SetNumProperty + }, + + "mustPress" => { + defaultValue: 1, + getter: function(l:State, data:Any):Int + { + Lua.pushboolean(l, connectedNote.mustPress); + return 1; + }, + setter: SetNumProperty + }, + + "x" => { + defaultValue: connectedNote.x, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, connectedNote.x); + return 1; + }, + setter: SetNumProperty + }, + + "tweenPos" => { + defaultValue: 0, + getter: function(l:State, data:Any) + { + Lua.pushcfunction(l, tweenPosC); + return 1; + }, + setter: function(l:State) + { + LuaL.error(l, "tweenPos is read-only."); + return 0; + } + }, + + "tweenAlpha" => { + defaultValue: 0, + getter: function(l:State, data:Any) + { + Lua.pushcfunction(l, tweenAlphaC); + return 1; + }, + setter: function(l:State) + { + LuaL.error(l, "tweenAlpha is read-only."); + return 0; + } + }, + + "tweenAngle" => { + defaultValue: 0, + getter: function(l:State, data:Any) + { + Lua.pushcfunction(l, tweenAngleC); + return 1; + }, + setter: function(l:State) + { + LuaL.error(l, "tweenAngle is read-only."); + return 0; + } + }, + + "yNoteOff" => { + defaultValue: 0, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, connectedNote.offsetY); + return 1; + }, + setter: SetNumProperty + }, + + "y" => { + defaultValue: connectedNote.y, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, connectedNote.y); + return 1; + }, + setter: SetNumProperty + } + + ]; + } + + private static function findNote(time:Float, data:Int) + { + for (i in PlayState.instance.notes) + { + if (i.strumTime == time && i.noteData == data) + { + return i; + } + } + return null; + } + + private static function tweenPos(l:StatePointer):Int + { + // 1 = self + // 2 = x + // 3 = y + // 4 = time + var xp = LuaL.checknumber(state, 2); + var yp = LuaL.checknumber(state, 3); + var time = LuaL.checknumber(state, 4); + + Lua.getfield(state, 1, "strumTime"); + var time = Lua.tonumber(state, -1); + Lua.getfield(state, 1, "data"); + var data = Lua.tonumber(state, -1); + + var note = findNote(time, Math.floor(data)); + + if (note == null) + { + LuaL.error(state, "Failure to tween (couldn't find note " + time + ")"); + return 0; + } + + FlxTween.tween(note, {x: xp, y: yp}, time); + + return 0; + } + + private static function tweenAngle(l:StatePointer):Int + { + // 1 = self + // 2 = angle + // 3 = time + var nangle = LuaL.checknumber(state, 2); + var time = LuaL.checknumber(state, 3); + + Lua.getfield(state, 1, "strumTime"); + var time = Lua.tonumber(state, -1); + Lua.getfield(state, 1, "data"); + var data = Lua.tonumber(state, -1); + + var note = findNote(time, Math.floor(data)); + + if (note == null) + { + LuaL.error(state, "Failure to tween (couldn't find note " + time + ")"); + return 0; + } + + FlxTween.tween(note, {modAngle: nangle}, time); + + return 0; + } + + private static function tweenAlpha(l:StatePointer):Int + { + // 1 = self + // 2 = alpha + // 3 = time + var nalpha = LuaL.checknumber(state, 2); + var time = LuaL.checknumber(state, 3); + + Lua.getfield(state, 1, "strumTime"); + var time = Lua.tonumber(state, -1); + Lua.getfield(state, 1, "data"); + var data = Lua.tonumber(state, -1); + + var note = findNote(time, Math.floor(data)); + + if (note == null) + { + LuaL.error(state, "Failure to tween (couldn't find note " + time + ")"); + return 0; + } + FlxTween.tween(note, {alpha: nalpha}, time); + + return 0; + } + + private static var tweenPosC:cpp.CallableInt> = cpp.Callable.fromStaticFunction(tweenPos); + private static var tweenAngleC:cpp.CallableInt> = cpp.Callable.fromStaticFunction(tweenAngle); + private static var tweenAlphaC:cpp.CallableInt> = cpp.Callable.fromStaticFunction(tweenAlpha); + + private function SetNumProperty(l:State) + { + // 1 = self + // 2 = key + // 3 = value + // 4 = metatable + if (Lua.type(l, 3) != Lua.LUA_TNUMBER) + { + LuaL.error(l, "invalid argument #3 (number expected, got " + Lua.typename(l, Lua.type(l, 3)) + ")"); + return 0; + } + note.modifiedByLua = true; + Reflect.setProperty(note, Lua.tostring(l, 2), Lua.tonumber(l, 3)); + return 0; + } + + override function Register(l:State) + { + state = l; + super.Register(l); + } +} + +class LuaReceptor extends LuaClass +{ // again, stolen from andromeda but improved a lot for better thinking interoperability (I made that up) + private static var state:State; + + public var sprite:StrumNote; + + public function new(connectedSprite:StrumNote, name:String) + { + super(); + var defaultY = connectedSprite.y; + var defaultX = connectedSprite.x; + var defaultAngle = connectedSprite.angle; + + sprite = connectedSprite; + + className = name; + + properties = [ + "alpha" => { + defaultValue: 1, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, connectedSprite.alpha); + return 1; + }, + setter: SetNumProperty + }, + + "id" => { + defaultValue: name, + getter: function(l:State, data:Any):Int + { + Lua.pushstring(l, name); + return 1; + }, + setter: SetNumProperty + }, + + "angle" => { + defaultValue: 0, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, connectedSprite.angle); + return 1; + }, + setter: function(l:State):Int + { + // 1 = self + // 2 = key + // 3 = value + // 4 = metatable + if (Lua.type(l, 3) != Lua.LUA_TNUMBER) + { + LuaL.error(l, "invalid argument #3 (number expected, got " + Lua.typename(l, Lua.type(l, 3)) + ")"); + return 0; + } + + var angle = Lua.tonumber(l, 3); + connectedSprite.modAngle = angle; + + LuaClass.DefaultSetter(l); + return 0; + } + }, + + "x" => { + defaultValue: connectedSprite.x, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, connectedSprite.x); + return 1; + }, + setter: SetNumProperty + }, + + "y" => { + defaultValue: connectedSprite.y, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, connectedSprite.y); + return 1; + }, + setter: SetNumProperty + }, + + "defaultAngle" => { + defaultValue: defaultAngle, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, defaultAngle); + return 1; + }, + setter: SetNumProperty + }, + + "defaultX" => { + defaultValue: defaultX, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, defaultX); + return 1; + }, + setter: SetNumProperty + }, + + "tweenPos" => { + defaultValue: 0, + getter: function(l:State, data:Any) + { + Lua.pushcfunction(l, tweenPosC); + return 1; + }, + setter: function(l:State) + { + LuaL.error(l, "tweenPos is read-only."); + return 0; + } + }, + + "tweenAlpha" => { + defaultValue: 0, + getter: function(l:State, data:Any) + { + Lua.pushcfunction(l, tweenAlphaC); + return 1; + }, + setter: function(l:State) + { + LuaL.error(l, "tweenAlpha is read-only."); + return 0; + } + }, + + "tweenAngle" => { + defaultValue: 0, + getter: function(l:State, data:Any) + { + Lua.pushcfunction(l, tweenAngleC); + return 1; + }, + setter: function(l:State) + { + LuaL.error(l, "tweenAngle is read-only."); + return 0; + } + }, + + "defaultY" => { + defaultValue: defaultY, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, defaultY); + return 1; + }, + setter: function(l:State):Int + { + // 1 = self + // 2 = key + // 3 = value + // 4 = metatable + return 0; + } + } + + ]; + } + + private static function findReceptor(index:Int) + { + for (i in 0...PlayState.instance.strumLineNotes.length) + { + if (index == i) + { + return PlayState.instance.strumLineNotes.members[i]; + } + } + return null; + } + + private static function tweenPos(l:StatePointer):Int + { + // 1 = self + // 2 = x + // 3 = y + // 4 = time + var xp = LuaL.checknumber(state, 2); + var yp = LuaL.checknumber(state, 3); + var time = LuaL.checknumber(state, 4); + + Lua.getfield(state, 1, "id"); + var index = Std.parseInt(Lua.tostring(state, -1).split('_')[1]); + + var receptor = findReceptor(index); + + if (receptor == null) + { + LuaL.error(state, "Failure to tween (couldn't find receptor " + index + ")"); + return 0; + } + + FlxTween.tween(receptor, {x: xp, y: yp}, time); + + return 0; + } + + private static function tweenAngle(l:StatePointer):Int + { + // 1 = self + // 2 = angle + // 3 = time + var nangle = LuaL.checknumber(state, 2); + var time = LuaL.checknumber(state, 3); + + Lua.getfield(state, 1, "id"); + var index = Std.parseInt(Lua.tostring(state, -1).split('_')[1]); + + var receptor = findReceptor(index); + + if (receptor == null) + { + LuaL.error(state, "Failure to tween (couldn't find receptor " + index + ")"); + return 0; + } + + FlxTween.tween(receptor, {modAngle: nangle}, time); + + return 0; + } + + private static function tweenAlpha(l:StatePointer):Int + { + // 1 = self + // 2 = alpha + // 3 = time + var nalpha = LuaL.checknumber(state, 2); + var time = LuaL.checknumber(state, 3); + + Lua.getfield(state, 1, "id"); + var index = Std.parseInt(Lua.tostring(state, -1).split('_')[1]); + + var receptor = findReceptor(index); + + if (receptor == null) + { + LuaL.error(state, "Failure to tween (couldn't find receptor " + index + ")"); + return 0; + } + + FlxTween.tween(receptor, {alpha: nalpha}, time); + + return 0; + } + + private static var tweenPosC:cpp.CallableInt> = cpp.Callable.fromStaticFunction(tweenPos); + private static var tweenAngleC:cpp.CallableInt> = cpp.Callable.fromStaticFunction(tweenAngle); + private static var tweenAlphaC:cpp.CallableInt> = cpp.Callable.fromStaticFunction(tweenAlpha); + + private function SetNumProperty(l:State) + { + // 1 = self + // 2 = key + // 3 = value + // 4 = metatable + if (Lua.type(l, 3) != Lua.LUA_TNUMBER) + { + LuaL.error(l, "invalid argument #3 (number expected, got " + Lua.typename(l, Lua.type(l, 3)) + ")"); + return 0; + } + + sprite.modifiedByLua = true; + + Reflect.setProperty(sprite, Lua.tostring(l, 2), Lua.tonumber(l, 3)); + return 0; + } + + override function Register(l:State) + { + state = l; + super.Register(l); + trace("Registered " + className); + } +} + +class LuaCamera extends LuaClass +{ // again, stolen from andromeda but improved a lot for better thinking interoperability (I made that up) + private static var state:State; + + public var cam:FlxCamera; + + public function new(connectedCamera:FlxCamera, name:String) + { + super(); + cam = connectedCamera; + + className = name; + + properties = [ + "alpha" => { + defaultValue: 1, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, connectedCamera.alpha); + return 1; + }, + setter: SetNumProperty + }, + + "angle" => { + defaultValue: 0, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, connectedCamera.angle); + return 1; + }, + setter: SetNumProperty + }, + + "x" => { + defaultValue: connectedCamera.x, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, connectedCamera.x); + return 1; + }, + setter: SetNumProperty + }, + + "y" => { + defaultValue: connectedCamera.y, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, connectedCamera.y); + return 1; + }, + setter: SetNumProperty + }, + + "id" => { + defaultValue: className, + getter: function(l:State, data:Any):Int + { + Lua.pushstring(l, className); + return 1; + }, + setter: SetNumProperty + }, + + "tweenZoom" => { + defaultValue: 0, + getter: function(l:State, data:Any) + { + Lua.pushcfunction(l, tweenZoomC); + return 1; + }, + setter: function(l:State) + { + LuaL.error(l, "tweenZoom is read-only."); + return 0; + } + }, + + "tweenPos" => { + defaultValue: 0, + getter: function(l:State, data:Any) + { + Lua.pushcfunction(l, tweenPosC); + return 1; + }, + setter: function(l:State) + { + LuaL.error(l, "tweenPos is read-only."); + return 0; + } + }, + + "tweenAlpha" => { + defaultValue: 0, + getter: function(l:State, data:Any) + { + Lua.pushcfunction(l, tweenAlphaC); + return 1; + }, + setter: function(l:State) + { + LuaL.error(l, "tweenAlpha is read-only."); + return 0; + } + }, + + "tweenAngle" => { + defaultValue: 0, + getter: function(l:State, data:Any) + { + Lua.pushcfunction(l, tweenAngleC); + return 1; + }, + setter: function(l:State) + { + LuaL.error(l, "tweenAngle is read-only."); + return 0; + } + }, + ]; + + LuaStorage.ListOfCameras.push(this); + } + + private function SetNumProperty(l:State) + { + // 1 = self + // 2 = key + // 3 = value + // 4 = metatable + if (Lua.type(l, 3) != Lua.LUA_TNUMBER) + { + LuaL.error(l, "invalid argument #3 (number expected, got " + Lua.typename(l, Lua.type(l, 3)) + ")"); + return 0; + } + Reflect.setProperty(cam, Lua.tostring(l, 2), Lua.tonumber(l, 3)); + return 0; + } + + private static function tweenZoom(l:StatePointer):Int + { + // 1 = self + // 2 = zoom + // 3 = time + var nzoom = LuaL.checknumber(state, 2); + var time = LuaL.checknumber(state, 3); + + Lua.getfield(state, 1, "id"); + var index = Lua.tostring(state, -1); + + var camera:FlxCamera = null; + + for (i in LuaStorage.ListOfCameras) + { + if (i.className == index) + { + camera = i.cam; + } + } + + if (camera == null) + { + LuaL.error(state, "Failure to tween (couldn't find camera " + index + ")"); + return 0; + } + + FlxTween.tween(camera, {zoom: nzoom}, time); + + return 0; + } + + private static var tweenZoomC:cpp.CallableInt> = cpp.Callable.fromStaticFunction(tweenZoom); + + private static function tweenPos(l:StatePointer):Int + { + // 1 = self + // 2 = x + // 3 = y + // 4 = time + var xp = LuaL.checknumber(state, 2); + var yp = LuaL.checknumber(state, 3); + var time = LuaL.checknumber(state, 4); + + Lua.getfield(state, 1, "id"); + var index = Lua.tostring(state, -1); + + var camera:FlxCamera = null; + + for (i in LuaStorage.ListOfCameras) + { + if (i.className == index) + camera = i.cam; + } + + if (camera == null) + { + LuaL.error(state, "Failure to tween (couldn't find camera " + index + ")"); + return 0; + } + + FlxTween.tween(camera, {x: xp, y: yp}, time); + + return 0; + } + + private static function tweenAngle(l:StatePointer):Int + { + // 1 = self + // 2 = angle + // 3 = time + var nangle = LuaL.checknumber(state, 2); + var time = LuaL.checknumber(state, 3); + + Lua.getfield(state, 1, "id"); + var index = Lua.tostring(state, -1); + + var camera:FlxCamera = null; + + for (i in LuaStorage.ListOfCameras) + { + if (i.className == index) + camera = i.cam; + } + + if (camera == null) + { + LuaL.error(state, "Failure to tween (couldn't find camera " + index + ")"); + return 0; + } + + FlxTween.tween(camera, {modAngle: nangle}, time); + + return 0; + } + + private static function tweenAlpha(l:StatePointer):Int + { + // 1 = self + // 2 = alpha + // 3 = time + var nalpha = LuaL.checknumber(state, 2); + var time = LuaL.checknumber(state, 3); + + Lua.getfield(state, 1, "id"); + var index = Lua.tostring(state, -1); + + var camera:FlxCamera = null; + + for (i in LuaStorage.ListOfCameras) + { + if (i.className == index) + camera = i.cam; + } + + if (camera == null) + { + LuaL.error(state, "Failure to tween (couldn't find camera " + index + ")"); + return 0; + } + + FlxTween.tween(camera, {alpha: nalpha}, time); + + return 0; + } + + private static var tweenPosC:cpp.CallableInt> = cpp.Callable.fromStaticFunction(tweenPos); + private static var tweenAngleC:cpp.CallableInt> = cpp.Callable.fromStaticFunction(tweenAngle); + private static var tweenAlphaC:cpp.CallableInt> = cpp.Callable.fromStaticFunction(tweenAlpha); + + override function Register(l:State) + { + state = l; + super.Register(l); + trace("Registered " + className); + } +} + +class LuaCharacter extends LuaClass +{ // again, stolen from andromeda but improved a lot for better thinking interoperability (I made that up) + private static var state:State; + + public var char:Character; + public var isPlayer:Bool = false; + + public static var ListOfCharacters:Array = []; + + public function new(connectedCharacter:Character, name:String) + { + super(); + className = name; + + char = connectedCharacter; + + isPlayer = char.isPlayer; + + properties = [ + "alpha" => { + defaultValue: 1, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, connectedCharacter.alpha); + return 1; + }, + setter: SetNumProperty + }, + + "angle" => { + defaultValue: 1, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, connectedCharacter.angle); + return 1; + }, + setter: function(l:State):Int + { + // 1 = self + // 2 = key + // 3 = value + // 4 = metatable + if (Lua.type(l, 3) != Lua.LUA_TNUMBER) + { + LuaL.error(l, "invalid argument #3 (number expected, got " + Lua.typename(l, Lua.type(l, 3)) + ")"); + return 0; + } + + var angle = Lua.tonumber(l, 3); + connectedCharacter.angle = angle; + + LuaClass.DefaultSetter(l); + return 0; + } + }, + + "x" => { + defaultValue: connectedCharacter.x, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, connectedCharacter.x); + return 1; + }, + setter: SetNumProperty + }, + + "tweenPos" => { + defaultValue: 0, + getter: function(l:State, data:Any) + { + Lua.pushcfunction(l, tweenPosC); + return 1; + }, + setter: function(l:State) + { + LuaL.error(l, "tweenPos is read-only."); + return 0; + } + }, + + "id" => { + defaultValue: name, + getter: function(l:State, data:Any):Int + { + Lua.pushstring(l, name); + return 1; + }, + setter: SetNumProperty + }, + + "tweenAlpha" => { + defaultValue: 0, + getter: function(l:State, data:Any) + { + Lua.pushcfunction(l, tweenAlphaC); + return 1; + }, + setter: function(l:State) + { + LuaL.error(l, "tweenAlpha is read-only."); + return 0; + } + }, + + "tweenAngle" => { + defaultValue: 0, + getter: function(l:State, data:Any) + { + Lua.pushcfunction(l, tweenAngleC); + return 1; + }, + setter: function(l:State) + { + LuaL.error(l, "tweenAngle is read-only."); + return 0; + } + }, + + "changeCharacter" => { + defaultValue: 0, + getter: function(l:State, data:Any) + { + Lua.pushcfunction(l, changeCharacterC); + return 1; + }, + setter: function(l:State) + { + LuaL.error(l, "changeCharacter is read-only."); + return 0; + } + }, + + "playAnim" => { + defaultValue: 0, + getter: function(l:State, data:Any) + { + Lua.pushcfunction(l, playAnimC); + return 1; + }, + setter: function(l:State) + { + LuaL.error(l, "playAnim is read-only."); + return 0; + } + }, + + "y" => { + defaultValue: connectedCharacter.y, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, connectedCharacter.y); + return 1; + }, + setter: SetNumProperty + } + + ]; + + ListOfCharacters.push(this); + } + + private static function findNote(time:Float, data:Int) + { + for (i in PlayState.instance.notes) + { + if (i.strumTime == time && i.noteData == data) + { + return i; + } + } + return null; + } + + private static function tweenPos(l:StatePointer):Int + { + // 1 = self + // 2 = x + // 3 = y + // 4 = time + var xp = LuaL.checknumber(state, 2); + var yp = LuaL.checknumber(state, 3); + var time = LuaL.checknumber(state, 4); + + Lua.getfield(state, 1, "id"); + var index = Lua.tostring(state, -1); + + var char:Character = null; + + for (i in ListOfCharacters) + { + if (i.className == index) + char = i.char; + } + + if (char == null) + { + LuaL.error(state, "Failure to tween (couldn't find character " + index + ")"); + return 0; + } + + FlxTween.tween(char, {x: xp, y: yp}, time); + + return 0; + } + + private static function tweenAngle(l:StatePointer):Int + { + // 1 = self + // 2 = angle + // 3 = time + var nangle = LuaL.checknumber(state, 2); + var time = LuaL.checknumber(state, 3); + + Lua.getfield(state, 1, "id"); + var index = Lua.tostring(state, -1); + + var char:Character = null; + + for (i in ListOfCharacters) + { + if (i.className == index) + char = i.char; + } + + if (char == null) + { + LuaL.error(state, "Failure to tween (couldn't find character " + index + ")"); + return 0; + } + + FlxTween.tween(char, {angle: nangle}, time); + + return 0; + } + + private static function tweenAlpha(l:StatePointer):Int + { + // 1 = self + // 2 = alpha + // 3 = time + var nalpha = LuaL.checknumber(state, 2); + var time = LuaL.checknumber(state, 3); + + Lua.getfield(state, 1, "id"); + var index = Lua.tostring(state, -1); + + var char:Character = null; + + for (i in ListOfCharacters) + { + if (i.className == index) + char = i.char; + } + + if (char == null) + { + LuaL.error(state, "Failure to tween (couldn't find character " + index + ")"); + return 0; + } + + FlxTween.tween(char, {alpha: nalpha}, time); + + return 0; + } + + private static function changeCharacter(l:StatePointer):Int + { + // 1 = self + // 2 = newName + // 3 = x + // 4 = y + var newName = LuaL.checkstring(state, 2); + var x = LuaL.checknumber(state, 3); + var y = LuaL.checknumber(state, 4); + + Lua.getfield(state, 1, "id"); + var index = Lua.tostring(state, -1); + + var char:Character = null; + var property:LuaCharacter = null; + + for (i in ListOfCharacters) + { + if (i.className == index) + { + char = i.char; + property = i; + } + } + + trace("fuck " + char); + + if (char == null) + { + LuaL.error(state, "Failure to tween (couldn't find character " + index + ")"); + return 0; + } + + PlayState.instance.remove(char); + + PlayState.instance.dad = new Character(x, y, newName, char.isPlayer); + + property.char = PlayState.instance.dad; + + PlayState.instance.add(PlayState.instance.dad); + + return 0; + } + + private static function playAnim(l:StatePointer):Int + { + // 1 = self + // 2 = animation + var anim = LuaL.checkstring(state, 2); + + Lua.getfield(state, 1, "id"); + var index = Lua.tostring(state, -1); + + var char:Character = null; + + for (i in ListOfCharacters) + { + if (i.className == index) + { + char = i.char; + } + } + + if (char == null) + { + LuaL.error(state, "Failure to tween (couldn't find character " + index + ")"); + return 0; + } + + char.playAnim(anim); + + return 0; + } + + private static var playAnimC:cpp.CallableInt> = cpp.Callable.fromStaticFunction(playAnim); + private static var changeCharacterC:cpp.CallableInt> = cpp.Callable.fromStaticFunction(changeCharacter); + private static var tweenPosC:cpp.CallableInt> = cpp.Callable.fromStaticFunction(tweenPos); + private static var tweenAngleC:cpp.CallableInt> = cpp.Callable.fromStaticFunction(tweenAngle); + private static var tweenAlphaC:cpp.CallableInt> = cpp.Callable.fromStaticFunction(tweenAlpha); + + private function SetNumProperty(l:State) + { + // 1 = self + // 2 = key + // 3 = value + // 4 = metatable + if (Lua.type(l, 3) != Lua.LUA_TNUMBER) + { + LuaL.error(l, "invalid argument #3 (number expected, got " + Lua.typename(l, Lua.type(l, 3)) + ")"); + return 0; + } + Reflect.setProperty(char, Lua.tostring(l, 2), Lua.tonumber(l, 3)); + return 0; + } + + override function Register(l:State) + { + state = l; + super.Register(l); + } +} + +class LuaSprite extends LuaClass +{ // again, stolen from andromeda but improved a lot for better thinking interoperability (I made that up) + private static var state:State; + + public var sprite:FlxSprite; + + public static var ListOfSprites:Array = []; + + public function new(connectedSprite:FlxSprite, name:String) + { + super(); + className = name; + + properties = [ + "alpha" => { + defaultValue: 1, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, connectedSprite.alpha); + return 1; + }, + setter: SetNumProperty + }, + + "angle" => { + defaultValue: 1, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, connectedSprite.angle); + return 1; + }, + setter: function(l:State):Int + { + // 1 = self + // 2 = key + // 3 = value + // 4 = metatable + if (Lua.type(l, 3) != Lua.LUA_TNUMBER) + { + LuaL.error(l, "invalid argument #3 (number expected, got " + Lua.typename(l, Lua.type(l, 3)) + ")"); + return 0; + } + + var angle = Lua.tonumber(l, 3); + connectedSprite.angle = angle; + + LuaClass.DefaultSetter(l); + return 0; + } + }, + + "x" => { + defaultValue: connectedSprite.x, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, connectedSprite.x); + return 1; + }, + setter: SetNumProperty + }, + + "tweenPos" => { + defaultValue: 0, + getter: function(l:State, data:Any) + { + Lua.pushcfunction(l, tweenPosC); + return 1; + }, + setter: function(l:State) + { + LuaL.error(l, "tweenPos is read-only."); + return 0; + } + }, + + "id" => { + defaultValue: name, + getter: function(l:State, data:Any):Int + { + Lua.pushstring(l, name); + return 1; + }, + setter: SetNumProperty + }, + + "tweenAlpha" => { + defaultValue: 0, + getter: function(l:State, data:Any) + { + Lua.pushcfunction(l, tweenAlphaC); + return 1; + }, + setter: function(l:State) + { + LuaL.error(l, "tweenAlpha is read-only."); + return 0; + } + }, + + "tweenAngle" => { + defaultValue: 0, + getter: function(l:State, data:Any) + { + Lua.pushcfunction(l, tweenAngleC); + return 1; + }, + setter: function(l:State) + { + LuaL.error(l, "tweenAngle is read-only."); + return 0; + } + }, + + "destroy" => { + defaultValue: 0, + getter: function(l:State, data:Any) + { + Lua.pushcfunction(l, destroyC); + return 1; + }, + setter: function(l:State) + { + LuaL.error(l, "destroy is read-only."); + return 0; + } + }, + + "y" => { + defaultValue: connectedSprite.y, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, connectedSprite.y); + return 1; + }, + setter: SetNumProperty + } + + ]; + + ListOfSprites.push(this); + } + + private static function findNote(time:Float, data:Int) + { + for (i in PlayState.instance.notes) + { + if (i.strumTime == time && i.noteData == data) + { + return i; + } + } + return null; + } + + private static function tweenPos(l:StatePointer):Int + { + // 1 = self + // 2 = x + // 3 = y + // 4 = time + var xp = LuaL.checknumber(state, 2); + var yp = LuaL.checknumber(state, 3); + var time = LuaL.checknumber(state, 4); + + Lua.getfield(state, 1, "id"); + var index = Lua.tostring(state, -1); + + var sprite:FlxSprite = null; + + for (i in ListOfSprites) + { + if (i.className == index) + sprite = i.sprite; + } + + if (sprite == null) + { + LuaL.error(state, "Failure to tween (couldn't find sprite " + index + ")"); + return 0; + } + + FlxTween.tween(sprite, {x: xp, y: yp}, time); + + return 0; + } + + private static function tweenAngle(l:StatePointer):Int + { + // 1 = self + // 2 = angle + // 3 = time + var nangle = LuaL.checknumber(state, 2); + var time = LuaL.checknumber(state, 3); + + Lua.getfield(state, 1, "id"); + var index = Lua.tostring(state, -1); + + var sprite:FlxSprite = null; + + for (i in ListOfSprites) + { + if (i.className == index) + sprite = i.sprite; + } + + if (sprite == null) + { + LuaL.error(state, "Failure to tween (couldn't find sprite " + index + ")"); + return 0; + } + + FlxTween.tween(sprite, {angle: nangle}, time); + + return 0; + } + + private static function tweenAlpha(l:StatePointer):Int + { + // 1 = self + // 2 = alpha + // 3 = time + var nalpha = LuaL.checknumber(state, 2); + var time = LuaL.checknumber(state, 3); + + Lua.getfield(state, 1, "id"); + var index = Lua.tostring(state, -1); + + var sprite:FlxSprite = null; + + for (i in ListOfSprites) + { + if (i.className == index) + sprite = i.sprite; + } + + if (sprite == null) + { + LuaL.error(state, "Failure to tween (couldn't find sprite " + index + ")"); + return 0; + } + + FlxTween.tween(sprite, {alpha: nalpha}, time); + + return 0; + } + + private static function destroy(l:StatePointer):Int + { + // 1 = self + + Lua.getfield(state, 1, "id"); + var index = Lua.tostring(state, -1); + + var sprite:FlxSprite = null; + + for (i in ListOfSprites) + { + if (i.className == index) + sprite = i.sprite; + } + + if (sprite == null) + { + LuaL.error(state, "Failure to tween (couldn't find sprite " + index + ")"); + return 0; + } + + PlayState.instance.remove(sprite); + sprite.destroy(); + + return 0; + } + + private static var destroyC:cpp.CallableInt> = cpp.Callable.fromStaticFunction(destroy); + private static var tweenPosC:cpp.CallableInt> = cpp.Callable.fromStaticFunction(tweenPos); + private static var tweenAngleC:cpp.CallableInt> = cpp.Callable.fromStaticFunction(tweenAngle); + private static var tweenAlphaC:cpp.CallableInt> = cpp.Callable.fromStaticFunction(tweenAlpha); + + private function SetNumProperty(l:State) + { + // 1 = self + // 2 = key + // 3 = value + // 4 = metatable + if (Lua.type(l, 3) != Lua.LUA_TNUMBER) + { + LuaL.error(l, "invalid argument #3 (number expected, got " + Lua.typename(l, Lua.type(l, 3)) + ")"); + return 0; + } + Reflect.setProperty(sprite, Lua.tostring(l, 2), Lua.tonumber(l, 3)); + return 0; + } + + override function Register(l:State) + { + state = l; + super.Register(l); + } +} + +class LuaWindow extends LuaClass +{ // again, stolen from andromeda but improved a lot for better thinking interoperability (I made that up) + private static var state:State; + + public function new() + { + super(); + className = "Window"; + + properties = [ + "x" => { + defaultValue: Application.current.window.x, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, Application.current.window.x); + return 1; + }, + setter: SetNumProperty + }, + + "y" => { + defaultValue: Application.current.window.y, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, Application.current.window.y); + return 1; + }, + setter: SetNumProperty + }, + + "width" => { + defaultValue: Application.current.window.width, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, Application.current.window.width); + return 1; + }, + setter: SetNumProperty + }, + + "height" => { + defaultValue: Application.current.window.height, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, Application.current.window.height); + return 1; + }, + setter: SetNumProperty + }, + + "tweenPos" => { + defaultValue: 0, + getter: function(l:State, data:Any) + { + Lua.pushcfunction(l, tweenPosC); + return 1; + }, + setter: function(l:State) + { + LuaL.error(l, "tweenPos is read-only."); + return 0; + }, + }, + ]; + } + + private static function tweenPos(l:StatePointer):Int + { + // 1 = self + // 2 = x + // 3 = y + // 4 = time + var xp = LuaL.checknumber(state, 2); + var yp = LuaL.checknumber(state, 3); + var time = LuaL.checknumber(state, 4); + + FlxTween.tween(Application.current.window, {x: xp, y: yp}, time); + + return 0; + } + + private static var tweenPosC:cpp.CallableInt> = cpp.Callable.fromStaticFunction(tweenPos); + + private function SetNumProperty(l:State) + { + // 1 = self + // 2 = key + // 3 = value + // 4 = metatable + if (Lua.type(l, 3) != Lua.LUA_TNUMBER) + { + LuaL.error(l, "invalid argument #3 (number expected, got " + Lua.typename(l, Lua.type(l, 3)) + ")"); + return 0; + } + Reflect.setProperty(Application.current.window, Lua.tostring(l, 2), Lua.tonumber(l, 3)); + return 0; + } + + override function Register(l:State) + { + state = l; + super.Register(l); + } +} + +class LuaGame extends LuaClass +{ // again, stolen from andromeda but improved a lot for better thinking interoperability (I made that up) + private static var state:State; + + public function new() + { + super(); + className = "Game"; + + properties = [ + + "health" => { + defaultValue: PlayState.instance.health, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, PlayState.instance.health); + return 1; + }, + setter: function(l:State):Int + { + PlayState.instance.health = Lua.tonumber(l, 3); + return 0; + }, + }, + + "accuracy" => { + defaultValue: PlayState.instance.accuracy, + getter: function(l:State, data:Any):Int + { + Lua.pushnumber(l, PlayState.instance.accuracy); + return 1; + }, + setter: SetNumProperty + }, + "changeStage" => { + defaultValue: 0, + getter: function(l:State, data:Any) + { + Lua.pushcfunction(l, changeStageC); + return 1; + }, + setter: function(l:State) + { + LuaL.error(l, "changeStage is read-only."); + return 0; + }, + } + ]; + } + + private static function changeStage(l:StatePointer):Int + { + // 1 = self + // 2 = stage + var stageName = LuaL.checkstring(state, 2); + + for (i in PlayState.instance.Stage.toAdd) + { + PlayState.instance.remove(i); + } + + PlayState.instance.Stage = new Stage(stageName); + + for (i in PlayState.instance.Stage.toAdd) + { + PlayState.instance.add(i); + } + + return 0; + } + + private static var changeStageC:cpp.CallableInt> = cpp.Callable.fromStaticFunction(changeStage); + + private function SetNumProperty(l:State) + { + // 1 = self + // 2 = key + // 3 = value + // 4 = metatable + if (Lua.type(l, 3) != Lua.LUA_TNUMBER) + { + LuaL.error(l, "invalid argument #3 (number expected, got " + Lua.typename(l, Lua.type(l, 3)) + ")"); + return 0; + } + Reflect.setProperty(Application.current.window, Lua.tostring(l, 2), Lua.tonumber(l, 3)); + return 0; + } + + override function Register(l:State) + { + state = l; + super.Register(l); + } +} +#end diff --git a/source/LuaShader.hx b/source/LuaShader.hx new file mode 100644 index 000000000..4e403c69c --- /dev/null +++ b/source/LuaShader.hx @@ -0,0 +1,72 @@ +/*import flixel.system.FlxAssets.FlxShader; + +class LuaShader extends FlxShader +{ + // SHADER SHIT FOR LUA CODE + + public function new(frag,vert) + { + glFragmentSource = ' + #pragma header + varying float openfl_Alphav; + varying vec4 openfl_ColorMultiplierv; + varying vec4 openfl_ColorOffsetv; + varying vec2 openfl_TextureCoordv; + + uniform bool openfl_HasColorTransform; + uniform vec2 openfl_TextureSize; + uniform sampler2D bitmap; + + uniform bool hasTransform; + uniform bool hasColorTransform; + + uniform vec3 iResolution; // viewport resolution (in pixels) + uniform float iTime; // shader playback time (in seconds) + uniform float iTimeDelta; // render time (in seconds) + uniform int iFrame; // shader playback frame + uniform float iChannelTime[4]; // channel playback time (in seconds) + uniform vec3 iChannelResolution[4]; // channel resolution (in pixels) + uniform vec4 iMouse; // mouse pixel coords. xy: current, zw: click + uniform samplerXX iChannel0..3; // input channel. XX = 2D/Cube + uniform vec4 iDate; // (year, month, day, time in seconds) + uniform float iSampleRate; // sound sample rate (i.e., 44100) + + vec4 flixel_texture2D(sampler2D bitmap, vec2 coord) + { + vec4 color = texture2D(bitmap, coord); + if (!hasTransform) + { + return color; + } + + if (color.a == 0.0) + { + return vec4(0.0, 0.0, 0.0, 0.0); + } + + if (!hasColorTransform) + { + return color * openfl_Alphav; + } + + color = vec4(color.rgb / color.a, color.a); + + mat4 colorMultiplier = mat4(0); + colorMultiplier[0][0] = openfl_ColorMultiplierv.x; + colorMultiplier[1][1] = openfl_ColorMultiplierv.y; + colorMultiplier[2][2] = openfl_ColorMultiplierv.z; + colorMultiplier[3][3] = openfl_ColorMultiplierv.w; + + color = clamp(openfl_ColorOffsetv + (color * colorMultiplier), 0.0, 1.0); + + if (color.a > 0.0) + { + return vec4(0.0, 0.0, 0.0, 0.0); + } + + ' + frag; + + iResolution + super(); + } +}*/ \ No newline at end of file diff --git a/source/MP4Handler.hx b/source/MP4Handler.hx new file mode 100644 index 000000000..a731bfb70 --- /dev/null +++ b/source/MP4Handler.hx @@ -0,0 +1,120 @@ +package; + +import openfl.events.Event; +import flixel.FlxG; + +/** + * Play a video using cpp. + * Use bitmap to connect to a graphic or use `MP4Sprite`. + */ +class MP4Handler extends vlc.VlcBitmap +{ + public var readyCallback:Void->Void; + public var finishCallback:Void->Void; + public var unskippable:Bool = false; + + var pauseMusic:Bool; + + public function new(width:Float = 320, height:Float = 240, autoScale:Bool = true, ?unskippable:Bool = false) + { + super(width, height, autoScale); + + onVideoReady = onVLCVideoReady; + onComplete = finishVideo; + onError = onVLCError; + this.unskippable = unskippable; + + FlxG.addChildBelowMouse(this); + + FlxG.stage.addEventListener(Event.ENTER_FRAME, update); + + FlxG.signals.focusGained.add(function() + { + resume(); + }); + FlxG.signals.focusLost.add(function() + { + pause(); + }); + } + + function update(e:Event) + { + if ((FlxG.keys.justPressed.ENTER || FlxG.keys.justPressed.SPACE) && isPlaying && !unskippable) + finishVideo(); + + if (FlxG.sound.muted || FlxG.sound.volume <= 0) + volume = 0; + else + volume = FlxG.sound.volume + 0.4; + } + + #if sys + function checkFile(fileName:String):String + { + var pDir = ""; + var appDir = "file:///" + Sys.getCwd() + "/"; + + if (fileName.indexOf(":") == -1) // Not a path + pDir = appDir; + else if (fileName.indexOf("file://") == -1 || fileName.indexOf("http") == -1) // C:, D: etc? ..missing "file:///" ? + pDir = "file:///"; + + return pDir + fileName; + } + #end + + function onVLCVideoReady() + { + trace("Video loaded!"); + + if (readyCallback != null) + readyCallback(); + } + + function onVLCError() + { + // TODO: Catch the error + throw "VLC caught an error!"; + } + + public function finishVideo() + { + if (FlxG.sound.music != null && pauseMusic) + FlxG.sound.music.resume(); + + FlxG.stage.removeEventListener(Event.ENTER_FRAME, update); + + dispose(); + + if (FlxG.game.contains(this)) + { + FlxG.game.removeChild(this); + + if (finishCallback != null) + finishCallback(); + } + } + + /** + * Native video support for Flixel & OpenFL + * @param path Example: `your/video/here.mp4` + * @param repeat Repeat the video. + * @param pauseMusic Pause music until done video. + */ + public function playVideo(path:String, ?repeat:Bool = false, pauseMusic:Bool = false) + { + this.pauseMusic = pauseMusic; + + if (FlxG.sound.music != null && pauseMusic) + FlxG.sound.music.pause(); + + #if sys + play(checkFile(path)); + + this.repeat = repeat ? -1 : 0; + #else + throw "Doesn't support sys"; + #end + } +} diff --git a/source/MP4Sprite.hx b/source/MP4Sprite.hx new file mode 100644 index 000000000..084023e04 --- /dev/null +++ b/source/MP4Sprite.hx @@ -0,0 +1,59 @@ +package; + +import flixel.FlxSprite; + +/** + * Compared to `MP4Handler`. This loads slower!! + */ +class MP4Sprite extends FlxSprite +{ + public var readyCallback:Void->Void; + public var finishCallback:Void->Void; + + var video:MP4Handler; + + public function new(x:Float = 0, y:Float = 0, width:Float = 320, height:Float = 240, autoScale:Bool = true) + { + super(x, y); + + video = new MP4Handler(width, height, autoScale); + video.alpha = 0; + + video.readyCallback = function() + { + loadGraphic(video.bitmapData); + + if (readyCallback != null) + readyCallback(); + } + + video.finishCallback = function() + { + if (finishCallback != null) + finishCallback(); + + kill(); + }; + } + + /** + * Native video support for Flixel & OpenFL + * @param path Example: `your/video/here.mp4` + * @param repeat Repeat the video. + * @param pauseMusic Pause music until done video. + */ + public function playVideo(path:String, ?repeat:Bool = false, pauseMusic:Bool = false) + { + video.playVideo(path, repeat, pauseMusic); + } + + public function pause() + { + video.pause(); + } + + public function resume() + { + video.resume(); + } +} diff --git a/source/Main.hx b/source/Main.hx index f77305df9..8d47c611a 100644 --- a/source/Main.hx +++ b/source/Main.hx @@ -1,5 +1,11 @@ package; + +import webm.WebmPlayer; +import openfl.display.BlendMode; +import openfl.text.TextFormat; +import openfl.display.Application; +import flixel.util.FlxColor; import flixel.FlxG; import flixel.FlxGame; import flixel.FlxState; @@ -8,9 +14,6 @@ import openfl.Lib; import openfl.display.FPS; import openfl.display.Sprite; import openfl.events.Event; -import sys.FileSystem; -import lime.app.Application; -import lime.system.System; class Main extends Sprite { @@ -18,40 +21,31 @@ class Main extends Sprite var gameHeight:Int = 720; // Height of the game in pixels (might be less / more in actual pixels depending on your zoom). var initialState:Class = TitleState; // The FlxState the game starts with. var zoom:Float = -1; // If -1, zoom is automatically calculated to fit the window dimensions. - var framerate:Int = 60; // How many frames per second the game should run at. + var framerate:Int = 120; // How many frames per second the game should run at. var skipSplash:Bool = true; // Whether to skip the flixel splash screen that appears in release mode. var startFullscreen:Bool = false; // Whether to start the game in fullscreen on desktop targets - public static var fpsVar:FPS; - private static var dataPath:String = null; - - static public function getDataPath():String - { - if (dataPath != null && dataPath.length > 0) - { - return dataPath; - } - else - { - #if mobile - if (FileSystem.exists("/storage/emulated/0/Android/data/" + Application.current.meta.get("packageName") + "/files/")) - { - dataPath = "/storage/emulated/0/Android/data/" + Application.current.meta.get("packageName") + "/files/"; - } - else - { - Application.current.window.alert("couldn't find directory: " + "/storage/emulated/0/Android/data/" + Application.current.meta.get("packageName") + "/files/" + "\n" + "try creating it and copying assets/assets, assets/mods from apk to it","an ERROR occured"); - dataPath = System.applicationStorageDirectory; - } - #else - dataPath = ""; - #end - } - return dataPath; - } + public static var watermarks = true; // Whether to put Kade Engine liteartly anywhere + public static var noCopyright:Bool = false; // For Sharkventure Copyright Stuff + public static var isHidden:Bool = false; //Lol Hidden Menu Stuff + public static var seenMessage:Bool = false; //Lol Hidden Restore Shit + public static var restoreUnlocked:Bool = false; //Lol Hidden Restore Shit + public static var realDeath:Bool = false; //now unused + public static var cursedUnlocked:Bool = false; //Lol cursed cocoa Shit + public static var deathHolo:Bool = false; //Lol Hidden deathmatch Shit + public static var hiddenSongs:Array = ['hunger', 'diva', 'sorrow', 'shinkyoku', 'norway', 'haachama-ex']; //Lol Hidden stuff + public static var keyAmmo:Array = [4, 6, 9, 5, 7]; + public static var dataJump:Array = [8, 12, 18]; + public static var isMegalo:Bool = false; + public static var curFPS:Int = 120; + + // You can pretty much ignore everything from here on - your code should go in your states. public static function main():Void { + + // quick checks + Lib.current.addChild(new Main()); } @@ -69,6 +63,8 @@ class Main extends Sprite } } + public static var webmHandler:WebmHandler; + private function init(?E:Event):Void { if (hasEventListener(Event.ADDED_TO_STAGE)) @@ -93,22 +89,63 @@ class Main extends Sprite gameHeight = Math.ceil(stageHeight / zoom); } - #if !debug initialState = TitleState; - #end + + game = new FlxGame(gameWidth, gameHeight, initialState, zoom, framerate, framerate, skipSplash, startFullscreen); - ClientPrefs.loadDefaultKeys(); - addChild(new FlxGame(gameWidth, gameHeight, initialState, zoom, framerate, framerate, skipSplash, startFullscreen)); + addChild(game); - fpsVar = new FPS(10, 3, 0xFFFFFF); - addChild(fpsVar); - if(fpsVar != null) { - fpsVar.visible = ClientPrefs.showFPS; - } + #if !mobile + fpsCounter = new FPS(10, 3, 0xFFFFFF); + addChild(fpsCounter); + toggleFPS(FlxG.save.data.fps); - #if html5 - FlxG.autoPause = false; - FlxG.mouse.visible = false; #end } + + public static function dumpCache() + { + ///* SPECIAL THANKS TO HAYA + @:privateAccess + for (key in FlxG.bitmap._cache.keys()) + { + var obj = FlxG.bitmap._cache.get(key); + if (obj != null) + { + Assets.cache.removeBitmapData(key); + FlxG.bitmap._cache.remove(key); + obj.destroy(); + } + } + Assets.cache.clear("songs"); + } + + var game:FlxGame; + + var fpsCounter:FPS; + + public function toggleFPS(fpsEnabled:Bool):Void { + fpsCounter.visible = fpsEnabled; + } + + public function changeFPSColor(color:FlxColor) + { + fpsCounter.textColor = color; + } + + public function setFPSCap(cap:Float) + { + openfl.Lib.current.stage.frameRate = cap; + curFPS = Std.int(cap); + } + + public function getFPSCap():Float + { + return openfl.Lib.current.stage.frameRate; + } + + public function getFPS():Float + { + return fpsCounter.currentFPS; + } } diff --git a/source/MainMenuState.hx b/source/MainMenuState.hx index a5fd2ead5..8d0e6c1e8 100644 --- a/source/MainMenuState.hx +++ b/source/MainMenuState.hx @@ -1,298 +1,299 @@ -package; - -#if desktop -import Discord.DiscordClient; -#end -import flixel.FlxG; -import flixel.FlxObject; -import flixel.FlxSprite; -import flixel.FlxCamera; -import flixel.addons.transition.FlxTransitionableState; -import flixel.effects.FlxFlicker; -import flixel.graphics.frames.FlxAtlasFrames; -import flixel.group.FlxGroup.FlxTypedGroup; -import flixel.text.FlxText; -import flixel.math.FlxMath; -import flixel.tweens.FlxEase; -import flixel.tweens.FlxTween; -import flixel.util.FlxColor; -import lime.app.Application; -import Achievements; -import editors.MasterEditorMenu; -import flixel.input.keyboard.FlxKey; - -using StringTools; - -class MainMenuState extends MusicBeatState -{ - public static var psychEngineVersion:String = '0.5'; //This is also used for Discord RPC - public static var curSelected:Int = 0; - - var menuItems:FlxTypedGroup; - private var camGame:FlxCamera; - private var camAchievement:FlxCamera; - - var optionShit:Array = [ - 'story_mode', - 'freeplay', - #if MODS_ALLOWED 'mods', #end - #if ACHIEVEMENTS_ALLOWED 'awards', #end - 'credits', - #if !switch 'donate', #end - 'options' - ]; - - var magenta:FlxSprite; - var camFollow:FlxObject; - var camFollowPos:FlxObject; - var debugKeys:Array; - - override function create() - { - #if desktop - // Updating Discord Rich Presence - DiscordClient.changePresence("In the Menus", null); - #end - - WeekData.setDirectoryFromWeek(); - debugKeys = ClientPrefs.copyKey(ClientPrefs.keyBinds.get('debug_1')); - - camGame = new FlxCamera(); - camAchievement = new FlxCamera(); - camAchievement.bgColor.alpha = 0; - - FlxG.cameras.reset(camGame); - FlxG.cameras.add(camAchievement); - FlxCamera.defaultCameras = [camGame]; - - transIn = FlxTransitionableState.defaultTransIn; - transOut = FlxTransitionableState.defaultTransOut; - - persistentUpdate = persistentDraw = true; - - var yScroll:Float = Math.max(0.25 - (0.05 * (optionShit.length - 4)), 0.1); - var bg:FlxSprite = new FlxSprite(-80).loadGraphic(Paths.image('menuBG')); - bg.scrollFactor.set(0, yScroll); - bg.setGraphicSize(Std.int(bg.width * 1.175)); - bg.updateHitbox(); - bg.screenCenter(); - bg.antialiasing = ClientPrefs.globalAntialiasing; - add(bg); - - camFollow = new FlxObject(0, 0, 1, 1); - camFollowPos = new FlxObject(0, 0, 1, 1); - add(camFollow); - add(camFollowPos); - - magenta = new FlxSprite(-80).loadGraphic(Paths.image('menuDesat')); - magenta.scrollFactor.set(0, yScroll); - magenta.setGraphicSize(Std.int(magenta.width * 1.175)); - magenta.updateHitbox(); - magenta.screenCenter(); - magenta.visible = false; - magenta.antialiasing = ClientPrefs.globalAntialiasing; - magenta.color = 0xFFfd719b; - add(magenta); - // magenta.scrollFactor.set(); - - menuItems = new FlxTypedGroup(); - add(menuItems); - - var scale:Float = 1; - /*if(optionShit.length > 6) { - scale = 6 / optionShit.length; - }*/ - - for (i in 0...optionShit.length) - { - var offset:Float = 108 - (Math.max(optionShit.length, 4) - 4) * 80; - var menuItem:FlxSprite = new FlxSprite(0, (i * 140) + offset); - menuItem.scale.x = scale; - menuItem.scale.y = scale; - menuItem.frames = Paths.getSparrowAtlas('mainmenu/menu_' + optionShit[i]); - menuItem.animation.addByPrefix('idle', optionShit[i] + " basic", 24); - menuItem.animation.addByPrefix('selected', optionShit[i] + " white", 24); - menuItem.animation.play('idle'); - menuItem.ID = i; - menuItem.screenCenter(X); - menuItems.add(menuItem); - var scr:Float = (optionShit.length - 4) * 0.135; - if(optionShit.length < 6) scr = 0; - menuItem.scrollFactor.set(0, scr); - menuItem.antialiasing = ClientPrefs.globalAntialiasing; - //menuItem.setGraphicSize(Std.int(menuItem.width * 0.58)); - menuItem.updateHitbox(); - } - - FlxG.camera.follow(camFollowPos, null, 1); - - var versionShit:FlxText = new FlxText(12, FlxG.height - 44, 0, "Psych Engine v" + psychEngineVersion, 12); - versionShit.scrollFactor.set(); - versionShit.setFormat("VCR OSD Mono", 16, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - add(versionShit); - var versionShit:FlxText = new FlxText(12, FlxG.height - 24, 0, "Friday Night Funkin' v" + Application.current.meta.get('version'), 12); - versionShit.scrollFactor.set(); - versionShit.setFormat("VCR OSD Mono", 16, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - add(versionShit); - - // NG.core.calls.event.logEvent('swag').send(); - - changeItem(); - - #if ACHIEVEMENTS_ALLOWED - Achievements.loadAchievements(); - var leDate = Date.now(); - if (leDate.getDay() == 5 && leDate.getHours() >= 18) { - var achieveID:Int = Achievements.getAchievementIndex('friday_night_play'); - if(!Achievements.isAchievementUnlocked(Achievements.achievementsStuff[achieveID][2])) { //It's a friday night. WEEEEEEEEEEEEEEEEEE - Achievements.achievementsMap.set(Achievements.achievementsStuff[achieveID][2], true); - giveAchievement(); - ClientPrefs.saveSettings(); - } - } - #end - - #if mobileC - addVirtualPad(UP_DOWN, A_B_7); - #end - - super.create(); - } - - #if ACHIEVEMENTS_ALLOWED - // Unlocks "Freaky on a Friday Night" achievement - function giveAchievement() { - add(new AchievementObject('friday_night_play', camAchievement)); - FlxG.sound.play(Paths.sound('confirmMenu'), 0.7); - trace('Giving achievement "friday_night_play"'); - } - #end - - var selectedSomethin:Bool = false; - - override function update(elapsed:Float) - { - if (FlxG.sound.music.volume < 0.8) - { - FlxG.sound.music.volume += 0.5 * FlxG.elapsed; - } - - var lerpVal:Float = CoolUtil.boundTo(elapsed * 7.5, 0, 1); - camFollowPos.setPosition(FlxMath.lerp(camFollowPos.x, camFollow.x, lerpVal), FlxMath.lerp(camFollowPos.y, camFollow.y, lerpVal)); - - if (!selectedSomethin) - { - if (controls.UI_UP_P) - { - FlxG.sound.play(Paths.sound('scrollMenu')); - changeItem(-1); - } - - if (controls.UI_DOWN_P) - { - FlxG.sound.play(Paths.sound('scrollMenu')); - changeItem(1); - } - - if (controls.BACK) - { - selectedSomethin = true; - FlxG.sound.play(Paths.sound('cancelMenu')); - MusicBeatState.switchState(new TitleState()); - } - - if (controls.ACCEPT) - { - if (optionShit[curSelected] == 'donate') - { - CoolUtil.browserLoad('https://ninja-muffin24.itch.io/funkin'); - } - else - { - selectedSomethin = true; - FlxG.sound.play(Paths.sound('confirmMenu')); - - if(ClientPrefs.flashing) FlxFlicker.flicker(magenta, 1.1, 0.15, false); - - menuItems.forEach(function(spr:FlxSprite) - { - if (curSelected != spr.ID) - { - FlxTween.tween(spr, {alpha: 0}, 0.4, { - ease: FlxEase.quadOut, - onComplete: function(twn:FlxTween) - { - spr.kill(); - } - }); - } - else - { - FlxFlicker.flicker(spr, 1, 0.06, false, false, function(flick:FlxFlicker) - { - var daChoice:String = optionShit[curSelected]; - - switch (daChoice) - { - case 'story_mode': - MusicBeatState.switchState(new StoryMenuState()); - case 'freeplay': - MusicBeatState.switchState(new FreeplayState()); - #if MODS_ALLOWED - case 'mods': - MusicBeatState.switchState(new ModsMenuState()); - #end - case 'awards': - MusicBeatState.switchState(new AchievementsMenuState()); - case 'credits': - MusicBeatState.switchState(new CreditsState()); - case 'options': - MusicBeatState.switchState(new options.OptionsState()); - } - }); - } - }); - } - } - else if (FlxG.keys.anyJustPressed(debugKeys) #if mobileC || _virtualpad.button7.justPressed #end) - { - selectedSomethin = true; - MusicBeatState.switchState(new MasterEditorMenu()); - } - } - - super.update(elapsed); - - menuItems.forEach(function(spr:FlxSprite) - { - spr.screenCenter(X); - }); - } - - function changeItem(huh:Int = 0) - { - curSelected += huh; - - if (curSelected >= menuItems.length) - curSelected = 0; - if (curSelected < 0) - curSelected = menuItems.length - 1; - - menuItems.forEach(function(spr:FlxSprite) - { - spr.animation.play('idle'); - spr.updateHitbox(); - - if (spr.ID == curSelected) - { - spr.animation.play('selected'); - var add:Float = 0; - if(menuItems.length > 4) { - add = menuItems.length * 8; - } - camFollow.setPosition(spr.getGraphicMidpoint().x, spr.getGraphicMidpoint().y - add); - spr.centerOffsets(); - } - }); - } -} +package; + +import Controls.KeyboardScheme; +import flixel.FlxG; +import flixel.FlxObject; +import flixel.FlxSprite; +import flixel.effects.FlxFlicker; +import flixel.graphics.frames.FlxAtlasFrames; +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.text.FlxText; +import flixel.tweens.FlxEase; +import flixel.tweens.FlxTween; +import flixel.util.FlxColor; +import io.newgrounds.NG; +import lime.app.Application; + +#if desktop +import Discord.DiscordClient; +#end + +using StringTools; + +class MainMenuState extends MusicBeatState +{ + var curSelected:Int = 0; + + var menuItems:FlxTypedGroup; + + #if !switch + var optionShit:Array = ['betadciu', 'bonus songs', 'neonight', 'vitor', 'donate', 'options', 'extras', 'freeplay']; + #else + var optionShit:Array = ['betadciu', 'bonus songs', 'neonight', 'vitor', 'extras', 'freeplay']; + #end + + var newGaming:FlxText; + var newGaming2:FlxText; + var newInput:Bool = true; + var menuItem:FlxSprite; + public static var mainMusic = true; + + public static var kadeEngineVer:String = "BETADCIU Engine"; + public static var gameVer:String = "0.2.7.1"; + public static var betadciuVer:String = "Version 1"; + + var magenta:FlxSprite; + var camFollow:FlxObject; + + override function create() + { + FlxG.mouse.visible = false; + activated = false; + + PlayState.customLoaded = false; + Paths.clearStoredMemory(); + Paths.clearUnusedMemory(); + + #if desktop + // Updating Discord Rich Presence + DiscordClient.changePresence("In the Menus", null); + #end + + if (!FlxG.sound.music.playing || !mainMusic) + { + FlxG.sound.playMusic(Paths.music('freakyMenu')); + } + + persistentUpdate = persistentDraw = true; + + var bg:FlxSprite = new FlxSprite(-80).loadGraphic(Paths.image('menuBG')); + bg.scrollFactor.x = 0; + bg.scrollFactor.y = 0.18; + bg.setGraphicSize(Std.int(bg.width * 1.1)); + bg.updateHitbox(); + bg.screenCenter(); + bg.antialiasing = true; + add(bg); + + camFollow = new FlxObject(0, 0, 1, 1); + add(camFollow); + + magenta = new FlxSprite(-80).loadGraphic(Paths.image('menuDesat')); + magenta.scrollFactor.x = 0; + magenta.scrollFactor.y = 0.18; + magenta.setGraphicSize(Std.int(magenta.width * 1.1)); + magenta.updateHitbox(); + magenta.screenCenter(); + magenta.visible = false; + magenta.antialiasing = true; + magenta.color = 0xFFfd719b; + add(magenta); + // magenta.scrollFactor.set(); + + menuItems = new FlxTypedGroup(); + add(menuItems); + + var tex = Paths.getSparrowAtlas('FNF_main_menu_assets'); + var menuItemX:Array = [100, 680, 100, 800, 150, 800, 150, 800]; + var menuItemY:Array = [60, 60, 240, 240, 420, 420, 600, 600]; + var menuItemSize:Array = [0.75, 0.65, 0.85, 0.85, 0.85, 0.85, 0.85, 0.85]; + + for (i in 0...optionShit.length) + { + menuItem = new FlxSprite(menuItemX[i], menuItemY[i]); + menuItem.frames = tex; + menuItem.animation.addByPrefix('idle', optionShit[i] + " basic", 24); + menuItem.animation.addByPrefix('selected', optionShit[i] + " white", 24); + menuItem.setGraphicSize(Std.int(menuItem.width * menuItemSize[i])); + menuItem.updateHitbox(); + menuItem.animation.play('idle'); + menuItem.ID = i; + menuItems.add(menuItem); + menuItem.scrollFactor.set(); + menuItem.antialiasing = true; + menuItem.centerOffsets(); + } + + FlxG.camera.follow(camFollow, null, 0.06); + + var versionShit:FlxText = new FlxText(5, FlxG.height - 18, 0, gameVer + " FNF - " + kadeEngineVer + " " + betadciuVer, 12); + versionShit.scrollFactor.set(); + versionShit.setFormat("VCR OSD Mono", 16, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + add(versionShit); + + // NG.core.calls.event.logEvent('swag').send(); + + if (FlxG.save.data.dfjk) + controls.setKeyboardScheme(KeyboardScheme.Solo, true); + else + controls.setKeyboardScheme(KeyboardScheme.Duo(true), true); + + changeItem(); + + Main.isHidden = false; + + super.create(); + } + + var selectedSomethin:Bool = false; + var activated:Bool = false; + var itemX:Array = []; + + override function update(elapsed:Float) + { + if (FlxG.sound.music.volume < 0.8) + { + FlxG.sound.music.volume += 0.5 * FlxG.elapsed; + } + + if (!selectedSomethin) + { + if (controls.UP_P) + { + FlxG.sound.play(Paths.sound('scrollMenu')); + changeItem(-2); + } + + if (controls.DOWN_P) + { + FlxG.sound.play(Paths.sound('scrollMenu')); + changeItem(2); + } + + if (controls.RIGHT_P) + { + FlxG.sound.play(Paths.sound('scrollMenu')); + changeItem(1); + } + + if (controls.LEFT_P) + { + FlxG.sound.play(Paths.sound('scrollMenu')); + changeItem(-1); + } + + if (controls.BACK) + { + FlxG.switchState(new TitleState()); + } + + if (controls.ACCEPT) + { + if (optionShit[curSelected] == 'donate') + { + #if linux + Sys.command('/usr/bin/xdg-open', ["https://ninja-muffin24.itch.io/funkin", "&"]); + #else + FlxG.openURL('https://ninja-muffin24.itch.io/funkin'); + #end + } + else + { + selectedSomethin = true; + FlxG.sound.play(Paths.sound('confirmMenu')); + + FlxFlicker.flicker(magenta, 1.1, 0.15, false); + + menuItems.forEach(function(spr:FlxSprite) + { + if (curSelected != spr.ID) + { + FlxTween.tween(spr, {alpha: 0}, 1.3, { + ease: FlxEase.quadOut, + onComplete: function(twn:FlxTween) + { + spr.kill(); + } + }); + } + else + { + FlxFlicker.flicker(spr, 1, 0.06, false, false, function(flick:FlxFlicker) + { + var daChoice:String = optionShit[curSelected]; + + switch (daChoice) + { + case 'betadciu': + FlxG.switchState(new BETADCIUState()); + trace("BETADCIU Menu Selected"); + + case 'bonus songs': + FlxG.switchState(new BonusSongsState()); + trace("BETADCIU Menu Selected"); + + case 'neonight': + FlxG.switchState(new NeonightState()); + trace("Neonight Menu Selected"); + + case 'vitor': + FlxG.switchState(new VitorState()); + trace("Vitor Menu Selected"); + + case 'options': + FlxG.switchState(new OptionsMenu()); + + case 'extras': + FlxG.switchState(new GuestBETADCIUState()); + trace("Extras Menu Selected"); + + case 'freeplay': + FlxG.switchState(new FreeplayState()); + trace("Freeplay Menu Selected"); + + } + }); + } + }); + } + } + } + super.update(elapsed); + } + + function changeItem(huh:Int = 0) + { + curSelected += huh; + + if (curSelected >= menuItems.length) + curSelected = 0; + if (curSelected == -2) + curSelected = menuItems.length - 2; + if (curSelected < 0) + curSelected = menuItems.length - 1; + + menuItems.forEach(function(spr:FlxSprite) + { + spr.animation.play('idle'); + + if (spr.ID == curSelected) + { + spr.animation.play('selected'); + + if (spr.ID < 6) + camFollow.setPosition(spr.getGraphicMidpoint().x, spr.getGraphicMidpoint().y); + } + + spr.updateHitbox(); + }); + + var selectedX:Array = [40, 600, 60, 750, 100, 750, 110, 750]; + var selectedY:Array = [50, 50, 230, 230, 410, 410, 590, 590]; + var staticX:Array = [100, 680, 100, 800, 150, 800, 150, 800]; + var staticY:Array = [60, 60, 240, 240, 420, 420, 600, 600]; + + for (i in 0...menuItems.members.length) + { + if (menuItems.members[i].animation.curAnim.name == 'selected') + { + menuItems.members[i].x = selectedX[i]; + menuItems.members[i].y = selectedY[i]; + } + else if (menuItems.members[i].animation.curAnim.name != 'selected') + { + menuItems.members[i].x = staticX[i]; + menuItems.members[i].y = staticY[i]; + } + } + } +} diff --git a/source/MansionDebris.hx b/source/MansionDebris.hx new file mode 100644 index 000000000..4230c013e --- /dev/null +++ b/source/MansionDebris.hx @@ -0,0 +1,66 @@ +package; + +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.animation.FlxBaseAnimation; +import flixel.graphics.frames.FlxAtlasFrames; + +using StringTools; + +class MansionDebris extends FlxSprite +{ + + var sc:Float = 1; + var tF:Float = 1; + var tD:Float = 1; + var pF:Float = 1; + var sx:Float = 0; + var sy:Float = 0; + + var time:Float = 0; + public function new(sX:Float, sY:Float, debName:String, scroll:Float, tFactor:Float, tDelay:Float, posFactor:Float) + { + sx = sX; + sy = sY; + x = sx; + y = sy; + super(x, y); + sc = scroll; + tF = tFactor; + tD = tDelay; + pF = posFactor; + frames = Paths.getSparrowAtlas('shaggy/god_bg'); + animation.addByPrefix('c', "deb_" + debName, 30); + //bgcloud.setGraphicSize(Std.int(bgcloud.width * 0.8)); + animation.play('c'); + scrollFactor.set(sc, sc); + antialiasing = true; + setGraphicSize(Std.int(frameWidth * (sc / 0.75))); + + updateHitbox(); + } + + var grav:Float = 0.15; + var vsp:Float = -20; + var hsp:Float = 0; + override function update(elapsed:Float) + { + time ++; + if (tD != -4) + { + x = sx; + y = sy + Math.sin((time + tD) / 50 * tF) * 50 * pF; + } + else + { + hsp = pF; + vsp += grav; + + x += hsp; + y += vsp; + angle -= hsp / 2; + } + + super.update(elapsed); + } +} \ No newline at end of file diff --git a/source/MenuCharacter.hx b/source/MenuCharacter.hx index 0ea1bfb78..1cf3e5b73 100644 --- a/source/MenuCharacter.hx +++ b/source/MenuCharacter.hx @@ -2,75 +2,78 @@ package; import flixel.FlxSprite; import flixel.graphics.frames.FlxAtlasFrames; -#if MODS_ALLOWED -import sys.io.File; -import sys.FileSystem; -#end -import openfl.utils.Assets; -import haxe.Json; -import haxe.format.JsonParser; -typedef MenuCharacterFile = { - var image:String; - var scale:Float; - var position:Array; - var idle_anim:String; - var confirm_anim:String; +class CharacterSetting +{ + public var x(default, null):Int; + public var y(default, null):Int; + public var scale(default, null):Float; + public var flipped(default, null):Bool; + + public function new(x:Int = 0, y:Int = 0, scale:Float = 1.0, flipped:Bool = false) + { + this.x = x; + this.y = y; + this.scale = scale; + this.flipped = flipped; + } } class MenuCharacter extends FlxSprite { - public var character:String; - private static var DEFAULT_CHARACTER:String = 'bf'; + private static var settings:Map = [ + 'bf' => new CharacterSetting(0, -20, 1.0, true), + 'gf' => new CharacterSetting(50, 80, 1.5, true), + 'dad' => new CharacterSetting(-15, 130), + 'spooky' => new CharacterSetting(20, 30), + 'pico' => new CharacterSetting(0, 0, 1.0, true), + 'mom' => new CharacterSetting(-30, 140, 0.85), + 'parents-christmas' => new CharacterSetting(100, 130, 1.8), + 'senpai' => new CharacterSetting(-40, -45, 1.4) + ]; + + private var flipped:Bool = false; - public function new(x:Float, character:String = 'bf') + public function new(x:Int, y:Int, scale:Float, flipped:Bool) { - super(x); + super(x, y); + this.flipped = flipped; - changeCharacter(character); - } + antialiasing = true; - public function changeCharacter(?character:String = 'bf') { - if(character == null) character = ''; - if(character == this.character) return; + frames = Paths.getSparrowAtlas('campaign_menu_UI_characters'); - this.character = character; - antialiasing = ClientPrefs.globalAntialiasing; - visible = true; + animation.addByPrefix('bf', "BF idle dance white", 24); + animation.addByPrefix('bfConfirm', 'BF HEY!!', 24, false); + animation.addByPrefix('gf', "GF Dancing Beat WHITE", 24); + 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); - var dontPlayAnim:Bool = false; - scale.set(1, 1); + setGraphicSize(Std.int(width * scale)); updateHitbox(); + } - switch(character) { - case '': - visible = false; - dontPlayAnim = true; - default: - var characterPath:String = 'images/menucharacters/' + character + '.json'; - var rawJson = null; - - var path:String = Paths.modFolders(characterPath); - if (!FileSystem.exists(path)) { - path = Main.getDataPath() + Paths.getPreloadPath(characterPath); - } + public function setCharacter(character:String):Void + { + if (character == '') + { + visible = false; + return; + } + else + { + visible = true; + } - if(!FileSystem.exists(path)) { - path = Main.getDataPath() + Paths.getPreloadPath('images/menucharacters/' + DEFAULT_CHARACTER + '.json'); - } - rawJson = File.getContent(path); - - var charFile:MenuCharacterFile = cast Json.parse(rawJson); - frames = Paths.getSparrowAtlas('menucharacters/' + charFile.image); - animation.addByPrefix('idle', charFile.idle_anim, 24); - animation.addByPrefix('confirm', charFile.confirm_anim, 24, false); + animation.play(character); - if(charFile.scale != 1) { - scale.set(charFile.scale, charFile.scale); - updateHitbox(); - } - offset.set(charFile.position[0], charFile.position[1]); - animation.play('idle'); - } + var setting:CharacterSetting = settings[character]; + offset.set(setting.x, setting.y); + setGraphicSize(Std.int(width * setting.scale)); + flipX = setting.flipped != flipped; } } diff --git a/source/MenuItem.hx b/source/MenuItem.hx index 2501463df..5f8304bc9 100644 --- a/source/MenuItem.hx +++ b/source/MenuItem.hx @@ -3,20 +3,21 @@ package; import flixel.FlxG; import flixel.FlxSprite; import flixel.graphics.frames.FlxAtlasFrames; +import flixel.group.FlxSpriteGroup; import flixel.math.FlxMath; import flixel.util.FlxColor; -class MenuItem extends FlxSprite +class MenuItem extends FlxSpriteGroup { public var targetY:Float = 0; + public var week:FlxSprite; public var flashingInt:Int = 0; - public function new(x:Float, y:Float, weekName:String = '') + public function new(x:Float, y:Float, weekNum:Int = 0) { super(x, y); - loadGraphic(Paths.image('storymenu/' + weekName)); - //trace('Test added: ' + WeekData.getWeekNumber(weekNum) + ' (' + weekNum + ')'); - antialiasing = ClientPrefs.globalAntialiasing; + week = new FlxSprite().loadGraphic(Paths.image('storymenu/week' + weekNum)); + add(week); } private var isFlashing:Bool = false; @@ -35,14 +36,14 @@ class MenuItem extends FlxSprite override function update(elapsed:Float) { super.update(elapsed); - y = FlxMath.lerp(y, (targetY * 120) + 480, CoolUtil.boundTo(elapsed * 10.2, 0, 1)); + y = FlxMath.lerp(y, (targetY * 120) + 480, 0.17 * (60 / FlxG.save.data.fpsCap)); if (isFlashing) flashingInt += 1; - + if (flashingInt % fakeFramerate >= Math.floor(fakeFramerate / 2)) - color = 0xFF33ffff; - else - color = FlxColor.WHITE; + week.color = 0xFF33ffff; + else if (FlxG.save.data.flashing) + week.color = FlxColor.WHITE; } } diff --git a/source/ModchartState.hx b/source/ModchartState.hx new file mode 100644 index 000000000..a5778877e --- /dev/null +++ b/source/ModchartState.hx @@ -0,0 +1,4140 @@ +// this file is for modchart things, this is to declutter playstate.hx + +// Lua +import openfl.display3D.textures.VideoTexture; +import flixel.graphics.FlxGraphic; +import flixel.graphics.frames.FlxAtlasFrames; +#if desktop +import flixel.tweens.FlxEase; +import openfl.filters.ShaderFilter; +import openfl.Lib; +import flixel.tweens.FlxTween; +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.util.FlxColor; +import openfl.geom.Matrix; +import openfl.display.BitmapData; +import lime.app.Application; +import flixel.FlxSprite; +import llua.Convert; +import llua.Lua; +import llua.State; +import llua.LuaL; +import flixel.FlxBasic; +import flixel.FlxCamera; +import flixel.FlxG; +import flixel.FlxObject; +import flixel.system.FlxSound; +import flixel.effects.FlxFlicker; +import flixel.addons.effects.FlxTrail; +import flixel.addons.effects.FlxTrailArea; +import Type.ValueType; +import flixel.util.FlxTimer; +import flixel.text.FlxText; +import openfl.system.System; +import lime.utils.Assets; +import flixel.math.FlxMath; +import openfl.display.BlendMode; +import flixel.tweens.misc.ColorTween; +import Shaders; +import flash.media.Sound; +import lime.media.AudioBuffer; + +import flixel.system.FlxAssets.FlxShader; +import openfl.display.Shader; +import openfl.display.ShaderInput; + +//why is detected's modchart confusing!? +import LuaClass.LuaGame; +import LuaClass.LuaWindow; +import LuaClass.LuaSprite; +import LuaClass.LuaCamera; +import LuaClass.LuaNote; +import LuaClass.LuaReceptor; + +#if desktop +import Sys; +import sys.io.File; +import sys.FileSystem; +#end + +using StringTools; + +class ModchartState +{ + //public static var shaders:Array = null; + public static var Function_Stop = 1; + public static var Function_Continue = 0; + + #if desktop + public var lua:State = null; + #end + + var lePlayState:PlayState = null; + + public var scriptName:String = ''; + var gonnaClose:Bool = false; + + public var accessedProps:Map = null; + + public static var shownNotes:Array = []; + + public var blam:Dynamic = ""; + + public function call(func_name : String, args : Array, ?type : String) : Dynamic + { + #if desktop + if(lua == null) { + return Function_Continue; + } + + var result : Any = null; + + Lua.getglobal(lua, func_name); + + for (arg in args) { + Convert.toLua(lua, arg); + } + + var result:Null = Lua.pcall(lua, args.length, 1, 0); + if(result != null && resultIsAllowed(lua, result)) { + if(Lua.type(lua, -1) == Lua.LUA_TSTRING) { + var error:String = Lua.tostring(lua, -1); + Lua.pop(lua, 1); + if(error == 'attempt to call a nil value') { //Makes it ignore warnings and not break stuff if you didn't put the functions on your lua file + return Function_Continue; + } + } + + return convert(result, type); + } + #end + return Function_Continue; + } + + #if desktop + function resultIsAllowed(leLua:State, leResult:Null) { //Makes it ignore warnings + switch(Lua.type(leLua, leResult)) { + case Lua.LUA_TNIL | Lua.LUA_TBOOLEAN | Lua.LUA_TNUMBER | Lua.LUA_TSTRING | Lua.LUA_TTABLE: + return true; + } + return false; + } + #end + + static function toLua(l:State, val:Any):Bool { + switch (Type.typeof(val)) { + case Type.ValueType.TNull: + Lua.pushnil(l); + case Type.ValueType.TBool: + Lua.pushboolean(l, val); + case Type.ValueType.TInt: + Lua.pushinteger(l, cast(val, Int)); + case Type.ValueType.TFloat: + Lua.pushnumber(l, val); + case Type.ValueType.TClass(String): + Lua.pushstring(l, cast(val, String)); + case Type.ValueType.TClass(Array): + Convert.arrayToLua(l, val); + case Type.ValueType.TObject: + objectToLua(l, val); + default: + trace("haxe value not supported - " + val + " which is a type of " + Type.typeof(val)); + return false; + } + + return true; + + } + + static function objectToLua(l:State, res:Any) { + + var FUCK = 0; + for(n in Reflect.fields(res)) + { + trace(Type.typeof(n).getName()); + FUCK++; + } + + Lua.createtable(l, FUCK, 0); // TODONE: I did it + + for (n in Reflect.fields(res)){ + if (!Reflect.isObject(n)) + continue; + Lua.pushstring(l, n); + toLua(l, Reflect.field(res, n)); + Lua.settable(l, -3); + } + + } + + function getType(l, type):Any + { + return switch Lua.type(l,type) { + case t if (t == Lua.LUA_TNIL): null; + case t if (t == Lua.LUA_TNUMBER): Lua.tonumber(l, type); + case t if (t == Lua.LUA_TSTRING): (Lua.tostring(l, type):String); + case t if (t == Lua.LUA_TBOOLEAN): Lua.toboolean(l, type); + case t: throw 'you don goofed up. lua type error ($t)'; + } + } + + function getReturnValues(l) { + var lua_v:Int; + var v:Any = null; + while((lua_v = Lua.gettop(l)) != 0) { + var type:String = getType(l,lua_v); + v = convert(lua_v, type); + Lua.pop(l, 1); + } + return v; + } + + + private function convert(v : Any, type : String) : Dynamic { // I didn't write this lol + if( Std.is(v, String) && type != null ) { + var v : String = v; + if( type.substr(0, 4) == 'array' ) { + if( type.substr(4) == 'float' ) { + var array : Array = v.split(','); + var array2 : Array = new Array(); + + for( vars in array ) { + array2.push(Std.parseFloat(vars)); + } + + return array2; + } else if( type.substr(4) == 'int' ) { + var array : Array = v.split(','); + var array2 : Array = new Array(); + + for( vars in array ) { + array2.push(Std.parseInt(vars)); + } + + return array2; + } else { + var array : Array = v.split(','); + return array; + } + } else if( type == 'float' ) { + return Std.parseFloat(v); + } else if( type == 'int' ) { + return Std.parseInt(v); + } else if( type == 'bool' ) { + if( v == 'true' ) { + return true; + } else { + return false; + } + } else { + return v; + } + } else { + return v; + } + } + + function getLuaErrorMessage(l) { + var v:String = Lua.tostring(l, -1); + Lua.pop(l, 1); + return v; + } + + public function set(var_name : String, object : Dynamic){ + // trace('setting variable ' + var_name + ' to ' + object); + + Convert.toLua(lua, object); + Lua.setglobal(lua, var_name); + } + + public function get(var_name : String, type : String) : Dynamic { + var result : Any = null; + + // trace('getting variable ' + var_name + ' with a type of ' + type); + + Lua.getglobal(lua, var_name); + result = Convert.fromLua(lua,-1); + Lua.pop(lua,1); + + if( result == null ) { + return null; + } else { + var result = convert(result, type); + //trace(var_name + ' result: ' + result); + return result; + } + } + + function doFunction(id:String, ?val1:Dynamic, ?val2:Dynamic, ?val3:Dynamic, ?val4:Dynamic) + { + //this is dumb but idk how else to do it and i don't wanna make multiple functions for different playstate functions so yeah. + switch (id) + { + case 'doP3Static': PlayState.instance.doP3Static(); + case 'doP3Jump': PlayState.instance.doP3Jump(val1); + case 'funCountdown': PlayState.instance.funCountdown(val1); + case 'softCountdown': PlayState.instance.softCountdown(); + case 'startCountdown': PlayState.instance.startCountdown(); + case 'doJumpscare': PlayState.instance.doJumpscare(); + case 'startWriting': PlayState.instance.startWriting(val1, val2); + case 'doSonicIntro': PlayState.instance.doSonicIntro(val1, val2); + case 'doSimpleJump': PlayState.instance.doSimpleJump(val1); + case 'resyncVocals': PlayState.instance.resyncVocals(); + case 'doTimeTravel': PlayState.instance.doTimeTravel(val1, val2); + case 'uncacheImage': Paths.clearStoredMemory2(val1); + case 'cacheImage': Paths.cacheImage(val1, val2); + case 'toggleHealthShit': PlayState.instance.toggleHealthShit(val1); + case 'spawnStartingNoteSplash': PlayState.instance.spawnStartingNoteSplash(0, 0, 0); + case 'doStopSign': PlayState.instance.doStopSign(val1, val2); + case 'doGremlin': PlayState.instance.doGremlin(val1, val2, val3); + case 'bgFlash': PlayState.instance.bgFlash(); + case 'createBFSpookyText': PlayState.instance.createBFSpookyText(val1); + case 'createSpookyText': PlayState.instance.createSpookyText(val1); + case 'createAuditorText': PlayState.instance.createAuditorText(val1, val2, val3, val4); + } + } + + public function luaTrace(text:String, ignoreCheck:Bool = false, deprecated:Bool = false) { + #if desktop + if(ignoreCheck || getBool('luaDebugMode')) { + if(deprecated && !getBool('luaDeprecatedWarnings')) { + return; + } + PlayState.instance.addTextToDebug(text); + trace(text); + } + #end + } + + #if desktop + public function getBool(variable:String) { + var result:String = null; + Lua.getglobal(lua, variable); + result = Convert.fromLua(lua, -1); + Lua.pop(lua, 1); + + if(result == null) { + return false; + } + + // YES! FINALLY IT WORKS + //trace('variable: ' + variable + ', ' + result); + return (result == 'true'); + } + #end + + public function makeLuaCharacter(tag:String, character:String, isPlayer:Bool = false, flipped:Bool = false) + { + tag = tag.replace('.', ''); + resetCharacterTag(tag); + var leSprite:Character = new Character(0, 0, character, isPlayer); + leSprite.flipMode = flipped; + PlayState.instance.modchartCharacters.set(tag, leSprite); //yes + var shit:Character = PlayState.instance.modchartCharacters.get(tag); + PlayState.instance.add(shit); + + var charOffset = new CharacterOffsets(character, flipped); + var charX:Float = charOffset.daOffsetArray[0]; + var charY:Float = charOffset.daOffsetArray[1] + (flipped ? 350 : 0); + + if (!isPlayer) + { + if (flipped) + shit.flipMode = true; + + if (!shit.isCustom) + { + if (flipped) + { + if (charX == 0 && charOffset.daOffsetArray[1] == 0 && !charOffset.hasOffsets) + { + var charOffset2 = new CharacterOffsets(character, false); + charX = charOffset2.daOffsetArray[0]; + charY = charOffset2.daOffsetArray[1]; + } + } + else + { + if (charX == 0 && charY == 0 && !charOffset.hasOffsets) + { + var charOffset2 = new CharacterOffsets(character, true); + charX = charOffset2.daOffsetArray[0]; + charY = charOffset2.daOffsetArray[1] + 350; + } + } + } + + if (shit.isCustom) + { + charX = shit.positionArray[0]; + charY = shit.positionArray[1]; + } + + shit.x = PlayState.instance.Stage.dadXOffset + charX + 100; + shit.y = PlayState.instance.Stage.dadYOffset + charY + 100; + } + else + { + if (flipped) + shit.flipMode = true; + + var charOffset = new CharacterOffsets(character, !flipped); + var charX:Float = charOffset.daOffsetArray[0]; + var charY:Float = charOffset.daOffsetArray[1] - (!flipped ? 0 : 350); + + if (!shit.isCustom) + { + if (flipped) + { + if (charX == 0 && charOffset.daOffsetArray[1] == 0) + { + var charOffset2 = new CharacterOffsets(character, true); + charX = charOffset2.daOffsetArray[0]; + charY = charOffset2.daOffsetArray[1]; + } + } + else + { + if (charX == 0 && charY == 0 && !shit.curCharacter.startsWith('bf')) + { + var charOffset2 = new CharacterOffsets(character, false); + charX = charOffset2.daOffsetArray[0]; + charY = charOffset2.daOffsetArray[1] - 350; + } + } + } + + if (shit.isCustom) + { + charX = shit.positionArray[0]; + charY = shit.positionArray[1] - 350; + } + + shit.x = PlayState.instance.Stage.bfXOffset + charX + 770; + shit.y = PlayState.instance.Stage.bfYOffset + charY + 450; + } + + PlayState.instance.startCharacterLua(shit.curCharacter); + } + + function getActorByName(id:String):Dynamic + { + // pre defined names + switch(id) + { + case 'boyfriend' | 'bf': + @:privateAccess + return PlayState.instance.boyfriend; + case 'gf': + @:privateAccess + return PlayState.instance.gf; + case 'camFollow': + @:privateAccess + return PlayState.instance.camFollow; + case 'camHUD': + @:privateAccess + return PlayState.instance.camHUD; + case 'camGame': + @:privateAccess + return FlxG.camera; + case 'camGame.scroll': + @:privateAccess + return FlxG.camera.scroll; + } + + if (id.contains('stage-')) + { + var daID:String = id.split('-')[1]; + return PlayState.instance.Stage.swagBacks[daID]; + } + + if (Std.parseInt(id) == null) + return Reflect.getProperty(getInstance(),id); + return PlayState.instance.strumLineNotes.members[Std.parseInt(id)]; + } + + function getCurCharacter(id:String) + { + return getActorByName(id).curCharacter; + } + + //Kade why tf is it not like in PlayState??? + + function changeGFCharacter(id:String, x:Float, y:Float) + { + PlayState.instance.removeObject(PlayState.instance.gf); + //PlayState.instance.gf = new Character(x, y, null); + PlayState.instance.destroyObject(PlayState.instance.gf); + PlayState.instance.gf = new Character(x, y, id); + PlayState.instance.gf.scrollFactor.set(0.95, 0.95); + PlayState.instance.addObject(PlayState.instance.gf); + + if (FlxG.save.data.poltatoPC) + PlayState.instance.gf.setPosition(PlayState.instance.gf.x + 100, PlayState.instance.gf.y + 170); + + PlayState.instance.startCharacterLua(PlayState.instance.gf.curCharacter); + + } + + function changeDadCharacter(id:String, x:Float, y:Float) + { + //this is why i don't use exTricky + var wasExTricky:Bool = false; + var isExTricky:Bool = false; + + if (PlayState.instance.dad.curCharacter == 'exTricky') + wasExTricky = true; + + if (id == 'exTricky') + isExTricky = true; + + if (wasExTricky) + { + PlayState.instance.removeObject(PlayState.instance.dad.exSpikes); + PlayState.instance.destroyObject(PlayState.instance.dad.exSpikes); + } + + PlayState.instance.removeObject(PlayState.instance.dadTrail); + PlayState.instance.removeObject(PlayState.instance.dad); + PlayState.instance.destroyObject(PlayState.instance.dad); + PlayState.instance.dad = new Character(x, y, id); + PlayState.instance.addObject(PlayState.instance.dadTrail); + PlayState.instance.dadTrail.resetTrail(); + PlayState.instance.addObject(PlayState.instance.dad); + + if (isExTricky) + PlayState.instance.addObject(PlayState.instance.dad.exSpikes); + + if (PlayState.newIcons) + { + if (PlayState.swapIcons) + PlayState.instance.iconP2.changeIcon(PlayState.instance.dad.healthIcon); + } + else + PlayState.instance.iconP2.useOldSystem(PlayState.instance.dad.healthIcon); + + if (PlayState.instance.changeArrows) + { + for (i in 0...Main.keyAmmo[PlayState.SONG.mania]) + { + PlayState.instance.strumLineNotes.members[i].texture = PlayState.instance.dad.noteSkin; + } + } + + if (PlayState.instance.defaultBar) + { + PlayState.instance.healthBar.createFilledBar(FlxColor.fromString('#' + PlayState.instance.dad.iconColor), FlxColor.fromString('#' + PlayState.instance.boyfriend.iconColor)); + PlayState.instance.healthBar.updateBar(); + } + + PlayState.instance.startCharacterLua(PlayState.instance.dad.curCharacter); + + } + + function changeBoyfriendCharacter(id:String, x:Float, y:Float) + { + var animationName:String = "no way anyone have an anim name this big"; + var animationFrame:Int = 0; + if (PlayState.instance.boyfriend.animation.curAnim.name.startsWith('sing')) + { + animationName = PlayState.instance.boyfriend.animation.curAnim.name; + animationFrame = PlayState.instance.boyfriend.animation.curAnim.curFrame; + } + + PlayState.instance.removeObject(PlayState.instance.bfTrail); + PlayState.instance.removeObject(PlayState.instance.boyfriend); + PlayState.instance.destroyObject(PlayState.instance.boyfriend); + PlayState.instance.boyfriend = new Boyfriend(x, y, id); + PlayState.instance.addObject(PlayState.instance.bfTrail); + PlayState.instance.bfTrail.resetTrail(); + PlayState.instance.addObject(PlayState.instance.boyfriend); + + if (PlayState.newIcons) + { + if (PlayState.swapIcons) + PlayState.instance.iconP1.changeIcon(PlayState.instance.boyfriend.healthIcon); + else + ''; //do nothing + } + else + PlayState.instance.iconP1.useOldSystem(PlayState.instance.boyfriend.healthIcon); + + if (PlayState.instance.changeArrows) + { + for (i in Main.keyAmmo[PlayState.SONG.mania]...Main.keyAmmo[PlayState.SONG.mania] * 2) + { + PlayState.instance.strumLineNotes.members[i].texture = PlayState.instance.boyfriend.noteSkin; + PlayState.instance.bfStrumStyle = PlayState.instance.boyfriend.noteSkin; + } + } + + if (PlayState.instance.defaultBar) + { + PlayState.instance.healthBar.createFilledBar(FlxColor.fromString('#' + PlayState.instance.dad.iconColor), FlxColor.fromString('#' + PlayState.instance.boyfriend.iconColor)); + PlayState.instance.healthBar.updateBar(); + } + + if (PlayState.instance.boyfriend.animOffsets.exists(animationName)) + PlayState.instance.boyfriend.playAnim(animationName, true, false, animationFrame); + + PlayState.instance.startCharacterLua(PlayState.instance.boyfriend.curCharacter); + } + + //does this work. right? -- future me here. yes it does. + function changeStage(id:String) + { + PlayState.instance.removeObject(PlayState.instance.gf); + PlayState.instance.removeObject(PlayState.instance.dad); + PlayState.instance.removeObject(PlayState.instance.boyfriend); + + if (PlayState.instance.Stage.isCustomStage && PlayState.instance.Stage.luaArray.length >= 1) + { + trace(PlayState.instance.Stage.luaArray.length); + + for (i in PlayState.instance.Stage.luaArray) + { + PlayState.instance.Stage.luaArray.remove(i); + i.die(); + } + PlayState.instance.Stage.luaArray = []; + trace(PlayState.instance.Stage.luaArray.length); + } + + for (i in PlayState.instance.Stage.toAdd) + { + PlayState.instance.removeObject(i); + PlayState.instance.destroyObject(i); + } + + for (i in PlayState.instance.Stage.layInFront[0]) + { + PlayState.instance.removeObject(i); + PlayState.instance.destroyObject(i); + } + + for (i in PlayState.instance.Stage.layInFront[1]) + { + PlayState.instance.removeObject(i); + PlayState.instance.destroyObject(i); + } + + for (i in PlayState.instance.Stage.layInFront[2]) + { + PlayState.instance.removeObject(i); + PlayState.instance.destroyObject(i); + } + + PlayState.instance.Stage.swagBacks.clear(); + + PlayState.instance.removeObject(PlayState.instance.Stage); + PlayState.instance.destroyObject(PlayState.instance.Stage); + + PlayState.instance.Stage = new Stage(id); + PlayState.curStage = PlayState.instance.Stage.curStage; + PlayState.instance.defaultCamZoom = PlayState.instance.Stage.camZoom; + + for (i in PlayState.instance.Stage.toAdd) + { + PlayState.instance.addObject(i); + } + + for (index => array in PlayState.instance.Stage.layInFront) + { + switch (index) + { + case 0: + PlayState.instance.addObject(PlayState.instance.gf); + PlayState.instance.gf.scrollFactor.set(0.95, 0.95); + for (bg in array) + PlayState.instance.addObject(bg); + case 1: + PlayState.instance.addObject(PlayState.instance.dad); + for (bg in array) + PlayState.instance.addObject(bg); + case 2: + PlayState.instance.addObject(PlayState.instance.boyfriend); + + for (bg in array) + PlayState.instance.addObject(bg); + } + } + } + + // this is better. easier to port shit from playstate. + function changeGFCharacterBetter(x:Float, y:Float, id:String) + { + changeGFCharacter(id, x, y); + } + + function changeDadCharacterBetter(x:Float, y:Float, id:String) + { + changeDadCharacter(id, x, y); + } + + function changeBoyfriendCharacterBetter(x:Float, y:Float, id:String) + { + changeBoyfriendCharacter(id, x, y); + } + + //trying to do some auto stuff so i don't have to set manual x and y values + public function changeBFAuto(id:String, ?flipped:Bool = false, ?dontDestroy:Bool = false) + { + var animationName:String = "no way anyone have an anim name this big"; + var animationFrame:Int = 0; + if (PlayState.instance.boyfriend.animation.curAnim.name.startsWith('sing')) + { + animationName = PlayState.instance.boyfriend.animation.curAnim.name; + animationFrame = PlayState.instance.boyfriend.animation.curAnim.curFrame; + } + + var bfPath:String = ""; + + if (FlxG.save.data.uncacheCharacterSwitch && !dontDestroy) + bfPath = 'shared:assets/shared/images/'+PlayState.instance.boyfriend.charPath; + + PlayState.instance.removeObject(PlayState.instance.bfTrail); + PlayState.instance.removeObject(PlayState.instance.boyfriend); + PlayState.instance.destroyObject(PlayState.instance.boyfriend); + PlayState.instance.boyfriend = new Boyfriend(0, 0, id, !flipped); + + PlayState.instance.boyfriend.flipMode = flipped; + + var charOffset = new CharacterOffsets(id, !flipped); + var charX:Float = charOffset.daOffsetArray[0]; + var charY:Float = charOffset.daOffsetArray[1] - (!flipped ? 0 : 350); + + if (!PlayState.instance.boyfriend.isCustom) + { + if (flipped) + { + if (charX == 0 && charOffset.daOffsetArray[1] == 0) + { + var charOffset2 = new CharacterOffsets(id, true); + charX = charOffset2.daOffsetArray[0]; + charY = charOffset2.daOffsetArray[1]; + } + } + else + { + if (charX == 0 && charY == 0 && !PlayState.instance.boyfriend.curCharacter.startsWith('bf')) + { + var charOffset2 = new CharacterOffsets(id, false); + charX = charOffset2.daOffsetArray[0]; + charY = charOffset2.daOffsetArray[1] - 350; + } + } + } + + if (PlayState.instance.boyfriend.isCustom) + { + charX = PlayState.instance.boyfriend.positionArray[0]; + charY = PlayState.instance.boyfriend.positionArray[1] - 350; + } + + PlayState.instance.boyfriend.x = PlayState.instance.Stage.bfXOffset + charX + 770; + PlayState.instance.boyfriend.y = PlayState.instance.Stage.bfYOffset + charY + 450; + + PlayState.instance.addObject(PlayState.instance.bfTrail); + PlayState.instance.bfTrail.resetTrail(); + PlayState.instance.addObject(PlayState.instance.boyfriend); + + if (PlayState.newIcons) + { + if (PlayState.swapIcons) + PlayState.instance.iconP1.changeIcon(PlayState.instance.boyfriend.healthIcon); + } + else + PlayState.instance.iconP1.useOldSystem(PlayState.instance.boyfriend.healthIcon); + + if (PlayState.instance.defaultBar) + { + PlayState.instance.healthBar.createFilledBar(FlxColor.fromString('#' + PlayState.instance.dad.iconColor), FlxColor.fromString('#' + PlayState.instance.boyfriend.iconColor)); + PlayState.instance.healthBar.updateBar(); + } + + if (PlayState.instance.boyfriend.animOffsets.exists(animationName)) + PlayState.instance.boyfriend.playAnim(animationName, true, false, animationFrame); + + if (FlxG.save.data.uncacheCharacterSwitch && !dontDestroy) + Paths.clearStoredMemory2(bfPath); + + if (PlayState.instance.changeArrows) + { + for (i in Main.keyAmmo[PlayState.SONG.mania]...Main.keyAmmo[PlayState.SONG.mania] * 2) + { + PlayState.instance.strumLineNotes.members[i].texture = PlayState.instance.boyfriend.noteSkin; + PlayState.instance.bfStrumStyle = PlayState.instance.boyfriend.noteSkin; + } + } + + PlayState.instance.startCharacterLua(PlayState.instance.boyfriend.curCharacter); + } + + public function changeDadAuto(id:String, ?flipped:Bool = false, ?dontDestroy:Bool = false) + { + var animationName:String = "no way anyone have an anim name this big"; + var animationFrame:Int = 0; + if (PlayState.instance.dad.animation.curAnim.name.startsWith('sing')) + { + animationName = PlayState.instance.dad.animation.curAnim.name; + animationFrame = PlayState.instance.dad.animation.curAnim.curFrame; + } + + var dadPath:String = ''; + var daCurChar:String = PlayState.instance.dad.curCharacter; + + if (FlxG.save.data.uncacheCharacterSwitch && !dontDestroy) + dadPath = 'shared:assets/shared/images/'+PlayState.instance.dad.charPath; + + PlayState.instance.removeObject(PlayState.instance.dadTrail); + PlayState.instance.removeObject(PlayState.instance.dad); + PlayState.instance.destroyObject(PlayState.instance.dad); + PlayState.instance.dad = new Character(0, 0, id, flipped); + + var charOffset = new CharacterOffsets(id, flipped); + var charX:Float = charOffset.daOffsetArray[0]; + var charY:Float = charOffset.daOffsetArray[1] + (flipped ? 350 : 0); + + if (flipped) + PlayState.instance.dad.flipMode = true; + + if (!PlayState.instance.dad.isCustom) + { + if (flipped) + { + if (charX == 0 && charOffset.daOffsetArray[1] == 0 && !charOffset.hasOffsets) + { + var charOffset2 = new CharacterOffsets(id, false); + charX = charOffset2.daOffsetArray[0]; + charY = charOffset2.daOffsetArray[1]; + } + } + else + { + if (charX == 0 && charY == 0 && !charOffset.hasOffsets) + { + var charOffset2 = new CharacterOffsets(id, true); + charX = charOffset2.daOffsetArray[0]; + charY = charOffset2.daOffsetArray[1] + 350; + } + } + } + + if (PlayState.instance.dad.isCustom) + { + charX = PlayState.instance.dad.positionArray[0]; + charY = PlayState.instance.dad.positionArray[1]; + } + + PlayState.instance.dad.x = PlayState.instance.Stage.dadXOffset + charX + 100; + PlayState.instance.dad.y = PlayState.instance.Stage.dadYOffset + charY + 100; + + PlayState.instance.addObject(PlayState.instance.dadTrail); + PlayState.instance.dadTrail.resetTrail(); + PlayState.instance.addObject(PlayState.instance.dad); + + if (PlayState.newIcons) + { + if (PlayState.swapIcons) + PlayState.instance.iconP2.changeIcon(PlayState.instance.dad.healthIcon); + } + else + PlayState.instance.iconP2.useOldSystem(PlayState.instance.dad.healthIcon); + + if (PlayState.instance.defaultBar) + { + PlayState.instance.healthBar.createFilledBar(FlxColor.fromString('#' + PlayState.instance.dad.iconColor), FlxColor.fromString('#' + PlayState.instance.boyfriend.iconColor)); + PlayState.instance.healthBar.updateBar(); + } + + if (PlayState.instance.dad.animOffsets.exists(animationName)) + PlayState.instance.dad.playAnim(animationName, true, false, animationFrame); + + if (FlxG.save.data.uncacheCharacterSwitch && !dontDestroy && daCurChar != PlayState.instance.dad.curCharacter) + Paths.clearStoredMemory2(dadPath); + + if (PlayState.instance.changeArrows) + { + for (i in 0...Main.keyAmmo[PlayState.SONG.mania]) + { + PlayState.instance.cpuStrums.members[i].texture = PlayState.instance.dad.noteSkin; + } + } + + PlayState.instance.startCharacterLua(PlayState.instance.dad.curCharacter); + } + + function changeGFAuto(id:String, ?dontDestroy:Bool = false) + { + PlayState.instance.removeObject(PlayState.instance.gf); + PlayState.instance.destroyObject(PlayState.instance.gf); + PlayState.instance.gf = new Character(0, 0, id); + PlayState.instance.gf.x = PlayState.instance.Stage.gfXOffset + 400 + PlayState.instance.gf.positionArray[0]; + PlayState.instance.gf.y = PlayState.instance.Stage.gfYOffset + 130 + PlayState.instance.gf.positionArray[1]; + PlayState.instance.gf.scrollFactor.set(0.95, 0.95); + PlayState.instance.addObject(PlayState.instance.gf); + + if (FlxG.save.data.poltatoPC) + PlayState.instance.gf.setPosition(PlayState.instance.gf.x + 100, PlayState.instance.gf.y + 170); + + var gfPath:String = ''; + + if (FlxG.save.data.uncacheCharacterSwitch && !dontDestroy) + gfPath = 'shared:assets/shared/images/'+PlayState.instance.gf.charPath; + + if (FlxG.save.data.uncacheCharacterSwitch && !dontDestroy) + Paths.clearStoredMemory2(gfPath); + + PlayState.instance.startCharacterLua(PlayState.instance.gf.curCharacter); + } + + function changeStageOffsets(char:String, x:Float = -10000, ?y:Float = -10000) //in case you need to change or test the stage offsets for the auto commands + { + switch (char) + { + case 'boyfriend' | 'bf': + if (x != -10000) + PlayState.instance.Stage.bfXOffset = x; + if (y != -10000) + PlayState.instance.Stage.bfYOffset = y; + case 'gf': + if (x != -10000) + PlayState.instance.Stage.gfXOffset = x; + if (y != -10000) + PlayState.instance.Stage.gfYOffset = y; + default: + if (x != -10000) + PlayState.instance.Stage.dadXOffset = x; + if (y != -10000) + PlayState.instance.Stage.dadYOffset = y; + } + } + + function getGroupStuff(leArray:Dynamic, variable:String) { + var killMe:Array = variable.split('.'); + if(killMe.length > 1) { + var coverMeInPiss:Dynamic = Reflect.getProperty(leArray, killMe[0]); + for (i in 1...killMe.length-1) { + coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); + } + return Reflect.getProperty(coverMeInPiss, killMe[killMe.length-1]); + } + return Reflect.getProperty(leArray, variable); + } + + function setGroupStuff(leArray:Dynamic, variable:String, value:Dynamic) { + var killMe:Array = variable.split('.'); + if(killMe.length > 1) { + var coverMeInPiss:Dynamic = Reflect.getProperty(leArray, killMe[0]); + for (i in 1...killMe.length-1) { + coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); + } + Reflect.setProperty(coverMeInPiss, killMe[killMe.length-1], value); + return; + } + Reflect.setProperty(leArray, variable, value); + } + + public function die() { + #if desktop + if(lua == null) { + return; + } + + if(accessedProps != null) { + accessedProps.clear(); + } + + Lua.close(lua); + lua = null; + #end + } + // LUA SHIT + + public function new(path:String) + { + // for detected + //instance = this; + + var ogPath:String = ""; + + if (path.contains('assets/shared')) //in case I wanna take from shared + { + ogPath = path; + path = FileSystem.absolutePath(path); + } + + + if (PlayState.instance.isDetected && PlayState.instance != null) + shownNotes = []; + + trace('opening a lua state (because we are cool :))'); + lua = LuaL.newstate(); + LuaL.openlibs(lua); + Lua.init_callbacks(lua); + trace("Lua version: " + Lua.version()); + trace("LuaJIT version: " + Lua.versionJIT()); + + var result = LuaL.dofile(lua, path); // execute le file + var resultStr:String = Lua.tostring(lua, result); + + if (resultStr != null && result != 0) + { + Application.current.window.alert("LUA COMPILE ERROR:\n" + resultStr,"Kade Engine Modcharts");//kep this + trace('oops you screwed up'); + Lua.close(lua); + lua = null; + PlayState.instance.luaArray.remove(this); + PlayState.instance.luaArray = []; + return; + } + + scriptName = path; + + if (ogPath.contains('assets/shared')) + scriptName = ogPath; + + //shaders = new Array(); + + var curState:Dynamic = FlxG.state; + lePlayState = curState; + + // get some fukin globals up in here bois + + set('Function_Stop', Function_Stop); + set('Function_Continue', Function_Continue); //i have no idea how this works + set('endDaSong', true); + set('luaDebugMode', true); + set('luaDeprecatedWarnings', true); + set('inChartEditor', false); + + set("difficulty", PlayState.storyDifficulty); + set("bpm", PlayState.SONG.bpm); + set("curBpm", Conductor.bpm); + set("scrollspeed", FlxG.save.data.scrollSpeed != 1 ? FlxG.save.data.scrollSpeed : PlayState.SONG.speed); + set("fpsCap", FlxG.save.data.fpsCap); + set("downscroll", FlxG.save.data.downscroll); + set("flashing", FlxG.save.data.flashing); + set("distractions", FlxG.save.data.distractions); + set('songLength', FlxG.sound.music.length); + set('songName', PlayState.SONG.song); + set('seenCutscene', PlayState.seenCutscene); + + set("curStep", 0); + set("daSection", 0); + set("curBeat", 0); + set("crochet", Conductor.crochet); + set("stepCrochet", Conductor.stepCrochet); + set("safeZoneOffset", Conductor.safeZoneOffset); + + set("cameraZoom", FlxG.camera.zoom); + + set("cameraAngle", FlxG.camera.angle); + + set("followBFXOffset",0); + set("followBFYOffset",0); + set("followDadXOffset",0); + set("followDadYOffset",0); + + set("bfAltAnim", false); + set("dadAltAnim", false); + set("bfNotesVisible", true); + set("dadNotesInvisible", false); + + set("showOnlyStrums", false); + set("strumLine1Visible", true); + set("strumLine2Visible", true); + + set("screenWidth",FlxG.width); + set("screenHeight",FlxG.height); + set("windowWidth",FlxG.width); + set("windowHeight",FlxG.height); + + set("mustHitSection", false); + set("newIcons", false); + set("swapIcons", true); + set("playDadSing", true); + set("playBFSing", true); + + if (PlayState.instance != null) + { + set("strumLineY", PlayState.instance.strumLine.y); + set("hudWidth", PlayState.instance.camHUD.width); + set("hudHeight", PlayState.instance.camHUD.height); + + set("hudZoom", PlayState.instance.camHUD.zoom); + set("camHudAngle", PlayState.instance.camHUD.angle); + } + + // callbacks + + // sprites + + Lua_helper.add_callback(lua,"doFunction", doFunction); + + Lua_helper.add_callback(lua,"changeDadCharacter", changeDadCharacter); + + Lua_helper.add_callback(lua,"changeBoyfriendCharacter", changeBoyfriendCharacter); + + Lua_helper.add_callback(lua,"changeGFCharacter", changeGFCharacter); + + Lua_helper.add_callback(lua,"changeStage", changeStage); + + Lua_helper.add_callback(lua,"changeDadCharacterBetter", changeDadCharacterBetter); + + Lua_helper.add_callback(lua,"changeBoyfriendCharacterBetter", changeBoyfriendCharacterBetter); + + Lua_helper.add_callback(lua,"changeGFCharacterBetter", changeGFCharacterBetter); + + //the auto stuff + Lua_helper.add_callback(lua,"changeBFAuto", changeBFAuto); + + //cuz sometimes i type boyfriend instead of bf + Lua_helper.add_callback(lua,"changeBoyfriendAuto", changeBFAuto); + + Lua_helper.add_callback(lua,"changeDadAuto", changeDadAuto); + + Lua_helper.add_callback(lua,"changeGFAuto", changeGFAuto); + + Lua_helper.add_callback(lua,"changeStageOffsets", changeStageOffsets); + + Lua_helper.add_callback(lua,"fileExists", function(key:String) { + if(FileSystem.exists(FileSystem.absolutePath(key))) { + return true; + } + return false; + }); + + Lua_helper.add_callback(lua, "toggleCamFilter", function(bool:Bool, camera:String = '') { + cameraFromString(camera).filtersEnabled = bool; + }); + + Lua_helper.add_callback(lua, "addLuaScript", function(luaFile:String, ?ignoreAlreadyRunning:Bool = false) { //would be dope asf. + var cervix = luaFile + ".lua"; + var doPush = false; + if(FileSystem.exists(FileSystem.absolutePath("assets/shared/"+cervix))) { + cervix = FileSystem.absolutePath("assets/shared/"+cervix); + doPush = true; + } + else if (FileSystem.exists(Paths.modFolders(cervix))) + { + cervix = Paths.modFolders(cervix); + doPush = true; + } + else { + cervix = Paths.getPreloadPath(cervix); + if(FileSystem.exists(cervix)) { + doPush = true; + } + } + + if(doPush) + { + if(!ignoreAlreadyRunning) + { + for (luaInstance in PlayState.instance.luaArray) + { + if(luaInstance.scriptName == cervix) + { + luaTrace('The script "' + cervix + '" is already running!'); + return; + } + } + } + PlayState.instance.luaArray.push(new ModchartState(cervix)); + return; + } + luaTrace("Script doesn't exist!"); + }); + Lua_helper.add_callback(lua, "removeLuaScript", function(luaFile:String, ?ignoreAlreadyRunning:Bool = false) { //would be dope asf. + var cervix = luaFile + ".lua"; + var doPush = false; + if(FileSystem.exists(FileSystem.absolutePath("assets/shared/"+cervix))) { + cervix = FileSystem.absolutePath("assets/shared/"+cervix); + doPush = true; + } + else if (FileSystem.exists(Paths.modFolders(cervix))) + { + cervix = Paths.modFolders(cervix); + doPush = true; + } + else { + cervix = Paths.getPreloadPath(cervix); + if(FileSystem.exists(cervix)) { + doPush = true; + } + } + + if(doPush) + { + if(!ignoreAlreadyRunning) + { + for (luaInstance in PlayState.instance.luaArray) + { + if(luaInstance.scriptName == cervix) + { + //luaTrace('The script "' + cervix + '" is already running!'); + + PlayState.instance.luaArray.remove(luaInstance); + return; + } + } + + for (luaInstance in PlayState.instance.Stage.luaArray) + { + if(luaInstance.scriptName == cervix) + { + //luaTrace('The script "' + cervix + '" is already running!'); + + PlayState.instance.Stage.luaArray.remove(luaInstance); + return; + } + } + } + return; + } + luaTrace("Script doesn't exist!"); + }); + + //because the regular close function isn't working for me + Lua_helper.add_callback(lua, "closeLuaScript", function(luaFile:String, ?ignoreAlreadyRunning:Bool = false) { //would be dope asf. + var cervix = luaFile + ".lua"; + var doPush = false; + if(FileSystem.exists(FileSystem.absolutePath("assets/shared/"+cervix))) { + cervix = FileSystem.absolutePath("assets/shared/"+cervix); + doPush = true; + } + else if (FileSystem.exists(Paths.modFolders(cervix))) + { + cervix = Paths.modFolders(cervix); + doPush = true; + } + else { + cervix = Paths.getPreloadPath(cervix); + if(FileSystem.exists(cervix)) { + doPush = true; + } + } + + if(doPush) + { + if(!ignoreAlreadyRunning) + { + for (luaInstance in PlayState.instance.luaArray) + { + if(luaInstance.scriptName == cervix) + { + PlayState.instance.closeLuas.push(luaInstance); + return; + } + } + + for (luaInstance in PlayState.instance.Stage.luaArray) + { + if(luaInstance.scriptName == cervix) + { + //luaTrace('The script "' + cervix + '" is already running!'); + + PlayState.instance.Stage.closeLuas.push(luaInstance); + return; + } + } + } + return; + } + luaTrace("Script doesn't exist!"); + }); + + + Lua_helper.add_callback(lua,"animationSwap", function(char:String, anim1:String, anim2:String) { + var shit = getThing(char); + + if (shit.animation.getByName(anim1) != null) + { + var oldRight = shit.animation.getByName(anim1).frames; + shit.animation.getByName(anim1).frames = shit.animation.getByName(anim2).frames; + shit.animation.getByName(anim2).frames = oldRight; + } + }); + + Lua_helper.add_callback(lua,"destroyObject", function(id:String, ?bg:Bool = false) { + if (bg) + PlayState.instance.Stage.destroyObject(PlayState.instance.Stage.swagBacks[id]); + else + { + var shit:Dynamic = getThing(id); + PlayState.instance.destroyObject(shit); + } + }); + + Lua_helper.add_callback(lua,"removeGroupObject", function(obj:String, index:Int = 0) { + var shit:Dynamic = Reflect.getProperty(getInstance(), obj); + + shit.forEach(function(spr:Dynamic) + { + if (spr.ID == index) + PlayState.instance.removeObject(spr); + }); + }); + + Lua_helper.add_callback(lua,"destroyGroupObject", function(obj:String, index:Int = 0) { + //i have no idea if this works.... it works + var shit:Dynamic = Reflect.getProperty(getInstance(), obj); + + shit.forEach(function(spr:Dynamic) + { + if (spr.ID == index) + spr.destroy(); + }); + }); + + Lua_helper.add_callback(lua, "removeLuaSprite", function(tag:String, destroy:Bool = true) { + if(!PlayState.instance.modchartSprites.exists(tag)) { + return; + } + + var pee:ModchartSprite = PlayState.instance.modchartSprites.get(tag); + if(destroy) { + pee.kill(); + } + + if(pee.wasAdded) { + getInstance().remove(pee, true); + pee.wasAdded = false; + } + + if(destroy) { + pee.destroy(); + PlayState.instance.modchartSprites.remove(tag); + } + }); + + Lua_helper.add_callback(lua, "removeLuaIcon", function(tag:String, destroy:Bool = true) { + if(!PlayState.instance.modchartIcons.exists(tag)) { + return; + } + + var pee:ModchartIcon = PlayState.instance.modchartIcons.get(tag); + if(destroy) { + pee.kill(); + } + + if(pee.wasAdded) { + getInstance().remove(pee, true); + pee.wasAdded = false; + } + + if(destroy) { + pee.destroy(); + PlayState.instance.modchartIcons.remove(tag); + } + }); + + Lua_helper.add_callback(lua, "getSongPosition", function() { + return Conductor.songPosition; + }); + + Lua_helper.add_callback(lua,"setScrollFactor", function(id:String , x:Float, y:Float, ?bg:Bool = false) { + var shit:Dynamic = getThing(id); + + shit.scrollFactor.set(x, y); + }); + + Lua_helper.add_callback(lua,"getScrollFactor", function(id:String , x:String) { + var shit:Dynamic = getThing(id); + if (x == 'x') + return shit.scrollFactor.x; + else + return shit.scrollFactor.y; + }); + + Lua_helper.add_callback(lua,"changeAnimOffset", function(id:String , x:Float, y:Float) { + getActorByName(id).addOffset(x, y); // it may say addoffset but it actually changes it instead of adding to the existing offset so this works. + }); + + Lua_helper.add_callback(lua,"checkDownscroll", function() { + return FlxG.save.data.downscroll; + }); + + Lua_helper.add_callback(lua,"getScared", function(id:String) { + PlayState.instance.Stage.swagBacks[id].getScared(); + }); + + // hud/camera + + Lua_helper.add_callback(lua,"updateHealthbar", function(dadColor:String = "", bfColor:String = ""){ + var opponent:String; + var player:String; + + if (dadColor == "") + opponent = PlayState.instance.dad.iconColor; + else + opponent = dadColor; + + if (bfColor == "") + player = PlayState.instance.boyfriend.iconColor; + else + player = bfColor; + + PlayState.instance.healthBar.createFilledBar(FlxColor.fromString('#' + opponent), FlxColor.fromString('#' + player)); + PlayState.instance.healthBar.updateBar(); + }); + + Lua_helper.add_callback(lua,"returnDominantColor", function(sprite:String, ?remove0:Bool = false){ + var shit:Dynamic = getThing(sprite); + + var coolColor = FlxColor.fromInt(CoolUtil.dominantColor(shit)); + var daColor = coolColor.toHexString(); + + if (remove0) + daColor = daColor.substring(2); + + return daColor; + }); + + + Lua_helper.add_callback(lua, "playSound", function(sound:String, ?volume:Float = 1, ?tag:String = null) { + var soundPath:Dynamic; + var isCustomSound:Bool = false; + + if (Assets.exists(Paths.sound(sound))) + soundPath = Paths.sound(sound); + else + { + if (FileSystem.exists(Paths.sound(sound))) + { + isCustomSound = true; + soundPath = Paths.sound(sound); + } + else + { + soundPath = Paths.sound('nogood'); + luaTrace('Sound not found!'); + } + } + + if(tag != null && tag.length > 0) { + tag = tag.replace('.', ''); + if(PlayState.instance.modchartSounds.exists(tag)) { + PlayState.instance.modchartSounds.get(tag).stop(); + } + + PlayState.instance.modchartSounds.set(tag, FlxG.sound.play((isCustomSound ? (Paths.currentTrackedSounds.exists(sound) ? Paths.currentTrackedSounds.get(sound) : Sound.fromFile(soundPath)): soundPath), volume, false, function() { + PlayState.instance.modchartSounds.remove(tag); + PlayState.instance.callOnLuas('onSoundFinished', [tag]); + })); + return; + } + if (isCustomSound) + FlxG.sound.play((Paths.currentTrackedSounds.exists(sound) ? Paths.currentTrackedSounds.get(sound) : Sound.fromFile(soundPath)), volume); + else + FlxG.sound.play(soundPath, volume); + }); + + Lua_helper.add_callback(lua, "stopSound", function(tag:String) { + if(tag != null && tag.length > 1 && PlayState.instance.modchartSounds.exists(tag)) { + PlayState.instance.modchartSounds.get(tag).stop(); + PlayState.instance.modchartSounds.remove(tag); + } + }); + + Lua_helper.add_callback(lua, "pauseSound", function(tag:String) { + if(tag != null && tag.length > 1 && PlayState.instance.modchartSounds.exists(tag)) { + PlayState.instance.modchartSounds.get(tag).pause(); + } + }); + Lua_helper.add_callback(lua, "resumeSound", function(tag:String) { + if(tag != null && tag.length > 1 && PlayState.instance.modchartSounds.exists(tag)) { + PlayState.instance.modchartSounds.get(tag).play(); + } + }); + Lua_helper.add_callback(lua, "soundFadeIn", function(tag:String, duration:Float, fromValue:Float = 0, toValue:Float = 1) { + if(tag == null || tag.length < 1) { + FlxG.sound.music.fadeIn(duration, fromValue, toValue); + } else if(PlayState.instance.modchartSounds.exists(tag)) { + PlayState.instance.modchartSounds.get(tag).fadeIn(duration, fromValue, toValue); + } + + }); + Lua_helper.add_callback(lua, "soundFadeOut", function(tag:String, duration:Float, toValue:Float = 0) { + if(tag == null || tag.length < 1) { + FlxG.sound.music.fadeOut(duration, toValue); + } else if(PlayState.instance.modchartSounds.exists(tag)) { + PlayState.instance.modchartSounds.get(tag).fadeOut(duration, toValue); + } + }); + Lua_helper.add_callback(lua, "soundFadeCancel", function(tag:String) { + if(tag == null || tag.length < 1) { + if(FlxG.sound.music.fadeTween != null) { + FlxG.sound.music.fadeTween.cancel(); + } + } else if(PlayState.instance.modchartSounds.exists(tag)) { + var theSound:FlxSound = PlayState.instance.modchartSounds.get(tag); + if(theSound.fadeTween != null) { + theSound.fadeTween.cancel(); + PlayState.instance.modchartSounds.remove(tag); + } + } + }); + Lua_helper.add_callback(lua, "getSoundVolume", function(tag:String) { + if(tag == null || tag.length < 1) { + if(FlxG.sound.music != null) { + return FlxG.sound.music.volume; + } + } else if(PlayState.instance.modchartSounds.exists(tag)) { + return PlayState.instance.modchartSounds.get(tag).volume; + } + return PlayState.instance.vocals.volume; + }); + Lua_helper.add_callback(lua, "setSoundVolume", function(tag:String, value:Float) { + if(tag == null || tag.length < 1) { + if(FlxG.sound.music != null) { + FlxG.sound.music.volume = value; + } + } else if(PlayState.instance.modchartSounds.exists(tag)) { + PlayState.instance.modchartSounds.get(tag).volume = value; + } + }); + Lua_helper.add_callback(lua, "getActualSoundVolume", function(tag:String) { + if(tag == null || tag.length < 1) { + if(FlxG.sound.music != null) { + return FlxG.sound.music.volume; + } + } else if(PlayState.instance.modchartSounds.exists(tag)) { + return PlayState.instance.modchartSounds.get(tag).getActualVolume(); + } + return PlayState.instance.vocals.getActualVolume(); + }); + Lua_helper.add_callback(lua, "getSoundTime", function(tag:String) { + if(tag != null && tag.length > 0 && PlayState.instance.modchartSounds.exists(tag)) { + return PlayState.instance.modchartSounds.get(tag).time; + } + return 0; + }); + Lua_helper.add_callback(lua, "setSoundTime", function(tag:String, value:Float) { + if(tag != null && tag.length > 0 && PlayState.instance.modchartSounds.exists(tag)) { + var theSound:FlxSound = PlayState.instance.modchartSounds.get(tag); + if(theSound != null) { + var wasResumed:Bool = theSound.playing; + theSound.pause(); + theSound.time = value; + if(wasResumed) theSound.play(); + } + } + }); + + /*Lua_helper.add_callback(lua, "close", function(printMessage:Bool) { + //this always closes the first one for some reason!? + if(!gonnaClose) { + if(printMessage) { + luaTrace('Stopping lua script: ' + scriptName); + } + PlayState.instance.closeLuas.push(this); + } + gonnaClose = true; + });*/ + + Lua_helper.add_callback(lua,"changeDadIcon", function(id:String) { + PlayState.instance.iconP2.useOldSystem(id); + }); + + Lua_helper.add_callback(lua,"changeBFIcon", function(id:String) { + PlayState.instance.iconP1.useOldSystem(id); + }); + + Lua_helper.add_callback(lua,"changeIcon", function(char:String, id:String) { + + trace('run dammit!'); + + if(PlayState.instance.modchartIcons.exists(char)) { + PlayState.instance.modchartIcons.get(char).changeIcon(id); + return; + } + + switch(char) + { + case 'bf' | 'boyfriend' | 'iconP1': + trace('changing bf icon'); + PlayState.instance.iconP1.changeIcon(id); + trace('changed bf icon'); + default: + trace('changing p2 icon'); + PlayState.instance.iconP2.changeIcon(id); + trace('changed p2 icon'); + } + }); + + Lua_helper.add_callback(lua,"softCountdown", function(id:String) { + PlayState.instance.softCountdown(id); + }); + + Lua_helper.add_callback(lua,"fixTrail", function(id:String) { + PlayState.instance.fixTrailShit(id); + }); + + Lua_helper.add_callback(lua,"uncacheObject", function(id:String) { + Assets.cache.clear(id); + }); + + Lua_helper.add_callback(lua,"removeCurrentTrackedAsset", function(id:String) { + Paths.currentTrackedAssets.remove(id); + }); + + Lua_helper.add_callback(lua,"resetTrail", function(id:String) { + getActorByName(id).resetTrail(); + }); + + Lua_helper.add_callback(lua,"generateNumberFromRange", function(min:Float, max:Float) { + return FlxG.random.float(min, max); + }); + + Lua_helper.add_callback(lua,"zoomingFunctionThing", function(?camSpeed:Float = 0.55, ?camZoomMult:Float = 1) { + PlayState.instance.Stage.zoomingFunctionThing(camSpeed, camZoomMult); //only works on concert stage. don't use anywhere else + }); + + Lua_helper.add_callback(lua,"exeStatic", function(?id:String, color:Int = 0) { + PlayState.instance.staticHitMiss(color); + }); + + Lua_helper.add_callback(lua,"changeDadIconNew", function(id:String) { + PlayState.instance.iconP2.changeIcon(id); + }); + + Lua_helper.add_callback(lua,"changeBFIconNew", function(id:String) { + PlayState.instance.iconP1.changeIcon(id); + }); + + Lua_helper.add_callback(lua,"stopIdle", function(id:String, bool:Bool) { + if (PlayState.instance.modchartCharacters.exists(id)) + { + PlayState.instance.modchartCharacters.get(id).stopIdle = bool; + return; + } + getActorByName(id).stopIdle = bool; + }); + + Lua_helper.add_callback(lua,"setDownscroll", function(id:Bool) { + FlxG.save.data.downscroll = id; + }); + + Lua_helper.add_callback(lua,"removeObject", function(id:String) { + var shit:Dynamic = getThing(id); + PlayState.instance.removeObject(shit); + }); + + Lua_helper.add_callback(lua,"addObject", function(id:String) { + var shit:Dynamic = getThing(id); + PlayState.instance.addObject(shit); + }); + + Lua_helper.add_callback(lua,"changeNotes", function(style:String, character:String, ?noteTypeStyle:String = "") { + switch (character) + { + case 'boyfriend' | 'bf': + PlayState.instance.notes.forEach(function(daNote:Note) + { + if (daNote.mustPress) + { + if (daNote.noteType != "") + PlayState.instance.callOnLuas('onNoteChange', [style, noteTypeStyle]); //i really don't wanna use this but I will if I have to + else + daNote.reloadNote(style, noteTypeStyle); + + if (daNote.isSustainNote) + { + if (FlxG.save.data.downscroll) + if(daNote.animation.curAnim.name.endsWith('end') && daNote.prevNote != null) + daNote.y -= daNote.prevNote.height; + else + daNote.y -= daNote.height / 2; + else + daNote.y += daNote.height/2; + } + } + }); + default: + PlayState.instance.notes.forEach(function(daNote:Note) + { + if (!daNote.mustPress) + { + if (daNote.noteType != "") + PlayState.instance.callOnLuas('onNoteChange', [style, noteTypeStyle]); //i really don't wanna use this but I will if I have to + else + daNote.reloadNote(style, noteTypeStyle); + + if (daNote.isSustainNote) + { + if (FlxG.save.data.downscroll) + if(daNote.animation.curAnim.name.endsWith('end') && daNote.prevNote != null) + daNote.y -= daNote.prevNote.height; + else + daNote.y -= daNote.height / 2; + else + daNote.y += daNote.height/2; + } + } + }); + } + }); + + Lua_helper.add_callback(lua,"changeNotes2", function(style:String, character:String, ?noteTypeStyle:String = "") { + for (i in 0...PlayState.instance.unspawnNotes.length) + { + var daNote = PlayState.instance.unspawnNotes[i]; + switch (character) + { + case 'boyfriend' | 'bf': + if (daNote.mustPress) + daNote.reloadNote(style, noteTypeStyle); + default: + if (!daNote.mustPress) + daNote.reloadNote(style, noteTypeStyle); + } + } + }); + + Lua_helper.add_callback(lua,"changeIndividualNotes", function(style:String, i:Int, ?noteTypeStyle:String = "") { + PlayState.instance.unspawnNotes[i].reloadNote(style, noteTypeStyle); + }); + + Lua_helper.add_callback(lua,"doStaticSign", function(lestatic:Int = 0, ?leopa:Bool = true) { + PlayState.instance.doStaticSign(lestatic, leopa); + }); + + Lua_helper.add_callback(lua,"characterZoom", function(id:String, zoomAmount:Float, ?isSenpai:Bool = false) { + if(PlayState.instance.modchartCharacters.exists(id)) { + var spr:Character = PlayState.instance.modchartCharacters.get(id); + spr.setZoom(zoomAmount, isSenpai); + } + else + getActorByName(id).setZoom(zoomAmount, isSenpai); + }); + + Lua_helper.add_callback(lua,"setHudAngle", function (x:Float) { + PlayState.instance.camHUD.angle = x; + }); + + Lua_helper.add_callback(lua,"setHealth", function (heal:Float) { + PlayState.instance.health = heal; + }); + + Lua_helper.add_callback(lua,"minusHealth", function (heal:Float) { + PlayState.instance.health -= heal; + }); + + Lua_helper.add_callback(lua,"setHudPosition", function (x:Int, y:Int) { + PlayState.instance.camHUD.x = x; + PlayState.instance.camHUD.y = y; + }); + + Lua_helper.add_callback(lua,"getHudX", function () { + return PlayState.instance.camHUD.x; + }); + + Lua_helper.add_callback(lua,"getHudY", function () { + return PlayState.instance.camHUD.y; + }); + + Lua_helper.add_callback(lua,"getPlayerStrumsY", function (id:Int) { + return PlayState.instance.strumLineNotes.members[id].y; + }); + + Lua_helper.add_callback(lua,"setCamPosition", function (x:Int, y:Int) { + FlxG.camera.x = x; + FlxG.camera.y = y; + }); + + Lua_helper.add_callback(lua,"shakeCam", function (i:Float, d:Float) { + FlxG.camera.shake(i, d); + }); + + Lua_helper.add_callback(lua,"shakeHUD", function (i:Float, d:Float) { + PlayState.instance.camHUD.shake(i, d); + }); + Lua_helper.add_callback(lua, "fadeCam", function (r:Int = 255,g:Int = 255,b:Int = 255, d:Float, f:Bool, ?camera:String = 'game') { + var c:FlxColor = new FlxColor(); + c.setRGB(r, g, b); + cameraFromString(camera).fade(c, d, f); + }); + + Lua_helper.add_callback(lua, "fadeCamPsych", function(camera:String, color:String, duration:Float, fadeOut:Bool = false, forced:Bool) { + var colorNum:Int = Std.parseInt(color); + if(!color.startsWith('0x')) colorNum = Std.parseInt('0xff' + color); + cameraFromString(camera).fade(colorNum, duration,fadeOut,null,forced); + }); + + Lua_helper.add_callback(lua, "flashCamPsych", function(camera:String, color:String, duration:Float, forced:Bool) { + var colorNum:Int = Std.parseInt(color); + if(!color.startsWith('0x')) colorNum = Std.parseInt('0xff' + color); + cameraFromString(camera).flash(colorNum, duration,null,forced); + }); + + Lua_helper.add_callback(lua, "cameraShake", function(camera:String, intensity:Float, duration:Float) { + cameraFromString(camera).shake(intensity, duration); + }); + + Lua_helper.add_callback(lua, "cameraFlash", function(camera:String, color:String, duration:Float,forced:Bool) { + var colorNum:Int = Std.parseInt(color); + if(!color.startsWith('0x')) colorNum = Std.parseInt('0xff' + color); + cameraFromString(camera).flash(colorNum, duration,null,forced); + }); + Lua_helper.add_callback(lua, "cameraFade", function(camera:String, color:String, duration:Float,forced:Bool) { + var colorNum:Int = Std.parseInt(color); + if(!color.startsWith('0x')) colorNum = Std.parseInt('0xff' + color); + cameraFromString(camera).fade(colorNum, duration,false,null,forced); + }); + + Lua_helper.add_callback(lua, "flashCam", function (r:Int,g:Int,b:Int, d:Float, f:Bool, ?camera:String) { + var c:FlxColor = new FlxColor(); + c.setRGB(r, g, b); + cameraFromString(camera).flash(c, d, f); + }); + + Lua_helper.add_callback(lua, "flashCamHUD", function (r:Int,g:Int,b:Int, d:Float, f:Bool) { + var c:FlxColor = new FlxColor(); + c.setRGB(r, g, b); + PlayState.instance.camHUD.flash(c, d, f); + }); + + Lua_helper.add_callback(lua, "inAndOutCam", function (d:Float, d2:Float, d3:Float, ?camera:String) + { + cameraFromString(camera).fade(FlxColor.WHITE, d, false, function() + { + new FlxTimer().start(d2, function(tmr:FlxTimer) + { + cameraFromString(camera).fade(FlxColor.WHITE, d3, true); + }); + } + ); + }); + + Lua_helper.add_callback(lua,"getCameraX", function () { + return FlxG.camera.x; + }); + + Lua_helper.add_callback(lua,"getCameraY", function () { + return FlxG.camera.y; + }); + + Lua_helper.add_callback(lua,"setCamZoom", function(zoomAmount:Float) { + FlxG.camera.zoom = zoomAmount; + }); + + Lua_helper.add_callback(lua,"addCamZoom", function(zoomAmount:Float) { + FlxG.camera.zoom += zoomAmount; + }); + + Lua_helper.add_callback(lua,"addHudZoom", function(zoomAmount:Float) { + PlayState.instance.camHUD.zoom += zoomAmount; + }); + + Lua_helper.add_callback(lua,"setDefaultCamZoom", function(zoomAmount:Float) { + luaTrace('setDefaultCamZoom is deprecated! Use setProperty("defaultCamZoom", "zoomAmount") instead.', false, true); + PlayState.instance.defaultCamZoom = zoomAmount; + }); + + Lua_helper.add_callback(lua,"setHudZoom", function(zoomAmount:Float) { + luaTrace('setHudZoom is deprecated! Use setProperty("camHUD.zoom", "zoomAmount") instead.', false, true); + PlayState.instance.camHUD.zoom = zoomAmount; + }); + + Lua_helper.add_callback(lua,"changeCamSpeed", function(camFollowSpeed:Float = 0.04) { //i know psych has that camSpeed stuff but I don't feel like changing to Psych's camera system + FlxG.camera.follow(PlayState.instance.camFollow, LOCKON, camFollowSpeed * (30 / (cast (Lib.current.getChildAt(0), Main)).getFPS())); + }); + + Lua_helper.add_callback(lua,"setCamFollow", function(x:Float, y:Float) { + PlayState.instance.camFollowIsOn = false; + PlayState.instance.camFollow.setPosition(x, y); + }); + + Lua_helper.add_callback(lua,"setDelayedCamFollow", function(time:Float,x:Float, y:Float) { + PlayState.instance.camFollowIsOn = false; + + new FlxTimer().start(time, function(tmr:FlxTimer) + { + PlayState.instance.camFollow.setPosition(x, y); + }); + }); + + Lua_helper.add_callback(lua,"sundayFilter", function(bool:Bool) { + PlayState.instance.chromOn = bool; + }); + + Lua_helper.add_callback(lua,"offCamFollow", function(id:String) { + PlayState.instance.camFollowIsOn = false; + }); + + Lua_helper.add_callback(lua,"resetCamFollow", function(id:String) { + PlayState.instance.camFollowIsOn = true; + }); + + Lua_helper.add_callback(lua,"snapCam", function(x:Float, y:Float) { + PlayState.instance.camFollowIsOn = false; + // PlayState.instance.defaultCamFollow = false; + { + var camPosition:FlxObject; + camPosition = new FlxObject(0, 0, 1, 1); + camPosition.setPosition(x, y); + FlxG.camera.focusOn(camPosition.getPosition()); + } + }); + + Lua_helper.add_callback(lua,"resetSnapCam", function(id:String) { + //The string does absolutely nothing + //PlayState.instance.defaultCamFollow = true; + }); + + Lua_helper.add_callback(lua,"resetCamEffects", function(id:String) { + PlayState.instance.camFollowIsOn = true; + }); + + Lua_helper.add_callback(lua,"stopCameraEffects", function(id:String) { //how convenient + cameraFromString(id).stopFX(); + }); + + Lua_helper.add_callback(lua,"miscCamFollow", function(camera:String, x:Float, y:Float) { + var camPosition:FlxObject; + camPosition = new FlxObject(0, 0, 1, 1); + camPosition.setPosition(x, y); + + cameraFromString(camera).follow(camPosition, LOCKON, 0.04 * (30 / (cast (Lib.current.getChildAt(0), Main)).getFPS())); + }); + + // strumline + + Lua_helper.add_callback(lua, "setStrumlineY", function(y:Float) + { + PlayState.instance.strumLine.y = y; + }); + + Lua_helper.add_callback(lua,"getArrayLength", function(obj:String) { + var shit:Dynamic = Reflect.getProperty(getInstance(), obj); + + return shit.length; + }); + + Lua_helper.add_callback(lua,"getMapLength", function(obj:String) { + var killMe:Array = obj.split('.'); + var shit:Map = Reflect.getProperty(getInstance(), obj); + + if(killMe.length > 1) + { + var coverMeInPiss:Dynamic = null; + + coverMeInPiss = Reflect.getProperty(getInstance(), killMe[0]); + + for (i in 1...killMe.length-1) { + coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); + } + + shit = Reflect.getProperty(coverMeInPiss, killMe[killMe.length-1]); + } + + var daArray:Array = []; + + for (key in shit.keys()) + daArray.push(key); + + return daArray.length; + }); + + Lua_helper.add_callback(lua,"getMapKeys", function(obj:String) { + var killMe:Array = obj.split('.'); + var shit:Map = Reflect.getProperty(getInstance(), obj); + + if(killMe.length > 1) + { + var coverMeInPiss:Dynamic = null; + + coverMeInPiss = Reflect.getProperty(getInstance(), killMe[0]); + + for (i in 1...killMe.length-1) { + coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); + } + + shit = Reflect.getProperty(coverMeInPiss, killMe[killMe.length-1]); + } + + var daArray:Array = []; + + for (key in shit.keys()) + daArray.push(key); + + return daArray; + }); + + // actors + + Lua_helper.add_callback(lua,"getRenderedNotes", function() { + return PlayState.instance.notes.length; + }); + + Lua_helper.add_callback(lua,"getRenderedNoteX", function(id:Int) { + return PlayState.instance.notes.members[id].x; + }); + + Lua_helper.add_callback(lua,"getRenderedNoteY", function(id:Int) { + return PlayState.instance.notes.members[id].y; + }); + + Lua_helper.add_callback(lua,"getRenderedNoteType", function(id:Int) { + return PlayState.instance.notes.members[id].noteData; + }); + + Lua_helper.add_callback(lua,"isSustain", function(id:Int) { + return PlayState.instance.notes.members[id].isSustainNote; + }); + + Lua_helper.add_callback(lua,"isParentSustain", function(id:Int) { + return PlayState.instance.notes.members[id].prevNote.isSustainNote; + }); + + + Lua_helper.add_callback(lua,"getRenderedNoteParentX", function(id:Int) { + return PlayState.instance.notes.members[id].prevNote.x; + }); + + Lua_helper.add_callback(lua,"getRenderedNoteParentY", function(id:Int) { + return PlayState.instance.notes.members[id].prevNote.y; + }); + + Lua_helper.add_callback(lua,"getRenderedNoteHit", function(id:Int) { + return PlayState.instance.notes.members[id].mustPress; + }); + + Lua_helper.add_callback(lua,"getRenderedNoteCalcX", function(id:Int) { + if (PlayState.instance.notes.members[id].mustPress) + return PlayState.instance.playerStrums.members[Math.floor(Math.abs(PlayState.instance.notes.members[id].noteData))].x; + return PlayState.instance.strumLineNotes.members[Math.floor(Math.abs(PlayState.instance.notes.members[id].noteData))].x; + }); + + Lua_helper.add_callback(lua,"anyNotes", function() { + return PlayState.instance.notes.members.length != 0; + }); + + Lua_helper.add_callback(lua,"getRenderedNoteStrumtime", function(id:Int) { + return PlayState.instance.notes.members[id].strumTime; + }); + + Lua_helper.add_callback(lua,"getRenderedNoteScaleX", function(id:Int) { + return PlayState.instance.notes.members[id].scale.x; + }); + + Lua_helper.add_callback(lua,"setRenderedNotePos", function(x:Float,y:Float, id:Int) { + if (PlayState.instance.notes.members[id] == null) + throw('error! you cannot set a rendered notes position when it doesnt exist! ID: ' + id); + else + { + PlayState.instance.notes.members[id].modifiedByLua = true; + PlayState.instance.notes.members[id].x = x; + PlayState.instance.notes.members[id].y = y; + } + }); + + Lua_helper.add_callback(lua,"setRenderedNoteAlpha", function(alpha:Float, id:Int) { + PlayState.instance.notes.members[id].modifiedByLua = true; + PlayState.instance.notes.members[id].alpha = alpha; + }); + + Lua_helper.add_callback(lua,"setRenderedNoteScale", function(scale:Float, id:Int) { + PlayState.instance.notes.members[id].modifiedByLua = true; + PlayState.instance.notes.members[id].setGraphicSize(Std.int(PlayState.instance.notes.members[id].width * scale)); + }); + + Lua_helper.add_callback(lua,"setRenderedNoteScale", function(scaleX:Int, scaleY:Int, id:Int) { + PlayState.instance.notes.members[id].modifiedByLua = true; + PlayState.instance.notes.members[id].setGraphicSize(scaleX,scaleY); + }); + + Lua_helper.add_callback(lua,"getRenderedNoteWidth", function(id:Int) { + return PlayState.instance.notes.members[id].width; + }); + + + Lua_helper.add_callback(lua,"setRenderedNoteAngle", function(angle:Float, id:Int) { + PlayState.instance.notes.members[id].modifiedByLua = true; + PlayState.instance.notes.members[id].angle = angle; + }); + + Lua_helper.add_callback(lua,"setActorX", function(x:Int,id:String, ?bg:Bool = false) { + var shit:Dynamic = getThing(id); + shit.x = x; + }); + + Lua_helper.add_callback(lua,"setActorScreenCenter", function(id:String, ?thing:String) { + var shit:Dynamic = getThing(id); + shit.screenCenter(); + }); + + Lua_helper.add_callback(lua,"screenCenter", function(id:String, ?thing:String) { //same thing. just for psych + var shit:Dynamic = getThing(id); + shit.screenCenter(); + }); + + Lua_helper.add_callback(lua,"setActorAccelerationX", function(x:Int,id:String) { + getActorByName(id).acceleration.x = x; + }); + + Lua_helper.add_callback(lua,"setActorDragX", function(x:Int,id:String) { + getActorByName(id).drag.x = x; + }); + + Lua_helper.add_callback(lua,"setActorVelocityX", function(x:Int,id:String, ?bg:Bool = false) { + if (bg){ + PlayState.instance.Stage.swagBacks[id].velocity.x = x; + } + else { + getActorByName(id).velocity.x = x; + } + }); + + Lua_helper.add_callback(lua,"playActorAnimation", function(id:String,anim:String,force:Bool = false,reverse:Bool = false, ?frame:Int = 0) { + if (PlayState.instance.modchartCharacters.exists(id)) + { + var shit:Character = PlayState.instance.modchartCharacters.get(id); + shit.playAnim(anim, force, reverse, frame); + } + else + getActorByName(id).playAnim(anim, force, reverse, frame); + }); + + Lua_helper.add_callback(lua,"enablePurpleMiss", function(id:String,toggle:Bool) { + getActorByName(id).doMissThing = toggle; + }); + + Lua_helper.add_callback(lua,"playBGAnimation", function(id:String,anim:String,force:Bool = false,reverse:Bool = false) { + var shit:Dynamic = getThing(id); + shit.animation.play(anim, force, reverse); + }); + + Lua_helper.add_callback(lua,"playBGAnimation2", function(id:String,anim:String,force:Bool = false,reverse:Bool = false) { + getActorByName(id).animation.play(anim, force, reverse); + }); + + Lua_helper.add_callback(lua,"setAltAnim", function(char:String, alt:String){ + switch (char) + { + case 'dad' | 'opponent': + PlayState.instance.dad.altAnim = alt; + case 'gf' | 'girlfriend': + PlayState.instance.gf.altAnim = alt; + default: + PlayState.instance.boyfriend.bfAltAnim = alt; + } + + }); + + Lua_helper.add_callback(lua,"flickerActor", function (id:FlxObject, duration:Float, interval:Float) { + FlxFlicker.flicker(id, duration, interval); + }); + + Lua_helper.add_callback(lua,"setActorAlpha", function(alpha:Float,id:String, ?bg:Bool = false) { + if (bg){ + PlayState.instance.Stage.swagBacks[id].alpha = alpha; + } + else { + getActorByName(id).alpha = alpha; + } + }); + + /*Lua_helper.add_callback(lua,"boomBoom", function(visible:Bool,id:String, id2:Int) { + getActorByName(id).members[id2].visible = visible; + });*/ + + Lua_helper.add_callback(lua,"setActorVisibility", function(alpha:Bool,id:String, ?bg:Bool = false) { + if (bg){ + PlayState.instance.Stage.swagBacks[id].visible = alpha; + } + else { + getActorByName(id).visible = alpha; + } + }); + + Lua_helper.add_callback(lua,"setActorY", function(y:Int,id:String, ?bg:Bool = false) { + if (bg){ + PlayState.instance.Stage.swagBacks[id].y = y; + } + else { + getActorByName(id).y = y; + } + }); + + Lua_helper.add_callback(lua,"setActorAccelerationY", function(y:Int,id:String) { + getActorByName(id).acceleration.y = y; + }); + + Lua_helper.add_callback(lua,"setActorDragY", function(y:Int,id:String) { + getActorByName(id).drag.y = y; + }); + + Lua_helper.add_callback(lua,"setActorVelocityY", function(y:Int,id:String) { + getActorByName(id).velocity.y = y; + }); + + Lua_helper.add_callback(lua,"setActorAngle", function(angle:Int,id:String) { + getActorByName(id).angle = angle; + }); + + Lua_helper.add_callback(lua,"setActorScale", function(scale:Float,id:String, ?bg:Bool = false) { + var shit:Dynamic = getThing(id); + shit.setGraphicSize(Std.int(shit.width * scale)); + shit.updateHitbox(); + }); + + Lua_helper.add_callback(lua, "setActorScaleXY", function(scaleX:Float, scaleY:Float, id:String) + { + getActorByName(id).setGraphicSize(Std.int(getActorByName(id).width * scaleX), Std.int(getActorByName(id).height * scaleY)); + }); + + Lua_helper.add_callback(lua, "setGraphicSize", function(obj:String, x:Int, y:Int = 0) { + if(PlayState.instance.modchartSprites.exists(obj)) { + var shit:ModchartSprite = PlayState.instance.modchartSprites.get(obj); + shit.setGraphicSize(x, y); + shit.updateHitbox(); + return; + } + + var poop:FlxSprite = Reflect.getProperty(getInstance(), obj); + if(poop != null) { + poop.setGraphicSize(x, y); + poop.updateHitbox(); + return; + } + luaTrace('Couldnt find object: ' + obj); + }); + + Lua_helper.add_callback(lua,"stopGFDance", function(stop:Bool) { + PlayState.instance.picoCutscene = stop; + }); + + Lua_helper.add_callback(lua,"isPixel", function(change:Bool) { + PlayState.isPixel = change; + }); + + Lua_helper.add_callback(lua, "setActorFlipX", function(flip:Bool, id:String) + { + getActorByName(id).flipX = flip; + }); + + + Lua_helper.add_callback(lua, "setActorFlipY", function(flip:Bool, id:String) + { + getActorByName(id).flipY = flip; + }); + + Lua_helper.add_callback(lua,"getActorWidth", function (id:String) { + return getActorByName(id).width; + }); + + Lua_helper.add_callback(lua,"getActorHeight", function (id:String) { + return getActorByName(id).height; + }); + + Lua_helper.add_callback(lua,"getActorAlpha", function(id:String) { + return getActorByName(id).alpha; + }); + + Lua_helper.add_callback(lua,"getActorAngle", function(id:String) { + return getActorByName(id).angle; + }); + + Lua_helper.add_callback(lua,"getActorX", function (id:String, ?bg:Bool = false) { + if (bg) + return PlayState.instance.Stage.swagBacks[id].x; + else + return getActorByName(id).x; + }); + + Lua_helper.add_callback(lua,"getCameraZoom", function (id:String) { + return PlayState.instance.defaultCamZoom; + }); + + Lua_helper.add_callback(lua,"getActorY", function (id:String, ?bg:Bool = false) { + if (bg) + return PlayState.instance.Stage.swagBacks[id].y; + else + return getActorByName(id).y; + }); + + Lua_helper.add_callback(lua,"getActorXMidpoint", function (id:String, ?graphic:Bool = false) { + var shit:Dynamic = getThing(id); + + if (graphic) + return shit.getGraphicMidpoint().x; + + return shit.getMidpoint().x; + }); + + Lua_helper.add_callback(lua,"getActorYMidpoint", function (id:String, ?graphic:Bool = false) { + var shit:Dynamic = getThing(id); + + if (graphic) + return shit.getGraphicMidpoint().y; + + return shit.getMidpoint().y; + }); + + Lua_helper.add_callback(lua,"setWindowPos",function(x:Int,y:Int) { + Application.current.window.x = x; + Application.current.window.y = y; + }); + + Lua_helper.add_callback(lua,"getWindowX",function() { + return Application.current.window.x; + }); + + Lua_helper.add_callback(lua,"getWindowY",function() { + return Application.current.window.y; + }); + + Lua_helper.add_callback(lua,"resizeWindow",function(Width:Int,Height:Int) { + Application.current.window.resize(Width,Height); + }); + + Lua_helper.add_callback(lua,"getScreenWidth",function() { + return Application.current.window.display.currentMode.width; + }); + + Lua_helper.add_callback(lua,"getScreenHeight",function() { + return Application.current.window.display.currentMode.height; + }); + + Lua_helper.add_callback(lua,"getWindowWidth",function() { + return Application.current.window.width; + }); + + Lua_helper.add_callback(lua,"getWindowHeight",function() { + return Application.current.window.height; + }); + + + // tweens + + Lua_helper.add_callback(lua,"tweenCameraPos", function(toX:Int, toY:Int, time:Float, onComplete:String) { + FlxTween.tween(FlxG.camera, {x: toX, y: toY}, time, {ease: FlxEase.linear, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenCameraAngle", function(toAngle:Float, time:Float, onComplete:String) { + FlxTween.tween(FlxG.camera, {angle:toAngle}, time, {ease: FlxEase.linear, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenCameraZoom", function(toZoom:Float, time:Float, onComplete:String) { + FlxTween.tween(FlxG.camera, {zoom:toZoom}, time, {ease: FlxEase.linear, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenHudPos", function(toX:Int, toY:Int, time:Float, onComplete:String) { + FlxTween.tween(PlayState.instance.camHUD, {x: toX, y: toY}, time, {ease: FlxEase.linear, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenHudAngle", function(toAngle:Float, time:Float, onComplete:String) { + FlxTween.tween(PlayState.instance.camHUD, {angle:toAngle}, time, {ease: FlxEase.linear, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenHudZoom", function(toZoom:Float, time:Float, onComplete:String) { + FlxTween.tween(PlayState.instance.camHUD, {zoom:toZoom}, time, {ease: FlxEase.linear, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenPos", function(id:String, toX:Int, toY:Int, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {x: toX, y: toY}, time, {ease: FlxEase.linear, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenPosQuad", function(id:String, toX:Int, toY:Int, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {x: toX, y: toY}, time, {ease: FlxEase.quadInOut, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenPosXAngle", function(id:String, toX:Int, toAngle:Float, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {x: toX, angle: toAngle}, time, {ease: FlxEase.linear, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenPosYAngle", function(id:String, toY:Int, toAngle:Float, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {y: toY, angle: toAngle}, time, {ease: FlxEase.linear, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenAngle", function(id:String, toAngle:Int, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {angle: toAngle}, time, {ease: FlxEase.linear, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenCameraPosOut", function(toX:Int, toY:Int, time:Float, onComplete:String) { + FlxTween.tween(FlxG.camera, {x: toX, y: toY}, time, {ease: FlxEase.cubeOut, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenCameraAngleOut", function(toAngle:Float, time:Float, onComplete:String) { + FlxTween.tween(FlxG.camera, {angle:toAngle}, time, {ease: FlxEase.cubeOut, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenCameraZoomOut", function(toZoom:Float, time:Float, ease:String, onComplete:String) { + FlxTween.tween(FlxG.camera, {zoom:toZoom}, time, {ease: getFlxEaseByString(ease), onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenHudPosOut", function(toX:Int, toY:Int, time:Float, onComplete:String) { + FlxTween.tween(PlayState.instance.camHUD, {x: toX, y: toY}, time, {ease: FlxEase.cubeOut, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenHudAngleOut", function(toAngle:Float, time:Float, onComplete:String) { + FlxTween.tween(PlayState.instance.camHUD, {angle:toAngle}, time, {ease: FlxEase.cubeOut, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenHudZoomOut", function(toZoom:Float, time:Float, onComplete:String) { + FlxTween.tween(PlayState.instance.camHUD, {zoom:toZoom}, time, {ease: FlxEase.cubeOut, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenPosOut", function(id:String, toX:Int, toY:Int, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {x: toX, y: toY}, time, {ease: FlxEase.cubeOut, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenPosXAngleOut", function(id:String, toX:Int, toAngle:Float, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {x: toX, angle: toAngle}, time, {ease: FlxEase.cubeOut, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenPosYAngleOut", function(id:String, toY:Int, toAngle:Float, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {y: toY, angle: toAngle}, time, {ease: FlxEase.cubeOut, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenAngleOut", function(id:String, toAngle:Int, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {angle: toAngle}, time, {ease: FlxEase.cubeOut, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenCameraPosIn", function(toX:Int, toY:Int, time:Float, onComplete:String) { + FlxTween.tween(FlxG.camera, {x: toX, y: toY}, time, {ease: FlxEase.cubeIn, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenCameraAngleIn", function(toAngle:Float, time:Float, onComplete:String) { + FlxTween.tween(FlxG.camera, {angle:toAngle}, time, {ease: FlxEase.cubeIn, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenCameraZoomIn", function(toZoom:Float, time:Float, ease:String, onComplete:String) { + FlxTween.tween(FlxG.camera, {zoom:toZoom}, time, {ease: getFlxEaseByString(ease), onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenHudPosIn", function(toX:Int, toY:Int, time:Float, onComplete:String) { + FlxTween.tween(PlayState.instance.camHUD, {x: toX, y: toY}, time, {ease: FlxEase.cubeIn, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenHudAngleIn", function(toAngle:Float, time:Float, onComplete:String) { + FlxTween.tween(PlayState.instance.camHUD, {angle:toAngle}, time, {ease: FlxEase.cubeIn, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenHudZoomIn", function(toZoom:Float, time:Float, onComplete:String) { + FlxTween.tween(PlayState.instance.camHUD, {zoom:toZoom}, time, {ease: FlxEase.cubeIn, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenPosIn", function(id:String, toX:Int, toY:Int, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {x: toX, y: toY}, time, {ease: FlxEase.cubeIn, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenPosXAngleIn", function(id:String, toX:Int, toAngle:Float, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {x: toX, angle: toAngle}, time, {ease: FlxEase.cubeIn, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenPosYAngleIn", function(id:String, toY:Int, toAngle:Float, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {y: toY, angle: toAngle}, time, {ease: FlxEase.cubeIn, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenAngleIn", function(id:String, toAngle:Int, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {angle: toAngle}, time, {ease: FlxEase.cubeIn, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenFadeIn", function(id:String, toAlpha:Float, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {alpha: toAlpha}, time, {ease: FlxEase.circIn, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenFadeInBG", function(id:String, toAlpha:Float, time:Float, onComplete:String) { + FlxTween.tween(PlayState.instance.Stage.swagBacks[id], {alpha: toAlpha}, time, {ease: FlxEase.circIn, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenFadeOut", function(id:String, toAlpha:Float, time:Float, ease:String, onComplete:String) { + FlxTween.tween(getActorByName(id), {alpha: toAlpha}, time, {ease: getFlxEaseByString(ease), onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenFadeOutBG", function(id:String, toAlpha:Float, time:Float, onComplete:String) { + FlxTween.tween(PlayState.instance.Stage.swagBacks[id], {alpha: toAlpha}, time, {ease: FlxEase.circOut, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenFadeOutOneShot", function(id:String, toAlpha:Float, time:Float) { + FlxTween.tween(getActorByName(id), {alpha: toAlpha}, time, {type: FlxTweenType.ONESHOT}); + }); + + Lua_helper.add_callback(lua,"tweenColor", function(id:String, time:Float, initColor:FlxColor, finalColor:FlxColor) { + var shit:Dynamic = getThing(id); + FlxTween.color(shit, time, initColor, finalColor); + }); + + Lua_helper.add_callback(lua, "RGBColor", function (r:Int,g:Int,b:Int, alpha:Int = 255) { + return FlxColor.fromRGB(r, g, b, alpha); + }); + + Lua_helper.add_callback(lua,"updateHealthbar", function(dadColor:String = "", bfColor:String = ""){ + var opponent:String; + var player:String; + + if (dadColor == "") + opponent = PlayState.instance.dad.iconColor; + else + opponent = dadColor; + + if (bfColor == "") + player = PlayState.instance.boyfriend.iconColor; + else + player = bfColor; + + PlayState.instance.healthBar.createFilledBar(FlxColor.fromString('#' + opponent), FlxColor.fromString('#' + player)); + PlayState.instance.healthBar.updateBar(); + }); + + Lua_helper.add_callback(lua, "getStageXOffsets", function (char:String, value:String) { + switch (char) + { + case 'boyfriend' | 'bf': + return (value == 'y' ? PlayState.instance.Stage.bfYOffset : PlayState.instance.Stage.bfXOffset); + case 'gf': + return (value == 'y' ? PlayState.instance.Stage.gfYOffset : PlayState.instance.Stage.gfXOffset); + default: + return (value == 'y' ? PlayState.instance.Stage.dadYOffset : PlayState.instance.Stage.dadXOffset); + } + }); + + Lua_helper.add_callback(lua,"changeHue", function(id:String, hue:Int) { + var newShader:ColorSwap = new ColorSwap(); + var shit:Dynamic = getThing(id); + shit.shader = newShader.shader; + newShader.hue = hue / 360; + }); + + Lua_helper.add_callback(lua,"changeGroupHue", function(obj:String, hue:Int) { + var shit:Dynamic = Reflect.getProperty(getInstance(), obj); + + shit.forEach(function(thing:Dynamic) + { + var newShader:ColorSwap = new ColorSwap(); + newShader.hue = hue / 360; + thing.shader = newShader.shader; + }); + }); + + Lua_helper.add_callback(lua,"changeGroupMemberHue", function(obj:String, index:Int, hue:Int) { + var shit:Dynamic = Reflect.getProperty(getInstance(), obj)[index]; + + if(Std.isOfType(Reflect.getProperty(getInstance(), obj), FlxTypedGroup)) + shit = Reflect.getProperty(getInstance(), obj).members[index]; + + var newShader:ColorSwap = new ColorSwap(); + newShader.hue = hue / 360; + shit.shader = newShader.shader; + + }); + + Lua_helper.add_callback(lua,"playStrumAnim", function(isDad:Bool, id:Int, ?time:Float = 0.15) { + PlayState.instance.StrumPlayAnim(isDad, id, time); + }); + + //a bunch of psych stuff + Lua_helper.add_callback(lua,"tweenAnglePsych", function(id:String, toAngle:Int, time:Float, ease:String, onComplete:String, ?bg:Bool = false) { + var shit:Dynamic = getThing(id); + FlxTween.tween(shit, {angle: toAngle}, time, {ease: getFlxEaseByString(ease), onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenXPsych", function(id:String, toX:Int, time:Float, ease:String, onComplete:String, ?bg:Bool = false) { + var shit:Dynamic = getThing(id); + FlxTween.tween(shit, {x: toX}, time, {ease: getFlxEaseByString(ease), onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenYPsych", function(id:String, toY:Int, time:Float, ease:String, onComplete:String, ?bg:Bool = false) { + var shit:Dynamic = getThing(id); + FlxTween.tween(shit, {y: toY}, time, {ease: getFlxEaseByString(ease), onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenZoomPsych", function(id:String, toZoom:Int, time:Float, ease:String, onComplete:String, ?bg:Bool = false) { + var shit:Dynamic = getThing(id); + FlxTween.tween(shit, {zoom: toZoom}, time, {ease: getFlxEaseByString(ease), onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenScale", function(id:String, scale:Float, time:Float, ease:String, onComplete:String, ?bg:Bool = false) { + var shit:Dynamic = getThing(id); + FlxTween.tween(shit, {"scale.x": scale, "scale.y": scale}, time, {ease: getFlxEaseByString(ease), onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenScaleXY", function(id:String, scaleX:Float, scaleY:Float, time:Float, ease:String, onComplete:String, ?bg:Bool = false) { + var shit:Dynamic = getThing(id); + FlxTween.tween(shit, {"scale.x": scaleX, "scale.y": scaleY}, time, {ease: getFlxEaseByString(ease), onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenAlpha", function(id:String, toAlpha:Float, time:Float, ease:String, onComplete:String) { + var shit:Dynamic = getThing(id); + FlxTween.tween(shit, {alpha: toAlpha}, time, {ease: getFlxEaseByString(ease), onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua, "doTweenX", function(tag:String, vars:String, value:Dynamic, duration:Float, ease:String) { + var penisExam:Dynamic = getThing(vars); + cancelTween(tag); + if(penisExam != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(penisExam, {x: value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } else { + luaTrace('Couldnt find object: ' + vars); + } + }); + + Lua_helper.add_callback(lua, "doTweenY", function(tag:String, vars:String, value:Dynamic, duration:Float, ease:String) { + var penisExam:Dynamic = getThing(vars); + cancelTween(tag); + if(penisExam != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(penisExam, {y: value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } else { + luaTrace('Couldnt find object: ' + vars); + } + }); + Lua_helper.add_callback(lua, "doTweenAngle", function(tag:String, vars:String, value:Dynamic, duration:Float, ease:String) { + var penisExam:Dynamic = getThing(vars); + cancelTween(tag); + if(penisExam != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(penisExam, {angle: value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } else { + luaTrace('Couldnt find object: ' + vars); + } + }); + + Lua_helper.add_callback(lua, "doTweenScale", function(tag:String, vars:String, value:Dynamic, value2:Dynamic, duration:Float, ease:String) { + var penisExam:Dynamic = getThing(vars); + cancelTween(tag); + cancelTween(tag+'Y'); + if(penisExam != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(penisExam, {"scale.x": value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + + PlayState.instance.modchartTweens.set(tag+'Y', FlxTween.tween(penisExam, {"scale.y": value2}, duration, {ease: getFlxEaseByString(ease)})); + } else { + luaTrace('Couldnt find object: ' + vars); + } + }); + + Lua_helper.add_callback(lua, "doTweenScaleX", function(tag:String, vars:String, value:Dynamic, duration:Float, ease:String) { + var penisExam:Dynamic = getThing(vars); + cancelTween(tag); + if(penisExam != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(penisExam, {"scale.x": value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } else { + luaTrace('Couldnt find object: ' + vars); + } + }); + + Lua_helper.add_callback(lua, "doTweenScaleY", function(tag:String, vars:String, value:Dynamic, duration:Float, ease:String) { + var penisExam:Dynamic = getThing(vars); + cancelTween(tag); + if(penisExam != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(penisExam, {"scale.y": value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } else { + luaTrace('Couldnt find object: ' + vars); + } + }); + + + Lua_helper.add_callback(lua, "doTweenAlpha", function(tag:String, vars:String, value:Dynamic, duration:Float, ease:String) { + var penisExam:Dynamic = getThing(vars); + cancelTween(tag); + if(penisExam != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(penisExam, {alpha: value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } else { + luaTrace('Couldnt find object: ' + vars); + } + }); + Lua_helper.add_callback(lua, "doTweenZoom", function(tag:String, vars:String, value:Dynamic, duration:Float, ease:String) { + var penisExam:Dynamic = getThing(vars); + cancelTween(tag); + if(penisExam != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(penisExam, {zoom: value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } else { + luaTrace('Couldnt find object: ' + vars); + } + }); + Lua_helper.add_callback(lua, "doTweenColor", function(tag:String, vars:String, targetColor:String, duration:Float, ease:String) { + var penisExam:Dynamic = getThing(vars); + cancelTween(tag); + if(penisExam != null) { + var color:Int = Std.parseInt(targetColor); + if(!targetColor.startsWith('0x')) color = Std.parseInt('0xff' + targetColor); + + var curColor:FlxColor = penisExam.color; + curColor.alphaFloat = penisExam.alpha; + PlayState.instance.modchartTweens.set(tag, FlxTween.color(penisExam, duration, curColor, color, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.modchartTweens.remove(tag); + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + } + })); + } else { + luaTrace('Couldnt find object: ' + vars); + } + }); + + Lua_helper.add_callback(lua, "startCountdown", function(variable:String) { + PlayState.instance.startCountdown(); + }); + + Lua_helper.add_callback(lua, "startSong", function(variable:String) { + PlayState.instance.startSong(); + }); + + Lua_helper.add_callback(lua, "playCutscene", function(video:String, ?unskippable:Bool = false) { + PlayState.instance.playCutscene(video, unskippable); + }); + + Lua_helper.add_callback(lua, "endSong", function(hmm:String) { + PlayState.instance.KillNotes(); + PlayState.instance.endSong(); + }); + + //idk if I wanna add events. alright I added the ones that are usable without that much tinkering. + Lua_helper.add_callback(lua, "triggerEvent", function(name:String, arg1:Dynamic, arg2:Dynamic) { + if (name == 'Change Character') + { + switch (arg1) + { + case 0: changeBFAuto(arg2); + case 1: changeDadAuto(arg2); + case 2: changeGFAuto(arg2); + } + + return; + } + + var value1:String = arg1; + var value2:String = arg2; + PlayState.instance.triggerEventNote(name, value1, value2); + }); + + Lua_helper.add_callback(lua, "getPropertyPsych", function(variable:String) { + var killMe:Array = variable.split('.'); + if(killMe.length > 1) + { + var coverMeInPiss:Dynamic = null; + if(PlayState.instance.modchartSprites.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartSprites.get(killMe[0]); + else if(PlayState.instance.modchartIcons.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartIcons.get(killMe[0]); + else if(PlayState.instance.modchartCharacters.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartCharacters.get(killMe[0]); + else if(PlayState.instance.modchartTexts.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartTexts.get(killMe[0]); + else if(PlayState.instance.Stage.swagBacks.exists(killMe[0])) + coverMeInPiss = PlayState.instance.Stage.swagBacks.get(killMe[0]); + else + coverMeInPiss = Reflect.getProperty(getInstance(), killMe[0]); + + for (i in 1...killMe.length-1) { + coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); + } + return Reflect.getProperty(coverMeInPiss, killMe[killMe.length-1]); + } + return Reflect.getProperty(getInstance(), variable); + }); + + Lua_helper.add_callback(lua, "setPropertyPsych", function(variable:String, value:Dynamic) { + var killMe:Array = variable.split('.'); + if(killMe.length > 1) { + var coverMeInPiss:Dynamic = null; + if(PlayState.instance.modchartSprites.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartSprites.get(killMe[0]); + else if(PlayState.instance.modchartTexts.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartTexts.get(killMe[0]); + else if(PlayState.instance.modchartIcons.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartIcons.get(killMe[0]); + else if(PlayState.instance.modchartCharacters.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartCharacters.get(killMe[0]); + else if(PlayState.instance.Stage.swagBacks.exists(killMe[0])) + coverMeInPiss = PlayState.instance.Stage.swagBacks.get(killMe[0]); + else + coverMeInPiss = Reflect.getProperty(getInstance(), killMe[0]); + + for (i in 1...killMe.length-1) { + coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); + } + return Reflect.setProperty(coverMeInPiss, killMe[killMe.length-1], value); + } + return Reflect.setProperty(getInstance(), variable, value); + }); + + //i have no idea why I added the Psych in the first place + Lua_helper.add_callback(lua, "getProperty", function(variable:String) { + var killMe:Array = variable.split('.'); + if(killMe.length > 1) + { + var coverMeInPiss:Dynamic = null; + if(PlayState.instance.modchartSprites.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartSprites.get(killMe[0]); + else if(PlayState.instance.modchartIcons.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartIcons.get(killMe[0]); + else if(PlayState.instance.modchartCharacters.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartCharacters.get(killMe[0]); + else if(PlayState.instance.modchartTexts.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartTexts.get(killMe[0]); + else if(PlayState.instance.Stage.swagBacks.exists(killMe[0])) + coverMeInPiss = PlayState.instance.Stage.swagBacks.get(killMe[0]); + else + coverMeInPiss = Reflect.getProperty(getInstance(), killMe[0]); + + for (i in 1...killMe.length-1) { + coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); + } + return Reflect.getProperty(coverMeInPiss, killMe[killMe.length-1]); + } + return Reflect.getProperty(getInstance(), variable); + }); + + Lua_helper.add_callback(lua, "setProperty", function(variable:String, value:Dynamic) { + var killMe:Array = variable.split('.'); + if(killMe.length > 1) { + var coverMeInPiss:Dynamic = null; + if(PlayState.instance.modchartSprites.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartSprites.get(killMe[0]); + else if(PlayState.instance.modchartTexts.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartTexts.get(killMe[0]); + else if(PlayState.instance.modchartIcons.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartIcons.get(killMe[0]); + else if(PlayState.instance.modchartCharacters.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartCharacters.get(killMe[0]); + else if(PlayState.instance.Stage.swagBacks.exists(killMe[0])) + coverMeInPiss = PlayState.instance.Stage.swagBacks.get(killMe[0]); + else + coverMeInPiss = Reflect.getProperty(getInstance(), killMe[0]); + + for (i in 1...killMe.length-1) { + coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); + } + return Reflect.setProperty(coverMeInPiss, killMe[killMe.length-1], value); + } + return Reflect.setProperty(getInstance(), variable, value); + }); + + Lua_helper.add_callback(lua, "doGroupTweenY", function(tag:String, obj:String, index:Int, value:Dynamic, duration:Float, ease:String) { + //if this works i might use this over the noteTween stuff. though realistically there aren't many other flxgroups. + cancelTween(tag); + var shit:Dynamic = Reflect.getProperty(getInstance(), obj); + var testicle:Dynamic = null; + + shit.forEach(function(spr:Dynamic) + { + if (spr.ID == index) + testicle = spr; + }); + + if(testicle != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(testicle, {y: value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } + }); + + Lua_helper.add_callback(lua, "getPropertyFromGroup", function(obj:String, index:Int, variable:Dynamic) { + if (PlayState.instance.Stage.swagGroup.exists(obj)) + { + var shit = PlayState.instance.Stage.swagGroup.get(obj); + + if(Std.isOfType(shit, FlxTypedGroup)) { + return getGroupStuff(shit.members[index], variable); + } + } + + if(Std.isOfType(Reflect.getProperty(getInstance(), obj), FlxTypedGroup)) { + return getGroupStuff(Reflect.getProperty(getInstance(), obj).members[index], variable); + } + + var leArray:Dynamic = Reflect.getProperty(getInstance(), obj); + var killMe:Array = obj.split('.'); + + if (killMe.length > 1) //all this just so I can get a character's camera position + { + var coverMeInPiss:Dynamic = null; + coverMeInPiss = Reflect.getProperty(getInstance(), killMe[0]); + + for (i in 1...killMe.length-1) { + coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); + } + + leArray = Reflect.getProperty(coverMeInPiss, killMe[killMe.length-1]); + } + + if(leArray != null) { + if(Type.typeof(variable) == ValueType.TInt) { + return leArray[variable]; + } + + leArray = Reflect.getProperty(getInstance(), obj)[index]; + return getGroupStuff(leArray, variable); + } + luaTrace("Object #" + index + " from group: " + obj + " doesn't exist!"); + return null; + }); + + Lua_helper.add_callback(lua, "setPropertyFromGroup", function(obj:String, index:Int, variable:Dynamic, value:Dynamic) { + + if (PlayState.instance.Stage.swagGroup.exists(obj)) + { + trace('swagGroup found'); + var shit = PlayState.instance.Stage.swagGroup.get(obj); + + if(Std.isOfType(shit, FlxTypedGroup)) { + trace('is a FlxTypedGroup'); + return setGroupStuff(shit.members[index], variable, value); + } + } + + if(Std.isOfType(Reflect.getProperty(getInstance(), obj), FlxTypedGroup)) { + setGroupStuff(Reflect.getProperty(getInstance(), obj).members[index], variable, value); + return; + } + + var leArray:Dynamic = Reflect.getProperty(getInstance(), obj)[index]; + if(leArray != null) { + if(Type.typeof(variable) == ValueType.TInt) { + leArray[variable] = value; + return; + } + setGroupStuff(leArray, variable, value); + } + }); + + Lua_helper.add_callback(lua, "getPropertyFromClass", function(classVar:String, variable:String) { + var killMe:Array = variable.split('.'); + if(killMe.length > 1) { + var coverMeInPiss:Dynamic = Reflect.getProperty(Type.resolveClass(classVar), killMe[0]); + for (i in 1...killMe.length-1) { + coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); + } + return Reflect.getProperty(coverMeInPiss, killMe[killMe.length-1]); + } + return Reflect.getProperty(Type.resolveClass(classVar), variable); + }); + Lua_helper.add_callback(lua, "setPropertyFromClass", function(classVar:String, variable:String, value:Dynamic) { + var killMe:Array = variable.split('.'); + if(killMe.length > 1) { + var coverMeInPiss:Dynamic = Reflect.getProperty(Type.resolveClass(classVar), killMe[0]); + for (i in 1...killMe.length-1) { + coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); + } + return Reflect.setProperty(coverMeInPiss, killMe[killMe.length-1], value); + } + return Reflect.setProperty(Type.resolveClass(classVar), variable, value); + }); + + Lua_helper.add_callback(lua, "arrayContains", function(obj:String, value:Dynamic) { + var leArray:Dynamic = Reflect.getProperty(getInstance(), obj); + + if (leArray.contains(value)) + return true; + + return false; + }); + + Lua_helper.add_callback(lua, "debugPrint", function(text1:Dynamic = '', text2:Dynamic = '', text3:Dynamic = '', text4:Dynamic = '', text5:Dynamic = '') { + if (text1 == null) text1 = ''; + if (text2 == null) text2 = ''; + if (text3 == null) text3 = ''; + if (text4 == null) text4 = ''; + if (text5 == null) text5 = ''; + luaTrace('' + text1 + text2 + text3 + text4 + text5, true, false); + }); + + Lua_helper.add_callback(lua, "setObjectCamera", function(obj:String, camera:String = '', ?index:Int = null) { + if (PlayState.instance.modchartSprites.exists(obj)) { + PlayState.instance.modchartSprites.get(obj).cameras = [cameraFromString(camera)]; + return true; + } + else if(PlayState.instance.modchartTexts.exists(obj)) { + PlayState.instance.modchartTexts.get(obj).cameras = [cameraFromString(camera)]; + return true; + } + else if (PlayState.instance.modchartIcons.exists(obj)) { + PlayState.instance.modchartIcons.get(obj).cameras = [cameraFromString(camera)]; + return true; + } + else if (PlayState.instance.Stage.swagBacks.exists(obj)) { + PlayState.instance.Stage.setObjectCamera(obj, camera); + return true; + } + else if (Stage.instance.swagBacks.exists(obj)) { + Stage.instance.setObjectCamera(obj, camera); + return true; + } + else + { + var object:Dynamic = Reflect.getProperty(getInstance(), obj); + if(object != null) { + + if (index != null) + object[index].cameras = [cameraFromString(camera)]; + else + object.cameras = [cameraFromString(camera)]; + + return true; + } + } + luaTrace("Object " + obj + " doesn't exist!"); + return false; + }); + + Lua_helper.add_callback(lua, "getRandomInt", function(min:Int, max:Int = FlxMath.MAX_VALUE_INT, exclude:String = '') { + var excludeArray:Array = exclude.split(','); + var toExclude:Array = []; + for (i in 0...excludeArray.length) + { + toExclude.push(Std.parseInt(excludeArray[i].trim())); + } + return FlxG.random.int(min, max, toExclude); + }); + Lua_helper.add_callback(lua, "getRandomFloat", function(min:Float, max:Float = 1, exclude:String = '') { + var excludeArray:Array = exclude.split(','); + var toExclude:Array = []; + for (i in 0...excludeArray.length) + { + toExclude.push(Std.parseFloat(excludeArray[i].trim())); + } + return FlxG.random.float(min, max, toExclude); + }); + Lua_helper.add_callback(lua, "getRandomBool", function(chance:Float = 50) { + return FlxG.random.bool(chance); + }); + + Lua_helper.add_callback(lua, "setBlendMode", function(obj:String, blend:String = '') { + var shit:Dynamic = getThing(obj); + if(shit != null) { + shit.blend = blendModeFromString(blend); + return true; + } + luaTrace("Object " + obj + " doesn't exist!"); + return false; + }); + + Lua_helper.add_callback(lua, "keyJustPressed", function(name:String) { + var key:Bool = false; + switch(name) { + case 'left': key = PlayState.instance.getControl('LEFT_P'); + case 'down': key = PlayState.instance.getControl('DOWN_P'); + case 'up': key = PlayState.instance.getControl('UP_P'); + case 'right': key = PlayState.instance.getControl('RIGHT_P'); + case 'accept': key = PlayState.instance.getControl('ACCEPT'); + case 'back': key = PlayState.instance.getControl('BACK'); + case 'pause': key = PlayState.instance.getControl('PAUSE'); + case 'reset': key = PlayState.instance.getControl('RESET'); + case 'space': key = FlxG.keys.justPressed.SPACE;//an extra key for convinience + } + return key; + }); + + Lua_helper.add_callback(lua, "keyPressed", function(name:String) { + var key:Bool = false; + switch(name) { + case 'left': key = PlayState.instance.getControl('LEFT'); + case 'down': key = PlayState.instance.getControl('DOWN'); + case 'up': key = PlayState.instance.getControl('UP'); + case 'right': key = PlayState.instance.getControl('RIGHT'); + case 'space': key = FlxG.keys.pressed.SPACE;//an extra key for convinience + } + return key; + }); + + Lua_helper.add_callback(lua, "keyReleased", function(name:String) { + var key:Bool = false; + switch(name) { + case 'left': key = PlayState.instance.getControl('LEFT_R'); + case 'down': key = PlayState.instance.getControl('DOWN_R'); + case 'up': key = PlayState.instance.getControl('UP_R'); + case 'right': key = PlayState.instance.getControl('RIGHT_R'); + case 'space': key = FlxG.keys.justReleased.SPACE;//an extra key for convinience + } + return key; + }); + + Lua_helper.add_callback(lua, "mouseClicked", function(button:String) { + var boobs = FlxG.mouse.justPressed; + switch(button){ + case 'middle': + boobs = FlxG.mouse.justPressedMiddle; + case 'right': + boobs = FlxG.mouse.justPressedRight; + } + + + return boobs; + }); + Lua_helper.add_callback(lua, "mousePressed", function(button:String) { + var boobs = FlxG.mouse.pressed; + switch(button){ + case 'middle': + boobs = FlxG.mouse.pressedMiddle; + case 'right': + boobs = FlxG.mouse.pressedRight; + } + return boobs; + }); + Lua_helper.add_callback(lua, "mouseReleased", function(button:String) { + var boobs = FlxG.mouse.justReleased; + switch(button){ + case 'middle': + boobs = FlxG.mouse.justReleasedMiddle; + case 'right': + boobs = FlxG.mouse.justReleasedRight; + } + return boobs; + }); + + Lua_helper.add_callback(lua, "runTimer", function(tag:String, time:Float = 1, loops:Int = 1) { + cancelTimer(tag); + PlayState.instance.modchartTimers.set(tag, new FlxTimer().start(time, function(tmr:FlxTimer) { + if(tmr.finished) { + PlayState.instance.modchartTimers.remove(tag); + } + PlayState.instance.callOnLuas('onTimerCompleted', [tag, tmr.loops, tmr.loopsLeft]); + //trace('Timer Completed: ' + tag); + }, loops)); + }); + + Lua_helper.add_callback(lua, "cancelTimer", function(tag:String) { + cancelTimer(tag); + }); + + Lua_helper.add_callback(lua, "cancelTween", function(tag:String) { + cancelTween(tag); + }); + + //used for testing. might as well leave it here. + Lua_helper.add_callback(lua, "indexOf", function(tag:String, thing:String, ?last:Bool) { + if (last) + return tag.lastIndexOf(thing); + + return tag.indexOf(thing); + }); + + Lua_helper.add_callback(lua, "addCharacterToList", function(name:String, type:String) { + var charType:Int = 0; + switch(type.toLowerCase()) { + case 'dad': charType = 1; + case 'gf' | 'girlfriend': charType = 2; + } + PlayState.preloadChar = new Character(0, 0, name); + }); + + Lua_helper.add_callback(lua, "precacheSound", function(name:String) { + return name; //lol + }); + + Lua_helper.add_callback(lua, "precacheImage", function(name:String) { + return name; //lol + }); + + Lua_helper.add_callback(lua, "makeLuaSprite", function(tag:String, image:String, x:Float, y:Float, ?antialiasing:Bool = true) { + tag = tag.replace('.', ''); + resetSpriteTag(tag); + var leSprite:ModchartSprite = new ModchartSprite(x, y); + if(image != null && image.length > 0) { + var rawPic:Dynamic; + + if (!Paths.currentTrackedAssets.exists(image)) + Paths.cacheImage(image); + + rawPic = Paths.currentTrackedAssets.get(image); + + leSprite.loadGraphic(rawPic); + } + leSprite.antialiasing = antialiasing; + PlayState.instance.modchartSprites.set(tag, leSprite); + leSprite.active = true; + }); + + Lua_helper.add_callback(lua, "makeAnimatedLuaSprite", function(tag:String, image:String, x:Float, y:Float,spriteType:String="sparrow", width:Int = 0, height:Int = 0) { + tag = tag.replace('.', ''); + resetSpriteTag(tag); + var leSprite:ModchartSprite = new ModchartSprite(x, y); + + switch(spriteType.toLowerCase()){ + + case "texture" | "textureatlas"|"tex": + leSprite.frames = AtlasFrameMaker.construct(image); + + case "packer" |"packeratlas"|"pac": + leSprite.frames = Paths.getPackerAtlas(image); + case "xmlless": //for the ones like the pixel notes and stuff. + { + var rawPic:Dynamic; + + if (!Paths.currentTrackedAssets.exists(image)) + Paths.cacheImage(image); + + rawPic = Paths.currentTrackedAssets.get(image); + leSprite.loadGraphic(rawPic, true, width, height); + } + default: + { + var rawPic:Dynamic; + var rawXml:String; + + if (!Paths.currentTrackedAssets.exists(image)) + Paths.cacheImage(image); + + rawPic = Paths.currentTrackedAssets.get(image); + + if (FileSystem.exists(FileSystem.absolutePath("assets/shared/images/"+image+".xml"))) + rawXml = File.getContent(FileSystem.absolutePath("assets/shared/images/"+image+".xml")); + else + rawXml = File.getContent(Paths.xmlNew('images/' + image)); + + leSprite.frames = FlxAtlasFrames.fromSparrow(rawPic,rawXml); + } + } + + PlayState.instance.modchartSprites.set(tag, leSprite); + }); + + Lua_helper.add_callback(lua, "makeAnimatedLuaSprite2", function(tag:String, image:String,width:Int, height:Int) { + tag = tag.replace('.', ''); + var leSprite:ModchartSprite = new ModchartSprite(0, 0); + + var rawPic:Dynamic; + + if (!Paths.currentTrackedAssets.exists(image)) + Paths.cacheImage(image); + + rawPic = Paths.currentTrackedAssets.get(image); + leSprite.loadGraphic(rawPic, true, width, height); + + PlayState.instance.modchartSprites.set(tag, leSprite); + }); + + Lua_helper.add_callback(lua, "makeGraphic", function(obj:String, width:Int, height:Int, color:String) { + var colorNum:Int = Std.parseInt(color); + if(!color.startsWith('0x')) colorNum = Std.parseInt('0xff' + color); + + if(PlayState.instance.modchartSprites.exists(obj)) { + PlayState.instance.modchartSprites.get(obj).makeGraphic(width, height, colorNum); + return; + } + + var object:FlxSprite = Reflect.getProperty(getInstance(), obj); + if(object != null) { + object.makeGraphic(width, height, colorNum); + } + }); + + Lua_helper.add_callback(lua, "addAnimationByIndices", function(obj:String, name:String, prefix:String, indices:String, framerate:Int = 24) { + var strIndices:Array = indices.trim().split(','); + var die:Array = []; + for (i in 0...strIndices.length) { + die.push(Std.parseInt(strIndices[i])); + } + + if(PlayState.instance.modchartSprites.exists(obj)) { + var pussy:ModchartSprite = PlayState.instance.modchartSprites.get(obj); + pussy.animation.addByIndices(name, prefix, die, '', framerate, false); + if(pussy.animation.curAnim == null) { + pussy.animation.play(name, true); + } + return; + } + if(PlayState.instance.modchartIcons.exists(obj)) { + var pussy:ModchartIcon = PlayState.instance.modchartIcons.get(obj); + pussy.animation.addByIndices(name, prefix, die, '', framerate, false); + if(pussy.animation.curAnim == null) { + pussy.animation.play(name, true); + } + return; + } + + var pussy:FlxSprite = Reflect.getProperty(getInstance(), obj); + if(pussy != null) { + pussy.animation.addByIndices(name, prefix, die, '', framerate, false); + if(pussy.animation.curAnim == null) { + pussy.animation.play(name, true); + } + } + }); + + Lua_helper.add_callback(lua, "addAnimationByPrefix", function(obj:String, name:String, prefix:String, framerate:Int = 24, loop:Bool = true) { + if(PlayState.instance.modchartSprites.exists(obj)) { + var cock:ModchartSprite = PlayState.instance.modchartSprites.get(obj); + cock.animation.addByPrefix(name, prefix, framerate, loop); + if(cock.animation.curAnim == null) { + cock.animation.play(name, true); + } + return; + } + + var cock:FlxSprite = Reflect.getProperty(getInstance(), obj); + if(cock != null) { + cock.animation.addByPrefix(name, prefix, framerate, loop); + if(cock.animation.curAnim == null) { + cock.animation.play(name, true); + } + } + }); + + Lua_helper.add_callback(lua, "addAnimation", function(obj:String, name:String, indices:String, framerate:Int = 24, loop:Bool = true) { + var strIndices:Array = indices.trim().split(','); + var die:Array = []; + for (i in 0...strIndices.length) { + die.push(Std.parseInt(strIndices[i])); + } + + if(PlayState.instance.modchartSprites.exists(obj)) { + var cock:ModchartSprite = PlayState.instance.modchartSprites.get(obj); + cock.animation.add(name, die, framerate, loop); + if(cock.animation.curAnim == null) { + cock.animation.play(name, true); + } + return; + } + + var cock:FlxSprite = Reflect.getProperty(getInstance(), obj); + if(cock != null) { + cock.animation.add(name, die, framerate, loop); + if(cock.animation.curAnim == null) { + cock.animation.play(name, true); + } + } + }); + + Lua_helper.add_callback(lua, "objectPlayAnimation", function(obj:String, name:String, forced:Bool = false) { + var spr:Dynamic = getThing(obj); + + if(spr != null) { + spr.animation.play(name, forced); + } + }); + + Lua_helper.add_callback(lua, "objectColorTransform", function(obj:String, r:Int, g:Int, b:Int, a:Int) { + var spr:Dynamic = getThing(obj); + + if(spr != null) { + spr.useColorTransform = true; + spr.setColorTransform(0, 0, 0, 1, r, g, b, a); + } + }); + + Lua_helper.add_callback(lua, "objectColorTween", function(obj:String, duration:Float, color:String, color2:String, ?ease:String = 'linear') { + var spr:Dynamic = getThing(obj); + + if(spr != null) { + var colorNum:Int = Std.parseInt(color); + if(!color.startsWith('0x')) colorNum = Std.parseInt('0xff' + color); + + var colorNum2:Int = Std.parseInt(color2); + if(!color2.startsWith('0x')) colorNum2 = Std.parseInt('0xff' + color2); + + FlxTween.color(spr, duration, colorNum, colorNum2, {ease: getFlxEaseByString()}); + } + }); + + Lua_helper.add_callback(lua, "inBetweenColor", function(color:String, color2:String, diff:Float, ?remove0:Bool = false) { + var colorNum:Int = Std.parseInt(color); + if(!color.startsWith('0x')) colorNum = Std.parseInt('0xff' + color); + + var colorNum2:Int = Std.parseInt(color2); + if(!color2.startsWith('0x')) colorNum2 = Std.parseInt('0xff' + color2); + + var color = FlxColor.interpolate(colorNum, colorNum2, diff); + var daColor = color.toHexString(); + + if (remove0) + daColor = daColor.substring(2); + + return daColor; + }); + + Lua_helper.add_callback(lua, "addLuaSprite", function(tag:String, front:Bool = false) { + if(PlayState.instance.modchartSprites.exists(tag)) { + var shit:ModchartSprite = PlayState.instance.modchartSprites.get(tag); + if(!shit.wasAdded) { + if(front) + { + getInstance().add(shit); + } + else + { + var position:Int = PlayState.instance.members.indexOf(PlayState.instance.gf); + if(PlayState.instance.members.indexOf(PlayState.instance.boyfriend) < position) { + position = PlayState.instance.members.indexOf(PlayState.instance.boyfriend); + } else if(PlayState.instance.members.indexOf(PlayState.instance.dad) < position) { + position = PlayState.instance.members.indexOf(PlayState.instance.dad); + } + PlayState.instance.insert(position, shit); + } + shit.wasAdded = true; + //trace('added a thing: ' + tag); + } + } + }); + + //Tween shit, but for strums + Lua_helper.add_callback(lua, "noteTweenX", function(tag:String, note:Int, value:Dynamic, duration:Float, ease:String, ?player:Bool = false) { + cancelTween(tag); + if(note < 0) note = 0; + var testicle:StrumNote = PlayState.instance.strumLineNotes.members[note % PlayState.instance.strumLineNotes.length]; + + if (player) + testicle = PlayState.instance.playerStrums.members[note]; + + if(testicle != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(testicle, {x: value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } + }); + Lua_helper.add_callback(lua, "noteTweenY", function(tag:String, note:Int, value:Dynamic, duration:Float, ease:String, ?player:Bool = false) { + cancelTween(tag); + if(note < 0) note = 0; + var testicle:StrumNote = PlayState.instance.strumLineNotes.members[note % PlayState.instance.strumLineNotes.length]; + + if (player) + testicle = PlayState.instance.playerStrums.members[note]; + + if(testicle != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(testicle, {y: value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } + }); + Lua_helper.add_callback(lua, "noteTweenAngle", function(tag:String, note:Int, value:Dynamic, duration:Float, ease:String) { + cancelTween(tag); + if(note < 0) note = 0; + var testicle:StrumNote = PlayState.instance.strumLineNotes.members[note % PlayState.instance.strumLineNotes.length]; + + if(testicle != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(testicle, {angle: value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } + }); + Lua_helper.add_callback(lua, "noteTweenDirection", function(tag:String, note:Int, value:Dynamic, duration:Float, ease:String) { + cancelTween(tag); + if(note < 0) note = 0; + var testicle:StrumNote = PlayState.instance.strumLineNotes.members[note % PlayState.instance.strumLineNotes.length]; + + if(testicle != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(testicle, {direction: value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } + }); + Lua_helper.add_callback(lua, "noteTweenAlpha", function(tag:String, note:Int, value:Dynamic, duration:Float, ease:String) { + cancelTween(tag); + if(note < 0) note = 0; + var testicle:StrumNote = PlayState.instance.strumLineNotes.members[note % PlayState.instance.strumLineNotes.length]; + + if(testicle != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(testicle, {alpha: value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } + }); + + //wow very convenient + Lua_helper.add_callback(lua, "makeHealthIcon", function(tag:String, character:String, player:Bool = false) { + tag = tag.replace('.', ''); + resetIconTag(tag); + var leSprite:ModchartIcon = new ModchartIcon(character, player); + PlayState.instance.modchartIcons.set(tag, leSprite); //yes + var shit:ModchartIcon = PlayState.instance.modchartIcons.get(tag); + shit.cameras = [PlayState.instance.camHUD]; + getInstance().add(shit); + }); + + Lua_helper.add_callback(lua, "changeAddedIcon", function(tag:String, character:String){ + var shit:ModchartIcon = PlayState.instance.modchartIcons.get(tag); + shit.useOldSystem(character); + }); + + Lua_helper.add_callback(lua, "makeLuaCharacter", function(tag:String, character:String, isPlayer:Bool = false, flipped:Bool = false) { + makeLuaCharacter(tag, character, isPlayer, flipped); + }); + + Lua_helper.add_callback(lua, "changeLuaCharacter", function(tag:String, character:String){ + var shit:Character = PlayState.instance.modchartCharacters.get(tag); + makeLuaCharacter(tag, character, shit.isPlayer, shit.flipMode); + }); + + Lua_helper.add_callback(lua, "animExists", function(tag:String, anim:String){ + var shit:Dynamic = getThing(tag); + + return shit.animation.getByName(anim) != null; + }); + + Lua_helper.add_callback(lua, "getObjectOrder", function(obj:String) { + if(PlayState.instance.modchartSprites.exists(obj)) + return getInstance().members.indexOf(PlayState.instance.modchartSprites.get(obj)); + if(PlayState.instance.modchartTexts.exists(obj)) + return getInstance().members.indexOf(PlayState.instance.modchartTexts.get(obj)); + if(PlayState.instance.modchartIcons.exists(obj)) + return getInstance().members.indexOf(PlayState.instance.modchartIcons.get(obj)); + if(PlayState.instance.modchartCharacters.exists(obj)) + return getInstance().members.indexOf(PlayState.instance.modchartCharacters.get(obj)); + if(PlayState.instance.Stage.swagBacks.exists(obj)) + return getInstance().members.indexOf(PlayState.instance.Stage.swagBacks.get(obj)); + + + var leObj:FlxBasic = Reflect.getProperty(getInstance(), obj); + if(leObj != null) + { + return getInstance().members.indexOf(leObj); + } + luaTrace("Object " + obj + " doesn't exist!"); + return -1; + }); + + Lua_helper.add_callback(lua, "setObjectOrder", function(obj:String, position:Int) { + if(PlayState.instance.modchartSprites.exists(obj)) { + var spr:ModchartSprite = PlayState.instance.modchartSprites.get(obj); + if(spr.wasAdded) { + getInstance().remove(spr, true); + } + getInstance().insert(position, spr); + return; + } + if(PlayState.instance.modchartCharacters.exists(obj)) { + var spr:Character = PlayState.instance.modchartCharacters.get(obj); + getInstance().remove(spr, true); + getInstance().insert(position, spr); + return; + } + if(PlayState.instance.modchartIcons.exists(obj)) { + var spr:ModchartIcon = PlayState.instance.modchartIcons.get(obj); + getInstance().remove(spr, true); + getInstance().insert(position, spr); + return; + } + if(PlayState.instance.modchartTexts.exists(obj)) { + var spr:ModchartText = PlayState.instance.modchartTexts.get(obj); + if(spr.wasAdded) { + getInstance().remove(spr, true); + } + getInstance().insert(position, spr); + return; + } + if(PlayState.instance.Stage.swagBacks.exists(obj)) { + var spr:Dynamic = PlayState.instance.Stage.swagBacks.get(obj); + getInstance().remove(spr, true); + getInstance().insert(position, spr); + return; + } + + var leObj:FlxBasic = Reflect.getProperty(getInstance(), obj); + if(leObj != null) { + getInstance().remove(leObj, true); + getInstance().insert(position, leObj); + return; + } + luaTrace("Object " + obj + " doesn't exist!"); + }); + + Lua_helper.add_callback(lua, "characterPlayAnim", function(character:String, anim:String, ?forced:Bool = false) { + switch(character.toLowerCase()) { + case 'dad': + if(PlayState.instance.dad.animOffsets.exists(anim)) + PlayState.instance.dad.playAnim(anim, forced); + case 'gf' | 'girlfriend': + if(PlayState.instance.gf.animOffsets.exists(anim)) + PlayState.instance.gf.playAnim(anim, forced); + default: + if(PlayState.instance.boyfriend.animOffsets.exists(anim)) + PlayState.instance.boyfriend.playAnim(anim, forced); + } + }); + + Lua_helper.add_callback(lua, "characterDance", function(character:String) { + if(PlayState.instance.modchartCharacters.exists(character)) { + var spr:Character = PlayState.instance.modchartCharacters.get(character); + spr.dance(); + } + else + getActorByName(character).dance(); + }); + + Lua_helper.add_callback(lua, "scaleObject", function(obj:String, x:Float, y:Float) { + if(PlayState.instance.modchartSprites.exists(obj)) { + var shit:ModchartState.ModchartSprite = PlayState.instance.modchartSprites.get(obj); + shit.scale.set(x, y); + shit.updateHitbox(); + return; + } + + if(PlayState.instance.modchartCharacters.exists(obj)) { + var shit:Dynamic = PlayState.instance.modchartCharacters.get(obj); + shit.scale.set(x, y); + shit.updateHitbox(); + return; + } + + if(PlayState.instance.modchartIcons.exists(obj)) { + var shit:Dynamic = PlayState.instance.modchartIcons.get(obj); + shit.scale.set(x, y); + shit.updateHitbox(); + return; + } + + if(Stage.instance.swagBacks.exists(obj)) { + var shit:ModchartSprite = Stage.instance.swagBacks.get(obj); + shit.scale.set(x, y); + shit.updateHitbox(); + return; + } + + if(PlayState.instance.Stage.swagBacks.exists(obj)) { + var shit:ModchartSprite = Stage.instance.swagBacks.get(obj); + shit.scale.set(x, y); + shit.updateHitbox(); + return; + } + + var poop:FlxSprite = Reflect.getProperty(getInstance(), obj); + if(poop != null) { + poop.scale.set(x, y); + poop.updateHitbox(); + return; + } + luaTrace('Couldnt find object: ' + obj); + }); + + Lua_helper.add_callback(lua, "setOffset", function(id:String, x:Float, y:Float) { + var shit:Dynamic = getThing(id); + shit.offset.set(x, y); + }); + + // LUA TEXTS + Lua_helper.add_callback(lua, "makeLuaText", function(tag:String, text:String, width:Int, x:Float, y:Float) { + tag = tag.replace('.', ''); + resetTextTag(tag); + var leText:ModchartText = new ModchartText(x, y, text, width); + PlayState.instance.modchartTexts.set(tag, leText); + }); + + Lua_helper.add_callback(lua, "setTextString", function(tag:String, text:String) { + var obj:FlxText = getTextObject(tag); + if(obj != null) + { + obj.text = text; + } + }); + Lua_helper.add_callback(lua, "setTextSize", function(tag:String, size:Int) { + var obj:FlxText = getTextObject(tag); + if(obj != null) + { + obj.size = size; + } + }); + Lua_helper.add_callback(lua, "setTextWidth", function(tag:String, width:Float) { + var obj:FlxText = getTextObject(tag); + if(obj != null) + { + obj.fieldWidth = width; + } + }); + Lua_helper.add_callback(lua, "setTextBorder", function(tag:String, size:Int, color:String) { + var obj:FlxText = getTextObject(tag); + if(obj != null) + { + var colorNum:Int = Std.parseInt(color); + if(!color.startsWith('0x')) colorNum = Std.parseInt('0xff' + color); + + obj.borderSize = size; + obj.borderColor = colorNum; + } + }); + Lua_helper.add_callback(lua, "setTextColor", function(tag:String, color:String) { + var obj:FlxText = getTextObject(tag); + if(obj != null) + { + var colorNum:Int = Std.parseInt(color); + if(!color.startsWith('0x')) colorNum = Std.parseInt('0xff' + color); + + obj.color = colorNum; + } + }); + Lua_helper.add_callback(lua, "setTextFont", function(tag:String, newFont:String) { + var obj:FlxText = getTextObject(tag); + if(obj != null) + { + obj.font = Paths.font(newFont); + } + }); + Lua_helper.add_callback(lua, "setTextItalic", function(tag:String, italic:Bool) { + var obj:FlxText = getTextObject(tag); + if(obj != null) + { + obj.italic = italic; + } + }); + Lua_helper.add_callback(lua, "setTextAlignment", function(tag:String, alignment:String = 'left') { + var obj:FlxText = getTextObject(tag); + if(obj != null) + { + obj.alignment = LEFT; + switch(alignment.trim().toLowerCase()) + { + case 'right': + obj.alignment = RIGHT; + case 'center': + obj.alignment = CENTER; + } + } + }); + + Lua_helper.add_callback(lua, "getTextString", function(tag:String) { + var obj:FlxText = getTextObject(tag); + if(obj != null) + { + return obj.text; + } + return null; + }); + Lua_helper.add_callback(lua, "getTextSize", function(tag:String) { + var obj:FlxText = getTextObject(tag); + if(obj != null) + { + return obj.size; + } + return -1; + }); + Lua_helper.add_callback(lua, "getTextFont", function(tag:String) { + var obj:FlxText = getTextObject(tag); + if(obj != null) + { + return obj.font; + } + return null; + }); + Lua_helper.add_callback(lua, "getTextWidth", function(tag:String) { + var obj:FlxText = getTextObject(tag); + if(obj != null) + { + return obj.fieldWidth; + } + return 0; + }); + + Lua_helper.add_callback(lua, "addLuaText", function(tag:String) { + if(PlayState.instance.modchartTexts.exists(tag)) { + var shit:ModchartText = PlayState.instance.modchartTexts.get(tag); + if(!shit.wasAdded) { + getInstance().add(shit); + shit.wasAdded = true; + //trace('added a thing: ' + tag); + } + } + }); + Lua_helper.add_callback(lua, "removeLuaText", function(tag:String, destroy:Bool = true) { + if(!PlayState.instance.modchartTexts.exists(tag)) { + return; + } + + var pee:ModchartText = PlayState.instance.modchartTexts.get(tag); + if(destroy) { + pee.kill(); + } + + if(pee.wasAdded) { + getInstance().remove(pee, true); + pee.wasAdded = false; + } + + if(destroy) { + pee.destroy(); + PlayState.instance.modchartTexts.remove(tag); + } + }); + + //SHADER SHIT + + Lua_helper.add_callback(lua, "addChromaticAbberationEffect", function(camera:String,chromeOffset:Float = 0.005) { + + PlayState.instance.addShaderToCamera(camera, new ChromaticAberrationEffect(chromeOffset)); + + }); + + Lua_helper.add_callback(lua, "addEffect", function(camera:String,effect:String, ?val1:Dynamic, ?val2:Dynamic, ?val3:Dynamic, ?val4:Dynamic) { + + PlayState.instance.addShaderToCamera(camera, getEffectFromString(effect, val1, val2, val3, val4)); + + }); + Lua_helper.add_callback(lua, "clearEffects", function(camera:String) { + PlayState.instance.clearShaderFromCamera(camera); + }); + + + + // default strums + + Lua_helper.add_callback(lua, "getNotes", function(y:Float) + { + Lua.newtable(lua); + + for (i in 0...PlayState.instance.notes.members.length) + { + var note = PlayState.instance.notes.members[i]; + Lua.pushstring(lua, note.LuaNote.className); + Lua.rawseti(lua, -2, i); + } + }); + + + if (PlayState.instance != null && PlayState.instance.isDetected) + { + for (i in 0...PlayState.instance.strumLineNotes.length) { + var member = PlayState.instance.strumLineNotes.members[i]; + trace(PlayState.instance.strumLineNotes.members[i].x + " " + PlayState.instance.strumLineNotes.members[i].y + " " + PlayState.instance.strumLineNotes.members[i].angle + " | strum" + i); + //set("strum" + i + "X", Math.floor(member.x)); + set("defaultStrum" + i + "X", Math.floor(member.x)); + //set("strum" + i + "Y", Math.floor(member.y)); + set("defaultStrum" + i + "Y", Math.floor(member.y)); + //set("strum" + i + "Angle", Math.floor(member.angle)); + set("defaultStrum" + i + "Angle", Math.floor(member.angle)); + set("defaultStrum" + i + "Alpha", Math.floor(member.alpha)); + trace("Adding strum" + i); + + if (PlayState.instance.isDetected) + new LuaReceptor(member, "receptor_" + i).Register(lua); + } + + if (PlayState.instance.isDetected) + { + new LuaGame().Register(lua); + new LuaWindow().Register(lua); + } + } + + //dumb group dancer shit + // default strums + } + + public function getThing(id:String) + { + var shit:Dynamic; + + if(PlayState.instance.modchartSprites.exists(id)) + shit = PlayState.instance.modchartSprites.get(id); + else if(PlayState.instance.modchartTexts.exists(id)) + shit = PlayState.instance.modchartTexts.get(id); + else if(PlayState.instance.modchartIcons.exists(id)) + shit = PlayState.instance.modchartIcons.get(id); + else if(PlayState.instance.modchartCharacters.exists(id)) + shit = PlayState.instance.modchartCharacters.get(id); + else if(PlayState.instance.Stage.swagBacks.exists(id)) + shit = PlayState.instance.Stage.swagBacks.get(id); + else if(Stage.instance.swagBacks.exists(id)) + shit = Stage.instance.swagBacks.get(id); + else + shit = getActorByName(id); + + return shit; + } + + public function executeState(name,args:Array) + { + return Lua.tostring(lua,call(name, args)); + } + + function cameraFromString(cam:String):FlxCamera + { + switch(cam.toLowerCase()) { + case 'camhud' | 'hud': return PlayState.instance.camHUD; + case 'camother' | 'other': return PlayState.instance.camOther; + case 'camnotes' | 'notes': return PlayState.instance.camNotes; + } + return PlayState.instance.camGame; + } + + inline function getTextObject(name:String):FlxText + { + return PlayState.instance.modchartTexts.exists(name) ? PlayState.instance.modchartTexts.get(name) : Reflect.getProperty(PlayState.instance, name); + } + + function cancelTimer(tag:String) { + if(PlayState.instance.modchartTimers.exists(tag)) { + var theTimer:FlxTimer = PlayState.instance.modchartTimers.get(tag); + theTimer.cancel(); + theTimer.destroy(); + PlayState.instance.modchartTimers.remove(tag); + + return; + } + + var daTimer:Dynamic = Reflect.getProperty(getInstance(), tag); + if(Std.isOfType(daTimer, FlxTimer)) { + daTimer.cancel(); + daTimer.destroy(); + return; + } + } + + function cancelTween(tag:String) { + if(PlayState.instance.modchartTweens.exists(tag)) { + PlayState.instance.modchartTweens.get(tag).cancel(); + PlayState.instance.modchartTweens.get(tag).destroy(); + PlayState.instance.modchartTweens.remove(tag); + } + } + + function tweenShit(tag:String, vars:String) { + cancelTween(tag); + var variables:Array = vars.replace(' ', '').split('.'); + var sexyProp:Dynamic = Reflect.getProperty(getInstance(), variables[0]); + if(PlayState.instance.modchartSprites.exists(variables[0])) { + sexyProp = PlayState.instance.modchartSprites.get(variables[0]); + } + if(PlayState.instance.modchartTexts.exists(variables[0])) { + sexyProp = PlayState.instance.modchartTexts.get(variables[0]); + } + + for (i in 1...variables.length) { + sexyProp = Reflect.getProperty(sexyProp, variables[i]); + } + return sexyProp; + } + + function resetTextTag(tag:String) { + if(!PlayState.instance.modchartTexts.exists(tag)) { + return; + } + + var pee:ModchartText = PlayState.instance.modchartTexts.get(tag); + pee.kill(); + if(pee.wasAdded) { + PlayState.instance.remove(pee, true); + } + pee.destroy(); + PlayState.instance.modchartTexts.remove(tag); + } + + function resetSpriteTag(tag:String) { + if(!PlayState.instance.modchartSprites.exists(tag)) { + return; + } + + var pee:ModchartSprite = PlayState.instance.modchartSprites.get(tag); + pee.kill(); + if(pee.wasAdded) { + PlayState.instance.remove(pee, true); + } + pee.destroy(); + PlayState.instance.modchartSprites.remove(tag); + } + + function resetIconTag(tag:String) { + if(!PlayState.instance.modchartIcons.exists(tag)) { + return; + } + + var pee:ModchartIcon = PlayState.instance.modchartIcons.get(tag); + pee.kill(); + if(pee.wasAdded) { + PlayState.instance.remove(pee, true); + } + pee.destroy(); + PlayState.instance.modchartIcons.remove(tag); + } + + function resetCharacterTag(tag:String) { + if(!PlayState.instance.modchartCharacters.exists(tag)) { + return; + } + + var pee:Dynamic = PlayState.instance.modchartCharacters.get(tag); + pee.kill(); + if(pee.wasAdded) { + PlayState.instance.remove(pee, true); + } + pee.destroy(); + PlayState.instance.modchartCharacters.remove(tag); + } + + function blendModeFromString(blend:String):BlendMode { + switch(blend.toLowerCase().trim()) { + case 'add': return ADD; + case 'alpha': return ALPHA; + case 'darken': return DARKEN; + case 'difference': return DIFFERENCE; + case 'erase': return ERASE; + case 'hardlight': return HARDLIGHT; + case 'invert': return INVERT; + case 'layer': return LAYER; + case 'lighten': return LIGHTEN; + case 'multiply': return MULTIPLY; + case 'overlay': return OVERLAY; + case 'screen': return SCREEN; + case 'shader': return SHADER; + case 'subtract': return SUBTRACT; + } + return NORMAL; + } + + function getFlxEaseByString(?ease:String = '') { + switch(ease.toLowerCase().trim()) { + case 'backin': return FlxEase.backIn; + case 'backinout': return FlxEase.backInOut; + case 'backout': return FlxEase.backOut; + case 'bouncein': return FlxEase.bounceIn; + case 'bounceinout': return FlxEase.bounceInOut; + case 'bounceout': return FlxEase.bounceOut; + case 'circin': return FlxEase.circIn; + case 'circinout': return FlxEase.circInOut; + case 'circout': return FlxEase.circOut; + case 'cubein': return FlxEase.cubeIn; + case 'cubeinout': return FlxEase.cubeInOut; + case 'cubeout': return FlxEase.cubeOut; + case 'elasticin': return FlxEase.elasticIn; + case 'elasticinout': return FlxEase.elasticInOut; + case 'elasticout': return FlxEase.elasticOut; + case 'expoin': return FlxEase.expoIn; + case 'expoinout': return FlxEase.expoInOut; + case 'expoout': return FlxEase.expoOut; + case 'quadin': return FlxEase.quadIn; + case 'quadinout': return FlxEase.quadInOut; + case 'quadout': return FlxEase.quadOut; + case 'quartin': return FlxEase.quartIn; + case 'quartinout': return FlxEase.quartInOut; + case 'quartout': return FlxEase.quartOut; + case 'quintin': return FlxEase.quintIn; + case 'quintinout': return FlxEase.quintInOut; + case 'quintout': return FlxEase.quintOut; + case 'sinein': return FlxEase.sineIn; + case 'sineinout': return FlxEase.sineInOut; + case 'sineout': return FlxEase.sineOut; + case 'smoothstepin': return FlxEase.smoothStepIn; + case 'smoothstepinout': return FlxEase.smoothStepInOut; + case 'smoothstepout': return FlxEase.smoothStepInOut; + case 'smootherstepin': return FlxEase.smootherStepIn; + case 'smootherstepinout': return FlxEase.smootherStepInOut; + case 'smootherstepout': return FlxEase.smootherStepOut; + } + return FlxEase.linear; + } + + function getEffectFromString(?effect:String = '', ?val1:Dynamic, ?val2:Dynamic, ?val3:Dynamic , ?val4:Dynamic):ShaderEffect { + switch(effect.toLowerCase().trim()) { + case 'grayscale' | 'greyscale' : return new GreyscaleEffect(); + case 'invert' | 'invertcolor': return new InvertColorsEffect(); + case 'tiltshift': return new TiltshiftEffect(val1,val2); + case 'grain': return new GrainEffect(val1,val2,val3); + case 'scanline': return new ScanlineEffect(val1); + case 'outline': return new OutlineEffect(val1, val2, val3, val4); + case 'distortion': return new DistortBGEffect(val1, val2, val3); + case 'vcr': return new VCRDistortionEffect(val1,val2,val3,val4); + case 'glitch': return new GlitchEffect(val1, val2, val3); + case 'vcr2': return new VCRDistortionEffect2(); //the tails doll one + case '3d': return new ThreeDEffect(val1, val2, val3, val4); + case 'bloom': return new BloomEffect(val1/512.0,val2); + case 'rgbshiftglitch' | 'rgbshift': return new RGBShiftGlitchEffect(val1, val2); + case 'pulse': return new PulseEffect(val1,val2,val3); + case 'chromaticabberation' | 'ca': return new ChromaticAberrationEffect(val1); + case 'sketch': return new SketchEffect(); + } + return new GreyscaleEffect(); + } + + inline function getInstance() + { + return PlayState.instance.isDead ? GameOverSubstate.instance : PlayState.instance; + } +} +#end + +class ModchartSprite extends FlxSprite +{ + public var wasAdded:Bool = false; + //public var isInFront:Bool = false; +} + +class ModchartIcon extends HealthIcon +{ + public var wasAdded:Bool = false; + //public var isInFront:Bool = false; +} + +class ModchartText extends FlxText +{ + public var wasAdded:Bool = false; + public function new(x:Float, y:Float, text:String, width:Float) + { + super(x, y, width, text, 16); + setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + cameras = [PlayState.instance.camHUD]; + scrollFactor.set(); + borderSize = 2; + } +} + +class DebugLuaText extends FlxText +{ + private var disableTime:Float = 6; + public var parentGroup:FlxTypedGroup; + public function new(text:String, parentGroup:FlxTypedGroup) { + this.parentGroup = parentGroup; + super(10, 10, 0, text, 16); + setFormat(Paths.font("vcr.ttf"), 20, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + scrollFactor.set(); + borderSize = 1; + } + + override function update(elapsed:Float) { + super.update(elapsed); + disableTime -= elapsed; + if(disableTime <= 0) { + kill(); + parentGroup.remove(this); + destroy(); + } + else if(disableTime < 1) alpha = disableTime; + } +} \ No newline at end of file diff --git a/source/ModchartStateButPsych.hx b/source/ModchartStateButPsych.hx new file mode 100644 index 000000000..98d6a09de --- /dev/null +++ b/source/ModchartStateButPsych.hx @@ -0,0 +1,4228 @@ +// i thought doing this would fix the bug of running a command on one messing with the other but I guess not. + +#if LUA_ALLOWED +import llua.Lua; +import llua.LuaL; +import llua.State; +import llua.Convert; +#end + +import openfl.display3D.textures.VideoTexture; +import flixel.graphics.FlxGraphic; +import flixel.graphics.frames.FlxAtlasFrames; +import lime.app.Application; + +import animateatlas.AtlasFrameMaker; +import flixel.FlxG; +import flixel.addons.effects.FlxTrail; +import flixel.input.keyboard.FlxKey; +import flixel.tweens.FlxTween; +import flixel.tweens.FlxEase; +import flixel.text.FlxText; +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.math.FlxPoint; +import flixel.system.FlxSound; +import flixel.util.FlxTimer; +import flixel.FlxSprite; +import flixel.FlxCamera; +import flixel.util.FlxColor; +import flixel.FlxBasic; +import flixel.FlxObject; +import flixel.FlxSprite; +import openfl.Lib; +import openfl.display.BlendMode; +import openfl.filters.BitmapFilter; +import openfl.utils.Assets; +import flixel.math.FlxMath; +import flixel.util.FlxSave; +import flixel.addons.transition.FlxTransitionableState; +import openfl.filters.ShaderFilter; +import flixel.effects.FlxFlicker; +import Shaders; +import flash.media.Sound; + +#if sys +import sys.FileSystem; +import sys.io.File; +#end +import Type.ValueType; +import Controls; + +#if desktop +import Discord; +#end + +//why is detected's modchart confusing!? +import LuaClass.LuaGame; +import LuaClass.LuaWindow; +import LuaClass.LuaSprite; +import LuaClass.LuaCamera; +import LuaClass.LuaNote; +import LuaClass.LuaReceptor; + +using StringTools; + +class ModchartState { + public static var Function_Stop:Dynamic = 1; + public static var Function_Continue:Dynamic = 0; + + public static var shownNotes:Array = []; + + #if LUA_ALLOWED + public var lua:State = null; + #end + public var camTarget:FlxCamera; + public var scriptName:String = ''; + var gonnaClose:Bool = false; + + public var accessedProps:Map = null; + public function new(script:String) { + #if LUA_ALLOWED + lua = LuaL.newstate(); + LuaL.openlibs(lua); + Lua.init_callbacks(lua); + + //trace('Lua version: ' + Lua.version()); + //trace("LuaJIT version: " + Lua.versionJIT()); + + LuaL.dostring(lua, CLENSE); + var result:Dynamic = LuaL.dofile(lua, script); + var resultStr:String = Lua.tostring(lua, result); + if(resultStr != null && result != 0) { + trace('Error on lua script! ' + resultStr); + #if windows + lime.app.Application.current.window.alert(resultStr, 'Error on lua script!'); + #else + luaTrace('Error loading lua script: "$script"\n' + resultStr,true,false); + #end + lua = null; + return; + } + scriptName = script; + trace('lua file loaded succesfully:' + script); + + #if (haxe >= "4.0.0") + accessedProps = new Map(); + #else + accessedProps = new Map(); + #end + + // Lua shit + set('Function_Stop', Function_Stop); + set('Function_Continue', Function_Continue); + set('luaDebugMode', false); + set('luaDeprecatedWarnings', true); + set('inChartEditor', false); + + // Song/Week shit + set('curBpm', Conductor.bpm); + set('bpm', PlayState.SONG.bpm); + set('scrollSpeed', PlayState.SONG.speed); + set("crochetReal", Conductor.crochet); //yeah i don't know either + set("crochet", Conductor.stepCrochet); + set('songLength', FlxG.sound.music.length); + set('songName', PlayState.SONG.song); + set('startedCountdown', false); + + set('isStoryMode', PlayState.isStoryMode); + set('difficulty', PlayState.storyDifficulty); + set('difficultyName', CoolUtil.difficulties[PlayState.storyDifficulty]); + set('weekRaw', PlayState.storyWeek); + set('week', WeekData.weeksList[PlayState.storyWeek]); + set('seenCutscene', PlayState.seenCutscene); + + set("safeZoneOffset", Conductor.safeZoneOffset); + + set("cameraZoom", FlxG.camera.zoom); + + set("cameraAngle", FlxG.camera.angle); + + // Block require and os, Should probably have a proper function but this should be good enough for now until someone smarter comes along and recreates a safe version of the OS library + set('require', false); + + // Camera poo + set('cameraX', 0); + set('cameraY', 0); + + // Screen stuff + set('screenWidth', FlxG.width); + set('screenHeight', FlxG.height); + + // PlayState cringe ass nae nae bullcrap + set('curBeat', 0); + set('curStep', 0); + + set('score', 0); + set('misses', 0); + set('hits', 0); + + set('rating', 0); + set('ratingName', ''); + set('ratingFC', ''); + + set('inGameOver', false); + set('mustHitSection', false); + set('altAnim', false); + set('gfSection', false); + + for (i in 0...4) { + set('defaultPlayerStrumX' + i, 0); + set('defaultPlayerStrumY' + i, 0); + set('defaultOpponentStrumX' + i, 0); + set('defaultOpponentStrumY' + i, 0); + } + + // Character shit + set('boyfriendName', PlayState.SONG.player1); + set('dadName', PlayState.SONG.player2); + set('gfName', PlayState.SONG.gfVersion); + + // Some settings, no jokes + set("scrollspeed", FlxG.save.data.scrollSpeed != 1 ? FlxG.save.data.scrollSpeed : PlayState.SONG.speed); + set("fpsCap", FlxG.save.data.fpsCap); + set("downscroll", FlxG.save.data.downscroll); + set("flashing", FlxG.save.data.flashing); + set("distractions", FlxG.save.data.distractions); + + set("followBFXOffset",0); + set("followBFYOffset",0); + set("followDadXOffset",0); + set("followDadYOffset",0); + + set("bfAltAnim", false); + set("dadAltAnim", false); + set("bfNotesVisible", true); + set("dadNotesInvisible", false); + + set("showOnlyStrums", false); + set("strumLine1Visible", true); + set("strumLine2Visible", true); + + set("screenWidth",FlxG.width); + set("screenHeight",FlxG.height); + set("windowWidth",FlxG.width); + set("windowHeight",FlxG.height); + + set("newIcons", false); + set("swapIcons", true); + set("playDadSing", true); + set("playBFSing", true); + + #if windows + set('buildTarget', 'windows'); + #elseif linux + set('buildTarget', 'linux'); + #elseif mac + set('buildTarget', 'mac'); + #elseif html5 + set('buildTarget', 'browser'); + #elseif android + set('buildTarget', 'android'); + #else + set('buildTarget', 'unknown'); + #end + + Lua_helper.add_callback(lua,"doFunction", doFunction); + + Lua_helper.add_callback(lua,"changeDadCharacter", changeDadCharacter); + + Lua_helper.add_callback(lua,"changeBoyfriendCharacter", changeBoyfriendCharacter); + + Lua_helper.add_callback(lua,"changeGFCharacter", changeGFCharacter); + + Lua_helper.add_callback(lua,"changeStage", changeStage); + + Lua_helper.add_callback(lua,"changeDadCharacterBetter", changeDadCharacterBetter); + + Lua_helper.add_callback(lua,"changeBoyfriendCharacterBetter", changeBoyfriendCharacterBetter); + + Lua_helper.add_callback(lua,"changeGFCharacterBetter", changeGFCharacterBetter); + + Lua_helper.add_callback(lua,"changeDad1Character", changeDad1Character); + + Lua_helper.add_callback(lua,"changeBoyfriend1Character", changeBoyfriend1Character); + + Lua_helper.add_callback(lua,"changeDad2Character", changeDad2Character); + + Lua_helper.add_callback(lua,"changeBoyfriend2Character", changeBoyfriend2Character); + + //the auto stuff + Lua_helper.add_callback(lua,"changeBFAuto", changeBFAuto); + + //cuz sometimes i type boyfriend instead of bf + Lua_helper.add_callback(lua,"changeBoyfriendAuto", changeBFAuto); + + Lua_helper.add_callback(lua,"changeDadAuto", changeDadAuto); + + Lua_helper.add_callback(lua,"changeGFAuto", changeGFAuto); + + + Lua_helper.add_callback(lua,"fileExists", function(key:String) { + if(FileSystem.exists(FileSystem.absolutePath(key))) { + return true; + } + return false; + }); + + Lua_helper.add_callback(lua, "toggleCamFilter", function(bool:Bool, camera:String = '') { + cameraFromString(camera).filtersEnabled = bool; + }); + + Lua_helper.add_callback(lua, "addLuaScript", function(luaFile:String, ?ignoreAlreadyRunning:Bool = false) { //would be dope asf. + var cervix = luaFile + ".lua"; + var doPush = false; + if(FileSystem.exists(FileSystem.absolutePath("assets/shared/"+cervix))) { + cervix = FileSystem.absolutePath("assets/shared/"+cervix); + doPush = true; + } + else if (FileSystem.exists(Paths.modFolders(cervix))) + { + cervix = Paths.modFolders(cervix); + doPush = true; + } + else { + cervix = Paths.getPreloadPath(cervix); + if(FileSystem.exists(cervix)) { + doPush = true; + } + } + + if(doPush) + { + if(!ignoreAlreadyRunning) + { + for (luaInstance in PlayState.instance.luaArray) + { + if(luaInstance.scriptName == cervix) + { + luaTrace('The script "' + cervix + '" is already running!'); + return; + } + } + } + PlayState.instance.luaArray.push(new ModchartState(cervix)); + return; + } + luaTrace("Script doesn't exist!"); + }); + Lua_helper.add_callback(lua, "removeLuaScript", function(luaFile:String, ?ignoreAlreadyRunning:Bool = false) { //would be dope asf. + var cervix = luaFile + ".lua"; + var doPush = false; + if(FileSystem.exists(FileSystem.absolutePath("assets/shared/"+cervix))) { + cervix = FileSystem.absolutePath("assets/shared/"+cervix); + doPush = true; + } + else if (FileSystem.exists(Paths.modFolders(cervix))) + { + cervix = Paths.modFolders(cervix); + doPush = true; + } + else { + cervix = Paths.getPreloadPath(cervix); + if(FileSystem.exists(cervix)) { + doPush = true; + } + } + + if(doPush) + { + if(!ignoreAlreadyRunning) + { + for (luaInstance in PlayState.instance.luaArray) + { + if(luaInstance.scriptName == cervix) + { + //luaTrace('The script "' + cervix + '" is already running!'); + + PlayState.instance.luaArray.remove(luaInstance); + return; + } + } + } + return; + } + luaTrace("Script doesn't exist!"); + }); + + //because the regular close function isn't working for me + Lua_helper.add_callback(lua, "closeLuaScript", function(luaFile:String, ?ignoreAlreadyRunning:Bool = false) { //would be dope asf. + var cervix = luaFile + ".lua"; + var doPush = false; + if(FileSystem.exists(FileSystem.absolutePath("assets/shared/"+cervix))) { + cervix = FileSystem.absolutePath("assets/shared/"+cervix); + doPush = true; + } + else if (FileSystem.exists(Paths.modFolders(cervix))) + { + cervix = Paths.modFolders(cervix); + doPush = true; + } + else { + cervix = Paths.getPreloadPath(cervix); + if(FileSystem.exists(cervix)) { + doPush = true; + } + } + + if(doPush) + { + if(!ignoreAlreadyRunning) + { + for (luaInstance in PlayState.instance.luaArray) + { + if(luaInstance.scriptName == cervix) + { + PlayState.instance.luaArray.remove(luaInstance); + luaInstance.die(); + return; + } + } + } + return; + } + luaTrace("Script doesn't exist!"); + }); + + + Lua_helper.add_callback(lua,"animationSwap", function(char:String, anim1:String, anim2:String) { + var shit = getThing(char); + + if (shit.animation.getByName(anim1) != null) + { + var oldRight = shit.animation.getByName(anim1).frames; + shit.animation.getByName(anim1).frames = shit.animation.getByName(anim2).frames; + shit.animation.getByName(anim2).frames = oldRight; + } + }); + + Lua_helper.add_callback(lua,"destroyObject", function(id:String, ?bg:Bool = false) { + if (bg) + PlayState.instance.Stage.destroyObject(PlayState.instance.Stage.swagBacks[id]); + else + { + var shit:Dynamic = getThing(id); + PlayState.instance.destroyObject(shit); + } + }); + + Lua_helper.add_callback(lua,"removeGroupObject", function(obj:String, index:Int = 0) { + var shit:Dynamic = Reflect.getProperty(getInstance(), obj); + + shit.forEach(function(spr:Dynamic) + { + if (spr.ID == index) + PlayState.instance.removeObject(spr); + }); + }); + + Lua_helper.add_callback(lua,"destroyGroupObject", function(obj:String, index:Int = 0) { + //i have no idea if this works.... it works + var shit:Dynamic = Reflect.getProperty(getInstance(), obj); + + shit.forEach(function(spr:Dynamic) + { + if (spr.ID == index) + spr.destroy(); + }); + }); + + Lua_helper.add_callback(lua, "removeLuaSprite", function(tag:String, destroy:Bool = true) { + if(!PlayState.instance.modchartSprites.exists(tag)) { + return; + } + + var pee:ModchartSprite = PlayState.instance.modchartSprites.get(tag); + if(destroy) { + pee.kill(); + } + + if(pee.wasAdded) { + getInstance().remove(pee, true); + pee.wasAdded = false; + } + + if(destroy) { + pee.destroy(); + PlayState.instance.modchartSprites.remove(tag); + } + }); + + Lua_helper.add_callback(lua, "removeLuaIcon", function(tag:String, destroy:Bool = true) { + if(!PlayState.instance.modchartIcons.exists(tag)) { + return; + } + + var pee:ModchartIcon = PlayState.instance.modchartIcons.get(tag); + if(destroy) { + pee.kill(); + } + + if(pee.wasAdded) { + getInstance().remove(pee, true); + pee.wasAdded = false; + } + + if(destroy) { + pee.destroy(); + PlayState.instance.modchartIcons.remove(tag); + } + }); + + Lua_helper.add_callback(lua, "getSongPosition", function() { + return Conductor.songPosition; + }); + + Lua_helper.add_callback(lua,"setScrollFactor", function(id:String , x:Float, y:Float, ?bg:Bool = false) { + var shit:Dynamic = getThing(id); + + shit.scrollFactor.set(x, y); + }); + + Lua_helper.add_callback(lua,"getScrollFactor", function(id:String , x:String) { + var shit:Dynamic = getThing(id); + if (x == 'x') + return shit.scrollFactor.x; + else + return shit.scrollFactor.y; + }); + + Lua_helper.add_callback(lua,"changeAnimOffset", function(id:String , x:Float, y:Float) { + getActorByName(id).addOffset(x, y); // it may say addoffset but it actually changes it instead of adding to the existing offset so this works. + }); + + Lua_helper.add_callback(lua,"checkDownscroll", function() { + return FlxG.save.data.downscroll; + }); + + Lua_helper.add_callback(lua,"getScared", function(id:String) { + PlayState.instance.Stage.swagBacks[id].getScared(); + }); + + // hud/camera + + Lua_helper.add_callback(lua,"updateHealthbar", function(dadColor:String = "", bfColor:String = ""){ + var opponent:String; + var player:String; + + if (dadColor == "") + opponent = PlayState.instance.dad.iconColor; + else + opponent = dadColor; + + if (bfColor == "") + player = PlayState.instance.boyfriend.iconColor; + else + player = bfColor; + + PlayState.instance.healthBar.createFilledBar(FlxColor.fromString('#' + opponent), FlxColor.fromString('#' + player)); + PlayState.instance.healthBar.updateBar(); + }); + + Lua_helper.add_callback(lua,"returnDominantColor", function(sprite:String, ?remove0:Bool = false){ + var shit:Dynamic = getThing(sprite); + + var coolColor = FlxColor.fromInt(CoolUtil.dominantColor(shit)); + var daColor = coolColor.toHexString(); + + if (remove0) + daColor = daColor.substring(2); + + return daColor; + }); + + + Lua_helper.add_callback(lua, "playSound", function(sound:String, ?volume:Float = 1, ?tag:String = null) { + var soundPath:Dynamic; + var isCustomSound:Bool = false; + + if (Assets.exists(Paths.sound(sound))) + soundPath = Paths.sound(sound); + else + { + if (FileSystem.exists(Paths.sound(sound))) + { + isCustomSound = true; + soundPath = Paths.sound(sound); + } + else + { + soundPath = Paths.sound('nogood'); + luaTrace('Sound not found!'); + } + } + + if(tag != null && tag.length > 0) { + tag = tag.replace('.', ''); + if(PlayState.instance.modchartSounds.exists(tag)) { + PlayState.instance.modchartSounds.get(tag).stop(); + } + + PlayState.instance.modchartSounds.set(tag, FlxG.sound.play((isCustomSound ? (Paths.currentTrackedSounds.exists(sound) ? Paths.currentTrackedSounds.get(sound) : Sound.fromFile(soundPath)): soundPath), volume, false, function() { + PlayState.instance.modchartSounds.remove(tag); + PlayState.instance.callOnLuas('onSoundFinished', [tag]); + })); + return; + } + if (isCustomSound) + FlxG.sound.play((Paths.currentTrackedSounds.exists(sound) ? Paths.currentTrackedSounds.get(sound) : Sound.fromFile(soundPath)), volume); + else + FlxG.sound.play(soundPath, volume); + }); + + Lua_helper.add_callback(lua, "stopSound", function(tag:String) { + if(tag != null && tag.length > 1 && PlayState.instance.modchartSounds.exists(tag)) { + PlayState.instance.modchartSounds.get(tag).stop(); + PlayState.instance.modchartSounds.remove(tag); + } + }); + + Lua_helper.add_callback(lua, "pauseSound", function(tag:String) { + if(tag != null && tag.length > 1 && PlayState.instance.modchartSounds.exists(tag)) { + PlayState.instance.modchartSounds.get(tag).pause(); + } + }); + Lua_helper.add_callback(lua, "resumeSound", function(tag:String) { + if(tag != null && tag.length > 1 && PlayState.instance.modchartSounds.exists(tag)) { + PlayState.instance.modchartSounds.get(tag).play(); + } + }); + Lua_helper.add_callback(lua, "soundFadeIn", function(tag:String, duration:Float, fromValue:Float = 0, toValue:Float = 1) { + if(tag == null || tag.length < 1) { + FlxG.sound.music.fadeIn(duration, fromValue, toValue); + } else if(PlayState.instance.modchartSounds.exists(tag)) { + PlayState.instance.modchartSounds.get(tag).fadeIn(duration, fromValue, toValue); + } + + }); + Lua_helper.add_callback(lua, "soundFadeOut", function(tag:String, duration:Float, toValue:Float = 0) { + if(tag == null || tag.length < 1) { + FlxG.sound.music.fadeOut(duration, toValue); + } else if(PlayState.instance.modchartSounds.exists(tag)) { + PlayState.instance.modchartSounds.get(tag).fadeOut(duration, toValue); + } + }); + Lua_helper.add_callback(lua, "soundFadeCancel", function(tag:String) { + if(tag == null || tag.length < 1) { + if(FlxG.sound.music.fadeTween != null) { + FlxG.sound.music.fadeTween.cancel(); + } + } else if(PlayState.instance.modchartSounds.exists(tag)) { + var theSound:FlxSound = PlayState.instance.modchartSounds.get(tag); + if(theSound.fadeTween != null) { + theSound.fadeTween.cancel(); + PlayState.instance.modchartSounds.remove(tag); + } + } + }); + Lua_helper.add_callback(lua, "getSoundVolume", function(tag:String) { + if(tag == null || tag.length < 1) { + if(FlxG.sound.music != null) { + return FlxG.sound.music.volume; + } + } else if(PlayState.instance.modchartSounds.exists(tag)) { + return PlayState.instance.modchartSounds.get(tag).volume; + } + return PlayState.instance.vocals.volume; + }); + Lua_helper.add_callback(lua, "setSoundVolume", function(tag:String, value:Float) { + if(tag == null || tag.length < 1) { + if(FlxG.sound.music != null) { + FlxG.sound.music.volume = value; + } + } else if(PlayState.instance.modchartSounds.exists(tag)) { + PlayState.instance.modchartSounds.get(tag).volume = value; + } + }); + Lua_helper.add_callback(lua, "getActualSoundVolume", function(tag:String) { + if(tag == null || tag.length < 1) { + if(FlxG.sound.music != null) { + return FlxG.sound.music.volume; + } + } else if(PlayState.instance.modchartSounds.exists(tag)) { + return PlayState.instance.modchartSounds.get(tag).getActualVolume(); + } + return PlayState.instance.vocals.getActualVolume(); + }); + Lua_helper.add_callback(lua, "getSoundTime", function(tag:String) { + if(tag != null && tag.length > 0 && PlayState.instance.modchartSounds.exists(tag)) { + return PlayState.instance.modchartSounds.get(tag).time; + } + return 0; + }); + Lua_helper.add_callback(lua, "setSoundTime", function(tag:String, value:Float) { + if(tag != null && tag.length > 0 && PlayState.instance.modchartSounds.exists(tag)) { + var theSound:FlxSound = PlayState.instance.modchartSounds.get(tag); + if(theSound != null) { + var wasResumed:Bool = theSound.playing; + theSound.pause(); + theSound.time = value; + if(wasResumed) theSound.play(); + } + } + }); + + Lua_helper.add_callback(lua, "close", function(printMessage:Bool) { + //this always closes the first one for some reason!? + if(!gonnaClose) { + if(printMessage) { + luaTrace('Stopping lua script: ' + scriptName); + } + PlayState.instance.closeLuas.push(this); + } + gonnaClose = true; + }); + + Lua_helper.add_callback(lua,"changeDadIcon", function(id:String) { + PlayState.instance.iconP2.useOldSystem(id); + }); + + Lua_helper.add_callback(lua,"changeBFIcon", function(id:String) { + PlayState.instance.iconP1.useOldSystem(id); + }); + + Lua_helper.add_callback(lua,"changeIcon", function(char:String, id:String) { + + trace('run dammit!'); + + if(PlayState.instance.modchartIcons.exists(char)) { + PlayState.instance.modchartIcons.get(char).changeIcon(id); + return; + } + + switch(char) + { + case 'bf' | 'boyfriend' | 'iconP1': + trace('changing bf icon'); + PlayState.instance.iconP1.changeIcon(id); + trace('changed bf icon'); + default: + trace('changing p2 icon'); + PlayState.instance.iconP2.changeIcon(id); + trace('changed p2 icon'); + } + }); + + Lua_helper.add_callback(lua,"softCountdown", function(id:String) { + PlayState.instance.softCountdown(id); + }); + + Lua_helper.add_callback(lua,"fixTrail", function(id:String) { + PlayState.instance.fixTrailShit(id); + }); + + Lua_helper.add_callback(lua,"uncacheObject", function(id:String) { + Assets.cache.clear(id); + }); + + Lua_helper.add_callback(lua,"removeCurrentTrackedAsset", function(id:String) { + Paths.currentTrackedAssets.remove(id); + }); + + Lua_helper.add_callback(lua,"resetTrail", function(id:String) { + getActorByName(id).resetTrail(); + }); + + Lua_helper.add_callback(lua,"generateNumberFromRange", function(min:Float, max:Float) { + return FlxG.random.float(min, max); + }); + + Lua_helper.add_callback(lua,"zoomingFunctionThing", function(?camSpeed:Float = 0.55, ?camZoomMult:Float = 1) { + PlayState.instance.Stage.zoomingFunctionThing(camSpeed, camZoomMult); //only works on concert stage. don't use anywhere else + }); + + Lua_helper.add_callback(lua,"exeStatic", function(?id:String, color:Int = 0) { + PlayState.instance.staticHitMiss(color); + }); + + Lua_helper.add_callback(lua,"changeDadIconNew", function(id:String) { + PlayState.instance.iconP2.changeIcon(id); + }); + + Lua_helper.add_callback(lua,"changeBFIconNew", function(id:String) { + PlayState.instance.iconP1.changeIcon(id); + }); + + Lua_helper.add_callback(lua,"stopIdle", function(id:String, bool:Bool) { + if (PlayState.instance.modchartCharacters.exists(id)) + { + PlayState.instance.modchartCharacters.get(id).stopIdle = bool; + return; + } + getActorByName(id).stopIdle = bool; + }); + + Lua_helper.add_callback(lua,"setDownscroll", function(id:Bool) { + FlxG.save.data.downscroll = id; + }); + + Lua_helper.add_callback(lua,"removeObject", function(id:String) { + var shit:Dynamic = getThing(id); + PlayState.instance.removeObject(shit); + }); + + Lua_helper.add_callback(lua,"addObject", function(id:String) { + var shit:Dynamic = getThing(id); + PlayState.instance.addObject(shit); + }); + + Lua_helper.add_callback(lua,"changeNotes", function(style:String, character:String, ?noteTypeStyle:String = "") { + switch (character) + { + case 'boyfriend' | 'bf': + PlayState.instance.notes.forEach(function(daNote:Note) + { + if (daNote.mustPress) + { + if (daNote.noteType != "") + PlayState.instance.callOnLuas('onNoteChange', [style, noteTypeStyle]); //i really don't wanna use this but I will if I have to + else + daNote.reloadNote(style, noteTypeStyle); + + if (daNote.isSustainNote) + { + if (FlxG.save.data.downscroll) + if(daNote.animation.curAnim.name.endsWith('end') && daNote.prevNote != null) + daNote.y -= daNote.prevNote.height; + else + daNote.y -= daNote.height / 2; + else + daNote.y += daNote.height/2; + } + } + }); + default: + PlayState.instance.notes.forEach(function(daNote:Note) + { + if (!daNote.mustPress) + { + if (daNote.noteType != "") + PlayState.instance.callOnLuas('onNoteChange', [style, noteTypeStyle]); //i really don't wanna use this but I will if I have to + else + daNote.reloadNote(style, noteTypeStyle); + + if (daNote.isSustainNote) + { + if (FlxG.save.data.downscroll) + if(daNote.animation.curAnim.name.endsWith('end') && daNote.prevNote != null) + daNote.y -= daNote.prevNote.height; + else + daNote.y -= daNote.height / 2; + else + daNote.y += daNote.height/2; + } + } + }); + } + }); + + Lua_helper.add_callback(lua,"changeNotes2", function(style:String, character:String, ?noteTypeStyle:String = "") { + for (i in 0...PlayState.instance.unspawnNotes.length) + { + var daNote = PlayState.instance.unspawnNotes[i]; + switch (character) + { + case 'boyfriend' | 'bf': + if (daNote.mustPress) + daNote.reloadNote(style, noteTypeStyle); + default: + if (!daNote.mustPress) + daNote.reloadNote(style, noteTypeStyle); + } + } + }); + + Lua_helper.add_callback(lua,"changeIndividualNotes", function(style:String, i:Int, ?noteTypeStyle:String = "") { + PlayState.instance.unspawnNotes[i].reloadNote(style, noteTypeStyle); + }); + + Lua_helper.add_callback(lua,"doStaticSign", function(lestatic:Int = 0, ?leopa:Bool = true) { + PlayState.instance.doStaticSign(lestatic, leopa); + }); + + Lua_helper.add_callback(lua,"characterZoom", function(id:String, zoomAmount:Float, ?isSenpai:Bool = false) { + if(PlayState.instance.modchartCharacters.exists(id)) { + var spr:Character = PlayState.instance.modchartCharacters.get(id); + spr.setZoom(zoomAmount, isSenpai); + } + else + getActorByName(id).setZoom(zoomAmount, isSenpai); + }); + + Lua_helper.add_callback(lua,"setHudAngle", function (x:Float) { + PlayState.instance.camHUD.angle = x; + }); + + Lua_helper.add_callback(lua,"setHealth", function (heal:Float) { + PlayState.instance.health = heal; + }); + + Lua_helper.add_callback(lua,"minusHealth", function (heal:Float) { + PlayState.instance.health -= heal; + }); + + Lua_helper.add_callback(lua,"setHudPosition", function (x:Int, y:Int) { + PlayState.instance.camHUD.x = x; + PlayState.instance.camHUD.y = y; + }); + + Lua_helper.add_callback(lua,"getHudX", function () { + return PlayState.instance.camHUD.x; + }); + + Lua_helper.add_callback(lua,"getHudY", function () { + return PlayState.instance.camHUD.y; + }); + + Lua_helper.add_callback(lua,"getPlayerStrumsY", function (id:Int) { + return PlayState.instance.strumLineNotes.members[id].y; + }); + + Lua_helper.add_callback(lua,"setCamPosition", function (x:Int, y:Int) { + FlxG.camera.x = x; + FlxG.camera.y = y; + }); + + Lua_helper.add_callback(lua,"shakeCam", function (i:Float, d:Float) { + FlxG.camera.shake(i, d); + }); + + Lua_helper.add_callback(lua,"shakeHUD", function (i:Float, d:Float) { + PlayState.instance.camHUD.shake(i, d); + }); + Lua_helper.add_callback(lua, "fadeCam", function (r:Int = 255,g:Int = 255,b:Int = 255, d:Float, f:Bool, ?camera:String = 'game') { + var c:FlxColor = new FlxColor(); + c.setRGB(r, g, b); + cameraFromString(camera).fade(c, d, f); + }); + + Lua_helper.add_callback(lua, "fadeCamPsych", function(camera:String, color:String, duration:Float, fadeOut:Bool = false, forced:Bool) { + var colorNum:Int = Std.parseInt(color); + if(!color.startsWith('0x')) colorNum = Std.parseInt('0xff' + color); + cameraFromString(camera).fade(colorNum, duration,fadeOut,null,forced); + }); + + Lua_helper.add_callback(lua, "flashCamPsych", function(camera:String, color:String, duration:Float, forced:Bool) { + var colorNum:Int = Std.parseInt(color); + if(!color.startsWith('0x')) colorNum = Std.parseInt('0xff' + color); + cameraFromString(camera).flash(colorNum, duration,null,forced); + }); + + Lua_helper.add_callback(lua, "cameraShake", function(camera:String, intensity:Float, duration:Float) { + cameraFromString(camera).shake(intensity, duration); + }); + + Lua_helper.add_callback(lua, "cameraFlash", function(camera:String, color:String, duration:Float,forced:Bool) { + var colorNum:Int = Std.parseInt(color); + if(!color.startsWith('0x')) colorNum = Std.parseInt('0xff' + color); + cameraFromString(camera).flash(colorNum, duration,null,forced); + }); + Lua_helper.add_callback(lua, "cameraFade", function(camera:String, color:String, duration:Float,forced:Bool) { + var colorNum:Int = Std.parseInt(color); + if(!color.startsWith('0x')) colorNum = Std.parseInt('0xff' + color); + cameraFromString(camera).fade(colorNum, duration,false,null,forced); + }); + + Lua_helper.add_callback(lua, "flashCam", function (r:Int,g:Int,b:Int, d:Float, f:Bool, ?camera:String) { + var c:FlxColor = new FlxColor(); + c.setRGB(r, g, b); + cameraFromString(camera).flash(c, d, f); + }); + + Lua_helper.add_callback(lua, "flashCamHUD", function (r:Int,g:Int,b:Int, d:Float, f:Bool) { + var c:FlxColor = new FlxColor(); + c.setRGB(r, g, b); + PlayState.instance.camHUD.flash(c, d, f); + }); + + Lua_helper.add_callback(lua, "inAndOutCam", function (d:Float, d2:Float, d3:Float, ?camera:String) + { + cameraFromString(camera).fade(FlxColor.WHITE, d, false, function() + { + new FlxTimer().start(d2, function(tmr:FlxTimer) + { + cameraFromString(camera).fade(FlxColor.WHITE, d3, true); + }); + } + ); + }); + + Lua_helper.add_callback(lua,"getCameraX", function () { + return FlxG.camera.x; + }); + + Lua_helper.add_callback(lua,"getCameraY", function () { + return FlxG.camera.y; + }); + + Lua_helper.add_callback(lua,"setCamZoom", function(zoomAmount:Float) { + FlxG.camera.zoom = zoomAmount; + }); + + Lua_helper.add_callback(lua,"addCamZoom", function(zoomAmount:Float) { + FlxG.camera.zoom += zoomAmount; + }); + + Lua_helper.add_callback(lua,"addHudZoom", function(zoomAmount:Float) { + PlayState.instance.camHUD.zoom += zoomAmount; + }); + + Lua_helper.add_callback(lua,"setDefaultCamZoom", function(zoomAmount:Float) { + luaTrace('setDefaultCamZoom is deprecated! Use setProperty("defaultCamZoom", "zoomAmount") instead.', false, true); + PlayState.instance.defaultCamZoom = zoomAmount; + }); + + Lua_helper.add_callback(lua,"setHudZoom", function(zoomAmount:Float) { + luaTrace('setHudZoom is deprecated! Use setProperty("camHUD.zoom", "zoomAmount") instead.', false, true); + PlayState.instance.camHUD.zoom = zoomAmount; + }); + + Lua_helper.add_callback(lua,"changeCamSpeed", function(camFollowSpeed:Float = 0.04) { //i know psych has that camSpeed stuff but I don't feel like changing to Psych's camera system + FlxG.camera.follow(PlayState.instance.camFollow, LOCKON, camFollowSpeed * (30 / (cast (Lib.current.getChildAt(0), Main)).getFPS())); + }); + + Lua_helper.add_callback(lua,"setCamFollow", function(x:Float, y:Float) { + PlayState.instance.camFollowIsOn = false; + PlayState.instance.camFollow.setPosition(x, y); + }); + + Lua_helper.add_callback(lua,"setDelayedCamFollow", function(time:Float,x:Float, y:Float) { + PlayState.instance.camFollowIsOn = false; + + new FlxTimer().start(time, function(tmr:FlxTimer) + { + PlayState.instance.camFollow.setPosition(x, y); + }); + }); + + Lua_helper.add_callback(lua,"sundayFilter", function(bool:Bool) { + PlayState.instance.chromOn = bool; + }); + + Lua_helper.add_callback(lua,"offCamFollow", function(id:String) { + PlayState.instance.camFollowIsOn = false; + }); + + Lua_helper.add_callback(lua,"resetCamFollow", function(id:String) { + PlayState.instance.camFollowIsOn = true; + }); + + Lua_helper.add_callback(lua,"snapCam", function(x:Float, y:Float) { + PlayState.instance.camFollowIsOn = false; + // PlayState.instance.defaultCamFollow = false; + { + var camPosition:FlxObject; + camPosition = new FlxObject(0, 0, 1, 1); + camPosition.setPosition(x, y); + FlxG.camera.focusOn(camPosition.getPosition()); + } + }); + + Lua_helper.add_callback(lua,"resetSnapCam", function(id:String) { + //The string does absolutely nothing + //PlayState.instance.defaultCamFollow = true; + }); + + Lua_helper.add_callback(lua,"resetCamEffects", function(id:String) { + PlayState.instance.camFollowIsOn = true; + }); + + Lua_helper.add_callback(lua,"miscCamFollow", function(camera:String, x:Float, y:Float) { + var camPosition:FlxObject; + camPosition = new FlxObject(0, 0, 1, 1); + camPosition.setPosition(x, y); + + cameraFromString(camera).follow(camPosition, LOCKON, 0.04 * (30 / (cast (Lib.current.getChildAt(0), Main)).getFPS())); + }); + + // strumline + + Lua_helper.add_callback(lua, "setStrumlineY", function(y:Float) + { + PlayState.instance.strumLine.y = y; + }); + + Lua_helper.add_callback(lua,"getArrayLength", function(obj:String) { + var shit:Dynamic = Reflect.getProperty(getInstance(), obj); + + return shit.length; + }); + + Lua_helper.add_callback(lua,"getMapLength", function(obj:String) { + var killMe:Array = obj.split('.'); + var shit:Map = Reflect.getProperty(getInstance(), obj); + + if(killMe.length > 1) + { + var coverMeInPiss:Dynamic = null; + + coverMeInPiss = Reflect.getProperty(getInstance(), killMe[0]); + + for (i in 1...killMe.length-1) { + coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); + } + + shit = Reflect.getProperty(coverMeInPiss, killMe[killMe.length-1]); + } + + var daArray:Array = []; + + for (key in shit.keys()) + daArray.push(key); + + return daArray.length; + }); + + Lua_helper.add_callback(lua,"getMapKeys", function(obj:String) { + var killMe:Array = obj.split('.'); + var shit:Map = Reflect.getProperty(getInstance(), obj); + + if(killMe.length > 1) + { + var coverMeInPiss:Dynamic = null; + + coverMeInPiss = Reflect.getProperty(getInstance(), killMe[0]); + + for (i in 1...killMe.length-1) { + coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); + } + + shit = Reflect.getProperty(coverMeInPiss, killMe[killMe.length-1]); + } + + var daArray:Array = []; + + for (key in shit.keys()) + daArray.push(key); + + return daArray; + }); + + // actors + + Lua_helper.add_callback(lua,"getRenderedNotes", function() { + return PlayState.instance.notes.length; + }); + + Lua_helper.add_callback(lua,"getRenderedNoteX", function(id:Int) { + return PlayState.instance.notes.members[id].x; + }); + + Lua_helper.add_callback(lua,"getRenderedNoteY", function(id:Int) { + return PlayState.instance.notes.members[id].y; + }); + + Lua_helper.add_callback(lua,"getRenderedNoteType", function(id:Int) { + return PlayState.instance.notes.members[id].noteData; + }); + + Lua_helper.add_callback(lua,"isSustain", function(id:Int) { + return PlayState.instance.notes.members[id].isSustainNote; + }); + + Lua_helper.add_callback(lua,"isParentSustain", function(id:Int) { + return PlayState.instance.notes.members[id].prevNote.isSustainNote; + }); + + + Lua_helper.add_callback(lua,"getRenderedNoteParentX", function(id:Int) { + return PlayState.instance.notes.members[id].prevNote.x; + }); + + Lua_helper.add_callback(lua,"getRenderedNoteParentY", function(id:Int) { + return PlayState.instance.notes.members[id].prevNote.y; + }); + + Lua_helper.add_callback(lua,"getRenderedNoteHit", function(id:Int) { + return PlayState.instance.notes.members[id].mustPress; + }); + + Lua_helper.add_callback(lua,"getRenderedNoteCalcX", function(id:Int) { + if (PlayState.instance.notes.members[id].mustPress) + return PlayState.instance.playerStrums.members[Math.floor(Math.abs(PlayState.instance.notes.members[id].noteData))].x; + return PlayState.instance.strumLineNotes.members[Math.floor(Math.abs(PlayState.instance.notes.members[id].noteData))].x; + }); + + Lua_helper.add_callback(lua,"anyNotes", function() { + return PlayState.instance.notes.members.length != 0; + }); + + Lua_helper.add_callback(lua,"getRenderedNoteStrumtime", function(id:Int) { + return PlayState.instance.notes.members[id].strumTime; + }); + + Lua_helper.add_callback(lua,"getRenderedNoteScaleX", function(id:Int) { + return PlayState.instance.notes.members[id].scale.x; + }); + + Lua_helper.add_callback(lua,"setRenderedNotePos", function(x:Float,y:Float, id:Int) { + if (PlayState.instance.notes.members[id] == null) + throw('error! you cannot set a rendered notes position when it doesnt exist! ID: ' + id); + else + { + PlayState.instance.notes.members[id].modifiedByLua = true; + PlayState.instance.notes.members[id].x = x; + PlayState.instance.notes.members[id].y = y; + } + }); + + Lua_helper.add_callback(lua,"setRenderedNoteAlpha", function(alpha:Float, id:Int) { + PlayState.instance.notes.members[id].modifiedByLua = true; + PlayState.instance.notes.members[id].alpha = alpha; + }); + + Lua_helper.add_callback(lua,"setRenderedNoteScale", function(scale:Float, id:Int) { + PlayState.instance.notes.members[id].modifiedByLua = true; + PlayState.instance.notes.members[id].setGraphicSize(Std.int(PlayState.instance.notes.members[id].width * scale)); + }); + + Lua_helper.add_callback(lua,"setRenderedNoteScale", function(scaleX:Int, scaleY:Int, id:Int) { + PlayState.instance.notes.members[id].modifiedByLua = true; + PlayState.instance.notes.members[id].setGraphicSize(scaleX,scaleY); + }); + + Lua_helper.add_callback(lua,"getRenderedNoteWidth", function(id:Int) { + return PlayState.instance.notes.members[id].width; + }); + + + Lua_helper.add_callback(lua,"setRenderedNoteAngle", function(angle:Float, id:Int) { + PlayState.instance.notes.members[id].modifiedByLua = true; + PlayState.instance.notes.members[id].angle = angle; + }); + + Lua_helper.add_callback(lua,"setActorX", function(x:Int,id:String, ?bg:Bool = false) { + var shit:Dynamic = getThing(id); + shit.x = x; + }); + + Lua_helper.add_callback(lua,"setActorScreenCenter", function(id:String, ?thing:String) { + var shit:Dynamic = getThing(id); + shit.screenCenter(); + }); + + Lua_helper.add_callback(lua,"screenCenter", function(id:String, ?thing:String) { //same thing. just for psych + var shit:Dynamic = getThing(id); + shit.screenCenter(); + }); + + Lua_helper.add_callback(lua,"setActorAccelerationX", function(x:Int,id:String) { + getActorByName(id).acceleration.x = x; + }); + + Lua_helper.add_callback(lua,"setActorDragX", function(x:Int,id:String) { + getActorByName(id).drag.x = x; + }); + + Lua_helper.add_callback(lua,"setActorVelocityX", function(x:Int,id:String, ?bg:Bool = false) { + if (bg){ + PlayState.instance.Stage.swagBacks[id].velocity.x = x; + } + else { + getActorByName(id).velocity.x = x; + } + }); + + Lua_helper.add_callback(lua,"playActorAnimation", function(id:String,anim:String,force:Bool = false,reverse:Bool = false, ?frame:Int = 0) { + if (PlayState.instance.modchartCharacters.exists(id)) + { + var shit:Character = PlayState.instance.modchartCharacters.get(id); + shit.playAnim(anim, force, reverse, frame); + } + else + getActorByName(id).playAnim(anim, force, reverse, frame); + }); + + Lua_helper.add_callback(lua,"enablePurpleMiss", function(id:String,toggle:Bool) { + getActorByName(id).doMissThing = toggle; + }); + + Lua_helper.add_callback(lua,"playBGAnimation", function(id:String,anim:String,force:Bool = false,reverse:Bool = false) { + var shit:Dynamic = getThing(id); + shit.animation.play(anim, force, reverse); + }); + + Lua_helper.add_callback(lua,"playBGAnimation2", function(id:String,anim:String,force:Bool = false,reverse:Bool = false) { + getActorByName(id).animation.play(anim, force, reverse); + }); + + Lua_helper.add_callback(lua,"setAltAnim", function(char:String, alt:String){ + switch (char) + { + case 'dad' | 'opponent': + PlayState.instance.dad.altAnim = alt; + case 'gf' | 'girlfriend': + PlayState.instance.gf.altAnim = alt; + default: + PlayState.instance.boyfriend.bfAltAnim = alt; + } + + }); + + Lua_helper.add_callback(lua,"flickerActor", function (id:FlxObject, duration:Float, interval:Float) { + FlxFlicker.flicker(id, duration, interval); + }); + + Lua_helper.add_callback(lua,"setActorAlpha", function(alpha:Float,id:String, ?bg:Bool = false) { + if (bg){ + PlayState.instance.Stage.swagBacks[id].alpha = alpha; + } + else { + getActorByName(id).alpha = alpha; + } + }); + + /*Lua_helper.add_callback(lua,"boomBoom", function(visible:Bool,id:String, id2:Int) { + getActorByName(id).members[id2].visible = visible; + });*/ + + Lua_helper.add_callback(lua,"setActorVisibility", function(alpha:Bool,id:String, ?bg:Bool = false) { + if (bg){ + PlayState.instance.Stage.swagBacks[id].visible = alpha; + } + else { + getActorByName(id).visible = alpha; + } + }); + + Lua_helper.add_callback(lua,"setActorY", function(y:Int,id:String, ?bg:Bool = false) { + if (bg){ + PlayState.instance.Stage.swagBacks[id].y = y; + } + else { + getActorByName(id).y = y; + } + }); + + Lua_helper.add_callback(lua,"setActorAccelerationY", function(y:Int,id:String) { + getActorByName(id).acceleration.y = y; + }); + + Lua_helper.add_callback(lua,"setActorDragY", function(y:Int,id:String) { + getActorByName(id).drag.y = y; + }); + + Lua_helper.add_callback(lua,"setActorVelocityY", function(y:Int,id:String) { + getActorByName(id).velocity.y = y; + }); + + Lua_helper.add_callback(lua,"setActorAngle", function(angle:Int,id:String) { + getActorByName(id).angle = angle; + }); + + Lua_helper.add_callback(lua,"setActorScale", function(scale:Float,id:String, ?bg:Bool = false) { + var shit:Dynamic = getThing(id); + shit.setGraphicSize(Std.int(shit.width * scale)); + shit.updateHitbox(); + }); + + Lua_helper.add_callback(lua, "setActorScaleXY", function(scaleX:Float, scaleY:Float, id:String) + { + getActorByName(id).setGraphicSize(Std.int(getActorByName(id).width * scaleX), Std.int(getActorByName(id).height * scaleY)); + }); + + Lua_helper.add_callback(lua, "setGraphicSize", function(obj:String, x:Int, y:Int = 0) { + if(PlayState.instance.modchartSprites.exists(obj)) { + var shit:ModchartSprite = PlayState.instance.modchartSprites.get(obj); + shit.setGraphicSize(x, y); + shit.updateHitbox(); + return; + } + + var poop:FlxSprite = Reflect.getProperty(getInstance(), obj); + if(poop != null) { + poop.setGraphicSize(x, y); + poop.updateHitbox(); + return; + } + luaTrace('Couldnt find object: ' + obj); + }); + + Lua_helper.add_callback(lua,"stopGFDance", function(stop:Bool) { + PlayState.instance.picoCutscene = stop; + }); + + Lua_helper.add_callback(lua,"isPixel", function(change:Bool) { + PlayState.isPixel = change; + }); + + Lua_helper.add_callback(lua, "setActorFlipX", function(flip:Bool, id:String) + { + getActorByName(id).flipX = flip; + }); + + + Lua_helper.add_callback(lua, "setActorFlipY", function(flip:Bool, id:String) + { + getActorByName(id).flipY = flip; + }); + + Lua_helper.add_callback(lua,"getActorWidth", function (id:String) { + return getActorByName(id).width; + }); + + Lua_helper.add_callback(lua,"getActorHeight", function (id:String) { + return getActorByName(id).height; + }); + + Lua_helper.add_callback(lua,"getActorAlpha", function(id:String) { + return getActorByName(id).alpha; + }); + + Lua_helper.add_callback(lua,"getActorAngle", function(id:String) { + return getActorByName(id).angle; + }); + + Lua_helper.add_callback(lua,"getActorX", function (id:String, ?bg:Bool = false) { + if (bg) + return PlayState.instance.Stage.swagBacks[id].x; + else + return getActorByName(id).x; + }); + + Lua_helper.add_callback(lua,"getCameraZoom", function (id:String) { + return PlayState.instance.defaultCamZoom; + }); + + Lua_helper.add_callback(lua,"getActorY", function (id:String, ?bg:Bool = false) { + if (bg) + return PlayState.instance.Stage.swagBacks[id].y; + else + return getActorByName(id).y; + }); + + Lua_helper.add_callback(lua,"getActorXMidpoint", function (id:String, ?graphic:Bool = false) { + var shit:Dynamic = getThing(id); + + if (graphic) + return shit.getGraphicMidpoint().x; + + return shit.getMidpoint().x; + }); + + Lua_helper.add_callback(lua,"getActorYMidpoint", function (id:String, ?graphic:Bool = false) { + var shit:Dynamic = getThing(id); + + if (graphic) + return shit.getGraphicMidpoint().y; + + return shit.getMidpoint().y; + }); + + Lua_helper.add_callback(lua,"setWindowPos",function(x:Int,y:Int) { + Application.current.window.x = x; + Application.current.window.y = y; + }); + + Lua_helper.add_callback(lua,"getWindowX",function() { + return Application.current.window.x; + }); + + Lua_helper.add_callback(lua,"getWindowY",function() { + return Application.current.window.y; + }); + + Lua_helper.add_callback(lua,"resizeWindow",function(Width:Int,Height:Int) { + Application.current.window.resize(Width,Height); + }); + + Lua_helper.add_callback(lua,"getScreenWidth",function() { + return Application.current.window.display.currentMode.width; + }); + + Lua_helper.add_callback(lua,"getScreenHeight",function() { + return Application.current.window.display.currentMode.height; + }); + + Lua_helper.add_callback(lua,"getWindowWidth",function() { + return Application.current.window.width; + }); + + Lua_helper.add_callback(lua,"getWindowHeight",function() { + return Application.current.window.height; + }); + + // tweens + + Lua_helper.add_callback(lua,"tweenCameraPos", function(toX:Int, toY:Int, time:Float, onComplete:String) { + FlxTween.tween(FlxG.camera, {x: toX, y: toY}, time, {ease: FlxEase.linear, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenCameraAngle", function(toAngle:Float, time:Float, onComplete:String) { + FlxTween.tween(FlxG.camera, {angle:toAngle}, time, {ease: FlxEase.linear, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenCameraZoom", function(toZoom:Float, time:Float, onComplete:String) { + FlxTween.tween(FlxG.camera, {zoom:toZoom}, time, {ease: FlxEase.linear, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenHudPos", function(toX:Int, toY:Int, time:Float, onComplete:String) { + FlxTween.tween(PlayState.instance.camHUD, {x: toX, y: toY}, time, {ease: FlxEase.linear, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenHudAngle", function(toAngle:Float, time:Float, onComplete:String) { + FlxTween.tween(PlayState.instance.camHUD, {angle:toAngle}, time, {ease: FlxEase.linear, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenHudZoom", function(toZoom:Float, time:Float, onComplete:String) { + FlxTween.tween(PlayState.instance.camHUD, {zoom:toZoom}, time, {ease: FlxEase.linear, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenPos", function(id:String, toX:Int, toY:Int, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {x: toX, y: toY}, time, {ease: FlxEase.linear, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenPosQuad", function(id:String, toX:Int, toY:Int, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {x: toX, y: toY}, time, {ease: FlxEase.quadInOut, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenPosXAngle", function(id:String, toX:Int, toAngle:Float, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {x: toX, angle: toAngle}, time, {ease: FlxEase.linear, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenPosYAngle", function(id:String, toY:Int, toAngle:Float, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {y: toY, angle: toAngle}, time, {ease: FlxEase.linear, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenAngle", function(id:String, toAngle:Int, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {angle: toAngle}, time, {ease: FlxEase.linear, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenCameraPosOut", function(toX:Int, toY:Int, time:Float, onComplete:String) { + FlxTween.tween(FlxG.camera, {x: toX, y: toY}, time, {ease: FlxEase.cubeOut, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenCameraAngleOut", function(toAngle:Float, time:Float, onComplete:String) { + FlxTween.tween(FlxG.camera, {angle:toAngle}, time, {ease: FlxEase.cubeOut, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenCameraZoomOut", function(toZoom:Float, time:Float, ease:String, onComplete:String) { + FlxTween.tween(FlxG.camera, {zoom:toZoom}, time, {ease: getFlxEaseByString(ease), onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenHudPosOut", function(toX:Int, toY:Int, time:Float, onComplete:String) { + FlxTween.tween(PlayState.instance.camHUD, {x: toX, y: toY}, time, {ease: FlxEase.cubeOut, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenHudAngleOut", function(toAngle:Float, time:Float, onComplete:String) { + FlxTween.tween(PlayState.instance.camHUD, {angle:toAngle}, time, {ease: FlxEase.cubeOut, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenHudZoomOut", function(toZoom:Float, time:Float, onComplete:String) { + FlxTween.tween(PlayState.instance.camHUD, {zoom:toZoom}, time, {ease: FlxEase.cubeOut, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenPosOut", function(id:String, toX:Int, toY:Int, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {x: toX, y: toY}, time, {ease: FlxEase.cubeOut, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenPosXAngleOut", function(id:String, toX:Int, toAngle:Float, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {x: toX, angle: toAngle}, time, {ease: FlxEase.cubeOut, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenPosYAngleOut", function(id:String, toY:Int, toAngle:Float, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {y: toY, angle: toAngle}, time, {ease: FlxEase.cubeOut, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenAngleOut", function(id:String, toAngle:Int, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {angle: toAngle}, time, {ease: FlxEase.cubeOut, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenCameraPosIn", function(toX:Int, toY:Int, time:Float, onComplete:String) { + FlxTween.tween(FlxG.camera, {x: toX, y: toY}, time, {ease: FlxEase.cubeIn, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenCameraAngleIn", function(toAngle:Float, time:Float, onComplete:String) { + FlxTween.tween(FlxG.camera, {angle:toAngle}, time, {ease: FlxEase.cubeIn, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenCameraZoomIn", function(toZoom:Float, time:Float, ease:String, onComplete:String) { + FlxTween.tween(FlxG.camera, {zoom:toZoom}, time, {ease: getFlxEaseByString(ease), onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenHudPosIn", function(toX:Int, toY:Int, time:Float, onComplete:String) { + FlxTween.tween(PlayState.instance.camHUD, {x: toX, y: toY}, time, {ease: FlxEase.cubeIn, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenHudAngleIn", function(toAngle:Float, time:Float, onComplete:String) { + FlxTween.tween(PlayState.instance.camHUD, {angle:toAngle}, time, {ease: FlxEase.cubeIn, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenHudZoomIn", function(toZoom:Float, time:Float, onComplete:String) { + FlxTween.tween(PlayState.instance.camHUD, {zoom:toZoom}, time, {ease: FlxEase.cubeIn, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,["camera"]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenPosIn", function(id:String, toX:Int, toY:Int, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {x: toX, y: toY}, time, {ease: FlxEase.cubeIn, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenPosXAngleIn", function(id:String, toX:Int, toAngle:Float, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {x: toX, angle: toAngle}, time, {ease: FlxEase.cubeIn, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenPosYAngleIn", function(id:String, toY:Int, toAngle:Float, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {y: toY, angle: toAngle}, time, {ease: FlxEase.cubeIn, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenAngleIn", function(id:String, toAngle:Int, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {angle: toAngle}, time, {ease: FlxEase.cubeIn, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenFadeIn", function(id:String, toAlpha:Float, time:Float, onComplete:String) { + FlxTween.tween(getActorByName(id), {alpha: toAlpha}, time, {ease: FlxEase.circIn, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenFadeInBG", function(id:String, toAlpha:Float, time:Float, onComplete:String) { + FlxTween.tween(PlayState.instance.Stage.swagBacks[id], {alpha: toAlpha}, time, {ease: FlxEase.circIn, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenFadeOut", function(id:String, toAlpha:Float, time:Float, ease:String, onComplete:String) { + FlxTween.tween(getActorByName(id), {alpha: toAlpha}, time, {ease: getFlxEaseByString(ease), onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenFadeOutBG", function(id:String, toAlpha:Float, time:Float, onComplete:String) { + FlxTween.tween(PlayState.instance.Stage.swagBacks[id], {alpha: toAlpha}, time, {ease: FlxEase.circOut, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenFadeOutOneShot", function(id:String, toAlpha:Float, time:Float) { + FlxTween.tween(getActorByName(id), {alpha: toAlpha}, time, {type: FlxTweenType.ONESHOT}); + }); + + Lua_helper.add_callback(lua,"tweenColor", function(id:String, time:Float, initColor:FlxColor, finalColor:FlxColor) { + var shit:Dynamic = getThing(id); + FlxTween.color(shit, time, initColor, finalColor); + }); + + Lua_helper.add_callback(lua, "RGBColor", function (r:Int,g:Int,b:Int, alpha:Int = 255) { + return FlxColor.fromRGB(r, g, b, alpha); + }); + + Lua_helper.add_callback(lua,"updateHealthbar", function(dadColor:String = "", bfColor:String = ""){ + var opponent:String; + var player:String; + + if (dadColor == "") + opponent = PlayState.instance.dad.iconColor; + else + opponent = dadColor; + + if (bfColor == "") + player = PlayState.instance.boyfriend.iconColor; + else + player = bfColor; + + PlayState.instance.healthBar.createFilledBar(FlxColor.fromString('#' + opponent), FlxColor.fromString('#' + player)); + PlayState.instance.healthBar.updateBar(); + }); + + Lua_helper.add_callback(lua, "getStageXOffsets", function (char:String, value:String) { + switch (char) + { + case 'boyfriend' | 'bf': + return (value == 'y' ? PlayState.instance.Stage.bfYOffset : PlayState.instance.Stage.bfXOffset); + case 'gf': + return (value == 'y' ? PlayState.instance.Stage.gfYOffset : PlayState.instance.Stage.gfXOffset); + default: + return (value == 'y' ? PlayState.instance.Stage.dadYOffset : PlayState.instance.Stage.dadXOffset); + } + }); + + Lua_helper.add_callback(lua,"changeHue", function(id:String, hue:Int) { + var newShader:ColorSwap = new ColorSwap(); + var shit:Dynamic = getThing(id); + shit.shader = newShader.shader; + newShader.hue = hue / 360; + }); + + Lua_helper.add_callback(lua,"changeGroupHue", function(obj:String, hue:Int) { + var shit:Dynamic = Reflect.getProperty(getInstance(), obj); + + shit.forEach(function(thing:Dynamic) + { + var newShader:ColorSwap = new ColorSwap(); + newShader.hue = hue / 360; + thing.shader = newShader.shader; + }); + }); + + Lua_helper.add_callback(lua,"changeGroupMemberHue", function(obj:String, index:Int, hue:Int) { + var shit:Dynamic = Reflect.getProperty(getInstance(), obj)[index]; + + if(Std.isOfType(Reflect.getProperty(getInstance(), obj), FlxTypedGroup)) + shit = Reflect.getProperty(getInstance(), obj).members[index]; + + var newShader:ColorSwap = new ColorSwap(); + newShader.hue = hue / 360; + shit.shader = newShader.shader; + + }); + + Lua_helper.add_callback(lua,"playStrumAnim", function(isDad:Bool, id:Int, ?time:Float = 0.15) { + PlayState.instance.StrumPlayAnim(isDad, id, time); + }); + + //a bunch of psych stuff + Lua_helper.add_callback(lua,"tweenAnglePsych", function(id:String, toAngle:Int, time:Float, ease:String, onComplete:String, ?bg:Bool = false) { + var shit:Dynamic = getThing(id); + FlxTween.tween(shit, {angle: toAngle}, time, {ease: getFlxEaseByString(ease), onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenXPsych", function(id:String, toX:Int, time:Float, ease:String, onComplete:String, ?bg:Bool = false) { + var shit:Dynamic = getThing(id); + FlxTween.tween(shit, {x: toX}, time, {ease: getFlxEaseByString(ease), onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenYPsych", function(id:String, toY:Int, time:Float, ease:String, onComplete:String, ?bg:Bool = false) { + var shit:Dynamic = getThing(id); + FlxTween.tween(shit, {y: toY}, time, {ease: getFlxEaseByString(ease), onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenZoomPsych", function(id:String, toZoom:Int, time:Float, ease:String, onComplete:String, ?bg:Bool = false) { + var shit:Dynamic = getThing(id); + FlxTween.tween(shit, {zoom: toZoom}, time, {ease: getFlxEaseByString(ease), onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenScale", function(id:String, scale:Float, time:Float, ease:String, onComplete:String, ?bg:Bool = false) { + var shit:Dynamic = getThing(id); + FlxTween.tween(shit, {"scale.x": scale, "scale.y": scale}, time, {ease: getFlxEaseByString(ease), onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenScaleXY", function(id:String, scaleX:Float, scaleY:Float, time:Float, ease:String, onComplete:String, ?bg:Bool = false) { + var shit:Dynamic = getThing(id); + FlxTween.tween(shit, {"scale.x": scaleX, "scale.y": scaleY}, time, {ease: getFlxEaseByString(ease), onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua,"tweenAlpha", function(id:String, toAlpha:Float, time:Float, ease:String, onComplete:String) { + var shit:Dynamic = getThing(id); + FlxTween.tween(shit, {alpha: toAlpha}, time, {ease: getFlxEaseByString(ease), onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {call(onComplete,[id]);}}}); + }); + + Lua_helper.add_callback(lua, "doTweenX", function(tag:String, vars:String, value:Dynamic, duration:Float, ease:String) { + var penisExam:Dynamic = getThing(vars); + cancelTween(tag); + if(penisExam != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(penisExam, {x: value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } else { + luaTrace('Couldnt find object: ' + vars); + } + }); + + Lua_helper.add_callback(lua, "doTweenY", function(tag:String, vars:String, value:Dynamic, duration:Float, ease:String) { + var penisExam:Dynamic = getThing(vars); + cancelTween(tag); + if(penisExam != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(penisExam, {y: value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } else { + luaTrace('Couldnt find object: ' + vars); + } + }); + Lua_helper.add_callback(lua, "doTweenAngle", function(tag:String, vars:String, value:Dynamic, duration:Float, ease:String) { + var penisExam:Dynamic = getThing(vars); + cancelTween(tag); + if(penisExam != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(penisExam, {angle: value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } else { + luaTrace('Couldnt find object: ' + vars); + } + }); + + Lua_helper.add_callback(lua, "doTweenScale", function(tag:String, vars:String, value:Dynamic, value2:Dynamic, duration:Float, ease:String) { + var penisExam:Dynamic = getThing(vars); + cancelTween(tag); + if(penisExam != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(penisExam, {"scale.x": value, "scale.y": value2}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } else { + luaTrace('Couldnt find object: ' + vars); + } + }); + + Lua_helper.add_callback(lua, "doTweenScaleX", function(tag:String, vars:String, value:Dynamic, duration:Float, ease:String) { + var penisExam:Dynamic = getThing(vars); + cancelTween(tag); + if(penisExam != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(penisExam, {"scale.x": value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } else { + luaTrace('Couldnt find object: ' + vars); + } + }); + + Lua_helper.add_callback(lua, "doTweenScaleY", function(tag:String, vars:String, value:Dynamic, duration:Float, ease:String) { + var penisExam:Dynamic = getThing(vars); + cancelTween(tag); + if(penisExam != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(penisExam, {"scale.y": value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } else { + luaTrace('Couldnt find object: ' + vars); + } + }); + + + Lua_helper.add_callback(lua, "doTweenAlpha", function(tag:String, vars:String, value:Dynamic, duration:Float, ease:String) { + var penisExam:Dynamic = getThing(vars); + cancelTween(tag); + if(penisExam != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(penisExam, {alpha: value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } else { + luaTrace('Couldnt find object: ' + vars); + } + }); + Lua_helper.add_callback(lua, "doTweenZoom", function(tag:String, vars:String, value:Dynamic, duration:Float, ease:String) { + var penisExam:Dynamic = getThing(vars); + cancelTween(tag); + if(penisExam != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(penisExam, {zoom: value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } else { + luaTrace('Couldnt find object: ' + vars); + } + }); + Lua_helper.add_callback(lua, "doTweenColor", function(tag:String, vars:String, targetColor:String, duration:Float, ease:String) { + var penisExam:Dynamic = getThing(vars); + cancelTween(tag); + if(penisExam != null) { + var color:Int = Std.parseInt(targetColor); + if(!targetColor.startsWith('0x')) color = Std.parseInt('0xff' + targetColor); + + var curColor:FlxColor = penisExam.color; + curColor.alphaFloat = penisExam.alpha; + PlayState.instance.modchartTweens.set(tag, FlxTween.color(penisExam, duration, curColor, color, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.modchartTweens.remove(tag); + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + } + })); + } else { + luaTrace('Couldnt find object: ' + vars); + } + }); + + Lua_helper.add_callback(lua, "startCountdown", function(variable:String) { + PlayState.instance.startCountdown(); + }); + + Lua_helper.add_callback(lua, "startSong", function(variable:String) { + PlayState.instance.startSong(); + }); + + Lua_helper.add_callback(lua, "playCutscene", function(video:String) { + PlayState.instance.playCutscene(video); + }); + + Lua_helper.add_callback(lua, "endSong", function(hmm:String) { + PlayState.instance.KillNotes(); + PlayState.instance.endSong(); + }); + + //idk if I wanna add events. alright I added the ones that are usable without that much tinkering. + Lua_helper.add_callback(lua, "triggerEvent", function(name:String, arg1:Dynamic, arg2:Dynamic) { + if (name == 'Change Character') + { + switch (arg1) + { + case 0: changeBFAuto(arg2); + case 1: changeDadAuto(arg2); + case 2: changeGFAuto(arg2); + } + + return; + } + + var value1:String = arg1; + var value2:String = arg2; + PlayState.instance.triggerEventNote(name, value1, value2); + }); + + Lua_helper.add_callback(lua, "getPropertyPsych", function(variable:String) { + var killMe:Array = variable.split('.'); + if(killMe.length > 1) + { + var coverMeInPiss:Dynamic = null; + if(PlayState.instance.modchartSprites.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartSprites.get(killMe[0]); + else if(PlayState.instance.modchartIcons.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartIcons.get(killMe[0]); + else if(PlayState.instance.modchartCharacters.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartCharacters.get(killMe[0]); + else if(PlayState.instance.modchartTexts.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartTexts.get(killMe[0]); + else if(PlayState.instance.Stage.swagBacks.exists(killMe[0])) + coverMeInPiss = PlayState.instance.Stage.swagBacks.get(killMe[0]); + else + coverMeInPiss = Reflect.getProperty(getInstance(), killMe[0]); + + for (i in 1...killMe.length-1) { + coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); + } + return Reflect.getProperty(coverMeInPiss, killMe[killMe.length-1]); + } + return Reflect.getProperty(getInstance(), variable); + }); + + Lua_helper.add_callback(lua, "setPropertyPsych", function(variable:String, value:Dynamic) { + var killMe:Array = variable.split('.'); + if(killMe.length > 1) { + var coverMeInPiss:Dynamic = null; + if(PlayState.instance.modchartSprites.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartSprites.get(killMe[0]); + else if(PlayState.instance.modchartTexts.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartTexts.get(killMe[0]); + else if(PlayState.instance.modchartIcons.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartIcons.get(killMe[0]); + else if(PlayState.instance.modchartCharacters.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartCharacters.get(killMe[0]); + else if(PlayState.instance.Stage.swagBacks.exists(killMe[0])) + coverMeInPiss = PlayState.instance.Stage.swagBacks.get(killMe[0]); + else + coverMeInPiss = Reflect.getProperty(getInstance(), killMe[0]); + + for (i in 1...killMe.length-1) { + coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); + } + return Reflect.setProperty(coverMeInPiss, killMe[killMe.length-1], value); + } + return Reflect.setProperty(getInstance(), variable, value); + }); + + //i have no idea why I added the Psych in the first place + Lua_helper.add_callback(lua, "getProperty", function(variable:String) { + var killMe:Array = variable.split('.'); + if(killMe.length > 1) + { + var coverMeInPiss:Dynamic = null; + if(PlayState.instance.modchartSprites.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartSprites.get(killMe[0]); + else if(PlayState.instance.modchartIcons.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartIcons.get(killMe[0]); + else if(PlayState.instance.modchartCharacters.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartCharacters.get(killMe[0]); + else if(PlayState.instance.modchartTexts.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartTexts.get(killMe[0]); + else if(PlayState.instance.Stage.swagBacks.exists(killMe[0])) + coverMeInPiss = PlayState.instance.Stage.swagBacks.get(killMe[0]); + else + coverMeInPiss = Reflect.getProperty(getInstance(), killMe[0]); + + for (i in 1...killMe.length-1) { + coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); + } + return Reflect.getProperty(coverMeInPiss, killMe[killMe.length-1]); + } + return Reflect.getProperty(getInstance(), variable); + }); + + Lua_helper.add_callback(lua, "setProperty", function(variable:String, value:Dynamic) { + var killMe:Array = variable.split('.'); + if(killMe.length > 1) { + var coverMeInPiss:Dynamic = null; + if(PlayState.instance.modchartSprites.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartSprites.get(killMe[0]); + else if(PlayState.instance.modchartTexts.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartTexts.get(killMe[0]); + else if(PlayState.instance.modchartIcons.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartIcons.get(killMe[0]); + else if(PlayState.instance.modchartCharacters.exists(killMe[0])) + coverMeInPiss = PlayState.instance.modchartCharacters.get(killMe[0]); + else if(PlayState.instance.Stage.swagBacks.exists(killMe[0])) + coverMeInPiss = PlayState.instance.Stage.swagBacks.get(killMe[0]); + else + coverMeInPiss = Reflect.getProperty(getInstance(), killMe[0]); + + for (i in 1...killMe.length-1) { + coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); + } + return Reflect.setProperty(coverMeInPiss, killMe[killMe.length-1], value); + } + return Reflect.setProperty(getInstance(), variable, value); + }); + + Lua_helper.add_callback(lua, "doGroupTweenY", function(tag:String, obj:String, index:Int, value:Dynamic, duration:Float, ease:String) { + //if this works i might use this over the noteTween stuff. though realistically there aren't many other flxgroups. + cancelTween(tag); + var shit:Dynamic = Reflect.getProperty(getInstance(), obj); + var testicle:Dynamic = null; + + shit.forEach(function(spr:Dynamic) + { + if (spr.ID == index) + testicle = spr; + }); + + if(testicle != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(testicle, {y: value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } + }); + + Lua_helper.add_callback(lua, "getPropertyFromGroup", function(obj:String, index:Int, variable:Dynamic) { + if (PlayState.instance.Stage.swagGroup.exists(obj)) + { + var shit = PlayState.instance.Stage.swagGroup.get(obj); + + if(Std.isOfType(shit, FlxTypedGroup)) { + return getGroupStuff(shit.members[index], variable); + } + } + + if(Std.isOfType(Reflect.getProperty(getInstance(), obj), FlxTypedGroup)) { + return getGroupStuff(Reflect.getProperty(getInstance(), obj).members[index], variable); + } + + var leArray:Dynamic = Reflect.getProperty(getInstance(), obj); + var killMe:Array = obj.split('.'); + + if (killMe.length > 1) //all this just so I can get a character's camera position + { + var coverMeInPiss:Dynamic = null; + coverMeInPiss = Reflect.getProperty(getInstance(), killMe[0]); + + for (i in 1...killMe.length-1) { + coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); + } + + leArray = Reflect.getProperty(coverMeInPiss, killMe[killMe.length-1]); + } + + if(leArray != null) { + if(Type.typeof(variable) == ValueType.TInt) { + return leArray[variable]; + } + + leArray = Reflect.getProperty(getInstance(), obj)[index]; + return getGroupStuff(leArray, variable); + } + luaTrace("Object #" + index + " from group: " + obj + " doesn't exist!"); + return null; + }); + + Lua_helper.add_callback(lua, "setPropertyFromGroup", function(obj:String, index:Int, variable:Dynamic, value:Dynamic) { + + if (PlayState.instance.Stage.swagGroup.exists(obj)) + { + trace('swagGroup found'); + var shit = PlayState.instance.Stage.swagGroup.get(obj); + + if(Std.isOfType(shit, FlxTypedGroup)) { + trace('is a FlxTypedGroup'); + return setGroupStuff(shit.members[index], variable, value); + } + } + + if(Std.isOfType(Reflect.getProperty(getInstance(), obj), FlxTypedGroup)) { + setGroupStuff(Reflect.getProperty(getInstance(), obj).members[index], variable, value); + return; + } + + var leArray:Dynamic = Reflect.getProperty(getInstance(), obj)[index]; + if(leArray != null) { + if(Type.typeof(variable) == ValueType.TInt) { + leArray[variable] = value; + return; + } + setGroupStuff(leArray, variable, value); + } + }); + + Lua_helper.add_callback(lua, "getPropertyFromClass", function(classVar:String, variable:String) { + var killMe:Array = variable.split('.'); + if(killMe.length > 1) { + var coverMeInPiss:Dynamic = Reflect.getProperty(Type.resolveClass(classVar), killMe[0]); + for (i in 1...killMe.length-1) { + coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); + } + return Reflect.getProperty(coverMeInPiss, killMe[killMe.length-1]); + } + return Reflect.getProperty(Type.resolveClass(classVar), variable); + }); + Lua_helper.add_callback(lua, "setPropertyFromClass", function(classVar:String, variable:String, value:Dynamic) { + var killMe:Array = variable.split('.'); + if(killMe.length > 1) { + var coverMeInPiss:Dynamic = Reflect.getProperty(Type.resolveClass(classVar), killMe[0]); + for (i in 1...killMe.length-1) { + coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); + } + return Reflect.setProperty(coverMeInPiss, killMe[killMe.length-1], value); + } + return Reflect.setProperty(Type.resolveClass(classVar), variable, value); + }); + + Lua_helper.add_callback(lua, "arrayContains", function(obj:String, value:Dynamic) { + var leArray:Dynamic = Reflect.getProperty(getInstance(), obj); + + if (leArray.contains(value)) + return true; + + return false; + }); + + Lua_helper.add_callback(lua, "debugPrint", function(text1:Dynamic = '', text2:Dynamic = '', text3:Dynamic = '', text4:Dynamic = '', text5:Dynamic = '') { + if (text1 == null) text1 = ''; + if (text2 == null) text2 = ''; + if (text3 == null) text3 = ''; + if (text4 == null) text4 = ''; + if (text5 == null) text5 = ''; + luaTrace('' + text1 + text2 + text3 + text4 + text5, true, false); + }); + + Lua_helper.add_callback(lua, "setObjectCamera", function(obj:String, camera:String = '', ?index:Int = null) { + if (PlayState.instance.modchartSprites.exists(obj)) { + PlayState.instance.modchartSprites.get(obj).cameras = [cameraFromString(camera)]; + return true; + } + else if(PlayState.instance.modchartTexts.exists(obj)) { + PlayState.instance.modchartTexts.get(obj).cameras = [cameraFromString(camera)]; + return true; + } + else if (PlayState.instance.modchartIcons.exists(obj)) { + PlayState.instance.modchartIcons.get(obj).cameras = [cameraFromString(camera)]; + return true; + } + else if (PlayState.instance.Stage.swagBacks.exists(obj)) { + PlayState.instance.Stage.setObjectCamera(obj, camera); + return true; + } + else if (Stage.instance.swagBacks.exists(obj)) { + Stage.instance.setObjectCamera(obj, camera); + return true; + } + else + { + var object:Dynamic = Reflect.getProperty(getInstance(), obj); + if(object != null) { + + if (index != null) + object[index].cameras = [cameraFromString(camera)]; + else + object.cameras = [cameraFromString(camera)]; + + return true; + } + } + luaTrace("Object " + obj + " doesn't exist!"); + return false; + }); + + Lua_helper.add_callback(lua, "getRandomInt", function(min:Int, max:Int = FlxMath.MAX_VALUE_INT, exclude:String = '') { + var excludeArray:Array = exclude.split(','); + var toExclude:Array = []; + for (i in 0...excludeArray.length) + { + toExclude.push(Std.parseInt(excludeArray[i].trim())); + } + return FlxG.random.int(min, max, toExclude); + }); + Lua_helper.add_callback(lua, "getRandomFloat", function(min:Float, max:Float = 1, exclude:String = '') { + var excludeArray:Array = exclude.split(','); + var toExclude:Array = []; + for (i in 0...excludeArray.length) + { + toExclude.push(Std.parseFloat(excludeArray[i].trim())); + } + return FlxG.random.float(min, max, toExclude); + }); + Lua_helper.add_callback(lua, "getRandomBool", function(chance:Float = 50) { + return FlxG.random.bool(chance); + }); + + Lua_helper.add_callback(lua, "setBlendMode", function(obj:String, blend:String = '') { + var shit:Dynamic = getThing(obj); + if(shit != null) { + shit.blend = blendModeFromString(blend); + return true; + } + luaTrace("Object " + obj + " doesn't exist!"); + return false; + }); + + Lua_helper.add_callback(lua, "keyJustPressed", function(name:String) { + var key:Bool = false; + switch(name) { + case 'left': key = PlayState.instance.getControl('LEFT_P'); + case 'down': key = PlayState.instance.getControl('DOWN_P'); + case 'up': key = PlayState.instance.getControl('UP_P'); + case 'right': key = PlayState.instance.getControl('RIGHT_P'); + case 'accept': key = PlayState.instance.getControl('ACCEPT'); + case 'back': key = PlayState.instance.getControl('BACK'); + case 'pause': key = PlayState.instance.getControl('PAUSE'); + case 'reset': key = PlayState.instance.getControl('RESET'); + case 'space': key = FlxG.keys.justPressed.SPACE;//an extra key for convinience + } + return key; + }); + + Lua_helper.add_callback(lua, "keyPressed", function(name:String) { + var key:Bool = false; + switch(name) { + case 'left': key = PlayState.instance.getControl('LEFT'); + case 'down': key = PlayState.instance.getControl('DOWN'); + case 'up': key = PlayState.instance.getControl('UP'); + case 'right': key = PlayState.instance.getControl('RIGHT'); + case 'space': key = FlxG.keys.pressed.SPACE;//an extra key for convinience + } + return key; + }); + + Lua_helper.add_callback(lua, "keyReleased", function(name:String) { + var key:Bool = false; + switch(name) { + case 'left': key = PlayState.instance.getControl('LEFT_R'); + case 'down': key = PlayState.instance.getControl('DOWN_R'); + case 'up': key = PlayState.instance.getControl('UP_R'); + case 'right': key = PlayState.instance.getControl('RIGHT_R'); + case 'space': key = FlxG.keys.justReleased.SPACE;//an extra key for convinience + } + return key; + }); + + Lua_helper.add_callback(lua, "mouseClicked", function(button:String) { + var boobs = FlxG.mouse.justPressed; + switch(button){ + case 'middle': + boobs = FlxG.mouse.justPressedMiddle; + case 'right': + boobs = FlxG.mouse.justPressedRight; + } + + + return boobs; + }); + Lua_helper.add_callback(lua, "mousePressed", function(button:String) { + var boobs = FlxG.mouse.pressed; + switch(button){ + case 'middle': + boobs = FlxG.mouse.pressedMiddle; + case 'right': + boobs = FlxG.mouse.pressedRight; + } + return boobs; + }); + Lua_helper.add_callback(lua, "mouseReleased", function(button:String) { + var boobs = FlxG.mouse.justReleased; + switch(button){ + case 'middle': + boobs = FlxG.mouse.justReleasedMiddle; + case 'right': + boobs = FlxG.mouse.justReleasedRight; + } + return boobs; + }); + + Lua_helper.add_callback(lua, "runTimer", function(tag:String, time:Float = 1, loops:Int = 1) { + cancelTimer(tag); + PlayState.instance.modchartTimers.set(tag, new FlxTimer().start(time, function(tmr:FlxTimer) { + if(tmr.finished) { + PlayState.instance.modchartTimers.remove(tag); + } + PlayState.instance.callOnLuas('onTimerCompleted', [tag, tmr.loops, tmr.loopsLeft]); + //trace('Timer Completed: ' + tag); + }, loops)); + }); + + Lua_helper.add_callback(lua, "cancelTimer", function(tag:String) { + cancelTimer(tag); + }); + + Lua_helper.add_callback(lua, "cancelTween", function(tag:String) { + cancelTween(tag); + }); + + //used for testing. might as well leave it here. + Lua_helper.add_callback(lua, "indexOf", function(tag:String, thing:String, ?last:Bool) { + if (last) + return tag.lastIndexOf(thing); + + return tag.indexOf(thing); + }); + + Lua_helper.add_callback(lua, "addCharacterToList", function(name:String, type:String) { + var charType:Int = 0; + switch(type.toLowerCase()) { + case 'dad': charType = 1; + case 'gf' | 'girlfriend': charType = 2; + } + PlayState.preloadChar = new Character(0, 0, name); + }); + + Lua_helper.add_callback(lua, "precacheSound", function(name:String) { + return name; //lol + }); + + Lua_helper.add_callback(lua, "precacheImage", function(name:String) { + return name; //lol + }); + + Lua_helper.add_callback(lua, "makeLuaSprite", function(tag:String, image:String, x:Float, y:Float, ?antialiasing:Bool = true) { + tag = tag.replace('.', ''); + resetSpriteTag(tag); + var leSprite:ModchartSprite = new ModchartSprite(x, y); + if(image != null && image.length > 0) { + var rawPic:Dynamic; + + if (!Paths.currentTrackedAssets.exists(image)) + Paths.cacheImage(image); + + rawPic = Paths.currentTrackedAssets.get(image); + + leSprite.loadGraphic(rawPic); + } + leSprite.antialiasing = antialiasing; + PlayState.instance.modchartSprites.set(tag, leSprite); + leSprite.active = true; + }); + + Lua_helper.add_callback(lua, "makeAnimatedLuaSprite", function(tag:String, image:String, x:Float, y:Float,spriteType:String="sparrow", width:Int = 0, height:Int = 0) { + tag = tag.replace('.', ''); + resetSpriteTag(tag); + var leSprite:ModchartSprite = new ModchartSprite(x, y); + + switch(spriteType.toLowerCase()){ + + case "texture" | "textureatlas"|"tex": + leSprite.frames = AtlasFrameMaker.construct(image); + + case "packer" |"packeratlas"|"pac": + leSprite.frames = Paths.getPackerAtlas(image); + case "xmlless": //for the ones like the pixel notes and stuff. + { + var rawPic:Dynamic; + + if (!Paths.currentTrackedAssets.exists(image)) + Paths.cacheImage(image); + + rawPic = Paths.currentTrackedAssets.get(image); + leSprite.loadGraphic(rawPic, true, width, height); + } + default: + { + var rawPic:Dynamic; + var rawXml:String; + + if (!Paths.currentTrackedAssets.exists(image)) + Paths.cacheImage(image); + + rawPic = Paths.currentTrackedAssets.get(image); + + if (FileSystem.exists(FileSystem.absolutePath("assets/shared/images/"+image+".xml"))) + rawXml = File.getContent(FileSystem.absolutePath("assets/shared/images/"+image+".xml")); + else + rawXml = File.getContent(Paths.xmlNew('images/' + image)); + + leSprite.frames = FlxAtlasFrames.fromSparrow(rawPic,rawXml); + } + } + + PlayState.instance.modchartSprites.set(tag, leSprite); + }); + + Lua_helper.add_callback(lua, "makeAnimatedLuaSprite2", function(tag:String, image:String,width:Int, height:Int) { + tag = tag.replace('.', ''); + var leSprite:ModchartSprite = new ModchartSprite(0, 0); + + var rawPic:Dynamic; + + if (!Paths.currentTrackedAssets.exists(image)) + Paths.cacheImage(image); + + rawPic = Paths.currentTrackedAssets.get(image); + leSprite.loadGraphic(rawPic, true, width, height); + + PlayState.instance.modchartSprites.set(tag, leSprite); + }); + + Lua_helper.add_callback(lua, "makeGraphic", function(obj:String, width:Int, height:Int, color:String) { + var colorNum:Int = Std.parseInt(color); + if(!color.startsWith('0x')) colorNum = Std.parseInt('0xff' + color); + + if(PlayState.instance.modchartSprites.exists(obj)) { + PlayState.instance.modchartSprites.get(obj).makeGraphic(width, height, colorNum); + return; + } + + var object:FlxSprite = Reflect.getProperty(getInstance(), obj); + if(object != null) { + object.makeGraphic(width, height, colorNum); + } + }); + + Lua_helper.add_callback(lua, "addAnimationByIndices", function(obj:String, name:String, prefix:String, indices:String, framerate:Int = 24) { + var strIndices:Array = indices.trim().split(','); + var die:Array = []; + for (i in 0...strIndices.length) { + die.push(Std.parseInt(strIndices[i])); + } + + if(PlayState.instance.modchartSprites.exists(obj)) { + var pussy:ModchartSprite = PlayState.instance.modchartSprites.get(obj); + pussy.animation.addByIndices(name, prefix, die, '', framerate, false); + if(pussy.animation.curAnim == null) { + pussy.animation.play(name, true); + } + return; + } + if(PlayState.instance.modchartIcons.exists(obj)) { + var pussy:ModchartIcon = PlayState.instance.modchartIcons.get(obj); + pussy.animation.addByIndices(name, prefix, die, '', framerate, false); + if(pussy.animation.curAnim == null) { + pussy.animation.play(name, true); + } + return; + } + + var pussy:FlxSprite = Reflect.getProperty(getInstance(), obj); + if(pussy != null) { + pussy.animation.addByIndices(name, prefix, die, '', framerate, false); + if(pussy.animation.curAnim == null) { + pussy.animation.play(name, true); + } + } + }); + + Lua_helper.add_callback(lua, "addAnimationByPrefix", function(obj:String, name:String, prefix:String, framerate:Int = 24, loop:Bool = true) { + if(PlayState.instance.modchartSprites.exists(obj)) { + var cock:ModchartSprite = PlayState.instance.modchartSprites.get(obj); + cock.animation.addByPrefix(name, prefix, framerate, loop); + if(cock.animation.curAnim == null) { + cock.animation.play(name, true); + } + return; + } + + var cock:FlxSprite = Reflect.getProperty(getInstance(), obj); + if(cock != null) { + cock.animation.addByPrefix(name, prefix, framerate, loop); + if(cock.animation.curAnim == null) { + cock.animation.play(name, true); + } + } + }); + + Lua_helper.add_callback(lua, "addAnimation", function(obj:String, name:String, indices:String, framerate:Int = 24, loop:Bool = true) { + var strIndices:Array = indices.trim().split(','); + var die:Array = []; + for (i in 0...strIndices.length) { + die.push(Std.parseInt(strIndices[i])); + } + + if(PlayState.instance.modchartSprites.exists(obj)) { + var cock:ModchartSprite = PlayState.instance.modchartSprites.get(obj); + cock.animation.add(name, die, framerate, loop); + if(cock.animation.curAnim == null) { + cock.animation.play(name, true); + } + return; + } + + var cock:FlxSprite = Reflect.getProperty(getInstance(), obj); + if(cock != null) { + cock.animation.add(name, die, framerate, loop); + if(cock.animation.curAnim == null) { + cock.animation.play(name, true); + } + } + }); + + Lua_helper.add_callback(lua, "objectPlayAnimation", function(obj:String, name:String, forced:Bool = false) { + var spr:Dynamic = getThing(obj); + + if(spr != null) { + spr.animation.play(name, forced); + } + }); + + Lua_helper.add_callback(lua, "objectColorTransform", function(obj:String, r:Int, g:Int, b:Int, a:Int) { + var spr:Dynamic = getThing(obj); + + if(spr != null) { + spr.useColorTransform = true; + spr.setColorTransform(0, 0, 0, 1, r, g, b, a); + } + }); + + Lua_helper.add_callback(lua, "objectColorTween", function(obj:String, duration:Float, color:String, color2:String, ?ease:String = 'linear') { + var spr:Dynamic = getThing(obj); + + if(spr != null) { + var colorNum:Int = Std.parseInt(color); + if(!color.startsWith('0x')) colorNum = Std.parseInt('0xff' + color); + + var colorNum2:Int = Std.parseInt(color2); + if(!color2.startsWith('0x')) colorNum2 = Std.parseInt('0xff' + color2); + + FlxTween.color(spr, duration, colorNum, colorNum2, {ease: getFlxEaseByString()}); + } + }); + + Lua_helper.add_callback(lua, "inBetweenColor", function(color:String, color2:String, diff:Float, ?remove0:Bool = false) { + var colorNum:Int = Std.parseInt(color); + if(!color.startsWith('0x')) colorNum = Std.parseInt('0xff' + color); + + var colorNum2:Int = Std.parseInt(color2); + if(!color2.startsWith('0x')) colorNum2 = Std.parseInt('0xff' + color2); + + var color = FlxColor.interpolate(colorNum, colorNum2, diff); + var daColor = color.toHexString(); + + if (remove0) + daColor = daColor.substring(2); + + return daColor; + }); + + Lua_helper.add_callback(lua, "addLuaSprite", function(tag:String, front:Bool = false) { + if(PlayState.instance.modchartSprites.exists(tag)) { + var shit:ModchartSprite = PlayState.instance.modchartSprites.get(tag); + if(!shit.wasAdded) { + if(front) + { + getInstance().add(shit); + } + else + { + var position:Int = PlayState.instance.members.indexOf(PlayState.instance.gf); + if(PlayState.instance.members.indexOf(PlayState.instance.boyfriend) < position) { + position = PlayState.instance.members.indexOf(PlayState.instance.boyfriend); + } else if(PlayState.instance.members.indexOf(PlayState.instance.dad) < position) { + position = PlayState.instance.members.indexOf(PlayState.instance.dad); + } + PlayState.instance.insert(position, shit); + } + shit.wasAdded = true; + //trace('added a thing: ' + tag); + } + } + }); + + //Tween shit, but for strums + Lua_helper.add_callback(lua, "noteTweenX", function(tag:String, note:Int, value:Dynamic, duration:Float, ease:String, ?player:Bool = false) { + cancelTween(tag); + if(note < 0) note = 0; + var testicle:StrumNote = PlayState.instance.strumLineNotes.members[note % PlayState.instance.strumLineNotes.length]; + + if (player) + testicle = PlayState.instance.playerStrums.members[note]; + + if(testicle != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(testicle, {x: value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } + }); + Lua_helper.add_callback(lua, "noteTweenY", function(tag:String, note:Int, value:Dynamic, duration:Float, ease:String, ?player:Bool = false) { + cancelTween(tag); + if(note < 0) note = 0; + var testicle:StrumNote = PlayState.instance.strumLineNotes.members[note % PlayState.instance.strumLineNotes.length]; + + if (player) + testicle = PlayState.instance.playerStrums.members[note]; + + if(testicle != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(testicle, {y: value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } + }); + Lua_helper.add_callback(lua, "noteTweenAngle", function(tag:String, note:Int, value:Dynamic, duration:Float, ease:String) { + cancelTween(tag); + if(note < 0) note = 0; + var testicle:StrumNote = PlayState.instance.strumLineNotes.members[note % PlayState.instance.strumLineNotes.length]; + + if(testicle != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(testicle, {angle: value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } + }); + Lua_helper.add_callback(lua, "noteTweenDirection", function(tag:String, note:Int, value:Dynamic, duration:Float, ease:String) { + cancelTween(tag); + if(note < 0) note = 0; + var testicle:StrumNote = PlayState.instance.strumLineNotes.members[note % PlayState.instance.strumLineNotes.length]; + + if(testicle != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(testicle, {direction: value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } + }); + Lua_helper.add_callback(lua, "noteTweenAlpha", function(tag:String, note:Int, value:Dynamic, duration:Float, ease:String) { + cancelTween(tag); + if(note < 0) note = 0; + var testicle:StrumNote = PlayState.instance.strumLineNotes.members[note % PlayState.instance.strumLineNotes.length]; + + if(testicle != null) { + PlayState.instance.modchartTweens.set(tag, FlxTween.tween(testicle, {alpha: value}, duration, {ease: getFlxEaseByString(ease), + onComplete: function(twn:FlxTween) { + PlayState.instance.callOnLuas('onTweenCompleted', [tag]); + PlayState.instance.modchartTweens.remove(tag); + } + })); + } + }); + + //wow very convenient + Lua_helper.add_callback(lua, "makeHealthIcon", function(tag:String, character:String, player:Bool = false) { + tag = tag.replace('.', ''); + resetIconTag(tag); + var leSprite:ModchartIcon = new ModchartIcon(character, player); + PlayState.instance.modchartIcons.set(tag, leSprite); //yes + var shit:ModchartIcon = PlayState.instance.modchartIcons.get(tag); + shit.cameras = [PlayState.instance.camHUD]; + getInstance().add(shit); + }); + + Lua_helper.add_callback(lua, "changeAddedIcon", function(tag:String, character:String){ + var shit:ModchartIcon = PlayState.instance.modchartIcons.get(tag); + shit.useOldSystem(character); + }); + + Lua_helper.add_callback(lua, "makeLuaCharacter", function(tag:String, character:String, isPlayer:Bool = false, flipped:Bool = false) { + makeLuaCharacter(tag, character, isPlayer, flipped); + }); + + Lua_helper.add_callback(lua, "changeLuaCharacter", function(tag:String, character:String){ + var shit:Character = PlayState.instance.modchartCharacters.get(tag); + makeLuaCharacter(tag, character, shit.isPlayer, shit.flipMode); + }); + + Lua_helper.add_callback(lua, "animExists", function(tag:String, anim:String){ + var shit:Dynamic = getThing(tag); + + return shit.animation.getByName(anim) != null; + }); + + Lua_helper.add_callback(lua, "getObjectOrder", function(obj:String) { + if(PlayState.instance.modchartSprites.exists(obj)) + return getInstance().members.indexOf(PlayState.instance.modchartSprites.get(obj)); + if(PlayState.instance.modchartTexts.exists(obj)) + return getInstance().members.indexOf(PlayState.instance.modchartTexts.get(obj)); + if(PlayState.instance.modchartIcons.exists(obj)) + return getInstance().members.indexOf(PlayState.instance.modchartIcons.get(obj)); + if(PlayState.instance.modchartCharacters.exists(obj)) + return getInstance().members.indexOf(PlayState.instance.modchartCharacters.get(obj)); + if(PlayState.instance.Stage.swagBacks.exists(obj)) + return getInstance().members.indexOf(PlayState.instance.Stage.swagBacks.get(obj)); + + + var leObj:FlxBasic = Reflect.getProperty(getInstance(), obj); + if(leObj != null) + { + return getInstance().members.indexOf(leObj); + } + luaTrace("Object " + obj + " doesn't exist!"); + return -1; + }); + + Lua_helper.add_callback(lua, "setObjectOrder", function(obj:String, position:Int) { + if(PlayState.instance.modchartSprites.exists(obj)) { + var spr:ModchartSprite = PlayState.instance.modchartSprites.get(obj); + if(spr.wasAdded) { + getInstance().remove(spr, true); + } + getInstance().insert(position, spr); + return; + } + if(PlayState.instance.modchartCharacters.exists(obj)) { + var spr:Character = PlayState.instance.modchartCharacters.get(obj); + getInstance().remove(spr, true); + getInstance().insert(position, spr); + return; + } + if(PlayState.instance.modchartIcons.exists(obj)) { + var spr:ModchartIcon = PlayState.instance.modchartIcons.get(obj); + getInstance().remove(spr, true); + getInstance().insert(position, spr); + return; + } + if(PlayState.instance.modchartTexts.exists(obj)) { + var spr:ModchartText = PlayState.instance.modchartTexts.get(obj); + if(spr.wasAdded) { + getInstance().remove(spr, true); + } + getInstance().insert(position, spr); + return; + } + if(PlayState.instance.Stage.swagBacks.exists(obj)) { + var spr:Dynamic = PlayState.instance.Stage.swagBacks.get(obj); + getInstance().remove(spr, true); + getInstance().insert(position, spr); + return; + } + + var leObj:FlxBasic = Reflect.getProperty(getInstance(), obj); + if(leObj != null) { + getInstance().remove(leObj, true); + getInstance().insert(position, leObj); + return; + } + luaTrace("Object " + obj + " doesn't exist!"); + }); + + Lua_helper.add_callback(lua, "characterPlayAnim", function(character:String, anim:String, ?forced:Bool = false) { + switch(character.toLowerCase()) { + case 'dad': + if(PlayState.instance.dad.animOffsets.exists(anim)) + PlayState.instance.dad.playAnim(anim, forced); + case 'gf' | 'girlfriend': + if(PlayState.instance.gf.animOffsets.exists(anim)) + PlayState.instance.gf.playAnim(anim, forced); + default: + if(PlayState.instance.boyfriend.animOffsets.exists(anim)) + PlayState.instance.boyfriend.playAnim(anim, forced); + } + }); + + Lua_helper.add_callback(lua, "characterDance", function(character:String) { + if(PlayState.instance.modchartCharacters.exists(character)) { + var spr:Character = PlayState.instance.modchartCharacters.get(character); + spr.dance(); + } + else + getActorByName(character).dance(); + }); + + Lua_helper.add_callback(lua, "scaleObject", function(obj:String, x:Float, y:Float) { + if(PlayState.instance.modchartSprites.exists(obj)) { + var shit:ModchartState.ModchartSprite = PlayState.instance.modchartSprites.get(obj); + shit.scale.set(x, y); + shit.updateHitbox(); + return; + } + + if(Stage.instance.swagBacks.exists(obj)) { + var shit:StageModchartState.StageModchartSprite = Stage.instance.swagBacks.get(obj); + shit.scale.set(x, y); + shit.updateHitbox(); + return; + } + + if(PlayState.instance.Stage.swagBacks.exists(obj)) { + var shit:StageModchartState.StageModchartSprite = Stage.instance.swagBacks.get(obj); + shit.scale.set(x, y); + shit.updateHitbox(); + return; + } + + var poop:FlxSprite = Reflect.getProperty(getInstance(), obj); + if(poop != null) { + poop.scale.set(x, y); + poop.updateHitbox(); + return; + } + luaTrace('Couldnt find object: ' + obj); + }); + + Lua_helper.add_callback(lua, "setOffset", function(id:String, x:Float, y:Float) { + var shit:Dynamic = getThing(id); + shit.offset.set(x, y); + }); + + // LUA TEXTS + Lua_helper.add_callback(lua, "makeLuaText", function(tag:String, text:String, width:Int, x:Float, y:Float) { + tag = tag.replace('.', ''); + resetTextTag(tag); + var leText:ModchartText = new ModchartText(x, y, text, width); + PlayState.instance.modchartTexts.set(tag, leText); + }); + + Lua_helper.add_callback(lua, "setTextString", function(tag:String, text:String) { + var obj:FlxText = getTextObject(tag); + if(obj != null) + { + obj.text = text; + } + }); + Lua_helper.add_callback(lua, "setTextSize", function(tag:String, size:Int) { + var obj:FlxText = getTextObject(tag); + if(obj != null) + { + obj.size = size; + } + }); + Lua_helper.add_callback(lua, "setTextWidth", function(tag:String, width:Float) { + var obj:FlxText = getTextObject(tag); + if(obj != null) + { + obj.fieldWidth = width; + } + }); + Lua_helper.add_callback(lua, "setTextBorder", function(tag:String, size:Int, color:String) { + var obj:FlxText = getTextObject(tag); + if(obj != null) + { + var colorNum:Int = Std.parseInt(color); + if(!color.startsWith('0x')) colorNum = Std.parseInt('0xff' + color); + + obj.borderSize = size; + obj.borderColor = colorNum; + } + }); + Lua_helper.add_callback(lua, "setTextColor", function(tag:String, color:String) { + var obj:FlxText = getTextObject(tag); + if(obj != null) + { + var colorNum:Int = Std.parseInt(color); + if(!color.startsWith('0x')) colorNum = Std.parseInt('0xff' + color); + + obj.color = colorNum; + } + }); + Lua_helper.add_callback(lua, "setTextFont", function(tag:String, newFont:String) { + var obj:FlxText = getTextObject(tag); + if(obj != null) + { + obj.font = Paths.font(newFont); + } + }); + Lua_helper.add_callback(lua, "setTextItalic", function(tag:String, italic:Bool) { + var obj:FlxText = getTextObject(tag); + if(obj != null) + { + obj.italic = italic; + } + }); + Lua_helper.add_callback(lua, "setTextAlignment", function(tag:String, alignment:String = 'left') { + var obj:FlxText = getTextObject(tag); + if(obj != null) + { + obj.alignment = LEFT; + switch(alignment.trim().toLowerCase()) + { + case 'right': + obj.alignment = RIGHT; + case 'center': + obj.alignment = CENTER; + } + } + }); + + Lua_helper.add_callback(lua, "getTextString", function(tag:String) { + var obj:FlxText = getTextObject(tag); + if(obj != null) + { + return obj.text; + } + return null; + }); + Lua_helper.add_callback(lua, "getTextSize", function(tag:String) { + var obj:FlxText = getTextObject(tag); + if(obj != null) + { + return obj.size; + } + return -1; + }); + Lua_helper.add_callback(lua, "getTextFont", function(tag:String) { + var obj:FlxText = getTextObject(tag); + if(obj != null) + { + return obj.font; + } + return null; + }); + Lua_helper.add_callback(lua, "getTextWidth", function(tag:String) { + var obj:FlxText = getTextObject(tag); + if(obj != null) + { + return obj.fieldWidth; + } + return 0; + }); + + Lua_helper.add_callback(lua, "addLuaText", function(tag:String) { + if(PlayState.instance.modchartTexts.exists(tag)) { + var shit:ModchartText = PlayState.instance.modchartTexts.get(tag); + if(!shit.wasAdded) { + getInstance().add(shit); + shit.wasAdded = true; + //trace('added a thing: ' + tag); + } + } + }); + Lua_helper.add_callback(lua, "removeLuaText", function(tag:String, destroy:Bool = true) { + if(!PlayState.instance.modchartTexts.exists(tag)) { + return; + } + + var pee:ModchartText = PlayState.instance.modchartTexts.get(tag); + if(destroy) { + pee.kill(); + } + + if(pee.wasAdded) { + getInstance().remove(pee, true); + pee.wasAdded = false; + } + + if(destroy) { + pee.destroy(); + PlayState.instance.modchartTexts.remove(tag); + } + }); + + //SHADER SHIT + + Lua_helper.add_callback(lua, "addEffect", function(camera:String,effect:String, ?val1:Dynamic, ?val2:Dynamic, ?val3:Dynamic, ?val4:Dynamic) { + + PlayState.instance.addShaderToCamera(camera, getEffectFromString(effect, val1, val2, val3, val4)); + + }); + Lua_helper.add_callback(lua, "clearEffects", function(camera:String) { + PlayState.instance.clearShaderFromCamera(camera); + }); + + + + // default strums + + Lua_helper.add_callback(lua, "getNotes", function(y:Float) + { + Lua.newtable(lua); + + for (i in 0...PlayState.instance.notes.members.length) + { + var note = PlayState.instance.notes.members[i]; + Lua.pushstring(lua, note.LuaNote.className); + Lua.rawseti(lua, -2, i); + } + }); + + // DEPRECATED, DONT MESS WITH THESE SHITS, ITS JUST THERE FOR BACKWARD COMPATIBILITY + Lua_helper.add_callback(lua, "luaSpriteMakeGraphic", function(tag:String, width:Int, height:Int, color:String) { + luaTrace("luaSpriteMakeGraphic is deprecated! Use makeGraphic instead", false, true); + if(PlayState.instance.modchartSprites.exists(tag)) { + var colorNum:Int = Std.parseInt(color); + if(!color.startsWith('0x')) colorNum = Std.parseInt('0xff' + color); + + PlayState.instance.modchartSprites.get(tag).makeGraphic(width, height, colorNum); + } + }); + Lua_helper.add_callback(lua, "luaSpriteAddAnimationByPrefix", function(tag:String, name:String, prefix:String, framerate:Int = 24, loop:Bool = true) { + luaTrace("luaSpriteAddAnimationByPrefix is deprecated! Use addAnimationByPrefix instead", false, true); + if(PlayState.instance.modchartSprites.exists(tag)) { + var cock:ModchartSprite = PlayState.instance.modchartSprites.get(tag); + cock.animation.addByPrefix(name, prefix, framerate, loop); + if(cock.animation.curAnim == null) { + cock.animation.play(name, true); + } + } + }); + Lua_helper.add_callback(lua, "luaSpriteAddAnimationByIndices", function(tag:String, name:String, prefix:String, indices:String, framerate:Int = 24) { + luaTrace("luaSpriteAddAnimationByIndices is deprecated! Use addAnimationByIndices instead", false, true); + if(PlayState.instance.modchartSprites.exists(tag)) { + var strIndices:Array = indices.trim().split(','); + var die:Array = []; + for (i in 0...strIndices.length) { + die.push(Std.parseInt(strIndices[i])); + } + var pussy:ModchartSprite = PlayState.instance.modchartSprites.get(tag); + pussy.animation.addByIndices(name, prefix, die, '', framerate, false); + if(pussy.animation.curAnim == null) { + pussy.animation.play(name, true); + } + } + }); + Lua_helper.add_callback(lua, "luaSpritePlayAnimation", function(tag:String, name:String, forced:Bool = false) { + luaTrace("luaSpritePlayAnimation is deprecated! Use objectPlayAnimation instead", false, true); + if(PlayState.instance.modchartSprites.exists(tag)) { + PlayState.instance.modchartSprites.get(tag).animation.play(name, forced); + } + }); + Lua_helper.add_callback(lua, "setLuaSpriteCamera", function(tag:String, camera:String = '') { + luaTrace("setLuaSpriteCamera is deprecated! Use setObjectCamera instead", false, true); + if(PlayState.instance.modchartSprites.exists(tag)) { + PlayState.instance.modchartSprites.get(tag).cameras = [cameraFromString(camera)]; + return true; + } + luaTrace("Lua sprite with tag: " + tag + " doesn't exist!"); + return false; + }); + Lua_helper.add_callback(lua, "setLuaSpriteScrollFactor", function(tag:String, scrollX:Float, scrollY:Float) { + luaTrace("setLuaSpriteScrollFactor is deprecated! Use setScrollFactor instead", false, true); + if(PlayState.instance.modchartSprites.exists(tag)) { + PlayState.instance.modchartSprites.get(tag).scrollFactor.set(scrollX, scrollY); + } + }); + Lua_helper.add_callback(lua, "scaleLuaSprite", function(tag:String, x:Float, y:Float) { + luaTrace("scaleLuaSprite is deprecated! Use scaleObject instead", false, true); + if(PlayState.instance.modchartSprites.exists(tag)) { + var shit:ModchartSprite = PlayState.instance.modchartSprites.get(tag); + shit.scale.set(x, y); + shit.updateHitbox(); + } + }); + Lua_helper.add_callback(lua, "getPropertyLuaSprite", function(tag:String, variable:String) { + luaTrace("getPropertyLuaSprite is deprecated! Use getProperty instead", false, true); + if(PlayState.instance.modchartSprites.exists(tag)) { + var killMe:Array = variable.split('.'); + if(killMe.length > 1) { + var coverMeInPiss:Dynamic = Reflect.getProperty(PlayState.instance.modchartSprites.get(tag), killMe[0]); + for (i in 1...killMe.length-1) { + coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); + } + return Reflect.getProperty(coverMeInPiss, killMe[killMe.length-1]); + } + return Reflect.getProperty(PlayState.instance.modchartSprites.get(tag), variable); + } + return null; + }); + Lua_helper.add_callback(lua, "setPropertyLuaSprite", function(tag:String, variable:String, value:Dynamic) { + luaTrace("setPropertyLuaSprite is deprecated! Use setProperty instead", false, true); + if(PlayState.instance.modchartSprites.exists(tag)) { + var killMe:Array = variable.split('.'); + if(killMe.length > 1) { + var coverMeInPiss:Dynamic = Reflect.getProperty(PlayState.instance.modchartSprites.get(tag), killMe[0]); + for (i in 1...killMe.length-1) { + coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); + } + return Reflect.setProperty(coverMeInPiss, killMe[killMe.length-1], value); + } + return Reflect.setProperty(PlayState.instance.modchartSprites.get(tag), variable, value); + } + luaTrace("Lua sprite with tag: " + tag + " doesn't exist!"); + }); + Lua_helper.add_callback(lua, "musicFadeIn", function(duration:Float, fromValue:Float = 0, toValue:Float = 1) { + FlxG.sound.music.fadeIn(duration, fromValue, toValue); + luaTrace('musicFadeIn is deprecated! Use soundFadeIn instead.', false, true); + + }); + Lua_helper.add_callback(lua, "musicFadeOut", function(duration:Float, toValue:Float = 0) { + FlxG.sound.music.fadeOut(duration, toValue); + luaTrace('musicFadeOut is deprecated! Use soundFadeOut instead.', false, true); + }); + + #end + } + + inline static function getTextObject(name:String):FlxText + { + return PlayState.instance.modchartTexts.exists(name) ? PlayState.instance.modchartTexts.get(name) : Reflect.getProperty(PlayState.instance, name); + } + + function getGroupStuff(leArray:Dynamic, variable:String) { + var killMe:Array = variable.split('.'); + if(killMe.length > 1) { + var coverMeInPiss:Dynamic = Reflect.getProperty(leArray, killMe[0]); + for (i in 1...killMe.length-1) { + coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); + } + return Reflect.getProperty(coverMeInPiss, killMe[killMe.length-1]); + } + return Reflect.getProperty(leArray, variable); + } + + function setGroupStuff(leArray:Dynamic, variable:String, value:Dynamic) { + var killMe:Array = variable.split('.'); + if(killMe.length > 1) { + var coverMeInPiss:Dynamic = Reflect.getProperty(leArray, killMe[0]); + for (i in 1...killMe.length-1) { + coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); + } + Reflect.setProperty(coverMeInPiss, killMe[killMe.length-1], value); + return; + } + Reflect.setProperty(leArray, variable, value); + } + + function resetIconTag(tag:String) { + if(!PlayState.instance.modchartIcons.exists(tag)) { + return; + } + + var pee:ModchartIcon = PlayState.instance.modchartIcons.get(tag); + pee.kill(); + if(pee.wasAdded) { + PlayState.instance.remove(pee, true); + } + pee.destroy(); + PlayState.instance.modchartIcons.remove(tag); + } + + function resetTextTag(tag:String) { + if(!PlayState.instance.modchartTexts.exists(tag)) { + return; + } + + var pee:ModchartText = PlayState.instance.modchartTexts.get(tag); + pee.kill(); + if(pee.wasAdded) { + PlayState.instance.remove(pee, true); + } + pee.destroy(); + PlayState.instance.modchartTexts.remove(tag); + } + + function resetSpriteTag(tag:String) { + if(!PlayState.instance.modchartSprites.exists(tag)) { + return; + } + + var pee:ModchartSprite = PlayState.instance.modchartSprites.get(tag); + pee.kill(); + if(pee.wasAdded) { + PlayState.instance.remove(pee, true); + } + pee.destroy(); + PlayState.instance.modchartSprites.remove(tag); + } + + function resetCharacterTag(tag:String) { + if(!PlayState.instance.modchartCharacters.exists(tag)) { + return; + } + + var pee:Dynamic = PlayState.instance.modchartCharacters.get(tag); + pee.kill(); + if(pee.wasAdded) { + PlayState.instance.remove(pee, true); + } + pee.destroy(); + PlayState.instance.modchartCharacters.remove(tag); + } + + function cancelTween(tag:String) { + if(PlayState.instance.modchartTweens.exists(tag)) { + PlayState.instance.modchartTweens.get(tag).cancel(); + PlayState.instance.modchartTweens.get(tag).destroy(); + PlayState.instance.modchartTweens.remove(tag); + } + } + + function tweenShit(tag:String, vars:String) { + cancelTween(tag); + var variables:Array = vars.replace(' ', '').split('.'); + var sexyProp:Dynamic = Reflect.getProperty(getInstance(), variables[0]); + if(PlayState.instance.modchartSprites.exists(variables[0])) { + sexyProp = PlayState.instance.modchartSprites.get(variables[0]); + } + if(PlayState.instance.modchartTexts.exists(variables[0])) { + sexyProp = PlayState.instance.modchartTexts.get(variables[0]); + } + + for (i in 1...variables.length) { + sexyProp = Reflect.getProperty(sexyProp, variables[i]); + } + return sexyProp; + } + + function cancelTimer(tag:String) { + if(PlayState.instance.modchartTimers.exists(tag)) { + var theTimer:FlxTimer = PlayState.instance.modchartTimers.get(tag); + theTimer.cancel(); + theTimer.destroy(); + PlayState.instance.modchartTimers.remove(tag); + } + } + + //Better optimized than using some getProperty shit or idk + function getFlxEaseByString(?ease:String = '') { + switch(ease.toLowerCase().trim()) { + case 'backin': return FlxEase.backIn; + case 'backinout': return FlxEase.backInOut; + case 'backout': return FlxEase.backOut; + case 'bouncein': return FlxEase.bounceIn; + case 'bounceinout': return FlxEase.bounceInOut; + case 'bounceout': return FlxEase.bounceOut; + case 'circin': return FlxEase.circIn; + case 'circinout': return FlxEase.circInOut; + case 'circout': return FlxEase.circOut; + case 'cubein': return FlxEase.cubeIn; + case 'cubeinout': return FlxEase.cubeInOut; + case 'cubeout': return FlxEase.cubeOut; + case 'elasticin': return FlxEase.elasticIn; + case 'elasticinout': return FlxEase.elasticInOut; + case 'elasticout': return FlxEase.elasticOut; + case 'expoin': return FlxEase.expoIn; + case 'expoinout': return FlxEase.expoInOut; + case 'expoout': return FlxEase.expoOut; + case 'quadin': return FlxEase.quadIn; + case 'quadinout': return FlxEase.quadInOut; + case 'quadout': return FlxEase.quadOut; + case 'quartin': return FlxEase.quartIn; + case 'quartinout': return FlxEase.quartInOut; + case 'quartout': return FlxEase.quartOut; + case 'quintin': return FlxEase.quintIn; + case 'quintinout': return FlxEase.quintInOut; + case 'quintout': return FlxEase.quintOut; + case 'sinein': return FlxEase.sineIn; + case 'sineinout': return FlxEase.sineInOut; + case 'sineout': return FlxEase.sineOut; + case 'smoothstepin': return FlxEase.smoothStepIn; + case 'smoothstepinout': return FlxEase.smoothStepInOut; + case 'smoothstepout': return FlxEase.smoothStepInOut; + case 'smootherstepin': return FlxEase.smootherStepIn; + case 'smootherstepinout': return FlxEase.smootherStepInOut; + case 'smootherstepout': return FlxEase.smootherStepOut; + } + return FlxEase.linear; + } + + function blendModeFromString(blend:String):BlendMode { + switch(blend.toLowerCase().trim()) { + case 'add': return ADD; + case 'alpha': return ALPHA; + case 'darken': return DARKEN; + case 'difference': return DIFFERENCE; + case 'erase': return ERASE; + case 'hardlight': return HARDLIGHT; + case 'invert': return INVERT; + case 'layer': return LAYER; + case 'lighten': return LIGHTEN; + case 'multiply': return MULTIPLY; + case 'overlay': return OVERLAY; + case 'screen': return SCREEN; + case 'shader': return SHADER; + case 'subtract': return SUBTRACT; + } + return NORMAL; + } + + function cameraFromString(cam:String):FlxCamera { + switch(cam.toLowerCase()) { + case 'camhud' | 'hud': return PlayState.instance.camHUD; + case 'camother' | 'other': return PlayState.instance.camOther; + } + return PlayState.instance.camGame; + } + + public function luaTrace(text:String, ignoreCheck:Bool = false, deprecated:Bool = false) { + #if LUA_ALLOWED + if(ignoreCheck || getBool('luaDebugMode')) { + if(deprecated && !getBool('luaDeprecatedWarnings')) { + return; + } + PlayState.instance.addTextToDebug(text); + trace(text); + } + #end + } + + public function get(var_name : String, type : String) : Dynamic { + var result : Any = null; + + // trace('getting variable ' + var_name + ' with a type of ' + type); + + Lua.getglobal(lua, var_name); + result = Convert.fromLua(lua,-1); + Lua.pop(lua,1); + + if( result == null ) { + return null; + } else { + var result = convert(result, type); + //trace(var_name + ' result: ' + result); + return result; + } + } + + private function convert(v : Any, type : String) : Dynamic { // I didn't write this lol + if( Std.is(v, String) && type != null ) { + var v : String = v; + if( type.substr(0, 4) == 'array' ) { + if( type.substr(4) == 'float' ) { + var array : Array = v.split(','); + var array2 : Array = new Array(); + + for( vars in array ) { + array2.push(Std.parseFloat(vars)); + } + + return array2; + } else if( type.substr(4) == 'int' ) { + var array : Array = v.split(','); + var array2 : Array = new Array(); + + for( vars in array ) { + array2.push(Std.parseInt(vars)); + } + + return array2; + } else { + var array : Array = v.split(','); + return array; + } + } else if( type == 'float' ) { + return Std.parseFloat(v); + } else if( type == 'int' ) { + return Std.parseInt(v); + } else if( type == 'bool' ) { + if( v == 'true' ) { + return true; + } else { + return false; + } + } else { + return v; + } + } else { + return v; + } + } + + public function call(event:String, args:Array):Dynamic { + #if LUA_ALLOWED + if(lua == null) { + return Function_Continue; + } + + Lua.getglobal(lua, event); + + for (arg in args) { + Convert.toLua(lua, arg); + } + + var result:Null = Lua.pcall(lua, args.length, 1, 0); + if(result != null && resultIsAllowed(lua, result)) { + /*var resultStr:String = Lua.tostring(lua, result); + var error:String = Lua.tostring(lua, -1); + Lua.pop(lua, 1);*/ + if(Lua.type(lua, -1) == Lua.LUA_TSTRING) { + var error:String = Lua.tostring(lua, -1); + Lua.pop(lua, 1); + if(error == 'attempt to call a nil value') { //Makes it ignore warnings and not break stuff if you didn't put the functions on your lua file + return Function_Continue; + } + } + + var conv:Dynamic = Convert.fromLua(lua, result); + Lua.pop(lua, 1); + return conv; + } + #end + return Function_Continue; + } + + public static function getPropertyLoopThingWhatever(killMe:Array, ?checkForTextsToo:Bool = true, ?noGameOver:Bool = false):Dynamic + { + var coverMeInPiss:Dynamic = getObjectDirectly(killMe[0], checkForTextsToo, noGameOver); + for (i in 1...killMe.length-1) { + coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]); + } + return coverMeInPiss; + } + + public static function getObjectDirectly(objectName:String, ?checkForTextsToo:Bool = true, ?noGameOver:Bool = false):Dynamic + { + var coverMeInPiss:Dynamic = null; + if(PlayState.instance.modchartSprites.exists(objectName)) { + coverMeInPiss = PlayState.instance.modchartSprites.get(objectName); + } else if(checkForTextsToo && PlayState.instance.modchartTexts.exists(objectName)) { + coverMeInPiss = PlayState.instance.modchartTexts.get(objectName); + } else { + coverMeInPiss = Reflect.getProperty(noGameOver ? PlayState.instance : getInstance(), objectName); + } + return coverMeInPiss; + } + + #if LUA_ALLOWED + function resultIsAllowed(leLua:State, leResult:Null) { //Makes it ignore warnings + switch(Lua.type(leLua, leResult)) { + case Lua.LUA_TNIL | Lua.LUA_TBOOLEAN | Lua.LUA_TNUMBER | Lua.LUA_TSTRING | Lua.LUA_TTABLE: + return true; + } + return false; + } + #end + + public function set(variable:String, data:Dynamic) { + #if LUA_ALLOWED + if(lua == null) { + return; + } + + Convert.toLua(lua, data); + Lua.setglobal(lua, variable); + #end + } + + #if LUA_ALLOWED + public function getBool(variable:String) { + var result:String = null; + Lua.getglobal(lua, variable); + result = Convert.fromLua(lua, -1); + Lua.pop(lua, 1); + + if(result == null) { + return false; + } + + // YES! FINALLY IT WORKS + //trace('variable: ' + variable + ', ' + result); + return (result == 'true'); + } + #end + + public function die() { + #if LUA_ALLOWED + if(lua == null) { + return; + } + + if(accessedProps != null) { + accessedProps.clear(); + } + + Lua.close(lua); + lua = null; + #end + } + + public function makeLuaCharacter(tag:String, character:String, isPlayer:Bool = false, flipped:Bool = false) + { + tag = tag.replace('.', ''); + resetCharacterTag(tag); + var leSprite:Character = new Character(0, 0, character, isPlayer); + leSprite.flipMode = flipped; + PlayState.instance.modchartCharacters.set(tag, leSprite); //yes + var shit:Character = PlayState.instance.modchartCharacters.get(tag); + PlayState.instance.add(shit); + + var charOffset = new CharacterOffsets(character, flipped); + var charX:Float = charOffset.daOffsetArray[0]; + var charY:Float = charOffset.daOffsetArray[1] + (flipped ? 350 : 0); + + if (!isPlayer) + { + if (flipped) + shit.flipMode = true; + + if (!shit.isCustom) + { + if (flipped) + { + if (charX == 0 && charOffset.daOffsetArray[1] == 0 && !charOffset.hasOffsets) + { + var charOffset2 = new CharacterOffsets(character, false); + charX = charOffset2.daOffsetArray[0]; + charY = charOffset2.daOffsetArray[1]; + } + } + else + { + if (charX == 0 && charY == 0 && !charOffset.hasOffsets) + { + var charOffset2 = new CharacterOffsets(character, true); + charX = charOffset2.daOffsetArray[0]; + charY = charOffset2.daOffsetArray[1] + 350; + } + } + } + + if (shit.isCustom) + { + charX = shit.positionArray[0]; + charY = shit.positionArray[1]; + } + + shit.x = PlayState.instance.Stage.dadXOffset + charX + 100; + shit.y = PlayState.instance.Stage.dadYOffset + charY + 100; + } + else + { + if (flipped) + shit.flipMode = true; + + var charOffset = new CharacterOffsets(character, !flipped); + var charX:Float = charOffset.daOffsetArray[0]; + var charY:Float = charOffset.daOffsetArray[1] - (!flipped ? 0 : 350); + + if (!shit.isCustom) + { + if (flipped) + { + if (charX == 0 && charOffset.daOffsetArray[1] == 0) + { + var charOffset2 = new CharacterOffsets(character, true); + charX = charOffset2.daOffsetArray[0]; + charY = charOffset2.daOffsetArray[1]; + } + } + else + { + if (charX == 0 && charY == 0 && !shit.curCharacter.startsWith('bf')) + { + var charOffset2 = new CharacterOffsets(character, false); + charX = charOffset2.daOffsetArray[0]; + charY = charOffset2.daOffsetArray[1] - 350; + } + } + } + + if (shit.isCustom) + { + charX = shit.positionArray[0]; + charY = shit.positionArray[1] - 350; + } + + shit.x = PlayState.instance.Stage.bfXOffset + charX + 770; + shit.y = PlayState.instance.Stage.bfYOffset + charY + 450; + } + + PlayState.instance.startCharacterLua(shit.curCharacter); + } + + public function getThing(id:String) + { + var shit:Dynamic; + + if(PlayState.instance.modchartSprites.exists(id)) + shit = PlayState.instance.modchartSprites.get(id); + else if(PlayState.instance.modchartTexts.exists(id)) + shit = PlayState.instance.modchartTexts.get(id); + else if(PlayState.instance.modchartIcons.exists(id)) + shit = PlayState.instance.modchartIcons.get(id); + else if(PlayState.instance.modchartCharacters.exists(id)) + shit = PlayState.instance.modchartCharacters.get(id); + else if(PlayState.instance.Stage.swagBacks.exists(id)) + shit = PlayState.instance.Stage.swagBacks.get(id); + else if(Stage.instance.swagBacks.exists(id)) + shit = Stage.instance.swagBacks.get(id); + else + shit = getActorByName(id); + + return shit; + } + + function getActorByName(id:String):Dynamic + { + // pre defined names + switch(id) + { + case 'boyfriend' | 'bf': + return PlayState.instance.boyfriend; + case 'boyfriend1' | 'bf1': + return PlayState.instance.boyfriend1; + case 'boyfriend2' | 'bf2': + @:privateAccess + return PlayState.instance.boyfriend2; + case 'gf': + @:privateAccess + return PlayState.instance.gf; + case 'camFollow': + @:privateAccess + return PlayState.instance.camFollow; + case 'camHUD': + @:privateAccess + return PlayState.instance.camHUD; + case 'camGame': + @:privateAccess + return FlxG.camera; + case 'camGame.scroll': + @:privateAccess + return FlxG.camera.scroll; + } + + if (id.contains('stage-')) + { + var daID:String = id.split('-')[1]; + return PlayState.instance.Stage.swagBacks[daID]; + } + + if (Std.parseInt(id) == null) + return Reflect.getProperty(getInstance(),id); + return PlayState.instance.strumLineNotes.members[Std.parseInt(id)]; + } + + function getEffectFromString(?effect:String = '', ?val1:Dynamic, ?val2:Dynamic, ?val3:Dynamic , ?val4:Dynamic):ShaderEffect { + switch(effect.toLowerCase().trim()) { + case 'grayscale' | 'greyscale' : return new GreyscaleEffect(); + case 'invert' | 'invertcolor': return new InvertColorsEffect(); + case 'tiltshift': return new TiltshiftEffect(val1,val2); + case 'grain': return new GrainEffect(val1,val2,val3); + case 'scanline': return new ScanlineEffect(val1); + case 'outline': return new OutlineEffect(val1, val2, val3, val4); + case 'distortion': return new DistortBGEffect(val1, val2, val3); + case 'vcr': return new VCRDistortionEffect(val1,val2,val3,val4); + case 'glitch': return new GlitchEffect(val1, val2, val3); + case 'vcr2': return new VCRDistortionEffect2(); //the tails doll one + case '3d': return new ThreeDEffect(val1, val2, val3, val4); + case 'bloom': return new BloomEffect(val1/512.0,val2); + case 'rgbshiftglitch' | 'rgbshift': return new RGBShiftGlitchEffect(val1, val2); + case 'pulse': return new PulseEffect(val1,val2,val3); + case 'chromaticabberation': new ChromaticAberrationEffect(val1); + case 'sketch': new SketchEffect(); + } + return new GreyscaleEffect(); + } + + function changeGFCharacter(id:String, x:Float, y:Float) + { + PlayState.instance.removeObject(PlayState.instance.gf); + //PlayState.instance.gf = new Character(x, y, null); + PlayState.instance.destroyObject(PlayState.instance.gf); + PlayState.instance.gf = new Character(x, y, id); + PlayState.instance.gf.scrollFactor.set(0.95, 0.95); + PlayState.instance.addObject(PlayState.instance.gf); + + if (FlxG.save.data.poltatoPC) + PlayState.instance.gf.setPosition(PlayState.instance.gf.x + 100, PlayState.instance.gf.y + 170); + + PlayState.instance.startCharacterLua(PlayState.instance.gf.curCharacter); + + } + + function changeDadCharacter(id:String, x:Float, y:Float) + { + //this is why i don't use exTricky + var wasExTricky:Bool = false; + var isExTricky:Bool = false; + + if (PlayState.instance.dad.curCharacter == 'exTricky') + wasExTricky = true; + + if (id == 'exTricky') + isExTricky = true; + + if (wasExTricky) + { + PlayState.instance.removeObject(PlayState.instance.dad.exSpikes); + PlayState.instance.destroyObject(PlayState.instance.dad.exSpikes); + } + + PlayState.instance.removeObject(PlayState.instance.dadTrail); + PlayState.instance.removeObject(PlayState.instance.dad); + PlayState.instance.destroyObject(PlayState.instance.dad); + PlayState.instance.dad = new Character(x, y, id); + PlayState.instance.addObject(PlayState.instance.dadTrail); + PlayState.instance.dadTrail.resetTrail(); + PlayState.instance.addObject(PlayState.instance.dad); + + if (isExTricky) + PlayState.instance.addObject(PlayState.instance.dad.exSpikes); + + if (PlayState.newIcons) + { + if (PlayState.swapIcons) + PlayState.instance.iconP2.changeIcon(PlayState.instance.dad.healthIcon); + } + else + PlayState.instance.iconP2.useOldSystem(PlayState.instance.dad.healthIcon); + + if (PlayState.instance.changeArrows) + { + for (i in 0...Main.keyAmmo[PlayState.SONG.mania]) + { + PlayState.instance.strumLineNotes.members[i].texture = PlayState.instance.dad.noteSkin; + } + } + + if (PlayState.instance.defaultBar) + { + PlayState.instance.healthBar.createFilledBar(FlxColor.fromString('#' + PlayState.instance.dad.iconColor), FlxColor.fromString('#' + PlayState.instance.boyfriend.iconColor)); + PlayState.instance.healthBar.updateBar(); + } + + PlayState.instance.startCharacterLua(PlayState.instance.dad.curCharacter); + + } + + function changeDad1Character(id:String, x:Float, y:Float) + { + PlayState.instance.removeObject(PlayState.instance.dad1Trail); + PlayState.instance.removeObject(PlayState.instance.dad1); + PlayState.instance.destroyObject(PlayState.instance.dad1); + PlayState.instance.dad1 = new Character(x, y, id); + PlayState.instance.addObject(PlayState.instance.dad1Trail); + PlayState.instance.dad1Trail.resetTrail(); + PlayState.instance.addObject(PlayState.instance.dad1); + } + + function changeDad2Character(id:String, x:Float, y:Float) + { + PlayState.instance.removeObject(PlayState.instance.dad2); + PlayState.instance.destroyObject(PlayState.instance.dad2); + PlayState.instance.dad2 = new Character(x, y, id); + PlayState.instance.addObject(PlayState.instance.dad2); + + if (PlayState.instance.defaultBar) + { + PlayState.instance.healthBar.createFilledBar(FlxColor.fromString('#' + PlayState.instance.dad2.iconColor), FlxColor.fromString('#' + PlayState.instance.boyfriend.iconColor)); + PlayState.instance.healthBar.updateBar(); + } + } + + function changeBoyfriendCharacter(id:String, x:Float, y:Float) + { + var animationName:String = "no way anyone have an anim name this big"; + var animationFrame:Int = 0; + if (PlayState.instance.boyfriend.animation.curAnim.name.startsWith('sing')) + { + animationName = PlayState.instance.boyfriend.animation.curAnim.name; + animationFrame = PlayState.instance.boyfriend.animation.curAnim.curFrame; + } + + PlayState.instance.removeObject(PlayState.instance.bfTrail); + PlayState.instance.removeObject(PlayState.instance.boyfriend); + PlayState.instance.destroyObject(PlayState.instance.boyfriend); + PlayState.instance.boyfriend = new Boyfriend(x, y, id); + PlayState.instance.addObject(PlayState.instance.bfTrail); + PlayState.instance.bfTrail.resetTrail(); + PlayState.instance.addObject(PlayState.instance.boyfriend); + + if (PlayState.newIcons) + { + if (PlayState.swapIcons) + PlayState.instance.iconP1.changeIcon(PlayState.instance.boyfriend.healthIcon); + else + ''; //do nothing + } + else + PlayState.instance.iconP1.useOldSystem(PlayState.instance.boyfriend.healthIcon); + + if (PlayState.instance.changeArrows) + { + for (i in Main.keyAmmo[PlayState.SONG.mania]...Main.keyAmmo[PlayState.SONG.mania] * 2) + { + PlayState.instance.strumLineNotes.members[i].texture = PlayState.instance.boyfriend.noteSkin; + PlayState.instance.bfStrumStyle = PlayState.instance.boyfriend.noteSkin; + } + } + + if (PlayState.instance.defaultBar) + { + PlayState.instance.healthBar.createFilledBar(FlxColor.fromString('#' + PlayState.instance.dad.iconColor), FlxColor.fromString('#' + PlayState.instance.boyfriend.iconColor)); + PlayState.instance.healthBar.updateBar(); + } + + if (PlayState.instance.boyfriend.animOffsets.exists(animationName)) + PlayState.instance.boyfriend.playAnim(animationName, true, false, animationFrame); + + PlayState.instance.startCharacterLua(PlayState.instance.boyfriend.curCharacter); + } + + function changeBoyfriend1Character(id:String, x:Float, y:Float) + { + PlayState.instance.removeObject(PlayState.instance.bf1Trail); + PlayState.instance.removeObject(PlayState.instance.boyfriend1); + //PlayState.instance.boyfriend1 = new Boyfriend1(x, y, null); + PlayState.instance.destroyObject(PlayState.instance.boyfriend1); + PlayState.instance.boyfriend1 = new Boyfriend(x, y, id); + PlayState.instance.addObject(PlayState.instance.bf1Trail); + PlayState.instance.bf1Trail.resetTrail(); + PlayState.instance.addObject(PlayState.instance.boyfriend1); + + if (PlayState.instance.changeArrows) + { + for (i in Main.keyAmmo[PlayState.SONG.mania]...Main.keyAmmo[PlayState.SONG.mania] * 2) + { + PlayState.instance.strumLineNotes.members[i].texture = PlayState.instance.boyfriend.noteSkin; + PlayState.instance.bfStrumStyle = PlayState.instance.boyfriend.noteSkin; + } + } + + if (PlayState.instance.defaultBar) + { + PlayState.instance.healthBar.createFilledBar(FlxColor.fromString('#' + PlayState.instance.dad.iconColor), FlxColor.fromString('#' + PlayState.instance.boyfriend1.iconColor)); + PlayState.instance.healthBar.updateBar(); + } + } + + function changeBoyfriend2Character(id:String, x:Float, y:Float) + { + PlayState.instance.removeObject(PlayState.instance.boyfriend2); + PlayState.instance.destroyObject(PlayState.instance.boyfriend2); + PlayState.instance.boyfriend2 = new Boyfriend(x, y, id); + PlayState.instance.addObject(PlayState.instance.boyfriend2); + + if (PlayState.instance.defaultBar) + { + PlayState.instance.healthBar.createFilledBar(FlxColor.fromString('#' + PlayState.instance.dad.iconColor), FlxColor.fromString('#' + PlayState.instance.boyfriend2.iconColor)); + PlayState.instance.healthBar.updateBar(); + } + } + + //does this work. right? -- future me here. yes it does. + function changeStage(id:String) + { + PlayState.instance.removeObject(PlayState.instance.gf); + PlayState.instance.removeObject(PlayState.instance.dad); + PlayState.instance.removeObject(PlayState.instance.boyfriend); + + if (PlayState.SONG.song.toLowerCase() == 'epiphany' && PlayState.storyDifficulty == 5) + PlayState.instance.removeObject(PlayState.instance.dad1); + + if (PlayState.instance.trioDad) + { + PlayState.instance.removeObject(PlayState.instance.dad1); + PlayState.instance.removeObject(PlayState.instance.dad2); + } + + if (PlayState.instance.duoBoyfriend || PlayState.instance.trioBoyfriend) + { + PlayState.instance.removeObject(PlayState.instance.boyfriend1); + + if (PlayState.instance.trioBoyfriend) + PlayState.instance.removeObject(PlayState.instance.boyfriend2); + } + + if (PlayState.instance.Stage.isCustomStage && PlayState.instance.Stage.stageLuaArray.length >= 1) + { + trace(PlayState.instance.Stage.stageLuaArray.length); + + for (i in PlayState.instance.Stage.stageLuaArray) + { + PlayState.instance.Stage.stageLuaArray.remove(i); + i.die(); + } + PlayState.instance.Stage.stageLuaArray = []; + trace(PlayState.instance.Stage.stageLuaArray.length); + } + + for (i in PlayState.instance.Stage.toAdd) + { + PlayState.instance.removeObject(i); + PlayState.instance.destroyObject(i); + } + + for (i in PlayState.instance.Stage.layInFront[0]) + { + PlayState.instance.removeObject(i); + PlayState.instance.destroyObject(i); + } + + for (i in PlayState.instance.Stage.layInFront[1]) + { + PlayState.instance.removeObject(i); + PlayState.instance.destroyObject(i); + } + + for (i in PlayState.instance.Stage.layInFront[2]) + { + PlayState.instance.removeObject(i); + PlayState.instance.destroyObject(i); + } + + PlayState.instance.Stage.swagBacks.clear(); + + PlayState.instance.removeObject(PlayState.instance.Stage); + PlayState.instance.destroyObject(PlayState.instance.Stage); + + PlayState.instance.Stage = new Stage(id); + PlayState.curStage = PlayState.instance.Stage.curStage; + PlayState.instance.defaultCamZoom = PlayState.instance.Stage.camZoom; + + for (i in PlayState.instance.Stage.toAdd) + { + PlayState.instance.addObject(i); + } + + for (index => array in PlayState.instance.Stage.layInFront) + { + switch (index) + { + case 0: + PlayState.instance.addObject(PlayState.instance.gf); + PlayState.instance.gf.scrollFactor.set(0.95, 0.95); + for (bg in array) + PlayState.instance.addObject(bg); + case 1: + if (PlayState.SONG.song.toLowerCase() == 'epiphany' && PlayState.storyDifficulty == 5) + PlayState.instance.addObject(PlayState.instance.dad1); + + if (PlayState.instance.trioDad) + { + PlayState.instance.addObject(PlayState.instance.dad1); + PlayState.instance.addObject(PlayState.instance.dad2); + } + + PlayState.instance.addObject(PlayState.instance.dad); + + if (PlayState.instance.trioBoyfriend) + { + PlayState.instance.addObject(PlayState.instance.boyfriend1); + PlayState.instance.addObject(PlayState.instance.boyfriend2); + } + for (bg in array) + PlayState.instance.addObject(bg); + case 2: + PlayState.instance.addObject(PlayState.instance.boyfriend); + + if (PlayState.instance.duoBoyfriend) + PlayState.instance.addObject(PlayState.instance.boyfriend1); + + for (bg in array) + PlayState.instance.addObject(bg); + } + } + } + + // this is better. easier to port shit from playstate. + function changeGFCharacterBetter(x:Float, y:Float, id:String) + { + changeGFCharacter(id, x, y); + } + + function changeDadCharacterBetter(x:Float, y:Float, id:String) + { + changeDadCharacter(id, x, y); + } + + function changeBoyfriendCharacterBetter(x:Float, y:Float, id:String) + { + changeBoyfriendCharacter(id, x, y); + } + + //trying to do some auto stuff so i don't have to set manual x and y values + public function changeBFAuto(id:String, ?flipped:Bool = false, ?dontDestroy:Bool = false) + { + var animationName:String = "no way anyone have an anim name this big"; + var animationFrame:Int = 0; + if (PlayState.instance.boyfriend.animation.curAnim.name.startsWith('sing')) + { + animationName = PlayState.instance.boyfriend.animation.curAnim.name; + animationFrame = PlayState.instance.boyfriend.animation.curAnim.curFrame; + } + + var bfPath:String = ""; + + if (FlxG.save.data.uncacheCharacterSwitch && !dontDestroy) + bfPath = 'shared:assets/shared/images/'+PlayState.instance.boyfriend.charPath; + + PlayState.instance.removeObject(PlayState.instance.bfTrail); + PlayState.instance.removeObject(PlayState.instance.boyfriend); + PlayState.instance.destroyObject(PlayState.instance.boyfriend); + PlayState.instance.boyfriend = new Boyfriend(0, 0, id, !flipped); + + PlayState.instance.boyfriend.flipMode = flipped; + + var charOffset = new CharacterOffsets(id, !flipped); + var charX:Float = charOffset.daOffsetArray[0]; + var charY:Float = charOffset.daOffsetArray[1] - (!flipped ? 0 : 350); + + if (!PlayState.instance.boyfriend.isCustom) + { + if (flipped) + { + if (charX == 0 && charOffset.daOffsetArray[1] == 0) + { + var charOffset2 = new CharacterOffsets(id, true); + charX = charOffset2.daOffsetArray[0]; + charY = charOffset2.daOffsetArray[1]; + } + } + else + { + if (charX == 0 && charY == 0 && !PlayState.instance.boyfriend.curCharacter.startsWith('bf')) + { + var charOffset2 = new CharacterOffsets(id, false); + charX = charOffset2.daOffsetArray[0]; + charY = charOffset2.daOffsetArray[1] - 350; + } + } + } + + if (PlayState.instance.boyfriend.isCustom) + { + charX = PlayState.instance.boyfriend.positionArray[0]; + charY = PlayState.instance.boyfriend.positionArray[1] - 350; + } + + PlayState.instance.boyfriend.x = PlayState.instance.Stage.bfXOffset + charX + 770; + PlayState.instance.boyfriend.y = PlayState.instance.Stage.bfYOffset + charY + 450; + + PlayState.instance.addObject(PlayState.instance.bfTrail); + PlayState.instance.bfTrail.resetTrail(); + PlayState.instance.addObject(PlayState.instance.boyfriend); + + if (PlayState.newIcons) + { + if (PlayState.swapIcons) + PlayState.instance.iconP1.changeIcon(PlayState.instance.boyfriend.healthIcon); + } + else + PlayState.instance.iconP1.useOldSystem(PlayState.instance.boyfriend.healthIcon); + + if (PlayState.instance.defaultBar) + { + PlayState.instance.healthBar.createFilledBar(FlxColor.fromString('#' + PlayState.instance.dad.iconColor), FlxColor.fromString('#' + PlayState.instance.boyfriend.iconColor)); + PlayState.instance.healthBar.updateBar(); + } + + if (PlayState.instance.boyfriend.animOffsets.exists(animationName)) + PlayState.instance.boyfriend.playAnim(animationName, true, false, animationFrame); + + if (FlxG.save.data.uncacheCharacterSwitch && !dontDestroy) + Paths.clearStoredMemory2(bfPath); + + if (PlayState.instance.changeArrows) + { + for (i in Main.keyAmmo[PlayState.SONG.mania]...Main.keyAmmo[PlayState.SONG.mania] * 2) + { + PlayState.instance.strumLineNotes.members[i].texture = PlayState.instance.boyfriend.noteSkin; + PlayState.instance.bfStrumStyle = PlayState.instance.boyfriend.noteSkin; + } + } + + PlayState.instance.startCharacterLua(PlayState.instance.boyfriend.curCharacter); + } + + public function changeDadAuto(id:String, ?flipped:Bool = false, ?dontDestroy:Bool = false) + { + var animationName:String = "no way anyone have an anim name this big"; + var animationFrame:Int = 0; + if (PlayState.instance.dad.animation.curAnim.name.startsWith('sing')) + { + animationName = PlayState.instance.dad.animation.curAnim.name; + animationFrame = PlayState.instance.dad.animation.curAnim.curFrame; + } + + var dadPath:String = ''; + var daCurChar:String = PlayState.instance.dad.curCharacter; + + if (FlxG.save.data.uncacheCharacterSwitch && !dontDestroy) + dadPath = 'shared:assets/shared/images/'+PlayState.instance.dad.charPath; + + PlayState.instance.removeObject(PlayState.instance.dadTrail); + PlayState.instance.removeObject(PlayState.instance.dad); + PlayState.instance.destroyObject(PlayState.instance.dad); + PlayState.instance.dad = new Character(0, 0, id, flipped); + + var charOffset = new CharacterOffsets(id, flipped); + var charX:Float = charOffset.daOffsetArray[0]; + var charY:Float = charOffset.daOffsetArray[1] + (flipped ? 350 : 0); + + if (flipped) + PlayState.instance.dad.flipMode = true; + + if (!PlayState.instance.dad.isCustom) + { + if (flipped) + { + if (charX == 0 && charOffset.daOffsetArray[1] == 0 && !charOffset.hasOffsets) + { + var charOffset2 = new CharacterOffsets(id, false); + charX = charOffset2.daOffsetArray[0]; + charY = charOffset2.daOffsetArray[1]; + } + } + else + { + if (charX == 0 && charY == 0 && !charOffset.hasOffsets) + { + var charOffset2 = new CharacterOffsets(id, true); + charX = charOffset2.daOffsetArray[0]; + charY = charOffset2.daOffsetArray[1] + 350; + } + } + } + + if (PlayState.instance.dad.isCustom) + { + charX = PlayState.instance.dad.positionArray[0]; + charY = PlayState.instance.dad.positionArray[1]; + } + + PlayState.instance.dad.x = PlayState.instance.Stage.dadXOffset + charX + 100; + PlayState.instance.dad.y = PlayState.instance.Stage.dadYOffset + charY + 100; + + PlayState.instance.addObject(PlayState.instance.dadTrail); + PlayState.instance.dadTrail.resetTrail(); + PlayState.instance.addObject(PlayState.instance.dad); + + if (PlayState.newIcons) + { + if (PlayState.swapIcons) + PlayState.instance.iconP2.changeIcon(PlayState.instance.dad.healthIcon); + } + else + PlayState.instance.iconP2.useOldSystem(PlayState.instance.dad.healthIcon); + + if (PlayState.instance.defaultBar) + { + PlayState.instance.healthBar.createFilledBar(FlxColor.fromString('#' + PlayState.instance.dad.iconColor), FlxColor.fromString('#' + PlayState.instance.boyfriend.iconColor)); + PlayState.instance.healthBar.updateBar(); + } + + if (PlayState.instance.dad.animOffsets.exists(animationName)) + PlayState.instance.dad.playAnim(animationName, true, false, animationFrame); + + if (FlxG.save.data.uncacheCharacterSwitch && !dontDestroy && daCurChar != PlayState.instance.dad.curCharacter) + Paths.clearStoredMemory2(dadPath); + + if (PlayState.instance.changeArrows) + { + for (i in 0...Main.keyAmmo[PlayState.SONG.mania]) + { + PlayState.instance.cpuStrums.members[i].texture = PlayState.instance.dad.noteSkin; + } + } + + PlayState.instance.startCharacterLua(PlayState.instance.dad.curCharacter); + } + + function changeGFAuto(id:String, ?dontDestroy:Bool = false) + { + PlayState.instance.removeObject(PlayState.instance.gf); + PlayState.instance.destroyObject(PlayState.instance.gf); + PlayState.instance.gf = new Character(0, 0, id); + PlayState.instance.gf.x = PlayState.instance.Stage.gfXOffset + 400 + PlayState.instance.gf.positionArray[0]; + PlayState.instance.gf.y = PlayState.instance.Stage.gfYOffset + 130 + PlayState.instance.gf.positionArray[1]; + PlayState.instance.gf.scrollFactor.set(0.95, 0.95); + PlayState.instance.addObject(PlayState.instance.gf); + + if (FlxG.save.data.poltatoPC) + PlayState.instance.gf.setPosition(PlayState.instance.gf.x + 100, PlayState.instance.gf.y + 170); + + var gfPath:String = ''; + + if (FlxG.save.data.uncacheCharacterSwitch && !dontDestroy) + gfPath = 'shared:assets/shared/images/'+PlayState.instance.gf.charPath; + + if (FlxG.save.data.uncacheCharacterSwitch && !dontDestroy) + Paths.clearStoredMemory2(gfPath); + + PlayState.instance.startCharacterLua(PlayState.instance.gf.curCharacter); + } + + function doFunction(id:String, ?val1:Dynamic, ?val2:Dynamic, ?val3:Dynamic, ?val4:Dynamic) + { + //this is dumb but idk how else to do it and i don't wanna make multiple functions for different playstate functions so yeah. + switch (id) + { + case 'doP3Static': PlayState.instance.doP3Static(); + case 'doP3Jump': PlayState.instance.doP3Jump(val1); + case 'funCountdown': PlayState.instance.funCountdown(val1); + case 'softCountdown': PlayState.instance.softCountdown(); + case 'startCountdown': PlayState.instance.startCountdown(); + case 'doJumpscare': PlayState.instance.doJumpscare(); + case 'startWriting': PlayState.instance.startWriting(val1, val2); + case 'doSonicIntro': PlayState.instance.doSonicIntro(val1, val2); + case 'doSimpleJump': PlayState.instance.doSimpleJump(val1); + case 'resyncVocals': PlayState.instance.resyncVocals(); + case 'doTimeTravel': PlayState.instance.doTimeTravel(val1, val2); + case 'uncacheImage': Paths.clearStoredMemory2(val1); + case 'cacheImage': Paths.cacheImage(val1, val2); + case 'toggleHealthShit': PlayState.instance.toggleHealthShit(val1); + case 'spawnStartingNoteSplash': PlayState.instance.spawnStartingNoteSplash(0, 0, 0); + case 'doStopSign': PlayState.instance.doStopSign(val1, val2); + case 'doGremlin': PlayState.instance.doGremlin(val1, val2, val3); + case 'bgFlash': PlayState.instance.bgFlash(); + case 'createBFSpookyText': PlayState.instance.createBFSpookyText(val1); + case 'createSpookyText': PlayState.instance.createSpookyText(val1); + case 'createAuditorText': PlayState.instance.createAuditorText(val1, val2, val3, val4); + } + } + + + + public static inline function getInstance() + { + return PlayState.instance.isDead ? GameOverSubstate.instance : PlayState.instance; + } + static inline var CLENSE:String = " + os.execute = nil; + os.exit = nil; + package.loaded.os.execute = nil; + package.loaded.os.exit = nil; + process = nil; + package.loaded.process = nil; + + "; // Fuck this, I can't figure out linc_lua, so I'mma set everything in Lua itself - Super +} + +class ModchartSprite extends FlxSprite +{ + public var wasAdded:Bool = false; + //public var isInFront:Bool = false; + + public function new(?x:Float = 0, ?y:Float = 0) + { + super(x, y); + antialiasing = true; + } +} + +class ModchartText extends FlxText +{ + public var wasAdded:Bool = false; + public function new(x:Float, y:Float, text:String, width:Float) + { + super(x, y, width, text, 16); + setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + cameras = [PlayState.instance.camHUD]; + scrollFactor.set(); + borderSize = 2; + } +} + +class ModchartIcon extends HealthIcon +{ + public var wasAdded:Bool = false; + //public var isInFront:Bool = false; +} + +class DebugLuaText extends FlxText +{ + private var disableTime:Float = 6; + public var parentGroup:FlxTypedGroup; + public function new(text:String, parentGroup:FlxTypedGroup) { + this.parentGroup = parentGroup; + super(10, 10, 0, text, 16); + setFormat(Paths.font("vcr.ttf"), 20, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + scrollFactor.set(); + borderSize = 1; + } + + override function update(elapsed:Float) { + super.update(elapsed); + disableTime -= elapsed; + if(disableTime <= 0) { + kill(); + parentGroup.remove(this); + destroy(); + } + else if(disableTime < 1) alpha = disableTime; + } + +} diff --git a/source/ModsMenuState.hx b/source/ModsMenuState.hx index 20893994e..b7fcd6c31 100644 --- a/source/ModsMenuState.hx +++ b/source/ModsMenuState.hx @@ -66,7 +66,8 @@ class ModsMenuState extends MusicBeatState override function create() { - Paths.destroyLoadedImages(); + Paths.clearStoredMemory(); + Paths.clearUnusedMemory(); WeekData.setDirectoryFromWeek(); #if desktop @@ -77,7 +78,8 @@ class ModsMenuState extends MusicBeatState bg = new FlxSprite().loadGraphic(Paths.image('menuDesat')); bg.antialiasing = ClientPrefs.globalAntialiasing; add(bg); - + bg.screenCenter(); + noModsTxt = new FlxText(0, 0, FlxG.width, "NO MODS INSTALLED\nPRESS BACK TO EXIT AND INSTALL A MOD", 48); if(FlxG.random.bool(0.1)) noModsTxt.text += '\nBITCH.'; //meanie noModsTxt.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); @@ -87,7 +89,7 @@ class ModsMenuState extends MusicBeatState noModsTxt.screenCenter(); visibleWhenNoMods.push(noModsTxt); - var path:String = Main.getDataPath() + 'modsList.txt'; + var path:String = 'modsList.txt'; if(FileSystem.exists(path)) { var leMods:Array = CoolUtil.coolTextFile(path); @@ -106,17 +108,24 @@ class ModsMenuState extends MusicBeatState // FIND MOD FOLDERS var boolshit = true; - if (FileSystem.exists(Main.getDataPath() + "modsList.txt")){ + if (FileSystem.exists("modsList.txt")){ for (folder in Paths.getModDirectories()) { if(!Paths.ignoreModFolders.contains(folder)) { - addToModsList([folder, true]); + addToModsList([folder, false]);//i like it false by default. } } } saveTxt(); + // FIND MOD FOLDERS + for (folder in Paths.getModDirectories()) + { + addToModsList([folder, true]); + } + saveTxt(); + selector = new AttachedSprite(); selector.xAdd = -205; selector.yAdd = -68; @@ -315,7 +324,8 @@ class ModsMenuState extends MusicBeatState if(loadedIcon != null) { newMod.icon.loadGraphic(loadedIcon, true, 150, 150);//animated icon support - newMod.icon.animation.add("icon", getIntArray(Math.floor(loadedIcon.width / 150)),24); + var totalFrames = Math.floor(loadedIcon.width / 150) * Math.floor(loadedIcon.height / 150); + newMod.icon.animation.add("icon", [for (i in 0...totalFrames) i],10); newMod.icon.animation.play("icon"); } else @@ -342,10 +352,6 @@ class ModsMenuState extends MusicBeatState FlxG.mouse.visible = true; - #if mobileC - addVirtualPad(UP_DOWN, B); - #end - super.create(); } @@ -421,7 +427,7 @@ class ModsMenuState extends MusicBeatState fileStr += values[0] + '|' + (values[1] ? '1' : '0'); } - var path:String = Main.getDataPath() + 'modsList.txt'; + var path:String = 'modsList.txt'; File.saveContent(path, fileStr); } diff --git a/source/MusicBeatState.hx b/source/MusicBeatState.hx index 732dd55be..137753c55 100644 --- a/source/MusicBeatState.hx +++ b/source/MusicBeatState.hx @@ -1,22 +1,18 @@ package; +#if windows +import Discord.DiscordClient; +#end +import flixel.tweens.FlxTween; +import flixel.util.FlxColor; +import openfl.Lib; import Conductor.BPMChangeEvent; import flixel.FlxG; +import flixel.addons.transition.FlxTransitionableState; import flixel.addons.ui.FlxUIState; import flixel.math.FlxRect; import flixel.util.FlxTimer; -import flixel.addons.transition.FlxTransitionableState; -import flixel.tweens.FlxEase; -import flixel.tweens.FlxTween; -import flixel.FlxSprite; -import flixel.util.FlxColor; -import flixel.util.FlxGradient; -import flixel.FlxState; import flixel.FlxBasic; -#if mobileC -import flixel.input.actions.FlxActionInput; -import ui.FlxVirtualPad; -#end class MusicBeatState extends FlxUIState { @@ -30,43 +26,31 @@ class MusicBeatState extends FlxUIState inline function get_controls():Controls return PlayerSettings.player1.controls; - #if mobileC - var _virtualpad:FlxVirtualPad; + private var assets:Array = []; - var trackedinputsUI:Array = []; - var trackedinputsNOTES:Array = []; + override function create() + { + (cast (Lib.current.getChildAt(0), Main)).setFPSCap(FlxG.save.data.fpsCap); - // adding virtualpad to state - public function addVirtualPad(?DPad:FlxDPadMode, ?Action:FlxActionMode) { - _virtualpad = new FlxVirtualPad(DPad, Action); - _virtualpad.alpha = 0.75; - add(_virtualpad); - controls.setVirtualPadUI(_virtualpad, DPad, Action); - trackedinputsUI = controls.trackedinputsUI; - controls.trackedinputsUI = []; - } - - override function destroy() { - controls.removeFlxInput(trackedinputsUI); - controls.removeFlxInput(trackedinputsNOTES); - - super.destroy(); - } - #else - public function addVirtualPad(?DPad, ?Action){}; - #end + if (transIn != null) + trace('reg ' + transIn.region); - override function create() { - var skip:Bool = FlxTransitionableState.skipNextTransOut; super.create(); - - // Custom made Trans out - if(!skip) { - openSubState(new CustomFadeTransition(1, true)); - } - FlxTransitionableState.skipNextTransOut = false; } + + var array:Array = [ + FlxColor.fromRGB(148, 0, 211), + FlxColor.fromRGB(75, 0, 130), + FlxColor.fromRGB(0, 0, 255), + FlxColor.fromRGB(0, 255, 0), + FlxColor.fromRGB(255, 255, 0), + FlxColor.fromRGB(255, 127, 0), + FlxColor.fromRGB(255, 0 , 0) + ]; + + var skippedFrames = 0; + override function update(elapsed:Float) { //everyStep(); @@ -78,14 +62,39 @@ class MusicBeatState extends FlxUIState if (oldStep != curStep && curStep > 0) stepHit(); + if (FlxG.save.data.fpsRain && skippedFrames >= 6) + { + if (currentColor >= array.length) + currentColor = 0; + (cast (Lib.current.getChildAt(0), Main)).changeFPSColor(array[currentColor]); + currentColor++; + skippedFrames = 0; + } + else + skippedFrames++; + + if ((cast (Lib.current.getChildAt(0), Main)).getFPSCap != FlxG.save.data.fpsCap && FlxG.save.data.fpsCap <= 290) + (cast (Lib.current.getChildAt(0), Main)).setFPSCap(FlxG.save.data.fpsCap); + super.update(elapsed); } private function updateBeat():Void { + lastBeat = curStep; curBeat = Math.floor(curStep / 4); } + public function clean() + { + for (i in assets) + { + remove(i); + } + } + + public static var currentColor = 0; + private function updateCurStep():Void { var lastChange:BPMChangeEvent = { @@ -99,44 +108,12 @@ class MusicBeatState extends FlxUIState lastChange = Conductor.bpmChangeMap[i]; } - curStep = lastChange.stepTime + Math.floor(((Conductor.songPosition - ClientPrefs.noteOffset) - lastChange.songTime) / Conductor.stepCrochet); - } - - public static function switchState(nextState:FlxState) { - // Custom made Trans in - var curState:Dynamic = FlxG.state; - var leState:MusicBeatState = curState; - if(!FlxTransitionableState.skipNextTransIn) { - leState.openSubState(new CustomFadeTransition(0.7, false)); - if(nextState == FlxG.state) { - CustomFadeTransition.finishCallback = function() { - FlxG.resetState(); - }; - //trace('resetted'); - } else { - CustomFadeTransition.finishCallback = function() { - FlxG.switchState(nextState); - }; - //trace('changed state'); - } - return; - } - FlxTransitionableState.skipNextTransIn = false; - FlxG.switchState(nextState); - } - - public static function resetState() { - MusicBeatState.switchState(FlxG.state); - } - - public static function getState():MusicBeatState { - var curState:Dynamic = FlxG.state; - var leState:MusicBeatState = curState; - return leState; + curStep = lastChange.stepTime + Math.floor((Conductor.songPosition - lastChange.songTime) / Conductor.stepCrochet); } public function stepHit():Void { + if (curStep % 4 == 0) beatHit(); } @@ -145,4 +122,13 @@ class MusicBeatState extends FlxUIState { //do literally nothing dumbass } + + public function fancyOpenURL(schmancy:String) + { + #if linux + Sys.command('/usr/bin/xdg-open', [schmancy, "&"]); + #else + FlxG.openURL(schmancy); + #end + } } diff --git a/source/MusicBeatSubstate.hx b/source/MusicBeatSubstate.hx index e317dfdab..c6da0fb59 100644 --- a/source/MusicBeatSubstate.hx +++ b/source/MusicBeatSubstate.hx @@ -3,13 +3,6 @@ package; import Conductor.BPMChangeEvent; import flixel.FlxG; import flixel.FlxSubState; -import flixel.FlxBasic; -import flixel.FlxSprite; -#if mobileC -import flixel.FlxCamera; -import flixel.input.actions.FlxActionInput; -import ui.FlxVirtualPad; -#end class MusicBeatSubstate extends FlxSubState { @@ -28,32 +21,6 @@ class MusicBeatSubstate extends FlxSubState inline function get_controls():Controls return PlayerSettings.player1.controls; - #if mobileC - var _virtualpad:FlxVirtualPad; - - var trackedinputsUI:Array = []; - var trackedinputsNOTES:Array = []; - - // adding virtualpad to state - public function addVirtualPad(?DPad:FlxDPadMode, ?Action:FlxActionMode) { - _virtualpad = new FlxVirtualPad(DPad, Action); - _virtualpad.alpha = 0.75; - add(_virtualpad); - controls.setVirtualPadUI(_virtualpad, DPad, Action); - trackedinputsUI = controls.trackedinputsUI; - controls.trackedinputsUI = []; - } - - override function destroy() { - controls.removeFlxInput(trackedinputsUI); - controls.removeFlxInput(trackedinputsNOTES); - - super.destroy(); - } - #else - public function addVirtualPad(?DPad, ?Action){}; - #end - override function update(elapsed:Float) { //everyStep(); diff --git a/source/NGio.hx b/source/NGio.hx new file mode 100644 index 000000000..f8d8948e5 --- /dev/null +++ b/source/NGio.hx @@ -0,0 +1,200 @@ +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; + +using StringTools; + +/** + * MADE BY GEOKURELI THE LEGENED GOD HERO MVP + */ +class NGio +{ + public static var isLoggedIn:Bool = false; + public static var scoreboardsLoaded:Bool = false; + + public static var scoreboardArray:Array = []; + + 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 GAME_VER_NUMS:String = ''; + public static var gotOnlineVer:Bool = false; + + public static function noLogin(api:String) + { + trace('INIT NOLOGIN'); + GAME_VER = "v" + Application.current.meta.get('version'); + + if (api.length != 0) + { + 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.currentVersion; + GAME_VER_NUMS = GAME_VER.split(" ")[0].trim(); + trace('CURRENT NG VERSION: ' + GAME_VER); + trace('CURRENT NG VERSION: ' + GAME_VER_NUMS); + gotOnlineVer = true; + }); + + call.send(); + }); + } + } + + public function new(api:String, encKey:String, ?sessionId:String) + { + trace("connecting to newgrounds"); + + NG.createAndCheckSession(api, sessionId); + + NG.core.verbose = true; + // Set the encryption cipher/format to RC4/Base64. AES128 and Hex are not implemented yet + NG.core.initEncryption(encKey); // Found in you NG project view + + trace(NG.core.attemptingLogin); + + if (NG.core.attemptingLogin) + { + /* a session_id was found in the loadervars, this means the user is playing on newgrounds.com + * and we should login shortly. lets wait for that to happen + */ + trace("attempting login"); + NG.core.onLogin.add(onNGLogin); + } + else + { + /* They are NOT playing on newgrounds.com, no session id was found. We must start one manually, if we want to. + * Note: This will cause a new browser window to pop up where they can log in to newgrounds + */ + NG.core.requestLogin(onNGLogin); + } + } + + function onNGLogin():Void + { + trace('logged in! user:${NG.core.user.name}'); + isLoggedIn = true; + FlxG.save.data.sessionId = NG.core.sessionId; + // FlxG.save.flush(); + // Load medals then call onNGMedalFetch() + NG.core.requestMedals(onNGMedalFetch); + + // Load Scoreboards hten call onNGBoardsFetch() + NG.core.requestScoreBoards(onNGBoardsFetch); + + ngDataLoaded.dispatch(); + } + + // --- MEDALS + function onNGMedalFetch():Void + { + /* + // Reading medal info + for (id in NG.core.medals.keys()) + { + var medal = NG.core.medals.get(id); + trace('loaded medal id:$id, name:${medal.name}, description:${medal.description}'); + } + + // Unlocking medals + var unlockingMedal = NG.core.medals.get(54352);// medal ids are listed in your NG project viewer + if (!unlockingMedal.unlocked) + unlockingMedal.sendUnlock(); + */ + } + + // --- SCOREBOARDS + function onNGBoardsFetch():Void + { + /* + // Reading medal info + for (id in NG.core.scoreBoards.keys()) + { + var board = NG.core.scoreBoards.get(id); + trace('loaded scoreboard id:$id, name:${board.name}'); + } + */ + // var board = NG.core.scoreBoards.get(8004);// ID found in NG project view + + // Posting a score thats OVER 9000! + // board.postScore(FlxG.random.int(0, 1000)); + + // --- To view the scores you first need to select the range of scores you want to see --- + + // add an update listener so we know when we get the new scores + // board.onUpdate.add(onNGScoresFetch); + trace("shoulda got score by NOW!"); + // board.requestScores(20);// get the best 10 scores ever logged + // more info on scores --- http://www.newgrounds.io/help/components/#scoreboard-getscores + } + + inline static public function postScore(score:Int = 0, song:String) + { + if (isLoggedIn) + { + for (id in NG.core.scoreBoards.keys()) + { + var board = NG.core.scoreBoards.get(id); + + if (song == board.name) + { + board.postScore(score, "Uhh meow?"); + } + + // trace('loaded scoreboard id:$id, name:${board.name}'); + } + } + } + + function onNGScoresFetch():Void + { + scoreboardsLoaded = true; + + ngScoresLoaded.dispatch(); + /* + for (score in NG.core.scoreBoards.get(8737).scores) + { + trace('score loaded user:${score.user.name}, score:${score.formatted_value}'); + + } + */ + + // var board = NG.core.scoreBoards.get(8004);// ID found in NG project view + // board.postScore(HighScore.score); + + // NGio.scoreboardArray = NG.core.scoreBoards.get(8004).scores; + } + + inline static public function logEvent(event:String) + { + NG.core.calls.event.logEvent(event).send(); + trace('should have logged: ' + event); + } + + inline static public function unlockMedal(id:Int) + { + if (isLoggedIn) + { + var medal = NG.core.medals.get(id); + if (!medal.unlocked) + medal.sendUnlock(); + } + } +} diff --git a/source/NeonightState.hx b/source/NeonightState.hx new file mode 100644 index 000000000..9662576a5 --- /dev/null +++ b/source/NeonightState.hx @@ -0,0 +1,381 @@ +package; + +import flash.text.TextField; +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.addons.display.FlxGridOverlay; +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.math.FlxMath; +import flixel.text.FlxText; +import flixel.util.FlxColor; +import lime.utils.Assets; +import flixel.effects.FlxFlicker; +import flixel.tweens.FlxTween; +import sys.FileSystem; +import flixel.util.FlxTimer; + +#if desktop +import Discord.DiscordClient; +#end + +using StringTools; + +class NeonightState extends MusicBeatState +{ + var songs:Array = []; + + var selector:FlxText; + var curSelected:Int = 0; + var curDifficulty:Int = 3; + + var scoreText:FlxText; + var diffText:FlxText; + var comboText:FlxText; + var lerpScore:Int = 0; + var intendedScore:Int = 0; + var combo:String = ''; + + var warning:Bool = false; + var canMove:Bool = true; + + private var grpSongs:FlxTypedGroup; + private var curPlaying:Bool = false; + public static var downscroll:Bool = false; + + private var iconArray:Array = []; + + override function create() + { + FlxG.mouse.visible = false; + + Paths.clearStoredMemory(); + Paths.clearUnusedMemory(); + WeekData.reloadWeekFiles(false, 3); + + for (i in 0...WeekData.weeksList.length) { + var leWeek:WeekData = WeekData.weeksLoaded.get(WeekData.weeksList[i]); + var leSongs:Array = []; + var leChars:Array = []; + for (j in 0...leWeek.songs.length) + { + leSongs.push(leWeek.songs[j][0]); + leChars.push(leWeek.songs[j][1]); + } + + WeekData.setDirectoryFromWeek(leWeek); + for (song in leWeek.songs) + { + var colors:Array = song[2]; + if(colors == null || colors.length < 3) + { + colors = [146, 113, 253]; + } + addSong(song[0], i, song[1]); + } + } + WeekData.setDirectoryFromWeek(); + + if (songs.length < 1) + { + addSong('Placeholder', 0, 'face'); + warning = true; + trace('warn em bro!'); + } + + if (FlxG.sound.music != null) + { + FlxG.sound.music.fadeIn(2, 0, 0.8); + FlxG.sound.playMusic(Paths.music('neonight'), 0); + } + + #if desktop + // Updating Discord Rich Presence + DiscordClient.changePresence("In Neonight BETADCIU Menu", null); + #end + + var isDebug:Bool = false; + + MainMenuState.mainMusic = false; + + #if debug + isDebug = true; + #end + + //addWeek(['Split-Ex', 'Crucify'], 1, ['amor-ex', 'taki']); + //addWeek(['Sorrow', 'Shinkyoku'], 2, ['calli', 'duet-sm']); + + // LOAD MUSIC + + // LOAD CHARACTERS + + var bg:FlxSprite = new FlxSprite(-1300, -90).loadGraphic(Paths.image('menuNEO')); + add(bg); + + grpSongs = new FlxTypedGroup(); + add(grpSongs); + + for (i in 0...songs.length) + { + var songText:Alphabet = new Alphabet(0, (70 * i) + 30, songs[i].songName, true, false); + songText.isMenuItem = true; + songText.targetY = i; + grpSongs.add(songText); + + Paths.currentModDirectory = songs[i].folder; + var icon:HealthIcon = new HealthIcon(songs[i].songCharacter); + icon.sprTracker = songText; + + // using a FlxGroup is too much fuss! + iconArray.push(icon); + add(icon); + + // songText.x += 40; + // DONT PUT X IN THE FIRST PARAMETER OF new ALPHABET() !! + // songText.screenCenter(X); + } + + WeekData.setDirectoryFromWeek(); + + scoreText = new FlxText(FlxG.width * 0.7, 5, 0, "", 32); + // scoreText.autoSize = false; + scoreText.setFormat(Paths.font("neo.ttf"), 32, FlxColor.WHITE, RIGHT); + // scoreText.alignment = RIGHT; + + var scoreBG:FlxSprite = new FlxSprite(scoreText.x - 6, 0).makeGraphic(Std.int(FlxG.width * 0.35), 66, 0xFF000000); + scoreBG.alpha = 0.6; + add(scoreBG); + + diffText = new FlxText(scoreText.x, scoreText.y + 36, 0, "", 24); + diffText.font = scoreText.font; + add(diffText); + + comboText = new FlxText(diffText.x + 100, diffText.y, 0, "", 24); + comboText.font = diffText.font; + add(comboText); + + add(scoreText); + + changeSelection(); + + // FlxG.sound.playMusic(Paths.music('title'), 0); + // FlxG.sound.music.fadeIn(2, 0, 0.8); + selector = new FlxText(); + + selector.size = 40; + selector.text = ">"; + // add(selector); + + var swag:Alphabet = new Alphabet(1, 0, "swag"); + + // JUST DOIN THIS SHIT FOR TESTING!!! + /* + var md:String = Markdown.markdownToHtml(Assets.getText('CHANGELOG.md')); + + var texFel:TextField = new TextField(); + texFel.width = FlxG.width; + texFel.height = FlxG.height; + // texFel. + texFel.htmlText = md; + + FlxG.stage.addChild(texFel); + + // scoreText.textField.htmlText = md; + + trace(md); + */ + + if (warning) + { + var blackScreen = new FlxSprite(-100, -100).makeGraphic(Std.int(FlxG.width * 0.5), Std.int(FlxG.height * 0.5), FlxColor.BLACK); + blackScreen.screenCenter(); + blackScreen.scrollFactor.set(); + blackScreen.visible = false; + add(blackScreen); + + blackScreen.visible = true; + canMove = false; + + var daText = new FlxText(0, 0, 0, "No BETADCIUs Detected! \n Press enter to return to main menu.", 48); + daText.setFormat(Paths.font("vcr.ttf"), 48, FlxColor.WHITE, CENTER); + daText.screenCenter(); + daText.x += 20; + daText.y -= 100; + add(daText); + + var daText2 = new FlxText(0, 0, Std.int(FlxG.width * 0.45), "Press enter to return to the main menu.", 44); + daText2.setFormat(Paths.font("vcr.ttf"), 44, FlxColor.WHITE, CENTER); + daText2.screenCenter(); + daText2.y += 100; + add(daText2); + } + + super.create(); + } + + public function addSong(songName:String, weekNum:Int, songCharacter:String) + { + songs.push(new FreeplayState.SongMetadata(songName, weekNum, songCharacter)); + } + + public function addWeek(songs:Array, weekNum:Int, ?songCharacters:Array) + { + if (songCharacters == null) + songCharacters = ['bf']; + + var num:Int = 0; + for (song in songs) + { + addSong(song, weekNum, songCharacters[num]); + + if (songCharacters.length != 1) + num++; + } + } + + override function update(elapsed:Float) + { + super.update(elapsed); + + if (FlxG.sound.music.volume < 0.7) + { + FlxG.sound.music.volume += 0.5 * FlxG.elapsed; + } + + lerpScore = Math.floor(FlxMath.lerp(lerpScore, intendedScore, 0.4)); + + if (Math.abs(lerpScore - intendedScore) <= 10) + lerpScore = intendedScore; + + scoreText.text = "PERSONAL BEST:" + lerpScore; + comboText.text = combo + '\n'; + + var upP = controls.UP_P; + var downP = controls.DOWN_P; + var accepted = controls.ACCEPT; + + if (warning && accepted) + FlxG.switchState(new MainMenuState()); + + if (upP && canMove) + changeSelection(-1); + + if (downP && canMove) + changeSelection(1); + + if (controls.BACK && canMove) + FlxG.switchState(new MainMenuState()); + + if (accepted && canMove) + { + var poop:String = Highscore.formatSong(songs[curSelected].songName.toLowerCase(), curDifficulty); + + trace(poop); + + PlayState.SONG = Song.loadFromJson(poop, songs[curSelected].songName.toLowerCase()); + PlayState.isStoryMode = false; + PlayState.isNeonight = true; + PlayState.isVitor = false; + PlayState.isBETADCIU = false; + PlayState.isBonus = false; + PlayState.storyDifficulty = curDifficulty; + canMove = false; + + PlayState.storyWeek = songs[curSelected].week; + trace('CUR WEEK' + PlayState.storyWeek); + var llll = FlxG.sound.play(Paths.sound('confirmMenu')).length; + + if (songs.length < 2) // the tween doesn't finish if it's just one song + { + new FlxTimer().start(llll/1000, function(tmr:FlxTimer) + { + if (FlxG.keys.pressed.ALT){ + FlxG.switchState(new ChartingState()); + }else{ + if (Main.hiddenSongs.contains(songs[curSelected].songName.toLowerCase()) && !Main.isHidden || PlayState.SONG.song == 'Restore' && !Main.restoreUnlocked || PlayState.SONG.song == 'Deathmatch-Holo' && !Main.deathHolo) + LoadingState.loadAndSwitchState(new GoFindTheSecretState()); + else + LoadingState.loadAndSwitchState(new CustomLoading()); + } + }); + } + + grpSongs.forEach(function(e:Alphabet){ + if (e.text != songs[curSelected].songName){ + FlxTween.tween(e, {x: -6000}, llll / 1000,{onComplete:function(e:FlxTween){ + + if (FlxG.keys.pressed.ALT){ + FlxG.switchState(new ChartingState()); + }else{ + LoadingState.loadAndSwitchState(new PlayState()); + } + }}); + }else{ + FlxFlicker.flicker(e); + trace(curSelected); + FlxTween.tween(e, {x: e.x + 20}, llll/1000); + } + }); + } + + #if !switch + intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty); + combo = Highscore.getCombo(songs[curSelected].songName, curDifficulty); + #end + + switch (curDifficulty) + { + case 3: + diffText.text = "HARD"; + } + } + + function changeSelection(change:Int = 0) + { + #if !switch + // NGio.logEvent('Fresh'); + #end + + // NGio.logEvent('Fresh'); + FlxG.sound.play(Paths.sound('scrollMenu'), 0.4); + + curSelected += change; + + if (curSelected < 0) + curSelected = songs.length - 1; + if (curSelected >= songs.length) + curSelected = 0; + + // selector.y = (70 * curSelected) + 30; + + #if !switch + intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty); + combo = Highscore.getCombo(songs[curSelected].songName, curDifficulty); + // lerpScore = 0; + #end + + var bullShit:Int = 0; + + for (i in 0...iconArray.length) + { + iconArray[i].alpha = 0.6; + } + + iconArray[curSelected].alpha = 1; + Paths.currentModDirectory = songs[curSelected].folder; + + for (item in grpSongs.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)); + } + } + } +} \ No newline at end of file diff --git a/source/Note.hx b/source/Note.hx index 4060e4af3..e6754fa4a 100644 --- a/source/Note.hx +++ b/source/Note.hx @@ -1,356 +1,963 @@ -package; - -import flixel.FlxG; -import flixel.FlxSprite; -import flixel.graphics.frames.FlxAtlasFrames; -import flixel.math.FlxMath; -import flixel.util.FlxColor; -import flash.display.BitmapData; -import editors.ChartingState; - -using StringTools; - -class Note extends FlxSprite -{ - public var strumTime:Float = 0; - - public var mustPress:Bool = false; - public var noteData:Int = 0; - public var canBeHit:Bool = false; - public var tooLate:Bool = false; - public var wasGoodHit:Bool = false; - public var ignoreNote:Bool = false; - public var hitByOpponent:Bool = false; - public var noteWasHit:Bool = false; - public var prevNote:Note; - - public var sustainLength:Float = 0; - public var isSustainNote:Bool = false; - public var noteType(default, set):String = null; - - public var eventName:String = ''; - public var eventLength:Int = 0; - public var eventVal1:String = ''; - public var eventVal2:String = ''; - - public var colorSwap:ColorSwap; - public var inEditor:Bool = false; - public var gfNote:Bool = false; - private var earlyHitMult:Float = 0.5; - - public static var swagWidth:Float = 160 * 0.7; - public static var PURP_NOTE:Int = 0; - public static var GREEN_NOTE:Int = 2; - public static var BLUE_NOTE:Int = 1; - public static var RED_NOTE:Int = 3; - - // Lua shit - public var noteSplashDisabled:Bool = false; - public var noteSplashTexture:String = null; - public var noteSplashHue:Float = 0; - public var noteSplashSat:Float = 0; - public var noteSplashBrt:Float = 0; - - public var offsetX:Float = 0; - public var offsetY:Float = 0; - public var offsetAngle:Float = 0; - public var multAlpha:Float = 1; - - public var copyX:Bool = true; - public var copyY:Bool = true; - public var copyAngle:Bool = true; - public var copyAlpha:Bool = true; - - public var hitHealth:Float = 0.023; - public var missHealth:Float = 0.0475; - - public var texture(default, set):String = null; - - public var noAnimation:Bool = false; - public var hitCausesMiss:Bool = false; - public var distance:Float = 2000;//plan on doing scroll directions soon -bb - - private function set_texture(value:String):String { - if(texture != value) { - reloadNote('', value); - } - texture = value; - return value; - } - - private function set_noteType(value:String):String { - noteSplashTexture = PlayState.SONG.splashSkin; - colorSwap.hue = ClientPrefs.arrowHSV[noteData % 4][0] / 360; - colorSwap.saturation = ClientPrefs.arrowHSV[noteData % 4][1] / 100; - colorSwap.brightness = ClientPrefs.arrowHSV[noteData % 4][2] / 100; - - if(noteData > -1 && noteType != value) { - switch(value) { - case 'Hurt Note': - ignoreNote = mustPress; - reloadNote('HURT'); - noteSplashTexture = 'HURTnoteSplashes'; - colorSwap.hue = 0; - colorSwap.saturation = 0; - colorSwap.brightness = 0; - if(isSustainNote) { - missHealth = 0.1; - } else { - missHealth = 0.3; - } - hitCausesMiss = true; - case 'No Animation': - noAnimation = true; - case 'GF Sing': - gfNote = true; - } - noteType = value; - } - noteSplashHue = colorSwap.hue; - noteSplashSat = colorSwap.saturation; - noteSplashBrt = colorSwap.brightness; - return value; - } - - public function new(strumTime:Float, noteData:Int, ?prevNote:Note, ?sustainNote:Bool = false, ?inEditor:Bool = false) - { - super(); - - if (prevNote == null) - prevNote = this; - - this.prevNote = prevNote; - isSustainNote = sustainNote; - this.inEditor = inEditor; - - x += (ClientPrefs.middleScroll ? PlayState.STRUM_X_MIDDLESCROLL : PlayState.STRUM_X) + 50; - // MAKE SURE ITS DEFINITELY OFF SCREEN? - y -= 2000; - this.strumTime = strumTime; - if(!inEditor) this.strumTime += ClientPrefs.noteOffset; - - this.noteData = noteData; - - if(noteData > -1) { - texture = ''; - colorSwap = new ColorSwap(); - shader = colorSwap.shader; - - x += swagWidth * (noteData % 4); - if(!isSustainNote) { //Doing this 'if' check to fix the warnings on Senpai songs - var animToPlay:String = ''; - switch (noteData % 4) - { - case 0: - animToPlay = 'purple'; - case 1: - animToPlay = 'blue'; - case 2: - animToPlay = 'green'; - case 3: - animToPlay = 'red'; - } - animation.play(animToPlay + 'Scroll'); - } - } - - // trace(prevNote); - - if (isSustainNote && prevNote != null) - { - alpha = 0.6; - multAlpha = 0.6; - if(ClientPrefs.downScroll) flipY = true; - - offsetX += width / 2; - copyAngle = false; - - switch (noteData) - { - case 0: - animation.play('purpleholdend'); - case 1: - animation.play('blueholdend'); - case 2: - animation.play('greenholdend'); - case 3: - animation.play('redholdend'); - } - - updateHitbox(); - - offsetX -= width / 2; - - if (PlayState.isPixelStage) - offsetX += 30; - - if (prevNote.isSustainNote) - { - switch (prevNote.noteData) - { - case 0: - prevNote.animation.play('purplehold'); - case 1: - prevNote.animation.play('bluehold'); - case 2: - prevNote.animation.play('greenhold'); - case 3: - prevNote.animation.play('redhold'); - } - - prevNote.scale.y *= Conductor.stepCrochet / 100 * 1.05; - if(PlayState.instance != null) - { - prevNote.scale.y *= PlayState.instance.songSpeed; - } - - if(PlayState.isPixelStage) { - prevNote.scale.y *= 1.19; - } - prevNote.updateHitbox(); - // prevNote.setGraphicSize(); - } - - if(PlayState.isPixelStage) { - scale.y *= PlayState.daPixelZoom; - updateHitbox(); - } - } else if(!isSustainNote) { - earlyHitMult = 1; - } - x += offsetX; - } - - function reloadNote(?prefix:String = '', ?texture:String = '', ?suffix:String = '') { - if(prefix == null) prefix = ''; - if(texture == null) texture = ''; - if(suffix == null) suffix = ''; - - var skin:String = texture; - if(texture.length < 1) { - skin = PlayState.SONG.arrowSkin; - if(skin == null || skin.length < 1) { - skin = 'NOTE_assets'; - } - } - - var animName:String = null; - if(animation.curAnim != null) { - animName = animation.curAnim.name; - } - - var arraySkin:Array = skin.split('/'); - arraySkin[arraySkin.length-1] = prefix + arraySkin[arraySkin.length-1] + suffix; - - var lastScaleY:Float = scale.y; - var blahblah:String = arraySkin.join('/'); - if(PlayState.isPixelStage) { - if(isSustainNote) { - loadGraphic(Paths.image('pixelUI/' + blahblah + 'ENDS')); - width = width / 4; - height = height / 2; - loadGraphic(Paths.image('pixelUI/' + blahblah + 'ENDS'), true, Math.floor(width), Math.floor(height)); - } else { - loadGraphic(Paths.image('pixelUI/' + blahblah)); - width = width / 4; - height = height / 5; - loadGraphic(Paths.image('pixelUI/' + blahblah), true, Math.floor(width), Math.floor(height)); - } - setGraphicSize(Std.int(width * PlayState.daPixelZoom)); - loadPixelNoteAnims(); - antialiasing = false; - } else { - frames = Paths.getSparrowAtlas(blahblah); - loadNoteAnims(); - antialiasing = ClientPrefs.globalAntialiasing; - } - if(isSustainNote) { - scale.y = lastScaleY; - if(ClientPrefs.keSustains) { - scale.y *= 0.75; - } - } - updateHitbox(); - - if(animName != null) - animation.play(animName, true); - - if(inEditor) { - setGraphicSize(ChartingState.GRID_SIZE, ChartingState.GRID_SIZE); - updateHitbox(); - } - } - - function loadNoteAnims() { - animation.addByPrefix('greenScroll', 'green0'); - animation.addByPrefix('redScroll', 'red0'); - animation.addByPrefix('blueScroll', 'blue0'); - animation.addByPrefix('purpleScroll', 'purple0'); - - if (isSustainNote) - { - 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(); - } - - function loadPixelNoteAnims() { - if(isSustainNote) { - animation.add('purpleholdend', [PURP_NOTE + 4]); - animation.add('greenholdend', [GREEN_NOTE + 4]); - animation.add('redholdend', [RED_NOTE + 4]); - animation.add('blueholdend', [BLUE_NOTE + 4]); - - animation.add('purplehold', [PURP_NOTE]); - animation.add('greenhold', [GREEN_NOTE]); - animation.add('redhold', [RED_NOTE]); - animation.add('bluehold', [BLUE_NOTE]); - } else { - animation.add('greenScroll', [GREEN_NOTE + 4]); - animation.add('redScroll', [RED_NOTE + 4]); - animation.add('blueScroll', [BLUE_NOTE + 4]); - animation.add('purpleScroll', [PURP_NOTE + 4]); - } - } - - override function update(elapsed:Float) - { - super.update(elapsed); - - if (mustPress) - { - // ok river - if (strumTime > Conductor.songPosition - Conductor.safeZoneOffset - && strumTime < Conductor.songPosition + (Conductor.safeZoneOffset * earlyHitMult)) - canBeHit = true; - else - canBeHit = false; - - if (strumTime < Conductor.songPosition - Conductor.safeZoneOffset && !wasGoodHit) - tooLate = true; - } - else - { - canBeHit = false; - - if (strumTime <= Conductor.songPosition) - wasGoodHit = true; - } - - if (tooLate && !inEditor) - { - if (alpha > 0.3) - alpha = 0.3; - } - } -} +package; + +import flixel.addons.effects.FlxSkewedSprite; +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.graphics.frames.FlxAtlasFrames; +import lime.utils.Assets; +import sys.io.File; +import sys.FileSystem; +import flixel.math.FlxMath; +import flixel.util.FlxColor; +#if polymod +import polymod.format.ParseRules.TargetSignatureElement; +#end +import PlayState; +import LuaClass.LuaNote; +import Type.ValueType; + +using StringTools; + +class Note extends FlxSprite +{ + public var strumTime:Float = 0; + + public var LuaNote:LuaNote; + + public var mustPress:Bool = false; + public var noteData:Int = 0; + public var canBeHit:Bool = false; + public var tooLate:Bool = false; + public var wasGoodHit:Bool = false; + public var prevNote:Note; + public var modifiedByLua:Bool = false; + public var sustainLength:Float = 0; + public var isSustainNote:Bool = false; + public var noteType(default, set):String = null; + + public var style:String = ""; + public var mania:Int = 0; + public var dType:Int = 0; + public var pixelBurn:Bool = false; + public var blackStatic:Bool = false; + public static var mickeyNotes:Bool = false; + public static var auditorNotes:Bool = false; + public var isAuditorNote:Bool = false; + + public var noteScore:Float = 1; + + public var luaID:Int = 0; + + public var offsetX:Float = 0; + public var offsetY:Float = 0; + public var offsetAngle:Float = 0; + public var multAlpha:Float = 1; + + //different notes + public var markov:Bool = false; + public var danger:Bool = false; + public var burning:Bool = false; + public var staticNote:Bool = false; + public var bomb:Bool = false; + public var neonNote:Bool = false; + public var biteNote:Bool = false; + public var earlyHitMult:Float = 1; + public var lateHitMult:Float = 1; + + public static var swagWidth:Float = 160 * 0.7; + public static var noteScale:Float; + public static var PURP_NOTE:Int = 0; + public static var GREEN_NOTE:Int = 2; + public static var BLUE_NOTE:Int = 1; + public static var RED_NOTE:Int = 3; + public static var tooMuch:Float = 30; + public static var scales:Array = [0.7, 0.6, 0.46, 0.66, 0.55]; + public static var swidths:Array = [160, 120, 90, 140, 110]; + public static var posRest:Array = [0, 35, 70, 60, 20]; + public var curSpeed:Float; + public var downscroll:Bool = false; //just use false for upscroll + var pre:String; + var suf:String; + + //detected + public var modAngle:Float = 0; // The angle set by modcharts + + public var rating:String = "shit"; + + public var hitHealth:Float = 0.023; + public var missHealth:Float = 0.0475; + public var noAnimation:Bool = false; + public var hitCausesMiss:Bool = false; + public var gfNote:Bool = false; + public var ignoreNote:Bool = false; + public var canMiss:Bool = false; + public var noRating:Bool = false; + + public var texture(default, set):String = null; + private function set_texture(value:String):String { + reloadNote(value); + return value; + } + + private function set_noteType(value:String):String { + + if(noteData > -1 && noteType != value) { + switch(value) { + case 'Hurt Note': + ignoreNote = mustPress; + if(isSustainNote) { + missHealth = 0.1; + } else { + missHealth = 0.3; + } + hitCausesMiss = true; + case 'No Animation': + noAnimation = true; + case 'GF Sing': + gfNote = true; + } + noteType = value; + } + return value; + } + + + public function new(_strumTime:Float, _noteData:Int, ?_prevNote:Note, ?sustainNote:Bool = false, ?noteTypeOld:String = "", style:String = 'normal') + { + super(); + + mania = PlayState.SONG.mania; + + if (prevNote == null) + prevNote = this; + + prevNote = _prevNote; + + isSustainNote = sustainNote; + this.style = style; + + swagWidth = swidths[mania] * 0.7; //factor not the same as noteScale + noteScale = scales[mania]; + + if (PlayState.SONG.song.toLowerCase() == 'bonedoggle') + { + swagWidth = swidths[3] * 0.7; //factor not the same as noteScale + noteScale = scales[3]; + } + + if (style == 'exe' && mania == 3) + { + swagWidth = swidths[0] * 0.7; //factor not the same as noteScale + noteScale = scales[0]; + } + + x += 50 - posRest[mania]; + + // MAKE SURE ITS DEFINITELY OFF SCREEN? + y -= 2000; + + if (PlayState.SONG.mania == 2) + x -= tooMuch; + + strumTime = _strumTime; + + if (this.strumTime < 0 ) + this.strumTime = 0; + +// if (PlayState.curStage == 'auditorHell' && noteType == 4) +// auditorNotes = true; + + noteData = _noteData % Main.keyAmmo[mania]; + + var daStage:String = PlayState.curStage; + + if(isSustainNote) + { + /* switch (noteType) + { + case 2: markov = true; + case 3: danger = true; + case 4: burning = true; + case 5: staticNote = true; + case 6: bomb = true; + } */ + } + + //defaults if no noteStyle was found in chart + var noteTypeCheck:String = 'normal'; + + loadNoteAnims(style, sustainNote); + + var frameN:Array = ['purple', 'blue', 'green', 'red']; + switch (mania) + { + case 1: + frameN = ['purple', 'green', 'red', 'yellow', 'blue', 'dark']; + case 2: + if (PlayState.SONG.song.toLowerCase() == 'bonedoggle') + frameN = ['purple', 'blue', 'green', 'red', 'white', 'purple', 'blue', 'green', 'red']; + else + frameN = ['purple', 'blue', 'green', 'red', 'white', 'yellow', 'violet', 'black', 'dark']; + case 3: + frameN = ['purple', 'blue', 'white', 'green', 'red']; + case 4: + frameN = ['purple', 'green', 'red', 'white', 'yellow', 'blue', 'dark']; + } + + x += swidths[mania] * swagWidth * (noteData % Main.keyAmmo[mania]); + + if (!isSustainNote) + animation.play(frameN[noteData] + 'Scroll'); + + if (style == "guitar"){ + offset.x = -15; + offset.y = -30; + } + + if ((FlxG.save.data.downscroll || downscroll) && sustainNote) + flipY = true; + + if (isSustainNote && prevNote != null) + { + noteScore * 0.2; + alpha = 0.6; + + offsetX += width / 2; + + animation.play(frameN[noteData] + 'holdend'); + + updateHitbox(); + + offsetX -= width / 2 + 1; + + if (style == "guitar") + { + offsetX -= 20; + offset.x = -15; + } + + if (style.contains('pixel') || style == 'neon') + offsetX += 30; + + if (prevNote.isSustainNote) + { + prevNote.animation.play(frameN[prevNote.noteData] + 'hold'); + + if(FlxG.save.data.scrollSpeed != 1) + prevNote.scale.y *= Conductor.stepCrochet / 100 * 1.5 * FlxG.save.data.scrollSpeed; + else + prevNote.scale.y *= Conductor.stepCrochet / 100 * (1.5 * (0.7 - noteScale + 1)) * PlayState.SONG.speed; + + prevNote.updateHitbox(); + } + } + + x += offsetX; + } + + override function update(elapsed:Float) + { + super.update(elapsed); + + if ((FlxG.save.data.downscroll || downscroll) && isSustainNote) + flipY = true; + + if (modifiedByLua) + angle = modAngle; + + if (noteData == -1) + this.kill(); //removes psych event arrows when porting charts from psych. + + if(isSustainNote) + { + /* switch (noteType) + { + case 2 | 3 | 4 | 5 | 6: + this.kill(); + } */ + } + + if (mustPress) + { + /*switch (noteType) + { + case 4 | 6 | 8 | 9 | 10: + if (strumTime > Conductor.songPosition - (Conductor.safeZoneOffset * 0.6) + && strumTime < Conductor.songPosition + (Conductor.safeZoneOffset * 0.4)) // also they're almost impossible to hit late! + canBeHit = true; + else + canBeHit = false; + case 2: + if (strumTime > Conductor.songPosition - (Conductor.safeZoneOffset * 0.3) + && strumTime < Conductor.songPosition + (Conductor.safeZoneOffset * 0.2)) // also they're almost impossible to hit late! + canBeHit = true; + else + canBeHit = false; + default: + }*/ + + if (burning && PlayState.curStage == 'auditorHell' || burning && auditorNotes) // the auditor ones + { + if (strumTime > Conductor.songPosition - (Conductor.safeZoneOffset * 0.3) + && strumTime < Conductor.songPosition + (Conductor.safeZoneOffset * 0.2)) // also they're almost impossible to hit late! + canBeHit = true; + else + canBeHit = false; + } + else + { + if (isSustainNote) + { + if (strumTime > Conductor.songPosition - (Conductor.safeZoneOffset * 1.5) + && strumTime < Conductor.songPosition + (Conductor.safeZoneOffset * 0.5)) + canBeHit = true; + else + canBeHit = false; + } + else + { + if (strumTime > Conductor.songPosition - (Conductor.safeZoneOffset * lateHitMult) + && strumTime < Conductor.songPosition + (Conductor.safeZoneOffset * earlyHitMult)) + canBeHit = true; + else + canBeHit = false; + } + } + + if (strumTime < Conductor.songPosition - Conductor.safeZoneOffset * Conductor.timeScale && !wasGoodHit) + tooLate = true; + } + else + { + canBeHit = false; + + if (strumTime <= Conductor.songPosition) + wasGoodHit = true; + } + + if (tooLate) + { + if (alpha > 0.3) + alpha = 0.3; + } + } + + var reloadedNote:Bool = false; + + // testing for arrow switching mid song. stealing from psych + public function reloadNote(style2:String, ?noteTypeStyles:String = "") + { + noteTypeStyle = noteTypeStyles; + reloadedNote = true; + + var lastScaleY:Float = scale.y; + var wasPixelNote:Bool = style.contains('pixel'); + var becomePixelNote:Bool = style2.contains('pixel'); + + var animName:String = null; + if(animation.curAnim != null) { + animName = animation.curAnim.name; + } + + loadNoteAnims(style2, isSustainNote); + + if(animName != null) + animation.play(animName, true); + + if(isSustainNote) + { + scale.y = lastScaleY; + + if (wasPixelNote && !becomePixelNote) //fixes the scaling + { + scale.y /= PlayState.daPixelZoom; + scale.y *= noteScale; + } + + if (becomePixelNote && !wasPixelNote) //fixes the scaling + { + scale.y /= noteScale; + scale.y *= PlayState.daPixelZoom; + } + } + updateHitbox(); + + style = style2; + } + + public var noteTypeStyle:String = ""; + + function loadNoteAnims(style:String, ?sustainNote:Bool = false) + { + switch (style) + { + case 'pixel': //| 'pixel-corrupted' | 'neon' | 'doki-pixel': + var suf:String = ""; + switch (style) + { + case 'pixel-corrupted': + suf = '-corrupted'; + case 'neon': + suf = '-neon'; + case 'doki-pixel': + suf = '-doki'; + } + + if (isSustainNote) + loadGraphic(Paths.image('notes/arrowEnds'+suf), true, 7, 6); + else + loadGraphic(Paths.image('notes/arrows-pixels'+suf), true, 17, 17); + + addAnims(true); + + case 'pixel-combined': + loadGraphic(Paths.image('notes/arrows-pixelscombined'), true, 17, 17); + + animation.add('greenScroll', [6]); + animation.add('redScroll', [7]); + animation.add('blueScroll', [5]); + animation.add('purpleScroll', [4]); + + animation.add('redScroll2', [27]); + animation.add('greenScroll2', [26]); + animation.add('blueScroll2', [25]); + animation.add('purpleScroll2', [24]); + + if (isSustainNote) + { + loadGraphic(Paths.image('notes/arrowEndscombined'), 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]); + + animation.add('purpleholdend2', [12]); + animation.add('blueholdend2', [13]); + animation.add('greenholdend2', [14]); + animation.add('redholdend2', [15]); + + animation.add('purplehold2', [8]); + animation.add('bluehold2', [9]); + animation.add('greenhold2', [10]); + animation.add('redhold2', [11]); + } + + setGraphicSize(Std.int(width * PlayState.daPixelZoom)); + updateHitbox(); + + case 'auditor': + frames = Paths.getSparrowAtlas('notes/NOTE_assets'); + + 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'); + + if (burning) + { + frames = Paths.getSparrowAtlas('notes/ALL_deathnotes'); + animation.addByPrefix('greenScroll', 'Green Arrow'); + animation.addByPrefix('redScroll', 'Red Arrow'); + animation.addByPrefix('blueScroll', 'Blue Arrow'); + animation.addByPrefix('purpleScroll', 'Purple Arrow'); + } + + setGraphicSize(Std.int(width * 0.7)); + updateHitbox(); + antialiasing = true; + + case 'guitar': + frames = Paths.getSparrowAtlas('notes/GH_NOTES'); + + animation.addByPrefix('greenScroll', 'upNote0'); + animation.addByPrefix('redScroll', 'rightNote0'); + animation.addByPrefix('blueScroll', 'downNote0'); + animation.addByPrefix('purpleScroll', 'leftNote0'); + + animation.addByPrefix('purpleholdend', 'leftHoldEnd'); + animation.addByPrefix('greenholdend', 'upHoldEnd'); + animation.addByPrefix('redholdend', 'rightHoldEnd'); + animation.addByPrefix('blueholdend', 'downHoldEnd'); + + animation.addByPrefix('purplehold', 'leftHold0'); + animation.addByPrefix('greenhold', 'upHold0'); + animation.addByPrefix('redhold', 'rightHold0'); + animation.addByPrefix('bluehold', 'downHold0'); + + antialiasing = true; + + case 'empty': + frames = Paths.getSparrowAtlas('notes/Note_Assets_withPixel'); + + animation.addByPrefix('greenScroll', 'Up0'); + animation.addByPrefix('redScroll', 'Right0'); + animation.addByPrefix('blueScroll', 'Down0'); + animation.addByPrefix('purpleScroll', 'Left0'); + + animation.addByPrefix('purpleholdend', 'LeftHoldEnd'); + animation.addByPrefix('greenholdend', 'UpHoldEnd'); + animation.addByPrefix('redholdend', 'RightHoldEnd'); + animation.addByPrefix('blueholdend', 'DownHoldEnd'); + + animation.addByPrefix('purplehold', 'LeftHoldPiece'); + animation.addByPrefix('greenhold', 'UpHoldPiece'); + animation.addByPrefix('redhold', 'RightHoldPiece'); + animation.addByPrefix('bluehold', 'DownHoldPiece'); + + setGraphicSize(Std.int(width * 0.7)); + updateHitbox(); + antialiasing = true; + + default: + if (Assets.exists(Paths.image('notes/'+style))) + { + frames = Paths.getSparrowAtlas('notes/'+style); + + if (frames == null) + { + if (mania > 0) + frames = Paths.getSparrowAtlas('notes/shaggyNotes'); + else + frames = Paths.getSparrowAtlas('notes/NOTE_assets'); + } + + addAnims(); + } + else + { + if (FileSystem.exists(Paths.modsImages('notes/'+style))) + style = 'notes/'+style; + + if (FileSystem.exists(Paths.modsImages(style))) + { + if (!Paths.currentTrackedAssets.exists(style)) + Paths.cacheImage(style); + + var rawPic:Dynamic = Paths.currentTrackedAssets.get(style); + + if (!FileSystem.exists(Paths.modsXml(style))) + { + trace('isPixel'); + + if (isSustainNote) + loadGraphic(rawPic, true, 7, 6); + else + loadGraphic(rawPic, true, 17, 17); + + addAnims(true); + } + else + { + var rawXml = File.getContent(Paths.modsXml(style)); + + frames = FlxAtlasFrames.fromSparrow(rawPic, rawXml); + + if (frames == null) + { + if (mania > 0) + frames = Paths.getSparrowAtlas('notes/shaggyNotes'); + else + frames = Paths.getSparrowAtlas('notes/NOTE_assets'); + } + + addAnims(); + } + } + } + } + + /*switch (noteType) + { + case 2: + if (PlayState.SONG.noteStyle.contains('pixel') || PlayState.isPixel) + { + loadGraphic(Paths.image('notes/arrows-pixels'), true, 17, 17); + animation.add('greenScroll', [22]); + animation.add('redScroll', [23]); + animation.add('blueScroll', [21]); + animation.add('purpleScroll', [20]); + + antialiasing = false; + setGraphicSize(Std.int(width * PlayState.daPixelZoom)); + updateHitbox(); + } + else + { + frames = Paths.getSparrowAtlas('notes/markov'); + + animation.addByPrefix('greenScroll', 'markov green0'); + animation.addByPrefix('redScroll', 'markov red0'); + animation.addByPrefix('blueScroll', 'markov blue0'); + animation.addByPrefix('purpleScroll', 'markov purple0'); + + animation.addByPrefix('purpleholdend', 'markov pruple end hold'); + animation.addByPrefix('greenholdend', 'markov green hold end'); + animation.addByPrefix('redholdend', 'markov red hold end'); + animation.addByPrefix('blueholdend', 'markov blue hold end'); + + animation.addByPrefix('purplehold', 'markov purple hold piece'); + animation.addByPrefix('greenhold', 'markov green hold piece'); + animation.addByPrefix('redhold', 'markov red hold piece'); + animation.addByPrefix('bluehold', 'markov blue hold piece'); + + setGraphicSize(Std.int(width * 0.7)); + updateHitbox(); + antialiasing = true; + } + case 3: + if (PlayState.SONG.noteStyle.contains('pixel') || PlayState.isPixel) + { + loadGraphic(Paths.image('notes/warningNotePixel'), true, 16, 16); + + animation.add('greenScroll', [0]); + animation.add('redScroll', [0]); + animation.add('blueScroll', [0]); + animation.add('purpleScroll', [0]); + pixelBurn = true; + + setGraphicSize(Std.int(width * PlayState.daPixelZoom)); + updateHitbox(); + antialiasing = false; + } + else + { + switch (noteTypeStyle) + { + case 'hank': + loadGraphic(Paths.image('notes/bullet'), true, 150, 150); + + animation.add('greenScroll', [0]); + animation.add('redScroll', [3]); + animation.add('blueScroll', [1]); + animation.add('purpleScroll', [2]); + + setGraphicSize(Std.int(width * noteScale)); + updateHitbox(); + antialiasing = true; + return; + case 'bite': + frames = Paths.getSparrowAtlas('notes/biteNotes'); + + 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; + return; + case 'mami': + loadGraphic(Paths.image('notes/holynote'), true, 157, 154); + default: + loadGraphic(Paths.image('notes/warningNote'), true, 157, 154); + } + + animation.add('greenScroll', [0]); + animation.add('redScroll', [0]); + animation.add('blueScroll', [0]); + animation.add('purpleScroll', [0]); + + setGraphicSize(Std.int(width * noteScale)); + updateHitbox(); + antialiasing = true; + } + case 4: + if (PlayState.SONG.noteStyle.contains('pixel') || PlayState.isPixel) + { + loadGraphic(Paths.image('notes/NOTE_fire-pixel'), true, 21, 31); + + animation.add('greenScroll', [6, 7, 6, 8], 8); + animation.add('redScroll', [9, 10, 9, 11], 8); + animation.add('blueScroll', [3, 4, 3, 5], 8); + animation.add('purpleScroll', [0, 1 ,0, 2], 8); + offsetX -= 5; + + setGraphicSize(Std.int(width * PlayState.daPixelZoom)); + updateHitbox(); + antialiasing = false; + } + else + { + if (auditorNotes) + { + isAuditorNote = true; + + frames = Paths.getSparrowAtlas('notes/ALL_deathnotes'); + animation.addByPrefix('greenScroll', 'Green Arrow'); + animation.addByPrefix('redScroll', 'Red Arrow'); + animation.addByPrefix('blueScroll', 'Blue Arrow'); + animation.addByPrefix('purpleScroll', 'Purple Arrow'); + + setGraphicSize(Std.int(width * 0.7)); + updateHitbox(); + antialiasing = true; + + offsetX -= 165; + } + else + { + frames = Paths.getSparrowAtlas('notes/NOTE_fire'); + if(!FlxG.save.data.downscroll){ + animation.addByPrefix('blueScroll', 'blue fire'); + animation.addByPrefix('greenScroll', 'green fire'); + } + else{ + animation.addByPrefix('greenScroll', 'blue fire'); + animation.addByPrefix('blueScroll', 'green fire'); + } + animation.addByPrefix('redScroll', 'red fire'); + animation.addByPrefix('purpleScroll', 'purple fire'); + + if((FlxG.save.data.downscroll || downscroll)) + flipY = true; + + offsetX -= 40; + + setGraphicSize(Std.int(width * noteScale)); + updateHitbox(); + antialiasing = true; + } + } + case 5: + if (noteTypeStyle == 'neonNote') + { + loadGraphic(Paths.image('notes/exeNotes-neon'), true, 17, 17); + + animation.add('greenScroll', [6]); + animation.add('redScroll', [7]); + animation.add('blueScroll', [5]); + animation.add('purpleScroll', [4]); + + setGraphicSize(Std.int(width * PlayState.daPixelZoom)); + updateHitbox(); + antialiasing = false; + } + else + { + if (PlayState.SONG.noteStyle == '1930' || PlayState.SONG.noteStyle == 'bw') + { + frames = Paths.getSparrowAtlas('notes/staticNotes1930'); + blackStatic = true; + } + else + frames = Paths.getSparrowAtlas('notes/staticNotes'); + + animation.addByPrefix('greenScroll', 'green static'); + animation.addByPrefix('redScroll', 'red static'); + animation.addByPrefix('blueScroll', 'blue static'); + animation.addByPrefix('purpleScroll', 'purple static'); + + setGraphicSize(Std.int(width * 0.7)); + + updateHitbox(); + antialiasing = true; + + offsetX -= 2; + } + case 6: + if (PlayState.SONG.player2 == 'whittyCrazy') + { + loadGraphic(Paths.image('notes/bombNote'), true, 222, 152); + + animation.add('greenScroll', [0]); + animation.add('redScroll', [0]); + animation.add('blueScroll', [0]); + animation.add('purpleScroll', [0]); + + setGraphicSize(Std.int(width * noteScale)); + updateHitbox(); + antialiasing = true; + + offsetX -= 43; + } + else + { + suf = ""; + if (mickeyNotes) suf = '_mickey'; + + frames = Paths.getSparrowAtlas('notes/HURTNOTE_assets'+suf); + + 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; + } + + case 7: + frames = Paths.getSparrowAtlas('notes/NOTE_rushia'); + + animation.addByPrefix('greenScroll', 'green alone0'); + animation.addByPrefix('redScroll', 'red alone0'); + animation.addByPrefix('blueScroll', 'blue alone0'); + animation.addByPrefix('purpleScroll', 'purple alone0'); + + animation.addByPrefix('purpleholdend', 'purple tail'); + animation.addByPrefix('greenholdend', 'green tail'); + animation.addByPrefix('redholdend', 'red tail'); + animation.addByPrefix('blueholdend', 'blue tail'); + + animation.addByPrefix('purplehold', 'purple hold'); + animation.addByPrefix('greenhold', 'green hold'); + animation.addByPrefix('redhold', 'red hold'); + animation.addByPrefix('bluehold', 'blue hold'); + + setGraphicSize(Std.int(width * 0.7)); + updateHitbox(); + antialiasing = true; + case 8: + frames = Paths.getSparrowAtlas('notes/NOTE_haato'); + + animation.addByPrefix('greenScroll', 'green alone0'); + animation.addByPrefix('redScroll', 'red alone0'); + animation.addByPrefix('blueScroll', 'blue alone0'); + animation.addByPrefix('purpleScroll', 'purple alone0'); + + animation.addByPrefix('purpleholdend', 'purple tail'); + animation.addByPrefix('greenholdend', 'green tail'); + animation.addByPrefix('redholdend', 'red tail'); + animation.addByPrefix('blueholdend', 'blue tail'); + + animation.addByPrefix('purplehold', 'purple hold'); + animation.addByPrefix('greenhold', 'green hold'); + animation.addByPrefix('redhold', 'red hold'); + animation.addByPrefix('bluehold', 'blue hold'); + + setGraphicSize(Std.int(width * 0.7)); + updateHitbox(); + antialiasing = true; + case 9: + loadGraphic(Paths.image('notes/scytheNotes'), true, 150, 150); + + animation.add('greenScroll', [2]); + animation.add('redScroll', [1]); + animation.add('blueScroll', [3]); + animation.add('purpleScroll', [0]); + + setGraphicSize(Std.int(width * noteScale)); + updateHitbox(); + antialiasing = true; + case 10: + if (noteTypeStyle == 'neonNote') + { + loadGraphic(Paths.image('notes/exeNotes-neon'), true, 17, 17); + + animation.add('greenScroll', [2]); + animation.add('redScroll', [3]); + animation.add('blueScroll', [1]); + animation.add('purpleScroll', [0]); + + setGraphicSize(Std.int(width * PlayState.daPixelZoom)); + updateHitbox(); + antialiasing = false; + } + else + { + frames = Paths.getSparrowAtlas('notes/PhantomNote'); + animation.addByPrefix('greenScroll', 'green withered'); + animation.addByPrefix('redScroll', 'red withered'); + animation.addByPrefix('blueScroll', 'blue withered'); + animation.addByPrefix('purpleScroll', 'purple withered'); + + setGraphicSize(Std.int(width * 0.7)); + + updateHitbox(); + antialiasing = true; + } + + }*/ + + if (burning && !pixelBurn && PlayState.curStage != 'auditorHell' && !isAuditorNote || bomb) + setGraphicSize(Std.int(width * 0.86)); + } + + function addAnims(?pixel:Bool = false) + { + if (pixel) + { + animation.add('greenScroll', [6]); + animation.add('redScroll', [7]); + animation.add('blueScroll', [5]); + animation.add('purpleScroll', [4]); + + if (isSustainNote) + { + 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]); + } + + antialiasing = false; + setGraphicSize(Std.int(width * PlayState.daPixelZoom)); + updateHitbox(); + } + else + { + var colorScroll:Array = ['purple', 'blue', 'green', 'red', 'white', 'yellow', 'violet', 'black', 'dark']; + var length:Int = 4; + + if (mania > 0) + length = 9; + + for (i in 0...length) + { + animation.addByPrefix(colorScroll[i]+'Scroll', colorScroll[i]+'0'); + animation.addByPrefix(colorScroll[i]+'hold', colorScroll[i]+' hold piece'); + animation.addByPrefix(colorScroll[i]+'holdend', colorScroll[i]+' hold end'); + + if (colorScroll[i] == 'purple') + animation.addByPrefix(colorScroll[i]+'holdend', 'pruple end hold'); //purple + } + + setGraphicSize(Std.int(width * noteScale)); + updateHitbox(); + antialiasing = true; + } + } +} \ No newline at end of file diff --git a/source/NoteSplash.hx b/source/NoteSplash.hx index 3333f4102..9c4ae59d9 100644 --- a/source/NoteSplash.hx +++ b/source/NoteSplash.hx @@ -1,65 +1,146 @@ -package; - -import flixel.FlxG; -import flixel.FlxSprite; -import flixel.graphics.frames.FlxAtlasFrames; - -class NoteSplash extends FlxSprite -{ - public var colorSwap:ColorSwap = null; - private var idleAnim:String; - private var textureLoaded:String = null; - - public function new(x:Float = 0, y:Float = 0, ?note:Int = 0) { - super(x, y); - - var skin:String = 'noteSplashes'; - if(PlayState.SONG.splashSkin != null && PlayState.SONG.splashSkin.length > 0) skin = PlayState.SONG.splashSkin; - - loadAnims(skin); - - colorSwap = new ColorSwap(); - shader = colorSwap.shader; - - setupNoteSplash(x, y, note); - antialiasing = ClientPrefs.globalAntialiasing; - } - - public function setupNoteSplash(x:Float, y:Float, note:Int = 0, texture:String = null, hueColor:Float = 0, satColor:Float = 0, brtColor:Float = 0) { - setPosition(x - Note.swagWidth * 0.95, y - Note.swagWidth); - alpha = 0.6; - - if(texture == null) { - texture = 'noteSplashes'; - if(PlayState.SONG.splashSkin != null && PlayState.SONG.splashSkin.length > 0) texture = PlayState.SONG.splashSkin; - } - - if(textureLoaded != texture) { - loadAnims(texture); - } - colorSwap.hue = hueColor; - colorSwap.saturation = satColor; - colorSwap.brightness = brtColor; - offset.set(10, 10); - - var animNum:Int = FlxG.random.int(1, 2); - animation.play('note' + note + '-' + animNum, true); - if(animation.curAnim != null)animation.curAnim.frameRate = 24 + FlxG.random.int(-2, 2); - } - - function loadAnims(skin:String) { - frames = Paths.getSparrowAtlas(skin); - for (i in 1...3) { - animation.addByPrefix("note1-" + i, "note splash blue " + i, 24, false); - animation.addByPrefix("note2-" + i, "note splash green " + i, 24, false); - animation.addByPrefix("note0-" + i, "note splash purple " + i, 24, false); - animation.addByPrefix("note3-" + i, "note splash red " + i, 24, false); - } - } - - override function update(elapsed:Float) { - if(animation.curAnim != null)if(animation.curAnim.finished) kill(); - - super.update(elapsed); - } +package; + +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.graphics.frames.FlxAtlasFrames; + +#if desktop +import sys.io.File; +import sys.FileSystem; +#end + +class NoteSplash extends FlxSprite +{ + private var idleAnim:String; + private var textureLoaded:String = null; + + public function new(x:Float = 0, y:Float = 0, ?note:Int = 0) { + super(x, y); + + var skin:String = ''; + + if (Paths.currentModDirectory == 'BETADCIU' || FileSystem.exists(Paths.modsImages("notes/noteSplashes-" + PlayState.instance.bfStrumStyle))) + skin = '-'+ PlayState.instance.bfStrumStyle; + else if (FileSystem.exists(Paths.modsImages("noteSplashes-" + PlayState.instance.bfStrumStyle))) + skin = '-'+ PlayState.instance.bfStrumStyle; + else + skin = PlayState.instance.splashSkin; + + if (skin == 'normal' || skin == 'default') skin = ""; + + loadAnims(skin); + + setupNoteSplash(x, y, note); + + antialiasing = true; + } + + public function setupNoteSplash(x:Float, y:Float, note:Int = 0, texture:String = null, hueColor:Float = 0, satColor:Float = 0, brtColor:Float = 0) { + setPosition(x - Note.swagWidth * 0.95, y - Note.swagWidth); + if (texture == '-holofunk') + { + switch (note) + { + case 0: + this.x += 30; + // offset.set(-20, 0); + case 1: + this.y += 30; + // offset.set(0, -20); + case 2: + this.y += 30; + // offset.set(0, -20); + case 3: + this.x += 30; + // offset.set(-20, 0); + } + alpha = 0.75; + scale.set(1.2, 1.2); + } + else + { + alpha = 0.6; + scale.set(1, 1); + offset.set(0, 0); + } + + + if(texture == null) { + texture = ""; + } + else + { + if (Paths.currentModDirectory == 'BETADCIU' || FileSystem.exists(Paths.modsImages("notes/noteSplashes-" + PlayState.instance.bfStrumStyle))) + texture = '-'+ PlayState.instance.bfStrumStyle; + else if (FileSystem.exists(Paths.modsImages("noteSplashes-" + PlayState.instance.bfStrumStyle))) + texture = '-'+ PlayState.instance.bfStrumStyle; + else + texture = PlayState.instance.splashSkin; + } + + if(textureLoaded != texture) { + loadAnims(texture); + } + + if (texture == '-fever') + { + scale.set(1.08, 1.08); + if(note == 0 || note == 3) + offset.set((0.291 * this.width) - 150, (0.315 * this.height) - 150); + else + offset.set((0.33 * this.width) - 150, (0.315 * this.height) - 150); + } + + + var animNum:Int = FlxG.random.int(1, 2); + animation.play('note' + note + '-' + animNum, true); + animation.curAnim.frameRate = 24 + FlxG.random.int(-2, 2); + } + + function loadAnims(skin:String) { + + var rawPic:Dynamic; + var rawXml:String = ""; + var daPath:String = "noteSplashes" + skin; + var oops:Bool = false; + + if (Paths.currentModDirectory == 'BETADCIU' || FileSystem.exists(Paths.modsImages("notes/noteSplashes" + skin))) + daPath = "notes/noteSplashes" + skin; + + if (FileSystem.exists(Paths.modsImages(daPath))) + rawXml = File.getContent(Paths.modsXml(daPath)); + else if (FileSystem.exists(FileSystem.absolutePath("assets/shared/images/"+daPath+".xml"))) + rawXml = File.getContent(FileSystem.absolutePath("assets/shared/images/"+daPath+".xml")); + else if (FileSystem.exists(Paths.image(daPath))) + rawXml = File.getContent(Paths.xmlNew('images/' + daPath)); + else + { + frames = Paths.getSparrowAtlas("notestuff/noteSplashes"); + oops = true; + } + + if (!Paths.currentTrackedAssets.exists(daPath) && !oops) + Paths.cacheImage(daPath); + + rawPic = Paths.currentTrackedAssets.get(daPath); + + if (!oops) + frames = FlxAtlasFrames.fromSparrow(rawPic,rawXml); + + if (frames == null) + frames = Paths.getSparrowAtlas("notestuff/noteSplashes"); + + for (i in 1...3) { + animation.addByPrefix("note1-" + i, "note impact " + i + " blue", 24, false); + animation.addByPrefix("note2-" + i, "note impact " + i + " green", 24, false); + animation.addByPrefix("note0-" + i, "note impact " + i + " purple", 24, false); + animation.addByPrefix("note3-" + i, "note impact " + i + " red" , 24, false); + } + } + + override function update(elapsed:Float) { + if(animation.curAnim.finished) kill(); + + super.update(elapsed); + } } \ No newline at end of file diff --git a/source/NoteSplashOld.hx b/source/NoteSplashOld.hx new file mode 100644 index 000000000..ca275bc5f --- /dev/null +++ b/source/NoteSplashOld.hx @@ -0,0 +1,97 @@ +package; + +import flixel.FlxSprite; +import flixel.graphics.frames.FlxAtlasFrames; +import Paths; +import Song; +import Conductor; +import Math; +import openfl.geom.Matrix; +import openfl.display.BitmapData; +import openfl.utils.AssetType; +import lime.graphics.Image; +import flixel.graphics.FlxGraphic; +import openfl.utils.AssetManifest; +import openfl.utils.AssetLibrary; +import flixel.system.FlxAssets; +import flixel.FlxBasic; +import flixel.FlxG; +import flixel.FlxGame; +import flixel.FlxObject; +import flixel.math.FlxMath; +import flixel.math.FlxPoint; +import flixel.math.FlxRect; +import lime.utils.Assets; +import openfl.geom.Matrix; +import openfl.display.BitmapData; +import openfl.utils.AssetType; +import lime.graphics.Image; +import flixel.graphics.FlxGraphic; +import flixel.animation.FlxAnimation; + +import openfl.utils.AssetManifest; +import openfl.utils.AssetLibrary; + +#if cpp +import Sys; +import sys.FileSystem; +#end + + +using StringTools; + +class NoteSplash extends FlxSprite +{ + + + override public function new() + { + super(); + switch (PlayState.SONG.noteStyle) + { + case '1930' | 'fever' | 'kapi': + frames = (Paths.getSparrowAtlas("notestuff/noteSplashes-"+PlayState.SONG.noteStyle)); + default: + if (PlayState.changeArrows) { + frames = Paths.getSparrowAtlas("notestuff/noteSplashes"+PlayState.splashSkin); + } + else { + frames = Paths.getSparrowAtlas("notestuff/noteSplashes"); + } + } + + //impact 1 + animation.addByPrefix("note1-0", "note impact 1 blue", 24, false); + animation.addByPrefix("note2-0", "note impact 1 green", 24, false); + animation.addByPrefix("note0-0", "note impact 1 purple", 24, false); + animation.addByPrefix("note3-0", "note impact 1 red", 24, false); + //impact 2 + animation.addByPrefix("note1-1", "note impact 2 blue", 24, false); + animation.addByPrefix("note2-1", "note impact 2 green", 24, false); + animation.addByPrefix("note0-1", "note impact 2 purple", 24, false); + animation.addByPrefix("note3-1", "note impact 2 red", 24, false); + } + + public function setupNoteSplash(xPos:Float, yPos:Float, note:Int) + { + if(note == 0) + { + note = 0; + } + x = xPos; + y = yPos; + alpha = 0.6; + animation.play("note" + note + "-" + FlxG.random.int(0, 1), true); + var a:FlxAnimation = animation.curAnim; + a.frameRate = a.frameRate + FlxG.random.int(-2, 2); + updateHitbox(); + offset.set(0.3 * width, 0.3 * height); + } + + override public function update(elapsed:Float) + { + if(animation.curAnim.finished) kill(); + + super.update(elapsed); + } +} \ No newline at end of file diff --git a/source/Options.hx b/source/Options.hx new file mode 100644 index 000000000..be5fc5df7 --- /dev/null +++ b/source/Options.hx @@ -0,0 +1,656 @@ +package; + +import lime.app.Application; +import lime.system.DisplayMode; +import flixel.util.FlxColor; +import Controls.KeyboardScheme; +import flixel.FlxG; +import openfl.display.FPS; +import openfl.Lib; + +class OptionCategory +{ + private var _options:Array