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

skillRequirements.py (13135B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\fittingScreen\skillRequirements.py
      2 from collections import defaultdict
      3 from carbon.common.script.sys.serviceConst import ROLE_GML
      4 from carbonui.text.styles import TextHeader
      5 from carbonui.util.sortUtil import SortListOfTuples
      6 from dogma.items.characterDogmaItem import CharacterDogmaItem
      7 from dogma.items.shipDogmaItem import ShipDogmaItem
      8 from carbonui.control.button import Button
      9 from eve.client.script.ui.control.eveLabel import EveLabelMedium, EveHeaderMedium
     10 import evetypes
     11 import carbonui.const as uiconst
     12 from eve.client.script.ui.shared.fittingScreen.skillRequirementsUtil import GetAllSkillsAndLevels, _GetSkillTypeIDAndLevelRequired
     13 from eve.client.script.ui.shared.industry.submitButton import PrimaryButton
     14 from eve.client.script.ui.shared.neocom.skillConst import COLOR_SKILL_1, COLOR_SKILL_2
     15 from eve.client.script.ui.shared.tooltip.itemObject import ItemObject
     16 from eve.client.script.ui.shared.tooltip.skill_requirement import RequiredSkillRow, AddSkillActionForList, AddTrainingTime
     17 from inventorycommon.const import categoryBlueprint
     18 from localization import GetByLabel
     19 import blue
     20 from omega.client.clone_grade_svc import get_clone_grade_svc
     21 
     22 def GetSkillTooltip(tooltipPanel, fittingController, fitName = None):
     23     tooltipPanel.state = uiconst.UI_NORMAL
     24     tooltipPanel.columns = 2
     25     tooltipPanel.margin = (12, 8, 12, 12)
     26     tooltipPanel.state = uiconst.UI_NORMAL
     27     dogmaLocation = fittingController.GetDogmaLocation()
     28     shipAndFitTypeIDs = _GetAllTypesForShipAndFit(dogmaLocation)
     29     shipAndFitTypeIDsMissingSomeReq = GetMissingSkillsForTypeIDs(shipAndFitTypeIDs)
     30     shipAndFitHighestLevelByTypeID, _ = GetMissingSkills_HighestLevelByTypeID(shipAndFitTypeIDsMissingSomeReq)
     31     cargoholdTypeIDs = _GetAllTypesForCargoHold(dogmaLocation)
     32     cargoholdTypeIDsMissingSomeReq = GetMissingSkillsForTypeIDs(cargoholdTypeIDs)
     33     cargoholdTypeIDsMissingSomeReq -= shipAndFitTypeIDsMissingSomeReq
     34     cargoholdHighestLevelByTypeID, _ = GetMissingSkills_HighestLevelByTypeID(cargoholdTypeIDsMissingSomeReq)
     35     for typeID, lvl in cargoholdHighestLevelByTypeID.items():
     36         lvlForFit = shipAndFitHighestLevelByTypeID.get(typeID, 0)
     37         if lvlForFit >= lvl:
     38             cargoholdHighestLevelByTypeID.pop(typeID)
     39 
     40     shipText = None
     41     holdText = GetByLabel('UI/Fitting/FittingWindow/Warnings/CargoHold')
     42     if shipAndFitTypeIDsMissingSomeReq and cargoholdTypeIDsMissingSomeReq:
     43         shipText = GetByLabel('UI/Fitting/FittingWindow/Warnings/ShipAndFit')
     44     if shipAndFitTypeIDs:
     45         AddMissingSkillRequirements(tooltipPanel, shipAndFitHighestLevelByTypeID, True, shipText)
     46     if cargoholdTypeIDsMissingSomeReq:
     47         AddMissingSkillRequirements(tooltipPanel, cargoholdHighestLevelByTypeID, False, holdText)
     48     allSkillLevelsByID = []
     49     for key in set(shipAndFitHighestLevelByTypeID.keys()) | set(cargoholdHighestLevelByTypeID.keys()):
     50         valA = shipAndFitHighestLevelByTypeID.get(key, 0)
     51         valB = cargoholdHighestLevelByTypeID.get(key, 0)
     52         allSkillLevelsByID.append((key, max(valA, valB)))
     53 
     54     skillSvc = sm.GetService('skills')
     55     allSkillLevelsByID = skillSvc.GetSkillsMissingToUseAllSkillsFromListRecursiveAsList(allSkillLevelsByID)
     56     allSkillLevelsByIDDict = dict(allSkillLevelsByID)
     57     missingSkills = skillSvc.GetMissingSkillBooksFromList(allSkillLevelsByID)
     58     totalTime = long(skillSvc.GetSkillTrainingTimeLeftForTypesAndLevels(allSkillLevelsByIDDict, includeBoosters=False))
     59     if totalTime <= 0:
     60         return
     61     isOmegaRestricted = False
     62     for typeID, level in allSkillLevelsByID:
     63         if not isOmegaRestricted:
     64             isOmegaRestricted = ItemObject(typeID).NeedsOmegaUpgrade()
     65 
     66     isOmega = get_clone_grade_svc().is_omega_with_grace_period()
     67     AddTrainingTime(tooltipPanel, isOmega=isOmega, isOmegaRestricted=isOmegaRestricted, trainingTime=totalTime, activityText=GetByLabel('Tooltips/SkillPlanner/ActivityFlyFittedShip'))
     68     if fitName:
     69         skillPlanName = GetByLabel('Tooltips/SkillPlanner/SkillPlanNameStringWithType', typeName=fitName)
     70     else:
     71         skillPlanName = GetByLabel('UI/SkillPlan/DefaultCreateFitSkillPlanName')
     72     AddSkillActionForList(tooltipPanel, allSkillLevelsByID, missingSkills, minWidth=300, skillPlanName=skillPlanName)
     73 
     74 
     75 def GetMissingSkillsForTypeIDs(allTypeIDs):
     76     skillsSvc = sm.GetService('skills')
     77     missingReq = set()
     78     for eachTypeID in allTypeIDs:
     79         if not skillsSvc.IsSkillRequirementMet(eachTypeID):
     80             missingReq.add(eachTypeID)
     81 
     82     return missingReq
     83 
     84 
     85 def GetAllTypeIDsMissingSkillsForShipAndContent(dogmaLocation):
     86     allTypeIDs = _GetAllTypesForShipAndFit(dogmaLocation)
     87     allTypeIDs.update(_GetAllTypesForCargoHold(dogmaLocation))
     88     return allTypeIDs
     89 
     90 
     91 def _GetAllTypesForShipAndFit(dogmaLocation):
     92     allTypeIDs = set()
     93     ship = dogmaLocation.GetShipItem()
     94     if ship is None:
     95         return allTypeIDs
     96     allTypeIDs.add(ship.typeID)
     97     fittedItems = dogmaLocation.GetFittedItemsToShip()
     98     for eachItem in fittedItems.itervalues():
     99         if isinstance(eachItem, (CharacterDogmaItem, ShipDogmaItem)):
    100             continue
    101         allTypeIDs.add(eachItem.typeID)
    102 
    103     for flagID in [const.flagDroneBay, const.flagFighterBay] + const.fighterTubeFlags:
    104         allTypeIDs.update(_GetTypesInFlag(dogmaLocation, flagID))
    105 
    106     return allTypeIDs
    107 
    108 
    109 def _GetAllTypesForCargoHold(dogmaLocation):
    110     return _GetTypesInFlag(dogmaLocation, const.flagCargo)
    111 
    112 
    113 def _GetTypesInFlag(dogmaLocation, flagID):
    114     holdItems = dogmaLocation.GetHoldItems(flagID)
    115     typesInHold = {x.typeID for x in holdItems.itervalues()}
    116     return typesInHold
    117 
    118 
    119 def AddMissingSkillRequirements(tooltipPanel, highestLevelByTypeID, addHeaderLabel = True, text = None):
    120     if not highestLevelByTypeID:
    121         return
    122     skillsSvc = sm.GetService('skills')
    123     tooltipPanel.AddSpacer(width=250, colSpan=tooltipPanel.columns)
    124     tooltipPanel.FillRow()
    125     if addHeaderLabel:
    126         headerText = GetByLabel('UI/Skills/RequiredSkills')
    127         headerLabel = TextHeader(text=headerText)
    128         tooltipPanel.AddCell(headerLabel, colSpan=tooltipPanel.columns, cellPadding=(0, 4, 0, 0))
    129     tooltipPanel.FillRow()
    130     if text:
    131         headerLabel = EveHeaderMedium(text=text, color=COLOR_SKILL_1)
    132         topPadding = 8 if addHeaderLabel else 20
    133         tooltipPanel.AddCell(headerLabel, colSpan=tooltipPanel.columns, cellPadding=(0,
    134          topPadding,
    135          0,
    136          0))
    137     skillList = []
    138     for skillTypeID, skillLevel in highestLevelByTypeID.iteritems():
    139         name = evetypes.GetName(skillTypeID)
    140         skillList.append((name, (skillTypeID, skillLevel)))
    141 
    142     skillList = SortListOfTuples(skillList)
    143     for skillID, level in skillList:
    144         tooltipPanel.AddRow(rowClass=RequiredSkillRow, typeID=skillID, level=level, cellPadding=(0, 4, 0, 0), colSpan=tooltipPanel.columns)
    145 
    146 
    147 def CopyAllSkills(typeIDs):
    148     allSkillsAndLevels = GetAllSkillsAndLevels(typeIDs)
    149     textList = []
    150     for eachSkillTypeID, skillLvl in allSkillsAndLevels:
    151         name = evetypes.GetName(eachSkillTypeID)
    152         textList.append('%s %d' % (name, skillLvl))
    153 
    154     text = '\r\n'.join(textList)
    155     blue.pyos.SetClipboardData(text)
    156 
    157 
    158 def AddSkillAction(tooltipPanel, typeIDs):
    159     allMissingSkillbooks = GetMissingSkillbooksForTypeIDs(typeIDs)
    160     areSomeTypesMissingSkillNotInQueue = bool(GetTypesWithMissingSkills(typeIDs))
    161     skillTypesAndLvlsToUse, _ = GetMissingSkills_HighestLevelByTypeID(typeIDs)
    162     if allMissingSkillbooks:
    163         AddBuyAndTrainForRequiredSkillbooksMissingRow(tooltipPanel, list(allMissingSkillbooks), skillTypesAndLvlsToUse, tooltipPanel.columns)
    164     if areSomeTypesMissingSkillNotInQueue:
    165         if _ShouldAddTrainNowBtn(skillTypesAndLvlsToUse.keys()):
    166             AddTrainNowRow(tooltipPanel, skillTypesAndLvlsToUse)
    167     if session.role & ROLE_GML == ROLE_GML:
    168         skillsAndLevels, _ = GetMissingSkills_HighestLevelByTypeID(typeIDs)
    169         if skillsAndLevels:
    170             btn = Button(label='Give Skills', func=sm.GetService('info').DoGiveSkills, args=(skillsAndLevels, None), idx=0)
    171             tooltipPanel.AddCell(cellObject=btn, colSpan=tooltipPanel.columns)
    172 
    173 
    174 def _ShouldAddTrainNowBtn(skillTypesToUse):
    175     for eachTypeID in skillTypesToUse:
    176         if ItemObject(eachTypeID).CanTrainNow():
    177             return True
    178 
    179     return False
    180 
    181 
    182 def AddTrainNowRow(tooltipPanel, skillTypesAndLvlsToUse):
    183     tooltipPanel.AddCell(cellPadding=(0, 12, 0, 0), colSpan=tooltipPanel.columns)
    184     trainNowButton = TrainNowButtonManyTypes(align=uiconst.CENTER, fixedheight=30, fixedwidth=120, skillTypesAndLvlsToUse=skillTypesAndLvlsToUse)
    185     tooltipPanel.AddCell(trainNowButton, colSpan=tooltipPanel.columns)
    186 
    187 
    188 def AddBuyAndTrainForRequiredSkillbooksMissingRow(grid, missing, skillTypesAndLvlsToUse, colSpan):
    189     grid.AddCell(cellPadding=(0, 12, 0, 0), colSpan=colSpan)
    190     grid.FillRow()
    191     available = [ x for x in missing if evetypes.IsSkillAvailableForPurchase(x) ]
    192     numUnavailable = len(missing) - len(available)
    193     text = GetByLabel('UI/SkillQueue/RequiredSkillBooksMissingWithNum', numBooks=len(missing))
    194     if available and numUnavailable:
    195         text += '<br>%s' % GetByLabel('UI/SkillQueue/AvailableAndUnavailableSkillbooks', numAvailable=len(available), numUnavailable=numUnavailable)
    196     label = EveLabelMedium(align=uiconst.CENTERLEFT, text=text, color=COLOR_SKILL_1)
    197     grid.AddCell(label, colSpan=colSpan - 1)
    198     btn = Button(align=uiconst.CENTERRIGHT, label=GetByLabel('UI/Skills/BuyAndTrain'), fixedheight=24, func=BuyAndTrain, args=(available, skillTypesAndLvlsToUse))
    199     if not available and numUnavailable:
    200         btn.Disable()
    201         if numUnavailable == 1:
    202             btn.hint = GetByLabel('UI/Skills/ErrorRareSkill')
    203         else:
    204             btn.hint = GetByLabel('UI/Skills/ErrorRareSkills')
    205     grid.AddCell(btn, cellPadding=(10, 0, 0, 0))
    206 
    207 
    208 def GetTypesWithMissingSkills(typeIDs):
    209     typesWithMissingSkills = set()
    210     for eachTypeID in typeIDs:
    211         isMet = sm.GetService('skills').IsSkillRequirementMetIncludingSkillQueue(eachTypeID)
    212         if not isMet:
    213             typesWithMissingSkills.add(eachTypeID)
    214 
    215     return typesWithMissingSkills
    216 
    217 
    218 def GetMissingSkillbooksForTypeIDs(typeIDs):
    219     allMissingSkillbooks = set()
    220     for eachTypeID in typeIDs:
    221         itemObject = ItemObject(eachTypeID)
    222         missingSkillbooks = itemObject.GetMissingSkillBooks()
    223         allMissingSkillbooks.update(missingSkillbooks)
    224 
    225     return allMissingSkillbooks
    226 
    227 
    228 def GetMissingSkills_HighestLevelByTypeID(typeIDs):
    229     skillsSvc = sm.GetService('skills')
    230     highestLevelByTypeID = defaultdict(int)
    231     missingSkillsForTypeID = defaultdict(set)
    232     for eachTypeID in typeIDs:
    233         if not evetypes.Exists(eachTypeID) or evetypes.GetCategoryID(eachTypeID) == categoryBlueprint:
    234             continue
    235         allMissing = skillsSvc.GetSkillsMissingToUseItemRecursive(eachTypeID)
    236         for skillTypeID, skillLevel in allMissing.iteritems():
    237             highestLevelByTypeID[skillTypeID] = int(max(skillLevel, highestLevelByTypeID[skillTypeID]))
    238             missingSkillsForTypeID[eachTypeID].add(skillTypeID)
    239 
    240     return (highestLevelByTypeID, missingSkillsForTypeID)
    241 
    242 
    243 def GetSkillTypeIDAndLevelRequired(typeID):
    244     ret = []
    245     _GetSkillTypeIDAndLevelRequired(typeID, ret)
    246     return ret
    247 
    248 
    249 class TrainNowButtonManyTypes(PrimaryButton):
    250     default_name = 'TrainNowButton'
    251 
    252     def ApplyAttributes(self, attributes):
    253         super(TrainNowButtonManyTypes, self).ApplyAttributes(attributes)
    254         self.skillTypesAndLvlsToUse = attributes.skillTypesAndLvlsToUse
    255         self._isFinished = False
    256         self.UpdateState()
    257 
    258     def IsActive(self):
    259         return not self._isFinished
    260 
    261     def ClickFunc(self, *args):
    262         self.Disable()
    263         try:
    264             for eachTypeID, eachLvl in self.skillTypesAndLvlsToUse.iteritems():
    265                 sm.GetService('skillqueue').AddSkillAndRequirementsToQueue(eachTypeID, eachLvl)
    266 
    267             self._isFinished = True
    268         except Exception:
    269             self.Enable()
    270 
    271         self.UpdateState()
    272 
    273     def GetColor(self):
    274         if self._isFinished:
    275             return (1.0, 1.0, 1.0, 0.3)
    276         else:
    277             return COLOR_SKILL_2
    278 
    279     def GetText(self):
    280         if self._isFinished:
    281             return GetByLabel('UI/SkillQueue/SkillQueueUpdated')
    282         else:
    283             return GetByLabel('UI/SkillQueue/AddToQueue')
    284 
    285     def GetTranslation(self):
    286         return 0.1667
    287 
    288     def Update_Size_(self):
    289         PrimaryButton.Update_Size_(self)
    290         self.width = max(self.fixedwidth, self.sr.label.width + 20)
    291 
    292 
    293 def BuyAndTrain(availableForPurchase, skillTypesAndLvlsToUse):
    294     skillSvc = sm.GetService('skills')
    295     boughtSkills = skillSvc.PurchaseSkills(availableForPurchase)
    296     if not boughtSkills:
    297         return
    298     skillSvc.WaitUntilSkillsAreAvailable(availableForPurchase)
    299     skillqueueSvc = sm.GetService('skillqueue')
    300     for eachTypeID, eachLvl in skillTypesAndLvlsToUse.iteritems():
    301         skillqueueSvc.AddSkillAndRequirementsToQueue(eachTypeID, eachLvl)