Compare commits

..

247 Commits

Author SHA1 Message Date
DarkPhoenix
4e890e1e1d Update database to tq version and bump version in config 2015-09-29 22:28:49 +03:00
DarkPhoenix
473b70944f Merge branch 'singularity' 2015-09-29 22:25:36 +03:00
blitzmann
37b158439d Fix #359 2015-09-28 20:32:55 -04:00
blitzmann
2617143330 Fix #363 2015-09-27 18:16:54 -04:00
blitzmann
e07c162453 Reduce confusion with number of cycles vs charges 2015-09-26 19:17:22 -04:00
blitzmann
c751544560 Do not show level change menu for All 5/0 in char editor 2015-09-25 12:56:40 -04:00
blitzmann
1d51e86c1c Added individual skill save to context menu 2015-09-25 12:16:11 -04:00
blitzmann
05b9d1e607 Fixed some bugs, added character action buttons on editor 2015-09-25 12:13:17 -04:00
blitzmann
2a88e3114b Skill color goes back to normal when saving/reverting skill. 2015-09-25 11:15:08 -04:00
blitzmann
a0f9fb6ad6 Enable/disable edit menu options, and add color to character editor to show which skills are edited 2015-09-24 22:11:31 -04:00
blitzmann
b844bdf986 Add save character as dialog 2015-09-24 20:46:07 -04:00
blitzmann
61614553a2 Fix bug with char copy, and added char revert and save as (unfinished) 2015-09-24 19:03:30 -04:00
blitzmann
ae870f9535 Merge branch 'newTempChar' 2015-09-24 17:16:14 -04:00
blitzmann
30a8437515 Fix returning unicode with __repr__ and __str__. Fixes #356 2015-09-24 14:15:54 -04:00
blitzmann
8647fa245f Fix Jump Drive Economizer. It does not project, and is only applies bonus when online. 2015-09-24 13:09:43 -04:00
blitzmann
23bb763c51 Fix system effects to respect their state 2015-09-24 13:09:25 -04:00
DarkPhoenix
51c481206c Bump version to make preview build 2015-09-24 01:15:56 +03:00
DarkPhoenix
7b6b922c57 Update database to 965413 and implement BC changes 2015-09-24 01:08:20 +03:00
blitzmann
a08bb2494b Fix system effect states 2015-09-22 21:45:32 -04:00
blitzmann
3ea4439b8d Allow changing all 5 and 0 from editor 2015-09-18 11:59:52 -04:00
blitzmann
bd53785667 Allow all 5 and 0 to change skills from affecting skill menu 2015-09-14 20:35:36 -04:00
blitzmann
f2b4400834 Do auto-save when editing in character editor. 2015-09-14 20:30:12 -04:00
blitzmann
b8d01d5ecb Fix a few things 2015-09-13 16:59:59 -04:00
blitzmann
9ae5cfbab2 Revert "Fix API stuff. This should theoretically work, but it's untested."
This reverts commit 1402ceec63.
2015-09-13 16:57:22 -04:00
blitzmann
045031e8ae Revert "Fix character rename, delete, and copy."
This reverts commit c72f049ccd.

Conflicts:
	service/character.py
2015-09-13 16:55:32 -04:00
blitzmann
2c7bfd14b6 Revert "Separate characters from Fit relationship..."
This reverts commit 3521b3887d.

Conflicts:
	eos/db/saveddata/queries.py
2015-09-13 16:53:42 -04:00
blitzmann
1584586fd2 Try a different approach to temp skill levels 2015-09-13 16:51:36 -04:00
blitzmann
1402ceec63 Fix API stuff. This should theoretically work, but it's untested. 2015-09-12 13:15:59 -04:00
blitzmann
4663270067 Since we now have a list of skills by default on our character, remove the iterSkills iterator which helped fetch skills that were not previously loaded 2015-09-12 11:06:21 -04:00
blitzmann
0b9cdaa944 Change the way skills are loaded. We now load all skills when character is created, instead of just creating character and loading skills on demand. This fixes a bug in which new characters were not saving their skills to the database. 2015-09-12 10:59:44 -04:00
blitzmann
89c011d37e Minor modifications. 2015-09-12 10:30:51 -04:00
blitzmann
c72f049ccd Fix character rename, delete, and copy. 2015-09-09 23:12:59 -04:00
blitzmann
ca34217f3b Added character saving.
Deleting characters is broken for now due to using wrong session, but I believe creating character works. Further tests needed
2015-09-09 20:33:15 -04:00
blitzmann
3521b3887d Separate characters from Fit relationship and create new character session. At this point, changes to characters do not persist. Efforts must still be made to focus on creating a character save function as well as ensure characters that are dirty are loaded correctly for fresh fits. 2015-09-09 19:08:38 -04:00
blitzmann
492776c5a8 Fix Scram effect to turn off MWDs. Fixes #70 2015-09-06 11:06:52 -04:00
blitzmann
51a8076d30 Comment cleanup 2015-09-01 23:29:47 -04:00
blitzmann
decf7ff028 Fix #351 2015-09-01 23:23:52 -04:00
DarkPhoenix
31b1c94c0f Add AT13 prize ships 2015-09-01 01:26:30 +03:00
DarkPhoenix
a9fc457510 Bump dev version 2015-09-01 00:09:10 +03:00
blitzmann
6dbed1403a Bump stable 2015-08-27 21:50:13 -04:00
blitzmann
aa5eb7ac92 Update DB, force Imp and Fiend as not published again (will publish these when they are live) 2015-08-27 21:49:06 -04:00
blitzmann
e0fbcc91f1 Update effect headers 2015-08-25 17:47:15 -04:00
blitzmann
b2dce223b0 Add AT13 prizes 2015-08-25 17:42:34 -04:00
blitzmann
4b7b22025c Add new drifter incursion effect 2015-08-25 17:39:57 -04:00
blitzmann
8e37dab37e Disallow assistance with active Estonis link 2015-08-25 17:37:17 -04:00
blitzmann
6e95f69565 Support speedLimit introduced with Entosis Link 2015-08-25 17:26:25 -04:00
blitzmann
31331b1e34 Update to 957210 - Galatea 1.0 2015-08-25 17:25:12 -04:00
blitzmann
05b3777ad2 Add build directory to ignore file. 2015-08-25 16:06:38 -04:00
blitzmann
cda8dd4c8b Windows skel has an issue with this, so if there is an issue, use default path to cache file. 2015-08-21 19:04:42 -04:00
blitzmann
cbedf03026 Another fix to prep_data. I'll get this right one day 2015-08-21 12:08:57 -04:00
blitzmann
a69589dd23 Merge pull request #346 from Will-W/master
Context menu to swap modules for different variation
2015-08-18 13:08:15 -04:00
Will Wykeham
2904ab6afa Non-windows platform fix for variations menu 2015-08-18 15:59:02 +01:00
Will Wykeham
c763595cc4 Remove debug print statement 2015-08-17 15:41:58 +01:00
Will Wykeham
8fe97180ed Sort higher metalevel items properly in variations menu 2015-08-16 21:56:39 +01:00
Will Wykeham
6a4b2ffe69 Make variations menu handle multiple selections
Ensure the variations menu only shows when you've got
a matching set of items selected.
2015-08-16 21:45:20 +01:00
Will Wykeham
7f100353e2 Make variations menu actually swap out module
Functional, but not handling multiple selections well
2015-08-16 18:30:27 +01:00
Will Wykeham
97ac0804c5 Add Submenu of variations of module type.
Non functional so far.
2015-08-15 19:35:31 +01:00
DarkPhoenix
598512a904 Fix stacking penalties on active tank effects 2015-08-13 02:21:24 +03:00
DarkPhoenix
121a81ce70 Remove few debugging prints 2015-08-11 15:59:38 +03:00
blitzmann
a2e031cf27 Fix prep_data script so that it actually works 2015-08-09 23:20:00 -04:00
DarkPhoenix
f18ba6160a Do 2 blank lines between cargo contents and the rest of the fit, and when exported with the implants - do cargo items after the implants 2015-08-08 13:36:16 +03:00
blitzmann
ab7bbcb6ef Remove matplotlib's font cache. Fixes #234 2015-08-04 22:18:28 -04:00
blitzmann
cc59612fa4 Debug logging when flag is set 2015-07-23 16:58:55 -04:00
Ryan Holmes
01db1efdf7 Merge pull request #336 from blitzmann/regSkills
Register skills when applying ship bonuses
2015-07-23 15:58:07 -04:00
blitzmann
e74e2615ad Merge remote-tracking branch 'origin/projections' 2015-07-23 15:46:32 -04:00
blitzmann
2f246d0897 Add context menu to affected by list 2015-07-23 15:32:27 -04:00
DarkPhoenix
505b0ce38f Clear info dicts in-place instead of replacing them with new ones
Sometimes it can cause fuckups, so who knows how PIL works with them...
2015-07-23 20:34:02 +03:00
DarkPhoenix
8c19a956e0 Strip ICC color profile data
Fixes #337
2015-07-23 20:32:40 +03:00
blitzmann
9de3600d7f Fix self-boosting 2015-07-23 01:38:51 -04:00
blitzmann
5a4f526b2b Fix fit copying 2015-07-22 14:27:44 -04:00
blitzmann
cd0b0eada0 Fix graphing 2015-07-22 13:12:57 -04:00
blitzmann
17733d5951 Added missing tactical mode calculations... whoops 2015-07-22 13:02:08 -04:00
blitzmann
0a1f324053 Fix Advanced Spaceship Command skill and resists for Occator 2015-07-21 12:27:46 -04:00
blitzmann
b32f76cfde Show affecting skills for charges as well 2015-07-19 16:39:07 -04:00
blitzmann
182104a010 Fix #109 2015-07-19 16:20:42 -04:00
blitzmann
90c883da67 Fix some syntax errors. 2015-07-19 15:51:03 -04:00
blitzmann
ac08b1b264 Add check for current skill level 2015-07-19 15:16:29 -04:00
blitzmann
f17d015ebe Fix having multiple skills in skill list (happens when multiple attributes are modified) 2015-07-19 15:02:50 -04:00
blitzmann
d496637614 Add ship skill bonuses to modified modules. Modify effect files for new skill parameter. Enable affecting skill menu. 2015-07-19 14:19:24 -04:00
blitzmann
4596c526a2 Fix #335 - properly represent charge modifiers 2015-07-18 23:39:16 -04:00
blitzmann
9941b6c74b Make default view module again 2015-07-18 15:23:10 -04:00
blitzmann
b06ce24d4a Fix attribute view items (two of the same item would merge into one, even if they had different modifiers. now simply list them individually) 2015-07-18 15:20:15 -04:00
blitzmann
2f8c201ab3 Add attribute view 2015-07-18 14:45:26 -04:00
blitzmann
d184820728 Fix toggle attribute names. Previous way assumed no other trees apart from first child and siblings. Not true now with projected fit trees. Instead of attempting to walk the tree, we simply store the items in a list that we later iterate over. Much easier 2015-07-17 18:28:31 -04:00
blitzmann
40aeb1ed4a Move active fir to init, fixes bug when refreshing with another active fit 2015-07-17 16:33:07 -04:00
blitzmann
71b258a8f5 Merge fit attributes with ship 2015-07-17 16:32:42 -04:00
blitzmann
cd7579a4bf Fix #332 - offline rigs calculated in calibration stats 2015-07-17 00:01:31 -04:00
blitzmann
d6199a58c2 Separate projected fits from list of affectors. Also, show when affected module is projected. Still need to clean up affector tree stuff 2015-07-16 23:59:37 -04:00
blitzmann
3ad5aaac89 Fix #331 - gang boosts not applied to self projection 2015-07-15 16:52:09 -04:00
blitzmann
3bed268d81 Fix use case for downgrading and adding a row with NULL 2015-07-14 19:13:56 -04:00
blitzmann
9a1b0f07c0 Added documentation on why projections don't respect the __calculated flag which gang boosts do 2015-07-14 16:32:10 -04:00
blitzmann
f591ecba10 Fix use case where gang boosts were not being applied when projections were added/removed. 2015-07-14 16:15:52 -04:00
blitzmann
c571fdc5e6 Fit fit alterations with self projections 2015-07-13 19:29:23 -04:00
DarkPhoenix
6f944fc7db Stacking penalize missile flight time rigs 2015-07-12 02:12:59 +03:00
blitzmann
63fce4be17 Handle self projections by creating a copy of the fit. Due to the way effects are calculated, we would have double effects implemented if not for the copy 2015-07-11 16:28:09 -04:00
blitzmann
86ee5292d8 Fix fit copying and deleting fits not being reflected in other fits. 2015-07-11 12:43:47 -04:00
blitzmann
0060f58e3d Support evemon character imports. 2015-07-11 10:17:02 -04:00
blitzmann
23b458534f Remove unneeded collection class for projected fits 2015-07-10 23:22:58 -04:00
blitzmann
2256efacb0 Do migration stuff for projected fits 2015-07-10 16:40:00 -04:00
blitzmann
28a5318e3b Merge branch 'master' into toggleProjectionFit
Conflicts:
	config.py
2015-07-10 16:09:00 -04:00
blitzmann
609ee13cd6 Redirect stderr and stdout to logger when we are frozen. Need to test this. 2015-07-10 15:58:45 -04:00
blitzmann
4216904736 Remove function to remove projected fits correctly. This is now handled by proper DB relationships 2015-07-10 15:46:42 -04:00
blitzmann
496e9b56b5 Handle use case of invalid fit's mucking things up 2015-07-10 15:46:15 -04:00
blitzmann
b8f73a7c94 bump dev 2015-07-10 12:58:03 -04:00
blitzmann
b4604f8207 Bump Stable... maybe it will be this time 2015-07-10 12:17:14 -04:00
blitzmann
68dddf2810 Fix for init projected fit. Took a long time to figure out what was happening. 2015-07-10 11:58:15 -04:00
blitzmann
4c17f38b1a Fix for #324 - do not reset itemID automatically upon removal due to way modules are swapped. 2015-07-09 18:36:11 -04:00
blitzmann
221a3fde14 Being extra cautious 2015-07-09 18:18:36 -04:00
blitzmann
c17e03d8d0 Fixes critical design issue when it comes to projected fits. Disabled some of the more advanced functionality (projection amount and active) to cope to development. Crash still happens occasionally when adding projected fit for unknown reasons - not 100% reproducable yet 2015-07-09 17:53:41 -04:00
blitzmann
af9f64db5f Move the chain into the runtime loop, otherwise projections won't work for some odd reason. 2015-07-09 14:48:15 -04:00
blitzmann
1f82465a65 Return None for price column on ship modes, fixes #322 2015-07-09 12:13:13 -04:00
blitzmann
d885bd4636 Bump dev and Fix #321 - oversight in tactical mode selection 2015-07-09 11:48:11 -04:00
blitzmann
c17bce55bb Lots of stuff
- Added logging and replaced Timer class with more useful one
- Move projected fit loop out of runtimes
- Eliminate recursions from Fit.clear()
- Clean up overall fit calc logic
2015-07-09 10:43:39 -04:00
blitzmann
4137a7cda9 Bump stable 2015-07-08 11:20:18 -04:00
blitzmann
c92911b79a Work around for lack of flag_modified() support 2015-07-08 10:54:26 -04:00
DarkPhoenix
adc9fb6d00 Don't call function multiple times after first unconditional call 2015-07-08 17:45:25 +03:00
Ryan Holmes
5baf70694a Merge pull request #318 from poettler-ric/fix-logging
Fix logging
2015-07-08 10:14:46 -04:00
Richard Poettler
f08dc97576 logging crashes if the directory doesn't exist 2015-07-08 10:47:25 +02:00
Richard Poettler
35094ae1ce moved dublicate code into one method 2015-07-08 10:45:37 +02:00
DarkPhoenix
5ac31920ee Fix #317
Crop images to square form before making thumbnail, not square images cause issues on Windows
2015-07-08 11:39:01 +03:00
DarkPhoenix
e63c3541c4 Bump for next development release 2015-07-08 00:09:34 +03:00
DarkPhoenix
4976516d4d Bump for a stable version 2015-07-07 23:36:03 +03:00
Ryan Holmes
e042a21d32 Merge pull request #315 from lunedis/resistmultiplier
Showing Resist Multiplier in Tooltip
2015-07-07 14:42:50 -04:00
Kalu
8a22907940 newline in resist multiplier tooltip and explanation 2015-07-07 20:38:27 +02:00
Kalu
a97847e644 show rr factor in tooltip 2015-07-07 20:38:16 +02:00
blitzmann
23309a5da6 Remove unneeded code that created a bitmap for checkboxes 2015-07-07 13:49:40 -04:00
blitzmann
06e4a7e80f Support changing amount of projected fits 2015-07-07 13:49:39 -04:00
blitzmann
b95a10d284 Add active column. Looping the fit to apply it x amount of times doesn't seem to work. Probably because it's been flagged calculated and returns early 2015-07-07 13:49:38 -04:00
blitzmann
2bca3ddcc8 GUI support (also made regular checkboxes pretty for drones/implant/etc) 2015-07-07 13:49:37 -04:00
blitzmann
9ef182aa99 First working prototype of toggleable projected fits. Creates a new association object that stores projection-specific information. GUI hasn't been touched (need to show state), and there are a lot of variables that I need to rename. 2015-07-07 13:49:35 -04:00
blitzmann
5e56107582 Revert changes to minimum / default sizes of splitter windows 2015-07-07 13:28:02 -04:00
DarkPhoenix
972c08e7e4 Remove AT13 prizes from ship list for now 2015-07-07 16:10:29 +03:00
DarkPhoenix
091832af21 Fix bug in script and add missing icons 2015-07-07 16:09:13 +03:00
DarkPhoenix
16d1891e16 Add script which updates renders and update them using aegis release export 2015-07-07 16:05:44 +03:00
DarkPhoenix
40ee68e2cf Update module/attribute icons 2015-07-07 15:11:55 +03:00
DarkPhoenix
bfe3b4a26d Add new entosis offline mass penalty 2015-07-07 15:10:37 +03:00
DarkPhoenix
9aa1332b15 Update database to 912410 2015-07-07 15:07:39 +03:00
DarkPhoenix
0521d242eb Make sure bitmap loader searches for proper file (w/o EVE embedfs-specific path and extension) 2015-07-06 11:31:02 +03:00
DarkPhoenix
2b3f3773e5 Merge branch 'master' into singularity 2015-07-06 01:39:50 +03:00
DarkPhoenix
4041407878 Also make sure to process icons for categories and attributes 2015-07-06 01:38:51 +03:00
blitzmann
1b5e0467fc Save browser sizes 2015-07-05 13:59:18 -04:00
DarkPhoenix
a7c346f78e Add script which is supposed to update icons 2015-07-05 20:59:15 +03:00
blitzmann
3cc51aaf89 Change logging location to ~/.pyfa and set default level to WARN 2015-07-05 13:15:26 -04:00
Ryan Holmes
a339ae1c55 Merge pull request #312 from blitzmann/dbCorruption
Fixes for database rot
2015-07-05 13:08:11 -04:00
blitzmann
3773d1c28e Improvements to fit initializations and logging 2015-07-05 12:57:04 -04:00
blitzmann
41b8db346f Fix broken drone drag 2015-07-05 01:16:53 -04:00
blitzmann
7959593c6c Improve object initialization and add support for logging the errors. 2015-07-05 00:31:52 -04:00
blitzmann
aaa60cbc14 Fix instance where some items were being re-added due to lack of return. Also, implement some basic logging. 2015-07-05 00:28:55 -04:00
DarkPhoenix
8ae5a96047 Merge branch 'master' into singularity 2015-07-04 12:45:15 +03:00
blitzmann
8c90b3132b Use lunedis's method and apply it to additions pane, cleans up code 2015-07-04 01:38:11 -04:00
blitzmann
1326e21f6b Fix IndexError when selecting module index that doesn't exist. Also, tweaked setting the selItem variable. 2015-07-04 01:27:57 -04:00
blitzmann
bfdc2161e0 Add shortcut cues as toggle in prefs 2015-07-04 00:52:44 -04:00
blitzmann
9ab79af70c Show shortcut values in market list 2015-07-04 00:44:19 -04:00
Ryan Holmes
f0de2000bf Merge pull request #313 from lunedis/quickfit
Quickly fitting modules using ALT+1-9
2015-07-04 00:34:43 -04:00
blitzmann
5991d19b3e Allow Subsystems as modules. 2015-07-04 00:32:28 -04:00
Kalu
51fed996f1 refactor quickfit shortcuts with list 2015-07-03 23:43:04 +02:00
Kalu
f6bbc6c410 Implemented using Alt+1-5 for quickly fitting modules, see issue #183 2015-07-03 23:42:54 +02:00
blitzmann
3de6b63325 Fix oversight when creating a new database 2015-07-03 14:18:11 -04:00
blitzmann
dd48815f30 Offline rigs, closes #100 2015-07-03 14:05:57 -04:00
DarkPhoenix
5608676dc8 Merge branch 'master' into singularity 2015-07-03 12:37:08 +03:00
DarkPhoenix
86ab1f7444 Ignore python pyc files and rely on index within file rather than just on amount of files 2015-07-03 12:36:17 +03:00
DarkPhoenix
8f51642f70 Merge branch 'master' into singularity 2015-07-03 12:13:53 +03:00
blitzmann
de71123a48 Merge branch 'pricing' 2015-07-03 02:38:23 -04:00
blitzmann
874cf4ef0a Use old price information if update fails. Add "(!)" to show that price is out of date 2015-07-03 02:37:52 -04:00
blitzmann
87e5929cb1 DB migration is triggered by number of upgrade files found, rather than number in config.py. This allows us to remove the db version variable in config.py and not worry about it. 2015-07-02 19:35:53 -04:00
blitzmann
84b1e0ac41 Migrate boosters table to new schema that drops the UNIQUE constraint (causes issues and is unneeded) 2015-07-02 19:34:02 -04:00
blitzmann
539360d5f6 Remove old debug print 2015-07-02 15:04:07 -04:00
blitzmann
ca08f8d8da Handle fits with invalid ships by removing and deleting them when loaded. 2015-07-02 15:03:56 -04:00
blitzmann
e1ce672569 Move flag_modified to HandledList.remove() so that it takes care of all our use cases. Give fits an itemID like everything else so that projected fits can be removed correctly by this logic. No reason for them to be special snowflakes. 2015-07-02 11:22:26 -04:00
blitzmann
717080b58c Handle invalid implants and boosters. Uses a different method to ensure implant and booster slot is not duplicated. Still need to modify existing databases to remove Booster table constraint. Reverts a previous commit: "Gracefully handle invalid boosters in database (both itemIDs that don't exist as well as non-booster items). Implants need a little more work" (aaa5a6ae18) 2015-07-02 00:48:32 -04:00
blitzmann
51696c509f Merged Cargo and Drone collection class (essentially the same). Utilized SQLAlchemy's flag_modified() to force SA to update DB (in this case, remove the entry) 2015-07-01 20:54:40 -04:00
blitzmann
4a5ae9f6f1 Handle invalid cargo. Noticed that cargo nor drones are removed from the database with these methods. Not sure why - projected drones and modules are correctly removed in similar ways 2015-07-01 15:21:27 -04:00
blitzmann
fa9f324f78 Handle invalid drones 2015-07-01 14:55:05 -04:00
blitzmann
bcc77f11cd Handle invalid projected drones 2015-07-01 14:50:08 -04:00
blitzmann
f737f292e3 Refine appending projected modules. Ensure that module can actually be projected, and also ensure that we only have 1 system effect running at a time. Invalid modules are removed at earliest opportunity as we are later accessing attributes that may not be there for corrupted data. 2015-07-01 13:34:19 -04:00
blitzmann
1c18a5207c System Effects are wrapped in Module class, even though they are not modules. Account for this. 2015-07-01 13:32:31 -04:00
blitzmann
fa2b1e3821 Handle invalid modules. This streamlines the module init code from both program and database sources. When loading from the database, we ensure that the module item is actually an item. If not, we set a flag to delete it (which is picked up by the collection class)(can't use exceptions as there's no place to catch them) 2015-07-01 02:20:56 -04:00
DarkPhoenix
6184753822 Merge branch 'master' into singularity 2015-06-30 21:16:15 +03:00
DarkPhoenix
91a9c860ea Merge branch 'singularity' of github.com:DarkFenX/Pyfa into singularity 2015-06-30 21:15:10 +03:00
DarkPhoenix
0730ac369f Update data to 910808 2015-06-30 21:14:22 +03:00
blitzmann
aaa5a6ae18 Gracefully handle invalid boosters in database (both itemIDs that don't exist as well as non-booster items). Implants need a little more work 2015-06-30 13:51:49 -04:00
blitzmann
646f3afd27 Fixed oversights 2015-06-27 19:32:21 -04:00
blitzmann
98815f2b85 Fix #307 by moving menu code to spawn event 2015-06-27 18:18:43 -04:00
Ryan Holmes
95eb5a6117 Update README.md
Added note for Linux users and wxPython 2.8
2015-06-25 21:45:06 -04:00
blitzmann
dc035469ed Fix background color for certain panels under Linux 2015-06-25 16:09:56 -04:00
DarkPhoenix
ec4a00cdfc Merge branch 'master' into singularity 2015-06-25 12:12:33 +03:00
blitzmann
21937c02ff Made it look nicer 2015-06-24 19:53:55 -04:00
DarkPhoenix
edfd446e46 Update to 908326 2015-06-25 00:33:37 +03:00
blitzmann
7ec78b941e Add help text for why api is disabled, per #269. I may or may not make it look nicer later 2015-06-24 15:10:37 -04:00
blitzmann
95bf1039c0 Fix #291 - Triage not properly implemented on projected fit 2015-06-24 14:36:31 -04:00
blitzmann
e6def6f5f9 Fix #299 - fit not recalculated after module states change upon module append 2015-06-24 00:40:13 -04:00
DarkPhoenix
de0b03630a Bump version 2015-06-23 00:17:41 +03:00
DarkPhoenix
90a2a79d5b Add hecate effects, update database to 906843 2015-06-23 00:00:09 +03:00
DarkPhoenix
21efd6d06a CCP added faction 200mm plates back to the game 2015-06-22 22:22:35 +03:00
DarkPhoenix
ea288a6133 Update conversion scripts to use new scheme 2015-06-21 16:50:07 +03:00
blitzmann
23baaa7dba Merge branch 'master' of https://github.com/DarkFenX/Pyfa 2015-06-16 13:14:28 -04:00
blitzmann
8008c986d3 Fix #302 - Projected fit applying Tactical Destroyer mode effects on projectee 2015-06-16 13:14:16 -04:00
DarkPhoenix
b9efc919ea Add missing RHML rof effect 2015-06-16 16:53:21 +03:00
blitzmann
6cc6fd9468 Instead of icon, use unicode refresh. Minor issues with image and GUI flickering 2015-06-06 22:42:42 -05:00
blitzmann
53c9169043 Simplified price pane. Will show pricing update label and will only clear it when prices are done. Removed all timer code as it makes it overly complicated and I suspect half of it didn't work as intended anyway 2015-06-05 15:39:10 -05:00
blitzmann
9e96aac04d Fix situation in which module prices are fetched individually (which the price column). Instead, have them wait in a queue that is processed when the entire fit is called and calculated (with the price pane). Also adds a little refresh icon to know that prices are updating and it's not just blank (might change) 2015-06-04 14:10:27 -05:00
DarkPhoenix
3395f8ebe6 Bump for next development release 2015-06-02 23:43:16 +03:00
DarkPhoenix
1d45102100 Bump for a stable release 2015-06-02 23:32:16 +03:00
DarkPhoenix
1694d74afa Add Carnyx tiericide module upgrade/import paths 2015-06-02 23:27:08 +03:00
DarkPhoenix
9c9f1dcefa Get faction 200mm plates back 2015-06-02 19:37:32 +03:00
DarkPhoenix
a4ca2e90f9 Add effect which affects entosis duration on cap ships 2015-06-02 16:48:58 +03:00
DarkPhoenix
dbfcfd9acf Change expansion data in config and update database to 893722 2015-06-02 16:38:38 +03:00
DarkPhoenix
8c30ee3fd3 Merge branch 'master' into singularity 2015-05-28 15:21:28 +03:00
Anton Vorobyov
ca17d17232 Merge pull request #292 from wolfwood/master
fix issue copying fits with sqlalchemy 1.0
2015-05-28 15:17:02 +03:00
wolfwood
b78c0a5845 fix issue copying fits with sqlalchemy 1.0 2015-05-27 10:21:16 -07:00
DarkPhoenix
ef6e25bfce Merge branch 'master' into singularity 2015-05-27 14:55:12 +03:00
DarkPhoenix
e81f7eb765 Change validator requirement for owner ID
This fixes bug related to sqlalch 1.0
2015-05-27 14:54:37 +03:00
DarkPhoenix
26122f6da7 Add latest changes from Singularity 2015-05-21 16:44:39 +03:00
DarkPhoenix
cca7f1112a Revert "Merge branch 'master' into wx3"
This reverts commit 33a0c10650, reversing
changes made to 2077655694.

Reverting merges fucks up git, but oh well - we probably better merge stuff manually rather than fucking up master with wx3 which is apparently buggy
2015-04-30 19:47:15 +03:00
DarkPhoenix
c809a614f9 Revert "Move logging initialization back to pyfa.py"
This reverts commit d18cf7b3b0.

Reverting all wx3 commits in master
2015-04-30 19:39:11 +03:00
DarkPhoenix
2c366faa66 Revert "Remove setting locale"
This reverts commit 7606bded40.

Reverting all wx3 commits on master
2015-04-30 19:38:47 +03:00
DarkPhoenix
06252d761d Revert "Change the way we detect pyfa path"
This reverts commit bb8d5d0d65.

Reverting all wx3 commits in master
2015-04-30 19:38:18 +03:00
DarkPhoenix
bb8d5d0d65 Change the way we detect pyfa path
This ensures that it works even with frozen executable
2015-04-29 00:27:42 +03:00
DarkPhoenix
7606bded40 Remove setting locale
It causes issues with wx3 on windows
2015-04-28 23:49:11 +03:00
DarkPhoenix
daaf48d02a Add effect i should've added for mosaic release 2015-04-28 21:59:54 +03:00
DarkPhoenix
d18cf7b3b0 Move logging initialization back to pyfa.py 2015-04-28 21:59:14 +03:00
DarkPhoenix
33a0c10650 Merge branch 'master' into wx3 2015-04-28 21:53:27 +03:00
DarkPhoenix
2077655694 Bump version for next development release 2015-04-28 21:43:22 +03:00
DarkPhoenix
0dc3cbb7c7 Bump version for a stable release 2015-04-28 19:50:53 +03:00
Anton Vorobyov
a3c19f6f2b Merge pull request #271 from BlckKnght/fix_stagger
Fix stagger
2015-04-28 19:34:58 +03:00
DarkPhoenix
f97b037011 Forgot to save file for previous commit 2015-04-28 19:18:56 +03:00
DarkPhoenix
dd3dd799b2 Move loggin configuration to config temporarily 2015-04-28 19:17:50 +03:00
Anton Vorobyov
ac881ac371 Merge pull request #276 from kainz/master
Support fits exported from jEveAssets
2015-04-28 18:30:20 +03:00
DarkPhoenix
d734ccbf0d Add effect for entosis link and update effect comments 2015-04-28 18:24:25 +03:00
DarkPhoenix
024e0ad4f5 Support proper migration for ishukone scorp (which is skin for regular scorp now) 2015-04-28 18:19:58 +03:00
DarkPhoenix
545d98883a Update DB to mosaic 2015-04-28 18:06:03 +03:00
DarkPhoenix
742abc3250 Remove bunch of chinese skinned ships 2015-04-28 18:05:15 +03:00
DarkPhoenix
294e213ac2 Remove support for vanity ships which were converted into base hulls in game
We do not need any DB conversion for them because we converted them into base hull during import time. Also it breaks import of old posted EFT-style fits with removed skinned ships, but i can't say we care alot about this case
2015-04-28 18:01:06 +03:00
Bryon Roche
557f32ab91 Implement support for loading utf-16 XML.
Such XML is generated by software like jEveAssets's owned ships->fitting
export tool.

Without such detection, pyfa will go and try to import those as DNA
fits, with all the ensuing hilarity, thus the DNA import debug code as
well.
2015-04-22 05:05:48 -07:00
DarkPhoenix
e5430cac84 Do not apply ES bonus to weapon locus rigs 2015-04-20 15:07:19 +03:00
blitzmann
39c14b62fd Merge branch 'master' into wx3 2015-04-17 17:48:56 -04:00
Steven Barker
cb1de9589e fix typo, pick a better stagger amount 2015-03-31 12:09:27 -07:00
Steven Barker
370e34cff9 Make staggerred modules with ammo work 2015-03-30 21:02:56 -07:00
DarkPhoenix
e8268633e3 Merge branch 'master' into wx3
Used code from the master on conflicts
2014-12-15 15:45:33 +03:00
DarkPhoenix
3c1bf22e87 Merge branch 'master' into wx3 2014-12-12 14:42:25 +03:00
blitzmann
ff55f2817b Fix for collapsible stats panels 2014-11-08 18:17:57 -05:00
Gleb Golubitsky
198ee8d129 Icon column size bumped to 24
Signed-off-by: Gleb Golubitsky <sectoid@gnolltech.org>
2014-11-08 17:33:37 +02:00
Gleb Golubitsky
7db13bd3ba Fixed ChromeTabs not rendering properly in wx 3.0
Signed-off-by: Gleb Golubitsky <sectoid@gnolltech.org>
2014-11-08 17:33:04 +02:00
blitzmann
5be0d4b70e Added version selection logic 2014-11-08 16:45:09 +02:00
blitzmann
a603a4359a Fixed font discrepancy from different wxPython versions. 2014-11-08 16:45:09 +02:00
blitzmann
b4f4024903 Fixed some bugs that blocked startup 2014-11-08 16:38:18 +02:00
blitzmann
df18651b4f Bump wxPython requirements 2014-11-08 16:38:18 +02:00
1897 changed files with 4492 additions and 3544 deletions

1
.gitignore vendored
View File

@@ -20,3 +20,4 @@ saveddata/
#Pyfa file
pyfaFits.html
build/

View File

@@ -6,6 +6,13 @@ It provides many advanced features such as graphs and full calculations of any p
Please see the [FAQ](https://github.com/DarkFenX/Pyfa/wiki/FAQ) for answers to common questions / concerns
#### A note for Linux users
pyfa currently only supports wxPython 2.8. However, there are some distros that have started to support 3.0 and subsequently dropped support for 2.8 altogether (such as Debian Jessie). If this is the case and wxPython 3.0 is the only version installed, the official pyfa releases will not run. You must either find a package for 2.8 or compile it yourself.
For Debian Jessie, wxPython 2.8 is available in Sid (the unstable repo). you can use apt-pinning to install select packages from unstable and still keep your stable system. See http://jaqque.sbih.org/kplug/apt-pinning.html for me details.
3.0 support is being worked on and can be found on the wx3 branch. It may be stable enough for you, but there are a few bugs related to it. Please see the wx3 label on the GitHub issues area for me information on known issues (biggest one currently is GTK warning spam): https://github.com/DarkFenX/Pyfa/labels/wx3
#### Links
* [Development repository: http://github.com/DarkFenX/Pyfa](http://github.com/DarkFenX/Pyfa)
* [XMPP conference:

View File

@@ -1,6 +1,11 @@
import os
import sys
# TODO: move all logging back to pyfa.py main loop
# We moved it here just to avoid rebuilding windows skeleton for now (any change to pyfa.py needs it)
import logging
import logging.handlers
# Load variable overrides specific to distribution type
try:
import configforced
@@ -12,23 +17,43 @@ debug = False
# Defines if our saveddata will be in pyfa root or not
saveInRoot = False
if debug:
logLevel = logging.DEBUG
else:
logLevel = logging.WARN
# Version data
version = "1.10.1"
tag = "preview"
expansionName = "t3d_changes"
version = "1.15.0"
tag = "Stable"
expansionName = "Vanguard"
expansionVersion = "1.0"
evemonMinVersion = "4081"
# Database version (int ONLY)
# Increment every time we need to flag for user database upgrade/modification
dbversion = 6
pyfaPath = None
savePath = None
staticPath = None
saveDB = None
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 = ''
def write(self, buf):
for line in buf.rstrip().splitlines():
self.logger.log(self.log_level, line.rstrip())
def __createDirs(path):
if not os.path.exists(path):
os.makedirs(path)
def defPaths():
global pyfaPath
global savePath
@@ -54,19 +79,25 @@ def defPaths():
savePath = unicode(os.path.expanduser(os.path.join("~", ".pyfa")),
sys.getfilesystemencoding())
# Redirect stderr to file if we're requested to do so
stderrToFile = getattr(configforced, "stderrToFile", None)
if stderrToFile is True:
if not os.path.exists(savePath):
os.mkdir(savePath)
sys.stderr = open(os.path.join(savePath, "error_log.txt"), "w")
__createDirs(savePath)
# Same for stdout
stdoutToFile = getattr(configforced, "stdoutToFile", None)
if stdoutToFile is True:
if not os.path.exists(savePath):
os.mkdir(savePath)
sys.stdout = open(os.path.join(savePath, "output_log.txt"), "w")
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)
handler.setFormatter(formatter)
logging.getLogger('').addHandler(handler)
logging.info("Starting pyfa")
if hasattr(sys, 'frozen'):
stdout_logger = logging.getLogger('STDOUT')
sl = StreamToLogger(stdout_logger, logging.INFO)
sys.stdout = sl
stderr_logger = logging.getLogger('STDERR')
sl = StreamToLogger(stderr_logger, logging.ERROR)
sys.stderr = sl
# Static EVE Data from the staticdata repository, should be in the staticdata
# directory in our pyfa directory

View File

@@ -82,18 +82,25 @@ class CapSimulator(object):
if self.scale:
duration, capNeed = self.scale_activation(duration, capNeed)
if self.stagger:
duration = int(duration/amount)
else:
capNeed *= amount
period = lcm(period, duration)
# set clipSize to infinite if reloads are disabled unless it's
# a cap booster module.
if not self.reload and capNeed > 0:
clipSize = 0
if self.stagger:
if clipSize == 0:
duration = int(duration/amount)
else:
stagger_amount = (duration*clipSize+10000)/(amount*clipSize)
for i in range(1, amount):
heapq.heappush(self.state,
[i*stagger_amount, duration,
capNeed, 0, clipSize])
else:
capNeed *= amount
period = lcm(period, duration)
# period optimization doesn't work when reloads are active.
if clipSize:
disable_period = True

View File

@@ -5,7 +5,7 @@ debug = False
gamedataCache = True
saveddataCache = True
gamedata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "staticdata", "eve.db")), sys.getfilesystemencoding())
saveddata_connectionstring = 'sqlite:///:memory:'
saveddata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "saveddata", "saveddata.db")), sys.getfilesystemencoding())
#Autodetect path, only change if the autodetection bugs out.
path = dirname(unicode(__file__, sys.getfilesystemencoding()))

View File

@@ -1,32 +1,46 @@
import config
import shutil
import time
import re
import os
def getAppVersion():
# calculate app version based on upgrade files we have
appVersion = 0
for fname in os.listdir(os.path.join(os.path.dirname(__file__), "migrations")):
m = re.match("^upgrade(?P<index>\d+)\.py$", fname)
if not m:
continue
index = int(m.group("index"))
appVersion = max(appVersion, index)
return appVersion
def getVersion(db):
cursor = db.execute('PRAGMA user_version')
return cursor.fetchone()[0]
def update(saveddata_engine):
currversion = getVersion(saveddata_engine)
dbVersion = getVersion(saveddata_engine)
appVersion = getAppVersion()
if currversion == config.dbversion:
if dbVersion == appVersion:
return
if currversion < config.dbversion:
if dbVersion < appVersion:
# Automatically backup database
toFile = "%s/saveddata_migration_%d-%d_%s.db"%(
config.savePath,
currversion,
config.dbversion,
dbVersion,
appVersion,
time.strftime("%Y%m%d_%H%M%S"))
shutil.copyfile(config.saveDB, toFile)
for version in xrange(currversion, config.dbversion):
module = __import__('eos.db.migrations.upgrade%d'%(version+1), fromlist=True)
for version in xrange(dbVersion, appVersion):
module = __import__("eos.db.migrations.upgrade{}".format(version + 1), fromlist=True)
upgrade = getattr(module, "upgrade", False)
if upgrade:
upgrade(saveddata_engine)
# when all is said and done, set version to current
saveddata_engine.execute('PRAGMA user_version = %d'%config.dbversion)
saveddata_engine.execute("PRAGMA user_version = {}".format(appVersion))

View File

@@ -0,0 +1,16 @@
"""
Migration 10
- Adds active attribute to projected fits
"""
import sqlalchemy
def upgrade(saveddata_engine):
# Update projectedFits schema to include active attribute
try:
saveddata_engine.execute("SELECT active FROM projectedFits LIMIT 1")
except sqlalchemy.exc.DatabaseError:
saveddata_engine.execute("ALTER TABLE projectedFits ADD COLUMN active BOOLEAN")
saveddata_engine.execute("UPDATE projectedFits SET active = 1")
saveddata_engine.execute("UPDATE projectedFits SET amount = 1")

View File

@@ -0,0 +1,24 @@
"""
Migration 7
- Converts Scorpion Ishukone Watch to Scorpion
Mosaic introduced proper skinning system, and Ishukone Scorp
was the only ship which was presented as stand-alone ship in
Pyfa.
"""
CONVERSIONS = {
640: ( # Scorpion
4005, # Scorpion Ishukone Watch
)
}
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))

View File

@@ -0,0 +1,85 @@
"""
Migration 8
- Converts modules based on Carnyx Module Tiericide
Some modules have been unpublished (and unpublished module attributes are removed
from database), which causes pyfa to crash. We therefore replace these
modules with their new replacements
"""
CONVERSIONS = {
8529: ( # Large F-S9 Regolith Compact Shield Extender
8409, # Large Subordinate Screen Stabilizer I
),
8419: ( # Large Azeotropic Restrained Shield Extender
8489, # Large Supplemental Barrier Emitter I
),
8517: ( # Medium F-S9 Regolith Compact Shield Extender
8397, # Medium Subordinate Screen Stabilizer I
),
8433: ( # Medium Azeotropic Restrained Shield Extender
8477, # Medium Supplemental Barrier Emitter I
),
20627: ( # Small 'Trapper' Shield Extender
8437, # Micro Azeotropic Ward Salubrity I
8505, # Micro F-S9 Regolith Shield Induction
3849, # Micro Shield Extender I
3851, # Micro Shield Extender II
8387, # Micro Subordinate Screen Stabilizer I
8465, # Micro Supplemental Barrier Emitter I
),
8521: ( # Small F-S9 Regolith Compact Shield Extender
8401, # Small Subordinate Screen Stabilizer I
),
8427: ( # Small Azeotropic Restrained Shield Extender
8481, # Small Supplemental Barrier Emitter I
),
11343: ( # 100mm Crystalline Carbonide Restrained Plates
11345, # 100mm Reinforced Nanofiber Plates I
),
11341: ( # 100mm Rolled Tungsten Compact Plates
11339, # 100mm Reinforced Titanium Plates I
),
11327: ( # 1600mm Crystalline Carbonide Restrained Plates
11329, # 1600mm Reinforced Nanofiber Plates I
),
11325: ( # 1600mm Rolled Tungsten Compact Plates
11323, # 1600mm Reinforced Titanium Plates I
),
11351: ( # 200mm Crystalline Carbonide Restrained Plates
11353, # 200mm Reinforced Nanofiber Plates I
),
11349: ( # 200mm Rolled Tungsten Compact Plates
11347, # 200mm Reinforced Titanium Plates I
),
11311: ( # 400mm Crystalline Carbonide Restrained Plates
11313, # 400mm Reinforced Nanofiber Plates I
),
11309: ( # 400mm Rolled Tungsten Compact Plates
11307, # 400mm Reinforced Titanium Plates I
),
23791: ( # 'Citadella' 100mm Steel Plates
11335, # 50mm Reinforced Crystalline Carbonide Plates I
11337, # 50mm Reinforced Nanofiber Plates I
11333, # 50mm Reinforced Rolled Tungsten Plates I
11291, # 50mm Reinforced Steel Plates I
20343, # 50mm Reinforced Steel Plates II
11331, # 50mm Reinforced Titanium Plates I
),
11319: ( # 800mm Crystalline Carbonide Restrained Plates
11321, # 800mm Reinforced Nanofiber Plates I
),
11317: ( # 800mm Rolled Tungsten Compact Plates
11315, # 800mm Reinforced Titanium Plates I
),
}
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))

View File

@@ -0,0 +1,23 @@
"""
Migration 9
Effectively drops UNIQUE constraint from boosters table. SQLite does not support
this, so we have to copy the table to the updated schema and then rename it
"""
tmpTable = """
CREATE TABLE boostersTemp (
'ID' INTEGER NOT NULL,
'itemID' INTEGER,
'fitID' INTEGER NOT NULL,
'active' BOOLEAN,
PRIMARY KEY(ID),
FOREIGN KEY('fitID') REFERENCES fits ('ID')
)
"""
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("DROP TABLE boosters")
saveddata_engine.execute("ALTER TABLE boostersTemp RENAME TO boosters")

View File

@@ -29,7 +29,7 @@ boosters_table = Table("boosters", saveddata_meta,
Column("itemID", Integer),
Column("fitID", Integer, ForeignKey("fits.ID"), nullable = False),
Column("active", Boolean),
UniqueConstraint("itemID", "fitID"))
)
activeSideEffects_table = Table("boostersActiveSideEffects", saveddata_meta,
Column("boosterID", ForeignKey("boosters.ID"), primary_key = True),

View File

@@ -17,9 +17,11 @@
# along with eos. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
from sqlalchemy import Table, Column, Integer, ForeignKey, String, Boolean
from sqlalchemy.orm import relation, mapper
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.sql import and_
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.orm.collections import attribute_mapped_collection
from eos.db import saveddata_meta
from eos.db.saveddata.module import modules_table
@@ -27,9 +29,7 @@ from eos.db.saveddata.drone import drones_table
from eos.db.saveddata.cargo import cargo_table
from eos.db.saveddata.implant import fitImplants_table
from eos.types import Fit, Module, User, Booster, Drone, Cargo, Implant, Character, DamagePattern, TargetResists
from eos.effectHandlerHelpers import HandledModuleList, HandledDroneList, \
HandledImplantBoosterList, HandledProjectedModList, HandledProjectedDroneList, \
HandledProjectedFitList, HandledCargoList
from eos.effectHandlerHelpers import *
fits_table = Table("fits", saveddata_meta,
Column("ID", Integer, primary_key = True),
@@ -47,31 +47,119 @@ fits_table = Table("fits", saveddata_meta,
projectedFits_table = Table("projectedFits", saveddata_meta,
Column("sourceID", ForeignKey("fits.ID"), primary_key = True),
Column("victimID", ForeignKey("fits.ID"), primary_key = True),
Column("amount", Integer))
Column("amount", Integer, nullable = False, default = 1),
Column("active", Boolean, nullable = False, default = 1),
)
class ProjectedFit(object):
def __init__(self, sourceID, source_fit, amount=1, active=True):
self.sourceID = sourceID
self.source_fit = source_fit
self.active = active
self.__amount = amount
@reconstructor
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)
# We have a series of setters and getters here just in case someone
# downgrades and screws up the table with NULL values
@property
def amount(self):
return self.__amount or 1
@amount.setter
def amount(self, amount):
self.__amount = amount
def __repr__(self):
return "ProjectedFit(sourceID={}, victimID={}, amount={}, active={}) at {}".format(
self.sourceID, self.victimID, self.amount, self.active, hex(id(self))
)
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)
)
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"),
"_Fit__boosters" : relation(Booster, collection_class = HandledImplantBoosterList, cascade='all, delete, delete-orphan', single_parent=True),
"_Fit__drones" : relation(Drone, collection_class = HandledDroneList, cascade='all, delete, delete-orphan', single_parent=True,
primaryjoin = and_(drones_table.c.fitID == fits_table.c.ID, drones_table.c.projected == False)),
"_Fit__cargo" : relation(Cargo, collection_class = HandledCargoList, 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__implants" : relation(Implant, collection_class = HandledImplantBoosterList, cascade='all, delete, delete-orphan', 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),
"_Fit__projectedFits" : relation(Fit,
primaryjoin = projectedFits_table.c.victimID == fits_table.c.ID,
secondaryjoin = fits_table.c.ID == projectedFits_table.c.sourceID,
secondary = projectedFits_table,
collection_class = HandledProjectedFitList)
})
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__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__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'),
}
)
mapper(ProjectedFit, projectedFits_table,
properties = {
"_ProjectedFit__amount": projectedFits_table.c.amount,
}
)

View File

@@ -185,6 +185,12 @@ def getFit(lookfor, eager=None):
fit = saveddata_session.query(Fit).options(*eager).filter(Fit.ID == fitID).first()
else:
raise TypeError("Need integer as argument")
if fit and fit.isInvalid:
with sd_lock:
removeInvalid([fit])
return None
return fit
@cachedQuery(Fleet, 1, "fleetID")
@@ -244,9 +250,10 @@ def getFitsWithShip(shipID, ownerID=None, where=None, eager=None):
filter = processWhere(filter, where)
eager = processEager(eager)
with sd_lock:
fits = saveddata_session.query(Fit).options(*eager).filter(filter).all()
fits = removeInvalid(saveddata_session.query(Fit).options(*eager).filter(filter).all())
else:
raise TypeError("ShipID must be integer")
return fits
def getBoosterFits(ownerID=None, where=None, eager=None):
@@ -264,7 +271,8 @@ def getBoosterFits(ownerID=None, where=None, eager=None):
filter = processWhere(filter, where)
eager = processEager(eager)
with sd_lock:
fits = saveddata_session.query(Fit).options(*eager).filter(filter).all()
fits = removeInvalid(saveddata_session.query(Fit).options(*eager).filter(filter).all())
return fits
def countAllFits():
@@ -295,7 +303,8 @@ def countFitsWithShip(shipID, ownerID=None, where=None, eager=None):
def getFitList(eager=None):
eager = processEager(eager)
with sd_lock:
fits = saveddata_session.query(Fit).options(*eager).all()
fits = removeInvalid(saveddata_session.query(Fit).options(*eager).all())
return fits
def getFleetList(eager=None):
@@ -385,7 +394,8 @@ def searchFits(nameLike, where=None, eager=None):
filter = processWhere(Fit.name.like(nameLike, escape="\\"), where)
eager = processEager(eager)
with sd_lock:
fits = saveddata_session.query(Fit).options(*eager).filter(filter).all()
fits = removeInvalid(saveddata_session.query(Fit).options(*eager).filter(filter).all())
return fits
def getSquadsIDsWithFitID(fitID):
@@ -406,6 +416,16 @@ def getProjectedFits(fitID):
else:
raise TypeError("Need integer as argument")
def removeInvalid(fits):
invalids = [f for f in fits if f.isInvalid]
if invalids:
map(fits.remove, invalids)
map(saveddata_session.delete, invalids)
saveddata_session.commit()
return fits
def add(stuff):
with sd_lock:
saveddata_session.add(stuff)

View File

@@ -17,8 +17,12 @@
# along with eos. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
#from sqlalchemy.orm.attributes import flag_modified
import eos.db
import eos.types
import logging
logger = logging.getLogger(__name__)
class HandledList(list):
def filteredItemPreAssign(self, filter, *args, **kwargs):
@@ -101,6 +105,14 @@ class HandledList(list):
except AttributeError:
pass
def remove(self, thing):
# We must flag it as modified, otherwise it not be removed from the database
# @todo: flag_modified isn't in os x skel. need to rebuild to include
#flag_modified(thing, "itemID")
if thing.isInvalid: # see GH issue #324
thing.itemID = 0
list.remove(self, thing)
class HandledModuleList(HandledList):
def append(self, mod):
emptyPosition = float("Inf")
@@ -115,10 +127,14 @@ class HandledModuleList(HandledList):
del self[emptyPosition]
mod.position = emptyPosition
HandledList.insert(self, emptyPosition, mod)
if mod.isInvalid:
self.remove(mod)
return
mod.position = len(self)
HandledList.append(self, mod)
if mod.isInvalid:
self.remove(mod)
def insert(self, index, mod):
mod.position = index
@@ -143,139 +159,82 @@ class HandledModuleList(HandledList):
dummy.position = index
self[index] = dummy
def toModule(self, index, mod):
mod.position = index
self[index] = mod
def freeSlot(self, slot):
for i in range(len(self) -1, -1, -1):
mod = self[i]
if mod.getModifiedItemAttr("subSystemSlot") == slot:
del self[i]
class HandledDroneList(HandledList):
class HandledDroneCargoList(HandledList):
def find(self, item):
for d in self:
if d.item == item:
yield d
for o in self:
if o.item == item:
yield o
def findFirst(self, item):
for d in self.find(item):
return d
for o in self.find(item):
return o
def append(self, drone):
list.append(self, drone)
def append(self, thing):
HandledList.append(self, thing)
def remove(self, drone):
HandledList.remove(self, drone)
def appendItem(self, item, amount = 1):
if amount < 1: ValueError("Amount of drones to add should be >= 1")
d = self.findFirst(item)
if d is None:
d = eos.types.Drone(item)
self.append(d)
d.amount += amount
return d
def removeItem(self, item, amount):
if amount < 1: ValueError("Amount of drones to remove should be >= 1")
d = self.findFirst(item)
if d is None: return
d.amount -= amount
if d.amount <= 0:
self.remove(d)
return None
return d
class HandledCargoList(HandledList):
# shameless copy of HandledDroneList
# I have no idea what this does, but I needed it
# @todo: investigate this
def find(self, item):
for d in self:
if d.item == item:
yield d
def findFirst(self, item):
for d in self.find(item):
return d
def append(self, cargo):
list.append(self, cargo)
def remove(self, cargo):
HandledList.remove(self, cargo)
def appendItem(self, item, qty = 1):
if qty < 1: ValueError("Amount of cargo to add should be >= 1")
d = self.findFirst(item)
if d is None:
d = eos.types.Cargo(item)
self.append(d)
d.qty += qty
return d
def removeItem(self, item, qty):
if qty < 1: ValueError("Amount of cargo to remove should be >= 1")
d = self.findFirst(item)
if d is None: return
d.qty -= qty
if d.qty <= 0:
self.remove(d)
return None
return d
if thing.isInvalid:
self.remove(thing)
class HandledImplantBoosterList(HandledList):
def __init__(self):
self.__slotCache = {}
def append(self, thing):
if thing.isInvalid:
HandledList.append(self, thing)
self.remove(thing)
return
def append(self, implant):
if self.__slotCache.has_key(implant.slot):
raise ValueError("Implant/Booster slot already in use, remove the old one first or set replace = True")
self.__slotCache[implant.slot] = implant
HandledList.append(self, implant)
# if needed, remove booster that was occupying slot
oldObj = next((m for m in self if m.slot == thing.slot), None)
if oldObj:
logging.info("Slot %d occupied with %s, replacing with %s", thing.slot, oldObj.item.name, thing.item.name)
oldObj.itemID = 0 # hack to remove from DB. See GH issue #324
self.remove(oldObj)
def remove(self, implant):
HandledList.remove(self, implant)
del self.__slotCache[implant.slot]
# While we deleted this implant, in edge case seems like not all references
# to it are removed and object still lives in session; forcibly remove it,
# or otherwise when adding the same booster twice booster's table (typeID, fitID)
# constraint will report database integrity error
# TODO: make a proper fix, probably by adjusting fit-boosters sqlalchemy relationships
eos.db.remove(implant)
def freeSlot(self, slot):
if hasattr(slot, "slot"):
slot = slot.slot
try:
implant = self.__slotCache[slot]
except KeyError:
return False
try:
self.remove(implant)
except ValueError:
return False
return True
HandledList.append(self, thing)
class HandledProjectedModList(HandledList):
def append(self, proj):
if proj.isInvalid:
# we must include it before we remove it. doing it this way ensures
# rows and relationships in database are removed as well
HandledList.append(self, proj)
self.remove(proj)
return
proj.projected = True
isSystemEffect = proj.item.group.name == "Effect Beacon"
if isSystemEffect:
# remove other system effects - only 1 per fit plz
oldEffect = next((m for m in self if m.item.group.name == "Effect Beacon"), None)
if oldEffect:
logging.info("System effect occupied with %s, replacing with %s", oldEffect.item.name, proj.item.name)
self.remove(oldEffect)
HandledList.append(self, proj)
# Remove non-projectable modules
if not proj.item.isType("projected") and not isSystemEffect:
self.remove(proj)
class HandledProjectedDroneList(HandledDroneCargoList):
def append(self, proj):
proj.projected = True
HandledList.append(self, proj)
class HandledProjectedDroneList(HandledDroneList):
def append(self, proj):
proj.projected = True
list.append(self, proj)
class HandledProjectedFitList(HandledList):
def append(self, proj):
proj.projected = True
list.append(self, proj)
# Remove invalid or non-projectable drones
if proj.isInvalid or not proj.item.isType("projected"):
self.remove(proj)
class HandledItem(object):
def preAssignItemAttr(self, *args, **kwargs):

View File

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

View File

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

View File

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

View File

@@ -6,4 +6,4 @@ type = "passive"
def handler(fit, implant, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Repair Systems"),
"armorDamageAmount", implant.getModifiedItemAttr("repairBonus"),
stackingPenalties = True)
stackingPenalties=True)

View File

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

View File

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

View File

@@ -0,0 +1,9 @@
# battlecruiserDroneSpeed
#
# Used by:
# Ship: Myrmidon
# Ship: Prophecy
type = "passive"
def handler(fit, ship, context):
fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Drones"),
"maxVelocity", ship.getModifiedItemAttr("roleBonusCBC"))

View File

@@ -0,0 +1,10 @@
# battlecruiserMETRange
#
# Used by:
# Ships named like: Harbinger (2 of 2)
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Energy Turret"),
"maxRange", ship.getModifiedItemAttr("roleBonusCBC"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Energy Turret"),
"falloff", ship.getModifiedItemAttr("roleBonusCBC"))

View File

@@ -0,0 +1,11 @@
# battlecruiserMHTRange
#
# Used by:
# Ships named like: Brutix (2 of 2)
# Ship: Ferox
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Hybrid Turret"),
"maxRange", ship.getModifiedItemAttr("roleBonusCBC"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Hybrid Turret"),
"falloff", ship.getModifiedItemAttr("roleBonusCBC"))

View File

@@ -0,0 +1,9 @@
# battlecruiserMissileRange
#
# Used by:
# Ships named like: Drake (2 of 2)
# Ship: Cyclone
type = "passive"
def handler(fit, skill, context):
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"),
"maxVelocity", skill.getModifiedItemAttr("roleBonusCBC"))

View File

@@ -0,0 +1,10 @@
# battlecruiserMPTRange
#
# Used by:
# Ships named like: Hurricane (2 of 2)
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Projectile Turret"),
"maxRange", ship.getModifiedItemAttr("roleBonusCBC"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Projectile Turret"),
"falloff", ship.getModifiedItemAttr("roleBonusCBC"))

View File

@@ -5,6 +5,5 @@
type = "passive"
runTime = "early"
def handler(fit, ship, context):
level = fit.character.getSkill("Transport Ships").level
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Cloaking Device",
"cpu", ship.getModifiedItemAttr("eliteIndustrialCovertCloakBonus") * level)
"cpu", ship.getModifiedItemAttr("eliteIndustrialCovertCloakBonus"), skill="Transport Ships")

View File

@@ -1,7 +1,7 @@
# boosterArmorHpPenalty
#
# Used by:
# Implants from group: Booster (12 of 37)
# Implants from group: Booster (12 of 39)
type = "boosterSideEffect"
def handler(fit, booster, context):
fit.ship.boostItemAttr("armorHP", booster.getModifiedItemAttr("boosterArmorHPPenalty"))

View File

@@ -1,7 +1,7 @@
# boosterArmorRepairAmountPenalty
#
# Used by:
# Implants from group: Booster (9 of 37)
# Implants from group: Booster (9 of 39)
type = "boosterSideEffect"
def handler(fit, booster, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Armor Repair Unit",

View File

@@ -1,7 +1,7 @@
# boosterMaxVelocityPenalty
#
# Used by:
# Implants from group: Booster (12 of 37)
# Implants from group: Booster (12 of 39)
type = "boosterSideEffect"
def handler(fit, booster, context):
fit.ship.boostItemAttr("maxVelocity", booster.getModifiedItemAttr("boosterMaxVelocityPenalty"))

View File

@@ -1,7 +1,7 @@
# boosterShieldCapacityPenalty
#
# Used by:
# Implants from group: Booster (12 of 37)
# Implants from group: Booster (12 of 39)
type = "boosterSideEffect"
def handler(fit, booster, context):
fit.ship.boostItemAttr("shieldCapacity", booster.getModifiedItemAttr("boosterShieldCapacityPenalty"))

View File

@@ -1,7 +1,7 @@
# boosterTurretOptimalRangePenalty
#
# Used by:
# Implants from group: Booster (9 of 37)
# Implants from group: Booster (9 of 39)
type = "boosterSideEffect"
def handler(fit, booster, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Gunnery"),

View File

@@ -2,9 +2,7 @@
#
# Used by:
# Ship: Scorpion
# Ship: Scorpion Ishukone Watch
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Caldari Battleship").level
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "ECM Burst",
"ecmBurstRange", ship.getModifiedItemAttr("shipBonusCB3") * level)
"ecmBurstRange", ship.getModifiedItemAttr("shipBonusCB3"), skill="Caldari Battleship")

View File

@@ -6,6 +6,5 @@
# Ship: Rook
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Caldari Cruiser").level
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "ECM",
"capacitorNeed", ship.getModifiedItemAttr("shipBonusCC") * level)
"capacitorNeed", ship.getModifiedItemAttr("shipBonusCC"), skill="Caldari Cruiser")

View File

@@ -4,6 +4,5 @@
# Variations of ship: Griffin (2 of 2)
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Caldari Frigate").level
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "ECM",
"capacitorNeed", ship.getModifiedItemAttr("shipBonusCF2") * level)
"capacitorNeed", ship.getModifiedItemAttr("shipBonusCF2"), skill="Caldari Frigate")

View File

@@ -2,9 +2,7 @@
#
# Used by:
# Ship: Scorpion
# Ship: Scorpion Ishukone Watch
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Caldari Battleship").level
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "ECM",
"falloff", ship.getModifiedItemAttr("shipBonusCB3") * level)
"falloff", ship.getModifiedItemAttr("shipBonusCB3"), skill="Caldari Battleship")

View File

@@ -4,6 +4,5 @@
# Ship: Blackbird
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Caldari Cruiser").level
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "ECM",
"falloff", ship.getModifiedItemAttr("shipBonusCC2") * level)
"falloff", ship.getModifiedItemAttr("shipBonusCC2"), skill="Caldari Cruiser")

View File

@@ -2,9 +2,7 @@
#
# Used by:
# Ship: Scorpion
# Ship: Scorpion Ishukone Watch
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Caldari Battleship").level
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "ECM",
"maxRange", ship.getModifiedItemAttr("shipBonusCB3") * level)
"maxRange", ship.getModifiedItemAttr("shipBonusCB3"), skill="Caldari Battleship")

View File

@@ -4,6 +4,5 @@
# Ship: Blackbird
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Caldari Cruiser").level
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "ECM",
"maxRange", ship.getModifiedItemAttr("shipBonusCC2") * level)
"maxRange", ship.getModifiedItemAttr("shipBonusCC2"), skill="Caldari Cruiser")

View File

@@ -2,11 +2,9 @@
#
# Used by:
# Ship: Scorpion
# Ship: Scorpion Ishukone Watch
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Caldari Battleship").level
for sensorType in ("Gravimetric", "Ladar", "Magnetometric", "Radar"):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "ECM",
"scan{0}StrengthBonus".format(sensorType),
ship.getModifiedItemAttr("shipBonusCB") * level)
ship.getModifiedItemAttr("shipBonusCB"), skill="Caldari Battleship")

View File

@@ -4,7 +4,7 @@
# Modules from group: Capacitor Flux Coil (6 of 6)
# Modules from group: Capacitor Power Relay (20 of 20)
# Modules from group: Power Diagnostic System (23 of 23)
# Modules from group: Propulsion Module (107 of 107)
# Modules from group: Propulsion Module (114 of 114)
# Modules from group: Reactor Control Unit (22 of 22)
# Modules from group: Shield Flux Coil (11 of 11)
# Modules from group: Shield Power Relay (11 of 11)

View File

@@ -5,9 +5,7 @@
# Ship: Archon
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Amarr Carrier").level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Remote Armor Repair Systems"),
"maxRange", ship.getModifiedItemAttr("carrierAmarrBonus3") * level)
"maxRange", ship.getModifiedItemAttr("carrierAmarrBonus3"), skill="Amarr Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Capacitor Emission Systems"),
"powerTransferRange", ship.getModifiedItemAttr("carrierAmarrBonus3") * level)
"powerTransferRange", ship.getModifiedItemAttr("carrierAmarrBonus3"), skill="Amarr Carrier")

View File

@@ -5,7 +5,6 @@
# Ship: Archon
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Amarr Carrier").level
for resType in ("Em", "Explosive", "Kinetic", "Thermal"):
fit.ship.boostItemAttr("armor{0}DamageResonance".format(resType),
ship.getModifiedItemAttr("carrierAmarrBonus2") * level)
ship.getModifiedItemAttr("carrierAmarrBonus2"), skill="Amarr Carrier")

View File

@@ -5,6 +5,4 @@
# Ship: Archon
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Amarr Carrier").level
amount = ship.getModifiedItemAttr("carrierAmarrBonus1")
fit.extraAttributes.increase("maxActiveDrones", amount * level)
fit.extraAttributes.increase("maxActiveDrones", ship.getModifiedItemAttr("carrierAmarrBonus1"), skill="Amarr Carrier")

View File

@@ -4,6 +4,5 @@
# Ship: Revenant
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Amarr Carrier").level
fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Fighter Bombers"),
"maxVelocity", ship.getModifiedItemAttr("carrierAmarrBonus2") * level)
"maxVelocity", ship.getModifiedItemAttr("carrierAmarrBonus2"), skill="Amarr Carrier")

View File

@@ -4,6 +4,5 @@
# Ship: Revenant
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Amarr Carrier").level
fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Fighters"),
"maxVelocity", ship.getModifiedItemAttr("carrierAmarrBonus2") * level)
"maxVelocity", ship.getModifiedItemAttr("carrierAmarrBonus2"), skill="Amarr Carrier")

View File

@@ -5,6 +5,5 @@
# Ship: Revenant
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Amarr Carrier").level
fit.modules.filteredItemIncrease(lambda mod: mod.item.group.name == "Gang Coordinator",
"maxGroupActive", ship.getModifiedItemAttr("carrierAmarrBonus4") * level)
"maxGroupActive", ship.getModifiedItemAttr("carrierAmarrBonus4"), skill="Amarr Carrier")

View File

@@ -5,6 +5,4 @@
# Ship: Wyvern
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Caldari Carrier").level
amount = ship.getModifiedItemAttr("carrierCaldariBonus1")
fit.extraAttributes.increase("maxActiveDrones", amount * level)
fit.extraAttributes.increase("maxActiveDrones", ship.getModifiedItemAttr("carrierCaldariBonus1"), skill="Caldari Carrier")

View File

@@ -4,6 +4,5 @@
# Ship: Revenant
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Caldari Carrier").level
fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Fighters") or drone.item.requiresSkill("Fighter Bombers"),
"signatureRadius", ship.getModifiedItemAttr("carrierCaldariBonus1") * level)
"signatureRadius", ship.getModifiedItemAttr("carrierCaldariBonus1"), skill="Caldari Carrier")

View File

@@ -4,6 +4,5 @@
# Ship: Wyvern
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Caldari Carrier").level
fit.modules.filteredItemIncrease(lambda mod: mod.item.group.name == "Gang Coordinator",
"maxGroupActive", ship.getModifiedItemAttr("carrierCaldariBonus4") * level)
"maxGroupActive", ship.getModifiedItemAttr("carrierCaldariBonus4"), skill="Caldari Carrier")

View File

@@ -6,8 +6,7 @@
# Ship: Wyvern
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Caldari Carrier").level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Shield Emission Systems"),
"shieldTransferRange", ship.getModifiedItemAttr("carrierCaldariBonus3") * level)
"shieldTransferRange", ship.getModifiedItemAttr("carrierCaldariBonus3"), skill="Caldari Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Capacitor Emission Systems"),
"powerTransferRange", ship.getModifiedItemAttr("carrierCaldariBonus3") * level)
"powerTransferRange", ship.getModifiedItemAttr("carrierCaldariBonus3"), skill="Caldari Carrier")

View File

@@ -5,7 +5,6 @@
# Ship: Wyvern
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Caldari Carrier").level
for resType in ("Em", "Explosive", "Kinetic", "Thermal"):
fit.ship.boostItemAttr("shield{0}DamageResonance".format(resType),
ship.getModifiedItemAttr("carrierCaldariBonus2") * level)
ship.getModifiedItemAttr("carrierCaldariBonus2"), skill="Caldari Carrier")

View File

@@ -5,8 +5,7 @@
# Ship: Thanatos
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Gallente Carrier").level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Shield Emission Systems"),
"shieldTransferRange", ship.getModifiedItemAttr("carrierGallenteBonus3") * level)
"shieldTransferRange", ship.getModifiedItemAttr("carrierGallenteBonus3"), skill="Gallente Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Remote Armor Repair Systems"),
"maxRange", ship.getModifiedItemAttr("carrierGallenteBonus3") * level)
"maxRange", ship.getModifiedItemAttr("carrierGallenteBonus3"), skill="Gallente Carrier")

View File

@@ -4,6 +4,5 @@
# Ship: Nyx
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Gallente Carrier").level
fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Fighter Bombers"),
"damageMultiplier", ship.getModifiedItemAttr("carrierGallenteBonus2") * level)
"damageMultiplier", ship.getModifiedItemAttr("carrierGallenteBonus2"), skill="Gallente Carrier")

View File

@@ -5,6 +5,4 @@
# Ship: Thanatos
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Gallente Carrier").level
amount = ship.getModifiedItemAttr("carrierGallenteBonus1")
fit.extraAttributes.increase("maxActiveDrones", amount * level)
fit.extraAttributes.increase("maxActiveDrones", ship.getModifiedItemAttr("carrierGallenteBonus1"), skill="Gallente Carrier")

View File

@@ -5,6 +5,5 @@
# Ship: Thanatos
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Gallente Carrier").level
fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Fighters"),
"damageMultiplier", ship.getModifiedItemAttr("carrierGallenteBonus2") * level)
"damageMultiplier", ship.getModifiedItemAttr("carrierGallenteBonus2"), skill="Gallente Carrier")

View File

@@ -4,6 +4,5 @@
# Ship: Nyx
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Gallente Carrier").level
fit.modules.filteredItemIncrease(lambda mod: mod.item.group.name == "Gang Coordinator",
"maxGroupActive", ship.getModifiedItemAttr("carrierGallenteBonus4") * level)
"maxGroupActive", ship.getModifiedItemAttr("carrierGallenteBonus4"), skill="Gallente Carrier")

View File

@@ -5,8 +5,7 @@
# Ship: Nidhoggur
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Minmatar Carrier").level
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Remote Shield Booster",
"shieldBonus", ship.getModifiedItemAttr("carrierMinmatarBonus2") * level)
"shieldBonus", ship.getModifiedItemAttr("carrierMinmatarBonus2"), skill="Minmatar Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Remote Armor Repairer",
"armorDamageAmount", ship.getModifiedItemAttr("carrierMinmatarBonus2") * level)
"armorDamageAmount", ship.getModifiedItemAttr("carrierMinmatarBonus2"), skill="Minmatar Carrier")

View File

@@ -5,8 +5,7 @@
# Ship: Nidhoggur
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Minmatar Carrier").level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Shield Emission Systems"),
"shieldTransferRange", ship.getModifiedItemAttr("carrierMinmatarBonus3") * level)
"shieldTransferRange", ship.getModifiedItemAttr("carrierMinmatarBonus3"), skill="Minmatar Carrier")
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Remote Armor Repair Systems"),
"maxRange", ship.getModifiedItemAttr("carrierMinmatarBonus3") * level)
"maxRange", ship.getModifiedItemAttr("carrierMinmatarBonus3"), skill="Minmatar Carrier")

View File

@@ -5,6 +5,4 @@
# Ship: Nidhoggur
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Minmatar Carrier").level
amount = ship.getModifiedItemAttr("carrierMinmatarBonus1")
fit.extraAttributes.increase("maxActiveDrones", amount * level)
fit.extraAttributes.increase("maxActiveDrones", ship.getModifiedItemAttr("carrierMinmatarBonus1"), skill="Minmatar Carrier")

View File

@@ -4,6 +4,5 @@
# Ship: Hel
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Minmatar Carrier").level
fit.modules.filteredItemIncrease(lambda mod: mod.item.group.name == "Gang Coordinator",
"maxGroupActive", ship.getModifiedItemAttr("carrierMinmatarBonus4") * level)
"maxGroupActive", ship.getModifiedItemAttr("carrierMinmatarBonus4"), skill="Minmatar Carrier")

View File

@@ -8,5 +8,5 @@ type = "active", "gang"
def handler(fit, module, context):
if "gang" not in context: return
for bonus in ("maxRangeBonus", "falloffBonus", "trackingSpeedBonus"):
fit.modules.filteredItemBoost(lambda mod: lambda mod: mod.item.requiresSkill("Weapon Disruption"),
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Weapon Disruption"),
bonus, module.getModifiedItemAttr("commandBonusTD"))

View File

@@ -1,9 +1,9 @@
# commandshipMultiRelayEffect
#
# Used by:
# Ships from group: Capital Industrial Ship (2 of 2)
# Ships from group: Command Ship (8 of 8)
# Ships from group: Industrial Command Ship (2 of 2)
# Ship: Orca
# Ship: Rorqual
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemIncrease(lambda mod: mod.item.group.name == "Gang Coordinator",

View File

@@ -5,6 +5,5 @@
type = "passive"
runTime = "early"
def handler(fit, ship, context):
level = fit.character.getSkill("Covert Ops").level
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Cloaking Device",
"cpu", ship.getModifiedItemAttr("eliteBonusCoverOps1") * level)
"cpu", ship.getModifiedItemAttr("eliteBonusCoverOps1"), skill="Covert Ops")

View File

@@ -2,7 +2,6 @@
#
# Used by:
# Modules from group: Rig Drones (64 of 64)
# Modules named like: Optimizer (16 of 16)
type = "passive"
def handler(fit, module, context):
fit.ship.boostItemAttr("cpuOutput", module.getModifiedItemAttr("drawback"))

View File

@@ -2,6 +2,7 @@
#
# Used by:
# Modules from group: Rig Shield (72 of 72)
# Modules named like: Optimizer (16 of 16)
type = "passive"
def handler(fit, module, context):
fit.ship.boostItemAttr("signatureRadius", module.getModifiedItemAttr("drawback"), stackingPenalties = True)

View File

@@ -1,9 +1,8 @@
# dreadnoughtMD1ProjDmgBonus
#
# Used by:
# Ships named like: Naglfar (2 of 2)
# Ship: Naglfar
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Minmatar Dreadnought").level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Projectile Turret"),
"damageMultiplier", ship.getModifiedItemAttr("dreadnoughtShipBonusM1") * level)
"damageMultiplier", ship.getModifiedItemAttr("dreadnoughtShipBonusM1"), skill="Minmatar Dreadnought")

View File

@@ -1,9 +1,8 @@
# dreadnoughtMD3ProjRoFBonus
#
# Used by:
# Ships named like: Naglfar (2 of 2)
# Ship: Naglfar
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Minmatar Dreadnought").level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Projectile Turret"),
"speed", ship.getModifiedItemAttr("dreadnoughtShipBonusM3") * level)
"speed", ship.getModifiedItemAttr("dreadnoughtShipBonusM3"), skill="Minmatar Dreadnought")

View File

@@ -1,9 +1,8 @@
# dreadnoughtShipBonusHybridDmgG1
#
# Used by:
# Ships named like: Moros (2 of 2)
# Ship: Moros
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Gallente Dreadnought").level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Hybrid Turret"),
"damageMultiplier", ship.getModifiedItemAttr("dreadnoughtShipBonusG1") * level)
"damageMultiplier", ship.getModifiedItemAttr("dreadnoughtShipBonusG1"), skill="Gallente Dreadnought")

View File

@@ -1,9 +1,8 @@
# dreadnoughtShipBonusHybridRoFG2
#
# Used by:
# Ships named like: Moros (2 of 2)
# Ship: Moros
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Gallente Dreadnought").level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Hybrid Turret"),
"speed", ship.getModifiedItemAttr("dreadnoughtShipBonusG2") * level)
"speed", ship.getModifiedItemAttr("dreadnoughtShipBonusG2"), skill="Gallente Dreadnought")

View File

@@ -1,9 +1,8 @@
# dreadnoughtShipBonusLaserCapNeedA1
#
# Used by:
# Ships named like: Revelation (2 of 2)
# Ship: Revelation
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Amarr Dreadnought").level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Energy Turret"),
"capacitorNeed", ship.getModifiedItemAttr("dreadnoughtShipBonusA1") * level)
"capacitorNeed", ship.getModifiedItemAttr("dreadnoughtShipBonusA1"), skill="Amarr Dreadnought")

View File

@@ -1,9 +1,8 @@
# dreadnoughtShipBonusLaserRofA2
#
# Used by:
# Ships named like: Revelation (2 of 2)
# Ship: Revelation
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Amarr Dreadnought").level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Energy Turret"),
"speed", ship.getModifiedItemAttr("dreadnoughtShipBonusA2") * level)
"speed", ship.getModifiedItemAttr("dreadnoughtShipBonusA2"), skill="Amarr Dreadnought")

View File

@@ -1,10 +1,9 @@
# dreadnoughtShipBonusShieldResistancesC2
#
# Used by:
# Ships named like: Phoenix (2 of 2)
# Ship: Phoenix
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Caldari Dreadnought").level
for damageType in ("em", "thermal", "explosive", "kinetic"):
fit.ship.boostItemAttr("shield{}DamageResonance".format(damageType.capitalize()),
ship.getModifiedItemAttr("dreadnoughtShipBonusC2") * level)
ship.getModifiedItemAttr("dreadnoughtShipBonusC2"), skill="Caldari Dreadnought")

View File

@@ -1,9 +1,8 @@
# eliteBargeBonusIceHarvestingCycleTimeBarge3
#
# Used by:
# Ships from group: Exhumer (4 of 4)
# Ships from group: Exhumer (3 of 3)
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Exhumers").level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Ice Harvesting"),
"duration", ship.getModifiedItemAttr("eliteBonusBarge2") * level)
"duration", ship.getModifiedItemAttr("eliteBonusBarge2"), skill="Exhumers")

View File

@@ -1,9 +1,8 @@
# eliteBargeBonusMiningDurationBarge2
#
# Used by:
# Ships from group: Exhumer (4 of 4)
# Ships from group: Exhumer (3 of 3)
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Exhumers").level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining"),
"duration", ship.getModifiedItemAttr("eliteBonusBarge2") * level)
"duration", ship.getModifiedItemAttr("eliteBonusBarge2"), skill="Exhumers")

View File

@@ -1,10 +1,9 @@
# eliteBargeShieldResistance1
#
# Used by:
# Ships from group: Exhumer (4 of 4)
# Ships from group: Exhumer (3 of 3)
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Exhumers").level
for damageType in ("em", "thermal", "explosive", "kinetic"):
fit.ship.boostItemAttr("shield{}DamageResonance".format(damageType.capitalize()),
ship.getModifiedItemAttr("eliteBonusBarge1") * level)
ship.getModifiedItemAttr("eliteBonusBarge1"), skill="Exhumers")

View File

@@ -4,6 +4,5 @@
# Ship: Cambion
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Assault Frigates").level
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Missile Launcher Light",
"speed", ship.getModifiedItemAttr("eliteBonusGunship1") * level)
"speed", ship.getModifiedItemAttr("eliteBonusGunship1"), skill="Assault Frigates")

View File

@@ -4,6 +4,5 @@
# Ship: Hawk
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Assault Frigates").level
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"),
"maxVelocity", ship.getModifiedItemAttr("eliteBonusGunship1") * level)
"maxVelocity", ship.getModifiedItemAttr("eliteBonusGunship1"), skill="Assault Frigates")

View File

@@ -4,6 +4,5 @@
# Ship: Cambion
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Assault Frigates").level
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Missile Launcher Rocket",
"speed", ship.getModifiedItemAttr("eliteBonusGunship1") * level)
"speed", ship.getModifiedItemAttr("eliteBonusGunship1"), skill="Assault Frigates")

View File

@@ -4,5 +4,4 @@
# Ship: Sin
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Black Ops").level
fit.ship.boostItemAttr("agility", ship.getModifiedItemAttr("eliteBonusBlackOps1") * level)
fit.ship.boostItemAttr("agility", ship.getModifiedItemAttr("eliteBonusBlackOps1"), skill="Black Ops")

View File

@@ -5,5 +5,4 @@
type = "passive"
def handler(fit, ship, context):
if fit.extraAttributes["cloaked"]:
level = fit.character.getSkill("Black Ops").level
fit.ship.multiplyItemAttr("maxVelocity", ship.getModifiedItemAttr("eliteBonusBlackOps2") * level)
fit.ship.multiplyItemAttr("maxVelocity", ship.getModifiedItemAttr("eliteBonusBlackOps2"), skill="Black Ops")

View File

@@ -4,8 +4,7 @@
# Ship: Widow
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Black Ops").level
sensorTypes = ("Gravimetric", "Ladar", "Magnetometric", "Radar")
for type in sensorTypes:
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "ECM Burst", "scan{0}StrengthBonus".format(type),
ship.getModifiedItemAttr("eliteBonusBlackOps1") * level)
ship.getModifiedItemAttr("eliteBonusBlackOps1"), skill="Black Ops")

View File

@@ -4,8 +4,7 @@
# Ship: Widow
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Black Ops").level
sensorTypes = ("Gravimetric", "Ladar", "Magnetometric", "Radar")
for type in sensorTypes:
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "ECM", "scan{0}StrengthBonus".format(type),
ship.getModifiedItemAttr("eliteBonusBlackOps1") * level)
ship.getModifiedItemAttr("eliteBonusBlackOps1"), skill="Black Ops")

View File

@@ -4,6 +4,5 @@
# Ship: Redeemer
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Black Ops").level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Large Energy Turret"),
"trackingSpeed", ship.getModifiedItemAttr("eliteBonusBlackOps1") * level)
"trackingSpeed", ship.getModifiedItemAttr("eliteBonusBlackOps1"), skill="Black Ops")

View File

@@ -4,5 +4,4 @@
# Ship: Panther
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Black Ops").level
fit.ship.boostItemAttr("maxVelocity", ship.getModifiedItemAttr("eliteBonusBlackOps1") * level)
fit.ship.boostItemAttr("maxVelocity", ship.getModifiedItemAttr("eliteBonusBlackOps1"), skill="Black Ops")

View File

@@ -4,6 +4,5 @@
# Ships from group: Command Ship (4 of 8)
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Command Ships").level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Warfare Specialist"),
"commandBonus", ship.getModifiedItemAttr("eliteBonusCommandShips3") * level)
"commandBonus", ship.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")

View File

@@ -4,5 +4,4 @@
# Ship: Damnation
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Command Ships").level
fit.ship.boostItemAttr("armorHP", ship.getModifiedItemAttr("eliteBonusCommandShips1") * level)
fit.ship.boostItemAttr("armorHP", ship.getModifiedItemAttr("eliteBonusCommandShips1"), skill="Command Ships")

View File

@@ -5,6 +5,5 @@
# Ship: Nighthawk
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Command Ships").level
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Missile Launcher Heavy Assault",
"speed", ship.getModifiedItemAttr("eliteBonusCommandShips1") * level)
"speed", ship.getModifiedItemAttr("eliteBonusCommandShips1"), skill="Command Ships")

View File

@@ -4,8 +4,7 @@
# Ship: Damnation
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Command Ships").level
damageTypes = ("em", "explosive", "kinetic", "thermal")
for damageType in damageTypes:
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Heavy Assault Missiles"),
"{0}Damage".format(damageType), ship.getModifiedItemAttr("eliteBonusCommandShips2") * level)
"{0}Damage".format(damageType), ship.getModifiedItemAttr("eliteBonusCommandShips2"), skill="Command Ships")

View File

@@ -4,6 +4,5 @@
# Ship: Eos
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Command Ships").level
fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Heavy Drone Operation"),
"trackingSpeed", ship.getModifiedItemAttr("eliteBonusCommandShips2") * level)
"trackingSpeed", ship.getModifiedItemAttr("eliteBonusCommandShips2"), skill="Command Ships")

View File

@@ -4,6 +4,5 @@
# Ship: Eos
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Command Ships").level
fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Heavy Drone Operation"),
"maxVelocity", ship.getModifiedItemAttr("eliteBonusCommandShips2") * level)
"maxVelocity", ship.getModifiedItemAttr("eliteBonusCommandShips2"), skill="Command Ships")

View File

@@ -4,8 +4,7 @@
# Ship: Damnation
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Command Ships").level
damageTypes = ("em", "explosive", "kinetic", "thermal")
for damageType in damageTypes:
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Heavy Missiles"),
"{0}Damage".format(damageType), ship.getModifiedItemAttr("eliteBonusCommandShips2") * level)
"{0}Damage".format(damageType), ship.getModifiedItemAttr("eliteBonusCommandShips2"), skill="Command Ships")

View File

@@ -5,6 +5,5 @@
# Ship: Nighthawk
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Command Ships").level
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Missile Launcher Heavy",
"speed", ship.getModifiedItemAttr("eliteBonusCommandShips1") * level)
"speed", ship.getModifiedItemAttr("eliteBonusCommandShips1"), skill="Command Ships")

View File

@@ -4,6 +4,5 @@
# Ship: Astarte
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Command Ships").level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Hybrid Turret"),
"falloff", ship.getModifiedItemAttr("eliteBonusCommandShips2") * level)
"falloff", ship.getModifiedItemAttr("eliteBonusCommandShips2"), skill="Command Ships")

View File

@@ -4,6 +4,5 @@
# Ship: Vulture
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Command Ships").level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Hybrid Turret"),
"maxRange", ship.getModifiedItemAttr("eliteBonusCommandShips1") * level)
"maxRange", ship.getModifiedItemAttr("eliteBonusCommandShips1"), skill="Command Ships")

View File

@@ -4,6 +4,5 @@
# Ships from group: Command Ship (4 of 8)
type = "passive"
def handler(fit, module, context):
level = fit.character.getSkill("Command Ships").level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Warfare Specialist"),
"commandBonus", module.getModifiedItemAttr("eliteBonusCommandShips3") * level)
"commandBonus", module.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")

View File

@@ -4,6 +4,5 @@
# Ships from group: Command Ship (4 of 8)
type = "passive"
def handler(fit, module, context):
level = fit.character.getSkill("Command Ships").level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Warfare Specialist"),
"commandBonusHidden", module.getModifiedItemAttr("eliteBonusCommandShips3") * level)
"commandBonusHidden", module.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")

View File

@@ -4,6 +4,5 @@
# Ship: Absolution
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Command Ships").level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Energy Turret"),
"damageMultiplier", ship.getModifiedItemAttr("eliteBonusCommandShips1") * level)
"damageMultiplier", ship.getModifiedItemAttr("eliteBonusCommandShips1"), skill="Command Ships")

View File

@@ -4,6 +4,5 @@
# Ship: Absolution
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Command Ships").level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Energy Turret"),
"speed", ship.getModifiedItemAttr("eliteBonusCommandShips2") * level)
"speed", ship.getModifiedItemAttr("eliteBonusCommandShips2"), skill="Command Ships")

View File

@@ -4,6 +4,5 @@
# Ship: Vulture
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Command Ships").level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Hybrid Turret"),
"damageMultiplier", ship.getModifiedItemAttr("eliteBonusCommandShips2") * level)
"damageMultiplier", ship.getModifiedItemAttr("eliteBonusCommandShips2"), skill="Command Ships")

View File

@@ -4,6 +4,5 @@
# Ship: Astarte
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Command Ships").level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Hybrid Turret"),
"speed", ship.getModifiedItemAttr("eliteBonusCommandShips1") * level)
"speed", ship.getModifiedItemAttr("eliteBonusCommandShips1"), skill="Command Ships")

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