Compare with Previous | Blame | View Log
--[[
***********************************************************************************
Copyright (c) 2014, saykoaddon
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
[1] Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
[2] Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
[3] Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
***********************************************************************************
]]
------- ItemLock Class ----------------------
ItemLock = ZO_Object:Subclass()
local DECONSTRUCTION_BAG = ZO_SmithingTopLevelDeconstructionPanelInventoryBackpackContents
-- Creates variables
function ItemLock:New()
ItemLock.name = "ItemLock"
ItemLock.version = 2
ItemLock.eventHandlers = {}
ItemLock.list = ZO_SavedVars:New(ItemLock.name .. "_SavedVariables", 1, "list", {}, nil)
ItemLock.settings = ZO_SavedVars:New(ItemLock.name .. "_SavedVariables", 1, "settings", { isActive = true }, nil)
ItemLock.settings.isActive = true -- <= REMOVE THIS LINE TO KEEP SETTINGS BETWEEN SESSIONS
end
-- Initializes event handlers and chat commands
function ItemLock:Init()
EVENT_MANAGER:RegisterForEvent( ItemLock.name .. "_OnInventorySlotLocked", EVENT_INVENTORY_SLOT_LOCKED, ItemLock_OnInventorySlotLocked )
ZO_CreateStringId("SI_BINDING_NAME_ITEM_LOCK_TOGGLE_ENABLE", "Enable/Disable")
ZO_CreateStringId("SI_BINDING_NAME_ITEM_LOCK_TOGGLE_LOCK", "Lock/Unlock")
SLASH_COMMANDS["/itemlock"] = ItemLock.ToggleEnable
-- override event handlers of DECONSTRUCTION_BAG, it is used to update item controls' event handlers
ItemLock:PreHookHandler( "OnEffectivelyShown", DECONSTRUCTION_BAG, ItemLock_DECONSTRUCTION_BAG_OnEffectivelyShown )
ItemLock:PreHookHandler( "OnMouseWheel", DECONSTRUCTION_BAG, ItemLock_DECONSTRUCTION_BAG_OnMouseWheel )
end
-- activates item protection
function ItemLock:Activate()
ItemLock.settings.isActive = true
CHAT_SYSTEM:AddMessage( ItemLock.name .. " is on")
end
-- deactivates item protection
function ItemLock:Deactivate()
ItemLock.settings.isActive = false
CHAT_SYSTEM:AddMessage( ItemLock.name .. " is off")
end
-- returns protection status
function ItemLock:IsActive()
return ItemLock.settings.isActive
end
-- toggles item protection
function ItemLock:ToggleEnable()
if (ItemLock:IsActive()) then
ItemLock:Deactivate()
else
ItemLock:Activate()
end
end
-- checks if item is in protection list
function ItemLock:IsItemLocked(itemId)
return itemId and ItemLock.list[itemId]
end
-- adds item to protection list
function ItemLock:LockItem(itemId)
if( not itemId ) then return end
ItemLock.list[itemId] = 1
end
-- removes item from protection list
function ItemLock:UnlockItem(itemId)
if( not itemId ) then return end
ItemLock.list[itemId] = nil
end
-- toggles item's protection status by manipulating protection list
function ItemLock:ToggleLock()
local control = WINDOW_MANAGER:GetMouseOverControl()
-- make sure control contains an item
if( not control or not control.dataEntry or not control.dataEntry.data ) then return nil end
local bag = control.dataEntry.data.bagId
local slot = control.dataEntry.data.slotIndex
-- make sure control contains an item
if( not bag or not slot ) then return nil end
-- get instance id of the item, this value is persistant across all game and sessions
local id = GetItemInstanceId(bag, slot)
if( not id ) then return nil end
-- convert to string to prevent negative number error of saved vars
local idStr = tostring(id)
-- check if item is in the protection list
if( ItemLock:IsItemLocked(idStr) ) then
ItemLock:UnlockItem(idStr)
CHAT_SYSTEM:AddMessage( GetItemLink(bag, slot, LINK_STYLE_BRACKETS) .. " has been unlocked")
else
ItemLock:LockItem(idStr)
CHAT_SYSTEM:AddMessage( GetItemLink(bag, slot, LINK_STYLE_BRACKETS) .. " has been locked")
end
end
-- warns user with a chat message
function ItemLock:WarnUser(bag, slot)
CHAT_SYSTEM:AddMessage( "WARNING!!!!" )
CHAT_SYSTEM:AddMessage( "You are trying to deconstruct a locked item" )
CHAT_SYSTEM:AddMessage( "Item: " .. GetItemLink(bag, slot, LINK_STYLE_BRACKETS) )
end
-- fired when user selects an item to deconstruct
-- warns user if the item is in protection list
function ItemLock:DeconstructionSelectionHandler(bag, slot)
-- make sure user is on deconstruction panel
if( not DECONSTRUCTION_BAG or DECONSTRUCTION_BAG:IsHidden() ) then return nil end
-- if not active then abort checking
if( not ItemLock:IsActive() ) then return nil end
-- get instance id of the item, this value is persistant across all game
local id = GetItemInstanceId(bag, slot)
-- convert to string to prevent negative number error of saved vars
local idStr = tostring(id)
-- if item is in protection list, warn user
if( ItemLock:IsItemLocked(idStr) ) then
ItemLock:WarnUser(bag, slot)
return true
end
return false
end
-- gets handler from the event handler list
function ItemLock:GetEventHandler(eventName, objName)
if( not ItemLock.eventHandlers or not ItemLock.eventHandlers[eventName] ) then return nil end
return ItemLock.eventHandlers[eventName][objName]
end
-- adds handler to the event handler list
function ItemLock:SetEventHandler(eventName, objName, handler)
if ( not ItemLock.eventHandlers[eventName] ) then ItemLock.eventHandlers[eventName] = {} end
ItemLock.eventHandlers[eventName][objName] = handler
end
-- puts given handler in front of the event handler of given object
function ItemLock:PreHookHandler(eventName, control, handler)
ItemLock:SetEventHandler(eventName, control:GetName(), control:GetHandler(eventName) )
control:SetHandler(eventName, handler)
end
-----------------------------------------
-- EVENT HANDLER FUNCTIONS -----
-- handler function for inventory item controls' OnMouseDoubleClick event
function ItemLock_InventoryItem_OnMouseDoubleClick(self, ...)
-- make sure control contains an item
if( self and self.dataEntry and self.dataEntry.data ) then
local bag = self.dataEntry.data.bagId
local slot = self.dataEntry.data.slotIndex
if( bag and slot ) then
-- check if deconstruction is forbidden
-- if so, return false to prevent selection of the item
if( ItemLock:DeconstructionSelectionHandler(bag, slot) ) then return false end
end
end
-- call the original handler function
local func = ItemLock:GetEventHandler("OnMouseDoubleClick", self:GetName())
if ( not func ) then return false end
return func(self, ...)
end
-- handler function for EVENT_INVENTORY_SLOT_LOCKED global event
function ItemLock_OnInventorySlotLocked(self, bag, slot)
-- check if deconstruction is forbidden
-- if so, clear item hold by cursor
if( ItemLock:DeconstructionSelectionHandler(bag, slot) ) then ClearCursor() end
end
-- handler function for decontruction bag's OnEffectivelyShown event
function ItemLock_DECONSTRUCTION_BAG_OnEffectivelyShown(self, ...)
if ( not self ) then return false end
for i = 1, self:GetNumChildren() do
-- override OnMouseDoubleClick event of inventory item controls
if( self:GetChild(i):GetHandler("OnMouseDoubleClick") ~= ItemLock_InventoryItem_OnMouseDoubleClick ) then
ItemLock:PreHookHandler( "OnMouseDoubleClick", self:GetChild(i), ItemLock_InventoryItem_OnMouseDoubleClick )
end
end
-- call the original handler function
local func = ItemLock:GetEventHandler("OnEffectivelyShown", self:GetName())
if ( not func ) then return false end
return func(self, ...)
end
-- handler function for decontruction bag's OnMouseWheel event
function ItemLock_DECONSTRUCTION_BAG_OnMouseWheel(self, ...)
if ( not self ) then return false end
for i = 1, self:GetNumChildren() do
-- override OnMouseDoubleClick event of inventory item controls
if( self:GetChild(i):GetHandler("OnMouseDoubleClick") ~= ItemLock_InventoryItem_OnMouseDoubleClick ) then
ItemLock:PreHookHandler( "OnMouseDoubleClick", self:GetChild(i), ItemLock_InventoryItem_OnMouseDoubleClick )
end
end
-- call the original handler function
local func = ItemLock:GetEventHandler("OnMouseWheel", self:GetName())
if ( not func ) then return false end
return func(self, ...)
end
-----------------------------------------
------- Entry Point ----------------
local function OnAddOnLoaded(eventCode, addOnName)
if (addOnName ~= "ItemLock") then
return
end
-- create and initialize variables
ItemLock:New()
ItemLock:Init()
end
------- Entry Point Register --------
EVENT_MANAGER:RegisterForEvent("Event_ItemLock_Loaded", EVENT_ADD_ON_LOADED, OnAddOnLoaded)