diff options
Diffstat (limited to 'Northstar.CustomServers/mod/scripts/vscripts/mp/spawn.nut')
-rw-r--r-- | Northstar.CustomServers/mod/scripts/vscripts/mp/spawn.nut | 188 |
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 61fabb3c..b72e660e 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 |