Files
pyfa/gui/builtinItemStatsViews/itemSkills.py

221 lines
8.2 KiB
Python

# noinspection PyPackageRequirements
import wx
import itertools
import gui.mainFrame
from eos.saveddata.character import Skill
from eos.saveddata.fighter import Fighter as es_Fighter
from eos.saveddata.module import Module as es_Module
from eos.saveddata.ship import Ship
from gui.utils.clipboard import toClipboard
from gui.utils.numberFormatter import formatAmount
from service.fit import Fit
_t = wx.GetTranslation
class ItemSkills(wx.Panel):
def __init__(self, parent, stuff, item):
wx.Panel.__init__(self, parent)
self.stuff = stuff
self.item = item
mainSizer = wx.BoxSizer(wx.HORIZONTAL)
leftPanel = wx.Panel(self)
leftSizer = wx.BoxSizer(wx.VERTICAL)
leftPanel.SetSizer(leftSizer)
header = wx.StaticText(leftPanel, wx.ID_ANY, _t("Components"))
font = header.GetFont()
font.SetWeight(wx.FONTWEIGHT_BOLD)
header.SetFont(font)
leftSizer.Add(header, 0, wx.ALL, 5)
self.checkboxes = {}
components = [
("Ship", "ship"),
("Modules", "modules"),
("Drones", "drones"),
("Fighters", "fighters"),
("Cargo", "cargo"),
("Implants", "appliedImplants"),
("Boosters", "boosters"),
("Necessary", "necessary"),
]
for label, key in components:
cb = wx.CheckBox(leftPanel, wx.ID_ANY, label)
cb.SetValue(True)
cb.Bind(wx.EVT_CHECKBOX, self.onCheckboxChange)
self.checkboxes[key] = cb
leftSizer.Add(cb, 0, wx.ALL, 2)
leftSizer.AddStretchSpacer()
mainSizer.Add(leftPanel, 0, wx.EXPAND | wx.ALL, 5)
rightPanel = wx.Panel(self)
rightSizer = wx.BoxSizer(wx.VERTICAL)
rightPanel.SetSizer(rightSizer)
headerRight = wx.StaticText(rightPanel, wx.ID_ANY, _t("Skills"))
fontRight = headerRight.GetFont()
fontRight.SetWeight(wx.FONTWEIGHT_BOLD)
headerRight.SetFont(fontRight)
rightSizer.Add(headerRight, 0, wx.ALL, 5)
self.skillsText = wx.TextCtrl(rightPanel, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_READONLY | wx.TE_DONTWRAP)
font = wx.Font(9, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
self.skillsText.SetFont(font)
rightSizer.Add(self.skillsText, 1, wx.EXPAND | wx.ALL, 5)
mainSizer.Add(rightPanel, 1, wx.EXPAND | wx.ALL, 5)
self.SetSizer(mainSizer)
self.nbContainer = parent if isinstance(parent, wx.Notebook) else None
if self.nbContainer:
self.nbContainer.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.onTabChanged)
self.updateSkills()
def onCheckboxChange(self, event):
self.updateSkills()
self._copyToClipboard()
def updateSkills(self):
fitID = gui.mainFrame.MainFrame.getInstance().getActiveFit()
if fitID is None:
self.skillsText.SetValue("")
self._updateCheckboxStates(None)
return
sFit = Fit.getInstance()
fit = sFit.getFit(fitID)
if fit is None:
self.skillsText.SetValue("")
self._updateCheckboxStates(None)
return
if not fit.calculated:
fit.calculate()
self._updateCheckboxStates(fit)
char = fit.character
skillsMap = {}
items = []
if self.checkboxes["ship"].GetValue():
items.append(fit.ship)
if self.checkboxes["modules"].GetValue():
items.extend(fit.modules)
if self.checkboxes["drones"].GetValue():
items.extend(fit.drones)
if self.checkboxes["fighters"].GetValue():
items.extend(fit.fighters)
if self.checkboxes["cargo"].GetValue():
items.extend(fit.cargo)
if self.checkboxes["appliedImplants"].GetValue():
items.extend(fit.appliedImplants)
if self.checkboxes["boosters"].GetValue():
items.extend(fit.boosters)
for thing in items:
self._collectAffectingSkills(thing, char, skillsMap)
if self.checkboxes["necessary"].GetValue():
self._collectRequiredSkills(items, char, skillsMap)
skillsList = ""
for skillName in sorted(skillsMap):
charLevel = skillsMap[skillName]
for level in range(1, charLevel + 1):
skillsList += "%s %d\n" % (skillName, level)
self.skillsText.SetValue(skillsList)
self._copyToClipboard()
def _copyToClipboard(self):
skillsText = self.skillsText.GetValue()
if skillsText:
toClipboard(skillsText)
def onTabChanged(self, event):
if self.nbContainer:
pageIndex = self.nbContainer.FindPage(self)
if pageIndex != -1 and event.GetSelection() == pageIndex:
self.updateSkills()
event.Skip()
def _updateCheckboxStates(self, fit):
if fit is None:
for cb in self.checkboxes.values():
cb.Enable(False)
return
self.checkboxes["ship"].Enable(True)
self.checkboxes["modules"].Enable(len(fit.modules) > 0)
self.checkboxes["drones"].Enable(len(fit.drones) > 0)
self.checkboxes["fighters"].Enable(len(fit.fighters) > 0)
self.checkboxes["cargo"].Enable(len(fit.cargo) > 0)
self.checkboxes["appliedImplants"].Enable(len(fit.appliedImplants) > 0)
self.checkboxes["boosters"].Enable(len(fit.boosters) > 0)
self.checkboxes["necessary"].Enable(True)
def _collectAffectingSkills(self, thing, char, skillsMap):
for attr in ("item", "charge"):
if attr == "charge" and isinstance(thing, es_Fighter):
continue
subThing = getattr(thing, attr, None)
if subThing is None:
continue
if isinstance(thing, es_Fighter) and attr == "charge":
continue
if attr == "charge":
cont = getattr(thing, "chargeModifiedAttributes", None)
else:
cont = getattr(thing, "itemModifiedAttributes", None)
if cont is not None:
for attrName in cont.iterAfflictions():
for fit, afflictors in cont.getAfflictions(attrName).items():
for afflictor, operator, stackingGroup, preResAmount, postResAmount, used in afflictors:
if isinstance(afflictor, Skill) and afflictor.character == char:
skillName = afflictor.item.name
if skillName not in skillsMap:
skillsMap[skillName] = afflictor.level
elif skillsMap[skillName] < afflictor.level:
skillsMap[skillName] = afflictor.level
def _collectRequiredSkills(self, items, char, skillsMap):
"""Collect required skills from items (necessary to use them)"""
for thing in items:
for attr in ("item", "charge"):
if attr == "charge" and isinstance(thing, es_Fighter):
continue
subThing = getattr(thing, attr, None)
if subThing is None:
continue
if isinstance(thing, es_Fighter) and attr == "charge":
continue
if hasattr(subThing, "requiredSkills"):
for reqSkill, level in subThing.requiredSkills.items():
skillName = reqSkill.name
charSkill = char.getSkill(reqSkill) if char else None
charLevel = charSkill.level if charSkill else 0
if charLevel > 0:
if skillName not in skillsMap:
skillsMap[skillName] = charLevel
elif skillsMap[skillName] < charLevel:
skillsMap[skillName] = charLevel
else:
if skillName not in skillsMap:
skillsMap[skillName] = level
elif skillsMap[skillName] < level:
skillsMap[skillName] = level