Files
unitscan-turtle-hc/unitscan.lua
T
2023-03-25 18:07:36 +00:00

424 lines
11 KiB
Lua

local unitscan = CreateFrame'Frame'
unitscan:SetScript('OnUpdate', function() unitscan.UPDATE() end)
unitscan:SetScript('OnEvent', function()
if event == "VARIABLES_LOADED" then
unitscan.LOAD()
else
unitscan.load_zonetargets()
end
end)
unitscan:RegisterEvent'VARIABLES_LOADED'
unitscan:RegisterEvent'MINIMAP_ZONE_CHANGED'
unitscan:RegisterEvent'PLAYER_ENTERING_WORLD'
local BROWN = {.7, .15, .05}
local YELLOW = {1, 1, .15}
local CHECK_INTERVAL = 1 -- .1
unitscan_targets = {}
local prevTarget
local dead
local reaction
do
local last_played
function unitscan.play_sound()
if not last_played or GetTime() - last_played > 10 then -- 8
SetCVar('MasterSoundEffects', 0)
SetCVar('MasterSoundEffects', 1)
-- PlaySoundFile[[Interface\AddOns\unitscan-turtle\Event_wardrum_ogre.ogg]]
-- PlaySoundFile[[Interface\AddOns\unitscan-turtle\scourge_horn.ogg]]
PlaySoundFile[[Interface\AddOns\unitscan-turtle\gruntling_horn_bb.ogg]]
last_played = GetTime()
end
end
end
function unitscan.load_zonetargets()
unitscan_zone_targets()
-- DEFAULT_CHAT_FRAME:AddMessage("DEBUG: unitscan: reloaded zone targets")
end
function unitscan.restore_target()
if prevTarget then
TargetLastTarget()
elseif dead then
ClearTarget()
end
dead = nil
reaction = nil
prevTarget = nil
end
function unitscan.check_for_targets()
for name, _ in unitscan_targets do
if name == unitscan.target(name) then
-- DEFAULT_CHAT_FRAME:AddMessage("DEBUG: unitscan check_for_targets: "..name.." was found!")
unitscan.foundTarget = name
unitscan.toggle_target(name)
unitscan.play_sound()
unitscan.flash.animation:Play()
unitscan.button:set_target()
unitscan.restore_target()
end
end
end
function unitscan.check_for_zonetargets()
for name, _ in unitscan_zonetargets do
if strupper(name) == unitscan.target(name) then
-- DEFAULT_CHAT_FRAME:AddMessage("DEBUG: unitscan check_for_zonetargets: "..name.." was found!")
if (not dead) and (reaction <= 4) then -- only for neutral or hostile mobs that are alive
unitscan.foundTarget = name
unitscan.toggle_zonetarget(name)
unitscan.play_sound()
unitscan.flash.animation:Play()
unitscan.button:set_target()
end
unitscan.restore_target()
end
end
end
do
local pass = function() end
function unitscan.target(name)
local orig = UIErrorsFrame_OnEvent
UIErrorsFrame_OnEvent = pass
prevTarget = UnitExists("target")
TargetByName(name, true)
UIErrorsFrame_OnEvent = orig
local target = UnitName("target")
dead = UnitIsDead'target'
reaction = UnitReaction("target", "player")
if target then
return strupper(target)
else
return nil
end
end
end
function unitscan.LOAD()
do
local flash = CreateFrame'Frame'
unitscan.flash = flash
flash:Show()
flash:SetAllPoints()
flash:SetAlpha(0)
flash:SetFrameStrata'FULLSCREEN_DIALOG'
local texture = flash:CreateTexture()
texture:SetBlendMode'ADD'
texture:SetAllPoints()
texture:SetTexture[[Interface\FullScreenTextures\LowHealth]]
flash.animation = CreateFrame'Frame'
flash.animation:Hide()
flash.animation:SetScript('OnUpdate', function()
local t = GetTime() - this.t0
if t <= .5 then
flash:SetAlpha(t * 2)
elseif t <= 1 then
flash:SetAlpha(1)
elseif t <= 1.5 then
flash:SetAlpha(1 - (t - 1) * 2)
else
flash:SetAlpha(0)
this.loops = this.loops - 1
if this.loops == 0 then
this.t0 = nil
this:Hide()
else
this.t0 = GetTime()
end
end
end)
function flash.animation:Play()
if self.t0 then
self.loops = 4
else
self.t0 = GetTime()
self.loops = 3
end
self:Show()
end
end
local button = CreateFrame("Button", "unitscan_button", UIParent)
button:Hide()
unitscan.button = button
button:SetPoint('BOTTOM', UIParent, 0, 148)
button:SetWidth(200)
button:SetHeight(42)
button:SetScale(1)
button:SetMovable(true)
button:SetUserPlaced(true)
button:SetClampedToScreen(true)
button:SetScript('OnMouseDown', function()
if IsControlKeyDown() then
this:RegisterForClicks()
this:StartMoving()
end
end)
button:SetScript('OnMouseUp', function()
this:StopMovingOrSizing()
this:RegisterForClicks'LeftButtonDown'
end)
button:SetFrameStrata'FULLSCREEN_DIALOG'
-- button:SetNormalTexture[[Interface\AddOns\unitscan-turtle\UI-Achievement-Parchment-Horizontal]]
button:SetBackdrop{
tile = true,
edgeSize = 16,
edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]],
}
button:SetBackdropBorderColor(unpack(BROWN))
button:SetScript('OnEnter', function()
this:SetBackdropBorderColor(unpack(YELLOW))
end)
button:SetScript('OnLeave', function()
this:SetBackdropBorderColor(unpack(BROWN))
end)
button:SetScript('OnClick', function()
TargetByName(this:GetText(), true)
end)
function button:set_target()
self:SetText(UnitName'target')
self.model:reset()
self.model:SetUnit'target'
self:Show()
self.glow.animation:Play()
self.shine.animation:Play()
end
do
local background = button:CreateTexture(nil, 'BACKGROUND')
background:SetTexture[[Interface\AddOns\unitscan-turtle\UI-Achievement-Parchment-Horizontal]]
background:SetPoint('BOTTOMLEFT', 3, 3)
background:SetPoint('TOPRIGHT', -3, -3)
background:SetTexCoord(0, 1, 0, .25)
end
do
local title_background = button:CreateTexture(nil, 'BORDER')
title_background:SetTexture[[Interface\AddOns\unitscan-turtle\UI-Achievement-Title]]
title_background:SetPoint('TOPRIGHT', -5, -5)
title_background:SetPoint('LEFT', 5, 0)
title_background:SetHeight(18)
title_background:SetTexCoord(0, .9765625, 0, .3125)
title_background:SetAlpha(.8)
local title = button:CreateFontString(nil, 'OVERLAY')
title:SetFont([[Fonts\FRIZQT__.TTF]], 14)
title:SetShadowOffset(1, -1)
title:SetPoint('TOPLEFT', title_background, 0, 0)
title:SetPoint('RIGHT', title_background)
button:SetFontString(title)
local subtitle = button:CreateFontString(nil, 'OVERLAY')
subtitle:SetFont([[Fonts\FRIZQT__.TTF]], 9)
subtitle:SetTextColor(0, 0, 0)
subtitle:SetPoint('TOPLEFT', title, 'BOTTOMLEFT', 0, -4)
subtitle:SetPoint('RIGHT', title )
subtitle:SetText'Unit Found!'
end
do
local model = CreateFrame('PlayerModel', nil, button)
button.model = model
model:SetPoint('BOTTOMLEFT', button, 'TOPLEFT', 0, -4)
model:SetPoint('RIGHT', 0, 0)
model:SetHeight(button:GetWidth() * .6)
do
local last_update, delay
function model:on_update()
this:SetFacing(this:GetFacing() + (GetTime() - last_update) * math.pi / 4)
last_update = GetTime()
end
function model:on_update_model()
if delay > 0 then
delay = delay - 1
return
end
this:SetScript('OnUpdateModel', nil)
this:SetScript('OnUpdate', this.on_update)
this:SetModelScale(.75)
this:SetAlpha(1)
last_update = GetTime()
end
function model:reset()
self:SetAlpha(0)
self:SetFacing(0)
self:SetModelScale(1)
self:ClearModel()
self:SetScript('OnUpdate', nil)
self:SetScript("OnUpdateModel", self.on_update_model)
delay = 10 -- to prevent scaling bugs
end
end
end
do
local close = CreateFrame('Button', nil, button, 'UIPanelCloseButton')
close:SetPoint('TOPRIGHT', 0, 0)
close:SetWidth(32)
close:SetHeight(32)
close:SetScale(.8)
close:SetHitRectInsets(8, 8, 8, 8)
end
do
local glow = button.model:CreateTexture(nil, 'OVERLAY')
button.glow = glow
glow:SetPoint('CENTER', button, 'CENTER')
glow:SetWidth(400 / 300 * button:GetWidth())
glow:SetHeight(171 / 70 * button:GetHeight())
glow:SetTexture[[Interface\AddOns\unitscan-turtle\UI-Achievement-Alert-Glow]]
glow:SetBlendMode'ADD'
glow:SetTexCoord(0, .78125, 0, .66796875)
glow:SetAlpha(0)
glow.animation = CreateFrame'Frame'
glow.animation:Hide()
glow.animation:SetScript('OnUpdate', function()
local t = GetTime() - this.t0
if t <= .2 then
glow:SetAlpha(t * 5)
elseif t <= .7 then
glow:SetAlpha(1 - (t - .2) * 2)
else
glow:SetAlpha(0)
this:Hide()
end
end)
function glow.animation:Play()
self.t0 = GetTime()
self:Show()
end
end
do
local shine = button:CreateTexture(nil, 'ARTWORK')
button.shine = shine
shine:SetPoint('TOPLEFT', button, 0, 8)
shine:SetWidth(67 / 300 * button:GetWidth())
shine:SetHeight(1.28 * button:GetHeight())
shine:SetTexture[[Interface\AddOns\unitscan-turtle\UI-Achievement-Alert-Glow]]
shine:SetBlendMode'ADD'
shine:SetTexCoord(.78125, .912109375, 0, .28125)
shine:SetAlpha(0)
shine.animation = CreateFrame'Frame'
shine.animation:Hide()
shine.animation:SetScript('OnUpdate', function()
local t = GetTime() - this.t0
if t <= .3 then
shine:SetPoint('TOPLEFT', button, 0, 8)
elseif t <= .7 then
shine:SetPoint('TOPLEFT', button, (t - .3) * 2.5 * this.distance, 8)
end
if t <= .3 then
shine:SetAlpha(0)
elseif t <= .5 then
shine:SetAlpha(1)
elseif t <= .7 then
shine:SetAlpha(1 - (t - .5) * 5)
else
shine:SetAlpha(0)
this:Hide()
end
end)
function shine.animation:Play()
self.t0 = GetTime()
self.distance = button:GetWidth() - shine:GetWidth() + 8
self:Show()
end
end
end
do
unitscan.last_check = GetTime()
function unitscan.UPDATE()
-- reload targets for zone
if unitscan.reloadtimer and (GetTime() > unitscan.reloadtimer) then
unitscan.load_zonetargets()
end
if GetTime() - unitscan.last_check >= CHECK_INTERVAL then
unitscan.last_check = GetTime()
unitscan.check_for_targets()
unitscan.check_for_zonetargets()
end
end
end
function unitscan.print(msg)
if DEFAULT_CHAT_FRAME then
DEFAULT_CHAT_FRAME:AddMessage(LIGHTYELLOW_FONT_COLOR_CODE .. '<unitscan> ' .. msg)
end
end
function unitscan.sorted_targets()
local sorted_targets = {}
for key in pairs(unitscan_targets) do
tinsert(sorted_targets, key)
end
sort(sorted_targets, function(key1, key2) return key1 < key2 end)
return sorted_targets
end
function unitscan.toggle_target(name)
local key = strupper(name)
if unitscan_targets[key] then
unitscan_targets[key] = nil
unitscan.print('- ' .. key)
elseif key ~= '' then
unitscan_targets[key] = true
unitscan.print('+ ' .. key)
end
end
function unitscan.toggle_zonetarget(name)
-- DEFAULT_CHAT_FRAME:AddMessage("DEBUG: unitscan: toggle_zonetarget")
if unitscan_zonetargets[name] then
unitscan_zonetargets[name] = nil
unitscan.print(name .. ' was found!')
unitscan.reloadtimer = GetTime() + 90 -- trigger reload zone timer
end
end
SLASH_UNITSCAN1 = '/unitscan'
function SlashCmdList.UNITSCAN(parameter)
local _, _, name = strfind(parameter, '^%s*(.-)%s*$')
if name == '' then
for _, key in ipairs(unitscan.sorted_targets()) do
unitscan.print(key)
end
else
unitscan.toggle_target(name)
end
end
SLASH_UNITSCANTARGET1 = '/unitscantarget'
function SlashCmdList.UNITSCANTARGET()
if unitscan.foundTarget then
TargetByName(unitscan.foundTarget, true)
end
end