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

warningIconTooltip.py (18715B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\fittingScreen\warningIconTooltip.py
      2 from collections import defaultdict
      3 import evetypes
      4 import inventorycommon
      5 from carbonui.primitives.container import Container
      6 from carbonui import const as uiconst
      7 from carbonui.primitives.containerAutoSize import ContainerAutoSize
      8 from carbonui.primitives.fill import Fill
      9 from carbonui.primitives.sprite import Sprite
     10 from carbonui.util.color import Color
     11 from dogma.attributes.format import GetFormattedAttributeAndValue
     12 from eve.client.script.ui.control.eveLabel import EveLabelMedium, EveHeaderLarge, EveLabelMediumBold
     13 import shipfitting.fittingWarnings as fittingWarnings
     14 import shipfitting.fittingWarningConst as fittingWarningConst
     15 from eve.client.script.ui.shared.info.infoConst import TAB_TRAITS
     16 from eve.client.script.ui.shared.neocom.skillConst import COLOR_SKILL_2
     17 from fsdBuiltData.common.iconIDs import GetIconFile
     18 from localization import GetByLabel
     19 import dogma.data as dogma_data
     20 ICON_SIZE = 20
     21 
     22 def AddSlotsToWarningDict(warningSlotDict, warningID, updateSet):
     23     warningLevel = fittingWarnings.GetWarningLevelFromWarningID(warningID)
     24     warningSlotDict[warningLevel].update(updateSet)
     25 
     26 
     27 def EvaluateFitAndPopulateTooltip(tooltipPanel, fittingController, warningLevel, fullVersion = False):
     28     tooltipPanel.warningLevel = 0
     29     tooltipPanel.Flush()
     30     headerLabel = False
     31     warningSlotDict = defaultdict(set)
     32     fitResults = fittingWarnings.EvaluateFit(fittingController)
     33     if fitResults is None:
     34         return
     35     fitResults = fittingWarnings.FilterResultsForWarningLevel(fitResults, [warningLevel])
     36     activeWarnings = fittingWarnings.GetActiveWarningsByLevelFromResults(fitResults)
     37     if activeWarnings:
     38         color = fittingWarnings.GetColorForLevel(warningLevel)
     39         headerLabelPath = fittingWarnings.GetHeaderForLevel(warningLevel)
     40         if headerLabelPath:
     41             headerText = GetByLabel(headerLabelPath)
     42             headerLabel = EveHeaderLarge(text=headerText)
     43             headerLabel.SetRGBA(*color)
     44             tooltipPanel.AddCell(headerLabel, colSpan=tooltipPanel.columns, cellPadding=(6, 4, 0, 4))
     45     currentWarningID = fittingWarningConst.WARNING_MISSING_SUBSYSTEMS
     46     missingSubsystems = fitResults.get(currentWarningID, None)
     47     if missingSubsystems:
     48         AddWarningAndAddToSlotDict(tooltipPanel, currentWarningID, fullVersion, set(missingSubsystems), warningSlotDict)
     49         if fullVersion:
     50             AddSubsystemSlotsToTooltip(tooltipPanel, missingSubsystems)
     51     currentWarningID = fittingWarningConst.WARNING_MODULES_IN_INVALID_FLAGS
     52     modulesInInvalidSlots = fitResults.get(currentWarningID, None)
     53     if modulesInInvalidSlots:
     54         PrepareFlagsAndAddWarning(tooltipPanel, currentWarningID, fullVersion, warningSlotDict, modulesInInvalidSlots)
     55     currentWarningID = fittingWarningConst.WARNING_OVER_CPU
     56     if fitResults.get(currentWarningID, None):
     57         AddWarningAndAddToSlotDict(tooltipPanel, currentWarningID, fullVersion, {-currentWarningID}, warningSlotDict)
     58     currentWarningID = fittingWarningConst.WARNING_OVER_POWERGRID
     59     if fitResults.get(currentWarningID, None):
     60         semiflagIDs = {-currentWarningID}
     61         AddWarningAndAddToSlotDict(tooltipPanel, currentWarningID, fullVersion, semiflagIDs, warningSlotDict)
     62     currentWarningID = fittingWarningConst.WARNING_OVER_CALIBRATION
     63     if fitResults.get(currentWarningID, None):
     64         semiflagIDs = set(const.rigSlotFlags)
     65         AddWarningAndAddToSlotDict(tooltipPanel, currentWarningID, fullVersion, semiflagIDs, warningSlotDict)
     66     currentWarningID = fittingWarningConst.WARNING_OVERLOADED_CARGO
     67     if fitResults.get(currentWarningID, None):
     68         flagIDs = [const.flagCargo]
     69         AddWarningAndAddToSlotDict(tooltipPanel, currentWarningID, fullVersion, flagIDs, warningSlotDict)
     70     for currentWarningID in [fittingWarningConst.WARNING_DUAL_TANKED, fittingWarningConst.WARNING_MULTI_TANKED]:
     71         tankingModules = fitResults.get(currentWarningID, None)
     72         if tankingModules:
     73             flagIDs = {x[1] for x in tankingModules}
     74             AddSlotsToWarningDict(warningSlotDict, currentWarningID, flagIDs)
     75             AddWarning(tooltipPanel, currentWarningID, fullVersion, flagIDs)
     76 
     77     for currentWarningID in [fittingWarningConst.WARNING_ARMOR_TANKED_SHIELD_SHIP, fittingWarningConst.WARNING_SHIELD_TANKED_ARMOR_SHIP]:
     78         wrongModules = fitResults.get(currentWarningID, None)
     79         if wrongModules:
     80             PrepareFlagsAndAddWarning(tooltipPanel, currentWarningID, fullVersion, warningSlotDict, wrongModules)
     81 
     82     currentWarningID = fittingWarningConst.WARNING_NOT_PROVIDING_BONUS
     83     notProvidingBonus = fitResults.get(currentWarningID, None)
     84     if notProvidingBonus:
     85         PrepareFlagsAndAddWarning(tooltipPanel, currentWarningID, fullVersion, warningSlotDict, notProvidingBonus)
     86         if fullVersion:
     87             AddModuleRows(tooltipPanel, notProvidingBonus, currentWarningID)
     88     currentWarningID = fittingWarningConst.WARNING_MIXING_TURRET_GROUPS
     89     mixedTurrets = fitResults.get(currentWarningID, None)
     90     if mixedTurrets:
     91         flagIDs = set()
     92         for each in mixedTurrets.itervalues():
     93             flagIDs.update({x[1] for x in each})
     94 
     95         AddWarningAndAddToSlotDict(tooltipPanel, currentWarningID, fullVersion, flagIDs, warningSlotDict)
     96         if fullVersion:
     97             AddTurretOrLauncherGroups(tooltipPanel, mixedTurrets, currentWarningID)
     98     currentWarningID = fittingWarningConst.WARNING_MIXING_LAUNCHER_GROUPS
     99     mixedLaunchers = fitResults.get(currentWarningID, None)
    100     if mixedLaunchers:
    101         flagIDs = set()
    102         for each in mixedLaunchers.itervalues():
    103             flagIDs.update({x[1] for x in each})
    104 
    105         AddWarningAndAddToSlotDict(tooltipPanel, currentWarningID, fullVersion, flagIDs, warningSlotDict)
    106         if fullVersion:
    107             AddTurretOrLauncherGroups(tooltipPanel, mixedLaunchers, currentWarningID)
    108     currentWarningID = fittingWarningConst.WARNING_MIXING_TURRET_SIZES
    109     mixedTurretSizes = fitResults.get(currentWarningID, None)
    110     if mixedTurretSizes:
    111         flagIDs = set()
    112         for each in mixedTurretSizes.itervalues():
    113             flagIDs.update({x[1] for x in each})
    114 
    115         AddWarningAndAddToSlotDict(tooltipPanel, currentWarningID, fullVersion, flagIDs, warningSlotDict)
    116         if fullVersion:
    117             AddTurretSizes(tooltipPanel, mixedTurretSizes, currentWarningID)
    118     currentWarningID = fittingWarningConst.WARNING_OFFLINE_MODULES
    119     offlineModules = fitResults.get(currentWarningID, None)
    120     if offlineModules:
    121         PrepareFlagsAndAddWarning(tooltipPanel, currentWarningID, fullVersion, warningSlotDict, offlineModules)
    122         if fullVersion:
    123             AddModuleRows(tooltipPanel, offlineModules, currentWarningID)
    124     currentWarningID = fittingWarningConst.WARNING_POLARIZED_WEAPONS
    125     polarizedWeapons = fitResults.get(currentWarningID, None)
    126     if polarizedWeapons:
    127         PrepareFlagsAndAddWarning(tooltipPanel, currentWarningID, fullVersion, warningSlotDict, polarizedWeapons)
    128     for currentWarningID in [fittingWarningConst.WARNING_MISSING_REQ_CHARGES, fittingWarningConst.WARNING_MISSING_OPTIONAL_CHARGES]:
    129         missingCharges = fitResults.get(currentWarningID, None)
    130         if missingCharges:
    131             PrepareFlagsAndAddWarning(tooltipPanel, currentWarningID, fullVersion, warningSlotDict, missingCharges)
    132 
    133     currentWarningID = fittingWarningConst.WARNING_UNDERSIZED_PROP_MOD
    134     undersizedPropMods = fitResults.get(currentWarningID, None)
    135     if undersizedPropMods:
    136         PrepareFlagsAndAddWarning(tooltipPanel, currentWarningID, fullVersion, warningSlotDict, undersizedPropMods)
    137     currentWarningID = fittingWarningConst.WARNING_INEFFICIENT_PROP_MOD
    138     inefficientPropMods = fitResults.get(currentWarningID, None)
    139     if inefficientPropMods:
    140         PrepareFlagsAndAddWarning(tooltipPanel, currentWarningID, fullVersion, warningSlotDict, inefficientPropMods)
    141     for currentWarningID in [fittingWarningConst.WARNING_STACKING_PENALTY_MED, fittingWarningConst.WARNING_STACKING_PENALTY_LOW, fittingWarningConst.WARNING_STACKING_PENALTY_TARGETED_LOW]:
    142         stackingPenalty = fitResults.get(currentWarningID, None)
    143         if stackingPenalty:
    144             flagIDs = set()
    145             for each in stackingPenalty.itervalues():
    146                 flagIDs.update({x[1] for x in each})
    147 
    148             AddSlotsToWarningDict(warningSlotDict, currentWarningID, flagIDs)
    149             AddWarning(tooltipPanel, currentWarningID, fullVersion, flagIDs)
    150             if fullVersion:
    151                 AddAttributes(tooltipPanel, stackingPenalty, currentWarningID)
    152 
    153     currentWarningID = fittingWarningConst.WARNING_DISABLED_BUBBLE_IMMUNITY
    154     modulesDisablingBubbleImmunity = fitResults.get(currentWarningID, None)
    155     if modulesDisablingBubbleImmunity:
    156         PrepareFlagsAndAddWarning(tooltipPanel, currentWarningID, fullVersion, warningSlotDict, modulesDisablingBubbleImmunity)
    157     slotsLevelLow = warningSlotDict[fittingWarningConst.WARNING_LEVEL_LOW]
    158     slotsLevelMedium = warningSlotDict[fittingWarningConst.WARNING_LEVEL_MEDIUM]
    159     slotsLevelHigh = warningSlotDict[fittingWarningConst.WARNING_LEVEL_HIGH]
    160     slotsLevelLow = slotsLevelLow - slotsLevelMedium - slotsLevelHigh
    161     slotsLevelMedium = slotsLevelMedium - slotsLevelHigh
    162     warningSlotDict = {x:fittingWarningConst.WARNING_LEVEL_HIGH for x in slotsLevelHigh}
    163     warningSlotDict.update({x:fittingWarningConst.WARNING_LEVEL_MEDIUM for x in slotsLevelMedium})
    164     warningSlotDict.update({x:fittingWarningConst.WARNING_LEVEL_LOW for x in slotsLevelLow})
    165     fittingController.ChangeFittingWarningDisplay(warningSlotDict)
    166     if headerLabel and headerLabel.parent:
    167         cell = headerLabel.parent
    168         cell.state = uiconst.UI_NORMAL
    169         cell.OnMouseEnter = (OnMouseEnterContainer, warningSlotDict)
    170         cell.OnMouseExit = OnMouseExitContainer
    171 
    172 
    173 def PrepareFlagsAndAddWarning(tooltipPanel, currentWarningID, fullVersion, flagIDsDict, notProvidingBonus):
    174     flagIDs = {x[1] for x in notProvidingBonus}
    175     AddWarningAndAddToSlotDict(tooltipPanel, currentWarningID, fullVersion, flagIDs, flagIDsDict)
    176 
    177 
    178 def AddWarningAndAddToSlotDict(tooltipPanel, currentWarningID, fullVersion, flagIDs, warningSlotDict):
    179     AddWarning(tooltipPanel, currentWarningID, fullVersion, flagIDs)
    180     AddSlotsToWarningDict(warningSlotDict, currentWarningID, flagIDs)
    181 
    182 
    183 def AddWarning(tooltipPanel, warningID, fullVersion = False, flagIDs = ()):
    184     warningLevel, textPath, _ = fittingWarningConst.warningsByWarningID[warningID]
    185     color = fittingWarnings.GetColorForLevel(warningLevel)
    186     hint = GetQuestionMarkHint(warningID)
    187     faintColor = color[:3] + (0.25,)
    188     row = tooltipPanel.AddRow()
    189     row.OnMouseEnter = (OnMouseEnterContainer, {flagID:warningLevel for flagID in flagIDs})
    190     row.OnMouseExit = OnMouseExitContainer
    191     row.state = uiconst.UI_NORMAL
    192     row.hint = hint
    193     tooltipPanel.warningLevel = max(tooltipPanel.warningLevel, warningLevel)
    194     tooltipPanel.FillRow()
    195     iconObj = Sprite(pos=(0,
    196      0,
    197      ICON_SIZE,
    198      ICON_SIZE), align=uiconst.CENTERLEFT)
    199     row.AddCell(iconObj, cellPadding=(0, 0, 10, 0))
    200     iconObj.LoadIcon(fittingWarningConst.WARNING_PATH, ignoreSize=True)
    201     iconObj.SetRGBA(*color)
    202     labelColSpan = tooltipPanel.columns - 1 - bool(fullVersion)
    203     label = EveLabelMediumBold(text=GetByLabel(textPath), align=uiconst.CENTERLEFT, bold=True, width=350, autoFitToText=True)
    204     cell = row.AddCell(label, cellPadding=(6, 4, 0, 4), colSpan=labelColSpan)
    205     if fullVersion:
    206         questionmarkLabel = EveLabelMedium(name='questionMark', text='?', align=uiconst.CENTERRIGHT, bold=True)
    207         cell = row.AddCell(questionmarkLabel, cellPadding=(6, 0, 6, 0), colSpan=labelColSpan)
    208         questionmarkLabel.SetRGBA(*color)
    209 
    210 
    211 def GetQuestionMarkHint(warningID):
    212     _, _, hintPath = fittingWarningConst.warningsByWarningID[warningID]
    213     if warningID in (fittingWarningConst.WARNING_ARMOR_TANKED_SHIELD_SHIP, fittingWarningConst.WARNING_SHIELD_TANKED_ARMOR_SHIP, fittingWarningConst.WARNING_WRONG_TANKING):
    214         fittingController = sm.GetService('ghostFittingSvc').GetGhostFittingController()
    215         hint = GetByLabel(hintPath, shipTypeID=fittingController.GetTypeID())
    216     elif warningID in (fittingWarningConst.WARNING_OVER_CPU_POWER, fittingWarningConst.WARNING_OVER_CPU, fittingWarningConst.WARNING_OVER_POWERGRID):
    217         hint = GetByLabel(hintPath, cpuMgmtLink=__GetSkillText(const.typeElectronics), weaponUpgradesLink=__GetSkillText(const.typeWeaponUpgrades), advancedWeaponUpgradesLink=__GetSkillText(const.typeAdvancedWeaponUpgrades), powerGridMgmtLink=__GetSkillText(const.typeEngineering))
    218     else:
    219         hint = GetByLabel(hintPath) if hintPath else None
    220     return hint
    221 
    222 
    223 def __GetSkillText(skillTypeID):
    224     skillName = evetypes.GetName(skillTypeID)
    225     color = Color.RGBtoHex(*COLOR_SKILL_2)
    226     return '<font color=%s><b>%s</b></font>' % (color, skillName)
    227 
    228 
    229 def AddModuleRows(tooltipPanel, modules, warningID):
    230     warningLevel = fittingWarnings.GetWarningLevelFromWarningID(warningID)
    231     sortedModules = sorted(modules, key=lambda x: const.moduleSlotFlags.index(x[1]))
    232     for eachTypeID, eachFlagID in sortedModules:
    233         texturePath = inventorycommon.typeHelpers.GetIconFile(eachTypeID)
    234         cell = _AddRowForGroupingAndItsWeapons(tooltipPanel, evetypes.GetName(eachTypeID), texturePath, [(eachTypeID, eachFlagID)], warningLevel)
    235         cell.GetMenu = lambda *args: sm.GetService('menu').GetMenuFromItemIDTypeID(itemID=None, typeID=eachTypeID)
    236 
    237 
    238 def AddTurretOrLauncherGroups(tooltipPanel, mixedTurrets, warningID):
    239     weaponGroupsAndNames = [ (groupID, evetypes.GetGroupNameByGroup(groupID)) for groupID, weapons in mixedTurrets.iteritems() if weapons ]
    240     weaponGroupsAndNames.sort(key=lambda x: x[1])
    241     warningLevel = fittingWarnings.GetWarningLevelFromWarningID(warningID)
    242     for eachGroup, eachGroupName in weaponGroupsAndNames:
    243         weapons = mixedTurrets[eachGroup]
    244         texturePath = fittingWarnings.GetIconPathForTurretGroup(eachGroup)
    245         _AddRowForGroupingAndItsWeapons(tooltipPanel, eachGroupName, texturePath, weapons, warningLevel)
    246 
    247 
    248 def AddTurretSizes(tooltipPanel, turretSizes, warningID):
    249     sizeAttributeInUse = turretSizes.keys()
    250     sizeAttributeInUse.sort()
    251     warningLevel = fittingWarnings.GetWarningLevelFromWarningID(warningID)
    252     for eachSize in sizeAttributeInUse:
    253         turrets = turretSizes[eachSize]
    254         groupingName = GetValueName(const.attributeChargeSize, eachSize)
    255         texturePath = fittingWarnings.GetIconPathForSizes(eachSize)
    256         _AddRowForGroupingAndItsWeapons(tooltipPanel, groupingName, texturePath, turrets, warningLevel)
    257 
    258 
    259 def AddAttributes(tooltipPanel, attributeInfo, warningID):
    260     attributesByModules = defaultdict(list)
    261     for k, v in attributeInfo.iteritems():
    262         attributesByModules[tuple(v)].append(k)
    263 
    264     for v in attributesByModules.itervalues():
    265         v.sort(key=lambda x: dogma_data.get_attribute_display_name(x[0]))
    266 
    267     sortedAttributes = [ (dogma_data.get_attribute_display_name(x[0]), x[0], y) for x, y in attributeInfo.iteritems() ]
    268     sortedAttributes.sort()
    269     warningLevel = fittingWarnings.GetWarningLevelFromWarningID(warningID)
    270     attributeAdded = defaultdict(list)
    271     for moduleInfoList, attrList in attributesByModules.iteritems():
    272         sortedModuleList = sorted(moduleInfoList)
    273         for attributeID, op, skillTypeID, domain in attrList:
    274             attrText = dogma_data.get_attribute_display_name(attributeID)
    275             if skillTypeID:
    276                 attrText = '%s<br>%s' % (attrText, GetByLabel('UI/Fitting/FittingWindow/Warnings/ForEquipmentRequiringSkill', skillName=evetypes.GetName(skillTypeID)))
    277             modulesAlreadyAddedForAttrName = attributeAdded.get(attrText.lower(), [])
    278             if sortedModuleList in modulesAlreadyAddedForAttrName:
    279                 continue
    280             attributeAdded[attrText.lower()].append(sortedModuleList)
    281             iconID = dogma_data.get_attribute_icon_id(attributeID)
    282             iconFile = GetIconFile(iconID)
    283             _AddRowForGroupingAndItsWeapons(tooltipPanel, attrText, iconFile, moduleInfoList, warningLevel)
    284 
    285 
    286 def _AddRowForGroupingAndItsWeapons(tooltipPanel, groupingName, texturePath, itemTypes, warningLevel, addExtraTypeText = False):
    287     typeIDs = {typeID for typeID, flagID in itemTypes}
    288     flagIDs = {flagID for typeID, flagID in itemTypes}
    289     if addExtraTypeText:
    290         typeNames = [ evetypes.GetName(typeID) for typeID in typeIDs ]
    291         typeNames.sort()
    292         typeText = ', '.join(typeNames[:2])
    293         if len(typeNames) > 2:
    294             typeText += '...'
    295         text = '%s (%s)' % (groupingName, typeText)
    296     else:
    297         text = groupingName
    298     tooltipPanel.FillRow()
    299     tooltipPanel.AddCell()
    300     c = Container(height=ICON_SIZE, align=uiconst.CENTERLEFT, state=uiconst.UI_NORMAL)
    301     c.flagIDs = flagIDs
    302     c.OnMouseEnter = (OnMouseEnterContainer, {flagID:warningLevel for _, flagID in itemTypes})
    303     c.OnMouseExit = OnMouseExitContainer
    304     iconObj = Sprite(parent=c, pos=(0,
    305      0,
    306      ICON_SIZE,
    307      ICON_SIZE), align=uiconst.CENTERLEFT, texturePath=texturePath)
    308     l = EveLabelMedium(parent=c, align=uiconst.CENTERLEFT, left=ICON_SIZE + 2, text=text)
    309     c.width = l.left + l.textwidth
    310     c.height = max(c.height, l.height + 4)
    311     tooltipPanel.AddCell(cellObject=c, colSpan=tooltipPanel.columns - 1)
    312     return c
    313 
    314 
    315 def OnMouseEnterContainer(warningSlotDict):
    316     if warningSlotDict:
    317         fittingController = sm.GetService('ghostFittingSvc').GetGhostFittingController()
    318         fittingController.ChangeFittingWarningDisplay(warningSlotDict)
    319 
    320 
    321 def OnMouseExitContainer(*args):
    322     fittingController = sm.GetService('ghostFittingSvc').GetGhostFittingController()
    323     fittingController.ChangeFittingWarningDisplay({})
    324 
    325 
    326 def AddSubsystemSlotsToTooltip(tooltipPanel, missingSubsystems):
    327     for eachFlagID in missingSubsystems:
    328         groupID, iconPath = fittingWarningConst.SUBSYSTEM_INFO_BY_SLOT[eachFlagID]
    329         groupName = evetypes.GetGroupNameByGroup(groupID)
    330         tooltipPanel.FillRow()
    331         tooltipPanel.AddCell()
    332         c = ContainerAutoSize(height=ICON_SIZE)
    333         iconObj = Sprite(parent=c, pos=(0,
    334          0,
    335          ICON_SIZE,
    336          ICON_SIZE), align=uiconst.CENTERLEFT, texturePath=iconPath)
    337         EveLabelMedium(parent=c, align=uiconst.CENTERLEFT, left=30, text=groupName)
    338         tooltipPanel.AddCell(cellObject=c, colSpan=tooltipPanel.columns - 1)
    339 
    340 
    341 def GetValueName(attributeID, value):
    342     formatInfo = GetFormattedAttributeAndValue(attributeID, value)
    343     return formatInfo.value