if Debug then Debug.beginFile "TasFlashyCommandButton" end
do
--[[ TasFlashyCommandButtonV3a by Tasyen
A small system to display "autocast" sprites on commandbuttons while some wanted condition is fullfilled.
Only works correct in single unit selection, does not support spellbooks, nor built menues.
Abilities should have no colisions in command card.
TasFlashyCommandButton.Remove(who)
removes and returns an activ entry (table)
who can be an integer aka index or a table.
TasFlashyCommandButton(model, buttonIndex, name, condition, requiredSpell)
can be used to readd a removed entry in this case give the table instead of model.
when requiredSpell provided, unit needs to have atleast level 1 to show it in the UI, can be either a FourCC or a FourCCString
buttonIndex is the index of the command button (0-11). Can also be a spellCode or fourCC. Then it uses the button position of that spell.
name is for you to access it by BlzGetFrameByName(name, 0)
returns the new obj inside TasFlashyCommandButton
will create warcraft 3 objects, do not use in Lua Root.
checks all models on every timeout
Does not work for observers
condition can be a trigger, function, string or Lua table.
trigger -> TriggerEvaluate use udg_TasFlashyCommandButtonUnit
function(unit, sprite, data) return true to show it right now.
string -> global array with that name has 1 or more for current Unit the limit 1 can be changed with array.TasFlashy = x
table -> like string, but works less good with a table made with __jarray(0) and dont need to be a global table
beaware, the condition is called in GetLocalPlayer context
-- example show autocast model on blizzard while it is day
TasFlashyCommandButton("UI/Feedback/Autocast/UI-ModalButtonOn.mdx", 'AHbz', "BlizzardDaySprite",
function(unit, sprite, data) return bj_dncIsDaytime end
, 'AHbz')
-- example show autocast model on attack while current order is attack
OrderAttack = OrderId("attack")
TasFlashyCommandButton("UI/Feedback/Autocast/UI-ModalButtonOn.mdx", 3, "AttackSprite",
function(unit, sprite, data) return GetUnitCurrentOrder(unit) == OrderAttack end
, 'Aatk')
TasFlashyCommandButton("UI/Feedback/Autocast/UI-ModalButtonOn.mdx", 3, "AttackSprite", "udg_MyArray" , 'Aatk')
show a sprite when global array with the name "udg_MyArray" has 1 or more for current Unit
you can change the req value with udg_MyArray.TasFlashy = 5
MyLuaArray = {}
MyLuaArray = __jarray(0)
TasFlashyCommandButton("UI/Feedback/Autocast/UI-ModalButtonOn.mdx", 3, "AttackSprite", MyLuaArray , 'Aatk')
MyLuaArray[udg_Unit] = 1
MyLuaArray.TasFlashy = 5 -- default 1 but not with __jarray(0)
TasFlashyCommandButton("UI/Feedback/Autocast/UI-ModalButtonOn.mdx", 3, "AttackSprite", gg_trg_Trigger, 'Aatk')
udg_TasFlashyCommandButtonUnit is the current Unit use the conditions when they return true it is okay.
]]
local this ={
data = {}
,unit = {}
}
setmetatable(this, {__call = function(table, model, buttonIndex, name, conditionFunc, spellCode) return this.Add(model, buttonIndex, name, conditionFunc, spellCode) end})
local lastXSize = 0
TasFlashyCommandButton = this
local function CreateFrame(model, index, name)
local sprite = BlzCreateFrameByType("SPRITE", name, this.Parent, "", 0)
BlzFrameSetSize(sprite, 0.0001, 0.0001)
BlzFrameSetModel(sprite, model, 0)
BlzFrameSetVisible(sprite, false)
BlzFrameSetPoint(sprite, FRAMEPOINT_BOTTOMLEFT, BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON, index), FRAMEPOINT_BOTTOMLEFT, 0, 0)
return sprite
end
local function ReCreateFrames()
-- reserve
for i = 0, 11 do BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON, i) end
this.Parent = BlzGetFrameByName("ConsoleUIBackdrop", 0)
-- (re)make custom frames
this.Parent = BlzCreateFrameByType("FRAME", "", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", 0)
lastXSize = 0
for i, data in ipairs(this.data) do
data[4] = CreateFrame(data[1], data[2], data[3])
end
end
function this.Update()
local unit = this.unit[GetLocalPlayer()]
local show = true
if not unit then show = false end
local hasControl = show and (IsUnitOwnedByPlayer(unit, GetLocalPlayer()) or GetPlayerAlliance(GetOwningPlayer(unit), GetLocalPlayer(), ALLIANCE_SHARED_CONTROL))
if not hasControl then show = false end
-- use hud UIscale
if BlzFrameGetChild then -- when this native exists it could be reforged
local newSize = BlzFrameGetWidth(BlzGetFrameByName("ConsoleUIBackdrop", 0))
if newSize ~= lastXSize then
lastXSize = newSize
BlzFrameSetScale(this.Parent, newSize/0.8)
end
end
for i, data in ipairs(this.data) do
if show and (data[6] <= 0 or GetUnitAbilityLevel(unit, data[6]) > 0) then
local frame = data[4]
local filterData = data[5]
local filterDataType = type(filterData)
if filterDataType == "function" then
BlzFrameSetVisible(frame, filterData(unit, frame, data))
elseif filterDataType == "table" then
BlzFrameSetVisible(frame, (filterData[unit] or 0) >= (filterData.TasFlashy or 1))
elseif filterDataType == "string" then -- gui
if _G[filterData] then BlzFrameSetVisible(frame, _G[filterData][unit] >= math.max(_G[filterData].TasFlashy, 1)) end
elseif filterDataType == "userdata" then -- gui trigger
udg_TasFlashyCommandButtonUnit = unit
if filterData then BlzFrameSetVisible(frame, TriggerEvaluate(filterData)) end
end
else
BlzFrameSetVisible(data[4], false)
end
end
unit = nil
end
function this.Remove(who)
local obj = nil
if type(who) == "number" then
obj = table.remove( this.data, who)
else
for i, data in ipairs(this.data) do if who == data then obj = table.remove(this.data, i) break end end
end
BlzFrameSetVisible(obj[4], false)
return obj
end
function this.Add(model, buttonIndex, name, conditionFunc, spellCode)
if not this.Timer then
this.Timer = CreateTimer()
TimerStart(this.Timer, 0.2, true, this.Update)
local trig = CreateTrigger()
TriggerAddAction(trig, function() this.unit[GetTriggerPlayer()] = GetTriggerUnit() end)
TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_SELECTED)
ReCreateFrames()
if FrameLoaderAdd then FrameLoaderAdd(ReCreateFrames) end
end
if type(model) == "table" then
table.insert(this.data, model)
return model
else
if type(spellCode) == "string" then spellCode = FourCC(spellCode) end
if type(buttonIndex) == "string" then buttonIndex = FourCC(buttonIndex) end
if buttonIndex > 11 then buttonIndex = BlzGetAbilityPosX(spellCode)+ BlzGetAbilityPosY(spellCode)*4 end
name = name or ""
local newobj = {model, buttonIndex, name, CreateFrame(model, buttonIndex, name), conditionFunc, spellCode or 0}
table.insert(this.data, newobj)
return newobj
end
end
end
if Debug then Debug.endFile() end