assembleModularShip.py (10063B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\station\assembleModularShip.py 2 from collections import defaultdict 3 import evetypes 4 import localization 5 import uthread 6 import utillib 7 from carbonui import uiconst 8 from carbonui.primitives.fill import Fill 9 from eve.client.script.ui.control.entries.generic import Generic 10 from eve.client.script.ui.control.entries.header import Header 11 from eve.client.script.ui.control.entries.util import GetFromClass 12 from eve.client.script.ui.control.listwindow import ListWindow 13 from eve.client.script.ui.control import eveLabel 14 from eve.common.lib import appConst as const 15 from eve.common.script.sys import eveCfg 16 from eve.common.script.sys.eveCfg import IsControllingStructure 17 from inventorycommon.const import numVisibleSubsystems 18 from inventorycommon.util import IsSubsystemFlagVisible 19 20 def prompt_assemble_modular_ship(ship): 21 wnd = AssembleShip.Open(windowID='assemble_modular_ship_dialog', ship=ship) 22 wnd.show_window_controls = False 23 wnd.MakeUnstackable() 24 if wnd.ShowModal() == 1: 25 return wnd.result 26 else: 27 return None 28 29 30 class AssembleShip(ListWindow): 31 __guid__ = 'form.AssembleShip' 32 __nonpersistvars__ = [] 33 default_ship = None 34 default_groupIDs = None 35 default_isPreview = None 36 ship_doc = 'Ship' 37 groupIDs_doc = 'Group IDs' 38 isPreview_doc = 'Is preview' 39 result = None 40 41 def ApplyAttributes(self, attributes): 42 ListWindow.ApplyAttributes(self, attributes) 43 ship = attributes.ship 44 groupIDs = attributes.groupIDs 45 isPreview = attributes.isPreview 46 self.ship = ship 47 self.groupIDs = groupIDs 48 self.scope = uiconst.SCOPE_INGAME 49 self.isPreview = isPreview 50 self.SetCaption(localization.GetByLabel('UI/Station/PickSubSystems')) 51 self.startSubSystems = {} 52 if not self.isPreview: 53 self.DefineButtons(uiconst.OKCANCEL, okFunc=self.Submit, cancelFunc=self.Cancel) 54 self.invalidateOpenState = 1 55 self.scroll.state = uiconst.UI_NORMAL 56 self.scroll.SelectAll = self.SelectAll 57 self.subSystems = {} 58 self.SetMinSize([300, 400]) 59 self.selectedSubSystemsByFlag = {} 60 self.LoadScrollList() 61 self.UpdateHint() 62 setselected = attributes.setselected 63 if setselected is not None: 64 self.SetSelected(setselected) 65 66 def SelectAll(self, *args): 67 pass 68 69 def UpdateShip(self, ship, selectedSubSystems = None): 70 self.ship = ship 71 self.startSubSystems = selectedSubSystems or {} 72 self.LoadScrollList() 73 74 def SetSelected(self, subSystems = None): 75 self.startSubSystems = subSystems or {} 76 self.LoadScrollList() 77 78 def GetSubSystemsByGroup(self): 79 godma = sm.StartService('godma') 80 if self.isPreview: 81 subSystemsByGroupID = defaultdict(list) 82 for groupID in evetypes.GetGroupIDsByCategory(const.categorySubSystem): 83 for typeID in evetypes.GetTypeIDsByGroup(groupID): 84 if not evetypes.IsPublished(typeID): 85 continue 86 if godma.GetTypeAttribute(typeID, const.attributeFitsToShipType) != self.ship.typeID: 87 continue 88 if not IsSubsystemFlagVisible(int(godma.GetTypeAttribute(typeID, const.attributeSubSystemSlot))): 89 continue 90 subSystemsByGroupID[groupID].append((typeID, typeID)) 91 92 else: 93 if not (eveCfg.IsDocked() or IsControllingStructure()): 94 return 95 inv = sm.GetService('invCache').GetInventory(const.containerHangar) 96 subSystemsByGroupID = defaultdict(list) 97 for item in inv.List(const.flagHangar): 98 if item.categoryID != const.categorySubSystem: 99 continue 100 if godma.GetTypeAttribute(item.typeID, const.attributeFitsToShipType) != self.ship.typeID: 101 continue 102 if not IsSubsystemFlagVisible(int(godma.GetTypeAttribute(item.typeID, const.attributeSubSystemSlot))): 103 continue 104 subSystemsByGroupID[item.groupID].append((item.typeID, item.itemID)) 105 106 return subSystemsByGroupID 107 108 def LoadScrollList(self): 109 scrolllist = [] 110 subSystemsByGroupID = self.GetSubSystemsByGroup() 111 godma = sm.GetService('godma') 112 for groupID in evetypes.GetGroupIDsByCategory(const.categorySubSystem): 113 if self.groupIDs is not None and groupID in self.groupIDs: 114 continue 115 scrolllist.append(GetFromClass(Header, {'label': evetypes.GetGroupNameByGroup(groupID)})) 116 types = [] 117 typeIDs = [] 118 if groupID in subSystemsByGroupID: 119 for subSystemTypeID, subSystemItemID in subSystemsByGroupID[groupID]: 120 if subSystemTypeID not in typeIDs: 121 types.append((subSystemTypeID, evetypes.GetName(subSystemTypeID), subSystemItemID)) 122 typeIDs.append(subSystemTypeID) 123 124 types.sort() 125 first = True 126 for typeID, typeName, itemID in types: 127 data = utillib.KeyVal() 128 data.typeID = typeID 129 data.label = typeName 130 data.showinfo = 1 131 data.itemID = itemID 132 data.OnClick = self.ClickEntry 133 if groupID in self.startSubSystems and typeID == self.startSubSystems[groupID] or not self.startSubSystems and first: 134 data.isSelected = 1 135 else: 136 data.isSelected = 0 137 if data.isSelected: 138 slotFlag = int(godma.GetTypeAttribute(typeID, const.attributeSubSystemSlot)) 139 self.subSystems[slotFlag] = itemID 140 self.selectedSubSystemsByFlag[slotFlag] = itemID 141 first = False 142 scrolllist.append(GetFromClass(AssembleShipEntry, data)) 143 144 self.UpdateHint() 145 self.scroll.Load(contentList=scrolllist, scrolltotop=0) 146 147 def getSubSystems(self): 148 subSystems = {} 149 for s in self.subSystems.values(): 150 subSystems[evetypes.GetGroupID(s)] = s 151 152 return subSystems 153 154 def ClickEntry(self, entry, *args): 155 slotFlag = int(sm.services['godma'].GetTypeAttribute(entry.typeID, const.attributeSubSystemSlot)) 156 node = None 157 if slotFlag in self.selectedSubSystemsByFlag: 158 oldItemID = self.selectedSubSystemsByFlag[slotFlag] 159 for node in self.scroll.GetNodes(): 160 if not node.itemID: 161 continue 162 if node.itemID == oldItemID: 163 break 164 165 if node is not None: 166 node.isSelected = False 167 content = self.scroll.sr.content 168 for child in content.children: 169 if getattr(child, 'itemID', None) == node.itemID: 170 child.HiliteMe(uiconst.UI_HIDDEN) 171 172 node = self.GetNode(entry) 173 if node is None: 174 return 175 self.selectedSubSystemsByFlag[slotFlag] = entry.itemID 176 entry.HiliteMe(uiconst.UI_DISABLED) 177 node = self.GetNode(entry) 178 if node is not None: 179 node.isSelected = True 180 self.subSystems[slotFlag] = entry.itemID 181 self.UpdateHint() 182 if self.isPreview: 183 sm.GetService('preview').PreviewType(self.ship.typeID, self.getSubSystems(), animate=False) 184 185 def GetNode(self, entry): 186 for node in self.scroll.GetNodes(): 187 if not node.itemID: 188 continue 189 if node.itemID == entry.itemID: 190 return node 191 192 def Error(self, *args): 193 pass 194 195 def UpdateHint(self): 196 ep = self.GetChild('errorParent') 197 if self.groupIDs is None: 198 groupIDs = [] 199 else: 200 groupIDs = self.groupIDs 201 lenGroupIDs = 0 202 if self.groupIDs is not None: 203 lenGroupIDs = len(self.groupIDs) 204 if len(self.subSystems) + lenGroupIDs != numVisibleSubsystems: 205 t = eveLabel.EveLabelMedium(text=localization.GetByLabel('UI/Station/SelectFiveSubsystems'), top=-3, parent=ep, width=self.minsize[0] - 32, state=uiconst.UI_DISABLED, color=(1.0, 0.0, 0.0, 1.0), align=uiconst.CENTER) 206 ep.state = uiconst.UI_DISABLED 207 ep.height = t.height + 8 208 else: 209 ep.state = uiconst.UI_HIDDEN 210 211 def Refresh(self): 212 self.groupIDs = None 213 self.subSystems = {} 214 self.LoadScrollList() 215 216 def Submit(self, *args): 217 lenGroupIDs = 0 218 if self.groupIDs is not None: 219 lenGroupIDs = len(self.groupIDs) 220 hangarContents = {i.itemID for i in sm.GetService('invCache').GetInventory(const.containerHangar).List(const.flagHangar)} 221 subSystems = set(self.subSystems.values()) 222 if subSystems & hangarContents != subSystems: 223 self.Refresh() 224 if len(self.subSystems) != numVisibleSubsystems - lenGroupIDs: 225 self.Refresh() 226 return 227 self.result = self.subSystems.values() 228 self.SetModalResult(1) 229 230 def Cancel(self, *args): 231 self.result = None 232 self.SetModalResult(0) 233 234 235 class AssembleShipEntry(Generic): 236 __guid__ = 'listentry.AssembleShipEntry' 237 238 def Startup(self, *args): 239 Generic.Startup(self, *args) 240 self.sr.selectedEntry = Fill(parent=self, padTop=1, padBottom=1, color=(0.0, 1.0, 0.0, 0.25)) 241 self.sr.selectedEntry.state = uiconst.UI_HIDDEN 242 243 def Load(self, node): 244 Generic.Load(self, node) 245 if node.Get('isSelected', False): 246 self.sr.selectedEntry.state = uiconst.UI_DISABLED 247 else: 248 self.sr.selectedEntry.state = uiconst.UI_HIDDEN 249 250 def GetMenu(self, *args): 251 return [] 252 253 def HiliteMe(self, state): 254 self.sr.selectedEntry.state = state 255 self.selected = state == uiconst.UI_DISABLED