Compare commits

...

168 Commits

Author SHA1 Message Date
blitzman
3d8c76209d update database from master 2017-01-29 19:52:56 -05:00
blitzman
c2038a6cf2 Change from UPDATE to DELETE for null damage pattern and target resist names 2017-01-29 19:04:57 -05:00
blitzman
082ac233ad Merge branch 'MissingDamageTargetProfileNames' of https://github.com/Ebag333/Pyfa into development
Conflicts:
	service/prefetch.py
2017-01-29 15:04:56 -05:00
blitzman
5d46fe7e4d Merge branch 'master' into development
Conflicts:
	gui/builtinContextMenus/amount.py
	gui/builtinStatsViews/priceViewFull.py
	service/fit.py
	service/prefetch.py
2017-01-29 15:02:22 -05:00
blitzman
6049c9837c Remove prefetch thread (unneeded and consumes resources?) 2017-01-28 23:35:42 -05:00
blitzman
a76eef01de name all ze threads 2017-01-28 17:46:59 -05:00
blitzman
b3eb4f35cd Max out cargo amount to sys.maxint (#958) 2017-01-28 13:31:03 -05:00
blitzman
6b6dacf94c Fix traceback when trying to cancel an amount dialog with nothing in the field 2017-01-28 13:30:14 -05:00
blitzman
f010f2fef2 Don't loop through all amounts of cargo and drones just to get the price. (#958) 2017-01-28 13:15:25 -05:00
blitzman
a952f80ea4 min version for sqlalchemy 2017-01-28 01:29:08 -05:00
blitzman
6d34ae2960 fix 2017-01-27 23:35:19 -05:00
blitzman
d17ff000c7 Add migration for alpha clone character update 2017-01-27 23:12:08 -05:00
blitzman
6b3d3ecd93 More import fixes for osx deprecated 2017-01-27 22:25:22 -05:00
blitzman
32dc28f48d Move CREST import inside a conditional 2017-01-27 22:17:07 -05:00
blitzman
a210724312 Fix conversion imports for osx deprecated... :( 2017-01-27 22:06:52 -05:00
blitzman
1d69ed7584 Merge branch 'test_import' into development
Conflicts:
	gui/builtinContextMenus/amount.py
	gui/characterEditor.py
	gui/itemStats.py
2017-01-27 20:39:54 -05:00
blitzman
43e864e47b Fix issue in which -s flag was not being honored 2017-01-27 20:36:19 -05:00
blitzman
fb538027f7 Fix issues with paths and linux / os x 2017-01-27 20:30:11 -05:00
blitzman
cbf7f7d320 Merge branch 'master' into development 2017-01-27 19:39:10 -05:00
blitzmann
4111d670a7 Fix possible issue with floats coming through (see #729) 2017-01-26 23:52:18 -05:00
blitzmann
397084a9ff Disable rename and delete button for restricted character on character editor spawn (fix for #930) 2017-01-26 21:33:13 -05:00
blitzmann
968d633d46 Merge branch 'feature/alphaclones' into development 2017-01-26 19:53:27 -05:00
blitzmann
96c3363edc Merge branch 'master' into feature/alphaclones
Conflicts:
	eve.db
2017-01-26 19:39:13 -05:00
Ebag333
a853ed9960 Remove test variable 2017-01-25 18:17:05 -08:00
Ebag333
323a7060ec Fix import 2017-01-25 17:53:04 -08:00
Ebag333
d0fa2510e5 Merge branch 'test_import' of https://github.com/Ebag333/Pyfa into test_import 2017-01-25 17:40:00 -08:00
Ebag333
8d57f641f7 Remove comments about conversion 2017-01-25 17:39:54 -08:00
blitzman
055957567f Fix fit import 2017-01-25 20:28:57 -05:00
blitzman
5aff3f007e Fix crest export 2017-01-25 20:22:07 -05:00
blitzman
c34d86ba80 Fix XML exports 2017-01-25 20:12:30 -05:00
Ebag333
2038f36254 Remove calls to null pattern name cleanup 2017-01-25 13:52:00 -08:00
Ebag333
b1fc07a4cf Abstract out the SQL Query Execution
gives more granular error handling
2017-01-25 13:28:34 -08:00
Ebag333
a366420d65 Catch scenario where names are missing 2017-01-25 09:58:26 -08:00
Ebag333
8095b4852b Clean up another broken reference. Fix broken XML export. 2017-01-24 21:34:24 -08:00
Ebag333
cc3274f245 Add comment to note special snowflakes needs 2017-01-24 18:21:09 -08:00
Ebag333
fbde9ce7bf Fix passing the fit into exportXML 2017-01-24 18:13:57 -08:00
Ebag333
130fc189ad Merge branch 'test_import' of https://github.com/Ebag333/Pyfa into test_import 2017-01-24 17:37:42 -08:00
Ebag333
a50e4fcc46 Fix issue caused by file path and import fix merges 2017-01-24 17:37:37 -08:00
Ebag333
ae96ff244e Fix crest exports 2017-01-24 17:09:48 -08:00
blitzman
1b0cdeedce Fix lack of instance 2017-01-24 19:57:16 -05:00
Ebag333
992820ac42 Redirect to correct module
Function was moved from service.Fit to service.Port
2017-01-24 16:48:28 -08:00
blitzman
c0ecc6a329 tweaks to fix merge issues 2017-01-23 21:07:20 -05:00
blitzman
85131e6166 oh god this isn't gonna work
Merge branch 'ebag_importchanges' into test_import

Conflicts:
	config.py
	eos/db/saveddata/queries.py
	eos/effects/chargebonuswarfarecharge.py
	eos/effects/elitebonuscommandshipinformationhiddencs3.py
	eos/effects/elitebonuslogisticremotearmorrepairoptimalfalloff1.py
	eos/effects/energydestabilizationnew.py
	eos/effects/iceharvestingdroneoperationdurationbonus.py
	eos/effects/miningforemanstrengthbonus.py
	eos/effects/modulebonuswarfarelinkarmor.py
	eos/effects/modulebonuswarfarelinkinfo.py
	eos/effects/modulebonuswarfarelinkmining.py
	eos/effects/modulebonuswarfarelinkshield.py
	eos/effects/modulebonuswarfarelinkskirmish.py
	eos/effects/moduletitaneffectgenerator.py
	eos/effects/remotehullrepair.py
	eos/effects/rolebonusremotearmorrepairoptimalfalloff.py
	eos/effects/shipbonusforceauxiliarya4warfarelinksbonus.py
	eos/effects/shipmodesmallmissiledamagepostdiv.py
	eos/effects/structureenergyneutralizerfalloff.py
	eos/effects/structuremoduleeffectstasiswebifier.py
	eos/effects/structurerigmaxtargets.py
	eos/effects/subsystembonusamarrdefensiveinformationwarfarehidden.py
	eos/effects/subsystembonuscaldaridefensiveinformationwarfarehidden.py
	eos/effects/subsystembonusgallentedefensiveinformationwarfarehidden.py
	eos/effects/techtwocommandburstbonus.py
	eos/saveddata/fighter.py
	eos/saveddata/fit.py
	eos/saveddata/module.py
	eve.db
	gui/bitmapLoader.py
	gui/builtinContextMenus/itemStats.py
	gui/builtinStatsViews/miningyieldViewFull.py
	gui/builtinViewColumns/misc.py
	gui/builtinViews/__init__.py
	gui/builtinViews/fittingView.py
	gui/contextMenu.py
	gui/graphFrame.py
	gui/itemStats.py
	gui/mainFrame.py
	gui/marketBrowser.py
	service/__init__.py
	service/character.py
	service/fit.py
	service/port.py
	service/prefetch.py
	service/pycrest/eve.py
	service/settings.py
2017-01-23 21:06:12 -05:00
blitzman
330983d9dd Merge branch 'master' into development
Conflicts:
	eve.db
2017-01-22 21:10:06 -05:00
Ryan Holmes
1bb7c4e825 Merge pull request #945 from Ebag333/Patch_1111328
Update database to 1111328
2017-01-17 20:39:32 -05:00
Ryan Holmes
450e1427a1 Merge pull request #948 from Ebag333/MiningYield
Revert back to /s for mining. Adds /hour to tooltips.
2017-01-17 20:21:15 -05:00
blitzman
5614cec19d Merge branch 'master' of https://github.com/pyfa-org/Pyfa 2017-01-17 20:18:21 -05:00
blitzman
3f24a4b2c5 Fix for #946 - citadel rig not increasing max targets 2017-01-17 20:18:12 -05:00
Ebag333
4e9e5735dc Revert "Add check for remote resistance"
This reverts commit 269565e959.
2017-01-17 10:03:14 -08:00
Ebag333
b1a6189c55 Revert back to /s for mining. Adds /hour to tooltips. 2017-01-17 09:29:22 -08:00
Ebag333
836504ee01 Expand gitattributes to cover a few more scenarios 2017-01-17 08:53:01 -08:00
Ebag333
269565e959 Add check for remote resistance 2017-01-17 00:28:44 -08:00
Ryan Holmes
e45027a66c Merge pull request #910 from Ebag333/UnicodePaths_v2
Unicode Paths 2: The Reckoning
2017-01-14 02:44:24 -05:00
Ebag333
2d3310d8e0 Update database to 1111328 2017-01-13 15:10:36 -08:00
Ryan Holmes
77066f0389 Fix Rabisu effects (#941) 2017-01-11 15:06:50 -05:00
blitzman
5e0567ef4d Merge branch 'master' of https://github.com/pyfa-org/Pyfa 2017-01-10 22:51:38 -05:00
blitzman
b49de4b0fa Update to 1108313 2017-01-10 22:51:27 -05:00
blitzman
372495a83a Remove vestigial appendage 2017-01-10 22:45:41 -05:00
blitzman
468a4644d6 Merge branch 'development'
Conflicts:
	eos/db/saveddata/queries.py
2017-01-10 22:42:01 -05:00
Ryan Holmes
29d0f102fd Move AT14 ships to the Limited Edition group (#935) 2017-01-05 11:38:47 -05:00
blitzman
ebc7173c50 Fix issues with unexpected module positions (see #932) 2017-01-04 23:48:37 -05:00
blitzman
43f1ac78a6 Keep subsystem module in the same position when swapping them out (see #932) 2017-01-04 23:17:56 -05:00
Ryan Holmes
d489fdd700 Merge pull request #913 from resinneublem/remember-user-filters-take2
Remembers user's meta filtering choices
2017-01-04 00:10:48 -05:00
blitzman
d6b1e4465e Merge branch 'test/cat-has-fits' 2017-01-03 01:32:50 -05:00
blitzman
5cbffcf3ac Handle counting number of fits per ship category more efficiently (see #819) 2017-01-03 01:32:12 -05:00
blitzman
c91723516e Do not calculate projected fits for command fits (see #931) 2017-01-02 23:54:06 -05:00
Ryan Holmes
a68f45d15a Merge pull request #927 from Ebag333/BurstProjectors
ECM Burst Projectors effect
2017-01-02 19:58:10 -05:00
Ryan Holmes
152a708ee8 Merge pull request #920 from Ebag333/Database_Cleanup
Database Validation and Cleanup
2017-01-02 19:25:26 -05:00
blitzman
a0ec13d2ed More tweaks 2017-01-02 18:45:08 -05:00
Ebag333
3313b7421f Move query logic into own function in queries. Tighten up flow in DB repair. Catch null values. 2017-01-02 13:41:39 -08:00
blitzman
a76ee6b2fc more tweaks 2017-01-02 12:07:15 -05:00
Ebag333
0056b704d4 Add other projector effects. Only allow it to affect the specific attribute it's modifying. 2017-01-02 03:18:54 -08:00
Ebag333
c1ead5fe27 change method for retreiving count 2017-01-02 00:29:44 -08:00
blitzman
85a89339a7 Cleaned up database corruption stuff 2017-01-02 00:58:54 -05:00
Ryan Holmes
55f82c48bc Merge pull request #929 from Ebag333/Character_Import_Sanitization
Add some sanity checks and validation of imported character data
2017-01-02 00:38:48 -05:00
Ebag333
f4761e099b Don't let people rename built in chars 2017-01-01 13:17:39 -08:00
Ebag333
be3696deba Add some sanity checks and validation of incoming data 2017-01-01 12:47:28 -08:00
Ebag333
cd41e9e9be Change to use skill rather than group, and modify correct attribute 2017-01-01 03:08:38 -08:00
Resin Neublem
d6db30b7fc We weren't setting user selection in all branches
I heavily refactored the button click handler to make it a little easier to understand
2016-12-28 19:54:37 -05:00
Ryan Holmes
fd066c2150 Merge branch 'Ebag333-EFTBoosterImports' into development 2016-12-28 17:46:33 -05:00
Ebag333
f9ba95b3de Check the ness to see if it's an implant, booster, or something else.
Log it if it's something else and don't try and import it. This prevents
a bad line from failing the entire import, and (hopefully) we know about
it.
2016-12-27 12:32:52 -08:00
Ebag333
7ee4d1d588 Try loading item as a booster if implant fails. 2016-12-26 23:29:22 -08:00
Ebag333
cef5842344 Database validation and cleanup 2016-12-26 21:54:52 -08:00
Resin Neublem
a7b6647135 Remembers user's meta filtering choices
There is a lot of logic that overwrites the user's choices of meta
filtering on every search.

That's a little too clever. Especially if the user is looking for
different variations of a certain meta.

If a user wants to include the other meta buttons they can re-add them
after filtering.

Extra care has to be taken with Windows. If a button is Enabled=False AND
SetValue=True, then it looks like it's Enabled=True, but clicking it
doesn't do anything. So we handle that logic in it's own class

closes: https://github.com/pyfa-org/Pyfa/issues/818
2016-12-19 22:39:56 -05:00
Ebag333
bef17e53c6 Recreating wheels 2016-12-19 00:11:55 -08:00
Ebag333
d4b6099d6e Handle unicode, utf8, and windows-1252
(cherry picked from commit 0d4f24a)
2016-12-18 14:11:55 -08:00
blitzman
ff60538e21 Revert "Merge branch 'Ebag333-UnicodePaths' into development"
This reverts commit 8a6ef788b3, reversing
changes made to cf91ae7627.
2016-12-18 15:56:06 -05:00
Ryan Holmes
50c6133046 Revert "Remembers user's meta filtering choices" 2016-12-18 10:09:55 -05:00
Ryan Holmes
b7d7b80544 Merge pull request #829 from resinneublem/remember-user-filters
Remembers user's meta filtering choices
2016-12-18 10:07:15 -05:00
blitzman
2b9342692d working commit 2016-12-18 09:45:26 -05:00
blitzman
a24e247f1b Merge branch 'master' into development
Conflicts:
	eos/effects/usemissiles.py
	eos/saveddata/fit.py
2016-12-18 09:24:39 -05:00
blitzman
3396056dae bump dev 2016-12-18 09:19:47 -05:00
Ebag333
af7272cd10 fix dual reference back to same object 2016-12-15 17:08:59 -08:00
Ebag333
d7c71f5d47 fix some, missed import references. 2016-12-15 16:17:10 -08:00
Ebag333
c858fc2859 Remove an inline import. Fix a reference that is missing. 2016-12-15 15:39:19 -08:00
Ebag333
f76f44e9f3 Fix port references, imports, and add some logging 2016-12-15 15:20:29 -08:00
Ebag333
4fb07cc1d0 Bunch of pep8 and inspection cleanup 2016-12-15 12:43:19 -08:00
Ebag333
658a87cbc0 Single line change to fix most (all??) of the problems 2016-12-15 12:10:03 -08:00
Ebag333
956fa7a8b7 Fixing some issues due to import cleanup 2016-12-14 13:06:13 -08:00
blitzman
0ebb992354 more clean up
(cherry picked from commit f198ff1)
2016-12-14 12:44:42 -08:00
blitzman
37f8253836 oops
(cherry picked from commit 0a28fb6)
2016-12-14 12:26:22 -08:00
blitzman
200ff5a1a4 Fix titan command effects
(cherry picked from commit 7875c2a)
2016-12-14 12:26:08 -08:00
blitzman
0d44cbf74a clean up path stuff
(cherry picked from commit d3e360b)
2016-12-14 12:24:35 -08:00
Stefan Dresselhaus
bb216aa6ed wrong index in tuple.
Array looks normally so:

(RunTime, Value, etc., etc.)
("normal", -10, ..., ...)

I guess "RunTime" got added and this is an artifact as it is rarely
called.

Fixes Orca-Mining-Boost onto itself and other ships.

(cherry picked from commit 0ba88d0)
2016-12-14 12:22:41 -08:00
Stefan Dresselhaus
eccf405ba8 fixed parameters in call when adding neuts to structures.
(cherry picked from commit 4f77dff)
2016-12-14 12:22:28 -08:00
blitzman
9df87f61cd bump dev
(cherry picked from commit 2b3e646)
2016-12-14 12:22:17 -08:00
blitzman
4186e19c65 bump stable
(cherry picked from commit e0e7478)
2016-12-14 12:22:10 -08:00
blitzman
57edc32a4b Clean up new tactical mode stats stuff
(cherry picked from commit c9bc234)
2016-12-14 12:21:00 -08:00
blitzman
9cfa0748ac fix for #871
(cherry picked from commit 70af2b0)
2016-12-14 12:20:42 -08:00
blitzman
df859a2132 Fix for #883
(cherry picked from commit 753b5c5)
2016-12-14 12:19:54 -08:00
blitzman
52257d60ac fix a couple command effects
(cherry picked from commit 9bb86b4)
2016-12-14 12:18:46 -08:00
blitzman
96ddb0bbff Fixed a few issues with command bursts
(cherry picked from commit 9071960)
2016-12-14 12:18:41 -08:00
Ebag333
b529a28715 Implement fittingMode
(cherry picked from commit 5eb2fef)
2016-12-14 12:18:34 -08:00
Ebag333
ea3a374ced Add logging, because why not
(cherry picked from commit 9403a1f)
2016-12-14 12:17:55 -08:00
Ebag333
2eacadf08f Don't use try for fittingView, and don't show remove item for modes.
(cherry picked from commit fd224d6)
2016-12-14 12:17:13 -08:00
Ebag333
1a127bb1a6 Add ability to look at tactical mode item info.
(cherry picked from commit f5776a0)
2016-12-14 12:16:51 -08:00
Ebag333
edfa130939 Fix tooltip order
(cherry picked from commit 61d1878)
2016-12-14 12:15:09 -08:00
blitzman
7fbd89392a Revert "Remove effect files that are not used by any item"
This reverts commit b29fa2467a.

(cherry picked from commit 4a95156)
2016-12-14 12:14:39 -08:00
Indiction
9f4b31979c Adding Fighter Support CREST
(cherry picked from commit ab5f348)
2016-12-14 12:14:11 -08:00
blitzman
9ecfc475e3 Bump dev, fix for #874
(cherry picked from commit b375d3c)
2016-12-14 12:13:55 -08:00
blitzman
84dc93ac54 bump release
(cherry picked from commit f160aed)
2016-12-14 12:13:02 -08:00
Ebag333
7532bcda08 Clean up some stuff left over from cherry picks 2016-12-14 10:42:04 -08:00
Ebag333
08b5abc7ad Handle unicode, utf8, and windows-1252
(cherry picked from commit 0d4f24a)
2016-12-14 10:38:56 -08:00
Indiction
38bf143704 Fighters for export and import functions
(cherry picked from commit 04c30e7)
2016-12-14 10:24:45 -08:00
Ebag333
a440ed3b37 Drop unicode
(cherry picked from commit 7fe7056)
2016-12-14 10:20:57 -08:00
Ebag333
39b7d9fdeb Change to shorthand unicode
(cherry picked from commit ab32a3a)
2016-12-14 10:20:53 -08:00
Ebag333
dfa728a486 Handle Lockbreaker, Void, and Focused Void Bombs
(cherry picked from commit ea3e5e2)
2016-12-14 10:20:48 -08:00
Ebag333
7bd8ca5a55 Removed actual fleet files. Cleaned up __init__.py that had references.
(cherry picked from commit b6c5183)
2016-12-14 10:20:20 -08:00
Ebag333
627977ab51 Purging fleet bonuses from code base
(cherry picked from commit 68f4570)
2016-12-14 10:18:19 -08:00
Ebag333
e3b592977a Make some imports more explicit 2016-12-13 23:49:37 -08:00
Ebag333
622a734405 remove lazy import. Fix test 2016-12-13 23:35:29 -08:00
Ebag333
28404cd8bb bajillion pep8 fixes to pass tox 2016-12-13 23:31:39 -08:00
Ebag333
be53dedb18 Large pep8 compliance to make work for Tox 2016-12-13 21:23:01 -08:00
Ebag333
b2a5a20650 Travis and CodeCov files 2016-12-13 20:37:52 -08:00
Ebag333
57f930c83e Cherry pick commits from @a-tal 2016-12-13 20:35:03 -08:00
a-tal
b4dd65cf3e dont use built-in function format as a var name
(cherry picked from commit 74dd6cf)
2016-12-13 20:19:27 -08:00
a-tal
4a9b1df9b4 pep8 fixes
(cherry picked from commit 5dc43b2)
2016-12-13 20:18:57 -08:00
a-tal
874bfb3305 missed a type
(cherry picked from commit f416c77)
2016-12-13 20:18:04 -08:00
a-tal
ab9c925c47 non-standard - use forces coding declarations
(cherry picked from commit 6e17d88)
2016-12-13 20:17:56 -08:00
a-tal
d3b6bc1c93 so many pep8 fixes
(cherry picked from commit bee125d)
2016-12-13 20:16:44 -08:00
Ryan Holmes
180de97893 Merge pull request #738 from Ebag333/Remove-Command-Boosts
Purging fleet bonuses from code base
2016-12-12 00:54:06 -05:00
blitzman
f198ff1773 more clean up 2016-12-12 00:49:47 -05:00
blitzman
55c13d1ad0 Merge branch 'master' into Ebag333-Remove-Command-Boosts 2016-12-12 00:43:52 -05:00
blitzman
16505b30bf working commit 2016-12-12 00:43:42 -05:00
blitzman
95b3f0a21c Merge branch 'Remove-Command-Boosts' of https://github.com/Ebag333/Pyfa into Ebag333-Remove-Command-Boosts
Conflicts:
	eos/db/saveddata/fleet.py
	eos/db/saveddata/queries.py
	gui/additionsPane.py
2016-12-12 00:41:47 -05:00
blitzman
49bf40484d Merge branch 'Ebag333-VoidBombs' into development 2016-12-11 23:27:40 -05:00
blitzman
07148f1e7f Merge branch 'VoidBombs' of https://github.com/Ebag333/Pyfa into Ebag333-VoidBombs
Conflicts:
	eos/effects/usemissiles.py
2016-12-11 23:27:30 -05:00
blitzman
8a6ef788b3 Merge branch 'Ebag333-UnicodePaths' into development 2016-12-11 23:06:23 -05:00
blitzman
d3e360b7c0 clean up path stuff 2016-12-11 23:03:09 -05:00
blitzman
b1bba74c5a Merge branch 'UnicodePaths' of https://github.com/Ebag333/Pyfa into Ebag333-UnicodePaths 2016-12-11 23:01:08 -05:00
blitzman
a954759012 GUI implementation of alpha clone switching 2016-12-11 22:51:48 -05:00
blitzman
90c1033437 add clone grades to the client extraction list 2016-12-11 20:27:27 -05:00
blitzman
191a065de1 Get skill limits working 2016-12-11 20:26:30 -05:00
blitzman
b6420b9a4b Get alpha clones in the database 2016-12-11 15:44:14 -05:00
Ebag333
510492e5e9 More refactoring, elimited another recursive import 2016-12-03 17:12:16 -08:00
Ebag333
6ef57e735e Missed imports. Fixed now. 2016-12-03 06:21:52 -08:00
Ebag333
ea8a4c01cb Eliminate export calling fit.py (no need)
Except for 1 (clipboardXML), same number of lines of code in mainFrame,
lots of code gone from fit, and no more complicated.  Also spotted an
import reference that got missed.
2016-12-02 12:50:49 -08:00
Ebag333
d963327ed4 Make it run again 2016-12-02 03:13:54 -08:00
Ebag333
0d4f24ade9 Handle unicode, utf8, and windows-1252 2016-11-26 22:57:53 -08:00
Resin Neublem
cfa57a70dc Remembers user's meta filtering choices
There is a lot of logic that overwrites the user's choices of meta filtering on every search.

That's a little too clever. Especially if the user is looking for different variations of a certain meta.

If a user wants to include the other meta buttons they can re-add them after filtering.

closes: https://github.com/pyfa-org/Pyfa/issues/818
2016-11-20 16:28:18 -05:00
Ebag333
7fe7056c12 Drop unicode 2016-11-07 12:18:36 -08:00
Ebag333
ab32a3afb0 Change to shorthand unicode 2016-11-07 12:09:20 -08:00
Ebag333
ea3e5e273f Handle Lockbreaker, Void, and Focused Void Bombs 2016-11-07 10:27:51 -08:00
Ebag333
b6c5183d40 Removed actual fleet files. Cleaned up __init__.py that had references. 2016-11-06 16:38:21 -08:00
Ebag333
e5d65b97ce Merged changes from Pyfa.org\Master to branch 2016-11-06 16:33:28 -08:00
Ebag333
c30190f63e Revert "Revert "Purging fleet bonuses from code base""
This reverts commit 6e54d6788c.
2016-09-15 15:27:30 -07:00
Ebag333
6e54d6788c Revert "Purging fleet bonuses from code base"
This reverts commit 68f45706ab.
2016-09-15 15:27:10 -07:00
Ebag333
68f45706ab Purging fleet bonuses from code base 2016-09-15 15:07:59 -07:00
309 changed files with 8916 additions and 9127 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`

108
config.py
View File

@@ -18,8 +18,8 @@ debug = False
saveInRoot = False
# Version data
version = "1.26.0"
tag = "Stable"
version = "1.26.1"
tag = "git"
expansionName = "YC118.10"
expansionVersion = "1.2"
evemonMinVersion = "4081"
@@ -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

@@ -8,7 +8,6 @@ __all__ = [
"booster",
"drone",
"implant",
"fleet",
"damagePattern",
"miscData",
"targetResists",

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

@@ -0,0 +1,162 @@
# ===============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
#
# pyfa is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# pyfa 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
# ===============================================================================
import sqlalchemy
import logging
logger = logging.getLogger(__name__)
class DatabaseCleanup:
def __init__(self):
pass
@staticmethod
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
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 results is None:
return
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
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)
if results is None:
return
row = results.first()
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.
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 results is None:
return
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

@@ -1,65 +0,0 @@
# ===============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of eos.
#
# eos is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# eos is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with eos. If not, see <http://www.gnu.org/licenses/>.
# ===============================================================================
from sqlalchemy import Table, Column, Integer, ForeignKey, String
from sqlalchemy.orm import mapper, relation
from eos.db import saveddata_meta
from eos.db.saveddata.fit import fits_table
from eos.types import Fleet, Wing, Squad, Fit
gangs_table = Table("gangs", saveddata_meta,
Column("ID", Integer, primary_key=True),
Column("leaderID", ForeignKey("fits.ID")),
Column("boosterID", ForeignKey("fits.ID")),
Column("name", String))
wings_table = Table("wings", saveddata_meta,
Column("ID", Integer, primary_key=True),
Column("gangID", ForeignKey("gangs.ID")),
Column("boosterID", ForeignKey("fits.ID")),
Column("leaderID", ForeignKey("fits.ID")))
squads_table = Table("squads", saveddata_meta,
Column("ID", Integer, primary_key=True),
Column("wingID", ForeignKey("wings.ID")),
Column("leaderID", ForeignKey("fits.ID")),
Column("boosterID", ForeignKey("fits.ID")))
squadmembers_table = Table("squadmembers", saveddata_meta,
Column("squadID", ForeignKey("squads.ID"), primary_key=True),
Column("memberID", ForeignKey("fits.ID"), primary_key=True))
mapper(Fleet, gangs_table,
properties={"wings": relation(Wing, backref="gang"),
"leader": relation(Fit, primaryjoin=gangs_table.c.leaderID == fits_table.c.ID),
"booster": relation(Fit, primaryjoin=gangs_table.c.boosterID == fits_table.c.ID)})
mapper(Wing, wings_table,
properties={"squads": relation(Squad, backref="wing"),
"leader": relation(Fit, primaryjoin=wings_table.c.leaderID == fits_table.c.ID),
"booster": relation(Fit, primaryjoin=wings_table.c.boosterID == fits_table.c.ID)})
mapper(Squad, squads_table,
properties={"leader": relation(Fit, primaryjoin=squads_table.c.leaderID == fits_table.c.ID),
"booster": relation(Fit, primaryjoin=squads_table.c.boosterID == fits_table.c.ID),
"members": relation(Fit,
primaryjoin=squads_table.c.ID == squadmembers_table.c.squadID,
secondaryjoin=squadmembers_table.c.memberID == fits_table.c.ID,
secondary=squadmembers_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

@@ -21,10 +21,12 @@ from sqlalchemy.sql import and_
from eos.db import saveddata_session, sd_lock
from eos.db.saveddata.fit import projectedFits_table
from eos.db.saveddata.fleet import squadmembers_table
from eos.db.util import processEager, processWhere
from eos.types import *
from eos.db import saveddata_session, sd_lock
from eos.types import *
from eos.db.saveddata.fit import projectedFits_table
from sqlalchemy.sql import and_
import eos.config
configVal = getattr(eos.config, "saveddataCache", None)
@@ -34,7 +36,6 @@ if configVal is True:
itemCache = {}
queryCache = {}
def cachedQuery(type, amount, *keywords):
itemCache[type] = localItemCache = weakref.WeakValueDictionary()
queryCache[type] = typeQueryCache = {}
@@ -93,7 +94,6 @@ if configVal is True:
return deco
def removeCachedEntry(type, ID):
if type not in queryCache:
return
@@ -123,7 +123,6 @@ else:
return deco
def removeCachedEntry(*args, **kwargs):
return
@@ -213,51 +212,6 @@ def getFit(lookfor, eager=None):
return fit
@cachedQuery(Fleet, 1, "fleetID")
def getFleet(fleetID, eager=None):
if isinstance(fleetID, int):
if eager is None:
with sd_lock:
fleet = saveddata_session.query(Fleet).get(fleetID)
else:
eager = processEager(eager)
with sd_lock:
fleet = saveddata_session.query(Fleet).options(*eager).filter(Fleet.ID == fleetID).first()
else:
raise TypeError("Need integer as argument")
return fleet
@cachedQuery(Wing, 1, "wingID")
def getWing(wingID, eager=None):
if isinstance(wingID, int):
if eager is None:
with sd_lock:
wing = saveddata_session.query(Wing).get(wingID)
else:
eager = processEager(eager)
with sd_lock:
wing = saveddata_session.query(Wing).options(*eager).filter(Wing.ID == wingID).first()
else:
raise TypeError("Need integer as argument")
return wing
@cachedQuery(Squad, 1, "squadID")
def getSquad(squadID, eager=None):
if isinstance(squadID, int):
if eager is None:
with sd_lock:
squad = saveddata_session.query(Squad).get(squadID)
else:
eager = processEager(eager)
with sd_lock:
squad = saveddata_session.query(Squad).options(*eager).filter(Fleet.ID == squadID).first()
else:
raise TypeError("Need integer as argument")
return squad
def getFitsWithShip(shipID, ownerID=None, where=None, eager=None):
"""
Get all the fits using a certain ship.
@@ -306,24 +260,31 @@ def countAllFits():
return count
def countFitsWithShip(shipID, ownerID=None, where=None, eager=None):
def countFitsWithShip(lookfor, ownerID=None, where=None, eager=None):
"""
Get all the fits using a certain ship.
If no user is passed, do this for all users.
"""
if isinstance(shipID, int):
if ownerID is not None and not isinstance(ownerID, int):
raise TypeError("OwnerID must be integer")
filter = Fit.shipID == shipID
if ownerID is not None:
filter = and_(filter, Fit.ownerID == ownerID)
if ownerID is not None and not isinstance(ownerID, int):
raise TypeError("OwnerID must be integer")
filter = processWhere(filter, where)
eager = processEager(eager)
with sd_lock:
count = saveddata_session.query(Fit).options(*eager).filter(filter).count()
if isinstance(lookfor, int):
filter = Fit.shipID == lookfor
elif isinstance(lookfor, list):
if len(lookfor) == 0:
return 0
filter = Fit.shipID.in_(lookfor)
else:
raise TypeError("ShipID must be integer")
raise TypeError("You must supply either an integer or ShipID must be integer")
if ownerID is not None:
filter = and_(filter, Fit.ownerID == ownerID)
filter = processWhere(filter, where)
eager = processEager(eager)
with sd_lock:
count = saveddata_session.query(Fit).options(*eager).filter(filter).count()
return count
@@ -335,13 +296,6 @@ def getFitList(eager=None):
return fits
def getFleetList(eager=None):
eager = processEager(eager)
with sd_lock:
fleets = saveddata_session.query(Fleet).options(*eager).all()
return fleets
@cachedQuery(Price, 1, "typeID")
def getPrice(typeID):
if isinstance(typeID, int):
@@ -466,17 +420,6 @@ def searchFits(nameLike, where=None, eager=None):
return fits
def getSquadsIDsWithFitID(fitID):
if isinstance(fitID, int):
with sd_lock:
squads = saveddata_session.query(squadmembers_table.c.squadID).filter(
squadmembers_table.c.memberID == fitID).all()
squads = tuple(entry[0] for entry in squads)
return squads
else:
raise TypeError("Need integer as argument")
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__)
@@ -172,10 +171,11 @@ class HandledModuleList(HandledList):
self[index] = mod
def freeSlot(self, slot):
for i in range(len(self) - 1, -1, -1):
for i in range(len(self)):
mod = self[i]
if mod.getModifiedItemAttr("subSystemSlot") == slot:
del self[i]
self.toDummy(i)
break
class HandledDroneCargoList(HandledList):

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

@@ -4,5 +4,5 @@
# Ship: Rabisu
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "falloffEffectiveness", src.getModifiedItemAttr("eliteBonusLogistics1"), stackingPenalties=True, skill="Logistics Cruisers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "maxRange", src.getModifiedItemAttr("eliteBonusLogistics1"), stackingPenalties=True, skill="Logistics Cruisers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "falloffEffectiveness", src.getModifiedItemAttr("eliteBonusLogistics1"), skill="Logistics Cruisers")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "maxRange", src.getModifiedItemAttr("eliteBonusLogistics1"), 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

@@ -4,5 +4,5 @@
# Ship: Rabisu
type = "passive"
def handler(fit, src, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "falloffEffectiveness", src.getModifiedItemAttr("roleBonusRepairRange"), stackingPenalties=True)
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "maxRange", src.getModifiedItemAttr("roleBonusRepairRange"), stackingPenalties=True)
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "falloffEffectiveness", src.getModifiedItemAttr("roleBonusRepairRange"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "maxRange", src.getModifiedItemAttr("roleBonusRepairRange"))

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"
)

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