Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Syntax and logic fixes #8

Merged
merged 8 commits into from
Mar 10, 2020
94 changes: 50 additions & 44 deletions lua/cfc_random_spawn/module/sv_player_spawning.lua
Original file line number Diff line number Diff line change
@@ -1,70 +1,76 @@
cfcRandomSpawn = cfcRandomSpawn or {}

local customSpawnsForMap = cfcRandomSpawn.config.CUSTOM_SPAWNS[game.GetMap()]
local mapHasCustomSpawns = customSpawnsForMap ~= nil

hook.Remove( "PlayerSpawn", "CFC_PlayerSpawning" )

if mapHasCustomSpawns then
cfcRandomSpawn.spawnPointRankings = cfcRandomSpawn.spawnPointRankings or {}
if not mapHasCustomSpawns then return end
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Short-circuit Instead of blanketing the entire file in a condition


local function getMeasurablePlayers()
local measurablePlayers = {}
for _, ply in pairs( player.GetHumans() ) do
if ( ply:Alive() ) then
table.insert( measurablePlayers, ply )
end
end
cfcRandomSpawn.spawnPointRankings = cfcRandomSpawn.spawnPointRankings or {}

return measurablePlayers
local function getMeasurablePlayers()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could do something stupid here, and maintain a cache of alive players and only invalidate it when a player dies or spawns - that way it'd be slightly more efficient

local measurablePlayers = {}
for _, ply in pairs( player.GetHumans() ) do
if ( ply:Alive() ) then
table.insert( measurablePlayers, ply )
end
end

-- This is operating on a model of spawn points and players as electrons putting a force on each other
-- The best spawn point is the spawn point under the smallest sum of forces then. This is why we use physics terms here
local function getPlayerForceFromCustomSpawn( spawn )
local totalDistanceSquared = 0
local measurablePlayers = getMeasurablePlayers()
return measurablePlayers
end

-- This is operating on a model of spawn points and players as electrons putting a force on each other
-- The best spawn point is the spawn point under the smallest sum of forces then. This is why we use physics terms here
local distSqr = 900 --(30^2)
local randMin, randMax = 1, 4
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract these houdini bois

local function getPlayerForceFromCustomSpawn( spawn )
local totalDistanceSquared = 0
local measurablePlayers = getMeasurablePlayers()

for _, ply in pairs( measurablePlayers ) do
local plyDistanceSqr = ( ply:GetPos():DistToSqr( spawn ) )
if plyDistanceSqr < 30*30 then plyDistanceSqr = 1 end
totalDistanceSquared = totalDistanceSquared + 1/( plyDistanceSqr )
for _, ply in pairs( measurablePlayers ) do
local plyDistanceSqr = ( ply:GetPos():DistToSqr( spawn ) )
if plyDistanceSqr < distSqr then plyDistanceSqr = 1 end
totalDistanceSquared = totalDistanceSquared + 1 / ( plyDistanceSqr )
end
return totalDistanceSquared
end

function cfcRandomSpawn.getOptimalSpawnPosition()
local randomSpawn = math.random(1,4)
return cfcRandomSpawn.spawnPointRankings[randomSpawn]["spawn"]
end
return totalDistanceSquared
end

function cfcRandomSpawn.updateSpawnPointRankings()
local averagePlayerDistanceFromSpawns = {}
function cfcRandomSpawn.getOptimalSpawnPosition()
local randomSpawn = math.random( randMin, randMax )
return cfcRandomSpawn.spawnPointRankings[randomSpawn]["spawn"]
end

for _, spawn in pairs( customSpawnsForMap ) do
local playerNetForce = getPlayerForceFromCustomSpawn( spawn )
function cfcRandomSpawn.updateSpawnPointRankings( ply )
local playerIDSFromSpawns = {}
local playerPVPStatus = ply:GetNWBool( "CFC_PvP_Mode", false )

for _, spawn in pairs( customSpawnsForMap ) do
if playerPVPStatus and spawn["pvp"] then
local playerNetForce = getPlayerForceFromCustomSpawn( spawn["spawn"] )
local spawnDistanceData = {}
spawnDistanceData["spawn"] = spawn

spawnDistanceData["spawn"] = spawn["spawn"]
spawnDistanceData["inverse-distance-squared"] = playerNetForce
table.insert( PlayerIDSFromSpawn, spawnDistanceData ) --ISD == Inverse Distance Squared
end


cfcRandomSpawn.spawnPointRankings = PlayerIDSFromSpawn
table.insert( playerIDSFromSpawn, spawnDistanceData ) --ISD == Inverse Distance Squared
justinmuskopf marked this conversation as resolved.
Show resolved Hide resolved
end
cfcRandomSpawn.spawnPointRankings = playerIDSFromSpawns
table.SortByMember( cfcRandomSpawn.spawnPointRankings, "inverse-distance-squared", true )
end

--timer.Create( "CFC_UpdateOptimalSpawnPosition", 0.5, 0, cfcRandomSpawn.updateSpawnPointRankings )
end

function cfcRandomSpawn.handlePlayerSpawn( ply )
if not (ply && IsValid( ply )) then return end
if ply.LinkedSpawnPoint then return end
function cfcRandomSpawn.handlePlayerSpawn( ply )
if not ( ply && IsValid( ply ) ) then return end
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When CFCLib is official, this will be CFCLib.isValidPlayer( ply )

brandonsturgeon marked this conversation as resolved.
Show resolved Hide resolved
if ply.LinkedSpawnPoint then return end

cfcRandomSpawn.updateSpawnPointRankings()
local optimalSpawnPosition = cfcRandomSpawn.getOptimalSpawnPosition()
cfcRandomSpawn.updateSpawnPointRankings( ply )
local optimalSpawnPosition = cfcRandomSpawn.getOptimalSpawnPosition()

ply:SetPos( optimalSpawnPosition )
end

hook.Add( "PlayerSpawn", "CFC_PlayerSpawning", cfcRandomSpawn.handlePlayerSpawn )
ply:SetPos( optimalSpawnPosition )
end

hook.Add( "PlayerSpawn", "CFC_PlayerSpawning", cfcRandomSpawn.handlePlayerSpawn )

34 changes: 18 additions & 16 deletions lua/cfc_random_spawn/sh_config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,22 @@ cfcRandomSpawn.config.MAXIMUM_DISTANCE_FROM_PLAYERS = 500 -- The maximum distanc

cfcRandomSpawn.config.CUSTOM_SPAWNS = {}
cfcRandomSpawn.config.CUSTOM_SPAWNS["gm_bluehills_test3"] = {
Vector( 1104.6744384766, 131.18112182617, 64.03125 ),
Vector( 385.55798339844, 157.09564208984, 64.03125 ),
Vector( 1272.7860107422, -485.29537963867, 264.03125 ),
Vector( 1117.4444580078, -1345.0144042969, 64.03125 ),
Vector( 1458.7664794922, -484.67016601563, 64.03125 ),
Vector( 971.29565429688, 401.40603637695, 264.03125 ),
Vector( 392.85052490234, 146.80117797852, 264.03125 ),
Vector( -456.48602294922, -442.73083496094, 264.03125 ),
Vector( 1148.5478515625, 90.367889404297, 456.03125 ),
Vector( -214.91020202637, -623.013671875, 64.03125 ),
Vector( -726.35272216797, -540.54400634766, 64.03125 ),
Vector( -809.68939208984, 1255.5084228516, 464.03125 ),
Vector( 425.38064575195, 1636.2911376953, 64.968605041504 ),
Vector( -974.1875, 130.53991699219, 128.03125 ),
Vector( -1357.5144042969, 1473.0662841797, 128.03125 ),
Vector( -1000.3621826172, 1044.5682373047, 464.03125 )

{ "spawn" = Vector( 1104.6744384766, 131.18112182617, 64.03125 ), "pvp" = true },
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like these keys. Could we do:

{ "spawn_pos" = Vector( ), "isPvpSpawn" = true }

Something like that.

Mostly this helps the other file read better.

{ "spawn" = Vector( 385.55798339844, 157.09564208984, 64.03125 ), "pvp" = true },
{ "spawn" = Vector( 1272.7860107422, -485.29537963867, 264.03125 ), "pvp" = true },
{ "spawn" = Vector( 1117.4444580078, -1345.0144042969, 64.03125 ), "pvp" = true },
{ "spawn" = Vector( 1458.7664794922, -484.67016601563, 64.03125 ), "pvp" = true },
{ "spawn" = Vector( 971.29565429688, 401.40603637695, 264.03125 ), "pvp" = true },
{ "spawn" = Vector( 392.85052490234, 146.80117797852, 264.03125 ), "pvp" = true },
{ "spawn" = Vector( -456.48602294922, -442.73083496094, 264.03125 ), "pvp" = true },
{ "spawn" = Vector( 1148.5478515625, 90.367889404297, 456.03125 ), "pvp" = true },
{ "spawn" = Vector( -214.91020202637, -623.013671875, 64.03125 ), "pvp" = true },
{ "spawn" = Vector( -726.35272216797, -540.54400634766, 64.03125 ), "pvp" = true },
{ "spawn" = Vector( -809.68939208984, 1255.5084228516, 464.03125 ), "pvp" = true },
{ "spawn" = Vector( 425.38064575195, 1636.2911376953, 64.968605041504 ), "pvp" = true },
{ "spawn" = Vector( -974.1875, 130.53991699219, 128.03125 ), "pvp" = true },
{ "spawn" = Vector( -1357.5144042969, 1473.0662841797, 128.03125 ), "pvp" = true },
{ "spawn" = Vector( -1000.3621826172, 1044.5682373047, 464.03125 ) "pvp" = true }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious to know if this much precision is necessary...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"too much precision"

said no one ever.

Copy link
Member Author

@justinmuskopf justinmuskopf Oct 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay frick you


}