sofpreviewer.py (37790B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\eveclientqatools\sofpreviewer.py 2 from __future__ import print_function 3 import re 4 import blue 5 import carbonui.fontconst 6 import carbonui.const as uiconst 7 import evegraphics.utils as gfxutils 8 import eveSpaceObject.spaceobjanimation as soanimation 9 from carbonui.control.combo import Combo 10 from carbonui.control.singlelineedits.singleLineEditFloat import SingleLineEditFloat 11 from carbonui.control.singlelineedits.singleLineEditInteger import SingleLineEditInteger 12 from carbonui.button.group import ButtonGroup 13 from carbonui.control.checkbox import Checkbox 14 from carbonui.control.singlelineedits.singleLineEditText import SingleLineEditText 15 from carbonui.control.window import Window 16 from carbonui.decorative.panelUnderlay import PanelUnderlay 17 from eve.client.script.ui.shared.preview import PreviewContainer 18 from carbonui.primitives.container import Container 19 from carbonui.primitives.gridcontainer import GridContainer 20 from carbonui.primitives.sprite import Sprite 21 from carbonui.primitives.line import Line 22 from eve.client.script.ui.control.eveLabel import EveLabelSmall 23 from carbonui.control.scrollContainer import ScrollContainer 24 from carbonui.control.slider import Slider 25 import fsdBuiltData.common.graphicMaterialSets as graphicMaterialSets 26 from shipskins.static import SkinMaterialStorage 27 from sofDnaLibrary.query import GetDnaStringsMatchingQuery 28 MAX_MULTI_HULLS = 4 29 MULTI_HULL_REGEX = re.compile('_s\\dv\\d') 30 MULTI_HULL_VARIATION_REGEX = re.compile('v\\d') 31 MULTI_HULL_SPECIFICATION_REGEX = re.compile('_s\\d') 32 DEFAULT_FACTION_FOR_T2HULLS = {'ardishapur': ['ac2_t2b', 33 'ai2_t2', 34 'af5_t2', 35 'ab2_t2', 36 'af2_t2', 37 'ac4_t2'], 38 'brutor': ['mf1_t2a', 39 'mcb1_t2c', 40 'mf5_t2a', 41 'mc3_t2a', 42 'mf7_t2c', 43 'mc2_t2a', 44 'mbc2_t2', 45 'mb2_t2', 46 'mf4_t2a', 47 'mdh1_t2', 48 'mdl1_t2', 49 'mdm1_t2', 50 'msd1_t2'], 51 'creodron': ['gfr1_t2', 52 'gbc2_t2', 53 'gf5_t2', 54 'gf4_t2a', 55 'gc3_t2', 56 'gb1_t2', 57 'gdh1_t2', 58 'gdl1_t2', 59 'gdm1_t2', 60 'gsd1_t2'], 61 'development': ['oref1_t2b'], 62 'duvolle': ['gc1_t2a', 63 'gbc1_t2a', 64 'gc4_t2a', 65 'gf7_t2', 66 'gb2_t2', 67 'gf3_t2', 68 'gf6_t2b', 69 'gi4_t2'], 70 'ishukone': ['cf3_t2', 71 'cc2_t2b', 72 'cc4_t2a', 73 'cf7_t2b', 74 'cfr1_t2', 75 'cbc1_t2b'], 76 'kaalakiota': ['ci2_t2', 77 'cf2_t2a', 78 'cde1_t2', 79 'cbc2_t2', 80 'cc2_t2a', 81 'cc4_t2b', 82 'cb2_t2'], 83 'khanid': ['af7_t2', 84 'ac1_t2a', 85 'abc1_t2a', 86 'ade1_t2', 87 'ai1_t2', 88 'af4_t2a', 89 'ac2_t2a', 90 'af3_t2a'], 91 'laidai': ['cc1_t2', 92 'ci3_t2', 93 'cc3_t2', 94 'cb1_t2', 95 'cf7_t2a', 96 'cf4_t2', 97 'cf6_t2', 98 'cf2_t2b', 99 'cdh1_t2', 100 'cdl1_t2', 101 'cdm1_t2', 102 'csd1_t2'], 103 'orebase': ['oredh1_t2'], 104 'prospecting': ['oreba3_t2', 'oreba2_t2', 'oreba1_t2'], 105 'roden': ['gf6_t2a', 106 'gf4_t2b', 107 'gde1_t2', 108 'gc1_t2b', 109 'gi2_t2', 110 'gc2_t2', 111 'gc4_t2b'], 112 'sarum': ['abc_t2', 113 'afr1_t2', 114 'af4_t2b', 115 'ac3_t2', 116 'ab1_t2', 117 'ac1_t2b', 118 'af3_t2b', 119 'adh1_t2', 120 'adl1_t2', 121 'adm1_t2', 122 'asd1_t2'], 123 'sebiestor': ['mc2_t2c', 124 'mi3_t2c', 125 'mc3_t2c', 126 'mde1_t2c', 127 'mc4_t2c', 128 'mf1_t2c'], 129 'thukker': ['mf2_t2b', 130 'mf4_t2b', 131 'mi2_t2b', 132 'mfr1_t2', 133 'mb1_t2b', 134 'mc1_t2b']} 135 136 def GetGenericName(label): 137 return label.replace(' ', '_').replace(':', '').strip().lower() 138 139 140 def _CreateCheckbox(name, checkboxLabel, checkboxCallback, parent, align = uiconst.TOLEFT): 141 return Checkbox(name=name + '_constraint', align=align, width=75, height=18, padLeft=10, parent=parent, text=checkboxLabel, callback=checkboxCallback) 142 143 144 def _CreateCombo(name, values, callback, select, label, parent, align = uiconst.TOLEFT, width = 150): 145 return Combo(name=name + '_combo', align=align, width=width, height=18, parent=parent, label=label, options=[ (name, i) for i, name in enumerate(values) ], callback=callback, select=select) 146 147 148 def _CreateInput(name, value, callback, label, parent, align = uiconst.TOLEFT): 149 return SingleLineEditText(name=name + '_input', align=align, label=label, parent=parent, width=150, height=18, setvalue=value, OnFocusLost=callback, OnReturn=callback) 150 151 152 def _CreateSlider(name, label, minValue, maxValue, startVal, valueChangeFunc, parent, align = uiconst.TOLEFT): 153 return Slider(name=name, align=align, label=label, parent=parent, width=150, height=18, minValue=minValue, maxValue=maxValue, value=startVal, on_dragging=valueChangeFunc, callback=valueChangeFunc) 154 155 156 def _CreateContainer(name, parent, padTop = 16, padBottom = 0): 157 return Container(name=name + '_container', parent=parent, align=uiconst.TOTOP, height=18, padTop=padTop, padBottom=padBottom, padLeft=5, padRight=5) 158 159 160 def CreateDropdownWithCheckbox(label, values, select, dropdownCallback, checkboxLabel, checkboxCallback, parent): 161 name = GetGenericName(label) 162 container = _CreateContainer(name, parent) 163 dropdown = _CreateCombo(name, values, dropdownCallback, select, label, container) 164 checkbox = _CreateCheckbox(name, checkboxLabel, checkboxCallback, container) 165 return (dropdown, checkbox) 166 167 168 def CreateDropdown(label, values, callback, select, parent, align = uiconst.TOLEFT): 169 name = GetGenericName(label) 170 container = _CreateContainer(name, parent) 171 combo = _CreateCombo(name, values, callback, select, label, container, align) 172 return combo 173 174 175 def CreateInput(label, value, callback, parent, align = uiconst.TOLEFT): 176 name = GetGenericName(label) 177 container = _CreateContainer(name, parent) 178 inputField = _CreateInput(name, value, callback, label, container, align) 179 return inputField 180 181 182 def CreateSlider(label, minValue, maxValue, startValue, valueChangedFunc, parent): 183 name = GetGenericName(label) 184 container = _CreateContainer(name, parent, padTop=0, padBottom=16) 185 slider = _CreateSlider(name, label, minValue, maxValue, startValue, valueChangedFunc, container) 186 return slider 187 188 189 def GetMultiHullInfo(hull): 190 results = MULTI_HULL_REGEX.findall(hull) 191 if len(results) > 0: 192 return (hull.replace(results[0], ''), GetMultiHullSpecification(hull), GetMultiHullVariation(hull)) 193 return (None, None, None) 194 195 196 def GetMultiHullVariation(hull): 197 return int(MULTI_HULL_VARIATION_REGEX.findall(hull)[0].replace('v', '')) 198 199 200 def GetMultiHullSpecification(hull): 201 return int(MULTI_HULL_SPECIFICATION_REGEX.findall(hull)[0].replace('_s', '')) 202 203 204 def GetMultiHullBaseName(hull): 205 results = MULTI_HULL_REGEX.findall(hull) 206 if len(results) > 0: 207 result = results[0] 208 return hull.replace(result, '') 209 return '' 210 211 212 def IsMultiHull(hull): 213 return len(MULTI_HULL_REGEX.findall(hull)) > 0 214 215 216 class StateMachineController: 217 218 def __init__(self): 219 self._states = {} 220 self._currentStates = {} 221 self._model = None 222 self._variables = {} 223 self._variableTypes = {} 224 self._variableEnumValues = {} 225 226 def _ClearAll(self): 227 self._states = {} 228 self._currentStates = {} 229 self._model = None 230 231 def SetupForHullAndModel(self, hull, model): 232 self._ClearAll() 233 self._model = model 234 soanimation.TriggerDefaultStates(model) 235 self._variables = {} 236 for each in self._model.controllers: 237 for var in getattr(each, 'variables', []): 238 self._variables[var.name] = var.value 239 self._variableTypes[var.name] = var.variableType 240 self._variableEnumValues[var.name] = var.enumValues 241 242 def GetVariables(self): 243 return self._variables 244 245 def GetVariableType(self, name): 246 return self._variableTypes.get(name, 0) 247 248 def GetEnumValues(self, name): 249 if self._variableTypes.get(name, 0) != 3: 250 return [] 251 result = [] 252 for each in self._variableEnumValues.get(name, '').split(','): 253 try: 254 k, v = each.strip().rsplit('=', 1) 255 v = float(v) 256 except ValueError: 257 continue 258 259 result.append((k, v)) 260 261 return result 262 263 def SetVariable(self, name, value): 264 self._variables[name] = float(value) 265 self._model.SetControllerVariable(name, float(value)) 266 267 def ApplyTo(self, model): 268 for name, value in self._variables.items(): 269 model.SetControllerVariable(name, value) 270 271 272 class SOFPreviewWindow: 273 274 def __init__(self): 275 self.name = 'SOF Preview Window' 276 self.windowID = 'SOFPreviewWindow_ ' + self.name 277 self.previewCont = None 278 dna = self.GetDnaFromPlayerShip() 279 multiHulls = dna.split(':')[0].split(';') 280 self.currentHulls = [ (None if i >= len(multiHulls) else multiHulls[i]) for i in xrange(0, MAX_MULTI_HULLS) ] 281 self.currentFaction = dna.split(':')[1] 282 self.currentRace = dna.split(':')[2] 283 self.currentMat = ['None', 284 'None', 285 'None', 286 'None'] 287 self.currentPatternMat = ['None', 'None'] 288 self.currentVariant = 'None' 289 self.currentPattern = 'None' 290 self.currentDirtLevel = None 291 self.currentResPathInsert = None 292 self.constrainToFaction = False 293 self.constrainToHull = False 294 self.constrainToRace = False 295 self.constrainToPattern = False 296 self.updateShip = True 297 self.stateMachineController = StateMachineController() 298 299 def _OnApplyButton(self, *args): 300 self._UpdatePlayerShip() 301 302 def _OnCopyDnaButton(self, *args): 303 blue.pyos.SetClipboardData(self.GetPreviewDna()) 304 305 def ShowUI(self): 306 Window.CloseIfOpen(windowID=self.windowID) 307 wnd = Window.Open(windowID=self.windowID) 308 wnd.SetMinSize([800, 500]) 309 wnd.SetCaption(self.name) 310 main = wnd.GetMainArea() 311 sofDB = blue.resMan.LoadObject('res:/dx9/model/spaceobjectfactory/data.red') 312 self.sofFactions = [] 313 for faction in sofDB.faction: 314 self.sofFactions.append(faction.name) 315 316 self.sofFactions.sort() 317 self.sofHulls = [] 318 self.multihulls = {} 319 for hull in sofDB.hull: 320 hull = hull.name 321 if IsMultiHull(hull): 322 baseHullName, subpart, variation = GetMultiHullInfo(hull) 323 if baseHullName not in self.multihulls: 324 self.multihulls[baseHullName] = [] 325 self.multihulls[baseHullName].append((hull, subpart, variation)) 326 if subpart == 1: 327 self.sofHulls.append(hull) 328 else: 329 self.sofHulls.append(hull) 330 331 self.sofHulls.sort() 332 self.sofRaces = [] 333 for race in sofDB.race: 334 self.sofRaces.append(race.name) 335 336 self.sofRaces.sort() 337 self.sofMaterials = [] 338 for material in sofDB.material: 339 self.sofMaterials.append(material.name) 340 341 self.sofMaterials.sort() 342 self.sofMaterials.insert(0, 'None') 343 self.sofVariants = [] 344 for i in xrange(len(sofDB.generic.variants)): 345 self.sofVariants.append(sofDB.generic.variants[i].name) 346 347 self.sofVariants.sort() 348 self.sofVariants.insert(0, 'None') 349 self.sofPatterns = [] 350 self.patternToHulls = {} 351 for pattern in sofDB.pattern: 352 self.sofPatterns.append(pattern.name) 353 self.patternToHulls[pattern.name] = [ hull.name for hull in pattern.projections ] 354 355 self.sofPatterns.sort() 356 self.sofPatterns.insert(0, 'None') 357 headerCont = Container(name='headerCont', parent=main, align=uiconst.TOTOP, height=30) 358 self.dnaLabel = EveLabelSmall(name='dnaLabel', align=uiconst.CENTER, parent=headerCont, text='') 359 self.SetupButtonContainer(main) 360 self.SetupInputContainers(main) 361 self.previewCont = PreviewContainer(parent=main, align=uiconst.TOALL) 362 self.previewCont.PreviewSofDna(self.GetPreviewDna()) 363 self._ReloadStateMachineOptions() 364 365 def SetupButtonContainer(self, parent): 366 buttonContainer = Container(name='_buttonCont', parent=parent, align=uiconst.TOBOTTOM, height=20, padBottom=10) 367 buttonGroup = ButtonGroup(name='buttonGroup', parent=buttonContainer, align=uiconst.CENTER, fontsize=carbonui.fontconst.EVE_MEDIUM_FONTSIZE) 368 buttonGroup.AddButton('Copy DNA', self._OnCopyDnaButton) 369 buttonGroup.AddButton('Apply', self._OnApplyButton) 370 371 def SetupInputContainers(self, parent): 372 inputContainer = GridContainer(name='inputCont', parent=parent, align=uiconst.TOBOTTOM, height=250, lines=1, columns=3) 373 self.SetupLeftContainer(inputContainer) 374 self.SetupCenterContainer(inputContainer) 375 self.SetupRightContainer(inputContainer) 376 377 def SetupLeftContainer(self, inputContainer): 378 _leftContainer = Container(name='_leftContainer', parent=inputContainer) 379 leftContainer = Container(name='leftContainer', parent=_leftContainer, align=uiconst.TORIGHT, height=250, width=250) 380 selectedRace = self.GetComboListIndex(self.sofRaces, self.currentRace) 381 self.raceCombo, self.raceConstraint = CreateDropdownWithCheckbox('Race:', self.sofRaces, selectedRace, self.OnRaceComboChange, 'Constrained', self.OnRaceConstraintChanged, leftContainer) 382 selectedHull = self.GetComboListIndex(self.sofHulls, self.currentHulls[0]) 383 self.hullCombos = [] 384 firstHullCombo, self.hullConstraint = CreateDropdownWithCheckbox('Hull:', self.sofHulls, selectedHull, self.OnHullComboChange, 'Constrained', self.OnHullConstraintChanged, leftContainer) 385 self.hullCombos.append(firstHullCombo) 386 self.multiHullContainer = Container(name='multiHulls', parent=leftContainer, align=uiconst.TOTOP, height=35 * (MAX_MULTI_HULLS - 1)) 387 for i in xrange(1, MAX_MULTI_HULLS): 388 self.hullCombos.append(CreateDropdown('Hull %d:' % (i + 1), [], self.OnSpecificationChanges, self.currentHulls[i], self.multiHullContainer, align=uiconst.TOALL)) 389 390 self.multiHullContainer.display = False 391 selectedFaction = self.GetComboListIndex(self.sofFactions, self.currentFaction) 392 self.factionCombo, self.factionConstraint = CreateDropdownWithCheckbox('Faction:', self.sofFactions, selectedFaction, self.OnFactionComboChange, 'Constrained', self.OnFactionConstraintChanged, leftContainer) 393 selectedPattern = self.GetComboListIndex(self.sofPatterns, self.currentPattern) 394 self.patternCombo, self.patternConstraint = CreateDropdownWithCheckbox('Pattern:', self.sofPatterns, selectedPattern, self.OnPatternComboChange, 'Constrained', self.OnPatternConstraintChanged, leftContainer) 395 previewContainer = Container(parent=leftContainer, align=uiconst.TOALL, padTop=16) 396 self.previewImage = Sprite(parent=previewContainer, align=uiconst.CENTER, width=64, height=64) 397 self.skinUnavailableLabel = EveLabelSmall(name='skinUnavailableLabel', align=uiconst.CENTERBOTTOM, parent=leftContainer, text='No skin license available', display=False) 398 self.UpdateIcon() 399 400 def SetupCenterContainer(self, inputContainer): 401 _centerContainer = Container(name='_centerContainer', parent=inputContainer) 402 centerContainer = Container(name='centerContainer', parent=_centerContainer, align=uiconst.CENTERTOP, height=250, width=250) 403 self.matCombo1 = CreateDropdown('Material 1:', self.sofMaterials, self.OnMat1ComboChange, self.GetComboListIndex(self.sofMaterials, self.currentMat[0]), centerContainer, align=uiconst.CENTER) 404 self.matCombo2 = CreateDropdown('Material 2:', self.sofMaterials, self.OnMat2ComboChange, self.GetComboListIndex(self.sofMaterials, self.currentMat[1]), centerContainer, align=uiconst.CENTER) 405 self.matCombo3 = CreateDropdown('Material 3:', self.sofMaterials, self.OnMat3ComboChange, self.GetComboListIndex(self.sofMaterials, self.currentMat[2]), centerContainer, align=uiconst.CENTER) 406 self.matCombo4 = CreateDropdown('Material 4:', self.sofMaterials, self.OnMat4ComboChange, self.GetComboListIndex(self.sofMaterials, self.currentMat[3]), centerContainer, align=uiconst.CENTER) 407 self.matCombo5 = CreateDropdown('Pattern Material 1:', self.sofMaterials, self.OnPatternMat1ComboChange, self.GetComboListIndex(self.sofMaterials, self.currentPatternMat[0]), centerContainer, align=uiconst.CENTER) 408 self.matCombo6 = CreateDropdown('Pattern Material 2:', self.sofMaterials, self.OnPatternMat2ComboChange, self.GetComboListIndex(self.sofMaterials, self.currentPatternMat[1]), centerContainer, align=uiconst.CENTER) 409 410 def SetupRightContainer(self, inputContainer): 411 _rightContainer = Container(name='_rightContainer', parent=inputContainer) 412 rightContainer = Container(name='rightContainer', parent=_rightContainer, align=uiconst.TOLEFT, height=250, width=250) 413 self.dirtSlider = CreateSlider('Dirt', 0.0, 100.0, 50.0, self.OnDirtSliderChange, rightContainer) 414 self.UpdateDirtSliderLabel() 415 self.materialSetIDCombo, self.materialSetFilteredByRace = CreateDropdownWithCheckbox('materialSetID', [], 0, self.OnMaterialSetIDChange, 'Filter By Race', self.OnMaterialSetFiltered, rightContainer) 416 self._FilterMaterialSet(False) 417 self.resPathInsertEdit = CreateInput('resPathInsert', '', self.OnResPathInsertChange, rightContainer) 418 self.variantCombo = CreateDropdown('Variants:', self.sofVariants, self.OnVariantComboChange, self.GetComboListIndex(self.sofVariants, self.currentVariant), rightContainer) 419 self.controllerParent = Container(parent=rightContainer, align=uiconst.TOTOP, height=68, padTop=16, padLeft=5, padRight=5) 420 self.controllers = None 421 422 @staticmethod 423 def GetComboListIndex(comboContentList, name): 424 for index, each in enumerate(comboContentList): 425 if each.lower() == name.lower(): 426 return index 427 428 def GetCurrentHull(self): 429 currentHull = self.currentHulls[0] 430 if IsMultiHull(currentHull): 431 currentHull += ';' + ';'.join((hull for hull in self.currentHulls[1:] if hull is not None)) 432 return currentHull 433 434 def GetPreviewDna(self): 435 dna = self.GetCurrentHull() + ':' + self.currentFaction + ':' + self.currentRace 436 if any((x != 'None' for x in self.currentMat)): 437 dna += ':material?' + str(self.currentMat[0]) + ';' + str(self.currentMat[1]) + ';' + str(self.currentMat[2]) + ';' + str(self.currentMat[3]) 438 if self.currentResPathInsert is not None: 439 dna += ':respathinsert?' + str(self.currentResPathInsert) 440 if self.currentVariant != 'None': 441 dna += ':variant?' + str(self.currentVariant) 442 if self.currentPattern != 'None': 443 dna += ':pattern?' + str(self.currentPattern) + ';' + str(self.currentPatternMat[0]) + ';' + str(self.currentPatternMat[1]) 444 self.dnaLabel.text = dna 445 return dna 446 447 @staticmethod 448 def GetDnaFromPlayerShip(): 449 michelle = sm.GetService('michelle') 450 ship = michelle.GetBall(session.shipid) 451 if ship is None: 452 return 'ab1_t1:amarrbase:amarr' 453 dna = ship.GetDNA() 454 if dna is None: 455 return 'ab1_t1:amarrbase:amarr' 456 return dna 457 458 def UpdateDirtSliderLabel(self): 459 dirtLevel = gfxutils.RemapDirtLevel(self.dirtSlider.GetValue()) 460 self.dirtSlider.SetLabel('Dirt level: ' + str(dirtLevel)) 461 462 def OnDirtSliderChange(self, slider): 463 self.currentDirtLevel = gfxutils.RemapDirtLevel(slider.GetValue()) 464 self.UpdateDirtSliderLabel() 465 self._UpdatePreviewShip() 466 467 def OnFactionConstraintChanged(self, checkbox): 468 self.constrainToFaction = checkbox.GetValue() 469 self.ConstrainDnaSelection() 470 471 def OnRaceConstraintChanged(self, checkbox): 472 self.constrainToRace = checkbox.GetValue() 473 self.ConstrainDnaSelection() 474 475 def OnHullConstraintChanged(self, checkbox): 476 self.constrainToHull = checkbox.GetValue() 477 self.ConstrainDnaSelection() 478 479 def OnPatternConstraintChanged(self, checkbox): 480 self.constrainToPattern = checkbox.GetValue() 481 self.ConstrainDnaSelection() 482 483 def OnMaterialSetFiltered(self, checkbox): 484 materialSetFiltered = checkbox.GetValue() 485 self._FilterMaterialSet(materialSetFiltered) 486 487 def _FilterMaterialSet(self, filterByRace): 488 materialSets = graphicMaterialSets.GetGraphicMaterialSets() 489 availableMaterialSets = [] 490 for materialSetID, materialSet in materialSets.iteritems(): 491 if filterByRace: 492 raceHint = graphicMaterialSets.GetSofRaceHint(materialSet) 493 if raceHint and raceHint == self.raceCombo.GetKey(): 494 availableMaterialSets.append((materialSetID, materialSet.description)) 495 else: 496 availableMaterialSets.append((materialSetID, materialSet.description)) 497 498 availableMaterialSets = sorted(availableMaterialSets, key=lambda x: x[0]) 499 options = [('None', -1)] + [ ('%s: %s' % keyAndDesc, keyAndDesc[0]) for keyAndDesc in availableMaterialSets ] 500 self.materialSetIDCombo.LoadOptions(options) 501 self.TrySettingComboValue(self.materialSetIDCombo, 0) 502 503 def ConstrainDnaSelection(self): 504 raceQuery = '.*' 505 factionQuery = '.*' 506 hullQuery = '.*' 507 if self.constrainToFaction: 508 factionQuery = self.factionCombo.GetKey() 509 if self.constrainToHull: 510 hullQuery = self.hullCombos[0].GetKey() 511 if self.constrainToRace: 512 raceQuery = self.raceCombo.GetKey() 513 if self.constrainToPattern and self.currentPattern != 'None': 514 self.currentHulls[0] = self.TrySettingComboOptions(self.hullCombos[0], self.patternToHulls[self.currentPattern], self.currentHulls[0]) 515 if not self.constrainToFaction and not self.constrainToHull and not self.constrainToRace and not self.constrainToPattern: 516 self.currentFaction = self.TrySettingComboOptions(self.factionCombo, self.sofFactions, self.GetDefaultFactionForHull()) 517 self.currentRace = self.TrySettingComboOptions(self.raceCombo, self.sofRaces, self.currentRace) 518 self.currentHulls[0] = self.TrySettingComboOptions(self.hullCombos[0], self.sofHulls, self.currentHulls[0]) 519 self.currentPattern = self.TrySettingComboOptions(self.patternCombo, self.sofPatterns, self.currentPattern) 520 else: 521 dnaList = GetDnaStringsMatchingQuery(hullQuery, factionQuery, raceQuery) 522 selectableRaces = [] 523 selectableFactions = [] 524 selectableHulls = [] 525 for dna in dnaList: 526 dnaElements = dna.split(':') 527 hull = dnaElements[0] 528 faction = dnaElements[1] 529 race = dnaElements[2] 530 if faction not in selectableFactions: 531 selectableFactions.append(faction) 532 if race not in selectableRaces: 533 selectableRaces.append(race) 534 if hull not in selectableHulls: 535 selectableHulls.append(hull) 536 537 if not self.constrainToPattern: 538 selectablePatterns = [ patternName for patternName, hulls in self.patternToHulls.iteritems() for hullName in selectableHulls if hullName in hulls ] 539 selectablePatterns = list(set(selectablePatterns)) 540 selectablePatterns.insert(0, 'None') 541 self.currentPattern = self.TrySettingComboOptions(self.patternCombo, selectablePatterns, self.currentPattern) 542 elif self.currentPattern != 'None': 543 selectableHullsBasedOfPattern = set(self.patternToHulls[self.currentPattern]) 544 selectableHulls = list(set(selectableHulls).intersection(selectableHullsBasedOfPattern)) 545 if not self.constrainToHull: 546 self.currentHulls[0] = self.TrySettingComboOptions(self.hullCombos[0], selectableHulls, self.currentHulls[0]) 547 self.ShowMultiHullComboBoxes(self.currentHulls[0]) 548 if not self.constrainToFaction: 549 self.currentFaction = self.TrySettingComboOptions(self.factionCombo, selectableFactions, self.GetDefaultFactionForHull()) 550 if not self.constrainToRace: 551 self.currentRace = self.TrySettingComboOptions(self.raceCombo, selectableRaces, self.currentRace) 552 if not self.constrainToPattern and self.constrainToHull: 553 availablePatterns = [ pattern for pattern, hulls in self.patternToHulls.iteritems() if self.currentHulls[0] in hulls ] 554 availablePatterns.insert(0, 'None') 555 self.currentPattern = self.TrySettingComboOptions(self.patternCombo, availablePatterns, self.currentPattern) 556 self._UpdatePreviewShip() 557 558 def GetDefaultFactionForHull(self): 559 if self.currentHulls[0].endswith('t2'): 560 return self._GetDefaultFactionForT2Hull(self.currentHulls[0]) 561 else: 562 return self._GetDefaultFactionForT1Hull(self.currentHulls[0]) 563 564 def UpdateIcon(self): 565 path = None 566 id = self.GetCurrentMaterialSetID() 567 for mid, m in SkinMaterialStorage().iteritems(): 568 if m.materialSetID == id: 569 path = 'res:/UI/Texture/classes/skins/icons/%s.png' % mid 570 break 571 572 self.skinUnavailableLabel.display = path is None 573 if path is None: 574 path = 'res:/UI/Texture/notavailable.dds' 575 self.previewImage.texture.resPath = path 576 577 @staticmethod 578 def _GetDefaultFactionForT1Hull(hullName): 579 dnaList = GetDnaStringsMatchingQuery(hullName) 580 if len(dnaList) == 0: 581 return '' 582 race = dnaList[0].split(':')[2] 583 return race + 'base' 584 585 @staticmethod 586 def _GetDefaultFactionForT2Hull(hullName): 587 for factionName, hullList in DEFAULT_FACTION_FOR_T2HULLS.iteritems(): 588 if hullName in hullList: 589 return factionName 590 591 return '' 592 593 def GetCurrentMaterialSetID(self): 594 if not hasattr(self, 'materialSetIDCombo'): 595 return -1 596 return self.materialSetIDCombo.GetValue() 597 598 def GetCurrentMaterialSet(self): 599 materialSetID = self.GetCurrentMaterialSetID() 600 print('trying to find materialset for ' + str(materialSetID)) 601 materialSet = graphicMaterialSets.GetGraphicMaterialSet(materialSetID) 602 return materialSet 603 604 def ShowMultiHullComboBoxes(self, hull): 605 isMultiHull = IsMultiHull(hull) 606 self.multiHullContainer.display = isMultiHull 607 if isMultiHull: 608 baseHullName = GetMultiHullBaseName(hull) 609 for i in xrange(1, MAX_MULTI_HULLS): 610 availableHulls = [ hull for hull, specification, variation in sorted(self.multihulls[baseHullName], key=lambda x: x[2]) if specification == i + 1 ] 611 self.TrySettingComboOptions(self.hullCombos[i], availableHulls, self.currentPattern) 612 self.currentHulls[i] = availableHulls[0] 613 614 else: 615 for i in xrange(1, MAX_MULTI_HULLS): 616 self.currentHulls[i] = None 617 618 def TrySettingComboOptions(self, comboBox, options, selectedValue): 619 options = sorted(options) 620 if 'None' in options: 621 o = options.pop(options.index('None')) 622 options.insert(0, o) 623 optionTuple = [ (name, i) for i, name in enumerate(options) ] 624 comboBox.LoadOptions(optionTuple) 625 return self.TrySettingComboValue(comboBox, selectedValue) 626 627 def TrySettingComboValue(self, comboBox, selectedValue): 628 try: 629 comboBox.SelectItemByLabel(selectedValue) 630 except RuntimeError: 631 comboBox.SelectItemByIndex(0) 632 print("Could not select '%s', defaulting to '%s'" % (selectedValue, comboBox.GetKey())) 633 634 return comboBox.GetKey() 635 636 def IsMaterialSetSelected(self): 637 return self.materialSetIDCombo.GetKey() != 'None' 638 639 def OnPatternComboChange(self, comboBox, pattern, value): 640 self.currentPattern = pattern 641 if self.constrainToPattern: 642 self.ConstrainDnaSelection() 643 self._UpdatePreviewShip() 644 645 def OnFactionComboChange(self, comboBox, faction, value): 646 self.currentFaction = faction 647 if self.constrainToFaction: 648 self.ConstrainDnaSelection() 649 self._UpdatePreviewShip() 650 651 def OnHullComboChange(self, comboBox, hull, value): 652 self.currentHulls[0] = hull 653 self.ShowMultiHullComboBoxes(hull) 654 if self.constrainToHull: 655 self.ConstrainDnaSelection() 656 self._UpdatePreviewShip() 657 658 def OnSpecificationChanges(self, comboBox, hull, value): 659 specification = GetMultiHullSpecification(hull) 660 self.currentHulls[specification - 1] = hull 661 self._UpdatePreviewShip() 662 663 def OnRaceComboChange(self, comboBox, race, value): 664 self.currentRace = race 665 if self.constrainToRace: 666 self.ConstrainDnaSelection() 667 if self.materialSetFilteredByRace.GetValue(): 668 self._FilterMaterialSet(self.currentRace) 669 self._UpdatePreviewShip() 670 671 def OnMat1ComboChange(self, comboBox, material, value): 672 self.currentMat[0] = material 673 self._UpdatePreviewShip() 674 675 def OnMat2ComboChange(self, comboBox, material, value): 676 self.currentMat[1] = material 677 self._UpdatePreviewShip() 678 679 def OnMat3ComboChange(self, comboBox, material, value): 680 self.currentMat[2] = material 681 self._UpdatePreviewShip() 682 683 def OnMat4ComboChange(self, comboBox, material, value): 684 self.currentMat[3] = material 685 self._UpdatePreviewShip() 686 687 def OnPatternMat1ComboChange(self, comboBox, material, value): 688 self.currentPatternMat[0] = material 689 self._UpdatePreviewShip() 690 691 def OnPatternMat2ComboChange(self, comboBox, material, value): 692 self.currentPatternMat[1] = material 693 self._UpdatePreviewShip() 694 695 def OnVariantComboChange(self, comboBox, variant, value): 696 self.currentVariant = variant 697 self._UpdatePreviewShip() 698 699 def OnMaterialSetIDChange(self, *args): 700 self.updateShip = False 701 materialSet = self.GetCurrentMaterialSet() 702 faction = graphicMaterialSets.GetSofFactionName(materialSet) 703 if not faction: 704 dna = self.GetDnaFromPlayerShip() 705 if dna.split(':')[0] == self.GetCurrentHull(): 706 faction = dna.split(':')[1] 707 if faction: 708 try: 709 self.factionCombo.SelectItemByLabel(faction) 710 except RuntimeError: 711 if materialSet is not None: 712 print("Removing constraints because '%s' is not in the constrained faction list" % materialSet.sofFactionName) 713 self.constrainToFaction = False 714 self.constrainToRace = False 715 self.constrainToHull = False 716 self.constrainToPattern = False 717 self.factionConstraint.SetValue(False) 718 self.raceConstraint.SetValue(False) 719 self.hullConstraint.SetValue(False) 720 self.patternConstraint.SetValue(False) 721 self.ConstrainDnaSelection() 722 723 self.factionCombo.SelectItemByLabel(faction) 724 self.OnFactionComboChange(self.factionCombo, faction, None) 725 material1 = graphicMaterialSets.GetMaterial1(materialSet, 'None') 726 idx = self.GetComboListIndex(self.sofMaterials, material1) 727 self.matCombo1.SelectItemByValue(idx) 728 self.OnMat1ComboChange(self.matCombo1, material1, idx) 729 material2 = graphicMaterialSets.GetMaterial2(materialSet, 'None') 730 idx = self.GetComboListIndex(self.sofMaterials, material2) 731 self.matCombo2.SelectItemByValue(idx) 732 self.OnMat2ComboChange(self.matCombo2, material2, idx) 733 material3 = graphicMaterialSets.GetMaterial3(materialSet, 'None') 734 idx = self.GetComboListIndex(self.sofMaterials, material3) 735 self.matCombo3.SelectItemByValue(idx) 736 self.OnMat3ComboChange(self.matCombo3, material3, idx) 737 material4 = graphicMaterialSets.GetMaterial4(materialSet, 'None') 738 idx = self.GetComboListIndex(self.sofMaterials, material4) 739 self.matCombo4.SelectItemByValue(idx) 740 self.OnMat4ComboChange(self.matCombo4, material4, idx) 741 patternmaterial1 = graphicMaterialSets.GetCustomMaterial1(materialSet, 'None') 742 idx = self.GetComboListIndex(self.sofMaterials, patternmaterial1) 743 self.matCombo5.SelectItemByValue(idx) 744 self.OnPatternMat1ComboChange(self.matCombo5, patternmaterial1, idx) 745 patternmaterial2 = graphicMaterialSets.GetCustomMaterial2(materialSet, 'None') 746 idx = self.GetComboListIndex(self.sofMaterials, patternmaterial2) 747 self.matCombo6.SelectItemByValue(idx) 748 self.OnPatternMat2ComboChange(self.matCombo6, patternmaterial2, idx) 749 self.resPathInsertEdit.SetValue(graphicMaterialSets.GetResPathInsert(materialSet, '')) 750 self.OnResPathInsertChange() 751 sofPatternName = graphicMaterialSets.GetSofPatternName(materialSet, 'None') 752 idx = self.GetComboListIndex(self.sofPatterns, sofPatternName) 753 self.patternCombo.SelectItemByValue(idx) 754 self.OnPatternComboChange(self.patternCombo, sofPatternName, idx) 755 self.updateShip = True 756 self._UpdatePreviewShip() 757 self.UpdateIcon() 758 759 def OnResPathInsertChange(self, *args): 760 resPathInsert = self.resPathInsertEdit.GetValue() 761 print('new respathinsert: ' + resPathInsert) 762 if len(resPathInsert) == 0: 763 self.currentResPathInsert = None 764 else: 765 self.currentResPathInsert = resPathInsert 766 self._UpdatePreviewShip() 767 768 def _UpdatePreviewShip(self): 769 if self.previewCont is not None and self.updateShip: 770 self.previewCont.PreviewSofDna(self.GetPreviewDna(), dirt=self.currentDirtLevel) 771 self._ReloadStateMachineOptions() 772 773 def _ReloadStateMachineOptions(self): 774 model = self.previewCont.context.GetModel() 775 hull = self.GetCurrentHull() 776 self.stateMachineController.SetupForHullAndModel(hull, model) 777 self._RefreshControllerVariables() 778 779 def _OnControllerVariable(self, edit): 780 edit.SetText(edit.text, 1) 781 name = edit.name 782 value = float(edit.text) 783 self.stateMachineController.SetVariable(name, value) 784 785 def _OnControllerBoolVariable(self, cb): 786 name = cb.name 787 value = cb.GetValue() 788 self.stateMachineController.SetVariable(name, 1.0 if value else 0.0) 789 790 def _OnControllerEnumVariable(self, cb, *args): 791 name = cb.name 792 value = cb.GetValue() 793 self.stateMachineController.SetVariable(name, value) 794 795 def _RefreshControllerVariables(self): 796 if self.controllers: 797 self.controllers.Close() 798 self.controllers = ScrollContainer(parent=self.controllerParent, align=uiconst.TOTOP, height=68) 799 PanelUnderlay(bgParent=self.controllers) 800 for name, value in self.stateMachineController.GetVariables().items(): 801 line = Container(parent=self.controllers, align=uiconst.TOTOP, height=20, state=uiconst.UI_NORMAL) 802 EveLabelSmall(parent=line, align=uiconst.CENTERLEFT, text=name, left=4) 803 varType = self.stateMachineController.GetVariableType(name) 804 if varType == 1: 805 SingleLineEditInteger(align=uiconst.CENTERRIGHT, name=name, parent=line, width=150, height=18, setvalue=str(int(value)), OnFocusLost=self._OnControllerVariable, OnReturn=self._OnControllerVariable, sendSelfAsArgument=True) 806 elif varType == 2: 807 Checkbox(align=uiconst.CENTERRIGHT, name=name, parent=line, width=150, height=18, setvalue=str(value), floats=(None, None), callback=self._OnControllerBoolVariable) 808 elif varType == 3: 809 Combo(align=uiconst.CENTERRIGHT, name=name, parent=line, width=150, height=18, options=self.stateMachineController.GetEnumValues(name), callback=self._OnControllerEnumVariable, select=value) 810 else: 811 SingleLineEditFloat(align=uiconst.CENTERRIGHT, name=name, parent=line, width=150, height=18, setvalue=str(value), OnFocusLost=self._OnControllerVariable, OnReturn=self._OnControllerVariable, sendSelfAsArgument=True) 812 Line(parent=line, align=uiconst.TOBOTTOM, opacity=0.05) 813 814 def _UpdatePlayerShip(self): 815 michelle = sm.GetService('michelle') 816 ship = michelle.GetBall(session.shipid) 817 if ship is None: 818 return 819 ship.UnfitHardpoints() 820 ship.Release() 821 while ship.model is not None: 822 blue.synchro.Yield() 823 824 ship.released = False 825 ship.GetDNA = self.GetPreviewDna 826 ship.LoadModel() 827 ship.Assemble() 828 if self.currentDirtLevel is not None: 829 ship.model.dirtLevel = self.currentDirtLevel 830 self.stateMachineController.ApplyTo(ship.model) 831 ship.model.StartControllers()