Compare commits
459 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d52c249921 | ||
|
|
0b9a50cd8d | ||
|
|
25bbfec318 | ||
|
|
1192c26b8f | ||
|
|
4a3201ffd4 | ||
|
|
406a22100d | ||
|
|
e83fa4d40b | ||
|
|
c552cb5e40 | ||
|
|
49bc9f50bc | ||
|
|
30501feb99 | ||
|
|
efc07e1553 | ||
|
|
9bbeec523e | ||
|
|
943ee517f4 | ||
|
|
18bb3bf246 | ||
|
|
117d51caab | ||
|
|
a3e411f225 | ||
|
|
083af3ebc7 | ||
|
|
3fd4d106d9 | ||
|
|
7c376c93a2 | ||
|
|
4ef7b645a8 | ||
|
|
cccc7ff2d0 | ||
|
|
b7c45f4c6e | ||
|
|
3964658d9a | ||
|
|
03212be54a | ||
|
|
46098f2127 | ||
|
|
2005d0b0b9 | ||
|
|
3293380515 | ||
|
|
68e5b22fe2 | ||
|
|
0f7dd7cc0c | ||
|
|
0713251685 | ||
|
|
3fda62e320 | ||
|
|
5f1c2d6676 | ||
|
|
c0ba559ca6 | ||
|
|
164720db3d | ||
|
|
bd90ec4bf0 | ||
|
|
d7e24dfa8f | ||
|
|
2f1ad21392 | ||
|
|
687d539534 | ||
|
|
bd6793bc19 | ||
|
|
6dd6452c11 | ||
|
|
e59a1cd27b | ||
|
|
24d14d5e19 | ||
|
|
e0584367c5 | ||
|
|
a2f48e8944 | ||
|
|
95ba18f8a9 | ||
|
|
122d8ef367 | ||
|
|
281d2ed1f4 | ||
|
|
48924774f9 | ||
|
|
ee00914a2b | ||
|
|
48d90c1eca | ||
|
|
415b3db809 | ||
|
|
53451dfaf6 | ||
|
|
49181dce2b | ||
|
|
199763bcca | ||
|
|
033647da61 | ||
|
|
00e8e9d84a | ||
|
|
96b701687b | ||
|
|
e1e90cc23e | ||
|
|
f41ecae8c8 | ||
|
|
65ec8cf4ee | ||
|
|
4fc93f7089 | ||
|
|
3ec01a20c2 | ||
|
|
8a10f0a766 | ||
|
|
0db125177f | ||
|
|
a3f532f62f | ||
|
|
234f36c8c0 | ||
|
|
2c3957b2db | ||
|
|
79deca41c1 | ||
|
|
570df7f645 | ||
|
|
8153b80d05 | ||
|
|
b74654a5b3 | ||
|
|
4c6f68b07e | ||
|
|
9839efc2dc | ||
|
|
9d379d966c | ||
|
|
61086989dc | ||
|
|
023ea43611 | ||
|
|
044e032ab3 | ||
|
|
da7b95041d | ||
|
|
f52f39984f | ||
|
|
1513b07071 | ||
|
|
be19b7414a | ||
|
|
75f9a0252a | ||
|
|
5169c35d5c | ||
|
|
bbdf1ee6cc | ||
|
|
6c6e8a9972 | ||
|
|
97742b08c8 | ||
|
|
8ef4c61fc3 | ||
|
|
ff607e4b03 | ||
|
|
30c1ab125c | ||
|
|
8276746dad | ||
|
|
5560ef4d34 | ||
|
|
fac31f7254 | ||
|
|
1efcc8d3ef | ||
|
|
03c2088e6b | ||
|
|
5c20ee7ade | ||
|
|
04c62aabea | ||
|
|
0994158abd | ||
|
|
77a66a66ea | ||
|
|
0b615b578a | ||
|
|
53f07db5fe | ||
|
|
4d4815d6af | ||
|
|
b296e0709c | ||
|
|
373e0a390b | ||
|
|
222037ff40 | ||
|
|
4fac10ccb7 | ||
|
|
7956ca0409 | ||
|
|
5b27d0559f | ||
|
|
85157fdf85 | ||
|
|
caf8e7f2d6 | ||
|
|
124bb027ab | ||
|
|
d5ca14ca52 | ||
|
|
99982aa547 | ||
|
|
3f4493c0ea | ||
|
|
cdb604b29f | ||
|
|
d3b8cebc8a | ||
|
|
7d245660bc | ||
|
|
b1e40427a3 | ||
|
|
73925df24b | ||
|
|
04fbd3b548 | ||
|
|
d9dd94d6c3 | ||
|
|
963353a1dc | ||
|
|
3411dcfd91 | ||
|
|
ae6434affb | ||
|
|
f773e0a935 | ||
|
|
7ab3ad9e08 | ||
|
|
3f3a82ca6c | ||
|
|
e902cc5780 | ||
|
|
fcb6952119 | ||
|
|
3eecd57979 | ||
|
|
6e73b9fefd | ||
|
|
f0b0285f77 | ||
|
|
e706a015b3 | ||
|
|
a804f9a1ad | ||
|
|
9e1b7dbb87 | ||
|
|
551ffe9ed3 | ||
|
|
cbe1ce5bcd | ||
|
|
917afd5067 | ||
|
|
c3fb9231a4 | ||
|
|
2ed2f8e262 | ||
|
|
390d90ac47 | ||
|
|
4c877e7a5a | ||
|
|
972fe433f7 | ||
|
|
ecaf6f96a9 | ||
|
|
8541e2a869 | ||
|
|
48a2963472 | ||
|
|
f245a02372 | ||
|
|
1c16343b46 | ||
|
|
d0f66f2d16 | ||
|
|
df0c6ed269 | ||
|
|
9a4e26a5be | ||
|
|
2b87f91279 | ||
|
|
9b48b61b9b | ||
|
|
57e67b3699 | ||
|
|
15e60c3d24 | ||
|
|
ebf07db6c6 | ||
|
|
1559767201 | ||
|
|
6e5e52df37 | ||
|
|
e9289c102b | ||
|
|
81d61d7e29 | ||
|
|
9ab4ec2d4f | ||
|
|
565332dfcd | ||
|
|
f94fbd740a | ||
|
|
a2719ec2f7 | ||
|
|
1da12cb18e | ||
|
|
e0cddcd061 | ||
|
|
78f632a4f6 | ||
|
|
52754535a0 | ||
|
|
a9db667c9c | ||
|
|
f442632fbc | ||
|
|
362086cc83 | ||
|
|
73d59569ff | ||
|
|
cb4fadf84c | ||
|
|
e85d144928 | ||
|
|
07099f4057 | ||
|
|
96c13c344a | ||
|
|
8f42822d9e | ||
|
|
c5ba79cfbb | ||
|
|
f69f76856a | ||
|
|
3a23d820cc | ||
|
|
c917d22db5 | ||
|
|
c3f8b102fa | ||
|
|
5e566db47d | ||
|
|
5b2c5907ed | ||
|
|
dd78a41171 | ||
|
|
201fb4e241 | ||
|
|
8abd25fe40 | ||
|
|
d59c897921 | ||
|
|
cb89d13d9f | ||
|
|
a1aa78adc0 | ||
|
|
4bbbd33917 | ||
|
|
42ccc53166 | ||
|
|
35ad21da38 | ||
|
|
72efef818f | ||
|
|
5571bae8b2 | ||
|
|
8b2cfe44f2 | ||
|
|
5ea7215ec0 | ||
|
|
e2ac90a040 | ||
|
|
6ab84240a2 | ||
|
|
12a526fa9e | ||
|
|
82e3db1ffb | ||
|
|
e779bb84e2 | ||
|
|
bd0fcbef3a | ||
|
|
0456cb2f96 | ||
|
|
cafd92f169 | ||
|
|
05f08970c9 | ||
|
|
f66485c48a | ||
|
|
2153c05183 | ||
|
|
f66c36e42b | ||
|
|
8771de9c1f | ||
|
|
fa3cf90421 | ||
|
|
636ee1de23 | ||
|
|
b36bf8fb21 | ||
|
|
55ad52919e | ||
|
|
0648feaa7b | ||
|
|
e16ae88ed9 | ||
|
|
c5c673e360 | ||
|
|
5cd21da7b1 | ||
|
|
da0f89ef91 | ||
|
|
efc3f1ba7d | ||
|
|
8d7f0b56f1 | ||
|
|
89b6e8f8c3 | ||
|
|
c6e715aa5c | ||
|
|
0e93136157 | ||
|
|
89c84aac96 | ||
|
|
649ba9f3e4 | ||
|
|
2d38fd4773 | ||
|
|
23f0f48c80 | ||
|
|
6254fa3e23 | ||
|
|
8686c02b1f | ||
|
|
fe1c4cc4d4 | ||
|
|
ed649dd4c7 | ||
|
|
33618f12f7 | ||
|
|
33eccaa374 | ||
|
|
5f0ce58c29 | ||
|
|
c329f5eeb8 | ||
|
|
320a0230f4 | ||
|
|
d94d49f0a9 | ||
|
|
9bfc5b35b6 | ||
|
|
0f30ea554d | ||
|
|
50dd74dbe8 | ||
|
|
9c355d8f96 | ||
|
|
7b0f672f04 | ||
|
|
33bf5234d0 | ||
|
|
cb392e7e5f | ||
|
|
dfba033190 | ||
|
|
5fbe623ae6 | ||
|
|
e025bff99b | ||
|
|
e77dddc15b | ||
|
|
eea8019593 | ||
|
|
c7360c8cc3 | ||
|
|
f81179db4b | ||
|
|
2d7eed4aac | ||
|
|
96828a5611 | ||
|
|
8a0f8ae609 | ||
|
|
ac8f805fcb | ||
|
|
9f3c2ca7a8 | ||
|
|
2376148380 | ||
|
|
2e8d7d3610 | ||
|
|
3179016aed | ||
|
|
514db91d7a | ||
|
|
269d3f326d | ||
|
|
b04fcb0d15 | ||
|
|
a29b3da8a6 | ||
|
|
18a5e35e80 | ||
|
|
3072dbb3ff | ||
|
|
b103f0df7e | ||
|
|
9e8166c13d | ||
|
|
9f7e4e0dc0 | ||
|
|
29d175c7b3 | ||
|
|
0c971a127c | ||
|
|
40ce7b7c0b | ||
|
|
a8060a5e15 | ||
|
|
cc063d1934 | ||
|
|
531721ef5e | ||
|
|
2936b88c3d | ||
|
|
2365112292 | ||
|
|
1daef5354d | ||
|
|
6f19d45c6d | ||
|
|
ac7908c62c | ||
|
|
c000b19986 | ||
|
|
1da127c898 | ||
|
|
fcdf55632f | ||
|
|
dd3bc66896 | ||
|
|
da67cdba9b | ||
|
|
8850da6cdb | ||
|
|
7d46d7e22d | ||
|
|
b3157303cd | ||
|
|
65e17119af | ||
|
|
f7b509f9a9 | ||
|
|
dea775058d | ||
|
|
3c405f51d8 | ||
|
|
337f0a9c8a | ||
|
|
53936a3e66 | ||
|
|
30a6e29b39 | ||
|
|
f3dc3bc654 | ||
|
|
0a935cf149 | ||
|
|
5697da7ec2 | ||
|
|
a7086b78cb | ||
|
|
e032c9c5b1 | ||
|
|
46b0aded03 | ||
|
|
d23398ce29 | ||
|
|
5e0a5da6d5 | ||
|
|
6e112b9ed5 | ||
|
|
b30b3fcbf1 | ||
|
|
455fea75c0 | ||
|
|
bd181559ed | ||
|
|
967128cb69 | ||
|
|
5fa43138b3 | ||
|
|
f0baba10df | ||
|
|
7058018aed | ||
|
|
d45d7204d2 | ||
|
|
b596447095 | ||
|
|
25df05a15d | ||
|
|
4a33365195 | ||
|
|
5d5646df79 | ||
|
|
405a965046 | ||
|
|
4138088d4a | ||
|
|
de44e6f932 | ||
|
|
d4df989427 | ||
|
|
6c8b143936 | ||
|
|
0f94557699 | ||
|
|
a52b9e58e9 | ||
|
|
0d8904d59f | ||
|
|
d956cb7861 | ||
|
|
e848cec815 | ||
|
|
ce8f1d385d | ||
|
|
90e338b969 | ||
|
|
1978f5cb92 | ||
|
|
979bc494f0 | ||
|
|
cc9b6ea04b | ||
|
|
8cbb327659 | ||
|
|
2f6e306f8e | ||
|
|
065747f425 | ||
|
|
c4f41fb5fa | ||
|
|
e4f3ed05cc | ||
|
|
0e84d6c557 | ||
|
|
c384848870 | ||
|
|
1fc9b2941d | ||
|
|
e9be07f281 | ||
|
|
df7dc30e7e | ||
|
|
d0235f6d93 | ||
|
|
de646cf252 | ||
|
|
21838f2d9a | ||
|
|
266398b1de | ||
|
|
0cc646bab9 | ||
|
|
cebca64e5e | ||
|
|
bd0de82a8e | ||
|
|
0f5ae8d9b6 | ||
|
|
5ae7805bb1 | ||
|
|
6a382c4445 | ||
|
|
3b0c8b6117 | ||
|
|
0e1e4cad6d | ||
|
|
e0b92198b0 | ||
|
|
ce3b94696a | ||
|
|
cacf286176 | ||
|
|
a02bbe3964 | ||
|
|
866d410695 | ||
|
|
ea6f31c021 | ||
|
|
d522fff511 | ||
|
|
ca27cd3250 | ||
|
|
20a1618e41 | ||
|
|
2830729cb4 | ||
|
|
c0e15f61c6 | ||
|
|
4355f35eef | ||
|
|
029e61edaf | ||
|
|
b18f82505b | ||
|
|
f8a65de47f | ||
|
|
e5a0ef1877 | ||
|
|
8647fe460c | ||
|
|
a4950e9015 | ||
|
|
82d50cfa0d | ||
|
|
efea46006a | ||
|
|
d9800dcf19 | ||
|
|
266b3ce985 | ||
|
|
3b61a07c55 | ||
|
|
5dc092ace5 | ||
|
|
7b32fe08ac | ||
|
|
fd6e318ae3 | ||
|
|
504c395ea2 | ||
|
|
9ed210d5b5 | ||
|
|
c7f0f6215a | ||
|
|
34c692c972 | ||
|
|
56f34873a6 | ||
|
|
b4dfcf53fb | ||
|
|
3c26676b66 | ||
|
|
3fb7411b9d | ||
|
|
cac8e528a3 | ||
|
|
2afc8b1abe | ||
|
|
06e82a04b4 | ||
|
|
782df18501 | ||
|
|
a87d659e5d | ||
|
|
cd35c9319c | ||
|
|
dfe3d5c82a | ||
|
|
ccd8cdd099 | ||
|
|
72062e6213 | ||
|
|
10836acab2 | ||
|
|
08ab8fbc5b | ||
|
|
da5aaf2f78 | ||
|
|
4484b68a3a | ||
|
|
81fce93186 | ||
|
|
d58987e427 | ||
|
|
05a5ebff00 | ||
|
|
2f28afc7ae | ||
|
|
0134c3b9a1 | ||
|
|
9f433fd072 | ||
|
|
7729bd9210 | ||
|
|
ce5803dd9c | ||
|
|
821ede8579 | ||
|
|
592f9a2298 | ||
|
|
c30c07b91c | ||
|
|
73d9dd60e6 | ||
|
|
dbdbe155f3 | ||
|
|
7d41260863 | ||
|
|
d53ff0f502 | ||
|
|
f37f4573bf | ||
|
|
ee392e07c4 | ||
|
|
59b09a255a | ||
|
|
3e73c2eb34 | ||
|
|
3625b4395a | ||
|
|
1444a24e70 | ||
|
|
73dfa25ef0 | ||
|
|
a01284ff1c | ||
|
|
8cc81cebdd | ||
|
|
3b716e6e5e | ||
|
|
961b389b40 | ||
|
|
0527a506ac | ||
|
|
1082d8a173 | ||
|
|
7ae41b71b2 | ||
|
|
de5a734919 | ||
|
|
987c55ed8f | ||
|
|
57783fe80f | ||
|
|
f24c2ddd22 | ||
|
|
f16e14e0b4 | ||
|
|
729c46ab00 | ||
|
|
3b546de070 | ||
|
|
ba64f75f88 | ||
|
|
4b8f2ce9e7 | ||
|
|
8c5c7fba29 | ||
|
|
bec26d5d05 | ||
|
|
8f369daf1e | ||
|
|
43cbdc1e57 | ||
|
|
cf4d0706ae | ||
|
|
2857eff884 | ||
|
|
050f1b4add | ||
|
|
2bbcd96ce3 | ||
|
|
1cbd8ee901 | ||
|
|
7e86cb0f84 | ||
|
|
0e7dccccfe | ||
|
|
9d75dea31a | ||
|
|
610f501608 | ||
|
|
361f7fc5bb | ||
|
|
951b35a345 | ||
|
|
6c317d56ee | ||
|
|
2acb3e759e | ||
|
|
9712ec4fbf | ||
|
|
ae0da59ed2 | ||
|
|
8e4db5a8c3 | ||
|
|
7f392006d1 | ||
|
|
828b18d0fd |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -117,3 +117,8 @@ ENV/
|
||||
# Pycharm project settings
|
||||
.idea
|
||||
eos.iml
|
||||
gitversion
|
||||
.version
|
||||
/.version
|
||||
*.swp
|
||||
|
||||
|
||||
14
.mailmap
Normal file
14
.mailmap
Normal file
@@ -0,0 +1,14 @@
|
||||
cncfanatics <diego.duclos@gmail.com> cncfanatics <cncfanatics@titanium.(none)>
|
||||
blitzmann <holmes.ryan.90@gmail.com>
|
||||
blitzmann <holmes.ryan.90@gmail.com> blitzmann <ryan.xgamer99@gmail.com>
|
||||
blitzmann <holmes.ryan.90@gmail.com>
|
||||
blitzmann <holmes.ryan.90@gmail.com> blitzman <ryan.xgamer99@gmail.com>
|
||||
blitzmann <holmes.ryan.90@gmail.com> Ryan Holmes <ryan.holmes.90@gmail.com>
|
||||
blitzmann <holmes.ryan.90@gmail.com>
|
||||
Corollax <corollax@gmail.com> Corollax <corollax@corollax-laptop.(none)>
|
||||
Corollax <corollax@gmail.com> Corollax <corollax@corollax-N76VM.(none)>
|
||||
Mr. Nukealizer <mr.nukealizer@gmail.com> Mr. Nukealizer <MrNukealizer@users.noreply.github.com>
|
||||
DarkPhoenix <phoenix@mail.ru>
|
||||
Sakari Orisi <sakari@evefit.org>
|
||||
Will Wykeham <will@wykeham.net> Will Wykeham <will.wykeham@paconsulting.com>
|
||||
OISumeko <camerongrout@gmail.com> OISumeko <cameron@sporadic.co.nz>
|
||||
@@ -1,11 +1,13 @@
|
||||
# Submit a bug report bug report or feature request
|
||||
<!--
|
||||
|
||||
Submit a bug report bug report or feature request
|
||||
|
||||
Here you can inform pyfa developers of potential bugs or suggest features / improvements to the project. Please check
|
||||
to make sure that the bug hasn't been reported or feature requested before submitting. If you have general questions
|
||||
about the project and want to reach out to the developers personally, please check out out our [Slack]
|
||||
(https://pyfainvite.azurewebsites.net/).
|
||||
|
||||
---
|
||||
-->
|
||||
|
||||
## Bug Report
|
||||
|
||||
|
||||
11
README.md
11
README.md
@@ -36,13 +36,8 @@ The following is a list of pyfa packages available for certain distributions. Pl
|
||||
### Dependencies
|
||||
If you wish to help with development or simply need to run pyfa through a Python interpreter, the following software is required:
|
||||
|
||||
* Python 2.7
|
||||
* `wxPython` 2.8/3.0
|
||||
* `sqlalchemy` >= 1.0.5
|
||||
* `dateutil`
|
||||
* `matplotlib` (for some Linux distributions you may need to install separate wxPython bindings such as `python-matplotlib-wx`)
|
||||
* `requests`
|
||||
* `logbook` >= 1.0.0
|
||||
* Python 3.6
|
||||
* Requirements as listed in `requirements.txt`
|
||||
|
||||
## Bug Reporting
|
||||
The preferred method of reporting bugs is through the project's [GitHub Issues interface](https://github.com/pyfa-org/Pyfa/issues). Alternatively, posting a report in the [pyfa thread](http://forums.eveonline.com/default.aspx?g=posts&t=247609) 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).
|
||||
@@ -52,7 +47,7 @@ pyfa is licensed under the GNU GPL v3.0, see LICENSE
|
||||
|
||||
## Resources
|
||||
* Development repository: [https://github.com/pyfa-org/Pyfa](https://github.com/pyfa-org/Pyfa)
|
||||
* [EVE forum thread](https://forums.eveonline.com/default.aspx?g=posts&t=466425)
|
||||
* [EVE forum thread](https://forums.eveonline.com/t/27156)
|
||||
* [EVE University guide using pyfa](http://wiki.eveuniversity.org/Guide_to_using_PYFA)
|
||||
* [EVE Online website](http://www.eveonline.com/)
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ def DBInMemory_test():
|
||||
gamedataCache = True
|
||||
saveddataCache = True
|
||||
gamedata_version = ""
|
||||
gamedata_connectionstring = 'sqlite:///' + realpath(join(dirname(abspath(unicode(__file__))), "..", "eve.db"))
|
||||
gamedata_connectionstring = 'sqlite:///' + realpath(join(dirname(abspath(str(__file__))), "..", "eve.db"))
|
||||
saveddata_connectionstring = 'sqlite:///:memory:'
|
||||
|
||||
class ReadOnlyException(Exception):
|
||||
@@ -100,8 +100,8 @@ def DBInMemory():
|
||||
import eos.db
|
||||
|
||||
# Output debug info to help us troubleshoot Travis
|
||||
print(eos.db.saveddata_engine)
|
||||
print(eos.db.gamedata_engine)
|
||||
print((eos.db.saveddata_engine))
|
||||
print((eos.db.gamedata_engine))
|
||||
|
||||
helper = {
|
||||
'config': eos.config,
|
||||
|
||||
@@ -41,7 +41,7 @@ def CurseFit(DB, Gamedata, Saveddata):
|
||||
mod.state = Saveddata['State'].ONLINE
|
||||
|
||||
# Add 5 neuts
|
||||
for _ in xrange(5):
|
||||
for _ in range(5):
|
||||
fit.modules.append(mod)
|
||||
|
||||
return fit
|
||||
@@ -60,7 +60,7 @@ def HeronFit(DB, Gamedata, Saveddata):
|
||||
mod.state = Saveddata['State'].ONLINE
|
||||
|
||||
# Add 5 neuts
|
||||
for _ in xrange(4):
|
||||
for _ in range(4):
|
||||
fit.modules.append(mod)
|
||||
|
||||
return fit
|
||||
@@ -94,8 +94,8 @@ def GetUnicodePath(root, file=None, codec=None):
|
||||
path = os.path.join(path, file)
|
||||
|
||||
if codec:
|
||||
path = unicode(path, codec)
|
||||
path = str(path, codec)
|
||||
else:
|
||||
path = unicode(path)
|
||||
path = str(path)
|
||||
|
||||
return path
|
||||
|
||||
177
config.py
177
config.py
@@ -1,7 +1,11 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
from logbook import Logger
|
||||
from logbook import CRITICAL, DEBUG, ERROR, FingersCrossedHandler, INFO, Logger, NestedSetup, NullHandler, \
|
||||
StreamHandler, TimedRotatingFileHandler, WARNING
|
||||
import hashlib
|
||||
|
||||
from cryptography.fernet import Fernet
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
@@ -19,17 +23,39 @@ debug = False
|
||||
saveInRoot = False
|
||||
|
||||
# Version data
|
||||
version = "1.31.0"
|
||||
tag = "Stable "
|
||||
expansionName = "YC119.8"
|
||||
expansionVersion = "1.0"
|
||||
|
||||
version = "2.0.0b5"
|
||||
tag = "git"
|
||||
expansionName = "YC120.3"
|
||||
expansionVersion = "1.8"
|
||||
evemonMinVersion = "4081"
|
||||
|
||||
minItemSearchLength = 3
|
||||
|
||||
pyfaPath = None
|
||||
savePath = None
|
||||
saveDB = None
|
||||
gameDB = None
|
||||
logPath = None
|
||||
loggingLevel = None
|
||||
logging_setup = None
|
||||
cipher = None
|
||||
clientHash = None
|
||||
|
||||
ESI_AUTH_PROXY = "https://www.pyfa.io" # "http://localhost:5015"
|
||||
ESI_CACHE = 'esi_cache'
|
||||
|
||||
LOGLEVEL_MAP = {
|
||||
"critical": CRITICAL,
|
||||
"error": ERROR,
|
||||
"warning": WARNING,
|
||||
"info": INFO,
|
||||
"debug": DEBUG,
|
||||
}
|
||||
|
||||
|
||||
def getClientSecret():
|
||||
return clientHash
|
||||
|
||||
|
||||
def isFrozen():
|
||||
@@ -45,23 +71,37 @@ def __createDirs(path):
|
||||
|
||||
|
||||
def getPyfaRoot():
|
||||
base = getattr(sys.modules['__main__'], "__file__", sys.executable) if isFrozen() else sys.argv[0]
|
||||
if hasattr(sys, '_MEIPASS'):
|
||||
return sys._MEIPASS
|
||||
base = getattr(sys.modules['__main__'], "__file__", sys.executable) if isFrozen() else __file__
|
||||
root = os.path.dirname(os.path.realpath(os.path.abspath(base)))
|
||||
root = unicode(root, sys.getfilesystemencoding())
|
||||
root = root
|
||||
return root
|
||||
|
||||
|
||||
def getVersion():
|
||||
if os.path.isfile(os.path.join(pyfaPath, '.version')):
|
||||
with open(os.path.join(pyfaPath, '.version')) as f:
|
||||
gitVersion = f.readline()
|
||||
return gitVersion
|
||||
# if no version file exists, then user is running from source or not an official build
|
||||
return version + " (git)"
|
||||
|
||||
|
||||
def getDefaultSave():
|
||||
return unicode(os.path.expanduser(os.path.join("~", ".pyfa")), sys.getfilesystemencoding())
|
||||
return os.path.expanduser(os.path.join("~", ".pyfa"))
|
||||
|
||||
|
||||
def defPaths(customSavePath):
|
||||
def defPaths(customSavePath=None):
|
||||
global debug
|
||||
global pyfaPath
|
||||
global savePath
|
||||
global saveDB
|
||||
global gameDB
|
||||
global saveInRoot
|
||||
global logPath
|
||||
global cipher
|
||||
global clientHash
|
||||
|
||||
pyfalog.debug("Configuring Pyfa")
|
||||
|
||||
@@ -86,12 +126,22 @@ def defPaths(customSavePath):
|
||||
|
||||
__createDirs(savePath)
|
||||
|
||||
if isFrozen():
|
||||
os.environ["REQUESTS_CA_BUNDLE"] = os.path.join(pyfaPath, "cacert.pem").encode('utf8')
|
||||
os.environ["SSL_CERT_FILE"] = os.path.join(pyfaPath, "cacert.pem").encode('utf8')
|
||||
secret_file = os.path.join(savePath, ".secret")
|
||||
if not os.path.exists(secret_file):
|
||||
with open(secret_file, "wb") as _file:
|
||||
_file.write(Fernet.generate_key())
|
||||
|
||||
with open(secret_file, 'rb') as fp:
|
||||
key = fp.read()
|
||||
clientHash = hashlib.sha3_256(key).hexdigest()
|
||||
cipher = Fernet(key)
|
||||
|
||||
# if isFrozen():
|
||||
# os.environ["REQUESTS_CA_BUNDLE"] = os.path.join(pyfaPath, "cacert.pem")
|
||||
# os.environ["SSL_CERT_FILE"] = os.path.join(pyfaPath, "cacert.pem")
|
||||
|
||||
# The database where we store all the fits etc
|
||||
saveDB = os.path.join(savePath, "saveddata.db")
|
||||
saveDB = os.path.join(savePath, "saveddata-py3-dev.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
|
||||
@@ -100,6 +150,13 @@ def defPaths(customSavePath):
|
||||
if not gameDB:
|
||||
gameDB = os.path.join(pyfaPath, "eve.db")
|
||||
|
||||
if debug:
|
||||
logFile = "pyfa_debug.log"
|
||||
else:
|
||||
logFile = "pyfa.log"
|
||||
|
||||
logPath = os.path.join(savePath, logFile)
|
||||
|
||||
# DON'T MODIFY ANYTHING BELOW
|
||||
import eos.config
|
||||
|
||||
@@ -109,6 +166,100 @@ def defPaths(customSavePath):
|
||||
eos.config.saveddata_connectionstring = "sqlite:///" + saveDB + "?check_same_thread=False"
|
||||
eos.config.gamedata_connectionstring = "sqlite:///" + gameDB + "?check_same_thread=False"
|
||||
|
||||
print(eos.config.saveddata_connectionstring)
|
||||
print(eos.config.gamedata_connectionstring)
|
||||
|
||||
# initialize the settings
|
||||
from service.settings import EOSSettings
|
||||
eos.config.settings = EOSSettings.getInstance().EOSSettings # this is kind of confusing, but whatever
|
||||
|
||||
|
||||
def defLogging():
|
||||
global debug
|
||||
global logPath
|
||||
global loggingLevel
|
||||
global logging_setup
|
||||
|
||||
try:
|
||||
if debug:
|
||||
logging_setup = NestedSetup([
|
||||
# make sure we never bubble up to the stderr handler
|
||||
# if we run out of setup handling
|
||||
NullHandler(),
|
||||
StreamHandler(
|
||||
sys.stdout,
|
||||
bubble=False,
|
||||
level=loggingLevel
|
||||
),
|
||||
TimedRotatingFileHandler(
|
||||
logPath,
|
||||
level=0,
|
||||
backup_count=3,
|
||||
bubble=True,
|
||||
date_format='%Y-%m-%d',
|
||||
),
|
||||
])
|
||||
else:
|
||||
logging_setup = NestedSetup([
|
||||
# make sure we never bubble up to the stderr handler
|
||||
# if we run out of setup handling
|
||||
NullHandler(),
|
||||
FingersCrossedHandler(
|
||||
TimedRotatingFileHandler(
|
||||
logPath,
|
||||
level=0,
|
||||
backup_count=3,
|
||||
bubble=False,
|
||||
date_format='%Y-%m-%d',
|
||||
),
|
||||
action_level=ERROR,
|
||||
buffer_size=1000,
|
||||
# pull_information=True,
|
||||
# reset=False,
|
||||
)
|
||||
])
|
||||
except:
|
||||
print("Critical error attempting to setup logging. Falling back to console only.")
|
||||
logging_setup = NestedSetup([
|
||||
# make sure we never bubble up to the stderr handler
|
||||
# if we run out of setup handling
|
||||
NullHandler(),
|
||||
StreamHandler(
|
||||
sys.stdout,
|
||||
bubble=False
|
||||
)
|
||||
])
|
||||
|
||||
with logging_setup.threadbound():
|
||||
|
||||
# Output all stdout (print) messages as warnings
|
||||
try:
|
||||
sys.stdout = LoggerWriter(pyfalog.warning)
|
||||
except:
|
||||
pyfalog.critical("Cannot redirect. Continuing without writing stdout to log.")
|
||||
|
||||
# Output all stderr (stacktrace) messages as critical
|
||||
try:
|
||||
sys.stderr = LoggerWriter(pyfalog.critical)
|
||||
except:
|
||||
pyfalog.critical("Cannot redirect. Continuing without writing stderr to log.")
|
||||
|
||||
|
||||
class LoggerWriter(object):
|
||||
def __init__(self, level):
|
||||
# self.level is really like using log.debug(message)
|
||||
# at least in my case
|
||||
self.level = level
|
||||
|
||||
def write(self, message):
|
||||
# if statement reduces the amount of newlines that are
|
||||
# printed to the logger
|
||||
if message.strip() != '':
|
||||
self.level(message.replace("\n", ""))
|
||||
|
||||
def flush(self):
|
||||
# create a flush method so things can be flushed when
|
||||
# the system wants to. Not sure if simply 'printing'
|
||||
# sys.stderr is the correct way to do it, but it seemed
|
||||
# to work properly for me.
|
||||
self.level(sys.stderr)
|
||||
|
||||
70
dist_assets/linux/pyfa-linux.spec
Normal file
70
dist_assets/linux/pyfa-linux.spec
Normal file
@@ -0,0 +1,70 @@
|
||||
# -*- mode: python -*-
|
||||
|
||||
import os
|
||||
from itertools import chain
|
||||
import subprocess
|
||||
|
||||
label = subprocess.check_output([
|
||||
"git", "describe", "--tags"]).strip()
|
||||
|
||||
with open('gitversion', 'w+') as f:
|
||||
f.write(label.decode())
|
||||
|
||||
block_cipher = None
|
||||
|
||||
|
||||
added_files = [
|
||||
( 'imgs/gui/*.png', 'imgs/gui' ),
|
||||
( 'imgs/gui/*.gif', 'imgs/gui' ),
|
||||
( 'imgs/icons/*.png', 'imgs/icons' ),
|
||||
( 'imgs/renders/*.png', 'imgs/renders' ),
|
||||
( 'dist_assets/win/pyfa.ico', '.' ),
|
||||
( 'dist_assets/cacert.pem', '.' ),
|
||||
( 'eve.db', '.' ),
|
||||
( 'README.md', '.' ),
|
||||
( 'LICENSE', '.' ),
|
||||
( 'gitversion', '.' ),
|
||||
]
|
||||
|
||||
import_these = []
|
||||
|
||||
# Walk directories that do dynamic importing
|
||||
paths = ('eos/effects', 'eos/db/migrations', 'service/conversions')
|
||||
for root, folders, files in chain.from_iterable(os.walk(path) for path in paths):
|
||||
for file_ in files:
|
||||
if file_.endswith(".py") and not file_.startswith("_"):
|
||||
mod_name = "{}.{}".format(
|
||||
root.replace("/", "."),
|
||||
file_.split(".py")[0],
|
||||
)
|
||||
import_these.append(mod_name)
|
||||
|
||||
|
||||
a = Analysis(['pyfa.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=added_files,
|
||||
hiddenimports=import_these,
|
||||
hookspath=[],
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher)
|
||||
pyz = PYZ(a.pure, a.zipped_data,
|
||||
cipher=block_cipher)
|
||||
exe = EXE(pyz,
|
||||
a.scripts,
|
||||
exclude_binaries=True,
|
||||
name='pyfa',
|
||||
debug=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
console=True )
|
||||
coll = COLLECT(exe,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
strip=False,
|
||||
upx=True,
|
||||
name='pyfa')
|
||||
74
dist_assets/mac/pyfa.spec
Normal file
74
dist_assets/mac/pyfa.spec
Normal file
@@ -0,0 +1,74 @@
|
||||
# -*- mode: python -*-
|
||||
|
||||
import os
|
||||
from itertools import chain
|
||||
import subprocess
|
||||
import requests.certs
|
||||
|
||||
label = subprocess.check_output([
|
||||
"git", "describe", "--tags"]).strip()
|
||||
|
||||
with open('.version', 'w+') as f:
|
||||
f.write(label.decode())
|
||||
|
||||
block_cipher = None
|
||||
|
||||
added_files = [
|
||||
('../../imgs/gui/*.png', 'imgs/gui'),
|
||||
('../../imgs/gui/*.gif', 'imgs/gui'),
|
||||
('../../imgs/icons/*.png', 'imgs/icons'),
|
||||
('../../imgs/renders/*.png', 'imgs/renders'),
|
||||
('../../dist_assets/win/pyfa.ico', '.'),
|
||||
('../../service/jargon/*.yaml', 'service/jargon'),
|
||||
(requests.certs.where(), '.'), # is this needed anymore?
|
||||
('../../eve.db', '.'),
|
||||
('../../README.md', '.'),
|
||||
('../../LICENSE', '.'),
|
||||
('../../.version', '.'),
|
||||
]
|
||||
|
||||
|
||||
import_these = []
|
||||
|
||||
# Walk directories that do dynamic importing
|
||||
paths = ('eos/effects', 'eos/db/migrations', 'service/conversions')
|
||||
for root, folders, files in chain.from_iterable(os.walk(path) for path in paths):
|
||||
for file_ in files:
|
||||
if file_.endswith(".py") and not file_.startswith("_"):
|
||||
mod_name = "{}.{}".format(
|
||||
root.replace("/", "."),
|
||||
file_.split(".py")[0],
|
||||
)
|
||||
import_these.append(mod_name)
|
||||
|
||||
a = Analysis([r'../../pyfa.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=added_files,
|
||||
hiddenimports=import_these,
|
||||
hookspath=['dist_assets/pyinstaller_hooks'],
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher)
|
||||
pyz = PYZ(a.pure, a.zipped_data,
|
||||
cipher=block_cipher)
|
||||
exe = EXE(pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
name='pyfa',
|
||||
debug=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
runtime_tmpdir=None,
|
||||
console=False ,
|
||||
icon='dist_assets/mac/pyfa.icns',
|
||||
)
|
||||
|
||||
app = BUNDLE(exe,
|
||||
name='pyfa.app',
|
||||
icon=None,
|
||||
bundle_identifier=None)
|
||||
78
dist_assets/pyinstaller_hooks/hook-matplotlib.backends.py
Normal file
78
dist_assets/pyinstaller_hooks/hook-matplotlib.backends.py
Normal file
@@ -0,0 +1,78 @@
|
||||
# This apes hook-matplotlib.backends.py, but REMOVES backends, all but
|
||||
# the ones in the list below.
|
||||
# Courtesy of https://github.com/bpteague/cytoflow/blob/70f9291/packaging/hook-matplotlib.backends.py
|
||||
|
||||
KEEP = ["WXAgg", "WX", "agg"]
|
||||
|
||||
from PyInstaller.compat import is_darwin
|
||||
from PyInstaller.utils.hooks import (
|
||||
eval_statement, exec_statement, logger)
|
||||
|
||||
|
||||
def get_matplotlib_backend_module_names():
|
||||
"""
|
||||
List the names of all matplotlib backend modules importable under the
|
||||
current Python installation.
|
||||
Returns
|
||||
----------
|
||||
list
|
||||
List of the fully-qualified names of all such modules.
|
||||
"""
|
||||
# Statement safely importing a single backend module.
|
||||
import_statement = """
|
||||
import os, sys
|
||||
# Preserve stdout.
|
||||
sys_stdout = sys.stdout
|
||||
try:
|
||||
# Redirect output printed by this importation to "/dev/null", preventing
|
||||
# such output from being erroneously interpreted as an error.
|
||||
with open(os.devnull, 'w') as dev_null:
|
||||
sys.stdout = dev_null
|
||||
__import__('%s')
|
||||
# If this is an ImportError, print this exception's message without a traceback.
|
||||
# ImportError messages are human-readable and require no additional context.
|
||||
except ImportError as exc:
|
||||
sys.stdout = sys_stdout
|
||||
print(exc)
|
||||
# Else, print this exception preceded by a traceback. traceback.print_exc()
|
||||
# prints to stderr rather than stdout and must not be called here!
|
||||
except Exception:
|
||||
sys.stdout = sys_stdout
|
||||
import traceback
|
||||
print(traceback.format_exc())
|
||||
"""
|
||||
|
||||
# List of the human-readable names of all available backends.
|
||||
backend_names = eval_statement(
|
||||
'import matplotlib; print(matplotlib.rcsetup.all_backends)')
|
||||
|
||||
# List of the fully-qualified names of all importable backend modules.
|
||||
module_names = []
|
||||
|
||||
# If the current system is not OS X and the "CocoaAgg" backend is available,
|
||||
# remove this backend from consideration. Attempting to import this backend
|
||||
# on non-OS X systems halts the current subprocess without printing output
|
||||
# or raising exceptions, preventing its reliable detection.
|
||||
if not is_darwin and 'CocoaAgg' in backend_names:
|
||||
backend_names.remove('CocoaAgg')
|
||||
|
||||
# For safety, attempt to import each backend in a unique subprocess.
|
||||
for backend_name in backend_names:
|
||||
if backend_name in KEEP:
|
||||
continue
|
||||
|
||||
module_name = 'matplotlib.backends.backend_%s' % backend_name.lower()
|
||||
stdout = exec_statement(import_statement % module_name)
|
||||
|
||||
# If no output was printed, this backend is importable.
|
||||
if not stdout:
|
||||
module_names.append(module_name)
|
||||
logger.info(' Matplotlib backend "%s": removed' % backend_name)
|
||||
|
||||
return module_names
|
||||
|
||||
# Freeze all importable backends, as PyInstaller is unable to determine exactly
|
||||
# which backends are required by the current program.
|
||||
e=get_matplotlib_backend_module_names()
|
||||
print(e)
|
||||
excludedimports = e
|
||||
@@ -1,35 +1,37 @@
|
||||
# -*- mode: python -*-
|
||||
|
||||
# Note: This script is provided AS-IS for those that may be interested.
|
||||
# pyfa does not currently support pyInstaller (or any other build process) 100% at the moment
|
||||
|
||||
# Command line to build:
|
||||
# (Run from directory where pyfa.py and pyfa.spec lives.)
|
||||
# c:\Python27\scripts\pyinstaller.exe --clean --noconfirm --windowed --upx-dir=.\scripts\upx.exe pyfa.spec
|
||||
|
||||
# Don't forget to change the path to where your pyfa.py and pyfa.spec lives
|
||||
# pathex=['C:\\Users\\Ebag333\\Documents\\GitHub\\Ebag333\\Pyfa'],
|
||||
|
||||
import os
|
||||
from itertools import chain
|
||||
import subprocess
|
||||
import requests.certs
|
||||
|
||||
label = subprocess.check_output([
|
||||
"git", "describe", "--tags"]).strip()
|
||||
|
||||
with open('.version', 'w+') as f:
|
||||
f.write(label.decode())
|
||||
|
||||
block_cipher = None
|
||||
|
||||
added_files = [
|
||||
( 'imgs/gui/*.png', 'imgs/gui' ),
|
||||
( 'imgs/gui/*.gif', 'imgs/gui' ),
|
||||
( 'imgs/icons/*.png', 'imgs/icons' ),
|
||||
( 'imgs/renders/*.png', 'imgs/renders' ),
|
||||
( 'dist_assets/win/pyfa.ico', '.' ),
|
||||
( 'dist_assets/cacert.pem', '.' ),
|
||||
( 'eve.db', '.' ),
|
||||
( 'README.md', '.' ),
|
||||
( 'LICENSE', '.' ),
|
||||
('../../imgs/gui/*.png', 'imgs/gui'),
|
||||
('../../imgs/gui/*.gif', 'imgs/gui'),
|
||||
('../../imgs/icons/*.png', 'imgs/icons'),
|
||||
('../../imgs/renders/*.png', 'imgs/renders'),
|
||||
('../../service/jargon/*.yaml', 'service/jargon'),
|
||||
('../../dist_assets/win/pyfa.ico', '.'),
|
||||
(requests.certs.where(), '.'), # is this needed anymore?
|
||||
('../../eve.db', '.'),
|
||||
('../../README.md', '.'),
|
||||
('../../LICENSE', '.'),
|
||||
('../../.version', '.'),
|
||||
]
|
||||
|
||||
import_these = []
|
||||
|
||||
# Walk eos.effects and add all effects so we can import them properly
|
||||
for root, folders, files in os.walk("eos/effects"):
|
||||
# Walk directories that do dynamic importing
|
||||
paths = ('eos/effects', 'eos/db/migrations', 'service/conversions')
|
||||
for root, folders, files in chain.from_iterable(os.walk(path) for path in paths):
|
||||
for file_ in files:
|
||||
if file_.endswith(".py") and not file_.startswith("_"):
|
||||
mod_name = "{}.{}".format(
|
||||
@@ -38,25 +40,24 @@ for root, folders, files in os.walk("eos/effects"):
|
||||
)
|
||||
import_these.append(mod_name)
|
||||
|
||||
a = Analysis(
|
||||
['pyfa.py'],
|
||||
pathex=['C:\\projects\\pyfa\\'],
|
||||
a = Analysis(['../../pyfa.py'],
|
||||
pathex=[
|
||||
# Need this, see https://github.com/pyinstaller/pyinstaller/issues/1566
|
||||
# To get this, download and install windows 10 SDK
|
||||
# If not building on Windows 10, this might be optional
|
||||
r'C:\Program Files (x86)\Windows Kits\10\Redist\ucrt\DLLs\x86'],
|
||||
binaries=[],
|
||||
datas=added_files,
|
||||
hiddenimports=import_these,
|
||||
hookspath=[],
|
||||
hookspath=['dist_assets/pyinstaller_hooks'],
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
excludes=['Tkinter'],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher,
|
||||
)
|
||||
cipher=block_cipher)
|
||||
|
||||
pyz = PYZ(
|
||||
a.pure,
|
||||
a.zipped_data,
|
||||
cipher=block_cipher,
|
||||
)
|
||||
pyz = PYZ(a.pure, a.zipped_data,
|
||||
cipher=block_cipher)
|
||||
|
||||
exe = EXE(pyz,
|
||||
a.scripts,
|
||||
@@ -67,7 +68,6 @@ exe = EXE(pyz,
|
||||
upx=True,
|
||||
name='pyfa',
|
||||
icon='dist_assets/win/pyfa.ico',
|
||||
onefile=False,
|
||||
)
|
||||
|
||||
coll = COLLECT(
|
||||
@@ -77,7 +77,6 @@ coll = COLLECT(
|
||||
a.datas,
|
||||
strip=False,
|
||||
upx=True,
|
||||
onefile=False,
|
||||
name='pyfa',
|
||||
icon='dist_assets/win/pyfa.ico',
|
||||
)
|
||||
)
|
||||
45
dist_assets/win/version_resource.py
Normal file
45
dist_assets/win/version_resource.py
Normal file
@@ -0,0 +1,45 @@
|
||||
# UTF-8
|
||||
#
|
||||
# For more details about fixed file info 'ffi' see:
|
||||
# http://msdn.microsoft.com/en-us/library/ms646997.aspx
|
||||
VSVersionInfo(
|
||||
ffi=FixedFileInfo(
|
||||
# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
|
||||
# Set not needed items to zero 0.
|
||||
filevers=(1, 15, 1, 0),
|
||||
prodvers=(1, 15, 1, 0),
|
||||
# Contains a bitmask that specifies the valid bits 'flags'r
|
||||
mask=0x3f,
|
||||
# Contains a bitmask that specifies the Boolean attributes of the file.
|
||||
flags=0x0,
|
||||
# The operating system for which this file was designed.
|
||||
# 0x4 - NT and there is no need to change it.
|
||||
OS=0x40004,
|
||||
# The general type of file.
|
||||
# 0x1 - the file is an application.
|
||||
fileType=0x1,
|
||||
# The function of the file.
|
||||
# 0x0 - the function is not defined for this fileType
|
||||
subtype=0x0,
|
||||
# Creation date and time stamp.
|
||||
date=(0, 0)
|
||||
),
|
||||
kids=[
|
||||
StringFileInfo(
|
||||
[
|
||||
StringTable(
|
||||
u'040904E4',
|
||||
[StringStruct(u'LegalCopyright', u''),
|
||||
StringStruct(u'InternalName', u'pyfa.exe'),
|
||||
StringStruct(u'FileVersion', u'1.15.1.0'),
|
||||
StringStruct(u'CompanyName', u''),
|
||||
StringStruct(u'OriginalFilename', u'pyfa.exe'),
|
||||
StringStruct(u'ProductVersion', u'1.15.1.0'),
|
||||
StringStruct(u'FileDescription', u'Python fitting assistant'),
|
||||
StringStruct(u'LegalTrademarks', u''),
|
||||
StringStruct(u'Comments', u''),
|
||||
StringStruct(u'ProductName', u'pyfa')])
|
||||
]),
|
||||
VarFileInfo([VarStruct(u'Translation', [1033, 1252])])
|
||||
]
|
||||
)
|
||||
@@ -1,6 +1,7 @@
|
||||
import heapq
|
||||
import time
|
||||
from math import sqrt, exp
|
||||
from functools import reduce
|
||||
|
||||
DAY = 24 * 60 * 60 * 1000
|
||||
|
||||
@@ -71,7 +72,7 @@ class CapSimulator(object):
|
||||
disable_period = False
|
||||
|
||||
# Loop over modules, clearing clipSize if applicable, and group modules based on attributes
|
||||
for (duration, capNeed, clipSize, disableStagger) in self.modules:
|
||||
for (duration, capNeed, clipSize, disableStagger, reloadTime) in self.modules:
|
||||
if self.scale:
|
||||
duration, capNeed = self.scale_activation(duration, capNeed)
|
||||
|
||||
@@ -79,24 +80,25 @@ class CapSimulator(object):
|
||||
# a cap booster module.
|
||||
if not self.reload and capNeed > 0:
|
||||
clipSize = 0
|
||||
reloadTime = 0
|
||||
|
||||
# Group modules based on their properties
|
||||
if (duration, capNeed, clipSize, disableStagger) in mods:
|
||||
mods[(duration, capNeed, clipSize, disableStagger)] += 1
|
||||
if (duration, capNeed, clipSize, disableStagger, reloadTime) in mods:
|
||||
mods[(duration, capNeed, clipSize, disableStagger, reloadTime)] += 1
|
||||
else:
|
||||
mods[(duration, capNeed, clipSize, disableStagger)] = 1
|
||||
mods[(duration, capNeed, clipSize, disableStagger, reloadTime)] = 1
|
||||
|
||||
# Loop over grouped modules, configure staggering and push to the simulation state
|
||||
for (duration, capNeed, clipSize, disableStagger), amount in mods.iteritems():
|
||||
for (duration, capNeed, clipSize, disableStagger, reloadTime), amount in mods.items():
|
||||
if self.stagger and not disableStagger:
|
||||
if clipSize == 0:
|
||||
duration = int(duration / amount)
|
||||
else:
|
||||
stagger_amount = (duration * clipSize + 10000) / (amount * clipSize)
|
||||
stagger_amount = (duration * clipSize + reloadTime) / (amount * clipSize)
|
||||
for i in range(1, amount):
|
||||
heapq.heappush(self.state,
|
||||
[i * stagger_amount, duration,
|
||||
capNeed, 0, clipSize])
|
||||
capNeed, 0, clipSize, reloadTime])
|
||||
else:
|
||||
capNeed *= amount
|
||||
|
||||
@@ -106,7 +108,7 @@ class CapSimulator(object):
|
||||
if clipSize:
|
||||
disable_period = True
|
||||
|
||||
heapq.heappush(self.state, [0, duration, capNeed, 0, clipSize])
|
||||
heapq.heappush(self.state, [0, duration, capNeed, 0, clipSize, reloadTime])
|
||||
|
||||
if disable_period:
|
||||
self.period = self.t_max
|
||||
@@ -143,7 +145,7 @@ class CapSimulator(object):
|
||||
|
||||
while 1:
|
||||
activation = pop(state)
|
||||
t_now, duration, capNeed, shot, clipSize = activation
|
||||
t_now, duration, capNeed, shot, clipSize, reloadTime = activation
|
||||
if t_now >= t_max:
|
||||
break
|
||||
|
||||
@@ -179,7 +181,7 @@ class CapSimulator(object):
|
||||
if clipSize:
|
||||
if shot % clipSize == 0:
|
||||
shot = 0
|
||||
t_now += 10000 # include reload time
|
||||
t_now += reloadTime # include reload time
|
||||
activation[0] = t_now
|
||||
activation[3] = shot
|
||||
|
||||
@@ -192,7 +194,7 @@ class CapSimulator(object):
|
||||
|
||||
# calculate EVE's stability value
|
||||
try:
|
||||
avgDrain = reduce(float.__add__, map(lambda x: x[2] / x[1], self.state), 0.0)
|
||||
avgDrain = reduce(float.__add__, [x[2] / x[1] for x in self.state], 0.0)
|
||||
self.cap_stable_eve = 0.25 * (1.0 + sqrt(-(2.0 * avgDrain * tau - capCapacity) / capCapacity)) ** 2
|
||||
except ValueError:
|
||||
self.cap_stable_eve = 0.0
|
||||
|
||||
@@ -11,14 +11,14 @@ debug = False
|
||||
gamedataCache = True
|
||||
saveddataCache = True
|
||||
gamedata_version = ""
|
||||
gamedata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "eve.db")), sys.getfilesystemencoding())
|
||||
gamedata_connectionstring = 'sqlite:///' + realpath(join(dirname(abspath(__file__)), "..", "eve.db"))
|
||||
pyfalog.debug("Gamedata connection string: {0}", gamedata_connectionstring)
|
||||
|
||||
if istravis is True or hasattr(sys, '_called_from_test'):
|
||||
# Running in Travis. Run saveddata database in memory.
|
||||
saveddata_connectionstring = 'sqlite:///:memory:'
|
||||
else:
|
||||
saveddata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "saveddata", "saveddata.db")), sys.getfilesystemencoding())
|
||||
saveddata_connectionstring = 'sqlite:///' + realpath(join(dirname(abspath(__file__)), "..", "saveddata", "saveddata-py3-db.db"))
|
||||
|
||||
pyfalog.debug("Saveddata connection string: {0}", saveddata_connectionstring)
|
||||
|
||||
@@ -28,4 +28,4 @@ settings = {
|
||||
}
|
||||
|
||||
# Autodetect path, only change if the autodetection bugs out.
|
||||
path = dirname(unicode(__file__, sys.getfilesystemencoding()))
|
||||
path = dirname(__file__)
|
||||
|
||||
@@ -22,7 +22,7 @@ import threading
|
||||
from sqlalchemy import MetaData, create_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
import migration
|
||||
from . import migration
|
||||
from eos import config
|
||||
from logbook import Logger
|
||||
|
||||
@@ -76,7 +76,7 @@ sd_lock = threading.RLock()
|
||||
# noinspection PyPep8
|
||||
from eos.db.gamedata import alphaClones, attribute, category, effect, group, icon, item, marketGroup, metaData, metaGroup, queries, traits, unit
|
||||
# noinspection PyPep8
|
||||
from eos.db.saveddata import booster, cargo, character, crest, damagePattern, databaseRepair, drone, fighter, fit, implant, implantSet, loadDefaultDatabaseValues, \
|
||||
from eos.db.saveddata import booster, cargo, character, damagePattern, databaseRepair, drone, fighter, fit, implant, implantSet, loadDefaultDatabaseValues, \
|
||||
miscData, module, override, price, queries, skill, targetResists, user
|
||||
|
||||
# Import queries
|
||||
|
||||
@@ -81,7 +81,7 @@ def getItem(lookfor, eager=None):
|
||||
item = gamedata_session.query(Item).get(lookfor)
|
||||
else:
|
||||
item = gamedata_session.query(Item).options(*processEager(eager)).filter(Item.ID == lookfor).first()
|
||||
elif isinstance(lookfor, basestring):
|
||||
elif isinstance(lookfor, str):
|
||||
if lookfor in itemNameMap:
|
||||
id = itemNameMap[lookfor]
|
||||
if eager is None:
|
||||
@@ -154,7 +154,7 @@ def getGroup(lookfor, eager=None):
|
||||
group = gamedata_session.query(Group).get(lookfor)
|
||||
else:
|
||||
group = gamedata_session.query(Group).options(*processEager(eager)).filter(Group.ID == lookfor).first()
|
||||
elif isinstance(lookfor, basestring):
|
||||
elif isinstance(lookfor, str):
|
||||
if lookfor in groupNameMap:
|
||||
id = groupNameMap[lookfor]
|
||||
if eager is None:
|
||||
@@ -181,7 +181,7 @@ def getCategory(lookfor, eager=None):
|
||||
else:
|
||||
category = gamedata_session.query(Category).options(*processEager(eager)).filter(
|
||||
Category.ID == lookfor).first()
|
||||
elif isinstance(lookfor, basestring):
|
||||
elif isinstance(lookfor, str):
|
||||
if lookfor in categoryNameMap:
|
||||
id = categoryNameMap[lookfor]
|
||||
if eager is None:
|
||||
@@ -210,7 +210,7 @@ def getMetaGroup(lookfor, eager=None):
|
||||
else:
|
||||
metaGroup = gamedata_session.query(MetaGroup).options(*processEager(eager)).filter(
|
||||
MetaGroup.ID == lookfor).first()
|
||||
elif isinstance(lookfor, basestring):
|
||||
elif isinstance(lookfor, str):
|
||||
if lookfor in metaGroupNameMap:
|
||||
id = metaGroupNameMap[lookfor]
|
||||
if eager is None:
|
||||
@@ -245,7 +245,7 @@ def getMarketGroup(lookfor, eager=None):
|
||||
def getItemsByCategory(filter, where=None, eager=None):
|
||||
if isinstance(filter, int):
|
||||
filter = Category.ID == filter
|
||||
elif isinstance(filter, basestring):
|
||||
elif isinstance(filter, str):
|
||||
filter = Category.name == filter
|
||||
else:
|
||||
raise TypeError("Need integer or string as argument")
|
||||
@@ -257,7 +257,7 @@ def getItemsByCategory(filter, where=None, eager=None):
|
||||
|
||||
@cachedQuery(3, "where", "nameLike", "join")
|
||||
def searchItems(nameLike, where=None, join=None, eager=None):
|
||||
if not isinstance(nameLike, basestring):
|
||||
if not isinstance(nameLike, str):
|
||||
raise TypeError("Need string as argument")
|
||||
|
||||
if join is None:
|
||||
@@ -268,7 +268,7 @@ def searchItems(nameLike, where=None, join=None, eager=None):
|
||||
|
||||
items = gamedata_session.query(Item).options(*processEager(eager)).join(*join)
|
||||
for token in nameLike.split(' '):
|
||||
token_safe = u"%{0}%".format(sqlizeString(token))
|
||||
token_safe = "%{0}%".format(sqlizeString(token))
|
||||
if where is not None:
|
||||
items = items.filter(and_(Item.name.like(token_safe, escape="\\"), where))
|
||||
else:
|
||||
@@ -279,12 +279,12 @@ def searchItems(nameLike, where=None, join=None, eager=None):
|
||||
|
||||
@cachedQuery(3, "where", "nameLike", "join")
|
||||
def searchSkills(nameLike, where=None, eager=None):
|
||||
if not isinstance(nameLike, basestring):
|
||||
if not isinstance(nameLike, str):
|
||||
raise TypeError("Need string as argument")
|
||||
|
||||
items = gamedata_session.query(Item).options(*processEager(eager)).join(Item.group, Group.category)
|
||||
for token in nameLike.split(' '):
|
||||
token_safe = u"%{0}%".format(sqlizeString(token))
|
||||
token_safe = "%{0}%".format(sqlizeString(token))
|
||||
if where is not None:
|
||||
items = items.filter(and_(Item.name.like(token_safe, escape="\\"), Category.ID == 16, where))
|
||||
else:
|
||||
@@ -322,7 +322,7 @@ def getVariations(itemids, groupIDs=None, where=None, eager=None):
|
||||
|
||||
@cachedQuery(1, "attr")
|
||||
def getAttributeInfo(attr, eager=None):
|
||||
if isinstance(attr, basestring):
|
||||
if isinstance(attr, str):
|
||||
filter = AttributeInfo.name == attr
|
||||
elif isinstance(attr, int):
|
||||
filter = AttributeInfo.ID == attr
|
||||
@@ -337,7 +337,7 @@ def getAttributeInfo(attr, eager=None):
|
||||
|
||||
@cachedQuery(1, "field")
|
||||
def getMetaData(field):
|
||||
if isinstance(field, basestring):
|
||||
if isinstance(field, str):
|
||||
data = gamedata_session.query(MetaData).get(field)
|
||||
else:
|
||||
raise TypeError("Need string as argument")
|
||||
@@ -367,7 +367,7 @@ def getRequiredFor(itemID, attrMapping):
|
||||
|
||||
skillToLevelClauses = []
|
||||
|
||||
for attrSkill, attrLevel in attrMapping.iteritems():
|
||||
for attrSkill, attrLevel in attrMapping.items():
|
||||
skillToLevelClauses.append(and_(Attribute1.attributeID == attrSkill, Attribute2.attributeID == attrLevel))
|
||||
|
||||
queryOr = or_(*skillToLevelClauses)
|
||||
|
||||
@@ -3,7 +3,7 @@ import shutil
|
||||
import time
|
||||
|
||||
import config
|
||||
import migrations
|
||||
from . import migrations
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
@@ -34,7 +34,7 @@ def update(saveddata_engine):
|
||||
|
||||
shutil.copyfile(config.saveDB, toFile)
|
||||
|
||||
for version in xrange(dbVersion, appVersion):
|
||||
for version in range(dbVersion, appVersion):
|
||||
func = migrations.updates[version + 1]
|
||||
if func:
|
||||
pyfalog.info("Applying database update: {0}", version + 1)
|
||||
|
||||
@@ -15,7 +15,27 @@ updates = {}
|
||||
appVersion = 0
|
||||
|
||||
prefix = __name__ + "."
|
||||
for importer, modname, ispkg in pkgutil.iter_modules(__path__, prefix):
|
||||
|
||||
# load modules to work based with and without pyinstaller
|
||||
# from: https://github.com/webcomics/dosage/blob/master/dosagelib/loader.py
|
||||
# see: https://github.com/pyinstaller/pyinstaller/issues/1905
|
||||
|
||||
# load modules using iter_modules()
|
||||
# (should find all filters in normal build, but not pyinstaller)
|
||||
module_names = [m[1] for m in pkgutil.iter_modules(__path__, prefix)]
|
||||
|
||||
# special handling for PyInstaller
|
||||
importers = map(pkgutil.get_importer, __path__)
|
||||
toc = set()
|
||||
for i in importers:
|
||||
if hasattr(i, 'toc'):
|
||||
toc |= i.toc
|
||||
|
||||
for elm in toc:
|
||||
if elm.startswith(prefix):
|
||||
module_names.append(elm)
|
||||
|
||||
for modname in module_names:
|
||||
# loop through python files, extracting update number and function, and
|
||||
# adding it to a list
|
||||
modname_tail = modname.rsplit('.', 1)[-1]
|
||||
|
||||
@@ -91,7 +91,7 @@ def upgrade(saveddata_engine):
|
||||
saveddata_engine.execute("ALTER TABLE fits ADD COLUMN targetResistsID INTEGER;")
|
||||
|
||||
# Convert modules
|
||||
for replacement_item, list in CONVERSIONS.iteritems():
|
||||
for replacement_item, list in CONVERSIONS.items():
|
||||
for retired_item in list:
|
||||
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
|
||||
(replacement_item, retired_item))
|
||||
|
||||
@@ -108,7 +108,7 @@ CONVERSIONS = {
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
# Convert modules
|
||||
for replacement_item, list in CONVERSIONS.iteritems():
|
||||
for replacement_item, list in CONVERSIONS.items():
|
||||
for retired_item in list:
|
||||
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
|
||||
(replacement_item, retired_item))
|
||||
|
||||
@@ -332,7 +332,7 @@ CONVERSIONS = {
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
# Convert modules
|
||||
for replacement_item, list in CONVERSIONS.iteritems():
|
||||
for replacement_item, list in CONVERSIONS.items():
|
||||
for retired_item in list:
|
||||
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
|
||||
(replacement_item, retired_item))
|
||||
|
||||
@@ -60,7 +60,7 @@ CONVERSIONS = {
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
# Convert modules
|
||||
for replacement_item, list in CONVERSIONS.iteritems():
|
||||
for replacement_item, list in CONVERSIONS.items():
|
||||
for retired_item in list:
|
||||
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
|
||||
(replacement_item, retired_item))
|
||||
|
||||
@@ -29,7 +29,7 @@ def upgrade(saveddata_engine):
|
||||
"targetResists": 2
|
||||
}
|
||||
|
||||
for table in tables.keys():
|
||||
for table in list(tables.keys()):
|
||||
|
||||
# midnight brain, there's probably a much more simple way to do this, but fuck it
|
||||
if tables[table] > 0:
|
||||
|
||||
@@ -4204,7 +4204,7 @@ conversion2 = {
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
# First we want to get a list of fittings that are completely fitted out with subsystems
|
||||
oldItems = [str(x) for x in conversion2.iterkeys()]
|
||||
oldItems = [str(x) for x in conversion2.keys()]
|
||||
|
||||
# I can't figure out a way to get IN operator to work when supplying a list using a parameterized query. So I'm
|
||||
# doing it the shitty way by formatting the SQL string. Don't do this kids!
|
||||
@@ -4239,7 +4239,7 @@ def upgrade(saveddata_engine):
|
||||
# if something fails, fuck it, we tried. It'll default to the generic conversion below
|
||||
continue
|
||||
|
||||
for oldItem, newItem in conversion2.iteritems():
|
||||
for oldItem, newItem in conversion2.items():
|
||||
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
|
||||
(newItem, oldItem))
|
||||
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?',
|
||||
|
||||
9
eos/db/migrations/upgrade27.py
Normal file
9
eos/db/migrations/upgrade27.py
Normal file
@@ -0,0 +1,9 @@
|
||||
"""
|
||||
Migration 27
|
||||
|
||||
- Resets all alpha clones to 1 (CCP consolidated all alpha's into one skillset)
|
||||
"""
|
||||
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
saveddata_engine.execute("UPDATE characters SET alphaCloneID = 1 WHERE alphaCloneID IS NOT NULL")
|
||||
@@ -133,7 +133,7 @@ CONVERSIONS = {
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
# Convert modules
|
||||
for replacement_item, list in CONVERSIONS.iteritems():
|
||||
for replacement_item, list in CONVERSIONS.items():
|
||||
for retired_item in list:
|
||||
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
|
||||
(replacement_item, retired_item))
|
||||
|
||||
@@ -17,7 +17,7 @@ CONVERSIONS = {
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
# Convert ships
|
||||
for replacement_item, list in CONVERSIONS.iteritems():
|
||||
for replacement_item, list in CONVERSIONS.items():
|
||||
for retired_item in list:
|
||||
saveddata_engine.execute('UPDATE "fits" SET "shipID" = ? WHERE "shipID" = ?',
|
||||
(replacement_item, retired_item))
|
||||
|
||||
@@ -77,7 +77,7 @@ CONVERSIONS = {
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
# Convert modules
|
||||
for replacement_item, list in CONVERSIONS.iteritems():
|
||||
for replacement_item, list in CONVERSIONS.items():
|
||||
for retired_item in list:
|
||||
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
|
||||
(replacement_item, retired_item))
|
||||
|
||||
@@ -12,7 +12,6 @@ __all__ = [
|
||||
"miscData",
|
||||
"targetResists",
|
||||
"override",
|
||||
"crest",
|
||||
"implantSet",
|
||||
"loadDefaultDatabaseValues"
|
||||
]
|
||||
|
||||
@@ -17,24 +17,24 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey, String, DateTime, Float
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey, String, DateTime, Float, UniqueConstraint
|
||||
from sqlalchemy.orm import relation, mapper
|
||||
import datetime
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.db.saveddata.implant import charImplants_table
|
||||
from eos.effectHandlerHelpers import HandledImplantBoosterList
|
||||
from eos.effectHandlerHelpers import HandledImplantBoosterList, HandledSsoCharacterList
|
||||
from eos.saveddata.implant import Implant
|
||||
from eos.saveddata.user import User
|
||||
from eos.saveddata.character import Character, Skill
|
||||
from eos.saveddata.ssocharacter import SsoCharacter
|
||||
|
||||
|
||||
|
||||
|
||||
characters_table = Table("characters", saveddata_meta,
|
||||
Column("ID", Integer, primary_key=True),
|
||||
Column("name", String, nullable=False),
|
||||
Column("apiID", Integer),
|
||||
Column("apiKey", String),
|
||||
Column("defaultChar", Integer),
|
||||
Column("chars", String, nullable=True),
|
||||
Column("defaultLevel", Integer, nullable=True),
|
||||
Column("alphaCloneID", Integer, nullable=True),
|
||||
Column("ownerID", ForeignKey("users.ID"), nullable=True),
|
||||
@@ -42,6 +42,28 @@ characters_table = Table("characters", saveddata_meta,
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now))
|
||||
|
||||
sso_table = Table("ssoCharacter", saveddata_meta,
|
||||
Column("ID", Integer, primary_key=True),
|
||||
Column("client", String, nullable=False),
|
||||
Column("characterID", Integer, nullable=False),
|
||||
Column("characterName", String, nullable=False),
|
||||
Column("refreshToken", String, nullable=False),
|
||||
Column("accessToken", String, nullable=False),
|
||||
Column("accessTokenExpires", DateTime, nullable=False),
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now),
|
||||
UniqueConstraint('client', 'characterID', name='uix_client_characterID'),
|
||||
UniqueConstraint('client', 'characterName', name='uix_client_characterName')
|
||||
)
|
||||
|
||||
sso_character_map_table = Table("ssoCharacterMap", saveddata_meta,
|
||||
Column("characterID", ForeignKey("characters.ID"), primary_key=True),
|
||||
Column("ssoCharacterID", ForeignKey("ssoCharacter.ID"), primary_key=True),
|
||||
)
|
||||
|
||||
|
||||
mapper(SsoCharacter, sso_table)
|
||||
|
||||
mapper(Character, characters_table,
|
||||
properties={
|
||||
"_Character__alphaCloneID": characters_table.c.alphaCloneID,
|
||||
@@ -63,5 +85,10 @@ mapper(Character, characters_table,
|
||||
primaryjoin=charImplants_table.c.charID == characters_table.c.ID,
|
||||
secondaryjoin=charImplants_table.c.implantID == Implant.ID,
|
||||
secondary=charImplants_table),
|
||||
"_Character__ssoCharacters" : relation(
|
||||
SsoCharacter,
|
||||
collection_class=HandledSsoCharacterList,
|
||||
backref='characters',
|
||||
secondary=sso_character_map_table)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
#
|
||||
# eos is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# eos is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, String, DateTime
|
||||
from sqlalchemy.orm import mapper
|
||||
import datetime
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.saveddata.crestchar 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),
|
||||
# These records aren't updated. Instead, they are dropped and created, hence we don't have a modified field
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now))
|
||||
|
||||
mapper(CrestChar, crest_table)
|
||||
@@ -68,7 +68,7 @@ class DefaultDatabaseValues(object):
|
||||
["[Hybrid Charges]Uranium", "0", "38.4", "57.6", "0"],
|
||||
["[Missiles]Mjolnir", "100", "0", "0", "0"], ["[Missiles]Inferno", "0", "100", "0", "0"],
|
||||
["[Missiles]Scourge", "0", "0", "100", "0"], ["[Missiles]Nova", "0", "0", "0", "100"],
|
||||
["[Missiles][Structure) Standup Missile", "100", "100", "100", "100"],
|
||||
["[Missiles][Structure] Standup Missile", "100", "100", "100", "100"],
|
||||
["[Projectile Ammo][T2] Tremor", "0", "0", "24", "40"],
|
||||
["[Projectile Ammo][T2] Quake", "0", "0", "40", "72"],
|
||||
["[Projectile Ammo][T2] Hail", "0", "0", "26.4", "96.8"],
|
||||
|
||||
@@ -25,8 +25,10 @@ from eos.saveddata.price import Price
|
||||
|
||||
prices_table = Table("prices", saveddata_meta,
|
||||
Column("typeID", Integer, primary_key=True),
|
||||
Column("price", Float),
|
||||
Column("price", Float, default=0.0),
|
||||
Column("time", Integer, nullable=False),
|
||||
Column("failed", Integer))
|
||||
|
||||
mapper(Price, prices_table)
|
||||
mapper(Price, prices_table, properties={
|
||||
"_Price__price": prices_table.c.price,
|
||||
})
|
||||
|
||||
@@ -27,7 +27,7 @@ from eos.db.saveddata.fit import projectedFits_table
|
||||
from eos.db.util import processEager, processWhere
|
||||
from eos.saveddata.price import Price
|
||||
from eos.saveddata.user import User
|
||||
from eos.saveddata.crestchar import CrestChar
|
||||
from eos.saveddata.ssocharacter import SsoCharacter
|
||||
from eos.saveddata.damagePattern import DamagePattern
|
||||
from eos.saveddata.targetResists import TargetResists
|
||||
from eos.saveddata.character import Character
|
||||
@@ -109,9 +109,9 @@ if configVal is True:
|
||||
if type not in queryCache:
|
||||
return
|
||||
functionCache = queryCache[type]
|
||||
for _, localCache in functionCache.iteritems():
|
||||
for _, localCache in functionCache.items():
|
||||
toDelete = set()
|
||||
for cacheKey, info in localCache.iteritems():
|
||||
for cacheKey, info in localCache.items():
|
||||
IDs = info[1]
|
||||
if ID in IDs:
|
||||
toDelete.add(cacheKey)
|
||||
@@ -156,7 +156,7 @@ def getUser(lookfor, eager=None):
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
user = saveddata_session.query(User).options(*eager).filter(User.ID == lookfor).first()
|
||||
elif isinstance(lookfor, basestring):
|
||||
elif isinstance(lookfor, str):
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
user = saveddata_session.query(User).options(*eager).filter(User.username == lookfor).first()
|
||||
@@ -175,7 +175,7 @@ def getCharacter(lookfor, eager=None):
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
character = saveddata_session.query(Character).options(*eager).filter(Character.ID == lookfor).first()
|
||||
elif isinstance(lookfor, basestring):
|
||||
elif isinstance(lookfor, str):
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
character = saveddata_session.query(Character).options(*eager).filter(
|
||||
@@ -337,7 +337,7 @@ def clearPrices():
|
||||
|
||||
|
||||
def getMiscData(field):
|
||||
if isinstance(field, basestring):
|
||||
if isinstance(field, str):
|
||||
with sd_lock:
|
||||
data = saveddata_session.query(MiscData).get(field)
|
||||
else:
|
||||
@@ -391,7 +391,7 @@ def getDamagePattern(lookfor, eager=None):
|
||||
with sd_lock:
|
||||
pattern = saveddata_session.query(DamagePattern).options(*eager).filter(
|
||||
DamagePattern.ID == lookfor).first()
|
||||
elif isinstance(lookfor, basestring):
|
||||
elif isinstance(lookfor, str):
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
pattern = saveddata_session.query(DamagePattern).options(*eager).filter(
|
||||
@@ -412,7 +412,7 @@ def getTargetResists(lookfor, eager=None):
|
||||
with sd_lock:
|
||||
pattern = saveddata_session.query(TargetResists).options(*eager).filter(
|
||||
TargetResists.ID == lookfor).first()
|
||||
elif isinstance(lookfor, basestring):
|
||||
elif isinstance(lookfor, str):
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
pattern = saveddata_session.query(TargetResists).options(*eager).filter(
|
||||
@@ -433,7 +433,7 @@ def getImplantSet(lookfor, eager=None):
|
||||
with sd_lock:
|
||||
pattern = saveddata_session.query(ImplantSet).options(*eager).filter(
|
||||
TargetResists.ID == lookfor).first()
|
||||
elif isinstance(lookfor, basestring):
|
||||
elif isinstance(lookfor, str):
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
pattern = saveddata_session.query(ImplantSet).options(*eager).filter(TargetResists.name == lookfor).first()
|
||||
@@ -443,10 +443,10 @@ def getImplantSet(lookfor, eager=None):
|
||||
|
||||
|
||||
def searchFits(nameLike, where=None, eager=None):
|
||||
if not isinstance(nameLike, basestring):
|
||||
if not isinstance(nameLike, str):
|
||||
raise TypeError("Need string as argument")
|
||||
# Prepare our string for request
|
||||
nameLike = u"%{0}%".format(sqlizeString(nameLike))
|
||||
nameLike = "%{0}%".format(sqlizeString(nameLike))
|
||||
|
||||
# Add any extra components to the search to our where clause
|
||||
filter = processWhere(Fit.name.like(nameLike, escape="\\"), where)
|
||||
@@ -467,29 +467,28 @@ def getProjectedFits(fitID):
|
||||
raise TypeError("Need integer as argument")
|
||||
|
||||
|
||||
def getCrestCharacters(eager=None):
|
||||
def getSsoCharacters(clientHash, eager=None):
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
characters = saveddata_session.query(CrestChar).options(*eager).all()
|
||||
characters = saveddata_session.query(SsoCharacter).filter(SsoCharacter.client == clientHash).options(*eager).all()
|
||||
return characters
|
||||
|
||||
|
||||
@cachedQuery(CrestChar, 1, "lookfor")
|
||||
def getCrestCharacter(lookfor, eager=None):
|
||||
@cachedQuery(SsoCharacter, 1, "lookfor", "clientHash")
|
||||
def getSsoCharacter(lookfor, clientHash, eager=None):
|
||||
filter = SsoCharacter.client == clientHash
|
||||
|
||||
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()
|
||||
filter = and_(filter, SsoCharacter.ID == lookfor)
|
||||
elif isinstance(lookfor, str):
|
||||
filter = and_(filter, SsoCharacter.characterName == lookfor)
|
||||
else:
|
||||
raise TypeError("Need integer or string as argument")
|
||||
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
character = saveddata_session.query(SsoCharacter).options(*eager).filter(filter).first()
|
||||
|
||||
return character
|
||||
|
||||
|
||||
@@ -515,8 +514,8 @@ def removeInvalid(fits):
|
||||
invalids = [f for f in fits if f.isInvalid]
|
||||
|
||||
if invalids:
|
||||
map(fits.remove, invalids)
|
||||
map(saveddata_session.delete, invalids)
|
||||
list(map(fits.remove, invalids))
|
||||
list(map(saveddata_session.delete, invalids))
|
||||
saveddata_session.commit()
|
||||
|
||||
return fits
|
||||
@@ -544,7 +543,7 @@ def commit():
|
||||
try:
|
||||
saveddata_session.commit()
|
||||
saveddata_session.flush()
|
||||
except Exception:
|
||||
except Exception as ex:
|
||||
saveddata_session.rollback()
|
||||
exc_info = sys.exc_info()
|
||||
raise exc_info[0], exc_info[1], exc_info[2]
|
||||
raise exc_info[0](exc_info[1]).with_traceback(exc_info[2])
|
||||
|
||||
@@ -39,7 +39,7 @@ def processEager(eager):
|
||||
return tuple()
|
||||
else:
|
||||
l = []
|
||||
if isinstance(eager, basestring):
|
||||
if isinstance(eager, str):
|
||||
eager = (eager,)
|
||||
|
||||
for e in eager:
|
||||
@@ -50,7 +50,7 @@ def processEager(eager):
|
||||
|
||||
def _replacements(eagerString):
|
||||
splitEager = eagerString.split(".")
|
||||
for i in xrange(len(splitEager)):
|
||||
for i in range(len(splitEager)):
|
||||
part = splitEager[i]
|
||||
replacement = replace.get(part)
|
||||
if replacement:
|
||||
|
||||
@@ -115,7 +115,7 @@ class HandledList(list):
|
||||
class HandledModuleList(HandledList):
|
||||
def append(self, mod):
|
||||
emptyPosition = float("Inf")
|
||||
for i in xrange(len(self)):
|
||||
for i in range(len(self)):
|
||||
currMod = self[i]
|
||||
if currMod.isEmpty and not mod.isEmpty and currMod.slot == mod.slot:
|
||||
currPos = mod.position or i
|
||||
@@ -149,7 +149,7 @@ class HandledModuleList(HandledList):
|
||||
oldPos = mod.position
|
||||
|
||||
mod.position = None
|
||||
for i in xrange(oldPos, len(self)):
|
||||
for i in range(oldPos, len(self)):
|
||||
self[i].position -= 1
|
||||
|
||||
def toDummy(self, index):
|
||||
@@ -205,6 +205,16 @@ class HandledImplantBoosterList(HandledList):
|
||||
HandledList.append(self, thing)
|
||||
|
||||
|
||||
class HandledSsoCharacterList(list):
|
||||
def append(self, character):
|
||||
old = next((x for x in self if x.client == character.client), None)
|
||||
if old is not None:
|
||||
pyfalog.warning("Removing SSO Character with same hash: {}".format(repr(old)))
|
||||
list.remove(self, old)
|
||||
|
||||
list.append(self, character)
|
||||
|
||||
|
||||
class HandledProjectedModList(HandledList):
|
||||
def append(self, proj):
|
||||
if proj.isInvalid:
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#
|
||||
# Used by:
|
||||
# Modules named like: Memetic Algorithm Bank (8 of 8)
|
||||
# Implant: Neural Lace 'Blackglass' Net Intrusion 920-40
|
||||
# Implant: Poteque 'Prospector' Environmental Analysis EY-1005
|
||||
# Implant: Poteque 'Prospector' Hacking HC-905
|
||||
type = "passive"
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
# ammoInfluenceCapNeed
|
||||
#
|
||||
# Used by:
|
||||
# Items from category: Charge (464 of 898)
|
||||
# Charges from group: Frequency Crystal (184 of 184)
|
||||
# Charges from group: Hybrid Charge (208 of 208)
|
||||
# Items from category: Charge (478 of 928)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# ammoInfluenceRange
|
||||
#
|
||||
# Used by:
|
||||
# Items from category: Charge (568 of 898)
|
||||
# Items from category: Charge (572 of 928)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# ammoSpeedMultiplier
|
||||
#
|
||||
# Used by:
|
||||
# Charges from group: Festival Charges (10 of 10)
|
||||
# Charges from group: Festival Charges (23 of 23)
|
||||
# Charges from group: Interdiction Probe (2 of 2)
|
||||
# Charges from group: Structure Festival Charges (3 of 3)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -6,4 +6,4 @@ type = "passive"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
fit.ship.increaseItemAttr("warmScrambleStatus", module.getModifiedItemAttr("warpScrambleStrength"))
|
||||
fit.ship.increaseItemAttr("warpScrambleStatus", module.getModifiedItemAttr("warpScrambleStrength"))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# boosterArmorHpPenalty
|
||||
#
|
||||
# Used by:
|
||||
# Implants from group: Booster (12 of 48)
|
||||
# Implants from group: Booster (12 of 62)
|
||||
type = "boosterSideEffect"
|
||||
|
||||
# User-friendly name for the side effect
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# boosterMaxVelocityPenalty
|
||||
#
|
||||
# Used by:
|
||||
# Implants from group: Booster (12 of 48)
|
||||
# Implants from group: Booster (12 of 62)
|
||||
type = "boosterSideEffect"
|
||||
|
||||
# User-friendly name for the side effect
|
||||
|
||||
@@ -14,4 +14,4 @@ attr = "boosterMissileVelocityPenalty"
|
||||
|
||||
def handler(fit, booster, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"),
|
||||
"maxVelocity", attr)
|
||||
"maxVelocity", booster.getModifiedItemAttr(attr))
|
||||
|
||||
@@ -9,7 +9,7 @@ type = "passive"
|
||||
|
||||
def handler(fit, container, context):
|
||||
level = container.level if "skill" in context else 1
|
||||
attrs = ("boosterTurretFalloffPenalty", "boosterTurretOptimalRange", "boosterTurretTrackingPenalty")
|
||||
attrs = ("boosterTurretFalloffPenalty", "boosterTurretOptimalRangePenalty", "boosterTurretTrackingPenalty")
|
||||
for attr in attrs:
|
||||
fit.boosters.filteredItemBoost(lambda booster: True, attr,
|
||||
container.getModifiedItemAttr("boosterAttributeModifier") * level)
|
||||
|
||||
20
eos/effects/boostershieldboostamountpenaltyshieldskills.py
Normal file
20
eos/effects/boostershieldboostamountpenaltyshieldskills.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# boosterShieldBoostAmountPenaltyShieldSkills
|
||||
#
|
||||
# Used by:
|
||||
# Implants named like: Crash Booster (3 of 4)
|
||||
# Implants named like: Frentix Booster (3 of 4)
|
||||
# Implants named like: Mindflood Booster (3 of 4)
|
||||
type = "boosterSideEffect"
|
||||
|
||||
# User-friendly name for the side effect
|
||||
displayName = "Shield Boost"
|
||||
|
||||
# Attribute that this effect targets
|
||||
attr = "boosterShieldBoostAmountPenalty"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Operation"), "shieldBonus",
|
||||
src.getModifiedItemAttr("boosterShieldBoostAmountPenalty"))
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Shield Operation"), "shieldBonus",
|
||||
src.getModifiedItemAttr("boosterShieldBoostAmountPenalty"))
|
||||
@@ -1,7 +1,7 @@
|
||||
# boosterShieldCapacityPenalty
|
||||
#
|
||||
# Used by:
|
||||
# Implants from group: Booster (12 of 48)
|
||||
# Implants from group: Booster (12 of 62)
|
||||
type = "boosterSideEffect"
|
||||
|
||||
# User-friendly name for the side effect
|
||||
|
||||
@@ -10,7 +10,7 @@ type = "boosterSideEffect"
|
||||
displayName = "Turret Optimal Range"
|
||||
|
||||
# Attribute that this effect targets
|
||||
attr = "boosterTurretOptimalRange"
|
||||
attr = "boosterTurretOptimalRangePenalty"
|
||||
|
||||
|
||||
def handler(fit, booster, context):
|
||||
|
||||
@@ -10,4 +10,6 @@ type = "passive"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
fit.ship.multiplyItemAttr("capacitorCapacity", module.getModifiedItemAttr("capacitorCapacityMultiplier"))
|
||||
# We default this to None as there are times when the source attribute doesn't exist (for example, Cap Power Relay).
|
||||
# It will return 0 as it doesn't exist, which would nullify whatever the target attribute is
|
||||
fit.ship.multiplyItemAttr("capacitorCapacity", module.getModifiedItemAttr("capacitorCapacityMultiplier", None))
|
||||
|
||||
@@ -6,6 +6,6 @@ type = "active"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
for x in xrange(1, 4):
|
||||
for x in range(1, 4):
|
||||
value = module.getModifiedChargeAttr("warfareBuff{}Multiplier".format(x))
|
||||
module.multiplyItemAttr("warfareBuff{}Value".format(x), value)
|
||||
|
||||
21
eos/effects/citadelrigbonus.py
Normal file
21
eos/effects/citadelrigbonus.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# Not used by any item
|
||||
type = "passive"
|
||||
runTime = "early"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
|
||||
for attr in [
|
||||
"structureRigDoomsdayDamageLossTargetBonus",
|
||||
"structureRigScanResBonus",
|
||||
"structureRigPDRangeBonus",
|
||||
"structureRigPDCapUseBonus",
|
||||
"structureRigMissileExploVeloBonus",
|
||||
"structureRigMissileVelocityBonus",
|
||||
"structureRigEwarOptimalBonus",
|
||||
"structureRigEwarFalloffBonus",
|
||||
"structureRigEwarCapUseBonus",
|
||||
"structureRigMissileExplosionRadiusBonus"
|
||||
]:
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Jury Rigging"),
|
||||
attr, src.getModifiedItemAttr("structureRoleBonus"))
|
||||
@@ -4,9 +4,9 @@
|
||||
# Ships from group: Carrier (4 of 4)
|
||||
# Ships from group: Combat Battlecruiser (13 of 13)
|
||||
# Ships from group: Command Ship (8 of 8)
|
||||
# Ships from group: Force Auxiliary (5 of 5)
|
||||
# Ships from group: Force Auxiliary (6 of 6)
|
||||
# Ships from group: Supercarrier (6 of 6)
|
||||
# Ships from group: Titan (6 of 6)
|
||||
# Ships from group: Titan (7 of 7)
|
||||
# Subsystems named like: Offensive Support Processor (4 of 4)
|
||||
# Ship: Orca
|
||||
# Ship: Rorqual
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Enforcer
|
||||
# Ship: Marshal
|
||||
# Ship: Pacifier
|
||||
type = "passive"
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# covertOpsAndReconOpsCloakModuleDelayBonus
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Black Ops (4 of 4)
|
||||
# Ships from group: Black Ops (5 of 5)
|
||||
# Ships from group: Blockade Runner (4 of 4)
|
||||
# Ships from group: Covert Ops (7 of 7)
|
||||
# Ships from group: Expedition Frigate (2 of 2)
|
||||
# Ships from group: Force Recon Ship (7 of 8)
|
||||
# Ships from group: Stealth Bomber (4 of 5)
|
||||
# Ships from group: Force Recon Ship (8 of 8)
|
||||
# Ships from group: Stealth Bomber (5 of 5)
|
||||
# Ships named like: Stratios (2 of 2)
|
||||
# Subsystems named like: Defensive Covert Reconfiguration (4 of 4)
|
||||
# Ship: Astero
|
||||
|
||||
@@ -8,4 +8,4 @@ runTime = "early"
|
||||
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Cloaking"),
|
||||
"cpu", ship.getModifiedItemAttr("eliteBonusCoverOps1"), skill="Covert Ops")
|
||||
"cpu", ship.getModifiedItemAttr("eliteBonusCovertOps1"), skill="Covert Ops")
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
# Ship: Astero
|
||||
# Ship: Enforcer
|
||||
# Ship: Pacifier
|
||||
# Ship: Victor
|
||||
# Ship: Victorieux Luxury Yacht
|
||||
# Ship: Virtuoso
|
||||
type = "passive"
|
||||
runTime = "early"
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
# covertOpsStealthBomberSiegeMissileLauncherCPUNeedBonus
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Virtuoso
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.group.name == "Missile Launcher Torpedo",
|
||||
"cpu", ship.getModifiedItemAttr("stealthBomberLauncherCPU"))
|
||||
@@ -1,7 +1,7 @@
|
||||
# covertOpsStealthBomberSiegeMissileLauncerPowerNeedBonus
|
||||
# covertOpsStealthBomberSiegeMissileLauncherPowerNeedBonus
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Stealth Bomber (4 of 5)
|
||||
# Ships from group: Stealth Bomber (5 of 5)
|
||||
type = "passive"
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# covertOpsStealthBomberTargettingDelayBonus
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Black Ops (4 of 4)
|
||||
# Ships from group: Stealth Bomber (4 of 5)
|
||||
# Ships from group: Black Ops (5 of 5)
|
||||
# Ships from group: Stealth Bomber (5 of 5)
|
||||
# Ship: Caedes
|
||||
# Ship: Chremoas
|
||||
# Ship: Endurance
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# cynosuralDurationBonus
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Force Recon Ship (6 of 8)
|
||||
# Ships from group: Force Recon Ship (7 of 8)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# cynosuralTheoryConsumptionBonus
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Force Recon Ship (6 of 8)
|
||||
# Ships from group: Force Recon Ship (7 of 8)
|
||||
# Skill: Cynosural Field Theory
|
||||
type = "passive"
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
# damageControl
|
||||
#
|
||||
# Used by:
|
||||
# Variations of module: Damage Control I (16 of 16)
|
||||
# Module: Civilian Damage Control
|
||||
# Modules from group: Damage Control (22 of 27)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# doHacking
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Data Miners (15 of 16)
|
||||
# Modules from group: Data Miners (9 of 9)
|
||||
type = "active"
|
||||
|
||||
|
||||
|
||||
9
eos/effects/doomsdayaoebubble.py
Normal file
9
eos/effects/doomsdayaoebubble.py
Normal file
@@ -0,0 +1,9 @@
|
||||
# doomsdayAOEBubble
|
||||
#
|
||||
# Used by:
|
||||
# Module: Warp Disruption Burst Projector
|
||||
type = "projected", "active"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
return
|
||||
16
eos/effects/doomsdayaoedamp.py
Normal file
16
eos/effects/doomsdayaoedamp.py
Normal file
@@ -0,0 +1,16 @@
|
||||
# doomsdayAOEDamp
|
||||
#
|
||||
# Used by:
|
||||
# Module: Sensor Dampening Burst Projector
|
||||
type = "projected", "active"
|
||||
|
||||
|
||||
def handler(fit, module, context, *args, **kwargs):
|
||||
if "projected" not in context:
|
||||
return
|
||||
|
||||
fit.ship.boostItemAttr("maxTargetRange", module.getModifiedItemAttr("maxTargetRangeBonus"),
|
||||
stackingPenalties=True, *args, **kwargs)
|
||||
|
||||
fit.ship.boostItemAttr("scanResolution", module.getModifiedItemAttr("scanResolutionBonus"),
|
||||
stackingPenalties=True, *args, **kwargs)
|
||||
21
eos/effects/doomsdayaoeneut.py
Normal file
21
eos/effects/doomsdayaoeneut.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# doomsdayAOENeut
|
||||
#
|
||||
# Used by:
|
||||
# Module: Energy Neutralization Burst Projector
|
||||
from eos.saveddata.module import State
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict
|
||||
|
||||
type = "active", "projected"
|
||||
|
||||
|
||||
def handler(fit, src, context, **kwargs):
|
||||
if "projected" in context and ((hasattr(src, "state") and src.state >= State.ACTIVE) or
|
||||
hasattr(src, "amountActive")):
|
||||
amount = src.getModifiedItemAttr("energyNeutralizerAmount")
|
||||
|
||||
if 'effect' in kwargs:
|
||||
amount *= ModifiedAttributeDict.getResistance(fit, kwargs['effect'])
|
||||
|
||||
time = src.getModifiedItemAttr("duration")
|
||||
|
||||
fit.addDrain(src, time, amount, 0)
|
||||
11
eos/effects/doomsdayaoepaint.py
Normal file
11
eos/effects/doomsdayaoepaint.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# doomsdayAOEPaint
|
||||
#
|
||||
# Used by:
|
||||
# Module: Target Illumination Burst Projector
|
||||
type = "projected", "active"
|
||||
|
||||
|
||||
def handler(fit, container, context, *args, **kwargs):
|
||||
if "projected" in context:
|
||||
fit.ship.boostItemAttr("signatureRadius", container.getModifiedItemAttr("signatureRadiusBonus"),
|
||||
stackingPenalties=True, *args, **kwargs)
|
||||
29
eos/effects/doomsdayaoetrack.py
Normal file
29
eos/effects/doomsdayaoetrack.py
Normal file
@@ -0,0 +1,29 @@
|
||||
# doomsdayAOETrack
|
||||
#
|
||||
# Used by:
|
||||
# Module: Weapon Disruption Burst Projector
|
||||
|
||||
type = "active", "projected"
|
||||
|
||||
|
||||
def handler(fit, module, context, *args, **kwargs):
|
||||
if "projected" in context:
|
||||
for srcAttr, tgtAttr in (
|
||||
("aoeCloudSizeBonus", "aoeCloudSize"),
|
||||
("aoeVelocityBonus", "aoeVelocity"),
|
||||
("missileVelocityBonus", "maxVelocity"),
|
||||
("explosionDelayBonus", "explosionDelay"),
|
||||
):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"),
|
||||
tgtAttr, module.getModifiedItemAttr(srcAttr),
|
||||
stackingPenalties=True, *args, **kwargs)
|
||||
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Gunnery"),
|
||||
"trackingSpeed", module.getModifiedItemAttr("trackingSpeedBonus"),
|
||||
stackingPenalties=True, *args, **kwargs)
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Gunnery"),
|
||||
"maxRange", module.getModifiedItemAttr("maxRangeBonus"),
|
||||
stackingPenalties=True, *args, **kwargs)
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Gunnery"),
|
||||
"falloff", module.getModifiedItemAttr("falloffBonus"),
|
||||
stackingPenalties=True, *args, **kwargs)
|
||||
12
eos/effects/doomsdayaoeweb.py
Normal file
12
eos/effects/doomsdayaoeweb.py
Normal file
@@ -0,0 +1,12 @@
|
||||
# doomsdayAOEWeb
|
||||
#
|
||||
# Used by:
|
||||
# Module: Stasis Webification Burst Projector
|
||||
type = "active", "projected"
|
||||
|
||||
|
||||
def handler(fit, module, context, *args, **kwargs):
|
||||
if "projected" not in context:
|
||||
return
|
||||
fit.ship.boostItemAttr("maxVelocity", module.getModifiedItemAttr("speedFactor"),
|
||||
stackingPenalties=True, *args, **kwargs)
|
||||
9
eos/effects/doomsdaybeamdot.py
Normal file
9
eos/effects/doomsdaybeamdot.py
Normal file
@@ -0,0 +1,9 @@
|
||||
# doomsdayBeamDOT
|
||||
#
|
||||
# Used by:
|
||||
# Modules named like: Lance (4 of 4)
|
||||
type = "active"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
pass
|
||||
9
eos/effects/doomsdayconedot.py
Normal file
9
eos/effects/doomsdayconedot.py
Normal file
@@ -0,0 +1,9 @@
|
||||
# doomsdayConeDOT
|
||||
#
|
||||
# Used by:
|
||||
# Module: Bosonic Field Generator
|
||||
type = "active"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
pass
|
||||
9
eos/effects/doomsdayhog.py
Normal file
9
eos/effects/doomsdayhog.py
Normal file
@@ -0,0 +1,9 @@
|
||||
# doomsdayHOG
|
||||
#
|
||||
# Used by:
|
||||
# Module: Gravitational Transportation Field Oscillator
|
||||
type = "active"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
pass
|
||||
9
eos/effects/doomsdayslash.py
Normal file
9
eos/effects/doomsdayslash.py
Normal file
@@ -0,0 +1,9 @@
|
||||
# doomsdaySlash
|
||||
#
|
||||
# Used by:
|
||||
# Modules named like: Reaper (4 of 4)
|
||||
type = "active"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
pass
|
||||
@@ -1,7 +1,7 @@
|
||||
# eliteBonusBlackOpsCloakVelocity2
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Black Ops (4 of 4)
|
||||
# Ships from group: Black Ops (5 of 5)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
10
eos/effects/elitebonusblackopsscramblerrange4.py
Normal file
10
eos/effects/elitebonusblackopsscramblerrange4.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# eliteBonusBlackOpsScramblerRange4
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Marshal
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Warp Scrambler", "maxRange",
|
||||
src.getModifiedItemAttr("eliteBonusBlackOps4"), stackingPenalties=True, skill="Black Ops")
|
||||
9
eos/effects/elitebonusblackopswarpvelocity1.py
Normal file
9
eos/effects/elitebonusblackopswarpvelocity1.py
Normal file
@@ -0,0 +1,9 @@
|
||||
# eliteBonusBlackOpsWarpVelocity1
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Marshal
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.ship.boostItemAttr("warpSpeedMultiplier", src.getModifiedItemAttr("eliteBonusBlackOps1"), stackingPenalties=True, skill="Black Ops")
|
||||
10
eos/effects/elitebonusblackopswebrange3.py
Normal file
10
eos/effects/elitebonusblackopswebrange3.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# eliteBonusBlackOpsWebRange3
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Marshal
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Stasis Web", "maxRange",
|
||||
src.getModifiedItemAttr("eliteBonusBlackOps3"), stackingPenalties=True, skill="Black Ops")
|
||||
@@ -7,4 +7,4 @@ type = "passive"
|
||||
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Bomb Deployment"),
|
||||
"emDamage", ship.getModifiedItemAttr("eliteBonusCoverOps1"), skill="Covert Ops")
|
||||
"emDamage", ship.getModifiedItemAttr("eliteBonusCovertOps1"), skill="Covert Ops")
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Hound
|
||||
# Ship: Virtuoso
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Bomb Deployment"),
|
||||
"explosiveDamage", ship.getModifiedItemAttr("eliteBonusCoverOps1"),
|
||||
"explosiveDamage", ship.getModifiedItemAttr("eliteBonusCovertOps1"),
|
||||
skill="Covert Ops")
|
||||
|
||||
@@ -7,5 +7,5 @@ type = "passive"
|
||||
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Bomb Deployment"),
|
||||
"kineticDamage", ship.getModifiedItemAttr("eliteBonusCoverOps1"),
|
||||
"kineticDamage", ship.getModifiedItemAttr("eliteBonusCovertOps1"),
|
||||
skill="Covert Ops")
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Nemesis
|
||||
# Ship: Virtuoso
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Bomb Deployment"),
|
||||
"thermalDamage", ship.getModifiedItemAttr("eliteBonusCoverOps1"),
|
||||
"thermalDamage", ship.getModifiedItemAttr("eliteBonusCovertOps1"),
|
||||
skill="Covert Ops")
|
||||
|
||||
@@ -7,5 +7,5 @@ type = "passive"
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name in ("Energy Nosferatu", "Energy Neutralizer"),
|
||||
"falloffEffectiveness", src.getModifiedItemAttr("eliteBonusCoverOps1"),
|
||||
"falloffEffectiveness", src.getModifiedItemAttr("eliteBonusCovertOps1"),
|
||||
stackingPenalties=True, skill="Covert Ops")
|
||||
|
||||
@@ -7,5 +7,5 @@ type = "passive"
|
||||
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.group.name == "Scanner Probe",
|
||||
"baseSensorStrength", ship.getModifiedItemAttr("eliteBonusCoverOps2"),
|
||||
"baseSensorStrength", ship.getModifiedItemAttr("eliteBonusCovertOps2"),
|
||||
skill="Covert Ops")
|
||||
|
||||
@@ -6,4 +6,4 @@ type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.ship.boostItemAttr("warpSpeedMultiplier", src.getModifiedItemAttr("eliteBonusCoverOps1"), skill="Covert Ops")
|
||||
fit.ship.boostItemAttr("warpSpeedMultiplier", src.getModifiedItemAttr("eliteBonusCovertOps1"), skill="Covert Ops")
|
||||
|
||||
10
eos/effects/elitebonuscovertopsshtdamage3.py
Normal file
10
eos/effects/elitebonuscovertopsshtdamage3.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# eliteBonusCovertOpsSHTDamage3
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Virtuoso
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Small Hybrid Turret"), "damageMultiplier",
|
||||
src.getModifiedItemAttr("eliteBonusCovertOps3"), skill="Covert Ops")
|
||||
20
eos/effects/elitebonusflagcruiserallresistances1.py
Normal file
20
eos/effects/elitebonusflagcruiserallresistances1.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# eliteBonusFlagCruiserAllResistances1
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Monitor
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.ship.boostItemAttr("explosiveDamageResonance", src.getModifiedItemAttr("eliteBonusFlagCruisers1"), skill="Flag Cruisers")
|
||||
fit.ship.boostItemAttr("shieldKineticDamageResonance", src.getModifiedItemAttr("eliteBonusFlagCruisers1"), skill="Flag Cruisers")
|
||||
fit.ship.boostItemAttr("shieldExplosiveDamageResonance", src.getModifiedItemAttr("eliteBonusFlagCruisers1"), skill="Flag Cruisers")
|
||||
fit.ship.boostItemAttr("armorThermalDamageResonance", src.getModifiedItemAttr("eliteBonusFlagCruisers1"), skill="Flag Cruisers")
|
||||
fit.ship.boostItemAttr("thermalDamageResonance", src.getModifiedItemAttr("eliteBonusFlagCruisers1"), skill="Flag Cruisers")
|
||||
fit.ship.boostItemAttr("shieldEmDamageResonance", src.getModifiedItemAttr("eliteBonusFlagCruisers1"), skill="Flag Cruisers")
|
||||
fit.ship.boostItemAttr("armorExplosiveDamageResonance", src.getModifiedItemAttr("eliteBonusFlagCruisers1"), skill="Flag Cruisers")
|
||||
fit.ship.boostItemAttr("armorEmDamageResonance", src.getModifiedItemAttr("eliteBonusFlagCruisers1"), skill="Flag Cruisers")
|
||||
fit.ship.boostItemAttr("shieldThermalDamageResonance", src.getModifiedItemAttr("eliteBonusFlagCruisers1"), skill="Flag Cruisers")
|
||||
fit.ship.boostItemAttr("kineticDamageResonance", src.getModifiedItemAttr("eliteBonusFlagCruisers1"), skill="Flag Cruisers")
|
||||
fit.ship.boostItemAttr("armorKineticDamageResonance", src.getModifiedItemAttr("eliteBonusFlagCruisers1"), skill="Flag Cruisers")
|
||||
fit.ship.boostItemAttr("emDamageResonance", src.getModifiedItemAttr("eliteBonusFlagCruisers1"), skill="Flag Cruisers")
|
||||
@@ -1,7 +1,4 @@
|
||||
# eliteBonusGunshipDroneCapacity2
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Ishkur
|
||||
# Not used by any item
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
7
eos/effects/elitebonusgunshipdronetracking2.py
Normal file
7
eos/effects/elitebonusgunshipdronetracking2.py
Normal file
@@ -0,0 +1,7 @@
|
||||
# Not used by any item
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "trackingSpeed",
|
||||
src.getModifiedItemAttr("eliteBonusGunship2"), stackingPenalties=True, skill="Assault Frigates")
|
||||
10
eos/effects/elitebonusgunshipemmissiledamage1.py
Normal file
10
eos/effects/elitebonusgunshipemmissiledamage1.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# eliteBonusGunshipEMMissileDamage1
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Jaguar
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"), "emDamage",
|
||||
src.getModifiedItemAttr("eliteBonusGunship1"), skill="Assault Frigates")
|
||||
10
eos/effects/elitebonusgunshipexplosionvelocity2.py
Normal file
10
eos/effects/elitebonusgunshipexplosionvelocity2.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# eliteBonusGunshipExplosionVelocity2
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Jaguar
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"), "aoeVelocity",
|
||||
src.getModifiedItemAttr("eliteBonusGunship2"), stackingPenalties=True, skill="Assault Frigates")
|
||||
10
eos/effects/elitebonusgunshipexplosivemissiledamage1.py
Normal file
10
eos/effects/elitebonusgunshipexplosivemissiledamage1.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# eliteBonusGunshipExplosiveMissileDamage1
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Jaguar
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"), "explosiveDamage",
|
||||
src.getModifiedItemAttr("eliteBonusGunship1"), skill="Assault Frigates")
|
||||
10
eos/effects/elitebonusgunshipkineticmissiledamage1.py
Normal file
10
eos/effects/elitebonusgunshipkineticmissiledamage1.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# eliteBonusGunshipKineticMissileDamage1
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Jaguar
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"), "kineticDamage",
|
||||
src.getModifiedItemAttr("eliteBonusGunship1"), skill="Assault Frigates")
|
||||
@@ -1,7 +1,4 @@
|
||||
# eliteBonusGunshipProjectileDamage2
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Jaguar
|
||||
# Not used by any item
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
# eliteBonusGunshipProjectileOptimal1
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Jaguar
|
||||
# Not used by any item
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
10
eos/effects/elitebonusgunshipthermalmissiledamage1.py
Normal file
10
eos/effects/elitebonusgunshipthermalmissiledamage1.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# eliteBonusGunshipThermalMissileDamage1
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Jaguar
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"), "thermalDamage",
|
||||
src.getModifiedItemAttr("eliteBonusGunship1"), skill="Assault Frigates")
|
||||
10
eos/effects/elitecovertopsbonusarmorrepamount4.py
Normal file
10
eos/effects/elitecovertopsbonusarmorrepamount4.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# eliteCovertOpsBonusArmorRepAmount4
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Virtuoso
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Repair Systems"), "armorDamageAmount",
|
||||
src.getModifiedItemAttr("eliteBonusCovertOps4"), skill="Covert Ops")
|
||||
10
eos/effects/elitereconbonusarmorrepamount3.py
Normal file
10
eos/effects/elitereconbonusarmorrepamount3.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# eliteReconBonusArmorRepAmount3
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Victor
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Repair Systems"), "armorDamageAmount",
|
||||
src.getModifiedItemAttr("eliteBonusReconShip3"), skill="Recon Ships")
|
||||
10
eos/effects/elitereconbonusmhtdamage1.py
Normal file
10
eos/effects/elitereconbonusmhtdamage1.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# eliteReconBonusMHTDamage1
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Victor
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Hybrid Turret"), "damageMultiplier",
|
||||
src.getModifiedItemAttr("eliteBonusReconShip1"), skill="Recon Ships")
|
||||
@@ -4,6 +4,7 @@
|
||||
# Ship: Huginn
|
||||
# Ship: Moracha
|
||||
# Ship: Rapier
|
||||
# Ship: Victor
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user