#=============================================================================== # Copyright (C) 2010 Diego Duclos # # This file is part of eos. # # eos is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # eos is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with eos. If not, see . #=============================================================================== from eos.graph import Graph, Data from eos.types import Hardpoint, State from math import log, sin, radians class FitDpsGraph(Graph): defaults = {"angle": 0, "distance": 0, "signatureRadius": None, "velocity": 0} def __init__(self, fit, data=None): Graph.__init__(self, fit, self.calcDps, data if data is not None else self.defaults) self.fit = fit def calcDps(self, data): fit = self.fit total = 0 distance = data["distance"] * 1000 for mod in fit.modules: if mod.hardpoint == Hardpoint.TURRET: if mod.state >= State.ACTIVE: total += mod.dps * self.calculateTurretMultiplier(mod, data) elif mod.hardpoint == Hardpoint.MISSILE: if mod.state >= State.ACTIVE and mod.maxRange >= distance: total += mod.dps * self.calculateMissileMultiplier(mod, data) if distance <= fit.extraAttributes["droneControlRange"]: for drone in fit.drones: multiplier = 1 if drone.getModifiedItemAttr("maxVelocity") > 0 else self.calculateTurretMultiplier(drone, data) total += drone.dps * multiplier return total def calculateMissileMultiplier(self, mod, data): targetSigRad = data["signatureRadius"] targetVelocity = data["velocity"] explosionRadius = mod.getModifiedChargeAttr("aoeCloudSize") targetSigRad = explosionRadius if targetSigRad is None else targetSigRad explosionVelocity = mod.getModifiedChargeAttr("aoeVelocity") damageReductionFactor = mod.getModifiedChargeAttr("aoeDamageReductionFactor") damageReductionSensitivity = mod.getModifiedChargeAttr("aoeDamageReductionSensitivity") sigRadiusFactor = targetSigRad / explosionRadius if targetVelocity: velocityFactor = (explosionVelocity / explosionRadius * targetSigRad / targetVelocity) ** (log(damageReductionFactor) / log(damageReductionSensitivity)) else: velocityFactor = 1 return min(sigRadiusFactor, velocityFactor, 1) def calculateTurretMultiplier(self, mod, data): #Source for most of turret calculation info: http://wiki.eveonline.com/en/wiki/Falloff chanceToHit = self.calculateTurretChanceToHit(mod, data) if chanceToHit > 0.01: #AvgDPS = Base Damage * [ ( ChanceToHit^2 + ChanceToHit + 0.0499 ) / 2 ] multiplier = (chanceToHit ** 2 + chanceToHit + 0.0499) / 2 else: #All hits are wreckings multiplier = chanceToHit * 3 dmgScaling = mod.getModifiedItemAttr("turretDamageScalingRadius") if dmgScaling: targetSigRad = data["signatureRadius"] multiplier = min(1, (float(targetSigRad) / dmgScaling) ** 2) return multiplier def calculateTurretChanceToHit(self, mod, data): distance = data["distance"] * 1000 tracking = mod.getModifiedItemAttr("trackingSpeed") turretOptimal = mod.maxRange turretFalloff = mod.falloff turretSigRes = mod.getModifiedItemAttr("optimalSigRadius") targetSigRad = data["signatureRadius"] targetSigRad = turretSigRes if targetSigRad is None else targetSigRad transversal = sin(radians(data["angle"])) * data["velocity"] trackingEq = (((transversal / (distance * tracking)) * (turretSigRes / targetSigRad)) ** 2) rangeEq = ((max(0, distance - turretOptimal)) / turretFalloff) ** 2 return 0.5 ** (trackingEq + rangeEq)