zombiesurvival-evolved/gamemodes/zombiesurvival/entities/weapons/weapon_zs_zombie/shared.lua

356 lines
8 KiB
Lua
Raw Normal View History

2014-10-02 08:49:54 +08:00
SWEP.ZombieOnly = true
SWEP.IsMelee = true
SWEP.ViewModel = Model("models/Weapons/v_zombiearms.mdl")
SWEP.WorldModel = "models/weapons/w_crowbar.mdl"
SWEP.MeleeDelay = 0.74
SWEP.MeleeReach = 48
SWEP.MeleeSize = 1.5
SWEP.MeleeDamage = 30
SWEP.MeleeForceScale = 1
SWEP.MeleeDamageType = DMG_SLASH
SWEP.AlertDelay = 2.5
SWEP.Primary.ClipSize = -1
SWEP.Primary.DefaultClip = -1
SWEP.Primary.Automatic = true
SWEP.Primary.Ammo = "none"
SWEP.Primary.Delay = 1.2
SWEP.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = -1
SWEP.Secondary.Automatic = true
SWEP.Secondary.Ammo = "none"
function SWEP:StopMoaningSound()
local owner = self.Owner
owner:StopSound("NPC_BaseZombie.Moan1")
owner:StopSound("NPC_BaseZombie.Moan2")
owner:StopSound("NPC_BaseZombie.Moan3")
owner:StopSound("NPC_BaseZombie.Moan4")
end
function SWEP:StartMoaningSound()
self.Owner:EmitSound("NPC_BaseZombie.Moan"..math.random(4))
end
function SWEP:PlayHitSound()
self.Owner:EmitSound("npc/zombie/claw_strike"..math.random(3)..".wav")
end
function SWEP:PlayMissSound()
self.Owner:EmitSound("npc/zombie/claw_miss"..math.random(2)..".wav")
end
function SWEP:PlayAttackSound()
self.Owner:EmitSound("npc/zombie/zo_attack"..math.random(2)..".wav")
end
function SWEP:Initialize()
self:HideWorldModel()
end
function SWEP:CheckIdleAnimation()
if self.IdleAnimation and self.IdleAnimation <= CurTime() then
self.IdleAnimation = nil
self:SendWeaponAnim(ACT_VM_IDLE)
end
end
function SWEP:CheckAttackAnimation()
if self.NextAttackAnim and self.NextAttackAnim <= CurTime() then
self.NextAttackAnim = nil
self:SendAttackAnim()
end
end
function SWEP:CheckMoaning()
if self:IsMoaning() and self.Owner:Health() < self:GetMoanHealth() then
self:SetNextSecondaryFire(CurTime() + 1)
self:StopMoaning()
end
end
function SWEP:CheckMeleeAttack()
local swingend = self:GetSwingEndTime()
if swingend == 0 or CurTime() < swingend then return end
self:StopSwinging(0)
if SERVER then
self:Swung()
end
end
function SWEP:GetTracesNumPlayers(traces)
local numplayers = 0
for _, trace in pairs(traces) do
local ent = trace.Entity
if ent and ent:IsValid() and ent:IsPlayer() then
numplayers = numplayers + 1
end
end
return numplayers
end
function SWEP:GetDamage(numplayers, basedamage)
basedamage = basedamage or self.MeleeDamage
if numplayers then
return basedamage * math.Clamp(1.2 - numplayers * 0.2, 0.5, 1)
end
return basedamage
end
function SWEP:Swung()
local owner = self.Owner
owner:LagCompensation(true)
local hit = false
local traces = owner:PenetratingMeleeTrace(self.MeleeReach, self.MeleeSize, self.PreHit)
self.PreHit = nil
local damage = self:GetDamage(self:GetTracesNumPlayers(traces))
for _, trace in ipairs(traces) do
if not trace.Hit then continue end
hit = true
if trace.HitWorld then
self:MeleeHitWorld(trace)
else
local ent = trace.Entity
if ent and ent:IsValid() then
self:MeleeHit(ent, trace, damage)
end
end
end
if SERVER then
if hit then
self:PlayHitSound()
else
self:PlayMissSound()
end
end
owner:LagCompensation(false)
if self.FrozenWhileSwinging then
owner:ResetSpeed()
end
end
function SWEP:Think()
self:CheckIdleAnimation()
self:CheckAttackAnimation()
self:CheckMoaning()
self:CheckMeleeAttack()
end
function SWEP:MeleeHitWorld(trace)
end
function SWEP:MeleeHit(ent, trace, damage, forcescale)
if ent:IsPlayer() then
self:MeleeHitPlayer(ent, trace, damage, forcescale)
else
self:MeleeHitEntity(ent, trace, damage, forcescale)
end
self:ApplyMeleeDamage(ent, trace, damage)
end
function SWEP:MeleeHitEntity(ent, trace, damage, forcescale)
local phys = ent:GetPhysicsObject()
if phys:IsValid() and phys:IsMoveable() then
if trace.IsPreHit then
phys:ApplyForceOffset(damage * 750 * (forcescale or self.MeleeForceScale) * self.Owner:GetAimVector(), (ent:NearestPoint(self.Owner:EyePos()) + ent:GetPos() * 5) / 6)
else
phys:ApplyForceOffset(damage * 750 * (forcescale or self.MeleeForceScale) * trace.Normal, (ent:NearestPoint(trace.StartPos) + ent:GetPos() * 2) / 3)
end
ent:SetPhysicsAttacker(self.Owner)
end
end
function SWEP:MeleeHitPlayer(ent, trace, damage, forcescale)
ent:ThrowFromPositionSetZ(self.Owner:GetPos(), damage * 2.5 * (forcescale or self.MeleeForceScale))
ent:MeleeViewPunch(damage)
local nearest = ent:NearestPoint(trace.StartPos)
util.Blood(nearest, math.Rand(damage * 0.5, damage * 0.75), (nearest - trace.StartPos):GetNormalized(), math.Rand(damage * 5, damage * 10), true)
end
function SWEP:ApplyMeleeDamage(ent, trace, damage)
if ent:IsPlayer() then
ent:TakeSpecialDamage(damage, self.MeleeDamageType, self.Owner, self, trace.HitPos)
else
local dmgtype, owner, hitpos = self.MeleeDamageType, self.Owner, trace.HitPos
timer.Simple(0, function() -- Avoid prediction errors.
if ent:IsValid() then
ent:TakeSpecialDamage(damage, dmgtype, owner, self, hitpos)
end
end)
end
end
function SWEP:PrimaryAttack()
if CurTime() < self:GetNextPrimaryFire() or IsValid(self.Owner.FeignDeath) then return end
self:SetNextPrimaryFire(CurTime() + self.Primary.Delay)
self:SetNextSecondaryFire(self:GetNextPrimaryFire() + 0.5)
self:StartSwinging()
end
function SWEP:SecondaryAttack()
if CLIENT then return end
if CurTime() < self:GetNextSecondaryFire() then return end
self:SetNextSecondaryFire(CurTime() + self.AlertDelay)
self:DoAlert()
end
function SWEP:DoAlert()
self.Owner:LagCompensation(true)
local ent = self.Owner:MeleeTrace(4096, 24, self.Owner:GetMeleeFilter()).Entity
if ent:IsValid() and ent:IsPlayer() then
self:PlayAlertSound()
else
self:PlayIdleSound()
end
self.Owner:LagCompensation(false)
end
function SWEP:PlayAlertSound()
self.Owner:EmitSound("npc/zombie/zombie_alert"..math.random(1, 3)..".wav")
end
function SWEP:PlayIdleSound()
self.Owner:EmitSound("npc/zombie/zombie_voice_idle"..math.random(1, 14)..".wav")
end
function SWEP:SendAttackAnim()
if self.SwapAnims then
self:SendWeaponAnim(ACT_VM_HITCENTER)
else
self:SendWeaponAnim(ACT_VM_SECONDARYATTACK)
end
self.SwapAnims = not self.SwapAnims
end
function SWEP:StartSwinging()
if self.MeleeAnimationDelay then
self.NextAttackAnim = CurTime() + self.MeleeAnimationDelay
else
self:SendAttackAnim()
end
local owner = self.Owner
owner:DoAttackEvent()
if SERVER then
self:PlayAttackSound()
end
self:StopMoaning()
if self.FrozenWhileSwinging then
owner:SetSpeed(1)
end
if self.MeleeDelay > 0 then
self:SetSwingEndTime(CurTime() + self.MeleeDelay)
local trace = self.Owner:MeleeTrace(self.MeleeReach, self.MeleeSize, player.GetAll())
if trace.HitNonWorld then
trace.IsPreHit = true
self.PreHit = trace
end
self.IdleAnimation = CurTime() + self:SequenceDuration()
else
self:Swung()
end
end
function SWEP:StopSwinging()
self:SetSwingEndTime(0)
end
function SWEP:KnockedDown(status, exists)
self:StopSwinging()
end
function SWEP:StopMoaning()
if not self:IsMoaning() then return end
self:SetMoaning(false)
self:StopMoaningSound()
end
function SWEP:StartMoaning()
if self:IsMoaning() or IsValid(self.Owner.Revive) or IsValid(self.Owner.FeignDeath) then return end
self:SetMoaning(true)
self:SetMoanHealth(self.Owner:Health())
self:StartMoaningSound()
end
function SWEP:Deploy()
self.IdleAnimation = CurTime() + self:SequenceDuration()
if self.DelayWhenDeployed and self.Primary.Delay > 0 then
self:SetNextPrimaryFire(CurTime() + self.Primary.Delay)
self:SetNextSecondaryFire(self:GetNextPrimaryFire() + 0.5)
end
return true
end
function SWEP:OnRemove()
if IsValid(self.Owner) then
self:StopMoaning()
end
end
SWEP.Holster = SWEP.OnRemove
function SWEP:SetMoaning(moaning)
self:SetDTBool(0, moaning)
end
function SWEP:GetMoaning()
return self:GetDTBool(0)
end
SWEP.IsMoaning = SWEP.GetMoaning
function SWEP:SetMoanHealth(health)
self:SetDTInt(0, health)
end
function SWEP:GetMoanHealth()
return self:GetDTInt(0)
end
function SWEP:SetSwingEndTime(time)
self:SetDTFloat(0, time)
end
function SWEP:GetSwingEndTime()
return self:GetDTFloat(0)
end
function SWEP:IsSwinging()
return self:GetSwingEndTime() > 0
end
SWEP.IsAttacking = SWEP.IsSwinging