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

panelAttributes.py (23494B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\info\shipInfoPanels\panelAttributes.py
      2 import eveicon
      3 import localization
      4 from collections import OrderedDict
      5 import uthread2
      6 from carbonui import Align, uiconst, TextColor
      7 from carbonui.text.styles import TextHeader, TextBody
      8 from carbonui.control.scrollContainer import ScrollContainer
      9 from carbonui.primitives.container import Container
     10 from carbonui.primitives.containerAutoSize import ContainerAutoSize
     11 from carbonui.uianimations import animations
     12 from dogma import const
     13 from dogma.attributes.format import GetFormattedAttributeAndValue
     14 from eve.client.script.ui.control.eveWindowUnderlay import ListEntryUnderlay
     15 from eve.client.script.ui.inflight.shipModuleButton.attributeValueRowContainer import AttributeValueRowContainer
     16 from eve.client.script.ui.shared.info.attribute import Attribute
     17 from eve.client.script.ui.shared.info.shipInfoCollapsibleGroup import CollapsibleGaugeGroup, CollapsibleGroup
     18 from eve.client.script.ui.shared.info.shipInfoListEntries import ListEntryStatusBarAttribute, ListEntryAttribute, ListEntryTypeAttribute
     19 from eve.client.script.ui.shared.info.shipInfoPanels.panelBase import PanelBase
     20 from eve.client.script.ui.shared.info.shipInfoConst import TOP_DOWN_NOSE_UP, TAB_ATTRIBUTES
     21 from eve.common.script.util.eveFormat import FmtDist2
     22 from fsdBuiltData.common.iconIDs import GetIconFile
     23 from localization import GetByLabel
     24 from shipfitting.fittingDogmaLocationUtil import GetAlignTimeFromAgilityAndMass
     25 DAMAGE_TYPE_ICONS = {'em': 'res:/ui/texture/icons/22_32_12.png',
     26  'thermal': 'res:/ui/texture/icons/22_32_10.png',
     27  'kinetic': 'res:/ui/texture/icons/22_32_9.png',
     28  'explosive': 'res:/ui/texture/icons/22_32_11.png'}
     29 DAMAGE_TYPE_COLORS = {'em': (0.1,
     30         0.37,
     31         0.55,
     32         1.0),
     33  'thermal': (0.55,
     34              0.1,
     35              0.1,
     36              1.0),
     37  'kinetic': (0.45,
     38              0.45,
     39              0.45,
     40              1.0),
     41  'explosive': (0.55,
     42                0.37,
     43                0.1,
     44                1.0)}
     45 MIN_IN_MS = 60 * 1000
     46 ATTRIBUTE_GROUP_ICONS = {'structure': eveicon.inventory,
     47  'armor': eveicon.armor,
     48  'shield': eveicon.shields,
     49  'ewar': eveicon.capacitor_warfare,
     50  'capacitor': eveicon.capacitor_plus,
     51  'targeting': eveicon.target,
     52  'sharedFacilities': eveicon.shared_folder,
     53  'fighterFacilities': eveicon.drones,
     54  'onDeath': eveicon.inventory,
     55  'jumpDrive': eveicon.broadcast_warp_to_jump_beacon,
     56  'propulsion': eveicon.warp_to,
     57  'navigation': eveicon.warp_to,
     58  'drones': eveicon.drones,
     59  'inventory': eveicon.inventory}
     60 
     61 class PanelAttributes(PanelBase):
     62 
     63     def ApplyAttributes(self, attributes):
     64         self.fitting_controller = None
     65         super(PanelAttributes, self).ApplyAttributes(attributes)
     66 
     67     def _construct_content(self):
     68         self.scrollContainer = ScrollContainer(name='abilityScroll', parent=self.rightCont, align=Align.TOALL)
     69         self.attributeCont = ContainerAutoSize(name='abilityCont', parent=self.scrollContainer, align=Align.TOTOP)
     70         self._construct_attributes()
     71         uthread2.start_tasklet(self._construct_size)
     72 
     73     def _construct_attributes(self):
     74         attrDict = self.infoSvc.GetAttributeDictForType(self.typeID)
     75         for group_id, attribGroup in self.attributesByCaption.iteritems():
     76             group_icon = ATTRIBUTE_GROUP_ICONS[group_id]
     77             group_name = attribGroup['groupName']
     78             normalAttributes = attribGroup['normalAttributes']
     79             groupedAttributes = attribGroup.get('groupedAttributes', [])
     80             constructedAttributes = attribGroup.get('constructedAttributes', None)
     81             derivedHeaderAttribute = attribGroup.get('derivedHeaderAttribute', None)
     82             derivedHeaderAttributeLabel = None
     83             derivedHeaderAttributeValue = None
     84             derivedHeaderAttributeTooltip = None
     85             derivedHeaderAttributeFormat = None
     86             if derivedHeaderAttribute:
     87                 derivedHeaderAttributeLabel = derivedHeaderAttribute['name']
     88                 derivedHeaderAttributeTooltip = derivedHeaderAttribute['tooltip']
     89                 derivedHeaderAttributeFormat = derivedHeaderAttribute['format']
     90                 valueFunc = derivedHeaderAttribute['valueFunc']
     91                 parameterAttribs = derivedHeaderAttribute['parameterAttributes']
     92                 params = {}
     93                 for name, attributeID in parameterAttribs.iteritems():
     94                     params[name] = self.attributes[attributeID].value
     95 
     96                 derivedHeaderAttributeValue = valueFunc(**params)
     97             if groupedAttributes:
     98                 groupedAttribs = {}
     99                 layerHpAttributeID = attribGroup['hpAttribute']
    100                 hpDescriptionPath = attribGroup['hpDescriptionPath']
    101                 layerHp = self.attributes[layerHpAttributeID].value
    102                 for damageType, attributeID in groupedAttributes:
    103                     attrib = self.attributes[attributeID]
    104                     modifiedAttrib = self.modifiedAttributesDict.get(attributeID, None)
    105                     groupedAttribs[damageType] = (attrib, modifiedAttrib)
    106 
    107                 groupContainer = CollapsibleGaugeGroup(parent=self.attributeCont, name=group_id, align=Align.TOTOP, groupIcon=group_icon, groupName=group_name, iconID=eveicon.armor, itemID=self.itemID, layerHp=layerHp, groupedAttributes=groupedAttribs, padBottom=8, damageTypeIcons=DAMAGE_TYPE_ICONS, damageTypeColors=DAMAGE_TYPE_COLORS, ehpDescriptionPath=hpDescriptionPath)
    108             else:
    109                 groupContainer = CollapsibleGroupWithHeaderAttribute(parent=self.attributeCont, name=group_id, align=Align.TOTOP, groupIcon=group_icon, groupName=group_name, padBottom=8, headerAttributeLabel=derivedHeaderAttributeLabel, headerAttributeValue=derivedHeaderAttributeValue, headerAttributeTooltip=derivedHeaderAttributeTooltip, headerAttributeFormat=derivedHeaderAttributeFormat)
    110             groupedEntries, attribsAdded = self.infoSvc.GetAttributeRowData(normalAttributes, attrDict, self.itemID, self.modifiedAttributesDict)
    111             shipAttr = [ each for each in normalAttributes if each in attrDict ]
    112             for attributeID in shipAttr:
    113                 if attributeID in attribsAdded:
    114                     continue
    115                 attrib = self.attributes[attributeID]
    116                 modifiedAttrib = self.modifiedAttributesDict.get(attributeID, None)
    117                 if attrib.unitID == const.unitMilliseconds and attrib.value >= 5 * MIN_IN_MS:
    118                     formatInfo = GetFormattedAttributeAndValue(attributeID, attrib.value / MIN_IN_MS / 60, const.unitHour)
    119                 else:
    120                     formatInfo = GetFormattedAttributeAndValue(attributeID, attrib.value)
    121                 if not formatInfo:
    122                     continue
    123                 statusBarData = self.infoSvc.GetStatusBarDataForAttribute(attributeID, self.itemID, self.typeID, modifiedAttrib)
    124                 if statusBarData:
    125                     texturePath = GetIconFile(statusBarData['iconID'])
    126                     ListEntryStatusBarAttribute(label=statusBarData['label'], text=statusBarData['text'], texturePath=texturePath, itemID=self.itemID, attributeID=statusBarData['attributeID'], modifiedAttribute=statusBarData['modifiedAttribute'], color=statusBarData['color'], value=statusBarData['value'], parent=groupContainer.mainCont)
    127                     continue
    128                 attributeData = self.infoSvc.GetDataForAttribute(attributeID, attrib.value, self.itemID, self.typeID, modifiedAttrib)
    129                 if attributeData:
    130                     texturePath = GetIconFile(attributeData['iconID'])
    131                     if attributeData['typeID']:
    132                         ListEntryTypeAttribute(label=attributeData['label'], text=attributeData['text'], texturePath=texturePath, typeID=attributeData['typeID'], itemID=self.itemID, attributeID=attributeData['attributeID'], modifiedAttribute=attributeData['modifiedAttribute'], parent=groupContainer.mainCont)
    133                     else:
    134                         ListEntryAttribute(label=attributeData['label'], text=attributeData['text'], texturePath=texturePath, itemID=self.itemID, attributeID=attributeData['attributeID'], modifiedAttribute=attributeData['modifiedAttribute'], parent=groupContainer.mainCont)
    135 
    136             if constructedAttributes:
    137                 for attributeID, dataFunc in constructedAttributes:
    138                     data = dataFunc(self.typeID, self.itemID)
    139                     texturePath = GetIconFile(data['iconID'])
    140                     if data:
    141                         ListEntryAttribute(parent=groupContainer.mainCont, label=data['label'], text=data['text'], texturePath=texturePath, itemID=self.itemID, attributeID=data['attributeID'], modifiedAttribute=data.get('modifiedAttribute', None))
    142 
    143             for dataEntry in groupedEntries:
    144                 ListEntryAttributeGroup(parent=groupContainer.mainCont, padLeft=4, **dataEntry)
    145 
    146             if len(groupContainer.mainCont.children) == 0:
    147                 groupContainer.Hide()
    148                 continue
    149 
    150     def _construct_size(self):
    151         bottomCont = Container(name='bottomCont', parent=self.leftCont, align=Align.TOBOTTOM, height=84, padLeft=32, opacity=0)
    152         long_axis_length = self._controller.long_axis_length
    153         while long_axis_length == 0:
    154             uthread2.sleep(0.01)
    155             long_axis_length = self._controller.long_axis_length
    156 
    157         length = FmtDist2(long_axis_length, maxDecimals=0)
    158         labelCont = Container(name='labelCont', parent=bottomCont, align=Align.TOTOP, height=12)
    159         TextBody(name='label', parent=labelCont, align=Align.CENTERLEFT, text=localization.GetByLabel('UI/InfoWindow/LongAxis'), color=TextColor.SECONDARY)
    160         valueCont = Container(name='valueCont', parent=bottomCont, align=Align.TOTOP, height=24)
    161         TextHeader(name='value', parent=valueCont, align=Align.CENTERLEFT, text=length, bold=True)
    162         animations.FadeIn(bottomCont, duration=1.2)
    163 
    164     def _gather_data(self):
    165         self.infoSvc = sm.GetService('info')
    166         self.attributesByCaption = self.get_ship_attributes()
    167         self.attributeDictForType, self.attributeDict = self.infoSvc.GetAttributeDictForItem(self.itemID, self.typeID)
    168         self.modifiedAttributesDict = self.infoSvc.FindAttributesThatHaveBeenModified(self.attributeDictForType, self.attributeDict)
    169         if not self.attributeDict:
    170             self.attributeDict = self.attributeDictForType
    171         self.attributes = {}
    172         for attributeID, value in self.attributeDict.iteritems():
    173             self.attributes[attributeID] = Attribute(attributeID, value)
    174 
    175     def _enable_expanded_view(self):
    176         self.attributeCont.SetParent(self.scrollContainer)
    177 
    178     def _enable_minimized_view(self):
    179         self.attributeCont.SetParent(self.content_scroll_minimized)
    180 
    181     @classmethod
    182     def get_name(cls):
    183         return localization.GetByLabel('UI/InfoWindow/TabNames/Attributes')
    184 
    185     @classmethod
    186     def get_icon(cls):
    187         return eveicon.attributes
    188 
    189     def get_camera_position(self):
    190         return TOP_DOWN_NOSE_UP
    191 
    192     def get_tab_type(self):
    193         return TAB_ATTRIBUTES
    194 
    195     @classmethod
    196     def is_visible(cls, typeID, itemID = None, rec = None):
    197         return True
    198 
    199     def _get_group_icon(self, group_id):
    200         return None
    201 
    202     def get_ship_attributes(self):
    203         shipAttributes = OrderedDict()
    204         shipAttributes['shield'] = {'groupName': GetByLabel('UI/Common/Shield'),
    205          'hpAttribute': const.attributeShieldCapacity,
    206          'hpDescriptionPath': 'UI/InfoWindow/EffectiveHpDescriptionShield',
    207          'groupedAttributes': [('em', const.attributeShieldEmDamageResonance),
    208                                ('thermal', const.attributeShieldThermalDamageResonance),
    209                                ('kinetic', const.attributeShieldKineticDamageResonance),
    210                                ('explosive', const.attributeShieldExplosiveDamageResonance)],
    211          'normalAttributes': [const.attributeShieldCapacity, const.attributeShieldRechargeRate, const.attributeShieldDamageLimit]}
    212         shipAttributes['armor'] = {'groupName': GetByLabel('UI/Common/Armor'),
    213          'hpAttribute': const.attributeArmorHP,
    214          'hpDescriptionPath': 'UI/InfoWindow/EffectiveHpDescriptionArmor',
    215          'groupedAttributes': [('em', const.attributeArmorEmDamageResonance),
    216                                ('thermal', const.attributeArmorThermalDamageResonance),
    217                                ('kinetic', const.attributeArmorKineticDamageResonance),
    218                                ('explosive', const.attributeArmorExplosiveDamageResonance)],
    219          'normalAttributes': [const.attributeArmorHP, const.attributeArmorDamageLimit]}
    220         shipAttributes['structure'] = {'groupName': GetByLabel('UI/Fitting/Structure'),
    221          'hpAttribute': const.attributeHp,
    222          'hpDescriptionPath': 'UI/InfoWindow/EffectiveHpDescriptionStructure',
    223          'groupedAttributes': [('em', const.attributeEmDamageResonance),
    224                                ('thermal', const.attributeThermalDamageResonance),
    225                                ('kinetic', const.attributeKineticDamageResonance),
    226                                ('explosive', const.attributeExplosiveDamageResonance)],
    227          'normalAttributes': [const.attributeHp, const.attributeStructureDamageLimit]}
    228         shipAttributes['capacitor'] = {'groupName': GetByLabel('UI/Fitting/FittingWindow/Capacitor'),
    229          'normalAttributes': [const.attributeCapacitorCapacity, const.attributeRechargeRate]}
    230         shipAttributes['navigation'] = {'groupName': GetByLabel('UI/Fitting/Navigation'),
    231          'derivedHeaderAttribute': {'name': 'Tooltips/FittingWindow/AlignTime',
    232                                     'format': 'UI/Fitting/FittingWindow/AlignTime',
    233                                     'tooltip': 'Tooltips/FittingWindow/AlignTime_description',
    234                                     'hint': '',
    235                                     'valueFunc': GetAlignTimeFromAgilityAndMass,
    236                                     'parameterAttributes': {'agility': const.attributeAgility,
    237                                                             'mass': const.attributeMass}},
    238          'normalAttributes': [const.attributeMaxVelocity,
    239                               const.attributeMass,
    240                               const.attributeAgility,
    241                               const.attributeBaseJumpBridgeCapacitorCost],
    242          'constructedAttributes': [(const.attributeBaseWarpSpeed, lambda typeID, itemID: sm.GetService('info').GetWarpSpeedData(typeID, itemID))]}
    243         shipAttributes['targeting'] = {'groupName': GetByLabel('UI/Fitting/FittingWindow/Targeting'),
    244          'normalAttributes': [const.attributeMaxTargetRange,
    245                               const.attributeMaxRange,
    246                               const.attributeMaxLockedTargets,
    247                               const.attributeSignatureRadius,
    248                               const.attributeOptimalSigRadius,
    249                               const.attributeScanResolution,
    250                               const.attributeScanLadarStrength,
    251                               const.attributeScanMagnetometricStrength,
    252                               const.attributeScanRadarStrength,
    253                               const.attributeScanGravimetricStrength,
    254                               const.attributeProximityRange,
    255                               const.attributeFalloff,
    256                               const.attributeTrackingSpeed,
    257                               const.attributeMaxDirectionalScanRange]}
    258         shipAttributes['drones'] = {'groupName': GetByLabel('UI/Drones/Drones'),
    259          'normalAttributes': [const.attributeDroneCapacity, const.attributeDroneBandwidth]}
    260         shipAttributes['inventory'] = {'groupName': GetByLabel('UI/Neocom/InventoryBtn'),
    261          'normalAttributes': [const.attributeVolume,
    262                               const.attributeCapacity,
    263                               const.attributeFrigateEscapeBayCapacity,
    264                               const.attributeSpecialAmmoHoldCapacity,
    265                               const.attributeSpecialGasHoldCapacity,
    266                               const.attributeSpecialIceHoldCapacity,
    267                               const.attributeSpecialIndustrialShipHoldCapacity,
    268                               const.attributeSpecialLargeShipHoldCapacity,
    269                               const.attributeSpecialMediumShipHoldCapacity,
    270                               const.attributeSpecialMineralHoldCapacity,
    271                               const.attributeGeneralMiningHoldCapacity,
    272                               const.attributeSpecialAsteroidHoldCapacity,
    273                               const.attributeSpecialSalvageHoldCapacity,
    274                               const.attributeSpecialShipHoldCapacity,
    275                               const.attributeSpecialSmallShipHoldCapacity,
    276                               const.attributeSpecialCommandCenterHoldCapacity,
    277                               const.attributeSpecialPlanetaryCommoditiesHoldCapacity,
    278                               const.attributeSpecialSubsystemHoldCapacity,
    279                               const.attributeSpecialCorpseHoldCapacity,
    280                               const.attributeSpecialBoosterHoldCapacity,
    281                               const.attributeSpecialMobileDepotHoldCapacity,
    282                               const.attributeSpecialColonyResourcesHoldCapacity,
    283                               const.attributeSpecialExpeditionHoldCapacity]}
    284         shipAttributes['ewar'] = {'groupName': GetByLabel('UI/Common/EWarResistances'),
    285          'normalAttributes': [const.attributeECMResistance,
    286                               const.attributeRemoteAssistanceImpedance,
    287                               const.attributeRemoteRepairImpedance,
    288                               const.attributeEnergyWarfareResistance,
    289                               const.attributeSensorDampenerResistance,
    290                               const.attributeStasisWebifierResistance,
    291                               const.attributeTargetPainterResistance,
    292                               const.attributeWeaponDisruptionResistance]}
    293         shipAttributes['sharedFacilities'] = {'groupName': GetByLabel('UI/InfoWindow/SharedFacilities'),
    294          'normalAttributes': [const.attributeFleetHangarCapacity,
    295                               const.attributeShipMaintenanceBayCapacity,
    296                               const.attributeMaxJumpClones,
    297                               const.attributeReclonerFuelType]}
    298         shipAttributes['fighterFacilities'] = {'groupName': GetByLabel('UI/InfoWindow/FighterFacilities'),
    299          'normalAttributes': [const.attributeFighterCapacity,
    300                               const.attributeFighterTubes,
    301                               const.attributeFighterLightSlots,
    302                               const.attributeFighterSupportSlots,
    303                               const.attributeFighterHeavySlots,
    304                               const.attributeFighterStandupLightSlots,
    305                               const.attributeFighterStandupSupportSlots,
    306                               const.attributeFighterStandupHeavySlots]}
    307         shipAttributes['onDeath'] = {'groupName': GetByLabel('UI/InfoWindow/OnDeath'),
    308          'normalAttributes': [const.attributeOnDeathAOERadius,
    309                               const.attributeOnDeathSignatureRadius,
    310                               const.attributeOnDeathDamageEM,
    311                               const.attributeOnDeathDamageTherm,
    312                               const.attributeOnDeathDamageKin,
    313                               const.attributeOnDeathDamageExp]}
    314         shipAttributes['jumpDrive'] = {'groupName': GetByLabel('UI/InfoWindow/JumpDriveSystems'),
    315          'normalAttributes': [const.attributeJumpDriveCapacitorNeed,
    316                               const.attributeJumpDriveRange,
    317                               const.attributeJumpDriveConsumptionType,
    318                               const.attributeJumpDriveConsumptionAmount,
    319                               const.attributeJumpDriveDuration,
    320                               const.attributeJumpPortalCapacitorNeed,
    321                               const.attributeJumpPortalConsumptionMassFactor,
    322                               const.attributeJumpPortalDuration,
    323                               const.attributeSpecialFuelBayCapacity,
    324                               const.attributeGroupJumpDriveConsumptionAmount,
    325                               const.attributeConduitJumpPassengerCount]}
    326         return shipAttributes
    327 
    328 
    329 class CollapsibleGroupWithHeaderAttribute(CollapsibleGroup):
    330 
    331     def ApplyAttributes(self, attributes):
    332         self.headerAttributeLabel = attributes.get('headerAttributeLabel', None)
    333         self.headerAttributeTooltip = attributes.get('headerAttributeTooltip', None)
    334         self.headerAttributeValue = attributes.get('headerAttributeValue', None)
    335         self.headerAttributeFormat = attributes.get('headerAttributeFormat', None)
    336         super(CollapsibleGroupWithHeaderAttribute, self).ApplyAttributes(attributes)
    337 
    338     def _construct_label(self):
    339         super(CollapsibleGroupWithHeaderAttribute, self)._construct_label()
    340         if not self.headerAttributeLabel:
    341             return
    342         headerAttributeCont = ContainerAutoSize(name='headerAttribContainer', parent=self.headerLabelWrapper, align=Align.TOLEFT, state=uiconst.UI_NORMAL, padLeft=8, hint=GetByLabel(self.headerAttributeTooltip))
    343         headerAttributeCont.OnClick = self.headerCont.OnClick
    344         headerAttributeLabel = TextBody(parent=headerAttributeCont, align=Align.CENTERLEFT, state=uiconst.UI_DISABLED, color=TextColor.SECONDARY, text=u'{}:'.format(GetByLabel(self.headerAttributeLabel)))
    345         headerValueLabel = TextBody(parent=headerAttributeCont, align=Align.CENTERLEFT, state=uiconst.UI_DISABLED, padLeft=headerAttributeLabel.width + 4, text=GetByLabel(self.headerAttributeFormat, value=self.headerAttributeValue))
    346 
    347 
    348 class ListEntryAttributeGroup(ContainerAutoSize):
    349 
    350     def ApplyAttributes(self, attributes):
    351         self.default_state = uiconst.UI_NORMAL
    352         self.default_align = Align.TOTOP
    353         self.default_padBottom = 2
    354         self._hiliteFill = None
    355         super(ListEntryAttributeGroup, self).ApplyAttributes(attributes)
    356         self.itemID = attributes.itemID
    357         self.attributeValues = attributes.attributeValues
    358         self.modifiedAttributesDict = attributes.modifiedAttributesDict
    359         self.labelCont = ContainerAutoSize(name='labelCont', parent=self, align=Align.TOTOP, padTop=8, padLeft=8)
    360         self.label = TextBody(parent=self.labelCont, text=GetByLabel(attributes.labelPath))
    361         self.valueContainer = AttributeValueRowContainer(parent=self, align=Align.TOTOP, padding=(2, 2, 0, 2), doWidthAdjustments=True, loadOnStartup=False)
    362         self.valueContainer.Load(self.attributeValues, mouseExitFunc=self.OnMouseExit, modifiedAttributesDict=self.modifiedAttributesDict, itemID=self.itemID)
    363 
    364     def ConstructHiliteFill(self):
    365         if not self._hiliteFill:
    366             self._hiliteFill = ListEntryUnderlay(name='selectionHighlight', bgParent=self)
    367 
    368     def ShowHilite(self, animate = True):
    369         self.ConstructHiliteFill()
    370         self._hiliteFill.set_hovered(True, animate)
    371 
    372     def HideHilite(self, animate = True):
    373         if self._hiliteFill:
    374             self._hiliteFill.set_hovered(False, animate)
    375 
    376     def OnMouseEnter(self, *args):
    377         self.ShowHilite()
    378 
    379     def OnMouseExit(self, *args):
    380         self.HideHilite()