Jump to content

[Help] Prefab file - explosion


Recommended Posts

Hi, I have been working on RGD-33 grenade. I have used Napsack prefab as my template and it has no error screen so far but when I throw it it won't do any damage. I don't get all those explosive functions so if anyone here could help me I will be happier person.

 

Prefab here:

local assets=
{ 
    Asset("ANIM", "anim/rgd3_nade.zip"),
    Asset("ANIM", "anim/swap_rgd3_nade.zip"), 

    Asset("ATLAS", "images/inventoryimages/rgd3_nade.xml"),
    Asset("IMAGE", "images/inventoryimages/rgd3_nade.tex"),
}

local prefabs = 
{
}


local function OnEquip(inst, owner)
	owner.AnimState:OverrideSymbol("swap_object", "swap_rgd3_nade", "rgd3")
	owner.AnimState:Show("ARM_carry")
	owner.AnimState:Hide("ARM_normal")
end

local function OnUnequip(inst, owner)
	owner.AnimState:Hide("ARM_carry")
	owner.AnimState:Show("ARM_normal")
end
    
-----------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
	

local function OnExplodeFn(inst)
  --nothing works
  SpawnPrefab("explode_small").Transform:SetPosition(x, y, z)
  
end

local function OnHit(inst, attacker, target)
    local x, y, z = inst.Transform:GetWorldPosition()
    inst:Remove()
    SpawnPrefab("explode_small").Transform:SetPosition(x, y, z)  			
end


local function OnThrown(inst)
    inst:AddTag("NOCLICK")
    inst.persists = false

    inst.AnimState:PlayAnimation("spin")

    inst.Physics:SetMass(1)
    inst.Physics:SetCapsule(0.2, 0.2)
    inst.Physics:SetFriction(0)
    inst.Physics:SetDamping(0)
    inst.Physics:SetCollisionGroup(COLLISION.CHARACTERS)
    inst.Physics:ClearCollisionMask()
    inst.Physics:CollidesWith(COLLISION.WORLD)
    inst.Physics:CollidesWith(COLLISION.OBSTACLES)
    inst.Physics:CollidesWith(COLLISION.ITEMS)
end


local function ReticuleTargetFn()
    local player = ThePlayer
    local ground = TheWorld.Map
    local pos = Vector3()
    --Attack range is 8, leave room for error
    --Min range was chosen to not hit yourself (2 is the hit range)
    for r = 6.5, 3.5, -.25 do
        pos.x, pos.y, pos.z = player.entity:LocalToWorldSpace(r, 0, 0)
        if ground:IsPassableAtPoint(pos:Get()) and not ground:IsGroundTargetBlocked(pos) then
            return pos
        end
    end
    return pos
end

----------------------------------------------------
----------------------------------------------------
----------------------------------------------------

local function fn(Sim)
	local inst = CreateEntity()
	inst.entity:AddTransform()
	inst.entity:AddAnimState()
	inst.entity:AddNetwork()
	inst.entity:AddSoundEmitter()
	
	MakeInventoryPhysics(inst)
	
	inst:AddTag("projectile")
	inst:AddTag("explosive")
	
	inst.AnimState:SetBank("rgd3")
	inst.AnimState:SetBuild("rgd3_nade")
	inst.AnimState:PlayAnimation("idle")
	
	if not TheWorld.ismastersim then
		return inst
	end
	
	inst.entity:SetPristine()
	
	inst:AddComponent("locomotor")
	
    inst:AddComponent("reticule")
    inst.components.reticule.targetfn = ReticuleTargetFn
    inst.components.reticule.ease = true
	
	local advancedtargeting = TheNet:GetServerGameMode() == "lavaarena"
    if advancedtargeting then
        inst.components.reticule.reticuleprefab = "reticuleaoe"
        inst.components.reticule.pingprefab = "reticuleaoeping"
        inst.components.reticule.mouseenabled = true

        inst:AddTag("nopunch")
    end
	
	inst:AddComponent("inventoryitem")
	inst.components.inventoryitem.imagename = "rgd3_nade"
	inst.components.inventoryitem.atlasname = "images/inventoryimages/rgd3_nade.xml"
	
	inst:AddComponent("inspectable")
	inst:AddComponent("equippable")
	
	MakeHauntableLaunch(inst)
	
	inst.components.equippable:SetOnEquip( OnEquip )
	inst.components.equippable:SetOnUnequip( OnUnequip )
	
	inst:AddComponent("complexprojectile")
    inst.components.complexprojectile:SetHorizontalSpeed(15)
    inst.components.complexprojectile:SetGravity(-35)
    inst.components.complexprojectile:SetLaunchOffset(Vector3(.25, 1, 0))
    inst.components.complexprojectile:SetOnLaunch(OnThrown)
    inst.components.complexprojectile:SetOnHit(OnHit)
	
	if not advancedtargeting then
        inst:AddComponent("weapon")
        inst.components.weapon:SetDamage(0)
        inst.components.weapon:SetRange(8, 10)
    end

	
	inst:AddComponent("explosive")
    inst.components.explosive:SetOnExplodeFn(OnExplodeFn)
    inst.components.explosive.explosivedamage = TUNING.GUNPOWDER_DAMAGE
    inst.components.explosive.explosiverange = 3
	
	return inst
end

return Prefab("common/inventory/rgd3_nade", fn, assets, prefabs)

 

Link to comment
Share on other sites

This problem is solved. I had to study wisdom of gunpowder (prefab) and explosive (component). Feel free to use it in your throwable explosive items.

Quote

local assets=
{
    Asset("ANIM", "anim/rgd3_nade.zip"),
    Asset("ANIM", "anim/swap_rgd3_nade.zip"),

    Asset("ATLAS", "images/inventoryimages/rgd3_nade.xml"),
    Asset("IMAGE", "images/inventoryimages/rgd3_nade.tex"),
}

local prefabs =
{
}
----------------------------------
local function Explosion(self)
    local explosiverange = 3
    local stacksize = self.inst.components.stackable ~= nil and self.inst.components.stackable:StackSize() or 1
    local totaldamage = self.explosivedamage * stacksize

    local x, y, z = self.inst.Transform:GetWorldPosition()
    local ents = TheSim:FindEntities(x, y, z, self.explosiverange, nil, { "INLIMBO" })

    for i, v in ipairs(ents) do
        if v ~= self.inst and v:IsValid() and not v:IsInLimbo() then
            if v.components.workable ~= nil and v.components.workable:CanBeWorked() then
                v.components.workable:WorkedBy(self.inst, self.buildingdamage)
            end

      --------------   This made structures burn so I had to turn it off   
---            if v:IsValid() and not v:IsInLimbo() then
 ---               if self.lightonexplode and
 ---                   v.components.fueled == nil and
 ---                   v.components.burnable ~= nil and
 ---                   not v.components.burnable:IsBurning() and
 ---                   not v:HasTag("burnt") then
  ---                  v.components.burnable:Ignite()
   ---             end

                if v.components.combat ~= nil and not (v.components.health ~= nil and v.components.health:IsDead()) then
                    local dmg = totaldamage
                    if v.components.explosiveresist ~= nil then
                        dmg = dmg * (1 - v.components.explosiveresist:GetResistance())
                        v.components.explosiveresist:OnExplosiveDamage(dmg, self.inst)
                    end
                    v.components.combat:GetAttacked(self.inst, dmg, nil)
                end

                v:PushEvent("explosion", { explosive = self.inst })
            end
        end
    end

-----------------------------------------------

local function OnEquip(inst, owner)
    owner.AnimState:OverrideSymbol("swap_object", "swap_rgd3_nade", "rgd3")
    owner.AnimState:Show("ARM_carry")
    owner.AnimState:Hide("ARM_normal")
end

local function OnUnequip(inst, owner)
    owner.AnimState:Hide("ARM_carry")
    owner.AnimState:Show("ARM_normal")
end
    
-----------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
    

local function OnExplodeFn(inst)  
  SpawnPrefab("explode_small").Transform:SetPosition(x, y, z)
  Explosion(inst.components.explosive)  
end

local function OnHit(inst, attacker, target)
    local x, y, z = inst.Transform:GetWorldPosition()
    inst:Remove()
    SpawnPrefab("explode_small").Transform:SetPosition(x, y, z)
    Explosion(inst.components.explosive)  
end


local function OnThrown(inst)
    inst:AddTag("NOCLICK")
    inst.persists = false

    inst.AnimState:PlayAnimation("spin")

    inst.Physics:SetMass(1)
    inst.Physics:SetCapsule(0.2, 0.2)
    inst.Physics:SetFriction(0)
    inst.Physics:SetDamping(0)
    inst.Physics:SetCollisionGroup(COLLISION.CHARACTERS)
    inst.Physics:ClearCollisionMask()
    inst.Physics:CollidesWith(COLLISION.WORLD)
    inst.Physics:CollidesWith(COLLISION.OBSTACLES)
    inst.Physics:CollidesWith(COLLISION.ITEMS)
end


local function ReticuleTargetFn()
    local player = ThePlayer
    local ground = TheWorld.Map
    local pos = Vector3()
    --Attack range is 8, leave room for error
    --Min range was chosen to not hit yourself (2 is the hit range)
    for r = 6.5, 3.5, -.25 do
        pos.x, pos.y, pos.z = player.entity:LocalToWorldSpace(r, 0, 0)
        if ground:IsPassableAtPoint(pos:Get()) and not ground:IsGroundTargetBlocked(pos) then
            return pos
        end
    end
    return pos
end

----------------------------------------------------
----------------------------------------------------
----------------------------------------------------

local function fn(Sim)
    local inst = CreateEntity()
    inst.entity:AddTransform()
    inst.entity:AddAnimState()
    inst.entity:AddNetwork()
    inst.entity:AddSoundEmitter()
    
    MakeInventoryPhysics(inst)
    
    inst:AddTag("projectile")
    inst:AddTag("explosive")
    
    inst.AnimState:SetBank("rgd3")
    inst.AnimState:SetBuild("rgd3_nade")
    inst.AnimState:PlayAnimation("idle")
    
    if not TheWorld.ismastersim then
        return inst
    end
    
    inst.entity:SetPristine()
    
    inst:AddComponent("locomotor")
    
    inst:AddComponent("reticule")
    inst.components.reticule.targetfn = ReticuleTargetFn
    inst.components.reticule.ease = true
    
    local advancedtargeting = TheNet:GetServerGameMode() == "lavaarena"
    if advancedtargeting then
        inst.components.reticule.reticuleprefab = "reticuleaoe"
        inst.components.reticule.pingprefab = "reticuleaoeping"
        inst.components.reticule.mouseenabled = true

        inst:AddTag("nopunch")
    end
    
    inst:AddComponent("inventoryitem")
    inst.components.inventoryitem.imagename = "rgd3_nade"
    inst.components.inventoryitem.atlasname = "images/inventoryimages/rgd3_nade.xml"
    
    inst:AddComponent("inspectable")
    inst:AddComponent("equippable")
    
    MakeHauntableLaunch(inst)
    
    inst.components.equippable:SetOnEquip( OnEquip )
    inst.components.equippable:SetOnUnequip( OnUnequip )
    
    inst:AddComponent("complexprojectile")
    inst.components.complexprojectile:SetHorizontalSpeed(15)
    inst.components.complexprojectile:SetGravity(-35)
    inst.components.complexprojectile:SetLaunchOffset(Vector3(.25, 1, 0))
    inst.components.complexprojectile:SetOnLaunch(OnThrown)
    inst.components.complexprojectile:SetOnHit(OnHit)
    
    if not advancedtargeting then
        inst:AddComponent("weapon")
        inst.components.weapon:SetDamage(0)
        inst.components.weapon:SetRange(8, 10)
    end

---------------------------------
    inst:AddComponent("explosive")
    inst.components.explosive:SetOnExplodeFn(OnExplodeFn)
    inst.components.explosive.explosivedamage = TUNING.GUNPOWDER_DAMAGE
    inst.components.explosive.explosiverange = 3
    
    return inst
end

return Prefab("common/inventory/rgd3_nade", fn, assets, prefabs)

 

rgd3_nade.lua

Edited by Yakuzashi
Link to comment
Share on other sites

All you really needed to do was call inst.components.explosive:OnBurnt() when it hit the ground. This will cause it to detonate the explosive using the explosive component, rather than needing to copy and paste parts of its code as a local function.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...