mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 21:53:46 +03:00
Upload
This commit is contained in:
216
gamemodes/terrortown/entities/weapons/weapon_ttt_flaregun.lua
Normal file
216
gamemodes/terrortown/entities/weapons/weapon_ttt_flaregun.lua
Normal file
@@ -0,0 +1,216 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
SWEP.HoldType = "pistol"
|
||||
|
||||
if CLIENT then
|
||||
SWEP.PrintName = "flare_name"
|
||||
SWEP.Slot = 6
|
||||
|
||||
SWEP.ViewModelFOV = 54
|
||||
SWEP.ViewModelFlip = false
|
||||
|
||||
SWEP.EquipMenuData = {
|
||||
type = "item_weapon",
|
||||
desc = "flare_desc"
|
||||
};
|
||||
|
||||
SWEP.Icon = "vgui/ttt/icon_flare"
|
||||
end
|
||||
|
||||
SWEP.Base = "weapon_tttbase"
|
||||
|
||||
-- if I run out of ammo types, this weapon is one I could move to a custom ammo
|
||||
-- handling strategy, because you never need to pick up ammo for it
|
||||
SWEP.Primary.Ammo = "AR2AltFire"
|
||||
SWEP.Primary.Recoil = 4
|
||||
SWEP.Primary.Damage = 7
|
||||
SWEP.Primary.Delay = 1.0
|
||||
SWEP.Primary.Cone = 0.01
|
||||
SWEP.Primary.ClipSize = 4
|
||||
SWEP.Primary.Automatic = false
|
||||
SWEP.Primary.DefaultClip = 4
|
||||
SWEP.Primary.ClipMax = 4
|
||||
SWEP.Primary.Sound = Sound( "Weapon_USP.SilencedShot" )
|
||||
|
||||
SWEP.Kind = WEAPON_EQUIP
|
||||
SWEP.CanBuy = {ROLE_TRAITOR} -- only traitors can buy
|
||||
SWEP.LimitedStock = true -- only buyable once
|
||||
SWEP.WeaponID = AMMO_FLARE
|
||||
|
||||
SWEP.Tracer = "AR2Tracer"
|
||||
|
||||
SWEP.UseHands = true
|
||||
SWEP.ViewModel = Model("models/weapons/c_357.mdl")
|
||||
SWEP.WorldModel = Model("models/weapons/w_357.mdl")
|
||||
|
||||
local function RunIgniteTimer(ent, timer_name)
|
||||
if IsValid(ent) and ent:IsOnFire() then
|
||||
if ent:WaterLevel() > 0 then
|
||||
ent:Extinguish()
|
||||
elseif CurTime() > ent.burn_destroy then
|
||||
ent:SetNotSolid(true)
|
||||
ent:Remove()
|
||||
else
|
||||
-- keep on burning
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
timer.Remove(timer_name) -- stop running timer
|
||||
end
|
||||
|
||||
local SendScorches
|
||||
|
||||
if CLIENT then
|
||||
local function ReceiveScorches()
|
||||
local ent = net.ReadEntity()
|
||||
local num = net.ReadUInt(8)
|
||||
for i=1, num do
|
||||
util.PaintDown(net.ReadVector(), "FadingScorch", ent)
|
||||
end
|
||||
|
||||
if IsValid(ent) then
|
||||
util.PaintDown(ent:LocalToWorld(ent:OBBCenter()), "Scorch", ent)
|
||||
end
|
||||
end
|
||||
net.Receive("TTT_FlareScorch", ReceiveScorches)
|
||||
else
|
||||
-- it's sad that decals are so unreliable when drawn serverside, failing to
|
||||
-- draw more often than they work, that I have to do this
|
||||
SendScorches = function(ent, tbl)
|
||||
net.Start("TTT_FlareScorch")
|
||||
net.WriteEntity(ent)
|
||||
net.WriteUInt(#tbl, 8)
|
||||
for _, p in ipairs(tbl) do
|
||||
net.WriteVector(p)
|
||||
end
|
||||
net.Broadcast()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
local function ScorchUnderRagdoll(ent)
|
||||
if SERVER then
|
||||
local postbl = {}
|
||||
-- small scorches under limbs
|
||||
for i=0, ent:GetPhysicsObjectCount()-1 do
|
||||
local subphys = ent:GetPhysicsObjectNum(i)
|
||||
if IsValid(subphys) then
|
||||
local pos = subphys:GetPos()
|
||||
util.PaintDown(pos, "FadingScorch", ent)
|
||||
|
||||
table.insert(postbl, pos)
|
||||
end
|
||||
end
|
||||
|
||||
SendScorches(ent, postbl)
|
||||
end
|
||||
|
||||
-- big scorch at center
|
||||
local mid = ent:LocalToWorld(ent:OBBCenter())
|
||||
mid.z = mid.z + 25
|
||||
util.PaintDown(mid, "Scorch", ent)
|
||||
end
|
||||
|
||||
|
||||
function IgniteTarget(att, path, dmginfo)
|
||||
local ent = path.Entity
|
||||
if not IsValid(ent) then return end
|
||||
|
||||
if CLIENT and IsFirstTimePredicted() then
|
||||
if ent:GetClass() == "prop_ragdoll" then
|
||||
ScorchUnderRagdoll(ent)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if SERVER then
|
||||
|
||||
local dur = ent:IsPlayer() and 5 or 10
|
||||
|
||||
-- disallow if prep or post round
|
||||
if ent:IsPlayer() and (not GAMEMODE:AllowPVP()) then return end
|
||||
|
||||
ent:Ignite(dur, 100)
|
||||
|
||||
ent.ignite_info = {att=dmginfo:GetAttacker(), infl=dmginfo:GetInflictor()}
|
||||
|
||||
if ent:IsPlayer() then
|
||||
timer.Simple(dur + 0.1, function()
|
||||
if IsValid(ent) then
|
||||
ent.ignite_info = nil
|
||||
end
|
||||
end)
|
||||
|
||||
elseif ent:GetClass() == "prop_ragdoll" then
|
||||
ScorchUnderRagdoll(ent)
|
||||
|
||||
local burn_time = 6
|
||||
local tname = Format("ragburn_%d_%d", ent:EntIndex(), math.ceil(CurTime()))
|
||||
|
||||
ent.burn_destroy = CurTime() + burn_time
|
||||
|
||||
timer.Create(tname,
|
||||
0.1,
|
||||
math.ceil(1 + burn_time / 0.1), -- upper limit, failsafe
|
||||
function()
|
||||
RunIgniteTimer(ent, tname)
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:ShootFlare()
|
||||
local cone = self.Primary.Cone
|
||||
local bullet = {}
|
||||
bullet.Num = 1
|
||||
bullet.Src = self:GetOwner():GetShootPos()
|
||||
bullet.Dir = self:GetOwner():GetAimVector()
|
||||
bullet.Spread = Vector( cone, cone, 0 )
|
||||
bullet.Tracer = 1
|
||||
bullet.Force = 2
|
||||
bullet.Damage = self.Primary.Damage
|
||||
bullet.TracerName = self.Tracer
|
||||
bullet.Callback = IgniteTarget
|
||||
|
||||
self:GetOwner():FireBullets( bullet )
|
||||
end
|
||||
|
||||
function SWEP:PrimaryAttack()
|
||||
self:SetNextPrimaryFire( CurTime() + self.Primary.Delay )
|
||||
|
||||
if not self:CanPrimaryAttack() then return end
|
||||
|
||||
self:EmitSound( self.Primary.Sound )
|
||||
|
||||
self:SendWeaponAnim( ACT_VM_PRIMARYATTACK )
|
||||
|
||||
self:ShootFlare()
|
||||
|
||||
self:TakePrimaryAmmo( 1 )
|
||||
|
||||
if IsValid(self:GetOwner()) then
|
||||
self:GetOwner():SetAnimation( PLAYER_ATTACK1 )
|
||||
|
||||
self:GetOwner():ViewPunch( Angle( math.Rand(-0.2,-0.1) * self.Primary.Recoil, math.Rand(-0.1,0.1) *self.Primary.Recoil, 0 ) )
|
||||
end
|
||||
|
||||
if ( (game.SinglePlayer() && SERVER) || CLIENT ) then
|
||||
self:SetNWFloat( "LastShootTime", CurTime() )
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:SecondaryAttack()
|
||||
end
|
||||
Reference in New Issue
Block a user