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

base.py (23556B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\station\base.py
      2 import sys
      3 import blue
      4 import evetypes
      5 import localization
      6 import log
      7 import uthread
      8 from carbon.common.script.sys import service
      9 from carbon.common.script.sys.row import Row
     10 from carbonui import uiconst
     11 from carbonui.button.group import ButtonGroup
     12 from carbonui.control.layer import LayerCore
     13 from carbonui.window.underlay import WindowUnderlay
     14 from carbonui.primitives.container import Container
     15 from carbonui.primitives.line import Line
     16 from carbonui.primitives.sprite import Sprite
     17 from carbonui.uianimations import animations
     18 from carbonui.uicore import uicore
     19 from eve.client.script.environment.model import turretSet
     20 from eve.client.script.ui.control import eveIcon, eveLabel
     21 from eve.client.script.ui.shared.dockedUI import ReloadLobbyWnd
     22 from eve.client.script.ui.shared.dockedUI.lobbyWnd import LobbyWnd
     23 from eve.client.script.ui.shared.skillRequirementDialog import prompt_missing_skill_requirements
     24 from eve.client.script.ui.station import stationServiceConst
     25 from eve.client.script.ui.util import uix
     26 from eve.common.lib.appConst import CLONE_STATION_SERVICES
     27 from eve.common.script.sys import eveCfg, idCheckers
     28 from eve.common.script.sys.eveCfg import IsControllingStructure
     29 from eve.common.script.sys.idCheckers import IsCapsule, IsNewbieShip
     30 from eve.common.script.util.structuresCommon import IsStationServiceAvailable
     31 from eveSpaceObject import spaceobjanimation
     32 from fsdBuiltData.common.graphicIDs import GetSofFactionName
     33 from player_messaging.client.ui_message import prompt_player_fsd_dialog
     34 from reprocessing.ui.reprocessingWnd import ReprocessingWnd
     35 
     36 class StationSvc(service.Service):
     37     __guid__ = 'svc.station'
     38     __update_on_reload__ = 0
     39     __exportedcalls__ = {'GetGuests': [],
     40      'IsGuest': [],
     41      'Setup': [],
     42      'GetSvc': [],
     43      'LoadSvc': [],
     44      'GiveHint': [],
     45      'ClearHint': [],
     46      'StopAllStationServices': [],
     47      'CleanUp': [],
     48      'SelectShipDlg': [],
     49      'GetServiceState': [],
     50      'GetStationItem': []}
     51     __dependencies__ = ['journal', 'insurance', 'crimewatchSvc']
     52     __notifyevents__ = ['OnCharNowInStation',
     53      'OnCharNoLongerInStation',
     54      'OnDogmaItemChange',
     55      'OnCharacterHandler',
     56      'OnDogmaAttributeChanged',
     57      'OnCharacterSelected',
     58      'OnSessionChanged',
     59      'OnActiveShipModelChange',
     60      'OnStanceActive',
     61      'ProcessSessionChange',
     62      'OnSessionReset']
     63 
     64     def __init__(self):
     65         super(StationSvc, self).__init__()
     66         self.guests = {}
     67 
     68     @property
     69     def stationItem(self):
     70         return self.GetStationItem()
     71 
     72     def OnCharacterSelected(self):
     73         self._stationItem = None
     74         self.CleanUp(clearGuestList=True)
     75 
     76     def OnSessionReset(self):
     77         self.CleanUp(clearGuestList=True)
     78 
     79     def OnSessionChanged(self, isRemote, session, change):
     80         if 'locationid' in change:
     81             oldLocation, newLocation = change['locationid']
     82             if idCheckers.IsStation(oldLocation):
     83                 self.CleanUp(clearGuestList=True)
     84 
     85     def ProcessSessionChange(self, isRemote, session, change):
     86         if 'stationid' in change or 'structureid' in change:
     87             self.ClearStationItem()
     88 
     89     def OnCharNowInStation(self, rec):
     90         charID, corpID, allianceID, warFactionID = rec
     91         if charID not in self.guests:
     92             self.guests[charID] = (corpID, allianceID, warFactionID)
     93 
     94     def OnCharNoLongerInStation(self, rec):
     95         charID, corpID, allianceID, factionID = rec
     96         if charID in self.guests:
     97             self.guests.pop(charID)
     98 
     99     def GetGuests(self):
    100         currentStationID = session.stationid
    101         if not self.guestListReceived or self.guestListReceived != currentStationID:
    102             self.guests.clear()
    103             guests = sm.RemoteSvc('station').GetGuests()
    104             for charID, corpID, allianceID, warFactionID in guests:
    105                 self.guests[charID] = (corpID, allianceID, warFactionID)
    106 
    107             self.guestListReceived = currentStationID
    108         return self.guests
    109 
    110     def IsGuest(self, whoID):
    111         if len(self.guests) == 0:
    112             self.GetGuests()
    113         return whoID in self.guests
    114 
    115     def Stop(self, memStream = None):
    116         self.LogInfo('Stopping Station Service')
    117         self.CleanUp(clearGuestList=True)
    118 
    119     def GetServiceDisplayName(self, service):
    120         s = self.GetStationServiceData(service)
    121         if s:
    122             return s.label
    123         return localization.GetByLabel('UI/Common/Unknown')
    124 
    125     def GetStationServiceData(self, serviceName):
    126         return stationServiceConst.serviceDataByNameID.get(serviceName, None)
    127 
    128     def IsCloneServiceAvailable(self):
    129         for stationServiceID in CLONE_STATION_SERVICES:
    130             if self.IsStationServiceAvailable(stationServiceID):
    131                 return True
    132 
    133         return False
    134 
    135     def IsStationServiceAvailable(self, stationServiceID):
    136         return IsStationServiceAvailable(session.solarsystemid2, self.stationItem, stationServiceID)
    137 
    138     def CleanUp(self, storeCamera = 1, clearGuestList = False):
    139         try:
    140             if getattr(self, 'underlay', None):
    141                 uicore.registry.UnregisterWindow(self.underlay)
    142                 self.underlay.OnClick = None
    143                 self.underlay.Minimize = None
    144                 self.underlay.Maximize = None
    145         except:
    146             pass
    147 
    148         uix.Close(self, ['closeBtn',
    149          'hint',
    150          'underlay',
    151          'lobby'])
    152         self.lobby = None
    153         self.underlay = None
    154         self.closeBtn = None
    155         self.hint = None
    156         self.selected_service = None
    157         self.loading = None
    158         self.active_service = None
    159         self.refreshingfitting = False
    160         self.activeShipItem = None
    161         self.activeShipTypeID = None
    162         self.activeshipmodel = None
    163         self.loadingSvc = 0
    164         self.activatingShip = 0
    165         self.leavingShip = 0
    166         self.paperdollState = None
    167         self.station = None
    168         if clearGuestList:
    169             self.guests = {}
    170             self.guestListReceived = None
    171 
    172     def StopAllStationServices(self):
    173         for serviceData in stationServiceConst.serviceData:
    174             if sm.IsServiceRunning(serviceData.name):
    175                 sm.services[serviceData.name].Stop()
    176 
    177     def Setup(self, reloading = 0):
    178         self.CleanUp(0)
    179         self.loading = 1
    180         if not reloading:
    181             prompt_player_fsd_dialog('OnEnterStation')
    182         if self.station is None and session.stationid:
    183             self.station = sm.GetService('ui').GetStation(session.stationid)
    184         sm.GetService('autoPilot').SetOff('toggled by Station Entry')
    185         if sm.GetService('viewState').IsViewActive('starmap', 'systemmap'):
    186             sm.StartService('map').MinimizeWindows()
    187         if sm.GetService('viewState').IsViewActive('planet'):
    188             sm.GetService('planetUI').MinimizeWindows()
    189         self.loading = 0
    190         self.sprite = None
    191 
    192     def GetPaperdollStateCache(self):
    193         if self.paperdollState is None:
    194             self.paperdollState = sm.RemoteSvc('charMgr').GetPaperdollState()
    195         return self.paperdollState
    196 
    197     def OnCharacterHandler(self):
    198         self.ClearPaperdollStateCache()
    199 
    200     def ClearPaperdollStateCache(self):
    201         self.paperdollState = None
    202 
    203     def BlinkButton(self, what):
    204         lobby = LobbyWnd.GetIfOpen()
    205         if lobby:
    206             lobby.BlinkButton(what)
    207 
    208     def TryActivateShip(self, invitem, onSessionChanged = 0, secondTry = 0):
    209         shipid = invitem.itemID
    210         dogmaLocation = sm.GetService('clientDogmaIM').GetDogmaLocation()
    211         if shipid == dogmaLocation.GetCurrentShipID():
    212             return
    213         if self.activatingShip or IsControllingStructure():
    214             return
    215         if len(dogmaLocation.GetMissingSkills(invitem.typeID)) > 0:
    216             prompt_missing_skill_requirements(invitem.typeID)
    217             return
    218         sm.GetService('invCache').TryLockItem(shipid, 'lockItemActivating', {'itemType': invitem.typeID}, 1)
    219         self.activatingShip = 1
    220         try:
    221             dogmaLocation = sm.GetService('clientDogmaIM').GetDogmaLocation()
    222             dogmaLocation.MakeShipActive(shipid)
    223             self.activeShipItem = invitem
    224             sm.GetService('fleet').UpdateFleetInfo()
    225         finally:
    226             self.activatingShip = 0
    227             sm.GetService('invCache').UnlockItem(shipid)
    228 
    229     def TryLeaveShip(self, invitem, onSessionChanged = 0, secondTry = 0):
    230         shipid = invitem.itemID
    231         dogmaLocation = sm.GetService('clientDogmaIM').GetDogmaLocation()
    232         if shipid != dogmaLocation.GetCurrentShipID():
    233             return
    234         if self.leavingShip:
    235             return
    236         sm.GetService('invCache').TryLockItem(shipid, 'lockItemLeavingShip', {'itemType': invitem.typeID}, 1)
    237         self.leavingShip = 1
    238         try:
    239             shipsvc = sm.GetService('gameui').GetShipAccess()
    240             shipsvc.LeaveShip(shipid)
    241         finally:
    242             self.leavingShip = 0
    243             sm.GetService('invCache').UnlockItem(shipid)
    244 
    245     def OnDogmaItemChange(self, item, change):
    246         if session.stationid is None:
    247             return
    248         if item.groupID in const.turretModuleGroups:
    249             self.FitHardpoints()
    250 
    251     def OnActiveShipModelChange(self, model, shipItem):
    252         self.activeshipmodel = model
    253         self.activeShipTypeID = shipItem.typeID
    254         self.FitHardpoints()
    255 
    256     def OnStanceActive(self, shipID, stanceID):
    257         if eveCfg.GetActiveShip() == shipID:
    258             if self.activeshipmodel is not None:
    259                 spaceobjanimation.SetShipAnimationStance(self.activeshipmodel, stanceID)
    260 
    261     def FitHardpoints(self):
    262         if not self.activeshipmodel or self.activeShipTypeID is None or self.refreshingfitting:
    263             return
    264         self.refreshingfitting = True
    265         activeShip = eveCfg.GetActiveShip()
    266         sofFactionName = GetSofFactionName(evetypes.GetGraphicID(self.activeShipTypeID))
    267         turretSet.TurretSet.FitTurrets(activeShip, self.activeshipmodel, sofFactionName)
    268         self.refreshingfitting = False
    269 
    270     def GetUnderlay(self):
    271         if self.underlay is None:
    272             for each in uicore.layer.main.children[:]:
    273                 if each is not None and not each.destroyed and each.name == 'services':
    274                     uicore.registry.UnregisterWindow(each)
    275                     each.OnClick = None
    276                     each.Minimize = None
    277                     each.Maximize = None
    278                     each.Close()
    279 
    280             self.underlay = Sprite(name='services', parent=uicore.layer.main, align=uiconst.TOTOP, state=uiconst.UI_HIDDEN)
    281             self.underlay.scope = uiconst.SCOPE_STATION
    282             self.underlay.minimized = 0
    283             self.underlay.Minimize = self.MinimizeUnderlay
    284             self.underlay.Maximize = self.MaximizeUnderlay
    285             main = Container(name='mainparentXX', parent=self.underlay, align=uiconst.TOALL, pos=(0, 0, 0, 0))
    286             main.OnClick = self.ClickParent
    287             main.state = uiconst.UI_NORMAL
    288             sub = Container(name='subparent', parent=main, align=uiconst.TOALL, pos=(0, 0, 0, 0))
    289             captionparent = Container(name='captionparent', parent=main, align=uiconst.TOPLEFT, left=128, top=36, idx=0)
    290             caption = eveLabel.CaptionLabel(text='', parent=captionparent)
    291             self.closeBtn = ButtonGroup(btns=[[localization.GetByLabel('UI/Commands/CmdClose'),
    292               self.CloseSvc,
    293               None,
    294               81]], parent=sub)
    295             self.sr.underlay = WindowUnderlay(parent=main)
    296             self.sr.underlay.padding = (-1, -10, -1, 0)
    297             svcparent = Container(name='serviceparent', parent=sub, align=uiconst.TOALL, pos=(0, 0, 0, 0))
    298             self.underlay.sr.main = main
    299             self.underlay.sr.svcparent = svcparent
    300             self.underlay.sr.caption = caption
    301             uicore.registry.RegisterWindow(self.underlay)
    302         return self.underlay
    303 
    304     def MinimizeUnderlay(self, *args):
    305         self.underlay.state = uiconst.UI_HIDDEN
    306 
    307     def MaximizeUnderlay(self, *args):
    308         self.underlay.state = uiconst.UI_PICKCHILDREN
    309         self.ClickParent()
    310 
    311     def ClickParent(self, *args):
    312         for each in uicore.layer.main.children:
    313             if getattr(each, 'isDockWnd', 0) == 1 and each.state == uiconst.UI_NORMAL:
    314                 each.SetOrder(-1)
    315 
    316     def LoadSvc(self, service, close = 1):
    317         serviceInfo = self.GetStationServiceData(service)
    318         if service is not None and serviceInfo is not None:
    319             self.ExecuteCommand(serviceInfo.command)
    320             return
    321         if getattr(self, 'loadingSvc', 0):
    322             return
    323         self.loadingSvc = 1
    324         while self.loading:
    325             blue.pyos.synchro.SleepWallclock(500)
    326 
    327         if self.selected_service is None:
    328             if service:
    329                 self._LoadSvc(1, service)
    330         elif service == self.selected_service:
    331             if close:
    332                 self._LoadSvc(0)
    333         else:
    334             self._LoadSvc(0, service)
    335         self.loadingSvc = 0
    336 
    337     def ExecuteCommand(self, cmdstr):
    338         func = getattr(uicore.cmd, cmdstr, None)
    339         if func:
    340             func()
    341 
    342     def GetSvc(self, svcname = None):
    343         if self.active_service is not None:
    344             if svcname is not None:
    345                 if self.selected_service == svcname:
    346                     return self.active_service
    347             else:
    348                 return self.active_service
    349 
    350     def ReloadLobby(self):
    351         ReloadLobbyWnd()
    352 
    353     def _LoadSvc(self, inout, service = None):
    354         self.loading = 1
    355         wnd = self.GetUnderlay()
    356         newsvc = None
    357         if inout == 1 and wnd is not None:
    358             self.ClearHint()
    359             newsvc, svctype = self.SetupService(wnd, service)
    360         if wnd.absoluteRight - wnd.absoluteLeft < 700 and inout == 1:
    361             sm.GetService('neocom').Minimize()
    362         height = uicore.desktop.height - 180
    363         wnd.state = uiconst.UI_PICKCHILDREN
    364         if inout == 1:
    365             sm.GetService('neocom').SetLocationInfoState(0)
    366         topStart = -height if inout else height
    367         topEnd = 0 if inout else -height
    368         animations.MorphScalar(wnd, 'top', startVal=topStart, endVal=topEnd, duration=0.5)
    369         snd = service
    370         if inout == 0:
    371             snd = self.selected_service
    372         if snd is not None:
    373             prompt_player_fsd_dialog('LoadSvc_%s%s' % (snd, ['Out', 'In'][inout]))
    374         blue.pyos.synchro.SleepWallclock([750, 1250][inout])
    375         if inout == 0:
    376             sm.GetService('neocom').SetLocationInfoState(1)
    377         if newsvc is not None:
    378             if svctype == 'form':
    379                 newsvc.Startup(self)
    380             elif settings.user.ui.Get('nottry', 0):
    381                 newsvc.Initialize(wnd.sr.svcparent)
    382             else:
    383                 try:
    384                     newsvc.Initialize(wnd.sr.svcparent)
    385                 except:
    386                     log.LogException(channel=self.__guid__)
    387                     sys.exc_clear()
    388 
    389             self.active_service = newsvc
    390             self.selected_service = service
    391         else:
    392             wnd.sr.svcparent.Flush()
    393             if self.active_service and hasattr(self.active_service, 'Reset'):
    394                 self.active_service.Reset()
    395             self.active_service = None
    396             self.selected_service = service
    397         self.loading = 0
    398         if inout == 0 and service is not None:
    399             self._LoadSvc(1, service)
    400         if inout == 0 and service is None:
    401             wnd.sr.svcparent.Flush()
    402 
    403     def Startup(self, svc):
    404         uthread.new(svc.Startup, self)
    405 
    406     def GiveHint(self, hintstr, left = 80, top = 320, width = 300):
    407         self.ClearHint()
    408         if self.hint is None:
    409             par = Container(name='captionParent', parent=self.GetUnderlay().sr.main, align=uiconst.TOPLEFT, top=top, left=left, width=width, height=256, idx=0)
    410             self.hint = eveLabel.CaptionLabel(text='', parent=par, align=uiconst.TOALL, left=0, top=0)
    411         self.hint.parent.top = top
    412         self.hint.parent.left = left
    413         self.hint.parent.width = width
    414         self.hint.text = hintstr or ''
    415 
    416     def ClearHint(self):
    417         if self.hint is not None:
    418             self.hint.text = ''
    419 
    420     def SetupService(self, wnd, servicename):
    421         wnd.sr.svcparent.Flush()
    422         svc = None
    423         topheight = 128
    424         btmheight = 0
    425         icon = 'ui_9_64_14'
    426         sz = 128
    427         top = -16
    428         icon = eveIcon.Icon(icon=icon, parent=wnd.sr.svcparent, left=0, top=top, size=sz, idx=0)
    429         iconpar = Container(name='iconpar', parent=wnd.sr.svcparent, align=uiconst.TOTOP, height=96, clipChildren=1, state=uiconst.UI_PICKCHILDREN)
    430         bigicon = icon.CopyTo()
    431         bigicon.width = bigicon.height = sz * 2
    432         bigicon.top = -64
    433         bigicon.opacity = 0.1
    434         iconpar.children.append(bigicon)
    435         closeX = eveIcon.Icon(icon='ui_38_16_220')
    436         closeX.align = uiconst.TOPRIGHT
    437         closeX.left = closeX.top = 2
    438         closeX.OnClick = self.CloseSvc
    439         iconpar.children.append(closeX)
    440         Line(parent=iconpar, align=uiconst.TOPRIGHT, height=1, left=2, top=16, width=18)
    441         icon.state = uiconst.UI_DISABLED
    442         wnd.sr.caption.text = self.GetServiceDisplayName(servicename)
    443         wnd.sr.caption.state = uiconst.UI_DISABLED
    444         return (svc, 'service')
    445 
    446     def CloseSvc(self, *args):
    447         uthread.new(self.LoadSvc, None)
    448 
    449     def UndockAttempt(self, shipID):
    450         return self._DoUndockAttempt(False, True, shipID)
    451 
    452     def _DoUndockAttempt(self, ignoreContraband, observedSuppressed, shipID):
    453         try:
    454             shipsvc = sm.GetService('gameui').GetShipAccess()
    455             undockingLogLabel = localization.GetByLabel('UI/Station/UndockingFromStationToSystem', fromStation=session.stationid, toSystem=session.solarsystemid2)
    456             sm.GetService('logger').AddText(undockingLogLabel)
    457             if observedSuppressed:
    458                 ignoreContraband = settings.user.suppress.Get('suppress.ShipContrabandWarningUndock', None) == uiconst.ID_OK
    459             onlineModules = sm.GetService('clientDogmaIM').GetDogmaLocation().GetOnlineModules(shipID)
    460             try:
    461                 sm.GetService('space').PrioritizeLoadingForIDs([session.stationid])
    462                 sm.GetService('sessionMgr').PerformSessionChange('undock', shipsvc.Undock, shipID, ignoreContraband, onlineModules=onlineModules)
    463             except UserError as e:
    464                 if e.msg == 'ShipNotInHangar':
    465                     capsuleID = e.dict.get('capsuleID', None)
    466                     dogmaLocation = sm.GetService('clientDogmaIM').GetDogmaLocation()
    467                     if capsuleID is not None:
    468                         dogmaLocation.MakeShipActive(capsuleID)
    469                     raise
    470                 elif e.msg == 'ShipContrabandWarningUndock':
    471                     if prompt_player_fsd_dialog(e.msg, e.dict, uiconst.OKCANCEL, suppress=uiconst.ID_OK) == uiconst.ID_OK:
    472                         sys.exc_clear()
    473                         return self._DoUndockAttempt(True, False, shipID)
    474                     else:
    475                         return False
    476                 else:
    477                     raise
    478 
    479             self.CloseStationWindows()
    480         except Exception as e:
    481             sm.GetService('undocking').AbortUndock()
    482             raise
    483 
    484         return True
    485 
    486     def CloseStationWindows(self):
    487         ReprocessingWnd.CloseIfOpen()
    488 
    489     def SelectShipDlg(self):
    490         hangarInv = sm.GetService('invCache').GetInventory(const.containerHangar)
    491         items = hangarInv.List(const.flagHangar)
    492         tmplst = []
    493         activeShipID = eveCfg.GetActiveShip()
    494         for item in items:
    495             if item[const.ixCategoryID] == const.categoryShip and item[const.ixSingleton]:
    496                 tmplst.append((evetypes.GetName(item[const.ixTypeID]), item, item[const.ixTypeID]))
    497 
    498         if not tmplst:
    499             prompt_player_fsd_dialog('NeedShipToUndock')
    500             return
    501         ret = uix.ListWnd(tmplst, 'item', localization.GetByLabel('UI/Station/SelectShip'), None, 1)
    502         if ret is None or ret[1].itemID == activeShipID:
    503             return
    504         newActiveShip = ret[1]
    505         try:
    506             self.TryActivateShip(newActiveShip)
    507         except:
    508             raise
    509 
    510     def OnDogmaAttributeChanged(self, shipID, itemID, attributeID, value):
    511         if self.activeshipmodel and attributeID == const.attributeIsOnline and shipID == eveCfg.GetActiveShip():
    512             dogmaLocation = sm.GetService('clientDogmaIM').GetDogmaLocation()
    513             slot = None
    514             if not dogmaLocation.IsItemLoaded(shipID):
    515                 dogmaLocation.LoadItem(shipID)
    516             if dogmaLocation.IsItemLoading(shipID):
    517                 dogmaLocation.loadingItems[shipID].receive()
    518             for module in dogmaLocation.GetDogmaItem(shipID).GetFittedItems().itervalues():
    519                 if module.itemID != itemID:
    520                     continue
    521                 slot = module.flagID - const.flagHiSlot0 + 1
    522                 sceneShip = self.activeshipmodel
    523                 for turretSet in sceneShip.turretSets:
    524                     if turretSet.slotNumber == slot:
    525                         if module.IsOnline():
    526                             turretSet.EnterStateIdle()
    527                         else:
    528                             turretSet.EnterStateDeactive()
    529 
    530     def GetStationItem(self):
    531         if session.stationid and self.HasInvalidStationItem():
    532             self.SetStationItemBits(sm.RemoteSvc('stationSvc').GetStationItemBits())
    533         return self._stationItem
    534 
    535     def ClearStationItem(self):
    536         self._stationItem = None
    537 
    538     def SetStationItemBits(self, bits):
    539         self._stationItem = Row(['ownerID',
    540          'itemID',
    541          'operationID',
    542          'stationTypeID'], bits)
    543 
    544     def HasInvalidStationItem(self):
    545         return self._stationItem is None or self._stationItem.itemID != session.stationid
    546 
    547     def OnStationInformationUpdated(self, stationID):
    548         sm.GetService('objectCaching').InvalidateCachedMethodCall('stationSvc', 'GetStation', stationID)
    549 
    550     def IsInNewbieShip(self):
    551         shipItem = sm.GetService('clientDogmaIM').GetDogmaLocation().GetShipItem()
    552         return shipItem and IsNewbieShip(shipItem.groupID)
    553 
    554     def CreateNewbieShip(self):
    555         locationID = session.stationid or session.structureid
    556         if not locationID:
    557             raise stationServiceConst.NewbieShipError('MustBeDocked')
    558         shipItem = sm.GetService('clientDogmaIM').GetDogmaLocation().GetShipItem()
    559         if not shipItem:
    560             raise stationServiceConst.NewbieShipError('ErrorCreatingNewbieShip')
    561         shipID = shipItem.itemID
    562         shipGroupID = shipItem.groupID
    563         if IsNewbieShip(shipGroupID):
    564             raise stationServiceConst.NewbieShipError('AlreadyInNewbieShip')
    565         if not IsCapsule(shipGroupID):
    566             areYouSureMessage = localization.GetByLabel('UI/Station/ConfirmMoveToNewbieShip')
    567             if prompt_player_fsd_dialog('AskAreYouSure', {'cons': areYouSureMessage}, uiconst.YESNO) != uiconst.ID_YES:
    568                 return
    569         try:
    570             sm.RemoteSvc('dogmaIM').CreateNewbieShip(shipID, locationID)
    571         except UserError:
    572             raise
    573         except Exception:
    574             raise stationServiceConst.NewbieShipError('ErrorCreatingNewbieShip')
    575 
    576 
    577 class StationLayer(LayerCore):
    578     __guid__ = 'form.StationLayer'
    579 
    580     def OnCloseView(self):
    581         sm.GetService('station').CleanUp()
    582 
    583     def OnOpenView(self, **kwargs):
    584         pass