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.
485 lines
13 KiB
485 lines
13 KiB
local E = select(2, ...):unpack()
|
|
local P, CM, CD = E.Party, E.Comm, E.Cooldowns
|
|
|
|
local pairs, type = pairs, type
|
|
local UnitExists, UnitGUID, UnitClass, UnitIsDeadOrGhost, UnitIsConnected, GetRaidRosterInfo, UnitRace, GetUnitName, UnitLevel = UnitExists, UnitGUID, UnitClass, UnitIsDeadOrGhost, UnitIsConnected, GetRaidRosterInfo, UnitRace, GetUnitName, UnitLevel
|
|
local C_PvP_IsRatedSoloShuffle = E.isDF and C_PvP and C_PvP.IsRatedSoloShuffle or E.Noop
|
|
local UPDATE_ROSTER_DELAY = 2
|
|
local MSG_INFO_REQUEST_DELAY = UPDATE_ROSTER_DELAY + 1
|
|
|
|
P.groupInfo = {}
|
|
P.pendingQueue = {}
|
|
P.loginsessionData = {}
|
|
P.callbackTimers = {}
|
|
|
|
P.userInfo = {}
|
|
P.userInfo.guid = E.userGUID
|
|
P.userInfo.class = E.userClass
|
|
P.userInfo.raceID = E.userRaceID
|
|
P.userInfo.name = E.userName
|
|
P.userInfo.level = E.userLevel
|
|
P.userInfo.preactiveIcons = {}
|
|
P.userInfo.spellIcons = {}
|
|
P.userInfo.glowIcons = {}
|
|
P.userInfo.active = {}
|
|
P.userInfo.auras = {}
|
|
P.userInfo.itemData = {}
|
|
P.userInfo.talentData = {}
|
|
P.userInfo.shadowlandsData = {}
|
|
P.userInfo.callbackTimers = {}
|
|
P.userInfo.spellModRates = {}
|
|
P.userInfo.sessionItemData = {}
|
|
|
|
local RAID_UNIT = {
|
|
"raid1", "raid2", "raid3", "raid4", "raid5", "raid6", "raid7", "raid8", "raid9", "raid10",
|
|
"raid11", "raid12", "raid13", "raid14", "raid15", "raid16", "raid17", "raid18", "raid19", "raid20",
|
|
"raid21", "raid22", "raid23", "raid24", "raid25", "raid26", "raid27", "raid28", "raid29", "raid30",
|
|
"raid31", "raid32", "raid33", "raid34", "raid35", "raid36", "raid37", "raid38", "raid39", "raid40",
|
|
}
|
|
|
|
local PARTY_UNIT = {
|
|
"party1", "party2", "party3", "party4", "player"
|
|
}
|
|
|
|
local INSTANCETYPE_EVENTS = E.preMoP and {
|
|
arena = {
|
|
|
|
'UPDATE_UI_WIDGET',
|
|
},
|
|
pvp = {
|
|
'CHAT_MSG_BG_SYSTEM_NEUTRAL',
|
|
|
|
'UPDATE_UI_WIDGET',
|
|
}
|
|
} or {
|
|
party = {
|
|
'CHALLENGE_MODE_START',
|
|
},
|
|
raid = {
|
|
'ENCOUNTER_END',
|
|
},
|
|
none = {
|
|
'PLAYER_FLAGS_CHANGED',
|
|
},
|
|
arena = {
|
|
|
|
'UPDATE_UI_WIDGET',
|
|
},
|
|
pvp = {
|
|
'CHAT_MSG_BG_SYSTEM_NEUTRAL',
|
|
'UPDATE_UI_WIDGET',
|
|
|
|
}
|
|
}
|
|
if (E.isWOTLKC or E.isCata) then
|
|
INSTANCETYPE_EVENTS.raid = { 'ENCOUNTER_END' }
|
|
end
|
|
|
|
function P:UnregisterZoneEvents()
|
|
local registeredZoneEvents = self.currentZoneEvents
|
|
if registeredZoneEvents then
|
|
for _, event in ipairs(registeredZoneEvents) do
|
|
self:UnregisterEvent(event)
|
|
end
|
|
end
|
|
self.currentZoneEvents = nil
|
|
end
|
|
|
|
function P:RegisterZoneEvents(currentZoneEvents)
|
|
self:UnregisterZoneEvents()
|
|
currentZoneEvents = currentZoneEvents or INSTANCETYPE_EVENTS[self.zone]
|
|
if currentZoneEvents then
|
|
for _, event in ipairs(currentZoneEvents) do
|
|
self:RegisterEvent(event)
|
|
end
|
|
end
|
|
self.currentZoneEvents = currentZoneEvents
|
|
end
|
|
|
|
local function IsInShadowlands()
|
|
local mapID = C_Map and C_Map.GetBestMapForUnit("player")
|
|
if mapID then
|
|
local mapInfo = C_Map.GetMapInfo(mapID)
|
|
while mapInfo do
|
|
if mapInfo.mapType == 2 then
|
|
return mapInfo.mapID == 1550
|
|
end
|
|
mapInfo = C_Map.GetMapInfo(mapInfo.parentMapID)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function AnchorFix()
|
|
P:UpdatePosition()
|
|
P.callbackTimers.anchorBackup = nil
|
|
end
|
|
|
|
local function SendRequestSync()
|
|
local success = CM:InspectUser()
|
|
if success then
|
|
CM:RequestSync()
|
|
P.joinedNewGroup = false
|
|
P.callbackTimers.syncDelay = nil
|
|
else
|
|
C_Timer.After(2, SendRequestSync)
|
|
end
|
|
end
|
|
|
|
local function UpdateRosterInfo(force, clearSession)
|
|
if not force then
|
|
P.callbackTimers.rosterDelay = nil
|
|
end
|
|
|
|
local size = P:GetEffectiveNumGroupMembers()
|
|
local oldDisabled = P.disabled
|
|
P.disabled = not P.isInTestMode and (P.disabledZone or size == 0
|
|
or (size == 1 and P.isUserDisabled)
|
|
or (GetNumGroupMembers(LE_PARTY_CATEGORY_HOME) == 0 and not E.profile.Party.visibility.finder)
|
|
or (size > E.profile.Party.groupSize[P.zone]))
|
|
|
|
if P.disabled then
|
|
if oldDisabled == false then
|
|
P:ResetModule()
|
|
end
|
|
P.joinedNewGroup = false
|
|
return
|
|
end
|
|
|
|
if oldDisabled ~= false then
|
|
CM:Enable()
|
|
CD:Enable()
|
|
force = true
|
|
end
|
|
|
|
if force then
|
|
P.isInShadowlands = E.isSL or (E.postBFA and not P.isInPvPInstance and IsInShadowlands())
|
|
end
|
|
|
|
E.Libs.CBH:Fire("OnStartup")
|
|
|
|
|
|
for guid, info in pairs(P.groupInfo) do
|
|
if not UnitExists(info.name) or (guid == E.userGUID and P.isUserDisabled) then
|
|
for _, timer in pairs(info.callbackTimers) do
|
|
if type(timer) == "userdata" then
|
|
timer:Cancel()
|
|
end
|
|
end
|
|
|
|
P.groupInfo[guid] = nil
|
|
P:HideBar(info.bar)
|
|
|
|
local capGUID = info.auras.capTotemGUID
|
|
if capGUID then
|
|
CD.totemGUIDS[capGUID] = nil
|
|
end
|
|
local petGUID = info.petGUID
|
|
if petGUID then
|
|
CD.petGUIDS[petGUID] = nil
|
|
end
|
|
|
|
CM.syncedGroupMembers[guid] = nil
|
|
CM:DequeueInspect(guid)
|
|
elseif clearSession then
|
|
wipe(info.sessionItemData)
|
|
info.auras.session_flashHeal = nil
|
|
end
|
|
end
|
|
|
|
local isInRaid = IsInRaid()
|
|
for i = 1, size do
|
|
local index = not isInRaid and i == size and 5 or i
|
|
local unit = isInRaid and RAID_UNIT[index] or PARTY_UNIT[index]
|
|
local guid = UnitGUID(unit)
|
|
local info = P.groupInfo[guid]
|
|
local _, class = UnitClass(unit)
|
|
local isDead = UnitIsDeadOrGhost(unit)
|
|
|
|
local isOffline = not UnitIsConnected(unit)
|
|
local isDeadOrOffline = isDead or isOffline
|
|
local isUser = guid == E.userGUID
|
|
|
|
local isAdminObsForMDI
|
|
if P.isInDungeon then
|
|
local _,_, subgroup = GetRaidRosterInfo(i)
|
|
isAdminObsForMDI = subgroup and subgroup > 1
|
|
end
|
|
|
|
local isWarlock = class == "WARLOCK"
|
|
local pet = (class == "HUNTER" or isWarlock) and E.UNIT_TO_PET[unit]
|
|
if pet then
|
|
local petGUID = UnitGUID(pet)
|
|
if petGUID then
|
|
pet = petGUID
|
|
CD.petGUIDS[petGUID] = guid
|
|
end
|
|
end
|
|
|
|
if info then
|
|
local frame = info.bar
|
|
local unitIdChanged = info.unit ~= unit
|
|
if unitIdChanged then
|
|
info.index, info.unit = index, unit
|
|
frame.key, frame.unit = index, unit
|
|
frame.anchor.text:SetText(index)
|
|
end
|
|
|
|
|
|
|
|
|
|
if force or not info.spec or (info.isAdminObsForMDI ~= isAdminObsForMDI) then
|
|
info.isAdminObsForMDI = isAdminObsForMDI
|
|
if not isUser then
|
|
P.pendingQueue[#P.pendingQueue + 1] = guid
|
|
end
|
|
P:UpdateUnitBar(guid, true)
|
|
elseif unitIdChanged and not isAdminObsForMDI then
|
|
frame:UnregisterAllEvents()
|
|
if not E.preMoP and not isUser then
|
|
frame:RegisterUnitEvent('PLAYER_SPECIALIZATION_CHANGED', unit)
|
|
end
|
|
if E.isBFA then
|
|
if P.isInArena then
|
|
frame:RegisterUnitEvent('UNIT_AURA', unit)
|
|
end
|
|
else
|
|
if info.glowIcons[125174] or info.preactiveIcons[5384] then
|
|
frame:RegisterUnitEvent('UNIT_AURA', unit)
|
|
end
|
|
end
|
|
if isDead then
|
|
frame:RegisterUnitEvent('UNIT_HEALTH', unit)
|
|
end
|
|
if not E.isClassic then
|
|
frame:RegisterUnitEvent('UNIT_SPELLCAST_SUCCEEDED', unit, E.UNIT_TO_PET[unit])
|
|
end
|
|
frame:RegisterUnitEvent('UNIT_CONNECTION', unit)
|
|
end
|
|
elseif isUser then
|
|
if not P.isUserDisabled then
|
|
P.groupInfo[guid] = P.userInfo
|
|
P.groupInfo[guid].index = index
|
|
P.groupInfo[guid].unit = unit
|
|
P.groupInfo[guid].petGUID = pet
|
|
P.groupInfo[guid].isDead = isDead
|
|
P.groupInfo[guid].isDeadOrOffline = isDeadOrOffline
|
|
P.groupInfo[guid].isAdminObsForMDI = isAdminObsForMDI
|
|
info = P.groupInfo[guid]
|
|
|
|
P:UpdateUnitBar(guid, true)
|
|
end
|
|
elseif class then
|
|
local _,_, race = UnitRace(unit)
|
|
local name = GetUnitName(unit, true) or ""
|
|
local level = UnitLevel(unit)
|
|
level = level > 0 and level or 200
|
|
info = {
|
|
guid = guid, class = class, raceID = race, name = name, level = level,
|
|
index = index, unit = unit, petGUID = pet,
|
|
isDead = isDead, isDeadOrOffline = isDeadOrOffline, isAdminObsForMDI = isAdminObsForMDI,
|
|
preactiveIcons = {},
|
|
spellIcons = {},
|
|
glowIcons = {},
|
|
active = {},
|
|
auras = {},
|
|
itemData = {},
|
|
talentData = {},
|
|
shadowlandsData = {},
|
|
callbackTimers = {},
|
|
spellModRates = {},
|
|
sessionItemData = {},
|
|
}
|
|
P.groupInfo[guid] = info
|
|
|
|
P.pendingQueue[#P.pendingQueue + 1] = guid
|
|
P:UpdateUnitBar(guid, true)
|
|
elseif not isOffline then
|
|
C_Timer.After(UPDATE_ROSTER_DELAY, function() UpdateRosterInfo(true) end)
|
|
end
|
|
|
|
if info then
|
|
if isDeadOrOffline then
|
|
P:SetDisabledColorScheme(info)
|
|
else
|
|
P:SetEnabledColorScheme(info)
|
|
end
|
|
info.isDeadOrOffline = isDeadOrOffline
|
|
end
|
|
end
|
|
|
|
P:UpdatePosition()
|
|
P:UpdateExBars()
|
|
CM:EnqueueInspect()
|
|
|
|
if P.joinedNewGroup or force then
|
|
if P.callbackTimers.syncDelay then
|
|
P.callbackTimers.syncDelay:Cancel()
|
|
end
|
|
P.callbackTimers.syncDelay = C_Timer.NewTicker(size == 1 and 0 or MSG_INFO_REQUEST_DELAY, SendRequestSync, 1)
|
|
end
|
|
|
|
if P.callbackTimers.anchorBackup then
|
|
P.callbackTimers.anchorBackup:Cancel()
|
|
end
|
|
P.callbackTimers.anchorBackup = C_Timer.NewTicker(6, AnchorFix, (E.customUF.active == "VuhDo" or E.customUF.active == "HealBot") and 2 or 1)
|
|
|
|
CM:ToggleCooldownSync()
|
|
end
|
|
|
|
|
|
function P:GROUP_ROSTER_UPDATE(isPEW, isRefresh)
|
|
if self.callbackTimers.rosterDelay then
|
|
self.callbackTimers.rosterDelay:Cancel()
|
|
end
|
|
if isRefresh or GetNumGroupMembers() == 0 then
|
|
UpdateRosterInfo(true)
|
|
elseif isPEW then
|
|
C_Timer.After(E.customUF.delay or 0.5, function() UpdateRosterInfo(true, true) end)
|
|
else
|
|
self.callbackTimers.rosterDelay = C_Timer.NewTimer(E.customUF.delay or 0.5, function() UpdateRosterInfo() end)
|
|
end
|
|
end
|
|
|
|
local inspectAllGroupMembers = function()
|
|
CM:EnqueueInspect(true)
|
|
end
|
|
|
|
|
|
|
|
|
|
function P:GROUP_JOINED()
|
|
if self.isInTestMode then
|
|
self:Test()
|
|
end
|
|
self.joinedNewGroup = true
|
|
|
|
if self.isInArena and C_PvP_IsRatedSoloShuffle() then
|
|
self:ResetAllIcons("joinedPvP", true)
|
|
if not self.callbackTimers.arenaTicker then
|
|
|
|
self.callbackTimers.arenaTicker = C_Timer.NewTicker(6, inspectAllGroupMembers, 5)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function IsAnyExBarEnabled()
|
|
for key in pairs(P.extraBars) do
|
|
local db = E.db.extraBars[key]
|
|
if db.enabled then return true end
|
|
end
|
|
end
|
|
|
|
|
|
function P:PLAYER_ENTERING_WORLD(isInitialLogin, isReloadingUi, isRefresh)
|
|
local _, instanceType = IsInInstance()
|
|
self.zone = instanceType
|
|
self.isInDungeon = instanceType == "party"
|
|
self.isInArena = instanceType == "arena"
|
|
self.isInBG = instanceType == "pvp"
|
|
self.isInPvPInstance = self.isInArena or self.isInBG
|
|
|
|
if not isRefresh and self.isInTestMode then
|
|
self:Test()
|
|
end
|
|
|
|
self.disabledZone = not self.isInTestMode and not E.profile.Party.visibility[instanceType]
|
|
if self.disabledZone then
|
|
self:ResetModule()
|
|
return
|
|
end
|
|
|
|
local zone = self.isInTestMode and self.testZone or instanceType
|
|
zone = zone == "none" and E.profile.Party.noneZoneSetting or (zone == "scenario" and E.profile.Party.scenarioZoneSetting) or zone
|
|
E.db = E.profile.Party[zone]
|
|
self.db = E.db
|
|
for key, frame in pairs(self.extraBars) do
|
|
frame.db = E.db.extraBars[key]
|
|
end
|
|
|
|
self.isUserHidden = not self.isInTestMode and not E.db.general.showPlayer
|
|
self.isUserDisabled = self.isUserHidden and (not E.db.general.showPlayerEx or not IsAnyExBarEnabled())
|
|
self.isPvP = E.preMoP or self.isInPvPInstance or (instanceType == "none" and C_PvP.IsWarModeDesired())
|
|
self.effectivePixelMult = nil
|
|
|
|
CD:UpdateCombatLogVar()
|
|
wipe(CD.diedHostileGUIDS)
|
|
wipe(CD.dispelledHostileGUIDS)
|
|
|
|
E:SetActiveUnitFrameData()
|
|
self:UpdateEnabledSpells()
|
|
self:UpdatePositionValues()
|
|
self:UpdateExBarPositionValues()
|
|
|
|
self:RegisterZoneEvents()
|
|
|
|
if self.isInPvPInstance then
|
|
self:ResetAllIcons("joinedPvP")
|
|
end
|
|
if self.isInArena then
|
|
if not self.callbackTimers.arenaTicker then
|
|
self.callbackTimers.arenaTicker = C_Timer.NewTicker(12, inspectAllGroupMembers, 6)
|
|
end
|
|
else
|
|
if self.callbackTimers.arenaTicker then
|
|
self.callbackTimers.arenaTicker:Cancel()
|
|
self.callbackTimers.arenaTicker = nil
|
|
end
|
|
end
|
|
|
|
|
|
self:GROUP_ROSTER_UPDATE(true, isRefresh)
|
|
end
|
|
|
|
function P:CHAT_MSG_BG_SYSTEM_NEUTRAL(arg1)
|
|
if self.disabled then return end
|
|
if strfind(arg1, "!$") then
|
|
CM:EnqueueInspect(true)
|
|
end
|
|
end
|
|
|
|
function P:UPDATE_UI_WIDGET(widgetInfo)
|
|
if self.disabled then return end
|
|
if widgetInfo.widgetSetID == 1 and widgetInfo.widgetType == 0 then
|
|
local info = C_UIWidgetManager.GetIconAndTextWidgetVisualizationInfo(widgetInfo.widgetID)
|
|
if info and info.state == 1 and info.hasTimer then
|
|
self:UnregisterZoneEvents()
|
|
C_Timer.After(.5, inspectAllGroupMembers)
|
|
end
|
|
end
|
|
end
|
|
|
|
function P:PLAYER_REGEN_ENABLED()
|
|
self.inLockdown = false
|
|
self:UpdatePassThroughButtons()
|
|
end
|
|
|
|
function P:PLAYER_REGEN_DISABLED()
|
|
self.inLockdown = true
|
|
if self.callbackTimers.arenaTicker then
|
|
self.callbackTimers.arenaTicker:Cancel()
|
|
self.callbackTimers.arenaTicker = nil
|
|
end
|
|
|
|
end
|
|
|
|
function P:PLAYER_FLAGS_CHANGED(unitTarget)
|
|
if unitTarget ~= "player" or self.inLockdown then return end
|
|
local oldpvp = self.isPvP
|
|
self.isPvP = C_PvP.IsWarModeDesired()
|
|
if oldpvp ~= self.isPvP then
|
|
self:UpdateAllBars()
|
|
CM:EnqueueInspect(true)
|
|
end
|
|
end
|
|
|
|
function P:CHALLENGE_MODE_START()
|
|
CM:EnqueueInspect(true)
|
|
self:ResetAllIcons()
|
|
self:UnregisterZoneEvents()
|
|
end
|
|
|
|
function P:ENCOUNTER_END(encounterID, encounterName, difficultyID, groupSize, success)
|
|
if groupSize > 5 then
|
|
self:ResetAllIcons("encounterEnd")
|
|
end
|
|
end
|
|
|