• Making a Projectile Inflict Damage to a Player
    9 replies, posted
I'm looking to make a custom projectile created by a SWEP inflict damage on the player. I'm converting the Popcorn SWEP to TTT as a Detective weapon, but the problem here is that the projectiles fired by using right click don't actually do damage, and I'd like for them to. In addition, how can I slow down the rate of fire, and how can I make it use ammo (I have it set to use pistol ammo, and it picks it up, but doesn't actually use it and has infinite ammo)? I'm no lua coder, but I'm trying to get a grasp on it, so putting it as simply as you can would be beneficial in this case. Also, please excuse the gigantic post below since [spoiler] tags are apparently broken. Or maybe it's just Firefox. I don't know. - weapons\weapon_popcorn\shared.lua [code]SWEP.ViewModel = "models/Teh_Maestro/popcorn.mdl" SWEP.WorldModel = "models/Teh_Maestro/popcorn.mdl" SWEP.Spawnable = true SWEP.AdminSpawnable = false SWEP.Primary.Clipsize = 20 // Placeholder SWEP.Primary.DefaultClip = 20 // Placeholder SWEP.Secondary.ClipMax = 60 // Placeholder SWEP.Primary.Automatic = false SWEP.Primary.Ammo = "item_ammo_pistol_ttt" SWEP.Secondary.Clipsize = 20 // Placeholder SWEP.Secondary.DefaultClip = 20 // Placeholder SWEP.Secondary.ClipMax = 60 // Placeholder SWEP.Secondary.Automatic = false SWEP.Secondary.Ammo = "item_ammo_pistol_ttt" SWEP.HoldType = "shotgun" if CLIENT then SWEP.PrintName = "Popcorn" SWEP.Slot = 1 SWEP.ViewModelFlip = false SWEP.EquipMenuData = { type = "item_weapon", desc = [[Munch on popcorn while assulting your foes with it. (Left click to munch, right click to launch) Ported by Rhapsody.]] }; SWEP.Icon = "VGUI/ttt/icon_fire" // Placeholder end function SWEP:Deploy() end function SWEP:Think() if (self.Owner.ChewScale or 0) > 0 then if SERVER then if (CurTime() >= self.Owner.BiteStart+0.625 and self.Owner.BitesRem > 0) then self.Owner.BiteStart = CurTime() self.Owner.BitesRem = self.Owner.BitesRem - 1 net.Start("Popcorn_Eat") net.WriteEntity(self.Owner) net.WriteFloat(math.Round(math.Rand(4,8)+self.Owner.BitesRem*8)) net.Broadcast() end end self.Owner.ChewScale = math.Clamp((self.Owner.ChewStart+self.Owner.ChewDur - CurTime())/self.Owner.ChewDur,0,1) end end function SWEP:Initialize() util.PrecacheSound("crisps/eat.wav") end function SWEP:PrimaryAttack() if SERVER then self.Owner:EmitSound( "crisps/eat.wav", 60) self.Owner.BiteStart = 0 self.Owner.BitesRem = 3 net.Start("Popcorn_Eat_Start") net.WriteEntity(self.Owner) net.Broadcast() end self.Owner.ChewScale = 1 self.Owner.ChewStart = CurTime() self.Owner.ChewDur = SoundDuration("crisps/eat.wav") self.Weapon:SetNextPrimaryFire(CurTime() + 12 ) end function SWEP:SecondaryAttack() local bucket, att, phys, tr self.Weapon:SetNextSecondaryFire(CurTime() + 16) if (self.Owner:IsAdmin()) then self.Weapon:SetNextSecondaryFire(CurTime()) end if CLIENT then return end self.Owner:EmitSound( "weapons/slam/throw.wav" ) self.Owner:ViewPunch( Angle( math.Rand(-8,8), math.Rand(-8,8), 0 ) ) bucket = ents.Create( "sent_popcorn_thrown" ) bucket:SetOwner( self.Owner ) bucket:SetPos( self.Owner:GetShootPos( ) ) bucket:Spawn() bucket:Activate() phys = bucket:GetPhysicsObject( ) if IsValid( phys ) then phys:SetVelocity( self.Owner:GetPhysicsObject():GetVelocity() ) phys:AddVelocity( self.Owner:GetAimVector( ) * 128 * phys:GetMass( ) ) phys:AddAngleVelocity( VectorRand() * 128 * phys:GetMass( ) ) end --[[ if !self.Owner:IsAdmin() then self.Owner:StripWeapon("weapon_popcorn") end --]] end // TTT Conversion Code \\ SWEP.Base = "weapon_tttbase" SWEP.Kind = WEAPON_PISTOL SWEP.AutoSpawnable = true SWEP.AmmoEnt = "item_ammo_pistol_ttt" SWEP.InLoadoutFor = nil SWEP.AllowDrop = true SWEP.IsSilent = false SWEP.NoSights = false SWEP.CanBuy = {ROLE_DETECTIVE} // TTT Conversion Code \\ [/code] weapons\popcorn_thrown\init.lua [code]AddCSLuaFile ("cl_init.lua") AddCSLuaFile ("shared.lua") include ("shared.lua") SWEP.AutoSwitchTo = true SWEP.AutoSwitchFrom = true util.AddNetworkString("Popcorn_Eat") util.AddNetworkString("Popcorn_Eat_Start")[/code] weapons\weapon_popcorn\cl_init.lua [code]include('shared.lua') SWEP.PrintName = "Popcorn" SWEP.Slot = 1 SWEP.SlotPos = 1 SWEP.DrawAmmo = true SWEP.DrawCrosshair = false SWEP.WepSelectIcon = surface.GetTextureID( "vgui/entities/weapon_popcorn" ) function SWEP:GetViewModelPosition( pos , ang) pos,ang = LocalToWorld(Vector(20,-10,-15),Angle(0,0,0),pos,ang) return pos, ang end local function kernel_init(particle, vel) particle:SetColor(255,255,255,255) particle:SetVelocity( vel or VectorRand():GetNormalized() * 15) particle:SetGravity( Vector(0,0,-200) ) particle:SetLifeTime(0) particle:SetDieTime(math.Rand(5,10)) particle:SetStartSize(1) particle:SetEndSize(0) particle:SetStartAlpha(255) particle:SetEndAlpha(0) particle:SetCollide(true) particle:SetBounce(0.25) particle:SetRoll(math.pi*math.Rand(0,1)) particle:SetRollDelta(math.pi*math.Rand(-4,4)) end function SWEP:Initialize() end net.Receive("Popcorn_Eat",function () local ply = net.ReadEntity() local size = net.ReadFloat() local attachid = ply:LookupAttachment("eyes") local emitter = ParticleEmitter(ply:GetPos()) local angpos = ply:GetAttachment(attachid) local fwd local pos if (ply != LocalPlayer()) then fwd = (angpos.Ang:Forward()-angpos.Ang:Up()):GetNormalized() pos = angpos.Pos + fwd*3 else fwd = ply:GetAimVector():GetNormalized() pos = ply:GetShootPos() + gui.ScreenToVector( ScrW()/2, ScrH()/4*3 )*10 end for i = 1,size do if !ply then return end local particle = emitter:Add( "particle/popcorn-kernel", pos ) if particle then local dir = VectorRand():GetNormalized() kernel_init(particle, ((fwd)+dir):GetNormalized() * math.Rand(0,40)) end end emitter:Finish() end) net.Receive("Popcorn_Eat_Start",function () local ply = net.ReadEntity() ply.ChewScale = 1 ply.ChewStart = CurTime() ply.ChewDur = SoundDuration("crisps/eat.wav") end) function GAMEMODE:MouthMoveAnimation (ply) local FlexNum = ply:GetFlexNum() - 1 if ( FlexNum <= 0 ) then return end local chewing = false local weight if ((ply.ChewScale or 0) > 0) then local x = CurTime()-ply.ChewStart weight = 0.5*math.sin(x*(2*math.pi/0.625)-0.5*math.pi)+0.5 chewing = true end for i=0, FlexNum-1 do local Name = ply:GetFlexName( i ) if ( Name == "jaw_drop" || Name == "right_part" || Name == "left_part" || Name == "right_mouth_drop" || Name == "left_mouth_drop" ) then if ( ply:IsSpeaking() ) then ply:SetFlexWeight( i, math.Clamp( ply:VoiceVolume() * 2, 0, 2 ) ) elseif ((ply.ChewScale or 0) > 0) then ply.ChewScale = math.Clamp((ply.ChewStart+ply.ChewDur - CurTime())/ply.ChewDur,0,1) if (Name == "jaw_drop" ) then ply:SetFlexWeight( i, weight*(ply.ChewScale*2) ) else ply:SetFlexWeight( i, weight*((ply.ChewScale*2)-1.25) ) end else ply:SetFlexWeight( i, 0 ) end end end end[/code] entities\sent_popcorn_thrown\shared.lua [code]ENT.Base = "base_anim" ENT.Type = "anim" ENT.PrintName = "Thrown Popcorn" ENT.Model = Model( "models/Teh_Maestro/popcorn.mdl" )[/code] entities\sent_popcorn_thrown\init.lua [code]AddCSLuaFile( "cl_init.lua" ) AddCSLuaFile( "shared.lua" ) include( "shared.lua" ) util.AddNetworkString( "Popcorn_Explosion" ) function ENT:Initialize() self:SetModel( self.Model ) self:PhysicsInit( SOLID_VPHYSICS ) self:SetMoveType( MOVETYPE_VPHYSICS ) self:SetSolid( SOLID_VPHYSICS ) self:DrawShadow( true ) local phys = self:GetPhysicsObject() if IsValid( phys ) then phys:Wake() end timer.Simple(10, function () SafeRemoveEntity( self ) end) end local b
For Damage, you need to either add a takedamage method on the target under ENT:Touch or ENT:PhysicsCollide. For ammo, you need to use self.Owner:RemoveAmmo( <#of ammo you want to be consumed> , <ammo type, which should read "pistol" with quotes. > ) in your primary fire function of the SWEP. [editline]20th February 2014[/editline] It's a good idea to check if the player has ammo before throwing, though. [editline]20th February 2014[/editline] So put [code]if self.Owner:GetAmmoCount("pistol") < 1 then return end self.Owner:RemoveAmmo( 1, "pistol" )[/code] At the beginning of the Primary Attack function. What the first line does is if the ammo is less than one, it prevents anything below it in the function from ever happening. [editline]20th February 2014[/editline] You can also replace "pistol" with self.Primary.Ammo, without quotes. This makes it easier to change the type of ammo it used later on if you ever feel the need.
The SWEP uses it's secondary fire to shoot the projectiles, the primary fire triggers an animation.
Oh, then put the if then return end thing I gave you in the second one. [editline]20th February 2014[/editline] After you get that working I'll tell you about how to use physicscollide.
Can you tell me why we would be using physicscollide? The projectiles break when they hit a wall, but not when they hit a player, if that's it. Also, the code you gave me worked, it now fails to fire if the player has no pistol ammo. However, the SWEP doesn't account for reloads or clip size due to the fact that it doesn't properly handle ammo yet. Just mentioning. As I said, I'm no lua coder, so I have no idea what physicscollide actually is, nor how to code a takedamage method on a target.
Wait you need reloads?
I can send you the SWEP if you accept my friend request on Steam so you can see what's currently there, and what's not. Currently, I need reloads and working ammo, since the gun [i]does[/i] account for ammo, but not for clip size. I also need it to actually do damage.
What is your steam name, I have ~ 70 friend requests atm
It's Rhapsody.
Following up, I've worked with BFG9000 via Steam, and we've hit a roadblock that neither of us knows how to solve. With the following code, we run into two errors that are directly related to each other. The first is that, when I attempt to buy it from the Detective menu, I get the following error; [code]Player [1][Rhapsody]tried to buy weapon his role is not permitted to buy[/code] When I pick up the weapon on the map or use the console command 'give weapon_popcorn', (at the time I tested I didn't have SWEP.AutoSpawnable added, so it spawned on the map. This is fixed.), this happens; [code]Equipped weapon weapon_popcorn is not compatible with TTT[/code] The SWEP code is the following; [code]SWEP.ViewModel = "models/Teh_Maestro/popcorn.mdl" SWEP.WorldModel = "models/Teh_Maestro/popcorn.mdl" SWEP.Spawnable = true SWEP.AdminSpawnable = false SWEP.AutoSpawnable = false SWEP.Primary.Clipsize = 20 // Placeholder SWEP.Primary.DefaultClip = 20 // Placeholder SWEP.Secondary.ClipMax = 60 // Placeholder SWEP.Primary.Automatic = false SWEP.Primary.Ammo = "item_ammo_pistol_ttt" SWEP.Secondary.Clipsize = 20 // Placeholder SWEP.Secondary.DefaultClip = 20 // Placeholder SWEP.Secondary.ClipMax = 60 // Placeholder SWEP.Secondary.Automatic = false SWEP.Secondary.Ammo = "item_ammo_pistol_ttt" SWEP.HoldType = "slam" if CLIENT then SWEP.PrintName = "Popcorn" SWEP.Slot = 1 SWEP.ViewModelFlip = false // This would normally be set to true, but this viewmodel is different SWEP.EquipMenuData = { type = "item_weapon", desc = [[Munch on popcorn while assulting your foes with it. (Left click to munch, right click to launch) Ported by Rhapsody.]] }; SWEP.Icon = "VGUI/ttt/icon_fire" // Placeholder end function SWEP:Deploy() end function SWEP:Think() if (self.Owner.ChewScale or 0) > 0 then if SERVER then if (CurTime() >= self.Owner.BiteStart+0.625 and self.Owner.BitesRem > 0) then self.Owner.BiteStart = CurTime() self.Owner.BitesRem = self.Owner.BitesRem - 1 net.Start("Popcorn_Eat") net.WriteEntity(self.Owner) net.WriteFloat(math.Round(math.Rand(4,8)+self.Owner.BitesRem*8)) net.Broadcast() end end self.Owner.ChewScale = math.Clamp((self.Owner.ChewStart+self.Owner.ChewDur - CurTime())/self.Owner.ChewDur,0,1) end end function SWEP:Initialize() util.PrecacheSound("crisps/eat.wav") end function SWEP:PrimaryAttack() if SERVER then self.Owner:EmitSound( "crisps/eat.wav", 60) self.Owner.BiteStart = 0 self.Owner.BitesRem = 3 net.Start("Popcorn_Eat_Start") net.WriteEntity(self.Owner) net.Broadcast() end self.Owner.ChewScale = 1 self.Owner.ChewStart = CurTime() self.Owner.ChewDur = SoundDuration("crisps/eat.wav") self.Weapon:SetNextPrimaryFire(CurTime() + 12 ) end function SWEP:SecondaryAttack() local bucket, att, phys, tr self.Weapon:SetNextSecondaryFire(CurTime() + 16) // Below code subtracts 1 pistol ammo from player's //clip unless less than 1 exists, in which case it doesn't fire if self.Owner:GetAmmoCount("pistol") < 1 then return end self.Owner:RemoveAmmo( 1, "pistol" ) if CLIENT then return end self.Owner:EmitSound( "weapons/slam/throw.wav" ) self.Owner:ViewPunch( Angle( math.Rand(-8,8), math.Rand(-8,8), 0 ) ) bucket = ents.Create( "sent_popcorn_thrown" ) bucket:SetOwner( self.Owner ) bucket:SetPos( self.Owner:GetShootPos( ) ) bucket:Spawn() bucket:Activate() phys = bucket:GetPhysicsObject( ) if IsValid( phys ) then phys:SetVelocity( self.Owner:GetPhysicsObject():GetVelocity() ) phys:AddVelocity( self.Owner:GetAimVector( ) * 128 * phys:GetMass( ) ) phys:AddAngleVelocity( VectorRand() * 128 * phys:GetMass( ) ) end --[[ if !self.Owner:IsAdmin() then self.Owner:StripWeapon("weapon_popcorn") end --]] end // Now it's time to make the weapon compatible with TTT... SWEP.Base = "weapon_tttbase" SWEP.Kind = WEAPON_PISTOL SWEP.AutoSpawnable = true SWEP.AmmoEnt = "item_ammo_pistol_ttt" SWEP.InLoadoutFor = nil SWEP.AllowDrop = true SWEP.IsSilent = false SWEP.NoSights = false SWEP.CanBuy = {ROLE_DETECTIVE}[/code]
Sorry, you need to Log In to post a reply to this thread.