From 6df399f251bbaf8b43629ba023061eea67a37656 Mon Sep 17 00:00:00 2001 From: Jack <66967891+ASpoonPlaysGames@users.noreply.github.com> Date: Mon, 16 Oct 2023 13:53:02 +0100 Subject: Make dropships immune to Titan step damage (#737) Currently dropships take damage from titans stepping on them, this prevents that Co-authored-by: William Miller --- .../mod/scripts/vscripts/mp/_base_gametype_mp.gnut | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Northstar.CustomServers') 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 bab7eaed..c11ca36f 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut @@ -628,6 +628,10 @@ void function SetRecalculateRespawnAsTitanStartPointCallback( entity functionref bool function ShouldEntTakeDamage_SPMP( entity ent, var damageInfo ) { + // dropships are immune to being crushed + if ( ( IsDropship( ent ) || IsEvacDropship( ent ) ) && IsTitanCrushDamage( damageInfo ) ) + return false + return true } -- cgit v1.2.3 From 327e40edf85e9ad12b85256382123049d55fd07f Mon Sep 17 00:00:00 2001 From: Jack <66967891+ASpoonPlaysGames@users.noreply.github.com> Date: Tue, 17 Oct 2023 14:27:37 +0100 Subject: Award titan assist stats based on titan soul damage history (#746) Titans stores damage history in their Soul component, not the NPC itself, probably due to how game handles pilot/auto-titan interaction with the Titan entities. This means that we weren't awarding assist stats properly for titan assists --- Northstar.CustomServers/mod/scripts/vscripts/mp/_stats.nut | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'Northstar.CustomServers') diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_stats.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_stats.nut index 208e6da1..dbfcea61 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_stats.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_stats.nut @@ -571,9 +571,11 @@ void function HandleKillStats( entity victim, entity attacker, var damageInfo ) // assistsTotal ( weapon_kill_stats ) // note: eww table alreadyAssisted - foreach( DamageHistoryStruct attackerInfo in victim.e.recentDamageHistory ) + // titans store their recentDamageHistory in the soul + entity assistVictim = ( victim.IsTitan() && IsValid( victim.GetTitanSoul() ) ) ? victim.GetTitanSoul() : victim + foreach( DamageHistoryStruct attackerInfo in assistVictim.e.recentDamageHistory ) { - if ( !IsValid( attackerInfo.attacker ) || !attackerInfo.attacker.IsPlayer() || attackerInfo.attacker == victim ) + if ( !IsValid( attackerInfo.attacker ) || !attackerInfo.attacker.IsPlayer() || attackerInfo.attacker == assistVictim ) continue bool exists = attackerInfo.attacker.GetEncodedEHandle() in alreadyAssisted ? true : false -- cgit v1.2.3 From aa79ad4b924d838904169b4e251c27c5f09557db Mon Sep 17 00:00:00 2001 From: William Miller Date: Tue, 17 Oct 2023 21:41:01 -0300 Subject: Fix Titan Assist not tracking properly (#744) Titan Assist medals aren't given to players who assisted damage when someone kills a titan, that is due the fact that Titans stores damage history in their Soul component, not the NPC itself. --- .../mod/scripts/vscripts/mp/_score.nut | 25 +++++++++++++--------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'Northstar.CustomServers') diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut index 0b55e9ff..df7577aa 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut @@ -202,18 +202,23 @@ void function ScoreEvent_TitanKilled( entity victim, entity attacker, var damage AddPlayerScore( attacker, "KillTitan" ) } - table alreadyAssisted - foreach( DamageHistoryStruct attackerInfo in victim.e.recentDamageHistory ) + entity soul = victim.GetTitanSoul() + if ( IsValid( soul ) ) { - if ( !IsValid( attackerInfo.attacker ) || !attackerInfo.attacker.IsPlayer() || attackerInfo.attacker == victim ) - continue - - bool exists = attackerInfo.attacker.GetEncodedEHandle() in alreadyAssisted ? true : false - if( attackerInfo.attacker != attacker && !exists ) + table alreadyAssisted + + foreach( DamageHistoryStruct attackerInfo in soul.e.recentDamageHistory ) { - alreadyAssisted[attackerInfo.attacker.GetEncodedEHandle()] <- true - AddPlayerScore(attackerInfo.attacker, "TitanAssist" ) - Remote_CallFunction_NonReplay( attackerInfo.attacker, "ServerCallback_SetAssistInformation", attackerInfo.damageSourceId, attacker.GetEncodedEHandle(), victim.GetEncodedEHandle(), attackerInfo.time ) + if ( !IsValid( attackerInfo.attacker ) || !attackerInfo.attacker.IsPlayer() || attackerInfo.attacker == soul ) + continue + + bool exists = attackerInfo.attacker.GetEncodedEHandle() in alreadyAssisted ? true : false + if( attackerInfo.attacker != attacker && !exists ) + { + alreadyAssisted[attackerInfo.attacker.GetEncodedEHandle()] <- true + AddPlayerScore(attackerInfo.attacker, "TitanAssist" ) + Remote_CallFunction_NonReplay( attackerInfo.attacker, "ServerCallback_SetAssistInformation", attackerInfo.damageSourceId, attacker.GetEncodedEHandle(), soul.GetEncodedEHandle(), attackerInfo.time ) + } } } -- cgit v1.2.3 From d84d875347b54e87dfada23f516f89cf507be610 Mon Sep 17 00:00:00 2001 From: Jack <66967891+ASpoonPlaysGames@users.noreply.github.com> Date: Wed, 18 Oct 2023 19:34:47 +0100 Subject: Stop logging invalid map/mode exception in progression (#750) Some game modes like Gun Game or Infection are not considered valid yet, causing the warning message to be spammed in the logs. Necessary work should be done to add the modes to the list of valid modes. Until we will just comment out the print statement in order to prevent log spam. Co-authored-by: GeckoEidechse <40122905+GeckoEidechse@users.noreply.github.com> --- Northstar.CustomServers/mod/scripts/vscripts/mp/_stats.nut | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Northstar.CustomServers') diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_stats.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_stats.nut index dbfcea61..63841f7a 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_stats.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_stats.nut @@ -264,7 +264,7 @@ void function Stats_IncrementStat( entity player, string statCategory, string st // persistence string, we can't save the persistence so we have to just return if ( str != saveVar ) { - printt( ex ) + //printt( ex, str, GetMapName(), mode ) // Commented out due to spamming logs on invalid modes (e.g. Gun Game, Infection, ...) return } } -- cgit v1.2.3 From faff062f6cbdac84803ced8a7c6e69dd7731af57 Mon Sep 17 00:00:00 2001 From: Jack <66967891+ASpoonPlaysGames@users.noreply.github.com> Date: Fri, 3 Nov 2023 16:10:40 +0000 Subject: Don't mark items as new if progression is disabled (#752) Also doesn't show the challenge completion notifications in game as a nice side effect --- Northstar.CustomServers/mod/scripts/vscripts/_items.nut | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Northstar.CustomServers') diff --git a/Northstar.CustomServers/mod/scripts/vscripts/_items.nut b/Northstar.CustomServers/mod/scripts/vscripts/_items.nut index a5c3e270..a23a68b0 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/_items.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/_items.nut @@ -10231,6 +10231,10 @@ void function StatUnlock_Unlocked( entity player, string itemRef, string parentR if ( IsItemNew( player, itemRef, parentRef ) ) return + // early out if the player has progression disabled + if ( !ProgressionEnabledForPlayer( player ) ) + return + int refGuid = file.itemRefToGuid[itemRef] int parentRefGuid = parentRef == "" ? 0 : file.itemRefToGuid[parentRef] -- cgit v1.2.3 From dfeaba7208deff89de67f32271c0d5c5a44746f1 Mon Sep 17 00:00:00 2001 From: William Miller Date: Fri, 3 Nov 2023 13:15:42 -0300 Subject: Fix wrong Item Type for Titan Camos (#728) Small fix which the wrong item type was being addressed to check for Titan Camos, allowing players to use any camo without fallback to default if they didn't own that item previously when enabling progression. --- Northstar.CustomServers/mod/scripts/vscripts/sh_progression.nut | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Northstar.CustomServers') diff --git a/Northstar.CustomServers/mod/scripts/vscripts/sh_progression.nut b/Northstar.CustomServers/mod/scripts/vscripts/sh_progression.nut index ceb5e837..496e8b42 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/sh_progression.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/sh_progression.nut @@ -268,7 +268,7 @@ void function ValidateEquippedItems( entity player ) // camoIndex if ( loadout.skinIndex == TITAN_SKIN_INDEX_CAMO ) { - array camoSkins = GetAllItemsOfType( eItemTypes.CAMO_SKIN ) + array camoSkins = GetAllItemsOfType( eItemTypes.CAMO_SKIN_TITAN ) if ( loadout.camoIndex >= camoSkins.len() || loadout.camoIndex < 0 ) { printt( " - INVALID TITAN CAMO/SKIN, RESETTING" ) @@ -363,7 +363,7 @@ void function ValidateEquippedItems( entity player ) // primeCamoIndex if ( loadout.primeSkinIndex == TITAN_SKIN_INDEX_CAMO ) { - array camoSkins = GetAllItemsOfType( eItemTypes.CAMO_SKIN ) + array camoSkins = GetAllItemsOfType( eItemTypes.CAMO_SKIN_TITAN ) if ( loadout.primeCamoIndex >= camoSkins.len() || loadout.primeCamoIndex < 0 ) { printt( " - INVALID TITAN CAMO/SKIN, RESETTING" ) -- cgit v1.2.3 From 54fae18d727aa84fb6eb45de4f9479aba3361158 Mon Sep 17 00:00:00 2001 From: William Miller Date: Fri, 3 Nov 2023 13:17:34 -0300 Subject: Fix wrong attacker receiving progression stat updates (#755) Fixes wrong attacker receiving stat updates --- Northstar.CustomServers/mod/scripts/vscripts/mp/_stats.nut | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Northstar.CustomServers') diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_stats.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_stats.nut index 63841f7a..bd64e4ca 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_stats.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_stats.nut @@ -587,7 +587,7 @@ void function HandleKillStats( entity victim, entity attacker, var damageInfo ) string source = DamageSourceIDToString( attackerInfo.damageSourceId ) if ( IsValidStatItemString( source ) ) - Stats_IncrementStat( attacker, "weapon_kill_stats", "assistsTotal", source, 1.0 ) + Stats_IncrementStat( attackerInfo.attacker, "weapon_kill_stats", "assistsTotal", source, 1.0 ) } } -- cgit v1.2.3 From 318561f5a6a1f965bca5caaef962ea1deb6f6b31 Mon Sep 17 00:00:00 2001 From: Jack <66967891+ASpoonPlaysGames@users.noreply.github.com> Date: Sun, 5 Nov 2023 12:31:30 +0000 Subject: Re-implement projectile kill replays (#723) Adds a new callback: `SetCallback_TryUseProjectileReplay` so that servers can write logic to enable/disable this behaviour on a case by case basis --- .../mod/scripts/vscripts/mp/_base_gametype_mp.gnut | 10 +++++-- .../mod/scripts/vscripts/mp/_gamestate_mp.nut | 34 ++++++++++++++++++++-- 2 files changed, 38 insertions(+), 6 deletions(-) (limited to 'Northstar.CustomServers') 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 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 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() } -- cgit v1.2.3 From 4e394ce4f7cdf18a4acea8db6ff85fc6f858d45e Mon Sep 17 00:00:00 2001 From: Jack <66967891+ASpoonPlaysGames@users.noreply.github.com> Date: Tue, 21 Nov 2023 01:22:45 +0000 Subject: Implement missing Score Events (#700) * use consts for killingspree and rampage score events * add Revenge and Quick Revenge score events * ensure no revenge/quick revenge against non-players * this is OnPlayerKilled i dont need this check * implement mayhem and onslaught --- .../mod/scripts/vscripts/mp/_score.nut | 50 +++++++++++++++++++++- 1 file changed, 48 insertions(+), 2 deletions(-) (limited to 'Northstar.CustomServers') diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut index df7577aa..be20982d 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut @@ -28,6 +28,10 @@ void function InitPlayerForScoreEvents( entity player ) player.s.currentKillstreak <- 0 player.s.lastKillTime <- 0.0 player.s.currentTimedKillstreak <- 0 + player.s.lastKillTime_Mayhem <- 0.0 + player.s.currentTimedKillstreak_Mayhem <- 0 + player.s.lastKillTime_Onslaught <- 0.0 + player.s.currentTimedKillstreak_Onslaught <- 0 } void function AddPlayerScore( entity targetPlayer, string scoreEventName, entity associatedEnt = null, string noideawhatthisis = "", int pointValueOverride = -1 ) @@ -93,6 +97,7 @@ void function ScoreEvent_PlayerKilled( entity victim, entity attacker, var damag victim.s.currentTimedKillstreak = 0 victim.p.numberOfDeathsSinceLastKill++ // this is reset on kill + victim.p.lastKiller = attacker // have to do this early before we reset victim's player killstreaks // nemesis when you kill a player that is dominating you @@ -131,12 +136,20 @@ void function ScoreEvent_PlayerKilled( entity victim, entity attacker, var damag attacker.p.numberOfDeathsSinceLastKill = 0 } + // revenge + quick revenge + if ( attacker.p.lastKiller == victim ) + { + if ( Time() - GetPlayerLastRespawnTime( attacker ) < QUICK_REVENGE_TIME_LIMIT ) + AddPlayerScore( attacker, "QuickRevenge" ) + else + AddPlayerScore( attacker, "Revenge" ) + } // untimed killstreaks attacker.s.currentKillstreak++ - if ( attacker.s.currentKillstreak == 3 ) + if ( attacker.s.currentKillstreak == KILLINGSPREE_KILL_REQUIREMENT ) AddPlayerScore( attacker, "KillingSpree" ) - else if ( attacker.s.currentKillstreak == 5 ) + else if ( attacker.s.currentKillstreak == RAMPAGE_KILL_REQUIREMENT ) AddPlayerScore( attacker, "Rampage" ) // increment untimed killstreaks against specific players @@ -234,6 +247,39 @@ void function ScoreEvent_NPCKilled( entity victim, entity attacker, var damageIn AddPlayerScore( attacker, ScoreEventForNPCKilled( victim, damageInfo ), victim ) } catch ( ex ) {} + + if ( !attacker.IsPlayer() ) + return + + // mayhem/onslaught (timed killstreaks vs AI) + + // reset before checking + if ( Time() - attacker.s.lastKillTime_Mayhem > MAYHEM_REQUIREMENT_TIME ) + { + attacker.s.currentTimedKillstreak_Mayhem = 0 + attacker.s.lastKillTime_Mayhem = Time() + } + if ( Time() - attacker.s.lastKillTime_Mayhem <= MAYHEM_REQUIREMENT_TIME ) + { + attacker.s.currentTimedKillstreak_Mayhem++ + + if ( attacker.s.currentTimedKillstreak_Mayhem == MAYHEM_REQUIREMENT_KILLS ) + AddPlayerScore( attacker, "Mayhem" ) + } + + // reset before checking + if ( Time() - attacker.s.lastKillTime_Onslaught > ONSLAUGHT_REQUIREMENT_TIME ) + { + attacker.s.currentTimedKillstreak_Onslaught = 0 + attacker.s.lastKillTime_Onslaught = Time() + } + if ( Time() - attacker.s.lastKillTime_Onslaught <= ONSLAUGHT_REQUIREMENT_TIME ) + { + attacker.s.currentTimedKillstreak_Onslaught++ + + if ( attacker.s.currentTimedKillstreak_Onslaught == ONSLAUGHT_REQUIREMENT_KILLS ) + AddPlayerScore( attacker, "Onslaught" ) + } } void function ScoreEvent_MatchComplete( int winningTeam ) -- cgit v1.2.3 From bdb73b1fd5ddd1899adae528ec64b3077b918a61 Mon Sep 17 00:00:00 2001 From: x3Karma Date: Fri, 1 Dec 2023 08:14:41 +0800 Subject: Fix crash when calling for invalid loadout index (#764) Requesting for invalid loadout index using SwapSecondaryAndWeapon3PersistentLoadoutData will cause a crash. This change just adds a check to reset the loadout index. --- Northstar.CustomServers/mod/scripts/vscripts/_loadouts_mp.gnut | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Northstar.CustomServers') diff --git a/Northstar.CustomServers/mod/scripts/vscripts/_loadouts_mp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_loadouts_mp.gnut index 76cb4ac4..63756fdc 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/_loadouts_mp.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/_loadouts_mp.gnut @@ -193,6 +193,10 @@ bool function ClientCommandCallback_SwapSecondaryAndWeapon3PersistentLoadoutData // get loadout int index = args[0].tointeger() + + if ( !IsValidPilotLoadoutIndex(index) ) + return false + PilotLoadoutDef loadout = GetPilotLoadoutFromPersistentData( player, index ) // swap loadouts -- cgit v1.2.3 From 0c5c9b1a46dc0078057e40f2e022bcb75b6fe842 Mon Sep 17 00:00:00 2001 From: GeckoEidechse <40122905+GeckoEidechse@users.noreply.github.com> Date: Mon, 4 Dec 2023 14:25:19 +0100 Subject: Add a doc comment to `StringReplace` (#748) This is an initial test to get formatting etc agreed upon to then build on this further --- Northstar.CustomServers/mod/scripts/vscripts/sh_utility_all.gnut | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'Northstar.CustomServers') diff --git a/Northstar.CustomServers/mod/scripts/vscripts/sh_utility_all.gnut b/Northstar.CustomServers/mod/scripts/vscripts/sh_utility_all.gnut index 9e762985..a97185b5 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/sh_utility_all.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/sh_utility_all.gnut @@ -348,6 +348,14 @@ string function GetMapDisplayDesc( string mapname ) return "#" + mapname + "_CLASSIC_DESC" } +/// Sends a string message to player +/// * `baseString` - The input string to search through +/// * `searchString` - Find this substring... +/// * `replaceString` - ...and replace with this substring +/// * `replaceAll` - Whether to replace all occurences or just the first +/// * `caseInsensitive` - Whether to consider casing (upper/lower) +/// +/// Returns the updated string string function StringReplace( string baseString, string searchString, string replaceString, bool replaceAll = false, bool caseInsensitive = false ) { bool loopedOnce = false -- cgit v1.2.3 From 6d678ac56b104a5c4aa2a2d9da05b163f2e1d6cd Mon Sep 17 00:00:00 2001 From: William Miller Date: Thu, 14 Dec 2023 10:39:26 -0300 Subject: Add Aegis Rank reset functionality command for Progression (#727) Adds a console command to allow players to reset the Aegis Ranks of their Titans --- .../mod/scripts/vscripts/sh_progression.nut | 23 ++++++++++++++++++++++ .../mod/scripts/vscripts/sh_utility_all.gnut | 16 +++++++++++++++ 2 files changed, 39 insertions(+) (limited to 'Northstar.CustomServers') diff --git a/Northstar.CustomServers/mod/scripts/vscripts/sh_progression.nut b/Northstar.CustomServers/mod/scripts/vscripts/sh_progression.nut index 496e8b42..2dc88d0d 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/sh_progression.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/sh_progression.nut @@ -38,6 +38,7 @@ void function Progression_Init() #if SERVER AddCallback_OnClientDisconnected( OnClientDisconnected ) AddClientCommandCallback( "ns_progression", ClientCommand_SetProgression ) + AddClientCommandCallback( "ns_resettitanaegis", ClientCommand_ResetTitanAegis ) AddCallback_GameStateEnter( eGameState.Playing, OnPlaying ) #elseif CLIENT AddCallback_OnClientScriptInit( OnClientScriptInit ) @@ -84,6 +85,28 @@ bool function ClientCommand_SetProgression( entity player, array args ) return true } + +/// Resets a specific Titan's Aegis rank back to `0` +/// * `player` - The player entity to perform the action on +/// * `args` - The arguments passed from the client command. `args[0]` should be an integer corresponding to the index of the Titan to reset. +/// +/// Returns `true` on success and `false` on missing args. +bool function ClientCommand_ResetTitanAegis( entity player, array args ) +{ + if ( !args.len() ) + return false + + int suitIndex = args[0].tointeger() + player.SetPersistentVar( "titanFDUnlockPoints[" + suitIndex + "]", 0 ) + player.SetPersistentVar( "previousFDUnlockPoints[" + suitIndex + "]", 0 ) + player.SetPersistentVar( "fdTitanXP[" + suitIndex + "]", 0 ) + player.SetPersistentVar( "fdPreviousTitanXP[" + suitIndex + "]", 0 ) + + // Refresh Highest Aegis Titan since we might get all of them back to 1 if players wants + RecalculateHighestTitanFDLevel( player ) + + return true +} #endif #if CLIENT diff --git a/Northstar.CustomServers/mod/scripts/vscripts/sh_utility_all.gnut b/Northstar.CustomServers/mod/scripts/vscripts/sh_utility_all.gnut index a97185b5..8751a250 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/sh_utility_all.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/sh_utility_all.gnut @@ -1540,6 +1540,22 @@ array function GetAvailableTitanRefs( entity player ) return availableTitanRefs } +/// Gets the highest Titan FD level and stores it in the corresponding persistent var. +/// * `player` - The player entity to perform the action on +void function RecalculateHighestTitanFDLevel( entity player ) +{ + int enumCount = PersistenceGetEnumCount( "titanClasses" ) + int highestAegis = 0 + for ( int i = 0; i < enumCount; i++ ) + { + string enumName = PersistenceGetEnumItemNameForIndex( "titanClasses", i ) + int aegisLevel = FD_TitanGetLevelForXP( enumName, FD_TitanGetXP( player, enumName ) ) + if ( highestAegis < aegisLevel ) + highestAegis = aegisLevel + } + player.SetPersistentVar( "fdStats.highestTitanFDLevel", highestAegis ) +} + #if MP string function GetTitanRefForLoadoutIndex( entity player, int loadoutIndex ) { -- cgit v1.2.3 From 93b9c734d66af04d6e245216723c93ea49766c5b Mon Sep 17 00:00:00 2001 From: Jack <66967891+ASpoonPlaysGames@users.noreply.github.com> Date: Sun, 17 Dec 2023 01:25:30 +0000 Subject: Fix `spec_mode` bind not working (#706) Fixes `spec_mode` bind not working by adding a small spectator replay delay Co-authored-by: DBmaoha <56738369+DBmaoha@users.noreply.github.com> --- .../mod/scripts/vscripts/mp/_spectator.gnut | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'Northstar.CustomServers') diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_spectator.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_spectator.gnut index aa2fc108..510a9b7e 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_spectator.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_spectator.gnut @@ -170,6 +170,9 @@ void function SpectatorFunc_Default( entity player ) { player.SetObserverTarget( target ) player.StartObserverMode( OBS_MODE_CHASE ) + // the delay of 0.1 seems to fix the spec_mode command not working + // when using the keybind + player.SetSpecReplayDelay( 0.1 ) } catch ( ex ) { } } @@ -215,9 +218,12 @@ bool function ClientCommandCallback_spec_mode( entity player, array args else if ( player.GetObserverMode() == OBS_MODE_IN_EYE ) { // set to third person spectate - player.SetSpecReplayDelay( 0.0 ) + + // the delay of 0.1 seems to fix the spec_mode command not working + // when using the keybind + player.SetSpecReplayDelay( 0.1 ) player.StartObserverMode( OBS_MODE_CHASE ) } return true -} \ No newline at end of file +} -- cgit v1.2.3 From a169e16508bed6b850450d17056433a234fa29f6 Mon Sep 17 00:00:00 2001 From: William Miller Date: Sun, 17 Dec 2023 22:38:29 -0300 Subject: Fix restricting Aegis Rank reset functionality to MP (#771) Move compiler flag so that `RecalculateHighestTitanFDLevel` is MP only. --- Northstar.CustomServers/mod/scripts/vscripts/sh_utility_all.gnut | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Northstar.CustomServers') diff --git a/Northstar.CustomServers/mod/scripts/vscripts/sh_utility_all.gnut b/Northstar.CustomServers/mod/scripts/vscripts/sh_utility_all.gnut index 8751a250..2ca051cf 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/sh_utility_all.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/sh_utility_all.gnut @@ -1542,6 +1542,7 @@ array function GetAvailableTitanRefs( entity player ) /// Gets the highest Titan FD level and stores it in the corresponding persistent var. /// * `player` - The player entity to perform the action on +#if MP void function RecalculateHighestTitanFDLevel( entity player ) { int enumCount = PersistenceGetEnumCount( "titanClasses" ) @@ -1556,7 +1557,6 @@ void function RecalculateHighestTitanFDLevel( entity player ) player.SetPersistentVar( "fdStats.highestTitanFDLevel", highestAegis ) } -#if MP string function GetTitanRefForLoadoutIndex( entity player, int loadoutIndex ) { TitanLoadoutDef loadout = GetTitanLoadoutFromPersistentData( player, loadoutIndex ) -- cgit v1.2.3