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:
parent
12335fef9d
commit
44623071cd
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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})';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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 + ')';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue