Merge branch 'master' into ammo_graph

This commit is contained in:
DarkPhoenix
2019-12-07 03:34:26 +03:00
129 changed files with 17059 additions and 845 deletions

View File

@@ -1,4 +1,5 @@
from collections import OrderedDict
from itertools import chain
# noinspection PyPackageRequirements
import wx
@@ -6,7 +7,8 @@ import wx
import gui.globalEvents as GE
import gui.mainFrame
from gui.contextMenu import ContextMenuUnconditional
from service.damagePattern import DamagePattern as import_DamagePattern
from gui.utils.sorter import smartSort
from service.damagePattern import DamagePattern as DmgPatternSvc
from service.fit import Fit
@@ -23,97 +25,88 @@ class ChangeDamagePattern(ContextMenuUnconditional):
return self.mainFrame.getActiveFit() is not None
def getText(self, callingWindow, itmContext):
sDP = import_DamagePattern.getInstance()
sDP = DmgPatternSvc.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
self.fit = sFit.getFit(fitID)
self.patterns = sDP.getDamagePatternList()
self.patterns.sort(key=lambda p: (p.name not in ["Uniform", "Selected Ammo"], p.name))
# Order here is important: patterns with duplicate names from the latter will overwrite
# patterns from the former
self.patterns = list(chain(sDP.getBuiltinDamagePatternList(), sDP.getUserDamagePatternList()))
self.patterns.sort(key=lambda p: (p.fullName not in ["Uniform", "Selected Ammo"], smartSort(p.fullName)))
self.patternIds = {}
self.subMenus = OrderedDict()
self.singles = []
self.patternEventMap = {}
# iterate and separate damage patterns based on "[Parent] Child"
self.items = (OrderedDict(), OrderedDict())
for pattern in self.patterns:
start, end = pattern.name.find('['), pattern.name.find(']')
if start is not -1 and end is not -1:
currBase = pattern.name[start + 1:end]
name = pattern.name[end + 1:].strip()
if not name:
self.singles.append(pattern)
continue
# set helper attr
setattr(pattern, "_name", name)
if currBase not in self.subMenus:
self.subMenus[currBase] = []
self.subMenus[currBase].append(pattern)
else:
self.singles.append(pattern)
container = self.items
for categoryName in pattern.hierarchy:
container = container[1].setdefault(categoryName, (OrderedDict(), OrderedDict()))
container[0][pattern.shortName] = pattern
# return list of names, with singles first followed by submenu names
self.m = [p.name for p in self.singles] + list(self.subMenus.keys())
return self.m
return list(self.items[0].keys()) + list(self.items[1].keys())
def addPattern(self, rootMenu, pattern):
def _addPattern(self, parentMenu, pattern, name):
id = ContextMenuUnconditional.nextID()
name = getattr(pattern, "_name", pattern.name) if pattern is not None else "No Profile"
self.patternIds[id] = pattern
menuItem = wx.MenuItem(rootMenu, id, name, kind=wx.ITEM_CHECK)
rootMenu.Bind(wx.EVT_MENU, self.handlePatternSwitch, menuItem)
# set pattern attr to menu item
menuItem.pattern = pattern
self.patternEventMap[id] = pattern
menuItem = wx.MenuItem(parentMenu, id, name, kind=wx.ITEM_CHECK)
parentMenu.Bind(wx.EVT_MENU, self.handlePatternSwitch, menuItem)
# determine active pattern
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
fit = sFit.getFit(fitID)
if fit:
dp = fit.damagePattern
checked = dp is pattern
else:
checked = False
checked = fit.damagePattern is pattern if fit else False
return menuItem, checked
def _addCategory(self, parentMenu, name):
id = ContextMenuUnconditional.nextID()
menuItem = wx.MenuItem(parentMenu, id, name)
parentMenu.Bind(wx.EVT_MENU, self.handlePatternSwitch, menuItem)
return menuItem
def isChecked(self, i):
try:
single = self.singles[i]
patternName = list(self.items[0].keys())[i]
except IndexError:
return super().isChecked(i)
if self.fit and single is self.fit.damagePattern:
pattern = self.items[0][patternName]
if self.fit and pattern is self.fit.damagePattern:
return True
return False
def getSubMenu(self, callingWindow, context, rootMenu, i, pitem):
# Attempt to remove attribute which carries info if non-sub-items should
# be checked or not
self.checked = None
if self.m[i] not in self.subMenus:
# if we're trying to get submenu to something that shouldn't have one,
# redirect event of the item to handlePatternSwitch and put pattern in
# our patternIds mapping, then return None for no submenu
# Pattern as menu item
if i < len(self.items[0]):
id = pitem.GetId()
self.patternIds[id] = self.singles[i]
self.patternEventMap[id] = list(self.items[0].values())[i]
rootMenu.Bind(wx.EVT_MENU, self.handlePatternSwitch, pitem)
return False
sub = wx.Menu()
# Items that have a parent
# Category as menu item - expands further
msw = "wxMSW" in wx.PlatformInfo
for pattern in self.subMenus[self.m[i]]:
mitem, checked = self.addPattern(rootMenu if msw else sub, pattern)
sub.Append(mitem)
mitem.Check(checked)
return sub
def makeMenu(container, parentMenu):
menu = wx.Menu()
for name, subcontainer in container[1].items():
menuItem = self._addCategory(rootMenu if msw else parentMenu, name)
subMenu = makeMenu(subcontainer, menu)
menuItem.SetSubMenu(subMenu)
menu.Append(menuItem)
for name, pattern in container[0].items():
menuItem, checked = self._addPattern(rootMenu if msw else parentMenu, pattern, name)
menu.Append(menuItem)
menuItem.Check(checked)
menu.Bind(wx.EVT_MENU, self.handlePatternSwitch)
return menu
container = list(self.items[1].values())[i - len(self.items[0])]
subMenu = makeMenu(container, rootMenu)
return subMenu
def handlePatternSwitch(self, event):
pattern = self.patternIds.get(event.Id, False)
pattern = self.patternEventMap.get(event.Id, False)
if pattern is False:
event.Skip()
return

View File

@@ -7,6 +7,7 @@ import wx
import gui.mainFrame
from eos.saveddata.targetProfile import TargetProfile
from gui.contextMenu import ContextMenuUnconditional
from gui.utils.sorter import smartSort
from service.targetProfile import TargetProfile as svc_TargetProfile
@@ -18,74 +19,68 @@ class TargetProfileAdder(ContextMenuUnconditional):
def display(self, callingWindow, srcContext):
if srcContext != 'graphTgtList':
return False
sTR = svc_TargetProfile.getInstance()
self.callingWindow = callingWindow
self.profiles = sTR.getTargetProfileList()
self.profiles.sort(key=lambda p: (p.name in ['None'], p.name))
return len(self.profiles) > 0
# We always show "Ideal Profile" anyway
return True
def getText(self, callingWindow, itmContext):
return 'Add Target Profile'
def handleProfileAdd(self, event):
profile = self.profileIds.get(event.Id, False)
profile = self.profileEventMap.get(event.Id, False)
if profile is False:
event.Skip()
return
self.callingWindow.addProfile(profile)
def addProfile(self, rootMenu, profile):
def _addProfile(self, parentMenu, profile, name):
id = ContextMenuUnconditional.nextID()
name = getattr(profile, '_name', profile.name)
self.profileEventMap[id] = profile
menuItem = wx.MenuItem(parentMenu, id, name)
parentMenu.Bind(wx.EVT_MENU, self.handleProfileAdd, menuItem)
return menuItem
self.profileIds[id] = profile
item = wx.MenuItem(rootMenu, id, name)
rootMenu.Bind(wx.EVT_MENU, self.handleProfileAdd, item)
return item
def _addCategory(self, parentMenu, name):
id = ContextMenuUnconditional.nextID()
menuItem = wx.MenuItem(parentMenu, id, name)
parentMenu.Bind(wx.EVT_MENU, self.handleProfileAdd, menuItem)
return menuItem
def getSubMenu(self, callingWindow, context, rootMenu, i, pitem):
self.profileIds = {}
self.subMenus = OrderedDict()
self.singles = []
self.callingWindow = callingWindow
sTR = svc_TargetProfile.getInstance()
profiles = list(chain(sTR.getBuiltinTargetProfileList(), sTR.getUserTargetProfileList()))
profiles.sort(key=lambda p: smartSort(p.fullName))
sub = wx.Menu()
for profile in chain([TargetProfile.getIdeal()], self.profiles):
start, end = profile.name.find('['), profile.name.find(']')
if start is not -1 and end is not -1:
currBase = profile.name[start + 1:end]
# set helper attr
setattr(profile, '_name', profile.name[end + 1:].strip())
if currBase not in self.subMenus:
self.subMenus[currBase] = []
self.subMenus[currBase].append(profile)
else:
self.singles.append(profile)
self.profileEventMap = {}
items = (OrderedDict(), OrderedDict())
for profile in profiles:
container = items
for categoryName in profile.hierarchy:
container = container[1].setdefault(categoryName, (OrderedDict(), OrderedDict()))
container[0][profile.shortName] = profile
# Single items, no parent
msw = 'wxMSW' in wx.PlatformInfo
for profile in self.singles:
sub.Append(self.addProfile(rootMenu if msw else sub, profile))
# Category as menu item - expands further
msw = "wxMSW" in wx.PlatformInfo
# Items that have a parent
for menuName, profiles in list(self.subMenus.items()):
# Create parent item for root menu that is simply name of parent
item = wx.MenuItem(rootMenu, ContextMenuUnconditional.nextID(), menuName)
def makeMenu(container, parentMenu, first=False):
menu = wx.Menu()
if first:
idealProfile = TargetProfile.getIdeal()
mitem = self._addProfile(rootMenu if msw else parentMenu, idealProfile, idealProfile.fullName)
menu.Append(mitem)
for name, pattern in container[0].items():
menuItem = self._addProfile(rootMenu if msw else parentMenu, pattern, name)
menu.Append(menuItem)
for name, subcontainer in container[1].items():
menuItem = self._addCategory(rootMenu if msw else parentMenu, name)
subMenu = makeMenu(subcontainer, menu)
menuItem.SetSubMenu(subMenu)
menu.Append(menuItem)
menu.Bind(wx.EVT_MENU, self.handleProfileAdd)
return menu
# Create menu for child items
grandSub = wx.Menu()
# Apply child menu to parent item
item.SetSubMenu(grandSub)
# Append child items to child menu
for profile in profiles:
grandSub.Append(self.addProfile(rootMenu if msw else grandSub, profile))
sub.Append(item) # finally, append parent item to root menu
return sub
subMenu = makeMenu(items, rootMenu, first=True)
return subMenu
TargetProfileAdder.register()

View File

@@ -1,5 +1,4 @@
import gui.mainFrame
from eos.saveddata.targetProfile import TargetProfile
from graphs.wrapper import TargetWrapper
from gui.contextMenu import ContextMenuSingle
from gui.targetProfileEditor import TargetProfileEditor
@@ -17,7 +16,7 @@ class TargetProfileEditorMenu(ContextMenuSingle):
return False
if not mainItem.isProfile:
return False
if mainItem.item is TargetProfile.getIdeal():
if mainItem.item.builtin:
return False
return True

View File

@@ -1,4 +1,5 @@
from collections import OrderedDict
from itertools import chain
# noinspection PyPackageRequirements
import wx
@@ -6,6 +7,7 @@ import wx
import gui.globalEvents as GE
import gui.mainFrame
from gui.contextMenu import ContextMenuUnconditional
from gui.utils.sorter import smartSort
from service.fit import Fit
from service.targetProfile import TargetProfile as svc_TargetProfile
@@ -16,21 +18,19 @@ class TargetProfileSwitcher(ContextMenuUnconditional):
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
def display(self, callingWindow, srcContext):
if self.mainFrame.getActiveFit() is None or srcContext != 'firepowerViewFull':
if srcContext != 'firepowerViewFull':
return False
sTR = svc_TargetProfile.getInstance()
self.profiles = sTR.getTargetProfileList()
self.profiles.sort(key=lambda p: (p.name in ['None'], p.name))
return len(self.profiles) > 0
if self.mainFrame.getActiveFit() is None:
return False
# We always show "No Profile" anyway
return True
def getText(self, callingWindow, itmContext):
# We take into consideration just target resists, so call menu item accordingly
return 'Target Resists'
def handleResistSwitch(self, event):
profile = self.profileIds.get(event.Id, False)
profile = self.profileEventMap.get(event.Id, False)
if profile is False:
event.Skip()
return
@@ -40,77 +40,62 @@ class TargetProfileSwitcher(ContextMenuUnconditional):
sFit.setTargetProfile(fitID, profile)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitIDs=(fitID,)))
def addProfile(self, rootMenu, profile):
def _addProfile(self, parentMenu, profile, name):
id = ContextMenuUnconditional.nextID()
name = getattr(profile, '_name', profile.name) if profile is not None else 'No Profile'
self.profileIds[id] = profile
item = wx.MenuItem(rootMenu, id, name, kind=wx.ITEM_CHECK)
rootMenu.Bind(wx.EVT_MENU, self.handleResistSwitch, item)
self.profileEventMap[id] = profile
menuItem = wx.MenuItem(parentMenu, id, name, kind=wx.ITEM_CHECK)
parentMenu.Bind(wx.EVT_MENU, self.handleResistSwitch, menuItem)
# determine active profile
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
f = sFit.getFit(fitID)
tr = f.targetProfile
checked = sFit.getFit(fitID).targetProfile is profile
return menuItem, checked
checked = tr == profile
return item, checked
def _addCategory(self, parentMenu, name):
id = ContextMenuUnconditional.nextID()
menuItem = wx.MenuItem(parentMenu, id, name)
parentMenu.Bind(wx.EVT_MENU, self.handleResistSwitch, menuItem)
return menuItem
def getSubMenu(self, callingWindow, context, rootMenu, i, pitem):
self.profileIds = {}
self.subMenus = OrderedDict()
self.singles = []
sTR = svc_TargetProfile.getInstance()
profiles = list(chain(sTR.getBuiltinTargetProfileList(), sTR.getUserTargetProfileList()))
profiles.sort(key=lambda p: smartSort(p.fullName))
sub = wx.Menu()
for profile in self.profiles:
start, end = profile.name.find('['), profile.name.find(']')
if start is not -1 and end is not -1:
currBase = profile.name[start + 1:end]
name = profile.name[end + 1:].strip()
if not name:
self.singles.append(profile)
continue
# set helper attr
setattr(profile, '_name', name)
if currBase not in self.subMenus:
self.subMenus[currBase] = []
self.subMenus[currBase].append(profile)
else:
self.singles.append(profile)
# Add reset
msw = 'wxMSW' in wx.PlatformInfo
mitem, checked = self.addProfile(rootMenu if msw else sub, None)
sub.Append(mitem)
mitem.Check(checked)
sub.AppendSeparator()
self.profileEventMap = {}
items = (OrderedDict(), OrderedDict())
for profile in profiles:
container = items
for categoryName in profile.hierarchy:
container = container[1].setdefault(categoryName, (OrderedDict(), OrderedDict()))
container[0][profile.shortName] = profile
# Single items, no parent
for profile in self.singles:
mitem, checked = self.addProfile(rootMenu if msw else sub, profile)
sub.Append(mitem)
mitem.Check(checked)
# Category as menu item - expands further
msw = "wxMSW" in wx.PlatformInfo
# Items that have a parent
for menuName, profiles in list(self.subMenus.items()):
# Create parent item for root menu that is simply name of parent
item = wx.MenuItem(rootMenu, ContextMenuUnconditional.nextID(), menuName)
# Create menu for child items
grandSub = wx.Menu()
# Apply child menu to parent item
item.SetSubMenu(grandSub)
# Append child items to child menu
for profile in profiles:
mitem, checked = self.addProfile(rootMenu if msw else grandSub, profile)
grandSub.Append(mitem)
def makeMenu(container, parentMenu, first=False):
menu = wx.Menu()
if first:
mitem, checked = self._addProfile(rootMenu if msw else parentMenu, None, 'No Profile')
menu.Append(mitem)
mitem.Check(checked)
sub.Append(item) # finally, append parent item to root menu
if len(container[0]) > 0 or len(container[1]) > 0:
menu.AppendSeparator()
for name, pattern in container[0].items():
menuItem, checked = self._addProfile(rootMenu if msw else parentMenu, pattern, name)
menu.Append(menuItem)
menuItem.Check(checked)
for name, subcontainer in container[1].items():
menuItem = self._addCategory(rootMenu if msw else parentMenu, name)
subMenu = makeMenu(subcontainer, menu)
menuItem.SetSubMenu(subMenu)
menu.Append(menuItem)
menu.Bind(wx.EVT_MENU, self.handleResistSwitch)
return menu
return sub
subMenu = makeMenu(items, rootMenu, first=True)
return subMenu
TargetProfileSwitcher.register()

View File

@@ -1,7 +1,6 @@
import wx
import config
from eos.db.saveddata.loadDefaultDatabaseValues import DefaultDatabaseValues
from eos.db.saveddata.queries import clearPrices, clearDamagePatterns, clearTargetProfiles
from gui.bitmap_loader import BitmapLoader
from gui.preferenceView import PreferenceView
@@ -75,10 +74,6 @@ class PFGeneralPref(PreferenceView):
btnSizer = wx.BoxSizer(wx.VERTICAL)
btnSizer.AddStretchSpacer()
self.btnImportDefaults = wx.Button(panel, wx.ID_ANY, "Reimport Database Defaults", wx.DefaultPosition, wx.DefaultSize, 0)
btnSizer.Add(self.btnImportDefaults, 0, wx.ALL, 5)
self.btnImportDefaults.Bind(wx.EVT_BUTTON, self.loadDatabaseDefaults)
self.btnDeleteDamagePatterns = wx.Button(panel, wx.ID_ANY, "Delete All Damage Pattern Profiles", wx.DefaultPosition, wx.DefaultSize, 0)
btnSizer.Add(self.btnDeleteDamagePatterns, 0, wx.ALL, 5)
self.btnDeleteDamagePatterns.Bind(wx.EVT_BUTTON, self.DeleteDamagePatterns)
@@ -97,14 +92,6 @@ class PFGeneralPref(PreferenceView):
panel.SetSizer(mainSizer)
panel.Layout()
def loadDatabaseDefaults(self, event):
# Import values that must exist otherwise Pyfa breaks
DefaultDatabaseValues.importRequiredDefaults()
# Import default values for damage profiles
DefaultDatabaseValues.importDamageProfileDefaults()
# Import default values for target resist profiles
DefaultDatabaseValues.importTargetProfileDefaults()
def DeleteDamagePatterns(self, event):
question = "This is a destructive action that will delete all damage pattern profiles.\nAre you sure you want to do this?"
if wxHelpers.YesNoDialog(question, "Confirm"):

View File

@@ -133,11 +133,17 @@ class CapacitorViewFull(StatsView):
label.SetLabel('{}{}'.format(formatAmount(value, prec, lowest, highest, forceSign=forceSign), unit))
label.SetToolTip(wx.ToolTip("%.1f" % value))
if labelName == 'label%sCapacitorDelta':
label_tooltip = 'Capacitor delta:\n+{} GJ/s\n-{} GJ/s'.format(
formatAmount(cap_recharge, 3, 0, 3),
formatAmount(cap_use, 3, 0, 3))
label.SetToolTip(wx.ToolTip(label_tooltip))
if labelName == 'label%sCapacitorDelta' and (cap_recharge or cap_use):
lines = []
lines.append('Capacitor delta:')
lines.append(' +{} GJ/s'.format(formatAmount(cap_recharge, 3, 0, 3)))
lines.append(' -{} GJ/s'.format(formatAmount(cap_use, 3, 0, 3)))
delta = round(cap_recharge - cap_use, 3)
if delta > 0 and neut_res < 1:
lines.append('')
lines.append('Effective excessive gain:')
lines.append(' +{} GJ/s'.format(formatAmount(delta / neut_res, 3, 0, 3)))
label.SetToolTip(wx.ToolTip('\n'.join(lines)))
if labelName == 'label%sCapacitorResist':
texts = ['Neutralizer resistance']
if cap_amount > 0 and neut_res < 1:

View File

@@ -151,52 +151,71 @@ class FirepowerViewFull(StatsView):
else:
self.stEff.Hide()
def dpsToolTip(preSpool, fullSpool, prec, lowest, highest):
if roundToPrec(preSpool, prec) == roundToPrec(fullSpool, prec):
def hasSpoolUp(preSpool, fullSpool):
if preSpool is None or fullSpool is None:
return False
return roundToPrec(preSpool.total, prec) != roundToPrec(fullSpool.total, prec)
def dpsToolTip(normal, preSpool, fullSpool, prec, lowest, highest):
if normal is None or preSpool is None or fullSpool is None:
return ""
else:
return "Spool up: {}-{}".format(
formatAmount(preSpool, prec, lowest, highest),
formatAmount(fullSpool, prec, lowest, highest))
hasSpool = hasSpoolUp(preSpool, fullSpool)
lines = []
if hasSpool:
lines.append("Spool up: {}-{}".format(
formatAmount(preSpool.total, prec, lowest, highest),
formatAmount(fullSpool.total, prec, lowest, highest)))
if getattr(normal, 'total', None):
if hasSpool:
lines.append("")
lines.append("Current: {}".format(formatAmount(normal.total, prec, lowest, highest)))
for dmgType in normal.names():
val = getattr(normal, dmgType, None)
if val:
lines.append("{}{}: {}%".format(
" " if hasSpool else "",
dmgType.capitalize(),
formatAmount(val / normal.total * 100, 3, 0, 0)))
return "\n".join(lines)
defaultSpoolValue = eos.config.settings['globalDefaultSpoolupPercentage']
stats = (
(
"labelFullDpsWeapon",
lambda: fit.getWeaponDps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, defaultSpoolValue, False)).total,
lambda: fit.getWeaponDps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 0, True)).total,
lambda: fit.getWeaponDps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 1, True)).total,
lambda: fit.getWeaponDps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, defaultSpoolValue, False)),
lambda: fit.getWeaponDps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 0, True)),
lambda: fit.getWeaponDps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 1, True)),
3, 0, 0, "{}{} DPS"),
(
"labelFullDpsDrone",
lambda: fit.getDroneDps().total,
lambda: fit.getDroneDps().total,
lambda: fit.getDroneDps().total,
lambda: fit.getDroneDps(),
lambda: fit.getDroneDps(),
lambda: fit.getDroneDps(),
3, 0, 0, "{}{} DPS"),
(
"labelFullVolleyTotal",
lambda: fit.getTotalVolley(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, defaultSpoolValue, False)).total,
lambda: fit.getTotalVolley(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 0, True)).total,
lambda: fit.getTotalVolley(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 1, True)).total,
lambda: fit.getTotalVolley(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, defaultSpoolValue, False)),
lambda: fit.getTotalVolley(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 0, True)),
lambda: fit.getTotalVolley(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 1, True)),
3, 0, 0, "{}{}"),
(
"labelFullDpsTotal",
lambda: fit.getTotalDps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, defaultSpoolValue, False)).total,
lambda: fit.getTotalDps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 0, True)).total,
lambda: fit.getTotalDps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 1, True)).total,
lambda: fit.getTotalDps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, defaultSpoolValue, False)),
lambda: fit.getTotalDps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 0, True)),
lambda: fit.getTotalDps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 1, True)),
3, 0, 0, "{}{}"))
counter = 0
for labelName, val, preSpoolVal, fullSpoolVal, prec, lowest, highest, valueFormat in stats:
label = getattr(self, labelName)
val = val() if fit is not None else 0
preSpoolVal = preSpoolVal() if fit is not None else 0
fullSpoolVal = fullSpoolVal() if fit is not None else 0
val = val() if fit is not None else None
preSpoolVal = preSpoolVal() if fit is not None else None
fullSpoolVal = fullSpoolVal() if fit is not None else None
if self._cachedValues[counter] != val:
tooltipText = dpsToolTip(preSpoolVal, fullSpoolVal, prec, lowest, highest)
tooltipText = dpsToolTip(val, preSpoolVal, fullSpoolVal, prec, lowest, highest)
label.SetLabel(valueFormat.format(
formatAmount(val, prec, lowest, highest),
"\u02e2" if tooltipText else ""))
formatAmount(0 if val is None else val.total, prec, lowest, highest),
"\u02e2" if hasSpoolUp(preSpoolVal, fullSpoolVal) else ""))
label.SetToolTip(wx.ToolTip(tooltipText))
self._cachedValues[counter] = val
counter += 1

View File

@@ -111,7 +111,7 @@ class BaseName(ViewColumn):
elif isinstance(stuff, Implant):
return stuff.item.name
elif isinstance(stuff, TargetProfile):
return stuff.name
return stuff.shortName
else:
item = getattr(stuff, "item", stuff)

View File

@@ -182,12 +182,12 @@ class ContextMenu(metaclass=ABCMeta):
return ContextMenu._ids[ContextMenu._idxid]
def isChecked(self, i):
'''If menu item is toggleable, this should return bool value'''
"""If menu item is toggleable, this should return bool value"""
return None
@property
def enabled(self):
'''If menu item is enabled. Allows an item to display, but not be selected'''
"""If menu item is enabled. Allows an item to display, but not be selected"""
return True
@abstractmethod

View File

@@ -321,7 +321,7 @@ def activeStateLimit(itemIdentity):
item = Market.getInstance().getItem(itemIdentity)
if {
'moduleBonusAssaultDamageControl', 'moduleBonusIndustrialInvulnerability',
'microJumpDrive', 'microJumpPortalDrive'
'microJumpDrive', 'microJumpPortalDrive', 'emergencyHullEnergizer'
}.intersection(item.effects):
return FittingModuleState.ONLINE
return FittingModuleState.ACTIVE

View File

@@ -48,7 +48,7 @@ class DmgPatternNameValidator(BaseValidator):
try:
if len(text) == 0:
raise ValueError("You must supply a name for your Damage Profile!")
elif text in [x.name for x in entityEditor.choices]:
elif text in [x.rawName for x in entityEditor.choices]:
raise ValueError("Damage Profile name already in use, please choose another.")
return True
@@ -66,8 +66,8 @@ class DmgPatternEntityEditor(EntityEditor):
def getEntitiesFromContext(self):
sDP = DamagePattern.getInstance()
choices = sorted(sDP.getDamagePatternList(), key=lambda p: p.name)
return [c for c in choices if c.name != "Selected Ammo"]
choices = sorted(sDP.getUserDamagePatternList(), key=lambda p: p.rawName)
return [c for c in choices if c.rawName != "Selected Ammo"]
def DoNew(self, name):
sDP = DamagePattern.getInstance()
@@ -237,7 +237,7 @@ class DmgPatternEditor(AuxiliaryFrame):
if p is None:
return
if p.name == "Uniform" or p.name == "Selected Ammo":
if p.rawName == "Uniform" or p.rawName == "Selected Ammo":
self.restrict()
else:
self.unrestrict()

View File

@@ -68,7 +68,7 @@ class TargetProfileNameValidator(BaseValidator):
try:
if len(text) == 0:
raise ValueError("You must supply a name for your Target Profile!")
elif text in [x.name for x in entityEditor.choices]:
elif text in [x.rawName for x in entityEditor.choices]:
raise ValueError("Target Profile name already in use, please choose another.")
return True
@@ -88,7 +88,7 @@ class TargetProfileEntityEditor(EntityEditor):
def getEntitiesFromContext(self):
sTR = TargetProfile.getInstance()
choices = sorted(sTR.getTargetProfileList(), key=lambda p: p.name)
choices = sorted(sTR.getUserTargetProfileList(), key=lambda p: p.rawName)
return choices
def DoNew(self, name):

13
gui/utils/sorter.py Normal file
View File

@@ -0,0 +1,13 @@
"""
Taken from https://stackoverflow.com/questions/2669059/how-to-sort-alpha-numeric-set-in-python
"""
import re
def _convert(text):
return int(text) if text.isdigit() else text
def smartSort(key):
return [_convert(c) for c in re.split('([0-9]+)', key)]