diff options
Diffstat (limited to 'Northstar.CustomServers/mod/scripts/vscripts/mp')
6 files changed, 146 insertions, 62 deletions
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_ai_mp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_ai_mp.gnut index ac0c309b..4cbab84c 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_ai_mp.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_ai_mp.gnut @@ -30,12 +30,12 @@ bool function IsAutoPopulateEnabled( var team = null ) return true } -void function SPMP_UpdateNPCProficiency(entity ent) +void function SPMP_UpdateNPCProficiency( entity ent ) { } -bool function SPMP_Callback_ForceAIMissPlayer(entity npc, entity player) +bool function SPMP_Callback_ForceAIMissPlayer( entity npc, entity player ) { return true }
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut index d7db601b..38803e04 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut @@ -219,6 +219,7 @@ void function CodeCallback_OnPlayerRespawned( entity player ) player.s.respawnTime = Time() Loadouts_TryGivePilotLoadout( player ) + SetHumanRagdollImpactTable( player ) foreach ( void functionref( entity ) callback in svGlobal.onPlayerRespawnedCallbacks ) callback( player ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_classic_mp.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_classic_mp.nut index ac8a397f..66bb3d6a 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_classic_mp.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_classic_mp.nut @@ -1,53 +1,80 @@ untyped global function ClassicMp_Init -global function ClassicMP_TryDefaultIntroSetup // called in mp_sh_init +global function ClassicMP_TryDefaultIntroSetup + +// intro setups +global function ClassicMP_SetLevelIntro global function ClassicMP_SetCustomIntro +global function ClassicMP_SetupIntro + +// intro funcs global function ClassicMP_OnIntroStarted global function ClassicMP_OnIntroFinished global function ClassicMP_GetIntroLength + +// epilogue setups +global function ClassicMP_ForceDisableEpilogue +global function ClassicMP_SetEpilogue +global function ClassicMP_SetupEpilogue +global function ClassicMP_ShouldRunEpilogue + global function GetClassicMPMode struct { - void functionref() introSetupFunc - float introLength + // level intros have a lower priority than custom intros + // level intros are used only if a custom intro was not specified + void functionref() levelIntroSetupFunc + float levelIntroLength + + void functionref() customIntroSetupFunc + float customIntroLength + + bool epilogueForceDisabled = false + void functionref() epilogueSetupFunc } file void function ClassicMp_Init() { - // literally nothing to do here atm lol + // default level intros + if ( IsFFAGame() ) + ClassicMP_SetLevelIntro( ClassicMP_DefaultNoIntro_Setup, ClassicMP_DefaultNoIntro_GetLength() ) + else + ClassicMP_SetLevelIntro( ClassicMP_DefaultDropshipIntro_Setup, DROPSHIP_INTRO_LENGTH ) } +// stub func, called in mp_sh_init void function ClassicMP_TryDefaultIntroSetup() { - if ( file.introSetupFunc == null ) - { - if ( IsFFAGame() ) - ClassicMP_SetCustomIntro( ClassicMP_DefaultNoIntro_Setup, ClassicMP_DefaultNoIntro_GetLength() ) - else - ClassicMP_SetCustomIntro( ClassicMP_DefaultDropshipIntro_Setup, DROPSHIP_INTRO_LENGTH ) - } - - thread DelayedDoDefaultIntroSetup() + } -void function DelayedDoDefaultIntroSetup() +void function ClassicMP_SetLevelIntro( void functionref() setupFunc, float introLength ) { - // wait a frame for CodeCallback_MapInit to run which generally sets custom intros - WaitFrame() - file.introSetupFunc() + file.levelIntroSetupFunc = setupFunc + file.levelIntroLength = introLength } void function ClassicMP_SetCustomIntro( void functionref() setupFunc, float introLength ) { - file.introSetupFunc = setupFunc - file.introLength = introLength + file.customIntroSetupFunc = setupFunc + file.customIntroLength = introLength +} + +void function ClassicMP_SetupIntro() +{ + if ( file.customIntroSetupFunc != null ) + file.customIntroSetupFunc() + else + file.levelIntroSetupFunc() } void function ClassicMP_OnIntroStarted() { print( "started intro!" ) - SetServerVar( "gameStartTime", Time() + file.introLength ) - SetServerVar( "roundStartTime", Time() + file.introLength ) + + float introLength = ClassicMP_GetIntroLength() + SetServerVar( "gameStartTime", Time() + introLength ) + SetServerVar( "roundStartTime", Time() + introLength ) } void function ClassicMP_OnIntroFinished() @@ -58,10 +85,37 @@ void function ClassicMP_OnIntroFinished() float function ClassicMP_GetIntroLength() { - return file.introLength + if ( file.customIntroSetupFunc != null ) + return file.customIntroLength + + return file.levelIntroLength +} + +void function ClassicMP_ForceDisableEpilogue( bool disabled ) +{ + file.epilogueForceDisabled = disabled +} + +void function ClassicMP_SetEpilogue( void functionref() setupFunc ) +{ + file.epilogueSetupFunc = setupFunc +} + +void function ClassicMP_SetupEpilogue() +{ + if ( file.epilogueSetupFunc == null ) // default is evac + ClassicMP_SetEpilogue( EvacEpilogueSetup ) + + file.epilogueSetupFunc() } bool function GetClassicMPMode() { return GetCurrentPlaylistVarInt( "classic_mp", 1 ) == 1 +} + +bool function ClassicMP_ShouldRunEpilogue() +{ + // note: there is a run_evac playlist var, but it's unused, and default 0, so use a new one + return !file.epilogueForceDisabled && GetClassicMPMode() && !IsRoundBased() && GetCurrentPlaylistVarInt( "run_epilogue", 1 ) == 1 }
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut index 197ac5e9..e3f7e0b0 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut @@ -92,7 +92,8 @@ void function SetGameState( int newState ) void function GameState_EntitiesDidLoad() { - // nothing of importance to put here, this is referenced in _gamestate though so need it + if ( GetClassicMPMode() ) + ClassicMP_SetupIntro() } void function WaittillGameStateOrHigher( int gameState ) @@ -185,9 +186,29 @@ void function GameStateEnter_Prematch() int timeLimit = GameMode_GetTimeLimit( GAMETYPE ) * 60 if ( file.switchSidesBased ) timeLimit /= 2 // endtime is half of total per side - + SetServerVar( "gameEndTime", Time() + timeLimit + ClassicMP_GetIntroLength() ) SetServerVar( "roundEndTime", Time() + ClassicMP_GetIntroLength() + GameMode_GetRoundTimeLimit( GAMETYPE ) * 60 ) + + if ( !GetClassicMPMode() ) + thread StartGameWithoutClassicMP() +} + +void function StartGameWithoutClassicMP() +{ + WaitFrame() // wait for callbacks to finish + + // need these otherwise game will complain + SetServerVar( "gameStartTime", Time() ) + SetServerVar( "roundStartTime", Time() ) + + foreach ( entity player in GetPlayerArray() ) + { + RespawnAsPilot( player ) + ScreenFadeFromBlack( player, 0 ) + } + + SetGameState( eGameState.Playing ) } @@ -246,38 +267,53 @@ void function GameStateEnter_WinnerDetermined() void function GameStateEnter_WinnerDetermined_Threaded() { - bool killcamsWereEnabled = KillcamsEnabled() - if ( killcamsWereEnabled ) // dont want killcams to interrupt stuff - SetKillcamsEnabled( false ) - + // do win announcement + int winningTeam = GetWinningTeam() + + foreach ( entity player in GetPlayerArray() ) + { + int announcementSubstr + if ( winningTeam != TEAM_UNASSIGNED ) + announcementSubstr = player.GetTeam() == winningTeam ? file.announceRoundWinnerWinningSubstr : file.announceRoundWinnerLosingSubstr + + if ( IsRoundBased() ) + Remote_CallFunction_NonReplay( player, "ServerCallback_AnnounceRoundWinner", GetWinningTeam(), announcementSubstr, ROUND_WINNING_KILL_REPLAY_SCREEN_FADE_TIME, GameRules_GetTeamScore2( TEAM_MILITIA ), GameRules_GetTeamScore2( TEAM_IMC ) ) + else + Remote_CallFunction_NonReplay( player, "ServerCallback_AnnounceWinner", GetWinningTeam(), announcementSubstr, ROUND_WINNING_KILL_REPLAY_SCREEN_FADE_TIME ) + } + WaitFrame() // wait a frame so other scripts can setup killreplay stuff entity replayAttacker = file.roundWinningKillReplayAttacker - bool doReplay = Replay_IsEnabled() && !( !IsRoundBased() && Evac_IsEnabled() ) && IsRoundWinningKillReplayEnabled() && IsValid( replayAttacker ) + bool doReplay = Replay_IsEnabled() && !ClassicMP_ShouldRunEpilogue() && IsRoundWinningKillReplayEnabled() && IsValid( replayAttacker ) && Time() - file.roundWinningKillReplayTime <= ROUND_WINNING_KILL_REPLAY_LENGTH_OF_REPLAY float replayLength = 2.0 // extra delay if no replay if ( doReplay ) { + bool killcamsWereEnabled = KillcamsEnabled() + if ( killcamsWereEnabled ) // dont want killcams to interrupt stuff + SetKillcamsEnabled( false ) + replayLength = ROUND_WINNING_KILL_REPLAY_LENGTH_OF_REPLAY if ( "respawnTime" in replayAttacker.s && Time() - replayAttacker.s.respawnTime < replayLength ) replayLength += Time() - expect float ( replayAttacker.s.respawnTime ) SetServerVar( "roundWinningKillReplayEntHealthFrac", file.roundWinningKillReplayHealthFrac ) - } - - foreach ( entity player in GetPlayerArray() ) - thread PlayerWatchesRoundWinningKillReplay( player, doReplay, replayLength ) - - wait ROUND_WINNING_KILL_REPLAY_SCREEN_FADE_TIME - CleanUpEntitiesForRoundEnd() // fade should be done by this point, so cleanup stuff now when people won't see - wait replayLength - - WaitFrame() // prevent a race condition with PlayerWatchesRoundWinningKillReplay - file.roundWinningKillReplayAttacker = null // clear this + + foreach ( entity player in GetPlayerArray() ) + thread PlayerWatchesRoundWinningKillReplay( player, doReplay, replayLength ) - if ( killcamsWereEnabled ) - SetKillcamsEnabled( true ) + wait ROUND_WINNING_KILL_REPLAY_SCREEN_FADE_TIME + CleanUpEntitiesForRoundEnd() // fade should be done by this point, so cleanup stuff now when people won't see + wait replayLength + + WaitFrame() // prevent a race condition with PlayerWatchesRoundWinningKillReplay + file.roundWinningKillReplayAttacker = null // clear this + + if ( killcamsWereEnabled ) + SetKillcamsEnabled( true ) + } if ( IsRoundBased() ) { @@ -299,8 +335,11 @@ void function GameStateEnter_WinnerDetermined_Threaded() } else { - if ( Evac_IsEnabled() ) + if ( ClassicMP_ShouldRunEpilogue() ) + { + ClassicMP_SetupEpilogue() SetGameState( eGameState.Epilogue ) + } else SetGameState( eGameState.Postmatch ) } @@ -309,18 +348,8 @@ void function GameStateEnter_WinnerDetermined_Threaded() void function PlayerWatchesRoundWinningKillReplay( entity player, bool doReplay, float replayLength ) { player.FreezeControlsOnServer() - - int winningTeam = GetWinningTeam() - int announcementSubstr - if ( winningTeam != TEAM_UNASSIGNED ) - announcementSubstr = player.GetTeam() == winningTeam ? file.announceRoundWinnerWinningSubstr : file.announceRoundWinnerLosingSubstr - - if ( IsRoundBased() ) - Remote_CallFunction_NonReplay( player, "ServerCallback_AnnounceRoundWinner", winningTeam, announcementSubstr, ROUND_WINNING_KILL_REPLAY_SCREEN_FADE_TIME, GameRules_GetTeamScore2( TEAM_MILITIA ), GameRules_GetTeamScore2( TEAM_IMC ) ) - else - Remote_CallFunction_NonReplay( player, "ServerCallback_AnnounceWinner", winningTeam, announcementSubstr, ROUND_WINNING_KILL_REPLAY_SCREEN_FADE_TIME ) - if ( IsRoundBased() || !Evac_IsEnabled() ) // if we're doing evac, then no fades or killreplay + if ( IsRoundBased() || !ClassicMP_ShouldRunEpilogue() ) // if we're doing evac, then no fades or killreplay { ScreenFadeToBlackForever( player, ROUND_WINNING_KILL_REPLAY_SCREEN_FADE_TIME ) wait ROUND_WINNING_KILL_REPLAY_SCREEN_FADE_TIME diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/_lf_maps_shared.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/_lf_maps_shared.gnut index d61d6baa..178b6560 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/_lf_maps_shared.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/_lf_maps_shared.gnut @@ -4,5 +4,5 @@ global function SetupLiveFireMaps void function SetupLiveFireMaps() { Riff_ForceTitanAvailability( eTitanAvailability.Never ) - ClassicMP_SetCustomIntro( ClassicMP_DefaultNoIntro_Setup, ClassicMP_DefaultNoIntro_GetLength() ) + ClassicMP_SetLevelIntro( ClassicMP_DefaultNoIntro_Setup, ClassicMP_DefaultNoIntro_GetLength() ) }
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_angel_city.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_angel_city.nut index 68b49ad5..87c9ea98 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_angel_city.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_angel_city.nut @@ -2,12 +2,12 @@ global function CodeCallback_MapInit void function CodeCallback_MapInit() { - Evac_AddLocation( < 2527.889893, -2865.360107, 753.002991 >, < 0, -80.54, 0 > ) - Evac_AddLocation( < 1253.530029, -554.075012, 811.125 >, < 0, 180, 0 > ) - Evac_AddLocation( < 2446.989990, 809.364014, 576.0 >, < 0, 90.253, 0 > ) - Evac_AddLocation( < -2027.430054, 960.395020, 609.007996 >, < 0, 179.604, 0 > ) + AddEvacNode( CreateScriptRef( < 2527.889893, -2865.360107, 753.002991 >, < 0, -80.54, 0 > ) ) + AddEvacNode( CreateScriptRef( < 1253.530029, -554.075012, 811.125 >, < 0, 180, 0 > ) ) + AddEvacNode( CreateScriptRef( < 2446.989990, 809.364014, 576.0 >, < 0, 90.253, 0 > ) ) + AddEvacNode( CreateScriptRef( < -2027.430054, 960.395020, 609.007996 >, < 0, 179.604, 0 > ) ) - Evac_SetSpacePosition( < -1700, -5500, -7600 >, < -3.620642, 270.307129, 0 > ) + SetEvacSpaceNode( CreateScriptRef( < -1700, -5500, -7600 >, < -3.620642, 270.307129, 0 > ) ) // todo: also we need to change the powerup spawns on this map, they use a version from an older patch |