diff options
Diffstat (limited to 'Northstar.CustomServers/scripts/vscripts/mp/spawn.nut')
-rw-r--r-- | Northstar.CustomServers/scripts/vscripts/mp/spawn.nut | 439 |
1 files changed, 0 insertions, 439 deletions
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/spawn.nut b/Northstar.CustomServers/scripts/vscripts/mp/spawn.nut deleted file mode 100644 index 26e4c713..00000000 --- a/Northstar.CustomServers/scripts/vscripts/mp/spawn.nut +++ /dev/null @@ -1,439 +0,0 @@ -untyped - -global function InitRatings // temp for testing - -global function Spawn_Init -global function SetSpawnsUseFrontline -global function SetRespawnsEnabled -global function RespawnsEnabled -global function SetSpawnpointGamemodeOverride -global function GetSpawnpointGamemodeOverride -global function CreateNoSpawnArea -global function DeleteNoSpawnArea - -global function GetCurrentFrontline -global function FindSpawnPoint - -global function RateSpawnpoints_Generic - -struct NoSpawnArea -{ - string id - int blockedTeam - int blockOtherTeams - vector position - float lifetime - float radius -} - -struct { - bool respawnsEnabled = true - string spawnpointGamemodeOverride - - array<vector> preferSpawnNodes - table<string, NoSpawnArea> noSpawnAreas - bool sidesSwitched = false - - bool frontlineBased = false - float lastImcFrontlineRatingTime - float lastMilitiaFrontlineRatingTime - Frontline& lastImcFrontline - Frontline& lastMilitiaFrontline -} file - -void function Spawn_Init() -{ - AddCallback_GameStateEnter( eGameState.SwitchingSides, OnSwitchingSides ) - AddCallback_EntitiesDidLoad( InitPreferSpawnNodes ) - - AddSpawnCallback( "info_spawnpoint_human", InitSpawnpoint ) - AddSpawnCallback( "info_spawnpoint_human_start", InitSpawnpoint ) - AddSpawnCallback( "info_spawnpoint_titan", InitSpawnpoint ) - AddSpawnCallback( "info_spawnpoint_titan_start", InitSpawnpoint ) -} - -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 ) -{ - spawnpoint.s.lastUsedTime <- -999 -} - -void function SetRespawnsEnabled( bool enabled ) -{ - file.respawnsEnabled = enabled -} - -bool function RespawnsEnabled() -{ - return file.respawnsEnabled -} - -string function CreateNoSpawnArea( int blockSpecificTeam, int blockEnemiesOfTeam, vector position, float lifetime, float radius ) -{ - NoSpawnArea noSpawnArea - noSpawnArea.blockedTeam = blockSpecificTeam - noSpawnArea.blockOtherTeams = blockEnemiesOfTeam - noSpawnArea.position = position - noSpawnArea.lifetime = lifetime - noSpawnArea.radius = radius - - // generate an id - noSpawnArea.id = UniqueString( "noSpawnArea" ) - - thread NoSpawnAreaLifetime( noSpawnArea ) - - return noSpawnArea.id -} - -void function NoSpawnAreaLifetime( NoSpawnArea noSpawnArea ) -{ - wait noSpawnArea.lifetime - DeleteNoSpawnArea( noSpawnArea.id ) -} - -void function DeleteNoSpawnArea( string noSpawnIdx ) -{ - try // unsure if the trycatch is necessary but better safe than sorry - { - delete file.noSpawnAreas[ noSpawnIdx ] - } - catch ( exception ) - {} -} - -void function SetSpawnpointGamemodeOverride( string gamemode ) -{ - file.spawnpointGamemodeOverride = gamemode -} - -string function GetSpawnpointGamemodeOverride() -{ - if ( file.spawnpointGamemodeOverride != "" ) - return file.spawnpointGamemodeOverride - else - return GAMETYPE - - unreachable -} - -void function SetSpawnsUseFrontline( bool useFrontline ) -{ - file.frontlineBased = useFrontline -} - -bool 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 -} - -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 ) - - // this doesn't work lol - /*if ( frontline.friendlyCenter == < 0, 0, 0 > ) - { - // recalculate to startspawnpoint positions - array<entity> startSpawns = SpawnPoints_GetPilotStart( team ) - - vector averagePos - vector averageDir - foreach ( entity spawnpoint in startSpawns ) - { - averagePos.x += spawnpoint.GetOrigin().x - averagePos.y += spawnpoint.GetOrigin().y - averagePos.z += spawnpoint.GetOrigin().z - - averageDir.x += spawnpoint.GetAngles().x - averageDir.y += spawnpoint.GetAngles().y - averageDir.z += spawnpoint.GetAngles().z - } - - averagePos.x /= startSpawns.len() - averagePos.y /= startSpawns.len() - averagePos.z /= startSpawns.len() - - averageDir.x /= startSpawns.len() - averageDir.y /= startSpawns.len() - averageDir.z /= startSpawns.len() - - print( "average " + averagePos ) - - frontline.friendlyCenter = averagePos - frontline.origin = averagePos - frontline.combatDir = averageDir * -1 - }*/ - - 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 ) -{ - int team = player.GetTeam() - if ( file.sidesSwitched ) - 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() - - void functionref( int, array<entity>, int, entity ) ratingFunc = isTitan ? GameMode_GetTitanSpawnpointsRatingFunc( GAMETYPE ) : GameMode_GetPilotSpawnpointsRatingFunc( GAMETYPE ) - ratingFunc( isTitan ? TD_TITAN : TD_PILOT, spawnpoints, team, player ) - - if ( isTitan ) - { - if ( useStartSpawnpoint ) - SpawnPoints_SortTitanStart() - else - SpawnPoints_SortTitan() - - spawnpoints = useStartSpawnpoint ? SpawnPoints_GetTitanStart( team ) : SpawnPoints_GetTitan() - } - else - { - if ( useStartSpawnpoint ) - SpawnPoints_SortPilotStart() - else - SpawnPoints_SortPilot() - - spawnpoints = useStartSpawnpoint ? SpawnPoints_GetPilotStart( team ) : SpawnPoints_GetPilot() - } - - entity spawnpoint = GetBestSpawnpoint( player, spawnpoints ) - - spawnpoint.s.lastUsedTime = Time() - player.SetLastSpawnPoint( spawnpoint ) - - return spawnpoint -} - -entity function GetBestSpawnpoint( entity player, array<entity> spawnpoints ) -{ - // not really 100% sure on this randomisation, needs some thought - array<entity> validSpawns - foreach ( entity spawnpoint in spawnpoints ) - { - if ( IsSpawnpointValid( spawnpoint, player.GetTeam() ) ) - { - validSpawns.append( spawnpoint ) - - if ( validSpawns.len() == 3 ) // arbitrary small sample size - break - } - } - - if ( validSpawns.len() == 0 ) - { - // no valid spawns, very bad, so dont care about spawns being valid anymore - print( "found no valid spawns! spawns may be subpar!" ) - foreach ( entity spawnpoint in spawnpoints ) - { - validSpawns.append( spawnpoint ) - - if ( validSpawns.len() == 3 ) // arbitrary small sample size - break - } - } - - return validSpawns[ RandomInt( validSpawns.len() ) ] // slightly randomize it -} - -bool function IsSpawnpointValid( entity spawnpoint, int team ) -{ - //if ( !spawnpoint.HasKey( "ignoreGamemode" ) || ( spawnpoint.HasKey( "ignoreGamemode" ) && spawnpoint.kv.ignoreGamemode == "0" ) ) // used by script-spawned spawnpoints - //{ - // if ( file.spawnpointGamemodeOverride != "" ) - // { - // string gamemodeKey = "gamemode_" + file.spawnpointGamemodeOverride - // if ( spawnpoint.HasKey( gamemodeKey ) && ( spawnpoint.kv[ gamemodeKey ] == "0" || spawnpoint.kv[ gamemodeKey ] == "" ) ) - // return false - // } - // else if ( GameModeRemove( spawnpoint ) ) - // return false - //} - - if ( Riff_FloorIsLava() && spawnpoint.GetOrigin().z < GetLethalFogTop() ) - return false - - int compareTeam = spawnpoint.GetTeam() - if ( file.sidesSwitched && ( compareTeam == TEAM_MILITIA || compareTeam == TEAM_IMC ) ) - compareTeam = GetOtherTeam( compareTeam ) - - if ( spawnpoint.GetTeam() > 0 && compareTeam != team && !IsFFAGame() ) - return false - - if ( spawnpoint.IsOccupied() ) - return false - - foreach ( k, NoSpawnArea noSpawnArea in file.noSpawnAreas ) - { - if ( Distance( noSpawnArea.position, spawnpoint.GetOrigin() ) > noSpawnArea.radius ) - continue - - if ( noSpawnArea.blockedTeam != TEAM_INVALID && noSpawnArea.blockedTeam == team ) - return false - - if ( noSpawnArea.blockOtherTeams != TEAM_INVALID && noSpawnArea.blockOtherTeams != team ) - return false - } - - array<entity> projectiles = GetProjectileArrayEx( "any", TEAM_ANY, TEAM_ANY, spawnpoint.GetOrigin(), 400 ) - foreach ( entity projectile in projectiles ) - if ( projectile.GetTeam() != team ) - return false - - if ( Time() - spawnpoint.s.lastUsedTime <= 1.0 ) - return false - - return true -} - -void function RateSpawnpoints_Generic( int checkClass, array<entity> spawnpoints, int team, entity player ) -{ - // 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 ) - } -} - -void function OnSwitchingSides() -{ - file.sidesSwitched = true -}
\ No newline at end of file |