Snoopy2016 Posted May 27, 2025 Share Posted May 27, 2025 (edited) Hi everyone, I’m currently working on a custom chest for DST and trying to achieve the following functionality: I want the chest to display one of three different ape face sprites depending on how many guycoins (custom item) are stored inside: I tried doing this by using the "keyhole" symbol and replacing it with my custom PNGs, which I placed into the keyhole symbol folder like this: i thought it might work like this (where guychest is my bank/build name). But this approach doesn't seem to work. local function UpdateKeyholeSymbol(inst)   if not inst or not inst.components or not inst.components.container then return end   local num_gold = 0   local items = inst.components.container:FindItems(function(item)     return item.prefab == "goldnugget"   end)   num_gold = #items   local symbol = "keyhole-1"   if num_gold >= 5 then     symbol = "keyhole-3"   elseif num_gold >= 2 then     symbol = "keyhole-2"   end   inst.AnimState:OverrideSymbol("keyhole", "guychest", symbol) end  my build and anim tables are a mess... i fixed all the animations frame by frame and the chest is working now, but i don't know how to set up the keyhole symbol and layers correctly. 🤕 Any help is appreciated! Edited May 27, 2025 by Snoopy2016 doubled pngs Link to comment https://forums.kleientertainment.com/forums/topic/165989-need-help-chest-with-goldnugget-based-count/ Share on other sites More sharing options...
maliblues Posted June 4, 2025 Share Posted June 4, 2025 I'm sure there is a way to get the override symbol stuff to work but it's easier for me to test things having the files. But another suggestion could be having different idle states for each of the faces with the chest and playing those when the condition is met? I tried working in that animtool shown in the screenshots but sometimes there are less issues using the previous method of just spriter Link to comment https://forums.kleientertainment.com/forums/topic/165989-need-help-chest-with-goldnugget-based-count/#findComment-1819613 Share on other sites More sharing options...
mathem99 Posted June 4, 2025 Share Posted June 4, 2025 (edited) If memory serves me right, you have to put each keyhole into a separate folder. Take the mighty_gym for instance that is a structure exclusive to Wolfgang, each meter on the gym has a single image inside each folder: So basically put keyhole-1, keyhole-2 and keyhole-3 to folders keyhole, keyhole2 and keyhole3 respectively then compile the .scml file. Afterwards change your code to the following: local function UpdateKeyholeSymbol(inst) if not inst or not inst.components or not inst.components.container then return end local num_gold = 0 local items = inst.components.container:FindItems(function(item) return item.prefab == "goldnugget" end) num_gold = #items local symbol = "keyhole" if num_gold >= 5 then symbol = "keyhole3" elseif num_gold >= 2 then symbol = "keyhole2" end inst.AnimState:OverrideSymbol("keyhole", "guychest", symbol) end Do note, that each image in their respective folder should be named BASED on the folder's name with digits at the end (for example: folder keyhole1 should have its image named keyhole1-0) If that doesn't work, does UpdateKeyholeSymbol get called each time the container (in this case the chest) gains an item or not? Edited June 4, 2025 by mathem99 1 Link to comment https://forums.kleientertainment.com/forums/topic/165989-need-help-chest-with-goldnugget-based-count/#findComment-1819628 Share on other sites More sharing options...
Snoopy2016 Posted June 5, 2025 Author Share Posted June 5, 2025 (edited)  @maliblues you're right. i forgot to attach the files. there are two versions. the spriter one and the anim tools one. @mathem99 thanks, im going to test this 😊 guychest_.scml guychest.zip guychest_.zip Edited June 5, 2025 by Snoopy2016 Link to comment https://forums.kleientertainment.com/forums/topic/165989-need-help-chest-with-goldnugget-based-count/#findComment-1819796 Share on other sites More sharing options...
Snoopy2016 Posted June 15, 2025 Author Share Posted June 15, 2025 (edited) On 6/4/2025 at 7:49 PM, mathem99 said: If memory serves me right, you have to put each keyhole into a separate folder. Take the mighty_gym for instance that is a structure exclusive to Wolfgang, each meter on the gym has a single image inside each folder: So basically put keyhole-1, keyhole-2 and keyhole-3 to folders keyhole, keyhole2 and keyhole3 respectively then compile the .scml file. Afterwards change your code to the following: Do note, that each image in their respective folder should be named BASED on the folder's name with digits at the end (for example: folder keyhole1 should have its image named keyhole1-0) If that doesn't work, does UpdateKeyholeSymbol get called each time the container (in this case the chest) gains an item or not? @mathem99 I tested this by creating four folders (keyhole, keyhole1, keyhole2, and keyhole3), each containing the corresponding -0.png image. The keyhole folder holds the default "invisible" layer, which should be replaced by one of the other three keyhole images depending on the number of gold nuggets in the chest. In the .scml file, I added the keyhole symbol to the animations using keyhole-0.png. However, keyhole-1 is the only ape face showing up... Here’s what my chest code looks like: require "prefabutil" local assets = { Asset("ANIM", "anim/guychest.zip"), } local prefabs_regular = { "collapse_small", "collapsed_treasurechest", } local SUNKEN_PHYSICS_RADIUS = .45 local SOUNDS = { open = "dontstarve/wilson/chest_open", close = "dontstarve/wilson/chest_close", built = "dontstarve/common/chest_craft", } local function UpdateKeyholeSymbol(inst) if not inst or not inst.components or not inst.components.container then return end local num_gold = 0 local items = inst.components.container:FindItems(function(item) return item.prefab == "goldnugget" end) num_gold = #items local symbol = "keyhole" if num_gold >= 10 then symbol = "keyhole3" elseif num_gold >= 5 then symbol = "keyhole2" elseif num_gold < 5 then symbol = "keyhole1" end inst.AnimState:OverrideSymbol("keyhole", "guychest", symbol) end local function onopen(inst) if not inst:HasTag("burnt") then inst.AnimState:PlayAnimation("open") UpdateKeyholeSymbol(inst) inst.SoundEmitter:PlaySound(inst.sounds.open) end end local function onclose(inst) if not inst:HasTag("burnt") then inst.AnimState:PlayAnimation("close") inst.AnimState:PushAnimation("closed", false) UpdateKeyholeSymbol(inst) inst.SoundEmitter:PlaySound(inst.sounds.close) end end local function onhammered(inst, worker) if inst.components.burnable ~= nil and inst.components.burnable:IsBurning() then inst.components.burnable:Extinguish() end inst.components.lootdropper:DropLoot() if inst.components.container ~= nil then inst.components.container:DropEverything() end local fx = SpawnPrefab("collapse_small") fx.Transform:SetPosition(inst.Transform:GetWorldPosition()) fx:SetMaterial("wood") inst:Remove() end local function onhit(inst, worker) if not inst:HasTag("burnt") then if inst.components.container ~= nil then inst.components.container:DropEverything() inst.components.container:Close() end inst.AnimState:PlayAnimation("hit") inst.AnimState:PushAnimation("closed", false) end end local function onbuilt(inst) inst.AnimState:PlayAnimation("rebuild") inst.AnimState:PushAnimation("closed", false) inst.SoundEmitter:PlaySound(inst.sounds.built) end local function onsave(inst, data) if inst:HasTag("burnt") or (inst.components.burnable ~= nil and inst.components.burnable:IsBurning()) then data.burnt = true end end local function onload(inst, data) if data ~= nil and data.burnt and inst.components.burnable ~= nil then inst.components.burnable.onburnt(inst) end end local function fn() local inst = CreateEntity() inst.entity:AddTransform() inst.entity:AddAnimState() inst.entity:AddSoundEmitter() inst.entity:AddMiniMapEntity() inst.entity:AddNetwork() MakeObstaclePhysics(inst, 0.7) inst.MiniMapEntity:SetIcon("chest.png") inst:AddTag("structure") inst:AddTag("chest") inst:AddTag("heavy") inst.AnimState:SetBank("guychest") inst.AnimState:SetBuild("guychest") inst.AnimState:PlayAnimation("closed") MakeSnowCoveredPristine(inst) inst.entity:SetPristine() if not TheWorld.ismastersim then return inst end inst.sounds = SOUNDS inst:AddComponent("inspectable") inst:AddComponent("container") inst.components.container:WidgetSetup("guychest") inst.components.container.onopenfn = onopen inst.components.container.onclosefn = onclose inst.components.container.skipclosesnd = true inst.components.container.skipopensnd = true -- Keyhole-Update bei Itemänderungen (onput/ontake) inst:DoTaskInTime(0, function(task_inst) if task_inst and task_inst.components and task_inst.components.container then if task_inst.components.container.SetOnPutItemFn then task_inst.components.container:SetOnPutItemFn(function(container_owner_inst, item_put, slot) UpdateKeyholeSymbol(container_owner_inst) end) else print("GUYCHEST_ERROR: SetOnPutItemFn is nil on container component for "..(task_inst.GUID or "UNKNOWN_GUID")) end if task_inst.components.container.SetOnItemTakenFn then task_inst.components.container:SetOnItemTakenFn(function(container_owner_inst, item_taken, slot) UpdateKeyholeSymbol(container_owner_inst) end) else print("GUYCHEST_ERROR: SetOnItemTakenFn is nil on container component for "..(task_inst.GUID or "UNKNOWN_GUID")) end else local guid = (task_inst and task_inst.GUID) or "UNKNOWN_GUID_OR_NIL_TASK_INST" print("GUYCHEST_ERROR: Container component is nil for "..guid.." when trying to set item change listeners via DoTaskInTime.") end end) -- Initiales Setzen beim Spawn inst:DoTaskInTime(0, function() UpdateKeyholeSymbol(inst) end) inst:AddComponent("lootdropper") inst:AddComponent("workable") inst.components.workable:SetWorkAction(ACTIONS.HAMMER) inst.components.workable:SetWorkLeft(10) inst.components.workable:SetOnFinishCallback(onhammered) inst.components.workable:SetOnWorkCallback(onhit) AddHauntableDropItemOrWork(inst) inst:ListenForEvent("onbuilt", onbuilt) MakeSnowCovered(inst) MakeSmallBurnable(inst, nil, nil, true) MakeMediumPropagator(inst) inst.OnSave = onsave inst.OnLoad = onload return inst end return Prefab("guychest", fn, assets), MakePlacer("guychest_placer", "guychest", "guychest", "closed")  Edited June 15, 2025 by Snoopy2016 Link to comment https://forums.kleientertainment.com/forums/topic/165989-need-help-chest-with-goldnugget-based-count/#findComment-1822648 Share on other sites More sharing options...
Rickzzs Posted June 16, 2025 Share Posted June 16, 2025 local items = inst.components.container:FindItems(function(item) return item.prefab == "goldnugget" end) num_gold = #items Are you sure you are counting the counts of goldnugget instead the amount? Did you forget `item.components.stackable.stacksize`? 1 Link to comment https://forums.kleientertainment.com/forums/topic/165989-need-help-chest-with-goldnugget-based-count/#findComment-1822698 Share on other sites More sharing options...
mathem99 Posted June 16, 2025 Share Posted June 16, 2025 9 hours ago, Snoopy2016 said: -- Keyhole-Update bei Itemänderungen (onput/ontake) inst:DoTaskInTime(0, function(task_inst) if task_inst and task_inst.components and task_inst.components.container then if task_inst.components.container.SetOnPutItemFn then task_inst.components.container:SetOnPutItemFn(function(container_owner_inst, item_put, slot) UpdateKeyholeSymbol(container_owner_inst) end) else print("GUYCHEST_ERROR: SetOnPutItemFn is nil on container component for "..(task_inst.GUID or "UNKNOWN_GUID")) end if task_inst.components.container.SetOnItemTakenFn then task_inst.components.container:SetOnItemTakenFn(function(container_owner_inst, item_taken, slot) UpdateKeyholeSymbol(container_owner_inst) end) else print("GUYCHEST_ERROR: SetOnItemTakenFn is nil on container component for "..(task_inst.GUID or "UNKNOWN_GUID")) end else local guid = (task_inst and task_inst.GUID) or "UNKNOWN_GUID_OR_NIL_TASK_INST" print("GUYCHEST_ERROR: Container component is nil for "..guid.." when trying to set item change listeners via DoTaskInTime.") end end) From what I remember container component does not have SetOnPutItemFn or SetOnItemTakenFn functions. Instead replace all that with this: inst:ListenForEvent("itemget", function() UpdateKeyholeSymbol(inst) end) inst:ListenForEvent("itelose", function() UpdateKeyholeSymbol(inst) end)  1 Link to comment https://forums.kleientertainment.com/forums/topic/165989-need-help-chest-with-goldnugget-based-count/#findComment-1822706 Share on other sites More sharing options...
Snoopy2016 Posted June 16, 2025 Author Share Posted June 16, 2025 (edited) Those were the changes needed. It's working now – you guys are legends! Really appreciate it, thanks! 🙌 Edited June 16, 2025 by Snoopy2016 Link to comment https://forums.kleientertainment.com/forums/topic/165989-need-help-chest-with-goldnugget-based-count/#findComment-1822746 Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now