Jump to content

Need help with preventing player actions


Recommended Posts

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)end
I'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 by mouse
Link to comment
Share on other sites

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)end
I'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

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

@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:

  • gosane
  • goinsane
  • inducedinsanity

If you're only wanting to make it while they are insane.

Link to comment
Share on other sites

@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:

  • gosane
  • goinsane
  • inducedinsanity
If 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

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
    end

end

Edited by Kzisor
Link to comment
Share on other sites

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

@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 by Kzisor
Link to comment
Share on other sites

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] ~= nilend
Then 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 by mouse
Link to comment
Share on other sites

@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-930

local 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-365

componentactions.lua lines 471-480

tool = 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 by Kzisor
Link to comment
Share on other sites

@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-930

local 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 by Kzisor
Link to comment
Share on other sites

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

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
  • Create New...