Merge branch 'test-3' into esi

# Conflicts:
#	eos/saveddata/character.py
#	service/character.py
#	service/eveapi.py
#	service/pycrest/eve.py
This commit is contained in:
blitzmann
2018-03-10 15:32:21 -05:00
113 changed files with 846 additions and 379 deletions

View File

@@ -18,7 +18,7 @@ if istravis is True or hasattr(sys, '_called_from_test'):
# Running in Travis. Run saveddata database in memory.
saveddata_connectionstring = 'sqlite:///:memory:'
else:
saveddata_connectionstring = 'sqlite:///' + realpath(join(dirname(abspath(__file__)), "..", "saveddata", "saveddata.db"))
saveddata_connectionstring = 'sqlite:///' + realpath(join(dirname(abspath(__file__)), "..", "saveddata", "saveddata-py3-db.db"))
pyfalog.debug("Saveddata connection string: {0}", saveddata_connectionstring)

View File

@@ -68,7 +68,7 @@ class DefaultDatabaseValues(object):
["[Hybrid Charges]Uranium", "0", "38.4", "57.6", "0"],
["[Missiles]Mjolnir", "100", "0", "0", "0"], ["[Missiles]Inferno", "0", "100", "0", "0"],
["[Missiles]Scourge", "0", "0", "100", "0"], ["[Missiles]Nova", "0", "0", "0", "100"],
["[Missiles][Structure) Standup Missile", "100", "100", "100", "100"],
["[Missiles][Structure] Standup Missile", "100", "100", "100", "100"],
["[Projectile Ammo][T2] Tremor", "0", "0", "24", "40"],
["[Projectile Ammo][T2] Quake", "0", "0", "40", "72"],
["[Projectile Ammo][T2] Hail", "0", "0", "26.4", "96.8"],

View File

@@ -2,6 +2,7 @@
#
# Used by:
# Modules named like: Memetic Algorithm Bank (8 of 8)
# Implant: Neural Lace 'Blackglass' Net Intrusion 920-40
# Implant: Poteque 'Prospector' Environmental Analysis EY-1005
# Implant: Poteque 'Prospector' Hacking HC-905
type = "passive"

View File

@@ -1,7 +1,7 @@
# ammoInfluenceCapNeed
#
# Used by:
# Items from category: Charge (478 of 924)
# Items from category: Charge (478 of 925)
type = "passive"

View File

@@ -1,7 +1,7 @@
# ammoInfluenceRange
#
# Used by:
# Items from category: Charge (572 of 924)
# Items from category: Charge (572 of 925)
type = "passive"

View File

@@ -1,7 +1,7 @@
# ammoSpeedMultiplier
#
# Used by:
# Charges from group: Festival Charges (22 of 22)
# Charges from group: Festival Charges (23 of 23)
# Charges from group: Interdiction Probe (2 of 2)
type = "passive"

View File

@@ -0,0 +1,21 @@
# Not used by any item
type = "passive"
runTime = "early"
def handler(fit, src, context):
for attr in [
"structureRigDoomsdayDamageLossTargetBonus",
"structureRigScanResBonus",
"structureRigPDRangeBonus",
"structureRigPDCapUseBonus",
"structureRigMissileExploVeloBonus",
"structureRigMissileVelocityBonus",
"structureRigEwarOptimalBonus",
"structureRigEwarFalloffBonus",
"structureRigEwarCapUseBonus",
"structureRigMissileExplosionRadiusBonus"
]:
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Jury Rigging"),
attr, src.getModifiedItemAttr("structureRoleBonus"))

View File

@@ -1,8 +1,7 @@
# damageControl
#
# Used by:
# Variations of module: Damage Control I (16 of 16)
# Module: Civilian Damage Control
# Modules from group: Damage Control (22 of 27)
type = "passive"

View File

@@ -1,7 +1,7 @@
# doHacking
#
# Used by:
# Modules from group: Data Miners (17 of 18)
# Modules from group: Data Miners (9 of 9)
type = "active"

View File

@@ -0,0 +1,9 @@
# doomsdayAOEBubble
#
# Used by:
# Module: Standup Warp Disruption Burst Projector
type = "projected", "active"
def handler(fit, module, context):
return

View File

@@ -0,0 +1,16 @@
# doomsdayAOEDamp
#
# Used by:
# Module: Sensor Dampening Burst Projector
type = "projected", "active"
def handler(fit, module, context, *args, **kwargs):
if "projected" not in context:
return
fit.ship.boostItemAttr("maxTargetRange", module.getModifiedItemAttr("maxTargetRangeBonus"),
stackingPenalties=True, *args, **kwargs)
fit.ship.boostItemAttr("scanResolution", module.getModifiedItemAttr("scanResolutionBonus"),
stackingPenalties=True, *args, **kwargs)

View File

@@ -0,0 +1,21 @@
# doomsdayAOENeut
#
# Used by:
# Module: Energy Neutralization Burst Projector
from eos.saveddata.module import State
from eos.modifiedAttributeDict import ModifiedAttributeDict
type = "active", "projected"
def handler(fit, src, context, **kwargs):
if "projected" in context and ((hasattr(src, "state") and src.state >= State.ACTIVE) or
hasattr(src, "amountActive")):
amount = src.getModifiedItemAttr("energyNeutralizerAmount")
if 'effect' in kwargs:
amount *= ModifiedAttributeDict.getResistance(fit, kwargs['effect'])
time = src.getModifiedItemAttr("duration")
fit.addDrain(src, time, amount, 0)

View File

@@ -0,0 +1,11 @@
# doomsdayAOEPaint
#
# Used by:
# Module: Target Illumination Burst Projector
type = "projected", "active"
def handler(fit, container, context, *args, **kwargs):
if "projected" in context:
fit.ship.boostItemAttr("signatureRadius", container.getModifiedItemAttr("signatureRadiusBonus"),
stackingPenalties=True, *args, **kwargs)

View File

@@ -0,0 +1,29 @@
# doomsdayAOETrack
#
# Used by:
# Module: Weapon Disruption Burst Projector
type = "active", "projected"
def handler(fit, module, context, *args, **kwargs):
if "projected" in context:
for srcAttr, tgtAttr in (
("aoeCloudSizeBonus", "aoeCloudSize"),
("aoeVelocityBonus", "aoeVelocity"),
("missileVelocityBonus", "maxVelocity"),
("explosionDelayBonus", "explosionDelay"),
):
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"),
tgtAttr, module.getModifiedItemAttr(srcAttr),
stackingPenalties=True, *args, **kwargs)
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Gunnery"),
"trackingSpeed", module.getModifiedItemAttr("trackingSpeedBonus"),
stackingPenalties=True, *args, **kwargs)
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Gunnery"),
"maxRange", module.getModifiedItemAttr("maxRangeBonus"),
stackingPenalties=True, *args, **kwargs)
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Gunnery"),
"falloff", module.getModifiedItemAttr("falloffBonus"),
stackingPenalties=True, *args, **kwargs)

View File

@@ -0,0 +1,12 @@
# doomsdayAOEWeb
#
# Used by:
# Module: Stasis Webification Burst Projector
type = "active", "projected"
def handler(fit, module, context, *args, **kwargs):
if "projected" not in context:
return
fit.ship.boostItemAttr("maxVelocity", module.getModifiedItemAttr("speedFactor"),
stackingPenalties=True, *args, **kwargs)

View File

@@ -1,7 +1,4 @@
# eliteBonusGunshipDroneCapacity2
#
# Used by:
# Ship: Ishkur
# Not used by any item
type = "passive"

View File

@@ -0,0 +1,7 @@
# Not used by any item
type = "passive"
def handler(fit, src, context):
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "trackingSpeed",
src.getModifiedItemAttr("eliteBonusGunship2"), stackingPenalties=True, skill="Assault Frigates")

View File

@@ -0,0 +1,10 @@
# eliteBonusGunshipEMMissileDamage1
#
# Used by:
# Ship: Jaguar
type = "passive"
def handler(fit, src, context):
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"), "emDamage",
src.getModifiedItemAttr("eliteBonusGunship1"), skill="Assault Frigates")

View File

@@ -0,0 +1,10 @@
# eliteBonusGunshipExplosionVelocity2
#
# Used by:
# Ship: Jaguar
type = "passive"
def handler(fit, src, context):
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"), "aoeVelocity",
src.getModifiedItemAttr("eliteBonusGunship2"), stackingPenalties=True, skill="Assault Frigates")

View File

@@ -0,0 +1,10 @@
# eliteBonusGunshipExplosiveMissileDamage1
#
# Used by:
# Ship: Jaguar
type = "passive"
def handler(fit, src, context):
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"), "explosiveDamage",
src.getModifiedItemAttr("eliteBonusGunship1"), skill="Assault Frigates")

View File

@@ -0,0 +1,10 @@
# eliteBonusGunshipKineticMissileDamage1
#
# Used by:
# Ship: Jaguar
type = "passive"
def handler(fit, src, context):
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"), "kineticDamage",
src.getModifiedItemAttr("eliteBonusGunship1"), skill="Assault Frigates")

View File

@@ -1,7 +1,4 @@
# eliteBonusGunshipProjectileDamage2
#
# Used by:
# Ship: Jaguar
# Not used by any item
type = "passive"

View File

@@ -1,7 +1,4 @@
# eliteBonusGunshipProjectileOptimal1
#
# Used by:
# Ship: Jaguar
# Not used by any item
type = "passive"

View File

@@ -0,0 +1,10 @@
# eliteBonusGunshipThermalMissileDamage1
#
# Used by:
# Ship: Jaguar
type = "passive"
def handler(fit, src, context):
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"), "thermalDamage",
src.getModifiedItemAttr("eliteBonusGunship1"), skill="Assault Frigates")

View File

@@ -14,4 +14,5 @@ grouped = True
def handler(fit, src, context):
if "projected" not in context:
return
fit.ship.boostItemAttr("maxVelocity", src.getModifiedItemAttr("{}SpeedPenalty".format(prefix)) * src.amountActive)
fit.ship.boostItemAttr("maxVelocity", src.getModifiedItemAttr("{}SpeedPenalty".format(prefix)) * src.amountActive,
stackingPenalties=True)

View File

@@ -2,6 +2,7 @@
#
# Used by:
# Modules named like: Memetic Algorithm Bank (8 of 8)
# Implant: Neural Lace 'Blackglass' Net Intrusion 920-40
# Implant: Poteque 'Prospector' Environmental Analysis EY-1005
# Implant: Poteque 'Prospector' Hacking HC-905
# Skill: Hacking

View File

@@ -1,4 +1,7 @@
# Not used by any item
# hackingVirusStrengthBonus
#
# Used by:
# Implant: Neural Lace 'Blackglass' Net Intrusion 920-40
type = "passive"

View File

@@ -0,0 +1,16 @@
# moduleBonusAssaultDamageControl
#
# Used by:
# Variations of module: Assault Damage Control I (5 of 5)
type = "active"
runTime = "early"
def handler(fit, src, context):
for layer, attrPrefix in (('shield', 'shield'), ('armor', 'armor'), ('hull', '')):
for damageType in ('Kinetic', 'Thermal', 'Explosive', 'Em'):
bonus = "%s%sDamageResonance" % (attrPrefix, damageType)
bonus = "%s%s" % (bonus[0].lower(), bonus[1:])
booster = "%s%sDamageResonance" % (layer, damageType)
src.forceItemAttr(booster, src.getModifiedItemAttr("resistanceMultiplier"))

View File

@@ -0,0 +1,10 @@
# remoteWebifierMaxRangeBonus
#
# Used by:
# Implants named like: Inquest 'Eros' Stasis Webifier MR (3 of 3)
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Stasis Web", "maxRange",
src.getModifiedItemAttr("stasisWebRangeBonus"), stackingPenalties=True)

View File

@@ -0,0 +1,10 @@
# scriptscanGravimetricStrengthBonusBonus
#
# Used by:
# Charges from group: Structure ECM script (4 of 4)
type = "passive"
runTime = "early"
def handler(fit, src, context, *args, **kwargs):
src.boostItemAttr("scanGravimetricStrengthBonus", src.getModifiedChargeAttr("scanGravimetricStrengthBonusBonus"))

View File

@@ -0,0 +1,10 @@
# scriptscanLadarStrengthBonusBonus
#
# Used by:
# Charges from group: Structure ECM script (4 of 4)
type = "passive"
runTime = "early"
def handler(fit, src, context, *args, **kwargs):
src.boostItemAttr("scanLadarStrengthBonus", src.getModifiedChargeAttr("scanLadarStrengthBonusBonus"))

View File

@@ -0,0 +1,10 @@
# scriptscanMagnetometricStrengthBonusBonus
#
# Used by:
# Charges from group: Structure ECM script (4 of 4)
type = "passive"
runTime = "early"
def handler(fit, src, context, *args, **kwargs):
src.boostItemAttr("scanMagnetometricStrengthBonus", src.getModifiedChargeAttr("scanMagnetometricStrengthBonusBonus"))

View File

@@ -0,0 +1,10 @@
# scriptscanRadarStrengthBonusBonus
#
# Used by:
# Charges from group: Structure ECM script (4 of 4)
type = "passive"
runTime = "early"
def handler(fit, src, context, *args, **kwargs):
src.boostItemAttr("scanRadarStrengthBonus", src.getModifiedChargeAttr("scanRadarStrengthBonusBonus"))

View File

@@ -0,0 +1,11 @@
# scriptStandupWarpScram
#
# Used by:
# Charge: Standup Focused Warp Scrambling Script
type = "passive"
runTime = "early"
def handler(fit, src, context, *args, **kwargs):
src.boostItemAttr("maxRange", src.getModifiedChargeAttr("warpScrambleRangeBonus"))

View File

@@ -0,0 +1,7 @@
# Not used by any item
type = "passive"
runTime = "early"
def handler(fit, src, context):
fit.ship.forceItemAttr("structureFullPowerStateHitpointMultiplier", src.getModifiedItemAttr("serviceModuleFullPowerStateHitpointMultiplier"))

View File

@@ -0,0 +1,10 @@
# shipBonusDroneTrackingEliteGunship2
#
# Used by:
# Ship: Ishkur
type = "passive"
def handler(fit, src, context):
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "trackingSpeed",
src.getModifiedItemAttr("eliteBonusGunship2"), skill="Assault Frigates")

View File

@@ -2,6 +2,7 @@
#
# Used by:
# Ship: Breacher
# Ship: Jaguar
type = "passive"

View File

@@ -1,11 +1,12 @@
# shipPDmgBonusMF
#
# Used by:
# Variations of ship: Rifter (3 of 3)
# Variations of ship: Slasher (3 of 3)
# Ship: Cheetah
# Ship: Freki
# Ship: Republic Fleet Firetail
# Ship: Rifter
# Ship: Wolf
type = "passive"

View File

@@ -2,7 +2,6 @@
#
# Used by:
# Variations of ship: Slasher (3 of 3)
# Ship: Jaguar
# Ship: Republic Fleet Firetail
# Ship: Wolf
type = "passive"

View File

@@ -0,0 +1,10 @@
# shipSETROFAF
#
# Used by:
# Ship: Retribution
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Small Energy Turret"), "speed",
src.getModifiedItemAttr("shipBonusAF"), stackingPenalties=False, skill="Amarr Frigate")

View File

@@ -1,7 +1,4 @@
# shipSETTrackingBonusAF
#
# Used by:
# Ship: Retribution
# Not used by any item
type = "passive"

View File

@@ -2,6 +2,7 @@
#
# Used by:
# Ship: Breacher
# Ship: Jaguar
type = "passive"

View File

@@ -0,0 +1,11 @@
# Not used by any item
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Structure Guided Bomb Launcher",
"speed", ship.getModifiedItemAttr("structureAoERoFRoleBonus"))
for attr in ["duration", "durationTargetIlluminationBurstProjector", "durationWeaponDisruptionBurstProjector",
"durationECMJammerBurstProjector", "durationSensorDampeningBurstProjector", "capacitorNeed"]:
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Structure Burst Projector",
attr, ship.getModifiedItemAttr("structureAoERoFRoleBonus"))

View File

@@ -0,0 +1,7 @@
# Not used by any item
type = "passive"
runTime = "early"
def handler(fit, src, context):
fit.ship.multiplyItemAttr("hiddenArmorHPMultiplier", src.getModifiedItemAttr("armorHPMultiplier"))

View File

@@ -11,7 +11,7 @@ def handler(fit, module, context):
module.getModifiedItemAttr("missileDamageMultiplierBonus"),
stackingPenalties=True)
launcherGroups = ("Structure AXL Missile Launcher", "Structure ASML Missile Launcher")
launcherGroups = ("Structure XL Missile Launcher", "Structure Multirole Missile Launcher")
fit.modules.filteredItemMultiply(lambda mod: mod.item.group.name in launcherGroups,
"speed", module.getModifiedItemAttr("speedMultiplier"),
stackingPenalties=True)

View File

@@ -0,0 +1,6 @@
# Not used by any item
type = "passive"
def handler(fit, ship, context):
fit.ship.increaseItemAttr("capacitorCapacity", ship.getModifiedItemAttr("capacitorBonus"))

View File

@@ -0,0 +1,7 @@
# Not used by any item
type = "passive"
def handler(fit, src, context):
fit.ship.multiplyItemAttr("shieldCapacity", src.getModifiedItemAttr("structureFullPowerStateHitpointMultiplier") or 0)
fit.ship.multiplyItemAttr("armorHP", src.getModifiedItemAttr("structureFullPowerStateHitpointMultiplier") or 0)

View File

@@ -0,0 +1,6 @@
# Not used by any item
type = "passive"
def handler(fit, src, context):
fit.ship.multiplyItemAttr("armorHP", src.getModifiedItemAttr("hiddenArmorHPMultiplier") or 0)

View File

@@ -0,0 +1,10 @@
# Not used by any item
type = "passive"
def handler(fit, src, context):
groups = ("Structure Anti-Subcapital Missile", "Structure Anti-Capital Missile")
for dmgType in ("em", "kinetic", "explosive", "thermal"):
fit.modules.filteredChargeMultiply(lambda mod: mod.item.group.name in groups,
"%sDamage" % dmgType,
src.getModifiedItemAttr("hiddenMissileDamageMultiplier"))

View File

@@ -0,0 +1,15 @@
# Not used by any item
type = "passive"
def handler(fit, container, context):
missileGroups = ("Structure Anti-Capital Missile", "Structure Anti-Subcapital Missile")
for srcAttr, tgtAttr in (
("aoeCloudSizeBonus", "aoeCloudSize"),
("aoeVelocityBonus", "aoeVelocity"),
("missileVelocityBonus", "maxVelocity"),
("explosionDelayBonus", "explosionDelay"),
):
fit.modules.filteredChargeBoost(lambda mod: mod.charge.group.name in missileGroups,
tgtAttr, container.getModifiedItemAttr(srcAttr),
stackingPenalties=True)

View File

@@ -0,0 +1,6 @@
# Not used by any item
type = "passive"
def handler(fit, module, context):
fit.ship.multiplyItemAttr("rechargeRate", module.getModifiedItemAttr("capacitorRechargeRateMultiplier"))

View File

@@ -0,0 +1,6 @@
# Not used by any item
type = "passive"
def handler(fit, module, context):
fit.ship.boostItemAttr("maxTargetRange", module.getModifiedItemAttr("structureRigMaxTargetRangeBonus"))

View File

@@ -7,12 +7,12 @@ type = "projected", "active"
def handler(fit, module, context):
if "projected" not in context:
return
fit.ship.increaseItemAttr("warpScrambleStatus", module.getModifiedItemAttr("warpScrambleStrength"))
# this is such a dirty hack
for mod in fit.modules:
if not mod.isEmpty and mod.item.requiresSkill("High Speed Maneuvering") and mod.state > State.ONLINE:
mod.state = State.ONLINE
if "projected" in context:
fit.ship.increaseItemAttr("warpScrambleStatus", module.getModifiedItemAttr("warpScrambleStrength"))
if module.charge is not None and module.charge.ID == 47336:
for mod in fit.modules:
if not mod.isEmpty and mod.state > State.ONLINE and (
mod.item.requiresSkill("High Speed Maneuvering")
or mod.item.requiresSkill("Micro Jump Drive Operation")
):
mod.state = State.ONLINE

View File

@@ -1,3 +1,4 @@
# warpDisruptSphere
#
# Used by:
@@ -9,18 +10,23 @@ runTime = "early"
def handler(fit, module, context):
fit.ship.boostItemAttr("mass", module.getModifiedItemAttr("massBonusPercentage"))
fit.ship.boostItemAttr("signatureRadius", module.getModifiedItemAttr("signatureRadiusBonus"))
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Propulsion Module",
"speedBoostFactor", module.getModifiedItemAttr("speedBoostFactorBonus"))
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Propulsion Module",
"speedFactor", module.getModifiedItemAttr("speedFactorBonus"))
fit.ship.forceItemAttr("disallowAssistance", 1)
if "projected" in context:
fit.ship.increaseItemAttr("warpScrambleStatus", module.getModifiedItemAttr("warpScrambleStrength"))
if module.charge is not None and module.charge.ID == 45010:
for mod in fit.modules:
if not mod.isEmpty and mod.item.requiresSkill("High Speed Maneuvering") and mod.state > State.ONLINE:
mod.state = State.ONLINE
if not mod.isEmpty and mod.item.requiresSkill("Micro Jump Drive Operation") and mod.state > State.ONLINE:
mod.state = State.ONLINE
else:
if module.charge is None:
fit.ship.boostItemAttr("mass", module.getModifiedItemAttr("massBonusPercentage"))
fit.ship.boostItemAttr("signatureRadius", module.getModifiedItemAttr("signatureRadiusBonus"))
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Propulsion Module",
"speedBoostFactor", module.getModifiedItemAttr("speedBoostFactorBonus"))
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Propulsion Module",
"speedFactor", module.getModifiedItemAttr("speedFactorBonus"))
fit.ship.forceItemAttr("disallowAssistance", 1)

View File

@@ -16,5 +16,8 @@ def handler(fit, module, context):
# this is such a dirty hack
for mod in fit.modules:
if not mod.isEmpty and mod.item.requiresSkill("High Speed Maneuvering") and mod.state > State.ONLINE:
if not mod.isEmpty and mod.state > State.ONLINE and (
mod.item.requiresSkill("Micro Jump Drive Operation")
or mod.item.requiresSkill("High Speed Maneuvering")
):
mod.state = State.ONLINE

View File

@@ -81,7 +81,7 @@ class FitDpsGraph(Graph):
total += dps * self.calculateTurretMultiplier(mod, data)
elif mod.hardpoint == Hardpoint.MISSILE:
if mod.state >= State.ACTIVE and mod.maxRange >= distance:
if mod.state >= State.ACTIVE and mod.maxRange is not None and mod.maxRange >= distance:
total += dps * self.calculateMissileMultiplier(mod, data)
if distance <= fit.extraAttributes["droneControlRange"]:

View File

@@ -18,12 +18,16 @@
# ===============================================================================
import re
import eos.db
class DamagePattern(object):
DAMAGE_TYPES = ("em", "thermal", "kinetic", "explosive")
def __init__(self, emAmount=25, thermalAmount=25, kineticAmount=25, explosiveAmount=25):
def __init__(self, *args, **kwargs):
self.update(*args, **kwargs)
def update(self, emAmount=25, thermalAmount=25, kineticAmount=25, explosiveAmount=25):
self.emAmount = emAmount
self.thermalAmount = thermalAmount
self.kineticAmount = kineticAmount
@@ -74,6 +78,14 @@ class DamagePattern(object):
lines = re.split('[\n\r]+', text)
patterns = []
numPatterns = 0
# When we import damage profiles, we create new ones and update old ones. To do this, get a list of current
# patterns to allow lookup
lookup = {}
current = eos.db.getDamagePatternList()
for pattern in current:
lookup[pattern.name] = pattern
for line in lines:
try:
if line.strip()[0] == "#": # comments
@@ -99,10 +111,18 @@ class DamagePattern(object):
continue
if len(fields) == 4: # Avoid possible blank lines
pattern = DamagePattern(**fields)
pattern.name = name.strip()
if name.strip() in lookup:
pattern = lookup[name.strip()]
pattern.update(**fields)
eos.db.save(pattern)
else:
pattern = DamagePattern(**fields)
pattern.name = name.strip()
eos.db.save(pattern)
patterns.append(pattern)
eos.db.commit()
return patterns, numPatterns
EXPORT_FORMAT = "DamageProfile = %s,%d,%d,%d,%d\n"

View File

@@ -264,7 +264,7 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
def fits(self, fit):
fitDroneGroupLimits = set()
for i in range(1, 3):
groneGrp = fit.ship.getModifiedItemAttr("allowedDroneGroup%d" % i)
groneGrp = fit.ship.getModifiedItemAttr("allowedDroneGroup%d" % i, None)
if groneGrp is not None:
fitDroneGroupLimits.add(int(groneGrp))
if len(fitDroneGroupLimits) == 0:

View File

@@ -89,8 +89,8 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
self.__itemModifiedAttributes.overrides = self.__item.overrides
self.__slot = self.__calculateSlot(self.__item)
chargeID = self.getModifiedItemAttr("fighterAbilityLaunchBombType", None)
if chargeID is not None:
chargeID = self.getModifiedItemAttr("fighterAbilityLaunchBombType")
if chargeID:
charge = eos.db.getItem(int(chargeID))
self.__charge = charge
self.__chargeModifiedAttributes.original = charge.attributes
@@ -104,7 +104,10 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
types = {
"Light" : Slot.F_LIGHT,
"Support": Slot.F_SUPPORT,
"Heavy" : Slot.F_HEAVY
"Heavy" : Slot.F_HEAVY,
"StandupLight": Slot.FS_LIGHT,
"StandupSupport": Slot.FS_SUPPORT,
"StandupHeavy": Slot.FS_HEAVY
}
for t, slot in types.items():

View File

@@ -917,7 +917,7 @@ class Fit(object):
for mod in chain(self.modules, self.fighters):
if mod.slot is type and (not getattr(mod, "isEmpty", False) or countDummies):
if type in (Slot.F_HEAVY, Slot.F_SUPPORT, Slot.F_LIGHT) and not mod.active:
if type in (Slot.F_HEAVY, Slot.F_SUPPORT, Slot.F_LIGHT, Slot.FS_HEAVY, Slot.FS_LIGHT, Slot.FS_SUPPORT) and not mod.active:
continue
amount += 1
@@ -932,7 +932,10 @@ class Fit(object):
Slot.SERVICE : "serviceSlots",
Slot.F_LIGHT : "fighterLightSlots",
Slot.F_SUPPORT: "fighterSupportSlots",
Slot.F_HEAVY : "fighterHeavySlots"
Slot.F_HEAVY : "fighterHeavySlots",
Slot.FS_LIGHT: "fighterStandupLightSlots",
Slot.FS_SUPPORT: "fighterStandupSupportSlots",
Slot.FS_HEAVY: "fighterStandupHeavySlots",
}
def getSlotsFree(self, type, countDummies=False):

View File

@@ -56,6 +56,10 @@ class Slot(Enum):
F_LIGHT = 10
F_SUPPORT = 11
F_HEAVY = 12
# fighter 'slots' (for structures)
FS_LIGHT = 13
FS_SUPPORT = 14
FS_HEAVY = 15
class Hardpoint(Enum):
@@ -178,7 +182,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
@property
def numShots(self):
if self.charge is None:
return -1
return 0
if self.__chargeCycles is None and self.charge:
numCharges = self.numCharges
# Usual ammo like projectiles and missiles
@@ -430,9 +434,9 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
and fit.ship.item.ID not in fitsOnType:
return False
# AFAIK Citadel modules will always be restricted based on canFitShipType/Group. If we are fitting to a Citadel
# and the module does not have these properties, return false to prevent regular ship modules from being used
if isinstance(fit.ship, Citadel) and len(fitsOnGroup) == 0 and len(fitsOnType) == 0:
# Citadel modules are now under a new category, so we can check this to ensure only structure modules can fit on a citadel
if isinstance(fit.ship, Citadel) and self.item.category.name != "Structure Module" or \
not isinstance(fit.ship, Citadel) and self.item.category.name == "Structure Module":
return False
# EVE doesn't let capital modules be fit onto subcapital hulls. Confirmed by CCP Larrikin that this is dictated

View File

@@ -19,6 +19,7 @@
import re
from logbook import Logger
import eos.db
pyfalog = Logger(__name__)
@@ -27,7 +28,10 @@ class TargetResists(object):
# also determined import/export order - VERY IMPORTANT
DAMAGE_TYPES = ("em", "thermal", "kinetic", "explosive")
def __init__(self, emAmount=0, thermalAmount=0, kineticAmount=0, explosiveAmount=0):
def __init__(self, *args, **kwargs):
self.update(*args, **kwargs)
def update(self, emAmount=0, thermalAmount=0, kineticAmount=0, explosiveAmount=0):
self.emAmount = emAmount
self.thermalAmount = thermalAmount
self.kineticAmount = kineticAmount
@@ -38,6 +42,14 @@ class TargetResists(object):
lines = re.split('[\n\r]+', text)
patterns = []
numPatterns = 0
# When we import damage profiles, we create new ones and update old ones. To do this, get a list of current
# patterns to allow lookup
lookup = {}
current = eos.db.getTargetResistsList()
for pattern in current:
lookup[pattern.name] = pattern
for line in lines:
try:
if line.strip()[0] == "#": # comments
@@ -66,10 +78,18 @@ class TargetResists(object):
continue
if len(fields) == 4: # Avoid possible blank lines
pattern = TargetResists(**fields)
pattern.name = name.strip()
if name.strip() in lookup:
pattern = lookup[name.strip()]
pattern.update(**fields)
eos.db.save(pattern)
else:
pattern = TargetResists(**fields)
pattern.name = name.strip()
eos.db.save(pattern)
patterns.append(pattern)
eos.db.commit()
return patterns, numPatterns
EXPORT_FORMAT = "TargetResists = %s,%.1f,%.1f,%.1f,%.1f\n"