So, I am having some trouble with running a derma button in cl_init.lua to run a function in init.lua. I can get it to call it, but the content in my function does not work.
[B]
Originally[/B] in the init.lua it was:
[CODE]function poppygrow(self)
growtime = 2
-- Timers
self:SetModel("models/pot/pot_06.mdl")
if !IsValid(self) then return end
timer.Create( "timer1", growtime, 1, function()
if !IsValid(self) then return end
self:SetModel("models/pot/pot_07.mdl")
timer.Create( "timer2", growtime, 1, function()
if !IsValid(self) then return end
self:SetModel("models/pot/pot_08.mdl")
timer.Create( "timer3", growtime, 1, function()
if !IsValid(self) then return end
self:SetModel("models/pot/pot_09.mdl")
timer.Create( "timer4", growtime, 1, function()
if !IsValid(self) then return end
self:SetModel("models/pot/pot_10.mdl")
self.isUsable = true
end)
end)
end)
end)
end[/CODE]
This worked fine, I could call it using:
[CODE]function ENT:Use(activator)
poppygrow(self)
end [/CODE]
This was fine, then I created a derma button which inside the press function (so when you press it down it does):
[CODE]net.Start("start_pop_grow")
net.SendToServer()[/CODE]
[B]This is the problem[/B] is when calling the poppygrow(self) function it does not work. I have this:
[CODE]net.Receive( "start_pop_grow", function ( self )
growtime = 2
-- Timers
self:SetModel("models/pot/pot_06.mdl")
if !IsValid(self) then return end
timer.Create( "timer1", growtime, 1, function()
if !IsValid(self) then return end
self:SetModel("models/pot/pot_07.mdl")
timer.Create( "timer2", growtime, 1, function()
if !IsValid(self) then return end
self:SetModel("models/pot/pot_08.mdl")
timer.Create( "timer3", growtime, 1, function()
if !IsValid(self) then return end
self:SetModel("models/pot/pot_09.mdl")
timer.Create( "timer4", growtime, 1, function()
if !IsValid(self) then return end
self:SetModel("models/pot/pot_10.mdl")
self.isUsable = true
end)
end)
end)
end)
end)[/CODE]
It is saying that "self" is the error. Does someone mind explaining how this works? I am not looking for an answer (if you can that is great) but I want to understand how this works and what to do instead of the "self"?
Thanks guys
With [img]http://wiki.garrysmod.com/favicon.ico[/img] [url=http://wiki.garrysmod.com/page/net/Receive]net.Receive[/url] you take the parameters:
[code]
(number) length - Length of the message, in bits
(Player) ply - The player that sent the message, works only serverside
For example:
net.Receive( "my_message", function( len, pl )
print( ply:Nick() .. " sent me a net message" )
end
[/code]
Self refers to the object itself, like when you're inside the function you wrote:
[code]
function ENT:Use(activator)
poppygrow(self)
end
[/code]
This self just refers to the 'ENT' part. Since you're inside the code of the entity. When you send a net message, you're not inside the entity so it doesn't know what you're referring to.
Remember that anyone can just craft and send a net message to the server, so make sure you do some sort of server-side check such as distance of the plant to the player to make sure they're not upgrading plants from across the map, I'm not sure what you're trying to fully create so it's hard to give specifics.
EDIT: Thinking about it actually that code that I snipped was an excessive way to do it, let me quickly test something and get back to you
[QUOTE=Adzter;48444677]With [img]http://wiki.garrysmod.com/favicon.ico[/img] [url=http://wiki.garrysmod.com/page/net/Receive]net.Receive[/url] you take the parameters:
-snip-
[/QUOTE]
Thank you for that, it really helped! :smile:
So what if I already have the entity name (which is "poppy_plant"). And I take it because I sent a message I cannot "get inside the entity" to do the self?
You said about needing more code but I would like to see if I can solve it (I just need directions).
What are some other "alternatives"? Could I use a conCommand to start the function?
Ignore that part that I snipped, I wasn't thinking properly, if you throw your
[code]
net.Receive( "start_pop_grow", function ( len, ply )
growtime = 2
-- Timers
self:SetModel("models/pot/pot_06.mdl")
if !IsValid(self) then return end
timer.Create( "timer1", growtime, 1, function()
if !IsValid(self) then return end
self:SetModel("models/pot/pot_07.mdl")
timer.Create( "timer2", growtime, 1, function()
if !IsValid(self) then return end
self:SetModel("models/pot/pot_08.mdl")
timer.Create( "timer3", growtime, 1, function()
if !IsValid(self) then return end
self:SetModel("models/pot/pot_09.mdl")
timer.Create( "timer4", growtime, 1, function()
if !IsValid(self) then return end
self:SetModel("models/pot/pot_10.mdl")
self.isUsable = true
end)
end)
end)
end)
end)
[/code]
inside of your ENT:Initialize() then your net message is running 'inside' of the entity, you still need the correct parameters if you want to use them however.
But I wouldn't use this way of doing things, that above is just to explain the 'self'. If you use the above code it should work, but only for the last plant spawned. Since every time you spawn one it'll override the net receive from the previous one. The way I'd do it depends on what you're actually creating, I'm assuming you want it so that the player can press E on the plant and it'll grow? I'm having trouble understanding the derma part, pressing E on the plant opens a menu which the player can press a button to grow the plant?
If that's the case I'd have the client send to the server the entity that needs to be changed using net.WriteEntity. Then verify on the server that the player is actually near to the plant to stop people growing plants from across the map, perhaps even a check to see if they own it (not sure on specifics). Then you'd run your timer code but using the entity sent to the server (net.ReadEntity()) instead of 'self'.
Sorry, you need to Log In to post a reply to this thread.