aboutsummaryrefslogtreecommitdiff
path: root/Northstar.CustomServers/mod/scripts/vscripts/mp
diff options
context:
space:
mode:
authorJack <66967891+ASpoonPlaysGames@users.noreply.github.com>2023-11-05 12:31:30 +0000
committerGitHub <noreply@github.com>2023-11-05 13:31:30 +0100
commit318561f5a6a1f965bca5caaef962ea1deb6f6b31 (patch)
tree8399ff7ab6912f45bfe5684d92d60c89a232a793 /Northstar.CustomServers/mod/scripts/vscripts/mp
parent5076bea54cfb2f88d5420ede0c207fb77dc5be05 (diff)
downloadNorthstarMods-318561f5a6a1f965bca5caaef962ea1deb6f6b31.tar.gz
NorthstarMods-318561f5a6a1f965bca5caaef962ea1deb6f6b31.zip
Re-implement projectile kill replays (#723)v1.20.0-rc2v1.20.0-rc1
Adds a new callback: `SetCallback_TryUseProjectileReplay` so that servers can write logic to enable/disable this behaviour on a case by case basis
Diffstat (limited to 'Northstar.CustomServers/mod/scripts/vscripts/mp')
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut10
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut34
2 files changed, 38 insertions, 6 deletions
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 c11ca36f..9288f75e 100644
--- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut
@@ -295,6 +295,10 @@ void function PostDeathThread_MP( entity player, var damageInfo ) // based on ga
})
entity attacker = DamageInfo_GetAttacker( damageInfo )
+ entity inflictor = DamageInfo_GetInflictor( damageInfo )
+ int eHandle = attacker.GetEncodedEHandle()
+ if ( inflictor && ShouldTryUseProjectileReplay( player, attacker, damageInfo, false ) )
+ eHandle = inflictor.GetEncodedEHandle()
int methodOfDeath = DamageInfo_GetDamageSourceIdentifier( damageInfo )
table<int, bool> alreadyAssisted
@@ -374,7 +378,7 @@ void function PostDeathThread_MP( entity player, var damageInfo ) // based on ga
if ( "respawnTime" in attacker.s )
respawnTime = Time() - expect float ( attacker.s.respawnTime )
- thread PlayerWatchesKillReplayWrapper( player, attacker, respawnTime, timeOfDeath, beforeTime, replayTracker )
+ thread PlayerWatchesKillReplayWrapper( player, attacker, eHandle, respawnTime, timeOfDeath, beforeTime, replayTracker )
}
player.SetPlayerSettings( "spectator" ) // prevent a crash with going from titan => pilot on respawn
@@ -432,7 +436,7 @@ void function ForceRespawnMeSignalAfterDelay( entity player, int delay = 5 )
player.Signal( "RespawnMe" )
}
-void function PlayerWatchesKillReplayWrapper( entity player, entity attacker, float timeSinceAttackerSpawned, float timeOfDeath, float beforeTime, table replayTracker )
+void function PlayerWatchesKillReplayWrapper( entity player, entity attacker, int eHandle, float timeSinceAttackerSpawned, float timeOfDeath, float beforeTime, table replayTracker )
{
player.EndSignal( "RespawnMe" )
player.EndSignal( "OnRespawned" )
@@ -455,7 +459,7 @@ void function PlayerWatchesKillReplayWrapper( entity player, entity attacker, fl
})
player.SetPredictionEnabled( false )
- PlayerWatchesKillReplay( player, attacker.GetEncodedEHandle(), attacker.GetIndexForEntity(), timeSinceAttackerSpawned, timeOfDeath, beforeTime, replayTracker )
+ PlayerWatchesKillReplay( player, eHandle, attacker.GetIndexForEntity(), timeSinceAttackerSpawned, timeOfDeath, beforeTime, replayTracker )
}
void function DecideRespawnPlayer( entity player )
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut
index 3426cec5..4c52a9bf 100644
--- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut
@@ -13,6 +13,8 @@ global function SetTimerBased
global function SetShouldUseRoundWinningKillReplay
global function SetRoundWinningKillReplayKillClasses
global function SetRoundWinningKillReplayAttacker
+global function SetCallback_TryUseProjectileReplay
+global function ShouldTryUseProjectileReplay
global function SetWinner
global function SetTimeoutWinnerDecisionFunc
global function AddTeamScore
@@ -48,13 +50,28 @@ struct {
float roundWinningKillReplayTime
entity roundWinningKillReplayVictim
entity roundWinningKillReplayAttacker
+ int roundWinningKillReplayInflictorEHandle // this is either the inflictor or the attacker
int roundWinningKillReplayMethodOfDeath
float roundWinningKillReplayTimeOfDeath
float roundWinningKillReplayHealthFrac
array<void functionref()> roundEndCleanupCallbacks
+ bool functionref( entity victim, entity attacker, var damageInfo, bool isRoundEnd ) shouldTryUseProjectileReplayCallback
} file
+void function SetCallback_TryUseProjectileReplay( bool functionref( entity victim, entity attacker, var damageInfo, bool isRoundEnd ) callback )
+{
+ file.shouldTryUseProjectileReplayCallback = callback
+}
+
+bool function ShouldTryUseProjectileReplay( entity victim, entity attacker, var damageInfo, bool isRoundEnd )
+{
+ if ( file.shouldTryUseProjectileReplayCallback != null )
+ return file.shouldTryUseProjectileReplayCallback( victim, attacker, damageInfo, isRoundEnd )
+ // default to true (vanilla behaviour)
+ return true
+}
+
void function PIN_GameStart()
{
// todo: using the pin telemetry function here, weird and was done veeery early on before i knew how this all worked, should use a different one
@@ -319,6 +336,7 @@ void function GameStateEnter_WinnerDetermined_Threaded()
WaitFrame() // prevent a race condition with PlayerWatchesRoundWinningKillReplay
file.roundWinningKillReplayAttacker = null // clear this
+ file.roundWinningKillReplayInflictorEHandle = -1
if ( killcamsWereEnabled )
SetKillcamsEnabled( true )
@@ -394,7 +412,7 @@ void function PlayerWatchesRoundWinningKillReplay( entity player, float replayLe
if ( IsValid( attacker ) )
{
player.SetKillReplayDelay( Time() - replayLength, THIRD_PERSON_KILL_REPLAY_ALWAYS )
- player.SetKillReplayInflictorEHandle( attacker.GetEncodedEHandle() )
+ player.SetKillReplayInflictorEHandle( file.roundWinningKillReplayInflictorEHandle )
player.SetKillReplayVictim( file.roundWinningKillReplayVictim )
player.SetViewIndex( attacker.GetIndexForEntity() )
player.SetIsReplayRoundWinning( true )
@@ -460,6 +478,7 @@ void function GameStateEnter_SwitchingSides_Threaded()
svGlobal.levelEnt.Signal( "RoundEnd" ) // might be good to get a new signal for this? not 100% necessary tho i think
SetServerVar( "switchedSides", 1 )
file.roundWinningKillReplayAttacker = null // reset this after replay
+ file.roundWinningKillReplayInflictorEHandle = -1
if ( file.usePickLoadoutScreen )
SetGameState( eGameState.PickLoadout )
@@ -483,7 +502,7 @@ void function PlayerWatchesSwitchingSidesKillReplay( entity player, bool doRepla
entity attacker = file.roundWinningKillReplayAttacker
player.SetKillReplayDelay( Time() - replayLength, THIRD_PERSON_KILL_REPLAY_ALWAYS )
- player.SetKillReplayInflictorEHandle( attacker.GetEncodedEHandle() )
+ player.SetKillReplayInflictorEHandle( file.roundWinningKillReplayInflictorEHandle )
player.SetKillReplayVictim( file.roundWinningKillReplayVictim )
player.SetViewIndex( attacker.GetIndexForEntity() )
player.SetIsReplayRoundWinning( true )
@@ -578,6 +597,9 @@ void function OnPlayerKilled( entity victim, entity attacker, var damageInfo )
return
}
+ entity inflictor = DamageInfo_GetInflictor( damageInfo )
+ bool shouldUseInflictor = IsValid( inflictor ) && ShouldTryUseProjectileReplay( victim, attacker, damageInfo, true )
+
// set round winning killreplay info here if we're tracking pilot kills
// todo: make this not count environmental deaths like falls, unsure how to prevent this
if ( file.roundWinningKillReplayTrackPilotKills && victim != attacker && attacker != svGlobal.worldspawn && IsValid( attacker ) )
@@ -587,6 +609,7 @@ void function OnPlayerKilled( entity victim, entity attacker, var damageInfo )
file.roundWinningKillReplayTime = Time()
file.roundWinningKillReplayVictim = victim
file.roundWinningKillReplayAttacker = attacker
+ file.roundWinningKillReplayInflictorEHandle = ( shouldUseInflictor ? inflictor : attacker ).GetEncodedEHandle()
file.roundWinningKillReplayMethodOfDeath = DamageInfo_GetDamageSourceIdentifier( damageInfo )
file.roundWinningKillReplayTimeOfDeath = Time()
file.roundWinningKillReplayHealthFrac = GetHealthFrac( attacker )
@@ -637,6 +660,9 @@ void function OnTitanKilled( entity victim, var damageInfo )
return
}
+ entity inflictor = DamageInfo_GetInflictor( damageInfo )
+ bool shouldUseInflictor = IsValid( inflictor ) && ShouldTryUseProjectileReplay( victim, DamageInfo_GetAttacker( damageInfo ), damageInfo, true )
+
// set round winning killreplay info here if we're tracking titan kills
// todo: make this not count environmental deaths like falls, unsure how to prevent this
entity attacker = DamageInfo_GetAttacker( damageInfo )
@@ -647,6 +673,7 @@ void function OnTitanKilled( entity victim, var damageInfo )
file.roundWinningKillReplayTime = Time()
file.roundWinningKillReplayVictim = victim
file.roundWinningKillReplayAttacker = attacker
+ file.roundWinningKillReplayInflictorEHandle = ( shouldUseInflictor ? inflictor : attacker ).GetEncodedEHandle()
file.roundWinningKillReplayMethodOfDeath = DamageInfo_GetDamageSourceIdentifier( damageInfo )
file.roundWinningKillReplayTimeOfDeath = Time()
file.roundWinningKillReplayHealthFrac = GetHealthFrac( attacker )
@@ -761,11 +788,12 @@ void function SetRoundWinningKillReplayKillClasses( bool pilot, bool titan )
file.roundWinningKillReplayTrackTitanKills = titan // player kills in titans should get tracked anyway, might be worth renaming this
}
-void function SetRoundWinningKillReplayAttacker( entity attacker )
+void function SetRoundWinningKillReplayAttacker( entity attacker, int inflictorEHandle = -1 )
{
file.roundWinningKillReplayTime = Time()
file.roundWinningKillReplayHealthFrac = GetHealthFrac( attacker )
file.roundWinningKillReplayAttacker = attacker
+ file.roundWinningKillReplayInflictorEHandle = inflictorEHandle == -1 ? attacker.GetEncodedEHandle() : inflictorEHandle
file.roundWinningKillReplayTimeOfDeath = Time()
}