aboutsummaryrefslogtreecommitdiff
path: root/Northstar.CustomServers/mod/scripts/vscripts/mp/spawn.nut
diff options
context:
space:
mode:
Diffstat (limited to 'Northstar.CustomServers/mod/scripts/vscripts/mp/spawn.nut')
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/spawn.nut188
1 files changed, 121 insertions, 67 deletions
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/spawn.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/spawn.nut
index 61fabb3cb..b72e660ed 100644
--- a/Northstar.CustomServers/mod/scripts/vscripts/mp/spawn.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/spawn.nut
@@ -3,7 +3,6 @@ untyped
global function InitRatings // temp for testing
global function Spawn_Init
-global function SetSpawnsUseFrontline
global function SetRespawnsEnabled
global function RespawnsEnabled
global function SetSpawnpointGamemodeOverride
@@ -11,7 +10,6 @@ global function GetSpawnpointGamemodeOverride
global function CreateNoSpawnArea
global function DeleteNoSpawnArea
-global function GetCurrentFrontline
global function FindSpawnPoint
global function RateSpawnpoints_Generic
@@ -32,11 +30,7 @@ struct {
table<string, NoSpawnArea> noSpawnAreas
- bool frontlineBased = false
- float lastImcFrontlineRatingTime
- float lastMilitiaFrontlineRatingTime
- Frontline& lastImcFrontline
- Frontline& lastMilitiaFrontline
+ array<vector> preferSpawnNodes
} file
void function Spawn_Init()
@@ -45,6 +39,25 @@ void function Spawn_Init()
AddSpawnCallback( "info_spawnpoint_human_start", InitSpawnpoint )
AddSpawnCallback( "info_spawnpoint_titan", InitSpawnpoint )
AddSpawnCallback( "info_spawnpoint_titan_start", InitSpawnpoint )
+
+ AddCallback_EntitiesDidLoad( InitPreferSpawnNodes )
+}
+
+void function InitPreferSpawnNodes()
+{
+ foreach ( entity hardpoint in GetEntArrayByClass_Expensive( "info_hardpoint" ) )
+ {
+ if ( !hardpoint.HasKey( "hardpointGroup" ) )
+ continue
+
+ if ( hardpoint.kv.hardpointGroup != "A" && hardpoint.kv.hardpointGroup != "B" && hardpoint.kv.hardpointGroup != "C" )
+ continue
+
+ file.preferSpawnNodes.append( hardpoint.GetOrigin() )
+ }
+
+ //foreach ( entity frontline in GetEntArrayByClass_Expensive( "info_frontline" ) )
+ // file.preferSpawnNodes.append( frontline.GetOrigin() )
}
void function InitSpawnpoint( entity spawnpoint )
@@ -106,63 +119,10 @@ string function GetSpawnpointGamemodeOverride()
unreachable
}
-void function SetSpawnsUseFrontline( bool useFrontline )
-{
- file.frontlineBased = useFrontline
-}
-
-bool function InitRatings( entity player, int team )
+void function InitRatings( entity player, int team )
{
- Frontline frontline = GetCurrentFrontline( team )
- print( team )
- print( frontline.friendlyCenter )
-
- vector offsetOrigin = frontline.friendlyCenter + frontline.combatDir * 256
- SpawnPoints_InitFrontlineData( offsetOrigin, frontline.combatDir, frontline.line, frontline.friendlyCenter, 2.0 ) // temp
-
if ( player != null )
SpawnPoints_InitRatings( player, team ) // no idea what the second arg supposed to be lol
-
- return frontline.friendlyCenter == < 0, 0, 0 > && file.frontlineBased // if true, use startspawns
-}
-
-// this sucks
-Frontline function GetCurrentFrontline( int team )
-{
- float lastFrontlineRatingTime
- Frontline lastFrontline
- if ( team == TEAM_IMC )
- {
- lastFrontline = file.lastImcFrontline
- lastFrontlineRatingTime = file.lastImcFrontlineRatingTime
- }
- else
- {
- lastFrontline = file.lastMilitiaFrontline
- lastFrontlineRatingTime = file.lastMilitiaFrontlineRatingTime
- }
-
- // current frontline is old, get a new one
- if ( lastFrontlineRatingTime + 20.0 < Time() || lastFrontline.friendlyCenter == < 0, 0, 0 > )
- {
- print( "rerating frontline..." )
- Frontline frontline = GetFrontline( team )
-
- if ( team == TEAM_IMC )
- {
- file.lastImcFrontlineRatingTime = Time()
- file.lastImcFrontline = frontline
- }
- else
- {
- file.lastMilitiaFrontlineRatingTime = Time()
- file.lastMilitiaFrontline = frontline
- }
-
- lastFrontline = frontline
- }
-
- return lastFrontline
}
entity function FindSpawnPoint( entity player, bool isTitan, bool useStartSpawnpoint )
@@ -171,15 +131,14 @@ entity function FindSpawnPoint( entity player, bool isTitan, bool useStartSpawnp
if ( HasSwitchedSides() )
team = GetOtherTeam( team )
- useStartSpawnpoint = InitRatings( player, player.GetTeam() ) || useStartSpawnpoint // force startspawns if no frontline
- print( "useStartSpawnpoint: " + useStartSpawnpoint )
-
array<entity> spawnpoints
if ( useStartSpawnpoint )
spawnpoints = isTitan ? SpawnPoints_GetTitanStart( team ) : SpawnPoints_GetPilotStart( team )
else
spawnpoints = isTitan ? SpawnPoints_GetTitan() : SpawnPoints_GetPilot()
+ InitRatings( player, team )
+
void functionref( int, array<entity>, int, entity ) ratingFunc = isTitan ? GameMode_GetTitanSpawnpointsRatingFunc( GAMETYPE ) : GameMode_GetPilotSpawnpointsRatingFunc( GAMETYPE )
ratingFunc( isTitan ? TD_TITAN : TD_PILOT, spawnpoints, team, player )
@@ -238,6 +197,19 @@ entity function GetBestSpawnpoint( entity player, array<entity> spawnpoints )
}
}
+ // last resort
+ if ( validSpawns.len() == 0 )
+ {
+ print( "map has literally 0 spawnpoints, as such everything is fucked probably, attempting to use info_player_start if present" )
+ entity start = GetEnt( "info_player_start" )
+
+ if ( IsValid( start ) )
+ {
+ start.s.lastUsedTime <- -999
+ validSpawns.append( start )
+ }
+ }
+
return validSpawns[ RandomInt( validSpawns.len() ) ] // slightly randomize it
}
@@ -268,6 +240,9 @@ bool function IsSpawnpointValid( entity spawnpoint, int team )
if ( spawnpoint.IsOccupied() )
return false
+ if ( Time() - spawnpoint.s.lastUsedTime <= 1.0 )
+ return false
+
foreach ( k, NoSpawnArea noSpawnArea in file.noSpawnAreas )
{
if ( Distance( noSpawnArea.position, spawnpoint.GetOrigin() ) > noSpawnArea.radius )
@@ -309,9 +284,6 @@ bool function IsSpawnpointValid( entity spawnpoint, int team )
if ( TraceLineSimple( enemyPlayer.EyePosition(), spawnpoint.GetOrigin() + < 0, 0, 48 >, enemyPlayer ) == 1.0 )
return false
}
-
- if ( Time() - spawnpoint.s.lastUsedTime <= 1.0 )
- return false
return true
}
@@ -323,4 +295,86 @@ void function RateSpawnpoints_Generic( int checkClass, array<entity> spawnpoints
// realistically, this should spawn people fairly spread out across the map, preferring being closer to their startspawns
// should spawn like, near fights, but not in them
+
+
+ // using old func for tests rq
+ // calculate ratings for preferred nodes
+ // this tries to prefer nodes with more teammates, then activity on them
+ // todo: in the future it might be good to have this prefer nodes with enemies up to a limit of some sort
+ // especially in ffa modes i could deffo see this falling apart a bit rn
+ // perhaps dead players could be used to calculate some sort of activity rating? so high-activity points with an even balance of friendly/unfriendly players are preferred
+ array<float> preferSpawnNodeRatings
+ foreach ( vector preferSpawnNode in file.preferSpawnNodes )
+ {
+ float currentRating
+
+ // this seems weird, not using rn
+ //Frontline currentFrontline = GetCurrentFrontline( team )
+ //if ( !IsFFAGame() || currentFrontline.friendlyCenter != < 0, 0, 0 > )
+ // currentRating += max( 0.0, ( 1000.0 - Distance2D( currentFrontline.origin, preferSpawnNode ) ) / 200 )
+
+ foreach ( entity nodePlayer in GetPlayerArray() )
+ {
+ float currentChange = 0.0
+
+ // the closer a player is to a node the more they matter
+ float dist = Distance2D( preferSpawnNode, nodePlayer.GetOrigin() )
+ if ( dist > 600.0 )
+ continue
+
+ currentChange = ( 600.0 - dist ) / 5
+ if ( player == nodePlayer )
+ currentChange *= -3 // always try to stay away from places we've already spawned
+ else if ( !IsAlive( nodePlayer ) ) // dead players mean activity which is good, but they're also dead so they don't matter as much as living ones
+ currentChange *= 0.6
+ if ( nodePlayer.GetTeam() != player.GetTeam() ) // if someone isn't on our team and alive they're probably bad
+ {
+ if ( IsFFAGame() ) // in ffa everyone is on different teams, so this isn't such a big deal
+ currentChange *= -0.2
+ else
+ currentChange *= -0.6
+ }
+
+ currentRating += currentChange
+ }
+
+ preferSpawnNodeRatings.append( currentRating )
+ }
+
+ foreach ( entity spawnpoint in spawnpoints )
+ {
+ float currentRating
+ float petTitanModifier
+ // scale how much a given spawnpoint matters to us based on how far it is from each node
+ bool spawnHasRecievedInitialBonus = false
+ for ( int i = 0; i < file.preferSpawnNodes.len(); i++ )
+ {
+ // bonus if autotitan is nearish
+ if ( IsAlive( player.GetPetTitan() ) && Distance( player.GetPetTitan().GetOrigin(), file.preferSpawnNodes[ i ] ) < 1200.0 )
+ petTitanModifier += 10.0
+
+ float dist = Distance2D( spawnpoint.GetOrigin(), file.preferSpawnNodes[ i ] )
+ if ( dist > 750.0 )
+ continue
+
+ if ( dist < 600.0 && !spawnHasRecievedInitialBonus )
+ {
+ currentRating += 10.0
+ spawnHasRecievedInitialBonus = true // should only get a bonus for simply being by a node once to avoid over-rating
+ }
+
+ currentRating += ( preferSpawnNodeRatings[ i ] * ( ( 750.0 - dist ) / 75 ) ) + max( RandomFloat( 1.25 ), 0.9 )
+ if ( dist < 250.0 ) // shouldn't get TOO close to an active node
+ currentRating *= 0.7
+
+ if ( spawnpoint.s.lastUsedTime < 10.0 )
+ currentRating *= 0.7
+ }
+
+ float rating = spawnpoint.CalculateRating( checkClass, team, currentRating, currentRating + petTitanModifier )
+ //print( "spawnpoint at " + spawnpoint.GetOrigin() + " has rating: " + )
+
+ if ( rating != 0.0 || currentRating != 0.0 )
+ print( "rating = " + rating + ", internal rating = " + currentRating )
+ }
} \ No newline at end of file