Compare commits
292 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a6b9114e2 | ||
|
|
61abcf3018 | ||
|
|
4845b3b0ce | ||
|
|
8f0e8f72cd | ||
|
|
96269a7777 | ||
|
|
bdcc05b7b6 | ||
|
|
060b512bcf | ||
|
|
3907c8c29a | ||
|
|
c786012b28 | ||
|
|
37a084e1d1 | ||
|
|
b9c3675894 | ||
|
|
60ecc95049 | ||
|
|
59d9d47a56 | ||
|
|
c619efa68e | ||
|
|
05e895e7b7 | ||
|
|
58daf2a543 | ||
|
|
0294684bb8 | ||
|
|
fa9b3be41c | ||
|
|
74bf3fbc8b | ||
|
|
dc2a4d4446 | ||
|
|
b0895611d6 | ||
|
|
f664a1cad3 | ||
|
|
19de7e40dc | ||
|
|
de2ee1dce6 | ||
|
|
90698dde90 | ||
|
|
0ab6d6e845 | ||
|
|
74d87845cf | ||
|
|
9e2b15776f | ||
|
|
c8ade0741c | ||
|
|
af8b444ab5 | ||
|
|
2ba26f01b2 | ||
|
|
e77bb11d0a | ||
|
|
c14b56f37d | ||
|
|
e6fe8de5ed | ||
|
|
cf27c2be10 | ||
|
|
78ff74f0f7 | ||
|
|
29a2a08986 | ||
|
|
881b92a6ea | ||
|
|
50c22c836b | ||
|
|
63115a7c0f | ||
|
|
f854627888 | ||
|
|
5ec8468d3f | ||
|
|
0da4e4359b | ||
|
|
c5e8742838 | ||
|
|
f9f90852c5 | ||
|
|
6b5f2450ad | ||
|
|
4f2e962a46 | ||
|
|
05ce8fbf1c | ||
|
|
929b2dfb38 | ||
|
|
659e0e5ead | ||
|
|
7bb44f6473 | ||
|
|
60f024fdb7 | ||
|
|
da601c9a63 | ||
|
|
7464de06b1 | ||
|
|
20fbda9e7a | ||
|
|
15bbf69fcf | ||
|
|
677a9b33c5 | ||
|
|
e9efdcd4e8 | ||
|
|
c3b0b7d1e1 | ||
|
|
d46a2d61bb | ||
|
|
673a2e25e3 | ||
|
|
749adb9ec8 | ||
|
|
5cab8b1070 | ||
|
|
00637f84cb | ||
|
|
bc5a43bfb3 | ||
|
|
723ef5c48d | ||
|
|
53c1a77aeb | ||
|
|
e5389d44d9 | ||
|
|
54b2e5b5fb | ||
|
|
1276016a98 | ||
|
|
c54d0dc5ff | ||
|
|
fc0bfd83b2 | ||
|
|
42620c842e | ||
|
|
fd3b3f98bf | ||
|
|
fd7c5c1580 | ||
|
|
c0922adfb2 | ||
|
|
1454cd8a0d | ||
|
|
3e249ec155 | ||
|
|
edfbf71958 | ||
|
|
4876ff7035 | ||
|
|
d5034c9e0d | ||
|
|
9ec54c9004 | ||
|
|
0749e03211 | ||
|
|
e03adad23a | ||
|
|
9b3ba8c9aa | ||
|
|
85746cd681 | ||
|
|
2e64280403 | ||
|
|
d7b81ea87d | ||
|
|
f4404e2649 | ||
|
|
f598e8e3c2 | ||
|
|
27488a0260 | ||
|
|
c53e7964bf | ||
|
|
3516d6fdc5 | ||
|
|
69af1440ae | ||
|
|
31c3101d6d | ||
|
|
5850026aa9 | ||
|
|
b4b8a158f5 | ||
|
|
5c6303995d | ||
|
|
f0353a7dd7 | ||
|
|
1fb19e3b94 | ||
|
|
1788b32b83 | ||
|
|
621672bf34 | ||
|
|
b08406b7d6 | ||
|
|
6211d1de70 | ||
|
|
916b11deb8 | ||
|
|
8e41a90f57 | ||
|
|
9aa2b17ae6 | ||
|
|
7f02a078fd | ||
|
|
07b6c9c437 | ||
|
|
7c7650ac07 | ||
|
|
4e399f9bbb | ||
|
|
12b11d57ba | ||
|
|
bea7102a3f | ||
|
|
b77a577c06 | ||
|
|
c5aab07d65 | ||
|
|
362ae72183 | ||
|
|
6f5d0453a6 | ||
|
|
c552f6a1d4 | ||
|
|
99a8b03697 | ||
|
|
9d63946aa7 | ||
|
|
6eba2b1abd | ||
|
|
b05f1573c6 | ||
|
|
f4311d1cef | ||
|
|
8abad416bd | ||
|
|
52dbd8d9ef | ||
|
|
4e5a70993e | ||
|
|
dd0fbfddb9 | ||
|
|
02e35181d5 | ||
|
|
302cab54fd | ||
|
|
ba157af496 | ||
|
|
d1e6647d1f | ||
|
|
0a47fba107 | ||
|
|
3faa57f39a | ||
|
|
75333264a7 | ||
|
|
e7d846063d | ||
|
|
c2b7cc00dd | ||
|
|
a107171543 | ||
|
|
79be16114d | ||
|
|
c530660132 | ||
|
|
ebe0efac81 | ||
|
|
18ee37d8fd | ||
|
|
f2c2e2e65a | ||
|
|
93f1a18b37 | ||
|
|
44aed364b7 | ||
|
|
eb8fa2f259 | ||
|
|
a8c69abc72 | ||
|
|
2dd1ddddd5 | ||
|
|
4a27c60486 | ||
|
|
66d559306f | ||
|
|
83222489c4 | ||
|
|
0a2fa62e21 | ||
|
|
6240f23c02 | ||
|
|
13498e9b35 | ||
|
|
ca30025be0 | ||
|
|
97ef231711 | ||
|
|
82d8c95d2f | ||
|
|
dde5ee3701 | ||
|
|
44a3cb3b2e | ||
|
|
44c58abe81 | ||
|
|
7055690805 | ||
|
|
116dde3f3f | ||
|
|
daef1ebdfd | ||
|
|
5c38ab4228 | ||
|
|
299243c446 | ||
|
|
970c3a5473 | ||
|
|
bc63eaa876 | ||
|
|
78de723b81 | ||
|
|
dbb9823df5 | ||
|
|
95899548e5 | ||
|
|
2a076292da | ||
|
|
308fa3c46c | ||
|
|
ccd6d357ed | ||
|
|
21b6a2cdfd | ||
|
|
ccbd0a117b | ||
|
|
6caa79c951 | ||
|
|
4365da8292 | ||
|
|
ff222b8d62 | ||
|
|
180b766b59 | ||
|
|
b4e765abfa | ||
|
|
2f40365a03 | ||
|
|
2001a395e5 | ||
|
|
7e94914f65 | ||
|
|
b17314f3c6 | ||
|
|
fd83a4b709 | ||
|
|
a37fdf48c8 | ||
|
|
5ee8e203db | ||
|
|
083b34c780 | ||
|
|
6c12e1c5fc | ||
|
|
bcbed3df39 | ||
|
|
083b618b71 | ||
|
|
3d4b41d135 | ||
|
|
eeb2b019c0 | ||
|
|
71257b5265 | ||
|
|
a5a152d395 | ||
|
|
f0983c1468 | ||
|
|
513e9d14d8 | ||
|
|
efbf2e7432 | ||
|
|
646a903f18 | ||
|
|
d74f2b2e42 | ||
|
|
9977866eb0 | ||
|
|
008d73e605 | ||
|
|
2164588329 | ||
|
|
391c3a32a6 | ||
|
|
bd975becf1 | ||
|
|
d6b280d3cc | ||
|
|
56ebb2926d | ||
|
|
804d90c50c | ||
|
|
326e1e04c2 | ||
|
|
0f4f8c636d | ||
|
|
425c7f657c | ||
|
|
3c7f0258df | ||
|
|
7a1b4b4a1e | ||
|
|
fcc53d3f21 | ||
|
|
15ba5c8ace | ||
|
|
6057a1a7d9 | ||
|
|
e0add506c9 | ||
|
|
aa282990a5 | ||
|
|
1686220523 | ||
|
|
c84c79c917 | ||
|
|
36b158637c | ||
|
|
fc153915b6 | ||
|
|
098f0f92ee | ||
|
|
cfb7a70da5 | ||
|
|
984978a80d | ||
|
|
dd430bc9bb | ||
|
|
b724e5bec1 | ||
|
|
1f09494df5 | ||
|
|
d9827b445f | ||
|
|
46e58ecba7 | ||
|
|
c1405fa675 | ||
|
|
b7900b0b25 | ||
|
|
bef8fbbc3a | ||
|
|
4fc630d44e | ||
|
|
582a3893d1 | ||
|
|
03e325cdcb | ||
|
|
7f8ad3885d | ||
|
|
0d32b60f7e | ||
|
|
53f6d43109 | ||
|
|
dd6fe01df5 | ||
|
|
1f9024a740 | ||
|
|
65c568bd95 | ||
|
|
9ccdb51063 | ||
|
|
d5aeb0913d | ||
|
|
38726675e1 | ||
|
|
622a3004c5 | ||
|
|
2ccad2a358 | ||
|
|
a66eb059e2 | ||
|
|
5d0342ee2d | ||
|
|
ec3cd75f4c | ||
|
|
9309ddff07 | ||
|
|
0c3fa53bcf | ||
|
|
926e0a9035 | ||
|
|
fe0266e517 | ||
|
|
0a8bb79e47 | ||
|
|
e9cb7696dd | ||
|
|
c054a2d80d | ||
|
|
2f7a3e0287 | ||
|
|
6be77646fc | ||
|
|
a6a0831123 | ||
|
|
682607c31f | ||
|
|
c0096fc016 | ||
|
|
ebac100e38 | ||
|
|
fe43c2ee2e | ||
|
|
b1f1db1bee | ||
|
|
df75646766 | ||
|
|
6270d34dfd | ||
|
|
497fdd7a11 | ||
|
|
6583aa9b34 | ||
|
|
910fe99e44 | ||
|
|
4be78db738 | ||
|
|
897763e8d5 | ||
|
|
f624528ce5 | ||
|
|
c0e9878982 | ||
|
|
7a078f433a | ||
|
|
da5893ac91 | ||
|
|
7af5c17015 | ||
|
|
6bbfb18680 | ||
|
|
d61ab0ff5a | ||
|
|
f8504cfa6e | ||
|
|
05e76a884a | ||
|
|
2a410a13a0 | ||
|
|
d5afacef3f | ||
|
|
56a3911b96 | ||
|
|
dba86edff2 | ||
|
|
e2d8a3a4e8 | ||
|
|
090065ddd4 | ||
|
|
acade56769 | ||
|
|
49b1e2ee36 | ||
|
|
aec9202be1 | ||
|
|
ed3083aa77 | ||
|
|
4b2a58ca6f | ||
|
|
0de950862b |
@@ -100,8 +100,8 @@ def DBInMemory():
|
||||
import eos.db
|
||||
|
||||
# Output debug info to help us troubleshoot Travis
|
||||
print((eos.db.saveddata_engine))
|
||||
print((eos.db.gamedata_engine))
|
||||
print(eos.db.saveddata_engine)
|
||||
print(eos.db.gamedata_engine)
|
||||
|
||||
helper = {
|
||||
'config': eos.config,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import pytest
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
from _development.helpers import DBInMemory as DB, Gamedata, Saveddata
|
||||
|
||||
|
||||
# noinspection PyShadowingNames
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import pytest
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
from _development.helpers import DBInMemory as DB, Gamedata, Saveddata
|
||||
|
||||
|
||||
# noinspection PyShadowingNames
|
||||
|
||||
20
config.py
20
config.py
@@ -24,10 +24,10 @@ saveInRoot = False
|
||||
|
||||
# Version data
|
||||
|
||||
version = "2.3.0"
|
||||
version = "2.6.1"
|
||||
tag = "Stable"
|
||||
expansionName = "YC120.7"
|
||||
expansionVersion = "1.2"
|
||||
expansionName = "Onslaught"
|
||||
expansionVersion = "1.5"
|
||||
evemonMinVersion = "4081"
|
||||
|
||||
minItemSearchLength = 3
|
||||
@@ -229,20 +229,6 @@ def defLogging():
|
||||
)
|
||||
])
|
||||
|
||||
with logging_setup.threadbound():
|
||||
|
||||
# Output all stdout (print) messages as warnings
|
||||
try:
|
||||
sys.stdout = LoggerWriter(pyfalog.warning)
|
||||
except:
|
||||
pyfalog.critical("Cannot redirect. Continuing without writing stdout to log.")
|
||||
|
||||
# Output all stderr (stacktrace) messages as critical
|
||||
try:
|
||||
sys.stderr = LoggerWriter(pyfalog.critical)
|
||||
except:
|
||||
pyfalog.critical("Cannot redirect. Continuing without writing stderr to log.")
|
||||
|
||||
|
||||
class LoggerWriter(object):
|
||||
def __init__(self, level):
|
||||
|
||||
@@ -38,7 +38,7 @@ call([
|
||||
iscc,
|
||||
os.path.join(os.getcwd(), "dist_assets", "win", "pyfa-setup.iss"),
|
||||
"/dMyAppVersion=%s" % (config['version']),
|
||||
"/dMyAppExpansion=%s" % (expansion),
|
||||
"/dMyAppExpansion=%s" % expansion,
|
||||
"/dMyAppDir=%s" % source,
|
||||
"/dMyOutputDir=%s" % os.path.join(os.getcwd(), "dist"),
|
||||
"/dMyOutputFile=%s" % fileName]) # stdout=devnull, stderr=devnull
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Column, String, Integer, ForeignKey, Boolean, Table
|
||||
from sqlalchemy.orm import relation, mapper, synonym, deferred
|
||||
from sqlalchemy import Boolean, Column, Integer, String, Table
|
||||
from sqlalchemy.orm import deferred, mapper, synonym
|
||||
|
||||
from eos.db import gamedata_meta
|
||||
from eos.gamedata import Category
|
||||
|
||||
@@ -17,15 +17,15 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Column, String, Integer, Boolean, ForeignKey, Table, Float
|
||||
from sqlalchemy import Boolean, Column, Float, ForeignKey, Integer, String, Table
|
||||
from sqlalchemy.ext.associationproxy import association_proxy
|
||||
from sqlalchemy.orm import relation, mapper, synonym, deferred, backref
|
||||
from sqlalchemy.orm import backref, deferred, mapper, relation, synonym
|
||||
from sqlalchemy.orm.collections import attribute_mapped_collection
|
||||
from eos.db.gamedata.effect import typeeffects_table
|
||||
|
||||
from eos.db import gamedata_meta
|
||||
from eos.gamedata import Attribute, Effect, Group, Item, MetaType, Traits, DynamicItemItem, DynamicItem
|
||||
from eos.db.gamedata.dynamicAttributes import dynamicApplicable_table, dynamic_table
|
||||
from eos.db.gamedata.dynamicAttributes import dynamicApplicable_table
|
||||
from eos.db.gamedata.effect import typeeffects_table
|
||||
from eos.gamedata import Attribute, DynamicItem, Effect, Group, Item, MetaType, Traits
|
||||
|
||||
items_table = Table("invtypes", gamedata_meta,
|
||||
Column("typeID", Integer, primary_key=True),
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy.orm import join, exc, aliased, joinedload, subqueryload
|
||||
from sqlalchemy.sql import and_, or_, select
|
||||
from sqlalchemy.inspection import inspect
|
||||
from sqlalchemy.orm import aliased, exc, join
|
||||
from sqlalchemy.sql import and_, or_, select
|
||||
|
||||
import eos.config
|
||||
from eos.db import gamedata_session
|
||||
from eos.db.gamedata.metaGroup import metatypes_table, items_table
|
||||
from eos.db.gamedata.group import groups_table
|
||||
from eos.db.gamedata.metaGroup import items_table, metatypes_table
|
||||
from eos.db.util import processEager, processWhere
|
||||
from eos.gamedata import AlphaClone, Attribute, Category, Group, Item, MarketGroup, MetaGroup, AttributeInfo, MetaData, DynamicItem
|
||||
from eos.gamedata import AlphaClone, Attribute, AttributeInfo, Category, DynamicItem, Group, Item, MarketGroup, MetaData, MetaGroup
|
||||
|
||||
cache = {}
|
||||
configVal = getattr(eos.config, "gamedataCache", None)
|
||||
@@ -396,6 +396,21 @@ def getAbyssalTypes():
|
||||
return set([r.resultingTypeID for r in gamedata_session.query(DynamicItem.resultingTypeID).distinct()])
|
||||
|
||||
|
||||
@cachedQuery(1, "itemID")
|
||||
def getDynamicItem(itemID, eager=None):
|
||||
try:
|
||||
if isinstance(itemID, int):
|
||||
if eager is None:
|
||||
result = gamedata_session.query(DynamicItem).filter(DynamicItem.ID == itemID).one()
|
||||
else:
|
||||
result = gamedata_session.query(DynamicItem).options(*processEager(eager)).filter(DynamicItem.ID == itemID).one()
|
||||
else:
|
||||
raise TypeError("Need integer as argument")
|
||||
except exc.NoResultFound:
|
||||
result = None
|
||||
return result
|
||||
|
||||
|
||||
def getRequiredFor(itemID, attrMapping):
|
||||
Attribute1 = aliased(Attribute)
|
||||
Attribute2 = aliased(Attribute)
|
||||
|
||||
@@ -17,33 +17,32 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy.ext.associationproxy import association_proxy
|
||||
from sqlalchemy.orm.collections import attribute_mapped_collection
|
||||
from sqlalchemy.sql import and_
|
||||
from sqlalchemy.orm import relation, reconstructor, mapper, relationship
|
||||
from sqlalchemy import ForeignKey, Column, Integer, String, Table, Boolean, DateTime
|
||||
import datetime
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.db import saveddata_session
|
||||
from sqlalchemy import Boolean, Column, DateTime, ForeignKey, Integer, String, Table
|
||||
from sqlalchemy.ext.associationproxy import association_proxy
|
||||
from sqlalchemy.orm import mapper, reconstructor, relation, relationship
|
||||
from sqlalchemy.orm.collections import attribute_mapped_collection
|
||||
from sqlalchemy.sql import and_
|
||||
|
||||
from eos.db import saveddata_meta, saveddata_session
|
||||
from eos.db.saveddata.cargo import cargo_table
|
||||
from eos.db.saveddata.drone import drones_table
|
||||
from eos.db.saveddata.fighter import fighters_table
|
||||
from eos.db.saveddata.implant import fitImplants_table
|
||||
from eos.db.saveddata.module import modules_table
|
||||
from eos.effectHandlerHelpers import HandledModuleList, HandledImplantBoosterList, HandledProjectedModList, \
|
||||
HandledDroneCargoList, HandledProjectedDroneList
|
||||
from eos.saveddata.implant import Implant
|
||||
from eos.saveddata.character import Character
|
||||
from eos.saveddata.user import User
|
||||
from eos.saveddata.fighter import Fighter
|
||||
from eos.saveddata.fit import Fit as es_Fit, ImplantLocation
|
||||
from eos.saveddata.drone import Drone
|
||||
from eos.effectHandlerHelpers import HandledDroneCargoList, HandledImplantBoosterList, HandledModuleList, HandledProjectedDroneList, HandledProjectedModList
|
||||
from eos.saveddata.booster import Booster
|
||||
from eos.saveddata.module import Module
|
||||
from eos.saveddata.cargo import Cargo
|
||||
from eos.saveddata.character import Character
|
||||
from eos.saveddata.damagePattern import DamagePattern
|
||||
from eos.saveddata.drone import Drone
|
||||
from eos.saveddata.fighter import Fighter
|
||||
from eos.saveddata.fit import Fit as es_Fit
|
||||
from eos.saveddata.implant import Implant
|
||||
from eos.saveddata.module import Module
|
||||
from eos.saveddata.targetResists import TargetResists
|
||||
from eos.saveddata.user import User
|
||||
|
||||
fits_table = Table("fits", saveddata_meta,
|
||||
Column("ID", Integer, primary_key=True),
|
||||
@@ -132,13 +131,13 @@ class CommandFit(object):
|
||||
)
|
||||
|
||||
|
||||
es_Fit._Fit__projectedFits = association_proxy(
|
||||
es_Fit.projectedFitDict = association_proxy(
|
||||
"victimOf", # look at the victimOf association...
|
||||
"source_fit", # .. and return the source fits
|
||||
creator=lambda sourceID, source_fit: ProjectedFit(sourceID, source_fit)
|
||||
)
|
||||
|
||||
es_Fit._Fit__commandFits = association_proxy(
|
||||
es_Fit.commandFitDict = association_proxy(
|
||||
"boostedOf", # look at the boostedOf association...
|
||||
"booster_fit", # .. and return the booster fit
|
||||
creator=lambda boosterID, booster_fit: CommandFit(boosterID, booster_fit)
|
||||
|
||||
@@ -17,10 +17,11 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey, Boolean, DateTime, Float
|
||||
from sqlalchemy.orm import mapper
|
||||
import datetime
|
||||
|
||||
from sqlalchemy import Column, DateTime, Float, ForeignKey, Integer, Table
|
||||
from sqlalchemy.orm import mapper
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.saveddata.mutator import Mutator
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
# ===============================================================================
|
||||
|
||||
from logbook import Logger
|
||||
from utils.deprecated import deprecated
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
@@ -113,6 +114,7 @@ class HandledList(list):
|
||||
|
||||
|
||||
class HandledModuleList(HandledList):
|
||||
|
||||
def append(self, mod):
|
||||
emptyPosition = float("Inf")
|
||||
for i in range(len(self)):
|
||||
@@ -130,6 +132,9 @@ class HandledModuleList(HandledList):
|
||||
self.remove(mod)
|
||||
return
|
||||
|
||||
self.appendIgnoreEmpty(mod)
|
||||
|
||||
def appendIgnoreEmpty(self, mod):
|
||||
mod.position = len(self)
|
||||
HandledList.append(self, mod)
|
||||
if mod.isInvalid:
|
||||
@@ -163,6 +168,7 @@ class HandledModuleList(HandledList):
|
||||
mod.position = index
|
||||
self[index] = mod
|
||||
|
||||
@deprecated
|
||||
def freeSlot(self, slot):
|
||||
for i in range(len(self)):
|
||||
mod = self[i]
|
||||
@@ -195,14 +201,20 @@ class HandledImplantBoosterList(HandledList):
|
||||
self.remove(thing)
|
||||
return
|
||||
|
||||
self.makeRoom(thing)
|
||||
HandledList.append(self, thing)
|
||||
|
||||
def makeRoom(self, thing):
|
||||
# if needed, remove booster that was occupying slot
|
||||
oldObj = next((m for m in self if m.slot == thing.slot), None)
|
||||
if oldObj:
|
||||
pyfalog.info("Slot {0} occupied with {1}, replacing with {2}", thing.slot, oldObj.item.name, thing.item.name)
|
||||
pyfalog.info("Slot {0} occupied with {1}, replacing with {2}", thing.slot, oldObj.item.name,
|
||||
thing.item.name)
|
||||
itemID = oldObj.itemID
|
||||
oldObj.itemID = 0 # hack to remove from DB. See GH issue #324
|
||||
self.remove(oldObj)
|
||||
|
||||
HandledList.append(self, thing)
|
||||
return itemID
|
||||
return None
|
||||
|
||||
|
||||
class HandledSsoCharacterList(list):
|
||||
@@ -228,12 +240,7 @@ class HandledProjectedModList(HandledList):
|
||||
isSystemEffect = proj.item.group.name == "Effect Beacon"
|
||||
|
||||
if isSystemEffect:
|
||||
# remove other system effects - only 1 per fit plz
|
||||
oldEffect = next((m for m in self if m.item.group.name == "Effect Beacon"), None)
|
||||
|
||||
if oldEffect:
|
||||
pyfalog.info("System effect occupied with {0}, replacing with {1}", oldEffect.item.name, proj.item.name)
|
||||
self.remove(oldEffect)
|
||||
self.makeRoom(proj)
|
||||
|
||||
HandledList.append(self, proj)
|
||||
|
||||
@@ -241,6 +248,16 @@ class HandledProjectedModList(HandledList):
|
||||
if not proj.item.isType("projected") and not isSystemEffect:
|
||||
self.remove(proj)
|
||||
|
||||
def makeRoom(self, proj):
|
||||
# remove other system effects - only 1 per fit plz
|
||||
oldEffect = next((m for m in self if m.item.group.name == "Effect Beacon"), None)
|
||||
|
||||
if oldEffect:
|
||||
pyfalog.info("System effect occupied with {0}, replacing with {1}", oldEffect.item.name, proj.item.name)
|
||||
self.remove(oldEffect)
|
||||
return oldEffect.itemID
|
||||
return None
|
||||
|
||||
|
||||
class HandledProjectedDroneList(HandledDroneCargoList):
|
||||
def append(self, proj):
|
||||
|
||||
@@ -6,4 +6,4 @@ type = "passive"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
fit.ship.boostItemAttr("agility", module.getModifiedItemAttr("agilityMultiplier"), stackingPenalties=True)
|
||||
fit.ship.boostItemAttr("agility", module.getModifiedItemAttr("agilityBonus"), stackingPenalties=True)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# boosterArmorHpPenalty
|
||||
#
|
||||
# Used by:
|
||||
# Implants named like: Booster (12 of 33)
|
||||
# Implants named like: Booster (12 of 35)
|
||||
type = "boosterSideEffect"
|
||||
|
||||
# User-friendly name for the side effect
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# boosterShieldCapacityPenalty
|
||||
#
|
||||
# Used by:
|
||||
# Implants from group: Booster (12 of 66)
|
||||
# Implants from group: Booster (12 of 69)
|
||||
type = "boosterSideEffect"
|
||||
|
||||
# User-friendly name for the side effect
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Carrier (4 of 4)
|
||||
# Ships from group: Combat Battlecruiser (13 of 13)
|
||||
# Ships from group: Combat Battlecruiser (14 of 14)
|
||||
# Ships from group: Command Ship (8 of 8)
|
||||
# Ships from group: Force Auxiliary (6 of 6)
|
||||
# Ships from group: Supercarrier (6 of 6)
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
# Used by:
|
||||
# Ships from group: Black Ops (5 of 5)
|
||||
# Ships from group: Blockade Runner (4 of 4)
|
||||
# Ships from group: Covert Ops (7 of 7)
|
||||
# Ships from group: Covert Ops (8 of 8)
|
||||
# Ships from group: Expedition Frigate (2 of 2)
|
||||
# Ships from group: Force Recon Ship (8 of 8)
|
||||
# Ships from group: Force Recon Ship (9 of 9)
|
||||
# Ships from group: Stealth Bomber (5 of 5)
|
||||
# Ships named like: Stratios (2 of 2)
|
||||
# Subsystems named like: Defensive Covert Reconfiguration (4 of 4)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# covertOpsCloakCpuPercentBonus1
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Covert Ops (5 of 7)
|
||||
# Ships from group: Covert Ops (6 of 8)
|
||||
type = "passive"
|
||||
runTime = "early"
|
||||
|
||||
|
||||
9
eos/effects/covertopswarpresistance.py
Normal file
9
eos/effects/covertopswarpresistance.py
Normal file
@@ -0,0 +1,9 @@
|
||||
# covertOpsWarpResistance
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Covert Ops (5 of 8)
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.ship.increaseItemAttr("warpFactor", src.getModifiedItemAttr("eliteBonusCovertOps1"), skill="Covert Ops")
|
||||
@@ -1,7 +1,7 @@
|
||||
# cynosuralDurationBonus
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Force Recon Ship (7 of 8)
|
||||
# Ships from group: Force Recon Ship (8 of 9)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# cynosuralTheoryConsumptionBonus
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Force Recon Ship (7 of 8)
|
||||
# Ships from group: Force Recon Ship (8 of 9)
|
||||
# Skill: Cynosural Field Theory
|
||||
type = "passive"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# disintegratorWeaponDamageMultiply
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Entropic Radiation Sink (3 of 3)
|
||||
# Modules from group: Entropic Radiation Sink (4 of 4)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# disintegratorWeaponSpeedMultiply
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Entropic Radiation Sink (3 of 3)
|
||||
# Modules from group: Entropic Radiation Sink (4 of 4)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#
|
||||
# Used by:
|
||||
# Modules named like: Drone Speed Augmentor (6 of 8)
|
||||
# Implant: Overmind 'Goliath' Drone Tuner T25-10S
|
||||
# Implant: Overmind 'Hawkmoth' Drone Tuner S10-25T
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# eliteBonusCoverOpsScanProbeStrength2
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Covert Ops (7 of 7)
|
||||
# Ships from group: Covert Ops (8 of 8)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
10
eos/effects/elitebonuscovertops3pctdamagepercycle.py
Normal file
10
eos/effects/elitebonuscovertops3pctdamagepercycle.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# eliteBonusCovertOps3PCTdamagePerCycle
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Hydra
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredItemIncrease(lambda mod: mod.item.requiresSkill("Small Precursor Weapon"), "damageMultiplierBonusPerCycle",
|
||||
src.getModifiedItemAttr("eliteBonusCovertOps3"), skill="Covert Ops")
|
||||
10
eos/effects/elitebonusreconscanprobestrength2.py
Normal file
10
eos/effects/elitebonusreconscanprobestrength2.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# eliteBonusReconScanProbeStrength2
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Tiamat
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Astrometrics"), "baseSensorStrength",
|
||||
src.getModifiedItemAttr("eliteBonusReconShip2"), skill="Recon Ships")
|
||||
10
eos/effects/elitebonusreconship3pctdamagepercycle.py
Normal file
10
eos/effects/elitebonusreconship3pctdamagepercycle.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# eliteBonusReconShip3PCTdamagePerCycle
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Tiamat
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredItemIncrease(lambda mod: mod.item.requiresSkill("Medium Precursor Weapon"), "damageMultiplierBonusPerCycle",
|
||||
src.getModifiedItemAttr("eliteBonusReconShip3"), skill="Recon Ships")
|
||||
11
eos/effects/emergencyhullenergizer.py
Normal file
11
eos/effects/emergencyhullenergizer.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# emergencyHullEnergizer
|
||||
#
|
||||
# Used by:
|
||||
# Variations of module: Capital Emergency Hull Energizer I (5 of 5)
|
||||
type = "active"
|
||||
runtime = "late"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
for dmgType in ('em', 'thermal', 'kinetic', 'explosive'):
|
||||
fit.ship.forceItemAttr('{}DamageResonance'.format(dmgType), src.getModifiedItemAttr("hull{}DamageResonance".format(dmgType.title())))
|
||||
@@ -1,7 +1,7 @@
|
||||
# energyWeaponDamageMultiply
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Heat Sink (18 of 18)
|
||||
# Modules from group: Heat Sink (19 of 19)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# energyWeaponSpeedMultiply
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Heat Sink (18 of 18)
|
||||
# Modules from group: Heat Sink (19 of 19)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -7,3 +7,9 @@ type = "active"
|
||||
|
||||
def handler(fit, module, context):
|
||||
fit.ship.forceItemAttr("disallowAssistance", module.getModifiedItemAttr("disallowAssistance"))
|
||||
for scanType in ("Gravimetric", "Magnetometric", "Radar", "Ladar"):
|
||||
fit.ship.boostItemAttr(
|
||||
"scan{}Strength".format(scanType),
|
||||
module.getModifiedItemAttr("scan{}StrengthPercent".format(scanType)),
|
||||
stackingPenalties=True
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# hybridWeaponDamageMultiply
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Magnetic Field Stabilizer (14 of 14)
|
||||
# Modules from group: Magnetic Field Stabilizer (15 of 15)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# hybridWeaponSpeedMultiply
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Magnetic Field Stabilizer (14 of 14)
|
||||
# Modules from group: Magnetic Field Stabilizer (15 of 15)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
17
eos/effects/massentanglereffect5.py
Normal file
17
eos/effects/massentanglereffect5.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# massEntanglerEffect5
|
||||
#
|
||||
# Used by:
|
||||
# Module: Zero-Point Mass Entangler
|
||||
type = "active"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.ship.increaseItemAttr("warpScrambleStatus", src.getModifiedItemAttr("warpScrambleStrength"))
|
||||
fit.ship.boostItemAttr("mass", src.getModifiedItemAttr("massBonusPercentage"), stackingPenalties=True)
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Afterburner"), "speedFactor",
|
||||
src.getModifiedItemAttr("speedFactorBonus"), stackingPenalties=True)
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Afterburner"), "speedBoostFactor",
|
||||
src.getModifiedItemAttr("speedBoostFactorBonus"))
|
||||
fit.modules.filteredItemIncrease(lambda mod: mod.item.requiresSkill("High Speed Maneuvering"), "activationBlocked",
|
||||
src.getModifiedItemAttr("activationBlockedStrenght"))
|
||||
fit.ship.boostItemAttr("maxVelocity", src.getModifiedItemAttr("maxVelocityBonus"), stackingPenalties=True)
|
||||
@@ -5,5 +5,6 @@
|
||||
type = "active"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
pass
|
||||
def handler(fit, module, context):
|
||||
fit.ship.boostItemAttr("signatureRadius", module.getModifiedItemAttr("signatureRadiusBonusPercent"),
|
||||
stackingPenalties=True)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# minigameVirusStrengthBonus
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Covert Ops (7 of 7)
|
||||
# Ships from group: Covert Ops (7 of 8)
|
||||
# Ships named like: Stratios (2 of 2)
|
||||
# Subsystems named like: Defensive Covert Reconfiguration (4 of 4)
|
||||
# Ship: Astero
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
# Modules from group: Frequency Mining Laser (3 of 3)
|
||||
# Modules from group: Mining Laser (15 of 15)
|
||||
# Modules from group: Strip Miner (5 of 5)
|
||||
# Module: Citizen Miner
|
||||
type = 'active'
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# missileDMGBonus
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Ballistic Control system (20 of 20)
|
||||
# Modules from group: Ballistic Control system (21 of 21)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# missileLauncherSpeedMultiplier
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Ballistic Control system (20 of 20)
|
||||
# Modules from group: Ballistic Control system (21 of 21)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# Used by:
|
||||
# Modules from group: Drone Damage Modules (11 of 11)
|
||||
# Modules named like: C3 'Hivaa Saitsuo' Ballistic Control System (2 of 2)
|
||||
# Module: Abyssal Ballistic Control System
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
# Used by:
|
||||
# Variations of module: Armor Command Burst I (2 of 2)
|
||||
|
||||
'''
|
||||
"""
|
||||
Some documentation:
|
||||
When the fit is calculated, we gather up all the gang effects and stick them onto the fit. We don't run the actual
|
||||
effect yet, only give the fit details so that it can run the effect at a later time. We need to do this so that we can
|
||||
only run the strongest effect. When we are done, one of the last things that we do with the fit is to loop through those
|
||||
bonuses and actually run the effect. To do this, we have a special argument passed into the effect handler that tells it
|
||||
which warfareBuffID to run (shouldn't need this right now, but better safe than sorry)
|
||||
'''
|
||||
"""
|
||||
|
||||
type = "active", "gang"
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
# Modules from group: Hull Repair Unit (25 of 25)
|
||||
# Modules from group: Remote Armor Repairer (39 of 39)
|
||||
# Modules from group: Remote Capacitor Transmitter (41 of 41)
|
||||
# Modules from group: Remote Hull Repairer (8 of 8)
|
||||
# Modules from group: Remote Shield Booster (38 of 38)
|
||||
# Modules from group: Smart Bomb (118 of 118)
|
||||
# Modules from group: Warp Disrupt Field Generator (7 of 7)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# projectileWeaponDamageMultiply
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Gyrostabilizer (13 of 13)
|
||||
# Modules from group: Gyrostabilizer (14 of 14)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# projectileWeaponSpeedMultiply
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Gyrostabilizer (13 of 13)
|
||||
# Modules from group: Gyrostabilizer (14 of 14)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# reconShipCloakCpuBonus1
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Force Recon Ship (6 of 8)
|
||||
# Ships from group: Force Recon Ship (7 of 9)
|
||||
type = "passive"
|
||||
runTime = "early"
|
||||
|
||||
|
||||
13
eos/effects/rolebonuswarpspeed.py
Normal file
13
eos/effects/rolebonuswarpspeed.py
Normal file
@@ -0,0 +1,13 @@
|
||||
# roleBonusWarpSpeed
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Cynabal
|
||||
# Ship: Dramiel
|
||||
# Ship: Leopard
|
||||
# Ship: Machariel
|
||||
# Ship: Victorieux Luxury Yacht
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.ship.boostItemAttr("warpSpeedMultiplier", src.getModifiedItemAttr("shipRoleBonusWarpSpeed"))
|
||||
@@ -3,6 +3,7 @@
|
||||
# Used by:
|
||||
# Structure Modules from group: Structure Citadel Service Module (2 of 2)
|
||||
# Structure Modules from group: Structure Engineering Service Module (6 of 6)
|
||||
# Structure Modules from group: Structure Navigation Service Module (3 of 3)
|
||||
# Structure Modules from group: Structure Resource Processing Service Module (4 of 4)
|
||||
# Structure Module: Standup Moon Drill I
|
||||
type = "passive"
|
||||
|
||||
10
eos/effects/shiparmoremresistancepbc2.py
Normal file
10
eos/effects/shiparmoremresistancepbc2.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# shipArmorEMResistancePBC2
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Drekavac
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, ship, context):
|
||||
fit.ship.boostItemAttr("armorEmDamageResonance", ship.getModifiedItemAttr("shipBonusPBC2"),
|
||||
skill="Precursor Battlecruiser")
|
||||
10
eos/effects/shiparmorexplosiveresistancepbc2.py
Normal file
10
eos/effects/shiparmorexplosiveresistancepbc2.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# shipArmorExplosiveResistancePBC2
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Drekavac
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, ship, context):
|
||||
fit.ship.boostItemAttr("armorExplosiveDamageResonance", ship.getModifiedItemAttr("shipBonusPBC2"),
|
||||
skill="Precursor Battlecruiser")
|
||||
10
eos/effects/shiparmorkineticresistancepbc2.py
Normal file
10
eos/effects/shiparmorkineticresistancepbc2.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# shipArmorKineticResistancePBC2
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Drekavac
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, ship, context):
|
||||
fit.ship.boostItemAttr("armorKineticDamageResonance", ship.getModifiedItemAttr("shipBonusPBC2"),
|
||||
skill="Precursor Battlecruiser")
|
||||
10
eos/effects/shiparmorthermalresistancepbc2.py
Normal file
10
eos/effects/shiparmorthermalresistancepbc2.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# shipArmorThermalResistancePBC2
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Drekavac
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, ship, context):
|
||||
fit.ship.boostItemAttr("armorThermalDamageResonance", ship.getModifiedItemAttr("shipBonusPBC2"),
|
||||
skill="Precursor Battlecruiser")
|
||||
@@ -1,8 +1,7 @@
|
||||
# shipBonusDreadnoughtC2ShieldResists
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Caiman
|
||||
# Ship: Phoenix
|
||||
# Variations of ship: Phoenix (2 of 2)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
# shipBonusForceAuxiliaryA3CapCapacity
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Apostle
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.ship.boostItemAttr("capacitorCapacity", src.getModifiedItemAttr("shipBonusForceAuxiliaryA3"),
|
||||
skill="Amarr Carrier")
|
||||
@@ -1,8 +1,7 @@
|
||||
# shipBonusForceAuxiliaryC2ShieldResists
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Loggerhead
|
||||
# Ship: Minokawa
|
||||
# Variations of ship: Minokawa (2 of 2)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
# shipBonusForceAuxiliaryC3CapCapacity
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Minokawa
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.ship.boostItemAttr("capacitorCapacity", src.getModifiedItemAttr("shipBonusForceAuxiliaryC3"),
|
||||
skill="Caldari Carrier")
|
||||
@@ -1,10 +0,0 @@
|
||||
# shipBonusForceAuxiliaryG3CapBoosterStrength
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Ninazu
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.group.name == "Capacitor Booster Charge", "capacitorBonus",
|
||||
src.getModifiedItemAttr("shipBonusForceAuxiliaryG3"), skill="Gallente Carrier")
|
||||
@@ -1,10 +0,0 @@
|
||||
# shipBonusForceAuxiliaryM3CapBoosterStrength
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Lif
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.group.name == "Capacitor Booster Charge", "capacitorBonus",
|
||||
src.getModifiedItemAttr("shipBonusForceAuxiliaryM3"), skill="Minmatar Carrier")
|
||||
@@ -2,7 +2,11 @@
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Damavik
|
||||
# Ship: Drekavac
|
||||
# Ship: Hydra
|
||||
# Ship: Kikimora
|
||||
# Ship: Leshak
|
||||
# Ship: Tiamat
|
||||
# Ship: Vedmak
|
||||
type = "passive"
|
||||
|
||||
|
||||
11
eos/effects/shipbonuspbc1disintegratordamage.py
Normal file
11
eos/effects/shipbonuspbc1disintegratordamage.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# shipBonusPBC1DisintegratorDamage
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Drekavac
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Precursor Weapon"),
|
||||
"damageMultiplier", ship.getModifiedItemAttr("shipBonusPBC1"),
|
||||
skill="Precursor Battlecruiser")
|
||||
@@ -1,6 +1,7 @@
|
||||
# shipbonusPCTDamagePC1
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Tiamat
|
||||
# Ship: Vedmak
|
||||
type = "passive"
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Damavik
|
||||
# Ship: Hydra
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Damavik
|
||||
# Ship: Hydra
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# shipbonusPCTTrackingPC2
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Tiamat
|
||||
# Ship: Vedmak
|
||||
type = "passive"
|
||||
|
||||
|
||||
11
eos/effects/shipbonuspd1disintegratordamage.py
Normal file
11
eos/effects/shipbonuspd1disintegratordamage.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# shipBonusPD1DisintegratorDamage
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Kikimora
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Small Precursor Weapon"),
|
||||
"damageMultiplier", ship.getModifiedItemAttr("shipBonusPD1"),
|
||||
skill="Precursor Destroyer")
|
||||
11
eos/effects/shipbonuspd2disintegratormaxrange.py
Normal file
11
eos/effects/shipbonuspd2disintegratormaxrange.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# shipBonusPD2DisintegratorMaxRange
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Kikimora
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Small Precursor Weapon"),
|
||||
"maxRange", ship.getModifiedItemAttr("shipBonusPD2"),
|
||||
skill="Precursor Destroyer")
|
||||
@@ -2,7 +2,11 @@
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Damavik
|
||||
# Ship: Drekavac
|
||||
# Ship: Hydra
|
||||
# Ship: Kikimora
|
||||
# Ship: Leshak
|
||||
# Ship: Tiamat
|
||||
# Ship: Vedmak
|
||||
type = "passive"
|
||||
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Damavik
|
||||
# Ship: Drekavac
|
||||
# Ship: Hydra
|
||||
# Ship: Kikimora
|
||||
# Ship: Leshak
|
||||
# Ship: Tiamat
|
||||
# Ship: Vedmak
|
||||
type = "passive"
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
# shipBonusRole3XLTorpdeoVelocityBonus
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Komodo
|
||||
# Ship: Leviathan
|
||||
# Variations of ship: Leviathan (2 of 2)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Damavik
|
||||
# Ship: Drekavac
|
||||
# Ship: Hydra
|
||||
# Ship: Kikimora
|
||||
# Ship: Leshak
|
||||
# Ship: Tiamat
|
||||
# Ship: Vedmak
|
||||
type = "passive"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# shipBonusSurveyProbeExplosionDelaySkillSurveyCovertOps3
|
||||
#
|
||||
# Used by:
|
||||
# Ships from group: Covert Ops (5 of 7)
|
||||
# Ships from group: Covert Ops (5 of 8)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
# shipBonusTitanA3WarpStrength
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Avatar
|
||||
# Ship: Molok
|
||||
# Variations of ship: Avatar (2 of 2)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
# shipBonusTitanC2ROFBonus
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Komodo
|
||||
# Ship: Leviathan
|
||||
# Variations of ship: Leviathan (2 of 2)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
# shipBonusTitanC3WarpStrength
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Komodo
|
||||
# Ship: Leviathan
|
||||
# Variations of ship: Leviathan (2 of 2)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
10
eos/effects/shiproledisintegratormaxrangecbc.py
Normal file
10
eos/effects/shiproledisintegratormaxrangecbc.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# shipRoleDisintegratorMaxRangeCBC
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Drekavac
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Precursor Weapon"),
|
||||
"maxRange", ship.getModifiedItemAttr("roleBonusCBC"))
|
||||
@@ -1,7 +1,7 @@
|
||||
# skillBonusDroneDurability
|
||||
#
|
||||
# Used by:
|
||||
# Implants from group: Cyber Drones (2 of 2)
|
||||
# Implants from group: Cyber Drones (4 of 4)
|
||||
# Skill: Drone Durability
|
||||
type = "passive"
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# skillBonusDroneInterfacing
|
||||
#
|
||||
# Used by:
|
||||
# Implants from group: Cyber Drones (2 of 2)
|
||||
# Implant: CreoDron 'Bumblebee' Drone Tuner T10-5D
|
||||
# Implant: CreoDron 'Yellowjacket' Drone Tuner D5-10T
|
||||
# Skill: Drone Interfacing
|
||||
type = "passive"
|
||||
|
||||
|
||||
10
eos/effects/smalldisintegratormaxrangebonus.py
Normal file
10
eos/effects/smalldisintegratormaxrangebonus.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# smallDisintegratorMaxRangeBonus
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Kikimora
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, ship, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Small Precursor Weapon"),
|
||||
"maxRange", ship.getModifiedItemAttr("maxRangeBonus"))
|
||||
@@ -1,7 +1,8 @@
|
||||
# structureAoERoFRoleBonus
|
||||
#
|
||||
# Used by:
|
||||
# Items from category: Structure (11 of 14)
|
||||
# Items from category: Structure (11 of 17)
|
||||
# Structures from group: Citadel (8 of 9)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# structureArmorHPMultiply
|
||||
# structureArmorHPBonus
|
||||
#
|
||||
# Used by:
|
||||
# Structure Modules from group: Structure Armor Reinforcer (2 of 2)
|
||||
@@ -7,4 +7,4 @@ runTime = "early"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.ship.multiplyItemAttr("hiddenArmorHPMultiplier", src.getModifiedItemAttr("armorHPMultiplier"))
|
||||
fit.ship.boostItemAttr("hiddenArmorHPMultiplier", src.getModifiedItemAttr("armorHpBonus"), stackingPenalties=True)
|
||||
@@ -1,7 +1,7 @@
|
||||
# structureFullPowerStateHitpointModifier
|
||||
#
|
||||
# Used by:
|
||||
# Items from category: Structure (14 of 14)
|
||||
# Items from category: Structure (17 of 17)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# structureHiddenArmorHPMultiplier
|
||||
#
|
||||
# Used by:
|
||||
# Items from category: Structure (14 of 14)
|
||||
# Items from category: Structure (17 of 17)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# structureHiddenMissileDamageMultiplier
|
||||
#
|
||||
# Used by:
|
||||
# Items from category: Structure (14 of 14)
|
||||
# Items from category: Structure (14 of 17)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# targetAttack
|
||||
#
|
||||
# Used by:
|
||||
# Drones from group: Combat Drone (74 of 74)
|
||||
# Drones from group: Combat Drone (75 of 75)
|
||||
# Modules from group: Energy Weapon (212 of 214)
|
||||
type = 'active'
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# warpScramble
|
||||
# warpDisrupt
|
||||
#
|
||||
# Used by:
|
||||
# Modules named like: Warp Disruptor (28 of 28)
|
||||
@@ -4,15 +4,15 @@
|
||||
# Celestial: darkness_weather_1
|
||||
# Celestial: darkness_weather_2
|
||||
# Celestial: darkness_weather_3
|
||||
# Celestial: pvp_weather_1
|
||||
runTime = "early"
|
||||
type = ("projected", "passive", "gang")
|
||||
|
||||
|
||||
def handler(fit, beacon, context, **kwargs):
|
||||
for x in range(1, 3):
|
||||
for x in range(1, 5):
|
||||
if beacon.getModifiedItemAttr("warfareBuff{}ID".format(x)):
|
||||
value = beacon.getModifiedItemAttr("warfareBuff{}Value".format(x))
|
||||
id = beacon.getModifiedItemAttr("warfareBuff{}ID".format(x))
|
||||
|
||||
if id:
|
||||
fit.addCommandBonus(id, value, beacon, kwargs['effect'], 'early')
|
||||
|
||||
@@ -166,14 +166,14 @@ class Effect(EqBase):
|
||||
|
||||
t = t if isinstance(t, tuple) or t is None else (t,)
|
||||
self.__type = t
|
||||
except (ImportError) as e:
|
||||
except ImportError as e:
|
||||
# Effect probably doesn't exist, so create a dummy effect and flag it with a warning.
|
||||
self.__handler = effectDummy
|
||||
self.__runTime = "normal"
|
||||
self.__activeByDefault = True
|
||||
self.__type = None
|
||||
pyfalog.debug("ImportError generating handler: {0}", e)
|
||||
except (AttributeError) as e:
|
||||
except AttributeError as e:
|
||||
# Effect probably exists but there is an issue with it. Turn it into a dummy effect so we can continue, but flag it with an error.
|
||||
self.__handler = effectDummy
|
||||
self.__runTime = "normal"
|
||||
@@ -476,6 +476,10 @@ class Item(EqBase):
|
||||
def getAbyssalYypes(cls):
|
||||
cls.ABYSSAL_TYPES = eos.db.getAbyssalTypes()
|
||||
|
||||
@property
|
||||
def isCharge(self):
|
||||
return self.category.name == "Charge"
|
||||
|
||||
def __repr__(self):
|
||||
return "Item(ID={}, name={}) at {}".format(
|
||||
self.ID, self.name, hex(id(self))
|
||||
@@ -563,51 +567,67 @@ class Unit(EqBase):
|
||||
""" This is a mapping of various tweaks that we have to do between the internal representation of an attribute
|
||||
value and the display (for example, 'Millisecond' units have the display name of 's', so we have to convert value
|
||||
from ms to s) """
|
||||
# Each entry contains:
|
||||
# Function to convert value to display value
|
||||
# Function to convert value to display format (which sometimes can be a string)
|
||||
# Function which controls unit name used with attribute
|
||||
# Function to convert display value to value
|
||||
return {
|
||||
"Inverse Absolute Percent": (
|
||||
lambda v: (1 - v) * 100,
|
||||
lambda d: -1 * (d / 100) + 1,
|
||||
lambda u: u),
|
||||
lambda v: (1 - v) * 100,
|
||||
lambda u: u,
|
||||
lambda d: -1 * (d / 100) + 1),
|
||||
"Inversed Modifier Percent": (
|
||||
lambda v: (1 - v) * 100,
|
||||
lambda d: -1 * (d / 100) + 1,
|
||||
lambda u: u),
|
||||
lambda v: (1 - v) * 100,
|
||||
lambda u: u,
|
||||
lambda d: -1 * (d / 100) + 1),
|
||||
"Modifier Percent": (
|
||||
lambda v: (v - 1) * 100,
|
||||
lambda v: ("%+.2f" if ((v - 1) * 100) % 1 else "%+d") % ((v - 1) * 100),
|
||||
lambda d: (d / 100) + 1,
|
||||
lambda u: u),
|
||||
lambda u: u,
|
||||
lambda d: (d / 100) + 1),
|
||||
"Volume": (
|
||||
lambda v: v,
|
||||
lambda d: d,
|
||||
lambda u: "m³"),
|
||||
lambda v: v,
|
||||
lambda u: "m³",
|
||||
lambda d: d),
|
||||
"Sizeclass": (
|
||||
lambda v: v,
|
||||
lambda d: d,
|
||||
lambda u: ""),
|
||||
lambda v: v,
|
||||
lambda u: "",
|
||||
lambda d: d),
|
||||
"Absolute Percent": (
|
||||
lambda v: (v * 100),
|
||||
lambda d: d / 100,
|
||||
lambda u: u),
|
||||
lambda v: v * 100,
|
||||
lambda v: v * 100,
|
||||
lambda u: u,
|
||||
lambda d: d / 100),
|
||||
"Milliseconds": (
|
||||
lambda v: v / 1000.0,
|
||||
lambda d: d * 1000.0,
|
||||
lambda u: u),
|
||||
lambda v: v / 1000,
|
||||
lambda v: v / 1000,
|
||||
lambda u: u,
|
||||
lambda d: d * 1000),
|
||||
"Boolean": (
|
||||
lambda v: "Yes" if v == 1 else "No",
|
||||
lambda d: 1.0 if d == "Yes" else 0.0,
|
||||
lambda u: ""),
|
||||
lambda v: True if v else False,
|
||||
lambda v: "Yes" if v else "No",
|
||||
lambda u: "",
|
||||
lambda d: 1.0 if d == "Yes" else 0.0),
|
||||
"typeID": (
|
||||
self.itemIDCallback,
|
||||
None, # we could probably convert these back if we really tried hard enough
|
||||
lambda u: ""),
|
||||
self.itemIDCallback,
|
||||
lambda u: "",
|
||||
None), # we could probably convert these back if we really tried hard enough
|
||||
"groupID": (
|
||||
self.groupIDCallback,
|
||||
None,
|
||||
lambda u: ""),
|
||||
self.groupIDCallback,
|
||||
lambda u: "",
|
||||
None),
|
||||
"attributeID": (
|
||||
self.attributeIDCallback,
|
||||
None,
|
||||
lambda u: ""),
|
||||
self.attributeIDCallback,
|
||||
lambda u: "",
|
||||
None),
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
@@ -626,29 +646,37 @@ class Unit(EqBase):
|
||||
def attributeIDCallback(v):
|
||||
v = int(v)
|
||||
if not v: # some attributes come through with a value of 0? See #1387
|
||||
return "%d" % (v)
|
||||
attribute = eos.db.getAttributeInfo(v, eager=("unit"))
|
||||
return "%d" % v
|
||||
attribute = eos.db.getAttributeInfo(v, eager="unit")
|
||||
return "%s (%d)" % (attribute.name.capitalize(), v)
|
||||
|
||||
def TranslateValue(self, value):
|
||||
def PreformatValue(self, value):
|
||||
"""Attributes have to be translated certain ways based on their unit (ex: decimals converting to percentages).
|
||||
This allows us to get an easy representation of how the attribute should be printed """
|
||||
|
||||
override = self.translations.get(self.name)
|
||||
if override is not None:
|
||||
return override[0](value), override[2](self.displayName)
|
||||
return override[1](value), override[2](self.displayName)
|
||||
|
||||
return value, self.displayName
|
||||
|
||||
def SimplifyValue(self, value):
|
||||
"""Takes the internal representation value and convert it into the display value"""
|
||||
|
||||
override = self.translations.get(self.name)
|
||||
if override is not None:
|
||||
return override[0](value)
|
||||
|
||||
return value
|
||||
|
||||
def ComplicateValue(self, value):
|
||||
"""Takes the display value and turns it back into the internal representation of it"""
|
||||
|
||||
override = self.translations.get(self.name)
|
||||
if override is not None:
|
||||
return override[1](value)
|
||||
return override[3](value)
|
||||
|
||||
return value
|
||||
|
||||
|
||||
class Traits(EqBase):
|
||||
pass
|
||||
|
||||
@@ -93,6 +93,8 @@ class FitDpsGraph(Graph):
|
||||
|
||||
# this is janky as fuck
|
||||
for fighter in fit.fighters:
|
||||
if not fighter.active:
|
||||
continue
|
||||
for ability in fighter.abilities:
|
||||
if ability.dealsDamage and ability.active:
|
||||
multiplier = self.calculateFighterMissileMultiplier(ability, data)
|
||||
|
||||
@@ -34,10 +34,10 @@ class ItemAttrShortcut(object):
|
||||
return return_value or default
|
||||
|
||||
def getBaseAttrValue(self, key, default=0):
|
||||
'''
|
||||
"""
|
||||
Gets base value in this order:
|
||||
Mutated value > override value > attribute value
|
||||
'''
|
||||
"""
|
||||
return_value = self.itemModifiedAttributes.getOriginal(key)
|
||||
|
||||
return return_value or default
|
||||
@@ -382,7 +382,7 @@ class ModifiedAttributeDict(collections.MutableMapping):
|
||||
if resist:
|
||||
afflictPenal += "r"
|
||||
|
||||
self.__afflict(attributeName, "%s*" % (afflictPenal), multiplier, multiplier != 1)
|
||||
self.__afflict(attributeName, "%s*" % afflictPenal, multiplier, multiplier != 1)
|
||||
|
||||
def boost(self, attributeName, boostFactor, skill=None, *args, **kwargs):
|
||||
"""Boost value by some percentage"""
|
||||
|
||||
@@ -124,6 +124,10 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
def dps(self):
|
||||
return self.damageStats()
|
||||
|
||||
def changeType(self, typeID):
|
||||
self.itemID = typeID
|
||||
self.init()
|
||||
|
||||
def damageStats(self, targetResists=None):
|
||||
if self.__dps is None:
|
||||
self.__volley = 0
|
||||
|
||||
@@ -53,6 +53,20 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
|
||||
self.build()
|
||||
|
||||
standardAttackActive = False
|
||||
for ability in self.abilities:
|
||||
if ability.effect.isImplemented and ability.effect.handlerName == 'fighterabilityattackm':
|
||||
# Activate "standard attack" if available
|
||||
ability.active = True
|
||||
standardAttackActive = True
|
||||
else:
|
||||
# Activate all other abilities (Neut, Web, etc) except propmods if no standard attack is active
|
||||
if ability.effect.isImplemented and \
|
||||
standardAttackActive is False and \
|
||||
ability.effect.handlerName != 'fighterabilitymicrowarpdrive' and \
|
||||
ability.effect.handlerName != 'fighterabilityevasivemaneuvers':
|
||||
ability.active = True
|
||||
|
||||
@reconstructor
|
||||
def init(self):
|
||||
"""Initialize a fighter from the database and validate"""
|
||||
|
||||
@@ -35,7 +35,6 @@ from eos.saveddata.character import Character
|
||||
from eos.saveddata.citadel import Citadel
|
||||
from eos.saveddata.module import Module, State, Slot, Hardpoint
|
||||
from logbook import Logger
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
@@ -258,11 +257,11 @@ class Fit(object):
|
||||
def projectedFits(self):
|
||||
# only in extreme edge cases will the fit be invalid, but to be sure do
|
||||
# not return them.
|
||||
return [fit for fit in list(self.__projectedFits.values()) if not fit.isInvalid]
|
||||
return [fit for fit in list(self.projectedFitDict.values()) if not fit.isInvalid]
|
||||
|
||||
@property
|
||||
def commandFits(self):
|
||||
return [fit for fit in list(self.__commandFits.values()) if not fit.isInvalid]
|
||||
return [fit for fit in list(self.commandFitDict.values()) if not fit.isInvalid]
|
||||
|
||||
def getProjectionInfo(self, fitID):
|
||||
return self.projectedOnto.get(fitID, None)
|
||||
@@ -685,17 +684,15 @@ class Fit(object):
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"),
|
||||
"armorDamageAmount", value, stackingPenalties=True)
|
||||
|
||||
if warfareBuffID == 88: # AOE_Beacon_filament_cloud_shield_booster
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Operation") or
|
||||
mod.item.requiresSkill("Shield Emission Systems"),
|
||||
"capacitorNeed", value, stackingPenalties=True)
|
||||
if warfareBuffID == 88: # AOE_Beacon_filament_cloud_shield_booster_shield_bonus
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Operation"),
|
||||
"shieldBonus", value, stackingPenalties=True)
|
||||
|
||||
if warfareBuffID == 89: # AOE_Beacon_filament_cloud_ancillary_charge_usage
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Operation") or
|
||||
mod.item.requiresSkill("Shield Emission Systems"),
|
||||
"chargeRate", value, stackingPenalties=True)
|
||||
if warfareBuffID == 89: # AOE_Beacon_filament_cloud_shield_booster_duration
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Operation"),
|
||||
"duration", value, stackingPenalties=True)
|
||||
|
||||
# Abysmal Weather Effects
|
||||
# Abyssal Weather Effects
|
||||
|
||||
if warfareBuffID == 90: # Weather_electric_storm_EM_resistance_penalty
|
||||
for tankType in ("shield", "armor"):
|
||||
@@ -913,6 +910,9 @@ class Fit(object):
|
||||
Fill this fit's module slots with enough dummy slots so that all slots are used.
|
||||
This is mostly for making the life of gui's easier.
|
||||
GUI's can call fill() and then stop caring about empty slots completely.
|
||||
|
||||
todo: want to get rid of using this from the gui/commands, and instead make it a more built-in feature within
|
||||
recalc. Figure out a way to keep track of any changes to slot layout and call this automatically
|
||||
"""
|
||||
if self.ship is None:
|
||||
return
|
||||
@@ -1605,7 +1605,7 @@ class Fit(object):
|
||||
eos.db.saveddata_session.refresh(fit)
|
||||
|
||||
for fit in self.commandFits:
|
||||
copy_ship.__commandFits[fit.ID] = fit
|
||||
copy_ship.commandFitDict[fit.ID] = fit
|
||||
forceUpdateSavedata(fit)
|
||||
copyCommandInfo = fit.getCommandInfo(copy_ship.ID)
|
||||
originalCommandInfo = fit.getCommandInfo(self.ID)
|
||||
@@ -1613,7 +1613,7 @@ class Fit(object):
|
||||
forceUpdateSavedata(fit)
|
||||
|
||||
for fit in self.projectedFits:
|
||||
copy_ship.__projectedFits[fit.ID] = fit
|
||||
copy_ship.projectedFitDict[fit.ID] = fit
|
||||
forceUpdateSavedata(fit)
|
||||
copyProjectionInfo = fit.getProjectionInfo(copy_ship.ID)
|
||||
originalProjectionInfo = fit.getProjectionInfo(self.ID)
|
||||
|
||||
@@ -17,16 +17,15 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
from logbook import Logger
|
||||
from copy import deepcopy
|
||||
|
||||
from sqlalchemy.orm import validates, reconstructor
|
||||
from math import floor
|
||||
|
||||
from logbook import Logger
|
||||
from sqlalchemy.orm import reconstructor, validates
|
||||
|
||||
import eos.db
|
||||
from eos.effectHandlerHelpers import HandledItem, HandledCharge
|
||||
from eos.effectHandlerHelpers import HandledCharge, HandledItem
|
||||
from eos.enum import Enum
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut, ChargeAttrShortcut
|
||||
from eos.modifiedAttributeDict import ChargeAttrShortcut, ItemAttrShortcut, ModifiedAttributeDict
|
||||
from eos.saveddata.citadel import Citadel
|
||||
from eos.saveddata.mutator import Mutator
|
||||
|
||||
@@ -64,6 +63,30 @@ class Slot(Enum):
|
||||
FS_HEAVY = 15
|
||||
|
||||
|
||||
ProjectedMap = {
|
||||
State.OVERHEATED: State.ACTIVE,
|
||||
State.ACTIVE: State.OFFLINE,
|
||||
State.OFFLINE: State.ACTIVE,
|
||||
State.ONLINE: State.ACTIVE # Just in case
|
||||
}
|
||||
|
||||
|
||||
# Old state : New State
|
||||
LocalMap = {
|
||||
State.OVERHEATED: State.ACTIVE,
|
||||
State.ACTIVE: State.ONLINE,
|
||||
State.OFFLINE: State.ONLINE,
|
||||
State.ONLINE: State.ACTIVE
|
||||
}
|
||||
|
||||
|
||||
# For system effects. They should only ever be online or offline
|
||||
ProjectedSystem = {
|
||||
State.OFFLINE: State.ONLINE,
|
||||
State.ONLINE: State.OFFLINE
|
||||
}
|
||||
|
||||
|
||||
class Hardpoint(Enum):
|
||||
NONE = 0
|
||||
MISSILE = 1
|
||||
@@ -626,7 +649,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
for i in range(5):
|
||||
itemChargeGroup = self.getModifiedItemAttr('chargeGroup' + str(i), None)
|
||||
if itemChargeGroup is not None:
|
||||
g = eos.db.getGroup(int(itemChargeGroup), eager=("items.attributes"))
|
||||
g = eos.db.getGroup(int(itemChargeGroup), eager="items.attributes")
|
||||
if g is None:
|
||||
continue
|
||||
for singleItem in g.items:
|
||||
@@ -832,6 +855,36 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
else:
|
||||
return 0
|
||||
|
||||
@staticmethod
|
||||
def getProposedState(mod, click, proposedState=None):
|
||||
# todo: instead of passing in module, make this a instanced function.
|
||||
pyfalog.debug("Get proposed state for module.")
|
||||
if mod.slot == Slot.SUBSYSTEM or mod.isEmpty:
|
||||
return State.ONLINE
|
||||
|
||||
if mod.slot == Slot.SYSTEM:
|
||||
transitionMap = ProjectedSystem
|
||||
else:
|
||||
transitionMap = ProjectedMap if mod.projected else LocalMap
|
||||
|
||||
currState = mod.state
|
||||
|
||||
if proposedState is not None:
|
||||
state = proposedState
|
||||
elif click == "right":
|
||||
state = State.OVERHEATED
|
||||
elif click == "ctrl":
|
||||
state = State.OFFLINE
|
||||
else:
|
||||
state = transitionMap[currState]
|
||||
if not mod.isValidState(state):
|
||||
state = -1
|
||||
|
||||
if mod.isValidState(state):
|
||||
return state
|
||||
else:
|
||||
return currState
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
item = self.item
|
||||
if item is None:
|
||||
|
||||
@@ -131,7 +131,7 @@ class Ship(ItemAttrShortcut, HandledItem):
|
||||
return None
|
||||
|
||||
items = []
|
||||
g = eos.db.getGroup("Ship Modifiers", eager=("items.attributes"))
|
||||
g = eos.db.getGroup("Ship Modifiers", eager="items.attributes")
|
||||
for item in g.items:
|
||||
# Rely on name detection because race is not reliable
|
||||
if item.name.lower().startswith(self.item.name.lower()):
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import copy
|
||||
import wx
|
||||
import math
|
||||
|
||||
from gui.utils import color as color_utils
|
||||
from gui.utils import draw, anim_effects
|
||||
from service.fit import Fit
|
||||
import wx
|
||||
|
||||
from gui.utils import anim_effects
|
||||
|
||||
|
||||
# todo: clean class up. Took from pyfa gauge, has a bunch of extra shit we don't need
|
||||
|
||||
@@ -168,8 +167,6 @@ class AttributeGauge(wx.Window):
|
||||
|
||||
def SetValue(self, value, animate=True):
|
||||
""" Sets the current position of the gauge. """
|
||||
|
||||
print("=" * 20, self._percentage)
|
||||
if self._value == value:
|
||||
return
|
||||
|
||||
|
||||
@@ -19,15 +19,14 @@
|
||||
|
||||
import io
|
||||
import os.path
|
||||
import zipfile
|
||||
from collections import OrderedDict
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
from logbook import Logger
|
||||
|
||||
import config
|
||||
|
||||
from logbook import Logger
|
||||
logging = Logger(__name__)
|
||||
|
||||
|
||||
@@ -46,18 +45,18 @@ class BitmapLoader(object):
|
||||
dont_use_cached_bitmaps = False
|
||||
max_cached_bitmaps = 500
|
||||
|
||||
scaling_factor = None
|
||||
|
||||
@classmethod
|
||||
def getStaticBitmap(cls, name, parent, location):
|
||||
static = wx.StaticBitmap(parent)
|
||||
static.SetBitmap(cls.getBitmap(name, location))
|
||||
static.SetBitmap(cls.getBitmap(name or 0, location))
|
||||
return static
|
||||
|
||||
@classmethod
|
||||
def getBitmap(cls, name, location):
|
||||
if cls.dont_use_cached_bitmaps:
|
||||
img = cls.getImage(name, location)
|
||||
if img is not None:
|
||||
return img.ConvertToBitmap()
|
||||
return cls.loadBitmap(name, location)
|
||||
|
||||
path = "%s%s" % (name, location)
|
||||
|
||||
@@ -65,11 +64,7 @@ class BitmapLoader(object):
|
||||
cls.cached_bitmaps.popitem(False)
|
||||
|
||||
if path not in cls.cached_bitmaps:
|
||||
img = cls.getImage(name, location)
|
||||
if img is not None:
|
||||
bmp = img.ConvertToBitmap()
|
||||
else:
|
||||
bmp = None
|
||||
bmp = cls.loadBitmap(name, location)
|
||||
cls.cached_bitmaps[path] = bmp
|
||||
else:
|
||||
bmp = cls.cached_bitmaps[path]
|
||||
@@ -78,8 +73,55 @@ class BitmapLoader(object):
|
||||
|
||||
@classmethod
|
||||
def getImage(cls, name, location):
|
||||
filename = "{0}.png".format(name)
|
||||
bmp = cls.getBitmap(name, location)
|
||||
if bmp is not None:
|
||||
return bmp.ConvertToImage()
|
||||
else:
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def loadBitmap(cls, name, location):
|
||||
if cls.scaling_factor is None:
|
||||
import gui.mainFrame
|
||||
cls.scaling_factor = int(gui.mainFrame.MainFrame.getInstance().GetContentScaleFactor())
|
||||
|
||||
scale = cls.scaling_factor
|
||||
|
||||
filename, img = cls.loadScaledBitmap(name, location, scale)
|
||||
|
||||
while img is None and scale > 0:
|
||||
# can't find the correctly scaled image, fallback to smaller scales
|
||||
scale -= 1
|
||||
filename, img = cls.loadScaledBitmap(name, location, scale)
|
||||
|
||||
if img is None:
|
||||
print(("Missing icon file: {0}/{1}".format(location, filename)))
|
||||
return None
|
||||
|
||||
bmp: wx.Bitmap = img.ConvertToBitmap()
|
||||
if scale > 1:
|
||||
bmp.SetSize((bmp.GetWidth() // scale, bmp.GetHeight() // scale))
|
||||
return bmp
|
||||
|
||||
@classmethod
|
||||
def loadScaledBitmap(cls, name, location, scale=0):
|
||||
"""Attempts to load a scaled bitmap.
|
||||
|
||||
Args:
|
||||
name (str): TypeID or basename of the image being requested.
|
||||
location (str): Path to a location that may contain the image.
|
||||
scale (int): Scale factor of the image variant to load. If ``0``, attempts to load the unscaled variant.
|
||||
|
||||
Returns:
|
||||
(str, wx.Image): Tuple of the filename that may have been loaded and the image at that location. The
|
||||
filename will always be present, but the image may be ``None``.
|
||||
"""
|
||||
filename = "{0}@{1}x.png".format(name, scale) if scale > 0 else "{0}.png".format(name)
|
||||
img = cls.loadImage(filename, location)
|
||||
return filename, img
|
||||
|
||||
@classmethod
|
||||
def loadImage(cls, filename, location):
|
||||
if cls.archive:
|
||||
path = os.path.join(location, filename)
|
||||
if os.sep != "/" and os.sep in path:
|
||||
@@ -97,4 +139,4 @@ class BitmapLoader(object):
|
||||
if os.path.exists(path):
|
||||
return wx.Image(path)
|
||||
else:
|
||||
print(("Missing icon file: {0}".format(path)))
|
||||
return None
|
||||
|
||||
@@ -26,6 +26,7 @@ from gui.builtinViewColumns.state import State
|
||||
from gui.contextMenu import ContextMenu
|
||||
from gui.utils.staticHelpers import DragDropHelper
|
||||
from service.fit import Fit
|
||||
import gui.fitCommands as cmd
|
||||
|
||||
|
||||
class BoosterViewDrop(wx.DropTarget):
|
||||
@@ -134,9 +135,7 @@ class BoosterView(d.Display):
|
||||
event.Skip()
|
||||
return
|
||||
|
||||
trigger = sFit.addBooster(fitID, event.itemID)
|
||||
if trigger:
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
|
||||
if self.mainFrame.command.Submit(cmd.GuiAddBoosterCommand(fitID, event.itemID)):
|
||||
self.mainFrame.additionsPane.select("Boosters")
|
||||
|
||||
event.Skip()
|
||||
@@ -150,9 +149,7 @@ class BoosterView(d.Display):
|
||||
|
||||
def removeBooster(self, booster):
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
sFit = Fit.getInstance()
|
||||
sFit.removeBooster(fitID, self.origional.index(booster))
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
|
||||
self.mainFrame.command.Submit(cmd.GuiRemoveBoosterCommand(fitID, self.origional.index(booster)))
|
||||
|
||||
def click(self, event):
|
||||
event.Skip()
|
||||
@@ -161,9 +158,7 @@ class BoosterView(d.Display):
|
||||
col = self.getColumn(event.Position)
|
||||
if col == self.getColIndex(State):
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
sFit = Fit.getInstance()
|
||||
sFit.toggleBooster(fitID, row)
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
|
||||
self.mainFrame.command.Submit(cmd.GuiToggleBoosterCommand(fitID, row))
|
||||
|
||||
def scheduleMenu(self, event):
|
||||
event.Skip()
|
||||
|
||||
@@ -26,6 +26,7 @@ import gui.globalEvents as GE
|
||||
from gui.utils.staticHelpers import DragDropHelper
|
||||
from service.fit import Fit
|
||||
from service.market import Market
|
||||
import gui.fitCommands as cmd
|
||||
|
||||
|
||||
class CargoViewDrop(wx.DropTarget):
|
||||
@@ -80,9 +81,7 @@ class CargoView(d.Display):
|
||||
if data[0] == "fitting":
|
||||
self.swapModule(x, y, int(data[1]))
|
||||
elif data[0] == "market":
|
||||
sFit = Fit.getInstance()
|
||||
sFit.addCargo(self.mainFrame.getActiveFit(), int(data[1]), 1)
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit()))
|
||||
self.mainFrame.command.Submit(cmd.GuiAddCargoCommand(self.mainFrame.getActiveFit(), int(data[1])))
|
||||
|
||||
def startDrag(self, event):
|
||||
row = event.GetIndex()
|
||||
@@ -127,18 +126,14 @@ class CargoView(d.Display):
|
||||
if not result:
|
||||
return
|
||||
|
||||
if dstRow != -1: # we're swapping with cargo
|
||||
if mstate.cmdDown: # if copying, append to cargo
|
||||
sFit.addCargo(self.mainFrame.getActiveFit(), module.item.ID if not module.item.isAbyssal else module.baseItemID)
|
||||
else: # else, move / swap
|
||||
sFit.moveCargoToModule(self.mainFrame.getActiveFit(), module.position, dstRow)
|
||||
else: # dragging to blank spot, append
|
||||
sFit.addCargo(self.mainFrame.getActiveFit(), module.item.ID if not module.item.isAbyssal else module.baseItemID)
|
||||
cargoPos = dstRow if dstRow > -1 else None
|
||||
|
||||
if not mstate.cmdDown: # if not copying, remove module
|
||||
sFit.removeModule(self.mainFrame.getActiveFit(), module.position)
|
||||
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit(), action="moddel", typeID=module.item.ID))
|
||||
self.mainFrame.command.Submit(cmd.GuiModuleToCargoCommand(
|
||||
self.mainFrame.getActiveFit(),
|
||||
module.modPosition,
|
||||
cargoPos,
|
||||
mstate.cmdDown
|
||||
))
|
||||
|
||||
def fitChanged(self, event):
|
||||
sFit = Fit.getInstance()
|
||||
|
||||
@@ -30,6 +30,7 @@ from gui.builtinViewColumns.state import State
|
||||
from gui.contextMenu import ContextMenu
|
||||
from gui.utils.staticHelpers import DragDropHelper
|
||||
from service.fit import Fit
|
||||
import gui.fitCommands as cmd
|
||||
|
||||
|
||||
class DummyItem(object):
|
||||
@@ -100,21 +101,16 @@ class CommandView(d.Display):
|
||||
keycode = event.GetKeyCode()
|
||||
if keycode == wx.WXK_DELETE or keycode == wx.WXK_NUMPAD_DELETE:
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
sFit = Fit.getInstance()
|
||||
row = self.GetFirstSelected()
|
||||
if row != -1:
|
||||
sFit.removeCommand(fitID, self.get(row))
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
|
||||
self.mainFrame.command.Submit(cmd.GuiRemoveCommandCommand(fitID, self.get(row).ID))
|
||||
|
||||
def handleDrag(self, type, fitID):
|
||||
# Those are drags coming from pyfa sources, NOT builtin wx drags
|
||||
if type == "fit":
|
||||
activeFit = self.mainFrame.getActiveFit()
|
||||
if activeFit:
|
||||
sFit = Fit.getInstance()
|
||||
draggedFit = sFit.getFit(fitID)
|
||||
sFit.addCommandFit(activeFit, draggedFit)
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=activeFit))
|
||||
self.mainFrame.command.Submit(cmd.GuiAddCommandCommand(activeFit, fitID))
|
||||
|
||||
def startDrag(self, event):
|
||||
row = event.GetIndex()
|
||||
@@ -190,9 +186,7 @@ class CommandView(d.Display):
|
||||
col = self.getColumn(event.Position)
|
||||
if col == self.getColIndex(State):
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
sFit = Fit.getInstance()
|
||||
sFit.toggleCommandFit(fitID, item)
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
|
||||
self.mainFrame.command.Submit(cmd.GuiToggleCommandCommand(fitID, item.ID))
|
||||
|
||||
def scheduleMenu(self, event):
|
||||
event.Skip()
|
||||
@@ -224,8 +218,6 @@ class CommandView(d.Display):
|
||||
col = self.getColumn(event.Position)
|
||||
if col != self.getColIndex(State):
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
sFit = Fit.getInstance()
|
||||
thing = self.get(row)
|
||||
if thing: # thing doesn't exist if it's the dummy value
|
||||
sFit.removeCommand(fitID, thing)
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
|
||||
self.mainFrame.command.Submit(cmd.GuiRemoveCommandCommand(fitID, thing.ID))
|
||||
|
||||
@@ -29,6 +29,7 @@ from gui.contextMenu import ContextMenu
|
||||
from gui.utils.staticHelpers import DragDropHelper
|
||||
from service.fit import Fit
|
||||
from service.market import Market
|
||||
import gui.fitCommands as cmd
|
||||
|
||||
|
||||
class DroneViewDrop(wx.DropTarget):
|
||||
@@ -144,10 +145,12 @@ class DroneView(Display):
|
||||
data[1] is typeID or index of data we want to manipulate
|
||||
"""
|
||||
if data[0] == "drone": # we want to merge drones
|
||||
srcRow = int(data[1])
|
||||
dstRow, _ = self.HitTest((x, y))
|
||||
if srcRow != -1 and dstRow != -1:
|
||||
self._merge(srcRow, dstRow)
|
||||
pass
|
||||
# remove merge functionality, if people complain in the next while, can add it back
|
||||
# srcRow = int(data[1])
|
||||
# dstRow, _ = self.HitTest((x, y))
|
||||
# if srcRow != -1 and dstRow != -1:
|
||||
# self._merge(srcRow, dstRow)
|
||||
elif data[0] == "market":
|
||||
wx.PostEvent(self.mainFrame, ItemSelected(itemID=int(data[1])))
|
||||
|
||||
@@ -213,9 +216,7 @@ class DroneView(Display):
|
||||
event.Skip()
|
||||
return
|
||||
|
||||
trigger = sFit.addDrone(fitID, event.itemID)
|
||||
if trigger:
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
|
||||
if self.mainFrame.command.Submit(cmd.GuiAddDroneCommand(fitID, event.itemID)):
|
||||
self.mainFrame.additionsPane.select("Drones")
|
||||
|
||||
event.Skip()
|
||||
@@ -230,9 +231,7 @@ class DroneView(Display):
|
||||
|
||||
def removeDrone(self, drone):
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
sFit = Fit.getInstance()
|
||||
sFit.removeDrone(fitID, self.original.index(drone))
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
|
||||
self.mainFrame.command.Submit(cmd.GuiRemoveDroneCommand(fitID, self.original.index(drone)))
|
||||
|
||||
def click(self, event):
|
||||
event.Skip()
|
||||
@@ -241,10 +240,8 @@ class DroneView(Display):
|
||||
col = self.getColumn(event.Position)
|
||||
if col == self.getColIndex(State):
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
sFit = Fit.getInstance()
|
||||
drone = self.drones[row]
|
||||
sFit.toggleDrone(fitID, self.original.index(drone))
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
|
||||
self.mainFrame.command.Submit(cmd.GuiToggleDroneCommand(fitID, self.original.index(drone)))
|
||||
|
||||
def scheduleMenu(self, event):
|
||||
event.Skip()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user