Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 81 additions & 38 deletions source/funkin/game/Note.hx
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,7 @@ class Note extends FlxSprite

static var DEFAULT_FIELDS:Array<String> = ["time", "id", "type", "sLen"];

public function new(strumLine:StrumLine, noteData:ChartNote, sustain:Bool = false, sustainLength:Float = 0, sustainOffset:Float = 0, ?prev:Note)
{
public function new(strumLine:StrumLine, noteData:ChartNote, sustain:Bool = false, sustainLength:Float = 0, sustainOffset:Float = 0, ?prev:Note) {
super();

moves = false;
Expand Down Expand Up @@ -241,23 +240,13 @@ class Note extends FlxSprite
*/
public var strumRelativePos:Bool = true;

override function drawComplex(camera:FlxCamera) {
var downscrollCam = (camera is HudCamera ? ({var _:HudCamera=cast camera;_;}).downscroll : false);
if (updateFlipY) flipY = (isSustainNote && flipSustain) && (downscrollCam != (__strum != null && __strum.getScrollSpeed(this) < 0));
if (downscrollCam && __strum != null) {
final xx = x;
x += origin.x - offset.x;
x -= __strum.x; x *= -1; x += __strum.x;
x -= origin.x - offset.x;
x += __strum.width; // ??? maybe this isnt good
super.drawComplex(camera);
x = xx;
} else
super.drawComplex(camera);
}

static var __notePosFrameOffset:FlxPoint = new FlxPoint();
static var __posPoint:FlxPoint = new FlxPoint();
@:dox(hide) static var __lastAngle:Float = Math.NaN;
@:dox(hide) static var __lastAngleSin:Float = 0;
@:dox(hide) static var __lastAngleCos:Float = 0;
@:dox(hide) static var __lastStrumW:Float = Math.NaN;
@:dox(hide) static var __lastStrumH:Float = Math.NaN;
@:dox(hide) static var __lastStrumHalfW:Float = 0;
@:dox(hide) static var __lastStrumHalfH:Float = 0;

override function draw() {
@:privateAccess var oldDefaultCameras = FlxCamera._defaultCameras;
Expand All @@ -266,16 +255,28 @@ class Note extends FlxSprite
var negativeScroll = isSustainNote && strumRelativePos && lastScrollSpeed < 0;
if (negativeScroll) y -= height;
if (__strum != null && strumRelativePos) {
final pos = __posPoint.set(x, y);
// distance = pos.y , we can use it safely like this
final xx = -origin.x + offset.x + (pos.y * Math.cos((__noteAngle + 90) * FlxAngle.TO_RAD));
final yy = -origin.y + offset.y + (pos.y * Math.sin((__noteAngle + 90) * FlxAngle.TO_RAD));
setPosition(
xx + __strum.x + (__strum.width * 0.5),
yy + __strum.y + (__strum.height * 0.5)
);
final originalX = x;
final originalY = y;

if (__noteAngle != __lastAngle) {
__lastAngle = __noteAngle;
final result = FlxMath.fastSinCos((__noteAngle + 90) * FlxAngle.TO_RAD);
__lastAngleSin = result.sin;
__lastAngleCos = result.cos;
}

if (__strum.width != __lastStrumW || __strum.height != __lastStrumH) {
__lastStrumW = __strum.width;
__lastStrumH = __strum.height;
__lastStrumHalfW = __strum.width * 0.5;
__lastStrumHalfH = __strum.height * 0.5;
}

x = -origin.x + offset.x + (originalY * __lastAngleCos) + __strum.x + __lastStrumHalfW;
y = -origin.y + offset.y + (originalY * __lastAngleSin) + __strum.y + __lastStrumHalfH;
super.draw();
setPosition(pos.x, pos.y);
x = originalX;
y = originalY;
} else {
super.draw();
}
Expand All @@ -284,6 +285,38 @@ class Note extends FlxSprite
@:privateAccess FlxCamera._defaultCameras = oldDefaultCameras;
}

var __lastDownscrollCam:Bool = false;
var __lastX:Float = 0;

@:noCompletion @:dox(hide) override function isOnScreen(?camera:FlxCamera):Bool {
var downscrollCam = (Std.isOfType(camera, HudCamera) ? cast(camera, HudCamera).downscroll : false);

if (downscrollCam == __lastDownscrollCam)
return super.isOnScreen(camera);
else
__lastX = x;

if (updateFlipY) flipY = (isSustainNote && flipSustain) && (downscrollCam != (__strum != null && __strum.getScrollSpeed(this) < 0));
if (downscrollCam && __strum != null) {
x = -x + 2 * (__strum.x - origin.x + offset.x) + __strum.width;
}
final isOnScreen = super.isOnScreen(camera);
return isOnScreen;
}

override function drawComplex(camera:FlxCamera):Void {
super.drawComplex(camera);

if (__lastDownscrollCam) {
__lastDownscrollCam = false;
x = __lastX;
}
}

public function isOnScreenOriginal(?camera:FlxCamera):Bool {
return super.isOnScreen(camera);
}

// The * 0.5 is so that it's easier to hit them too late, instead of too early
public var earlyPressWindow:Float = 0.5;
public var latePressWindow:Float = 1;
Expand All @@ -294,7 +327,7 @@ class Note extends FlxSprite
if (lastScrollSpeed != scrollSpeed) {
lastScrollSpeed = scrollSpeed;
if (nextSustain != null) {
scale.y = (sustainLength * 0.45 * Math.abs(scrollSpeed)) / frameHeight;
scale.y = (sustainLength * 0.45 * scrollSpeed) / frameHeight;
updateHitbox();
scale.y += gapFix / frameHeight;
}
Expand All @@ -304,18 +337,28 @@ class Note extends FlxSprite
}

public function updateSustainClip() if (wasGoodHit && !noSustainClip) {
var t = CoolUtil.bound((Conductor.songPosition - strumTime) / height * 0.45 * Math.abs(lastScrollSpeed), 0, 1);
var rect = clipRect == null ? FlxRect.get() : clipRect;
clipRect = rect.set(0, frameHeight * t, frameWidth, frameHeight * (1 - t));
var t = CoolUtil.bound((Conductor.songPosition - strumTime) / height * 0.45 * lastScrollSpeed, 0, 1);
@:bypassAccessor {
if (clipRect == null) clipRect = FlxRect.get();
clipRect.set(0, frameHeight * t, frameWidth, frameHeight * (1 - t));
}
@:privateAccess {
if (frame != null && _frame != null)
_frame = frame.clipTo(clipRect, _frame);
}
}

@:noCompletion
override function set_clipRect(rect:FlxRect):FlxRect
{
clipRect = rect;

if (frames != null)
frame = frames.frames[animation.frameIndex];
override function set_clipRect(rect:FlxRect):FlxRect {
@:bypassAccessor clipRect = rect;

@:privateAccess if (frame != null) {
if (rect != null && _frame != null)
_frame = frame.clipTo(rect, _frame);
else if (_frame != null)
_frame = frame.copyTo(_frame);
dirty = true;
}

return rect;
}
Expand Down
85 changes: 66 additions & 19 deletions source/funkin/game/Strum.hx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package funkin.game;

import flixel.math.FlxPoint;
import flixel.math.FlxAngle;
import flixel.util.typeLimit.OneOfTwo;
import funkin.backend.system.Conductor;

class Strum extends FlxSprite {
Expand Down Expand Up @@ -52,8 +53,27 @@ class Strum extends FlxSprite {
public var updateNotesPosY:Bool = true;
public var extraCopyFields(default, set):Array<String> = [];

private inline function set_extraCopyFields(val:Array<String>)
return extraCopyFields = val == null ? [] : val;
@:noCompletion public var __cachedCopyFields:Array<Array<OneOfTwo<String, Int>>> = null;

private function set_extraCopyFields(val:Array<String>) {
extraCopyFields = val == null ? [] : val;
__cachedCopyFields = null;
return extraCopyFields;
}

private inline function __initCachedCopyFields() {
if (__cachedCopyFields != null) return;
__cachedCopyFields = [for (field in extraCopyFields) CoolUtil.parsePropertyString(field)];
}

private inline function __applyCopyFields(daNote:Note) {
for (i in 0...extraCopyFields.length) {
final parsed = __cachedCopyFields[i];
final fromProp = CoolUtil.parseProperty(this, parsed);
final toProp = CoolUtil.parseProperty(daNote, parsed);
toProp.setValue(fromProp.getValue());
}
}

/**
* Whenever the strum is pressed.
Expand Down Expand Up @@ -129,13 +149,28 @@ class Strum extends FlxSprite {
}

public override function draw() {
lastDrawCameras = cameras.copy();
if (cameras.length == 1) {
if (lastDrawCameras.length != 1 || lastDrawCameras[0] != cameras[0]) {
lastDrawCameras = [cameras[0]];
}
} else {
lastDrawCameras = cameras.copy();
}
super.draw();
}

@:noCompletion public static inline final PIX180:Float = 565.4866776461628; // 180 * Math.PI
@:noCompletion public static final N_WIDTHDIV2:Float = Note.swagWidth / 2; // DEPRECATED

static var __lastStrumW:Float = Math.NaN;
static var __lastStrumH:Float = Math.NaN;
static var __lastStrumHalfW:Float = 0;
static var __lastStrumHalfH:Float = 0;
static var __noteOffset:FlxPoint = FlxPoint.get();
static var __lastNoteAngle:Float = Math.NaN;
static var __lastAngleCos:Float = 0;
static var __lastAngleSin:Float = 0;

/**
* Updates the position of a note.
* @param daNote The note
Expand All @@ -153,8 +188,10 @@ class Strum extends FlxSprite {
}

updateNotePos(daNote);
for (field in extraCopyFields)
CoolUtil.cloneProperty(daNote, field, this); // TODO: make this cached to reduce the reflection calls - Neo
if (extraCopyFields.length > 0) {
__initCachedCopyFields();
__applyCopyFields(daNote);
}
}

private inline function updateNotePos(daNote:Note) {
Expand All @@ -169,24 +206,34 @@ class Strum extends FlxSprite {
if (daNote.isSustainNote) daNote.y += daNote.height * 0.5;
}
} else {
if (width != __lastStrumW || height != __lastStrumH) {
__lastStrumW = width;
__lastStrumH = height;
__lastStrumHalfW = width * 0.5;
__lastStrumHalfH = height * 0.5;
}

if (daNote.__noteAngle != __lastNoteAngle) {
__lastNoteAngle = daNote.__noteAngle;
final result = FlxMath.fastSinCos((__lastNoteAngle + 90) * FlxAngle.TO_RAD);
__lastAngleCos = result.cos;
__lastAngleSin = result.sin;
}

final speed = getScrollSpeed(daNote);
final distance = (daNote.strumTime - Conductor.songPosition) * 0.45 * speed;
final __noteAngle = FlxMath.fastSinCos((daNote.__noteAngle + 90) * FlxAngle.TO_RAD);
final angleX = __noteAngle.cos;
final angleY = __noteAngle.sin;
final _noteOffset = FlxPoint.get(angleX * distance, angleY * distance);
_noteOffset.x += -daNote.origin.x + daNote.offset.x;
_noteOffset.y += -daNote.origin.y + daNote.offset.y;
__noteOffset.set(__lastAngleCos * distance, __lastAngleSin * distance);
__noteOffset.x += -daNote.origin.x + daNote.offset.x;
__noteOffset.y += -daNote.origin.y + daNote.offset.y;
if (daNote.isSustainNote) {
final m = (daNote.height * 0.5 * (speed < 0 ? -1 : 1)); // daNote.height works better than this.height in this case ???
_noteOffset.x += angleX * m;
_noteOffset.y += angleY * m;
final m = (daNote.height * 0.5 * (speed < 0 ? -1 : 1));
__noteOffset.x += __lastAngleCos * m;
__noteOffset.y += __lastAngleSin * m;
}
_noteOffset.x += x + (width * 0.5);
_noteOffset.y += y + (height * 0.5);
if (shouldX) daNote.x = _noteOffset.x;
if (shouldY) daNote.y = _noteOffset.y;
_noteOffset.put();
__noteOffset.x += x + __lastStrumHalfW;
__noteOffset.y += y + __lastStrumHalfH;
if (shouldX) daNote.x = __noteOffset.x;
if (shouldY) daNote.y = __noteOffset.y;
}
}
}
Expand Down