Compare commits
384 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9bb83d4574 | ||
|
|
8023b2ea29 | ||
|
|
3e1244a27a | ||
|
|
51e610830f | ||
|
|
a2877f6b5f | ||
|
|
acf6b3dffd | ||
|
|
b6a1c4b308 | ||
|
|
e29ab817af | ||
|
|
86576581cd | ||
|
|
50bd46015b | ||
|
|
aa2ffaf1ea | ||
|
|
5cc6b6c69c | ||
|
|
0365f71c00 | ||
|
|
4d666907c9 | ||
|
|
0466678176 | ||
|
|
c1e239b9b3 | ||
|
|
26aaeabd7f | ||
|
|
0e0bc9dfd2 | ||
|
|
8990cbfd6a | ||
|
|
8f34c03289 | ||
|
|
c1322a3566 | ||
|
|
5101e2851a | ||
|
|
7b7f67ad2e | ||
|
|
dbdc566ae4 | ||
|
|
f4fd991907 | ||
|
|
42ad74158b | ||
|
|
c99afa79e1 | ||
|
|
789c3b869a | ||
|
|
7d8d87662b | ||
|
|
645a5ced14 | ||
|
|
5ed98e8fed | ||
|
|
f12370389c | ||
|
|
fc35d7bb26 | ||
|
|
95c1f7bde0 | ||
|
|
d52c249921 | ||
|
|
0b9a50cd8d | ||
|
|
25bbfec318 | ||
|
|
1192c26b8f | ||
|
|
4a3201ffd4 | ||
|
|
406a22100d | ||
|
|
2547cf70c2 | ||
|
|
e83fa4d40b | ||
|
|
c552cb5e40 | ||
|
|
363904411d | ||
|
|
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 | ||
|
|
c6e715aa5c | ||
|
|
0e93136157 | ||
|
|
23f0f48c80 | ||
|
|
fe1c4cc4d4 | ||
|
|
ed649dd4c7 | ||
|
|
33618f12f7 | ||
|
|
33eccaa374 | ||
|
|
5f0ce58c29 | ||
|
|
c329f5eeb8 | ||
|
|
320a0230f4 | ||
|
|
50dd74dbe8 | ||
|
|
9c355d8f96 | ||
|
|
7b0f672f04 | ||
|
|
33bf5234d0 | ||
|
|
cb392e7e5f | ||
|
|
dfba033190 | ||
|
|
5fbe623ae6 | ||
|
|
e025bff99b | ||
|
|
e77dddc15b | ||
|
|
eea8019593 | ||
|
|
c7360c8cc3 | ||
|
|
2376148380 | ||
|
|
2e8d7d3610 | ||
|
|
3179016aed | ||
|
|
9e8166c13d | ||
|
|
9f7e4e0dc0 | ||
|
|
29d175c7b3 | ||
|
|
40ce7b7c0b | ||
|
|
2936b88c3d | ||
|
|
2365112292 | ||
|
|
1daef5354d | ||
|
|
6f19d45c6d | ||
|
|
ac7908c62c | ||
|
|
c000b19986 | ||
|
|
1da127c898 | ||
|
|
fcdf55632f | ||
|
|
dd3bc66896 | ||
|
|
da67cdba9b | ||
|
|
8850da6cdb | ||
|
|
7d46d7e22d | ||
|
|
b3157303cd | ||
|
|
65e17119af | ||
|
|
3c405f51d8 | ||
|
|
337f0a9c8a | ||
|
|
53936a3e66 | ||
|
|
30a6e29b39 | ||
|
|
f3dc3bc654 | ||
|
|
0a935cf149 | ||
|
|
5697da7ec2 | ||
|
|
a7086b78cb | ||
|
|
e032c9c5b1 | ||
|
|
46b0aded03 | ||
|
|
d23398ce29 | ||
|
|
5e0a5da6d5 | ||
|
|
6e112b9ed5 | ||
|
|
b30b3fcbf1 | ||
|
|
4a33365195 | ||
|
|
5d5646df79 | ||
|
|
405a965046 | ||
|
|
4138088d4a | ||
|
|
de44e6f932 | ||
|
|
d4df989427 | ||
|
|
6c8b143936 | ||
|
|
0f94557699 | ||
|
|
a52b9e58e9 | ||
|
|
0d8904d59f | ||
|
|
d956cb7861 | ||
|
|
e848cec815 | ||
|
|
ce8f1d385d | ||
|
|
90e338b969 | ||
|
|
1978f5cb92 | ||
|
|
979bc494f0 | ||
|
|
cc9b6ea04b | ||
|
|
8cbb327659 | ||
|
|
1fc9b2941d | ||
|
|
e9be07f281 | ||
|
|
df7dc30e7e | ||
|
|
d0235f6d93 | ||
|
|
de646cf252 | ||
|
|
21838f2d9a | ||
|
|
266398b1de | ||
|
|
0cc646bab9 | ||
|
|
cebca64e5e | ||
|
|
bd0de82a8e | ||
|
|
0f5ae8d9b6 | ||
|
|
5ae7805bb1 | ||
|
|
6a382c4445 | ||
|
|
3b0c8b6117 | ||
|
|
0e1e4cad6d | ||
|
|
e0b92198b0 | ||
|
|
ce3b94696a | ||
|
|
56f34873a6 | ||
|
|
2afc8b1abe | ||
|
|
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 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -118,3 +118,7 @@ ENV/
|
||||
.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>
|
||||
15
README.md
15
README.md
@@ -15,12 +15,8 @@ The latest version along with release notes can always be found on the project's
|
||||
Windows and OS X users are supplied self-contained builds of pyfa on the [latest releases](https://github.com/pyfa-org/Pyfa/releases/latest) page. An `.exe` installer is also available for Windows builds. Linux users can run pyfa using their distribution's Python interpreter. There is no official self-contained package for Linux, however, there are a number of third-party packages available through distribution-specific repositories.
|
||||
|
||||
#### OS X
|
||||
There are two different distributives for OS X: `-mac` and `-mac-deprecated`.
|
||||
|
||||
* `-mac`: based on wxPython 3.0.2.0 and has updated libraries. This is the recommended build.
|
||||
* `-mac-deprecated`: utilizes older binaries running on wxPython 2.8; because of this, some features are not available (currently CREST support and Attribute Overrides). Additionally, as development happens primarily on wxPython 3.0, a few GUI bugs may pop up as `-mac-deprecated` is not actively tested. However, due to some general issues with wxPython 3.0, especially on some newer OS X versions, `-mac-deprecated` is still offered for those that need it.
|
||||
|
||||
There is also a [Homebrew](http://brew.sh) option for installing pyfa on OS X. Please note this is maintained by a third-party and is not tested by pyfa developers. Simply fire up in terminal:
|
||||
Apart from the official release, there is also a [Homebrew](http://brew.sh) option for installing pyfa on OS X. Please note this is maintained by a third-party and is not tested by pyfa developers. Simply fire up in terminal:
|
||||
```
|
||||
$ brew install Caskroom/cask/pyfa
|
||||
```
|
||||
@@ -36,13 +32,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).
|
||||
|
||||
@@ -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
|
||||
|
||||
172
config.py
172
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,38 @@ debug = False
|
||||
saveInRoot = False
|
||||
|
||||
# Version data
|
||||
version = "1.35.0"
|
||||
|
||||
version = "2.0.1"
|
||||
tag = "Stable"
|
||||
expansionName = "YC120.2"
|
||||
expansionVersion = "1.1"
|
||||
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_CACHE = 'esi_cache'
|
||||
|
||||
LOGLEVEL_MAP = {
|
||||
"critical": CRITICAL,
|
||||
"error": ERROR,
|
||||
"warning": WARNING,
|
||||
"info": INFO,
|
||||
"debug": DEBUG,
|
||||
}
|
||||
|
||||
|
||||
def getClientSecret():
|
||||
return clientHash
|
||||
|
||||
|
||||
def isFrozen():
|
||||
@@ -45,23 +70,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,9 +125,19 @@ 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")
|
||||
@@ -100,6 +149,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 +165,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')
|
||||
76
dist_assets/mac/pyfa.spec
Normal file
76
dist_assets/mac/pyfa.spec
Normal file
@@ -0,0 +1,76 @@
|
||||
# -*- 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 = []
|
||||
|
||||
icon = os.path.join(os.getcwd(), "dist_assets", "mac", "pyfa.icns")
|
||||
|
||||
# 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=icon,
|
||||
)
|
||||
|
||||
app = BUNDLE(exe,
|
||||
name='pyfa.app',
|
||||
icon=icon,
|
||||
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
|
||||
46
dist_assets/win/dist.py
Normal file
46
dist_assets/win/dist.py
Normal file
@@ -0,0 +1,46 @@
|
||||
# helper script to zip up pyinstaller distribution and create installer file
|
||||
|
||||
import os.path
|
||||
from subprocess import call
|
||||
import zipfile
|
||||
|
||||
|
||||
def zipdir(path, zip):
|
||||
for root, dirs, files in os.walk(path):
|
||||
for file in files:
|
||||
zip.write(os.path.join(root, file))
|
||||
|
||||
config = {}
|
||||
|
||||
exec(compile(open("config.py").read(), "config.py", 'exec'), config)
|
||||
|
||||
iscc = "C:\Program Files (x86)\Inno Setup 5\ISCC.exe" # inno script location via wine
|
||||
|
||||
print("Creating archive")
|
||||
|
||||
source = os.path.join(os.getcwd(), "dist", "pyfa")
|
||||
|
||||
fileName = "pyfa-{}-{}-{}-win".format(
|
||||
config['version'],
|
||||
config['expansionName'].lower(),
|
||||
config['expansionVersion']
|
||||
)
|
||||
|
||||
archive = zipfile.ZipFile(os.path.join(os.getcwd(), "dist", fileName + ".zip"), 'w', compression=zipfile.ZIP_DEFLATED)
|
||||
zipdir(source, archive)
|
||||
archive.close()
|
||||
|
||||
print("Compiling EXE")
|
||||
|
||||
expansion = "%s %s" % (config['expansionName'], config['expansionVersion']),
|
||||
|
||||
call([
|
||||
iscc,
|
||||
os.path.join(os.getcwd(), "dist_assets", "win", "pyfa-setup.iss"),
|
||||
"/dMyAppVersion=%s" % (config['version']),
|
||||
"/dMyAppExpansion=%s" % (expansion),
|
||||
"/dMyAppDir=%s" % source,
|
||||
"/dMyOutputDir=%s" % os.path.join(os.getcwd(), "dist"),
|
||||
"/dMyOutputFile=%s" % fileName]) # stdout=devnull, stderr=devnull
|
||||
|
||||
print("Done")
|
||||
@@ -19,7 +19,8 @@
|
||||
#define MyAppExeName "pyfa.exe"
|
||||
|
||||
; What version starts with the new structure (1.x.0). This is used to determine if we run directory structure cleanup
|
||||
#define VersionFlag 16
|
||||
#define MajorVersionFlag 2
|
||||
#define MinorVersionFlag 0
|
||||
|
||||
#ifndef MyOutputFile
|
||||
#define MyOutputFile LowerCase(StringChange(MyAppName+'-'+MyAppVersion+'-'+MyAppExpansion+'-win-wx3', " ", "-"))
|
||||
@@ -138,15 +139,19 @@ var
|
||||
V: Integer;
|
||||
iResultCode: Integer;
|
||||
sUnInstallString: string;
|
||||
iOldVersion: Cardinal;
|
||||
iOldVersionMajor: Cardinal;
|
||||
iOldVersionMinor: Cardinal;
|
||||
begin
|
||||
Result := True; // in case when no previous version is found
|
||||
if RegValueExists(HKEY_LOCAL_MACHINE,'Software\Microsoft\Windows\CurrentVersion\Uninstall\{3DA39096-C08D-49CD-90E0-1D177F32C8AA}_is1', 'UninstallString') then //Your App GUID/ID
|
||||
begin
|
||||
RegQueryDWordValue(HKEY_LOCAL_MACHINE,
|
||||
'Software\Microsoft\Windows\CurrentVersion\Uninstall\{3DA39096-C08D-49CD-90E0-1D177F32C8AA}_is1',
|
||||
'MinorVersion', iOldVersion);
|
||||
if iOldVersion < {#VersionFlag} then // If old version with old structure is installed.
|
||||
'MajorVersion', iOldVersionMajor);
|
||||
RegQueryDWordValue(HKEY_LOCAL_MACHINE,
|
||||
'Software\Microsoft\Windows\CurrentVersion\Uninstall\{3DA39096-C08D-49CD-90E0-1D177F32C8AA}_is1',
|
||||
'MinorVersion', iOldVersionMinor);
|
||||
if (iOldVersionMajor < {#MajorVersionFlag}) or ((iOldVersionMajor = {#MajorVersionFlag}) and (iOldVersionMinor < {#MinorVersionFlag})) then // If old version with old structure is installed.
|
||||
begin
|
||||
V := MsgBox(ExpandConstant('An old version of pyfa was detected. Due to recent changes in the application structure, you must uninstall the previous version first. This will not affect your user data (saved fittings, characters, etc.). Do you want to uninstall now?'), mbInformation, MB_YESNO); //Custom Message if App installed
|
||||
if V = IDYES then
|
||||
@@ -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,7 @@ 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" = ?',
|
||||
|
||||
@@ -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"],
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# ammoInfluenceCapNeed
|
||||
#
|
||||
# Used by:
|
||||
# Items from category: Charge (478 of 925)
|
||||
# Items from category: Charge (478 of 928)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# ammoInfluenceRange
|
||||
#
|
||||
# Used by:
|
||||
# Items from category: Charge (572 of 925)
|
||||
# Items from category: Charge (572 of 928)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# Used by:
|
||||
# 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"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# boosterArmorHpPenalty
|
||||
#
|
||||
# Used by:
|
||||
# Implants from group: Booster (12 of 54)
|
||||
# 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 54)
|
||||
# Implants from group: Booster (12 of 62)
|
||||
type = "boosterSideEffect"
|
||||
|
||||
# User-friendly name for the side effect
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# boosterShieldCapacityPenalty
|
||||
#
|
||||
# Used by:
|
||||
# Implants from group: Booster (12 of 54)
|
||||
# Implants from group: Booster (12 of 62)
|
||||
type = "boosterSideEffect"
|
||||
|
||||
# User-friendly name for the side effect
|
||||
|
||||
@@ -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"))
|
||||
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
|
||||
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")
|
||||
@@ -9,4 +9,4 @@ type = "passive"
|
||||
def handler(fit, container, context):
|
||||
level = container.level if "skill" in context else 1
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("High Speed Maneuvering"),
|
||||
"capacitorNeed", container.getModifiedItemAttr("capacitorNeedMultiplier") * level)
|
||||
"capacitorNeed", container.getModifiedItemAttr("capNeedBonus") * level)
|
||||
|
||||
9
eos/effects/microjumpportaldrive.py
Normal file
9
eos/effects/microjumpportaldrive.py
Normal file
@@ -0,0 +1,9 @@
|
||||
# microJumpPortalDrive
|
||||
#
|
||||
# Used by:
|
||||
# Module: Micro Jump Field Generator
|
||||
type = "active"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
pass
|
||||
@@ -1,7 +1,7 @@
|
||||
# missileDMGBonus
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Ballistic Control system (18 of 18)
|
||||
# Modules from group: Ballistic Control system (20 of 20)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# missileLauncherSpeedMultiplier
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Ballistic Control system (18 of 18)
|
||||
# Modules from group: Ballistic Control system (20 of 20)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ type = "passive"
|
||||
|
||||
def handler(fit, container, context):
|
||||
level = container.level if "skill" in context else 1
|
||||
for i in xrange(5):
|
||||
for i in range(5):
|
||||
attr = "boosterEffectChance{0}".format(i + 1)
|
||||
fit.boosters.filteredItemBoost(lambda booster: attr in booster.itemModifiedAttributes,
|
||||
attr, container.getModifiedItemAttr("boosterChanceBonus") * level)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Drone Damage Modules (11 of 11)
|
||||
# Modules named like: C3 'Hivaa Saitsuo' Ballistic Control System (2 of 2)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ type = "active", "gang"
|
||||
|
||||
|
||||
def handler(fit, module, context, **kwargs):
|
||||
for x in xrange(1, 5):
|
||||
for x in range(1, 5):
|
||||
if module.getModifiedChargeAttr("warfareBuff{}ID".format(x)):
|
||||
value = module.getModifiedItemAttr("warfareBuff{}Value".format(x))
|
||||
id = module.getModifiedChargeAttr("warfareBuff{}ID".format(x))
|
||||
|
||||
@@ -7,7 +7,7 @@ type = "active", "gang"
|
||||
|
||||
|
||||
def handler(fit, module, context, **kwargs):
|
||||
for x in xrange(1, 5):
|
||||
for x in range(1, 5):
|
||||
if module.getModifiedChargeAttr("warfareBuff{}ID".format(x)):
|
||||
value = module.getModifiedItemAttr("warfareBuff{}Value".format(x))
|
||||
id = module.getModifiedChargeAttr("warfareBuff{}ID".format(x))
|
||||
|
||||
@@ -7,7 +7,7 @@ type = "active", "gang"
|
||||
|
||||
|
||||
def handler(fit, module, context, **kwargs):
|
||||
for x in xrange(1, 5):
|
||||
for x in range(1, 5):
|
||||
if module.getModifiedChargeAttr("warfareBuff{}ID".format(x)):
|
||||
value = module.getModifiedItemAttr("warfareBuff{}Value".format(x))
|
||||
id = module.getModifiedChargeAttr("warfareBuff{}ID".format(x))
|
||||
|
||||
@@ -7,7 +7,7 @@ type = "active", "gang"
|
||||
|
||||
|
||||
def handler(fit, module, context, **kwargs):
|
||||
for x in xrange(1, 5):
|
||||
for x in range(1, 5):
|
||||
if module.getModifiedChargeAttr("warfareBuff{}ID".format(x)):
|
||||
value = module.getModifiedItemAttr("warfareBuff{}Value".format(x))
|
||||
id = module.getModifiedChargeAttr("warfareBuff{}ID".format(x))
|
||||
|
||||
@@ -7,7 +7,7 @@ type = "active", "gang"
|
||||
|
||||
|
||||
def handler(fit, module, context, **kwargs):
|
||||
for x in xrange(1, 5):
|
||||
for x in range(1, 5):
|
||||
if module.getModifiedChargeAttr("warfareBuff{}ID".format(x)):
|
||||
value = module.getModifiedItemAttr("warfareBuff{}Value".format(x))
|
||||
id = module.getModifiedChargeAttr("warfareBuff{}ID".format(x))
|
||||
|
||||
@@ -6,7 +6,7 @@ type = "active", "gang"
|
||||
|
||||
|
||||
def handler(fit, module, context, **kwargs):
|
||||
for x in xrange(1, 5):
|
||||
for x in range(1, 5):
|
||||
if module.getModifiedItemAttr("warfareBuff{}ID".format(x)):
|
||||
value = module.getModifiedItemAttr("warfareBuff{}Value".format(x))
|
||||
id = module.getModifiedItemAttr("warfareBuff{}ID".format(x))
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Missile Launcher Torpedo (22 of 22)
|
||||
# Items from market group: Ship Equipment > Turrets & Bays (429 of 861)
|
||||
# Items from market group: Ship Equipment > Turrets & Bays (429 of 863)
|
||||
# Module: Interdiction Sphere Launcher I
|
||||
type = "overheat"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# overloadSelfDamageBonus
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Energy Weapon (101 of 213)
|
||||
# Modules from group: Energy Weapon (101 of 214)
|
||||
# Modules from group: Hybrid Weapon (105 of 221)
|
||||
# Modules from group: Projectile Weapon (99 of 165)
|
||||
type = "overheat"
|
||||
|
||||
@@ -9,4 +9,6 @@ type = "passive"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
fit.ship.multiplyItemAttr("powerOutput", module.getModifiedItemAttr("powerOutputMultiplier"))
|
||||
# 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("powerOutput", module.getModifiedItemAttr("powerOutputMultiplier", None))
|
||||
|
||||
17
eos/effects/rolebonusflagcruisermodulefittingreduction.py
Normal file
17
eos/effects/rolebonusflagcruisermodulefittingreduction.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# roleBonusFlagCruiserModuleFittingReduction
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Monitor
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name in ("Propulsion Module", "Micro Jump Drive"),
|
||||
"power", src.getModifiedItemAttr("flagCruiserFittingBonusPropMods"))
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name in ("Propulsion Module", "Micro Jump Drive"),
|
||||
"cpu", src.getModifiedItemAttr("flagCruiserFittingBonusPropMods"))
|
||||
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name in ("Target Painter", "Scan Probe Launcher"),
|
||||
"cpu", src.getModifiedItemAttr("flagCruiserFittingBonusPainterProbes"))
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name in ("Target Painter", "Scan Probe Launcher"),
|
||||
"power", src.getModifiedItemAttr("flagCruiserFittingBonusPainterProbes"))
|
||||
@@ -0,0 +1,12 @@
|
||||
# roleBonusFlagCruiserTargetPainterModifications
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Monitor
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Target Painter", "signatureRadiusBonus",
|
||||
src.getModifiedItemAttr("targetPainterStrengthModifierFlagCruisers"))
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Target Painter", "maxRange",
|
||||
src.getModifiedItemAttr("targetPainterRangeModifierFlagCruisers"))
|
||||
10
eos/effects/scriptscangravimetricstrengthbonusbonus.py
Normal file
10
eos/effects/scriptscangravimetricstrengthbonusbonus.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# scriptscanGravimetricStrengthBonusBonus
|
||||
#
|
||||
# Used by:
|
||||
# Charges from group: Structure ECM script (4 of 4)
|
||||
type = "passive"
|
||||
runTime = "early"
|
||||
|
||||
|
||||
def handler(fit, src, context, *args, **kwargs):
|
||||
src.boostItemAttr("scanGravimetricStrengthBonus", src.getModifiedChargeAttr("scanGravimetricStrengthBonusBonus"))
|
||||
10
eos/effects/scriptscanladarstrengthbonusbonus.py
Normal file
10
eos/effects/scriptscanladarstrengthbonusbonus.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# scriptscanLadarStrengthBonusBonus
|
||||
#
|
||||
# Used by:
|
||||
# Charges from group: Structure ECM script (4 of 4)
|
||||
type = "passive"
|
||||
runTime = "early"
|
||||
|
||||
|
||||
def handler(fit, src, context, *args, **kwargs):
|
||||
src.boostItemAttr("scanLadarStrengthBonus", src.getModifiedChargeAttr("scanLadarStrengthBonusBonus"))
|
||||
10
eos/effects/scriptscanmagnetometricstrengthbonusbonus.py
Normal file
10
eos/effects/scriptscanmagnetometricstrengthbonusbonus.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# scriptscanMagnetometricStrengthBonusBonus
|
||||
#
|
||||
# Used by:
|
||||
# Charges from group: Structure ECM script (4 of 4)
|
||||
type = "passive"
|
||||
runTime = "early"
|
||||
|
||||
|
||||
def handler(fit, src, context, *args, **kwargs):
|
||||
src.boostItemAttr("scanMagnetometricStrengthBonus", src.getModifiedChargeAttr("scanMagnetometricStrengthBonusBonus"))
|
||||
10
eos/effects/scriptscanradarstrengthbonusbonus.py
Normal file
10
eos/effects/scriptscanradarstrengthbonusbonus.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# scriptscanRadarStrengthBonusBonus
|
||||
#
|
||||
# Used by:
|
||||
# Charges from group: Structure ECM script (4 of 4)
|
||||
type = "passive"
|
||||
runTime = "early"
|
||||
|
||||
|
||||
def handler(fit, src, context, *args, **kwargs):
|
||||
src.boostItemAttr("scanRadarStrengthBonus", src.getModifiedChargeAttr("scanRadarStrengthBonusBonus"))
|
||||
11
eos/effects/scriptstandupwarpscram.py
Normal file
11
eos/effects/scriptstandupwarpscram.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# scriptStandupWarpScram
|
||||
#
|
||||
# Used by:
|
||||
# Charge: Standup Focused Warp Scrambling Script
|
||||
|
||||
type = "passive"
|
||||
runTime = "early"
|
||||
|
||||
|
||||
def handler(fit, src, context, *args, **kwargs):
|
||||
src.boostItemAttr("maxRange", src.getModifiedChargeAttr("warpScrambleRangeBonus"))
|
||||
7
eos/effects/servicemodulefullpowerhitpointpostassign.py
Normal file
7
eos/effects/servicemodulefullpowerhitpointpostassign.py
Normal file
@@ -0,0 +1,7 @@
|
||||
# Not used by any item
|
||||
type = "passive"
|
||||
runTime = "early"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.ship.forceItemAttr("structureFullPowerStateHitpointMultiplier", src.getModifiedItemAttr("serviceModuleFullPowerStateHitpointMultiplier"))
|
||||
@@ -9,4 +9,6 @@ type = "passive"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
fit.ship.multiplyItemAttr("shieldCapacity", module.getModifiedItemAttr("shieldCapacityMultiplier"))
|
||||
# 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("shieldCapacity", module.getModifiedItemAttr("shieldCapacityMultiplier", None))
|
||||
|
||||
9
eos/effects/shipagilitybonusgc1.py
Normal file
9
eos/effects/shipagilitybonusgc1.py
Normal file
@@ -0,0 +1,9 @@
|
||||
# shipAgilityBonusGC1
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Monitor
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.ship.boostItemAttr("agility", src.getModifiedItemAttr("shipBonusGC"), skill="Gallente Cruiser")
|
||||
9
eos/effects/shiparmorhitpointsac1.py
Normal file
9
eos/effects/shiparmorhitpointsac1.py
Normal file
@@ -0,0 +1,9 @@
|
||||
# shipArmorHitPointsAC1
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Monitor
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.ship.boostItemAttr("armorHP", src.getModifiedItemAttr("shipBonusAC"), skill="Amarr Cruiser")
|
||||
@@ -2,6 +2,7 @@
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Gnosis
|
||||
# Ship: Praxis
|
||||
# Ship: Sunesis
|
||||
# Ship: Taipan
|
||||
# Ship: Velator
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# Used by:
|
||||
# Variations of ship: Procurer (2 of 2)
|
||||
# Ship: Gnosis
|
||||
# Ship: Praxis
|
||||
# Ship: Sunesis
|
||||
# Ship: Taipan
|
||||
# Ship: Velator
|
||||
|
||||
10
eos/effects/shipbonusdronetrackingelitegunship2.py
Normal file
10
eos/effects/shipbonusdronetrackingelitegunship2.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# shipBonusDroneTrackingEliteGunship2
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Ishkur
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "trackingSpeed",
|
||||
src.getModifiedItemAttr("eliteBonusGunship2"), skill="Assault Frigates")
|
||||
10
eos/effects/shipbonusheavyassaultmissileemdamagecbc2.py
Normal file
10
eos/effects/shipbonusheavyassaultmissileemdamagecbc2.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# shipBonusHeavyAssaultMissileEMDamageCBC2
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Drake Navy Issue
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Heavy Assault Missiles"), "emDamage",
|
||||
src.getModifiedItemAttr("shipBonusCBC2"), skill="Caldari Battlecruiser")
|
||||
@@ -0,0 +1,10 @@
|
||||
# shipBonusHeavyAssaultMissileExplosiveDamageCBC2
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Drake Navy Issue
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Heavy Assault Missiles"), "explosiveDamage",
|
||||
src.getModifiedItemAttr("shipBonusCBC2"), skill="Caldari Battlecruiser")
|
||||
10
eos/effects/shipbonusheavyassaultmissilekineticdamagecbc2.py
Normal file
10
eos/effects/shipbonusheavyassaultmissilekineticdamagecbc2.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# shipBonusHeavyAssaultMissileKineticDamageCBC2
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Drake Navy Issue
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Heavy Assault Missiles"),
|
||||
"kineticDamage", src.getModifiedItemAttr("shipBonusCBC2"), skill="Caldari Battlecruiser")
|
||||
10
eos/effects/shipbonusheavyassaultmissilethermaldamagecbc2.py
Normal file
10
eos/effects/shipbonusheavyassaultmissilethermaldamagecbc2.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# shipBonusHeavyAssaultMissileThermalDamageCBC2
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Drake Navy Issue
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Heavy Assault Missiles"),
|
||||
"thermalDamage", src.getModifiedItemAttr("shipBonusCBC2"), skill="Caldari Battlecruiser")
|
||||
10
eos/effects/shipbonusheavymissileemdamagecbc2.py
Normal file
10
eos/effects/shipbonusheavymissileemdamagecbc2.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# shipBonusHeavyMissileEMDamageCBC2
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Drake Navy Issue
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Heavy Missiles"),
|
||||
"emDamage", src.getModifiedItemAttr("shipBonusCBC2"), skill="Caldari Battlecruiser")
|
||||
10
eos/effects/shipbonusheavymissileexplosivedamagecbc2.py
Normal file
10
eos/effects/shipbonusheavymissileexplosivedamagecbc2.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# shipBonusHeavyMissileExplosiveDamageCBC2
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Drake Navy Issue
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Heavy Missiles"), "explosiveDamage",
|
||||
src.getModifiedItemAttr("shipBonusCBC2"), skill="Caldari Battlecruiser")
|
||||
10
eos/effects/shipbonusheavymissilekineticdamagecbc2.py
Normal file
10
eos/effects/shipbonusheavymissilekineticdamagecbc2.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# shipBonusHeavyMissileKineticDamageCBC2
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Drake Navy Issue
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Heavy Missiles"), "kineticDamage",
|
||||
src.getModifiedItemAttr("shipBonusCBC2"), skill="Caldari Battlecruiser")
|
||||
10
eos/effects/shipbonusheavymissilethermaldamagecbc2.py
Normal file
10
eos/effects/shipbonusheavymissilethermaldamagecbc2.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# shipBonusHeavyMissileThermalDamageCBC2
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Drake Navy Issue
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Heavy Missiles"), "thermalDamage",
|
||||
src.getModifiedItemAttr("shipBonusCBC2"), skill="Caldari Battlecruiser")
|
||||
@@ -2,6 +2,7 @@
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Gnosis
|
||||
# Ship: Praxis
|
||||
# Ship: Taipan
|
||||
# Ship: Velator
|
||||
type = "passive"
|
||||
|
||||
@@ -9,4 +9,4 @@ type = "passive"
|
||||
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"),
|
||||
"explosionDelay", ship.getModifiedItemAttr("shipBonusPirateFaction2"))
|
||||
"explosionDelay", ship.getModifiedItemAttr("shipBonusRole8"))
|
||||
|
||||
@@ -7,6 +7,6 @@ type = "passive"
|
||||
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"),
|
||||
"maxRange", ship.getModifiedItemAttr("shipBonusPirateFaction2"))
|
||||
"maxRange", ship.getModifiedItemAttr("shipBonusRole8"))
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"),
|
||||
"falloffEffectiveness", ship.getModifiedItemAttr("shipBonusPirateFaction2"))
|
||||
"falloffEffectiveness", ship.getModifiedItemAttr("shipBonusRole8"))
|
||||
|
||||
38
eos/effects/shiplargeweaponsdamagebonus.py
Normal file
38
eos/effects/shiplargeweaponsdamagebonus.py
Normal file
@@ -0,0 +1,38 @@
|
||||
# shipLargeWeaponsDamageBonus
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Praxis
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Large Hybrid Turret"), "damageMultiplier",
|
||||
src.getModifiedItemAttr("shipBonusRole7"))
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Large Projectile Turret"), "damageMultiplier",
|
||||
src.getModifiedItemAttr("shipBonusRole7"))
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Large Energy Turret"), "damageMultiplier",
|
||||
src.getModifiedItemAttr("shipBonusRole7"))
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Heavy Missiles"), "thermalDamage",
|
||||
src.getModifiedItemAttr("shipBonusRole7"))
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Heavy Missiles"), "emDamage",
|
||||
src.getModifiedItemAttr("shipBonusRole7"))
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Heavy Missiles"), "kineticDamage",
|
||||
src.getModifiedItemAttr("shipBonusRole7"))
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Heavy Missiles"), "explosiveDamage",
|
||||
src.getModifiedItemAttr("shipBonusRole7"))
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Torpedoes"), "emDamage",
|
||||
src.getModifiedItemAttr("shipBonusRole7"))
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Torpedoes"), "kineticDamage",
|
||||
src.getModifiedItemAttr("shipBonusRole7"))
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Torpedoes"), "explosiveDamage",
|
||||
src.getModifiedItemAttr("shipBonusRole7"))
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Torpedoes"), "thermalDamage",
|
||||
src.getModifiedItemAttr("shipBonusRole7"))
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Cruise Missiles"), "thermalDamage",
|
||||
src.getModifiedItemAttr("shipBonusRole7"))
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Cruise Missiles"), "explosiveDamage",
|
||||
src.getModifiedItemAttr("shipBonusRole7"))
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Cruise Missiles"), "kineticDamage",
|
||||
src.getModifiedItemAttr("shipBonusRole7"))
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Cruise Missiles"), "emDamage",
|
||||
src.getModifiedItemAttr("shipBonusRole7"))
|
||||
@@ -4,10 +4,11 @@
|
||||
# Ships named like: Stratios (2 of 2)
|
||||
# Ship: Astero
|
||||
# Ship: Gnosis
|
||||
# Ship: Praxis
|
||||
# Ship: Sunesis
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, container, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Astrometrics"),
|
||||
"baseSensorStrength", container.getModifiedItemAttr("shipBonusPirateFaction2"))
|
||||
"baseSensorStrength", container.getModifiedItemAttr("shipBonusRole8"))
|
||||
|
||||
@@ -7,4 +7,4 @@ type = "passive"
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Small Energy Turret"), "speed",
|
||||
src.getModifiedItemAttr("shipBonusAF"), stackingPenalties=True, skill="Amarr Frigate")
|
||||
src.getModifiedItemAttr("shipBonusAF"), stackingPenalties=False, skill="Amarr Frigate")
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# shipShieldEmResistance1CBC2
|
||||
#
|
||||
# Used by:
|
||||
# Variations of ship: Drake (3 of 3)
|
||||
# Ship: Drake
|
||||
# Ship: Nighthawk
|
||||
# Ship: Vulture
|
||||
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