Problem with clients in multiplayer [Gamemode]

So I’ve been trying to change and make the code apply to each player separately, but I cant find a way to do it.
Here is the code, It’s located in “init.lua”.



AddCSLuaFile("cl_init.lua")
AddCSLuaFile("shared.lua")
include("shared.lua")
resource.AddFile("sound/allahu2.wav")

local ply=FindMetaTable("Player")
local expt=0


function GM:KeyPress(ply,key)
	if key==IN_USE and ply:Alive() then
		if expt==0 then
		expt=1
		local exp=ents.Create("env_explosion")
		exp:Spawn()
		exp:SetKeyValue("iMagnitude",200)
		sound.Play("allahu2.wav",ply:GetPos(),70,100,1)
		timer.Simple(1,function()
		if ply:Alive() then
		exp:SetPos(ply:GetPos())
		exp:Fire("Explode",0,0)
		expt=0
		else
		expt=0
		end
		end)
	else 
		sound.Play("weapons/slam/buttonclick.wav",Vector(ply:GetPos()))                      -- Sends players to this part of the code If someone is already using the function.
	end
	end
end


So here is the problem, If one player presses the use button (Default E) and starts the function on himself, then others would not be able to enable the function and execute it on themselves. What It would do is just send them to this part of the code,



...
..
.
else 
		sound.Play("weapons/slam/buttonclick.wav",Vector(ply:GetPos()))
	end
.
..
...


I don’t know what I’m doing wrong, maybe I need to setup a database for each player or something?

Thanks.

Firstly, the KeyPress hook already calls for every player. That’s what the first parameter “ply” is for. You don’t need to define the meta function ply in this case because it’s already a parameter of the hook.

Secondly where are you putting this code that you’re overwriting the entire KeyPress function? You should be using hook.Add in this case.

Finally remove that else statement and just play the sound from the timer or the function itself.

Actually come to think of it, why are you running a timer a second after the explosion? I presume it’s to kill the player if they survive but the explosion will happen regardless of whether they’re alive or not since it’s defined by the player’s position. You easily just kill the player right after you spawn the explosion and it’d yield the same.

You don’t need a database for this that’s for sure

You don’t need the metatable for Player in this context, that’s mostly used to add functions onto it, like so:



local PLAYER = FindMetaTable( "Player" )

function PLAYER:DoSomething()

end


Also, you should work on indenting the code consistently, it’s difficult to keep track of blocks otherwise

**ninja’d

edit:

**Also, check if the player is valid when the timer callbacks.
P.S. If expt is going to be set to 0, regardless of the player being alive or not, place it outside of the if statement inside the timer callback.

As of right now your code looks like it’ll play a clicking nose every time a player presses a key where they’re either alive or it’s not the USE key.

Also jesus looking at this, why are you using Vector( ply:GetPos() ), that already returns a vector. That’s like saying tonumber( 42 )

[editline]20th March 2016[/editline]

No ninjas you actually caught something I didn’t. I didn’t realize he was running a variable outside the function locally.

Do like Mc said originally before the snip: Set the variable using ply.VARIABLENAME ( Where it will become an index of the player )

I read afterwise, he doesn’t want multiple players to use it:


-- Sends players to this part of the code If someone is already using the function.

Just seems like his logic is wrong

ALSO couldn’t help but notice the file structure. Is this for a swep or an entity? Because if so, you actually shouldn’t be using keypress at all. You should use the swep’s THINK function or the entity’s USE function

Alright, I just want to clarify what’s the problem I’m having and answers some questions,
Firstly, This is a part of a gamemode, I wrote that in the title. Second of all, I didn’t copy and paste the whole code because It would be just useless information to go through. What I pasted in here is what is relevant to the problem I’m having. The problem itself is, whenever a player calls for the function, it works for him but If another player tried to call for the function, it doesn’t work, it just sends him to this line,



else 
	sound.Play("weapons/slam/buttonclick.wav",Vector(ply:GetPos()))
end
 

What the function does is, It waits till a player presses the Use key (Default E) then It would check if the player pressed the Use key and If the player is alive, then it would create the explosion, spawn it, set its key values, play a sound that lasts around 1 second and then do the explosion. The part with the “expt” value is just to make sure the player wont spam the key and create multiple explosions.

Hopefully I answered some questions, and sorry If I wasn’t clear enough with my problem.

Set expt to ply.expt then

Okay, if that’s the case, then what I said previously applies, your comment in the code is just misleading then.

Instead of using a local variable outside of GM KeyPress, which would apply to all players do:

if Key and Player Alive
if not Player.expt
Player.expt = 1

Also, change Vector( ply:GetPos() ) to ply:GetPos()

Player:GetPos() already returns a vector, solid_jake explained that previously

Alright, thank you it worked.