Advertisement
Guest User

entities/weapons/weapon_ttt_knife.lua

a guest
Jan 25th, 2013
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.27 KB | None | 0 0
  1.  
  2. if SERVER then
  3.    AddCSLuaFile( "shared.lua" )
  4. end
  5.    
  6. SWEP.HoldType = "knife"
  7.  
  8. if CLIENT then
  9.  
  10.    SWEP.PrintName    = "knife_name"
  11.    SWEP.Slot         = 6
  12.  
  13.    SWEP.ViewModelFlip = false
  14.  
  15.    SWEP.EquipMenuData = {
  16.       type = "item_weapon",
  17.       desc = "knife_desc"
  18.    };
  19.  
  20.    SWEP.Icon = "VGUI/ttt/icon_knife"
  21. end
  22.  
  23. SWEP.Base               = "weapon_tttbase"
  24.  
  25. SWEP.ViewModel          = "models/weapons/v_knife_t.mdl"
  26. SWEP.WorldModel         = "models/weapons/w_knife_t.mdl"
  27.  
  28. SWEP.DrawCrosshair      = false
  29. SWEP.Primary.Damage         = 50
  30. SWEP.Primary.ClipSize       = -1
  31. SWEP.Primary.DefaultClip    = -1
  32. SWEP.Primary.Automatic      = true
  33. SWEP.Primary.Delay = 1.1
  34. SWEP.Primary.Ammo       = "none"
  35. SWEP.Secondary.ClipSize     = -1
  36. SWEP.Secondary.DefaultClip  = -1
  37. SWEP.Secondary.Automatic    = true
  38. SWEP.Secondary.Ammo     = "none"
  39. SWEP.Secondary.Delay = .5
  40.  
  41. SWEP.Kind = WEAPON_EQUIP
  42. SWEP.CanBuy = {ROLE_TRAITOR} -- only traitors can buy
  43. SWEP.LimitedStock = true -- only buyable once
  44. SWEP.WeaponID = AMMO_KNIFE
  45.  
  46. SWEP.IsSilent = true
  47.  
  48. -- Pull out faster than standard guns
  49. SWEP.DeploySpeed = 2
  50.  
  51. function SWEP:PrimaryAttack()
  52.    self.Weapon:SetNextPrimaryFire( CurTime() + self.Primary.Delay )
  53.    self.Weapon:SetNextSecondaryFire( CurTime() + self.Secondary.Delay )
  54.  
  55.    self.Owner:LagCompensation(true)
  56.  
  57.    local spos = self.Owner:GetShootPos()
  58.    local sdest = spos + (self.Owner:GetAimVector() * 70)
  59.  
  60.    local kmins = Vector(1,1,1) * -10
  61.    local kmaxs = Vector(1,1,1) * 10
  62.  
  63.    local tr = util.TraceHull({start=spos, endpos=sdest, filter=self.Owner, mask=MASK_SHOT_HULL, mins=kmins, maxs=kmaxs})
  64.  
  65.    -- Hull might hit environment stuff that line does not hit
  66.    if not IsValid(tr.Entity) then
  67.       tr = util.TraceLine({start=spos, endpos=sdest, filter=self.Owner, mask=MASK_SHOT_HULL})
  68.    end
  69.  
  70.    local hitEnt = tr.Entity
  71.  
  72.    -- effects
  73.    if IsValid(hitEnt) then
  74.       self.Weapon:SendWeaponAnim( ACT_VM_HITCENTER )
  75.  
  76.       local edata = EffectData()
  77.       edata:SetStart(spos)
  78.       edata:SetOrigin(tr.HitPos)
  79.       edata:SetNormal(tr.Normal)
  80.       edata:SetEntity(hitEnt)
  81.  
  82.       if hitEnt:IsPlayer() or hitEnt:GetClass() == "prop_ragdoll" then
  83.          util.Effect("BloodImpact", edata)
  84.       end
  85.    else
  86.       self.Weapon:SendWeaponAnim( ACT_VM_MISSCENTER )
  87.    end
  88.  
  89.    if SERVER then
  90.       self.Owner:SetAnimation( PLAYER_ATTACK1 )
  91.    end
  92.  
  93.  
  94.    if SERVER and tr.Hit and tr.HitNonWorld and IsValid(hitEnt) then
  95.       if hitEnt:IsPlayer() then
  96.          -- knife damage is never karma'd, so don't need to take that into
  97.          -- account we do want to avoid rounding error strangeness caused by
  98.          -- other damage scaling, causing a death when we don't expect one, so
  99.          -- when the target's health is close to kill-point we just kill
  100.          if hitEnt:Health() < (self.Primary.Damage + 10) then
  101.             self:StabKill(tr, spos, sdest)
  102.          else
  103.             local dmg = DamageInfo()
  104.             dmg:SetDamage(self.Primary.Damage)
  105.             dmg:SetAttacker(self.Owner)
  106.             dmg:SetInflictor(self.Weapon or self)
  107.             dmg:SetDamageForce(self.Owner:GetAimVector() * 5)
  108.             dmg:SetDamagePosition(self.Owner:GetPos())
  109.             dmg:SetDamageType(DMG_SLASH)
  110.  
  111.             hitEnt:DispatchTraceAttack(dmg, spos + (self.Owner:GetAimVector() * 3), sdest)
  112.          end
  113.       end
  114.    end
  115.  
  116.    self.Owner:LagCompensation(false)
  117. end
  118.  
  119. function SWEP:StabKill(tr, spos, sdest)
  120.    local target = tr.Entity
  121.  
  122.    local dmg = DamageInfo()
  123.    dmg:SetDamage(2000)
  124.    dmg:SetAttacker(self.Owner)
  125.    dmg:SetInflictor(self.Weapon or self)
  126.    dmg:SetDamageForce(self.Owner:GetAimVector())
  127.    dmg:SetDamagePosition(self.Owner:GetPos())
  128.    dmg:SetDamageType(DMG_SLASH)
  129.  
  130.    -- now that we use a hull trace, our hitpos is guaranteed to be
  131.    -- terrible, so try to make something of it with a separate trace and
  132.    -- hope our effect_fn trace has more luck
  133.  
  134.    -- first a straight up line trace to see if we aimed nicely
  135.    local retr = util.TraceLine({start=spos, endpos=sdest, filter=self.Owner, mask=MASK_SHOT_HULL})
  136.  
  137.    -- if that fails, just trace to worldcenter so we have SOMETHING
  138.    if retr.Entity != target then
  139.       local center = target:LocalToWorld(target:OBBCenter())
  140.       retr = util.TraceLine({start=spos, endpos=center, filter=self.Owner, mask=MASK_SHOT_HULL})
  141.    end
  142.  
  143.  
  144.    -- create knife effect creation fn
  145.    local bone = retr.PhysicsBone
  146.    local pos = retr.HitPos
  147.    local norm = tr.Normal
  148.    local ang = Angle(-28,0,0) + norm:Angle()
  149.    ang:RotateAroundAxis(ang:Right(), -90)
  150.    pos = pos - (ang:Forward() * 7)
  151.  
  152.    local prints = self.fingerprints
  153.    local ignore = self.Owner
  154.  
  155.    target.effect_fn = function(rag)
  156.                          -- we might find a better location
  157.                          local rtr = util.TraceLine({start=pos, endpos=pos + norm * 40, filter=ignore, mask=MASK_SHOT_HULL})
  158.  
  159.                          if IsValid(rtr.Entity) and rtr.Entity == rag then
  160.                             bone = rtr.PhysicsBone
  161.                             pos = rtr.HitPos
  162.                             ang = Angle(-28,0,0) + rtr.Normal:Angle()
  163.                             ang:RotateAroundAxis(ang:Right(), -90)
  164.                             pos = pos - (ang:Forward() * 10)
  165.  
  166.                          end
  167.  
  168.                          local knife = ents.Create("prop_physics")
  169.                          knife:SetModel("models/weapons/w_knife_t.mdl")
  170.                          knife:SetPos(pos)
  171.                          knife:SetCollisionGroup(COLLISION_GROUP_DEBRIS)
  172.                          knife:SetAngles(ang)
  173.                          knife.CanPickup = false
  174.  
  175.                          knife:Spawn()
  176.  
  177.                          local phys = knife:GetPhysicsObject()
  178.                          if IsValid(phys) then
  179.                             phys:EnableCollisions(false)
  180.                          end
  181.  
  182.                          constraint.Weld(rag, knife, bone, 0, 0, true)
  183.  
  184.                          -- need to close over knife in order to keep a valid ref to it
  185.                          rag:CallOnRemove("ttt_knife_cleanup", function() SafeRemoveEntity(knife) end)
  186.                       end
  187.  
  188.  
  189.    -- seems the spos and sdest are purely for effects/forces?
  190.    target:DispatchTraceAttack(dmg, spos + (self.Owner:GetAimVector() * 3), sdest)
  191.  
  192.    -- target appears to die right there, so we could theoretically get to
  193.    -- the ragdoll in here...
  194.  
  195.    self:Remove()      
  196. end
  197.  
  198. function SWEP:SecondaryAttack()
  199.    self.Weapon:SetNextPrimaryFire( CurTime() + self.Primary.Delay )
  200.    self.Weapon:SetNextSecondaryFire( CurTime() + self.Secondary.Delay )
  201.  
  202.  
  203.    self.Weapon:SendWeaponAnim( ACT_VM_MISSCENTER )
  204.  
  205.    if SERVER then
  206.       self.Owner:SetAnimation( PLAYER_ATTACK1 )
  207.  
  208.       local ply = self.Owner
  209.       if not IsValid(ply) then return end
  210.  
  211.       local ang = ply:EyeAngles()
  212.  
  213.       if ang.p < 90 then
  214.          ang.p = -10 + ang.p * ((90 + 10) / 90)
  215.       else
  216.          ang.p = 360 - ang.p
  217.          ang.p = -10 + ang.p * -((90 + 10) / 90)
  218.       end
  219.  
  220.       local vel = math.Clamp((90 - ang.p) * 5.5, 550, 800)
  221.  
  222.       local vfw = ang:Forward()
  223.       local vrt = ang:Right()
  224.      
  225.       local src = ply:GetPos() + (ply:Crouching() and ply:GetViewOffsetDucked() or ply:GetViewOffset())
  226.  
  227.       src = src + (vfw * 1) + (vrt * 3)
  228.  
  229.       local thr = vfw * vel + ply:GetVelocity()
  230.  
  231.       local knife_ang = Angle(-28,0,0) + ang
  232.       knife_ang:RotateAroundAxis(knife_ang:Right(), -90)
  233.  
  234.       local knife = ents.Create("ttt_knife_proj")
  235.       if not IsValid(knife) then return end
  236.       knife:SetPos(src)
  237.       knife:SetAngles(knife_ang)
  238.  
  239.       knife:Spawn()
  240.  
  241.       knife.Damage = self.Primary.Damage
  242.  
  243.       knife:SetOwner(ply)
  244.  
  245.       local phys = knife:GetPhysicsObject()
  246.       if IsValid(phys) then
  247.          phys:SetVelocity(thr)
  248.          phys:AddAngleVelocity(Vector(0, 1500, 0))
  249.          phys:Wake()
  250.       end
  251.  
  252.       self:Remove()
  253.    end
  254. end
  255.  
  256. function SWEP:Equip()
  257.    self.Weapon:SetNextPrimaryFire( CurTime() + (self.Primary.Delay * 1.5) )
  258.    self.Weapon:SetNextSecondaryFire( CurTime() + (self.Secondary.Delay * 1) )
  259. end
  260.  
  261. function SWEP:PreDrop()
  262.    -- for consistency, dropped knife should not have DNA/prints
  263.    self.fingerprints = {}
  264. end
  265.  
  266. function SWEP:OnRemove()
  267.    if CLIENT and IsValid(self.Owner) and self.Owner == LocalPlayer() and self.Owner:Alive() then
  268.       RunConsoleCommand("lastinv")
  269.    end
  270. end
  271.  
  272. if CLIENT then
  273.    function SWEP:DrawHUD()
  274.       local tr = self.Owner:GetEyeTrace(MASK_SHOT)
  275.  
  276.       if tr.HitNonWorld and IsValid(tr.Entity) and tr.Entity:IsPlayer()
  277.          and tr.Entity:Health() < (self.Primary.Damage + 10) then
  278.  
  279.          local x = ScrW() / 2.0
  280.          local y = ScrH() / 2.0
  281.  
  282.          surface.SetDrawColor(255, 0, 0, 255)
  283.  
  284.          local outer = 20
  285.          local inner = 10
  286.          surface.DrawLine(x - outer, y - outer, x - inner, y - inner)
  287.          surface.DrawLine(x + outer, y + outer, x + inner, y + inner)
  288.  
  289.          surface.DrawLine(x - outer, y + outer, x - inner, y + inner)
  290.          surface.DrawLine(x + outer, y - outer, x + inner, y - inner)
  291.  
  292.          draw.SimpleText("INSTANT KILL", "TabLarge", x, y - 30, COLOR_RED, TEXT_ALIGN_CENTER, TEXT_ALIGN_BOTTOM)
  293.       end        
  294.  
  295.       return self.BaseClass.DrawHUD(self)
  296.    end
  297. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement