Make Flare gun spawn Cadavers

Is there a simple way to make the ttt traitor flaregun spawn the burned cadaver ragdoll that comes with Gmod instead of just making a chared patch? Would it be hard to make it spawn in the same position as the player ragdoll?




if SERVER then
   AddCSLuaFile( "shared.lua" )
end

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"
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.Kind = WEAPON_EQUIP
SWEP.CanBuy = {ROLE_TRAITOR} -- only traitors can buy
SWEP.LimitedStock = true -- only buyable once
SWEP.WeaponID = AMMO_FLARE

-- 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.UseHands			= true
SWEP.ViewModel	= Model("models/weapons/c_357.mdl")
SWEP.WorldModel	= Model("models/weapons/w_357.mdl")

SWEP.Primary.Sound = Sound( "Weapon_USP.SilencedShot" )

SWEP.Tracer = "AR2Tracer"

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.Destroy(timer_name) -- stop running timer
end

local SendScorches

if CLIENT then
   local function ReceiveScorches(um)
      local ent = um:ReadEntity()
      local num = um:ReadChar()
      for i=1, num do
         util.PaintDown(um:ReadVector(), "FadingScorch", ent)
      end

      if IsValid(ent) then
         util.PaintDown(ent:LocalToWorld(ent:OBBCenter()), "Scorch", ent)
      end
   end
   usermessage.Hook("flare_scorch", 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)
      umsg.Start("flare_scorch")
      umsg.Entity(ent)
      umsg.Char(#tbl)
      for _, p in pairs(tbl) do
         umsg.Vector(p)
      end
      umsg.End()
   end
   usermessage.Hook("flare_scorch") -- pools it
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.Owner:GetShootPos()
   bullet.Dir       = self.Owner: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.Owner:FireBullets( bullet )
end

function SWEP:PrimaryAttack()
   self.Weapon:SetNextPrimaryFire( CurTime() + self.Primary.Delay )

   if not self:CanPrimaryAttack() then return end

   self.Weapon:EmitSound( self.Primary.Sound )

   self.Weapon:SendWeaponAnim( ACT_VM_PRIMARYATTACK )

   self:ShootFlare()

   self:TakePrimaryAmmo( 1 )

   if IsValid(self.Owner) then
      self.Owner:SetAnimation( PLAYER_ATTACK1 )

      self.Owner: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.Weapon:SetNetworkedFloat( "LastShootTime", CurTime() )
   end
end

function SWEP:SecondaryAttack()
end


Here’s what I did, replicating bones as well:

from line 52, overwriting the RunIgniteTimer function:

[LUA]
local function ReplicateBones( victim, ragObj )

--Loop through each bone
local numberOfBones = ragObj:GetPhysicsObjectCount()
for i = 1, numberOfBones - 1 do
	
	local ragBone = ragObj:GetPhysicsObjectNum( i )	--Get the current bone
	
	if IsValid( ragBone ) then	
		
		local vicBonePos, vicBoneAng = victim:GetBonePosition( ragObj:TranslatePhysBoneToBone( i ) )  --get the position of the bone on the player
			
		ragBone:SetPos( vicBonePos) --set the ragdoll bone position to the player bone position
		ragBone:SetAngles( vicBoneAng )
		
		ragBone:SetVelocity( ragObj:GetVelocity() )
		
	end
	
end

end

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
local burnt = ents.Create( “prop_ragdoll” )
burnt:SetModel( “models/Humans/Charple01.mdl” )
burnt:SetPos( ent:GetPos() )
burnt:Spawn()
burnt:SetCollisionGroup( COLLISION_GROUP_INTERACTIVE_DEBRIS )
ReplicateBones( ent, burnt )
ent:SetNotSolid(true)
ent:Remove()
else
– keep on burning
return
end
end

timer.Destroy(timer_name) – stop running timer
end
[/LUA]

Wow, this is amazing!