diff --git a/README.md b/README.md
index 75f0d2c68..69e22cd49 100644
--- a/README.md
+++ b/README.md
@@ -6,6 +6,13 @@ It provides many advanced features such as graphs and full calculations of any p
Please see the [FAQ](https://github.com/DarkFenX/Pyfa/wiki/FAQ) for answers to common questions / concerns
+#### A note for Linux users
+pyfa currently only supports wxPython 2.8. However, there are some distros that have started to support 3.0 and subsequently dropped support for 2.8 altogether (such as Debian Jessie). If this is the case and wxPython 3.0 is the only version installed, the official pyfa releases will not run. You must either find a package for 2.8 or compile it yourself.
+
+For Debian Jessie, wxPython 2.8 is available in Sid (the unstable repo). you can use apt-pinning to install select packages from unstable and still keep your stable system. See http://jaqque.sbih.org/kplug/apt-pinning.html for me details.
+
+3.0 support is being worked on and can be found on the wx3 branch. It may be stable enough for you, but there are a few bugs related to it. Please see the wx3 label on the GitHub issues area for me information on known issues (biggest one currently is GTK warning spam): https://github.com/DarkFenX/Pyfa/labels/wx3
+
#### Links
* [Development repository: http://github.com/DarkFenX/Pyfa](http://github.com/DarkFenX/Pyfa)
* [XMPP conference:
diff --git a/config.py b/config.py
index 8fe03c592..3ac5d9779 100644
--- a/config.py
+++ b/config.py
@@ -13,9 +13,9 @@ debug = False
saveInRoot = False
# Version data
-version = "1.11.1"
+version = "1.12.1"
tag = "git"
-expansionName = "Mosaic"
+expansionName = "Carnyx"
expansionVersion = "1.0"
evemonMinVersion = "4081"
diff --git a/eos/db/migrations/upgrade8.py b/eos/db/migrations/upgrade8.py
new file mode 100644
index 000000000..6097c3799
--- /dev/null
+++ b/eos/db/migrations/upgrade8.py
@@ -0,0 +1,88 @@
+"""
+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 = {
+ 8529: ( # Large F-S9 Regolith Compact Shield Extender
+ 8409, # Large Subordinate Screen Stabilizer I
+ ),
+ 8419: ( # Large Azeotropic Restrained Shield Extender
+ 8489, # Large Supplemental Barrier Emitter I
+ ),
+ 8517: ( # Medium F-S9 Regolith Compact Shield Extender
+ 8397, # Medium Subordinate Screen Stabilizer I
+ ),
+ 8433: ( # Medium Azeotropic Restrained Shield Extender
+ 8477, # Medium Supplemental Barrier Emitter I
+ ),
+ 20627: ( # Small 'Trapper' Shield Extender
+ 8437, # Micro Azeotropic Ward Salubrity I
+ 8505, # Micro F-S9 Regolith Shield Induction
+ 3849, # Micro Shield Extender I
+ 3851, # Micro Shield Extender II
+ 8387, # Micro Subordinate Screen Stabilizer I
+ 8465, # Micro Supplemental Barrier Emitter I
+ ),
+ 8521: ( # Small F-S9 Regolith Compact Shield Extender
+ 8401, # Small Subordinate Screen Stabilizer I
+ ),
+ 8427: ( # Small Azeotropic Restrained Shield Extender
+ 8481, # Small Supplemental Barrier Emitter I
+ ),
+ 11343: ( # 100mm Crystalline Carbonide Restrained Plates
+ 11345, # 100mm Reinforced Nanofiber Plates I
+ ),
+ 11341: ( # 100mm Rolled Tungsten Compact Plates
+ 11339, # 100mm Reinforced Titanium Plates I
+ ),
+ 11327: ( # 1600mm Crystalline Carbonide Restrained Plates
+ 11329, # 1600mm Reinforced Nanofiber Plates I
+ ),
+ 11325: ( # 1600mm Rolled Tungsten Compact Plates
+ 11323, # 1600mm Reinforced Titanium Plates I
+ ),
+ 11351: ( # 200mm Crystalline Carbonide Restrained Plates
+ 11353, # 200mm Reinforced Nanofiber Plates I
+ ),
+ 11349: ( # 200mm Rolled Tungsten Compact Plates
+ 11347, # 200mm Reinforced Titanium Plates I
+ ),
+ 11311: ( # 400mm Crystalline Carbonide Restrained Plates
+ 11313, # 400mm Reinforced Nanofiber Plates I
+ ),
+ 11309: ( # 400mm Rolled Tungsten Compact Plates
+ 11307, # 400mm Reinforced Titanium Plates I
+ ),
+ 23791: ( # 'Citadella' 100mm Steel Plates
+ 11335, # 50mm Reinforced Crystalline Carbonide Plates I
+ 11337, # 50mm Reinforced Nanofiber Plates I
+ 11333, # 50mm Reinforced Rolled Tungsten Plates I
+ 11291, # 50mm Reinforced Steel Plates I
+ 20343, # 50mm Reinforced Steel Plates II
+ 11331, # 50mm Reinforced Titanium Plates I
+ ),
+ 11319: ( # 800mm Crystalline Carbonide Restrained Plates
+ 11321, # 800mm Reinforced Nanofiber Plates I
+ ),
+ 11317: ( # 800mm Rolled Tungsten Compact Plates
+ 11315, # 800mm Reinforced Titanium Plates 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/effects/addtosignatureradius2.py b/eos/effects/addtosignatureradius2.py
index 658d72b61..01e6cf6c4 100644
--- a/eos/effects/addtosignatureradius2.py
+++ b/eos/effects/addtosignatureradius2.py
@@ -2,7 +2,7 @@
#
# Used by:
# Modules from group: Missile Launcher Bomb (2 of 2)
-# Modules from group: Shield Extender (37 of 37)
+# Modules from group: Shield Extender (25 of 25)
type = "passive"
def handler(fit, module, context):
fit.ship.increaseItemAttr("signatureRadius", module.getModifiedItemAttr("signatureRadiusAdd"))
\ No newline at end of file
diff --git a/eos/effects/armorhpbonusadd.py b/eos/effects/armorhpbonusadd.py
index 32fac9468..2ea8082d2 100644
--- a/eos/effects/armorhpbonusadd.py
+++ b/eos/effects/armorhpbonusadd.py
@@ -1,7 +1,7 @@
# armorHPBonusAdd
#
# Used by:
-# Modules from group: Armor Reinforcer (57 of 57)
+# Modules from group: Armor Reinforcer (38 of 38)
type = "passive"
def handler(fit, module, context):
fit.ship.increaseItemAttr("armorHP", module.getModifiedItemAttr("armorHPBonusAdd"))
\ No newline at end of file
diff --git a/eos/effects/armorreinforcermassadd.py b/eos/effects/armorreinforcermassadd.py
index 75cbe0525..4c00614b8 100644
--- a/eos/effects/armorreinforcermassadd.py
+++ b/eos/effects/armorreinforcermassadd.py
@@ -1,7 +1,7 @@
# armorReinforcerMassAdd
#
# Used by:
-# Modules from group: Armor Reinforcer (57 of 57)
+# Modules from group: Armor Reinforcer (38 of 38)
# Modules from group: Entosis Link (2 of 2)
type = "passive"
def handler(fit, module, context):
diff --git a/eos/effects/capacitorcapacitymultiply.py b/eos/effects/capacitorcapacitymultiply.py
index 17e9d1da4..b60cb07a5 100644
--- a/eos/effects/capacitorcapacitymultiply.py
+++ b/eos/effects/capacitorcapacitymultiply.py
@@ -4,7 +4,7 @@
# Modules from group: Capacitor Flux Coil (6 of 6)
# 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: Propulsion Module (114 of 114)
# 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/entosisdurationmultiply.py b/eos/effects/entosisdurationmultiply.py
new file mode 100644
index 000000000..0918f2079
--- /dev/null
+++ b/eos/effects/entosisdurationmultiply.py
@@ -0,0 +1,12 @@
+# entosisDurationMultiply
+#
+# Used by:
+# Ships from group: Carrier (4 of 4)
+# Ships from group: Dreadnought (4 of 4)
+# Ships from group: Supercarrier (5 of 5)
+# Ships from group: Titan (4 of 4)
+# Ship: Rorqual
+type = "passive"
+def handler(fit, ship, context):
+ fit.modules.filteredItemMultiply(lambda mod: mod.item.requiresSkill("Infomorph Psychology"),
+ "duration", ship.getModifiedItemAttr("entosisDurationMultiplier") or 1)
diff --git a/eos/effects/minmatarshipewtargetpaintermc1.py b/eos/effects/minmatarshipewtargetpaintermc1.py
index 772e3f166..bc6088a6b 100644
--- a/eos/effects/minmatarshipewtargetpaintermc1.py
+++ b/eos/effects/minmatarshipewtargetpaintermc1.py
@@ -2,6 +2,7 @@
#
# Used by:
# Ship: Bellicose
+# Ship: Rapier
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Minmatar Cruiser").level
diff --git a/eos/effects/minmatarshipewtargetpaintermc2.py b/eos/effects/minmatarshipewtargetpaintermc2.py
index 7cc33c2a7..7867bcd1c 100644
--- a/eos/effects/minmatarshipewtargetpaintermc2.py
+++ b/eos/effects/minmatarshipewtargetpaintermc2.py
@@ -2,7 +2,6 @@
#
# Used by:
# Ship: Huginn
-# Ship: Rapier
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Minmatar Cruiser").level
diff --git a/eos/effects/modeagilitypostdiv.py b/eos/effects/modeagilitypostdiv.py
index d57571078..1f8ece16e 100644
--- a/eos/effects/modeagilitypostdiv.py
+++ b/eos/effects/modeagilitypostdiv.py
@@ -1,7 +1,7 @@
# modeAgilityPostDiv
#
# Used by:
-# Modules named like: Propulsion Mode (2 of 2)
+# Modules named like: Propulsion Mode (3 of 3)
type = "passive"
def handler(fit, module, context):
fit.ship.multiplyItemAttr(
diff --git a/eos/effects/modearmorresonancepostdiv.py b/eos/effects/modearmorresonancepostdiv.py
index b24e6b14e..27121df39 100644
--- a/eos/effects/modearmorresonancepostdiv.py
+++ b/eos/effects/modearmorresonancepostdiv.py
@@ -1,7 +1,8 @@
# modeArmorResonancePostDiv
#
# Used by:
-# Modules named like: Defense Mode (2 of 2)
+# Module: Confessor Defense Mode
+# Module: Svipul Defense Mode
type = "passive"
def handler(fit, module, context):
for srcResType, tgtResType in (
diff --git a/eos/effects/modeshieldresonancepostdiv.py b/eos/effects/modeshieldresonancepostdiv.py
index a40c3c78a..de5de9343 100644
--- a/eos/effects/modeshieldresonancepostdiv.py
+++ b/eos/effects/modeshieldresonancepostdiv.py
@@ -1,6 +1,7 @@
# modeShieldResonancePostDiv
#
# Used by:
+# Module: Jackdaw Defense Mode
# Module: Svipul Defense Mode
type = "passive"
def handler(fit, module, context):
diff --git a/eos/effects/modesigradiuspostdiv.py b/eos/effects/modesigradiuspostdiv.py
index 7522b2aaf..2b1dcfb88 100644
--- a/eos/effects/modesigradiuspostdiv.py
+++ b/eos/effects/modesigradiuspostdiv.py
@@ -2,7 +2,8 @@
#
# Used by:
# Module: Confessor Defense Mode
+# Module: Jackdaw Defense Mode
type = "passive"
def handler(fit, module, context):
- fit.ship.multiplyItemAttr("signatureRadius", 1/module.getModifiedItemAttr("modeSignatureRadiusPostDiv"),
- stackingPenalties = True, penaltyGroup="postDiv")
+ 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 14a4a5271..f3b1090ab 100644
--- a/eos/effects/modevelocitypostdiv.py
+++ b/eos/effects/modevelocitypostdiv.py
@@ -1,7 +1,7 @@
# modeVelocityPostDiv
#
# Used by:
-# Modules named like: Propulsion Mode (2 of 2)
+# Modules named like: Propulsion Mode (3 of 3)
type = "passive"
def handler(fit, module, context):
fit.ship.multiplyItemAttr(
diff --git a/eos/effects/overloadselfspeedbonus.py b/eos/effects/overloadselfspeedbonus.py
index 08a621729..53d17411a 100644
--- a/eos/effects/overloadselfspeedbonus.py
+++ b/eos/effects/overloadselfspeedbonus.py
@@ -1,7 +1,7 @@
# overloadSelfSpeedBonus
#
# Used by:
-# Modules from group: Propulsion Module (107 of 107)
+# Modules from group: Propulsion Module (114 of 114)
type = "overheat"
def handler(fit, module, context):
module.boostItemAttr("speedFactor", module.getModifiedItemAttr("overloadSpeedFactorBonus"),
diff --git a/eos/effects/probelaunchercpupercentbonustacticaldestroyer.py b/eos/effects/probelaunchercpupercentbonustacticaldestroyer.py
index 808c13098..05cd1f11c 100644
--- a/eos/effects/probelaunchercpupercentbonustacticaldestroyer.py
+++ b/eos/effects/probelaunchercpupercentbonustacticaldestroyer.py
@@ -1,7 +1,7 @@
# probeLauncherCPUPercentBonusTacticalDestroyer
#
# Used by:
-# Ships from group: Tactical Destroyer (2 of 2)
+# Ships from group: Tactical Destroyer (3 of 3)
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Astrometrics"),
diff --git a/eos/effects/shieldcapacitybonusonline.py b/eos/effects/shieldcapacitybonusonline.py
index be433f63a..caf100297 100644
--- a/eos/effects/shieldcapacitybonusonline.py
+++ b/eos/effects/shieldcapacitybonusonline.py
@@ -2,7 +2,7 @@
#
# Used by:
# Modules from group: Shield Amplifier (88 of 88)
-# Modules from group: Shield Extender (37 of 37)
+# Modules from group: Shield Extender (25 of 25)
type = "passive"
def handler(fit, module, context):
fit.ship.increaseItemAttr("shieldCapacity", module.getModifiedItemAttr("capacityBonus"))
\ No newline at end of file
diff --git a/eos/effects/shipbonusheavyassaultmissilealldamagemc2.py b/eos/effects/shipbonusheavyassaultmissilealldamagemc2.py
new file mode 100644
index 000000000..5f089797f
--- /dev/null
+++ b/eos/effects/shipbonusheavyassaultmissilealldamagemc2.py
@@ -0,0 +1,11 @@
+# shipBonusHeavyAssaultMissileAllDamageMC2
+#
+# Used by:
+# Ship: Rapier
+# Ship: Scythe Fleet Issue
+type = "passive"
+def handler(fit, ship, context):
+ level = fit.character.getSkill("Minmatar Cruiser").level
+ for damageType in ("em", "explosive", "kinetic", "thermal"):
+ fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Heavy Assault Missiles"),
+ "{0}Damage".format(damageType), ship.getModifiedItemAttr("shipBonusMC2") * level)
diff --git a/eos/effects/shipbonusheavymissilealldamagemc2.py b/eos/effects/shipbonusheavymissilealldamagemc2.py
new file mode 100644
index 000000000..ed2309bef
--- /dev/null
+++ b/eos/effects/shipbonusheavymissilealldamagemc2.py
@@ -0,0 +1,11 @@
+# shipBonusHeavyMissileAllDamageMC2
+#
+# Used by:
+# Ship: Rapier
+# Ship: Scythe Fleet Issue
+type = "passive"
+def handler(fit, ship, context):
+ level = fit.character.getSkill("Minmatar Cruiser").level
+ for damageType in ("em", "explosive", "kinetic", "thermal"):
+ fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Heavy Missiles"),
+ "{0}Damage".format(damageType), ship.getModifiedItemAttr("shipBonusMC2") * level)
diff --git a/eos/effects/shipbonuslightmissilealldamagemc2.py b/eos/effects/shipbonuslightmissilealldamagemc2.py
new file mode 100644
index 000000000..43cd3189c
--- /dev/null
+++ b/eos/effects/shipbonuslightmissilealldamagemc2.py
@@ -0,0 +1,11 @@
+# shipBonusLightMissileAllDamageMC2
+#
+# Used by:
+# Ship: Rapier
+# Ship: Scythe Fleet Issue
+type = "passive"
+def handler(fit, ship, context):
+ level = fit.character.getSkill("Minmatar Cruiser").level
+ for damageType in ("em", "explosive", "kinetic", "thermal"):
+ fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Light Missiles"),
+ "{0}Damage".format(damageType), ship.getModifiedItemAttr("shipBonusMC2") * level)
diff --git a/eos/effects/shipbonusrhmlrofcb.py b/eos/effects/shipbonusrhmlrofcb.py
new file mode 100644
index 000000000..c1a1f4c5f
--- /dev/null
+++ b/eos/effects/shipbonusrhmlrofcb.py
@@ -0,0 +1,5 @@
+type = "passive"
+def handler(fit, ship, context):
+ level = fit.character.getSkill("Caldari Battleship").level
+ fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Missile Launcher Rapid Heavy",
+ "speed", ship.getModifiedItemAttr("shipBonusCB") * level)
diff --git a/eos/effects/shipheatdamagecaldaritacticaldestroyer3.py b/eos/effects/shipheatdamagecaldaritacticaldestroyer3.py
new file mode 100644
index 000000000..16ae36618
--- /dev/null
+++ b/eos/effects/shipheatdamagecaldaritacticaldestroyer3.py
@@ -0,0 +1,9 @@
+# shipHeatDamageCaldariTacticalDestroyer3
+#
+# Used by:
+# Ship: Jackdaw
+type = "passive"
+def handler(fit, ship, context):
+ level = fit.character.getSkill("Caldari Tactical Destroyer").level
+ fit.modules.filteredItemBoost(lambda mod: True, "heatDamage",
+ ship.getModifiedItemAttr("shipBonusTacticalDestroyerCaldari3") * level)
diff --git a/eos/effects/shipmissilebonusemdmgmc.py b/eos/effects/shipmissilebonusemdmgmc.py
deleted file mode 100644
index 1230c3f94..000000000
--- a/eos/effects/shipmissilebonusemdmgmc.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# 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
deleted file mode 100644
index cdaa2637d..000000000
--- a/eos/effects/shipmissilebonusexpdmgmc.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# 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
deleted file mode 100644
index c4173ca36..000000000
--- a/eos/effects/shipmissilebonuskindmgmc.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# 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
deleted file mode 100644
index 90a8c3daa..000000000
--- a/eos/effects/shipmissilebonusthermdmgmc.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# 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/shipmissileemdamagemc2.py b/eos/effects/shipmissileemdamagemc2.py
deleted file mode 100644
index bf1b3bca0..000000000
--- a/eos/effects/shipmissileemdamagemc2.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# shipMissileEMDamageMC2
-#
-# Used by:
-# Ship: Scythe Fleet Issue
-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("shipBonusMC2") * level)
diff --git a/eos/effects/shipmissileexpdamagemc2.py b/eos/effects/shipmissileexpdamagemc2.py
deleted file mode 100644
index 774290e88..000000000
--- a/eos/effects/shipmissileexpdamagemc2.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# shipMissileExpDamageMC2
-#
-# Used by:
-# Ship: Scythe Fleet Issue
-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("shipBonusMC2") * level)
diff --git a/eos/effects/shipmissilekineticdamagemc2.py b/eos/effects/shipmissilekineticdamagemc2.py
deleted file mode 100644
index 5a0a4f716..000000000
--- a/eos/effects/shipmissilekineticdamagemc2.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# shipMissileKineticDamageMC2
-#
-# Used by:
-# Ship: Scythe Fleet Issue
-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("shipBonusMC2") * level)
diff --git a/eos/effects/shipmissilereloadtimecaldaritacticaldestroyer2.py b/eos/effects/shipmissilereloadtimecaldaritacticaldestroyer2.py
new file mode 100644
index 000000000..25ad3540e
--- /dev/null
+++ b/eos/effects/shipmissilereloadtimecaldaritacticaldestroyer2.py
@@ -0,0 +1,9 @@
+# shipMissileReloadTimeCaldariTacticalDestroyer2
+#
+# Used by:
+# Ship: Jackdaw
+type = "passive"
+def handler(fit, ship, context):
+ level = fit.character.getSkill("Caldari Tactical Destroyer").level
+ fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Missile Launcher Operation"),
+ "reloadTime", ship.getModifiedItemAttr("shipBonusTacticalDestroyerCaldari2") * level)
diff --git a/eos/effects/shipmissilerofcaldaritacticaldestroyer1.py b/eos/effects/shipmissilerofcaldaritacticaldestroyer1.py
new file mode 100644
index 000000000..1dd592339
--- /dev/null
+++ b/eos/effects/shipmissilerofcaldaritacticaldestroyer1.py
@@ -0,0 +1,11 @@
+# shipMissileRoFCaldariTacticalDestroyer1
+#
+# Used by:
+# Ship: Jackdaw
+type = "passive"
+def handler(fit, ship, context):
+ level = fit.character.getSkill("Caldari Tactical Destroyer").level
+ fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Missile Launcher Operation"),
+ "speed", ship.getModifiedItemAttr("shipBonusTacticalDestroyerCaldari1") * level)
+
+
diff --git a/eos/effects/shipmissilethermdamagemc2.py b/eos/effects/shipmissilethermdamagemc2.py
deleted file mode 100644
index 6f87ba285..000000000
--- a/eos/effects/shipmissilethermdamagemc2.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# shipMissileThermDamageMC2
-#
-# Used by:
-# Ship: Scythe Fleet Issue
-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("shipBonusMC2") * level)
diff --git a/eos/effects/shipmodemaxtargetrangepostdiv.py b/eos/effects/shipmodemaxtargetrangepostdiv.py
index 573574fe7..4e160e1cc 100644
--- a/eos/effects/shipmodemaxtargetrangepostdiv.py
+++ b/eos/effects/shipmodemaxtargetrangepostdiv.py
@@ -1,7 +1,7 @@
# shipModeMaxTargetRangePostDiv
#
# Used by:
-# Modules named like: Sharpshooter Mode (2 of 2)
+# Modules named like: Sharpshooter Mode (3 of 3)
type = "passive"
def handler(fit, module, context):
fit.ship.multiplyItemAttr(
diff --git a/eos/effects/shipmodemissilevelocitypostdiv.py b/eos/effects/shipmodemissilevelocitypostdiv.py
new file mode 100644
index 000000000..e713dd801
--- /dev/null
+++ b/eos/effects/shipmodemissilevelocitypostdiv.py
@@ -0,0 +1,13 @@
+# shipModeMissileVelocityPostDiv
+#
+# Used by:
+# Module: Jackdaw Sharpshooter Mode
+type = "passive"
+def handler(fit, module, context):
+ fit.modules.filteredChargeMultiply(
+ lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"),
+ "maxVelocity",
+ 1 / module.getModifiedItemAttr("modeMaxRangePostDiv"),
+ stackingPenalties=True,
+ penaltyGroup="postDiv"
+ )
diff --git a/eos/effects/shipmodescanrespostdiv.py b/eos/effects/shipmodescanrespostdiv.py
index f418fa328..d7cc9b72a 100644
--- a/eos/effects/shipmodescanrespostdiv.py
+++ b/eos/effects/shipmodescanrespostdiv.py
@@ -1,7 +1,7 @@
# shipModeScanResPostDiv
#
# Used by:
-# Modules named like: Sharpshooter Mode (2 of 2)
+# Modules named like: Sharpshooter Mode (3 of 3)
type = "passive"
def handler(fit, module, context):
fit.ship.multiplyItemAttr(
diff --git a/eos/effects/shipmodescanstrengthpostdiv.py b/eos/effects/shipmodescanstrengthpostdiv.py
index e42d5f69c..7e4613108 100644
--- a/eos/effects/shipmodescanstrengthpostdiv.py
+++ b/eos/effects/shipmodescanstrengthpostdiv.py
@@ -1,7 +1,7 @@
# shipModeScanStrengthPostDiv
#
# Used by:
-# Modules named like: Sharpshooter Mode (2 of 2)
+# Modules named like: Sharpshooter Mode (3 of 3)
type = "passive"
def handler(fit, module, context):
for scanType in ("Gravimetric", "Magnetometric", "Radar", "Ladar"):
diff --git a/eos/effects/shipsmallmissiledmgpiratefaction.py b/eos/effects/shipsmallmissiledmgpiratefaction.py
new file mode 100644
index 000000000..ecafce21e
--- /dev/null
+++ b/eos/effects/shipsmallmissiledmgpiratefaction.py
@@ -0,0 +1,9 @@
+# shipSmallMissileDmgPirateFaction
+#
+# Used by:
+# Ship: Jackdaw
+type = "passive"
+def handler(fit, ship, context):
+ for damageType in ("em", "explosive", "kinetic", "thermal"):
+ fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Rockets") or mod.charge.requiresSkill("Light Missiles"),
+ "{0}Damage".format(damageType), ship.getModifiedItemAttr("shipBonusPirateFaction"))
diff --git a/eos/effects/speedboostmassaddition.py b/eos/effects/speedboostmassaddition.py
index 49869ae95..c8dd1b62a 100644
--- a/eos/effects/speedboostmassaddition.py
+++ b/eos/effects/speedboostmassaddition.py
@@ -1,10 +1,9 @@
# speedBoostMassAddition
#
# Used by:
-# Variations of module: 100MN Afterburner I (24 of 24)
-# Variations of module: 10MN Afterburner I (14 of 14)
-# Variations of module: 1MN Afterburner I (15 of 15)
-# Module: Civilian Afterburner
+# Variations of module: 100MN Afterburner I (25 of 25)
+# Variations of module: 10MN Afterburner I (15 of 15)
+# Variations of module: 1MN Afterburner I (16 of 16)
type = "active"
runTime = "late"
def handler(fit, module, context):
diff --git a/eos/effects/speedboostmasssigrad.py b/eos/effects/speedboostmasssigrad.py
index b15ab26c5..26f9614f3 100644
--- a/eos/effects/speedboostmasssigrad.py
+++ b/eos/effects/speedboostmasssigrad.py
@@ -1,9 +1,9 @@
# speedBoostMassSigRad
#
# Used by:
-# Variations of module: 100MN Microwarpdrive I (24 of 24)
-# Variations of module: 10MN Microwarpdrive I (14 of 14)
-# Variations of module: 1MN Microwarpdrive I (15 of 15)
+# Variations of module: 500MN Microwarpdrive I (26 of 26)
+# Variations of module: 50MN Microwarpdrive I (16 of 16)
+# Variations of module: 5MN Microwarpdrive I (16 of 16)
type = "active"
runTime = "late"
def handler(fit, module, context):
diff --git a/eos/effects/triagemodeeffect3.py b/eos/effects/triagemodeeffect3.py
index dbb95a00a..bc33ee55c 100644
--- a/eos/effects/triagemodeeffect3.py
+++ b/eos/effects/triagemodeeffect3.py
@@ -3,6 +3,7 @@
# Used by:
# Module: Triage Module I
type = "active"
+runTime = "early"
def handler(fit, module, context):
# Remote armor reps
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Remote Armor Repair Systems"),
diff --git a/eos/effects/triagemodeeffect7.py b/eos/effects/triagemodeeffect7.py
index 196af8891..c84c95a5c 100644
--- a/eos/effects/triagemodeeffect7.py
+++ b/eos/effects/triagemodeeffect7.py
@@ -3,6 +3,7 @@
# Used by:
# Module: Triage Module II
type = "active"
+runTime = "early"
def handler(fit, module, context):
# Remote armor reps
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Remote Armor Repair Systems"),
diff --git a/eos/saveddata/fit.py b/eos/saveddata/fit.py
index f49c1f60e..f8328371f 100644
--- a/eos/saveddata/fit.py
+++ b/eos/saveddata/fit.py
@@ -295,7 +295,7 @@ class Fit(object):
@validates("ID", "ownerID", "shipID")
def validator(self, key, val):
map = {"ID": lambda val: isinstance(val, int),
- "ownerID" : lambda val: isinstance(val, int),
+ "ownerID" : lambda val: isinstance(val, int) or val is None,
"shipID" : lambda val: isinstance(val, int) or val is None}
if map[key](val) == False: raise ValueError(str(val) + " is not a valid value for " + key)
@@ -386,7 +386,8 @@ class Fit(object):
# Avoid adding projected drones and modules when fit is projected onto self
# TODO: remove this workaround when proper self-projection using virtual duplicate fits is implemented
if forceProjected is True:
- c = chain((self.character, self.ship, self.mode), self.drones, self.boosters, self.appliedImplants, self.modules)
+ # if fit is being projected onto another fit
+ c = chain((self.character, self.ship), self.drones, self.boosters, self.appliedImplants, self.modules)
else:
c = chain((self.character, self.ship, self.mode), self.drones, self.boosters, self.appliedImplants, self.modules,
self.projectedDrones, self.projectedModules)
diff --git a/eos/saveddata/ship.py b/eos/saveddata/ship.py
index f9585e1ab..03eeef3d4 100644
--- a/eos/saveddata/ship.py
+++ b/eos/saveddata/ship.py
@@ -112,7 +112,8 @@ class Ship(ItemAttrShortcut, HandledItem):
items = []
g = eos.db.getGroup(modeGroupID, eager=("items.icon", "items.attributes"))
for item in g.items:
- if item.raceID == self.item.raceID:
+ # Rely on name detection because race is not reliable
+ if item.name.lower().startswith(self.item.name.lower()):
items.append(item)
return items
diff --git a/gui/builtinStatsViews/resistancesViewFull.py b/gui/builtinStatsViews/resistancesViewFull.py
index e98696fb6..9a1df251f 100644
--- a/gui/builtinStatsViews/resistancesViewFull.py
+++ b/gui/builtinStatsViews/resistancesViewFull.py
@@ -74,9 +74,12 @@ class ResistancesViewFull(StatsView):
# Display table
col = 0
row = 0
- sizerResistances = wx.GridBagSizer()
+ sizerResistances = wx.GridBagSizer(0, 0)
contentSizer.Add( sizerResistances, 0, wx.EXPAND , 0)
+ for i in xrange(6):
+ sizerResistances.AddGrowableCol(i + 1)
+
# Add an empty label, then the rest.
sizerResistances.Add(wx.StaticText(contentPanel, wx.ID_ANY), wx.GBPosition( row, col ), wx.GBSpan( 1, 1 ))
col+=1
@@ -92,8 +95,6 @@ class ResistancesViewFull(StatsView):
self.stEHPs.Bind(wx.EVT_BUTTON, self.toggleEHP)
- for i in xrange(4):
- sizerResistances.AddGrowableCol(i+1)
sizerResistances.Add(self.stEHPs, wx.GBPosition( row, col ), wx.GBSpan( 1, 1 ), wx.ALIGN_CENTER)
col=0
diff --git a/gui/builtinStatsViews/targetingMiscViewFull.py b/gui/builtinStatsViews/targetingMiscViewFull.py
index ac0fc79e9..fc2673389 100644
--- a/gui/builtinStatsViews/targetingMiscViewFull.py
+++ b/gui/builtinStatsViews/targetingMiscViewFull.py
@@ -52,7 +52,7 @@ class TargetingMiscViewFull(StatsView):
gridTargetingMisc.AddGrowableCol(2)
# Targeting
- gridTargeting = wx.FlexGridSizer(5, 2)
+ gridTargeting = wx.FlexGridSizer(4, 2)
gridTargeting.AddGrowableCol(1)
gridTargetingMisc.Add(gridTargeting, 0, wx.ALIGN_LEFT | wx.ALL, 5)
@@ -77,7 +77,7 @@ class TargetingMiscViewFull(StatsView):
# Misc
gridTargetingMisc.Add( wx.StaticLine( contentPanel, wx.ID_ANY, style = wx.VERTICAL),0, wx.EXPAND, 3 )
- gridMisc = wx.FlexGridSizer(5, 2)
+ gridMisc = wx.FlexGridSizer(4, 2)
gridMisc.AddGrowableCol(1)
gridTargetingMisc.Add(gridMisc,0 , wx.ALIGN_LEFT | wx.ALL, 5)
diff --git a/gui/builtinViewColumns/ammoIcon.py b/gui/builtinViewColumns/ammoIcon.py
index 19d55364e..1dfddf791 100644
--- a/gui/builtinViewColumns/ammoIcon.py
+++ b/gui/builtinViewColumns/ammoIcon.py
@@ -27,7 +27,7 @@ class AmmoIcon(ViewColumn):
name = "Ammo Icon"
def __init__(self, fittingView, params):
ViewColumn.__init__(self, fittingView)
- self.size = 24
+ self.size = 16
self.maxsize = self.size
self.mask = wx.LIST_MASK_IMAGE
self.columnText = ""
diff --git a/gui/builtinViewColumns/baseIcon.py b/gui/builtinViewColumns/baseIcon.py
index 975267f4a..5f88227a6 100644
--- a/gui/builtinViewColumns/baseIcon.py
+++ b/gui/builtinViewColumns/baseIcon.py
@@ -8,7 +8,7 @@ class BaseIcon(ViewColumn):
name = "Base Icon"
def __init__(self, fittingView, params):
ViewColumn.__init__(self, fittingView)
- self.size = 24
+ self.size = 16
self.maxsize = self.size
self.mask = wx.LIST_MASK_IMAGE
self.columnText = ""
diff --git a/gui/characterEditor.py b/gui/characterEditor.py
index d8da9ccd1..55fa8d403 100644
--- a/gui/characterEditor.py
+++ b/gui/characterEditor.py
@@ -92,10 +92,10 @@ class CharacterEditor(wx.Frame):
self.viewsNBContainer = wx.Notebook(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, 0)
self.sview = SkillTreeView(self.viewsNBContainer)
- self.iview = ImplantsTreeView(self.viewsNBContainer)
+ #self.iview = ImplantsTreeView(self.viewsNBContainer)
#=======================================================================
# RC2
- self.iview.Show(False)
+ #self.iview.Show(False)
#=======================================================================
self.aview = APIView(self.viewsNBContainer)
@@ -148,6 +148,7 @@ class CharacterEditor(wx.Frame):
def restrict(self):
self.btnRename.Enable(False)
self.btnDelete.Enable(False)
+ self.aview.stDisabledTip.Show(True)
self.aview.inputID.Enable(False)
self.aview.inputKey.Enable(False)
self.aview.charChoice.Enable(False)
@@ -159,6 +160,7 @@ class CharacterEditor(wx.Frame):
def unrestrict(self):
self.btnRename.Enable(True)
self.btnDelete.Enable(True)
+ self.aview.stDisabledTip.Show(False)
self.aview.inputID.Enable(True)
self.aview.inputKey.Enable(True)
self.aview.btnFetchCharList.Enable(True)
@@ -269,6 +271,7 @@ class CharacterEditor(wx.Frame):
class SkillTreeView (wx.Panel):
def __init__(self, parent):
wx.Panel.__init__ (self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.Size(500, 300), style=wx.TAB_TRAVERSAL)
+ self.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
pmainSizer = wx.BoxSizer(wx.VERTICAL)
@@ -528,12 +531,23 @@ class APIView (wx.Panel):
def __init__(self, parent):
wx.Panel.__init__ (self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.Size(500, 300), style=wx.TAB_TRAVERSAL)
self.Parent.Parent.Bind(GE.CHAR_CHANGED, self.charChanged)
+ self.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
self.apiUrlCreatePredefined = u"https://community.eveonline.com/support/api-key/CreatePredefined?accessMask=8"
self.apiUrlKeyList = u"https://community.eveonline.com/support/api-key/"
pmainSizer = wx.BoxSizer(wx.VERTICAL)
+ hintSizer = wx.BoxSizer( wx.HORIZONTAL )
+ hintSizer.AddStretchSpacer()
+ self.stDisabledTip = wx.StaticText( self, wx.ID_ANY, u"You cannot add API Details for All 0 and All 5 characters.\n"
+ u"Please select another character or make a new one.", style=wx.ALIGN_CENTER )
+ self.stDisabledTip.Wrap( -1 )
+ hintSizer.Add( self.stDisabledTip, 0, wx.TOP | wx.BOTTOM, 10 )
+ hintSizer.AddStretchSpacer()
+ pmainSizer.Add(hintSizer, 0, wx.EXPAND, 5)
+
+
fgSizerInput = wx.FlexGridSizer(3, 2, 0, 0)
fgSizerInput.AddGrowableCol(1)
fgSizerInput.SetFlexibleDirection(wx.BOTH)
diff --git a/gui/chromeTabs.py b/gui/chromeTabs.py
index eaab63b3e..49946c453 100644
--- a/gui/chromeTabs.py
+++ b/gui/chromeTabs.py
@@ -671,8 +671,6 @@ class PFTabsContainer(wx.Panel):
"""
wx.Panel.__init__(self, parent, id, pos, size)
- if wx.VERSION >= (3,0):
- self.SetBackgroundStyle(wx.BG_STYLE_PAINT)
self.tabs = []
width, height = size
diff --git a/gui/pyfatogglepanel.py b/gui/pyfatogglepanel.py
index 7cf088b24..ce92f10c8 100644
--- a/gui/pyfatogglepanel.py
+++ b/gui/pyfatogglepanel.py
@@ -146,6 +146,7 @@ class TogglePanel ( wx.Panel ):
else:
return True
+
def IsExpanded(self):
""" Returns ``True`` if the pane window is currently shown. """
if self._toggle == 1:
@@ -153,6 +154,7 @@ class TogglePanel ( wx.Panel ):
else:
return True
+
def OnStateChange(self, sz):
"""
Handles the status changes (collapsing/expanding).
@@ -166,8 +168,9 @@ class TogglePanel ( wx.Panel ):
self.parent.GetSizer().SetSizeHints(self.parent)
+
if self.IsCollapsed():
- # expanded . collapsed transition
+ # expanded . collapsed transition
if self.parent.GetSizer():
# we have just set the size hints...
sz = self.parent.GetSizer().CalcMin()
@@ -175,36 +178,39 @@ class TogglePanel ( wx.Panel ):
# use SetClientSize() and not SetSize() otherwise the size for
# e.g. a wxFrame with a menubar wouldn't be correctly set
self.parent.SetClientSize(sz)
+
else:
self.parent.Layout()
+
else:
- # collapsed . expanded transition
- # force our parent to "fit", i.e. expand so that it can honour
- # our minimal size
+
+ # collapsed . expanded transition
+
+ # force our parent to "fit", i.e. expand so that it can honour
+ # our minimal size
self.parent.Fit()
+
# Toggle the content panel (hide/show)
- def toggleContent(self, event):
+
+ def toggleContent( self, event ):
self.Freeze()
- print self.contentPanel.GetSize()
if self._toggle == 1:
self.contentMinSize = self.contentPanel.GetSize()
- self.contentPanel.Hide()
- self.headerBmp.SetBitmap(self.bmpCollapsed)
- else:
- self.contentPanel.Show()
- self.headerBmp.SetBitmap(self.bmpExpanded)
+ self.contentPanel.SetMinSize(wx.Size(self.contentMinSize[0],0))
+ self.headerBmp.SetBitmap( self.bmpCollapsed)
+
+
+ else:
+ self.contentPanel.SetMinSize(self.contentMinSize)
+
+ self.headerBmp.SetBitmap( self.bmpExpanded)
+
+
+ self._toggle *=-1
- self._toggle *= -1
- self.Layout()
self.Thaw()
-
if self.forceLayout == -1:
- if wx.VERSION >= (3, 0):
- x, y = self.GetBestSize()
- y -= self.contentPanel.GetSize()[1]
- else:
- x, y = self.GetBestSize()
- self.OnStateChange((x, y))
+ self.OnStateChange(self.GetBestSize())
else:
- self.parent.Layout()
\ No newline at end of file
+ self.parent.Layout()
diff --git a/gui/shipBrowser.py b/gui/shipBrowser.py
index 8f1b40834..5e59e6c83 100644
--- a/gui/shipBrowser.py
+++ b/gui/shipBrowser.py
@@ -15,7 +15,6 @@ import gui.utils.animEffects as animEffects
import gui.sfBrowserItem as SFItem
from gui.contextMenu import ContextMenu
-import gui.utils.fonts as fonts
import service
import gui.utils.fonts as fonts
@@ -940,11 +939,12 @@ class ShipBrowser(wx.Panel):
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())
+ self.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
mainSizer = wx.BoxSizer(wx.VERTICAL)
text = wx.StaticText( self, wx.ID_ANY, label, wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_CENTRE )
text.Wrap( -1 )
- mainSizer.Add( text, 1, wx.EXPAND|wx.TOP, 10 )
+ mainSizer.Add( text, 1, wx.ALL, 10 )
self.SetSizer(mainSizer)
self.Layout()
def GetType(self):
@@ -1427,9 +1427,6 @@ class FitItem(SFItem.SFBrowserItem):
self.deleted = False
- # @todo: replace all getActiveFit() in class with this variable and test
- self.activeFit = self.mainFrame.getActiveFit()
-
if shipID:
self.shipBmp = bitmapLoader.getBitmap(str(shipID),"ships")
@@ -1442,19 +1439,6 @@ class FitItem(SFItem.SFBrowserItem):
# see GH issue #62
if self.fitBooster is None: self.fitBooster = False
- # access these by index based on toggle for booster fit
-
- self.fitMenu = wx.Menu()
- self.toggleItem = self.fitMenu.Append(-1, "Booster Fit", kind=wx.ITEM_CHECK)
- self.fitMenu.Check(self.toggleItem.GetId(), self.fitBooster)
- self.Bind(wx.EVT_MENU, self.OnPopupItemSelected, self.toggleItem)
-
- if self.activeFit:
- # If there is an active fit, get menu for setting individual boosters
- self.fitMenu.AppendSeparator()
- boosterMenu = self.mainFrame.additionsPane.gangPage.FitDNDPopupMenu
- self.fitMenu.AppendMenu(wx.ID_ANY, 'Set Booster', boosterMenu)
-
self.boosterBmp = bitmapLoader.getBitmap("fleet_fc_small", "icons")
self.copyBmp = bitmapLoader.getBitmap("fit_add_small", "icons")
self.renameBmp = bitmapLoader.getBitmap("fit_rename_small", "icons")
@@ -1531,14 +1515,12 @@ class FitItem(SFItem.SFBrowserItem):
self.Bind(wx.EVT_RIGHT_UP, self.OnContextMenu)
- def OnPopupItemSelected(self, event):
- ''' Fires when fit menu item is selected '''
- # currently only have one menu option (toggle booster)
+ def OnToggleBooster(self, event):
sFit = service.Fit.getInstance()
sFit.toggleBoostFit(self.fitID)
self.fitBooster = not self.fitBooster
self.boosterBtn.Show(self.fitBooster)
- self.fitMenu.Check(self.toggleItem.GetId(), self.fitBooster)
+ self.Refresh()
wx.PostEvent(self.mainFrame, BoosterListUpdated())
event.Skip()
@@ -1546,9 +1528,23 @@ class FitItem(SFItem.SFBrowserItem):
''' Handles context menu for fit. Dragging is handled by MouseLeftUp() '''
pos = wx.GetMousePosition()
pos = self.ScreenToClient(pos)
+
# Even though we may not select a booster, automatically set this so that the fleet pane knows which fit we're applying
self.mainFrame.additionsPane.gangPage.draggedFitID = self.fitID
- self.PopupMenu(self.fitMenu, pos)
+
+ menu = wx.Menu()
+ toggleItem = menu.Append(wx.ID_ANY, "Booster Fit", kind=wx.ITEM_CHECK)
+ menu.Check(toggleItem.GetId(), self.fitBooster)
+
+ self.Bind(wx.EVT_MENU, self.OnToggleBooster, toggleItem)
+
+ if self.mainFrame.getActiveFit():
+ # If there is an active fit, get menu for setting individual boosters
+ menu.AppendSeparator()
+ boosterMenu = self.mainFrame.additionsPane.gangPage.FitDNDPopupMenu
+ menu.AppendSubMenu(boosterMenu, 'Set Booster')
+
+ self.PopupMenu(menu, pos)
event.Skip()
diff --git a/gui/utils/fonts.py b/gui/utils/fonts.py
index eb2dd95f5..08f858f21 100644
--- a/gui/utils/fonts.py
+++ b/gui/utils/fonts.py
@@ -1,8 +1,3 @@
-'''
-Font file to handle the differences in font calculations between
-different wxPython versions
-'''
-
import wx
if 'wxMac' in wx.PlatformInfo:
diff --git a/pyfa.py b/pyfa.py
index 1d954ecfe..e112ba06b 100755
--- a/pyfa.py
+++ b/pyfa.py
@@ -31,9 +31,9 @@ if not hasattr(sys, 'frozen'):
try:
import wxversion
except ImportError:
- print("Cannot find wxPython\nYou can download wxPython (2.8+) from http://www.wxpython.org/")
+ print("Cannot find wxPython\nYou can download wxPython (2.8) from http://www.wxpython.org/")
sys.exit(1)
-
+
# if user wants to force 2.8, try that and go directly to ensureMinimal path if fails
try:
if getattr(config.configforced, "force28", False):
@@ -48,10 +48,10 @@ if not hasattr(sys, 'frozen'):
try:
wxversion.ensureMinimal('2.8')
except wxversion.VersionError:
- print "Installed wxPython version doesn't meet requirements.\nYou can download wxPython (2.8+) from http://www.wxpython.org/"
+ print("Installed wxPython version doesn't meet requirements.\nYou can download wxPython (2.8) from http://www.wxpython.org/")
sys.exit(1)
else:
- print "wxPython 2.8 not found; attempting to use newer version, expect errors"
+ print("wxPython 2.8 not found; attempting to use newer version, expect errors")
try:
import sqlalchemy
diff --git a/scripts/jsonToSql.py b/scripts/jsonToSql.py
index 23f037db6..07b6cbc94 100755
--- a/scripts/jsonToSql.py
+++ b/scripts/jsonToSql.py
@@ -1,202 +1,208 @@
-#!/usr/bin/env python
-#======================================================================
-# Copyright (C) 2012 Diego Duclos
-#
-# This file is part of eos.
-#
-# eos is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as
-# published by the Free Software Foundation, either version 3 of
-# the License, or (at your option) any later version.
-#
-# eos is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with eos. If not, see .
-#======================================================================
-
-import os
-import sys
-
-# Add eos root path to sys.path so we can import ourselves
-path = os.path.dirname(unicode(__file__, sys.getfilesystemencoding()))
-sys.path.append(os.path.realpath(os.path.join(path, "..")))
-
-import json
-import argparse
-
-def main(db, json_path):
-
- jsonPath = os.path.expanduser(json_path)
-
- # Import eos.config first and change it
- import eos.config
- eos.config.gamedata_connectionstring = db
- eos.config.debug = False
-
- # Now thats done, we can import the eos modules using the config
- import eos.db
- import eos.gamedata
-
- # Create the database tables
- eos.db.gamedata_meta.create_all()
-
- # Config dict
- tables = {
- "dgmattribs": eos.gamedata.AttributeInfo,
- "dgmeffects": eos.gamedata.EffectInfo,
- "dgmtypeattribs": eos.gamedata.Attribute,
- "dgmtypeeffects": eos.gamedata.Effect,
- "dgmunits": eos.gamedata.Unit,
- "icons": eos.gamedata.Icon,
- "invcategories": eos.gamedata.Category,
- "invgroups": eos.gamedata.Group,
- "invmetagroups": eos.gamedata.MetaGroup,
- "invmetatypes": eos.gamedata.MetaType,
- "invtypes": eos.gamedata.Item,
- "phbtraits": eos.gamedata.Traits,
- "phbmetadata": eos.gamedata.MetaData,
- "mapbulk_marketGroups": eos.gamedata.MarketGroup
- }
-
- fieldMapping = {
- "dgmattribs": {
- "displayName_en-us": "displayName"
- },
- "dgmeffects": {
- "displayName_en-us": "displayName",
- "description_en-us": "description"
- },
- "dgmunits": {
- "displayName_en-us": "displayName"
- },
- #icons???
- "invcategories": {
- "categoryName_en-us": "categoryName"
- },
- "invgroups": {
- "groupName_en-us": "groupName"
- },
- "invmetagroups": {
- "metaGroupName_en-us": "metaGroupName"
- },
- "invtypes": {
- "typeName_en-us": "typeName",
- "description_en-us": "description"
- },
- #phbtraits???
- "mapbulk_marketGroups": {
- "marketGroupName_en-us": "marketGroupName",
- "description_en-us": "description"
- }
-
- }
-
- def convertIcons(data):
- new = []
- for k, v in data.items():
- v["iconID"] = k
- new.append(v)
- return new
-
- def convertTraits(data):
-
- def convertSection(sectionData):
- sectionLines = []
- headerText = u"{}".format(sectionData["header"])
- sectionLines.append(headerText)
- for bonusData in sectionData["bonuses"]:
- prefix = u"{} ".format(bonusData["number"]) if "number" in bonusData else ""
- bonusText = u"{}{}".format(prefix, bonusData["text"].replace(u"\u00B7", u"\u2022 "))
- sectionLines.append(bonusText)
- sectionLine = u"
\n".join(sectionLines)
- return sectionLine
-
- newData = []
- for row in data:
- typeLines = []
- typeId = row["typeID"]
- traitData = row["traits_en-us"]
- for skillData in sorted(traitData.get("skills", ()), key=lambda i: i["header"]):
- typeLines.append(convertSection(skillData))
- if "role" in traitData:
- typeLines.append(convertSection(traitData["role"]))
- if "misc" in traitData:
- typeLines.append(convertSection(traitData["misc"]))
- traitLine = u"
\n
\n".join(typeLines)
- newRow = {"typeID": typeId, "traitText": traitLine}
- newData.append(newRow)
- return newData
-
- def convertTypes(typesData):
- """
- Add factionID column to invtypes table.
- """
- factionMap = {}
- with open(os.path.join(jsonPath, "fsdTypeOverrides.json")) as f:
- overridesData = json.load(f)
- for typeID, typeData in overridesData.items():
- factionID = typeData.get("factionID")
- if factionID is not None:
- factionMap[int(typeID)] = factionID
- for row in typesData:
- row['factionID'] = factionMap.get(int(row['typeID']))
- return typesData
-
- data = {}
-
- # Dump all data to memory so we can easely cross check ignored rows
- for jsonName, cls in tables.iteritems():
- with open(os.path.join(jsonPath, "{}.json".format(jsonName))) as f:
- tableData = json.load(f)
- if jsonName == "icons":
- tableData = convertIcons(tableData)
- if jsonName == "phbtraits":
- tableData = convertTraits(tableData)
- if jsonName == "invtypes":
- tableData = convertTypes(tableData)
- data[jsonName] = tableData
-
- # Set with typeIDs which we will have in our database
- invTypes = set()
- for row in data["invtypes"]:
- # 1306 - group Ship Modifiers, for items like tactical t3 ship modes
- if (row["published"] or row['groupID'] == 1306):
- invTypes.add(row["typeID"])
-
- # ignore checker
- def isIgnored(file, row):
- if file in ("invtypes", "dgmtypeeffects", "dgmtypeattribs", "invmetatypes") and row['typeID'] not in invTypes:
- return True
- return False
-
- # Loop through each json file and write it away, checking ignored rows
- for jsonName, table in data.iteritems():
- fieldMap = fieldMapping.get(jsonName, {})
- print "processing {}".format(jsonName)
- for row in table:
- # We don't care about some kind of rows, filter it out if so
- if not isIgnored(jsonName, row):
- instance = tables[jsonName]()
- # fix for issue 80
- if jsonName is "icons" and "res:/UI/Texture/Icons/" in str(row["iconFile"]):
- row["iconFile"] = row["iconFile"].replace("res:/UI/Texture/Icons/","").replace(".png", "")
- for k, v in row.iteritems():
- setattr(instance, fieldMap.get(k, k), v)
-
- eos.db.gamedata_session.add(instance)
-
- eos.db.gamedata_session.commit()
-
- print("done")
-
-if __name__ == "__main__":
- parser = argparse.ArgumentParser(description="This scripts dumps effects from an sqlite cache dump to mongo")
- parser.add_argument("-d", "--db", required=True, type=str, help="The sqlalchemy connectionstring, example: sqlite:///c:/tq.db")
- parser.add_argument("-j", "--json", required=True, type=str, help="The path to the json dump")
- args = parser.parse_args()
-
- main(args.db, args.json)
+#!/usr/bin/env python
+#======================================================================
+# Copyright (C) 2012 Diego Duclos
+#
+# This file is part of eos.
+#
+# eos is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# eos is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with eos. If not, see .
+#======================================================================
+
+import os
+import sys
+
+# Add eos root path to sys.path so we can import ourselves
+path = os.path.dirname(unicode(__file__, sys.getfilesystemencoding()))
+sys.path.append(os.path.realpath(os.path.join(path, "..")))
+
+import json
+import argparse
+
+def main(db, json_path):
+
+ jsonPath = os.path.expanduser(json_path)
+
+ # Import eos.config first and change it
+ import eos.config
+ eos.config.gamedata_connectionstring = db
+ eos.config.debug = False
+
+ # Now thats done, we can import the eos modules using the config
+ import eos.db
+ import eos.gamedata
+
+ # Create the database tables
+ eos.db.gamedata_meta.create_all()
+
+ # Config dict
+ tables = {
+ "dgmattribs": eos.gamedata.AttributeInfo,
+ "dgmeffects": eos.gamedata.EffectInfo,
+ "dgmtypeattribs": eos.gamedata.Attribute,
+ "dgmtypeeffects": eos.gamedata.Effect,
+ "dgmunits": eos.gamedata.Unit,
+ "icons": eos.gamedata.Icon,
+ "invcategories": eos.gamedata.Category,
+ "invgroups": eos.gamedata.Group,
+ "invmetagroups": eos.gamedata.MetaGroup,
+ "invmetatypes": eos.gamedata.MetaType,
+ "invtypes": eos.gamedata.Item,
+ "phbtraits": eos.gamedata.Traits,
+ "phbmetadata": eos.gamedata.MetaData,
+ "mapbulk_marketGroups": eos.gamedata.MarketGroup
+ }
+
+ fieldMapping = {
+ "dgmattribs": {
+ "displayName_en-us": "displayName"
+ },
+ "dgmeffects": {
+ "displayName_en-us": "displayName",
+ "description_en-us": "description"
+ },
+ "dgmunits": {
+ "displayName_en-us": "displayName"
+ },
+ #icons???
+ "invcategories": {
+ "categoryName_en-us": "categoryName"
+ },
+ "invgroups": {
+ "groupName_en-us": "groupName"
+ },
+ "invmetagroups": {
+ "metaGroupName_en-us": "metaGroupName"
+ },
+ "invtypes": {
+ "typeName_en-us": "typeName",
+ "description_en-us": "description"
+ },
+ #phbtraits???
+ "mapbulk_marketGroups": {
+ "marketGroupName_en-us": "marketGroupName",
+ "description_en-us": "description"
+ }
+
+ }
+
+ def convertIcons(data):
+ new = []
+ for k, v in data.items():
+ v["iconID"] = k
+ new.append(v)
+ return new
+
+ def convertTraits(data):
+
+ def convertSection(sectionData):
+ sectionLines = []
+ headerText = u"{}".format(sectionData["header"])
+ sectionLines.append(headerText)
+ for bonusData in sectionData["bonuses"]:
+ prefix = u"{} ".format(bonusData["number"]) if "number" in bonusData else ""
+ bonusText = u"{}{}".format(prefix, bonusData["text"].replace(u"\u00B7", u"\u2022 "))
+ sectionLines.append(bonusText)
+ sectionLine = u"
\n".join(sectionLines)
+ return sectionLine
+
+ newData = []
+ for row in data:
+ typeLines = []
+ typeId = row["typeID"]
+ traitData = row["traits_en-us"]
+ for skillData in sorted(traitData.get("skills", ()), key=lambda i: i["header"]):
+ typeLines.append(convertSection(skillData))
+ if "role" in traitData:
+ typeLines.append(convertSection(traitData["role"]))
+ if "misc" in traitData:
+ typeLines.append(convertSection(traitData["misc"]))
+ traitLine = u"
\n
\n".join(typeLines)
+ newRow = {"typeID": typeId, "traitText": traitLine}
+ newData.append(newRow)
+ return newData
+
+ def convertTypes(typesData):
+ """
+ Add factionID column to invtypes table.
+ """
+ factionMap = {}
+ with open(os.path.join(jsonPath, "fsdTypeOverrides.json")) as f:
+ overridesData = json.load(f)
+ for typeID, typeData in overridesData.items():
+ factionID = typeData.get("factionID")
+ if factionID is not None:
+ factionMap[int(typeID)] = factionID
+ for row in typesData:
+ row['factionID'] = factionMap.get(int(row['typeID']))
+ return typesData
+
+ data = {}
+
+ # Dump all data to memory so we can easely cross check ignored rows
+ for jsonName, cls in tables.iteritems():
+ with open(os.path.join(jsonPath, "{}.json".format(jsonName))) as f:
+ tableData = json.load(f)
+ if jsonName == "icons":
+ tableData = convertIcons(tableData)
+ if jsonName == "phbtraits":
+ tableData = convertTraits(tableData)
+ if jsonName == "invtypes":
+ tableData = convertTypes(tableData)
+ data[jsonName] = tableData
+
+ # Set with typeIDs which we will have in our database
+ invTypes = {
+ # Sometimes CCP unpublishes some items we want to have published, we
+ # can do it here
+ 31906, # Federation Navy 200mm Steel Plates
+ 31904, # Imperial Navy 200mm Steel Plates
+ 28782, # Syndicate 200mm Steel Plates
+ }
+ for row in data["invtypes"]:
+ # 1306 - group Ship Modifiers, for items like tactical t3 ship modes
+ if (row["published"] or row['groupID'] == 1306):
+ invTypes.add(row["typeID"])
+
+ # ignore checker
+ def isIgnored(file, row):
+ if file in ("invtypes", "dgmtypeeffects", "dgmtypeattribs", "invmetatypes") and row['typeID'] not in invTypes:
+ return True
+ return False
+
+ # Loop through each json file and write it away, checking ignored rows
+ for jsonName, table in data.iteritems():
+ fieldMap = fieldMapping.get(jsonName, {})
+ print "processing {}".format(jsonName)
+ for row in table:
+ # We don't care about some kind of rows, filter it out if so
+ if not isIgnored(jsonName, row):
+ instance = tables[jsonName]()
+ # fix for issue 80
+ if jsonName is "icons" and "res:/UI/Texture/Icons/" in str(row["iconFile"]):
+ row["iconFile"] = row["iconFile"].replace("res:/UI/Texture/Icons/","").replace(".png", "")
+ for k, v in row.iteritems():
+ setattr(instance, fieldMap.get(k, k), v)
+
+ eos.db.gamedata_session.add(instance)
+
+ eos.db.gamedata_session.commit()
+
+ print("done")
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(description="This scripts dumps effects from an sqlite cache dump to mongo")
+ parser.add_argument("-d", "--db", required=True, type=str, help="The sqlalchemy connectionstring, example: sqlite:///c:/tq.db")
+ parser.add_argument("-j", "--json", required=True, type=str, help="The path to the json dump")
+ args = parser.parse_args()
+
+ main(args.db, args.json)
diff --git a/service/conversions/releaseCarnyx.py b/service/conversions/releaseCarnyx.py
new file mode 100644
index 000000000..c23426f27
--- /dev/null
+++ b/service/conversions/releaseCarnyx.py
@@ -0,0 +1,146 @@
+"""
+Conversion pack for Carnyx Module Tiericide
+"""
+
+CONVERSIONS = {
+ # Renamed items
+ "1MN Microwarpdrive I": "5MN Microwarpdrive I",
+ "1MN Microwarpdrive II": "5MN Microwarpdrive II",
+ "Prototype 100MN Microwarpdrive I": "500MN Cold-Gas Enduring Microwarpdrive",
+ "Experimental 100MN Afterburner I": "100MN Monopropellant Enduring Afterburner",
+ "Upgraded 1MN Microwarpdrive I": "5MN Cold-Gas Enduring Microwarpdrive",
+ "Limited 1MN Microwarpdrive I": "5MN Y-T8 Compact Microwarpdrive",
+ "Experimental 10MN Microwarpdrive I": "50MN Cold-Gas Enduring Microwarpdrive",
+ "Limited 1MN Afterburner I": "1MN Y-S8 Compact Afterburner",
+ "Experimental 1MN Afterburner I": "1MN Monopropellant Enduring Afterburner",
+ "Experimental 10MN Afterburner I": "10MN Monopropellant Enduring Afterburner",
+ "Large Azeotropic Ward Salubrity I": "Large Azeotropic Restrained Shield Extender",
+ "Small Azeotropic Ward Salubrity I": "Small Azeotropic Restrained Shield Extender",
+ "Medium Azeotropic Ward Salubrity I": "Medium Azeotropic Restrained Shield Extender",
+ "Medium F-S9 Regolith Shield Induction": "Medium F-S9 Regolith Compact Shield Extender",
+ "Small F-S9 Regolith Shield Induction": "Small F-S9 Regolith Compact Shield Extender",
+ "Large F-S9 Regolith Shield Induction": "Large F-S9 Regolith Compact Shield Extender",
+ "1600mm Reinforced Steel Plates I": "1600mm Steel Plates I",
+ "100mm Reinforced Steel Plates I": "100mm Steel Plates I",
+ "200mm Reinforced Steel Plates I": "200mm Steel Plates I",
+ "400mm Reinforced Steel Plates I": "400mm Steel Plates I",
+ "800mm Reinforced Steel Plates I": "800mm Steel Plates I",
+ "400mm Reinforced Rolled Tungsten Plates I": "400mm Rolled Tungsten Compact Plates",
+ "400mm Reinforced Crystalline Carbonide Plates I": "400mm Crystalline Carbonide Restrained Plates",
+ "800mm Reinforced Rolled Tungsten Plates I": "800mm Rolled Tungsten Compact Plates",
+ "800mm Reinforced Crystalline Carbonide Plates I": "800mm Crystalline Carbonide Restrained Plates",
+ "1600mm Reinforced Rolled Tungsten Plates I": "1600mm Rolled Tungsten Compact Plates",
+ "1600mm Reinforced Crystalline Carbonide Plates I": "1600mm Crystalline Carbonide Restrained Plates",
+ "100mm Reinforced Rolled Tungsten Plates I": "100mm Rolled Tungsten Compact Plates",
+ "100mm Reinforced Crystalline Carbonide Plates I": "100mm Crystalline Carbonide Restrained Plates",
+ "200mm Reinforced Rolled Tungsten Plates I": "200mm Rolled Tungsten Compact Plates",
+ "200mm Reinforced Crystalline Carbonide Plates I": "200mm Crystalline Carbonide Restrained Plates",
+ "10MN Microwarpdrive I": "50MN Microwarpdrive I",
+ "100MN Microwarpdrive I": "500MN Microwarpdrive I",
+ "10MN Microwarpdrive II": "50MN Microwarpdrive II",
+ "100MN Microwarpdrive II": "500MN Microwarpdrive II",
+ "Domination 100MN Microwarpdrive": "Domination 500MN Microwarpdrive",
+ "Shadow Serpentis 100MN Microwarpdrive": "Shadow Serpentis 500MN Microwarpdrive",
+ "Domination 10MN Microwarpdrive": "Domination 50MN Microwarpdrive",
+ "Shadow Serpentis 10MN Microwarpdrive": "Shadow Serpentis 50MN Microwarpdrive",
+ "Domination 1MN Microwarpdrive": "Domination 5MN Microwarpdrive",
+ "Shadow Serpentis 1MN Microwarpdrive": "Shadow Serpentis 5MN Microwarpdrive",
+ "Mizuro's Modified 100MN Microwarpdrive": "Mizuro's Modified 500MN Microwarpdrive",
+ "Hakim's Modified 100MN Microwarpdrive": "Hakim's Modified 500MN Microwarpdrive",
+ "Gotan's Modified 100MN Microwarpdrive": "Gotan's Modified 500MN Microwarpdrive",
+ "Tobias' Modified 100MN Microwarpdrive": "Tobias' Modified 500MN Microwarpdrive",
+ "Brynn's Modified 100MN Microwarpdrive": "Brynn's Modified 500MN Microwarpdrive",
+ "Tuvan's Modified 100MN Microwarpdrive": "Tuvan's Modified 500MN Microwarpdrive",
+ "Setele's Modified 100MN Microwarpdrive": "Setele's Modified 500MN Microwarpdrive",
+ "Cormack's Modified 100MN Microwarpdrive": "Cormack's Modified 500MN Microwarpdrive",
+ "Republic Fleet 1MN Microwarpdrive": "Republic Fleet 5MN Microwarpdrive",
+ "Republic Fleet 10MN Microwarpdrive": "Republic Fleet 50MN Microwarpdrive",
+ "Republic Fleet 100MN Microwarpdrive": "Republic Fleet 500MN Microwarpdrive",
+ "Federation Navy 1MN Microwarpdrive": "Federation Navy 5MN Microwarpdrive",
+ "Federation Navy 10MN Microwarpdrive": "Federation Navy 50MN Microwarpdrive",
+ "Federation Navy 100MN Microwarpdrive": "Federation Navy 500MN Microwarpdrive",
+ "Coreli C-Type 1MN Microwarpdrive": "Coreli C-Type 5MN Microwarpdrive",
+ "Corelum C-Type 10MN Microwarpdrive": "Corelum C-Type 50MN Microwarpdrive",
+ "Core C-Type 100MN Microwarpdrive": "Core C-Type 500MN Microwarpdrive",
+ "Coreli B-Type 1MN Microwarpdrive": "Coreli B-Type 5MN Microwarpdrive",
+ "Corelum B-Type 10MN Microwarpdrive": "Corelum B-Type 50MN Microwarpdrive",
+ "Core B-Type 100MN Microwarpdrive": "Core B-Type 500MN Microwarpdrive",
+ "Coreli A-Type 1MN Microwarpdrive": "Coreli A-Type 5MN Microwarpdrive",
+ "Corelum A-Type 10MN Microwarpdrive": "Corelum A-Type 50MN Microwarpdrive",
+ "Core A-Type 100MN Microwarpdrive": "Core A-Type 500MN Microwarpdrive",
+ "Core X-Type 100MN Microwarpdrive": "Core X-Type 500MN Microwarpdrive",
+ "Gistii C-Type 1MN Microwarpdrive": "Gistii C-Type 5MN Microwarpdrive",
+ "Gistum C-Type 10MN Microwarpdrive": "Gistum C-Type 50MN Microwarpdrive",
+ "Gist C-Type 100MN Microwarpdrive": "Gist C-Type 500MN Microwarpdrive",
+ "Gistii B-Type 1MN Microwarpdrive": "Gistii B-Type 5MN Microwarpdrive",
+ "Gistum B-Type 10MN Microwarpdrive": "Gistum B-Type 50MN Microwarpdrive",
+ "Gist B-Type 100MN Microwarpdrive": "Gist B-Type 500MN Microwarpdrive",
+ "Gistii A-Type 1MN Microwarpdrive": "Gistii A-Type 5MN Microwarpdrive",
+ "Gistum A-Type 10MN Microwarpdrive": "Gistum A-Type 50MN Microwarpdrive",
+ "Gist A-Type 100MN Microwarpdrive": "Gist A-Type 500MN Microwarpdrive",
+ "Gist X-Type 100MN Microwarpdrive": "Gist X-Type 500MN Microwarpdrive",
+ "100mm Reinforced Steel Plates II": "100mm Steel Plates II",
+ "200mm Reinforced Steel Plates II": "200mm Steel Plates II",
+ "400mm Reinforced Steel Plates II": "400mm Steel Plates II",
+ "800mm Reinforced Steel Plates II": "800mm Steel Plates II",
+ "1600mm Reinforced Steel Plates II": "1600mm Steel Plates II",
+ "Micro 'Trapper' Shield Extender": "Small 'Trapper' Shield Extender",
+ "1MN Analog Booster Rockets": "1MN Analog Booster Afterburner",
+ "10MN Analog Booster Rockets": "10MN Analog Booster Afterburner",
+ "100MN Analog Booster Rockets": "100MN Analog Booster Afterburner",
+ "1MN Digital Booster Rockets": "5MN Digital Booster Microwarpdrive",
+ "10MN Digital Booster Rockets": "50MN Digital Booster Microwarpdrive",
+ "100MN Digital Booster Rockets": "500MN Digital Booster Microwarpdrive",
+ "Civilian Afterburner": "1MN Civilian Afterburner",
+ "'Abatis' 100mm Reinforced Steel Plates I": "'Abatis' 100mm Steel Plates",
+ "'Bailey' 1600mm Reinforced Steel Plates I": "'Bailey' 1600mm Steel Plates",
+ "'Chainmail' 200mm Reinforced Steel Plates I": "'Chainmail' 200mm Steel Plates",
+ "'Bastion' 400mm Reinforced Steel Plates I": "'Bastion' 400mm Steel Plates",
+ "'Citadella' 50mm Reinforced Steel Plates I": "'Citadella' 100mm Steel Plates",
+ "'Barbican' 800mm Reinforced Steel Plates I": "'Barbican' 800mm Steel Plates",
+ "Syndicate 100mm Reinforced Steel Plates": "Syndicate 100mm Steel Plates",
+ "Syndicate 1600mm Reinforced Steel Plates": "Syndicate 1600mm Steel Plates",
+ "Syndicate 200mm Reinforced Steel Plates": "Syndicate 200mm Steel Plates",
+ "Syndicate 400mm Reinforced Steel Plates": "Syndicate 400mm Steel Plates",
+ "Syndicate 800mm Reinforced Steel Plates": "Syndicate 800mm Steel Plates",
+ "Imperial Navy 100mm Reinforced Steel Plates": "Imperial Navy 100mm Steel Plates",
+ "Federation Navy 100mm Reinforced Steel Plates": "Federation Navy 100mm Steel Plates",
+ "Imperial Navy 1600mm Reinforced Steel Plates": "Imperial Navy 1600mm Steel Plates",
+ "Federation Navy 1600mm Reinforced Steel Plates": "Federation Navy 1600mm Steel Plates",
+ "Imperial Navy 200mm Reinforced Steel Plates": "Imperial Navy 200mm Steel Plates",
+ "Federation Navy 200mm Reinforced Steel Plates": "Federation Navy 200mm Steel Plates",
+ "Imperial Navy 400mm Reinforced Steel Plates": "Imperial Navy 400mm Steel Plates",
+ "Federation Navy 400mm Reinforced Steel Plates": "Federation Navy 400mm Steel Plates",
+ "Imperial Navy 800mm Reinforced Steel Plates": "Imperial Navy 800mm Steel Plates",
+ "Federation Navy 800mm Reinforced Steel Plates": "Federation Navy 800mm Steel Plates",
+ "Polarized Small Pulse Laser": "Polarized Small Focused Pulse Laser",
+ # Converted items
+ "Large Subordinate Screen Stabilizer I": "Large F-S9 Regolith Compact Shield Extender",
+ "Large Supplemental Barrier Emitter I": "Large Azeotropic Restrained Shield Extender",
+ "Medium Subordinate Screen Stabilizer I": "Medium F-S9 Regolith Compact Shield Extender",
+ "Medium Supplemental Barrier Emitter I": "Medium Azeotropic Restrained Shield Extender",
+ "Micro Azeotropic Ward Salubrity I": "Small 'Trapper' Shield Extender",
+ "Micro F-S9 Regolith Shield Induction": "Small 'Trapper' Shield Extender",
+ "Micro Shield Extender I": "Small 'Trapper' Shield Extender",
+ "Micro Shield Extender II": "Small 'Trapper' Shield Extender",
+ "Micro Subordinate Screen Stabilizer I": "Small 'Trapper' Shield Extender",
+ "Micro Supplemental Barrier Emitter I": "Small 'Trapper' Shield Extender",
+ "Small Subordinate Screen Stabilizer I": "Small F-S9 Regolith Compact Shield Extender",
+ "Small Supplemental Barrier Emitter I": "Small Azeotropic Restrained Shield Extender",
+ "100mm Reinforced Nanofiber Plates I": "100mm Crystalline Carbonide Restrained Plates",
+ "100mm Reinforced Titanium Plates I": "100mm Rolled Tungsten Compact Plates",
+ "1600mm Reinforced Nanofiber Plates I": "1600mm Crystalline Carbonide Restrained Plates",
+ "1600mm Reinforced Titanium Plates I": "1600mm Rolled Tungsten Compact Plates",
+ "200mm Reinforced Nanofiber Plates I": "200mm Crystalline Carbonide Restrained Plates",
+ "200mm Reinforced Titanium Plates I": "200mm Rolled Tungsten Compact Plates",
+ "400mm Reinforced Nanofiber Plates I": "400mm Crystalline Carbonide Restrained Plates",
+ "400mm Reinforced Titanium Plates I": "400mm Rolled Tungsten Compact Plates",
+ "50mm Reinforced Crystalline Carbonide Plates I": "'Citadella' 100mm Steel Plates",
+ "50mm Reinforced Nanofiber Plates I": "'Citadella' 100mm Steel Plates",
+ "50mm Reinforced Rolled Tungsten Plates I": "'Citadella' 100mm Steel Plates",
+ "50mm Reinforced Steel Plates I": "'Citadella' 100mm Steel Plates",
+ "50mm Reinforced Steel Plates II": "'Citadella' 100mm Steel Plates",
+ "50mm Reinforced Titanium Plates I": "'Citadella' 100mm Steel Plates",
+ "800mm Reinforced Nanofiber Plates I": "800mm Crystalline Carbonide Restrained Plates",
+ "800mm Reinforced Titanium Plates I": "800mm Rolled Tungsten Compact Plates"
+}
diff --git a/service/fit.py b/service/fit.py
index dfda754e0..5360a376a 100644
--- a/service/fit.py
+++ b/service/fit.py
@@ -398,8 +398,11 @@ class Fit(object):
if m.isValidState(State.ACTIVE):
m.state = State.ACTIVE
+ # As some items may affect state-limiting attributes of the ship, calculate new attributes first
self.recalc(fit)
+ # Then, check states of all modules and change where needed. This will recalc if needed
self.checkStates(fit, m)
+
fit.fill()
eos.db.commit()
@@ -857,7 +860,10 @@ class Fit(object):
if drone.amountActive > 0 and not drone.canBeApplied(fit):
drone.amountActive = 0
changed = True
- return changed
+
+ # If any state was changed, recalculate attributes again
+ if changed:
+ self.recalc(fit)
def toggleModulesState(self, fitID, base, modules, click):
proposedState = self.__getProposedState(base, click)
@@ -873,11 +879,8 @@ class Fit(object):
# As some items may affect state-limiting attributes of the ship, calculate new attributes first
self.recalc(fit)
- # Then, check states of all modules and change where needed
- changed = self.checkStates(fit, base)
- # If any state was changed, recalulate attributes again
- if changed is True:
- self.recalc(fit)
+ # Then, check states of all modules and change where needed. This will recalc if needed
+ self.checkStates(fit, base)
# Old state : New State
localMap = {State.OVERHEATED: State.ACTIVE,
@@ -922,5 +925,5 @@ class Fit(object):
def recalc(self, fit, withBoosters=False):
if fit.factorReload is not self.serviceFittingOptions["useGlobalForceReload"]:
fit.factorReload = self.serviceFittingOptions["useGlobalForceReload"]
- fit.clear()
+ fit.clear()
fit.calculateModifiedAttributes(withBoosters=withBoosters, dirtyStorage=self.dirtyFitIDs)
diff --git a/service/market.py b/service/market.py
index b4f3ef1b3..0ea234aaf 100644
--- a/service/market.py
+++ b/service/market.py
@@ -218,6 +218,9 @@ class Market():
"Mobile Decoy Unit": False, # Seems to be left over test mod for deployables
"Tournament Micro Jump Unit": False, # Normally seen only on tournament arenas
"Council Diplomatic Shuttle": False, # CSM X celebration
+ "Federation Navy 200mm Steel Plates": True, # Accidentally unpublished by CCP
+ "Imperial Navy 200mm Steel Plates": True, # Accidentally unpublished by CCP
+ "Syndicate 200mm Steel Plates": True, # Accidentally unpublished by CCP
}
# do not publish ships that we convert
diff --git a/staticdata/eve.db b/staticdata/eve.db
index a5c1e7998..032a2a351 100644
Binary files a/staticdata/eve.db and b/staticdata/eve.db differ
diff --git a/staticdata/icons/ships/34828.png b/staticdata/icons/ships/34828.png
new file mode 100644
index 000000000..cfd751e1d
Binary files /dev/null and b/staticdata/icons/ships/34828.png differ