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.