Dropping weapons - Need help

Hi, I’m trying to make a gamemode at the moment and I’m trying to make it so that when the user presses Q, they drop their weapon. I’ve tried copying an example from a video but my problem is that the server receives the player’s name (needed to set the pos) as ‘0’ and the weapon’s name as the player’s name. I’ve spent quite a while googling and looking though my code and trying various things but to no avail. If anybody can help me I will be very happy.

Also, the code gets executed numerous times (I think this might be because of the actual IsKeyDown() function being called rapidly). Is there a better function to put here?

check for Q press (client side):



local function keyQ()
	if input.IsKeyDown(KEY_Q) then
		net.Start("KEY_Q")
		net.SendToServer()
		
		hook.Call("KEY_Q", GAMEMODE)
	end
end

hook.Add("Think", "q_pressed", keyQ)


Client-side weapon-dropping code:



function weaponDrop() 
    
    local ply = LocalPlayer()
    
    if !IsValid(ply:GetActiveWeapon()) then return end
    local wep = tostring(ply:GetActiveWeapon():GetClass())

    RunConsoleCommand("ent_remove", wep)
    
    net.Start("SpawnWeapon")
    net.SendToServer()
    hook.Call("SpawnWeapon", ply, wep)
end

hook.Add("KEY_Q", "weaponDrop", weaponDrop)


Entity creation (server side) - here’s where the crash is:



function weaponSpawn(ply, wep)  --wep is userdata type and = player's name, ply is 0
    local ent = ents.Create(tostring(wep))
    local pos = ply:GetPos()
    ent:SetPos(pos + Vector(10,0,20))
end


Network receiving code (obviously server-side):



net.Receive("KEY_Q", function(len, ply)
	hook.Call("KEY_Q", GAMEMODE, ply)
end)

net.Receive("SpawnWeapon", function(ply, wep)
    weaponSpawn(ply, wep)
end)


I’m new to lua and this is the first networking code I’ve ever come across in my life. I know it’s a little out of my reach but I’m eager to learn and any help will be greatly appreciated! I know my code is a horrible mess, mainly because I was just trying everything, so sorry about that.

Bump

-snip dumb-

Hook it to - open spawnmenu or context menu, or you could make it a chat command, thats what i did and my version works 100% :stuck_out_tongue:

If you hook it to spawnmenu or context menu, be sure dissable those menus

Hang on, what has this got to do with dropping weapons?

Binding a key to a command/chat command ? Xd

Edit: man, your code is way more complicater then it should be.
I can’t curr come on the pc, but tonight if i don’t forget, ill provide you with a better answer

In client.
[lua]
net.Start(“KEY_Q”)
net.SendToServer()
[/lua]

In server.
[lua]
net.Receive(“KEY_Q”, function(len, ply)
print(ply:GetActiveWeapon():GetClass())
print(ply:GetPos())
end)
[/lua]

Dont forget to precache the network string: util.AddNetworkString(“KEY_Q”)
in the start of your file (server) or it wont work and you’ll get errors.

The server already know what kind of weapon you’re currently holding and what your position is so there’s no need to send it over with networking, if you want the client to tell the server that you’ve dropped your current weapon, all you need to do is send a single network message and have the player drop it.

PS. You could delay your think hook each time its used so that it wont be triggered like 10 times with each Q press.

Thanks! I’m playing around with a slightly different method at the moment, based off of the way TTT does it (turns out ply:DropWeapon() exists, so no point remaking it). If that fails though, I’ll come back to this.

I wish you good luck! Also I made a quick example of how you /could/ do it if you’re interested.

[lua]
if(SERVER) then
AddCSLuaFile()

util.AddNetworkString("KEY_Q")

local nodrops = {
	"weapon_physgun",
	"gmod_tool",
	"gmod_camera"
}
function DropWeapon(ply)
	local wep = ply:GetActiveWeapon()
	if(!wep:IsValid() or table.HasValue(nodrops, wep:GetClass())) then return end
	ply:StripWeapon(wep:GetClass())

	local ent = ents.Create(wep:GetClass())
	ent:SetPos(ply:GetShootPos() + (ply:GetAimVector()*124))
	ent:Spawn()
end
net.Receive("KEY_Q", function(len, ply) DropWeapon(ply) end)

end

if(CLIENT) then
local dropdelay = 0
hook.Add(“Think”, “Drop weapon”, function()
– 27 = Q.
if(input.IsKeyDown(27) and dropdelay <= CurTime()) then
dropdelay = CurTime() + 2
print(dropdelay)
net.Start(“KEY_Q”)
net.SendToServer()
end
end)
end
[/lua]

Basically lets you drop your current weapon 124 units infront of you every 2nd second. Wont let you drop weapons such as gmod_tool or weapon_physgun etc. It’s not flawless (you’ll be able to drop guns through walls cause I’m not using traces here) but it should give you a simple idea of how it can be done. Once again, good luck.

Edit.
FYI, the standard ply:DropWeapon() function in gmod can be a bit buggy from my experience. Some weapons like the crowbar (iirc) disappears completely when dropped.

In the end this is all I needed (will share how easy it actually is for those in need of this in the future)

Client-side:



local function SendWeaponDrop()
    RunConsoleCommand("ex_dropweapon")
end

function GM:OnSpawnMenuOpen()
    SendWeaponDrop()
end


Server-side:



include("weaponry_shd.lua")

function WEPS.DropNotifiedWeapon(ply, wep) 
    ply:DropWeapon(wep)
    wep:PhysWake()
    
    ply:SelectWeapon("m9k_fists")
end

local function DropActiveWeapon(ply)
   if not IsValid(ply) then return end

   local wep = ply:GetActiveWeapon()

   if not IsValid(wep) then return end

   if wep.AllowDrop == false then
      return
   end

   local tr = util.QuickTrace(ply:GetShootPos(), ply:GetAimVector() * 32, ply)

   if tr.HitWorld then
      ply:PrintMessage(HUD_PRINTTALK, "You can't drop that there.")
      return
   end

   WEPS.DropNotifiedWeapon(ply, wep)
end
concommand.Add("ex_dropweapon", DropActiveWeapon)


Shared:



WEPS = {}