Bumber64 Posted January 25, 2022 Share Posted January 25, 2022 I'm creating a mod that converts killer bees into regular bees when caught. Unfortunately, it seems to mess up the inventory slot where the bee is spawned. You can't see the bee, and trying to move anything into that slot fails. My best guess is that the client isn't replicating something. I think I had it working before, but I removed some debug code and now it isn't. Any thoughts? Code: Spoiler if not GLOBAL.TheNet:GetIsServer() then return end local function Beeify(inst) if not inst:IsValid() then return nil end local bee = GLOBAL.SpawnPrefab("bee") if bee then bee.Transform:SetPosition(inst.Transform:GetWorldPosition()) if bee.components.stackable and inst.components.stackable then bee.components.stackable:SetStackSize(inst.components.stackable.stacksize) end if bee.components.perishable and inst.components.perishable then bee.components.perishable:SetPercent(inst.components.perishable:GetPercent()) end if inst.components.homeseeker and inst.components.homeseeker.home then inst:PushEvent("detachchild") end if bee.components.inventoryitem and inst.components.inventoryitem then bee.components.inventoryitem:InheritMoisture(inst.components.inventoryitem:GetMoisture(), inst.components.inventoryitem:IsWet()) local owner = inst.components.inventoryitem.owner local holder = owner and (owner.components.inventory or owner.components.container) local slot = holder and holder:GetItemSlot(inst) if slot then inst:Remove() holder:GiveItem(bee, slot) return bee end end inst.persists = false inst.entity:Hide() inst:DoTaskInTime(0, inst.Remove) end return bee end AddPrefabPostInit("killerbee", function(inst) local oldfn = inst.components.inventoryitem.onputininventoryfn inst.components.inventoryitem:SetOnPutInInventoryFn(function(inst) if oldfn then oldfn(inst) end local new_bee = Beeify(inst) local newfn = new_bee and new_bee.components.inventoryitem and new_bee.components.inventoryitem.onputininventoryfn if newfn then newfn(new_bee) end end) end) Link to comment https://forums.kleientertainment.com/forums/topic/137091-solved-need-help-converting-caught-bees-in-inventory/ Share on other sites More sharing options...
Bumber64 Posted January 25, 2022 Author Share Posted January 25, 2022 Started a new world without other mods, and the slot doesn't break, but the item won't update to a regular bee until it's manipulated in the inventory. Link to comment https://forums.kleientertainment.com/forums/topic/137091-solved-need-help-converting-caught-bees-in-inventory/#findComment-1535038 Share on other sites More sharing options...
Monti18 Posted January 25, 2022 Share Posted January 25, 2022 You probably need to change this code if slot then inst:Remove() holder:GiveItem(bee, slot) return bee end to this: if slot then inst:DoTaskInTime(0, inst.Remove) holder:GiveItem(bee, slot) return bee end Link to comment https://forums.kleientertainment.com/forums/topic/137091-solved-need-help-converting-caught-bees-in-inventory/#findComment-1535071 Share on other sites More sharing options...
Bumber64 Posted January 26, 2022 Author Share Posted January 26, 2022 @Monti18 That works, but it won't go to the same slot. As a result, the bee will end up held or released when it doesn't have to be. Link to comment https://forums.kleientertainment.com/forums/topic/137091-solved-need-help-converting-caught-bees-in-inventory/#findComment-1535297 Share on other sites More sharing options...
Monti18 Posted January 26, 2022 Share Posted January 26, 2022 (edited) AddPrefabPostInit("killerbee", function(inst) if GLOBAL.TheWorld.ismastersim then local function OnPutInInventory(inst,owner) owner = owner or inst.components.inventoryitem.owner local new_bee = GLOBAL.ReplacePrefab(inst,"bee") if owner then owner.components.inventory:GiveItem(new_bee) end end inst:ListenForEvent("onputininventory",OnPutInInventory) end end) Try it with this, this was working for me. Edited January 26, 2022 by Monti18 Link to comment https://forums.kleientertainment.com/forums/topic/137091-solved-need-help-converting-caught-bees-in-inventory/#findComment-1535323 Share on other sites More sharing options...
Bumber64 Posted January 26, 2022 Author Share Posted January 26, 2022 @Monti18 Client inventory still not updating visually until I try to move stuff around. Link to comment https://forums.kleientertainment.com/forums/topic/137091-solved-need-help-converting-caught-bees-in-inventory/#findComment-1535326 Share on other sites More sharing options...
Monti18 Posted January 26, 2022 Share Posted January 26, 2022 That's right, I forgot to test it without a bee already in the inventory. AddPrefabPostInit("killerbee", function(inst) if GLOBAL.TheWorld.ismastersim then local function OnPutInInventory(inst,owner) local new_bee = GLOBAL.ReplacePrefab(inst,"bee") owner = owner or inst.components.inventoryitem.owner if owner then inst:DoTaskInTime(0,function() owner.components.inventory:GiveItem(new_bee) end) end end inst:ListenForEvent("onputininventory",OnPutInInventory) end end) By adding the taskintime, at least for me the bee appeared correctly in the same place. But if you try to catch it with a full inventory, the killerbee will fall on the ground without being transformed. Link to comment https://forums.kleientertainment.com/forums/topic/137091-solved-need-help-converting-caught-bees-in-inventory/#findComment-1535346 Share on other sites More sharing options...
Bumber64 Posted January 27, 2022 Author Share Posted January 27, 2022 (edited) @Monti18 No good, I'm afraid. I'm still getting phantom killerbees in my inventory after the first one caught. Or if I catch one with all my slots full, I end up with a phantom killerbee in my hand, I can't perform any actions with the cursor, and the server crashes on right-click (due to nil inventoryitem of the non-existent killerbee.) This occurs even when the OnPutInInventory function contains nothing but GLOBAL.ReplacePrefab(inst, "bee"). Additional information: --client_log.txt says: "Don't Starve Together: 490729 WIN32_STEAM" --modinfo.lua: api_version = 10 dst_compatible = true all_clients_require_mod = false --also tried "true" clients_only_mod = false Addendum: Looks like ReplacePrefab is just this: function ReplacePrefab(original_inst, name, skin, skin_id, creator) local x,y,z = original_inst.Transform:GetWorldPosition() local replacement_inst = SpawnPrefab(name, skin, skin_id, creator) replacement_inst.Transform:SetPosition(x,y,z) original_inst:Remove() return replacement_inst end Going to try using "original_inst:DoTaskInTime(0, original_inst.Remove)" and see if that makes any difference. No more phantom bees, but it's back to putting them into the wrong slot (or releasing them as bees when inventory isn't full if I add a 0.01 delay to GiveItem task.) Edited January 27, 2022 by Bumber64 Addendum Link to comment https://forums.kleientertainment.com/forums/topic/137091-solved-need-help-converting-caught-bees-in-inventory/#findComment-1535663 Share on other sites More sharing options...
Monti18 Posted January 27, 2022 Share Posted January 27, 2022 You also did it with the ListenForEvent right? As then the function takes a bit more time to start so that the rest can be loaded. I retried it, for me it's still working. You may want to delay the ListenForEvent a bit further: AddPrefabPostInit("killerbee", function(inst) if GLOBAL.TheWorld.ismastersim then local function OnPutInInventory(inst,owner) local new_bee = GLOBAL.ReplacePrefab(inst,"bee") owner = owner or inst.components.inventoryitem.owner if owner then inst:DoTaskInTime(0,function() owner.components.inventory:GiveItem(new_bee) end) end end inst:ListenForEvent("onputininventory",function(inst,owner) inst:DoTaskInTime(0,function() OnPutInInventory(inst,owner) end) end) end end) That is also working on my side. 1 Link to comment https://forums.kleientertainment.com/forums/topic/137091-solved-need-help-converting-caught-bees-in-inventory/#findComment-1535851 Share on other sites More sharing options...
Bumber64 Posted January 27, 2022 Author Share Posted January 27, 2022 (edited) @Monti18 Yes, I was using ListenForEvent. I got it working just now by putting the Remove in the same function as the GiveItem: AddPrefabPostInit("killerbee", function(inst) if GLOBAL.TheWorld.ismastersim then local function OnPutInInventory(inst, owner) local new_bee = ReplacePrefab(inst, "bee") owner = owner or inst.components.inventoryitem.owner if owner then inst:DoTaskInTime(0, function() inst:Remove(); owner.components.inventory:GiveItem(new_bee) end) else inst:DoTaskInTime(0, inst.Remove) end end inst:ListenForEvent("onputininventory", OnPutInInventory) end end) Where ReplacePrefab is a local function without "original_inst:Remove()". Not sure why your code wasn't working for me, other than maybe CPU differences. In any case, thanks for your help solving this! Addendum: Your most recent code works too. Edited January 27, 2022 by Bumber64 Addendum 1 Link to comment https://forums.kleientertainment.com/forums/topic/137091-solved-need-help-converting-caught-bees-in-inventory/#findComment-1535876 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