Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- if SERVER then
- AddCSLuaFile( "shared.lua" )
- end
- SWEP.HoldType = "knife"
- if CLIENT then
- SWEP.PrintName = "knife_name"
- SWEP.Slot = 6
- SWEP.ViewModelFlip = false
- SWEP.EquipMenuData = {
- type = "item_weapon",
- desc = "knife_desc"
- };
- SWEP.Icon = "VGUI/ttt/icon_knife"
- end
- SWEP.Base = "weapon_tttbase"
- SWEP.ViewModel = "models/weapons/v_knife_t.mdl"
- SWEP.WorldModel = "models/weapons/w_knife_t.mdl"
- SWEP.DrawCrosshair = false
- SWEP.Primary.Damage = 50
- SWEP.Primary.ClipSize = -1
- SWEP.Primary.DefaultClip = -1
- SWEP.Primary.Automatic = true
- SWEP.Primary.Delay = 1.1
- SWEP.Primary.Ammo = "none"
- SWEP.Secondary.ClipSize = -1
- SWEP.Secondary.DefaultClip = -1
- SWEP.Secondary.Automatic = true
- SWEP.Secondary.Ammo = "none"
- SWEP.Secondary.Delay = .5
- SWEP.Kind = WEAPON_EQUIP
- SWEP.CanBuy = {ROLE_TRAITOR} -- only traitors can buy
- SWEP.LimitedStock = true -- only buyable once
- SWEP.WeaponID = AMMO_KNIFE
- SWEP.IsSilent = true
- -- Pull out faster than standard guns
- SWEP.DeploySpeed = 2
- function SWEP:PrimaryAttack()
- self.Weapon:SetNextPrimaryFire( CurTime() + self.Primary.Delay )
- self.Weapon:SetNextSecondaryFire( CurTime() + self.Secondary.Delay )
- self.Owner:LagCompensation(true)
- local spos = self.Owner:GetShootPos()
- local sdest = spos + (self.Owner:GetAimVector() * 70)
- local kmins = Vector(1,1,1) * -10
- local kmaxs = Vector(1,1,1) * 10
- local tr = util.TraceHull({start=spos, endpos=sdest, filter=self.Owner, mask=MASK_SHOT_HULL, mins=kmins, maxs=kmaxs})
- -- Hull might hit environment stuff that line does not hit
- if not IsValid(tr.Entity) then
- tr = util.TraceLine({start=spos, endpos=sdest, filter=self.Owner, mask=MASK_SHOT_HULL})
- end
- local hitEnt = tr.Entity
- -- effects
- if IsValid(hitEnt) then
- self.Weapon:SendWeaponAnim( ACT_VM_HITCENTER )
- local edata = EffectData()
- edata:SetStart(spos)
- edata:SetOrigin(tr.HitPos)
- edata:SetNormal(tr.Normal)
- edata:SetEntity(hitEnt)
- if hitEnt:IsPlayer() or hitEnt:GetClass() == "prop_ragdoll" then
- util.Effect("BloodImpact", edata)
- end
- else
- self.Weapon:SendWeaponAnim( ACT_VM_MISSCENTER )
- end
- if SERVER then
- self.Owner:SetAnimation( PLAYER_ATTACK1 )
- end
- if SERVER and tr.Hit and tr.HitNonWorld and IsValid(hitEnt) then
- if hitEnt:IsPlayer() then
- -- knife damage is never karma'd, so don't need to take that into
- -- account we do want to avoid rounding error strangeness caused by
- -- other damage scaling, causing a death when we don't expect one, so
- -- when the target's health is close to kill-point we just kill
- if hitEnt:Health() < (self.Primary.Damage + 10) then
- self:StabKill(tr, spos, sdest)
- else
- local dmg = DamageInfo()
- dmg:SetDamage(self.Primary.Damage)
- dmg:SetAttacker(self.Owner)
- dmg:SetInflictor(self.Weapon or self)
- dmg:SetDamageForce(self.Owner:GetAimVector() * 5)
- dmg:SetDamagePosition(self.Owner:GetPos())
- dmg:SetDamageType(DMG_SLASH)
- hitEnt:DispatchTraceAttack(dmg, spos + (self.Owner:GetAimVector() * 3), sdest)
- end
- end
- end
- self.Owner:LagCompensation(false)
- end
- function SWEP:StabKill(tr, spos, sdest)
- local target = tr.Entity
- local dmg = DamageInfo()
- dmg:SetDamage(2000)
- dmg:SetAttacker(self.Owner)
- dmg:SetInflictor(self.Weapon or self)
- dmg:SetDamageForce(self.Owner:GetAimVector())
- dmg:SetDamagePosition(self.Owner:GetPos())
- dmg:SetDamageType(DMG_SLASH)
- -- now that we use a hull trace, our hitpos is guaranteed to be
- -- terrible, so try to make something of it with a separate trace and
- -- hope our effect_fn trace has more luck
- -- first a straight up line trace to see if we aimed nicely
- local retr = util.TraceLine({start=spos, endpos=sdest, filter=self.Owner, mask=MASK_SHOT_HULL})
- -- if that fails, just trace to worldcenter so we have SOMETHING
- if retr.Entity != target then
- local center = target:LocalToWorld(target:OBBCenter())
- retr = util.TraceLine({start=spos, endpos=center, filter=self.Owner, mask=MASK_SHOT_HULL})
- end
- -- create knife effect creation fn
- local bone = retr.PhysicsBone
- local pos = retr.HitPos
- local norm = tr.Normal
- local ang = Angle(-28,0,0) + norm:Angle()
- ang:RotateAroundAxis(ang:Right(), -90)
- pos = pos - (ang:Forward() * 7)
- local prints = self.fingerprints
- local ignore = self.Owner
- target.effect_fn = function(rag)
- -- we might find a better location
- local rtr = util.TraceLine({start=pos, endpos=pos + norm * 40, filter=ignore, mask=MASK_SHOT_HULL})
- if IsValid(rtr.Entity) and rtr.Entity == rag then
- bone = rtr.PhysicsBone
- pos = rtr.HitPos
- ang = Angle(-28,0,0) + rtr.Normal:Angle()
- ang:RotateAroundAxis(ang:Right(), -90)
- pos = pos - (ang:Forward() * 10)
- end
- local knife = ents.Create("prop_physics")
- knife:SetModel("models/weapons/w_knife_t.mdl")
- knife:SetPos(pos)
- knife:SetCollisionGroup(COLLISION_GROUP_DEBRIS)
- knife:SetAngles(ang)
- knife.CanPickup = false
- knife:Spawn()
- local phys = knife:GetPhysicsObject()
- if IsValid(phys) then
- phys:EnableCollisions(false)
- end
- constraint.Weld(rag, knife, bone, 0, 0, true)
- -- need to close over knife in order to keep a valid ref to it
- rag:CallOnRemove("ttt_knife_cleanup", function() SafeRemoveEntity(knife) end)
- end
- -- seems the spos and sdest are purely for effects/forces?
- target:DispatchTraceAttack(dmg, spos + (self.Owner:GetAimVector() * 3), sdest)
- -- target appears to die right there, so we could theoretically get to
- -- the ragdoll in here...
- self:Remove()
- end
- function SWEP:SecondaryAttack()
- self.Weapon:SetNextPrimaryFire( CurTime() + self.Primary.Delay )
- self.Weapon:SetNextSecondaryFire( CurTime() + self.Secondary.Delay )
- self.Weapon:SendWeaponAnim( ACT_VM_MISSCENTER )
- if SERVER then
- self.Owner:SetAnimation( PLAYER_ATTACK1 )
- local ply = self.Owner
- if not IsValid(ply) then return end
- local ang = ply:EyeAngles()
- if ang.p < 90 then
- ang.p = -10 + ang.p * ((90 + 10) / 90)
- else
- ang.p = 360 - ang.p
- ang.p = -10 + ang.p * -((90 + 10) / 90)
- end
- local vel = math.Clamp((90 - ang.p) * 5.5, 550, 800)
- local vfw = ang:Forward()
- local vrt = ang:Right()
- local src = ply:GetPos() + (ply:Crouching() and ply:GetViewOffsetDucked() or ply:GetViewOffset())
- src = src + (vfw * 1) + (vrt * 3)
- local thr = vfw * vel + ply:GetVelocity()
- local knife_ang = Angle(-28,0,0) + ang
- knife_ang:RotateAroundAxis(knife_ang:Right(), -90)
- local knife = ents.Create("ttt_knife_proj")
- if not IsValid(knife) then return end
- knife:SetPos(src)
- knife:SetAngles(knife_ang)
- knife:Spawn()
- knife.Damage = self.Primary.Damage
- knife:SetOwner(ply)
- local phys = knife:GetPhysicsObject()
- if IsValid(phys) then
- phys:SetVelocity(thr)
- phys:AddAngleVelocity(Vector(0, 1500, 0))
- phys:Wake()
- end
- self:Remove()
- end
- end
- function SWEP:Equip()
- self.Weapon:SetNextPrimaryFire( CurTime() + (self.Primary.Delay * 1.5) )
- self.Weapon:SetNextSecondaryFire( CurTime() + (self.Secondary.Delay * 1) )
- end
- function SWEP:PreDrop()
- -- for consistency, dropped knife should not have DNA/prints
- self.fingerprints = {}
- end
- function SWEP:OnRemove()
- if CLIENT and IsValid(self.Owner) and self.Owner == LocalPlayer() and self.Owner:Alive() then
- RunConsoleCommand("lastinv")
- end
- end
- if CLIENT then
- function SWEP:DrawHUD()
- local tr = self.Owner:GetEyeTrace(MASK_SHOT)
- if tr.HitNonWorld and IsValid(tr.Entity) and tr.Entity:IsPlayer()
- and tr.Entity:Health() < (self.Primary.Damage + 10) then
- local x = ScrW() / 2.0
- local y = ScrH() / 2.0
- surface.SetDrawColor(255, 0, 0, 255)
- local outer = 20
- local inner = 10
- surface.DrawLine(x - outer, y - outer, x - inner, y - inner)
- surface.DrawLine(x + outer, y + outer, x + inner, y + inner)
- surface.DrawLine(x - outer, y + outer, x - inner, y + inner)
- surface.DrawLine(x + outer, y - outer, x + inner, y - inner)
- draw.SimpleText("INSTANT KILL", "TabLarge", x, y - 30, COLOR_RED, TEXT_ALIGN_CENTER, TEXT_ALIGN_BOTTOM)
- end
- return self.BaseClass.DrawHUD(self)
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement