dollManager.py (18725B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\login\charcreation_new\dollManager.py 2 import telemetry 3 import blue 4 import log 5 import copy 6 import eve.client.script.ui.login.charcreation_new.ccUtil as ccUtil 7 import charactercreator.const as ccConst 8 import evegraphics.settings as gfxsettings 9 from carbonui.uicore import uicore 10 from eve.common.script.paperDoll.paperDollDefinitions import BODY_CATEGORIES, DEFAULT_NUDE_PARTS, DESIRED_ORDER, LOD_SKIN 11 CLOTHING_ITEMS = (ccConst.topouter, 12 ccConst.topmiddle, 13 ccConst.bottomouter, 14 ccConst.outer, 15 ccConst.feet, 16 ccConst.glasses, 17 ccConst.bottommiddle, 18 ccConst.mask) 19 ccDollManager = None 20 21 def GetCharacterCreationDollManager(): 22 global ccDollManager 23 if ccDollManager is None: 24 ccDollManager = CharacterCreationDollManager() 25 return ccDollManager 26 27 28 class CharacterCreationDollManager(object): 29 30 def __init__(self): 31 self.characterSvc = sm.GetService('character') 32 self.dolls = {} 33 self._setColorsByCategory = {} 34 self._setSpecularityByCategory = {} 35 self._setIntensityByCategory = {} 36 self.clothesOff = 0 37 self.clothesStorage = {} 38 self.clothesMetaStorage = {} 39 self.dnaList = None 40 self.lastLitHistoryBit = None 41 42 def TearDown(self): 43 self.dolls = {} 44 45 def GetDoll(self, charID): 46 return self.dolls.get(charID, None) 47 48 def SetDoll(self, charID, doll): 49 self.dolls[charID] = doll 50 51 @telemetry.ZONE_METHOD 52 def AddCharacter(self, charID, bloodlineID, raceID, genderID, scene = None, dna = None, validateColors = True, position = (0.0, 0.0, 0.0)): 53 self.ResetDna() 54 self.characterSvc.AddCharacterToScene(charID, scene, ccUtil.GenderIDToPaperDollGender(genderID), dna=dna, bloodlineID=bloodlineID, raceID=raceID, updateDoll=False, position=position) 55 doll = self.characterSvc.GetSingleCharactersDoll(charID) 56 self.dolls[charID] = doll 57 while doll.IsBusyUpdating(): 58 blue.synchro.Yield() 59 60 _ApplyGraphicsSettingsToDoll(doll) 61 uicore.layer.charactercreation.controller.SetBloodline(charID, bloodlineID) 62 self.characterSvc.SetDollBloodline(charID, bloodlineID) 63 if validateColors: 64 for categoryName in ccConst.COLORMAPPING.keys(): 65 self.UpdateColorSelectionFromDoll(categoryName) 66 self.ValidateColors(categoryName) 67 68 self.ClearDnaLog() 69 self.characterSvc.UpdateDoll(charID, fromWhere='AddCharacter') 70 71 def ResetDna(self, *args): 72 self.dnaList = None 73 self.lastLitHistoryBit = None 74 75 @telemetry.ZONE_METHOD 76 def ClearDnaLog(self): 77 self.dnaList = [] 78 self.lastLitHistoryBit = None 79 80 @telemetry.ZONE_METHOD 81 def ClearDnaLogFromIndex(self, fromIndex): 82 if self.dnaList: 83 to = fromIndex + 1 84 if to > len(self.dnaList): 85 to = len(self.dnaList) 86 self.dnaList = self.dnaList[:to] 87 88 @telemetry.ZONE_METHOD 89 def GetDollDNAHistory(self): 90 return self.dnaList 91 92 @telemetry.ZONE_METHOD 93 def LoadDnaFromHistory(self, historyIndex): 94 if len(self.characterSvc.characters) > 0: 95 info = uicore.layer.charactercreation.controller.GetInfo() 96 character = self.characterSvc.GetSingleCharacter(info.charID) 97 if character: 98 historyIndex = max(0, min(len(self.dnaList) - 1, historyIndex)) 99 dna, metadata = self.dnaList[historyIndex] 100 metadata = copy.deepcopy(metadata) 101 self.ToggleClothes(forcedValue=0, doUpdate=False) 102 self.characterSvc.MatchDNA(character, dna) 103 self.characterSvc.characterMetadata[info.charID] = metadata 104 if self.characterSvc.GetSculptingActive(): 105 sculpting = self.characterSvc.GetSculpting() 106 sculpting.UpdateFieldsBasedOnExistingValues(character.doll) 107 self.characterSvc.UpdateDoll(info.charID, fromWhere='LoadDnaFromHistory', registerDna=False) 108 self.characterSvc.SynchronizeHairColors(info.charID) 109 110 def TryStoreDna(self, lastUpdateRedundant, currentIndex, charID, force = 0, allowRedundant = 0): 111 if self.dnaList is not None: 112 self.CheckDnaLog() 113 dna = self.GetDNA(charID, getHiddenModifiers=False, getWeightless=True) 114 if not allowRedundant and len(self.dnaList) > 0: 115 if dna == self.dnaList[currentIndex][0]: 116 return 117 currMetadata = copy.deepcopy(self.characterSvc.characterMetadata[charID]) 118 self.dnaList.append((dna, currMetadata)) 119 if lastUpdateRedundant or force: 120 sm.ScatterEvent('OnHistoryUpdated') 121 122 @telemetry.ZONE_METHOD 123 def CheckDnaLog(self): 124 currentStep = uicore.layer.charactercreation.controller.step 125 if currentStep and currentStep.sr.historySlider: 126 currentIndex, maxIndex = currentStep.sr.historySlider.GetCurrentIndexAndMaxIndex() 127 if currentIndex != maxIndex: 128 self.ClearDnaLogFromIndex(currentIndex) 129 130 @telemetry.ZONE_METHOD 131 def GetDNA(self, charID, getHiddenModifiers = False, getWeightless = False): 132 return self.dolls[charID].GetDNA(getHiddenModifiers=getHiddenModifiers, getWeightless=getWeightless) 133 134 @telemetry.ZONE_METHOD 135 def SetItemType(self, itemType, weight = 1.0, doUpdate = True): 136 info = uicore.layer.charactercreation.controller.GetInfo() 137 category = self.characterSvc.GetCategoryFromResPath(itemType[1][0]) 138 if category in CLOTHING_ITEMS: 139 if category in self.clothesStorage: 140 self.clothesStorage.pop(category) 141 self.clothesMetaStorage.pop(category) 142 self.ToggleClothes(forcedValue=0, doUpdate=False) 143 self.characterSvc.ApplyTypeToDoll(info.charID, itemType, weight=weight, doUpdate=False) 144 if category in self._setColorsByCategory: 145 var1, var2 = self._setColorsByCategory[category] 146 self.SetColorValue(category, var1, var2, doUpdate=False) 147 self.ValidateColors(category) 148 if doUpdate: 149 self.characterSvc.UpdateDoll(info.charID, fromWhere='SetItemType') 150 151 @telemetry.ZONE_METHOD 152 def SetStyle(self, category, style, variation = None, doUpdate = True): 153 info = uicore.layer.charactercreation.controller.GetInfo() 154 if style or variation or category in CLOTHING_ITEMS: 155 self.ToggleClothes(forcedValue=0, doUpdate=False) 156 self.characterSvc.ApplyItemToDoll(info.charID, category, style, removeFirst=True, variation=variation, doUpdate=False) 157 if style: 158 if category in self._setColorsByCategory: 159 var1, var2 = self._setColorsByCategory[category] 160 self.SetColorValue(category, var1, var2, doUpdate=False) 161 self.ValidateColors(category) 162 if doUpdate: 163 self.characterSvc.UpdateDoll(info.charID, fromWhere='SetStyle') 164 165 @telemetry.ZONE_METHOD 166 def ClearCategory(self, category, doUpdate = True): 167 self.SetStyle(category, style=None, doUpdate=doUpdate) 168 169 def ToggleClothes(self, forcedValue = None, doUpdate = True, *args): 170 valueBefore = self.clothesOff 171 if forcedValue is None: 172 self.clothesOff = not self.clothesOff 173 else: 174 self.clothesOff = forcedValue 175 if valueBefore == self.clothesOff: 176 return 177 info = uicore.layer.charactercreation.controller.GetInfo() 178 if info.charID in self.characterSvc.characters: 179 character = self.characterSvc.GetSingleCharacter(info.charID) 180 if self.clothesOff: 181 self.RemoveClothes(character, info.charID, doUpdate=doUpdate) 182 else: 183 self.ReApplyClothes(character, info.charID, doUpdate=doUpdate) 184 185 @telemetry.ZONE_METHOD 186 def ReApplyClothes(self, character, charID, doUpdate = True): 187 if not self.clothesStorage or character is None: 188 return 189 doll = character.doll 190 bdm = doll.buildDataManager 191 for category in self.clothesMetaStorage: 192 self.characterSvc.SetCharacterMetadataByCategory(charID, category, self.clothesMetaStorage[category]) 193 194 modifiers = doll.SortModifiersForBatchAdding(self.clothesStorage.values()) 195 for modifier in modifiers: 196 bdm.AddModifier(modifier) 197 198 self.ResetClothesStorage() 199 if doUpdate: 200 sm.GetService('character').UpdateDollsAvatar(character) 201 202 @telemetry.ZONE_METHOD 203 def RemoveClothes(self, character, charID, doUpdate = True): 204 if self.clothesStorage or character is None: 205 return 206 categoriesToRemove = BODY_CATEGORIES - (BODY_CATEGORIES.SKIN, 207 BODY_CATEGORIES.TATTOO, 208 BODY_CATEGORIES.TOPUNDERWEAR, 209 BODY_CATEGORIES.BOTTOMUNDERWEAR, 210 BODY_CATEGORIES.SKINTONE, 211 BODY_CATEGORIES.SKINTYPE, 212 BODY_CATEGORIES.SCARS) 213 categoriesToRemove = list(categoriesToRemove) 214 categoriesToRemove.sort(key=lambda x: -DESIRED_ORDER.index(x)) 215 self.ResetClothesStorage() 216 bdm = character.doll.buildDataManager 217 for category in categoriesToRemove: 218 categoryModifiers = bdm.GetModifiersByCategory(category) 219 self.StoreCharacterMetadata(category, charID) 220 self.characterSvc.RemoveFromCharacterMetadata(charID, category) 221 for modifier in categoryModifiers: 222 if modifier.respath not in DEFAULT_NUDE_PARTS: 223 self.clothesStorage[category] = modifier 224 bdm.RemoveModifier(modifier) 225 226 modifier = self.characterSvc.GetModifierByCategory(charID, ccConst.glasses) 227 if modifier: 228 self.StoreCharacterMetadata(ccConst.glasses, charID) 229 self.characterSvc.RemoveFromCharacterMetadata(charID, ccConst.glasses) 230 self.clothesStorage[ccConst.glasses] = modifier 231 bdm.RemoveModifier(modifier) 232 modifier = self.characterSvc.GetModifierByCategory(charID, ccConst.mask) 233 if modifier: 234 self.StoreCharacterMetadata(ccConst.mask, charID) 235 self.characterSvc.RemoveFromCharacterMetadata(charID, ccConst.mask) 236 self.clothesStorage[ccConst.mask] = modifier 237 bdm.RemoveModifier(modifier) 238 if doUpdate: 239 sm.GetService('character').UpdateDollsAvatar(character) 240 241 def ResetClothesStorage(self, *args): 242 self.clothesStorage.clear() 243 self.clothesMetaStorage.clear() 244 245 def StoreCharacterMetadata(self, category, charID): 246 self.clothesMetaStorage[category] = self.characterSvc.GetCharacterMetadataByCategory(charID, category) 247 248 def UpdateColorSelectionFromDoll(self, category): 249 if category not in ccConst.COLORMAPPING: 250 return 251 info = uicore.layer.charactercreation.controller.GetInfo() 252 categoryColors = self.characterSvc.GetAvailableColorsForCategory(category, info.genderID, info.raceID) 253 if not categoryColors: 254 return 255 primary, secondary = categoryColors 256 modifier = self.characterSvc.GetModifiersByCategory(info.charID, category) 257 if modifier: 258 corPrimary = None 259 corSecondary = None 260 try: 261 chosenPrimary, chosenSecondary = self.characterSvc.GetSingleCharactersMetadata(info.charID).typeColors[category] 262 for primaryColorTuple in primary: 263 if primaryColorTuple[0] == chosenPrimary: 264 corPrimary = primaryColorTuple 265 break 266 267 if secondary and chosenSecondary: 268 for secondaryColorTuple in secondary: 269 if secondaryColorTuple[0] == chosenSecondary: 270 corSecondary = secondaryColorTuple 271 break 272 273 except KeyError: 274 log.LogWarn('KeyError when getting Metadata for a single character in UpdateColorSelectionFromDoll', info.charID, category) 275 276 if corPrimary is not None: 277 self._setColorsByCategory[category] = (corPrimary, corSecondary) 278 if category in self.characterSvc.characterMetadata[info.charID].typeWeights: 279 self._setIntensityByCategory[category] = self.characterSvc.characterMetadata[info.charID].typeWeights[category] 280 if category in self.characterSvc.characterMetadata[info.charID].typeSpecularity: 281 self._setSpecularityByCategory[category] = self.characterSvc.characterMetadata[info.charID].typeSpecularity[category] 282 283 @telemetry.ZONE_METHOD 284 def SetColorValue(self, modifier, primaryColor, secondaryColor = None, doUpdate = True, ignoreValidate = False): 285 self._setColorsByCategory[modifier] = (primaryColor, secondaryColor) 286 info = uicore.layer.charactercreation.controller.GetInfo() 287 self.characterSvc.SetColorValueByCategory(info.charID, modifier, primaryColor, secondaryColor, doUpdate=False) 288 if ccUtil.HasUserDefinedSpecularity(modifier): 289 specValue = self._setSpecularityByCategory.setdefault(modifier, 0.5) 290 self.SetColorSpecularity(modifier, specValue, doUpdate=False) 291 if ccUtil.HasUserDefinedWeight(modifier): 292 defaultIntensity = ccConst.defaultIntensity.get(modifier, 0.5) 293 intensityValue = self._setIntensityByCategory.setdefault(modifier, defaultIntensity) 294 self.SetIntensity(modifier, intensityValue, doUpdate=False) 295 if not ignoreValidate: 296 self.ValidateColors(modifier) 297 if doUpdate: 298 self.characterSvc.UpdateDoll(info.charID, fromWhere='SetColorValue') 299 300 @telemetry.ZONE_METHOD 301 def SetColorSpecularity(self, modifier, specularity, doUpdate = True): 302 self._setSpecularityByCategory[modifier] = specularity 303 info = uicore.layer.charactercreation.controller.GetInfo() 304 self.characterSvc.SetColorSpecularityByCategory(info.charID, modifier, specularity, doUpdate=doUpdate) 305 306 @telemetry.ZONE_METHOD 307 def SetIntensity(self, modifier, value, doUpdate = True): 308 info = uicore.layer.charactercreation.controller.GetInfo() 309 if modifier == ccConst.muscle: 310 self.characterSvc.SetCharacterMuscularity(info.charID, value, doUpdate=doUpdate) 311 elif modifier == ccConst.weight: 312 self.characterSvc.SetCharacterWeight(info.charID, value, doUpdate=doUpdate) 313 else: 314 self._setIntensityByCategory[modifier] = value 315 self.characterSvc.SetWeightByCategory(info.charID, modifier, value, doUpdate=doUpdate) 316 317 @telemetry.ZONE_METHOD 318 def ValidateColors(self, category): 319 if category not in ccConst.COLORMAPPING: 320 return 321 info = uicore.layer.charactercreation.controller.GetInfo() 322 categoryColors = self.characterSvc.GetAvailableColorsForCategory(category, info.genderID, info.raceID) 323 if not categoryColors: 324 return 325 primary, secondary = categoryColors 326 hasValidColor = False 327 modifier = self.characterSvc.GetModifiersByCategory(info.charID, category) 328 if modifier: 329 currentColor = modifier[0].GetColorizeData() 330 if secondary: 331 if modifier[0].metaData.numColorAreas > 1: 332 for primaryColorTuple in primary: 333 primaryColorName, primaryDisplayColor, primaryColorValue = primaryColorTuple 334 pA, pB, pC = primaryColorValue['colors'] 335 for secondaryColorTuple in secondary: 336 secondaryColorName, secondaryDisplayColor, secondaryColorValue = secondaryColorTuple 337 srA, srB, srC = secondaryColorValue['colors'] 338 if pA == currentColor[0] and srB == currentColor[1] and srC == currentColor[2]: 339 hasValidColor = True 340 if category not in self._setColorsByCategory or self._setColorsByCategory[category][1] is None: 341 self.SetColorValue(category, primaryColorTuple, secondaryColorTuple, doUpdate=False, ignoreValidate=True) 342 break 343 344 if hasValidColor: 345 break 346 347 if not hasValidColor: 348 for primaryColorTuple in primary: 349 primaryColorName, primaryDisplayColor, primaryColorValue = primaryColorTuple 350 if primaryColorValue['colors'] == currentColor: 351 hasValidColor = True 352 self.SetColorValue(category, primaryColorTuple, secondary[0], doUpdate=False, ignoreValidate=True) 353 break 354 355 else: 356 for primaryColorTuple in primary: 357 primaryColorName, primaryDisplayColor, primaryColorValue = primaryColorTuple 358 if primaryColorValue['colors'] == currentColor: 359 hasValidColor = True 360 if category not in self._setColorsByCategory: 361 self.SetColorValue(category, primaryColorTuple, None, doUpdate=False, ignoreValidate=True) 362 break 363 else: 364 if category in self._setColorsByCategory: 365 hasValidColor = True 366 else: 367 for primaryColorTuple in primary: 368 primaryColorName, primaryDisplayColor, primaryColorValue = primaryColorTuple 369 if primaryColorValue['colors'] == currentColor: 370 hasValidColor = True 371 if category not in self._setColorsByCategory: 372 self.SetColorValue(category, primaryColorTuple, None, doUpdate=False, ignoreValidate=True) 373 break 374 375 if not hasValidColor and primary: 376 if secondary: 377 var2 = secondary[0] 378 else: 379 var2 = None 380 self.SetColorValue(category, primary[0], var2, doUpdate=False, ignoreValidate=True) 381 382 383 def _ApplyGraphicsSettingsToDoll(doll): 384 doll.overrideLod = LOD_SKIN 385 textureQuality = gfxsettings.Get(gfxsettings.GFX_CHAR_TEXTURE_QUALITY) 386 doll.textureResolution = ccConst.TEXTURE_RESOLUTIONS[textureQuality] 387 if ccUtil.IsSlowMachine(): 388 doll.useFastShader = True 389 else: 390 doll.useFastShader = False