Jump to content

Assistance: Mod Crash


Recommended Posts

This mod was working previously (about 6 months ago)
I came back to the game after an extended break and now it crashes the game.

 

The item in question is a food item (liquor) that can be ignited to explode.

The item can be loaded, set on fire, whereupon it begins to burble (custom sound file) and then, after it burns for a few seconds, the game crashes to desktop.

The log file doesn't capture the reason for the crash, and I have gone over the lua file for gunpowder and it appears to be set up the same way.

As I said, it was working previously, but now crashes

Does anyone see the problem?

 

It is supposed to be compatible with RoG, SW, and DST - in case that matters


Liquor.lua

Spoiler

 

local Assets =
{
    Asset("ANIM", "anim/liquor.zip"),
    Asset("ATLAS", "images/inventoryimages/liquor.xml"),
    Asset("ANIM", "anim/explode.zip"),
    
    Asset("SOUNDPACKAGE", "sound/waiter.fev"),
    Asset( "SOUND", "sound/waiter.fsb" ),
}

local prefabs =
{
    "explode_small",
    "spoiled_food",
}


local function OnIgniteFn(inst)
    inst.SoundEmitter:PlaySound("waiter/liquor/burble", "burble")
    end

local function OnExtinguishFn(inst)
    inst.SoundEmitter:KillSound("burble")
end

 

local function OnExplodeFn(inst)

    local pos = Vector3(inst.Transform:GetWorldPosition())
    inst.SoundEmitter:KillSound("burble")
    inst.SoundEmitter:PlaySound("dontstarve/common/blackpowder_explo")

    local explode = SpawnPrefab("explode_small")
    local pos = inst:GetPosition()
    explode.Transform:SetPosition(pos.x, pos.y, pos.z)


    explode.AnimState:SetBloomEffectHandle( "shaders/anim.ksh" )
    explode.AnimState:SetLightOverride(1)
end    
    
local function OnPutInInv(inst, owner)
    if owner.prefab == "mole" then
        inst.components.explosive:OnBurnt()
    end
end

local function fn(Sim)
    local inst = CreateEntity()
    inst.entity:AddTransform()
    inst.entity:AddAnimState()
    inst.entity:AddSoundEmitter()
    if TheSim:GetGameID() =="DST" then inst.entity:AddNetwork() end

    MakeInventoryPhysics(inst)
   
    inst.AnimState:SetBank("liquor")
    inst.AnimState:SetBuild("liquor")
    inst.AnimState:PlayAnimation("idle", false)
    
    inst:AddTag("preparedfood")
            
    if TheSim:GetGameID()=="DST" then
        if not TheWorld.ismastersim then
            return inst
        end
        
        inst.entity:SetPristine()
    end

    inst:AddComponent("inspectable")
    
    inst:AddComponent("edible")
    inst.components.edible.foodtype = "GENERIC"
    inst.components.edible.healthvalue = -TUNING.HEALING_SMALL
    inst.components.edible.hungervalue = TUNING.CALORIES_MED
    inst.components.edible.sanityvalue = TUNING.SANITY_MED
        
    if IsDLCEnabled(CAPY_DLC) or IsDLCEnabled(REIGN_OF_GIANTS) or TheSim:GetGameID()=="DST" then inst.components.edible.temperaturedelta = TUNING.COLD_FOOD_BONUS_TEMP*0.5 else end
    if IsDLCEnabled(CAPY_DLC) or IsDLCEnabled(REIGN_OF_GIANTS) or TheSim:GetGameID()=="DST" then inst.components.edible.temperatureduration = TUNING.FOOD_TEMP_AVERAGE*2 else end

    inst:AddComponent("inventoryitem")
    inst.components.inventoryitem.atlasname = "images/inventoryimages/liquor.xml"

    inst:AddComponent("stackable")
    inst.components.stackable.maxsize = TUNING.STACK_SIZE_SMALLITEM

    inst:AddComponent("fuel")
    inst.components.fuel.fuelvalue = TUNING.LARGE_FUEL
    
    MakeSmallBurnable(inst, 3 + math.random() * 3)
    MakeSmallPropagator(inst)
    --V2C: Remove default OnBurnt handler, as it conflicts with
    --explosive component's OnBurnt handler for removing itself
    inst.components.burnable:SetOnBurntFn(nil)
    inst.components.burnable:SetOnIgniteFn(OnIgniteFn)
    inst.components.burnable:SetOnExtinguishFn(OnExtinguishFn)

    inst:AddComponent("explosive")
    inst.components.explosive:SetOnExplodeFn(OnExplodeFn)
    inst.components.explosive.explosivedamage = TUNING.GUNPOWDER_DAMAGE*0.1
        
    inst:AddComponent("perishable")
    inst.components.perishable:SetPerishTime(TUNING.PERISH_SUPERSLOW)
    inst.components.perishable:StartPerishing()
    inst.components.perishable.onperishreplacement = "spoiled_food"

    return inst
end


return Prefab( "common/inventory/liquor", fn, Assets )

 

 

 

Link to comment
Share on other sites

Get the log.txt for further details. The crash in itself is near the end of the file (obviously) and the stacktrace after it is indented, so you can easily find it with your bare eyes. If you need help understanding the error, post the log here.

Link to comment
Share on other sites

8 hours ago, Mobbstar said:

Get the log.txt for further details. The crash in itself is near the end of the file (obviously) and the stacktrace after it is indented, so you can easily find it with your bare eyes. If you need help understanding the error, post the log here.

 

Ok,  but as I said - I checked the logs already  and the log file doesn't capture the reason for the crash.

Anyway - here is the latest log.

 

Edit: I've run it multiple times in both SW and RoG games, same thing happens every time - crashes out without logging anything.

 

log.txt

Link to comment
Share on other sites

UPDATE:

After removing bits of code piece by piece I have found something,

When I remove the lines referencing OnExtinguishFn it seems to work.

Not a huge deal, since most, people wouldn't try to extingusih something that is about to explode anyway.

So it's not strictly _needed_

But if anyone knows why its causing the crash, I'd love to know.

 

Lines 20-22

local function OnExtinguishFn(inst)
    inst.SoundEmitter:KillSound("burble")
end

 

Line 85

    inst.components.burnable:SetOnExtinguishFn(OnExtinguishFn)

 

 

Complete .Lua

Spoiler

local Assets =
{
    Asset("ANIM", "anim/liquor.zip"),
    Asset("ATLAS", "images/inventoryimages/liquor.xml"),
    Asset("ANIM", "anim/explode.zip"),
    
    Asset("SOUNDPACKAGE", "sound/waiter.fev"),
    Asset( "SOUND", "sound/waiter.fsb" ),
}

local prefabs =
{
    "explode_small",
    "spoiled_food",
}


local function OnIgniteFn(inst)
    inst.SoundEmitter:PlaySound("waiter/liquor/burble", "burble")
    end

 

local function OnExtinguishFn(inst)
    inst.SoundEmitter:KillSound("burble")
end

 

local function OnExplodeFn(inst)

    local pos = Vector3(inst.Transform:GetWorldPosition())
    inst.SoundEmitter:KillSound("burble")
    inst.SoundEmitter:PlaySound("dontstarve/common/blackpowder_explo")

    local explode = SpawnPrefab("explode_small")
    local pos = inst:GetPosition()
    explode.Transform:SetPosition(pos.x, pos.y, pos.z)


    explode.AnimState:SetBloomEffectHandle( "shaders/anim.ksh" )
    explode.AnimState:SetLightOverride(1)
end    
    
local function OnPutInInv(inst, owner)
    if owner.prefab == "mole" then
        inst.components.explosive:OnBurnt()
    end
end

local function fn(Sim)
    local inst = CreateEntity()
    inst.entity:AddTransform()
    inst.entity:AddAnimState()
    inst.entity:AddSoundEmitter()
    if TheSim:GetGameID() =="DST" then inst.entity:AddNetwork() end

    MakeInventoryPhysics(inst)
   
    inst.AnimState:SetBank("liquor")
    inst.AnimState:SetBuild("liquor")
    inst.AnimState:PlayAnimation("idle", false)
    
    inst:AddTag("preparedfood")
            
    if TheSim:GetGameID()=="DST" then
        if not TheWorld.ismastersim then
            return inst
        end
        
        inst.entity:SetPristine()
    end

    inst:AddComponent("inspectable")
    
    inst:AddComponent("edible")
    inst.components.edible.foodtype = "GENERIC"
    inst.components.edible.healthvalue = -TUNING.HEALING_SMALL
    inst.components.edible.hungervalue = TUNING.CALORIES_MED
    inst.components.edible.sanityvalue = TUNING.SANITY_MED
        
    if IsDLCEnabled(CAPY_DLC) or IsDLCEnabled(REIGN_OF_GIANTS) or TheSim:GetGameID()=="DST" then inst.components.edible.temperaturedelta = TUNING.COLD_FOOD_BONUS_TEMP*0.5 else end
    if IsDLCEnabled(CAPY_DLC) or IsDLCEnabled(REIGN_OF_GIANTS) or TheSim:GetGameID()=="DST" then inst.components.edible.temperatureduration = TUNING.FOOD_TEMP_AVERAGE*2 else end

    inst:AddComponent("inventoryitem")
    inst.components.inventoryitem.atlasname = "images/inventoryimages/liquor.xml"

    inst:AddComponent("stackable")
    inst.components.stackable.maxsize = TUNING.STACK_SIZE_SMALLITEM

    inst:AddComponent("fuel")
    inst.components.fuel.fuelvalue = TUNING.LARGE_FUEL
    
    MakeSmallBurnable(inst, 3 + math.random() * 3)
    MakeSmallPropagator(inst)
    --V2C: Remove default OnBurnt handler, as it conflicts with
    --explosive component's OnBurnt handler for removing itself
    inst.components.burnable:SetOnBurntFn(nil)
    inst.components.burnable:SetOnIgniteFn(OnIgniteFn)
    inst.components.burnable:SetOnExtinguishFn(OnExtinguishFn)

    inst:AddComponent("explosive")
    inst.components.explosive:SetOnExplodeFn(OnExplodeFn)
    inst.components.explosive.explosivedamage = TUNING.GUNPOWDER_DAMAGE*0.1
        
    inst:AddComponent("perishable")
    inst.components.perishable:SetPerishTime(TUNING.PERISH_SUPERSLOW)
    inst.components.perishable:StartPerishing()
    inst.components.perishable.onperishreplacement = "spoiled_food"

    return inst
end


return Prefab( "common/inventory/liquor", fn, Assets )

 

Link to comment
Share on other sites

There are differences between DS and DST code.

 

This is gunpowder from DS:

  MakeSmallBurnable(inst, 3+math.random()*3)
  MakeSmallPropagator(inst)

  inst:AddComponent("explosive")
  inst.components.explosive:SetOnExplodeFn(OnExplodeFn)
  inst.components.explosive:SetOnIgniteFn(OnIgniteFn)
  inst.components.explosive.explosivedamage = TUNING.GUNPOWDER_DAMAGE

 

This is gunpowder from DST:

    MakeSmallBurnable(inst, 3 + math.random() * 3)
    MakeSmallPropagator(inst)
    --V2C: Remove default OnBurnt handler, as it conflicts with
    --explosive component's OnBurnt handler for removing itself
    inst.components.burnable:SetOnBurntFn(nil)
    inst.components.burnable:SetOnIgniteFn(OnIgniteFn)
    inst.components.burnable:SetOnExtinguishFn(OnExtinguishFn)

    inst:AddComponent("explosive")
    inst.components.explosive:SetOnExplodeFn(OnExplodeFn)
    inst.components.explosive.explosivedamage = TUNING.GUNPOWDER_DAMAGE

 

That being said, the issue didn't get solved for me after doing what you said.

Setting the onburnt function to nil makes it so there isn't proper cleanup of the entity when it burns.

Therefore, some inventoryitem data isn't handled correctly.

And thanks to that, when the game reaches this code

	if not self.inst.components.SoundEmitter then
		self.inst.entity:AddSoundEmitter() --Need this for the drop on water and sink sounds
	end

in the inventoryitem component, the game crashes (for whatever reason, we can't know), whether the entity had a sound emitter, or not (SoundEmitter isn't a component, you access it via self.inst.SoundEmitter).

 

If you want to replicate the crash in a single console line:

local a=c_spawn("axe"); a:RemoveComponent("inventoryitem"); a:Remove(); a:AddComponent("inventoryitem");

Which is more or less, what is happening to your gunpowder.

 

So, the solution?

Make two functions to setup the burnable and explosive components, one for DS, another for DST.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.

×
  • Create New...