Help with lua coding

I’m trying to make a watermelon bomb that works just like a frag grenade but I’m having trouble coding the explosion. Here is what I have (for the primary attack part):


function SWEP:PrimaryAttack()
	//Call the throw attack function, with the watermelon model
	self:throw_attack("models/props_junk/watermelon01.mdl")

	local entpos = ent.GetPos();
	local explode = ents.Create("env_explosion")
	explode:SetPos(entpos)
	explode:SetOwner(self.Owner)
	explode:Spawn()
	explode:SetKeyValue("iMagnitude", "220")
	explode:Fire("Explode", 0, 0)
	explode:EmitSound("BaseGrenade.Explode", 400, 400)
	timer.Create("timer1", 2.5, 1, ents.Create("env_explosion"))
end

I have a feeling that my problem has to do with finding the physics prop (watermelon) to create the explosion there, but I can’t fix the problem myself.

Having the timer run ents.Create won’t create that “explode” entity you defined earlier. You’d either have to either run the :Spawn() in the timer or just have the entire thing create within your timer.


timer.Simple(2.5, function()
	local explode = ents.Create("env_explosion")
	explode:SetPos(entpos)
	explode:SetOwner(self.Owner)
	explode:Spawn()
	explode:SetKeyValue("iMagnitude", "220")
	explode:Fire("Explode", 0, 0)
	explode:EmitSound("BaseGrenade.Explode", 400, 400)
end)

What’s the code from your SWEP:throw_attack function? running ent.GetPos() without defining your “ent” won’t return anything, so tying the explosion to the melon location is also an issue.

Also ents.Create is a server function. If you’re testing it out in singleplayer, it’ll probably work fine but it’ll give you some errors if you try to run it on a multiplayer server. Wrapping the timer in a


if SERVER then
end

should fix any issues from that.

The SWEP:throw_attack and Primaryattack now look like this.


function SWEP:throw_attack (model_file)

	local tr = self.Owner:GetEyeTrace()
 
	self:EmitSound(ShootSound)
	self.BaseClass.ShootEffects(self)
 
	if (!SERVER) then return end
 
	local ent = ents.Create("prop_physics")
	ent:SetModel(model_file)
 
	ent:SetPos(self.Owner:EyePos() + (self.Owner:GetAimVector() * 16))
	ent:SetAngles(self.Owner:EyeAngles())
	ent:Spawn()
 
	local phys = ent:GetPhysicsObject()
 
	if !(phys && IsValid(phys)) then ent:Remove() return end
 
	phys:ApplyForceCenter(self.Owner:GetAimVector():GetNormalized() *  math.pow(tr.HitPos:Length(), 1.75))
 
	cleanup.Add(self.Owner, "props", ent)
 
	undo.Create ("Thrown_SWEP_Entity")
		undo.AddEntity (ent)
		undo.SetPlayer (self.Owner)
	undo.Finish()
end

//Throw a watermelon on primary attack
function SWEP:PrimaryAttack()
	//Call the throw attack function, with the watermelon model
	self:throw_attack("models/props_junk/watermelon01.mdl")

	local entpos = ent.GetPos()
	local explode = ents.Create("env_explosion")
	explode:SetPos(entpos)
	explode:SetOwner(self.Owner)
	explode:Spawn()
	explode:SetKeyValue("iMagnitude", "220")
	explode:Fire("Explode", 0, 0)
	explode:EmitSound("BaseGrenade.Explode", 400, 400)
	
	if SERVER then
		timer.Simple(2.5, function()
		local explode = ents.Create("env_explosion")
		explode:SetPos(entpos)
		explode:SetOwner(self.Owner)
		explode:Spawn()
		explode:SetKeyValue("iMagnitude", "220")
		explode:Fire("Explode", 0, 0)
		explode:EmitSound("BaseGrenade.Explode", 400, 400)
		end)
	end
end

I am still having a problem with the explosion and I have a feeling you were right about not defining my “ent”. I defined “ent” in the throw_attack part, but not Primaryattack, and I’m not sure what the best way of fixing that is. Also, I know the formula for adding force seems weird, but I can fix that later.

I think the easiest fix would be to just move the code from your primary fire to your custom function, or vice-versa. Try giving this a try.


function SWEP:throw_attack(model_file)

    local tr = self.Owner:GetEyeTrace()
 
    self:EmitSound(ShootSound)
    self.BaseClass.ShootEffects(self)
 
    if (!SERVER) then return end
 
    local ent = ents.Create("prop_physics")
    ent:SetModel(model_file)
 
    ent:SetPos(self.Owner:EyePos() + (self.Owner:GetAimVector() * 16))
    ent:SetAngles(self.Owner:EyeAngles())
    ent:Spawn()
 
    local phys = ent:GetPhysicsObject()
 
    if !(phys && IsValid(phys)) then ent:Remove() return end
 
    phys:ApplyForceCenter(self.Owner:GetAimVector():GetNormalized() *  math.pow(tr.HitPos:Length(), 1.75))
 
    cleanup.Add(self.Owner, "props", ent)
 
    undo.Create ("Thrown_SWEP_Entity")
        undo.AddEntity (ent)
        undo.SetPlayer (self.Owner)
    undo.Finish()
    
    local entpos = ent:GetPos()
    
    timer.Simple(2.5, function()
        if !ent:IsValid() then return end --fail safe in case melon was undone before it blew up.
        local explode = ents.Create("env_explosion")
        explode:SetPos(entpos)
        explode:SetOwner(self.Owner)
        explode:Spawn()
        explode:SetKeyValue("iMagnitude", "220")
        explode:Fire("Explode", 0, 0)
        explode:EmitSound("BaseGrenade.Explode", 400, 400)
        ent:Remove() --cleanup that old melon after it blows.
    end)
end

//Throw a watermelon on primary attack
function SWEP:PrimaryAttack()
    //Call the throw attack function, with the watermelon model
    self:throw_attack("models/props_junk/watermelon01.mdl")
end

Also sorry for the late reply. I meant to sent this hours ago, but my net died as I hit send and wound up just going to bed after.

It’s still not working and I tried moving some things around, but still no progress. I now have exactly what you have above.
And don’t worry about the late reply, I’m just glad someone is actually trying to help me.

I tried to get it working myself. Melons wouldn’t explode if they broke on impact, and the explosion location was off because I had it call ent:GetPos() outside of the timer.

Giving the melons extra health and having it just call the melon position inside the timer fixed that though.

This is the full code I have, and it works fine now.


if CLIENT then
	SWEP.Slot = 1
	SWEP.SlotPos = 2
	SWEP.DrawAmmo = false
	SWEP.DrawCrosshair = false
	SWEP.PrintName = "MelonGun"
	SWEP.Instructions = ""
end

SWEP.Spawnable = false
SWEP.AdminOnly = false

SWEP.Primary.ClipSize = -1
SWEP.Primary.DefaultClip = -1
SWEP.Primary.Automatic = false
SWEP.Primary.Ammo = ""

SWEP.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = -1
SWEP.Secondary.Automatic = true
SWEP.Secondary.Ammo = ""

SWEP.ViewModel = "models/weapons/v_pistol.mdl"
SWEP.WorldModel = "models/weapons/w_pistol.mdl"

function SWEP:Think()
end

function SWEP:throw_attack(model_file)

    local tr = self.Owner:GetEyeTrace()
	
    self.BaseClass.ShootEffects(self)
 
    if (!SERVER) then return end
 
    local ent = ents.Create("prop_physics")
    ent:SetModel(model_file)
 
    ent:SetPos(self.Owner:EyePos() + (self.Owner:GetAimVector() * 16))
    ent:SetAngles(self.Owner:EyeAngles())
    ent:Spawn()
	ent:SetHealth(1000)
 
    local phys = ent:GetPhysicsObject()
 
    if !(phys && IsValid(phys)) then ent:Remove() return end
 
    phys:ApplyForceCenter(self.Owner:GetAimVector():GetNormalized() *  math.pow(tr.HitPos:Length(), 1.75))
 
    cleanup.Add(self.Owner, "props", ent)
 
    undo.Create ("Thrown_SWEP_Entity")
        undo.AddEntity (ent)
        undo.SetPlayer (self.Owner)
    undo.Finish()
    
    timer.Simple(2.5, function()
        if !ent:IsValid() then return end --fail safe in case melon was undone before it blew up.
        local explode = ents.Create("env_explosion")
        explode:SetPos(ent:GetPos())
        explode:SetOwner(self.Owner)
        explode:Spawn()
        explode:SetKeyValue("iMagnitude", "220")
        explode:Fire("Explode", 0, 0)
        explode:EmitSound("BaseGrenade.Explode", 400, 400)
        ent:Remove() --cleanup that old melon after it blows.
    end)
end

//Throw a watermelon on primary attack
function SWEP:PrimaryAttack()
    //Call the throw attack function, with the watermelon model
    self:throw_attack("models/props_junk/watermelon01.mdl")
end


I just have one more problem. If the player who threw the melon dies before it explodes, how can I make sure it still explodes. Usually when the player dies, it says there is a script error and the timer stops so it doesn’t explode or remove itself.

[editline]26th July 2015[/editline]

Also how can I make it so if it takes explosive damage, it immediately explodes.