Merge branch 'singularity'

This commit is contained in:
blitzmann
2016-04-30 18:23:32 -04:00
350 changed files with 4512 additions and 1075 deletions

View File

@@ -20,8 +20,8 @@ saveInRoot = False
# Version data
version = "1.20.2"
tag = "git"
expansionName = "March 2016"
expansionVersion = "1.3"
expansionName = "Singularity"
expansionVersion = "1027729"
evemonMinVersion = "4081"
pyfaPath = None

View File

@@ -4,6 +4,9 @@ import time
import re
import os
import migrations
import logging
logger = logging.getLogger(__name__)
def getVersion(db):
cursor = db.execute('PRAGMA user_version')
@@ -30,10 +33,9 @@ def update(saveddata_engine):
shutil.copyfile(config.saveDB, toFile)
for version in xrange(dbVersion, appVersion):
func = migrations.updates[version+1]
if func:
print "applying update",version+1
logger.info("Applying database update: %d", version+1)
func(saveddata_engine)
# when all is said and done, set version to current

View File

@@ -0,0 +1,15 @@
"""
Migration 13
- Alters fits table to introduce implant location attribute
"""
import sqlalchemy
def upgrade(saveddata_engine):
# Update fits schema to include implant location attribute
try:
saveddata_engine.execute("SELECT implantLocation FROM fits LIMIT 1")
except sqlalchemy.exc.DatabaseError:
saveddata_engine.execute("ALTER TABLE fits ADD COLUMN implantLocation INTEGER;")
saveddata_engine.execute("UPDATE fits SET implantLocation = 0")

View File

@@ -13,6 +13,7 @@ __all__ = [
"miscData",
"targetResists",
"override",
"crest"
"crest",
"implantSet"
]

View File

@@ -36,9 +36,23 @@ characters_table = Table("characters", saveddata_meta,
Column("ownerID", ForeignKey("users.ID"), nullable = True))
mapper(Character, characters_table,
properties = {"_Character__owner" : relation(User, backref = "characters"),
"_Character__skills" : relation(Skill, backref="character", cascade = "all,delete-orphan"),
"_Character__implants" : relation(Implant, collection_class = HandledImplantBoosterList, cascade='all,delete-orphan', single_parent=True,
primaryjoin = charImplants_table.c.charID == characters_table.c.ID,
secondaryjoin = charImplants_table.c.implantID == Implant.ID,
secondary = charImplants_table),})
properties = {
"savedName": characters_table.c.name,
"_Character__owner": relation(
User,
backref = "characters"),
"_Character__skills": relation(
Skill,
backref="character",
cascade = "all,delete-orphan"),
"_Character__implants": relation(
Implant,
collection_class = HandledImplantBoosterList,
cascade='all,delete-orphan',
backref='character',
single_parent=True,
primaryjoin = charImplants_table.c.charID == characters_table.c.ID,
secondaryjoin = charImplants_table.c.implantID == Implant.ID,
secondary = charImplants_table),
}
)

View File

@@ -0,0 +1,51 @@
#===============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of eos.
#
# eos is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# eos is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with eos. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
from sqlalchemy import Table, Column, Integer, ForeignKey, Boolean
from sqlalchemy.orm import mapper
from eos.db import saveddata_meta
from eos.types import Fighter
from sqlalchemy.orm import *
from sqlalchemy.sql import and_
from eos.effectHandlerHelpers import *
from eos.types import FighterAbility
fighters_table = Table("fighters", saveddata_meta,
Column("groupID", Integer, primary_key=True),
Column("fitID", Integer, ForeignKey("fits.ID"), nullable = False, index = True),
Column("itemID", Integer, nullable = False),
Column("active", Boolean, nullable=True),
Column("amount", Integer, nullable = False),
Column("projected", Boolean, default = False))
fighter_abilities_table = Table("fightersAbilities", saveddata_meta,
Column("groupID", Integer, ForeignKey("fighters.groupID"), primary_key=True, index = True),
Column("effectID", Integer, nullable = False, primary_key=True),
Column("active", Boolean, default = False))
mapper(Fighter, fighters_table,
properties = {
"_Fighter__abilities": relation(
FighterAbility,
backref="fighter",
cascade='all, delete, delete-orphan'),
})
mapper(FighterAbility, fighter_abilities_table)

View File

@@ -26,9 +26,10 @@ from sqlalchemy.orm.collections import attribute_mapped_collection
from eos.db import saveddata_meta
from eos.db.saveddata.module import modules_table
from eos.db.saveddata.drone import drones_table
from eos.db.saveddata.fighter import fighters_table
from eos.db.saveddata.cargo import cargo_table
from eos.db.saveddata.implant import fitImplants_table
from eos.types import Fit, Module, User, Booster, Drone, Cargo, Implant, Character, DamagePattern, TargetResists
from eos.types import Fit, Module, User, Booster, Drone, Fighter, Cargo, Implant, Character, DamagePattern, TargetResists, ImplantLocation
from eos.effectHandlerHelpers import *
fits_table = Table("fits", saveddata_meta,
@@ -42,6 +43,7 @@ fits_table = Table("fits", saveddata_meta,
Column("booster", Boolean, nullable = False, index = True, default = 0),
Column("targetResistsID", ForeignKey("targetResists.ID"), nullable=True),
Column("modeID", Integer, nullable=True),
Column("implantLocation", Integer, nullable=False, default=ImplantLocation.FIT),
)
projectedFits_table = Table("projectedFits", saveddata_meta,
@@ -117,6 +119,12 @@ mapper(Fit, fits_table,
cascade='all, delete, delete-orphan',
single_parent=True,
primaryjoin=and_(drones_table.c.fitID == fits_table.c.ID, drones_table.c.projected == False)),
"_Fit__fighters": relation(
Fighter,
collection_class=HandledDroneCargoList,
cascade='all, delete, delete-orphan',
single_parent=True,
primaryjoin=and_(fighters_table.c.fitID == fits_table.c.ID, fighters_table.c.projected == False)),
"_Fit__cargo": relation(
Cargo,
collection_class=HandledDroneCargoList,

View File

@@ -36,4 +36,8 @@ charImplants_table = Table("charImplants", saveddata_meta,
Column("charID", ForeignKey("characters.ID"), index = True),
Column("implantID", ForeignKey("implants.ID"), primary_key = True))
implantsSetMap_table = Table("implantSetMap", saveddata_meta,
Column("setID", ForeignKey("implantSets.ID"), index = True),
Column("implantID", ForeignKey("implants.ID"), primary_key = True))
mapper(Implant, implants_table)

View File

@@ -0,0 +1,45 @@
#===============================================================================
# Copyright (C) 2016 Ryan Holmes
#
# This file is part of eos.
#
# eos is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# eos is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with eos. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
from sqlalchemy import Table, Column, Integer, ForeignKey, String
from sqlalchemy.orm import relation, mapper
from eos.db import saveddata_meta
from eos.db.saveddata.implant import implantsSetMap_table
from eos.types import Implant, ImplantSet
from eos.effectHandlerHelpers import HandledImplantBoosterList
implant_set_table = Table("implantSets", saveddata_meta,
Column("ID", Integer, primary_key = True),
Column("name", String, nullable = False),
)
mapper(ImplantSet, implant_set_table,
properties = {
"_ImplantSet__implants": relation(
Implant,
collection_class = HandledImplantBoosterList,
cascade='all, delete, delete-orphan',
backref='set',
single_parent=True,
primaryjoin = implantsSetMap_table.c.setID == implant_set_table.c.ID,
secondaryjoin = implantsSetMap_table.c.implantID == Implant.ID,
secondary = implantsSetMap_table),
}
)

View File

@@ -20,7 +20,7 @@
from eos.db.util import processEager, processWhere
from eos.db import saveddata_session, sd_lock
from eos.types import User, Character, Fit, Price, DamagePattern, Fleet, MiscData, Wing, Squad, TargetResists, Override, CrestChar
from eos.types import *
from eos.db.saveddata.fleet import squadmembers_table
from eos.db.saveddata.fit import projectedFits_table
from sqlalchemy.sql import and_
@@ -154,7 +154,7 @@ def getCharacter(lookfor, eager=None):
elif isinstance(lookfor, basestring):
eager = processEager(eager)
with sd_lock:
character = saveddata_session.query(Character).options(*eager).filter(Character.name == lookfor).first()
character = saveddata_session.query(Character).options(*eager).filter(Character.savedName == lookfor).first()
else:
raise TypeError("Need integer or string as argument")
return character
@@ -349,6 +349,12 @@ def getTargetResistsList(eager=None):
patterns = saveddata_session.query(TargetResists).options(*eager).all()
return patterns
def getImplantSetList(eager=None):
eager = processEager(eager)
with sd_lock:
sets = saveddata_session.query(ImplantSet).options(*eager).all()
return sets
@cachedQuery(DamagePattern, 1, "lookfor")
def getDamagePattern(lookfor, eager=None):
if isinstance(lookfor, int):
@@ -385,6 +391,24 @@ def getTargetResists(lookfor, eager=None):
raise TypeError("Need integer or string as argument")
return pattern
@cachedQuery(ImplantSet, 1, "lookfor")
def getImplantSet(lookfor, eager=None):
if isinstance(lookfor, int):
if eager is None:
with sd_lock:
pattern = saveddata_session.query(ImplantSet).get(lookfor)
else:
eager = processEager(eager)
with sd_lock:
pattern = saveddata_session.query(ImplantSet).options(*eager).filter(TargetResists.ID == lookfor).first()
elif isinstance(lookfor, basestring):
eager = processEager(eager)
with sd_lock:
pattern = saveddata_session.query(ImplantSet).options(*eager).filter(TargetResists.name == lookfor).first()
else:
raise TypeError("Improper argument")
return pattern
def searchFits(nameLike, where=None, eager=None):
if not isinstance(nameLike, basestring):
raise TypeError("Need string as argument")

View File

@@ -2,7 +2,7 @@
#
# Used by:
# Modules from group: Missile Launcher Bomb (2 of 2)
# Modules from group: Shield Extender (25 of 25)
# Modules from group: Shield Extender (33 of 33)
type = "passive"
def handler(fit, module, context):
fit.ship.increaseItemAttr("signatureRadius", module.getModifiedItemAttr("signatureRadiusAdd"))

View File

@@ -4,5 +4,5 @@
# Skill: Advanced Drone Interfacing
type = "passive"
def handler(fit, skill, context):
fit.modules.filteredItemIncrease(lambda mod: mod.item.group.name == "Drone Control Unit",
fit.modules.filteredItemIncrease(lambda mod: mod.item.group.name == "Fighter Support Unit",
"maxGroupActive", skill.level)

View File

@@ -1,12 +1,12 @@
# ammoFallofMultiplier
#
# Used by:
# Charges from group: Advanced Artillery Ammo (6 of 6)
# Charges from group: Advanced Autocannon Ammo (6 of 6)
# Charges from group: Advanced Beam Laser Crystal (6 of 6)
# Charges from group: Advanced Blaster Charge (6 of 6)
# Charges from group: Advanced Pulse Laser Crystal (6 of 6)
# Charges from group: Advanced Railgun Charge (6 of 6)
# Charges from group: Advanced Artillery Ammo (8 of 8)
# Charges from group: Advanced Autocannon Ammo (8 of 8)
# Charges from group: Advanced Beam Laser Crystal (8 of 8)
# Charges from group: Advanced Blaster Charge (8 of 8)
# Charges from group: Advanced Pulse Laser Crystal (8 of 8)
# Charges from group: Advanced Railgun Charge (8 of 8)
type = "passive"
def handler(fit, module, context):
module.multiplyItemAttr("falloff", module.getModifiedChargeAttr("fallofMultiplier") or 1)

View File

@@ -1,7 +1,7 @@
# ammoInfluenceCapNeed
#
# Used by:
# Items from category: Charge (458 of 851)
# Items from category: Charge (465 of 884)
type = "passive"
def handler(fit, module, context):
# Dirty hack to work around cap charges setting cap booster

View File

@@ -1,7 +1,7 @@
# ammoInfluenceRange
#
# Used by:
# Items from category: Charge (559 of 851)
# Items from category: Charge (571 of 884)
type = "passive"
def handler(fit, module, context):
module.multiplyItemAttr("maxRange", module.getModifiedChargeAttr("weaponRangeMultiplier"))

View File

@@ -1,12 +1,12 @@
# ammoTrackingMultiplier
#
# Used by:
# Charges from group: Advanced Artillery Ammo (6 of 6)
# Charges from group: Advanced Autocannon Ammo (6 of 6)
# Charges from group: Advanced Beam Laser Crystal (6 of 6)
# Charges from group: Advanced Blaster Charge (6 of 6)
# Charges from group: Advanced Pulse Laser Crystal (6 of 6)
# Charges from group: Advanced Railgun Charge (6 of 6)
# Charges from group: Advanced Artillery Ammo (8 of 8)
# Charges from group: Advanced Autocannon Ammo (8 of 8)
# Charges from group: Advanced Beam Laser Crystal (8 of 8)
# Charges from group: Advanced Blaster Charge (8 of 8)
# Charges from group: Advanced Pulse Laser Crystal (8 of 8)
# Charges from group: Advanced Railgun Charge (8 of 8)
# Charges from group: Projectile Ammo (129 of 129)
type = "passive"
def handler(fit, module, context):

View File

@@ -5,7 +5,7 @@
runTime = "early"
type = "passive"
def handler(fit, implant, context):
fit.implants.filteredItemMultiply(
fit.appliedImplants.filteredItemMultiply(
lambda implant: "signatureRadiusBonus" in implant.itemModifiedAttributes and "implantSetAngel" in implant.itemModifiedAttributes,
"signatureRadiusBonus",
implant.getModifiedItemAttr("implantSetAngel"))

View File

@@ -1,7 +1,7 @@
# armorHPBonusAdd
#
# Used by:
# Modules from group: Armor Reinforcer (41 of 41)
# Modules from group: Armor Reinforcer (48 of 48)
type = "passive"
def handler(fit, module, context):
fit.ship.increaseItemAttr("armorHP", module.getModifiedItemAttr("armorHPBonusAdd"))

View File

@@ -1,7 +1,7 @@
# armorReinforcerMassAdd
#
# Used by:
# Modules from group: Armor Reinforcer (41 of 41)
# Modules from group: Armor Reinforcer (48 of 48)
type = "passive"
def handler(fit, module, context):
fit.ship.increaseItemAttr("mass", module.getModifiedItemAttr("massAddition"))

View File

@@ -1,7 +1,7 @@
# armorRepair
#
# Used by:
# Modules from group: Armor Repair Unit (100 of 100)
# Modules from group: Armor Repair Unit (105 of 105)
runTime = "late"
type = "active"
def handler(fit, module, context):

View File

@@ -5,5 +5,5 @@
runTime = "early"
type = "passive"
def handler(fit, implant, context):
fit.implants.filteredItemMultiply(lambda target: target.item.requiresSkill("Cybernetics"),
fit.appliedImplants.filteredItemMultiply(lambda target: target.item.requiresSkill("Cybernetics"),
"scanGravimetricStrengthPercent", implant.getModifiedItemAttr("implantSetCaldariNavy"))

View File

@@ -5,5 +5,5 @@
runTime = "early"
type = "passive"
def handler(fit, implant, context):
fit.implants.filteredItemMultiply(lambda target: target.item.requiresSkill("Cybernetics"),
fit.appliedImplants.filteredItemMultiply(lambda target: target.item.requiresSkill("Cybernetics"),
"scanGravimetricStrengthModifier", implant.getModifiedItemAttr("implantSetLGCaldariNavy"))

View File

@@ -1,7 +1,7 @@
# capacitorCapacityBonus
#
# Used by:
# Modules from group: Capacitor Battery (22 of 22)
# Modules from group: Capacitor Battery (27 of 27)
type = "passive"
def handler(fit, ship, context):
fit.ship.increaseItemAttr("capacitorCapacity", ship.getModifiedItemAttr("capacitorBonus"))

View File

@@ -4,7 +4,7 @@
# Modules from group: Capacitor Flux Coil (6 of 6)
# Modules from group: Capacitor Power Relay (20 of 20)
# Modules from group: Power Diagnostic System (23 of 23)
# Modules from group: Propulsion Module (114 of 114)
# Modules from group: Propulsion Module (127 of 127)
# Modules from group: Reactor Control Unit (22 of 22)
type = "passive"
def handler(fit, module, context):

View File

@@ -8,4 +8,4 @@ def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Remote Armor Repair Systems"),
"maxRange", ship.getModifiedItemAttr("carrierAmarrBonus3"), skill="Amarr Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Capacitor Emission Systems"),
"powerTransferRange", ship.getModifiedItemAttr("carrierAmarrBonus3"), skill="Amarr Carrier")
"maxRange", ship.getModifiedItemAttr("carrierAmarrBonus3"), skill="Amarr Carrier")

View File

@@ -9,4 +9,4 @@ def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Shield Emission Systems"),
"maxRange", ship.getModifiedItemAttr("carrierCaldariBonus3"), skill="Caldari Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Capacitor Emission Systems"),
"powerTransferRange", ship.getModifiedItemAttr("carrierCaldariBonus3"), skill="Caldari Carrier")
"maxRange", ship.getModifiedItemAttr("carrierCaldariBonus3"), skill="Caldari Carrier")

View File

@@ -1,7 +1,8 @@
# damageControl
#
# Used by:
# Modules from group: Damage Control (17 of 17)
# Variations of module: Damage Control I (16 of 16)
# Module: Civilian Damage Control
type = "passive"
def handler(fit, module, context):
for layer, attrPrefix in (('shield', 'shield'), ('armor', 'armor'), ('hull', '')):

View File

@@ -1,7 +1,7 @@
# drawbackCPUOutput
#
# Used by:
# Modules from group: Rig Drones (64 of 64)
# Modules from group: Rig Drones (58 of 64)
type = "passive"
def handler(fit, module, context):
fit.ship.boostItemAttr("cpuOutput", module.getModifiedItemAttr("drawback"))

View File

@@ -1,7 +1,7 @@
# droneDurabilityArmorHPBonus
#
# Used by:
# Modules named like: Drone Durability Enhancer (8 of 8)
# Modules named like: Drone Durability Enhancer (6 of 8)
type = "passive"
def handler(fit, module, context):
fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Drones"),

View File

@@ -1,8 +1,7 @@
# droneDurabilityHPBonus
#
# Used by:
# Modules named like: Drone Durability Enhancer (8 of 8)
# Skill: Drone Durability
# Modules named like: Drone Durability Enhancer (6 of 8)
type = "passive"
def handler(fit, container, context):
level = container.level if "skill" in context else 1

View File

@@ -1,7 +1,7 @@
# droneDurabilityShieldCapBonus
#
# Used by:
# Modules named like: Drone Durability Enhancer (8 of 8)
# Modules named like: Drone Durability Enhancer (6 of 8)
type = "passive"
def handler(fit, module, context):
fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Drones"),

View File

@@ -1,8 +1,7 @@
# droneMaxRangeBonus
#
# Used by:
# Modules named like: Drone Scope Chip (8 of 8)
# Skill: Drone Sharpshooting
# Modules named like: Drone Scope Chip (6 of 8)
type = "passive"
def handler(fit, container, context):
level = container.level if "skill" in context else 1

View File

@@ -1,8 +1,7 @@
# droneMaxVelocityBonus
#
# Used by:
# Modules named like: Drone Speed Augmentor (8 of 8)
# Skill: Drone Navigation
# Modules named like: Drone Speed Augmentor (6 of 8)
type = "passive"
def handler(fit, container, context):
level = container.level if "skill" in context else 1

View File

@@ -1,7 +1,7 @@
# eliteBonusCommandDestroyerMJFGspool2
#
# Used by:
# Ships from group: Command Destroyers (4 of 4)
# Ships from group: Command Destroyer (4 of 4)
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Micro Jump Drive Operation"), "duration", src.getModifiedItemAttr("eliteBonusCommandDestroyer2"), skill="Command Destroyers")

View File

@@ -1,7 +1,8 @@
# energyNeutralizerFalloff
#
# Used by:
# Modules from group: Energy Neutralizer (45 of 45)
# Drones from group: Energy Neutralizer Drone (3 of 3)
# Modules from group: Energy Neutralizer (51 of 51)
from eos.types import State
type = "active", "projected"
def handler(fit, container, context):

View File

@@ -1,7 +1,7 @@
# energyNosferatuFalloff
#
# Used by:
# Modules from group: Energy Nosferatu (45 of 45)
# Modules from group: Energy Nosferatu (51 of 51)
type = "active", "projected"
runTime = "late"
def handler(fit, module, context):

View File

@@ -6,4 +6,4 @@
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Remote Capacitor Transmitter",
"powerTransferRange", ship.getModifiedItemAttr("maxRangeBonus2"))
"maxRange", ship.getModifiedItemAttr("maxRangeBonus2"))

View File

@@ -1,7 +1,7 @@
# energyWeaponDamageMultiply
#
# Used by:
# Modules from group: Heat Sink (18 of 18)
# Modules from group: Heat Sink (17 of 17)
# Modules named like: QA Multiship Module Players (4 of 4)
# Module: QA Damage Module
type = "passive"

View File

@@ -1,7 +1,7 @@
# energyWeaponSpeedMultiply
#
# Used by:
# Modules from group: Heat Sink (18 of 18)
# Modules from group: Heat Sink (17 of 17)
type = "passive"
def handler(fit, module, context):
fit.modules.filteredItemMultiply(lambda mod: mod.item.group.name == "Energy Weapon",

View File

@@ -1,11 +1,8 @@
# entosisDurationMultiply
#
# Used by:
# Ships from group: Carrier (4 of 4)
# Ships from group: Dreadnought (4 of 4)
# Ships from group: Supercarrier (5 of 5)
# Ships from group: Titan (4 of 4)
# Ship: Rorqual
# Items from market group: Ships > Capital Ships (22 of 32)
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemMultiply(lambda mod: mod.item.requiresSkill("Infomorph Psychology"),

View File

@@ -4,5 +4,5 @@
# Implants named like: grade Centurion (10 of 12)
type = "passive"
def handler(fit, implant, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Remote ECM Burst",
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Burst Projectors",
"maxRange", implant.getModifiedItemAttr("rangeSkillBonus"))

View File

@@ -5,5 +5,5 @@
type = "passive"
runTime = "early"
def handler(fit, implant, context):
fit.implants.filteredItemMultiply(lambda target: target.item.requiresSkill("Cybernetics"),
fit.appliedImplants.filteredItemMultiply(lambda target: target.item.requiresSkill("Cybernetics"),
"scanMagnetometricStrengthPercent", implant.getModifiedItemAttr("implantSetFederationNavy"))

View File

@@ -5,5 +5,5 @@
type = "passive"
runTime = "early"
def handler(fit, implant, context):
fit.implants.filteredItemMultiply(lambda target: target.item.requiresSkill("Cybernetics"),
fit.appliedImplants.filteredItemMultiply(lambda target: target.item.requiresSkill("Cybernetics"),
"scanMagnetometricStrengthModifier", implant.getModifiedItemAttr("implantSetLGFederationNavy"))

View File

@@ -0,0 +1,14 @@
"""
Since fighter abilities do not have any sort of item entity in the EVE database, we must derive the abilities from the
effects, and thus this effect file contains some custom information useful only to fighters.
"""
# User-friendly name for the ability
displayName = "Turret Attack"
# Attribute prefix that this ability targets
prefix = "fighterAbilityAttackMissile"
type = "active"
def handler(fit, src, context):
pass

View File

@@ -0,0 +1,18 @@
"""
Since fighter abilities do not have any sort of item entity in the EVE database, we must derive the abilities from the
effects, and thus this effect file contains some custom information useful only to fighters.
"""
from eos.types import State
# User-friendly name for the ability
displayName = "ECM"
prefix = "fighterAbilityECM"
type = "projected", "active"
def handler(fit, module, context):
if "projected" not in context: return
# jam formula: 1 - (1- (jammer str/ship str))^(# of jam mods with same str))
strModifier = 1 - module.getModifiedItemAttr("{}Srength{}".format(prefix, fit.scanType))/fit.scanStrength
fit.ecmProjectedStr *= strModifier

View File

@@ -0,0 +1,19 @@
"""
Since fighter abilities do not have any sort of item entity in the EVE database, we must derive the abilities from the
effects, and thus this effect file contains some custom information useful only to fighters.
"""
from eos.types import State
# User-friendly name for the ability
displayName = "Energy Neutralizer"
prefix = "fighterAbilityEnergyNeutralizer"
type = "active", "projected"
def handler(fit, container, context):
if "projected" in context and ((hasattr(container, "state") and container.state >= State.ACTIVE) or hasattr(container, "amountActive")):
multiplier = container.amountActive if hasattr(container, "amountActive") else 1
amount = container.getModifiedItemAttr("{}Amount".format(prefix))
time = container.getModifiedItemAttr("{}Duration".format(prefix))
fit.addDrain(time, amount * multiplier, 0)

View File

@@ -0,0 +1,14 @@
"""
Since fighter abilities do not have any sort of item entity in the EVE database, we must derive the abilities from the
effects, and thus this effect file contains some custom information useful only to fighters.
"""
# User-friendly name for the ability
displayName = "Bomb"
# Attribute prefix that this ability targets
prefix = "fighterAbilityLaunchBomb"
type = "active"
def handler(fit, src, context):
pass

View File

@@ -0,0 +1,15 @@
"""
Since fighter abilities do not have any sort of item entity in the EVE database, we must derive the abilities from the
effects, and thus this effect file contains some custom information useful only to fighters.
"""
# User-friendly name for the ability
displayName = "Microwarpdrive"
# Is ability applied to the fighter squad as a whole, or per fighter?
grouped = True
type = "active"
runTime = "late"
def handler(fit, module, context):
module.boostItemAttr("maxVelocity", module.getModifiedItemAttr("fighterAbilityMicroWarpDriveSpeedBonus"))
module.boostItemAttr("signatureRadius", module.getModifiedItemAttr("fighterAbilityMicroWarpDriveSignatureRadiusBonus"), stackingPenalties = True)

View File

@@ -0,0 +1,14 @@
"""
Since fighter abilities do not have any sort of item entity in the EVE database, we must derive the abilities from the
effects, and thus this effect file contains some custom information useful only to fighters.
"""
# User-friendly name for the ability
displayName = "Missile Attack"
# Attribute prefix that this ability targets
prefix = "fighterAbilityMissiles"
type = "active"
def handler(fit, src, context):
pass

View File

@@ -0,0 +1,17 @@
"""
Since fighter abilities do not have any sort of item entity in the EVE database, we must derive the abilities from the
effects, and thus this effect file contains some custom information useful only to fighters.
"""
from eos.types import State
# User-friendly name for the ability
displayName = "Stasis Webifier"
prefix = "fighterAbilityStasisWebifier"
type = "active", "projected"
def handler(fit, src, context):
if "projected" not in context: return
multiplier = src.amountActive if hasattr(src, "amountActive") else 1
fit.ship.boostItemAttr("maxVelocity", src.getModifiedItemAttr("{}SpeedPenalty") * multiplier)

View File

@@ -0,0 +1,16 @@
"""
Since fighter abilities do not have any sort of item entity in the EVE database, we must derive the abilities from the
effects, and thus this effect file contains some custom information useful only to fighters.
"""
from eos.types import State
# User-friendly name for the ability
displayName = "Warp Disruption"
prefix = "fighterAbilityWarpDisruption"
type = "active", "projected"
def handler(fit, src, context):
if "projected" not in context: return
fit.ship.increaseItemAttr("warpScrambleStatus", src.getModifiedItemAttr("{}PointStrength".format(prefix)))

View File

@@ -1,7 +1,7 @@
# fueledArmorRepair
#
# Used by:
# Modules from group: Fueled Armor Repairer (3 of 3)
# Modules from group: Ancillary Armor Repairer (4 of 4)
runTime = "late"
type = "active"
def handler(fit, module, context):

View File

@@ -1,7 +1,7 @@
# fueledShieldBoosting
#
# Used by:
# Modules from group: Fueled Shield Booster (4 of 4)
# Modules from group: Ancillary Shield Booster (5 of 5)
runTime = "late"
type = "active"
def handler(fit, module, context):

View File

@@ -5,5 +5,5 @@
type = "passive"
runTime = "early"
def handler(fit, implant, context):
fit.implants.filteredItemMultiply(lambda target: target.item.requiresSkill("Cybernetics"),
fit.appliedImplants.filteredItemMultiply(lambda target: target.item.requiresSkill("Cybernetics"),
"scanRadarStrengthPercent", implant.getModifiedItemAttr("implantSetImperialNavy"))

View File

@@ -5,5 +5,5 @@
type = "passive"
runTime = "early"
def handler(fit, implant, context):
fit.implants.filteredItemMultiply(lambda target: target.item.requiresSkill("Cybernetics"),
fit.appliedImplants.filteredItemMultiply(lambda target: target.item.requiresSkill("Cybernetics"),
"scanRadarStrengthModifier", implant.getModifiedItemAttr("implantSetLGImperialNavy"))

View File

@@ -5,5 +5,5 @@
runTime = "early"
type = "passive"
def handler(fit, implant, context):
fit.implants.filteredItemMultiply(lambda mod: mod.item.group.name == "Cyberimplant",
fit.appliedImplants.filteredItemMultiply(lambda mod: mod.item.group.name == "Cyberimplant",
"WarpSBonus", implant.getModifiedItemAttr("implantSetWarpSpeed"))

View File

@@ -7,4 +7,4 @@ runTime = "early"
def handler(fit, module, context):
fit.extraAttributes["siege"] = True
fit.ship.boostItemAttr("maxVelocity", module.getModifiedItemAttr("speedFactor"))
fit.ship.multiplyItemAttr("mass", module.getModifiedItemAttr("massMultiplier"))
fit.ship.multiplyItemAttr("mass", module.getModifiedItemAttr("siegeMassMultiplier"))

View File

@@ -2,7 +2,6 @@
#
# Used by:
# Modules named like: Drone Mining Augmentor (8 of 8)
# Skill: Drone Interfacing
# Skill: Mining Drone Operation
type = "passive"
def handler(fit, container, context):

View File

@@ -1,8 +1,8 @@
# missileSkillRapidLauncherRoF
#
# Used by:
# Implants named like: Cerebral Accelerator (3 of 3)
# Implants named like: Zainou 'Deadeye' Rapid Launch RL (6 of 6)
# Implant: Standard Cerebral Accelerator
# Implant: Whelan Machorin's Ballistic Smartlink
# Skill: Missile Launcher Operation
# Skill: Rapid Launch

View File

@@ -2,6 +2,7 @@
#
# Used by:
# Modules from group: Armor Hardener (156 of 156)
# Modules from group: Flex Armor Hardener (4 of 4)
type = "active"
def handler(fit, module, context):
for damageType in ("kinetic", "thermal", "explosive", "em"):

View File

@@ -1,6 +1,7 @@
# modifyActiveShieldResonancePostPercent
#
# Used by:
# Modules from group: Flex Shield Hardener (5 of 5)
# Modules from group: Shield Hardener (97 of 97)
type = "active"
def handler(fit, module, context):

View File

@@ -1,7 +1,7 @@
# modifyEnergyWarfareResistance
#
# Used by:
# Modules from group: Capacitor Battery (22 of 22)
# Modules from group: Capacitor Battery (27 of 27)
type = "passive"
def handler(fit, module, context):
fit.ship.boostItemAttr("energyWarfareResistance",

View File

@@ -0,0 +1,12 @@
# moduleBonusArmoredWarfareLinkDamageControl
#
# Used by:
# Variations of module: Armored Warfare Link - Damage Control I (2 of 2)
type = "gang", "active"
gangBoost = "armorRepairCapacitorNeed"
runTime = "late"
def handler(fit, module, context):
if "gang" not in context: return
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Repair Systems") or mod.item.requiresSkill("Remote Armor Repair Systems"),
"capacitorNeed", module.getModifiedItemAttr("commandBonus"))

View File

@@ -0,0 +1,14 @@
# moduleBonusArmoredWarfareLinkPassiveDefense
#
# Used by:
# Variations of module: Armored Warfare Link - Passive Defense I (2 of 2)
type = "gang", "active"
gangBoost = "armorResistance"
runTime = "late"
def handler(fit, module, context):
if "gang" not in context: return
for damageType in ("Em", "Thermal", "Explosive", "Kinetic"):
fit.ship.boostItemAttr("armor%sDamageResonance" % damageType,
module.getModifiedItemAttr("commandBonus"),
stackingPenalties = True)

View File

@@ -0,0 +1,12 @@
# moduleBonusArmoredWarfareLinkRapidRepair
#
# Used by:
# Variations of module: Armored Warfare Link - Rapid Repair I (2 of 2)
type = "gang", "active"
gangBoost = "armorRepairDuration"
runTime = "late"
def handler(fit, module, context):
if "gang" not in context: return
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Repair Systems") or mod.item.requiresSkill("Remote Armor Repair Systems"),
"duration", module.getModifiedItemAttr("commandBonus"))

View File

@@ -0,0 +1,69 @@
# moduleBonusBastionModule
#
# Used by:
# Module: Bastion Module I
type = "active"
runTime = "early"
def handler(fit, src, context):
# Resistances
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)
penalize = False if layer == 'hull' else True
fit.ship.multiplyItemAttr(bonus, src.getModifiedItemAttr(booster),
stackingPenalties=penalize, penaltyGroup="preMul")
# Turrets
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Large Energy Turret") or \
mod.item.requiresSkill("Large Hybrid Turret") or \
mod.item.requiresSkill("Large Projectile Turret"),
"maxRange", src.getModifiedItemAttr("maxRangeBonus"),
stackingPenalties=True)
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Large Energy Turret") or \
mod.item.requiresSkill("Large Hybrid Turret") or \
mod.item.requiresSkill("Large Projectile Turret"),
"falloff", src.getModifiedItemAttr("falloffBonus"),
stackingPenalties=True)
# Missiles
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Torpedoes") or \
mod.charge.requiresSkill("Cruise Missiles") or \
mod.charge.requiresSkill("Heavy Missiles"),
"maxVelocity", src.getModifiedItemAttr("missileVelocityBonus"))
# Tanking
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Repair Systems"),
"armorDamageAmount", src.getModifiedItemAttr("armorDamageAmountBonus"),
stackingPenalties=True)
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Operation"),
"shieldBonus", src.getModifiedItemAttr("shieldBoostMultiplier"),
stackingPenalties=True)
# Speed penalty
fit.ship.boostItemAttr("maxVelocity", src.getModifiedItemAttr("speedFactor"))
# @todo: test these for April 2016 release
# Max locked targets
fit.ship.forceItemAttr("maxLockedTargets", src.getModifiedItemAttr("maxLockedTargets"))
# Block Hostile ewar
fit.ship.forceItemAttr("disallowOffensiveModifiers", src.getModifiedItemAttr("disallowOffensiveModifiers"))
# new with April 2016 release
for scanType in ('Magnetometric', 'Ladar', 'Gravimetric', 'Radar'):
fit.ship.boostItemAttr("scan{}Strength".format(scanType),
src.getModifiedItemAttr("scan{}StrengthPercent".format(scanType)),
stackingPenalties=True)
fit.ship.boostItemAttr("remoteRepairImpedance", src.getModifiedItemAttr("remoteRepairImpedanceBonus"))
fit.ship.boostItemAttr("remoteAssistanceImpedance", src.getModifiedItemAttr("remoteAssistanceImpedanceBonus"))
fit.ship.boostItemAttr("sensorDampenerResistance", src.getModifiedItemAttr("sensorDampenerResistanceBonus"))
fit.modules.filteredItemIncrease(lambda mod: mod.item.requiresSkill("Micro Jump Drive Operation"), "activationBlocked", src.getModifiedItemAttr("activationBlockedStrenght"))
fit.ship.boostItemAttr("targetPainterResistance", src.getModifiedItemAttr("targetPainterResistanceBonus"))
fit.ship.boostItemAttr("weaponDisruptionResistance", src.getModifiedItemAttr("weaponDisruptionResistanceBonus"))
fit.ship.increaseItemAttr("warpScrambleStatus", src.getModifiedItemAttr("siegeModeWarpStatus"))
fit.ship.forceItemAttr("disallowDocking", src.getModifiedItemAttr("disallowDocking"))
fit.ship.forceItemAttr("disallowTethering", src.getModifiedItemAttr("disallowTethering"))

View File

@@ -0,0 +1,11 @@
# moduleBonusCapitalDroneDurabilityEnhancer
#
# Used by:
# Variations of module: Capital Drone Durability Enhancer I (2 of 2)
type = "passive"
def handler(fit, src, context):
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "armorHP", src.getModifiedItemAttr("hullHpBonus"))
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "hp", src.getModifiedItemAttr("hullHpBonus"))
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "shieldCapacity", src.getModifiedItemAttr("hullHpBonus"))
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "shieldCapacity", src.getModifiedItemAttr("hullHpBonus"))
fit.ship.boostItemAttr("cpuOutput", src.getModifiedItemAttr("drawback"))

View File

@@ -0,0 +1,11 @@
# moduleBonusCapitalDroneScopeChip
#
# Used by:
# Variations of module: Capital Drone Scope Chip I (2 of 2)
type = "passive"
def handler(fit, src, context):
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "maxRange", src.getModifiedItemAttr("rangeSkillBonus"), stackingPenalties=True)
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityMissilesRange", src.getModifiedItemAttr("rangeSkillBonus"), stackingPenalties=True)
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityAttackTurretRangeOptimal", src.getModifiedItemAttr("rangeSkillBonus"), stackingPenalties=True)
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityAttackMissileRangeOptimal", src.getModifiedItemAttr("rangeSkillBonus"), stackingPenalties=True)
fit.ship.boostItemAttr("cpuOutput", src.getModifiedItemAttr("drawback"))

View File

@@ -0,0 +1,9 @@
# moduleBonusCapitalDroneSpeedAugmentor
#
# Used by:
# Variations of module: Capital Drone Speed Augmentor I (2 of 2)
type = "passive"
def handler(fit, src, context):
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "maxVelocity", src.getModifiedItemAttr("droneMaxVelocityBonus"), stackingPenalties=True)
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "maxVelocity", src.getModifiedItemAttr("droneMaxVelocityBonus"), stackingPenalties=True)
fit.ship.boostItemAttr("cpuOutput", src.getModifiedItemAttr("drawback"))

View File

@@ -0,0 +1,10 @@
# moduleBonusDroneDamageAmplifier
#
# Used by:
# Modules from group: Drone Damage Modules (11 of 11)
type = "passive"
def handler(fit, src, context):
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityMissilesDamageMultiplier", src.getModifiedItemAttr("droneDamageBonus"))
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityAttackTurretDamageMultiplier", src.getModifiedItemAttr("droneDamageBonus"))
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityAttackMissileDamageMultiplier", src.getModifiedItemAttr("droneDamageBonus"))
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "damageMultiplier", src.getModifiedItemAttr("droneDamageBonus"), stackingPenalties=True)

View File

@@ -0,0 +1,8 @@
# moduleBonusDroneNavigationComputer
#
# Used by:
# Modules from group: Drone Navigation Computer (8 of 8)
type = "passive"
def handler(fit, src, context):
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "maxVelocity", src.getModifiedItemAttr("speedFactor"), stackingPenalties=True)
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "maxVelocity", src.getModifiedItemAttr("speedFactor"), stackingPenalties=True)

View File

@@ -0,0 +1,12 @@
# moduleBonusFighterSupportUnit
#
# Used by:
# Modules from group: Fighter Support Unit (8 of 8)
type = "passive"
def handler(fit, src, context):
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityAttackMissileDuration", src.getModifiedItemAttr("fighterBonusROFPercent"))
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "shieldRechargeRate", src.getModifiedItemAttr("fighterBonusShieldRechargePercent"))
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityMissilesDuration", src.getModifiedItemAttr("fighterBonusROFPercent"))
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "shieldCapacity", src.getModifiedItemAttr("fighterBonusShieldCapacityPercent"))
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "maxVelocity", src.getModifiedItemAttr("fighterBonusVelocityPercent"), stackingPenalties=True)
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityAttackTurretDuration", src.getModifiedItemAttr("fighterBonusROFPercent"))

View File

@@ -0,0 +1,11 @@
# moduleBonusInformationWarfareLinkElectronicSuperiority
#
# Used by:
# Variations of module: Information Warfare Link - Electronic Superiority I (2 of 2)
type = "active"
def handler(fit, module, context):
module.multiplyItemAttr("commandBonusTD", module.getModifiedItemAttr("commandBonusHidden"))
module.multiplyItemAttr("commandBonusECM", module.getModifiedItemAttr("commandBonusHidden"))
module.multiplyItemAttr("commandBonusRSD", module.getModifiedItemAttr("commandBonusHidden"))
module.multiplyItemAttr("commandBonusTP", module.getModifiedItemAttr("commandBonusHidden"))

View File

@@ -0,0 +1,14 @@
# moduleBonusInformationWarfareLinkReconOperation
#
# Used by:
# Variations of module: Information Warfare Link - Recon Operation I (2 of 2)
type = "gang", "active"
gangBoost = "electronicMaxRange"
runTime = "late"
def handler(fit, module, context):
if "gang" not in context: return
groups = ("Target Painter", "Weapon Disruptor", "Sensor Dampener", "ECM", "Burst Jammer")
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name in groups,
"maxRange", module.getModifiedItemAttr("commandBonus"),
stackingPenalties = True)

View File

@@ -0,0 +1,17 @@
# moduleBonusInformationWarfareLinkSensorIntegrity
#
# Used by:
# Variations of module: Information Warfare Link - Sensor Integrity I (2 of 2)
type = "gang", "active"
gangBoost = "maxTargetRange"
gangBonus = "commandBonus"
runTime = "late"
def handler(fit, module, context):
if "gang" not in context: return
fit.ship.boostItemAttr("maxTargetRange", module.getModifiedItemAttr("commandBonus"),
stackingPenalties = True)
for scanType in ("Gravimetric", "Radar", "Ladar", "Magnetometric"):
fit.ship.boostItemAttr("scan%sStrength" % scanType,
module.getModifiedItemAttr("commandBonus"),
stackingPenalties = True)

View File

@@ -0,0 +1,13 @@
# moduleBonusMiningForemanLinkHarvesterCapacitorEfficiency
#
# Used by:
# Variations of module: Mining Foreman Link - Harvester Capacitor Efficiency I (2 of 2)
type = "gang", "active"
gangBoost = "miningCapacitorNeed"
def handler(fit, module, context):
if "gang" not in context: return
groups = ("Mining Laser", "Strip Miner", "Frequency Mining Laser",
"Ice Harvester", "Gas Cloud Harvester")
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name in groups,
"capacitorNeed", module.getModifiedItemAttr("commandBonus"),
stackingPenalties = True)

View File

@@ -0,0 +1,13 @@
# moduleBonusMiningForemanLinkLaserOptimization
#
# Used by:
# Variations of module: Mining Foreman Link - Laser Optimization I (2 of 2)
type = "gang", "active"
gangBoost = "miningDuration"
def handler(fit, module, context):
if "gang" not in context: return
groups = ("Mining Laser", "Strip Miner", "Frequency Mining Laser",
"Ice Harvester", "Gas Cloud Harvester")
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name in groups,
"duration", module.getModifiedItemAttr("commandBonus"),
stackingPenalties = True)

View File

@@ -0,0 +1,13 @@
# moduleBonusMiningForemanLinkMiningLaserFieldEnhancement
#
# Used by:
# Variations of module: Mining Foreman Link - Mining Laser Field Enhancement I (2 of 2)
type = "gang", "active"
gangBoost = "miningMaxRange"
def handler(fit, module, context):
if "gang" not in context: return
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Gas Cloud Harvesting") or mod.item.requiresSkill("Ice Harvesting") or mod.item.requiresSkill("Mining"),
"maxRange", module.getModifiedItemAttr("commandBonus"),
stackingPenalties = True)
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("CPU Management"),
"surveyScanRange", module.getModifiedItemAttr("commandBonus"))

View File

@@ -0,0 +1,28 @@
# moduleBonusNetworkedSensorArray
#
# Used by:
# Module: Networked Sensor Array
type = "active"
def handler(fit, src, context):
fit.ship.increaseItemAttr("maxLockedTargets", src.getModifiedItemAttr("maxLockedTargetsBonus"))
fit.ship.multiplyItemAttr("maxTargetRange", src.getModifiedItemAttr("maxTargetRangeMultiplier"), stackingPenalties=True, penaltyGroup="postMul")
fit.ship.multiplyItemAttr("scanResolution", src.getModifiedItemAttr("scanResolutionMultiplier"), stackingPenalties=True)
for scanType in ('Magnetometric', 'Ladar', 'Gravimetric', 'Radar'):
fit.ship.boostItemAttr("scan{}Strength".format(scanType),
src.getModifiedItemAttr("scan{}StrengthPercent".format(scanType)),
stackingPenalties=True)
# EW cap need increase
groups = [
'Burst Jammer',
'Weapon Disruptor',
'ECM',
'Sensor Dampener',
'Target Painter']
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name in groups or
mod.item.requiresSkill("Propulsion Jamming"),
"capacitorNeed", src.getModifiedItemAttr("ewCapacitorNeedBonus"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Propulsion Jamming"),
"capacitorNeed", src.getModifiedItemAttr("ewCapacitorNeedBonus"))

View File

@@ -0,0 +1,19 @@
# moduleBonusOmnidirectionalTrackingEnhancer
#
# Used by:
# Modules from group: Drone Tracking Enhancer (10 of 10)
type = "passive"
def handler(fit, src, context):
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityAttackMissileExplosionRadius", src.getModifiedItemAttr("aoeCloudSizeBonus"))
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityAttackMissileRangeOptimal", src.getModifiedItemAttr("maxRangeBonus"))
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityAttackTurretRangeFalloff", src.getModifiedItemAttr("falloffBonus"))
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityMissilesExplosionRadius", src.getModifiedItemAttr("aoeCloudSizeBonus"))
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "falloff", src.getModifiedItemAttr("falloffBonus"), stackingPenalties=True)
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityAttackMissileRangeFalloff", src.getModifiedItemAttr("falloffBonus"))
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityAttackTurretTrackingSpeed", src.getModifiedItemAttr("trackingSpeedBonus"))
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "maxRange", src.getModifiedItemAttr("maxRangeBonus"), stackingPenalties=True)
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "trackingSpeed", src.getModifiedItemAttr("trackingSpeedBonus"), stackingPenalties=True)
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityAttackTurretRangeOptimal", src.getModifiedItemAttr("maxRangeBonus"))
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityMissilesExplosionVelocity", src.getModifiedItemAttr("aoeVelocityBonus"))
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityAttackMissileExplosionVelocity", src.getModifiedItemAttr("aoeVelocityBonus"))
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityMissilesRange", src.getModifiedItemAttr("maxRangeBonus"))

View File

@@ -0,0 +1,19 @@
# moduleBonusOmnidirectionalTrackingLink
#
# Used by:
# Modules from group: Drone Tracking Modules (10 of 10)
type = "passive"
def handler(fit, src, context):
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityAttackTurretRangeFalloff", src.getModifiedItemAttr("falloffBonus"))
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityMissilesExplosionVelocity", src.getModifiedItemAttr("aoeVelocityBonus"))
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "trackingSpeed", src.getModifiedItemAttr("trackingSpeedBonus"), stackingPenalties=True)
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityAttackMissileExplosionRadius", src.getModifiedItemAttr("aoeCloudSizeBonus"))
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityAttackTurretTrackingSpeed", src.getModifiedItemAttr("trackingSpeedBonus"))
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityMissilesExplosionRadius", src.getModifiedItemAttr("aoeCloudSizeBonus"))
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityMissilesRange", src.getModifiedItemAttr("maxRangeBonus"))
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityAttackMissileRangeOptimal", src.getModifiedItemAttr("maxRangeBonus"))
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "falloff", src.getModifiedItemAttr("falloffBonus"), stackingPenalties=True)
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityAttackMissileExplosionVelocity", src.getModifiedItemAttr("aoeVelocityBonus"))
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityAttackMissileRangeFalloff", src.getModifiedItemAttr("falloffBonus"))
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "maxRange", src.getModifiedItemAttr("maxRangeBonus"), stackingPenalties=True)
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill("Fighters"), "fighterAbilityAttackTurretRangeOptimal", src.getModifiedItemAttr("maxRangeBonus"))

View File

@@ -0,0 +1,9 @@
# moduleBonusOmnidirectionalTrackingLinkOverload
#
# Used by:
# Modules from group: Drone Tracking Modules (10 of 10)
type = "overheat"
def handler(fit, module, context):
module.boostItemAttr("maxRangeBonus", module.getModifiedItemAttr("overloadTrackingModuleStrengthBonus"))
module.boostItemAttr("falloffBonus", module.getModifiedItemAttr("overloadTrackingModuleStrengthBonus"))
module.boostItemAttr("trackingSpeedBonus", module.getModifiedItemAttr("overloadTrackingModuleStrengthBonus"))

View File

@@ -0,0 +1,65 @@
# moduleBonusSiegeModule
#
# Used by:
# Variations of module: Siege Module I (2 of 2)
type = "active"
runTime = "early"
def handler(fit, src, context):
#Turrets
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Energy Turret") or \
mod.item.requiresSkill("Capital Hybrid Turret") or \
mod.item.requiresSkill("Capital Projectile Turret"),
"damageMultiplier", src.getModifiedItemAttr("siegeTurretDamageBonus"))
#Missiles
for type in ("kinetic", "thermal", "explosive", "em"):
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("XL Torpedoes") or \
mod.charge.requiresSkill("XL Cruise Missiles") or \
mod.charge.requiresSkill("Torpedoes"),
"%sDamage" % type, src.getModifiedItemAttr("siegeMissileDamageBonus"))
# Reppers
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Shield Operation") or \
mod.item.requiresSkill("Capital Repair Systems"),
"duration", src.getModifiedItemAttr("siegeLocalLogisticsDurationBonus"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Shield Operation"),
"shieldBonus", src.getModifiedItemAttr("siegeLocalLogisticsAmountBonus"),
stackingPenalties=True)
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Repair Systems"),
"armorDamageAmount", src.getModifiedItemAttr("siegeLocalLogisticsAmountBonus"),
stackingPenalties=True)
#Speed penalty
fit.ship.boostItemAttr("maxVelocity", src.getModifiedItemAttr("speedFactor"))
#Mass
fit.ship.multiplyItemAttr("mass", src.getModifiedItemAttr("siegeMassMultiplier"),
stackingPenalties=True, penaltyGroup="postMul")
# @ todo: test for April 2016 release
#Block Hostile EWAR and friendly effects
fit.ship.forceItemAttr("disallowOffensiveModifiers", src.getModifiedItemAttr("disallowOffensiveModifiers"))
fit.ship.forceItemAttr("disallowAssistance", src.getModifiedItemAttr("disallowAssistance"))
# new in April 2016 release
for scanType in ('Magnetometric', 'Ladar', 'Gravimetric', 'Radar'):
fit.ship.boostItemAttr("scan{}Strength".format(scanType),
src.getModifiedItemAttr("scan{}StrengthPercent".format(scanType)),
stackingPenalties=True)
# missile ROF bonus
for group in ("Missile Launcher XL Torpedo", "Missile Launcher Rapid Torpedo", "Missile Launcher XL Cruise"):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == group, "speed", src.getModifiedItemAttr("siegeLauncherROFBonus"), stackingPenalties=True)
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Torpedoes"), "maxVelocity", src.getModifiedItemAttr("siegeTorpedoVelocityBonus"), stackingPenalties=True)
fit.ship.increaseItemAttr("warpScrambleStatus", src.getModifiedItemAttr("siegeModeWarpStatus"))
fit.ship.boostItemAttr("remoteRepairImpedance", src.getModifiedItemAttr("remoteRepairImpedanceBonus"))
fit.ship.boostItemAttr("sensorDampenerResistance", src.getModifiedItemAttr("sensorDampenerResistanceBonus"))
fit.ship.boostItemAttr("remoteAssistanceImpedance", src.getModifiedItemAttr("remoteAssistanceImpedanceBonus"))
fit.ship.boostItemAttr("weaponDisruptionResistance", src.getModifiedItemAttr("weaponDisruptionResistanceBonus"))
fit.ship.forceItemAttr("disallowDocking", src.getModifiedItemAttr("disallowDocking"))
fit.ship.forceItemAttr("disallowTethering", src.getModifiedItemAttr("disallowTethering"))

View File

@@ -0,0 +1,12 @@
# moduleBonusSiegeWarfareLinkActiveShielding
#
# Used by:
# Variations of module: Siege Warfare Link - Active Shielding I (2 of 2)
type = "gang", "active"
gangBoost = "shieldRepairDuration"
runTime = "late"
def handler(fit, module, context):
if "gang" not in context: return
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Operation") or mod.item.requiresSkill("Shield Emission Systems"),
"duration", module.getModifiedItemAttr("commandBonus"))

View File

@@ -0,0 +1,14 @@
# moduleBonusSiegeWarfareLinkShieldEfficiency
#
# Used by:
# Variations of module: Siege Warfare Link - Shield Efficiency I (2 of 2)
type = "gang", "active"
gangBoost = "shieldResistance"
runTime = "late"
def handler(fit, module, context):
if "gang" not in context: return
for damageType in ("Em", "Explosive", "Thermal", "Kinetic"):
fit.ship.boostItemAttr("shield%sDamageResonance" % damageType,
module.getModifiedItemAttr("commandBonus"),
stackingPenalties = True)

View File

@@ -0,0 +1,12 @@
# moduleBonusSiegeWarfareLinkShieldHarmonizing
#
# Used by:
# Variations of module: Siege Warfare Link - Shield Harmonizing I (2 of 2)
type = "gang", "active"
gangBoost = "shieldRepairCapacitorNeed"
runTime = "late"
def handler(fit, module, context):
if "gang" not in context: return
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Operation") or mod.item.requiresSkill("Shield Emission Systems"),
"capacitorNeed", module.getModifiedItemAttr("commandBonus"))

View File

@@ -0,0 +1,12 @@
# moduleBonusSkirmishWarfareLinkEvasiveManeuvers
#
# Used by:
# Variations of module: Skirmish Warfare Link - Evasive Maneuvers I (2 of 2)
type = "gang", "active"
gangBoost = "signatureRadius"
runTime = "late"
def handler(fit, module, context):
if "gang" not in context: return
fit.ship.boostItemAttr("signatureRadius", module.getModifiedItemAttr("commandBonus"),
stackingPenalties = True)

View File

@@ -0,0 +1,14 @@
# moduleBonusSkirmishWarfareLinkInterdictionManeuvers
#
# Used by:
# Variations of module: Skirmish Warfare Link - Interdiction Maneuvers I (2 of 2)
type = "gang", "active"
gangBoost = "interdictionMaxRange"
runTime = "late"
def handler(fit, module, context):
if "gang" not in context: return
groups = ("Stasis Web", "Warp Scrambler")
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name in groups,
"maxRange", module.getModifiedItemAttr("commandBonus"),
stackingPenalties = True)

View File

@@ -0,0 +1,13 @@
# moduleBonusSkirmishWarfareLinkRapidDeployment
#
# Used by:
# Variations of module: Skirmish Warfare Link - Rapid Deployment I (2 of 2)
type = "gang", "active"
gangBoost = "speedFactor"
runTime = "late"
def handler(fit, module, context):
if "gang" not in context: return
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Propulsion Module",
"speedFactor", module.getModifiedItemAttr("commandBonus"),
stackingPenalties=True)

View File

@@ -0,0 +1,74 @@
# moduleBonusTriageModule
#
# Used by:
# Variations of module: Triage Module I (2 of 2)
type = "active"
runTime = "early"
def handler(fit, src, context):
# Remote effect bonuses (duration / amount / range / fallout)
for skill, amtAttr, stack in (
("Capital Remote Armor Repair Systems", "armorDamageAmount", True),
("Capital Shield Emission Systems", "shieldBonus", True),
("Capital Capacitor Emission Systems", "powerTransferAmount", False),
("Capital Remote Hull Repair Systems", "structureDamageAmount", False)):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill(skill), "duration", src.getModifiedItemAttr("siegeRemoteLogisticsDurationBonus"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill(skill), amtAttr, src.getModifiedItemAttr("siegeRemoteLogisticsAmountBonus"), stackingPenalties=stack)
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill(skill), "maxRange", src.getModifiedItemAttr("siegeRemoteLogisticsRangeBonus"), stackingPenalties=True)
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill(skill), "falloffEffectiveness", src.getModifiedItemAttr("siegeRemoteLogisticsRangeBonus"), stackingPenalties=True)
# Local armor/shield rep effects (duration / amoutn)
for skill, amtAttr in (
("Capital Shield Operation", "shieldBonus"),
("Capital Repair Systems", "armorDamageAmount")):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill(skill), "duration", src.getModifiedItemAttr("siegeLocalLogisticsDurationBonus"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill(skill), amtAttr, src.getModifiedItemAttr("siegeLocalLogisticsAmountBonus"))
# Speed bonus
fit.ship.boostItemAttr("maxVelocity", src.getModifiedItemAttr("speedFactor"), stackingPenalties=True)
# Scan resolution multiplier
fit.ship.multiplyItemAttr("scanResolution", src.getModifiedItemAttr("scanResolutionMultiplier"), stackingPenalties=True)
# Mass multiplier
fit.ship.multiplyItemAttr("mass", src.getModifiedItemAttr("siegeMassMultiplier"), stackingPenalties=True)
# Max locked targets
fit.ship.increaseItemAttr("maxLockedTargets", src.getModifiedItemAttr("maxLockedTargetsBonus"))
# EW cap need increase
groups = [
'Burst Jammer',
'Weapon Disruptor',
'ECM',
'Sensor Dampener',
'Target Painter']
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name in groups or
mod.item.requiresSkill("Propulsion Jamming"),
"capacitorNeed", src.getModifiedItemAttr("ewCapacitorNeedBonus"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Propulsion Jamming"),
"capacitorNeed", src.getModifiedItemAttr("ewCapacitorNeedBonus"))
# todo: test for April 2016 release
# Block EWAR & projected effects
fit.ship.forceItemAttr("disallowOffensiveModifiers", src.getModifiedItemAttr("disallowOffensiveModifiers"))
fit.ship.forceItemAttr("disallowAssistance", src.getModifiedItemAttr("disallowAssistance"))
# new in April 2016 release
for scanType in ('Magnetometric', 'Ladar', 'Gravimetric', 'Radar'):
fit.ship.boostItemAttr("scan{}Strength".format(scanType),
src.getModifiedItemAttr("scan{}StrengthPercent".format(scanType)),
stackingPenalties=True)
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "damageMultiplier", src.getModifiedItemAttr("droneDamageBonus"), stackingPenalties=True)
fit.ship.increaseItemAttr("warpScrambleStatus", src.getModifiedItemAttr("siegeModeWarpStatus"))
fit.ship.boostItemAttr("sensorDampenerResistance", src.getModifiedItemAttr("sensorDampenerResistanceBonus"))
fit.ship.boostItemAttr("remoteAssistanceImpedance", src.getModifiedItemAttr("remoteAssistanceImpedanceBonus"))
fit.ship.boostItemAttr("remoteRepairImpedance", src.getModifiedItemAttr("remoteRepairImpedanceBonus"))
fit.ship.forceItemAttr("disallowTethering", src.getModifiedItemAttr("disallowTethering"))
fit.ship.forceItemAttr("disallowDocking", src.getModifiedItemAttr("disallowDocking"))

View File

@@ -2,6 +2,7 @@
#
# Used by:
# Ships from group: Assault Frigate (8 of 12)
# Ships from group: Command Destroyer (4 of 4)
# Ships from group: Heavy Assault Cruiser (8 of 11)
type = "passive"
def handler(fit, ship, context):

View File

@@ -2,7 +2,7 @@
#
# Used by:
# Modules from group: Missile Launcher Torpedo (22 of 22)
# Items from market group: Ship Equipment > Turrets & Bays (397 of 767)
# Items from market group: Ship Equipment > Turrets & Bays (428 of 848)
# Module: Interdiction Sphere Launcher I
type = "overheat"
def handler(fit, module, context):

View File

@@ -1,8 +1,8 @@
# overloadSelfArmorDamageAmountDurationBonus
#
# Used by:
# Modules from group: Armor Repair Unit (100 of 100)
# Modules from group: Fueled Armor Repairer (3 of 3)
# Modules from group: Ancillary Armor Repairer (4 of 4)
# Modules from group: Armor Repair Unit (105 of 105)
type = "overheat"
def handler(fit, module, context):
module.boostItemAttr("duration", module.getModifiedItemAttr("overloadSelfDurationBonus"))

View File

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

View File

@@ -1,15 +1,16 @@
# overloadSelfDurationBonus
#
# Used by:
# Modules from group: Capacitor Booster (54 of 54)
# Modules from group: Energy Neutralizer (45 of 45)
# Modules from group: Energy Nosferatu (45 of 45)
# Modules from group: Hull Repair Unit (21 of 21)
# Modules from group: Remote Armor Repairer (33 of 33)
# Modules from group: Remote Capacitor Transmitter (38 of 38)
# Modules from group: Remote Shield Booster (31 of 31)
# Modules from group: Capacitor Booster (59 of 59)
# Modules from group: Energy Neutralizer (51 of 51)
# Modules from group: Energy Nosferatu (51 of 51)
# Modules from group: Hull Repair Unit (25 of 25)
# Modules from group: Remote Armor Repairer (39 of 39)
# Modules from group: Remote Capacitor Transmitter (41 of 41)
# Modules from group: Remote Shield Booster (38 of 38)
# Modules from group: Smart Bomb (118 of 118)
# Modules from group: Warp Disrupt Field Generator (7 of 7)
# Modules named like: Ancillary Remote (8 of 8)
# Module: QA Remote Armor Repair System - 5 Players
# Module: QA Shield Transporter - 5 Players
# Module: Reactive Armor Hardener

View File

@@ -1,6 +1,7 @@
# overloadSelfHardeningInvulnerabilityBonus
#
# Used by:
# Modules named like: Capital Flex Hardener (9 of 9)
# Variations of module: Adaptive Invulnerability Field I (17 of 17)
type = "overheat"
def handler(fit, module, context):

View File

@@ -3,7 +3,7 @@
# Used by:
# Modules from group: Stasis Grappler (7 of 7)
# Modules from group: Stasis Web (18 of 18)
# Modules from group: Warp Scrambler (38 of 39)
# Modules from group: Warp Scrambler (52 of 53)
type = "overheat"
def handler(fit, module, context):
module.boostItemAttr("maxRange", module.getModifiedItemAttr("overloadRangeBonus"),

View File

@@ -1,8 +1,8 @@
# overloadSelfShieldBonusDurationBonus
#
# Used by:
# Modules from group: Fueled Shield Booster (4 of 4)
# Modules from group: Shield Booster (87 of 87)
# Modules from group: Ancillary Shield Booster (5 of 5)
# Modules from group: Shield Booster (93 of 93)
type = "overheat"
def handler(fit, module, context):
module.boostItemAttr("duration", module.getModifiedItemAttr("overloadSelfDurationBonus"))

View File

@@ -1,7 +1,7 @@
# overloadSelfSpeedBonus
#
# Used by:
# Modules from group: Propulsion Module (114 of 114)
# Modules from group: Propulsion Module (127 of 127)
type = "overheat"
def handler(fit, module, context):
module.boostItemAttr("speedFactor", module.getModifiedItemAttr("overloadSpeedFactorBonus"),

View File

@@ -1,7 +1,6 @@
# overloadSelfTrackingModuleBonus
#
# Used by:
# Modules from group: Drone Tracking Modules (10 of 10)
# Modules named like: Tracking Computer (19 of 19)
# Variations of module: Tracking Disruptor I (6 of 6)
type = "overheat"

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