Fancy_Fox_Pers Posted September 7, 2017 Share Posted September 7, 2017 (edited) So, an awesome person a long time ago gave me this code that allows me to give items to mobs: (the ultimate goal being befriending them) for k, v in pairs(creatureprefabs) do AddPrefabPostInit(v, function(inst) inst:AddComponent("trader") inst.components.trader:SetAcceptTest(ShouldAcceptItem) inst.components.trader.onaccept = OnGetItemFromPlayer inst.components.trader:Enable() end) AddPrefabPostInit(v.."follower", function(inst) inst:AddComponent("trader") inst.components.trader:SetAcceptTest(ShouldAcceptItem) inst.components.trader.onaccept = OnGetItemFromPlayerLeader inst.components.trader:Enable() end) end I have noticed that this mod makes the Beefalo unwanting to accept food like grass and twigs (when this was written you couldn't feed them grass or twigs in the first place, no taming yet). It will still take the item but it won't start following, the taming process (it does without the mod). I think that's due to this code that states what items the mobs can accept: local function ShouldAcceptItem(inst, item, giver) if giver.prefab == "mimi" then if item.components.edible and item.components.edible.foodtype == GLOBAL.FOODTYPE.ANIMALFOOD then if not inst.components.follower or inst.components.follower:GetLoyaltyPercent() < 0.5 then return true end end end end What's the best strategy here? Is there a way I can add in the ShouldAcceptItem function something like and not receiver.prefab == "Beefalo" ? Also, Beefalos won't accept grass or twigs from other characters than "mimi" either. So I am not entirely certain about the cause Edited September 7, 2017 by Thibooms Link to comment Share on other sites More sharing options...
alainmcd Posted September 7, 2017 Share Posted September 7, 2017 Remove "beefalo" from the creatureprefabs table? Link to comment Share on other sites More sharing options...
Serpens Posted September 8, 2017 Share Posted September 8, 2017 (edited) you should except every mob that already has the trader component (eg. also pigs, pigking, antlion...). Otherwise you will overwrite it and normal behaviour does not work anymore. Or you have to adjust your code to not overwrite, but add additional behaviours. Edited September 8, 2017 by Serpens Link to comment Share on other sites More sharing options...
Fancy_Fox_Pers Posted September 16, 2017 Author Share Posted September 16, 2017 (edited) So sorry about the late reply. Have been having some pc issues that needed maintenance. Mods are fine though! Thanks for the replies. On 8-9-2017 at 0:35 AM, alainmcd said: Remove "beefalo" from the creatureprefabs table? That would defeat the purpose of the mod, unfortunately. On 8-9-2017 at 3:47 AM, Serpens said: you should except every mob that already has the trader component (eg. also pigs, pigking, antlion...). Otherwise you will overwrite it and normal behaviour does not work anymore. Or you have to adjust your code to not overwrite, but add additional behaviours. So here's what I did. I made some new functions that will only affect beefalos. The following still works as intended (by giving the right item, only with the right character), but now nor my character "mimi" or any other character can start the domestication process. For instance, when giving grass (by any character), the beefalo will simply shake its head and refuse the item. local function ShouldAcceptItem2(inst, item, giver) if giver.prefab == "mimi" then if item.components.edible.foodtype == GLOBAL.FOODTYPE.ANIMALFOOD then if not inst.components.follower or inst.components.follower:GetLoyaltyPercent() < 0.5 then return true end end end if not item.components.edible.foodtype == GLOBAL.FOODTYPE.ANIMALFOOD then return inst.components.eater:CanEat(item) and not inst.components.combat:HasTarget() end end local function OnGetItemFromPlayer2 (inst, giver, item) local newfollow = GLOBAL.SpawnPrefab(inst.prefab.."follower") if giver.prefab == "mimi" then newfollow.Transform:SetPosition(inst.Transform:GetWorldPosition()) giver.components.leader:AddFollower(newfollow) newfollow.components.follower:AddLoyaltyTime(480) inst:Remove() end if not giver.prefab == "mimi" then if inst.components.eater:CanEat(item) then inst.components.eater:Eat(item, giver) end end end Any ideas for a fix? My guess is something else should be in the second if of the function ShouldAcceptItem2 Also I realise that the way this code is set up "mimi" won't be able to start the domestication anyway (because of the if giver.prefab). I guess I just have to paste whatever would be the right code under the second if in the function ShouldAcceptItem2. Edit: how do you remove spoilers without removing the content, when editing? I accidentally made one for the entire rest of my reply.Edit 2: the reason for my second if is that I found this in beefalo.lua's original ShouldAcceptItem: local function ShouldAcceptItem(inst, item) return inst.components.eater:CanEat(item) and not inst.components.combat:HasTarget() end Edited September 16, 2017 by Thibooms Link to comment Share on other sites More sharing options...
Serpens Posted September 16, 2017 Share Posted September 16, 2017 (edited) the forum itself sucks yes. It is always best to write your text somewhere else, so in case you accisdently mess up everything, you don't have to write again. In your case I would copy the conent of spoiler, remove the whole stuff and copy the text back into (if it is still formatted, then copy it in any windows text editor first to remove the formatting... , cause hitting the link from forum "remove formatting" can also mess up your whole post) Now back to your problem: The problem is, that the game only accepts 1 single "ShouldAcceptItem" function. If you call "SetAcceptTest()" you are overwriting any previous function. It also does not help to give your function another name, since in the component "trader" it is always saved in self.test. So normally you should not overwrite this self.test, but change it, so it has both, default and your mod behaviour. In the beefalo.lua the ShouldAcceptItem function is local, that means you can not change it (easily). The other way would be to change something in the trader component. You can change self.test directly. When calling SetAcceptTest() the game does (see trader component code):function Trader:SetAcceptTest(fn) self.test = fn end which is overwriting. So you should not call this, but instead change self.test in the component itself. Eg you could make: AddComponentPostInit("trader", function(self) local oldtest = self.test -- first save the old test function self.test = function(self, self.inst, item, giver) -- then change it if giver.prefab == "mimi" and item.components.edible and item.components.edible.foodtype == GLOBAL.FOODTYPE.ANIMALFOOD and (not inst.components.follower or inst.components.follower:GetLoyaltyPercent() < 0.5) then return true elseif oldtest(self, self.inst, item, giver) then return true end end end) you need to do the same for the onaccept function (so different result, depending if your criteria are true or not) I did not test the code, there might be an error in it, but I think it is mostly okay Ah and I don't know, if the SetAcceptTest() in beefalo is called first, or if our "AddComponentPostInit" is called first... If ours is called first, this will not work, since self.test is unknown at this moment. In this cause you should do AddComponentPostInit("trader", function(self) self:DoTaskInTime(1,function(self) -- wait a second... local oldtest = self.test -- first save the old test function self.test = function(self, self.inst, item, giver) -- then change it if giver.prefab == "mimi" and item.components.edible and item.components.edible.foodtype == GLOBAL.FOODTYPE.ANIMALFOOD and (not inst.components.follower or inst.components.follower:GetLoyaltyPercent() < 0.5) then return true elseif oldtest(self, self.inst, item, giver) then return true end end end) end) (but I'm not 100% sure if DoTaskInTime is working when a component is calling it... if it does not work, change it to self.inst:DoTaskInTime...) Edited September 16, 2017 by Serpens Link to comment Share on other sites More sharing options...
Fancy_Fox_Pers Posted September 17, 2017 Author Share Posted September 17, 2017 (edited) Spoiler 3 hours ago, Serpens said: the forum itself sucks yes. It is always best to write your text somewhere else, so in case you accisdently mess up everything, you don't have to write again. In your case I would copy the conent of spoiler, remove the whole stuff and copy the text back into (if it is still formatted, then copy it in any windows text editor first to remove the formatting... , cause hitting the link from forum "remove formatting" can also mess up your whole post) Good to know, thanks! Spoiler 3 hours ago, Serpens said: In the beefalo.lua the ShouldAcceptItem function is local, that means you can not change it (easily) Oh, thanks, TIL. Thank you for the explanation. Really helps out. I tried your code but the game is expecting a ')' somewhere around this line: self.test = function(self, self.inst, item, giver) -- then change it And I am baffled that I can't find where to put the missing ')'. I tested my game some more to make sure it wasn't any other code than yours. Also, if I try the second code (because why not) it gives me the same error and the "same" line (well this time it says line 243 instead of 242 but that's only because there is one more line in your second code, it does indicate the same line I gave above). Spoiler I later also commented out the part of code that called "ShouldAcceptItem2", since that clearly isn't necessary anymore. -- inst.components.trader:SetAcceptTest(ShouldAcceptItem2) Hope I explained myself not too confusingly. Edited September 17, 2017 by Thibooms Link to comment Share on other sites More sharing options...
Serpens Posted September 17, 2017 Share Posted September 17, 2017 I don't have much time, but from I can see at the moment, there is no bracket missing. It can also mean that you made "(" somewhere in your code above, but did not close it. If you do not find it, please post also the code above, so we can see if a bracket is missing there. You can also first try a testmod that only contains my code, to make sure it is really your code, not mine. Link to comment Share on other sites More sharing options...
Fancy_Fox_Pers Posted September 17, 2017 Author Share Posted September 17, 2017 (edited) I just think it's weird because the problem doesn't occur when deleting the (your) same code. Let me provide you the full .lua (warning, it's a bit messy at the moment, but everything important is at the bottom) modmain.lua Edited September 17, 2017 by Thibooms Link to comment Share on other sites More sharing options...
Serpens Posted September 17, 2017 Share Posted September 17, 2017 Seems there is an update of DST. I currently have a limited data volume of internet, so I can not download the update. And DST does not start in steam offline modus for whatever reason... so I can't test it myself unfortunately. You have to try around what exatly is causing it. I think the error message with the bracket is misleading. It must be something else. All you can do is wait for someone else or try to find it out yourself (you should try the version without "DoTaskInTime" first, then there are less possible error causes) Link to comment Share on other sites More sharing options...
ptr Posted September 17, 2017 Share Posted September 17, 2017 You can't do indexing in the parameter list when declaring a function... self.test = function(self, self.inst, item, giver) Link to comment Share on other sites More sharing options...
Fancy_Fox_Pers Posted September 17, 2017 Author Share Posted September 17, 2017 45 minutes ago, ptr said: You can't do indexing in the parameter list when declaring a function... self.test = function(self, self.inst, item, giver) Thanks! Removed. Also, I noticed my "OnGetItemFromPlayer2" wasn't commented out either, so I fixed that. So quick update: beefalo domestication process now starts as usual but beefalo befriending with the animalfood doesn't work. I don't know what's wrong this time honestly.As a reminder, this is the (relevant) code currently being used: Spoiler AddComponentPostInit("trader", function(self) local oldtest = self.test -- first save the old test function self.test = function(self, item, giver) -- then change it if giver.prefab == "mimi" and item.components.edible and item.components.edible.foodtype == GLOBAL.FOODTYPE.ANIMALFOOD and (not inst.components.follower or inst.components.follower:GetLoyaltyPercent() < 0.5) then return true elseif oldtest(self, self.inst, item, giver) then return true end end end) ------------- -- If the animal is already a follower, no replacement needed, just add time local function OnGetItemFromPlayerLeader(inst, giver, item) inst.components.follower:AddLoyaltyTime(480) end local creatureprefabs2 = { "beefalo", } for k, v in pairs(creatureprefabs2) do AddPrefabPostInit(v, function(inst) -- inst:AddComponent("trader") -- inst.components.trader:SetAcceptTest(ShouldAcceptItem2) -- inst.components.trader.onaccept = OnGetItemFromPlayer2 -- inst.components.trader:Enable() end) AddPrefabPostInit(v.."follower", function(inst) inst:AddComponent("trader") inst.components.trader:SetAcceptTest(ShouldAcceptItem) inst.components.trader.onaccept = OnGetItemFromPlayerLeader inst.components.trader:Enable() end) end Link to comment Share on other sites More sharing options...
ptr Posted September 18, 2017 Share Posted September 18, 2017 I'm quite curious why you are replacing the original prefab with ...follower? Link to comment Share on other sites More sharing options...
Fancy_Fox_Pers Posted September 19, 2017 Author Share Posted September 19, 2017 20 hours ago, ptr said: I'm quite curious why you are replacing the original prefab with ...follower? DarkXerox basically did 95% of the code for this particular character. I mean I tried but I didn't know much and I still know only the minimum. iirc I had the idea and he happened to know about a DS mod that did it that way. It replaced the original mob with a new one, that would become the befriended version. Since there was that DS mod, there was less worrying about making this work Plus I got to easily change things like health, damage and for some mobs things like cutting down trees when running towards one (like bearger). Helped a ton for the brain too. I guess it could work differently too, but I wouldn't be really excited about starting from scratch at this points Link to comment 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