Advertisement
Guest User

entities/ttt_knife_proj.lua

a guest
Jan 25th, 2013
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.52 KB | None | 0 0
  1. -- thrown knife
  2.  
  3. if SERVER then
  4.    AddCSLuaFile("shared.lua")
  5. else
  6.    ENT.PrintName = "knife_thrown"
  7.    ENT.Icon = "VGUI/ttt/icon_knife"
  8. end
  9.  
  10.  
  11. ENT.Type = "anim"
  12. ENT.Model = Model("models/weapons/w_knife_t.mdl")
  13.  
  14. -- When true, score code considers us a weapon
  15. ENT.Projectile = true
  16.  
  17. ENT.Stuck = false
  18. ENT.Weaponised = false
  19. ENT.CanHavePrints = false
  20. ENT.IsSilent = true
  21. ENT.CanPickup = false
  22.  
  23. ENT.WeaponID = AMMO_KNIFE
  24.  
  25. ENT.Damage = 50
  26.  
  27. function ENT:Initialize()
  28.    self.Entity:SetModel(self.Model)
  29.  
  30.    self.Entity:PhysicsInit(SOLID_VPHYSICS)
  31.  
  32.    if SERVER then
  33.       self:SetGravity(0.4)
  34.       self:SetFriction(1.0)
  35.       self:SetElasticity(0.45)
  36.  
  37.       self.StartPos = self:GetPos()
  38.  
  39.       self.Entity:NextThink(CurTime())
  40.    end
  41.  
  42.    self.Weaponised = false
  43.    self.Stuck = false
  44. end
  45.  
  46. function ENT:HitPlayer(other, tr)
  47.  
  48.    local range_dmg = math.max(self.Damage, self.StartPos:Distance(self:GetPos()) / 3)
  49.  
  50.    if other:Health() < range_dmg + 10 then
  51.       self:KillPlayer(other, tr)
  52.    elseif SERVER then
  53.       local dmg = DamageInfo()
  54.       dmg:SetDamage(range_dmg)
  55.       dmg:SetAttacker(self:GetOwner())
  56.       dmg:SetInflictor(self.Entity)
  57.       dmg:SetDamageForce(self:EyeAngles():Forward())
  58.       dmg:SetDamagePosition(self:GetPos())
  59.       dmg:SetDamageType(DMG_SLASH)
  60.  
  61.       local ang = Angle(-28,0,0) + tr.Normal:Angle()
  62.       ang:RotateAroundAxis(ang:Right(), -90)
  63.       other:DispatchTraceAttack(dmg, self:GetPos() + ang:Forward() * 3, other:GetPos())
  64.  
  65.       if not self.Weaponised then
  66.          self:BecomeWeaponDelayed()
  67.       end
  68.    end
  69. end
  70.  
  71. function ENT:KillPlayer(other, tr)
  72.    local dmg = DamageInfo()
  73.    dmg:SetDamage(2000)
  74.    dmg:SetAttacker(self:GetOwner())
  75.    dmg:SetInflictor(self.Entity)
  76.    dmg:SetDamageForce(self:EyeAngles():Forward())
  77.    dmg:SetDamagePosition(self:GetPos())
  78.    dmg:SetDamageType(DMG_SLASH)
  79.  
  80.    -- this bone is why we need the trace
  81.    local bone = tr.PhysicsBone
  82.    local pos = tr.HitPos
  83.    local norm = tr.Normal
  84.    local ang = Angle(-28,0,0) + norm:Angle()
  85.    ang:RotateAroundAxis(ang:Right(), -90)
  86.    pos = pos - (ang:Forward() * 8)
  87.  
  88.    local knife = self.Entity
  89.    local prints = self.fingerprints
  90.  
  91.    other.effect_fn = function(rag)
  92.  
  93.                         if not IsValid(knife) or not IsValid(rag) then return end
  94.  
  95.                         knife:SetPos(pos)
  96.                         knife:SetCollisionGroup(COLLISION_GROUP_DEBRIS)
  97.                         knife:SetAngles(ang)
  98.  
  99.                         knife:SetMoveCollide(MOVECOLLIDE_DEFAULT)
  100.                         knife:SetMoveType(MOVETYPE_VPHYSICS)
  101.  
  102.                         knife.fingerprints = prints
  103.                         knife:SetNWBool("HasPrints", true)
  104.  
  105.                         --knife:SetSolid(SOLID_NONE)
  106.                         -- knife needs to be trace-able to get prints
  107.                         local phys = knife:GetPhysicsObject()
  108.                         if IsValid(phys) then
  109.                            phys:EnableCollisions(false)
  110.                         end
  111.  
  112.                         constraint.Weld(rag, knife, bone, 0, 0, true)
  113.  
  114.                         rag:CallOnRemove("ttt_knife_cleanup", function() SafeRemoveEntity(knife) end)
  115.                      end
  116.  
  117.  
  118.    other:DispatchTraceAttack(dmg, self:GetPos() + ang:Forward() * 3, other:GetPos())
  119.  
  120.    self.Stuck = true
  121. end
  122.  
  123. if SERVER then
  124.   function ENT:Think()
  125.      if self.Stuck then return end
  126.  
  127.      local vel = self:GetVelocity()
  128.      if vel == vector_origin then return end
  129.  
  130.      local tr = util.TraceLine({start=self:GetPos(), endpos=self:GetPos() + vel:GetNormal() * 20, filter={self.Entity, self:GetOwner()}, mask=MASK_SHOT_HULL})
  131.  
  132.      if tr.Hit and tr.HitNonWorld and IsValid(tr.Entity) then
  133.         local other = tr.Entity
  134.         if other:IsPlayer() then
  135.            self:HitPlayer(other, tr)
  136.         end
  137.      end
  138.  
  139.      self.Entity:NextThink(CurTime())
  140.      return true
  141.   end
  142. end
  143.  
  144. -- When this entity touches anything that is not a player, it should turn into a
  145. -- weapon ent again. If it touches a player it sticks in it.
  146. if SERVER then
  147.    function ENT:BecomeWeapon()
  148.       self.Weaponised = true
  149.  
  150.       local wep = ents.Create("weapon_ttt_knife")
  151.       wep:SetPos(self:GetPos())
  152.       wep:SetAngles(self:GetAngles())
  153.       wep.IsDropped = true
  154.  
  155.       local prints = self.fingerprints or {}
  156.  
  157.       self:Remove()
  158.  
  159.       wep:Spawn()
  160.       wep.fingerprints = wep.fingerprints or {}
  161.       table.Add(wep.fingerprints, prints)
  162.  
  163.       return wep
  164.    end
  165.  
  166.    function ENT:BecomeWeaponDelayed()
  167.       -- delay the weapon-replacement a tick because Source gets very angry
  168.       -- if you do fancy stuff in a physics callback
  169.       local knife = self
  170.       timer.Simple(0,
  171.                    function()
  172.                       if IsValid(knife) and not knife.Weaponised then
  173.                          knife:BecomeWeapon()
  174.                       end
  175.                    end)
  176.    end
  177.  
  178.    function ENT:PhysicsCollide(data, phys)
  179.       if self.Stuck then return false end
  180.  
  181.       local other = data.HitEntity
  182.       if not IsValid(other) and not other:IsWorld() then return end
  183.  
  184.       if other:IsPlayer() then
  185.          local tr = util.TraceLine({start=self:GetPos(), endpos=other:LocalToWorld(other:OBBCenter()), filter={self.Entity, self:GetOwner()}, mask=MASK_SHOT_HULL})
  186.          if tr.Hit and tr.Entity == other then
  187.             self:HitPlayer(other, tr)
  188.          end
  189.  
  190.          return true
  191.       end
  192.  
  193.       if not self.Weaponised then
  194.          self:BecomeWeaponDelayed()
  195.       end
  196.    end
  197. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement