A basic system for replacing and overriding music within KF2. I do not know if this is fully compilable because the workshop upload tool is now broken and I'm too lazy to setup everything to run via KFEditor Make but I did leave comments for most everything.
BaseMusicGRI.uc
KFMusicManager.uc
KFMusicTrackInfo_Custom.uc
BaseMusicGRI.uc
Code:
class BaseMusicGRI extends KFGameReplicationInfo;
/************************************
* Music Manager
************************************/
/** Class that is spawned, replace this from a mutator to update or change the music system. */
var class<KFMusicManager> MusicManagerClass;
/** The spawned manager everything music related goes through this */
var KFMusicManager MusicManager;
/** Spawn and setup the manager class for music */
simulated function ReceivedGameClass()
{
MusicManager = Spawn(MusicManagerClass, Self);
MusicManager.GRIOwner = Self;
Super.ReceivedGameClass();
}
/** Redirect the default music system through the music manager but else fallback to the default behavior */
simulated function PlayNewMusicTrack( optional bool bGameStateChanged, optional bool bForceAmbient )
{
if( MusicManager != None )
{
MusicManager.SelectMusicTrack(bGameStateChanged, bForceAmbient);
}
else
{
Super.PlayNewMusicTrack(bGameStateChanged, bForceAmbient);
}
}
simulated function ForceNewMusicTrack( KFMusicTrackInfo ForcedTrackInfo )
{
if( MusicManager != None )
{
MusicManager.ForceMusicTrack(ForcedTrackInfo);
}
else
{
Super.ForceNewMusicTrack(ForcedTrackInfo);
}
}
defaultproperties
{
MusicManagerClass=class'KFMusicManager'
}
KFMusicManager.uc
Code:
//=============================================================================
// KFMusicManager
//=============================================================================
// A class spawned by the GameReplicationInfo to handle playing music.
//=============================================================================
class KFMusicManager extends Info;
/** The KFGameReplicationInfo that owns this class */
var KFGameReplicationInfo GRIOwner;
/** Current SoundCue component that is used when SoundCue music is playing */
var AudioComponent MusicComp;
simulated function SetupMusicTrack( KFMusicTrackInfo NextMusicTrackInfo, bool bPlayStandardTrack )
{
local KFMusicTrackInfo_Custom CustomInfo;
local SoundCue CurrentTrack;
local KFPlayerController KFPC;
CustomInfo = KFMusicTrackInfo_Custom(NextMusicTrackInfo);
/** If the selected track is not a custom track or is AkEvent music */
if( CustomInfo == None || CustomInfo.StandardTrack != None )
{
GRIOwner.UpdateMusicTrack(NextMusicTrackInfo, bPlayStandardTrack);
return;
}
/** The sound track was a SoundCue so lets select the correct version then play it */
if( bPlayStandardTrack )
{
CurrentTrack = SoundCue(CustomInfo.StandardSong);
}
else
{
CurrentTrack = SoundCue(CustomInfo.InstrumentalSong);
}
/** Set the music track info in the GRI */
GRIOwner.CurrentMusicTrackInfo = CustomInfo;
/** Force the SoundCue to the Music type so that the music volume slider changes the volume of the played Cue */
CurrentTrack.SoundClass = 'Music';
/** Stop the original system from spamming songs */
GRIOwner.bPendingMusicTrackChange = false;
GRIOwner.MusicComp = None;
/** Play the SoundCue */
PlayMusicSoundCue(CurrentTrack);
/** Display the music ScaleForm GUI and assign the music name and artist */
foreach WorldInfo.AllControllers(class'KFPlayerController', KFPC)
{
KFPC.TeamMessage(KFPC.PlayerReplicationInfo, CustomInfo.TrackName$" -- "$CustomInfo.ArtistName, 'Music');
}
}
simulated function PlayMusicSoundCue(SoundCue MusicTrack)
{
local AudioComponent A;
/** Fadeout any currently playing SoundCue music */
if( MusicComp != None )
{
MusicComp.FadeOut(5.0f, 0.0);
MusicComp = None;
}
/** Create a AudioComponent */
A = WorldInfo.CreateAudioComponent(MusicTrack, false, false, false,, false);
if( A != None )
{
/** Basic settings to tell the AudioComponent that this is music */
A.bAutoDestroy = true;
A.bShouldRemainActiveIfDropped = true;
A.bIsMusic = true;
/** Play the music by fading it in and then setting the MusicComp var to the AudioComponent */
A.FadeIn(5.0f, 1.0f);
MusicComp = A;
}
}
/** A basic delegate function that you can replace to override what happens when a music track is selected and wants to be played */
delegate OnMusicTrackSelected(KFMusicTrackInfo Track)
{
SetupMusicTrack( Track, KFGameEngine(Class'Engine'.static.GetEngine()).bMusicVocalsEnabled );
}
simulated function SelectMusicTrack( optional bool bGameStateChanged, optional bool bForceAmbient )
{
local KFMapInfo KFMI;
local class<KFGameInfo> KFGameClass;
local KFMusicTrackInfo NextMusicTrackInfo;
local bool bLoop;
local bool bPlayActionTrack;
if ( class'KFGameEngine'.static.CheckNoMusic() )
{
return;
}
KFGameClass = class<KFGameInfo>(GRIOwner.GameClass);
if ( KFGameClass == None )
{
return;
}
// @todo: consider using music intensity (255?) for ambient music to simplify this logic
bPlayActionTrack = (!bForceAmbient && KFGameClass.static.ShouldPlayActionMusicTrack(GRIOwner));
// if we've just transitioned into the "action" phase of the game,
// check if we need to delay the action music
if( bGameStateChanged )
{
if( bPlayActionTrack )
{
if( KFGameClass.default.ActionMusicDelay > 0 )
{
SetTimer( KFGameClass.default.ActionMusicDelay, false, nameof(SelectMusicTrack) );
return;
}
}
}
else if( GRIOwner.CurrentMusicTrackInfo != none )
{
bLoop = GRIOwner.CurrentMusicTrackInfo.bLoop;
}
// loop if we're designated to loop or this is the boss wave
if( bLoop || GRIOwner.IsFinalWave() )
{
NextMusicTrackInfo = GRIOwner.CurrentMusicTrackInfo;
}
else
{
KFMI = KFMapInfo(WorldInfo.GetMapInfo());
if ( KFMI != none )
{
NextMusicTrackInfo = KFMI.GetNextMusicTrackByGameIntensity(bPlayActionTrack, GRIOwner.MusicIntensity);
}
else
{
// Some maps might not be setup correctly, let's just grab a random default song
NextMusicTrackInfo = class'KFMapInfo'.static.StaticGetRandomTrack(bPlayActionTrack);
}
}
OnMusicTrackSelected(NextMusicTrackInfo);
}
simulated function SelectBossMusicTrack( KFMusicTrackInfo BossTrack )
{
OnMusicTrackSelected(BossTrack);
}
simulated function ForceMusicTrack( KFMusicTrackInfo ForcedTrackInfo )
{
local int Index;
local class<KFGameInfo> KFGameClass;
/** Check if the music being forced is boss music */
KFGameClass = class<KFGameInfo>(GRIOwner.GameClass);
if( KFGameClass != None )
{
/** Look for the track inside of ForcedMusicTracks inside the GameInfo and if it's not the main menu music then call SelectBossMusicTrack */
Index = KFGameClass.default.ForcedMusicTracks.Find(ForcedTrackInfo);
if( Index != INDEX_NONE && KFGameClass.default.ForcedMusicTracks[Index].Name != 'TrackInfo' )
{
SelectBossMusicTrack(ForcedTrackInfo);
return;
}
}
OnMusicTrackSelected(ForcedTrackInfo);
}
defaultproperties
{
bAlwaysRelevant=True
RemoteRole=ROLE_SimulatedProxy
}
KFMusicTrackInfo_Custom.uc
Code:
class KFMusicTrackInfo_Custom extends KFMusicTrackInfo;
var() AkBaseSoundObject StandardSong;
var() AkBaseSoundObject InstrumentalSong;
defaultproperties
{
}
Last edited: