NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

buffButtons.py (23339B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\inflight\shipHud\buffButtons.py
      2 from collections import OrderedDict
      3 from operator import itemgetter
      4 from carbon.common.lib.const import MSEC
      5 import carbonui.const as uiconst
      6 from carbon.common.script.util.timerstuff import AutoTimer
      7 from dbuff.client.uiFormatters import GetDisplayNameAndValue
      8 import eve.client.script.parklife.states as stateConst
      9 import dotWeapons.client.dotClientUtil as dotClientUtil
     10 from eve.client.script.ui.inflight.shipHud.buffButtonsUtil import HintRow
     11 from eve.common.script.mgt.buffBarConst import DBUFFS_BY_SLOT, Slot_DotWeaponTarget, Slot_DotWeaponAttacker
     12 import evetypes
     13 from gametime import GetSimTime
     14 from localization.formatters import FormatTimeIntervalShortWritten
     15 import trinity
     16 from carbonui.primitives.container import Container
     17 from carbonui.primitives.sprite import Sprite
     18 from eve.client.script.ui.control.eveIcon import Icon
     19 from eve.client.script.ui.inflight.moduleEffectTimer import ModuleEffectTimer
     20 from eve.common.script.mgt import buffBarConst
     21 from localization import GetByLabel
     22 from localization.util import Sort
     23 from carbonui.uicore import uicore
     24 from eveservices.menu import GetMenuService
     25 MAX_ITEMS_IN_HINT = 6
     26 SLOT_WIDTH = 48
     27 ICON_SIZE = 40
     28 
     29 class BuffHintProvider(object):
     30 
     31     def __init__(self, effectType):
     32         self.effectType = effectType
     33         self.dbuffIDsForButton = DBUFFS_BY_SLOT.get(effectType, [])
     34         captionLabel = buffBarConst.BUFF_SLOT_HINTS.get(effectType, None)
     35         if captionLabel is not None:
     36             self.caption = '<b>%s</b>' % GetByLabel(captionLabel)
     37         else:
     38             self.caption = None
     39 
     40     def GetCaptionHintList(self):
     41         items = []
     42         if self.caption:
     43             items.append(HintRow(col1=self.caption))
     44         return items
     45 
     46     def GetNormalHintList(self, effectSources):
     47         items = []
     48         if self.effectType == buffBarConst.Slot_Electronic:
     49             items.extend(self._GetEcmHintItems(effectSources))
     50         else:
     51             items.extend(self._GetBuffHintItems(effectSources))
     52         return items
     53 
     54     def _GetEcmHintItems(self, effectSources):
     55         ewarAggressors = self._GetEwarAggressorsByJammingType(effectSources)
     56         activeList = []
     57         inactiveList = []
     58         for sourceID, moduleCount, activeCount in ewarAggressors:
     59             if activeCount:
     60                 targetedBuffSourceText = self._GetTextForTargetedBuffSource(sourceID, activeCount)
     61                 if targetedBuffSourceText:
     62                     activeList.append(targetedBuffSourceText)
     63             if moduleCount > activeCount:
     64                 targetedBuffSourceText = self._GetTextForTargetedBuffSource(sourceID, moduleCount - activeCount)
     65                 if targetedBuffSourceText:
     66                     inactiveList.append(targetedBuffSourceText)
     67 
     68         Sort(activeList, key=lambda x: x.col2)
     69         Sort(inactiveList, key=lambda x: x.col2)
     70         hintList = activeList[:MAX_ITEMS_IN_HINT]
     71         if len(activeList) < MAX_ITEMS_IN_HINT and len(inactiveList):
     72             hintList.append(HintRow(fullRowText='<color=gray>%s</color>' % GetByLabel('UI/Inflight/EwarHints/FailedEwarAttempts')))
     73             for eachHintRow in inactiveList[:MAX_ITEMS_IN_HINT - len(activeList)]:
     74                 hintList.append(eachHintRow)
     75 
     76         extraAttackers = len(activeList) + len(inactiveList) - MAX_ITEMS_IN_HINT
     77         hintList += self._GetExtraAttackersText(extraAttackers)
     78         return hintList
     79 
     80     def _GetEwarAggressorsByJammingType(self, effectSources):
     81         activeModulesBySource = self._FindActiveJammers()
     82         ewarAggressors = []
     83         for sourceID, moduleCount in effectSources.iteritems():
     84             activeCount = activeModulesBySource.get(sourceID, 0)
     85             ewarAggressors.append((sourceID, moduleCount, activeCount))
     86 
     87         ewarAggressors.sort(key=lambda x: -x[2])
     88         return ewarAggressors
     89 
     90     def _FindActiveJammers(self):
     91         allActiveJams = sm.GetService('godma').activeJams
     92         activeJammers = {}
     93         for sourceBallID, moduleID, targetBallID, _jammingType in allActiveJams:
     94             if self.effectType != _jammingType:
     95                 continue
     96             count = activeJammers.get(sourceBallID, 0)
     97             activeJammers[sourceBallID] = count + 1
     98 
     99         return activeJammers
    100 
    101     def GetDbuffHintItemList(self, incomingDbuffTracker):
    102         hintList = []
    103         for dbuffID in self.dbuffIDsForButton:
    104             buffState = incomingDbuffTracker.incomingDbuffs.get(dbuffID, None)
    105             if buffState is not None:
    106                 buffValue, expiryTime = buffState
    107                 displayName, formattedValue = GetDisplayNameAndValue(dbuffID, buffValue)
    108                 if displayName is None:
    109                     continue
    110                 if expiryTime is not None:
    111                     timeRemaining = max(0, expiryTime - GetSimTime())
    112                     formattedTimeRemaining = FormatTimeIntervalShortWritten(timeRemaining)
    113                 else:
    114                     formattedTimeRemaining = ''
    115                 hr = HintRow(col1=formattedValue, col2=displayName, col3=formattedTimeRemaining)
    116                 hintList.append(hr)
    117 
    118         return hintList
    119 
    120     def _GetBuffHintItems(self, effectSources):
    121         hintList = []
    122         extraAttackers = 0
    123         sortedEffectSources = sorted(effectSources.iteritems(), key=itemgetter(1), reverse=True)
    124         for shipID, num in sortedEffectSources:
    125             if len(hintList) >= MAX_ITEMS_IN_HINT:
    126                 extraAttackers = len(effectSources) - len(hintList)
    127                 break
    128             targetedBuffSourceText = self._GetTextForTargetedBuffSource(shipID, num)
    129             if targetedBuffSourceText:
    130                 hintList.append(targetedBuffSourceText)
    131 
    132         hintList = Sort(hintList, key=lambda x: x.col2)
    133         hintList += self._GetExtraAttackersText(extraAttackers)
    134         return hintList
    135 
    136     def _GetTextForTargetedBuffSource(self, sourceID, numModules):
    137         invItem = sm.GetService('michelle').GetBallpark().GetInvItem(sourceID)
    138         if not invItem:
    139             return
    140         attackerShipTypeID = invItem.typeID
    141         numModulesText = GetByLabel('UI/Inflight/NumAttacks', num=numModules)
    142         hr = HintRow(col1=numModulesText)
    143         if invItem.charID:
    144             attackerID = invItem.charID
    145             hr.col2 = GetByLabel('UI/Inflight/EwarAttacker2', attackerID=attackerID, attackerShipID=attackerShipTypeID)
    146         else:
    147             hr.col2 = GetByLabel('UI/Inflight/EwarAttackerNPC2', attackerShipID=attackerShipTypeID)
    148         return hr
    149 
    150     def _GetExtraAttackersText(self, extraAttackers):
    151         if extraAttackers > 0:
    152             return [HintRow(col2=GetByLabel('UI/Inflight/AndMorewarAttackers', num=extraAttackers))]
    153         return []
    154 
    155     def GetDotWeaponHintList(self, incomingDotWeaponTracker):
    156         hintList = []
    157         if self.effectType == Slot_DotWeaponTarget:
    158             hintList += dotClientUtil.GetTotalTimeHintRow(incomingDotWeaponTracker)
    159             hintList += dotClientUtil.GetFormattedDotInfoForCurrentShip(incomingDotWeaponTracker)
    160         if self.effectType == Slot_DotWeaponAttacker:
    161             hintList += dotClientUtil.GetFormattedPendingDotsAsAttacker(incomingDotWeaponTracker)
    162         return hintList
    163 
    164 
    165 class BuffBtnController(object):
    166 
    167     def __init__(self, effectType):
    168         self.effectType = effectType
    169         self.tacticalSvc = sm.GetService('tactical')
    170         self.hintProvider = BuffHintProvider(self.effectType)
    171 
    172     def GetCaptionHintList(self):
    173         return self.hintProvider.GetCaptionHintList()
    174 
    175     def GetNormalHintList(self):
    176         effectSources = self._FindWhoIsAffectingMe()
    177         return self.hintProvider.GetNormalHintList(effectSources)
    178 
    179     def GetDbuffHintItemList(self):
    180         incomingDbuffTracker = sm.GetService('dbuffClient').incomingDbuffTracker
    181         return self.hintProvider.GetDbuffHintItemList(incomingDbuffTracker)
    182 
    183     def GetDotWeaponItemList(self):
    184         incomingDotWeaponTracker = sm.GetService('dotWeaponSvc').incomingDotTracker
    185         return self.hintProvider.GetDotWeaponHintList(incomingDotWeaponTracker)
    186 
    187     def GetButtonMenu(self):
    188         effectSources = self._FindWhoIsAffectingMe()
    189         ballpark = sm.GetService('michelle').GetBallpark()
    190         m = []
    191         for shipID, num in effectSources.iteritems():
    192             invItem = ballpark.GetInvItem(shipID)
    193             if invItem:
    194                 if invItem.charID:
    195                     sourceName = cfg.eveowners.Get(invItem.charID).name
    196                 else:
    197                     sourceName = evetypes.GetName(invItem.typeID)
    198                 m.append([sourceName, ('isDynamic', GetMenuService().CelestialMenu, (invItem.itemID,
    199                    None,
    200                    invItem,
    201                    invItem.typeID))])
    202 
    203         m = Sort(m, key=lambda x: x[0])
    204         return m
    205 
    206     def OnButtonClick(self):
    207         if not uicore.cmd.IsSomeCombatCommandLoaded():
    208             return
    209         michelle = sm.GetService('michelle')
    210         stateSvc = sm.GetService('stateSvc')
    211         targets = []
    212         effectSources = self._FindWhoIsAffectingMe()
    213         targetStates = (stateConst.targeted, stateConst.targeting)
    214         targeting = uicore.cmd.combatCmdLoaded.name == 'CmdLockTargetItem'
    215         for sourceID in effectSources:
    216             try:
    217                 if targeting and any(stateSvc.GetStates(sourceID, targetStates)):
    218                     continue
    219                 ball = michelle.GetBall(sourceID)
    220                 targets.append((ball.surfaceDist, sourceID))
    221             except RuntimeError:
    222                 pass
    223 
    224         if len(targets) > 0:
    225             targets.sort()
    226             itemID = targets[0][1]
    227             uicore.cmd.ExecuteCombatCommand(itemID, uiconst.UI_CLICK)
    228 
    229     def _FindWhoIsAffectingMe(self):
    230         return self.tacticalSvc.GetEffectSourcesAndCountByJammingType(self.effectType)
    231 
    232 
    233 class BuffSlotParent(Container):
    234     default_align = uiconst.TOLEFT
    235     default_width = SLOT_WIDTH
    236     default_height = ICON_SIZE
    237     effectGuidForButtonType = None
    238     dbuffIDsForButton = None
    239     currentDbuffExpiryTime = None
    240     currentDotExpiryTime = None
    241 
    242     def ApplyAttributes(self, attributes):
    243         Container.ApplyAttributes(self, attributes)
    244         self.display = False
    245         self.fadingOut = False
    246         self.effectType = attributes.effectType
    247         graphicID = attributes.graphicID
    248         btnClass = BUTTON_CLASS_BY_SLOT.get(self.effectType, BuffButton)
    249         self.btn = btnClass(parent=self, name=self.effectType, align=uiconst.CENTER, width=ICON_SIZE, height=ICON_SIZE, graphicID=graphicID, effectType=self.effectType)
    250         self.effectGuidForButtonType = buffBarConst.FX_GUIDS_BY_SLOT.get(self.effectType, None)
    251         self.dbuffIDsForButton = DBUFFS_BY_SLOT.get(self.effectType, [])
    252 
    253     def UpdateVisibility(self, jammersByType, myShipEffectGuids, incomingDbuffTracker, incomingDotTracker, genericBuffBarIcons, doAnimate):
    254         if self._ShouldBeVisible(jammersByType, myShipEffectGuids, incomingDbuffTracker, incomingDotTracker, genericBuffBarIcons):
    255             if self.btn.IsOffensive():
    256                 order = self._GetNumberOfActiveDebuffs(jammersByType) - 1
    257             else:
    258                 order = -1
    259             self.FadeButtonIn(doAnimate, order)
    260         else:
    261             self.FadeButtonOut(doAnimate)
    262 
    263     def _ShouldBeVisible(self, jammersByType, myShipEffectGuids, incomingDbuffTracker, incomingDotTracker, genericBuffBarIcons):
    264         if jammersByType.get(self.effectType, None):
    265             return True
    266         if self.effectGuidForButtonType and self.effectGuidForButtonType in myShipEffectGuids:
    267             return True
    268         if self.effectType in genericBuffBarIcons:
    269             return True
    270         for dbuffID in self.dbuffIDsForButton:
    271             if dbuffID in incomingDbuffTracker.incomingDbuffs:
    272                 return True
    273 
    274         if self.effectType == Slot_DotWeaponTarget and incomingDotTracker.CurrentShipHasIncomingDotApps():
    275             return True
    276         if self.effectType == Slot_DotWeaponAttacker and incomingDotTracker.ShouldShowAttackingBtn():
    277             return True
    278         return False
    279 
    280     def _GetNumberOfActiveDebuffs(self, jammersByType):
    281         return len(jammersByType.get(self.effectType, []))
    282 
    283     def FadeButtonIn(self, doAnimate = False, order = -1):
    284         if not self.display or self.fadingOut:
    285             self.fadingOut = False
    286             self.SetOrder(order)
    287             self.display = True
    288             if doAnimate:
    289                 uicore.animations.FadeIn(self, duration=0.25)
    290                 uicore.animations.MorphScalar(self, 'width', startVal=0, endVal=SLOT_WIDTH, duration=0.25)
    291             else:
    292                 self.opacity = 1.0
    293                 self.width = SLOT_WIDTH
    294 
    295     def FadeButtonOut(self, doAnimate = True):
    296         if not self.display:
    297             return
    298         if not self.fadingOut:
    299             self.fadingOut = True
    300             if doAnimate:
    301                 uicore.animations.MorphScalar(self, 'width', startVal=SLOT_WIDTH, endVal=0, duration=0.25)
    302                 uicore.animations.FadeOut(self, duration=0.25, sleep=True)
    303                 if self.fadingOut:
    304                     self.display = False
    305             else:
    306                 self.display = False
    307                 self.opacity = 0.0
    308                 self.width = 0
    309 
    310     def UpdateDbuffTimer(self, incomingDbuffTracker):
    311         myDbuffExpiryTimes = [ expiryTime for dbuffID, (value, expiryTime) in incomingDbuffTracker.incomingDbuffs.iteritems() if dbuffID in self.dbuffIDsForButton ]
    312         if len(myDbuffExpiryTimes) == 0 or None in myDbuffExpiryTimes:
    313             self.currentDbuffExpiryTime = None
    314             self.btn.RemoveTimer('DBUFF_TIMER_ID')
    315         else:
    316             latestExpiryTime = max(myDbuffExpiryTimes)
    317             if self.currentDbuffExpiryTime != latestExpiryTime:
    318                 self.currentDbuffExpiryTime = latestExpiryTime
    319                 duration = max((latestExpiryTime - GetSimTime()) / MSEC, 0.2)
    320                 self.btn.GetTimer('DBUFF_TIMER_ID').StartTimer(duration)
    321 
    322     def UpdateDotTimer(self, incomingDotTracker):
    323         if self.effectType != Slot_DotWeaponTarget:
    324             return
    325         latestExpiryTime = incomingDotTracker.GetLastExpiryTimestampForCurrentShip()
    326         nowInSim = GetSimTime()
    327         timerID = 'DOT_TIMER_ID'
    328         if latestExpiryTime < nowInSim:
    329             self.currentDbuffExpiryTime = None
    330             self.btn.RemoveTimer(timerID)
    331         elif self.currentDotExpiryTime != latestExpiryTime:
    332             self.currentDotExpiryTime = latestExpiryTime
    333             duration = max((latestExpiryTime - nowInSim) / MSEC, 0.2)
    334             self.btn.GetTimer(timerID).StartTimer(duration)
    335 
    336 
    337 class BuffButton(Container):
    338     __guid__ = 'BuffButton'
    339     default_state = uiconst.UI_NORMAL
    340     default_align = uiconst.RELATIVE
    341     default_pickRadius = -1
    342     ICON_BASE_ALPHA = 1.0
    343     ICON_HIGHLIGHTED_ALPHA = 1.5
    344     ICON_COLOR = (1.0,
    345      1.0,
    346      1.0,
    347      ICON_BASE_ALPHA)
    348     SLOT_COLOR = (1.0, 1.0, 1.0, 1)
    349     SLOT_TEXTURE_PATH = 'res:/UI/Texture/classes/ShipUI/EwarBar/ewarBarUnderlayClean.png'
    350     SLOT_GRADIENT_TEXTURE_PATH = 'res:/UI/Texture/classes/ShipUI/EwarBar/ewarBarUnderlayGrad.png'
    351     SLOT_BASE_ALPHA = 0.2
    352     SLOT_GRADIENT_ALPHA = 0.25
    353     SHADOW_COLOR = (1.0, 1.0, 1.0, 0.25)
    354     SHADOW_TEXTURE_PATH = 'res:/UI/Texture/classes/ShipUI/EwarBar/ewarBarShadow.png'
    355     TIMER_OPACITY = 0.65
    356     TIMER_COLOR = (1.0, 1.0, 1.0)
    357     TIMER_RIGHT_COUNTER_TEXTURE_PATH = 'res:/UI/Texture/classes/ShipUI/EwarBar/ewarCounterRight.png'
    358     TIMER_LEFT_COUNTER_TEXTURE_PATH = 'res:/UI/Texture/classes/ShipUI/EwarBar/ewarCounterLeft.png'
    359     TIMER_COUNTER_GAUGE_TEXTURE_PATH = 'res:/UI/Texture/classes/ShipUI/EwarBar/ewarCounterGauge.png'
    360     TIMER_INCREASE = False
    361     isOffensive = False
    362 
    363     def ApplyAttributes(self, attributes):
    364         Container.ApplyAttributes(self, attributes)
    365         self.btnName = attributes.btnName
    366         self.effectType = attributes.effectType
    367         self.orgTop = None
    368         self.timers = OrderedDict()
    369         self._tooltipUpdateTimer = None
    370         self.controller = BuffBtnController(self.effectType)
    371         graphicID = attributes.graphicID
    372         iconSize = self.height
    373         self.icon = Icon(parent=self, name='bufficon', pos=(0,
    374          0,
    375          iconSize,
    376          iconSize), align=uiconst.CENTER, state=uiconst.UI_DISABLED, ignoreSize=1, color=self.ICON_COLOR)
    377         Sprite(parent=self, name='slot_gradient', align=uiconst.TOALL, state=uiconst.UI_DISABLED, color=self.SLOT_COLOR, blendMode=trinity.TR2_SBM_ADD, texturePath=self.SLOT_GRADIENT_TEXTURE_PATH, opacity=self.SLOT_GRADIENT_ALPHA)
    378         Sprite(parent=self, name='slot_base', align=uiconst.TOALL, state=uiconst.UI_DISABLED, color=self.SLOT_COLOR, blendMode=trinity.TR2_SBM_ADD, texturePath=self.SLOT_TEXTURE_PATH, opacity=self.SLOT_BASE_ALPHA)
    379         Sprite(parent=self, name='shadow', align=uiconst.TOALL, state=uiconst.UI_DISABLED, color=self.SHADOW_COLOR, texturePath=self.SHADOW_TEXTURE_PATH)
    380         self.LoadIcon(graphicID)
    381 
    382     def LoadIcon(self, graphicID):
    383         self.icon.LoadIconByIconID(graphicID)
    384 
    385     def GetTimer(self, timerId):
    386         if timerId not in self.timers:
    387             timer = ModuleEffectTimer(parent=self, timerColor=self.TIMER_COLOR, timerOpacity=self.TIMER_OPACITY, timerRightCounterTexturePath=self.TIMER_RIGHT_COUNTER_TEXTURE_PATH, timerLeftCounterTexturePath=self.TIMER_LEFT_COUNTER_TEXTURE_PATH, timerCounterGaugeTexturePath=self.TIMER_COUNTER_GAUGE_TEXTURE_PATH, timeIncreases=self.TIMER_INCREASE, idx=0)
    388             self.timers[timerId] = timer
    389         else:
    390             timer = self.timers.pop(timerId)
    391             self.timers[timerId] = timer
    392         return timer
    393 
    394     def RemoveTimer(self, timerId):
    395         if timerId in self.timers:
    396             self.timers[timerId].RemoveTimer()
    397             del self.timers[timerId]
    398 
    399     def GetHint(self):
    400         return ''
    401 
    402     def LoadTooltipPanel(self, tooltipPanel, *args, **kwds):
    403         tooltipPanel.LoadGeneric3ColumnTemplate()
    404         tooltipPanel.cellSpacing = (10, 4)
    405         self._LoadTooltipPanel(tooltipPanel)
    406         self._tooltipUpdateTimer = AutoTimer(250, self._LoadTooltipPanel, tooltipPanel)
    407 
    408     def _LoadTooltipPanel(self, tooltipPanel):
    409         if tooltipPanel.destroyed:
    410             self._tooltipUpdateTimer = None
    411             return
    412         tooltipPanel.Flush()
    413         hintList = self.controller.GetCaptionHintList()
    414         for eachHintRow in hintList:
    415             tooltipPanel.AddLabelLarge(text=eachHintRow.col1, colSpan=3)
    416 
    417         hintList = self.controller.GetNormalHintList()
    418         hintList += self.controller.GetDotWeaponItemList()
    419         hintList += self.controller.GetDbuffHintItemList()
    420         for eachHintRow in hintList:
    421             if eachHintRow.fullRowText:
    422                 tooltipPanel.AddLabelMedium(text=eachHintRow.fullRowText, colSpan=3)
    423             else:
    424                 tooltipPanel.AddLabelMedium(text=eachHintRow.col1, align=uiconst.CENTERRIGHT)
    425                 tooltipPanel.AddLabelMedium(text=eachHintRow.col2)
    426                 if eachHintRow.col3:
    427                     tooltipPanel.AddLabelMedium(text=eachHintRow.col3)
    428                 tooltipPanel.FillRow()
    429 
    430     def OnMouseEnter(self, *args):
    431         self.icon.SetAlpha(self.ICON_HIGHLIGHTED_ALPHA)
    432 
    433     def OnMouseExit(self, *args):
    434         if getattr(self, 'orgTop', None) is not None:
    435             self.top = self.orgTop
    436         self.icon.SetAlpha(self.ICON_BASE_ALPHA)
    437 
    438     def GetMenu(self, *args):
    439         return self.controller.GetButtonMenu()
    440 
    441     def OnClick(self, *args):
    442         return self.controller.OnButtonClick()
    443 
    444     def IsOffensive(self):
    445         return self.isOffensive
    446 
    447 
    448 class OffensiveBuffButton(BuffButton):
    449     SLOT_COLOR = (0.7, 0.0, 0.0, 1)
    450     ICON_COLOR = (1.0,
    451      0.7,
    452      0.7,
    453      BuffButton.ICON_BASE_ALPHA)
    454     TIMER_COLOR = (1.0, 0.3, 0.0)
    455     isOffensive = True
    456 
    457 
    458 class DefensiveBuffButton(BuffButton):
    459     SLOT_COLOR = (0.0, 0.6, 0.6, 1)
    460     ICON_COLOR = (0.7,
    461      1,
    462      1,
    463      BuffButton.ICON_BASE_ALPHA)
    464     TIMER_COLOR = (0.0, 0.8, 0.8)
    465     isOffensive = False
    466 
    467 
    468 BUTTON_CLASS_BY_SLOT = {buffBarConst.Slot_WarpScramblerMWD: OffensiveBuffButton,
    469  buffBarConst.Slot_WarpScrambler: OffensiveBuffButton,
    470  buffBarConst.Slot_FighterTackle: OffensiveBuffButton,
    471  buffBarConst.Slot_FocusedWarpScrambler: OffensiveBuffButton,
    472  buffBarConst.Slot_Webify: OffensiveBuffButton,
    473  buffBarConst.Slot_Electronic: OffensiveBuffButton,
    474  buffBarConst.Slot_EwRemoteSensorDamp: OffensiveBuffButton,
    475  buffBarConst.Slot_EwTrackingDisrupt: OffensiveBuffButton,
    476  buffBarConst.Slot_EwGuidanceDisrupt: OffensiveBuffButton,
    477  buffBarConst.Slot_EwTargetPaint: OffensiveBuffButton,
    478  buffBarConst.Slot_EwEnergyVampire: OffensiveBuffButton,
    479  buffBarConst.Slot_EwEnergyNeut: OffensiveBuffButton,
    480  buffBarConst.Slot_RemoteTracking: DefensiveBuffButton,
    481  buffBarConst.Slot_EnergyTransfer: DefensiveBuffButton,
    482  buffBarConst.Slot_SensorBooster: DefensiveBuffButton,
    483  buffBarConst.Slot_EccmProjector: DefensiveBuffButton,
    484  buffBarConst.Slot_RemoteHullRepair: DefensiveBuffButton,
    485  buffBarConst.Slot_RemoteArmorRepair: DefensiveBuffButton,
    486  buffBarConst.Slot_ShieldTransfer: DefensiveBuffButton,
    487  buffBarConst.Slot_Tethering: DefensiveBuffButton,
    488  buffBarConst.Slot_TetheringRepair: DefensiveBuffButton,
    489  buffBarConst.Slot_ShieldBurst: DefensiveBuffButton,
    490  buffBarConst.Slot_ArmorBurst: DefensiveBuffButton,
    491  buffBarConst.Slot_InformationBurst: DefensiveBuffButton,
    492  buffBarConst.Slot_SkirmishBurst: DefensiveBuffButton,
    493  buffBarConst.Slot_MiningBurst: DefensiveBuffButton,
    494  buffBarConst.Slot_InvulnerabilityBurst: DefensiveBuffButton,
    495  buffBarConst.Slot_TitanBurst: DefensiveBuffButton,
    496  buffBarConst.Slot_NotTethered: OffensiveBuffButton,
    497  buffBarConst.Slot_RemoteArmorMutadaptiveRepairer: DefensiveBuffButton,
    498  buffBarConst.Slot_CloakDisrupt: OffensiveBuffButton,
    499  buffBarConst.Slot_CloakDefense: DefensiveBuffButton,
    500  buffBarConst.Slot_LinkWithShipBonuses: DefensiveBuffButton,
    501  buffBarConst.Slot_TetheringRestrictedBySecurity: OffensiveBuffButton,
    502  buffBarConst.Slot_RemoteRepairImpedance: OffensiveBuffButton,
    503  buffBarConst.Slot_DotWeaponTarget: OffensiveBuffButton,
    504  buffBarConst.Slot_DotWeaponAttacker: DefensiveBuffButton,
    505  buffBarConst.Slot_LinkedToTraceGate: DefensiveBuffButton,
    506  buffBarConst.Slot_ExpeditionBurst: DefensiveBuffButton,
    507  buffBarConst.Slot_PhaseStabilizer: DefensiveBuffButton,
    508  buffBarConst.Slot_SOEEnvironmentSystemEffect: DefensiveBuffButton,
    509  buffBarConst.Slot_HordeModeStructureEffects: OffensiveBuffButton,
    510  buffBarConst.Slot_HordeModeWreckEffects: OffensiveBuffButton,
    511  buffBarConst.Slot_HordeModeBonusEffects: DefensiveBuffButton,
    512  buffBarConst.Slot_FactionWarfareDungeonEffectAmarr: DefensiveBuffButton,
    513  buffBarConst.Slot_FactionWarfareDungeonEffectCaldari: DefensiveBuffButton,
    514  buffBarConst.Slot_FactionWarfareDungeonEffectGallente: DefensiveBuffButton,
    515  buffBarConst.Slot_FactionWarfareDungeonEffectMinmatar: DefensiveBuffButton,
    516  buffBarConst.Slot_FactionWarfareDungeonEffectGeneric: DefensiveBuffButton,
    517  buffBarConst.Slot_FactionWarfareDungeonEffectChaos: DefensiveBuffButton,
    518  buffBarConst.Slot_AIREpicArcEffects: DefensiveBuffButton,
    519  buffBarConst.Slot_BreacherPodDamageControl: DefensiveBuffButton}