Is there a way to make it where a "shot" is fired only at a certain point in a weapon's animation? I'm trying to make some melee SWEPs, but it's odd how the weapon hits a surface before the animation is at the right frame where it looks like it's hitting something.
You could use a timer.Simple where the ShootBullets function is called with some math to determine a reasonable delay for impact depending on the distance of the trace.
[QUOTE=KingofBeast;42353623]You could use a timer.Simple where the ShootBullets function is called with some math to determine a reasonable delay for impact depending on the distance of the trace.[/QUOTE]
Sorry, I'm not all that familiar with how to implement this in my lua. Here's a snippet of the PrimaryAttack function:
[code]function SWEP:PrimaryAttack()
local tr = {}
tr.start = self.Owner:GetShootPos()
tr.endpos = self.Owner:GetShootPos() + ( self.Owner:GetAimVector() * 85 )
tr.filter = self.Owner
tr.mask = MASK_SHOT
local trace = util.TraceLine( tr )
self:DoIdle(1)
self.Weapon:SetNextSecondaryFire(CurTime() + 0.5)
self.Weapon:SetNextPrimaryFire(CurTime() + 0.5)
self.Owner:SetAnimation( PLAYER_ATTACK1 )
if ( trace.Hit ) then
if (trace.Hit) and (trace.Entity:IsWorld()) then
util.Decal("ManhackCut", trace.HitPos + trace.HitNormal, trace.HitPos - trace.HitNormal)
self:EmitSound("Weapon_Knife.HitWall")
local effectdata = EffectData()
effectdata:SetOrigin(trace.HitPos)
effectdata:SetEntity(self.Owner:GetViewModel())
effectdata:SetStart(trace.HitPos)
effectdata:SetNormal(trace.HitNormal)
effectdata:SetScale( 1.5 )
effectdata:SetRadius( 0.9 )
effectdata:SetMagnitude( 0.6 )
util.Effect( "Sparks", effectdata )
end
if trace.Entity:IsPlayer() or string.find(trace.Entity:GetClass(),"npc") or string.find(trace.Entity:GetClass(),"prop_ragdoll") then
self.Weapon:SendWeaponAnim(ACT_VM_HITCENTER)
bullet = {}
bullet.Num = 1
bullet.Src = self.Owner:GetShootPos()
bullet.Dir = self.Owner:GetAimVector()
bullet.Spread = Vector(0, 0, 0)
bullet.Tracer = 0
bullet.Force = 10
bullet.Damage = 35
self.Owner:FireBullets(bullet)
self.Weapon:EmitSound( "weapons/knife/knife_hit" .. math.random(1, 4) .. ".wav" )
else
self.Weapon:SendWeaponAnim(ACT_VM_HITCENTER)
bullet = {}
bullet.Num = 1
bullet.Src = self.Owner:GetShootPos()
bullet.Dir = self.Owner:GetAimVector()
bullet.Spread = Vector(0, 0, 0)
bullet.Tracer = 0
bullet.Force = 10
bullet.Damage = 35
self.Owner:FireBullets(bullet)
self.Weapon:EmitSound(self.WallSound,100,math.random(90,120))
util.Decal("ManhackCut", trace.HitPos + trace.HitNormal, trace.HitPos - trace.HitNormal)
end
else
self.Weapon:EmitSound(self.MissSound,100,math.random(90,120))
self.Weapon:SendWeaponAnim(ACT_VM_MISSCENTER)
self.Weapon:SetNextSecondaryFire(CurTime() + 0.8)
end
end[/code]
Fortune,
Now it's saying "attempt to index global 'trace' (a nil value)."
The line it points out is the "if ( trace.Hit ) then" statement.
[QUOTE=Fidchell;42354108]Fortune,
Now it's saying "attempt to index global 'trace' (a nil value)."
The line it points out is the "if ( trace.Hit ) then" statement.[/QUOTE]
Woops hang on, replace this:
[CODE] timer.Simple(0.5,function()
local tr = {}
tr.start = self.Owner:GetShootPos()
tr.endpos = self.Owner:GetShootPos() + ( self.Owner:GetAimVector() * 85 )
tr.filter = self.Owner
tr.mask = MASK_SHOT
local trace = util.TraceLine( tr )
end)[/CODE]
With this:
[CODE]timer.Simple(0.5,function()
local tr = {}
tr.start = self.Owner:GetShootPos()
tr.endpos = self.Owner:GetShootPos() + ( self.Owner:GetAimVector() * 85 )
tr.filter = self.Owner
tr.mask = MASK_SHOT
trace = util.TraceLine( tr )
end)[/CODE]
I forgot that it would become local to the timer, that should fix it.
That won't help. Give me a moment, I'll fix it up.
[b]Edited:[/b] Give this a whirl.
[lua]
local hitdelay = 0.5-- Edit this variable to your liking
function SWEP:PrimaryAttack()
local tr = {}
tr.start = self.Owner:GetShootPos()
tr.endpos = self.Owner:GetShootPos() + ( self.Owner:GetAimVector() * 85 )
tr.filter = self.Owner
tr.mask = MASK_SHOT
local trace = util.TraceLine( tr )
self:DoIdle(1)
self.Weapon:SetNextSecondaryFire(CurTime() + 0.5)
self.Weapon:SetNextPrimaryFire(CurTime() + 0.5)
self.Owner:SetAnimation( PLAYER_ATTACK1 )
self.Weapon:EmitSound(self.MissSound,100,math.random(90,120))
-- Woosh sound no matter what
if ( trace.Hit ) then
if (trace.Entity:IsWorld()) then
util.Decal("ManhackCut", trace.HitPos + trace.HitNormal, trace.HitPos - trace.HitNormal)
self:EmitSound("Weapon_Knife.HitWall")
local effectdata = EffectData()
effectdata:SetOrigin(trace.HitPos)
effectdata:SetEntity(self.Owner:GetViewModel())
effectdata:SetStart(trace.HitPos)
effectdata:SetNormal(trace.HitNormal)
effectdata:SetScale( 1.5 )
effectdata:SetRadius( 0.9 )
effectdata:SetMagnitude( 0.6 )
timer.Simple(hitdelay, function()
util.Effect( "Sparks", effectdata )
end)
elseif trace.Entity:IsPlayer() or string.find(trace.Entity:GetClass(),"npc") or string.find(trace.Entity:GetClass(),"prop_ragdoll") then
self.Weapon:SendWeaponAnim(ACT_VM_HITCENTER)
bullet = {}
bullet.Num = 1
bullet.Src = self.Owner:GetShootPos()
bullet.Dir = self.Owner:GetAimVector()
bullet.Spread = Vector(0, 0, 0)
bullet.Tracer = 0
bullet.Force = 10
bullet.Damage = 35
local wep = self.Weapon
local own = self.Owner
timer.Simple(hitdelay, function()
if (!wep or !own or !own:IsValid() or !wep:IsValid()) then return end
own:FireBullets(bullet)
wep:EmitSound( "weapons/knife/knife_hit" .. math.random(1, 4) .. ".wav" )
end)
else
self.Weapon:SendWeaponAnim(ACT_VM_HITCENTER)
bullet = {}
bullet.Num = 1
bullet.Src = self.Owner:GetShootPos()
bullet.Dir = self.Owner:GetAimVector()
bullet.Spread = Vector(0, 0, 0)
bullet.Tracer = 0
bullet.Force = 10
bullet.Damage = 35
local wep = self.Weapon
local own = self.Owner
timer.Simple(hitdelay, function()
if (!wep or !own or !own:IsValid() or !wep:IsValid()) then return end
own:FireBullets(bullet)
wep:EmitSound(self.WallSound,100,math.random(90,120))
util.Decal("ManhackCut", trace.HitPos + trace.HitNormal, trace.HitPos - trace.HitNormal)
end)
end
else
self.Weapon:SendWeaponAnim(ACT_VM_MISSCENTER)
self.Weapon:SetNextSecondaryFire(CurTime() + 0.8)
end
end[/lua]
KingofBeast, it works excellently! Thanks a bunch for your help. The only remaining problem now is that for some reason when I strike the world, the weapon doesn't go through an animation at all.
EDIT: Also, I have noticed that in order to actually hit someone, you have to be in range, no matter how long the delay is. Is it possible to make it where the weapon only detects the distance between you and the enemy when the delay is over?
What about delay based on how far what you are shooting is? That would be cool.
Sorry, you need to Log In to post a reply to this thread.