baseDogmaStaticSvc.py (13891B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\common\script\dogma\baseDogmaStaticSvc.py 2 import sys 3 import bluepy 4 import dogma.data as dogma_data 5 import evetypes 6 import telemetry 7 from carbon.common.script.sys.service import Service 8 from dogma.data import get_effects_indexed_by_effect_id_and_type_id, get_effects_indexed_by_type_id_and_effect_id 9 from eve.common.lib import appConst as const 10 from eve.common.script.sys.idCheckers import IsModule 11 from evetypes.skills import get_dogma_required_skills 12 from spacecomponents.common.helper import HasIgnoreFittingRestrictionsComponent 13 14 class BaseDogmaStaticSvc(Service): 15 __guid__ = 'svc.baseDogmaStaticSvc' 16 17 def __init__(self): 18 Service.__init__(self) 19 self.attributes = {} 20 self.attributesByName = {} 21 self.attributesByTypeAttribute = {} 22 self.effects = {} 23 self.unwantedEffects = {const.effectHiPower: True, 24 const.effectLoPower: True, 25 const.effectMedPower: True, 26 const.effectSkillEffect: True} 27 28 def Run(self, *args): 29 self.Load() 30 self._MonitorStaticDataChanges() 31 32 def _MonitorStaticDataChanges(self): 33 dogma_data.DogmaAttributes.ConnectToOnReload(self._ReloadDogmaData) 34 dogma_data.DogmaEffects.ConnectToOnReload(self._ReloadDogmaData) 35 dogma_data.TypeDogma.ConnectToOnReload(self._ReloadDogmaData) 36 37 def _ReloadDogmaData(self): 38 dogma_data.refresh_dogma() 39 self.LoadAttributes() 40 self.LoadTypeAttributes() 41 self.LoadEffects() 42 self.LoadTypeEffects(run=False) 43 44 def Load(self): 45 with bluepy.Timer('LoadAttributes'): 46 self.LoadAttributes() 47 with bluepy.Timer('LoadTypeAttributes'): 48 self.LoadTypeAttributes() 49 with bluepy.Timer('LoadEffects'): 50 self.LoadEffects() 51 with bluepy.Timer('LoadTypeEffects'): 52 self.LoadTypeEffects(run=True) 53 self.crystalGroupIDs = cfg.GetCrystalGroups() 54 self.controlBunkersByFactionID = {} 55 for typeID in evetypes.GetTypeIDsByGroup(const.groupControlBunker): 56 factionID = int(self.GetTypeAttribute2(typeID, const.attributeFactionID)) 57 self.controlBunkersByFactionID[factionID] = typeID 58 59 cgattrs = dogma_data.get_charge_group_attribute_ids() 60 self.chargeGroupAttributes = cgattrs 61 self.crystalModuleGroupIDs = {} 62 for categoryID in (const.categoryModule, const.categoryStructureModule, const.categoryStarbase): 63 for groupID in evetypes.GetGroupIDsByCategory(categoryID): 64 typeIDs = evetypes.GetTypeIDsByGroup(groupID) 65 if len(typeIDs) > 0: 66 typeID = typeIDs.pop() 67 for attributeID in cgattrs: 68 v = self.GetTypeAttribute(typeID, attributeID) 69 if v is not None and v in self.crystalGroupIDs: 70 self.crystalModuleGroupIDs[groupID] = True 71 break 72 73 def LoadAttributes(self): 74 self.attributes = dogma_data.get_all_attributes_by_id() 75 if len(self.attributes) == 0: 76 self.LogError('STATIC DATA MISSING: Dogma Attributes') 77 self.attributesByName = dogma_data.get_all_attributes_by_name() 78 self.attributesByCategory = dogma_data.get_attribute_list_by_data_type() 79 self.chargedAttributes = dogma_data.get_charge_recharge_time_attributes_by_id() 80 self.attributesRechargedByAttribute = dogma_data.get_attributes_by_charge_recharge_time_id() 81 self.attributesByIdx = {} 82 self.idxByAttribute = {} 83 self.canFitShipGroupAttributes = [] 84 self.allowedDroneGroupAttributes = [] 85 self.chargeGroupAttributes = [] 86 for att in self.attributesByCategory[const.dgmAttrCatGroup]: 87 attributeName = att.name 88 if attributeName.startswith('canFitShipGroup'): 89 self.canFitShipGroupAttributes.append(att.attributeID) 90 elif attributeName.startswith('allowedDroneGroup'): 91 self.allowedDroneGroupAttributes.append(att.attributeID) 92 elif attributeName.startswith('chargeGroup'): 93 self.chargeGroupAttributes.append(att.attributeID) 94 95 self.canFitShipTypeAttributes = [] 96 self.requiredSkillAttributes = {} 97 for att in self.attributesByCategory[const.dgmAttrCatType]: 98 attributeName = att.name 99 if attributeName == 'fitsToShipType' or attributeName.startswith('canFitShipType'): 100 self.canFitShipTypeAttributes.append(att.attributeID) 101 elif attributeName.startswith('requiredSkill'): 102 levelAttribute = self.attributesByName[attributeName + 'Level'] 103 self.requiredSkillAttributes[att.attributeID] = levelAttribute.attributeID 104 105 self.shipHardwareModifierAttribs = [(const.attributeHiSlots, const.attributeHiSlotModifier), 106 (const.attributeMedSlots, const.attributeMedSlotModifier), 107 (const.attributeLowSlots, const.attributeLowSlotModifier), 108 (const.attributeTurretSlotsLeft, const.attributeTurretHardpointModifier), 109 (const.attributeLauncherSlotsLeft, const.attributeLauncherHardPointModifier)] 110 self.resistanceAttributesByLayer = {} 111 for attributeID, layerName, hpAttributeID, uniformityAttributeID in ((const.attributeShieldCharge, 112 'Shield', 113 const.attributeShieldCapacity, 114 const.attributeShieldUniformity), (const.attributeArmorDamage, 115 'Armor', 116 const.attributeArmorHP, 117 const.attributeArmorUniformity), (const.attributeDamage, 118 '', 119 const.attributeHp, 120 const.attributeStructureUniformity)): 121 self.resistanceAttributesByLayer[attributeID] = [ getattr(const, 'attribute%s%s' % (layerName, resName)) for resName in ('EmDamageResonance', 'ExplosiveDamageResonance', 'KineticDamageResonance', 'ThermalDamageResonance') ] 122 123 self.damageAttributes = (const.attributeEmDamage, 124 const.attributeExplosiveDamage, 125 const.attributeKineticDamage, 126 const.attributeThermalDamage) 127 self.damageStateAttributes = (const.attributeDamage, const.attributeArmorDamage, const.attributeShieldCharge) 128 self.layerResAttributesByDamage = {} 129 for layerAttributeID, resAttribs in self.resistanceAttributesByLayer.iteritems(): 130 self.layerResAttributesByDamage[layerAttributeID] = zip(self.damageAttributes, resAttribs) 131 132 def LoadEffects(self): 133 self.effects = dogma_data.get_all_effects_by_id() 134 if len(self.effects) == 0: 135 self.LogError('STATIC DATA MISSING: Dogma Effects') 136 self.effectsByName = dogma_data.get_all_effects_by_name() 137 138 def LoadTypeEffects(self, run = False): 139 self.effectsByType = get_effects_indexed_by_type_id_and_effect_id() 140 self.typesByEffect = get_effects_indexed_by_effect_id_and_type_id() 141 self.passiveFilteredEffectsByType = {} 142 for typeID in self.effectsByType.iterkeys(): 143 passiveEffects = [] 144 for effectID in self.effectsByType[typeID].iterkeys(): 145 if effectID in self.unwantedEffects: 146 continue 147 effect = self.effects[effectID] 148 if effect.effectCategory in [const.dgmEffPassive, const.dgmEffSystem]: 149 passiveEffects.append(effectID) 150 151 if len(passiveEffects): 152 self.passiveFilteredEffectsByType[typeID] = passiveEffects 153 154 defaultEffect = {} 155 for typeID2, effects in dogma_data.get_all_type_ids_and_effects(): 156 for effect in effects: 157 if effect.isDefault: 158 defaultEffect[typeID2] = effect.effectID 159 160 self.defaultEffectByType = defaultEffect 161 162 def LoadAllTypeAttributes(self): 163 raise NotImplementedError('LoadAllTypeAttributes - not implemented') 164 165 def LoadSpecificTypeAttributes(self, typeID, attributeID, newRow): 166 raise NotImplementedError('LoadSpecificTypeAttributes - not implemented') 167 168 def LoadTypeAttributes(self, typeID = None, attributeID = None, newRow = None): 169 if typeID is None: 170 self.LoadAllTypeAttributes() 171 else: 172 self.LoadSpecificTypeAttributes(typeID, attributeID, newRow) 173 174 def GetTypeAttribute(self, typeID, attributeID, defaultValue = None): 175 return dogma_data.get_type_attribute(typeID, attributeID, defaultValue) 176 177 def GetTypeAttribute2(self, typeID, attributeID): 178 try: 179 return self.attributesByTypeAttribute[typeID][attributeID] 180 except KeyError: 181 return self.attributes[attributeID].defaultValue 182 183 def GetTypeAttributes(self, typeID): 184 try: 185 return self.attributesByTypeAttribute[typeID] 186 except KeyError: 187 return {} 188 189 @telemetry.ZONE_METHOD 190 def GetRequiredSkills(self, typeID): 191 return get_dogma_required_skills(typeID) 192 193 def GetEffect(self, effectID): 194 return self.effects[effectID] 195 196 def GetEffectTypes(self): 197 return self.effects 198 199 def GetEffectType(self, effectID): 200 return self.effects[effectID] 201 202 def GetAttributeType(self, attributeID): 203 if isinstance(attributeID, str): 204 return self.attributesByName[attributeID] 205 return self.attributes[attributeID] 206 207 def GetAttributeByName(self, attributeName): 208 ret = self.attributesByName[attributeName] 209 return ret.attributeID 210 211 def TypeHasAttribute(self, typeID, attributeID): 212 return typeID in self.attributesByTypeAttribute and attributeID in self.attributesByTypeAttribute[typeID] 213 214 def TypeGetOrderedEffectIDs(self, typeID, categoryID = None): 215 return self.effectsByType[typeID].iterkeys() 216 217 def TypeGetEffects(self, typeID): 218 return self.effectsByType.get(typeID, {}) 219 220 def TypeExists(self, typeID): 221 return typeID in self.attributesByTypeAttribute 222 223 def TypeHasEffect(self, typeID, effectID): 224 return typeID in self.effectsByType and effectID in self.effectsByType[typeID] 225 226 def GetAttributesByCategory(self, categoryID): 227 return self.attributesByCategory.get(categoryID, []) 228 229 def EffectGetTypes(self, effectID): 230 return self.typesByEffect.get(effectID, {}) 231 232 def EffectGetModuleGroups(self, effectID): 233 moduleGroups = [] 234 for typeID in self.typesByEffect.get(effectID, {}): 235 categoryID = evetypes.GetCategoryID(typeID) 236 if IsModule(categoryID): 237 groupID = evetypes.GetGroupID(typeID) 238 if groupID not in moduleGroups: 239 moduleGroups.append(groupID) 240 241 return moduleGroups 242 243 def AttributeGetTypes(self, attributeID): 244 return self.typesByAttribute.get(attributeID, {}) 245 246 def GetCanFitShipGroups(self, typeID): 247 rtn = [] 248 for att in self.canFitShipGroupAttributes: 249 try: 250 rtn.append(self.attributesByTypeAttribute[typeID][att]) 251 except KeyError: 252 sys.exc_clear() 253 254 return rtn 255 256 def GetChargeGroupAttributes(self): 257 return self.chargeGroupAttributes 258 259 def GetCanFitShipTypes(self, typeID): 260 rtn = [] 261 for att in self.canFitShipTypeAttributes: 262 try: 263 rtn.append(self.attributesByTypeAttribute[typeID][att]) 264 except KeyError: 265 sys.exc_clear() 266 267 return rtn 268 269 def CanFitModuleToShipTypeOrGroup(self, moduleTypeID, shipTypeID, shipGroupID): 270 canFitShipGroups = self.GetCanFitShipGroups(moduleTypeID) 271 canFitShipTypes = self.GetCanFitShipTypes(moduleTypeID) 272 if HasIgnoreFittingRestrictionsComponent(shipTypeID): 273 return True 274 if not canFitShipGroups and not canFitShipTypes: 275 return True 276 if canFitShipGroups and shipGroupID in canFitShipGroups: 277 return True 278 if canFitShipTypes and shipTypeID in canFitShipTypes: 279 return True 280 return False 281 282 def GetAllowedDroneGroups(self, typeID): 283 groups = [] 284 attributes = self.attributesByTypeAttribute.get(typeID) 285 if attributes: 286 for attributeID in self.allowedDroneGroupAttributes: 287 value = attributes.get(attributeID) 288 if value: 289 groups.append(int(value)) 290 291 return groups 292 293 def GetDefaultEffect(self, typeID): 294 return self.defaultEffectByType[typeID] 295 296 def GetShipHardwareModifierAttribs(self): 297 return self.shipHardwareModifierAttribs 298 299 def GetValidChargeGroupsForType(self, typeID): 300 ret = set() 301 for attributeID in self.chargeGroupAttributes: 302 try: 303 ret.add(int(self.GetTypeAttribute(typeID, attributeID))) 304 except TypeError: 305 pass 306 307 return ret 308 309 def GetSkillModifiedAttributePercentageValue(self, attributeID, modifyingAttributeID, skillTypeID, skillRecord = None): 310 percentageMod = 1.0 311 skillLevel = 0 312 if skillRecord: 313 skillLevel = skillRecord.effectiveSkillLevel 314 try: 315 percentageMod = (100 + self.GetTypeAttribute(skillTypeID, modifyingAttributeID, None) * skillLevel) / 100.0 316 except TypeError as e: 317 self.LogError('dogmaStaticMgr::GetSkillModifiedAttributePercentageValue.Failed calculating modification! %s' % e) 318 percentageMod = 1.0 319 320 if not 0.0 <= percentageMod <= 1.0: 321 self.LogError('dogmaStaticMgr::GetSkillModifiedAttributePercentageValue.Value %s not a percentile!' % percentageMod) 322 percentageMod = 1.0 323 return percentageMod 324 325 def GetPassiveFilteredEffectsByType(self, typeID): 326 return self.passiveFilteredEffectsByType.get(typeID, [])