Skip to content

Commit

Permalink
Merge pull request #8 from CFC-Servers/master_syntax_fixes
Browse files Browse the repository at this point in the history
Syntax and logic fixes
  • Loading branch information
brandonsturgeon authored Mar 10, 2020
2 parents 704e7a3 + 1ed0227 commit 6a9b375
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 149 deletions.
125 changes: 67 additions & 58 deletions lua/autorun/cfc_random_spawn.lua
Original file line number Diff line number Diff line change
@@ -1,58 +1,67 @@

cfcRandomSpawn = cfcRandomSpawn or {
config = {},

IDENTIFIER = "cfcRandomSpawn",
NICE_NAME = "cfcRandomSpawn"
}


local version = 1

if not frile or frile.VERSION < version then
frile = {
VERSION = version,

STATE_SERVER = 0,
STATE_CLIENT = 1,
STATE_SHARED = 2
}

function frile.includeFile( filename, state )
if state == frile.STATE_SHARED or filename:find( "sh_" ) then
if SERVER then AddCSLuaFile( filename ) end
include( filename )
elseif state == frile.STATE_SERVER or SERVER and filename:find( "sv_" ) then
include( filename )
elseif state == frile.STATE_CLIENT or filename:find( "cl_" ) then
if SERVER then AddCSLuaFile( filename )
else include( filename ) end
end
end

function frile.includeFolder( currentFolder, ignoreFilesInFolder, ignoreFoldersInFolder )
if file.Exists( currentFolder .. "sh_frile.lua", "LUA" ) then
frile.includeFile( currentFolder .. "sh_frile.lua" )

return
end

local files, folders = file.Find( currentFolder .. "*", "LUA" )

if not ignoreFilesInFolder then
for _, File in ipairs( files ) do
frile.includeFile( currentFolder .. File )
end
end

if not ignoreFoldersInFolder then
for _, folder in ipairs( folders ) do
frile.includeFolder( currentFolder .. folder .. "/" )
end
end
end
end

-- Do not adjust the load order. You must first load the libraries, than module and then languages.
frile.includeFolder( "cfc_random_spawn/", false, true )
frile.includeFolder( "cfc_random_spawn/module/" )

CFCRandomSpawn = CFCRandomSpawn or {
config = {},

IDENTIFIER = "cfcRandomSpawn",
NICE_NAME = "cfcRandomSpawn"
}

local version = 1

-- A valid instance already exists
if CFCRandomSpawnInit and CFCRandomSpawnInit.VERSION >= version then return end

CFCRandomSpawnInit = {
VERSION = version,

STATE_SERVER = 0,
STATE_CLIENT = 1,
STATE_SHARED = 2
}

local function isSharedFile( filename, state )
return state == CFCRandomSpawnInit.STATE_SHARED or filename:find( "sh_" )
end

local function isServerFile( filename, state )
return state == CFCRandomSpawnInit.STATE_SERVER or ( SERVER and filename:find( "sv_" ) )
end

local function isClientFile( filename, state )
return state == CFCRandomSpawnInit.STATE_CLIENT or filename:find( "cl_" )
end

function CFCRandomSpawnInit.includeFile( filename, state )
if isSharedFile( filename, state ) then
if SERVER then AddCSLuaFile( filename ) end
include( filename )
elseif isServerFile( filename, state ) then
include( filename )
elseif isClientFile( filename, state ) then
if SERVER then AddCSLuaFile( filename ) else include( filename ) end
end
end

function CFCRandomSpawnInit.includeFolder( currentFolder, ignoreFilesInFolder, ignoreFoldersInFolder )
if file.Exists( currentFolder .. "sh_CFCRandomSpawnInit.lua", "LUA" ) then
return CFCRandomSpawnInit.includeFile( currentFolder .. "sh_CFCRandomSpawnInit.lua" )
end

local files, folders = file.Find( currentFolder .. " * ", "LUA" )

if not ignoreFilesInFolder then
for _, filename in ipairs( files ) do
CFCRandomSpawnInit.includeFile( currentFolder .. filename )
end
end

if not ignoreFoldersInFolder then
for _, folder in ipairs( folders ) do
CFCRandomSpawnInit.includeFolder( currentFolder .. folder .. "/" )
end
end
end

-- Do not adjust the load order. You must first load the libraries, then module, and then languages.
CFCRandomSpawnInit.includeFolder( "cfc_random_spawn/", false, true )
CFCRandomSpawnInit.includeFolder( "cfc_random_spawn/module/" )
148 changes: 79 additions & 69 deletions lua/cfc_random_spawn/module/sv_player_spawning.lua
Original file line number Diff line number Diff line change
@@ -1,69 +1,79 @@
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 {}

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

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 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
end

return totalDistanceSquared
end

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

function cfcRandomSpawn.updateSpawnPointRankings()
for _, spawn in pairs( customSpawnsForMap ) do
local playerNetForce = getPlayerForceFromCustomSpawn( spawn )

local spawnDistanceData = {}
spawnDistanceData["spawn"] = spawn

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


cfcRandomSpawn.spawnPointRankings = PlayerIDSFromSpawn
table.SortByMember( cfcRandomSpawn.spawnPointRankings, "inverse-distance-squared", true )
end

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

function cfcRandomSpawn.handlePlayerSpawn( ply )
if not ( ply and IsValid( ply ) ) then return end
if ply.LinkedSpawnPoint then return end

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

ply:SetPos( optimalSpawnPosition )
end

hook.Add( "PlayerSpawn", "CFC_PlayerSpawning", cfcRandomSpawn.handlePlayerSpawn )
end
CFCRandomSpawn = CFCRandomSpawn or {}

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

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

if not mapHasCustomSpawns then return end

CFCRandomSpawn.spawnPointRankings = CFCRandomSpawn.spawnPointRankings or {}

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

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
local function getPlayerForceFromCustomSpawn( spawn )
local totalDistanceSquared = 0
local measurablePlayers = getMeasurablePlayers()

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( randMin, randMax )
return CFCRandomSpawn.spawnPointRankings[randomSpawn]["spawn_pos"]
end

function CFCRandomSpawn.updateSpawnPointRankings( ply )
local playerIDSFromSpawns = {}
local playerPVPStatus = ply:GetNWBool( "CFC_PvP_Mode", false )

for _, spawn in pairs( customSpawnsForMap ) do
local isPvpSpawn = spawn["isPvpSpawn"]

if playerPVPStatus and isPvpSpawn then
local spawnPosition = spawn["spawn_pos"]
local playerNetForce = getPlayerForceFromCustomSpawn( spawnPosition )
local spawnDistanceData = {}
spawnDistanceData["spawn"] = spawnPosition
spawnDistanceData["inverse-distance-squared"] = playerNetForce

table.insert( playerIDSFromSpawn, spawnDistanceData ) -- IDS == Inverse Distance Squared
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 and IsValid( ply ) ) then return end
if ply.LinkedSpawnPoint then return end

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

ply:SetPos( optimalSpawnPosition )
end

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

46 changes: 24 additions & 22 deletions lua/cfc_random_spawn/sh_config.lua
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@

cfcRandomSpawn.config.MAXIMUM_DISTANCE_FROM_PLAYERS = 500 -- The maximum distance it checks for players for when you spawn. You will automatically spawn where the least players are.

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 )
}

cfcRandomSpawn.config.MAXIMUM_DISTANCE_FROM_PLAYERS = 500 -- The maximum distance it checks for players for when you spawn_pos. You will automatically spawn where the least players are.

cfcRandomSpawn.config.CUSTOM_SPAWNS = {}
cfcRandomSpawn.config.CUSTOM_SPAWNS["gm_bluehills_test3"] = {

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

}

0 comments on commit 6a9b375

Please sign in to comment.