Files
2026-03-31 10:27:04 +03:00

348 lines
11 KiB
Lua

SWEP.GrenadeDownKey = IN_GRENADE1
SWEP.GrenadeMenuKey = IN_GRENADE2
function SWEP:IsQuickNadeAllowed()
return TacRP.ConVars["quicknade"]:GetBool() and self:GetValue("CanQuickNade")
end
function SWEP:PrimeGrenade()
self.Primary.Automatic = true
if !self:IsQuickNadeAllowed() and !self:GetValue("PrimaryGrenade") then return end
if self:StillWaiting(nil, true) then return end
if self:GetPrimedGrenade() then return end
if engine.ActiveGamemode() == "terrortown" and GetRoundState() == ROUND_PREP and ((TTT2 and !GetConVar("ttt_nade_throw_during_prep"):GetBool()) or (!TTT2 and GetConVar("ttt_no_nade_throw_during_prep"):GetBool())) then
return
end
if !self:GetValue("PrimaryGrenade") and !self:CheckGrenade(nil, true) then
self:SelectGrenade(nil, true)
end
-- if self:SprintLock() then return end
self:CancelReload()
local nade = self:GetValue("PrimaryGrenade") and TacRP.QuickNades[self:GetValue("PrimaryGrenade")] or self:GetGrenade()
if nade.Singleton then
if !self:GetOwner():HasWeapon(nade.GrenadeWep) then return end
elseif !TacRP.IsGrenadeInfiniteAmmo(nade) then
local ammo = self:GetOwner():GetAmmoCount(nade.Ammo)
if ammo < 1 then return end
-- self:GetOwner():SetAmmo(ammo - 1, nade.Ammo)
end
local rate = self:GetValue("QuickNadeTimeMult") / (nade.ThrowSpeed or 1)
if self:GetValue("QuickNadeTryImpact") and nade.CanSetImpact then
rate = rate * 1.5
end
local t = self:PlayAnimation("prime_grenade", rate, true)
self:SetPrimedGrenade(true)
self:ToggleBlindFire(TacRP.BLINDFIRE_NONE)
self:ScopeToggle(0)
local ct = CurTime()
self:SetStartPrimedGrenadeTime(ct)
self:SetAnimLockTime(ct + (t * 0.75))
self:SetNextPrimaryFire(ct + (t * 1.1))
self:GetOwner():DoCustomAnimEvent(PLAYERANIMEVENT_ATTACK_SECONDARY, t * 1000)
if !nade.NoSounds then
self:EmitSound(nade.PullSound or ("TacRP/weapons/grenade/pullpin-" .. math.random(1, 2) .. ".wav"), 65)
end
if CLIENT then return end
self.CurrentGrenade = self:GetGrenade()
end
function SWEP:ThrowGrenade()
local nade = self:GetValue("PrimaryGrenade") and TacRP.QuickNades[self:GetValue("PrimaryGrenade")] or self.CurrentGrenade or self:GetGrenade()
local force = nade.ThrowForce
local ent = nade.GrenadeEnt
local src = self:GetOwner():EyePos()
local ang = self:GetOwner():EyeAngles()
local spread = 0
local amount = 1
local t = 0
if !nade.OverhandOnly and (self.GrenadeThrowOverride == true or (self.GrenadeThrowOverride == nil and !self:GetOwner():KeyDown(self.GrenadeDownKey))) then
t = self:PlayAnimation("throw_grenade_underhand", self:GetValue("QuickNadeTimeMult"), true, true)
force = force / 2
ang:RotateAroundAxis(ang:Right(), 20)
if nade.UnderhandSpecial then
force = force * 0.75
ang:RotateAroundAxis(ang:Right(), -10)
amount = math.random(2, 4)
spread = 0.15
end
else
ang:RotateAroundAxis(ang:Right(), 5)
t = self:PlayAnimation("throw_grenade", self:GetValue("QuickNadeTimeMult"), true, true)
end
self.GrenadeThrowOverride = nil
self.GrenadeDownKey = IN_GRENADE1
if SERVER then
if (self.GrenadeThrowCharge or 0) > 0 then
force = force * (1 + self.GrenadeThrowCharge)
end
self.GrenadeThrowCharge = nil
for i = 1, amount do
local rocket = ents.Create(ent or "")
if !IsValid(rocket) then return end
local dispersion = Angle(math.Rand(-1, 1), math.Rand(-1, 1), 0)
dispersion = dispersion * spread * 36
rocket:SetPos(src)
rocket:SetOwner(self:GetOwner())
rocket:SetAngles(ang + dispersion)
rocket:Spawn()
rocket:SetPhysicsAttacker(self:GetOwner(), 10)
if TacRP.IsGrenadeInfiniteAmmo(nade) then
rocket.PickupAmmo = nil
rocket.WeaponClass = nil -- dz ents
end
if self:GetValue("QuickNadeTryImpact") and nade.CanSetImpact then
rocket.InstantFuse = false
rocket.Delay = 0
rocket.Armed = false
rocket.ImpactFuse = true
end
if nade.TTTTimer then
rocket:SetGravity(0.4)
rocket:SetFriction(0.2)
rocket:SetElasticity(0.45)
rocket:SetDetonateExact(CurTime() + nade.TTTTimer)
rocket:SetThrower(self:GetOwner())
end
local phys = rocket:GetPhysicsObject()
if phys:IsValid() then
phys:ApplyForceCenter((ang + dispersion):Forward() * force + self:GetOwner():GetVelocity())
phys:AddAngleVelocity(VectorRand() * 1000)
end
if nade.Spoon and TacRP.ConVars["dropmagazinemodel"]:GetBool() then
local mag = ents.Create("TacRP_droppedmag")
if mag then
mag:SetPos(src)
mag:SetAngles(ang)
mag.Model = "models/weapons/tacint/flashbang_spoon.mdl"
mag.ImpactType = "spoon"
mag:SetOwner(self:GetOwner())
mag:Spawn()
local phys2 = mag:GetPhysicsObject()
if IsValid(phys2) then
phys2:ApplyForceCenter(ang:Forward() * force * 0.25 + VectorRand() * 25)
phys2:AddAngleVelocity(Vector(math.Rand(-300, 300), math.Rand(-300, 300), math.Rand(-300, 300)))
end
end
end
end
if !nade.NoSounds then
self:EmitSound(nade.ThrowSound or ("tacrp/weapons/grenade/throw-" .. math.random(1, 2) .. ".wav"), 65)
end
if !nade.Singleton and !TacRP.IsGrenadeInfiniteAmmo(nade) then
self:GetOwner():RemoveAmmo(1, nade.Ammo)
end
end
if self:GetValue("PrimaryGrenade") then
if !TacRP.IsGrenadeInfiniteAmmo(nade) and self:GetOwner():GetAmmoCount(nade.Ammo) == 0 then
if SERVER then
self:Remove()
end
else
self:SetTimer(t, function()
self:PlayAnimation("deploy", self:GetValue("DeployTimeMult"), true, true)
end)
end
elseif nade.Singleton and self:GetOwner():HasWeapon(nade.GrenadeWep) then
local nadewep = self:GetOwner():GetWeapon(nade.GrenadeWep)
nadewep.OnRemove = nil -- TTT wants to switch to unarmed when the nade wep is removed - DON'T.
if SERVER then
nadewep:Remove()
end
elseif nade.GrenadeWep and self:GetOwner():HasWeapon(nade.GrenadeWep) and !TacRP.IsGrenadeInfiniteAmmo(nade) and self:GetOwner():GetAmmoCount(nade.Ammo) == 0 then
if SERVER then
self:GetOwner():GetWeapon(nade.GrenadeWep):Remove()
end
end
end
function SWEP:GetGrenade(index)
index = index or self:GetGrenadeIndex()
return TacRP.QuickNades[TacRP.QuickNades_Index[index]]
end
function SWEP:GetGrenadeIndex()
return IsValid(self:GetOwner()) and self:GetOwner():GetNWInt("ti_nade", 1) or 1
end
function SWEP:GetNextGrenade(ind)
ind = ind or self:GetGrenadeIndex()
ind = ind + 1
if ind > TacRP.QuickNades_Count then
ind = 1
elseif ind < 1 then
ind = TacRP.QuickNades_Count
end
if !self:CheckGrenade(ind) then
return self:GetNextGrenade(ind)
end
return self:GetGrenade(ind)
end
function SWEP:SelectGrenade(index, requireammo)
if !self:IsQuickNadeAllowed() then return end
if !IsFirstTimePredicted() then return end
if self:GetPrimedGrenade() then return end
local ind = self:GetOwner():GetNWInt("ti_nade", 1)
if index then
ind = index
elseif !requireammo then
if self:GetOwner():KeyDown(IN_WALK) then
ind = ind - 1
else
ind = ind + 1
end
end
if ind > TacRP.QuickNades_Count then
ind = 1
elseif ind < 1 then
ind = TacRP.QuickNades_Count
end
if !self:CheckGrenade(ind, requireammo) then
local nades = self:GetAvailableGrenades(requireammo)
if #nades > 0 then
ind = nades[1].Index
end
end
self:GetOwner():SetNWInt("ti_nade", ind)
self.Secondary.Ammo = self:GetGrenade().Ammo or "none"
end
function SWEP:CheckGrenade(index, checkammo)
index = index or (self:GetValue("PrimaryGrenade") and TacRP.QuickNades_Index[self:GetValue("PrimaryGrenade")] or self:GetOwner():GetNWInt("ti_nade", 1))
local nade = self:GetGrenade(index)
if nade.Singleton then
return self:GetOwner():HasWeapon(nade.GrenadeWep)
end
local hasammo = (nade.Ammo == nil or self:GetOwner():GetAmmoCount(nade.Ammo) > 0)
if (nade.Secret and !hasammo and (!nade.SecretWeapon or !self:GetOwner():HasWeapon(nade.SecretWeapon))) or (nade.RequireStat and !self:GetValue(nade.RequireStat)) then
return false
end
if checkammo and !TacRP.IsGrenadeInfiniteAmmo(index) and !hasammo then
return false
end
return true
end
function SWEP:GetAvailableGrenades(checkammo)
local nades = {}
for i = 1, TacRP.QuickNades_Count do
if self:CheckGrenade(i, checkammo) then
table.insert(nades, self:GetGrenade(i))
end
end
return nades
end
if CLIENT then
SWEP.QuickNadeModel = nil
end
function SWEP:ThinkGrenade()
if !self:IsQuickNadeAllowed() then return end
if CLIENT then
if self:GetPrimedGrenade() and !IsValid(self.QuickNadeModel) and self:GetStartPrimedGrenadeTime() + 0.2 < CurTime() and self:GetGrenade().Model then
local nade = self:GetGrenade()
local vm = self:GetVM()
local model = ClientsideModel(nade.Model or "models/weapons/tacint/v_quicknade_frag.mdl")
if !IsValid(model) then return end
model:SetParent(vm)
model:AddEffects(EF_BONEMERGE)
model:SetNoDraw(true)
if nade.Material then
model:SetMaterial(nade.Material)
end
self.QuickNadeModel = model
local tbl = {
Model = model,
Weapon = self
}
table.insert(TacRP.CSModelPile, tbl)
elseif !self:GetPrimedGrenade() and self.QuickNadeModel then
SafeRemoveEntity(self.QuickNadeModel)
self.QuickNadeModel = nil
end
end
if self:GetOwner():KeyPressed(IN_GRENADE1) then
self:PrimeGrenade()
elseif !tobool(self:GetOwner():GetInfo("tacrp_nademenu")) and self:GetOwner():KeyPressed(self.GrenadeMenuKey) then
self:SelectGrenade()
elseif tobool(self:GetOwner():GetInfo("tacrp_nademenu")) and self.GrenadeMenuKey != IN_GRENADE2 and !self:GetOwner():KeyDown(self.GrenadeMenuKey) then
self.GrenadeMenuKey = IN_GRENADE2
end
if CLIENT and self.GrenadeWaitSelect and self:GetOwner():HasWeapon(self.GrenadeWaitSelect) then
input.SelectWeapon(self:GetOwner():GetWeapon(self.GrenadeWaitSelect))
self.GrenadeWaitSelect = nil
end
if self:GetPrimedGrenade() and self:GetAnimLockTime() < CurTime() then
self:ThrowGrenade()
self:SetPrimedGrenade(false)
end
end