Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- thrown knife
- if SERVER then
- AddCSLuaFile("shared.lua")
- else
- ENT.PrintName = "knife_thrown"
- ENT.Icon = "VGUI/ttt/icon_knife"
- end
- ENT.Type = "anim"
- ENT.Model = Model("models/weapons/w_knife_t.mdl")
- -- When true, score code considers us a weapon
- ENT.Projectile = true
- ENT.Stuck = false
- ENT.Weaponised = false
- ENT.CanHavePrints = false
- ENT.IsSilent = true
- ENT.CanPickup = false
- ENT.WeaponID = AMMO_KNIFE
- ENT.Damage = 50
- function ENT:Initialize()
- self.Entity:SetModel(self.Model)
- self.Entity:PhysicsInit(SOLID_VPHYSICS)
- if SERVER then
- self:SetGravity(0.4)
- self:SetFriction(1.0)
- self:SetElasticity(0.45)
- self.StartPos = self:GetPos()
- self.Entity:NextThink(CurTime())
- end
- self.Weaponised = false
- self.Stuck = false
- end
- function ENT:HitPlayer(other, tr)
- local range_dmg = math.max(self.Damage, self.StartPos:Distance(self:GetPos()) / 3)
- if other:Health() < range_dmg + 10 then
- self:KillPlayer(other, tr)
- elseif SERVER then
- local dmg = DamageInfo()
- dmg:SetDamage(range_dmg)
- dmg:SetAttacker(self:GetOwner())
- dmg:SetInflictor(self.Entity)
- dmg:SetDamageForce(self:EyeAngles():Forward())
- dmg:SetDamagePosition(self:GetPos())
- dmg:SetDamageType(DMG_SLASH)
- local ang = Angle(-28,0,0) + tr.Normal:Angle()
- ang:RotateAroundAxis(ang:Right(), -90)
- other:DispatchTraceAttack(dmg, self:GetPos() + ang:Forward() * 3, other:GetPos())
- if not self.Weaponised then
- self:BecomeWeaponDelayed()
- end
- end
- end
- function ENT:KillPlayer(other, tr)
- local dmg = DamageInfo()
- dmg:SetDamage(2000)
- dmg:SetAttacker(self:GetOwner())
- dmg:SetInflictor(self.Entity)
- dmg:SetDamageForce(self:EyeAngles():Forward())
- dmg:SetDamagePosition(self:GetPos())
- dmg:SetDamageType(DMG_SLASH)
- -- this bone is why we need the trace
- local bone = tr.PhysicsBone
- local pos = tr.HitPos
- local norm = tr.Normal
- local ang = Angle(-28,0,0) + norm:Angle()
- ang:RotateAroundAxis(ang:Right(), -90)
- pos = pos - (ang:Forward() * 8)
- local knife = self.Entity
- local prints = self.fingerprints
- other.effect_fn = function(rag)
- if not IsValid(knife) or not IsValid(rag) then return end
- knife:SetPos(pos)
- knife:SetCollisionGroup(COLLISION_GROUP_DEBRIS)
- knife:SetAngles(ang)
- knife:SetMoveCollide(MOVECOLLIDE_DEFAULT)
- knife:SetMoveType(MOVETYPE_VPHYSICS)
- knife.fingerprints = prints
- knife:SetNWBool("HasPrints", true)
- --knife:SetSolid(SOLID_NONE)
- -- knife needs to be trace-able to get prints
- local phys = knife:GetPhysicsObject()
- if IsValid(phys) then
- phys:EnableCollisions(false)
- end
- constraint.Weld(rag, knife, bone, 0, 0, true)
- rag:CallOnRemove("ttt_knife_cleanup", function() SafeRemoveEntity(knife) end)
- end
- other:DispatchTraceAttack(dmg, self:GetPos() + ang:Forward() * 3, other:GetPos())
- self.Stuck = true
- end
- if SERVER then
- function ENT:Think()
- if self.Stuck then return end
- local vel = self:GetVelocity()
- if vel == vector_origin then return end
- local tr = util.TraceLine({start=self:GetPos(), endpos=self:GetPos() + vel:GetNormal() * 20, filter={self.Entity, self:GetOwner()}, mask=MASK_SHOT_HULL})
- if tr.Hit and tr.HitNonWorld and IsValid(tr.Entity) then
- local other = tr.Entity
- if other:IsPlayer() then
- self:HitPlayer(other, tr)
- end
- end
- self.Entity:NextThink(CurTime())
- return true
- end
- end
- -- When this entity touches anything that is not a player, it should turn into a
- -- weapon ent again. If it touches a player it sticks in it.
- if SERVER then
- function ENT:BecomeWeapon()
- self.Weaponised = true
- local wep = ents.Create("weapon_ttt_knife")
- wep:SetPos(self:GetPos())
- wep:SetAngles(self:GetAngles())
- wep.IsDropped = true
- local prints = self.fingerprints or {}
- self:Remove()
- wep:Spawn()
- wep.fingerprints = wep.fingerprints or {}
- table.Add(wep.fingerprints, prints)
- return wep
- end
- function ENT:BecomeWeaponDelayed()
- -- delay the weapon-replacement a tick because Source gets very angry
- -- if you do fancy stuff in a physics callback
- local knife = self
- timer.Simple(0,
- function()
- if IsValid(knife) and not knife.Weaponised then
- knife:BecomeWeapon()
- end
- end)
- end
- function ENT:PhysicsCollide(data, phys)
- if self.Stuck then return false end
- local other = data.HitEntity
- if not IsValid(other) and not other:IsWorld() then return end
- if other:IsPlayer() then
- local tr = util.TraceLine({start=self:GetPos(), endpos=other:LocalToWorld(other:OBBCenter()), filter={self.Entity, self:GetOwner()}, mask=MASK_SHOT_HULL})
- if tr.Hit and tr.Entity == other then
- self:HitPlayer(other, tr)
- end
- return true
- end
- if not self.Weaponised then
- self:BecomeWeaponDelayed()
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement