This commit is contained in:
Bunny67
2017-12-23 14:08:21 +03:00
parent 1fdd15d497
commit 49fd843612
14 changed files with 905 additions and 2263 deletions
+1 -9
View File
@@ -11,16 +11,8 @@ local registerEvent = frame_metatable.__index.RegisterEvent
local unregisterEvent = frame_metatable.__index.UnregisterEvent
function Private.UpdateUnits(frame, unit, realUnit)
if(unit == realUnit) then
realUnit = nil
end
if(frame.unit ~= unit or frame.realUnit ~= realUnit) then
frame.unit = unit
frame.realUnit = realUnit
frame.id = string.match(unit, '^.-(%d+)')
return true
end
return true
end
local function onEvent()
+3
View File
@@ -1,4 +1,7 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/">
<Script file="templates.lua"/>
<Include file="templates.xml"/>
<Script file="init.lua"/>
<Script file="private.lua"/>
<Script file="ouf.lua"/>
+53 -105
View File
@@ -14,64 +14,6 @@ local callback, units, objects, headers = {}, {}, {}, {}
local elements = {}
local activeElements = {}
local pairs = pairs
local unitExistsWatchers = {}
local unitExistsCache = setmetatable({},{
__index = function(t, k)
local v = UnitExists(k) or false
t[k] = v
return v
end
})
local function updateUnitWatch(frame)
local unit = frame.unit
local exists = (unit and unitExistsCache[unit])
if exists then
frame:Show()
else
frame:Hide()
end
end
local unitWatch = CreateFrame("Frame")
unitWatch:Hide()
local timer = 0
unitWatch:SetScript("OnUpdate", function()
timer = timer - arg1
if timer <= 0 then
timer = 0.2
for k in pairs(unitExistsCache) do
unitExistsCache[k] = nil
end
for frame in pairs(unitExistsWatchers) do
updateUnitWatch(frame)
end
end
end)
unitWatch:SetScript("OnEvent", function() timer = 0 end)
unitWatch:RegisterEvent("PLAYER_TARGET_CHANGED")
unitWatch:RegisterEvent("PLAYER_FOCUS_CHANGED")
unitWatch:RegisterEvent("PLAYER_REGEN_DISABLED")
unitWatch:RegisterEvent("PLAYER_REGEN_ENABLED")
unitWatch:RegisterEvent("UNIT_PET")
unitWatch:RegisterEvent("RAID_ROSTER_UPDATE")
unitWatch:RegisterEvent("PARTY_MEMBERS_CHANGED")
local function RegisterUnitWatch(frame)
unitExistsWatchers[frame] = true
unitWatch:Show()
updateUnitWatch(frame)
end
local function UnregisterUnitWatch(frame)
unitExistsWatchers[frame] = nil
end
-- updating of "invalid" units.
local function enableTargetUpdate(object)
object.onUpdateFrequency = object.onUpdateFrequency or .5
@@ -267,6 +209,12 @@ for k, v in next, {
self:PostUpdate(event)
end
end,
SetUnit = function(self, unit)
if unit ~= unit then
self.unit = unit
end
end,
} do
frame_metatable.__index[k] = v
end
@@ -335,7 +283,7 @@ local function initObject(unit, style, styleFunc, header, ...)
for i = 1, num do
local object = arg[i]
local objectUnit = object.guessUnit or unit
local suffix = "ery"
local suffix = string.match(objectUnit or unit, '%w+target')
object.__elements = {}
object.__registeredEvents = {}
@@ -352,19 +300,21 @@ local function initObject(unit, style, styleFunc, header, ...)
-- No header means it's a frame created through :Spawn().
object.menu = togglemenu
object:SetScript("OnClick", function()
TargetUnit(unit)
TargetUnit(object.unit)
end)
-- Other target units are handled by :HandleUnit().
if(suffix == 'target') then
enableTargetUpdate(object)
else
oUF:HandleUnit(object)
oUF:HandleUnit(object, unit)
end
else
-- Used to update frames when they change position in a group.
object:RegisterEvent('RAID_ROSTER_UPDATE', object.UpdateAllElements)
object:SetScript("OnClick", function()
TargetUnit(object.unit)
end)
if(num > 1) then
if(object:GetParent() == header) then
object.hasChildren = true
@@ -410,7 +360,7 @@ local function walkObject(object, unit)
-- Check if we should leave the main frame blank.
if(object.onlyProcessChildren) then
object.hasChildren = true
object:SetScript('OnAttributeChanged', onAttributeChanged)
--object:SetScript('OnAttributeChanged', onAttributeChanged)
return initObject(unit, style, styleFunc, header, object:GetChildren())
end
@@ -581,56 +531,47 @@ do
-- There has to be an easier way to do this.
local initialConfigFunction = function(self)
local header = self:GetParent()
for i = 1, select('#', self), 1 do
local frame = select(i, self)
local unit
-- There's no need to do anything on frames with onlyProcessChildren
if(not frame.onlyProcessChildren) then
-- Attempt to guess what the header is set to spawn.
local groupFilter = header:GetAttribute('groupFilter')
if(type(groupFilter) == 'string' and groupFilter:match('MAIN[AT]')) then
local role = groupFilter:match('MAIN([AT])')
if(role == 'T') then
unit = 'maintank'
else
unit = 'mainassist'
end
elseif(header:GetAttribute('showRaid')) then
unit = 'raid'
elseif(header:GetAttribute('showParty')) then
unit = 'party'
end
local unit
if(not self.onlyProcessChildren) then
local groupFilter = header:GetAttribute('groupFilter')
local headerType = header.headerType
local suffix = frame:GetAttribute('unitsuffix')
if(unit and suffix) then
if(headerType == 'pet' and suffix == 'target') then
unit = unit .. headerType .. suffix
else
unit = unit .. suffix
end
elseif(unit and headerType == 'pet') then
unit = unit .. headerType
end
frame.menu = togglemenu
frame:SetAttribute('type1', 'target')
frame:SetAttribute('type2', 'menu')
frame.guessUnit = unit
if(header:GetAttribute('showRaid')) then
unit = 'raid'
elseif(header:GetAttribute('showParty')) then
unit = 'party'
end
self.menu = togglemenu
--self:SetAttribute('type1', 'target')
--self:SetAttribute('type2', 'menu')
self.guessUnit = unit
self.unit = "player"
-- self.onlyProcessChildren =true
end
header:styleFunction(self:GetName())
styleProxy(nil, self:GetName())
end
local setAttribute = function(self, name, value)
if self.attributes[name] ~= value then
self.attributes[name] = value
if self:IsVisible() then
SecureGroupHeader_Update(self)
end
end
end
local getAttribute = function(self, name)
return self.attributes[name]
end
--[[ oUF:SpawnHeader(overrideName, template, visibility, ...)
Used to create a group header and apply the currently active style to it.
* self - the global oUF object
* overrideName - unique global name to be used for the header. Defaults to an auto-generated name based on the name
of the active style and other arguments passed to `:SpawnHeader` (string?)
* template - name of a template to be used for creating the header. Defaults to `'SecureGroupHeaderTemplate'`
* template - name of a template to be used for creating the header. Defaults to `'oUF_GroupHeaderTemplate'`
(string?)
* visibility - macro conditional(s) which define when to display the header (string).
* ... - further argument pairs. Consult [Group Headers](http://wowprogramming.com/docs/secure_template/Group_Headers)
@@ -646,16 +587,22 @@ do
function oUF:SpawnHeader(overrideName, template, visibility, ...)
if(not style) then return error('Unable to create frame. No styles have been registered.') end
template = (template or 'SecureGroupHeaderTemplate')
template = (template or 'oUF_GroupHeaderTemplate')
local isPetHeader = string.match(template, 'PetHeader')
local name = overrideName or generateName(nil, unpack(arg))
local header = CreateFrame('Frame', name, UIParent, template)
header:Hide()
header:SetAttribute('template', 'SecureUnitButtonTemplate')
for i = 1, select('#', arg), 2 do
header.attributes = {}
header.SetAttribute = setAttribute
header.GetAttribute = getAttribute
--header:SetAttribute('template', 'SecureUnitButtonTemplate')
for i = 1, getn(arg), 2 do
local att, val = select(i, unpack(arg))
if(not att) then break end
header:SetAttribute(att, val)
end
@@ -673,7 +620,8 @@ do
self:DisableBlizzard('party')
end
if(visibility) then
--[[if(visibility) then
local type, list = string.split(' ', visibility, 2)
if(list and type == 'custom') then
RegisterStateDriver(header, 'visibility', list)
@@ -683,7 +631,7 @@ do
RegisterStateDriver(header, 'visibility', condition)
header.visibility = condition
end
end
end]]
return header
end
@@ -0,0 +1,461 @@
local pairs = pairs
local ipairs = ipairs
local unitExistsWatchers = {}
local unitExistsCache = setmetatable({},{
__index = function(t, k)
local v = UnitExists(k) or false
t[k] = v
return v
end
})
local function updateUnitWatch(frame)
local unit = frame.unit
local exists = (unit and unitExistsCache[unit])
if exists then
if not frame:IsShown() then
frame:Show()
else
-- frame:UpdateAllElements('RefreshUnit')
end
elseif frame:IsShown() then
frame:Hide()
end
end
local unitWatch = CreateFrame("Frame")
unitWatch:Hide()
local timer = 0
unitWatch:SetScript("OnUpdate", function()
timer = timer - arg1
if timer <= 0 then
timer = 0.2
for k in pairs(unitExistsCache) do
unitExistsCache[k] = nil
end
for frame in pairs(unitExistsWatchers) do
updateUnitWatch(frame)
end
end
end)
unitWatch:SetScript("OnEvent", function() timer = 0 end)
unitWatch:RegisterEvent("PLAYER_TARGET_CHANGED")
unitWatch:RegisterEvent("PLAYER_REGEN_DISABLED")
unitWatch:RegisterEvent("PLAYER_REGEN_ENABLED")
unitWatch:RegisterEvent("UNIT_PET")
unitWatch:RegisterEvent("RAID_ROSTER_UPDATE")
unitWatch:RegisterEvent("PARTY_MEMBERS_CHANGED")
function RegisterUnitWatch(frame)
unitExistsWatchers[frame] = true
unitWatch:Show()
updateUnitWatch(frame)
end
function UnregisterUnitWatch(frame)
unitExistsWatchers[frame] = nil
end
--[[
List of the various configuration attributes
======================================================
showRaid = [BOOLEAN] -- true if the header should be shown while in a raid
showParty = [BOOLEAN] -- true if the header should be shown while in a party and not in a raid
showPlayer = [BOOLEAN] -- true if the header should show the player when not in a raid
showSolo = [BOOLEAN] -- true if the header should be shown while not in a group (implies showPlayer)
nameList = [STRING] -- a comma separated list of player names (not used if 'groupFilter' is set)
groupFilter = [1-8, STRING] -- a comma seperated list of raid group numbers and/or uppercase class names and/or uppercase roles
strictFiltering = [BOOLEAN] - if true, then characters must match both a group and a class from the groupFilter list
point = [STRING] -- a valid XML anchoring point (Default: "TOP")
xOffset = [NUMBER] -- the x-Offset to use when anchoring the unit buttons (Default: 0)
yOffset = [NUMBER] -- the y-Offset to use when anchoring the unit buttons (Default: 0)
sortMethod = ["INDEX", "NAME"] -- defines how the group is sorted (Default: "INDEX")
sortDir = ["ASC", "DESC"] -- defines the sort order (Default: "ASC")
template = [STRING] -- the XML template to use for the unit buttons
templateType = [STRING] - specifies the frame type of the managed subframes (Default: "Button")
groupBy = [nil, "GROUP", "CLASS", "ROLE"] - specifies a "grouping" type to apply before regular sorting (Default: nil)
groupingOrder = [STRING] - specifies the order of the groupings (ie. "1,2,3,4,5,6,7,8")
maxColumns = [NUMBER] - maximum number of columns the header will create (Default: 1)
unitsPerColumn = [NUMBER or nil] - maximum units that will be displayed in a singe column, nil is infinate (Default: nil)
startingIndex = [NUMBER] - the index in the final sorted unit list at which to start displaying units (Default: 1)
columnSpacing = [NUMBER] - the ammount of space between the rows/columns (Default: 0)
columnAnchorPoint = [STRING] - the anchor point of each new column (ie. use LEFT for the columns to grow to the right)
--]]
function SecureGroupHeader_OnEvent()
if (event == "PARTY_MEMBERS_CHANGED" or event == "RAID_ROSTER_UPDATE") and this:IsVisible() then
SecureGroupHeader_Update(this)
end
end
-- relativePoint, xMultiplier, yMultiplier = getRelativePointAnchor( point )
-- Given a point return the opposite point and which axes the point
-- depends on.
local function getRelativePointAnchor( point )
if not point then return end
point = strupper(point)
if point == "TOP" then
return "BOTTOM", 0, -1;
elseif point == "BOTTOM" then
return "TOP", 0, 1
elseif point == "LEFT" then
return "RIGHT", 1, 0
elseif point == "RIGHT" then
return "LEFT", -1, 0
elseif point == "TOPLEFT" then
return "BOTTOMRIGHT", 1, -1
elseif point == "TOPRIGHT" then
return "BOTTOMLEFT", -1, -1
elseif point == "BOTTOMLEFT" then
return "TOPRIGHT", 1, 1
elseif point == "BOTTOMRIGHT" then
return "TOPLEFT", -1, 1
else
return "CENTER", 0, 0
end
end
function ApplyUnitButtonConfiguration( frame )
-- for i = 1, getn(arg), 1 do
-- local frame = arg[i];
--if ( unitWatch ) then
-- if ( unitWatch == "state" ) then
-- RegisterUnitWatch(frame, true);
-- else
RegisterUnitWatch(frame);
-- end
--end
-- call this function recursively for the current frame's children
-- ApplyUnitButtonConfiguration(frame:GetChildren());
-- end
end
local function ApplyConfig(header, newChild, defaultConfigFunction)
local configFunction = header.initialConfigFunction or defaultConfigFunction
if type(configFunction) == "function" then
configFunction(newChild)
return true
end
end
function SetupUnitButtonConfiguration(header, newChild, defaultConfigFunction)
if ApplyConfig(header, newChild, defaultConfigFunction) then
ApplyUnitButtonConfiguration(newChild)
end
end
-- empties tbl and assigns the value true to each key passed as part of ...
local function fillTable(tbl, ...)
for key in pairs(tbl) do
tbl[key] = nil
end
for i = 1, getn(arg), 1 do
local key = arg[i]
key = tonumber(key) or key
tbl[key] = true
end
end
-- same as fillTable() except that each key is also stored in
-- the array portion of the table in order
local function doubleFillTable(tbl, ...)
fillTable(tbl, unpack(arg))
for i = 1, getn(arg), 1 do
tbl[i] = arg[i]
end
end
--working tables
local tokenTable = {}
local sortingTable = {}
local groupingTable = {}
local tempTable = {}
-- creates child frames and finished configuring them
local function configureChildren(self)
local point = self:GetAttribute("point") or "TOP" --default anchor point of "TOP"
local relativePoint, xOffsetMult, yOffsetMult = getRelativePointAnchor(point)
local xMultiplier, yMultiplier = abs(xOffsetMult), abs(yOffsetMult)
local xOffset = self:GetAttribute("xOffset") or 0 --default of 0
local yOffset = self:GetAttribute("yOffset") or 0 --default of 0
local sortDir = self:GetAttribute("sortDir") or "ASC"; --sort ascending by default
local columnSpacing = self:GetAttribute("columnSpacing") or 0
local startingIndex = self:GetAttribute("startingIndex") or 1
local unitCount = getn(sortingTable)
local numDisplayed = unitCount - (startingIndex - 1)
local unitsPerColumn = self:GetAttribute("unitsPerColumn")
local numColumns
if unitsPerColumn and numDisplayed > unitsPerColumn then
numColumns = min(ceil(numDisplayed / unitsPerColumn), (self:GetAttribute("maxColumns") or 1))
else
unitsPerColumn = numDisplayed
numColumns = 1
end
local loopStart = startingIndex
local loopFinish = min((startingIndex - 1) + unitsPerColumn * numColumns, unitCount)
local step = 1
numDisplayed = loopFinish - (loopStart - 1)
if sortDir == "DESC" then
loopStart = unitCount - (startingIndex - 1)
loopFinish = loopStart - (numDisplayed - 1)
step = -1
end
-- ensure there are enough buttons
local needButtons = max(1, numDisplayed)
if not self:GetAttribute("child"..needButtons) then
local name = self:GetName()
if not name then
self:Hide()
return
end
for i = 1, needButtons, 1 do
local childAttr = "child"..i
if not self:GetAttribute(childAttr) then
local newButton = CreateFrame("Button", name.."UnitButton"..i, self)
SetupUnitButtonConfiguration(self, newButton)
self:SetAttribute(childAttr, newButton)
end
end
end
local columnAnchorPoint, columnRelPoint, colxMulti, colyMulti
if numColumns > 1 then
columnAnchorPoint = self:GetAttribute("columnAnchorPoint")
columnRelPoint, colxMulti, colyMulti = getRelativePointAnchor(columnAnchorPoint)
end
local buttonNum = 0
local columnNum = 1
local columnUnitCount = 0
local currentAnchor = self
for i = loopStart, loopFinish, step do
buttonNum = buttonNum + 1
columnUnitCount = columnUnitCount + 1
if columnUnitCount > unitsPerColumn then
columnUnitCount = 1
columnNum = columnNum + 1
end
local unitButton = self:GetAttribute("child"..buttonNum);
unitButton:Hide()
unitButton:ClearAllPoints()
if buttonNum == 1 then
unitButton:SetPoint(point, currentAnchor, point, 0, 0)
if columnAnchorPoint then
unitButton:SetPoint(columnAnchorPoint, currentAnchor, columnAnchorPoint, 0, 0)
end
elseif columnUnitCount == 1 then
local columnAnchor = self:GetAttribute("child"..(buttonNum - unitsPerColumn))
unitButton:SetPoint(columnAnchorPoint, columnAnchor, columnRelPoint, colxMulti * columnSpacing, colyMulti * columnSpacing)
else
unitButton:SetPoint(point, currentAnchor, relativePoint, xMultiplier * xOffset, yMultiplier * yOffset)
end
unitButton.unit = sortingTable[sortingTable[i]]
unitButton:Show()
currentAnchor = unitButton
end
repeat
buttonNum = buttonNum + 1
local unitButton = self:GetAttribute("child"..buttonNum)
if unitButton then
unitButton:Hide()
unitButton.unit = nil
end
until not unitButton
local unitButton = self:GetAttribute("child1")
local unitButtonWidth = unitButton:GetWidth()
local unitButtonHeight = unitButton:GetHeight()
if numDisplayed > 0 then
local width = xMultiplier * (unitsPerColumn - 1) * unitButtonWidth + ((unitsPerColumn - 1) * (xOffset * xOffsetMult)) + unitButtonWidth
local height = yMultiplier * (unitsPerColumn - 1) * unitButtonHeight + ((unitsPerColumn - 1) * (yOffset * yOffsetMult)) + unitButtonHeight
if numColumns > 1 then
width = width + ((numColumns -1) * abs(colxMulti) * (width + columnSpacing))
height = height + ((numColumns -1) * abs(colyMulti) * (height + columnSpacing))
end
self:SetWidth(width)
self:SetHeight(height)
else
local minWidth = self:GetAttribute("minWidth") or (yMultiplier * unitButtonWidth)
local minHeight = self:GetAttribute("minHeight") or (xMultiplier * unitButtonHeight)
self:SetWidth(max(minWidth, 0.1))
self:SetHeight(max(minHeight, 0.1))
end
end
local function GetGroupHeaderType(self)
local type, start, stop
local nRaid = GetNumRaidMembers()
local nParty = GetNumPartyMembers()
if nRaid > 0 and self:GetAttribute("showRaid") then
type = "RAID";
elseif (nRaid > 0 or nParty > 0) and self:GetAttribute("showParty") then
type = "PARTY"
elseif self:GetAttribute("showSolo") then
type = "SOLO"
end
if type then
if type == "RAID" then
start = 1
stop = nRaid
else
if type == "SOLO" or self:GetAttribute("showPlayer") then
start = 0
else
start = 1
end
stop = nParty
end
end
return type, start, stop
end
local function GetGroupRosterInfo(type, index)
local _, unit, name, subgroup, className
if type == "RAID" then
unit = "raid"..index
name, _, subgroup, _, _, className = GetRaidRosterInfo(index)
else
if index > 0 then
unit = "party"..index
else
unit = "player"
end
if UnitExists(unit) then
name = UnitName(unit)
_, className = UnitClass(unit)
end
subgroup = 1
end
return unit, name, subgroup, className
end
function SecureGroupHeader_Update(self)
local nameList = self:GetAttribute("nameList")
local groupFilter = self:GetAttribute("groupFilter")
local sortMethod = self:GetAttribute("sortMethod")
local groupBy = self:GetAttribute("groupBy")
for key in pairs(sortingTable) do
sortingTable[key] = nil
end
table.setn(sortingTable, 0)
-- See if this header should be shown
local type, start, stop = GetGroupHeaderType(self)
if not type then
configureChildren(self)
return
end
if not groupFilter and not nameList then
groupFilter = "1,2,3,4,5,6,7,8";
end
if groupFilter then
-- filtering by a list of group numbers and/or classes
fillTable(tokenTable, strsplit(",", groupFilter));
local strictFiltering = self:GetAttribute("strictFiltering"); -- non-strict by default
for i = start, stop, 1 do
local unit, name, subgroup, className = GetGroupRosterInfo(type, i)
if name and ((not strictFiltering) and (tokenTable[subgroup] or tokenTable[className])) or (tokenTable[subgroup] and tokenTable[className]) then
tinsert(sortingTable, name)
sortingTable[name] = unit
if groupBy == "GROUP" then
groupingTable[name] = subgroup
elseif groupBy == "CLASS" then
groupingTable[name] = className
end
end
end
if groupBy then
local groupingOrder = self:GetAttribute("groupingOrder")
doubleFillTable(tokenTable, strsplit(",", groupingOrder))
for k in pairs(tempTable) do
tempTable[k] = nil
end
for _, grouping in ipairs(tokenTable) do
grouping = tonumber(grouping) or grouping
for k in ipairs(groupingTable) do
groupingTable[k] = nil
end
table.setn(groupingTable, 0)
for index, name in ipairs(sortingTable) do
if groupingTable[name] == grouping then
tinsert(groupingTable, name)
tempTable[name] = true
end
end
if sortMethod == "NAME" then -- sort by ID by default
table.sort(groupingTable)
end
for _, name in ipairs(groupingTable) do
tinsert(tempTable, name)
end
end
-- handle units whose group didn't appear in groupingOrder
for k in ipairs(groupingTable) do
groupingTable[k] = nil
end
table.setn(groupingTable, 0)
for index, name in ipairs(sortingTable) do
if not tempTable[name] then
tinsert(groupingTable, name)
end
end
if sortMethod == "NAME" then -- sort by ID by default
table.sort(groupingTable)
end
for _, name in ipairs(groupingTable) do
tinsert(tempTable, name)
end
--copy the names back to sortingTable
for index, name in ipairs(tempTable) do
sortingTable[index] = name
end
elseif sortMethod == "NAME" then -- sort by ID by default
table.sort(sortingTable)
end
else
-- filtering via a list of names
doubleFillTable(sortingTable, strsplit(",", nameList))
for i = start, stop, 1 do
local unit, name = GetGroupRosterInfo(type, i)
if sortingTable[name] then
sortingTable[name] = unit
end
end
for i = getn(sortingTable), 1, -1 do
local name = sortingTable[i]
if sortingTable[name] == true then
tremove(sortingTable, i)
end
end
if sortMethod == "NAME" then
table.sort(sortingTable)
end
end
configureChildren(self)
end
@@ -0,0 +1,16 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/">
<Frame name="oUF_GroupHeaderTemplate" hidden="true" virtual="true">
<Scripts>
<OnLoad>
this:RegisterEvent("PARTY_MEMBERS_CHANGED")
this:RegisterEvent("RAID_ROSTER_UPDATE")
</OnLoad>
<OnEvent>
SecureGroupHeader_OnEvent(this, event)
</OnEvent>
<OnShow>
SecureGroupHeader_Update(this)
</OnShow>
</Scripts>
</Frame>
</Ui>
@@ -12,8 +12,6 @@ function oUF:HandleUnit(object, unit)
object:RegisterEvent('PLAYER_TARGET_CHANGED', object.UpdateAllElements)
elseif(unit == 'mouseover') then
object:RegisterEvent('UPDATE_MOUSEOVER_UNIT', object.UpdateAllElements)
elseif(unit == 'focus') then
object:RegisterEvent('PLAYER_FOCUS_CHANGED', object.UpdateAllElements)
elseif(string.match(unit, '%w+target')) then
enableTargetUpdate(object)
end