Jump to content

Mouse click issues with componentactions, inventory, inventory_classified and widgets


hoxi
  • Pending

Edit: this report is mentioned further below as well, but just to be sure this is clear right away, I'm putting it here as well and clarifying that these issues result in what that report explains, which is not being able to turn on/off equipped lanterns, but only on mouse and keyboard, while a controller can do it just fine, so it's definitely not intended.

 

In components/inventory.lua:

function Inventory:UseItemFromInvTile(item, actioncode, mod_name)
    if not self.inst.sg:HasStateTag("busy") and
        self:CanAccessItem(item) and
        self.inst.components.playeractionpicker ~= nil then
        local actions
        SetClientRequestedAction(actioncode, mod_name)
        if self:GetActiveItem() ~= nil then
            --use the active item on the inventory item
            actions = self.inst.components.playeractionpicker:GetUseItemActions(item, self:GetActiveItem(), true)
        else
            --just use the inventory item
            actions = self.inst.components.playeractionpicker:GetInventoryActions(item) -- HERE
        end
        ClearClientRequestedAction()

		local act = actions[1]
		if act == nil then
            return
        elseif actioncode == nil or (act.action.code == actioncode and act.action.mod_name == mod_name) then
           	self.inst.components.locomotor:PushAction(act, true)
        --elseif mod_name ~= nil then
            --print("Remote use inventory item failed: "..tostring(ACTION_MOD_IDS[mod_name][actioncode]))
        --else
            --print("Remote use inventory item failed: "..tostring(ACTION_IDS[actioncode]))
        end
    end
end

In prefabs/inventory_classified.lua:

local function UseItemFromInvTile(inst, item)
    if not IsBusy(inst) and
        inst._parent ~= nil and
        not inst._parent:HasTag("busy") and
        not (inst._parent.sg ~= nil and
            inst._parent.sg:HasStateTag("busy")) and
        inst._parent.components.playeractionpicker ~= nil and
        inst._parent.components.playercontroller ~= nil then
        local actions = inst._activeitem ~= nil and
            inst._parent.components.playeractionpicker:GetUseItemActions(item, inst._activeitem, true) or
            inst._parent.components.playeractionpicker:GetInventoryActions(item) -- HERE
		local act = actions[1]
		if act ~= nil and not TryNonNetworkedAction(inst, act, item) then
			inst._parent.components.playercontroller:RemoteUseItemFromInvTile(act, item)
        end
    end
end

In widgets/itemtile.lua:

function ItemTile:GetDescriptionString()
    local str = ""
    if self.item ~= nil and self.item:IsValid() and self.item.replica.inventoryitem ~= nil then
        local adjective = self.item:GetAdjective()
        if adjective ~= nil then
            str = adjective.." "
        end
        str = str..self.item:GetDisplayName()

        local player = ThePlayer
        local actionpicker = player.components.playeractionpicker
        local active_item = player.replica.inventory:GetActiveItem()
        if active_item == nil then
            if not (self.item.replica.equippable ~= nil and self.item.replica.equippable:IsEquipped()) then
                --self.namedisp:SetHAlign(ANCHOR_LEFT)
                if TheInput:IsControlPressed(CONTROL_FORCE_INSPECT) then
                    str = str.."\n"..TheInput:GetLocalizedControl(TheInput:GetControllerID(), CONTROL_PRIMARY)..": "..STRINGS.INSPECTMOD
                elseif TheInput:IsControlPressed(CONTROL_FORCE_TRADE) and not self.item.replica.inventoryitem:CanOnlyGoInPocket() then
                    if next(player.replica.inventory:GetOpenContainers()) ~= nil then
                        str = str.."\n"..TheInput:GetLocalizedControl(TheInput:GetControllerID(), CONTROL_PRIMARY)..": "..((TheInput:IsControlPressed(CONTROL_FORCE_STACK) and self.item.replica.stackable ~= nil) and (STRINGS.STACKMOD.." "..STRINGS.TRADEMOD) or STRINGS.TRADEMOD)
                    end
                elseif TheInput:IsControlPressed(CONTROL_FORCE_STACK) and self.item.replica.stackable ~= nil then
                    str = str.."\n"..TheInput:GetLocalizedControl(TheInput:GetControllerID(), CONTROL_PRIMARY)..": "..STRINGS.STACKMOD
                end
            end

            local actions = actionpicker:GetInventoryActions(self.item) -- HERE
            if #actions > 0 then
                str = str.."\n"..TheInput:GetLocalizedControl(TheInput:GetControllerID(), CONTROL_SECONDARY)..": "..actions[1]:GetActionString()
            end
        elseif active_item:IsValid() then
            if not (self.item.replica.equippable ~= nil and self.item.replica.equippable:IsEquipped()) then
                if active_item.replica.stackable ~= nil and active_item.prefab == self.item.prefab and self.item:StackableSkinHack(active_item) then
                    str = str.."\n"..TheInput:GetLocalizedControl(TheInput:GetControllerID(), CONTROL_PRIMARY)..": "..STRINGS.UI.HUD.PUT
                else
                    str = str.."\n"..TheInput:GetLocalizedControl(TheInput:GetControllerID(), CONTROL_PRIMARY)..": "..STRINGS.UI.HUD.SWAP
                end
            end

            --no RMB hint for quickdrop while holding an item, as that might be confusing since players would think its the item they are holding.
            --the mod never had the hint, and people discovered it just fine, so this should also be fine -Zachary

            local actions = actionpicker:GetUseItemActions(self.item, active_item, true)
            if #actions > 0 then
                str = str.."\n"..TheInput:GetLocalizedControl(TheInput:GetControllerID(), CONTROL_SECONDARY)..": "..actions[1]:GetActionString()
            end
        end
    end
    return str
end

In the bits of code highlighted above with -- HERE, shouldn't them be sending (item, true) to the actionpicker component? There's normally no way to use items with left click, only move them around or stack them.

Alternatively, in componentactions.lua, remove the right parameter and clarify it's implicit for INVENTORY type actions, though that sounds like it might not be the best way to go about it, because later on you could make more FORCE keybinds let you do alternative actions with left click, or some other new functionality (from what I can tell, inspecting is a separate thing altogether so it's not affected).

The right parameter being there as a condition (but it not being sent) is why you can't turn off a lantern equipped in your hand on mouse and keyboard, but you can on controller. The only other INVENTORY type actions beside machine that use it are edible and magiciantool, The latter isn't affected, and I'm not sure if there are even edible items that are also equippable, besides the very old unused hambat feature.

 

 

Additionally, there's a few improvements that could be made to widgets/equipslot.lua and widgets/itemtile.lua, shown below, highlighted with -- HERE as well:

function EquipSlot:OnControl(control, down)
	if self.tile ~= nil then
		self.tile:UpdateTooltip()
	end

    if down then
        local inventory = self.owner.replica.inventory
        if control == CONTROL_ACCEPT then
            -- HERE, allow inspecting equipped items, even with an active item
            if self.tile ~= nil and self.tile.item ~= nil and TheInput:IsControlPressed(CONTROL_FORCE_INSPECT) then
                inventory:InspectItemFromInvTile(self.tile.item)
            else
                local active_item = inventory:GetActiveItem()
                if active_item ~= nil then
                    if active_item.replica.equippable ~= nil and
                        self.equipslot == active_item.replica.equippable:EquipSlot() and
                        not active_item.replica.equippable:IsRestricted(self.owner) then
                        if self.tile ~= nil and self.tile.item ~= nil then
                            if self.tile.item.replica.equippable == nil or not self.tile.item.replica.equippable:ShouldPreventUnequipping() then
                                inventory:SwapEquipWithActiveItem()
                            end
                        else
                            inventory:EquipActiveItem()
                        end
                    end
                elseif self.tile ~= nil and self.tile.item ~= nil and self.owner.replica.inventory:GetNumSlots() > 0 then
                    if self.tile.item.replica.equippable == nil or not self.tile.item.replica.equippable:ShouldPreventUnequipping() then
                        inventory:TakeActiveItemFromEquipSlot(self.equipslot)
                    end
                end
			end
            return true
        elseif control == CONTROL_SECONDARY and
            self.tile ~= nil and
            self.tile.item ~= nil then
                if TheInput:IsControlPressed(CONTROL_FORCE_TRADE) then
                    if self.tile.item.replica.equippable == nil or not self.tile.item.replica.equippable:ShouldPreventUnequipping() then
                        inventory:DropItemFromInvTile(self.tile.item, TheInput:IsControlPressed(CONTROL_FORCE_STACK))
                    end
                else
                    inventory:UseItemFromInvTile(self.tile.item)
                end
            return true
        end
    end
end

--------

function ItemTile:GetDescriptionString()
    local str = ""
    if self.item ~= nil and self.item:IsValid() and self.item.replica.inventoryitem ~= nil then
        local adjective = self.item:GetAdjective()
        if adjective ~= nil then
            str = adjective.." "
        end
        str = str..self.item:GetDisplayName()

        local player = ThePlayer
        local actionpicker = player.components.playeractionpicker
        local active_item = player.replica.inventory:GetActiveItem()
        if active_item == nil then
            -- HERE, show that you can inspect even equipped items when holding force inspect (possible with change to widgets/equipslot.lua)
            if TheInput:IsControlPressed(CONTROL_FORCE_INSPECT) then
                str = str.."\n"..TheInput:GetLocalizedControl(TheInput:GetControllerID(), CONTROL_PRIMARY)..": "..STRINGS.INSPECTMOD
            elseif not (self.item.replica.equippable ~= nil and self.item.replica.equippable:IsEquipped()) then
                --self.namedisp:SetHAlign(ANCHOR_LEFT)
                --if TheInput:IsControlPressed(CONTROL_FORCE_INSPECT) then
                --    str = str.."\n"..TheInput:GetLocalizedControl(TheInput:GetControllerID(), CONTROL_PRIMARY)..": "..STRINGS.INSPECTMOD
                --elseif TheInput:IsControlPressed(CONTROL_FORCE_TRADE) and not self.item.replica.inventoryitem:CanOnlyGoInPocket() then
                if TheInput:IsControlPressed(CONTROL_FORCE_TRADE) and not self.item.replica.inventoryitem:CanOnlyGoInPocket() then
                    if next(player.replica.inventory:GetOpenContainers()) ~= nil then
                        str = str.."\n"..TheInput:GetLocalizedControl(TheInput:GetControllerID(), CONTROL_PRIMARY)..": "..((TheInput:IsControlPressed(CONTROL_FORCE_STACK) and self.item.replica.stackable ~= nil) and (STRINGS.STACKMOD.." "..STRINGS.TRADEMOD) or STRINGS.TRADEMOD)
                    end
                elseif TheInput:IsControlPressed(CONTROL_FORCE_STACK) and self.item.replica.stackable ~= nil then
                    str = str.."\n"..TheInput:GetLocalizedControl(TheInput:GetControllerID(), CONTROL_PRIMARY)..": "..STRINGS.STACKMOD
                end
            end

            local actions = actionpicker:GetInventoryActions(self.item, true)
            if #actions > 0 then
                str = str.."\n"..TheInput:GetLocalizedControl(TheInput:GetControllerID(), CONTROL_SECONDARY)..": "..actions[1]:GetActionString()
            end
        elseif active_item:IsValid() then
            -- HERE, show that you can still force-inspect something with an active item
            -- this already works in vanilla, but the hint doesn't show (including equippable if change to widgets/equipslot.lua is included)
            if TheInput:IsControlPressed(CONTROL_FORCE_INSPECT) then
                str = str.."\n"..TheInput:GetLocalizedControl(TheInput:GetControllerID(), CONTROL_PRIMARY)..": "..STRINGS.INSPECTMOD
            elseif not (self.item.replica.equippable ~= nil and self.item.replica.equippable:IsEquipped()) then
                if active_item.replica.stackable ~= nil and active_item.prefab == self.item.prefab and self.item:StackableSkinHack(active_item) then
                    str = str.."\n"..TheInput:GetLocalizedControl(TheInput:GetControllerID(), CONTROL_PRIMARY)..": "..STRINGS.UI.HUD.PUT
                else
                    str = str.."\n"..TheInput:GetLocalizedControl(TheInput:GetControllerID(), CONTROL_PRIMARY)..": "..STRINGS.UI.HUD.SWAP
                end
            end

            -- HERE, no code example but, the comment below isn't necessarily true unless the items are the same?
            -- and in that case, you could use a unique string for it instead of "Drop" maybe? so instead it displays something like "Drop other item"?

            --no RMB hint for quickdrop while holding an item, as that might be confusing since players would think its the item they are holding.
            --the mod never had the hint, and people discovered it just fine, so this should also be fine -Zachary

            local actions = actionpicker:GetUseItemActions(self.item, active_item, true)
            if #actions > 0 then
                str = str.."\n"..TheInput:GetLocalizedControl(TheInput:GetControllerID(), CONTROL_SECONDARY)..": "..actions[1]:GetActionString()
            end
        end
    end
    return str
end

These would mainly allow the player to inspect equippables when holding force inspect, since it's kinda weird that this doesn't work despite controllers being able to and that it wouldn't interfere with anything else..? It's also weird how Swap doesn't show up when hovering an equippable over an equippable slot that has an item already, so cases like that could be addressed too maybe?


Steps to Reproduce

For the right click on equipped lantern issue, see here.

For the inspect issues:

  • Try to inspect an equipped item, with or without an active (cursor) item.
  • Notice how it doesn't work despite there no being any reason not to, as the force inspect key tends to override many other actions without interfering otherwise.



User Feedback


There are no comments to display.



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...