mouse Posted March 9, 2015 Share Posted March 9, 2015 (edited) EDIT: This problem has been solved.I'm trying to add a mechanic that checks the player's sanity and prevents them from using tools when the player's sanity is below a certain point. The code below works great with mouse input but it isn't applied to keyboard(and probably controller) input for some reason: local PlayerActionPicker = require "components/playeractionpicker"local mypicker = PlayerActionPicker.GetEquippedItemActionsfunction PlayerActionPicker:GetEquippedItemActions(target, useitem, right) if self.inst:HasTag("player") and self.inst.components.sanity then if self.inst.components.sanity.current/self.inst.components.sanity.max < .66 then return nil end end return mypicker(self, target, useitem, right)endI've been monkeying with this for a couple days and I'm running out of patience. I honestly can't list everything I've tried. Would anyone have any suggestions? Edited March 10, 2015 by mouse Link to comment Share on other sites More sharing options...
Kzisor Posted March 9, 2015 Share Posted March 9, 2015 I'm trying to add a mechanic that checks the player's sanity and prevents them from using tools when the player's sanity is below a certain point. The code below works great with mouse input but it isn't applied to keyboard(and probably controller) input for some reason: local PlayerActionPicker = require "components/playeractionpicker"local mypicker = PlayerActionPicker.GetEquippedItemActionsfunction PlayerActionPicker:GetEquippedItemActions(target, useitem, right) if self.inst:HasTag("player") and self.inst.components.sanity then if self.inst.components.sanity.current/self.inst.components.sanity.max < .66 then return nil end end return mypicker(self, target, useitem, right)endI've been monkeying with this for a couple days and I'm running out of patience. I honestly can't list everything I've tried. Would anyone have any suggestions? You could simply use AddPlayerPostInit to listen for event 'equipped', run your sanity check, then unequip the item if not met and say something like 'are you insane or what?' Link to comment Share on other sites More sharing options...
mouse Posted March 9, 2015 Author Share Posted March 9, 2015 You could simply use AddPlayerPostInit to listen for event 'equipped', run your sanity check, then unequip the item if not met and say something like 'are you insane or what?' There's two problems with that. They can't use their tools for fighting while insane and if they go insane while the tool is equipped, they can still use the tool. Link to comment Share on other sites More sharing options...
Kzisor Posted March 9, 2015 Share Posted March 9, 2015 @mouse, so you'd have to also listen for the sanity changed event 'sanitydelta' and check using the same function? I don't see the problem; you said "prevents a player from using tools", which comes across as no fighting with them either while insane. There are also these events being pushed which you can check on as well:gosanegoinsaneinducedinsanityIf you're only wanting to make it while they are insane. Link to comment Share on other sites More sharing options...
mouse Posted March 9, 2015 Author Share Posted March 9, 2015 @mouse, so you'd have to also listen for the sanity changed event 'sanitydelta' and check using the same function? I don't see the problem; you said "prevents a player from using tools", which comes across as no fighting with them either while insane. There are also these events being pushed which you can check on as well:gosanegoinsaneinducedinsanityIf you're only wanting to make it while they are insane. I meant using tools as tools. A whole festival of listenforevent's can be very messy and it doesn't give me the control I need. I'm trying to find an existing function to hook my code into. In the normal DS it was easy. I could hook it into Workable:IsActionValid but half of the functions in some of DST's components are never called. So that complicates things a bit and that's why I'm looking for someone who has enough knowledge of the inner-workings of DST to give a hand. Link to comment Share on other sites More sharing options...
Kzisor Posted March 9, 2015 Share Posted March 9, 2015 (edited) I meant using tools as tools. If that is what you meant, then you should be more clear in the future. However, the above two events (equipped and sanitydelta) will do what you originally requested. What you're looking for is the tool component, there is a function Tool:CanDoAction(action). Here is where that is called:function EntityScript:CanDoAction(action) if self.inherentactions ~= nil and self.inherentactions[action] then return true end if self:HasTag(action.id.."_tool") then return true end local inventory = self.replica.inventory if inventory ~= nil then local item = inventory:GetActiveItem() if item ~= nil and item:CanDoAction(action) then return true end item = inventory:GetEquippedItem(EQUIPSLOTS.HANDS) if item ~= nil and item:CanDoAction(action) then return true end endend Edited March 9, 2015 by Kzisor Link to comment Share on other sites More sharing options...
mouse Posted March 9, 2015 Author Share Posted March 9, 2015 If that is what you meant, then you should be more clear in the future. However, the above two events (equipped and sanitydelta) will do what you originally requested. What you're looking for is the tool component, there is a function Tool:CanDoAction(action). Yes I'm aware of that, thank you. But that function is never called. Do you understand now? Link to comment Share on other sites More sharing options...
Kzisor Posted March 9, 2015 Share Posted March 9, 2015 (edited) @mouse, the reason that is never being called is because it's adding a tag, but removing the tag will cause it not to work. The only way around it is by editing the EntityScript:CanDoAction function, which I posted above. Edit:Corrected information. Edited March 9, 2015 by Kzisor Link to comment Share on other sites More sharing options...
mouse Posted March 9, 2015 Author Share Posted March 9, 2015 (edited) Edited for edit.You're still not getting it. The function Tool:CanDoAction is never called. To test it yourself, temporarily edit your tool component file directly so it reads:function Tool:CanDoAction(action)print("asdfasdfasdf") return self.actions[action] ~= nilendThen run DST, make an axe, and chop at a tree. If you open your console, you'll see that "asdfasdfasdf" is never printed.Then undo the print line in the file and save. Edited March 9, 2015 by mouse Link to comment Share on other sites More sharing options...
Kzisor Posted March 9, 2015 Share Posted March 9, 2015 (edited) @mouse, I think you completely missed the fact that I bypassed the tool component and went directly to the EntityScript.lua file which is what makes components work. It seems that EntityScript:CanDoAction isn't being called for tools period; it's only relying on the tag itself. In every place that I've searched to determine if a tool can be used; it simply required that the tag be on the tool. Example:playercontroller.lua lines 920-930local function GetPickupAction(target, tool) if tool ~= nil then for k, v in pairs(TOOLACTIONS) do if target:HasTag(k.."_workable") then if tool:HasTag(k.."_tool") then return ACTIONS[k] end break end end end playercontroller.lua lines 1057-1062 if tool ~= nil then for k, v in pairs(TOOLACTIONS) do if tool:HasTag(k.."_tool") then table.insert(pickup_tags, k.."_workable") end end end componentactions.lua lines 356-365componentactions.lua lines 471-480tool = function(inst, doer, target, actions, right) for k, v in pairs(TOOLACTIONS) do if inst:HasTag(k.."_tool") then if target:IsActionValid(ACTIONS[k], right) then table.insert(actions, ACTIONS[k]) return end end end end What I'd do is use AddPrefabPostInit for each of the tools, call a single function which removes the action.id_tool tag on equip if below X sanity. When the item is equipped and sanity is above X simply add the tag back if it doesn't exist. Yes it probably isn't the way you want to do it, but it does allow you to fight with the tool while not using it for the "tools" purposes. Edited March 9, 2015 by Kzisor Link to comment Share on other sites More sharing options...
Kzisor Posted March 9, 2015 Share Posted March 9, 2015 (edited) @mouse, if you're dead set on not using the ListenForEvent, then you want to modify the following lines of code: playercontroller.lua lines 920-930local function GetPickupAction(target, tool) if tool ~= nil then for k, v in pairs(TOOLACTIONS) do if target:HasTag(k.."_workable") then if tool:HasTag(k.."_tool") then return ACTIONS[k] end break end end end Edited March 9, 2015 by Kzisor Link to comment Share on other sites More sharing options...
DarkXero Posted March 10, 2015 Share Posted March 10, 2015 I want to contribute:AddStategraphPostInit("wilson", function(sg) for k, v in pairs(sg.actionhandlers) do if GLOBAL.TOOLACTIONS[v.action.id] then local old = v.deststate sg.actionhandlers[k].deststate = function(inst, ...) if inst.components.sanity and not inst.components.sanity.sane then print("Nope") else return old(inst, ...) end end end endend) Link to comment Share on other sites More sharing options...
mouse Posted March 10, 2015 Author Share Posted March 10, 2015 Thank you everyone for your help. I finally came up with a solution that works very well. Cheers. 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