Thread Tools Display Modes
04/17/18, 07:23 PM   #1
Phuein
 
Phuein's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2018
Posts: 132
Question 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
  Reply With Quote
04/17/18, 08:53 PM   #2
eventHandler
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 12
Originally Posted by Phuein View Post
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.
  Reply With Quote
04/17/18, 08:54 PM   #3
Rhyono
AddOn Author - Click to view addons
Join Date: Sep 2016
Posts: 659
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

Last edited by Rhyono : 04/19/18 at 12:38 PM. Reason: Fixed for future viewers
  Reply With Quote
04/18/18, 01:34 AM   #4
Dolgubon
 
Dolgubon's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2016
Posts: 408
Originally Posted by Phuein View Post
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.
  Reply With Quote
04/18/18, 11:44 AM   #5
Phuein
 
Phuein's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2018
Posts: 132
Originally Posted by Rhyono View Post
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

Last edited by Phuein : 04/18/18 at 07:53 PM.
  Reply With Quote
04/19/18, 08:05 AM   #6
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,912
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.
  Reply With Quote
04/19/18, 11:56 AM   #7
Phuein
 
Phuein's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2018
Posts: 132
Originally Posted by Baertram View Post
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.

Last edited by Phuein : 04/19/18 at 11:59 AM.
  Reply With Quote
04/19/18, 02:05 PM   #8
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,912
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?
Checking type on argument slotIndex failed in IsSlotLocked_lua
  Reply With Quote
04/20/18, 01:38 PM   #9
Phuein
 
Phuein's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2018
Posts: 132
Originally Posted by Baertram View Post
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()?

Last edited by Phuein : 04/20/18 at 02:17 PM.
  Reply With Quote
04/20/18, 02:56 PM   #10
Rhyono
AddOn Author - Click to view addons
Join Date: Sep 2016
Posts: 659
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?).
  Reply With Quote
04/21/18, 01:43 PM   #11
Phuein
 
Phuein's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2018
Posts: 132
Originally Posted by Rhyono View Post
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.
  Reply With Quote
04/21/18, 03:44 PM   #12
Rhyono
AddOn Author - Click to view addons
Join Date: Sep 2016
Posts: 659
Sorry, I didn't specify properly: I was talking about IsItemAlreadySlottedToCraft()
  Reply With Quote
04/22/18, 12:11 PM   #13
Phuein
 
Phuein's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2018
Posts: 132
Originally Posted by Rhyono View Post
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.
  Reply With Quote
04/22/18, 12:17 PM   #14
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,912
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
  Reply With Quote
04/23/18, 10:58 AM   #15
Phuein
 
Phuein's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2018
Posts: 132
Originally Posted by Baertram View Post
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.
  Reply With Quote
04/23/18, 07:42 PM   #16
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,912
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".
  Reply With Quote
04/25/18, 07:19 AM   #17
Phuein
 
Phuein's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2018
Posts: 132
Originally Posted by Baertram View Post
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.
  Reply With Quote

ESOUI » Developer Discussions » General Authoring Discussion » How to lock an item?

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off