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)