So, I made this script with my blood, sweat, and tears. I think it's a very cool and neat addition to my TTT server. Unfortunately, the script will continuously crash/stop my server.
What the script does is it respawns everyone on the server two times. Once when the round ends, and again when the end round timer hits 0:14. It will also give randomized weapons on spawn.
It also keeps track of their kills, and rewards the winner points based on kill count.
There are no errors in console whatsoever. The server will just stop printing anything in console and all players on at the time will lose connection. Usually, the server will need to be manually restarted.
I'm at a loss at why this would happen. If anyone could help me or, at the very least, point me in the right direction I'd greatly appreciate it.
Here's the script:
[code]
if SERVER then
-- Initialize PRDM vars
local prdmWinner = ""
local prdmWinnerKC = 0
local prdmWinnerENT = ""
local pistolWepID = { "pistol", "magnum", "revolver" }
local rifleWepID = { "m16", "rifle", "ak47", "galil", "famas", "m3", "p90", "sg552", "shotgun", "sledge" }
local specialWepID = { "awp", "dragonsbreath", "medgun", "jihad" }
local wepID = ""
local pistolWepName = { "Five-SeveN", "Magnum", "Desert Eagle" }
local rifleWepName = { "M16", "Scout", "AK47", "Galil", "Famas", "M3", "P90", "SG552", "XM1014", "useless piece of sh- I mean a H.U.G.E-249" }
local specialWepName = { "AWP", "Dragon's Breath", "Med-Gun", "Billy Bomb" }
local wepName = ""
-- PRDM Respawn function
function prdmRespawn()
for k, v in pairs(player.GetAll()) do
-- Intializing random weapon vars
local randWepCategory = math.random(1,100)
local randPistol = math.random(1,3)
local randRifle = math.random(1,10)
local randSpecial = math.random(1,4)
-- Handling weapon IDs and names
-- Category: Pistol
if randWepCategory <= 45 then
wepID = pistolWepID[randPistol]
wepName = pistolWepName[randPistol]
-- Category: Rifle/Shotgun
elseif randWepCategory > 45 and randWepCategory <= 90 then
wepID = rifleWepID[randRifle]
wepName = rifleWepName[randRifle]
-- Category: Special
else
wepID = specialWepID[randSpecial]
wepName = specialWepName[randSpecial]
end
-- PointShop perma weapon checker
local permWepCount = v:PS_NumItemsEquippedFromCategory('Weapons')
-- The actual respawn
if !v:Alive() and IsValid(v) then
-- Find corpse
local corpse = corpse_find(v)
if corpse then corpse_remove(corpse) end
-- RESPAWN
v:SpawnForRound()
-- Give random weapon
-- zm IDs
if permWepCount == 0 then
if wepID == "pistol" or wepID == "revolver" or wepID == "rifle" or wepID == "shotgun" or wepID == "sledge" then
v:Give("weapon_zm_" .. wepID)
v:SelectWeapon("weapon_zm_" .. wepID)
-- ttt IDs
else
v:Give("weapon_ttt_" .. wepID)
v:SelectWeapon("weapon_ttt_" .. wepID)
end
-- Print out weapon received
v:PrintColor(WF_TC_WHITE, "You've been given a ", WF_TC_RED, wepName, WF_TC_WHITE, "!")
end
end
end
end
hook.Add("TTTEndRound", "PRDM", function()
-- Setting to default values.
prdmWinner = ""
prdmWinnerKC = 0
prdmWinnerENT = ""
-- Set PRDM kill counts back to 0 and health to 100.
for k, v in pairs(player.GetAll()) do
v:SetFrags(0)
v:SetHealth(100)
end
-- Set PRDM state and respawn first time.
prdmState = true
prdmRespawn()
-- PRDM respawn timer
timer.Simple(15, function()
prdmRespawn()
end )
-- Timer for kill count check and rewards.
timer.Simple(27, function()
-- Check kill counts and find winner.
for k, v in pairs(player.GetAll()) do
if v:Frags() > prdmWinnerKC then
prdmWinnerKC = v:Frags()
prdmWinner = v:Name()
prdmWinnerENT = v
end
end
-- If winner got more than 1 kill
if prdmWinnerKC > 1 then
for k, ply in pairs(player.GetAll()) do
ply:PrintColor(WF_TC_RED, prdmWinner .. " won ", WF_TC_WHITE, "PRDM with ", WF_TC_RED, prdmWinnerKC .. " kills", WF_TC_WHITE, "!")
end
prdmWinnerENT:PS_Notify("You've been given ", (25 * prdmWinnerKC), " points for winning PRDM!")
prdmWinnerENT:PS_GivePoints(25 * prdmWinnerKC)
-- If winner only got 1 kill
elseif prdmWinnerKC == 1 then
for k, ply in pairs(player.GetAll()) do
ply:PrintColor(WF_TC_RED, prdmWinner .. " won ", WF_TC_WHITE, "PRDM with ", WF_TC_RED, prdmWinnerKC .. " kill", WF_TC_WHITE, "!")
end
prdmWinnerENT:PS_Notify("You've been given ", (25 * prdmWinnerKC), " points for winning PRDM!")
prdmWinnerENT:PS_GivePoints(25 * prdmWinnerKC)
-- If no one won PRDM
else
for k, ply in pairs(player.GetAll()) do
ply:PrintColor(WF_TC_RED, "No one won ", WF_TC_WHITE, "PRDM!")
end
end
-- Set prdm state to false
prdmState = false
end )
end )
--[[hook.Add("TTTPrepareRound", "EndPRDM", function()
-- Stop PRDM
prdmState = false
timer.Remove("PRDMRespawnTimer")
timer.Remove("PRDMWinnerCheckTimer")
end )]]
hook.Add("PlayerDeath", "PrintDeaths", function(victim, weapon, attacker)
-- Check if PRDM and attacker and victim are players and valid
if prdmState == true and IsValid(victim) and IsValid(attacker) and victim:IsPlayer() and attacker:IsPlayer() then
-- Suicide
if (victim == attacker) then
for k, ply in pairs(player.GetAll()) do
ply:PrintColor(WF_TC_RED, victim:Name(), WF_TC_WHITE, " commited suicide.")
end
-- Actual kill
else
for k, ply in pairs(player.GetAll()) do
ply:PrintColor(WF_TC_RED, victim:Name(), WF_TC_WHITE, " was killed by ", WF_TC_RED, attacker:Name(), WF_TC_WHITE, ".")
end
-- Add to kill count and give points.
attacker:AddFrags(1)
attacker:PS_Notify("You've been given 5 points for killing someone in PRDM!")
attacker:PS_GivePoints(5)
end
end
end )
end
[/code]
Bump because I still need help, if anyone is willing to offer.
I would try removing bits of code until it doesn't crash anymore.
Add debug messages to see where and when things are getting called.
[QUOTE=Derek_SM;51701125]I would try removing bits of code until it doesn't crash anymore.
Add debug messages to see where and when things are getting called.[/QUOTE]
I've tried this, even stripping it to it's bare basics and just respawning. The version excluded kill counts and everything. It was strictly respawning.
The server still crashed.
Could it be a problem with timers? This has me so confused. There are no errors in console whatsoever. The server doesn't stop every end round, and even sometimes stops mid-round.
I'm at a loss. :/
If there are no errors in the console, add some.
If youhave to, put a print("LOADING LINE #334) to every and each line, until you find the source of the problem.
Also, when does the server crash exactly?
Can you post the code for these two functions:
corpse_find
corpse_remove
[QUOTE=Kiro The Pro;51701817]If there are no errors in the console, add some.
If youhave to, put a print("LOADING LINE #334) to every and each line, until you find the source of the problem.
Also, when does the server crash exactly?[/QUOTE]
I made prints like this to the console and it didn't help anything as the server usually just crashes at 0:00 in end round phase.
[editline]20th January 2017[/editline]
[QUOTE=Derek_SM;51702159]Can you post the code for these two functions:
corpse_find
corpse_remove[/QUOTE]
The functions are used from ULX TTT commands.
[code]
--[[corpse_find][Finds the corpse of a given player.]
@param {[PlayerObject]} v [The player that to find the corpse for.]
--]]
function corpse_find(v)
for _, ent in pairs( ents.FindByClass( "prop_ragdoll" )) do
if ent.uqid == v:UniqueID() and IsValid(ent) then
return ent or false
end
end
end
--[[corpse_remove][removes the corpse given.]
@param {[Ragdoll]} corpse [The corpse to be removed.]
--]]
function corpse_remove(corpse)
CORPSE.SetFound(corpse, false)
if string.find(corpse:GetModel(), "zm_", 6, true) then
corpse:Remove()
elseif corpse.player_ragdoll then
corpse:Remove()
end
end
[/code]
It all looks fine at a glance so I don't know.
But what is the point of this
[lua]
prdmRespawn()
-- PRDM respawn timer
timer.Simple(15, function()
prdmRespawn()
end )
[/lua]
Put your function in the TTTBeginRound or whatever hook TTT uses, don't rely on these things.
Also I would change all of those timer.Simple's to each individual timer.Create's. If something happens and you restart the round within those 15 seconds the function will be called twice instead of once with a timer.Simple
[QUOTE=Derek_SM;51702623]It all looks fine at a glance so I don't know.
But what is the point of this
[lua]
prdmRespawn()
-- PRDM respawn timer
timer.Simple(15, function()
prdmRespawn()
end )
[/lua]
Put your function in the TTTBeginRound or whatever hook TTT uses, don't rely on these things.
Also I would change all of those timer.Simple's to each individual timer.Create's. If something happens and you restart the round within those 15 seconds the function will be called twice instead of once with a timer.Simple[/QUOTE]
That would defeat the entire purpose of the script. The prdmRespawn function was created by me to respawn IN END ROUND.
Sorry, you need to Log In to post a reply to this thread.