Compare commits
45 Commits
v2.17.0
...
v2.19.1dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
098b088da6 | ||
|
|
14d62f31e1 | ||
|
|
e7b1f55d08 | ||
|
|
8f501896a1 | ||
|
|
befcb9b874 | ||
|
|
c70afa9a4c | ||
|
|
029c7dd4c2 | ||
|
|
1f83dba1ac | ||
|
|
6eae3405fd | ||
|
|
c0e1d9e4de | ||
|
|
7c0bd7aa88 | ||
|
|
394583584c | ||
|
|
4112e2aa6b | ||
|
|
aa19e0da72 | ||
|
|
bba9be1598 | ||
|
|
17998916b4 | ||
|
|
543089bcd9 | ||
|
|
7f35c78a65 | ||
|
|
b25798dd83 | ||
|
|
744b9ff78a | ||
|
|
8dc1457ebb | ||
|
|
982ad54fab | ||
|
|
912192cd7d | ||
|
|
74cd6d48da | ||
|
|
3467a7fe3f | ||
|
|
eb269a05ed | ||
|
|
c63cf4b3b0 | ||
|
|
11ed94454d | ||
|
|
8df07645da | ||
|
|
5666fdd250 | ||
|
|
0b55ae40fc | ||
|
|
3726e84697 | ||
|
|
a0c4341102 | ||
|
|
cd6b1038e8 | ||
|
|
10583fd506 | ||
|
|
713694be56 | ||
|
|
f50293cf77 | ||
|
|
7c88fa477f | ||
|
|
f8df540fad | ||
|
|
61a01805cc | ||
|
|
a93915cf04 | ||
|
|
0f74c97fbf | ||
|
|
29713b69dc | ||
|
|
cc3c2cb9c8 | ||
|
|
b36a3959da |
@@ -3,7 +3,7 @@ clone_depth: 400
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- PYTHON: "C:\\Python38-x64"
|
||||
- PYTHON: "C:\\Python37-x64"
|
||||
# Should be enabled only for build process debugging
|
||||
# init:
|
||||
# - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
@@ -40,6 +40,8 @@ install:
|
||||
# pip will build them from source using the MSVC compiler matching the
|
||||
# target Python version and architecture
|
||||
- ps: echo("Install pip requirements:")
|
||||
# This one is needed to build wxpython 4.0.6 on windows
|
||||
- cmd: "python -m pip install pathlib2"
|
||||
- cmd: "python -m pip install -r requirements.txt"
|
||||
- cmd: "python -m pip install PyInstaller==3.6"
|
||||
|
||||
@@ -63,7 +65,7 @@ build_script:
|
||||
|
||||
after_build:
|
||||
- ps: "ls \"./\""
|
||||
- ps: 7z a "pyfa-$env:PYFA_VERSION-win.zip" -r "$env:PYFA_DIST_DIR\pyfa\*.*"
|
||||
- ps: 7z a "pyfa-$env:PYFA_VERSION-win.zip" -r "$env:PYFA_DIST_DIR\pyfa\*"
|
||||
|
||||
test_script:
|
||||
# Ha... we're just building
|
||||
|
||||
34
db_update.py
@@ -23,6 +23,7 @@ import functools
|
||||
import itertools
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sqlite3
|
||||
import sys
|
||||
|
||||
@@ -458,6 +459,38 @@ def update_db():
|
||||
if itemReplacements is not None:
|
||||
item.replacements = ','.join('{}'.format(tid) for tid in sorted(itemReplacements))
|
||||
|
||||
def processImplantSets(eveTypesData):
|
||||
print('composing implant sets')
|
||||
# Includes only implants which can be considered part of sets, not all implants
|
||||
implant_groups = (300, 1730)
|
||||
specials = {'Genolution': ('Genolution Core Augmentation', r'CA-\d+')}
|
||||
implantSets = {}
|
||||
for row in eveTypesData:
|
||||
if not row.get('published'):
|
||||
continue
|
||||
if row.get('groupID') not in implant_groups:
|
||||
continue
|
||||
typeName = row.get('typeName', '')
|
||||
# Regular sets matching
|
||||
m = re.match('(?P<grade>(High|Mid|Low)-grade) (?P<set>\w+) (?P<implant>(Alpha|Beta|Gamma|Delta|Epsilon|Omega))', typeName)
|
||||
if m:
|
||||
implantSets.setdefault((m.group('grade'), m.group('set')), set()).add(row['typeID'])
|
||||
# Special set matching
|
||||
for setHandle, (setName, implantPattern) in specials.items():
|
||||
pattern = '(?P<set>{}) (?P<implant>{})'.format(setName, implantPattern)
|
||||
m = re.match(pattern, typeName)
|
||||
if m:
|
||||
implantSets.setdefault((None, setHandle), set()).add(row['typeID'])
|
||||
break
|
||||
data = []
|
||||
for (gradeName, setName), implants in implantSets.items():
|
||||
if len(implants) < 2:
|
||||
continue
|
||||
implants = ','.join('{}'.format(tid) for tid in sorted(implants))
|
||||
row = {'setName': setName, 'gradeName': gradeName, 'implants': implants}
|
||||
data.append(row)
|
||||
_addRows(data, eos.gamedata.ImplantSet)
|
||||
|
||||
eveTypesData = processEveTypes()
|
||||
eveGroupsData = processEveGroups()
|
||||
processEveCategories()
|
||||
@@ -476,6 +509,7 @@ def update_db():
|
||||
eos.db.gamedata_session.flush()
|
||||
processReqSkills(eveTypesData)
|
||||
processReplacements(eveTypesData, eveGroupsData, dogmaTypeAttributesData, dogmaTypeEffectsData)
|
||||
processImplantSets(eveTypesData)
|
||||
|
||||
# Add schema version to prevent further updates
|
||||
metadata_schema_version = eos.gamedata.MetaData()
|
||||
|
||||
@@ -30,7 +30,8 @@ added_files = [
|
||||
|
||||
import_these = [
|
||||
'numpy.core._dtype_ctypes', # https://github.com/pyinstaller/pyinstaller/issues/3982
|
||||
'sqlalchemy.ext.baked' # windows build doesn't launch without if when using sqlalchemy 1.3.x
|
||||
'sqlalchemy.ext.baked', # windows build doesn't launch without if when using sqlalchemy 1.3.x
|
||||
'pkg_resources.py2_warn' # issue 2156
|
||||
]
|
||||
|
||||
icon = os.path.join(os.getcwd(), "dist_assets", "mac", "pyfa.icns")
|
||||
|
||||
@@ -29,7 +29,8 @@ added_files = [
|
||||
|
||||
import_these = [
|
||||
'numpy.core._dtype_ctypes', # https://github.com/pyinstaller/pyinstaller/issues/3982
|
||||
'sqlalchemy.ext.baked' # windows build doesn't launch without if when using sqlalchemy 1.3.x
|
||||
'sqlalchemy.ext.baked', # windows build doesn't launch without if when using sqlalchemy 1.3.x
|
||||
'pkg_resources.py2_warn' # issue 2156
|
||||
]
|
||||
|
||||
# Walk directories that do dynamic importing
|
||||
|
||||
@@ -84,7 +84,7 @@ sd_lock = threading.RLock()
|
||||
pyfalog.debug('Importing gamedata DB scheme')
|
||||
# Import all the definitions for all our database stuff
|
||||
# noinspection PyPep8
|
||||
from eos.db.gamedata import alphaClones, attribute, category, effect, group, item, marketGroup, metaData, metaGroup, queries, traits, unit, dynamicAttributes
|
||||
from eos.db.gamedata import alphaClones, attribute, category, effect, group, item, marketGroup, metaData, metaGroup, queries, traits, unit, dynamicAttributes, implantSet
|
||||
pyfalog.debug('Importing saveddata DB scheme')
|
||||
# noinspection PyPep8
|
||||
from eos.db.saveddata import booster, cargo, character, damagePattern, databaseRepair, drone, fighter, fit, implant, implantSet, \
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
__all__ = ["attribute", "category", "effect", "group", "metaData", "dynamicAttributes",
|
||||
"item", "marketGroup", "metaGroup", "unit", "alphaClones"]
|
||||
"item", "marketGroup", "metaGroup", "unit", "alphaClones", "implantSet"]
|
||||
|
||||
33
eos/db/gamedata/implantSet.py
Normal file
@@ -0,0 +1,33 @@
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
#
|
||||
# eos is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# eos is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Column, String, Integer, Table
|
||||
from sqlalchemy.orm import mapper, synonym
|
||||
|
||||
from eos.db import gamedata_meta
|
||||
from eos.gamedata import ImplantSet
|
||||
|
||||
implant_set_table = Table("implantsets", gamedata_meta,
|
||||
Column("setID", Integer, primary_key=True),
|
||||
Column("setName", String),
|
||||
Column("gradeName", String),
|
||||
Column("implants", String))
|
||||
|
||||
mapper(ImplantSet, implant_set_table,
|
||||
properties={"ID": synonym("setID")})
|
||||
@@ -26,7 +26,7 @@ from eos.db import gamedata_session
|
||||
from eos.db.gamedata.item import items_table
|
||||
from eos.db.gamedata.group import groups_table
|
||||
from eos.db.util import processEager, processWhere
|
||||
from eos.gamedata import AlphaClone, Attribute, AttributeInfo, Category, DynamicItem, Group, Item, MarketGroup, MetaData, MetaGroup
|
||||
from eos.gamedata import AlphaClone, Attribute, AttributeInfo, Category, DynamicItem, Group, Item, MarketGroup, MetaData, MetaGroup, ImplantSet
|
||||
|
||||
cache = {}
|
||||
configVal = getattr(eos.config, "gamedataCache", None)
|
||||
@@ -424,3 +424,9 @@ def getDynamicItem(itemID, eager=None):
|
||||
except exc.NoResultFound:
|
||||
result = None
|
||||
return result
|
||||
|
||||
|
||||
@cachedQuery(1, "lookfor")
|
||||
def getAllImplantSets():
|
||||
implantSets = gamedata_session.query(ImplantSet).all()
|
||||
return implantSets
|
||||
|
||||
@@ -6,16 +6,16 @@ Allow use of floats in damage pattern values
|
||||
|
||||
tmpTable = """
|
||||
CREATE TABLE "damagePatternsTemp" (
|
||||
"ID" INTEGER NOT NULL,
|
||||
"name" VARCHAR,
|
||||
"emAmount" FLOAT,
|
||||
"thermalAmount" FLOAT,
|
||||
"kineticAmount" FLOAT,
|
||||
"explosiveAmount" FLOAT,
|
||||
"ownerID" INTEGER,
|
||||
"created" DATETIME,
|
||||
"modified" DATETIME,
|
||||
PRIMARY KEY ("ID"),
|
||||
"ID" INTEGER NOT NULL,
|
||||
"name" VARCHAR,
|
||||
"emAmount" FLOAT,
|
||||
"thermalAmount" FLOAT,
|
||||
"kineticAmount" FLOAT,
|
||||
"explosiveAmount" FLOAT,
|
||||
"ownerID" INTEGER,
|
||||
"created" DATETIME,
|
||||
"modified" DATETIME,
|
||||
PRIMARY KEY ("ID"),
|
||||
FOREIGN KEY("ownerID") REFERENCES users ("ID")
|
||||
)
|
||||
"""
|
||||
|
||||
44
eos/db/migrations/upgrade37.py
Normal file
@@ -0,0 +1,44 @@
|
||||
"""
|
||||
Migration 37
|
||||
|
||||
- Capacitor Booster tiericide
|
||||
"""
|
||||
|
||||
CONVERSIONS = {
|
||||
4959: ( # 'Seed' Micro Capacitor Booster I
|
||||
4957, # Micro Brief Capacitor Overcharge I
|
||||
4961, # Micro Tapered Capacitor Infusion I
|
||||
4955, # Micro F-RX Prototype Capacitor Boost
|
||||
3556, # Micro Capacitor Booster I
|
||||
3558, # Micro Capacitor Booster II
|
||||
15774, # Ammatar Navy Micro Capacitor Booster
|
||||
14180, # Dark Blood Micro Capacitor Booster
|
||||
14182, # True Sansha Micro Capacitor Booster
|
||||
15782, # Imperial Navy Micro Capacitor Booster
|
||||
),
|
||||
5011: ( # Small F-RX Compact Capacitor Booster
|
||||
5009, # Small Brief Capacitor Overcharge I
|
||||
5013, # Small Tapered Capacitor Infusion I
|
||||
5007, # Small F-RX Prototype Capacitor Boost
|
||||
),
|
||||
4833: ( # Medium F-RX Compact Capacitor Booster
|
||||
4831, # Medium Brief Capacitor Overcharge I
|
||||
4835, # Medium Tapered Capacitor Infusion I
|
||||
4829, # Medium F-RX Prototype Capacitor Boost
|
||||
),
|
||||
5051: ( # Heavy F-RX Compact Capacitor Booster
|
||||
5049, # Heavy Brief Capacitor Overcharge I
|
||||
5053, # Heavy Tapered Capacitor Infusion I
|
||||
5047, # Heavy F-RX Prototype Capacitor Boost
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
# Convert modules
|
||||
for replacement_item, list in CONVERSIONS.items():
|
||||
for retired_item in list:
|
||||
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
|
||||
(replacement_item, retired_item))
|
||||
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?',
|
||||
(replacement_item, retired_item))
|
||||
269
eos/effects.py
@@ -218,7 +218,7 @@ class Effect48(BaseEffect):
|
||||
powerBooster
|
||||
|
||||
Used by:
|
||||
Modules from group: Capacitor Booster (59 of 59)
|
||||
Modules from group: Capacitor Booster (41 of 41)
|
||||
"""
|
||||
|
||||
type = 'active'
|
||||
@@ -989,7 +989,7 @@ class Effect290(BaseEffect):
|
||||
sharpshooterRangeSkillBonusPostPercentMaxRangeLocationShipModulesRequiringGunnery
|
||||
|
||||
Used by:
|
||||
Implants named like: Frentix Booster (4 of 4)
|
||||
Implants named like: Frentix Booster (9 of 9)
|
||||
Implants named like: Zainou 'Deadeye' Sharpshooter ST (6 of 6)
|
||||
Skill: Sharpshooter
|
||||
"""
|
||||
@@ -1008,7 +1008,7 @@ class Effect298(BaseEffect):
|
||||
surgicalStrikeFalloffBonusPostPercentFalloffLocationShipModulesRequiringGunnery
|
||||
|
||||
Used by:
|
||||
Implants named like: Sooth Sayer Booster (4 of 4)
|
||||
Implants named like: Sooth Sayer Booster (9 of 9)
|
||||
Implants named like: Zainou 'Deadeye' Trajectory Analysis TA (6 of 6)
|
||||
Skill: Trajectory Analysis
|
||||
"""
|
||||
@@ -1742,7 +1742,7 @@ class Effect596(BaseEffect):
|
||||
ammoInfluenceRange
|
||||
|
||||
Used by:
|
||||
Items from category: Charge (590 of 954)
|
||||
Items from category: Charge (590 of 955)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -1757,7 +1757,7 @@ class Effect598(BaseEffect):
|
||||
ammoSpeedMultiplier
|
||||
|
||||
Used by:
|
||||
Charges from group: Festival Charges (28 of 28)
|
||||
Charges from group: Festival Charges (29 of 29)
|
||||
Charges from group: Interdiction Probe (2 of 2)
|
||||
Charges from group: Structure Festival Charges (2 of 2)
|
||||
Special Edition Assetss from group: Festival Charges Expired (4 of 4)
|
||||
@@ -2328,7 +2328,7 @@ class Effect804(BaseEffect):
|
||||
ammoInfluenceCapNeed
|
||||
|
||||
Used by:
|
||||
Items from category: Charge (496 of 954)
|
||||
Items from category: Charge (496 of 955)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -3694,7 +3694,7 @@ class Effect1185(BaseEffect):
|
||||
structureStealthEmitterArraySigDecrease
|
||||
|
||||
Used by:
|
||||
Implants named like: X Instinct Booster (4 of 4)
|
||||
Implants named like: X Instinct Booster (9 of 9)
|
||||
Implants named like: grade Halo (15 of 18)
|
||||
"""
|
||||
|
||||
@@ -5977,6 +5977,7 @@ class Effect2019(BaseEffect):
|
||||
repairDroneShieldBonusBonus
|
||||
|
||||
Used by:
|
||||
Implants named like: Black Market 'Valdimar' Repair Drone Operation DR (3 of 3)
|
||||
Modules named like: Drone Repair Augmentor (8 of 8)
|
||||
Skill: Repair Drone Operation
|
||||
"""
|
||||
@@ -5986,7 +5987,7 @@ class Effect2019(BaseEffect):
|
||||
@staticmethod
|
||||
def handler(fit, container, context, projectionRange, **kwargs):
|
||||
level = container.level if 'skill' in context else 1
|
||||
penalized = False if 'skill' in context else True
|
||||
penalized = False if 'skill' in context or 'implant' in context else True
|
||||
fit.drones.filteredItemBoost(lambda drone: drone.item.group.name == 'Logistic Drone',
|
||||
'shieldBonus', container.getModifiedItemAttr('damageHP') * level,
|
||||
stackingPenalties=penalized, **kwargs)
|
||||
@@ -5997,6 +5998,7 @@ class Effect2020(BaseEffect):
|
||||
repairDroneArmorDamageAmountBonus
|
||||
|
||||
Used by:
|
||||
Implants named like: Black Market 'Valdimar' Repair Drone Operation DR (3 of 3)
|
||||
Modules named like: Drone Repair Augmentor (8 of 8)
|
||||
Skill: Repair Drone Operation
|
||||
"""
|
||||
@@ -6006,7 +6008,7 @@ class Effect2020(BaseEffect):
|
||||
@staticmethod
|
||||
def handler(fit, container, context, projectionRange, **kwargs):
|
||||
level = container.level if 'skill' in context else 1
|
||||
penalized = False if 'skill' in context else True
|
||||
penalized = False if 'skill' in context or 'implant' in context else True
|
||||
fit.drones.filteredItemBoost(lambda drone: drone.item.group.name == 'Logistic Drone',
|
||||
'armorDamageAmount', container.getModifiedItemAttr('damageHP') * level,
|
||||
stackingPenalties=penalized, **kwargs)
|
||||
@@ -6964,7 +6966,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: Mindflood Booster (9 of 9)
|
||||
Modules named like: Semiconductor Memory Cell (8 of 8)
|
||||
Implant: Antipharmakon Aeolis
|
||||
Implant: Genolution Core Augmentation CA-1
|
||||
@@ -7148,8 +7150,7 @@ class Effect2491(BaseEffect):
|
||||
def handler(fit, container, context, projectionRange, **kwargs):
|
||||
level = container.level if 'skill' in context else 1
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == 'Burst Jammer',
|
||||
'ecmBurstRange', container.getModifiedItemAttr('rangeSkillBonus') * level,
|
||||
stackingPenalties=False if 'skill' in context else True, **kwargs)
|
||||
'ecmBurstRange', container.getModifiedItemAttr('rangeSkillBonus') * level, **kwargs)
|
||||
|
||||
|
||||
class Effect2492(BaseEffect):
|
||||
@@ -7821,7 +7822,9 @@ class Effect2735(BaseEffect):
|
||||
boosterArmorHpPenalty
|
||||
|
||||
Used by:
|
||||
Implants named like: Booster (12 of 35)
|
||||
Implants named like: Improved Booster (4 of 8)
|
||||
Implants named like: Standard Booster (4 of 8)
|
||||
Implants named like: Strong Booster (4 of 8)
|
||||
"""
|
||||
|
||||
attr = 'boosterArmorHPPenalty'
|
||||
@@ -7838,9 +7841,15 @@ class Effect2736(BaseEffect):
|
||||
boosterArmorRepairAmountPenalty
|
||||
|
||||
Used by:
|
||||
Implants named like: Drop Booster (3 of 4)
|
||||
Implants named like: Mindflood Booster (3 of 4)
|
||||
Implants named like: Sooth Sayer Booster (3 of 4)
|
||||
Implant: Improved Drop Booster
|
||||
Implant: Improved Mindflood Booster
|
||||
Implant: Improved Sooth Sayer Booster
|
||||
Implant: Standard Drop Booster
|
||||
Implant: Standard Mindflood Booster
|
||||
Implant: Standard Sooth Sayer Booster
|
||||
Implant: Strong Drop Booster
|
||||
Implant: Strong Mindflood Booster
|
||||
Implant: Strong Sooth Sayer Booster
|
||||
"""
|
||||
|
||||
attr = 'boosterArmorRepairAmountPenalty'
|
||||
@@ -7858,7 +7867,9 @@ class Effect2737(BaseEffect):
|
||||
boosterShieldCapacityPenalty
|
||||
|
||||
Used by:
|
||||
Implants from group: Booster (12 of 67)
|
||||
Implants named like: Improved Booster (4 of 8)
|
||||
Implants named like: Standard Booster (4 of 8)
|
||||
Implants named like: Strong Booster (4 of 8)
|
||||
"""
|
||||
|
||||
attr = 'boosterShieldCapacityPenalty'
|
||||
@@ -7875,9 +7886,15 @@ class Effect2739(BaseEffect):
|
||||
boosterTurretOptimalRangePenalty
|
||||
|
||||
Used by:
|
||||
Implants named like: Blue Pill Booster (3 of 5)
|
||||
Implants named like: Mindflood Booster (3 of 4)
|
||||
Implants named like: Sooth Sayer Booster (3 of 4)
|
||||
Implant: Improved Blue Pill Booster
|
||||
Implant: Improved Mindflood Booster
|
||||
Implant: Improved Sooth Sayer Booster
|
||||
Implant: Standard Blue Pill Booster
|
||||
Implant: Standard Mindflood Booster
|
||||
Implant: Standard Sooth Sayer Booster
|
||||
Implant: Strong Blue Pill Booster
|
||||
Implant: Strong Mindflood Booster
|
||||
Implant: Strong Sooth Sayer Booster
|
||||
"""
|
||||
|
||||
attr = 'boosterTurretOptimalRangePenalty'
|
||||
@@ -7895,8 +7912,12 @@ class Effect2741(BaseEffect):
|
||||
boosterTurretFalloffPenalty
|
||||
|
||||
Used by:
|
||||
Implants named like: Drop Booster (3 of 4)
|
||||
Implants named like: X Instinct Booster (3 of 4)
|
||||
Implant: Improved Drop Booster
|
||||
Implant: Improved X-Instinct Booster
|
||||
Implant: Standard Drop Booster
|
||||
Implant: Standard X-Instinct Booster
|
||||
Implant: Strong Drop Booster
|
||||
Implant: Strong X-Instinct Booster
|
||||
"""
|
||||
|
||||
attr = 'boosterTurretFalloffPenalty'
|
||||
@@ -7914,8 +7935,12 @@ class Effect2745(BaseEffect):
|
||||
boosterCapacitorCapacityPenalty
|
||||
|
||||
Used by:
|
||||
Implants named like: Blue Pill Booster (3 of 5)
|
||||
Implants named like: Exile Booster (3 of 4)
|
||||
Implant: Improved Blue Pill Booster
|
||||
Implant: Improved Exile Booster
|
||||
Implant: Standard Blue Pill Booster
|
||||
Implant: Standard Exile Booster
|
||||
Implant: Strong Blue Pill Booster
|
||||
Implant: Strong Exile Booster
|
||||
"""
|
||||
|
||||
attr = 'boosterCapacitorCapacityPenalty'
|
||||
@@ -7932,8 +7957,10 @@ class Effect2746(BaseEffect):
|
||||
boosterMaxVelocityPenalty
|
||||
|
||||
Used by:
|
||||
Implants named like: Crash Booster (3 of 4)
|
||||
Items from market group: Implants & Boosters > Booster > Booster Slot 02 (9 of 13)
|
||||
Implant: Improved Crash Booster
|
||||
Implant: Standard Crash Booster
|
||||
Implant: Strong Crash Booster
|
||||
"""
|
||||
|
||||
attr = 'boosterMaxVelocityPenalty'
|
||||
@@ -7950,8 +7977,12 @@ class Effect2747(BaseEffect):
|
||||
boosterTurretTrackingPenalty
|
||||
|
||||
Used by:
|
||||
Implants named like: Exile Booster (3 of 4)
|
||||
Implants named like: Frentix Booster (3 of 4)
|
||||
Implant: Improved Exile Booster
|
||||
Implant: Improved Frentix Booster
|
||||
Implant: Standard Exile Booster
|
||||
Implant: Standard Frentix Booster
|
||||
Implant: Strong Exile Booster
|
||||
Implant: Strong Frentix Booster
|
||||
"""
|
||||
|
||||
attr = 'boosterTurretTrackingPenalty'
|
||||
@@ -7969,8 +8000,12 @@ class Effect2748(BaseEffect):
|
||||
boosterMissileVelocityPenalty
|
||||
|
||||
Used by:
|
||||
Implants named like: Crash Booster (3 of 4)
|
||||
Implants named like: X Instinct Booster (3 of 4)
|
||||
Implant: Improved Crash Booster
|
||||
Implant: Improved X-Instinct Booster
|
||||
Implant: Standard Crash Booster
|
||||
Implant: Standard X-Instinct Booster
|
||||
Implant: Strong Crash Booster
|
||||
Implant: Strong X-Instinct Booster
|
||||
"""
|
||||
|
||||
attr = 'boosterMissileVelocityPenalty'
|
||||
@@ -7988,7 +8023,9 @@ class Effect2749(BaseEffect):
|
||||
boosterMissileExplosionVelocityPenalty
|
||||
|
||||
Used by:
|
||||
Implants named like: Blue Pill Booster (3 of 5)
|
||||
Implant: Improved Blue Pill Booster
|
||||
Implant: Standard Blue Pill Booster
|
||||
Implant: Strong Blue Pill Booster
|
||||
"""
|
||||
|
||||
attr = 'boosterAOEVelocityPenalty'
|
||||
@@ -8143,8 +8180,12 @@ class Effect2791(BaseEffect):
|
||||
boosterMissileExplosionCloudPenaltyFixed
|
||||
|
||||
Used by:
|
||||
Implants named like: Exile Booster (3 of 4)
|
||||
Implants named like: Mindflood Booster (3 of 4)
|
||||
Implant: Improved Exile Booster
|
||||
Implant: Improved Mindflood Booster
|
||||
Implant: Standard Exile Booster
|
||||
Implant: Standard Mindflood Booster
|
||||
Implant: Strong Exile Booster
|
||||
Implant: Strong Mindflood Booster
|
||||
"""
|
||||
|
||||
attr = 'boosterMissileAOECloudPenalty'
|
||||
@@ -8436,7 +8477,7 @@ class Effect2847(BaseEffect):
|
||||
trackingSpeedBonusPassiveRequiringGunneryTrackingSpeedBonus
|
||||
|
||||
Used by:
|
||||
Implants named like: Drop Booster (4 of 4)
|
||||
Implants named like: Drop Booster (9 of 9)
|
||||
Implants named like: Eifyr and Co. 'Gunslinger' Motion Prediction MR (6 of 6)
|
||||
Implant: Antipharmakon Iokira
|
||||
Implant: Ogdin's Eye Coordination Enhancer
|
||||
@@ -9189,7 +9230,7 @@ class Effect3002(BaseEffect):
|
||||
|
||||
Used by:
|
||||
Modules from group: Ancillary Remote Shield Booster (4 of 4)
|
||||
Modules from group: Capacitor Booster (59 of 59)
|
||||
Modules from group: Capacitor Booster (41 of 41)
|
||||
Modules from group: Energy Neutralizer (54 of 54)
|
||||
Modules from group: Energy Nosferatu (54 of 54)
|
||||
Modules from group: Hull Repair Unit (25 of 25)
|
||||
@@ -9303,9 +9344,9 @@ class Effect3029(BaseEffect):
|
||||
overloadSelfEmHardeningBonus
|
||||
|
||||
Used by:
|
||||
Modules named like: Anti EM Shield Hardener (21 of 21)
|
||||
Variations of module: Anti-EM Shield Hardener I (20 of 20)
|
||||
Variations of module: Armor EM Hardener I (39 of 39)
|
||||
Variations of module: EM Ward Field I (19 of 19)
|
||||
Module: Civilian EM Ward Field
|
||||
"""
|
||||
|
||||
type = 'overheat'
|
||||
@@ -9320,9 +9361,9 @@ class Effect3030(BaseEffect):
|
||||
overloadSelfThermalHardeningBonus
|
||||
|
||||
Used by:
|
||||
Variations of module: Anti-Thermal Shield Hardener I (20 of 20)
|
||||
Variations of module: Armor Thermal Hardener I (39 of 39)
|
||||
Variations of module: Thermal Dissipation Field I (19 of 19)
|
||||
Module: Civilian Thermal Dissipation Field
|
||||
Module: Civilian Anti-Thermal Shield Hardener
|
||||
"""
|
||||
|
||||
type = 'overheat'
|
||||
@@ -9337,9 +9378,9 @@ class Effect3031(BaseEffect):
|
||||
overloadSelfExplosiveHardeningBonus
|
||||
|
||||
Used by:
|
||||
Variations of module: Anti-Explosive Shield Hardener I (20 of 20)
|
||||
Variations of module: Armor Explosive Hardener I (39 of 39)
|
||||
Variations of module: Explosive Deflection Field I (19 of 19)
|
||||
Module: Civilian Explosive Deflection Field
|
||||
Module: Civilian Anti-Explosive Shield Hardener
|
||||
"""
|
||||
|
||||
type = 'overheat'
|
||||
@@ -9354,9 +9395,9 @@ class Effect3032(BaseEffect):
|
||||
overloadSelfKineticHardeningBonus
|
||||
|
||||
Used by:
|
||||
Modules named like: Anti Kinetic Shield Hardener (21 of 21)
|
||||
Variations of module: Anti-Kinetic Shield Hardener I (20 of 20)
|
||||
Variations of module: Armor Kinetic Hardener I (39 of 39)
|
||||
Variations of module: Kinetic Deflection Field I (19 of 19)
|
||||
Module: Civilian Kinetic Deflection Field
|
||||
"""
|
||||
|
||||
type = 'overheat'
|
||||
@@ -9372,7 +9413,7 @@ class Effect3035(BaseEffect):
|
||||
|
||||
Used by:
|
||||
Modules named like: Capital Flex Hardener (9 of 9)
|
||||
Variations of module: Adaptive Invulnerability Field I (17 of 17)
|
||||
Variations of module: Adaptive Invulnerability Shield Hardener I (18 of 18)
|
||||
"""
|
||||
|
||||
type = 'overheat'
|
||||
@@ -16714,7 +16755,7 @@ class Effect4951(BaseEffect):
|
||||
|
||||
Used by:
|
||||
Implants named like: Agency 'Hardshell' TB Dose (4 of 4)
|
||||
Implants named like: Blue Pill Booster (5 of 5)
|
||||
Implants named like: Blue Pill Booster (10 of 10)
|
||||
Implant: Antipharmakon Thureo
|
||||
"""
|
||||
|
||||
@@ -16768,9 +16809,15 @@ class Effect4970(BaseEffect):
|
||||
boosterShieldBoostAmountPenaltyShieldSkills
|
||||
|
||||
Used by:
|
||||
Implants named like: Crash Booster (3 of 4)
|
||||
Implants named like: Frentix Booster (3 of 4)
|
||||
Implants named like: Mindflood Booster (3 of 4)
|
||||
Implant: Improved Crash Booster
|
||||
Implant: Improved Frentix Booster
|
||||
Implant: Improved Mindflood Booster
|
||||
Implant: Standard Crash Booster
|
||||
Implant: Standard Frentix Booster
|
||||
Implant: Standard Mindflood Booster
|
||||
Implant: Strong Crash Booster
|
||||
Implant: Strong Frentix Booster
|
||||
Implant: Strong Mindflood Booster
|
||||
"""
|
||||
|
||||
attr = 'boosterShieldBoostAmountPenalty'
|
||||
@@ -16872,7 +16919,7 @@ class Effect4989(BaseEffect):
|
||||
missileSkillAoeCloudSizeBonusAllIncludingCapitals
|
||||
|
||||
Used by:
|
||||
Implants named like: Crash Booster (4 of 4)
|
||||
Implants named like: Crash Booster (9 of 9)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -18631,7 +18678,7 @@ class Effect5230(BaseEffect):
|
||||
|
||||
Used by:
|
||||
Modules from group: Flex Shield Hardener (5 of 5)
|
||||
Modules from group: Shield Hardener (97 of 97)
|
||||
Modules from group: Shield Hardener (102 of 102)
|
||||
"""
|
||||
|
||||
type = 'active'
|
||||
@@ -19797,7 +19844,7 @@ class Effect5364(BaseEffect):
|
||||
|
||||
Used by:
|
||||
Implants named like: Agency 'Hardshell' TB Dose (4 of 4)
|
||||
Implants named like: Exile Booster (4 of 4)
|
||||
Implants named like: Exile Booster (9 of 9)
|
||||
Implant: Antipharmakon Kosybo
|
||||
"""
|
||||
|
||||
@@ -22035,6 +22082,7 @@ class Effect5769(BaseEffect):
|
||||
repairDroneHullBonusBonus
|
||||
|
||||
Used by:
|
||||
Implants named like: Black Market 'Valdimar' Repair Drone Operation DR (3 of 3)
|
||||
Modules named like: Drone Repair Augmentor (8 of 8)
|
||||
Skill: Repair Drone Operation
|
||||
"""
|
||||
@@ -29064,10 +29112,6 @@ class Effect6582(BaseEffect):
|
||||
mod.item.requiresSkill('Capital Precursor Weapon'),
|
||||
'damageMultiplier', src.getModifiedItemAttr('siegeTurretDamageBonus'), **kwargs)
|
||||
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.requiresSkill('Motion Prediction'),
|
||||
'damageMultiplier', src.getModifiedItemAttr('siegeHAWTurretDamageBonus'),
|
||||
stackingPenalties=True, **kwargs)
|
||||
|
||||
# Missiles
|
||||
for type in ('kinetic', 'thermal', 'explosive', 'em'):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill('XL Torpedoes') or
|
||||
@@ -29079,7 +29123,7 @@ class Effect6582(BaseEffect):
|
||||
mod.item.requiresSkill('XL Cruise Missiles'),
|
||||
'speed', src.getModifiedItemAttr('siegeLauncherROFBonus'), **kwargs)
|
||||
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill('Target Navigation Prediction'),
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == 'Missile Launcher Rapid Torpedo',
|
||||
'speed', src.getModifiedItemAttr('siegeHAWMissileROFBonus'),
|
||||
stackingPenalties=True, penaltyGroup='postPercent', **kwargs)
|
||||
|
||||
@@ -30461,6 +30505,7 @@ class Effect6664(BaseEffect):
|
||||
skillBonusDroneSharpshooting
|
||||
|
||||
Used by:
|
||||
Implants named like: Black Market 'Valdimar' Drone Sharpshooting DS (3 of 3)
|
||||
Skill: Drone Sharpshooting
|
||||
"""
|
||||
|
||||
@@ -30469,16 +30514,18 @@ class Effect6664(BaseEffect):
|
||||
@staticmethod
|
||||
def handler(fit, src, context, projectionRange, **kwargs):
|
||||
lvl = src.level if 'skill' in context else 1
|
||||
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill('Drones'), 'maxRange',
|
||||
src.getModifiedItemAttr('rangeSkillBonus') * lvl, **kwargs)
|
||||
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill('Fighters'), 'fighterAbilityMissilesRange',
|
||||
src.getModifiedItemAttr('rangeSkillBonus') * lvl, **kwargs)
|
||||
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill('Fighters'),
|
||||
'fighterAbilityAttackTurretRangeOptimal',
|
||||
src.getModifiedItemAttr('rangeSkillBonus') * lvl, **kwargs)
|
||||
fit.fighters.filteredItemBoost(lambda mod: mod.item.requiresSkill('Fighters'),
|
||||
'fighterAbilityAttackMissileRangeOptimal',
|
||||
src.getModifiedItemAttr('rangeSkillBonus') * lvl, **kwargs)
|
||||
fit.drones.filteredItemBoost(
|
||||
lambda mod: mod.item.requiresSkill('Drones'), 'maxRange',
|
||||
src.getModifiedItemAttr('rangeSkillBonus') * lvl, **kwargs)
|
||||
fit.fighters.filteredItemBoost(
|
||||
lambda mod: mod.item.requiresSkill('Fighters'), 'fighterAbilityMissilesRange',
|
||||
src.getModifiedItemAttr('rangeSkillBonus') * lvl, **kwargs)
|
||||
fit.fighters.filteredItemBoost(
|
||||
lambda mod: mod.item.requiresSkill('Fighters'), 'fighterAbilityAttackTurretRangeOptimal',
|
||||
src.getModifiedItemAttr('rangeSkillBonus') * lvl, **kwargs)
|
||||
fit.fighters.filteredItemBoost(
|
||||
lambda mod: mod.item.requiresSkill('Fighters'), 'fighterAbilityAttackMissileRangeOptimal',
|
||||
src.getModifiedItemAttr('rangeSkillBonus') * lvl, **kwargs)
|
||||
|
||||
|
||||
class Effect6665(BaseEffect):
|
||||
@@ -30486,6 +30533,7 @@ class Effect6665(BaseEffect):
|
||||
skillBonusDroneDurability
|
||||
|
||||
Used by:
|
||||
Implants named like: Black Market 'Valdimar' Drone Durability DD (3 of 3)
|
||||
Skill: Drone Durability
|
||||
"""
|
||||
|
||||
@@ -30509,6 +30557,7 @@ class Effect6667(BaseEffect):
|
||||
skillBonusDroneNavigation
|
||||
|
||||
Used by:
|
||||
Implants named like: Black Market 'Valdimar' Drone Navigation DN (3 of 3)
|
||||
Skill: Drone Navigation
|
||||
"""
|
||||
|
||||
@@ -35664,7 +35713,7 @@ class Effect7177(BaseEffect):
|
||||
skillBonusDroneDurabilityNotFighters
|
||||
|
||||
Used by:
|
||||
Implants from group: Cyber Drones (4 of 4)
|
||||
Implants named like: Drone Tuner (4 of 4)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -36258,3 +36307,91 @@ class Effect8018(BaseEffect):
|
||||
def handler(fit, implant, context, projectionRange, **kwargs):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill('Shield Emission Systems') or mod.item.requiresSkill('Remote Armor Repair Systems'),
|
||||
'duration', implant.getModifiedItemAttr('remoteRepDurationBonus'), **kwargs)
|
||||
|
||||
|
||||
class Effect8021(BaseEffect):
|
||||
"""
|
||||
hydraSetBonus
|
||||
|
||||
Used by:
|
||||
Implants named like: grade Hydra (18 of 18)
|
||||
"""
|
||||
|
||||
runTime = 'early'
|
||||
type = 'passive'
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, implant, context, projectionRange, **kwargs):
|
||||
for attr in ('hydraDroneTrackingBonus', 'hydraDroneRangeBonus', 'hydraMissileFlightTimeBonus', 'hydraMissileExplosionVelocityBonus'):
|
||||
fit.appliedImplants.filteredItemMultiply(
|
||||
lambda implant: implant.item.requiresSkill('Cybernetics'),
|
||||
attr, implant.getModifiedItemAttr('implantSetHydra'), **kwargs)
|
||||
|
||||
|
||||
class Effect8023(BaseEffect):
|
||||
"""
|
||||
hydraDroneTrackingEffect
|
||||
|
||||
Used by:
|
||||
Implants named like: grade Hydra (15 of 18)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, implant, context, projectionRange, **kwargs):
|
||||
fit.drones.filteredItemBoost(
|
||||
lambda drone: drone.item.requiresSkill('Drones'),
|
||||
'trackingSpeed', implant.getModifiedItemAttr('hydraDroneTrackingBonus'), **kwargs)
|
||||
|
||||
|
||||
class Effect8024(BaseEffect):
|
||||
"""
|
||||
hydraDroneRangeEffect
|
||||
|
||||
Used by:
|
||||
Implants named like: grade Hydra (15 of 18)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, implant, context, projectionRange, **kwargs):
|
||||
for attr in ('maxRange', 'falloff'):
|
||||
fit.drones.filteredItemBoost(
|
||||
lambda drone: drone.item.requiresSkill('Drones'),
|
||||
attr, implant.getModifiedItemAttr('hydraDroneRangeBonus'), **kwargs)
|
||||
|
||||
|
||||
class Effect8025(BaseEffect):
|
||||
"""
|
||||
hydraMissileFlightTimeEffect
|
||||
|
||||
Used by:
|
||||
Implants named like: grade Hydra (15 of 18)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, implant, context, projectionRange, **kwargs):
|
||||
fit.modules.filteredChargeBoost(
|
||||
lambda mod: mod.charge.requiresSkill('Missile Launcher Operation'),
|
||||
'explosionDelay', implant.getModifiedItemAttr('hydraMissileFlightTimeBonus'), **kwargs)
|
||||
|
||||
|
||||
class Effect8026(BaseEffect):
|
||||
"""
|
||||
hydraMissileExplosionVelocityEffect
|
||||
|
||||
Used by:
|
||||
Implants named like: grade Hydra (15 of 18)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, implant, context, projectionRange, **kwargs):
|
||||
fit.modules.filteredChargeBoost(
|
||||
lambda mod: mod.charge.requiresSkill('Missile Launcher Operation'),
|
||||
'aoeVelocity', implant.getModifiedItemAttr('hydraMissileExplosionVelocityBonus'), **kwargs)
|
||||
|
||||
@@ -723,5 +723,15 @@ class Unit(EqBase):
|
||||
|
||||
return value
|
||||
|
||||
|
||||
class Traits(EqBase):
|
||||
pass
|
||||
|
||||
|
||||
class ImplantSet(EqBase):
|
||||
|
||||
@property
|
||||
def fullName(self):
|
||||
if not self.gradeName:
|
||||
return self.setName
|
||||
return '{} {}'.format(self.gradeName, self.setName)
|
||||
|
||||
@@ -576,11 +576,15 @@ class Fit:
|
||||
|
||||
if warfareBuffID == 11: # Shield Burst: Active Shielding: Repair Duration/Capacitor
|
||||
self.modules.filteredItemBoost(
|
||||
lambda mod: mod.item.requiresSkill("Shield Operation") or mod.item.requiresSkill(
|
||||
"Shield Emission Systems"), "capacitorNeed", value)
|
||||
lambda mod: mod.item.requiresSkill("Shield Operation") or
|
||||
mod.item.requiresSkill("Shield Emission Systems") or
|
||||
mod.item.requiresSkill("Capital Shield Emission Systems"),
|
||||
"capacitorNeed", value)
|
||||
self.modules.filteredItemBoost(
|
||||
lambda mod: mod.item.requiresSkill("Shield Operation") or mod.item.requiresSkill(
|
||||
"Shield Emission Systems"), "duration", value)
|
||||
lambda mod: mod.item.requiresSkill("Shield Operation") or
|
||||
mod.item.requiresSkill("Shield Emission Systems") or
|
||||
mod.item.requiresSkill("Capital Shield Emission Systems"),
|
||||
"duration", value)
|
||||
|
||||
if warfareBuffID == 12: # Shield Burst: Shield Extension: Shield HP
|
||||
self.ship.boostItemAttr("shieldCapacity", value, stackingPenalties=True)
|
||||
@@ -590,12 +594,16 @@ class Fit:
|
||||
self.ship.boostItemAttr("armor%sDamageResonance" % damageType, value, stackingPenalties=True)
|
||||
|
||||
if warfareBuffID == 14: # Armor Burst: Rapid Repair: Repair Duration/Capacitor
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems") or
|
||||
mod.item.requiresSkill("Repair Systems"),
|
||||
"capacitorNeed", value)
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems") or
|
||||
mod.item.requiresSkill("Repair Systems"),
|
||||
"duration", value)
|
||||
self.modules.filteredItemBoost(
|
||||
lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems") or
|
||||
mod.item.requiresSkill("Repair Systems") or
|
||||
mod.item.requiresSkill("Capital Remote Armor Repair Systems"),
|
||||
"capacitorNeed", value)
|
||||
self.modules.filteredItemBoost(
|
||||
lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems") or
|
||||
mod.item.requiresSkill("Repair Systems") or
|
||||
mod.item.requiresSkill("Capital Remote Armor Repair Systems"),
|
||||
"duration", value)
|
||||
|
||||
if warfareBuffID == 15: # Armor Burst: Armor Reinforcement: Armor HP
|
||||
self.ship.boostItemAttr("armorHP", value, stackingPenalties=True)
|
||||
|
||||
@@ -26,11 +26,12 @@ VectorDef = namedtuple('VectorDef', ('lengthHandle', 'lengthUnit', 'angleHandle'
|
||||
|
||||
class YDef:
|
||||
|
||||
def __init__(self, handle, unit, label, selectorLabel=None):
|
||||
def __init__(self, handle, unit, label, selectorLabel=None, hidden=False):
|
||||
self.handle = handle
|
||||
self.unit = unit
|
||||
self.label = label
|
||||
self._selectorLabel = selectorLabel
|
||||
self.hidden = hidden
|
||||
|
||||
@property
|
||||
def selectorLabel(self):
|
||||
@@ -53,12 +54,13 @@ class YDef:
|
||||
|
||||
class XDef:
|
||||
|
||||
def __init__(self, handle, unit, label, mainInput, selectorLabel=None):
|
||||
def __init__(self, handle, unit, label, mainInput, selectorLabel=None, hidden=False):
|
||||
self.handle = handle
|
||||
self.unit = unit
|
||||
self.label = label
|
||||
self.mainInput = mainInput
|
||||
self._selectorLabel = selectorLabel
|
||||
self.hidden = hidden
|
||||
|
||||
@property
|
||||
def selectorLabel(self):
|
||||
|
||||
@@ -31,8 +31,8 @@ from .getter import (
|
||||
|
||||
class FitDamageStatsGraph(FitGraph):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self._timeCache = TimeCache()
|
||||
self._projectedCache = ProjectedDataCache()
|
||||
|
||||
|
||||
@@ -23,24 +23,6 @@ import math
|
||||
from graphs.data.base import SmoothPointGetter
|
||||
|
||||
|
||||
class Time2SpeedGetter(SmoothPointGetter):
|
||||
|
||||
def _getCommonData(self, miscParams, src, tgt):
|
||||
return {
|
||||
'maxSpeed': src.getMaxVelocity(),
|
||||
'mass': src.item.ship.getModifiedItemAttr('mass'),
|
||||
'agility': src.item.ship.getModifiedItemAttr('agility')}
|
||||
|
||||
def _calculatePoint(self, x, miscParams, src, tgt, commonData):
|
||||
time = x
|
||||
maxSpeed = commonData['maxSpeed']
|
||||
mass = commonData['mass']
|
||||
agility = commonData['agility']
|
||||
# https://wiki.eveuniversity.org/Acceleration#Mathematics_and_formulae
|
||||
speed = maxSpeed * (1 - math.exp((-time * 1000000) / (agility * mass)))
|
||||
return speed
|
||||
|
||||
|
||||
class Time2DistanceGetter(SmoothPointGetter):
|
||||
|
||||
def _getCommonData(self, miscParams, src, tgt):
|
||||
@@ -60,3 +42,62 @@ class Time2DistanceGetter(SmoothPointGetter):
|
||||
distance_0 = maxSpeed * 0 + (maxSpeed * agility * mass * math.exp((-0 * 1000000) / (agility * mass)) / 1000000)
|
||||
distance = distance_t - distance_0
|
||||
return distance
|
||||
|
||||
|
||||
class Time2SpeedGetter(SmoothPointGetter):
|
||||
|
||||
def _getCommonData(self, miscParams, src, tgt):
|
||||
return {
|
||||
'maxSpeed': src.getMaxVelocity(),
|
||||
'mass': src.item.ship.getModifiedItemAttr('mass'),
|
||||
'agility': src.item.ship.getModifiedItemAttr('agility')}
|
||||
|
||||
def _calculatePoint(self, x, miscParams, src, tgt, commonData):
|
||||
time = x
|
||||
maxSpeed = commonData['maxSpeed']
|
||||
mass = commonData['mass']
|
||||
agility = commonData['agility']
|
||||
# https://wiki.eveuniversity.org/Acceleration#Mathematics_and_formulae
|
||||
speed = maxSpeed * (1 - math.exp((-time * 1000000) / (agility * mass)))
|
||||
return speed
|
||||
|
||||
|
||||
class Time2MomentumGetter(Time2SpeedGetter):
|
||||
|
||||
def _calculatePoint(self, x, miscParams, src, tgt, commonData):
|
||||
mass = commonData['mass']
|
||||
speed = Time2SpeedGetter._calculatePoint(
|
||||
self, x=x, miscParams=miscParams,
|
||||
src=src, tgt=tgt, commonData=commonData)
|
||||
momentum = speed * mass
|
||||
return momentum
|
||||
|
||||
|
||||
class Time2BumpSpeedGetter(Time2SpeedGetter):
|
||||
|
||||
def _calculatePoint(self, x, miscParams, src, tgt, commonData):
|
||||
# S. Santorine, Ship Motion in EVE-Online, p3, Collisions & Bumping section
|
||||
# https://docs.google.com/document/d/1rwVWjTvzVdPEFETf0vwm649AFb4bgRBaNLpRPaoB03o
|
||||
# Internally, Santorine's formulas are using millions of kilograms, so we normalize to them here
|
||||
bumperMass = commonData['mass'] / 10 ** 6
|
||||
bumperSpeed = Time2SpeedGetter._calculatePoint(
|
||||
self, x=x, miscParams=miscParams,
|
||||
src=src, tgt=tgt, commonData=commonData)
|
||||
tgtMass = miscParams['tgtMass'] / 10 ** 6
|
||||
tgtSpeed = (2 * bumperSpeed * bumperMass) / (bumperMass + tgtMass)
|
||||
return tgtSpeed
|
||||
|
||||
|
||||
class Time2BumpDistanceGetter(Time2BumpSpeedGetter):
|
||||
|
||||
def _calculatePoint(self, x, miscParams, src, tgt, commonData):
|
||||
# S. Santorine, Ship Motion in EVE-Online, p3, Collisions & Bumping section
|
||||
# https://docs.google.com/document/d/1rwVWjTvzVdPEFETf0vwm649AFb4bgRBaNLpRPaoB03o
|
||||
# Internally, Santorine's formulas are using millions of kilograms, so we normalize to them here
|
||||
tgtMass = miscParams['tgtMass'] / 10 ** 6
|
||||
tgtInertia = miscParams['tgtInertia']
|
||||
tgtSpeed = Time2BumpSpeedGetter._calculatePoint(
|
||||
self, x=x, miscParams=miscParams,
|
||||
src=src, tgt=tgt, commonData=commonData)
|
||||
tgtDistance = tgtSpeed * tgtMass * tgtInertia
|
||||
return tgtDistance
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
|
||||
from graphs.data.base import FitGraph, XDef, YDef, Input
|
||||
from .getter import Time2SpeedGetter, Time2DistanceGetter
|
||||
from .getter import Time2SpeedGetter, Time2DistanceGetter, Time2MomentumGetter, Time2BumpSpeedGetter, Time2BumpDistanceGetter
|
||||
|
||||
|
||||
class FitMobilityGraph(FitGraph):
|
||||
@@ -30,12 +30,26 @@ class FitMobilityGraph(FitGraph):
|
||||
xDefs = [XDef(handle='time', unit='s', label='Time', mainInput=('time', 's'))]
|
||||
yDefs = [
|
||||
YDef(handle='speed', unit='m/s', label='Speed'),
|
||||
YDef(handle='distance', unit='km', label='Distance')]
|
||||
inputs = [Input(handle='time', unit='s', label='Time', iconID=1392, defaultValue=10, defaultRange=(0, 30))]
|
||||
YDef(handle='distance', unit='km', label='Distance'),
|
||||
YDef(handle='momentum', unit='Gkg⋅m/s', label='Momentum'),
|
||||
YDef(handle='bumpSpeed', unit='m/s', label='Target speed', selectorLabel='Bump speed'),
|
||||
YDef(handle='bumpDistance', unit='km', label='Target distance traveled', selectorLabel='Bump distance')]
|
||||
inputs = [
|
||||
Input(handle='time', unit='s', label='Time', iconID=1392, defaultValue=10, defaultRange=(0, 30)),
|
||||
# Default values in target fields correspond to a random carrier/fax
|
||||
Input(handle='tgtMass', unit='Mkg', label='Target mass', iconID=76, defaultValue=1300, defaultRange=(100, 2500), conditions=[(None, ('bumpSpeed', 'm/s')), (None, ('bumpDistance', 'km'))], secondaryTooltip='Defined in millions of kilograms'),
|
||||
Input(handle='tgtInertia', unit=None, label='Target inertia factor', iconID=1401, defaultValue=0.015, defaultRange=(0.03, 0.1), conditions=[(None, ('bumpDistance', 'km'))], secondaryTooltip='Inertia Modifier attribute value of the target ship')]
|
||||
srcExtraCols = ('Speed', 'Agility')
|
||||
|
||||
# Calculation stuff
|
||||
_normalizers = {('tgtMass', 'Mkg'): lambda v, src, tgt: None if v is None else v * 10 ** 6}
|
||||
_getters = {
|
||||
('time', 'speed'): Time2SpeedGetter,
|
||||
('time', 'distance'): Time2DistanceGetter}
|
||||
_denormalizers = {('distance', 'km'): lambda v, src, tgt: v / 1000}
|
||||
('time', 'distance'): Time2DistanceGetter,
|
||||
('time', 'momentum'): Time2MomentumGetter,
|
||||
('time', 'bumpSpeed'): Time2BumpSpeedGetter,
|
||||
('time', 'bumpDistance'): Time2BumpDistanceGetter}
|
||||
_denormalizers = {
|
||||
('distance', 'km'): lambda v, src, tgt: v / 1000,
|
||||
('momentum', 'Gkg⋅m/s'): lambda v, src, tgt: v / 10 ** 9,
|
||||
('bumpDistance', 'km'): lambda v, src, tgt: v / 1000}
|
||||
|
||||
@@ -26,8 +26,8 @@ from .getter import Distance2RpsGetter, Distance2RepAmountGetter, Time2RpsGetter
|
||||
|
||||
class FitRemoteRepsGraph(FitGraph):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self._timeCache = TimeCache()
|
||||
|
||||
def _clearInternalCache(self, reason, extraData):
|
||||
|
||||
@@ -27,6 +27,10 @@ from .getter import (
|
||||
|
||||
class FitShieldRegenGraph(FitGraph):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.isEffective = gui.mainFrame.MainFrame.getInstance().statsPane.nameViewMap['resistancesViewFull'].showEffective
|
||||
|
||||
# UI stuff
|
||||
internalName = 'shieldRegenGraph'
|
||||
name = 'Shield Regeneration'
|
||||
@@ -73,7 +77,3 @@ class FitShieldRegenGraph(FitGraph):
|
||||
('shieldAmount', '%'): lambda v, src, tgt: v * 100 / src.item.ship.getModifiedItemAttr('shieldCapacity'),
|
||||
('shieldAmount', 'EHP'): lambda v, src, tgt: src.item.damagePattern.effectivify(src.item, v, 'shield'),
|
||||
('shieldRegen', 'EHP/s'): lambda v, src, tgt: src.item.damagePattern.effectivify(src.item, v, 'shield')}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.isEffective = gui.mainFrame.MainFrame.getInstance().statsPane.nameViewMap['resistancesViewFull'].showEffective
|
||||
|
||||
@@ -26,8 +26,8 @@ from .getter import AU_METERS, Distance2TimeGetter
|
||||
|
||||
class FitWarpTimeGraph(FitGraph):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self._subspeedCache = SubwarpSpeedCache()
|
||||
|
||||
def _clearInternalCache(self, reason, extraData):
|
||||
|
||||
@@ -295,12 +295,16 @@ class GraphControlPanel(wx.Panel):
|
||||
|
||||
self.ySubSelection.Clear()
|
||||
for yDef in view.yDefs:
|
||||
if yDef.hidden and not self.graphFrame.includeHidden:
|
||||
continue
|
||||
self.ySubSelection.Append(self.formatLabel(yDef, selector=True), yDef)
|
||||
self.ySubSelection.Enable(len(view.yDefs) > 1)
|
||||
self.ySubSelection.SetSelection(selectedY)
|
||||
|
||||
self.xSubSelection.Clear()
|
||||
for xDef in view.xDefs:
|
||||
if xDef.hidden and not self.graphFrame.includeHidden:
|
||||
continue
|
||||
self.xSubSelection.Append(self.formatLabel(xDef, selector=True), xDef)
|
||||
self.xSubSelection.Enable(len(view.xDefs) > 1)
|
||||
self.xSubSelection.SetSelection(selectedX)
|
||||
|
||||
@@ -50,6 +50,7 @@ class GraphFrame(AuxiliaryFrame):
|
||||
|
||||
super().__init__(parent, title='Graphs', size=(520, 390), resizeable=True)
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
self.includeHidden = includeHidden
|
||||
|
||||
self.SetIcon(wx.Icon(BitmapLoader.getBitmap('graphs_small', 'gui')))
|
||||
|
||||
@@ -74,7 +75,7 @@ class GraphFrame(AuxiliaryFrame):
|
||||
|
||||
# Setup - graph selector
|
||||
for view in FitGraph.views:
|
||||
if view.hidden and not includeHidden:
|
||||
if view.hidden and not self.includeHidden:
|
||||
continue
|
||||
self.graphSelection.Append(view.name, view())
|
||||
self.graphSelection.SetSelection(0)
|
||||
|
||||
@@ -316,7 +316,7 @@ class ImplantDisplay(d.Display):
|
||||
implants.append(implant)
|
||||
return implants
|
||||
|
||||
def addImplantSet(self, impSet):
|
||||
def addImplants(self, implants):
|
||||
self.mainFrame.command.Submit(cmd.GuiAddImplantSetCommand(
|
||||
fitID=self.mainFrame.getActiveFit(),
|
||||
itemIDs=[i.itemID for i in impSet.implants]))
|
||||
itemIDs=[i.itemID for i in implants]))
|
||||
|
||||
@@ -2,17 +2,19 @@
|
||||
import wx
|
||||
|
||||
from gui.contextMenu import ContextMenuUnconditional
|
||||
from service.implantSet import ImplantSets as s_ImplantSets
|
||||
from service.market import Market
|
||||
from service.implantSet import ImplantSets as UserImplantSets
|
||||
from service.precalcImplantSet import PrecalcedImplantSets
|
||||
|
||||
|
||||
class ImplantSetApply(ContextMenuUnconditional):
|
||||
|
||||
def display(self, callingWindow, srcContext):
|
||||
|
||||
sIS = s_ImplantSets.getInstance()
|
||||
implantSets = sIS.getImplantSetList()
|
||||
self.userImplantSets = UserImplantSets.getInstance().getImplantSetList()
|
||||
self.structedImplantSets = PrecalcedImplantSets.getStructuredSets()
|
||||
|
||||
if len(implantSets) == 0:
|
||||
if len(self.userImplantSets) == 0 and len(self.structedImplantSets) == 0:
|
||||
return False
|
||||
|
||||
return srcContext in ("implantItemMisc", "implantEditor")
|
||||
@@ -20,34 +22,87 @@ class ImplantSetApply(ContextMenuUnconditional):
|
||||
def getText(self, callingWindow, context):
|
||||
return "Apply Implant Set"
|
||||
|
||||
def getSubMenu(self, callingWindow, context, rootMenu, i, pitem):
|
||||
m = wx.Menu()
|
||||
bindmenu = rootMenu if "wxMSW" in wx.PlatformInfo else m
|
||||
def _addSeparator(self, m, text):
|
||||
id_ = ContextMenuUnconditional.nextID()
|
||||
m.Append(id_, '─ %s ─' % text)
|
||||
m.Enable(id_, False)
|
||||
|
||||
sIS = s_ImplantSets.getInstance()
|
||||
implantSets = sIS.getImplantSetList()
|
||||
def _addSet(self, parentMenu, profile, name):
|
||||
id = ContextMenuUnconditional.nextID()
|
||||
self.eventSetMap[id] = profile
|
||||
menuItem = wx.MenuItem(parentMenu, id, name)
|
||||
parentMenu.Bind(wx.EVT_MENU, self.handleSelection, menuItem)
|
||||
return menuItem
|
||||
|
||||
def _addCategory(self, parentMenu, name):
|
||||
id = ContextMenuUnconditional.nextID()
|
||||
menuItem = wx.MenuItem(parentMenu, id, name)
|
||||
parentMenu.Bind(wx.EVT_MENU, self.handleSelection, menuItem)
|
||||
return menuItem
|
||||
|
||||
def _gradeSorter(self, item):
|
||||
order = ['low-grade', 'mid-grade', 'high-grade']
|
||||
try:
|
||||
pos = order.index(item.lower())
|
||||
except IndexError:
|
||||
pos = len(order)
|
||||
return pos, item
|
||||
|
||||
def getSubMenu(self, callingWindow, context, rootMenu, i, pitem):
|
||||
msw = "wxMSW" in wx.PlatformInfo
|
||||
menu_lvl1 = wx.Menu()
|
||||
|
||||
self.context = context
|
||||
self.callingWindow = callingWindow
|
||||
|
||||
self.idmap = {}
|
||||
self.eventSetMap = {}
|
||||
|
||||
for set in sorted(implantSets, key=lambda i: i.name):
|
||||
id = ContextMenuUnconditional.nextID()
|
||||
mitem = wx.MenuItem(rootMenu, id, set.name)
|
||||
bindmenu.Bind(wx.EVT_MENU, self.handleSelection, mitem)
|
||||
self.idmap[id] = set
|
||||
m.Append(mitem)
|
||||
# Auto-generated sets
|
||||
for setName in sorted(self.structedImplantSets):
|
||||
setData = self.structedImplantSets[setName]
|
||||
if len(setData) == 1:
|
||||
for implantIDs in setData.values():
|
||||
menuitem_lvl1 = self._addSet(rootMenu, implantIDs, setName)
|
||||
menu_lvl1.Append(menuitem_lvl1)
|
||||
else:
|
||||
menuitem_lvl1 = self._addCategory(rootMenu, setName)
|
||||
menu_lvl2 = wx.Menu()
|
||||
for gradeName in sorted(setData, key=self._gradeSorter):
|
||||
implantIDs = setData[gradeName]
|
||||
menuitem_lvl2 = self._addSet(rootMenu if msw else menu_lvl1, implantIDs, gradeName)
|
||||
menu_lvl2.Append(menuitem_lvl2)
|
||||
menu_lvl2.Bind(wx.EVT_MENU, self.handleSelection)
|
||||
menuitem_lvl1.SetSubMenu(menu_lvl2)
|
||||
menu_lvl1.Append(menuitem_lvl1)
|
||||
|
||||
return m
|
||||
# Separator
|
||||
if self.userImplantSets and self.structedImplantSets:
|
||||
menu_lvl1.AppendSeparator()
|
||||
|
||||
# Saved sets
|
||||
if self.userImplantSets:
|
||||
menuitem_lvl1 = self._addCategory(rootMenu, 'Saved Sets')
|
||||
menu_lvl2 = wx.Menu()
|
||||
for implantSet in sorted(self.userImplantSets, key=lambda i: i.name):
|
||||
menuitem_lvl2 = self._addSet(rootMenu if msw else menu_lvl1, implantSet, implantSet.name)
|
||||
menu_lvl2.Append(menuitem_lvl2)
|
||||
menu_lvl2.Bind(wx.EVT_MENU, self.handleSelection)
|
||||
menuitem_lvl1.SetSubMenu(menu_lvl2)
|
||||
menu_lvl1.Append(menuitem_lvl1)
|
||||
|
||||
menu_lvl1.Bind(wx.EVT_MENU, self.handleSelection)
|
||||
return menu_lvl1
|
||||
|
||||
def handleSelection(self, event):
|
||||
impSet = self.idmap.get(event.Id, None)
|
||||
impSet = self.eventSetMap.get(event.Id, None)
|
||||
if impSet is None:
|
||||
event.Skip()
|
||||
return
|
||||
|
||||
self.callingWindow.addImplantSet(impSet)
|
||||
if isinstance(impSet, str):
|
||||
implants = PrecalcedImplantSets.stringToImplants(impSet)
|
||||
else:
|
||||
implants = impSet.implants
|
||||
self.callingWindow.addImplants(implants)
|
||||
|
||||
|
||||
ImplantSetApply.register()
|
||||
|
||||
@@ -26,7 +26,7 @@ class TargetProfileAdder(ContextMenuUnconditional):
|
||||
return 'Add Target Profile'
|
||||
|
||||
def handleProfileAdd(self, event):
|
||||
profile = self.profileEventMap.get(event.Id, False)
|
||||
profile = self.eventProfileMap.get(event.Id, False)
|
||||
if profile is False:
|
||||
event.Skip()
|
||||
return
|
||||
@@ -34,7 +34,7 @@ class TargetProfileAdder(ContextMenuUnconditional):
|
||||
|
||||
def _addProfile(self, parentMenu, profile, name):
|
||||
id = ContextMenuUnconditional.nextID()
|
||||
self.profileEventMap[id] = profile
|
||||
self.eventProfileMap[id] = profile
|
||||
menuItem = wx.MenuItem(parentMenu, id, name)
|
||||
parentMenu.Bind(wx.EVT_MENU, self.handleProfileAdd, menuItem)
|
||||
return menuItem
|
||||
@@ -51,7 +51,7 @@ class TargetProfileAdder(ContextMenuUnconditional):
|
||||
profiles = list(chain(sTR.getBuiltinTargetProfileList(), sTR.getUserTargetProfileList()))
|
||||
profiles.sort(key=lambda p: smartSort(p.fullName))
|
||||
|
||||
self.profileEventMap = {}
|
||||
self.eventProfileMap = {}
|
||||
items = (OrderedDict(), OrderedDict())
|
||||
for profile in profiles:
|
||||
container = items
|
||||
|
||||
@@ -25,7 +25,7 @@ class PFGeneralPref(PreferenceView):
|
||||
self.stTitle.Wrap(-1)
|
||||
self.stTitle.SetFont(wx.Font(12, 70, 90, 90, False, wx.EmptyString))
|
||||
mainSizer.Add(self.stTitle, 0, wx.EXPAND | wx.ALL, 5)
|
||||
|
||||
|
||||
helpCursor = wx.Cursor(wx.CURSOR_QUESTION_ARROW)
|
||||
|
||||
self.m_staticline1 = wx.StaticLine(panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL)
|
||||
|
||||
@@ -608,6 +608,18 @@ class Miscellanea(ViewColumn):
|
||||
shield_hp = stuff.getModifiedItemAttr("shieldBonus", 0)
|
||||
hp = max(stuff_hp, armor_hp * cycles, capacitor_hp * cycles, shield_hp * cycles, 0)
|
||||
|
||||
nonChargedMap = {
|
||||
"Ancillary Remote Armor Repairer": ("armor", "Armor repaired per second"),
|
||||
"Ancillary Remote Shield Booster": ("shield", "Shield transferred per second")}
|
||||
if not cycles and itemGroup in nonChargedMap:
|
||||
rps = stuff.getRemoteReps(ignoreState=True)
|
||||
rps = getattr(rps, nonChargedMap[itemGroup][0])
|
||||
if not rps:
|
||||
return "", None
|
||||
text = "{0}/s".format(formatAmount(rps, 3, 0, 3, forceSign=True))
|
||||
tooltip = nonChargedMap[itemGroup][1]
|
||||
return text, tooltip
|
||||
|
||||
if not hp or not cycleTime or not cycles:
|
||||
return "", None
|
||||
|
||||
|
||||
@@ -729,12 +729,12 @@ class ImplantEditorView(BaseImplantEditorView):
|
||||
|
||||
sChar.removeImplant(char.ID, implant)
|
||||
|
||||
def addImplantSet(self, impSet):
|
||||
def addImplants(self, implants):
|
||||
charEditor = self.Parent.Parent
|
||||
char = charEditor.entityEditor.getActiveEntity()
|
||||
|
||||
sChar = Character.getInstance()
|
||||
for implant in impSet.implants:
|
||||
for implant in implants:
|
||||
sChar.addImplant(char.ID, implant.item.ID)
|
||||
|
||||
wx.PostEvent(charEditor, GE.CharChanged())
|
||||
|
||||
@@ -678,8 +678,8 @@ class MainFrame(wx.Frame):
|
||||
|
||||
def toggleOverrides(self, event):
|
||||
ModifiedAttributeDict.overrides_enabled = not ModifiedAttributeDict.overrides_enabled
|
||||
|
||||
wx.PostEvent(self, GE.FitChanged(fitIDs=(self.getActiveFit(),)))
|
||||
changedFitIDs = Fit.getInstance().processOverrideToggle()
|
||||
wx.PostEvent(self, GE.FitChanged(fitIDs=changedFitIDs))
|
||||
menu = self.GetMenuBar()
|
||||
menu.SetLabel(menu.toggleOverridesId,
|
||||
"&Turn Overrides Off" if ModifiedAttributeDict.overrides_enabled else "&Turn Overrides On")
|
||||
|
||||
@@ -67,7 +67,8 @@ class DmgPatternEntityEditor(EntityEditor):
|
||||
def getEntitiesFromContext(self):
|
||||
sDP = DamagePattern.getInstance()
|
||||
choices = sorted(sDP.getUserDamagePatternList(), key=lambda p: p.rawName)
|
||||
return [c for c in choices if c.rawName != "Selected Ammo"]
|
||||
choices = [c for c in choices if c.rawName != "Selected Ammo"]
|
||||
return choices
|
||||
|
||||
def DoNew(self, name):
|
||||
sDP = DamagePattern.getInstance()
|
||||
@@ -183,6 +184,10 @@ class DmgPatternEditor(AuxiliaryFrame):
|
||||
footerSizer.Add(btn, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_RIGHT)
|
||||
btn.Bind(wx.EVT_BUTTON, getattr(self, "{}Patterns".format(name.lower())))
|
||||
|
||||
if not self.entityEditor.checkEntitiesExist():
|
||||
self.Close()
|
||||
return
|
||||
|
||||
self.Layout()
|
||||
bsize = self.GetBestSize()
|
||||
self.SetSize((-1, bsize.height))
|
||||
@@ -232,6 +237,11 @@ class DmgPatternEditor(AuxiliaryFrame):
|
||||
self.entityEditor.btnDelete.Enable()
|
||||
|
||||
def patternChanged(self, event=None):
|
||||
|
||||
if not self.entityEditor.checkEntitiesExist():
|
||||
self.Close()
|
||||
return
|
||||
|
||||
p = self.entityEditor.getActiveEntity()
|
||||
|
||||
if p is None:
|
||||
|
||||
@@ -25,12 +25,12 @@ from collections import OrderedDict
|
||||
import wx
|
||||
from logbook import Logger
|
||||
|
||||
import gui.mainFrame
|
||||
import gui.globalEvents as GE
|
||||
import gui.mainFrame
|
||||
from gui.auxFrame import AuxiliaryFrame
|
||||
from gui.bitmap_loader import BitmapLoader
|
||||
from gui.builtinViews.entityEditor import EntityEditor, BaseValidator
|
||||
from gui.utils.clipboard import toClipboard, fromClipboard
|
||||
from gui.builtinViews.entityEditor import BaseValidator, EntityEditor
|
||||
from gui.utils.clipboard import fromClipboard, toClipboard
|
||||
from gui.utils.inputs import FloatBox, InputValidator, strToFloat
|
||||
from service.fit import Fit
|
||||
from service.targetProfile import TargetProfile
|
||||
|
||||
|
Before Width: | Height: | Size: 926 B After Width: | Height: | Size: 590 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 825 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 779 B |
|
Before Width: | Height: | Size: 824 B After Width: | Height: | Size: 585 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 913 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 778 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 732 B |
|
Before Width: | Height: | Size: 779 B After Width: | Height: | Size: 449 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 852 B |
|
Before Width: | Height: | Size: 740 B After Width: | Height: | Size: 438 B |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 897 B After Width: | Height: | Size: 693 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 137 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 138 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 138 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 142 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 142 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 141 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 141 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 142 B |
|
Before Width: | Height: | Size: 870 B After Width: | Height: | Size: 577 B |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 609 B After Width: | Height: | Size: 305 B |
|
Before Width: | Height: | Size: 336 B After Width: | Height: | Size: 153 B |
|
Before Width: | Height: | Size: 325 B After Width: | Height: | Size: 113 B |
|
Before Width: | Height: | Size: 253 B After Width: | Height: | Size: 72 B |
|
Before Width: | Height: | Size: 316 B After Width: | Height: | Size: 109 B |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 936 B After Width: | Height: | Size: 669 B |
|
Before Width: | Height: | Size: 385 B After Width: | Height: | Size: 172 B |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 810 B After Width: | Height: | Size: 561 B |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1023 B |
|
Before Width: | Height: | Size: 926 B After Width: | Height: | Size: 633 B |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 975 B |
|
Before Width: | Height: | Size: 951 B After Width: | Height: | Size: 691 B |
BIN
imgs/gui/eve.png
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 952 B |
|
Before Width: | Height: | Size: 989 B After Width: | Height: | Size: 780 B |
|
Before Width: | Height: | Size: 932 B After Width: | Height: | Size: 697 B |
|
Before Width: | Height: | Size: 829 B After Width: | Height: | Size: 530 B |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 606 B |
|
Before Width: | Height: | Size: 877 B After Width: | Height: | Size: 640 B |
|
Before Width: | Height: | Size: 847 B After Width: | Height: | Size: 625 B |
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 943 B After Width: | Height: | Size: 435 B |
|
Before Width: | Height: | Size: 750 B After Width: | Height: | Size: 531 B |
|
Before Width: | Height: | Size: 806 B After Width: | Height: | Size: 577 B |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 510 B After Width: | Height: | Size: 184 B |
|
Before Width: | Height: | Size: 809 B After Width: | Height: | Size: 415 B |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 343 B After Width: | Height: | Size: 121 B |
|
Before Width: | Height: | Size: 514 B After Width: | Height: | Size: 255 B |
|
Before Width: | Height: | Size: 500 B After Width: | Height: | Size: 175 B |
|
Before Width: | Height: | Size: 686 B After Width: | Height: | Size: 345 B |
|
Before Width: | Height: | Size: 793 B After Width: | Height: | Size: 706 B |
|
Before Width: | Height: | Size: 816 B After Width: | Height: | Size: 524 B |
|
Before Width: | Height: | Size: 825 B After Width: | Height: | Size: 534 B |
|
Before Width: | Height: | Size: 738 B After Width: | Height: | Size: 497 B |
|
Before Width: | Height: | Size: 652 B After Width: | Height: | Size: 373 B |
|
Before Width: | Height: | Size: 817 B After Width: | Height: | Size: 617 B |
|
Before Width: | Height: | Size: 762 B After Width: | Height: | Size: 715 B |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.3 KiB |