aboutsummaryrefslogtreecommitdiff
path: root/Northstar.CustomServers
diff options
context:
space:
mode:
Diffstat (limited to 'Northstar.CustomServers')
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut3
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_at.nut6
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ps.nut198
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_speedball.nut7
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut8
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut43
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut8
7 files changed, 249 insertions, 24 deletions
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut b/Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut
index 732773714..d1f4bd804 100644
--- a/Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut
@@ -293,6 +293,9 @@ void function PlayerUsesAmpedWeaponsBurncardThreaded( entity player )
//weapons.extend( player.GetOffhandWeapons() ) // idk? unsure of vanilla behaviour here
foreach ( entity weapon in weapons )
{
+ if( weapon.GetWeaponPrimaryClipCountMax() > 0 )
+ weapon.SetWeaponPrimaryClipCount( weapon.GetWeaponPrimaryClipCountMax() ) // kind of a fix to get ammo to full, cba to give new weapon
+
weapon.RemoveMod( "silencer" ) // both this and the burnmod will override firing fx, if a second one overrides this we crash
foreach ( string mod in GetWeaponBurnMods( weapon.GetWeaponClassName() ) )
{
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_at.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_at.nut
index b75ed51b6..573ea72fc 100644
--- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_at.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_at.nut
@@ -1,6 +1,5 @@
global function GamemodeAt_Init
global function RateSpawnpoints_AT
-global function RateSpawnpoints_SpawnZones
void function GamemodeAt_Init()
{
@@ -10,9 +9,4 @@ void function GamemodeAt_Init()
void function RateSpawnpoints_AT( int checkclass, array<entity> spawnpoints, int team, entity player )
{
RateSpawnpoints_Generic( checkclass, spawnpoints, team, player ) // temp
-}
-
-void function RateSpawnpoints_SpawnZones( int checkclass, array<entity> spawnpoints, int team, entity player )
-{
- RateSpawnpoints_Generic( checkclass, spawnpoints, team, player ) // temp
} \ No newline at end of file
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ps.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ps.nut
index 7eec7c89f..4f05d87a5 100644
--- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ps.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ps.nut
@@ -1,4 +1,16 @@
+untyped
global function GamemodePs_Init
+global function RateSpawnpoints_SpawnZones
+
+struct {
+ array<entity> spawnzones
+
+ entity militiaActiveSpawnZone
+ entity imcActiveSpawnZone
+
+ array<entity> militiaPreviousSpawnZones
+ array<entity> imcPreviousSpawnZones
+} file
void function GamemodePs_Init()
{
@@ -8,6 +20,12 @@ void function GamemodePs_Init()
ScoreEvent_SetupEarnMeterValuesForMixedModes()
SetTimeoutWinnerDecisionFunc( CheckScoreForDraw )
+ // spawnzone stuff
+ AddCallback_OnPlayerKilled( CheckSpawnzoneSuspiciousDeaths )
+ AddSpawnCallbackEditorClass( "trigger_multiple", "trigger_mp_spawn_zone", SpawnzoneTriggerInit )
+
+ file.militiaPreviousSpawnZones = [ null, null, null ]
+ file.imcPreviousSpawnZones = [ null, null, null ]
}
void function GiveScoreForPlayerKill( entity victim, entity attacker, var damageInfo )
@@ -18,10 +36,186 @@ void function GiveScoreForPlayerKill( entity victim, entity attacker, var damage
int function CheckScoreForDraw()
{
- if (GameRules_GetTeamScore(TEAM_IMC) > GameRules_GetTeamScore(TEAM_MILITIA))
+ if ( GameRules_GetTeamScore( TEAM_IMC ) > GameRules_GetTeamScore( TEAM_MILITIA ) )
return TEAM_IMC
- else if (GameRules_GetTeamScore(TEAM_MILITIA) > GameRules_GetTeamScore(TEAM_IMC))
+ else if ( GameRules_GetTeamScore( TEAM_MILITIA ) > GameRules_GetTeamScore( TEAM_IMC ) )
return TEAM_MILITIA
return TEAM_UNASSIGNED
+}
+
+// spawnzone logic
+void function SpawnzoneTriggerInit( entity spawnzone )
+{
+ // initialise spawnzone script vars
+ spawnzone.s.lastDeathRateCheck <- 0.0
+ spawnzone.s.numRecentSuspiciousDeaths <- 0
+ spawnzone.s.minimapObj <- null
+
+ file.spawnzones.append( spawnzone )
+}
+
+void function SetNewSpawnzoneForTeam( int team, entity spawnzone )
+{
+ entity minimapObj = CreatePropScript( $"models/dev/empty_model.mdl", spawnzone.GetOrigin() )
+ SetTeam( minimapObj, team )
+ minimapObj.Minimap_SetObjectScale( 100.0 / Distance2D( < 0, 0, 0 >, spawnzone.GetBoundingMaxs() ) )
+ minimapObj.Minimap_SetAlignUpright( true )
+ minimapObj.Minimap_AlwaysShow( TEAM_IMC, null )
+ minimapObj.Minimap_AlwaysShow( TEAM_MILITIA, null )
+ minimapObj.Minimap_SetHeightTracking( true )
+ minimapObj.Minimap_SetZOrder( MINIMAP_Z_OBJECT )
+
+ if ( team == TEAM_IMC )
+ {
+ if ( IsValid( file.imcActiveSpawnZone ) )
+ file.imcActiveSpawnZone.s.minimapObj.Destroy()
+
+ // update last 3 zones
+ file.imcPreviousSpawnZones[ 2 ] = file.imcPreviousSpawnZones[ 1 ]
+ file.imcPreviousSpawnZones[ 1 ] = file.imcPreviousSpawnZones[ 0 ]
+ file.imcPreviousSpawnZones[ 0 ] = file.imcActiveSpawnZone
+
+ file.imcActiveSpawnZone = spawnzone
+ minimapObj.Minimap_SetCustomState( eMinimapObject_prop_script.SPAWNZONE_IMC )
+ }
+ else
+ {
+ if ( IsValid( file.militiaActiveSpawnZone ) )
+ file.militiaActiveSpawnZone.s.minimapObj.Destroy()
+
+ // update last 3 zones
+ file.militiaPreviousSpawnZones[ 2 ] = file.militiaPreviousSpawnZones[ 1 ]
+ file.militiaPreviousSpawnZones[ 1 ] = file.militiaPreviousSpawnZones[ 0 ]
+ file.militiaPreviousSpawnZones[ 0 ] = file.militiaActiveSpawnZone
+
+ file.militiaActiveSpawnZone = spawnzone
+ minimapObj.Minimap_SetCustomState( eMinimapObject_prop_script.SPAWNZONE_MIL )
+ }
+
+ minimapObj.DisableHibernation()
+
+ spawnzone.s.minimapObj = minimapObj
+ spawnzone.s.lastDeathRateCheck = 0.0
+ spawnzone.s.numRecentSuspiciousDeaths = Time()
+}
+
+void function CheckSpawnzoneSuspiciousDeaths( entity victim, entity attacker, var damageInfo )
+{
+ if ( victim.s.respawnTime + 10.0 < Time() )
+ return
+
+ entity spawnzone
+ if ( victim.GetTeam() == TEAM_IMC )
+ spawnzone = file.imcActiveSpawnZone
+ else
+ spawnzone = file.militiaActiveSpawnZone
+
+ if ( Distance2D( victim.GetOrigin(), spawnzone.GetOrigin() ) <= Distance2D( < 0, 0, 0 >, spawnzone.GetBoundingMaxs() ) * 1.2 )
+ spawnzone.s.numRecentSuspiciousDeaths++
+}
+
+entity function FindNewSpawnZone( int team )
+{
+ array<entity> startSpawns = SpawnPoints_GetPilotStart( team )
+ array<entity> enemyStartSpawns = SpawnPoints_GetPilotStart( GetOtherTeam( team ) )
+
+ // get average friendly startspawn position
+ vector averageFriendlySpawns
+ foreach ( entity spawn in startSpawns )
+ averageFriendlySpawns += spawn.GetOrigin()
+ averageFriendlySpawns /= startSpawns.len()
+
+ // get average enemy startspawn position
+ vector averageEnemySpawns
+ foreach ( entity spawn in enemyStartSpawns )
+ averageEnemySpawns += spawn.GetOrigin()
+ averageEnemySpawns /= enemyStartSpawns.len()
+
+ array<entity> validZones
+ array<entity> enemyPlayers = GetPlayerArrayOfTeam( GetOtherTeam( team ) )
+ float averageFriendlySpawnDist
+
+ foreach ( entity spawnzone in file.spawnzones )
+ {
+ if ( team == TEAM_IMC && file.imcPreviousSpawnZones.contains( spawnzone ) )
+ continue
+ else if ( file.militiaPreviousSpawnZones.contains( spawnzone ) )
+ continue
+
+ // check if it's too far from startspawns
+ float friendlySpawnDist = Distance2D( spawnzone.GetOrigin(), averageFriendlySpawns )
+ if ( friendlySpawnDist > Distance2D( averageFriendlySpawns, averageEnemySpawns ) * 1.2 )
+ continue
+
+ // check if it's safe atm
+ bool safe = true
+ foreach ( entity enemy in enemyPlayers )
+ {
+ if ( Distance2D( enemy.GetOrigin(), spawnzone.GetOrigin() ) < Distance2D( < 0, 0, 0 >, spawnzone.GetBoundingMaxs() ) * 1.2 )
+ {
+ safe = false
+ break
+ }
+ }
+
+ if ( !safe )
+ continue
+
+ averageFriendlySpawnDist += friendlySpawnDist
+ validZones.append( spawnzone )
+ }
+
+ averageFriendlySpawnDist /= validZones.len()
+
+ array<entity> realValidZones = clone validZones
+ foreach ( entity validzone in validZones )
+ {
+ if ( Distance2D( averageFriendlySpawns, validzone.GetOrigin() ) < averageFriendlySpawnDist * 1.4 )
+ realValidZones.append( validzone )
+ }
+
+ entity spawnzone = realValidZones.getrandom()
+ SetNewSpawnzoneForTeam( team, spawnzone )
+
+ return spawnzone
+}
+
+void function RateSpawnpoints_SpawnZones( int checkClass, array<entity> spawnpoints, int team, entity player )
+{
+ entity spawnzone
+ if ( player.GetTeam() == TEAM_IMC )
+ spawnzone = file.imcActiveSpawnZone
+ else
+ spawnzone = file.militiaActiveSpawnZone
+
+ // spawnzones don't exist yet, create them now
+ if ( !IsValid( spawnzone ) )
+ spawnzone = FindNewSpawnZone( player.GetTeam() )
+
+ // check if we should shift spawnzones
+ // if it's been more than 15 seconds since last check, reset
+ if ( spawnzone.s.lastDeathRateCheck + 15.0 < Time() )
+ {
+ spawnzone.s.numRecentSuspiciousDeaths = 0
+ spawnzone.s.lastDeathRateCheck = Time()
+ }
+
+ // check if we've gone over the threshold for recent deaths too close to our current spawnzone
+ if ( spawnzone.s.numRecentSuspiciousDeaths >= GetPlayerArrayOfTeam( player.GetTeam() ).len() * 0.4 )
+ // over the threshold, find a new spawn zone
+ spawnzone = FindNewSpawnZone( player.GetTeam() )
+
+ // rate spawnpoints
+ foreach ( entity spawn in spawnpoints )
+ {
+ float rating = 0.0
+ float distance = Distance2D( spawn.GetOrigin(), spawnzone.GetOrigin() )
+ if ( distance < Distance2D( < 0, 0, 0 >, spawnzone.GetBoundingMaxs() ) )
+ rating = 100.0
+ else // max 35 rating if not in zone, rate by closest
+ rating = 35.0 * ( 1 - ( distance / 5000.0 ) )
+
+ spawn.CalculateRating( checkClass, player.GetTeam(), rating, rating )
+ }
} \ No newline at end of file
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_speedball.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_speedball.nut
index 974481c18..207af721e 100644
--- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_speedball.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_speedball.nut
@@ -23,6 +23,7 @@ void function GamemodeSpeedball_Init()
AddCallback_GameStateEnter( eGameState.Prematch, CreateFlagIfNoFlagSpawnpoint )
AddCallback_GameStateEnter( eGameState.Playing, ResetFlag )
+ AddCallback_GameStateEnter( eGameState.WinnerDetermined,GamemodeSpeedball_OnWinnerDetermined)
AddCallback_OnTouchHealthKit( "item_flag", OnFlagCollected )
AddCallback_OnPlayerKilled( OnPlayerKilled )
SetTimeoutWinnerDecisionFunc( TimeoutCheckFlagHolder )
@@ -147,3 +148,9 @@ int function TimeoutCheckFlagHolder()
return file.flagCarrier.GetTeam()
}
+
+void function GamemodeSpeedball_OnWinnerDetermined()
+{
+ if(IsValid(file.flagCarrier))
+ file.flagCarrier.AddToPlayerGameStat( PGS_ASSAULT_SCORE, 1 )
+} \ 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 b8cd67adc..4b2e539cf 100644
--- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut
@@ -222,6 +222,7 @@ void function CodeCallback_OnPlayerRespawned( entity player )
player.SetPredictionEnabled( true )
Loadouts_TryGivePilotLoadout( player )
SetHumanRagdollImpactTable( player )
+ ClearLastAttacker( player ) // so dying to anything doesn't credit the same attacker after respawning
foreach ( entity weapon in player.GetMainWeapons() )
weapon.SetProScreenOwner( player )
@@ -261,7 +262,7 @@ void function PostDeathThread_MP( entity player, var damageInfo ) // based on ga
player.SetNoTargetSmartAmmo( false )
player.ClearExtraWeaponMods()
- player.AddToPlayerGameStat( PGS_DEATHS, 1 )
+
if ( player.IsTitan() )
SoulDies( player.GetTitanSoul(), damageInfo ) // cleanup some titan stuff, no idea where else to put this
@@ -303,7 +304,10 @@ void function PostDeathThread_MP( entity player, var damageInfo ) // based on ga
player.SetObserverTarget( null )
if ( !file.playerDeathsHidden )
+ {
+ player.AddToPlayerGameStat( PGS_DEATHS, 1 )
Remote_CallFunction_NonReplay( player, "ServerCallback_YouDied", attacker.GetEncodedEHandle(), GetHealthFrac( attacker ), methodOfDeath )
+ }
float deathcamLength = GetDeathCamLength( player )
wait deathcamLength
@@ -630,4 +634,4 @@ float function GetTitanBuildTime(entity player)
void function TitanPlayerHotDropsIntoLevel( entity player )
{
-} \ 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 598b45228..2d39cf2d8 100644
--- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut
@@ -15,6 +15,7 @@ global function SetRoundWinningKillReplayAttacker
global function SetWinner
global function SetTimeoutWinnerDecisionFunc
global function AddTeamScore
+global function GetWinningTeamWithFFASupport
global function GameState_GetTimeLimitOverride
global function IsRoundBasedGameOver
@@ -231,10 +232,7 @@ void function GameStateEnter_Playing_Threaded()
if ( file.timeoutWinnerDecisionFunc != null )
winningTeam = file.timeoutWinnerDecisionFunc()
else
- winningTeam = GetWinningTeam()
-
- if ( winningTeam == -1 )
- winningTeam = TEAM_UNASSIGNED
+ winningTeam = GetWinningTeamWithFFASupport()
if ( file.switchSidesBased && !file.hasSwitchedSides && !IsRoundBased() ) // in roundbased modes, we handle this in setwinner
SetGameState( eGameState.SwitchingSides )
@@ -264,9 +262,7 @@ void function GameStateEnter_WinnerDetermined()
void function GameStateEnter_WinnerDetermined_Threaded()
{
// do win announcement
- int winningTeam = GetWinningTeam()
- if ( winningTeam == -1 )
- winningTeam = TEAM_UNASSIGNED
+ int winningTeam = GetWinningTeamWithFFASupport()
foreach ( entity player in GetPlayerArray() )
{
@@ -334,9 +330,7 @@ void function GameStateEnter_WinnerDetermined_Threaded()
int roundsPlayed = expect int ( GetServerVar( "roundsPlayed" ) )
SetServerVar( "roundsPlayed", roundsPlayed + 1 )
- int winningTeam = GetWinningTeam()
- if ( winningTeam == -1 )
- winningTeam = TEAM_UNASSIGNED
+ int winningTeam = GetWinningTeamWithFFASupport()
int highestScore = GameRules_GetTeamScore( winningTeam )
int roundScoreLimit = GameMode_GetRoundScoreLimit( GAMETYPE )
@@ -801,6 +795,35 @@ void function SetTimeoutWinnerDecisionFunc( int functionref() callback )
file.timeoutWinnerDecisionFunc = callback
}
+int function GetWinningTeamWithFFASupport()
+{
+ if ( !IsFFAGame() )
+ return GameScore_GetWinningTeam()
+ else
+ {
+ // custom logic for calculating ffa winner as GameScore_GetWinningTeam doesn't handle this
+ int winningTeam = TEAM_UNASSIGNED
+ int winningScore = 0
+
+ foreach ( entity player in GetPlayerArray() )
+ {
+ int currentScore = GameRules_GetTeamScore( player.GetTeam() )
+
+ if ( currentScore == winningScore )
+ winningTeam = TEAM_UNASSIGNED // if 2 teams are equal, return TEAM_UNASSIGNED
+ else if ( currentScore > winningScore )
+ {
+ winningTeam = player.GetTeam()
+ winningScore = currentScore
+ }
+ }
+
+ return winningTeam
+ }
+
+ unreachable
+}
+
// idk
float function GameState_GetTimeLimitOverride()
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut
index 002b13312..7b86a1d84 100644
--- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut
@@ -95,7 +95,7 @@ void function ScoreEvent_PlayerKilled( entity victim, entity attacker, var damag
// have to do this early before we reset victim's player killstreaks
// nemesis when you kill a player that is dominating you
- if ( attacker.IsPlayer() && attacker in victim.p.playerKillStreaks && victim.p.playerKillStreaks[ attacker ] == NEMESIS_KILL_REQUIREMENT )
+ if ( attacker.IsPlayer() && attacker in victim.p.playerKillStreaks && victim.p.playerKillStreaks[ attacker ] >= NEMESIS_KILL_REQUIREMENT )
AddPlayerScore( attacker, "Nemesis" )
// reset killstreaks on specific players
@@ -108,7 +108,7 @@ void function ScoreEvent_PlayerKilled( entity victim, entity attacker, var damag
if ( !attacker.IsPlayer() )
return
-
+ attacker.p.numberOfDeathsSinceLastKill = 0 // since they got a kill, remove the comeback trigger
// pilot kill
AddPlayerScore( attacker, "KillPilot", victim )
@@ -145,7 +145,7 @@ void function ScoreEvent_PlayerKilled( entity victim, entity attacker, var damag
attacker.p.playerKillStreaks[ victim ]++
// dominating
- if ( attacker.p.playerKillStreaks[ victim ] == DOMINATING_KILL_REQUIREMENT )
+ if ( attacker.p.playerKillStreaks[ victim ] >= DOMINATING_KILL_REQUIREMENT )
AddPlayerScore( attacker, "Dominating" )
if ( Time() - attacker.s.lastKillTime > CASCADINGKILL_REQUIREMENT_TIME )
@@ -163,7 +163,7 @@ void function ScoreEvent_PlayerKilled( entity victim, entity attacker, var damag
AddPlayerScore( attacker, "DoubleKill" )
else if ( attacker.s.currentTimedKillstreak == TRIPLEKILL_REQUIREMENT_KILLS )
AddPlayerScore( attacker, "TripleKill" )
- else if ( attacker.s.currentTimedKillstreak == MEGAKILL_REQUIREMENT_KILLS )
+ else if ( attacker.s.currentTimedKillstreak >= MEGAKILL_REQUIREMENT_KILLS )
AddPlayerScore( attacker, "MegaKill" )
}