Merge branch 'development'

This commit is contained in:
blitzman
2017-02-05 16:52:27 -05:00
295 changed files with 8706 additions and 7370 deletions

26
.codecov.yml Normal file
View File

@@ -0,0 +1,26 @@
codecov:
notify:
require_ci_to_pass: yes
coverage:
precision: 2
round: down
range: "70...100"
status:
project: yes
patch: yes
changes: no
parsers:
gcov:
branch_detection:
conditional: yes
loop: yes
method: no
macro: no
comment:
layout: "header, diff"
behavior: default
require_changes: no

40
.gitattributes vendored Normal file
View File

@@ -0,0 +1,40 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto
# Explicitly declare text files you want to always be normalized and converted
# to native line endings on checkout.
# *.c text
# *.h text
# Declare files that will always have CRLF line endings on checkout.
# Source files
# ============
*.pxd text eol=crlf
*.py text eol=crlf
*.py3 text eol=crlf
*.pyw text eol=crlf
*.pyx text eol=crlf
# Denote all files that are truly binary and should not be modified.
# Binary files
# ============
*.db binary
*.p binary
*.pkl binary
*.pyc binary
*.pyd binary
*.pyo binary
# Note: .db, .p, and .pkl files are associated
# with the python modules ``pickle``, ``dbm.*``,
# ``shelve``, ``marshal``, ``anydbm``, & ``bsddb``
# (among others).
# Denote all files that are truly binary and should not be modified.
# Image files
# ============
*.png binary
*.jpg binary
*.icns binary
*.ico binary

25
.travis.yml Normal file
View File

@@ -0,0 +1,25 @@
language: python
python:
- '2.7'
env:
- TOXENV=pep8
addons:
apt:
packages:
# for wxPython:
- python-wxgtk2.8
- python-wxtools
- wx2.8-doc
- wx2.8-examples
- wx2.8-headers
- wx2.8-i18n
before_install:
- pip install -U tox
install:
- pip install -r requirements.txt
- pip install -r requirements_test.txt
script:
- tox
- py.test --cov=./
after_success:
- bash <(curl -s https://codecov.io/bash)

View File

@@ -38,7 +38,7 @@ If you wish to help with development or simply need to run pyfa through a Python
* Python 2.7
* `wxPython` 2.8/3.0
* `sqlalchemy` >= 0.6
* `sqlalchemy` >= 1.0.5
* `dateutil`
* `matplotlib` (for some Linux distributions you may need to install separate wxPython bindings such as `python-matplotlib-wx`)
* `requests`

104
config.py
View File

@@ -31,18 +31,20 @@ gameDB = None
class StreamToLogger(object):
"""
Fake file-like stream object that redirects writes to a logger instance.
From: http://www.electricmonk.nl/log/2011/08/14/redirect-stdout-and-stderr-to-a-logger-in-python/
"""
def __init__(self, logger, log_level=logging.INFO):
self.logger = logger
self.log_level = log_level
self.linebuf = ''
"""
Fake file-like stream object that redirects writes to a logger instance.
From: http://www.electricmonk.nl/log/2011/08/14/redirect-stdout-and-stderr-to-a-logger-in-python/
"""
def __init__(self, logger, log_level=logging.INFO):
self.logger = logger
self.log_level = log_level
self.linebuf = ''
def write(self, buf):
for line in buf.rstrip().splitlines():
self.logger.log(self.log_level, line.rstrip())
def write(self, buf):
for line in buf.rstrip().splitlines():
self.logger.log(self.log_level, line.rstrip())
def isFrozen():
if hasattr(sys, 'frozen'):
@@ -50,16 +52,12 @@ def isFrozen():
else:
return False
def getPyfaRoot():
base = getattr(sys.modules['__main__'], "__file__", sys.executable) if isFrozen() else sys.argv[0]
root = os.path.dirname(os.path.realpath(os.path.abspath(base)))
root = unicode(root, sys.getfilesystemencoding())
return root
def __createDirs(path):
if not os.path.exists(path):
os.makedirs(path)
def defPaths(customSavePath):
global debug
global pyfaPath
@@ -77,32 +75,32 @@ def defPaths(customSavePath):
# Python 2.X uses ANSI by default, so we need to convert the character encoding
pyfaPath = getattr(configforced, "pyfaPath", pyfaPath)
if pyfaPath is None:
pyfaPath = getPyfaRoot()
pyfaPath = getPyfaPath()
# Where we store the saved fits etc, default is the current users home directory
if saveInRoot is True:
savePath = getattr(configforced, "savePath", None)
if savePath is None:
savePath = os.path.join(pyfaPath, "saveddata")
savePath = getPyfaPath("saveddata")
else:
savePath = getattr(configforced, "savePath", None)
if savePath is None:
if customSavePath is None: # customSavePath is not overriden
savePath = unicode(os.path.expanduser(os.path.join("~", ".pyfa")),
sys.getfilesystemencoding())
if customSavePath is None: # customSavePath is not overriden
savePath = os.path.expanduser(os.path.join("~", ".pyfa"))
else:
savePath = customSavePath
__createDirs(savePath)
if isFrozen():
os.environ["REQUESTS_CA_BUNDLE"] = os.path.join(pyfaPath, "cacert.pem")
os.environ["SSL_CERT_FILE"] = os.path.join(pyfaPath, "cacert.pem")
certName = "cacert.pem"
os.environ["REQUESTS_CA_BUNDLE"] = getPyfaPath(certName).encode('utf8')
os.environ["SSL_CERT_FILE"] = getPyfaPath(certName).encode('utf8')
format = '%(asctime)s %(name)-24s %(levelname)-8s %(message)s'
logging.basicConfig(format=format, level=logLevel)
handler = logging.handlers.RotatingFileHandler(os.path.join(savePath, "log.txt"), maxBytes=1000000, backupCount=3)
formatter = logging.Formatter(format)
loggingFormat = '%(asctime)s %(name)-24s %(levelname)-8s %(message)s'
logging.basicConfig(format=loggingFormat, level=logLevel)
handler = logging.handlers.RotatingFileHandler(getSavePath("log.txt"), maxBytes=1000000, backupCount=3)
formatter = logging.Formatter(loggingFormat)
handler.setFormatter(formatter)
logging.getLogger('').addHandler(handler)
@@ -114,23 +112,61 @@ def defPaths(customSavePath):
sys.stdout = sl
# This interferes with cx_Freeze's own handling of exceptions. Find a way to fix this.
#stderr_logger = logging.getLogger('STDERR')
#sl = StreamToLogger(stderr_logger, logging.ERROR)
#sys.stderr = sl
# stderr_logger = logging.getLogger('STDERR')
# sl = StreamToLogger(stderr_logger, logging.ERROR)
# sys.stderr = sl
# The database where we store all the fits etc
saveDB = os.path.join(savePath, "saveddata.db")
saveDB = getSavePath("saveddata.db")
# The database where the static EVE data from the datadump is kept.
# This is not the standard sqlite datadump but a modified version created by eos
# maintenance script
gameDB = os.path.join(pyfaPath, "eve.db")
gameDB = getPyfaPath("eve.db")
## DON'T MODIFY ANYTHING BELOW ##
# DON'T MODIFY ANYTHING BELOW!
import eos.config
#Caching modifiers, disable all gamedata caching, its unneeded.
# Caching modifiers, disable all gamedata caching, its unneeded.
eos.config.gamedataCache = False
# saveddata db location modifier, shouldn't ever need to touch this
eos.config.saveddata_connectionstring = "sqlite:///" + saveDB + "?check_same_thread=False"
eos.config.gamedata_connectionstring = "sqlite:///" + gameDB + "?check_same_thread=False"
def getPyfaPath(Append=None):
base = getattr(sys.modules['__main__'], "__file__", sys.executable) if isFrozen() else sys.argv[0]
root = os.path.dirname(os.path.realpath(os.path.abspath(base)))
if Append:
path = parsePath(root, Append)
else:
path = parsePath(root)
return path
def getSavePath(Append=None):
root = savePath
if Append:
path = parsePath(root, Append)
else:
path = parsePath(root)
return path
def parsePath(root, Append=None):
if Append:
path = os.path.join(root, Append)
else:
path = root
if type(path) == str: # leave unicode ones alone
try:
path = path.decode('utf8')
except UnicodeDecodeError:
path = path.decode('windows-1252')
return path

View File

@@ -4,10 +4,12 @@ from os.path import realpath, join, dirname, abspath
debug = False
gamedataCache = True
saveddataCache = True
gamedata_version = ""
gamedata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "eve.db")),
sys.getfilesystemencoding())
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()))

View File

@@ -1,2 +1,2 @@
__all__ = ["attribute", "category", "effect", "group", "metaData",
"icon", "item", "marketGroup", "metaGroup", "unit"]
"icon", "item", "marketGroup", "metaGroup", "unit", "alphaClones"]

View File

@@ -0,0 +1,46 @@
# ===============================================================================
# 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 Column, String, Integer, Table, ForeignKey
from sqlalchemy.orm import relation, mapper, synonym
from eos.db import gamedata_meta
from eos.types import AlphaClone, AlphaCloneSkill
alphaclones_table = Table("alphaClones", gamedata_meta,
Column("alphaCloneID", Integer, primary_key=True),
Column("alphaCloneName", String),
)
alphacloneskskills_table = Table("alphaCloneSkills", gamedata_meta,
Column("alphaCloneID", Integer, ForeignKey("alphaClones.alphaCloneID"), primary_key=True),
Column("typeID", Integer, primary_key=True),
Column("level", Integer),
)
mapper(AlphaClone, alphaclones_table,
properties={
"ID": synonym("alphaCloneID"),
"skills": relation(
AlphaCloneSkill,
cascade="all,delete-orphan",
backref="clone")
})
mapper(AlphaCloneSkill, alphacloneskskills_table)

View File

@@ -39,8 +39,8 @@ items_table = Table("invtypes", gamedata_meta,
Column("iconID", Integer, ForeignKey("icons.iconID")),
Column("groupID", Integer, ForeignKey("invgroups.groupID"), index=True))
from .metaGroup import metatypes_table
from .traits import traits_table
from .metaGroup import metatypes_table # noqa
from .traits import traits_table # noqa
mapper(Item, items_table,
properties={"group": relation(Group, backref="items"),

View File

@@ -21,10 +21,13 @@ from sqlalchemy.orm import join, exc
from sqlalchemy.sql import and_, or_, select
import eos.config
# TODO: Unsure which item the code below needs :(
# from eos.gamedata import Item
from eos.gamedata import Attribute
from eos.db import gamedata_session
from eos.db.gamedata.metaGroup import metatypes_table, items_table
from eos.db.util import processEager, processWhere
from eos.types import Item, Category, Group, MarketGroup, AttributeInfo, MetaData, MetaGroup
from eos.types import Item, Category, Group, MarketGroup, AttributeInfo, MetaData, MetaGroup, AlphaClone
configVal = getattr(eos.config, "gamedataCache", None)
if configVal is True:
@@ -97,6 +100,24 @@ def getItem(lookfor, eager=None):
return item
@cachedQuery(1, "lookfor")
def getAlphaClone(lookfor, eager=None):
if isinstance(lookfor, int):
if eager is None:
item = gamedata_session.query(AlphaClone).get(lookfor)
else:
item = gamedata_session.query(AlphaClone).options(*processEager(eager)).filter(AlphaClone.ID == lookfor).first()
else:
raise TypeError("Need integer as argument")
return item
def getAlphaCloneList(eager=None):
eager = processEager(eager)
clones = gamedata_session.query(AlphaClone).options(*eager).all()
return clones
groupNameMap = {}
@@ -280,9 +301,9 @@ def directAttributeRequest(itemIDs, attrIDs):
if not isinstance(itemID, int):
raise TypeError("All itemIDs must be integer")
q = select((eos.types.Item.typeID, eos.types.Attribute.attributeID, eos.types.Attribute.value),
and_(eos.types.Attribute.attributeID.in_(attrIDs), eos.types.Item.typeID.in_(itemIDs)),
from_obj=[join(eos.types.Attribute, eos.types.Item)])
q = select((Item.typeID, Attribute.attributeID, Attribute.value),
and_(Attribute.attributeID.in_(attrIDs), Item.typeID.in_(itemIDs)),
from_obj=[join(Attribute, Item)])
result = gamedata_session.execute(q).fetchall()
return result

View File

@@ -45,7 +45,7 @@ CONVERSIONS = {
8746, # Quantum Co-Processor
8745, # Photonic CPU Enhancer
15425, # Naiyon's Modified Co-Processor (never existed but convert
# anyway as some fits may include it)
# anyway as some fits may include it)
],
8748: [ # Upgraded Co-Processor
8747, # Nanomechanical CPU Enhancer I
@@ -70,7 +70,7 @@ CONVERSIONS = {
16543, # Micro 'Vigor' Core Augmentation
],
8089: [ # Compact Light Missile Launcher
8093, # Prototype 'Arbalest' Light Missile Launcher
8093, # Prototype 'Arbalest' Light Missile Launcher
],
8091: [ # Ample Light Missile Launcher
7993, # Experimental TE-2100 Light Missile Launcher
@@ -82,6 +82,7 @@ CONVERSIONS = {
]
}
def upgrade(saveddata_engine):
# Update fits schema to include target resists attribute
try:
@@ -92,6 +93,7 @@ def upgrade(saveddata_engine):
# Convert modules
for replacement_item, list in CONVERSIONS.iteritems():
for retired_item in list:
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
(replacement_item, retired_item))
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?',
(replacement_item, retired_item))

View File

@@ -6,6 +6,7 @@ Migration 10
import sqlalchemy
def upgrade(saveddata_engine):
# Update projectedFits schema to include active attribute
try:

View File

@@ -7,7 +7,6 @@ Migration 11
modules with their new replacements
"""
CONVERSIONS = {
16467: ( # Medium Gremlin Compact Energy Neutralizer
16471, # Medium Unstable Power Fluctuator I
@@ -106,11 +105,12 @@ CONVERSIONS = {
),
}
def upgrade(saveddata_engine):
def upgrade(saveddata_engine):
# Convert modules
for replacement_item, list in CONVERSIONS.iteritems():
for retired_item in list:
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
(replacement_item, retired_item))
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?',
(replacement_item, retired_item))

View File

@@ -7,7 +7,6 @@ Migration 12
modules with their new replacements
"""
CONVERSIONS = {
16457: ( # Crosslink Compact Ballistic Control System
16459, # Muon Coil Bolt Array I
@@ -330,11 +329,12 @@ CONVERSIONS = {
),
}
def upgrade(saveddata_engine):
def upgrade(saveddata_engine):
# Convert modules
for replacement_item, list in CONVERSIONS.iteritems():
for retired_item in list:
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
(replacement_item, retired_item))
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?',
(replacement_item, retired_item))

View File

@@ -6,10 +6,11 @@ Migration 13
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")
saveddata_engine.execute("UPDATE fits SET implantLocation = 0")

View File

@@ -6,8 +6,10 @@ Migration 14
import sqlalchemy
def upgrade(saveddata_engine):
if saveddata_engine.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='fighters'").scalar() == 'fighters':
if saveddata_engine.execute(
"SELECT name FROM sqlite_master WHERE type='table' AND name='fighters'").scalar() == 'fighters':
# Fighters table exists
try:
saveddata_engine.execute("SELECT active FROM fighters LIMIT 1")
@@ -16,4 +18,4 @@ def upgrade(saveddata_engine):
# (they will be recreated)
saveddata_engine.execute("DROP TABLE fighters")
saveddata_engine.execute("DROP TABLE fightersAbilities")
saveddata_engine.execute("DROP TABLE fightersAbilities")

View File

@@ -6,8 +6,8 @@ Migration 15
import sqlalchemy
def upgrade(saveddata_engine):
def upgrade(saveddata_engine):
sql = """
DELETE FROM modules WHERE ID IN
(

View File

@@ -6,6 +6,7 @@ Migration 16
import sqlalchemy
def upgrade(saveddata_engine):
# Update fits schema to include notes attribute
try:

View File

@@ -33,7 +33,8 @@ def upgrade(saveddata_engine):
inserts.append({"boosterID": value, "boostedID": boosted, "active": 1})
try:
saveddata_session.execute(commandFits_table.insert(), {"boosterID": value, "boostedID": boosted, "active": 1})
except Exception, e:
saveddata_session.execute(commandFits_table.insert(),
{"boosterID": value, "boostedID": boosted, "active": 1})
except Exception:
pass
saveddata_session.commit()

View File

@@ -4,27 +4,26 @@ Migration 8
- Converts modules from old Warfare Links to Command Modules
"""
CONVERSIONS = {
42526: ( # Armor Command Burst I
20069, # Armored Warfare Link - Damage Control I
20409, # Armored Warfare Link - Passive Defense I
22227, # Armored Warfare Link - Rapid Repair I
20069, # Armored Warfare Link - Damage Control I
20409, # Armored Warfare Link - Passive Defense I
22227, # Armored Warfare Link - Rapid Repair I
),
43552: ( # Armor Command Burst II
4264, # Armored Warfare Link - Damage Control II
4266, # Armored Warfare Link - Passive Defense II
4266, # Armored Warfare Link - Rapid Repair II
4264, # Armored Warfare Link - Damage Control II
4266, # Armored Warfare Link - Passive Defense II
4266, # Armored Warfare Link - Rapid Repair II
),
42527: ( # Information Command Burst I
11052, # Information Warfare Link - Sensor Integrity I
20405, # Information Warfare Link - Recon Operation I
20406, # Information Warfare Link - Electronic Superiority I
11052, # Information Warfare Link - Sensor Integrity I
20405, # Information Warfare Link - Recon Operation I
20406, # Information Warfare Link - Electronic Superiority I
),
43554: ( # Information Command Burst II
4268, # Information Warfare Link - Electronic Superiority II
4270, # Information Warfare Link - Recon Operation II
4272, # Information Warfare Link - Sensor Integrity II
4268, # Information Warfare Link - Electronic Superiority II
4270, # Information Warfare Link - Recon Operation II
4272, # Information Warfare Link - Sensor Integrity II
),
42529: ( # Shield Command Burst I
20124, # Siege Warfare Link - Active Shielding I
@@ -34,17 +33,17 @@ CONVERSIONS = {
43555: ( # Shield Command Burst II
4280, # Siege Warfare Link - Active Shielding II
4282, # Siege Warfare Link - Shield Efficiency II
4284 # Siege Warfare Link - Shield Harmonizing II
4284 # Siege Warfare Link - Shield Harmonizing II
),
42530: ( # Skirmish Command Burst I
11017, # Skirmish Warfare Link - Interdiction Maneuvers I
20070, # Skirmish Warfare Link - Evasive Maneuvers I
20408, # Skirmish Warfare Link - Rapid Deployment I
11017, # Skirmish Warfare Link - Interdiction Maneuvers I
20070, # Skirmish Warfare Link - Evasive Maneuvers I
20408, # Skirmish Warfare Link - Rapid Deployment I
),
43556: ( # Skirmish Command Burst II
4286, # Skirmish Warfare Link - Evasive Maneuvers II
4288, # Skirmish Warfare Link - Interdiction Maneuvers II
4290 # Skirmish Warfare Link - Rapid Deployment II
4290 # Skirmish Warfare Link - Rapid Deployment II
),
42528: ( # Mining Foreman Burst I
22553, # Mining Foreman Link - Harvester Capacitor Efficiency I
@@ -54,15 +53,16 @@ CONVERSIONS = {
43551: ( # Mining Foreman Burst II
4274, # Mining Foreman Link - Harvester Capacitor Efficiency II
4276, # Mining Foreman Link - Laser Optimization II
4278 # Mining Foreman Link - Mining Laser Field Enhancement II
4278 # Mining Foreman Link - Mining Laser Field Enhancement II
),
}
def upgrade(saveddata_engine):
def upgrade(saveddata_engine):
# Convert modules
for replacement_item, list in CONVERSIONS.iteritems():
for retired_item in list:
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
(replacement_item, retired_item))
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?',
(replacement_item, retired_item))

View File

@@ -11,10 +11,10 @@ def upgrade(saveddata_engine):
from eos.db import saveddata_session
sql = """
DELETE FROM commandFits
WHERE boosterID NOT IN (select ID from fits)
OR boostedID NOT IN (select ID from fits)
"""
DELETE FROM commandFits
WHERE boosterID NOT IN (select ID from fits)
OR boostedID NOT IN (select ID from fits)
"""
saveddata_session.execute(sql)
saveddata_session.commit()

View File

@@ -6,6 +6,7 @@ Migration 2
import sqlalchemy
def upgrade(saveddata_engine):
# Update characters schema to include default chars
try:

View File

@@ -0,0 +1,15 @@
"""
Migration 20
- Adds support for alpha clones to the characters table
"""
import sqlalchemy
def upgrade(saveddata_engine):
# Update characters schema to include alphaCloneID
try:
saveddata_engine.execute("SELECT alphaCloneID FROM characters LIMIT 1")
except sqlalchemy.exc.DatabaseError:
saveddata_engine.execute("ALTER TABLE characters ADD COLUMN alphaCloneID INTEGER;")

View File

@@ -6,6 +6,7 @@ Migration 3
import sqlalchemy
def upgrade(saveddata_engine):
try:
saveddata_engine.execute("SELECT modeID FROM fits LIMIT 1")

View File

@@ -10,7 +10,6 @@ Migration 4
and output of itemDiff.py
"""
CONVERSIONS = {
506: ( # 'Basic' Capacitor Power Relay
8205, # Alpha Reactor Control: Capacitor Power Relay
@@ -131,11 +130,12 @@ CONVERSIONS = {
),
}
def upgrade(saveddata_engine):
def upgrade(saveddata_engine):
# Convert modules
for replacement_item, list in CONVERSIONS.iteritems():
for retired_item in list:
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
(replacement_item, retired_item))
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?',
(replacement_item, retired_item))

View File

@@ -4,5 +4,6 @@ Migration 5
Simply deletes damage profiles with a blank name. See GH issue #256
"""
def upgrade(saveddata_engine):
saveddata_engine.execute('DELETE FROM damagePatterns WHERE name LIKE ?', ("",))

View File

@@ -4,6 +4,8 @@ Migration 6
Overwrites damage profile 0 to reset bad uniform values (bad values set with bug)
"""
def upgrade(saveddata_engine):
saveddata_engine.execute('DELETE FROM damagePatterns WHERE name LIKE ? OR ID LIKE ?', ("Uniform", "1"))
saveddata_engine.execute('INSERT INTO damagePatterns VALUES (?, ?, ?, ?, ?, ?, ?)', (1, "Uniform", 25, 25, 25, 25, None))
saveddata_engine.execute('INSERT INTO damagePatterns VALUES (?, ?, ?, ?, ?, ?, ?)',
(1, "Uniform", 25, 25, 25, 25, None))

View File

@@ -8,17 +8,16 @@ Migration 7
Pyfa.
"""
CONVERSIONS = {
640: ( # Scorpion
4005, # Scorpion Ishukone Watch
)
}
def upgrade(saveddata_engine):
def upgrade(saveddata_engine):
# Convert ships
for replacement_item, list in CONVERSIONS.iteritems():
for retired_item in list:
saveddata_engine.execute('UPDATE "fits" SET "shipID" = ? WHERE "shipID" = ?', (replacement_item, retired_item))
saveddata_engine.execute('UPDATE "fits" SET "shipID" = ? WHERE "shipID" = ?',
(replacement_item, retired_item))

View File

@@ -7,7 +7,6 @@ Migration 8
modules with their new replacements
"""
CONVERSIONS = {
8529: ( # Large F-S9 Regolith Compact Shield Extender
8409, # Large Subordinate Screen Stabilizer I
@@ -71,15 +70,16 @@ CONVERSIONS = {
11321, # 800mm Reinforced Nanofiber Plates I
),
11317: ( # 800mm Rolled Tungsten Compact Plates
11315, # 800mm Reinforced Titanium Plates I
11315, # 800mm Reinforced Titanium Plates I
),
}
def upgrade(saveddata_engine):
def upgrade(saveddata_engine):
# Convert modules
for replacement_item, list in CONVERSIONS.iteritems():
for retired_item in list:
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
(replacement_item, retired_item))
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?',
(replacement_item, retired_item))

View File

@@ -16,8 +16,10 @@ CREATE TABLE boostersTemp (
)
"""
def upgrade(saveddata_engine):
saveddata_engine.execute(tmpTable)
saveddata_engine.execute("INSERT INTO boostersTemp (ID, itemID, fitID, active) SELECT ID, itemID, fitID, active FROM boosters")
saveddata_engine.execute(
"INSERT INTO boostersTemp (ID, itemID, fitID, active) SELECT ID, itemID, fitID, active FROM boosters")
saveddata_engine.execute("DROP TABLE boosters")
saveddata_engine.execute("ALTER TABLE boostersTemp RENAME TO boosters")

View File

@@ -33,10 +33,12 @@ characters_table = Table("characters", saveddata_meta,
Column("defaultChar", Integer),
Column("chars", String, nullable=True),
Column("defaultLevel", Integer, nullable=True),
Column("alphaCloneID", Integer, nullable=True),
Column("ownerID", ForeignKey("users.ID"), nullable=True))
mapper(Character, characters_table,
properties={
"_Character__alphaCloneID": characters_table.c.alphaCloneID,
"savedName": characters_table.c.name,
"_Character__owner": relation(
User,

View File

@@ -28,77 +28,135 @@ class DatabaseCleanup:
pass
@staticmethod
def OrphanedCharacterSkills(saveddata_engine):
# Finds and fixes database corruption issues.
logger.debug("Start databsae validation and cleanup.")
def ExecuteSQLQuery(saveddata_engine, query):
try:
results = saveddata_engine.execute(query)
return results
except sqlalchemy.exc.DatabaseError:
logger.error("Failed to connect to database or error executing query:\n%s",query)
return None
@staticmethod
def OrphanedCharacterSkills(saveddata_engine):
# Find orphaned character skills.
# This solves an issue where the character doesn't exist, but skills for that character do.
# See issue #917
try:
logger.debug("Running database cleanup for character skills.")
results = saveddata_engine.execute("SELECT COUNT(*) AS num FROM characterSkills "
"WHERE characterID NOT IN (SELECT ID from characters)")
row = results.first()
logger.debug("Running database cleanup for character skills.")
query = "SELECT COUNT(*) AS num FROM characterSkills WHERE characterID NOT IN (SELECT ID from characters)"
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
if row and row['num']:
delete = saveddata_engine.execute("DELETE FROM characterSkills WHERE characterID NOT IN (SELECT ID from characters)")
logger.error("Database corruption found. Cleaning up %d records.", delete.rowcount)
if results is None:
return
except sqlalchemy.exc.DatabaseError:
logger.error("Failed to connect to database.")
row = results.first()
if row and row['num']:
query = "DELETE FROM characterSkills WHERE characterID NOT IN (SELECT ID from characters)"
delete = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
logger.error("Database corruption found. Cleaning up %d records.", delete.rowcount)
@staticmethod
def OrphanedFitDamagePatterns(saveddata_engine):
# Find orphaned damage patterns.
# This solves an issue where the damage pattern doesn't exist, but fits reference the pattern.
# See issue #777
try:
logger.debug("Running database cleanup for orphaned damage patterns attached to fits.")
logger.debug("Running database cleanup for orphaned damage patterns attached to fits.")
query = "SELECT COUNT(*) AS num FROM fits WHERE damagePatternID NOT IN (SELECT ID FROM damagePatterns) OR damagePatternID IS NULL"
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
results = saveddata_engine.execute("SELECT COUNT(*) AS num FROM fits WHERE damagePatternID NOT IN (SELECT ID FROM damagePatterns) OR damagePatternID IS NULL")
row = results.first()
if results is None:
return
if row and row['num']:
# Get Uniform damage pattern ID
query = saveddata_engine.execute("SELECT ID FROM damagePatterns WHERE name = 'Uniform'")
rows = query.fetchall()
row = results.first()
if len(rows) == 0:
logger.error("Missing uniform damage pattern.")
elif len(rows) > 1:
logger.error("More than one uniform damage pattern found.")
else:
uniform_damage_pattern_id = rows[0]['ID']
update = saveddata_engine.execute("UPDATE 'fits' SET 'damagePatternID' = ? "
"WHERE damagePatternID NOT IN (SELECT ID FROM damagePatterns) OR damagePatternID IS NULL",
uniform_damage_pattern_id)
logger.error("Database corruption found. Cleaning up %d records.", update.rowcount)
except sqlalchemy.exc.DatabaseError:
logger.error("Failed to connect to database.")
if row and row['num']:
# Get Uniform damage pattern ID
uniform_query = "SELECT ID FROM damagePatterns WHERE name = 'Uniform'"
uniform_results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, uniform_query)
if uniform_results is None:
return
rows = uniform_results.fetchall()
if len(rows) == 0:
logger.error("Missing uniform damage pattern.")
elif len(rows) > 1:
logger.error("More than one uniform damage pattern found.")
else:
uniform_damage_pattern_id = rows[0]['ID']
update_query = "UPDATE 'fits' SET 'damagePatternID' = " + str(uniform_damage_pattern_id) + \
" WHERE damagePatternID NOT IN (SELECT ID FROM damagePatterns) OR damagePatternID IS NULL"
update_results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, update_query)
logger.error("Database corruption found. Cleaning up %d records.", update_results.rowcount)
@staticmethod
def OrphanedFitCharacterIDs(saveddata_engine):
# Find orphaned character IDs. This solves an issue where the character doesn't exist, but fits reference the pattern.
try:
logger.debug("Running database cleanup for orphaned characters attached to fits.")
results = saveddata_engine.execute("SELECT COUNT(*) AS num FROM fits WHERE characterID NOT IN (SELECT ID FROM characters) OR characterID IS NULL")
row = results.first()
logger.debug("Running database cleanup for orphaned characters attached to fits.")
query = "SELECT COUNT(*) AS num FROM fits WHERE characterID NOT IN (SELECT ID FROM characters) OR characterID IS NULL"
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
if row['num']:
# Get All 5 character ID
query = saveddata_engine.execute("SELECT ID FROM characters WHERE name = 'All 5'")
rows = query.fetchall()
if results is None:
return
if len(rows) == 0:
logger.error("Missing 'All 5' character.")
elif len(rows) > 1:
logger.error("More than one 'All 5' character found.")
else:
all5_id = rows[0]['ID']
update = saveddata_engine.execute("UPDATE 'fits' SET 'characterID' = ? "
"WHERE characterID not in (select ID from characters) OR characterID IS NULL",
all5_id)
logger.error("Database corruption found. Cleaning up %d records.", update.rowcount)
except sqlalchemy.exc.DatabaseError:
logger.error("Failed to connect to database.")
row = results.first()
if row and row['num']:
# Get All 5 character ID
all5_query = "SELECT ID FROM characters WHERE name = 'All 5'"
all5_results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, all5_query)
if all5_results is None:
return
rows = all5_results.fetchall()
if len(rows) == 0:
logger.error("Missing 'All 5' character.")
elif len(rows) > 1:
logger.error("More than one 'All 5' character found.")
else:
all5_id = rows[0]['ID']
update_query = "UPDATE 'fits' SET 'characterID' = " + str(all5_id) + \
" WHERE characterID not in (select ID from characters) OR characterID IS NULL"
update_results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, update_query)
logger.error("Database corruption found. Cleaning up %d records.", update_results.rowcount)
@staticmethod
def NullDamagePatternNames(saveddata_engine):
# Find damage patterns that are missing the name.
# This solves an issue where the damage pattern ends up with a name that is null.
# See issue #949
logger.debug("Running database cleanup for missing damage pattern names.")
query = "SELECT COUNT(*) AS num FROM damagePatterns WHERE name IS NULL OR name = ''"
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
if results is None:
return
row = results.first()
if row and row['num']:
query = "DELETE FROM damagePatterns WHERE name IS NULL OR name = ''"
delete = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
logger.error("Database corruption found. Cleaning up %d records.", delete.rowcount)
@staticmethod
def NullTargetResistNames(saveddata_engine):
# Find target resists that are missing the name.
# This solves an issue where the target resist ends up with a name that is null.
# See issue #949
logger.debug("Running database cleanup for missing target resist names.")
query = "SELECT COUNT(*) AS num FROM targetResists WHERE name IS NULL OR name = ''"
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
if results is None:
return
row = results.first()
if row and row['num']:
query = "DELETE FROM targetResists WHERE name IS NULL OR name = ''"
delete = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
logger.error("Database corruption found. Cleaning up %d records.", delete.rowcount)

View File

@@ -18,7 +18,7 @@
# ===============================================================================
from sqlalchemy import Table, Column, Integer, ForeignKey, Boolean
from sqlalchemy.orm import *
from sqlalchemy.orm import mapper, relation
from eos.db import saveddata_meta
from eos.types import Fighter, Fit

View File

@@ -17,20 +17,22 @@
# along with eos. If not, see <http://www.gnu.org/licenses/>.
# ===============================================================================
from sqlalchemy import *
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.orm import *
from sqlalchemy.orm.collections import attribute_mapped_collection
from sqlalchemy.sql import and_
from sqlalchemy.orm import relation, reconstructor, mapper, relationship
from sqlalchemy import ForeignKey, Column, Integer, String, Table, Boolean
from eos.db import saveddata_meta
from eos.db import saveddata_session
from eos.db.saveddata.cargo import cargo_table
from eos.db.saveddata.drone import drones_table
from eos.db.saveddata.fighter import fighters_table
from eos.db.saveddata.implant import fitImplants_table
from eos.db.saveddata.module import modules_table
from eos.effectHandlerHelpers import *
from eos.types import Fit, Module, User, Booster, Drone, Fighter, Cargo, Implant, Character, DamagePattern, \
from eos.effectHandlerHelpers import HandledModuleList, HandledImplantBoosterList, HandledProjectedModList, \
HandledDroneCargoList, HandledProjectedDroneList
from eos.types import Fit as es_Fit, Module, User, Booster, Drone, Fighter, Cargo, Implant, Character, DamagePattern, \
TargetResists, ImplantLocation
fits_table = Table("fits", saveddata_meta,
@@ -45,7 +47,7 @@ fits_table = Table("fits", saveddata_meta,
Column("targetResistsID", ForeignKey("targetResists.ID"), nullable=True),
Column("modeID", Integer, nullable=True),
Column("implantLocation", Integer, nullable=False, default=ImplantLocation.FIT),
Column("notes", String, nullable = True),
Column("notes", String, nullable=True),
)
projectedFits_table = Table("projectedFits", saveddata_meta,
@@ -61,6 +63,7 @@ commandFits_table = Table("commandFits", saveddata_meta,
Column("active", Boolean, nullable=False, default=1)
)
class ProjectedFit(object):
def __init__(self, sourceID, source_fit, amount=1, active=True):
self.sourceID = sourceID
@@ -72,9 +75,9 @@ class ProjectedFit(object):
def init(self):
if self.source_fit.isInvalid:
# Very rare for this to happen, but be prepared for it
eos.db.saveddata_session.delete(self.source_fit)
eos.db.saveddata_session.flush()
eos.db.saveddata_session.refresh(self.victim_fit)
saveddata_session.delete(self.source_fit)
saveddata_session.flush()
saveddata_session.refresh(self.victim_fit)
# We have a series of setters and getters here just in case someone
# downgrades and screws up the table with NULL values
@@ -91,6 +94,7 @@ class ProjectedFit(object):
self.sourceID, self.victimID, self.amount, self.active, hex(id(self))
)
class CommandFit(object):
def __init__(self, boosterID, booster_fit, active=True):
self.boosterID = boosterID
@@ -101,125 +105,126 @@ class CommandFit(object):
def init(self):
if self.booster_fit.isInvalid:
# Very rare for this to happen, but be prepared for it
eos.db.saveddata_session.delete(self.booster_fit)
eos.db.saveddata_session.flush()
eos.db.saveddata_session.refresh(self.boosted_fit)
saveddata_session.delete(self.booster_fit)
saveddata_session.flush()
saveddata_session.refresh(self.boosted_fit)
def __repr__(self):
return "CommandFit(boosterID={}, boostedID={}, active={}) at {}".format(
self.boosterID, self.boostedID, self.active, hex(id(self))
)
Fit._Fit__projectedFits = association_proxy(
es_Fit._Fit__projectedFits = association_proxy(
"victimOf", # look at the victimOf association...
"source_fit", # .. and return the source fits
creator=lambda sourceID, source_fit: ProjectedFit(sourceID, source_fit)
)
Fit._Fit__commandFits = association_proxy(
es_Fit._Fit__commandFits = association_proxy(
"boostedOf", # look at the boostedOf association...
"booster_fit", # .. and return the booster fit
creator=lambda boosterID, booster_fit: CommandFit(boosterID, booster_fit)
)
mapper(Fit, fits_table,
properties={
"_Fit__modules": relation(
Module,
collection_class=HandledModuleList,
primaryjoin=and_(modules_table.c.fitID == fits_table.c.ID, modules_table.c.projected == False),
order_by=modules_table.c.position,
cascade='all, delete, delete-orphan'),
"_Fit__projectedModules": relation(
Module,
collection_class=HandledProjectedModList,
cascade='all, delete, delete-orphan',
single_parent=True,
primaryjoin=and_(modules_table.c.fitID == fits_table.c.ID, modules_table.c.projected == True)),
"owner": relation(
User,
backref="fits"),
"itemID": fits_table.c.shipID,
"shipID": fits_table.c.shipID,
"_Fit__boosters": relation(
Booster,
collection_class=HandledImplantBoosterList,
cascade='all, delete, delete-orphan',
single_parent=True),
"_Fit__drones": relation(
Drone,
collection_class=HandledDroneCargoList,
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,
cascade='all, delete, delete-orphan',
single_parent=True,
primaryjoin=and_(cargo_table.c.fitID == fits_table.c.ID)),
"_Fit__projectedDrones": relation(
Drone,
collection_class=HandledProjectedDroneList,
cascade='all, delete, delete-orphan',
single_parent=True,
primaryjoin=and_(drones_table.c.fitID == fits_table.c.ID, drones_table.c.projected == True)),
"_Fit__projectedFighters": relation(
Fighter,
collection_class=HandledProjectedDroneList,
cascade='all, delete, delete-orphan',
single_parent=True,
primaryjoin=and_(fighters_table.c.fitID == fits_table.c.ID, fighters_table.c.projected == True)),
"_Fit__implants": relation(
Implant,
collection_class=HandledImplantBoosterList,
cascade='all, delete, delete-orphan',
backref='fit',
single_parent=True,
primaryjoin=fitImplants_table.c.fitID == fits_table.c.ID,
secondaryjoin=fitImplants_table.c.implantID == Implant.ID,
secondary=fitImplants_table),
"_Fit__character": relation(
Character,
backref="fits"),
"_Fit__damagePattern": relation(DamagePattern),
"_Fit__targetResists": relation(TargetResists),
"projectedOnto": relationship(
ProjectedFit,
primaryjoin=projectedFits_table.c.sourceID == fits_table.c.ID,
backref='source_fit',
collection_class=attribute_mapped_collection('victimID'),
cascade='all, delete, delete-orphan'),
"victimOf": relationship(
ProjectedFit,
primaryjoin=fits_table.c.ID == projectedFits_table.c.victimID,
backref='victim_fit',
collection_class=attribute_mapped_collection('sourceID'),
cascade='all, delete, delete-orphan'),
"boostedOnto": relationship(
CommandFit,
primaryjoin=commandFits_table.c.boosterID == fits_table.c.ID,
backref='booster_fit',
collection_class=attribute_mapped_collection('boostedID'),
cascade='all, delete, delete-orphan'),
"boostedOf": relationship(
CommandFit,
primaryjoin=fits_table.c.ID == commandFits_table.c.boostedID,
backref='boosted_fit',
collection_class=attribute_mapped_collection('boosterID'),
cascade='all, delete, delete-orphan'),
}
)
mapper(es_Fit, fits_table,
properties={
"_Fit__modules": relation(
Module,
collection_class=HandledModuleList,
primaryjoin=and_(modules_table.c.fitID == fits_table.c.ID, modules_table.c.projected == False), # noqa
order_by=modules_table.c.position,
cascade='all, delete, delete-orphan'),
"_Fit__projectedModules": relation(
Module,
collection_class=HandledProjectedModList,
cascade='all, delete, delete-orphan',
single_parent=True,
primaryjoin=and_(modules_table.c.fitID == fits_table.c.ID, modules_table.c.projected == True)), # noqa
"owner": relation(
User,
backref="fits"),
"itemID": fits_table.c.shipID,
"shipID": fits_table.c.shipID,
"_Fit__boosters": relation(
Booster,
collection_class=HandledImplantBoosterList,
cascade='all, delete, delete-orphan',
single_parent=True),
"_Fit__drones": relation(
Drone,
collection_class=HandledDroneCargoList,
cascade='all, delete, delete-orphan',
single_parent=True,
primaryjoin=and_(drones_table.c.fitID == fits_table.c.ID, drones_table.c.projected == False)), # noqa
"_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)), # noqa
"_Fit__cargo": relation(
Cargo,
collection_class=HandledDroneCargoList,
cascade='all, delete, delete-orphan',
single_parent=True,
primaryjoin=and_(cargo_table.c.fitID == fits_table.c.ID)),
"_Fit__projectedDrones": relation(
Drone,
collection_class=HandledProjectedDroneList,
cascade='all, delete, delete-orphan',
single_parent=True,
primaryjoin=and_(drones_table.c.fitID == fits_table.c.ID, drones_table.c.projected == True)), # noqa
"_Fit__projectedFighters": relation(
Fighter,
collection_class=HandledProjectedDroneList,
cascade='all, delete, delete-orphan',
single_parent=True,
primaryjoin=and_(fighters_table.c.fitID == fits_table.c.ID, fighters_table.c.projected == True)), # noqa
"_Fit__implants": relation(
Implant,
collection_class=HandledImplantBoosterList,
cascade='all, delete, delete-orphan',
backref='fit',
single_parent=True,
primaryjoin=fitImplants_table.c.fitID == fits_table.c.ID,
secondaryjoin=fitImplants_table.c.implantID == Implant.ID,
secondary=fitImplants_table),
"_Fit__character": relation(
Character,
backref="fits"),
"_Fit__damagePattern": relation(DamagePattern),
"_Fit__targetResists": relation(TargetResists),
"projectedOnto": relationship(
ProjectedFit,
primaryjoin=projectedFits_table.c.sourceID == fits_table.c.ID,
backref='source_fit',
collection_class=attribute_mapped_collection('victimID'),
cascade='all, delete, delete-orphan'),
"victimOf": relationship(
ProjectedFit,
primaryjoin=fits_table.c.ID == projectedFits_table.c.victimID,
backref='victim_fit',
collection_class=attribute_mapped_collection('sourceID'),
cascade='all, delete, delete-orphan'),
"boostedOnto": relationship(
CommandFit,
primaryjoin=commandFits_table.c.boosterID == fits_table.c.ID,
backref='booster_fit',
collection_class=attribute_mapped_collection('boostedID'),
cascade='all, delete, delete-orphan'),
"boostedOf": relationship(
CommandFit,
primaryjoin=fits_table.c.ID == commandFits_table.c.boostedID,
backref='boosted_fit',
collection_class=attribute_mapped_collection('boosterID'),
cascade='all, delete, delete-orphan'),
}
)
mapper(ProjectedFit, projectedFits_table,
properties={
"_ProjectedFit__amount": projectedFits_table.c.amount,
}
)
properties={
"_ProjectedFit__amount": projectedFits_table.c.amount,
}
)
mapper(CommandFit, commandFits_table)
mapper(CommandFit, commandFits_table)

View File

@@ -18,7 +18,8 @@
# ===============================================================================
import eos.db
import eos.types
from eos.saveddata.damagePattern import DamagePattern as es_DamagePattern
from eos.saveddata.targetResists import TargetResists as es_TargetResists
class ImportError(Exception):
@@ -118,7 +119,7 @@ class DefaultDatabaseValues():
name, em, therm, kin, exp = damageProfileRow
damageProfile = eos.db.getDamagePattern(name)
if damageProfile is None:
damageProfile = eos.types.DamagePattern(em, therm, kin, exp)
damageProfile = es_DamagePattern(em, therm, kin, exp)
damageProfile.name = name
eos.db.save(damageProfile)
@@ -180,7 +181,7 @@ class DefaultDatabaseValues():
name, em, therm, kin, exp = targetResistProfileRow
resistsProfile = eos.db.eos.db.getTargetResists(name)
if resistsProfile is None:
resistsProfile = eos.types.TargetResists(em, therm, kin, exp)
resistsProfile = es_TargetResists(em, therm, kin, exp)
resistsProfile.name = name
eos.db.save(resistsProfile)
@@ -192,6 +193,6 @@ class DefaultDatabaseValues():
name, em, therm, kin, exp = damageProfileRow
damageProfile = eos.db.getDamagePattern(name)
if damageProfile is None:
damageProfile = eos.types.DamagePattern(em, therm, kin, exp)
damageProfile = es_DamagePattern(em, therm, kin, exp)
damageProfile.name = name
eos.db.save(damageProfile)

View File

@@ -17,6 +17,10 @@
# along with eos. If not, see <http://www.gnu.org/licenses/>.
# ===============================================================================
from sqlalchemy.sql import and_
from eos.db import saveddata_session, sd_lock
from eos.db.saveddata.fit import projectedFits_table
from eos.db.util import processEager, processWhere
from eos.db import saveddata_session, sd_lock
@@ -32,7 +36,6 @@ if configVal is True:
itemCache = {}
queryCache = {}
def cachedQuery(type, amount, *keywords):
itemCache[type] = localItemCache = weakref.WeakValueDictionary()
queryCache[type] = typeQueryCache = {}
@@ -91,7 +94,6 @@ if configVal is True:
return deco
def removeCachedEntry(type, ID):
if type not in queryCache:
return
@@ -121,7 +123,6 @@ else:
return deco
def removeCachedEntry(*args, **kwargs):
return
@@ -210,6 +211,7 @@ def getFit(lookfor, eager=None):
return fit
def getFitsWithShip(shipID, ownerID=None, where=None, eager=None):
"""
Get all the fits using a certain ship.
@@ -293,6 +295,7 @@ def getFitList(eager=None):
return fits
@cachedQuery(Price, 1, "typeID")
def getPrice(typeID):
if isinstance(typeID, int):
@@ -416,6 +419,7 @@ def searchFits(nameLike, where=None, eager=None):
return fits
def getProjectedFits(fitID):
if isinstance(fitID, int):
with sd_lock:

View File

@@ -21,7 +21,6 @@
import logging
import eos.db
import eos.types
logger = logging.getLogger(__name__)

View File

@@ -8,13 +8,15 @@ logger = logging.getLogger(__name__)
runTime = "late"
type = "active"
def handler(fit, module, context):
damagePattern = fit.damagePattern
# Skip if there is no damage pattern. Example: projected ships or fleet boosters
if damagePattern:
#logger.debug("Damage Pattern: %f/%f/%f/%f", damagePattern.emAmount, damagePattern.thermalAmount, damagePattern.kineticAmount, damagePattern.explosiveAmount)
#logger.debug("Original Armor Resists: %f/%f/%f/%f", fit.ship.getModifiedItemAttr('armorEmDamageResonance'), fit.ship.getModifiedItemAttr('armorThermalDamageResonance'), fit.ship.getModifiedItemAttr('armorKineticDamageResonance'), fit.ship.getModifiedItemAttr('armorExplosiveDamageResonance'))
# logger.debug("Damage Pattern: %f/%f/%f/%f", damagePattern.emAmount, damagePattern.thermalAmount, damagePattern.kineticAmount, damagePattern.explosiveAmount)
# logger.debug("Original Armor Resists: %f/%f/%f/%f", fit.ship.getModifiedItemAttr('armorEmDamageResonance'), fit.ship.getModifiedItemAttr('armorThermalDamageResonance'), fit.ship.getModifiedItemAttr('armorKineticDamageResonance'), fit.ship.getModifiedItemAttr('armorExplosiveDamageResonance'))
# Populate a tuple with the damage profile modified by current armor resists.
baseDamageTaken = (
@@ -23,35 +25,36 @@ def handler(fit, module, context):
damagePattern.kineticAmount * fit.ship.getModifiedItemAttr('armorKineticDamageResonance'),
damagePattern.explosiveAmount * fit.ship.getModifiedItemAttr('armorExplosiveDamageResonance'),
)
#logger.debug("Damage Adjusted for Armor Resists: %f/%f/%f/%f", baseDamageTaken[0], baseDamageTaken[1], baseDamageTaken[2], baseDamageTaken[3])
# logger.debug("Damage Adjusted for Armor Resists: %f/%f/%f/%f", baseDamageTaken[0], baseDamageTaken[1], baseDamageTaken[2], baseDamageTaken[3])
resistanceShiftAmount = module.getModifiedItemAttr('resistanceShiftAmount') / 100 # The attribute is in percent and we want a fraction
resistanceShiftAmount = module.getModifiedItemAttr(
'resistanceShiftAmount') / 100 # The attribute is in percent and we want a fraction
RAHResistance = [
module.getModifiedItemAttr('armorEmDamageResonance'),
module.getModifiedItemAttr('armorThermalDamageResonance'),
module.getModifiedItemAttr('armorKineticDamageResonance'),
module.getModifiedItemAttr('armorEmDamageResonance'),
module.getModifiedItemAttr('armorThermalDamageResonance'),
module.getModifiedItemAttr('armorKineticDamageResonance'),
module.getModifiedItemAttr('armorExplosiveDamageResonance'),
]
# Simulate RAH cycles until the RAH either stops changing or enters a loop.
# The number of iterations is limited to prevent an infinite loop if something goes wrong.
cycleList = []
loopStart = -20
for num in range(50):
#logger.debug("Starting cycle %d.", num)
# logger.debug("Starting cycle %d.", num)
# The strange order is to emulate the ingame sorting when different types have taken the same amount of damage.
# This doesn't take into account stacking penalties. In a few cases fitting a Damage Control causes an inaccurate result.
damagePattern_tuples = [
(0, baseDamageTaken[0] * RAHResistance[0], RAHResistance[0]),
(3, baseDamageTaken[3] * RAHResistance[3], RAHResistance[3]),
(3, baseDamageTaken[3] * RAHResistance[3], RAHResistance[3]),
(2, baseDamageTaken[2] * RAHResistance[2], RAHResistance[2]),
(1, baseDamageTaken[1] * RAHResistance[1], RAHResistance[1]),
]
#logger.debug("Damage taken this cycle: %f/%f/%f/%f", damagePattern_tuples[0][1], damagePattern_tuples[3][1], damagePattern_tuples[2][1], damagePattern_tuples[1][1])
# logger.debug("Damage taken this cycle: %f/%f/%f/%f", damagePattern_tuples[0][1], damagePattern_tuples[3][1], damagePattern_tuples[2][1], damagePattern_tuples[1][1])
# Sort the tuple to drop the highest damage value to the bottom
sortedDamagePattern_tuples = sorted(damagePattern_tuples, key=lambda damagePattern: damagePattern[1])
if sortedDamagePattern_tuples[2][1] == 0:
# One damage type: the top damage type takes from the other three
# Since the resistances not taking damage will end up going to the type taking damage we just do the whole thing at once.
@@ -72,41 +75,47 @@ def handler(fit, module, context):
change1 = min(resistanceShiftAmount, 1 - sortedDamagePattern_tuples[1][2])
change2 = -(change0 + change1) / 2
change3 = -(change0 + change1) / 2
RAHResistance[sortedDamagePattern_tuples[0][0]] = sortedDamagePattern_tuples[0][2] + change0
RAHResistance[sortedDamagePattern_tuples[1][0]] = sortedDamagePattern_tuples[1][2] + change1
RAHResistance[sortedDamagePattern_tuples[2][0]] = sortedDamagePattern_tuples[2][2] + change2
RAHResistance[sortedDamagePattern_tuples[3][0]] = sortedDamagePattern_tuples[3][2] + change3
#logger.debug("Resistances shifted to %f/%f/%f/%f", RAHResistance[0], RAHResistance[1], RAHResistance[2], RAHResistance[3])
# logger.debug("Resistances shifted to %f/%f/%f/%f", RAHResistance[0], RAHResistance[1], RAHResistance[2], RAHResistance[3])
# See if the current RAH profile has been encountered before, indicating a loop.
for i, val in enumerate(cycleList):
tolerance = 1e-06
if abs(RAHResistance[0] - val[0]) <= tolerance and abs(RAHResistance[1] - val[1]) <= tolerance and abs(RAHResistance[2] - val[2]) <= tolerance and abs(RAHResistance[3] - val[3]) <= tolerance:
tolerance = 1e-06
if abs(RAHResistance[0] - val[0]) <= tolerance and \
abs(RAHResistance[1] - val[1]) <= tolerance and \
abs(RAHResistance[2] - val[2]) <= tolerance and \
abs(RAHResistance[3] - val[3]) <= tolerance:
loopStart = i
#logger.debug("Loop found: %d-%d", loopStart, num)
# logger.debug("Loop found: %d-%d", loopStart, num)
break
if loopStart >= 0: break
if loopStart >= 0:
break
cycleList.append(list(RAHResistance))
if loopStart < 0:
logger.error("Reactive Armor Hardener failed to find equilibrium. Damage profile after armor: %f/%f/%f/%f", baseDamageTaken[0], baseDamageTaken[1], baseDamageTaken[2], baseDamageTaken[3])
# Average the profiles in the RAH loop, or the last 20 if it didn't find a loop.
logger.error("Reactive Armor Hardener failed to find equilibrium. Damage profile after armor: %f/%f/%f/%f",
baseDamageTaken[0], baseDamageTaken[1], baseDamageTaken[2], baseDamageTaken[3])
# Average the profiles in the RAH loop, or the last 20 if it didn't find a loop.
loopCycles = cycleList[loopStart:]
numCycles = len(loopCycles)
average = [0, 0, 0, 0]
for cycle in loopCycles:
for i in range(4):
average[i] += cycle[i]
for i in range(4):
average[i] = round(average[i] / numCycles, 3)
# Set the new resistances
#logger.debug("Setting new resist profile: %f/%f/%f/%f", average[0], average[1], average[2],average[3])
for i, attr in enumerate(('armorEmDamageResonance', 'armorThermalDamageResonance', 'armorKineticDamageResonance', 'armorExplosiveDamageResonance')):
# logger.debug("Setting new resist profile: %f/%f/%f/%f", average[0], average[1], average[2],average[3])
for i, attr in enumerate((
'armorEmDamageResonance', 'armorThermalDamageResonance', 'armorKineticDamageResonance',
'armorExplosiveDamageResonance')):
module.increaseItemAttr(attr, average[i] - module.getModifiedItemAttr(attr))
fit.ship.multiplyItemAttr(attr, average[i], stackingPenalties=True, penaltyGroup="preMul")

View File

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

View File

@@ -3,6 +3,9 @@
# Used by:
# Skill: Armored Command
type = "passive"
def handler(fit, src, context):
lvl = src.level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "buffDuration", src.getModifiedItemAttr("durationBonus") * lvl)
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "buffDuration",
src.getModifiedItemAttr("durationBonus") * lvl)

View File

@@ -5,9 +5,16 @@
# Implant: Federation Navy Command Mindlink
# Implant: Imperial Navy Command Mindlink
type = "passive"
def handler(fit, src, context):
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff2Multiplier", src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff1Multiplier", src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff4Multiplier", src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff3Multiplier", src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "buffDuration", src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff2Multiplier",
src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff1Multiplier",
src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff4Multiplier",
src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff3Multiplier",
src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "buffDuration",
src.getModifiedItemAttr("mindlinkBonus"))

View File

@@ -3,9 +3,15 @@
# Used by:
# Skill: Armored Command Specialist
type = "passive"
def handler(fit, src, context):
lvl = src.level
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff1Multiplier", src.getModifiedItemAttr("commandStrengthBonus") * lvl)
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff2Multiplier", src.getModifiedItemAttr("commandStrengthBonus") * lvl)
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff4Multiplier", src.getModifiedItemAttr("commandStrengthBonus") * lvl)
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff3Multiplier", src.getModifiedItemAttr("commandStrengthBonus") * lvl)
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff1Multiplier",
src.getModifiedItemAttr("commandStrengthBonus") * lvl)
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff2Multiplier",
src.getModifiedItemAttr("commandStrengthBonus") * lvl)
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff4Multiplier",
src.getModifiedItemAttr("commandStrengthBonus") * lvl)
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff3Multiplier",
src.getModifiedItemAttr("commandStrengthBonus") * lvl)

View File

@@ -7,5 +7,7 @@ type = "passive"
def handler(fit, ship, context):
for sensorType in ("Gravimetric", "Ladar", "Magnetometric", "Radar"):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Electronic Warfare"), "scan{0}StrengthBonus".format(sensorType),
ship.getModifiedItemAttr("shipBonusCB"), stackingPenalties=True, skill="Caldari Battleship")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Electronic Warfare"),
"scan{0}StrengthBonus".format(sensorType),
ship.getModifiedItemAttr("shipBonusCB"), stackingPenalties=True,
skill="Caldari Battleship")

View File

@@ -5,6 +5,8 @@
# Skill: Leadership
# Skill: Wing Command
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Leadership"),
"maxRange",

View File

@@ -11,5 +11,8 @@
# Ship: Orca
# Ship: Rorqual
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Leadership"), "maxRange", src.getModifiedItemAttr("roleBonusCommandBurstAoERange"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Leadership"), "maxRange",
src.getModifiedItemAttr("roleBonusCommandBurstAoERange"))

View File

@@ -3,6 +3,8 @@
# Used by:
# Skill: Command Burst Specialist
type = "passive"
def handler(fit, src, context):
lvl = src.level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Leadership"),

View File

@@ -3,6 +3,10 @@
# Used by:
# Modules named like: Command Processor I (4 of 4)
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemIncrease(lambda mod: mod.item.requiresSkill("Leadership"), "maxGroupActive", src.getModifiedItemAttr("maxGangModules"))
fit.modules.filteredItemIncrease(lambda mod: mod.item.requiresSkill("Leadership"), "maxGroupOnline", src.getModifiedItemAttr("maxGangModules"))
fit.modules.filteredItemIncrease(lambda mod: mod.item.requiresSkill("Leadership"), "maxGroupActive",
src.getModifiedItemAttr("maxGangModules"))
fit.modules.filteredItemIncrease(lambda mod: mod.item.requiresSkill("Leadership"), "maxGroupOnline",
src.getModifiedItemAttr("maxGangModules"))

View File

@@ -6,6 +6,9 @@
# Ship: Rorqual
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemIncrease(lambda mod: mod.item.requiresSkill("Leadership"), "maxGroupActive", src.getModifiedItemAttr("maxGangModules"))
fit.modules.filteredItemIncrease(lambda mod: mod.item.requiresSkill("Leadership"), "maxGroupOnline", src.getModifiedItemAttr("maxGangModules"))
fit.modules.filteredItemIncrease(lambda mod: mod.item.requiresSkill("Leadership"), "maxGroupActive",
src.getModifiedItemAttr("maxGangModules"))
fit.modules.filteredItemIncrease(lambda mod: mod.item.requiresSkill("Leadership"), "maxGroupOnline",
src.getModifiedItemAttr("maxGangModules"))

View File

@@ -4,9 +4,16 @@
# Ship: Magus
# Ship: Pontifex
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff2Value", src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff3Value", src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "buffDuration", src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff4Value", src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff1Value", src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff2Value",
src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff3Value",
src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "buffDuration",
src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff4Value",
src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff1Value",
src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")

View File

@@ -4,9 +4,16 @@
# Ship: Pontifex
# Ship: Stork
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff1Value", src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff3Value", src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff2Value", src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command"), "buffDuration", src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff4Value", src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff1Value",
src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff3Value",
src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff2Value",
src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command"), "buffDuration",
src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff4Value",
src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")

View File

@@ -4,9 +4,16 @@
# Ship: Bifrost
# Ship: Stork
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff3Value", src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "buffDuration", src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff1Value", src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff4Value", src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff2Value", src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff3Value",
src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "buffDuration",
src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff1Value",
src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff4Value",
src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff2Value",
src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")

View File

@@ -4,9 +4,16 @@
# Ship: Bifrost
# Ship: Magus
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command"), "warfareBuff3Value", src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command"), "buffDuration", src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command"), "warfareBuff1Value", src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command"), "warfareBuff4Value", src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command"), "warfareBuff2Value", src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command"), "warfareBuff3Value",
src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command"), "buffDuration",
src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command"), "warfareBuff1Value",
src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command"), "warfareBuff4Value",
src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command"), "warfareBuff2Value",
src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")

View File

@@ -3,9 +3,16 @@
# Used by:
# Ships from group: Command Ship (4 of 8)
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff3Value", src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff1Value", src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff2Value", src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "buffDuration", src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff4Value", src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff3Value",
src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff1Value",
src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff2Value",
src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "buffDuration",
src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff4Value",
src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")

View File

@@ -3,9 +3,16 @@
# Used by:
# Ships from group: Command Ship (4 of 8)
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command"), "buffDuration", src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff3Value", src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff2Value", src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff1Value", src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff4Value", src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command"), "buffDuration",
src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff3Value",
src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff2Value",
src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff1Value",
src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff4Value",
src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")

View File

@@ -3,9 +3,16 @@
# Used by:
# Ships from group: Command Ship (4 of 8)
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff1Value", src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff4Value", src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff2Value", src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "buffDuration", src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff3Value", src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff1Value",
src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff4Value",
src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff2Value",
src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "buffDuration",
src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff3Value",
src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")

View File

@@ -3,9 +3,16 @@
# Used by:
# Ships from group: Command Ship (4 of 8)
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command"), "warfareBuff2Value", src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command"), "warfareBuff1Value", src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command"), "warfareBuff3Value", src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command"), "warfareBuff4Value", src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command"), "buffDuration", src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command"), "warfareBuff2Value",
src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command"), "warfareBuff1Value",
src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command"), "warfareBuff3Value",
src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command"), "warfareBuff4Value",
src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command"), "buffDuration",
src.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")

View File

@@ -3,7 +3,9 @@
# Used by:
# Ship: Caedes
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name in ("Energy Nosferatu", "Energy Neutralizer"),
"falloffEffectiveness", src.getModifiedItemAttr("eliteBonusCoverOps1"), stackingPenalties=True, skill="Covert Ops")
"falloffEffectiveness", src.getModifiedItemAttr("eliteBonusCoverOps1"),
stackingPenalties=True, skill="Covert Ops")

View File

@@ -3,5 +3,8 @@
# Used by:
# Ship: Rabisu
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "duration", src.getModifiedItemAttr("eliteBonusLogistics3"), skill="Logistics Cruisers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "duration",
src.getModifiedItemAttr("eliteBonusLogistics3"), skill="Logistics Cruisers")

View File

@@ -8,8 +8,8 @@ type = "active", "projected"
def handler(fit, src, context):
if "projected" in context and (
(hasattr(src, "state") and src.state >= State.ACTIVE) or hasattr(src, "amountActive")):
if "projected" in context and ((hasattr(src, "state") and src.state >= State.ACTIVE) or
hasattr(src, "amountActive")):
amount = src.getModifiedItemAttr("energyNeutralizerAmount")
time = src.getModifiedItemAttr("duration")

View File

@@ -8,8 +8,8 @@ type = "active", "projected"
def handler(fit, src, context):
if "projected" in context and (
(hasattr(src, "state") and src.state >= State.ACTIVE) or hasattr(src, "amountActive")):
if "projected" in context and ((hasattr(src, "state") and src.state >= State.ACTIVE) or
hasattr(src, "amountActive")):
amount = src.getModifiedItemAttr("energyNeutralizerAmount")
time = src.getModifiedItemAttr("energyNeutralizerDuration")

View File

@@ -3,7 +3,11 @@
# Used by:
# Skill: Ice Harvesting Drone Specialization
type = "passive"
def handler(fit, src, context):
lvl = src.level
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Ice Harvesting Drone Specialization"), "duration", src.getModifiedItemAttr("rofBonus") * lvl)
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Ice Harvesting Drone Specialization"), "maxVelocity", src.getModifiedItemAttr("maxVelocityBonus") * lvl)
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Ice Harvesting Drone Specialization"), "duration",
src.getModifiedItemAttr("rofBonus") * lvl)
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Ice Harvesting Drone Specialization"),
"maxVelocity", src.getModifiedItemAttr("maxVelocityBonus") * lvl)

View File

@@ -11,8 +11,8 @@
# Ship: Rorqual
type = "passive"
def handler(fit, src, context):
fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Drones"),
"damageMultiplier",
src.getModifiedItemAttr("industrialBonusDroneDamage"))

View File

@@ -3,6 +3,9 @@
# Used by:
# Skill: Information Command
type = "passive"
def handler(fit, src, context):
lvl = src.level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command"), "buffDuration", src.getModifiedItemAttr("durationBonus") * lvl)
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command"), "buffDuration",
src.getModifiedItemAttr("durationBonus") * lvl)

View File

@@ -5,9 +5,16 @@
# Implant: Imperial Navy Command Mindlink
# Implant: Information Command Mindlink
type = "passive"
def handler(fit, src, context):
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff4Multiplier", src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff3Multiplier", src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff1Multiplier", src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff2Multiplier", src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command"), "buffDuration", src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff4Multiplier",
src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff3Multiplier",
src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff1Multiplier",
src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff2Multiplier",
src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command"), "buffDuration",
src.getModifiedItemAttr("mindlinkBonus"))

View File

@@ -3,9 +3,15 @@
# Used by:
# Skill: Information Command Specialist
type = "passive"
def handler(fit, src, context):
lvl = src.level
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff2Multiplier", src.getModifiedItemAttr("commandStrengthBonus") * lvl)
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff1Multiplier", src.getModifiedItemAttr("commandStrengthBonus") * lvl)
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff3Multiplier", src.getModifiedItemAttr("commandStrengthBonus") * lvl)
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff4Multiplier", src.getModifiedItemAttr("commandStrengthBonus") * lvl)
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff2Multiplier",
src.getModifiedItemAttr("commandStrengthBonus") * lvl)
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff1Multiplier",
src.getModifiedItemAttr("commandStrengthBonus") * lvl)
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff3Multiplier",
src.getModifiedItemAttr("commandStrengthBonus") * lvl)
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Information Command"), "warfareBuff4Multiplier",
src.getModifiedItemAttr("commandStrengthBonus") * lvl)

View File

@@ -3,7 +3,11 @@
# Used by:
# Skill: Invulnerability Core Operation
type = "passive"
def handler(fit, src, context):
lvl = src.level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Invulnerability Core Operation"), "buffDuration", src.getModifiedItemAttr("durationBonus") * lvl)
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Invulnerability Core Operation"), "duration", src.getModifiedItemAttr("durationBonus") * lvl)
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Invulnerability Core Operation"), "buffDuration",
src.getModifiedItemAttr("durationBonus") * lvl)
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Invulnerability Core Operation"), "duration",
src.getModifiedItemAttr("durationBonus") * lvl)

View File

@@ -3,7 +3,11 @@
# Used by:
# Skill: Mining Drone Specialization
type = "passive"
def handler(fit, src, context):
lvl = src.level
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Drone Specialization"), "miningAmount", src.getModifiedItemAttr("miningAmountBonus") * lvl)
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Drone Specialization"), "maxVelocity", src.getModifiedItemAttr("maxVelocityBonus") * lvl)
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Drone Specialization"), "miningAmount",
src.getModifiedItemAttr("miningAmountBonus") * lvl)
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Drone Specialization"), "maxVelocity",
src.getModifiedItemAttr("maxVelocityBonus") * lvl)

View File

@@ -3,9 +3,16 @@
# Used by:
# Ships from group: Industrial Command Ship (2 of 2)
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff4Multiplier", src.getModifiedItemAttr("shipBonusICS2"), skill="Industrial Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff1Multiplier", src.getModifiedItemAttr("shipBonusICS2"), skill="Industrial Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "buffDuration", src.getModifiedItemAttr("shipBonusICS2"), skill="Industrial Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff3Multiplier", src.getModifiedItemAttr("shipBonusICS2"), skill="Industrial Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff2Multiplier", src.getModifiedItemAttr("shipBonusICS2"), skill="Industrial Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff4Multiplier",
src.getModifiedItemAttr("shipBonusICS2"), skill="Industrial Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff1Multiplier",
src.getModifiedItemAttr("shipBonusICS2"), skill="Industrial Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "buffDuration",
src.getModifiedItemAttr("shipBonusICS2"), skill="Industrial Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff3Multiplier",
src.getModifiedItemAttr("shipBonusICS2"), skill="Industrial Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff2Multiplier",
src.getModifiedItemAttr("shipBonusICS2"), skill="Industrial Command Ships")

View File

@@ -3,9 +3,16 @@
# Used by:
# Ship: Rorqual
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff1Multiplier", src.getModifiedItemAttr("shipBonusORECapital2"), skill="Capital Industrial Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff2Multiplier", src.getModifiedItemAttr("shipBonusORECapital2"), skill="Capital Industrial Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff4Multiplier", src.getModifiedItemAttr("shipBonusORECapital2"), skill="Capital Industrial Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff3Multiplier", src.getModifiedItemAttr("shipBonusORECapital2"), skill="Capital Industrial Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "buffDuration", src.getModifiedItemAttr("shipBonusORECapital2"), skill="Capital Industrial Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff1Multiplier",
src.getModifiedItemAttr("shipBonusORECapital2"), skill="Capital Industrial Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff2Multiplier",
src.getModifiedItemAttr("shipBonusORECapital2"), skill="Capital Industrial Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff4Multiplier",
src.getModifiedItemAttr("shipBonusORECapital2"), skill="Capital Industrial Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff3Multiplier",
src.getModifiedItemAttr("shipBonusORECapital2"), skill="Capital Industrial Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "buffDuration",
src.getModifiedItemAttr("shipBonusORECapital2"), skill="Capital Industrial Ships")

View File

@@ -3,6 +3,9 @@
# Used by:
# Skill: Mining Foreman
type = "passive"
def handler(fit, src, context):
lvl = src.level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "buffDuration", src.getModifiedItemAttr("durationBonus") * lvl)
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "buffDuration",
src.getModifiedItemAttr("durationBonus") * lvl)

View File

@@ -4,9 +4,16 @@
# Implant: Mining Foreman Mindlink
# Implant: ORE Mining Director Mindlink
type = "passive"
def handler(fit, src, context):
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff4Multiplier", src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff2Multiplier", src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff1Multiplier", src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff3Multiplier", src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "buffDuration", src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff4Multiplier",
src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff2Multiplier",
src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff1Multiplier",
src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff3Multiplier",
src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "buffDuration",
src.getModifiedItemAttr("mindlinkBonus"))

View File

@@ -7,5 +7,6 @@ type = "passive"
def handler(fit, module, context):
module.multiplyItemAttr("specialtyMiningAmount", module.getModifiedChargeAttr("specialisationAsteroidYieldMultiplier"))
#module.multiplyItemAttr("miningAmount", module.getModifiedChargeAttr("specialisationAsteroidYieldMultiplier"))
module.multiplyItemAttr("specialtyMiningAmount",
module.getModifiedChargeAttr("specialisationAsteroidYieldMultiplier"))
# module.multiplyItemAttr("miningAmount", module.getModifiedChargeAttr("specialisationAsteroidYieldMultiplier"))

View File

@@ -4,6 +4,7 @@
# Modules named like: Sharpshooter Mode (4 of 4)
type = "passive"
def handler(fit, module, context):
fit.ship.multiplyItemAttr("weaponDisruptionResistance", 1 / module.getModifiedItemAttr("modeEwarResistancePostDiv"))
fit.ship.multiplyItemAttr("sensorDampenerResistance", 1 / module.getModifiedItemAttr("modeEwarResistancePostDiv"))

View File

@@ -11,4 +11,4 @@ def handler(fit, module, context):
speedBoost = module.getModifiedItemAttr("speedFactor")
mass = fit.ship.getModifiedItemAttr("mass")
thrust = module.getModifiedItemAttr("speedBoostFactor")
fit.ship.boostItemAttr("maxVelocity", speedBoost * thrust / mass)
fit.ship.boostItemAttr("maxVelocity", speedBoost * thrust / mass)

View File

@@ -7,7 +7,8 @@ type = "projected", "active"
def handler(fit, module, context):
if "projected" not in context: return
if "projected" not in context:
return
if module.charge and module.charge.name == "Nanite Repair Paste":
multiplier = 3

View File

@@ -7,7 +7,8 @@ type = "projected", "active"
def handler(fit, module, context):
if "projected" not in context: return
if "projected" not in context:
return
amount = module.getModifiedItemAttr("shieldBonus")
speed = module.getModifiedItemAttr("duration") / 1000.0
fit.extraAttributes.increase("shieldRepair", amount / speed)

View File

@@ -12,4 +12,5 @@ def handler(fit, module, context):
mass = fit.ship.getModifiedItemAttr("mass")
thrust = module.getModifiedItemAttr("speedBoostFactor")
fit.ship.boostItemAttr("maxVelocity", speedBoost * thrust / mass)
fit.ship.boostItemAttr("signatureRadius", module.getModifiedItemAttr("signatureRadiusBonus"), stackingPenalties = True)
fit.ship.boostItemAttr("signatureRadius", module.getModifiedItemAttr("signatureRadiusBonus"),
stackingPenalties=True)

View File

@@ -3,5 +3,8 @@
# Used by:
# Ship: Rabisu
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Energy Nosferatu", "cpu", src.getModifiedItemAttr("nosferatuCpuNeedBonus"))
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Energy Nosferatu", "cpu",
src.getModifiedItemAttr("nosferatuCpuNeedBonus"))

View File

@@ -11,6 +11,7 @@ def handler(fit, module, context):
# Make so that reloads are always taken into account during clculations
module.forceReload = True
if module.charge is None: return
if module.charge is None:
return
capAmount = module.getModifiedChargeAttr("capacitorBonus") or 0
module.itemModifiedAttributes["capacitorNeed"] = -capAmount

View File

@@ -7,7 +7,8 @@ runTime = "late"
def handler(fit, module, context):
if "projected" not in context: return
if "projected" not in context:
return
bonus = module.getModifiedItemAttr("structureDamageAmount")
duration = module.getModifiedItemAttr("duration") / 1000.0
fit.extraAttributes.increase("hullRepair", bonus / duration)

View File

@@ -7,7 +7,8 @@ runTime = "late"
def handler(fit, module, context):
if "projected" not in context: return
if "projected" not in context:
return
bonus = module.getModifiedItemAttr("structureDamageAmount")
duration = module.getModifiedItemAttr("duration") / 1000.0
fit.extraAttributes.increase("hullRepair", bonus / duration)

View File

@@ -6,6 +6,7 @@ type = "active", "projected"
def handler(fit, module, context):
if "projected" not in context: return
if "projected" not in context:
return
fit.ship.boostItemAttr("maxVelocity", module.getModifiedItemAttr("speedFactor"),
stackingPenalties=True, remoteResists=True)

View File

@@ -7,6 +7,7 @@ type = "active", "projected"
def handler(fit, module, context):
if "projected" not in context: return
if "projected" not in context:
return
fit.ship.boostItemAttr("maxVelocity", module.getModifiedItemAttr("speedFactor"),
stackingPenalties=True, remoteResists=True)

View File

@@ -1,8 +1,8 @@
# setBonusAsklepian
#
# Used by:
# Implants named like: Asklepian Omega (3 of 3)
# Implants named like: Grade Asklepian (16 of 16)
# Implants named like: grade Asklepian Omega (2 of 2)
runTime = "early"
type = "passive"

View File

@@ -3,9 +3,16 @@
# Used by:
# Ship: Orca
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff4Multiplier", src.getModifiedItemAttr("shipBonusICS3"), skill="Industrial Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff1Multiplier", src.getModifiedItemAttr("shipBonusICS3"), skill="Industrial Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff2Multiplier", src.getModifiedItemAttr("shipBonusICS3"), skill="Industrial Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff3Multiplier", src.getModifiedItemAttr("shipBonusICS3"), skill="Industrial Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "buffDuration", src.getModifiedItemAttr("shipBonusICS3"), skill="Industrial Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff4Multiplier",
src.getModifiedItemAttr("shipBonusICS3"), skill="Industrial Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff1Multiplier",
src.getModifiedItemAttr("shipBonusICS3"), skill="Industrial Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff2Multiplier",
src.getModifiedItemAttr("shipBonusICS3"), skill="Industrial Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff3Multiplier",
src.getModifiedItemAttr("shipBonusICS3"), skill="Industrial Command Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "buffDuration",
src.getModifiedItemAttr("shipBonusICS3"), skill="Industrial Command Ships")

View File

@@ -3,9 +3,16 @@
# Used by:
# Ship: Rorqual
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff4Multiplier", src.getModifiedItemAttr("shipBonusORECapital3"), skill="Capital Industrial Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "buffDuration", src.getModifiedItemAttr("shipBonusORECapital3"), skill="Capital Industrial Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff1Multiplier", src.getModifiedItemAttr("shipBonusORECapital3"), skill="Capital Industrial Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff3Multiplier", src.getModifiedItemAttr("shipBonusORECapital3"), skill="Capital Industrial Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff2Multiplier", src.getModifiedItemAttr("shipBonusORECapital3"), skill="Capital Industrial Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff4Multiplier",
src.getModifiedItemAttr("shipBonusORECapital3"), skill="Capital Industrial Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "buffDuration",
src.getModifiedItemAttr("shipBonusORECapital3"), skill="Capital Industrial Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff1Multiplier",
src.getModifiedItemAttr("shipBonusORECapital3"), skill="Capital Industrial Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff3Multiplier",
src.getModifiedItemAttr("shipBonusORECapital3"), skill="Capital Industrial Ships")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff2Multiplier",
src.getModifiedItemAttr("shipBonusORECapital3"), skill="Capital Industrial Ships")

View File

@@ -3,6 +3,9 @@
# Used by:
# Skill: Shield Command
type = "passive"
def handler(fit, src, context):
lvl = src.level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "buffDuration", src.getModifiedItemAttr("durationBonus") * lvl)
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "buffDuration",
src.getModifiedItemAttr("durationBonus") * lvl)

View File

@@ -3,9 +3,16 @@
# Used by:
# Implants from group: Cyber Leadership (4 of 10)
type = "passive"
def handler(fit, src, context):
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff4Multiplier", src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff3Multiplier", src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff2Multiplier", src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff1Multiplier", src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "buffDuration", src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff4Multiplier",
src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff3Multiplier",
src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff2Multiplier",
src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff1Multiplier",
src.getModifiedItemAttr("mindlinkBonus"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "buffDuration",
src.getModifiedItemAttr("mindlinkBonus"))

View File

@@ -3,9 +3,15 @@
# Used by:
# Skill: Shield Command Specialist
type = "passive"
def handler(fit, src, context):
lvl = src.level
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff3Multiplier", src.getModifiedItemAttr("commandStrengthBonus") * lvl)
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff1Multiplier", src.getModifiedItemAttr("commandStrengthBonus") * lvl)
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff2Multiplier", src.getModifiedItemAttr("commandStrengthBonus") * lvl)
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff4Multiplier", src.getModifiedItemAttr("commandStrengthBonus") * lvl)
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff3Multiplier",
src.getModifiedItemAttr("commandStrengthBonus") * lvl)
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff1Multiplier",
src.getModifiedItemAttr("commandStrengthBonus") * lvl)
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff2Multiplier",
src.getModifiedItemAttr("commandStrengthBonus") * lvl)
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff4Multiplier",
src.getModifiedItemAttr("commandStrengthBonus") * lvl)

View File

@@ -3,9 +3,21 @@
# Used by:
# Ship: Archon
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command") or mod.item.requiresSkill("Information Command"), "buffDuration", src.getModifiedItemAttr("shipBonusCarrierA4"), skill="Amarr Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command") or mod.item.requiresSkill("Information Command"), "warfareBuff3Value", src.getModifiedItemAttr("shipBonusCarrierA4"), skill="Amarr Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command") or mod.item.requiresSkill("Information Command"), "warfareBuff1Value", src.getModifiedItemAttr("shipBonusCarrierA4"), skill="Amarr Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command") or mod.item.requiresSkill("Information Command"), "warfareBuff4Value", src.getModifiedItemAttr("shipBonusCarrierA4"), skill="Amarr Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command") or mod.item.requiresSkill("Information Command"), "warfareBuff2Value", src.getModifiedItemAttr("shipBonusCarrierA4"), skill="Amarr Carrier")
fit.modules.filteredItemBoost(
lambda mod: mod.item.requiresSkill("Armored Command") or mod.item.requiresSkill("Information Command"),
"buffDuration", src.getModifiedItemAttr("shipBonusCarrierA4"), skill="Amarr Carrier")
fit.modules.filteredItemBoost(
lambda mod: mod.item.requiresSkill("Armored Command") or mod.item.requiresSkill("Information Command"),
"warfareBuff3Value", src.getModifiedItemAttr("shipBonusCarrierA4"), skill="Amarr Carrier")
fit.modules.filteredItemBoost(
lambda mod: mod.item.requiresSkill("Armored Command") or mod.item.requiresSkill("Information Command"),
"warfareBuff1Value", src.getModifiedItemAttr("shipBonusCarrierA4"), skill="Amarr Carrier")
fit.modules.filteredItemBoost(
lambda mod: mod.item.requiresSkill("Armored Command") or mod.item.requiresSkill("Information Command"),
"warfareBuff4Value", src.getModifiedItemAttr("shipBonusCarrierA4"), skill="Amarr Carrier")
fit.modules.filteredItemBoost(
lambda mod: mod.item.requiresSkill("Armored Command") or mod.item.requiresSkill("Information Command"),
"warfareBuff2Value", src.getModifiedItemAttr("shipBonusCarrierA4"), skill="Amarr Carrier")

View File

@@ -3,9 +3,21 @@
# Used by:
# Ship: Chimera
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command") or mod.item.requiresSkill("Information Command"), "warfareBuff2Value", src.getModifiedItemAttr("shipBonusCarrierC4"), skill="Caldari Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command") or mod.item.requiresSkill("Information Command"), "buffDuration", src.getModifiedItemAttr("shipBonusCarrierC4"), skill="Caldari Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command") or mod.item.requiresSkill("Information Command"), "warfareBuff3Value", src.getModifiedItemAttr("shipBonusCarrierC4"), skill="Caldari Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command") or mod.item.requiresSkill("Information Command"), "warfareBuff4Value", src.getModifiedItemAttr("shipBonusCarrierC4"), skill="Caldari Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command") or mod.item.requiresSkill("Information Command"), "warfareBuff1Value", src.getModifiedItemAttr("shipBonusCarrierC4"), skill="Caldari Carrier")
fit.modules.filteredItemBoost(
lambda mod: mod.item.requiresSkill("Shield Command") or mod.item.requiresSkill("Information Command"),
"warfareBuff2Value", src.getModifiedItemAttr("shipBonusCarrierC4"), skill="Caldari Carrier")
fit.modules.filteredItemBoost(
lambda mod: mod.item.requiresSkill("Shield Command") or mod.item.requiresSkill("Information Command"),
"buffDuration", src.getModifiedItemAttr("shipBonusCarrierC4"), skill="Caldari Carrier")
fit.modules.filteredItemBoost(
lambda mod: mod.item.requiresSkill("Shield Command") or mod.item.requiresSkill("Information Command"),
"warfareBuff3Value", src.getModifiedItemAttr("shipBonusCarrierC4"), skill="Caldari Carrier")
fit.modules.filteredItemBoost(
lambda mod: mod.item.requiresSkill("Shield Command") or mod.item.requiresSkill("Information Command"),
"warfareBuff4Value", src.getModifiedItemAttr("shipBonusCarrierC4"), skill="Caldari Carrier")
fit.modules.filteredItemBoost(
lambda mod: mod.item.requiresSkill("Shield Command") or mod.item.requiresSkill("Information Command"),
"warfareBuff1Value", src.getModifiedItemAttr("shipBonusCarrierC4"), skill="Caldari Carrier")

View File

@@ -3,9 +3,21 @@
# Used by:
# Ship: Thanatos
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command") or mod.item.requiresSkill("Armored Command"), "warfareBuff2Value", src.getModifiedItemAttr("shipBonusCarrierG4"), skill="Gallente Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command") or mod.item.requiresSkill("Armored Command"), "warfareBuff3Value", src.getModifiedItemAttr("shipBonusCarrierG4"), skill="Gallente Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command") or mod.item.requiresSkill("Armored Command"), "warfareBuff4Value", src.getModifiedItemAttr("shipBonusCarrierG4"), skill="Gallente Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command") or mod.item.requiresSkill("Armored Command"), "buffDuration", src.getModifiedItemAttr("shipBonusCarrierG4"), skill="Gallente Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command") or mod.item.requiresSkill("Armored Command"), "warfareBuff1Value", src.getModifiedItemAttr("shipBonusCarrierG4"), skill="Gallente Carrier")
fit.modules.filteredItemBoost(
lambda mod: mod.item.requiresSkill("Skirmish Command") or mod.item.requiresSkill("Armored Command"),
"warfareBuff2Value", src.getModifiedItemAttr("shipBonusCarrierG4"), skill="Gallente Carrier")
fit.modules.filteredItemBoost(
lambda mod: mod.item.requiresSkill("Skirmish Command") or mod.item.requiresSkill("Armored Command"),
"warfareBuff3Value", src.getModifiedItemAttr("shipBonusCarrierG4"), skill="Gallente Carrier")
fit.modules.filteredItemBoost(
lambda mod: mod.item.requiresSkill("Skirmish Command") or mod.item.requiresSkill("Armored Command"),
"warfareBuff4Value", src.getModifiedItemAttr("shipBonusCarrierG4"), skill="Gallente Carrier")
fit.modules.filteredItemBoost(
lambda mod: mod.item.requiresSkill("Skirmish Command") or mod.item.requiresSkill("Armored Command"),
"buffDuration", src.getModifiedItemAttr("shipBonusCarrierG4"), skill="Gallente Carrier")
fit.modules.filteredItemBoost(
lambda mod: mod.item.requiresSkill("Skirmish Command") or mod.item.requiresSkill("Armored Command"),
"warfareBuff1Value", src.getModifiedItemAttr("shipBonusCarrierG4"), skill="Gallente Carrier")

View File

@@ -3,9 +3,21 @@
# Used by:
# Ship: Nidhoggur
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command") or mod.item.requiresSkill("Shield Command"), "warfareBuff4Value", src.getModifiedItemAttr("shipBonusCarrierM4"), skill="Minmatar Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command") or mod.item.requiresSkill("Shield Command"), "warfareBuff2Value", src.getModifiedItemAttr("shipBonusCarrierM4"), skill="Minmatar Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command") or mod.item.requiresSkill("Shield Command"), "warfareBuff3Value", src.getModifiedItemAttr("shipBonusCarrierM4"), skill="Minmatar Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command") or mod.item.requiresSkill("Shield Command"), "warfareBuff1Value", src.getModifiedItemAttr("shipBonusCarrierM4"), skill="Minmatar Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Skirmish Command") or mod.item.requiresSkill("Shield Command"), "buffDuration", src.getModifiedItemAttr("shipBonusCarrierM4"), skill="Minmatar Carrier")
fit.modules.filteredItemBoost(
lambda mod: mod.item.requiresSkill("Skirmish Command") or mod.item.requiresSkill("Shield Command"),
"warfareBuff4Value", src.getModifiedItemAttr("shipBonusCarrierM4"), skill="Minmatar Carrier")
fit.modules.filteredItemBoost(
lambda mod: mod.item.requiresSkill("Skirmish Command") or mod.item.requiresSkill("Shield Command"),
"warfareBuff2Value", src.getModifiedItemAttr("shipBonusCarrierM4"), skill="Minmatar Carrier")
fit.modules.filteredItemBoost(
lambda mod: mod.item.requiresSkill("Skirmish Command") or mod.item.requiresSkill("Shield Command"),
"warfareBuff3Value", src.getModifiedItemAttr("shipBonusCarrierM4"), skill="Minmatar Carrier")
fit.modules.filteredItemBoost(
lambda mod: mod.item.requiresSkill("Skirmish Command") or mod.item.requiresSkill("Shield Command"),
"warfareBuff1Value", src.getModifiedItemAttr("shipBonusCarrierM4"), skill="Minmatar Carrier")
fit.modules.filteredItemBoost(
lambda mod: mod.item.requiresSkill("Skirmish Command") or mod.item.requiresSkill("Shield Command"),
"buffDuration", src.getModifiedItemAttr("shipBonusCarrierM4"), skill="Minmatar Carrier")

View File

@@ -3,5 +3,8 @@
# Used by:
# Ship: Rabisu
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Cloaking"), "cpu", src.getModifiedItemAttr("shipBonusMC2"), skill="Minmatar Cruiser")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Cloaking"), "cpu",
src.getModifiedItemAttr("shipBonusMC2"), skill="Minmatar Cruiser")

View File

@@ -3,5 +3,8 @@
# Used by:
# Ship: Caedes
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Cloaking"), "cpu", src.getModifiedItemAttr("shipBonusMF"), skill="Minmatar Frigate")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Cloaking"), "cpu",
src.getModifiedItemAttr("shipBonusMF"), skill="Minmatar Frigate")

View File

@@ -35,4 +35,3 @@ def handler(fit, src, context):
src.getModifiedItemAttr("shipBonusICS4"),
skill="Industrial Command Ships"
)

View File

@@ -35,4 +35,3 @@ def handler(fit, src, context):
src.getModifiedItemAttr("shipBonusORECapital4"),
skill="Capital Industrial Ships"
)

View File

@@ -3,5 +3,8 @@
# Used by:
# Ship: Orca
type = "passive"
def handler(fit, src, context):
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Ice Harvesting Drone Operation"), "duration", src.getModifiedItemAttr("roleBonusDroneIceHarvestingSpeed"))
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Ice Harvesting Drone Operation"), "duration",
src.getModifiedItemAttr("roleBonusDroneIceHarvestingSpeed"))

View File

@@ -3,7 +3,12 @@
# Used by:
# Ship: Rabisu
type = "passive"
def handler(fit, src, context):
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "shieldBonus", src.getModifiedItemAttr("shipBonusMC"), skill="Minmatar Cruiser")
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "structureDamageAmount", src.getModifiedItemAttr("shipBonusMC"), skill="Minmatar Cruiser")
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "armorDamageAmount", src.getModifiedItemAttr("shipBonusMC"), skill="Minmatar Cruiser")
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "shieldBonus",
src.getModifiedItemAttr("shipBonusMC"), skill="Minmatar Cruiser")
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "structureDamageAmount",
src.getModifiedItemAttr("shipBonusMC"), skill="Minmatar Cruiser")
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "armorDamageAmount",
src.getModifiedItemAttr("shipBonusMC"), skill="Minmatar Cruiser")

View File

@@ -3,9 +3,21 @@
# Used by:
# Ship: Minokawa
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command") or mod.item.requiresSkill("Information Command"), "warfareBuff3Value", src.getModifiedItemAttr("shipBonusForceAuxiliaryC4"), skill="Caldari Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command") or mod.item.requiresSkill("Information Command"), "warfareBuff4Value", src.getModifiedItemAttr("shipBonusForceAuxiliaryC4"), skill="Caldari Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command") or mod.item.requiresSkill("Information Command"), "warfareBuff2Value", src.getModifiedItemAttr("shipBonusForceAuxiliaryC4"), skill="Caldari Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command") or mod.item.requiresSkill("Information Command"), "buffDuration", src.getModifiedItemAttr("shipBonusForceAuxiliaryC4"), skill="Caldari Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command") or mod.item.requiresSkill("Information Command"), "warfareBuff1Value", src.getModifiedItemAttr("shipBonusForceAuxiliaryC4"), skill="Caldari Carrier")
fit.modules.filteredItemBoost(
lambda mod: mod.item.requiresSkill("Shield Command") or mod.item.requiresSkill("Information Command"),
"warfareBuff3Value", src.getModifiedItemAttr("shipBonusForceAuxiliaryC4"), skill="Caldari Carrier")
fit.modules.filteredItemBoost(
lambda mod: mod.item.requiresSkill("Shield Command") or mod.item.requiresSkill("Information Command"),
"warfareBuff4Value", src.getModifiedItemAttr("shipBonusForceAuxiliaryC4"), skill="Caldari Carrier")
fit.modules.filteredItemBoost(
lambda mod: mod.item.requiresSkill("Shield Command") or mod.item.requiresSkill("Information Command"),
"warfareBuff2Value", src.getModifiedItemAttr("shipBonusForceAuxiliaryC4"), skill="Caldari Carrier")
fit.modules.filteredItemBoost(
lambda mod: mod.item.requiresSkill("Shield Command") or mod.item.requiresSkill("Information Command"),
"buffDuration", src.getModifiedItemAttr("shipBonusForceAuxiliaryC4"), skill="Caldari Carrier")
fit.modules.filteredItemBoost(
lambda mod: mod.item.requiresSkill("Shield Command") or mod.item.requiresSkill("Information Command"),
"warfareBuff1Value", src.getModifiedItemAttr("shipBonusForceAuxiliaryC4"), skill="Caldari Carrier")

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