• [Help] damaging player and timers
    8 replies, posted
Hi, I am VERY new to lua, but I have been watching the Tutorial on Gmod Lua series by MrCosmicSeagull on youtube. I am on episode 8, where in the episode before I learned about Timers. So the timer I wanted to set up would be as if the player is poisoned (damage over time), but I am facing 2 issues: The first is my timer seems to fail. Since I am working on a Gamemode Templete, I have 3 lua files; init.lua, cl_ini.lua, and shared.lua In the shared.lua I create my timer SHARED.LUA: [CODE] // Timer should tick every second for 5 seconds timer.Create("health_degen", 1, 5, HealthDegen) [/CODE] Now in init.lua i have the timer starting, and the function of the timer: INIT.LUA: [CODE] // Start the timer function GM:PlayerSpawn( ply ) timer.Start("health_degen") end // When the timer ticks, damage the enemy function HealthDegen() /*ply:SetHealth( ply:Health() -= 5 )*/ ply:PrintMessage( HUD_PRINTTALK, "You are poisoned, " .. ply:Name() .. "!" ) ply:SetHealth( 5 ) sound.Play( "physics/body/body_medium_break2.wav", Vector( 0, 0, 0 ) ) end [/CODE] When I start up my game mode, I get an alert "Timer Failed! [health_degen][@gamemodes/playerquest/gamemode/init.lua (line 13)]" And line 13 would be: [CODE]timer.Start("health_degen")[/CODE] What am I doing wrong with my timer setup? My second issue is if the timer were to go off, damage wouldnt be dealt, I tried using these lines of codes to deal damage but non worked: [CODE] // make sure this code gets initiated ply:PrintMessage( HUD_PRINTTALK, "Player should take damage" ) // this should set my Health to 5 but doesnt do anything it seems. ply:SetHealth( 5 ) // my thought behind this setup was it would get my current health, and subtract by 5. ply:SetHealth( ply:Health() -= 5 ) [/CODE]
[code] -- init.lua local function damageProc(ply) -- you need to pass the player argument to the function. if (!IsValid(ply) or !ply:Alive()) then return end -- make sure the player is still exists and is alive ply:SetHealth(ply:Health()-5) -- set their health to their current health minus 5 ply:ChatPrint("You are poisoned, " .. ply:Name() .. "!") -- Use chatprint because why not. ply:EmitSound("physics/body/body_medium_break2.wav") -- emitsound because why not. end function GM:PlayerSpawn( ply ) timer.Create("health_degen", 1, 5, function() damageProc(ply) end) --timer.Create starts the timer when it is made. remembering to pass the player entity. end [/code] All of your code should be done server side, no need for shared stuff. I suggest you read the [URL="http://wiki.garrysmod.com/"]wiki articles[/URL] on the functions you're trying to use. For reference, the Garry's Mod wiki has [URL="http://wiki.garrysmod.com/page/Category:Lua_Tutorials"]a lot of tutorials[/URL] on getting into coding for Garry's Mod, and the [URL="https://maurits.tv/data/garrysmod/wiki/wiki.garrysmod.com/index7a06.html"]Old Garry's Mod Wiki[/URL] has a lot of useful information regarding that as well.
Did you include your init.lua correctly? It's erroring because it thinks the function doesn't exist. Also, you are calling ply in a function that doesn't supply that argument. Lastly, -= doesn't exist in lua.
Make sure to check if ply is nil
[QUOTE=Lolcats;47889584] All of your code should be done server side, no need for shared stuff. I suggest you read the [URL="http://wiki.garrysmod.com/"]wiki articles[/URL] on the functions you're trying to use. For reference, the Garry's Mod wiki has [URL="http://wiki.garrysmod.com/page/Category:Lua_Tutorials"]a lot of tutorials[/URL] on getting into coding for Garry's Mod, and the [URL="https://maurits.tv/data/garrysmod/wiki/wiki.garrysmod.com/index7a06.html"]Old Garry's Mod Wiki[/URL] has a lot of useful information regarding that as well.[/QUOTE] Since I dont plan this game mode to be multiplayer, do I even need shared.lua, and cl_init.lua (should I just have 1 lua?) I was using the website you linked: [URL="http://wiki.garrysmod.com/"]wiki articles[/URL] to try and solve my timer issue, health issue, and just searching around, but for finding out my issues, I probably have to search harder. I am also going to take a look at the tutorial page, specifically these ones: [url]http://wiki.garrysmod.com/page/Gamemode_Creation[/url] [url]http://wiki.garrysmod.com/page/Player_Classes[/url] This one should be esspecially helpful for me since I want to make a "Staff" that shoots Ice Spears (Staff model will be Stun Stick, and the ice spear will use model "wood_chunk08f") [url]http://wiki.garrysmod.com/page/Chair_Throwing_Gun[/url] [QUOTE=code_gs;47889602]Did you include your init.lua correctly? It's erroring because it thinks the function doesn't exist. Also, you are calling ply in a function that doesn't supply that argument. Lastly, -= doesn't exist in lua.[/QUOTE] in my INIT.LUA file I have these: AddCSLuaFile( "cl_init.lua" ) AddCSLuaFile( "shared.lua" ) include( 'shared.lua' ) also thanks for confiming -= and += doesnt work [QUOTE=Kevlon;47889671]Make sure to check if ply is nil[/QUOTE] What is Nil? I see it in the console with an Alert Message: "[ERROR] gamemodes/playerquest/gamemode/shared.lua:8: bad argument #4 to 'Create' (function expected, got nil)" Also does Lua read from bottom to top? Right now this is my code, however I recently swapped the position of Part 1 with Part 2, if the GM:PlayerSpawn was above the Damage over Time effect, then the SetGravity, MaxHealth, Walkspeed, ect wouldnt work. [CODE] --Part 1 local function damageProc(ply) -- you need to pass the player argument to the function. if (!IsValid(ply) or !ply:Alive()) then return end -- make sure the player is still exists and is alive ply:SetHealth(ply:Health()-5) -- set their health to their current health minus 5 ply:ChatPrint("You are poisoned, " .. ply:Name() .. "!") -- Use chatprint because why not. ply:EmitSound("physics/body/body_medium_break2.wav") -- emitsound because why not. end --Part 2 function GM:PlayerSpawn( ply ) self.BaseClass:PlayerSpawn( ply ) ply:SetGravity ( 1 ) ply:SetMaxHealth( 100, true ) ply:SetWalkSpeed( 100 ) ply:SetRunSpeed ( 200 ) ply:SetModel("model/players/male_07") ply:Give("weapon_stunstick") timer.Create("health_degen", 1, 5, function() damageProc(ply) end) --timer.Create starts the timer when it is made. remembering to pass the player entity. end [/CODE] EDIT: I want to take this opportunity to ask how to access entities from other scripts. For example, if I mod an enemy Antlion so that when it hits me, how can I get applied with the Poison effect that we created here? I guess a better wuestion would be, do I need Damage over Time effects in the INIT.LUA file and when hit by enemies or objects that can poison or Damage over Time, that enemy accesses the INIT.LUA and triggers the Poison event? Thanks for the help guys!
I don't understand what/who you're asking. Does the code I supplied work how you intend? Lua reads from the top down.
[QUOTE=Lolcats;47889783]I don't understand what/who you're asking. Does the code I supplied work how you intend? Lua reads from the top down.[/QUOTE] I was trying to reply to everyone, hahah, and yes the code you provided works, I had to rearrange the GM:PlayerSpawn to be under the damageProc. I do have a quick question. Do I need Damage over Time(poison) effects in the INIT.LUA file and when hit by enemies or objects that can poison or Damage over Time, that enemy accesses the INIT.LUA and triggers the Poison event?
[URL="https://maurits.tv/data/garrysmod/wiki/wiki.garrysmod.com/index611a.html"]When you localize a function[/URL], it can only be called within that file. In your case, I would recommend making a global table like this [code] NGM = {} --or whatever clever thing you come up with for your gamemode [/code] and put your functions inside it. You can then call your functions outside of the init.lua file. In example [code] NGM = {} function NGM.damageProc(ply) -- you can now access this function anywhere by calling NGM.damageProc() if (!IsValid(ply) or !ply:Alive()) then return end ply:SetHealth(ply:Health()-5) ply:ChatPrint("You are poisoned, " .. ply:Name() .. "!") ply:EmitSound("physics/body/body_medium_break2.wav") end function GM:PlayerSpawn( ply ) timer.Create("health_degen", 1, 5, function() NGM.damageProc(ply) end) end [/code] So if you wanted to call this in another file, you could do exactly how you do in the PlayerSpawn function. Remember though that Server and Client are separate realms, so you won't be able to call NGM.damageProc() anywhere clientside.
[QUOTE=Lolcats;47889820][URL="https://maurits.tv/data/garrysmod/wiki/wiki.garrysmod.com/index611a.html"]When you localize a function[/URL], it can only be called within that file. In your case, I would recommend making a global table like this [code] NGM = {} --or whatever clever thing you come up with for your gamemode [/code] and put your functions inside it. You can then call your functions outside of the init.lua file. In example [code] NGM = {} function NGM.damageProc(ply) -- you can now access this function anywhere by calling NGM.damageProc() if (!IsValid(ply) or !ply:Alive()) then return end ply:SetHealth(ply:Health()-5) ply:ChatPrint("You are poisoned, " .. ply:Name() .. "!") ply:EmitSound("physics/body/body_medium_break2.wav") end function GM:PlayerSpawn( ply ) timer.Create("health_degen", 1, 5, function() NGM.damageProc(ply) end) end [/code] So if you wanted to call this in another file, you could do exactly how you do in the PlayerSpawn function. Remember though that Server and Client are separate realms, so you won't be able to call NGM.damageProc() anywhere clientside.[/QUOTE] Yeah I am hoping you can explain the "NGM=NGM or {}" part to me someday, I will mark this post as solved, and I'll pm you, but please dont reply tonight since you stated you are tired tonight, hahah.
Sorry, you need to Log In to post a reply to this thread.