Merge branch 'master' into development
This commit is contained in:
@@ -42,6 +42,7 @@ If you wish to help with development or simply need to run pyfa through a Python
|
||||
* `dateutil`
|
||||
* `matplotlib` (for some Linux distributions you may need to install separate wxPython bindings such as `python-matplotlib-wx`)
|
||||
* `requests`
|
||||
* `logbook` >= 1.0.0
|
||||
|
||||
## Bug Reporting
|
||||
The preferred method of reporting bugs is through the project's [GitHub Issues interface](https://github.com/pyfa-org/Pyfa/issues). Alternatively, posting a report in the [pyfa thread](http://forums.eveonline.com/default.aspx?g=posts&t=247609) on the official EVE Online forums is acceptable. Guidelines for bug reporting can be found on [this wiki page](https://github.com/DarkFenX/Pyfa/wiki/Bug-Reporting).
|
||||
|
||||
@@ -20,7 +20,7 @@ saveInRoot = False
|
||||
|
||||
# Version data
|
||||
version = "1.28.1"
|
||||
tag = "git"
|
||||
tag = "Stable"
|
||||
expansionName = "YC119.3"
|
||||
expansionVersion = "1.0"
|
||||
evemonMinVersion = "4081"
|
||||
|
||||
@@ -128,9 +128,9 @@ class Fit(object):
|
||||
self.__capRecharge = None
|
||||
self.__calculatedTargets = []
|
||||
self.__remoteReps = {
|
||||
"Armor": None,
|
||||
"Shield": None,
|
||||
"Hull": None,
|
||||
"Armor" : None,
|
||||
"Shield" : None,
|
||||
"Hull" : None,
|
||||
"Capacitor": None,
|
||||
}
|
||||
self.factorReload = False
|
||||
@@ -370,9 +370,11 @@ class Fit(object):
|
||||
|
||||
@validates("ID", "ownerID", "shipID")
|
||||
def validator(self, key, val):
|
||||
map = {"ID": lambda _val: isinstance(_val, int),
|
||||
"ownerID": lambda _val: isinstance(_val, int) or _val is None,
|
||||
"shipID": lambda _val: isinstance(_val, int) or _val is None}
|
||||
map = {
|
||||
"ID" : lambda _val: isinstance(_val, int),
|
||||
"ownerID": lambda _val: isinstance(_val, int) or _val is None,
|
||||
"shipID" : lambda _val: isinstance(_val, int) or _val is None
|
||||
}
|
||||
|
||||
if not map[key](val):
|
||||
raise ValueError(str(val) + " is not a valid value for " + key)
|
||||
@@ -408,15 +410,15 @@ class Fit(object):
|
||||
self.ship.clear()
|
||||
|
||||
c = chain(
|
||||
self.modules,
|
||||
self.drones,
|
||||
self.fighters,
|
||||
self.boosters,
|
||||
self.implants,
|
||||
self.projectedDrones,
|
||||
self.projectedModules,
|
||||
self.projectedFighters,
|
||||
(self.character, self.extraAttributes),
|
||||
self.modules,
|
||||
self.drones,
|
||||
self.fighters,
|
||||
self.boosters,
|
||||
self.implants,
|
||||
self.projectedDrones,
|
||||
self.projectedModules,
|
||||
self.projectedFighters,
|
||||
(self.character, self.extraAttributes),
|
||||
)
|
||||
|
||||
for stuff in c:
|
||||
@@ -476,11 +478,11 @@ class Fit(object):
|
||||
|
||||
if warfareBuffID == 11: # Shield Burst: Active Shielding: Repair Duration/Capacitor
|
||||
self.modules.filteredItemBoost(
|
||||
lambda mod: mod.item.requiresSkill("Shield Operation") or mod.item.requiresSkill(
|
||||
"Shield Emission Systems"), "capacitorNeed", value)
|
||||
lambda mod: mod.item.requiresSkill("Shield Operation") or mod.item.requiresSkill(
|
||||
"Shield Emission Systems"), "capacitorNeed", value)
|
||||
self.modules.filteredItemBoost(
|
||||
lambda mod: mod.item.requiresSkill("Shield Operation") or mod.item.requiresSkill(
|
||||
"Shield Emission Systems"), "duration", value)
|
||||
lambda mod: mod.item.requiresSkill("Shield Operation") or mod.item.requiresSkill(
|
||||
"Shield Emission Systems"), "duration", value)
|
||||
|
||||
if warfareBuffID == 12: # Shield Burst: Shield Extension: Shield HP
|
||||
self.ship.boostItemAttr("shieldCapacity", value, stackingPenalties=True)
|
||||
@@ -506,26 +508,26 @@ class Fit(object):
|
||||
if warfareBuffID == 17: # Information Burst: Electronic Superiority: EWAR Range and Strength
|
||||
groups = ("ECM", "Sensor Dampener", "Weapon Disruptor", "Target Painter")
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.group.name in groups, "maxRange", value,
|
||||
stackingPenalties=True)
|
||||
stackingPenalties=True)
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.group.name in groups,
|
||||
"falloffEffectiveness", value, stackingPenalties=True)
|
||||
"falloffEffectiveness", value, stackingPenalties=True)
|
||||
|
||||
for scanType in ("Magnetometric", "Radar", "Ladar", "Gravimetric"):
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.group.name == "ECM",
|
||||
"scan%sStrengthBonus" % scanType, value,
|
||||
stackingPenalties=True)
|
||||
"scan%sStrengthBonus" % scanType, value,
|
||||
stackingPenalties=True)
|
||||
|
||||
for attr in ("missileVelocityBonus", "explosionDelayBonus", "aoeVelocityBonus", "falloffBonus",
|
||||
"maxRangeBonus", "aoeCloudSizeBonus", "trackingSpeedBonus"):
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Weapon Disruptor",
|
||||
attr, value)
|
||||
attr, value)
|
||||
|
||||
for attr in ("maxTargetRangeBonus", "scanResolutionBonus"):
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Sensor Dampener",
|
||||
attr, value)
|
||||
attr, value)
|
||||
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Target Painter",
|
||||
"signatureRadiusBonus", value, stackingPenalties=True)
|
||||
"signatureRadiusBonus", value, stackingPenalties=True)
|
||||
|
||||
if warfareBuffID == 18: # Information Burst: Electronic Hardening: Scan Strength
|
||||
for scanType in ("Gravimetric", "Radar", "Ladar", "Magnetometric"):
|
||||
@@ -544,40 +546,36 @@ class Fit(object):
|
||||
if warfareBuffID == 21: # Skirmish Burst: Interdiction Maneuvers: Tackle Range
|
||||
groups = ("Stasis Web", "Warp Scrambler")
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.group.name in groups, "maxRange", value,
|
||||
stackingPenalties=True)
|
||||
stackingPenalties=True)
|
||||
|
||||
if warfareBuffID == 22: # Skirmish Burst: Rapid Deployment: AB/MWD Speed Increase
|
||||
self.modules.filteredItemBoost(
|
||||
lambda mod: mod.item.requiresSkill("Afterburner")
|
||||
or mod.item.requiresSkill("High Speed Maneuvering"),
|
||||
"speedFactor", value, stackingPenalties=True)
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Afterburner") or
|
||||
mod.item.requiresSkill("High Speed Maneuvering"),
|
||||
"speedFactor", value, stackingPenalties=True)
|
||||
|
||||
if warfareBuffID == 23: # Mining Burst: Mining Laser Field Enhancement: Mining/Survey Range
|
||||
self.modules.filteredItemBoost(
|
||||
lambda mod: mod.item.requiresSkill("Mining") or
|
||||
mod.item.requiresSkill("Ice Harvesting") or
|
||||
mod.item.requiresSkill("Gas Cloud Harvesting"),
|
||||
"maxRange", value, stackingPenalties=True)
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining") or
|
||||
mod.item.requiresSkill("Ice Harvesting") or
|
||||
mod.item.requiresSkill("Gas Cloud Harvesting"),
|
||||
"maxRange", value, stackingPenalties=True)
|
||||
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("CPU Management"),
|
||||
"surveyScanRange", value, stackingPenalties=True)
|
||||
"surveyScanRange", value, stackingPenalties=True)
|
||||
|
||||
if warfareBuffID == 24: # Mining Burst: Mining Laser Optimization: Mining Capacitor/Duration
|
||||
self.modules.filteredItemBoost(
|
||||
lambda mod: mod.item.requiresSkill("Mining") or
|
||||
mod.item.requiresSkill("Ice Harvesting") or
|
||||
mod.item.requiresSkill("Gas Cloud Harvesting"),
|
||||
"capacitorNeed", value, stackingPenalties=True)
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining") or
|
||||
mod.item.requiresSkill("Ice Harvesting") or
|
||||
mod.item.requiresSkill("Gas Cloud Harvesting"),
|
||||
"capacitorNeed", value, stackingPenalties=True)
|
||||
|
||||
self.modules.filteredItemBoost(
|
||||
lambda mod: mod.item.requiresSkill("Mining") or
|
||||
mod.item.requiresSkill("Ice Harvesting") or
|
||||
mod.item.requiresSkill("Gas Cloud Harvesting"),
|
||||
"duration", value, stackingPenalties=True)
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining") or
|
||||
mod.item.requiresSkill("Ice Harvesting") or
|
||||
mod.item.requiresSkill("Gas Cloud Harvesting"),
|
||||
"duration", value, stackingPenalties=True)
|
||||
|
||||
if warfareBuffID == 25: # Mining Burst: Mining Equipment Preservation: Crystal Volatility
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining"),
|
||||
"crystalVolatilityChance", value, stackingPenalties=True)
|
||||
"crystalVolatilityChance", value, stackingPenalties=True)
|
||||
|
||||
if warfareBuffID == 60: # Skirmish Burst: Evasive Maneuvers: Agility
|
||||
self.ship.boostItemAttr("agility", value, stackingPenalties=True)
|
||||
@@ -850,15 +848,17 @@ class Fit(object):
|
||||
|
||||
return amount
|
||||
|
||||
slots = {Slot.LOW: "lowSlots",
|
||||
Slot.MED: "medSlots",
|
||||
Slot.HIGH: "hiSlots",
|
||||
Slot.RIG: "rigSlots",
|
||||
Slot.SUBSYSTEM: "maxSubSystems",
|
||||
Slot.SERVICE: "serviceSlots",
|
||||
Slot.F_LIGHT: "fighterLightSlots",
|
||||
Slot.F_SUPPORT: "fighterSupportSlots",
|
||||
Slot.F_HEAVY: "fighterHeavySlots"}
|
||||
slots = {
|
||||
Slot.LOW : "lowSlots",
|
||||
Slot.MED : "medSlots",
|
||||
Slot.HIGH : "hiSlots",
|
||||
Slot.RIG : "rigSlots",
|
||||
Slot.SUBSYSTEM: "maxSubSystems",
|
||||
Slot.SERVICE : "serviceSlots",
|
||||
Slot.F_LIGHT : "fighterLightSlots",
|
||||
Slot.F_SUPPORT: "fighterSupportSlots",
|
||||
Slot.F_HEAVY : "fighterHeavySlots"
|
||||
}
|
||||
|
||||
def getSlotsFree(self, type, countDummies=False):
|
||||
if type in (Slot.MODE, Slot.SYSTEM):
|
||||
@@ -1007,29 +1007,35 @@ class Fit(object):
|
||||
def calculateSustainableTank(self, effective=True):
|
||||
if self.__sustainableTank is None:
|
||||
if self.capStable:
|
||||
sustainable = {"armorRepair": self.extraAttributes["armorRepair"],
|
||||
"shieldRepair": self.extraAttributes["shieldRepair"],
|
||||
"hullRepair": self.extraAttributes["hullRepair"]}
|
||||
sustainable = {
|
||||
"armorRepair" : self.extraAttributes["armorRepair"],
|
||||
"shieldRepair": self.extraAttributes["shieldRepair"],
|
||||
"hullRepair" : self.extraAttributes["hullRepair"]
|
||||
}
|
||||
else:
|
||||
sustainable = {}
|
||||
|
||||
repairers = []
|
||||
# Map a repairer type to the attribute it uses
|
||||
groupAttrMap = {"Armor Repair Unit": "armorDamageAmount",
|
||||
"Ancillary Armor Repairer": "armorDamageAmount",
|
||||
"Hull Repair Unit": "structureDamageAmount",
|
||||
"Shield Booster": "shieldBonus",
|
||||
"Ancillary Shield Booster": "shieldBonus",
|
||||
"Remote Armor Repairer": "armorDamageAmount",
|
||||
"Remote Shield Booster": "shieldBonus"}
|
||||
groupAttrMap = {
|
||||
"Armor Repair Unit" : "armorDamageAmount",
|
||||
"Ancillary Armor Repairer": "armorDamageAmount",
|
||||
"Hull Repair Unit" : "structureDamageAmount",
|
||||
"Shield Booster" : "shieldBonus",
|
||||
"Ancillary Shield Booster": "shieldBonus",
|
||||
"Remote Armor Repairer" : "armorDamageAmount",
|
||||
"Remote Shield Booster" : "shieldBonus"
|
||||
}
|
||||
# Map repairer type to attribute
|
||||
groupStoreMap = {"Armor Repair Unit": "armorRepair",
|
||||
"Hull Repair Unit": "hullRepair",
|
||||
"Shield Booster": "shieldRepair",
|
||||
"Ancillary Shield Booster": "shieldRepair",
|
||||
"Remote Armor Repairer": "armorRepair",
|
||||
"Remote Shield Booster": "shieldRepair",
|
||||
"Ancillary Armor Repairer": "armorRepair", }
|
||||
groupStoreMap = {
|
||||
"Armor Repair Unit" : "armorRepair",
|
||||
"Hull Repair Unit" : "hullRepair",
|
||||
"Shield Booster" : "shieldRepair",
|
||||
"Ancillary Shield Booster": "shieldRepair",
|
||||
"Remote Armor Repairer" : "armorRepair",
|
||||
"Remote Shield Booster" : "shieldRepair",
|
||||
"Ancillary Armor Repairer": "armorRepair",
|
||||
}
|
||||
|
||||
capUsed = self.capUsed
|
||||
for attr in ("shieldRepair", "armorRepair", "hullRepair"):
|
||||
@@ -1057,7 +1063,7 @@ class Fit(object):
|
||||
|
||||
# Sort repairers by efficiency. We want to use the most efficient repairers first
|
||||
repairers.sort(key=lambda _mod: _mod.getModifiedItemAttr(
|
||||
groupAttrMap[_mod.item.group.name]) / _mod.getModifiedItemAttr("capacitorNeed"), reverse=True)
|
||||
groupAttrMap[_mod.item.group.name]) / _mod.getModifiedItemAttr("capacitorNeed"), reverse=True)
|
||||
|
||||
# Loop through every module until we're above peak recharge
|
||||
# Most efficient first, as we sorted earlier.
|
||||
@@ -1370,10 +1376,10 @@ class Fit(object):
|
||||
|
||||
def __repr__(self):
|
||||
return u"Fit(ID={}, ship={}, name={}) at {}".format(
|
||||
self.ID, self.ship.item.name, self.name, hex(id(self))
|
||||
self.ID, self.ship.item.name, self.name, hex(id(self))
|
||||
).encode('utf8')
|
||||
|
||||
def __str__(self):
|
||||
return u"{} ({})".format(
|
||||
self.name, self.ship.item.name
|
||||
self.name, self.ship.item.name
|
||||
).encode('utf8')
|
||||
|
||||
@@ -173,7 +173,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
charges = 0
|
||||
else:
|
||||
charges = floor(containerCapacity / chargeVolume)
|
||||
return charges
|
||||
return int(charges)
|
||||
|
||||
@property
|
||||
def numShots(self):
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
__all__ = [
|
||||
"openFit",
|
||||
# "moduleGlobalAmmoPicker",
|
||||
"moduleAmmoPicker",
|
||||
"itemStats",
|
||||
"damagePattern",
|
||||
"marketJump",
|
||||
"droneSplit",
|
||||
"itemRemove",
|
||||
"droneRemoveStack",
|
||||
"ammoPattern",
|
||||
"project",
|
||||
"factorReload",
|
||||
"whProjector",
|
||||
"cargo",
|
||||
"shipJump",
|
||||
"changeAffectingSkills",
|
||||
"tacticalMode",
|
||||
"targetResists",
|
||||
"priceClear",
|
||||
"amount",
|
||||
"metaSwap",
|
||||
"implantSets",
|
||||
"fighterAbilities",
|
||||
"cargoAmmo",
|
||||
"droneStack"
|
||||
]
|
||||
|
||||
@@ -3,13 +3,19 @@ import gui.mainFrame
|
||||
import service
|
||||
import gui.globalEvents as GE
|
||||
import wx
|
||||
from service.settings import ContextMenuSettings
|
||||
from service.fit import Fit
|
||||
|
||||
|
||||
class CargoAmmo(ContextMenu):
|
||||
def __init__(self):
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
self.settings = ContextMenuSettings.getInstance()
|
||||
|
||||
def display(self, srcContext, selection):
|
||||
if not self.settings.get('cargoAmmo'):
|
||||
return False
|
||||
|
||||
if srcContext not in ("marketItemGroup", "marketItemMisc") or self.mainFrame.getActiveFit() is None:
|
||||
return False
|
||||
|
||||
@@ -23,7 +29,7 @@ class CargoAmmo(ContextMenu):
|
||||
return "Add {0} to Cargo (x1000)".format(itmContext)
|
||||
|
||||
def activate(self, fullContext, selection, i):
|
||||
sFit = service.Fit.getInstance()
|
||||
sFit = Fit.getInstance()
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
|
||||
typeID = int(selection[0].ID)
|
||||
|
||||
@@ -3,13 +3,19 @@ import gui.mainFrame
|
||||
import service
|
||||
import gui.globalEvents as GE
|
||||
import wx
|
||||
from service.settings import ContextMenuSettings
|
||||
from service.fit import Fit
|
||||
|
||||
|
||||
class CargoAmmo(ContextMenu):
|
||||
class DroneStack(ContextMenu):
|
||||
def __init__(self):
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
self.settings = ContextMenuSettings.getInstance()
|
||||
|
||||
def display(self, srcContext, selection):
|
||||
if not self.settings.get('droneStack'):
|
||||
return False
|
||||
|
||||
if srcContext not in ("marketItemGroup", "marketItemMisc") or self.mainFrame.getActiveFit() is None:
|
||||
return False
|
||||
|
||||
@@ -25,7 +31,7 @@ class CargoAmmo(ContextMenu):
|
||||
return "Add {0} to Drone Bay (x5)".format(itmContext)
|
||||
|
||||
def activate(self, fullContext, selection, i):
|
||||
sFit = service.Fit.getInstance()
|
||||
sFit = Fit.getInstance()
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
|
||||
typeID = int(selection[0].ID)
|
||||
@@ -34,4 +40,4 @@ class CargoAmmo(ContextMenu):
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
|
||||
|
||||
|
||||
CargoAmmo.register()
|
||||
DroneStack.register()
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
from gui.statsView import StatsView
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from gui.utils.numberFormatter import formatAmount
|
||||
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@ class ContextMenu(object):
|
||||
# noinspection PyUnresolvedReferences
|
||||
from gui.builtinContextMenus import ( # noqa: E402,F401
|
||||
openFit,
|
||||
# moduleGlobalAmmoPicker,
|
||||
moduleGlobalAmmoPicker,
|
||||
moduleAmmoPicker,
|
||||
itemStats,
|
||||
damagePattern,
|
||||
@@ -200,6 +200,8 @@ from gui.builtinContextMenus import ( # noqa: E402,F401
|
||||
targetResists,
|
||||
priceClear,
|
||||
amount,
|
||||
cargoAmmo,
|
||||
droneStack,
|
||||
metaSwap,
|
||||
implantSets,
|
||||
fighterAbilities,
|
||||
|
||||
@@ -29,13 +29,14 @@ import gui.mainFrame
|
||||
import gui.globalEvents as GE
|
||||
from gui.graph import Graph
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
import traceback
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
try:
|
||||
import matplotlib as mpl
|
||||
|
||||
mpl_version = int(mpl.__version__[0])
|
||||
mpl_version = int(mpl.__version__[0]) or -1
|
||||
if mpl_version >= 2:
|
||||
mpl.use('wxagg')
|
||||
mplImported = True
|
||||
@@ -48,43 +49,33 @@ try:
|
||||
|
||||
graphFrame_enabled = True
|
||||
mplImported = True
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
pyfalog.warning("Matplotlib failed to import. Likely missing or incompatible version.")
|
||||
mpl_version = -1
|
||||
Patch = mpl = Canvas = Figure = None
|
||||
graphFrame_enabled = False
|
||||
mplImported = False
|
||||
except Exception:
|
||||
# We can get exceptions deep within matplotlib. Catch those. See GH #1046
|
||||
tb = traceback.format_exc()
|
||||
pyfalog.critical("Exception when importing Matplotlib. Continuing without importing.")
|
||||
pyfalog.critical(tb)
|
||||
mpl_version = -1
|
||||
Patch = mpl = Canvas = Figure = None
|
||||
graphFrame_enabled = False
|
||||
mplImported = False
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class GraphFrame(wx.Frame):
|
||||
def __init__(self, parent, style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE | wx.FRAME_FLOAT_ON_PARENT):
|
||||
|
||||
global graphFrame_enabled
|
||||
global mplImported
|
||||
|
||||
self.Patch = None
|
||||
self.mpl_version = -1
|
||||
|
||||
try:
|
||||
import matplotlib as mpl
|
||||
self.mpl_version = int(mpl.__version__[0])
|
||||
if self.mpl_version >= 2:
|
||||
mpl.use('wxagg')
|
||||
mplImported = True
|
||||
else:
|
||||
mplImported = False
|
||||
from matplotlib.patches import Patch
|
||||
self.Patch = Patch
|
||||
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as Canvas
|
||||
from matplotlib.figure import Figure
|
||||
graphFrame_enabled = True
|
||||
except ImportError:
|
||||
Patch = mpl = Canvas = Figure = None
|
||||
graphFrame_enabled = False
|
||||
global mpl_version
|
||||
|
||||
self.legendFix = False
|
||||
|
||||
if not graphFrame_enabled:
|
||||
pyfalog.info("Problems importing matplotlib; continuing without graphs")
|
||||
pyfalog.warning("Matplotlib is not enabled. Skipping initialization.")
|
||||
return
|
||||
|
||||
try:
|
||||
@@ -236,6 +227,8 @@ class GraphFrame(wx.Frame):
|
||||
self.draw()
|
||||
|
||||
def draw(self, event=None):
|
||||
global mpl_version
|
||||
|
||||
values = self.getValues()
|
||||
view = self.getView()
|
||||
self.subplot.clear()
|
||||
@@ -260,7 +253,7 @@ class GraphFrame(wx.Frame):
|
||||
self.canvas.draw()
|
||||
return
|
||||
|
||||
if self.mpl_version < 2:
|
||||
if mpl_version < 2:
|
||||
if self.legendFix and len(legend) > 0:
|
||||
leg = self.subplot.legend(tuple(legend), "upper right", shadow=False)
|
||||
for t in leg.get_texts():
|
||||
@@ -276,7 +269,7 @@ class GraphFrame(wx.Frame):
|
||||
|
||||
for l in leg.get_lines():
|
||||
l.set_linewidth(1)
|
||||
elif self.mpl_version >= 2:
|
||||
elif mpl_version >= 2:
|
||||
legend2 = []
|
||||
legend_colors = {
|
||||
0: "blue",
|
||||
|
||||
5
pyfa.py
5
pyfa.py
@@ -26,6 +26,7 @@ import config
|
||||
|
||||
from optparse import OptionParser, BadOptionError, AmbiguousOptionError
|
||||
|
||||
import logbook
|
||||
from logbook import TimedRotatingFileHandler, Logger, StreamHandler, NestedSetup, FingersCrossedHandler, NullHandler, \
|
||||
CRITICAL, ERROR, WARNING, DEBUG, INFO
|
||||
pyfalog = Logger(__name__)
|
||||
@@ -144,6 +145,10 @@ if not hasattr(sys, 'frozen'):
|
||||
print("Cannot find python-dateutil.\nYou can download python-dateutil from https://pypi.python.org/pypi/python-dateutil")
|
||||
sys.exit(1)
|
||||
|
||||
logVersion = logbook.__version__.split('.')
|
||||
if int(logVersion[0]) < 1:
|
||||
print ("Logbook version >= 1.0.0 is recommended. You may have some performance issues by continuing to use an earlier version.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Configure paths
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
logbook
|
||||
logbook>=1.0.0
|
||||
matplotlib
|
||||
PyYAML
|
||||
python-dateutil
|
||||
|
||||
@@ -408,14 +408,17 @@ class ContextMenuSettings(object):
|
||||
"ammoPattern" : 1,
|
||||
"amount" : 1,
|
||||
"cargo" : 1,
|
||||
"cargoAmmo" : 1,
|
||||
"changeAffectingSkills" : 1,
|
||||
"damagePattern" : 1,
|
||||
"droneRemoveStack" : 1,
|
||||
"droneSplit" : 1,
|
||||
"droneStack" : 1,
|
||||
"factorReload" : 1,
|
||||
"fighterAbilities" : 1,
|
||||
"implantSet" : 1,
|
||||
"implantSets" : 1,
|
||||
"itemStats" : 1,
|
||||
"itemRemove" : 1,
|
||||
"marketJump" : 1,
|
||||
"metaSwap" : 1,
|
||||
"moduleAmmoPicker" : 1,
|
||||
|
||||
Reference in New Issue
Block a user