Merge branch 'master' into charImplants
Conflicts: gui/characterEditor.py
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -13,7 +13,7 @@
|
||||
*.patch
|
||||
|
||||
#Personal
|
||||
saveddata/
|
||||
/saveddata/
|
||||
|
||||
#PyCharm
|
||||
.idea/
|
||||
|
||||
50
README.md
50
README.md
@@ -1,22 +1,48 @@
|
||||
# Pyfa
|
||||
# pyfa
|
||||
|
||||
Pyfa is a cross-platform desktop fitting application for EVE online that can be used natively on any platform where python and wxwidgets are available.
|
||||

|
||||
|
||||
It provides many advanced features such as graphs and full calculations of any possible combination of modules, fits, etc.
|
||||
## What is it?
|
||||
|
||||
Please see the [FAQ](https://github.com/DarkFenX/Pyfa/wiki/FAQ) for answers to common questions / concerns
|
||||
pyfa, short for **py**thon **f**itting **a**ssistant, allows you to create, experiment with, and save ship fittings without being in game. Open source and written in Python, it is available on any platform where Python 2.x and wxWidgets are available, including Windows, Mac OS X, and Linux.
|
||||
|
||||
#### A note for Linux users
|
||||
pyfa currently only supports wxPython 2.8. However, there are some distros that have started to support 3.0 and subsequently dropped support for 2.8 altogether (such as Debian Jessie). If this is the case and wxPython 3.0 is the only version installed, the official pyfa releases will not run. You must either find a package for 2.8 or compile it yourself.
|
||||
## Latest Version and Changelogs
|
||||
The latest version along with release notes can always be found on the projects [Releases](https://github.com/DarkFenX/Pyfa/releases) page. pyfa will notify you if you are running an outdated version.
|
||||
|
||||
For Debian Jessie, wxPython 2.8 is available in Sid (the unstable repo). you can use apt-pinning to install select packages from unstable and still keep your stable system. See http://jaqque.sbih.org/kplug/apt-pinning.html for me details.
|
||||
## Installing
|
||||
Windows and OS X users are supplied self-contained builds of pyfa that can be run without additional software. An `.exe` installer is also available for the Windows builds. There is no self-contained package for Linux users, which are expected to run pyfa through their distributions Python interpreter. However, there are a number of third-party packages available that handle the dependencies and updates for pyfa (for example, [pyfa for Arch Linux](https://aur.archlinux.org/packages/pyfa/)). Please check your distributions repositories.
|
||||
|
||||
3.0 support is being worked on and can be found on the wx3 branch. It may be stable enough for you, but there are a few bugs related to it. Please see the wx3 label on the GitHub issues area for me information on known issues (biggest one currently is GTK warning spam): https://github.com/DarkFenX/Pyfa/labels/wx3
|
||||
## Requirements
|
||||
If you wish to help with development or simply need to run pyfa through a Python interpreter, the following software is required:
|
||||
|
||||
#### Links
|
||||
* [Development repository: http://github.com/DarkFenX/Pyfa](http://github.com/DarkFenX/Pyfa)
|
||||
* [XMPP conference:
|
||||
pyfa@conference.jabber.org](pyfa@conference.jabber.org)
|
||||
* Python >= 2.6
|
||||
* `wxPython` 2.8/3.0
|
||||
* `sqlalchemy` >= 0.6
|
||||
* `dateutil`
|
||||
* `matplotlib` (for some Linux distributions, you may need to install separate wxPython bindings, such as `python-matplotlib-wx`)
|
||||
* `requests`
|
||||
|
||||
## Bug Reporting
|
||||
The preferred method of reporting bugs is through the projects GitHub Issues interface. Alternatively, posting a report in the pyfa thread on the official EVE Online forums is acceptable. Guidelines for bug reporting can be found on [this wiki page](https://github.com/DarkFenX/Pyfa/wiki/Bug-Reporting).
|
||||
|
||||
## License
|
||||
pyfa is licensed under the GNU GPL v3.0, see LICENSE
|
||||
|
||||
## Resources
|
||||
* Development repository: [http://github.com/DarkFenX/Pyfa](http://github.com/DarkFenX/Pyfa)
|
||||
* XMPP conference: [pyfa@conference.jabber.org](pyfa@conference.jabber.org)
|
||||
* [EVE forum thread](http://forums.eveonline.com/default.aspx?g=posts&t=247609)
|
||||
* [EVE University guide using pyfa](http://wiki.eveuniversity.org/Guide_to_using_PYFA)
|
||||
* [EVE Online website](http://www.eveonline.com/)
|
||||
|
||||
## Contacts:
|
||||
* Kadesh Priestess
|
||||
* GitHub: @DarkFenX
|
||||
* [TweetFleet Slack](https://www.fuzzwork.co.uk/tweetfleet-slack-invites/): @kadesh
|
||||
* Sable Blitzmann
|
||||
* GitHub: @blitzmann
|
||||
* [TweetFleet Slack](https://www.fuzzwork.co.uk/tweetfleet-slack-invites/): @blitzmann
|
||||
* Email: sable.blitzmann@gmail.com
|
||||
|
||||
## CCP Copyright Notice
|
||||
EVE Online, the EVE logo, EVE and all associated logos and designs are the intellectual property of CCP hf. All artwork, screenshots, characters, vehicles, storylines, world facts or other recognizable features of the intellectual property relating to these trademarks are likewise the intellectual property of CCP hf. EVE Online and the EVE logo are the registered trademarks of CCP hf. All rights are reserved worldwide. All other trademarks are the property of their respective owners. CCP hf. has granted permission to Osmium to use EVE Online and all associated logos and designs for promotional and information purposes on its website but does not endorse, and is not in any way affiliated with, Osmium. CCP is in no way responsible for the content on or functioning of this website, nor can it be liable for any damage arising from the use of this website.
|
||||
|
||||
53
config.py
53
config.py
@@ -17,21 +17,15 @@ debug = False
|
||||
# Defines if our saveddata will be in pyfa root or not
|
||||
saveInRoot = False
|
||||
|
||||
if debug:
|
||||
logLevel = logging.DEBUG
|
||||
else:
|
||||
logLevel = logging.WARN
|
||||
|
||||
# Version data
|
||||
version = "1.14.1"
|
||||
tag = "git"
|
||||
expansionName = "Galatea"
|
||||
expansionVersion = "1.2"
|
||||
version = "1.16.2"
|
||||
tag = "Stable"
|
||||
expansionName = "Parallax"
|
||||
expansionVersion = "1.1"
|
||||
evemonMinVersion = "4081"
|
||||
|
||||
pyfaPath = None
|
||||
savePath = None
|
||||
staticPath = None
|
||||
saveDB = None
|
||||
gameDB = None
|
||||
|
||||
@@ -50,23 +44,40 @@ class StreamToLogger(object):
|
||||
for line in buf.rstrip().splitlines():
|
||||
self.logger.log(self.log_level, line.rstrip())
|
||||
|
||||
def isFrozen():
|
||||
if hasattr(sys, 'frozen'):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def getPyfaRoot():
|
||||
base = getattr(sys.modules['__main__'], "__file__", sys.executable) if isFrozen() else sys.argv[0]
|
||||
root = os.path.dirname(os.path.realpath(os.path.abspath(base)))
|
||||
root = unicode(root, sys.getfilesystemencoding())
|
||||
return root
|
||||
|
||||
def __createDirs(path):
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
|
||||
def defPaths():
|
||||
global debug
|
||||
global pyfaPath
|
||||
global savePath
|
||||
global staticPath
|
||||
global saveDB
|
||||
global gameDB
|
||||
global saveInRoot
|
||||
|
||||
if debug:
|
||||
logLevel = logging.DEBUG
|
||||
else:
|
||||
logLevel = logging.WARN
|
||||
|
||||
# The main pyfa directory which contains run.py
|
||||
# Python 2.X uses ANSI by default, so we need to convert the character encoding
|
||||
pyfaPath = getattr(configforced, "pyfaPath", pyfaPath)
|
||||
if pyfaPath is None:
|
||||
pyfaPath = unicode(os.path.dirname(os.path.realpath(os.path.abspath(
|
||||
sys.modules['__main__'].__file__))), sys.getfilesystemencoding())
|
||||
pyfaPath = getPyfaRoot()
|
||||
|
||||
# Where we store the saved fits etc, default is the current users home directory
|
||||
if saveInRoot is True:
|
||||
@@ -81,6 +92,9 @@ def defPaths():
|
||||
|
||||
__createDirs(savePath)
|
||||
|
||||
if isFrozen():
|
||||
os.environ["REQUESTS_CA_BUNDLE"] = os.path.join(pyfaPath, "cacert.pem")
|
||||
|
||||
format = '%(asctime)s %(name)-24s %(levelname)-8s %(message)s'
|
||||
logging.basicConfig(format=format, level=logLevel)
|
||||
handler = logging.handlers.RotatingFileHandler(os.path.join(savePath, "log.txt"), maxBytes=1000000, backupCount=3)
|
||||
@@ -95,13 +109,10 @@ def defPaths():
|
||||
sl = StreamToLogger(stdout_logger, logging.INFO)
|
||||
sys.stdout = sl
|
||||
|
||||
stderr_logger = logging.getLogger('STDERR')
|
||||
sl = StreamToLogger(stderr_logger, logging.ERROR)
|
||||
sys.stderr = sl
|
||||
|
||||
# Static EVE Data from the staticdata repository, should be in the staticdata
|
||||
# directory in our pyfa directory
|
||||
staticPath = os.path.join(pyfaPath, "staticdata")
|
||||
# This interferes with cx_Freeze's own handling of exceptions. Find a way to fix this.
|
||||
#stderr_logger = logging.getLogger('STDERR')
|
||||
#sl = StreamToLogger(stderr_logger, logging.ERROR)
|
||||
#sys.stderr = sl
|
||||
|
||||
# The database where we store all the fits etc
|
||||
saveDB = os.path.join(savePath, "saveddata.db")
|
||||
@@ -109,7 +120,7 @@ def defPaths():
|
||||
# The database where the static EVE data from the datadump is kept.
|
||||
# This is not the standard sqlite datadump but a modified version created by eos
|
||||
# maintenance script
|
||||
gameDB = os.path.join(staticPath, "eve.db")
|
||||
gameDB = os.path.join(pyfaPath, "eve.db")
|
||||
|
||||
## DON'T MODIFY ANYTHING BELOW ##
|
||||
import eos.config
|
||||
|
||||
BIN
dist_assets/mac/pyfa.icns
Normal file
BIN
dist_assets/mac/pyfa.icns
Normal file
Binary file not shown.
BIN
dist_assets/win/pyfa.ico
Normal file
BIN
dist_assets/win/pyfa.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 76 KiB |
@@ -59,26 +59,20 @@ class CapSimulator(object):
|
||||
return duration, capNeed
|
||||
|
||||
def init(self, modules):
|
||||
"""prepare modules. a list of (duration, capNeed, clipSize) tuples is
|
||||
"""prepare modules. a list of (duration, capNeed, clipSize, disableStagger) tuples is
|
||||
expected, with clipSize 0 if the module has infinite ammo.
|
||||
"""
|
||||
mods = {}
|
||||
for module in modules:
|
||||
if module in mods:
|
||||
mods[module] += 1
|
||||
else:
|
||||
mods[module] = 1
|
||||
|
||||
self.modules = mods
|
||||
|
||||
self.modules = modules
|
||||
|
||||
def reset(self):
|
||||
"""Reset the simulator state"""
|
||||
self.state = []
|
||||
mods = {}
|
||||
period = 1
|
||||
disable_period = False
|
||||
|
||||
for (duration, capNeed, clipSize), amount in self.modules.iteritems():
|
||||
# Loop over modules, clearing clipSize if applicable, and group modules based on attributes
|
||||
for (duration, capNeed, clipSize, disableStagger) in self.modules:
|
||||
if self.scale:
|
||||
duration, capNeed = self.scale_activation(duration, capNeed)
|
||||
|
||||
@@ -87,7 +81,15 @@ class CapSimulator(object):
|
||||
if not self.reload and capNeed > 0:
|
||||
clipSize = 0
|
||||
|
||||
if self.stagger:
|
||||
# Group modules based on their properties
|
||||
if (duration, capNeed, clipSize, disableStagger) in mods:
|
||||
mods[(duration, capNeed, clipSize, disableStagger)] += 1
|
||||
else:
|
||||
mods[(duration, capNeed, clipSize, disableStagger)] = 1
|
||||
|
||||
# Loop over grouped modules, configure staggering and push to the simulation state
|
||||
for (duration, capNeed, clipSize, disableStagger), amount in mods.iteritems():
|
||||
if self.stagger and not disableStagger:
|
||||
if clipSize == 0:
|
||||
duration = int(duration/amount)
|
||||
else:
|
||||
@@ -167,13 +169,13 @@ class CapSimulator(object):
|
||||
|
||||
iterations += 1
|
||||
|
||||
t_last = t_now
|
||||
|
||||
if cap < cap_lowest:
|
||||
if cap < 0.0:
|
||||
break
|
||||
cap_lowest = cap
|
||||
|
||||
t_last = t_now
|
||||
|
||||
# queue the next activation of this module
|
||||
t_now += duration
|
||||
shot += 1
|
||||
|
||||
@@ -4,7 +4,7 @@ import sys
|
||||
debug = False
|
||||
gamedataCache = True
|
||||
saveddataCache = True
|
||||
gamedata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "staticdata", "eve.db")), sys.getfilesystemencoding())
|
||||
gamedata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "eve.db")), sys.getfilesystemencoding())
|
||||
saveddata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "saveddata", "saveddata.db")), sys.getfilesystemencoding())
|
||||
|
||||
#Autodetect path, only change if the autodetection bugs out.
|
||||
|
||||
@@ -68,14 +68,8 @@ from eos.db.gamedata import *
|
||||
from eos.db.saveddata import *
|
||||
|
||||
#Import queries
|
||||
from eos.db.gamedata.queries import getItem, searchItems, getVariations, getItemsByCategory, directAttributeRequest, \
|
||||
getMarketGroup, getGroup, getCategory, getAttributeInfo, getMetaData, getMetaGroup
|
||||
from eos.db.saveddata.queries import getUser, getCharacter, getFit, getFitsWithShip, countFitsWithShip, searchFits, \
|
||||
getCharacterList, getPrice, getDamagePatternList, getDamagePattern, \
|
||||
getFitList, getFleetList, getFleet, save, remove, commit, add, \
|
||||
getCharactersForUser, getMiscData, getSquadsIDsWithFitID, getWing, \
|
||||
getSquad, getBoosterFits, getProjectedFits, getTargetResistsList, getTargetResists,\
|
||||
clearPrices, countAllFits
|
||||
from eos.db.gamedata.queries import *
|
||||
from eos.db.saveddata.queries import *
|
||||
|
||||
#If using in memory saveddata, you'll want to reflect it so the data structure is good.
|
||||
if config.saveddata_connectionstring == "sqlite:///:memory:":
|
||||
|
||||
@@ -3,22 +3,15 @@ import shutil
|
||||
import time
|
||||
import re
|
||||
import os
|
||||
|
||||
def getAppVersion():
|
||||
# calculate app version based on upgrade files we have
|
||||
appVersion = 0
|
||||
for fname in os.listdir(os.path.join(os.path.dirname(__file__), "migrations")):
|
||||
m = re.match("^upgrade(?P<index>\d+)\.py$", fname)
|
||||
if not m:
|
||||
continue
|
||||
index = int(m.group("index"))
|
||||
appVersion = max(appVersion, index)
|
||||
return appVersion
|
||||
import migrations
|
||||
|
||||
def getVersion(db):
|
||||
cursor = db.execute('PRAGMA user_version')
|
||||
return cursor.fetchone()[0]
|
||||
|
||||
def getAppVersion():
|
||||
return migrations.appVersion
|
||||
|
||||
def update(saveddata_engine):
|
||||
dbVersion = getVersion(saveddata_engine)
|
||||
appVersion = getAppVersion()
|
||||
@@ -37,10 +30,11 @@ def update(saveddata_engine):
|
||||
shutil.copyfile(config.saveDB, toFile)
|
||||
|
||||
for version in xrange(dbVersion, appVersion):
|
||||
module = __import__("eos.db.migrations.upgrade{}".format(version + 1), fromlist=True)
|
||||
upgrade = getattr(module, "upgrade", False)
|
||||
if upgrade:
|
||||
upgrade(saveddata_engine)
|
||||
|
||||
func = migrations.updates[version+1]
|
||||
if func:
|
||||
print "applying update",version+1
|
||||
func(saveddata_engine)
|
||||
|
||||
# when all is said and done, set version to current
|
||||
saveddata_engine.execute("PRAGMA user_version = {}".format(appVersion))
|
||||
|
||||
@@ -7,3 +7,25 @@ define an upgrade() function with the logic. Please note that there must be as
|
||||
many upgrade files as there are database versions (version 5 would include
|
||||
upgrade files 1-5)
|
||||
"""
|
||||
|
||||
import pkgutil
|
||||
import re
|
||||
|
||||
|
||||
updates = {}
|
||||
appVersion = 0
|
||||
|
||||
prefix = __name__ + "."
|
||||
for importer, modname, ispkg in pkgutil.iter_modules(__path__, prefix):
|
||||
# loop through python files, extracting update number and function, and
|
||||
# adding it to a list
|
||||
modname_tail = modname.rsplit('.', 1)[-1]
|
||||
module = __import__(modname, fromlist=True)
|
||||
m = re.match("^upgrade(?P<index>\d+)$", modname_tail)
|
||||
if not m:
|
||||
continue
|
||||
index = int(m.group("index"))
|
||||
appVersion = max(appVersion, index)
|
||||
upgrade = getattr(module, "upgrade", False)
|
||||
if upgrade:
|
||||
updates[index] = upgrade
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
__all__ = ["character", "fit", "module", "user", "skill", "price",
|
||||
"booster", "drone", "implant", "fleet", "damagePattern",
|
||||
"miscData", "targetResists"]
|
||||
__all__ = [
|
||||
"character",
|
||||
"fit",
|
||||
"module",
|
||||
"user",
|
||||
"skill",
|
||||
"price",
|
||||
"booster",
|
||||
"drone",
|
||||
"implant",
|
||||
"fleet",
|
||||
"damagePattern",
|
||||
"miscData",
|
||||
"targetResists",
|
||||
"override",
|
||||
"crest"
|
||||
]
|
||||
|
||||
|
||||
31
eos/db/saveddata/crest.py
Normal file
31
eos/db/saveddata/crest.py
Normal file
@@ -0,0 +1,31 @@
|
||||
#===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
#
|
||||
# eos is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# eos is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, String, Boolean
|
||||
from sqlalchemy.orm import mapper
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.types import CrestChar
|
||||
|
||||
crest_table = Table("crest", saveddata_meta,
|
||||
Column("ID", Integer, primary_key = True),
|
||||
Column("name", String, nullable = False, unique = True),
|
||||
Column("refresh_token", String, nullable = False))
|
||||
|
||||
mapper(CrestChar, crest_table)
|
||||
31
eos/db/saveddata/override.py
Normal file
31
eos/db/saveddata/override.py
Normal file
@@ -0,0 +1,31 @@
|
||||
#===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
#
|
||||
# eos is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# eos is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, Float
|
||||
from sqlalchemy.orm import mapper
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.types import Override
|
||||
|
||||
overrides_table = Table("overrides", saveddata_meta,
|
||||
Column("itemID", Integer, primary_key=True, index = True),
|
||||
Column("attrID", Integer, primary_key=True, index = True),
|
||||
Column("value", Float, nullable = False))
|
||||
|
||||
mapper(Override, overrides_table)
|
||||
@@ -19,7 +19,8 @@
|
||||
|
||||
from eos.db.util import processEager, processWhere
|
||||
from eos.db import saveddata_session, sd_lock
|
||||
from eos.types import User, Character, Fit, Price, DamagePattern, Fleet, MiscData, Wing, Squad, TargetResists
|
||||
|
||||
from eos.types import User, Character, Fit, Price, DamagePattern, Fleet, MiscData, Wing, Squad, TargetResists, Override, CrestChar
|
||||
from eos.db.saveddata.fleet import squadmembers_table
|
||||
from eos.db.saveddata.fit import projectedFits_table
|
||||
from sqlalchemy.sql import and_
|
||||
@@ -182,7 +183,7 @@ def getFit(lookfor, eager=None):
|
||||
else:
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
fit = saveddata_session.query(Fit).options(*eager).filter(Fit.ID == fitID).first()
|
||||
fit = saveddata_session.query(Fit).options(*eager).filter(Fit.ID == lookfor).first()
|
||||
else:
|
||||
raise TypeError("Need integer as argument")
|
||||
|
||||
@@ -416,6 +417,45 @@ def getProjectedFits(fitID):
|
||||
else:
|
||||
raise TypeError("Need integer as argument")
|
||||
|
||||
def getCrestCharacters(eager=None):
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
characters = saveddata_session.query(CrestChar).options(*eager).all()
|
||||
return characters
|
||||
|
||||
@cachedQuery(CrestChar, 1, "lookfor")
|
||||
def getCrestCharacter(lookfor, eager=None):
|
||||
if isinstance(lookfor, int):
|
||||
if eager is None:
|
||||
with sd_lock:
|
||||
character = saveddata_session.query(CrestChar).get(lookfor)
|
||||
else:
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
character = saveddata_session.query(CrestChar).options(*eager).filter(CrestChar.ID == lookfor).first()
|
||||
elif isinstance(lookfor, basestring):
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
character = saveddata_session.query(CrestChar).options(*eager).filter(CrestChar.name == lookfor).first()
|
||||
else:
|
||||
raise TypeError("Need integer or string as argument")
|
||||
return character
|
||||
|
||||
def getOverrides(itemID, eager=None):
|
||||
if isinstance(itemID, int):
|
||||
return saveddata_session.query(Override).filter(Override.itemID == itemID).all()
|
||||
else:
|
||||
raise TypeError("Need integer as argument")
|
||||
|
||||
def clearOverrides():
|
||||
with sd_lock:
|
||||
deleted_rows = saveddata_session.query(Override).delete()
|
||||
commit()
|
||||
return deleted_rows
|
||||
|
||||
def getAllOverrides(eager=None):
|
||||
return saveddata_session.query(Override).all()
|
||||
|
||||
def removeInvalid(fits):
|
||||
invalids = [f for f in fits if f.isInvalid]
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# armorTankingGang2
|
||||
# armorWarfareArmorHpReplacer
|
||||
#
|
||||
# Used by:
|
||||
# Implant: Armored Warfare Mindlink
|
||||
9
eos/effects/battlecruiserdronespeed.py
Normal file
9
eos/effects/battlecruiserdronespeed.py
Normal file
@@ -0,0 +1,9 @@
|
||||
# battlecruiserDroneSpeed
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Myrmidon
|
||||
# Ship: Prophecy
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Drones"),
|
||||
"maxVelocity", ship.getModifiedItemAttr("roleBonusCBC"))
|
||||
10
eos/effects/battlecruisermetrange.py
Normal file
10
eos/effects/battlecruisermetrange.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# battlecruiserMETRange
|
||||
#
|
||||
# Used by:
|
||||
# Ships named like: Harbinger (2 of 2)
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Energy Turret"),
|
||||
"maxRange", ship.getModifiedItemAttr("roleBonusCBC"))
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Energy Turret"),
|
||||
"falloff", ship.getModifiedItemAttr("roleBonusCBC"))
|
||||
11
eos/effects/battlecruisermhtrange.py
Normal file
11
eos/effects/battlecruisermhtrange.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# battlecruiserMHTRange
|
||||
#
|
||||
# Used by:
|
||||
# Ships named like: Brutix (2 of 2)
|
||||
# Ship: Ferox
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Hybrid Turret"),
|
||||
"maxRange", ship.getModifiedItemAttr("roleBonusCBC"))
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Hybrid Turret"),
|
||||
"falloff", ship.getModifiedItemAttr("roleBonusCBC"))
|
||||
9
eos/effects/battlecruisermissilerange.py
Normal file
9
eos/effects/battlecruisermissilerange.py
Normal file
@@ -0,0 +1,9 @@
|
||||
# battlecruiserMissileRange
|
||||
#
|
||||
# Used by:
|
||||
# Ships named like: Drake (2 of 2)
|
||||
# Ship: Cyclone
|
||||
type = "passive"
|
||||
def handler(fit, skill, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"),
|
||||
"maxVelocity", skill.getModifiedItemAttr("roleBonusCBC"))
|
||||
10
eos/effects/battlecruisermptrange.py
Normal file
10
eos/effects/battlecruisermptrange.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# battlecruiserMPTRange
|
||||
#
|
||||
# Used by:
|
||||
# Ships named like: Hurricane (2 of 2)
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Projectile Turret"),
|
||||
"maxRange", ship.getModifiedItemAttr("roleBonusCBC"))
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Projectile Turret"),
|
||||
"falloff", ship.getModifiedItemAttr("roleBonusCBC"))
|
||||
7
eos/effects/crystalminingamountinfo2.py
Normal file
7
eos/effects/crystalminingamountinfo2.py
Normal file
@@ -0,0 +1,7 @@
|
||||
# crystalMiningamountInfo2
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Frequency Mining Laser (3 of 3)
|
||||
type = "passive"
|
||||
def handler(fit, module, context):
|
||||
module.preAssignItemAttr("specialtyMiningAmount", module.getModifiedItemAttr("miningAmount"))
|
||||
8
eos/effects/entosiscpuaddition.py
Normal file
8
eos/effects/entosiscpuaddition.py
Normal file
@@ -0,0 +1,8 @@
|
||||
# entosisCPUAddition
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Entosis Link (2 of 2)
|
||||
type = "passive"
|
||||
def handler(fit, module, context):
|
||||
module.increaseItemAttr("cpu", module.getModifiedItemAttr("entosisCPUAdd"))
|
||||
|
||||
8
eos/effects/entosiscpupenalty.py
Normal file
8
eos/effects/entosiscpupenalty.py
Normal file
@@ -0,0 +1,8 @@
|
||||
# entosisCPUPenalty
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Interceptor (10 of 10)
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredItemIncrease(lambda mod: mod.item.requiresSkill("Infomorph Psychology"),
|
||||
"entosisCPUAdd", ship.getModifiedItemAttr("entosisCPUPenalty"))
|
||||
11
eos/effects/informationwarfaremaxtargetrangebonus.py
Normal file
11
eos/effects/informationwarfaremaxtargetrangebonus.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# informationWarfareMaxTargetRangeBonus
|
||||
#
|
||||
# Used by:
|
||||
# Implant: Caldari Navy Warfare Mindlink
|
||||
# Implant: Imperial Navy Warfare Mindlink
|
||||
# Implant: Information Warfare Mindlink
|
||||
type = "gang"
|
||||
gangBoost = "maxTargetRange"
|
||||
gangBonus = "maxTargetRangeBonus"
|
||||
def handler(fit, container, context):
|
||||
fit.ship.boostItemAttr(gangBoost, container.getModifiedItemAttr(gangBonus))
|
||||
@@ -2,7 +2,6 @@
|
||||
#
|
||||
# Used by:
|
||||
# Implant: Caldari Navy Warfare Mindlink
|
||||
# Implant: Imperial Navy Warfare Mindlink
|
||||
# Implant: Information Warfare Mindlink
|
||||
type = "passive"
|
||||
def handler(fit, implant, context):
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# Used by:
|
||||
# Module: Medium Mercoxit Mining Crystal Optimization I
|
||||
type = "passive"
|
||||
runTime="early"
|
||||
def handler(fit, module, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Mercoxit Processing"),
|
||||
"specialisationAsteroidYieldMultiplier", module.getModifiedItemAttr("miningAmountBonus"))
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
# miningForemanMindLinkMiningAmountBonusReplacer
|
||||
#
|
||||
# Used by:
|
||||
# Implant: Mining Foreman Mindlink
|
||||
type = "gang"
|
||||
gangBoost = "miningAmount"
|
||||
gangBonus = "miningAmountBonus"
|
||||
def handler(fit, container, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining"),
|
||||
gangBoost, container.getModifiedItemAttr(gangBonus) * level)
|
||||
@@ -5,4 +5,4 @@
|
||||
# Charges named like: Mining Crystal (32 of 32)
|
||||
type = "passive"
|
||||
def handler(fit, module, context):
|
||||
module.multiplyItemAttr("miningAmount", module.getModifiedChargeAttr("specialisationAsteroidYieldMultiplier"))
|
||||
module.multiplyItemAttr("specialtyMiningAmount", module.getModifiedChargeAttr("specialisationAsteroidYieldMultiplier"))
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# miningYieldGangBonusFixed
|
||||
#
|
||||
# Used by:
|
||||
# Implant: Mining Foreman Mindlink
|
||||
# Skill: Mining Foreman
|
||||
type = "gang"
|
||||
gangBoost = "miningAmount"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# overloadSelfThermalHardeningBonus
|
||||
#
|
||||
# Used by:
|
||||
# Variations of module: Armor Thermic Hardener I (39 of 39)
|
||||
# Variations of module: Thermic Dissipation Field I (19 of 19)
|
||||
# Module: Civilian Thermic Dissipation Field
|
||||
# Variations of module: Armor Thermal Hardener I (39 of 39)
|
||||
# Variations of module: Thermal Dissipation Field I (19 of 19)
|
||||
# Module: Civilian Thermal Dissipation Field
|
||||
type = "overheat"
|
||||
def handler(fit, module, context):
|
||||
module.boostItemAttr("thermalDamageResistanceBonus", module.getModifiedItemAttr("overloadHardeningBonus"))
|
||||
@@ -1,9 +1,6 @@
|
||||
# reconOperationsMaxTargetRangeBonusPostPercentMaxTargetRangeGangShips
|
||||
#
|
||||
# Used by:
|
||||
# Implant: Caldari Navy Warfare Mindlink
|
||||
# Implant: Imperial Navy Warfare Mindlink
|
||||
# Implant: Information Warfare Mindlink
|
||||
# Skill: Information Warfare
|
||||
type = "gang"
|
||||
gangBoost = "maxTargetRange"
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
# shieldDefensiveOperationsShieldCapacityBonusPostPercentShieldCapacityGangShips
|
||||
#
|
||||
# Used by:
|
||||
# Implant: Caldari Navy Warfare Mindlink
|
||||
# Implant: Republic Fleet Warfare Mindlink
|
||||
# Implant: Siege Warfare Mindlink
|
||||
# Skill: Siege Warfare
|
||||
type = "gang"
|
||||
gangBoost = "shieldCapacity"
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Devoter
|
||||
# Ship: Gold Magnate
|
||||
# Ship: Impairor
|
||||
# Ship: Phobos
|
||||
# Ship: Silver Magnate
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
fit.ship.boostItemAttr("armorEmDamageResonance", ship.getModifiedItemAttr("rookieArmorResistanceBonus"))
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Devoter
|
||||
# Ship: Gold Magnate
|
||||
# Ship: Impairor
|
||||
# Ship: Phobos
|
||||
# Ship: Silver Magnate
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
fit.ship.boostItemAttr("armorExplosiveDamageResonance", ship.getModifiedItemAttr("rookieArmorResistanceBonus"))
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Devoter
|
||||
# Ship: Gold Magnate
|
||||
# Ship: Impairor
|
||||
# Ship: Phobos
|
||||
# Ship: Silver Magnate
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
fit.ship.boostItemAttr("armorKineticDamageResonance", ship.getModifiedItemAttr("rookieArmorResistanceBonus"))
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Devoter
|
||||
# Ship: Gold Magnate
|
||||
# Ship: Impairor
|
||||
# Ship: Phobos
|
||||
# Ship: Silver Magnate
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
fit.ship.boostItemAttr("armorThermalDamageResonance", ship.getModifiedItemAttr("rookieArmorResistanceBonus"))
|
||||
|
||||
8
eos/effects/shipbonusprojectiletrackingmbc2.py
Normal file
8
eos/effects/shipbonusprojectiletrackingmbc2.py
Normal file
@@ -0,0 +1,8 @@
|
||||
# shipBonusProjectileTrackingMBC2
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Hurricane Fleet Issue
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Projectile Turret"),
|
||||
"trackingSpeed", ship.getModifiedItemAttr("shipBonusMBC2"), skill="Minmatar Battlecruiser")
|
||||
@@ -1,4 +1,4 @@
|
||||
# shipBonusWDFGnullSpeedEffects
|
||||
# shipBonusWDFGnullPenalties
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Fiend
|
||||
@@ -1,8 +0,0 @@
|
||||
# shipHeavyAssaultMissileVelocityCBC2
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Drake Navy Issue
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Heavy Assault Missiles"),
|
||||
"maxVelocity", ship.getModifiedItemAttr("shipBonusCBC2"), skill="Caldari Battlecruiser")
|
||||
@@ -1,8 +0,0 @@
|
||||
# shipHeavyMissileVelocityCBC2
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Drake Navy Issue
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Heavy Missiles"),
|
||||
"maxVelocity", ship.getModifiedItemAttr("shipBonusCBC2"), skill="Caldari Battlecruiser")
|
||||
8
eos/effects/shiphybriddmg1cbc2.py
Normal file
8
eos/effects/shiphybriddmg1cbc2.py
Normal file
@@ -0,0 +1,8 @@
|
||||
# shipHybridDmg1CBC2
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Ferox
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Hybrid Turret"),
|
||||
"damageMultiplier", ship.getModifiedItemAttr("shipBonusCBC2"), skill="Caldari Battlecruiser")
|
||||
@@ -1,7 +1,7 @@
|
||||
# shipProjectileRof1MBC2
|
||||
#
|
||||
# Used by:
|
||||
# Ships named like: Hurricane (2 of 2)
|
||||
# Ship: Hurricane
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Projectile Turret"),
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
# shipShieldEmResistance1CBC2
|
||||
#
|
||||
# Used by:
|
||||
# Variations of ship: Ferox (2 of 2)
|
||||
# Ship: Drake
|
||||
# Ship: Nighthawk
|
||||
# Variations of ship: Drake (3 of 3)
|
||||
# Ship: Vulture
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
fit.ship.boostItemAttr("shieldEmDamageResonance", ship.getModifiedItemAttr("shipBonusCBC2"), skill="Caldari Battlecruiser")
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
# shipShieldExplosiveResistance1CBC2
|
||||
#
|
||||
# Used by:
|
||||
# Variations of ship: Ferox (2 of 2)
|
||||
# Ship: Drake
|
||||
# Ship: Nighthawk
|
||||
# Variations of ship: Drake (3 of 3)
|
||||
# Ship: Vulture
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
fit.ship.boostItemAttr("shieldExplosiveDamageResonance", ship.getModifiedItemAttr("shipBonusCBC2"), skill="Caldari Battlecruiser")
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
# shipShieldKineticResistance1CBC2
|
||||
#
|
||||
# Used by:
|
||||
# Variations of ship: Ferox (2 of 2)
|
||||
# Ship: Drake
|
||||
# Ship: Nighthawk
|
||||
# Variations of ship: Drake (3 of 3)
|
||||
# Ship: Vulture
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
fit.ship.boostItemAttr("shieldKineticDamageResonance", ship.getModifiedItemAttr("shipBonusCBC2"), skill="Caldari Battlecruiser")
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
# shipShieldThermalResistance1CBC2
|
||||
#
|
||||
# Used by:
|
||||
# Variations of ship: Ferox (2 of 2)
|
||||
# Ship: Drake
|
||||
# Ship: Nighthawk
|
||||
# Variations of ship: Drake (3 of 3)
|
||||
# Ship: Vulture
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
fit.ship.boostItemAttr("shieldThermalDamageResonance", ship.getModifiedItemAttr("shipBonusCBC2"), skill="Caldari Battlecruiser")
|
||||
|
||||
11
eos/effects/siegewarfareshieldcapacitybonusreplacer.py
Normal file
11
eos/effects/siegewarfareshieldcapacitybonusreplacer.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# siegeWarfareShieldCapacityBonusReplacer
|
||||
#
|
||||
# Used by:
|
||||
# Implant: Caldari Navy Warfare Mindlink
|
||||
# Implant: Republic Fleet Warfare Mindlink
|
||||
# Implant: Siege Warfare Mindlink
|
||||
type = "gang"
|
||||
gangBoost = "shieldCapacity"
|
||||
gangBonus = "shieldCapacityBonus"
|
||||
def handler(fit, container, context):
|
||||
fit.ship.boostItemAttr(gangBoost, container.getModifiedItemAttr(gangBonus) * level)
|
||||
@@ -1,9 +1,6 @@
|
||||
# skirmishWarfareAgilityBonus
|
||||
#
|
||||
# Used by:
|
||||
# Implant: Federation Navy Warfare Mindlink
|
||||
# Implant: Republic Fleet Warfare Mindlink
|
||||
# Implant: Skirmish Warfare Mindlink
|
||||
# Skill: Skirmish Warfare
|
||||
type = "gang"
|
||||
gangBoost = "agility"
|
||||
|
||||
11
eos/effects/skirmishwarfareagilitybonusreplacer.py
Normal file
11
eos/effects/skirmishwarfareagilitybonusreplacer.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# skirmishWarfareAgilityBonusReplacer
|
||||
#
|
||||
# Used by:
|
||||
# Implant: Federation Navy Warfare Mindlink
|
||||
# Implant: Republic Fleet Warfare Mindlink
|
||||
# Implant: Skirmish Warfare Mindlink
|
||||
type = "gang"
|
||||
gangBoost = "agility"
|
||||
gangBonus = "agilityBonus"
|
||||
def handler(fit, container, context):
|
||||
fit.ship.boostItemAttr(gangBoost, container.getModifiedItemAttr(gangBonus) * level)
|
||||
@@ -2,6 +2,8 @@
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Coercer
|
||||
# Ship: Gold Magnate
|
||||
# Ship: Silver Magnate
|
||||
type = "passive"
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Small Energy Turret"),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# thermalShieldCompensationHardeningBonusGroupShieldAmp
|
||||
#
|
||||
# Used by:
|
||||
# Skill: Thermic Shield Compensation
|
||||
# Skill: Thermal Shield Compensation
|
||||
type = "passive"
|
||||
def handler(fit, skill, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Shield Amplifier",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# thermicArmorCompensationHardeningBonusGroupArmorCoating
|
||||
#
|
||||
# Used by:
|
||||
# Skill: Thermic Armor Compensation
|
||||
# Skill: Thermal Armor Compensation
|
||||
type = "passive"
|
||||
def handler(fit, skill, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Armor Coating",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# thermicArmorCompensationHardeningBonusGroupEnergized
|
||||
#
|
||||
# Used by:
|
||||
# Skill: Thermic Armor Compensation
|
||||
# Skill: Thermal Armor Compensation
|
||||
type = "passive"
|
||||
def handler(fit, skill, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Armor Plating Energized",
|
||||
|
||||
@@ -9,7 +9,8 @@ def handler(fit, module, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Remote Armor Repair Systems"),
|
||||
"duration", module.getModifiedItemAttr("remoteArmorDamageDurationBonus"))
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Remote Armor Repair Systems"),
|
||||
"armorDamageAmount", module.getModifiedItemAttr("remoteArmorDamageAmountBonus"))
|
||||
"armorDamageAmount", module.getModifiedItemAttr("remoteArmorDamageAmountBonus"),
|
||||
stackingPenalties=True)
|
||||
|
||||
# Remote hull reppers
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Remote Hull Repair Systems"),
|
||||
@@ -19,7 +20,8 @@ def handler(fit, module, context):
|
||||
|
||||
# Shield Transporters
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Shield Emission Systems"),
|
||||
"shieldBonus", module.getModifiedItemAttr("shieldTransportAmountBonus"))
|
||||
"shieldBonus", module.getModifiedItemAttr("shieldTransportAmountBonus"),
|
||||
stackingPenalties=True)
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Shield Emission Systems"),
|
||||
"duration", module.getModifiedItemAttr("shieldTransportDurationBonus"))
|
||||
|
||||
@@ -34,26 +36,29 @@ def handler(fit, module, context):
|
||||
"shieldBonus", module.getModifiedItemAttr("shieldBoostMultiplier"),
|
||||
stackingPenalties=True)
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Shield Operation"),
|
||||
"duration", module.getModifiedItemAttr("shieldBonusDurationBonus"),
|
||||
stackingPenalties=True)
|
||||
"duration", module.getModifiedItemAttr("shieldBonusDurationBonus"))
|
||||
|
||||
# Armor reps
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Armor Repair Unit",
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Repair Systems"),
|
||||
"armorDamageAmount", module.getModifiedItemAttr("armorDamageAmountBonus"))
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Armor Repair Unit",
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Repair Systems"),
|
||||
"duration", module.getModifiedItemAttr("armorDamageDurationBonus"))
|
||||
|
||||
# Speed bonus
|
||||
fit.ship.boostItemAttr("maxVelocity", module.getModifiedItemAttr("speedFactor"))
|
||||
fit.ship.boostItemAttr("maxVelocity", module.getModifiedItemAttr("speedFactor"),
|
||||
stackingPenalties=True)
|
||||
|
||||
# Scan resolution multiplier
|
||||
fit.ship.multiplyItemAttr("scanResolution", module.getModifiedItemAttr("scanResolutionMultiplier"))
|
||||
fit.ship.multiplyItemAttr("scanResolution", module.getModifiedItemAttr("scanResolutionMultiplier"),
|
||||
stackingPenalties=True)
|
||||
|
||||
# Mass multiplier
|
||||
fit.ship.multiplyItemAttr("mass", module.getModifiedItemAttr("massMultiplier"))
|
||||
fit.ship.multiplyItemAttr("mass", module.getModifiedItemAttr("massMultiplier"),
|
||||
stackingPenalties=True)
|
||||
|
||||
# Lock range
|
||||
fit.ship.multiplyItemAttr("maxTargetRange", module.getModifiedItemAttr("maxTargetRangeMultiplier"))
|
||||
fit.ship.multiplyItemAttr("maxTargetRange", module.getModifiedItemAttr("maxTargetRangeMultiplier"),
|
||||
stackingPenalties=True)
|
||||
|
||||
# Max locked targets
|
||||
fit.ship.increaseItemAttr("maxLockedTargets", module.getModifiedItemAttr("maxLockedTargetsBonus"))
|
||||
@@ -61,3 +66,16 @@ def handler(fit, module, context):
|
||||
# Block EWAR & projected effects
|
||||
fit.ship.forceItemAttr("disallowOffensiveModifiers", module.getModifiedItemAttr("disallowOffensiveModifiers"))
|
||||
fit.ship.forceItemAttr("disallowAssistance", module.getModifiedItemAttr("disallowAssistance"))
|
||||
|
||||
# EW cap need increase
|
||||
groups = [
|
||||
'ECM Burst',
|
||||
'Remote ECM Burst',
|
||||
'Tracking Disruptor',
|
||||
'ECM',
|
||||
'Remote Sensor Damper',
|
||||
'Target Painter']
|
||||
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name in groups or
|
||||
mod.item.requiresSkill("Propulsion Jamming"),
|
||||
"capacitorNeed", module.getModifiedItemAttr("ewCapacitorNeedBonus"))
|
||||
|
||||
@@ -9,7 +9,8 @@ def handler(fit, module, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Remote Armor Repair Systems"),
|
||||
"duration", module.getModifiedItemAttr("remoteArmorDamageDurationBonus"))
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Remote Armor Repair Systems"),
|
||||
"armorDamageAmount", module.getModifiedItemAttr("remoteArmorDamageAmountBonus"))
|
||||
"armorDamageAmount", module.getModifiedItemAttr("remoteArmorDamageAmountBonus"),
|
||||
stackingPenalties=True)
|
||||
|
||||
# Remote hull reppers
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Remote Hull Repair Systems"),
|
||||
@@ -19,7 +20,8 @@ def handler(fit, module, context):
|
||||
|
||||
# Shield Transporters
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Shield Emission Systems"),
|
||||
"shieldBonus", module.getModifiedItemAttr("shieldTransportAmountBonus"))
|
||||
"shieldBonus", module.getModifiedItemAttr("shieldTransportAmountBonus"),
|
||||
stackingPenalties=True)
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Shield Emission Systems"),
|
||||
"duration", module.getModifiedItemAttr("shieldTransportDurationBonus"))
|
||||
|
||||
@@ -34,26 +36,29 @@ def handler(fit, module, context):
|
||||
"shieldBonus", module.getModifiedItemAttr("shieldBoostMultiplier"),
|
||||
stackingPenalties=True)
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Shield Operation"),
|
||||
"duration", module.getModifiedItemAttr("shieldBonusDurationBonus"),
|
||||
stackingPenalties=True)
|
||||
"duration", module.getModifiedItemAttr("shieldBonusDurationBonus"))
|
||||
|
||||
# Armor reps
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Armor Repair Unit",
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Repair Systems"),
|
||||
"armorDamageAmount", module.getModifiedItemAttr("armorDamageAmountBonus"))
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Armor Repair Unit",
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Repair Systems"),
|
||||
"duration", module.getModifiedItemAttr("armorDamageDurationBonus"))
|
||||
|
||||
# Speed bonus
|
||||
fit.ship.boostItemAttr("maxVelocity", module.getModifiedItemAttr("speedFactor"))
|
||||
fit.ship.boostItemAttr("maxVelocity", module.getModifiedItemAttr("speedFactor"),
|
||||
stackingPenalties=True)
|
||||
|
||||
# Scan resolution multiplier
|
||||
fit.ship.multiplyItemAttr("scanResolution", module.getModifiedItemAttr("scanResolutionMultiplier"))
|
||||
fit.ship.multiplyItemAttr("scanResolution", module.getModifiedItemAttr("scanResolutionMultiplier"),
|
||||
stackingPenalties=True)
|
||||
|
||||
# Mass multiplier
|
||||
fit.ship.multiplyItemAttr("mass", module.getModifiedItemAttr("massMultiplier"))
|
||||
fit.ship.multiplyItemAttr("mass", module.getModifiedItemAttr("massMultiplier"),
|
||||
stackingPenalties=True)
|
||||
|
||||
# Lock range
|
||||
fit.ship.multiplyItemAttr("maxTargetRange", module.getModifiedItemAttr("maxTargetRangeMultiplier"))
|
||||
fit.ship.multiplyItemAttr("maxTargetRange", module.getModifiedItemAttr("maxTargetRangeMultiplier"),
|
||||
stackingPenalties=True)
|
||||
|
||||
# Max locked targets
|
||||
fit.ship.increaseItemAttr("maxLockedTargets", module.getModifiedItemAttr("maxLockedTargetsBonus"))
|
||||
@@ -69,3 +74,18 @@ def handler(fit, module, context):
|
||||
"capacitorNeed", module.getModifiedItemAttr("triageRemoteModuleCapNeed"))
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Shield Emission Systems"),
|
||||
"capacitorNeed", module.getModifiedItemAttr("triageRemoteModuleCapNeed"))
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Capacitor Emission Systems"),
|
||||
"capacitorNeed", module.getModifiedItemAttr("triageRemoteModuleCapNeed"))
|
||||
|
||||
# EW cap need increase
|
||||
groups = [
|
||||
'ECM Burst',
|
||||
'Remote ECM Burst',
|
||||
'Tracking Disruptor',
|
||||
'ECM',
|
||||
'Remote Sensor Damper',
|
||||
'Target Painter']
|
||||
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name in groups or
|
||||
mod.item.requiresSkill("Propulsion Jamming"),
|
||||
"capacitorNeed", module.getModifiedItemAttr("ewCapacitorNeedBonus"))
|
||||
|
||||
@@ -24,6 +24,7 @@ from sqlalchemy.orm import reconstructor
|
||||
from eqBase import EqBase
|
||||
|
||||
import traceback
|
||||
import eos.db
|
||||
|
||||
try:
|
||||
from collections import OrderedDict
|
||||
@@ -168,7 +169,6 @@ class Item(EqBase):
|
||||
info = getattr(cls, "MOVE_ATTR_INFO", None)
|
||||
if info is None:
|
||||
cls.MOVE_ATTR_INFO = info = []
|
||||
import eos.db
|
||||
for id in cls.MOVE_ATTRS:
|
||||
info.append(eos.db.getAttributeInfo(id))
|
||||
|
||||
@@ -191,6 +191,7 @@ class Item(EqBase):
|
||||
self.__moved = False
|
||||
self.__offensive = None
|
||||
self.__assistive = None
|
||||
self.__overrides = None
|
||||
|
||||
@property
|
||||
def attributes(self):
|
||||
@@ -210,6 +211,32 @@ class Item(EqBase):
|
||||
|
||||
return False
|
||||
|
||||
@property
|
||||
def overrides(self):
|
||||
if self.__overrides is None:
|
||||
self.__overrides = {}
|
||||
overrides = eos.db.getOverrides(self.ID)
|
||||
for x in overrides:
|
||||
if x.attr.name in self.__attributes:
|
||||
self.__overrides[x.attr.name] = x
|
||||
|
||||
return self.__overrides
|
||||
|
||||
def setOverride(self, attr, value):
|
||||
from eos.saveddata.override import Override
|
||||
if attr.name in self.__overrides:
|
||||
override = self.__overrides.get(attr.name)
|
||||
override.value = value
|
||||
else:
|
||||
override = Override(self, attr, value)
|
||||
self.__overrides[attr.name] = override
|
||||
eos.db.save(override)
|
||||
|
||||
def deleteOverride(self, attr):
|
||||
override = self.__overrides.pop(attr.name, None)
|
||||
eos.db.saveddata_session.delete(override)
|
||||
eos.db.commit()
|
||||
|
||||
@property
|
||||
def requiredSkills(self):
|
||||
if self.__requiredSkills is None:
|
||||
@@ -345,6 +372,12 @@ class Item(EqBase):
|
||||
|
||||
return False
|
||||
|
||||
def __repr__(self):
|
||||
return "Item(ID={}, name={}) at {}".format(
|
||||
self.ID, self.name, hex(id(self))
|
||||
)
|
||||
|
||||
|
||||
class MetaData(EqBase):
|
||||
pass
|
||||
|
||||
|
||||
@@ -43,7 +43,8 @@ class FitDpsGraph(Graph):
|
||||
if "ewTargetPaint" in mod.item.effects:
|
||||
ew['signatureRadius'].append(1+(mod.getModifiedItemAttr("signatureRadiusBonus") / 100))
|
||||
if "decreaseTargetSpeed" in mod.item.effects:
|
||||
ew['velocity'].append(1+(mod.getModifiedItemAttr("speedFactor") / 100))
|
||||
if distance <= mod.getModifiedItemAttr("maxRange"):
|
||||
ew['velocity'].append(1+(mod.getModifiedItemAttr("speedFactor") / 100))
|
||||
|
||||
ew['signatureRadius'].sort(key=abssort)
|
||||
ew['velocity'].sort(key=abssort)
|
||||
|
||||
@@ -38,6 +38,9 @@ class ChargeAttrShortcut(object):
|
||||
return None
|
||||
|
||||
class ModifiedAttributeDict(collections.MutableMapping):
|
||||
|
||||
OVERRIDES = False
|
||||
|
||||
class CalculationPlaceholder():
|
||||
pass
|
||||
|
||||
@@ -51,6 +54,8 @@ class ModifiedAttributeDict(collections.MutableMapping):
|
||||
self.__modified = {}
|
||||
# Affected by entities
|
||||
self.__affectedBy = {}
|
||||
# Overrides
|
||||
self.__overrides = {}
|
||||
# Dictionaries for various value modification types
|
||||
self.__forced = {}
|
||||
self.__preAssigns = {}
|
||||
@@ -79,6 +84,14 @@ class ModifiedAttributeDict(collections.MutableMapping):
|
||||
self.__original = val
|
||||
self.__modified.clear()
|
||||
|
||||
@property
|
||||
def overrides(self):
|
||||
return self.__overrides
|
||||
|
||||
@overrides.setter
|
||||
def overrides(self, val):
|
||||
self.__overrides = val
|
||||
|
||||
def __getitem__(self, key):
|
||||
# Check if we have final calculated value
|
||||
if key in self.__modified:
|
||||
@@ -99,6 +112,8 @@ class ModifiedAttributeDict(collections.MutableMapping):
|
||||
del self.__intermediary[key]
|
||||
|
||||
def getOriginal(self, key):
|
||||
if self.OVERRIDES and key in self.__overrides:
|
||||
return self.__overrides.get(key).value
|
||||
val = self.__original.get(key)
|
||||
if val is None:
|
||||
return None
|
||||
@@ -285,7 +300,7 @@ class ModifiedAttributeDict(collections.MutableMapping):
|
||||
else:
|
||||
if not attributeName in self.__multipliers:
|
||||
self.__multipliers[attributeName] = 1
|
||||
self.__multipliers[attributeName] *= multiplier
|
||||
self.__multipliers[attributeName] *= multiplier if multiplier is not None else 1
|
||||
self.__placehold(attributeName)
|
||||
self.__afflict(attributeName, "%s*" % ("s" if stackingPenalties else ""), multiplier, multiplier != 1)
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ class Booster(HandledItem, ItemAttrShortcut):
|
||||
self.__sideEffects = []
|
||||
self.__itemModifiedAttributes = ModifiedAttributeDict()
|
||||
self.__itemModifiedAttributes.original = self.__item.attributes
|
||||
self.__itemModifiedAttributes.overrides = self.__item.overrides
|
||||
self.__slot = self.__calculateSlot(self.__item)
|
||||
|
||||
for effect in self.__item.effects.itervalues():
|
||||
|
||||
@@ -34,6 +34,7 @@ class Cargo(HandledItem, ItemAttrShortcut):
|
||||
self.amount = 0
|
||||
self.__itemModifiedAttributes = ModifiedAttributeDict()
|
||||
self.__itemModifiedAttributes.original = item.attributes
|
||||
self.__itemModifiedAttributes.overrides = item.overrides
|
||||
|
||||
@reconstructor
|
||||
def init(self):
|
||||
@@ -48,6 +49,7 @@ class Cargo(HandledItem, ItemAttrShortcut):
|
||||
|
||||
self.__itemModifiedAttributes = ModifiedAttributeDict()
|
||||
self.__itemModifiedAttributes.original = self.__item.attributes
|
||||
self.__itemModifiedAttributes.overrides = self.__item.overrides
|
||||
|
||||
@property
|
||||
def itemModifiedAttributes(self):
|
||||
|
||||
@@ -23,7 +23,9 @@ from sqlalchemy.orm import validates, reconstructor
|
||||
from eos.effectHandlerHelpers import HandledItem, HandledImplantBoosterList
|
||||
import eos.db
|
||||
import eos
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class Character(object):
|
||||
__itemList = None
|
||||
@@ -221,6 +223,11 @@ class Character(object):
|
||||
if map[key](val) == False: raise ValueError(str(val) + " is not a valid value for " + key)
|
||||
else: return val
|
||||
|
||||
def __repr__(self):
|
||||
return "Character(ID={}, name={}) at {}".format(
|
||||
self.ID, self.name, hex(id(self))
|
||||
)
|
||||
|
||||
class Skill(HandledItem):
|
||||
def __init__(self, item, level=0, ro=False, learned=True):
|
||||
self.__item = item if not isinstance(item, int) else None
|
||||
|
||||
46
eos/saveddata/crestchar.py
Normal file
46
eos/saveddata/crestchar.py
Normal file
@@ -0,0 +1,46 @@
|
||||
#===============================================================================
|
||||
# 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 urllib
|
||||
from cStringIO import StringIO
|
||||
|
||||
from sqlalchemy.orm import reconstructor
|
||||
#from tomorrow import threads
|
||||
|
||||
|
||||
class CrestChar(object):
|
||||
|
||||
def __init__(self, id, name, refresh_token=None):
|
||||
self.ID = id
|
||||
self.name = name
|
||||
self.refresh_token = refresh_token
|
||||
|
||||
@reconstructor
|
||||
def init(self):
|
||||
pass
|
||||
|
||||
'''
|
||||
@threads(1)
|
||||
def fetchImage(self):
|
||||
url = 'https://image.eveonline.com/character/%d_128.jpg'%self.ID
|
||||
fp = urllib.urlopen(url)
|
||||
data = fp.read()
|
||||
fp.close()
|
||||
self.img = StringIO(data)
|
||||
'''
|
||||
@@ -67,6 +67,7 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
self.__miningyield = None
|
||||
self.__itemModifiedAttributes = ModifiedAttributeDict()
|
||||
self.__itemModifiedAttributes.original = self.__item.attributes
|
||||
self.__itemModifiedAttributes.overrides = self.__item.overrides
|
||||
|
||||
self.__chargeModifiedAttributes = ModifiedAttributeDict()
|
||||
chargeID = self.getModifiedItemAttr("entityMissileTypeID")
|
||||
@@ -74,6 +75,7 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
charge = eos.db.getItem(int(chargeID))
|
||||
self.__charge = charge
|
||||
self.__chargeModifiedAttributes.original = charge.attributes
|
||||
self.__chargeModifiedAttributes.overrides = charge.overrides
|
||||
|
||||
@property
|
||||
def itemModifiedAttributes(self):
|
||||
|
||||
@@ -25,7 +25,7 @@ from eos import capSim
|
||||
from copy import deepcopy
|
||||
from math import sqrt, log, asinh
|
||||
from eos.types import Drone, Cargo, Ship, Character, State, Slot, Module, Implant, Booster, Skill
|
||||
from eos.saveddata.module import State
|
||||
from eos.saveddata.module import State, Hardpoint
|
||||
from eos.saveddata.mode import Mode
|
||||
import eos.db
|
||||
import time
|
||||
@@ -390,9 +390,9 @@ class Fit(object):
|
||||
self.__modifier = currModifier
|
||||
self.__origin = origin
|
||||
if hasattr(currModifier, "itemModifiedAttributes"):
|
||||
currModifier.itemModifiedAttributes.fit = self
|
||||
currModifier.itemModifiedAttributes.fit = origin or self
|
||||
if hasattr(currModifier, "chargeModifiedAttributes"):
|
||||
currModifier.chargeModifiedAttributes.fit = self
|
||||
currModifier.chargeModifiedAttributes.fit = origin or self
|
||||
|
||||
def getModifier(self):
|
||||
return self.__modifier
|
||||
@@ -480,17 +480,22 @@ class Fit(object):
|
||||
self.__calculated = True
|
||||
|
||||
for runTime in ("early", "normal", "late"):
|
||||
c = chain(
|
||||
# Items that are unrestricted. These items are run on the local fit
|
||||
# first and then projected onto the target fit it one is designated
|
||||
u = [
|
||||
(self.character, self.ship),
|
||||
self.drones,
|
||||
self.boosters,
|
||||
self.appliedImplants,
|
||||
self.modules
|
||||
)
|
||||
]
|
||||
|
||||
if not projected:
|
||||
# if not a projected fit, add a couple of more things
|
||||
c = chain(c, (self.mode,), self.projectedDrones, self.projectedModules)
|
||||
# Items that are restricted. These items are only run on the local
|
||||
# fit. They are NOT projected onto the target fit. # See issue 354
|
||||
r = [(self.mode,), self.projectedDrones, self.projectedModules]
|
||||
|
||||
# chain unrestricted and restricted into one iterable
|
||||
c = chain.from_iterable(u+r)
|
||||
|
||||
# We calculate gang bonuses first so that projected fits get them
|
||||
if self.gangBoosts is not None:
|
||||
@@ -500,9 +505,12 @@ class Fit(object):
|
||||
# Registering the item about to affect the fit allows us to
|
||||
# track "Affected By" relations correctly
|
||||
if item is not None:
|
||||
# apply effects locally
|
||||
self.register(item)
|
||||
item.calculateModifiedAttributes(self, runTime, False)
|
||||
if projected is True:
|
||||
|
||||
if projected is True and item not in chain.from_iterable(r):
|
||||
# apply effects onto target fit
|
||||
for _ in xrange(projectionInfo.amount):
|
||||
targetFit.register(item, origin=self)
|
||||
item.calculateModifiedAttributes(targetFit, runTime, True)
|
||||
@@ -839,10 +847,14 @@ class Fit(object):
|
||||
else:
|
||||
capAdded -= capNeed
|
||||
|
||||
drains.append((int(fullCycleTime), mod.getModifiedItemAttr("capacitorNeed") or 0, mod.numShots or 0))
|
||||
# If this is a turret, don't stagger activations
|
||||
disableStagger = mod.hardpoint == Hardpoint.TURRET
|
||||
|
||||
drains.append((int(fullCycleTime), mod.getModifiedItemAttr("capacitorNeed") or 0, mod.numShots or 0, disableStagger))
|
||||
|
||||
for fullCycleTime, capNeed, clipSize in self.iterDrains():
|
||||
drains.append((int(fullCycleTime), capNeed, clipSize))
|
||||
# Stagger incoming effects for cap simulation
|
||||
drains.append((int(fullCycleTime), capNeed, clipSize, False))
|
||||
if capNeed > 0:
|
||||
capUsed += capNeed / (fullCycleTime / 1000.0)
|
||||
else:
|
||||
|
||||
@@ -56,6 +56,7 @@ class Implant(HandledItem, ItemAttrShortcut):
|
||||
""" Build object. Assumes proper and valid item already set """
|
||||
self.__itemModifiedAttributes = ModifiedAttributeDict()
|
||||
self.__itemModifiedAttributes.original = self.__item.attributes
|
||||
self.__itemModifiedAttributes.overrides = self.__item.overrides
|
||||
self.__slot = self.__calculateSlot(self.__item)
|
||||
|
||||
@property
|
||||
|
||||
@@ -30,6 +30,7 @@ class Mode(ItemAttrShortcut, HandledItem):
|
||||
self.__item = item
|
||||
self.__itemModifiedAttributes = ModifiedAttributeDict()
|
||||
self.__itemModifiedAttributes.original = self.item.attributes
|
||||
self.__itemModifiedAttributes.overrides = self.item.overrides
|
||||
|
||||
@property
|
||||
def item(self):
|
||||
|
||||
@@ -113,10 +113,13 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
|
||||
if self.__item:
|
||||
self.__itemModifiedAttributes.original = self.__item.attributes
|
||||
self.__itemModifiedAttributes.overrides = self.__item.overrides
|
||||
self.__hardpoint = self.__calculateHardpoint(self.__item)
|
||||
self.__slot = self.__calculateSlot(self.__item)
|
||||
if self.__charge:
|
||||
self.__chargeModifiedAttributes.original = self.__charge.attributes
|
||||
self.__chargeModifiedAttributes.overrides = self.__charge.overrides
|
||||
|
||||
|
||||
@classmethod
|
||||
def buildEmpty(cls, slot):
|
||||
@@ -283,9 +286,11 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
if charge is not None:
|
||||
self.chargeID = charge.ID
|
||||
self.__chargeModifiedAttributes.original = charge.attributes
|
||||
self.__chargeModifiedAttributes.overrides = charge.overrides
|
||||
else:
|
||||
self.chargeID = None
|
||||
self.__chargeModifiedAttributes.original = None
|
||||
self.__chargeModifiedAttributes.overrides = {}
|
||||
|
||||
self.__itemModifiedAttributes.clear()
|
||||
|
||||
@@ -316,7 +321,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
self.__miningyield = 0
|
||||
else:
|
||||
if self.state >= State.ACTIVE:
|
||||
volley = sum(map(lambda attr: self.getModifiedItemAttr(attr) or 0, self.MINING_ATTRIBUTES))
|
||||
volley = self.getModifiedItemAttr("specialtyMiningAmount") or self.getModifiedItemAttr("miningAmount") or 0
|
||||
if volley:
|
||||
cycleTime = self.cycleTime
|
||||
self.__miningyield = volley / (cycleTime / 1000.0)
|
||||
|
||||
59
eos/saveddata/override.py
Normal file
59
eos/saveddata/override.py
Normal file
@@ -0,0 +1,59 @@
|
||||
#===============================================================================
|
||||
# Copyright (C) 2015 Ryan Holmes
|
||||
#
|
||||
# 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 eos.eqBase import EqBase
|
||||
from sqlalchemy.orm import validates, reconstructor
|
||||
import eos.db
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class Override(EqBase):
|
||||
|
||||
def __init__(self, item, attr, value):
|
||||
self.itemID = item.ID
|
||||
self.__item = item
|
||||
self.attrID = attr.ID
|
||||
self.__attr = attr
|
||||
self.value = value
|
||||
|
||||
@reconstructor
|
||||
def init(self):
|
||||
self.__attr = None
|
||||
self.__item = None
|
||||
|
||||
if self.attrID:
|
||||
self.__attr = eos.db.getAttributeInfo(self.attrID)
|
||||
if self.__attr is None:
|
||||
logger.error("Attribute (id: %d) does not exist", self.attrID)
|
||||
return
|
||||
|
||||
if self.itemID:
|
||||
self.__item = eos.db.getItem(self.itemID)
|
||||
if self.__item is None:
|
||||
logger.error("Item (id: %d) does not exist", self.itemID)
|
||||
return
|
||||
|
||||
@property
|
||||
def attr(self):
|
||||
return self.__attr
|
||||
|
||||
@property
|
||||
def item(self):
|
||||
return self.__item
|
||||
@@ -51,6 +51,7 @@ class Ship(ItemAttrShortcut, HandledItem):
|
||||
self.__itemModifiedAttributes = ModifiedAttributeDict()
|
||||
self.__itemModifiedAttributes.original = dict(self.item.attributes)
|
||||
self.__itemModifiedAttributes.original.update(self.EXTRA_ATTRIBUTES)
|
||||
self.__itemModifiedAttributes.overrides = self.item.overrides
|
||||
|
||||
self.commandBonus = 0
|
||||
|
||||
@@ -121,3 +122,8 @@ class Ship(ItemAttrShortcut, HandledItem):
|
||||
def __deepcopy__(self, memo):
|
||||
copy = Ship(self.item)
|
||||
return copy
|
||||
|
||||
def __repr__(self):
|
||||
return "Ship(ID={}, name={}) at {}".format(
|
||||
self.item.ID, self.item.name, hex(id(self))
|
||||
)
|
||||
|
||||
@@ -21,6 +21,7 @@ from eos.gamedata import Attribute, Category, Effect, Group, Icon, Item, MarketG
|
||||
MetaGroup, AttributeInfo, Unit, EffectInfo, MetaType, MetaData, Traits
|
||||
from eos.saveddata.price import Price
|
||||
from eos.saveddata.user import User
|
||||
from eos.saveddata.crestchar import CrestChar
|
||||
from eos.saveddata.damagePattern import DamagePattern
|
||||
from eos.saveddata.targetResists import TargetResists
|
||||
from eos.saveddata.character import Character, Skill
|
||||
@@ -35,4 +36,5 @@ from eos.saveddata.fit import Fit
|
||||
from eos.saveddata.mode import Mode
|
||||
from eos.saveddata.fleet import Fleet, Wing, Squad
|
||||
from eos.saveddata.miscData import MiscData
|
||||
from eos.saveddata.override import Override
|
||||
import eos.db
|
||||
|
||||
Binary file not shown.
@@ -1,7 +1,7 @@
|
||||
import wx
|
||||
import gui.utils.colorUtils as colorUtils
|
||||
import gui.utils.drawUtils as drawUtils
|
||||
from gui import bitmapLoader
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
|
||||
|
||||
SearchButton, EVT_SEARCH_BTN = wx.lib.newevent.NewEvent()
|
||||
@@ -11,7 +11,7 @@ TextTyped, EVT_TEXT = wx.lib.newevent.NewEvent()
|
||||
|
||||
class PFSearchBox(wx.Window):
|
||||
def __init__(self, parent, id = wx.ID_ANY, value = "", pos = wx.DefaultPosition, size = wx.Size(-1,24), style = 0):
|
||||
wx.Window.__init__(self, parent, id, pos, size, style = 0)
|
||||
wx.Window.__init__(self, parent, id, pos, size, style = style)
|
||||
|
||||
self.isSearchButtonVisible = False
|
||||
self.isCancelButtonVisible = False
|
||||
@@ -49,10 +49,6 @@ class PFSearchBox(wx.Window):
|
||||
|
||||
self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
|
||||
self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
|
||||
self.Bind(wx.EVT_MOTION, self.OnMouseMove)
|
||||
|
||||
self.Bind(wx.EVT_ENTER_WINDOW, self.OnEnterLeaveWindow)
|
||||
self.Bind(wx.EVT_LEAVE_WINDOW, self.OnEnterLeaveWindow)
|
||||
|
||||
# self.EditBox.ChangeValue(self.descriptiveText)
|
||||
|
||||
@@ -64,25 +60,26 @@ class PFSearchBox(wx.Window):
|
||||
|
||||
self.SetMinSize(size)
|
||||
|
||||
def OnEnterLeaveWindow(self, event):
|
||||
self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
|
||||
self._hl = False
|
||||
|
||||
def OnText(self, event):
|
||||
wx.PostEvent(self, TextTyped())
|
||||
event.Skip()
|
||||
|
||||
def OnTextEnter(self, event):
|
||||
wx.PostEvent(self, TextEnter())
|
||||
event.Skip()
|
||||
|
||||
|
||||
def OnEditSetFocus(self, event):
|
||||
# value = self.EditBox.GetValue()
|
||||
# if value == self.descriptiveText:
|
||||
# self.EditBox.ChangeValue("")
|
||||
pass
|
||||
event.Skip()
|
||||
|
||||
def OnEditKillFocus(self, event):
|
||||
if self.EditBox.GetValue() == "":
|
||||
self.Clear()
|
||||
event.Skip()
|
||||
|
||||
|
||||
def Clear(self):
|
||||
self.EditBox.Clear()
|
||||
@@ -138,20 +135,6 @@ class PFSearchBox(wx.Window):
|
||||
btnsize.append( (cw,ch))
|
||||
return btnsize
|
||||
|
||||
def OnMouseMove(self, event):
|
||||
btnpos = self.GetButtonsPos()
|
||||
btnsize = self.GetButtonsSize()
|
||||
for btn in xrange(2):
|
||||
if self.HitTest(btnpos[btn], event.GetPosition(), btnsize[btn]):
|
||||
if not self._hl:
|
||||
self.SetCursor(wx.StockCursor(wx.CURSOR_HAND))
|
||||
self._hl = True
|
||||
break
|
||||
else:
|
||||
if self._hl:
|
||||
self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
|
||||
self._hl = False
|
||||
|
||||
def OnLeftDown(self, event):
|
||||
btnpos = self.GetButtonsPos()
|
||||
btnsize = self.GetButtonsSize()
|
||||
|
||||
@@ -20,7 +20,7 @@ import config
|
||||
|
||||
versionString = "{0} {1} - {2} {3}".format(config.version, config.tag, config.expansionName, config.expansionVersion)
|
||||
licenses = (
|
||||
"pyfa is released under GNU GPLv3 - see included gpl.txt",
|
||||
"pyfa is released under GNU GPLv3 - see included LICENSE file",
|
||||
"All EVE-Online related materials are property of CCP hf.",
|
||||
"Silk Icons Set by famfamfam.com - Creative Commons Attribution 2.5 License",
|
||||
"Fat Cow Icons by fatcow.com - Creative Commons Attribution 3.0 License"
|
||||
|
||||
@@ -26,7 +26,7 @@ from gui.implantView import ImplantView
|
||||
from gui.projectedView import ProjectedView
|
||||
from gui.pyfatogglepanel import TogglePanel
|
||||
from gui.gangView import GangView
|
||||
from gui import bitmapLoader
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
|
||||
import gui.chromeTabs
|
||||
|
||||
@@ -45,18 +45,16 @@ class AdditionsPane(TogglePanel):
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
self.notebook = gui.chromeTabs.PFNotebook(pane, False)
|
||||
size = wx.Size()
|
||||
# This size lets you see 4 drones at a time
|
||||
size.SetHeight(180)
|
||||
self.notebook.SetMinSize(size)
|
||||
self.notebook.SetMinSize((-1, 1000))
|
||||
|
||||
baseSizer.Add(self.notebook, 1, wx.EXPAND)
|
||||
|
||||
droneImg = bitmapLoader.getImage("drone_small", "icons")
|
||||
implantImg = bitmapLoader.getImage("implant_small", "icons")
|
||||
boosterImg = bitmapLoader.getImage("booster_small", "icons")
|
||||
projectedImg = bitmapLoader.getImage("projected_small", "icons")
|
||||
gangImg = bitmapLoader.getImage("fleet_fc_small", "icons")
|
||||
cargoImg = bitmapLoader.getImage("cargo_small", "icons")
|
||||
droneImg = BitmapLoader.getImage("drone_small", "gui")
|
||||
implantImg = BitmapLoader.getImage("implant_small", "gui")
|
||||
boosterImg = BitmapLoader.getImage("booster_small", "gui")
|
||||
projectedImg = BitmapLoader.getImage("projected_small", "gui")
|
||||
gangImg = BitmapLoader.getImage("fleet_fc_small", "gui")
|
||||
cargoImg = BitmapLoader.getImage("cargo_small", "gui")
|
||||
|
||||
self.notebook.AddPage(DroneView(self.notebook), "Drones", tabImage = droneImg, showClose = False)
|
||||
self.notebook.AddPage(CargoView(self.notebook), "Cargo", tabImage = cargoImg, showClose = False)
|
||||
@@ -76,3 +74,21 @@ class AdditionsPane(TogglePanel):
|
||||
|
||||
def getName(self, idx):
|
||||
return self.PANES[idx]
|
||||
|
||||
def toggleContent(self, event):
|
||||
TogglePanel.toggleContent(self, event)
|
||||
h = self.headerPanel.GetSize()[1]+4
|
||||
|
||||
if self.IsCollapsed():
|
||||
self.old_pos = self.parent.GetSashPosition()
|
||||
self.parent.SetMinimumPaneSize(h)
|
||||
self.parent.SetSashPosition(h*-1, True)
|
||||
# only available in >= wx2.9
|
||||
if getattr(self.parent, "SetSashInvisible", None):
|
||||
self.parent.SetSashInvisible(True)
|
||||
else:
|
||||
if getattr(self.parent, "SetSashInvisible", None):
|
||||
self.parent.SetSashInvisible(False)
|
||||
self.parent.SetMinimumPaneSize(200)
|
||||
self.parent.SetSashPosition(self.old_pos, True)
|
||||
|
||||
|
||||
@@ -20,87 +20,74 @@
|
||||
import os.path
|
||||
import config
|
||||
import wx
|
||||
import time
|
||||
import zipfile
|
||||
import cStringIO
|
||||
|
||||
try:
|
||||
from collections import OrderedDict
|
||||
except ImportError:
|
||||
from utils.compat import OrderedDict
|
||||
|
||||
cachedBitmapsCount = 0
|
||||
cachedBitmaps = OrderedDict()
|
||||
dontUseCachedBitmaps = False
|
||||
class BitmapLoader():
|
||||
|
||||
def getStaticBitmap(name, parent, location):
|
||||
static = wx.StaticBitmap(parent)
|
||||
static.SetBitmap(getBitmap(name,location))
|
||||
return static
|
||||
try:
|
||||
archive = zipfile.ZipFile(os.path.join(config.pyfaPath, 'imgs.zip'), 'r')
|
||||
except IOError:
|
||||
archive = None
|
||||
|
||||
locationMap = {"pack": os.path.join(config.staticPath, "icons"),
|
||||
"ships": os.path.join(config.staticPath, "icons/ships")}
|
||||
cachedBitmaps = OrderedDict()
|
||||
dontUseCachedBitmaps = False
|
||||
max_bmps = 500
|
||||
|
||||
def getBitmap(name,location):
|
||||
@classmethod
|
||||
def getStaticBitmap(cls, name, parent, location):
|
||||
static = wx.StaticBitmap(parent)
|
||||
static.SetBitmap(cls.getBitmap(name,location))
|
||||
return static
|
||||
|
||||
global cachedBitmaps
|
||||
global cachedBitmapsCount
|
||||
global dontUseCachedBitmaps
|
||||
@classmethod
|
||||
def getBitmap(cls, name, location):
|
||||
if cls.dontUseCachedBitmaps:
|
||||
img = cls.getImage(name, location)
|
||||
if img is not None:
|
||||
return img.ConvertToBitmap()
|
||||
|
||||
if dontUseCachedBitmaps:
|
||||
img = getImage(name, location)
|
||||
if img is not None:
|
||||
return img.ConvertToBitmap()
|
||||
path = "%s%s" % (name, location)
|
||||
|
||||
path = "%s%s" % (name,location)
|
||||
MAX_BMPS = 500
|
||||
# start = time.clock()
|
||||
if cachedBitmapsCount == MAX_BMPS:
|
||||
cachedBitmaps.popitem(False)
|
||||
cachedBitmapsCount -=1
|
||||
if len(cls.cachedBitmaps) == cls.max_bmps:
|
||||
cls.cachedBitmaps.popitem(False)
|
||||
|
||||
if path not in cachedBitmaps:
|
||||
img = getImage(name, location)
|
||||
if img is not None:
|
||||
bmp = img.ConvertToBitmap()
|
||||
if path not in cls.cachedBitmaps:
|
||||
img = cls.getImage(name, location)
|
||||
if img is not None:
|
||||
bmp = img.ConvertToBitmap()
|
||||
else:
|
||||
bmp = None
|
||||
cls.cachedBitmaps[path] = bmp
|
||||
else:
|
||||
bmp = None
|
||||
cachedBitmaps[path] = bmp
|
||||
cachedBitmapsCount += 1
|
||||
else:
|
||||
bmp = cachedBitmaps[path]
|
||||
bmp = cls.cachedBitmaps[path]
|
||||
|
||||
# print "#BMPs:%d - Current took: %.8f" % (cachedBitmapsCount,time.clock() - start)
|
||||
return bmp
|
||||
return bmp
|
||||
|
||||
def stripPath(fname):
|
||||
"""
|
||||
Here we extract 'core' of icon name. Path and
|
||||
extension are sometimes specified in database
|
||||
but we don't need them.
|
||||
"""
|
||||
# Path before the icon file name
|
||||
fname = fname.split('/')[-1]
|
||||
# Extension
|
||||
fname = fname.rsplit('.', 1)[0]
|
||||
return fname
|
||||
|
||||
def getImage(name, location):
|
||||
if location in locationMap:
|
||||
if location == "pack":
|
||||
location = locationMap[location]
|
||||
name = stripPath(name)
|
||||
filename = "icon{0}.png".format(name)
|
||||
path = os.path.join(location, filename)
|
||||
else:
|
||||
location = locationMap[location]
|
||||
filename = "{0}.png".format(name)
|
||||
path = os.path.join(location, filename)
|
||||
|
||||
else:
|
||||
location = os.path.join(config.pyfaPath, location)
|
||||
@classmethod
|
||||
def getImage(cls, name, location):
|
||||
filename = "{0}.png".format(name)
|
||||
path = os.path.join(location, filename)
|
||||
|
||||
if os.path.exists(path):
|
||||
return wx.Image(path)
|
||||
else:
|
||||
print "Missing icon file: {0}".format(filename)
|
||||
if cls.archive:
|
||||
path = os.path.join(location, filename)
|
||||
if os.sep != "/" and os.sep in path:
|
||||
path = path.replace(os.sep, "/")
|
||||
|
||||
try:
|
||||
img_data = cls.archive.read(path)
|
||||
sbuf = cStringIO.StringIO(img_data)
|
||||
return wx.ImageFromStream(sbuf)
|
||||
except KeyError:
|
||||
print "Missing icon file from zip: {0}".format(path)
|
||||
else:
|
||||
path = os.path.join(config.pyfaPath, 'imgs', location, filename)
|
||||
|
||||
if os.path.exists(path):
|
||||
return wx.Image(path)
|
||||
else:
|
||||
print "Missing icon file: {0}".format(path)
|
||||
|
||||
@@ -20,7 +20,6 @@ class ChangeAmount(ContextMenu):
|
||||
srcContext = fullContext[0]
|
||||
dlg = AmountChanger(self.mainFrame, selection[0], srcContext)
|
||||
dlg.ShowModal()
|
||||
dlg.Destroy()
|
||||
|
||||
ChangeAmount.register()
|
||||
|
||||
@@ -59,7 +58,7 @@ class AmountChanger(wx.Dialog):
|
||||
wx.PostEvent(mainFrame, GE.FitChanged(fitID=fitID))
|
||||
|
||||
event.Skip()
|
||||
self.Destroy()
|
||||
self.Close()
|
||||
|
||||
## checks to make sure it's valid number
|
||||
def onChar(self, event):
|
||||
|
||||
@@ -3,7 +3,7 @@ from gui.contextMenu import ContextMenu
|
||||
import gui.mainFrame
|
||||
import service
|
||||
import wx
|
||||
from gui import bitmapLoader
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from eos.types import Skill
|
||||
import gui.globalEvents as GE
|
||||
|
||||
@@ -74,7 +74,7 @@ class ChangeAffectingSkills(ContextMenu):
|
||||
grandSub = wx.Menu()
|
||||
skillItem.SetSubMenu(grandSub)
|
||||
if skill.learned:
|
||||
bitmap = bitmapLoader.getBitmap("lvl%s" % skill.level, "icons")
|
||||
bitmap = BitmapLoader.getBitmap("lvl%s" % skill.level, "gui")
|
||||
if bitmap is not None:
|
||||
skillItem.SetBitmap(bitmap)
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import gui.mainFrame
|
||||
import service
|
||||
import gui.globalEvents as GE
|
||||
import wx
|
||||
from gui import bitmapLoader
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
|
||||
try:
|
||||
from collections import OrderedDict
|
||||
@@ -65,7 +65,7 @@ class DamagePattern(ContextMenu):
|
||||
dp = f.damagePattern
|
||||
|
||||
if dp == pattern:
|
||||
bitmap = bitmapLoader.getBitmap("state_active_small", "icons")
|
||||
bitmap = BitmapLoader.getBitmap("state_active_small", "gui")
|
||||
menuItem.SetBitmap(bitmap)
|
||||
return menuItem
|
||||
|
||||
@@ -80,7 +80,7 @@ class DamagePattern(ContextMenu):
|
||||
self.patternIds[id] = self.singles[i]
|
||||
rootMenu.Bind(wx.EVT_MENU, self.handlePatternSwitch, pitem)
|
||||
if self.patternIds[id] == self.fit.damagePattern:
|
||||
bitmap = bitmapLoader.getBitmap("state_active_small", "icons")
|
||||
bitmap = BitmapLoader.getBitmap("state_active_small", "gui")
|
||||
pitem.SetBitmap(bitmap)
|
||||
return False
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import gui.mainFrame
|
||||
import service
|
||||
import gui.globalEvents as GE
|
||||
import wx
|
||||
from gui import bitmapLoader
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
|
||||
class FactorReload(ContextMenu):
|
||||
def __init__(self):
|
||||
@@ -27,7 +27,7 @@ class FactorReload(ContextMenu):
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
fit = sFit.getFit(fitID)
|
||||
if fit.factorReload:
|
||||
return bitmapLoader.getBitmap("state_active_small", "icons")
|
||||
return BitmapLoader.getBitmap("state_active_small", "gui")
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ from gui.contextMenu import ContextMenu
|
||||
import gui.mainFrame
|
||||
import service
|
||||
import wx
|
||||
from gui import bitmapLoader
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from eos.types import Hardpoint
|
||||
import gui.globalEvents as GE
|
||||
|
||||
@@ -105,7 +105,7 @@ class ModuleAmmoPicker(ContextMenu):
|
||||
menu.Bind(wx.EVT_MENU, self.handleAmmoSwitch, item)
|
||||
item.charge = charge
|
||||
if charge is not None and charge.icon is not None:
|
||||
bitmap = bitmapLoader.getBitmap(charge.icon.iconFile, "pack")
|
||||
bitmap = BitmapLoader.getBitmap(charge.icon.iconFile, "icons")
|
||||
if bitmap is not None:
|
||||
item.SetBitmap(bitmap)
|
||||
|
||||
@@ -181,7 +181,7 @@ class ModuleAmmoPicker(ContextMenu):
|
||||
|
||||
type = currType
|
||||
item = wx.MenuItem(m, wx.ID_ANY, type.capitalize())
|
||||
bitmap = bitmapLoader.getBitmap("%s_small" % type, "icons")
|
||||
bitmap = BitmapLoader.getBitmap("%s_small" % type, "gui")
|
||||
if bitmap is not None:
|
||||
item.SetBitmap(bitmap)
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ from gui.contextMenu import ContextMenu
|
||||
import gui.mainFrame
|
||||
import service
|
||||
import wx
|
||||
from gui import bitmapLoader
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from eos.types import Hardpoint
|
||||
import gui.globalEvents as GE
|
||||
from gui.builtinContextMenus.moduleAmmoPicker import ModuleAmmoPicker
|
||||
|
||||
@@ -3,7 +3,7 @@ import gui.mainFrame
|
||||
import service
|
||||
import gui.globalEvents as GE
|
||||
import wx
|
||||
from gui import bitmapLoader
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
|
||||
try:
|
||||
from collections import OrderedDict
|
||||
@@ -56,7 +56,7 @@ class TargetResists(ContextMenu):
|
||||
tr = f.targetResists
|
||||
|
||||
if tr == pattern:
|
||||
bitmap = bitmapLoader.getBitmap("state_active_small", "icons")
|
||||
bitmap = BitmapLoader.getBitmap("state_active_small", "gui")
|
||||
item.SetBitmap(bitmap)
|
||||
return item
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
from gui.graph import Graph
|
||||
import service
|
||||
from gui import bitmapLoader
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from eos.graph.fitDps import FitDpsGraph as FitDps
|
||||
from eos.graph import Data
|
||||
import gui.mainFrame
|
||||
@@ -56,7 +56,7 @@ class FitDpsGraph(Graph):
|
||||
sAttr = service.Attribute.getInstance()
|
||||
for key, attrName in self.propertyAttributeMap.iteritems():
|
||||
iconFile = sAttr.getAttributeInfo(attrName).icon.iconFile
|
||||
bitmap = bitmapLoader.getBitmap(iconFile, "pack")
|
||||
bitmap = BitmapLoader.getBitmap(iconFile, "icons")
|
||||
if bitmap:
|
||||
icons[key] = bitmap
|
||||
|
||||
|
||||
@@ -1 +1,6 @@
|
||||
__all__ = ["pyfaGeneralPreferences","pyfaHTMLExportPreferences","pyfaUpdatePreferences","pyfaNetworkPreferences"]
|
||||
|
||||
import wx
|
||||
|
||||
if not 'wxMac' in wx.PlatformInfo or ('wxMac' in wx.PlatformInfo and wx.VERSION >= (3,0)):
|
||||
__all__.append("pyfaCrestPreferences")
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
import wx
|
||||
from gui.preferenceView import PreferenceView
|
||||
from gui import bitmapLoader
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
class DummyView(PreferenceView):
|
||||
title = "Dummy"
|
||||
|
||||
|
||||
120
gui/builtinPreferenceViews/pyfaCrestPreferences.py
Normal file
120
gui/builtinPreferenceViews/pyfaCrestPreferences.py
Normal file
@@ -0,0 +1,120 @@
|
||||
import wx
|
||||
|
||||
from gui.preferenceView import PreferenceView
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
|
||||
import gui.mainFrame
|
||||
import service
|
||||
from service.crest import CrestModes
|
||||
|
||||
class PFCrestPref ( PreferenceView):
|
||||
title = "CREST"
|
||||
|
||||
def populatePanel( self, panel ):
|
||||
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
self.settings = service.settings.CRESTSettings.getInstance()
|
||||
self.dirtySettings = False
|
||||
dlgWidth = panel.GetParent().GetParent().ClientSize.width
|
||||
mainSizer = wx.BoxSizer( wx.VERTICAL )
|
||||
|
||||
self.stTitle = wx.StaticText( panel, wx.ID_ANY, self.title, wx.DefaultPosition, wx.DefaultSize, 0 )
|
||||
self.stTitle.Wrap( -1 )
|
||||
self.stTitle.SetFont( wx.Font( 12, 70, 90, 90, False, wx.EmptyString ) )
|
||||
|
||||
mainSizer.Add( self.stTitle, 0, wx.ALL, 5 )
|
||||
|
||||
self.m_staticline1 = wx.StaticLine( panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL )
|
||||
mainSizer.Add( self.m_staticline1, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 5 )
|
||||
|
||||
self.stInfo = wx.StaticText( panel, wx.ID_ANY, u"Please see the pyfa wiki on GitHub for information regarding these options.", wx.DefaultPosition, wx.DefaultSize, 0 )
|
||||
self.stInfo.Wrap(dlgWidth - 50)
|
||||
mainSizer.Add( self.stInfo, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 5 )
|
||||
|
||||
rbSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
self.rbMode = wx.RadioBox(panel, -1, "Mode", wx.DefaultPosition, wx.DefaultSize, ['Implicit', 'User-supplied details'], 1, wx.RA_SPECIFY_COLS)
|
||||
self.rbServer = wx.RadioBox(panel, -1, "Server", wx.DefaultPosition, wx.DefaultSize, ['Tranquility', 'Singularity'], 1, wx.RA_SPECIFY_COLS)
|
||||
|
||||
self.rbMode.SetSelection(self.settings.get('mode'))
|
||||
self.rbServer.SetSelection(self.settings.get('server'))
|
||||
|
||||
rbSizer.Add(self.rbMode, 1, wx.TOP | wx.RIGHT, 5 )
|
||||
rbSizer.Add(self.rbServer, 1, wx.ALL, 5 )
|
||||
|
||||
self.rbMode.Bind(wx.EVT_RADIOBOX, self.OnModeChange)
|
||||
self.rbServer.Bind(wx.EVT_RADIOBOX, self.OnServerChange)
|
||||
|
||||
mainSizer.Add(rbSizer, 1, wx.ALL|wx.EXPAND, 0)
|
||||
|
||||
detailsTitle = wx.StaticText( panel, wx.ID_ANY, "CREST client details", wx.DefaultPosition, wx.DefaultSize, 0 )
|
||||
detailsTitle.Wrap( -1 )
|
||||
detailsTitle.SetFont( wx.Font( 12, 70, 90, 90, False, wx.EmptyString ) )
|
||||
|
||||
mainSizer.Add( detailsTitle, 0, wx.ALL, 5 )
|
||||
mainSizer.Add( wx.StaticLine( panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ), 0, wx.EXPAND, 5 )
|
||||
|
||||
|
||||
fgAddrSizer = wx.FlexGridSizer( 2, 2, 0, 0 )
|
||||
fgAddrSizer.AddGrowableCol( 1 )
|
||||
fgAddrSizer.SetFlexibleDirection( wx.BOTH )
|
||||
fgAddrSizer.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )
|
||||
|
||||
self.stSetID = wx.StaticText( panel, wx.ID_ANY, u"Client ID:", wx.DefaultPosition, wx.DefaultSize, 0 )
|
||||
self.stSetID.Wrap( -1 )
|
||||
fgAddrSizer.Add( self.stSetID, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
|
||||
|
||||
self.inputClientID = wx.TextCtrl( panel, wx.ID_ANY, self.settings.get('clientID'), wx.DefaultPosition, wx.DefaultSize, 0 )
|
||||
|
||||
fgAddrSizer.Add( self.inputClientID, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 5 )
|
||||
|
||||
self.stSetSecret = wx.StaticText( panel, wx.ID_ANY, u"Client Secret:", wx.DefaultPosition, wx.DefaultSize, 0 )
|
||||
self.stSetSecret.Wrap( -1 )
|
||||
|
||||
fgAddrSizer.Add( self.stSetSecret, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
|
||||
|
||||
self.inputClientSecret = wx.TextCtrl( panel, wx.ID_ANY, self.settings.get('clientSecret'), wx.DefaultPosition, wx.DefaultSize, 0 )
|
||||
|
||||
fgAddrSizer.Add( self.inputClientSecret, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 5 )
|
||||
|
||||
self.btnApply = wx.Button( panel, wx.ID_ANY, u"Save Client Settings", wx.DefaultPosition, wx.DefaultSize, 0 )
|
||||
self.btnApply.Bind(wx.EVT_BUTTON, self.OnBtnApply)
|
||||
|
||||
mainSizer.Add( fgAddrSizer, 0, wx.EXPAND, 5)
|
||||
mainSizer.Add( self.btnApply, 0, wx.ALIGN_RIGHT, 5)
|
||||
|
||||
self.ToggleProxySettings(self.settings.get('mode'))
|
||||
|
||||
panel.SetSizer( mainSizer )
|
||||
panel.Layout()
|
||||
|
||||
def OnModeChange(self, event):
|
||||
self.settings.set('mode', event.GetInt())
|
||||
self.ToggleProxySettings(self.settings.get('mode'))
|
||||
service.Crest.restartService()
|
||||
|
||||
def OnServerChange(self, event):
|
||||
self.settings.set('server', event.GetInt())
|
||||
service.Crest.restartService()
|
||||
|
||||
def OnBtnApply(self, event):
|
||||
self.settings.set('clientID', self.inputClientID.GetValue())
|
||||
self.settings.set('clientSecret', self.inputClientSecret.GetValue())
|
||||
sCrest = service.Crest.getInstance()
|
||||
sCrest.delAllCharacters()
|
||||
|
||||
def ToggleProxySettings(self, mode):
|
||||
if mode:
|
||||
self.stSetID.Enable()
|
||||
self.inputClientID.Enable()
|
||||
self.stSetSecret.Enable()
|
||||
self.inputClientSecret.Enable()
|
||||
else:
|
||||
self.stSetID.Disable()
|
||||
self.inputClientID.Disable()
|
||||
self.stSetSecret.Disable()
|
||||
self.inputClientSecret.Disable()
|
||||
|
||||
def getImage(self):
|
||||
return BitmapLoader.getBitmap("eve", "gui")
|
||||
|
||||
PFCrestPref.register()
|
||||
@@ -6,7 +6,7 @@ import wx
|
||||
import copy
|
||||
|
||||
from gui.preferenceView import PreferenceView
|
||||
from gui import bitmapLoader
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from gui.utils import colorUtils
|
||||
import gui.utils.drawUtils as drawUtils
|
||||
|
||||
@@ -313,7 +313,7 @@ class PFGaugePref ( PreferenceView):
|
||||
self.cp103105E.Bind( wx.EVT_COLOURPICKER_CHANGED, self.OnColourChanged )
|
||||
|
||||
def getImage(self):
|
||||
return bitmapLoader.getBitmap("pref-gauges_big", "icons")
|
||||
return BitmapLoader.getBitmap("pref-gauges_big", "gui")
|
||||
|
||||
def InitDefaultColours(self):
|
||||
self.c0100S = wx.Colour(191, 191, 191, 255)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import wx
|
||||
|
||||
from gui.preferenceView import PreferenceView
|
||||
from gui import bitmapLoader
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
|
||||
import gui.mainFrame
|
||||
import service
|
||||
@@ -144,6 +144,6 @@ class PFGeneralPref ( PreferenceView):
|
||||
self.sFit.serviceFittingOptions["showMarketShortcuts"] = self.cbMarketShortcuts.GetValue()
|
||||
|
||||
def getImage(self):
|
||||
return bitmapLoader.getBitmap("prefs_settings", "icons")
|
||||
return BitmapLoader.getBitmap("prefs_settings", "gui")
|
||||
|
||||
PFGeneralPref.register()
|
||||
|
||||
@@ -2,7 +2,7 @@ import wx
|
||||
import os
|
||||
|
||||
from gui.preferenceView import PreferenceView
|
||||
from gui import bitmapLoader
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
|
||||
import gui.mainFrame
|
||||
import service
|
||||
@@ -76,6 +76,6 @@ class PFHTMLExportPref ( PreferenceView):
|
||||
self.HTMLExportSettings.setEnabled(self.exportEnabled.GetValue())
|
||||
|
||||
def getImage(self):
|
||||
return bitmapLoader.getBitmap("prefs_html", "icons")
|
||||
return BitmapLoader.getBitmap("prefs_html", "gui")
|
||||
|
||||
PFHTMLExportPref.register()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import wx
|
||||
|
||||
from gui.preferenceView import PreferenceView
|
||||
from gui import bitmapLoader
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
|
||||
import gui.mainFrame
|
||||
import service
|
||||
@@ -223,6 +223,6 @@ class PFNetworkPref ( PreferenceView):
|
||||
self.editProxySettingsPort.Disable()
|
||||
|
||||
def getImage(self):
|
||||
return bitmapLoader.getBitmap("prefs_proxy", "icons")
|
||||
return BitmapLoader.getBitmap("prefs_proxy", "gui")
|
||||
|
||||
PFNetworkPref.register()
|
||||
|
||||
@@ -3,7 +3,7 @@ import service
|
||||
import os
|
||||
|
||||
from gui.preferenceView import PreferenceView
|
||||
from gui import bitmapLoader
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
|
||||
import service
|
||||
import gui.globalEvents as GE
|
||||
@@ -99,6 +99,6 @@ class PFUpdatePref (PreferenceView):
|
||||
wx.LaunchDefaultBrowser('https://github.com/DarkFenX/Pyfa/releases/tag/'+self.UpdateSettings.get('version'))
|
||||
|
||||
def getImage(self):
|
||||
return bitmapLoader.getBitmap("prefs_update", "icons")
|
||||
return BitmapLoader.getBitmap("prefs_update", "gui")
|
||||
|
||||
PFUpdatePref.register()
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
import wx
|
||||
from gui.statsView import StatsView
|
||||
from gui import builtinStatsViews
|
||||
from gui import bitmapLoader
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from gui.utils.numberFormatter import formatAmount
|
||||
|
||||
class CapacitorViewFull(StatsView):
|
||||
@@ -48,7 +48,7 @@ class CapacitorViewFull(StatsView):
|
||||
baseBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
sizerCapacitor.Add(baseBox, 0, wx.ALIGN_LEFT)
|
||||
bitmap = bitmapLoader.getStaticBitmap("capacitorInfo_big", parent, "icons")
|
||||
bitmap = BitmapLoader.getStaticBitmap("capacitorInfo_big", parent, "gui")
|
||||
tooltip = wx.ToolTip("Capacitor stability")
|
||||
bitmap.SetToolTip(tooltip)
|
||||
baseBox.Add(bitmap, 0, wx.ALIGN_CENTER)
|
||||
@@ -83,7 +83,7 @@ class CapacitorViewFull(StatsView):
|
||||
sizerCapacitor.Add(baseBox, 0, wx.ALIGN_CENTER_HORIZONTAL)
|
||||
|
||||
tooltip = wx.ToolTip("Capacitor throughput")
|
||||
bitmap = bitmapLoader.getStaticBitmap("capacitorRecharge_big", parent, "icons")
|
||||
bitmap = BitmapLoader.getStaticBitmap("capacitorRecharge_big", parent, "gui")
|
||||
bitmap.SetToolTip(tooltip)
|
||||
baseBox.Add(bitmap, 0, wx.ALIGN_CENTER)
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import wx
|
||||
import service
|
||||
import gui.mainFrame
|
||||
from gui.statsView import StatsView
|
||||
from gui import bitmapLoader
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from gui.utils.numberFormatter import formatAmount
|
||||
|
||||
class FirepowerViewFull(StatsView):
|
||||
@@ -61,7 +61,7 @@ class FirepowerViewFull(StatsView):
|
||||
baseBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
sizerFirepower.Add(baseBox, 1, wx.ALIGN_LEFT if counter == 0 else wx.ALIGN_CENTER_HORIZONTAL)
|
||||
|
||||
baseBox.Add(bitmapLoader.getStaticBitmap("%s_big" % image, parent, "icons"), 0, wx.ALIGN_CENTER)
|
||||
baseBox.Add(BitmapLoader.getStaticBitmap("%s_big" % image, parent, "gui"), 0, wx.ALIGN_CENTER)
|
||||
|
||||
box = wx.BoxSizer(wx.VERTICAL)
|
||||
baseBox.Add(box, 0, wx.ALIGN_CENTER)
|
||||
@@ -82,7 +82,7 @@ class FirepowerViewFull(StatsView):
|
||||
baseBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
targetSizer.Add(baseBox, 0, wx.ALIGN_RIGHT)
|
||||
|
||||
baseBox.Add(bitmapLoader.getStaticBitmap("volley_big", parent, "icons"), 0, wx.ALIGN_CENTER)
|
||||
baseBox.Add(BitmapLoader.getStaticBitmap("volley_big", parent, "gui"), 0, wx.ALIGN_CENTER)
|
||||
|
||||
gridS = wx.GridSizer(2,2,0,0)
|
||||
|
||||
@@ -103,7 +103,7 @@ class FirepowerViewFull(StatsView):
|
||||
|
||||
gridS.Add(lbl, 0, wx.ALIGN_LEFT)
|
||||
|
||||
image = bitmapLoader.getBitmap("mining_small", "icons")
|
||||
image = BitmapLoader.getBitmap("mining_small", "gui")
|
||||
self.miningyield = wx.BitmapButton(contentPanel, -1, image)
|
||||
self.miningyield.SetToolTip(wx.ToolTip("Click to toggle to Mining Yield "))
|
||||
self.miningyield.Bind(wx.EVT_BUTTON, self.switchToMiningYieldView)
|
||||
|
||||
@@ -21,7 +21,7 @@ import wx
|
||||
import service
|
||||
import gui.mainFrame
|
||||
from gui.statsView import StatsView
|
||||
from gui import bitmapLoader
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from gui.utils.numberFormatter import formatAmount
|
||||
|
||||
class MiningYieldViewFull(StatsView):
|
||||
@@ -55,7 +55,7 @@ class MiningYieldViewFull(StatsView):
|
||||
baseBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
sizerMiningYield.Add(baseBox, 1, wx.ALIGN_LEFT if counter == 0 else wx.ALIGN_CENTER_HORIZONTAL)
|
||||
|
||||
baseBox.Add(bitmapLoader.getStaticBitmap("%s_big" % image, parent, "icons"), 0, wx.ALIGN_CENTER)
|
||||
baseBox.Add(BitmapLoader.getStaticBitmap("%s_big" % image, parent, "gui"), 0, wx.ALIGN_CENTER)
|
||||
|
||||
box = wx.BoxSizer(wx.VERTICAL)
|
||||
baseBox.Add(box, 0, wx.ALIGN_CENTER)
|
||||
@@ -76,7 +76,7 @@ class MiningYieldViewFull(StatsView):
|
||||
baseBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
targetSizer.Add(baseBox, 0, wx.ALIGN_LEFT)
|
||||
|
||||
baseBox.Add(bitmapLoader.getStaticBitmap("cargoBay_big", parent, "icons"), 0, wx.ALIGN_CENTER)
|
||||
baseBox.Add(BitmapLoader.getStaticBitmap("cargoBay_big", parent, "gui"), 0, wx.ALIGN_CENTER)
|
||||
|
||||
box = wx.BoxSizer(wx.VERTICAL)
|
||||
baseBox.Add(box, 0, wx.EXPAND)
|
||||
@@ -92,7 +92,7 @@ class MiningYieldViewFull(StatsView):
|
||||
|
||||
self._cachedValues.append(0)
|
||||
|
||||
image = bitmapLoader.getBitmap("turret_small", "icons")
|
||||
image = BitmapLoader.getBitmap("turret_small", "gui")
|
||||
firepower = wx.BitmapButton(contentPanel, -1, image)
|
||||
firepower.SetToolTip(wx.ToolTip("Click to toggle to Firepower View"))
|
||||
firepower.Bind(wx.EVT_BUTTON, self.switchToFirepowerView)
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
import wx
|
||||
from gui.statsView import StatsView
|
||||
from gui import builtinStatsViews
|
||||
from gui import bitmapLoader
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from gui.utils.numberFormatter import formatAmount
|
||||
import service
|
||||
import locale
|
||||
@@ -56,7 +56,7 @@ class PriceViewFull(StatsView):
|
||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||
gridPrice.Add(box, 0, wx.ALIGN_TOP)
|
||||
|
||||
box.Add(bitmapLoader.getStaticBitmap(image, contentPanel, "icons"), 0, wx.ALIGN_CENTER)
|
||||
box.Add(BitmapLoader.getStaticBitmap(image, contentPanel, "gui"), 0, wx.ALIGN_CENTER)
|
||||
|
||||
vbox = wx.BoxSizer(wx.VERTICAL)
|
||||
box.Add(vbox, 1, wx.EXPAND)
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
import wx
|
||||
from gui.statsView import StatsView
|
||||
from gui import bitmapLoader
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from gui.utils.numberFormatter import formatAmount
|
||||
import gui.mainFrame
|
||||
import gui.builtinStatsViews.resistancesViewFull as rvf
|
||||
@@ -62,14 +62,14 @@ class RechargeViewFull(StatsView):
|
||||
sizerTankStats.Add(wx.StaticText(contentPanel, wx.ID_ANY, ""), 0)
|
||||
toolTipText = {"shieldPassive" : "Passive shield recharge", "shieldActive" : "Active shield boost", "armorActive" : "Armor repair amount", "hullActive" : "Hull repair amount"}
|
||||
for tankType in ("shieldPassive", "shieldActive", "armorActive", "hullActive"):
|
||||
bitmap = bitmapLoader.getStaticBitmap("%s_big" % tankType, contentPanel, "icons")
|
||||
bitmap = BitmapLoader.getStaticBitmap("%s_big" % tankType, contentPanel, "gui")
|
||||
tooltip = wx.ToolTip(toolTipText[tankType])
|
||||
bitmap.SetToolTip(tooltip)
|
||||
sizerTankStats.Add(bitmap, 0, wx.ALIGN_CENTER)
|
||||
|
||||
toolTipText = {"reinforced" : "Reinforced", "sustained" : "Sustained"}
|
||||
for stability in ("reinforced", "sustained"):
|
||||
bitmap = bitmapLoader.getStaticBitmap("regen%s_big" % stability.capitalize(), contentPanel, "icons")
|
||||
bitmap = BitmapLoader.getStaticBitmap("regen%s_big" % stability.capitalize(), contentPanel, "gui")
|
||||
tooltip = wx.ToolTip(toolTipText[stability])
|
||||
bitmap.SetToolTip(tooltip)
|
||||
sizerTankStats.Add(bitmap, 0, wx.ALIGN_CENTER)
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
import wx
|
||||
from gui.statsView import StatsView
|
||||
from gui import builtinStatsViews
|
||||
from gui import bitmapLoader
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from gui import pygauge as PG
|
||||
from gui.utils.numberFormatter import formatAmount
|
||||
import service
|
||||
@@ -74,18 +74,15 @@ class ResistancesViewFull(StatsView):
|
||||
# Display table
|
||||
col = 0
|
||||
row = 0
|
||||
sizerResistances = wx.GridBagSizer(0, 0)
|
||||
sizerResistances = wx.GridBagSizer()
|
||||
contentSizer.Add( sizerResistances, 0, wx.EXPAND , 0)
|
||||
|
||||
for i in xrange(6):
|
||||
sizerResistances.AddGrowableCol(i + 1)
|
||||
|
||||
# Add an empty label, then the rest.
|
||||
sizerResistances.Add(wx.StaticText(contentPanel, wx.ID_ANY), wx.GBPosition( row, col ), wx.GBSpan( 1, 1 ))
|
||||
col+=1
|
||||
toolTipText = {"em" : "Electromagnetic resistance", "thermal" : "Thermal resistance", "kinetic" : "Kinetic resistance", "explosive" : "Explosive resistance"}
|
||||
for damageType in ("em", "thermal", "kinetic", "explosive"):
|
||||
bitmap = bitmapLoader.getStaticBitmap("%s_big" % damageType, contentPanel, "icons")
|
||||
bitmap = BitmapLoader.getStaticBitmap("%s_big" % damageType, contentPanel, "gui")
|
||||
tooltip = wx.ToolTip(toolTipText[damageType])
|
||||
bitmap.SetToolTip(tooltip)
|
||||
sizerResistances.Add(bitmap, wx.GBPosition( row, col ), wx.GBSpan( 1, 1 ), wx.ALIGN_CENTER)
|
||||
@@ -95,6 +92,8 @@ class ResistancesViewFull(StatsView):
|
||||
|
||||
self.stEHPs.Bind(wx.EVT_BUTTON, self.toggleEHP)
|
||||
|
||||
for i in xrange(4):
|
||||
sizerResistances.AddGrowableCol(i+1)
|
||||
|
||||
sizerResistances.Add(self.stEHPs, wx.GBPosition( row, col ), wx.GBSpan( 1, 1 ), wx.ALIGN_CENTER)
|
||||
col=0
|
||||
@@ -105,7 +104,7 @@ class ResistancesViewFull(StatsView):
|
||||
toolTipText = {"shield" : "Shield resistance", "armor" : "Armor resistance", "hull" : "Hull resistance", "damagePattern" : "Incoming damage pattern"}
|
||||
for tankType in ("shield", "armor", "hull", "separator", "damagePattern"):
|
||||
if tankType != "separator":
|
||||
bitmap = bitmapLoader.getStaticBitmap("%s_big" % tankType, contentPanel, "icons")
|
||||
bitmap = BitmapLoader.getStaticBitmap("%s_big" % tankType, contentPanel, "gui")
|
||||
tooltip = wx.ToolTip(toolTipText[tankType])
|
||||
bitmap.SetToolTip(tooltip)
|
||||
sizerResistances.Add(bitmap, wx.GBPosition( row, col ), wx.GBSpan( 1, 1 ), wx.ALIGN_CENTER)
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
import wx
|
||||
from gui.statsView import StatsView
|
||||
from gui import builtinStatsViews
|
||||
from gui import bitmapLoader
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from gui import pygauge as PG
|
||||
import gui.mainFrame
|
||||
import gui.chromeTabs
|
||||
@@ -91,7 +91,7 @@ class ResourcesViewFull(StatsView):
|
||||
for type in ("turret", "launcher", "drones", "calibration"):
|
||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
bitmap = bitmapLoader.getStaticBitmap("%s_big" % type, parent, "icons")
|
||||
bitmap = BitmapLoader.getStaticBitmap("%s_big" % type, parent, "gui")
|
||||
tooltip = wx.ToolTip(tooltipText[type])
|
||||
bitmap.SetToolTip(tooltip)
|
||||
|
||||
@@ -119,7 +119,7 @@ class ResourcesViewFull(StatsView):
|
||||
|
||||
for type in group:
|
||||
capitalizedType = type[0].capitalize() + type[1:]
|
||||
bitmap = bitmapLoader.getStaticBitmap(type + "_big", parent, "icons")
|
||||
bitmap = BitmapLoader.getStaticBitmap(type + "_big", parent, "gui")
|
||||
tooltip = wx.ToolTip(tooltipText[type])
|
||||
bitmap.SetToolTip(tooltip)
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ class TargetingMiscViewFull(StatsView):
|
||||
gridTargetingMisc.AddGrowableCol(2)
|
||||
# Targeting
|
||||
|
||||
gridTargeting = wx.FlexGridSizer(4, 2)
|
||||
gridTargeting = wx.FlexGridSizer(5, 2)
|
||||
gridTargeting.AddGrowableCol(1)
|
||||
|
||||
gridTargetingMisc.Add(gridTargeting, 0, wx.ALIGN_LEFT | wx.ALL, 5)
|
||||
@@ -77,7 +77,7 @@ class TargetingMiscViewFull(StatsView):
|
||||
|
||||
# Misc
|
||||
gridTargetingMisc.Add( wx.StaticLine( contentPanel, wx.ID_ANY, style = wx.VERTICAL),0, wx.EXPAND, 3 )
|
||||
gridMisc = wx.FlexGridSizer(4, 2)
|
||||
gridMisc = wx.FlexGridSizer(5, 2)
|
||||
gridMisc.AddGrowableCol(1)
|
||||
gridTargetingMisc.Add(gridMisc,0 , wx.ALIGN_LEFT | wx.ALL, 5)
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user