diff --git a/config.py b/config.py index 21b88fdd3..8b0f4b9ae 100644 --- a/config.py +++ b/config.py @@ -1,90 +1,90 @@ -import os -import sys - -# Load variable overrides specific to distribution type -try: - import configforced -except ImportError: - configforced = None - -# Turns on debug mode -debug = False -# Defines if our saveddata will be in pyfa root or not -saveInRoot = False - -# Version data -version = "1.7.2" -tag = "git" -expansionName = "Rhea" -expansionVersion = "1.0" -evemonMinVersion = "4081" - -# Database version (int ONLY) -# Increment every time we need to flag for user database upgrade/modification -dbversion = 3 - -pyfaPath = None -savePath = None -staticPath = None -saveDB = None -gameDB = None - -def defPaths(): - global pyfaPath - global savePath - global staticPath - global saveDB - global gameDB - global saveInRoot - # The main pyfa directory which contains run.py - # Python 2.X uses ANSI by default, so we need to convert the character encoding - pyfaPath = getattr(configforced, "pyfaPath", pyfaPath) - if pyfaPath is None: - pyfaPath = unicode(os.path.dirname(os.path.realpath(os.path.abspath( - sys.modules['__main__'].__file__))), sys.getfilesystemencoding()) - - # Where we store the saved fits etc, default is the current users home directory - if saveInRoot is True: - savePath = getattr(configforced, "savePath", None) - if savePath is None: - savePath = os.path.join(pyfaPath, "saveddata") - else: - savePath = getattr(configforced, "savePath", None) - if savePath is None: - savePath = unicode(os.path.expanduser(os.path.join("~", ".pyfa")), - sys.getfilesystemencoding()) - - # Redirect stderr to file if we're requested to do so - stderrToFile = getattr(configforced, "stderrToFile", None) - if stderrToFile is True: - if not os.path.exists(savePath): - os.mkdir(savePath) - sys.stderr = open(os.path.join(savePath, "error_log.txt"), "w") - - # Same for stdout - stdoutToFile = getattr(configforced, "stdoutToFile", None) - if stdoutToFile is True: - if not os.path.exists(savePath): - os.mkdir(savePath) - sys.stdout = open(os.path.join(savePath, "output_log.txt"), "w") - - # Static EVE Data from the staticdata repository, should be in the staticdata - # directory in our pyfa directory - staticPath = os.path.join(pyfaPath, "staticdata") - - # The database where we store all the fits etc - saveDB = os.path.join(savePath, "saveddata.db") - - # The database where the static EVE data from the datadump is kept. - # This is not the standard sqlite datadump but a modified version created by eos - # maintenance script - gameDB = os.path.join(staticPath, "eve.db") - - ## DON'T MODIFY ANYTHING BELOW ## - import eos.config - - #Caching modifiers, disable all gamedata caching, its unneeded. - eos.config.gamedataCache = False - # saveddata db location modifier, shouldn't ever need to touch this - eos.config.saveddata_connectionstring = "sqlite:///" + saveDB + "?check_same_thread=False" - eos.config.gamedata_connectionstring = "sqlite:///" + gameDB + "?check_same_thread=False" +import os +import sys + +# Load variable overrides specific to distribution type +try: + import configforced +except ImportError: + configforced = None + +# Turns on debug mode +debug = False +# Defines if our saveddata will be in pyfa root or not +saveInRoot = False + +# Version data +version = "1.10.1" +tag = "git" +expansionName = "Scylla" +expansionVersion = "1.0" +evemonMinVersion = "4081" + +# Database version (int ONLY) +# Increment every time we need to flag for user database upgrade/modification +dbversion = 6 + +pyfaPath = None +savePath = None +staticPath = None +saveDB = None +gameDB = None + +def defPaths(): + global pyfaPath + global savePath + global staticPath + global saveDB + global gameDB + global saveInRoot + # The main pyfa directory which contains run.py + # Python 2.X uses ANSI by default, so we need to convert the character encoding + pyfaPath = getattr(configforced, "pyfaPath", pyfaPath) + if pyfaPath is None: + pyfaPath = unicode(os.path.dirname(os.path.realpath(os.path.abspath( + sys.modules['__main__'].__file__))), sys.getfilesystemencoding()) + + # Where we store the saved fits etc, default is the current users home directory + if saveInRoot is True: + savePath = getattr(configforced, "savePath", None) + if savePath is None: + savePath = os.path.join(pyfaPath, "saveddata") + else: + savePath = getattr(configforced, "savePath", None) + if savePath is None: + savePath = unicode(os.path.expanduser(os.path.join("~", ".pyfa")), + sys.getfilesystemencoding()) + + # Redirect stderr to file if we're requested to do so + stderrToFile = getattr(configforced, "stderrToFile", None) + if stderrToFile is True: + if not os.path.exists(savePath): + os.mkdir(savePath) + sys.stderr = open(os.path.join(savePath, "error_log.txt"), "w") + + # Same for stdout + stdoutToFile = getattr(configforced, "stdoutToFile", None) + if stdoutToFile is True: + if not os.path.exists(savePath): + os.mkdir(savePath) + sys.stdout = open(os.path.join(savePath, "output_log.txt"), "w") + + # Static EVE Data from the staticdata repository, should be in the staticdata + # directory in our pyfa directory + staticPath = os.path.join(pyfaPath, "staticdata") + + # The database where we store all the fits etc + saveDB = os.path.join(savePath, "saveddata.db") + + # The database where the static EVE data from the datadump is kept. + # This is not the standard sqlite datadump but a modified version created by eos + # maintenance script + gameDB = os.path.join(staticPath, "eve.db") + + ## DON'T MODIFY ANYTHING BELOW ## + import eos.config + + #Caching modifiers, disable all gamedata caching, its unneeded. + eos.config.gamedataCache = False + # saveddata db location modifier, shouldn't ever need to touch this + eos.config.saveddata_connectionstring = "sqlite:///" + saveDB + "?check_same_thread=False" + eos.config.gamedata_connectionstring = "sqlite:///" + gameDB + "?check_same_thread=False" diff --git a/eos/config.py b/eos/config.py index 192982e1f..35e2fe0dc 100644 --- a/eos/config.py +++ b/eos/config.py @@ -1,11 +1,11 @@ -import os.path +from os.path import realpath, join, dirname, abspath import sys debug = False gamedataCache = True saveddataCache = True -gamedata_connectionstring = 'sqlite:///' + os.path.expanduser(os.path.join("~", ".pyfa","eve.db")) +gamedata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "staticdata", "eve.db")), sys.getfilesystemencoding()) saveddata_connectionstring = 'sqlite:///:memory:' #Autodetect path, only change if the autodetection bugs out. -path = os.path.dirname(unicode(__file__, sys.getfilesystemencoding())) +path = dirname(unicode(__file__, sys.getfilesystemencoding())) diff --git a/eos/db/__init__.py b/eos/db/__init__.py index bedb917d6..8867d63c5 100644 --- a/eos/db/__init__.py +++ b/eos/db/__init__.py @@ -75,7 +75,7 @@ from eos.db.saveddata.queries import getUser, getCharacter, getFit, getFitsWithS getFitList, getFleetList, getFleet, save, remove, commit, add, \ getCharactersForUser, getMiscData, getSquadsIDsWithFitID, getWing, \ getSquad, getBoosterFits, getProjectedFits, getTargetResistsList, getTargetResists,\ - clearPrices + clearPrices, countAllFits #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/migrations/upgrade3.py b/eos/db/migrations/upgrade3.py index 5467fdf2d..0350ded72 100644 --- a/eos/db/migrations/upgrade3.py +++ b/eos/db/migrations/upgrade3.py @@ -8,6 +8,6 @@ import sqlalchemy def upgrade(saveddata_engine): try: - saveddata_engine.execute("SELECT mode FROM fits LIMIT 1") + saveddata_engine.execute("SELECT modeID FROM fits LIMIT 1") except sqlalchemy.exc.DatabaseError: saveddata_engine.execute("ALTER TABLE fits ADD COLUMN modeID INTEGER") diff --git a/eos/db/migrations/upgrade4.py b/eos/db/migrations/upgrade4.py new file mode 100644 index 000000000..87906cffc --- /dev/null +++ b/eos/db/migrations/upgrade4.py @@ -0,0 +1,141 @@ +""" +Migration 4 + +- Converts modules based on Proteus Module Tiericide + Some modules have been unpublished (and unpublished module attributes are removed + from database), which causes pyfa to crash. We therefore replace these + modules with their new replacements + + Based on http://community.eveonline.com/news/patch-notes/patch-notes-for-proteus/ + and output of itemDiff.py +""" + + +CONVERSIONS = { + 506: ( # 'Basic' Capacitor Power Relay + 8205, # Alpha Reactor Control: Capacitor Power Relay + 8209, # Marked Generator Refitting: Capacitor Power Relay + 8203, # Partial Power Plant Manager: Capacity Power Relay + 8207, # Type-E Power Core Modification: Capacitor Power Relay + ), + 8177: ( # Mark I Compact Capacitor Power Relay + 8173, # Beta Reactor Control: Capacitor Power Relay I + ), + 8175: ( # Type-D Restrained Capacitor Power Relay + 8171, # Local Power Plant Manager: Capacity Power Relay I + ), + + 421: ( # 'Basic' Capacitor Recharger + 4425, # AGM Capacitor Charge Array, + 4421, # F-a10 Buffer Capacitor Regenerator + 4423, # Industrial Capacitor Recharger + 4427, # Secondary Parallel Link-Capacitor + ), + 4435: ( # Eutectic Compact Cap Recharger + 4433, # Barton Reactor Capacitor Recharger I + 4431, # F-b10 Nominal Capacitor Regenerator + 4437, # Fixed Parallel Link-Capacitor I + ), + + 1315: ( # 'Basic' Expanded Cargohold + 5483, # Alpha Hull Mod Expanded Cargo + 5479, # Marked Modified SS Expanded Cargo + 5481, # Partial Hull Conversion Expanded Cargo + 5485, # Type-E Altered SS Expanded Cargo + ), + 5493: ( # Type-D Restrained Expanded Cargo + 5491, # Beta Hull Mod Expanded Cargo + 5489, # Local Hull Conversion Expanded Cargo I + 5487, # Mark I Modified SS Expanded Cargo + ), + + 1401: ( # 'Basic' Inertial Stabilizers + 5523, # Alpha Hull Mod Inertial Stabilizers + 5521, # Partial Hull Conversion Inertial Stabilizers + 5525, # Type-E Altered SS Inertial Stabilizers + ), + 5533: ( # Type-D Restrained Inertial Stabilizers + 5531, # Beta Hull Mod Inertial Stabilizers + 5529, # Local Hull Conversion Inertial Stabilizers I + 5527, # Mark I Modified SS Inertial Stabilizers + 5519, # Marked Modified SS Inertial Stabilizers + ), + + 5239: ( # EP-S Gaussian Scoped Mining Laser + 5241, # Dual Diode Mining Laser I + ), + 5233: ( # Single Diode Basic Mining Laser + 5231, # EP-R Argon Ion Basic Excavation Pulse + 5237, # Rubin Basic Particle Bore Stream + 5235, # Xenon Basic Drilling Beam + ), + 5245: ( # Particle Bore Compact Mining Laser + 5243, # XeCl Drilling Beam I + ), + + 22619: ( # Frigoris Restrained Ice Harvester Upgrade + 22617, # Crisium Ice Harvester Upgrade + ), + 22611: ( # Elara Restrained Mining Laser Upgrade + 22609, # Erin Mining Laser Upgrade + ), + + 1242: ( # 'Basic' Nanofiber Internal Structure + 5591, # Alpha Hull Mod Nanofiber Structure + 5595, # Marked Modified SS Nanofiber Structure + 5559, # Partial Hull Conversion Nanofiber Structure + 5593, # Type-E Altered SS Nanofiber Structure + ), + 5599: ( # Type-D Restrained Nanofiber Structure + 5597, # Beta Hull Mod Nanofiber Structure + 5561, # Local Hull Conversion Nanofiber Structure I + 5601, # Mark I Modified SS Nanofiber Structure + ), + + 1192: ( # 'Basic' Overdrive Injector System + 5613, # Alpha Hull Mod Overdrive Injector + 5617, # Marked Modified SS Overdrive Injector + 5611, # Partial Hull Conversion Overdrive Injector + 5615, # Type-E Altered SS Overdrive Injector + ), + 5631: ( # Type-D Restrained Overdrive Injector + 5629, # Beta Hull Mod Overdrive Injector + 5627, # Local Hull Conversion Overdrive Injector I + 5633, # Mark I Modified SS Overdrive Injector + ), + + 1537: ( # 'Basic' Power Diagnostic System + 8213, # Alpha Reactor Control: Diagnostic System + 8217, # Marked Generator Refitting: Diagnostic System + 8211, # Partial Power Plant Manager: Diagnostic System + 8215, # Type-E Power Core Modification: Diagnostic System + 8255, # Type-E Power Core Modification: Reaction Control + ), + 8225: ( # Mark I Compact Power Diagnostic System + 8221, # Beta Reactor Control: Diagnostic System I + 8219, # Local Power Plant Manager: Diagnostic System I + 8223, # Type-D Power Core Modification: Diagnostic System + ), + + 1240: ( # 'Basic' Reinforced Bulkheads + 5677, # Alpha Hull Mod Reinforced Bulkheads + 5681, # Marked Modified SS Reinforced Bulkheads + 5675, # Partial Hull Conversion Reinforced Bulkheads + 5679, # Type-E Altered SS Reinforced Bulkheads + ), + 5649: ( # Mark I Compact Reinforced Bulkheads + 5645, # Beta Hull Mod Reinforced Bulkheads + ), + 5647: ( # Type-D Restrained Reinforced Bulkheads + 5643, # Local Hull Conversion Reinforced Bulkheads I + ), +} + +def upgrade(saveddata_engine): + + # Convert modules + for replacement_item, list in CONVERSIONS.iteritems(): + for retired_item in list: + saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item)) + saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item)) + diff --git a/eos/db/migrations/upgrade5.py b/eos/db/migrations/upgrade5.py new file mode 100644 index 000000000..cf6a3385d --- /dev/null +++ b/eos/db/migrations/upgrade5.py @@ -0,0 +1,8 @@ +""" +Migration 5 + +Simply deletes damage profiles with a blank name. See GH issue #256 +""" + +def upgrade(saveddata_engine): + saveddata_engine.execute('DELETE FROM damagePatterns WHERE name LIKE ?', ("",)) diff --git a/eos/db/migrations/upgrade6.py b/eos/db/migrations/upgrade6.py new file mode 100644 index 000000000..ee8a091e6 --- /dev/null +++ b/eos/db/migrations/upgrade6.py @@ -0,0 +1,9 @@ +""" +Migration 6 + +Overwrites damage profile 0 to reset bad uniform values (bad values set with bug) +""" + +def upgrade(saveddata_engine): + saveddata_engine.execute('DELETE FROM damagePatterns WHERE name LIKE ? OR ID LIKE ?', ("Uniform", "1")) + saveddata_engine.execute('INSERT INTO damagePatterns VALUES (?, ?, ?, ?, ?, ?, ?)', (1, "Uniform", 25, 25, 25, 25, None)) diff --git a/eos/db/saveddata/queries.py b/eos/db/saveddata/queries.py index 9fee22561..be7c078fc 100644 --- a/eos/db/saveddata/queries.py +++ b/eos/db/saveddata/queries.py @@ -267,6 +267,11 @@ def getBoosterFits(ownerID=None, where=None, eager=None): fits = saveddata_session.query(Fit).options(*eager).filter(filter).all() return fits +def countAllFits(): + with sd_lock: + count = saveddata_session.query(Fit).count() + return count + def countFitsWithShip(shipID, ownerID=None, where=None, eager=None): """ Get all the fits using a certain ship. diff --git a/eos/effects/agilitymultipliereffect.py b/eos/effects/agilitymultipliereffect.py index 9478201f3..11306be36 100644 --- a/eos/effects/agilitymultipliereffect.py +++ b/eos/effects/agilitymultipliereffect.py @@ -1,9 +1,9 @@ # agilityMultiplierEffect # # Used by: -# Modules from group: Inertia Stabilizer (12 of 12) -# Modules from group: Nanofiber Internal Structure (14 of 14) -# Modules from group: Reinforced Bulkhead (12 of 12) +# Modules from group: Inertial Stabilizer (7 of 7) +# Modules from group: Nanofiber Internal Structure (7 of 7) +# Modules from group: Reinforced Bulkhead (8 of 8) type = "passive" def handler(fit, module, context): fit.ship.boostItemAttr("agility", diff --git a/eos/effects/capacitorcapacitymultiply.py b/eos/effects/capacitorcapacitymultiply.py index d761c502c..17e9d1da4 100644 --- a/eos/effects/capacitorcapacitymultiply.py +++ b/eos/effects/capacitorcapacitymultiply.py @@ -2,8 +2,8 @@ # # Used by: # Modules from group: Capacitor Flux Coil (6 of 6) -# Modules from group: Capacitor Power Relay (26 of 26) -# Modules from group: Power Diagnostic System (31 of 31) +# Modules from group: Capacitor Power Relay (20 of 20) +# Modules from group: Power Diagnostic System (23 of 23) # Modules from group: Propulsion Module (107 of 107) # Modules from group: Reactor Control Unit (22 of 22) # Modules from group: Shield Flux Coil (11 of 11) diff --git a/eos/effects/cargocapacitymultiply.py b/eos/effects/cargocapacitymultiply.py index c98c31387..c476f9b79 100644 --- a/eos/effects/cargocapacitymultiply.py +++ b/eos/effects/cargocapacitymultiply.py @@ -1,9 +1,9 @@ # cargoCapacityMultiply # # Used by: -# Modules from group: Expanded Cargohold (13 of 13) -# Modules from group: Overdrive Injector System (14 of 14) -# Modules from group: Reinforced Bulkhead (12 of 12) +# Modules from group: Expanded Cargohold (7 of 7) +# Modules from group: Overdrive Injector System (7 of 7) +# Modules from group: Reinforced Bulkhead (8 of 8) type = "passive" def handler(fit, module, context): fit.ship.multiplyItemAttr("capacity", module.getModifiedItemAttr("cargoCapacityMultiplier")) diff --git a/eos/effects/commandbonustdmultiplywithcommandbonushidden.py b/eos/effects/commandbonustdmultiplywithcommandbonushidden.py index 6b0ea92f7..05825349c 100644 --- a/eos/effects/commandbonustdmultiplywithcommandbonushidden.py +++ b/eos/effects/commandbonustdmultiplywithcommandbonushidden.py @@ -6,6 +6,7 @@ gangBonus = "commandBonusTD" gangBoost = "ewarStrTD" type = "active", "gang" def handler(fit, module, context): + if "gang" not in context: return for bonus in ("maxRangeBonus", "falloffBonus", "trackingSpeedBonus"): fit.modules.filteredItemBoost(lambda mod: lambda mod: mod.item.requiresSkill("Weapon Disruption"), bonus, module.getModifiedItemAttr("commandBonusTD")) diff --git a/eos/effects/covertopscloakcpupercentbonuspiratefaction.py b/eos/effects/covertopscloakcpupercentbonuspiratefaction.py index 0e6fe99e3..fa7faffc3 100644 --- a/eos/effects/covertopscloakcpupercentbonuspiratefaction.py +++ b/eos/effects/covertopscloakcpupercentbonuspiratefaction.py @@ -3,6 +3,7 @@ # Used by: # Ship: Astero # Ship: Prospect +# Ship: Victorieux Luxury Yacht type = "passive" runTime = "early" def handler(fit, ship, context): diff --git a/eos/effects/elitereconbonusassaultlauncherrof1.py b/eos/effects/elitereconbonusassaultlauncherrof1.py deleted file mode 100644 index b4237469e..000000000 --- a/eos/effects/elitereconbonusassaultlauncherrof1.py +++ /dev/null @@ -1,10 +0,0 @@ -# eliteReconBonusAssaultLauncherROF1 -# -# Used by: -# Ship: Huginn -# Ship: Lachesis -type = "passive" -def handler(fit, ship, context): - level = fit.character.getSkill("Recon Ships").level - fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Missile Launcher Rapid Light", - "speed", ship.getModifiedItemAttr("eliteBonusReconShip1") * level) diff --git a/eos/effects/elitereconbonusheavyassaultlauncherrof1.py b/eos/effects/elitereconbonusheavyassaultlauncherrof1.py deleted file mode 100644 index 15c7c8e29..000000000 --- a/eos/effects/elitereconbonusheavyassaultlauncherrof1.py +++ /dev/null @@ -1,9 +0,0 @@ -# eliteReconBonusHeavyAssaultLauncherROF1 -# -# Used by: -# Ship: Huginn -type = "passive" -def handler(fit, ship, context): - level = fit.character.getSkill("Recon Ships").level - fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Missile Launcher Heavy Assault", - "speed", ship.getModifiedItemAttr("eliteBonusReconShip1") * level) diff --git a/eos/effects/elitereconbonusheavylauncherrof1.py b/eos/effects/elitereconbonusheavylauncherrof1.py deleted file mode 100644 index bbce42793..000000000 --- a/eos/effects/elitereconbonusheavylauncherrof1.py +++ /dev/null @@ -1,10 +0,0 @@ -# eliteReconBonusHeavyLauncherROF1 -# -# Used by: -# Ship: Huginn -# Ship: Lachesis -type = "passive" -def handler(fit, ship, context): - level = fit.character.getSkill("Recon Ships").level - fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Missile Launcher Heavy", - "speed", ship.getModifiedItemAttr("eliteBonusReconShip1") * level) diff --git a/eos/effects/elitereconbonusmhtoptimalrange1.py b/eos/effects/elitereconbonusmhtoptimalrange1.py new file mode 100644 index 000000000..4f9ad6048 --- /dev/null +++ b/eos/effects/elitereconbonusmhtoptimalrange1.py @@ -0,0 +1,9 @@ +# eliteReconBonusMHTOptimalRange1 +# +# Used by: +# Ship: Lachesis +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Recon Ships").level + fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Hybrid Turret"), + "maxRange", ship.getModifiedItemAttr("eliteBonusReconShip1") * level) diff --git a/eos/effects/elitereconbonusmptdamage1.py b/eos/effects/elitereconbonusmptdamage1.py new file mode 100644 index 000000000..1a8b12924 --- /dev/null +++ b/eos/effects/elitereconbonusmptdamage1.py @@ -0,0 +1,9 @@ +# eliteReconBonusMPTdamage1 +# +# Used by: +# Ship: Huginn +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Recon Ships").level + fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Projectile Turret"), + "damageMultiplier", ship.getModifiedItemAttr("eliteBonusReconShip1") * level) diff --git a/eos/effects/elitereconbonusneutrange3.py b/eos/effects/elitereconbonusneutrange3.py new file mode 100644 index 000000000..88b6ecb03 --- /dev/null +++ b/eos/effects/elitereconbonusneutrange3.py @@ -0,0 +1,9 @@ +# eliteReconBonusNeutRange3 +# +# Used by: +# Ship: Pilgrim +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Recon Ships").level + fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Energy Destabilizer", + "energyDestabilizationRange", ship.getModifiedItemAttr("eliteBonusReconShip3") * level) diff --git a/eos/effects/elitereconbonusvamprange3.py b/eos/effects/elitereconbonusvamprange3.py new file mode 100644 index 000000000..dfafdd3a3 --- /dev/null +++ b/eos/effects/elitereconbonusvamprange3.py @@ -0,0 +1,9 @@ +# eliteReconBonusVampRange3 +# +# Used by: +# Ship: Pilgrim +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Recon Ships").level + fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Energy Vampire", + "powerTransferRange", ship.getModifiedItemAttr("eliteBonusReconShip3") * level) diff --git a/eos/effects/iceharvestcycletimemodulesrequiringiceharvestingonline.py b/eos/effects/iceharvestcycletimemodulesrequiringiceharvestingonline.py index 501ab9bd4..b495ccaaf 100644 --- a/eos/effects/iceharvestcycletimemodulesrequiringiceharvestingonline.py +++ b/eos/effects/iceharvestcycletimemodulesrequiringiceharvestingonline.py @@ -1,7 +1,7 @@ # iceHarvestCycleTimeModulesRequiringIceHarvestingOnline # # Used by: -# Variations of module: Ice Harvester Upgrade I (6 of 6) +# Variations of module: Ice Harvester Upgrade I (5 of 5) type = "passive" def handler(fit, module, context): fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Ice Harvesting"), diff --git a/eos/effects/iceminercpuusagepercent.py b/eos/effects/iceminercpuusagepercent.py index d14d89589..9a3f04694 100644 --- a/eos/effects/iceminercpuusagepercent.py +++ b/eos/effects/iceminercpuusagepercent.py @@ -1,7 +1,7 @@ # iceMinerCpuUsagePercent # # Used by: -# Variations of module: Ice Harvester Upgrade I (6 of 6) +# Variations of module: Ice Harvester Upgrade I (5 of 5) type = "passive" def handler(fit, module, context): fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Ice Harvesting"), diff --git a/eos/effects/increasesignatureradiusonline.py b/eos/effects/increasesignatureradiusonline.py index a4bd284b4..a67dc074f 100644 --- a/eos/effects/increasesignatureradiusonline.py +++ b/eos/effects/increasesignatureradiusonline.py @@ -1,7 +1,7 @@ # increaseSignatureRadiusOnline # # Used by: -# Modules from group: Inertia Stabilizer (12 of 12) +# Modules from group: Inertial Stabilizer (7 of 7) type = "passive" def handler(fit, module, context): fit.ship.boostItemAttr("signatureRadius", module.getModifiedItemAttr("signatureRadiusBonus")) \ No newline at end of file diff --git a/eos/effects/minercpuusagemultiplypercent2.py b/eos/effects/minercpuusagemultiplypercent2.py index 6f1b9aa33..f76b5323b 100644 --- a/eos/effects/minercpuusagemultiplypercent2.py +++ b/eos/effects/minercpuusagemultiplypercent2.py @@ -1,7 +1,7 @@ # minerCpuUsageMultiplyPercent2 # # Used by: -# Variations of module: Mining Laser Upgrade I (6 of 6) +# Variations of module: Mining Laser Upgrade I (5 of 5) type = "passive" def handler(fit, module, context): fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining"), diff --git a/eos/effects/mininglaser.py b/eos/effects/mininglaser.py index a691775fa..a4095f4ed 100644 --- a/eos/effects/mininglaser.py +++ b/eos/effects/mininglaser.py @@ -2,7 +2,7 @@ # # Used by: # Modules from group: Frequency Mining Laser (3 of 3) -# Modules from group: Mining Laser (17 of 17) +# Modules from group: Mining Laser (12 of 12) # Modules from group: Strip Miner (5 of 5) type = 'active' def handler(fit, module, context): diff --git a/eos/effects/miningyieldmultiplypercent.py b/eos/effects/miningyieldmultiplypercent.py index 0ca493d0b..d00198ab4 100644 --- a/eos/effects/miningyieldmultiplypercent.py +++ b/eos/effects/miningyieldmultiplypercent.py @@ -1,7 +1,7 @@ # miningYieldMultiplyPercent # # Used by: -# Variations of module: Mining Laser Upgrade I (6 of 6) +# Variations of module: Mining Laser Upgrade I (5 of 5) type = "passive" def handler(fit, module, context): fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining"), diff --git a/eos/effects/modeagilitypostdiv.py b/eos/effects/modeagilitypostdiv.py index 022951098..d57571078 100644 --- a/eos/effects/modeagilitypostdiv.py +++ b/eos/effects/modeagilitypostdiv.py @@ -1,8 +1,12 @@ # modeAgilityPostDiv # # Used by: -# Module: Amarr Tactical Destroyer Propulsion Mode +# Modules named like: Propulsion Mode (2 of 2) type = "passive" def handler(fit, module, context): - fit.ship.multiplyItemAttr("agility", 1/module.getModifiedItemAttr("modeAgilityPostDiv"), - stackingPenalties = True, penaltyGroup="postDiv") + fit.ship.multiplyItemAttr( + "agility", + 1 / module.getModifiedItemAttr("modeAgilityPostDiv"), + stackingPenalties=True, + penaltyGroup="postDiv" + ) diff --git a/eos/effects/modearmorresonancepostdiv.py b/eos/effects/modearmorresonancepostdiv.py index af767b63b..b24e6b14e 100644 --- a/eos/effects/modearmorresonancepostdiv.py +++ b/eos/effects/modearmorresonancepostdiv.py @@ -1,15 +1,18 @@ # modeArmorResonancePostDiv # # Used by: -# Module: Amarr Tactical Destroyer Defense Mode +# Modules named like: Defense Mode (2 of 2) type = "passive" def handler(fit, module, context): - for resType in ("Em", "Explosive", "Kinetic"): - fit.ship.multiplyItemAttr("armor{0}DamageResonance".format(resType), - 1/module.getModifiedItemAttr("mode{0}ResistancePostDiv".format(resType)), - stackingPenalties = True, penaltyGroup="postDiv") - - # Thermal != Thermic - fit.ship.multiplyItemAttr("armorThermalDamageResonance", - 1/module.getModifiedItemAttr("modeThermicResistancePostDiv"), - stackingPenalties = True, penaltyGroup="postDiv") + for srcResType, tgtResType in ( + ("Em", "Em"), + ("Explosive", "Explosive"), + ("Kinetic", "Kinetic"), + ("Thermic", "Thermal") + ): + fit.ship.multiplyItemAttr( + "armor{0}DamageResonance".format(tgtResType), + 1 / module.getModifiedItemAttr("mode{0}ResistancePostDiv".format(srcResType)), + stackingPenalties=True, + penaltyGroup="postDiv" + ) diff --git a/eos/effects/modemwdsigradiuspostdiv.py b/eos/effects/modemwdsigradiuspostdiv.py new file mode 100644 index 000000000..01421c82e --- /dev/null +++ b/eos/effects/modemwdsigradiuspostdiv.py @@ -0,0 +1,13 @@ +# modeMWDSigRadiusPostDiv +# +# Used by: +# Module: Svipul Defense Mode +type = "passive" +def handler(fit, module, context): + fit.modules.filteredItemMultiply( + lambda mod: mod.item.requiresSkill("High Speed Maneuvering"), + "signatureRadiusBonus", + 1 / module.getModifiedItemAttr("modeMWDSigPenaltyPostDiv"), + stackingPenalties=True, + penaltyGroup="postDiv" + ) diff --git a/eos/effects/modeshieldresonancepostdiv.py b/eos/effects/modeshieldresonancepostdiv.py new file mode 100644 index 000000000..a40c3c78a --- /dev/null +++ b/eos/effects/modeshieldresonancepostdiv.py @@ -0,0 +1,18 @@ +# modeShieldResonancePostDiv +# +# Used by: +# Module: Svipul Defense Mode +type = "passive" +def handler(fit, module, context): + for srcResType, tgtResType in ( + ("Em", "Em"), + ("Explosive", "Explosive"), + ("Kinetic", "Kinetic"), + ("Thermic", "Thermal") + ): + fit.ship.multiplyItemAttr( + "shield{0}DamageResonance".format(tgtResType), + 1 / module.getModifiedItemAttr("mode{0}ResistancePostDiv".format(srcResType)), + stackingPenalties=True, + penaltyGroup="postDiv" + ) diff --git a/eos/effects/modesigradiuspostdiv.py b/eos/effects/modesigradiuspostdiv.py index 72e955f73..7522b2aaf 100644 --- a/eos/effects/modesigradiuspostdiv.py +++ b/eos/effects/modesigradiuspostdiv.py @@ -1,9 +1,8 @@ # modeSigRadiusPostDiv # # Used by: -# Module: Amarr Tactical Destroyer Defense Mode +# Module: Confessor Defense Mode type = "passive" def handler(fit, module, context): - level = fit.character.getSkill("Minmatar Destroyer").level fit.ship.multiplyItemAttr("signatureRadius", 1/module.getModifiedItemAttr("modeSignatureRadiusPostDiv"), stackingPenalties = True, penaltyGroup="postDiv") diff --git a/eos/effects/modevelocitypostdiv.py b/eos/effects/modevelocitypostdiv.py index a38c9ddb8..14a4a5271 100644 --- a/eos/effects/modevelocitypostdiv.py +++ b/eos/effects/modevelocitypostdiv.py @@ -1,8 +1,12 @@ # modeVelocityPostDiv # # Used by: -# Module: Amarr Tactical Destroyer Propulsion Mode +# Modules named like: Propulsion Mode (2 of 2) type = "passive" def handler(fit, module, context): - fit.ship.multiplyItemAttr("maxVelocity", 1/module.getModifiedItemAttr("modeVelocityPostDiv"), - stackingPenalties = True, penaltyGroup="postDiv") + fit.ship.multiplyItemAttr( + "maxVelocity", + 1 / module.getModifiedItemAttr("modeVelocityPostDiv"), + stackingPenalties=True, + penaltyGroup="postDiv" + ) diff --git a/eos/effects/modifymaxvelocityofshippassive.py b/eos/effects/modifymaxvelocityofshippassive.py index 3c134f937..62670476a 100644 --- a/eos/effects/modifymaxvelocityofshippassive.py +++ b/eos/effects/modifymaxvelocityofshippassive.py @@ -1,7 +1,7 @@ # modifyMaxVelocityOfShipPassive # # Used by: -# Modules from group: Expanded Cargohold (13 of 13) +# Modules from group: Expanded Cargohold (7 of 7) type = "passive" def handler(fit, module, context): fit.ship.multiplyItemAttr("maxVelocity", module.getModifiedItemAttr("maxVelocityBonus"), diff --git a/eos/effects/modifypowerrechargerate.py b/eos/effects/modifypowerrechargerate.py index 9dcea33b5..4f1e35a4b 100644 --- a/eos/effects/modifypowerrechargerate.py +++ b/eos/effects/modifypowerrechargerate.py @@ -2,9 +2,9 @@ # # Used by: # Modules from group: Capacitor Flux Coil (6 of 6) -# Modules from group: Capacitor Power Relay (26 of 26) -# Modules from group: Capacitor Recharger (25 of 25) -# Modules from group: Power Diagnostic System (31 of 31) +# Modules from group: Capacitor Power Relay (20 of 20) +# Modules from group: Capacitor Recharger (18 of 18) +# Modules from group: Power Diagnostic System (23 of 23) # Modules from group: Reactor Control Unit (22 of 22) # Modules from group: Shield Flux Coil (11 of 11) # Modules from group: Shield Power Relay (11 of 11) diff --git a/eos/effects/modifyshieldrechargerate.py b/eos/effects/modifyshieldrechargerate.py index 1e1dbc192..1986cbb09 100644 --- a/eos/effects/modifyshieldrechargerate.py +++ b/eos/effects/modifyshieldrechargerate.py @@ -2,8 +2,8 @@ # # Used by: # Modules from group: Capacitor Flux Coil (6 of 6) -# Modules from group: Capacitor Power Relay (26 of 26) -# Modules from group: Power Diagnostic System (31 of 31) +# Modules from group: Capacitor Power Relay (20 of 20) +# Modules from group: Power Diagnostic System (23 of 23) # Modules from group: Reactor Control Unit (22 of 22) # Modules from group: Shield Flux Coil (11 of 11) # Modules from group: Shield Recharger (6 of 6) diff --git a/eos/effects/mwdsignatureradiusrolebonus.py b/eos/effects/mwdsignatureradiusrolebonus.py index b160c5b28..92f757399 100644 --- a/eos/effects/mwdsignatureradiusrolebonus.py +++ b/eos/effects/mwdsignatureradiusrolebonus.py @@ -2,7 +2,7 @@ # # Used by: # Ships from group: Assault Frigate (8 of 12) -# Ships from group: Heavy Assault Cruiser (8 of 11) +# Ships from group: Heavy Assault Cruiser (10 of 13) type = "passive" def handler(fit, ship, context): fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("High Speed Maneuvering"), diff --git a/eos/effects/overloadrofbonus.py b/eos/effects/overloadrofbonus.py index 5382e5f2c..4cfc38d2f 100644 --- a/eos/effects/overloadrofbonus.py +++ b/eos/effects/overloadrofbonus.py @@ -1,7 +1,7 @@ # overloadRofBonus # # Used by: -# Modules from group: Energy Weapon (100 of 186) +# Modules from group: Energy Weapon (100 of 187) # Modules from group: Hybrid Weapon (110 of 202) # Modules from group: Missile Launcher Citadel (4 of 4) # Modules from group: Missile Launcher Heavy (12 of 12) diff --git a/eos/effects/overloadselfdamagebonus.py b/eos/effects/overloadselfdamagebonus.py index 0e43c84c1..2e46fe1ec 100644 --- a/eos/effects/overloadselfdamagebonus.py +++ b/eos/effects/overloadselfdamagebonus.py @@ -1,7 +1,7 @@ # overloadSelfDamageBonus # # Used by: -# Modules from group: Energy Weapon (86 of 186) +# Modules from group: Energy Weapon (86 of 187) # Modules from group: Hybrid Weapon (92 of 202) # Modules from group: Projectile Weapon (86 of 146) type = "overheat" diff --git a/eos/effects/poweroutputmultiply.py b/eos/effects/poweroutputmultiply.py index e4f988ff8..e0ac4fe57 100644 --- a/eos/effects/poweroutputmultiply.py +++ b/eos/effects/poweroutputmultiply.py @@ -2,8 +2,8 @@ # # Used by: # Modules from group: Capacitor Flux Coil (6 of 6) -# Modules from group: Capacitor Power Relay (26 of 26) -# Modules from group: Power Diagnostic System (31 of 31) +# Modules from group: Capacitor Power Relay (20 of 20) +# Modules from group: Power Diagnostic System (23 of 23) # Modules from group: Reactor Control Unit (22 of 22) # Modules from group: Shield Flux Coil (11 of 11) # Modules from group: Shield Power Relay (11 of 11) diff --git a/eos/effects/probelaunchercpupercentbonustacticaldestroyer.py b/eos/effects/probelaunchercpupercentbonustacticaldestroyer.py index 1efb4913c..808c13098 100644 --- a/eos/effects/probelaunchercpupercentbonustacticaldestroyer.py +++ b/eos/effects/probelaunchercpupercentbonustacticaldestroyer.py @@ -1,7 +1,7 @@ # probeLauncherCPUPercentBonusTacticalDestroyer # # Used by: -# Ship: Confessor +# Ships from group: Tactical Destroyer (2 of 2) type = "passive" def handler(fit, ship, context): fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Astrometrics"), diff --git a/eos/effects/energytransferpowerneedbonuseffect.py b/eos/effects/remotecapacitortransmitterpowerneedbonuseffect.py similarity index 86% rename from eos/effects/energytransferpowerneedbonuseffect.py rename to eos/effects/remotecapacitortransmitterpowerneedbonuseffect.py index e40ba2002..b55a1c8b1 100644 --- a/eos/effects/energytransferpowerneedbonuseffect.py +++ b/eos/effects/remotecapacitortransmitterpowerneedbonuseffect.py @@ -1,4 +1,4 @@ -# energyTransferPowerNeedBonusEffect +# remoteCapacitorTransmitterPowerNeedBonusEffect # # Used by: # Ships from group: Logistics (3 of 5) diff --git a/eos/effects/scanstrengthbonuspercentactivate.py b/eos/effects/scanstrengthbonuspercentactivate.py index 46f606c35..7a652b614 100644 --- a/eos/effects/scanstrengthbonuspercentactivate.py +++ b/eos/effects/scanstrengthbonuspercentactivate.py @@ -5,7 +5,9 @@ # Module: QA ECCM type = "active" def handler(fit, module, context): - for type in ("Gravimetric", "Magnetometric", "Radar", "Ladar"): - fit.ship.boostItemAttr("scan%sStrength" % type, - module.getModifiedItemAttr("scan%sStrengthPercent" % type), - stackingPenalties = True) \ No newline at end of file + for scanType in ("Gravimetric", "Magnetometric", "Radar", "Ladar"): + fit.ship.boostItemAttr( + "scan{}Strength".format(scanType), + module.getModifiedItemAttr("scan{}StrengthPercent".format(scanType)), + stackingPenalties=True + ) diff --git a/eos/effects/shieldboostamplifier.py b/eos/effects/shieldboostamplifier.py index 164c39319..137df0af1 100644 --- a/eos/effects/shieldboostamplifier.py +++ b/eos/effects/shieldboostamplifier.py @@ -1,7 +1,7 @@ # shieldBoostAmplifier # # Used by: -# Modules from group: Capacitor Power Relay (26 of 26) +# Modules from group: Capacitor Power Relay (20 of 20) # Modules from group: Shield Boost Amplifier (25 of 25) type = "passive" def handler(fit, module, context): diff --git a/eos/effects/shieldcapacitymultiply.py b/eos/effects/shieldcapacitymultiply.py index 4f536da11..9cf482cc7 100644 --- a/eos/effects/shieldcapacitymultiply.py +++ b/eos/effects/shieldcapacitymultiply.py @@ -2,8 +2,8 @@ # # Used by: # Modules from group: Capacitor Flux Coil (6 of 6) -# Modules from group: Capacitor Power Relay (26 of 26) -# Modules from group: Power Diagnostic System (31 of 31) +# Modules from group: Capacitor Power Relay (20 of 20) +# Modules from group: Power Diagnostic System (23 of 23) # Modules from group: Reactor Control Unit (22 of 22) # Modules from group: Shield Flux Coil (11 of 11) # Modules from group: Shield Power Relay (11 of 11) diff --git a/eos/effects/shipbonusdronedamagemultipliergb2.py b/eos/effects/shipbonusdronedamagemultipliergb2.py index c65feca5a..80fe20844 100644 --- a/eos/effects/shipbonusdronedamagemultipliergb2.py +++ b/eos/effects/shipbonusdronedamagemultipliergb2.py @@ -2,6 +2,7 @@ # # Used by: # Variations of ship: Dominix (3 of 3) +# Ship: Dominix Quafe Edition # Ship: Nestor type = "passive" def handler(fit, ship, context): diff --git a/eos/effects/shipbonusdronedamagemultipliergc2.py b/eos/effects/shipbonusdronedamagemultipliergc2.py index 8c3aa4af0..dc87ee023 100644 --- a/eos/effects/shipbonusdronedamagemultipliergc2.py +++ b/eos/effects/shipbonusdronedamagemultipliergc2.py @@ -2,7 +2,7 @@ # # Used by: # Ships named like: Stratios (2 of 2) -# Variations of ship: Vexor (3 of 4) +# Ships named like: Vexor (3 of 4) type = "passive" def handler(fit, ship, context): level = fit.character.getSkill("Gallente Cruiser").level diff --git a/eos/effects/shipbonusdronehitpointsgb2.py b/eos/effects/shipbonusdronehitpointsgb2.py index 0a526d7e1..aa6c3958a 100644 --- a/eos/effects/shipbonusdronehitpointsgb2.py +++ b/eos/effects/shipbonusdronehitpointsgb2.py @@ -2,6 +2,7 @@ # # Used by: # Variations of ship: Dominix (3 of 3) +# Ship: Dominix Quafe Edition # Ship: Nestor type = "passive" def handler(fit, ship, context): diff --git a/eos/effects/shipbonusdronehitpointsgc2.py b/eos/effects/shipbonusdronehitpointsgc2.py index 5e36004ae..369566d00 100644 --- a/eos/effects/shipbonusdronehitpointsgc2.py +++ b/eos/effects/shipbonusdronehitpointsgc2.py @@ -2,7 +2,7 @@ # # Used by: # Ships named like: Stratios (2 of 2) -# Variations of ship: Vexor (3 of 4) +# Ships named like: Vexor (3 of 4) type = "passive" def handler(fit, ship, context): level = fit.character.getSkill("Gallente Cruiser").level diff --git a/eos/effects/shipbonusdronehitpointsgf.py b/eos/effects/shipbonusdronehitpointsgf.py index d1892d7c8..b5d838c4b 100644 --- a/eos/effects/shipbonusdronehitpointsgf.py +++ b/eos/effects/shipbonusdronehitpointsgf.py @@ -1,8 +1,8 @@ # shipBonusDroneHitpointsGF # # Used by: +# Ships named like: Tristan (2 of 2) # Ship: Astero -# Ship: Tristan type = "passive" def handler(fit, ship, context): level = fit.character.getSkill("Gallente Frigate").level diff --git a/eos/effects/shipbonusdroneminingamountgc2.py b/eos/effects/shipbonusdroneminingamountgc2.py index 60a66e282..643e7f522 100644 --- a/eos/effects/shipbonusdroneminingamountgc2.py +++ b/eos/effects/shipbonusdroneminingamountgc2.py @@ -1,8 +1,7 @@ # shipBonusDroneMiningAmountGC2 # # Used by: -# Ship: Vexor -# Ship: Vexor Navy Issue +# Ships named like: Vexor (3 of 4) type = "passive" def handler(fit, ship, context): level = fit.character.getSkill("Gallente Cruiser").level diff --git a/eos/effects/shipbonusdroneoptimalrangegb.py b/eos/effects/shipbonusdroneoptimalrangegb.py index 746b74c2a..c8e8f2346 100644 --- a/eos/effects/shipbonusdroneoptimalrangegb.py +++ b/eos/effects/shipbonusdroneoptimalrangegb.py @@ -2,6 +2,7 @@ # # Used by: # Ship: Dominix +# Ship: Dominix Quafe Edition type = "passive" def handler(fit, ship, context): level = fit.character.getSkill("Gallente Battleship").level diff --git a/eos/effects/shipbonusdronetrackinggb.py b/eos/effects/shipbonusdronetrackinggb.py index 192608c97..553479ae0 100644 --- a/eos/effects/shipbonusdronetrackinggb.py +++ b/eos/effects/shipbonusdronetrackinggb.py @@ -2,6 +2,7 @@ # # Used by: # Ship: Dominix +# Ship: Dominix Quafe Edition type = "passive" def handler(fit, ship, context): level = fit.character.getSkill("Gallente Battleship").level diff --git a/eos/effects/shipbonusdronetrackinggf.py b/eos/effects/shipbonusdronetrackinggf.py index 9f666dfe4..8e172b68b 100644 --- a/eos/effects/shipbonusdronetrackinggf.py +++ b/eos/effects/shipbonusdronetrackinggf.py @@ -1,7 +1,7 @@ # shipBonusDroneTrackingGF # # Used by: -# Ship: Tristan +# Ships named like: Tristan (2 of 2) type = "passive" def handler(fit, ship, context): level = fit.character.getSkill("Gallente Frigate").level diff --git a/eos/effects/shipbonusheavyassaultlauncherrateoffirecc2.py b/eos/effects/shipbonusheavyassaultlauncherrateoffirecc2.py deleted file mode 100644 index 7edf68e60..000000000 --- a/eos/effects/shipbonusheavyassaultlauncherrateoffirecc2.py +++ /dev/null @@ -1,9 +0,0 @@ -# shipBonusHeavyAssaultLauncherRateOfFireCC2 -# -# Used by: -# Ship: Rook -type = "passive" -def handler(fit, ship, context): - level = fit.character.getSkill("Caldari Cruiser").level - fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Missile Launcher Heavy Assault", - "speed", ship.getModifiedItemAttr("shipBonusCC2") * level) diff --git a/eos/effects/shipbonusheavydronearmorhpgc2.py b/eos/effects/shipbonusheavydronearmorhpgc2.py new file mode 100644 index 000000000..55a3a9339 --- /dev/null +++ b/eos/effects/shipbonusheavydronearmorhpgc2.py @@ -0,0 +1,9 @@ +# shipBonusHeavyDroneArmorHPGC2 +# +# Used by: +# Ship: Ishtar +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Gallente Cruiser").level + fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Heavy Drone Operation"), + "armorHP", ship.getModifiedItemAttr("shipBonusGC2") * level) diff --git a/eos/effects/shipbonusheavydronedamagemultipliergc2.py b/eos/effects/shipbonusheavydronedamagemultipliergc2.py new file mode 100644 index 000000000..ac7e9ec08 --- /dev/null +++ b/eos/effects/shipbonusheavydronedamagemultipliergc2.py @@ -0,0 +1,9 @@ +# shipBonusHeavyDroneDamageMultiplierGC2 +# +# Used by: +# Ship: Ishtar +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Gallente Cruiser").level + fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Heavy Drone Operation"), + "damageMultiplier", ship.getModifiedItemAttr("shipBonusGC2") * level) diff --git a/eos/effects/shipbonusheavydronehpgc2.py b/eos/effects/shipbonusheavydronehpgc2.py new file mode 100644 index 000000000..6e5a858eb --- /dev/null +++ b/eos/effects/shipbonusheavydronehpgc2.py @@ -0,0 +1,9 @@ +# shipBonusHeavyDroneHPGC2 +# +# Used by: +# Ship: Ishtar +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Gallente Cruiser").level + fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Heavy Drone Operation"), + "hp", ship.getModifiedItemAttr("shipBonusGC2") * level) diff --git a/eos/effects/shipbonusheavydroneshieldhpgc2.py b/eos/effects/shipbonusheavydroneshieldhpgc2.py new file mode 100644 index 000000000..66e33b8a9 --- /dev/null +++ b/eos/effects/shipbonusheavydroneshieldhpgc2.py @@ -0,0 +1,9 @@ +# shipBonusHeavyDroneShieldHPGC2 +# +# Used by: +# Ship: Ishtar +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Gallente Cruiser").level + fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Heavy Drone Operation"), + "shieldCapacity", ship.getModifiedItemAttr("shipBonusGC2") * level) diff --git a/eos/effects/shipbonusheavylauncherrateoffirecc2.py b/eos/effects/shipbonusheavylauncherrateoffirecc2.py deleted file mode 100644 index 5ca8c9393..000000000 --- a/eos/effects/shipbonusheavylauncherrateoffirecc2.py +++ /dev/null @@ -1,9 +0,0 @@ -# shipBonusHeavyLauncherRateOfFireCC2 -# -# Used by: -# Ship: Rook -type = "passive" -def handler(fit, ship, context): - level = fit.character.getSkill("Caldari Cruiser").level - fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Missile Launcher Heavy", - "speed", ship.getModifiedItemAttr("shipBonusCC2") * level) diff --git a/eos/effects/shipbonushybridtrackinggf2.py b/eos/effects/shipbonushybridtrackinggf2.py index e0aabdeba..d50ab59b4 100644 --- a/eos/effects/shipbonushybridtrackinggf2.py +++ b/eos/effects/shipbonushybridtrackinggf2.py @@ -1,10 +1,10 @@ # shipBonusHybridTrackingGF2 # # Used by: +# Ships named like: Tristan (2 of 2) # Ship: Ares # Ship: Federation Navy Comet # Ship: Police Pursuit Comet -# Ship: Tristan type = "passive" def handler(fit, ship, context): level = fit.character.getSkill("Gallente Frigate").level diff --git a/eos/effects/shipbonuslightdronearmorhpgc2.py b/eos/effects/shipbonuslightdronearmorhpgc2.py new file mode 100644 index 000000000..99c1aa07f --- /dev/null +++ b/eos/effects/shipbonuslightdronearmorhpgc2.py @@ -0,0 +1,9 @@ +# shipBonusLightDroneArmorHPGC2 +# +# Used by: +# Ship: Ishtar +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Gallente Cruiser").level + fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Light Drone Operation"), + "armorHP", ship.getModifiedItemAttr("shipBonusGC2") * level) \ No newline at end of file diff --git a/eos/effects/shipbonuslightdronedamagemultipliergc2.py b/eos/effects/shipbonuslightdronedamagemultipliergc2.py new file mode 100644 index 000000000..104b7f5a1 --- /dev/null +++ b/eos/effects/shipbonuslightdronedamagemultipliergc2.py @@ -0,0 +1,9 @@ +# shipBonusLightDroneDamageMultiplierGC2 +# +# Used by: +# Ship: Ishtar +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Gallente Cruiser").level + fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Light Drone Operation"), + "damageMultiplier", ship.getModifiedItemAttr("shipBonusGC2") * level) diff --git a/eos/effects/shipbonuslightdronehpgc2.py b/eos/effects/shipbonuslightdronehpgc2.py new file mode 100644 index 000000000..7a9328b1e --- /dev/null +++ b/eos/effects/shipbonuslightdronehpgc2.py @@ -0,0 +1,9 @@ +# shipBonusLightDroneHPGC2 +# +# Used by: +# Ship: Ishtar +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Gallente Cruiser").level + fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Light Drone Operation"), + "hp", ship.getModifiedItemAttr("shipBonusGC2") * level) diff --git a/eos/effects/shipbonuslightdroneshieldhpgc2.py b/eos/effects/shipbonuslightdroneshieldhpgc2.py new file mode 100644 index 000000000..d6b6dd492 --- /dev/null +++ b/eos/effects/shipbonuslightdroneshieldhpgc2.py @@ -0,0 +1,9 @@ +# shipBonusLightDroneShieldHPGC2 +# +# Used by: +# Ship: Ishtar +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Gallente Cruiser").level + fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Light Drone Operation"), + "shieldCapacity", ship.getModifiedItemAttr("shipBonusGC2") * level) diff --git a/eos/effects/shipbonusmediumdronearmorhpgc2.py b/eos/effects/shipbonusmediumdronearmorhpgc2.py new file mode 100644 index 000000000..2439abe96 --- /dev/null +++ b/eos/effects/shipbonusmediumdronearmorhpgc2.py @@ -0,0 +1,9 @@ +# shipBonusMediumDroneArmorHPGC2 +# +# Used by: +# Ship: Ishtar +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Gallente Cruiser").level + fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Medium Drone Operation"), + "armorHP", ship.getModifiedItemAttr("shipBonusGC2") * level) diff --git a/eos/effects/shipbonusmediumdronedamagemultipliergc2.py b/eos/effects/shipbonusmediumdronedamagemultipliergc2.py new file mode 100644 index 000000000..b5d2da3bf --- /dev/null +++ b/eos/effects/shipbonusmediumdronedamagemultipliergc2.py @@ -0,0 +1,9 @@ +# shipBonusMediumDroneDamageMultiplierGC2 +# +# Used by: +# Ship: Ishtar +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Gallente Cruiser").level + fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Medium Drone Operation"), + "damageMultiplier", ship.getModifiedItemAttr("shipBonusGC2") * level) diff --git a/eos/effects/shipbonusmediumdronehpgc2.py b/eos/effects/shipbonusmediumdronehpgc2.py new file mode 100644 index 000000000..74644acb0 --- /dev/null +++ b/eos/effects/shipbonusmediumdronehpgc2.py @@ -0,0 +1,9 @@ +# shipBonusMediumDroneHPGC2 +# +# Used by: +# Ship: Ishtar +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Gallente Cruiser").level + fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Medium Drone Operation"), + "hp", ship.getModifiedItemAttr("shipBonusGC2") * level) diff --git a/eos/effects/shipbonusmediumdroneshieldhpgc2.py b/eos/effects/shipbonusmediumdroneshieldhpgc2.py new file mode 100644 index 000000000..210cc6eb8 --- /dev/null +++ b/eos/effects/shipbonusmediumdroneshieldhpgc2.py @@ -0,0 +1,9 @@ +# shipBonusMediumDroneShieldHPGC2 +# +# Used by: +# Ship: Ishtar +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Gallente Cruiser").level + fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Medium Drone Operation"), + "shieldCapacity", ship.getModifiedItemAttr("shipBonusGC2") * level) diff --git a/eos/effects/shipbonussentryarmorhpgc3.py b/eos/effects/shipbonussentryarmorhpgc3.py new file mode 100644 index 000000000..80dc34d01 --- /dev/null +++ b/eos/effects/shipbonussentryarmorhpgc3.py @@ -0,0 +1,9 @@ +# shipBonusSentryArmorHPGC3 +# +# Used by: +# Ship: Ishtar +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Gallente Cruiser").level + fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Sentry Drone Interfacing"), + "armorHP", ship.getModifiedItemAttr("shipBonusGC3") * level) diff --git a/eos/effects/shipbonussentrydamagemultipliergc3.py b/eos/effects/shipbonussentrydamagemultipliergc3.py new file mode 100644 index 000000000..73987a70b --- /dev/null +++ b/eos/effects/shipbonussentrydamagemultipliergc3.py @@ -0,0 +1,9 @@ +# shipBonusSentryDamageMultiplierGC3 +# +# Used by: +# Ship: Ishtar +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Gallente Cruiser").level + fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Sentry Drone Interfacing"), + "damageMultiplier", ship.getModifiedItemAttr("shipBonusGC3") * level) diff --git a/eos/effects/shipbonussentryhpgc3.py b/eos/effects/shipbonussentryhpgc3.py new file mode 100644 index 000000000..633c8267e --- /dev/null +++ b/eos/effects/shipbonussentryhpgc3.py @@ -0,0 +1,9 @@ +# shipBonusSentryHPGC3 +# +# Used by: +# Ship: Ishtar +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Gallente Cruiser").level + fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Sentry Drone Interfacing"), + "hp", ship.getModifiedItemAttr("shipBonusGC3") * level) diff --git a/eos/effects/shipbonussentryshieldhpgc3.py b/eos/effects/shipbonussentryshieldhpgc3.py new file mode 100644 index 000000000..64bb46455 --- /dev/null +++ b/eos/effects/shipbonussentryshieldhpgc3.py @@ -0,0 +1,9 @@ +# shipBonusSentryShieldHPGC3 +# +# Used by: +# Ship: Ishtar +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Gallente Cruiser").level + fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Sentry Drone Interfacing"), + "shieldCapacity", ship.getModifiedItemAttr("shipBonusGC3") * level) diff --git a/eos/effects/shipbonusthermalmissiledamagegc2.py b/eos/effects/shipbonusthermalmissiledamagegc2.py index 05e602e20..19fefc9c7 100644 --- a/eos/effects/shipbonusthermalmissiledamagegc2.py +++ b/eos/effects/shipbonusthermalmissiledamagegc2.py @@ -3,6 +3,7 @@ # Used by: # Ship: Chameleon # Ship: Gila + type = "passive" def handler(fit, ship, context): level = fit.character.getSkill("Gallente Cruiser").level diff --git a/eos/effects/shipheatdamageminmatartacticaldestroyer3.py b/eos/effects/shipheatdamageminmatartacticaldestroyer3.py new file mode 100644 index 000000000..13607c1fa --- /dev/null +++ b/eos/effects/shipheatdamageminmatartacticaldestroyer3.py @@ -0,0 +1,9 @@ +# shipHeatDamageMinmatarTacticalDestroyer3 +# +# Used by: +# Ship: Svipul +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Minmatar Tactical Destroyer").level + fit.modules.filteredItemBoost(lambda mod: True, "heatDamage", + ship.getModifiedItemAttr("shipBonusTacticalDestroyerMinmatar3") * level) diff --git a/eos/effects/shiphtdmgbonusfixedgc.py b/eos/effects/shiphtdmgbonusfixedgc.py index c0fac0f09..33ad961e3 100644 --- a/eos/effects/shiphtdmgbonusfixedgc.py +++ b/eos/effects/shiphtdmgbonusfixedgc.py @@ -2,13 +2,11 @@ # # Used by: # Ships named like: Thorax (3 of 3) +# Ships named like: Vexor (3 of 4) # Ship: Adrestia # Ship: Arazu # Ship: Deimos # Ship: Exequror Navy Issue -# Ship: Guardian-Vexor -# Ship: Lachesis -# Ship: Vexor type = "passive" def handler(fit, ship, context): level = fit.character.getSkill("Gallente Cruiser").level diff --git a/eos/effects/shiphybridtrackinggc.py b/eos/effects/shiphybridtrackinggc.py index f99cea0b0..02215246a 100644 --- a/eos/effects/shiphybridtrackinggc.py +++ b/eos/effects/shiphybridtrackinggc.py @@ -1,6 +1,7 @@ # shipHybridTrackingGC # # Used by: +# Ship: Lachesis # Ship: Phobos type = "passive" def handler(fit, ship, context): diff --git a/eos/effects/shipmissilebonusemdmgmc.py b/eos/effects/shipmissilebonusemdmgmc.py new file mode 100644 index 000000000..1230c3f94 --- /dev/null +++ b/eos/effects/shipmissilebonusemdmgmc.py @@ -0,0 +1,9 @@ +# shipMissileBonusEMdmgMC +# +# Used by: +# Ship: Rapier +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Minmatar Cruiser").level + fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"), + "emDamage", ship.getModifiedItemAttr("shipBonusMC") * level) diff --git a/eos/effects/shipmissilebonusexpdmgmc.py b/eos/effects/shipmissilebonusexpdmgmc.py new file mode 100644 index 000000000..cdaa2637d --- /dev/null +++ b/eos/effects/shipmissilebonusexpdmgmc.py @@ -0,0 +1,9 @@ +# shipMissileBonusExpdmgMC +# +# Used by: +# Ship: Rapier +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Minmatar Cruiser").level + fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"), + "explosiveDamage", ship.getModifiedItemAttr("shipBonusMC") * level) diff --git a/eos/effects/shipmissilebonuskindmgmc.py b/eos/effects/shipmissilebonuskindmgmc.py new file mode 100644 index 000000000..c4173ca36 --- /dev/null +++ b/eos/effects/shipmissilebonuskindmgmc.py @@ -0,0 +1,9 @@ +# shipMissileBonusKindmgMC +# +# Used by: +# Ship: Rapier +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Minmatar Cruiser").level + fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"), + "kineticDamage", ship.getModifiedItemAttr("shipBonusMC") * level) diff --git a/eos/effects/shipmissilebonusthermdmgmc.py b/eos/effects/shipmissilebonusthermdmgmc.py new file mode 100644 index 000000000..90a8c3daa --- /dev/null +++ b/eos/effects/shipmissilebonusthermdmgmc.py @@ -0,0 +1,9 @@ +# shipMissileBonusThermdmgMC +# +# Used by: +# Ship: Rapier +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Minmatar Cruiser").level + fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"), + "thermalDamage", ship.getModifiedItemAttr("shipBonusMC") * level) diff --git a/eos/effects/shipmissilekindamagecc2.py b/eos/effects/shipmissilekindamagecc2.py index eee63477c..97ff60cc1 100644 --- a/eos/effects/shipmissilekindamagecc2.py +++ b/eos/effects/shipmissilekindamagecc2.py @@ -2,6 +2,7 @@ # # Used by: # Ship: Osprey Navy Issue +# Ship: Rook type = "passive" def handler(fit, ship, context): level = fit.character.getSkill("Caldari Cruiser").level diff --git a/eos/effects/shipmodemaxtargetrangepostdiv.py b/eos/effects/shipmodemaxtargetrangepostdiv.py index d9cb50254..573574fe7 100644 --- a/eos/effects/shipmodemaxtargetrangepostdiv.py +++ b/eos/effects/shipmodemaxtargetrangepostdiv.py @@ -1,8 +1,12 @@ # shipModeMaxTargetRangePostDiv # # Used by: -# Module: Amarr Tactical Destroyer Sharpshooter Mode +# Modules named like: Sharpshooter Mode (2 of 2) type = "passive" def handler(fit, module, context): - fit.ship.multiplyItemAttr("maxTargetRange", 1/module.getModifiedItemAttr("modeMaxTargetRangePostDiv"), - stackingPenalties = True, penaltyGroup="postDiv") + fit.ship.multiplyItemAttr( + "maxTargetRange", + 1 / module.getModifiedItemAttr("modeMaxTargetRangePostDiv"), + stackingPenalties=True, + penaltyGroup="postDiv" + ) diff --git a/eos/effects/shipmodescanrespostdiv.py b/eos/effects/shipmodescanrespostdiv.py index 07db84ad5..f418fa328 100644 --- a/eos/effects/shipmodescanrespostdiv.py +++ b/eos/effects/shipmodescanrespostdiv.py @@ -1,8 +1,12 @@ # shipModeScanResPostDiv # # Used by: -# Module: Amarr Tactical Destroyer Sharpshooter Mode +# Modules named like: Sharpshooter Mode (2 of 2) type = "passive" def handler(fit, module, context): - fit.ship.multiplyItemAttr("scanResolution", 1/module.getModifiedItemAttr("modeScanResPostDiv"), - stackingPenalties = True, penaltyGroup="postDiv") + fit.ship.multiplyItemAttr( + "scanResolution", + 1 / module.getModifiedItemAttr("modeScanResPostDiv"), + stackingPenalties=True, + penaltyGroup="postDiv" + ) diff --git a/eos/effects/shipmodescanstrengthpostdiv.py b/eos/effects/shipmodescanstrengthpostdiv.py index cdf2b20f3..e42d5f69c 100644 --- a/eos/effects/shipmodescanstrengthpostdiv.py +++ b/eos/effects/shipmodescanstrengthpostdiv.py @@ -1,8 +1,13 @@ # shipModeScanStrengthPostDiv # # Used by: -# Module: Amarr Tactical Destroyer Sharpshooter Mode +# Modules named like: Sharpshooter Mode (2 of 2) type = "passive" def handler(fit, module, context): - fit.ship.multiplyItemAttr("scanRadarStrength", 1/module.getModifiedItemAttr("modeRadarStrengthPostDiv"), - stackingPenalties = True, penaltyGroup="postDiv") + for scanType in ("Gravimetric", "Magnetometric", "Radar", "Ladar"): + fit.ship.multiplyItemAttr( + "scan{}Strength".format(scanType), + 1 / (module.getModifiedItemAttr("mode{}StrengthPostDiv".format(scanType)) or 1), + stackingPenalties=True, + penaltyGroup="postDiv" + ) diff --git a/eos/effects/shipmodesetoptimalrangepostdiv.py b/eos/effects/shipmodesetoptimalrangepostdiv.py index bafceea86..a4aadbee8 100644 --- a/eos/effects/shipmodesetoptimalrangepostdiv.py +++ b/eos/effects/shipmodesetoptimalrangepostdiv.py @@ -1,9 +1,13 @@ # shipModeSETOptimalRangePostDiv # # Used by: -# Module: Amarr Tactical Destroyer Sharpshooter Mode +# Module: Confessor Sharpshooter Mode type = "passive" def handler(fit, module, context): - fit.modules.filteredItemMultiply(lambda mod: mod.item.requiresSkill("Small Energy Turret"), - "maxRange", 1/module.getModifiedItemAttr("modeMaxRangePostDiv"), - stackingPenalties=True, penaltyGroup="postDiv") + fit.modules.filteredItemMultiply( + lambda mod: mod.item.requiresSkill("Small Energy Turret"), + "maxRange", + 1 / module.getModifiedItemAttr("modeMaxRangePostDiv"), + stackingPenalties=True, + penaltyGroup="postDiv" + ) diff --git a/eos/effects/shipmodespttrackingpostdiv.py b/eos/effects/shipmodespttrackingpostdiv.py new file mode 100644 index 000000000..40c5cdaeb --- /dev/null +++ b/eos/effects/shipmodespttrackingpostdiv.py @@ -0,0 +1,13 @@ +# shipModeSPTTrackingPostDiv +# +# Used by: +# Module: Svipul Sharpshooter Mode +type = "passive" +def handler(fit, module, context): + fit.modules.filteredItemMultiply( + lambda mod: mod.item.requiresSkill("Small Projectile Turret"), + "trackingSpeed", + 1 / module.getModifiedItemAttr("modeTrackingPostDiv"), + stackingPenalties=True, + penaltyGroup="postDiv" + ) diff --git a/eos/effects/shippturretfalloffbonusgb.py b/eos/effects/shippturretfalloffbonusgb.py index 7088999a4..4286e1bd6 100644 --- a/eos/effects/shippturretfalloffbonusgb.py +++ b/eos/effects/shippturretfalloffbonusgb.py @@ -6,4 +6,4 @@ type = "passive" def handler(fit, ship, context): level = fit.character.getSkill("Gallente Battleship").level fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Large Projectile Turret"), - "falloff", ship.getModifiedItemAttr("shipBonusGB") * level) \ No newline at end of file + "falloff", ship.getModifiedItemAttr("shipBonusGB") * level) diff --git a/eos/effects/shippturretspeedbonusmc.py b/eos/effects/shippturretspeedbonusmc.py index 6a5ad4d5b..c561afc47 100644 --- a/eos/effects/shippturretspeedbonusmc.py +++ b/eos/effects/shippturretspeedbonusmc.py @@ -5,7 +5,6 @@ # Variations of ship: Rupture (3 of 3) # Variations of ship: Stabber (3 of 3) # Ship: Huginn -# Ship: Rapier # Ship: Scythe Fleet Issue type = "passive" def handler(fit, ship, context): diff --git a/eos/effects/shipsptdamageminmatartacticaldestroyer1.py b/eos/effects/shipsptdamageminmatartacticaldestroyer1.py new file mode 100644 index 000000000..349767adf --- /dev/null +++ b/eos/effects/shipsptdamageminmatartacticaldestroyer1.py @@ -0,0 +1,9 @@ +# shipSPTDamageMinmatarTacticalDestroyer1 +# +# Used by: +# Ship: Svipul +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Minmatar Tactical Destroyer").level + fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Small Projectile Turret"), + "damageMultiplier", ship.getModifiedItemAttr("shipBonusTacticalDestroyerMinmatar1") * level) diff --git a/eos/effects/shipsptoptimalminmatartacticaldestroyer2.py b/eos/effects/shipsptoptimalminmatartacticaldestroyer2.py new file mode 100644 index 000000000..da0ff3d12 --- /dev/null +++ b/eos/effects/shipsptoptimalminmatartacticaldestroyer2.py @@ -0,0 +1,9 @@ +# shipSPTOptimalMinmatarTacticalDestroyer2 +# +# Used by: +# Ship: Svipul +type = "passive" +def handler(fit, ship, context): + level = fit.character.getSkill("Minmatar Tactical Destroyer").level + fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Small Projectile Turret"), + "maxRange", ship.getModifiedItemAttr("shipBonusTacticalDestroyerMinmatar2") * level) diff --git a/eos/effects/structurehpmultiply.py b/eos/effects/structurehpmultiply.py index 502d67636..aa7d43c7c 100644 --- a/eos/effects/structurehpmultiply.py +++ b/eos/effects/structurehpmultiply.py @@ -1,8 +1,8 @@ # structureHPMultiply # # Used by: -# Modules from group: Nanofiber Internal Structure (14 of 14) -# Modules from group: Reinforced Bulkhead (12 of 12) +# Modules from group: Nanofiber Internal Structure (7 of 7) +# Modules from group: Reinforced Bulkhead (8 of 8) # Modules named like: QA Multiship Module Players (4 of 4) type = "passive" def handler(fit, module, context): diff --git a/eos/effects/structurehpmultiplypassive.py b/eos/effects/structurehpmultiplypassive.py index 60159c104..89ab600df 100644 --- a/eos/effects/structurehpmultiplypassive.py +++ b/eos/effects/structurehpmultiplypassive.py @@ -1,7 +1,7 @@ # structureHPMultiplyPassive # # Used by: -# Modules from group: Expanded Cargohold (13 of 13) +# Modules from group: Expanded Cargohold (7 of 7) type = "passive" def handler(fit, module, context): fit.ship.multiplyItemAttr("hp", module.getModifiedItemAttr("structureHPMultiplier")) \ No newline at end of file diff --git a/eos/effects/subsystembonuscaldaridefensiveshieldrechargerate.py b/eos/effects/subsystembonuscaldaridefensiveshieldrechargerate.py new file mode 100644 index 000000000..7c63b3a27 --- /dev/null +++ b/eos/effects/subsystembonuscaldaridefensiveshieldrechargerate.py @@ -0,0 +1,8 @@ +# subsystemBonusCaldariDefensiveShieldRechargeRate +# +# Used by: +# Subsystem: Tengu Defensive - Supplemental Screening +type = "passive" +def handler(fit, module, context): + level = fit.character.getSkill("Caldari Defensive Systems").level + fit.ship.boostItemAttr("shieldRechargeRate", module.getModifiedItemAttr("subsystemBonusCaldariDefensive2") * level) diff --git a/eos/effects/targetattack.py b/eos/effects/targetattack.py index 3403c880b..3fafbf2fa 100644 --- a/eos/effects/targetattack.py +++ b/eos/effects/targetattack.py @@ -3,7 +3,7 @@ # Used by: # Drones from group: Combat Drone (74 of 74) # Drones from group: Fighter Drone (4 of 4) -# Modules from group: Energy Weapon (186 of 186) +# Modules from group: Energy Weapon (186 of 187) type = 'active' def handler(fit, module, context): # Set reload time to 1 second diff --git a/eos/effects/velocitybonusonline.py b/eos/effects/velocitybonusonline.py index ef6a5e458..1af6d4411 100644 --- a/eos/effects/velocitybonusonline.py +++ b/eos/effects/velocitybonusonline.py @@ -1,8 +1,8 @@ # velocityBonusOnline # # Used by: -# Modules from group: Nanofiber Internal Structure (14 of 14) -# Modules from group: Overdrive Injector System (14 of 14) +# Modules from group: Nanofiber Internal Structure (7 of 7) +# Modules from group: Overdrive Injector System (7 of 7) type = "passive" def handler(fit, module, context): fit.ship.boostItemAttr("maxVelocity", module.getModifiedItemAttr("implantBonusVelocity"), diff --git a/eos/gamedata.py b/eos/gamedata.py index 8c1fc1df2..d5691da46 100644 --- a/eos/gamedata.py +++ b/eos/gamedata.py @@ -120,7 +120,12 @@ class Effect(EqBase): ''' try: self.__effectModule = effectModule = __import__('eos.effects.' + self.handlerName, fromlist=True) - self.__handler = getattr(effectModule, "handler") + try: + self.__handler = getattr(effectModule, "handler") + except AttributeError: + print "effect {} exists, but no handler".format(self.handlerName) + raise + try: self.__runTime = getattr(effectModule, "runTime") or "normal" except AttributeError: @@ -133,7 +138,7 @@ class Effect(EqBase): t = t if isinstance(t, tuple) or t is None else (t,) self.__type = t - except ImportError as e: + except (ImportError, AttributeError) as e: self.__handler = effectDummy self.__runTime = "normal" self.__type = None diff --git a/eos/saveddata/fit.py b/eos/saveddata/fit.py index 484e314fe..f49c1f60e 100644 --- a/eos/saveddata/fit.py +++ b/eos/saveddata/fit.py @@ -406,12 +406,14 @@ class Fit(object): (effect.isType("active") and thing.state >= State.ACTIVE): # Run effect, and get proper bonuses applied try: + self.register(thing) effect.handler(self, thing, context) except: pass else: # Run effect, and get proper bonuses applied try: + self.register(thing) effect.handler(self, thing, context) except: pass @@ -735,7 +737,7 @@ class Fit(object): capAdded = 0 for mod in self.modules: if mod.state >= State.ACTIVE: - if mod.getModifiedItemAttr("capacitorNeed") != 0: + if (mod.getModifiedItemAttr("capacitorNeed") or 0) != 0: cycleTime = mod.rawCycleTime or 0 reactivationTime = mod.getModifiedItemAttr("moduleReactivationDelay") or 0 fullCycleTime = cycleTime + reactivationTime diff --git a/gpl.txt b/gpl.txt index 5737cfa27..94a9ed024 100644 --- a/gpl.txt +++ b/gpl.txt @@ -549,14 +549,14 @@ to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. - 13. Use with the GNU General Public License. + 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed -under version 3 of the GNU General Public License into a single +under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, -but the special requirements of the GNU General Public License, +but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. diff --git a/gui/builtinContextMenus/damagePattern.py b/gui/builtinContextMenus/damagePattern.py index 352340204..29a029389 100644 --- a/gui/builtinContextMenus/damagePattern.py +++ b/gui/builtinContextMenus/damagePattern.py @@ -24,7 +24,7 @@ class DamagePattern(ContextMenu): self.fit = sFit.getFit(fitID) self.patterns = sDP.getDamagePatternList() - self.patterns.sort(key=lambda p: (p.name not in ["Uniform","Selected Ammo"], p.name)) + self.patterns.sort(key=lambda p: (p.name not in ["Uniform", "Selected Ammo"], p.name)) self.patternIds = {} self.subMenus = OrderedDict() @@ -71,7 +71,6 @@ class DamagePattern(ContextMenu): def getSubMenu(self, context, selection, rootMenu, i, pitem): msw = True if "wxMSW" in wx.PlatformInfo else False - rootMenu.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, @@ -79,10 +78,11 @@ class DamagePattern(ContextMenu): # our patternIds mapping, then return None for no submenu id = pitem.GetId() self.patternIds[id] = self.singles[i] + rootMenu.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 + return False sub = wx.Menu() diff --git a/gui/builtinPreferenceViews/pyfaGeneralPreferences.py b/gui/builtinPreferenceViews/pyfaGeneralPreferences.py index 98190fcde..60468ec9a 100644 --- a/gui/builtinPreferenceViews/pyfaGeneralPreferences.py +++ b/gui/builtinPreferenceViews/pyfaGeneralPreferences.py @@ -53,6 +53,9 @@ class PFGeneralPref ( PreferenceView): labelSizer.Add( self.cbRackLabels, 0, wx.ALL|wx.EXPAND, 5 ) mainSizer.Add( labelSizer, 0, wx.LEFT|wx.EXPAND, 30 ) + self.cbShowTooltip = wx.CheckBox( panel, wx.ID_ANY, u"Show tab tooltips", wx.DefaultPosition, wx.DefaultSize, 0 ) + mainSizer.Add( self.cbShowTooltip, 0, wx.ALL|wx.EXPAND, 5 ) + defCharSizer = wx.BoxSizer( wx.HORIZONTAL ) self.sFit = service.Fit.getInstance() @@ -65,6 +68,7 @@ class PFGeneralPref ( PreferenceView): self.cbRackLabels.SetValue(self.sFit.serviceFittingOptions["rackLabels"] or False) self.cbCompactSkills.SetValue(self.sFit.serviceFittingOptions["compactSkills"] or False) self.cbReopenFits.SetValue(self.openFitsSettings["enabled"]) + self.cbShowTooltip.SetValue(self.sFit.serviceFittingOptions["showTooltip"] or False) self.cbGlobalChar.Bind(wx.EVT_CHECKBOX, self.OnCBGlobalCharStateChange) self.cbGlobalDmgPattern.Bind(wx.EVT_CHECKBOX, self.OnCBGlobalDmgPatternStateChange) @@ -74,6 +78,7 @@ class PFGeneralPref ( PreferenceView): self.cbRackLabels.Bind(wx.EVT_CHECKBOX, self.onCBGlobalRackLabels) self.cbCompactSkills.Bind(wx.EVT_CHECKBOX, self.onCBCompactSkills) self.cbReopenFits.Bind(wx.EVT_CHECKBOX, self.onCBReopenFits) + self.cbShowTooltip.Bind(wx.EVT_CHECKBOX, self.onCBShowTooltip) self.cbRackLabels.Enable(self.sFit.serviceFittingOptions["rackSlots"] or False) @@ -127,6 +132,9 @@ class PFGeneralPref ( PreferenceView): def onCBReopenFits(self, event): self.openFitsSettings["enabled"] = self.cbReopenFits.GetValue() + def onCBShowTooltip(self, event): + self.sFit.serviceFittingOptions["showTooltip"] = self.cbShowTooltip.GetValue() + def getImage(self): return bitmapLoader.getBitmap("prefs_settings", "icons") diff --git a/gui/builtinStatsViews/firepowerViewFull.py b/gui/builtinStatsViews/firepowerViewFull.py index e6e1df75a..a7180252e 100644 --- a/gui/builtinStatsViews/firepowerViewFull.py +++ b/gui/builtinStatsViews/firepowerViewFull.py @@ -43,12 +43,10 @@ class FirepowerViewFull(StatsView): 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) + hsizer = self.headerPanel.GetSizer() + self.stEff = wx.StaticText(self.headerPanel, wx.ID_ANY, "( Effective )") + hsizer.Add(self.stEff) + self.headerPanel.GetParent().AddToggleItem(self.stEff) panel = "full" @@ -59,7 +57,7 @@ class FirepowerViewFull(StatsView): counter = 0 - for damageType, image in (("weapon", "turret") , ("drone", "droneDPS")): + for damageType, image in (("weapon", "turret"), ("drone", "droneDPS")): baseBox = wx.BoxSizer(wx.HORIZONTAL) sizerFirepower.Add(baseBox, 1, wx.ALIGN_LEFT if counter == 0 else wx.ALIGN_CENTER_HORIZONTAL) @@ -124,6 +122,12 @@ class FirepowerViewFull(StatsView): # And no longer display us self.panel.GetSizer().Clear(True) self.panel.GetSizer().Layout() + + # Remove effective label + hsizer = self.headerPanel.GetSizer() + hsizer.Remove(self.stEff) + self.stEff.Destroy() + # Get the new view view = StatsView.getView("miningyieldViewFull")(self.parent) view.populatePanel(self.panel, self.headerPanel) diff --git a/gui/builtinViewColumns/ammo.py b/gui/builtinViewColumns/ammo.py index cb3234ccc..fe50c6fbd 100644 --- a/gui/builtinViewColumns/ammo.py +++ b/gui/builtinViewColumns/ammo.py @@ -42,7 +42,6 @@ class Ammo(ViewColumn): return text - def getImageId(self, mod): return -1 diff --git a/gui/builtinViewColumns/ammoIcon.py b/gui/builtinViewColumns/ammoIcon.py index b712ec435..19d55364e 100644 --- a/gui/builtinViewColumns/ammoIcon.py +++ b/gui/builtinViewColumns/ammoIcon.py @@ -48,4 +48,8 @@ class AmmoIcon(ViewColumn): else: return -1 + def getToolTip(self, mod): + if isinstance(mod, Module) and mod.charge is not None: + return mod.charge.name + AmmoIcon.register() diff --git a/gui/builtinViewColumns/attributeDisplay.py b/gui/builtinViewColumns/attributeDisplay.py index a55a50407..86966574b 100644 --- a/gui/builtinViewColumns/attributeDisplay.py +++ b/gui/builtinViewColumns/attributeDisplay.py @@ -89,6 +89,12 @@ class AttributeDisplay(ViewColumn): def getImageId(self, mod): return -1 + def getToolTip(self, stuff): + if self.info.name == "cpu": + return "CPU" + else: + return self.info.name.title() + @staticmethod def getParameters(): return (("attribute", str, None), diff --git a/gui/builtinViewColumns/capacitorUse.py b/gui/builtinViewColumns/capacitorUse.py index 9e4916f2b..497869a66 100644 --- a/gui/builtinViewColumns/capacitorUse.py +++ b/gui/builtinViewColumns/capacitorUse.py @@ -34,9 +34,8 @@ class CapacitorUse(ViewColumn): sAttr = service.Attribute.getInstance() info = sAttr.getAttributeInfo("capacitorNeed") - self.imageId = fittingView.imageList.GetImageIndex(info.icon.iconFile, "pack") - self.bitmap = bitmapLoader.getBitmap(info.icon.iconFile, "pack") - + self.imageId = fittingView.imageList.GetImageIndex("capacitorRecharge_small", "icons") + self.bitmap = bitmapLoader.getBitmap("capacitorRecharge_small", "icons") def getText(self, mod): if isinstance(mod, Mode): @@ -51,4 +50,7 @@ class CapacitorUse(ViewColumn): def getImageId(self, mod): return -1 + def getToolTip(self, mod): + return self.name + CapacitorUse.register() diff --git a/gui/builtinViewColumns/maxRange.py b/gui/builtinViewColumns/maxRange.py index be6be2a86..17d27ef5d 100644 --- a/gui/builtinViewColumns/maxRange.py +++ b/gui/builtinViewColumns/maxRange.py @@ -74,4 +74,7 @@ class MaxRange(ViewColumn): return (("displayName", bool, False), ("showIcon", bool, True)) + def getToolTip(self, mod): + return "Optimal + Falloff" + MaxRange.register() diff --git a/gui/builtinViewColumns/price.py b/gui/builtinViewColumns/price.py index 0afcb22c0..5fe6ef954 100644 --- a/gui/builtinViewColumns/price.py +++ b/gui/builtinViewColumns/price.py @@ -60,4 +60,7 @@ class Price(ViewColumn): def getImageId(self, mod): return -1 + def getToolTip(self, mod): + return self.name + Price.register() diff --git a/gui/builtinViewColumns/state.py b/gui/builtinViewColumns/state.py index 01e93e4f6..d26c46443 100644 --- a/gui/builtinViewColumns/state.py +++ b/gui/builtinViewColumns/state.py @@ -44,6 +44,10 @@ class State(ViewColumn): def getText(self, mod): return "" + def getToolTip(self, mod): + if isinstance(mod, Module) and not mod.isEmpty: + return State_.getName(mod.state).title() + def getImageId(self, stuff): if isinstance(stuff, Drone): return self.checkedId if stuff.amountActive > 0 else self.uncheckedId diff --git a/gui/builtinViews/fittingView.py b/gui/builtinViews/fittingView.py index 455e1e06b..76c291cdd 100644 --- a/gui/builtinViews/fittingView.py +++ b/gui/builtinViews/fittingView.py @@ -141,6 +141,7 @@ class FittingView(d.Display): self.Bind(wx.EVT_KEY_UP, self.kbEvent) self.Bind(wx.EVT_LEFT_DOWN, self.click) self.Bind(wx.EVT_RIGHT_DOWN, self.click) + self.Bind(wx.EVT_MIDDLE_DOWN, self.click) self.Bind(wx.EVT_SHOW, self.OnShow) self.Bind(wx.EVT_MOTION, self.OnMouseMove) self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow) @@ -162,12 +163,9 @@ class FittingView(d.Display): self.hoveredColumn = col if row != -1 and row not in self.blanks and col != -1 and col < len(self.DEFAULT_COLS): mod = self.mods[self.GetItemData(row)] - if self.DEFAULT_COLS[col] == "Miscellanea": - tooltip = self.activeColumns[col].getToolTip(mod) - if tooltip is not None: - self.SetToolTipString(tooltip) - else: - self.SetToolTip(None) + tooltip = self.activeColumns[col].getToolTip(mod) + if tooltip is not None: + self.SetToolTipString(tooltip) else: self.SetToolTip(None) else: @@ -522,16 +520,21 @@ class FittingView(d.Display): sFit = service.Fit.getInstance() fitID = self.mainFrame.getActiveFit() - ctrl = wx.GetMouseState().CmdDown() + ctrl = wx.GetMouseState().CmdDown() or wx.GetMouseState().MiddleDown() click = "ctrl" if ctrl is True else "right" if event.Button == 3 else "left" sFit.toggleModulesState(fitID, self.mods[self.GetItemData(row)], mods, click) + + # update state tooltip + tooltip = self.activeColumns[col].getToolTip(self.mods[self.GetItemData(row)]) + self.SetToolTipString(tooltip) + wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit())) else: event.Skip() - slotColourMap = {1: wx.Colour(250, 235, 204), # yellow = low slots - 2: wx.Colour(188,215,241), # blue = mid slots - 3: wx.Colour(235,204,209), # red = high slots + slotColourMap = {1: wx.Colour(250, 235, 204), # yellow = low slots + 2: wx.Colour(188, 215, 241), # blue = mid slots + 3: wx.Colour(235, 204, 209), # red = high slots 4: '', 5: ''} diff --git a/gui/chromeTabs.py b/gui/chromeTabs.py index d9563acb7..15c1141e1 100644 --- a/gui/chromeTabs.py +++ b/gui/chromeTabs.py @@ -25,6 +25,8 @@ import gui.utils.fonts as fonts from gui import bitmapLoader import gui.utils.fonts as fonts +import service + _PageChanging, EVT_NOTEBOOK_PAGE_CHANGING = wx.lib.newevent.NewEvent() _PageChanged, EVT_NOTEBOOK_PAGE_CHANGED = wx.lib.newevent.NewEvent() _PageAdding, EVT_NOTEBOOK_PAGE_ADDING = wx.lib.newevent.NewEvent() @@ -680,6 +682,7 @@ class PFTabsContainer(wx.Panel): self.containerHeight = height self.startDrag = False self.dragging = False + self.sFit = service.Fit.getInstance() self.inclination = 7 if canAdd: @@ -1013,6 +1016,9 @@ class PFTabsContainer(wx.Panel): Checks to see if we have a tab preview and sets up the timer for it to display """ + if not self.sFit.serviceFittingOptions["showTooltip"] or False: + return + if self.previewTimer: if self.previewTimer.IsRunning(): if self.previewWnd: diff --git a/gui/contextMenu.py b/gui/contextMenu.py index 41bbca392..4ed09f9c1 100644 --- a/gui/contextMenu.py +++ b/gui/contextMenu.py @@ -73,18 +73,25 @@ class ContextMenu(object): rootMenu.info[id] = (m, fullContext, it) sub = m.getSubMenu(srcContext, selection, rootMenu, it, rootItem) + if sub is None: # if there is no sub menu, bind the handler to the rootItem rootMenu.Bind(wx.EVT_MENU, cls.handler, rootItem) - else: + elif sub: + # If sub exists and is not False, set submenu. + # Sub might return False when we have a mix of + # single menu items and submenus (see: damage profile + # context menu) + # # If there is a submenu, it is expected that the sub - # logic take care of it's own binding. No binding is - # done here + # logic take care of it's own bindings, including for + # any single root items. No binding is done here # # It is important to remember that when binding sub - # menu items, bind them to the rootMenu for proper - # event handling, eg: - # rootMenu.Bind(wx.EVE_MENU, self.handle, menuItem) + # menu items, the menu to bind to depends on platform. + # Windows should bind to rootMenu, and all other + # platforms should bind to sub menu. See existing + # implementations for examples. rootItem.SetSubMenu(sub) if bitmap is not None: diff --git a/gui/itemStats.py b/gui/itemStats.py index c727c170b..a26406af5 100644 --- a/gui/itemStats.py +++ b/gui/itemStats.py @@ -523,10 +523,24 @@ class ItemEffects (wx.Panel): self.Layout() def OnClick(self, event): + """ + Debug use: open effect file with default application. + If effect file does not exist, create it + """ + import os - file = os.path.join(config.pyfaPath,"eos","effects","%s.py"%event.GetText().lower()) + file = os.path.join(config.pyfaPath, "eos", "effects", "%s.py"%event.GetText().lower()) + + if not os.path.isfile(file): + open(file, 'a').close() + if 'wxMSW' in wx.PlatformInfo: os.startfile(file) + elif 'wxMac' in wx.PlatformInfo: + os.system("open "+file) + else: + import subprocess + subprocess.call(["xdg-open", file]) ########################################################################### diff --git a/gui/mainFrame.py b/gui/mainFrame.py index 2d71da48a..634a22f01 100644 --- a/gui/mainFrame.py +++ b/gui/mainFrame.py @@ -42,7 +42,7 @@ from gui.additionsPane import AdditionsPane from gui.marketBrowser import MarketBrowser from gui.multiSwitch import MultiSwitch from gui.statsPane import StatsPane -from gui.shipBrowser import ShipBrowser, FitSelected +from gui.shipBrowser import ShipBrowser, FitSelected, ImportSelected, Stage3Selected from gui.characterEditor import CharacterEditor from gui.characterSelection import CharacterSelection from gui.patternEditor import DmgPatternEditorDlg @@ -54,6 +54,9 @@ from gui.utils.clipboard import toClipboard, fromClipboard from gui.fleetBrowser import FleetBrowser from gui.updateDialog import UpdateDialog from gui.builtinViews import * + +from time import gmtime, strftime + import locale locale.setlocale(locale.LC_ALL, '') @@ -201,9 +204,18 @@ class MainFrame(wx.Frame): dlg.Destroy() def LoadPreviousOpenFits(self): + sFit = service.Fit.getInstance() + self.prevOpenFits = service.SettingsProvider.getInstance().getSettings("pyfaPrevOpenFits", {"enabled": False, "pyfaOpenFits": []}) fits = self.prevOpenFits['pyfaOpenFits'] + # Remove any fits that cause exception when fetching (non-existent fits) + for id in fits[:]: + try: + sFit.getFit(id) + except: + fits.remove(id) + if not self.prevOpenFits['enabled'] or len(fits) is 0: # add blank page if there are no fits to be loaded self.fitMultiSwitch.AddPage() @@ -327,47 +339,21 @@ class MainFrame(wx.Frame): dlg.ShowModal() dlg.Destroy() - def showImportDialog(self, event): - fits = [] - sFit = service.Fit.getInstance() - dlg=wx.FileDialog( - self, - "Open One Or More Fitting Files", - wildcard = "EFT text fitting files (*.cfg)|*.cfg|" \ - "EVE XML fitting files (*.xml)|*.xml|" \ - "All Files (*)|*", - style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE) - if (dlg.ShowModal() == wx.ID_OK): - self.waitDialog = animUtils.WaitDialog(self, title = "Importing") - sFit.importFitsThreaded(dlg.GetPaths(), self.importCallback) - dlg.Destroy() - self.waitDialog.ShowModal() - - def importCallback(self, fits): - self.waitDialog.Destroy() - sFit = service.Fit.getInstance() - IDs = sFit.saveImportedFits(fits) - self._openAfterImport(len(fits), IDs) - - def _openAfterImport(self, importCount, fitIDs): - if importCount == 1: - wx.PostEvent(self, FitSelected(fitID=fitIDs[0])) - - self.shipBrowser.RefreshContent() - def showExportDialog(self, event): - dlg=wx.FileDialog( - self, - "Save Fitting As...", - wildcard = "EVE XML fitting files (*.xml)|*.xml", - style = wx.FD_SAVE) - if (dlg.ShowModal() == wx.ID_OK): - sFit = service.Fit.getInstance() + """ Export active fit """ + sFit = service.Fit.getInstance() + fit = sFit.getFit(self.getActiveFit()) + defaultFile = "%s - %s.xml"%(fit.ship.item.name, fit.name) if fit else None + + dlg = wx.FileDialog(self, "Save Fitting As...", + wildcard = "EVE XML fitting files (*.xml)|*.xml", + style = wx.FD_SAVE, + defaultFile=defaultFile) + if dlg.ShowModal() == wx.ID_OK: format = dlg.GetFilterIndex() - output = "" path = dlg.GetPath() - if (format == 0): - output = sFit.exportXml(self.getActiveFit()) + if format == 0: + output = sFit.exportXml(None, self.getActiveFit()) if '.' not in os.path.basename(path): path += ".xml" else: @@ -406,7 +392,7 @@ class MainFrame(wx.Frame): # 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) + self.Bind(wx.EVT_MENU, self.fileImportDialog, id=wx.ID_OPEN) # Export dialog self.Bind(wx.EVT_MENU, self.showExportDialog, id=wx.ID_SAVEAS) # Import from Clipboard @@ -545,17 +531,16 @@ class MainFrame(wx.Frame): def clipboardXml(self): sFit = service.Fit.getInstance() - toClipboard(sFit.exportXml(self.getActiveFit())) + toClipboard(sFit.exportXml(None, self.getActiveFit())) def importFromClipboard(self, event): sFit = service.Fit.getInstance() try: fits = sFit.importFitFromBuffer(fromClipboard(), self.getActiveFit()) - IDs = sFit.saveImportedFits(fits) - self._openAfterImport(len(fits), IDs) except: pass - + else: + self._openAfterImport(fits) def exportToClipboard(self, event): CopySelectDict = {CopySelectDialog.copyFormatEft: self.clipboardEft, @@ -571,44 +556,109 @@ class MainFrame(wx.Frame): pass dlg.Destroy() - def backupToXml(self, event): + def fileImportDialog(self, event): + """Handles importing single/multiple EVE XML / EFT cfg fit files""" sFit = service.Fit.getInstance() - saveDialog = wx.FileDialog( - self, - "Save Backup As...", - wildcard = "EVE XML fitting file (*.xml)|*.xml", - style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) - if (saveDialog.ShowModal() == wx.ID_OK): + dlg = wx.FileDialog(self, "Open One Or More Fitting Files", + wildcard = "EVE XML fitting files (*.xml)|*.xml|" \ + "EFT text fitting files (*.cfg)|*.cfg|" \ + "All Files (*)|*", + style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE) + if (dlg.ShowModal() == wx.ID_OK): + self.progressDialog = wx.ProgressDialog( + "Importing fits", + " "*100, # set some arbitrary spacing to create wifth in window + parent=self, style = wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME) + self.progressDialog.message = None + sFit.importFitsThreaded(dlg.GetPaths(), self.fileImportCallback) + self.progressDialog.ShowModal() + dlg.Destroy() + + def fileImportCallback(self, info, fits=None): + """ + While importing fits from file, the logic calls back to this function to + update progress bar to show activity. XML files can contain multiple + ships with multiple fits, whereas EFT cfg files contain many fits of + a single ship. When iterating through the files, we update the message + when we start a new file, and then Pulse the progress bar with every fit + that is processed. + """ + + if info == -1: + # Done processing + self.progressDialog.Hide() + self._openAfterImport(fits) + elif info != self.progressDialog.message and info is not None: + # New message, overwrite cached message and update + self.progressDialog.message = info + self.progressDialog.Pulse(info) + else: + # Simply Pulse() if we don't have anything else to do + self.progressDialog.Pulse() + + def _openAfterImport(self, fits): + if len(fits) > 0: + if len(fits) == 1: + fit = fits[0] + wx.PostEvent(self, FitSelected(fitID=fit.ID)) + wx.PostEvent(self.shipBrowser, Stage3Selected(shipID=fit.shipID, back=True)) + else: + wx.PostEvent(self.shipBrowser, ImportSelected(fits=fits, back=True)) + + def backupToXml(self, event): + """ Back up all fits to EVE XML file """ + defaultFile = "pyfa-fits-%s.xml"%strftime("%Y%m%d_%H%M%S", gmtime()) + + saveDialog = wx.FileDialog(self, "Save Backup As...", + wildcard = "EVE XML fitting file (*.xml)|*.xml", + style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT, + defaultFile=defaultFile) + + if saveDialog.ShowModal() == wx.ID_OK: filePath = saveDialog.GetPath() if '.' not in os.path.basename(filePath): filePath += ".xml" - self.waitDialog = animUtils.WaitDialog(self) - sFit.backupFits(filePath, self.closeWaitDialog) - self.waitDialog.ShowModal() - saveDialog.Destroy() + sFit = service.Fit.getInstance() + max = sFit.countAllFits() + + self.progressDialog = wx.ProgressDialog("Backup fits", + "Backing up %d fits to: %s"%(max, filePath), + maximum=max, parent=self, + style=wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME) + + sFit.backupFits(filePath, self.backupCallback) + self.progressDialog.ShowModal() + + def backupCallback(self, info): + if info == -1: + self.progressDialog.Hide() + else: + self.progressDialog.Update(info) def exportSkillsNeeded(self, event): + """ Exports skills needed for active fit and active character """ sCharacter = service.Character.getInstance() - saveDialog = wx.FileDialog( - self, - "Export Skills Needed As...", - wildcard = "EVEMon skills training file (*.emp)|*.emp|" \ - "EVEMon skills training XML file (*.xml)|*.xml|" \ - "Text skills training file (*.txt)|*.txt", - style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) - if (saveDialog.ShowModal() == wx.ID_OK): + saveDialog = wx.FileDialog(self, "Export Skills Needed As...", + wildcard = "EVEMon skills training file (*.emp)|*.emp|" \ + "EVEMon skills training XML file (*.xml)|*.xml|" \ + "Text skills training file (*.txt)|*.txt", + style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) + + if saveDialog.ShowModal() == wx.ID_OK: saveFmtInt = saveDialog.GetFilterIndex() - saveFmt = "" + if saveFmtInt == 0: # Per ordering of wildcards above saveFmt = "emp" elif saveFmtInt == 1: saveFmt = "xml" else: saveFmt = "txt" + filePath = saveDialog.GetPath() if '.' not in os.path.basename(filePath): filePath += ".{0}".format(saveFmt) + self.waitDialog = animUtils.WaitDialog(self) sCharacter.backupSkills(filePath, saveFmt, self.getActiveFit(), self.closeWaitDialog) self.waitDialog.ShowModal() @@ -616,29 +666,38 @@ class MainFrame(wx.Frame): saveDialog.Destroy() def importCharacter(self, event): - sCharacter = service.Character.getInstance() - dlg=wx.FileDialog( - self, - "Open One Or More Character Files", - wildcard = "EVE CCP API XML character files (*.xml)|*.xml|" \ - "All Files (*)|*", - style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE) - if (dlg.ShowModal() == wx.ID_OK): - self.waitDialog = animUtils.WaitDialog(self, title = "Importing Character") + """ Imports character XML file from EVE API """ + dlg = wx.FileDialog(self, "Open One Or More Character Files", + wildcard="EVE API XML character files (*.xml)|*.xml|" \ + "All Files (*)|*", + style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE) + + if dlg.ShowModal() == wx.ID_OK: + self.waitDialog = animUtils.WaitDialog(self, title="Importing Character") + sCharacter = service.Character.getInstance() sCharacter.importCharacter(dlg.GetPaths(), self.importCharacterCallback) dlg.Destroy() self.waitDialog.ShowModal() - def exportHtml(self, event): - from gui.utils.exportHtml import exportHtml - self.waitDialog = animUtils.WaitDialog(self) - exportHtml.getInstance().refreshFittingHtml(True, self.closeWaitDialog) - self.waitDialog.ShowModal() - def importCharacterCallback(self): self.waitDialog.Destroy() wx.PostEvent(self, GE.CharListUpdated()) + def exportHtml(self, event): + from gui.utils.exportHtml import exportHtml + sFit = service.Fit.getInstance() + settings = service.settings.HTMLExportSettings.getInstance() + + max = sFit.countAllFits() + path = settings.getPath() + self.progressDialog = wx.ProgressDialog("Backup fits", + "Generating HTML file at: %s"%path, + maximum=max, parent=self, + style=wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME) + + exportHtml.getInstance().refreshFittingHtml(True, self.backupCallback) + self.progressDialog.ShowModal() + def closeWaitDialog(self): self.waitDialog.Destroy() @@ -650,7 +709,7 @@ class MainFrame(wx.Frame): else: self.graphFrame.SetFocus() - def openWXInspectTool(self,event): + def openWXInspectTool(self, event): from wx.lib.inspection import InspectionTool if not InspectionTool().initialized: InspectionTool().Init() diff --git a/gui/patternEditor.py b/gui/patternEditor.py index f3b8da855..8bcdde295 100644 --- a/gui/patternEditor.py +++ b/gui/patternEditor.py @@ -28,11 +28,11 @@ from service.damagePattern import ImportError ## Class DmgPatternEditorDlg ########################################################################### -class DmgPatternEditorDlg (wx.Dialog): +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 )) + wx.Dialog.__init__(self, parent, id = wx.ID_ANY, title = u"Damage Pattern Editor", size = wx.Size( 400,240 )) self.block = False self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize) @@ -125,7 +125,7 @@ class DmgPatternEditorDlg (wx.Dialog): editObj.Bind(wx.EVT_TEXT, self.ValuesUpdated) editObj.SetLimited(True) editObj.SetMin(0) - editObj.SetMax(99999) + editObj.SetMax(2000000) contentSizer.Add(dmgeditSizer, 1, wx.EXPAND | wx.ALL, 5) self.slfooter = wx.StaticLine(self) @@ -244,23 +244,22 @@ class DmgPatternEditorDlg (wx.Dialog): self.block = False self.ValuesUpdated() - def newPattern(self,event): - sDP = service.DamagePattern.getInstance() - p = sDP.newPattern() - self.choices.append(p) - id = self.ccDmgPattern.Append(p.name) - self.ccDmgPattern.SetSelection(id) - + def newPattern(self, event): self.restrict() + + self.block = True # reset values for type in self.DAMAGE_TYPES: editObj = getattr(self, "%sEdit"%type) editObj.SetValue(0) + self.block = False + self.btnSave.SetLabel("Create") + self.Refresh() self.renamePattern() - def renamePattern(self,event=None): + def renamePattern(self, event=None): if event is not None: self.btnSave.SetLabel("Rename") @@ -268,7 +267,12 @@ class DmgPatternEditorDlg (wx.Dialog): self.namePicker.Show() self.headerSizer.Replace(self.ccDmgPattern, 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() @@ -284,19 +288,25 @@ class DmgPatternEditorDlg (wx.Dialog): 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 choose another") - return - if newName == "": self.stNotice.SetLabel("Invalid name.") return sDP = service.DamagePattern.getInstance() + if self.btnSave.Label == "Create": + p = sDP.newPattern() + else: + # we are renaming, so get the current selection + p = self.getActivePattern() + + for pattern in self.choices: + if pattern.name == newName and p != pattern: + self.stNotice.SetLabel("Name already used, please choose another") + return + sDP.renamePattern(p, newName) + self.updateChoices(newName) self.headerSizer.Replace(self.namePicker, self.ccDmgPattern) self.ccDmgPattern.Show() self.namePicker.Hide() @@ -335,7 +345,7 @@ class DmgPatternEditorDlg (wx.Dialog): def __del__( self ): pass - def updateChoices(self): + def updateChoices(self, select=None): "Gathers list of patterns and updates choice selections" sDP = service.DamagePattern.getInstance() self.choices = sDP.getDamagePatternList() @@ -348,10 +358,14 @@ class DmgPatternEditorDlg (wx.Dialog): self.choices.sort(key=lambda p: p.name) self.ccDmgPattern.Clear() - for choice in map(lambda p: p.name, self.choices): + for i, choice in enumerate(map(lambda p: p.name, self.choices)): self.ccDmgPattern.Append(choice) - self.ccDmgPattern.SetSelection(0) + if select is not None and choice == select: + self.ccDmgPattern.SetSelection(i) + + if select is None: + self.ccDmgPattern.SetSelection(0) self.patternChanged() def importPatterns(self, event): diff --git a/gui/resistsEditor.py b/gui/resistsEditor.py index a5764a74a..0d26be5da 100644 --- a/gui/resistsEditor.py +++ b/gui/resistsEditor.py @@ -23,12 +23,12 @@ import service from gui.utils.clipboard import toClipboard, fromClipboard from service.targetResists import ImportError -class ResistsEditorDlg (wx.Dialog): +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 )) + 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) @@ -301,7 +301,7 @@ class ResistsEditorDlg (wx.Dialog): return sTR = service.TargetResists.getInstance() - if event.EventObject.Label == "Create": + if self.btnSave.Label == "Create": p = sTR.newPattern() else: # we are renaming, so get the current selection diff --git a/gui/sfBrowserItem.py b/gui/sfBrowserItem.py index 0a2da9090..4067707c3 100644 --- a/gui/sfBrowserItem.py +++ b/gui/sfBrowserItem.py @@ -413,4 +413,4 @@ class SFBrowserItem(wx.Window): self.bkBitmap.state = state self.bkBitmap.sFactor = sFactor self.bkBitmap.eFactor = eFactor - self.bkBitmap.mFactor = mFactor \ No newline at end of file + self.bkBitmap.mFactor = mFactor diff --git a/gui/shipBrowser.py b/gui/shipBrowser.py index 659c2fe23..7e916181c 100644 --- a/gui/shipBrowser.py +++ b/gui/shipBrowser.py @@ -30,6 +30,7 @@ Stage1Selected, EVT_SB_STAGE1_SEL = wx.lib.newevent.NewEvent() Stage2Selected, EVT_SB_STAGE2_SEL = wx.lib.newevent.NewEvent() Stage3Selected, EVT_SB_STAGE3_SEL = wx.lib.newevent.NewEvent() SearchSelected, EVT_SB_SEARCH_SEL = wx.lib.newevent.NewEvent() +ImportSelected, EVT_SB_IMPORT_SEL = wx.lib.newevent.NewEvent() class PFWidgetsContainer(PFListPane): def __init__(self,parent): @@ -324,7 +325,7 @@ class RaceSelector(wx.Window): event.Skip() class NavigationPanel(SFItem.SFBrowserItem): - def __init__(self,parent, size = (-1,24)): + def __init__(self,parent, size = (-1, 24)): SFItem.SFBrowserItem.__init__(self,parent,size = size) self.rewBmpH = bitmapLoader.getBitmap("frewind_small","icons") @@ -352,7 +353,7 @@ class NavigationPanel(SFItem.SFBrowserItem): self.padding = 4 self.lastSearch = "" - self.recentSearches = [] + self.recentSearches = [] # not used? self.inSearch = False self.fontSmall = wx.Font(fonts.SMALL, wx.SWISS, wx.NORMAL, wx.NORMAL) @@ -371,23 +372,14 @@ class NavigationPanel(SFItem.SFBrowserItem): self.Bind(wx.EVT_SIZE, self.OnResize) - def OnScheduleSearch(self, event): search = self.BrowserSearchBox.GetValue() # Make sure we do not count wildcard as search symbol realsearch = search.replace("*", "") - if len(realsearch) < 3 and len(realsearch) >= 0: - if self.inSearch == True: - self.inSearch = False - if len(self.shipBrowser.browseHist) > 0: - stage,data = self.shipBrowser.browseHist.pop() - self.gotoStage(stage,data) - else: - if search: - wx.PostEvent(self.shipBrowser,SearchSelected(text=search, back = False)) - self.inSearch = True - else: - self.inSearch = False + if len(realsearch) >= 3: + self.lastSearch = search + wx.PostEvent(self.shipBrowser,SearchSelected(text=search, back = False)) + def ToggleSearchBox(self): if self.BrowserSearchBox.IsShown(): @@ -401,8 +393,6 @@ class NavigationPanel(SFItem.SFBrowserItem): self.OnBrowserSearchBoxLostFocus(None) def OnBrowserSearchBoxLostFocus(self, event): - self.lastSearch = self.BrowserSearchBox.GetValue() - self.BrowserSearchBox.ChangeValue("") self.BrowserSearchBox.Show(False) def OnBrowserSearchBoxEsc(self, event): @@ -411,7 +401,6 @@ class NavigationPanel(SFItem.SFBrowserItem): else: event.Skip() - def OnResize(self, event): self.Refresh() @@ -449,7 +438,7 @@ class NavigationPanel(SFItem.SFBrowserItem): sFit = service.Fit.getInstance() fitID = sFit.newFit(shipID, "%s fit" %shipName) self.shipBrowser.fitIDMustEditName = fitID - wx.PostEvent(self.Parent,Stage3Selected(shipID=shipID, back = True)) + wx.PostEvent(self.Parent,Stage3Selected(shipID=shipID)) wx.PostEvent(self.mainFrame, FitSelected(fitID=fitID)) def OnHistoryReset(self): @@ -460,11 +449,11 @@ class NavigationPanel(SFItem.SFBrowserItem): def OnHistoryBack(self): if len(self.shipBrowser.browseHist) > 0: stage,data = self.shipBrowser.browseHist.pop() - self.gotoStage(stage,data) + self.gotoStage(stage, data) def AdjustChannels(self, bitmap): img = wx.ImageFromBitmap(bitmap) - img = img.AdjustChannels(1.05,1.05,1.05,1) + img = img.AdjustChannels(1.05, 1.05, 1.05, 1) return wx.BitmapFromImage(img) def UpdateElementsPos(self, mdc): @@ -536,20 +525,20 @@ class NavigationPanel(SFItem.SFBrowserItem): self.bkBitmap.mFactor = mFactor - def gotoStage(self,stage, data = None): + def gotoStage(self, stage, data=None): if stage == 1: - wx.PostEvent(self.Parent,Stage1Selected()) + wx.PostEvent(self.Parent, Stage1Selected()) elif stage == 2: - wx.PostEvent(self.Parent,Stage2Selected(categoryID=data, back = True)) + wx.PostEvent(self.Parent, Stage2Selected(categoryID=data, back=True)) elif stage == 3: - wx.PostEvent(self.Parent,Stage3Selected(shipID=data, back = 1)) + wx.PostEvent(self.Parent, Stage3Selected(shipID=data)) elif stage == 4: self.shipBrowser._activeStage = 4 - self.stStatus.SetLabel("Search: %s" % data.capitalize()) - self.Layout() - wx.PostEvent(self.Parent,SearchSelected(text=data, back = True)) + wx.PostEvent(self.Parent, SearchSelected(text=data, back=True)) + elif stage == 5: + wx.PostEvent(self.Parent, ImportSelected(fits=data)) else: - wx.PostEvent(self.Parent,Stage1Selected()) + wx.PostEvent(self.Parent, Stage1Selected()) class ShipBrowser(wx.Panel): @@ -610,6 +599,7 @@ class ShipBrowser(wx.Panel): self.Bind(EVT_SB_STAGE1_SEL, self.stage1) self.Bind(EVT_SB_STAGE3_SEL, self.stage3) self.Bind(EVT_SB_SEARCH_SEL, self.searchStage) + self.Bind(EVT_SB_IMPORT_SEL, self.importStage) self.mainFrame.Bind(GE.FIT_CHANGED, self.RefreshList) @@ -654,6 +644,8 @@ class ShipBrowser(wx.Panel): return self._stage2Data if stage == 3: return self._stage3Data + if stage == 4: + return self.navpanel.lastSearch return -1 def GetStage3ShipName(self): @@ -809,13 +801,15 @@ class ShipBrowser(wx.Panel): self.lpane.ShowLoading(False) - if event.back == 0: - self.browseHist.append( (2,self._stage2Data) ) - elif event.back == -1: - if len(self.navpanel.recentSearches)>0: + # If back is False, do not append to history. This could be us calling + # the stage from previous history, creating / copying fit, etc. + # We also have to use conditional for search stage since it's last data + # is kept elsewhere + if getattr(event, "back", False): + if self._activeStage == 4 and self.navpanel.lastSearch != "": self.browseHist.append((4, self.navpanel.lastSearch)) - elif event.back > 0: - self.browseHist.append( (2,event.back) ) + else: + self.browseHist.append((self._activeStage, self.lastdata)) shipID = event.shipID self.lastdata = shipID @@ -868,11 +862,11 @@ class ShipBrowser(wx.Panel): self.navpanel.ShowSwitchEmptyGroupsButton(False) if not event.back: - if self._activeStage !=4: - if len(self.browseHist) >0: - self.browseHist.append( (self._activeStage, self.lastdata) ) + if self._activeStage != 4: + if len(self.browseHist) > 0: + self.browseHist.append((self._activeStage, self.lastdata)) else: - self.browseHist.append((1,0)) + self.browseHist.append((1, 0)) self._lastStage = self._activeStage self._activeStage = 4 @@ -903,6 +897,46 @@ class ShipBrowser(wx.Panel): self.raceselect.Show(False) self.Layout() + def importStage(self, event): + self.lpane.ShowLoading(False) + + self.navpanel.ShowNewFitButton(False) + self.navpanel.ShowSwitchEmptyGroupsButton(False) + + if getattr(event, "back", False): + self.browseHist.append((self._activeStage, self.lastdata)) + + self._lastStage = self._activeStage + self._activeStage = 5 + + fits = event.fits + + # sort by ship name, then fit name + fits.sort(key=lambda fit: (fit.ship.item.name, fit.name)) + + self.lastdata = fits + self.lpane.Freeze() + self.lpane.RemoveAllChildren() + + if fits: + for fit in fits: + self.lpane.AddWidget(FitItem( + self.lpane, + fit.ID, ( + fit.ship.item.name, + fit.name, + fit.booster, + fit.timestamp), + fit.ship.item.ID)) + self.lpane.RefreshList(doFocus=False) + self.lpane.Thaw() + + self.raceselect.RebuildRaces(self.RACE_ORDER) + + if self.showRacesFilterInStage2Only: + self.raceselect.Show(False) + self.Layout() + class PFStaticText(wx.Panel): def __init__(self, parent, label=wx.EmptyString): wx.Panel.__init__ (self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size = parent.GetSize()) @@ -1165,7 +1199,7 @@ class ShipItem(SFItem.SFBrowserItem): else: shipName, fittings = self.shipFittingInfo if fittings > 0: - wx.PostEvent(self.shipBrowser,Stage3Selected(shipID=self.shipID, back = -1 if self.shipBrowser.GetActiveStage() == 4 else 0)) + wx.PostEvent(self.shipBrowser, Stage3Selected(shipID=self.shipID, back=True)) else: self.newBtnCB() @@ -1577,7 +1611,7 @@ class FitItem(SFItem.SFBrowserItem): sFit = service.Fit.getInstance() fitID = sFit.copyFit(self.fitID) self.shipBrowser.fitIDMustEditName = fitID - wx.PostEvent(self.shipBrowser,Stage3Selected(shipID=self.shipID, back=True)) + wx.PostEvent(self.shipBrowser,Stage3Selected(shipID=self.shipID)) wx.PostEvent(self.mainFrame, FitSelected(fitID=fitID)) def renameBtnCB(self): @@ -1620,18 +1654,22 @@ class FitItem(SFItem.SFBrowserItem): self.deleted = True sFit = service.Fit.getInstance() + fit = sFit.getFit(self.fitID) sFit.deleteFit(self.fitID) - if self.shipBrowser.GetActiveStage() == 4: - wx.PostEvent(self.shipBrowser,SearchSelected(text=self.shipBrowser.navpanel.lastSearch,back=True)) + if self.shipBrowser.GetActiveStage() == 5: + if fit in self.shipBrowser.lastdata: # remove fit from import cache + self.shipBrowser.lastdata.remove(fit) + wx.PostEvent(self.shipBrowser, ImportSelected(fits=self.shipBrowser.lastdata)) + elif self.shipBrowser.GetActiveStage() == 4: + wx.PostEvent(self.shipBrowser, SearchSelected(text=self.shipBrowser.navpanel.lastSearch, back=True)) else: - wx.PostEvent(self.shipBrowser,Stage3Selected(shipID=self.shipID, back=True)) + wx.PostEvent(self.shipBrowser, Stage3Selected(shipID=self.shipID)) wx.PostEvent(self.mainFrame, FitRemoved(fitID=self.fitID)) def MouseLeftUp(self, event): - if self.dragging and self.dragged: self.dragging = False self.dragged = False diff --git a/gui/utils/exportHtml.py b/gui/utils/exportHtml.py index c61c2444a..726bec265 100644 --- a/gui/utils/exportHtml.py +++ b/gui/utils/exportHtml.py @@ -7,7 +7,7 @@ class exportHtml(): _instance = None @classmethod def getInstance(cls): - if cls._instance == None: + if cls._instance is None: cls._instance = exportHtml() return cls._instance @@ -15,17 +15,17 @@ class exportHtml(): def __init__(self): self.thread = exportHtmlThread() - def refreshFittingHtml(self, force = False, callback = False): + def refreshFittingHtml(self, force=False, callback=False): settings = service.settings.HTMLExportSettings.getInstance() - if (force or settings.getEnabled()): + if force or settings.getEnabled(): self.thread.stop() self.thread = exportHtmlThread(callback) self.thread.start() class exportHtmlThread(threading.Thread): - def __init__(self, callback = False): + def __init__(self, callback=False): threading.Thread.__init__(self) self.callback = callback self.stopRunning = False @@ -40,7 +40,7 @@ class exportHtmlThread(threading.Thread): return sMkt = service.Market.getInstance() - sFit = service.Fit.getInstance() + sFit = service.Fit.getInstance() settings = service.settings.HTMLExportSettings.getInstance() timestamp = time.localtime(time.time()) @@ -135,6 +135,9 @@ class exportHtmlThread(threading.Thread): HTML += '