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

infoUtil.py (14403B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\info\infoUtil.py
      2 import sys
      3 from collections import defaultdict
      4 import dogma.const
      5 import dogma.data
      6 import eveformat
      7 import evetypes
      8 import localization
      9 from carbon.common.script.util.mathCommon import FloatCloseEnough
     10 from carbonui import uiconst
     11 from dogma.attributes.format import GetFormattedAttributeAndValue
     12 from eve.client.script.ui import eveColor
     13 from eve.client.script.ui.shared.fittingScreen.fittingUtil import allPowerEffects
     14 from eve.client.script.ui.shared.info.attribute import IsModified, IsMutated
     15 from eve.client.script.ui.shared.dynamicItem.mutationBar import MutationBar
     16 import inventorycommon.const as invConst
     17 from dogma.attributes.groups import fitting_attribute_ids
     18 OVERLOAD_ATTRIBUTE = 'overLoadAttribute'
     19 attributesWithUnknownHighIsGood = (dogma.const.attributeMass, dogma.const.attributeDrawback)
     20 
     21 def GetAttributeTooltipTitleAndDescription(attributeID):
     22     if attributeID:
     23         attributeInfo = dogma.data.get_attribute(attributeID)
     24         tooltipTitleID = getattr(attributeInfo, 'tooltipTitleID', None)
     25         if tooltipTitleID:
     26             tooltipDescriptionID = attributeInfo.tooltipDescriptionID
     27             return (localization.GetByMessageID(tooltipTitleID), localization.GetByMessageID(tooltipDescriptionID))
     28     return (None, None)
     29 
     30 
     31 def GetColoredText(attribute, text):
     32     return GetColoredTextWithCustomColors(attribute, text, positiveChange=eveColor.SUCCESS_GREEN, negativeChange=eveColor.DANGER_RED, unknown=eveColor.SAND_YELLOW)
     33 
     34 
     35 def GetColoredTextWithCustomColors(attribute, text, positiveChange, negativeChange, unknown):
     36     if IsModified(attribute) and _IsValidValue(attribute.value) and _IsValidValue(attribute.baseValue):
     37         if attribute.isSame and IsMutated(attribute):
     38             if attribute.isMutationPositive:
     39                 color = positiveChange
     40             else:
     41                 color = negativeChange
     42         elif attribute.isSame:
     43             color = unknown
     44         elif attribute.isBetter and IsMutated(attribute):
     45             if attribute.isMutationPositive:
     46                 color = positiveChange
     47             else:
     48                 color = negativeChange
     49         elif attribute.attributeID in attributesWithUnknownHighIsGood:
     50             color = unknown
     51         elif attribute.isBetter:
     52             color = positiveChange
     53         else:
     54             color = negativeChange
     55     elif IsMutated(attribute):
     56         if attribute.isMutationPositive:
     57             color = positiveChange
     58         else:
     59             color = negativeChange
     60     else:
     61         return text
     62     return eveformat.color(text, color)
     63 
     64 
     65 def _IsValidValue(value):
     66     return value is not None and not isinstance(value, basestring)
     67 
     68 
     69 def PrepareInfoTextForAttributeHint(textLabel, attribute, itemID = None, extraModifyingAttrIDs = None, extraModifyingFactors = None):
     70     if not attribute:
     71         return
     72     if textLabel.state == uiconst.UI_DISABLED:
     73         textLabel.state = uiconst.UI_NORMAL
     74     textLabel.LoadTooltipPanel = LoadAttributeTooltipPanel
     75     textLabel.modifiedAttribute = attribute
     76     textLabel.itemID = itemID
     77     textLabel.extraModifyingAttrIDs = extraModifyingAttrIDs or []
     78     textLabel.extraModifyingFactors = extraModifyingFactors or []
     79 
     80 
     81 def LoadAttributeTooltipPanel(panel, owner):
     82     panel.margin = (8, 8, 8, 0)
     83     attribute = getattr(owner, 'modifiedAttribute', None)
     84     itemID = getattr(owner, 'itemID', None)
     85     extraModifyingAttrIDs = getattr(owner, 'extraModifyingAttrIDs', None) or []
     86     extraModifyingFactors = getattr(owner, 'extraModifyingFactors', None) or []
     87     if attribute is None:
     88         return
     89     if IsMutated(attribute):
     90         text = localization.GetByLabel('UI/InfoWindow/AttributeIsMutated')
     91         panel.AddLabelMedium(text=text)
     92         MutationBar(parent=panel, align=uiconst.TOPLEFT, top=4, attribute=attribute, barWidth=60)
     93     if IsModified(attribute):
     94         panel.margin = (8, 8, 8, 8)
     95         if attribute.baseValue is None:
     96             text = localization.GetByLabel('UI/InfoWindow/AttributeModified')
     97             panel.AddLabelMedium(text=text)
     98         else:
     99             affectedByTextList = GetAffectedByTextList(attribute.attributeID, itemID)
    100             for mAttrID in extraModifyingAttrIDs:
    101                 affectedByTextList += GetAffectedByTextList(mAttrID, itemID)
    102 
    103             affectedByTextList += GetExtraModifyingFactorsList(extraModifyingFactors)
    104             affectedByText = GetAffectedByText(affectedByTextList) or ''
    105             if affectedByText:
    106                 text = localization.GetByLabel('UI/InfoWindow/AttributeModifiedByWithBaseValue', affectedByText=affectedByText, baseAttributeValue=attribute.displayBaseValue)
    107             else:
    108                 text = localization.GetByLabel('UI/InfoWindow/AttributeModifiedWithBaseValue', baseAttributeValue=attribute.displayBaseValue)
    109             panel.AddLabelMedium(text=text)
    110 
    111 
    112 def GetAffectedByText(textList):
    113     if textList:
    114         return '<br>'.join(textList)
    115 
    116 
    117 def GetAffectedByTextList(attributeID, itemID):
    118     if not itemID:
    119         return []
    120     infoSvc = sm.GetService('info')
    121     dogmaLocation = infoSvc.GetDogmaLocation(itemID)
    122     dogmaItem = dogmaLocation.SafeGetDogmaItem(itemID)
    123     if not dogmaItem:
    124         return []
    125     itemAttributes = dogmaItem.attributes
    126     attribRoot = None
    127     if attributeID in itemAttributes:
    128         attribRoot = itemAttributes[attributeID]
    129     if not attribRoot:
    130         return []
    131     makesHigher = defaultdict(list)
    132     makesLower = defaultdict(list)
    133     textList = []
    134     externalFactorsMakeHigher = False
    135     externalFactorsMakeLower = False
    136     if not infoSvc.IsItemSimulated(itemID):
    137         try:
    138             clientValue = dogmaLocation.GetAttributeValue(itemID, attributeID)
    139             attrName = dogma.data.get_attribute_name(attributeID)
    140             godmaVal = sm.GetService('godma').GetStateManager().GetAttribute(itemID, attrName)
    141             if not FloatCloseEnough(godmaVal, clientValue):
    142                 externalFactorsMakeHigher = godmaVal > clientValue
    143                 externalFactorsMakeLower = clientValue > godmaVal
    144         except (KeyError, RuntimeError, ZeroDivisionError):
    145             sys.exc_clear()
    146 
    147     HarvestModifiers(attribRoot, makesHigher, makesLower)
    148     for direction, dictToUse, externalFactorsActive in [(u'\u2191', makesHigher, externalFactorsMakeHigher), (u'\u2193', makesLower, externalFactorsMakeLower)]:
    149         if dictToUse:
    150             for what, typeList in dictToUse.iteritems():
    151                 countDict = defaultdict(int)
    152                 for typeID in typeList:
    153                     countDict[typeID] += 1
    154 
    155                 for typeID, typeCount in countDict.iteritems():
    156                     if what == OVERLOAD_ATTRIBUTE:
    157                         cat = localization.GetByLabel('UI/InfoWindow/OverloadedModule')
    158                     else:
    159                         cat = evetypes.GetCategoryName(typeID)
    160                     typeText = ' %s %s: %s%s ' % (direction,
    161                      cat,
    162                      '%sx ' % typeCount if typeCount > 1 else '',
    163                      evetypes.GetName(typeID))
    164                     textList.append(typeText)
    165 
    166         if externalFactorsActive:
    167             textList.append(' %s %s' % (direction, localization.Get('UI/InfoWindow/ExternalFactors')))
    168 
    169     return textList
    170 
    171 
    172 def HarvestModifiers(curAttrib, makesHigher, makesLower):
    173     modifiers = curAttrib.GetIncomingModifiers()
    174     if not modifiers:
    175         return
    176     for opIdx, attrib in modifiers:
    177         val = attrib.GetValue()
    178         dictToUse = None
    179         if opIdx in (dogma.const.dgmAssPreMul, dogma.const.dgmAssPostMul):
    180             if val > 1.0:
    181                 dictToUse = makesHigher
    182             elif val < 1.0:
    183                 dictToUse = makesLower
    184         elif opIdx == dogma.const.dgmAssPostPercent:
    185             if val > 0.0:
    186                 dictToUse = makesHigher
    187             elif val < 0.0:
    188                 dictToUse = makesLower
    189         elif opIdx in (dogma.const.dgmAssPreDiv, dogma.const.dgmAssPostDiv):
    190             if val < 1.0:
    191                 dictToUse = makesHigher
    192             elif val > 1.0:
    193                 dictToUse = makesLower
    194         elif opIdx == dogma.const.dgmAssModAdd:
    195             if val > 0.0:
    196                 dictToUse = makesHigher
    197             elif val < 0.0:
    198                 dictToUse = makesLower
    199         elif opIdx == dogma.const.dgmAssModSub:
    200             if val < 0.0:
    201                 dictToUse = makesHigher
    202             elif val > 0.0:
    203                 dictToUse = makesLower
    204         if dictToUse is None:
    205             continue
    206         skills = getattr(attrib, 'skills', [])
    207         if skills:
    208             dictToUse[attrib.__class__.__name__].extend(skills)
    209         else:
    210             invItem = getattr(attrib, 'invItem', None)
    211             if invItem:
    212                 typeID = attrib.invItem.typeID
    213                 if IsOverloadAttribute(attrib, typeID):
    214                     dictToUse[OVERLOAD_ATTRIBUTE].append(typeID)
    215                 else:
    216                     dictToUse[attrib.__class__.__name__].append(typeID)
    217         HarvestModifiers(attrib, makesHigher, makesLower)
    218 
    219     return (makesHigher, makesLower)
    220 
    221 
    222 def GetExtraModifyingFactorsList(extraModifyingFactors):
    223     ret = []
    224     for factorText, direction in extraModifyingFactors:
    225         text = ''
    226         if direction > 0:
    227             text = u'\u2191 '
    228         elif direction < 0:
    229             text = u'\u2193 '
    230         text += factorText
    231         ret.append(text)
    232 
    233     return ret
    234 
    235 
    236 overloadingAttributesByTypeID = {}
    237 
    238 def IsOverloadAttribute(attrib, typeID):
    239     if getattr(attrib, 'attribID', None):
    240         overloadingAttributes = overloadingAttributesByTypeID.get(typeID, None)
    241         if overloadingAttributes is None:
    242             overloadingAttributes = GetOverloadingAttributes(typeID)
    243             overloadingAttributesByTypeID[typeID] = overloadingAttributes
    244         if attrib.attribID in overloadingAttributes:
    245             return True
    246     return False
    247 
    248 
    249 def GetOverloadingAttributes(typeID):
    250     overloadingAttributes = set()
    251     for e in dogma.data.get_type_effects(typeID):
    252         if dogma.data.get_effect_category(e.effectID) != dogma.const.dgmEffOverload:
    253             continue
    254         effect = dogma.data.get_effect(e.effectID)
    255         for m in effect.modifierInfo:
    256             if m.modifyingAttributeID:
    257                 overloadingAttributes.add(m.modifyingAttributeID)
    258 
    259     return overloadingAttributes
    260 
    261 
    262 hybridTexturePath = 'res:/UI/Texture/classes/ShipTree/attributes/hybridTurrets.png'
    263 projectileTexturePath = 'res:/UI/Texture/classes/ShipTree/attributes/projectileTurrets.png'
    264 energyTexturePath = 'res:/UI/Texture/classes/ShipTree/attributes/energyTurrets.png'
    265 precursorTexturePath = 'res:/UI/Texture/classes/ShipTree/attributes/precursor.png'
    266 missileTexturePath = 'res:/UI/Texture/classes/ShipTree/attributes/missiles.png'
    267 iconPathsForGroupIDs = {invConst.groupHybridWeapon: hybridTexturePath,
    268  invConst.groupProjectileWeapon: projectileTexturePath,
    269  invConst.groupEnergyWeapon: energyTexturePath,
    270  invConst.groupPrecursorTurret: precursorTexturePath,
    271  invConst.groupHybridAmmo: hybridTexturePath,
    272  invConst.groupAdvancedRailgunCharge: hybridTexturePath,
    273  invConst.groupAdvancedBlasterCharge: hybridTexturePath,
    274  invConst.groupProjectileAmmo: projectileTexturePath,
    275  invConst.groupAdvancedArtilleryAmmo: projectileTexturePath,
    276  invConst.groupAdvancedAutocannonAmmo: projectileTexturePath,
    277  invConst.groupFrequencyCrystal: energyTexturePath,
    278  invConst.groupAdvancedBeamLaserCrystal: energyTexturePath,
    279  invConst.groupAdvancedPulseLaserCrystal: energyTexturePath,
    280  invConst.groupChargeBottle: precursorTexturePath,
    281  invConst.groupAdvancedChargeBottle: precursorTexturePath}
    282 iconPathForChargeSizes = {1: 'res:/UI/Texture/classes/Fitting/Small.png',
    283  2: 'res:/UI/Texture/classes/Fitting/Medium.png',
    284  3: 'res:/UI/Texture/classes/Fitting/Large.png',
    285  4: 'res:/UI/Texture/classes/Fitting/XLarge.png'}
    286 
    287 def GetWeaonSystemIconForTypeID(typeID):
    288     groupID = evetypes.GetGroupID(typeID)
    289     iconPath = iconPathsForGroupIDs.get(groupID, None)
    290     if iconPath:
    291         return iconPath
    292     typeEffects = dogma.data.get_type_effects(typeID)
    293     usesMissiles = any((x for x in typeEffects if x.effectID in (dogma.const.effectUseMissiles, dogma.const.effectDotMissileLaunching)))
    294     if usesMissiles:
    295         return missileTexturePath
    296     isMissile = any((x for x in typeEffects if x.effectID in (dogma.const.effectMissileLaunching, dogma.const.effectFofMissileLaunching)))
    297     if isMissile:
    298         return missileTexturePath
    299 
    300 
    301 def GetIconAndLabelForChargeSize(typeID):
    302     chargeAttributeValue = dogma.data.get_type_attribute(typeID, dogma.const.attributeChargeSize)
    303     if not chargeAttributeValue:
    304         return (None, '')
    305     groupID = evetypes.GetGroupID(typeID)
    306     if groupID not in iconPathsForGroupIDs:
    307         return (None, '')
    308     texturePath = iconPathForChargeSizes.get(int(chargeAttributeValue), None)
    309     formattedInfo = GetFormattedAttributeAndValue(dogma.const.attributeChargeSize, chargeAttributeValue)
    310     label = '%s: %s' % (formattedInfo.displayName, formattedInfo.value)
    311     return (texturePath, label)
    312 
    313 
    314 def GetEffectIconIdAndLabelID(typeID):
    315     for effect in dogma.data.get_type_effects(typeID):
    316         if effect.effectID in allPowerEffects:
    317             powerType = effect.effectID
    318             effectInfo = dogma.data.get_effect(powerType)
    319             break
    320     else:
    321         return (None, '')
    322 
    323     return (effectInfo.iconID, effectInfo.displayNameID)
    324 
    325 
    326 usedWithAttributes = [dogma.const.attributeChargeGroup1,
    327  dogma.const.attributeChargeGroup2,
    328  dogma.const.attributeChargeGroup3,
    329  dogma.const.attributeChargeGroup4,
    330  dogma.const.attributeChargeGroup5,
    331  dogma.const.attributeLauncherGroup,
    332  dogma.const.attributeLauncherGroup2,
    333  dogma.const.attributeLauncherGroup3,
    334  dogma.const.attributeLauncherGroup4,
    335  dogma.const.attributeLauncherGroup5,
    336  dogma.const.attributeLauncherGroup6]
    337 
    338 def GetUsedWithText(typeID):
    339     textList = []
    340     for eachAttribute in usedWithAttributes:
    341         usedWithGroup = dogma.data.get_type_attribute(typeID, eachAttribute, None)
    342         if usedWithGroup:
    343             textList.append('- %s' % evetypes.GetGroupNameByGroup(int(usedWithGroup)))
    344 
    345     if textList:
    346         textList.insert(0, '%s:' % localization.GetByLabel('UI/InfoWindow/TabNames/UsedWith'))
    347     return '<br>'.join(textList)