Jump to content

Recommended Posts

Hello all. Is there way to modify actions used by components? My custom prefab have "container" component and "cooker". But when I hover food over it it shows only "store" action. Someone know how to swap this by holding "alt" for example? Or maybe there is way to disable "store" action?

Link to comment
https://forums.kleientertainment.com/forums/topic/33312-modyfing-actions/
Share on other sites

You want to override this function (in actions.lua):

ACTIONS.STORE.strfn = function(act)    if act.target and act.target.components.stewer then        return "COOK"    elseif act.target and act.target.components.occupiable then        return "IMPRISON"    endend
Try this:

local ACTIONS = GLOBAL.ACTIONSlocal ACTIONS_STORE_strfn_base = ACTIONS.STORE.strfnACTIONS.STORE.strfn = function(act)    if act.target and act.target.components.cooker then        return "COOK"    else        return ACTIONS_STORE_strfn_base(act)    endend

Hmm, now it showing "cook" action when hover food, but still working as "store".

Oh, I see. I thought cooker is what the crockpot used.

Look at cookable.lua's CollectUseActions function (that's what adds the COOK action) and container.lua's CollectSceneActions (that's what adds the RUMMAGE action).

You could do something like override your prefab's container component's CollectSceneActions to only call the base function if the player does not have a cookable active item.

-- in the prefab's fn functionlocal container_CollectSceneActions_base = inst.components.container.CollectSceneActionsinst.components.container.CollectSceneActions = function(self, doer, actions)    local active_item = doer and doer.components.inventory and doer.components.inventory:GetActiveItem()    if not active_item or not active_item.components.cookable then        container_CollectSceneActions_base(self, doer, actions)    endend

Oh, I see. I thought cooker is what the crockpot used.

Look at cookable.lua's CollectUseActions function (that's what adds the COOK action) and container.lua's CollectSceneActions (that's what adds the RUMMAGE action).

You could do something like override your prefab's container component's CollectSceneActions to only call the base function if the player does not have a cookable active item.

-- in the prefab's fn functionlocal container_CollectSceneActions_base = inst.components.container.CollectSceneActionsinst.components.container.CollectSceneActions = function(self, doer, actions)    local active_item = doer and doer.components.inventory and doer.components.inventory:GetActiveItem()    if not active_item or not active_item.components.cookable then        container_CollectSceneActions_base(self, doer, actions)    endend

Not working.

If I understand it correctly, it means: "if there is active item and it isnt cookable use normal container function" right? Sadly problems is that its using container functions whole time and i cant force it do use "cooker" functions.

	local container_CollectSceneActions_base = inst.components.container.CollectSceneActionsinst.components.container.CollectSceneActions = function(self, doer, actions)    local active_item = doer and doer.components.inventory and doer.components.inventory:GetActiveItem()    if not active_item or not active_item.components.cookable then        container_CollectSceneActions_base(self, doer, actions)		else		active_item.components.cookable.CollectSceneActions(doer, target, actions)    endend

I tried to fix it myself but still not working. Any more ideas?

Edited by EmielRegis

Cookable uses CollectUseActions, not CollectSceneActions (see components/playeractionpicker.lua for where it aggregates all possible actions and chooses between them). Have you tried removing the 'container' component to see if the cooker works on its own?

The code I posted is doing 'if there is no active item or, if there is one, if it is not cookable, then call the base function' (and insert RUMMAGE into the possible actions table), otherwise do not call it. I suppose the way I wrote it is confusing; this is probably more clear: if not (active_item and active_item.components.cookable) then

Actually, this shouldn't even be an issue as the RUMMAGE action has a lower priority (-1) than COOK (0). Definitely make sure that your cooker component is working on its own.

Edited by squeek

Cookable uses CollectUseActions, not CollectSceneActions (see components/playeractionpicker.lua for where it aggregates all possible actions and chooses between them). Have you tried removing the 'container' component to see if the cooker works on its own?

The code I posted is doing 'if there is no active item or, if there is one, if it is not cookable, then call the base function' (and insert RUMMAGE into the possible actions table), otherwise do not call it. I suppose the way I wrote it is confusing; this is probably more clear: if not (active_item and active_item.components.cookable) then

Actually, this shouldn't even be an issue as the RUMMAGE action has a lower priority (-1) than COOK (0). Definitely make sure that your cooker component is working on its own.

Alone cooker working fine. I used both codes from you, first to modmain, second to fn function and only noticable effect is "cook" after hovering food but still works as "store".

Turns out the STORE action is added in InventoryItem:GetUseActions(), so you need to stop that from getting added if the active item is cookable and the target is a container.

This will work:

 

local function PatchInventoryItemComponent(comp)	local InventoryItem_CollectUseActions_base = comp.CollectUseActions	comp.CollectUseActions = function(self, doer, target, actions)		local is_target_a_container = target and target.components.container and target.components.container.canbeopened		local is_target_a_cooker = target and target.components.cooker		local is_inst_cookable = self.inst and self.inst.components.cookable		if not is_target_a_container or not is_target_a_cooker or not is_inst_cookable then			InventoryItem_CollectUseActions_base(self, doer, target, actions)		end	endendAddComponentPostInit("inventoryitem", PatchInventoryItemComponent)
Had to use a component post init instead of require because of this bug. Edited by squeek

Turns out the STORE action is added in InventoryItem:GetUseActions(), so you need to stop that from getting added if the active item is cookable and the target is a container.

This will work:

 

local function PatchInventoryItemComponent(comp)	local InventoryItem_CollectUseActions_base = comp.CollectUseActions	comp.CollectUseActions = function(self, doer, target, actions)		local is_target_a_container = target and target.components.container and target.components.container.canbeopened		local is_target_a_cooker = target and target.components.cooker		local is_inst_cookable = self.inst and self.inst.components.cookable		if not is_target_a_container or not is_target_a_cooker or not is_inst_cookable then			InventoryItem_CollectUseActions_base(self, doer, target, actions)		end	endendAddComponentPostInit("inventoryitem", PatchInventoryItemComponent)
Had to use a component post init instead of require because of this bug.

 

Working. Great thx squeek, helpfull as always :)

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
×
  • Create New...