You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

307 lines
10 KiB

--========================================================--
-- Scorpio Secure Bag Handler --
-- --
-- Author : kurapica125@outlook.com --
-- Create Date : 2021/03/29 --
--========================================================--
--========================================================--
Scorpio "Scorpio.Secure.BagHandler" "1.0.0"
--========================================================--
__Sealed__() enum "BagSlotCountStyle" { "Hidden", "Empty", "Total", "AllEmpty", "All" }
_Enabled = false
------------------------------------------------------
-- Action Handler
------------------------------------------------------
handler = ActionTypeHandler {
Name = "bag",
DragStyle = "Keep",
ReceiveStyle = "Keep",
InitSnippet = [[ _BagSlotMap = newtable() ]],
PickupSnippet = [[
local id = ...
if id ~= 0 then
Manager:CallMethod("CloseContainerForSafe", id)
return "clear", "bag", _BagSlotMap[id]
end
]],
ReceiveSnippet = "Custom",
UpdateSnippet = [[
local target = ...
target = tonumber(target)
if target == 0 then
self:SetAttribute("*type*", "macro")
self:SetAttribute("*macrotext*", "/click MainMenuBarBackpackButton")
elseif target and target <= 4 then
self:SetAttribute("*type*", "macro")
self:SetAttribute("*macrotext*", "/click CharacterBag".. tostring(target-1) .."Slot")
elseif target and target <= 11 then
self:SetAttribute("*type*", "openbank")
Manager:CallMethod("RegisterBankBag", self:GetName())
else
self:SetAttribute("*type*", nil)
self:SetAttribute("*macrotext*", nil)
Manager:CallMethod("UnregisterBankBag", self:GetName())
end
]],
ClearSnippet = [[
self:SetAttribute("*type*", nil)
self:SetAttribute("*macrotext*", nil)
Manager:CallMethod("UnregisterBankBag", self:GetName())
]],
OnEnableChanged = function(self, value) _Enabled = value end,
}
------------------------------------------------------
-- Module Event Handler
------------------------------------------------------
_BagSlotMapTemplate = "_BagSlotMap[%d] = %d"
_, _EmptyTexture = GetInventorySlotInfo("Bag0Slot")
_BagSlotMap = {}
_ContainerMap = {}
_IconLocked = {}
function OnEnable(self)
OnEnable = nil
local cache = {}
-- Container
_BagSlotMap[0] = GetInventorySlotInfo("BackSlot")
for i = 1, 11 do
_BagSlotMap[i] = ContainerIDToInventoryID(i)
tinsert(cache, _BagSlotMapTemplate:format(i, _BagSlotMap[i]))
end
handler:RunSnippet( tblconcat(cache, ";") )
handler:RefreshActionButtons()
for i = 1, NUM_CONTAINER_FRAMES do
SecureActionButton.RegisterContainer(_G["ContainerFrame"..i])
end
end
------------------------------------------------------
-- System Event Handler
------------------------------------------------------
__SystemEvent__()
function ITEM_LOCK_CHANGED(bag, slot)
if not slot then
for i, map in pairs(_BagSlotMap) do
if map == bag then
_IconLocked[i] = IsInventoryItemLocked(bag)
return handler:RefreshIconLocked()
end
end
end
end
__SystemEvent__"BAG_UPDATE_DELAYED" "PLAYERBANKBAGSLOTS_CHANGED"
function BAG_UPDATE_DELAYED()
return handler:RefreshActionButtons()
end
__SystemEvent__()
function PLAYERBANKSLOTS_CHANGED(slot)
if slot > NUM_BANKGENERIC_SLOTS then
slot = slot - NUM_BANKGENERIC_SLOTS + NUM_BAG_FRAMES
for _, btn in handler:GetIterator() do
if btn.ActionTarget == slot then
handler:RefreshActionButtons(btn)
end
end
end
end
__SystemEvent__()
function INVENTORY_SEARCH_UPDATE()
return handler:RefreshShowSearchOverlay()
end
__SecureMethod__() __NoCombat__()
function handler.Manager:RegisterBankBag(btnName)
_G[btnName]:SetAttribute("_openbank", [=[ self:GetFrameRef("_Manager"):RunFor(self, [[ Manager:CallMethod("OpenBankBag", self:GetName()) ]]) ]=])
end
__SecureMethod__() __NoCombat__()
function handler.Manager:UnregisterBankBag(btnName)
_G[btnName]:SetAttribute("_openbank", nil)
end
__SecureMethod__()
function handler.Manager:OpenBankBag(btnName)
local button = UI.GetProxyUI(_G[btnName])
local bankID = button.BagSlot
if bankID and not InCombatLockdown() then
local inventoryID = BankButtonIDToInvSlotID(bankID - 4, 1)
if not PutItemInBag(inventoryID) then
-- open bag
ToggleBag(bankID)
end
end
end
__SecureMethod__()
function handler.Manager:CloseContainerForSafe(id)
if id and not InCombatLockdown() then
CloseBag(id)
end
end
-- Overridable Methods
function handler:IsUsableAction()
return self.ActionTarget - 4 <= GetNumBankSlots()
end
function handler:ReceiveAction(target, detail)
if target == 0 then
return PutItemInBackpack()
elseif _BagSlotMap[target] then
return PutItemInBag(_BagSlotMap[target])
end
end
function handler:HasAction()
return _BagSlotMap[self.ActionTarget] and true or false
end
function handler:IsSearchOverlayShow()
return IsContainerFiltered(self.ActionTarget)
end
function handler:IsIconLocked()
return _IconLocked[self.ActionTarget] or false
end
function handler:GetActionTexture()
if self.ActionTarget == 0 then return MainMenuBarBackpackButtonIconTexture:GetTexture() end
local target = _BagSlotMap[self.ActionTarget]
return target and GetInventoryItemTexture("player", target) or _EmptyTexture
end
function handler:GetActionCharges()
local style = self.BagSlotCountStyle
if style == "Hidden" then
return nil
elseif style == "Empty" or style == "Total" then
local free, total = GetContainerNumFreeSlots(self.ActionTarget), GetContainerNumSlots(self.ActionTarget)
if style == "Empty" then
return free, total
else
return total, total
end
elseif style == "AllEmpty" or style == "All" then
if self.ActionTarget <= 4 then
local sFree, sTotal, free, total, bagFamily = 0, 0
local _, tarFamily = GetContainerNumFreeSlots(self.ActionTarget)
if not tarFamily then return nil end
for i = BACKPACK_CONTAINER, NUM_BAG_SLOTS do
free, bagFamily = GetContainerNumFreeSlots(i)
total = GetContainerNumSlots(i)
if bagFamily == tarFamily then
sFree = sFree + free
sTotal = sTotal + total
end
end
if self.ActionTarget == 0 then
self.__BagHandler_FreeSlots = sFree
end
if style == "AllEmpty" then
return sFree, sTotal
else
return sTotal, sTotal
end
else
return nil
end
end
end
function handler:IsActivedAction()
local id = self.ActionTarget
for container in pairs(_ContainerMap) do
if container:GetID() == id and container:IsVisible() then
return true
end
end
return false
end
function handler:SetTooltip(tip)
local target = self.ActionTarget
if target == 0 then
tip:SetText(BACKPACK_TOOLTIP, 1.0, 1.0, 1.0)
local keyBinding = GetBindingKey("TOGGLEBACKPACK")
if ( keyBinding ) then
tip:AppendText(" "..NORMAL_FONT_COLOR_CODE.."("..keyBinding..")"..FONT_COLOR_CODE_CLOSE)
end
tip:AddLine(string.format(NUM_FREE_SLOTS, (self.__BagHandler_FreeSlots or 0)))
tip:Show()
elseif _BagSlotMap[target] then
local id = _BagSlotMap[target]
if ( tip:SetInventoryItem("player", id) ) then
if id <= 4 then
local bindingKey = GetBindingKey("TOGGLEBAG"..(5 - target))
if ( bindingKey ) then
tip:AppendText(" "..NORMAL_FONT_COLOR_CODE.."("..bindingKey..")"..FONT_COLOR_CODE_CLOSE)
end
end
if (not IsInventoryItemProfessionBag("player", ContainerIDToInventoryID(target))) then
for i = LE_BAG_FILTER_FLAG_EQUIPMENT, NUM_LE_BAG_FILTER_FLAGS do
if ( GetBagSlotFlag(target, i) ) then
tip:AddLine(BAG_FILTER_ASSIGNED_TO:format(BAG_FILTER_LABELS[i]))
break
end
end
end
tip:Show()
else
tip:SetText(EQUIP_CONTAINER, 1.0, 1.0, 1.0)
end
else
end
end
-- Expand IFActionHandler
class "SecureActionButton" (function(_ENV)
local function OnShowOrHide(self)
return handler:RefreshButtonState()
end
------------------------------------------------------
-- Static Method
------------------------------------------------------
__Static__() __Arguments__{ UI }
function RegisterContainer(container)
if _ContainerMap[container] then return end
_ContainerMap[container]= true
container:HookScript("OnShow", OnShowOrHide)
container:HookScript("OnHide", OnShowOrHide)
end
------------------------------------------------------
-- Property
------------------------------------------------------
--- What to be shown as the count
property "BagSlotCountStyle" { type = BagSlotCountStyle, default = "Hidden", handler = function(self) return handler:RefreshCount(self) end }
end)