Merge branch 'master' into ammo_graph

This commit is contained in:
DarkPhoenix
2019-11-12 16:58:34 +03:00
22 changed files with 11119 additions and 1707 deletions

View File

@@ -40,6 +40,7 @@ logging_setup = None
cipher = None
clientHash = None
experimentalFeatures = None
version = None
ESI_CACHE = 'esi_cache'

View File

@@ -18,7 +18,7 @@
# ===============================================================================
from collections import MutableMapping
from collections.abc import MutableMapping
from copy import copy
from math import exp

View File

@@ -46,11 +46,11 @@ class DmgTypes:
# Round for comparison's sake because often damage profiles are
# generated from data which includes float errors
return (
floatUnerr(self.em) == floatUnerr(other.em) and
floatUnerr(self.thermal) == floatUnerr(other.thermal) and
floatUnerr(self.kinetic) == floatUnerr(other.kinetic) and
floatUnerr(self.explosive) == floatUnerr(other.explosive) and
floatUnerr(self.total) == floatUnerr(other.total))
floatUnerr(self.em) == floatUnerr(other.em) and
floatUnerr(self.thermal) == floatUnerr(other.thermal) and
floatUnerr(self.kinetic) == floatUnerr(other.kinetic) and
floatUnerr(self.explosive) == floatUnerr(other.explosive) and
floatUnerr(self.total) == floatUnerr(other.total))
def __bool__(self):
return any((
@@ -110,9 +110,19 @@ class DmgTypes:
return self
def __repr__(self):
spec = ['em', 'thermal', 'kinetic', 'explosive', 'total']
spec = DmgTypes.names()
spec.append('total')
return makeReprStr(self, spec)
@staticmethod
def names(short=None, postProcessor=None):
value = ['em', 'th', 'kin', 'exp'] if short else ['em', 'thermal', 'kinetic', 'explosive']
if postProcessor:
value = [postProcessor(x) for x in value]
return value
class RRTypes:
"""Container for tank data stats."""
@@ -136,10 +146,10 @@ class RRTypes:
# Round for comparison's sake because often tanking numbers are
# generated from data which includes float errors
return (
floatUnerr(self.shield) == floatUnerr(other.shield) and
floatUnerr(self.armor) == floatUnerr(other.armor) and
floatUnerr(self.hull) == floatUnerr(other.hull) and
floatUnerr(self.capacitor) == floatUnerr(other.capacitor))
floatUnerr(self.shield) == floatUnerr(other.shield) and
floatUnerr(self.armor) == floatUnerr(other.armor) and
floatUnerr(self.hull) == floatUnerr(other.hull) and
floatUnerr(self.capacitor) == floatUnerr(other.capacitor))
def __bool__(self):
return any((self.shield, self.armor, self.hull, self.capacitor))
@@ -191,5 +201,17 @@ class RRTypes:
return self
def __repr__(self):
spec = ['shield', 'armor', 'hull', 'capacitor']
spec = RRTypes.names(False)
return makeReprStr(self, spec)
@staticmethod
def names(ehpOnly=True, postProcessor=None):
value = ['shield', 'armor', 'hull']
if not ehpOnly:
value.append('capacitor')
if postProcessor:
value = [postProcessor(x) for x in value]
return value

View File

@@ -19,7 +19,12 @@
import config
versionString = "{0}".format(config.version)
try:
versionString = "{0}".format(config.getVersion())
except NameError:
# is caught in case we run test and there are no config values initialized
versionString = "0.0"
licenses = (
"pyfa is released under GNU GPLv3 - see included LICENSE file",
"All EVE-Online related materials are property of CCP hf.",

View File

@@ -33,12 +33,17 @@ pyfalog = Logger(__name__)
class BitmapLoader:
try:
archive = zipfile.ZipFile(config.imgsZIP, 'r')
pyfalog.info("Using zipped image files.")
except (IOError, TypeError):
# Can be None if we're running from tests
if config.imgsZIP is None:
pyfalog.info("Using local image files.")
archive = None
else:
try:
archive = zipfile.ZipFile(config.imgsZIP, 'r')
pyfalog.info("Using zipped image files.")
except (IOError, TypeError):
pyfalog.info("Using local image files.")
archive = None
cached_bitmaps = OrderedDict()
dont_use_cached_bitmaps = False

View File

@@ -24,7 +24,7 @@ import yaml
from .jargon import Jargon
from .resources import DEFAULT_DATA, DEFAULT_HEADER
JARGON_PATH = os.path.join(config.savePath, 'jargon.yaml')
JARGON_PATH = os.path.join(config.savePath, 'jargon.yaml') if config.savePath is not None else None
class JargonLoader:
@@ -44,14 +44,15 @@ class JargonLoader:
def _load_jargon(self):
jargondata = yaml.load(DEFAULT_DATA, Loader=yaml.SafeLoader)
with open(JARGON_PATH) as f:
userdata = yaml.load(f, Loader=yaml.SafeLoader)
jargondata.update(userdata)
if JARGON_PATH is not None:
with open(JARGON_PATH) as f:
userdata = yaml.load(f, Loader=yaml.SafeLoader)
jargondata.update(userdata)
self.jargon_mtime = self._get_jargon_file_mtime()
self._jargon = Jargon(jargondata)
def _get_jargon_file_mtime(self) -> int:
if not os.path.exists(self.jargon_path):
if self.jargon_path is None or not os.path.exists(self.jargon_path):
return 0
return os.stat(self.jargon_path).st_mtime
@@ -82,4 +83,5 @@ class JargonLoader:
return JargonLoader._instance
JargonLoader.init_user_jargon(JARGON_PATH)
if JARGON_PATH is not None:
JargonLoader.init_user_jargon(JARGON_PATH)

View File

@@ -5,7 +5,7 @@ from numbers import Number
from logbook import Logger
import eos.db
from config import version as pyfaVersion
from config import getVersion
from service.fit import Fit
from service.market import Market
from eos.const import FittingModuleState, FittingHardpoint, FittingSlot
@@ -23,6 +23,7 @@ from gui.fitCommands.helpers import ModuleInfo
pyfalog = Logger(__name__)
pyfaVersion = getVersion()
class EfsPort:

View File

@@ -1,14 +1,15 @@
from functools import reduce
from eos.saveddata.damagePattern import DamagePattern
from eos.utils.stats import RRTypes, DmgTypes
from gui.utils.numberFormatter import formatAmount
tankTypes = ("shield", "armor", "hull")
damageTypes = ("em", "thermal", "kinetic", "explosive")
tankTypes = RRTypes.names()
damageTypes = DmgTypes.names()
damagePatterns = [DamagePattern.oneType(damageType) for damageType in damageTypes]
damageTypeResonanceNames = [damageType.capitalize() + "DamageResonance" for damageType in damageTypes]
resonanceNames = {"shield": ["shield" + s for s in damageTypeResonanceNames],
"armor": ["armor" + s for s in damageTypeResonanceNames],
"hull": [s[0].lower() + s[1:] for s in damageTypeResonanceNames]}
resonanceNames = {tankTypes[0]: [tankTypes[0] + s for s in damageTypeResonanceNames],
tankTypes[1]: [tankTypes[1] + s for s in damageTypeResonanceNames],
tankTypes[2]: [s[0].lower() + s[1:] for s in damageTypeResonanceNames]}
def firepowerSection(fit):
@@ -48,15 +49,43 @@ def tankSection(fit):
# "Hull {:>7} {:>7.0%} {:>7.0%} {:>7.0%} {:>7.0%}\n".format(ehpStr[2], *resists["hull"])
def generalOutput():
rowNames = ["EHP"]
rowNames.extend(RRTypes.names(postProcessor=lambda v: v.capitalize()))
colNames = DmgTypes.names(short=True, postProcessor=lambda v: " " + v.capitalize())
colNames[0] = colNames[0][1::]
outputScheme = []
for index, rowName in enumerate(rowNames):
row = rowName + ": {:>} ("
subsValue = " {:.0%}," if index > 0 else " {:>},"
row += ''.join([(colName + ":" + subsValue) for colName in colNames])
row = row[:-1:] + ")\n"
outputScheme.append(row)
return \
"EHP: {:>} (Em: {:>}, Th: {:>}, Kin: {:>}, Exp: {:>})\n".format(ehpStr[3], *ehpAgainstDamageTypeStr) + \
"Shield: {:>} (Em: {:.0%}, Th: {:.0%}, Kin: {:.0%}, Exp: {:.0%})\n".format(ehpStr[0], *resists["shield"]) + \
"Armor: {:>} (Em: {:.0%}, Th: {:.0%}, Kin: {:.0%}, Exp: {:.0%})\n".format(ehpStr[1], *resists["armor"]) + \
"Hull: {:>} (Em: {:.0%}, Th: {:.0%}, Kin: {:.0%}, Exp: {:.0%})\n".format(ehpStr[2], *resists["hull"])
outputScheme[0].format(ehpStr[3], *ehpAgainstDamageTypeStr) + \
outputScheme[1].format(ehpStr[0], *resists["shield"]) + \
outputScheme[2].format(ehpStr[1], *resists["armor"]) + \
outputScheme[3].format(ehpStr[2], *resists["hull"])
# return \
# "EHP: {:>} (Em: {:>}, Th: {:>}, Kin: {:>}, Exp: {:>})\n".format(ehpStr[3], *ehpAgainstDamageTypeStr) + \
# "Shield: {:>} (Em: {:.0%}, Th: {:.0%}, Kin: {:.0%}, Exp: {:.0%})\n".format(ehpStr[0], *resists["shield"]) + \
# "Armor: {:>} (Em: {:.0%}, Th: {:.0%}, Kin: {:.0%}, Exp: {:.0%})\n".format(ehpStr[1], *resists["armor"]) + \
# "Hull: {:>} (Em: {:.0%}, Th: {:.0%}, Kin: {:.0%}, Exp: {:.0%})\n".format(ehpStr[2], *resists["hull"])
return generalOutput()
def _addFormattedColumn(value, name, header, linesList, repStr):
if value:
header += "{:>7} ".format(name)
linesList = [line + "{:>7} ".format(rep) for line, rep in zip(linesList, repStr)]
return header, linesList
def repsSection(fit):
""" Returns the text of the repairs section"""
selfRep = [fit.effectiveTank[tankType + "Repair"] for tankType in tankTypes]
@@ -115,34 +144,23 @@ def repsSection(fit):
shieldRegenStr = [formatAmount(rep, 3, 0, 9) if rep != 0 else "" for rep in shieldRegen]
totalRepStr = [formatAmount(rep, 3, 0, 9) for rep in totalRep]
header = "REPS "
lines = [
"Shield ",
"Armor ",
"Hull ",
"Total "
]
lines = RRTypes.names(postProcessor=lambda v: v.capitalize())
lines.append("Total")
lines = ["{:<8}".format(line) for line in lines]
showSelfRepColumn = totalSelfRep > 0
showSustainRepColumn = sustainRep != selfRep
showRemoteRepColumn = totalRemoteRep > 0
showShieldRegenColumn = totalShieldRegen > 0
if showSelfRepColumn + showSustainRepColumn + showRemoteRepColumn + showShieldRegenColumn > 1:
header += "{:>7} ".format("TOTAL")
lines = [line + "{:>7} ".format(rep) for line, rep in zip(lines, totalRepStr)]
if showSelfRepColumn:
header += "{:>7} ".format("SELF")
lines = [line + "{:>7} ".format(rep) for line, rep in zip(lines, selfRepStr)]
if showSustainRepColumn:
header += "{:>7} ".format("SUST")
lines = [line + "{:>7} ".format(rep) for line, rep in zip(lines, sustainRepStr)]
if showRemoteRepColumn:
header += "{:>7} ".format("REMOTE")
lines = [line + "{:>7} ".format(rep) for line, rep in zip(lines, remoteRepStr)]
if showShieldRegenColumn:
header += "{:>7} ".format("REGEN")
lines = [line + "{:>7} ".format(rep) for line, rep in zip(lines, shieldRegenStr)]
header = "REPS "
header, lines = _addFormattedColumn(
(showSelfRepColumn + showSustainRepColumn + showRemoteRepColumn + showShieldRegenColumn > 1),
"TOTAL", header, lines, totalRepStr)
header, lines = _addFormattedColumn(showSelfRepColumn, "SELF", header, lines, selfRepStr)
header, lines = _addFormattedColumn(showSustainRepColumn, "SUST", header, lines, sustainRepStr)
header, lines = _addFormattedColumn(showRemoteRepColumn, "REMOTE", header, lines, remoteRepStr)
header, lines = _addFormattedColumn(showShieldRegenColumn, "REGEN", header, lines, shieldRegenStr)
text += header + "\n"
repsByTank = zip(totalRep, selfRep, sustainRep, remoteRep, shieldRegen)

View File

@@ -52143,5 +52143,110 @@
"tooltipDescriptionID": null,
"tooltipTitleID": null,
"unitID": 137
},
{
"attributeCategory": 5,
"attributeID": 2828,
"attributeIdx": null,
"attributeName": "shipBonusPDread1",
"categoryID": 9,
"chargeRechargeTimeID": null,
"dataID": 105192278,
"defaultValue": 0.0,
"description": "skill bonus for trig dread",
"displayName": "Special Ability Bonus",
"displayNameID": 318140,
"highIsGood": true,
"iconID": null,
"maxAttributeID": null,
"published": true,
"stackable": true,
"tooltipDescriptionID": null,
"tooltipTitleID": null,
"unitID": 105
},
{
"attributeCategory": 5,
"attributeID": 2829,
"attributeIdx": null,
"attributeName": "shipBonusDreadnoughtPC2",
"categoryID": 37,
"chargeRechargeTimeID": null,
"dataID": 105195411,
"defaultValue": 0.0,
"description": "Multiplied by Triglavian Dreadnought skill level",
"displayName": "",
"displayNameID": null,
"highIsGood": true,
"iconID": null,
"maxAttributeID": null,
"published": false,
"stackable": true,
"tooltipDescriptionID": null,
"tooltipTitleID": null,
"unitID": null
},
{
"attributeCategory": 5,
"attributeID": 2830,
"attributeIdx": null,
"attributeName": "shipBonusDreadnoughtPC1",
"categoryID": 37,
"chargeRechargeTimeID": null,
"dataID": 105195412,
"defaultValue": 0.0,
"description": "Multiplied by Triglavian Dreadnought skill level",
"displayName": "",
"displayNameID": null,
"highIsGood": true,
"iconID": null,
"maxAttributeID": null,
"published": false,
"stackable": true,
"tooltipDescriptionID": null,
"tooltipTitleID": null,
"unitID": null
},
{
"attributeCategory": 5,
"attributeID": 2831,
"attributeIdx": null,
"attributeName": "shipBonusDreadnoughtPC3",
"categoryID": 37,
"chargeRechargeTimeID": null,
"dataID": 105195413,
"defaultValue": 0.0,
"description": "",
"displayName": "",
"displayNameID": null,
"highIsGood": true,
"iconID": null,
"maxAttributeID": null,
"published": false,
"stackable": true,
"tooltipDescriptionID": null,
"tooltipTitleID": null,
"unitID": null
},
{
"attributeCategory": 4,
"attributeID": 2832,
"attributeIdx": null,
"attributeName": "mjdShipJumpCap",
"categoryID": 17,
"chargeRechargeTimeID": null,
"dataID": 106539665,
"defaultValue": 1.0,
"description": "The maximum number of ships that can be jumped per activation",
"displayName": "Maximum Ship Jump cap",
"displayNameID": 318141,
"highIsGood": true,
"iconID": 1391,
"maxAttributeID": null,
"published": true,
"stackable": true,
"tooltipDescriptionID": null,
"tooltipTitleID": null,
"unitID": null
}
]

View File

@@ -89284,7 +89284,7 @@
"trackingSpeedAttributeID": null
},
{
"dataID": 101783199,
"dataID": 105195555,
"description": "Atomic Beam Cannon main effect",
"descriptionID": 317020,
"disallowAutoRepeat": false,
@@ -89299,7 +89299,7 @@
"electronicChance": false,
"falloffAttributeID": null,
"fittingUsageChanceAttributeID": null,
"guid": "effects.TriglavianBeam,effects.SiegeMode",
"guid": "effects.TriglavianBeam,effects.AttackMode",
"iconID": null,
"isAssistance": false,
"isOffensive": true,
@@ -93398,7 +93398,7 @@
"trackingSpeedAttributeID": null
},
{
"dataID": 100671121,
"dataID": 105195557,
"description": null,
"descriptionID": null,
"disallowAutoRepeat": false,
@@ -93413,7 +93413,7 @@
"electronicChance": false,
"falloffAttributeID": null,
"fittingUsageChanceAttributeID": null,
"guid": "effects.TriglavianBeam,effects.SiegeMode",
"guid": "effects.TriglavianBeam,effects.AttackMode",
"iconID": null,
"isAssistance": true,
"isOffensive": false,
@@ -94655,6 +94655,40 @@
"sfxName": null,
"trackingSpeedAttributeID": null
},
{
"dataID": 105183933,
"description": null,
"descriptionID": null,
"disallowAutoRepeat": false,
"dischargeAttributeID": null,
"displayName": "",
"displayNameID": null,
"distribution": null,
"durationAttributeID": null,
"effectCategory": 2,
"effectID": 7235,
"effectName": "aoeDamageMultiplier",
"electronicChance": false,
"falloffAttributeID": null,
"fittingUsageChanceAttributeID": null,
"guid": "",
"iconID": null,
"isAssistance": false,
"isOffensive": false,
"isWarpSafe": false,
"modifierInfo": "- domain: targetID\n func: ItemModifier\n modifiedAttributeID: 292\n modifyingAttributeID: 64\n operator: 6\n",
"npcActivationChanceAttributeID": null,
"npcUsageChanceAttributeID": null,
"postExpression": null,
"preExpression": null,
"propulsionChance": false,
"published": true,
"rangeAttributeID": null,
"rangeChance": false,
"resistanceID": null,
"sfxName": null,
"trackingSpeedAttributeID": null
},
{
"dataID": 105183969,
"description": null,
@@ -94722,5 +94756,175 @@
"resistanceID": null,
"sfxName": null,
"trackingSpeedAttributeID": null
},
{
"dataID": 105195549,
"description": "precursor XL weapon damage modifier by skill level",
"descriptionID": 318139,
"disallowAutoRepeat": false,
"dischargeAttributeID": null,
"displayName": "",
"displayNameID": null,
"distribution": null,
"durationAttributeID": null,
"effectCategory": 0,
"effectID": 7238,
"effectName": "shipBonusDreadnoughtPC1DamageMultMax",
"electronicChance": false,
"falloffAttributeID": null,
"fittingUsageChanceAttributeID": null,
"guid": "",
"iconID": null,
"isAssistance": false,
"isOffensive": false,
"isWarpSafe": false,
"modifierInfo": "- domain: shipID\n func: LocationRequiredSkillModifier\n modifiedAttributeID: 64\n modifyingAttributeID: 2830\n operator: 6\n skillTypeID: 52998\n",
"npcActivationChanceAttributeID": null,
"npcUsageChanceAttributeID": null,
"postExpression": null,
"preExpression": null,
"propulsionChance": false,
"published": false,
"rangeAttributeID": null,
"rangeChance": false,
"resistanceID": 0,
"sfxName": null,
"trackingSpeedAttributeID": null
},
{
"dataID": 105195436,
"description": null,
"descriptionID": null,
"disallowAutoRepeat": false,
"dischargeAttributeID": null,
"displayName": "",
"displayNameID": null,
"distribution": null,
"durationAttributeID": null,
"effectCategory": 0,
"effectID": 7239,
"effectName": "shipBonusDreadnoughtPC2ArmorResists",
"electronicChance": false,
"falloffAttributeID": null,
"fittingUsageChanceAttributeID": null,
"guid": "",
"iconID": null,
"isAssistance": false,
"isOffensive": false,
"isWarpSafe": false,
"modifierInfo": "- domain: shipID\n func: ItemModifier\n modifiedAttributeID: 267\n modifyingAttributeID: 2829\n operator: 6\n- domain: shipID\n func: ItemModifier\n modifiedAttributeID: 270\n modifyingAttributeID: 2829\n operator: 6\n- domain: shipID\n func: ItemModifier\n modifiedAttributeID: 269\n modifyingAttributeID: 2829\n operator: 6\n- domain: shipID\n func: ItemModifier\n modifiedAttributeID: 268\n modifyingAttributeID: 2829\n operator: 6\n",
"npcActivationChanceAttributeID": null,
"npcUsageChanceAttributeID": null,
"postExpression": null,
"preExpression": null,
"propulsionChance": false,
"published": false,
"rangeAttributeID": null,
"rangeChance": false,
"resistanceID": null,
"sfxName": null,
"trackingSpeedAttributeID": null
},
{
"dataID": 105195550,
"description": null,
"descriptionID": null,
"disallowAutoRepeat": false,
"dischargeAttributeID": null,
"displayName": "",
"displayNameID": null,
"distribution": null,
"durationAttributeID": null,
"effectCategory": 0,
"effectID": 7240,
"effectName": "shipBonusDreadnoughtPC3WeaponSpeed",
"electronicChance": false,
"falloffAttributeID": null,
"fittingUsageChanceAttributeID": null,
"guid": "",
"iconID": null,
"isAssistance": false,
"isOffensive": false,
"isWarpSafe": false,
"modifierInfo": "- domain: shipID\n func: LocationRequiredSkillModifier\n modifiedAttributeID: 51\n modifyingAttributeID: 2831\n operator: 6\n skillTypeID: 52998\n",
"npcActivationChanceAttributeID": null,
"npcUsageChanceAttributeID": null,
"postExpression": null,
"preExpression": null,
"propulsionChance": false,
"published": false,
"rangeAttributeID": null,
"rangeChance": false,
"resistanceID": null,
"sfxName": null,
"trackingSpeedAttributeID": null
},
{
"dataID": 105195558,
"description": null,
"descriptionID": null,
"disallowAutoRepeat": false,
"dischargeAttributeID": null,
"displayName": "",
"displayNameID": null,
"distribution": null,
"durationAttributeID": null,
"effectCategory": 0,
"effectID": 7241,
"effectName": "skillMultiplierShipBonusDreadnoughtPrecursor",
"electronicChance": false,
"falloffAttributeID": null,
"fittingUsageChanceAttributeID": null,
"guid": "",
"iconID": null,
"isAssistance": false,
"isOffensive": false,
"isWarpSafe": false,
"modifierInfo": "- domain: shipID\n func: ItemModifier\n modifiedAttributeID: 2830\n modifyingAttributeID: 280\n operator: 0\n- domain: shipID\n func: ItemModifier\n modifiedAttributeID: 2829\n modifyingAttributeID: 280\n operator: 0\n- domain: shipID\n func: ItemModifier\n modifiedAttributeID: 2831\n modifyingAttributeID: 280\n operator: 0\n",
"npcActivationChanceAttributeID": null,
"npcUsageChanceAttributeID": null,
"postExpression": null,
"preExpression": null,
"propulsionChance": false,
"published": false,
"rangeAttributeID": null,
"rangeChance": false,
"resistanceID": null,
"sfxName": null,
"trackingSpeedAttributeID": null
},
{
"dataID": 105195530,
"description": null,
"descriptionID": null,
"disallowAutoRepeat": false,
"dischargeAttributeID": null,
"displayName": "",
"displayNameID": null,
"distribution": null,
"durationAttributeID": null,
"effectCategory": 0,
"effectID": 7242,
"effectName": "capitalPrecursorTurretDmgBonusRequiredSkill",
"electronicChance": false,
"falloffAttributeID": null,
"fittingUsageChanceAttributeID": null,
"guid": "",
"iconID": null,
"isAssistance": false,
"isOffensive": false,
"isWarpSafe": false,
"modifierInfo": "- domain: shipID\n func: LocationRequiredSkillModifier\n modifiedAttributeID: 64\n modifyingAttributeID: 292\n operator: 6\n skillTypeID: 52998\n",
"npcActivationChanceAttributeID": null,
"npcUsageChanceAttributeID": null,
"postExpression": null,
"preExpression": null,
"propulsionChance": false,
"published": false,
"rangeAttributeID": null,
"rangeChance": false,
"resistanceID": null,
"sfxName": null,
"trackingSpeedAttributeID": null
}
]

File diff suppressed because it is too large Load Diff

View File

@@ -212669,6 +212669,31 @@
"isDefault": true,
"typeID": 52694
},
{
"effectID": 7235,
"isDefault": false,
"typeID": 52700
},
{
"effectID": 10,
"isDefault": false,
"typeID": 52701
},
{
"effectID": 6882,
"isDefault": false,
"typeID": 52701
},
{
"effectID": 6884,
"isDefault": false,
"typeID": 52701
},
{
"effectID": 6885,
"isDefault": false,
"typeID": 52701
},
{
"effectID": 310,
"isDefault": false,
@@ -212774,6 +212799,16 @@
"isDefault": false,
"typeID": 52790
},
{
"effectID": 10,
"isDefault": true,
"typeID": 52797
},
{
"effectID": 878,
"isDefault": false,
"typeID": 52797
},
{
"effectID": 302,
"isDefault": false,
@@ -212824,6 +212859,131 @@
"isDefault": false,
"typeID": 52814
},
{
"effectID": 10,
"isDefault": false,
"typeID": 52815
},
{
"effectID": 6882,
"isDefault": false,
"typeID": 52815
},
{
"effectID": 6884,
"isDefault": false,
"typeID": 52815
},
{
"effectID": 6885,
"isDefault": false,
"typeID": 52815
},
{
"effectID": 6743,
"isDefault": false,
"typeID": 52842
},
{
"effectID": 7092,
"isDefault": false,
"typeID": 52907
},
{
"effectID": 7093,
"isDefault": false,
"typeID": 52907
},
{
"effectID": 7094,
"isDefault": false,
"typeID": 52907
},
{
"effectID": 7112,
"isDefault": false,
"typeID": 52907
},
{
"effectID": 7238,
"isDefault": false,
"typeID": 52907
},
{
"effectID": 7239,
"isDefault": false,
"typeID": 52907
},
{
"effectID": 7240,
"isDefault": false,
"typeID": 52907
},
{
"effectID": 12,
"isDefault": false,
"typeID": 52915
},
{
"effectID": 16,
"isDefault": false,
"typeID": 52915
},
{
"effectID": 42,
"isDefault": false,
"typeID": 52915
},
{
"effectID": 3025,
"isDefault": false,
"typeID": 52915
},
{
"effectID": 6995,
"isDefault": true,
"typeID": 52915
},
{
"effectID": 596,
"isDefault": false,
"typeID": 52916
},
{
"effectID": 804,
"isDefault": false,
"typeID": 52916
},
{
"effectID": 1173,
"isDefault": false,
"typeID": 52916
},
{
"effectID": 132,
"isDefault": true,
"typeID": 52997
},
{
"effectID": 7241,
"isDefault": false,
"typeID": 52997
},
{
"effectID": 132,
"isDefault": true,
"typeID": 52998
},
{
"effectID": 152,
"isDefault": false,
"typeID": 52998
},
{
"effectID": 7242,
"isDefault": false,
"typeID": 52998
},
{
"effectID": 302,
"isDefault": false,

View File

@@ -14765,7 +14765,7 @@
"description": "Amarr Shuttle Skins",
"descriptionID": 315927,
"hasTypes": 1,
"iconID": 2703,
"iconID": 20959,
"name": "Amarr",
"nameID": 315926,
"parentGroupID": 2315

View File

@@ -5,7 +5,7 @@
},
"2": {
"iconID": 24150,
"iconSuffix": "tech2",
"iconSuffix": "t2",
"name": "Tech II",
"nameID": 66673
},
@@ -65,7 +65,7 @@
},
"14": {
"iconID": 24151,
"iconSuffix": "tech3",
"iconSuffix": "t3",
"name": "Tech III",
"nameID": 66685
},
@@ -93,19 +93,19 @@
},
"52": {
"iconID": 24155,
"iconSuffix": "structureFaction",
"iconSuffix": "struct_faction",
"name": "Structure Faction",
"nameID": 550638
},
"53": {
"iconID": 24156,
"iconSuffix": "structureTech2",
"iconSuffix": "struct_t2",
"name": "Structure Tech II",
"nameID": 550639
},
"54": {
"iconID": 24157,
"iconSuffix": "structureTech1",
"iconSuffix": "struct",
"name": "Structure Tech I",
"nameID": 550644
}

View File

@@ -9477,6 +9477,50 @@
"published": false,
"useBasePrice": false
},
"4034": {
"anchorable": false,
"anchored": false,
"categoryID": 11,
"fittableNonSingleton": false,
"groupID": 4034,
"groupName": "Retaliating Amarr Entities",
"groupNameID": 552396,
"published": false,
"useBasePrice": false
},
"4035": {
"anchorable": false,
"anchored": false,
"categoryID": 11,
"fittableNonSingleton": false,
"groupID": 4035,
"groupName": "Retaliating Caldari Entities",
"groupNameID": 552397,
"published": false,
"useBasePrice": false
},
"4036": {
"anchorable": false,
"anchored": false,
"categoryID": 11,
"fittableNonSingleton": false,
"groupID": 4036,
"groupName": "Retaliating Gallente Entities",
"groupNameID": 552398,
"published": false,
"useBasePrice": false
},
"4037": {
"anchorable": false,
"anchored": false,
"categoryID": 11,
"fittableNonSingleton": false,
"groupID": 4037,
"groupName": "Retaliating Minmatar Entities",
"groupNameID": 552399,
"published": false,
"useBasePrice": false
},
"404": {
"anchorable": true,
"anchored": false,

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,10 @@
[
{
"field_name": "client_build",
"field_value": 1596526
"field_value": 1604553
},
{
"field_name": "dump_time",
"field_value": 1572522923
"field_value": 1573560935
}
]

View File

@@ -733,7 +733,7 @@
"text": "reduction in Small Energy Turret activation cost"
},
{
"number": "10%",
"number": "5%",
"text": "bonus to Small Energy Turret damage"
}
],
@@ -10405,7 +10405,7 @@
{
"bonuses": [
{
"number": "15%",
"number": "10%",
"text": "bonus to Small Hybrid Turret damage"
}
],
@@ -14922,7 +14922,7 @@
"text": "reduction in Microwarpdrive signature radius penalty"
},
{
"number": "10%",
"number": "5%",
"text": "bonus to Small Projectile Turret damage"
}
],
@@ -17674,6 +17674,58 @@
},
"typeID": 12735
},
{
"traits": {
"role": {
"bonuses": [
{
"text": "·Can fit a Siege module"
},
{
"number": "5x",
"text": "penalty to Entosis Link cycle time"
},
{
"number": "100%",
"text": "bonus to Remote Armor Repairer range"
},
{
"number": "50%",
"text": "reduced Energy Neutralizer capacitor need"
},
{
"number": "50%",
"text": "reduced Remote Armor Repairer capacitor need"
},
{
"number": "50%",
"text": "reduced Smart Bomb capacitor need"
}
],
"header": "Role Bonus:"
},
"skills": [
{
"bonuses": [
{
"number": "5%",
"text": "bonus to XL Disintegrator damage"
},
{
"number": "4%",
"text": "bonus to all armor resistances"
},
{
"number": "3%",
"text": "bonus to XL Disintegrator rate of fire"
}
],
"header": "Zirnitra bonuses (per skill level):"
}
]
},
"typeID": 52907
},
{
"traits": {
"skills": [
@@ -18758,7 +18810,7 @@
{
"bonuses": [
{
"number": "10%",
"number": "5%",
"text": "bonus to Small Hybrid Turret damage"
},
{

View File

@@ -0,0 +1,53 @@
# Add root folder to python paths
# This must be done on every test in order to pass in Travis
import os
import sys
script_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.realpath(os.path.join(script_dir, '..', '..', '..', '..')))
import pytest
from eos.utils.stats import DmgTypes, RRTypes
@pytest.fixture()
def setup_damage_types():
return DmgTypes(10, 20, 30, 40)
def test_dmgtypes_names():
assert DmgTypes.names() == ['em', 'thermal', 'kinetic', 'explosive']
assert DmgTypes.names(True) == ['em', 'th', 'kin', 'exp']
assert DmgTypes.names(short=True) == ['em', 'th', 'kin', 'exp']
def test_dmgtypes__repr(setup_damage_types):
assert setup_damage_types.__repr__() == '<DmgTypes(em=10, thermal=20, kinetic=30, explosive=40, total=100)>'
def test_dmgtypes_names_lambda():
assert DmgTypes.names(False, lambda v: v.capitalize()) == ['Em', 'Thermal', 'Kinetic', 'Explosive']
assert DmgTypes.names(True, lambda v: v.upper()) == ['EM', 'TH', 'KIN', 'EXP']
@pytest.fixture()
def setup_rr_types():
return RRTypes(10, 20, 30, 40)
def test_rrtypes_names():
assert RRTypes.names() == ['shield', 'armor', 'hull']
assert RRTypes.names(True) == ['shield', 'armor', 'hull']
assert RRTypes.names(ehpOnly=True) == ['shield', 'armor', 'hull']
assert RRTypes.names(False) == ['shield', 'armor', 'hull', 'capacitor']
def test_rrtypes__repr(setup_rr_types):
assert setup_rr_types.__repr__() == '<RRTypes(shield=10, armor=20, hull=30, capacitor=40)>'
def test_rrtypes_names_lambda():
assert RRTypes.names(True, lambda v: v.capitalize()) == ['Shield', 'Armor', 'Hull']
assert RRTypes.names(postProcessor=lambda v: v.upper(), ehpOnly=False) == ['SHIELD', 'ARMOR', 'HULL', 'CAPACITOR']

View File

@@ -5,7 +5,8 @@ import sys
script_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.realpath(os.path.join(script_dir, '..', '..', '..')))
# noinspection PyPackageRequirements
# This import is here to hack around circular import issues
import gui.mainFrame
# noinspection PyPackageRequirements
from service.fit import Fit

View File

@@ -9,17 +9,15 @@ import os
import sys
# nopep8
import re
# from utils.strfunctions import sequential_rep, replace_ltgt
#from utils.stopwatch import Stopwatch
script_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.realpath(os.path.join(script_dir, '..')))
sys._called_from_test = True # need db open for tests. (see eos/config.py#17
# This import is here to hack around circular import issues
import gui.mainFrame
# noinspection PyPep8
from service.port import Port, IPortUser
#
# noinspection PyPackageRequirements
# from _development.helpers import DBInMemory as DB
"""
NOTE:

View File

@@ -1 +1 @@
version: v2.14.1
version: v2.14.2