local BossBar = ZO_Object:Subclass() local SMOOTH_ANIMATE_BAR = true local SET_BAR = false function BossBar:New(...) local bar = ZO_Object.New(self) bar:Initialize(...) return bar end function BossBar:Initialize(control) self.control = control self.healthText = control:GetNamedChild("HealthText") self.bars = { GetControl(control, "HealthBarLeft"), GetControl(control, "HealthBarRight") } self.bossHealthValues = {} for i = 1, #self.bars do local gradient = ZO_POWER_BAR_GRADIENT_COLORS[COMBAT_MECHANIC_FLAGS_HEALTH] ZO_StatusBar_SetGradientColor(self.bars[i], gradient) end self.bossUnitTags = {} for i = BOSS_RANK_ITERATION_BEGIN, BOSS_RANK_ITERATION_END do self.bossUnitTags["boss"..i] = true end local function PowerUpdateHandlerFunction(unitTag, powerPoolIndex, powerType, powerPool, powerPoolMax) self:OnPowerUpdate(unitTag, powerType) end local powerUpdateEventHandler = ZO_MostRecentPowerUpdateHandler:New("BossBar", PowerUpdateHandlerFunction) powerUpdateEventHandler:AddFilterForEvent(REGISTER_FILTER_POWER_TYPE, COMBAT_MECHANIC_FLAGS_HEALTH) powerUpdateEventHandler:AddFilterForEvent(REGISTER_FILTER_UNIT_TAG_PREFIX, "boss") control:RegisterForEvent(EVENT_BOSSES_CHANGED, function(_, forceReset) self:RefreshAllBosses(forceReset) end) control:RegisterForEvent(EVENT_PLAYER_ACTIVATED, function() self:OnPlayerActivated() end) control:RegisterForEvent(EVENT_INTERFACE_SETTING_CHANGED, function(_, settingSystem, settingId) self:OnInterfaceSettingChanged(settingSystem, settingId) end) self:ApplyStyle() -- Setup initial visual style based on current mode. control:RegisterForEvent(EVENT_GAMEPAD_PREFERRED_MODE_CHANGED, function() self:OnGamepadPreferredModeChanged() end) end function BossBar:ApplyStyle() ApplyTemplateToControl(self.control, ZO_GetPlatformTemplate("ZO_BossBar")) end function BossBar:OnGamepadPreferredModeChanged() self:ApplyStyle() end function BossBar:AddBoss(unitTag) self.bossHealthValues[unitTag] = {} self:RefreshBossHealth(unitTag) end function BossBar:RemoveBoss(unitTag) self.bossHealthValues[unitTag] = nil end function BossBar:RefreshBossHealth(unitTag) local bossEntry = self.bossHealthValues[unitTag] if bossEntry ~= nil then local health, maxHealth = GetUnitPower(unitTag, COMBAT_MECHANIC_FLAGS_HEALTH) bossEntry.health = health bossEntry.maxHealth = maxHealth end end function BossBar:RefreshBossHealthBar(smoothAnimate) local totalHealth = 0 local totalMaxHealth = 0 for unitTag, bossEntry in pairs(self.bossHealthValues) do totalHealth = totalHealth + bossEntry.health totalMaxHealth = totalMaxHealth + bossEntry.maxHealth end local halfHealth = zo_floor(totalHealth / 2) local halfMax = zo_max(zo_floor(totalMaxHealth / 2), 1) for i = 1, #self.bars do ZO_StatusBar_SmoothTransition(self.bars[i], halfHealth, halfMax, not smoothAnimate) end self.healthText:SetText(ZO_FormatResourceBarCurrentAndMax(totalHealth, totalMaxHealth)) COMPASS_FRAME:SetBossBarActive(totalHealth > 0) end function BossBar:RefreshAllBosses(forceReset) --if there are multiple bosses and one of them dies and despawns in the middle of the fight we --still want to show them as part of the boss bar (otherwise it will reset to 100%). local currentBossCount = 0 for unitTag in pairs(self.bossUnitTags) do if(DoesUnitExist(unitTag)) then self:AddBoss(unitTag) currentBossCount = currentBossCount + 1 end end --if there are no bosses left it's safe to reset everything if(forceReset or (currentBossCount == 0 and next(self.bossHealthValues) ~= nil)) then self.bossHealthValues = {} end self:RefreshBossHealthBar(SET_BAR) end --Events function BossBar:OnPowerUpdate(unitTag, powerType) if(self.bossUnitTags[unitTag]) then self:RefreshBossHealth(unitTag) self:RefreshBossHealthBar(SMOOTH_ANIMATE_BAR) end end function BossBar:OnPlayerActivated() self:RefreshAllBosses() COMPASS_FRAME:SetBossBarReady(true) end function BossBar:OnInterfaceSettingChanged(settingSystem, settingId) if settingSystem == SETTING_TYPE_UI and settingId == UI_SETTING_RESOURCE_NUMBERS then self:RefreshBossHealthBar(SET_BAR) end end --Global XML function ZO_BossBar_OnInitialized(self) BOSS_BAR = BossBar:New(self) end