Merge remote-tracking branch 'refs/remotes/pyfa-org/master'

This commit is contained in:
Ebag333
2016-06-05 00:13:09 -07:00
117 changed files with 544 additions and 225 deletions

View File

@@ -14,6 +14,17 @@ The latest version along with release notes can always be found on the project's
## Installation
Windows and OS X users are supplied self-contained builds of pyfa on the [latest releases](https://github.com/pyfa-org/Pyfa/releases/latest) page. An `.exe` installer is also available for Windows builds. Linux users can run pyfa using their distribution's Python interpreter. There is no official self-contained package for Linux, however, there are a number of third-party packages available through distribution-specific repositories.
#### OS X
There are two different distributives for OS X: `-mac` and `-mac-deprecated`.
* `-mac`: based on wxPython 3.0.2.0 and has updated libraries. This is the recommended build.
* `-mac-deprecated`: utilizes older binaries running on wxPython 2.8; because of this, some features are not available (currently CREST support and Attribute Overrides). Additionally, as development happens primarily on wxPython 3.0, a few GUI bugs may pop up as `-mac-deprecated` is not actively tested. However, due to some general issues with wxPython 3.0, especially on some newer OS X versions, `-mac-deprecated` is still offered for those that need it.
There is also a [Homebrew](http://brew.sh) option for installing pyfa on OS X. Please note this is maintained by a third-party and is not tested by pyfa developers. Simply fire up in terminal:
```
$ brew cask install pyfa
```
### Linux Distro-specific Packages
The following is a list of pyfa packages available for certain distributions. Please note that these packages are maintained by third-parties and are not evaluated by the pyfa developers.

View File

@@ -18,10 +18,10 @@ debug = False
saveInRoot = False
# Version data
version = "1.21.2"
tag = "Stable"
version = "1.21.4"
tag = "git"
expansionName = "Citadel"
expansionVersion = "1.3"
expansionVersion = "1.11"
evemonMinVersion = "4081"
pyfaPath = None

View File

@@ -194,7 +194,7 @@ def searchItems(nameLike, where=None, join=None, eager=None):
items = gamedata_session.query(Item).options(*processEager(eager)).join(*join)
for token in nameLike.split(' '):
token_safe = u"%{0}%".format(sqlizeString(token))
items = items.filter(processWhere(Item.name.like(token_safe, escape="\\"), where))
items = items.filter(and_(Item.name.like(token_safe, escape="\\"), where))
items = items.limit(100).all()
return items

View File

@@ -20,7 +20,7 @@
from sqlalchemy import Table, Column, Integer, ForeignKey, Boolean
from sqlalchemy.orm import mapper
from eos.db import saveddata_meta
from eos.types import Fighter
from eos.types import Fighter, Fit
from sqlalchemy.orm import *
from sqlalchemy.sql import and_
from eos.effectHandlerHelpers import *
@@ -42,6 +42,7 @@ fighter_abilities_table = Table("fightersAbilities", saveddata_meta,
mapper(Fighter, fighters_table,
properties = {
"owner": relation(Fit),
"_Fighter__abilities": relation(
FighterAbility,
backref="fighter",

View File

@@ -18,7 +18,7 @@
#===============================================================================
from sqlalchemy.orm import eagerload
from sqlalchemy.sql import and_
from sqlalchemy.sql import and_, or_
replace = {"attributes": "_Item__attributes",
"modules": "_Fit__modules",

View File

@@ -1,4 +1,4 @@
# capitalLauncherSkillCruiseCitadelEmDamage1
# capitalLauncherSkillCruiseCitadelEmDamage1
#
# Used by:
# Skill: XL Cruise Missiles

View File

@@ -1,7 +1,4 @@
# decreaseTargetSpeed
#
# Used by:
# Drones from group: Stasis Webifying Drone (3 of 3)
# Not used by any item
type = "active", "projected"
def handler(fit, module, context):
if "projected" not in context:

View File

@@ -1,7 +1,4 @@
# droneDamageBonusRequringDrones
#
# Used by:
# Skill: Drone Interfacing
# Not used by any item
type = "passive"
def handler(fit, skill, context):
fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Drones"),

View File

@@ -1,7 +1,4 @@
# eliteBonusCommandDestroyerMWDSigRadius3
#
# Used by:
# Ships from group: Command Destroyers (4 of 4)
# Not used by any item
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("High Speed Maneuvering"), "signatureRadiusBonus", src.getModifiedItemAttr("eliteBonusCommandDestroyer3"), skill="Command Destroyers")

View File

@@ -3,6 +3,5 @@
# Used by:
# Ship: Oneiros
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Remote Armor Repairer",
"capacitorNeed", ship.getModifiedItemAttr("eliteBonusLogistics1"), skill="Logistics Cruisers")
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "capacitorNeed", src.getModifiedItemAttr("eliteBonusLogistics1"), skill="Logistics Cruisers")

View File

@@ -3,6 +3,5 @@
# Used by:
# Ship: Guardian
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Remote Armor Repairer",
"capacitorNeed", ship.getModifiedItemAttr("eliteBonusLogistics2"), skill="Logistics Cruisers")
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "capacitorNeed", src.getModifiedItemAttr("eliteBonusLogistics2"), skill="Logistics Cruisers")

View File

@@ -4,6 +4,5 @@
# Ship: Basilisk
# Ship: Etana
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Remote Shield Booster",
"capacitorNeed", ship.getModifiedItemAttr("eliteBonusLogistics1"), skill="Logistics Cruisers")
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Emission Systems"), "capacitorNeed", src.getModifiedItemAttr("eliteBonusLogistics1"), skill="Logistics Cruisers")

View File

@@ -3,6 +3,5 @@
# Used by:
# Ship: Scimitar
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Remote Shield Booster",
"capacitorNeed", ship.getModifiedItemAttr("eliteBonusLogistics2"), skill="Logistics Cruisers")
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Emission Systems"), "capacitorNeed", src.getModifiedItemAttr("eliteBonusLogistics2"), skill="Logistics Cruisers")

View File

@@ -1,7 +1,4 @@
# energyDestabilizationNew
#
# Used by:
# Drones from group: Energy Neutralizer Drone (3 of 3)
# Not used by any item
from eos.types import State
type = "active", "projected"
def handler(fit, container, context):

View File

@@ -0,0 +1,12 @@
# energyNeutralizerEntity
#
# Used by:
# Drones from group: Energy Neutralizer Drone (3 of 3)
from eos.types import State
type = "active", "projected"
def handler(fit, container, context):
if "projected" in context and ((hasattr(container, "state") \
and container.state >= State.ACTIVE) or hasattr(container, "amountActive")):
amount = container.getModifiedItemAttr("energyDestabilizationAmount")
time = container.getModifiedItemAttr("duration")
fit.addDrain(time, amount, 0)

View File

@@ -1,14 +1,12 @@
# energyNeutralizerFalloff
#
# Used by:
# Drones from group: Energy Neutralizer Drone (3 of 3)
# Modules from group: Energy Neutralizer (51 of 51)
from eos.types import State
type = "active", "projected"
def handler(fit, container, context):
if "projected" in context and ((hasattr(container, "state") \
and container.state >= State.ACTIVE) or hasattr(container, "amountActive")):
multiplier = container.amountActive if hasattr(container, "amountActive") else 1
amount = container.getModifiedItemAttr("energyDestabilizationAmount")
time = container.getModifiedItemAttr("duration")
fit.addDrain(time, amount * multiplier, 0)
fit.addDrain(time, amount, 0)

View File

@@ -1,7 +1,4 @@
# energyTransfer
#
# Used by:
# Modules from group: Remote Capacitor Transmitter (38 of 38)
# Not used by any item
type = "projected", "active"
def handler(fit, module, context):
if "projected" in context:

View File

@@ -1,7 +1,4 @@
# ewTargetPaint
#
# Used by:
# Drones named like: TP (3 of 3)
# Not used by any item
type = "projected", "active"
def handler(fit, container, context):
if "projected" in context:

View File

@@ -1,3 +1,4 @@
# Not used by any item
"""
Since fighter abilities do not have any sort of item entity in the EVE database, we must derive the abilities from the
effects, and thus this effect file contains some custom information useful only to fighters.

View File

@@ -1,3 +1,4 @@
# Not used by any item
"""
Since fighter abilities do not have any sort of item entity in the EVE database, we must derive the abilities from the
effects, and thus this effect file contains some custom information useful only to fighters.

View File

@@ -1,3 +1,4 @@
# Not used by any item
"""
Since fighter abilities do not have any sort of item entity in the EVE database, we must derive the abilities from the
effects, and thus this effect file contains some custom information useful only to fighters.

View File

@@ -1,3 +1,4 @@
# Not used by any item
"""
Since fighter abilities do not have any sort of item entity in the EVE database, we must derive the abilities from the
effects, and thus this effect file contains some custom information useful only to fighters.

View File

@@ -1,3 +1,4 @@
# Not used by any item
"""
Since fighter abilities do not have any sort of item entity in the EVE database, we must derive the abilities from the
effects, and thus this effect file contains some custom information useful only to fighters.

View File

@@ -1,3 +1,4 @@
# Not used by any item
"""
Since fighter abilities do not have any sort of item entity in the EVE database, we must derive the abilities from the
effects, and thus this effect file contains some custom information useful only to fighters.

View File

@@ -1,3 +1,4 @@
# Not used by any item
"""
Since fighter abilities do not have any sort of item entity in the EVE database, we must derive the abilities from the
effects, and thus this effect file contains some custom information useful only to fighters.

View File

@@ -1,3 +1,4 @@
# Not used by any item
"""
Since fighter abilities do not have any sort of item entity in the EVE database, we must derive the abilities from the
effects, and thus this effect file contains some custom information useful only to fighters.

View File

@@ -6,8 +6,10 @@ runTime = "late"
type = "active"
def handler(fit, module, context):
if module.charge and module.charge.name == "Nanite Repair Paste":
module.multiplyItemAttr("armorDamageAmount", 3)
multiplier = 3
else:
multiplier = 1
amount = module.getModifiedItemAttr("armorDamageAmount")
amount = module.getModifiedItemAttr("armorDamageAmount") * multiplier
speed = module.getModifiedItemAttr("duration") / 1000.0
fit.extraAttributes.increase("armorRepair", amount / speed)

View File

@@ -1,7 +1,4 @@
# marauderModeEffect26
#
# Used by:
# Module: Bastion Module I
# Not used by any item
type = "active"
runTime = "early"
def handler(fit, module, context):

View File

@@ -0,0 +1,17 @@
# moduleBonusAncillaryRemoteArmorRepairer
#
# Used by:
# Modules from group: Ancillary Remote Armor Repairer (4 of 4)
runTime = "late"
type = "projected", "active"
def handler(fit, module, context):
if "projected" not in context: return
if module.charge and module.charge.name == "Nanite Repair Paste":
multiplier = 3
else:
multiplier = 1
amount = module.getModifiedItemAttr("armorDamageAmount") * multiplier
speed = module.getModifiedItemAttr("duration") / 1000.0
fit.extraAttributes.increase("armorRepair", amount / speed)

View File

@@ -0,0 +1,11 @@
# moduleBonusAncillaryRemoteShieldBooster
#
# Used by:
# Modules from group: Ancillary Remote Shield Booster (4 of 4)
runTime = "late"
type = "projected", "active"
def handler(fit, module, context):
if "projected" not in context: return
amount = module.getModifiedItemAttr("shieldBonus")
speed = module.getModifiedItemAttr("duration") / 1000.0
fit.extraAttributes.increase("shieldRepair", amount / speed)

View File

@@ -4,7 +4,7 @@
# Variations of module: Armored Warfare Link - Damage Control I (2 of 2)
type = "gang", "active"
gangBoost = "armorRepairCapacitorNeed"
runTime = "late"
#runTime = "late"
def handler(fit, module, context):
if "gang" not in context: return

View File

@@ -4,7 +4,7 @@
# Variations of module: Armored Warfare Link - Passive Defense I (2 of 2)
type = "gang", "active"
gangBoost = "armorResistance"
runTime = "late"
#runTime = "late"
def handler(fit, module, context):
if "gang" not in context: return

View File

@@ -4,7 +4,7 @@
# Variations of module: Armored Warfare Link - Rapid Repair I (2 of 2)
type = "gang", "active"
gangBoost = "armorRepairDuration"
runTime = "late"
#runTime = "late"
def handler(fit, module, context):
if "gang" not in context: return

View File

@@ -4,7 +4,7 @@
# Variations of module: Information Warfare Link - Recon Operation I (2 of 2)
type = "gang", "active"
gangBoost = "electronicMaxRange"
runTime = "late"
#runTime = "late"
def handler(fit, module, context):
if "gang" not in context: return

View File

@@ -5,7 +5,7 @@
type = "gang", "active"
gangBoost = "maxTargetRange"
gangBonus = "commandBonus"
runTime = "late"
#runTime = "late"
def handler(fit, module, context):
if "gang" not in context: return

View File

@@ -18,11 +18,10 @@ def handler(fit, src, context):
'Burst Jammer',
'Weapon Disruptor',
'ECM',
'Stasis Grappler',
'Sensor Dampener',
'Target Painter']
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name in groups or
mod.item.requiresSkill("Propulsion Jamming"),
"capacitorNeed", src.getModifiedItemAttr("ewCapacitorNeedBonus"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Propulsion Jamming"),
"capacitorNeed", src.getModifiedItemAttr("ewCapacitorNeedBonus"))
"capacitorNeed", src.getModifiedItemAttr("ewCapacitorNeedBonus"))

View File

@@ -4,7 +4,7 @@
# Variations of module: Siege Warfare Link - Active Shielding I (2 of 2)
type = "gang", "active"
gangBoost = "shieldRepairDuration"
runTime = "late"
#runTime = "late"
def handler(fit, module, context):
if "gang" not in context: return

View File

@@ -4,7 +4,7 @@
# Variations of module: Siege Warfare Link - Shield Efficiency I (2 of 2)
type = "gang", "active"
gangBoost = "shieldRepairCapacitorNeed"
runTime = "late"
#runTime = "late"
def handler(fit, module, context):
if "gang" not in context: return

View File

@@ -3,7 +3,7 @@
# Used by:
# Variations of module: Siege Warfare Link - Shield Harmonizing I (2 of 2)
type = "gang", "active"
runTime = "late"
#runTime = "late"
gangBoost = "shieldResistance"
def handler(fit, module, context):

View File

@@ -4,7 +4,7 @@
# Variations of module: Skirmish Warfare Link - Evasive Maneuvers I (2 of 2)
type = "gang", "active"
gangBoost = "signatureRadius"
runTime = "late"
#runTime = "late"
def handler(fit, module, context):
if "gang" not in context: return

View File

@@ -4,7 +4,7 @@
# Variations of module: Skirmish Warfare Link - Interdiction Maneuvers I (2 of 2)
type = "gang", "active"
gangBoost = "interdictionMaxRange"
runTime = "late"
#runTime = "late"
def handler(fit, module, context):
if "gang" not in context: return

View File

@@ -4,7 +4,7 @@
# Variations of module: Skirmish Warfare Link - Rapid Deployment I (2 of 2)
type = "gang", "active"
gangBoost = "speedFactor"
runTime = "late"
#runTime = "late"
def handler(fit, module, context):
if "gang" not in context: return

View File

@@ -42,14 +42,13 @@ def handler(fit, src, context):
'Burst Jammer',
'Weapon Disruptor',
'ECM',
'Stasis Grappler',
'Sensor Dampener',
'Target Painter']
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name in groups or
mod.item.requiresSkill("Propulsion Jamming"),
"capacitorNeed", src.getModifiedItemAttr("ewCapacitorNeedBonus"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Propulsion Jamming"),
"capacitorNeed", src.getModifiedItemAttr("ewCapacitorNeedBonus"))
# todo: test for April 2016 release
# Block EWAR & projected effects

View File

@@ -1,9 +1,9 @@
# overloadSelfDamageBonus
#
# Used by:
# Modules from group: Energy Weapon (102 of 209)
# Modules from group: Hybrid Weapon (106 of 221)
# Modules from group: Projectile Weapon (100 of 165)
# Modules from group: Energy Weapon (101 of 209)
# Modules from group: Hybrid Weapon (105 of 221)
# Modules from group: Projectile Weapon (99 of 165)
type = "overheat"
def handler(fit, module, context):
module.boostItemAttr("damageMultiplier", module.getModifiedItemAttr("overloadDamageModifier"))

View File

@@ -4,6 +4,5 @@
# Ship: Guardian
# Ship: Oneiros
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Remote Armor Repairer",
"power", ship.getModifiedItemAttr("remoteArmorPowerNeedBonus"))
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "power", src.getModifiedItemAttr("remoteArmorPowerNeedBonus"))

View File

@@ -0,0 +1,10 @@
# remoteArmorRepairEntity
#
# Used by:
# Drones named like: Armor Maintenance Bot (6 of 6)
type = "projected", "active"
def handler(fit, container, context):
if "projected" in context:
bonus = container.getModifiedItemAttr("armorDamageAmount")
duration = container.getModifiedItemAttr("duration") / 1000.0
fit.extraAttributes.increase("armorRepair", bonus / duration)

View File

@@ -2,7 +2,6 @@
#
# Used by:
# Modules from group: Remote Armor Repairer (39 of 39)
# Drones named like: Armor Maintenance Bot (6 of 6)
type = "projected", "active"
def handler(fit, container, context):
if "projected" in context:

View File

@@ -1,7 +1,4 @@
# remoteEcmBurst
#
# Used by:
# Module: ECM Jammer Burst Projector
# Not used by any item
type = 'active'
def handler(fit, module, context):
pass

View File

@@ -14,4 +14,4 @@ def handler(fit, src, context):
):
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"),
tgtAttr, src.getModifiedItemAttr(srcAttr),
stackingPenalties=True)
stackingPenalties=True, remoteResists=True)

View File

@@ -1,7 +1,4 @@
# remoteHullRepair
#
# Used by:
# Drones named like: Hull Maintenance Bot (6 of 6)
# Not used by any item
type = "projected", "active"
runTime = "late"
def handler(fit, module, context):

View File

@@ -0,0 +1,11 @@
# remoteHullRepairEntity
#
# Used by:
# Drones named like: Hull Maintenance Bot (6 of 6)
type = "projected", "active"
runTime = "late"
def handler(fit, module, context):
if "projected" not in context: return
bonus = module.getModifiedItemAttr("structureDamageAmount")
duration = module.getModifiedItemAttr("duration") / 1000.0
fit.extraAttributes.increase("hullRepair", bonus / duration)

View File

@@ -2,7 +2,6 @@
#
# Used by:
# Modules from group: Remote Hull Repairer (8 of 8)
# Drones named like: Hull Maintenance Bot (6 of 6)
type = "projected", "active"
runTime = "late"
def handler(fit, module, context):

View File

@@ -0,0 +1,14 @@
# remoteSensorDampEntity
#
# Used by:
# Drones named like: SD (3 of 3)
type= "projected", "active"
def handler(fit, module, context):
if "projected" not in context:
return
fit.ship.boostItemAttr("maxTargetRange", module.getModifiedItemAttr("maxTargetRangeBonus"),
stackingPenalties = True, remoteResists=True)
fit.ship.boostItemAttr("scanResolution", module.getModifiedItemAttr("scanResolutionBonus"),
stackingPenalties = True, remoteResists=True)

View File

@@ -2,12 +2,13 @@
#
# Used by:
# Modules from group: Sensor Dampener (6 of 6)
# Drones named like: SD (3 of 3)
type= "projected", "active"
def handler(fit, module, context):
if "projected" not in context:
return
fit.ship.boostItemAttr("maxTargetRange", module.getModifiedItemAttr("maxTargetRangeBonus"),
stackingPenalties = True)
stackingPenalties = True, remoteResists=True)
fit.ship.boostItemAttr("scanResolution", module.getModifiedItemAttr("scanResolutionBonus"),
stackingPenalties = True)
stackingPenalties = True, remoteResists=True)

View File

@@ -0,0 +1,10 @@
# remoteShieldTransferEntity
#
# Used by:
# Drones named like: Shield Maintenance Bot (6 of 6)
type = "projected", "active"
def handler(fit, container, context):
if "projected" in context:
bonus = container.getModifiedItemAttr("shieldBonus")
duration = container.getModifiedItemAttr("duration") / 1000.0
fit.extraAttributes.increase("shieldRepair", bonus / duration)

View File

@@ -2,7 +2,6 @@
#
# Used by:
# Modules from group: Remote Shield Booster (38 of 38)
# Drones named like: Shield Maintenance Bot (6 of 6)
type = "projected", "active"
def handler(fit, container, context):
if "projected" in context:

View File

@@ -0,0 +1,9 @@
# remoteTargetPaintEntity
#
# Used by:
# Drones named like: TP (3 of 3)
type = "projected", "active"
def handler(fit, container, context):
if "projected" in context:
fit.ship.boostItemAttr("signatureRadius", container.getModifiedItemAttr("signatureRadiusBonus"),
stackingPenalties = True, remoteResists=True)

View File

@@ -2,9 +2,8 @@
#
# Used by:
# Modules from group: Target Painter (8 of 8)
# Drones named like: TP (3 of 3)
type = "projected", "active"
def handler(fit, container, context):
if "projected" in context:
fit.ship.boostItemAttr("signatureRadius", container.getModifiedItemAttr("signatureRadiusBonus"),
stackingPenalties = True)
stackingPenalties = True, remoteResists=True)

View File

@@ -1,17 +1,16 @@
# remoteTrackingDisruptFalloff
#
# Used by:
# Drones named like: TD (3 of 3)
# Variations of module: Tracking Disruptor I (6 of 6)
type= "projected", "active"
def handler(fit, module, context):
if "projected" in context:
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Gunnery"),
"trackingSpeed", module.getModifiedItemAttr("trackingSpeedBonus"),
stackingPenalties = True)
stackingPenalties = True, remoteResists=True)
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Gunnery"),
"maxRange", module.getModifiedItemAttr("maxRangeBonus"),
stackingPenalties = True)
stackingPenalties = True, remoteResists=True)
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Gunnery"),
"falloff", module.getModifiedItemAttr("falloffBonus"),
stackingPenalties = True)
stackingPenalties = True, remoteResists=True)

View File

@@ -0,0 +1,16 @@
# remoteWeaponDisruptEntity
#
# Used by:
# Drones named like: TD (3 of 3)
type= "projected", "active"
def handler(fit, module, context):
if "projected" in context:
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Gunnery"),
"trackingSpeed", module.getModifiedItemAttr("trackingSpeedBonus"),
stackingPenalties = True, remoteResists=True)
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Gunnery"),
"maxRange", module.getModifiedItemAttr("maxRangeBonus"),
stackingPenalties = True, remoteResists=True)
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Gunnery"),
"falloff", module.getModifiedItemAttr("falloffBonus"),
stackingPenalties = True, remoteResists=True)

View File

@@ -0,0 +1,9 @@
# remoteWebifierEntity
#
# Used by:
# Drones from group: Stasis Webifying Drone (3 of 3)
type = "active", "projected"
def handler(fit, module, context):
if "projected" not in context: return
fit.ship.boostItemAttr("maxVelocity", module.getModifiedItemAttr("speedFactor"),
stackingPenalties = True, remoteResists=True)

View File

@@ -1,11 +1,10 @@
# remoteWebifierFalloff
#
# Used by:
# Drones from group: Stasis Webifying Drone (3 of 3)
# Modules from group: Stasis Grappler (7 of 7)
# Modules from group: Stasis Web (18 of 18)
type = "active", "projected"
def handler(fit, module, context):
if "projected" not in context: return
fit.ship.boostItemAttr("maxVelocity", module.getModifiedItemAttr("speedFactor"),
stackingPenalties = True)
stackingPenalties = True, remoteResists=True)

View File

@@ -3,6 +3,5 @@
# Used by:
# Ships from group: Logistics (3 of 5)
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Remote Shield Booster",
"cpu", ship.getModifiedItemAttr("shieldTransportCpuNeedBonus"))
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Emission Systems"), "cpu", src.getModifiedItemAttr("shieldTransportCpuNeedBonus"))

View File

@@ -1,7 +1,4 @@
# shipBonusEnergyVampireRangeAD2
#
# Used by:
# Ship: Dragoon
# Not used by any item
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Energy Nosferatu",

View File

@@ -4,5 +4,9 @@
# Ship: Apostle
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Capacitor Emission Systems"), "powerTransferAmount", src.getModifiedItemAttr("shipBonusForceAuxiliaryA1"), skill="Amarr Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Remote Armor Repair Systems"), "armorDamageAmount", src.getModifiedItemAttr("shipBonusForceAuxiliaryA1"), skill="Amarr Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capacitor Emission Systems") or
mod.item.requiresSkill("Capital Capacitor Emission Systems"),
"powerTransferAmount", src.getModifiedItemAttr("shipBonusForceAuxiliaryA1"), skill="Amarr Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems") or
mod.item.requiresSkill("Capital Remote Armor Repair Systems"),
"armorDamageAmount", src.getModifiedItemAttr("shipBonusForceAuxiliaryA1"), skill="Amarr Carrier")

View File

@@ -4,5 +4,9 @@
# Ship: Minokawa
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Capacitor Emission Systems"), "powerTransferAmount", src.getModifiedItemAttr("shipBonusForceAuxiliaryC1"), skill="Caldari Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Shield Emission Systems"), "shieldBonus", src.getModifiedItemAttr("shipBonusForceAuxiliaryC1"), skill="Caldari Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capacitor Emission Systems") or
mod.item.requiresSkill("Capital Capacitor Emission Systems"),
"powerTransferAmount", src.getModifiedItemAttr("shipBonusForceAuxiliaryC1"), skill="Caldari Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Emission Systems") or
mod.item.requiresSkill("Capital Shield Emission Systems"),
"shieldBonus", src.getModifiedItemAttr("shipBonusForceAuxiliaryC1"), skill="Caldari Carrier")

View File

@@ -4,7 +4,9 @@
# Ship: Ninazu
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Remote Armor Repair Systems"), "duration", src.getModifiedItemAttr("shipBonusForceAuxiliaryG1"), skill="Gallente Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Shield Emission Systems"), "duration", src.getModifiedItemAttr("shipBonusForceAuxiliaryG1"), skill="Gallente Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Emission Systems"), "duration", src.getModifiedItemAttr("shipBonusForceAuxiliaryG1"), skill="Gallente Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "duration", src.getModifiedItemAttr("shipBonusForceAuxiliaryG1"), skill="Gallente Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Emission Systems") or
mod.item.requiresSkill("Capital Shield Emission Systems"),
"duration", src.getModifiedItemAttr("shipBonusForceAuxiliaryG1"), skill="Gallente Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems") or
mod.item.requiresSkill("Capital Remote Armor Repair Systems"),
"duration", src.getModifiedItemAttr("shipBonusForceAuxiliaryG1"), skill="Gallente Carrier")

View File

@@ -4,7 +4,10 @@
# Ship: Lif
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Emission Systems"), "duration", src.getModifiedItemAttr("shipBonusForceAuxiliaryM1"), skill="Minmatar Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Shield Emission Systems"), "duration", src.getModifiedItemAttr("shipBonusForceAuxiliaryM1"), skill="Minmatar Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "duration", src.getModifiedItemAttr("shipBonusForceAuxiliaryM1"), skill="Minmatar Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Remote Armor Repair Systems"), "duration", src.getModifiedItemAttr("shipBonusForceAuxiliaryM1"), skill="Minmatar Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Emission Systems") or
mod.item.requiresSkill("Capital Shield Emission Systems"),
"duration", src.getModifiedItemAttr("shipBonusForceAuxiliaryM1"), skill="Minmatar Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems") or
mod.item.requiresSkill("Capital Remote Armor Repair Systems"),
"duration", src.getModifiedItemAttr("shipBonusForceAuxiliaryM1"), skill="Minmatar Carrier")

View File

@@ -4,6 +4,5 @@
# Ship: Deacon
# Ship: Inquisitor
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Remote Armor Repairer",
"armorDamageAmount", ship.getModifiedItemAttr("shipBonus2AF"), skill="Amarr Frigate")
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "armorDamageAmount", src.getModifiedItemAttr("shipBonus2AF"), skill="Amarr Frigate")

View File

@@ -3,6 +3,5 @@
# Used by:
# Ship: Augoror
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Remote Armor Repairer",
"armorDamageAmount", ship.getModifiedItemAttr("shipBonusAC2"), skill="Amarr Cruiser")
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "armorDamageAmount", src.getModifiedItemAttr("shipBonusAC2"), skill="Amarr Cruiser")

View File

@@ -3,6 +3,5 @@
# Used by:
# Ship: Exequror
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Remote Armor Repairer",
"armorDamageAmount", ship.getModifiedItemAttr("shipBonusGC2"), skill="Gallente Cruiser")
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "armorDamageAmount", src.getModifiedItemAttr("shipBonusGC2"), skill="Gallente Cruiser")

View File

@@ -3,6 +3,5 @@
# Used by:
# Variations of ship: Navitas (2 of 2)
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Remote Armor Repairer",
"armorDamageAmount", ship.getModifiedItemAttr("shipBonusGF2"), skill="Gallente Frigate")
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "armorDamageAmount", src.getModifiedItemAttr("shipBonusGF2"), skill="Gallente Frigate")

View File

@@ -3,6 +3,5 @@
# Used by:
# Ship: Augoror
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Remote Armor Repairer",
"capacitorNeed", ship.getModifiedItemAttr("shipBonusAC"), skill="Amarr Cruiser")
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "capacitorNeed", src.getModifiedItemAttr("shipBonusAC"), skill="Amarr Cruiser")

View File

@@ -4,6 +4,5 @@
# Ship: Deacon
# Ship: Inquisitor
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Remote Armor Repairer",
"capacitorNeed", ship.getModifiedItemAttr("shipBonusAF"), skill="Amarr Frigate")
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "capacitorNeed", src.getModifiedItemAttr("shipBonusAF"), skill="Amarr Frigate")

View File

@@ -3,6 +3,5 @@
# Used by:
# Ship: Exequror
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Remote Armor Repairer",
"capacitorNeed", ship.getModifiedItemAttr("shipBonusGC"), skill="Gallente Cruiser")
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "capacitorNeed", src.getModifiedItemAttr("shipBonusGC"), skill="Gallente Cruiser")

View File

@@ -3,6 +3,5 @@
# Used by:
# Variations of ship: Navitas (2 of 2)
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Remote Armor Repairer",
"capacitorNeed", ship.getModifiedItemAttr("shipBonusGF"), skill="Gallente Frigate")
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "capacitorNeed", src.getModifiedItemAttr("shipBonusGF"), skill="Gallente Frigate")

View File

@@ -3,6 +3,5 @@
# Used by:
# Ship: Osprey
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Remote Shield Booster",
"capacitorNeed", ship.getModifiedItemAttr("shipBonusCC"), skill="Caldari Cruiser")
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Emission Systems"), "capacitorNeed", src.getModifiedItemAttr("shipBonusCC"), skill="Caldari Cruiser")

View File

@@ -1,7 +1,4 @@
# shipXLProjectileDamageRole
#
# Used by:
# Ship: Naglfar
# Not used by any item
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Projectile Turret"),

View File

@@ -5,5 +5,5 @@
type = "passive"
def handler(fit, src, context):
lvl = src.level
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "maxVelocity", src.getModifiedItemAttr("droneMaxVelocityBonus") * lvl)
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "maxVelocity", src.getModifiedItemAttr("droneMaxVelocityBonus") * lvl)
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "maxVelocity", src.getModifiedItemAttr("maxVelocityBonus") * lvl)
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "maxVelocity", src.getModifiedItemAttr("maxVelocityBonus") * lvl)

View File

@@ -1,3 +1,7 @@
# skillReactiveArmorHardenerCapNeedBonus
#
# Used by:
# Skill: Resistance Phasing
type = "passive"
def handler(fit, src, context):
lvl = src.level

View File

@@ -1,3 +1,7 @@
# skillReactiveArmorHardenerDurationBonus
#
# Used by:
# Skill: Resistance Phasing
type = "passive"
def handler(fit, src, context):
lvl = src.level

View File

@@ -1,4 +1,4 @@
# skillRemoteHullRepairSystemsCapNeedBonus
# skillRemoteHullRepairSystemsCapNeedBonus
#
# Used by:
# Skill: Remote Hull Repair Systems

View File

@@ -4,5 +4,5 @@
# Subsystem: Legion Defensive - Adaptive Augmenter
type = "passive"
def handler(fit, module, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Remote Armor Repairer",
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"),
"armorDamageAmount", module.getModifiedItemAttr("subsystemBonusAmarrDefensive2"), skill="Amarr Defensive Systems")

View File

@@ -4,5 +4,5 @@
# Subsystem: Tengu Defensive - Adaptive Shielding
type = "passive"
def handler(fit, module, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Remote Shield Booster",
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Emission Systems"),
"shieldBonus", module.getModifiedItemAttr("subsystemBonusCaldariDefensive2"), skill="Caldari Defensive Systems")

View File

@@ -4,5 +4,5 @@
# Subsystem: Proteus Defensive - Adaptive Augmenter
type = "passive"
def handler(fit, module, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Remote Armor Repairer",
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"),
"armorDamageAmount", module.getModifiedItemAttr("subsystemBonusGallenteDefensive2"), skill="Gallente Defensive Systems")

View File

@@ -4,5 +4,5 @@
# Subsystem: Loki Defensive - Adaptive Shielding
type = "passive"
def handler(fit, module, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Remote Shield Booster",
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Emission Systems"),
"shieldBonus", module.getModifiedItemAttr("subsystemBonusMinmatarDefensive2"), skill="Minmatar Defensive Systems")

View File

@@ -1,7 +1,4 @@
# titanTurretDamageScaling
#
# Used by:
# Ships from group: Titan (4 of 4)
# Not used by any item
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemIncrease(lambda mod: mod.item.requiresSkill("Gunnery"),

View File

@@ -73,6 +73,7 @@ def handler(fit, module, context):
'Burst Projectors',
'Weapon Disruptor',
'ECM',
'Stasis Grappler',
'Remote Sensor Damper',
'Target Painter']

View File

@@ -83,6 +83,7 @@ def handler(fit, module, context):
'Burst Projectors',
'Weapon Disruptor',
'ECM',
'Stasis Grappler',
'Remote Sensor Damper',
'Target Painter']

View File

@@ -1,7 +1,4 @@
# turretWeaponRangeFalloffTrackingSpeedMultiplyTargetHostile
#
# Used by:
# Drones named like: TD (3 of 3)
# Not used by any item
type = "projected", "active"
def handler(fit, container, context):
if "projected" in context:

View File

@@ -1,9 +1,7 @@
# warpScramble
#
# Used by:
# Variations of module: Heavy Warp Disruptor I (7 of 7)
# Variations of module: Warp Disruptor I (19 of 19)
# Module: Civilian Warp Disruptor
# Modules named like: Warp Disruptor (27 of 27)
type = "projected", "active"
def handler(fit, module, context):
fit.ship.increaseItemAttr("warpScrambleStatus", module.getModifiedItemAttr("warpScrambleStrength"))

View File

@@ -1,8 +1,7 @@
# warpScrambleBlockMWDWithNPCEffect
#
# Used by:
# Variations of module: Heavy Warp Scrambler I (7 of 7)
# Variations of module: Warp Scrambler I (19 of 19)
# Modules named like: Warp Scrambler (26 of 26)
runTime = "early"
type = "projected", "active"

View File

@@ -78,9 +78,13 @@ class FitDpsGraph(Graph):
dps, _ = drone.damageStats(fit.targetResists)
total += dps * multiplier
# this is janky as fuck
for fighter in fit.fighters:
dps, _ = fighter.damageStats(fit.targetResists)
total += dps
for ability in fighter.abilities:
if ability.dealsDamage and ability.active:
multiplier = self.calculateFighterMissileMultiplier(ability, data)
dps, _ = ability.damageStats(fit.targetResists)
total += dps * multiplier
return total
@@ -116,6 +120,35 @@ class FitDpsGraph(Graph):
multiplier = min(1, (float(targetSigRad) / dmgScaling) ** 2)
return multiplier
def calculateFighterMissileMultiplier(self, ability, data):
prefix = ability.attrPrefix
targetSigRad = data["signatureRadius"]
targetVelocity = data["velocity"]
explosionRadius = ability.fighter.getModifiedItemAttr("{}ExplosionRadius".format(prefix))
explosionVelocity = ability.fighter.getModifiedItemAttr("{}ExplosionVelocity".format(prefix))
damageReductionFactor = ability.fighter.getModifiedItemAttr("{}ReductionFactor".format(prefix))
# the following conditionals are because CCP can't keep a decent naming convention, as if fighter implementation
# wasn't already fucked.
if damageReductionFactor is None:
damageReductionFactor = ability.fighter.getModifiedItemAttr("{}DamageReductionFactor".format(prefix))
damageReductionSensitivity = ability.fighter.getModifiedItemAttr("{}ReductionSensitivity".format(prefix))
if damageReductionSensitivity is None:
damageReductionSensitivity = ability.fighter.getModifiedItemAttr("{}DamageReductionSensitivity".format(prefix))
targetSigRad = explosionRadius if targetSigRad is None else targetSigRad
sigRadiusFactor = targetSigRad / explosionRadius
if targetVelocity:
velocityFactor = (explosionVelocity / explosionRadius * targetSigRad / targetVelocity) ** (
log(damageReductionFactor) / log(damageReductionSensitivity))
else:
velocityFactor = 1
return min(sigRadiusFactor, velocityFactor, 1)
def calculateTurretChanceToHit(self, mod, data):
distance = data["distance"] * 1000
tracking = mod.getModifiedItemAttr("trackingSpeed")

View File

@@ -153,13 +153,24 @@ class ModifiedAttributeDict(collections.MutableMapping):
if attrInfo is None:
cappingId = cappingAttrKeyCache[key] = None
else:
# see GH issue #620
cappingId = cappingAttrKeyCache[key] = attrInfo.maxAttributeID
if cappingId is None:
cappingKey = None
else:
cappingAttrInfo = getAttributeInfo(cappingId)
cappingKey = None if cappingAttrInfo is None else cappingAttrInfo.name
cappingValue = self.__calculateValue(cappingKey) if cappingKey is not None else None
if cappingKey:
if cappingKey in self.original:
# some items come with their own caps (ie: carriers). If they do, use this
cappingValue = self.original.get(cappingKey).value
else:
# If not, get info about the default value
cappingValue = self.__calculateValue(cappingKey)
else:
cappingValue = None
# If value is forced, we don't have to calculate anything,
# just return forced value instead
force = self.__forced[key] if key in self.__forced else None
@@ -312,14 +323,27 @@ class ModifiedAttributeDict(collections.MutableMapping):
if not attributeName in self.__multipliers:
self.__multipliers[attributeName] = 1
self.__multipliers[attributeName] *= multiplier
self.__placehold(attributeName)
self.__afflict(attributeName, "%s*" % ("s" if stackingPenalties else ""), multiplier, multiplier != 1)
def boost(self, attributeName, boostFactor, skill=None, *args, **kwargs):
def boost(self, attributeName, boostFactor, skill=None, remoteResists=False, *args, **kwargs):
"""Boost value by some percentage"""
if skill:
boostFactor *= self.__handleSkill(skill)
if remoteResists:
# @todo: this is such a disgusting hack. Look into sending these checks to the module class before the
# effect is applied.
mod = self.fit.getModifier()
remoteResistID = mod.getModifiedItemAttr("remoteResistanceID") or None
# We really don't have a way of getting a ships attribute by ID. Fail.
resist = next((x for x in self.fit.ship.item.attributes.values() if x.ID == remoteResistID), None)
if remoteResistID and resist:
boostFactor *= resist.value
# We just transform percentage boost into multiplication factor
self.multiply(attributeName, 1 + boostFactor / 100.0, *args, **kwargs)

View File

@@ -315,7 +315,10 @@ class Skill(HandledItem):
return self.__item
def getModifiedItemAttr(self, key):
return self.item.attributes[key].value
if key in self.item.attributes:
return self.item.attributes[key].value
else:
return None
def calculateModifiedAttributes(self, fit, runTime):
if self.__suppressed: # or not self.learned - removed for GH issue 101

View File

@@ -159,25 +159,11 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
if self.__dps is None:
self.__volley = 0
self.__dps = 0
if self.active:
if self.active and self.amountActive > 0:
for ability in self.abilities:
if ability.dealsDamage and ability.active and self.amountActive > 0:
cycleTime = self.getModifiedItemAttr("{}Duration".format(ability.attrPrefix))
if ability.attrPrefix == "fighterAbilityLaunchBomb":
# bomb calcs
volley = sum(map(lambda attr: (self.getModifiedChargeAttr("%sDamage" % attr) or 0) * (1 - getattr(targetResists, "%sAmount" % attr, 0)), self.DAMAGE_TYPES))
print volley
else:
volley = sum(map(lambda d2, d:
(self.getModifiedItemAttr("{}Damage{}".format(ability.attrPrefix, d2)) or 0) *
(1-getattr(targetResists, "{}Amount".format(d), 0)),
self.DAMAGE_TYPES2, self.DAMAGE_TYPES))
volley *= self.amountActive
volley *= self.getModifiedItemAttr("{}DamageMultiplier".format(ability.attrPrefix)) or 1
self.__volley += volley
self.__dps += volley / (cycleTime / 1000.0)
dps, volley = ability.damageStats(targetResists)
self.__dps += dps
self.__volley += volley
return self.__dps, self.__volley
@@ -222,6 +208,7 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
self.__miningyield = None
self.itemModifiedAttributes.clear()
self.chargeModifiedAttributes.clear()
[x.clear() for x in self.abilities]
def canBeApplied(self, projectedOnto):
"""Check if fighter can engage specific fitting"""

View File

@@ -23,6 +23,8 @@ import logging
logger = logging.getLogger(__name__)
class FighterAbility(object):
DAMAGE_TYPES = ("em", "kinetic", "explosive", "thermal")
DAMAGE_TYPES2 = ("EM", "Kin", "Exp", "Therm")
def __init__(self, effect):
"""Initialize from the program"""
@@ -67,4 +69,33 @@ class FighterAbility(object):
@property
def grouped(self):
# is the ability applied per fighter (webs, returns False), or as a group (MWD, returned True)
return self.__effect.getattr('grouped')
return self.__effect.getattr('grouped')
def damageStats(self, targetResists=None):
if self.__dps is None:
self.__volley = 0
self.__dps = 0
if self.dealsDamage and self.active:
cycleTime = self.fighter.getModifiedItemAttr("{}Duration".format(self.attrPrefix))
if self.attrPrefix == "fighterAbilityLaunchBomb":
# bomb calcs
volley = sum(map(lambda attr: (self.fighter.getModifiedChargeAttr("%sDamage" % attr) or 0) * (
1 - getattr(targetResists, "%sAmount" % attr, 0)), self.DAMAGE_TYPES))
else:
volley = sum(map(lambda d2, d:
(self.fighter.getModifiedItemAttr(
"{}Damage{}".format(self.attrPrefix, d2)) or 0) *
(1 - getattr(targetResists, "{}Amount".format(d), 0)),
self.DAMAGE_TYPES2, self.DAMAGE_TYPES))
volley *= self.fighter.amountActive
volley *= self.fighter.getModifiedItemAttr("{}DamageMultiplier".format(self.attrPrefix)) or 1
self.__volley += volley
self.__dps += volley / (cycleTime / 1000.0)
return self.__dps, self.__volley
def clear(self):
self.__dps = None
self.__volley = None

View File

@@ -48,7 +48,7 @@ class Ship(ItemAttrShortcut, HandledItem):
self.__item = item
self.__modeItems = self.__getModeItems()
self.__itemModifiedAttributes = ModifiedAttributeDict()
self.__itemModifiedAttributes = ModifiedAttributeDict(parent=self)
self.__itemModifiedAttributes.original = dict(self.item.attributes)
self.__itemModifiedAttributes.original.update(self.EXTRA_ATTRIBUTES)
self.__itemModifiedAttributes.overrides = self.item.overrides

BIN
eve.db

Binary file not shown.

View File

@@ -60,7 +60,7 @@ class ChangeAffectingSkills(ContextMenu):
else:
label = "Level %s" % i
id = wx.NewId()
id = ContextMenu.nextID()
self.skillIds[id] = (skill, i)
menuItem = wx.MenuItem(rootMenu, id, label, kind=wx.ITEM_RADIO)
rootMenu.Bind(wx.EVT_MENU, self.handleSkillChange, menuItem)
@@ -72,7 +72,7 @@ class ChangeAffectingSkills(ContextMenu):
sub = wx.Menu()
for skill in self.skills:
skillItem = wx.MenuItem(sub, wx.NewId(), skill.item.name)
skillItem = wx.MenuItem(sub, ContextMenu.nextID(), skill.item.name)
grandSub = wx.Menu()
skillItem.SetSubMenu(grandSub)
if skill.learned:

Some files were not shown because too many files have changed in this diff Show More