From 1ab76a7170f8809adee0a5831cdb942a3e97a24e Mon Sep 17 00:00:00 2001 From: blitzmann Date: Wed, 3 Sep 2014 00:49:53 -0400 Subject: [PATCH 01/11] Commit initial work for effect DPS / Target resists --- eos/db/__init__.py | 2 +- eos/db/migration.py | 17 + eos/db/saveddata/__init__.py | 2 +- eos/db/saveddata/fit.py | 7 +- eos/db/saveddata/queries.py | 30 +- eos/db/saveddata/targetResists.py | 35 ++ eos/saveddata/fit.py | 16 +- eos/saveddata/module.py | 11 +- eos/saveddata/targetResists.py | 82 +++++ eos/types.py | 1 + gui/builtinContextMenus/__init__.py | 3 +- gui/builtinContextMenus/targetResists.py | 98 ++++++ gui/builtinStatsViews/firepowerViewFull.py | 13 +- gui/mainFrame.py | 8 + gui/mainMenuBar.py | 5 + gui/resistsEditor.py | 353 +++++++++++++++++++++ service/__init__.py | 1 + service/fit.py | 21 ++ service/targetResists.py | 92 ++++++ 19 files changed, 781 insertions(+), 16 deletions(-) create mode 100644 eos/db/saveddata/targetResists.py create mode 100644 eos/saveddata/targetResists.py create mode 100644 gui/builtinContextMenus/targetResists.py create mode 100644 gui/resistsEditor.py create mode 100644 service/targetResists.py diff --git a/eos/db/__init__.py b/eos/db/__init__.py index 7891414352..a02979112c 100644 --- a/eos/db/__init__.py +++ b/eos/db/__init__.py @@ -66,7 +66,7 @@ class ReadOnlyException(Exception): getCharacterList, getPrice, getDamagePatternList, getDamagePattern, \ getFitList, getFleetList, getFleet, save, remove, commit, add, \ getCharactersForUser, getMiscData, getSquadsIDsWithFitID, getWing, \ - getSquad, getBoosterFits, getProjectedFits + getSquad, getBoosterFits, getProjectedFits, getTargetResistsList, getTargetResists #If using in memory saveddata, you'll want to reflect it so the data structure is good. if config.saveddata_connectionstring == "sqlite:///:memory:": diff --git a/eos/db/migration.py b/eos/db/migration.py index 2c67b8334f..81399f4a5a 100644 --- a/eos/db/migration.py +++ b/eos/db/migration.py @@ -4,6 +4,7 @@ def update(saveddata_engine): checkPriceFailures(saveddata_engine) checkApiDefaultChar(saveddata_engine) checkFitBooster(saveddata_engine) + checktargetResists(saveddata_engine) def checkPriceFailures(saveddata_engine): # Check if we have 'failed' column @@ -57,3 +58,19 @@ def checkFitBooster(saveddata_engine): saveddata_engine.execute("ALTER TABLE fits ADD COLUMN booster BOOLEAN;") # Set NULL data to 0 (needed in case of downgrade, see GH issue #62 saveddata_engine.execute("UPDATE fits SET booster = 0 WHERE booster IS NULL;") + +def checktargetResists(saveddata_engine): + try: + saveddata_engine.execute("SELECT * FROM fits LIMIT 1") + # If table doesn't exist, it means we're doing everything from scratch + # and sqlalchemy will process everything as needed + except sqlalchemy.exc.DatabaseError: + pass + # If not, we're running on top of existing DB + else: + # Check that we have columns + try: + saveddata_engine.execute("SELECT targetResistsID FROM fits LIMIT 1") + # If we don't, create them + except sqlalchemy.exc.DatabaseError: + saveddata_engine.execute("ALTER TABLE fits ADD COLUMN targetResistsID INTEGER;") diff --git a/eos/db/saveddata/__init__.py b/eos/db/saveddata/__init__.py index 70c7b22ec0..31e71c01ac 100644 --- a/eos/db/saveddata/__init__.py +++ b/eos/db/saveddata/__init__.py @@ -1,3 +1,3 @@ __all__ = ["character", "fit", "module", "user", "skill", "price", "booster", "drone", "implant", "fleet", "damagePattern", - "miscData"] + "miscData", "targetResists"] diff --git a/eos/db/saveddata/fit.py b/eos/db/saveddata/fit.py index ccb8bbb716..b06b8f9242 100644 --- a/eos/db/saveddata/fit.py +++ b/eos/db/saveddata/fit.py @@ -26,10 +26,11 @@ from eos.db.saveddata.drone import drones_table from eos.db.saveddata.cargo import cargo_table from eos.db.saveddata.implant import fitImplants_table -from eos.types import Fit, Module, User, Booster, Drone, Cargo, Implant, Character, DamagePattern +from eos.types import Fit, Module, User, Booster, Drone, Cargo, Implant, Character, DamagePattern, TargetResists from eos.effectHandlerHelpers import HandledModuleList, HandledDroneList, \ HandledImplantBoosterList, HandledProjectedModList, HandledProjectedDroneList, \ HandledProjectedFitList, HandledCargoList + fits_table = Table("fits", saveddata_meta, Column("ID", Integer, primary_key = True), Column("ownerID", ForeignKey("users.ID"), nullable = True, index = True), @@ -38,7 +39,8 @@ Column("timestamp", Integer, nullable = False), Column("characterID", ForeignKey("characters.ID"), nullable = True), Column("damagePatternID", ForeignKey("damagePatterns.ID"), nullable=True), - Column("booster", Boolean, nullable = False, index = True, default = 0)) + Column("booster", Boolean, nullable = False, index = True, default = 0), + Column("targetResistsID", ForeignKey("targetResists.ID"), nullable=True)) projectedFits_table = Table("projectedFits", saveddata_meta, Column("sourceID", ForeignKey("fits.ID"), primary_key = True), @@ -64,6 +66,7 @@ secondary = fitImplants_table), "_Fit__character" : relation(Character, backref = "fits"), "_Fit__damagePattern" : relation(DamagePattern), + "_Fit__targetResists" : relation(TargetResists), "_Fit__projectedFits" : relation(Fit, primaryjoin = projectedFits_table.c.victimID == fits_table.c.ID, secondaryjoin = fits_table.c.ID == projectedFits_table.c.sourceID, diff --git a/eos/db/saveddata/queries.py b/eos/db/saveddata/queries.py index ddb8d53ac6..e939bb65fb 100644 --- a/eos/db/saveddata/queries.py +++ b/eos/db/saveddata/queries.py @@ -19,7 +19,7 @@ from eos.db.util import processEager, processWhere from eos.db import saveddata_session, sd_lock -from eos.types import User, Character, Fit, Price, DamagePattern, Fleet, MiscData, Wing, Squad +from eos.types import User, Character, Fit, Price, DamagePattern, Fleet, MiscData, Wing, Squad, TargetResists from eos.db.saveddata.fleet import squadmembers_table from eos.db.saveddata.fit import projectedFits_table from sqlalchemy.sql import and_ @@ -322,6 +322,12 @@ def getDamagePatternList(eager=None): patterns = saveddata_session.query(DamagePattern).options(*eager).all() return patterns +def getTargetResistsList(eager=None): + eager = processEager(eager) + with sd_lock: + patterns = saveddata_session.query(TargetResists).options(*eager).all() + return patterns + @cachedQuery(DamagePattern, 1, "lookfor") def getDamagePattern(lookfor, eager=None): if isinstance(lookfor, int): @@ -340,6 +346,24 @@ def getDamagePattern(lookfor, eager=None): raise TypeError("Need integer or string as argument") return pattern +@cachedQuery(TargetResists, 1, "lookfor") +def getTargetResists(lookfor, eager=None): + if isinstance(lookfor, int): + if eager is None: + with sd_lock: + pattern = saveddata_session.query(TargetResists).get(lookfor) + else: + eager = processEager(eager) + with sd_lock: + pattern = saveddata_session.query(TargetResists).options(*eager).filter(TargetResists.ID == lookfor).first() + elif isinstance(lookfor, basestring): + eager = processEager(eager) + with sd_lock: + pattern = saveddata_session.query(TargetResists).options(*eager).filter(TargetResists.name == lookfor).first() + else: + raise TypeError("Need integer or string as argument") + return pattern + def searchFits(nameLike, where=None, eager=None): if not isinstance(nameLike, basestring): raise TypeError("Need string as argument") @@ -361,7 +385,7 @@ def getSquadsIDsWithFitID(fitID): return squads else: raise TypeError("Need integer as argument") - + def getProjectedFits(fitID): if isinstance(fitID, int): with sd_lock: @@ -369,7 +393,7 @@ def getProjectedFits(fitID): fits = saveddata_session.query(Fit).filter(filter).all() return fits else: - raise TypeError("Need integer as argument") + raise TypeError("Need integer as argument") def add(stuff): with sd_lock: diff --git a/eos/db/saveddata/targetResists.py b/eos/db/saveddata/targetResists.py new file mode 100644 index 0000000000..f7106fe45f --- /dev/null +++ b/eos/db/saveddata/targetResists.py @@ -0,0 +1,35 @@ +#=============================================================================== +# Copyright (C) 2014 Ryan Holmes +# +# This file is part of eos. +# +# eos is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# eos is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with eos. If not, see . +#=============================================================================== + +from sqlalchemy import Table, Column, Integer, Float, ForeignKey, String +from sqlalchemy.orm import mapper + +from eos.db import saveddata_meta +from eos.types import TargetResists + +targetResists_table = Table("targetResists", saveddata_meta, + Column("ID", Integer, primary_key = True), + Column("name", String), + Column("emAmount", Float), + Column("thermalAmount", Float), + Column("kineticAmount", Float), + Column("explosiveAmount", Float), + Column("ownerID", ForeignKey("users.ID"), nullable=True)) + +mapper(TargetResists, targetResists_table) diff --git a/eos/saveddata/fit.py b/eos/saveddata/fit.py index e2aaaa8470..65df79ebf5 100644 --- a/eos/saveddata/fit.py +++ b/eos/saveddata/fit.py @@ -99,6 +99,17 @@ def build(self): self.extraAttributes.original = self.EXTRA_ATTRIBUTES self.ship = Ship(db.getItem(self.shipID)) if self.shipID is not None else None + @property + def targetResists(self): + return self.__targetResists + + @targetResists.setter + def targetResists(self, targetResists): + self.__targetResists = targetResists + self.__weaponDPS = None + self.__weaponVolley = None + self.__droneDPS = None + @property def damagePattern(self): return self.__damagePattern @@ -809,9 +820,9 @@ def calculateWeaponStats(self): weaponDPS = 0 droneDPS = 0 weaponVolley = 0 - + print "calc weapons with: %s"%self.targetResists for mod in self.modules: - dps, volley = mod.damageStats + dps, volley = mod.damageStats(self.targetResists) weaponDPS += dps weaponVolley += volley @@ -838,6 +849,7 @@ def __deepcopy__(self, memo): copy.ship = deepcopy(self.ship, memo) copy.name = "%s copy" % self.name copy.damagePattern = self.damagePattern + copy.targetResists = self.targetResists toCopy = ("modules", "drones", "implants", "boosters", "projectedModules", "projectedDrones") for name in toCopy: diff --git a/eos/saveddata/module.py b/eos/saveddata/module.py index 2e68816c38..de65e62249 100644 --- a/eos/saveddata/module.py +++ b/eos/saveddata/module.py @@ -44,7 +44,7 @@ class Hardpoint(Enum): class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): """An instance of this class represents a module together with its charge and modified attributes""" - DAMAGE_ATTRIBUTES = ("emDamage", "kineticDamage", "explosiveDamage", "thermalDamage") + DAMAGE_TYPES = ("em", "thermal", "kinetic", "explosive") MINING_ATTRIBUTES = ("miningAmount", ) def __init__(self, item): @@ -308,8 +308,7 @@ def charge(self, charge): self.__itemModifiedAttributes.clear() - @property - def damageStats(self): + def damageStats(self, targetResists): if self.__dps == None: if self.isEmpty: self.__dps = 0 @@ -317,9 +316,11 @@ def damageStats(self): else: if self.state >= State.ACTIVE: if self.charge: - volley = sum(map(lambda attr: self.getModifiedChargeAttr(attr) or 0, self.DAMAGE_ATTRIBUTES)) + func = self.getModifiedChargeAttr else: - volley = sum(map(lambda attr: self.getModifiedItemAttr(attr) or 0, self.DAMAGE_ATTRIBUTES)) + func = self.getModifiedItemAttr + + volley = sum(map(lambda attr: (func("%sDamage"%attr) or 0) * (1-getattr(targetResists, "%sAmount"%attr, 0)), self.DAMAGE_TYPES)) volley *= self.getModifiedItemAttr("damageMultiplier") or 1 if volley: cycleTime = self.cycleTime diff --git a/eos/saveddata/targetResists.py b/eos/saveddata/targetResists.py new file mode 100644 index 0000000000..7512e1dfc9 --- /dev/null +++ b/eos/saveddata/targetResists.py @@ -0,0 +1,82 @@ +#=============================================================================== +# Copyright (C) 2014 Ryan Holmes +# +# This file is part of eos. +# +# eos is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# eos is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with eos. If not, see . +#=============================================================================== + +import re + +class TargetResists(object): + # also determined import/export order - VERY IMPORTANT + DAMAGE_TYPES = ("em", "thermal", "kinetic", "explosive") + + def __init__(self, emAmount = 0, thermalAmount = 0, kineticAmount = 0, explosiveAmount = 0): + print "new" + self.emAmount = emAmount + self.thermalAmount = thermalAmount + self.kineticAmount = kineticAmount + self.explosiveAmount = explosiveAmount + + @classmethod + def importPatterns(cls, text): + lines = re.split('[\n\r]+', text) + patterns = [] + + for line in lines: + if line.strip()[0] == "#": # comments + continue + line = line.split('#',1)[0] # allows for comments + type, data = line.rsplit('=',1) + type, data = type.strip(), data.split(',') + + #if type != "TargetResists": + #continue + + name, data = data[0], data[1:5] + #print name, data + fields = {} + + for index, val in enumerate(data): + val = float(val) + try: + assert 0 <= val <= 100 + fields["%sAmount" % cls.DAMAGE_TYPES[index]] = val/100 + except: + continue + + if len(fields) == 4: # Avoid possible blank lines + print name, fields + pattern = TargetResists(**fields) + pattern.name = name.strip() + patterns.append(pattern) + + return patterns + + EXPORT_FORMAT = "TargetResists = %s,%.1f,%.1f,%.1f,%.1f\n" + @classmethod + def exportPatterns(cls, *patterns): + out = "# Exported from pyfa\n#\n" + out += "# Values are in following format:\n" + out += "# TargetResists = [name],[EM %],[Thermal %],[Kinetic %],[Explosive %]\n\n" + for dp in patterns: + out += cls.EXPORT_FORMAT % (dp.name, dp.emAmount*100, dp.thermalAmount*100, dp.kineticAmount*100, dp.explosiveAmount*100) + + return out.strip() + + def __deepcopy__(self, memo): + p = TargetResists(self.emAmount, self.thermalAmount, self.kineticAmount, self.explosiveAmount) + p.name = "%s copy" % self.name + return p diff --git a/eos/types.py b/eos/types.py index 9896e526a4..3e5223f4bc 100644 --- a/eos/types.py +++ b/eos/types.py @@ -22,6 +22,7 @@ from eos.saveddata.price import Price from eos.saveddata.user import User from eos.saveddata.damagePattern import DamagePattern +from eos.saveddata.targetResists import TargetResists from eos.saveddata.character import Character, Skill from eos.saveddata.module import Module, State, Slot, Hardpoint, Rack from eos.saveddata.drone import Drone diff --git a/gui/builtinContextMenus/__init__.py b/gui/builtinContextMenus/__init__.py index 4f93b84240..bd385255d3 100644 --- a/gui/builtinContextMenus/__init__.py +++ b/gui/builtinContextMenus/__init__.py @@ -1,2 +1,3 @@ __all__ = ["moduleAmmoPicker", "itemStats", "damagePattern", "marketJump", "droneSplit", "itemRemove", - "droneRemoveStack", "ammoPattern", "project", "factorReload", "whProjector", "cargo", "shipJump"] + "droneRemoveStack", "ammoPattern", "project", "factorReload", "whProjector", "cargo", "shipJump", + "targetResists"] diff --git a/gui/builtinContextMenus/targetResists.py b/gui/builtinContextMenus/targetResists.py new file mode 100644 index 0000000000..24904b4297 --- /dev/null +++ b/gui/builtinContextMenus/targetResists.py @@ -0,0 +1,98 @@ +# -*- coding: utf-8 -*- + +from gui.contextMenu import ContextMenu +import gui.mainFrame +import service +import gui.globalEvents as GE +import wx +from gui import bitmapLoader + +class TargetResists(ContextMenu): + def __init__(self): + self.mainFrame = gui.mainFrame.MainFrame.getInstance() + + def display(self, srcContext, selection): + if self.mainFrame.getActiveFit() is None or srcContext not in ("firepowerViewFull",): + return False + + sTR = service.TargetResists.getInstance() + self.patterns = sTR.getTargetResistsList() + self.patterns.sort( key=lambda p: (p.name in ["None"], p.name) ) + return len(self.patterns) > 0 + + def getText(self, itmContext, selection): + return "Target Resists" + + def activate(self, fullContext, selection, i): + pass + + def handleResistSwitch(self, event): + pattern = self.patternIds.get(event.Id, False) + if pattern is False: + event.Skip() + return + + sFit = service.Fit.getInstance() + fitID = self.mainFrame.getActiveFit() + sFit.setTargetResists(fitID, pattern) + wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID)) + + def addPattern(self, menu, pattern, currBase = None): + id = wx.NewId() + name = pattern.name if pattern is not None else "No Profile" + self.patternIds[id] = pattern + if currBase: + item = wx.MenuItem(menu, id, currBase) + else: + item = wx.MenuItem(menu, id, name) + + item.pattern = pattern + return item + + def addSeperator(self, m, text): + id = wx.NewId() + m.Append(id, u'─ %s ─' % text) + m.Enable(id, False) + + def getSubMenu(self, context, selection, menu, i): + self.context = context + menu.Bind(wx.EVT_MENU, self.handleResistSwitch) + m = wx.Menu() + m.Bind(wx.EVT_MENU, self.handleResistSwitch) + self.patternIds = {} + + # @todo: this whole thing is a mess, please fix + # Maybe look into processing resists into a dict and iterating through + # dict to make submenus instead of this shitty logic + items = [] + nameBase = None + sub = None + + m.AppendItem(self.addPattern(m, None)) # Add reset + m.AppendSeparator() + 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] + else: + currBase = None + + if nameBase is None or nameBase != currBase: + sub = None + base = pattern + nameBase = currBase + item = self.addPattern(m, pattern, currBase) + items.append(item) + else: + if sub is None: + sub = wx.Menu() + sub.Bind(wx.EVT_MENU, self.handleResistSwitch) + item.SetSubMenu(sub) + sub.AppendItem(self.addPattern(sub, base)) + + sub.AppendItem(self.addPattern(sub, pattern)) + for item in items: + m.AppendItem(item) + return m + +TargetResists.register() diff --git a/gui/builtinStatsViews/firepowerViewFull.py b/gui/builtinStatsViews/firepowerViewFull.py index 1b26b26620..7f18b6a0c3 100644 --- a/gui/builtinStatsViews/firepowerViewFull.py +++ b/gui/builtinStatsViews/firepowerViewFull.py @@ -40,13 +40,20 @@ def getTextExtentW(self, text): def populatePanel(self, contentPanel, headerPanel): contentSizer = contentPanel.GetSizer() parent = self.panel = contentPanel + self.headerPanel = headerPanel + headerContentSizer = wx.BoxSizer(wx.HORIZONTAL) + hsizer = headerPanel.GetSizer() + hsizer.Add(headerContentSizer,0,0,0) + self.stEff = wx.StaticText(headerPanel, wx.ID_ANY, "( Effective )") + headerContentSizer.Add(self.stEff) + headerPanel.GetParent().AddToggleItem(self.stEff) panel = "full" sizerFirepower = wx.FlexGridSizer(1, 4) sizerFirepower.AddGrowableCol(1) - + contentSizer.Add( sizerFirepower, 0, wx.EXPAND, 0) counter = 0 @@ -129,6 +136,10 @@ def switchToMiningYieldView(self, event): def refreshPanel(self, fit): #If we did anything intresting, we'd update our labels to reflect the new fit's stats here + if fit is not None and fit.targetResists is not None: + self.stEff.Show() + else: + self.stEff.Hide() stats = (("labelFullDpsWeapon", lambda: fit.weaponDPS, 3, 0, 0, "%s DPS",None), ("labelFullDpsDrone", lambda: fit.droneDPS, 3, 0, 0, "%s DPS", None), diff --git a/gui/mainFrame.py b/gui/mainFrame.py index 05ec3e0149..e6c08cecd8 100644 --- a/gui/mainFrame.py +++ b/gui/mainFrame.py @@ -46,6 +46,7 @@ from gui.characterEditor import CharacterEditor from gui.characterSelection import CharacterSelection from gui.patternEditor import DmgPatternEditorDlg +from gui.resistsEditor import ResistsEditorDlg from gui.preferenceDialog import PreferenceDialog from gui.graphFrame import GraphFrame from gui.copySelectDialog import CopySelectDialog @@ -311,6 +312,11 @@ def showCharacterEditor(self, event): dlg=CharacterEditor(self) dlg.Show() + def showTargetResistsEditor(self, event): + dlg=ResistsEditorDlg(self) + dlg.ShowModal() + dlg.Destroy() + def showDamagePatternEditor(self, event): dlg=DmgPatternEditorDlg(self) dlg.ShowModal() @@ -392,6 +398,8 @@ def registerMenu(self): self.Bind(wx.EVT_MENU, self.showCharacterEditor, id=menuBar.characterEditorId) # Damage pattern editor self.Bind(wx.EVT_MENU, self.showDamagePatternEditor, id=menuBar.damagePatternEditorId) + # Target Resists editor + self.Bind(wx.EVT_MENU, self.showTargetResistsEditor, id=menuBar.targetResistsEditorId) # Import dialog self.Bind(wx.EVT_MENU, self.showImportDialog, id=wx.ID_OPEN) # Export dialog diff --git a/gui/mainMenuBar.py b/gui/mainMenuBar.py index 73577578d8..06e1dfabf7 100644 --- a/gui/mainMenuBar.py +++ b/gui/mainMenuBar.py @@ -28,6 +28,7 @@ class MainMenuBar(wx.MenuBar): def __init__(self): self.characterEditorId = wx.NewId() self.damagePatternEditorId = wx.NewId() + self.targetResistsEditorId = wx.NewId() self.graphFrameId = wx.NewId() self.backupFitsId = wx.NewId() self.exportSkillsNeededId = wx.NewId() @@ -82,6 +83,10 @@ def __init__(self): damagePatternEditItem.SetBitmap(bitmapLoader.getBitmap("damagePattern_small", "icons")) windowMenu.AppendItem(damagePatternEditItem) + targetResistsEditItem = wx.MenuItem(windowMenu, self.targetResistsEditorId, "Target Resists Editor\tCTRL+R") + targetResistsEditItem.SetBitmap(bitmapLoader.getBitmap("explosive_big", "icons")) + windowMenu.AppendItem(targetResistsEditItem) + graphFrameItem = wx.MenuItem(windowMenu, self.graphFrameId, "Graphs\tCTRL+G") graphFrameItem.SetBitmap(bitmapLoader.getBitmap("graphs_small", "icons")) windowMenu.AppendItem(graphFrameItem) diff --git a/gui/resistsEditor.py b/gui/resistsEditor.py new file mode 100644 index 0000000000..ad53e952ba --- /dev/null +++ b/gui/resistsEditor.py @@ -0,0 +1,353 @@ +#=============================================================================== +# Copyright (C) 2014 Ryan Holmes +# +# This file is part of pyfa. +# +# pyfa is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# pyfa is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with pyfa. If not, see . +#=============================================================================== + +import wx +import bitmapLoader +import service +from gui.utils.clipboard import toClipboard, fromClipboard + +class ResistsEditorDlg (wx.Dialog): + + DAMAGE_TYPES = ("em", "thermal", "kinetic", "explosive") + + def __init__(self, parent): + wx.Dialog.__init__ (self, parent, id = wx.ID_ANY, title = u"Target Resists Editor", size = wx.Size( 350,240 )) + + self.block = False + self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize) + + mainSizer = wx.BoxSizer(wx.VERTICAL) + + self.headerSizer = headerSizer = wx.BoxSizer(wx.HORIZONTAL) + + sTR = service.TargetResists.getInstance() + + self.choices = sTR.getTargetResistsList() + + # Sort the remaining list and continue on + self.choices.sort(key=lambda p: p.name) + self.ccResists = wx.Choice(self, choices=map(lambda p: p.name, self.choices)) + self.ccResists.Bind(wx.EVT_CHOICE, self.patternChanged) + self.ccResists.SetSelection(0) + + self.namePicker = wx.TextCtrl(self, style=wx.TE_PROCESS_ENTER) + self.namePicker.Bind(wx.EVT_TEXT_ENTER, self.processRename) + self.namePicker.Hide() + + self.btnSave = wx.Button(self, wx.ID_SAVE) + self.btnSave.Hide() + self.btnSave.Bind(wx.EVT_BUTTON, self.processRename) + + size = None + headerSizer.Add(self.ccResists, 1, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT|wx.LEFT, 3) + + buttons = (("new", wx.ART_NEW), + ("rename", bitmapLoader.getBitmap("rename", "icons")), + ("copy", wx.ART_COPY), + ("delete", wx.ART_DELETE)) + for name, art in buttons: + bitmap = wx.ArtProvider.GetBitmap(art, wx.ART_BUTTON) if name != "rename" else art + btn = wx.BitmapButton(self, wx.ID_ANY, bitmap) + if size is None: + size = btn.GetSize() + + btn.SetMinSize(size) + btn.SetMaxSize(size) + + btn.Layout() + setattr(self, name, btn) + btn.Enable(True) + btn.SetToolTipString("%s resist profile" % name.capitalize()) + headerSizer.Add(btn, 0, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(headerSizer, 0, wx.EXPAND | wx.ALL, 2) + + self.sl = wx.StaticLine(self) + mainSizer.Add(self.sl, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5) + + contentSizer = wx.BoxSizer(wx.VERTICAL) + + resistEditSizer = wx.FlexGridSizer(2, 6, 0, 2) + resistEditSizer.AddGrowableCol(0) + resistEditSizer.AddGrowableCol(5) + resistEditSizer.SetFlexibleDirection(wx.BOTH) + resistEditSizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_SPECIFIED) + + width = -1 + defSize = wx.Size(50,-1) + + for i, type in enumerate(self.DAMAGE_TYPES): + if i%2: + style = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx. LEFT + border = 25 + else: + style = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT + border = 5 + + bmp = wx.StaticBitmap(self, wx.ID_ANY, bitmapLoader.getBitmap("%s_big"%type, "icons")) + resistEditSizer.Add(bmp, 0, style, border) + # set text edit + setattr(self, "%sEdit"%type, wx.TextCtrl(self, wx.ID_ANY, "", wx.DefaultPosition, defSize)) + editObj = getattr(self, "%sEdit"%type) + resistEditSizer.Add(editObj, 0, wx.BOTTOM | wx.TOP | wx.ALIGN_CENTER_VERTICAL, 5) + resistEditSizer.Add(wx.StaticText( self, wx.ID_ANY, u"%", wx.DefaultPosition, wx.DefaultSize, 0 ), 0, wx.BOTTOM | wx.TOP | wx.ALIGN_CENTER_VERTICAL, 5) + editObj.Bind(wx.EVT_TEXT, self.ValuesUpdated) + + contentSizer.Add(resistEditSizer, 1, wx.EXPAND | wx.ALL, 5) + self.slfooter = wx.StaticLine(self) + contentSizer.Add(self.slfooter, 0, wx.EXPAND | wx.TOP, 5) + + footerSizer = wx.BoxSizer(wx.HORIZONTAL) + perSizer = wx.BoxSizer(wx.VERTICAL) + + self.stNotice = wx.StaticText(self, wx.ID_ANY, u"") + self.stNotice.Wrap(-1) + perSizer.Add(self.stNotice, 0, wx.BOTTOM | wx.TOP | wx.LEFT, 5) + + footerSizer.Add(perSizer, 1, wx.ALIGN_CENTER_VERTICAL, 5) + + self.totSizer = wx.BoxSizer(wx.VERTICAL) + + contentSizer.Add(footerSizer, 0, wx.EXPAND, 5) + + mainSizer.Add(contentSizer, 1, wx.EXPAND, 0) + + if "wxGTK" in wx.PlatformInfo: + self.closeBtn = wx.Button( self, wx.ID_ANY, u"Close", wx.DefaultPosition, wx.DefaultSize, 0 ) + mainSizer.Add( self.closeBtn, 0, wx.ALL|wx.ALIGN_RIGHT, 5 ) + self.closeBtn.Bind(wx.EVT_BUTTON, self.closeEvent) + + self.SetSizer(mainSizer) + + importExport = (("Import", wx.ART_FILE_OPEN, "from"), + ("Export", wx.ART_FILE_SAVE_AS, "to")) + + for name, art, direction in importExport: + bitmap = wx.ArtProvider.GetBitmap(art, wx.ART_BUTTON) + btn = wx.BitmapButton(self, wx.ID_ANY, bitmap) + + btn.SetMinSize( btn.GetSize() ) + btn.SetMaxSize( btn.GetSize() ) + + btn.Layout() + setattr(self, name, btn) + btn.Enable(True) + btn.SetToolTipString("%s patterns %s clipboard" % (name, direction) ) + footerSizer.Add(btn, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_RIGHT) + + self.Layout() + bsize = self.GetBestSize() + self.SetSize((-1,bsize.height)) + + self.new.Bind(wx.EVT_BUTTON, self.newPattern) + self.rename.Bind(wx.EVT_BUTTON, self.renamePattern) + self.copy.Bind(wx.EVT_BUTTON, self.copyPattern) + self.delete.Bind(wx.EVT_BUTTON, self.deletePattern) + self.Import.Bind(wx.EVT_BUTTON, self.importPatterns) + self.Export.Bind(wx.EVT_BUTTON, self.exportPatterns) + + self.patternChanged() + + def closeEvent(self, event): + self.Destroy() + + def ValuesUpdated(self, event=None): + if self.block: + return + if event is not None: + print event.GetString() + + try: + p = self.getActivePattern() + + for type in self.DAMAGE_TYPES: + editObj = getattr(self, "%sEdit"%type) + + if editObj.GetValue() == "": + # if we are blank, overwrite with 0 + editObj.ChangeValue("0") + editObj.SetInsertionPointEnd() + + value = float(editObj.GetValue()) + + # assertion, because they're easy + assert 0 <= value <= 100 + + # if everything checks out, set resist attribute + setattr(p, "%sAmount"%type, value/100) + + self.stNotice.SetLabel("") + self.totSizer.Layout() + + if event is not None: + # If we get here, everything is normal. Reset color + event.EventObject.SetForegroundColour(wx.NullColor) + event.Skip() + + service.TargetResists.getInstance().saveChanges(p) + + except ValueError: + event.EventObject.SetForegroundColour(wx.RED) + self.stNotice.SetLabel("Incorrect Formatting (decimals only)") + except AssertionError: + event.EventObject.SetForegroundColour(wx.RED) + self.stNotice.SetLabel("Incorrect Range (must be 0-100)") + finally: + self.Refresh() # Refresh for color changes to take effect immediately + + def restrict(self): + for type in self.DAMAGE_TYPES: + editObj = getattr(self, "%sEdit"%type) + editObj.Enable(False) + self.rename.Enable(False) + self.delete.Enable(False) + + def unrestrict(self): + for type in self.DAMAGE_TYPES: + editObj = getattr(self, "%sEdit"%type) + editObj.Enable() + self.rename.Enable() + self.delete.Enable() + + def getActivePattern(self): + if len(self.choices) == 0: + return None + + return self.choices[self.ccResists.GetSelection()] + + def patternChanged(self, event=None): + p = self.getActivePattern() + if p is None: + return + + self.block = True + for field in self.DAMAGE_TYPES: + edit = getattr(self, "%sEdit" % field) + amount = getattr(p, "%sAmount" % field)*100 + edit.ChangeValue(str(amount)) + + self.block = False + self.ValuesUpdated() + + def newPattern(self,event): + sTR = service.TargetResists.getInstance() + p = sTR.newPattern() + self.choices.append(p) + id = self.ccResists.Append(p.name) + self.ccResists.SetSelection(id) + self.btnSave.SetLabel("Create") + + # reset values + for type in self.DAMAGE_TYPES: + editObj = getattr(self, "%sEdit"%type) + editObj.ChangeValue("0") + editObj.SetForegroundColour(wx.NullColor) + + self.Refresh() + self.renamePattern() + + def renamePattern(self,event=None): + if event is not None: + self.btnSave.SetLabel("Rename") + + self.ccResists.Hide() + self.namePicker.Show() + self.headerSizer.Replace(self.ccResists, self.namePicker) + self.namePicker.SetFocus() + self.namePicker.SetValue(self.getActivePattern().name) + + for btn in (self.new, self.rename, self.delete, self.copy): + btn.Hide() + self.headerSizer.Remove(btn) + + self.headerSizer.Add(self.btnSave, 0, wx.ALIGN_CENTER) + self.btnSave.Show() + self.headerSizer.Layout() + if event is not None: + event.Skip() + + def processRename(self, event): + newName = self.namePicker.GetLineText(0) + self.stNotice.SetLabel("") + + p = self.getActivePattern() + for pattern in self.choices: + if pattern.name == newName and p != pattern: + self.stNotice.SetLabel("Name already used, please pick another") + return + + if newName == "": + self.stNotice.SetLabel("Invalid name") + return + + sTR = service.TargetResists.getInstance() + sTR.renamePattern(p, newName) + + self.headerSizer.Replace(self.namePicker, self.ccResists) + self.ccResists.Show() + self.namePicker.Hide() + self.btnSave.Hide() + self.headerSizer.Remove(self.btnSave) + for btn in (self.new, self.rename, self.delete, self.copy): + self.headerSizer.Add(btn, 0, wx.ALIGN_CENTER_VERTICAL) + btn.Show() + + sel = self.ccResists.GetSelection() + self.ccResists.Delete(sel) + self.ccResists.Insert(newName, sel) + self.ccResists.SetSelection(sel) + self.ValuesUpdated() + self.unrestrict() + + def copyPattern(self,event): + sTR = service.TargetResists.getInstance() + p = sTR.copyPattern(self.getActivePattern()) + self.choices.append(p) + id = self.ccResists.Append(p.name) + self.ccResists.SetSelection(id) + self.btnSave.SetLabel("Copy") + self.renamePattern() + self.patternChanged() + + def deletePattern(self,event): + sTR = service.TargetResists.getInstance() + sel = self.ccResists.GetSelection() + sTR.deletePattern(self.getActivePattern()) + self.ccResists.Delete(sel) + self.ccResists.SetSelection(max(0, sel - 1)) + del self.choices[sel] + self.patternChanged() + + def __del__( self ): + pass + + def importPatterns(self, event): + text = fromClipboard() + if text: + sTR = service.TargetResists.getInstance() + # @todo: fix return value and use that to determine label + sTR.importPatterns(text) + self.stNotice.SetLabel("Patterns imported from clipboard") + else: + self.stNotice.SetLabel("Could not import from clipboard") + + def exportPatterns(self, event): + sTR = service.TargetResists.getInstance() + toClipboard( sTR.exportPatterns() ) + self.stNotice.SetLabel("Patterns exported to clipboard") diff --git a/service/__init__.py b/service/__init__.py index 8ded8a66a5..8e9e9f6f50 100644 --- a/service/__init__.py +++ b/service/__init__.py @@ -3,6 +3,7 @@ from service.attribute import Attribute from service.character import Character from service.damagePattern import DamagePattern +from service.targetResists import TargetResists from service.settings import SettingsProvider from service.fleet import Fleet from service.update import Update diff --git a/service/fit.py b/service/fit.py index f6f747cf26..9719fe8e17 100644 --- a/service/fit.py +++ b/service/fit.py @@ -83,6 +83,7 @@ def getInstance(cls): def __init__(self): self.pattern = DamagePattern.getInstance().getDamagePattern("Uniform") + self.targetResists = None self.character = Character.getInstance().all5() self.booster = False self.dirtyFitIDs = set() @@ -148,6 +149,7 @@ def newFit(self, shipID, name=None): fit.ship = eos.types.Ship(eos.db.getItem(shipID)) fit.name = name if name is not None else "New %s" % fit.ship.item.name fit.damagePattern = self.pattern + fit.targetResists = self.targetResists fit.character = self.character fit.booster = self.booster eos.db.save(fit) @@ -683,6 +685,23 @@ def setAmmo(self, fitID, ammoID, modules): self.recalc(fit) + def getTargetResists(self, fitID): + if fitID is None: + return + + fit = eos.db.getFit(fitID) + return fit.targetResists + + def setTargetResists(self, fitID, pattern): + if fitID is None: + return + print "Set target resists: %s"%pattern + fit = eos.db.getFit(fitID) + fit.targetResists = pattern + eos.db.commit() + + self.recalc(fit) + def getDamagePattern(self, fitID): if fitID is None: return @@ -760,6 +779,7 @@ def importFit(self, path): for fit in fits: fit.character = self.character fit.damagePattern = self.pattern + fit.targetResists = self.targetResists return fits def importFitFromBuffer(self, bufferStr, activeFit=None): @@ -767,6 +787,7 @@ def importFitFromBuffer(self, bufferStr, activeFit=None): for fit in fits: fit.character = self.character fit.damagePattern = self.pattern + fit.targetResists = self.targetResists return fits def saveImportedFits(self, fits): diff --git a/service/targetResists.py b/service/targetResists.py new file mode 100644 index 0000000000..bdca643ce7 --- /dev/null +++ b/service/targetResists.py @@ -0,0 +1,92 @@ +#=============================================================================== +# Copyright (C) 2014 Ryan Holmes +# +# This file is part of pyfa. +# +# pyfa is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# pyfa is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with pyfa. If not, see . +#=============================================================================== + +import eos.db +import eos.types +import copy + +class TargetResists(): + instance = None + @classmethod + def getInstance(cls): + if cls.instance is None: + cls.instance = TargetResists() + + return cls.instance + + def __init__(self): + uniform = eos.db.getTargetResists("None") + if uniform is None: + uniform = eos.types.TargetResists(0,0,0,0) + uniform.name = "None" + eos.db.save(uniform) + + def getTargetResistsList(self): + return eos.db.getTargetResistsList() + + def getTargetResists(self, name): + print "Getting Target Resists: %s"%name + return eos.db.getTargetResists(name) + + def newPattern(self): + p = eos.types.TargetResists(0, 0, 0, 0) + p.name = "" + return p + + def renamePattern(self, p, newName): + p.name = newName + eos.db.save(p) + + def deletePattern(self, p): + eos.db.remove(p) + + def copyPattern(self, p): + newP = copy.deepcopy(p) + eos.db.save(newP) + return newP + + def saveChanges(self, p): + eos.db.save(p) + + def importPatterns(self, text): + lookup = {} + current = self.getTargetResistsList() + for pattern in current: + lookup[pattern.name] = pattern + try: + imports = eos.types.TargetResists.importPatterns(text) + for pattern in imports: + if pattern.name in lookup: + match = lookup[pattern.name] + match.__dict__.update(pattern.__dict__) + else: + eos.db.save(pattern) + eos.db.commit() + except: + pass + + def exportPatterns(self): + patterns = self.getTargetResistsList() + for i in xrange(len(patterns) - 1, -1, -1): + if patterns[i].name in ("None"): + del patterns[i] + + patterns.sort(key=lambda p: p.name) + return eos.types.TargetResists.exportPatterns(*patterns) + From a95eabac7b43d79ea4ed2fd25b6bf7994ff20fbb Mon Sep 17 00:00:00 2001 From: blitzmann Date: Wed, 3 Sep 2014 01:37:59 -0400 Subject: [PATCH 02/11] TargetResists: drones work. Also cleaned up redundancy in module.damageStats() --- eos/saveddata/drone.py | 9 +++++++-- eos/saveddata/fit.py | 2 +- eos/saveddata/module.py | 37 +++++++++++++++---------------------- 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/eos/saveddata/drone.py b/eos/saveddata/drone.py index bd5812c4ba..3e959bec32 100644 --- a/eos/saveddata/drone.py +++ b/eos/saveddata/drone.py @@ -22,7 +22,7 @@ from sqlalchemy.orm import validates, reconstructor class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): - DAMAGE_ATTRIBUTES = ("emDamage", "kineticDamage", "explosiveDamage", "thermalDamage") + DAMAGE_TYPES = ("em", "kinetic", "explosive", "thermal") MINING_ATTRIBUTES = ("miningAmount",) def __init__(self, item): @@ -111,6 +111,9 @@ def hasAmmo(self): @property def dps(self): + return self.damageStats() + + def damageStats(self, targetResists = None): if self.__dps == None: if self.dealsDamage is True and self.amountActive > 0: if self.hasAmmo: @@ -121,7 +124,9 @@ def dps(self): getter = self.getModifiedItemAttr cycleTime = self.getModifiedItemAttr(attr) - volley = sum(map(lambda d: getter(d), self.DAMAGE_ATTRIBUTES)) * self.amountActive + + volley = sum(map(lambda d: (getter("%sDamage"%d) or 0) * (1-getattr(targetResists, "%sAmount"%d, 0)), self.DAMAGE_TYPES)) + volley *= self.amountActive volley *= self.getModifiedItemAttr("damageMultiplier") or 1 self.__dps = volley / (cycleTime / 1000.0) else: diff --git a/eos/saveddata/fit.py b/eos/saveddata/fit.py index 65df79ebf5..35dcbbb763 100644 --- a/eos/saveddata/fit.py +++ b/eos/saveddata/fit.py @@ -827,7 +827,7 @@ def calculateWeaponStats(self): weaponVolley += volley for drone in self.drones: - droneDPS += drone.dps + droneDPS += drone.damageStats(self.targetResists) self.__weaponDPS = weaponDPS self.__weaponVolley = weaponVolley diff --git a/eos/saveddata/module.py b/eos/saveddata/module.py index de65e62249..b7d7e13154 100644 --- a/eos/saveddata/module.py +++ b/eos/saveddata/module.py @@ -310,28 +310,21 @@ def charge(self, charge): def damageStats(self, targetResists): if self.__dps == None: - if self.isEmpty: - self.__dps = 0 - self.__volley = 0 - else: - if self.state >= State.ACTIVE: - if self.charge: - func = self.getModifiedChargeAttr - else: - func = self.getModifiedItemAttr + self.__dps = 0 + self.__volley = 0 - volley = sum(map(lambda attr: (func("%sDamage"%attr) or 0) * (1-getattr(targetResists, "%sAmount"%attr, 0)), self.DAMAGE_TYPES)) - volley *= self.getModifiedItemAttr("damageMultiplier") or 1 - if volley: - cycleTime = self.cycleTime - self.__volley = volley - self.__dps = volley / (cycleTime / 1000.0) - else: - self.__volley = 0 - self.__dps = 0 + if not self.isEmpty and self.state >= State.ACTIVE: + if self.charge: + func = self.getModifiedChargeAttr else: - self.__volley = 0 - self.__dps = 0 + func = self.getModifiedItemAttr + + volley = sum(map(lambda attr: (func("%sDamage"%attr) or 0) * (1-getattr(targetResists, "%sAmount"%attr, 0)), self.DAMAGE_TYPES)) + volley *= self.getModifiedItemAttr("damageMultiplier") or 1 + if volley: + cycleTime = self.cycleTime + self.__volley = volley + self.__dps = volley / (cycleTime / 1000.0) return self.__dps, self.__volley @@ -355,11 +348,11 @@ def miningStats(self): @property def dps(self): - return self.damageStats[0] + return self.damageStats(None)[0] @property def volley(self): - return self.damageStats[1] + return self.damageStats(None)[1] @property def reloadTime(self): From f0473f1eab2fde0c99a1a296384159bb35306a6c Mon Sep 17 00:00:00 2001 From: blitzmann Date: Wed, 3 Sep 2014 12:52:05 -0400 Subject: [PATCH 03/11] Added support to show errors for resist imports, as well as many improvements to GUI logic. --- eos/saveddata/targetResists.py | 21 ++++--- gui/resistsEditor.py | 107 ++++++++++++++++++++++++--------- service/targetResists.py | 42 ++++++------- 3 files changed, 110 insertions(+), 60 deletions(-) diff --git a/eos/saveddata/targetResists.py b/eos/saveddata/targetResists.py index 7512e1dfc9..00133be3f4 100644 --- a/eos/saveddata/targetResists.py +++ b/eos/saveddata/targetResists.py @@ -34,17 +34,22 @@ def __init__(self, emAmount = 0, thermalAmount = 0, kineticAmount = 0, explosive def importPatterns(cls, text): lines = re.split('[\n\r]+', text) patterns = [] - + numPatterns = 0 for line in lines: - if line.strip()[0] == "#": # comments + try: + if line.strip()[0] == "#": # comments + continue + line = line.split('#',1)[0] # allows for comments + type, data = line.rsplit('=',1) + type, data = type.strip(), data.split(',') + except: + # Data isn't in correct format, continue to next line continue - line = line.split('#',1)[0] # allows for comments - type, data = line.rsplit('=',1) - type, data = type.strip(), data.split(',') - #if type != "TargetResists": - #continue + if type != "TargetResists": + continue + numPatterns += 1 name, data = data[0], data[1:5] #print name, data fields = {} @@ -63,7 +68,7 @@ def importPatterns(cls, text): pattern.name = name.strip() patterns.append(pattern) - return patterns + return patterns, numPatterns EXPORT_FORMAT = "TargetResists = %s,%.1f,%.1f,%.1f,%.1f\n" @classmethod diff --git a/gui/resistsEditor.py b/gui/resistsEditor.py index ad53e952ba..fee5928c16 100644 --- a/gui/resistsEditor.py +++ b/gui/resistsEditor.py @@ -21,6 +21,7 @@ import bitmapLoader import service from gui.utils.clipboard import toClipboard, fromClipboard +from service.targetResists import ImportError class ResistsEditorDlg (wx.Dialog): @@ -168,10 +169,14 @@ def closeEvent(self, event): self.Destroy() def ValuesUpdated(self, event=None): + ''' + Event that is fired when resists values change. Iterates through all + resist edit fields. If blank, sets it to 0.0. If it is not a proper + decimal value, sets text color to red and refuses to save changes until + issue is resolved + ''' if self.block: return - if event is not None: - print event.GetString() try: p = self.getActivePattern() @@ -181,7 +186,7 @@ def ValuesUpdated(self, event=None): if editObj.GetValue() == "": # if we are blank, overwrite with 0 - editObj.ChangeValue("0") + editObj.ChangeValue("0.0") editObj.SetInsertionPointEnd() value = float(editObj.GetValue()) @@ -208,8 +213,8 @@ def ValuesUpdated(self, event=None): except AssertionError: event.EventObject.SetForegroundColour(wx.RED) self.stNotice.SetLabel("Incorrect Range (must be 0-100)") - finally: - self.Refresh() # Refresh for color changes to take effect immediately + finally: # Refresh for color changes to take effect immediately + self.Refresh() def restrict(self): for type in self.DAMAGE_TYPES: @@ -232,11 +237,16 @@ def getActivePattern(self): return self.choices[self.ccResists.GetSelection()] def patternChanged(self, event=None): + "Event fired when user selects pattern. Can also be called from script" p = self.getActivePattern() if p is None: + # This happens when there are no patterns in the DB. As such, force + # user to create one first or exit dlg. + self.newPattern(None) return self.block = True + # Set new values for field in self.DAMAGE_TYPES: edit = getattr(self, "%sEdit" % field) amount = getattr(p, "%sAmount" % field)*100 @@ -245,32 +255,35 @@ def patternChanged(self, event=None): self.block = False self.ValuesUpdated() - def newPattern(self,event): - sTR = service.TargetResists.getInstance() - p = sTR.newPattern() - self.choices.append(p) - id = self.ccResists.Append(p.name) - self.ccResists.SetSelection(id) + def newPattern(self, event): + ''' + Simply does new-pattern specifics: replaces label on button, restricts, + and resets values to default. Hands off to the rename function for + further handling. + ''' self.btnSave.SetLabel("Create") - + self.restrict() # reset values for type in self.DAMAGE_TYPES: editObj = getattr(self, "%sEdit"%type) - editObj.ChangeValue("0") + editObj.ChangeValue("0.0") editObj.SetForegroundColour(wx.NullColor) self.Refresh() self.renamePattern() - def renamePattern(self,event=None): - if event is not None: - self.btnSave.SetLabel("Rename") + def renamePattern(self, event=None): + "Changes layout to facilitate naming a pattern" self.ccResists.Hide() self.namePicker.Show() self.headerSizer.Replace(self.ccResists, self.namePicker) self.namePicker.SetFocus() - self.namePicker.SetValue(self.getActivePattern().name) + if event is not None: # Rename mode + self.btnSave.SetLabel("Rename") + self.namePicker.SetValue(self.getActivePattern().name) + else: # Create mode + self.namePicker.SetValue("") for btn in (self.new, self.rename, self.delete, self.copy): btn.Hide() @@ -283,22 +296,37 @@ def renamePattern(self,event=None): event.Skip() def processRename(self, event): + ''' + Processes rename event (which can be new or old patterns). If new + pattern, creates it; if old, selects it. if checks are valid, rename + saves pattern to DB. + + Also resets to default layout and unrestricts. + ''' newName = self.namePicker.GetLineText(0) self.stNotice.SetLabel("") - p = self.getActivePattern() - for pattern in self.choices: - if pattern.name == newName and p != pattern: - self.stNotice.SetLabel("Name already used, please pick another") - return - if newName == "": self.stNotice.SetLabel("Invalid name") return sTR = service.TargetResists.getInstance() + if event.EventObject.Label == "Create": + p = sTR.newPattern() + else: + # we are renaming, so get the current selection + p = self.getActivePattern() + + # test for patterns of the same name + for pattern in self.choices: + if pattern.name == newName and p != pattern: + self.stNotice.SetLabel("Name already used, please pick another") + return + + # rename regardless of new or rename sTR.renamePattern(p, newName) + self.updateChoices() self.headerSizer.Replace(self.namePicker, self.ccResists) self.ccResists.Show() self.namePicker.Hide() @@ -309,9 +337,6 @@ def processRename(self, event): btn.Show() sel = self.ccResists.GetSelection() - self.ccResists.Delete(sel) - self.ccResists.Insert(newName, sel) - self.ccResists.SetSelection(sel) self.ValuesUpdated() self.unrestrict() @@ -337,17 +362,41 @@ def deletePattern(self,event): def __del__( self ): pass + def updateChoices(self): + "Gathers list of patterns and updates choice selections" + sTR = service.TargetResists.getInstance() + self.choices = sTR.getTargetResistsList() + + # Sort the remaining list and continue on + self.choices.sort(key=lambda p: p.name) + self.ccResists.Clear() + + for choice in map(lambda p: p.name, self.choices): + self.ccResists.Append(choice) + self.ccResists.SetSelection(0) + self.patternChanged() + def importPatterns(self, event): + "Event fired when import from clipboard button is clicked" + text = fromClipboard() if text: sTR = service.TargetResists.getInstance() - # @todo: fix return value and use that to determine label - sTR.importPatterns(text) - self.stNotice.SetLabel("Patterns imported from clipboard") + try: + sTR.importPatterns(text) + self.stNotice.SetLabel("Patterns successfully imported from clipboard") + except service.targetResists.ImportError, e: + self.stNotice.SetLabel(str(e)) + except Exception, e: + self.stNotice.SetLabel("Could not import from clipboard: unknown errors") + finally: + self.updateChoices() else: self.stNotice.SetLabel("Could not import from clipboard") def exportPatterns(self, event): + "Event fired when export to clipboard button is clicked" + sTR = service.TargetResists.getInstance() toClipboard( sTR.exportPatterns() ) self.stNotice.SetLabel("Patterns exported to clipboard") diff --git a/service/targetResists.py b/service/targetResists.py index bdca643ce7..49deb154b8 100644 --- a/service/targetResists.py +++ b/service/targetResists.py @@ -21,6 +21,9 @@ import eos.types import copy +class ImportError(Exception): + pass + class TargetResists(): instance = None @classmethod @@ -30,13 +33,6 @@ def getInstance(cls): return cls.instance - def __init__(self): - uniform = eos.db.getTargetResists("None") - if uniform is None: - uniform = eos.types.TargetResists(0,0,0,0) - uniform.name = "None" - eos.db.save(uniform) - def getTargetResistsList(self): return eos.db.getTargetResistsList() @@ -45,7 +41,7 @@ def getTargetResists(self, name): return eos.db.getTargetResists(name) def newPattern(self): - p = eos.types.TargetResists(0, 0, 0, 0) + p = eos.types.TargetResists(0.0, 0.0, 0.0, 0.0) p.name = "" return p @@ -69,24 +65,24 @@ def importPatterns(self, text): current = self.getTargetResistsList() for pattern in current: lookup[pattern.name] = pattern - try: - imports = eos.types.TargetResists.importPatterns(text) - for pattern in imports: - if pattern.name in lookup: - match = lookup[pattern.name] - match.__dict__.update(pattern.__dict__) - else: - eos.db.save(pattern) - eos.db.commit() - except: - pass + + imports, num = eos.types.TargetResists.importPatterns(text) + for pattern in imports: + if pattern.name in lookup: + match = lookup[pattern.name] + match.__dict__.update(pattern.__dict__) + else: + eos.db.save(pattern) + eos.db.commit() + + lenImports = len(imports) + if lenImports == 0: + raise ImportError("No patterns found for import") + if lenImports != num: + raise ImportError("%d patterns imported from clipboard; %d had errors"%(num, num-lenImports)) def exportPatterns(self): patterns = self.getTargetResistsList() - for i in xrange(len(patterns) - 1, -1, -1): - if patterns[i].name in ("None"): - del patterns[i] - patterns.sort(key=lambda p: p.name) return eos.types.TargetResists.exportPatterns(*patterns) From 0e10ac39281f79221929efd4c15edbbafa24b7a6 Mon Sep 17 00:00:00 2001 From: blitzmann Date: Wed, 3 Sep 2014 13:52:42 -0400 Subject: [PATCH 04/11] Damage Pattern editor cleanup / GUI improvements --- gui/patternEditor.py | 101 +++++++++++++++++++------------------------ gui/resistsEditor.py | 2 +- 2 files changed, 46 insertions(+), 57 deletions(-) diff --git a/gui/patternEditor.py b/gui/patternEditor.py index 013fe11f60..28d098eeb1 100644 --- a/gui/patternEditor.py +++ b/gui/patternEditor.py @@ -28,6 +28,7 @@ ########################################################################### class DmgPatternEditorDlg (wx.Dialog): + DAMAGE_TYPES = ("em", "thermal", "kinetic", "explosive") def __init__(self, parent): wx.Dialog.__init__ (self, parent, id = wx.ID_ANY, title = u"Damage Pattern Editor", size = wx.Size( 400,240 )) @@ -102,25 +103,26 @@ def __init__(self, parent): width = -1 defSize = wx.Size(width,-1) - self.bmpEM = wx.StaticBitmap(self, wx.ID_ANY, self.embitmap) - dmgeditSizer.Add(self.bmpEM, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 5) - self.editEm = IntCtrl(self, wx.ID_ANY, 0, wx.DefaultPosition, defSize) - dmgeditSizer.Add(self.editEm, 0, wx.BOTTOM | wx.TOP | wx.ALIGN_CENTER_VERTICAL, 5) + for i, type in enumerate(self.DAMAGE_TYPES): + bmp = wx.StaticBitmap(self, wx.ID_ANY, bitmapLoader.getBitmap("%s_big"%type, "icons")) + if i%2: + style = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx. LEFT + border = 25 + else: + style = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT + border = 5 - self.bmpTHERM = wx.StaticBitmap(self, wx.ID_ANY, self.thermbitmap) - dmgeditSizer.Add(self.bmpTHERM, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.LEFT, 25) - self.editThermal = IntCtrl(self, wx.ID_ANY, 0, wx.DefaultPosition, defSize, 0) - dmgeditSizer.Add(self.editThermal, 0, wx.BOTTOM | wx.TOP | wx.ALIGN_CENTER_VERTICAL, 5) + # set text edit + setattr(self, "%sEdit"%type, IntCtrl(self, wx.ID_ANY, 0, wx.DefaultPosition, defSize)) + editObj = getattr(self, "%sEdit"%type) - self.bmpKIN = wx.StaticBitmap(self, wx.ID_ANY, self.kinbitmap) - dmgeditSizer.Add(self.bmpKIN, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 5) - self.editKinetic = IntCtrl(self, wx.ID_ANY, 0, wx.DefaultPosition, defSize) - dmgeditSizer.Add(self.editKinetic, 0, wx.BOTTOM | wx.TOP | wx.ALIGN_CENTER_VERTICAL, 5) + dmgeditSizer.Add(bmp, 0, style, border) + dmgeditSizer.Add(editObj, 0, wx.BOTTOM | wx.TOP | wx.ALIGN_CENTER_VERTICAL, 5) - self.bmpEXP = wx.StaticBitmap(self, wx.ID_ANY, self.expbitmap) - dmgeditSizer.Add(self.bmpEXP, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.LEFT, 25) - self.editExplosive = IntCtrl(self, wx.ID_ANY, 0, wx.DefaultPosition, defSize, 0) - dmgeditSizer.Add(self.editExplosive, 0, wx.BOTTOM | wx.TOP | wx.ALIGN_CENTER_VERTICAL, 5) + editObj.Bind(wx.EVT_TEXT, self.ValuesUpdated) + editObj.SetLimited(True) + editObj.SetMin(0) + editObj.SetMax(99999) contentSizer.Add(dmgeditSizer, 1, wx.EXPAND | wx.ALL, 5) self.slfooter = wx.StaticLine(self) @@ -167,22 +169,6 @@ def __init__(self, parent): bsize = self.GetBestSize() self.SetSize((-1,bsize.height)) - self.editEm.SetLimited(True) - self.editThermal.SetLimited(True) - self.editKinetic.SetLimited(True) - self.editExplosive.SetLimited(True) - - self.editEm.SetMin(0) - self.editThermal.SetMin(0) - self.editKinetic.SetMin(0) - self.editExplosive.SetMin(0) - - self.editEm.SetMax(99999) - self.editThermal.SetMax(99999) - self.editKinetic.SetMax(99999) - self.editExplosive.SetMax(99999) - - self.new.Bind(wx.EVT_BUTTON, self.newPattern) self.rename.Bind(wx.EVT_BUTTON, self.renamePattern) self.copy.Bind(wx.EVT_BUTTON, self.copyPattern) @@ -190,11 +176,6 @@ def __init__(self, parent): self.Import.Bind(wx.EVT_BUTTON, self.importPatterns) self.Export.Bind(wx.EVT_BUTTON, self.exportPatterns) - self.editEm.Bind(wx.EVT_TEXT, self.ValuesUpdated) - self.editThermal.Bind(wx.EVT_TEXT, self.ValuesUpdated) - self.editKinetic.Bind(wx.EVT_TEXT, self.ValuesUpdated) - self.editExplosive.Bind(wx.EVT_TEXT, self.ValuesUpdated) - self.patternChanged() def closeEvent(self, event): @@ -205,16 +186,18 @@ def ValuesUpdated(self, event=None): return p = self.getActivePattern() - p.emAmount = self._EM = self.editEm.GetValue() - p.thermalAmount = self._THERM = self.editThermal.GetValue() - p.kineticAmount = self._KIN = self.editKinetic.GetValue() - p.explosiveAmount = self._EXP = self.editExplosive.GetValue() - total = self._EM + self._THERM + self._KIN + self._EXP - format = "EM: %d%%, THERM: %d%%, KIN: %d%%, EXP: %d%%" + total = 0 + for type in self.DAMAGE_TYPES: + editObj = getattr(self, "%sEdit"%type) + setattr(p, "%sAmount"%type, editObj.GetValue()) + total += editObj.GetValue() + + format = "EM: %d%%, THERM: %d%%, KIN: %d%%, EXP: %d%%" + if total > 0: - ltext = format %(self._EM*100/total, self._THERM*100/total, self._KIN*100/total, self._EXP*100/total) + ltext = format % tuple(map(lambda attr: getattr(self, "%sEdit"%attr).GetValue()*100/total, self.DAMAGE_TYPES)) else: - ltext = format %(0, 0, 0, 0) + ltext = format % (0, 0, 0, 0) self.stPercentages.SetLabel(ltext) self.totSizer.Layout() @@ -225,18 +208,16 @@ def ValuesUpdated(self, event=None): service.DamagePattern.getInstance().saveChanges(p) def restrict(self): - self.editEm.Enable(False) - self.editExplosive.Enable(False) - self.editKinetic.Enable(False) - self.editThermal.Enable(False) + for type in self.DAMAGE_TYPES: + editObj = getattr(self, "%sEdit"%type) + editObj.Enable(False) self.rename.Enable(False) self.delete.Enable(False) def unrestrict(self): - self.editEm.Enable() - self.editExplosive.Enable() - self.editKinetic.Enable() - self.editThermal.Enable() + for type in self.DAMAGE_TYPES: + editObj = getattr(self, "%sEdit"%type) + editObj.Enable() self.rename.Enable() self.delete.Enable() @@ -257,8 +238,9 @@ def patternChanged(self, event=None): self.unrestrict() self.block = True - for field in ("em", "thermal", "kinetic", "explosive"): - edit = getattr(self, "edit%s" % field.capitalize()) + + for field in self.DAMAGE_TYPES: + edit = getattr(self, "%sEdit" % field) amount = getattr(p, "%sAmount" % field) edit.SetValue(amount) @@ -271,6 +253,13 @@ def newPattern(self,event): self.choices.append(p) id = self.ccDmgPattern.Append(p.name) self.ccDmgPattern.SetSelection(id) + + self.restrict() + # reset values + for type in self.DAMAGE_TYPES: + editObj = getattr(self, "%sEdit"%type) + editObj.SetValue(0) + self.btnSave.SetLabel("Create") self.renamePattern() @@ -301,7 +290,7 @@ def processRename(self, event): p = self.getActivePattern() for pattern in self.choices: if pattern.name == newName and p != pattern: - self.stPercentages.SetLabel("Name already used, please pick another") + self.stPercentages.SetLabel("Name already used, please choose another") return if newName == "": diff --git a/gui/resistsEditor.py b/gui/resistsEditor.py index fee5928c16..47b6364dde 100644 --- a/gui/resistsEditor.py +++ b/gui/resistsEditor.py @@ -320,7 +320,7 @@ def processRename(self, event): # test for patterns of the same name for pattern in self.choices: if pattern.name == newName and p != pattern: - self.stNotice.SetLabel("Name already used, please pick another") + self.stNotice.SetLabel("Name already used, please choose another") return # rename regardless of new or rename From 035443b4ff9f54db27ad1adfaf4bca6bc099f9be Mon Sep 17 00:00:00 2001 From: blitzmann Date: Wed, 3 Sep 2014 14:56:44 -0400 Subject: [PATCH 05/11] We now use EFT-style import/exports for damage profiles. Also, percentages now shown next to damage amount instead of foot (where notifications are going) --- eos/saveddata/damagePattern.py | 39 +++++++++++++------ eos/saveddata/targetResists.py | 1 - gui/patternEditor.py | 71 ++++++++++++++++++++++------------ gui/resistsEditor.py | 5 +-- service/damagePattern.py | 29 ++++++++------ 5 files changed, 95 insertions(+), 50 deletions(-) diff --git a/eos/saveddata/damagePattern.py b/eos/saveddata/damagePattern.py index de70acef38..22f40355f2 100644 --- a/eos/saveddata/damagePattern.py +++ b/eos/saveddata/damagePattern.py @@ -69,23 +69,40 @@ def effectivify(self, fit, amount, type): def importPatterns(cls, text): lines = re.split('[\n\r]+', text) patterns = [] + numPatterns = 0 for line in lines: - line = line.split('#',1)[0] # allows for comments - name, data = line.rsplit('=',1) - name, data = name.strip(), ''.join(data.split()) # whitespace - + try: + if line.strip()[0] == "#": # comments + continue + line = line.split('#',1)[0] # allows for comments + type, data = line.rsplit('=',1) + type, data = type.strip(), data.split(',') + except: + # Data isn't in correct format, continue to next line + continue + + if type != "DamageProfile": + continue + + numPatterns += 1 + name, data = data[0], data[1:5] fields = {} - for entry in data.split(','): - key, val = entry.split(':') - fields["%sAmount" % cls.importMap[key.lower()]] = float(val) - if len(fields) > 0: # Avoid possible blank lines + for index, val in enumerate(data): + try: + fields["%sAmount" % cls.DAMAGE_TYPES[index]] = int(val) + except: + continue + + if len(fields) == 4: # Avoid possible blank lines + print name, fields pattern = DamagePattern(**fields) - pattern.name = name + pattern.name = name.strip() patterns.append(pattern) - return patterns - EXPORT_FORMAT = "%s = EM:%d, Therm:%d, Kin:%d, Exp:%d\n" + return patterns, numPatterns + + EXPORT_FORMAT = "DamageProfile = %s,%d,%d,%d,%d\n" @classmethod def exportPatterns(cls, *patterns): out = "" diff --git a/eos/saveddata/targetResists.py b/eos/saveddata/targetResists.py index 00133be3f4..d23890ce0f 100644 --- a/eos/saveddata/targetResists.py +++ b/eos/saveddata/targetResists.py @@ -51,7 +51,6 @@ def importPatterns(cls, text): numPatterns += 1 name, data = data[0], data[1:5] - #print name, data fields = {} for index, val in enumerate(data): diff --git a/gui/patternEditor.py b/gui/patternEditor.py index 28d098eeb1..f3b8da855c 100644 --- a/gui/patternEditor.py +++ b/gui/patternEditor.py @@ -22,6 +22,7 @@ import service from wx.lib.intctrl import IntCtrl from gui.utils.clipboard import toClipboard, fromClipboard +from service.damagePattern import ImportError ########################################################################### ## Class DmgPatternEditorDlg @@ -94,9 +95,9 @@ def __init__(self, parent): self.kinbitmap = bitmapLoader.getBitmap("kinetic_big", "icons") self.expbitmap = bitmapLoader.getBitmap("explosive_big", "icons") - dmgeditSizer = wx.FlexGridSizer(2, 4, 0, 2) + dmgeditSizer = wx.FlexGridSizer(2, 6, 0, 2) dmgeditSizer.AddGrowableCol(0) - dmgeditSizer.AddGrowableCol(3) + dmgeditSizer.AddGrowableCol(5) dmgeditSizer.SetFlexibleDirection(wx.BOTH) dmgeditSizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_SPECIFIED) @@ -106,18 +107,20 @@ def __init__(self, parent): for i, type in enumerate(self.DAMAGE_TYPES): bmp = wx.StaticBitmap(self, wx.ID_ANY, bitmapLoader.getBitmap("%s_big"%type, "icons")) if i%2: - style = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx. LEFT - border = 25 + style = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.LEFT + border = 10 else: style = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT border = 5 # set text edit setattr(self, "%sEdit"%type, IntCtrl(self, wx.ID_ANY, 0, wx.DefaultPosition, defSize)) + setattr(self, "%sPerc"%type, wx.StaticText(self, wx.ID_ANY, u"0%")) editObj = getattr(self, "%sEdit"%type) dmgeditSizer.Add(bmp, 0, style, border) dmgeditSizer.Add(editObj, 0, wx.BOTTOM | wx.TOP | wx.ALIGN_CENTER_VERTICAL, 5) + dmgeditSizer.Add(getattr(self, "%sPerc"%type), 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5) editObj.Bind(wx.EVT_TEXT, self.ValuesUpdated) editObj.SetLimited(True) @@ -131,9 +134,9 @@ def __init__(self, parent): footerSizer = wx.BoxSizer(wx.HORIZONTAL) perSizer = wx.BoxSizer(wx.VERTICAL) - self.stPercentages = wx.StaticText(self, wx.ID_ANY, u"") - self.stPercentages.Wrap(-1) - perSizer.Add(self.stPercentages, 0, wx.BOTTOM | wx.TOP | wx.LEFT, 5) + self.stNotice = wx.StaticText(self, wx.ID_ANY, u"") + self.stNotice.Wrap(-1) + perSizer.Add(self.stNotice, 0, wx.BOTTOM | wx.TOP | wx.LEFT, 5) footerSizer.Add(perSizer, 1, wx.ALIGN_CENTER_VERTICAL, 5) @@ -186,20 +189,13 @@ def ValuesUpdated(self, event=None): return p = self.getActivePattern() - total = 0 + total = sum(map(lambda attr: getattr(self, "%sEdit"%attr).GetValue(), self.DAMAGE_TYPES)) for type in self.DAMAGE_TYPES: editObj = getattr(self, "%sEdit"%type) + percObj = getattr(self, "%sPerc"%type) setattr(p, "%sAmount"%type, editObj.GetValue()) - total += editObj.GetValue() + percObj.SetLabel("%.1f%%"%(float(editObj.GetValue())*100/total if total > 0 else 0)) - format = "EM: %d%%, THERM: %d%%, KIN: %d%%, EXP: %d%%" - - if total > 0: - ltext = format % tuple(map(lambda attr: getattr(self, "%sEdit"%attr).GetValue()*100/total, self.DAMAGE_TYPES)) - else: - ltext = format % (0, 0, 0, 0) - - self.stPercentages.SetLabel(ltext) self.totSizer.Layout() if event is not None: @@ -229,6 +225,7 @@ def getActivePattern(self): def patternChanged(self, event=None): p = self.getActivePattern() + if p is None: return @@ -285,16 +282,16 @@ def renamePattern(self,event=None): def processRename(self, event): newName = self.namePicker.GetLineText(0) - self.stPercentages.SetLabel("") + self.stNotice.SetLabel("") p = self.getActivePattern() for pattern in self.choices: if pattern.name == newName and p != pattern: - self.stPercentages.SetLabel("Name already used, please choose another") + self.stNotice.SetLabel("Name already used, please choose another") return if newName == "": - self.stPercentages.SetLabel("Invalid name.") + self.stNotice.SetLabel("Invalid name.") return sDP = service.DamagePattern.getInstance() @@ -338,16 +335,42 @@ def deletePattern(self,event): def __del__( self ): pass + def updateChoices(self): + "Gathers list of patterns and updates choice selections" + sDP = service.DamagePattern.getInstance() + self.choices = sDP.getDamagePatternList() + + for dp in self.choices: + if dp.name == "Selected Ammo": # don't include this special butterfly + self.choices.remove(dp) + + # Sort the remaining list and continue on + self.choices.sort(key=lambda p: p.name) + self.ccDmgPattern.Clear() + + for choice in map(lambda p: p.name, self.choices): + self.ccDmgPattern.Append(choice) + + self.ccDmgPattern.SetSelection(0) + self.patternChanged() + def importPatterns(self, event): text = fromClipboard() if text: sDP = service.DamagePattern.getInstance() - sDP.importPatterns(text) - self.stPercentages.SetLabel("Patterns imported from clipboard") + try: + sDP.importPatterns(text) + self.stNotice.SetLabel("Patterns successfully imported from clipboard") + except service.damagePattern.ImportError, e: + self.stNotice.SetLabel(str(e)) + except Exception, e: + self.stNotice.SetLabel("Could not import from clipboard: unknown errors") + finally: + self.updateChoices() else: - self.stPercentages.SetLabel("Could not import from clipboard") + self.stNotice.SetLabel("Could not import from clipboard") def exportPatterns(self, event): sDP = service.DamagePattern.getInstance() toClipboard( sDP.exportPatterns() ) - self.stPercentages.SetLabel("Patterns exported to clipboard") + self.stNotice.SetLabel("Patterns exported to clipboard") diff --git a/gui/resistsEditor.py b/gui/resistsEditor.py index 47b6364dde..01d8747254 100644 --- a/gui/resistsEditor.py +++ b/gui/resistsEditor.py @@ -56,7 +56,7 @@ def __init__(self, parent): self.btnSave.Bind(wx.EVT_BUTTON, self.processRename) size = None - headerSizer.Add(self.ccResists, 1, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT|wx.LEFT, 3) + headerSizer.Add(self.ccResists, 1, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.LEFT, 3) buttons = (("new", wx.ART_NEW), ("rename", bitmapLoader.getBitmap("rename", "icons")), @@ -95,7 +95,7 @@ def __init__(self, parent): for i, type in enumerate(self.DAMAGE_TYPES): if i%2: - style = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx. LEFT + style = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.LEFT border = 25 else: style = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT @@ -197,7 +197,6 @@ def ValuesUpdated(self, event=None): # if everything checks out, set resist attribute setattr(p, "%sAmount"%type, value/100) - self.stNotice.SetLabel("") self.totSizer.Layout() if event is not None: diff --git a/service/damagePattern.py b/service/damagePattern.py index f5c1ebd13c..374940e0ca 100644 --- a/service/damagePattern.py +++ b/service/damagePattern.py @@ -21,6 +21,9 @@ import eos.types import copy +class ImportError(Exception): + pass + class DamagePattern(): instance = None @classmethod @@ -68,17 +71,21 @@ def importPatterns(self, text): current = self.getDamagePatternList() for pattern in current: lookup[pattern.name] = pattern - try: - imports = eos.types.DamagePattern.importPatterns(text) - for pattern in imports: - if pattern.name in lookup: - match = lookup[pattern.name] - match.__dict__.update(pattern.__dict__) - else: - eos.db.save(pattern) - eos.db.commit() - except: - pass + + imports, num = eos.types.DamagePattern.importPatterns(text) + for pattern in imports: + if pattern.name in lookup: + match = lookup[pattern.name] + match.__dict__.update(pattern.__dict__) + else: + eos.db.save(pattern) + eos.db.commit() + + lenImports = len(imports) + if lenImports == 0: + raise ImportError("No patterns found for import") + if lenImports != num: + raise ImportError("%d patterns imported from clipboard; %d had errors"%(num, num-lenImports)) def exportPatterns(self): patterns = self.getDamagePatternList() From bb16e649afe9a359b187b90dda6ac16a81b5a696 Mon Sep 17 00:00:00 2001 From: blitzmann Date: Wed, 3 Sep 2014 18:45:04 -0400 Subject: [PATCH 06/11] Added message to damage profile export --- eos/saveddata/damagePattern.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/eos/saveddata/damagePattern.py b/eos/saveddata/damagePattern.py index 22f40355f2..8c938736a6 100644 --- a/eos/saveddata/damagePattern.py +++ b/eos/saveddata/damagePattern.py @@ -105,7 +105,9 @@ def importPatterns(cls, text): EXPORT_FORMAT = "DamageProfile = %s,%d,%d,%d,%d\n" @classmethod def exportPatterns(cls, *patterns): - out = "" + out = "# Exported from pyfa\n#\n" + out += "# Values are in following format:\n" + out += "# DamageProfile = [name],[EM amount],[Thermal amount],[Kinetic amount],[Explosive amount]\n\n" for dp in patterns: out += cls.EXPORT_FORMAT % (dp.name, dp.emAmount, dp.thermalAmount, dp.kineticAmount, dp.explosiveAmount) From c04bb8f82c3dae70e5b755664ff1e874fb5305a7 Mon Sep 17 00:00:00 2001 From: blitzmann Date: Thu, 4 Sep 2014 00:23:41 -0400 Subject: [PATCH 07/11] Greatly simplified target resists menu logic. Also added active bitmap --- gui/builtinContextMenus/targetResists.py | 78 ++++++++++++++---------- 1 file changed, 47 insertions(+), 31 deletions(-) diff --git a/gui/builtinContextMenus/targetResists.py b/gui/builtinContextMenus/targetResists.py index 24904b4297..d88e0685aa 100644 --- a/gui/builtinContextMenus/targetResists.py +++ b/gui/builtinContextMenus/targetResists.py @@ -18,6 +18,7 @@ def display(self, srcContext, selection): sTR = service.TargetResists.getInstance() self.patterns = sTR.getTargetResistsList() self.patterns.sort( key=lambda p: (p.name in ["None"], p.name) ) + return len(self.patterns) > 0 def getText(self, itmContext, selection): @@ -39,14 +40,22 @@ def handleResistSwitch(self, event): def addPattern(self, menu, pattern, currBase = None): id = wx.NewId() - name = pattern.name if pattern is not None else "No Profile" - self.patternIds[id] = pattern - if currBase: - item = wx.MenuItem(menu, id, currBase) - else: - item = wx.MenuItem(menu, id, name) + name = getattr(pattern, "_name", pattern.name) if pattern is not None else "No Profile" + self.patternIds[id] = pattern + item = wx.MenuItem(menu, id, name) + # set pattern attr to menu item item.pattern = pattern + + # determine active pattern + sFit = service.Fit.getInstance() + fitID = self.mainFrame.getActiveFit() + f = sFit.getFit(fitID) + tr = f.targetResists + + if tr == pattern: + bitmap = bitmapLoader.getBitmap("state_active_small", "icons") + item.SetBitmap(bitmap) return item def addSeperator(self, m, text): @@ -61,38 +70,45 @@ def getSubMenu(self, context, selection, menu, i): m.Bind(wx.EVT_MENU, self.handleResistSwitch) self.patternIds = {} - # @todo: this whole thing is a mess, please fix - # Maybe look into processing resists into a dict and iterating through - # dict to make submenus instead of this shitty logic - items = [] - nameBase = None - sub = None + self.subMenus = {} + self.singles = [] - m.AppendItem(self.addPattern(m, None)) # Add reset - m.AppendSeparator() - for pattern in self.patterns: + 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] + # set helper attr + setattr(pattern, "_name", pattern.name[end+1:].strip()) + if currBase not in self.subMenus: + self.subMenus[currBase] = [] + self.subMenus[currBase].append(pattern) else: - currBase = None - - if nameBase is None or nameBase != currBase: - sub = None - base = pattern - nameBase = currBase - item = self.addPattern(m, pattern, currBase) - items.append(item) - else: - if sub is None: - sub = wx.Menu() - sub.Bind(wx.EVT_MENU, self.handleResistSwitch) - item.SetSubMenu(sub) - sub.AppendItem(self.addPattern(sub, base)) + self.singles.append(pattern) + + m.AppendItem(self.addPattern(m, None)) # Add reset + m.AppendSeparator() + + # Single items, no parent + for pattern in self.singles: + m.AppendItem(self.addPattern(m, pattern)) + # Items that have a parent + for menuName, patterns in self.subMenus.items(): + # Create parent item for root menu that is simply name of parent + item = wx.MenuItem(menu, wx.NewId(), menuName) + + # Create menu for child items + sub = wx.Menu() + sub.Bind(wx.EVT_MENU, self.handleResistSwitch) + + # Apply child menu to parent item + item.SetSubMenu(sub) + + # Append child items to child menu + for pattern in patterns: sub.AppendItem(self.addPattern(sub, pattern)) - for item in items: - m.AppendItem(item) + m.AppendItem(item) #finally, append parent item to root menu + return m TargetResists.register() From da047106f3cc4f03adf9dcea4ad1b5b5d89faebe Mon Sep 17 00:00:00 2001 From: blitzmann Date: Mon, 8 Sep 2014 01:11:38 -0400 Subject: [PATCH 08/11] Implements support for child menus for damage patterns. --- .../changeAffectingSkills.py | 2 +- gui/builtinContextMenus/damagePattern.py | 79 +++++++++++++++---- gui/builtinContextMenus/moduleAmmoPicker.py | 2 +- gui/builtinContextMenus/targetResists.py | 2 +- gui/builtinContextMenus/whProjector.py | 2 +- gui/contextMenu.py | 2 +- 6 files changed, 69 insertions(+), 20 deletions(-) diff --git a/gui/builtinContextMenus/changeAffectingSkills.py b/gui/builtinContextMenus/changeAffectingSkills.py index 4d1f5fdd40..95d2bc228b 100644 --- a/gui/builtinContextMenus/changeAffectingSkills.py +++ b/gui/builtinContextMenus/changeAffectingSkills.py @@ -67,7 +67,7 @@ def addSkill(self, rootMenu, skill, i): rootMenu.Bind(wx.EVT_MENU, self.handleSkillChange, menuItem) return menuItem - def getSubMenu(self, context, selection, menu, i): + def getSubMenu(self, context, selection, menu, i, id): self.context = context self.skillIds = {} diff --git a/gui/builtinContextMenus/damagePattern.py b/gui/builtinContextMenus/damagePattern.py index 1cde95a542..2242dba309 100644 --- a/gui/builtinContextMenus/damagePattern.py +++ b/gui/builtinContextMenus/damagePattern.py @@ -15,33 +15,82 @@ def display(self, srcContext, selection): def getText(self, itmContext, selection): sDP = service.DamagePattern.getInstance() self.patterns = sDP.getDamagePatternList() - self.patterns.sort( key=lambda p: (p.name in ["Selected Ammo", - "Uniform"], p.name) ) - m = map(lambda p: p.name, self.patterns) - return m + self.patterns.sort( key=lambda p: (p.name not in ["Uniform", + "Selected Ammo"], p.name) ) + + self.patternIds = {} + self.subMenus = {} + self.singles = [] + + # iterate and separate damage patterns based on "[Parent] Child" + 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] + # set helper attr + setattr(pattern, "_name", pattern.name[end+1:].strip()) + if currBase not in self.subMenus: + self.subMenus[currBase] = [] + self.subMenus[currBase].append(pattern) + else: + self.singles.append(pattern) + + # return list of names, with singles first followed by submenu names + self.m = map(lambda p: p.name, self.singles) + self.subMenus.keys() + return self.m + + def handlePatternSwitch(self, event): + pattern = self.patternIds.get(event.Id, False) + if pattern is False: + event.Skip() + return - def activate(self, fullContext, selection, i): - sDP = service.DamagePattern.getInstance() sFit = service.Fit.getInstance() fitID = self.mainFrame.getActiveFit() - sFit.setDamagePattern(fitID, self.patterns[i]) - setattr(self.mainFrame,"_activeDmgPattern",self.patterns[i]) + sFit.setDamagePattern(fitID, pattern) + setattr(self.mainFrame,"_activeDmgPattern", pattern) wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID)) - def getBitmap(self, context, selection): + def addPattern(self, menu, pattern): + id = wx.NewId() + name = getattr(pattern, "_name", pattern.name) if pattern is not None else "No Profile" + + self.patternIds[id] = pattern + item = wx.MenuItem(menu, id, name) + menu.Bind(wx.EVT_MENU, self.handlePatternSwitch, item) + + # set pattern attr to menu item + item.pattern = pattern + + # determine active pattern sFit = service.Fit.getInstance() fitID = self.mainFrame.getActiveFit() f = sFit.getFit(fitID) dp = f.damagePattern - if dp is None: + + if dp == pattern: + bitmap = bitmapLoader.getBitmap("state_active_small", "icons") + item.SetBitmap(bitmap) + return item + + def getSubMenu(self, context, selection, menu, i, id): + menu.Bind(wx.EVT_MENU, self.handlePatternSwitch) # this bit is required for some reason + + 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 + self.patternIds[id] = self.singles[i] + menu.Bind(wx.EVT_MENU, self.handlePatternSwitch, id=id) return None - index = self.patterns.index(dp) - bitmap = bitmapLoader.getBitmap("state_active_small", "icons") - l = [None] * len(self.patterns) - l[index] = bitmap + sub = wx.Menu() + sub.Bind(wx.EVT_MENU, self.handlePatternSwitch) - return l + # Items that have a parent + for pattern in self.subMenus[self.m[i]]: + sub.AppendItem(self.addPattern(sub, pattern)) + return sub DamagePattern.register() diff --git a/gui/builtinContextMenus/moduleAmmoPicker.py b/gui/builtinContextMenus/moduleAmmoPicker.py index c19c9d7ab9..a1a9f45cf3 100644 --- a/gui/builtinContextMenus/moduleAmmoPicker.py +++ b/gui/builtinContextMenus/moduleAmmoPicker.py @@ -116,7 +116,7 @@ def addSeperator(self, m, text): m.Append(id, u'─ %s ─' % text) m.Enable(id, False) - def getSubMenu(self, context, selection, menu, i): + def getSubMenu(self, context, selection, menu, i, id): self.context = context menu.Bind(wx.EVT_MENU, self.handleAmmoSwitch) m = wx.Menu() diff --git a/gui/builtinContextMenus/targetResists.py b/gui/builtinContextMenus/targetResists.py index d88e0685aa..c5b9c18929 100644 --- a/gui/builtinContextMenus/targetResists.py +++ b/gui/builtinContextMenus/targetResists.py @@ -63,7 +63,7 @@ def addSeperator(self, m, text): m.Append(id, u'─ %s ─' % text) m.Enable(id, False) - def getSubMenu(self, context, selection, menu, i): + def getSubMenu(self, context, selection, menu, i, id): self.context = context menu.Bind(wx.EVT_MENU, self.handleResistSwitch) m = wx.Menu() diff --git a/gui/builtinContextMenus/whProjector.py b/gui/builtinContextMenus/whProjector.py index 146139aa8e..522d40bd22 100644 --- a/gui/builtinContextMenus/whProjector.py +++ b/gui/builtinContextMenus/whProjector.py @@ -17,7 +17,7 @@ def getText(self, itmContext, selection): def activate(self, fullContext, selection, i): pass - def getSubMenu(self, context, selection, menu, i): + def getSubMenu(self, context, selection, menu, i, id): self.idmap = {} menu.Bind(wx.EVT_MENU, self.handleSelection) m = wx.Menu() diff --git a/gui/contextMenu.py b/gui/contextMenu.py index 9f0a8d7bd4..e5dd475088 100644 --- a/gui/contextMenu.py +++ b/gui/contextMenu.py @@ -54,7 +54,7 @@ def getMenu(cls, selection, *fullContexts): item = wx.MenuItem(menu, id, text) menu.info[id] = (m, fullContext, it) - sub = m.getSubMenu(srcContext, selection, menu, it) + sub = m.getSubMenu(srcContext, selection, menu, it, id) if sub is not None: item.SetSubMenu(sub) From 030e6aa9dba060ccfbae7520709c6bbd7f361dbe Mon Sep 17 00:00:00 2001 From: blitzmann Date: Mon, 15 Sep 2014 15:48:26 -0400 Subject: [PATCH 09/11] Instead of sending id, send parent item (which contains ID). This allows us to access the item to modify bitmap or any other value for it. --- gui/builtinContextMenus/changeAffectingSkills.py | 2 +- gui/builtinContextMenus/damagePattern.py | 12 ++++++++++-- gui/builtinContextMenus/moduleAmmoPicker.py | 2 +- gui/builtinContextMenus/targetResists.py | 2 +- gui/builtinContextMenus/whProjector.py | 2 +- gui/contextMenu.py | 4 ++-- 6 files changed, 16 insertions(+), 8 deletions(-) diff --git a/gui/builtinContextMenus/changeAffectingSkills.py b/gui/builtinContextMenus/changeAffectingSkills.py index 95d2bc228b..5748ce78a4 100644 --- a/gui/builtinContextMenus/changeAffectingSkills.py +++ b/gui/builtinContextMenus/changeAffectingSkills.py @@ -67,7 +67,7 @@ def addSkill(self, rootMenu, skill, i): rootMenu.Bind(wx.EVT_MENU, self.handleSkillChange, menuItem) return menuItem - def getSubMenu(self, context, selection, menu, i, id): + def getSubMenu(self, context, selection, menu, i, pitem): self.context = context self.skillIds = {} diff --git a/gui/builtinContextMenus/damagePattern.py b/gui/builtinContextMenus/damagePattern.py index 2242dba309..f763886290 100644 --- a/gui/builtinContextMenus/damagePattern.py +++ b/gui/builtinContextMenus/damagePattern.py @@ -14,6 +14,10 @@ def display(self, srcContext, selection): def getText(self, itmContext, selection): sDP = service.DamagePattern.getInstance() + sFit = service.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) ) @@ -73,15 +77,19 @@ def addPattern(self, menu, pattern): item.SetBitmap(bitmap) return item - def getSubMenu(self, context, selection, menu, i, id): + def getSubMenu(self, context, selection, menu, i, pitem): menu.Bind(wx.EVT_MENU, self.handlePatternSwitch) # this bit is required for some reason 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 + id = pitem.GetId() self.patternIds[id] = self.singles[i] - menu.Bind(wx.EVT_MENU, self.handlePatternSwitch, id=id) + menu.Bind(wx.EVT_MENU, self.handlePatternSwitch, pitem) + if self.patternIds[id] == self.fit.damagePattern: + bitmap = bitmapLoader.getBitmap("state_active_small", "icons") + pitem.SetBitmap(bitmap) return None sub = wx.Menu() diff --git a/gui/builtinContextMenus/moduleAmmoPicker.py b/gui/builtinContextMenus/moduleAmmoPicker.py index a1a9f45cf3..55b03cf8ba 100644 --- a/gui/builtinContextMenus/moduleAmmoPicker.py +++ b/gui/builtinContextMenus/moduleAmmoPicker.py @@ -116,7 +116,7 @@ def addSeperator(self, m, text): m.Append(id, u'─ %s ─' % text) m.Enable(id, False) - def getSubMenu(self, context, selection, menu, i, id): + def getSubMenu(self, context, selection, menu, i, pitem): self.context = context menu.Bind(wx.EVT_MENU, self.handleAmmoSwitch) m = wx.Menu() diff --git a/gui/builtinContextMenus/targetResists.py b/gui/builtinContextMenus/targetResists.py index c5b9c18929..c7180a88fb 100644 --- a/gui/builtinContextMenus/targetResists.py +++ b/gui/builtinContextMenus/targetResists.py @@ -63,7 +63,7 @@ def addSeperator(self, m, text): m.Append(id, u'─ %s ─' % text) m.Enable(id, False) - def getSubMenu(self, context, selection, menu, i, id): + def getSubMenu(self, context, selection, menu, i, pitem): self.context = context menu.Bind(wx.EVT_MENU, self.handleResistSwitch) m = wx.Menu() diff --git a/gui/builtinContextMenus/whProjector.py b/gui/builtinContextMenus/whProjector.py index 522d40bd22..fb32f34a86 100644 --- a/gui/builtinContextMenus/whProjector.py +++ b/gui/builtinContextMenus/whProjector.py @@ -17,7 +17,7 @@ def getText(self, itmContext, selection): def activate(self, fullContext, selection, i): pass - def getSubMenu(self, context, selection, menu, i, id): + def getSubMenu(self, context, selection, menu, i, pitem): self.idmap = {} menu.Bind(wx.EVT_MENU, self.handleSelection) m = wx.Menu() diff --git a/gui/contextMenu.py b/gui/contextMenu.py index e5dd475088..9c6213d635 100644 --- a/gui/contextMenu.py +++ b/gui/contextMenu.py @@ -54,7 +54,7 @@ def getMenu(cls, selection, *fullContexts): item = wx.MenuItem(menu, id, text) menu.info[id] = (m, fullContext, it) - sub = m.getSubMenu(srcContext, selection, menu, it, id) + sub = m.getSubMenu(srcContext, selection, menu, it, item) if sub is not None: item.SetSubMenu(sub) @@ -95,7 +95,7 @@ def display(self, context, selection): def activate(self, context, selection, i): return None - def getSubMenu(self, context, selection, menu, i): + def getSubMenu(self, context, selection, menu, i, pitem): return None def getText(self, context, selection): From 35d5c49745a795770f434b4830595253f1d8d24d Mon Sep 17 00:00:00 2001 From: blitzmann Date: Mon, 15 Sep 2014 16:11:30 -0400 Subject: [PATCH 10/11] Allow us to select target resist after creating / renaming it --- gui/resistsEditor.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/gui/resistsEditor.py b/gui/resistsEditor.py index 01d8747254..1092e77a2c 100644 --- a/gui/resistsEditor.py +++ b/gui/resistsEditor.py @@ -325,7 +325,7 @@ def processRename(self, event): # rename regardless of new or rename sTR.renamePattern(p, newName) - self.updateChoices() + self.updateChoices(newName) self.headerSizer.Replace(self.namePicker, self.ccResists) self.ccResists.Show() self.namePicker.Hide() @@ -361,7 +361,7 @@ def deletePattern(self,event): def __del__( self ): pass - def updateChoices(self): + def updateChoices(self, select=None): "Gathers list of patterns and updates choice selections" sTR = service.TargetResists.getInstance() self.choices = sTR.getTargetResistsList() @@ -370,9 +370,15 @@ def updateChoices(self): self.choices.sort(key=lambda p: p.name) self.ccResists.Clear() - for choice in map(lambda p: p.name, self.choices): + for i, choice in enumerate(map(lambda p: p.name, self.choices)): self.ccResists.Append(choice) - self.ccResists.SetSelection(0) + + if select is not None and choice == select: + self.ccResists.SetSelection(i) + + if select is None: + self.ccResists.SetSelection(0) + self.patternChanged() def importPatterns(self, event): From c903dff8ad6d097fae35ce814b4b69570ebb6ec4 Mon Sep 17 00:00:00 2001 From: blitzmann Date: Mon, 15 Sep 2014 18:02:49 -0400 Subject: [PATCH 11/11] Removed debugging prints --- eos/saveddata/damagePattern.py | 1 - eos/saveddata/fit.py | 2 +- eos/saveddata/targetResists.py | 2 -- service/fit.py | 2 +- service/targetResists.py | 1 - 5 files changed, 2 insertions(+), 6 deletions(-) diff --git a/eos/saveddata/damagePattern.py b/eos/saveddata/damagePattern.py index 8c938736a6..f9be897464 100644 --- a/eos/saveddata/damagePattern.py +++ b/eos/saveddata/damagePattern.py @@ -95,7 +95,6 @@ def importPatterns(cls, text): continue if len(fields) == 4: # Avoid possible blank lines - print name, fields pattern = DamagePattern(**fields) pattern.name = name.strip() patterns.append(pattern) diff --git a/eos/saveddata/fit.py b/eos/saveddata/fit.py index 35dcbbb763..f8aefa83ba 100644 --- a/eos/saveddata/fit.py +++ b/eos/saveddata/fit.py @@ -820,7 +820,7 @@ def calculateWeaponStats(self): weaponDPS = 0 droneDPS = 0 weaponVolley = 0 - print "calc weapons with: %s"%self.targetResists + for mod in self.modules: dps, volley = mod.damageStats(self.targetResists) weaponDPS += dps diff --git a/eos/saveddata/targetResists.py b/eos/saveddata/targetResists.py index d23890ce0f..8798ebf19d 100644 --- a/eos/saveddata/targetResists.py +++ b/eos/saveddata/targetResists.py @@ -24,7 +24,6 @@ class TargetResists(object): DAMAGE_TYPES = ("em", "thermal", "kinetic", "explosive") def __init__(self, emAmount = 0, thermalAmount = 0, kineticAmount = 0, explosiveAmount = 0): - print "new" self.emAmount = emAmount self.thermalAmount = thermalAmount self.kineticAmount = kineticAmount @@ -62,7 +61,6 @@ def importPatterns(cls, text): continue if len(fields) == 4: # Avoid possible blank lines - print name, fields pattern = TargetResists(**fields) pattern.name = name.strip() patterns.append(pattern) diff --git a/service/fit.py b/service/fit.py index 9719fe8e17..60e899fafd 100644 --- a/service/fit.py +++ b/service/fit.py @@ -695,7 +695,7 @@ def getTargetResists(self, fitID): def setTargetResists(self, fitID, pattern): if fitID is None: return - print "Set target resists: %s"%pattern + fit = eos.db.getFit(fitID) fit.targetResists = pattern eos.db.commit() diff --git a/service/targetResists.py b/service/targetResists.py index 49deb154b8..a8f61b9f92 100644 --- a/service/targetResists.py +++ b/service/targetResists.py @@ -37,7 +37,6 @@ def getTargetResistsList(self): return eos.db.getTargetResistsList() def getTargetResists(self, name): - print "Getting Target Resists: %s"%name return eos.db.getTargetResists(name) def newPattern(self):