• self:function doesn't work
    9 replies, posted
I'm trying to call a function that is in another script using self:function. This is the code I've got currently: [CODE] function GM:TimerCheck() if roundTimer <= 0 then self:EndTheRound(2, nil) end end [/CODE] I'm trying to call a function within a script within the gamemode Murder, in the script sv_rounds. This is the function: [CODE] function GM:EndTheRound(reason, murderer) if self.RoundStage != 1 then return end local players = team.GetPlayers(2) for k, ply in pairs(players) do ply:SetTKer(false) ply:SetMurdererRevealed(false) ply:UnMurdererDisguise() end if reason == 3 then if murderer then local col = murderer:GetPlayerColor() local msgs = Translator:AdvVarTranslate(translate.murdererDisconnectKnown, { murderer = {text = murderer:Nick() .. ", " .. murderer:GetBystanderName(), color = Color(col.x * 255, col.y * 255, col.z * 255)} }) local ct = ChatText(msgs) ct:SendAll() -- ct:Add(", it was ") -- ct:Add(murderer:Nick() .. ", " .. murderer:GetBystanderName(), Color(col.x * 255, col.y * 255, col.z * 255)) else local ct = ChatText() ct:Add(translate.murdererDisconnect) ct:SendAll() end elseif reason == 2 then local col = murderer:GetPlayerColor() local msgs = Translator:AdvVarTranslate(translate.winBystandersMurdererWas, { murderer = {text = murderer:Nick() .. ", " .. murderer:GetBystanderName(), color = Color(col.x * 255, col.y * 255, col.z * 255)} }) local ct = ChatText() ct:Add(translate.winBystanders, Color(20, 120, 255)) ct:AddParts(msgs) ct:SendAll() elseif reason == 1 then local col = murderer:GetPlayerColor() local msgs = Translator:AdvVarTranslate(translate.winMurdererMurdererWas, { murderer = {text = murderer:Nick() .. ", " .. murderer:GetBystanderName(), color = Color(col.x * 255, col.y * 255, col.z * 255)} }) local ct = ChatText() ct:Add(translate.winMurderer, Color(190, 20, 20)) ct:AddParts(msgs) ct:SendAll() end net.Start("DeclareWinner") net.WriteUInt(reason, 8) if murderer then net.WriteEntity(murderer) net.WriteVector(murderer:GetPlayerColor()) net.WriteString(murderer:GetBystanderName()) else net.WriteEntity(Entity(0)) net.WriteVector(Vector(1, 1, 1)) net.WriteString("?") end for k, ply in pairs(team.GetPlayers(2)) do net.WriteUInt(1, 8) net.WriteEntity(ply) net.WriteUInt(ply.LootCollected, 32) net.WriteVector(ply:GetPlayerColor()) net.WriteString(ply:GetBystanderName()) end net.WriteUInt(0, 8) net.Broadcast() for k, ply in pairs(players) do if !ply.HasMoved && !ply.Frozen && self.AFKMoveToSpec:GetBool() then local oldTeam = ply:Team() ply:SetTeam(1) GAMEMODE:PlayerOnChangeTeam(ply, 1, oldTeam) local col = ply:GetPlayerColor() local msgs = Translator:AdvVarTranslate(translate.teamMovedAFK, { player = {text = ply:Nick(), color = Color(col.x * 255, col.y * 255, col.z * 255)}, team = {text = team.GetName(1), color = team.GetColor(2)} }) local ct = ChatText() ct:AddParts(msgs) ct:SendAll() end if ply:Alive() then ply:Freeze(false) ply.Frozen = false end end self.RoundUnFreezePlayers = nil self.MurdererLastKill = nil hook.Call("OnEndRound") self.RoundCount = self.RoundCount + 1 local limit = self.RoundLimit:GetInt() if limit > 0 then if self.RoundCount >= limit then self:ChangeMap() self:SetRound(4) return end end self:SetRound(2) end [/CODE] The problem is that whenever i go to test the code, i always get the error: "attempt to call method 'EndTheRound' (a nil value) and I'm not sure why. I'm new to this kinda stuff so If it's a nooby question then I'm sorry Could anyone help me out?
Are you sure that file with function GM:EndTheRound(reason, murderer) is being run? You have to include() it. Put a print in the first line, make sure that it works.
[QUOTE=Neat-Nit;50126941]Are you sure that file with function GM:EndTheRound(reason, murderer) is being run? You have to include() it. Put a print in the first line, make sure that it works.[/QUOTE] It isn't being run at the time I call it through my script but it does get ran: [CODE] function GM:RoundCheckForWin() local murderer local players = team.GetPlayers(2) if #players <= 0 then self:SetRound(0) return end local survivors = {} for k,v in pairs(players) do if v:Alive() && !v:GetMurderer() then table.insert(survivors, v) end if v:GetMurderer() then murderer = v end end // check we have a murderer if !IsValid(murderer) then self:EndTheRound(3, murderer) return end // has the murderer killed everyone? if #survivors < 1 then self:EndTheRound(1, murderer) return end // is the murderer dead? if !murderer:Alive() then self:EndTheRound(2, murderer) return end // keep playing. end [/CODE] If that's what you mean
I meant:[lua]print("TEST TEST TEST TEST TEST") function GM:EndTheRound(reason, murderer) if self.RoundStage != 1 then return end ...[/lua] and check to see that it prints in the console
[QUOTE=Neat-Nit;50127060]I meant:[lua]print("TEST TEST TEST TEST TEST") function GM:EndTheRound(reason, murderer) if self.RoundStage != 1 then return end ...[/lua] and check to see that it prints in the console[/QUOTE] Seems the script isn't being run. Does that mean i have to check when it's being run somehow before i try to use the function?
I may be wrong, but I think that your function GM:TimerCheck() is ran before sv_rounds.lua You should maybe include your custom script to Gamemode initialization (see this : [url]https://github.com/garrynewman/garrysmod/blob/451b4ff5d1aea7b9b06a8024ef706c248a79647e/garrysmod/gamemodes/base/gamemode/init.lua[/url]) To make some debugging, you could also use hook Think which is only ran once the first player join the game. I know that it's the ugliest way to do it :p [code] hook.Add("Think", "Load Your Script", function() function GM:TimerCheck() if roundTimer <= 0 then self:EndTheRound(2, nil) end end hook.Remove("Think", "Load Your Script") end) [/code]
[QUOTE=Speedy02;50127855]I may be wrong, but I think that your function GM:TimerCheck() is ran before sv_rounds.lua You should maybe include your custom script to Gamemode initialization (see this : [url]https://github.com/garrynewman/garrysmod/blob/451b4ff5d1aea7b9b06a8024ef706c248a79647e/garrysmod/gamemodes/base/gamemode/init.lua[/url]) To make some debugging, you could also use hook Think which is only ran once the first player join the game. I know that it's the ugliest way to do it :p [code] hook.Add("Think", "Load Your Script", function() function GM:TimerCheck() if roundTimer <= 0 then self:EndTheRound(2, nil) end end hook.Remove("Think", "Load Your Script") end) [/code][/QUOTE] The script i used is ran before the sv_rounds script but it doesn't call the function for a while after sv_rounds is being used so i wouldn't think it would be a problem. Unless it is? [editline]14th April 2016[/editline] [QUOTE=Speedy02;50127855]I may be wrong, but I think that your function GM:TimerCheck() is ran before sv_rounds.lua You should maybe include your custom script to Gamemode initialization (see this : [url]https://github.com/garrynewman/garrysmod/blob/451b4ff5d1aea7b9b06a8024ef706c248a79647e/garrysmod/gamemodes/base/gamemode/init.lua[/url]) To make some debugging, you could also use hook Think which is only ran once the first player join the game. I know that it's the ugliest way to do it :p [code] hook.Add("Think", "Load Your Script", function() function GM:TimerCheck() if roundTimer <= 0 then self:EndTheRound(2, nil) end end hook.Remove("Think", "Load Your Script") end) [/code][/QUOTE] Also using GM:Initialization won't work considering it only runs once when I'm wanting to it keep checking if roundTimer is below 0 [editline]14th April 2016[/editline] I'm not sure if this is a issue but the script that I'm using is running on the client side while the function I'm trying to use is in a script being run on the server side.
-snip- i was being dumb
Have you used include?
[QUOTE=Neat-Nit;50129418]Have you used include?[/QUOTE] Don't worry. I figured out the problem. I was trying to call a function that was on the server side from the client side without using something like net.SendToServer. My mistake but I've got it working now :)
Sorry, you need to Log In to post a reply to this thread.