AnonymousKoala Posted January 5, 2016 Share Posted January 5, 2016 I catched a crab, and then fed it 3 monster meat.It then immediatly disappeared. I have no idea what happened. Link to comment Share on other sites More sharing options...
Morfeo Posted January 5, 2016 Share Posted January 5, 2016 you can fed crabs?? xD Link to comment Share on other sites More sharing options...
AnonymousKoala Posted January 5, 2016 Author Share Posted January 5, 2016 you can fed crabs?? xD In inventory, so they wont starve to death Link to comment Share on other sites More sharing options...
Mday Posted January 5, 2016 Share Posted January 5, 2016 The health penalty from monster meat may have killed it? Crab have 50 Health, monster meat reduce Health by 20. So 3 MM is enough to kill it. Link to comment Share on other sites More sharing options...
AnonymousKoala Posted January 5, 2016 Author Share Posted January 5, 2016 The health penalty from monster meat may have killed it? Crab have 50 Health, monster meat reduce Health by 20. So 3 MM is enough to kill it.That's what I thought, but if it killed it it should have dropped something, shouldnt it? If its not a bug and actually a feature than I'm sorry haha Link to comment Share on other sites More sharing options...
Mday Posted January 5, 2016 Share Posted January 5, 2016 That's what I thought, but if it killed it it should have dropped something, shouldnt it? If its not a bug and actually a feature than I'm sorry hahaMay be it should add a fish morsel into your inventory? Link to comment Share on other sites More sharing options...
AnonymousKoala Posted January 6, 2016 Author Share Posted January 6, 2016 May be it should add a fish morsel into your inventory?Thats what I thought but instead it just disappeared. Link to comment Share on other sites More sharing options...
GuyPerfect Posted January 6, 2016 Share Posted January 6, 2016 The health penalty from monster meat may have killed it?This is precisely the problem. Before Crabs and Wobsters came along, nothing you could feed in your inventory accepted meat items, so there was never--hold it, does this work with Red Caps on Butterflies in RoG too?.. Huh, yes it does. This bug has apparently been around for quite a while. There's no code in the scripts for handling this situation, but of course we can add such code. We can always add such code. I considered various solutions to this problem, and I've settled on the one that I believe is the most all-encompassing so we don't run into anything similar in the future. Here's what I have in mind: if something in inventory should drop some loot on the ground when it dies, it will instead drop the loot in its owner's inventory. A simple concept, right? The correct way to fix this is to modify scripts/components/lootdropper.lua so it always drops loot in an owner's inventory where applicable, but that's kind of a lot of code, so I'm going to post a lazy fix. What I am about to show you is something we in the software development industry refer to as "staggeringly stupid." It's called a "hack", where a patch is made to code in such a way that it technically functions as desired, but the means by which it accomplishes this relies so heavily on the particular implementation (tight coupling) that should anything ever be changed somewhere down the line, the hack will break and cause new problems all over again. Never do this in a production build. This is just a temporary stopgap. That out of the way, I noticed that the global function MakeFeedablePet()--defined in scripts/standardcomponents.lua and used on everything that can starve in your inventory--already has the code needed to handle dropping loot into an owner's inventory, which makes this hack very simple. All we need to do is determine when an entity dies, check whether it's currently in something's inventory, then pretend it starved there instead of got killed... ... See what I mean? Staggeringly stupid. Devs, please turn back now. UPDATE: Or turn your attention to this post. The only way an entity can outright die is if it has health and its health drops to zero. This is handled in the Health component, not surprisingly defined in the file scripts/components/health.lua. Way down in Health:SetVal(), circa line 263, we have the following:if old_percent > 0 and new_percent <= 0 or self:GetMaxHealth() <= 0 then self.inst:PushEvent("death", {cause=cause}) GetWorld():PushEvent("entity_death", {inst = self.inst, cause=cause} ) if not self.nofadeout then self.inst:AddTag("NOCLICK") self.inst.persists = false self.inst:DoTaskInTime(self.destroytime or 2, destroy) endendWhen something dies, it fires off a couple events and, if configured to do so, automatically fizzles out a couple seconds later. Loot dropping is generally handled by the entity's stategraph, but it won't actually produce any loot if the entity is in inventory, and I didn't bother looking into why... I know, staggeringly stupid of me. We still need those death events to fire off, though, so certain things like Abigail's Flower still function properly. The hack shall hereby be applied beginning at line 268:if self.inst.components.inventoryitem and self.inst.components.inventoryitem.owner then if not self.inst.components.perishable then MakeFeedablePet(self.inst, 0) end self.inst.components.perishable:Perish()elseif not self.nofadeout then self.inst:AddTag("NOCLICK") self.inst.persists = false self.inst:DoTaskInTime(self.destroytime or 2, destroy)endThis checks to see whether an entity is currently in somebody's inventory when it dies. If it is, it ensures it's a feedable pet, then promptly forces it to starve to death. Otherwise, if the entity was not in inventory when it died, then it does its usual death mechanic. Link to comment Share on other sites More sharing options...
AnonymousKoala Posted January 7, 2016 Author Share Posted January 7, 2016 This is precisely the problem. Before Crabs and Wobsters came along, nothing you could feed in your inventory accepted meat items, so there was never--hold it, does this work with Red Caps on Butterflies in RoG too?.. Huh, yes it does. This bug has apparently been around for quite a while. There's no code in the scripts for handling this situation, but of course we can add such code. We can always add such code. I considered various solutions to this problem, and I've settled on the one that I believe is the most all-encompassing so we don't run into anything similar in the future. Here's what I have in mind: if something in inventory should drop some loot on the ground when it dies, it will instead drop the loot in its owner's inventory. A simple concept, right? The correct way to fix this is to modify scripts/components/lootdropper.lua so it always drops loot in an owner's inventory where applicable, but that's kind of a lot of code, so I'm going to post a lazy fix. What I am about to show you is something we in the software development industry refer to as "staggeringly stupid." It's called a "hack", where a patch is made to code in such a way that it technically functions as desired, but the means by which it accomplishes this relies so heavily on the particular implementation (tight coupling) that should anything ever be changed somewhere down the line, the hack will break and cause new problems all over again. Never do this in a production build. This is just a temporary stopgap. That out of the way, I noticed that the global function MakeFeedablePet()--defined in scripts/standardcomponents.lua and used on everything that can starve in your inventory--already has the code needed to handle dropping loot into an owner's inventory, which makes this hack very simple. All we need to do is determine when an entity dies, check whether it's currently in something's inventory, then pretend it starved there instead of got killed... ... See what I mean? Staggeringly stupid. Devs, please turn back now. The only way an entity can outright die is if it has health and its health drops to zero. This is handled in the Health component, not surprisingly defined in the file scripts/components/health.lua. Way down in Health:SetVal(), circa line 263, we have the following:if old_percent > 0 and new_percent <= 0 or self:GetMaxHealth() <= 0 then self.inst:PushEvent("death", {cause=cause}) GetWorld():PushEvent("entity_death", {inst = self.inst, cause=cause} ) if not self.nofadeout then self.inst:AddTag("NOCLICK") self.inst.persists = false self.inst:DoTaskInTime(self.destroytime or 2, destroy) endendWhen something dies, it fires off a couple events and, if configured to do so, automatically fizzles out a couple seconds later. Loot dropping is generally handled by the entity's stategraph, but it won't actually produce any loot if the entity is in inventory, and I didn't bother looking into why... I know, staggeringly stupid of me. We still need those death events to fire off, though, so certain things like Abigail's Flower still function properly. The hack shall hereby be applied beginning at line 268:if self.inst.components.inventoryitem and self.inst.components.inventoryitem.owner then if not self.inst.components.perishable then MakeFeedablePet(self.inst, 0) end self.inst.components.perishable:Perish()elseif not self.nofadeout then self.inst:AddTag("NOCLICK") self.inst.persists = false self.inst:DoTaskInTime(self.destroytime or 2, destroy)endThis checks to see whether an entity is currently in somebody's inventory when it dies. If it is, it ensures it's a feedable pet, then promptly forces it to starve to death. Otherwise, if the entity was not in inventory when it died, then it does its usual death mechanic.I cant believe I just saw your response. I love the way you constantly find out what's the issue. Link to comment Share on other sites More sharing options...
GuyPerfect Posted January 7, 2016 Share Posted January 7, 2016 I cant believe I just saw your response. I love the way you constantly find out what's the issue. By all means, direct your friends and family to my other thread! (-:__________I took the time to solve this bug properly, but like I said, it's kind of a lot of code. I added a new method to LootDropper that will drop its loot into an owner's inventory instead of on the ground, then tweaked Health to call that method when something dies while in inventory. scripts/components/lootdropper.lua, line 213:-- Fix for critters in inventory being killed by harmful foodsfunction LootDropper:DropLootIntoInventory() -- Determine this item's owner, if any local owner = self.inst.components.inventoryitem and self.inst.components.inventoryitem.owner or nil if not owner then return end -- No owner -- Resolve the type of inventory the owner has if owner.components.inventory then owner = owner.components.inventory elseif owner.components.container then owner = owner.components.container else return -- Then how was it holding this item? end -- Remove this item from its owner self.inst.components.inventoryitem:RemoveFromOwner(true) -- Determine the number of loot rolls to make local stacksize = 1 if self.inst.components.stackable then stacksize = self.inst.components.stackable.stacksize end -- Drop loot for each item in the stack for i = 1, stacksize do local loots = self:GenerateLoot() -- Add each loot to the owner's inventory for k, v in pairs(loots) do owner:GiveItem(SpawnPrefab(v)) end -- loots end -- iendscripts/components/health.lua, line 268: -- Entity died while in inventory if self.inst.components.inventoryitem and self.inst.components.inventoryitem.owner then -- Drop any loot into the owner's inventory if self.inst.components.lootdropper then self.inst.components.lootdropper:DropLootIntoInventory() end -- Delete the entity here self.inst:Remove() -- Entity was not in inventory when it died elseif not self.nofadeout then self.inst:AddTag("NOCLICK") self.inst.persists = false self.inst:DoTaskInTime(self.destroytime or 2, destroy) end Link to comment Share on other sites More sharing options...
AnonymousKoala Posted January 8, 2016 Author Share Posted January 8, 2016 By all means, direct your friends and family to my other thread! (-:__________I took the time to solve this bug properly, but like I said, it's kind of a lot of code. I added a new method to LootDropper that will drop its loot into an owner's inventory instead of on the ground, then tweaked Health to call that method when something dies while in inventory. scripts/components/lootdropper.lua, line 213:-- Fix for critters in inventory being killed by harmful foodsfunction LootDropper:DropLootIntoInventory() -- Determine this item's owner, if any local owner = self.inst.components.inventoryitem and self.inst.components.inventoryitem.owner or nil if not owner then return end -- No owner -- Resolve the type of inventory the owner has if owner.components.inventory then owner = owner.components.inventory elseif owner.components.container then owner = owner.components.container else return -- Then how was it holding this item? end -- Remove this item from its owner self.inst.components.inventoryitem:RemoveFromOwner(true) -- Determine the number of loot rolls to make local stacksize = 1 if self.inst.components.stackable then stacksize = self.inst.components.stackable.stacksize end -- Drop loot for each item in the stack for i = 1, stacksize do local loots = self:GenerateLoot() -- Add each loot to the owner's inventory for k, v in pairs(loots) do owner:GiveItem(SpawnPrefab(v)) end -- loots end -- iendscripts/components/health.lua, line 268: -- Entity died while in inventory if self.inst.components.inventoryitem and self.inst.components.inventoryitem.owner then -- Drop any loot into the owner's inventory if self.inst.components.lootdropper then self.inst.components.lootdropper:DropLootIntoInventory() end -- Delete the entity here self.inst:Remove() -- Entity was not in inventory when it died elseif not self.nofadeout then self.inst:AddTag("NOCLICK") self.inst.persists = false self.inst:DoTaskInTime(self.destroytime or 2, destroy) endAny chance you can post it on the workshop?Becuase well...I don't trust myself to put this code correctly without destroying something in my game haha. Link to comment Share on other sites More sharing options...
GuyPerfect Posted January 8, 2016 Share Posted January 8, 2016 Eh, not crazy about posting a whole Workshop mod just for a bug fix that will be gone in the next game update, but I'll gladly attach such a mod to this post! It's a .zip file. Just extract it to its own subdirectory in your mods/ folder and it will be available in-game. The only configuration is to disable this bug fix, which is enabled by default. Why bother, you ask, since you can just disable the mod? This is part of a larger bug-fixing mod, of course!deathbyfood.zip Link to comment Share on other sites More sharing options...
AnonymousKoala Posted January 9, 2016 Author Share Posted January 9, 2016 Eh, not crazy about posting a whole Workshop mod just for a bug fix that will be gone in the next game update, but I'll gladly attach such a mod to this post! It's a .zip file. Just extract it to its own subdirectory in your mods/ folder and it will be available in-game. The only configuration is to disable this bug fix, which is enabled by default. Why bother, you ask, since you can just disable the mod? This is part of a larger bug-fixing mod, of course!Once again, thank you. (also that description is gold) Link to comment Share on other sites More sharing options...
AnonymousKoala Posted January 9, 2016 Author Share Posted January 9, 2016 Eh, not crazy about posting a whole Workshop mod just for a bug fix that will be gone in the next game update, but I'll gladly attach such a mod to this post! It's a .zip file. Just extract it to its own subdirectory in your mods/ folder and it will be available in-game. The only configuration is to disable this bug fix, which is enabled by default. Why bother, you ask, since you can just disable the mod? This is part of a larger bug-fixing mod, of course!Also, playing in a shipwrecked file with this mod(or that it wasnt a mod exclusive issue, i cant remember haha)...makes corpses never disappear. I am still surrounded by spider corpses for a good amount of days. Link to comment Share on other sites More sharing options...
GuyPerfect Posted January 9, 2016 Share Posted January 9, 2016 Yup, sorry about that. It's a bug introduced by the bug fix. (-: The way I implemented it was that I injected the new code on top of the old code at runtime, and Health:SetVal() has a call to local function destroy, which of course isn't accessible outside of health.lua, which is why corpses don't disappear. I've corrected that particular issue in the finished mod, which fixes every bug I've documented so far. Give that one a try and it should be better. Link to comment Share on other sites More sharing options...
Recommended Posts
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.