Skip to content

Commit

Permalink
Clean up several messy chunks of code, and add support for dragging n…
Browse files Browse the repository at this point in the history
…otes and events.
  • Loading branch information
EliteMasterEric committed Oct 26, 2023
1 parent 8d87594 commit eec3ac3
Show file tree
Hide file tree
Showing 59 changed files with 4,409 additions and 3,522 deletions.
30 changes: 25 additions & 5 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
"files.eol": "\n",

"haxe.displayPort": "auto",
"haxe.enableCompilationServer": true,
"haxe.enableCompilationServer": false,
"haxe.displayServer": {
"arguments": ["-v"]
},
Expand All @@ -97,14 +97,34 @@
"args": ["-debug"]
},
{
"label": "Windows / Debug (DEBUG ASSETS)",
"label": "Windows / Debug (FlxAnimate Test)",
"target": "windows",
"args": ["-debug", "-DDEBUG_ASSETS"]
"args": ["-debug", "-DANIMATE"]
},
{
"label": "Windows / Debug (ANIMATE)",
"label": "Windows / Debug (Straight to Freeplay)",
"target": "windows",
"args": ["-debug", "-DANIMATE"]
"args": ["-debug", "-DFREEPLAY"]
},
{
"label": "Windows / Debug (Straight to Play - Bopeebo Normal)",
"target": "windows",
"args": ["-debug", "-DSONG=bopeebo -DDIFFICULTY=normal"]
},
{
"label": "Windows / Debug (Straight to Chart Editor)",
"target": "windows",
"args": ["-debug", "-DCHARTING"]
},
{
"label": "Windows / Debug (Straight to Animation Editor)",
"target": "windows",
"args": ["-debug", "-DANIMDEBUG"]
},
{
"label": "Windows / Debug (Latency Test)",
"target": "windows",
"args": ["-debug", "-DLATENCY"]
},
{
"label": "HTML5 / Debug",
Expand Down
2 changes: 1 addition & 1 deletion assets
9 changes: 8 additions & 1 deletion docs/style-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Example:
```
/**
* Finds the largest deviation from the desired time inside this VoicesGroup.
*
*
* @param targetTime The time to check against.
* If none is provided, it checks the time of all members against the first member of this VoicesGroup.
* @return The largest deviation from the target time found.
Expand Down Expand Up @@ -52,3 +52,10 @@ import sys.io.File;
#end
```

## Argument Formatting

[Optional arguments](https://haxe.org/manual/types-function-optional-arguments.html) and [default arguments](https://haxe.org/manual/types-function-default-values.html) should be mutually exclusive and not used together!

For example, `myFunction(?input:Int)` should be used if you want the argument to be a `Null<Int>` whose value is `null` if no value is passed, and `myFunction(input:Int = 0)` should be used if you want the argument to be an `Int`, whose value is `0` if no value is passed.

Using both at the same time is considered valid by Haxe, but `myFunction(?input:Int = 0)` results in a `Null<Int>` whose value defaults to 0 anyway, so it's never null, but it's annotated as nullable! The biggest consequence of this is that it makes null safety more annoying.
4 changes: 4 additions & 0 deletions source/funkin/InitState.hx
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,10 @@ class InitState extends FlxState
return;
}

// Load and cache the song's charts.
// TODO: Do this in the loading state.
songData.cacheCharts(true);

LoadingState.loadAndSwitchState(new funkin.play.PlayState(
{
targetSong: songData,
Expand Down
14 changes: 7 additions & 7 deletions source/funkin/MusicBeatState.hx
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ class MusicBeatState extends FlxTransitionableState implements IEventHandler

public function stepHit():Bool
{
var event = new SongTimeScriptEvent(ScriptEventType.SONG_STEP_HIT, Conductor.currentBeat, Conductor.currentStep);
var event = new SongTimeScriptEvent(SONG_STEP_HIT, Conductor.currentBeat, Conductor.currentStep);

dispatchEvent(event);

Expand All @@ -128,7 +128,7 @@ class MusicBeatState extends FlxTransitionableState implements IEventHandler

public function beatHit():Bool
{
var event = new SongTimeScriptEvent(ScriptEventType.SONG_BEAT_HIT, Conductor.currentBeat, Conductor.currentStep);
var event = new SongTimeScriptEvent(SONG_BEAT_HIT, Conductor.currentBeat, Conductor.currentStep);

dispatchEvent(event);

Expand All @@ -148,7 +148,7 @@ class MusicBeatState extends FlxTransitionableState implements IEventHandler

override function startOutro(onComplete:() -> Void):Void
{
var event = new StateChangeScriptEvent(ScriptEventType.STATE_CHANGE_BEGIN, null, true);
var event = new StateChangeScriptEvent(STATE_CHANGE_BEGIN, null, true);

dispatchEvent(event);

Expand All @@ -164,7 +164,7 @@ class MusicBeatState extends FlxTransitionableState implements IEventHandler

public override function openSubState(targetSubState:FlxSubState):Void
{
var event = new SubStateScriptEvent(ScriptEventType.SUBSTATE_OPEN_BEGIN, targetSubState, true);
var event = new SubStateScriptEvent(SUBSTATE_OPEN_BEGIN, targetSubState, true);

dispatchEvent(event);

Expand All @@ -175,12 +175,12 @@ class MusicBeatState extends FlxTransitionableState implements IEventHandler

function onOpenSubStateComplete(targetState:FlxSubState):Void
{
dispatchEvent(new SubStateScriptEvent(ScriptEventType.SUBSTATE_OPEN_END, targetState, true));
dispatchEvent(new SubStateScriptEvent(SUBSTATE_OPEN_END, targetState, true));
}

public override function closeSubState():Void
{
var event = new SubStateScriptEvent(ScriptEventType.SUBSTATE_CLOSE_BEGIN, this.subState, true);
var event = new SubStateScriptEvent(SUBSTATE_CLOSE_BEGIN, this.subState, true);

dispatchEvent(event);

Expand All @@ -191,6 +191,6 @@ class MusicBeatState extends FlxTransitionableState implements IEventHandler

function onCloseSubStateComplete(targetState:FlxSubState):Void
{
dispatchEvent(new SubStateScriptEvent(ScriptEventType.SUBSTATE_CLOSE_END, targetState, true));
dispatchEvent(new SubStateScriptEvent(SUBSTATE_CLOSE_END, targetState, true));
}
}
4 changes: 2 additions & 2 deletions source/funkin/MusicBeatSubState.hx
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class MusicBeatSubState extends FlxTransitionableSubState implements IEventHandl
*/
public function stepHit():Bool
{
var event:ScriptEvent = new SongTimeScriptEvent(ScriptEventType.SONG_STEP_HIT, Conductor.currentBeat, Conductor.currentStep);
var event:ScriptEvent = new SongTimeScriptEvent(SONG_STEP_HIT, Conductor.currentBeat, Conductor.currentStep);

dispatchEvent(event);

Expand All @@ -112,7 +112,7 @@ class MusicBeatSubState extends FlxTransitionableSubState implements IEventHandl
*/
public function beatHit():Bool
{
var event:ScriptEvent = new SongTimeScriptEvent(ScriptEventType.SONG_BEAT_HIT, Conductor.currentBeat, Conductor.currentStep);
var event:ScriptEvent = new SongTimeScriptEvent(SONG_BEAT_HIT, Conductor.currentBeat, Conductor.currentStep);

dispatchEvent(event);

Expand Down
119 changes: 79 additions & 40 deletions source/funkin/data/song/SongData.hx
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ class SongChartData
}
}

class SongEventData
class SongEventDataRaw
{
/**
* The timestamp of the event. The timestamp is in the format of the song's time format.
Expand Down Expand Up @@ -503,40 +503,57 @@ class SongEventData

return _stepTime = Conductor.getTimeInSteps(this.time);
}
}

/**
* Wrap SongEventData in an abstract so we can overload operators.
*/
@:forward(time, event, value, activated, getStepTime)
abstract SongEventData(SongEventDataRaw) from SongEventDataRaw to SongEventDataRaw
{
public function new(time:Float, event:String, value:Dynamic = null)
{
this = new SongEventDataRaw(time, event, value);
}

public inline function getDynamic(key:String):Null<Dynamic>
{
return value == null ? null : Reflect.field(value, key);
return this.value == null ? null : Reflect.field(this.value, key);
}

public inline function getBool(key:String):Null<Bool>
{
return value == null ? null : cast Reflect.field(value, key);
return this.value == null ? null : cast Reflect.field(this.value, key);
}

public inline function getInt(key:String):Null<Int>
{
return value == null ? null : cast Reflect.field(value, key);
return this.value == null ? null : cast Reflect.field(this.value, key);
}

public inline function getFloat(key:String):Null<Float>
{
return value == null ? null : cast Reflect.field(value, key);
return this.value == null ? null : cast Reflect.field(this.value, key);
}

public inline function getString(key:String):String
{
return value == null ? null : cast Reflect.field(value, key);
return this.value == null ? null : cast Reflect.field(this.value, key);
}

public inline function getArray(key:String):Array<Dynamic>
{
return value == null ? null : cast Reflect.field(value, key);
return this.value == null ? null : cast Reflect.field(this.value, key);
}

public inline function getBoolArray(key:String):Array<Bool>
{
return value == null ? null : cast Reflect.field(value, key);
return this.value == null ? null : cast Reflect.field(this.value, key);
}

public function clone():SongEventData
{
return new SongEventData(this.time, this.event, this.value);
}

@:op(A == B)
Expand Down Expand Up @@ -584,7 +601,7 @@ class SongEventData
}
}

class SongNoteData
class SongNoteDataRaw
{
/**
* The timestamp of the note. The timestamp is in the format of the song's time format.
Expand Down Expand Up @@ -655,6 +672,48 @@ class SongNoteData
return _stepTime = Conductor.getTimeInSteps(this.time);
}

@:jignored
var _stepLength:Null<Float> = null;

/**
* @param force Set to `true` to force recalculation (good after BPM changes)
* @return The length of the hold note in steps, or `0` if this is not a hold note.
*/
public function getStepLength(force = false):Float
{
if (this.length <= 0) return 0.0;

if (_stepLength != null && !force) return _stepLength;

return _stepLength = Conductor.getTimeInSteps(this.time + this.length) - getStepTime();
}

public function setStepLength(value:Float):Void
{
if (value <= 0)
{
this.length = 0.0;
}
else
{
var lengthMs:Float = Conductor.getStepTimeInMs(value) - this.time;
this.length = lengthMs;
}
_stepLength = null;
}
}

/**
* Wrap SongNoteData in an abstract so we can overload operators.
*/
@:forward
abstract SongNoteData(SongNoteDataRaw) from SongNoteDataRaw to SongNoteDataRaw
{
public function new(time:Float, data:Int, length:Float = 0, kind:String = '')
{
this = new SongNoteDataRaw(time, data, length, kind);
}

/**
* The direction of the note, if applicable.
* Strips the strumline index from the data.
Expand All @@ -668,7 +727,12 @@ class SongNoteData

public function getDirectionName(strumlineSize:Int = 4):String
{
switch (this.data % strumlineSize)
return SongNoteData.buildDirectionName(this.data, strumlineSize);
}

public static function buildDirectionName(data:Int, strumlineSize:Int = 4):String
{
switch (data % strumlineSize)
{
case 0:
return 'Left';
Expand Down Expand Up @@ -705,36 +769,6 @@ class SongNoteData
return getStrumlineIndex(strumlineSize) == 0;
}

@:jignored
var _stepLength:Null<Float> = null;

/**
* @param force Set to `true` to force recalculation (good after BPM changes)
* @return The length of the hold note in steps, or `0` if this is not a hold note.
*/
public function getStepLength(force = false):Float
{
if (this.length <= 0) return 0.0;

if (_stepLength != null && !force) return _stepLength;

return _stepLength = Conductor.getTimeInSteps(this.time + this.length) - getStepTime();
}

public function setStepLength(value:Float):Void
{
if (value <= 0)
{
this.length = 0.0;
}
else
{
var lengthMs:Float = Conductor.getStepTimeInMs(value) - this.time;
this.length = lengthMs;
}
_stepLength = null;
}

@:jignored
public var isHoldNote(get, never):Bool;

Expand Down Expand Up @@ -797,6 +831,11 @@ class SongNoteData
return this.time <= other.time;
}

public function clone():SongNoteData
{
return new SongNoteData(this.time, this.data, this.length, this.kind);
}

/**
* Produces a string representation suitable for debugging.
*/
Expand Down
8 changes: 7 additions & 1 deletion source/funkin/data/song/SongDataUtils.hx
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,14 @@ class SongDataUtils

var result = notes.filter(function(note:SongNoteData):Bool {
for (x in subtrahend)
{
// The currently iterated note is in the subtrahend array.
// SongNoteData's == operation has been overridden so that this will work.
if (x == note) return false;
if (x == note)
{
return false;
}
}

return true;
});
Expand Down
2 changes: 2 additions & 0 deletions source/funkin/import.hx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ using Lambda;
using StringTools;
using funkin.util.tools.ArraySortTools;
using funkin.util.tools.ArrayTools;
using funkin.util.tools.FloatTools;
using funkin.util.tools.Int64Tools;
using funkin.util.tools.IntTools;
using funkin.util.tools.IteratorTools;
using funkin.util.tools.MapTools;
using funkin.util.tools.SongEventDataArrayTools;
Expand Down
Loading

0 comments on commit eec3ac3

Please sign in to comment.