def LoadEffects(self): self.effects = IndexedRows(cfg.dgmeffects.data.itervalues(), ('effectID', )) if len(self.effects) == 0: self.LogError('STATIC DATA MISSING: Dogma Effects') self.effectsByName = IndexedRows(cfg.dgmeffects.data.itervalues(), ('effectName', ))
def LoadTypeEffects(self, typeID = None, effectID = None, newRow = None, run = False): if typeID is None: rs = [] for typeValues in cfg.dgmtypeeffects.values(): rs.extend(typeValues) if len(rs) == 0: self.LogError('STATIC DATA MISSING: Dogma Type Effects') self.effectsByType = IndexedRows(rs, ('typeID', 'effectID')) self.typesByEffect = IndexedRows(rs, ('effectID', 'typeID')) else: self.RefreshTwoKeyIndexedRows(self.effectsByType, typeID, effectID, newRow) self.RefreshTwoKeyIndexedRows(self.typesByEffect, effectID, typeID, newRow) self.passiveFilteredEffectsByType = {} for typeID in self.effectsByType.iterkeys(): passiveEffects = [] for effectID in self.effectsByType[typeID].iterkeys(): if self.unwantedEffects.has_key(effectID): continue effect = self.effects[effectID] if effect.effectCategory in [const.dgmEffPassive, const.dgmEffSystem]: passiveEffects.append(effectID) if len(passiveEffects): self.passiveFilteredEffectsByType[typeID] = passiveEffects defaultEffect = {} for typeID2 in cfg.dgmtypeeffects: for r in cfg.dgmtypeeffects[typeID2]: if r.isDefault == 1: defaultEffect[typeID2] = r.effectID self.defaultEffectByType = defaultEffect
def RefreshTwoKeyIndexedRows(self, ir, keyID, keyID2, newRow): if keyID in ir: ir2 = ir[keyID] if keyID2 in ir2: del ir2[keyID2] if newRow: if keyID in ir: ir2 = ir[keyID] else: ir2 = IndexedRows() ir[keyID] = ir2 ir2[keyID2] = newRow
def LoadTypeEffects(self, typeID = None, effectID = None, newRow = None, run = False): if typeID is None: rs = [] for key, r in cfg.dgmtypeeffects.iteritems(): if evetypes.Exists(key): rs.extend(r) else: self.LogWarn('Dogma effect assigned to a type that does not exist in this branch. typeID:' + str(key)) if len(rs) == 0: self.LogError('STATIC DATA MISSING: Dogma Type Effects') self.effectsByType = IndexedRows(rs, ('typeID', 'effectID')) self.typesByEffect = IndexedRows(rs, ('effectID', 'typeID')) else: self.RefreshTwoKeyIndexedRows(self.effectsByType, typeID, effectID, newRow) self.RefreshTwoKeyIndexedRows(self.typesByEffect, effectID, typeID, newRow) self.passiveFilteredEffectsByType = {} for typeID in self.effectsByType.iterkeys(): passiveEffects = [] for effectID in self.effectsByType[typeID].iterkeys(): if self.unwantedEffects.has_key(effectID): continue effect = self.effects[effectID] if effect.effectCategory in [const.dgmEffPassive, const.dgmEffSystem]: passiveEffects.append(effectID) if len(passiveEffects): self.passiveFilteredEffectsByType[typeID] = passiveEffects defaultEffect = {} for typeID2 in cfg.dgmtypeeffects: if evetypes.Exists(typeID2): for r in cfg.dgmtypeeffects[typeID2]: if r.isDefault == 1: defaultEffect[typeID2] = r.effectID self.defaultEffectByType = defaultEffect
def LoadAttributes(self): self.attributes = IndexedRows(cfg.dgmattribs.data.itervalues(), ('attributeID',)) if len(self.attributes) == 0: self.LogError('STATIC DATA MISSING: Dogma Attributes') self.attributesByName = IndexedRows(cfg.dgmattribs.data.itervalues(), ('attributeName',)) self.attributesByCategory = IndexedRowLists(cfg.dgmattribs.data.itervalues(), ('attributeCategory',)) chargedAttributes = [] for att in self.attributes.itervalues(): if att.chargeRechargeTimeID and att.attributeCategory != 8: chargedAttributes.append(att) self.chargedAttributes = IndexedRows(chargedAttributes, ('attributeID',)) self.attributesRechargedByAttribute = IndexedRowLists(chargedAttributes, ('chargeRechargeTimeID',)) self.attributesCappedByAttribute = IndexedRowLists(chargedAttributes, ('maxAttributeID',)) self.attributesByIdx = {} self.idxByAttribute = {} self.canFitShipGroupAttributes = [] self.allowedDroneGroupAttributes = [] self.chargeGroupAttributes = [] for att in self.attributesByCategory[const.dgmAttrCatGroup]: if att.attributeName.startswith('canFitShipGroup'): self.canFitShipGroupAttributes.append(att.attributeID) elif att.attributeName.startswith('allowedDroneGroup'): self.allowedDroneGroupAttributes.append(att.attributeID) elif att.attributeName.startswith('chargeGroup'): self.chargeGroupAttributes.append(att.attributeID) self.canFitShipTypeAttributes = [] self.requiresSovUpgrade = [] self.requiredSkillAttributes = {} for att in self.attributesByCategory[const.dgmAttrCatType]: if att.attributeName.startswith('canFitShipType'): self.canFitShipTypeAttributes.append(att.attributeID) elif att.attributeName.startswith('anchoringRequiresSovUpgrade'): self.requiresSovUpgrade.append(att.attributeID) elif att.attributeName.startswith('requiredSkill'): levelAttribute = self.attributesByName[att.attributeName + 'Level'] self.requiredSkillAttributes[att.attributeID] = levelAttribute.attributeID self.shipHardwareModifierAttribs = [(const.attributeHiSlots, const.attributeHiSlotModifier), (const.attributeMedSlots, const.attributeMedSlotModifier), (const.attributeLowSlots, const.attributeLowSlotModifier), (const.attributeTurretSlotsLeft, const.attributeTurretHardpointModifier), (const.attributeLauncherSlotsLeft, const.attributeLauncherHardPointModifier)] self.mirroredAttributes = set() for r in self.attributesByCategory.get(9, []): if r.attributeID != const.attributeRaceID: self.mirroredAttributes.add(r.attributeID) self.resistanceAttributesByLayer = {} for attributeID, layerName, hpAttributeID, uniformityAttributeID in ((const.attributeShieldCharge, 'Shield', const.attributeShieldCapacity, const.attributeShieldUniformity), (const.attributeArmorDamage, 'Armor', const.attributeArmorHP, const.attributeArmorUniformity), (const.attributeDamage, '', const.attributeHp, const.attributeStructureUniformity)): self.resistanceAttributesByLayer[attributeID] = [ getattr(const, 'attribute%s%s' % (layerName, resName)) for resName in ('EmDamageResonance', 'ExplosiveDamageResonance', 'KineticDamageResonance', 'ThermalDamageResonance') ] self.damageAttributes = (const.attributeEmDamage, const.attributeExplosiveDamage, const.attributeKineticDamage, const.attributeThermalDamage) self.damageStateAttributes = (const.attributeDamage, const.attributeArmorDamage, const.attributeShieldCharge) self.layerResAttributesByDamage = {} for layerAttributeID, resAttribs in self.resistanceAttributesByLayer.iteritems(): self.layerResAttributesByDamage[layerAttributeID] = zip(self.damageAttributes, resAttribs)
class BaseDogmaStaticSvc(service.Service): __guid__ = 'svc.baseDogmaStaticSvc' __notifyevents__ = ['OnCfgRevisionChange'] def __init__(self): service.Service.__init__(self) self.attributes = {} self.attributesByName = {} self.attributesByTypeAttribute = {} self.effects = {} self.requiredSkills = {} self.unwantedEffects = {const.effectHiPower: True, const.effectLoPower: True, const.effectMedPower: True, const.effectSkillEffect: True} def Run(self, *args): self.Load() def OnCfgRevisionChange(self, uniqueRefName, cfgEntryName, cacheID, keyIDs, keyCols, oldRow, newRow): keyID, keyID2, keyID3 = keyIDs if cacheID == const.cacheDogmaAttributes: self.LoadAttributes() elif cacheID == const.cacheDogmaEffects: self.LoadEffects() elif cacheID == const.cacheDogmaTypeAttributes: self.LoadTypeAttributes(keyID, keyID2, newRow) elif cacheID == const.cacheDogmaTypeEffects: self.LoadTypeEffects(keyID, keyID2, newRow) def RefreshTwoKeyIndexedRows(self, ir, keyID, keyID2, newRow): if keyID in ir: ir2 = ir[keyID] if keyID2 in ir2: del ir2[keyID2] if newRow: if keyID in ir: ir2 = ir[keyID] else: ir2 = IndexedRows() ir[keyID] = ir2 ir2[keyID2] = newRow def Load(self): with bluepy.Timer('LoadAttributes'): self.LoadAttributes() with bluepy.Timer('LoadTypeAttributes'): self.LoadTypeAttributes() with bluepy.Timer('LoadEffects'): self.LoadEffects() with bluepy.Timer('LoadTypeEffects'): self.LoadTypeEffects(run=True) self.crystalGroupIDs = cfg.GetCrystalGroups() self.controlBunkersByFactionID = {} for typeID in evetypes.GetTypeIDsByGroup(const.groupControlBunker): factionID = int(self.GetTypeAttribute2(typeID, const.attributeFactionID)) self.controlBunkersByFactionID[factionID] = typeID import re cgre = re.compile('chargeGroup\\d{1,2}') cgattrs = tuple([ a.attributeID for a in cfg.dgmattribs if cgre.match(a.attributeName) is not None ]) self.chargeGroupAttributes = cgattrs self.crystalModuleGroupIDs = {} for groupID in (const.categoryModule, const.categoryStarbase): for grpID in evetypes.GetGroupIDsByCategory(groupID): typeIDs = evetypes.GetTypeIDsByGroup(grpID) if len(typeIDs) > 0: typeID = typeIDs.pop() for attributeID in cgattrs: v = self.GetTypeAttribute(typeID, attributeID) if v is not None and v in self.crystalGroupIDs: self.crystalModuleGroupIDs[grpID] = True break def LoadAttributes(self): self.attributes = IndexedRows(cfg.dgmattribs.data.itervalues(), ('attributeID',)) if len(self.attributes) == 0: self.LogError('STATIC DATA MISSING: Dogma Attributes') self.attributesByName = IndexedRows(cfg.dgmattribs.data.itervalues(), ('attributeName',)) self.attributesByCategory = IndexedRowLists(cfg.dgmattribs.data.itervalues(), ('attributeCategory',)) chargedAttributes = [] for att in self.attributes.itervalues(): if att.chargeRechargeTimeID and att.attributeCategory != 8: chargedAttributes.append(att) self.chargedAttributes = IndexedRows(chargedAttributes, ('attributeID',)) self.attributesRechargedByAttribute = IndexedRowLists(chargedAttributes, ('chargeRechargeTimeID',)) self.attributesCappedByAttribute = IndexedRowLists(chargedAttributes, ('maxAttributeID',)) self.attributesByIdx = {} self.idxByAttribute = {} self.canFitShipGroupAttributes = [] self.allowedDroneGroupAttributes = [] self.chargeGroupAttributes = [] for att in self.attributesByCategory[const.dgmAttrCatGroup]: if att.attributeName.startswith('canFitShipGroup'): self.canFitShipGroupAttributes.append(att.attributeID) elif att.attributeName.startswith('allowedDroneGroup'): self.allowedDroneGroupAttributes.append(att.attributeID) elif att.attributeName.startswith('chargeGroup'): self.chargeGroupAttributes.append(att.attributeID) self.canFitShipTypeAttributes = [] self.requiresSovUpgrade = [] self.requiredSkillAttributes = {} for att in self.attributesByCategory[const.dgmAttrCatType]: if att.attributeName.startswith('canFitShipType'): self.canFitShipTypeAttributes.append(att.attributeID) elif att.attributeName.startswith('anchoringRequiresSovUpgrade'): self.requiresSovUpgrade.append(att.attributeID) elif att.attributeName.startswith('requiredSkill'): levelAttribute = self.attributesByName[att.attributeName + 'Level'] self.requiredSkillAttributes[att.attributeID] = levelAttribute.attributeID self.shipHardwareModifierAttribs = [(const.attributeHiSlots, const.attributeHiSlotModifier), (const.attributeMedSlots, const.attributeMedSlotModifier), (const.attributeLowSlots, const.attributeLowSlotModifier), (const.attributeTurretSlotsLeft, const.attributeTurretHardpointModifier), (const.attributeLauncherSlotsLeft, const.attributeLauncherHardPointModifier)] self.mirroredAttributes = set() for r in self.attributesByCategory.get(9, []): if r.attributeID != const.attributeRaceID: self.mirroredAttributes.add(r.attributeID) self.resistanceAttributesByLayer = {} for attributeID, layerName, hpAttributeID, uniformityAttributeID in ((const.attributeShieldCharge, 'Shield', const.attributeShieldCapacity, const.attributeShieldUniformity), (const.attributeArmorDamage, 'Armor', const.attributeArmorHP, const.attributeArmorUniformity), (const.attributeDamage, '', const.attributeHp, const.attributeStructureUniformity)): self.resistanceAttributesByLayer[attributeID] = [ getattr(const, 'attribute%s%s' % (layerName, resName)) for resName in ('EmDamageResonance', 'ExplosiveDamageResonance', 'KineticDamageResonance', 'ThermalDamageResonance') ] self.damageAttributes = (const.attributeEmDamage, const.attributeExplosiveDamage, const.attributeKineticDamage, const.attributeThermalDamage) self.damageStateAttributes = (const.attributeDamage, const.attributeArmorDamage, const.attributeShieldCharge) self.layerResAttributesByDamage = {} for layerAttributeID, resAttribs in self.resistanceAttributesByLayer.iteritems(): self.layerResAttributesByDamage[layerAttributeID] = zip(self.damageAttributes, resAttribs) def LoadEffects(self): self.effects = IndexedRows(cfg.dgmeffects.data.itervalues(), ('effectID',)) if len(self.effects) == 0: self.LogError('STATIC DATA MISSING: Dogma Effects') self.effectsByName = IndexedRows(cfg.dgmeffects.data.itervalues(), ('effectName',)) def LoadTypeEffects(self, typeID = None, effectID = None, newRow = None, run = False): if typeID is None: rs = [] for key, r in cfg.dgmtypeeffects.iteritems(): if evetypes.Exists(key): rs.extend(r) else: self.LogWarn('Dogma effect assigned to a type that does not exist in this branch. typeID:' + str(key)) if len(rs) == 0: self.LogError('STATIC DATA MISSING: Dogma Type Effects') self.effectsByType = IndexedRows(rs, ('typeID', 'effectID')) self.typesByEffect = IndexedRows(rs, ('effectID', 'typeID')) else: self.RefreshTwoKeyIndexedRows(self.effectsByType, typeID, effectID, newRow) self.RefreshTwoKeyIndexedRows(self.typesByEffect, effectID, typeID, newRow) self.passiveFilteredEffectsByType = {} for typeID in self.effectsByType.iterkeys(): passiveEffects = [] for effectID in self.effectsByType[typeID].iterkeys(): if self.unwantedEffects.has_key(effectID): continue effect = self.effects[effectID] if effect.effectCategory in [const.dgmEffPassive, const.dgmEffSystem]: passiveEffects.append(effectID) if len(passiveEffects): self.passiveFilteredEffectsByType[typeID] = passiveEffects defaultEffect = {} for typeID2 in cfg.dgmtypeeffects: if evetypes.Exists(typeID2): for r in cfg.dgmtypeeffects[typeID2]: if r.isDefault == 1: defaultEffect[typeID2] = r.effectID self.defaultEffectByType = defaultEffect def LoadAllTypeAttributes(self): raise NotImplementedError('LoadAllTypeAttributes - not implemented') def LoadSpecificTypeAttributes(self, typeID, attributeID, newRow): raise NotImplementedError('LoadSpecificTypeAttributes - not implemented') def LoadTypeAttributes(self, typeID = None, attributeID = None, newRow = None): if typeID is None: self.LoadAllTypeAttributes() else: self.LoadSpecificTypeAttributes(typeID, attributeID, newRow) def GetTypeAttribute(self, typeID, attributeID, defaultValue = None): try: return self.attributesByTypeAttribute[typeID][attributeID] except KeyError: return defaultValue def GetTypeAttribute2(self, typeID, attributeID): try: return self.attributesByTypeAttribute[typeID][attributeID] except KeyError: return self.attributes[attributeID].defaultValue @telemetry.ZONE_METHOD def GetRequiredSkills(self, typeID): if typeID in self.requiredSkills: return self.requiredSkills[typeID] ret = {} for attributeID, levelAttributeID in self.requiredSkillAttributes.iteritems(): requiredSkill = self.GetTypeAttribute(typeID, attributeID) requiredLevel = self.GetTypeAttribute2(typeID, levelAttributeID) if requiredSkill is not None and requiredSkill not in ret: ret[int(requiredSkill)] = int(requiredLevel) self.requiredSkills[typeID] = ret return ret def GetEffect(self, effectID): return self.effects[effectID] def GetEffectTypes(self): return self.effects def GetEffectType(self, effectID): return self.effects[effectID] def GetAttributeType(self, attributeID): if isinstance(attributeID, str): return self.attributesByName[attributeID] return self.attributes[attributeID] def GetAttributeByName(self, attributeName): ret = self.attributesByName[attributeName] return ret.attributeID def TypeHasAttribute(self, typeID, attributeID): return typeID in self.attributesByTypeAttribute and attributeID in self.attributesByTypeAttribute[typeID] def TypeGetOrderedEffectIDs(self, typeID, categoryID = None): return self.effectsByType[typeID].iterkeys() def TypeGetEffects(self, typeID): return self.effectsByType.get(typeID, {}) def TypeExists(self, typeID): return typeID in self.attributesByTypeAttribute def TypeHasEffect(self, typeID, effectID): return self.effectsByType.has_key(typeID) and self.effectsByType[typeID].has_key(effectID) def GetAttributesByCategory(self, categoryID): return self.attributesByCategory.get(categoryID, []) def EffectGetTypes(self, effectID): return self.typesByEffect.get(effectID, {}) def AttributeGetTypes(self, attributeID): return self.typesByAttribute.get(attributeID, {}) def GetCanFitShipGroups(self, typeID): rtn = [] for att in self.canFitShipGroupAttributes: try: rtn.append(self.attributesByTypeAttribute[typeID][att]) except KeyError: sys.exc_clear() return rtn def GetChargeGroupAttributes(self): return self.chargeGroupAttributes def GetCanFitShipTypes(self, typeID): rtn = [] for att in self.canFitShipTypeAttributes: try: rtn.append(self.attributesByTypeAttribute[typeID][att]) except KeyError: sys.exc_clear() return rtn def CanFitModuleToShipTypeOrGroup(self, moduleTypeID, shipTypeID, shipGroupID): canFitShipGroups = self.GetCanFitShipGroups(moduleTypeID) canFitShipTypes = self.GetCanFitShipTypes(moduleTypeID) if not canFitShipGroups and not canFitShipTypes: return True if canFitShipGroups and shipGroupID in canFitShipGroups: return True if canFitShipTypes and shipTypeID in canFitShipTypes: return True return False def GetAllowedDroneGroups(self, typeID): groups = [] attributes = self.attributesByTypeAttribute.get(typeID) if attributes: for attributeID in self.allowedDroneGroupAttributes: value = attributes.get(attributeID) if value: groups.append(int(value)) return groups def GetDefaultEffect(self, typeID): return self.defaultEffectByType[typeID] def GetShipHardwareModifierAttribs(self): return self.shipHardwareModifierAttribs def GetValidChargeGroupsForType(self, typeID): ret = set() for attributeID in self.chargeGroupAttributes: try: ret.add(int(self.GetTypeAttribute(typeID, attributeID))) except TypeError: pass return ret def GetSkillModifiedAttributePercentageValue(self, attributeID, modifyingAttributeID, skillTypeID, skillRecord = None): percentageMod = 1.0 skillLevel = 0 if skillRecord: skillLevel = skillRecord.skillLevel try: percentageMod = (100 + self.GetTypeAttribute(skillTypeID, modifyingAttributeID, None) * skillLevel) / 100.0 except TypeError as e: self.LogError('dogmaStaticMgr::GetSkillModifiedAttributePercentageValue.Failed calculating modification! %s' % e) percentageMod = 1.0 if not 0.0 <= percentageMod <= 1.0: self.LogError('dogmaStaticMgr::GetSkillModifiedAttributePercentageValue.Value %s not a percentile!' % percentageMod) percentageMod = 1.0 return percentageMod
def LoadAttributes(self): self.attributes = IndexedRows(cfg.dgmattribs.data.itervalues(), ('attributeID', )) if len(self.attributes) == 0: self.LogError('STATIC DATA MISSING: Dogma Attributes') self.attributesByName = IndexedRows(cfg.dgmattribs.data.itervalues(), ('attributeName', )) self.attributesByCategory = IndexedRowLists( cfg.dgmattribs.data.itervalues(), ('attributeCategory', )) chargedAttributes = [] for att in self.attributes.itervalues(): if att.chargeRechargeTimeID and att.attributeCategory != 8: chargedAttributes.append(att) self.chargedAttributes = IndexedRows(chargedAttributes, ('attributeID', )) self.attributesRechargedByAttribute = IndexedRowLists( chargedAttributes, ('chargeRechargeTimeID', )) self.attributesCappedByAttribute = IndexedRowLists( chargedAttributes, ('maxAttributeID', )) self.attributesByIdx = {} self.idxByAttribute = {} self.canFitShipGroupAttributes = [] self.allowedDroneGroupAttributes = [] self.chargeGroupAttributes = [] for att in self.attributesByCategory[const.dgmAttrCatGroup]: if att.attributeName.startswith('canFitShipGroup'): self.canFitShipGroupAttributes.append(att.attributeID) elif att.attributeName.startswith('allowedDroneGroup'): self.allowedDroneGroupAttributes.append(att.attributeID) elif att.attributeName.startswith('chargeGroup'): self.chargeGroupAttributes.append(att.attributeID) self.canFitShipTypeAttributes = [] self.requiresSovUpgrade = [] self.requiredSkillAttributes = {} for att in self.attributesByCategory[const.dgmAttrCatType]: if att.attributeName.startswith('canFitShipType'): self.canFitShipTypeAttributes.append(att.attributeID) elif att.attributeName.startswith('anchoringRequiresSovUpgrade'): self.requiresSovUpgrade.append(att.attributeID) elif att.attributeName.startswith('requiredSkill'): levelAttribute = self.attributesByName[att.attributeName + 'Level'] self.requiredSkillAttributes[ att.attributeID] = levelAttribute.attributeID self.shipHardwareModifierAttribs = [ (const.attributeHiSlots, const.attributeHiSlotModifier), (const.attributeMedSlots, const.attributeMedSlotModifier), (const.attributeLowSlots, const.attributeLowSlotModifier), (const.attributeTurretSlotsLeft, const.attributeTurretHardpointModifier), (const.attributeLauncherSlotsLeft, const.attributeLauncherHardPointModifier) ] self.mirroredAttributes = set() for r in self.attributesByCategory.get(9, []): if r.attributeID != const.attributeRaceID: self.mirroredAttributes.add(r.attributeID) self.resistanceAttributesByLayer = {} for attributeID, layerName, hpAttributeID, uniformityAttributeID in ( (const.attributeShieldCharge, 'Shield', const.attributeShieldCapacity, const.attributeShieldUniformity), (const.attributeArmorDamage, 'Armor', const.attributeArmorHP, const.attributeArmorUniformity), (const.attributeDamage, '', const.attributeHp, const.attributeStructureUniformity)): self.resistanceAttributesByLayer[attributeID] = [ getattr(const, 'attribute%s%s' % (layerName, resName)) for resName in ('EmDamageResonance', 'ExplosiveDamageResonance', 'KineticDamageResonance', 'ThermalDamageResonance') ] self.damageAttributes = (const.attributeEmDamage, const.attributeExplosiveDamage, const.attributeKineticDamage, const.attributeThermalDamage) self.layerResAttributesByDamage = {} for layerAttributeID, resAttribs in self.resistanceAttributesByLayer.iteritems( ): self.layerResAttributesByDamage[layerAttributeID] = zip( self.damageAttributes, resAttribs)
class BaseDogmaStaticSvc(service.Service): """ This mirrors the dogmaIM on the server. The reason I didn't created a base dogmaIM and had dogmaIM inherit from that is because the dogmaIM is a lot more complicated than this needs to be. """ __guid__ = 'svc.baseDogmaStaticSvc' __notifyevents__ = ['OnCfgRevisionChange'] def __init__(self): service.Service.__init__(self) self.attributes = {} self.attributesByName = {} self.attributesByTypeAttribute = {} self.effects = {} self.requiredSkills = {} self.unwantedEffects = { const.effectHiPower: True, const.effectLoPower: True, const.effectMedPower: True, const.effectSkillEffect: True } def Run(self, *args): self.Load() def OnCfgRevisionChange(self, uniqueRefName, cfgEntryName, cacheID, keyIDs, keyCols, oldRow, newRow): keyID, keyID2, keyID3 = keyIDs if cacheID == const.cacheDogmaAttributes: self.LoadAttributes() elif cacheID == const.cacheDogmaEffects: self.LoadEffects() elif cacheID == const.cacheDogmaTypeAttributes: self.LoadTypeAttributes(keyID, keyID2, newRow) elif cacheID == const.cacheDogmaTypeEffects: self.LoadTypeEffects(keyID, keyID2, newRow) def RefreshTwoKeyIndexedRows(self, ir, keyID, keyID2, newRow): if keyID in ir: ir2 = ir[keyID] if keyID2 in ir2: del ir2[keyID2] if newRow: if keyID in ir: ir2 = ir[keyID] else: ir2 = IndexedRows() ir[keyID] = ir2 ir2[keyID2] = newRow def Load(self): with bluepy.Timer('LoadAttributes'): self.LoadAttributes() with bluepy.Timer('LoadTypeAttributes'): self.LoadTypeAttributes() with bluepy.Timer('LoadEffects'): self.LoadEffects() with bluepy.Timer('LoadTypeEffects'): self.LoadTypeEffects(run=True) self.crystalGroupIDs = cfg.GetCrystalGroups() self.controlBunkersByFactionID = {} for typeObj in cfg.typesByGroups.get(const.groupControlBunker, []): typeID = typeObj.typeID factionID = int( self.GetTypeAttribute2(typeID, const.attributeFactionID)) self.controlBunkersByFactionID[factionID] = typeID import re cgre = re.compile('chargeGroup\\d{1,2}') cgattrs = tuple([ a.attributeID for a in cfg.dgmattribs if cgre.match(a.attributeName) is not None ]) self.chargeGroupAttributes = cgattrs self.crystalModuleGroupIDs = {} for groupID in (const.categoryModule, const.categoryStructure): for groupOb in cfg.groupsByCategories.get(groupID, []): if groupOb.groupID in cfg.typesByGroups: typeOb = cfg.typesByGroups[groupOb.groupID][0] for attributeID in cgattrs: v = self.GetTypeAttribute(typeOb.typeID, attributeID) if v is not None and v in self.crystalGroupIDs: self.crystalModuleGroupIDs[groupOb.groupID] = True break def LoadAttributes(self): self.attributes = IndexedRows(cfg.dgmattribs.data.itervalues(), ('attributeID', )) if len(self.attributes) == 0: self.LogError('STATIC DATA MISSING: Dogma Attributes') self.attributesByName = IndexedRows(cfg.dgmattribs.data.itervalues(), ('attributeName', )) self.attributesByCategory = IndexedRowLists( cfg.dgmattribs.data.itervalues(), ('attributeCategory', )) chargedAttributes = [] for att in self.attributes.itervalues(): if att.chargeRechargeTimeID and att.attributeCategory != 8: chargedAttributes.append(att) self.chargedAttributes = IndexedRows(chargedAttributes, ('attributeID', )) self.attributesRechargedByAttribute = IndexedRowLists( chargedAttributes, ('chargeRechargeTimeID', )) self.attributesCappedByAttribute = IndexedRowLists( chargedAttributes, ('maxAttributeID', )) self.attributesByIdx = {} self.idxByAttribute = {} self.canFitShipGroupAttributes = [] self.allowedDroneGroupAttributes = [] self.chargeGroupAttributes = [] for att in self.attributesByCategory[const.dgmAttrCatGroup]: if att.attributeName.startswith('canFitShipGroup'): self.canFitShipGroupAttributes.append(att.attributeID) elif att.attributeName.startswith('allowedDroneGroup'): self.allowedDroneGroupAttributes.append(att.attributeID) elif att.attributeName.startswith('chargeGroup'): self.chargeGroupAttributes.append(att.attributeID) self.canFitShipTypeAttributes = [] self.requiresSovUpgrade = [] self.requiredSkillAttributes = {} for att in self.attributesByCategory[const.dgmAttrCatType]: if att.attributeName.startswith('canFitShipType'): self.canFitShipTypeAttributes.append(att.attributeID) elif att.attributeName.startswith('anchoringRequiresSovUpgrade'): self.requiresSovUpgrade.append(att.attributeID) elif att.attributeName.startswith('requiredSkill'): levelAttribute = self.attributesByName[att.attributeName + 'Level'] self.requiredSkillAttributes[ att.attributeID] = levelAttribute.attributeID self.shipHardwareModifierAttribs = [ (const.attributeHiSlots, const.attributeHiSlotModifier), (const.attributeMedSlots, const.attributeMedSlotModifier), (const.attributeLowSlots, const.attributeLowSlotModifier), (const.attributeTurretSlotsLeft, const.attributeTurretHardpointModifier), (const.attributeLauncherSlotsLeft, const.attributeLauncherHardPointModifier) ] self.mirroredAttributes = set() for r in self.attributesByCategory.get(9, []): if r.attributeID != const.attributeRaceID: self.mirroredAttributes.add(r.attributeID) self.resistanceAttributesByLayer = {} for attributeID, layerName, hpAttributeID, uniformityAttributeID in ( (const.attributeShieldCharge, 'Shield', const.attributeShieldCapacity, const.attributeShieldUniformity), (const.attributeArmorDamage, 'Armor', const.attributeArmorHP, const.attributeArmorUniformity), (const.attributeDamage, '', const.attributeHp, const.attributeStructureUniformity)): self.resistanceAttributesByLayer[attributeID] = [ getattr(const, 'attribute%s%s' % (layerName, resName)) for resName in ('EmDamageResonance', 'ExplosiveDamageResonance', 'KineticDamageResonance', 'ThermalDamageResonance') ] self.damageAttributes = (const.attributeEmDamage, const.attributeExplosiveDamage, const.attributeKineticDamage, const.attributeThermalDamage) self.layerResAttributesByDamage = {} for layerAttributeID, resAttribs in self.resistanceAttributesByLayer.iteritems( ): self.layerResAttributesByDamage[layerAttributeID] = zip( self.damageAttributes, resAttribs) def LoadEffects(self): self.effects = IndexedRows(cfg.dgmeffects.data.itervalues(), ('effectID', )) if len(self.effects) == 0: self.LogError('STATIC DATA MISSING: Dogma Effects') self.effectsByName = IndexedRows(cfg.dgmeffects.data.itervalues(), ('effectName', )) def LoadTypeEffects(self, typeID=None, effectID=None, newRow=None, run=False): if typeID is None: rs = [] for r in cfg.dgmtypeeffects.itervalues(): rs.extend(r) if len(rs) == 0: self.LogError('STATIC DATA MISSING: Dogma Type Effects') self.effectsByType = IndexedRows(rs, ('typeID', 'effectID')) self.typesByEffect = IndexedRows(rs, ('effectID', 'typeID')) else: self.RefreshTwoKeyIndexedRows(self.effectsByType, typeID, effectID, newRow) self.RefreshTwoKeyIndexedRows(self.typesByEffect, effectID, typeID, newRow) self.passiveFilteredEffectsByType = {} for typeID in self.effectsByType.iterkeys(): passiveEffects = [] for effectID in self.effectsByType[typeID].iterkeys(): if self.unwantedEffects.has_key(effectID): continue effect = self.effects[effectID] if effect.effectCategory in [ const.dgmEffPassive, const.dgmEffSystem ]: passiveEffects.append(effectID) if len(passiveEffects): self.passiveFilteredEffectsByType[typeID] = passiveEffects defaultEffect = {} for typeID2 in cfg.dgmtypeeffects: for r in cfg.dgmtypeeffects[typeID2]: if r.isDefault == 1: defaultEffect[typeID2] = r.effectID self.defaultEffectByType = defaultEffect def LoadAllTypeAttributes(self): raise NotImplementedError('LoadAllTypeAttributes - not implemented') def LoadSpecificTypeAttributes(self, typeID, attributeID, newRow): raise NotImplementedError( 'LoadSpecificTypeAttributes - not implemented') def LoadTypeAttributes(self, typeID=None, attributeID=None, newRow=None): if typeID is None: self.LoadAllTypeAttributes() else: self.LoadSpecificTypeAttributes(typeID, attributeID, newRow) def GetTypeAttribute(self, typeID, attributeID, defaultValue=None): try: return self.attributesByTypeAttribute[typeID][attributeID] except KeyError: return defaultValue def GetTypeAttribute2(self, typeID, attributeID): try: return self.attributesByTypeAttribute[typeID][attributeID] except KeyError: return self.attributes[attributeID].defaultValue @telemetry.ZONE_METHOD def GetRequiredSkills(self, typeID): if typeID in self.requiredSkills: return self.requiredSkills[typeID] ret = {} for attributeID, levelAttributeID in self.requiredSkillAttributes.iteritems( ): requiredSkill = self.GetTypeAttribute(typeID, attributeID) requiredLevel = self.GetTypeAttribute2(typeID, levelAttributeID) if requiredSkill is not None and requiredSkill not in ret: ret[int(requiredSkill)] = int(requiredLevel) self.requiredSkills[typeID] = ret return ret def GetEffect(self, effectID): return self.effects[effectID] def GetEffectTypes(self): return self.effects def GetEffectType(self, effectID): return self.effects[effectID] def GetAttributeType(self, attributeID): if isinstance(attributeID, str): return self.attributesByName[attributeID] return self.attributes[attributeID] def GetAttributeByName(self, attributeName): ret = self.attributesByName[attributeName] return ret.attributeID def TypeHasAttribute(self, typeID, attributeID): return typeID in self.attributesByTypeAttribute and attributeID in self.attributesByTypeAttribute[ typeID] def TypeGetOrderedEffectIDs(self, typeID, categoryID=None): return self.effectsByType[typeID].iterkeys() def TypeGetEffects(self, typeID): return self.effectsByType.get(typeID, {}) def TypeExists(self, typeID): return typeID in self.attributesByTypeAttribute def TypeHasEffect(self, typeID, effectID): return self.effectsByType.has_key( typeID) and self.effectsByType[typeID].has_key(effectID) def GetAttributesByCategory(self, categoryID): return self.attributesByCategory.get(categoryID, []) def EffectGetTypes(self, effectID): return self.typesByEffect.get(effectID, {}) def AttributeGetTypes(self, attributeID): return self.typesByAttribute.get(attributeID, {}) def GetCanFitShipGroups(self, typeID): rtn = [] for att in self.canFitShipGroupAttributes: try: rtn.append(self.attributesByTypeAttribute[typeID][att]) except KeyError: sys.exc_clear() return rtn def GetChargeGroupAttributes(self): return self.chargeGroupAttributes def GetCanFitShipTypes(self, typeID): rtn = [] for att in self.canFitShipTypeAttributes: try: rtn.append(self.attributesByTypeAttribute[typeID][att]) except KeyError: sys.exc_clear() return rtn def CanFitModuleToShipTypeOrGroup(self, moduleTypeID, shipTypeID, shipGroupID): """ Returns True if moduleTypeID is acceptable for fitting to ships belonging to shipTypeID/shipGroupID Otherwise returns False """ canFitShipGroups = self.GetCanFitShipGroups(moduleTypeID) canFitShipTypes = self.GetCanFitShipTypes(moduleTypeID) if not canFitShipGroups and not canFitShipTypes: return True if canFitShipGroups and shipGroupID in canFitShipGroups: return True if canFitShipTypes and shipTypeID in canFitShipTypes: return True return False def GetAllowedDroneGroups(self, typeID): groups = [] attributes = self.attributesByTypeAttribute.get(typeID) if attributes: for attributeID in self.allowedDroneGroupAttributes: value = attributes.get(attributeID) if value: groups.append(int(value)) return groups def GetDefaultEffect(self, typeID): return self.defaultEffectByType[typeID] def GetShipHardwareModifierAttribs(self): return self.shipHardwareModifierAttribs def GetValidChargeGroupsForType(self, typeID): ret = set() for attributeID in self.chargeGroupAttributes: try: ret.add(int(self.GetTypeAttribute(typeID, attributeID))) except TypeError: pass return ret