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

planetEditModeContainer.py (22445B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\planet\planetEditModeContainer.py
      2 import blue
      3 import eveicon
      4 import evetypes
      5 import inventorycommon
      6 import localization
      7 from bannedwords.client import bannedwords
      8 from carbon.client.script.environment.AudioUtil import PlaySound
      9 from carbon.common.lib.const import ixLocationID
     10 from carbon.common.script.util.format import FmtDate
     11 from carbonui import uiconst, Align
     12 from carbonui.button.group import ButtonGroup
     13 from carbonui.primitives.container import Container
     14 from carbonui.primitives.containerAutoSize import ContainerAutoSize
     15 from carbonui.uianimations import animations
     16 from carbonui.uicore import uicore
     17 from dogma.const import attributePlanetRestriction
     18 from eve.client.script.ui.control.eveLabel import EveLabelMedium
     19 from eve.client.script.ui.control.eveWindowUnderlay import ListEntryUnderlay
     20 from eve.client.script.ui.control.glowSprite import GlowSprite
     21 from player_messaging.client.ui_message import message_player, prompt_player
     22 from eve.client.script.ui.shared.planet import planetConst
     23 from eve.client.script.ui.shared.planet.colonyTemplateWindow import ColonyTemplateWindow
     24 from eve.client.script.ui.shared.planet.planetUtil import iconsByGroupID, IsSerenity
     25 from eve.client.script.ui.shared.planet.templatePreviewWindow import TemplatePreviewWindow
     26 from eve.client.script.ui.shared.planet.templateSavingUtil import ConfirmExportWnd, SaveToLocalFile
     27 from eveplanet.client.templates.templateConst import TemplatePinDataDictKeys, TemplateLinkDataDictKeys, TemplateRouteDataDictKeys, TemplateDictKeys
     28 from eve.common.script.planet.planetUtil import CMDCTRSTRING
     29 from eve.common.lib import appConst
     30 from eve.common.script.sys.eveCfg import InShipInSpace
     31 from eve.common.script.util.eveFormat import FmtISK
     32 from localization import GetByLabel
     33 try:
     34     import json
     35 except ImportError:
     36     import simplejson as json
     37 
     38 ICON_SIZE = 24
     39 TYPE_PLACELINK = -1
     40 TYPE_DECOMMISSION = -3
     41 tooltipByGroupID = {appConst.groupExtractionControlUnitPins: GetByLabel('UI/PI/BuildTooltips/ECU'),
     42  appConst.groupProcessPins: GetByLabel('UI/PI/BuildTooltips/ProcessorCommonText'),
     43  appConst.groupStoragePins: GetByLabel('UI/PI/BuildTooltips/Storage'),
     44  appConst.groupSpaceportPins: GetByLabel('UI/PI/BuildTooltips/Launchpad'),
     45  appConst.groupPlanetaryLinks: GetByLabel('UI/PI/BuildTooltips/Link'),
     46  appConst.groupCommandPins: GetByLabel('UI/PI/BuildTooltips/CommandCenter')}
     47 
     48 class PlanetEditModeContainer(ContainerAutoSize):
     49     default_name = 'planetEditMode'
     50     default_align = uiconst.TOTOP
     51     default_state = uiconst.UI_HIDDEN
     52     __notifyevents__ = ['OnEditModeChanged',
     53      'OnEditModeBuiltOrDestroyed',
     54      'OnPlanetCommandCenterDeployedOrRemoved',
     55      'OnItemChange',
     56      'OnSessionChanged',
     57      'OnPlanetUIStateChanged']
     58     COLOR_ENABLED = (1.0, 1.0, 1.0, 1.0)
     59     COLOR_DISABLED = (0.7, 0.7, 0.7, 0.8)
     60 
     61     def ApplyAttributes(self, attributes):
     62         ContainerAutoSize.ApplyAttributes(self, attributes)
     63         self.activeBuildEntry = None
     64         self.entriesByTypeID = {}
     65         self.exportClipboardBtn = None
     66         self.exportFileBtn = None
     67         self.buildContainer = ContainerAutoSize(parent=self, name='buildContainer', align=uiconst.TOTOP)
     68         self.CreateLayout()
     69         sm.RegisterNotify(self)
     70 
     71     def CreateLayout(self):
     72         isCommandCenterPresent = self.IsCommandCenterPresent()
     73         groupIDs = self._GetPinGroupIDs(isCommandCenterPresent)
     74         for groupID in groupIDs:
     75             typeIDs = self.GetStructuresForGroup(groupID)
     76             for typeID in typeIDs:
     77                 self._ConstructPlacePinEntry(groupID, typeID)
     78 
     79         if isCommandCenterPresent:
     80             self._ConstructToolEntries()
     81         self._ConstructTemplateButtons()
     82 
     83     def _GetPinGroupIDs(self, isCommandCenterPresent):
     84         if isCommandCenterPresent:
     85             return [appConst.groupExtractionControlUnitPins,
     86              appConst.groupProcessPins,
     87              appConst.groupStoragePins,
     88              appConst.groupSpaceportPins]
     89         else:
     90             return [appConst.groupCommandPins]
     91 
     92     def _ConstructToolEntries(self):
     93         self.entriesByTypeID[TYPE_PLACELINK] = PlaceLinkEntry(parent=self.buildContainer, padTop=8)
     94         self.entriesByTypeID[TYPE_DECOMMISSION] = DecommissionEntry(parent=self.buildContainer)
     95 
     96     def _ConstructTemplateButtons(self):
     97         self.templateButtonGroup = ButtonGroup(parent=self.buildContainer, align=Align.TOTOP, orientation=uiconst.VERTICAL, top=8)
     98         if self.IsCommandCenterPresent():
     99             self.exportFileBtn = self.templateButtonGroup.AddButton(label=GetByLabel('UI/PI/ExportToFile'), func=lambda *args: self.SaveTemplateToFile(), texturePath=eveicon.export)
    100         self.templateButtonGroup.AddButton(label=GetByLabel('UI/PI/ShowTemplateWindow'), func=self.ShowTemplateWindow, texturePath=eveicon.open_window)
    101 
    102     def UpdateButtons(self, inEditMode):
    103         if self.exportClipboardBtn is not None:
    104             if inEditMode:
    105                 self.exportClipboardBtn.Disable()
    106             else:
    107                 self.exportClipboardBtn.Enable()
    108         if self.exportFileBtn is not None:
    109             if inEditMode:
    110                 self.exportFileBtn.Disable()
    111             else:
    112                 self.exportFileBtn.Enable()
    113 
    114     def _ConstructPlacePinEntry(self, groupID, typeID):
    115         isDisabledHint = self.GetBuildEntryDisabledHint(groupID, typeID)
    116         entry = PlacePinEntry(parent=self.buildContainer, typeID=typeID, isDisabledHint=isDisabledHint)
    117         self.entriesByTypeID[typeID] = entry
    118 
    119     def IsCommandCenterPresent(self):
    120         commandPinObject = sm.GetService('planetUI').GetCurrentPlanet().GetCommandCenterForCharacter(session.charid)
    121         isCommandCenterPresent = commandPinObject is not None and not commandPinObject.IsInEditMode()
    122         return isCommandCenterPresent
    123 
    124     def GetStructuresForGroup(self, groupID):
    125         planetTypeID = sm.GetService('planetUI').typeID
    126         godma = sm.GetService('godma')
    127         structureIDs = set()
    128         for typeID in evetypes.GetTypeIDsByGroup(groupID):
    129             typeRestriction = godma.GetTypeAttribute(typeID, attributePlanetRestriction)
    130             if typeRestriction and int(typeRestriction) != planetTypeID:
    131                 continue
    132             if not evetypes.IsPublished(typeID):
    133                 continue
    134             structureIDs.add(typeID)
    135 
    136         return sorted(structureIDs, key=evetypes.GetBasePrice)
    137 
    138     def GetBuildEntryDisabledHint(self, groupID, typeID):
    139         if groupID == appConst.groupCommandPins:
    140             planetID = sm.GetService('planetUI').planetID
    141             planetSolarSystemID = sm.GetService('map').GetPlanetInfo(planetID).solarSystemID
    142             if not InShipInSpace() or session.solarsystemid != planetSolarSystemID:
    143                 return localization.GetByLabel('UI/PI/Common/CannotBuildLocation')
    144             planetRows = sm.GetService('planetSvc').GetMyPlanets()
    145             skillSvc = sm.GetService('skills')
    146             if len(planetRows) > 0:
    147                 interplanetaryConsolidationSkillLevel = skillSvc.GetEffectiveLevel(appConst.typeInterplanetaryConsolidation) or 0
    148                 if interplanetaryConsolidationSkillLevel < len(planetRows):
    149                     if interplanetaryConsolidationSkillLevel < 5:
    150                         hint = localization.GetByLabel('UI/PI/Common/CannotBuildMaxColoniesTrain', skillName=evetypes.GetName(appConst.typeInterplanetaryConsolidation))
    151                     else:
    152                         hint = localization.GetByLabel('UI/PI/Common/CannotBuildMaxColonies')
    153                     return hint
    154             skillsRequired = skillSvc.GetRequiredSkills(typeID)
    155             for skillTypeID, requiredLevel in skillsRequired.iteritems():
    156                 myLevel = skillSvc.GetEffectiveLevel(skillTypeID) or 0
    157                 if myLevel < requiredLevel:
    158                     hint = localization.GetByLabel('UI/PI/Common/CannotBuildSkillNeeded', skillName=evetypes.GetName(skillTypeID), skillLevel=int(requiredLevel))
    159                     return hint
    160 
    161             if session.shipid is None:
    162                 hint = localization.GetByLabel('UI/PI/Common/CannotBuildNoCommandCenter', typeName=evetypes.GetName(typeID))
    163                 return hint
    164             inv = sm.GetService('invCache').GetInventoryFromId(session.shipid)
    165             commandCenterID = None
    166             if inv:
    167                 invList = inv.List(inventorycommon.const.flagSpecializedCommandCenterHold)
    168                 invList.extend(inv.List(inventorycommon.const.flagCargo))
    169                 invList.extend(inv.List(inventorycommon.const.flagColonyResourcesHold))
    170                 for item in invList:
    171                     if item.typeID == typeID:
    172                         commandCenterID = item.itemID
    173                         break
    174 
    175             if commandCenterID is None:
    176                 hint = localization.GetByLabel('UI/PI/Common/CannotBuildNoCommandCenter', typeName=evetypes.GetName(typeID))
    177                 return hint
    178 
    179     def OnPlanetCommandCenterDeployedOrRemoved(self):
    180         self.ResetBuildbuttons()
    181 
    182     def OnPlanetUIStateChanged(self, state, oldState):
    183         typeID = self._GetTypeIDByState(state)
    184         for _typeID, entry in self.entriesByTypeID.iteritems():
    185             if typeID == _typeID:
    186                 entry.Select()
    187             else:
    188                 entry.Deselect()
    189 
    190     def _GetTypeIDByState(self, state):
    191         if state == planetConst.STATE_BUILDPIN:
    192             return sm.GetService('planetUI').myPinManager.newPinType
    193         if state in (planetConst.STATE_CREATELINKSTART, planetConst.STATE_CREATELINKEND):
    194             return TYPE_PLACELINK
    195         if state == planetConst.STATE_DECOMMISSION:
    196             return TYPE_DECOMMISSION
    197 
    198     def OnItemChange(self, item, change, location):
    199         locationIdx = ixLocationID
    200         if session.shipid not in (item[locationIdx], change.get(locationIdx, 'No location change')):
    201             return
    202         if evetypes.GetGroupID(item.typeID) == appConst.groupCommandPins:
    203             self.ResetBuildbuttons()
    204 
    205     def ResetBuildbuttons(self):
    206         animations.FadeOut(self.buildContainer, duration=0.25, sleep=True)
    207         if not self or self.destroyed:
    208             return
    209         self.buildContainer.Flush()
    210         self.activeBuildEntry = None
    211         self.entriesByTypeID = {}
    212         self.CreateLayout()
    213         blue.pyos.synchro.SleepWallclock(300)
    214         if not self or self.destroyed:
    215             return
    216         animations.FadeIn(self.buildContainer, duration=0.25, sleep=True)
    217 
    218     def SaveTemplateToFile(self):
    219         jsonText = self._GetJsonInfoToStore('UI/PI/SaveNewTemplate', 'UI/PI/SaveTemplate')
    220         if jsonText is None:
    221             return
    222         self.ShowTemplateWindow()
    223         SaveToLocalFile(jsonText, encoding='unicode-escape')
    224 
    225     def CopyTemplateToClipboard(self):
    226         jsonText = self._GetJsonInfoToStore('UI/PI/CopyToClipboard', 'UI/PI/CopyToClipboard')
    227         if jsonText is None:
    228             return
    229         blue.pyos.SetClipboardData(jsonText)
    230         message_player(localization.GetByLabel('UI/PI/Copied'))
    231 
    232     def _GetJsonInfoToStore(self, captionPath, okPath):
    233         if not self.Verify_No_CmdCtr_Link():
    234             return
    235         if sm.GetService('planetUI').inEditMode:
    236             message_player(localization.GetByLabel('UI/PI/CannotExportWhileEditing'))
    237             return
    238         defaultNote = u'{0} {1}'.format(cfg.eveowners.Get(session.charid).name, FmtDate(blue.os.GetSimTime()))
    239         wnd = ConfirmExportWnd.Open(defaultNote=defaultNote, captionPath=captionPath, okPath=okPath)
    240         wnd.SetParent(uicore.layer.planet)
    241         wnd.ShowDialog(modal=True)
    242         retval = wnd.result
    243         if retval is None:
    244             return
    245         note = retval.get('note', '')
    246         bannedwords.check_words_allowed(note)
    247         if IsSerenity():
    248             retval.get('note', '')
    249             includeCmdCtr = retval.get('includeCmdCtr', False)
    250         else:
    251             includeCmdCtr = False
    252         planetID = sm.GetService('planetUI').planetID
    253         if not planetID:
    254             message_player(localization.GetByLabel('UI/PI/FailedTosave'))
    255             return
    256         planet = sm.GetService('planetSvc').GetClientPlanet(planetID)
    257         pins = planet.colony.colonyData.pins
    258         links = planet.colony.colonyData.links
    259         routes = planet.colony.colonyData.routes
    260         pinIDs = {}
    261         cmdCtrLvl = planet.colony.colonyData.level
    262         pinExtracted = []
    263         linkExtracted = []
    264         routeExtracted = []
    265         if includeCmdCtr:
    266             self.ExtractCmdCenterPin(pinExtracted, pinIDs, pins)
    267         self.ExtractNormalPins(pinExtracted, pinIDs, pins)
    268         for link in links.values():
    269             linkExtracted.append({TemplateLinkDataDictKeys.Source: pinIDs[link.endpoint1.id],
    270              TemplateLinkDataDictKeys.Destination: pinIDs[link.endpoint2.id],
    271              TemplateLinkDataDictKeys.Level: link.level})
    272 
    273         for route in routes.values():
    274             path = []
    275             for node in route.path:
    276                 path.append(pinIDs[node])
    277 
    278             routeExtracted.append({TemplateRouteDataDictKeys.Path: path,
    279              TemplateRouteDataDictKeys.ItemType: route.GetType(),
    280              TemplateRouteDataDictKeys.ItemQuantity: route.GetQuantity()})
    281 
    282         fullOutput = {TemplateDictKeys.Comments: note if note is not None else '',
    283          TemplateDictKeys.CmdCenterLV: cmdCtrLvl,
    284          TemplateDictKeys.PlanetType: planet.GetPlanetTypeID(),
    285          TemplateDictKeys.Diameter: planet.radius * 2 / 1000,
    286          TemplateDictKeys.PinData: pinExtracted,
    287          TemplateDictKeys.LinkData: linkExtracted,
    288          TemplateDictKeys.RouteData: routeExtracted}
    289         jsonText = json.dumps(obj=fullOutput, sort_keys=True).decode('unicode-escape')
    290         return jsonText
    291 
    292     def Verify_No_CmdCtr_Link(self):
    293         planet = sm.GetService('planetUI').GetCurrentPlanet()
    294         links = planet.colony.colonyData.links
    295         for link in links.itervalues():
    296             if link.endpoint1.id == planet.colony.colonyData.commandPin.id or link.endpoint2.id == planet.colony.colonyData.commandPin.id:
    297                 prompt_player(text=localization.GetByLabel('UI/PI/LinkWithCmdCtrNotAvailable'), options=uiconst.OK, icon=uiconst.INFO)
    298                 return False
    299 
    300         return True
    301 
    302     def ExtractNormalPins(self, pinExtracted, pinIDs, pins):
    303         anotherCounter = 1
    304         for pin in pins.itervalues():
    305             if pin.IsCommandCenter():
    306                 continue
    307             pinExtracted.append(self._GetPinInfo(pin))
    308             pinIDs[pin.id] = anotherCounter
    309             anotherCounter += 1
    310 
    311     def ExtractCmdCenterPin(self, pinExtracted, pinIDs, pins):
    312         for pin in pins.itervalues():
    313             if not pin.IsCommandCenter():
    314                 continue
    315             pinExtracted.append(self._GetPinInfo(pin))
    316             pinIDs[pin.id] = CMDCTRSTRING
    317             return
    318 
    319     def _GetPinInfo(self, pin):
    320         products = pin.GetProducts()
    321         pinInfo = {TemplatePinDataDictKeys.PinTypeID: pin.typeID,
    322          TemplatePinDataDictKeys.Lat: round(pin.latitude, 5),
    323          TemplatePinDataDictKeys.Longi: round(pin.longitude, 5),
    324          TemplatePinDataDictKeys.Product: products.keys()[0] if products else None,
    325          TemplatePinDataDictKeys.ExtractorHeadCount: pin.GetNumHeads() if pin.IsExtractor() else 0}
    326         return pinInfo
    327 
    328     def ShowTemplateWindow(self, *args):
    329         instance = ColonyTemplateWindow.GetIfOpen()
    330         if instance:
    331             instance.Close()
    332         wnd = TemplatePreviewWindow.GetIfOpen()
    333         if wnd:
    334             wnd.Close()
    335         ColonyTemplateWindow.Open(target=self)
    336 
    337     def OnSessionChanged(self, isRemote, sess, change):
    338         self.ResetBuildbuttons()
    339 
    340     def Close(self, *args):
    341         instance = ColonyTemplateWindow.GetIfOpen()
    342         if instance:
    343             instance.Close()
    344             ColonyTemplateWindow.Open(target=None)
    345         super(type(self), self).Close()
    346 
    347 
    348 class BaseEditModeEntry(Container):
    349     default_name = 'BaseEditModeEntry'
    350     default_align = uiconst.TOTOP
    351     default_state = uiconst.UI_NORMAL
    352     default_height = 24
    353 
    354     def ApplyAttributes(self, attributes):
    355         Container.ApplyAttributes(self, attributes)
    356         self.isDisabledHint = attributes.isDisabledHint
    357         self.isSelected = False
    358         self.isEnabled = True
    359         self.icon = GlowSprite(parent=self, align=uiconst.CENTERLEFT, pos=(0, 0, 22, 22), texturePath=self.GetTexturePath(), state=uiconst.UI_DISABLED)
    360         EveLabelMedium(parent=self, align=uiconst.CENTERLEFT, text=self.GetName(), state=uiconst.UI_DISABLED, left=26)
    361         self.hoverBG = ListEntryUnderlay(bgParent=self)
    362 
    363     def GetName(self):
    364         pass
    365 
    366     def OnClick(self, *args):
    367         PlaySound(uiconst.SOUND_ENTRY_SELECT)
    368         if self.isEnabled:
    369             self.ClickFunc()
    370 
    371     def ClickFunc(self):
    372         pass
    373 
    374     def GetTexturePath(self):
    375         pass
    376 
    377     def OnMouseEnter(self, *args):
    378         if self.isEnabled:
    379             self.hoverBG.hovered = True
    380             if not self.isSelected:
    381                 PlaySound(uiconst.SOUND_ENTRY_HOVER)
    382                 self.icon.OnMouseEnter()
    383 
    384     def OnMouseExit(self, *args):
    385         self.hoverBG.hovered = False
    386         if not self.isSelected:
    387             self.icon.OnMouseExit()
    388 
    389     def Select(self):
    390         self.isSelected = True
    391         self.hoverBG.Select()
    392         self.icon.OnMouseEnter()
    393 
    394     def Deselect(self):
    395         if self.isSelected:
    396             self.isSelected = False
    397             self.hoverBG.Deselect()
    398             self.icon.OnMouseExit()
    399 
    400     def LoadTooltipPanel(self, tooltipPanel, *args):
    401         tooltipPanel.LoadGeneric2ColumnTemplate()
    402         tooltipPanel.AddLabelMedium(text=self.GetTooltipText(), wrapWidth=250, colSpan=2)
    403 
    404     def GetTooltipPointer(self):
    405         return uiconst.POINT_LEFT_2
    406 
    407     def GetTooltipText(self):
    408         return ''
    409 
    410 
    411 class PlacePinEntry(BaseEditModeEntry):
    412     default_name = 'PlacePinEntry'
    413 
    414     def ApplyAttributes(self, attributes):
    415         self.typeID = attributes.typeID
    416         BaseEditModeEntry.ApplyAttributes(self, attributes)
    417 
    418     def GetName(self):
    419         return evetypes.GetName(self.typeID)
    420 
    421     def ClickFunc(self, *args):
    422         sm.GetService('planetUI').myPinManager.PlacePinOnNextClick(self.typeID)
    423 
    424     def GetTexturePath(self):
    425         if self.typeID in planetConst.TYPEIDS_PROCESSORS_ADVANCED:
    426             return 'res:/UI/Texture/Planet/icons/processorAdvanced.png'
    427         elif self.typeID in planetConst.TYPEIDS_PROCESSORS_HIGHTECH:
    428             return 'res:/UI/Texture/Planet/icons/processorHighTech.png'
    429         else:
    430             groupID = self.GetGroupID()
    431             return iconsByGroupID[groupID]
    432 
    433     def GetGroupID(self):
    434         return evetypes.GetGroupID(self.typeID)
    435 
    436     def GetTooltipText(self):
    437         hint = tooltipByGroupID[self.GetGroupID()]
    438         if self.typeID in planetConst.TYPEIDS_PROCESSORS_BASIC:
    439             hint += '\n\n' + GetByLabel('UI/PI/BuildTooltips/BasicProcessor')
    440         elif self.typeID in planetConst.TYPEIDS_PROCESSORS_ADVANCED:
    441             hint += '\n\n' + GetByLabel('UI/PI/BuildTooltips/AdvancedProcessor')
    442         elif self.typeID in planetConst.TYPEIDS_PROCESSORS_HIGHTECH:
    443             hint += '\n\n' + GetByLabel('UI/PI/BuildTooltips/HighTechProcessor')
    444         if self.isDisabledHint:
    445             hint += '\n\n<color=red>%s</color>' % self.isDisabledHint
    446         return hint
    447 
    448     def GetMenu(self, *args):
    449         includeMarketDetails = self.GetGroupID() == appConst.groupCommandPins
    450         return sm.GetService('menu').GetMenuFromItemIDTypeID(None, self.typeID, includeMarketDetails=includeMarketDetails)
    451 
    452     def LoadTooltipPanel(self, tooltipPanel, *args):
    453         BaseEditModeEntry.LoadTooltipPanel(self, tooltipPanel, *args)
    454         buildCost = self.GetBuildCost()
    455         if buildCost:
    456             iskPrice = FmtISK(buildCost, showFractionsAlways=False)
    457             label = GetByLabel('UI/PI/Common/BuildCost')
    458             tooltipPanel.AddLabelMedium(text='%s: <b>%s</b>' % (label, iskPrice), colSpan=2, cellPadding=(0, 12, 0, 0))
    459         powerUsage = self.GetPowerUsage()
    460         if powerUsage:
    461             powerTxt = GetByLabel('UI/PI/Common/MegaWattsAmount', amount=int(powerUsage))
    462             powerUsedTxt = GetByLabel('UI/PI/Common/PowerUsage')
    463             tooltipPanel.AddLabelMedium(text='%s: <b>%s</b>' % (powerUsedTxt, powerTxt), colSpan=2, cellPadding=(0, 12, 0, 0))
    464         cpuUsage = self.GetCpuUsage()
    465         if cpuUsage:
    466             cpuTxt = GetByLabel('UI/PI/Common/TeraFlopsAmount', amount=int(cpuUsage))
    467             cpuUsedTxt = GetByLabel('UI/PI/Common/CpuUsage')
    468             tooltipPanel.AddLabelMedium(text='%s: <b>%s</b>' % (cpuUsedTxt, cpuTxt), colSpan=2)
    469 
    470     def GetBuildCost(self):
    471         if self.GetGroupID() == appConst.groupCommandPins:
    472             return None
    473         else:
    474             return evetypes.GetBasePrice(self.typeID)
    475 
    476     def GetPowerUsage(self):
    477         return sm.GetService('godma').GetTypeAttribute(self.typeID, appConst.attributePowerLoad)
    478 
    479     def GetCpuUsage(self):
    480         return sm.GetService('godma').GetTypeAttribute(self.typeID, appConst.attributeCpuLoad)
    481 
    482 
    483 class PlaceLinkEntry(BaseEditModeEntry):
    484     default_name = 'PlaceLinkEntry'
    485 
    486     def GetName(self):
    487         return localization.GetByLabel('UI/PI/Common/CreateLink')
    488 
    489     def ClickFunc(self, *args):
    490         sm.GetService('planetUI').eventManager.SetStateCreateLinkStart()
    491 
    492     def GetTexturePath(self):
    493         return 'res:/UI/Texture/Planet/icons/link.png'
    494 
    495     def GetTooltipText(self):
    496         return GetByLabel('UI/PI/BuildTooltips/Link')
    497 
    498     def LoadTooltipPanel(self, tooltipPanel, *args):
    499         BaseEditModeEntry.LoadTooltipPanel(self, tooltipPanel)
    500         tooltipPanel.AddSpacer(height=10)
    501         tooltipPanel.AddLabelShortcut(GetByLabel('UI/PI/Common/CreateLink'), GetByLabel('UI/PI/Common/CreateLinkShortcut'))
    502 
    503 
    504 class DecommissionEntry(BaseEditModeEntry):
    505     default_name = 'DecommissionEntry'
    506 
    507     def GetName(self):
    508         return localization.GetByLabel('UI/PI/Common/Decommission')
    509 
    510     def ClickFunc(self, *args):
    511         sm.GetService('planetUI').eventManager.SetStateDecommission()
    512 
    513     def GetTexturePath(self):
    514         return 'res:/UI/Texture/Planet/icons/decommission.png'
    515 
    516     def GetTooltipText(self):
    517         return GetByLabel('UI/PI/BuildTooltips/Decommission')