1
0
Fork 0
mirror of https://github.com/ninjamuffin99/Funkin.git synced 2025-06-27 13:06:26 +00:00

Redo event stuff for abot and game over audio logic

This commit is contained in:
EliteMasterEric 2024-02-18 03:02:36 -05:00
parent 12335fef9d
commit 44623071cd
11 changed files with 104 additions and 46 deletions

View file

@ -128,6 +128,7 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
function fixMaxVolume():Void
{
return;
#if lime_openal
// This code is pretty fragile, it reaches through 5 layers of private access.
@:privateAccess

View file

@ -108,8 +108,8 @@ class SongEventRegistry
public static function handleEvent(data:SongEventData):Void
{
var eventType:String = data.event;
var eventHandler:SongEvent = eventCache.get(eventType);
var eventKind:String = data.eventKind;
var eventHandler:SongEvent = eventCache.get(eventKind);
if (eventHandler != null)
{
@ -117,7 +117,7 @@ class SongEventRegistry
}
else
{
trace('WARNING: No event handler for event with id: ${eventType}');
trace('WARNING: No event handler for event with kind: ${eventKind}');
}
data.activated = true;

View file

@ -650,7 +650,7 @@ class SongEventDataRaw implements ICloneable<SongEventDataRaw>
* Custom events can be added by scripts with the `ScriptedSongEvent` class.
*/
@:alias("e")
public var event:String;
public var eventKind:String;
/**
* The data for the event.
@ -670,10 +670,10 @@ class SongEventDataRaw implements ICloneable<SongEventDataRaw>
@:jignored
public var activated:Bool = false;
public function new(time:Float, event:String, value:Dynamic = null)
public function new(time:Float, eventKind:String, value:Dynamic = null)
{
this.time = time;
this.event = event;
this.eventKind = eventKind;
this.value = value;
}
@ -689,19 +689,19 @@ class SongEventDataRaw implements ICloneable<SongEventDataRaw>
public function clone():SongEventDataRaw
{
return new SongEventDataRaw(this.time, this.event, this.value);
return new SongEventDataRaw(this.time, this.eventKind, this.value);
}
}
/**
* Wrap SongEventData in an abstract so we can overload operators.
*/
@:forward(time, event, value, activated, getStepTime, clone)
@:forward(time, eventKind, value, activated, getStepTime, clone)
abstract SongEventData(SongEventDataRaw) from SongEventDataRaw to SongEventDataRaw
{
public function new(time:Float, event:String, value:Dynamic = null)
public function new(time:Float, eventKind:String, value:Dynamic = null)
{
this = new SongEventDataRaw(time, event, value);
this = new SongEventDataRaw(time, eventKind, value);
}
public inline function valueAsStruct(?defaultKey:String = "key"):Dynamic
@ -728,12 +728,12 @@ abstract SongEventData(SongEventDataRaw) from SongEventDataRaw to SongEventDataR
public inline function getHandler():Null<SongEvent>
{
return SongEventRegistry.getEvent(this.event);
return SongEventRegistry.getEvent(this.eventKind);
}
public inline function getSchema():Null<SongEventSchema>
{
return SongEventRegistry.getEventSchema(this.event);
return SongEventRegistry.getEventSchema(this.eventKind);
}
public inline function getDynamic(key:String):Null<Dynamic>
@ -786,7 +786,7 @@ abstract SongEventData(SongEventDataRaw) from SongEventDataRaw to SongEventDataR
var eventHandler = getHandler();
var eventSchema = getSchema();
if (eventSchema == null) return 'Unknown Event: ${this.event}';
if (eventSchema == null) return 'Unknown Event: ${this.eventKind}';
var result = '${eventHandler.getTitle()}';
@ -811,19 +811,19 @@ abstract SongEventData(SongEventDataRaw) from SongEventDataRaw to SongEventDataR
public function clone():SongEventData
{
return new SongEventData(this.time, this.event, this.value);
return new SongEventData(this.time, this.eventKind, this.value);
}
@:op(A == B)
public function op_equals(other:SongEventData):Bool
{
return this.time == other.time && this.event == other.event && this.value == other.value;
return this.time == other.time && this.eventKind == other.eventKind && this.value == other.value;
}
@:op(A != B)
public function op_notEquals(other:SongEventData):Bool
{
return this.time != other.time || this.event != other.event || this.value != other.value;
return this.time != other.time || this.eventKind != other.eventKind || this.value != other.value;
}
@:op(A > B)
@ -855,7 +855,7 @@ abstract SongEventData(SongEventDataRaw) from SongEventDataRaw to SongEventDataR
*/
public function toString():String
{
return 'SongEventData(${this.time}ms, ${this.event}: ${this.value})';
return 'SongEventData(${this.time}ms, ${this.eventKind}: ${this.value})';
}
}

View file

@ -47,7 +47,7 @@ class SongDataUtils
public static function offsetSongEventData(events:Array<SongEventData>, offset:Float):Array<SongEventData>
{
return events.map(function(event:SongEventData):SongEventData {
return new SongEventData(event.time + offset, event.event, event.value);
return new SongEventData(event.time + offset, event.eventKind, event.value);
});
}

View file

@ -189,17 +189,17 @@ class SongEventScriptEvent extends ScriptEvent
* The note associated with this event.
* You cannot replace it, but you can edit it.
*/
public var event(default, null):funkin.data.song.SongData.SongEventData;
public var eventData(default, null):funkin.data.song.SongData.SongEventData;
public function new(event:funkin.data.song.SongData.SongEventData):Void
public function new(eventData:funkin.data.song.SongData.SongEventData):Void
{
super(SONG_EVENT, true);
this.event = event;
this.eventData = eventData;
}
public override function toString():String
{
return 'SongEventScriptEvent(event=' + event + ')';
return 'SongEventScriptEvent(event=' + eventData + ')';
}
}

View file

@ -4,6 +4,7 @@ import flixel.FlxG;
import flixel.FlxObject;
import flixel.FlxSprite;
import flixel.sound.FlxSound;
import funkin.audio.FunkinSound;
import flixel.util.FlxColor;
import flixel.util.FlxTimer;
import funkin.graphics.FunkinSprite;
@ -64,7 +65,7 @@ class GameOverSubState extends MusicBeatSubState
/**
* The music playing in the background of the state.
*/
var gameOverMusic:FlxSound = new FlxSound();
var gameOverMusic:Null<FunkinSound> = null;
/**
* Whether the player has confirmed and prepared to restart the level.
@ -72,6 +73,11 @@ class GameOverSubState extends MusicBeatSubState
*/
var isEnding:Bool = false;
/**
* Whether the death music is on its first loop.
*/
var isStarting:Bool = true;
var isChartingMode:Bool = false;
var transparent:Bool;
@ -141,10 +147,6 @@ class GameOverSubState extends MusicBeatSubState
// Set up the audio
//
// Prepare the game over music.
FlxG.sound.list.add(gameOverMusic);
gameOverMusic.stop();
// The conductor now represents the BPM of the game over music.
Conductor.instance.update(0);
}
@ -223,7 +225,7 @@ class GameOverSubState extends MusicBeatSubState
}
}
if (gameOverMusic.playing)
if (gameOverMusic != null && gameOverMusic.playing)
{
// Match the conductor to the music.
// This enables the stepHit and beatHit events.
@ -298,24 +300,71 @@ class GameOverSubState extends MusicBeatSubState
ScriptEventDispatcher.callEvent(boyfriend, event);
}
/**
* Rather than hardcoding stuff, we look for the presence of a music file
* with the given suffix, and strip it down until we find one that's valid.
*/
function resolveMusicPath(suffix:String, starting:Bool = false, ending:Bool = false):Null<String>
{
var basePath = 'gameplay/gameover/gameOver';
if (starting) basePath += 'Start';
else if (ending) basePath += 'End';
var musicPath = Paths.music(basePath + suffix);
while (!Assets.exists(musicPath) && suffix.length > 0)
{
suffix = suffix.split('-').slice(0, -1).join('-');
musicPath = Paths.music(basePath + suffix);
}
if (!Assets.exists(musicPath)) return null;
trace('Resolved music path: ' + musicPath);
return musicPath;
}
/**
* Starts the death music at the appropriate volume.
* @param startingVolume
*/
public function startDeathMusic(?startingVolume:Float = 1, force:Bool = false):Void
public function startDeathMusic(startingVolume:Float = 1, force:Bool = false):Void
{
var musicPath = Paths.music('gameplay/gameover/gameOver' + musicSuffix);
if (isEnding)
var musicPath = resolveMusicPath(musicSuffix, isStarting, isEnding);
var onComplete = null;
if (isStarting)
{
musicPath = Paths.music('gameplay/gameover/gameOverEnd' + musicSuffix);
if (musicPath == null)
{
isStarting = false;
musicPath = resolveMusicPath(musicSuffix, isStarting, isEnding);
}
else
{
isStarting = false;
onComplete = function() {
// We need to force to ensure that the non-starting music plays.
startDeathMusic(1.0, true);
};
}
}
if (!gameOverMusic.playing || force)
if (musicPath == null)
{
gameOverMusic.loadEmbedded(musicPath);
trace('Could not find game over music!');
return;
}
else if (gameOverMusic == null || !gameOverMusic.playing || force)
{
if (gameOverMusic != null) gameOverMusic.stop();
gameOverMusic = FunkinSound.load(musicPath);
gameOverMusic.volume = startingVolume;
gameOverMusic.looped = !isEnding;
gameOverMusic.looped = !(isEnding || isStarting);
gameOverMusic.onComplete = onComplete;
gameOverMusic.play();
}
else
{
@:privateAccess
trace('Music already playing! ${gameOverMusic?._label}');
}
}
static var blueballed:Bool = false;
@ -358,6 +407,14 @@ class GameOverSubState extends MusicBeatSubState
});
}
public override function destroy()
{
super.destroy();
if (gameOverMusic != null) gameOverMusic.stop();
gameOverMusic = null;
instance = null;
}
public override function toString():String
{
return "GameOverSubState";

View file

@ -3417,7 +3417,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
// Update the event sprite's position.
eventSprite.updateEventPosition(renderedEvents);
// Update the sprite's graphic. TODO: Is this inefficient?
eventSprite.playAnimation(eventSprite.eventData.event);
eventSprite.playAnimation(eventSprite.eventData.eventKind);
}
else
{
@ -4678,9 +4678,9 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
var eventData:SongEventData = gridGhostEvent.eventData != null ? gridGhostEvent.eventData : new SongEventData(cursorMs, eventKindToPlace, null);
if (eventKindToPlace != eventData.event)
if (eventKindToPlace != eventData.eventKind)
{
eventData.event = eventKindToPlace;
eventData.eventKind = eventKindToPlace;
}
eventData.time = cursorSnappedMs;

View file

@ -38,7 +38,7 @@ class SelectItemsCommand implements ChartEditorCommand
{
var eventSelected = this.events[0];
state.eventKindToPlace = eventSelected.event;
state.eventKindToPlace = eventSelected.eventKind;
// This code is here to parse event data that's not built as a struct for some reason.
// TODO: Clean this up or get rid of it.
@ -46,7 +46,7 @@ class SelectItemsCommand implements ChartEditorCommand
var defaultKey = null;
if (eventSchema == null)
{
trace('[WARNING] Event schema not found for event ${eventSelected.event}.');
trace('[WARNING] Event schema not found for event ${eventSelected.eventKind}.');
}
else
{

View file

@ -35,7 +35,7 @@ class SetItemSelectionCommand implements ChartEditorCommand
{
var eventSelected = this.events[0];
state.eventKindToPlace = eventSelected.event;
state.eventKindToPlace = eventSelected.eventKind;
// This code is here to parse event data that's not built as a struct for some reason.
// TODO: Clean this up or get rid of it.
@ -43,7 +43,7 @@ class SetItemSelectionCommand implements ChartEditorCommand
var defaultKey = null;
if (eventSchema == null)
{
trace('[WARNING] Event schema not found for event ${eventSelected.event}.');
trace('[WARNING] Event schema not found for event ${eventSelected.eventKind}.');
}
else
{

View file

@ -133,7 +133,7 @@ class ChartEditorEventSprite extends FlxSprite
public function playAnimation(?name:String):Void
{
if (name == null) name = eventData?.event ?? DEFAULT_EVENT;
if (name == null) name = eventData?.eventKind ?? DEFAULT_EVENT;
var correctedName = correctAnimationName(name);
this.animation.play(correctedName);
@ -160,7 +160,7 @@ class ChartEditorEventSprite extends FlxSprite
else
{
this.visible = true;
playAnimation(value.event);
playAnimation(value.eventKind);
this.eventData = value;
// Update the position to match the note data.
updateEventPosition();

View file

@ -90,7 +90,7 @@ class ChartEditorEventDataToolbox extends ChartEditorBaseToolbox
// Edit the event data of any selected events.
for (event in chartEditorState.currentEventSelection)
{
event.event = chartEditorState.eventKindToPlace;
event.eventKind = chartEditorState.eventKindToPlace;
event.value = chartEditorState.eventDataToPlace;
}
chartEditorState.saveDataDirty = true;
@ -255,7 +255,7 @@ class ChartEditorEventDataToolbox extends ChartEditorBaseToolbox
{
for (event in chartEditorState.currentEventSelection)
{
event.event = chartEditorState.eventKindToPlace;
event.eventKind = chartEditorState.eventKindToPlace;
event.value = chartEditorState.eventDataToPlace;
}
chartEditorState.saveDataDirty = true;