145
.appveyor.yml
145
.appveyor.yml
@@ -1,5 +1,4 @@
|
||||
environment:
|
||||
|
||||
global:
|
||||
# SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the
|
||||
# /E:ON and /V:ON options are not enabled in the batch script intepreter
|
||||
@@ -8,76 +7,11 @@ environment:
|
||||
|
||||
matrix:
|
||||
|
||||
# Python 2.7.10 is the latest version and is not pre-installed.
|
||||
|
||||
- PYTHON: "C:\\Python27.10"
|
||||
PYTHON_VERSION: "2.7.10"
|
||||
- PYTHON: "C:\\Python36"
|
||||
PYTHON_VERSION: "3.6.x"
|
||||
PYTHON_ARCH: "32"
|
||||
|
||||
#- PYTHON: "C:\\Python27.10-x64"
|
||||
# PYTHON_VERSION: "2.7.10"
|
||||
# PYTHON_ARCH: "64"
|
||||
|
||||
# Pre-installed Python versions, which Appveyor may upgrade to
|
||||
# a later point release.
|
||||
# See: http://www.appveyor.com/docs/installed-software#python
|
||||
|
||||
#- PYTHON: "C:\\Python27"
|
||||
# PYTHON_VERSION: "2.7.x" # currently 2.7.9
|
||||
# PYTHON_ARCH: "32"
|
||||
|
||||
#- PYTHON: "C:\\Python27-x64"
|
||||
# PYTHON_VERSION: "2.7.x" # currently 2.7.9
|
||||
# PYTHON_ARCH: "64"
|
||||
|
||||
#- PYTHON: "C:\\Python33"
|
||||
# PYTHON_VERSION: "3.3.x" # currently 3.3.5
|
||||
# PYTHON_ARCH: "32"
|
||||
|
||||
#- PYTHON: "C:\\Python33-x64"
|
||||
# PYTHON_VERSION: "3.3.x" # currently 3.3.5
|
||||
# PYTHON_ARCH: "64"
|
||||
|
||||
#- PYTHON: "C:\\Python34"
|
||||
# PYTHON_VERSION: "3.4.x" # currently 3.4.3
|
||||
# PYTHON_ARCH: "32"
|
||||
|
||||
#- PYTHON: "C:\\Python34-x64"
|
||||
# PYTHON_VERSION: "3.4.x" # currently 3.4.3
|
||||
# PYTHON_ARCH: "64"
|
||||
|
||||
# Python versions not pre-installed
|
||||
|
||||
# Python 2.6.6 is the latest Python 2.6 with a Windows installer
|
||||
# See: https://github.com/ogrisel/python-appveyor-demo/issues/10
|
||||
|
||||
#- PYTHON: "C:\\Python266"
|
||||
# PYTHON_VERSION: "2.6.6"
|
||||
# PYTHON_ARCH: "32"
|
||||
|
||||
#- PYTHON: "C:\\Python266-x64"
|
||||
# PYTHON_VERSION: "2.6.6"
|
||||
# PYTHON_ARCH: "64"
|
||||
|
||||
#- PYTHON: "C:\\Python35"
|
||||
# PYTHON_VERSION: "3.5.0"
|
||||
# PYTHON_ARCH: "32"
|
||||
|
||||
#- PYTHON: "C:\\Python35-x64"
|
||||
# PYTHON_VERSION: "3.5.0"
|
||||
# PYTHON_ARCH: "64"
|
||||
|
||||
# Major and minor releases (i.e x.0.0 and x.y.0) prior to 3.3.0 use
|
||||
# a different naming scheme.
|
||||
|
||||
#- PYTHON: "C:\\Python270"
|
||||
# PYTHON_VERSION: "2.7.0"
|
||||
# PYTHON_ARCH: "32"
|
||||
|
||||
#- PYTHON: "C:\\Python270-x64"
|
||||
# PYTHON_VERSION: "2.7.0"
|
||||
# PYTHON_ARCH: "64"
|
||||
|
||||
init:
|
||||
- ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
install:
|
||||
# If there is a newer build queued for the same PR, cancel this one.
|
||||
# The AppVeyor 'rollout builds' option is supposed to serve the same
|
||||
@@ -89,34 +23,23 @@ install:
|
||||
Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { `
|
||||
throw "There are newer queued builds for this pull request, failing early." }
|
||||
|
||||
# Install wxPython
|
||||
- 'ECHO Downloading wxPython.'
|
||||
- "appveyor DownloadFile https://goo.gl/yvO8PB -FileName C:\\wxpython.exe"
|
||||
#- "appveyor DownloadFile https://goo.gl/Uj0jV3 -FileName C:\\wxpython64.exe"
|
||||
|
||||
- 'ECHO Install wxPython'
|
||||
- "C:\\wxpython.exe /SP- /VERYSILENT /NORESTART"
|
||||
#- "C:\\wxpython64.exe /SP- /VERYSILENT /NORESTART"
|
||||
|
||||
- ECHO "Filesystem root:"
|
||||
- ps: "ls \"C:/\""
|
||||
|
||||
- ECHO "Filesystem projects root:"
|
||||
- ps: "ls \"C:\\projects\\\""
|
||||
|
||||
- ECHO "Filesystem pyfa root:"
|
||||
- ps: "ls \"C:\\projects\\pyfa\\\""
|
||||
- ps: "ls \"C:\\projects\\$env:APPVEYOR_PROJECT_SLUG\""
|
||||
|
||||
- ECHO "Installed SDKs:"
|
||||
- ps: "ls \"C:/Program Files/Microsoft SDKs/Windows\""
|
||||
|
||||
# Install Python (from the official .msi of http://python.org) and pip when
|
||||
# not already installed.
|
||||
# - ps: if (-not(Test-Path($env:PYTHON))) { & appveyor\install.ps1 }
|
||||
|
||||
# Prepend newly installed Python to the PATH of this build (this cannot be
|
||||
# done from inside the powershell script as it would require to restart
|
||||
# the parent CMD process).
|
||||
- "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
|
||||
|
||||
# Check that we have the expected version and architecture for Python
|
||||
- "python --version"
|
||||
- "python -c \"import struct; print(struct.calcsize('P') * 8)\""
|
||||
|
||||
@@ -128,19 +51,36 @@ install:
|
||||
# compiled extensions and are not provided as pre-built wheel packages,
|
||||
# pip will build them from source using the MSVC compiler matching the
|
||||
# target Python version and architecture
|
||||
# C:\\projects\\eve-gnosis\\
|
||||
- ECHO "Install pip requirements:"
|
||||
- "pip install -r requirements.txt"
|
||||
- "pip install -r requirements_test.txt"
|
||||
- "pip install -r requirements_build_windows.txt"
|
||||
- "pip install PyInstaller"
|
||||
|
||||
before_build:
|
||||
# directory that will contain the built files
|
||||
- ps: $env:PYFA_DIST_DIR = "c:\projects\$env:APPVEYOR_PROJECT_SLUG\dist"
|
||||
- ps: $env:PYFA_VERSION = (python ./scripts/dump_version.py)
|
||||
- ps: echo("pyfa version ")
|
||||
- ps: echo ($env:PYFA_VERSION)
|
||||
|
||||
build_script:
|
||||
# Build the compiled extension
|
||||
# - "python setup.py build"
|
||||
- ECHO "Build pyfa:"
|
||||
#- copy C:\projects\pyfa\dist_assets\win\pyfa.spec C:\projects\pyfa\pyfa.spec
|
||||
- "python C:\\projects\\pyfa\\setup.py build"
|
||||
|
||||
##########
|
||||
# PyInstaller - create binaries for pyfa
|
||||
##########
|
||||
# Build command for PyInstaller
|
||||
- "python -m PyInstaller --noupx --clean --windowed --noconsole -y pyfa.spec"
|
||||
# Copy over manifest (See pyfa-org/pyfa#1622)
|
||||
- ps: xcopy /y dist_assets\win\pyfa.exe.manifest $env:PYFA_DIST_DIR\pyfa\
|
||||
# Not really sure if this is needed, but why not
|
||||
- ps: xcopy /y dist_assets\win\Microsoft.VC90.CRT.manifest $env:PYFA_DIST_DIR\pyfa\
|
||||
|
||||
##########
|
||||
# InnoScript EXE building
|
||||
# This is in a separate script because I don't feel like copying over the logic to AppVeyor script right now...
|
||||
##########
|
||||
- "python dist_assets/win/dist.py"
|
||||
- ps: dir $env:PYFA_DIST_DIR/
|
||||
#- ECHO "Build pyfa (Debug):"
|
||||
#- copy C:\projects\pyfa\dist_assets\win\pyfa_debug.spec C:\projects\pyfa\pyfa_debug.spec
|
||||
#- "pyinstaller.exe --clean --noconfirm --windowed --upx-dir=C:\\projects\\pyfa\\scripts\\upx.exe C:\\projects\\pyfa\\pyfa_debug.spec"
|
||||
@@ -150,12 +90,11 @@ build: on
|
||||
after_build:
|
||||
- ps: "ls \"./\""
|
||||
#- ps: "ls \"C:\\projects\\pyfa\\build\\pyfa\\\""
|
||||
- ps: "ls \"C:\\projects\\pyfa\\build\\\""
|
||||
- ps: "ls \"C:\\projects\\pyfa\\build\\exe.win32-2.7\\\""
|
||||
# - ps: "ls \"C:\\projects\\$env:APPVEYOR_PROJECT_SLUG\\build\\exe.win32-2.7\\\""
|
||||
# Zip
|
||||
# APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER
|
||||
#- 7z a build.zip -r C:\projects\pyfa\build\pyfa\*.*
|
||||
- 7z a pyfa.zip -r C:\projects\pyfa\build\exe.win32-2.7\*.*
|
||||
- ps: 7z a "pyfa-$env:PYFA_VERSION-win.zip" -r "$env:PYFA_DIST_DIR\pyfa\*.*"
|
||||
#- 7z a pyfa_debug.zip -r C:\projects\pyfa\dist\pyfa_debug\*.*
|
||||
|
||||
on_success:
|
||||
@@ -176,11 +115,21 @@ after_test:
|
||||
|
||||
artifacts:
|
||||
# Archive the generated packages in the ci.appveyor.com build report.
|
||||
- path: pyfa.zip
|
||||
name: 'pyfa.zip'
|
||||
- path: pyfa*-win.zip
|
||||
- path: pyfa*-win.exe
|
||||
#- path: pyfa_debug.zip
|
||||
# name: Pyfa_debug
|
||||
|
||||
|
||||
deploy:
|
||||
tag: $(pyfa_version)
|
||||
release: pyfa $(pyfa_version)
|
||||
description: 'Release description'
|
||||
provider: GitHub
|
||||
auth_token:
|
||||
secure: BfNHO66ff5hVx2O2ORbl49X0U/5h2V2T0IuRZDwm7fd1HvsVluF0wRCbl29oRp1M
|
||||
draft: true
|
||||
on:
|
||||
APPVEYOR_REPO_TAG: true # deploy on tag push only
|
||||
#on_success:
|
||||
# - TODO: upload the content of dist/*.whl to a public wheelhouse
|
||||
#
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -122,3 +122,4 @@ gitversion
|
||||
/.version
|
||||
*.swp
|
||||
|
||||
*.fsdbinary
|
||||
|
||||
58
.travis.yml
58
.travis.yml
@@ -1,39 +1,29 @@
|
||||
os: linux
|
||||
language: python
|
||||
cache: pip
|
||||
python:
|
||||
- '2.7'
|
||||
env:
|
||||
- TOXENV=pep8
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- 3.6
|
||||
matrix:
|
||||
include:
|
||||
- os: osx
|
||||
osx_image: xcode7.3
|
||||
language: generic
|
||||
env: PYTHON=3.6.1
|
||||
before_install:
|
||||
- sudo apt-get update && sudo apt-get --reinstall install -qq language-pack-en language-pack-ru language-pack-he language-pack-zh-hans
|
||||
- pip install tox
|
||||
# We're not actually installing Tox, but have to run it before we install wxPython via Conda. This is fugly but vOv
|
||||
- tox
|
||||
# get Conda
|
||||
- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then
|
||||
wget https://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh;
|
||||
else
|
||||
wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh;
|
||||
fi
|
||||
- bash miniconda.sh -b -p $HOME/miniconda
|
||||
- export PATH="$HOME/miniconda/bin:$PATH"
|
||||
- hash -r
|
||||
- conda config --set always_yes yes --set changeps1 no
|
||||
- conda update -q conda
|
||||
# Useful for debugging any issues with conda
|
||||
- conda info -a
|
||||
- bash scripts/setup-osx.sh
|
||||
install:
|
||||
# install wxPython 3.0.0.0
|
||||
- conda install -c https://conda.anaconda.org/travis wxpython
|
||||
before_script:
|
||||
- pip install -r requirements.txt
|
||||
- pip install -r requirements_test.txt
|
||||
script:
|
||||
- py.test --cov=./
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
- export PYFA_VERSION="$(python3 scripts/dump_version.py)"
|
||||
- bash scripts/package-osx.sh
|
||||
before_deploy:
|
||||
- pip install -r requirements_build_linux.txt
|
||||
- export RELEASE_PKG_FILE=$(ls *.deb)
|
||||
- echo "deploying $RELEASE_PKG_FILE to GitHub releases"
|
||||
deploy:
|
||||
provider: releases
|
||||
api_key:
|
||||
secure: Xfu0xApoB0zUPLXl29aYUulVC3iA4/3bXQwwADKCfAKZwxgNon4dLbO7Rie5/7Ukf2POL0KwmRaQGN3kOr+XSoIVTE4M5sXxnhiaaLGKQ+48hDizLE6JuXcZGJvkxUaghaTzIdCwHsG7VGBsPfQgfGsjJcfBp8tFNLmRyM/Jpsr8T6BR2MxtBIEUVy8zrOWFNZqnmWrY2pWMsB9fYt3JFNdpqeIgRAYqbBsBcZQ1MngLTi3ztuYS5IaF+lk06RrnBlHmUsJu/5nCvIpvPvD0i2BLZ3Uu0+Fn+8QWUgjJEL9MNseXZMXynu05xd8YRk7Ajc9CUrzQIIbAktyteYp85kE3pUJHmrMLcXhh7nqkwttR5/47Zwa3OLJLJFKBxMx6wY5jFkJjkV08850B7aWrmTFl/Eqc3Q5nZMuiEt3wFRbjxHi9h1mTN/fkxfRRHg8u3ENGPR+ZPiFC3J18qtks/B/hsKjjHvZP1i79OYlET4V/zyLyyQkCbpDaARQANuotLYJyZ7tH+KWEyRsvTi0M9Yev9mNNw6aI4vzh4HfkEhvcvnWnYwckPj1dnjQ573Qpw0Z9wsconoWfHAn+hBDt3+YLMrrFZl++mCRskHH1mZChX3aGMDi49zD0kfxBUkYPOAhguc6PwudBxHUZP+O6T/SoHylff6EizCE/k5dGeAk=
|
||||
file_glob: true
|
||||
file: "dist/pyfa-*.zip"
|
||||
skip_cleanup: true
|
||||
draft: true
|
||||
on:
|
||||
tags: true
|
||||
repo: pyfa-org/Pyfa
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import pytest
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
from _development.helpers import DBInMemory as DB, Gamedata, Saveddata
|
||||
|
||||
|
||||
# noinspection PyShadowingNames
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import pytest
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
from _development.helpers import DBInMemory as DB, Gamedata, Saveddata
|
||||
|
||||
|
||||
# noinspection PyShadowingNames
|
||||
|
||||
38
config.py
38
config.py
@@ -1,5 +1,6 @@
|
||||
import os
|
||||
import sys
|
||||
import yaml
|
||||
|
||||
from logbook import CRITICAL, DEBUG, ERROR, FingersCrossedHandler, INFO, Logger, NestedSetup, NullHandler, \
|
||||
StreamHandler, TimedRotatingFileHandler, WARNING
|
||||
@@ -22,12 +23,6 @@ debug = False
|
||||
# Defines if our saveddata will be in pyfa root or not
|
||||
saveInRoot = False
|
||||
|
||||
# Version data
|
||||
|
||||
version = "2.0.0"
|
||||
tag = "Stable"
|
||||
expansionName = "YC120.3"
|
||||
expansionVersion = "1.8"
|
||||
evemonMinVersion = "4081"
|
||||
|
||||
minItemSearchLength = 3
|
||||
@@ -42,7 +37,6 @@ logging_setup = None
|
||||
cipher = None
|
||||
clientHash = None
|
||||
|
||||
ESI_AUTH_PROXY = "https://www.pyfa.io" # "http://localhost:5015"
|
||||
ESI_CACHE = 'esi_cache'
|
||||
|
||||
LOGLEVEL_MAP = {
|
||||
@@ -80,12 +74,7 @@ def getPyfaRoot():
|
||||
|
||||
|
||||
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)"
|
||||
return version
|
||||
|
||||
|
||||
def getDefaultSave():
|
||||
@@ -97,11 +86,12 @@ def defPaths(customSavePath=None):
|
||||
global pyfaPath
|
||||
global savePath
|
||||
global saveDB
|
||||
global gameDB
|
||||
global gameDB
|
||||
global saveInRoot
|
||||
global logPath
|
||||
global cipher
|
||||
global clientHash
|
||||
global version
|
||||
|
||||
pyfalog.debug("Configuring Pyfa")
|
||||
|
||||
@@ -111,6 +101,12 @@ def defPaths(customSavePath=None):
|
||||
if pyfaPath is None:
|
||||
pyfaPath = getPyfaRoot()
|
||||
|
||||
# Version data
|
||||
|
||||
with open(os.path.join(pyfaPath, "version.yml"), 'r') as file:
|
||||
data = yaml.load(file)
|
||||
version = data['version']
|
||||
|
||||
# Where we store the saved fits etc, default is the current users home directory
|
||||
if saveInRoot is True:
|
||||
savePath = getattr(configforced, "savePath", None)
|
||||
@@ -230,20 +226,6 @@ def defLogging():
|
||||
)
|
||||
])
|
||||
|
||||
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):
|
||||
|
||||
@@ -24,11 +24,15 @@ added_files = [
|
||||
('../../eve.db', '.'),
|
||||
('../../README.md', '.'),
|
||||
('../../LICENSE', '.'),
|
||||
('../../.version', '.'),
|
||||
('../../version.yml', '.'),
|
||||
]
|
||||
|
||||
|
||||
import_these = []
|
||||
import_these = [
|
||||
'numpy.core._dtype_ctypes' # https://github.com/pyinstaller/pyinstaller/issues/3982
|
||||
]
|
||||
|
||||
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')
|
||||
@@ -52,8 +56,10 @@ a = Analysis([r'../../pyfa.py'],
|
||||
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,
|
||||
@@ -65,10 +71,19 @@ exe = EXE(pyz,
|
||||
upx=True,
|
||||
runtime_tmpdir=None,
|
||||
console=False ,
|
||||
icon='dist_assets/mac/pyfa.icns',
|
||||
icon=icon,
|
||||
)
|
||||
|
||||
app = BUNDLE(exe,
|
||||
name='pyfa.app',
|
||||
icon=None,
|
||||
bundle_identifier=None)
|
||||
app = BUNDLE(
|
||||
exe,
|
||||
name='pyfa.app',
|
||||
icon=icon,
|
||||
bundle_identifier=None,
|
||||
info_plist={
|
||||
'NSHighResolutionCapable': 'True',
|
||||
'NSPrincipalClass': 'NSApplication',
|
||||
'CFBundleName': 'pyfa',
|
||||
'CFBundleDisplayName': 'pyfa',
|
||||
'CFBundleIdentifier': 'org.pyfaorg.pyfa',
|
||||
}
|
||||
)
|
||||
13
dist_assets/win/Microsoft.VC90.CRT.manifest
Normal file
13
dist_assets/win/Microsoft.VC90.CRT.manifest
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<noInheritable/>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.VC90.CRT"
|
||||
version="9.0.21022.8"
|
||||
processorArchitecture="x86"
|
||||
publicKeyToken="1fc8b3b9a1e18e3b"/>
|
||||
<file name="MSVCR90.DLL"/>
|
||||
<file name="MSVCM90.DLL"/>
|
||||
<file name="MSVCP90.DLL"/>
|
||||
</assembly>
|
||||
37
dist_assets/win/dist.py
Normal file
37
dist_assets/win/dist.py
Normal file
@@ -0,0 +1,37 @@
|
||||
# helper script to zip up pyinstaller distribution and create installer file
|
||||
|
||||
import os.path
|
||||
from subprocess import call
|
||||
import zipfile
|
||||
from packaging.version import Version
|
||||
import yaml
|
||||
|
||||
|
||||
with open("version.yml", 'r') as file:
|
||||
data = yaml.load(file)
|
||||
version = data['version']
|
||||
|
||||
os.environ["PYFA_DIST_DIR"] = os.path.join(os.getcwd(), 'dist')
|
||||
|
||||
os.environ["PYFA_VERSION"] = version
|
||||
iscc = "C:\Program Files (x86)\Inno Setup 5\ISCC.exe" # inno script location via wine
|
||||
|
||||
source = os.path.join(os.environ["PYFA_DIST_DIR"], "pyfa")
|
||||
|
||||
fileName = "pyfa-{}-win".format(os.environ["PYFA_VERSION"])
|
||||
|
||||
print("Compiling EXE")
|
||||
|
||||
v = Version(version)
|
||||
|
||||
print(v)
|
||||
|
||||
call([
|
||||
iscc,
|
||||
os.path.join(os.getcwd(), "dist_assets", "win", "pyfa-setup.iss"),
|
||||
"/dMyAppVersion=%s" % v,
|
||||
"/dMyAppDir=%s" % source,
|
||||
"/dMyOutputDir=%s" % os.path.join(os.getcwd()),
|
||||
"/dMyOutputFile=%s" % fileName]) # stdout=devnull, stderr=devnull
|
||||
|
||||
print("Done")
|
||||
@@ -5,24 +5,22 @@
|
||||
; we do some #ifdef conditionals because automated compilation passes these as arguments
|
||||
|
||||
#ifndef MyAppVersion
|
||||
#define MyAppVersion "1.15.0"
|
||||
#endif
|
||||
#ifndef MyAppExpansion
|
||||
#define MyAppExpansion "Vanguard 1.0"
|
||||
#define MyAppVersion "2.1.0"
|
||||
#endif
|
||||
|
||||
; Other config
|
||||
|
||||
#define MyAppName "pyfa"
|
||||
#define MyAppPublisher "pyfa"
|
||||
#define MyAppURL "https://forums.eveonline.com/t/27156"
|
||||
#define MyAppURL "https://github.com/pyfa-org/Pyfa/"
|
||||
#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', " ", "-"))
|
||||
#define MyOutputFile LowerCase(StringChange(MyAppName+'-'+MyAppVersion+'-win', " ", "-"))
|
||||
#endif
|
||||
#ifndef MyAppDir
|
||||
#define MyAppDir "pyfa"
|
||||
@@ -38,7 +36,7 @@
|
||||
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
|
||||
AppId={{3DA39096-C08D-49CD-90E0-1D177F32C8AA}
|
||||
AppName={#MyAppName}
|
||||
AppVersion={#MyAppVersion} ({#MyAppExpansion})
|
||||
AppVersion={#MyAppVersion}
|
||||
AppPublisher={#MyAppPublisher}
|
||||
AppPublisherURL={#MyAppURL}
|
||||
AppSupportURL={#MyAppURL}
|
||||
@@ -50,10 +48,8 @@ LicenseFile={#MyAppDir}\LICENSE
|
||||
OutputDir={#MyOutputDir}
|
||||
OutputBaseFilename={#MyOutputFile}
|
||||
SetupIconFile={#MyAppDir}\pyfa.ico
|
||||
Compression=lzma
|
||||
SolidCompression=yes
|
||||
CloseApplications=yes
|
||||
AppReadmeFile=https://github.com/pyfa-org/Pyfa/blob/v{#MyAppVersion}/readme.txt
|
||||
|
||||
[Languages]
|
||||
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||
@@ -63,7 +59,7 @@ Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{
|
||||
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1
|
||||
|
||||
[Files]
|
||||
Source: "{#MyAppDir}\pyfa.exe"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "{#MyAppDir}\pyfa.exe"; DestDir: "{app}"; Flags: ignoreversion; AfterInstall: RemoveFromVirtualStore
|
||||
Source: "{#MyAppDir}\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
|
||||
|
||||
@@ -103,6 +99,22 @@ begin
|
||||
FSWbemLocator := Unassigned;
|
||||
end;
|
||||
|
||||
procedure RemoveFromVirtualStore;
|
||||
var
|
||||
VirtualStore,FileName,FilePath:String;
|
||||
DriveChars:Integer;
|
||||
begin
|
||||
VirtualStore:=AddBackslash(ExpandConstant('{localappdata}'))+'VirtualStore';
|
||||
FileName:=ExpandConstant(CurrentFileName);
|
||||
DriveChars:=Length(ExtractFileDrive(FileName));
|
||||
if DriveChars>0 then begin
|
||||
Delete(FileName,1,DriveChars);
|
||||
FileName:=VirtualStore+FileName;
|
||||
FilePath:=ExtractFilePath(FileName);
|
||||
DelTree(FilePath, True, True, True);
|
||||
end;
|
||||
end;
|
||||
|
||||
function PrepareToInstall(var NeedsRestart: Boolean): String;
|
||||
begin
|
||||
if(IsAppRunning( 'pyfa.exe' )) then
|
||||
@@ -138,15 +150,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
|
||||
25
dist_assets/win/pyfa.exe.manifest
Normal file
25
dist_assets/win/pyfa.exe.manifest
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<assemblyIdentity name="pyfa" processorArchitecture="x86" type="win32" version="1.0.0.0"/>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<security>
|
||||
<requestedPrivileges>
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
|
||||
</application>
|
||||
</compatibility>
|
||||
</assembly>
|
||||
@@ -5,8 +5,7 @@ from itertools import chain
|
||||
import subprocess
|
||||
import requests.certs
|
||||
|
||||
label = subprocess.check_output([
|
||||
"git", "describe", "--tags"]).strip()
|
||||
label = subprocess.check_output(["git", "describe", "--tags"]).strip()
|
||||
|
||||
with open('.version', 'w+') as f:
|
||||
f.write(label.decode())
|
||||
@@ -18,16 +17,20 @@ added_files = [
|
||||
('../../imgs/gui/*.gif', 'imgs/gui'),
|
||||
('../../imgs/icons/*.png', 'imgs/icons'),
|
||||
('../../imgs/renders/*.png', 'imgs/renders'),
|
||||
('../../service/jargon/*.yaml', 'service/jargon'),
|
||||
('../../service/jargon/*.yaml', 'service/jargon'),
|
||||
('../../dist_assets/win/pyfa.ico', '.'),
|
||||
('../../dist_assets/win/pyfa.exe.manifest', '.'),
|
||||
('../../dist_assets/win/Microsoft.VC90.CRT.manifest', '.'),
|
||||
(requests.certs.where(), '.'), # is this needed anymore?
|
||||
('../../eve.db', '.'),
|
||||
('../../README.md', '.'),
|
||||
('../../LICENSE', '.'),
|
||||
('../../.version', '.'),
|
||||
('../../version.yml', '.'),
|
||||
]
|
||||
|
||||
import_these = []
|
||||
import_these = [
|
||||
'numpy.core._dtype_ctypes' # https://github.com/pyinstaller/pyinstaller/issues/3982
|
||||
]
|
||||
|
||||
# Walk directories that do dynamic importing
|
||||
paths = ('eos/effects', 'eos/db/migrations', 'service/conversions')
|
||||
@@ -79,4 +82,5 @@ coll = COLLECT(
|
||||
upx=True,
|
||||
name='pyfa',
|
||||
icon='dist_assets/win/pyfa.ico',
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ debug = False
|
||||
gamedataCache = True
|
||||
saveddataCache = True
|
||||
gamedata_version = ""
|
||||
gamedata_date = ""
|
||||
gamedata_connectionstring = 'sqlite:///' + realpath(join(dirname(abspath(__file__)), "..", "eve.db"))
|
||||
pyfalog.debug("Gamedata connection string: {0}", gamedata_connectionstring)
|
||||
|
||||
|
||||
@@ -51,10 +51,14 @@ try:
|
||||
config.gamedata_version = gamedata_session.execute(
|
||||
"SELECT `field_value` FROM `metadata` WHERE `field_name` LIKE 'client_build'"
|
||||
).fetchone()[0]
|
||||
config.gamedata_date = gamedata_session.execute(
|
||||
"SELECT `field_value` FROM `metadata` WHERE `field_name` LIKE 'dump_time'"
|
||||
).fetchone()[0]
|
||||
except Exception as e:
|
||||
pyfalog.warning("Missing gamedata version.")
|
||||
pyfalog.critical(e)
|
||||
config.gamedata_version = None
|
||||
config.gamedata_date = None
|
||||
|
||||
saveddata_connectionstring = config.saveddata_connectionstring
|
||||
if saveddata_connectionstring is not None:
|
||||
@@ -74,10 +78,10 @@ sd_lock = threading.RLock()
|
||||
|
||||
# Import all the definitions for all our database stuff
|
||||
# noinspection PyPep8
|
||||
from eos.db.gamedata import alphaClones, attribute, category, effect, group, icon, item, marketGroup, metaData, metaGroup, queries, traits, unit
|
||||
from eos.db.gamedata import alphaClones, attribute, category, effect, group, item, marketGroup, metaData, metaGroup, queries, traits, unit, dynamicAttributes
|
||||
# noinspection PyPep8
|
||||
from eos.db.saveddata import booster, cargo, character, damagePattern, databaseRepair, drone, fighter, fit, implant, implantSet, loadDefaultDatabaseValues, \
|
||||
miscData, module, override, price, queries, skill, targetResists, user
|
||||
miscData, mutator, module, override, price, queries, skill, targetResists, user
|
||||
|
||||
# Import queries
|
||||
# noinspection PyPep8
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
__all__ = ["attribute", "category", "effect", "group", "metaData",
|
||||
"icon", "item", "marketGroup", "metaGroup", "unit", "alphaClones"]
|
||||
__all__ = ["attribute", "category", "effect", "group", "metaData", "dynamicAttributes",
|
||||
"item", "marketGroup", "metaGroup", "unit", "alphaClones"]
|
||||
|
||||
@@ -22,7 +22,7 @@ from sqlalchemy.ext.associationproxy import association_proxy
|
||||
from sqlalchemy.orm import relation, mapper, synonym, deferred
|
||||
|
||||
from eos.db import gamedata_meta
|
||||
from eos.gamedata import Attribute, AttributeInfo, Unit, Icon
|
||||
from eos.gamedata import Attribute, AttributeInfo, Unit
|
||||
|
||||
typeattributes_table = Table("dgmtypeattribs", gamedata_meta,
|
||||
Column("value", Float),
|
||||
@@ -38,7 +38,7 @@ attributes_table = Table("dgmattribs", gamedata_meta,
|
||||
Column("published", Boolean),
|
||||
Column("displayName", String),
|
||||
Column("highIsGood", Boolean),
|
||||
Column("iconID", Integer, ForeignKey("icons.iconID")),
|
||||
Column("iconID", Integer),
|
||||
Column("unitID", Integer, ForeignKey("dgmunits.unitID")))
|
||||
|
||||
mapper(Attribute, typeattributes_table,
|
||||
@@ -46,7 +46,6 @@ mapper(Attribute, typeattributes_table,
|
||||
|
||||
mapper(AttributeInfo, attributes_table,
|
||||
properties={
|
||||
"icon" : relation(Icon),
|
||||
"unit" : relation(Unit),
|
||||
"ID" : synonym("attributeID"),
|
||||
"name" : synonym("attributeName"),
|
||||
|
||||
@@ -17,22 +17,21 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Column, String, Integer, ForeignKey, Boolean, Table
|
||||
from sqlalchemy.orm import relation, mapper, synonym, deferred
|
||||
from sqlalchemy import Boolean, Column, Integer, String, Table
|
||||
from sqlalchemy.orm import deferred, mapper, synonym
|
||||
|
||||
from eos.db import gamedata_meta
|
||||
from eos.gamedata import Category, Icon
|
||||
from eos.gamedata import Category
|
||||
|
||||
categories_table = Table("invcategories", gamedata_meta,
|
||||
Column("categoryID", Integer, primary_key=True),
|
||||
Column("categoryName", String),
|
||||
Column("description", String),
|
||||
Column("published", Boolean),
|
||||
Column("iconID", Integer, ForeignKey("icons.iconID")))
|
||||
Column("iconID", Integer))
|
||||
|
||||
mapper(Category, categories_table,
|
||||
properties={
|
||||
"icon" : relation(Icon),
|
||||
"ID" : synonym("categoryID"),
|
||||
"name" : synonym("categoryName"),
|
||||
"description": deferred(categories_table.c.description)
|
||||
|
||||
65
eos/db/gamedata/dynamicAttributes.py
Normal file
65
eos/db/gamedata/dynamicAttributes.py
Normal file
@@ -0,0 +1,65 @@
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
#
|
||||
# eos is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# eos is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Column, Float, Integer, Table, ForeignKey
|
||||
from sqlalchemy.orm import mapper, relation, synonym
|
||||
from sqlalchemy.ext.associationproxy import association_proxy
|
||||
|
||||
from eos.db import gamedata_meta
|
||||
from eos.gamedata import DynamicItem, DynamicItemAttribute, DynamicItemItem, Item
|
||||
|
||||
from eos.gamedata import AttributeInfo
|
||||
|
||||
dynamic_table = Table("mutaplasmids", gamedata_meta,
|
||||
Column("typeID", ForeignKey("invtypes.typeID"), primary_key=True, index=True),
|
||||
Column("resultingTypeID", ForeignKey("invtypes.typeID"), primary_key=True))
|
||||
|
||||
dynamicAttributes_table = Table("mutaplasmidAttributes", gamedata_meta,
|
||||
Column("typeID", Integer, ForeignKey("mutaplasmids.typeID"), primary_key=True),
|
||||
Column("attributeID", ForeignKey("dgmattribs.attributeID"), primary_key=True),
|
||||
Column("min", Float),
|
||||
Column("max", Float))
|
||||
|
||||
dynamicApplicable_table = Table("mutaplasmidItems", gamedata_meta,
|
||||
Column("typeID", ForeignKey("mutaplasmids.typeID"), primary_key=True),
|
||||
Column("applicableTypeID", ForeignKey("invtypes.typeID"), primary_key=True),)
|
||||
|
||||
mapper(DynamicItem, dynamic_table, properties={
|
||||
"attributes": relation(DynamicItemAttribute),
|
||||
"item": relation(Item, foreign_keys=[dynamic_table.c.typeID]),
|
||||
"resultingItem": relation(Item, foreign_keys=[dynamic_table.c.resultingTypeID]),
|
||||
"ID": synonym("typeID"),
|
||||
})
|
||||
|
||||
mapper(DynamicItemAttribute, dynamicAttributes_table,
|
||||
properties={"info": relation(AttributeInfo, lazy=False)})
|
||||
|
||||
mapper(DynamicItemItem, dynamicApplicable_table, properties={
|
||||
"mutaplasmid": relation(DynamicItem),
|
||||
})
|
||||
|
||||
DynamicItemAttribute.ID = association_proxy("info", "attributeID")
|
||||
DynamicItemAttribute.name = association_proxy("info", "attributeName")
|
||||
DynamicItemAttribute.description = association_proxy("info", "description")
|
||||
DynamicItemAttribute.published = association_proxy("info", "published")
|
||||
DynamicItemAttribute.displayName = association_proxy("info", "displayName")
|
||||
DynamicItemAttribute.highIsGood = association_proxy("info", "highIsGood")
|
||||
DynamicItemAttribute.iconID = association_proxy("info", "iconID")
|
||||
DynamicItemAttribute.icon = association_proxy("info", "icon")
|
||||
DynamicItemAttribute.unit = association_proxy("info", "unit")
|
||||
@@ -18,10 +18,10 @@
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Column, String, Integer, Boolean, ForeignKey, Table
|
||||
from sqlalchemy.orm import relation, mapper, synonym, deferred
|
||||
from sqlalchemy.orm import relation, mapper, synonym, deferred, backref
|
||||
|
||||
from eos.db import gamedata_meta
|
||||
from eos.gamedata import Category, Group, Icon
|
||||
from eos.gamedata import Category, Group
|
||||
|
||||
groups_table = Table("invgroups", gamedata_meta,
|
||||
Column("groupID", Integer, primary_key=True),
|
||||
@@ -29,12 +29,11 @@ groups_table = Table("invgroups", gamedata_meta,
|
||||
Column("description", String),
|
||||
Column("published", Boolean),
|
||||
Column("categoryID", Integer, ForeignKey("invcategories.categoryID")),
|
||||
Column("iconID", Integer, ForeignKey("icons.iconID")))
|
||||
Column("iconID", Integer))
|
||||
|
||||
mapper(Group, groups_table,
|
||||
properties={
|
||||
"category" : relation(Category, backref="groups"),
|
||||
"icon" : relation(Icon),
|
||||
"category" : relation(Category, backref=backref("groups", cascade="all,delete")),
|
||||
"ID" : synonym("groupID"),
|
||||
"name" : synonym("groupName"),
|
||||
"description": deferred(groups_table.c.description)
|
||||
|
||||
@@ -1,35 +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 Column, String, Integer, Table
|
||||
from sqlalchemy.orm import mapper, synonym, deferred
|
||||
|
||||
from eos.db import gamedata_meta
|
||||
from eos.gamedata import Icon
|
||||
|
||||
icons_table = Table("icons", gamedata_meta,
|
||||
Column("iconID", Integer, primary_key=True),
|
||||
Column("description", String),
|
||||
Column("iconFile", String))
|
||||
|
||||
mapper(Icon, icons_table,
|
||||
properties={
|
||||
"ID" : synonym("iconID"),
|
||||
"description": deferred(icons_table.c.description)
|
||||
})
|
||||
@@ -17,14 +17,15 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Column, String, Integer, Boolean, ForeignKey, Table, Float
|
||||
from sqlalchemy import Boolean, Column, Float, ForeignKey, Integer, String, Table
|
||||
from sqlalchemy.ext.associationproxy import association_proxy
|
||||
from sqlalchemy.orm import relation, mapper, synonym, deferred
|
||||
from sqlalchemy.orm import backref, deferred, mapper, relation, synonym
|
||||
from sqlalchemy.orm.collections import attribute_mapped_collection
|
||||
from eos.db.gamedata.effect import typeeffects_table
|
||||
|
||||
from eos.db import gamedata_meta
|
||||
from eos.gamedata import Attribute, Effect, Group, Icon, Item, MetaType, Traits
|
||||
from eos.db.gamedata.dynamicAttributes import dynamicApplicable_table
|
||||
from eos.db.gamedata.effect import typeeffects_table
|
||||
from eos.gamedata import Attribute, DynamicItem, Effect, Group, Item, MetaType, Traits
|
||||
|
||||
items_table = Table("invtypes", gamedata_meta,
|
||||
Column("typeID", Integer, primary_key=True),
|
||||
@@ -37,16 +38,18 @@ items_table = Table("invtypes", gamedata_meta,
|
||||
Column("capacity", Float),
|
||||
Column("published", Boolean),
|
||||
Column("marketGroupID", Integer, ForeignKey("invmarketgroups.marketGroupID")),
|
||||
Column("iconID", Integer, ForeignKey("icons.iconID")),
|
||||
Column("groupID", Integer, ForeignKey("invgroups.groupID"), index=True))
|
||||
Column("iconID", Integer),
|
||||
Column("graphicID", Integer),
|
||||
Column("groupID", Integer, ForeignKey("invgroups.groupID"), index=True),
|
||||
Column("replaceSame", String),
|
||||
Column("replaceBetter", String))
|
||||
|
||||
from .metaGroup import metatypes_table # noqa
|
||||
from .traits import traits_table # noqa
|
||||
|
||||
mapper(Item, items_table,
|
||||
properties={
|
||||
"group" : relation(Group, backref="items"),
|
||||
"icon" : relation(Icon),
|
||||
"group" : relation(Group, backref=backref("items", cascade="all,delete")),
|
||||
"_Item__attributes": relation(Attribute, cascade='all, delete, delete-orphan', collection_class=attribute_mapped_collection('name')),
|
||||
"effects": relation(Effect, secondary=typeeffects_table, collection_class=attribute_mapped_collection('name')),
|
||||
"metaGroup" : relation(MetaType,
|
||||
@@ -57,7 +60,12 @@ mapper(Item, items_table,
|
||||
"description" : deferred(items_table.c.description),
|
||||
"traits" : relation(Traits,
|
||||
primaryjoin=traits_table.c.typeID == items_table.c.typeID,
|
||||
uselist=False)
|
||||
uselist=False),
|
||||
"mutaplasmids": relation(DynamicItem,
|
||||
primaryjoin=dynamicApplicable_table.c.applicableTypeID == items_table.c.typeID,
|
||||
secondaryjoin=dynamicApplicable_table.c.typeID == DynamicItem.typeID,
|
||||
secondary=dynamicApplicable_table,
|
||||
backref="applicableItems")
|
||||
})
|
||||
|
||||
Item.category = association_proxy("group", "category")
|
||||
|
||||
@@ -21,7 +21,7 @@ from sqlalchemy import Column, String, Integer, Boolean, ForeignKey, Table
|
||||
from sqlalchemy.orm import relation, mapper, synonym, deferred
|
||||
|
||||
from eos.db import gamedata_meta
|
||||
from eos.gamedata import Icon, Item, MarketGroup
|
||||
from eos.gamedata import Item, MarketGroup
|
||||
|
||||
marketgroups_table = Table("invmarketgroups", gamedata_meta,
|
||||
Column("marketGroupID", Integer, primary_key=True),
|
||||
@@ -30,14 +30,13 @@ marketgroups_table = Table("invmarketgroups", gamedata_meta,
|
||||
Column("hasTypes", Boolean),
|
||||
Column("parentGroupID", Integer,
|
||||
ForeignKey("invmarketgroups.marketGroupID", initially="DEFERRED", deferrable=True)),
|
||||
Column("iconID", Integer, ForeignKey("icons.iconID")))
|
||||
Column("iconID", Integer))
|
||||
|
||||
mapper(MarketGroup, marketgroups_table,
|
||||
properties={
|
||||
"items" : relation(Item, backref="marketGroup"),
|
||||
"parent" : relation(MarketGroup, backref="children",
|
||||
remote_side=[marketgroups_table.c.marketGroupID]),
|
||||
"icon" : relation(Icon),
|
||||
"ID" : synonym("marketGroupID"),
|
||||
"name" : synonym("marketGroupName"),
|
||||
"description": deferred(marketgroups_table.c.description)
|
||||
|
||||
@@ -17,15 +17,16 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy.orm import join, exc, aliased
|
||||
from sqlalchemy.inspection import inspect
|
||||
from sqlalchemy.orm import aliased, exc, join
|
||||
from sqlalchemy.sql import and_, or_, select
|
||||
|
||||
import eos.config
|
||||
from eos.db import gamedata_session
|
||||
from eos.db.gamedata.metaGroup import metatypes_table, items_table
|
||||
from eos.db.gamedata.group import groups_table
|
||||
from eos.db.gamedata.metaGroup import items_table, metatypes_table
|
||||
from eos.db.util import processEager, processWhere
|
||||
from eos.gamedata import AlphaClone, Attribute, Category, Group, Item, MarketGroup, MetaGroup, AttributeInfo, MetaData
|
||||
from eos.gamedata import AlphaClone, Attribute, AttributeInfo, Category, DynamicItem, Group, Item, MarketGroup, MetaData, MetaGroup
|
||||
|
||||
cache = {}
|
||||
configVal = getattr(eos.config, "gamedataCache", None)
|
||||
@@ -97,6 +98,36 @@ def getItem(lookfor, eager=None):
|
||||
return item
|
||||
|
||||
|
||||
def getMutaplasmid(lookfor, eager=None):
|
||||
if isinstance(lookfor, int):
|
||||
item = gamedata_session.query(DynamicItem).filter(DynamicItem.ID == lookfor).first()
|
||||
else:
|
||||
raise TypeError("Need integer as argument")
|
||||
return item
|
||||
|
||||
|
||||
def getItemWithBaseItemAttribute(lookfor, baseItemID, eager=None):
|
||||
# A lot of this is described in more detail in #1597
|
||||
item = gamedata_session.query(Item).get(lookfor)
|
||||
base = getItem(baseItemID)
|
||||
|
||||
# we have to load all attributes for this object, otherwise we'll lose access to them when we expunge.
|
||||
# todo: figure out a way to eagerly load all these via the query...
|
||||
for x in [*inspect(Item).relationships.keys(), 'description']:
|
||||
getattr(item, x)
|
||||
|
||||
# Copy over the attributes from the base, but ise the items attributes when there's an overlap
|
||||
# WARNING: the attribute object still has the old typeID. I don't believe we access this typeID anywhere in the code,
|
||||
# but should keep this in mind for now.
|
||||
item._Item__attributes = {**base.attributes, **item.attributes}
|
||||
|
||||
# Expunge the item form the session. This is required to have different Abyssal / Base combinations loaded in memory.
|
||||
# Without expunging it, once one Abyssal Web is created, SQLAlchmey will use it for all others. We don't want this,
|
||||
# we want to generate a completely new object to work with
|
||||
gamedata_session.expunge(item)
|
||||
return item
|
||||
|
||||
|
||||
@cachedQuery(1, "lookfor")
|
||||
def getItems(lookfor, eager=None):
|
||||
"""
|
||||
@@ -361,6 +392,25 @@ def directAttributeRequest(itemIDs, attrIDs):
|
||||
return result
|
||||
|
||||
|
||||
def getAbyssalTypes():
|
||||
return set([r.resultingTypeID for r in gamedata_session.query(DynamicItem.resultingTypeID).distinct()])
|
||||
|
||||
|
||||
@cachedQuery(1, "itemID")
|
||||
def getDynamicItem(itemID, eager=None):
|
||||
try:
|
||||
if isinstance(itemID, int):
|
||||
if eager is None:
|
||||
result = gamedata_session.query(DynamicItem).filter(DynamicItem.ID == itemID).one()
|
||||
else:
|
||||
result = gamedata_session.query(DynamicItem).options(*processEager(eager)).filter(DynamicItem.ID == itemID).one()
|
||||
else:
|
||||
raise TypeError("Need integer as argument")
|
||||
except exc.NoResultFound:
|
||||
result = None
|
||||
return result
|
||||
|
||||
|
||||
def getRequiredFor(itemID, attrMapping):
|
||||
Attribute1 = aliased(Attribute)
|
||||
Attribute2 = aliased(Attribute)
|
||||
|
||||
@@ -14,7 +14,7 @@ def upgrade(saveddata_engine):
|
||||
"boosters": 2,
|
||||
"cargo": 2,
|
||||
"characters": 2,
|
||||
"crest": 1,
|
||||
# "crest": 1,
|
||||
"damagePatterns": 2,
|
||||
"drones": 2,
|
||||
"fighters": 2,
|
||||
|
||||
18
eos/db/migrations/upgrade28.py
Normal file
18
eos/db/migrations/upgrade28.py
Normal file
@@ -0,0 +1,18 @@
|
||||
"""
|
||||
Migration 28
|
||||
|
||||
- adds baseItemID and mutaplasmidID to modules table
|
||||
"""
|
||||
import sqlalchemy
|
||||
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
try:
|
||||
saveddata_engine.execute("SELECT baseItemID FROM modules LIMIT 1")
|
||||
except sqlalchemy.exc.DatabaseError:
|
||||
saveddata_engine.execute("ALTER TABLE modules ADD COLUMN baseItemID INT;")
|
||||
|
||||
try:
|
||||
saveddata_engine.execute("SELECT mutaplasmidID FROM modules LIMIT 1")
|
||||
except sqlalchemy.exc.DatabaseError:
|
||||
saveddata_engine.execute("ALTER TABLE modules ADD COLUMN mutaplasmidID INT;")
|
||||
18
eos/db/migrations/upgrade29.py
Normal file
18
eos/db/migrations/upgrade29.py
Normal file
@@ -0,0 +1,18 @@
|
||||
"""
|
||||
Migration 29
|
||||
|
||||
- adds spoolType and spoolAmount to modules table
|
||||
"""
|
||||
import sqlalchemy
|
||||
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
try:
|
||||
saveddata_engine.execute("SELECT spoolType FROM modules LIMIT 1")
|
||||
except sqlalchemy.exc.DatabaseError:
|
||||
saveddata_engine.execute("ALTER TABLE modules ADD COLUMN spoolType INT;")
|
||||
|
||||
try:
|
||||
saveddata_engine.execute("SELECT spoolAmount FROM modules LIMIT 1")
|
||||
except sqlalchemy.exc.DatabaseError:
|
||||
saveddata_engine.execute("ALTER TABLE modules ADD COLUMN spoolAmount FLOAT;")
|
||||
17
eos/db/migrations/upgrade30.py
Normal file
17
eos/db/migrations/upgrade30.py
Normal file
@@ -0,0 +1,17 @@
|
||||
"""
|
||||
Migration 30
|
||||
|
||||
- changes to prices table
|
||||
"""
|
||||
|
||||
|
||||
import sqlalchemy
|
||||
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
try:
|
||||
saveddata_engine.execute("SELECT status FROM prices LIMIT 1")
|
||||
except sqlalchemy.exc.DatabaseError:
|
||||
# Just drop table, table will be re-created by sqlalchemy and
|
||||
# data will be re-fetched
|
||||
saveddata_engine.execute("DROP TABLE prices;")
|
||||
@@ -1,6 +1,7 @@
|
||||
__all__ = [
|
||||
"character",
|
||||
"fit",
|
||||
"mutator",
|
||||
"module",
|
||||
"user",
|
||||
"skill",
|
||||
|
||||
@@ -29,9 +29,6 @@ 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),
|
||||
|
||||
@@ -17,33 +17,32 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy.ext.associationproxy import association_proxy
|
||||
from sqlalchemy.orm.collections import attribute_mapped_collection
|
||||
from sqlalchemy.sql import and_
|
||||
from sqlalchemy.orm import relation, reconstructor, mapper, relationship
|
||||
from sqlalchemy import ForeignKey, Column, Integer, String, Table, Boolean, DateTime
|
||||
import datetime
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.db import saveddata_session
|
||||
from sqlalchemy import Boolean, Column, DateTime, ForeignKey, Integer, String, Table
|
||||
from sqlalchemy.ext.associationproxy import association_proxy
|
||||
from sqlalchemy.orm import mapper, reconstructor, relation, relationship
|
||||
from sqlalchemy.orm.collections import attribute_mapped_collection
|
||||
from sqlalchemy.sql import and_
|
||||
|
||||
from eos.db import saveddata_meta, saveddata_session
|
||||
from eos.db.saveddata.cargo import cargo_table
|
||||
from eos.db.saveddata.drone import drones_table
|
||||
from eos.db.saveddata.fighter import fighters_table
|
||||
from eos.db.saveddata.implant import fitImplants_table
|
||||
from eos.db.saveddata.module import modules_table
|
||||
from eos.effectHandlerHelpers import HandledModuleList, HandledImplantBoosterList, HandledProjectedModList, \
|
||||
HandledDroneCargoList, HandledProjectedDroneList
|
||||
from eos.saveddata.implant import Implant
|
||||
from eos.saveddata.character import Character
|
||||
from eos.saveddata.user import User
|
||||
from eos.saveddata.fighter import Fighter
|
||||
from eos.saveddata.fit import Fit as es_Fit, ImplantLocation
|
||||
from eos.saveddata.drone import Drone
|
||||
from eos.effectHandlerHelpers import HandledDroneCargoList, HandledImplantBoosterList, HandledModuleList, HandledProjectedDroneList, HandledProjectedModList
|
||||
from eos.saveddata.booster import Booster
|
||||
from eos.saveddata.module import Module
|
||||
from eos.saveddata.cargo import Cargo
|
||||
from eos.saveddata.character import Character
|
||||
from eos.saveddata.damagePattern import DamagePattern
|
||||
from eos.saveddata.drone import Drone
|
||||
from eos.saveddata.fighter import Fighter
|
||||
from eos.saveddata.fit import Fit as es_Fit
|
||||
from eos.saveddata.implant import Implant
|
||||
from eos.saveddata.module import Module
|
||||
from eos.saveddata.targetResists import TargetResists
|
||||
from eos.saveddata.user import User
|
||||
|
||||
fits_table = Table("fits", saveddata_meta,
|
||||
Column("ID", Integer, primary_key=True),
|
||||
@@ -56,7 +55,7 @@ fits_table = Table("fits", saveddata_meta,
|
||||
Column("booster", Boolean, nullable=False, index=True, default=0),
|
||||
Column("targetResistsID", ForeignKey("targetResists.ID"), nullable=True),
|
||||
Column("modeID", Integer, nullable=True),
|
||||
Column("implantLocation", Integer, nullable=False, default=ImplantLocation.FIT),
|
||||
Column("implantLocation", Integer, nullable=False),
|
||||
Column("notes", String, nullable=True),
|
||||
Column("ignoreRestrictions", Boolean, default=0),
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||
@@ -132,13 +131,13 @@ class CommandFit(object):
|
||||
)
|
||||
|
||||
|
||||
es_Fit._Fit__projectedFits = association_proxy(
|
||||
es_Fit.projectedFitDict = association_proxy(
|
||||
"victimOf", # look at the victimOf association...
|
||||
"source_fit", # .. and return the source fits
|
||||
creator=lambda sourceID, source_fit: ProjectedFit(sourceID, source_fit)
|
||||
)
|
||||
|
||||
es_Fit._Fit__commandFits = association_proxy(
|
||||
es_Fit.commandFitDict = association_proxy(
|
||||
"boostedOf", # look at the boostedOf association...
|
||||
"booster_fit", # .. and return the booster fit
|
||||
creator=lambda boosterID, booster_fit: CommandFit(boosterID, booster_fit)
|
||||
|
||||
@@ -17,18 +17,22 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey, CheckConstraint, Boolean, DateTime
|
||||
from sqlalchemy import Table, Column, Integer, Float, ForeignKey, CheckConstraint, Boolean, DateTime
|
||||
from sqlalchemy.orm.collections import attribute_mapped_collection
|
||||
from sqlalchemy.orm import relation, mapper
|
||||
import datetime
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.saveddata.module import Module
|
||||
from eos.saveddata.mutator import Mutator
|
||||
from eos.saveddata.fit import Fit
|
||||
|
||||
modules_table = Table("modules", saveddata_meta,
|
||||
Column("ID", Integer, primary_key=True),
|
||||
Column("fitID", Integer, ForeignKey("fits.ID"), nullable=False, index=True),
|
||||
Column("itemID", Integer, nullable=True),
|
||||
Column("baseItemID", Integer, nullable=True),
|
||||
Column("mutaplasmidID", Integer, nullable=True),
|
||||
Column("dummySlot", Integer, nullable=True, default=None),
|
||||
Column("chargeID", Integer),
|
||||
Column("state", Integer, CheckConstraint("state >= -1"), CheckConstraint("state <= 2")),
|
||||
@@ -36,7 +40,17 @@ modules_table = Table("modules", saveddata_meta,
|
||||
Column("position", Integer),
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now),
|
||||
Column("spoolType", Integer, nullable=True),
|
||||
Column("spoolAmount", Float, nullable=True),
|
||||
CheckConstraint('("dummySlot" = NULL OR "itemID" = NULL) AND "dummySlot" != "itemID"'))
|
||||
|
||||
mapper(Module, modules_table,
|
||||
properties={"owner": relation(Fit)})
|
||||
properties={
|
||||
"owner": relation(Fit),
|
||||
"mutators": relation(
|
||||
Mutator,
|
||||
backref="module",
|
||||
cascade="all,delete-orphan",
|
||||
collection_class=attribute_mapped_collection('attrID')
|
||||
)
|
||||
})
|
||||
|
||||
35
eos/db/saveddata/mutator.py
Normal file
35
eos/db/saveddata/mutator.py
Normal file
@@ -0,0 +1,35 @@
|
||||
# ===============================================================================
|
||||
# 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/>.
|
||||
# ===============================================================================
|
||||
|
||||
import datetime
|
||||
|
||||
from sqlalchemy import Column, DateTime, Float, ForeignKey, Integer, Table
|
||||
from sqlalchemy.orm import mapper
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.saveddata.mutator import Mutator
|
||||
|
||||
mutator_table = Table("mutators", saveddata_meta,
|
||||
Column("moduleID", Integer, ForeignKey("modules.ID"), primary_key=True, index=True),
|
||||
Column("attrID", Integer, primary_key=True, index=True),
|
||||
Column("value", Float, nullable=False),
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now))
|
||||
|
||||
mapper(Mutator, mutator_table)
|
||||
@@ -17,17 +17,20 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
|
||||
from sqlalchemy import Table, Column, Float, Integer
|
||||
from sqlalchemy.orm import mapper
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.saveddata.price import Price
|
||||
|
||||
|
||||
prices_table = Table("prices", saveddata_meta,
|
||||
Column("typeID", Integer, primary_key=True),
|
||||
Column("price", Float, default=0.0),
|
||||
Column("time", Integer, nullable=False),
|
||||
Column("failed", Integer))
|
||||
Column("status", Integer, nullable=False))
|
||||
|
||||
|
||||
mapper(Price, prices_table, properties={
|
||||
"_Price__price": prices_table.c.price,
|
||||
|
||||
@@ -542,8 +542,17 @@ def commit():
|
||||
with sd_lock:
|
||||
try:
|
||||
saveddata_session.commit()
|
||||
saveddata_session.flush()
|
||||
except Exception as ex:
|
||||
except Exception:
|
||||
saveddata_session.rollback()
|
||||
exc_info = sys.exc_info()
|
||||
raise exc_info[0](exc_info[1]).with_traceback(exc_info[2])
|
||||
|
||||
|
||||
def flush():
|
||||
with sd_lock:
|
||||
try:
|
||||
saveddata_session.flush()
|
||||
except Exception:
|
||||
saveddata_session.rollback()
|
||||
exc_info = sys.exc_info()
|
||||
raise exc_info[0](exc_info[1]).with_traceback(exc_info[2])
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
# ===============================================================================
|
||||
|
||||
from logbook import Logger
|
||||
from utils.deprecated import deprecated
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
@@ -113,6 +114,7 @@ class HandledList(list):
|
||||
|
||||
|
||||
class HandledModuleList(HandledList):
|
||||
|
||||
def append(self, mod):
|
||||
emptyPosition = float("Inf")
|
||||
for i in range(len(self)):
|
||||
@@ -130,12 +132,32 @@ class HandledModuleList(HandledList):
|
||||
self.remove(mod)
|
||||
return
|
||||
|
||||
self.appendIgnoreEmpty(mod)
|
||||
|
||||
def appendIgnoreEmpty(self, mod):
|
||||
mod.position = len(self)
|
||||
HandledList.append(self, mod)
|
||||
if mod.isInvalid:
|
||||
self.remove(mod)
|
||||
return
|
||||
|
||||
def replaceRackPosition(self, rackPosition, mod):
|
||||
listPositions = []
|
||||
for currMod in self:
|
||||
if currMod.slot == mod.slot:
|
||||
listPositions.append(currMod.position)
|
||||
listPositions.sort()
|
||||
try:
|
||||
modListPosition = listPositions[rackPosition]
|
||||
except IndexError:
|
||||
self.appendIgnoreEmpty(mod)
|
||||
else:
|
||||
self.toDummy(modListPosition)
|
||||
if not mod.isEmpty:
|
||||
self.toModule(modListPosition, mod)
|
||||
if mod.isInvalid:
|
||||
self.toDummy(modListPosition)
|
||||
|
||||
def insert(self, index, mod):
|
||||
mod.position = index
|
||||
i = index
|
||||
@@ -163,6 +185,7 @@ class HandledModuleList(HandledList):
|
||||
mod.position = index
|
||||
self[index] = mod
|
||||
|
||||
@deprecated
|
||||
def freeSlot(self, slot):
|
||||
for i in range(len(self)):
|
||||
mod = self[i]
|
||||
@@ -195,14 +218,20 @@ class HandledImplantBoosterList(HandledList):
|
||||
self.remove(thing)
|
||||
return
|
||||
|
||||
self.makeRoom(thing)
|
||||
HandledList.append(self, thing)
|
||||
|
||||
def makeRoom(self, thing):
|
||||
# if needed, remove booster that was occupying slot
|
||||
oldObj = next((m for m in self if m.slot == thing.slot), None)
|
||||
if oldObj:
|
||||
pyfalog.info("Slot {0} occupied with {1}, replacing with {2}", thing.slot, oldObj.item.name, thing.item.name)
|
||||
pyfalog.info("Slot {0} occupied with {1}, replacing with {2}", thing.slot, oldObj.item.name,
|
||||
thing.item.name)
|
||||
itemID = oldObj.itemID
|
||||
oldObj.itemID = 0 # hack to remove from DB. See GH issue #324
|
||||
self.remove(oldObj)
|
||||
|
||||
HandledList.append(self, thing)
|
||||
return itemID
|
||||
return None
|
||||
|
||||
|
||||
class HandledSsoCharacterList(list):
|
||||
@@ -225,22 +254,30 @@ class HandledProjectedModList(HandledList):
|
||||
return
|
||||
|
||||
proj.projected = True
|
||||
isSystemEffect = proj.item.group.name == "Effect Beacon"
|
||||
|
||||
if isSystemEffect:
|
||||
# remove other system effects - only 1 per fit plz
|
||||
oldEffect = next((m for m in self if m.item.group.name == "Effect Beacon"), None)
|
||||
|
||||
if oldEffect:
|
||||
pyfalog.info("System effect occupied with {0}, replacing with {1}", oldEffect.item.name, proj.item.name)
|
||||
self.remove(oldEffect)
|
||||
if proj.isExclusiveSystemEffect:
|
||||
self.makeRoom(proj)
|
||||
|
||||
HandledList.append(self, proj)
|
||||
|
||||
# Remove non-projectable modules
|
||||
if not proj.item.isType("projected") and not isSystemEffect:
|
||||
if not proj.item.isType("projected") and not proj.isExclusiveSystemEffect:
|
||||
self.remove(proj)
|
||||
|
||||
@property
|
||||
def currentSystemEffect(self):
|
||||
return next((m for m in self if m.isExclusiveSystemEffect), None)
|
||||
|
||||
def makeRoom(self, proj):
|
||||
# remove other system effects - only 1 per fit plz
|
||||
oldEffect = self.currentSystemEffect
|
||||
|
||||
if oldEffect:
|
||||
pyfalog.info("System effect occupied with {0}, replacing with {1}", oldEffect.item.name, proj.item.name)
|
||||
self.remove(oldEffect)
|
||||
return oldEffect.itemID
|
||||
return None
|
||||
|
||||
|
||||
class HandledProjectedDroneList(HandledDroneCargoList):
|
||||
def append(self, proj):
|
||||
|
||||
@@ -13,11 +13,14 @@ type = "active"
|
||||
|
||||
def handler(fit, module, context):
|
||||
damagePattern = fit.damagePattern
|
||||
# pyfalog.debug("==============================")
|
||||
|
||||
static_adaptive_behavior = eos.config.settings['useStaticAdaptiveArmorHardener']
|
||||
|
||||
if (damagePattern.emAmount == damagePattern.thermalAmount == damagePattern.kineticAmount == damagePattern.explosiveAmount) and static_adaptive_behavior:
|
||||
pyfalog.debug("Setting adaptivearmorhardener resists to uniform profile.")
|
||||
# pyfalog.debug("Setting adaptivearmorhardener resists to uniform profile.")
|
||||
for attr in ("armorEmDamageResonance", "armorThermalDamageResonance", "armorKineticDamageResonance", "armorExplosiveDamageResonance"):
|
||||
fit.ship.multiplyItemAttr(attr, module.getModifiedItemAttr(attr), stackingPenalties=True, penaltyGroup="preMul")
|
||||
return
|
||||
|
||||
# Skip if there is no damage pattern. Example: projected ships or fleet boosters
|
||||
@@ -30,7 +33,7 @@ def handler(fit, module, context):
|
||||
damagePattern.kineticAmount * fit.ship.getModifiedItemAttr('armorKineticDamageResonance'),
|
||||
damagePattern.explosiveAmount * fit.ship.getModifiedItemAttr('armorExplosiveDamageResonance'),
|
||||
)
|
||||
# pyfalog.debug("Damage Adjusted for Armor Resists: %f/%f/%f/%f", baseDamageTaken[0], baseDamageTaken[1], baseDamageTaken[2], baseDamageTaken[3])
|
||||
# pyfalog.debug("Damage Adjusted for Armor Resists: %f/%f/%f/%f" % (baseDamageTaken[0], baseDamageTaken[1], baseDamageTaken[2], baseDamageTaken[3]))
|
||||
|
||||
resistanceShiftAmount = module.getModifiedItemAttr(
|
||||
'resistanceShiftAmount') / 100 # The attribute is in percent and we want a fraction
|
||||
@@ -46,7 +49,7 @@ def handler(fit, module, context):
|
||||
cycleList = []
|
||||
loopStart = -20
|
||||
for num in range(50):
|
||||
# pyfalog.debug("Starting cycle %d.", num)
|
||||
# pyfalog.debug("Starting cycle %d." % num)
|
||||
# The strange order is to emulate the ingame sorting when different types have taken the same amount of damage.
|
||||
# This doesn't take into account stacking penalties. In a few cases fitting a Damage Control causes an inaccurate result.
|
||||
damagePattern_tuples = [
|
||||
@@ -84,7 +87,7 @@ def handler(fit, module, context):
|
||||
RAHResistance[sortedDamagePattern_tuples[1][0]] = sortedDamagePattern_tuples[1][2] + change1
|
||||
RAHResistance[sortedDamagePattern_tuples[2][0]] = sortedDamagePattern_tuples[2][2] + change2
|
||||
RAHResistance[sortedDamagePattern_tuples[3][0]] = sortedDamagePattern_tuples[3][2] + change3
|
||||
# pyfalog.debug("Resistances shifted to %f/%f/%f/%f", RAHResistance[0], RAHResistance[1], RAHResistance[2], RAHResistance[3])
|
||||
# pyfalog.debug("Resistances shifted to %f/%f/%f/%f" % ( RAHResistance[0], RAHResistance[1], RAHResistance[2], RAHResistance[3]))
|
||||
|
||||
# See if the current RAH profile has been encountered before, indicating a loop.
|
||||
for i, val in enumerate(cycleList):
|
||||
@@ -94,16 +97,16 @@ def handler(fit, module, context):
|
||||
abs(RAHResistance[2] - val[2]) <= tolerance and \
|
||||
abs(RAHResistance[3] - val[3]) <= tolerance:
|
||||
loopStart = i
|
||||
# pyfalog.debug("Loop found: %d-%d", loopStart, num)
|
||||
# pyfalog.debug("Loop found: %d-%d" % (loopStart, num))
|
||||
break
|
||||
if loopStart >= 0:
|
||||
break
|
||||
|
||||
cycleList.append(list(RAHResistance))
|
||||
|
||||
if loopStart < 0:
|
||||
pyfalog.error("Reactive Armor Hardener failed to find equilibrium. Damage profile after armor: {0}/{1}/{2}/{3}",
|
||||
baseDamageTaken[0], baseDamageTaken[1], baseDamageTaken[2], baseDamageTaken[3])
|
||||
# if loopStart < 0:
|
||||
# pyfalog.error("Reactive Armor Hardener failed to find equilibrium. Damage profile after armor: {0}/{1}/{2}/{3}".format(
|
||||
# baseDamageTaken[0], baseDamageTaken[1], baseDamageTaken[2], baseDamageTaken[3]))
|
||||
|
||||
# Average the profiles in the RAH loop, or the last 20 if it didn't find a loop.
|
||||
loopCycles = cycleList[loopStart:]
|
||||
@@ -117,7 +120,7 @@ def handler(fit, module, context):
|
||||
average[i] = round(average[i] / numCycles, 3)
|
||||
|
||||
# Set the new resistances
|
||||
# pyfalog.debug("Setting new resist profile: %f/%f/%f/%f", average[0], average[1], average[2],average[3])
|
||||
# pyfalog.debug("Setting new resist profile: %f/%f/%f/%f" % ( average[0], average[1], average[2],average[3]))
|
||||
for i, attr in enumerate((
|
||||
'armorEmDamageResonance', 'armorThermalDamageResonance', 'armorKineticDamageResonance',
|
||||
'armorExplosiveDamageResonance')):
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Missile Launcher Bomb (2 of 2)
|
||||
# Modules from group: Shield Extender (33 of 33)
|
||||
# Modules from group: Shield Extender (36 of 36)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -6,4 +6,4 @@ type = "passive"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
fit.ship.boostItemAttr("agility", module.getModifiedItemAttr("agilityMultiplier"), stackingPenalties=True)
|
||||
fit.ship.boostItemAttr("agility", module.getModifiedItemAttr("agilityBonus"), stackingPenalties=True)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# ammoInfluenceCapNeed
|
||||
#
|
||||
# Used by:
|
||||
# Items from category: Charge (478 of 928)
|
||||
# Items from category: Charge (493 of 949)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# ammoInfluenceRange
|
||||
#
|
||||
# Used by:
|
||||
# Items from category: Charge (572 of 928)
|
||||
# Items from category: Charge (587 of 949)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# ammoSpeedMultiplier
|
||||
#
|
||||
# Used by:
|
||||
# Charges from group: Festival Charges (23 of 23)
|
||||
# Charges from group: Festival Charges (26 of 26)
|
||||
# Charges from group: Interdiction Probe (2 of 2)
|
||||
# Charges from group: Structure Festival Charges (3 of 3)
|
||||
# Items from market group: Special Edition Assets > Special Edition Festival Assets (30 of 33)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
# ammoTrackingMultiplier
|
||||
#
|
||||
# Used by:
|
||||
# Charges from group: Advanced Artillery Ammo (8 of 8)
|
||||
# Charges from group: Advanced Autocannon Ammo (8 of 8)
|
||||
# Charges from group: Advanced Beam Laser Crystal (8 of 8)
|
||||
# Charges from group: Advanced Blaster Charge (8 of 8)
|
||||
# Charges from group: Advanced Pulse Laser Crystal (8 of 8)
|
||||
# Charges from group: Advanced Railgun Charge (8 of 8)
|
||||
# Items from category: Charge (182 of 949)
|
||||
# Charges from group: Projectile Ammo (128 of 128)
|
||||
type = "passive"
|
||||
|
||||
|
||||
16
eos/effects/aoebeaconbioluminescencecloud.py
Normal file
16
eos/effects/aoebeaconbioluminescencecloud.py
Normal file
@@ -0,0 +1,16 @@
|
||||
# aoe_beacon_bioluminescence_cloud
|
||||
#
|
||||
# Used by:
|
||||
# Celestials named like: Bioluminescence Cloud (3 of 3)
|
||||
runTime = "early"
|
||||
type = ("projected", "passive", "gang")
|
||||
|
||||
|
||||
def handler(fit, beacon, context, **kwargs):
|
||||
for x in range(1, 3):
|
||||
if beacon.getModifiedItemAttr("warfareBuff{}ID".format(x)):
|
||||
value = beacon.getModifiedItemAttr("warfareBuff{}Value".format(x))
|
||||
id = beacon.getModifiedItemAttr("warfareBuff{}ID".format(x))
|
||||
|
||||
if id:
|
||||
fit.addCommandBonus(id, value, beacon, kwargs['effect'], 'early')
|
||||
16
eos/effects/aoebeaconcausticcloud.py
Normal file
16
eos/effects/aoebeaconcausticcloud.py
Normal file
@@ -0,0 +1,16 @@
|
||||
# aoe_beacon_caustic_cloud
|
||||
#
|
||||
# Used by:
|
||||
# Celestials named like: Caustic Cloud (3 of 3)
|
||||
runTime = "early"
|
||||
type = ("projected", "passive", "gang")
|
||||
|
||||
|
||||
def handler(fit, beacon, context, **kwargs):
|
||||
for x in range(1, 3):
|
||||
if beacon.getModifiedItemAttr("warfareBuff{}ID".format(x)):
|
||||
value = beacon.getModifiedItemAttr("warfareBuff{}Value".format(x))
|
||||
id = beacon.getModifiedItemAttr("warfareBuff{}ID".format(x))
|
||||
|
||||
if id:
|
||||
fit.addCommandBonus(id, value, beacon, kwargs['effect'], 'early')
|
||||
16
eos/effects/aoebeaconfilamentcloud.py
Normal file
16
eos/effects/aoebeaconfilamentcloud.py
Normal file
@@ -0,0 +1,16 @@
|
||||
# aoe_beacon_filament_cloud
|
||||
#
|
||||
# Used by:
|
||||
# Celestials named like: Filament Cloud (3 of 3)
|
||||
runTime = "early"
|
||||
type = ("projected", "passive", "gang")
|
||||
|
||||
|
||||
def handler(fit, beacon, context, **kwargs):
|
||||
for x in range(1, 3):
|
||||
if beacon.getModifiedItemAttr("warfareBuff{}ID".format(x)):
|
||||
value = beacon.getModifiedItemAttr("warfareBuff{}Value".format(x))
|
||||
id = beacon.getModifiedItemAttr("warfareBuff{}ID".format(x))
|
||||
|
||||
if id:
|
||||
fit.addCommandBonus(id, value, beacon, kwargs['effect'], 'early')
|
||||
@@ -1,6 +1,7 @@
|
||||
# armorAllRepairSystemsAmountBonusPassive
|
||||
#
|
||||
# Used by:
|
||||
# Implants named like: Agency 'Hardshell' TB Dose (4 of 4)
|
||||
# Implants named like: Exile Booster (4 of 4)
|
||||
# Implant: Antipharmakon Kosybo
|
||||
type = "passive"
|
||||
@@ -9,4 +10,4 @@ type = "passive"
|
||||
def handler(fit, booster, context):
|
||||
fit.modules.filteredItemBoost(
|
||||
lambda mod: mod.item.requiresSkill("Repair Systems") or mod.item.requiresSkill("Capital Repair Systems"),
|
||||
"armorDamageAmount", booster.getModifiedItemAttr("armorDamageAmountBonus"))
|
||||
"armorDamageAmount", booster.getModifiedItemAttr("armorDamageAmountBonus") or 0)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# armorHPBonusAdd
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Armor Reinforcer (48 of 48)
|
||||
# Modules from group: Armor Reinforcer (51 of 51)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# armorReinforcerMassAdd
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Armor Reinforcer (48 of 48)
|
||||
# Modules from group: Armor Reinforcer (51 of 51)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# armorRepair
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Armor Repair Unit (105 of 105)
|
||||
# Modules from group: Armor Repair Unit (108 of 108)
|
||||
runTime = "late"
|
||||
type = "active"
|
||||
|
||||
@@ -9,4 +9,7 @@ type = "active"
|
||||
def handler(fit, module, context):
|
||||
amount = module.getModifiedItemAttr("armorDamageAmount")
|
||||
speed = module.getModifiedItemAttr("duration") / 1000.0
|
||||
fit.extraAttributes.increase("armorRepair", amount / speed)
|
||||
rps = amount / speed
|
||||
fit.extraAttributes.increase("armorRepair", rps)
|
||||
fit.extraAttributes.increase("armorRepairPreSpool", rps)
|
||||
fit.extraAttributes.increase("armorRepairFullSpool", rps)
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
# Not used by any item
|
||||
type = "gang", "active"
|
||||
gangBonus = "armorHpBonus2"
|
||||
gangBoost = "armorHP"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
if "gang" not in context:
|
||||
return
|
||||
fit.ship.boostItemAttr("armorHP", module.getModifiedItemAttr("armorHpBonus2"))
|
||||
@@ -1,7 +1,7 @@
|
||||
# boosterArmorHpPenalty
|
||||
#
|
||||
# Used by:
|
||||
# Implants from group: Booster (12 of 62)
|
||||
# Implants named like: Booster (12 of 35)
|
||||
type = "boosterSideEffect"
|
||||
|
||||
# User-friendly name for the side effect
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# boosterMaxVelocityPenalty
|
||||
#
|
||||
# Used by:
|
||||
# Implants from group: Booster (12 of 62)
|
||||
# Implants named like: Crash Booster (3 of 4)
|
||||
# Items from market group: Implants & Boosters > Booster > Booster Slot 02 (9 of 13)
|
||||
type = "boosterSideEffect"
|
||||
|
||||
# User-friendly name for the side effect
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
# Implants named like: Eifyr and Co. 'Alchemist' Neurotoxin Control NC (2 of 2)
|
||||
# Implants named like: grade Edge (10 of 12)
|
||||
# Skill: Neurotoxin Control
|
||||
runTime = 'early'
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# boosterShieldCapacityPenalty
|
||||
#
|
||||
# Used by:
|
||||
# Implants from group: Booster (12 of 62)
|
||||
# Implants from group: Booster (12 of 70)
|
||||
type = "boosterSideEffect"
|
||||
|
||||
# User-friendly name for the side effect
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# capacitorCapacityBonus
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Capacitor Battery (27 of 27)
|
||||
# Modules from group: Capacitor Battery (30 of 30)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# Modules from group: Capacitor Flux Coil (6 of 6)
|
||||
# Modules from group: Capacitor Power Relay (20 of 20)
|
||||
# Modules from group: Power Diagnostic System (23 of 23)
|
||||
# Modules from group: Propulsion Module (65 of 127)
|
||||
# Modules from group: Propulsion Module (68 of 133)
|
||||
# Modules from group: Reactor Control Unit (22 of 22)
|
||||
type = "passive"
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
# Not used by any item
|
||||
# citadelRigBonus
|
||||
#
|
||||
# Used by:
|
||||
# Structures from group: Citadel (9 of 9)
|
||||
type = "passive"
|
||||
runTime = "early"
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Carrier (4 of 4)
|
||||
# Ships from group: Combat Battlecruiser (13 of 13)
|
||||
# Ships from group: Combat Battlecruiser (14 of 14)
|
||||
# Ships from group: Command Ship (8 of 8)
|
||||
# Ships from group: Force Auxiliary (6 of 6)
|
||||
# Ships from group: Supercarrier (6 of 6)
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
# Used by:
|
||||
# Ships from group: Black Ops (5 of 5)
|
||||
# Ships from group: Blockade Runner (4 of 4)
|
||||
# Ships from group: Covert Ops (7 of 7)
|
||||
# Ships from group: Covert Ops (8 of 8)
|
||||
# Ships from group: Expedition Frigate (2 of 2)
|
||||
# Ships from group: Force Recon Ship (8 of 8)
|
||||
# Ships from group: Force Recon Ship (9 of 9)
|
||||
# Ships from group: Stealth Bomber (5 of 5)
|
||||
# Ships named like: Stratios (2 of 2)
|
||||
# Subsystems named like: Defensive Covert Reconfiguration (4 of 4)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# covertOpsCloakCpuPercentBonus1
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Covert Ops (5 of 7)
|
||||
# Ships from group: Covert Ops (6 of 8)
|
||||
type = "passive"
|
||||
runTime = "early"
|
||||
|
||||
|
||||
9
eos/effects/covertopswarpresistance.py
Normal file
9
eos/effects/covertopswarpresistance.py
Normal file
@@ -0,0 +1,9 @@
|
||||
# covertOpsWarpResistance
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Covert Ops (5 of 8)
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.ship.increaseItemAttr("warpFactor", src.getModifiedItemAttr("eliteBonusCovertOps1"), skill="Covert Ops")
|
||||
@@ -2,6 +2,7 @@
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: CPU Enhancer (19 of 19)
|
||||
# Variations of structure module: Standup Co-Processor Array I (2 of 2)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Modules from group: Frequency Mining Laser (3 of 3)
|
||||
type = "passive"
|
||||
|
||||
runTime = "late"
|
||||
|
||||
def handler(fit, module, context):
|
||||
module.preAssignItemAttr("specialtyMiningAmount", module.getModifiedItemAttr("miningAmount"))
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# cynosuralDurationBonus
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Force Recon Ship (7 of 8)
|
||||
# Ships from group: Force Recon Ship (8 of 9)
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Cynosural Field",
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Cynosural Field Generator",
|
||||
"duration", ship.getModifiedItemAttr("durationBonus"))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# cynosuralGeneration
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Cynosural Field (2 of 2)
|
||||
# Modules from group: Cynosural Field Generator (2 of 2)
|
||||
type = "active"
|
||||
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
# cynosuralTheoryConsumptionBonus
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Force Recon Ship (7 of 8)
|
||||
# Ships from group: Force Recon Ship (8 of 9)
|
||||
# Skill: Cynosural Field Theory
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, container, context):
|
||||
level = container.level if "skill" in context else 1
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Cynosural Field",
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Cynosural Field Generator",
|
||||
"consumptionQuantity",
|
||||
container.getModifiedItemAttr("consumptionQuantityBonusPercentage") * level)
|
||||
|
||||
@@ -11,6 +11,5 @@ def handler(fit, module, context):
|
||||
bonus = "%s%sDamageResonance" % (attrPrefix, damageType)
|
||||
bonus = "%s%s" % (bonus[0].lower(), bonus[1:])
|
||||
booster = "%s%sDamageResonance" % (layer, damageType)
|
||||
penalize = False if layer == 'hull' else True
|
||||
fit.ship.multiplyItemAttr(bonus, module.getModifiedItemAttr(booster),
|
||||
stackingPenalties=penalize, penaltyGroup="preMul")
|
||||
stackingPenalties=True, penaltyGroup="preMul")
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
# Not used by any item
|
||||
type = "active", "projected"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
if "projected" not in context:
|
||||
return
|
||||
fit.ship.boostItemAttr("maxVelocity", module.getModifiedItemAttr("speedFactor"),
|
||||
stackingPenalties=True)
|
||||
11
eos/effects/disintegratorweapondamagemultiply.py
Normal file
11
eos/effects/disintegratorweapondamagemultiply.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# disintegratorWeaponDamageMultiply
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Entropic Radiation Sink (4 of 4)
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.group.name == "Precursor Weapon",
|
||||
"damageMultiplier", module.getModifiedItemAttr("damageMultiplier"),
|
||||
stackingPenalties=True)
|
||||
11
eos/effects/disintegratorweaponspeedmultiply.py
Normal file
11
eos/effects/disintegratorweaponspeedmultiply.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# disintegratorWeaponSpeedMultiply
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Entropic Radiation Sink (4 of 4)
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.group.name == "Precursor Weapon",
|
||||
"speed", module.getModifiedItemAttr("speedMultiplier"),
|
||||
stackingPenalties=True)
|
||||
@@ -1,7 +1,7 @@
|
||||
# doHacking
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Data Miners (9 of 9)
|
||||
# Modules from group: Data Miners (10 of 10)
|
||||
type = "active"
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#
|
||||
# Used by:
|
||||
# Module: Warp Disruption Burst Projector
|
||||
# Structure Module: Standup Warp Disruption Burst Projector
|
||||
type = "projected", "active"
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#
|
||||
# Used by:
|
||||
# Module: Sensor Dampening Burst Projector
|
||||
# Structure Module: Standup Sensor Dampening Burst Projector
|
||||
type = "projected", "active"
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#
|
||||
# Used by:
|
||||
# Module: ECM Jammer Burst Projector
|
||||
# Structure Module: Standup ECM Jammer Burst Projector
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict
|
||||
|
||||
type = "projected", "active"
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#
|
||||
# Used by:
|
||||
# Module: Energy Neutralization Burst Projector
|
||||
# Structure Module: Standup Energy Neutralization Burst Projector
|
||||
from eos.saveddata.module import State
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#
|
||||
# Used by:
|
||||
# Module: Target Illumination Burst Projector
|
||||
# Structure Module: Standup Target Illumination Burst Projector
|
||||
type = "projected", "active"
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#
|
||||
# Used by:
|
||||
# Module: Weapon Disruption Burst Projector
|
||||
# Structure Module: Standup Weapon Disruption Burst Projector
|
||||
|
||||
type = "active", "projected"
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#
|
||||
# Used by:
|
||||
# Module: Stasis Webification Burst Projector
|
||||
# Structure Module: Standup Stasis Webification Burst Projector
|
||||
type = "active", "projected"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# droneArmorDamageBonusEffect
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Logistics (5 of 6)
|
||||
# Ships from group: Logistics (6 of 7)
|
||||
# Ship: Exequror
|
||||
# Ship: Scythe
|
||||
type = "passive"
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# Not used by any item
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, skill, context):
|
||||
fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Drones"),
|
||||
"damageMultiplier", skill.getModifiedItemAttr("damageMultiplierBonus") * skill.level)
|
||||
@@ -1,7 +1,7 @@
|
||||
# droneHullRepairBonusEffect
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Logistics (5 of 6)
|
||||
# Ships from group: Logistics (6 of 7)
|
||||
# Ship: Exequror
|
||||
# Ship: Scythe
|
||||
type = "passive"
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
#
|
||||
# Used by:
|
||||
# Modules named like: Drone Speed Augmentor (6 of 8)
|
||||
# Implant: Overmind 'Goliath' Drone Tuner T25-10S
|
||||
# Implant: Overmind 'Hawkmoth' Drone Tuner S10-25T
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, container, context):
|
||||
level = container.level if "skill" in context else 1
|
||||
fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Drones"),
|
||||
"maxVelocity", container.getModifiedItemAttr("droneMaxVelocityBonus") * level)
|
||||
"maxVelocity", container.getModifiedItemAttr("droneMaxVelocityBonus") * level, stackingPenalties=True)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# droneShieldBonusBonusEffect
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Logistics (5 of 6)
|
||||
# Ships from group: Logistics (6 of 7)
|
||||
# Ship: Exequror
|
||||
# Ship: Scythe
|
||||
type = "passive"
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
# Not used by any item
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command Specialist"),
|
||||
"commandBonusHidden",
|
||||
src.getModifiedItemAttr("eliteBonusCommandDestroyer1"),
|
||||
skill="Command Destroyers")
|
||||
@@ -1,7 +0,0 @@
|
||||
# Not used by any item
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("High Speed Maneuvering"), "signatureRadiusBonus",
|
||||
src.getModifiedItemAttr("eliteBonusCommandDestroyer3"), skill="Command Destroyers")
|
||||
@@ -1,7 +0,0 @@
|
||||
# Not used by any item
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command Specialist"),
|
||||
"commandBonusHidden", module.getModifiedItemAttr("eliteBonusCommandShips3"), skill="Command Ships")
|
||||
@@ -1,7 +1,7 @@
|
||||
# eliteBonusCoverOpsScanProbeStrength2
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Covert Ops (7 of 7)
|
||||
# Ships from group: Covert Ops (8 of 8)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
10
eos/effects/elitebonuscovertops3pctdamagepercycle.py
Normal file
10
eos/effects/elitebonuscovertops3pctdamagepercycle.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# eliteBonusCovertOps3PCTdamagePerCycle
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Hydra
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredItemIncrease(lambda mod: mod.item.requiresSkill("Small Precursor Weapon"), "damageMultiplierBonusPerCycle",
|
||||
src.getModifiedItemAttr("eliteBonusCovertOps3"), skill="Covert Ops")
|
||||
@@ -1,6 +0,0 @@
|
||||
# Not used by any item
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, ship, context):
|
||||
fit.ship.increaseItemAttr("droneCapacity", ship.getModifiedItemAttr("eliteBonusGunship2"), skill="Assault Frigates")
|
||||
@@ -1,7 +0,0 @@
|
||||
# Not used by any item
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "trackingSpeed",
|
||||
src.getModifiedItemAttr("eliteBonusGunship2"), stackingPenalties=True, skill="Assault Frigates")
|
||||
@@ -1,8 +0,0 @@
|
||||
# Not used by any item
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Small Projectile Turret"),
|
||||
"damageMultiplier", ship.getModifiedItemAttr("eliteBonusGunship2"),
|
||||
skill="Assault Frigates")
|
||||
@@ -1,7 +0,0 @@
|
||||
# Not used by any item
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Small Projectile Turret"),
|
||||
"maxRange", ship.getModifiedItemAttr("eliteBonusGunship1"), skill="Assault Frigates")
|
||||
10
eos/effects/elitebonusreconscanprobestrength2.py
Normal file
10
eos/effects/elitebonusreconscanprobestrength2.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# eliteBonusReconScanProbeStrength2
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Tiamat
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Astrometrics"), "baseSensorStrength",
|
||||
src.getModifiedItemAttr("eliteBonusReconShip2"), skill="Recon Ships")
|
||||
10
eos/effects/elitebonusreconship3pctdamagepercycle.py
Normal file
10
eos/effects/elitebonusreconship3pctdamagepercycle.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# eliteBonusReconShip3PCTdamagePerCycle
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Tiamat
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredItemIncrease(lambda mod: mod.item.requiresSkill("Medium Precursor Weapon"), "damageMultiplierBonusPerCycle",
|
||||
src.getModifiedItemAttr("eliteBonusReconShip3"), skill="Recon Ships")
|
||||
13
eos/effects/emergencyhullenergizer.py
Normal file
13
eos/effects/emergencyhullenergizer.py
Normal file
@@ -0,0 +1,13 @@
|
||||
# emergencyHullEnergizer
|
||||
#
|
||||
# Used by:
|
||||
# Variations of module: Capital Emergency Hull Energizer I (5 of 5)
|
||||
type = "active"
|
||||
runtime = "late"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
for dmgType in ('em', 'thermal', 'kinetic', 'explosive'):
|
||||
fit.ship.multiplyItemAttr('{}DamageResonance'.format(dmgType),
|
||||
src.getModifiedItemAttr("hull{}DamageResonance".format(dmgType.title())),
|
||||
stackingPenalties=True, penaltyGroup="postMul")
|
||||
@@ -1,12 +0,0 @@
|
||||
# Not used by any item
|
||||
from eos.saveddata.module import State
|
||||
|
||||
type = "active", "projected"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
if "projected" in context and ((hasattr(src, "state") and src.state >= State.ACTIVE) or hasattr(src, "amountActive")):
|
||||
multiplier = src.amountActive if hasattr(src, "amountActive") else 1
|
||||
amount = src.getModifiedItemAttr("energyNeutralizerAmount")
|
||||
time = src.getModifiedItemAttr("duration")
|
||||
fit.addDrain(src, time, amount * multiplier, 0)
|
||||
@@ -1,7 +1,7 @@
|
||||
# energyNeutralizerFalloff
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Energy Neutralizer (51 of 51)
|
||||
# Modules from group: Energy Neutralizer (54 of 54)
|
||||
from eos.saveddata.module import State
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# energyNosferatuFalloff
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Energy Nosferatu (51 of 51)
|
||||
# Modules from group: Energy Nosferatu (54 of 54)
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict
|
||||
|
||||
type = "active", "projected"
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
# Not used by any item
|
||||
type = "projected", "active"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
if "projected" in context:
|
||||
amount = src.getModifiedItemAttr("powerTransferAmount")
|
||||
duration = src.getModifiedItemAttr("duration")
|
||||
fit.addDrain(src, duration, -amount, 0)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user