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

skillQueueSkillEntry.py (17212B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\skillPlan\skillQueuePanel\skillQueueSkillEntry.py
      2 import sys
      3 import blue
      4 import evetypes
      5 import gametime
      6 import localization
      7 import log
      8 import trinity
      9 import uthread
     10 from carbon.common.script.util import timerstuff
     11 from carbon.common.script.util.commonutils import GetAttrs
     12 from carbonui import const as uiconst
     13 from carbonui.control.buttonIcon import ButtonIcon
     14 from carbonui.primitives.container import Container
     15 from carbonui.primitives.containerAutoSize import ContainerAutoSize
     16 from carbonui.primitives.line import Line
     17 from carbonui.primitives.sprite import Sprite
     18 from carbonui.uianimations import animations
     19 from carbonui.uicore import uicore
     20 from clonegrade.const import COLOR_OMEGA_ORANGE
     21 from eve.client.script.ui.control.eveLabel import EveLabelLarge
     22 from eve.client.script.ui.control.eveScroll import Scroll
     23 from eve.client.script.ui.shared.industry.views.errorFrame import ErrorFrame
     24 from eve.client.script.ui.shared.info.panels.panelRequiredFor import RequiredForScrollController
     25 from eve.client.script.ui.skillPlan.skillPlanEditor.skillPlanDropIndicatorCont import IsMultiSkillEntryMove
     26 from omega.client.clone_grade_svc import get_clone_grade_svc
     27 from player_messaging.client.ui_message import prompt_player_fsd_dialog
     28 from skills.client.skillController import SkillController
     29 from eve.client.script.ui.shared.neocom.skillConst import COLOR_SKILL_1, COLOR_MOVE_INDICATOR
     30 from eve.client.script.ui.shared.neocom.skillConst import COLOR_TRAININGALLOWED, COLOR_TRAININGNOTALLOWED
     31 from eve.client.script.ui.shared.neocom.timelineContainer import TimelineContainer
     32 from eve.client.script.ui.skillPlan.skillQueuePanel.baseSkillEntry import BaseSkillEntry
     33 from eveservices.menu import GetMenuService
     34 from fsdBuiltData.common.iconIDs import GetIconFile
     35 from localization import GetByLabel
     36 from menu import MenuLabel
     37 OPACITY_START = 0.3
     38 
     39 class SkillQueueSkillEntry(BaseSkillEntry):
     40     __guid__ = 'listentry.SkillQueueSkillEntry'
     41     __nonpersistvars__ = ['selection', 'id']
     42     isDragObject = True
     43 
     44     def ApplyAttributes(self, attributes):
     45         self.entryHeight = 0
     46         self.blinking = 0
     47         super(SkillQueueSkillEntry, self).ApplyAttributes(attributes)
     48         self.posIndicatorLine = None
     49         self.acceleratedSprite = None
     50         self.skillQueueSvc = sm.GetService('skillqueue')
     51         self.skills = sm.GetService('skills')
     52         self.timelineCont = None
     53         self.flashCont = None
     54         self.disabledFrame = None
     55         self.removeButton = None
     56 
     57     def CheckConstructRemoveButton(self):
     58         if not self.removeButton:
     59             self.removeButton = ButtonIcon(parent=self, align=uiconst.CENTERRIGHT, texturePath='res:/UI/Texture/Icons/105_32_12.png', pos=(0, 0, 24, 24), iconSize=24, func=self.RemoveFromQueue)
     60 
     61     def CheckConstructAcceleratedSprite(self):
     62         if not self.acceleratedSprite:
     63             self.acceleratedSprite = Sprite(name='accelratedTraining', parent=self, align=uiconst.BOTTOMLEFT, state=uiconst.UI_HIDDEN, pos=(2, 4, 16, 16), texturePath='res:/UI/Texture/Crimewatch/booster.png', idx=0, hint=localization.GetByLabel('UI/SkillQueue/Skills/AcceleratedTraining'))
     64 
     65     def Load(self, node):
     66         BaseSkillEntry.Load(self, node)
     67         self.controller = SkillController(node.skillID)
     68         data = node
     69         self.skillID = data.skillID
     70         self.UpdateSkillNameLevelLabel()
     71         self.inQueue = data.Get('inQueue', 0)
     72         if data.trained:
     73             queue = self.skillQueueSvc.GetQueue()
     74             isTypeActive = len(queue) and data.skill.typeID == queue[0].trainingTypeID
     75             isNextLevel = data.Get('currentLevel', -1) + 1 == data.Get('trainToLevel')
     76             isNotQueuedRecord = data.Get('inQueue', 0) == 0
     77             recordNeedsUpdating = isTypeActive and (isNotQueuedRecord or isNextLevel)
     78             if recordNeedsUpdating:
     79                 uthread.new(self.UpdateTraining, data.skill)
     80             else:
     81                 skill = data.skill
     82                 spsNextLevel = self.skills.SkillpointsNextLevel(skill.typeID)
     83                 if spsNextLevel is not None:
     84                     timeLeft = data.timeLeft
     85                     if timeLeft > 0:
     86                         timeLeftText = self._GetTimeLeftText(long(timeLeft))
     87                     else:
     88                         timeLeftText = ''
     89                     self.timeLeftText.text = timeLeftText
     90         self.HidePosIndicator()
     91         if self.inQueue == 1 and self.inTrainingHilite:
     92             self.inTrainingHilite.Hide()
     93         self.UpdateAcceleratedMarker()
     94         self.ConstructTypeUnlockIcons()
     95         self.UpdateRemoveButton()
     96         if self.timeLeftText:
     97             if self.IsCurrentlyTraining():
     98                 self.StartFlashAnimation()
     99                 self.timeLeftText.opacity = 1.0
    100             else:
    101                 self.timeLeftText.opacity = 0.5
    102         if self.IsDisabledForTraining() or self.sr.node.disabledForTraining:
    103             self.ShowDisabledFrame()
    104         else:
    105             self.HideDisabledFrame()
    106 
    107     def GetTypeID(self):
    108         return self.sr.node.skillID
    109 
    110     def IsCurrentlyTraining(self):
    111         currSkill = sm.GetService('skillqueue').SkillInTraining()
    112         isCurrentSkill = currSkill and currSkill.typeID == self.GetTypeID() and currSkill.trainedSkillLevel == self.GetTrainToLevel() - 1
    113         return isCurrentSkill
    114 
    115     def GetTrainToLevel(self):
    116         return self.sr.node.trainToLevel
    117 
    118     def HideDisabledFrame(self):
    119         if self.disabledFrame:
    120             self.disabledFrame.Hide()
    121 
    122     def ShowDisabledFrame(self):
    123         if not self.disabledFrame:
    124             self.disabledFrame = ErrorFrame(bgParent=self, color=COLOR_OMEGA_ORANGE, opacityLow=0.15, padding=2)
    125         self.disabledFrame.Show()
    126 
    127     def IsDisabledForTraining(self):
    128         maxLevel = get_clone_grade_svc().get_max_skill_level(self.skillID)
    129         return maxLevel < self.GetTrainToLevel()
    130 
    131     def DrawTimeline(self, offset, segments, animate = False):
    132         self._CheckConstructTimeline()
    133         self.timelineCont.FlushLine()
    134         for width, color in segments:
    135             self.timelineCont.AddSegment(width, color)
    136 
    137         self.timelineCont.SetOffset(offset)
    138         if animate:
    139             self.timelineCont.opacity = 0.0
    140             animations.FadeIn(self.timelineCont)
    141         else:
    142             self.timelineCont.StopAnimations()
    143             self.timelineCont.opacity = 1.0
    144 
    145     def HideTimeline(self, animate = False):
    146         if animate:
    147             animations.FadeOut(self.timelineCont, callback=self.timelineCont.FlushLine)
    148         else:
    149             self.timelineCont.FlushLine()
    150 
    151     def _CheckConstructTimeline(self):
    152         if self.timelineCont is None:
    153             self.timelineCont = TimelineContainer(parent=self, idx=0, align=uiconst.TOBOTTOM_NOPUSH, state=uiconst.UI_DISABLED, barHeight=1, height=2, clipChildren=1)
    154 
    155     def RemoveFromQueue(self):
    156         self.sr.node.RemoveFromQueue(self.sr.node)
    157 
    158     def UpdateRemoveButton(self):
    159         data = self.sr.node
    160         skillQueueSvc = sm.GetService('skillqueue')
    161         isRemovable = skillQueueSvc.IsRemoveAllowed(data.invtype, data.trainToLevel)
    162         if isRemovable:
    163             self.CheckConstructRemoveButton()
    164             self.removeButton.Show()
    165         elif self.removeButton:
    166             self.removeButton.Hide()
    167 
    168     def StartFlashAnimation(self):
    169         if not self.flashCont:
    170             self.ConstructFlashCont()
    171         uicore.animations.FadeTo(self.flashSprite, 0.3, 0.5, duration=1.0)
    172         uicore.animations.MorphScalar(self.flashCont, 'left', -120, 0, duration=4.0, curveType=uiconst.ANIM_LINEAR, loops=uiconst.ANIM_REPEAT)
    173         uicore.animations.FadeTo(self.flashCont, OPACITY_START, 1.0, duration=5.0, curveType=uiconst.ANIM_WAVE, loops=uiconst.ANIM_REPEAT)
    174 
    175     def StopFlashAnimation(self):
    176         if self.flashCont:
    177             self.flashCont.StopAnimations()
    178             self.flashCont.opacity = OPACITY_START
    179             self.flashSprite.opacity = 0.0
    180 
    181     def ConstructFlashCont(self):
    182         color = COLOR_SKILL_1
    183         self.flashCont = Container(name='flashCont', parent=self, state=uiconst.UI_DISABLED, idx=0, align=uiconst.TOPLEFT, width=self.width, height=self.height, opcaity=OPACITY_START)
    184         self.flashSprite = Sprite(parent=self.flashCont, align=uiconst.CENTERLEFT, texturePath='res:/UI/Texture/Classes/Industry/CenterBar/arrows.png', pos=(0,
    185          0,
    186          1000,
    187          self.height), color=color, opacity=0.2, tileX=True)
    188 
    189     def OnDblClick(self, *args):
    190         sm.GetService('info').ShowInfo(self.GetTypeID())
    191 
    192     def ConstructTypeUnlockIcons(self):
    193         from eve.client.script.ui.shared.info.panels.panelRequiredFor import RequiredForScrollController
    194         controller = RequiredForScrollController()
    195         typeIDsByMarketGroupID = controller.GetUnlockTypeIDsByMarketGroup(self.GetTypeID(), self.GetTrainToLevel())
    196         if typeIDsByMarketGroupID:
    197             iconSize = 24
    198             cont = Container(parent=self.textCont)
    199             iconCont = ContainerAutoSize(parent=cont, align=uiconst.CENTERLEFT, height=iconSize, left=8)
    200             for marketGroupID, typeIDs in typeIDsByMarketGroupID.iteritems():
    201                 TypesUnlockedIcon(parent=iconCont, align=uiconst.TOLEFT, width=iconSize, marketGroupID=marketGroupID, typeIDs=typeIDs)
    202 
    203             iconCont.SetSizeAutomatically()
    204 
    205     def UpdateSkillNameLevelLabel(self):
    206         self.CheckConstructNameLevelLabel()
    207         text = self.controller.GetRequiredSkillNameAndLevelComparedToTrainedLevel(self.GetTrainToLevel())
    208         self.nameLevelLabel.text = text
    209 
    210     def UpdateAcceleratedMarker(self):
    211         if not self.inQueue:
    212             return
    213         data = self.sr.node
    214         if data.isAccelerated:
    215             self.CheckConstructAcceleratedSprite()
    216             self.acceleratedSprite.display = True
    217         elif self.acceleratedSprite:
    218             self.acceleratedSprite.display = False
    219 
    220     def FillBoxes(self, currentLevel, trainToLevel):
    221         inTraining = self.skillQueueSvc.SkillInTraining()
    222         for i in xrange(currentLevel, 5):
    223             if inTraining and inTraining.typeID == self.skillID:
    224                 if not self.inQueue:
    225                     if i == currentLevel:
    226                         self.blinking = 1
    227                         continue
    228                 elif currentLevel + 1 == trainToLevel:
    229                     self.blinking = 1
    230                     continue
    231             box = self.sr.Get('box_%s' % i, None)
    232             if box and i < trainToLevel:
    233                 box.SetRGBA(*self.blueColor)
    234                 box.state = uiconst.UI_DISABLED
    235 
    236     def GetMenu(self):
    237         m = GetMenuService().GetMenuForSkill(self.rec.typeID)
    238         selected = self.sr.node.scroll.GetSelectedNodes(self.sr.node)
    239         if self.inQueue == 1:
    240             if GetAttrs(self, 'parent', 'RemoveSkillFromQueue'):
    241                 m.append(None)
    242                 m.append((MenuLabel('UI/Commands/Remove'), self.parent.RemoveSkillFromQueue, ()))
    243         return m
    244 
    245     def GetHint(self):
    246         return evetypes.GetDescription(self.skillID)
    247 
    248     def OnClick(self, *args):
    249         if self.sr.node:
    250             if self.sr.node.Get('selectable', 1):
    251                 self.sr.node.scroll.SelectNode(self.sr.node)
    252             prompt_player_fsd_dialog('ListEntryClick')
    253             if self.sr.node.Get('OnClick', None):
    254                 self.sr.node.OnClick(self)
    255 
    256     def UpdateTraining(self, skill):
    257         if not self or self.destroyed:
    258             return
    259         currentPoints = self.GetCurrentPoints(skill)
    260         fill = self.sr.Get('box_%s' % int(skill.trainedSkillLevel))
    261         if not fill:
    262             return
    263         fill.state = uiconst.UI_DISABLED
    264         if self.blinking == 1:
    265             fill.SetRGBA(*COLOR_SKILL_1)
    266             sm.StartService('ui').BlinkSpriteA(fill, 1.0, time=1000.0, maxCount=0, passColor=0, minA=0.5)
    267         if self.inQueue == 0:
    268             self.OnSkillpointChange(currentPoints)
    269 
    270     def GetCurrentPoints(self, skill):
    271         if not self or self.destroyed:
    272             return
    273         ETA = sm.GetService('skillqueue').GetEndOfTraining(skill.typeID)
    274         level = skill.trainedSkillLevel
    275         if not self or self.destroyed or GetAttrs(self, 'sr', 'node', 'skill', 'typeID') != skill.typeID:
    276             return
    277         if ETA:
    278             time = ETA - gametime.GetWallclockTime()
    279             secs = time / 10000000
    280         else:
    281             time = 0
    282             secs = 0
    283         currentPoints = sm.GetService('skillqueue').GetEstimatedSkillPointsTrained(skill.typeID)
    284         if GetAttrs(self, 'sr', 'node', 'trainToLevel') != level:
    285             if GetAttrs(self, 'sr', 'node', 'timeLeft'):
    286                 time = self.sr.node.timeLeft
    287             else:
    288                 time = None
    289         self.SetTimeLeft(time)
    290         if ETA:
    291             self.endOfTraining = ETA
    292         else:
    293             self.endOfTraining = None
    294         self.lasttime = gametime.GetWallclockTime()
    295         self.lastsecs = secs
    296         self.lastpoints = currentPoints
    297         self.timer = timerstuff.AutoTimer(1000, self.UpdateProgress)
    298         return currentPoints
    299 
    300     def UpdateProgress(self):
    301         try:
    302             if self.endOfTraining is None:
    303                 self.timer = None
    304                 return
    305             skill = self.rec
    306             timeLeft = self.endOfTraining - blue.os.GetWallclockTime()
    307             if self.inQueue == 0:
    308                 currentPoints = self.skillQueueSvc.GetEstimatedSkillPointsTrained(skill.typeID)
    309                 self.OnSkillpointChange(currentPoints)
    310             else:
    311                 self.SetTimeLeft(timeLeft)
    312         except:
    313             self.timer = None
    314             log.LogException()
    315             sys.exc_clear()
    316 
    317     def GetDragData(self, *args):
    318         return self.sr.node.scroll.GetSelectedNodes(self.sr.node)
    319 
    320     def OnDropData(self, dragObj, nodes, *args):
    321         self.HidePosIndicator()
    322         if GetAttrs(self, 'parent', 'OnDropData'):
    323             if self.inQueue:
    324                 self.parent.OnDropData(dragObj, nodes, idx=self.sr.node.idx)
    325             else:
    326                 node = nodes[0]
    327                 if GetAttrs(node, 'panel', 'inQueue'):
    328                     self.parent.OnDropData(dragObj, nodes)
    329 
    330     def OnDragEnter(self, dragObj, nodes, *args):
    331         if not self.inQueue or nodes is None:
    332             return
    333         self.ShowPosIndicator(nodes)
    334 
    335     def CheckConstructPosIndicatorLine(self):
    336         if not self.posIndicatorLine:
    337             self.posIndicatorLine = Line(parent=self, align=uiconst.TOPLEFT_PROP, pos=(0, 0, 0.99, 2), state=uiconst.UI_DISABLED, opacity=0.0, idx=0)
    338 
    339     def ShowPosIndicator(self, nodes):
    340         self.CheckConstructPosIndicatorLine()
    341         if IsMultiSkillEntryMove(nodes):
    342             color = COLOR_MOVE_INDICATOR
    343         else:
    344             firstNode = nodes[0]
    345             allowedMove = self.skillQueueSvc.IsMoveAllowed(firstNode, self.sr.node.idx)
    346             if allowedMove:
    347                 color = COLOR_TRAININGALLOWED
    348             elif self.skillQueueSvc.IsSkillEntry(firstNode):
    349                 color = COLOR_TRAININGNOTALLOWED
    350             else:
    351                 color = (0, 0, 0, 0)
    352         self.posIndicatorLine.SetRGBA(*color)
    353 
    354     def OnDragExit(self, *args):
    355         if not self.inQueue:
    356             return
    357         self.HidePosIndicator()
    358 
    359     def HidePosIndicator(self):
    360         if self.posIndicatorLine:
    361             self.posIndicatorLine.opacity = 0.0
    362 
    363     def GetDynamicHeight(node, width):
    364         name = localization.GetByLabel('UI/SkillQueue/Skills/SkillNameAndRankValue', skill=node.skill.typeID, rank=0)
    365         _, nameHeight = EveLabelLarge.MeasureTextSize(name, maxLines=1)
    366         return max(32, nameHeight + 8)
    367 
    368 
    369 class TypesUnlockedIcon(Sprite):
    370     default_spriteEffect = trinity.TR2_SFX_SOFTLIGHT
    371     default_saturation = 0.0
    372     default_effectOpacity = 0.0
    373     default_opacity = 0.85
    374 
    375     def ApplyAttributes(self, attributes):
    376         Sprite.ApplyAttributes(self, attributes)
    377         self.typeIDs = attributes.typeIDs
    378         marketGroupID = attributes.marketGroupID
    379         self.marketGroup = cfg.GetMarketGroup(marketGroupID)
    380         self.texturePath = GetIconFile(self.marketGroup.iconID, 'res:/ui/Texture/WindowIcons/smallfolder.png')
    381 
    382     def LoadTooltipPanel(self, tooltipPanel, *args):
    383         tooltipPanel.LoadGeneric1ColumnTemplate()
    384         tooltipPanel.state = uiconst.UI_NORMAL
    385         text = GetByLabel('UI/CharacterSheet/CharacterSheetWindow/SkillTabs/TypesUnlockedCaption', groupName=self.marketGroup.marketGroupName)
    386         tooltipPanel.AddLabelLarge(text=text, cellPadding=(0, 4, 0, 6))
    387         controller = RequiredForScrollController()
    388         scrollList = controller.GetTypeScrollList(self.typeIDs)
    389         maxWidth = max((EveLabelLarge.MeasureTextSize(x.label)[0] for x in scrollList))
    390         maxWidth = max(maxWidth + 60, 250)
    391         maxHeight = 205
    392         height = min(maxHeight, len(scrollList) * 30 + 3)
    393         scroll = Scroll(align=uiconst.TOPLEFT, pos=(0,
    394          0,
    395          maxWidth,
    396          height))
    397         scroll.HideBackground()
    398         scroll.Load(fixedEntryHeight=27, contentList=scrollList)
    399         tooltipPanel.AddCell(scroll)