How do I make a SWEP that kills the target in my crosshair?
17 replies, posted
I want to make a SWEP or STool that kills (sets health to 0) the targeted NPC/player/prop/vehicle.
How do I go about this?
I looked in the wiki but I must say I'm stumped, as I find it incomplete.
Thanks in advance for the help provided.
First determine how you want to cause this effect: is it a Swep, a key bind, a console command, an effect which is triggered every tick?
Then you need to make the kill ray by using the following:
So you use traceline to find what you're looking at
Then check if its a valid entity (because the next step will cause a crash if there is no target)
Then check if its a player
Then you need to determine how to kill the target
Hopefully those resources will help you out, if you really have no idea post what you got so far and I will (or someone else might) try to help you fix it up
This is as far as I got by modifying the Chair Throwing Weapon tutorial
https://pastebin.com/SWNFAypD
My guess for killing the player would be the Player:Kill() function but that's as far as I got to.
Okey doke well consider it's like cause and effect.
When you click your mouse button the game engine runs the SWEP:PrimaryAttack() function.
So you want to put your code inside this function, so the code is executed when you left click.
function SWEP:PrimaryAttack()
end
(I've just looked and found an easier trace to use)
So we need to add in the code to draw a line to where the player is looking. For this we will use a trace, you can make a custom trace between 2 points using the page above or you can use this simpler trace code.
local eyetrace = self.Owner:GetEyeTrace()
Note: self is a local variable which in this case references the SWEP. I'll explain a little what local means at the end.
so we wanna do something (kill) the entity the trace is hitting, but first we need to check if the entity is a a player or even if its an entity. (if the trace doesnt hit anything then there will be no entity so the lua will throw an error if you try to run functions on it)
local traceTarget = eyetrace.Entity
We will store the traceTarget so its easier to use
IsValid( traceTarget ) -- returns bool
traceTarget:IsPlayer( ) -- returns bool
Put those 2 together to get an if statement
if ( IsValid( traceTarget ) and traceTarget:IsPlayer( ) ) then
...
end
so if the entity is valid (ie exists) and is a player we do something to it
Finally we need some code to kill the player.
traceTarget:Kill()
So put it all together to get
------------------- Code starts here (code formatting is junk)
function SWEP:PrimaryAttack() -- This function is run when the player left clicks
local eyetrace = self.Owner:GetEyeTrace() -- Draw a line from the user's eyes to where they're pointing the gun
local traceTarget = eyetrace.Entity -- This is the entity the kill ray is hitting
if ( IsValid( traceTarget ) and traceTarget:IsPlayer( ) ) then -- check if the entity exists and if theyre a player
traceTarget:Kill() -- kill the target
end
end
----------------- Code ends here
(holy shit newpunch code formatting is hard to use!)
I've used -- comments to add in some notes so its easier to read.
find the PrimaryAttack on your existing swep and overwrite it with this code. Future stuff might include a sound or a delay to fire it.
Note on scope:
I mentioned local variable before. When you code variables have scope, this is where they're available. So If I have some code with 2 functions in it
-------------------------------------- Start example code
local variable1 = "hi"
function DoStuff1()
local variable2 = "hiya"
end
function DoStuff2()
local variable3 = "yo"
end
-------------------------------------- Finish example code
So if you try to access variable1 in either function it will have value "hi". But if you try to access variable2 inside DoStuff2 it will be null - because it's not in the scope. If you declare a local variable inside a function it is only available inside that function - not inside others.
This might be important if you want to add a cooldown to your gun
Another note on networking:
In the future, once you got the basics, you'll encounter networking and prediction. The basis of this is that because your pc (and your players pcs) are different from the server each machine must run a separate copy of the game. Then to avoid lag each machine must know what its gonna do when you fire a gun - so theyll shoot but then the server tells them if they succeeded. Generally you're ok putting everything inside shared.lua, so the same code is run on the server and a client so they're both doing the same thing. But some stuff is serverside only (like kill, you should only kill people on the server because the game doesn't really let the client decide that, thats like me joining your server and telling you who ive just killed. So you use something like
if ( !SERVER ) then return end
to prevent the client from running kill ie
-------------------- Amended code for swep primary fire
function SWEP:PrimaryAttack() -- This function is run when the player left clicks
local eyetrace = self.Owner:GetEyeTrace() -- Draw a line from the user's eyes to where they're pointing the gun
local traceTarget = eyetrace.Entity -- This is the entity the kill ray is hitting
if ( IsValid( traceTarget ) and traceTarget:IsPlayer( ) ) then -- check if the entity exists and if theyre a player
if ( !SERVER ) then return end -- If the code is being run on the client then don't bother doing this stuff since the client (ie players computer) isn't allowed to decide who is dead
traceTarget:Kill() -- kill the target
end
end
---- Fin
We put the "if ( !SERVER ) then return end " Inside the if since you might want to add sound/particle fx
A bit of a ramble, I hope it's not too much random junk. Give it a try and see how it goes, tell us how it went
Thanks so much for your help, Fulcrum. I'll upload it and test it immediately.
I have credited you in the SWEP's name and I will credit you in the workshop addon's workshop page as well.
Be right back.
You don't need to credit me, best thing you can do is learn to code, its super super useful. I failed my university degree but got lucky and landed a well paying web developer job because of the coding I had been doing in my free time. Good luck
Hello.
I did private workshop upload to test the addon, I'm afraid it's not working (have tried targeting NPCs, entities, etc and it wouldn't destroy them).
I think your guidance is once again required. :s
It only works on other players as per the code. You should also move the "if ( !SERVER ) then return end" check to the top of the function as to not do useless trace work. You can use Entity/TakeDamage with Entity/Health as the damage to kill an entity.
SWEP.PrintName = "InstaKill"
SWEP.Author = "Dracus, under the excellent guidance of Fulcrum from Facepunch Forums"
SWEP.Instructions = "Kills the targeted entity or player by left-clicking"
SWEP.Spawnable = true
SWEP.AdminOnly = true
SWEP.Primary.ClipSize = -1
SWEP.Primary.DefaultClip = -1
SWEP.Primary.Automatic = true
SWEP.Primary.Ammo = "none"
SWEP.Weight = 5
SWEP.AutoSwitchTo = false
SWEP.AutoSwitchFrom = false
SWEP.Slot = 1
SWEP.SlotPos = 2
SWEP.DrawAmmo = false
SWEP.DrawCrosshair = true
SWEP.ViewModel = "models/weapons/v_pistol.mdl"
SWEP.WorldModel = "models/weapons/w_pistol.mdl"
function SWEP:PrimaryAttack() --This function is run when the player left clicks.
if ( !SERVER ) then return end --If the code is being run on the client then don't bother doing this stuff since the client (i.e. players computer) isn't allowed to decide who is dead.
local eyetrace = self.Owner:GetEyeTrace() --Draw a line from the user's eyes to where they're pointing the gun.
local traceTarget = eyetrace.Entity --This is the entity the kill ray is hitting.
if ( IsValid( traceTarget ) and traceTarget:IsPlayer( ) ) then --Check if the entity exists and if they're a player.
traceTarget:Kill() --Kill the target.
elseif ( IsValid ( traceTarget ) and traceTarget:IsEntity( ) ) then --Check if the entity exists and if it's an entity.
traceTarget:Entity:TakeDamage(traceTarget:Entity:Health(), Entity attacker, Entity inflictor)
end
end
This is were I got it to. I don't know how to set the shooting player as the attacker or inflictor, I'm afraid.
Thanks for the help.
"self:GetOwner()" for the attacker, "self" for the inflictor. IsEntity is not a function since traceTarget will already always be an entity. Here's some cleaner code so you can understand:
function SWEP:PrimaryAttack() --This function is run when the player left clicks.
if ( CLIENT ) then return end --If the code is being run on the client then don't bother doing this stuff since the client (i.e. players computer) isn't allowed to decide who is dead.
local owner = self:GetOwner()
local eyetrace = owner:GetEyeTrace() --Draw a line from the user's eyes to where they're pointing the gun.
local traceTarget = eyetrace.Entity --This is the entity the kill ray is hitting.
if ( traceTarget:IsValid() ) then --Check if the entity exists
if ( traceTarget:IsPlayer() ) then --Check if the enitty is a player
traceTarget:Kill() --Kill the target.
else
traceTarget:TakeDamage( traceTarget:Health(), owner, self )
end
end
end
Thanks much for the help. Does the function also work for vehicles and NPCs? Or will they be considered entities as well, due to how traceTarget works? I also used an IsNPC condition in the previous post, not sure if it's necessary.
Again, sorry, I am rather oblivious as to the mechanics used here.
Thanks again for your help.
This is the code as it is now:
SWEP.PrintName = "InstaKill"
SWEP.Author = "Dracus, under the excellent guidance of Fulcrum and code_gs from Facepunch Forums"
SWEP.Instructions = "Kills the targeted entity or player by left-clicking"
SWEP.Spawnable = true
SWEP.AdminOnly = true
SWEP.Primary.ClipSize = -1
SWEP.Primary.DefaultClip = -1
SWEP.Primary.Automatic = true
SWEP.Primary.Ammo = "none"
SWEP.Weight = 5
SWEP.AutoSwitchTo = false
SWEP.AutoSwitchFrom = false
SWEP.Slot = 1
SWEP.SlotPos = 2
SWEP.DrawAmmo = false
SWEP.DrawCrosshair = true
SWEP.ViewModel = "models/weapons/v_pistol.mdl"
SWEP.WorldModel = "models/weapons/w_pistol.mdl"
function SWEP:PrimaryAttack() --This function is run when the player left clicks.
if ( CLIENT ) then return end --If the code is being run on the client then don't bother doing this stuff since the client (i.e. players computer) isn't allowed to decide who is dead.
local owner = self:GetOwner()
local eyetrace = owner:GetEyeTrace() --Draw a line from the user's eyes to where they're pointing the gun.
local traceTarget = eyetrace.Entity --This is the entity the kill ray is hitting.
if ( traceTarget:IsValid() ) then --Check if the entity exists
if ( traceTarget:IsPlayer() ) then --Check if the enitty is a player
traceTarget:Kill() --Kill the target.
else
traceTarget:TakeDamage( traceTarget:Health(), owner, self ) --Destroy the entity.
end
end
end
It works for all entities, which include vehicles, NPCs, players, props, anything. Due to how TakeDamage works, however, it will not work on entities that don't take damage (specifically, have m_takedamage set to DAMAGE_NO internally).
It is not. The only checks you have to do are IsValid to make sure the eye trace hit an entity (the world does not count as a valid entity), and IsPlayer since players have their own "Kill" function.
Thanks. Just finished testing the addon on NPCs (worked) but it didn't work on any of the vehicles I have subscribed to, not even the default HL2 vehicles.
Must be what you said about entities that don't take damage.
Thanks for the help, man. Appreciate it a ton.
Yeah, vehicles themselves can't "die" - you can make players inside of them die, though, if that's what you're wanting.
I see.
And yet, vehicles can be destroyed by damage from weapons - could that be replicated somehow? Or would it be far too complex?
HL2 vehicles cannot be - if you are referring to vehicles provided by some addon, it depends on their API.
Thanks again for the help. I think I have a good start on GMod scripting now.
Peace.
Hey guys. I'm back with some more questions again.
So basically I've been trying to implement aimbot functionality to my SWEP, however I'm stuck with the console reporting that (apparently) ULib is conflicting with my code.
This is as far as I got to with some googling: https://pastebin.com/6SG80870
Console was repeatedly reporting that Line 54 was attempting to call a nil value.
Thanks in advance for your help.
Sorry, you need to Log In to post a reply to this thread.