Compare commits

...

45 Commits

Author SHA1 Message Date
DarkPhoenix
098b088da6 Bump version 2020-04-07 21:39:24 +03:00
DarkPhoenix
14d62f31e1 Add conversions for names 2020-04-07 21:37:40 +03:00
DarkPhoenix
e7b1f55d08 Update static data to 1702461 2020-04-07 20:59:07 +03:00
DarkPhoenix
8f501896a1 Give separate axis selector and axis label names to make it clearer what the graphs do 2020-04-07 20:37:28 +03:00
DarkPhoenix
befcb9b874 Un-hide and un-fuck bumping graphs 2020-04-07 20:14:06 +03:00
DarkPhoenix
c70afa9a4c Hide experimental bumping graphs 2020-04-07 18:25:40 +03:00
DarkPhoenix
029c7dd4c2 Recalculate fit when overrides are toggled 2020-04-07 18:05:43 +03:00
DarkPhoenix
1f83dba1ac Add missing hidden imports to platform-specific specifications 2020-04-07 18:00:17 +03:00
DarkPhoenix
6eae3405fd Add hidden import for newer version of setuptools 2020-04-07 17:39:24 +03:00
DarkPhoenix
c0e1d9e4de Attempt to use newer version of setuptools 2020-04-07 17:09:59 +03:00
DarkPhoenix
7c0bd7aa88 Leave only setuptools override 2020-04-07 16:41:28 +03:00
DarkPhoenix
394583584c Remove some of hardcoded libraries for MacOS X build 2020-04-07 15:08:30 +03:00
DarkPhoenix
4112e2aa6b Debugging Mac OS X build, step 1 2020-04-07 14:17:55 +03:00
DarkPhoenix
aa19e0da72 Add bunch of experimental graphs related to bumping 2020-04-07 13:46:28 +03:00
DarkPhoenix
bba9be1598 Add momentum graphs 2020-04-07 10:50:12 +03:00
DarkPhoenix
17998916b4 Bump version 2020-04-06 22:24:06 +03:00
DarkPhoenix
543089bcd9 Add context menu support for predefined implant sets 2020-04-06 22:20:28 +03:00
DarkPhoenix
7f35c78a65 Add data about implant sets to eve.db 2020-04-06 21:01:20 +03:00
DarkPhoenix
b25798dd83 Update effects 2020-04-06 20:14:19 +03:00
DarkPhoenix
744b9ff78a Updated staticdata to 1701385 2020-04-06 19:19:06 +03:00
DarkPhoenix
8dc1457ebb Change the way zip file is generated 2020-04-06 15:09:06 +03:00
DarkPhoenix
982ad54fab Merge branch 'Metallicow-optimize-images' 2020-04-06 15:29:10 +03:00
DarkPhoenix
912192cd7d Merge branch 'optimize-images' of https://github.com/Metallicow/Pyfa into Metallicow-optimize-images 2020-04-06 15:26:32 +03:00
DarkPhoenix
74cd6d48da Show propmpt to creade damage patterns when there're none 2020-04-06 11:14:21 +03:00
DarkPhoenix
3467a7fe3f Update static data to 1684558 2020-03-11 17:01:34 +03:00
DarkPhoenix
eb269a05ed Bump version 2020-03-10 19:39:22 +03:00
DarkPhoenix
c63cf4b3b0 Add cap booster conversions 2020-03-10 19:19:13 +03:00
DarkPhoenix
11ed94454d Update staticdata to 1683031 2020-03-10 19:07:42 +03:00
DarkPhoenix
8df07645da Show RR power for uncharged ancillary RRs 2020-03-06 00:50:18 +03:00
DarkPhoenix
5666fdd250 Bump version 2020-02-27 15:24:45 +03:00
DarkPhoenix
0b55ae40fc Update staticdata to 1675961 2020-02-27 15:09:54 +03:00
DarkPhoenix
3726e84697 Add dbuffcollections (just to have overview of changed fleet buffs when stuff changes) 2020-02-20 13:31:18 +03:00
DarkPhoenix
a0c4341102 Fix ECM range rigs affecting ECM bursts with penalty 2020-02-17 23:42:48 +03:00
Metallicow
cd6b1038e8 optimize all pngs 2020-02-13 14:58:27 -06:00
DarkPhoenix
10583fd506 Update fighter additions tab icon 2020-02-13 17:25:40 +03:00
DarkPhoenix
713694be56 Bump version 2020-02-13 17:00:58 +03:00
DarkPhoenix
f50293cf77 Revert to wxpython 4.0.6 once again (see issue 2136) 2020-02-13 16:57:23 +03:00
DarkPhoenix
7c88fa477f Bump version 2020-02-13 12:20:03 +03:00
DarkPhoenix
f8df540fad Use newer wxpython version once again 2020-02-13 12:19:37 +03:00
DarkPhoenix
61a01805cc Reset locale and remove resolution data from all the images (wxpython phoenix issue #1515) 2020-02-13 12:14:26 +03:00
Metallicow
a93915cf04 trim trailing whitespace 2020-02-12 16:14:12 -06:00
DarkPhoenix
0f74c97fbf Temporarily revert python version to 3.7 2020-02-12 18:31:44 +03:00
DarkPhoenix
29713b69dc Fix the hack 2020-02-12 18:25:17 +03:00
DarkPhoenix
cc3c2cb9c8 Add hack to build wx on windows 2020-02-12 18:22:31 +03:00
DarkPhoenix
b36a3959da Revert wxpython version to 4.0.6 2020-02-12 18:18:18 +03:00
3354 changed files with 28023 additions and 2388 deletions

View File

@@ -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

View File

@@ -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()

View File

@@ -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")

View File

@@ -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

View File

@@ -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, \

View File

@@ -1,2 +1,2 @@
__all__ = ["attribute", "category", "effect", "group", "metaData", "dynamicAttributes",
"item", "marketGroup", "metaGroup", "unit", "alphaClones"]
"item", "marketGroup", "metaGroup", "unit", "alphaClones", "implantSet"]

View 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")})

View File

@@ -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

View File

@@ -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")
)
"""

View 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))

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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):

View File

@@ -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()

View File

@@ -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

View File

@@ -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}

View File

@@ -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):

View File

@@ -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

View File

@@ -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):

View File

@@ -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)

View File

@@ -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)

View File

@@ -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]))

View File

@@ -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()

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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())

View File

@@ -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")

View File

@@ -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:

View File

@@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 926 B

After

Width:  |  Height:  |  Size: 590 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 825 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 779 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 824 B

After

Width:  |  Height:  |  Size: 585 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 913 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 778 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 732 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 779 B

After

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 852 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 740 B

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 897 B

After

Width:  |  Height:  |  Size: 693 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 137 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 142 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 142 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 141 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 141 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 142 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 870 B

After

Width:  |  Height:  |  Size: 577 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 609 B

After

Width:  |  Height:  |  Size: 305 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 336 B

After

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 325 B

After

Width:  |  Height:  |  Size: 113 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 253 B

After

Width:  |  Height:  |  Size: 72 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 316 B

After

Width:  |  Height:  |  Size: 109 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 936 B

After

Width:  |  Height:  |  Size: 669 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 385 B

After

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 810 B

After

Width:  |  Height:  |  Size: 561 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1023 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 926 B

After

Width:  |  Height:  |  Size: 633 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 975 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 951 B

After

Width:  |  Height:  |  Size: 691 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 952 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 989 B

After

Width:  |  Height:  |  Size: 780 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 932 B

After

Width:  |  Height:  |  Size: 697 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 829 B

After

Width:  |  Height:  |  Size: 530 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 606 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 877 B

After

Width:  |  Height:  |  Size: 640 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 847 B

After

Width:  |  Height:  |  Size: 625 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 943 B

After

Width:  |  Height:  |  Size: 435 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 750 B

After

Width:  |  Height:  |  Size: 531 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 806 B

After

Width:  |  Height:  |  Size: 577 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 510 B

After

Width:  |  Height:  |  Size: 184 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 809 B

After

Width:  |  Height:  |  Size: 415 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 343 B

After

Width:  |  Height:  |  Size: 121 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 514 B

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 500 B

After

Width:  |  Height:  |  Size: 175 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 686 B

After

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 793 B

After

Width:  |  Height:  |  Size: 706 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 816 B

After

Width:  |  Height:  |  Size: 524 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 825 B

After

Width:  |  Height:  |  Size: 534 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 738 B

After

Width:  |  Height:  |  Size: 497 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 652 B

After

Width:  |  Height:  |  Size: 373 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 817 B

After

Width:  |  Height:  |  Size: 617 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 762 B

After

Width:  |  Height:  |  Size: 715 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Some files were not shown because too many files have changed in this diff Show More