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

crimewatchHints.py (24532B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\crimewatch\crimewatchHints.py
      2 import dogma.data as dogma_data
      3 from carbonui.primitives.container import Container
      4 from carbonui.primitives.containerAutoSize import ContainerAutoSize
      5 from carbonui.primitives.frame import Frame
      6 from carbonui.primitives.sprite import Sprite
      7 from dogma.attributes.format import GetFormatAndValue
      8 from eve.client.script.parklife import states as state
      9 import evetypes
     10 import localization
     11 import uthread
     12 import copy
     13 import blue
     14 import carbonui.const as uiconst
     15 from carbonui.primitives.fill import Fill
     16 from carbonui.util.color import Color
     17 from dogma.const import attributeNonDiminishingSkillInjectorUses
     18 from eve.client.script.ui.control import eveLabel
     19 from eve.client.script.ui.control.eveIcon import Icon
     20 from eve.client.script.ui.control.eveLabel import Label, EveLabelSmall
     21 from carbonui.util.various_unsorted import IsUnder
     22 from eve.client.script.ui.crimewatch.crimewatchConst import Colors
     23 from eve.client.script.ui.shared.stateFlag import FlagIconWithState
     24 from utillib import KeyVal
     25 from carbonui.control.scrollContainer import ScrollContainer
     26 from localization.formatters.timeIntervalFormatters import FormatTimeInterval
     27 from carbonui.uicore import uicore
     28 from eveservices.menu import GetMenuService
     29 import jumpFatigue.const as jumpFatigueConst
     30 from stargate.client.gateLockController import GateLockController
     31 from stargate.client import get_gate_lock_messenger
     32 import eve.common.lib.appConst as appConst
     33 HINT_FRAME_COLOR = (1.0, 1.0, 1.0, 0.25)
     34 HINT_BACKGROUND_COLOR = (0, 0, 0, 0.85)
     35 MAX_ENGAGED_VISIBLE = 10
     36 
     37 def FmtTime(timeLeft):
     38     if timeLeft > 0:
     39         minutes, seconds = divmod(timeLeft / const.SEC, 60)
     40         hours, minutes = divmod(minutes, 60)
     41     else:
     42         hours = 0
     43         minutes = 0
     44         seconds = 0
     45     if hours > 0:
     46         return '%02d:%02d:%02d' % (hours, max(0, minutes), max(0, seconds))
     47     else:
     48         return '%02d:%02d' % (max(0, minutes), max(0, seconds))
     49 
     50 
     51 class TimerHint(Container):
     52     default_align = uiconst.TOPLEFT
     53     default_state = uiconst.UI_NORMAL
     54     default_bgColor = HINT_BACKGROUND_COLOR
     55     default_width = 300
     56     default_height = 48
     57     TIME_WIDTH = 58
     58     TEXT_WIDTH = 242
     59 
     60     def ApplyAttributes(self, attributes):
     61         Container.ApplyAttributes(self, attributes)
     62         self.parentTimer = attributes.get('parentTimer')
     63         self.timerData = attributes.get('timerData')
     64         self.GetTime = self.timerData.timerFunc
     65         Frame(pgParent=self, state=uiconst.UI_DISABLED, color=HINT_FRAME_COLOR)
     66         leftCont = Container(parent=self, align=uiconst.TOLEFT, width=self.TIME_WIDTH)
     67         rightCont = Container(parent=self, align=uiconst.TOALL)
     68         self.time = eveLabel.Label(parent=leftCont, name='counter', text=str(int(self.timerData.maxTimeout / const.SEC)), fontsize=self.GetTimerFontSize(), bold=False, align=uiconst.CENTERLEFT, color=self.timerData.color, left=2 * const.defaultPadding)
     69         self.text = eveLabel.EveLabelSmall(left=const.defaultPadding, parent=rightCont, name='timer description', text=self.GetTooltipText(), align=uiconst.CENTERLEFT, width=self.TEXT_WIDTH - 2 * const.defaultPadding)
     70         self.height = self.text.actualTextHeight + 2 * const.defaultPadding
     71         self.activeBlink = None
     72         self.doUpdates = True
     73         uthread.new(self.UpdateTimer)
     74         self.opacity = 0.0
     75         uicore.animations.FadeIn(self, duration=0.5)
     76 
     77     def GetTimerFontSize(self):
     78         if session.languageID == 'ZH':
     79             return 16
     80         else:
     81             return 20
     82 
     83     def _OnClose(self):
     84         self.doUpdates = False
     85         self.parentTimer.timerHint = None
     86 
     87     def UpdateTimer(self):
     88         wallclockStartTime = blue.os.GetWallclockTime()
     89         while self.doUpdates:
     90             timeNow = self.GetTime()
     91             wallclockTimeNow = blue.os.GetWallclockTime()
     92             if self.parentTimer.expiryTime is not None:
     93                 timeLeft = max(0, self.parentTimer.expiryTime - timeNow)
     94                 if timeLeft == 0:
     95                     self.doUpdates = False
     96                 if self.activeBlink is not None:
     97                     self.activeBlink.Stop()
     98                     self.time.opacity = 1.0
     99                     self.activeBlink = None
    100             else:
    101                 timeLeft = self.timerData.maxTimeout
    102                 if self.activeBlink is None:
    103                     self.activeBlink = uicore.animations.BlinkOut(self.time, duration=1.0, loops=uiconst.ANIM_REPEAT)
    104             if wallclockStartTime + const.SEC < wallclockTimeNow:
    105                 if not (uicore.uilib.mouseOver is self or IsUnder(uicore.uilib.mouseOver, self.parentTimer)):
    106                     self.doUpdates = False
    107             try:
    108                 self.OnUpdate(timeLeft)
    109             except Exception:
    110                 pass
    111 
    112             if self.doUpdates:
    113                 blue.pyos.synchro.SleepWallclock(200)
    114 
    115         uicore.animations.FadeOut(self, sleep=True)
    116         self.Close()
    117 
    118     def OnUpdate(self, timeLeft):
    119         self.time.text = FmtTime(timeLeft)
    120 
    121     def GetTooltipArguments(self):
    122         return {}
    123 
    124     def GetTooltipText(self):
    125         return localization.GetByLabel(self.timerData.tooltip, **self.GetTooltipArguments())
    126 
    127 
    128 class EngagementEntry(Container):
    129     default_align = uiconst.TOTOP
    130     default_height = 32
    131     default_padBottom = 1
    132     default_state = uiconst.UI_NORMAL
    133     isDragObject = True
    134     __notifyevents__ = ['OnCrimewatchEngagementUpdated']
    135 
    136     def ApplyAttributes(self, attributes):
    137         Container.ApplyAttributes(self, attributes)
    138         self.charID = attributes.get('charID')
    139         self.timeout = attributes.get('timeout')
    140         self.isDragObject = True
    141         self.itemID = self.charID
    142         self.info = cfg.eveowners.Get(self.charID)
    143         self.activeBlink = None
    144         self.highlight = Fill(bgParent=self, color=(1, 1, 1, 0.1), state=uiconst.UI_HIDDEN)
    145         leftCont = Container(parent=self, align=uiconst.TOLEFT, width=54)
    146         self.time = eveLabel.Label(parent=leftCont, name='counter', text='', fontsize=16, bold=False, align=uiconst.CENTERLEFT, color=Colors.Engagement.GetRGBA(), left=2 * const.defaultPadding)
    147         self.portrait = Sprite(parent=self, pos=(50, 0, 32, 32), state=uiconst.UI_DISABLED)
    148         eveLabel.EveLabelSmall(parent=self, name='name', text=self.info.ownerName, align=uiconst.TOPLEFT, top=1, left=96)
    149         self.corpText = eveLabel.EveLabelSmall(parent=self, name='corporation', text='', align=uiconst.TOPLEFT, top=17, left=96)
    150         self.stateFlag = FlagIconWithState(parent=self, align=uiconst.TOPRIGHT, left=13, top=4)
    151         self.LoadData()
    152         sm.RegisterNotify(self)
    153 
    154     def LoadData(self):
    155         self.SetTimer()
    156         sm.GetService('photo').GetPortrait(self.charID, 32, self.portrait)
    157         uthread.new(self.LazyLoadData)
    158 
    159     def OnMouseEnter(self, *args):
    160         self.highlight.display = True
    161 
    162     def OnMouseExit(self, *args):
    163         self.highlight.display = False
    164 
    165     def SetTimer(self):
    166         if self.timeout == const.crimewatchEngagementTimeoutOngoing:
    167             self.time.text = FmtTime(const.crimewatchEngagementDuration)
    168             if self.activeBlink is None:
    169                 self.activeBlink = uicore.animations.BlinkOut(self.time, duration=1.0, loops=uiconst.ANIM_REPEAT)
    170         else:
    171             self.time.text = FmtTime(self.timeout - blue.os.GetWallclockTime())
    172             if self.activeBlink is not None:
    173                 self.activeBlink.Stop()
    174                 self.activeBlink = None
    175                 self.time.opacity = 1.0
    176 
    177     def LazyLoadData(self):
    178         slimItem = sm.GetService('crimewatchSvc').GetSlimItemDataForCharID(self.charID)
    179         if slimItem is not None:
    180             self.corpText.text = cfg.eveowners.Get(slimItem.corpID).ownerName
    181             stateSvc = sm.GetService('stateSvc')
    182             flagCode = stateSvc.CheckFilteredFlagState(slimItem, (state.flagLimitedEngagement,))
    183             flagInfo = stateSvc.GetStatePropsColorAndBlink(flagCode)
    184             self.stateFlag.ModifyIcon(flagInfo=flagInfo)
    185             self.slimItem = copy.copy(slimItem)
    186 
    187     def OnClick(self):
    188         sm.GetService('info').ShowInfo(typeID=self.info.typeID, itemID=self.charID)
    189 
    190     def GetDragData(self, *args):
    191         if self and not self.destroyed:
    192             fakeNode = KeyVal()
    193             fakeNode.charID = self.charID
    194             fakeNode.typeID = self.info.typeID
    195             fakeNode.info = self.info
    196             fakeNode.itemID = self.itemID
    197             fakeNode.__guid__ = 'listentry.User'
    198             return [fakeNode]
    199         else:
    200             return []
    201 
    202     def GetMenu(self):
    203         if self.slimItem:
    204             if self.slimItem.itemID:
    205                 return GetMenuService().CelestialMenu(self.slimItem.itemID)
    206             else:
    207                 return GetMenuService().GetMenuFromItemIDTypeID(self.itemID, self.info.typeID)
    208 
    209     def OnCrimewatchEngagementUpdated(self, otherCharId, timeout):
    210         if otherCharId == self.charID:
    211             if timeout is None:
    212                 uicore.animations.FadeOut(self, duration=0.5, sleep=True)
    213                 self.Close()
    214                 sm.ScatterEvent('OnEngagementTimerHintResize')
    215             else:
    216                 self.timeout = timeout
    217 
    218 
    219 class BaseAdvancedTimerHint(ContainerAutoSize):
    220     default_name = 'BaseAdvancedTimerHint'
    221     default_align = uiconst.TOPLEFT
    222     default_state = uiconst.UI_NORMAL
    223     default_bgColor = HINT_BACKGROUND_COLOR
    224     default_width = 240
    225 
    226     def ApplyAttributes(self, attributes):
    227         ContainerAutoSize.ApplyAttributes(self, attributes)
    228         self.parentTimer = attributes.get('parentTimer')
    229         self.timerData = attributes.get('timerData')
    230         self.GetTime = self.timerData.timerFunc
    231         self.doUpdates = True
    232         Frame(bgParent=self, state=uiconst.UI_DISABLED, color=(1.0, 1.0, 1.0, 0.25))
    233         self.mainText = eveLabel.EveLabelMedium(parent=self, align=uiconst.TOTOP, text='', padding=(8, 8, 8, 8), state=uiconst.UI_DISABLED)
    234         self.entryContainer = ScrollContainer(parent=self, align=uiconst.TOTOP)
    235 
    236     def UpdateTimer(self):
    237         startTime = self.GetTime()
    238         count = 0
    239         while self.doUpdates:
    240             timeNow = self.GetTime()
    241             self._UpdateTimers()
    242             if startTime + const.SEC < timeNow:
    243                 if not (uicore.uilib.mouseOver is self or IsUnder(uicore.uilib.mouseOver, self) or IsUnder(uicore.uilib.mouseOver, self.parentTimer)):
    244                     if count > 2:
    245                         self.doUpdates = False
    246                     else:
    247                         count += 1
    248                 else:
    249                     count = 0
    250             if self.doUpdates:
    251                 blue.pyos.synchro.SleepWallclock(200)
    252 
    253         uicore.animations.FadeOut(self, sleep=True)
    254         self.Close()
    255 
    256     def _UpdateTimers(self):
    257         for child in self.entryContainer.mainCont.children[:]:
    258             child.SetTimer()
    259 
    260         self.UpdateHeightAndWidth()
    261 
    262     def _OnClose(self):
    263         self.doUpdates = False
    264         self.parentTimer.timerHint = None
    265 
    266 
    267 class EngagementTimerHint(BaseAdvancedTimerHint):
    268     __notifyevents__ = ['OnEngagementTimerHintResize', 'OnCrimewatchEngagementUpdated']
    269     default_name = 'EngagementTimerHint'
    270 
    271     def ApplyAttributes(self, attributes):
    272         BaseAdvancedTimerHint.ApplyAttributes(self, attributes)
    273         self.LoadData()
    274         uthread.new(self.UpdateTimer)
    275         sm.RegisterNotify(self)
    276 
    277     def OnEngagementTimerHintResize(self):
    278         self.UpdateScrollHeight()
    279 
    280     def SortKey(self, entry):
    281         if entry[0] == const.crimewatchEngagementTimeoutOngoing:
    282             return blue.os.GetWallclockTime()
    283 
    284     def LoadData(self):
    285         engagements = sm.GetService('crimewatchSvc').GetMyEngagements()
    286         cfg.eveowners.Prime(engagements.keys())
    287         engagementList = [ (timeout, charID) for charID, timeout in engagements.iteritems() ]
    288         engagementList.sort(key=self.SortKey)
    289         for timeout, charID in engagementList:
    290             self.AddEntry(charID, timeout)
    291 
    292         self.mainText.text = localization.GetByLabel('UI/Crimewatch/Timers/EngagementTooltipHintHeader', count=len(engagementList))
    293         self.UpdateScrollHeight()
    294 
    295     def AddEntry(self, charID, timeout):
    296         EngagementEntry(parent=self.entryContainer, charID=charID, timeout=timeout)
    297 
    298     def UpdateScrollHeight(self):
    299         self.entryContainer.height = sum((x.height + x.padBottom for x in self.entryContainer.mainCont.children[:MAX_ENGAGED_VISIBLE]))
    300 
    301     def OnCrimewatchEngagementUpdated(self, otherCharId, timeout):
    302         for child in self.entryContainer.mainCont.children[:]:
    303             if otherCharId == child.charID:
    304                 break
    305         else:
    306             self.AddEntry(otherCharId, timeout)
    307             self.UpdateScrollHeight()
    308 
    309     def UpdateHeightAndWidth(self):
    310         pass
    311 
    312 
    313 class BoosterTimerHint(BaseAdvancedTimerHint):
    314     default_name = 'BoosterTimerHint'
    315 
    316     def ApplyAttributes(self, attributes):
    317         BaseAdvancedTimerHint.ApplyAttributes(self, attributes)
    318         self.mainText.text = localization.GetByLabel('UI/Crimewatch/Timers/ActiveBoosters')
    319         self.entryContainer = ScrollContainer(parent=self, align=uiconst.TOTOP)
    320         self.LoadData()
    321         uthread.new(self.UpdateTimer)
    322 
    323     def LoadData(self):
    324         boosters = sm.GetService('crimewatchSvc').GetMyBoosters()
    325         sortedBoosters = [ (b.expiryTime, b) for b in boosters if b.boosterDuration ]
    326         sortedBoosters.sort(reverse=True)
    327         for expiryTime, booster in sortedBoosters:
    328             effects = sm.GetService('crimewatchSvc').GetBoosterEffects(booster)
    329             self.AddEntry(booster, expiryTime, effects)
    330 
    331         self.UpdateHeightAndWidth()
    332 
    333     def AddEntry(self, booster, expiryTime, effects):
    334         entry = BoosterEntry(parent=self.entryContainer, booster=booster, expiryTime=expiryTime, effects=effects)
    335         return entry
    336 
    337     def UpdateHeightAndWidth(self):
    338         if not self.entryContainer.mainCont.children:
    339             return
    340         self.entryContainer.height = sum((x.height + x.padBottom for x in self.entryContainer.mainCont.children))
    341         timerWidth = max((x.time.width for x in self.entryContainer.mainCont.children)) + 2 * const.defaultPadding
    342         for x in self.entryContainer.mainCont.children:
    343             x.time.parent.width = timerWidth
    344 
    345         self.width = timerWidth + max((x.maxtextwidth + 10 for x in self.entryContainer.mainCont.children))
    346 
    347 
    348 class BoosterEntry(Container):
    349     default_align = uiconst.TOTOP
    350     default_height = 50
    351     default_padBottom = 1
    352     default_state = uiconst.UI_NORMAL
    353     TIME_WIDTH = 60
    354 
    355     def ApplyAttributes(self, attributes):
    356         Container.ApplyAttributes(self, attributes)
    357         self.booster = attributes.get('booster')
    358         self.expiryTime = attributes.get('expiryTime')
    359         self.effects = attributes.get('effects')
    360         self.positiveEffects = self.effects.get('positive', [])
    361         self.negativeEffects = self.effects.get('negative', [])
    362         self.typeID = self.booster.typeID
    363         self.activeBlink = None
    364         self.highlight = Fill(bgParent=self, color=(1, 1, 1, 0.1), state=uiconst.UI_HIDDEN)
    365         leftCont = Container(parent=self, align=uiconst.TOLEFT, width=self.TIME_WIDTH)
    366         rightCont = Container(parent=self, align=uiconst.TOALL)
    367         self.time = Label(parent=leftCont, name='counter', text='', fontsize=16, bold=False, align=uiconst.TOPLEFT, color=(1, 1, 1, 0.75), left=2 * const.defaultPadding)
    368         self.boosterSprite = Icon(parent=rightCont, name='boosterIcon', icon=evetypes.GetIconID(self.typeID), pos=(0, 0, 24, 24), ignoreSize=True, state=uiconst.UI_DISABLED)
    369         left = self.boosterSprite.width
    370         boosterName = EveLabelSmall(parent=rightCont, name='name', text=evetypes.GetName(self.typeID), align=uiconst.TOPLEFT, top=1, left=left)
    371         self.maxtextwidth = boosterName.textwidth + boosterName.left
    372         padTop = boosterName.textheight + 4
    373         allModified = self.GetBoosterEffectsInfo(self.positiveEffects) + self.GetBoosterEffectsInfo(self.negativeEffects, True)
    374         self._AddNonDiminishingInjections(allModified)
    375         addedText = set()
    376         for lineText in allModified:
    377             if lineText in addedText:
    378                 continue
    379             effectLabel = EveLabelSmall(parent=rightCont, name='effect', text=lineText, align=uiconst.TOPLEFT, padTop=padTop, left=30)
    380             addedText.add(lineText)
    381             padTop += effectLabel.textheight + 2
    382             self.maxtextwidth = max(self.maxtextwidth, effectLabel.textwidth + effectLabel.left)
    383 
    384         self.height = max(padTop + 4, self.boosterSprite.height + 2)
    385         self.LoadData()
    386 
    387     def _AddNonDiminishingInjections(self, allModified):
    388         dogmaLM = sm.GetService('clientDogmaIM').GetDogmaLocation()
    389         if dogmaLM.dogmaStaticMgr.GetTypeAttribute(self.typeID, attributeNonDiminishingSkillInjectorUses, defaultValue=0):
    390             nonDiminishingInjectionsRemaining = sm.GetService('nonDiminishingInjection').GetRemaining()
    391             effectText = localization.GetByLabel('UI/Skills/NonDiminishingInjectionsRemainingForBooster', timesRemaining=int(nonDiminishingInjectionsRemaining))
    392             allModified.append(effectText)
    393 
    394     def GetBoosterEffectsInfo(self, effects, isNegative = False):
    395         dogmaLM = sm.GetService('clientDogmaIM').GetDogmaLocation()
    396         neurotoxinControlTypeID = 25538
    397         effectsTextList = []
    398         for eff in effects:
    399             if eff.modifierInfo:
    400                 for mi in eff.modifierInfo:
    401                     modifyingAttributeID = mi.modifyingAttributeID
    402                     effectAmount = dogmaLM.dogmaStaticMgr.GetTypeAttribute(self.booster.typeID, modifyingAttributeID)
    403                     if isNegative and effectAmount:
    404                         neurotoxinControlSkill = sm.GetService('skills').GetSkill(neurotoxinControlTypeID)
    405                         effectModifier = dogmaLM.dogmaStaticMgr.GetSkillModifiedAttributePercentageValue(modifyingAttributeID, appConst.attributeBoosterAttributeModifier, neurotoxinControlTypeID, neurotoxinControlSkill)
    406                         effectAmount *= effectModifier
    407                         effectAmount *= self._GetToxinControlImplantModifier()
    408                     attributes = dogma_data.get_attribute(modifyingAttributeID)
    409                     effectText = localization.GetByLabel('UI/Crimewatch/Timers/BoosterPenaltyWithValue', value=GetFormatAndValue(attributes, abs(effectAmount)), penaltyName=dogma_data.get_attribute_display_name(modifyingAttributeID))
    410                     effectsTextList.append(effectText)
    411 
    412             else:
    413                 effectText = dogma_data.get_effect_display_name(eff.effectID)
    414                 effectsTextList.append(effectText)
    415 
    416         return effectsTextList
    417 
    418     def _GetToxinControlImplantModifier(self):
    419         implants = sm.GetService('godma').GetItem(session.charid).implants
    420         ret = 1.0
    421         if not implants:
    422             return ret
    423         for implant in implants:
    424             if implant.typeID in [appConst.typeNeurotoxinControl903, appConst.typeNeurotoxinControl905]:
    425                 dogmaLM = sm.GetService('clientDogmaIM').GetDogmaLocation()
    426                 mod = dogmaLM.dogmaStaticMgr.GetTypeAttribute2(implant.typeID, appConst.attributeBoosterAttributeModifier)
    427                 if mod:
    428                     return (100 + mod) / 100.0
    429 
    430         return ret
    431 
    432     def LoadData(self):
    433         self.SetTimer()
    434 
    435     def OnMouseEnter(self, *args):
    436         self.highlight.display = True
    437 
    438     def OnMouseExit(self, *args):
    439         self.highlight.display = False
    440 
    441     def SetTimer(self):
    442         self.time.text = FmtTime(self.expiryTime - blue.os.GetWallclockTime())
    443         if self.activeBlink is not None:
    444             self.activeBlink.Stop()
    445             self.activeBlink = None
    446             self.time.opacity = 1.0
    447 
    448     def OnClick(self):
    449         sm.GetService('info').ShowInfo(typeID=self.typeID, itemID=self.booster.boosterID)
    450 
    451     def GetMenu(self):
    452         return GetMenuService().GetMenuFromItemIDTypeID(itemID=self.booster.boosterID, typeID=self.typeID)
    453 
    454 
    455 class JumpTimerHint(TimerHint):
    456 
    457     def ApplyAttributes(self, attributes):
    458         TimerHint.ApplyAttributes(self, attributes)
    459         self.time.parent.Close()
    460         self.text.parent.Close()
    461         self.container = ContainerAutoSize(parent=self, align=uiconst.TOTOP, alignMode=uiconst.TOTOP, padding=(3 * const.defaultPadding,
    462          2 * const.defaultPadding,
    463          2 * const.defaultPadding,
    464          2 * const.defaultPadding), callback=self.OnContainerResized)
    465         self.time = eveLabel.Label(parent=self.container, align=uiconst.TOTOP, fontsize=self.GetTimerFontSize(), color=self.timerData.color)
    466         self.text = eveLabel.EveLabelSmall(parent=self.container, align=uiconst.TOTOP, top=const.defaultPadding)
    467         self.next = eveLabel.EveLabelSmall(parent=self.container, align=uiconst.TOTOP, top=2 * const.defaultPadding, color=self.timerData.color)
    468 
    469     def OnContainerResized(self):
    470         self.height = self.container.height + 4 * const.defaultPadding
    471 
    472     def OnUpdate(self, remaining):
    473         color = Color.RGBtoHex(*self.timerData.color)
    474         if remaining:
    475             self.time.text = FormatTimeInterval(remaining, color, color)
    476             self.text.text = self.GetTooltipText()
    477             self.AddExtraHint(remaining)
    478 
    479     def AddExtraHint(self, remaining):
    480         pass
    481 
    482 
    483 class JumpTimerFatigueHint(JumpTimerHint):
    484 
    485     def AddExtraHint(self, remaining):
    486         newMinimumActivationTime, maxSecondsWhereDistanceMatters = GetJumpActivationTimes(remaining)
    487         isAccurate = newMinimumActivationTime >= maxSecondsWhereDistanceMatters
    488         newActivationTime = FmtActivationTime(long(newMinimumActivationTime * const.SEC))
    489         if isAccurate:
    490             text = localization.GetByLabel('UI/Crimewatch/Timers/JumpFatigueNextActivation', time=newActivationTime)
    491         else:
    492             maxTime = FmtActivationTime(long(maxSecondsWhereDistanceMatters * const.SEC))
    493             text = localization.GetByLabel('UI/Crimewatch/Timers/JumpFatigueNextActivationRange', minTime=newActivationTime, maxTime=maxTime)
    494         self.next.text = text
    495 
    496 
    497 class EmanationLockHint(TimerHint):
    498     default_width = 500
    499     default_height = 48
    500     TIME_WIDTH = 85
    501     TEXT_WIDTH = 415
    502 
    503     def ApplyAttributes(self, attributes):
    504         TimerHint.ApplyAttributes(self, attributes)
    505         sm.GetService('uiHighlightingService').clear_ui_highlighting_for_element(pointToID=self.parentTimer.name)
    506 
    507     def GetTooltipArguments(self):
    508         arguments = {}
    509         controller = GateLockController.get_instance(get_gate_lock_messenger(sm.GetService('publicGatewaySvc')))
    510         lockDetails = controller.get_current_system_lock()
    511         if lockDetails is not None:
    512             arguments['gate'] = cfg.evelocations.Get(lockDetails.gate_id).name
    513             arguments['system'] = cfg.evelocations.Get(lockDetails.solar_system_id).name
    514         return arguments
    515 
    516 
    517 def GetJumpActivationTimes(remainingFatigue):
    518     dogmaLocation = sm.GetService('clientDogmaIM').GetDogmaLocation()
    519     shipMaxDistance = dogmaLocation.GetAttributeValue(session.shipid, const.attributeJumpDriveRange)
    520     return GetJumpActivationTimesForDistance(remainingFatigue, shipMaxDistance)
    521 
    522 
    523 def GetJumpActivationTimesForDistance(remainingFatigue, distance):
    524     dogmaLocation = sm.GetService('clientDogmaIM').GetDogmaLocation()
    525     shipMultiplier = dogmaLocation.GetAttributeValue(session.shipid, const.attributeJumpFatigueMultiplier)
    526     multiplier = jumpFatigueConst.ADDITIONAL_DISTANCE
    527     minimumActivationSeconds = multiplier * jumpFatigueConst.ACTIVATION_SECONDS_PER_DISTANCE
    528     multiplier = jumpFatigueConst.ADDITIONAL_DISTANCE + distance * shipMultiplier
    529     maxSecondsWhereDistanceMatters = multiplier * jumpFatigueConst.ACTIVATION_SECONDS_PER_DISTANCE
    530     remainingFatigueSec = remainingFatigue / const.SEC
    531     newActicationTimeRaw = remainingFatigueSec * jumpFatigueConst.FATIGUE_RATIO
    532     newActivationTime = max(minimumActivationSeconds, newActicationTimeRaw)
    533     return (newActivationTime, maxSecondsWhereDistanceMatters)
    534 
    535 
    536 def FmtActivationTime(time):
    537     mins = localization.formatters.FormatNumeric(time / const.MIN, leadingZeroes=2)
    538     secs = localization.formatters.FormatNumeric(time % const.MIN / const.SEC, leadingZeroes=2)
    539     return localization.GetByLabel('/Carbon/UI/Common/DateTimeQuantity/DateTimeShort2Elements', value1=mins, value2=secs)