diff --git a/assets/images/game/notes/default.xml b/assets/images/game/notes/default.xml
index d7df312c..587e6821 100644
--- a/assets/images/game/notes/default.xml
+++ b/assets/images/game/notes/default.xml
@@ -9,10 +9,12 @@
-
-
-
-
+
+
+
+
+
+
@@ -20,10 +22,12 @@
+
+
@@ -50,10 +54,12 @@
-
-
+
+
+
+
diff --git a/assets/songs/test/scripts/modchart.hx b/assets/songs/test/scripts/modchart.hx
index c517ed5a..b91a084d 100644
--- a/assets/songs/test/scripts/modchart.hx
+++ b/assets/songs/test/scripts/modchart.hx
@@ -14,10 +14,22 @@ function postCreate() {
}
function postUpdate(elapsed) {
- // var sin = Math.sin(curBeatFloat * Math.PI / 2);
+ for(s in strumLines) {
+ for(i in 0...4) {
+ var n = s.members[i];
+ n.angle = Math.sin(curBeatFloat + (i * 0.45)) * 35;
+ }
+ }
- // camGame.angle = sin * -15;
-
- if (curSection != null)
- defaultCamZoom = curSection.mustHitSection ? 0.9 : 0.5;
+
+ // for(s in strumLines) {
+ // for(i in 0...4) {
+ // var n = s.members[i];
+ // n.y = FlxG.height - 200;
+ // n.angle = 180;
+ // }
+ // }
+
+ // if (curSection != null)
+ // defaultCamZoom = curSection.mustHitSection ? 0.9 : 0.5;
}
\ No newline at end of file
diff --git a/source/funkin/game/Note.hx b/source/funkin/game/Note.hx
index 3210375d..bbf058fb 100644
--- a/source/funkin/game/Note.hx
+++ b/source/funkin/game/Note.hx
@@ -119,7 +119,7 @@ class Note extends FlxSprite
this.noteData = noteData.id.getDefault(0);
var customType = Paths.image('game/notes/${this.noteType}');
- var event = EventManager.get(NoteCreationEvent).recycle(this, strumID, this.noteType, noteTypeID, PlayState.instance.strumLines.indexOf(strumLine), mustPress,
+ var event = EventManager.get(NoteCreationEvent).recycle(this, strumID, this.noteType, noteTypeID, PlayState.instance.strumLines.members.indexOf(strumLine), mustPress,
(this.noteType != null && customTypePathExists(customType)) ? 'game/notes/${this.noteType}' : 'game/notes/default', 0.7, animSuffix);
if (PlayState.instance != null)
@@ -251,7 +251,11 @@ class Note extends FlxSprite
if (!wasGoodHit) return;
var t = FlxMath.bound((Conductor.songPosition - strumTime) / (height / (0.45 * FlxMath.roundDecimal(scrollSpeed, 2))), 0, 1);
- var swagRect = new FlxRect(0, t * frameHeight, frameWidth, frameHeight);
+ var swagRect = this.clipRect == null ? new FlxRect() : this.clipRect;
+ swagRect.x = 0;
+ swagRect.y = t * frameHeight;
+ swagRect.width = frameWidth;
+ swagRect.height = frameHeight;
setClipRect(swagRect);
}
diff --git a/source/funkin/game/PlayState.hx b/source/funkin/game/PlayState.hx
index fbaf1709..b2175d04 100644
--- a/source/funkin/game/PlayState.hx
+++ b/source/funkin/game/PlayState.hx
@@ -87,7 +87,7 @@ class PlayState extends MusicBeatState
/**
* Array of all the players in the stage.
*/
- public var strumLines:Array = [];
+ public var strumLines:FlxTypedGroup = new FlxTypedGroup();
/**
* Game Over Song. (assets/music/gameOver.ogg)
@@ -618,11 +618,12 @@ class PlayState extends MusicBeatState
var strLine = new StrumLine(chars, strOffset, strumLine.type == 2 || (!coopMode && !((strumLine.type == 1 && !opponentMode) || (strumLine.type == 0 && opponentMode))), strumLine.type != 1, coopMode ? (strumLine.type == 1 ? controlsP1 : controlsP2) : controls);
strLine.cameras = [camHUD];
strLine.data = strumLine;
- strumLines.push(strLine);
- if (strumLine.visible != false)
- add(strLine);
+ strLine.visible = (strumLine.visible != false);
+ strumLines.add(strLine);
}
+ add(strumLines);
+
splashHandler = new SplashHandler();
add(splashHandler);
@@ -1114,11 +1115,11 @@ class PlayState extends MusicBeatState
while(events.length > 0 && events[0].time <= Conductor.songPosition)
executeEvent(events.shift());
- if (generatedMusic && strumLines[curCameraTarget] != null)
+ if (generatedMusic && strumLines.members[curCameraTarget] != null)
{
var pos = FlxPoint.get();
var r = 0;
- for(c in strumLines[curCameraTarget].characters) {
+ for(c in strumLines.members[curCameraTarget].characters) {
if (c == null) continue;
var cpos = c.getCameraPosition();
pos.x += cpos.x;
@@ -1130,7 +1131,7 @@ class PlayState extends MusicBeatState
pos.x /= r;
pos.y /= r;
- var event = scripts.event("onCameraMove", EventManager.get(CamMoveEvent).recycle(pos, strumLines[curCameraTarget], r));
+ var event = scripts.event("onCameraMove", EventManager.get(CamMoveEvent).recycle(pos, strumLines.members[curCameraTarget], r));
if (!event.cancelled)
camFollow.setPosition(pos.x, pos.y);
}
@@ -1181,7 +1182,7 @@ class PlayState extends MusicBeatState
// automatically handled by conductor
case ALT_ANIM_TOGGLE:
if (event.params[0] is Int && event.params[1] is Bool) {
- var strLine = strumLines[event.params[0]];
+ var strLine = strumLines.members[event.params[0]];
if (strLine != null)
strLine.altAnim = cast event.params[1];
}
@@ -1322,74 +1323,10 @@ class PlayState extends MusicBeatState
MusicBeatState.skipTransOut = true;
}
- var __funcsToExec:ArrayVoid> = [];
- var __pressed:Array = [];
- var __justPressed:Array = [];
- var __justReleased:Array = [];
- private function keyShit():Void
+ private inline function keyShit():Void
{
- for(id=>p in strumLines) {
- p.updateNotes();
-
- if (p.cpu) continue;
-
- __funcsToExec = [null, null];
- __pressed.clear();
- __justPressed.clear();
- __justReleased.clear();
-
- __pressed.pushGroup(p.controls.NOTE_LEFT, p.controls.NOTE_DOWN, p.controls.NOTE_UP, p.controls.NOTE_RIGHT);
- __justPressed.pushGroup(p.controls.NOTE_LEFT_P, p.controls.NOTE_DOWN_P, p.controls.NOTE_UP_P, p.controls.NOTE_RIGHT_P);
- __justReleased.pushGroup(p.controls.NOTE_LEFT_R, p.controls.NOTE_DOWN_R, p.controls.NOTE_UP_R, p.controls.NOTE_RIGHT_R);
-
- var event = scripts.event("onKeyShit", EventManager.get(InputSystemEvent).recycle(__pressed, __justPressed, __justReleased, p, id));
- if (event.cancelled) return;
-
- __pressed = CoolUtil.getDefault(event.pressed, []);
- __justPressed = CoolUtil.getDefault(event.justPressed, []);
- __justReleased = CoolUtil.getDefault(event.justReleased, []);
-
-
- if (__pressed.contains(true)) {
- for(c in p.characters)
- if (c.lastAnimContext != DANCE)
- c.__lockAnimThisFrame = true;
-
- __funcsToExec[0] = function(note:Note) {
- if (__pressed[note.strumID] && note.isSustainNote && note.canBeHit && !note.wasGoodHit) {
- goodNoteHit(p, note);
- }
- };
- }
-
- var notePerStrum = [for(_ in 0...4) null];
- if (__justPressed.contains(true)) {
- __funcsToExec[1] = function(note:Note) {
- if (__justPressed[note.strumID] && !note.isSustainNote && !note.wasGoodHit && note.canBeHit) {
- if (notePerStrum[note.strumID] == null) notePerStrum[note.strumID] = note;
- else if (Math.abs(notePerStrum[note.strumID].strumTime - note.strumTime) <= 2) p.deleteNote(note);
- else if (note.strumTime < notePerStrum[note.strumID].strumTime) notePerStrum[note.strumID] = note;
- }
- };
- }
-
- if (__funcsToExec.length > 0) {
- p.notes.forEachAlive(function(note:Note) {
- for(e in __funcsToExec) if (e != null) e(note);
- });
- }
-
- if (!p.ghostTapping) for(k=>pr in __justPressed) if (pr && notePerStrum[k] == null) {
- // FUCK YOU
- noteMiss(p, null, k, id);
- }
- for(e in notePerStrum) if (e != null) goodNoteHit(p, e);
-
- p.forEach(function(str:Strum) {
- str.updatePlayerInput(__pressed[str.ID], __justPressed[str.ID], __justReleased[str.ID]);
- });
- scripts.call("onPostKeyShit");
- }
+ for(id=>p in strumLines.members)
+ p.updateInput(id);
}
/**
@@ -1400,11 +1337,11 @@ class PlayState extends MusicBeatState
*/
public function noteMiss(strumLine:StrumLine, note:Note, ?direction:Int, ?player:Int):Void
{
- var playerID:Null = note == null ? player : strumLines.indexOf(strumLine);
+ var playerID:Null = note == null ? player : strumLines.members.indexOf(strumLine);
var directionID:Null = note == null ? direction : note.strumID;
if (playerID == null || directionID == null) return;
- var event:NoteHitEvent = scripts.event("onPlayerMiss", EventManager.get(NoteHitEvent).recycle(true, false, false, note, strumLines[playerID].characters, true, note != null ? note.noteType : null, "", "", "", directionID, -10, 0, -0.04, "shit"));
+ var event:NoteHitEvent = scripts.event("onPlayerMiss", EventManager.get(NoteHitEvent).recycle(true, false, false, note, strumLines.members[playerID].characters, true, note != null ? note.noteType : null, "", "", "", directionID, -10, 0, -0.04, "shit"));
strumLine.onMiss.dispatch(event);
if (event.cancelled) return;
@@ -1647,44 +1584,44 @@ class PlayState extends MusicBeatState
return cpuStrums = s;
private function get_boyfriend():Character {
- if (strumLines != null && strumLines[1] != null)
- return strumLines[1].characters[0];
+ if (strumLines != null && strumLines.members[1] != null)
+ return strumLines.members[1].characters[0];
return null;
}
private function set_boyfriend(bf:Character):Character {
- if (strumLines != null && strumLines[1] != null)
- strumLines[1].characters = [bf];
+ if (strumLines != null && strumLines.members[1] != null)
+ strumLines.members[1].characters = [bf];
return bf;
}
private function get_dad():Character {
- if (strumLines != null && strumLines[0] != null)
- return strumLines[0].characters[0];
+ if (strumLines != null && strumLines.members[0] != null)
+ return strumLines.members[0].characters[0];
return null;
}
private function set_dad(dad:Character):Character {
- if (strumLines != null && strumLines[0] != null)
- strumLines[0].characters = [dad];
+ if (strumLines != null && strumLines.members[0] != null)
+ strumLines.members[0].characters = [dad];
return dad;
}
private function get_gf():Character {
- if (strumLines != null && strumLines[2] != null)
- return strumLines[2].characters[0];
+ if (strumLines != null && strumLines.members[2] != null)
+ return strumLines.members[2].characters[0];
return null;
}
private function set_gf(gf:Character):Character {
- if (strumLines != null && strumLines[2] != null)
- strumLines[2].characters = [gf];
+ if (strumLines != null && strumLines.members[2] != null)
+ strumLines.members[2].characters = [gf];
return gf;
}
private inline function get_cpuStrums():StrumLine
- return strumLines[0];
+ return strumLines.members[0];
private inline function get_playerStrums():StrumLine
- return strumLines[1];
+ return strumLines.members[1];
private inline function get_gfSpeed():Int
- return (strumLines[2] != null && strumLines[2].characters[0] != null) ? strumLines[2].characters[0].danceInterval : 1;
+ return (strumLines.members[2] != null && strumLines.members[2].characters[0] != null) ? strumLines.members[2].characters[0].danceInterval : 1;
private inline function set_gfSpeed(v:Int):Int {
- if (strumLines[2] != null && strumLines[2].characters[0] != null)
- strumLines[2].characters[0].danceInterval = v;
+ if (strumLines.members[2] != null && strumLines.members[2].characters[0] != null)
+ strumLines.members[2].characters[0].danceInterval = v;
return v;
}
diff --git a/source/funkin/game/Strum.hx b/source/funkin/game/Strum.hx
index f06d6b82..1e3b3d99 100644
--- a/source/funkin/game/Strum.hx
+++ b/source/funkin/game/Strum.hx
@@ -51,8 +51,12 @@ class Strum extends FlxSprite {
daNote.__noteAngle = getNotesAngle(daNote);
daNote.angle = daNote.isSustainNote ? daNote.__noteAngle : angle;
+ updateNotePos(daNote);
+ }
+
+ private inline function updateNotePos(daNote:Note) {
if (daNote.strumRelativePos) {
- daNote.setPosition((Note.swagWidth - daNote.width) / 2, (daNote.strumTime - Conductor.songPosition) * (0.45 * FlxMath.roundDecimal(getScrollSpeed(daNote), 2)));
+ daNote.setPosition((this.width - daNote.width) / 2, (daNote.strumTime - Conductor.songPosition) * (0.45 * FlxMath.roundDecimal(getScrollSpeed(daNote), 2)));
if (daNote.isSustainNote) daNote.y += N_WIDTHDIV2;
} else {
var offset = FlxPoint.get(0, (Conductor.songPosition - daNote.strumTime) * (0.45 * FlxMath.roundDecimal(getScrollSpeed(daNote), 2)));
@@ -104,8 +108,6 @@ class Strum extends FlxSprite {
case null:
playAnim("static");
}
- centerOffsets();
- centerOrigin();
}
public inline function press(time:Float) {
@@ -114,7 +116,6 @@ class Strum extends FlxSprite {
}
public function playAnim(anim:String, force:Bool = true) {
- var oldAnim = animation.curAnim;
animation.play(anim, force);
centerOffsets();
centerOrigin();
diff --git a/source/funkin/game/StrumLine.hx b/source/funkin/game/StrumLine.hx
index d8ab2b16..3d959738 100644
--- a/source/funkin/game/StrumLine.hx
+++ b/source/funkin/game/StrumLine.hx
@@ -27,6 +27,12 @@ class StrumLine extends FlxTypedGroup {
* `strumLine.onNoteUpdate.add(function(e:NoteUpdateEvent) {});`
*/
public var onNoteUpdate:FlxTypedSignalVoid> = new FlxTypedSignalVoid>();
+ /**
+ * Signal that triggers whenever a note is being updated. Similar to onNoteUpdate, except strumline specific.
+ * To add a listener, do
+ * `strumLine.onNoteUpdate.add(function(e:NoteUpdateEvent) {});`
+ */
+ public var onNoteDelete:FlxTypedSignalVoid> = new FlxTypedSignalVoid>();
/**
* Array containing all of the characters "attached" to those strums.
*/
@@ -112,7 +118,7 @@ class StrumLine extends FlxTypedGroup {
notes.draw();
}
- public function updateNotes() {
+ public inline function updateNotes() {
notes.forEach(updateNote);
}
@@ -121,7 +127,7 @@ class StrumLine extends FlxTypedGroup {
__updateNote_strum = members[daNote.noteData];
if (__updateNote_strum == null) return;
- PlayState.instance.scripts.event("onNoteUpdate", PlayState.instance.__updateNote_event.recycle(daNote, FlxG.elapsed, __updateNote_strum));
+ PlayState.instance.__updateNote_event.recycle(daNote, FlxG.elapsed, __updateNote_strum);
onNoteUpdate.dispatch(PlayState.instance.__updateNote_event);
if (PlayState.instance.__updateNote_event.cancelled) return;
@@ -133,7 +139,7 @@ class StrumLine extends FlxTypedGroup {
daNote.tooLate = true;
}
- if (PlayState.instance.__updateNote_event.__autoCPUHit && cpu && !daNote.wasGoodHit && daNote.strumTime < Conductor.songPosition) PlayState.instance.goodNoteHit(this, daNote);
+ if (cpu && PlayState.instance.__updateNote_event.__autoCPUHit && !daNote.wasGoodHit && daNote.strumTime < Conductor.songPosition) PlayState.instance.goodNoteHit(this, daNote);
if (daNote.wasGoodHit && daNote.isSustainNote && daNote.strumTime + (daNote.sustainLength) < Conductor.songPosition) {
deleteNote(daNote);
@@ -149,9 +155,78 @@ class StrumLine extends FlxTypedGroup {
if (PlayState.instance.__updateNote_event.strum == null) return;
if (PlayState.instance.__updateNote_event.__reposNote) PlayState.instance.__updateNote_event.strum.updateNotePosition(daNote);
- PlayState.instance.__updateNote_event.strum.updateSustain(daNote);
+ if (daNote.isSustainNote)
+ daNote.updateSustain(PlayState.instance.__updateNote_event.strum);
+ }
- PlayState.instance.scripts.event("onNotePostUpdate", PlayState.instance.__updateNote_event);
+ var __funcsToExec:ArrayVoid> = [];
+ var __pressed:Array = [];
+ var __justPressed:Array = [];
+ var __justReleased:Array = [];
+ var __notePerStrum:Array = [];
+
+ function __inputProcessPressed(note:Note) {
+ if (__pressed[note.strumID] && note.isSustainNote && note.canBeHit && !note.wasGoodHit) {
+ PlayState.instance.goodNoteHit(this, note);
+ }
+ }
+ function __inputProcessJustPressed(note:Note) {
+ if (__justPressed[note.strumID] && !note.isSustainNote && !note.wasGoodHit && note.canBeHit) {
+ if (__notePerStrum[note.strumID] == null) __notePerStrum[note.strumID] = note;
+ else if (Math.abs(__notePerStrum[note.strumID].strumTime - note.strumTime) <= 2) deleteNote(note);
+ else if (note.strumTime < __notePerStrum[note.strumID].strumTime) __notePerStrum[note.strumID] = note;
+ }
+ }
+ public function updateInput(id:Int = 0) {
+ updateNotes();
+
+ if (cpu) return;
+
+ __funcsToExec.clear();
+ __pressed.clear();
+ __justPressed.clear();
+ __justReleased.clear();
+
+ __pressed.pushGroup(controls.NOTE_LEFT, controls.NOTE_DOWN, controls.NOTE_UP, controls.NOTE_RIGHT);
+ __justPressed.pushGroup(controls.NOTE_LEFT_P, controls.NOTE_DOWN_P, controls.NOTE_UP_P, controls.NOTE_RIGHT_P);
+ __justReleased.pushGroup(controls.NOTE_LEFT_R, controls.NOTE_DOWN_R, controls.NOTE_UP_R, controls.NOTE_RIGHT_R);
+
+ var event = PlayState.instance.scripts.event("onKeyShit", EventManager.get(InputSystemEvent).recycle(__pressed, __justPressed, __justReleased, this, id));
+ if (event.cancelled) return;
+
+ __pressed = CoolUtil.getDefault(event.pressed, []);
+ __justPressed = CoolUtil.getDefault(event.justPressed, []);
+ __justReleased = CoolUtil.getDefault(event.justReleased, []);
+
+ __notePerStrum = [for(_ in 0...4) null];
+
+
+ if (__pressed.contains(true)) {
+ for(c in characters)
+ if (c.lastAnimContext != DANCE)
+ c.__lockAnimThisFrame = true;
+
+ __funcsToExec.push(__inputProcessPressed);
+ }
+ if (__justPressed.contains(true))
+ __funcsToExec.push(__inputProcessJustPressed);
+
+ if (__funcsToExec.length > 0) {
+ notes.forEachAlive(function(note:Note) {
+ for(e in __funcsToExec) if (e != null) e(note);
+ });
+ }
+
+ if (!ghostTapping) for(k=>pr in __justPressed) if (pr && __notePerStrum[k] == null) {
+ // FUCK YOU
+ PlayState.instance.noteMiss(this, null, k, ID);
+ }
+ for(e in __notePerStrum) if (e != null) PlayState.instance.goodNoteHit(this, e);
+
+ forEach(function(str:Strum) {
+ str.updatePlayerInput(__pressed[str.ID], __justPressed[str.ID], __justReleased[str.ID]);
+ });
+ PlayState.instance.scripts.call("onPostKeyShit");
}
public inline function addHealth(health:Float)
@@ -163,7 +238,7 @@ class StrumLine extends FlxTypedGroup {
var babyArrow:Strum = new Strum((FlxG.width * strumOffset) + (Note.swagWidth * (i - 2)), PlayState.instance.strumLine.y);
babyArrow.ID = i;
- var event = PlayState.instance.scripts.event("onStrumCreation", EventManager.get(StrumCreationEvent).recycle(babyArrow, PlayState.instance.strumLines.indexOf(this), i));
+ var event = PlayState.instance.scripts.event("onStrumCreation", EventManager.get(StrumCreationEvent).recycle(babyArrow, PlayState.instance.strumLines.members.indexOf(this), i));
if (!event.cancelled) {
babyArrow.frames = Paths.getFrames(event.sprite);
@@ -219,7 +294,8 @@ class StrumLine extends FlxTypedGroup {
*/
public function deleteNote(note:Note) {
if (note == null) return;
- var event:SimpleNoteEvent = PlayState.instance.scripts.event("onNoteDelete", EventManager.get(SimpleNoteEvent).recycle(note));
+ var event:SimpleNoteEvent = EventManager.get(SimpleNoteEvent).recycle(note);
+ onNoteDelete.dispatch(event);
if (!event.cancelled) {
note.kill();
notes.remove(note, true);