Merge branch 'master' into wx3
Conflicts: gui/characterEditor.py
This commit is contained in:
@@ -18,8 +18,8 @@ debug = False
|
||||
saveInRoot = False
|
||||
|
||||
# Version data
|
||||
version = "1.14.0"
|
||||
tag = "Stable"
|
||||
version = "1.14.1"
|
||||
tag = "git"
|
||||
expansionName = "Galatea"
|
||||
expansionVersion = "1.2"
|
||||
evemonMinVersion = "4081"
|
||||
|
||||
@@ -5,7 +5,7 @@ debug = False
|
||||
gamedataCache = True
|
||||
saveddataCache = True
|
||||
gamedata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "staticdata", "eve.db")), sys.getfilesystemencoding())
|
||||
saveddata_connectionstring = 'sqlite:///:memory:'
|
||||
saveddata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "saveddata", "saveddata.db")), sys.getfilesystemencoding())
|
||||
|
||||
#Autodetect path, only change if the autodetection bugs out.
|
||||
path = dirname(unicode(__file__, sys.getfilesystemencoding()))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# eliteBonusHeavyInterdictorsWarpDisruptFieldGeneratorWarpScrambleRange2
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Heavy Interdiction Cruiser (4 of 5)
|
||||
# Ships from group: Heavy Interdiction Cruiser (5 of 5)
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Warp Disrupt Field Generator",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Interceptor2WarpScrambleRange
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Interceptor (5 of 10)
|
||||
# Ships from group: Interceptor (6 of 10)
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Warp Scrambler",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# interceptorMWDSignatureRadiusBonus
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Interceptor (9 of 10)
|
||||
# Ships from group: Interceptor (10 of 10)
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("High Speed Maneuvering"),
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# Celestials named like: Drifter Incursion (6 of 6)
|
||||
# Celestials named like: Incursion ship attributes effects (3 of 3)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
damages = ("em", "thermal", "kinetic", "explosive")
|
||||
for damage in damages:
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
# Used by:
|
||||
# Modules from group: Jump Drive Economizer (3 of 3)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, module, context):
|
||||
fit.ship.boostItemAttr("jumpDriveConsumptionAmount", module.getModifiedItemAttr("consumptionQuantityBonusPercentage"), stackingPenalties=True)
|
||||
|
||||
13
eos/effects/shipbonuswdfgnullspeedeffects.py
Normal file
13
eos/effects/shipbonuswdfgnullspeedeffects.py
Normal file
@@ -0,0 +1,13 @@
|
||||
# shipBonusWDFGnullSpeedEffects
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Fiend
|
||||
runTime = "early"
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Propulsion Jamming"),
|
||||
"speedFactorBonus", ship.getModifiedItemAttr("shipBonusAT"))
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Propulsion Jamming"),
|
||||
"speedBoostFactorBonus", ship.getModifiedItemAttr("shipBonusAT"))
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Propulsion Jamming"),
|
||||
"massBonusPercentage", ship.getModifiedItemAttr("shipBonusAT"))
|
||||
@@ -1,7 +1,7 @@
|
||||
# shipCapPropulsionJamming
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Interceptor (9 of 10)
|
||||
# Ships from group: Interceptor (10 of 10)
|
||||
# Ship: Atron
|
||||
# Ship: Condor
|
||||
# Ship: Executioner
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
# shipShieldEMResistanceRookie
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Broadsword
|
||||
# Ships from group: Heavy Interdiction Cruiser (3 of 5)
|
||||
# Ship: Ibis
|
||||
# Ship: Onyx
|
||||
# Ship: Taipan
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
# shipShieldExplosiveResistanceRookie
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Broadsword
|
||||
# Ships from group: Heavy Interdiction Cruiser (3 of 5)
|
||||
# Ship: Ibis
|
||||
# Ship: Onyx
|
||||
# Ship: Taipan
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
# shipShieldKineticResistanceRookie
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Broadsword
|
||||
# Ships from group: Heavy Interdiction Cruiser (3 of 5)
|
||||
# Ship: Ibis
|
||||
# Ship: Onyx
|
||||
# Ship: Taipan
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
# shipShieldThermalResistanceRookie
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Broadsword
|
||||
# Ships from group: Heavy Interdiction Cruiser (3 of 5)
|
||||
# Ship: Ibis
|
||||
# Ship: Onyx
|
||||
# Ship: Taipan
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
# Used by:
|
||||
# Celestials named like: Black Hole Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.ship.multiplyItemAttr("agility", beacon.getModifiedItemAttr("agilityMultiplier"), stackingPenalties=True)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Magnetar Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredChargeMultiply(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"),
|
||||
"aoeCloudSize", beacon.getModifiedItemAttr("aoeCloudSizeMultiplier"))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Black Hole Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredChargeMultiply(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"),
|
||||
"aoeVelocity", beacon.getModifiedItemAttr("aoeVelocityMultiplier"))
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# Celestials named like: Incursion Effect (2 of 2)
|
||||
# Celestials named like: Pulsar Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.ship.boostItemAttr("armorEmDamageResonance", beacon.getModifiedItemAttr("armorEmDamageResistanceBonus"),
|
||||
stackingPenalties=True)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# Celestials named like: Incursion Effect (2 of 2)
|
||||
# Celestials named like: Pulsar Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.ship.boostItemAttr("armorExplosiveDamageResonance", beacon.getModifiedItemAttr("armorExplosiveDamageResistanceBonus"),
|
||||
stackingPenalties=True)
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
# Used by:
|
||||
# Celestials named like: Wolf Rayet Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.ship.multiplyItemAttr("armorHP", beacon.getModifiedItemAttr("armorHPMultiplier"))
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# Celestials named like: Incursion Effect (2 of 2)
|
||||
# Celestials named like: Pulsar Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.ship.boostItemAttr("armorKineticDamageResonance", beacon.getModifiedItemAttr("armorKineticDamageResistanceBonus"),
|
||||
stackingPenalties=True)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Cataclysmic Variable Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.group.name == "Remote Armor Repairer",
|
||||
"armorDamageAmount", module.getModifiedItemAttr("armorDamageAmountMultiplierRemote"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Cataclysmic Variable Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.group.name == "Armor Repair Unit",
|
||||
"armorDamageAmount", module.getModifiedItemAttr("armorDamageAmountMultiplier"),
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# Celestials named like: Incursion Effect (2 of 2)
|
||||
# Celestials named like: Pulsar Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.ship.boostItemAttr("armorThermalDamageResonance", beacon.getModifiedItemAttr("armorThermalDamageResistanceBonus"),
|
||||
stackingPenalties=True)
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
# Used by:
|
||||
# Celestials named like: Cataclysmic Variable Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.ship.multiplyItemAttr("capacitorCapacity", beacon.getModifiedItemAttr("capacitorCapacityMultiplierSystem"))
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
# Celestials named like: Cataclysmic Variable Effect Beacon Class (6 of 6)
|
||||
# Celestials named like: Pulsar Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.ship.multiplyItemAttr("rechargeRate", beacon.getModifiedItemAttr("rechargeRateMultiplier"))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Magnetar Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.drones.filteredItemMultiply(lambda drone: drone.item.requiresSkill("Drones"),
|
||||
"damageMultiplier", beacon.getModifiedItemAttr("damageMultiplierMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Red Giant Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredChargeMultiply(lambda mod: mod.charge.requiresSkill("Bomb Deployment"),
|
||||
"emDamage", beacon.getModifiedItemAttr("smartbombDamageMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Magnetar Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredChargeMultiply(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"),
|
||||
"emDamage", beacon.getModifiedItemAttr("damageMultiplierMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Red Giant Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredChargeMultiply(lambda mod: mod.charge.requiresSkill("Bomb Deployment"),
|
||||
"explosiveDamage", beacon.getModifiedItemAttr("smartbombDamageMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Magnetar Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredChargeMultiply(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"),
|
||||
"explosiveDamage", beacon.getModifiedItemAttr("damageMultiplierMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Magnetar Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.drones.filteredItemMultiply(lambda drone: drone.item.requiresSkill("Fighters"),
|
||||
"damageMultiplier", beacon.getModifiedItemAttr("damageMultiplierMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Red Giant Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredChargeMultiply(lambda mod: mod.charge.requiresSkill("Bomb Deployment"),
|
||||
"kineticDamage", beacon.getModifiedItemAttr("smartbombDamageMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Magnetar Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredChargeMultiply(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"),
|
||||
"kineticDamage", beacon.getModifiedItemAttr("damageMultiplierMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Magnetar Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.requiresSkill("Gunnery"),
|
||||
"damageMultiplier", beacon.getModifiedItemAttr("damageMultiplierMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Red Giant Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredChargeMultiply(lambda mod: mod.charge.requiresSkill("Bomb Deployment"),
|
||||
"thermalDamage", beacon.getModifiedItemAttr("smartbombDamageMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Magnetar Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredChargeMultiply(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"),
|
||||
"thermalDamage", beacon.getModifiedItemAttr("damageMultiplierMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Magnetar Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.drones.filteredItemMultiply(lambda drone: True,
|
||||
"trackingSpeed", beacon.getModifiedItemAttr("trackingSpeedMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Pulsar Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.group.name == "Energy Destabilizer",
|
||||
"energyDestabilizationAmount", beacon.getModifiedItemAttr("energyWarfareStrengthMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Pulsar Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.group.name == "Energy Vampire",
|
||||
"powerTransferAmount", beacon.getModifiedItemAttr("energyWarfareStrengthMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Red Giant Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredChargeMultiply(lambda mod: mod.charge.requiresSkill("Bomb Deployment"),
|
||||
"scanGravimetricStrengthBonus", beacon.getModifiedItemAttr("smartbombDamageMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Red Giant Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: "heatDamage" in mod.itemModifiedAttributes,
|
||||
"heatDamage", module.getModifiedItemAttr("heatDamageMultiplier"))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Red Giant Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredChargeMultiply(lambda mod: mod.charge.requiresSkill("Bomb Deployment"),
|
||||
"scanLadarStrengthBonus", beacon.getModifiedItemAttr("smartbombDamageMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Red Giant Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredChargeMultiply(lambda mod: mod.charge.requiresSkill("Bomb Deployment"),
|
||||
"scanMagnetometricStrengthBonus", beacon.getModifiedItemAttr("smartbombDamageMultiplier"),
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
# Used by:
|
||||
# Celestials named like: Black Hole Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.ship.multiplyItemAttr("maxVelocity", beacon.getModifiedItemAttr("maxVelocityMultiplier"), stackingPenalties=True, penaltyGroup="postMul")
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
# Used by:
|
||||
# Celestials named like: Drifter Incursion (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.ship.boostItemAttr("maxVelocity", beacon.getModifiedItemAttr("maxVelocityMultiplier"), stackingPenalties=True)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Black Hole Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredChargeMultiply(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"),
|
||||
"maxVelocity", beacon.getModifiedItemAttr("missileVelocityMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Red Giant Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredChargeMultiply(lambda mod: mod.charge.requiresSkill("Bomb Deployment"),
|
||||
"energyDestabilizationAmount", beacon.getModifiedItemAttr("smartbombDamageMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Red Giant Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: "overloadArmorDamageAmount" in mod.itemModifiedAttributes,
|
||||
"overloadArmorDamageAmount", module.getModifiedItemAttr("overloadBonusMultiplier"))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Red Giant Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: "overloadDamageModifier" in mod.itemModifiedAttributes,
|
||||
"overloadDamageModifier", module.getModifiedItemAttr("overloadBonusMultiplier"))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Red Giant Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: "overloadDurationBonus" in mod.itemModifiedAttributes,
|
||||
"overloadDurationBonus", module.getModifiedItemAttr("overloadBonusMultiplier"))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Red Giant Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: "overloadECCMStrenghtBonus" in mod.itemModifiedAttributes,
|
||||
"overloadECCMStrenghtBonus", module.getModifiedItemAttr("overloadBonusMultiplier"))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Red Giant Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: "overloadECMStrenghtBonus" in mod.itemModifiedAttributes,
|
||||
"overloadECMStrenghtBonus", module.getModifiedItemAttr("overloadBonusMultiplier"))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Red Giant Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: "overloadHardeningBonus" in mod.itemModifiedAttributes,
|
||||
"overloadHardeningBonus", module.getModifiedItemAttr("overloadBonusMultiplier"))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Red Giant Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: "overloadRangeBonus" in mod.itemModifiedAttributes,
|
||||
"overloadRangeBonus", module.getModifiedItemAttr("overloadBonusMultiplier"))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Red Giant Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: "overloadRofBonus" in mod.itemModifiedAttributes,
|
||||
"overloadRofBonus", module.getModifiedItemAttr("overloadBonusMultiplier"))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Red Giant Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: "overloadSelfDurationBonus" in mod.itemModifiedAttributes,
|
||||
"overloadSelfDurationBonus", module.getModifiedItemAttr("overloadBonusMultiplier"))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Red Giant Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: "overloadShieldBonus" in mod.itemModifiedAttributes,
|
||||
"overloadShieldBonus", module.getModifiedItemAttr("overloadBonusMultiplier"))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Red Giant Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: "overloadSpeedFactorBonus" in mod.itemModifiedAttributes,
|
||||
"overloadSpeedFactorBonus", module.getModifiedItemAttr("overloadBonusMultiplier"))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Red Giant Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredChargeMultiply(lambda mod: mod.charge.requiresSkill("Bomb Deployment"),
|
||||
"scanRadarStrengthBonus", beacon.getModifiedItemAttr("smartbombDamageMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Cataclysmic Variable Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.group.name == "Remote Capacitor Transmitter",
|
||||
"powerTransferAmount", beacon.getModifiedItemAttr("energyTransferAmountBonus"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Wolf Rayet Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredChargeMultiply(lambda mod: mod.charge.requiresSkill("Rockets"),
|
||||
"emDamage", beacon.getModifiedItemAttr("smallWeaponDamageMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Wolf Rayet Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredChargeMultiply(lambda mod: mod.charge.requiresSkill("Rockets"),
|
||||
"explosiveDamage", beacon.getModifiedItemAttr("smallWeaponDamageMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Wolf Rayet Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredChargeMultiply(lambda mod: mod.charge.requiresSkill("Rockets"),
|
||||
"kineticDamage", beacon.getModifiedItemAttr("smallWeaponDamageMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Wolf Rayet Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredChargeMultiply(lambda mod: mod.charge.requiresSkill("Rockets"),
|
||||
"thermalDamage", beacon.getModifiedItemAttr("smallWeaponDamageMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Wolf Rayet Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.ship.boostItemAttr("shieldEmDamageResonance", beacon.getModifiedItemAttr("shieldEmDamageResistanceBonus"),
|
||||
stackingPenalties=True)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Wolf Rayet Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.ship.boostItemAttr("shieldExplosiveDamageResonance", beacon.getModifiedItemAttr("shieldExplosiveDamageResistanceBonus"),
|
||||
stackingPenalties=True)
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
# Used by:
|
||||
# Celestials named like: Pulsar Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.ship.multiplyItemAttr("shieldCapacity", beacon.getModifiedItemAttr("shieldCapacityMultiplier"))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Wolf Rayet Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.ship.boostItemAttr("shieldKineticDamageResonance", beacon.getModifiedItemAttr("shieldKineticDamageResistanceBonus"),
|
||||
stackingPenalties=True)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Cataclysmic Variable Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.group.name == "Remote Shield Booster",
|
||||
"shieldBonus", module.getModifiedItemAttr("shieldBonusMultiplierRemote"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Cataclysmic Variable Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.requiresSkill("Shield Operation") or mod.item.requiresSkill("Capital Shield Operation"),
|
||||
"shieldBonus", module.getModifiedItemAttr("shieldBonusMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Wolf Rayet Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.ship.boostItemAttr("shieldThermalDamageResonance", beacon.getModifiedItemAttr("shieldThermalDamageResistanceBonus"),
|
||||
stackingPenalties=True)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# Celestials named like: Pulsar Effect Beacon Class (6 of 6)
|
||||
# Celestials named like: Wolf Rayet Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.ship.multiplyItemAttr("signatureRadius", beacon.getModifiedItemAttr("signatureRadiusMultiplier"),
|
||||
stackingPenalties=True, penaltyGroup="postMul")
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Wolf Rayet Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.requiresSkill("Small Energy Turret"),
|
||||
"damageMultiplier", module.getModifiedItemAttr("smallWeaponDamageMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Wolf Rayet Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.requiresSkill("Small Hybrid Turret"),
|
||||
"damageMultiplier", module.getModifiedItemAttr("smallWeaponDamageMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Wolf Rayet Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.requiresSkill("Small Projectile Turret"),
|
||||
"damageMultiplier", module.getModifiedItemAttr("smallWeaponDamageMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Red Giant Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.group.name == "Smart Bomb",
|
||||
"emDamage", module.getModifiedItemAttr("smartbombDamageMultiplier"))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Red Giant Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.group.name == "Smart Bomb",
|
||||
"explosiveDamage", module.getModifiedItemAttr("smartbombDamageMultiplier"))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Red Giant Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.group.name == "Smart Bomb",
|
||||
"kineticDamage", module.getModifiedItemAttr("smartbombDamageMultiplier"))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Red Giant Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.group.name == "Smart Bomb",
|
||||
"empFieldRange", module.getModifiedItemAttr("empFieldRangeMultiplier"))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Red Giant Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.group.name == "Smart Bomb",
|
||||
"thermalDamage", module.getModifiedItemAttr("smartbombDamageMultiplier"))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Wolf Rayet Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredChargeMultiply(lambda mod: mod.charge.requiresSkill("Light Missiles"),
|
||||
"emDamage", beacon.getModifiedItemAttr("smallWeaponDamageMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Wolf Rayet Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredChargeMultiply(lambda mod: mod.charge.requiresSkill("Light Missiles"),
|
||||
"explosiveDamage", beacon.getModifiedItemAttr("smallWeaponDamageMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Wolf Rayet Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredChargeMultiply(lambda mod: mod.charge.requiresSkill("Light Missiles"),
|
||||
"kineticDamage", beacon.getModifiedItemAttr("smallWeaponDamageMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Wolf Rayet Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredChargeMultiply(lambda mod: mod.charge.requiresSkill("Light Missiles"),
|
||||
"thermalDamage", beacon.getModifiedItemAttr("smallWeaponDamageMultiplier"),
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# Celestials named like: Black Hole Effect Beacon Class (6 of 6)
|
||||
# Celestials named like: Magnetar Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.ship.multiplyItemAttr("maxTargetRange", beacon.getModifiedItemAttr("maxTargetRangeMultiplier"),
|
||||
stackingPenalties=True, penaltyGroup="postMul")
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Magnetar Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.requiresSkill("Target Painting"),
|
||||
"signatureRadiusBonus", beacon.getModifiedItemAttr("targetPainterStrengthMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Magnetar Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.requiresSkill("Gunnery"),
|
||||
"trackingSpeed", module.getModifiedItemAttr("trackingSpeedMultiplier"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Celestials named like: Black Hole Effect Beacon Class (6 of 6)
|
||||
runTime = "early"
|
||||
type = ("projected", "offline")
|
||||
type = ("projected", "passive")
|
||||
def handler(fit, beacon, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.group.name == "Stasis Web",
|
||||
"speedFactor", beacon.getModifiedItemAttr("stasisWebStrengthMultiplier"),
|
||||
|
||||
@@ -4,5 +4,13 @@
|
||||
# Variations of module: Warp Scrambler I (19 of 19)
|
||||
runTime = "early"
|
||||
type = "projected", "active"
|
||||
|
||||
from eos.types import State
|
||||
|
||||
def handler(fit, module, context):
|
||||
pass
|
||||
if "projected" not in context:
|
||||
return
|
||||
# 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
|
||||
|
||||
@@ -250,11 +250,11 @@ class ModifiedAttributeDict(collections.MutableMapping):
|
||||
|
||||
def increase(self, attributeName, increase, position="pre", skill=None):
|
||||
"""Increase value of given attribute by given number"""
|
||||
# Increases applied before multiplications and after them are
|
||||
# written in separate maps
|
||||
if skill:
|
||||
increase *= self.__handleSkill(skill)
|
||||
|
||||
# Increases applied before multiplications and after them are
|
||||
# written in separate maps
|
||||
if position == "pre":
|
||||
tbl = self.__preIncreases
|
||||
elif position == "post":
|
||||
@@ -269,11 +269,11 @@ class ModifiedAttributeDict(collections.MutableMapping):
|
||||
|
||||
def multiply(self, attributeName, multiplier, stackingPenalties=False, penaltyGroup="default", skill=None):
|
||||
"""Multiply value of given attribute by given factor"""
|
||||
# If we're asked to do stacking penalized multiplication, append values
|
||||
# to per penalty group lists
|
||||
if skill:
|
||||
multiplier *= self.__handleSkill(skill)
|
||||
|
||||
# If we're asked to do stacking penalized multiplication, append values
|
||||
# to per penalty group lists
|
||||
if stackingPenalties:
|
||||
if not attributeName in self.__penalizedMultipliers:
|
||||
self.__penalizedMultipliers[attributeName] = {}
|
||||
@@ -291,9 +291,10 @@ class ModifiedAttributeDict(collections.MutableMapping):
|
||||
|
||||
def boost(self, attributeName, boostFactor, skill=None, *args, **kwargs):
|
||||
"""Boost value by some percentage"""
|
||||
# We just transform percentage boost into multiplication factor
|
||||
if skill:
|
||||
boostFactor *= self.__handleSkill(skill)
|
||||
|
||||
# We just transform percentage boost into multiplication factor
|
||||
self.multiply(attributeName, 1 + boostFactor / 100.0, *args, **kwargs)
|
||||
|
||||
def force(self, attributeName, value):
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
from sqlalchemy.orm import validates, reconstructor
|
||||
|
||||
from eos.effectHandlerHelpers import HandledItem
|
||||
import eos.db
|
||||
import eos
|
||||
|
||||
|
||||
class Character(object):
|
||||
__all5 = None
|
||||
__all0 = None
|
||||
__itemList = None
|
||||
__itemIDMap = None
|
||||
__itemNameMap = None
|
||||
@@ -33,7 +33,6 @@ class Character(object):
|
||||
@classmethod
|
||||
def getSkillList(cls):
|
||||
if cls.__itemList is None:
|
||||
import eos.db
|
||||
cls.__itemList = eos.db.getItemsByCategory("Skill")
|
||||
|
||||
return cls.__itemList
|
||||
@@ -66,36 +65,39 @@ class Character(object):
|
||||
|
||||
@classmethod
|
||||
def getAll5(cls):
|
||||
if cls.__all5 is None:
|
||||
import eos.db
|
||||
all5 = eos.db.getCharacter("All 5")
|
||||
if all5 is None:
|
||||
all5 = Character("All 5")
|
||||
all5.defaultLevel = 5
|
||||
eos.db.add(all5)
|
||||
all5 = eos.db.getCharacter("All 5")
|
||||
|
||||
cls.__all5 = all5
|
||||
return cls.__all5
|
||||
if all5 is None:
|
||||
# We do not have to be afraid of committing here and saving
|
||||
# edited character data. If this ever runs, it will be during the
|
||||
# get character list phase when pyfa first starts
|
||||
all5 = Character("All 5", 5)
|
||||
eos.db.save(all5)
|
||||
|
||||
return all5
|
||||
|
||||
@classmethod
|
||||
def getAll0(cls):
|
||||
if cls.__all0 is None:
|
||||
import eos.db
|
||||
all0 = eos.db.getCharacter("All 0")
|
||||
if all0 is None:
|
||||
all0 = Character("All 0")
|
||||
all0.defaultLevel = None
|
||||
eos.db.add(all0)
|
||||
all0 = eos.db.getCharacter("All 0")
|
||||
|
||||
cls.__all0 = all0
|
||||
return cls.__all0
|
||||
if all0 is None:
|
||||
all0 = Character("All 0")
|
||||
eos.db.save(all0)
|
||||
|
||||
def __init__(self, name):
|
||||
return all0
|
||||
|
||||
def __init__(self, name, defaultLevel=None, initSkills=True):
|
||||
self.name = name
|
||||
self.__owner = None
|
||||
self.defaultLevel = None
|
||||
self.defaultLevel = defaultLevel
|
||||
self.__skills = []
|
||||
self.__skillIdMap = {}
|
||||
self.dirtySkills = set()
|
||||
|
||||
if initSkills:
|
||||
for item in self.getSkillList():
|
||||
self.addSkill(Skill(item.ID, self.defaultLevel))
|
||||
|
||||
self.__implants = eos.saveddata.fit.HandledImplantBoosterList()
|
||||
self.apiKey = None
|
||||
|
||||
@@ -104,14 +106,18 @@ class Character(object):
|
||||
self.__skillIdMap = {}
|
||||
for skill in self.__skills:
|
||||
self.__skillIdMap[skill.itemID] = skill
|
||||
self.dirtySkills = set()
|
||||
|
||||
def apiUpdateCharSheet(self, skills):
|
||||
del self.__skills[:]
|
||||
self.__skillIdMap.clear()
|
||||
for skillRow in skills:
|
||||
|
||||
self.addSkill(Skill(skillRow["typeID"], skillRow["level"]))
|
||||
|
||||
@property
|
||||
def ro(self):
|
||||
return self == self.getAll0() or self == self.getAll5()
|
||||
|
||||
@property
|
||||
def owner(self):
|
||||
return self.__owner
|
||||
@@ -120,6 +126,10 @@ class Character(object):
|
||||
def owner(self, owner):
|
||||
self.__owner = owner
|
||||
|
||||
@property
|
||||
def skills(self):
|
||||
return self.__skills
|
||||
|
||||
def addSkill(self, skill):
|
||||
self.__skills.append(skill)
|
||||
self.__skillIdMap[skill.itemID] = skill
|
||||
@@ -137,11 +147,7 @@ class Character(object):
|
||||
skill = self.__skillIdMap.get(item.ID)
|
||||
|
||||
if skill is None:
|
||||
if self.defaultLevel is None:
|
||||
skill = Skill(item, 0, False, False)
|
||||
else:
|
||||
skill = Skill(item, self.defaultLevel, False, True)
|
||||
|
||||
skill = Skill(item, self.defaultLevel, False, True)
|
||||
self.addSkill(skill)
|
||||
|
||||
return skill
|
||||
@@ -150,40 +156,57 @@ class Character(object):
|
||||
def implants(self):
|
||||
return self.__implants
|
||||
|
||||
def iterSkills(self):
|
||||
for item in self.getSkillList():
|
||||
yield self.getSkill(item)
|
||||
@property
|
||||
def isDirty(self):
|
||||
return len(self.dirtySkills) > 0
|
||||
|
||||
def saveLevels(self):
|
||||
if self == self.getAll5() or self == self.getAll0():
|
||||
raise ReadOnlyException("This character is read-only")
|
||||
|
||||
for skill in self.dirtySkills.copy():
|
||||
skill.saveLevel()
|
||||
|
||||
self.dirtySkills = set()
|
||||
eos.db.commit()
|
||||
|
||||
def revertLevels(self):
|
||||
for skill in self.dirtySkills.copy():
|
||||
skill.revert()
|
||||
|
||||
self.dirtySkills = set()
|
||||
|
||||
def filteredSkillIncrease(self, filter, *args, **kwargs):
|
||||
for element in self.iterSkills():
|
||||
for element in self.skills:
|
||||
if filter(element):
|
||||
element.increaseItemAttr(*args, **kwargs)
|
||||
|
||||
def filteredSkillMultiply(self, filter, *args, **kwargs):
|
||||
for element in self.iterSkills():
|
||||
for element in self.skills:
|
||||
if filter(element):
|
||||
element.multiplyItemAttr(*args, **kwargs)
|
||||
|
||||
def filteredSkillBoost(self, filter, *args, **kwargs):
|
||||
for element in self.iterSkills():
|
||||
for element in self.skills:
|
||||
if filter(element):
|
||||
element.boostItemAttr(*args, **kwargs)
|
||||
|
||||
def calculateModifiedAttributes(self, fit, runTime, forceProjected = False):
|
||||
if forceProjected: return
|
||||
for skill in self.iterSkills():
|
||||
for skill in self.skills:
|
||||
fit.register(skill)
|
||||
skill.calculateModifiedAttributes(fit, runTime)
|
||||
|
||||
def clear(self):
|
||||
for skill in self.iterSkills():
|
||||
for skill in self.skills:
|
||||
skill.clear()
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
copy = Character("%s copy" % self.name)
|
||||
copy = Character("%s copy" % self.name, initSkills=False)
|
||||
copy.apiKey = self.apiKey
|
||||
copy.apiID = self.apiID
|
||||
for skill in self.iterSkills():
|
||||
|
||||
for skill in self.skills:
|
||||
copy.addSkill(Skill(skill.itemID, skill.level, False, skill.learned))
|
||||
|
||||
return copy
|
||||
@@ -199,7 +222,7 @@ class Character(object):
|
||||
else: return val
|
||||
|
||||
class Skill(HandledItem):
|
||||
def __init__(self, item, level = 0, ro = False, learned = True):
|
||||
def __init__(self, item, level=0, ro=False, learned=True):
|
||||
self.__item = item if not isinstance(item, int) else None
|
||||
self.itemID = item.ID if not isinstance(item, int) else item
|
||||
self.__level = level if learned else None
|
||||
@@ -214,14 +237,28 @@ class Skill(HandledItem):
|
||||
def build(self, ro):
|
||||
self.__ro = ro
|
||||
self.__suppressed = False
|
||||
self.activeLevel = self.__level
|
||||
|
||||
def saveLevel(self):
|
||||
self.__level = self.activeLevel
|
||||
|
||||
if self in self.character.dirtySkills:
|
||||
self.character.dirtySkills.remove(self)
|
||||
|
||||
def revert(self):
|
||||
self.level = self.__level
|
||||
|
||||
@property
|
||||
def isDirty(self):
|
||||
return self.__level != self.activeLevel
|
||||
|
||||
@property
|
||||
def learned(self):
|
||||
return self.__level is not None
|
||||
return self.activeLevel is not None
|
||||
|
||||
@property
|
||||
def level(self):
|
||||
return self.__level or 0
|
||||
return self.activeLevel or 0
|
||||
|
||||
@level.setter
|
||||
def level(self, level):
|
||||
@@ -231,7 +268,12 @@ class Skill(HandledItem):
|
||||
if hasattr(self, "_Skill__ro") and self.__ro == True:
|
||||
raise ReadOnlyException()
|
||||
|
||||
self.__level = level
|
||||
self.activeLevel = level
|
||||
self.character.dirtySkills.add(self)
|
||||
|
||||
if self.activeLevel == self.__level and self in self.character.dirtySkills:
|
||||
self.character.dirtySkills.remove(self)
|
||||
|
||||
|
||||
@property
|
||||
def item(self):
|
||||
|
||||
@@ -401,7 +401,7 @@ class Fit(object):
|
||||
return self.__origin
|
||||
|
||||
def __calculateGangBoosts(self, runTime):
|
||||
logger.debug("Applying gang boosts in `%s` runtime for %s", runTime, repr(self))
|
||||
logger.debug("Applying gang boosts in `%s` runtime for %r", runTime, self)
|
||||
for name, info in self.gangBoosts.iteritems():
|
||||
# Unpack all data required to run effect properly
|
||||
effect, thing = info[1]
|
||||
@@ -425,12 +425,12 @@ class Fit(object):
|
||||
pass
|
||||
|
||||
def calculateModifiedAttributes(self, targetFit=None, withBoosters=False, dirtyStorage=None):
|
||||
timer = Timer('Fit: {}, {}'.format(self.ID, self.name), logger)
|
||||
logger.debug("Starting fit calculation on: %s, withBoosters: %s", repr(self), withBoosters)
|
||||
timer = Timer(u'Fit: {}, {}'.format(self.ID, self.name), logger)
|
||||
logger.debug("Starting fit calculation on: %r, withBoosters: %s", self, withBoosters)
|
||||
|
||||
shadow = False
|
||||
if targetFit:
|
||||
logger.debug("Applying projections to target: %s", repr(targetFit))
|
||||
logger.debug("Applying projections to target: %r", targetFit)
|
||||
projectionInfo = self.getProjectionInfo(targetFit.ID)
|
||||
logger.debug("ProjectionInfo: %s", projectionInfo)
|
||||
if self == targetFit:
|
||||
@@ -438,7 +438,7 @@ class Fit(object):
|
||||
shadow = True
|
||||
self = copy.deepcopy(self)
|
||||
self.fleet = copied.fleet
|
||||
logger.debug("Handling self projection - making shadow copy of fit. %s => %s", repr(copied), repr(self))
|
||||
logger.debug("Handling self projection - making shadow copy of fit. %r => %r", copied, self)
|
||||
# we delete the fit because when we copy a fit, flush() is
|
||||
# called to properly handle projection updates. However, we do
|
||||
# not want to save this fit to the database, so simply remove it
|
||||
@@ -447,7 +447,7 @@ class Fit(object):
|
||||
if self.fleet is not None and withBoosters is True:
|
||||
logger.debug("Fleet is set, gathering gang boosts")
|
||||
self.gangBoosts = self.fleet.recalculateLinear(withBoosters=withBoosters)
|
||||
timer.checkpoint("Done calculating gang boosts for %s"%repr(self))
|
||||
timer.checkpoint("Done calculating gang boosts for %r"%self)
|
||||
elif self.fleet is None:
|
||||
self.gangBoosts = None
|
||||
|
||||
@@ -473,7 +473,7 @@ class Fit(object):
|
||||
# projection have modifying stuff applied, such as gang boosts and other
|
||||
# local modules that may help
|
||||
if self.__calculated and not projected:
|
||||
logger.debug("Fit has already been calculated and is not projected, returning: %s", repr(self))
|
||||
logger.debug("Fit has already been calculated and is not projected, returning: %r", self)
|
||||
return
|
||||
|
||||
# Mark fit as calculated
|
||||
@@ -604,8 +604,8 @@ class Fit(object):
|
||||
Slot.RIG: "rigSlots",
|
||||
Slot.SUBSYSTEM: "maxSubSystems"}
|
||||
|
||||
if type == Slot.MODE:
|
||||
# Mode slot doesn't really exist, return default 0
|
||||
if type in (Slot.MODE, Slot.SYSTEM):
|
||||
# These slots don't really exist, return default 0
|
||||
return 0
|
||||
|
||||
slotsUsed = self.getSlotsUsed(type, countDummies)
|
||||
@@ -1000,11 +1000,11 @@ class Fit(object):
|
||||
return copy
|
||||
|
||||
def __repr__(self):
|
||||
return "Fit(ID={}, ship={}, name={}) at {}".format(
|
||||
return u"Fit(ID={}, ship={}, name={}) at {}".format(
|
||||
self.ID, self.ship.item.name, self.name, hex(id(self))
|
||||
)
|
||||
).encode('utf8')
|
||||
|
||||
def __str__(self):
|
||||
return "{} ({})".format(
|
||||
return u"{} ({})".format(
|
||||
self.name, self.ship.item.name
|
||||
)
|
||||
).encode('utf8')
|
||||
|
||||
@@ -247,7 +247,7 @@ class Store(object):
|
||||
dict.clear()
|
||||
|
||||
# Go through everything which can be used as gang booster
|
||||
for thing in chain(fitBooster.modules, fitBooster.implants, fitBooster.character.iterSkills(), (fitBooster.ship,)):
|
||||
for thing in chain(fitBooster.modules, fitBooster.implants, fitBooster.character.skills, (fitBooster.ship,)):
|
||||
if thing.item is None:
|
||||
continue
|
||||
for effect in thing.item.effects.itervalues():
|
||||
|
||||
@@ -35,12 +35,17 @@ class State(Enum):
|
||||
OVERHEATED = 2
|
||||
|
||||
class Slot(Enum):
|
||||
# These are self-explanatory
|
||||
LOW = 1
|
||||
MED = 2
|
||||
HIGH = 3
|
||||
RIG = 4
|
||||
SUBSYSTEM = 5
|
||||
MODE = 6 # not a real slot, need for pyfa display rack separation
|
||||
# not a real slot, need for pyfa display rack separation
|
||||
MODE = 6
|
||||
# system effects. They are projected "modules" and pyfa assumes all modules
|
||||
# have a slot. In this case, make one up.
|
||||
SYSTEM = 7
|
||||
|
||||
class Hardpoint(Enum):
|
||||
NONE = 0
|
||||
@@ -528,7 +533,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
if effectName in item.effects:
|
||||
return slot
|
||||
if item.group.name == "Effect Beacon":
|
||||
return Slot.RIG
|
||||
return Slot.SYSTEM
|
||||
|
||||
raise ValueError("Passed item does not fit in any known slot")
|
||||
|
||||
|
||||
@@ -70,6 +70,14 @@ class Ship(ItemAttrShortcut, HandledItem):
|
||||
if forceProjected: return
|
||||
for effect in self.item.effects.itervalues():
|
||||
if effect.runTime == runTime and effect.isType("passive"):
|
||||
# Ships have effects that utilize the level of a skill as an
|
||||
# additional operator to the modifier. These are defined in
|
||||
# the effect itself, and these skillbooks are registered when
|
||||
# they are provided. However, we must re-register the ship
|
||||
# before each effect, otherwise effects that do not have
|
||||
# skillbook modifiers will use the stale modifier value
|
||||
# GH issue #351
|
||||
fit.register(self)
|
||||
effect.handler(fit, self, ("ship",))
|
||||
|
||||
def validateModeItem(self, item):
|
||||
|
||||
@@ -21,8 +21,8 @@ class ChangeAffectingSkills(ContextMenu):
|
||||
|
||||
self.charID = fit.character.ID
|
||||
|
||||
if self.sChar.getCharName(self.charID) in ("All 0", "All 5"):
|
||||
return False
|
||||
#if self.sChar.getCharName(self.charID) in ("All 0", "All 5"):
|
||||
# return False
|
||||
|
||||
if srcContext == "fittingShip":
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
@@ -94,6 +94,7 @@ class ChangeAffectingSkills(ContextMenu):
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
self.sFit.changeChar(fitID, self.charID)
|
||||
|
||||
wx.PostEvent(self.mainFrame, GE.CharListUpdated())
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
|
||||
|
||||
ChangeAffectingSkills.register()
|
||||
|
||||
@@ -35,6 +35,9 @@ class CharacterEditor(wx.Frame):
|
||||
size=wx.Size(641, 600), style=wx.DEFAULT_FRAME_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.TAB_TRAVERSAL)
|
||||
|
||||
i = wx.IconFromBitmap(BitmapLoader.getBitmap("character_small", "gui"))
|
||||
|
||||
self.mainFrame = parent
|
||||
|
||||
self.SetIcon(i)
|
||||
|
||||
self.disableWin= wx.WindowDisabler(self)
|
||||
@@ -45,8 +48,6 @@ class CharacterEditor(wx.Frame):
|
||||
self.navSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
sChar = service.Character.getInstance()
|
||||
charList = sChar.getCharacterList()
|
||||
charList.sort(key=lambda t: t[1])
|
||||
|
||||
self.btnSave = wx.Button(self, wx.ID_SAVE)
|
||||
self.btnSave.Hide()
|
||||
@@ -56,15 +57,15 @@ class CharacterEditor(wx.Frame):
|
||||
self.characterRename.Hide()
|
||||
self.characterRename.Bind(wx.EVT_TEXT_ENTER, self.processRename)
|
||||
|
||||
self.skillTreeChoice = wx.Choice(self, wx.ID_ANY, style=0)
|
||||
self.charChoice = wx.Choice(self, wx.ID_ANY, style=0)
|
||||
self.navSizer.Add(self.charChoice, 1, wx.ALL | wx.EXPAND, 5)
|
||||
|
||||
charList = sChar.getCharacterList()
|
||||
|
||||
for id, name, active in charList:
|
||||
i = self.skillTreeChoice.Append(name, id)
|
||||
i = self.charChoice.Append(name, id)
|
||||
if active:
|
||||
self.skillTreeChoice.SetSelection(i)
|
||||
|
||||
self.navSizer.Add(self.skillTreeChoice, 1, wx.ALL | wx.EXPAND, 5)
|
||||
self.navSizer.Add(self.btnSave, 0, wx.ALIGN_CENTER)
|
||||
self.charChoice.SetSelection(i)
|
||||
|
||||
buttons = (("new", wx.ART_NEW),
|
||||
("rename", BitmapLoader.getBitmap("rename", "gui")),
|
||||
@@ -111,12 +112,26 @@ class CharacterEditor(wx.Frame):
|
||||
|
||||
bSizerButtons = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
self.btnSave = wx.Button(self, wx.ID_ANY, "Save")
|
||||
self.btnSaveAs = wx.Button(self, wx.ID_ANY, "Save As...")
|
||||
self.btnRevert = wx.Button(self, wx.ID_ANY, "Revert")
|
||||
self.btnOK = wx.Button(self, wx.ID_OK)
|
||||
|
||||
bSizerButtons.Add(self.btnSave, 0, wx.ALL, 5)
|
||||
bSizerButtons.Add(self.btnSaveAs, 0, wx.ALL, 5)
|
||||
bSizerButtons.Add(self.btnRevert, 0, wx.ALL, 5)
|
||||
bSizerButtons.AddStretchSpacer()
|
||||
bSizerButtons.Add(self.btnOK, 0, wx.ALL, 5)
|
||||
|
||||
|
||||
self.btnSave.Bind(wx.EVT_BUTTON, self.saveChar)
|
||||
self.btnSaveAs.Bind(wx.EVT_BUTTON, self.saveCharAs)
|
||||
self.btnRevert.Bind(wx.EVT_BUTTON, self.revertChar)
|
||||
self.btnOK.Bind(wx.EVT_BUTTON, self.editingFinished)
|
||||
|
||||
mainSizer.Add(bSizerButtons, 0, wx.ALIGN_RIGHT, 5)
|
||||
mainSizer.Add(bSizerButtons, 0, wx.EXPAND, 5)
|
||||
|
||||
self.btnRestrict()
|
||||
|
||||
self.SetSizer(mainSizer)
|
||||
self.Layout()
|
||||
@@ -129,7 +144,28 @@ class CharacterEditor(wx.Frame):
|
||||
|
||||
self.registerEvents()
|
||||
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
def btnRestrict(self):
|
||||
sChar = service.Character.getInstance()
|
||||
charID = self.getActiveCharacter()
|
||||
char = sChar.getCharacter(charID)
|
||||
|
||||
# enable/disable character saving stuff
|
||||
self.btnSave.Enable(not char.ro and char.isDirty)
|
||||
self.btnSaveAs.Enable(char.isDirty)
|
||||
self.btnRevert.Enable(char.isDirty)
|
||||
|
||||
def refreshCharacterList(self, event=None):
|
||||
sChar = service.Character.getInstance()
|
||||
charList = sChar.getCharacterList()
|
||||
active = self.getActiveCharacter()
|
||||
self.charChoice.Clear()
|
||||
|
||||
for id, name, _ in charList:
|
||||
i = self.charChoice.Append(name, id)
|
||||
if active == id:
|
||||
self.charChoice.SetSelection(i)
|
||||
|
||||
self.btnRestrict()
|
||||
|
||||
def editingFinished(self, event):
|
||||
del self.disableWin
|
||||
@@ -138,7 +174,29 @@ class CharacterEditor(wx.Frame):
|
||||
|
||||
def registerEvents(self):
|
||||
self.Bind(wx.EVT_CLOSE, self.closeEvent)
|
||||
self.skillTreeChoice.Bind(wx.EVT_CHOICE, self.charChanged)
|
||||
self.Bind(GE.CHAR_LIST_UPDATED, self.refreshCharacterList)
|
||||
self.charChoice.Bind(wx.EVT_CHOICE, self.charChanged)
|
||||
|
||||
def saveChar(self, event):
|
||||
sChr = service.Character.getInstance()
|
||||
charID = self.getActiveCharacter()
|
||||
sChr.saveCharacter(charID)
|
||||
self.sview.populateSkillTree()
|
||||
wx.PostEvent(self, GE.CharListUpdated())
|
||||
|
||||
def saveCharAs(self, event):
|
||||
charID = self.getActiveCharacter()
|
||||
dlg = SaveCharacterAs(self, charID)
|
||||
dlg.ShowModal()
|
||||
dlg.Destroy()
|
||||
self.sview.populateSkillTree()
|
||||
|
||||
def revertChar(self, event):
|
||||
sChr = service.Character.getInstance()
|
||||
charID = self.getActiveCharacter()
|
||||
sChr.revertCharacter(charID)
|
||||
self.sview.populateSkillTree()
|
||||
wx.PostEvent(self, GE.CharListUpdated())
|
||||
|
||||
def closeEvent(self, event):
|
||||
del self.disableWin
|
||||
@@ -148,7 +206,7 @@ class CharacterEditor(wx.Frame):
|
||||
def restrict(self):
|
||||
self.btnRename.Enable(False)
|
||||
self.btnDelete.Enable(False)
|
||||
self.aview.stDisabledTip.Show(True)
|
||||
self.aview.stDisabledTip.Show()
|
||||
self.aview.inputID.Enable(False)
|
||||
self.aview.inputKey.Enable(False)
|
||||
self.aview.charChoice.Enable(False)
|
||||
@@ -160,7 +218,7 @@ class CharacterEditor(wx.Frame):
|
||||
def unrestrict(self):
|
||||
self.btnRename.Enable(True)
|
||||
self.btnDelete.Enable(True)
|
||||
self.aview.stDisabledTip.Show(False)
|
||||
self.aview.stDisabledTip.Hide()
|
||||
self.aview.inputID.Enable(True)
|
||||
self.aview.inputKey.Enable(True)
|
||||
self.aview.btnFetchCharList.Enable(True)
|
||||
@@ -169,7 +227,6 @@ class CharacterEditor(wx.Frame):
|
||||
self.aview.Layout()
|
||||
|
||||
def charChanged(self, event):
|
||||
self.sview.skillTreeListCtrl.DeleteChildren(self.sview.root)
|
||||
self.sview.populateSkillTree()
|
||||
sChar = service.Character.getInstance()
|
||||
charID = self.getActiveCharacter()
|
||||
@@ -183,14 +240,14 @@ class CharacterEditor(wx.Frame):
|
||||
event.Skip()
|
||||
|
||||
def getActiveCharacter(self):
|
||||
selection = self.skillTreeChoice.GetCurrentSelection()
|
||||
return self.skillTreeChoice.GetClientData(selection) if selection is not None else None
|
||||
selection = self.charChoice.GetCurrentSelection()
|
||||
return self.charChoice.GetClientData(selection) if selection is not None else None
|
||||
|
||||
def new(self, event):
|
||||
sChar = service.Character.getInstance()
|
||||
charID = sChar.new()
|
||||
id = self.skillTreeChoice.Append(sChar.getCharName(charID), charID)
|
||||
self.skillTreeChoice.SetSelection(id)
|
||||
id = self.charChoice.Append(sChar.getCharName(charID), charID)
|
||||
self.charChoice.SetSelection(id)
|
||||
self.unrestrict()
|
||||
self.btnSave.SetLabel("Create")
|
||||
self.rename(None)
|
||||
@@ -199,9 +256,9 @@ class CharacterEditor(wx.Frame):
|
||||
def rename(self, event):
|
||||
if event is not None:
|
||||
self.btnSave.SetLabel("Rename")
|
||||
self.skillTreeChoice.Hide()
|
||||
self.charChoice.Hide()
|
||||
self.characterRename.Show()
|
||||
self.navSizer.Replace(self.skillTreeChoice, self.characterRename)
|
||||
self.navSizer.Replace(self.charChoice, self.characterRename)
|
||||
self.characterRename.SetFocus()
|
||||
for btn in (self.btnNew, self.btnCopy, self.btnRename, self.btnDelete):
|
||||
btn.Hide()
|
||||
@@ -224,24 +281,21 @@ class CharacterEditor(wx.Frame):
|
||||
charID = self.getActiveCharacter()
|
||||
sChar.rename(charID, newName)
|
||||
|
||||
self.skillTreeChoice.Show()
|
||||
self.charChoice.Show()
|
||||
self.characterRename.Hide()
|
||||
self.navSizer.Replace(self.characterRename, self.skillTreeChoice)
|
||||
self.navSizer.Replace(self.characterRename, self.charChoice)
|
||||
for btn in (self.btnNew, self.btnCopy, self.btnRename, self.btnDelete):
|
||||
btn.Show()
|
||||
|
||||
self.btnSave.Hide()
|
||||
self.navSizer.Layout()
|
||||
selection = self.skillTreeChoice.GetCurrentSelection()
|
||||
self.skillTreeChoice.Delete(selection)
|
||||
self.skillTreeChoice.Insert(newName, selection, charID)
|
||||
self.skillTreeChoice.SetSelection(selection)
|
||||
self.refreshCharacterList()
|
||||
|
||||
def copy(self, event):
|
||||
sChar = service.Character.getInstance()
|
||||
charID = sChar.copy(self.getActiveCharacter())
|
||||
id = self.skillTreeChoice.Append(sChar.getCharName(charID), charID)
|
||||
self.skillTreeChoice.SetSelection(id)
|
||||
id = self.charChoice.Append(sChar.getCharName(charID), charID)
|
||||
self.charChoice.SetSelection(id)
|
||||
self.unrestrict()
|
||||
self.btnSave.SetLabel("Copy")
|
||||
self.rename(None)
|
||||
@@ -250,9 +304,9 @@ class CharacterEditor(wx.Frame):
|
||||
def delete(self, event):
|
||||
sChar = service.Character.getInstance()
|
||||
sChar.delete(self.getActiveCharacter())
|
||||
sel = self.skillTreeChoice.GetSelection()
|
||||
self.skillTreeChoice.Delete(sel)
|
||||
self.skillTreeChoice.SetSelection(sel - 1)
|
||||
sel = self.charChoice.GetSelection()
|
||||
self.charChoice.Delete(sel)
|
||||
self.charChoice.SetSelection(sel - 1)
|
||||
newSelection = self.getActiveCharacter()
|
||||
if sChar.getCharName(newSelection) in ("All 0", "All 5"):
|
||||
self.restrict()
|
||||
@@ -314,6 +368,14 @@ class SkillTreeView (wx.Panel):
|
||||
self.levelIds[id] = level
|
||||
self.levelChangeMenu.Append(id, "Level %d" % level)
|
||||
|
||||
self.levelChangeMenu.AppendSeparator()
|
||||
self.revertID = wx.NewId()
|
||||
self.levelChangeMenu.Append(self.revertID, "Revert")
|
||||
|
||||
|
||||
self.saveID = wx.NewId()
|
||||
self.levelChangeMenu.Append(self.saveID, "Save")
|
||||
|
||||
self.levelChangeMenu.Bind(wx.EVT_MENU, self.changeLevel)
|
||||
self.SetSizer(pmainSizer)
|
||||
|
||||
@@ -321,15 +383,22 @@ class SkillTreeView (wx.Panel):
|
||||
|
||||
def populateSkillTree(self):
|
||||
sChar = service.Character.getInstance()
|
||||
charID = self.Parent.Parent.getActiveCharacter()
|
||||
dirtySkills = sChar.getDirtySkills(charID)
|
||||
dirtyGroups = set([skill.item.group.ID for skill in dirtySkills])
|
||||
|
||||
groups = sChar.getSkillGroups()
|
||||
imageId = self.skillBookImageId
|
||||
root = self.root
|
||||
tree = self.skillTreeListCtrl
|
||||
tree.DeleteChildren(root)
|
||||
|
||||
for id, name in groups:
|
||||
childId = tree.AppendItem(root, name, imageId)
|
||||
tree.SetPyData(childId, id)
|
||||
tree.AppendItem(childId, "dummy")
|
||||
if id in dirtyGroups:
|
||||
tree.SetItemTextColour(childId, wx.BLUE)
|
||||
|
||||
tree.SortChildren(root)
|
||||
|
||||
@@ -346,8 +415,10 @@ class SkillTreeView (wx.Panel):
|
||||
for id, name in sChar.getSkills(tree.GetPyData(root)):
|
||||
iconId = self.skillBookImageId
|
||||
childId = tree.AppendItem(root, name, iconId, data=wx.TreeItemData(id))
|
||||
level = sChar.getSkillLevel(char, id)
|
||||
level, dirty = sChar.getSkillLevel(char, id)
|
||||
tree.SetItemText(childId, "Level %d" % level if isinstance(level, int) else level, 1)
|
||||
if dirty:
|
||||
tree.SetItemTextColour(childId, wx.BLUE)
|
||||
|
||||
tree.SortChildren(root)
|
||||
|
||||
@@ -372,18 +443,34 @@ class SkillTreeView (wx.Panel):
|
||||
|
||||
def changeLevel(self, event):
|
||||
level = self.levelIds.get(event.Id)
|
||||
|
||||
sChar = service.Character.getInstance()
|
||||
charID = self.Parent.Parent.getActiveCharacter()
|
||||
selection = self.skillTreeListCtrl.GetSelection()
|
||||
skillID = self.skillTreeListCtrl.GetPyData(selection)
|
||||
|
||||
if level is not None:
|
||||
sChar = service.Character.getInstance()
|
||||
charID = self.Parent.Parent.getActiveCharacter()
|
||||
selection = self.skillTreeListCtrl.GetSelection()
|
||||
skillID = self.skillTreeListCtrl.GetPyData(selection)
|
||||
|
||||
self.skillTreeListCtrl.SetItemText(selection, "Level %d" % level if isinstance(level, int) else level, 1)
|
||||
sChar.changeLevel(charID, skillID, level)
|
||||
sChar.changeLevel(charID, skillID, level, persist=True)
|
||||
elif event.Id == self.revertID:
|
||||
sChar.revertLevel(charID, skillID)
|
||||
elif event.Id == self.saveID:
|
||||
sChar.saveSkill(charID, skillID)
|
||||
|
||||
self.skillTreeListCtrl.SetItemTextColour(selection, None)
|
||||
|
||||
dirtySkills = sChar.getDirtySkills(charID)
|
||||
dirtyGroups = set([skill.item.group.ID for skill in dirtySkills])
|
||||
|
||||
parentID = self.skillTreeListCtrl.GetItemParent(selection)
|
||||
groupID = self.skillTreeListCtrl.GetPyData(parentID)
|
||||
|
||||
if groupID not in dirtyGroups:
|
||||
self.skillTreeListCtrl.SetItemTextColour(parentID, None)
|
||||
|
||||
wx.PostEvent(self.Parent.Parent, GE.CharListUpdated())
|
||||
event.Skip()
|
||||
|
||||
|
||||
class ImplantsTreeView (wx.Panel):
|
||||
def addMarketViewImage(self, iconFile):
|
||||
if iconFile is None:
|
||||
@@ -544,6 +631,7 @@ class APIView (wx.Panel):
|
||||
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 )
|
||||
self.stDisabledTip.Hide()
|
||||
hintSizer.AddStretchSpacer()
|
||||
pmainSizer.Add(hintSizer, 0, wx.EXPAND, 5)
|
||||
|
||||
@@ -649,7 +737,7 @@ class APIView (wx.Panel):
|
||||
|
||||
sChar = service.Character.getInstance()
|
||||
try:
|
||||
list = sChar.charList(self.Parent.Parent.getActiveCharacter(), self.inputID.GetLineText(0), self.inputKey.GetLineText(0))
|
||||
list = sChar.apiCharList(self.Parent.Parent.getActiveCharacter(), self.inputID.GetLineText(0), self.inputKey.GetLineText(0))
|
||||
except service.network.AuthenticationError, e:
|
||||
self.stStatus.SetLabel("Authentication failure. Please check keyID and vCode combination.")
|
||||
except service.network.TimeoutError, e:
|
||||
@@ -677,3 +765,34 @@ class APIView (wx.Panel):
|
||||
self.stStatus.SetLabel("Successfully fetched %s\'s skills from EVE API." % charName)
|
||||
except Exception, e:
|
||||
self.stStatus.SetLabel("Unable to retrieve %s\'s skills. Error message:\n%s" % (charName, e))
|
||||
|
||||
class SaveCharacterAs(wx.Dialog):
|
||||
|
||||
def __init__(self, parent, charID):
|
||||
wx.Dialog.__init__(self, parent, title="Save Character As...", size=wx.Size(300, 60))
|
||||
self.charID = charID
|
||||
self.parent = parent
|
||||
sChar = service.Character.getInstance()
|
||||
name = sChar.getCharName(charID)
|
||||
bSizer1 = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
self.input = wx.TextCtrl(self, wx.ID_ANY, name, style=wx.TE_PROCESS_ENTER)
|
||||
|
||||
bSizer1.Add(self.input, 1, wx.ALL, 5)
|
||||
self.input.Bind(wx.EVT_TEXT_ENTER, self.change)
|
||||
self.button = wx.Button(self, wx.ID_OK, u"Save")
|
||||
bSizer1.Add(self.button, 0, wx.ALL, 5)
|
||||
|
||||
self.SetSizer(bSizer1)
|
||||
self.Layout()
|
||||
self.Centre(wx.BOTH)
|
||||
self.button.Bind(wx.EVT_BUTTON, self.change)
|
||||
|
||||
def change(self, event):
|
||||
sChar = service.Character.getInstance()
|
||||
sChar.saveCharacterAs(self.charID, self.input.GetLineText(0))
|
||||
wx.PostEvent(self.parent, GE.CharListUpdated())
|
||||
|
||||
event.Skip()
|
||||
self.Destroy()
|
||||
|
||||
|
||||
@@ -81,7 +81,6 @@ class CharacterSelection(wx.Panel):
|
||||
|
||||
choice.Clear()
|
||||
charList = sChar.getCharacterList()
|
||||
sChar.getCharacterList()
|
||||
picked = False
|
||||
|
||||
for id, name, active in charList:
|
||||
|
||||
@@ -43,7 +43,7 @@ from gui.marketBrowser import MarketBrowser, ItemSelected
|
||||
from gui.multiSwitch import MultiSwitch
|
||||
from gui.statsPane import StatsPane
|
||||
from gui.shipBrowser import ShipBrowser, FitSelected, ImportSelected, Stage3Selected
|
||||
from gui.characterEditor import CharacterEditor
|
||||
from gui.characterEditor import CharacterEditor, SaveCharacterAs
|
||||
from gui.characterSelection import CharacterSelection
|
||||
from gui.patternEditor import DmgPatternEditorDlg
|
||||
from gui.resistsEditor import ResistsEditorDlg
|
||||
@@ -416,6 +416,12 @@ class MainFrame(wx.Frame):
|
||||
self.Bind(wx.EVT_MENU, self.goWiki, id = menuBar.wikiId)
|
||||
# EVE Forums
|
||||
self.Bind(wx.EVT_MENU, self.goForums, id = menuBar.forumId)
|
||||
# Save current character
|
||||
self.Bind(wx.EVT_MENU, self.saveChar, id = menuBar.saveCharId)
|
||||
# Save current character as another character
|
||||
self.Bind(wx.EVT_MENU, self.saveCharAs, id = menuBar.saveCharAsId)
|
||||
# Save current character
|
||||
self.Bind(wx.EVT_MENU, self.revertChar, id = menuBar.revertCharId)
|
||||
|
||||
#Clipboard exports
|
||||
self.Bind(wx.EVT_MENU, self.exportToClipboard, id=wx.ID_COPY)
|
||||
@@ -480,6 +486,24 @@ class MainFrame(wx.Frame):
|
||||
atable = wx.AcceleratorTable(actb)
|
||||
self.SetAcceleratorTable(atable)
|
||||
|
||||
def saveChar(self, event):
|
||||
sChr = service.Character.getInstance()
|
||||
charID = self.charSelection.getActiveCharacter()
|
||||
sChr.saveCharacter(charID)
|
||||
wx.PostEvent(self, GE.CharListUpdated())
|
||||
|
||||
def saveCharAs(self, event):
|
||||
charID = self.charSelection.getActiveCharacter()
|
||||
dlg = SaveCharacterAs(self, charID)
|
||||
dlg.ShowModal()
|
||||
dlg.Destroy()
|
||||
|
||||
def revertChar(self, event):
|
||||
sChr = service.Character.getInstance()
|
||||
charID = self.charSelection.getActiveCharacter()
|
||||
sChr.revertCharacter(charID)
|
||||
wx.PostEvent(self, GE.CharListUpdated())
|
||||
|
||||
def AdditionsTabSelect(self, event):
|
||||
selTab = self.additionsSelect.index(event.GetId())
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ from gui.bitmapLoader import BitmapLoader
|
||||
import gui.mainFrame
|
||||
import gui.graphFrame
|
||||
import gui.globalEvents as GE
|
||||
import service
|
||||
|
||||
class MainMenuBar(wx.MenuBar):
|
||||
def __init__(self):
|
||||
@@ -36,6 +37,9 @@ class MainMenuBar(wx.MenuBar):
|
||||
self.exportHtmlId = wx.NewId()
|
||||
self.wikiId = wx.NewId()
|
||||
self.forumId = wx.NewId()
|
||||
self.saveCharId = wx.NewId()
|
||||
self.saveCharAsId = wx.NewId()
|
||||
self.revertCharId = wx.NewId()
|
||||
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
@@ -70,7 +74,10 @@ class MainMenuBar(wx.MenuBar):
|
||||
pasteText = "&From Clipboard" + ("\tCTRL+V" if 'wxMSW' in wx.PlatformInfo else "")
|
||||
editMenu.Append(wx.ID_COPY, copyText, "Export a fit to the clipboard")
|
||||
editMenu.Append(wx.ID_PASTE, pasteText, "Import a fit from the clipboard")
|
||||
|
||||
editMenu.AppendSeparator()
|
||||
editMenu.Append(self.saveCharId, "Save Character")
|
||||
editMenu.Append(self.saveCharAsId, "Save Character As...")
|
||||
editMenu.Append(self.revertCharId, "Revert Character")
|
||||
# Character menu
|
||||
windowMenu = wx.Menu()
|
||||
self.Append(windowMenu, "&Window")
|
||||
@@ -113,5 +120,14 @@ class MainMenuBar(wx.MenuBar):
|
||||
self.Enable(wx.ID_SAVEAS, enable)
|
||||
self.Enable(wx.ID_COPY, enable)
|
||||
self.Enable(self.exportSkillsNeededId, enable)
|
||||
event.Skip()
|
||||
|
||||
sChar = service.Character.getInstance()
|
||||
charID = self.mainFrame.charSelection.getActiveCharacter()
|
||||
char = sChar.getCharacter(charID)
|
||||
|
||||
# enable/disable character saving stuff
|
||||
self.Enable(self.saveCharId, not char.ro and char.isDirty)
|
||||
self.Enable(self.saveCharAsId, char.isDirty)
|
||||
self.Enable(self.revertCharId, char.isDirty)
|
||||
|
||||
event.Skip()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user