# ============================================================================= # Copyright (C) 2010 Diego Duclos # # This file is part of pyfa. # # pyfa is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # pyfa 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with pyfa. If not, see . # ============================================================================= from eos.calc import calculateMultiplier from eos.saveddata.damagePattern import DamagePattern from eos.saveddata.fit import Fit from eos.saveddata.targetProfile import TargetProfile from service.const import TargetResistMode class BaseWrapper: def __init__(self, item): self.item = item @property def isFit(self): return isinstance(self.item, Fit) @property def isProfile(self): return isinstance(self.item, TargetProfile) @property def name(self): if self.isFit: return '{} ({})'.format(self.item.name, self.item.ship.item.name) elif self.isProfile: return self.item.fullName return '' @property def shortName(self): if self.isFit: return '{} ({})'.format(self.item.name, self.item.ship.item.getShortName()) elif self.isProfile: return self.item.shortName return '' def getMaxVelocity(self, extraMultipliers=None, ignoreAfflictors=()): if self.isFit: if extraMultipliers or ignoreAfflictors: maxVelocity = self.item.ship.getModifiedItemAttrExtended( 'maxVelocity', extraMultipliers=extraMultipliers, ignoreAfflictors=ignoreAfflictors) else: maxVelocity = self.item.ship.getModifiedItemAttr('maxVelocity') elif self.isProfile: maxVelocity = self.item.maxVelocity if extraMultipliers: maxVelocity *= calculateMultiplier(extraMultipliers) else: maxVelocity = None return maxVelocity def getSigRadius(self, extraMultipliers=None, ignoreAfflictors=()): if self.isFit: if extraMultipliers or ignoreAfflictors: sigRadius = self.item.ship.getModifiedItemAttrExtended( 'signatureRadius', extraMultipliers=extraMultipliers, ignoreAfflictors=ignoreAfflictors) else: sigRadius = self.item.ship.getModifiedItemAttr('signatureRadius') elif self.isProfile: sigRadius = self.item.signatureRadius if extraMultipliers: sigRadius *= calculateMultiplier(extraMultipliers) else: sigRadius = None return sigRadius def getRadius(self): if self.isFit: radius = self.item.ship.getModifiedItemAttr('radius') elif self.isProfile: radius = self.item.radius else: radius = None return radius class SourceWrapper(BaseWrapper): def __init__(self, item, colorID): super().__init__(item) self._colorID = colorID @property def colorID(self): return self._colorID @colorID.setter def colorID(self, value): self._colorID = value class TargetWrapper(BaseWrapper): def __init__(self, item, lightnessID, lineStyleID): super().__init__(item=item) self.lightnessID = lightnessID self.lineStyleID = lineStyleID self.resistMode = TargetResistMode.auto def getResists(self, includeLayer=False): em = therm = kin = explo = 0 layer = None if self.isProfile: em = self.item.emAmount therm = self.item.thermalAmount kin = self.item.kineticAmount explo = self.item.explosiveAmount if self.isFit: if self.resistMode == TargetResistMode.auto: em, therm, kin, explo, layer = _getAutoResists(fit=self.item) elif self.resistMode == TargetResistMode.shield: em, therm, kin, explo = _getShieldResists(ship=self.item.ship) elif self.resistMode == TargetResistMode.armor: em, therm, kin, explo = _getArmorResists(ship=self.item.ship) elif self.resistMode == TargetResistMode.hull: em, therm, kin, explo = _getHullResists(ship=self.item.ship) elif self.resistMode == TargetResistMode.weightedAverage: em, therm, kin, explo = _getWeightedResists(fit=self.item) if includeLayer: return em, therm, kin, explo, layer else: return em, therm, kin, explo def _getShieldResists(ship): em = 1 - ship.getModifiedItemAttr('shieldEmDamageResonance') therm = 1 - ship.getModifiedItemAttr('shieldThermalDamageResonance') kin = 1 - ship.getModifiedItemAttr('shieldKineticDamageResonance') explo = 1 - ship.getModifiedItemAttr('shieldExplosiveDamageResonance') return em, therm, kin, explo def _getArmorResists(ship): em = 1 - ship.getModifiedItemAttr('armorEmDamageResonance') therm = 1 - ship.getModifiedItemAttr('armorThermalDamageResonance') kin = 1 - ship.getModifiedItemAttr('armorKineticDamageResonance') explo = 1 - ship.getModifiedItemAttr('armorExplosiveDamageResonance') return em, therm, kin, explo def _getHullResists(ship): em = 1 - ship.getModifiedItemAttr('emDamageResonance') therm = 1 - ship.getModifiedItemAttr('thermalDamageResonance') kin = 1 - ship.getModifiedItemAttr('kineticDamageResonance') explo = 1 - ship.getModifiedItemAttr('explosiveDamageResonance') return em, therm, kin, explo def _getWeightedResists(fit): shieldEmRes, shieldThermRes, shieldKinRes, shieldExploRes = _getShieldResists(fit.ship) armorEmRes, armorThermRes, armorKinRes, armorExploRes = _getArmorResists(fit.ship) hullEmRes, hullThermRes, hullKinRes, hullExploRes = _getHullResists(fit.ship) hpData = fit.hp shieldHp = hpData['shield'] armorHp = hpData['armor'] hullHp = hpData['hull'] totalHp = shieldHp + armorHp + hullHp totalEhpEm = shieldHp / (1 - shieldEmRes) + armorHp / (1 - armorEmRes) + hullHp / (1 - hullEmRes) totalEhpTherm = shieldHp / (1 - shieldThermRes) + armorHp / (1 - armorThermRes) + hullHp / (1 - hullThermRes) totalEhpKin = shieldHp / (1 - shieldKinRes) + armorHp / (1 - armorKinRes) + hullHp / (1 - hullKinRes) totalEhpExplo = shieldHp / (1 - shieldExploRes) + armorHp / (1 - armorExploRes) + hullHp / (1 - hullExploRes) weightedEmRes = 1 - totalHp / totalEhpEm weightedThermRes = 1 - totalHp / totalEhpTherm weightedKinRes = 1 - totalHp / totalEhpKin weightedExploRes = 1 - totalHp / totalEhpExplo return weightedEmRes, weightedThermRes, weightedKinRes, weightedExploRes def _getAutoResists(fit): # Get all the data # HP / EHP hpData = fit.hp shieldHp = hpData['shield'] armorHp = hpData['armor'] hullHp = hpData['hull'] uniformDamagePattern = DamagePattern(emAmount=25, thermalAmount=25, kineticAmount=25, explosiveAmount=25) ehpData = uniformDamagePattern.calculateEhp(fit) shieldEhp = ehpData['shield'] armorEhp = ehpData['armor'] hullEhp = ehpData['hull'] totalEhp = shieldEhp + armorEhp + hullEhp # Resist factors try: shieldResFactor = shieldEhp / shieldHp except ZeroDivisionError: shieldResFactor = 1 try: armorResFactor = armorEhp / armorHp except ZeroDivisionError: armorResFactor = 1 try: hullResFactor = hullEhp / hullHp except ZeroDivisionError: hullResFactor = 1 # Tank tankData = fit.tank shieldTank = tankData['shieldRepair'] armorTank = tankData['armorRepair'] hullTank = tankData['hullRepair'] shieldRegen = tankData['passiveShield'] shieldScore = 0 armorScore = 0 hullScore = 0 # EHP scoring ehpWeight = 100 shieldScore += ehpWeight * (shieldEhp / totalEhp) ** 1.5 armorScore += ehpWeight * (armorEhp / totalEhp) ** 1.5 hullScore += ehpWeight * (hullEhp / totalEhp) ** 1.5 # Resists scoring # We include it to have some extra points for receiving better reps from the outside resistWeight = 25 bestResFactor = max(shieldResFactor, armorResFactor, hullResFactor) shieldScore += resistWeight * (shieldResFactor / bestResFactor) ** 1.5 armorScore += resistWeight * (armorResFactor / bestResFactor) ** 1.5 hullScore += resistWeight * (hullResFactor / bestResFactor) ** 1.5 # Active tank activeWeight = 10000 shieldScore += activeWeight * shieldTank * shieldResFactor / totalEhp armorScore += activeWeight * armorTank * armorResFactor / totalEhp hullScore += activeWeight * hullTank * hullResFactor / totalEhp # Shield regen regenWeight = 5000 shieldScore += regenWeight * shieldRegen * shieldResFactor / totalEhp maxScore = max(shieldScore, armorScore, hullScore) if maxScore == shieldScore: return (*_getShieldResists(fit.ship), 'shield') if maxScore == armorScore: return (*_getArmorResists(fit.ship), 'armor') if maxScore == hullScore: return (*_getHullResists(fit.ship), 'hull') return 0, 0, 0, 0, None