# 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