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

characterDollUtilities.py (12903B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\charactercreator\client\characterDollUtilities.py
      2 from __future__ import print_function
      3 import charactercreator.const as ccConst
      4 from eve.common.script.paperDoll.paperDollDefinitions import BODY_CATEGORIES, GENDER, HAIR_CATEGORIES, SEPERATOR_CHAR
      5 from utillib import KeyVal
      6 
      7 class CharacterDollUtilities:
      8 
      9     def __init__(self):
     10         self.modifierLocationsByName = {}
     11         self.modifierLocationsByKey = {}
     12         self.assetsToIDs = {'male': None,
     13          'female': None}
     14 
     15     def GetNewCharacterMetadata(self, genderID, bloodlineID):
     16         return KeyVal(genderID=genderID, bloodlineID=bloodlineID, types={}, typeColors={}, typeWeights={}, typeSpecularity={}, hairDarkness=0.0)
     17 
     18     def RemoveFromCharacterMetadata(self, metadata, category):
     19         if category in metadata.types:
     20             metadata.types.pop(category, None)
     21             metadata.typeColors.pop(category, None)
     22             metadata.typeSpecularity.pop(category, None)
     23             metadata.typeWeights.pop(category, None)
     24 
     25     def SetColorSpecularityByCategory(self, doll, category, specularity, doUpdate = True, metadata = None):
     26         modifier = self.GetModifierByCategory(doll, category)
     27         if modifier:
     28             metadata.typeSpecularity[category] = specularity
     29             m1 = 1.0 + 0.4 * specularity
     30             s1 = 0.5 + 0.3 * specularity
     31             s2 = 0.5 - 0.2 * specularity
     32             modifier.SetColorVariationSpecularity([(s1,
     33               s1,
     34               s1,
     35               m1), (s2,
     36               s2,
     37               s2,
     38               1.0), (0.5, 0.5, 0.5, 1.0)])
     39 
     40     def GetModifierByCategory(self, doll, category, getAll = False):
     41         modifiers = self.GetModifiersByCategory(doll, category)
     42         if not modifiers:
     43             return None
     44         elif getAll:
     45             return modifiers
     46         else:
     47             if category == HAIR_CATEGORIES.BEARD:
     48                 for modifier in modifiers:
     49                     if modifier.name != 'stubble':
     50                         return modifier
     51 
     52             return modifiers[0]
     53 
     54     def GetModifiersByCategory(self, doll, category):
     55         ret = []
     56         mods = doll.buildDataManager.GetModifiersAsList(includeFuture=True)
     57         for m in mods:
     58             resPath = m.GetResPath()
     59             resPathSplit = resPath.split('/')
     60             categSplit = category.split('/')
     61             match = True
     62             for i, each in enumerate(categSplit):
     63                 if not (len(resPathSplit) > i and resPathSplit[i] == each):
     64                     match = False
     65                     break
     66 
     67             if match:
     68                 ret.append(m)
     69 
     70         return ret
     71 
     72     def ApplyTypeToDoll(self, itemType, weight = 1.0, doUpdate = True, rawColorVariation = None, metadata = None, factory = None, doll = None):
     73         assetTypeID = None
     74         if itemType is None:
     75             return
     76         import eve.client.script.ui.login.charcreation.ccUtil as ccUtil
     77         self.PopulateModifierLocationDicts()
     78         genderID = metadata.genderID
     79         if type(itemType) is not tuple:
     80             charGender = ccUtil.GenderIDToPaperDollGender(genderID)
     81             itemTypeData = factory.GetItemType(itemType, gender=charGender)
     82             if itemTypeData is None:
     83                 itemTypeLower = itemType.lower()
     84                 if BODY_CATEGORIES.TOPINNER in itemTypeLower:
     85                     self.ApplyItemToDoll(BODY_CATEGORIES.TOPINNER, None, removeFirst=True, doUpdate=False, doll=doll, metadata=metadata, factory=factory)
     86                 elif BODY_CATEGORIES.BOTTOMINNER in itemTypeLower:
     87                     self.ApplyItemToDoll(BODY_CATEGORIES.BOTTOMINNER, None, removeFirst=True, doUpdate=False, doll=doll, metadata=metadata, factory=factory)
     88                 else:
     89                     print("Item type file is missing, can't be loaded %s" % str(itemType))
     90                 return
     91             assetID, assetTypeID = self.GetAssetAndTypeIDsFromPath(charGender, itemType)
     92             itemType = (assetID, itemTypeData[:3], assetTypeID)
     93         category = self.GetCategoryFromResPath(itemType[1][0])
     94         modifierLocationKey = self.modifierLocationsByName.get(category, None)
     95         toRemove = []
     96         for otherCategory, otherResourceID in metadata.types.iteritems():
     97             if otherResourceID is None:
     98                 continue
     99             otherResource = cfg.paperdollResources.Get(otherResourceID)
    100             if otherResource.typeID is None:
    101                 continue
    102             if otherResource.clothingRemovesCategory == modifierLocationKey:
    103                 toRemove.append(otherCategory)
    104 
    105         for itemToRemove in toRemove:
    106             self.ApplyItemToDoll(itemToRemove, None, removeFirst=True, doUpdate=False)
    107 
    108         activeMod = self.GetModifierByCategory(doll, category)
    109         if activeMod:
    110             doll.RemoveResource(activeMod.GetResPath(), factory)
    111         modifier = doll.AddItemType(factory, itemType[1], weight, rawColorVariation)
    112         metadata.types[category] = itemType[0]
    113         myTypeID = itemType[2]
    114         if myTypeID:
    115             removesCategory = cfg.paperdollResources.Get(itemType[0]).clothingRemovesCategory
    116             if removesCategory:
    117                 modifierLocationName = self.modifierLocationsByKey[int(removesCategory)]
    118                 self.ApplyItemToDoll(modifierLocationName, None, removeFirst=True, doUpdate=False, doll=doll, metadata=metadata, factory=factory)
    119         if ccUtil.HasUserDefinedWeight(category):
    120             metadata.typeWeights[category] = weight
    121         if category in (ccConst.hair, ccConst.beard, ccConst.eyebrows) and assetTypeID is None:
    122             self.SynchronizeHairColors(metadata, doll)
    123         return modifier
    124 
    125     def PopulateModifierLocationDicts(self, force = False):
    126         if not force and len(self.modifierLocationsByKey) > 0:
    127             return
    128         self.modifierLocationsByName = {}
    129         self.modifierLocationsByKey = {}
    130         for row in cfg.paperdollModifierLocations:
    131             self.modifierLocationsByKey[row.modifierLocationID] = row.modifierKey
    132             self.modifierLocationsByName[row.modifierKey] = row.modifierLocationID
    133 
    134     def ApplyItemToDoll(self, category, name, removeFirst = False, variation = None, doUpdate = True, doll = None, metadata = None, factory = None):
    135         modifier = None
    136         modifierFoundForVariationSwitch = False
    137         if name and variation:
    138             modifier = self.GetModifierByCategory(doll, category)
    139             if modifier and modifier.name.split(SEPERATOR_CHAR)[-1] == name:
    140                 modifier.SetVariation(variation)
    141                 modifierFoundForVariationSwitch = True
    142         if not modifierFoundForVariationSwitch:
    143             if removeFirst:
    144                 if name:
    145                     modifier = self.GetModifierByCategory(doll, category)
    146                     if modifier:
    147                         self.RemoveFromCharacterMetadata(metadata, category)
    148                         doll.RemoveResource(modifier.respath, factory)
    149                 else:
    150                     modifiers = self.GetModifierByCategory(doll, category, getAll=True)
    151                     if modifiers:
    152                         self.RemoveFromCharacterMetadata(metadata, category)
    153                         for modifier in modifiers:
    154                             doll.RemoveResource(modifier.respath, factory)
    155 
    156             if name:
    157                 modifier = doll.AddResource(category + '/' + name, 1.0, factory, variation=variation)
    158             elif not removeFirst:
    159                 modifier = self.GetModifierByCategory(doll, category)
    160                 if modifier:
    161                     self.RemoveFromCharacterMetadata(metadata, category)
    162                     doll.RemoveResource(modifier.GetResPath(), factory)
    163         return modifier
    164 
    165     def SynchronizeHairColors(self, metadata, doll):
    166         import geo2
    167         hairData = self.GetModifierByCategory(doll, ccConst.hair)
    168         if hairData is not None:
    169             colorizeData = hairData.colorizeData
    170             orgA, orgB, orgC = colorizeData
    171             newA = geo2.Vector(*orgA)
    172             lowA = newA * 0.2
    173             newA = geo2.Vec4Lerp(lowA, newA, metadata.hairDarkness)
    174             adjustedColor = (newA, orgB, orgC)
    175             for hairModifier in (ccConst.beard, ccConst.eyebrows):
    176                 if hairModifier == ccConst.beard:
    177                     hms = self.GetModifierByCategory(doll, hairModifier, getAll=True)
    178                 else:
    179                     hms = [self.GetModifierByCategory(doll, hairModifier)]
    180                 if hms is None:
    181                     continue
    182                 for hm in hms:
    183                     if hm:
    184                         hm.colorizeData = adjustedColor
    185                         hm.pattern = hairData.pattern
    186                         hm.patternData = hairData.patternData
    187                         hm.specularColorData = hairData.specularColorData
    188                         hm.SetColorVariation('none')
    189 
    190     def SetColorValueByCategory(self, doll, metadata, category, colorVar1, colorVar2, doUpdate = True):
    191         if colorVar1 is None:
    192             return
    193         color1Value, color1Name, color2Name, variation = self.GetColorsToUse(colorVar1, colorVar2)
    194         modifier = self.GetModifierByCategory(doll, category)
    195         if not modifier:
    196             return
    197         if color1Value:
    198             metadata.typeColors[category] = (color1Name, None)
    199             modifier.SetColorizeData(color1Value)
    200         elif colorVar2 is not None:
    201             metadata.typeColors[category] = (color1Name, color2Name)
    202             modifier.SetColorVariationDirectly(variation)
    203         else:
    204             metadata.typeColors[category] = (color1Name, None)
    205             modifier.SetColorVariationDirectly(variation)
    206         if category == ccConst.hair:
    207             self.SynchronizeHairColors(metadata, doll)
    208 
    209     def GetColorsToUse(self, colorVar1, colorVar2, *args):
    210         if colorVar1 is None:
    211             return (None, None, None, None)
    212         if len(colorVar1) == 3:
    213             colorVar1 = (colorVar1[0], colorVar1[2])
    214         if colorVar2 is not None and len(colorVar2) == 3:
    215             colorVar2 = (colorVar2[0], colorVar2[2])
    216         color1Name, color1Value = colorVar1
    217         import types
    218         if type(color1Value) == types.TupleType:
    219             return (color1Value,
    220              color1Name,
    221              None,
    222              None)
    223         elif colorVar2 is not None:
    224             color2Name, color2Value = colorVar2
    225             variation = {}
    226             if color1Value:
    227                 if color2Value and 'colors' in color1Value:
    228                     variation['colors'] = [color1Value['colors'][0], color2Value['colors'][1], color2Value['colors'][2]]
    229                 if 'pattern' in color1Value:
    230                     variation['pattern'] = color1Value['pattern']
    231                 if color2Value and 'patternColors' in color1Value:
    232                     variation['patternColors'] = [color1Value['patternColors'][0], color2Value['patternColors'][1], color2Value['patternColors'][2]]
    233                 if 'patternColors' in color1Value:
    234                     variation['patternColors'] = color1Value['patternColors']
    235                 if color2Value and 'specularColors' in color1Value:
    236                     variation['specularColors'] = [color1Value['specularColors'][0], color2Value['specularColors'][1], color2Value['specularColors'][2]]
    237             return (None,
    238              color1Name,
    239              color2Name,
    240              variation)
    241         else:
    242             return (None,
    243              color1Name,
    244              None,
    245              color1Value)
    246 
    247     def GetAssetAndTypeIDsFromPath(self, gender, assetPath):
    248         if self.assetsToIDs[gender] is None:
    249             self.assetsToIDs[gender] = {}
    250             for row in cfg.paperdollResources:
    251                 if row.resGender == (gender == GENDER.MALE):
    252                     self.assetsToIDs[gender][self.GetRelativePath(row.resPath).lower()] = (row.paperdollResourceID, row.typeID)
    253 
    254         assetPath = self.GetRelativePath(assetPath).lower()
    255         if assetPath in self.assetsToIDs[gender]:
    256             return self.assetsToIDs[gender][assetPath]
    257         else:
    258             return (None, None)
    259 
    260     def GetRelativePath(self, resPath):
    261         if resPath.lower().startswith('res:'):
    262             for chopPart in ['Modular/Female/',
    263              'Modular/Male/',
    264              'Female/Paperdoll/',
    265              'Male/Paperdoll/',
    266              'modular/female/',
    267              'modular/male/',
    268              'female/paperdoll/',
    269              'male/paperdoll/']:
    270                 startPos = resPath.find(chopPart)
    271                 if startPos != -1:
    272                     chopTo = len(chopPart) + startPos
    273                     resPath = resPath[chopTo:]
    274 
    275         return resPath
    276 
    277     def GetCategoryFromResPath(self, resPath):
    278         parts = resPath.split('/')
    279         return '/'.join(parts[:-1])