330 lines
9.3 KiB
Lua
330 lines
9.3 KiB
Lua
|
|
--[[
|
|
Stungun SWEP Created by Donkie (http://steamcommunity.com/id/Donkie/)
|
|
For personal/server usage only, do not resell or distribute!
|
|
]]
|
|
|
|
STUNGUN = {} -- General stungun stuff table
|
|
|
|
STUNGUN.IsDarkRP = ((type(DarkRP) == "table") or (RPExtraTeams != nil))
|
|
STUNGUN.IsTTT = ((ROLE_TRAITOR != nil) and (ROLE_INNOCENT != nil) and (ROLE_DETECTIVE != nil) and (GetRoundState != nil)) -- For a gamemode to be TTT, these should probably exist.
|
|
|
|
include("config/stungun.lua")
|
|
|
|
-- if STUNGUN.IsTTT then
|
|
-- SWEP.Base = "weapon_octo_base_zoom"
|
|
-- SWEP.AmmoEnt = ""
|
|
-- SWEP.IsSilent = false
|
|
-- SWEP.NoSights = true
|
|
-- end
|
|
|
|
SWEP.Base = "weapon_octo_base_pistol"
|
|
SWEP.PrintName = L.stungun
|
|
SWEP.Author = "Donkie"
|
|
SWEP.Instructions = string.format("Left click to stun a person.%s", STUNGUN.CanUntaze and "\nRight click to unstun a person." or "")
|
|
SWEP.Contact = ""
|
|
SWEP.Purpose = ""
|
|
|
|
SWEP.ViewModelFOV = 50
|
|
SWEP.ViewModelFlip = false
|
|
SWEP.ViewModel = Model("models/weapons/c_pistol.mdl")
|
|
SWEP.WorldModel = Model("models/weapons/cg_ocrp2/w_taser.mdl")
|
|
|
|
SWEP.UseHands = true
|
|
|
|
SWEP.Spawnable = true
|
|
SWEP.AdminOnly = true
|
|
|
|
SWEP.MuzzlePos = Vector(10, 0.65, 3.5)
|
|
SWEP.MuzzleAng = Angle(-4, 2, 0)
|
|
|
|
-- SWEP.InfiniteAmmo = (SWEP.Ammo <= -1) -- Not used anymore
|
|
if SWEP.InfiniteAmmo then
|
|
SWEP.Primary.ClipSize = -1
|
|
SWEP.Primary.DefaultClip = 0
|
|
SWEP.Primary.Ammo = "none"
|
|
else
|
|
SWEP.Primary.ClipSize = 1
|
|
SWEP.Primary.DefaultClip = 1
|
|
|
|
if STUNGUN.IsTTT then
|
|
SWEP.Primary.ClipMax = SWEP.Ammo
|
|
end
|
|
|
|
SWEP.Primary.Ammo = "ammo_stungun"
|
|
end
|
|
SWEP.Primary.Automatic = false
|
|
|
|
SWEP.Secondary.ClipSize = -1
|
|
SWEP.Secondary.DefaultClip = -1
|
|
SWEP.Secondary.Automatic = false
|
|
SWEP.Secondary.Ammo = "none"
|
|
|
|
-- print(SERVER and "SERVER INIT" or "CLIENT INIT")
|
|
|
|
SWEP.Uncharging = false
|
|
|
|
game.AddAmmoType({
|
|
name = "ammo_stungun",
|
|
dmgtype = DMG_GENERIC,
|
|
tracer = TRACER_NONE,
|
|
plydmg = 0,
|
|
npcdmg = 0,
|
|
force = 0,
|
|
minsplash = 0,
|
|
maxsplash = 0
|
|
})
|
|
|
|
function SWEP:DoEffect(tr)
|
|
-- Animations
|
|
self:SendWeaponAnim( ACT_VM_PRIMARYATTACK )
|
|
self.Owner:SetAnimation(PLAYER_ATTACK1)
|
|
|
|
-- Electric bolt, taken from toolgun
|
|
local effectdata = EffectData()
|
|
effectdata:SetOrigin( tr.HitPos )
|
|
effectdata:SetStart( self.Owner:GetShootPos() )
|
|
effectdata:SetAttachment( 1 )
|
|
effectdata:SetEntity( self )
|
|
util.Effect( "ToolTracer", effectdata )
|
|
end
|
|
|
|
function SWEP:PrimaryAttack()
|
|
|
|
local ct = CurTime()
|
|
if not IsFirstTimePredicted() or not self:CanFire() or
|
|
(self.nextFire or 0) > ct or self:GetNextPrimaryFire() > ct
|
|
then return end
|
|
|
|
if self.Charge < 100 then
|
|
if SERVER then
|
|
self.Owner:EmitSound('weapons/clipempty_pistol.wav', 60)
|
|
end
|
|
|
|
self.nextFire = ct + 1
|
|
self:SetNextPrimaryFire(self.nextFire)
|
|
return
|
|
end
|
|
|
|
if not self.InfiniteAmmo then
|
|
if self:Clip1() <= 0 then return end
|
|
self:TakePrimaryAmmo(1)
|
|
end
|
|
|
|
self.Uncharging = true
|
|
|
|
-- Shoot trace
|
|
self.Owner:LagCompensation(true)
|
|
local shootPos, shootDir = self:GetShootPosAndDir()
|
|
local trData = {
|
|
start = shootPos,
|
|
endpos = shootPos + shootDir * 32768,
|
|
filter = self.Owner,
|
|
}
|
|
local tr = util.TraceLine(trData)
|
|
local ent = tr.Entity
|
|
if IsValid(ent) and ent:GetClass() == 'gmod_sent_vehicle_fphysics_base' then
|
|
trData.filter = { ent, trData.filter }
|
|
trData.collisiongroup = COLLISION_GROUP_NONE
|
|
tr = util.TraceLine(trData)
|
|
end
|
|
self.Owner:LagCompensation(false)
|
|
|
|
self:DoEffect(tr)
|
|
|
|
if SERVER then
|
|
self.Owner:EmitSound("npc/turret_floor/shoot1.wav", 75, 100)
|
|
end
|
|
|
|
local ent = tr.Entity
|
|
|
|
if CLIENT then return end
|
|
|
|
self.Owner:ViewPunch(Angle(math.random(-12,-5) * self.Primary.Recoil / 50, math.random(-5,5) * self.Primary.Recoil / 50))
|
|
|
|
-- Don't proceed if we don't hit any player
|
|
if not IsValid(ent) or not ent:IsPlayer() then return end
|
|
if ent == self.Owner then return end
|
|
if IsValid(ent.tazeragdoll) then return end
|
|
if self.Owner:GetShootPos():Distance(tr.HitPos) > self.Range then return end
|
|
|
|
if not STUNGUN.IsPlayerImmune(ent) and (STUNGUN.AllowFriendlyFire or not STUNGUN.SameTeam(self.Owner, ent)) then
|
|
-- Damage
|
|
if (STUNGUN.StunDamage and STUNGUN.StunDamage > 0) and not ent.tazeimmune then
|
|
local dmginfo = DamageInfo()
|
|
dmginfo:SetDamage(STUNGUN.StunDamage)
|
|
dmginfo:SetAttacker(self.Owner)
|
|
dmginfo:SetInflictor(self)
|
|
dmginfo:SetDamageType(DMG_SHOCK)
|
|
dmginfo:SetDamagePosition(tr.HitPos)
|
|
dmginfo:SetDamageForce(self.Owner:GetAimVector() * 30)
|
|
ent:TakeDamageInfo(dmginfo)
|
|
end
|
|
|
|
--The player might have died while getting tazed
|
|
if ent:Alive() then
|
|
-- Electrolute the player
|
|
STUNGUN.Electrolute( ent, (ent:GetPos() - self.Owner:GetPos()):GetNormal() )
|
|
end
|
|
|
|
if STUNGUN.bLogs then
|
|
bLogs.Log({
|
|
module = "Stungun",
|
|
log = string.format("%s was tazed by %s.", bLogs.GetName(ent), bLogs.GetName(self.Owner)),
|
|
involved = {ent, self.Owner}
|
|
})
|
|
end
|
|
|
|
if STUNGUN.pLogs then
|
|
plogs.PlayerLog(ent, "Stungun", string.format("%s was tazed by %s.", ent:NameID(), self.Owner:NameID()), {
|
|
["Name"] = ent:Name(),
|
|
["SteamID"] = ent:SteamID(),
|
|
["Attacker Name"] = self.Owner:Name(),
|
|
["Attacker SteamID"] = self.Owner:SteamID(),
|
|
})
|
|
end
|
|
|
|
hook.Run('tazer.tazed', self.Owner, ent)
|
|
end
|
|
end
|
|
|
|
local chargeinc
|
|
function SWEP:Think()
|
|
self.BaseClass.Think(self)
|
|
-- In charge of charging the swep
|
|
-- Since we got the same in-sensitive code both client and serverside we don't need to network anything.
|
|
if SERVER or (CLIENT and IsFirstTimePredicted()) then
|
|
if not chargeinc then
|
|
-- Calculate how much we should increase charge every tick based on how long we want it to take.
|
|
chargeinc = ((100 / self.RechargeTime) * engine.TickInterval())
|
|
end
|
|
|
|
local inc = self.Uncharging and (-5) or chargeinc
|
|
|
|
if self:Clip1() <= 0 and not self.InfiniteAmmo then inc = math.min(inc, 0) end -- If we're out of clip, we shouldn't be allowed to recharge.
|
|
|
|
local oldCharge = self.Charge
|
|
self.Charge = math.min(self.Charge + inc, 100)
|
|
if oldCharge ~= 100 and self.Charge >= 100 then self.Owner:EmitSound('ambient/energy/spark' .. math.random(1,4) .. '.wav', 60, 100, 0.3) end
|
|
if self.Charge < 0 then self:Reload() self.Uncharging = false self.Charge = 0 end
|
|
end
|
|
end
|
|
|
|
function SWEP:FailAttack()
|
|
self:SetNextSecondaryFire(CurTime() + 0.5)
|
|
self.Owner:EmitSound( "Weapon_Pistol.Empty" )
|
|
end
|
|
|
|
-- function SWEP:SecondaryAttack()
|
|
-- if STUNGUN.CanUntaze then
|
|
-- if self:GetNextSecondaryFire() >= CurTime() then self:FailAttack() return end
|
|
|
|
-- -- Shoot trace
|
|
-- self.Owner:LagCompensation(true)
|
|
-- local tr = util.TraceLine(util.GetPlayerTrace( self.Owner ))
|
|
-- self.Owner:LagCompensation(false)
|
|
|
|
-- local ent = tr.Entity
|
|
|
|
-- if CLIENT then return end
|
|
|
|
-- -- Don't proceed if we don't hit any raggy
|
|
-- if not IsValid(ent) or ent:GetClass() != "prop_ragdoll" or not IsValid(ent.tazeplayer) then self:FailAttack() return end
|
|
-- if self.Owner:GetShootPos():Distance(tr.HitPos) > self.Range then self:FailAttack() return end
|
|
|
|
-- self:DoEffect(tr)
|
|
|
|
-- self.Owner:EmitSound("npc/turret_floor/shoot1.wav",100,100)
|
|
|
|
-- local ply = ent.tazeplayer
|
|
-- timer.Simple(.4, function() ply:EmitSound("items/smallmedkit1.wav",100,100) end)
|
|
|
|
-- STUNGUN.UnMute( ply )
|
|
-- STUNGUN.UnElectrolute( ply )
|
|
|
|
-- local id = ply:UserID()
|
|
-- timer.Remove("Unelectrolute" .. id)
|
|
-- timer.Remove("tazeUngag" .. id)
|
|
|
|
-- if STUNGUN.bLogs then
|
|
-- bLogs.Log({
|
|
-- module = "Stungun",
|
|
-- log = string.format("%s was un-tazed by %s.", bLogs.GetName(ply), bLogs.GetName(self.Owner)),
|
|
-- involved = {ply, self.Owner}
|
|
-- })
|
|
-- end
|
|
|
|
-- if STUNGUN.pLogs then
|
|
-- plogs.PlayerLog(ply, "Stungun", string.format("%s was un-tazed by %s.", ply:NameID(), self.Owner:NameID()), {
|
|
-- ["Name"] = ply:Name(),
|
|
-- ["SteamID"] = ply:SteamID(),
|
|
-- ["Attacker Name"] = self.Owner:Name(),
|
|
-- ["Attacker SteamID"] = self.Owner:SteamID(),
|
|
-- })
|
|
-- end
|
|
|
|
-- self:SetNextSecondaryFire(CurTime() + 2)
|
|
-- end
|
|
-- return false
|
|
-- end
|
|
|
|
function SWEP:Reload()
|
|
self:DefaultReload( ACT_VM_RELOAD )
|
|
return true
|
|
end
|
|
|
|
local shoulddisable = {} -- Disables muzzleflashes and ejections
|
|
shoulddisable[21] = true
|
|
shoulddisable[5003] = true
|
|
shoulddisable[6001] = true
|
|
function SWEP:FireAnimationEvent( pos, ang, event, options )
|
|
if shoulddisable[event] then return true end
|
|
end
|
|
|
|
hook.Add("PhysgunPickup", "Tazer", function(_,ent)
|
|
if not STUNGUN.AllowPhysgun and IsValid(ent:GetNWEntity("plyowner")) then return false end
|
|
end)
|
|
hook.Add("CanTool", "Tazer", function(_,tr,_)
|
|
if not STUNGUN.AllowToolgun and IsValid(tr.Entity) and IsValid(tr.Entity:GetNWEntity("plyowner")) then return false end
|
|
end)
|
|
|
|
hook.Add("StartCommand", "Tazer", function(ply, cmd)
|
|
if ply:GetNWBool("tazefrozen", false) == false then return end
|
|
|
|
cmd:ClearMovement()
|
|
cmd:RemoveKey(IN_ATTACK)
|
|
cmd:RemoveKey(IN_ATTACK2)
|
|
cmd:RemoveKey(IN_RELOAD)
|
|
cmd:RemoveKey(IN_USE)
|
|
cmd:RemoveKey(IN_DUCK)
|
|
end)
|
|
|
|
--[[
|
|
pLogs-2
|
|
]]
|
|
local function InitpLogs()
|
|
if not plogs or not plogs.Version then return end
|
|
local versionstr = plogs.Version
|
|
local versiontbl = string.Explode(".", versionstr)
|
|
if #versiontbl != 3 then return end
|
|
|
|
local major = tonumber(versiontbl[1])
|
|
local minor = tonumber(versiontbl[2])
|
|
local patch = tonumber(versiontbl[3])
|
|
|
|
if major < 2 or (major == 2 and minor < 7) then
|
|
MsgN("[STUNGUN] pLogs detected but its version is too old!")
|
|
return
|
|
end
|
|
|
|
plogs.Register("Stungun", true, Color(255,163,0))
|
|
STUNGUN.pLogs = true
|
|
|
|
MsgN("[STUNGUN] pLogs detected.")
|
|
end
|
|
|
|
if plogs then
|
|
InitpLogs()
|
|
else
|
|
hook.Add("Initialize","stungun_waitforplogs",InitpLogs)
|
|
end
|