ESOUI

ESOUI (https://www.esoui.com/forums/index.php)
-   General Authoring Discussion (https://www.esoui.com/forums/forumdisplay.php?f=174)
-   -   How to lock an item? (https://www.esoui.com/forums/showthread.php?t=7729)

Phuein 04/17/18 07:23 PM

How to lock an item?
 
I've been trying different calls and options for hours, and I only got as far as this:

Code:

PLAYER_INVENTORY:RefreshInventorySlotLocked(1, slotId, lock, bagId)

All values checked valid. It only fades out the item and toggles the .locked property, but doesn't do the rest of what happens when locking an item. Is there just a simple call to lock/unlock items? I couldn't find it. I found this:
http://esodata.uesp.net/100022/src/i....lua.html#2694
http://esodata.uesp.net/100022/src/i....lua.html#1595

eventHandler 04/17/18 08:53 PM

Quote:

Originally Posted by Phuein (Post 34425)
I've been trying different calls and options for hours, and I only got as far as this:

Code:

PLAYER_INVENTORY:RefreshInventorySlotLocked(1, slotId, lock, bagId)
All values checked valid. It only fades out the item and toggles the .locked property, but doesn't do the rest of what happens when locking an item. Is there just a simple call to lock/unlock items? I couldn't find it. I found this:
http://esodata.uesp.net/100022/src/i....lua.html#2694
http://esodata.uesp.net/100022/src/i....lua.html#1595

An addon like FCO Item Saver would probably be a good source of information on how that system works. I've never tried to mess with this before, so I can't do better than that at the moment.

Rhyono 04/17/18 08:54 PM

So your goal is to lock the item? I haven't tested this, but is this what you want?

lua Code:
  1. if CanItemBePlayerLocked(bagId,slotId) then
  2.     SetItemIsPlayerLocked(bagId,slotId,true)
  3. else
  4.     d("Item cannot be locked.")
  5. end

Dolgubon 04/18/18 01:34 AM

Quote:

Originally Posted by Phuein (Post 34425)
I've been trying different calls and options for hours, and I only got as far as this:

Code:

PLAYER_INVENTORY:RefreshInventorySlotLocked(1, slotId, lock, bagId)
All values checked valid. It only fades out the item and toggles the .locked property, but doesn't do the rest of what happens when locking an item. Is there just a simple call to lock/unlock items? I couldn't find it. I found this:
http://esodata.uesp.net/100022/src/i....lua.html#2694
http://esodata.uesp.net/100022/src/i....lua.html#1595

What you are toggling there is just the UI's lock value. You aren't actually changing the base game's UI value. So if the Inventory ran a refresh then the item wouldn't be 'locked' anymore. It's like you are telling someone some false information, but you aren't actually changing the records where that information is kept.

Phuein 04/18/18 11:44 AM

Quote:

Originally Posted by Rhyono (Post 34427)
So your goal is to lock the item? I haven't tested this, but is this what you want?

lua Code:
  1. if CanItemBePlayerLocked(slotId,bagId) then
  2.     SetItemIsPlayerLocked(slotId,bagId,true)
  3. else
  4.     d("Item cannot be locked.")
  5. end


That was what I was looking for - although bag and slot are reversed, should be:
Code:

        local bag, index = bagId, slotId
        local locking = not IsItemPlayerLocked(bag, index) -- The locking state to apply.
        if CanItemBePlayerLocked(bag, index) then
            SetItemIsPlayerLocked(bag, index, locking)
        end


And the above works! BUT with that I saw the code calls to:
http://esodata.uesp.net/100015/src/i....lua.html#1179

SO, I would like to implement the original call into mine:
http://esodata.uesp.net/100022/src/i....lua.html#1630

I mimicked it for myself, but I get an unexpected error about:
Code:

Checking type on argument slotIndex failed in IsSlotLocked_lua
stack traceback:
        [C]: in function 'IsSlotLocked'

My code just copies from original and all values check out, but I can't find a .slotType anywhere, in control, nowhere. Thus my code:
Code:

        local inventorySlot = slotControl
        local bag, index = bagId, slotId -- ZO_Inventory_GetBagAndIndex(inventorySlot)
        local locking = not IsItemPlayerLocked(bag, index) -- The locking state to apply.
        local action
       
        if locking then
                action = SI_ITEM_ACTION_MARK_AS_LOCKED
                -- Can't lock these.
                if IsItemAlreadySlottedToCraft(inventorySlot) then return end
        else
                action = SI_ITEM_ACTION_UNMARK_AS_LOCKED
        end
       
    if not IsSlotLocked(inventorySlot) and CanItemBePlayerLocked(bag, index) and
            not QUICKSLOT_WINDOW:AreQuickSlotsShowing() then
        slotActions:AddSlotAction(action,
                function() MarkAsPlayerLockedHelper(bag, index, locking) end,
                "secondary")
    end


Baertram 04/19/18 08:05 AM

In order to find the error please post the whole code and not the snippet here only.
It seems that your index variable is NIL somehow.

Btw: Why do you copy the bag and slot to new vars?

local bag, index = bagId, slotId -- ZO_Inventory_GetBagAndIndex(inventorySlot)
Just use bagId and slotId if they are defined via ZO_Inventory_GetBagAndIndex(inventorySlot) before.

Phuein 04/19/18 11:56 AM

Quote:

Originally Posted by Baertram (Post 34440)
In order to find the error please post the whole code and not the snippet here only.
It seems that your index variable is NIL somehow.

Btw: Why do you copy the bag and slot to new vars?

local bag, index = bagId, slotId -- ZO_Inventory_GetBagAndIndex(inventorySlot)
Just use bagId and slotId if they are defined via ZO_Inventory_GetBagAndIndex(inventorySlot) before.

The values are checked and are fine. None of them are nil - the error has nothing to do with nil btw. The var copying is irrelevant here, just denotes my copying the values. This is all the relevant code needed to be reviewed.

Please note that I said above that Dolgubon's code (with fixes) works fine. My interest is in mimicking the game code, rather than overriding their way of locking items.

Baertram 04/19/18 02:05 PM

I don't get what you are trying then sorry.
Do you want to know where the inventory row's data.slotType is created?

If this is all relevant code where is the "slotIndex" in that code which the lua error messages tells you the type is wrong?
Quote:

Checking type on argument slotIndex failed in IsSlotLocked_lua

Phuein 04/20/18 01:38 PM

Quote:

Originally Posted by Baertram (Post 34449)
I don't get what you are trying then sorry.
Do you want to know where the inventory row's data.slotType is created?

If this is all relevant code where is the "slotIndex" in that code which the lua error messages tells you the type is wrong?

It's in:
Code:

IsSlotLocked(inventorySlot)
But when I follow into it in the game code, I can't find any such type check for it! It just takes the same bagID and slotID from inventorySlot, which all check out fine. Reference to function:
https://esoapi.uesp.net/current/src/...t.lua.html#463

The error isn't in my code, it's in that game function that should be working fine. After all, with the same bagID and slotID values, I can do CanItemBePlayerLocked() and SetItemIsPlayerLocked() just fine in the bypass code suggested.

EDIT: I just realized my function toggles locking, so I don't even need to run their IsSlotLocked() check. I took it out. I also realized I can just access the same .locked data from the data object I already have.

However, I then ran into the IsItemAlreadySlottedToCraft() check they run. It's a local, so I can't even use it. And the actions object actionHandlers[] is local too, so no access either. I'm left with locking it myself, rather than using the game functions for it. *smh*

Unless somebody knows how to access IsItemAlreadySlottedToCraft()?

Rhyono 04/20/18 02:56 PM

I don't really know what you're trying to do with it, but you need to call it on the specific station you're attempting to check it against. Alchemy, Enchanting, or "Smithing" (woodworking, blacksmithing and clothier should fall under this, Jewelry probably will too?).

Phuein 04/21/18 01:43 PM

Quote:

Originally Posted by Rhyono (Post 34473)
I don't really know what you're trying to do with it, but you need to call it on the specific station you're attempting to check it against. Alchemy, Enchanting, or "Smithing" (woodworking, blacksmithing and clothier should fall under this, Jewelry probably will too?).

This is what the game runs when locking and unlocking. I shouldn't need to call anything else but this. If you check my links above, you'll see just that. I'm just trying to mimic the way the game locks and unlocks items, from the code, nothing else.

Rhyono 04/21/18 03:44 PM

Sorry, I didn't specify properly: I was talking about IsItemAlreadySlottedToCraft()

Phuein 04/22/18 12:11 PM

Quote:

Originally Posted by Rhyono (Post 34491)
Sorry, I didn't specify properly: I was talking about IsItemAlreadySlottedToCraft()

This is from the game code. They don't want for players to lock items that are slotted to craft. They don't call a check for each station, but rather call this one function that takes care of everything for the case of locking items.

Baertram 04/22/18 12:17 PM

If you want to use the funciton but it is local, just copy&paste it to your code?

Lua Code:
  1. local function IsItemAlreadySlottedToCraft(inventorySlot)
  2.     local bag, slot = ZO_Inventory_GetBagAndIndex(inventorySlot)
  3.     if SYSTEMS:IsShowing("alchemy") then
  4.         return SYSTEMS:GetObject("alchemy"):IsItemAlreadySlottedToCraft(bag, slot)
  5.     elseif ZO_Enchanting_IsSceneShowing() then
  6.         return ZO_Enchanting_GetVisibleEnchanting():IsItemAlreadySlottedToCraft(bag, slot)
  7.     elseif ZO_Smithing_IsSceneShowing() then
  8.         return ZO_Smithing_GetActiveObject():IsItemAlreadySlottedToCraft(bag, slot)
  9.     elseif ZO_RETRAIT_STATION_MANAGER:IsRetraitSceneShowing() then
  10.         return SYSTEMS:GetObject("retrait"):IsItemAlreadySlottedToCraft(bag, slot)
  11.     end
  12.     return false
  13. end

Phuein 04/23/18 10:58 AM

Quote:

Originally Posted by Baertram (Post 34502)
If you want to use the funciton but it is local, just copy&paste it to your code?

Lua Code:
  1. local function IsItemAlreadySlottedToCraft(inventorySlot)
  2.     local bag, slot = ZO_Inventory_GetBagAndIndex(inventorySlot)
  3.     if SYSTEMS:IsShowing("alchemy") then
  4.         return SYSTEMS:GetObject("alchemy"):IsItemAlreadySlottedToCraft(bag, slot)
  5.     elseif ZO_Enchanting_IsSceneShowing() then
  6.         return ZO_Enchanting_GetVisibleEnchanting():IsItemAlreadySlottedToCraft(bag, slot)
  7.     elseif ZO_Smithing_IsSceneShowing() then
  8.         return ZO_Smithing_GetActiveObject():IsItemAlreadySlottedToCraft(bag, slot)
  9.     elseif ZO_RETRAIT_STATION_MANAGER:IsRetraitSceneShowing() then
  10.         return SYSTEMS:GetObject("retrait"):IsItemAlreadySlottedToCraft(bag, slot)
  11.     end
  12.     return false
  13. end


No way. Then it can break at any update. The whole purpose of me asking for this is to stick to game code, so I don't need to worry about game dev changes to this mechanism.

Baertram 04/23/18 07:42 PM

As the function is local you cannot access it. If it changes you need to adopt it in your code.
Or find another solution like getting the control names of the slots and check if the slot is filed within your addon (which might brake as well as they decide to change control names or function names or whatever).
There is no "safe way".

Phuein 04/25/18 07:19 AM

Quote:

Originally Posted by Baertram (Post 34518)
As the function is local you cannot access it. If it changes you need to adopt it in your code.
Or find another solution like getting the control names of the slots and check if the slot is filed within your addon (which might brake as well as they decide to change control names or function names or whatever).
There is no "safe way".


That is exactly the answer I have not been looking for, as I've repeatedly said. It makes no sense that I can't implement Locking into my addon the same way the game does, and if that's the case, then I should report it to the dev' team.


All times are GMT -6. The time now is 01:34 PM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2014 - 2022 MMOUI