scanBonusController.py (13552B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\probescanning\scanBonusController.py 2 import operator 3 import dogma.data as dogma_data 4 from dogma.const import attributeBoosterAttributeModifier 5 from dogma.items.moduleDogmaItem import ModuleDogmaItem 6 from dogma.items.shipDogmaItem import ShipDogmaItem 7 from logmodule import LogException 8 from probescanning.const import SCAN_STRENGTH_ATTRIBUTE_ID, SCAN_DEVIATION_ATTRIBUTE_ID, SCAN_DURATION_ATTRIBUTE_ID, SCAN_STRENGTH_BONUS_ATTRIBUTE_IDS, SCAN_DEVIATION_BONUS_ATTRIBUTE_IDS, SCAN_DURATION_ALTERNATE_ATTRIBUTE_IDS, SCANNING_IMPLANTS_TYPE_IDS, attributeImplantSetSister, SCANNING_SUBSYSTEM_TYPE_IDS, SCANNING_SKILLS_TYPE_IDS 9 from functools import reduce 10 11 class ScanBonusController: 12 13 def __init__(self): 14 self.skillSvc = sm.GetService('skills') 15 self.scanSvc = sm.GetService('scanSvc') 16 self.godma = sm.GetService('godma') 17 self.dogmaLoc = sm.GetService('clientDogmaIM').GetDogmaLocation() 18 self.fittedModules = None 19 20 def GetAttribute(self, attributeID, categoryID = None, groupID = None): 21 self.UpdateFittedItems() 22 if not self.fittedModules: 23 return None 24 for itemID, item in self.fittedModules.iteritems(): 25 if item.categoryID == categoryID or item.groupID == groupID: 26 if not self.TypeHasAttribute(item.typeID, attributeID): 27 continue 28 return item.attributes[attributeID] 29 30 def TypeHasAttribute(self, typeID, attributeID): 31 for each in dogma_data.get_type_attributes(typeID): 32 if each.attributeID == attributeID: 33 return True 34 35 return False 36 37 def GetScanStrengthAttribute(self): 38 return self.GetAttribute(SCAN_STRENGTH_ATTRIBUTE_ID, categoryID=const.categoryCharge) 39 40 def GetScanDeviationAttribute(self): 41 return self.GetAttribute(SCAN_DEVIATION_ATTRIBUTE_ID, categoryID=const.categoryCharge) 42 43 def GetScanDurationAttribute(self): 44 return self.GetAttribute(SCAN_DURATION_ATTRIBUTE_ID, groupID=const.groupScanProbeLauncher) 45 46 def GetBaseScanStrength(self): 47 return self.godma.GetTypeAttribute2(self.scanSvc.GetActiveProbeTypeID(), SCAN_STRENGTH_ATTRIBUTE_ID) 48 49 def GetBaseScanDeviation(self): 50 return self.godma.GetTypeAttribute2(self.scanSvc.GetActiveProbeTypeID(), SCAN_DEVIATION_ATTRIBUTE_ID) 51 52 def GetBaseScanDuration(self): 53 return self.godma.GetTypeAttribute2(self.scanSvc.GetProbeLauncher().typeID, SCAN_DURATION_ATTRIBUTE_ID) 54 55 def GetTotalScanStrength(self): 56 launchedProbesData = self.scanSvc.GetProbeData() 57 if not launchedProbesData: 58 strengthAttribute = self.GetScanStrengthAttribute() 59 if not strengthAttribute: 60 return 0 61 return strengthAttribute.GetValue() 62 typeID = launchedProbesData.iteritems().next()[1].typeID 63 return self.godma.GetTypeAttribute2(typeID, SCAN_STRENGTH_ATTRIBUTE_ID) * self.ConvertToFraction(self.GetTotalScanStrengthBonus()) 64 65 def GetTotalScanDeviation(self): 66 launchedProbesData = self.scanSvc.GetProbeData() 67 if not launchedProbesData: 68 deviationAttribute = self.GetScanDeviationAttribute() 69 if not deviationAttribute: 70 return 0 71 return deviationAttribute.GetValue() 72 typeID = launchedProbesData.iteritems().next()[1].typeID 73 return self.godma.GetTypeAttribute2(typeID, SCAN_DEVIATION_ATTRIBUTE_ID) * abs(self.ConvertToFraction(self.GetTotalScanDeviationBonus())) 74 75 def GetTotalScanDuration(self): 76 durationAttribute = self.GetScanDurationAttribute() 77 if durationAttribute is None: 78 return 0 79 return durationAttribute.GetValue() 80 81 def GetTotalScanStrengthBonus(self): 82 modulesFactor = self.ConvertToFraction(self.GetScanStrengthBonusFromModules()) 83 shipFactor = self.ConvertToFraction(self.GetScanStrengthBonusFromShip()) 84 implantFactor = self.ConvertToFraction(self.GetScanStrengthBonusFromImplants()) 85 skillsFactor = self.ConvertToFraction(self.GetScanStrengthBonusFromSkills()) 86 boosterFactor = self.ConvertToFraction(self.GetScanStrengthBonusFromBoosters()) 87 return self.ConvertToDecimal(modulesFactor * shipFactor * implantFactor * skillsFactor * boosterFactor) 88 89 def GetTotalScanDeviationBonus(self): 90 modulesFactor = self.ConvertToFraction(self.GetScanDeviationBonusFromModules()) 91 shipFactor = self.ConvertToFraction(self.GetScanDeviationBonusFromShip()) 92 implantFactor = self.ConvertToFraction(self.GetScanDeviationBonusFromImplants()) 93 skillsFactor = self.ConvertToFraction(self.GetScanDeviationBonusFromSkills()) 94 boosterFactor = self.ConvertToFraction(self.GetScanDeviationBonusFromBoosters()) 95 return self.ConvertToDecimal(modulesFactor * shipFactor * implantFactor * skillsFactor * boosterFactor) 96 97 def GetTotalScanDurationBonus(self): 98 modulesFactor = self.ConvertToFraction(self.GetScanDurationBonusFromModules()) 99 shipFactor = self.ConvertToFraction(self.GetScanDurationBonusFromShip()) 100 implantFactor = self.ConvertToFraction(self.GetScanDurationBonusFromImplants()) 101 skillsFactor = self.ConvertToFraction(self.GetScanDurationBonusFromSkills()) 102 boosterFactor = self.ConvertToFraction(self.GetScanDurationBonusFromBoosters()) 103 return self.ConvertToDecimal(modulesFactor * shipFactor * implantFactor * skillsFactor * boosterFactor) 104 105 def GetBonusFromLaunchedProbes(self, bonusID, originID): 106 launchedProbesData = self.scanSvc.GetProbeData() 107 if not launchedProbesData: 108 return 0 109 val = launchedProbesData.iteritems().next()[1].scanBonuses[bonusID][originID] 110 if val: 111 return val 112 return 0 113 114 def GetBonusFromModulesToNurfedAttribute(self, attribute): 115 if attribute is None: 116 return 0 117 factor = attribute.GetNurfedModsFactor() 118 return self.ConvertToDecimal(factor) 119 120 def GetBonusFromModulesToAttribute(self, attribute): 121 if attribute is None: 122 return 0 123 totalBonus = 0 124 for id, modifier in attribute.GetIncomingModifiers(): 125 if isinstance(modifier.item, ModuleDogmaItem): 126 totalBonus += modifier.GetValue() 127 128 return totalBonus 129 130 def GetScanStrengthBonusFromModules(self): 131 fittedProbeAttribute = self.GetScanStrengthAttribute() 132 if not fittedProbeAttribute: 133 return self.GetBonusFromLaunchedProbes('strength', 'modules') 134 return self.GetBonusFromModulesToNurfedAttribute(self.GetScanStrengthAttribute()) 135 136 def GetScanDeviationBonusFromModules(self): 137 fittedProbeAttribute = self.GetScanDeviationAttribute() 138 if not fittedProbeAttribute: 139 return self.GetBonusFromLaunchedProbes('deviation', 'modules') 140 return self.GetBonusFromModulesToNurfedAttribute(fittedProbeAttribute) 141 142 def GetScanDurationBonusFromModules(self): 143 return self.GetBonusFromModulesToAttribute(self.GetScanDurationAttribute()) 144 145 def GetBonusFromSkillsByAttributes(self, attributeIDs): 146 bonuses = [] 147 for skillID in SCANNING_SKILLS_TYPE_IDS: 148 totalBonus = 0 149 skillLevel = self.skillSvc.GetEffectiveLevel(skillID) or 0 150 for bonusID in attributeIDs: 151 percentagePerLevel = self.godma.GetTypeAttribute2(skillID, bonusID) 152 if percentagePerLevel: 153 totalBonus += skillLevel * percentagePerLevel 154 bonuses.append(self.ConvertToFraction(totalBonus)) 155 156 if bonuses: 157 return self.ConvertToDecimal(reduce(operator.mul, bonuses)) 158 else: 159 return 0 160 161 def GetScanStrengthBonusFromSkills(self): 162 return self.GetBonusFromSkillsByAttributes(SCAN_STRENGTH_BONUS_ATTRIBUTE_IDS) 163 164 def GetScanDeviationBonusFromSkills(self): 165 return self.GetBonusFromSkillsByAttributes(SCAN_DEVIATION_BONUS_ATTRIBUTE_IDS) 166 167 def GetScanDurationBonusFromSkills(self): 168 return self.GetBonusFromSkillsByAttributes(SCAN_DURATION_ALTERNATE_ATTRIBUTE_IDS) 169 170 def GetBonusFromImplantsByAttributes(self, attributeIDs): 171 implants = self.skillSvc.GetImplants() 172 bonuses = [] 173 setBonuses = [] 174 for id, implant in implants.iteritems(): 175 if implant.typeID in SCANNING_IMPLANTS_TYPE_IDS: 176 for bonusID in attributeIDs: 177 percentageBonus = self.godma.GetTypeAttribute2(implant.typeID, bonusID) 178 if percentageBonus: 179 bonuses.append(self.ConvertToFraction(percentageBonus)) 180 181 setBonus = self.godma.GetTypeAttribute2(implant.typeID, attributeImplantSetSister) 182 if setBonus: 183 setBonuses.append(setBonus) 184 185 if bonuses: 186 totalBonus = self.ConvertToDecimal(reduce(operator.mul, bonuses)) 187 if len(setBonuses) > 1: 188 totalSetBonus = reduce(operator.mul, setBonuses) 189 totalBonus *= totalSetBonus 190 return totalBonus 191 else: 192 return 0 193 194 def GetBonusFromBoostersByAttributes(self, attributeIDs): 195 bonuses = self._GetBonusFromBoostersByAttributes(attributeIDs) 196 if bonuses: 197 totalBonus = self.ConvertToDecimal(reduce(operator.mul, bonuses)) 198 return totalBonus 199 else: 200 return 0 201 202 def _GetBonusFromBoostersByAttributes(self, attributeIDs): 203 dogmaLM = sm.GetService('clientDogmaIM').GetDogmaLocation() 204 bonuses = [] 205 boosters = sm.GetService('crimewatchSvc').GetMyBoosters() 206 for b in boosters: 207 boosterEffects = sm.GetService('crimewatchSvc').GetBoosterEffects(b) 208 if not boosterEffects: 209 continue 210 positiveEffects = boosterEffects.get('positive', []) 211 for eff in positiveEffects: 212 if not eff.modifierInfo: 213 continue 214 for mi in eff.modifierInfo: 215 if mi.modifyingAttributeID not in attributeIDs: 216 continue 217 effectAmount = dogmaLM.dogmaStaticMgr.GetTypeAttribute(b.typeID, mi.modifyingAttributeID) 218 bonuses.append(self.ConvertToFraction(effectAmount)) 219 220 return bonuses 221 222 def GetScanStrengthBonusFromImplants(self): 223 return self.GetBonusFromImplantsByAttributes(SCAN_STRENGTH_BONUS_ATTRIBUTE_IDS) 224 225 def GetScanDeviationBonusFromImplants(self): 226 return self.GetBonusFromImplantsByAttributes(SCAN_DEVIATION_BONUS_ATTRIBUTE_IDS) 227 228 def GetScanDurationBonusFromImplants(self): 229 return self.GetBonusFromImplantsByAttributes(SCAN_DURATION_ALTERNATE_ATTRIBUTE_IDS) 230 231 def GetScanStrengthBonusFromBoosters(self): 232 return self.GetBonusFromBoostersByAttributes(SCAN_STRENGTH_BONUS_ATTRIBUTE_IDS) 233 234 def GetScanDeviationBonusFromBoosters(self): 235 return self.GetBonusFromBoostersByAttributes(SCAN_DEVIATION_BONUS_ATTRIBUTE_IDS) 236 237 def GetScanDurationBonusFromBoosters(self): 238 return self.GetBonusFromBoostersByAttributes(SCAN_DURATION_ALTERNATE_ATTRIBUTE_IDS) 239 240 def GetBonusFromShip(self, attribute): 241 shipBonus = self._GetBonusFromShip(attribute) / 100.0 242 subsystemBonus = self.GetBonusFromSubsystems(attribute) 243 return ((1.0 + shipBonus) * (1.0 + subsystemBonus) - 1.0) * 100.0 244 245 def _GetBonusFromShip(self, attribute): 246 if attribute is None: 247 return 0 248 try: 249 for modifier in attribute.GetIncomingModifiers(): 250 if isinstance(modifier[1].item, ShipDogmaItem): 251 val = modifier[1].GetValue() or 0 252 if val: 253 return val 254 return 0 255 256 except AttributeError: 257 LogException('Getting Scan Bonus From Ship Failed') 258 259 return 0 260 261 def GetBonusFromSubsystems(self, attribute): 262 if attribute.attribID != SCAN_STRENGTH_ATTRIBUTE_ID: 263 return 0.0 264 bonus = 1.0 265 for typeID, attributeID in SCANNING_SUBSYSTEM_TYPE_IDS.iteritems(): 266 for module in self.fittedModules.values(): 267 if module.typeID == typeID: 268 attrValue = module.attributes[attributeID].GetValue() 269 bonus *= 1.0 + attrValue / 100.0 270 271 return bonus - 1.0 272 273 def GetScanStrengthBonusFromShip(self): 274 fittedProbeAttribute = self.GetScanStrengthAttribute() 275 if not fittedProbeAttribute: 276 return self.GetBonusFromLaunchedProbes('strength', 'ship') 277 return self.GetBonusFromShip(fittedProbeAttribute) 278 279 def GetScanDeviationBonusFromShip(self): 280 fittedProbeAttribute = self.GetScanDeviationAttribute() 281 if not fittedProbeAttribute: 282 return self.GetBonusFromLaunchedProbes('deviation', 'ship') 283 return self.GetBonusFromShip(fittedProbeAttribute) 284 285 def GetScanDurationBonusFromShip(self): 286 return self.GetBonusFromShip(self.GetScanDurationAttribute()) 287 288 def ConvertToDecimal(self, fraction): 289 if not fraction: 290 return 0 291 return (fraction - 1) * 100 292 293 def ConvertToFraction(self, decimal): 294 if not decimal: 295 return 1 296 return decimal / 100 + 1 297 298 def UpdateFittedItems(self): 299 ship = self.dogmaLoc.SafeGetDogmaItem(session.shipid) 300 if ship: 301 self.fittedModules = ship.GetFittedItems()