Merge branch 'sso_v2' of https://github.com/pyfa-org/Pyfa into sso_v2
@@ -27,6 +27,8 @@ import re
|
||||
import sqlite3
|
||||
import sys
|
||||
|
||||
from sqlalchemy import or_
|
||||
|
||||
|
||||
# todo: need to set the EOS language to en, becasuse this assumes it's being run within an English context
|
||||
# Need to know what that would do if called from pyfa
|
||||
@@ -591,7 +593,10 @@ def update_db():
|
||||
# pyfa, we can do it here as a post-processing step
|
||||
for attr in eos.db.gamedata_session.query(eos.gamedata.Attribute).filter(eos.gamedata.Attribute.ID == 1367).all():
|
||||
attr.value = 4.0
|
||||
for item in eos.db.gamedata_session.query(eos.gamedata.Item).filter(eos.gamedata.Item.name.like('%abyssal%')).all():
|
||||
for item in eos.db.gamedata_session.query(eos.gamedata.Item).filter(or_(
|
||||
eos.gamedata.Item.name.like('%abyssal%'),
|
||||
eos.gamedata.Item.name.like('%mutated%')
|
||||
)).all():
|
||||
item.published = False
|
||||
|
||||
for x in [
|
||||
|
||||
@@ -118,7 +118,7 @@ from eos.db.gamedata import alphaClones, attribute, category, effect, group, ite
|
||||
pyfalog.debug('Importing saveddata DB scheme')
|
||||
# noinspection PyPep8
|
||||
from eos.db.saveddata import booster, cargo, character, damagePattern, databaseRepair, drone, fighter, fit, implant, implantSet, \
|
||||
miscData, mutator, module, override, price, queries, skill, targetProfile, user
|
||||
miscData, mutatorMod, mutatorDrone, module, override, price, queries, skill, targetProfile, user
|
||||
|
||||
pyfalog.debug('Importing gamedata queries')
|
||||
# noinspection PyPep8
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Boolean, Column, Float, ForeignKey, Integer, String, Table
|
||||
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, Table
|
||||
from sqlalchemy.ext.associationproxy import association_proxy
|
||||
from sqlalchemy.orm import backref, deferred, mapper, relation, synonym
|
||||
from sqlalchemy.orm.collections import attribute_mapped_collection
|
||||
|
||||
18
eos/db/migrations/upgrade45.py
Normal file
@@ -0,0 +1,18 @@
|
||||
"""
|
||||
Migration 45
|
||||
|
||||
- Drone mutaplasmid support
|
||||
"""
|
||||
|
||||
import sqlalchemy
|
||||
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
try:
|
||||
saveddata_engine.execute("SELECT baseItemID FROM drones LIMIT 1")
|
||||
except sqlalchemy.exc.DatabaseError:
|
||||
saveddata_engine.execute("ALTER TABLE drones ADD COLUMN baseItemID INTEGER;")
|
||||
try:
|
||||
saveddata_engine.execute("SELECT mutaplasmidID FROM drones LIMIT 1")
|
||||
except sqlalchemy.exc.DatabaseError:
|
||||
saveddata_engine.execute("ALTER TABLE drones ADD COLUMN mutaplasmidID INTEGER;")
|
||||
@@ -1,7 +1,8 @@
|
||||
__all__ = [
|
||||
"character",
|
||||
"fit",
|
||||
"mutator",
|
||||
"mutatorMod",
|
||||
"mutatorDrone",
|
||||
"module",
|
||||
"user",
|
||||
"skill",
|
||||
|
||||
@@ -18,27 +18,35 @@
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, Float, ForeignKey, Boolean, DateTime
|
||||
from sqlalchemy.orm import mapper, relation
|
||||
from sqlalchemy.orm import mapper, relation, synonym
|
||||
from sqlalchemy.orm.collections import attribute_mapped_collection
|
||||
import datetime
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.saveddata.drone import Drone
|
||||
from eos.saveddata.fit import Fit
|
||||
from eos.saveddata.mutator import MutatorDrone
|
||||
|
||||
drones_table = Table("drones", saveddata_meta,
|
||||
Column("groupID", Integer, primary_key=True),
|
||||
Column("fitID", Integer, ForeignKey("fits.ID"), nullable=False, index=True),
|
||||
Column("itemID", Integer, nullable=False),
|
||||
Column("baseItemID", Integer, nullable=True),
|
||||
Column("mutaplasmidID", Integer, nullable=True),
|
||||
Column("amount", Integer, nullable=False),
|
||||
Column("amountActive", Integer, nullable=False),
|
||||
Column("projected", Boolean, default=False),
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now),
|
||||
Column("projectionRange", Float, nullable=True)
|
||||
)
|
||||
Column("projectionRange", Float, nullable=True))
|
||||
|
||||
|
||||
mapper(Drone, drones_table,
|
||||
properties={
|
||||
"owner": relation(Fit)
|
||||
}
|
||||
)
|
||||
"ID": synonym("groupID"),
|
||||
"owner": relation(Fit),
|
||||
"mutators": relation(
|
||||
MutatorDrone,
|
||||
backref="item",
|
||||
cascade="all,delete-orphan",
|
||||
collection_class=attribute_mapped_collection('attrID'))})
|
||||
|
||||
@@ -18,14 +18,14 @@
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, Float, ForeignKey, CheckConstraint, Boolean, DateTime
|
||||
from sqlalchemy.orm.collections import attribute_mapped_collection
|
||||
from sqlalchemy.orm import relation, mapper
|
||||
from sqlalchemy.orm.collections import attribute_mapped_collection
|
||||
import datetime
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.saveddata.module import Module
|
||||
from eos.saveddata.mutator import Mutator
|
||||
from eos.saveddata.fit import Fit
|
||||
from eos.saveddata.mutator import MutatorModule
|
||||
|
||||
modules_table = Table("modules", saveddata_meta,
|
||||
Column("ID", Integer, primary_key=True),
|
||||
@@ -45,13 +45,12 @@ modules_table = Table("modules", saveddata_meta,
|
||||
Column("projectionRange", Float, nullable=True),
|
||||
CheckConstraint('("dummySlot" = NULL OR "itemID" = NULL) AND "dummySlot" != "itemID"'))
|
||||
|
||||
|
||||
mapper(Module, modules_table,
|
||||
properties={
|
||||
"owner": relation(Fit),
|
||||
"mutators": relation(
|
||||
Mutator,
|
||||
backref="module",
|
||||
MutatorModule,
|
||||
backref="item",
|
||||
cascade="all,delete-orphan",
|
||||
collection_class=attribute_mapped_collection('attrID')
|
||||
)
|
||||
})
|
||||
collection_class=attribute_mapped_collection('attrID'))})
|
||||
|
||||
@@ -23,13 +23,14 @@ 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
|
||||
from eos.saveddata.mutator import MutatorDrone
|
||||
|
||||
mutator_table = Table("mutators", saveddata_meta,
|
||||
Column("moduleID", Integer, ForeignKey("modules.ID"), primary_key=True, index=True),
|
||||
Column("attrID", Integer, primary_key=True, index=True),
|
||||
Column("value", Float, nullable=False),
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now))
|
||||
mutatorDrones_table = Table(
|
||||
"mutatorsDrones", saveddata_meta,
|
||||
Column("groupID", Integer, ForeignKey("drones.groupID"), primary_key=True, index=True),
|
||||
Column("attrID", Integer, primary_key=True, index=True),
|
||||
Column("value", Float, nullable=False),
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now))
|
||||
|
||||
mapper(Mutator, mutator_table)
|
||||
mapper(MutatorDrone, mutatorDrones_table)
|
||||
36
eos/db/saveddata/mutatorMod.py
Normal file
@@ -0,0 +1,36 @@
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
#
|
||||
# eos is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# eos is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
import datetime
|
||||
|
||||
from sqlalchemy import Column, DateTime, Float, ForeignKey, Integer, Table
|
||||
from sqlalchemy.orm import mapper
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.saveddata.mutator import MutatorModule
|
||||
|
||||
mutatorMods_table = Table(
|
||||
"mutators", saveddata_meta,
|
||||
Column("moduleID", Integer, ForeignKey("modules.ID"), primary_key=True, index=True),
|
||||
Column("attrID", Integer, primary_key=True, index=True),
|
||||
Column("value", Float, nullable=False),
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now))
|
||||
|
||||
mapper(MutatorModule, mutatorMods_table)
|
||||
244
eos/effects.py
@@ -61,8 +61,9 @@ class Effect10(BaseEffect):
|
||||
|
||||
Used by:
|
||||
Celestials from group: Destructible Effect Beacon (6 of 6)
|
||||
Drones from group: Combat Drone (75 of 75)
|
||||
Drones from group: Combat Drone (79 of 79)
|
||||
Modules from group: Energy Weapon (212 of 214)
|
||||
Celestial: EDENCOM Stockpile Non-Interactable (Do not translate)
|
||||
"""
|
||||
|
||||
dealsDamage = True
|
||||
@@ -614,8 +615,7 @@ class Effect101(BaseEffect):
|
||||
# Lockbreaker Bombs
|
||||
ecmStrengthBonus = src.getModifiedChargeAttr('scan{0}StrengthBonus'.format(fit.scanType))
|
||||
if ecmStrengthBonus:
|
||||
strModifier = 1 - min(1, ecmStrengthBonus / fit.scanStrength)
|
||||
fit.ecmProjectedStr *= strModifier
|
||||
fit.addProjectedEcm(ecmStrengthBonus)
|
||||
elif src.item.group.name == 'Interdiction Sphere Launcher':
|
||||
speedFactor = src.getModifiedChargeAttr('speedFactor')
|
||||
if speedFactor:
|
||||
@@ -871,7 +871,7 @@ class Effect230(BaseEffect):
|
||||
Used by:
|
||||
Implants named like: Eifyr and Co. 'Rogue' Afterburner AB (6 of 6)
|
||||
Implants named like: Eifyr and Co. 'Rogue' Agility (2 of 2)
|
||||
Implant: Serenity Anniversary Limited 'Overclocker' Dose
|
||||
Implants named like: Serenity Limited 'Overclocker' Dose (3 of 3)
|
||||
Implant: Zor's Custom Navigation Link
|
||||
Skill: Afterburner
|
||||
"""
|
||||
@@ -907,7 +907,7 @@ class Effect242(BaseEffect):
|
||||
Used by:
|
||||
Implants named like: Eifyr and Co. 'Rogue' Acceleration Control AC (6 of 6)
|
||||
Implants named like: Eifyr and Co. 'Rogue' Agility (2 of 2)
|
||||
Implant: Serenity Anniversary Limited 'Overclocker' Dose
|
||||
Implants named like: Serenity Limited 'Overclocker' Dose (3 of 3)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -1109,9 +1109,9 @@ class Effect391(BaseEffect):
|
||||
Implants named like: Inherent Implants 'Highwall' Mining MX (3 of 3)
|
||||
Implants named like: Mining Blitz Yield Booster Dose (3 of 3)
|
||||
Implants named like: ORE 'Harvester' Efficiency (2 of 2)
|
||||
Implants named like: Serenity Limited 'Efficiency' Dose (3 of 3)
|
||||
Implants named like: Serenity Poteque 'Prospector' Harvesting MC (3 of 3)
|
||||
Implant: Michi's Excavation Augmentor
|
||||
Implant: Serenity Anniversary Limited 'Efficiency' Dose
|
||||
Skill: Astrogeology
|
||||
Skill: Mining
|
||||
"""
|
||||
@@ -1133,8 +1133,8 @@ class Effect392(BaseEffect):
|
||||
Implants named like: Capsuleer Defense Augmentation Chip (3 of 3)
|
||||
Implants named like: Festival only 'Rock' HH Dose (4 of 4)
|
||||
Implants named like: Inherent Implants 'Noble' Mechanic MC (6 of 6)
|
||||
Implants named like: Serenity Limited 'Hardshell' Dose (3 of 3)
|
||||
Modules named like: Transverse Bulkhead (8 of 8)
|
||||
Implant: Serenity Anniversary Limited 'Hardshell' Dose
|
||||
Skill: Mechanics
|
||||
"""
|
||||
|
||||
@@ -1156,7 +1156,7 @@ class Effect394(BaseEffect):
|
||||
Implants named like: grade Snake (16 of 18)
|
||||
Modules named like: Auxiliary Thrusters (8 of 8)
|
||||
Implant: Grand Prix Velocity Booster
|
||||
Implant: Quafe Zero
|
||||
Implant: Quafe Zero Classic
|
||||
Implant: Serenity YC122.9 Season Booster - Max Velocity
|
||||
Skill: Navigation
|
||||
"""
|
||||
@@ -1182,6 +1182,7 @@ class Effect395(BaseEffect):
|
||||
Implants named like: grade Nomad (10 of 12)
|
||||
Modules named like: Low Friction Nozzle Joints (8 of 8)
|
||||
Implant: Genolution Core Augmentation CA-4
|
||||
Implant: Quafe Zero Green Apple
|
||||
Implant: Serenity YC122.9 Season Booster - Agility
|
||||
Skill: Evasive Maneuvering
|
||||
Skill: Spaceship Command
|
||||
@@ -1192,7 +1193,7 @@ class Effect395(BaseEffect):
|
||||
@staticmethod
|
||||
def handler(fit, container, context, projectionRange, **kwargs):
|
||||
level = container.level if 'skill' in context else 1
|
||||
penalties = 'skill' not in context and 'implant' not in context
|
||||
penalties = 'skill' not in context and 'implant' not in context and 'booster' not in context
|
||||
fit.ship.boostItemAttr('agility', container.getModifiedItemAttr('agilityBonus') * level,
|
||||
stackingPenalties=penalties, **kwargs)
|
||||
|
||||
@@ -1283,11 +1284,11 @@ class Effect446(BaseEffect):
|
||||
Used by:
|
||||
Implants named like: Capsuleer Defense Augmentation Chip (3 of 3)
|
||||
Implants named like: Festival only 'Rock' SH Dose (4 of 4)
|
||||
Implants named like: Serenity Limited 'Hardshell' Dose (3 of 3)
|
||||
Implants named like: Zainou 'Gnome' Shield Management SM (6 of 6)
|
||||
Modules named like: Core Defense Field Extender (8 of 8)
|
||||
Implant: Genolution Core Augmentation CA-3
|
||||
Implant: Sansha Modified 'Gnome' Implant
|
||||
Implant: Serenity Anniversary Limited 'Hardshell' Dose
|
||||
Skill: Shield Management
|
||||
"""
|
||||
|
||||
@@ -1309,6 +1310,7 @@ class Effect485(BaseEffect):
|
||||
Modules named like: Capacitor Control Circuit (8 of 8)
|
||||
Implant: Basic Capsuleer Engineering Augmentation Chip
|
||||
Implant: Genolution Core Augmentation CA-2
|
||||
Implant: Quafe Zero Green Apple
|
||||
Skill: Capacitor Systems Operation
|
||||
"""
|
||||
|
||||
@@ -1738,9 +1740,8 @@ class Effect584(BaseEffect):
|
||||
surgicalStrikeDamageMultiplierBonusPostPercentDamageMultiplierLocationShipModulesRequiringGunnery
|
||||
|
||||
Used by:
|
||||
Implants named like: Agency 'Pyrolancea' DB Dose (4 of 4)
|
||||
Implants named like: 'Pyrolancea' Dose (7 of 7)
|
||||
Implants named like: Eifyr and Co. 'Gunslinger' Surgical Strike SS (6 of 6)
|
||||
Implant: Serenity Anniversary Limited 'Pyrolancea' Dose
|
||||
Implant: Standard Cerebral Accelerator
|
||||
"""
|
||||
|
||||
@@ -2120,7 +2121,7 @@ class Effect699(BaseEffect):
|
||||
Used by:
|
||||
Implants named like: Zainou 'Gypsy' Signature Analysis SA (6 of 6)
|
||||
Modules named like: Targeting System Subcontroller (8 of 8)
|
||||
Implant: Quafe Zero
|
||||
Implant: Quafe Zero Classic
|
||||
Skill: Signature Analysis
|
||||
"""
|
||||
|
||||
@@ -2463,10 +2464,10 @@ class Effect856(BaseEffect):
|
||||
Used by:
|
||||
Implants named like: Eifyr and Co. 'Rogue' Agility (2 of 2)
|
||||
Implants named like: Eifyr and Co. 'Rogue' Warp Drive Speed WS (6 of 6)
|
||||
Implants named like: Serenity Limited 'Overclocker' Dose (3 of 3)
|
||||
Implants named like: grade Ascendancy (10 of 12)
|
||||
Modules named like: Hyperspatial Velocity Optimizer (8 of 8)
|
||||
Implant: Grand Prix Warp Booster
|
||||
Implant: Serenity Anniversary Limited 'Overclocker' Dose
|
||||
Implant: Serenity YC122.9 Season Booster - Warp Speed
|
||||
"""
|
||||
|
||||
@@ -3749,8 +3750,8 @@ class Effect1190(BaseEffect):
|
||||
Used by:
|
||||
Implants named like: Inherent Implants 'Yeti' Ice Harvesting IH (3 of 3)
|
||||
Implants named like: ORE 'Harvester' Efficiency (2 of 2)
|
||||
Implants named like: Serenity Limited 'Efficiency' Dose (3 of 3)
|
||||
Implants named like: Serenity Poteque 'Prospector' Harvesting MC (3 of 3)
|
||||
Implant: Serenity Anniversary Limited 'Efficiency' Dose
|
||||
Module: Medium Ice Harvester Accelerator I
|
||||
Skill: Ice Harvesting
|
||||
"""
|
||||
@@ -4259,9 +4260,9 @@ class Effect1409(BaseEffect):
|
||||
systemScanDurationSkillAstrometrics
|
||||
|
||||
Used by:
|
||||
Implants named like: Poteque 'Prospector' Astrometric Acquisition AQ (3 of 3)
|
||||
Implants named like: Acquisition (6 of 6)
|
||||
Implants named like: Poteque 'Prospector' Sharpeye (2 of 2)
|
||||
Implant: Serenity Anniversary Limited 'Sharpeye' Dose
|
||||
Implants named like: Serenity Limited 'Sharpeye' Dose (3 of 3)
|
||||
Skill: Astrometric Acquisition
|
||||
Skill: Astrometrics
|
||||
"""
|
||||
@@ -4404,7 +4405,6 @@ class Effect1446(BaseEffect):
|
||||
ewSkillTpMaxRangeBonus
|
||||
|
||||
Used by:
|
||||
Implants named like: Liberation Games EWar Booster (3 of 3)
|
||||
Modules named like: Particle Dispersion Projector (8 of 8)
|
||||
Skill: Long Distance Jamming
|
||||
"""
|
||||
@@ -4568,7 +4568,6 @@ class Effect1550(BaseEffect):
|
||||
ewSkillTargetPaintingStrengthBonus
|
||||
|
||||
Used by:
|
||||
Implants named like: Liberation Games EWar Booster (3 of 3)
|
||||
Skill: Signature Focusing
|
||||
"""
|
||||
|
||||
@@ -4722,7 +4721,6 @@ class Effect1590(BaseEffect):
|
||||
missileSkillAoeVelocityBonus
|
||||
|
||||
Used by:
|
||||
Implants named like: Liberation Games Accuracy Booster (3 of 3)
|
||||
Implants named like: Zainou 'Deadeye' Target Navigation Prediction TN (6 of 6)
|
||||
Modules named like: Warhead Flare Catalyst (8 of 8)
|
||||
Skill: Target Navigation Prediction
|
||||
@@ -4798,8 +4796,7 @@ class Effect1595(BaseEffect):
|
||||
missileSkillWarheadUpgradesEmDamageBonus
|
||||
|
||||
Used by:
|
||||
Implants named like: Agency 'Pyrolancea' DB Dose (4 of 4)
|
||||
Implant: Serenity Anniversary Limited 'Pyrolancea' Dose
|
||||
Implants named like: 'Pyrolancea' Dose (7 of 7)
|
||||
Skill: Warhead Upgrades
|
||||
"""
|
||||
|
||||
@@ -4817,8 +4814,7 @@ class Effect1596(BaseEffect):
|
||||
missileSkillWarheadUpgradesExplosiveDamageBonus
|
||||
|
||||
Used by:
|
||||
Implants named like: Agency 'Pyrolancea' DB Dose (4 of 4)
|
||||
Implant: Serenity Anniversary Limited 'Pyrolancea' Dose
|
||||
Implants named like: 'Pyrolancea' Dose (7 of 7)
|
||||
Skill: Warhead Upgrades
|
||||
"""
|
||||
|
||||
@@ -4836,8 +4832,7 @@ class Effect1597(BaseEffect):
|
||||
missileSkillWarheadUpgradesKineticDamageBonus
|
||||
|
||||
Used by:
|
||||
Implants named like: Agency 'Pyrolancea' DB Dose (4 of 4)
|
||||
Implant: Serenity Anniversary Limited 'Pyrolancea' Dose
|
||||
Implants named like: 'Pyrolancea' Dose (7 of 7)
|
||||
Skill: Warhead Upgrades
|
||||
"""
|
||||
|
||||
@@ -4855,7 +4850,7 @@ class Effect1615(BaseEffect):
|
||||
shipAdvancedSpaceshipCommandAgilityBonus
|
||||
|
||||
Used by:
|
||||
Items from market group: Ships > Capital Ships (40 of 41)
|
||||
Items from market group: Ships > Capital Ships (41 of 41)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -4888,7 +4883,12 @@ class Effect1617(BaseEffect):
|
||||
shipCapitalAgilityBonus
|
||||
|
||||
Used by:
|
||||
Items from market group: Ships > Capital Ships (31 of 41)
|
||||
Ships from group: Carrier (4 of 4)
|
||||
Ships from group: Dreadnought (8 of 8)
|
||||
Ships from group: Force Auxiliary (6 of 6)
|
||||
Ships from group: Supercarrier (6 of 6)
|
||||
Ships from group: Titan (7 of 7)
|
||||
Ship: Rorqual
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -5079,8 +5079,7 @@ class Effect1657(BaseEffect):
|
||||
missileSkillWarheadUpgradesThermalDamageBonus
|
||||
|
||||
Used by:
|
||||
Implants named like: Agency 'Pyrolancea' DB Dose (4 of 4)
|
||||
Implant: Serenity Anniversary Limited 'Pyrolancea' Dose
|
||||
Implants named like: 'Pyrolancea' Dose (7 of 7)
|
||||
Skill: Warhead Upgrades
|
||||
"""
|
||||
|
||||
@@ -5253,7 +5252,7 @@ class Effect1730(BaseEffect):
|
||||
droneDmgBonus
|
||||
|
||||
Used by:
|
||||
Skills from group: Drones (8 of 27)
|
||||
Skills from group: Drones (9 of 28)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -5301,7 +5300,6 @@ class Effect1764(BaseEffect):
|
||||
missileSkillMissileProjectileVelocityBonus
|
||||
|
||||
Used by:
|
||||
Implants named like: Liberation Games Range Booster (3 of 3)
|
||||
Implants named like: Zainou 'Deadeye' Missile Projection MP (6 of 6)
|
||||
Modules named like: Hydraulic Bay Thrusters (8 of 8)
|
||||
Skill: Missile Projection
|
||||
@@ -6832,6 +6830,30 @@ class Effect2255(BaseEffect):
|
||||
type = 'active'
|
||||
|
||||
|
||||
class Effect2296(BaseEffect):
|
||||
"""
|
||||
modifyArmorResonancePassivePostPercentPassive
|
||||
|
||||
Used by:
|
||||
Implants named like: Tetrimon Resistance Booster (3 of 3)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, src, context, projectionRange, **kwargs):
|
||||
for srcResType, tgtResType in (
|
||||
('Em', 'Em'),
|
||||
('Explosive', 'Explosive'),
|
||||
('Kinetic', 'Kinetic'),
|
||||
('Thermic', 'Thermal')
|
||||
):
|
||||
fit.ship.boostItemAttr(
|
||||
'armor{}DamageResonance'.format(tgtResType),
|
||||
src.getModifiedItemAttr('passive{}DamageResistanceBonus'.format(srcResType)),
|
||||
**kwargs)
|
||||
|
||||
|
||||
class Effect2298(BaseEffect):
|
||||
"""
|
||||
scanStrengthBonusPercentPassive
|
||||
@@ -6988,6 +7010,7 @@ class Effect2432(BaseEffect):
|
||||
Used by:
|
||||
Implants named like: Inherent Implants 'Squire' Capacitor Management EM (6 of 6)
|
||||
Implants named like: Mindflood Booster (4 of 4)
|
||||
Implants named like: Tetrimon Capacitor Booster (3 of 3)
|
||||
Modules named like: Semiconductor Memory Cell (8 of 8)
|
||||
Implant: Antipharmakon Aeolis
|
||||
Implant: Basic Capsuleer Engineering Augmentation Chip
|
||||
@@ -7098,10 +7121,10 @@ class Effect2485(BaseEffect):
|
||||
Implants named like: Capsuleer Defense Augmentation Chip (3 of 3)
|
||||
Implants named like: Festival only 'Rock' AH Dose (4 of 4)
|
||||
Implants named like: Inherent Implants 'Noble' Hull Upgrades HG (7 of 7)
|
||||
Implants named like: Serenity Limited 'Hardshell' Dose (3 of 3)
|
||||
Implant: Genolution Core Augmentation CA-4
|
||||
Implant: Imperial Navy Modified 'Noble' Implant
|
||||
Implant: Imperial Special Ops Field Enhancer - Standard
|
||||
Implant: Serenity Anniversary Limited 'Hardshell' Dose
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -7589,7 +7612,6 @@ class Effect2695(BaseEffect):
|
||||
falloffBonusEffectProjectiles
|
||||
|
||||
Used by:
|
||||
Implants named like: Liberation Games Range Booster (3 of 3)
|
||||
Modules named like: Projectile Ambit Extension (8 of 8)
|
||||
"""
|
||||
|
||||
@@ -7608,6 +7630,7 @@ class Effect2696(BaseEffect):
|
||||
maxRangeBonusEffectLasers
|
||||
|
||||
Used by:
|
||||
Implants named like: Tetrimon Precision Booster (3 of 3)
|
||||
Modules named like: Energy Locus Coordinator (8 of 8)
|
||||
"""
|
||||
|
||||
@@ -7615,9 +7638,10 @@ class Effect2696(BaseEffect):
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, module, context, projectionRange, **kwargs):
|
||||
penalties = 'booster' not in context
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == 'Energy Weapon',
|
||||
'maxRange', module.getModifiedItemAttr('maxRangeBonus'),
|
||||
stackingPenalties=True, **kwargs)
|
||||
stackingPenalties=penalties, **kwargs)
|
||||
|
||||
|
||||
class Effect2697(BaseEffect):
|
||||
@@ -7642,7 +7666,6 @@ class Effect2698(BaseEffect):
|
||||
maxRangeBonusEffectProjectiles
|
||||
|
||||
Used by:
|
||||
Implants named like: Liberation Games Range Booster (3 of 3)
|
||||
Modules named like: Projectile Locus Coordinator (8 of 8)
|
||||
"""
|
||||
|
||||
@@ -8287,7 +8310,6 @@ class Effect2798(BaseEffect):
|
||||
projectileWeaponDamageMultiplyPassive
|
||||
|
||||
Used by:
|
||||
Implants named like: Liberation Games Damage Booster (3 of 3)
|
||||
Modules named like: Projectile Collision Accelerator (8 of 8)
|
||||
"""
|
||||
|
||||
@@ -8357,6 +8379,7 @@ class Effect2803(BaseEffect):
|
||||
energyWeaponDamageMultiplyPassive
|
||||
|
||||
Used by:
|
||||
Implants named like: Harvest Damage Booster (3 of 3)
|
||||
Modules named like: Energy Collision Accelerator (8 of 8)
|
||||
"""
|
||||
|
||||
@@ -8364,9 +8387,10 @@ class Effect2803(BaseEffect):
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, module, context, projectionRange, **kwargs):
|
||||
penalties = 'booster' not in context
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.group.name == 'Energy Weapon',
|
||||
'damageMultiplier', module.getModifiedItemAttr('damageMultiplier'),
|
||||
stackingPenalties=True, **kwargs)
|
||||
stackingPenalties=penalties, **kwargs)
|
||||
|
||||
|
||||
class Effect2804(BaseEffect):
|
||||
@@ -8554,7 +8578,6 @@ class Effect2851(BaseEffect):
|
||||
missileDMGBonusPassive
|
||||
|
||||
Used by:
|
||||
Implants named like: Liberation Games Damage Booster (3 of 3)
|
||||
Modules named like: Warhead Calefaction Catalyst (8 of 8)
|
||||
"""
|
||||
|
||||
@@ -8783,8 +8806,8 @@ class Effect2885(BaseEffect):
|
||||
Used by:
|
||||
Implants named like: Eifyr and Co. 'Alchemist' Gas Harvesting GH (3 of 3)
|
||||
Implants named like: ORE 'Harvester' Efficiency (2 of 2)
|
||||
Implants named like: Serenity Limited 'Efficiency' Dose (3 of 3)
|
||||
Implants named like: Serenity Poteque 'Prospector' Harvesting MC (3 of 3)
|
||||
Implant: Serenity Anniversary Limited 'Efficiency' Dose
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -9638,11 +9661,10 @@ class Effect3182(BaseEffect):
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, module, context, projectionRange, **kwargs):
|
||||
if 'projected' not in context:
|
||||
for scanType in ('Gravimetric', 'Magnetometric', 'Radar', 'Ladar'):
|
||||
module.boostItemAttr('scan{0}StrengthBonus'.format(scanType),
|
||||
module.getModifiedItemAttr('overloadECMStrengthBonus'),
|
||||
stackingPenalties=True, **kwargs)
|
||||
for scanType in ('Gravimetric', 'Magnetometric', 'Radar', 'Ladar'):
|
||||
module.boostItemAttr('scan{0}StrengthBonus'.format(scanType),
|
||||
module.getModifiedItemAttr('overloadECMStrengthBonus'),
|
||||
stackingPenalties=True, **kwargs)
|
||||
|
||||
|
||||
class Effect3196(BaseEffect):
|
||||
@@ -13529,9 +13551,9 @@ class Effect4161(BaseEffect):
|
||||
baseMaxScanDeviationModifierRequiringAstrometrics
|
||||
|
||||
Used by:
|
||||
Implants named like: Poteque 'Prospector' Astrometric Pinpointing AP (3 of 3)
|
||||
Implants named like: Pinpointing (6 of 6)
|
||||
Implants named like: Poteque 'Prospector' Sharpeye (2 of 2)
|
||||
Implant: Serenity Anniversary Limited 'Sharpeye' Dose
|
||||
Implants named like: Serenity Limited 'Sharpeye' Dose (3 of 3)
|
||||
Skill: Astrometric Pinpointing
|
||||
Skill: Astrometrics
|
||||
"""
|
||||
@@ -13552,11 +13574,11 @@ class Effect4162(BaseEffect):
|
||||
|
||||
Used by:
|
||||
Modules from group: Scan Probe Launcher (4 of 7)
|
||||
Implants named like: Poteque 'Prospector' Astrometric Rangefinding AR (3 of 3)
|
||||
Implants named like: Poteque 'Prospector' Sharpeye (2 of 2)
|
||||
Implants named like: Rangefinding (6 of 6)
|
||||
Implants named like: Serenity Limited 'Sharpeye' Dose (3 of 3)
|
||||
Implants named like: grade Virtue (10 of 12)
|
||||
Modules named like: Gravity Capacitor Upgrade (8 of 8)
|
||||
Implant: Serenity Anniversary Limited 'Sharpeye' Dose
|
||||
Implant: Serenity YC122.9 Season Booster - Probe Scanning Strength
|
||||
Skill: Astrometric Rangefinding
|
||||
Skill: Astrometrics
|
||||
@@ -13567,7 +13589,7 @@ class Effect4162(BaseEffect):
|
||||
@staticmethod
|
||||
def handler(fit, container, context, projectionRange, **kwargs):
|
||||
level = container.level if 'skill' in context else 1
|
||||
penalized = False if 'skill' in context or 'implant' in context else True
|
||||
penalized = False if 'skill' in context or 'implant' in context or 'booster' in context else True
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill('Astrometrics'),
|
||||
'baseSensorStrength', container.getModifiedItemAttr('scanStrengthBonus') * level,
|
||||
stackingPenalties=penalized, **kwargs)
|
||||
@@ -18148,6 +18170,7 @@ class Effect5189(BaseEffect):
|
||||
trackingSpeedBonusEffectLasers
|
||||
|
||||
Used by:
|
||||
Implants named like: Tetrimon Precision Booster (3 of 3)
|
||||
Modules named like: Energy Metastasis Adjuster (8 of 8)
|
||||
"""
|
||||
|
||||
@@ -18155,9 +18178,10 @@ class Effect5189(BaseEffect):
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, module, context, projectionRange, **kwargs):
|
||||
penalties = 'booster' not in context
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == 'Energy Weapon',
|
||||
'trackingSpeed', module.getModifiedItemAttr('trackingSpeedBonus'),
|
||||
stackingPenalties=True, **kwargs)
|
||||
stackingPenalties=penalties, **kwargs)
|
||||
|
||||
|
||||
class Effect5190(BaseEffect):
|
||||
@@ -18165,7 +18189,6 @@ class Effect5190(BaseEffect):
|
||||
trackingSpeedBonusEffectProjectiles
|
||||
|
||||
Used by:
|
||||
Implants named like: Liberation Games Accuracy Booster (3 of 3)
|
||||
Modules named like: Projectile Metastasis Adjuster (8 of 8)
|
||||
"""
|
||||
|
||||
@@ -24319,7 +24342,12 @@ class Effect6104(BaseEffect):
|
||||
entosisDurationMultiply
|
||||
|
||||
Used by:
|
||||
Items from market group: Ships > Capital Ships (31 of 41)
|
||||
Ships from group: Carrier (4 of 4)
|
||||
Ships from group: Dreadnought (8 of 8)
|
||||
Ships from group: Force Auxiliary (6 of 6)
|
||||
Ships from group: Supercarrier (6 of 6)
|
||||
Ships from group: Titan (7 of 7)
|
||||
Ship: Rorqual
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -27265,8 +27293,7 @@ class Effect6437(BaseEffect):
|
||||
if 'effect' in kwargs:
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict
|
||||
strength *= ModifiedAttributeDict.getResistance(fit, kwargs['effect'])
|
||||
chanceModifier = 1 - min(1, strength / fit.scanStrength)
|
||||
fit.ecmProjectedStr *= chanceModifier
|
||||
fit.addProjectedEcm(strength)
|
||||
|
||||
|
||||
class Effect6439(BaseEffect):
|
||||
@@ -27460,8 +27487,7 @@ class Effect6470(BaseEffect):
|
||||
if 'effect' in kwargs:
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict
|
||||
strength *= ModifiedAttributeDict.getResistance(fit, kwargs['effect'])
|
||||
chanceModifier = 1 - min(1, strength / fit.scanStrength)
|
||||
fit.ecmProjectedStr *= chanceModifier
|
||||
fit.addProjectedEcm(strength)
|
||||
|
||||
|
||||
class Effect6472(BaseEffect):
|
||||
@@ -27769,14 +27795,11 @@ class Effect6502(BaseEffect):
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, src, context, projectionRange, **kwargs):
|
||||
fit.ship.boostItemAttr('armorExplosiveDamageResonance', src.getModifiedItemAttr('shipBonusDreadnoughtA2'),
|
||||
skill='Amarr Dreadnought', **kwargs)
|
||||
fit.ship.boostItemAttr('armorEmDamageResonance', src.getModifiedItemAttr('shipBonusDreadnoughtA2'),
|
||||
skill='Amarr Dreadnought', **kwargs)
|
||||
fit.ship.boostItemAttr('armorThermalDamageResonance', src.getModifiedItemAttr('shipBonusDreadnoughtA2'),
|
||||
skill='Amarr Dreadnought', **kwargs)
|
||||
fit.ship.boostItemAttr('armorKineticDamageResonance', src.getModifiedItemAttr('shipBonusDreadnoughtA2'),
|
||||
skill='Amarr Dreadnought', **kwargs)
|
||||
for dmgType in ('em', 'thermal', 'kinetic', 'explosive'):
|
||||
fit.ship.boostItemAttr(
|
||||
'armor{}DamageResonance'.format(dmgType.capitalize()),
|
||||
src.getModifiedItemAttr('shipBonusDreadnoughtA2'),
|
||||
skill='Amarr Dreadnought', **kwargs)
|
||||
|
||||
|
||||
class Effect6503(BaseEffect):
|
||||
@@ -27954,8 +27977,7 @@ class Effect6513(BaseEffect):
|
||||
if 'effect' in kwargs:
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict
|
||||
strength *= ModifiedAttributeDict.getResistance(fit, kwargs['effect'])
|
||||
chanceModifier = 1 - min(1, strength / fit.scanStrength)
|
||||
fit.ecmProjectedStr *= chanceModifier
|
||||
fit.addProjectedEcm(strength)
|
||||
|
||||
|
||||
class Effect6526(BaseEffect):
|
||||
@@ -28275,7 +28297,7 @@ class Effect6556(BaseEffect):
|
||||
moduleBonusDroneDamageAmplifier
|
||||
|
||||
Used by:
|
||||
Modules from group: Drone Damage Modules (11 of 11)
|
||||
Modules from group: Drone Damage Modules (12 of 12)
|
||||
Modules named like: C3 'Hivaa Saitsuo' Ballistic Control System (2 of 2)
|
||||
Module: Abyssal Ballistic Control System
|
||||
"""
|
||||
@@ -28532,7 +28554,7 @@ class Effect6566(BaseEffect):
|
||||
moduleBonusFighterSupportUnit
|
||||
|
||||
Used by:
|
||||
Modules from group: Fighter Support Unit (8 of 8)
|
||||
Modules from group: Fighter Support Unit (9 of 9)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -30181,9 +30203,6 @@ class Effect6658(BaseEffect):
|
||||
# Speed penalty
|
||||
fit.ship.boostItemAttr('maxVelocity', src.getModifiedItemAttr('speedFactor'), **kwargs)
|
||||
|
||||
# Max locked targets
|
||||
fit.ship.forceItemAttr('maxLockedTargets', src.getModifiedItemAttr('maxLockedTargets'), **kwargs)
|
||||
|
||||
# new with April 2016 release
|
||||
for scanType in ('Magnetometric', 'Ladar', 'Gravimetric', 'Radar'):
|
||||
fit.ship.boostItemAttr('scan{}Strength'.format(scanType),
|
||||
@@ -30586,8 +30605,7 @@ class Effect6685(BaseEffect):
|
||||
if 'effect' in kwargs:
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict
|
||||
strength *= ModifiedAttributeDict.getResistance(fit, kwargs['effect'])
|
||||
chanceModifier = 1 - min(1, strength / fit.scanStrength)
|
||||
fit.ecmProjectedStr *= chanceModifier
|
||||
fit.addProjectedEcm(strength)
|
||||
|
||||
|
||||
class Effect6686(BaseEffect):
|
||||
@@ -30846,8 +30864,7 @@ class Effect6695(BaseEffect):
|
||||
if 'effect' in kwargs:
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict
|
||||
strength *= ModifiedAttributeDict.getResistance(fit, kwargs['effect'])
|
||||
chanceModifier = 1 - min(1, strength / fit.scanStrength)
|
||||
fit.ecmProjectedStr *= chanceModifier
|
||||
fit.addProjectedEcm(strength)
|
||||
|
||||
|
||||
class Effect6697(BaseEffect):
|
||||
@@ -31133,6 +31150,7 @@ class Effect6714(BaseEffect):
|
||||
"""
|
||||
|
||||
type = 'projected', 'active'
|
||||
runTime = 'late'
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, module, context, projectionRange, **kwargs):
|
||||
@@ -31146,8 +31164,7 @@ class Effect6714(BaseEffect):
|
||||
if 'effect' in kwargs:
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict
|
||||
strength *= ModifiedAttributeDict.getResistance(fit, kwargs['effect'])
|
||||
chanceModifier = 1 - min(1, strength / fit.scanStrength)
|
||||
fit.ecmProjectedStr *= chanceModifier
|
||||
fit.addProjectedEcm(strength)
|
||||
|
||||
|
||||
class Effect6717(BaseEffect):
|
||||
@@ -34065,7 +34082,6 @@ class Effect7020(BaseEffect):
|
||||
Used by:
|
||||
Implants named like: Inquest 'Eros' Stasis Webifier MR (3 of 3)
|
||||
Implants named like: Inquest 'Hedone' Entanglement Optimizer WS (3 of 3)
|
||||
Implants named like: Liberation Games EWar Booster (3 of 3)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -35648,7 +35664,7 @@ class Effect7193(BaseEffect):
|
||||
systemMiningCycleTimeBonus
|
||||
|
||||
Used by:
|
||||
Celestials named like: Stellar Observatory (4 of 4)
|
||||
Celestials from group: Destructible Effect Beacon (4 of 6)
|
||||
Celestials named like: Triglavian Invasion System Effects (3 of 3)
|
||||
"""
|
||||
|
||||
@@ -37553,3 +37569,71 @@ class Effect8158(BaseEffect):
|
||||
fit.modules.filteredItemBoost(
|
||||
lambda mod: mod.item.requiresSkill('Cloaking'), 'stabilizeCloakDuration',
|
||||
booster.getModifiedItemAttr('stabilizeCloakDurationBonus'), **kwargs)
|
||||
|
||||
|
||||
class Effect8267(BaseEffect):
|
||||
"""
|
||||
weaponDisruptorResistanceBonusPassive
|
||||
|
||||
Used by:
|
||||
Implants named like: Harvest Anti Disruptor Booster (3 of 3)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, container, context, projectionRange, **kwargs):
|
||||
fit.ship.boostItemAttr(
|
||||
'weaponDisruptionResistance',
|
||||
container.getModifiedItemAttr('weaponDisruptionResistanceBonus'), **kwargs)
|
||||
|
||||
|
||||
class Effect8268(BaseEffect):
|
||||
"""
|
||||
nosferatuDurationBonusPassive
|
||||
|
||||
Used by:
|
||||
Implants named like: Harvest Nosferatu Booster (3 of 3)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, module, context, projectionRange, **kwargs):
|
||||
fit.modules.filteredItemBoost(
|
||||
lambda mod: mod.item.group.name == 'Energy Nosferatu', 'duration',
|
||||
module.getModifiedItemAttr('durationBonus'), **kwargs)
|
||||
|
||||
|
||||
class Effect8269(BaseEffect):
|
||||
"""
|
||||
stasisWebifierMaxRangeAddPassive
|
||||
|
||||
Used by:
|
||||
Implants named like: Harvest Webifier Booster (3 of 3)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, module, context, projectionRange, **kwargs):
|
||||
fit.modules.filteredItemIncrease(
|
||||
lambda mod: mod.item.group.name == 'Stasis Web', 'maxRange',
|
||||
module.getModifiedItemAttr('stasisWebRangeAdd'), **kwargs)
|
||||
|
||||
|
||||
class Effect8270(BaseEffect):
|
||||
"""
|
||||
capacitorWarfareResistanceBonusPassive
|
||||
|
||||
Used by:
|
||||
Implants named like: Tetrimon Anti Drain Booster (3 of 3)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, container, context, projectionRange, **kwargs):
|
||||
fit.ship.boostItemAttr(
|
||||
'energyWarfareResistance',
|
||||
container.getModifiedItemAttr('energyWarfareResistanceBonus'), **kwargs)
|
||||
|
||||
@@ -567,7 +567,18 @@ class Group(EqBase):
|
||||
|
||||
|
||||
class DynamicItem(EqBase):
|
||||
pass
|
||||
|
||||
@property
|
||||
def shortName(self):
|
||||
name = self.item.customName
|
||||
keywords = ('Decayed', 'Gravid', 'Unstable', 'Radical')
|
||||
for kw in keywords:
|
||||
if name.startswith(f'{kw} '):
|
||||
name = kw
|
||||
m = re.match('(?P<mutagrade>\S+) (?P<dronetype>\S+) Drone (?P<mutatype>\S+) Mutaplasmid', name)
|
||||
if m:
|
||||
name = '{} {}'.format(m.group('mutagrade'), m.group('mutatype'))
|
||||
return name
|
||||
|
||||
|
||||
class DynamicItemAttribute(EqBase):
|
||||
|
||||
@@ -25,6 +25,8 @@ from sqlalchemy.orm import reconstructor, validates
|
||||
import eos.db
|
||||
from eos.effectHandlerHelpers import HandledCharge, HandledItem
|
||||
from eos.modifiedAttributeDict import ChargeAttrShortcut, ItemAttrShortcut, ModifiedAttributeDict
|
||||
from eos.saveddata.mutatedMixin import MutatedMixin, MutaError
|
||||
from eos.saveddata.mutator import MutatorDrone
|
||||
from eos.utils.cycles import CycleInfo
|
||||
from eos.utils.default import DEFAULT
|
||||
from eos.utils.stats import DmgTypes, RRTypes
|
||||
@@ -33,12 +35,13 @@ from eos.utils.stats import DmgTypes, RRTypes
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut, MutatedMixin):
|
||||
MINING_ATTRIBUTES = ("miningAmount",)
|
||||
|
||||
def __init__(self, item):
|
||||
def __init__(self, item, baseItem=None, mutaplasmid=None):
|
||||
"""Initialize a drone from the program"""
|
||||
self.__item = item
|
||||
self._item = item
|
||||
self._mutaInit(baseItem=baseItem, mutaplasmid=mutaplasmid)
|
||||
|
||||
if self.isInvalid:
|
||||
raise ValueError("Passed item is not a Drone")
|
||||
@@ -53,14 +56,19 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
@reconstructor
|
||||
def init(self):
|
||||
"""Initialize a drone from the database and validate"""
|
||||
self.__item = None
|
||||
self._item = None
|
||||
|
||||
if self.itemID:
|
||||
self.__item = eos.db.getItem(self.itemID)
|
||||
if self.__item is None:
|
||||
self._item = eos.db.getItem(self.itemID)
|
||||
if self._item is None:
|
||||
pyfalog.error("Item (id: {0}) does not exist", self.itemID)
|
||||
return
|
||||
|
||||
try:
|
||||
self._mutaReconstruct()
|
||||
except MutaError:
|
||||
return
|
||||
|
||||
if self.isInvalid:
|
||||
pyfalog.error("Item (id: {0}) is not a Drone", self.itemID)
|
||||
return
|
||||
@@ -74,10 +82,13 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
self.__baseRRAmount = None
|
||||
self.__miningyield = None
|
||||
self.__itemModifiedAttributes = ModifiedAttributeDict()
|
||||
self.__itemModifiedAttributes.original = self.__item.attributes
|
||||
self.__itemModifiedAttributes.overrides = self.__item.overrides
|
||||
|
||||
self.__itemModifiedAttributes.original = self._item.attributes
|
||||
self.__itemModifiedAttributes.overrides = self._item.overrides
|
||||
self.__chargeModifiedAttributes = ModifiedAttributeDict()
|
||||
|
||||
self._mutaLoadMutators(mutatorClass=MutatorDrone)
|
||||
self.__itemModifiedAttributes.mutators = self.mutators
|
||||
|
||||
# pheonix todo: check the attribute itself, not the modified. this will always return 0 now.
|
||||
chargeID = self.getModifiedItemAttr("entityMissileTypeID", None)
|
||||
if chargeID is not None:
|
||||
@@ -96,11 +107,17 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
|
||||
@property
|
||||
def isInvalid(self):
|
||||
return self.__item is None or self.__item.category.name != "Drone"
|
||||
if self._item is None:
|
||||
return True
|
||||
if self._item.category.name != "Drone":
|
||||
return True
|
||||
if self._mutaIsInvalid:
|
||||
return True
|
||||
return False
|
||||
|
||||
@property
|
||||
def item(self):
|
||||
return self.__item
|
||||
return self._item
|
||||
|
||||
@property
|
||||
def charge(self):
|
||||
@@ -337,10 +354,11 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
effect.handler(fit, self, ("droneCharge",), projectionRange, effect=effect)
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
copy = Drone(self.item)
|
||||
copy = Drone(self.item, self.baseItem, self.mutaplasmid)
|
||||
copy.amount = self.amount
|
||||
copy.amountActive = self.amountActive
|
||||
copy.projectionRange = self.projectionRange
|
||||
self._mutaApplyMutators(mutatorClass=MutatorDrone, targetInstance=copy)
|
||||
return copy
|
||||
|
||||
def rebase(self, item):
|
||||
@@ -348,10 +366,11 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
amountActive = self.amountActive
|
||||
projectionRange = self.projectionRange
|
||||
|
||||
Drone.__init__(self, item)
|
||||
Drone.__init__(self, item, self.baseItem, self.mutaplasmid)
|
||||
self.amount = amount
|
||||
self.amountActive = amountActive
|
||||
self.projectionRange = projectionRange
|
||||
self._mutaApplyMutators(mutatorClass=MutatorDrone)
|
||||
|
||||
def fits(self, fit):
|
||||
fitDroneGroupLimits = set()
|
||||
|
||||
@@ -155,7 +155,7 @@ class Fit:
|
||||
self.factorReload = False
|
||||
self.boostsFits = set()
|
||||
self.gangBoosts = None
|
||||
self.ecmProjectedStr = 1
|
||||
self.__ecmProjectedList = []
|
||||
self.commandBonuses = {}
|
||||
|
||||
def clearFactorReloadDependentData(self):
|
||||
@@ -411,7 +411,11 @@ class Fit:
|
||||
|
||||
@property
|
||||
def jamChance(self):
|
||||
return (1 - self.ecmProjectedStr) * 100
|
||||
sensors = self.scanStrength
|
||||
retainLockChance = 1
|
||||
for jamStr in self.__ecmProjectedList:
|
||||
retainLockChance *= 1 - min(1, jamStr / sensors)
|
||||
return (1 - retainLockChance) * 100
|
||||
|
||||
@property
|
||||
def maxSpeed(self):
|
||||
@@ -499,7 +503,7 @@ class Fit:
|
||||
self.__capUsed = None
|
||||
self.__capRecharge = None
|
||||
self.__savedCapSimData.clear()
|
||||
self.ecmProjectedStr = 1
|
||||
self.__ecmProjectedList = []
|
||||
# self.commandBonuses = {}
|
||||
|
||||
del self.__calculatedTargets[:]
|
||||
@@ -562,6 +566,9 @@ class Fit:
|
||||
if warfareBuffID not in self.commandBonuses or abs(self.commandBonuses[warfareBuffID][1]) < abs(value):
|
||||
self.commandBonuses[warfareBuffID] = (runTime, value, module, effect)
|
||||
|
||||
def addProjectedEcm(self, strength):
|
||||
self.__ecmProjectedList.append(strength)
|
||||
|
||||
def __runCommandBoosts(self, runTime="normal"):
|
||||
pyfalog.debug("Applying gang boosts for {0}", repr(self))
|
||||
for warfareBuffID in list(self.commandBonuses.keys()):
|
||||
|
||||
@@ -27,7 +27,8 @@ from eos.const import FittingHardpoint, FittingModuleState, FittingSlot
|
||||
from eos.effectHandlerHelpers import HandledCharge, HandledItem
|
||||
from eos.modifiedAttributeDict import ChargeAttrShortcut, ItemAttrShortcut, ModifiedAttributeDict
|
||||
from eos.saveddata.citadel import Citadel
|
||||
from eos.saveddata.mutator import Mutator
|
||||
from eos.saveddata.mutatedMixin import MutatedMixin, MutaError
|
||||
from eos.saveddata.mutator import MutatorModule
|
||||
from eos.utils.cycles import CycleInfo, CycleSequence
|
||||
from eos.utils.default import DEFAULT
|
||||
from eos.utils.float import floatUnerr
|
||||
@@ -61,7 +62,7 @@ ProjectedSystem = {
|
||||
}
|
||||
|
||||
|
||||
class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut, MutatedMixin):
|
||||
"""An instance of this class represents a module together with its charge and modified attributes"""
|
||||
MINING_ATTRIBUTES = ("miningAmount",)
|
||||
SYSTEM_GROUPS = (
|
||||
@@ -72,21 +73,9 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
"""Initialize a module from the program"""
|
||||
|
||||
self.itemID = item.ID if item is not None else None
|
||||
self.baseItemID = baseItem.ID if baseItem is not None else None
|
||||
self.mutaplasmidID = mutaplasmid.ID if mutaplasmid is not None else None
|
||||
|
||||
if baseItem is not None:
|
||||
# we're working with a mutated module, need to get abyssal module loaded with the base attributes
|
||||
# Note: there may be a better way of doing this, such as a metho on this classe to convert(mutaplamid). This
|
||||
# will require a bit more research though, considering there has never been a need to "swap" out the item of a Module
|
||||
# before, and there may be assumptions taken with regards to the item never changing (pre-calculated / cached results, for example)
|
||||
self.__item = eos.db.getItemWithBaseItemAttribute(self.itemID, self.baseItemID)
|
||||
self.__baseItem = baseItem
|
||||
self.__mutaplasmid = mutaplasmid
|
||||
else:
|
||||
self.__item = item
|
||||
self.__baseItem = baseItem
|
||||
self.__mutaplasmid = mutaplasmid
|
||||
self._item = item
|
||||
self._mutaInit(baseItem=baseItem, mutaplasmid=mutaplasmid)
|
||||
|
||||
if item is not None and self.isInvalid:
|
||||
raise ValueError("Passed item is not a Module")
|
||||
@@ -101,27 +90,22 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
@reconstructor
|
||||
def init(self):
|
||||
"""Initialize a module from the database and validate"""
|
||||
self.__item = None
|
||||
self.__baseItem = None
|
||||
self._item = None
|
||||
self.__charge = None
|
||||
self.__mutaplasmid = None
|
||||
|
||||
# we need this early if module is invalid and returns early
|
||||
self.__slot = self.dummySlot
|
||||
|
||||
if self.itemID:
|
||||
self.__item = eos.db.getItem(self.itemID)
|
||||
if self.__item is None:
|
||||
self._item = eos.db.getItem(self.itemID)
|
||||
if self._item is None:
|
||||
pyfalog.error("Item (id: {0}) does not exist", self.itemID)
|
||||
return
|
||||
|
||||
if self.baseItemID:
|
||||
self.__item = eos.db.getItemWithBaseItemAttribute(self.itemID, self.baseItemID)
|
||||
self.__baseItem = eos.db.getItem(self.baseItemID)
|
||||
self.__mutaplasmid = eos.db.getMutaplasmid(self.mutaplasmidID)
|
||||
if self.__baseItem is None:
|
||||
pyfalog.error("Base Item (id: {0}) does not exist", self.itemID)
|
||||
return
|
||||
try:
|
||||
self._mutaReconstruct()
|
||||
except MutaError:
|
||||
return
|
||||
|
||||
if self.isInvalid:
|
||||
pyfalog.error("Item (id: {0}) is not a Module", self.itemID)
|
||||
@@ -149,21 +133,13 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
self.__chargeModifiedAttributes = ModifiedAttributeDict(parent=self)
|
||||
self.__slot = self.dummySlot # defaults to None
|
||||
|
||||
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)
|
||||
|
||||
# Instantiate / remove mutators if this is a mutated module
|
||||
if self.__baseItem:
|
||||
for x in self.mutaplasmid.attributes:
|
||||
attr = self.item.attributes[x.name]
|
||||
id = attr.ID
|
||||
if id not in self.mutators: # create the mutator
|
||||
Mutator(self, attr, attr.value)
|
||||
# @todo: remove attributes that are no longer part of the mutaplasmid.
|
||||
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)
|
||||
|
||||
self._mutaLoadMutators(mutatorClass=MutatorModule)
|
||||
self.__itemModifiedAttributes.mutators = self.mutators
|
||||
|
||||
if self.__charge:
|
||||
@@ -198,28 +174,22 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
# todo: validate baseItem as well if it's set.
|
||||
if self.isEmpty:
|
||||
return False
|
||||
if self.__item is None:
|
||||
if self._item is None:
|
||||
return True
|
||||
if (
|
||||
self.__item.category.name not in ("Module", "Subsystem", "Structure Module")
|
||||
and self.__item.group.name not in self.SYSTEM_GROUPS
|
||||
self._item.category.name not in ("Module", "Subsystem", "Structure Module")
|
||||
and self._item.group.name not in self.SYSTEM_GROUPS
|
||||
):
|
||||
return True
|
||||
if (
|
||||
self.__item.category.name == "Structure Module"
|
||||
and self.__item.group.name == "Quantum Cores"
|
||||
self._item.category.name == "Structure Module"
|
||||
and self._item.group.name == "Quantum Cores"
|
||||
):
|
||||
return True
|
||||
if self.item.isAbyssal and not self.isMutated:
|
||||
return True
|
||||
if self.isMutated and not self.__mutaplasmid:
|
||||
if self._mutaIsInvalid:
|
||||
return True
|
||||
return False
|
||||
|
||||
@property
|
||||
def isMutated(self):
|
||||
return self.baseItemID and self.mutaplasmidID
|
||||
|
||||
@property
|
||||
def numCharges(self):
|
||||
return self.getNumCharges(self.charge)
|
||||
@@ -419,15 +389,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
|
||||
@property
|
||||
def item(self):
|
||||
return self.__item if self.__item != 0 else None
|
||||
|
||||
@property
|
||||
def baseItem(self):
|
||||
return self.__baseItem
|
||||
|
||||
@property
|
||||
def mutaplasmid(self):
|
||||
return self.__mutaplasmid
|
||||
return self._item if self._item != 0 else None
|
||||
|
||||
@property
|
||||
def charge(self):
|
||||
@@ -1098,9 +1060,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
copy.spoolType = self.spoolType
|
||||
copy.spoolAmount = self.spoolAmount
|
||||
copy.projectionRange = self.projectionRange
|
||||
|
||||
for x in self.mutators.values():
|
||||
Mutator(copy, x.attribute, x.value)
|
||||
self._mutaApplyMutators(mutatorClass=MutatorModule, targetInstance=copy)
|
||||
|
||||
return copy
|
||||
|
||||
@@ -1118,14 +1078,11 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
self.spoolType = spoolType
|
||||
self.spoolAmount = spoolAmount
|
||||
self.projectionRange = projectionRange
|
||||
for x in self.mutators.values():
|
||||
Mutator(self, x.attribute, x.value)
|
||||
self._mutaApplyMutators(mutatorClass=MutatorModule)
|
||||
|
||||
def __repr__(self):
|
||||
if self.item:
|
||||
return "Module(ID={}, name={}) at {}".format(
|
||||
self.item.ID, self.item.name, hex(id(self))
|
||||
)
|
||||
return "Module(ID={}, name={}) at {}".format(self.item.ID, self.item.name, hex(id(self)))
|
||||
else:
|
||||
return "EmptyModule() at {}".format(hex(id(self)))
|
||||
|
||||
|
||||
105
eos/saveddata/mutatedMixin.py
Normal file
@@ -0,0 +1,105 @@
|
||||
# ===============================================================================
|
||||
# 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 eos.db
|
||||
|
||||
from logbook import Logger
|
||||
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class MutaError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class MutatedMixin:
|
||||
|
||||
@property
|
||||
def isMutated(self):
|
||||
return bool(self.baseItemID and self.mutaplasmidID)
|
||||
|
||||
@property
|
||||
def baseItem(self):
|
||||
return self.__baseItem
|
||||
|
||||
@property
|
||||
def mutaplasmid(self):
|
||||
return self.__mutaplasmid
|
||||
|
||||
@property
|
||||
def fullName(self):
|
||||
if self.isMutated:
|
||||
mutaShortName = self.mutaplasmid.shortName
|
||||
mutaFullName = self.mutaplasmid.item.customName
|
||||
# Short name can be unavailable for non-english language
|
||||
if mutaShortName != mutaFullName:
|
||||
return f'{self.mutaplasmid.shortName} {self.baseItem.customName}'
|
||||
return self.item.customName
|
||||
|
||||
def _mutaInit(self, baseItem, mutaplasmid):
|
||||
self.baseItemID = baseItem.ID if baseItem is not None else None
|
||||
self.mutaplasmidID = mutaplasmid.ID if mutaplasmid is not None else None
|
||||
if baseItem is not None:
|
||||
# we're working with a mutated module, need to get abyssal module loaded with the base attributes
|
||||
# Note: there may be a better way of doing this, such as a metho on this classe to convert(mutaplamid). This
|
||||
# will require a bit more research though, considering there has never been a need to "swap" out the item of a Module
|
||||
# before, and there may be assumptions taken with regards to the item never changing (pre-calculated / cached results, for example)
|
||||
self._item = eos.db.getItemWithBaseItemAttribute(self._item.ID, self.baseItemID)
|
||||
self.__baseItem = baseItem
|
||||
self.__mutaplasmid = mutaplasmid
|
||||
else:
|
||||
self.__baseItem = None
|
||||
self.__mutaplasmid = None
|
||||
|
||||
def _mutaReconstruct(self):
|
||||
self.__baseItem = None
|
||||
self.__mutaplasmid = None
|
||||
if self.baseItemID:
|
||||
self._item = eos.db.getItemWithBaseItemAttribute(self.itemID, self.baseItemID)
|
||||
self.__baseItem = eos.db.getItem(self.baseItemID)
|
||||
self.__mutaplasmid = eos.db.getMutaplasmid(self.mutaplasmidID)
|
||||
if self.__baseItem is None:
|
||||
pyfalog.error("Base Item (id: {0}) does not exist", self.itemID)
|
||||
raise MutaError
|
||||
|
||||
def _mutaLoadMutators(self, mutatorClass):
|
||||
# Instantiate / remove mutators if this is a mutated module
|
||||
if self.__baseItem:
|
||||
for x in self.mutaplasmid.attributes:
|
||||
attr = self.item.attributes[x.name]
|
||||
id = attr.ID
|
||||
if id not in self.mutators: # create the mutator
|
||||
mutatorClass(self, attr, attr.value)
|
||||
# @todo: remove attributes that are no longer part of the mutaplasmid.
|
||||
|
||||
@property
|
||||
def _mutaIsInvalid(self):
|
||||
if self.item.isAbyssal and not self.isMutated:
|
||||
return True
|
||||
if self.isMutated and not self.__mutaplasmid:
|
||||
return True
|
||||
return False
|
||||
|
||||
def _mutaApplyMutators(self, mutatorClass, targetInstance=None):
|
||||
if targetInstance is None:
|
||||
targetInstance = self
|
||||
for x in self.mutators.values():
|
||||
mutatorClass(targetInstance, x.attribute, x.value)
|
||||
@@ -27,10 +27,10 @@ from eos.eqBase import EqBase
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class Mutator(EqBase):
|
||||
""" Mutators are the object that represent an attribute override on the module level, in conjunction with
|
||||
mutaplasmids. Each mutated module, when created, is instantiated with a list of these objects, dictated by the
|
||||
mutaplasmid that is used on the base module.
|
||||
class MutatorBase(EqBase):
|
||||
""" Mutators are the object that represent an attribute override on the eos item level, in conjunction with
|
||||
mutaplasmids. Each mutated item, when created, is instantiated with a list of these objects, dictated by the
|
||||
mutaplasmid that is used on the base item.
|
||||
|
||||
A note on the different attributes on this object:
|
||||
* attribute: points to the definition of the attribute from dgmattribs.
|
||||
@@ -40,13 +40,13 @@ class Mutator(EqBase):
|
||||
This could probably be cleaned up with smarter relationships, but whatever
|
||||
"""
|
||||
|
||||
def __init__(self, module, attr, value):
|
||||
# this needs to be above module assignment, as assigning the module will add it to the list and it via
|
||||
def __init__(self, item, attr, value):
|
||||
# this needs to be above item assignment, as assigning the item will add it to the list and it via
|
||||
# relationship and needs this set 4correctly
|
||||
self.attrID = attr.ID
|
||||
|
||||
self.module = module
|
||||
self.moduleID = module.ID
|
||||
self.item = item
|
||||
self.itemID = item.ID
|
||||
|
||||
self.__attr = attr
|
||||
self.build()
|
||||
@@ -67,20 +67,20 @@ class Mutator(EqBase):
|
||||
|
||||
def build(self):
|
||||
# try...except here to catch orphaned mutators. Pretty rare, only happens so far if hacking the database
|
||||
# But put it here to remove the module link if it happens, until a better solution can be developed
|
||||
# But put it here to remove the eos item link if it happens, until a better solution can be developed
|
||||
try:
|
||||
# dynamic attribute links to the Mutaplasmids attribute definition for this mutated definition
|
||||
self.dynamicAttribute = next(a for a in self.module.mutaplasmid.attributes if a.attributeID == self.attrID)
|
||||
self.dynamicAttribute = next(a for a in self.item.mutaplasmid.attributes if a.attributeID == self.attrID)
|
||||
# base attribute links to the base ite's attribute for this mutated definition (contains original, base value)
|
||||
self.baseAttribute = self.module.item.attributes[self.dynamicAttribute.name]
|
||||
self.baseAttribute = self.item.item.attributes[self.dynamicAttribute.name]
|
||||
except (KeyboardInterrupt, SystemExit):
|
||||
raise
|
||||
except:
|
||||
self.module = None
|
||||
self.item = None
|
||||
|
||||
@validates("value")
|
||||
def validator(self, key, val):
|
||||
""" Validates values as properly falling within the range of the modules' Mutaplasmid """
|
||||
""" Validates values as properly falling within the range of the items' Mutaplasmid """
|
||||
if self.baseValue == 0:
|
||||
return 0
|
||||
mod = val / self.baseValue
|
||||
@@ -99,7 +99,7 @@ class Mutator(EqBase):
|
||||
# @todo: need to test what happens:
|
||||
# 1) if an attribute is removed from the EVE database
|
||||
# 2) if a mutaplasmid does not have the attribute anymore
|
||||
# 3) if a mutaplasmid does not exist (in eve or on the module's item)
|
||||
# 3) if a mutaplasmid does not exist (in eve or on the pyfa item's item)
|
||||
# Can remove invalid ones in a SQLAlchemy collection class... eventually
|
||||
return self.__attr is None
|
||||
|
||||
@@ -139,3 +139,11 @@ class Mutator(EqBase):
|
||||
@property
|
||||
def attribute(self):
|
||||
return self.__attr
|
||||
|
||||
|
||||
class MutatorModule(MutatorBase):
|
||||
pass
|
||||
|
||||
|
||||
class MutatorDrone(MutatorBase):
|
||||
pass
|
||||
|
||||
@@ -193,11 +193,8 @@ class DroneView(Display):
|
||||
|
||||
@staticmethod
|
||||
def droneKey(drone):
|
||||
sMkt = Market.getInstance()
|
||||
|
||||
groupName = sMkt.getMarketGroupByItem(drone.item).marketGroupName
|
||||
|
||||
return (DRONE_ORDER.index(groupName), drone.item.name)
|
||||
groupName = Market.getInstance().getMarketGroupByItem(drone.item).marketGroupName
|
||||
return (DRONE_ORDER.index(groupName), drone.isMutated, drone.fullName)
|
||||
|
||||
def fitChanged(self, event):
|
||||
event.Skip()
|
||||
|
||||
@@ -26,7 +26,7 @@ from gui.builtinContextMenus import itemAmountChange
|
||||
from gui.builtinContextMenus import itemProjectionRange
|
||||
from gui.builtinContextMenus import droneSplitStack
|
||||
from gui.builtinContextMenus import itemVariationChange
|
||||
from gui.builtinContextMenus import moduleMutations
|
||||
from gui.builtinContextMenus import itemMutations
|
||||
from gui.builtinContextMenus import moduleFill
|
||||
from gui.builtinContextMenus import moduleMutatedExport
|
||||
from gui.builtinContextMenus import skillAffectors
|
||||
|
||||
@@ -5,7 +5,7 @@ from gui import fitCommands as cmd
|
||||
from gui.contextMenu import ContextMenuUnconditional
|
||||
from gui.utils.clipboard import fromClipboard
|
||||
from service.fit import Fit
|
||||
from service.port.eft import parseAdditions
|
||||
from service.port.eft import parseAdditions, importGetMutationData, lineIter
|
||||
|
||||
_t = wx.GetTranslation
|
||||
|
||||
@@ -41,9 +41,12 @@ class AdditionsImport(ContextMenuUnconditional):
|
||||
|
||||
def activate(self, callingWindow, fullContext, i):
|
||||
text = fromClipboard()
|
||||
items = parseAdditions(text)
|
||||
lines = list(lineIter(text))
|
||||
mutaData = importGetMutationData(lines)
|
||||
text = '\n'.join(lines)
|
||||
items = parseAdditions(text, mutaData=mutaData)
|
||||
filterFunc = self.viewSpecMap[self.srcContext][1]
|
||||
items = [(i.ID, a) for i, a in items if filterFunc(i)]
|
||||
items = [(i.ID, a, m) for i, a, m in items if filterFunc(i)]
|
||||
if not items:
|
||||
return
|
||||
command = self.viewSpecMap[self.srcContext][2]
|
||||
|
||||
@@ -8,7 +8,7 @@ from eos.saveddata.cargo import Cargo as es_Cargo
|
||||
from eos.saveddata.drone import Drone
|
||||
from eos.saveddata.fighter import Fighter as es_Fighter
|
||||
from eos.saveddata.fit import Fit as es_Fit
|
||||
from gui.contextMenu import ContextMenuSingle
|
||||
from gui.contextMenu import ContextMenuCombined
|
||||
from service.fit import Fit
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
@@ -16,12 +16,12 @@ from service.fit import Fit
|
||||
_t = wx.GetTranslation
|
||||
|
||||
|
||||
class ChangeItemAmount(ContextMenuSingle):
|
||||
class ChangeItemAmount(ContextMenuCombined):
|
||||
|
||||
def __init__(self):
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
def display(self, callingWindow, srcContext, mainItem):
|
||||
def display(self, callingWindow, srcContext, mainItem, selection):
|
||||
if srcContext not in ("droneItem", "projectedDrone", "cargoItem", "projectedFit", "fighterItem", "projectedFighter"):
|
||||
return False
|
||||
|
||||
@@ -30,10 +30,12 @@ class ChangeItemAmount(ContextMenuSingle):
|
||||
|
||||
return True
|
||||
|
||||
def getText(self, callingWindow, itmContext, mainItem):
|
||||
def getText(self, callingWindow, itmContext, mainItem, selection):
|
||||
if isinstance(mainItem, es_Cargo):
|
||||
return _t("Change Selection Quantity")
|
||||
return _t("Change {0} Quantity").format(itmContext)
|
||||
|
||||
def activate(self, callingWindow, fullContext, mainItem, i):
|
||||
def activate(self, callingWindow, fullContext, mainItem, selection, i):
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
srcContext = fullContext[0]
|
||||
if isinstance(mainItem, es_Fit):
|
||||
@@ -56,8 +58,12 @@ class ChangeItemAmount(ContextMenuSingle):
|
||||
cleanInput = int(float(re.sub(r'[^0-9.]', '', dlg.input.GetLineText(0).strip())))
|
||||
|
||||
if isinstance(mainItem, es_Cargo):
|
||||
self.mainFrame.command.Submit(cmd.GuiChangeCargoAmountCommand(
|
||||
fitID=fitID, itemID=mainItem.itemID, amount=cleanInput))
|
||||
itemIDs = []
|
||||
for cargo in selection:
|
||||
if cargo in fit.cargo:
|
||||
itemIDs.append(cargo.itemID)
|
||||
self.mainFrame.command.Submit(cmd.GuiChangeCargosAmountCommand(
|
||||
fitID=fitID, itemIDs=itemIDs, amount=cleanInput))
|
||||
elif isinstance(mainItem, Drone):
|
||||
if srcContext == "projectedDrone":
|
||||
self.mainFrame.command.Submit(cmd.GuiChangeProjectedDroneAmountCommand(
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
# noinspection PyPackageRequirements
|
||||
import re
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
import gui.mainFrame
|
||||
from gui.contextMenu import ContextMenuSingle
|
||||
from gui.fitCommands import GuiConvertMutatedLocalModuleCommand, GuiRevertMutatedLocalModuleCommand
|
||||
from gui.fitCommands import (
|
||||
GuiConvertMutatedLocalModuleCommand, GuiRevertMutatedLocalModuleCommand,
|
||||
GuiConvertMutatedLocalDroneCommand, GuiRevertMutatedLocalDroneCommand)
|
||||
from service.fit import Fit
|
||||
|
||||
_t = wx.GetTranslation
|
||||
|
||||
|
||||
class ChangeModuleMutation(ContextMenuSingle):
|
||||
class ChangeItemMutation(ContextMenuSingle):
|
||||
|
||||
def __init__(self):
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
@@ -18,10 +21,10 @@ class ChangeModuleMutation(ContextMenuSingle):
|
||||
|
||||
def display(self, callingWindow, srcContext, mainItem):
|
||||
|
||||
if srcContext != "fittingModule" or self.mainFrame.getActiveFit() is None:
|
||||
if srcContext not in ("fittingModule", "droneItem") or self.mainFrame.getActiveFit() is None:
|
||||
return False
|
||||
|
||||
if mainItem is None or mainItem.isEmpty:
|
||||
if mainItem is None or getattr(mainItem, 'isEmpty', False):
|
||||
return False
|
||||
|
||||
if len(mainItem.item.mutaplasmids) == 0 and not mainItem.isMutated:
|
||||
@@ -42,24 +45,27 @@ class ChangeModuleMutation(ContextMenuSingle):
|
||||
|
||||
menu = rootMenu if msw else sub
|
||||
|
||||
for item in mainItem.item.mutaplasmids:
|
||||
label = item.item.name
|
||||
for mutaplasmid in mainItem.item.mutaplasmids:
|
||||
id = ContextMenuSingle.nextID()
|
||||
self.eventIDs[id] = (item, mainItem)
|
||||
skillItem = wx.MenuItem(menu, id, label)
|
||||
menu.Bind(wx.EVT_MENU, self.handleMenu, skillItem)
|
||||
sub.Append(skillItem)
|
||||
self.eventIDs[id] = (mutaplasmid, mainItem)
|
||||
mItem = wx.MenuItem(menu, id, mutaplasmid.shortName)
|
||||
menu.Bind(wx.EVT_MENU, self.handleMenu, mItem)
|
||||
sub.Append(mItem)
|
||||
|
||||
return sub
|
||||
|
||||
def handleMenu(self, event):
|
||||
mutaplasmid, mod = self.eventIDs[event.Id]
|
||||
mutaplasmid, item = self.eventIDs[event.Id]
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
fit = Fit.getInstance().getFit(fitID)
|
||||
if mod in fit.modules:
|
||||
position = fit.modules.index(mod)
|
||||
if item in fit.modules:
|
||||
position = fit.modules.index(item)
|
||||
self.mainFrame.command.Submit(GuiConvertMutatedLocalModuleCommand(
|
||||
fitID=fitID, position=position, mutaplasmid=mutaplasmid))
|
||||
elif item in fit.drones:
|
||||
position = fit.drones.index(item)
|
||||
self.mainFrame.command.Submit(GuiConvertMutatedLocalDroneCommand(
|
||||
fitID=fitID, position=position, mutaplasmid=mutaplasmid))
|
||||
|
||||
def activate(self, callingWindow, fullContext, mainItem, i):
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
@@ -68,9 +74,13 @@ class ChangeModuleMutation(ContextMenuSingle):
|
||||
position = fit.modules.index(mainItem)
|
||||
self.mainFrame.command.Submit(GuiRevertMutatedLocalModuleCommand(
|
||||
fitID=fitID, position=position))
|
||||
elif mainItem in fit.drones:
|
||||
position = fit.drones.index(mainItem)
|
||||
self.mainFrame.command.Submit(GuiRevertMutatedLocalDroneCommand(
|
||||
fitID=fitID, position=position))
|
||||
|
||||
def getBitmap(self, callingWindow, context, mainItem):
|
||||
return None
|
||||
|
||||
|
||||
ChangeModuleMutation.register()
|
||||
ChangeItemMutation.register()
|
||||
@@ -355,4 +355,5 @@ class ItemParams(wx.Panel):
|
||||
fvalue = roundDec(value, digits)
|
||||
else:
|
||||
fvalue = value
|
||||
return "%s %s" % (fvalue, unit)
|
||||
unitSuffix = f' {unit}' if unit is not None else ''
|
||||
return f'{fvalue}{unitSuffix}'
|
||||
|
||||
@@ -18,23 +18,22 @@ _t = wx.GetTranslation
|
||||
|
||||
class ItemMutatorPanel(wx.Panel):
|
||||
|
||||
def __init__(self, parent, mod):
|
||||
def __init__(self, parent, stuff):
|
||||
wx.Panel.__init__(self, parent)
|
||||
self.stuff = mod
|
||||
self.stuff = stuff
|
||||
self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE))
|
||||
|
||||
mainSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
headerSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
headerSizer.AddStretchSpacer()
|
||||
itemIcon = BitmapLoader.getStaticBitmap(mod.item.iconID, self, "icons")
|
||||
itemIcon = BitmapLoader.getStaticBitmap(stuff.item.iconID, self, "icons")
|
||||
if itemIcon is not None:
|
||||
headerSizer.Add(itemIcon, 0, 0, 0)
|
||||
mutaIcon = BitmapLoader.getStaticBitmap(mod.mutaplasmid.item.iconID, self, "icons")
|
||||
mutaIcon = BitmapLoader.getStaticBitmap(stuff.mutaplasmid.item.iconID, self, "icons")
|
||||
if mutaIcon is not None:
|
||||
headerSizer.Add(mutaIcon, 0, wx.LEFT, 0)
|
||||
sourceItemShort = "{} {}".format(mod.mutaplasmid.item.name.split(" ")[0], mod.baseItem.name)
|
||||
sourceItemText = wx.StaticText(self, wx.ID_ANY, sourceItemShort)
|
||||
sourceItemText = wx.StaticText(self, wx.ID_ANY, stuff.fullName)
|
||||
font = parent.GetFont()
|
||||
font.SetWeight(wx.BOLD)
|
||||
sourceItemText.SetFont(font)
|
||||
@@ -43,7 +42,7 @@ class ItemMutatorPanel(wx.Panel):
|
||||
mainSizer.Add(headerSizer, 0, wx.ALL | wx.EXPAND, 5)
|
||||
mainSizer.Add(wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL), 0, wx.EXPAND, 0)
|
||||
|
||||
self.mutaList = ItemMutatorList(self, mod)
|
||||
self.mutaList = ItemMutatorList(self, stuff)
|
||||
mainSizer.Add(self.mutaList, 1, wx.EXPAND | wx.ALL, 0)
|
||||
|
||||
mainSizer.Add(wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL), 0, wx.EXPAND, 0)
|
||||
@@ -68,13 +67,13 @@ class ItemMutatorPanel(wx.Panel):
|
||||
|
||||
class ItemMutatorList(wx.ScrolledWindow):
|
||||
|
||||
def __init__(self, parent, mod):
|
||||
def __init__(self, parent, stuff):
|
||||
wx.ScrolledWindow.__init__(self, parent)
|
||||
self.SetScrollRate(0, 15)
|
||||
self.carryingFitID = gui.mainFrame.MainFrame.getInstance().getActiveFit()
|
||||
self.initialMutations = {}
|
||||
self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))
|
||||
self.mod = mod
|
||||
self.stuff = stuff
|
||||
self.timer = None
|
||||
self.isModified = False
|
||||
|
||||
@@ -91,9 +90,8 @@ class ItemMutatorList(wx.ScrolledWindow):
|
||||
('Damage Control', 'duration'): True,
|
||||
('Siege Module', 'siegeLocalLogisticsDurationBonus'): False
|
||||
}
|
||||
|
||||
first = True
|
||||
for m in sorted(mod.mutators.values(), key=lambda x: x.attribute.displayName):
|
||||
for m in sorted(stuff.mutators.values(), key=lambda x: x.attribute.displayName):
|
||||
if m.baseValue == 0:
|
||||
continue
|
||||
if not first:
|
||||
@@ -102,10 +100,10 @@ class ItemMutatorList(wx.ScrolledWindow):
|
||||
|
||||
self.initialMutations[m.attrID] = m.value
|
||||
|
||||
highIsGood = higOverrides.get((mod.item.group.name, m.attribute.name), m.highIsGood)
|
||||
highIsGood = higOverrides.get((stuff.item.group.name, m.attribute.name), m.highIsGood)
|
||||
# Format: [raw value, modifier applied to base raw value, display value]
|
||||
range1 = (m.minValue, m.attribute.unit.SimplifyValue(m.minValue))
|
||||
range2 = (m.maxValue, m.attribute.unit.SimplifyValue(m.maxValue))
|
||||
range1 = (m.minValue, self._simplifyValue(m, m.minValue))
|
||||
range2 = (m.maxValue, self._simplifyValue(m, m.maxValue))
|
||||
|
||||
# minValue/maxValue do not always correspond to min/max, because these are
|
||||
# just base value multiplied by minMod/maxMod, and in case base is negative
|
||||
@@ -148,11 +146,11 @@ class ItemMutatorList(wx.ScrolledWindow):
|
||||
|
||||
headingSizer.Add(displayName, 3, wx.ALL | wx.EXPAND, 0)
|
||||
|
||||
worseVal = ItemParams.FormatValue(*m.attribute.unit.PreformatValue(worseRange[0]), rounding='dec')
|
||||
worseVal = ItemParams.FormatValue(*self._preformatValue(m, worseRange[0]), rounding='dec')
|
||||
worseText = wx.StaticText(self, wx.ID_ANY, worseVal)
|
||||
worseText.SetForegroundColour(badColor)
|
||||
|
||||
betterVal = ItemParams.FormatValue(*m.attribute.unit.PreformatValue(betterRange[0]), rounding='dec')
|
||||
betterVal = ItemParams.FormatValue(*self._preformatValue(m, betterRange[0]), rounding='dec')
|
||||
betterText = wx.StaticText(self, wx.ID_ANY, betterVal)
|
||||
betterText.SetForegroundColour(goodColor)
|
||||
|
||||
@@ -163,23 +161,38 @@ class ItemMutatorList(wx.ScrolledWindow):
|
||||
sizer.Add(headingSizer, 0, wx.ALL | wx.EXPAND, 5)
|
||||
|
||||
slider = AttributeSlider(parent=self,
|
||||
baseValue=m.attribute.unit.SimplifyValue(sliderBaseValue),
|
||||
baseValue=self._simplifyValue(m, sliderBaseValue),
|
||||
minValue=displayMinRange[1],
|
||||
maxValue=displayMaxRange[1],
|
||||
inverse=displayMaxRange is worseRange)
|
||||
slider.SetValue(m.attribute.unit.SimplifyValue(m.value), False)
|
||||
slider.SetValue(self._simplifyValue(m, m.value), False)
|
||||
slider.Bind(EVT_VALUE_CHANGED, self.changeMutatedValue)
|
||||
self.event_mapping[slider] = m
|
||||
sizer.Add(slider, 0, wx.RIGHT | wx.LEFT | wx.EXPAND, 10)
|
||||
|
||||
self.SetSizer(sizer)
|
||||
|
||||
def _simplifyValue(self, mutator, value):
|
||||
if mutator.attribute.unit is None:
|
||||
return value
|
||||
return mutator.attribute.unit.SimplifyValue(value)
|
||||
|
||||
def _complicateValue(self, mutator, value):
|
||||
if mutator.attribute.unit is None:
|
||||
return value
|
||||
return mutator.attribute.unit.ComplicateValue(value)
|
||||
|
||||
def _preformatValue(self, mutator, value):
|
||||
if mutator.attribute.unit is None:
|
||||
return value, None
|
||||
return mutator.attribute.unit.PreformatValue(value)
|
||||
|
||||
def changeMutatedValue(self, evt):
|
||||
if evt.AffectsModifiedFlag:
|
||||
self.isModified = True
|
||||
m = self.event_mapping[evt.Object]
|
||||
value = evt.Value
|
||||
value = m.attribute.unit.ComplicateValue(value)
|
||||
value = self._complicateValue(m, value)
|
||||
sFit = Fit.getInstance()
|
||||
|
||||
sFit.changeMutatedValuePrelim(m, value)
|
||||
@@ -198,7 +211,7 @@ class ItemMutatorList(wx.ScrolledWindow):
|
||||
sFit = Fit.getInstance()
|
||||
for slider, m in self.event_mapping.items():
|
||||
value = sFit.changeMutatedValuePrelim(m, m.baseValue)
|
||||
value = m.attribute.unit.SimplifyValue(value)
|
||||
value = self._simplifyValue(m, value)
|
||||
slider.SetValue(value, affect_modified_flag=False)
|
||||
evt.Skip()
|
||||
|
||||
@@ -208,7 +221,7 @@ class ItemMutatorList(wx.ScrolledWindow):
|
||||
for slider, m in self.event_mapping.items():
|
||||
value = random.uniform(m.minValue, m.maxValue)
|
||||
value = sFit.changeMutatedValuePrelim(m, value)
|
||||
value = m.attribute.unit.SimplifyValue(value)
|
||||
value = self._simplifyValue(m, value)
|
||||
slider.SetValue(value, affect_modified_flag=False)
|
||||
evt.Skip()
|
||||
|
||||
@@ -218,7 +231,7 @@ class ItemMutatorList(wx.ScrolledWindow):
|
||||
for slider, m in self.event_mapping.items():
|
||||
if m.attrID in self.initialMutations:
|
||||
value = sFit.changeMutatedValuePrelim(m, self.initialMutations[m.attrID])
|
||||
value = m.attribute.unit.SimplifyValue(value)
|
||||
value = self._simplifyValue(m, value)
|
||||
slider.SetValue(value, affect_modified_flag=False)
|
||||
evt.Skip()
|
||||
|
||||
@@ -226,25 +239,34 @@ class ItemMutatorList(wx.ScrolledWindow):
|
||||
# Submit mutation changes
|
||||
sFit = Fit.getInstance()
|
||||
fit = sFit.getFit(self.carryingFitID)
|
||||
if self.mod in fit.modules:
|
||||
isCurrentMod = self.stuff in fit.modules
|
||||
isCurrentDrone = self.stuff in fit.drones
|
||||
if isCurrentMod or isCurrentDrone:
|
||||
if self.isModified:
|
||||
currentMutation = {}
|
||||
for slider, m in self.event_mapping.items():
|
||||
# Sliders may have more up-to-date info than mutator in case we changed
|
||||
# value in slider and without confirming it, decided to close window
|
||||
value = slider.GetValue()
|
||||
value = m.attribute.unit.ComplicateValue(value)
|
||||
value = self._complicateValue(m, value)
|
||||
if value != m.value:
|
||||
value = sFit.changeMutatedValuePrelim(m, value)
|
||||
currentMutation[m.attrID] = value
|
||||
else:
|
||||
currentMutation = self.initialMutations
|
||||
mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
mainFrame.getCommandForFit(self.carryingFitID).Submit(cmd.GuiChangeLocalModuleMutationCommand(
|
||||
fitID=self.carryingFitID,
|
||||
position=fit.modules.index(self.mod),
|
||||
mutation=currentMutation,
|
||||
oldMutation=self.initialMutations))
|
||||
if isCurrentMod:
|
||||
mainFrame.getCommandForFit(self.carryingFitID).Submit(cmd.GuiChangeLocalModuleMutationCommand(
|
||||
fitID=self.carryingFitID,
|
||||
position=fit.modules.index(self.stuff),
|
||||
mutation=currentMutation,
|
||||
oldMutation=self.initialMutations))
|
||||
elif isCurrentDrone:
|
||||
mainFrame.getCommandForFit(self.carryingFitID).Submit(cmd.GuiChangeLocalDroneMutationCommand(
|
||||
fitID=self.carryingFitID,
|
||||
position=fit.drones.index(self.stuff),
|
||||
mutation=currentMutation,
|
||||
oldMutation=self.initialMutations))
|
||||
for slider in self.event_mapping:
|
||||
slider.OnWindowClose()
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ class BaseName(ViewColumn):
|
||||
stuff = stuff.item
|
||||
|
||||
if isinstance(stuff, Drone):
|
||||
return "%dx %s" % (stuff.amount, stuff.item.name)
|
||||
return "%dx %s" % (stuff.amount, stuff.fullName)
|
||||
elif isinstance(stuff, Fighter):
|
||||
return "%d/%d %s" % \
|
||||
(stuff.amount, stuff.getModifiedItemAttr("fighterSquadronMaxSize"), stuff.item.name)
|
||||
@@ -117,7 +117,7 @@ class BaseName(ViewColumn):
|
||||
if stuff.isEmpty:
|
||||
return "%s Slot" % FittingSlot(stuff.slot).name.capitalize()
|
||||
else:
|
||||
return stuff.item.customName
|
||||
return stuff.fullName
|
||||
elif isinstance(stuff, Implant):
|
||||
return stuff.item.name
|
||||
elif isinstance(stuff, TargetProfile):
|
||||
|
||||
@@ -5,7 +5,7 @@ from .gui.booster.remove import GuiRemoveBoostersCommand
|
||||
from .gui.booster.sideEffectToggleState import GuiToggleBoosterSideEffectStateCommand
|
||||
from .gui.booster.toggleStates import GuiToggleBoosterStatesCommand
|
||||
from .gui.cargo.add import GuiAddCargoCommand
|
||||
from .gui.cargo.changeAmount import GuiChangeCargoAmountCommand
|
||||
from .gui.cargo.changeAmount import GuiChangeCargosAmountCommand
|
||||
from .gui.cargo.changeMetas import GuiChangeCargoMetasCommand
|
||||
from .gui.cargo.imprt import GuiImportCargosCommand
|
||||
from .gui.cargo.remove import GuiRemoveCargosCommand
|
||||
@@ -26,8 +26,12 @@ from .gui.itemsRebase import GuiRebaseItemsCommand
|
||||
from .gui.localDrone.add import GuiAddLocalDroneCommand
|
||||
from .gui.localDrone.changeAmount import GuiChangeLocalDroneAmountCommand
|
||||
from .gui.localDrone.changeMetas import GuiChangeLocalDroneMetasCommand
|
||||
from .gui.localDrone.changeMutation import GuiChangeLocalDroneMutationCommand
|
||||
from .gui.localDrone.clone import GuiCloneLocalDroneCommand
|
||||
from .gui.localDrone.imprt import GuiImportLocalDronesCommand
|
||||
from .gui.localDrone.mutatedConvert import GuiConvertMutatedLocalDroneCommand
|
||||
from .gui.localDrone.mutatedImport import GuiImportLocalMutatedDroneCommand
|
||||
from .gui.localDrone.mutatedRevert import GuiRevertMutatedLocalDroneCommand
|
||||
from .gui.localDrone.remove import GuiRemoveLocalDronesCommand
|
||||
from .gui.localDrone.stackSplit import GuiSplitLocalDroneStackCommand
|
||||
from .gui.localDrone.stacksMerge import GuiMergeLocalDroneStacksCommand
|
||||
|
||||
51
gui/fitCommands/calc/drone/localChangeMutation.py
Normal file
@@ -0,0 +1,51 @@
|
||||
import wx
|
||||
from logbook import Logger
|
||||
|
||||
from service.fit import Fit
|
||||
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class CalcChangeLocalDroneMutationCommand(wx.Command):
|
||||
|
||||
def __init__(self, fitID, position, mutation, oldMutation=None):
|
||||
wx.Command.__init__(self, True, 'Change Local Drone Mutation')
|
||||
self.fitID = fitID
|
||||
self.position = position
|
||||
self.mutation = mutation
|
||||
self.savedMutation = oldMutation
|
||||
|
||||
def Do(self):
|
||||
pyfalog.debug('Doing changing of local drone mutation at position {} to {} for fit ID {}'.format(
|
||||
self.position, self.mutation, self.fitID))
|
||||
sFit = Fit.getInstance()
|
||||
fit = sFit.getFit(self.fitID)
|
||||
drone = fit.drones[self.position]
|
||||
if not drone.isMutated:
|
||||
return False
|
||||
|
||||
if self.savedMutation is None:
|
||||
self.savedMutation = {}
|
||||
for mutator in drone.mutators.values():
|
||||
self.savedMutation[mutator.attrID] = mutator.value
|
||||
|
||||
if self.mutation == self.savedMutation:
|
||||
return False
|
||||
|
||||
for mutator in drone.mutators.values():
|
||||
if mutator.attrID not in self.mutation:
|
||||
continue
|
||||
if mutator.value != self.mutation[mutator.attrID]:
|
||||
mutator.value = self.mutation[mutator.attrID]
|
||||
|
||||
return True
|
||||
|
||||
def Undo(self):
|
||||
pyfalog.debug('Undoing changing of local drone mutation at position {} to {} for fit ID {}'.format(
|
||||
self.position, self.mutation, self.fitID))
|
||||
cmd = CalcChangeLocalDroneMutationCommand(
|
||||
fitID=self.fitID,
|
||||
position=self.position,
|
||||
mutation=self.savedMutation)
|
||||
return cmd.Do()
|
||||
@@ -10,21 +10,26 @@ from gui.fitCommands.calc.cargo.remove import CalcRemoveCargoCommand
|
||||
from gui.fitCommands.helpers import CargoInfo, InternalCommandHistory
|
||||
|
||||
|
||||
class GuiChangeCargoAmountCommand(wx.Command):
|
||||
class GuiChangeCargosAmountCommand(wx.Command):
|
||||
|
||||
def __init__(self, fitID, itemID, amount):
|
||||
def __init__(self, fitID, itemIDs, amount):
|
||||
wx.Command.__init__(self, True, 'Change Cargo Amount')
|
||||
self.internalHistory = InternalCommandHistory()
|
||||
self.fitID = fitID
|
||||
self.itemID = itemID
|
||||
self.itemIDs = itemIDs
|
||||
self.amount = amount
|
||||
|
||||
def Do(self):
|
||||
results = []
|
||||
if self.amount > 0:
|
||||
cmd = CalcChangeCargoAmountCommand(fitID=self.fitID, cargoInfo=CargoInfo(itemID=self.itemID, amount=self.amount))
|
||||
for itemID in self.itemIDs:
|
||||
cmd = CalcChangeCargoAmountCommand(fitID=self.fitID, cargoInfo=CargoInfo(itemID=itemID, amount=self.amount))
|
||||
results.append(self.internalHistory.submit(cmd))
|
||||
else:
|
||||
cmd = CalcRemoveCargoCommand(fitID=self.fitID, cargoInfo=CargoInfo(itemID=self.itemID, amount=math.inf))
|
||||
success = self.internalHistory.submit(cmd)
|
||||
for itemID in self.itemIDs:
|
||||
cmd = CalcRemoveCargoCommand(fitID=self.fitID, cargoInfo=CargoInfo(itemID=itemID, amount=math.inf))
|
||||
results.append(self.internalHistory.submit(cmd))
|
||||
success = any(results)
|
||||
eos.db.commit()
|
||||
wx.PostEvent(gui.mainFrame.MainFrame.getInstance(), GE.FitChanged(fitIDs=(self.fitID,)))
|
||||
return success
|
||||
|
||||
@@ -14,7 +14,7 @@ class GuiImportCargosCommand(wx.Command):
|
||||
self.internalHistory = InternalCommandHistory()
|
||||
self.fitID = fitID
|
||||
self.cargos = {}
|
||||
for itemID, amount in cargos:
|
||||
for itemID, amount, mutation in cargos:
|
||||
if itemID not in self.cargos:
|
||||
self.cargos[itemID] = 0
|
||||
self.cargos[itemID] += amount
|
||||
|
||||
44
gui/fitCommands/gui/localDrone/changeMutation.py
Normal file
@@ -0,0 +1,44 @@
|
||||
import wx
|
||||
|
||||
import eos.db
|
||||
import gui.mainFrame
|
||||
from gui import globalEvents as GE
|
||||
from gui.fitCommands.calc.drone.localChangeMutation import CalcChangeLocalDroneMutationCommand
|
||||
from gui.fitCommands.helpers import InternalCommandHistory
|
||||
from service.fit import Fit
|
||||
|
||||
|
||||
class GuiChangeLocalDroneMutationCommand(wx.Command):
|
||||
|
||||
def __init__(self, fitID, position, mutation, oldMutation=None):
|
||||
wx.Command.__init__(self, True, 'Change Local Drone Mutation')
|
||||
self.internalHistory = InternalCommandHistory()
|
||||
self.fitID = fitID
|
||||
self.position = position
|
||||
self.mutation = mutation
|
||||
self.oldMutation = oldMutation
|
||||
|
||||
def Do(self):
|
||||
cmd = CalcChangeLocalDroneMutationCommand(
|
||||
fitID=self.fitID,
|
||||
position=self.position,
|
||||
mutation=self.mutation,
|
||||
oldMutation=self.oldMutation)
|
||||
success = self.internalHistory.submit(cmd)
|
||||
eos.db.flush()
|
||||
sFit = Fit.getInstance()
|
||||
sFit.recalc(self.fitID)
|
||||
sFit.fill(self.fitID)
|
||||
eos.db.commit()
|
||||
wx.PostEvent(gui.mainFrame.MainFrame.getInstance(), GE.FitChanged(fitIDs=(self.fitID,)))
|
||||
return success
|
||||
|
||||
def Undo(self):
|
||||
success = self.internalHistory.undoAll()
|
||||
eos.db.flush()
|
||||
sFit = Fit.getInstance()
|
||||
sFit.recalc(self.fitID)
|
||||
sFit.fill(self.fitID)
|
||||
eos.db.commit()
|
||||
wx.PostEvent(gui.mainFrame.MainFrame.getInstance(), GE.FitChanged(fitIDs=(self.fitID,)))
|
||||
return success
|
||||
@@ -14,15 +14,24 @@ class GuiImportLocalDronesCommand(wx.Command):
|
||||
wx.Command.__init__(self, True, 'Import Local Drones')
|
||||
self.internalHistory = InternalCommandHistory()
|
||||
self.fitID = fitID
|
||||
self.drones = drones
|
||||
self.droneInfos = []
|
||||
for itemID, amount, mutation in drones:
|
||||
if mutation:
|
||||
mutaplasmid, attrs = mutation
|
||||
self.droneInfos.append(DroneInfo(
|
||||
itemID=mutaplasmid.resultingItem.ID,
|
||||
amount=amount,
|
||||
amountActive=0,
|
||||
baseItemID=itemID,
|
||||
mutaplasmidID=mutaplasmid.ID,
|
||||
mutations=attrs))
|
||||
else:
|
||||
self.droneInfos.append(DroneInfo(itemID=itemID, amount=amount, amountActive=0))
|
||||
|
||||
def Do(self):
|
||||
results = []
|
||||
for itemID, amount in self.drones:
|
||||
cmd = CalcAddLocalDroneCommand(
|
||||
fitID=self.fitID,
|
||||
droneInfo=DroneInfo(itemID=itemID, amount=amount, amountActive=0),
|
||||
forceNewStack=True)
|
||||
for info in self.droneInfos:
|
||||
cmd = CalcAddLocalDroneCommand(fitID=self.fitID, droneInfo=info, forceNewStack=True)
|
||||
results.append(self.internalHistory.submit(cmd))
|
||||
success = any(results)
|
||||
eos.db.flush()
|
||||
|
||||
65
gui/fitCommands/gui/localDrone/mutatedConvert.py
Normal file
@@ -0,0 +1,65 @@
|
||||
import math
|
||||
|
||||
import wx
|
||||
|
||||
import eos.db
|
||||
import gui.mainFrame
|
||||
from gui import globalEvents as GE
|
||||
from gui.fitCommands.calc.drone.localAdd import CalcAddLocalDroneCommand
|
||||
from gui.fitCommands.calc.drone.localRemove import CalcRemoveLocalDroneCommand
|
||||
from gui.fitCommands.helpers import DroneInfo, InternalCommandHistory
|
||||
from service.fit import Fit
|
||||
|
||||
|
||||
class GuiConvertMutatedLocalDroneCommand(wx.Command):
|
||||
|
||||
def __init__(self, fitID, position, mutaplasmid):
|
||||
wx.Command.__init__(self, True, 'Convert Local Drone to Mutated')
|
||||
self.internalHistory = InternalCommandHistory()
|
||||
self.fitID = fitID
|
||||
self.position = position
|
||||
self.itemID = mutaplasmid.resultingItem.ID
|
||||
self.mutaplasmidID = mutaplasmid.ID
|
||||
|
||||
def Do(self):
|
||||
sFit = Fit.getInstance()
|
||||
fit = sFit.getFit(self.fitID)
|
||||
try:
|
||||
drone = fit.drones[self.position]
|
||||
except IndexError:
|
||||
return False
|
||||
if drone.isMutated:
|
||||
return False
|
||||
info = DroneInfo(
|
||||
amount=drone.amount,
|
||||
amountActive=drone.amountActive,
|
||||
itemID=self.itemID,
|
||||
baseItemID=drone.item.ID,
|
||||
mutaplasmidID=self.mutaplasmidID,
|
||||
mutations={})
|
||||
cmdRemove = CalcRemoveLocalDroneCommand(
|
||||
fitID=self.fitID,
|
||||
position=self.position,
|
||||
amount=math.inf)
|
||||
cmdAdd = CalcAddLocalDroneCommand(
|
||||
fitID=self.fitID,
|
||||
droneInfo=info,
|
||||
forceNewStack=True,
|
||||
ignoreRestrictions=True)
|
||||
success = self.internalHistory.submitBatch(cmdRemove, cmdAdd)
|
||||
eos.db.flush()
|
||||
sFit.recalc(self.fitID)
|
||||
sFit.fill(self.fitID)
|
||||
eos.db.commit()
|
||||
wx.PostEvent(gui.mainFrame.MainFrame.getInstance(), GE.FitChanged(fitIDs=(self.fitID,)))
|
||||
return success
|
||||
|
||||
def Undo(self):
|
||||
success = self.internalHistory.undoAll()
|
||||
eos.db.flush()
|
||||
sFit = Fit.getInstance()
|
||||
sFit.recalc(self.fitID)
|
||||
sFit.fill(self.fitID)
|
||||
eos.db.commit()
|
||||
wx.PostEvent(gui.mainFrame.MainFrame.getInstance(), GE.FitChanged(fitIDs=(self.fitID,)))
|
||||
return success
|
||||
44
gui/fitCommands/gui/localDrone/mutatedImport.py
Normal file
@@ -0,0 +1,44 @@
|
||||
import wx
|
||||
|
||||
import eos.db
|
||||
import gui.mainFrame
|
||||
from gui import globalEvents as GE
|
||||
from gui.fitCommands.calc.drone.localAdd import CalcAddLocalDroneCommand
|
||||
from gui.fitCommands.helpers import InternalCommandHistory, DroneInfo
|
||||
from service.fit import Fit
|
||||
|
||||
|
||||
class GuiImportLocalMutatedDroneCommand(wx.Command):
|
||||
|
||||
def __init__(self, fitID, baseItem, mutaplasmid, mutations, amount):
|
||||
wx.Command.__init__(self, True, 'Import Local Mutated Drone')
|
||||
self.internalHistory = InternalCommandHistory()
|
||||
self.fitID = fitID
|
||||
self.newDroneInfo = DroneInfo(
|
||||
amount=amount,
|
||||
amountActive=0,
|
||||
itemID=mutaplasmid.resultingItem.ID,
|
||||
baseItemID=baseItem.ID,
|
||||
mutaplasmidID=mutaplasmid.ID,
|
||||
mutations=mutations)
|
||||
|
||||
def Do(self):
|
||||
cmd = CalcAddLocalDroneCommand(fitID=self.fitID, droneInfo=self.newDroneInfo, forceNewStack=True)
|
||||
success = self.internalHistory.submit(cmd)
|
||||
eos.db.flush()
|
||||
sFit = Fit.getInstance()
|
||||
sFit.recalc(self.fitID)
|
||||
sFit.fill(self.fitID)
|
||||
eos.db.commit()
|
||||
wx.PostEvent(gui.mainFrame.MainFrame.getInstance(), GE.FitChanged(fitIDs=(self.fitID,)))
|
||||
return success
|
||||
|
||||
def Undo(self):
|
||||
success = self.internalHistory.undoAll()
|
||||
eos.db.flush()
|
||||
sFit = Fit.getInstance()
|
||||
sFit.recalc(self.fitID)
|
||||
sFit.fill(self.fitID)
|
||||
eos.db.commit()
|
||||
wx.PostEvent(gui.mainFrame.MainFrame.getInstance(), GE.FitChanged(fitIDs=(self.fitID,)))
|
||||
return success
|
||||
60
gui/fitCommands/gui/localDrone/mutatedRevert.py
Normal file
@@ -0,0 +1,60 @@
|
||||
import math
|
||||
|
||||
import wx
|
||||
|
||||
import eos.db
|
||||
import gui.mainFrame
|
||||
from gui import globalEvents as GE
|
||||
from gui.fitCommands.calc.drone.localAdd import CalcAddLocalDroneCommand
|
||||
from gui.fitCommands.calc.drone.localRemove import CalcRemoveLocalDroneCommand
|
||||
from gui.fitCommands.helpers import DroneInfo, InternalCommandHistory
|
||||
from service.fit import Fit
|
||||
|
||||
|
||||
class GuiRevertMutatedLocalDroneCommand(wx.Command):
|
||||
|
||||
def __init__(self, fitID, position):
|
||||
wx.Command.__init__(self, True, 'Revert Local Drone from Mutated')
|
||||
self.internalHistory = InternalCommandHistory()
|
||||
self.fitID = fitID
|
||||
self.position = position
|
||||
|
||||
def Do(self):
|
||||
sFit = Fit.getInstance()
|
||||
fit = sFit.getFit(self.fitID)
|
||||
try:
|
||||
drone = fit.drones[self.position]
|
||||
except IndexError:
|
||||
return False
|
||||
if not drone.isMutated:
|
||||
return False
|
||||
info = DroneInfo(
|
||||
amount=drone.amount,
|
||||
amountActive=drone.amountActive,
|
||||
itemID=drone.baseItemID)
|
||||
cmdRemove = CalcRemoveLocalDroneCommand(
|
||||
fitID=self.fitID,
|
||||
position=self.position,
|
||||
amount=math.inf)
|
||||
cmdAdd = CalcAddLocalDroneCommand(
|
||||
fitID=self.fitID,
|
||||
droneInfo=info,
|
||||
forceNewStack=True,
|
||||
ignoreRestrictions=True)
|
||||
success = self.internalHistory.submitBatch(cmdRemove, cmdAdd)
|
||||
eos.db.flush()
|
||||
sFit.recalc(self.fitID)
|
||||
sFit.fill(self.fitID)
|
||||
eos.db.commit()
|
||||
wx.PostEvent(gui.mainFrame.MainFrame.getInstance(), GE.FitChanged(fitIDs=(self.fitID,)))
|
||||
return success
|
||||
|
||||
def Undo(self):
|
||||
success = self.internalHistory.undoAll()
|
||||
eos.db.flush()
|
||||
sFit = Fit.getInstance()
|
||||
sFit.recalc(self.fitID)
|
||||
sFit.fill(self.fitID)
|
||||
eos.db.commit()
|
||||
wx.PostEvent(gui.mainFrame.MainFrame.getInstance(), GE.FitChanged(fitIDs=(self.fitID,)))
|
||||
return success
|
||||
@@ -14,7 +14,7 @@ class GuiImportLocalFightersCommand(wx.Command):
|
||||
wx.Command.__init__(self, True, 'Import Local Fighters')
|
||||
self.internalHistory = InternalCommandHistory()
|
||||
self.fitID = fitID
|
||||
self.fighters = fighters
|
||||
self.fighters = [(i, a) for i, a, m in fighters]
|
||||
|
||||
def Do(self):
|
||||
results = []
|
||||
|
||||
@@ -21,7 +21,10 @@ class GuiConvertMutatedLocalModuleCommand(wx.Command):
|
||||
def Do(self):
|
||||
sFit = Fit.getInstance()
|
||||
fit = sFit.getFit(self.fitID)
|
||||
mod = fit.modules[self.position]
|
||||
try:
|
||||
mod = fit.modules[self.position]
|
||||
except IndexError:
|
||||
return False
|
||||
if mod.isEmpty:
|
||||
return False
|
||||
if mod.isMutated:
|
||||
|
||||
@@ -19,7 +19,10 @@ class GuiRevertMutatedLocalModuleCommand(wx.Command):
|
||||
def Do(self):
|
||||
sFit = Fit.getInstance()
|
||||
fit = sFit.getFit(self.fitID)
|
||||
mod = fit.modules[self.position]
|
||||
try:
|
||||
mod = fit.modules[self.position]
|
||||
except IndexError:
|
||||
return False
|
||||
if mod.isEmpty:
|
||||
return False
|
||||
if not mod.isMutated:
|
||||
|
||||
@@ -158,8 +158,11 @@ class ModuleInfo:
|
||||
|
||||
class DroneInfo:
|
||||
|
||||
def __init__(self, itemID, amount, amountActive):
|
||||
def __init__(self, amount, amountActive, itemID, baseItemID=None, mutaplasmidID=None, mutations=None):
|
||||
self.itemID = itemID
|
||||
self.baseItemID = baseItemID
|
||||
self.mutaplasmidID = mutaplasmidID
|
||||
self.mutations = mutations
|
||||
self.amount = amount
|
||||
self.amountActive = amountActive
|
||||
|
||||
@@ -170,22 +173,40 @@ class DroneInfo:
|
||||
info = cls(
|
||||
itemID=drone.itemID,
|
||||
amount=drone.amount,
|
||||
amountActive=drone.amountActive)
|
||||
amountActive=drone.amountActive,
|
||||
baseItemID=drone.baseItemID,
|
||||
mutaplasmidID=drone.mutaplasmidID,
|
||||
mutations={m.attrID: m.value for m in drone.mutators.values()})
|
||||
return info
|
||||
|
||||
def toDrone(self):
|
||||
item = Market.getInstance().getItem(self.itemID, eager=('attributes', 'group.category'))
|
||||
mkt = Market.getInstance()
|
||||
item = mkt.getItem(self.itemID, eager=('attributes', 'group.category'))
|
||||
if self.baseItemID and self.mutaplasmidID:
|
||||
baseItem = mkt.getItem(self.baseItemID, eager=('attributes', 'group.category'))
|
||||
mutaplasmid = eos.db.getDynamicItem(self.mutaplasmidID)
|
||||
else:
|
||||
baseItem = None
|
||||
mutaplasmid = None
|
||||
try:
|
||||
drone = Drone(item)
|
||||
drone = Drone(item, baseItem=baseItem, mutaplasmid=mutaplasmid)
|
||||
except ValueError:
|
||||
pyfalog.warning('Invalid item: {}'.format(self.itemID))
|
||||
return None
|
||||
|
||||
if self.mutations is not None:
|
||||
for attrID, mutator in drone.mutators.items():
|
||||
if attrID in self.mutations:
|
||||
mutator.value = self.mutations[attrID]
|
||||
|
||||
drone.amount = self.amount
|
||||
drone.amountActive = self.amountActive
|
||||
return drone
|
||||
|
||||
def __repr__(self):
|
||||
return makeReprStr(self, ['itemID', 'amount', 'amountActive'])
|
||||
return makeReprStr(self, [
|
||||
'itemID', 'amount', 'amountActive',
|
||||
'baseItemID', 'mutaplasmidID', 'mutations'])
|
||||
|
||||
|
||||
class FighterInfo:
|
||||
|
||||
@@ -22,6 +22,7 @@ import wx
|
||||
|
||||
import config
|
||||
import gui.mainFrame
|
||||
from eos.saveddata.drone import Drone
|
||||
from eos.saveddata.module import Module
|
||||
from gui.auxWindow import AuxiliaryFrame
|
||||
from gui.bitmap_loader import BitmapLoader
|
||||
@@ -165,7 +166,7 @@ class ItemStatsContainer(wx.Panel):
|
||||
self.traits = ItemTraits(self.nbContainer, stuff, item)
|
||||
self.nbContainer.AddPage(self.traits, _t("Traits"))
|
||||
|
||||
if isinstance(stuff, Module) and stuff.isMutated:
|
||||
if isinstance(stuff, (Module, Drone)) and stuff.isMutated:
|
||||
self.mutator = ItemMutatorPanel(self.nbContainer, stuff)
|
||||
self.nbContainer.AddPage(self.mutator, _t("Mutations"))
|
||||
|
||||
|
||||
@@ -762,28 +762,33 @@ class MainFrame(wx.Frame):
|
||||
if importType == "FittingItem":
|
||||
baseItem, mutaplasmidItem, mutations = importData[0]
|
||||
if mutaplasmidItem:
|
||||
self.command.Submit(cmd.GuiImportLocalMutatedModuleCommand(activeFit, baseItem, mutaplasmidItem, mutations))
|
||||
if baseItem.isDrone:
|
||||
self.command.Submit(cmd.GuiImportLocalMutatedDroneCommand(
|
||||
activeFit, baseItem, mutaplasmidItem, mutations, amount=1))
|
||||
else:
|
||||
self.command.Submit(cmd.GuiImportLocalMutatedModuleCommand(
|
||||
activeFit, baseItem, mutaplasmidItem, mutations))
|
||||
else:
|
||||
self.command.Submit(cmd.GuiAddLocalModuleCommand(activeFit, baseItem.ID))
|
||||
return
|
||||
if importType == "AdditionsDrones":
|
||||
if self.command.Submit(cmd.GuiImportLocalDronesCommand(activeFit, [(i.ID, a) for i, a in importData[0]])):
|
||||
if self.command.Submit(cmd.GuiImportLocalDronesCommand(activeFit, [(i.ID, a, m) for i, a, m in importData[0]])):
|
||||
self.additionsPane.select("Drones")
|
||||
return
|
||||
if importType == "AdditionsFighters":
|
||||
if self.command.Submit(cmd.GuiImportLocalFightersCommand(activeFit, [(i.ID, a) for i, a in importData[0]])):
|
||||
if self.command.Submit(cmd.GuiImportLocalFightersCommand(activeFit, [(i.ID, a, m) for i, a, m in importData[0]])):
|
||||
self.additionsPane.select("Fighters")
|
||||
return
|
||||
if importType == "AdditionsImplants":
|
||||
if self.command.Submit(cmd.GuiImportImplantsCommand(activeFit, [(i.ID, a) for i, a in importData[0]])):
|
||||
if self.command.Submit(cmd.GuiImportImplantsCommand(activeFit, [(i.ID, a, m) for i, a, m in importData[0]])):
|
||||
self.additionsPane.select("Implants")
|
||||
return
|
||||
if importType == "AdditionsBoosters":
|
||||
if self.command.Submit(cmd.GuiImportBoostersCommand(activeFit, [(i.ID, a) for i, a in importData[0]])):
|
||||
if self.command.Submit(cmd.GuiImportBoostersCommand(activeFit, [(i.ID, a, m) for i, a, m in importData[0]])):
|
||||
self.additionsPane.select("Boosters")
|
||||
return
|
||||
if importType == "AdditionsCargo":
|
||||
if self.command.Submit(cmd.GuiImportCargosCommand(activeFit, [(i.ID, a) for i, a in importData[0]])):
|
||||
if self.command.Submit(cmd.GuiImportCargosCommand(activeFit, [(i.ID, a, m) for i, a, m in importData[0]])):
|
||||
self.additionsPane.select("Cargo")
|
||||
return
|
||||
except (KeyboardInterrupt, SystemExit):
|
||||
|
||||
|
Before Width: | Height: | Size: 683 B |
|
Before Width: | Height: | Size: 1.7 KiB |
BIN
imgs/icons/24776@1x.png
Normal file
|
After Width: | Height: | Size: 761 B |
BIN
imgs/icons/24776@2x.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
imgs/icons/24777@1x.png
Normal file
|
After Width: | Height: | Size: 848 B |
BIN
imgs/icons/24777@2x.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
imgs/icons/24778@1x.png
Normal file
|
After Width: | Height: | Size: 763 B |
BIN
imgs/icons/24778@2x.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
imgs/icons/24779@1x.png
Normal file
|
After Width: | Height: | Size: 856 B |
BIN
imgs/icons/24779@2x.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
imgs/icons/24780@1x.png
Normal file
|
After Width: | Height: | Size: 759 B |
BIN
imgs/icons/24780@2x.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
imgs/icons/24781@1x.png
Normal file
|
After Width: | Height: | Size: 822 B |
BIN
imgs/icons/24781@2x.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
imgs/icons/24782@1x.png
Normal file
|
After Width: | Height: | Size: 742 B |
BIN
imgs/icons/24782@2x.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
imgs/icons/24783@1x.png
Normal file
|
After Width: | Height: | Size: 812 B |
BIN
imgs/icons/24783@2x.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
imgs/icons/24792@1x.png
Normal file
|
After Width: | Height: | Size: 820 B |
BIN
imgs/icons/24792@2x.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
imgs/icons/24793@1x.png
Normal file
|
After Width: | Height: | Size: 831 B |
BIN
imgs/icons/24793@2x.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
imgs/icons/24794@1x.png
Normal file
|
After Width: | Height: | Size: 821 B |
BIN
imgs/icons/24794@2x.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
imgs/icons/24795@1x.png
Normal file
|
After Width: | Height: | Size: 839 B |
BIN
imgs/icons/24795@2x.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
imgs/icons/24796@1x.png
Normal file
|
After Width: | Height: | Size: 863 B |
BIN
imgs/icons/24796@2x.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
imgs/icons/24797@1x.png
Normal file
|
After Width: | Height: | Size: 868 B |
BIN
imgs/icons/24797@2x.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
imgs/icons/24798@1x.png
Normal file
|
After Width: | Height: | Size: 883 B |
BIN
imgs/icons/24798@2x.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
imgs/icons/24799@1x.png
Normal file
|
After Width: | Height: | Size: 677 B |
BIN
imgs/icons/24799@2x.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
imgs/icons/24800@1x.png
Normal file
|
After Width: | Height: | Size: 676 B |
BIN
imgs/icons/24800@2x.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
imgs/icons/24801@1x.png
Normal file
|
After Width: | Height: | Size: 677 B |
BIN
imgs/icons/24801@2x.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
imgs/icons/24802@1x.png
Normal file
|
After Width: | Height: | Size: 678 B |
BIN
imgs/icons/24802@2x.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
imgs/icons/24803@1x.png
Normal file
|
After Width: | Height: | Size: 672 B |
BIN
imgs/icons/24803@2x.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
imgs/icons/24804@1x.png
Normal file
|
After Width: | Height: | Size: 673 B |
BIN
imgs/icons/24804@2x.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
imgs/icons/24805@1x.png
Normal file
|
After Width: | Height: | Size: 785 B |
BIN
imgs/icons/24805@2x.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
imgs/icons/24806@1x.png
Normal file
|
After Width: | Height: | Size: 791 B |
BIN
imgs/icons/24806@2x.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
imgs/icons/24807@1x.png
Normal file
|
After Width: | Height: | Size: 787 B |
BIN
imgs/icons/24807@2x.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
imgs/icons/24808@1x.png
Normal file
|
After Width: | Height: | Size: 811 B |
BIN
imgs/icons/24808@2x.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
imgs/icons/24815@1x.png
Normal file
|
After Width: | Height: | Size: 875 B |
BIN
imgs/icons/24815@2x.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
imgs/icons/24816@1x.png
Normal file
|
After Width: | Height: | Size: 863 B |
BIN
imgs/icons/24816@2x.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
imgs/icons/24817@1x.png
Normal file
|
After Width: | Height: | Size: 865 B |
BIN
imgs/icons/24817@2x.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
imgs/icons/24818@1x.png
Normal file
|
After Width: | Height: | Size: 831 B |
BIN
imgs/icons/24818@2x.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
imgs/icons/24819@1x.png
Normal file
|
After Width: | Height: | Size: 775 B |