diff --git a/Project.xml b/Project.xml
index 3504b38806..33ea82aee4 100644
--- a/Project.xml
+++ b/Project.xml
@@ -128,7 +128,7 @@
-
+
@@ -184,6 +184,8 @@
+
+
diff --git a/appveyor-linux.yml b/appveyor-linux.yml
index e8f76aba93..a6c03fcb38 100644
--- a/appveyor-linux.yml
+++ b/appveyor-linux.yml
@@ -29,6 +29,7 @@ install:
- haxelib git polymod https://github.com/larsiusprime/polymod.git
- haxelib git discord_rpc https://github.com/Aidan63/linc_discord-rpc
- haxelib git extension-webm https://github.com/KadeDev/extension-webm
+ - haxelib git hxvm-luajit https://github.com/KadeDev/hxvm-luajit
- haxelib run lime rebuild extension-webm linux
- haxelib git linc_luajit https://github.com/AndreiRudenko/linc_luajit.git
- haxelib install actuate
diff --git a/appveyor-macos.yml b/appveyor-macos.yml
index 47c0bcd1b8..57c76afd9d 100644
--- a/appveyor-macos.yml
+++ b/appveyor-macos.yml
@@ -29,6 +29,7 @@ install:
- haxelib git polymod https://github.com/larsiusprime/polymod.git
- haxelib git discord_rpc https://github.com/Aidan63/linc_discord-rpc
- haxelib git extension-webm https://github.com/KadeDev/extension-webm
+ - haxelib git hxvm-luajit https://github.com/KadeDev/hxvm-luajit
- haxelib run lime rebuild extension-webm macos
- haxelib install linc_luajit
- haxelib install actuate
diff --git a/appveyor-windows.yml b/appveyor-windows.yml
index 58d5d98f9e..16b6d42721 100644
--- a/appveyor-windows.yml
+++ b/appveyor-windows.yml
@@ -34,6 +34,7 @@ install:
- haxelib git polymod https://github.com/larsiusprime/polymod.git
- haxelib git discord_rpc https://github.com/Aidan63/linc_discord-rpc
- haxelib git extension-webm https://github.com/KadeDev/extension-webm
+ - haxelib git hxvm-luajit https://github.com/KadeDev/hxvm-luajit
- haxelib run lime rebuild extension-webm windows
- haxelib install linc_luajit
- haxelib install actuate
diff --git a/assets/preload/data/tutorial/modchart.lua b/assets/preload/data/tutorial/modchart.lua
index 4db18f0eda..71a33b8a3c 100644
--- a/assets/preload/data/tutorial/modchart.lua
+++ b/assets/preload/data/tutorial/modchart.lua
@@ -1,13 +1,21 @@
function start(song) -- do nothing
-
+ spinLength = 0
end
function update(elapsed)
+
if difficulty == 2 and curStep > 400 then
+ if spinLength < 32 then
+ spinLength = spinLength + 0.2
+ end
+
+
local currentBeat = (songPos / 1000)*(bpm/60)
- for i=0,7 do
- setActorX(_G['defaultStrum'..i..'X'] + 32 * math.sin((currentBeat + i*0.25) * math.pi), i)
- setActorY(_G['defaultStrum'..i..'Y'] + 32 * math.cos((currentBeat + i*0.25) * math.pi), i)
+ for i=0,7,1 do
+ local receptor = _G['receptor_'..i]
+ receptor.angle = (spinLength / 7) * -math.sin((currentBeat + i*0.25) * math.pi)
+ receptor.x = receptor.defaultX + spinLength * math.sin((currentBeat + i*0.25) * math.pi)
+ receptor.y = receptor.defaultY + spinLength * math.cos((currentBeat + i*0.25) * math.pi)
end
end
end
@@ -21,9 +29,9 @@ function stepHit(step) -- do nothing
end
function playerTwoTurn()
- tweenCameraZoom(1.3,(crochet * 4) / 1000)
+ camGame.tweenZoom(camGame,1.3,(crochet * 4) / 1000)
end
function playerOneTurn()
- tweenCameraZoom(1,(crochet * 4) / 1000)
+ camGame.tweenZoom(camGame,1,(crochet * 4) / 1000)
end
\ No newline at end of file
diff --git a/docs/building.md b/docs/building.md
index 806c8f3154..62f29cb69b 100644
--- a/docs/building.md
+++ b/docs/building.md
@@ -36,13 +36,9 @@
If you are planning to build for Windows, you also need to install **Visual Studio 2019**. While installing it, *don't click on any of the options to install workloads*. Instead, go to the **individual components** tab and choose the following:
- MSVC v142 - VS 2019 C++ x64/x86 build tools
-- MSVC v141 - VS 2017 C++ x64/x86 build tools
- Windows SDK (10.0.17763.0)
-- C++ Profiling tools
-- C++ CMake tools for windows
-- C++ ATL for v142 build tools (x86 & x64)
-This will install about 7 GB of crap, but is necessary to build for Windows.
+This will install about 4 GB of crap, but is necessary to build for Windows.
### macOS-only dependencies (these are required for building on macOS at all, including html5.)
If you are running macOS, you'll need to install Xcode. You can download it from the macOS App Store or from the [Xcode website](https://developer.apple.com/xcode/).
diff --git a/docs/changelogs/changelog-1.7.md b/docs/changelogs/changelog-1.7.md
new file mode 100644
index 0000000000..43cd0e5167
--- /dev/null
+++ b/docs/changelogs/changelog-1.7.md
@@ -0,0 +1,29 @@
+# Latest (master) changelog/Changelog
+
+Changes marked with 💖 will be listed in the short version of the changelog in `version.downloadMe`.
+
+### Additions
+- 💖 A speed modifier (To use, press shift-left/right in freeplay or the charter. Does not work on modcharts.)
+
+### Changes
+- Relocated all of the stage code into it's own file
+- 💖 Completely redid all of modcharting (docs can be found [here](https://github.com/KadeDev/Kade-Engine/wiki))
+- Removed replay functionality due to it being a peice of shit and never working and causing issues and problems all the time.
+- 💖 Optimized a lot of code to run better
+- 💖 Allowed numpad to be binded as a key
+- Optimized rating code to be faster
+- Removed debug code from release builds for faster execution
+- Binding a key to an already binded key no longer sets the other as null
+- When beat quant colors are enabled, your key presses are highlighted in the color you hit instead of the original color.
+- Removed beat base idle animations for characters
+- Changed beat quant colors to. 4th = red, 8th = blue, green = 12th, purple = 16th+
+- 💖 Changed the editor to work entirely on beats
+- Changed the BPM change code to work on beats instead of timestamps
+- Removed a lot of unnecessary code.
+- Changed **scroll speed** change events to be **based on multipliers instead of constant values** (aka 2 scroll speed would be scrollSpeed * 2 instead of setting it to 2)
+
+### Bugfixes
+- 💖 Fix multiplie crashes with story mode and other weeks in story mode
+- 💖 Fix desyncs with bpm changes and section notes in the charter
+- Fix snap working in the charter (it's way more accurate now)
+- Fixed crashing on a song that has a modchart at the end.
diff --git a/docs/changelogs/index.md b/docs/changelogs/index.md
index b85d9e07ca..923beb7a79 100644
--- a/docs/changelogs/index.md
+++ b/docs/changelogs/index.md
@@ -1,6 +1,7 @@
# Changelogs
- [Latest](latest) (Contains changes that are not in a release yet)
+- [1.7](changelog-1.7)
- [1.6.2](changelog-1.6.2)
- [1.6.1](changelog-1.6.1)
- [1.6](changelog-1.6)
diff --git a/source/BackgroundDancer.hx b/source/BackgroundDancer.hx
index 99a83dff18..38978c91d1 100644
--- a/source/BackgroundDancer.hx
+++ b/source/BackgroundDancer.hx
@@ -15,6 +15,8 @@ class BackgroundDancer extends FlxSprite
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 = FlxG.save.data.antialiasing;
+
+
}
var danceDir:Bool = false;
diff --git a/source/Caching.hx b/source/Caching.hx
index 9160f8e1d1..2d9f28ff6a 100644
--- a/source/Caching.hx
+++ b/source/Caching.hx
@@ -152,6 +152,7 @@ class Caching extends MusicBeatState
function cache()
{
+ #if !linux
trace("LOADING: " + toBeDone + " OBJECTS.");
for (i in images)
@@ -181,6 +182,7 @@ class Caching extends MusicBeatState
trace(Assets.cache.hasBitmapData('GF_assets'));
+ #end
FlxG.switchState(new TitleState());
}
diff --git a/source/Character.hx b/source/Character.hx
index 542b868813..7e1328065d 100644
--- a/source/Character.hx
+++ b/source/Character.hx
@@ -382,7 +382,7 @@ class Character extends FlxSprite
dance();
- if (isPlayer)
+ if (isPlayer && frames != null)
{
flipX = !flipX;
diff --git a/source/ChartingState.hx b/source/ChartingState.hx
index 39c5c01086..ebad6da9e5 100644
--- a/source/ChartingState.hx
+++ b/source/ChartingState.hx
@@ -44,6 +44,9 @@ import openfl.events.IOErrorEvent;
import openfl.media.Sound;
import openfl.net.FileReference;
import openfl.utils.ByteArray;
+#if windows
+import Discord.DiscordClient;
+#end
using StringTools;
@@ -65,6 +68,8 @@ class ChartingState extends MusicBeatState
public static var lengthInSteps:Float = 0;
public static var lengthInBeats:Float = 0;
+ public var speed = 1.0;
+
public var beatsShown:Float = 1; // for the zoom factor
public var zoomFactor:Float = 0.4;
@@ -160,8 +165,26 @@ class ChartingState extends MusicBeatState
TimingStruct.clearTimings();
+
+
+
if (PlayState.SONG != null)
- _song = PlayState.SONG;
+ {
+ if (PlayState.isSM)
+ _song = Song.conversionChecks(Song.loadFromJsonRAW(File.getContent(PlayState.pathToSm + "/converted.json")));
+ else
+ {
+ var songFormat = StringTools.replace(PlayState.SONG.song, " ", "-");
+ switch (songFormat) {
+ case 'Dad-Battle': songFormat = 'Dadbattle';
+ case 'Philly-Nice': songFormat = 'Philly';
+ }
+
+ var poop:String = Highscore.formatSong(songFormat, PlayState.storyDifficulty);
+
+ _song = Song.conversionChecks(Song.loadFromJson(poop, PlayState.SONG.song));
+ }
+ }
else
{
_song = {
@@ -265,8 +288,12 @@ class ChartingState extends MusicBeatState
lastSeg = seg;
}
+ trace("STRUCTS: " + TimingStruct.AllTimings.length);
+
recalculateAllSectionTimes();
+
+ poggers();
trace("Song length in MS: " + FlxG.sound.music.length);
@@ -429,32 +456,6 @@ class ChartingState extends MusicBeatState
trace("create");
- TimingStruct.clearTimings();
-
- var currentIndex = 0;
- for (i in _song.eventObjects)
- {
- if (i.type == "BPM Change")
- {
- var beat:Float = i.position;
-
- var endBeat:Float = Math.POSITIVE_INFINITY;
-
- TimingStruct.addTiming(beat,i.value,endBeat, 0); // offset in this case = start time since we don't have a offset
-
- if (currentIndex != 0)
- {
- var data = TimingStruct.AllTimings[currentIndex - 1];
- data.endBeat = beat;
- data.length = (data.endBeat - data.startBeat) / (data.bpm / 60);
- var step = ((60 / data.bpm) * 1000) / 4;
- TimingStruct.AllTimings[currentIndex].startStep = Math.floor(((data.endBeat / (data.bpm / 60)) * 1000) / step);
- TimingStruct.AllTimings[currentIndex].startTime = data.startTime + data.length;
- }
-
- currentIndex++;
- }
- }
super.create();
}
@@ -558,8 +559,8 @@ class ChartingState extends MusicBeatState
var check_snap:FlxUICheckBox;
var listOfEvents:FlxUIDropDownMenu;
var currentSelectedEventName:String = "";
- var savedType:String = "";
- var savedValue:String = "";
+ var savedType:String = "BPM Change";
+ var savedValue:String = "100";
var currentEventPosition:Float = 0;
function containsName(name:String, events:Array):Song.Event
@@ -652,7 +653,10 @@ class ChartingState extends MusicBeatState
}
if (pog.type == "BPM Change")
+ {
recalculateAllSectionTimes();
+ poggers();
+ }
regenerateLines();
@@ -743,6 +747,7 @@ class ChartingState extends MusicBeatState
trace(i.bpm + " - START: " + i.startBeat + " - END: " + i.endBeat + " - START-TIME: " + i.startTime);
recalculateAllSectionTimes();
+ poggers();
regenerateLines();
@@ -825,6 +830,7 @@ class ChartingState extends MusicBeatState
}
recalculateAllSectionTimes();
+ poggers();
regenerateLines();
@@ -1182,8 +1188,8 @@ class ChartingState extends MusicBeatState
var check_mustHitSection:FlxUICheckBox;
var check_changeBPM:FlxUICheckBox;
var stepperSectionBPM:FlxUINumericStepper;
- var check_p1AltAnim:FlxUICheckBox;
- var check_p2AltAnim:FlxUICheckBox;
+ var check_CPUAltAnim:FlxUICheckBox;
+ var check_playerAltAnim:FlxUICheckBox;
function addSectionUI():Void
{
@@ -1236,7 +1242,7 @@ class ChartingState extends MusicBeatState
}
}
});
- check_mustHitSection = new FlxUICheckBox(10, 30, null, null, "Camera Points to P1?", 100,null,function() {
+ check_mustHitSection = new FlxUICheckBox(10, 30, null, null, "Camera Points to Player?", 100,null,function() {
var sect = lastUpdatedSection;
trace(sect);
@@ -1267,11 +1273,11 @@ class ChartingState extends MusicBeatState
check_mustHitSection.checked = true;
// _song.needsVoices = check_mustHit.checked;
- check_p1AltAnim = new FlxUICheckBox(10, 340, null, null, "P1 Alternate Animation", 100);
- check_p1AltAnim.name = 'check_p1AltAnim';
+ check_CPUAltAnim = new FlxUICheckBox(10, 340, null, null, "CPU Alternate Animation", 100);
+ check_CPUAltAnim.name = 'check_CPUAltAnim';
- check_p2AltAnim = new FlxUICheckBox(200, 340, null, null, "P2 Alternate Animation", 100);
- check_p2AltAnim.name = 'check_p2AltAnim';
+ check_playerAltAnim = new FlxUICheckBox(180, 340, null, null, "Player Alternate Animation", 100);
+ check_playerAltAnim.name = 'check_playerAltAnim';
var refresh = new FlxButton(10, 60, 'Refresh Section', function() {
var section = getSectionByTime(Conductor.songPosition);
@@ -1280,8 +1286,8 @@ class ChartingState extends MusicBeatState
return;
check_mustHitSection.checked = section.mustHitSection;
- check_p1AltAnim.checked = section.p1AltAnim;
- check_p2AltAnim.checked = section.p2AltAnim;
+ check_CPUAltAnim.checked = section.CPUAltAnim;
+ check_playerAltAnim.checked = section.playerAltAnim;
});
var startSection:FlxButton = new FlxButton(10, 85, "Play Here", function() {
@@ -1298,8 +1304,8 @@ class ChartingState extends MusicBeatState
//tab_group_section.add(stepperCopy);
//tab_group_section.add(stepperCopyLabel);
tab_group_section.add(check_mustHitSection);
- tab_group_section.add(check_p1AltAnim);
- tab_group_section.add(check_p2AltAnim);
+ tab_group_section.add(check_CPUAltAnim);
+ tab_group_section.add(check_playerAltAnim);
//tab_group_section.add(copyButton);
tab_group_section.add(clearSectionButton);
tab_group_section.add(swapSection);
@@ -1403,12 +1409,12 @@ class ChartingState extends MusicBeatState
{
trace("new strum " + strum + " - at section " + section);
// alright we're in this section lets paste the note here.
- var newData = [strum,i[1],i[2]];
+ var newData = [strum,i[1],i[2],i[3],i[4]];
ii.sectionNotes.push(newData);
var thing = ii.sectionNotes[ii.sectionNotes.length - 1];
- var note:Note = new Note(strum, Math.floor(i[1] % 4),null,false,true);
+ var note:Note = new Note(strum, Math.floor(i[1] % 4),null,false,true,i[3], i[4]);
note.rawNoteData = i[1];
note.sustainLength = i[2];
note.setGraphicSize(Math.floor(GRID_SIZE), Math.floor(GRID_SIZE));
@@ -1466,6 +1472,21 @@ class ChartingState extends MusicBeatState
FlxG.sound.playMusic(Paths.inst(daSong), 0.6);
#end
+ if (PlayState.isSM)
+ _song = Song.conversionChecks(Song.loadFromJsonRAW(File.getContent(PlayState.pathToSm + "/converted.json")));
+ else
+ {
+ var songFormat = StringTools.replace(PlayState.SONG.song, " ", "-");
+ switch (songFormat) {
+ case 'Dad-Battle': songFormat = 'Dadbattle';
+ case 'Philly-Nice': songFormat = 'Philly';
+ }
+
+ var poop:String = Highscore.formatSong(songFormat, PlayState.storyDifficulty);
+
+ _song = Song.conversionChecks(Song.loadFromJson(poop, PlayState.SONG.song));
+ }
+
// WONT WORK FOR TUTORIAL OR TEST SONG!!! REDO LATER
#if sys
if (PlayState.isSM)
@@ -1516,10 +1537,10 @@ class ChartingState extends MusicBeatState
var label = check.getLabel().text;
switch (label)
{
- case "P1 Alternate Animation":
- getSectionByTime(Conductor.songPosition).p1AltAnim = check.checked;
- case "P2 Alternate Animation":
- getSectionByTime(Conductor.songPosition).p2AltAnim = check.checked;
+ case "CPU Alternate Animation":
+ getSectionByTime(Conductor.songPosition).CPUAltAnim = check.checked;
+ case "Player Alternate Animation":
+ getSectionByTime(Conductor.songPosition).playerAltAnim = check.checked;
}
}
else if (id == FlxUINumericStepper.CHANGE_EVENT && (sender is FlxUINumericStepper))
@@ -1549,7 +1570,54 @@ class ChartingState extends MusicBeatState
if (_song.eventObjects[0].type != "BPM Change")
Application.current.window.alert("i'm crying, first event isn't a bpm change. fuck you");
else
+ {
_song.eventObjects[0].value = nums.value;
+ regenerateLines();
+ }
+
+ TimingStruct.clearTimings();
+
+ var currentIndex = 0;
+ for (i in _song.eventObjects)
+ {
+ var name = Reflect.field(i,"name");
+ var type = Reflect.field(i,"type");
+ var pos = Reflect.field(i,"position");
+ var value = Reflect.field(i,"value");
+
+ trace(i.type);
+ if (type == "BPM Change")
+ {
+ var beat:Float = pos;
+
+ var endBeat:Float = Math.POSITIVE_INFINITY;
+
+ TimingStruct.addTiming(beat,value,endBeat, 0); // offset in this case = start time since we don't have a offset
+
+ if (currentIndex != 0)
+ {
+ var data = TimingStruct.AllTimings[currentIndex - 1];
+ data.endBeat = beat;
+ data.length = (data.endBeat - data.startBeat) / (data.bpm / 60);
+ var step = ((60 / data.bpm) * 1000) / 4;
+ TimingStruct.AllTimings[currentIndex].startStep = Math.floor(((data.endBeat / (data.bpm / 60)) * 1000) / step);
+ TimingStruct.AllTimings[currentIndex].startTime = data.startTime + data.length;
+ }
+
+ currentIndex++;
+ }
+ }
+ trace("BPM CHANGES:");
+
+ for (i in TimingStruct.AllTimings)
+ trace(i.bpm + " - START: " + i.startBeat + " - END: " + i.endBeat + " - START-TIME: " + i.startTime);
+
+ recalculateAllSectionTimes();
+
+ regenerateLines();
+
+ poggers();
+
case 'note_susLength':
if (curSelectedNote == null)
return;
@@ -1596,7 +1664,73 @@ class ChartingState extends MusicBeatState
return getSectionByTime(Conductor.songPosition).lengthInSteps;
}*/
-
+ function poggers()
+ {
+ var notes = [];
+
+ for(section in _song.notes)
+ {
+
+ var removed = [];
+
+ for(note in section.sectionNotes)
+ {
+ // commit suicide
+ var old = note[0];
+ note[0] = TimingStruct.getTimeFromBeat(note[4]);
+ note[2] = TimingStruct.getTimeFromBeat(TimingStruct.getBeatFromTime(note[2]));
+ if (note[0] < section.startTime)
+ {
+ notes.push(note);
+ removed.push(note);
+ }
+ if (note[0] > section.endTime)
+ {
+ notes.push(note);
+ removed.push(note);
+ }
+ }
+
+ for(i in removed)
+ {
+ section.sectionNotes.remove(i);
+ }
+ }
+
+ for(section in _song.notes)
+ {
+
+ var saveRemove = [];
+
+ for(i in notes)
+ {
+ if (i[0] >= section.startTime && i[0] < section.endTime)
+ {
+ saveRemove.push(i);
+ section.sectionNotes.push(i);
+ }
+ }
+
+ for(i in saveRemove)
+ notes.remove(i);
+ }
+
+ for(i in curRenderedNotes)
+ {
+ i.strumTime = TimingStruct.getTimeFromBeat(i.beat);
+ i.y = Math.floor(getYfromStrum(i.strumTime) * zoomFactor);
+ i.sustainLength = TimingStruct.getTimeFromBeat(TimingStruct.getBeatFromTime(i.sustainLength));
+ if (i.noteCharterObject != null)
+ {
+ i.noteCharterObject.y = i.y + 40;
+ i.noteCharterObject.makeGraphic(8,Math.floor((getYfromStrum(i.strumTime + i.sustainLength) * zoomFactor) - i.y),FlxColor.WHITE);
+ }
+
+ }
+
+ trace("FUCK YOU BITCH FUCKER CUCK SUCK BITCH " + _song.notes.length);
+ }
+
function stepStartTime(step):Float
{
@@ -1656,6 +1790,10 @@ class ChartingState extends MusicBeatState
override function update(elapsed:Float)
{
updateHeads();
+
+ #if windows
+ DiscordClient.changePresence("Chart Editor", null, null, true);
+ #end
for(i in sectionRenderes)
{
@@ -1674,6 +1812,26 @@ class ChartingState extends MusicBeatState
shownNotes = [];
+ if (FlxG.sound.music != null)
+ {
+ if (FlxG.sound.music.playing)
+ {
+ @:privateAccess
+ {
+ lime.media.openal.AL.sourcef(FlxG.sound.music._channel.__source.__backend.handle, lime.media.openal.AL.PITCH, speed);
+ try
+ {
+ lime.media.openal.AL.sourcef(vocals._channel.__source.__backend.handle, lime.media.openal.AL.PITCH, speed);
+ }
+ catch(e)
+ {
+ // trace("failed to pitch vocals (probably cuz they don't exist)");
+ }
+
+ }
+ }
+ }
+
for(note in curRenderedNotes)
{
var diff = note.strumTime - Conductor.songPosition;
@@ -1785,7 +1943,7 @@ class ChartingState extends MusicBeatState
if (data != null)
{
- FlxG.sound.music.time = (data.startTime + ((beats - data.startBeat) / (bpm/60)) ) * 1000;
+ FlxG.sound.music.time = (data.startTime + ((beats - data.startBeat) / (bpm/60))) * 1000;
}
}
else
@@ -1799,10 +1957,25 @@ class ChartingState extends MusicBeatState
}
}
- if (FlxG.keys.justPressed.RIGHT && !FlxG.keys.pressed.CONTROL)
- goToSection(curSection + 1);
- else if (FlxG.keys.justPressed.LEFT && !FlxG.keys.pressed.CONTROL)
- goToSection(curSection - 1);
+ if (FlxG.keys.pressed.SHIFT)
+ {
+ if (FlxG.keys.justPressed.RIGHT)
+ speed += 0.1;
+ else if (FlxG.keys.justPressed.LEFT)
+ speed -= 0.1;
+
+ if (speed > 3)
+ speed = 3;
+ if (speed <= 0.01)
+ speed = 0.1;
+ }
+ else
+ {
+ if (FlxG.keys.justPressed.RIGHT && !FlxG.keys.pressed.CONTROL)
+ goToSection(curSection + 1);
+ else if (FlxG.keys.justPressed.LEFT && !FlxG.keys.pressed.CONTROL)
+ goToSection(curSection - 1);
+ }
if (FlxG.mouse.pressed && FlxG.keys.pressed.CONTROL)
{
@@ -1897,7 +2070,7 @@ class ChartingState extends MusicBeatState
{
copiedNotes = [];
for(i in selectedBoxes.members)
- copiedNotes.push([i.connectedNote.strumTime,i.connectedNote.rawNoteData,i.connectedNote.sustainLength,i.connectedNote.isAlt]);
+ copiedNotes.push([i.connectedNote.strumTime,i.connectedNote.rawNoteData,i.connectedNote.sustainLength,i.connectedNote.isAlt,i.connectedNote.beat]);
var firstNote = copiedNotes[0][0];
@@ -2086,8 +2259,8 @@ class ChartingState extends MusicBeatState
{
lastUpdatedSection = weird;
check_mustHitSection.checked = weird.mustHitSection;
- check_p1AltAnim.checked = weird.p1AltAnim;
- check_p2AltAnim.checked = weird.p2AltAnim;
+ check_CPUAltAnim.checked = weird.CPUAltAnim;
+ check_playerAltAnim.checked = weird.playerAltAnim;
}
}
@@ -2108,7 +2281,9 @@ class ChartingState extends MusicBeatState
+ "\nCurStep: "
+ curStep
+ "\nZoom: "
- + HelperFunctions.truncateFloat(zoomFactor,2);
+ + HelperFunctions.truncateFloat(zoomFactor,2)
+ + "\nSpeed: "
+ + HelperFunctions.truncateFloat(speed,1);
var left = FlxG.keys.justPressed.ONE;
@@ -2126,7 +2301,7 @@ class ChartingState extends MusicBeatState
{
curRenderedNotes.forEach(function(note:Note)
{
- if (strumLine.overlaps(note) && pressArray[Math.floor(Math.abs(note.noteData))])
+ if (strumLine.overlaps(note) && pressArray[Math.floor(Math.abs(note.rawNoteData))])
{
deleteNote(note);
delete = true;
@@ -2271,7 +2446,19 @@ class ChartingState extends MusicBeatState
dummyArrow.x = Math.floor(FlxG.mouse.x / GRID_SIZE) * GRID_SIZE;
- dummyArrow.y = (Math.floor(FlxG.mouse.y / (GRID_SIZE / deezNuts.get(snap))) * (GRID_SIZE / deezNuts.get(snap)));
+ if (doSnapShit)
+ {
+ var time = getStrumTime(FlxG.mouse.y / zoomFactor);
+
+ var beat = TimingStruct.getBeatFromTime(time);
+ var snapped = Math.round(beat * deezNuts.get(snap)) / deezNuts.get(snap);
+
+ dummyArrow.y = getYfromStrum(TimingStruct.getTimeFromBeat(snapped)) * zoomFactor;
+ }
+ else
+ {
+ dummyArrow.y = FlxG.mouse.y;
+ }
}
else
{
@@ -2303,7 +2490,11 @@ class ChartingState extends MusicBeatState
if (FlxG.keys.justPressed.C && !FlxG.keys.pressed.CONTROL)
{
var sect = _song.notes[curSection];
+
+ trace(sect);
+
sect.mustHitSection = !sect.mustHitSection;
+ check_mustHitSection.checked = sect.mustHitSection;
var i = sectionRenderes.members[curSection];
var cachedY = i.icon.y;
remove(i.icon);
@@ -2561,14 +2752,14 @@ class ChartingState extends MusicBeatState
if (sec == null)
{
check_mustHitSection.checked = true;
- check_p1AltAnim.checked = false;
- check_p2AltAnim.checked = false;
+ check_CPUAltAnim.checked = false;
+ check_playerAltAnim.checked = false;
}
else
{
check_mustHitSection.checked = sec.mustHitSection;
- check_p1AltAnim.checked = sec.p1AltAnim;
- check_p2AltAnim.checked = sec.p2AltAnim;
+ check_CPUAltAnim.checked = sec.CPUAltAnim;
+ check_playerAltAnim.checked = sec.playerAltAnim;
}
}
@@ -2638,7 +2829,7 @@ class ChartingState extends MusicBeatState
var daStrumTime = i[0];
var daSus = i[2];
- var note:Note = new Note(daStrumTime, daNoteInfo % 4,null,false,true,i[3]);
+ var note:Note = new Note(daStrumTime, daNoteInfo % 4,null,false,true,i[3], i[4]);
note.rawNoteData = daNoteInfo;
note.sustainLength = daSus;
note.setGraphicSize(Math.floor(GRID_SIZE), Math.floor(GRID_SIZE));
@@ -2697,8 +2888,8 @@ class ChartingState extends MusicBeatState
sectionNotes: [],
typeOfSection: 0,
altAnim: false,
- p1AltAnim: false,
- p2AltAnim: false
+ CPUAltAnim: false,
+ playerAltAnim: false
};
_song.notes.push(sec);
@@ -2809,7 +3000,7 @@ class ChartingState extends MusicBeatState
updateGrid();
}
- private function newSection(lengthInSteps:Int = 16,mustHitSection:Bool = false,p1AltAnim:Bool = true, p2AltAnim:Bool = true):SwagSection
+ private function newSection(lengthInSteps:Int = 16,mustHitSection:Bool = false,CPUAltAnim:Bool = true, playerAltAnim:Bool = true):SwagSection
{
var daPos:Float = 0;
@@ -2838,8 +3029,8 @@ class ChartingState extends MusicBeatState
sectionNotes: [],
typeOfSection: 0,
altAnim: false,
- p1AltAnim: p1AltAnim,
- p2AltAnim: p2AltAnim
+ CPUAltAnim: CPUAltAnim,
+ playerAltAnim: playerAltAnim
};
@@ -2849,28 +3040,10 @@ class ChartingState extends MusicBeatState
function recalculateAllSectionTimes()
{
- /*if (TimingStruct.AllTimings.length > 0)
- {
- trace("Song length in MS: " + FlxG.sound.music.length);
-
- for(i in 0...9000000) // REALLY HIGH BEATS just cuz like ig this is the upper limit, I mean ur chart is probably going to run like ass anyways
- {
- var seg = TimingStruct.getTimingAtBeat(i);
-
- var time = (i / (seg.bpm / 60)) * 1000;
-
- if (time > FlxG.sound.music.length)
- break;
-
- lengthInBeats = i;
- }
-
- lengthInSteps = lengthInBeats * 4;
+ trace("RECALCULATING SECTION TIMES");
- trace('LENGTH IN STEPS ' + lengthInSteps + ' | LENGTH IN BEATS ' + lengthInBeats);
- }*/
+ var savedNotes:Array = [];
- trace("RECALCULATING SECTION TIMES");
for (i in 0..._song.notes.length) // loops through sections
{
var section = _song.notes[i];
@@ -2889,12 +3062,9 @@ class ChartingState extends MusicBeatState
if (i != 0)
_song.notes[i - 1].endTime = section.startTime;
section.endTime = Math.POSITIVE_INFINITY;
-
}
- once = true;
}
- var once = false;
function shiftNotes(measure:Int=0,step:Int=0,ms:Int = 0):Void
@@ -2913,7 +3083,7 @@ class ChartingState extends MusicBeatState
}
for (daSection1 in 0..._song.notes.length)
{
- newSong.push(newSection(16,_song.notes[daSection1].mustHitSection,_song.notes[daSection1].p1AltAnim,_song.notes[daSection1].p2AltAnim));
+ newSong.push(newSection(16,_song.notes[daSection1].mustHitSection,_song.notes[daSection1].CPUAltAnim,_song.notes[daSection1].playerAltAnim));
}
for (daSection in 0...(_song.notes.length))
@@ -2921,8 +3091,8 @@ class ChartingState extends MusicBeatState
var aimtosetsection = daSection+Std.int((totaladdsection));
if(aimtosetsection<0) aimtosetsection = 0;
newSong[aimtosetsection].mustHitSection = _song.notes[daSection].mustHitSection;
- newSong[aimtosetsection].p1AltAnim = _song.notes[daSection].p1AltAnim;
- newSong[aimtosetsection].p2AltAnim = _song.notes[daSection].p2AltAnim;
+ newSong[aimtosetsection].CPUAltAnim = _song.notes[daSection].CPUAltAnim;
+ newSong[aimtosetsection].playerAltAnim = _song.notes[daSection].playerAltAnim;
//trace("section "+daSection);
for(daNote in 0...(_song.notes[daSection].sectionNotes.length))
{
@@ -2999,9 +3169,9 @@ class ChartingState extends MusicBeatState
var noteSus = 0;
if (n != null)
- section.sectionNotes.push([n.strumTime, n.noteData, n.sustainLength, false]);
+ section.sectionNotes.push([n.strumTime, n.noteData, n.sustainLength, false, TimingStruct.getBeatFromTime(n.strumTime)]);
else
- section.sectionNotes.push([noteStrum, noteData, noteSus, false]);
+ section.sectionNotes.push([noteStrum, noteData, noteSus, false, TimingStruct.getBeatFromTime(noteStrum)]);
var thingy = section.sectionNotes[section.sectionNotes.length - 1];
@@ -3011,7 +3181,7 @@ class ChartingState extends MusicBeatState
if (n == null)
{
- var note:Note = new Note(noteStrum, noteData % 4,null,false,true);
+ var note:Note = new Note(noteStrum, noteData % 4,null,false,true,TimingStruct.getBeatFromTime(noteStrum));
note.rawNoteData = noteData;
note.sustainLength = noteSus;
note.setGraphicSize(Math.floor(GRID_SIZE), Math.floor(GRID_SIZE));
@@ -3041,7 +3211,8 @@ class ChartingState extends MusicBeatState
}
else
{
- var note:Note = new Note(n.strumTime, n.noteData % 4,null,false,true, n.isAlt);
+ var note:Note = new Note(n.strumTime, n.noteData % 4,null,false,true, n.isAlt,TimingStruct.getBeatFromTime(n.strumTime));
+ note.beat = TimingStruct.getBeatFromTime(n.strumTime);
note.rawNoteData = n.noteData;
note.sustainLength = noteSus;
note.setGraphicSize(Math.floor(GRID_SIZE), Math.floor(GRID_SIZE));
diff --git a/source/ConvertScore.hx b/source/ConvertScore.hx
index 9eba969fef..cd88854a0d 100644
--- a/source/ConvertScore.hx
+++ b/source/ConvertScore.hx
@@ -2,19 +2,7 @@ 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;
}
diff --git a/source/DialogueBox.hx b/source/DialogueBox.hx
index 07363c6f85..64107f5235 100644
--- a/source/DialogueBox.hx
+++ b/source/DialogueBox.hx
@@ -1,5 +1,6 @@
package;
+import flixel.system.FlxSound;
import flixel.FlxG;
import flixel.FlxSprite;
import flixel.addons.text.FlxTypeText;
@@ -34,6 +35,8 @@ class DialogueBox extends FlxSpriteGroup
var handSelect:FlxSprite;
var bgFade:FlxSprite;
+ var sound:FlxSound;
+
public function new(talkingRight:Bool = true, ?dialogueList:Array)
{
super();
@@ -41,11 +44,15 @@ class DialogueBox extends FlxSpriteGroup
switch (PlayState.SONG.song.toLowerCase())
{
case 'senpai':
- FlxG.sound.playMusic(Paths.music('Lunchbox'), 0);
- FlxG.sound.music.fadeIn(1, 0, 0.8);
+ sound = new FlxSound().loadEmbedded(Paths.music('Lunchbox'),true);
+ sound.volume = 0;
+ FlxG.sound.list.add(sound);
+ sound.fadeIn(1, 0, 0.8);
case 'thorns':
- FlxG.sound.playMusic(Paths.music('LunchboxScary'), 0);
- FlxG.sound.music.fadeIn(1, 0, 0.8);
+ sound = new FlxSound().loadEmbedded(Paths.music('LunchboxScary'),true);
+ sound.volume = 0;
+ FlxG.sound.list.add(sound);
+ sound.fadeIn(1, 0, 0.8);
}
bgFade = new FlxSprite(-200, -200).makeGraphic(Std.int(FlxG.width * 1.3), Std.int(FlxG.height * 1.3), 0xFFB3DFd8);
@@ -190,8 +197,7 @@ class DialogueBox extends FlxSpriteGroup
isEnding = true;
if (PlayState.SONG.song.toLowerCase() == 'senpai' || PlayState.SONG.song.toLowerCase() == 'thorns')
- FlxG.sound.music.fadeOut(2.2, 0);
-
+ sound.fadeOut(2.2, 0);
new FlxTimer().start(0.2, function(tmr:FlxTimer)
{
box.alpha -= 1 / 5;
diff --git a/source/DiffCalc.hx b/source/DiffCalc.hx
index 608fb05f3c..91bf3298d0 100644
--- a/source/DiffCalc.hx
+++ b/source/DiffCalc.hx
@@ -40,9 +40,9 @@ class DiffCalc
var gottaHitNote:Bool = i.mustHitSection;
if (ii[1] >= 3 && gottaHitNote)
- cleanedNotes.push(new SmallNote(ii[0],Math.floor(Math.abs(ii[1]))));
+ cleanedNotes.push(new SmallNote(ii[0] / FreeplayState.rate,Math.floor(Math.abs(ii[1]))));
if (ii[1] <= 4 && !gottaHitNote)
- cleanedNotes.push(new SmallNote(ii[0],Math.floor(Math.abs(ii[1]))));
+ cleanedNotes.push(new SmallNote(ii[0] / FreeplayState.rate,Math.floor(Math.abs(ii[1]))));
}
}
diff --git a/source/EtternaFunctions.hx b/source/EtternaFunctions.hx
index 9fcfbaea9d..126269a4fa 100644
--- a/source/EtternaFunctions.hx
+++ b/source/EtternaFunctions.hx
@@ -65,7 +65,7 @@ class EtternaFunctions
var max_points = 1.0;
var miss_weight = -5.5;
var ridic= 5 * ts;
- var max_boo_weight = 180 * ts;
+ var max_boo_weight = 166 * (ts / PlayState.songMultiplier);
var ts_pow = 0.75;
var zero = 65 * (Math.pow(ts,ts_pow));
var power = 2.5;
diff --git a/source/FreeplayState.hx b/source/FreeplayState.hx
index d4372e07e2..daf1c886bf 100644
--- a/source/FreeplayState.hx
+++ b/source/FreeplayState.hx
@@ -32,6 +32,9 @@ class FreeplayState extends MusicBeatState
public static var songs:Array = [];
var selector:FlxText;
+
+ public static var rate:Float = 1.0;
+
public static var curSelected:Int = 0;
public static var curDifficulty:Int = 1;
@@ -136,7 +139,7 @@ class FreeplayState extends MusicBeatState
{
if (file.contains(" "))
FileSystem.rename("assets/sm/" + i + "/" + file,"assets/sm/" + i + "/" + file.replace(" ","_"));
- if (file.endsWith(".sm"))
+ if (file.endsWith(".sm") && !FileSystem.exists("assets/sm/" + i + "/converted.json"))
{
trace("reading " + file);
var file:SMFile = SMFile.loadFile("assets/sm/" + i + "/" + file.replace(" ","_"));
@@ -147,6 +150,18 @@ class FreeplayState extends MusicBeatState
var song = Song.loadFromJsonRAW(data);
songData.set(file.header.TITLE, [song,song,song]);
}
+ else if (FileSystem.exists("assets/sm/" + i + "/converted.json") && file.endsWith(".sm"))
+ {
+ trace("reading " + file);
+ var file:SMFile = SMFile.loadFile("assets/sm/" + i + "/" + file.replace(" ","_"));
+ trace("Converting " + file.header.TITLE);
+ var data = file.convertToFNF("assets/sm/" + i + "/converted.json");
+ var meta = new SongMetadata(file.header.TITLE, 0, "sm",file,"assets/sm/" + i);
+ songs.push(meta);
+ var song = Song.loadFromJsonRAW(File.getContent("assets/sm/" + i + "/converted.json"));
+ trace("got content lol");
+ songData.set(file.header.TITLE, [song,song,song]);
+ }
}
}
}
@@ -210,7 +225,7 @@ class FreeplayState extends MusicBeatState
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), 105, 0xFF000000);
+ var scoreBG:FlxSprite = new FlxSprite(scoreText.x - 6, 0).makeGraphic(Std.int(FlxG.width * 0.35), 135, 0xFF000000);
scoreBG.alpha = 0.6;
add(scoreBG);
@@ -222,9 +237,9 @@ class FreeplayState extends MusicBeatState
diffCalcText.font = scoreText.font;
add(diffCalcText);
- previewtext = new FlxText(scoreText.x, scoreText.y + 94, 0, "" + (KeyBinds.gamepad ? "X" : "SPACE") + " to preview", 24);
+ previewtext = new FlxText(scoreText.x, scoreText.y + 94, 0, "Rate: " + rate + "x", 24);
previewtext.font = scoreText.font;
- //add(previewtext);
+ add(previewtext);
comboText = new FlxText(diffText.x + 100, diffText.y, 0, "", 24);
comboText.font = diffText.font;
@@ -349,10 +364,48 @@ class FreeplayState extends MusicBeatState
//if (FlxG.keys.justPressed.SPACE && !openedPreview)
//openSubState(new DiffOverview());
- if (FlxG.keys.justPressed.LEFT)
- changeDiff(-1);
- if (FlxG.keys.justPressed.RIGHT)
- changeDiff(1);
+ if (FlxG.keys.pressed.SHIFT)
+ {
+ if (FlxG.keys.justPressed.LEFT)
+ {
+ rate -= 0.05;
+ diffCalcText.text = 'RATING: ${DiffCalc.CalculateDiff(songData.get(songs[curSelected].songName)[curDifficulty])}';
+ }
+ if (FlxG.keys.justPressed.RIGHT)
+ {
+ rate += 0.05;
+ diffCalcText.text = 'RATING: ${DiffCalc.CalculateDiff(songData.get(songs[curSelected].songName)[curDifficulty])}';
+ }
+
+ if (rate > 3)
+ {
+ rate = 3;
+ diffCalcText.text = 'RATING: ${DiffCalc.CalculateDiff(songData.get(songs[curSelected].songName)[curDifficulty])}';
+ }
+ else if (rate < 0.5)
+ {
+ rate = 0.5;
+ diffCalcText.text = 'RATING: ${DiffCalc.CalculateDiff(songData.get(songs[curSelected].songName)[curDifficulty])}';
+ }
+
+ previewtext.text = "Rate: " + rate + "x";
+ }
+ else
+ {
+ if (FlxG.keys.justPressed.LEFT)
+ changeDiff(-1);
+ if (FlxG.keys.justPressed.RIGHT)
+ changeDiff(1);
+ }
+
+
+ #if cpp
+ @:privateAccess
+ {
+ if (FlxG.sound.music.playing)
+ lime.media.openal.AL.sourcef(FlxG.sound.music._channel.__source.__backend.handle, lime.media.openal.AL.PITCH, rate);
+ }
+ #end
if (controls.BACK)
{
@@ -398,7 +451,11 @@ class FreeplayState extends MusicBeatState
#else
PlayState.isSM = false;
#end
+
+ PlayState.songMultiplier = rate;
+
LoadingState.loadAndSwitchState(new PlayState());
+
clean();
}
}
diff --git a/source/GameOverSubstate.hx b/source/GameOverSubstate.hx
index 182ce8c79f..798feb170d 100644
--- a/source/GameOverSubstate.hx
+++ b/source/GameOverSubstate.hx
@@ -16,9 +16,9 @@ class GameOverSubstate extends MusicBeatSubstate
public function new(x:Float, y:Float)
{
- var daStage = PlayState.curStage;
+ var daStage = PlayState.Stage.curStage;
var daBf:String = '';
- switch (PlayState.SONG.player1)
+ switch (PlayState.boyfriend.curCharacter)
{
case 'bf-pixel':
stageSuffix = '-pixel';
diff --git a/source/HitGraph.hx b/source/HitGraph.hx
index 169d823197..4b9ed586b9 100644
--- a/source/HitGraph.hx
+++ b/source/HitGraph.hx
@@ -38,6 +38,8 @@ class HitGraph extends Sprite
public var bitmap:Bitmap;
+ public var ts:Float;
+
var _axis:Shape;
var _width:Int;
var _height:Int;
@@ -60,7 +62,7 @@ class HitGraph extends Sprite
_axis = new Shape();
_axis.x = _labelWidth + 10;
- var ts = Math.floor((PlayState.rep.replay.sf / 60) * 1000) / 166;
+ ts = Math.floor((PlayState.rep.replay.sf / 60) * 1000) / 166;
var early = createTextField(10,10,FlxColor.WHITE,12);
var late = createTextField(10,_height - 20,FlxColor.WHITE,12);
@@ -157,35 +159,35 @@ class HitGraph extends Sprite
gfx.lineStyle(1, graphColor, 1);
gfx.beginFill(0x00FF00);
- drawJudgementLine(45);
+ drawJudgementLine(45 );
gfx.endFill();
gfx.beginFill(0xFF0000);
- drawJudgementLine(90);
+ drawJudgementLine(90 );
gfx.endFill();
gfx.beginFill(0x8b0000);
- drawJudgementLine(135);
+ drawJudgementLine(135 );
gfx.endFill();
gfx.beginFill(0x580000);
- drawJudgementLine(166);
+ drawJudgementLine(166 );
gfx.endFill();
gfx.beginFill(0x00FF00);
- drawJudgementLine(-45);
+ drawJudgementLine(-45 );
gfx.endFill();
gfx.beginFill(0xFF0000);
- drawJudgementLine(-90);
+ drawJudgementLine(-90 );
gfx.endFill();
gfx.beginFill(0x8b0000);
- drawJudgementLine(-135);
+ drawJudgementLine(-135 );
gfx.endFill();
gfx.beginFill(0x580000);
- drawJudgementLine(-166);
+ drawJudgementLine(-166 );
gfx.endFill();
var range:Float = Math.max(maxValue - minValue, maxValue * 0.1);
@@ -233,7 +235,7 @@ class HitGraph extends Sprite
default:
gfx.beginFill(0xFFFFFF);
}
- var pointY = (-value * _height - 1) + _height;
+ var pointY = ((-value * _height - 1) + _height);
/*if (i == 0)
gfx.moveTo(graphX, _axis.y + pointY);*/
diff --git a/source/KadeEngineData.hx b/source/KadeEngineData.hx
index 9556ed3daf..2fc7cc5354 100644
--- a/source/KadeEngineData.hx
+++ b/source/KadeEngineData.hx
@@ -73,7 +73,10 @@ class KadeEngineData
if (FlxG.save.data.distractions == null)
FlxG.save.data.distractions = true;
- if (FlxG.save.data.stepMania == null)
+ if (FlxG.save.data.colour == null)
+ FlxG.save.data.colour = true;
+
+ if (FlxG.save.data.stepMania == null)
FlxG.save.data.stepMania = false;
if (FlxG.save.data.flashing == null)
@@ -130,4 +133,4 @@ class KadeEngineData
(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
index e7efdc82ee..12d1a5e35f 100644
--- a/source/KeyBindMenu.hx
+++ b/source/KeyBindMenu.hx
@@ -180,10 +180,13 @@ class KeyBindMenu extends FlxSubState
}
case "input":
- tempKey = keys[curSelected];
- keys[curSelected] = "?";
- if (KeyBinds.gamepad)
+ if (KeyBinds.gamepad) {
+ tempKey = gpKeys[curSelected];
gpKeys[curSelected] = "?";
+ } else {
+ tempKey = keys[curSelected];
+ keys[curSelected] = "?";
+ }
textUpdate();
state = "waiting";
@@ -322,12 +325,15 @@ class KeyBindMenu extends FlxSubState
var shouldReturn:Bool = true;
var notAllowed:Array = ["START"];
+ var swapKey:Int = -1;
for(x in 0...gpKeys.length)
{
var oK = gpKeys[x];
- if(oK == r)
+ if(oK == r) {
+ swapKey = x;
gpKeys[x] = null;
+ }
if (notAllowed.contains(oK))
{
gpKeys[x] = null;
@@ -336,7 +342,17 @@ class KeyBindMenu extends FlxSubState
}
}
+ if (notAllowed.contains(r))
+ {
+ gpKeys[curSelected] = tempKey;
+ lastKey = r;
+ return;
+ }
+
if(shouldReturn){
+ if (swapKey != -1) {
+ gpKeys[swapKey] = tempKey;
+ }
gpKeys[curSelected] = r;
FlxG.sound.play(Paths.sound('scrollMenu'));
}
@@ -354,6 +370,7 @@ class KeyBindMenu extends FlxSubState
var shouldReturn:Bool = true;
var notAllowed:Array = [];
+ var swapKey:Int = -1;
for(x in blacklist){notAllowed.push(x);}
@@ -362,8 +379,10 @@ class KeyBindMenu extends FlxSubState
for(x in 0...keys.length)
{
var oK = keys[x];
- if(oK == r)
+ if(oK == r) {
+ swapKey = x;
keys[x] = null;
+ }
if (notAllowed.contains(oK))
{
keys[x] = null;
@@ -372,9 +391,9 @@ class KeyBindMenu extends FlxSubState
}
}
- if (r.contains("NUMPAD"))
+ if (notAllowed.contains(r))
{
- keys[curSelected] = null;
+ keys[curSelected] = tempKey;
lastKey = r;
return;
}
@@ -382,6 +401,10 @@ class KeyBindMenu extends FlxSubState
lastKey = "";
if(shouldReturn){
+ // Swap keys instead of setting the other one as null
+ if (swapKey != -1) {
+ keys[swapKey] = tempKey;
+ }
keys[curSelected] = r;
FlxG.sound.play(Paths.sound('scrollMenu'));
}
diff --git a/source/KeyBinds.hx b/source/KeyBinds.hx
index b9c704d212..7813db5861 100644
--- a/source/KeyBinds.hx
+++ b/source/KeyBinds.hx
@@ -35,26 +35,18 @@ class KeyBinds
FlxG.save.data.upBind = "W";
trace("No UP");
}
- if (StringTools.contains(FlxG.save.data.upBind,"NUMPAD"))
- FlxG.save.data.upBind = "W";
if(FlxG.save.data.downBind == null){
FlxG.save.data.downBind = "S";
trace("No DOWN");
}
- if (StringTools.contains(FlxG.save.data.downBind,"NUMPAD"))
- FlxG.save.data.downBind = "S";
if(FlxG.save.data.leftBind == null){
FlxG.save.data.leftBind = "A";
trace("No LEFT");
}
- if (StringTools.contains(FlxG.save.data.leftBind,"NUMPAD"))
- FlxG.save.data.leftBind = "A";
if(FlxG.save.data.rightBind == null){
FlxG.save.data.rightBind = "D";
trace("No RIGHT");
}
- if (StringTools.contains(FlxG.save.data.rightBind,"NUMPAD"))
- FlxG.save.data.rightBind = "D";
if(FlxG.save.data.gpupBind == null){
FlxG.save.data.gpupBind = "DPAD_UP";
diff --git a/source/LuaClass.hx b/source/LuaClass.hx
new file mode 100644
index 0000000000..375054d1f4
--- /dev/null
+++ b/source/LuaClass.hx
@@ -0,0 +1,1789 @@
+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;
+import sys.io.File;
+import flash.display.BitmapData;
+import sys.FileSystem;
+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
+ },
+
+ "beat"=>{
+ defaultValue: 1 ,
+ getter: function(l:State,data:Any):Int{
+ Lua.pushnumber(l,connectedNote.beat);
+ return 1;
+ },
+ setter: SetNumProperty
+ },
+
+ "isSustain"=>{
+ defaultValue: 1 ,
+ getter: function(l:State,data:Any):Int{
+ Lua.pushnumber(l,connectedNote.rawNoteData);
+ return 1;
+ },
+ setter: SetNumProperty
+ },
+
+ "isParent"=>{
+ defaultValue: 1 ,
+ getter: function(l:State,data:Any):Int{
+ Lua.pushboolean(l,connectedNote.isParent);
+ return 1;
+ },
+ setter:function(l:State){
+ LuaL.error(l,"isParent is read-only.");
+ return 0;
+ }
+ },
+
+ "getParent"=>{
+ defaultValue: 1 ,
+ getter: function(l:State,data:Any):Int{
+ Lua.pushstring(l,"note_" + connectedNote.parent.luaID);
+ return 1;
+ },
+ setter:function(l:State){
+ LuaL.error(l,"getParent is read-only.");
+ return 0;
+ }
+ },
+
+ "getChildren"=>{
+ defaultValue: 1 ,
+ getter: function(l:State,data:Any):Int{
+ Lua.newtable(l);
+
+ for(i in 0...connectedNote.children.length)
+ {
+ var note = connectedNote.children[i];
+ Lua.pushstring(l,"note_" + note.luaID);
+ Lua.rawseti(l, -2, i);
+ }
+
+ return 1;
+ },
+ setter:function(l:State){
+ LuaL.error(l,"getChildren is read-only.");
+ return 0;
+ }
+ },
+
+ "getSpotInline"=>{
+ defaultValue: 1 ,
+ getter: function(l:State,data:Any):Int{
+ Lua.pushnumber(l,connectedNote.spotInLine);
+ return 1;
+ },
+ setter:function(l:State){
+ LuaL.error(l,"spot in line is read-only.");
+ return 0;
+ }
+ },
+
+ "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;
+ }
+ },
+
+
+ "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:StaticArrow;
+ public function new(connectedSprite:StaticArrow, 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.strumLineNotes.length)
+ {
+ if (index == i)
+ {
+ return PlayState.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.dad = new Character(x,y,newName,char.isPlayer);
+
+ property.char = PlayState.dad;
+
+ PlayState.instance.add(PlayState.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.Stage.toAdd)
+ {
+ PlayState.instance.remove(i);
+ }
+
+ PlayState.Stage = new Stage(stageName);
+
+ for (i in PlayState.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);
+ }
+ }
\ No newline at end of file
diff --git a/source/MainMenuState.hx b/source/MainMenuState.hx
index a1f39f8056..e4e91664e2 100644
--- a/source/MainMenuState.hx
+++ b/source/MainMenuState.hx
@@ -40,7 +40,7 @@ class MainMenuState extends MusicBeatState
public static var nightly:String = "";
- public static var kadeEngineVer:String = "1.6.2" + nightly;
+ public static var kadeEngineVer:String = "1.7" + nightly;
public static var gameVer:String = "0.2.7.1";
var magenta:FlxSprite;
diff --git a/source/ModchartState.hx b/source/ModchartState.hx
index 58215604f0..4339c3b70d 100644
--- a/source/ModchartState.hx
+++ b/source/ModchartState.hx
@@ -1,6 +1,11 @@
// this file is for modchart things, this is to declutter playstate.hx
// Lua
+import LuaClass.LuaGame;
+import LuaClass.LuaWindow;
+import LuaClass.LuaSprite;
+import LuaClass.LuaCamera;
+import LuaClass.LuaReceptor;
import openfl.display3D.textures.VideoTexture;
import flixel.graphics.FlxGraphic;
import flixel.graphics.frames.FlxAtlasFrames;
@@ -41,15 +46,14 @@ class ModchartState
var p = Lua.tostring(lua,result);
var e = getLuaErrorMessage(lua);
+ Lua.tostring(lua,-1);
+
if (e != null)
{
- if (p != null)
- {
- Application.current.window.alert("LUA ERROR:\n" + p + "\nhaxe things: " + e,"Kade Engine Modcharts");
- lua = null;
- LoadingState.loadAndSwitchState(new MainMenuState());
- }
- // trace('err: ' + e);
+ if (e != "attempt to call a nil value")
+ {
+ trace(StringTools.replace(e,"c++","haxe function"));
+ }
}
if( result == null) {
return null;
@@ -343,6 +347,9 @@ class ModchartState
}
}
#end
+
+ new LuaSprite(sprite,toBeCalled).Register(lua);
+
return toBeCalled;
}
@@ -356,599 +363,142 @@ class ModchartState
// LUA SHIT
- function new()
+ function new(? isStoryMode = true)
{
- trace('opening a lua state (because we are cool :))');
- lua = LuaL.newstate();
- LuaL.openlibs(lua);
- trace("Lua version: " + Lua.version());
- trace("LuaJIT version: " + Lua.versionJIT());
- Lua.init_callbacks(lua);
-
- //shaders = new Array();
-
- // pre lowercasing the song name (new)
- var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase();
- switch (songLowercase) {
- case 'dad-battle': songLowercase = 'dadbattle';
- case 'philly-nice': songLowercase = 'philly';
- }
-
- var path = Paths.lua(songLowercase + "/modchart");
- if (PlayState.isSM)
- path = PlayState.pathToSm + "/modchart.lua";
-
- var result = LuaL.dofile(lua, path); // execute le file
-
- if (result != 0)
- {
- Application.current.window.alert("LUA COMPILE ERROR:\n" + Lua.tostring(lua,result),"Kade Engine Modcharts");
- lua = null;
- LoadingState.loadAndSwitchState(new MainMenuState());
- }
-
- // get some fukin globals up in here bois
-
- setVar("difficulty", PlayState.storyDifficulty);
- setVar("bpm", Conductor.bpm);
- setVar("scrollspeed", FlxG.save.data.scrollSpeed != 1 ? FlxG.save.data.scrollSpeed : PlayState.SONG.speed);
- setVar("fpsCap", FlxG.save.data.fpsCap);
- setVar("downscroll", FlxG.save.data.downscroll);
- setVar("flashing", FlxG.save.data.flashing);
- setVar("distractions", FlxG.save.data.distractions);
-
- setVar("curStep", 0);
- setVar("curBeat", 0);
- setVar("crochet", Conductor.stepCrochet);
- setVar("safeZoneOffset", Conductor.safeZoneOffset);
-
- setVar("hudZoom", PlayState.instance.camHUD.zoom);
- setVar("cameraZoom", FlxG.camera.zoom);
-
- setVar("cameraAngle", FlxG.camera.angle);
- setVar("camHudAngle", PlayState.instance.camHUD.angle);
-
- setVar("followXOffset",0);
- setVar("followYOffset",0);
-
- setVar("showOnlyStrums", false);
- setVar("strumLine1Visible", true);
- setVar("strumLine2Visible", true);
-
- setVar("screenWidth",FlxG.width);
- setVar("screenHeight",FlxG.height);
- setVar("windowWidth",FlxG.width);
- setVar("windowHeight",FlxG.height);
- setVar("hudWidth", PlayState.instance.camHUD.width);
- setVar("hudHeight", PlayState.instance.camHUD.height);
-
- setVar("mustHit", false);
-
- setVar("strumLineY", PlayState.instance.strumLine.y);
-
- // callbacks
-
- // sprites
-
- Lua_helper.add_callback(lua,"makeSprite", makeLuaSprite);
-
- Lua_helper.add_callback(lua,"changeDadCharacter", changeDadCharacter);
-
- Lua_helper.add_callback(lua,"changeBoyfriendCharacter", changeBoyfriendCharacter);
-
- Lua_helper.add_callback(lua,"getProperty", getPropertyByName);
-
- Lua_helper.add_callback(lua,"setNoteWiggle", function(wiggleId) {
- PlayState.instance.camNotes.setFilters([new ShaderFilter(luaWiggles.get(wiggleId).shader)]);
- });
-
- Lua_helper.add_callback(lua,"setSustainWiggle", function(wiggleId) {
- PlayState.instance.camSustains.setFilters([new ShaderFilter(luaWiggles.get(wiggleId).shader)]);
- });
-
- Lua_helper.add_callback(lua,"createWiggle", function(freq:Float,amplitude:Float,speed:Float) {
- var wiggle = new WiggleEffect();
- wiggle.waveAmplitude = amplitude;
- wiggle.waveSpeed = speed;
- wiggle.waveFrequency = freq;
-
- var id = Lambda.count(luaWiggles) + 1 + "";
-
- luaWiggles.set(id,wiggle);
- return id;
- });
-
- Lua_helper.add_callback(lua,"setWiggleTime", function(wiggleId:String,time:Float) {
- var wiggle = luaWiggles.get(wiggleId);
-
- wiggle.shader.uTime.value = [time];
- });
-
-
- Lua_helper.add_callback(lua,"setWiggleAmplitude", function(wiggleId:String,amp:Float) {
- var wiggle = luaWiggles.get(wiggleId);
-
- wiggle.waveAmplitude = amp;
- });
-
-
-
- // Lua_helper.add_callback(lua,"makeAnimatedSprite", makeAnimatedLuaSprite);
- // this one is still in development
-
- Lua_helper.add_callback(lua,"destroySprite", function(id:String) {
- var sprite = luaSprites.get(id);
- if (sprite == null)
- return false;
- PlayState.instance.removeObject(sprite);
- return true;
- });
-
- // hud/camera
-
- Lua_helper.add_callback(lua,"initBackgroundVideo", function(videoName:String) {
- trace('playing assets/videos/' + videoName + '.webm');
- PlayState.instance.backgroundVideo("assets/videos/" + videoName + ".webm");
- });
-
- Lua_helper.add_callback(lua,"pauseVideo", function() {
- if (!GlobalVideo.get().paused)
- GlobalVideo.get().pause();
- });
-
- Lua_helper.add_callback(lua,"resumeVideo", function() {
- if (GlobalVideo.get().paused)
- GlobalVideo.get().pause();
- });
-
- Lua_helper.add_callback(lua,"restartVideo", function() {
- GlobalVideo.get().restart();
- });
-
- Lua_helper.add_callback(lua,"getVideoSpriteX", function() {
- return PlayState.instance.videoSprite.x;
- });
-
- Lua_helper.add_callback(lua,"getVideoSpriteY", function() {
- return PlayState.instance.videoSprite.y;
- });
-
- Lua_helper.add_callback(lua,"setVideoSpritePos", function(x:Int,y:Int) {
- PlayState.instance.videoSprite.setPosition(x,y);
- });
-
- Lua_helper.add_callback(lua,"setVideoSpriteScale", function(scale:Float) {
- PlayState.instance.videoSprite.setGraphicSize(Std.int(PlayState.instance.videoSprite.width * scale));
- });
-
- 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,"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,"setCamPosition", function (x:Int, y:Int) {
- FlxG.camera.x = x;
- FlxG.camera.y = y;
- });
-
- 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,"setHudZoom", function(zoomAmount:Float) {
- PlayState.instance.camHUD.zoom = zoomAmount;
- });
-
- // strumline
-
- Lua_helper.add_callback(lua, "setStrumlineY", function(y:Float)
- {
- PlayState.instance.strumLine.y = y;
- });
-
- // 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.playerStrums.members[Math.floor(Math.abs(PlayState.instance.notes.members[id].noteData))].x;
- return PlayState.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) {
- getActorByName(id).x = x;
- });
-
- 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) {
- getActorByName(id).velocity.x = x;
- });
-
- Lua_helper.add_callback(lua,"playActorAnimation", function(id:String,anim:String,force:Bool = false,reverse:Bool = false) {
- getActorByName(id).playAnim(anim, force, reverse);
- });
-
- Lua_helper.add_callback(lua,"setActorAlpha", function(alpha:Float,id:String) {
- getActorByName(id).alpha = alpha;
- });
-
- Lua_helper.add_callback(lua,"setActorY", function(y:Int,id:String) {
- 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) {
- getActorByName(id).setGraphicSize(Std.int(getActorByName(id).width * scale));
- });
-
- 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, "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) {
- return getActorByName(id).x;
- });
-
- Lua_helper.add_callback(lua,"getActorY", function (id:String) {
- return getActorByName(id).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) {callLua(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) {callLua(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) {callLua(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) {callLua(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) {callLua(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) {callLua(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) {callLua(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) {callLua(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) {callLua(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) {callLua(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) {callLua(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) {callLua(onComplete,["camera"]);}}});
- });
-
- Lua_helper.add_callback(lua,"tweenCameraZoomOut", function(toZoom:Float, time:Float, onComplete:String) {
- FlxTween.tween(FlxG.camera, {zoom:toZoom}, time, {ease: FlxEase.cubeOut, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {callLua(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) {callLua(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) {callLua(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) {callLua(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) {callLua(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) {callLua(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) {callLua(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) {callLua(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) {callLua(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) {callLua(onComplete,["camera"]);}}});
- });
-
- Lua_helper.add_callback(lua,"tweenCameraZoomIn", function(toZoom:Float, time:Float, onComplete:String) {
- FlxTween.tween(FlxG.camera, {zoom:toZoom}, time, {ease: FlxEase.cubeIn, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {callLua(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) {callLua(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) {callLua(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) {callLua(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) {callLua(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) {callLua(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) {callLua(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) {callLua(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) {callLua(onComplete,[id]);}}});
- });
-
- Lua_helper.add_callback(lua,"tweenFadeOut", function(id:String, toAlpha:Float, time:Float, onComplete:String) {
- FlxTween.tween(getActorByName(id), {alpha: toAlpha}, time, {ease: FlxEase.circOut, onComplete: function(flxTween:FlxTween) { if (onComplete != '' && onComplete != null) {callLua(onComplete,[id]);}}});
- });
-
- //forgot and accidentally commit to master branch
- // shader
-
- /*Lua_helper.add_callback(lua,"createShader", function(frag:String,vert:String) {
- var shader:LuaShader = new LuaShader(frag,vert);
-
- trace(shader.glFragmentSource);
-
- shaders.push(shader);
- // if theres 1 shader we want to say theres 0 since 0 index and length returns a 1 index.
- return shaders.length == 1 ? 0 : shaders.length;
- });
-
-
- Lua_helper.add_callback(lua,"setFilterHud", function(shaderIndex:Int) {
- PlayState.instance.camHUD.setFilters([new ShaderFilter(shaders[shaderIndex])]);
- });
-
- Lua_helper.add_callback(lua,"setFilterCam", function(shaderIndex:Int) {
- FlxG.camera.setFilters([new ShaderFilter(shaders[shaderIndex])]);
- });*/
-
- // default strums
-
- for (i in 0...PlayState.strumLineNotes.length) {
- var member = PlayState.strumLineNotes.members[i];
- trace(PlayState.strumLineNotes.members[i].x + " " + PlayState.strumLineNotes.members[i].y + " " + PlayState.strumLineNotes.members[i].angle + " | strum" + i);
- //setVar("strum" + i + "X", Math.floor(member.x));
- setVar("defaultStrum" + i + "X", Math.floor(member.x));
- //setVar("strum" + i + "Y", Math.floor(member.y));
- setVar("defaultStrum" + i + "Y", Math.floor(member.y));
- //setVar("strum" + i + "Angle", Math.floor(member.angle));
- setVar("defaultStrum" + i + "Angle", Math.floor(member.angle));
- trace("Adding strum" + i);
- }
+ trace('opening a lua state (because we are cool :))');
+ lua = LuaL.newstate();
+ LuaL.openlibs(lua);
+ trace("Lua version: " + Lua.version());
+ trace("LuaJIT version: " + Lua.versionJIT());
+ Lua.init_callbacks(lua);
+
+ // shaders = new Array();
+
+ // pre lowercasing the song name (new)
+ var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase();
+ switch (songLowercase)
+ {
+ case 'dad-battle':
+ songLowercase = 'dadbattle';
+ case 'philly-nice':
+ songLowercase = 'philly';
+ }
+
+ var path = Paths.lua(songLowercase + "/modchart");
+ if (PlayState.isSM)
+ path = PlayState.pathToSm + "/modchart.lua";
+
+ var result = LuaL.dofile(lua, path); // execute le file
+
+ if (result != 0)
+ {
+ Application.current.window.alert("LUA COMPILE ERROR:\n" + Lua.tostring(lua, result), "Kade Engine Modcharts");
+ FlxG.switchState(new FreeplayState());
+ return;
+ }
+
+ // get some fukin globals up in here bois
+
+ setVar("difficulty", PlayState.storyDifficulty);
+ setVar("bpm", Conductor.bpm);
+ setVar("scrollspeed", FlxG.save.data.scrollSpeed != 1 ? FlxG.save.data.scrollSpeed : PlayState.SONG.speed);
+ setVar("fpsCap", FlxG.save.data.fpsCap);
+ setVar("downscroll", FlxG.save.data.downscroll);
+ setVar("flashing", FlxG.save.data.flashing);
+ setVar("distractions", FlxG.save.data.distractions);
+ setVar("colour", FlxG.save.data.colour);
+
+ setVar("curStep", 0);
+ setVar("curBeat", 0);
+ setVar("crochet", Conductor.stepCrochet);
+ setVar("safeZoneOffset", Conductor.safeZoneOffset);
+
+ setVar("hudZoom", PlayState.instance.camHUD.zoom);
+ setVar("cameraZoom", FlxG.camera.zoom);
+
+ setVar("cameraAngle", FlxG.camera.angle);
+ setVar("camHudAngle", PlayState.instance.camHUD.angle);
+
+ setVar("followXOffset", 0);
+ setVar("followYOffset", 0);
+
+ setVar("showOnlyStrums", false);
+ setVar("strumLine1Visible", true);
+ setVar("strumLine2Visible", true);
+
+ setVar("screenWidth", FlxG.width);
+ setVar("screenHeight", FlxG.height);
+ setVar("windowWidth", FlxG.width);
+ setVar("windowHeight", FlxG.height);
+ setVar("hudWidth", PlayState.instance.camHUD.width);
+ setVar("hudHeight", PlayState.instance.camHUD.height);
+
+ setVar("mustHit", false);
+
+ setVar("strumLineY", PlayState.instance.strumLine.y);
+
+ // callbacks
+
+ Lua_helper.add_callback(lua, "makeSprite", makeLuaSprite);
+
+ // sprites
+
+ Lua_helper.add_callback(lua, "setNoteWiggle", function(wiggleId)
+ {
+ PlayState.instance.camNotes.setFilters([new ShaderFilter(luaWiggles.get(wiggleId).shader)]);
+ });
+
+ Lua_helper.add_callback(lua, "setSustainWiggle", function(wiggleId)
+ {
+ PlayState.instance.camSustains.setFilters([new ShaderFilter(luaWiggles.get(wiggleId).shader)]);
+ });
+
+ Lua_helper.add_callback(lua, "createWiggle", function(freq:Float, amplitude:Float, speed:Float)
+ {
+ var wiggle = new WiggleEffect();
+ wiggle.waveAmplitude = amplitude;
+ wiggle.waveSpeed = speed;
+ wiggle.waveFrequency = freq;
+
+ var id = Lambda.count(luaWiggles) + 1 + "";
+
+ luaWiggles.set(id, wiggle);
+ return id;
+ });
+
+ Lua_helper.add_callback(lua, "setWiggleTime", function(wiggleId:String, time:Float)
+ {
+ var wiggle = luaWiggles.get(wiggleId);
+
+ wiggle.shader.uTime.value = [time];
+ });
+
+ Lua_helper.add_callback(lua, "setWiggleAmplitude", function(wiggleId:String, amp:Float)
+ {
+ var wiggle = luaWiggles.get(wiggleId);
+
+ wiggle.waveAmplitude = amp;
+ });
+
+ Lua_helper.add_callback(lua, "setStrumlineY", function(y:Float)
+ {
+ PlayState.instance.strumLine.y = y;
+ });
+
+ Lua_helper.add_callback(lua, "getNumberOfNotes", function(y:Float)
+ {
+ return PlayState.instance.notes.members.length;
+ });
+
+ for (i in 0...PlayState.strumLineNotes.length)
+ {
+ var member = PlayState.strumLineNotes.members[i];
+ new LuaReceptor(member, "receptor_" + i).Register(lua);
+ }
+
+ new LuaGame().Register(lua);
+
+ new LuaWindow().Register(lua);
}
public function executeState(name,args:Array)
@@ -956,9 +506,9 @@ class ModchartState
return Lua.tostring(lua,callLua(name, args));
}
- public static function createModchartState():ModchartState
+ public static function createModchartState(? isStoryMode = true):ModchartState
{
- return new ModchartState();
+ return new ModchartState(isStoryMode);
}
}
#end
diff --git a/source/MusicBeatState.hx b/source/MusicBeatState.hx
index 5575771693..75f36a9d0c 100644
--- a/source/MusicBeatState.hx
+++ b/source/MusicBeatState.hx
@@ -107,8 +107,8 @@ class MusicBeatState extends FlxUIState
var step = ((60 / data.bpm) * 1000) / 4;
var startInMS = (data.startTime * 1000);
- curDecimalBeat = data.startBeat + (((Conductor.songPosition/1000) - data.startTime) * (data.bpm / 60));
- var ste:Int = Math.floor(data.startStep + ((Conductor.songPosition - startInMS) / step));
+ curDecimalBeat = data.startBeat + ((((Conductor.songPosition / 1000) ) - data.startTime) * (data.bpm / 60));
+ var ste:Int = Math.floor(data.startStep + ((Conductor.songPosition ) - startInMS) / step);
if (ste >= 0)
{
if (ste > curStep)
@@ -132,8 +132,8 @@ class MusicBeatState extends FlxUIState
}
else
{
- curDecimalBeat = (Conductor.songPosition / 1000) * (Conductor.bpm/60);
- var nextStep:Int = Math.floor(Conductor.songPosition / Conductor.stepCrochet);
+ curDecimalBeat = (((Conductor.songPosition / 1000))) * (Conductor.bpm/60);
+ var nextStep:Int = Math.floor((Conductor.songPosition) / Conductor.stepCrochet);
if (nextStep >= 0)
{
if (nextStep > curStep)
diff --git a/source/Note.hx b/source/Note.hx
index e42b218ba4..e6bb8e1fdb 100644
--- a/source/Note.hx
+++ b/source/Note.hx
@@ -35,6 +35,8 @@ class Note extends FlxSprite
public var originColor:Int = 0; // The sustain note's original note's color
public var noteSection:Int = 0;
+ public var luaID:Int = 0;
+
public var isAlt:Bool = false;
public var noteCharterObject:FlxSprite;
@@ -43,6 +45,8 @@ class Note extends FlxSprite
public var noteYOff:Int = 0;
+ public var beat:Float = 0;
+
public static var swagWidth:Float = 160 * 0.7;
public static var PURP_NOTE:Int = 0;
public static var GREEN_NOTE:Int = 2;
@@ -53,9 +57,10 @@ class Note extends FlxSprite
public var modAngle:Float = 0; // The angle set by modcharts
public var localAngle:Float = 0; // The angle to be edited inside Note.hx
+ public var originAngle:Float = 0; // The angle the OG note of the sus note had (?)
public var dataColor:Array = ['purple', 'blue', 'green', 'red'];
- public var quantityColor:Array = [RED_NOTE, 2, BLUE_NOTE, 2, PURP_NOTE, 2, BLUE_NOTE, 2];
+ public var quantityColor:Array = [RED_NOTE, 2, BLUE_NOTE, 2, PURP_NOTE, 2, GREEN_NOTE, 2];
public var arrowAngles:Array = [180, 90, 270, 0];
public var isParent:Bool = false;
@@ -65,13 +70,15 @@ class Note extends FlxSprite
public var children:Array = [];
- public function new(strumTime:Float, noteData:Int, ?prevNote:Note, ?sustainNote:Bool = false, ?inCharter:Bool = false, ?isAlt:Bool = false)
+ public function new(strumTime:Float, noteData:Int, ?prevNote:Note, ?sustainNote:Bool = false, ?inCharter:Bool = false, ?isAlt:Bool = false, ?bet:Float = 0)
{
super();
if (prevNote == null)
prevNote = this;
+ beat = bet;
+
this.isAlt = isAlt;
this.prevNote = prevNote;
@@ -95,9 +102,9 @@ class Note extends FlxSprite
rStrumTime = strumTime;
}
else
- rStrumTime = (strumTime - FlxG.save.data.offset + PlayState.songOffset);
+ rStrumTime = strumTime;
#else
- rStrumTime = (strumTime - FlxG.save.data.offset + PlayState.songOffset);
+ rStrumTime = strumTime;
#end
}
@@ -105,9 +112,12 @@ class Note extends FlxSprite
if (this.strumTime < 0 )
this.strumTime = 0;
+ if (!inCharter)
+ y += FlxG.save.data.offset + PlayState.songOffset;
+
this.noteData = noteData;
- var daStage:String = PlayState.curStage;
+ var daStage:String = PlayState.Stage.curStage;
//defaults if no noteStyle was found in chart
var noteTypeCheck:String = 'normal';
@@ -147,9 +157,7 @@ class Note extends FlxSprite
animation.add(dataColor[i] + 'holdend', [i + 4]); // Tails
}
- var widthSize = Std.int(PlayState.curStage.startsWith('school') ? (width * PlayState.daPixelZoom) : (isSustainNote ? (width * (PlayState.daPixelZoom - 1.5)) : (width * PlayState.daPixelZoom)));
-
- setGraphicSize(widthSize);
+ setGraphicSize(Std.int(width * PlayState.daPixelZoom));
updateHitbox();
default:
frames = Paths.getSparrowAtlas('NOTE_assets');
@@ -172,22 +180,32 @@ class Note extends FlxSprite
animation.play(dataColor[noteData] + 'Scroll');
originColor = noteData; // The note's origin color will be checked by its sustain notes
- if (FlxG.save.data.stepMania && !isSustainNote)
+ if (FlxG.save.data.stepMania && !isSustainNote && !PlayState.instance.executeModchart)
{
- var strumCheck:Float = rStrumTime;
+ var col:Int = 0;
- // I give up on fluctuating bpms. something has to be subtracted from strumCheck to make them look right but idk what.
- // I'd use the note's section's start time but neither the note's section nor its start time are accessible by themselves
- //strumCheck -= ???
+ var beatRow = Math.round(beat * 48);
- var ind:Int = Std.int(Math.round(strumCheck / (Conductor.stepCrochet / 2)));
+ // STOLEN ETTERNA CODE (IN 2002)
+
+ if (beatRow % (192 / 4) == 0)
+ col = quantityColor[0];
+ else if (beatRow % (192 / 8) == 0)
+ col = quantityColor[2];
+ else if (beatRow % (192 / 12) == 0)
+ col = quantityColor[4];
+ else if (beatRow % (192 / 16) == 0)
+ col = quantityColor[6];
+ else if (beatRow % (192 / 24) == 0)
+ col = quantityColor[4];
+ else if (beatRow % (192 / 32) == 0)
+ col = quantityColor[4];
- var col:Int = 0;
- col = quantityColor[ind % 8]; // Set the color depending on the beats
animation.play(dataColor[col] + 'Scroll');
localAngle -= arrowAngles[col];
localAngle += arrowAngles[noteData];
+ originAngle = localAngle;
originColor = col;
}
@@ -199,7 +217,10 @@ class Note extends FlxSprite
if (FlxG.save.data.downscroll && sustainNote)
flipY = true;
- var stepHeight = (0.45 * Conductor.stepCrochet * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? PlayState.SONG.speed : PlayStateChangeables.scrollSpeed, 2));
+
+ var stepHeight = (((0.45 * Conductor.stepCrochet)) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? PlayState.SONG.speed : PlayStateChangeables.scrollSpeed, 2));
+
+ // we can't divide step height cuz if we do uh it'll fucking lag the shit out of the game
if (isSustainNote && prevNote != null)
{
@@ -209,6 +230,7 @@ class Note extends FlxSprite
x += width / 2;
originColor = prevNote.originColor;
+ originAngle = prevNote.originAngle;
animation.play(dataColor[originColor] + 'holdend'); // This works both for normal colors and quantization colors
updateHitbox();
@@ -225,6 +247,7 @@ class Note extends FlxSprite
prevNote.animation.play(dataColor[prevNote.originColor] + 'hold');
prevNote.updateHitbox();
+
prevNote.scale.y *= (stepHeight + 1) / prevNote.height; // + 1 so that there's no odd gaps as the notes scroll
prevNote.updateHitbox();
prevNote.noteYOff = Math.round(-prevNote.offset.y);
@@ -239,7 +262,10 @@ class Note extends FlxSprite
override function update(elapsed:Float)
{
super.update(elapsed);
- angle = modAngle + localAngle;
+ if (!modifiedByLua)
+ angle = modAngle + localAngle;
+ else
+ angle = modAngle;
if (!modifiedByLua)
{
@@ -253,22 +279,22 @@ class Note extends FlxSprite
{
if (isSustainNote)
{
- if (strumTime - Conductor.songPosition <= ((166 * Conductor.timeScale) * 0.5)
- && strumTime - Conductor.songPosition >= (-166 * Conductor.timeScale))
+ if (strumTime - Conductor.songPosition <= ((166 * Conductor.timeScale) * PlayState.songMultiplier * 0.5)
+ && strumTime - Conductor.songPosition >=((-166 * Conductor.timeScale) * PlayState.songMultiplier))
canBeHit = true;
else
canBeHit = false;
}
else
{
- if (strumTime - Conductor.songPosition <= (166 * Conductor.timeScale)
- && strumTime - Conductor.songPosition >= (-166 * Conductor.timeScale))
+ if (strumTime - Conductor.songPosition <= ((166 * Conductor.timeScale) * PlayState.songMultiplier)
+ && strumTime - Conductor.songPosition >= ((-166 * Conductor.timeScale) * PlayState.songMultiplier))
canBeHit = true;
else
canBeHit = false;
}
- if (strumTime - Conductor.songPosition < -166 && !wasGoodHit)
- tooLate = true;
+ /*if (strumTime - Conductor.songPosition < (-166 * Conductor.timeScale) && !wasGoodHit)
+ tooLate = true;*/
}
else
{
diff --git a/source/Options.hx b/source/Options.hx
index 0248a8d4a3..5ac14f4d66 100644
--- a/source/Options.hx
+++ b/source/Options.hx
@@ -267,6 +267,26 @@ class DistractionsAndEffectsOption extends Option
}
}
+class Colour extends Option
+{
+ public function new(desc:String)
+ {
+ super();
+ description = desc;
+ }
+ public override function press():Bool
+ {
+ FlxG.save.data.colour = !FlxG.save.data.colour;
+ display = updateDisplay();
+ return true;
+ }
+
+ private override function updateDisplay():String
+ {
+ return "Color Health Bar By Character " + (!FlxG.save.data.colour ? "off" : "on");
+ }
+}
+
class StepManiaOption extends Option
{
public function new(desc:String)
@@ -933,6 +953,7 @@ class ResetSettings extends Option
FlxG.save.data.watermark = null;
FlxG.save.data.ghost = null;
FlxG.save.data.distractions = null;
+ FlxG.save.data.colour = null;
FlxG.save.data.stepMania = null;
FlxG.save.data.flashing = null;
FlxG.save.data.resetButton = null;
diff --git a/source/OptionsMenu.hx b/source/OptionsMenu.hx
index 440df091b7..d4d5e19748 100644
--- a/source/OptionsMenu.hx
+++ b/source/OptionsMenu.hx
@@ -47,6 +47,7 @@ class OptionsMenu extends MusicBeatState
new StepManiaOption("Sets the colors of the arrows depending on quantization instead of direction."),
new AccuracyOption("Display accuracy information on the info bar."),
new SongPositionOption("Show the song's current position as a scrolling bar."),
+ new Colour("The color behind icons now fit with their theme. (e.g. Pico = green)"),
new NPSDisplayOption("Shows your current Notes Per Second on the info bar."),
new RainbowFPSOption("Make the FPS Counter flicker through rainbow colors."),
new CpuStrums("Toggle the CPU's strumline lighting up when it hits a note."),
@@ -67,7 +68,7 @@ class OptionsMenu extends MusicBeatState
new OptionCategory("Saves and Data", [
#if desktop
- new ReplayOption("View saved song replays."),
+ //new ReplayOption("View saved song replays."),
#end
new ResetScoreOption("Reset your score on all songs and weeks. This is irreversible!"),
new LockWeeksOption("Reset your story mode progress. This is irreversible!"),
diff --git a/source/PlayState.hx b/source/PlayState.hx
index 3acdc32af1..b8f8241f5f 100644
--- a/source/PlayState.hx
+++ b/source/PlayState.hx
@@ -1,6 +1,10 @@
package;
+import LuaClass.LuaCamera;
+import LuaClass.LuaCharacter;
+import lime.media.openal.AL;
+import LuaClass.LuaNote;
import Song.Event;
import openfl.media.Sound;
#if sys
@@ -79,11 +83,11 @@ import sys.FileSystem;
using StringTools;
+
class PlayState extends MusicBeatState
{
public static var instance:PlayState = null;
- public static var curStage:String = '';
public static var SONG:SwagSong;
public static var isStoryMode:Bool = false;
public static var storyWeek:Int = 0;
@@ -100,6 +104,8 @@ class PlayState extends MusicBeatState
public var visibleCombos:Array = [];
+ public var visibleNotes:Array = [];
+
public static var songPosBar:FlxBar;
public static var rep:Replay;
@@ -108,8 +114,6 @@ class PlayState extends MusicBeatState
public static var noteBools:Array = [false, false, false, false];
- var halloweenLevel:Bool = false;
-
var songLength:Float = 0;
var kadeEngineWatermark:FlxText;
@@ -147,9 +151,9 @@ class PlayState extends MusicBeatState
private static var prevCamFollow:FlxObject;
- public static var strumLineNotes:FlxTypedGroup = null;
- public static var playerStrums:FlxTypedGroup = null;
- public static var cpuStrums:FlxTypedGroup = null;
+ public static var strumLineNotes:FlxTypedGroup = null;
+ public static var playerStrums:FlxTypedGroup = null;
+ public static var cpuStrums:FlxTypedGroup = null;
private var camZooming:Bool = false;
private var curSong:String = "";
@@ -197,29 +201,19 @@ class PlayState extends MusicBeatState
var notesHitArray:Array = [];
var currentFrames:Int = 0;
- var idleToBeat:Bool = true; // change if bf and dad would idle to the beat of the song
+ var idleToBeat:Bool = false; // change if bf and dad would idle to the beat of the song
var idleBeat:Int = 2; // how frequently bf and dad would play their idle animation(1 - every beat, 2 - every 2 beats and so on)
public var dialogue:Array = ['dad:blah blah blah', 'bf:coolswag'];
- var halloweenBG:FlxSprite;
- var isHalloween:Bool = false;
-
- var phillyCityLights:FlxTypedGroup;
- var phillyTrain:FlxSprite;
- var trainSound:FlxSound;
+ public static var trainSound:FlxSound;
- var limo:FlxSprite;
- var grpLimoDancers:FlxTypedGroup;
- var fastCar:FlxSprite;
var songName:FlxText;
- var upperBoppers:FlxSprite;
- var bottomBoppers:FlxSprite;
- var santa:FlxSprite;
+
+ public var currentSection:SwagSection;
var fc:Bool = true;
- var bgGirls:BackgroundGirls;
var wiggleShit:WiggleEffect = new WiggleEffect();
var talking:Bool = true;
@@ -232,8 +226,6 @@ class PlayState extends MusicBeatState
public static var campaignScore:Int = 0;
- var defaultCamZoom:Float = 1.05;
-
public static var daPixelZoom:Float = 6;
public static var theFunne:Bool = true;
@@ -242,6 +234,10 @@ class PlayState extends MusicBeatState
var inCutscene:Bool = false;
var usedTimeTravel:Bool = false;
+ public var randomVar = false;
+
+ public static var Stage:Stage;
+
public static var repPresses:Int = 0;
public static var repReleases:Int = 0;
@@ -266,7 +262,7 @@ class PlayState extends MusicBeatState
public static var highestCombo:Int = 0;
- private var executeModchart = false;
+ public var executeModchart = false;
// Animation common suffixes
private var dataSuffix:Array = ['LEFT', 'DOWN', 'UP', 'RIGHT'];
@@ -288,10 +284,14 @@ class PlayState extends MusicBeatState
override public function create()
{
-
FlxG.mouse.visible = false;
instance = this;
+ previousRate = songMultiplier - 0.05;
+
+ if (previousRate < 1.00)
+ previousRate = 1;
+
if (FlxG.save.data.fpsCap > 290)
(cast(Lib.current.getChildAt(0), Main)).setFPSCap(800);
@@ -342,6 +342,10 @@ class PlayState extends MusicBeatState
trace('Mod chart: ' + executeModchart + " - " + Paths.lua(songLowercase + "/modchart"));
+
+ if (executeModchart)
+ songMultiplier = 1;
+
#if windows
// Making difficulty text for Discord Rich Presence.
storyDifficultyText = CoolUtil.difficultyFromInt(storyDifficulty);
@@ -372,8 +376,6 @@ class PlayState extends MusicBeatState
// String for when the game is paused
detailsPausedText = "Paused - " + detailsText;
- curStage = "";
-
// Updating Discord Rich Presence.
DiscordClient.changePresence(detailsText
+ " "
@@ -417,11 +419,12 @@ class PlayState extends MusicBeatState
Conductor.mapBPMChanges(SONG);
Conductor.changeBPM(SONG.bpm);
+ Conductor.bpm = SONG.bpm;
+
if (SONG.eventObjects == null)
{
SONG.eventObjects = [new Song.Event("Init BPM",0,SONG.bpm,"BPM Change")];
}
-
TimingStruct.clearTimings();
@@ -434,7 +437,9 @@ class PlayState extends MusicBeatState
var endBeat:Float = Math.POSITIVE_INFINITY;
- TimingStruct.addTiming(beat,i.value,endBeat, 0); // offset in this case = start time since we don't have a offset
+ var bpm = i.value;
+
+ TimingStruct.addTiming(beat,bpm,endBeat, 0); // offset in this case = start time since we don't have a offset
if (currentIndex != 0)
{
@@ -448,8 +453,11 @@ class PlayState extends MusicBeatState
}
}
+
+ recalculateAllSectionTimes();
+
trace('INFORMATION ABOUT WHAT U PLAYIN WIT:\nFRAMES: ' + PlayStateChangeables.safeFrames + '\nZONE: ' + Conductor.safeZoneOffset + '\nTS: '
+ Conductor.timeScale + '\nBotPlay : ' + PlayStateChangeables.botPlay);
@@ -457,7 +465,7 @@ class PlayState extends MusicBeatState
{
//if the song has dialogue, so we don't accidentally try to load a nonexistant file and crash the game
case 'senpai' | 'roses' | 'thorns':
- dialogue = CoolUtil.coolTextFile(Paths.txt('data/' + songLowercase + '/dialogue'));
+ dialogue = CoolUtil.coolTextFile(Paths.txt('data/$songLowercase/dialogue'));
}
// defaults if no stage was found in chart
@@ -499,373 +507,9 @@ class PlayState extends MusicBeatState
stageCheck = SONG.stage;
}
- if (!PlayStateChangeables.Optimize)
- {
- switch (stageCheck)
- {
- case 'halloween':
- {
- curStage = 'spooky';
- halloweenLevel = true;
-
- var hallowTex = Paths.getSparrowAtlas('halloween_bg', 'week2');
-
- halloweenBG = new FlxSprite(-200, -100);
- halloweenBG.frames = hallowTex;
- halloweenBG.animation.addByPrefix('idle', 'halloweem bg0');
- halloweenBG.animation.addByPrefix('lightning', 'halloweem bg lightning strike', 24, false);
- halloweenBG.animation.play('idle');
- halloweenBG.antialiasing = FlxG.save.data.antialiasing;
- add(halloweenBG);
-
- isHalloween = true;
- }
- case 'philly':
- {
- curStage = 'philly';
-
- var bg:FlxSprite = new FlxSprite(-100).loadGraphic(Paths.image('philly/sky', 'week3'));
- bg.scrollFactor.set(0.1, 0.1);
- add(bg);
-
- var city:FlxSprite = new FlxSprite(-10).loadGraphic(Paths.image('philly/city', 'week3'));
- city.scrollFactor.set(0.3, 0.3);
- city.setGraphicSize(Std.int(city.width * 0.85));
- city.updateHitbox();
- add(city);
-
- phillyCityLights = new FlxTypedGroup();
- if (FlxG.save.data.distractions)
- {
- add(phillyCityLights);
- }
-
- for (i in 0...5)
- {
- var light:FlxSprite = new FlxSprite(city.x).loadGraphic(Paths.image('philly/win' + i, 'week3'));
- light.scrollFactor.set(0.3, 0.3);
- light.visible = false;
- light.setGraphicSize(Std.int(light.width * 0.85));
- light.updateHitbox();
- light.antialiasing = FlxG.save.data.antialiasing;
- phillyCityLights.add(light);
- }
-
- var streetBehind:FlxSprite = new FlxSprite(-40, 50).loadGraphic(Paths.image('philly/behindTrain', 'week3'));
- add(streetBehind);
-
- phillyTrain = new FlxSprite(2000, 360).loadGraphic(Paths.image('philly/train', 'week3'));
- if (FlxG.save.data.distractions)
- {
- add(phillyTrain);
- }
-
- trainSound = new FlxSound().loadEmbedded(Paths.sound('train_passes', 'week3'));
- FlxG.sound.list.add(trainSound);
-
- // var cityLights:FlxSprite = new FlxSprite().loadGraphic(AssetPaths.win0.png);
-
- var street:FlxSprite = new FlxSprite(-40, streetBehind.y).loadGraphic(Paths.image('philly/street', 'week3'));
- add(street);
- }
- case 'limo':
- {
- curStage = 'limo';
- defaultCamZoom = 0.90;
-
- var skyBG:FlxSprite = new FlxSprite(-120, -50).loadGraphic(Paths.image('limo/limoSunset', 'week4'));
- skyBG.scrollFactor.set(0.1, 0.1);
- skyBG.antialiasing = FlxG.save.data.antialiasing;
- add(skyBG);
-
- var bgLimo:FlxSprite = new FlxSprite(-200, 480);
- bgLimo.frames = Paths.getSparrowAtlas('limo/bgLimo', 'week4');
- bgLimo.animation.addByPrefix('drive', "background limo pink", 24);
- bgLimo.animation.play('drive');
- bgLimo.scrollFactor.set(0.4, 0.4);
- bgLimo.antialiasing = FlxG.save.data.antialiasing;
- add(bgLimo);
- if (FlxG.save.data.distractions)
- {
- grpLimoDancers = new FlxTypedGroup();
- add(grpLimoDancers);
-
- for (i in 0...5)
- {
- var dancer:BackgroundDancer = new BackgroundDancer((370 * i) + 130, bgLimo.y - 400);
- dancer.scrollFactor.set(0.4, 0.4);
- grpLimoDancers.add(dancer);
- }
- }
-
- var overlayShit:FlxSprite = new FlxSprite(-500, -600).loadGraphic(Paths.image('limo/limoOverlay', 'week4'));
- overlayShit.alpha = 0.5;
- // add(overlayShit);
-
- // var shaderBullshit = new BlendModeEffect(new OverlayShader(), FlxColor.RED);
-
- // FlxG.camera.setFilters([new ShaderFilter(cast shaderBullshit.shader)]);
-
- // overlayShit.shader = shaderBullshit;
-
- var limoTex = Paths.getSparrowAtlas('limo/limoDrive', 'week4');
-
- limo = new FlxSprite(-120, 550);
- limo.frames = limoTex;
- limo.animation.addByPrefix('drive', "Limo stage", 24);
- limo.animation.play('drive');
- limo.antialiasing = FlxG.save.data.antialiasing;
-
- fastCar = new FlxSprite(-300, 160).loadGraphic(Paths.image('limo/fastCarLol', 'week4'));
- fastCar.antialiasing = FlxG.save.data.antialiasing;
- // add(limo);
- }
- case 'mall':
- {
- curStage = 'mall';
-
- defaultCamZoom = 0.80;
-
- var bg:FlxSprite = new FlxSprite(-1000, -500).loadGraphic(Paths.image('christmas/bgWalls', 'week5'));
- bg.antialiasing = FlxG.save.data.antialiasing;
- bg.scrollFactor.set(0.2, 0.2);
- bg.active = false;
- bg.setGraphicSize(Std.int(bg.width * 0.8));
- bg.updateHitbox();
- add(bg);
-
- upperBoppers = new FlxSprite(-240, -90);
- upperBoppers.frames = Paths.getSparrowAtlas('christmas/upperBop', 'week5');
- upperBoppers.animation.addByPrefix('bop', "Upper Crowd Bob", 24, false);
- upperBoppers.antialiasing = FlxG.save.data.antialiasing;
- upperBoppers.scrollFactor.set(0.33, 0.33);
- upperBoppers.setGraphicSize(Std.int(upperBoppers.width * 0.85));
- upperBoppers.updateHitbox();
- if (FlxG.save.data.distractions)
- {
- add(upperBoppers);
- }
-
- var bgEscalator:FlxSprite = new FlxSprite(-1100, -600).loadGraphic(Paths.image('christmas/bgEscalator', 'week5'));
- bgEscalator.antialiasing = FlxG.save.data.antialiasing;
- bgEscalator.scrollFactor.set(0.3, 0.3);
- bgEscalator.active = false;
- bgEscalator.setGraphicSize(Std.int(bgEscalator.width * 0.9));
- bgEscalator.updateHitbox();
- add(bgEscalator);
-
- var tree:FlxSprite = new FlxSprite(370, -250).loadGraphic(Paths.image('christmas/christmasTree', 'week5'));
- tree.antialiasing = FlxG.save.data.antialiasing;
- tree.scrollFactor.set(0.40, 0.40);
- add(tree);
-
- bottomBoppers = new FlxSprite(-300, 140);
- bottomBoppers.frames = Paths.getSparrowAtlas('christmas/bottomBop', 'week5');
- bottomBoppers.animation.addByPrefix('bop', 'Bottom Level Boppers', 24, false);
- bottomBoppers.antialiasing = FlxG.save.data.antialiasing;
- bottomBoppers.scrollFactor.set(0.9, 0.9);
- bottomBoppers.setGraphicSize(Std.int(bottomBoppers.width * 1));
- bottomBoppers.updateHitbox();
- if (FlxG.save.data.distractions)
- {
- add(bottomBoppers);
- }
-
- var fgSnow:FlxSprite = new FlxSprite(-600, 700).loadGraphic(Paths.image('christmas/fgSnow', 'week5'));
- fgSnow.active = false;
- fgSnow.antialiasing = FlxG.save.data.antialiasing;
- add(fgSnow);
-
- santa = new FlxSprite(-840, 150);
- santa.frames = Paths.getSparrowAtlas('christmas/santa', 'week5');
- santa.animation.addByPrefix('idle', 'santa idle in fear', 24, false);
- santa.antialiasing = FlxG.save.data.antialiasing;
- if (FlxG.save.data.distractions)
- {
- add(santa);
- }
- }
- case 'mallEvil':
- {
- curStage = 'mallEvil';
- var bg:FlxSprite = new FlxSprite(-400, -500).loadGraphic(Paths.image('christmas/evilBG', 'week5'));
- bg.antialiasing = FlxG.save.data.antialiasing;
- bg.scrollFactor.set(0.2, 0.2);
- bg.active = false;
- bg.setGraphicSize(Std.int(bg.width * 0.8));
- bg.updateHitbox();
- add(bg);
-
- var evilTree:FlxSprite = new FlxSprite(300, -300).loadGraphic(Paths.image('christmas/evilTree', 'week5'));
- evilTree.antialiasing = FlxG.save.data.antialiasing;
- evilTree.scrollFactor.set(0.2, 0.2);
- add(evilTree);
-
- var evilSnow:FlxSprite = new FlxSprite(-200, 700).loadGraphic(Paths.image("christmas/evilSnow", 'week5'));
- evilSnow.antialiasing = FlxG.save.data.antialiasing;
- add(evilSnow);
- }
- case 'school':
- {
- curStage = 'school';
-
- // defaultCamZoom = 0.9;
-
- var bgSky = new FlxSprite().loadGraphic(Paths.image('weeb/weebSky', 'week6'));
- bgSky.scrollFactor.set(0.1, 0.1);
- add(bgSky);
-
- var repositionShit = -200;
-
- var bgSchool:FlxSprite = new FlxSprite(repositionShit, 0).loadGraphic(Paths.image('weeb/weebSchool', 'week6'));
- bgSchool.scrollFactor.set(0.6, 0.90);
- add(bgSchool);
-
- var bgStreet:FlxSprite = new FlxSprite(repositionShit).loadGraphic(Paths.image('weeb/weebStreet', 'week6'));
- bgStreet.scrollFactor.set(0.95, 0.95);
- add(bgStreet);
-
- var fgTrees:FlxSprite = new FlxSprite(repositionShit + 170, 130).loadGraphic(Paths.image('weeb/weebTreesBack', 'week6'));
- fgTrees.scrollFactor.set(0.9, 0.9);
- add(fgTrees);
-
- var bgTrees:FlxSprite = new FlxSprite(repositionShit - 380, -800);
- var treetex = Paths.getPackerAtlas('weeb/weebTrees', 'week6');
- bgTrees.frames = treetex;
- bgTrees.animation.add('treeLoop', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], 12);
- bgTrees.animation.play('treeLoop');
- bgTrees.scrollFactor.set(0.85, 0.85);
- add(bgTrees);
-
- var treeLeaves:FlxSprite = new FlxSprite(repositionShit, -40);
- treeLeaves.frames = Paths.getSparrowAtlas('weeb/petals', 'week6');
- treeLeaves.animation.addByPrefix('leaves', 'PETALS ALL', 24, true);
- treeLeaves.animation.play('leaves');
- treeLeaves.scrollFactor.set(0.85, 0.85);
- add(treeLeaves);
-
- var widShit = Std.int(bgSky.width * 6);
-
- bgSky.setGraphicSize(widShit);
- bgSchool.setGraphicSize(widShit);
- bgStreet.setGraphicSize(widShit);
- bgTrees.setGraphicSize(Std.int(widShit * 1.4));
- fgTrees.setGraphicSize(Std.int(widShit * 0.8));
- treeLeaves.setGraphicSize(widShit);
-
- fgTrees.updateHitbox();
- bgSky.updateHitbox();
- bgSchool.updateHitbox();
- bgStreet.updateHitbox();
- bgTrees.updateHitbox();
- treeLeaves.updateHitbox();
-
- bgGirls = new BackgroundGirls(-100, 190);
- bgGirls.scrollFactor.set(0.9, 0.9);
-
- if (songLowercase == 'roses')
- {
- if (FlxG.save.data.distractions)
- {
- bgGirls.getScared();
- }
- }
-
- bgGirls.setGraphicSize(Std.int(bgGirls.width * daPixelZoom));
- bgGirls.updateHitbox();
- if (FlxG.save.data.distractions)
- {
- add(bgGirls);
- }
- }
- case 'schoolEvil':
- {
- curStage = 'schoolEvil';
-
- if (!PlayStateChangeables.Optimize)
- {
- var waveEffectBG = new FlxWaveEffect(FlxWaveMode.ALL, 2, -1, 3, 2);
- var waveEffectFG = new FlxWaveEffect(FlxWaveMode.ALL, 2, -1, 5, 2);
- }
+ if (isStoryMode)
+ songMultiplier = 1;
- var posX = 400;
- var posY = 200;
-
- var bg:FlxSprite = new FlxSprite(posX, posY);
- bg.frames = Paths.getSparrowAtlas('weeb/animatedEvilSchool', 'week6');
- bg.animation.addByPrefix('idle', 'background 2', 24);
- bg.animation.play('idle');
- bg.scrollFactor.set(0.8, 0.9);
- bg.scale.set(6, 6);
- add(bg);
-
- /*
- var bg:FlxSprite = new FlxSprite(posX, posY).loadGraphic(Paths.image('weeb/evilSchoolBG'));
- bg.scale.set(6, 6);
- // bg.setGraphicSize(Std.int(bg.width * 6));
- // bg.updateHitbox();
- add(bg);
- var fg:FlxSprite = new FlxSprite(posX, posY).loadGraphic(Paths.image('weeb/evilSchoolFG'));
- fg.scale.set(6, 6);
- // fg.setGraphicSize(Std.int(fg.width * 6));
- // fg.updateHitbox();
- add(fg);
- wiggleShit.effectType = WiggleEffectType.DREAMY;
- wiggleShit.waveAmplitude = 0.01;
- wiggleShit.waveFrequency = 60;
- wiggleShit.waveSpeed = 0.8;
- */
-
- // bg.shader = wiggleShit.shader;
- // fg.shader = wiggleShit.shader;
-
- /*
- var waveSprite = new FlxEffectSprite(bg, [waveEffectBG]);
- var waveSpriteFG = new FlxEffectSprite(fg, [waveEffectFG]);
- // Using scale since setGraphicSize() doesnt work???
- waveSprite.scale.set(6, 6);
- waveSpriteFG.scale.set(6, 6);
- waveSprite.setPosition(posX, posY);
- waveSpriteFG.setPosition(posX, posY);
- waveSprite.scrollFactor.set(0.7, 0.8);
- waveSpriteFG.scrollFactor.set(0.9, 0.8);
- // waveSprite.setGraphicSize(Std.int(waveSprite.width * 6));
- // waveSprite.updateHitbox();
- // waveSpriteFG.setGraphicSize(Std.int(fg.width * 6));
- // waveSpriteFG.updateHitbox();
- add(waveSprite);
- add(waveSpriteFG);
- */
- }
- default:
- {
- defaultCamZoom = 0.9;
- curStage = 'stage';
- var bg:FlxSprite = new FlxSprite(-600, -200).loadGraphic(Paths.image('stageback'));
- bg.antialiasing = FlxG.save.data.antialiasing;
- bg.scrollFactor.set(0.9, 0.9);
- bg.active = false;
- 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 = FlxG.save.data.antialiasing;
- stageFront.scrollFactor.set(0.9, 0.9);
- stageFront.active = false;
- 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 = FlxG.save.data.antialiasing;
- stageCurtains.scrollFactor.set(1.3, 1.3);
- stageCurtains.active = false;
-
- add(stageCurtains);
- }
- }
- }
// defaults if no gf was found in chart
var gfCheck:String = 'gf';
@@ -886,27 +530,67 @@ class PlayState extends MusicBeatState
gfCheck = SONG.gfVersion;
}
- var curGf:String = '';
- switch (gfCheck)
+ gf = new Character(400, 130, gfCheck);
+
+ if (gf.frames == null)
{
- case 'gf-car':
- curGf = 'gf-car';
- case 'gf-christmas':
- curGf = 'gf-christmas';
- case 'gf-pixel':
- curGf = 'gf-pixel';
- default:
- curGf = 'gf';
+ #if debug
+ FlxG.log.warn(["Couldn't load gf: " + gfCheck + ". Loading default gf"]);
+ #end
+ gf = new Character(770, 450, 'gf');
}
- gf = new Character(400, 130, curGf);
- gf.scrollFactor.set(0.95, 0.95);
+ boyfriend = new Boyfriend(770, 450, SONG.player1);
+
+ if (boyfriend.frames == null)
+ {
+ #if debug
+ FlxG.log.warn(["Couldn't load boyfriend: " + SONG.player1 + ". Loading default boyfriend"]);
+ #end
+ boyfriend = new Boyfriend(770, 450, 'bf');
+ }
dad = new Character(100, 100, SONG.player2);
+ if (dad.frames == null)
+ {
+ #if debug
+ FlxG.log.warn(["Couldn't load opponent: " + SONG.player2 + ". Loading default opponent"]);
+ #end
+ dad = new Character(100, 100, 'dad');
+ }
+
+ if (!PlayStateChangeables.Optimize)
+ {
+ Stage = new Stage(SONG.stage);
+ for (i in Stage.toAdd)
+ {
+ add(i);
+ }
+ for (index => array in Stage.layInFront)
+ {
+ switch (index)
+ {
+ case 0:
+ add(gf);
+ gf.scrollFactor.set(0.95, 0.95);
+ for (bg in array)
+ add(bg);
+ case 1:
+ add(dad);
+ for (bg in array)
+ add(bg);
+ case 2:
+ add(boyfriend);
+ for (bg in array)
+ add(bg);
+ }
+ }
+ }
+
var camPos:FlxPoint = new FlxPoint(dad.getGraphicMidpoint().x, dad.getGraphicMidpoint().y);
- switch (SONG.player2)
+ switch (dad.curCharacter)
{
case 'gf':
dad.setPosition(gf.x, gf.y);
@@ -957,10 +641,8 @@ class PlayState extends MusicBeatState
camPos.set(dad.getGraphicMidpoint().x + 300, dad.getGraphicMidpoint().y);
}
- boyfriend = new Boyfriend(770, 450, SONG.player1);
-
// REPOSITIONING PER STAGE
- switch (curStage)
+ switch (Stage.curStage)
{
case 'limo':
boyfriend.y -= 220;
@@ -968,7 +650,6 @@ class PlayState extends MusicBeatState
if (FlxG.save.data.distractions)
{
resetFastCar();
- add(fastCar);
}
case 'mall':
@@ -989,18 +670,6 @@ class PlayState extends MusicBeatState
gf.y += 300;
}
- if (!PlayStateChangeables.Optimize)
- {
- add(gf);
-
- // Shitty layering but whatev it works LOL
- if (curStage == 'limo')
- add(limo);
-
- add(dad);
- add(boyfriend);
- }
-
if (loadRep)
{
FlxG.watch.addQuick('rep rpesses', repPresses);
@@ -1016,11 +685,16 @@ class PlayState extends MusicBeatState
trace("SF CALC: " + Math.floor((PlayStateChangeables.safeFrames / 60) * 1000));
- var doof:DialogueBox = new DialogueBox(false, dialogue);
- // doof.x += 70;
- // doof.y = FlxG.height * 0.5;
- doof.scrollFactor.set();
- doof.finishThing = startCountdown;
+ var doof = null;
+
+ if (isStoryMode)
+ {
+ doof = new DialogueBox(false, dialogue);
+ // doof.x += 70;
+ // doof.y = FlxG.height * 0.5;
+ doof.scrollFactor.set();
+ doof.finishThing = startCountdown;
+ }
Conductor.songPosition = -5000;
@@ -1030,11 +704,11 @@ class PlayState extends MusicBeatState
if (PlayStateChangeables.useDownscroll)
strumLine.y = FlxG.height - 165;
- strumLineNotes = new FlxTypedGroup();
+ strumLineNotes = new FlxTypedGroup();
add(strumLineNotes);
- playerStrums = new FlxTypedGroup();
- cpuStrums = new FlxTypedGroup();
+ playerStrums = new FlxTypedGroup();
+ cpuStrums = new FlxTypedGroup();
generateStaticArrows(0);
generateStaticArrows(1);
@@ -1048,22 +722,34 @@ class PlayState extends MusicBeatState
generateSong(SONG.song);
- for(i in unspawnNotes)
+ #if cpp
+ // pre lowercasing the song name (startCountdown)
+ var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase();
+ switch (songLowercase)
{
- var dunceNote:Note = i;
- notes.add(dunceNote);
- if (executeModchart)
- {
- if (!dunceNote.isSustainNote)
- dunceNote.cameras = [camNotes];
- else
- dunceNote.cameras = [camSustains];
- }
- else
+ case 'dad-battle':
+ songLowercase = 'dadbattle';
+ case 'philly-nice':
+ songLowercase = 'philly';
+ }
+ if (executeModchart)
+ {
+ luaModchart = ModchartState.createModchartState(isStoryMode);
+ luaModchart.executeState('start', [songLowercase]);
+ }
+ #end
+
+ if (executeModchart)
{
- dunceNote.cameras = [camHUD];
+ new LuaCamera(camGame,"camGame").Register(ModchartState.lua);
+ new LuaCamera(camHUD,"camHUD").Register(ModchartState.lua);
+ new LuaCamera(camSustains,"camSustains").Register(ModchartState.lua);
+ new LuaCamera(camSustains,"camNotes").Register(ModchartState.lua);
+ new LuaCharacter(dad,"dad").Register(ModchartState.lua);
+ new LuaCharacter(gf,"gf").Register(ModchartState.lua);
+ new LuaCharacter(boyfriend,"boyfriend").Register(ModchartState.lua);
}
- }
+ var index = 0;
if (startTime != 0)
{
@@ -1080,22 +766,22 @@ class PlayState extends MusicBeatState
{
if (dunceNote.mustPress)
dunceNote.y = (playerStrums.members[Math.floor(Math.abs(dunceNote.noteData))].y
- + 0.45 * (startTime - dunceNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed,
+ * (startTime - dunceNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed,
2)) - dunceNote.noteYOff;
else
dunceNote.y = (strumLineNotes.members[Math.floor(Math.abs(dunceNote.noteData))].y
- + 0.45 * (startTime - dunceNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed,
+ * (startTime - dunceNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed,
2)) - dunceNote.noteYOff;
}
else
{
if (dunceNote.mustPress)
dunceNote.y = (playerStrums.members[Math.floor(Math.abs(dunceNote.noteData))].y
- - 0.45 * (startTime - dunceNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed,
+ * (startTime - dunceNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed,
2)) + dunceNote.noteYOff;
else
dunceNote.y = (strumLineNotes.members[Math.floor(Math.abs(dunceNote.noteData))].y
- - 0.45 * (startTime - dunceNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed,
+ * (startTime - dunceNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed,
2)) + dunceNote.noteYOff;
}
}
@@ -1123,7 +809,7 @@ class PlayState extends MusicBeatState
FlxG.camera.follow(camFollow, LOCKON, 0.04 * (30 / (cast(Lib.current.getChildAt(0), Main)).getFPS()));
// FlxG.camera.setScrollBounds(0, FlxG.width, 0, FlxG.height);
- FlxG.camera.zoom = defaultCamZoom;
+ FlxG.camera.zoom = Stage.camZoom;
FlxG.camera.focusOn(camFollow.getPosition());
FlxG.worldBounds.set(0, 0, FlxG.width, FlxG.height);
@@ -1164,8 +850,29 @@ class PlayState extends MusicBeatState
healthBar = new FlxBar(healthBarBG.x + 4, healthBarBG.y + 4, RIGHT_TO_LEFT, Std.int(healthBarBG.width - 8), Std.int(healthBarBG.height - 8), this,
'health', 0, 2);
healthBar.scrollFactor.set();
- healthBar.createFilledBar(0xFFFF0000, 0xFF66FF33);
- // healthBar
+ if(FlxG.save.data.colour)
+ {
+ switch (SONG.player2)
+ {
+ case 'gf':
+ healthBar.createFilledBar(0xFFFF0000, 0xFF0097C4);
+ case 'dad' | 'mom-car' | 'parents-christmas':
+ healthBar.createFilledBar(0xFF5A07F5, 0xFF0097C4);
+ case 'spooky':
+ healthBar.createFilledBar(0xFFF57E07, 0xFF0097C4);
+ case 'monster-christmas' | 'monster':
+ healthBar.createFilledBar(0xFFF5DD07, 0xFF0097C4);
+ case 'pico':
+ healthBar.createFilledBar(0xFF52B514, 0xFF0097C4);
+ case 'senpai' | 'senpai-angry':
+ healthBar.createFilledBar(0xFFF76D6D, 0xFF0097C4);
+ case 'spirit':
+ healthBar.createFilledBar(0xFFAD0505, 0xFF0097C4);
+ }
+ }
+ else
+ healthBar.createFilledBar(0xFFFF0000, 0xFF66FF33);
+ // healthBar
add(healthBar);
// Add Kade Engine watermark
@@ -1214,11 +921,11 @@ class PlayState extends MusicBeatState
if (PlayStateChangeables.botPlay && !loadRep)
add(botPlayState);
- iconP1 = new HealthIcon(SONG.player1, true);
+ iconP1 = new HealthIcon(boyfriend.curCharacter, true);
iconP1.y = healthBar.y - (iconP1.height / 2);
add(iconP1);
- iconP2 = new HealthIcon(SONG.player2, false);
+ iconP2 = new HealthIcon(dad.curCharacter, false);
iconP2.y = healthBar.y - (iconP2.height / 2);
add(iconP2);
@@ -1229,7 +936,8 @@ class PlayState extends MusicBeatState
iconP1.cameras = [camHUD];
iconP2.cameras = [camHUD];
scoreTxt.cameras = [camHUD];
- doof.cameras = [camHUD];
+ if (isStoryMode)
+ doof.cameras = [camHUD];
if (FlxG.save.data.songPosition)
{
songPosBG.cameras = [camHUD];
@@ -1267,11 +975,11 @@ class PlayState extends MusicBeatState
FlxG.camera.focusOn(camFollow.getPosition());
FlxG.camera.zoom = 1.5;
- new FlxTimer().start(0.8, function(tmr:FlxTimer)
+ new FlxTimer().start(1, function(tmr:FlxTimer)
{
camHUD.visible = true;
remove(blackScreen);
- FlxTween.tween(FlxG.camera, {zoom: defaultCamZoom}, 2.5, {
+ FlxTween.tween(FlxG.camera, {zoom: Stage.camZoom}, 2.5, {
ease: FlxEase.quadInOut,
onComplete: function(twn:FlxTween)
{
@@ -1288,12 +996,16 @@ class PlayState extends MusicBeatState
case 'thorns':
schoolIntro(doof);
default:
- startCountdown();
+ new FlxTimer().start(1, function(timer) {
+ startCountdown();
+ });
}
}
else
{
- startCountdown();
+ new FlxTimer().start(1, function(timer) {
+ startCountdown();
+ });
}
if (!loadRep)
@@ -1391,7 +1103,6 @@ class PlayState extends MusicBeatState
var startTimer:FlxTimer;
var perfectMode:Bool = false;
-
var luaWiggles:Array = [];
#if cpp
@@ -1408,23 +1119,6 @@ class PlayState extends MusicBeatState
- #if cpp
- // pre lowercasing the song name (startCountdown)
- var songLowercase = StringTools.replace(PlayState.SONG.song, " ", "-").toLowerCase();
- switch (songLowercase)
- {
- case 'dad-battle':
- songLowercase = 'dadbattle';
- case 'philly-nice':
- songLowercase = 'philly';
- }
- if (executeModchart)
- {
- luaModchart = ModchartState.createModchartState();
- luaModchart.executeState('start', [songLowercase]);
- }
- #end
-
talking = false;
startedCountdown = true;
Conductor.songPosition = 0;
@@ -1516,10 +1210,9 @@ class PlayState extends MusicBeatState
}
swagCounter += 1;
- // generateSong('fresh');
}, 5);
}
-
+
var previousFrameTime:Int = 0;
var lastReportedPlayheadPosition:Int = 0;
var songTime:Float = 0;
@@ -1539,7 +1232,7 @@ class PlayState extends MusicBeatState
private function releaseInput(evt:KeyboardEvent):Void // handles releases
{
@:privateAccess
- var key = FlxKey.toStringMap.get(Keyboard.__convertKeyCode(evt.keyCode));
+ var key = FlxKey.toStringMap.get(evt.keyCode);
var binds:Array = [
FlxG.save.data.leftBind,
@@ -1588,7 +1281,7 @@ class PlayState extends MusicBeatState
// this makes it work for special characters
@:privateAccess
- var key = FlxKey.toStringMap.get(Keyboard.__convertKeyCode(evt.keyCode));
+ var key = FlxKey.toStringMap.get(evt.keyCode);
var binds:Array = [
FlxG.save.data.leftBind,
@@ -1636,6 +1329,8 @@ class PlayState extends MusicBeatState
if (i.noteData == data)
dataNotes.push(i);
+ trace("notes able to hit for " + key.toString() + " " + dataNotes.length);
+
if (dataNotes.length != 0)
{
var coolNote = null;
@@ -1661,9 +1356,9 @@ class PlayState extends MusicBeatState
var note = dataNotes[i];
- if (!note.isSustainNote && (note.strumTime - coolNote.strumTime) < 2)
+ if (!note.isSustainNote && (note.strumTime / songMultiplier - coolNote.strumTime / songMultiplier) < 2)
{
- trace('found a stacked/really close note ' + (note.strumTime - coolNote.strumTime));
+ trace('found a stacked/really close note ' + (note.strumTime / songMultiplier - coolNote.strumTime / songMultiplier));
// just fuckin remove it since it's a stacked note and shouldn't be there
note.kill();
notes.remove(note, true);
@@ -1673,10 +1368,10 @@ class PlayState extends MusicBeatState
}
goodNoteHit(coolNote);
- var noteDiff:Float = -(coolNote.strumTime - Conductor.songPosition);
+ var noteDiff:Float = -(coolNote.strumTime / songMultiplier - Conductor.songPosition / songMultiplier);
ana.hit = true;
- ana.hitJudge = Ratings.CalculateRating(noteDiff, Math.floor((PlayStateChangeables.safeFrames / 60) * 1000));
- ana.nearestNote = [coolNote.strumTime, coolNote.noteData, coolNote.sustainLength];
+ ana.hitJudge = Ratings.judgeNote(coolNote);
+ ana.nearestNote = [coolNote.strumTime / songMultiplier, coolNote.noteData, coolNote.sustainLength];
}
else if (!FlxG.save.data.ghost && songStarted)
{
@@ -1690,6 +1385,12 @@ class PlayState extends MusicBeatState
var songStarted = false;
+ public var doAnything = false;
+
+
+ public static var songMultiplier = 1.0;
+ public var previousRate = songMultiplier;
+
function startSong():Void
{
startingSong = false;
@@ -1700,6 +1401,7 @@ class PlayState extends MusicBeatState
FlxG.sound.music.play();
vocals.play();
+
// Song check real quick
switch (curSong)
{
@@ -1712,6 +1414,9 @@ class PlayState extends MusicBeatState
if (useVideo)
GlobalVideo.get().resume();
+ if (executeModchart)
+ luaModchart.executeState("songStart",[null]);
+
#if windows
// Updating Discord Rich Presence (with Time Left)
DiscordClient.changePresence(detailsText
@@ -1730,10 +1435,46 @@ class PlayState extends MusicBeatState
#end
FlxG.sound.music.time = startTime;
- vocals.time = startTime;
+ if (vocals != null)
+ vocals.time = startTime;
Conductor.songPosition = startTime;
startTime = 0;
+
+
+ /*@:privateAccess
+ {
+ var aux = AL.createAux();
+ var fx = AL.createEffect();
+ AL.effectf(fx,AL.PITCH,songMultiplier);
+ AL.auxi(aux, AL.EFFECTSLOT_EFFECT, fx);
+ var instSource = FlxG.sound.music._channel.__source;
+
+ var backend:lime._internal.backend.native.NativeAudioSource = instSource.__backend;
+
+ AL.source3i(backend.handle, AL.AUXILIARY_SEND_FILTER, aux, 1, AL.FILTER_NULL);
+ if (vocals != null)
+ {
+ var vocalSource = vocals._channel.__source;
+
+ backend = vocalSource.__backend;
+ AL.source3i(backend.handle, AL.AUXILIARY_SEND_FILTER, aux, 1, AL.FILTER_NULL);
+ }
+
+ trace("pitched to " + songMultiplier);
+ }*/
+
+ #if cpp
+ @:privateAccess
+ {
+ lime.media.openal.AL.sourcef(FlxG.sound.music._channel.__source.__backend.handle, lime.media.openal.AL.PITCH, songMultiplier);
+ if (vocals.playing)
+ lime.media.openal.AL.sourcef(vocals._channel.__source.__backend.handle, lime.media.openal.AL.PITCH, songMultiplier);
+
+ }
+ trace("pitched inst and vocals to " + songMultiplier);
+ #end
+
for(i in 0...unspawnNotes.length)
if (unspawnNotes[i].strumTime < startTime)
unspawnNotes.remove(unspawnNotes[i]);
@@ -1778,6 +1519,7 @@ class PlayState extends MusicBeatState
FlxG.sound.playMusic(sound);
}
else
+
FlxG.sound.playMusic(Paths.inst(PlayState.SONG.song), 1, false);
#else
FlxG.sound.playMusic(Paths.inst(PlayState.SONG.song), 1, false);
@@ -1786,9 +1528,19 @@ class PlayState extends MusicBeatState
FlxG.sound.music.onComplete = endSong;
FlxG.sound.music.pause();
+
+ if (SONG.needsVoices)
+ FlxG.sound.cache(Paths.voices(PlayState.SONG.song));
+ if (!PlayState.isSM)
+ FlxG.sound.cache(Paths.inst(PlayState.SONG.song));
+
+
// Song duration in a float, useful for the time left feature
- songLength = FlxG.sound.music.length;
+ songLength = FlxG.sound.music.length / 1000;
+
+ Conductor.crochet = ((60 / (SONG.bpm) * 1000)) / songMultiplier;
+ Conductor.stepCrochet = Conductor.crochet / 4;
if (FlxG.save.data.songPosition)
{
@@ -1806,8 +1558,7 @@ class PlayState extends MusicBeatState
songPosBar = new FlxBar(songPosBG.x
+ 4, songPosBG.y
+ 4, LEFT_TO_RIGHT, Std.int(songPosBG.width - 8), Std.int(songPosBG.height - 8), this,
- 'songPositionBar', 0, songLength
- - 1000);
+ 'songPositionBar', 0, 100);
songPosBar.numDivisions = 1000;
songPosBar.scrollFactor.set();
songPosBar.createFilledBar(FlxColor.GRAY, FlxColor.LIME);
@@ -1883,17 +1634,18 @@ class PlayState extends MusicBeatState
for (songNotes in section.sectionNotes)
{
- var daStrumTime:Float = songNotes[0] + FlxG.save.data.offset + songOffset;
+ var daStrumTime:Float = songNotes[0] - FlxG.save.data.offset - songOffset;
if (daStrumTime < 0)
daStrumTime = 0;
var daNoteData:Int = Std.int(songNotes[1] % 4);
- var gottaHitNote:Bool = section.mustHitSection;
+ var gottaHitNote:Bool = true;
- if (songNotes[1] > 3)
- {
- gottaHitNote = !section.mustHitSection;
- }
+ if (songNotes[1] > 3 && section.mustHitSection)
+ gottaHitNote = false;
+ else if (songNotes[1] < 4 && !section.mustHitSection)
+ gottaHitNote = false;
+
var oldNote:Note;
if (unspawnNotes.length > 0)
@@ -1901,12 +1653,12 @@ class PlayState extends MusicBeatState
else
oldNote = null;
- var swagNote:Note = new Note(daStrumTime, daNoteData, oldNote);
+ var swagNote:Note = new Note(daStrumTime, daNoteData, oldNote,false,false,false,songNotes[4]);
if (!gottaHitNote && PlayStateChangeables.Optimize)
continue;
- swagNote.sustainLength = songNotes[2];
+ swagNote.sustainLength = TimingStruct.getTimeFromBeat((TimingStruct.getBeatFromTime(songNotes[2])));
swagNote.scrollFactor.set(0, 0);
var susLength:Float = swagNote.sustainLength;
@@ -1961,6 +1713,7 @@ class PlayState extends MusicBeatState
generatedMusic = true;
}
+
function sortByShit(Obj1:Note, Obj2:Note):Int
{
return FlxSort.byValues(FlxSort.ASCENDING, Obj1.strumTime, Obj2.strumTime);
@@ -1971,7 +1724,7 @@ class PlayState extends MusicBeatState
for (i in 0...4)
{
// FlxG.log.add(i);
- var babyArrow:FlxSprite = new FlxSprite(0, strumLine.y);
+ var babyArrow:StaticArrow = new StaticArrow(0, strumLine.y);
// defaults if no noteStyle was found in chart
var noteTypeCheck:String = 'normal';
@@ -2005,28 +1758,14 @@ class PlayState extends MusicBeatState
babyArrow.updateHitbox();
babyArrow.antialiasing = false;
- switch (Math.abs(i))
+ babyArrow.x += Note.swagWidth * i;
+ babyArrow.animation.add('static', [i]);
+ babyArrow.animation.add('pressed', [4 + i, 8 + i], 12, false);
+ babyArrow.animation.add('confirm', [12 + i, 16 + i], 24, false);
+
+ for (j in 0...4)
{
- case 2:
- babyArrow.x += Note.swagWidth * 2;
- babyArrow.animation.add('static', [2]);
- babyArrow.animation.add('pressed', [6, 10], 12, false);
- babyArrow.animation.add('confirm', [14, 18], 12, false);
- case 3:
- babyArrow.x += Note.swagWidth * 3;
- babyArrow.animation.add('static', [3]);
- babyArrow.animation.add('pressed', [7, 11], 12, false);
- babyArrow.animation.add('confirm', [15, 19], 24, false);
- case 1:
- babyArrow.x += Note.swagWidth * 1;
- babyArrow.animation.add('static', [1]);
- babyArrow.animation.add('pressed', [5, 9], 12, false);
- babyArrow.animation.add('confirm', [13, 17], 24, false);
- case 0:
- babyArrow.x += Note.swagWidth * 0;
- babyArrow.animation.add('static', [0]);
- babyArrow.animation.add('pressed', [4, 8], 12, false);
- babyArrow.animation.add('confirm', [12, 16], 24, false);
+ babyArrow.animation.add('dirCon' + j, [12 + j, 16 + j], 24, false);
}
default:
@@ -2034,6 +1773,7 @@ class PlayState extends MusicBeatState
for (j in 0...4)
{
babyArrow.animation.addByPrefix(dataColor[j], 'arrow' + dataSuffix[j]);
+ babyArrow.animation.addByPrefix('dirCon' + j, dataSuffix[j].toLowerCase() + ' confirm', 24, false);
}
var lowerDir:String = dataSuffix[i].toLowerCase();
@@ -2069,7 +1809,7 @@ class PlayState extends MusicBeatState
playerStrums.add(babyArrow);
}
- babyArrow.animation.play('static');
+ babyArrow.playAnim('static');
babyArrow.x += 50;
babyArrow.x += ((FlxG.width / 2) * player);
@@ -2116,7 +1856,7 @@ class PlayState extends MusicBeatState
+ storyDifficultyText
+ ") "
+ Ratings.GenerateLetterRank(accuracy),
- "Acc: "
+ "\nAcc: "
+ HelperFunctions.truncateFloat(accuracy, 2)
+ "% | Score: "
+ songScore
@@ -2178,9 +1918,17 @@ class PlayState extends MusicBeatState
FlxG.sound.music.play();
Conductor.songPosition = FlxG.sound.music.time;
- vocals.time = Conductor.songPosition;
+ vocals.time = FlxG.sound.music.time;
vocals.play();
+ @:privateAccess
+ {
+ lime.media.openal.AL.sourcef(FlxG.sound.music._channel.__source.__backend.handle, lime.media.openal.AL.PITCH, songMultiplier);
+ if (vocals.playing)
+ lime.media.openal.AL.sourcef(vocals._channel.__source.__backend.handle, lime.media.openal.AL.PITCH, songMultiplier);
+
+ }
+
#if windows
DiscordClient.changePresence(detailsText
+ " "
@@ -2215,64 +1963,151 @@ class PlayState extends MusicBeatState
public var pastScrollChanges:Array = [];
+
+ var currentLuaIndex = 0;
+
override public function update(elapsed:Float)
{
#if !debug
perfectMode = false;
#end
- if (generatedMusic)
+
+ if (unspawnNotes[0] != null)
{
- for(i in notes)
+
+ if (unspawnNotes[0].strumTime - Conductor.songPosition < 14000 * songMultiplier)
{
- var diff = i.strumTime - Conductor.songPosition;
- if (diff < 2650 && diff >= -2650)
+ var dunceNote:Note = unspawnNotes[0];
+ notes.add(dunceNote);
+
+ if (executeModchart)
{
- i.active = true;
- i.visible = true;
+ new LuaNote(dunceNote,currentLuaIndex);
+ dunceNote.luaID = currentLuaIndex;
+ }
+
+ if (executeModchart)
+ {
+ if (!dunceNote.isSustainNote)
+ dunceNote.cameras = [camNotes];
+ else
+ dunceNote.cameras = [camSustains];
}
else
{
- i.active = false;
- i.visible = false;
+ dunceNote.cameras = [camHUD];
}
+
+ var index:Int = unspawnNotes.indexOf(dunceNote);
+ unspawnNotes.splice(index, 1);
+ currentLuaIndex++;
}
}
-
- var timingSeg = TimingStruct.getTimingAtTimestamp(Conductor.songPosition);
-
- if (timingSeg != null)
+ #if cpp
+ if (FlxG.sound.music.playing)
+ @:privateAccess
{
-
- var timingSegBpm = timingSeg.bpm;
-
- if (timingSegBpm != Conductor.bpm)
- {
- trace("BPM CHANGE to " + timingSegBpm);
- Conductor.changeBPM(timingSegBpm, false);
- }
-
- }
+ lime.media.openal.AL.sourcef(FlxG.sound.music._channel.__source.__backend.handle, lime.media.openal.AL.PITCH, songMultiplier);
+ if (vocals.playing)
+ lime.media.openal.AL.sourcef(vocals._channel.__source.__backend.handle, lime.media.openal.AL.PITCH, songMultiplier);
- var newScroll = PlayStateChangeables.scrollSpeed;
+ }
+ #end
- for(i in SONG.eventObjects)
- {
- switch(i.type)
+ if (generatedMusic)
{
- case "Scroll Speed Change":
- if (i.position <= curDecimalBeat && !pastScrollChanges.contains(i))
+ if (songStarted && !endingSong)
+ {
+ // Song ends abruptly on slow rate even with second condition being deleted,
+ // and if it's deleted on songs like cocoa then it would end without finishing instrumental fully,
+ // so no reason to delete it at all
+ if (notes.length == 0 && FlxG.sound.music.length - Conductor.songPosition <= 100)
{
- pastScrollChanges.push(i);
- trace("SCROLL SPEED CHANGE to " + i.value);
- newScroll = i.value;
+ endSong();
}
+ }
}
- }
- PlayStateChangeables.scrollSpeed = newScroll;
+
+ if (updateFrame == 4)
+ {
+ TimingStruct.clearTimings();
+
+ var currentIndex = 0;
+ for (i in SONG.eventObjects)
+ {
+ if (i.type == "BPM Change")
+ {
+ var beat:Float = i.position;
+
+ var endBeat:Float = Math.POSITIVE_INFINITY;
+
+ var bpm = i.value;
+
+ TimingStruct.addTiming(beat,bpm,endBeat, 0); // offset in this case = start time since we don't have a offset
+
+ if (currentIndex != 0)
+ {
+ var data = TimingStruct.AllTimings[currentIndex - 1];
+ data.endBeat = beat;
+ data.length = (data.endBeat - data.startBeat) / (data.bpm / 60);
+ var step = ((60 / data.bpm) * 1000) / 4;
+ TimingStruct.AllTimings[currentIndex].startStep = Math.floor(((data.endBeat / (data.bpm / 60)) * 1000) / step);
+ TimingStruct.AllTimings[currentIndex].startTime = data.startTime + data.length;
+ }
+
+ currentIndex++;
+ }
+ }
+
+ updateFrame++;
+ }
+ else if (updateFrame != 5)
+ updateFrame++;
+
+
+ if (FlxG.sound.music.playing)
+ {
+
+ var timingSeg = TimingStruct.getTimingAtBeat(curDecimalBeat);
+
+ if (timingSeg != null)
+ {
+
+ var timingSegBpm = timingSeg.bpm;
+
+ if (timingSegBpm != Conductor.bpm)
+ {
+ trace("BPM CHANGE to " + timingSegBpm);
+ Conductor.changeBPM(timingSegBpm, false);
+ Conductor.crochet = ((60 / (timingSegBpm) * 1000)) / songMultiplier;
+ Conductor.stepCrochet = Conductor.crochet / 4;
+ }
+
+ }
+
+ var newScroll = 1.0;
+
+ for(i in SONG.eventObjects)
+ {
+ switch(i.type)
+ {
+ case "Scroll Speed Change":
+ if (i.position <= curDecimalBeat && !pastScrollChanges.contains(i))
+ {
+ pastScrollChanges.push(i);
+ trace("SCROLL SPEED CHANGE to " + i.value);
+ newScroll = i.value;
+ }
+ }
+ }
+
+ if (newScroll != 0)
+ PlayStateChangeables.scrollSpeed *= newScroll;
+ }
if (PlayStateChangeables.botPlay && FlxG.keys.justPressed.ONE)
camHUD.visible = !camHUD.visible;
@@ -2295,6 +2130,7 @@ class PlayState extends MusicBeatState
luaModchart.setVar('hudZoom', camHUD.zoom);
luaModchart.setVar('curBeat', HelperFunctions.truncateFloat(curDecimalBeat,3));
luaModchart.setVar('cameraZoom', FlxG.camera.zoom);
+
luaModchart.executeState('update', [elapsed]);
for (key => value in luaModchart.luaWiggles)
@@ -2303,6 +2139,8 @@ class PlayState extends MusicBeatState
value.update(elapsed);
}
+ PlayStateChangeables.useDownscroll = luaModchart.getVar("downscroll","bool");
+
/*for (i in 0...strumLineNotes.length) {
var member = strumLineNotes.members[i];
member.x = luaModchart.getVar("strum" + i + "X", "float");
@@ -2375,7 +2213,7 @@ class PlayState extends MusicBeatState
if (FlxG.keys.justPressed.NINE)
iconP1.swapOldIcon();
- switch (curStage)
+ switch (Stage.curStage)
{
case 'philly':
if (trainMoving && !PlayStateChangeables.Optimize)
@@ -2391,9 +2229,6 @@ class PlayState extends MusicBeatState
// phillyCityLights.members[curLight].alpha -= (Conductor.crochet / 1000) * FlxG.elapsed;
}
- super.update(elapsed);
-
- scoreTxt.text = Ratings.CalculateRanking(songScore, songScoreDef, nps, maxNPS, accuracy);
var lengthInPx = scoreTxt.textField.length * scoreTxt.frameHeight; // bad way but does more or less a better job
@@ -2418,6 +2253,7 @@ class PlayState extends MusicBeatState
if (FlxG.keys.justPressed.SEVEN && songStarted)
{
+ songMultiplier = 1;
if (useVideo)
{
GlobalVideo.get().stop();
@@ -2429,9 +2265,6 @@ class PlayState extends MusicBeatState
removedVideo = true;
}
cannotDie = true;
- #if windows
- DiscordClient.changePresence("Chart Editor", null, null, true);
- #end
FlxG.switchState(new ChartingState());
clean();
@@ -2487,7 +2320,46 @@ class PlayState extends MusicBeatState
removedVideo = true;
}
- FlxG.switchState(new AnimationDebug(SONG.player2));
+ FlxG.switchState(new AnimationDebug(dad.curCharacter));
+ clean();
+ FlxG.stage.removeEventListener(KeyboardEvent.KEY_DOWN, handleInput);
+ FlxG.stage.removeEventListener(KeyboardEvent.KEY_UP, releaseInput);
+ #if cpp
+ if (luaModchart != null)
+ {
+ luaModchart.die();
+ luaModchart = null;
+ }
+ #end
+ }
+
+ if (FlxG.keys.justPressed.EIGHT && songStarted)
+ {
+ paused = true;
+ if (useVideo)
+ {
+ GlobalVideo.get().stop();
+ remove(videoSprite);
+ FlxG.stage.window.onFocusOut.remove(focusOut);
+ FlxG.stage.window.onFocusIn.remove(focusIn);
+ removedVideo = true;
+ }
+ new FlxTimer().start(0.3, function(tmr:FlxTimer)
+ {
+ for (bg in Stage.toAdd)
+ {
+ remove(bg);
+ }
+ for (array in Stage.layInFront)
+ {
+ for (bg in array)
+ remove(bg);
+ }
+ remove(boyfriend);
+ remove(dad);
+ remove(gf);
+ });
+ FlxG.switchState(new StagePositioningDebug(SONG.stage, gf.curCharacter, boyfriend.curCharacter, dad.curCharacter));
clean();
FlxG.stage.removeEventListener(KeyboardEvent.KEY_DOWN, handleInput);
FlxG.stage.removeEventListener(KeyboardEvent.KEY_UP, releaseInput);
@@ -2502,7 +2374,7 @@ class PlayState extends MusicBeatState
if (FlxG.keys.justPressed.ZERO)
{
- FlxG.switchState(new AnimationDebug(SONG.player1));
+ FlxG.switchState(new AnimationDebug(boyfriend.curCharacter));
clean();
FlxG.stage.removeEventListener(KeyboardEvent.KEY_DOWN, handleInput);
FlxG.stage.removeEventListener(KeyboardEvent.KEY_UP, releaseInput);
@@ -2515,7 +2387,7 @@ class PlayState extends MusicBeatState
#end
}
- if(FlxG.keys.justPressed.TWO) { //Go 10 seconds into the future, credit: Shadow Mario#9396
+ if(FlxG.keys.justPressed.TWO && songStarted) { //Go 10 seconds into the future, credit: Shadow Mario#9396
if (!usedTimeTravel && Conductor.songPosition + 10000 < FlxG.sound.music.length)
{
usedTimeTravel = true;
@@ -2560,12 +2432,14 @@ class PlayState extends MusicBeatState
else
{
// Conductor.songPosition = FlxG.sound.music.time;
- Conductor.songPosition += FlxG.elapsed * 1000;
+ Conductor.songPosition = FlxG.sound.music.time;
/*@:privateAccess
{
FlxG.sound.music._channel.
}*/
- songPositionBar = Conductor.songPosition;
+ songPositionBar = (Conductor.songPosition - songLength) / 1000;
+
+ currentSection = getSectionByTime(Conductor.songPosition);
if (!paused)
{
@@ -2585,22 +2459,19 @@ class PlayState extends MusicBeatState
// Conductor.lastSongPos = FlxG.sound.music.time;
}
- if (generatedMusic && PlayState.SONG.notes[Std.int(curStep / 16)] != null)
+ if (generatedMusic && currentSection != null)
{
closestNotes = [];
notes.forEachAlive(function(daNote:Note)
{
- if (daNote.canBeHit && daNote.mustPress && !daNote.tooLate && !daNote.wasGoodHit)
+ if (daNote.canBeHit && daNote.mustPress && !daNote.wasGoodHit)
closestNotes.push(daNote);
}); // Collect notes that can be hit
closestNotes.sort((a, b) -> Std.int(a.strumTime - b.strumTime));
- if (closestNotes.length != 0)
- FlxG.watch.addQuick("Current Note",closestNotes[0].strumTime - Conductor.songPosition);
-
// Make sure Girlfriend cheers only for certain songs
if (allowedToHeadbang)
{
@@ -2711,10 +2582,10 @@ class PlayState extends MusicBeatState
#if cpp
if (luaModchart != null)
- luaModchart.setVar("mustHit", PlayState.SONG.notes[Std.int(curStep / 16)].mustHitSection);
+ luaModchart.setVar("mustHit", currentSection.mustHitSection);
#end
- if (camFollow.x != dad.getMidpoint().x + 150 && !PlayState.SONG.notes[Std.int(curStep / 16)].mustHitSection)
+ if (camFollow.x != dad.getMidpoint().x + 150 && !currentSection.mustHitSection)
{
var offsetX = 0;
var offsetY = 0;
@@ -2742,7 +2613,7 @@ class PlayState extends MusicBeatState
}
}
- if (PlayState.SONG.notes[Std.int(curStep / 16)].mustHitSection && camFollow.x != boyfriend.getMidpoint().x - 100)
+ if (currentSection.mustHitSection && camFollow.x != boyfriend.getMidpoint().x - 100)
{
var offsetX = 0;
var offsetY = 0;
@@ -2760,7 +2631,7 @@ class PlayState extends MusicBeatState
luaModchart.executeState('playerOneTurn', []);
#end
- switch (curStage)
+ switch (Stage.curStage)
{
case 'limo':
camFollow.x = boyfriend.getMidpoint().x - 300;
@@ -2776,8 +2647,14 @@ class PlayState extends MusicBeatState
}
}
- if (camZooming)
+ if (camZooming && Conductor.bpm < 320)
{
+
+ if (Conductor.bpm > 320) // if we don't do this it'll be really annoying
+ {
+ camZooming = false;
+ }
+
if (FlxG.save.data.zoom < 0.8)
FlxG.save.data.zoom = 0.8;
@@ -2786,7 +2663,7 @@ class PlayState extends MusicBeatState
if (!executeModchart)
{
- FlxG.camera.zoom = FlxMath.lerp(defaultCamZoom, FlxG.camera.zoom, 0.95);
+ FlxG.camera.zoom = FlxMath.lerp(Stage.camZoom, FlxG.camera.zoom, 0.95);
camHUD.zoom = FlxMath.lerp(FlxG.save.data.zoom, camHUD.zoom, 0.95);
camNotes.zoom = camHUD.zoom;
@@ -2794,7 +2671,7 @@ class PlayState extends MusicBeatState
}
else
{
- FlxG.camera.zoom = FlxMath.lerp(defaultCamZoom, FlxG.camera.zoom, 0.95);
+ FlxG.camera.zoom = FlxMath.lerp(Stage.camZoom, FlxG.camera.zoom, 0.95);
camHUD.zoom = FlxMath.lerp(1, camHUD.zoom, 0.95);
camNotes.zoom = camHUD.zoom;
@@ -2803,8 +2680,6 @@ class PlayState extends MusicBeatState
}
FlxG.watch.addQuick("curBPM", Conductor.bpm);
- FlxG.watch.addQuick("Closest Note", (unspawnNotes.length != 0 ? unspawnNotes[0].strumTime - Conductor.songPosition : "No note"));
-
FlxG.watch.addQuick("beatShit", curBeat);
FlxG.watch.addQuick("stepShit", curStep);
@@ -2851,7 +2726,14 @@ class PlayState extends MusicBeatState
vocals.stop();
FlxG.sound.music.stop();
- openSubState(new GameOverSubstate(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y));
+ if (FlxG.save.data.InstantRespawn)
+ {
+ FlxG.switchState(new PlayState());
+ }
+ else
+ {
+ openSubState(new GameOverSubstate(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y));
+ }
#if windows
// Game Over doesn't get his own variable because it's only used here
@@ -2868,7 +2750,7 @@ class PlayState extends MusicBeatState
+ " | Misses: "
+ misses, iconRPC);
#end
-
+ // God i love futabu!! so fucking much (From: McChomk)
// FlxG.switchState(new GameOverState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y));
}
else
@@ -2886,8 +2768,15 @@ class PlayState extends MusicBeatState
vocals.stop();
FlxG.sound.music.stop();
-
- openSubState(new GameOverSubstate(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y));
+
+ if (FlxG.save.data.InstantRespawn)
+ {
+ FlxG.switchState(new PlayState());
+ }
+ else
+ {
+ openSubState(new GameOverSubstate(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y));
+ }
#if windows
// Game Over doesn't get his own variable because it's only used here
@@ -2918,41 +2807,34 @@ class PlayState extends MusicBeatState
{
// instead of doing stupid y > FlxG.height
// we be men and actually calculate the time :)
- if (daNote.tooLate)
- {
- daNote.active = false;
- daNote.visible = false;
- }
- else
- {
- daNote.visible = true;
- daNote.active = true;
- }
if (!daNote.modifiedByLua)
{
if (PlayStateChangeables.useDownscroll)
{
+
if (daNote.mustPress)
+ {
daNote.y = (playerStrums.members[Math.floor(Math.abs(daNote.noteData))].y
- + 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed,
- 2)) - daNote.noteYOff;
+ + 0.45 * ((Conductor.songPosition - daNote.strumTime) / songMultiplier) *
+ (FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed,
+ 2) ))
+ - daNote.noteYOff;
+ }
else
daNote.y = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y
- + 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed,
- 2)) - daNote.noteYOff;
+ + 0.45 * ((Conductor.songPosition - daNote.strumTime) / songMultiplier) * (FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed,
+ 2))) - daNote.noteYOff;
if (daNote.isSustainNote)
{
// Remember = minus makes notes go up, plus makes them go down
if (daNote.animation.curAnim.name.endsWith('end') && daNote.prevNote != null)
daNote.y += daNote.prevNote.height;
- else
- daNote.y += daNote.height / 2;
// If not in botplay, only clip sustain notes when properly hit, botplay gets to clip it everytime
if (!PlayStateChangeables.botPlay)
{
- if ((!daNote.mustPress || daNote.wasGoodHit || daNote.prevNote.wasGoodHit || holdArray[Math.floor(Math.abs(daNote.noteData))] && !daNote.tooLate)
+ if ((!daNote.mustPress || daNote.wasGoodHit || daNote.prevNote.wasGoodHit || holdArray[Math.floor(Math.abs(daNote.noteData))])
&& daNote.y - daNote.offset.y * daNote.scale.y + daNote.height >= (strumLine.y + Note.swagWidth / 2))
{
// Clip to strumline
@@ -2981,19 +2863,18 @@ class PlayState extends MusicBeatState
{
if (daNote.mustPress)
daNote.y = (playerStrums.members[Math.floor(Math.abs(daNote.noteData))].y
- - 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed,
- 2)) + daNote.noteYOff;
+ - 0.45 * ((Conductor.songPosition - daNote.strumTime) / songMultiplier) * (FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed,
+ 2))) + daNote.noteYOff;
else
daNote.y = (strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].y
- - 0.45 * (Conductor.songPosition - daNote.strumTime) * FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed,
- 2)) + daNote.noteYOff;
+ - 0.45 * ((Conductor.songPosition - daNote.strumTime) / songMultiplier) * (FlxMath.roundDecimal(PlayStateChangeables.scrollSpeed == 1 ? SONG.speed : PlayStateChangeables.scrollSpeed,
+ 2))) + daNote.noteYOff;
if (daNote.isSustainNote)
{
- daNote.y -= daNote.height / 2;
if (!PlayStateChangeables.botPlay)
{
- if ((!daNote.mustPress || daNote.wasGoodHit || daNote.prevNote.wasGoodHit || holdArray[Math.floor(Math.abs(daNote.noteData))] && !daNote.tooLate)
+ if ((!daNote.mustPress || daNote.wasGoodHit || daNote.prevNote.wasGoodHit || holdArray[Math.floor(Math.abs(daNote.noteData))])
&& daNote.y + daNote.offset.y * daNote.scale.y <= (strumLine.y + Note.swagWidth / 2))
{
// Clip to strumline
@@ -3027,9 +2908,9 @@ class PlayState extends MusicBeatState
var altAnim:String = "";
- if (SONG.notes[Math.floor(curStep / 16)] != null)
+ if (currentSection != null)
{
- if (SONG.notes[Math.floor(curStep / 16)].p1AltAnim)
+ if (currentSection.CPUAltAnim)
altAnim = '-alt';
}
@@ -3049,12 +2930,10 @@ class PlayState extends MusicBeatState
if (FlxG.save.data.cpuStrums)
{
- cpuStrums.forEach(function(spr:FlxSprite)
+ cpuStrums.forEach(function(spr:StaticArrow)
{
- if (Math.abs(daNote.noteData) == spr.ID)
- {
- spr.animation.play('confirm', true);
- }
+ pressArrow(spr, spr.ID, daNote);
+ /*
if (spr.animation.curAnim.name == 'confirm' && SONG.noteStyle != 'pixel')
{
spr.centerOffsets();
@@ -3063,6 +2942,7 @@ class PlayState extends MusicBeatState
}
else
spr.centerOffsets();
+ */
});
}
@@ -3084,12 +2964,10 @@ class PlayState extends MusicBeatState
if (FlxG.save.data.cpuStrums)
{
- cpuStrums.forEach(function(spr:FlxSprite)
+ cpuStrums.forEach(function(spr:StaticArrow)
{
- if (Math.abs(daNote.noteData) == spr.ID)
- {
- spr.animation.play('confirm', true);
- }
+ pressArrow(spr, spr.ID, daNote);
+ /*
if (spr.animation.curAnim.name == 'confirm' && SONG.noteStyle != 'pixel')
{
spr.centerOffsets();
@@ -3098,6 +2976,7 @@ class PlayState extends MusicBeatState
}
else
spr.centerOffsets();
+ */
});
}
@@ -3123,26 +3002,26 @@ class PlayState extends MusicBeatState
daNote.visible = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].visible;
daNote.x = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].x;
if (!daNote.isSustainNote)
- daNote.modAngle = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].angle;
+ daNote.modAngle = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].modAngle;
if (daNote.sustainActive)
{
if (executeModchart)
daNote.alpha = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].alpha;
}
- daNote.modAngle = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].angle;
+ daNote.modAngle = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].modAngle;
}
else if (!daNote.wasGoodHit && !daNote.modifiedByLua)
{
daNote.visible = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].visible;
daNote.x = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].x;
if (!daNote.isSustainNote)
- daNote.modAngle = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].angle;
+ daNote.modAngle = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].modAngle;
if (daNote.sustainActive)
{
if (executeModchart)
daNote.alpha = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].alpha;
}
- daNote.modAngle = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].angle;
+ daNote.modAngle = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].modAngle;
}
if (daNote.isSustainNote)
@@ -3162,9 +3041,9 @@ class PlayState extends MusicBeatState
notes.remove(daNote, true);
daNote.destroy();
}
- else if ((daNote.mustPress && daNote.tooLate && !PlayStateChangeables.useDownscroll || daNote.mustPress && daNote.tooLate
+ else if ((daNote.mustPress && !PlayStateChangeables.useDownscroll || daNote.mustPress
&& PlayStateChangeables.useDownscroll)
- && daNote.mustPress)
+ && daNote.mustPress && daNote.strumTime / songMultiplier - Conductor.songPosition / songMultiplier < -(166 * Conductor.timeScale) && songStarted)
{
if (daNote.isSustainNote && daNote.wasGoodHit)
{
@@ -3202,7 +3081,7 @@ class PlayState extends MusicBeatState
&& daNote.sustainActive
&& daNote.spotInLine != daNote.parent.children.length)
{
- health -= 0.2; // give a health punishment for failing a LN
+ //health -= 0.05; // give a health punishment for failing a LN
trace("hold fell over at " + daNote.spotInLine);
for (i in daNote.parent.children)
{
@@ -3213,7 +3092,8 @@ class PlayState extends MusicBeatState
misses++;
updateAccuracy();
}
- else
+ else if (!daNote.wasGoodHit
+ && !daNote.isSustainNote)
{
health -= 0.15;
}
@@ -3234,7 +3114,7 @@ class PlayState extends MusicBeatState
noteMiss(daNote.noteData, daNote);
}
- if (daNote.isParent)
+ if (daNote.isParent && daNote.visible)
{
health -= 0.15; // give a health punishment for failing a LN
trace("hold fell over at the start");
@@ -3242,7 +3122,6 @@ class PlayState extends MusicBeatState
{
i.alpha = 0.3;
i.sustainActive = false;
- trace(i.alpha);
}
}
else
@@ -3252,19 +3131,19 @@ class PlayState extends MusicBeatState
&& daNote.sustainActive
&& daNote.spotInLine != daNote.parent.children.length)
{
- health -= 0.25; // give a health punishment for failing a LN
+ //health -= 0.05; // give a health punishment for failing a LN
trace("hold fell over at " + daNote.spotInLine);
for (i in daNote.parent.children)
{
i.alpha = 0.3;
i.sustainActive = false;
- trace(i.alpha);
}
if (daNote.parent.wasGoodHit)
misses++;
updateAccuracy();
}
- else
+ else if (!daNote.wasGoodHit
+ && !daNote.isSustainNote)
{
health -= 0.15;
}
@@ -3281,22 +3160,22 @@ class PlayState extends MusicBeatState
if (FlxG.save.data.cpuStrums)
{
- cpuStrums.forEach(function(spr:FlxSprite)
+ cpuStrums.forEach(function(spr:StaticArrow)
{
if (spr.animation.finished)
{
- spr.animation.play('static');
+ spr.playAnim('static');
spr.centerOffsets();
}
});
if (PlayStateChangeables.botPlay)
{
- playerStrums.forEach(function(spr:FlxSprite)
+ playerStrums.forEach(function(spr:StaticArrow)
{
if (spr.animation.finished)
{
- spr.animation.play('static');
- spr.centerOffsets();
+ spr.playAnim('static');
+ //spr.centerOffsets();
}
});
}
@@ -3309,8 +3188,56 @@ class PlayState extends MusicBeatState
if (FlxG.keys.justPressed.ONE)
endSong();
#end
+
+ super.update(elapsed);
}
+ public function getSectionByTime(ms:Float):SwagSection
+ {
+
+ for (i in SONG.notes)
+ {
+ var start = TimingStruct.getTimeFromBeat((TimingStruct.getBeatFromTime(i.startTime)));
+ var end = TimingStruct.getTimeFromBeat((TimingStruct.getBeatFromTime(i.endTime)));
+
+
+ if (ms >= start && ms < end)
+ {
+ return i;
+ }
+ }
+
+
+ return null;
+ }
+
+ function recalculateAllSectionTimes()
+ {
+
+ trace("RECALCULATING SECTION TIMES");
+
+ for (i in 0...SONG.notes.length) // loops through sections
+ {
+ var section = SONG.notes[i];
+
+ var currentBeat = 4 * i;
+
+ var currentSeg = TimingStruct.getTimingAtBeat(currentBeat);
+
+ if (currentSeg == null)
+ return;
+
+ var start:Float = (currentBeat - currentSeg.startBeat) / ((currentSeg.bpm) / 60);
+
+ section.startTime = (currentSeg.startTime + start) * 1000;
+
+ if (i != 0)
+ SONG.notes[i - 1].endTime = section.startTime;
+ section.endTime = Math.POSITIVE_INFINITY;
+ }
+ }
+
+
function endSong():Void
{
endingSong = true;
@@ -3501,6 +3428,28 @@ class PlayState extends MusicBeatState
var hits:Array = [];
var offsetTest:Float = 0;
+ public function getRatesScore(rate:Float, score:Float):Float
+ {
+ var rateX:Float = 1;
+ var lastScore:Float = score;
+ var pr = rate - 0.05;
+ if (pr < 1.00)
+ pr = 1;
+
+ while(rateX <= pr)
+ {
+ if (rateX > pr)
+ break;
+ lastScore = score + ((lastScore * rateX) * 0.022);
+ rateX += 0.05;
+ }
+
+ var actualScore = Math.round(score + (Math.floor((lastScore * pr)) * 0.022));
+
+ return actualScore;
+ }
+
+
var timeShown = 0;
var currentTimingShown:FlxText = null;
@@ -3561,13 +3510,15 @@ class PlayState extends MusicBeatState
sicks++;
}
+ if (songMultiplier >= 1.05)
+ score = getRatesScore(songMultiplier, score);
+
// trace('Wife accuracy loss: ' + wife + ' | Rating: ' + daRating + ' | Score: ' + score + ' | Weight: ' + (1 - wife));
if (daRating != 'shit' || daRating != 'bad')
{
songScore += Math.round(score);
- songScoreDef += Math.round(ConvertScore.convertScore(noteDiff));
/* if (combo > 60)
daRating = 'sick';
@@ -3602,7 +3553,7 @@ class PlayState extends MusicBeatState
rating.velocity.y -= FlxG.random.int(140, 175);
rating.velocity.x -= FlxG.random.int(0, 10);
- var msTiming = HelperFunctions.truncateFloat(noteDiff, 3);
+ var msTiming = HelperFunctions.truncateFloat(noteDiff / songMultiplier, 3);
if (PlayStateChangeables.botPlay && !loadRep)
msTiming = 0;
@@ -3865,7 +3816,6 @@ class PlayState extends MusicBeatState
{
if (daNote.isSustainNote && daNote.canBeHit && daNote.mustPress && holdArray[daNote.noteData] && daNote.sustainActive)
{
- trace(daNote.sustainActive);
goodNoteHit(daNote);
}
});
@@ -3885,7 +3835,7 @@ class PlayState extends MusicBeatState
notes.forEachAlive(function(daNote:Note)
{
- if (daNote.canBeHit && daNote.mustPress && !daNote.tooLate && !daNote.wasGoodHit && !directionsAccounted[daNote.noteData])
+ if (daNote.canBeHit && daNote.mustPress && !daNote.wasGoodHit && !directionsAccounted[daNote.noteData])
{
if (directionList.contains(daNote.noteData))
{
@@ -3949,7 +3899,7 @@ class PlayState extends MusicBeatState
scoreTxt.color = FlxColor.WHITE;
var noteDiff:Float = -(coolNote.strumTime - Conductor.songPosition);
anas[coolNote.noteData].hit = true;
- anas[coolNote.noteData].hitJudge = Ratings.CalculateRating(noteDiff, Math.floor((PlayStateChangeables.safeFrames / 60) * 1000));
+ anas[coolNote.noteData].hitJudge = Ratings.judgeNote(coolNote);
anas[coolNote.noteData].nearestNote = [coolNote.strumTime, coolNote.noteData, coolNote.sustainLength];
goodNoteHit(coolNote);
}
@@ -3977,9 +3927,9 @@ class PlayState extends MusicBeatState
if (PlayStateChangeables.botPlay)
notes.forEachAlive(function(daNote:Note)
{
- var diff = -(daNote.strumTime - Conductor.songPosition);
+ var diff = -(daNote.strumTime / songMultiplier - Conductor.songPosition / songMultiplier );
- daNote.rating = Ratings.CalculateRating(diff, Math.floor((PlayStateChangeables.safeFrames / 60) * 1000));
+ daNote.rating = Ratings.judgeNote(daNote);
if (daNote.mustPress && daNote.rating == "sick" || (diff > 0 && daNote.mustPress))
{
// Force good note hit regardless if it's too late to hit it or not as a fail safe
@@ -3991,21 +3941,36 @@ class PlayState extends MusicBeatState
if (n != null)
{
goodNoteHit(daNote);
- boyfriend.holdTimer = daNote.sustainLength;
+ boyfriend.holdTimer = 0;
+ if (FlxG.save.data.cpuStrums)
+ {
+ playerStrums.forEach(function(spr:StaticArrow)
+ {
+ pressArrow(spr, spr.ID, daNote);
+ /*
+ if (spr.animation.curAnim.name == 'confirm' && SONG.noteStyle != 'pixel')
+ {
+ spr.centerOffsets();
+ spr.offset.x -= 13;
+ spr.offset.y -= 13;
+ }
+ else
+ spr.centerOffsets();
+ */
+ });
+ }
}
}
else
{
goodNoteHit(daNote);
- boyfriend.holdTimer = daNote.sustainLength;
+ boyfriend.holdTimer = 0;
if (FlxG.save.data.cpuStrums)
{
- playerStrums.forEach(function(spr:FlxSprite)
+ playerStrums.forEach(function(spr:StaticArrow)
{
- if (Math.abs(daNote.noteData) == spr.ID)
- {
- spr.animation.play('confirm', true);
- }
+ pressArrow(spr, spr.ID, daNote);
+ /*
if (spr.animation.curAnim.name == 'confirm' && SONG.noteStyle != 'pixel')
{
spr.centerOffsets();
@@ -4014,6 +3979,7 @@ class PlayState extends MusicBeatState
}
else
spr.centerOffsets();
+ */
});
}
}
@@ -4028,21 +3994,12 @@ class PlayState extends MusicBeatState
if (!PlayStateChangeables.botPlay)
{
- playerStrums.forEach(function(spr:FlxSprite)
+ playerStrums.forEach(function(spr:StaticArrow)
{
- if (keys[spr.ID] && spr.animation.curAnim.name != 'confirm' && spr.animation.curAnim.name != 'pressed')
- spr.animation.play('pressed', false);
+ if (keys[spr.ID] && spr.animation.curAnim.name != 'confirm' && spr.animation.curAnim.name != 'pressed' && !spr.animation.curAnim.name.startsWith('dirCon'))
+ spr.playAnim('pressed', false);
if (!keys[spr.ID])
- spr.animation.play('static', false);
-
- if (spr.animation.curAnim.name == 'confirm' && SONG.noteStyle != 'pixel')
- {
- spr.centerOffsets();
- spr.offset.x -= 13;
- spr.offset.y -= 13;
- }
- else
- spr.centerOffsets();
+ spr.playAnim('static', false);
});
}
}
@@ -4178,7 +4135,7 @@ class PlayState extends MusicBeatState
daNote.strumTime,
0,
direction,
- 166 * Math.floor((PlayState.rep.replay.sf / 60) * 1000) / 166
+ -(166 * Math.floor((PlayState.rep.replay.sf / 60) * 1000) / 166)
]);
saveJudge.push("miss");
}
@@ -4189,7 +4146,7 @@ class PlayState extends MusicBeatState
Conductor.songPosition,
0,
direction,
- 166 * Math.floor((PlayState.rep.replay.sf / 60) * 1000) / 166
+ -(166 * Math.floor((PlayState.rep.replay.sf / 60) * 1000) / 166)
]);
saveJudge.push("miss");
}
@@ -4215,6 +4172,7 @@ class PlayState extends MusicBeatState
// FlxG.log.add('played imss note');
}
+
// Hole switch statement replaced with a single line :)
boyfriend.playAnim('sing' + dataSuffix[direction] + 'miss', true);
@@ -4252,6 +4210,8 @@ class PlayState extends MusicBeatState
totalPlayed += 1;
accuracy = Math.max(0, totalNotesHit / totalPlayed * 100);
accuracyDefault = Math.max(0, totalNotesHitDefault / totalPlayed * 100);
+
+ scoreTxt.text = Ratings.CalculateRanking(songScore, songScoreDef, nps, maxNPS, accuracy);
}
function getKeyPresses(note:Note):Int
@@ -4260,7 +4220,7 @@ class PlayState extends MusicBeatState
notes.forEachAlive(function(daNote:Note)
{
- if (daNote.canBeHit && daNote.mustPress && !daNote.tooLate)
+ if (daNote.canBeHit && daNote.mustPress)
{
possibleNotes.push(daNote);
possibleNotes.sort((a, b) -> Std.int(a.strumTime - b.strumTime));
@@ -4280,7 +4240,7 @@ class PlayState extends MusicBeatState
{
var noteDiff:Float = -(note.strumTime - Conductor.songPosition);
- note.rating = Ratings.CalculateRating(noteDiff, Math.floor((PlayStateChangeables.safeFrames / 60) * 1000));
+ note.rating = Ratings.judgeNote(note);
/* if (loadRep)
{
@@ -4327,7 +4287,8 @@ class PlayState extends MusicBeatState
if (mashing != 0)
mashing = 0;
- var noteDiff:Float = -(note.strumTime - Conductor.songPosition);
+ var noteDiff:Float = -(note.strumTime - Conductor.songPosition );
+
if (loadRep)
{
@@ -4335,7 +4296,7 @@ class PlayState extends MusicBeatState
note.rating = rep.replay.songJudgements[findByTimeIndex(note.strumTime)];
}
else
- note.rating = Ratings.CalculateRating(noteDiff);
+ note.rating = Ratings.judgeNote(note);
if (note.rating == "miss")
return;
@@ -4358,8 +4319,6 @@ class PlayState extends MusicBeatState
popUpScore(note);
combo += 1;
}
- else
- totalNotesHit += 1;
var altAnim:String = "";
if (note.isAlt)
@@ -4386,12 +4345,9 @@ class PlayState extends MusicBeatState
if (!PlayStateChangeables.botPlay)
{
- playerStrums.forEach(function(spr:FlxSprite)
+ playerStrums.forEach(function(spr:StaticArrow)
{
- if (Math.abs(note.noteData) == spr.ID)
- {
- spr.animation.play('confirm', true);
- }
+ pressArrow(spr, spr.ID, note);
});
}
@@ -4405,17 +4361,33 @@ class PlayState extends MusicBeatState
{
note.wasGoodHit = true;
}
-
- updateAccuracy();
+ if (!note.isSustainNote)
+ updateAccuracy();
}
}
+ function pressArrow(spr:StaticArrow, idCheck:Int, daNote:Note)
+ {
+ if (Math.abs(daNote.noteData) == idCheck)
+ {
+ if (!FlxG.save.data.stepMania)
+ {
+ spr.playAnim('confirm', true);
+ }
+ else
+ {
+ spr.playAnim('dirCon' + daNote.originColor, true);
+ spr.localAngle = daNote.originAngle;
+ }
+ }
+ }
var fastCarCanDrive:Bool = true;
function resetFastCar():Void
{
if (FlxG.save.data.distractions)
{
+ var fastCar = Stage.swagBacks['fastCar'];
fastCar.x = -12600;
fastCar.y = FlxG.random.int(140, 250);
fastCar.velocity.x = 0;
@@ -4429,7 +4401,7 @@ class PlayState extends MusicBeatState
{
FlxG.sound.play(Paths.soundRandom('carPass', 0, 1), 0.7);
- fastCar.velocity.x = (FlxG.random.int(170, 220) / FlxG.elapsed) * 3;
+ Stage.swagBacks['fastCar'].velocity.x = (FlxG.random.int(170, 220) / FlxG.elapsed) * 3;
fastCarCanDrive = false;
new FlxTimer().start(2, function(tmr:FlxTimer)
{
@@ -4469,6 +4441,7 @@ class PlayState extends MusicBeatState
if (startedMoving)
{
+ var phillyTrain = Stage.swagBacks['phillyTrain'];
phillyTrain.x -= 400;
if (phillyTrain.x < -2000 && !trainFinishing)
@@ -4491,7 +4464,7 @@ class PlayState extends MusicBeatState
if (FlxG.save.data.distractions)
{
gf.playAnim('hairFall');
- phillyTrain.x = FlxG.width + 200;
+ Stage.swagBacks['phillyTrain'].x = FlxG.width + 200;
trainMoving = false;
// trainSound.stop();
// trainSound.time = 0;
@@ -4504,7 +4477,7 @@ class PlayState extends MusicBeatState
function lightningStrikeShit():Void
{
FlxG.sound.play(Paths.soundRandom('thunder_', 1, 2));
- halloweenBG.animation.play('lightning');
+ Stage.swagBacks['halloweenBG'].animation.play('lightning');
lightningStrikeBeat = curBeat;
lightningOffset = FlxG.random.int(8, 24);
@@ -4523,38 +4496,41 @@ class PlayState extends MusicBeatState
resyncVocals();
}
+ for (step in Stage.slowBacks.keys())
+ {
+ if (step == curStep)
+ {
+ if (Stage.hideLastBG)
+ {
+ for (bg in Stage.swagBacks)
+ {
+ if (!Stage.slowBacks[step].contains(bg))
+ FlxTween.tween(bg, {alpha: 0}, Stage.tweenDuration);
+ }
+ for (bg in Stage.slowBacks[step])
+ {
+ FlxTween.tween(bg, {alpha: 1}, Stage.tweenDuration);
+ }
+ }
+ else
+ {
+ for (bg in Stage.slowBacks[step])
+ bg.visible = !bg.visible;
+ }
+ }
+ }
+
#if cpp
if (executeModchart && luaModchart != null)
{
luaModchart.setVar('curStep', curStep);
luaModchart.executeState('stepHit', [curStep]);
}
- #end
- // yes this updates every step.
- // yes this is bad
- // but i'm doing it to update misses and accuracy
- #if windows
- // Song duration in a float, useful for the time left feature
- songLength = FlxG.sound.music.length;
- // Updating Discord Rich Presence (with Time Left)
- DiscordClient.changePresence(detailsText
- + " "
- + SONG.song
- + " ("
- + storyDifficultyText
- + ") "
- + Ratings.GenerateLetterRank(accuracy),
- "Acc: "
- + HelperFunctions.truncateFloat(accuracy, 2)
- + "% | Score: "
- + songScore
- + " | Misses: "
- + misses, iconRPC, true,
- songLength
- - Conductor.songPosition);
+
#end
+
}
var lightningStrikeBeat:Int = 0;
@@ -4576,9 +4552,9 @@ class PlayState extends MusicBeatState
}
#end
- if (curSong == 'Tutorial' && dad.curCharacter == 'gf' && SONG.notes[Math.floor(curStep / 16)] != null)
+ if (curSong == 'Tutorial' && dad.curCharacter == 'gf' && currentSection != null)
{
- if (SONG.notes[Math.floor(curStep / 16)].mustHitSection)
+ if (currentSection.mustHitSection)
dad.dance();
else
{
@@ -4589,7 +4565,7 @@ class PlayState extends MusicBeatState
}
}
- if (SONG.notes[Math.floor(curStep / 16)] != null)
+ if (currentSection != null)
{
// else
// Conductor.changeBPM(SONG.bpm);
@@ -4597,124 +4573,257 @@ class PlayState extends MusicBeatState
// Dad doesnt interupt his own notes
if ((!dad.animation.curAnim.name.startsWith("sing")) && dad.curCharacter != 'gf')
if ((curBeat % idleBeat == 0 || !idleToBeat) || dad.curCharacter == "spooky")
- dad.dance(idleToBeat, SONG.notes[Math.floor(curStep / 16)].p1AltAnim);
+ dad.dance(idleToBeat, currentSection.CPUAltAnim);
}
// FlxG.log.add('change bpm' + SONG.notes[Std.int(curStep / 16)].changeBPM);
wiggleShit.update(Conductor.crochet);
- if (FlxG.save.data.camzoom)
+ if (FlxG.save.data.camzoom && Conductor.bpm < 340)
{
// HARDCODING FOR MILF ZOOMS!
if (curSong.toLowerCase() == 'milf' && curBeat >= 168 && curBeat < 200 && camZooming && FlxG.camera.zoom < 1.35)
{
- FlxG.camera.zoom += 0.015;
- camHUD.zoom += 0.03;
+ FlxG.camera.zoom += 0.015 / songMultiplier;
+ camHUD.zoom += 0.03 / songMultiplier;
}
if (camZooming && FlxG.camera.zoom < 1.35 && curBeat % 4 == 0)
{
- FlxG.camera.zoom += 0.015;
- camHUD.zoom += 0.03;
+ FlxG.camera.zoom += 0.015 / songMultiplier;
+ camHUD.zoom += 0.03 / songMultiplier;
}
}
-
- iconP1.setGraphicSize(Std.int(iconP1.width + 30));
- iconP2.setGraphicSize(Std.int(iconP2.width + 30));
-
- iconP1.updateHitbox();
- iconP2.updateHitbox();
-
- if (curBeat % gfSpeed == 0)
+ if (Conductor.bpm < 340)
{
- gf.dance();
- }
+ iconP1.setGraphicSize(Std.int(iconP1.width + 30));
+ iconP2.setGraphicSize(Std.int(iconP2.width + 30));
- if (!boyfriend.animation.curAnim.name.startsWith("sing") && (curBeat % idleBeat == 0 || !idleToBeat))
+ iconP1.updateHitbox();
+ iconP2.updateHitbox();
+ }
+ else
{
- boyfriend.playAnim('idle' + ((SONG.notes[Math.floor(curStep / 16)].p2AltAnim && boyfriend.animation.getByName('idle-alt') != null) ? '-alt' : ''), idleToBeat);
+
+ iconP1.setGraphicSize(Std.int(iconP1.width + 4));
+ iconP2.setGraphicSize(Std.int(iconP2.width + 4));
+
+ iconP1.updateHitbox();
+ iconP2.updateHitbox();
}
- /*if (!dad.animation.curAnim.name.startsWith("sing"))
+ if (!endingSong && currentSection != null)
{
- dad.dance();
- }*/
+ if (curBeat % gfSpeed == 0)
+ {
+ gf.dance();
+ }
- if (curBeat % 8 == 7 && curSong == 'Bopeebo')
- {
- boyfriend.playAnim('hey', true);
- }
+ if (!boyfriend.animation.curAnim.name.startsWith("sing") && (curBeat % idleBeat == 0 || !idleToBeat))
+ {
+ boyfriend.playAnim('idle' + ((currentSection.playerAltAnim && boyfriend.animation.getByName('idle-alt') != null) ? '-alt' : ''), idleToBeat);
+ }
- if (curBeat % 16 == 15 && SONG.song == 'Tutorial' && dad.curCharacter == 'gf' && curBeat > 16 && curBeat < 48)
- {
- boyfriend.playAnim('hey', true);
- dad.playAnim('cheer', true);
- }
+ /*if (!dad.animation.curAnim.name.startsWith("sing"))
+ {
+ dad.dance();
+ }*/
- switch (curStage)
- {
- case 'school':
- if (FlxG.save.data.distractions)
- {
- bgGirls.dance();
- }
+ if (curBeat % 8 == 7 && curSong == 'Bopeebo')
+ {
+ boyfriend.playAnim('hey', true);
+ }
- case 'mall':
+ if (curBeat % 16 == 15 && SONG.song == 'Tutorial' && dad.curCharacter == 'gf' && curBeat > 16 && curBeat < 48)
+ {
+ boyfriend.playAnim('hey', true);
+ dad.playAnim('cheer', true);
+ }
+
+ switch (Stage.curStage)
+ {
+ case 'school':
+ if (FlxG.save.data.distractions && Stage.swagBacks['bgGirls'] != null)
+ {
+ Stage.swagBacks['bgGirls'].dance();
+ }
+
+ case 'mall':
+ if (FlxG.save.data.distractions)
+ {
+ for (bg in Stage.animatedBacks)
+ bg.animation.play('idle');
+ }
+
+ case 'limo':
+ if (FlxG.save.data.distractions)
+ {
+ Stage.swagGroup['grpLimoDancers'].forEach(function(dancer:BackgroundDancer)
+ {
+ dancer.dance();
+ });
+
+ if (FlxG.random.bool(10) && fastCarCanDrive)
+ fastCarDrive();
+ }
+ case "philly":
+ if (FlxG.save.data.distractions)
+ {
+ if (!trainMoving)
+ trainCooldown += 1;
+
+ if (curBeat % 4 == 0)
+ {
+ var phillyCityLights = Stage.swagGroup['phillyCityLights'];
+ phillyCityLights.forEach(function(light:FlxSprite)
+ {
+ light.visible = false;
+ });
+
+ curLight = FlxG.random.int(0, phillyCityLights.length - 1);
+
+ phillyCityLights.members[curLight].visible = true;
+ // phillyCityLights.members[curLight].alpha = 1;
+ }
+ }
+
+ if (curBeat % 8 == 4 && FlxG.random.bool(Conductor.bpm > 320 ? 150 : 30) && !trainMoving && trainCooldown > 8)
+ {
+ if (FlxG.save.data.distractions)
+ {
+ trainCooldown = FlxG.random.int(-4, 0);
+ trainStart();
+ }
+ }
+ }
+
+ if (Stage.halloweenLevel && FlxG.random.bool(Conductor.bpm > 320 ? 100 : 10) && curBeat > lightningStrikeBeat + lightningOffset)
+ {
if (FlxG.save.data.distractions)
{
- upperBoppers.animation.play('bop', true);
- bottomBoppers.animation.play('bop', true);
- santa.animation.play('idle', true);
+ lightningStrikeShit();
}
+ }
+ }
+ }
- case 'limo':
- if (FlxG.save.data.distractions)
+ public var cleanedSong:SwagSong;
+
+ function poggers(?cleanTheSong = false)
+ {
+ var notes = [];
+
+ if (cleanTheSong)
+ {
+ cleanedSong = SONG;
+
+ for(section in cleanedSong.notes)
{
- grpLimoDancers.forEach(function(dancer:BackgroundDancer)
+
+ var removed = [];
+
+ for(note in section.sectionNotes)
{
- dancer.dance();
- });
-
- if (FlxG.random.bool(10) && fastCarCanDrive)
- fastCarDrive();
+ // commit suicide
+ var old = note[0];
+ if (note[0] < section.startTime)
+ {
+ notes.push(note);
+ removed.push(note);
+ }
+ if (note[0] > section.endTime)
+ {
+ notes.push(note);
+ removed.push(note);
+ }
+ }
+
+ for(i in removed)
+ {
+ section.sectionNotes.remove(i);
+ }
}
- case "philly":
- if (FlxG.save.data.distractions)
+
+ for(section in cleanedSong.notes)
{
- if (!trainMoving)
- trainCooldown += 1;
-
- if (curBeat % 4 == 0)
+
+ var saveRemove = [];
+
+ for(i in notes)
{
- phillyCityLights.forEach(function(light:FlxSprite)
+ if (i[0] >= section.startTime && i[0] < section.endTime)
{
- light.visible = false;
- });
+ saveRemove.push(i);
+ section.sectionNotes.push(i);
+ }
+ }
+
+ for(i in saveRemove)
+ notes.remove(i);
+ }
+
- curLight = FlxG.random.int(0, phillyCityLights.length - 1);
- phillyCityLights.members[curLight].visible = true;
- // phillyCityLights.members[curLight].alpha = 1;
+ trace("FUCK YOU BITCH FUCKER CUCK SUCK BITCH " + cleanedSong.notes.length);
+
+
+ SONG = cleanedSong;
+ }
+ else
+ {
+
+ for(section in SONG.notes)
+ {
+
+ var removed = [];
+
+ for(note in section.sectionNotes)
+ {
+ // commit suicide
+ var old = note[0];
+ if (note[0] < section.startTime)
+ {
+ notes.push(note);
+ removed.push(note);
+ }
+ if (note[0] > section.endTime)
+ {
+ notes.push(note);
+ removed.push(note);
+ }
+ }
+
+ for(i in removed)
+ {
+ section.sectionNotes.remove(i);
}
}
-
- if (curBeat % 8 == 4 && FlxG.random.bool(30) && !trainMoving && trainCooldown > 8)
+
+ for(section in SONG.notes)
{
- if (FlxG.save.data.distractions)
+
+ var saveRemove = [];
+
+ for(i in notes)
{
- trainCooldown = FlxG.random.int(-4, 0);
- trainStart();
+ if (i[0] >= section.startTime && i[0] < section.endTime)
+ {
+ saveRemove.push(i);
+ section.sectionNotes.push(i);
+ }
}
+
+ for(i in saveRemove)
+ notes.remove(i);
}
- }
+
- if (isHalloween && FlxG.random.bool(10) && curBeat > lightningStrikeBeat + lightningOffset)
- {
- if (FlxG.save.data.distractions)
- {
- lightningStrikeShit();
+
+ trace("FUCK YOU BITCH FUCKER CUCK SUCK BITCH " + cleanedSong.notes.length);
+
+
+ SONG = cleanedSong;
}
}
- }
var curLight:Int = 0;
}
diff --git a/source/Ratings.hx b/source/Ratings.hx
index 495efb932f..92150f50d9 100644
--- a/source/Ratings.hx
+++ b/source/Ratings.hx
@@ -92,45 +92,31 @@ class Ratings
return ranking;
}
- public static function CalculateRating(noteDiff:Float, ?customSafeZone:Float):String // Generate a judgement through some timing shit
- {
-
- var customTimeScale = Conductor.timeScale;
-
- if (customSafeZone != null)
- customTimeScale = customSafeZone / 166;
-
- // trace(customTimeScale + ' vs ' + Conductor.timeScale);
-
- // I HATE THIS IF CONDITION
- // IF LEMON SEES THIS I'M SORRY :(
-
- // trace('Hit Info\nDifference: ' + noteDiff + '\nZone: ' + Conductor.safeZoneOffset * 1.5 + "\nTS: " + customTimeScale + "\nLate: " + 155 * customTimeScale);
-
- var rating = checkRating(noteDiff,customTimeScale);
-
-
- return rating;
- }
+ public static var timingWindows = [166,135,90,45];
- public static function checkRating(ms:Float, ts:Float)
+ public static function judgeNote(note:Note)
{
- var rating = "shit";
- if (ms <= 166 * ts && ms >= 135 * ts)
- rating = "shit";
- if (ms < 135 * ts && ms >= 90 * ts)
- rating = "bad";
- if (ms < 90 * ts && ms >= 45 * ts)
- rating = "good";
- if (ms < 45 * ts && ms >= -45 * ts)
- rating = "sick";
- if (ms > -90 * ts && ms <= -45 * ts)
- rating = "good";
- if (ms > -135 * ts && ms <= -90 * ts)
- rating = "bad";
- if (ms > -166 * ts && ms <= -135 * ts)
- rating = "shit";
- return rating;
+ var diff = Math.abs(note.strumTime - Conductor.songPosition);
+ for(index in 0...timingWindows.length) // based on 4 timing windows, will break with anything else
+ {
+ var time = timingWindows[index];
+ var nextTime = index + 1 > timingWindows.length - 1 ? 0 : timingWindows[index + 1];
+ if (diff < time * PlayState.songMultiplier && diff >= nextTime * PlayState.songMultiplier)
+ {
+ switch(index)
+ {
+ case 0: // shit
+ return "shit";
+ case 1: // bad
+ return "bad";
+ case 2: // good
+ return "good";
+ case 3: // sick
+ return "sick";
+ }
+ }
+ }
+ return "shit";
}
public static function CalculateRanking(score:Int,scoreDef:Int,nps:Int,maxNPS:Int,accuracy:Float):String
@@ -144,4 +130,5 @@ class Ratings
" | Accuracy:" + (PlayStateChangeables.botPlay && !PlayState.loadRep ? "N/A" : HelperFunctions.truncateFloat(accuracy, 2) + " %") + // Accuracy
" | " + GenerateLetterRank(accuracy) : "") : ""); // Letter Rank
}
+
}
diff --git a/source/ResultsScreen.hx b/source/ResultsScreen.hx
index 66b5569197..df7700877f 100644
--- a/source/ResultsScreen.hx
+++ b/source/ResultsScreen.hx
@@ -88,7 +88,7 @@ class ResultsScreen extends FlxSubState
var bads = PlayState.isStoryMode ? PlayState.campaignBads : PlayState.bads;
var shits = PlayState.isStoryMode ? PlayState.campaignShits : PlayState.shits;
- comboText = new FlxText(20,-75,0,'Judgements:\nSicks - ${sicks}\nGoods - ${goods}\nBads - ${bads}\n\nCombo Breaks: ${(PlayState.isStoryMode ? PlayState.campaignMisses : PlayState.misses)}\nHighest Combo: ${PlayState.highestCombo + 1}\nScore: ${PlayState.instance.songScore}\nAccuracy: ${HelperFunctions.truncateFloat(PlayState.instance.accuracy,2)}%\n\n${Ratings.GenerateLetterRank(PlayState.instance.accuracy)}\n\n${!PlayState.loadRep ? "F1 - View replay\nF2 - Replay song" : ""}
+ comboText = new FlxText(20,-75,0,'Judgements:\nSicks - ${sicks}\nGoods - ${goods}\nBads - ${bads}\n\nCombo Breaks: ${(PlayState.isStoryMode ? PlayState.campaignMisses : PlayState.misses)}\nHighest Combo: ${PlayState.highestCombo + 1}\nScore: ${PlayState.instance.songScore}\nAccuracy: ${HelperFunctions.truncateFloat(PlayState.instance.accuracy,2)}%\n\n${Ratings.GenerateLetterRank(PlayState.instance.accuracy)}\nRate: ${PlayState.songMultiplier}x\n\n${!PlayState.loadRep ? "\nF1 - Replay song" : ""}
');
comboText.size = 28;
comboText.setBorderStyle(FlxTextBorderStyle.OUTLINE,FlxColor.BLACK,4,1);
@@ -147,7 +147,7 @@ class ResultsScreen extends FlxSubState
if (diff != (166 * Math.floor((PlayState.rep.replay.sf / 60) * 1000) / 166))
mean += diff;
if (obj[1] != -1)
- graph.addToHistory(diff, judge, obj3);
+ graph.addToHistory(diff / PlayState.songMultiplier, judge, obj3 / PlayState.songMultiplier);
}
if (sicks == Math.POSITIVE_INFINITY || sicks == Math.NaN)
@@ -222,77 +222,6 @@ class ResultsScreen extends FlxSubState
}
if (FlxG.keys.justPressed.F1 && !PlayState.loadRep)
- {
- trace(PlayState.rep.path);
- PlayState.rep = Replay.LoadReplay(PlayState.rep.path);
-
- PlayState.loadRep = true;
- PlayState.isSM = PlayState.rep.replay.sm;
-
- 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 songHighscore = StringTools.replace(PlayState.SONG.song, " ", "-");
- switch (songHighscore) {
- case 'Dad-Battle': songHighscore = 'Dadbattle';
- case 'Philly-Nice': songHighscore = 'Philly';
- }
-
- #if !switch
- Highscore.saveScore(songHighscore, Math.round(PlayState.instance.songScore), PlayState.storyDifficulty);
- Highscore.saveCombo(songHighscore, Ratings.GenerateLetterRank(PlayState.instance.accuracy),PlayState.storyDifficulty);
- #end
-
- #if sys
- if (PlayState.rep.replay.sm)
- if (!FileSystem.exists(StringTools.replace(PlayState.rep.replay.chartPath,"converted.json","")))
- {
- Application.current.window.alert("The SM file in this replay does not exist!","SM Replays");
- return;
- }
- #end
-
- var poop = "";
-
- #if sys
- if (PlayState.isSM)
- {
- poop = File.getContent(PlayState.rep.replay.chartPath);
- try
- {
- PlayState.sm = SMFile.loadFile(PlayState.pathToSm + "/" + StringTools.replace(PlayState.rep.replay.songName," ", "_") + ".sm");
- }
- catch(e:Exception)
- {
- Application.current.window.alert("Make sure that the SM file is called " + PlayState.pathToSm + "/" + StringTools.replace(PlayState.rep.replay.songName," ", "_") + ".sm!\nAs I couldn't read it.","SM Replays");
- return;
- }
- }
- else
- poop = Highscore.formatSong(songFormat, PlayState.rep.replay.songDiff);
- #else
- poop = Highscore.formatSong(PlayState.rep.replay.songName, PlayState.rep.replay.songDiff);
- #end
-
- music.fadeOut(0.3);
-
- if (PlayState.isSM)
- PlayState.SONG = Song.conversionChecks(Song.loadFromJsonRAW(poop));
- else
- PlayState.SONG = Song.conversionChecks(Song.loadFromJson(poop, PlayState.rep.replay.songName));
- PlayState.isStoryMode = false;
- PlayState.storyDifficulty = PlayState.rep.replay.songDiff;
- LoadingState.loadAndSwitchState(new PlayState());
- PlayState.instance.clean();
- }
-
- if (FlxG.keys.justPressed.F2 && !PlayState.loadRep)
{
PlayState.rep = null;
@@ -309,20 +238,9 @@ class ResultsScreen extends FlxSubState
Highscore.saveCombo(songHighscore, Ratings.GenerateLetterRank(PlayState.instance.accuracy),PlayState.storyDifficulty);
#end
- var songFormat = StringTools.replace(PlayState.SONG.song, " ", "-");
- switch (songFormat) {
- case 'Dad-Battle': songFormat = 'Dadbattle';
- case 'Philly-Nice': songFormat = 'Philly';
- case 'dad-battle': songFormat = 'Dadbattle';
- case 'philly-nice': songFormat = 'Philly';
- }
-
- var poop:String = Highscore.formatSong(songFormat, PlayState.storyDifficulty);
-
if (music != null)
music.fadeOut(0.3);
- PlayState.SONG = Song.loadFromJson(poop, PlayState.SONG.song);
PlayState.isStoryMode = false;
PlayState.storyDifficulty = PlayState.storyDifficulty;
LoadingState.loadAndSwitchState(new PlayState());
diff --git a/source/Section.hx b/source/Section.hx
index cd17e25289..1e92e87334 100644
--- a/source/Section.hx
+++ b/source/Section.hx
@@ -11,8 +11,8 @@ typedef SwagSection =
var bpm:Float;
var changeBPM:Bool;
var altAnim:Bool;
- var p1AltAnim:Bool;
- var p2AltAnim:Bool;
+ var CPUAltAnim:Bool;
+ var playerAltAnim:Bool;
}
class Section
diff --git a/source/Song.hx b/source/Song.hx
index a0cbecb5b0..cc858003d7 100644
--- a/source/Song.hx
+++ b/source/Song.hx
@@ -43,6 +43,7 @@ typedef SwagSong =
class Song
{
+ public static var latestChart:String = "KE1";
public var chartVersion:String;
public var song:String;
public var notes:Array;
@@ -63,6 +64,7 @@ class Song
this.notes = notes;
this.bpm = bpm;
}
+
public static function loadFromJsonRAW(rawJson:String)
{
@@ -74,6 +76,7 @@ class Song
return parseJSONshit(rawJson);
}
+
public static function loadFromJson(jsonInput:String, ?folder:String):SwagSong
{
@@ -137,6 +140,41 @@ class Song
song.eventObjects = convertedStuff;
+ if (song.noteStyle == null)
+ song.noteStyle = "normal";
+
+ if (song.gfVersion == null)
+ song.gfVersion = "gf";
+
+
+ TimingStruct.clearTimings();
+
+ var currentIndex = 0;
+ for (i in song.eventObjects)
+ {
+ if (i.type == "BPM Change")
+ {
+ var beat:Float = i.position;
+
+ var endBeat:Float = Math.POSITIVE_INFINITY;
+
+ TimingStruct.addTiming(beat,i.value,endBeat, 0); // offset in this case = start time since we don't have a offset
+
+ if (currentIndex != 0)
+ {
+ var data = TimingStruct.AllTimings[currentIndex - 1];
+ data.endBeat = beat;
+ data.length = (data.endBeat - data.startBeat) / (data.bpm / 60);
+ var step = ((60 / data.bpm) * 1000) / 4;
+ TimingStruct.AllTimings[currentIndex].startStep = Math.floor(((data.endBeat / (data.bpm / 60)) * 1000) / step);
+ TimingStruct.AllTimings[currentIndex].startTime = data.startTime + data.length;
+ }
+
+ currentIndex++;
+ }
+ }
+
+
for(i in song.notes)
{
var currentBeat = 4 * index;
@@ -157,13 +195,21 @@ class Song
for(ii in i.sectionNotes)
{
- if (ii[3] == null)
+ if (song.chartVersion == null)
+ {
ii[3] = false;
+ ii[4] = TimingStruct.getBeatFromTime(ii[0]);
+ }
+
+ if (ii[3] == 0)
+ ii[3] == false;
}
index++;
}
+ song.chartVersion = latestChart;
+
return song;
}
@@ -178,7 +224,7 @@ class Song
for (section in swagShit.notes)
{
if (section.altAnim)
- section.p1AltAnim = section.altAnim;
+ section.CPUAltAnim = section.altAnim;
}
return swagShit;
diff --git a/source/Stage.hx b/source/Stage.hx
new file mode 100644
index 0000000000..ba7efe23aa
--- /dev/null
+++ b/source/Stage.hx
@@ -0,0 +1,430 @@
+package;
+
+import flixel.FlxSprite;
+import flixel.FlxG;
+import flixel.FlxBasic;
+import flixel.group.FlxGroup;
+import flixel.system.FlxSound;
+import flixel.addons.effects.chainable.FlxWaveEffect;
+
+class Stage
+{
+ public var curStage:String = '';
+ public var halloweenLevel:Bool = false;
+ public var camZoom:Float;
+ public var hideLastBG:Bool = false; // True = hide last BG and show ones from slowBacks on certain step, False = Toggle Visibility of BGs from SlowBacks on certain step
+ public var tweenDuration:Float = 2; // How long will it tween hiding/showing BGs, variable above must be set to True for tween to activate
+ public var toAdd:Array = []; // Add BGs on stage startup, load BG in by using "toAdd.push(bgVar);"
+ // Layering algorithm for noobs: Everything loads by the method of "On Top", example: You load wall first(Every other added BG layers on it), then you load road(comes on top of wall and doesn't clip through it), then loading street lights(comes on top of wall and road)
+ public var swagBacks:Map = []; // Store BGs here to use them later in PlayState or when slowBacks activate
+ public var swagGroup:Map> = []; //Store Groups
+ public var animatedBacks:Array = []; // Store animated backgrounds and make them play animation(Animation must be named Idle!! Else use swagGroup)
+ public var layInFront:Array> = [[], [], []]; // BG layering, format: first [0] - in front of GF, second [1] - in front of opponent, third [2] - in front of boyfriend(and techincally also opponent since Haxe layering moment)
+ public var slowBacks:Map> = []; // Change/add/remove backgrounds mid song! Format: "slowBacks[StepToBeActivated] = [Sprites,To,Be,Changed,Or,Added];"
+
+ public function new(daStage:String)
+ {
+ this.curStage = daStage;
+ camZoom = 1.05; // Don't change zoom here, unless you want to change zoom of every stage that doesn't have custom one
+ halloweenLevel = false;
+
+ switch(daStage)
+ {
+ case 'halloween':
+ {
+ halloweenLevel = true;
+
+ var hallowTex = Paths.getSparrowAtlas('halloween_bg', 'week2');
+
+ var halloweenBG = new FlxSprite(-200, -100);
+ halloweenBG.frames = hallowTex;
+ halloweenBG.animation.addByPrefix('idle', 'halloweem bg0');
+ halloweenBG.animation.addByPrefix('lightning', 'halloweem bg lightning strike', 24, false);
+ halloweenBG.animation.play('idle');
+ halloweenBG.antialiasing = FlxG.save.data.antialiasing;
+ swagBacks['halloweenBG'] = halloweenBG;
+ toAdd.push(halloweenBG);
+ }
+ case 'philly':
+ {
+
+ var bg:FlxSprite = new FlxSprite(-100).loadGraphic(Paths.image('philly/sky', 'week3'));
+ bg.scrollFactor.set(0.1, 0.1);
+ swagBacks['bg'] = bg;
+ toAdd.push(bg);
+
+ var city:FlxSprite = new FlxSprite(-10).loadGraphic(Paths.image('philly/city', 'week3'));
+ city.scrollFactor.set(0.3, 0.3);
+ city.setGraphicSize(Std.int(city.width * 0.85));
+ city.updateHitbox();
+ swagBacks['city'] = city;
+ toAdd.push(city);
+
+ var phillyCityLights = new FlxTypedGroup();
+ if (FlxG.save.data.distractions)
+ {
+ swagGroup['phillyCityLights'] = phillyCityLights;
+ toAdd.push(phillyCityLights);
+ }
+
+ for (i in 0...5)
+ {
+ var light:FlxSprite = new FlxSprite(city.x).loadGraphic(Paths.image('philly/win' + i, 'week3'));
+ light.scrollFactor.set(0.3, 0.3);
+ light.visible = false;
+ light.setGraphicSize(Std.int(light.width * 0.85));
+ light.updateHitbox();
+ light.antialiasing = FlxG.save.data.antialiasing;
+ phillyCityLights.add(light);
+ }
+
+ var streetBehind:FlxSprite = new FlxSprite(-40, 50).loadGraphic(Paths.image('philly/behindTrain', 'week3'));
+ swagBacks['streetBehind'] = streetBehind;
+ toAdd.push(streetBehind);
+
+ var phillyTrain = new FlxSprite(2000, 360).loadGraphic(Paths.image('philly/train', 'week3'));
+ if (FlxG.save.data.distractions)
+ {
+ swagBacks['phillyTrain'] = phillyTrain;
+ toAdd.push(phillyTrain);
+ }
+
+ PlayState.trainSound = new FlxSound().loadEmbedded(Paths.sound('train_passes', 'week3'));
+ FlxG.sound.list.add(PlayState.trainSound);
+
+ // var cityLights:FlxSprite = new FlxSprite().loadGraphic(AssetPaths.win0.png);
+
+ var street:FlxSprite = new FlxSprite(-40, streetBehind.y).loadGraphic(Paths.image('philly/street', 'week3'));
+ swagBacks['street'] = street;
+ toAdd.push(street);
+ }
+ case 'limo':
+ {
+ camZoom = 0.90;
+
+ var skyBG:FlxSprite = new FlxSprite(-120, -50).loadGraphic(Paths.image('limo/limoSunset', 'week4'));
+ skyBG.scrollFactor.set(0.1, 0.1);
+ skyBG.antialiasing = FlxG.save.data.antialiasing;
+ swagBacks['skyBG'] = skyBG;
+ toAdd.push(skyBG);
+
+ var bgLimo:FlxSprite = new FlxSprite(-200, 480);
+ bgLimo.frames = Paths.getSparrowAtlas('limo/bgLimo', 'week4');
+ bgLimo.animation.addByPrefix('drive', "background limo pink", 24);
+ bgLimo.animation.play('drive');
+ bgLimo.scrollFactor.set(0.4, 0.4);
+ bgLimo.antialiasing = FlxG.save.data.antialiasing;
+ swagBacks['bgLimo'] = bgLimo;
+ toAdd.push(bgLimo);
+
+ var fastCar:FlxSprite;
+ fastCar = new FlxSprite(-300, 160).loadGraphic(Paths.image('limo/fastCarLol', 'week4'));
+ fastCar.antialiasing = FlxG.save.data.antialiasing;
+
+ if (FlxG.save.data.distractions)
+ {
+ var grpLimoDancers = new FlxTypedGroup();
+ swagGroup['grpLimoDancers'] = grpLimoDancers;
+ toAdd.push(grpLimoDancers);
+
+ for (i in 0...5)
+ {
+ var dancer:BackgroundDancer = new BackgroundDancer((370 * i) + 130, bgLimo.y - 400);
+ dancer.scrollFactor.set(0.4, 0.4);
+ grpLimoDancers.add(dancer);
+ }
+
+ swagBacks['fastCar'] = fastCar;
+ layInFront[2].push(fastCar);
+ }
+
+ var overlayShit:FlxSprite = new FlxSprite(-500, -600).loadGraphic(Paths.image('limo/limoOverlay', 'week4'));
+ overlayShit.alpha = 0.5;
+ // add(overlayShit);
+
+ // var shaderBullshit = new BlendModeEffect(new OverlayShader(), FlxColor.RED);
+
+ // FlxG.camera.setFilters([new ShaderFilter(cast shaderBullshit.shader)]);
+
+ // overlayShit.shader = shaderBullshit;
+
+ var limoTex = Paths.getSparrowAtlas('limo/limoDrive', 'week4');
+
+ var limo = new FlxSprite(-120, 550);
+ limo.frames = limoTex;
+ limo.animation.addByPrefix('drive', "Limo stage", 24);
+ limo.animation.play('drive');
+ limo.antialiasing = FlxG.save.data.antialiasing;
+ layInFront[0].push(limo);
+ swagBacks['limo'] = limo;
+
+ // Testing
+ //
+ // hideLastBG = true;
+ // slowBacks[40] = [limo];
+ // slowBacks[120] = [limo, bgLimo, skyBG, fastCar];
+ }
+ case 'mall':
+ {
+ camZoom = 0.80;
+
+ var bg:FlxSprite = new FlxSprite(-1000, -500).loadGraphic(Paths.image('christmas/bgWalls', 'week5'));
+ bg.antialiasing = FlxG.save.data.antialiasing;
+ bg.scrollFactor.set(0.2, 0.2);
+ bg.active = false;
+ bg.setGraphicSize(Std.int(bg.width * 0.8));
+ bg.updateHitbox();
+ swagBacks['bg'] = bg;
+ toAdd.push(bg);
+
+ var upperBoppers = new FlxSprite(-240, -90);
+ upperBoppers.frames = Paths.getSparrowAtlas('christmas/upperBop', 'week5');
+ upperBoppers.animation.addByPrefix('idle', "Upper Crowd Bob", 24, false);
+ upperBoppers.antialiasing = FlxG.save.data.antialiasing;
+ upperBoppers.scrollFactor.set(0.33, 0.33);
+ upperBoppers.setGraphicSize(Std.int(upperBoppers.width * 0.85));
+ upperBoppers.updateHitbox();
+ if (FlxG.save.data.distractions)
+ {
+ swagBacks['upperBoppers'] = upperBoppers;
+ toAdd.push(upperBoppers);
+ animatedBacks.push(upperBoppers);
+ }
+
+ var bgEscalator:FlxSprite = new FlxSprite(-1100, -600).loadGraphic(Paths.image('christmas/bgEscalator', 'week5'));
+ bgEscalator.antialiasing = FlxG.save.data.antialiasing;
+ bgEscalator.scrollFactor.set(0.3, 0.3);
+ bgEscalator.active = false;
+ bgEscalator.setGraphicSize(Std.int(bgEscalator.width * 0.9));
+ bgEscalator.updateHitbox();
+ swagBacks['bgEscalator'] = bgEscalator;
+ toAdd.push(bgEscalator);
+
+ var tree:FlxSprite = new FlxSprite(370, -250).loadGraphic(Paths.image('christmas/christmasTree', 'week5'));
+ tree.antialiasing = FlxG.save.data.antialiasing;
+ tree.scrollFactor.set(0.40, 0.40);
+ swagBacks['tree'] = tree;
+ toAdd.push(tree);
+
+ var bottomBoppers = new FlxSprite(-300, 140);
+ bottomBoppers.frames = Paths.getSparrowAtlas('christmas/bottomBop', 'week5');
+ bottomBoppers.animation.addByPrefix('idle', 'Bottom Level Boppers', 24, false);
+ bottomBoppers.antialiasing = FlxG.save.data.antialiasing;
+ bottomBoppers.scrollFactor.set(0.9, 0.9);
+ bottomBoppers.setGraphicSize(Std.int(bottomBoppers.width * 1));
+ bottomBoppers.updateHitbox();
+ if (FlxG.save.data.distractions)
+ {
+ swagBacks['bottomBoppers'] = bottomBoppers;
+ toAdd.push(bottomBoppers);
+ animatedBacks.push(bottomBoppers);
+ }
+
+ var fgSnow:FlxSprite = new FlxSprite(-600, 700).loadGraphic(Paths.image('christmas/fgSnow', 'week5'));
+ fgSnow.active = false;
+ fgSnow.antialiasing = FlxG.save.data.antialiasing;
+ swagBacks['fgSnow'] = fgSnow;
+ toAdd.push(fgSnow);
+
+ var santa = new FlxSprite(-840, 150);
+ santa.frames = Paths.getSparrowAtlas('christmas/santa', 'week5');
+ santa.animation.addByPrefix('idle', 'santa idle in fear', 24, false);
+ santa.antialiasing = FlxG.save.data.antialiasing;
+ if (FlxG.save.data.distractions)
+ {
+ swagBacks['santa'] = santa;
+ toAdd.push(santa);
+ animatedBacks.push(santa);
+ }
+ }
+ case 'mallEvil':
+ {
+ var bg:FlxSprite = new FlxSprite(-400, -500).loadGraphic(Paths.image('christmas/evilBG', 'week5'));
+ bg.antialiasing = FlxG.save.data.antialiasing;
+ bg.scrollFactor.set(0.2, 0.2);
+ bg.active = false;
+ bg.setGraphicSize(Std.int(bg.width * 0.8));
+ bg.updateHitbox();
+ swagBacks['bg'] = bg;
+ toAdd.push(bg);
+
+ var evilTree:FlxSprite = new FlxSprite(300, -300).loadGraphic(Paths.image('christmas/evilTree', 'week5'));
+ evilTree.antialiasing = FlxG.save.data.antialiasing;
+ evilTree.scrollFactor.set(0.2, 0.2);
+ swagBacks['evilTree'] = evilTree;
+ toAdd.push(evilTree);
+
+ var evilSnow:FlxSprite = new FlxSprite(-200, 700).loadGraphic(Paths.image("christmas/evilSnow", 'week5'));
+ evilSnow.antialiasing = FlxG.save.data.antialiasing;
+ swagBacks['evilSnow'] = evilSnow;
+ toAdd.push(evilSnow);
+ }
+ case 'school':
+ {
+ // defaultCamZoom = 0.9;
+
+ var bgSky = new FlxSprite().loadGraphic(Paths.image('weeb/weebSky', 'week6'));
+ bgSky.scrollFactor.set(0.1, 0.1);
+ swagBacks['bgSky'] = bgSky;
+ toAdd.push(bgSky);
+
+ var repositionShit = -200;
+
+ var bgSchool:FlxSprite = new FlxSprite(repositionShit, 0).loadGraphic(Paths.image('weeb/weebSchool', 'week6'));
+ bgSchool.scrollFactor.set(0.6, 0.90);
+ swagBacks['bgSchool'] = bgSchool;
+ toAdd.push(bgSchool);
+
+ var bgStreet:FlxSprite = new FlxSprite(repositionShit).loadGraphic(Paths.image('weeb/weebStreet', 'week6'));
+ bgStreet.scrollFactor.set(0.95, 0.95);
+ swagBacks['bgStreet'] = bgStreet;
+ toAdd.push(bgStreet);
+
+ var fgTrees:FlxSprite = new FlxSprite(repositionShit + 170, 130).loadGraphic(Paths.image('weeb/weebTreesBack', 'week6'));
+ fgTrees.scrollFactor.set(0.9, 0.9);
+ swagBacks['fgTrees'] = fgTrees;
+ toAdd.push(fgTrees);
+
+ var bgTrees:FlxSprite = new FlxSprite(repositionShit - 380, -800);
+ var treetex = Paths.getPackerAtlas('weeb/weebTrees', 'week6');
+ bgTrees.frames = treetex;
+ bgTrees.animation.add('treeLoop', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], 12);
+ bgTrees.animation.play('treeLoop');
+ bgTrees.scrollFactor.set(0.85, 0.85);
+ swagBacks['bgTrees'] = bgTrees;
+ toAdd.push(bgTrees);
+
+ var treeLeaves:FlxSprite = new FlxSprite(repositionShit, -40);
+ treeLeaves.frames = Paths.getSparrowAtlas('weeb/petals', 'week6');
+ treeLeaves.animation.addByPrefix('leaves', 'PETALS ALL', 24, true);
+ treeLeaves.animation.play('leaves');
+ treeLeaves.scrollFactor.set(0.85, 0.85);
+ swagBacks['treeLeaves'] = treeLeaves;
+ toAdd.push(treeLeaves);
+
+ var widShit = Std.int(bgSky.width * 6);
+
+ bgSky.setGraphicSize(widShit);
+ bgSchool.setGraphicSize(widShit);
+ bgStreet.setGraphicSize(widShit);
+ bgTrees.setGraphicSize(Std.int(widShit * 1.4));
+ fgTrees.setGraphicSize(Std.int(widShit * 0.8));
+ treeLeaves.setGraphicSize(widShit);
+
+ fgTrees.updateHitbox();
+ bgSky.updateHitbox();
+ bgSchool.updateHitbox();
+ bgStreet.updateHitbox();
+ bgTrees.updateHitbox();
+ treeLeaves.updateHitbox();
+
+ var bgGirls = new BackgroundGirls(-100, 190);
+ bgGirls.scrollFactor.set(0.9, 0.9);
+
+ if (PlayState.SONG.song.toLowerCase() == 'roses')
+ {
+ if (FlxG.save.data.distractions)
+ {
+ bgGirls.getScared();
+ }
+ }
+
+ bgGirls.setGraphicSize(Std.int(bgGirls.width * PlayState.daPixelZoom));
+ bgGirls.updateHitbox();
+ if (FlxG.save.data.distractions)
+ {
+ swagBacks['bgGirls'] = bgGirls;
+ toAdd.push(bgGirls);
+ }
+ }
+ case 'schoolEvil':
+ {
+ if (!PlayStateChangeables.Optimize)
+ {
+ var waveEffectBG = new FlxWaveEffect(FlxWaveMode.ALL, 2, -1, 3, 2);
+ var waveEffectFG = new FlxWaveEffect(FlxWaveMode.ALL, 2, -1, 5, 2);
+ }
+
+ var posX = 400;
+ var posY = 200;
+
+ var bg:FlxSprite = new FlxSprite(posX, posY);
+ bg.frames = Paths.getSparrowAtlas('weeb/animatedEvilSchool', 'week6');
+ bg.animation.addByPrefix('idle', 'background 2', 24);
+ bg.animation.play('idle');
+ bg.scrollFactor.set(0.8, 0.9);
+ bg.scale.set(6, 6);
+ swagBacks['bg'] = bg;
+ toAdd.push(bg);
+
+ /*
+ var bg:FlxSprite = new FlxSprite(posX, posY).loadGraphic(Paths.image('weeb/evilSchoolBG'));
+ bg.scale.set(6, 6);
+ // bg.setGraphicSize(Std.int(bg.width * 6));
+ // bg.updateHitbox();
+ add(bg);
+ var fg:FlxSprite = new FlxSprite(posX, posY).loadGraphic(Paths.image('weeb/evilSchoolFG'));
+ fg.scale.set(6, 6);
+ // fg.setGraphicSize(Std.int(fg.width * 6));
+ // fg.updateHitbox();
+ add(fg);
+ wiggleShit.effectType = WiggleEffectType.DREAMY;
+ wiggleShit.waveAmplitude = 0.01;
+ wiggleShit.waveFrequency = 60;
+ wiggleShit.waveSpeed = 0.8;
+ */
+
+ // bg.shader = wiggleShit.shader;
+ // fg.shader = wiggleShit.shader;
+
+ /*
+ var waveSprite = new FlxEffectSprite(bg, [waveEffectBG]);
+ var waveSpriteFG = new FlxEffectSprite(fg, [waveEffectFG]);
+ // Using scale since setGraphicSize() doesnt work???
+ waveSprite.scale.set(6, 6);
+ waveSpriteFG.scale.set(6, 6);
+ waveSprite.setPosition(posX, posY);
+ waveSpriteFG.setPosition(posX, posY);
+ waveSprite.scrollFactor.set(0.7, 0.8);
+ waveSpriteFG.scrollFactor.set(0.9, 0.8);
+ // waveSprite.setGraphicSize(Std.int(waveSprite.width * 6));
+ // waveSprite.updateHitbox();
+ // waveSpriteFG.setGraphicSize(Std.int(fg.width * 6));
+ // waveSpriteFG.updateHitbox();
+ add(waveSprite);
+ add(waveSpriteFG);
+ */
+ }
+ default:
+ {
+ camZoom = 0.9;
+ curStage = 'stage';
+ var bg:FlxSprite = new FlxSprite(-600, -200).loadGraphic(Paths.image('stageback'));
+ bg.antialiasing = FlxG.save.data.antialiasing;
+ bg.scrollFactor.set(0.9, 0.9);
+ bg.active = false;
+ swagBacks['bg'] = bg;
+ toAdd.push(bg);
+
+ var stageFront:FlxSprite = new FlxSprite(-650, 600).loadGraphic(Paths.image('stagefront'));
+ stageFront.setGraphicSize(Std.int(stageFront.width * 1.1));
+ stageFront.updateHitbox();
+ stageFront.antialiasing = FlxG.save.data.antialiasing;
+ stageFront.scrollFactor.set(0.9, 0.9);
+ stageFront.active = false;
+ swagBacks['stageFront'] = stageFront;
+ toAdd.push(stageFront);
+
+ var stageCurtains:FlxSprite = new FlxSprite(-500, -300).loadGraphic(Paths.image('stagecurtains'));
+ stageCurtains.setGraphicSize(Std.int(stageCurtains.width * 0.9));
+ stageCurtains.updateHitbox();
+ stageCurtains.antialiasing = FlxG.save.data.antialiasing;
+ stageCurtains.scrollFactor.set(1.3, 1.3);
+ stageCurtains.active = false;
+
+ swagBacks['stageCurtains'] = stageCurtains;
+ toAdd.push(stageCurtains);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/StagePositioningDebug.hx b/source/StagePositioningDebug.hx
new file mode 100644
index 0000000000..e34099ede6
--- /dev/null
+++ b/source/StagePositioningDebug.hx
@@ -0,0 +1,182 @@
+package;
+
+import flixel.FlxState;
+import flixel.FlxG;
+import flixel.FlxObject;
+import flixel.group.FlxGroup;
+import flixel.text.FlxText;
+import flixel.FlxCamera;
+import flixel.FlxSprite;
+
+class StagePositioningDebug extends FlxState
+{
+ public var daStage:String;
+ public var daBf:String;
+ public var daGf:String;
+ public var opponent:String;
+
+ var gf:Character;
+ var boyfriend:Boyfriend;
+ var dad:Character;
+ var Stage:Stage;
+ var camFollow:FlxObject;
+ var posText:FlxText;
+ var curChar:FlxSprite;
+ var curCharIndex:Int = 0;
+ var curCharString:String;
+ var curChars:Array;
+ var dragging:Bool = false;
+ var oldMousePosX:Int;
+ var oldMousePosY:Int;
+ var camHUD:FlxCamera;
+ var camGame:FlxCamera;
+
+ public function new(daStage:String = 'stage', daGf:String = 'gf', daBf:String = 'bf', opponent:String = 'dad')
+ {
+ super();
+ this.daStage = daStage;
+ this.daGf = daGf;
+ this.daBf = daBf;
+ this.opponent = opponent;
+ curCharString = daGf;
+ }
+
+ override function create()
+ {
+ FlxG.sound.music.stop();
+ FlxG.mouse.visible = true;
+
+ Stage = PlayState.Stage;
+
+ gf = PlayState.gf;
+ boyfriend = PlayState.boyfriend;
+ dad = PlayState.dad;
+ curChars = [gf, boyfriend, dad];
+ curChar = curChars[curCharIndex];
+
+ for (i in Stage.toAdd)
+ {
+ add(i);
+ }
+
+ for (index => array in Stage.layInFront)
+ {
+ switch (index)
+ {
+ case 0:
+ add(gf);
+ for (bg in array)
+ add(bg);
+ case 1:
+ add(dad);
+ for (bg in array)
+ add(bg);
+ case 2:
+ add(boyfriend);
+ for (bg in array)
+ add(bg);
+ }
+ }
+
+ camFollow = new FlxObject(0, 0, 2, 2);
+ camFollow.screenCenter();
+ add(camFollow);
+
+ camHUD = new FlxCamera();
+ camHUD.bgColor.alpha = 0;
+ camGame = new FlxCamera();
+ camGame.zoom = 0.7;
+ FlxG.cameras.add(camGame);
+ FlxG.cameras.add(camHUD);
+ FlxCamera.defaultCameras = [camGame];
+ camGame.follow(camFollow);
+
+ posText = new FlxText(0, 0);
+ posText.size = 26;
+ posText.scrollFactor.set();
+ posText.cameras = [camHUD];
+ add(posText);
+ }
+
+ override public function update(elapsed:Float)
+ {
+ if (FlxG.keys.justPressed.E)
+ camGame.zoom += 0.1;
+ if (FlxG.keys.justPressed.Q)
+ {
+ if (camGame.zoom > 0.11) // me when floating point error
+ camGame.zoom -= 0.1;
+ }
+ FlxG.watch.addQuick('Camera Zoom', camGame.zoom);
+
+ 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.SPACE)
+ {
+ ++curCharIndex;
+ if (curCharIndex >= curChars.length)
+ {
+ curChar = curChars[0];
+ curCharIndex = 0;
+ }
+ else
+ curChar = curChars[curCharIndex];
+ switch (curCharIndex)
+ {
+ case 0:
+ curCharString = daGf;
+ case 1:
+ curCharString = daBf;
+ case 2:
+ curCharString = opponent;
+ }
+ }
+
+ if (FlxG.mouse.pressed && curChar.pixelsOverlapPoint(FlxG.mouse.getPosition()) && !dragging)
+ {
+ dragging = true;
+ updateMousePos();
+ }
+
+ if (dragging && FlxG.mouse.justMoved)
+ {
+ curChar.setPosition(-(oldMousePosX - FlxG.mouse.x) + curChar.x, -(oldMousePosY - FlxG.mouse.y) + curChar.y);
+ updateMousePos();
+ }
+
+ if (dragging && FlxG.mouse.justReleased || FlxG.keys.justPressed.TAB)
+ dragging = false;
+
+ posText.text = (curCharString + " X: " + curChar.x + " Y: " + curChar.y);
+
+ if (FlxG.keys.justPressed.ESCAPE)
+ FlxG.switchState(new MainMenuState());
+
+ super.update(elapsed);
+ }
+
+ public function updateMousePos()
+ {
+ oldMousePosX = FlxG.mouse.x;
+ oldMousePosY = FlxG.mouse.y;
+ }
+}
\ No newline at end of file
diff --git a/source/StaticArrow.hx b/source/StaticArrow.hx
new file mode 100644
index 0000000000..a5d54ab53a
--- /dev/null
+++ b/source/StaticArrow.hx
@@ -0,0 +1,54 @@
+package;
+
+import flixel.FlxG;
+import flixel.FlxSprite;
+import flixel.animation.FlxBaseAnimation;
+import flixel.graphics.frames.FlxAtlasFrames;
+
+using StringTools;
+
+class StaticArrow extends FlxSprite
+{
+ public var modifiedByLua:Bool = false;
+ public var modAngle:Float = 0; // The angle set by modcharts
+ public var localAngle:Float = 0; // The angle to be edited inside here
+
+ public function new(xx:Float, yy:Float)
+ {
+ x = xx;
+ y = yy;
+ super(x, y);
+ updateHitbox();
+ }
+
+ override function update(elapsed:Float)
+ {
+ if (!modifiedByLua)
+ angle = localAngle + modAngle;
+ else
+ angle = modAngle;
+ super.update(elapsed);
+
+ if (FlxG.keys.justPressed.THREE)
+ {
+ localAngle += 10;
+ }
+ }
+
+ public function playAnim(AnimName:String, ?force:Bool = false):Void
+ {
+ animation.play(AnimName, force);
+
+ if (!AnimName.startsWith('dirCon'))
+ {
+ localAngle = 0;
+ }
+ updateHitbox();
+ offset.set(frameWidth / 2, frameHeight / 2);
+
+ offset.x -= 54;
+ offset.y -= 56;
+
+ angle = localAngle + modAngle;
+ }
+}
diff --git a/source/StoryMenuState.hx b/source/StoryMenuState.hx
index e046ed64e6..6fb80d217b 100644
--- a/source/StoryMenuState.hx
+++ b/source/StoryMenuState.hx
@@ -352,7 +352,7 @@ class StoryMenuState extends MusicBeatState
PlayState.storyPlaylist = weekData()[curWeek];
PlayState.isStoryMode = true;
selectedWeek = true;
-
+ PlayState.songMultiplier = 1;
PlayState.storyDifficulty = curDifficulty;
diff --git a/source/TimingStruct.hx b/source/TimingStruct.hx
index d1301c1880..1e933e43f6 100644
--- a/source/TimingStruct.hx
+++ b/source/TimingStruct.hx
@@ -4,12 +4,12 @@ class TimingStruct
{
public static var AllTimings:Array = [];
- public var bpm:Float = 0;
+ public var bpm:Float = 0; // idk what does this do
- public var startBeat:Float = 0;
- public var startStep:Int = 0;
- public var endBeat:Float = Math.POSITIVE_INFINITY;
- public var startTime:Float = 0;
+ public var startBeat:Float = 0; // BEATS
+ public var startStep:Int = 0; // BAD MEASUREMENTS
+ public var endBeat:Float = Math.POSITIVE_INFINITY; // BEATS
+ public var startTime:Float = 0; // SECONDS
public var length:Float = Math.POSITIVE_INFINITY; // in beats
@@ -24,6 +24,29 @@ class TimingStruct
AllTimings.push(pog);
}
+ public static function getBeatFromTime(time:Float)
+ {
+ var beat = -1.0;
+ var seg = TimingStruct.getTimingAtTimestamp(time);
+
+ if (seg != null)
+ beat = seg.startBeat + (((time / 1000) - seg.startTime) * (seg.bpm / 60));
+
+ return beat;
+ }
+
+ public static function getTimeFromBeat(beat:Float)
+ {
+ var time = -1.0;
+ var seg = TimingStruct.getTimingAtBeat(beat);
+
+ if (seg != null)
+ time = seg.startTime + ((beat - seg.startBeat) / (seg.bpm / 60));
+
+ return time * 1000;
+ }
+
+
public function new(startBeat:Float,bpm:Float,endBeat:Float, offset:Float)
{
this.bpm = bpm;
@@ -40,7 +63,6 @@ class TimingStruct
if (msTime >= i.startTime * 1000 && msTime < (i.startTime + i.length) * 1000)
return i;
}
- trace('Apparently ' + msTime + ' is out of any segs');
return null;
}
diff --git a/source/smTools/SMFile.hx b/source/smTools/SMFile.hx
index 145ccb032d..d5b81be271 100644
--- a/source/smTools/SMFile.hx
+++ b/source/smTools/SMFile.hx
@@ -134,7 +134,8 @@ class SMFile
noteStyle: 'normal',
stage: 'stage',
speed: 1.0,
- validScore: false
+ validScore: false,
+ chartVersion: "",
};
// lets check if the sm loading was valid
@@ -244,16 +245,16 @@ class SMFile
switch(numba)
{
case 1: // normal
- section.sectionNotes.push([rowTime,lane ,0]);
+ section.sectionNotes.push([rowTime,lane ,0,0, currentBeat]);
case 2: // held head
- heldNotes[lane] = [rowTime,lane,0];
+ heldNotes[lane] = [rowTime,lane,0,0, currentBeat];
case 3: // held tail
var data = heldNotes[lane];
var timeDiff = rowTime - data[0];
- section.sectionNotes.push([data[0],lane,timeDiff]);
+ section.sectionNotes.push([data[0],lane,timeDiff,0, data[4]]);
heldNotes[index] = [];
case 4: // roll head
- heldNotes[lane] = [rowTime,lane,0];
+ heldNotes[lane] = [rowTime,lane,0,0, currentBeat];
}
index++;
}
@@ -327,6 +328,8 @@ class SMFile
// save da song
+ song.chartVersion = Song.latestChart;
+
var json = {
"song": song
};
diff --git a/version.downloadMe b/version.downloadMe
index 93bbd4b397..ab531e921b 100644
--- a/version.downloadMe
+++ b/version.downloadMe
@@ -1,8 +1,8 @@
-1.6.2;
-- Added the ability to select and modify notes in the editor
-- Added copy and paste (with ctrl z support) while selecting notes
-- Optimized gameplay
-- Optimized the chart editor (less lag on longer songs, and faster load times)
-- Fixed stutter at the start of a song
-- Fixed scroll speed changes so they work when more then one of them exist
-- Modcharts now work on Linux!
\ No newline at end of file
+1.7;
+- A speed modifier
+- Completely redid all of the modcharting api
+- Optimized a lot of code to run better
+- Allowed numpad to be binded as a key
+- Changed the editor to work entirely on beats
+- Fix multiplie crashes with story mode and other weeks in story mode
+- Fix desyncs with bpm changes and section notes in the charter
\ No newline at end of file