zombiesurvival-evolved/gamemodes/zombiesurvival/entities/weapons/weapon_zs_lacerator_charging.lua

292 lines
7.4 KiB
Lua
Raw Normal View History

AddCSLuaFile()
DEFINE_BASECLASS("weapon_zs_zombie")
SWEP.PrintName = "Charger"
SWEP.ViewModel = Model("models/weapons/v_pza.mdl")
SWEP.MeleeDelay = 0.8
SWEP.MeleeDamage = 23
SWEP.BleedDamage = 10
SWEP.MeleeDamageVsProps = 23
SWEP.Primary.Delay = 1.5
SWEP.SwingAnimSpeed = 0.6
SWEP.ChargeDamage = 30
SWEP.ChargeDamageVsPlayerMul = 0.8333
SWEP.ChargeReach = 26
SWEP.ChargeSize = 12
SWEP.ChargeStartDelay = 0.35
SWEP.ChargeDelay = 2
SWEP.ChargeRecovery = 0.75
SWEP.ChargeTime = 2.5
SWEP.ChargeAccel = 0.5
SWEP.ChargeKnockdown = 1.75
SWEP.Secondary.Automatic = false
SWEP.NextAllowCharge = 0
function SWEP:Think()
BaseClass.Think(self)
local curtime = CurTime()
local owner = self:GetOwner()
if self.NextAllowJump and self.NextAllowJump <= curtime then
self.NextAllowJump = nil
owner:ResetJumpPower()
end
if self:IsCharging() then
if owner:WaterLevel() >= 2 or CurTime() > self:GetChargeStart() + self.ChargeTime then
self:StopCharge()
elseif IsFirstTimePredicted() then
local dir = owner:GetVelocity()
dir:Normalize()
local chargemul = math.min(self:GetCharge(), owner:GetVelocity():LengthSqr() / 193600)
local traces = owner:CompensatedZombieMeleeTrace(self.ChargeReach, self.ChargeSize, owner:WorldSpaceCenter(), dir)
local damage = self:GetDamage(self:GetTracesNumPlayers(traces), self.ChargeDamage * chargemul)
local hit = false
for _, trace in ipairs(traces) do
if not trace.Hit then continue end
if trace.HitWorld then
if trace.HitNormal.z < 0.8 then
hit = true
self:MeleeHitWorld(trace)
end
else
local ent = trace.Entity
if ent and ent:IsValid() and not ent:IsProjectile() then
hit = true
self:MeleeHit(ent, trace, damage * (ent:IsPlayer() and self.ChargeDamageVsPlayerMul or ent.PounceWeakness or 1) * (self:IsChargeCritical() and not ent:IsPlayer() and 2 or 1), 1)
if ent:IsPlayer() then
ent:ThrowFromPositionSetZ(trace.StartPos, 120 * chargemul + owner:GetVelocity():Length() * 0.5)
if CurTime() >= (ent.NextKnockdown or 0) and self:IsChargeCritical() then
ent:GiveStatus("knockdown", self.ChargeKnockdown * chargemul)
ent.NextKnockdown = CurTime() + 4 * chargemul
end
end
end
end
end
if not self.CriticalCharge and self:IsChargeCritical() then
self:PlayCriticalChargeStartSound()
self.CriticalCharge = true
end
if hit then
self:PlayChargeHitSound()
self:StopCharge()
end
end
elseif self:GetChargeStart() > 0 and CurTime() > self:GetChargeStart() then
self:StartCharge()
elseif self.m_ViewAngles then
self.m_ViewAngles = nil
end
self:NextThink(curtime)
return true
end
function SWEP:PlayChargeHitSound()
self:EmitSound("npc/antlion_guard/shove1.wav")
self:EmitSound("npc/fast_zombie/wake1.wav", 75, math.random(75, 80), nil, CHAN_AUTO)
end
function SWEP:PlayCriticalChargeStartSound()
self:EmitSound("npc/zombie_poison/pz_throw3.wav", 75, math.random(85, 90), nil, CHAN_AUTO)
end
function SWEP:Move(mv)
local charge = self:GetCharge()
if self:GetChargeStart() > 0 and charge <= 0 then
mv:SetMaxSpeed(0)
mv:SetMaxClientSpeed(0)
elseif charge > 0 then
mv:SetForwardSpeed(10000)
mv:SetSideSpeed(mv:GetSideSpeed() * 0.1)
local mul = 1 + charge * 1 + (self:IsChargeCritical() and 0.5 or 0)
mv:SetMaxSpeed(mv:GetMaxSpeed() * mul)
mv:SetMaxClientSpeed(mv:GetMaxClientSpeed() * mul)
end
end
function SWEP:PrimaryAttack()
if self:IsCharging() or self:GetChargeStart() > 0 then return end
BaseClass.PrimaryAttack(self)
end
function SWEP:MeleeHit(ent, trace, damage, forcescale)
if not ent:IsPlayer() and not (self:IsCharging() or self:GetChargeStart() > 0) then
damage = self.MeleeDamageVsProps
end
BaseClass.MeleeHit(self, ent, trace, damage, forcescale)
end
function SWEP:ApplyMeleeDamage(ent, trace, damage)
if SERVER and ent:IsPlayer() and not (self:IsCharging() or self:GetChargeStart() > 0) then
local bleed = ent:GiveStatus("bleed")
if bleed and bleed:IsValid() then
bleed:AddDamage(self.BleedDamage)
bleed.Damager = self:GetOwner()
end
end
BaseClass.ApplyMeleeDamage(self, ent, trace, damage)
end
function SWEP:SecondaryAttack()
if self:IsCharging() or self:GetChargeStart() > 0 then return end
if self:GetOwner():IsOnGround() then
if CurTime() < self:GetNextPrimaryFire() or CurTime() < self:GetNextSecondaryFire() or CurTime() < self.NextAllowCharge then return end
self:SetNextPrimaryFire(math.huge)
self:SetChargeStart(CurTime() + self.ChargeStartDelay)
self:GetOwner():ResetJumpPower()
if IsFirstTimePredicted() then
self:PlayChargeStartSound()
end
end
end
function SWEP:StartCharge()
if self:IsCharging() then return end
local owner = self:GetOwner()
if owner:IsOnGround() then
self:SetCharging(true)
self.m_ViewAngles = owner:EyeAngles()
if IsFirstTimePredicted() then
self:PlayChargeSound()
end
owner:SetAnimation(PLAYER_JUMP)
else
self:SetNextSecondaryFire(CurTime())
self.m_ViewAngles = nil
self.NextAllowJump = CurTime()
self.NextAllowCharge = CurTime() + self.ChargeDelay
self:SetNextPrimaryFire(CurTime() + self.ChargeRecovery)
self:GetOwner():ResetJumpPower()
end
end
function SWEP:PlayChargeSound()
self:EmitSound("npc/ichthyosaur/attack_growl1.wav", 75, math.random(100,116), nil, CHAN_AUTO)
end
function SWEP:PlayChargeStartSound()
self:EmitSound("npc/fast_zombie/leap1.wav", 75, math.random(75,80), nil, CHAN_AUTO)
end
function SWEP:StopCharge()
if not self:IsCharging() then return end
self:SetChargeStart(0)
self:SetCharging(false)
self:SetNextSecondaryFire(CurTime())
self.m_ViewAngles = nil
self.NextAllowJump = CurTime() + 0.25
self.NextAllowCharge = CurTime() + self.ChargeDelay
self:SetNextPrimaryFire(CurTime() + self.ChargeRecovery)
self:GetOwner():ResetJumpPower()
self.CriticalCharge = nil
end
function SWEP:Reload()
BaseClass.SecondaryAttack(self)
end
function SWEP:OnRemove()
self.Removing = true
local owner = self:GetOwner()
if owner and owner:IsValid() then
owner:ResetJumpPower()
end
BaseClass.OnRemove(self)
end
function SWEP:Holster()
local owner = self:GetOwner()
if owner and owner:IsValid() then
owner:ResetJumpPower()
end
BaseClass.Holster(self)
end
function SWEP:ResetJumpPower(power)
if self.Removing then return end
if self.NextAllowJump and CurTime() < self.NextAllowJump or self:IsCharging() or self:GetChargeStart() > 0 then
return 1
end
end
function SWEP:PlayAttackSound()
self:EmitSound("npc/antlion_guard/angry"..math.random(3)..".wav")
end
function SWEP:PlayAlertSound()
self:GetOwner():EmitSound("npc/zombie/zombie_alert"..math.random(1,3)..".wav", 75, math.random(80,85))
end
SWEP.PlayIdleSound = SWEP.PlayAlertSound
function SWEP:SetChargeStart(time)
self:SetDTFloat(1, time)
end
function SWEP:GetChargeStart()
return self:GetDTFloat(1)
end
function SWEP:GetCharge()
if self:GetChargeStart() == 0 then return 0 end
return math.Clamp((CurTime() - self:GetChargeStart()) / self.ChargeAccel, 0, 1)
end
function SWEP:IsChargeCritical()
if not self:IsCharging() then return false end
return CurTime() >= self:GetChargeStart() + self.ChargeTime * 0.6
end
function SWEP:SetCharging(charging)
self:SetDTBool(2, charging)
end
function SWEP:GetCharging()
return self:GetDTBool(2)
end
SWEP.IsCharging = SWEP.GetCharging
if not CLIENT then return end
SWEP.ViewModelFOV = 48
function SWEP:ViewModelDrawn()
render.SetColorModulation(1, 1, 1)
end
function SWEP:PreDrawViewModel(vm)
render.SetColorModulation(0.7, 0.17, 0)
end