Compare commits
569 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fb997ab16d | ||
|
|
8fe5f43875 | ||
|
|
c8cfee3511 | ||
|
|
bf0b89f3b5 | ||
|
|
1d295c04e3 | ||
|
|
11ebde87c9 | ||
|
|
88c4de9820 | ||
|
|
09e0a0576c | ||
|
|
fc84c5dc94 | ||
|
|
687ebbc41b | ||
|
|
0abe953a70 | ||
|
|
2a8f3e4855 | ||
|
|
8cd36f3cbf | ||
|
|
5577e1976b | ||
|
|
4b27becb5f | ||
|
|
3c055b78d3 | ||
|
|
eb5ce91cb2 | ||
|
|
ef36dc5ba3 | ||
|
|
d9c710c5a1 | ||
|
|
c436e0e669 | ||
|
|
e80917e3d1 | ||
|
|
0d0ec42daf | ||
|
|
0e4cca6138 | ||
|
|
b701acb275 | ||
|
|
4eb61051c6 | ||
|
|
56aba37758 | ||
|
|
f432b08149 | ||
|
|
3e0b2fd09c | ||
|
|
c7b8d94e4f | ||
|
|
31a9b03436 | ||
|
|
f33f558006 | ||
|
|
bb4fe63a7c | ||
|
|
ccb9e085b2 | ||
|
|
702d249bad | ||
|
|
cc2835a341 | ||
|
|
d73c53cb10 | ||
|
|
73409a3324 | ||
|
|
24f770aa7b | ||
|
|
649b99d7bd | ||
|
|
a8b50032c4 | ||
|
|
d1d276ae68 | ||
|
|
6eafbb0a25 | ||
|
|
aedd7ce2de | ||
|
|
b0511ed856 | ||
|
|
d60b288e0e | ||
|
|
f7d5287087 | ||
|
|
7032baa7ef | ||
|
|
b52cbef26f | ||
|
|
34f699b96a | ||
|
|
5b341dfc06 | ||
|
|
cb0003b942 | ||
|
|
6ee6186280 | ||
|
|
781abeea53 | ||
|
|
6496164d95 | ||
|
|
1ce2921eb7 | ||
|
|
6eb6925606 | ||
|
|
9d7a3605dc | ||
|
|
056e961ccc | ||
|
|
8f08f8efb8 | ||
|
|
167eb60fe3 | ||
|
|
c04b7e0552 | ||
|
|
ff87d5e456 | ||
|
|
c81774a3aa | ||
|
|
a5920a9c9c | ||
|
|
c103e563a9 | ||
|
|
08382db011 | ||
|
|
9929510e53 | ||
|
|
f6cddcc86d | ||
|
|
953a70327a | ||
|
|
6e04c64ffb | ||
|
|
e0f99ee133 | ||
|
|
6ed81e9bae | ||
|
|
69a4e42ab0 | ||
|
|
8151debfe1 | ||
|
|
972df6cad3 | ||
|
|
b1729095a0 | ||
|
|
23dbb59f3f | ||
|
|
9269c54434 | ||
|
|
c4246c0d50 | ||
|
|
d013a41079 | ||
|
|
94995685e9 | ||
|
|
11c3859270 | ||
|
|
1415de9573 | ||
|
|
73de795082 | ||
|
|
bb9760f79c | ||
|
|
53b8ca3940 | ||
|
|
8a9107c798 | ||
|
|
52f06bbd43 | ||
|
|
5246432420 | ||
|
|
8ccdbcc51d | ||
|
|
81c2895c9e | ||
|
|
cbb31c1217 | ||
|
|
6c80d15f1d | ||
|
|
4baa6e9e9f | ||
|
|
2e998bd5a4 | ||
|
|
a33ec89e87 | ||
|
|
ba9232e514 | ||
|
|
f090cafa5c | ||
|
|
a67b46bb9a | ||
|
|
f17fb82ce7 | ||
|
|
3f6c484c99 | ||
|
|
11cf4b356c | ||
|
|
231cdb8399 | ||
|
|
30f077027b | ||
|
|
8a2c4671bf | ||
|
|
35f56b9c32 | ||
|
|
ae3bd9d9d4 | ||
|
|
9465aceddb | ||
|
|
8e353b08ae | ||
|
|
a5f1370eec | ||
|
|
b454ac003b | ||
|
|
17d353e09b | ||
|
|
365cacac66 | ||
|
|
30fef3039c | ||
|
|
6f161b495f | ||
|
|
582e54e758 | ||
|
|
072fac4259 | ||
|
|
4e890e1e1d | ||
|
|
473b70944f | ||
|
|
37b158439d | ||
|
|
2617143330 | ||
|
|
a3b108382e | ||
|
|
e07c162453 | ||
|
|
0f8992432b | ||
|
|
c751544560 | ||
|
|
1d51e86c1c | ||
|
|
05b9d1e607 | ||
|
|
2a88e3114b | ||
|
|
a0f9fb6ad6 | ||
|
|
b844bdf986 | ||
|
|
61614553a2 | ||
|
|
ae870f9535 | ||
|
|
30a8437515 | ||
|
|
8647fa245f | ||
|
|
23bb763c51 | ||
|
|
c158cb076f | ||
|
|
b1ebf8562a | ||
|
|
e9d02ce4c8 | ||
|
|
ec6914d4aa | ||
|
|
474f270b26 | ||
|
|
fb7574e476 | ||
|
|
760b5f3d74 | ||
|
|
51c481206c | ||
|
|
7b6b922c57 | ||
|
|
a08bb2494b | ||
|
|
4affc24ec7 | ||
|
|
d7cb0d536f | ||
|
|
bf9a4b4919 | ||
|
|
3ea4439b8d | ||
|
|
bd53785667 | ||
|
|
f2b4400834 | ||
|
|
b8d01d5ecb | ||
|
|
9ae5cfbab2 | ||
|
|
045031e8ae | ||
|
|
2c7bfd14b6 | ||
|
|
1584586fd2 | ||
|
|
1402ceec63 | ||
|
|
4663270067 | ||
|
|
0b9cdaa944 | ||
|
|
89c011d37e | ||
|
|
c72f049ccd | ||
|
|
ca34217f3b | ||
|
|
3521b3887d | ||
|
|
492776c5a8 | ||
|
|
51a8076d30 | ||
|
|
decf7ff028 | ||
|
|
31b1c94c0f | ||
|
|
a9fc457510 | ||
|
|
7c3c8182a7 | ||
|
|
b162927f79 | ||
|
|
6dbed1403a | ||
|
|
aa5eb7ac92 | ||
|
|
e0fbcc91f1 | ||
|
|
b2dce223b0 | ||
|
|
4b7b22025c | ||
|
|
8e37dab37e | ||
|
|
6e95f69565 | ||
|
|
31331b1e34 | ||
|
|
05b3777ad2 | ||
|
|
cda8dd4c8b | ||
|
|
e7542fec44 | ||
|
|
e7fcdd86ac | ||
|
|
d909e8adc4 | ||
|
|
def20311a8 | ||
|
|
503907e2d8 | ||
|
|
88dc1edfb4 | ||
|
|
cbedf03026 | ||
|
|
a69589dd23 | ||
|
|
2904ab6afa | ||
|
|
c763595cc4 | ||
|
|
8fe97180ed | ||
|
|
6a4b2ffe69 | ||
|
|
7f100353e2 | ||
|
|
97ac0804c5 | ||
|
|
48f96a7a32 | ||
|
|
598512a904 | ||
|
|
121a81ce70 | ||
|
|
a2e031cf27 | ||
|
|
f18ba6160a | ||
|
|
c2ca5dffe8 | ||
|
|
ab7bbcb6ef | ||
|
|
e5e7311748 | ||
|
|
9ba3ca3f5f | ||
|
|
cc59612fa4 | ||
|
|
01db1efdf7 | ||
|
|
e74e2615ad | ||
|
|
2f246d0897 | ||
|
|
505b0ce38f | ||
|
|
8c19a956e0 | ||
|
|
9de3600d7f | ||
|
|
5a4f526b2b | ||
|
|
cd0b0eada0 | ||
|
|
17733d5951 | ||
|
|
0a1f324053 | ||
|
|
e12b3f3054 | ||
|
|
b32f76cfde | ||
|
|
182104a010 | ||
|
|
90c883da67 | ||
|
|
ac08b1b264 | ||
|
|
f17d015ebe | ||
|
|
d496637614 | ||
|
|
4596c526a2 | ||
|
|
9941b6c74b | ||
|
|
b06ce24d4a | ||
|
|
2f8c201ab3 | ||
|
|
d184820728 | ||
|
|
40aeb1ed4a | ||
|
|
71b258a8f5 | ||
|
|
cd7579a4bf | ||
|
|
d6199a58c2 | ||
|
|
3ad5aaac89 | ||
|
|
3bed268d81 | ||
|
|
9a1b0f07c0 | ||
|
|
f591ecba10 | ||
|
|
c571fdc5e6 | ||
|
|
6f944fc7db | ||
|
|
63fce4be17 | ||
|
|
86ee5292d8 | ||
|
|
0060f58e3d | ||
|
|
23b458534f | ||
|
|
2256efacb0 | ||
|
|
28a5318e3b | ||
|
|
609ee13cd6 | ||
|
|
4216904736 | ||
|
|
496e9b56b5 | ||
|
|
b8f73a7c94 | ||
|
|
b4604f8207 | ||
|
|
68dddf2810 | ||
|
|
4c17f38b1a | ||
|
|
221a3fde14 | ||
|
|
c17e03d8d0 | ||
|
|
af9f64db5f | ||
|
|
1f82465a65 | ||
|
|
d885bd4636 | ||
|
|
c17bce55bb | ||
|
|
4137a7cda9 | ||
|
|
c92911b79a | ||
|
|
adc9fb6d00 | ||
|
|
5baf70694a | ||
|
|
f08dc97576 | ||
|
|
35094ae1ce | ||
|
|
5ac31920ee | ||
|
|
e63c3541c4 | ||
|
|
4976516d4d | ||
|
|
e042a21d32 | ||
|
|
8a22907940 | ||
|
|
a97847e644 | ||
|
|
23309a5da6 | ||
|
|
06e4a7e80f | ||
|
|
b95a10d284 | ||
|
|
2bca3ddcc8 | ||
|
|
9ef182aa99 | ||
|
|
5e56107582 | ||
|
|
972c08e7e4 | ||
|
|
091832af21 | ||
|
|
16d1891e16 | ||
|
|
40ee68e2cf | ||
|
|
bfe3b4a26d | ||
|
|
9aa1332b15 | ||
|
|
0521d242eb | ||
|
|
2b3f3773e5 | ||
|
|
4041407878 | ||
|
|
1b5e0467fc | ||
|
|
a7c346f78e | ||
|
|
3cc51aaf89 | ||
|
|
a339ae1c55 | ||
|
|
3773d1c28e | ||
|
|
41b8db346f | ||
|
|
7959593c6c | ||
|
|
aaa60cbc14 | ||
|
|
8ae5a96047 | ||
|
|
8c90b3132b | ||
|
|
1326e21f6b | ||
|
|
bfdc2161e0 | ||
|
|
9ab79af70c | ||
|
|
f0de2000bf | ||
|
|
5991d19b3e | ||
|
|
51fed996f1 | ||
|
|
f6bbc6c410 | ||
|
|
3de6b63325 | ||
|
|
dd48815f30 | ||
|
|
5608676dc8 | ||
|
|
86ab1f7444 | ||
|
|
8f51642f70 | ||
|
|
de71123a48 | ||
|
|
874cf4ef0a | ||
|
|
87e5929cb1 | ||
|
|
84b1e0ac41 | ||
|
|
539360d5f6 | ||
|
|
ca08f8d8da | ||
|
|
e1ce672569 | ||
|
|
717080b58c | ||
|
|
51696c509f | ||
|
|
4a5ae9f6f1 | ||
|
|
fa9f324f78 | ||
|
|
bcc77f11cd | ||
|
|
f737f292e3 | ||
|
|
1c18a5207c | ||
|
|
fa2b1e3821 | ||
|
|
6184753822 | ||
|
|
91a9c860ea | ||
|
|
0730ac369f | ||
|
|
aaa5a6ae18 | ||
|
|
5372f31be8 | ||
|
|
6d01877d78 | ||
|
|
646f3afd27 | ||
|
|
030f22b66f | ||
|
|
98815f2b85 | ||
|
|
a4fe3fe142 | ||
|
|
5b0857e169 | ||
|
|
975a414c5f | ||
|
|
95eb5a6117 | ||
|
|
8a7e69b902 | ||
|
|
dc035469ed | ||
|
|
ec4a00cdfc | ||
|
|
21937c02ff | ||
|
|
edfd446e46 | ||
|
|
7ec78b941e | ||
|
|
95bf1039c0 | ||
|
|
e6def6f5f9 | ||
|
|
de0b03630a | ||
|
|
90a2a79d5b | ||
|
|
21efd6d06a | ||
|
|
ea288a6133 | ||
|
|
da16f6cee7 | ||
|
|
f285395e0f | ||
|
|
b54e3aeaf9 | ||
|
|
23baaa7dba | ||
|
|
8008c986d3 | ||
|
|
b9efc919ea | ||
|
|
6cc6fd9468 | ||
|
|
53c9169043 | ||
|
|
eb2f4991ee | ||
|
|
16017a3c31 | ||
|
|
98d9adef8a | ||
|
|
9e96aac04d | ||
|
|
3395f8ebe6 | ||
|
|
1d45102100 | ||
|
|
1694d74afa | ||
|
|
9c9f1dcefa | ||
|
|
a4ca2e90f9 | ||
|
|
dbfcfd9acf | ||
|
|
8c30ee3fd3 | ||
|
|
ca17d17232 | ||
|
|
b78c0a5845 | ||
|
|
ef6e25bfce | ||
|
|
e81f7eb765 | ||
|
|
26122f6da7 | ||
|
|
e7264108dd | ||
|
|
2bcbb03c10 | ||
|
|
9cf20942f1 | ||
|
|
dbb98e981a | ||
|
|
3ae39b2e7c | ||
|
|
7b43b516c9 | ||
|
|
12d6a2c5de | ||
|
|
26bba49193 | ||
|
|
4e69a2656c | ||
|
|
68d504c79d | ||
|
|
2180b1ac3b | ||
|
|
32712a8798 | ||
|
|
73c7ad55b6 | ||
|
|
a34c5ace5c | ||
|
|
fd77661f41 | ||
|
|
ad07cf25d8 | ||
|
|
4daf1b1ba3 | ||
|
|
4b189ab146 | ||
|
|
64a69e3910 | ||
|
|
9482404ca7 | ||
|
|
124d4fab9b | ||
|
|
722406f636 | ||
|
|
6d4957b148 | ||
|
|
cca7f1112a | ||
|
|
c809a614f9 | ||
|
|
2c366faa66 | ||
|
|
06252d761d | ||
|
|
bb8d5d0d65 | ||
|
|
7606bded40 | ||
|
|
daaf48d02a | ||
|
|
d18cf7b3b0 | ||
|
|
33a0c10650 | ||
|
|
2077655694 | ||
|
|
0dc3cbb7c7 | ||
|
|
a3c19f6f2b | ||
|
|
f97b037011 | ||
|
|
dd3dd799b2 | ||
|
|
ac881ac371 | ||
|
|
d734ccbf0d | ||
|
|
024e0ad4f5 | ||
|
|
545d98883a | ||
|
|
742abc3250 | ||
|
|
294e213ac2 | ||
|
|
557f32ab91 | ||
|
|
e5430cac84 | ||
|
|
39c14b62fd | ||
|
|
940035fa8c | ||
|
|
5eaaaf070b | ||
|
|
0bc9264c28 | ||
|
|
cb1de9589e | ||
|
|
370e34cff9 | ||
|
|
28c3fc720f | ||
|
|
04b3a687fc | ||
|
|
629f6e60a4 | ||
|
|
f801d7905c | ||
|
|
694a2a3d9b | ||
|
|
222888984a | ||
|
|
bb96ecb647 | ||
|
|
e082077dfc | ||
|
|
a31769bde3 | ||
|
|
be7e8be85b | ||
|
|
b16d2eae15 | ||
|
|
0ef05ffaf8 | ||
|
|
9ee7671a3c | ||
|
|
ca301f8d5b | ||
|
|
471261275a | ||
|
|
55f2f3bfe8 | ||
|
|
3ce673d8af | ||
|
|
3e2053b2dd | ||
|
|
931e48d9a0 | ||
|
|
6c19f446be | ||
|
|
d4842c2f8e | ||
|
|
dc77ee9353 | ||
|
|
6d29fd6bc1 | ||
|
|
cbcd5ccca5 | ||
|
|
30d2ab23ad | ||
|
|
f4f028b843 | ||
|
|
ef62f102bc | ||
|
|
7b8bb79cbe | ||
|
|
3a26790109 | ||
|
|
c861adc5ed | ||
|
|
36a3ac70b6 | ||
|
|
54d1b35ce7 | ||
|
|
675213f20f | ||
|
|
3a9e1f8b85 | ||
|
|
e520758334 | ||
|
|
073309de0a | ||
|
|
1bce724190 | ||
|
|
2c47d0758e | ||
|
|
8f7ae4b00c | ||
|
|
f11f3bfb79 | ||
|
|
68703f3db5 | ||
|
|
ad18560412 | ||
|
|
d3def54b5a | ||
|
|
27d72ed909 | ||
|
|
55e45b6bc1 | ||
|
|
252f56732b | ||
|
|
d52e88cdaa | ||
|
|
371e33764e | ||
|
|
9b8b7aba07 | ||
|
|
0a6274474e | ||
|
|
0ff69068c0 | ||
|
|
731477b366 | ||
|
|
0295f04ec4 | ||
|
|
059af217aa | ||
|
|
2a391fa38b | ||
|
|
88b1426fe0 | ||
|
|
07da5aa861 | ||
|
|
192d6f4605 | ||
|
|
487f65d62b | ||
|
|
c202aefd2e | ||
|
|
0ed91e4079 | ||
|
|
9c2a667635 | ||
|
|
19579fb087 | ||
|
|
ea77e6851e | ||
|
|
1c3f9ccf5b | ||
|
|
e42671fbec | ||
|
|
18c86daea6 | ||
|
|
c59b818677 | ||
|
|
71bf1556a1 | ||
|
|
26e50f2e8a | ||
|
|
25e30672fe | ||
|
|
e8268633e3 | ||
|
|
1b3c058eab | ||
|
|
adcae42ae7 | ||
|
|
238712e62c | ||
|
|
f2b959895e | ||
|
|
ffb7719937 | ||
|
|
3c1bf22e87 | ||
|
|
e0488dce4f | ||
|
|
88074c8516 | ||
|
|
359840aee8 | ||
|
|
77e3a0f666 | ||
|
|
3d4eef2466 | ||
|
|
663cf7104c | ||
|
|
0d6a55dcb6 | ||
|
|
85608616dd | ||
|
|
d5ce666d8d | ||
|
|
2bff11e5ab | ||
|
|
5adaaac75e | ||
|
|
a49269b759 | ||
|
|
a96efaee1a | ||
|
|
299de38bf6 | ||
|
|
b29019f0a7 | ||
|
|
da15b63831 | ||
|
|
20b2f1e5fc | ||
|
|
f1cdabf37c | ||
|
|
94e1c7aba3 | ||
|
|
797db36a42 | ||
|
|
ac18c58a0a | ||
|
|
281850d7df | ||
|
|
2e460adbc9 | ||
|
|
5660b2b8ed | ||
|
|
de9fbd672f | ||
|
|
85029f6be8 | ||
|
|
337db326fd | ||
|
|
795230dae6 | ||
|
|
022a929399 | ||
|
|
b64238634a | ||
|
|
4b0e0300ad | ||
|
|
7762bb365f | ||
|
|
dfec7d8fa2 | ||
|
|
5c5ec60efd | ||
|
|
2a7e35ff6f | ||
|
|
d7ab709d52 | ||
|
|
831478e034 | ||
|
|
d0b5f3ad78 | ||
|
|
190c1f135f | ||
|
|
374d6d6d34 | ||
|
|
edbdaf5631 | ||
|
|
23a71e7448 | ||
|
|
892c5c5b60 | ||
|
|
081e32da6f | ||
|
|
7100e8997b | ||
|
|
9a8642e789 | ||
|
|
a565abe6f7 | ||
|
|
b93b59fe4d | ||
|
|
9782ca3a29 | ||
|
|
f9fd894c9f | ||
|
|
ee8395e8fd | ||
|
|
7836506444 | ||
|
|
8df7593223 | ||
|
|
8351b0fc9d | ||
|
|
88ee1d60be | ||
|
|
dda1494b90 | ||
|
|
f53384c4c2 | ||
|
|
d4af877e47 | ||
|
|
5242c6df60 | ||
|
|
8c1d14ec4a | ||
|
|
f187caa549 | ||
|
|
70d52fd0b2 | ||
|
|
222ee22fe3 | ||
|
|
76f1f217e1 | ||
|
|
6f42e7c286 | ||
|
|
ff55f2817b | ||
|
|
198ee8d129 | ||
|
|
7db13bd3ba | ||
|
|
5be0d4b70e | ||
|
|
a603a4359a | ||
|
|
b4f4024903 | ||
|
|
df18651b4f |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -11,8 +11,13 @@
|
||||
|
||||
#Patch files
|
||||
*.patch
|
||||
|
||||
#Personal
|
||||
/saveddata
|
||||
/saveddata/
|
||||
|
||||
#PyCharm
|
||||
.idea/
|
||||
|
||||
#Pyfa file
|
||||
pyfaFits.html
|
||||
build/
|
||||
|
||||
@@ -549,14 +549,14 @@ to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU General Public License.
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU General Public License into a single
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU General Public License,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
48
README.md
48
README.md
@@ -1,15 +1,47 @@
|
||||
# Pyfa
|
||||
# pyfa
|
||||
|
||||
Pyfa is a cross-platform desktop fitting application for EVE online that can be used natively on any platform where python and wxwidgets are available.
|
||||

|
||||
|
||||
It provides many advanced features such as graphs and full calculations of any possible combination of modules, fits, etc.
|
||||
## What is it?
|
||||
|
||||
Please see the [FAQ](https://github.com/DarkFenX/Pyfa/wiki/FAQ) for answers to common questions / concerns
|
||||
pyfa, short for **py**thon **f**itting **a**ssistant, allows you to create, experiment with, and save ship fittings without being in game. Open source and written in Python, it is available on any platform where Python 2.x and wxWidgets are available, including Windows, Mac OS X, and Linux.
|
||||
|
||||
#### Links
|
||||
* [Development repository: http://github.com/DarkFenX/Pyfa](http://github.com/DarkFenX/Pyfa)
|
||||
* [XMPP conference:
|
||||
pyfa@conference.jabber.org](pyfa@conference.jabber.org)
|
||||
## Latest Version and Changelogs
|
||||
The latest version along with release notes can always be found on the projects [Releases](https://github.com/DarkFenX/Pyfa/releases) page. pyfa will notify you if you are running an outdated version.
|
||||
|
||||
## Installing
|
||||
Windows and OS X users are supplied self-contained builds of pyfa that can be run without additional software. An `.exe` installer is also available for the Windows builds. There is no self-contained package for Linux users, which are expected to run pyfa through their distributions Python interpreter. However, there are a number of third-party packages available that handle the dependencies and updates for pyfa (for example, [pyfa for Arch Linux](https://aur.archlinux.org/packages/pyfa/)). Please check your distributions repositories.
|
||||
|
||||
## Requirements
|
||||
If you wish to help with development or simply need to run pyfa through a Python interpreter, the following software is required:
|
||||
|
||||
* Python >= 2.6
|
||||
* `wxPython` 2.8/3.0
|
||||
* `sqlalchemy` >= 0.6
|
||||
* `dateutil`
|
||||
* `matplotlib` (for some Linux distributions, you may need to install separate wxPython bindings, such as `python-matplotlib-wx`)
|
||||
|
||||
## Bug Reporting
|
||||
The preferred method of reporting bugs is through the projects GitHub Issues interface. Alternatively, posting a report in the pyfa thread on the official EVE Online forums is acceptable. Guidelines for bug reporting can be found on [this wiki page](https://github.com/DarkFenX/Pyfa/wiki/Bug-Reporting).
|
||||
|
||||
## Liscense
|
||||
pyfa is licensed under the GNU GPL v3.0, see LICENSE
|
||||
|
||||
## Resources
|
||||
* Development repository: [http://github.com/DarkFenX/Pyfa](http://github.com/DarkFenX/Pyfa)
|
||||
* XMPP conference: [pyfa@conference.jabber.org](pyfa@conference.jabber.org)
|
||||
* [EVE forum thread](http://forums.eveonline.com/default.aspx?g=posts&t=247609)
|
||||
* [EVE University guide using pyfa](http://wiki.eveuniversity.org/Guide_to_using_PYFA)
|
||||
* [EVE Online website](http://www.eveonline.com/)
|
||||
|
||||
## Contacts:
|
||||
* Kadesh Priestess
|
||||
* GitHub: @DarkFenX
|
||||
* [TweetFleet Slack](https://www.fuzzwork.co.uk/tweetfleet-slack-invites/): @kadesh
|
||||
* Sable Blitzmann
|
||||
* GitHub: @blitzmann
|
||||
* [TweetFleet Slack](https://www.fuzzwork.co.uk/tweetfleet-slack-invites/): @blitzmann
|
||||
* Email: sable.blitzmann@gmail.com
|
||||
|
||||
## CCP Copyright Notice
|
||||
EVE Online, the EVE logo, EVE and all associated logos and designs are the intellectual property of CCP hf. All artwork, screenshots, characters, vehicles, storylines, world facts or other recognizable features of the intellectual property relating to these trademarks are likewise the intellectual property of CCP hf. EVE Online and the EVE logo are the registered trademarks of CCP hf. All rights are reserved worldwide. All other trademarks are the property of their respective owners. CCP hf. has granted permission to Osmium to use EVE Online and all associated logos and designs for promotional and information purposes on its website but does not endorse, and is not in any way affiliated with, Osmium. CCP is in no way responsible for the content on or functioning of this website, nor can it be liable for any damage arising from the use of this website.
|
||||
|
||||
222
config.py
222
config.py
@@ -1,90 +1,132 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
# Load variable overrides specific to distribution type
|
||||
try:
|
||||
import configforced
|
||||
except ImportError:
|
||||
configforced = None
|
||||
|
||||
# Turns on debug mode
|
||||
debug = False
|
||||
# Defines if our saveddata will be in pyfa root or not
|
||||
saveInRoot = False
|
||||
|
||||
# Version data
|
||||
version = "1.6.1"
|
||||
tag = "Stable"
|
||||
expansionName = "Phoebe"
|
||||
expansionVersion = "1.0"
|
||||
evemonMinVersion = "4081"
|
||||
|
||||
# Database version (int ONLY)
|
||||
# Increment every time we need to flag for user database upgrade/modification
|
||||
dbversion = 2
|
||||
|
||||
pyfaPath = None
|
||||
savePath = None
|
||||
staticPath = None
|
||||
saveDB = None
|
||||
gameDB = None
|
||||
|
||||
def defPaths():
|
||||
global pyfaPath
|
||||
global savePath
|
||||
global staticPath
|
||||
global saveDB
|
||||
global gameDB
|
||||
global saveInRoot
|
||||
# The main pyfa directory which contains run.py
|
||||
# Python 2.X uses ANSI by default, so we need to convert the character encoding
|
||||
pyfaPath = getattr(configforced, "pyfaPath", pyfaPath)
|
||||
if pyfaPath is None:
|
||||
pyfaPath = unicode(os.path.dirname(os.path.realpath(os.path.abspath(
|
||||
sys.modules['__main__'].__file__))), sys.getfilesystemencoding())
|
||||
|
||||
# Where we store the saved fits etc, default is the current users home directory
|
||||
if saveInRoot is True:
|
||||
savePath = getattr(configforced, "savePath", None)
|
||||
if savePath is None:
|
||||
savePath = os.path.join(pyfaPath, "saveddata")
|
||||
else:
|
||||
savePath = getattr(configforced, "savePath", None)
|
||||
if savePath is None:
|
||||
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")
|
||||
|
||||
# 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")
|
||||
|
||||
# Static EVE Data from the staticdata repository, should be in the staticdata
|
||||
# directory in our pyfa directory
|
||||
staticPath = os.path.join(pyfaPath, "staticdata")
|
||||
|
||||
# The database where we store all the fits etc
|
||||
saveDB = os.path.join(savePath, "saveddata.db")
|
||||
|
||||
# The database where the static EVE data from the datadump is kept.
|
||||
# This is not the standard sqlite datadump but a modified version created by eos
|
||||
# maintenance script
|
||||
gameDB = os.path.join(staticPath, "eve.db")
|
||||
|
||||
## DON'T MODIFY ANYTHING BELOW ##
|
||||
import eos.config
|
||||
|
||||
#Caching modifiers, disable all gamedata caching, its unneeded.
|
||||
eos.config.gamedataCache = False
|
||||
# saveddata db location modifier, shouldn't ever need to touch this
|
||||
eos.config.saveddata_connectionstring = "sqlite:///" + saveDB + "?check_same_thread=False"
|
||||
eos.config.gamedata_connectionstring = "sqlite:///" + gameDB + "?check_same_thread=False"
|
||||
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
|
||||
except ImportError:
|
||||
configforced = None
|
||||
|
||||
# Turns on debug mode
|
||||
debug = False
|
||||
# Defines if our saveddata will be in pyfa root or not
|
||||
saveInRoot = False
|
||||
|
||||
# Version data
|
||||
version = "1.16.1"
|
||||
tag = "Stable"
|
||||
expansionName = "Parallax"
|
||||
expansionVersion = "1.0"
|
||||
evemonMinVersion = "4081"
|
||||
|
||||
pyfaPath = None
|
||||
savePath = 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 isFrozen():
|
||||
if hasattr(sys, 'frozen'):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def getPyfaRoot():
|
||||
base = getattr(sys.modules['__main__'], "__file__", sys.executable) if isFrozen() else sys.argv[0]
|
||||
root = os.path.dirname(os.path.realpath(os.path.abspath(base)))
|
||||
root = unicode(root, sys.getfilesystemencoding())
|
||||
return root
|
||||
|
||||
def __createDirs(path):
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
|
||||
def defPaths():
|
||||
global debug
|
||||
global pyfaPath
|
||||
global savePath
|
||||
global saveDB
|
||||
global gameDB
|
||||
global saveInRoot
|
||||
|
||||
if debug:
|
||||
logLevel = logging.DEBUG
|
||||
else:
|
||||
logLevel = logging.WARN
|
||||
|
||||
# The main pyfa directory which contains run.py
|
||||
# Python 2.X uses ANSI by default, so we need to convert the character encoding
|
||||
pyfaPath = getattr(configforced, "pyfaPath", pyfaPath)
|
||||
if pyfaPath is None:
|
||||
pyfaPath = getPyfaRoot()
|
||||
|
||||
# Where we store the saved fits etc, default is the current users home directory
|
||||
if saveInRoot is True:
|
||||
savePath = getattr(configforced, "savePath", None)
|
||||
if savePath is None:
|
||||
savePath = os.path.join(pyfaPath, "saveddata")
|
||||
else:
|
||||
savePath = getattr(configforced, "savePath", None)
|
||||
if savePath is None:
|
||||
savePath = unicode(os.path.expanduser(os.path.join("~", ".pyfa")),
|
||||
sys.getfilesystemencoding())
|
||||
|
||||
__createDirs(savePath)
|
||||
|
||||
if isFrozen():
|
||||
os.environ["REQUESTS_CA_BUNDLE"] = os.path.join(pyfaPath, "cacert.pem")
|
||||
|
||||
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
|
||||
|
||||
# This interferes with cx_Freeze's own handling of exceptions. Find a way to fix this.
|
||||
#stderr_logger = logging.getLogger('STDERR')
|
||||
#sl = StreamToLogger(stderr_logger, logging.ERROR)
|
||||
#sys.stderr = sl
|
||||
|
||||
# The database where we store all the fits etc
|
||||
saveDB = os.path.join(savePath, "saveddata.db")
|
||||
|
||||
# The database where the static EVE data from the datadump is kept.
|
||||
# This is not the standard sqlite datadump but a modified version created by eos
|
||||
# maintenance script
|
||||
gameDB = os.path.join(pyfaPath, "eve.db")
|
||||
|
||||
## DON'T MODIFY ANYTHING BELOW ##
|
||||
import eos.config
|
||||
|
||||
#Caching modifiers, disable all gamedata caching, its unneeded.
|
||||
eos.config.gamedataCache = False
|
||||
# saveddata db location modifier, shouldn't ever need to touch this
|
||||
eos.config.saveddata_connectionstring = "sqlite:///" + saveDB + "?check_same_thread=False"
|
||||
eos.config.gamedata_connectionstring = "sqlite:///" + gameDB + "?check_same_thread=False"
|
||||
|
||||
BIN
dist_assets/mac/pyfa.icns
Normal file
BIN
dist_assets/mac/pyfa.icns
Normal file
Binary file not shown.
BIN
dist_assets/win/pyfa.ico
Normal file
BIN
dist_assets/win/pyfa.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 76 KiB |
@@ -59,41 +59,50 @@ class CapSimulator(object):
|
||||
return duration, capNeed
|
||||
|
||||
def init(self, modules):
|
||||
"""prepare modules. a list of (duration, capNeed, clipSize) tuples is
|
||||
"""prepare modules. a list of (duration, capNeed, clipSize, disableStagger) tuples is
|
||||
expected, with clipSize 0 if the module has infinite ammo.
|
||||
"""
|
||||
mods = {}
|
||||
for module in modules:
|
||||
if module in mods:
|
||||
mods[module] += 1
|
||||
else:
|
||||
mods[module] = 1
|
||||
|
||||
self.modules = mods
|
||||
|
||||
self.modules = modules
|
||||
|
||||
def reset(self):
|
||||
"""Reset the simulator state"""
|
||||
self.state = []
|
||||
mods = {}
|
||||
period = 1
|
||||
disable_period = False
|
||||
|
||||
for (duration, capNeed, clipSize), amount in self.modules.iteritems():
|
||||
# Loop over modules, clearing clipSize if applicable, and group modules based on attributes
|
||||
for (duration, capNeed, clipSize, disableStagger) in self.modules:
|
||||
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
|
||||
|
||||
# Group modules based on their properties
|
||||
if (duration, capNeed, clipSize, disableStagger) in mods:
|
||||
mods[(duration, capNeed, clipSize, disableStagger)] += 1
|
||||
else:
|
||||
mods[(duration, capNeed, clipSize, disableStagger)] = 1
|
||||
|
||||
# Loop over grouped modules, configure staggering and push to the simulation state
|
||||
for (duration, capNeed, clipSize, disableStagger), amount in mods.iteritems():
|
||||
if self.stagger and not disableStagger:
|
||||
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
|
||||
@@ -160,13 +169,13 @@ class CapSimulator(object):
|
||||
|
||||
iterations += 1
|
||||
|
||||
t_last = t_now
|
||||
|
||||
if cap < cap_lowest:
|
||||
if cap < 0.0:
|
||||
break
|
||||
cap_lowest = cap
|
||||
|
||||
t_last = t_now
|
||||
|
||||
# queue the next activation of this module
|
||||
t_now += duration
|
||||
shot += 1
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import os.path
|
||||
from os.path import realpath, join, dirname, abspath
|
||||
import sys
|
||||
|
||||
debug = False
|
||||
gamedataCache = True
|
||||
saveddataCache = True
|
||||
gamedata_connectionstring = 'sqlite:///' + os.path.expanduser(os.path.join("~", ".pyfa","eve.db"))
|
||||
saveddata_connectionstring = 'sqlite:///:memory:'
|
||||
gamedata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "eve.db")), sys.getfilesystemencoding())
|
||||
saveddata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "saveddata", "saveddata.db")), sys.getfilesystemencoding())
|
||||
|
||||
#Autodetect path, only change if the autodetection bugs out.
|
||||
path = os.path.dirname(unicode(__file__, sys.getfilesystemencoding()))
|
||||
path = dirname(unicode(__file__, sys.getfilesystemencoding()))
|
||||
|
||||
@@ -40,6 +40,15 @@ gamedata_meta = MetaData()
|
||||
gamedata_meta.bind = gamedata_engine
|
||||
gamedata_session = sessionmaker(bind=gamedata_engine, autoflush=False, expire_on_commit=False)()
|
||||
|
||||
# This should be moved elsewhere, maybe as an actual query. Current, without try-except, it breaks when making a new
|
||||
# game db because we haven't reached gamedata_meta.create_all()
|
||||
try:
|
||||
config.gamedata_version = gamedata_session.execute(
|
||||
"SELECT `field_value` FROM `metadata` WHERE `field_name` LIKE 'client_build'"
|
||||
).fetchone()[0]
|
||||
except:
|
||||
config.gamedata_version = None
|
||||
|
||||
saveddata_connectionstring = config.saveddata_connectionstring
|
||||
if saveddata_connectionstring is not None:
|
||||
if callable(saveddata_connectionstring):
|
||||
@@ -59,13 +68,8 @@ from eos.db.gamedata import *
|
||||
from eos.db.saveddata import *
|
||||
|
||||
#Import queries
|
||||
from eos.db.gamedata.queries import getItem, searchItems, getVariations, getItemsByCategory, directAttributeRequest, \
|
||||
getMarketGroup, getGroup, getCategory, getAttributeInfo, getMetaData, getMetaGroup
|
||||
from eos.db.saveddata.queries import getUser, getCharacter, getFit, getFitsWithShip, countFitsWithShip, searchFits, \
|
||||
getCharacterList, getPrice, getDamagePatternList, getDamagePattern, \
|
||||
getFitList, getFleetList, getFleet, save, remove, commit, add, \
|
||||
getCharactersForUser, getMiscData, getSquadsIDsWithFitID, getWing, \
|
||||
getSquad, getBoosterFits, getProjectedFits, getTargetResistsList, getTargetResists
|
||||
from eos.db.gamedata.queries import *
|
||||
from eos.db.saveddata.queries import *
|
||||
|
||||
#If using in memory saveddata, you'll want to reflect it so the data structure is good.
|
||||
if config.saveddata_connectionstring == "sqlite:///:memory:":
|
||||
@@ -74,3 +78,4 @@ if config.saveddata_connectionstring == "sqlite:///:memory:":
|
||||
def rollback():
|
||||
with sd_lock:
|
||||
saveddata_session.rollback()
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ items_table = Table("invtypes", gamedata_meta,
|
||||
Column("typeName", String, index=True),
|
||||
Column("description", String),
|
||||
Column("raceID", Integer),
|
||||
Column("factionID", Integer),
|
||||
Column("volume", Float),
|
||||
Column("mass", Float),
|
||||
Column("capacity", Float),
|
||||
|
||||
@@ -23,7 +23,7 @@ from eos.types import MetaData
|
||||
from eos.db import gamedata_meta
|
||||
|
||||
metadata_table = Table("metadata", gamedata_meta,
|
||||
Column("fieldName", String, primary_key=True),
|
||||
Column("fieldValue", String))
|
||||
Column("field_name", String, primary_key=True),
|
||||
Column("field_value", String))
|
||||
|
||||
mapper(MetaData, metadata_table)
|
||||
|
||||
@@ -1,32 +1,40 @@
|
||||
import config
|
||||
import shutil
|
||||
import time
|
||||
import re
|
||||
import os
|
||||
import migrations
|
||||
|
||||
def getVersion(db):
|
||||
cursor = db.execute('PRAGMA user_version')
|
||||
return cursor.fetchone()[0]
|
||||
|
||||
def update(saveddata_engine):
|
||||
currversion = getVersion(saveddata_engine)
|
||||
def getAppVersion():
|
||||
return migrations.appVersion
|
||||
|
||||
if currversion == config.dbversion:
|
||||
def update(saveddata_engine):
|
||||
dbVersion = getVersion(saveddata_engine)
|
||||
appVersion = getAppVersion()
|
||||
|
||||
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)
|
||||
upgrade = getattr(module, "upgrade", False)
|
||||
if upgrade:
|
||||
upgrade(saveddata_engine)
|
||||
for version in xrange(dbVersion, appVersion):
|
||||
|
||||
func = migrations.updates[version+1]
|
||||
if func:
|
||||
print "applying update",version+1
|
||||
func(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))
|
||||
|
||||
@@ -7,3 +7,25 @@ define an upgrade() function with the logic. Please note that there must be as
|
||||
many upgrade files as there are database versions (version 5 would include
|
||||
upgrade files 1-5)
|
||||
"""
|
||||
|
||||
import pkgutil
|
||||
import re
|
||||
|
||||
|
||||
updates = {}
|
||||
appVersion = 0
|
||||
|
||||
prefix = __name__ + "."
|
||||
for importer, modname, ispkg in pkgutil.iter_modules(__path__, prefix):
|
||||
# loop through python files, extracting update number and function, and
|
||||
# adding it to a list
|
||||
modname_tail = modname.rsplit('.', 1)[-1]
|
||||
module = __import__(modname, fromlist=True)
|
||||
m = re.match("^upgrade(?P<index>\d+)$", modname_tail)
|
||||
if not m:
|
||||
continue
|
||||
index = int(m.group("index"))
|
||||
appVersion = max(appVersion, index)
|
||||
upgrade = getattr(module, "upgrade", False)
|
||||
if upgrade:
|
||||
updates[index] = upgrade
|
||||
|
||||
16
eos/db/migrations/upgrade10.py
Normal file
16
eos/db/migrations/upgrade10.py
Normal 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")
|
||||
13
eos/db/migrations/upgrade3.py
Normal file
13
eos/db/migrations/upgrade3.py
Normal file
@@ -0,0 +1,13 @@
|
||||
"""
|
||||
Migration 3
|
||||
|
||||
- Adds mode column for fits (t3 dessy)
|
||||
"""
|
||||
|
||||
import sqlalchemy
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
try:
|
||||
saveddata_engine.execute("SELECT modeID FROM fits LIMIT 1")
|
||||
except sqlalchemy.exc.DatabaseError:
|
||||
saveddata_engine.execute("ALTER TABLE fits ADD COLUMN modeID INTEGER")
|
||||
141
eos/db/migrations/upgrade4.py
Normal file
141
eos/db/migrations/upgrade4.py
Normal file
@@ -0,0 +1,141 @@
|
||||
"""
|
||||
Migration 4
|
||||
|
||||
- Converts modules based on Proteus 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
|
||||
|
||||
Based on http://community.eveonline.com/news/patch-notes/patch-notes-for-proteus/
|
||||
and output of itemDiff.py
|
||||
"""
|
||||
|
||||
|
||||
CONVERSIONS = {
|
||||
506: ( # 'Basic' Capacitor Power Relay
|
||||
8205, # Alpha Reactor Control: Capacitor Power Relay
|
||||
8209, # Marked Generator Refitting: Capacitor Power Relay
|
||||
8203, # Partial Power Plant Manager: Capacity Power Relay
|
||||
8207, # Type-E Power Core Modification: Capacitor Power Relay
|
||||
),
|
||||
8177: ( # Mark I Compact Capacitor Power Relay
|
||||
8173, # Beta Reactor Control: Capacitor Power Relay I
|
||||
),
|
||||
8175: ( # Type-D Restrained Capacitor Power Relay
|
||||
8171, # Local Power Plant Manager: Capacity Power Relay I
|
||||
),
|
||||
|
||||
421: ( # 'Basic' Capacitor Recharger
|
||||
4425, # AGM Capacitor Charge Array,
|
||||
4421, # F-a10 Buffer Capacitor Regenerator
|
||||
4423, # Industrial Capacitor Recharger
|
||||
4427, # Secondary Parallel Link-Capacitor
|
||||
),
|
||||
4435: ( # Eutectic Compact Cap Recharger
|
||||
4433, # Barton Reactor Capacitor Recharger I
|
||||
4431, # F-b10 Nominal Capacitor Regenerator
|
||||
4437, # Fixed Parallel Link-Capacitor I
|
||||
),
|
||||
|
||||
1315: ( # 'Basic' Expanded Cargohold
|
||||
5483, # Alpha Hull Mod Expanded Cargo
|
||||
5479, # Marked Modified SS Expanded Cargo
|
||||
5481, # Partial Hull Conversion Expanded Cargo
|
||||
5485, # Type-E Altered SS Expanded Cargo
|
||||
),
|
||||
5493: ( # Type-D Restrained Expanded Cargo
|
||||
5491, # Beta Hull Mod Expanded Cargo
|
||||
5489, # Local Hull Conversion Expanded Cargo I
|
||||
5487, # Mark I Modified SS Expanded Cargo
|
||||
),
|
||||
|
||||
1401: ( # 'Basic' Inertial Stabilizers
|
||||
5523, # Alpha Hull Mod Inertial Stabilizers
|
||||
5521, # Partial Hull Conversion Inertial Stabilizers
|
||||
5525, # Type-E Altered SS Inertial Stabilizers
|
||||
),
|
||||
5533: ( # Type-D Restrained Inertial Stabilizers
|
||||
5531, # Beta Hull Mod Inertial Stabilizers
|
||||
5529, # Local Hull Conversion Inertial Stabilizers I
|
||||
5527, # Mark I Modified SS Inertial Stabilizers
|
||||
5519, # Marked Modified SS Inertial Stabilizers
|
||||
),
|
||||
|
||||
5239: ( # EP-S Gaussian Scoped Mining Laser
|
||||
5241, # Dual Diode Mining Laser I
|
||||
),
|
||||
5233: ( # Single Diode Basic Mining Laser
|
||||
5231, # EP-R Argon Ion Basic Excavation Pulse
|
||||
5237, # Rubin Basic Particle Bore Stream
|
||||
5235, # Xenon Basic Drilling Beam
|
||||
),
|
||||
5245: ( # Particle Bore Compact Mining Laser
|
||||
5243, # XeCl Drilling Beam I
|
||||
),
|
||||
|
||||
22619: ( # Frigoris Restrained Ice Harvester Upgrade
|
||||
22617, # Crisium Ice Harvester Upgrade
|
||||
),
|
||||
22611: ( # Elara Restrained Mining Laser Upgrade
|
||||
22609, # Erin Mining Laser Upgrade
|
||||
),
|
||||
|
||||
1242: ( # 'Basic' Nanofiber Internal Structure
|
||||
5591, # Alpha Hull Mod Nanofiber Structure
|
||||
5595, # Marked Modified SS Nanofiber Structure
|
||||
5559, # Partial Hull Conversion Nanofiber Structure
|
||||
5593, # Type-E Altered SS Nanofiber Structure
|
||||
),
|
||||
5599: ( # Type-D Restrained Nanofiber Structure
|
||||
5597, # Beta Hull Mod Nanofiber Structure
|
||||
5561, # Local Hull Conversion Nanofiber Structure I
|
||||
5601, # Mark I Modified SS Nanofiber Structure
|
||||
),
|
||||
|
||||
1192: ( # 'Basic' Overdrive Injector System
|
||||
5613, # Alpha Hull Mod Overdrive Injector
|
||||
5617, # Marked Modified SS Overdrive Injector
|
||||
5611, # Partial Hull Conversion Overdrive Injector
|
||||
5615, # Type-E Altered SS Overdrive Injector
|
||||
),
|
||||
5631: ( # Type-D Restrained Overdrive Injector
|
||||
5629, # Beta Hull Mod Overdrive Injector
|
||||
5627, # Local Hull Conversion Overdrive Injector I
|
||||
5633, # Mark I Modified SS Overdrive Injector
|
||||
),
|
||||
|
||||
1537: ( # 'Basic' Power Diagnostic System
|
||||
8213, # Alpha Reactor Control: Diagnostic System
|
||||
8217, # Marked Generator Refitting: Diagnostic System
|
||||
8211, # Partial Power Plant Manager: Diagnostic System
|
||||
8215, # Type-E Power Core Modification: Diagnostic System
|
||||
8255, # Type-E Power Core Modification: Reaction Control
|
||||
),
|
||||
8225: ( # Mark I Compact Power Diagnostic System
|
||||
8221, # Beta Reactor Control: Diagnostic System I
|
||||
8219, # Local Power Plant Manager: Diagnostic System I
|
||||
8223, # Type-D Power Core Modification: Diagnostic System
|
||||
),
|
||||
|
||||
1240: ( # 'Basic' Reinforced Bulkheads
|
||||
5677, # Alpha Hull Mod Reinforced Bulkheads
|
||||
5681, # Marked Modified SS Reinforced Bulkheads
|
||||
5675, # Partial Hull Conversion Reinforced Bulkheads
|
||||
5679, # Type-E Altered SS Reinforced Bulkheads
|
||||
),
|
||||
5649: ( # Mark I Compact Reinforced Bulkheads
|
||||
5645, # Beta Hull Mod Reinforced Bulkheads
|
||||
),
|
||||
5647: ( # Type-D Restrained Reinforced Bulkheads
|
||||
5643, # Local Hull Conversion Reinforced Bulkheads 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))
|
||||
|
||||
8
eos/db/migrations/upgrade5.py
Normal file
8
eos/db/migrations/upgrade5.py
Normal file
@@ -0,0 +1,8 @@
|
||||
"""
|
||||
Migration 5
|
||||
|
||||
Simply deletes damage profiles with a blank name. See GH issue #256
|
||||
"""
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
saveddata_engine.execute('DELETE FROM damagePatterns WHERE name LIKE ?', ("",))
|
||||
9
eos/db/migrations/upgrade6.py
Normal file
9
eos/db/migrations/upgrade6.py
Normal file
@@ -0,0 +1,9 @@
|
||||
"""
|
||||
Migration 6
|
||||
|
||||
Overwrites damage profile 0 to reset bad uniform values (bad values set with bug)
|
||||
"""
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
saveddata_engine.execute('DELETE FROM damagePatterns WHERE name LIKE ? OR ID LIKE ?', ("Uniform", "1"))
|
||||
saveddata_engine.execute('INSERT INTO damagePatterns VALUES (?, ?, ?, ?, ?, ?, ?)', (1, "Uniform", 25, 25, 25, 25, None))
|
||||
24
eos/db/migrations/upgrade7.py
Normal file
24
eos/db/migrations/upgrade7.py
Normal 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))
|
||||
|
||||
85
eos/db/migrations/upgrade8.py
Normal file
85
eos/db/migrations/upgrade8.py
Normal 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))
|
||||
|
||||
23
eos/db/migrations/upgrade9.py
Normal file
23
eos/db/migrations/upgrade9.py
Normal 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")
|
||||
@@ -1,3 +1,18 @@
|
||||
__all__ = ["character", "fit", "module", "user", "skill", "price",
|
||||
"booster", "drone", "implant", "fleet", "damagePattern",
|
||||
"miscData", "targetResists"]
|
||||
__all__ = [
|
||||
"character",
|
||||
"fit",
|
||||
"module",
|
||||
"user",
|
||||
"skill",
|
||||
"price",
|
||||
"booster",
|
||||
"drone",
|
||||
"implant",
|
||||
"fleet",
|
||||
"damagePattern",
|
||||
"miscData",
|
||||
"targetResists",
|
||||
"override",
|
||||
"crest"
|
||||
]
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
31
eos/db/saveddata/crest.py
Normal file
31
eos/db/saveddata/crest.py
Normal file
@@ -0,0 +1,31 @@
|
||||
#===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
#
|
||||
# eos is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# eos is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, String, Boolean
|
||||
from sqlalchemy.orm import mapper
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.types import CrestChar
|
||||
|
||||
crest_table = Table("crest", saveddata_meta,
|
||||
Column("ID", Integer, primary_key = True),
|
||||
Column("name", String, nullable = False, unique = True),
|
||||
Column("refresh_token", String, nullable = False))
|
||||
|
||||
mapper(CrestChar, crest_table)
|
||||
@@ -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),
|
||||
@@ -40,36 +40,126 @@ fits_table = Table("fits", saveddata_meta,
|
||||
Column("characterID", ForeignKey("characters.ID"), nullable = True),
|
||||
Column("damagePatternID", ForeignKey("damagePatterns.ID"), nullable=True),
|
||||
Column("booster", Boolean, nullable = False, index = True, default = 0),
|
||||
Column("targetResistsID", ForeignKey("targetResists.ID"), nullable=True))
|
||||
Column("targetResistsID", ForeignKey("targetResists.ID"), nullable=True),
|
||||
Column("modeID", Integer, nullable=True),
|
||||
)
|
||||
|
||||
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,
|
||||
}
|
||||
)
|
||||
|
||||
31
eos/db/saveddata/override.py
Normal file
31
eos/db/saveddata/override.py
Normal file
@@ -0,0 +1,31 @@
|
||||
#===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
#
|
||||
# eos is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# eos is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, Float
|
||||
from sqlalchemy.orm import mapper
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.types import Override
|
||||
|
||||
overrides_table = Table("overrides", saveddata_meta,
|
||||
Column("itemID", Integer, primary_key=True, index = True),
|
||||
Column("attrID", Integer, primary_key=True, index = True),
|
||||
Column("value", Float, nullable = False))
|
||||
|
||||
mapper(Override, overrides_table)
|
||||
@@ -19,7 +19,8 @@
|
||||
|
||||
from eos.db.util import processEager, processWhere
|
||||
from eos.db import saveddata_session, sd_lock
|
||||
from eos.types import User, Character, Fit, Price, DamagePattern, Fleet, MiscData, Wing, Squad, TargetResists
|
||||
|
||||
from eos.types import User, Character, Fit, Price, DamagePattern, Fleet, MiscData, Wing, Squad, TargetResists, Override, CrestChar
|
||||
from eos.db.saveddata.fleet import squadmembers_table
|
||||
from eos.db.saveddata.fit import projectedFits_table
|
||||
from sqlalchemy.sql import and_
|
||||
@@ -182,9 +183,15 @@ def getFit(lookfor, eager=None):
|
||||
else:
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
fit = saveddata_session.query(Fit).options(*eager).filter(Fit.ID == fitID).first()
|
||||
fit = saveddata_session.query(Fit).options(*eager).filter(Fit.ID == lookfor).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 +251,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,9 +272,15 @@ 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():
|
||||
with sd_lock:
|
||||
count = saveddata_session.query(Fit).count()
|
||||
return count
|
||||
|
||||
def countFitsWithShip(shipID, ownerID=None, where=None, eager=None):
|
||||
"""
|
||||
Get all the fits using a certain ship.
|
||||
@@ -290,7 +304,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):
|
||||
@@ -308,6 +323,12 @@ def getPrice(typeID):
|
||||
raise TypeError("Need integer as argument")
|
||||
return price
|
||||
|
||||
def clearPrices():
|
||||
with sd_lock:
|
||||
deleted_rows = saveddata_session.query(Price).delete()
|
||||
commit()
|
||||
return deleted_rows
|
||||
|
||||
def getMiscData(field):
|
||||
if isinstance(field, basestring):
|
||||
with sd_lock:
|
||||
@@ -374,7 +395,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):
|
||||
@@ -395,6 +417,55 @@ def getProjectedFits(fitID):
|
||||
else:
|
||||
raise TypeError("Need integer as argument")
|
||||
|
||||
def getCrestCharacters(eager=None):
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
characters = saveddata_session.query(CrestChar).options(*eager).all()
|
||||
return characters
|
||||
|
||||
@cachedQuery(CrestChar, 1, "lookfor")
|
||||
def getCrestCharacter(lookfor, eager=None):
|
||||
if isinstance(lookfor, int):
|
||||
if eager is None:
|
||||
with sd_lock:
|
||||
character = saveddata_session.query(CrestChar).get(lookfor)
|
||||
else:
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
character = saveddata_session.query(CrestChar).options(*eager).filter(CrestChar.ID == lookfor).first()
|
||||
elif isinstance(lookfor, basestring):
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
character = saveddata_session.query(CrestChar).options(*eager).filter(CrestChar.name == lookfor).first()
|
||||
else:
|
||||
raise TypeError("Need integer or string as argument")
|
||||
return character
|
||||
|
||||
def getOverrides(itemID, eager=None):
|
||||
if isinstance(itemID, int):
|
||||
return saveddata_session.query(Override).filter(Override.itemID == itemID).all()
|
||||
else:
|
||||
raise TypeError("Need integer as argument")
|
||||
|
||||
def clearOverrides():
|
||||
with sd_lock:
|
||||
deleted_rows = saveddata_session.query(Override).delete()
|
||||
commit()
|
||||
return deleted_rows
|
||||
|
||||
def getAllOverrides(eager=None):
|
||||
return saveddata_session.query(Override).all()
|
||||
|
||||
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)
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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"))
|
||||
@@ -1,9 +1,9 @@
|
||||
# agilityMultiplierEffect
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Inertia Stabilizer (12 of 12)
|
||||
# Modules from group: Nanofiber Internal Structure (14 of 14)
|
||||
# Modules from group: Reinforced Bulkhead (12 of 12)
|
||||
# Modules from group: Inertial Stabilizer (7 of 7)
|
||||
# Modules from group: Nanofiber Internal Structure (7 of 7)
|
||||
# Modules from group: Reinforced Bulkhead (8 of 8)
|
||||
type = "passive"
|
||||
def handler(fit, module, context):
|
||||
fit.ship.boostItemAttr("agility",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"))
|
||||
@@ -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)
|
||||
|
||||
@@ -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"))
|
||||
@@ -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"))
|
||||
@@ -1,4 +1,4 @@
|
||||
# armorTankingGang2
|
||||
# armorWarfareArmorHpReplacer
|
||||
#
|
||||
# Used by:
|
||||
# Implant: Armored Warfare Mindlink
|
||||
9
eos/effects/battlecruiserdronespeed.py
Normal file
9
eos/effects/battlecruiserdronespeed.py
Normal 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"))
|
||||
10
eos/effects/battlecruisermetrange.py
Normal file
10
eos/effects/battlecruisermetrange.py
Normal 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"))
|
||||
11
eos/effects/battlecruisermhtrange.py
Normal file
11
eos/effects/battlecruisermhtrange.py
Normal 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"))
|
||||
9
eos/effects/battlecruisermissilerange.py
Normal file
9
eos/effects/battlecruisermissilerange.py
Normal 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"))
|
||||
10
eos/effects/battlecruisermptrange.py
Normal file
10
eos/effects/battlecruisermptrange.py
Normal 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"))
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Capacitor Flux Coil (6 of 6)
|
||||
# Modules from group: Capacitor Power Relay (26 of 26)
|
||||
# Modules from group: Power Diagnostic System (31 of 31)
|
||||
# Modules from group: Propulsion Module (107 of 107)
|
||||
# Modules from group: Capacitor Power Relay (20 of 20)
|
||||
# Modules from group: Power Diagnostic System (23 of 23)
|
||||
# Modules from group: Propulsion Module (114 of 114)
|
||||
# Modules from group: Reactor Control Unit (22 of 22)
|
||||
# Modules from group: Shield Flux Coil (11 of 11)
|
||||
# Modules from group: Shield Power Relay (11 of 11)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# cargoCapacityMultiply
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Expanded Cargohold (13 of 13)
|
||||
# Modules from group: Overdrive Injector System (14 of 14)
|
||||
# Modules from group: Reinforced Bulkhead (12 of 12)
|
||||
# Modules from group: Expanded Cargohold (7 of 7)
|
||||
# Modules from group: Overdrive Injector System (7 of 7)
|
||||
# Modules from group: Reinforced Bulkhead (8 of 8)
|
||||
type = "passive"
|
||||
def handler(fit, module, context):
|
||||
fit.ship.multiplyItemAttr("capacity", module.getModifiedItemAttr("cargoCapacityMultiplier"))
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -6,6 +6,7 @@ gangBonus = "commandBonusTD"
|
||||
gangBoost = "ewarStrTD"
|
||||
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"))
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# Used by:
|
||||
# Ship: Astero
|
||||
# Ship: Prospect
|
||||
# Ship: Victorieux Luxury Yacht
|
||||
type = "passive"
|
||||
runTime = "early"
|
||||
def handler(fit, ship, context):
|
||||
|
||||
7
eos/effects/crystalminingamountinfo2.py
Normal file
7
eos/effects/crystalminingamountinfo2.py
Normal file
@@ -0,0 +1,7 @@
|
||||
# crystalMiningamountInfo2
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Frequency Mining Laser (3 of 3)
|
||||
type = "passive"
|
||||
def handler(fit, module, context):
|
||||
module.preAssignItemAttr("specialtyMiningAmount", module.getModifiedItemAttr("miningAmount"))
|
||||
@@ -1,7 +1,7 @@
|
||||
# drawbackArmorHP
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Rig Navigation (48 of 68)
|
||||
# Modules from group: Rig Navigation (48 of 64)
|
||||
type = "passive"
|
||||
def handler(fit, module, context):
|
||||
fit.ship.boostItemAttr("armorHP", module.getModifiedItemAttr("drawback"))
|
||||
@@ -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"))
|
||||
@@ -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)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# drawbackWarpSpeed
|
||||
#
|
||||
# Used by:
|
||||
# Modules named like: Higgs Anchor I (4 of 4)
|
||||
# Modules from group: Rig Anchor (4 of 4)
|
||||
type = "passive"
|
||||
def handler(fit, module, context):
|
||||
fit.ship.boostItemAttr("warpSpeedMultiplier", module.getModifiedItemAttr("drawback"), stackingPenalties=True)
|
||||
|
||||
@@ -4,6 +4,5 @@
|
||||
# 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")
|
||||
|
||||
@@ -4,6 +4,5 @@
|
||||
# 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")
|
||||
|
||||
@@ -4,6 +4,5 @@
|
||||
# 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")
|
||||
|
||||
@@ -4,6 +4,5 @@
|
||||
# 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")
|
||||
|
||||
@@ -4,6 +4,5 @@
|
||||
# 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")
|
||||
|
||||
@@ -4,6 +4,5 @@
|
||||
# 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")
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
# 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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user