Merge branch 'master' into py3EFFS
This commit is contained in:
@@ -24,10 +24,10 @@ saveInRoot = False
|
||||
|
||||
# Version data
|
||||
|
||||
version = "2.2.0b1"
|
||||
tag = "git"
|
||||
expansionName = "Into the Abyss"
|
||||
expansionVersion = "1.1"
|
||||
version = "2.3.0"
|
||||
tag = "Stable"
|
||||
expansionName = "YC120.7"
|
||||
expansionVersion = "1.2"
|
||||
evemonMinVersion = "4081"
|
||||
|
||||
minItemSearchLength = 3
|
||||
|
||||
@@ -73,4 +73,7 @@ exe = EXE(pyz,
|
||||
app = BUNDLE(exe,
|
||||
name='pyfa.app',
|
||||
icon=icon,
|
||||
bundle_identifier=None)
|
||||
bundle_identifier=None,
|
||||
info_plist={
|
||||
'NSHighResolutionCapable': 'True'
|
||||
})
|
||||
|
||||
@@ -38,8 +38,7 @@ dynamicAttributes_table = Table("mutaplasmidAttributes", gamedata_meta,
|
||||
|
||||
dynamicApplicable_table = Table("mutaplasmidItems", gamedata_meta,
|
||||
Column("typeID", ForeignKey("mutaplasmids.typeID"), primary_key=True),
|
||||
Column("applicableTypeID", ForeignKey("invtypes.typeID"), primary_key=True),
|
||||
)
|
||||
Column("applicableTypeID", ForeignKey("invtypes.typeID"), primary_key=True),)
|
||||
|
||||
mapper(DynamicItem, dynamic_table, properties={
|
||||
"attributes": relation(DynamicItemAttribute),
|
||||
|
||||
@@ -63,8 +63,7 @@ mapper(Item, items_table,
|
||||
primaryjoin=dynamicApplicable_table.c.applicableTypeID == items_table.c.typeID,
|
||||
secondaryjoin=dynamicApplicable_table.c.typeID == DynamicItem.typeID,
|
||||
secondary=dynamicApplicable_table,
|
||||
backref="applicableItems"
|
||||
)
|
||||
backref="applicableItems")
|
||||
})
|
||||
|
||||
Item.category = association_proxy("group", "category")
|
||||
|
||||
@@ -127,6 +127,7 @@ def getItemWithBaseItemAttribute(lookfor, baseItemID, eager=None):
|
||||
gamedata_session.expunge(item)
|
||||
return item
|
||||
|
||||
|
||||
@cachedQuery(1, "lookfor")
|
||||
def getItems(lookfor, eager=None):
|
||||
"""
|
||||
|
||||
@@ -56,7 +56,7 @@ fits_table = Table("fits", saveddata_meta,
|
||||
Column("booster", Boolean, nullable=False, index=True, default=0),
|
||||
Column("targetResistsID", ForeignKey("targetResists.ID"), nullable=True),
|
||||
Column("modeID", Integer, nullable=True),
|
||||
Column("implantLocation", Integer, nullable=True),
|
||||
Column("implantLocation", Integer, nullable=False),
|
||||
Column("notes", String, nullable=True),
|
||||
Column("ignoreRestrictions", Boolean, default=0),
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||
|
||||
@@ -29,7 +29,6 @@ mutator_table = Table("mutators", saveddata_meta,
|
||||
Column("attrID", Integer, primary_key=True, index=True),
|
||||
Column("value", Float, nullable=False),
|
||||
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now)
|
||||
)
|
||||
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now))
|
||||
|
||||
mapper(Mutator, mutator_table)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# armorAllRepairSystemsAmountBonusPassive
|
||||
#
|
||||
# Used by:
|
||||
# Implants named like: Agency 'Hardshell' TB Dose (3 of 4)
|
||||
# Implants named like: Agency 'Hardshell' TB Dose (4 of 4)
|
||||
# Implants named like: Exile Booster (4 of 4)
|
||||
# Implant: Antipharmakon Kosybo
|
||||
type = "passive"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# boosterMaxVelocityPenalty
|
||||
#
|
||||
# Used by:
|
||||
# Implants named like: Booster (12 of 33)
|
||||
# Implants named like: Crash Booster (3 of 4)
|
||||
# Items from market group: Implants & Boosters > Booster > Booster Slot 02 (9 of 13)
|
||||
type = "boosterSideEffect"
|
||||
|
||||
# User-friendly name for the side effect
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# boosterShieldCapacityPenalty
|
||||
#
|
||||
# Used by:
|
||||
# Implants named like: Booster (12 of 33)
|
||||
# Implants from group: Booster (12 of 66)
|
||||
type = "boosterSideEffect"
|
||||
|
||||
# User-friendly name for the side effect
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# capacitorCapacityBonus
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Capacitor Battery (27 of 27)
|
||||
# Modules from group: Capacitor Battery (30 of 30)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# energyNosferatuFalloff
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Energy Nosferatu (51 of 51)
|
||||
# Modules from group: Energy Nosferatu (54 of 54)
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict
|
||||
|
||||
type = "active", "projected"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# missileSkillWarheadUpgradesEmDamageBonus
|
||||
#
|
||||
# Used by:
|
||||
# Implants named like: Agency 'Pyrolancea' DB Dose (3 of 4)
|
||||
# Implants named like: Agency 'Pyrolancea' DB Dose (4 of 4)
|
||||
# Skill: Warhead Upgrades
|
||||
type = "passive"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# missileSkillWarheadUpgradesExplosiveDamageBonus
|
||||
#
|
||||
# Used by:
|
||||
# Implants named like: Agency 'Pyrolancea' DB Dose (3 of 4)
|
||||
# Implants named like: Agency 'Pyrolancea' DB Dose (4 of 4)
|
||||
# Skill: Warhead Upgrades
|
||||
type = "passive"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# missileSkillWarheadUpgradesKineticDamageBonus
|
||||
#
|
||||
# Used by:
|
||||
# Implants named like: Agency 'Pyrolancea' DB Dose (3 of 4)
|
||||
# Implants named like: Agency 'Pyrolancea' DB Dose (4 of 4)
|
||||
# Skill: Warhead Upgrades
|
||||
type = "passive"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# missileSkillWarheadUpgradesThermalDamageBonus
|
||||
#
|
||||
# Used by:
|
||||
# Implants named like: Agency 'Pyrolancea' DB Dose (3 of 4)
|
||||
# Implants named like: Agency 'Pyrolancea' DB Dose (4 of 4)
|
||||
# Skill: Warhead Upgrades
|
||||
type = "passive"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# modifyEnergyWarfareResistance
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Capacitor Battery (27 of 27)
|
||||
# Modules from group: Capacitor Battery (30 of 30)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Rig Anchor (4 of 4)
|
||||
# Implants named like: Agency 'Overclocker' SB Dose (3 of 4)
|
||||
# Implants named like: Agency 'Overclocker' SB Dose (4 of 4)
|
||||
# Implants named like: grade Snake (16 of 18)
|
||||
# Modules named like: Auxiliary Thrusters (8 of 8)
|
||||
# Implant: Quafe Zero
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Modules from group: Capacitor Booster (59 of 59)
|
||||
# Modules from group: Energy Neutralizer (54 of 54)
|
||||
# Modules from group: Energy Nosferatu (51 of 51)
|
||||
# Modules from group: Energy Nosferatu (54 of 54)
|
||||
# Modules from group: Hull Repair Unit (25 of 25)
|
||||
# Modules from group: Remote Armor Repairer (39 of 39)
|
||||
# Modules from group: Remote Capacitor Transmitter (41 of 41)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# shieldBoostAmplifierPassiveBooster
|
||||
#
|
||||
# Used by:
|
||||
# Implants named like: Agency 'Hardshell' TB Dose (3 of 4)
|
||||
# Implants named like: Agency 'Hardshell' TB Dose (4 of 4)
|
||||
# Implants named like: Blue Pill Booster (5 of 5)
|
||||
# Implant: Antipharmakon Thureo
|
||||
type = "passive"
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
# shipPDmgBonusMF
|
||||
#
|
||||
# Used by:
|
||||
# Variations of ship: Slasher (3 of 3)
|
||||
# Ship: Cheetah
|
||||
# Ship: Freki
|
||||
# Ship: Republic Fleet Firetail
|
||||
# Ship: Rifter
|
||||
# Ship: Slasher
|
||||
# Ship: Stiletto
|
||||
# Ship: Wolf
|
||||
type = "passive"
|
||||
|
||||
|
||||
10
eos/effects/shipprojectilerofmf.py
Normal file
10
eos/effects/shipprojectilerofmf.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# shipProjectileRofMF
|
||||
#
|
||||
# Used by:
|
||||
# Ship: Claw
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Small Projectile Turret"), "speed",
|
||||
src.getModifiedItemAttr("shipBonusMF"), stackingPenalties=True, skill="Minmatar Frigate")
|
||||
@@ -1,8 +1,7 @@
|
||||
# skillBonusDroneDurability
|
||||
#
|
||||
# Used by:
|
||||
# Implant: CreoDron 'Bumblebee' Drone Tuner T10-5D
|
||||
# Implant: CreoDron 'Yellowjacket' Drone Tuner D5-10T
|
||||
# Implants from group: Cyber Drones (2 of 2)
|
||||
# Skill: Drone Durability
|
||||
type = "passive"
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
# skillBonusDroneInterfacing
|
||||
#
|
||||
# Used by:
|
||||
# Implant: CreoDron 'Bumblebee' Drone Tuner T10-5D
|
||||
# Implant: CreoDron 'Yellowjacket' Drone Tuner D5-10T
|
||||
# Implants from group: Cyber Drones (2 of 2)
|
||||
# Skill: Drone Interfacing
|
||||
type = "passive"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# surgicalStrikeDamageMultiplierBonusPostPercentDamageMultiplierLocationShipModulesRequiringGunnery
|
||||
#
|
||||
# Used by:
|
||||
# Implants named like: Agency 'Pyrolancea' DB Dose (3 of 4)
|
||||
# Implants named like: Agency 'Pyrolancea' DB Dose (4 of 4)
|
||||
# Implants named like: Eifyr and Co. 'Gunslinger' Surgical Strike SS (6 of 6)
|
||||
# Implant: Standard Cerebral Accelerator
|
||||
type = "passive"
|
||||
|
||||
@@ -536,6 +536,7 @@ class DynamicItemAttribute(EqBase):
|
||||
class DynamicItemItem(EqBase):
|
||||
pass
|
||||
|
||||
|
||||
class MarketGroup(EqBase):
|
||||
def __repr__(self):
|
||||
return "MarketGroup(ID={}, name={}, parent={}) at {}".format(
|
||||
|
||||
@@ -42,6 +42,7 @@ class ItemAttrShortcut(object):
|
||||
|
||||
return return_value or default
|
||||
|
||||
|
||||
class ChargeAttrShortcut(object):
|
||||
def getModifiedChargeAttr(self, key, default=0):
|
||||
return_value = self.chargeModifiedAttributes.get(key)
|
||||
|
||||
@@ -142,14 +142,8 @@ class Booster(HandledItem, ItemAttrShortcut):
|
||||
copy = Booster(self.item)
|
||||
copy.active = self.active
|
||||
|
||||
# Legacy booster side effect code, disabling as not currently implemented
|
||||
'''
|
||||
origSideEffects = list(self.iterSideEffects())
|
||||
copySideEffects = list(copy.iterSideEffects())
|
||||
i = 0
|
||||
while i < len(origSideEffects):
|
||||
copySideEffects[i].active = origSideEffects[i].active
|
||||
i += 1
|
||||
'''
|
||||
for sideEffect in self.sideEffects:
|
||||
copyEffect = next(filter(lambda eff: eff.effectID == sideEffect.effectID, copy.sideEffects))
|
||||
copyEffect.active = sideEffect.active
|
||||
|
||||
return copy
|
||||
|
||||
@@ -291,6 +291,10 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
def __deepcopy__(self, memo):
|
||||
copy = Fighter(self.item)
|
||||
copy.amount = self.amount
|
||||
copy.active = self.active
|
||||
for ability in self.abilities:
|
||||
copyAbility = next(filter(lambda a: a.effectID == ability.effectID, copy.abilities))
|
||||
copyAbility.active = ability.active
|
||||
return copy
|
||||
|
||||
def fits(self, fit):
|
||||
|
||||
@@ -1580,6 +1580,7 @@ class Fit(object):
|
||||
copy_ship.name = "%s copy" % self.name
|
||||
copy_ship.damagePattern = self.damagePattern
|
||||
copy_ship.targetResists = self.targetResists
|
||||
copy_ship.implantLocation = self.implantLocation
|
||||
copy_ship.notes = self.notes
|
||||
|
||||
toCopy = (
|
||||
@@ -1598,12 +1599,27 @@ class Fit(object):
|
||||
for i in orig:
|
||||
c.append(deepcopy(i))
|
||||
|
||||
for fit in self.projectedFits:
|
||||
copy_ship.__projectedFits[fit.ID] = fit
|
||||
# this bit is required -- see GH issue # 83
|
||||
# this bit is required -- see GH issue # 83
|
||||
def forceUpdateSavedata(fit):
|
||||
eos.db.saveddata_session.flush()
|
||||
eos.db.saveddata_session.refresh(fit)
|
||||
|
||||
for fit in self.commandFits:
|
||||
copy_ship.__commandFits[fit.ID] = fit
|
||||
forceUpdateSavedata(fit)
|
||||
copyCommandInfo = fit.getCommandInfo(copy_ship.ID)
|
||||
originalCommandInfo = fit.getCommandInfo(self.ID)
|
||||
copyCommandInfo.active = originalCommandInfo.active
|
||||
forceUpdateSavedata(fit)
|
||||
|
||||
for fit in self.projectedFits:
|
||||
copy_ship.__projectedFits[fit.ID] = fit
|
||||
forceUpdateSavedata(fit)
|
||||
copyProjectionInfo = fit.getProjectionInfo(copy_ship.ID)
|
||||
originalProjectionInfo = fit.getProjectionInfo(self.ID)
|
||||
copyProjectionInfo.active = originalProjectionInfo.active
|
||||
forceUpdateSavedata(fit)
|
||||
|
||||
return copy_ship
|
||||
|
||||
def __repr__(self):
|
||||
|
||||
@@ -177,7 +177,6 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
self.__chargeModifiedAttributes.original = self.__charge.attributes
|
||||
self.__chargeModifiedAttributes.overrides = self.__charge.overrides
|
||||
|
||||
|
||||
@classmethod
|
||||
def buildEmpty(cls, slot):
|
||||
empty = Module(None)
|
||||
@@ -209,7 +208,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
return self.__item is None or \
|
||||
(self.__item.category.name not in ("Module", "Subsystem", "Structure Module") and
|
||||
self.__item.group.name not in self.SYSTEM_GROUPS) or \
|
||||
(self.item.isAbyssal and (not self.baseItemID or not self.mutaplasmidID) )
|
||||
(self.item.isAbyssal and (not self.baseItemID or not self.mutaplasmidID))
|
||||
|
||||
@property
|
||||
def isMutated(self):
|
||||
|
||||
@@ -79,7 +79,7 @@ class Mutator(EqBase):
|
||||
@validates("value")
|
||||
def validator(self, key, val):
|
||||
""" Validates values as properly falling within the range of the modules' Mutaplasmid """
|
||||
mod = val/self.baseValue
|
||||
mod = val / self.baseValue
|
||||
|
||||
if self.minMod <= mod <= self.maxMod:
|
||||
# sweet, all good
|
||||
@@ -129,5 +129,3 @@ class Mutator(EqBase):
|
||||
@property
|
||||
def attribute(self):
|
||||
return self.__attr
|
||||
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ class AttributeGauge(wx.Window):
|
||||
def SetValue(self, value, animate=True):
|
||||
""" Sets the current position of the gauge. """
|
||||
|
||||
print ("="*20, self._percentage)
|
||||
print("=" * 20, self._percentage)
|
||||
if self._value == value:
|
||||
return
|
||||
|
||||
@@ -248,14 +248,15 @@ class AttributeGauge(wx.Window):
|
||||
w = min(w, half) # Ensure that we don't overshoot our drawing area
|
||||
w = math.ceil(w) # round up to nearest pixel, this ensures that we don't lose representation for sub pixels
|
||||
|
||||
# print("Percentage: {}\t\t\t\t\tValue: {}\t\t\t\t\tWidth: {}\t\t\t\t\tHalf: {}\t\t\t\t\tRect Width: {}".format(round(self._percentage, 3), round(value,3), w, half, rect.width))
|
||||
# print("Percentage: {}\t\t\t\t\tValue: {}\t\t\t\t\tWidth: {}\t\t\t\t\tHalf: {}\t\t\t\t\tRect Width: {}".format(
|
||||
# round(self._percentage, 3), round(value,3), w, half, rect.width))
|
||||
|
||||
# set guide_lines every 10 pixels of the main gauge (not including borders)
|
||||
if self.guide_lines:
|
||||
for x in range(1, 20):
|
||||
dc.SetBrush(wx.Brush(wx.LIGHT_GREY))
|
||||
dc.SetPen(wx.Pen(wx.LIGHT_GREY))
|
||||
dc.DrawRectangle(x*10, 1, 1, rect.height)
|
||||
dc.DrawRectangle(x * 10, 1, 1, rect.height)
|
||||
|
||||
dc.SetBrush(wx.Brush(colour))
|
||||
dc.SetPen(wx.Pen(colour))
|
||||
@@ -264,10 +265,10 @@ class AttributeGauge(wx.Window):
|
||||
# However, if there is an odd width, the middle pixel is shared between the left and right gauge
|
||||
|
||||
if value >= 0:
|
||||
padding = (half if is_even else math.ceil(half-1)) + 1
|
||||
padding = (half if is_even else math.ceil(half - 1)) + 1
|
||||
dc.DrawRectangle(padding, 1, w, rect.height)
|
||||
else:
|
||||
padding = half - w + 1 if is_even else math.ceil(half)-(w-1)
|
||||
padding = half - w + 1 if is_even else math.ceil(half) - (w - 1)
|
||||
dc.DrawRectangle(padding, 1, w, rect.height)
|
||||
|
||||
if self.leading_edge and (self.edge_on_neutral or value != 0):
|
||||
@@ -277,7 +278,7 @@ class AttributeGauge(wx.Window):
|
||||
if value > 0:
|
||||
dc.DrawRectangle(min(padding + w, rect.width), 1, 1, rect.height)
|
||||
else:
|
||||
dc.DrawRectangle(max(padding-1, 1), 1, 1, rect.height)
|
||||
dc.DrawRectangle(max(padding - 1, 1), 1, 1, rect.height)
|
||||
|
||||
def OnTimer(self, event):
|
||||
old_value = self._old_percentage
|
||||
@@ -332,14 +333,12 @@ if __name__ == "__main__":
|
||||
wx.Panel.__init__(self, parent, size=size)
|
||||
box = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
font = wx.Font(9, wx.SWISS, wx.NORMAL, wx.NORMAL, False)
|
||||
|
||||
self.gauge = gauge = AttributeGauge(self, size=(204, 4))
|
||||
gauge.SetBackgroundColour(wx.Colour(52, 86, 98))
|
||||
gauge.SetBarColour(wx.Colour(255, 128, 0))
|
||||
gauge.SetValue(100)
|
||||
gauge.SetFractionDigits(1)
|
||||
box.Add(gauge, 0, wx.ALL|wx.CENTER, 10)
|
||||
box.Add(gauge, 0, wx.ALL | wx.CENTER, 10)
|
||||
|
||||
self.gauge11 = gauge = AttributeGauge(self, size=(204, 6))
|
||||
gauge.SetBackgroundColour(wx.Colour(52, 86, 98))
|
||||
@@ -473,16 +472,16 @@ if __name__ == "__main__":
|
||||
def UpdateValue2(self, event):
|
||||
num = self.spinCtrl2.GetValue()
|
||||
self.gauge2.SetValue(num)
|
||||
self.gauge3.SetValue(num*-1)
|
||||
self.gauge3.SetValue(num * -1)
|
||||
self.gauge4.SetValue(num)
|
||||
self.gauge5.SetValue(num*-1)
|
||||
self.gauge5.SetValue(num * -1)
|
||||
self.gauge6.SetValue(num)
|
||||
self.gauge7.SetValue(num*-1)
|
||||
self.gauge7.SetValue(num * -1)
|
||||
self.gauge8.SetValue(num)
|
||||
self.gauge9.SetValue(num*-1)
|
||||
self.gauge9.SetValue(num * -1)
|
||||
|
||||
def OnTimer(self, evt):
|
||||
num = random.randint(-100,100)
|
||||
num = random.randint(-100, 100)
|
||||
self.gauge.SetValue(num)
|
||||
self.gauge11.SetValue(num)
|
||||
self.gauge12.SetValue(num)
|
||||
|
||||
@@ -100,10 +100,10 @@ class AttributeSlider(wx.Panel):
|
||||
slider_percentage = 0
|
||||
if mod < 1:
|
||||
modEnd = self.UserMinValue
|
||||
slider_percentage = (1-mod)/(1 - modEnd) * -100
|
||||
slider_percentage = (1 - mod) / (1 - modEnd) * -100
|
||||
elif mod > 1:
|
||||
modEnd = self.UserMaxValue
|
||||
slider_percentage = ((mod-1)/(modEnd-1)) * 100
|
||||
slider_percentage = ((mod - 1) / (modEnd - 1)) * 100
|
||||
# print(slider_percentage)
|
||||
if self.inverse:
|
||||
slider_percentage *= -1
|
||||
@@ -111,6 +111,7 @@ class AttributeSlider(wx.Panel):
|
||||
if post_event:
|
||||
wx.PostEvent(self, ValueChanged(self, None, value, None, slider_percentage))
|
||||
|
||||
|
||||
class TestAttributeSlider(wx.Frame):
|
||||
|
||||
def __init__(self, parent, id):
|
||||
@@ -245,4 +246,3 @@ if __name__ == "__main__":
|
||||
# else:
|
||||
# self.statxt2.SetLabel("{0:.3f} ({1:+.3f})".format(newValue, newValue - self.base_value, ))
|
||||
# self.statxt2.SetToolTip("{0:+f}%".format(new_mod*100))
|
||||
|
||||
|
||||
@@ -9,13 +9,13 @@ from gui.contextMenu import ContextMenu
|
||||
from .itemAttributes import ItemParams
|
||||
from gui.bitmap_loader import BitmapLoader
|
||||
import gui.globalEvents as GE
|
||||
import gui.mainFrame
|
||||
import random
|
||||
|
||||
from logbook import Logger
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class ItemMutator(wx.Panel):
|
||||
|
||||
def __init__(self, parent, stuff, item):
|
||||
@@ -77,7 +77,6 @@ class ItemMutator(wx.Panel):
|
||||
|
||||
headingSizer.Add(displayName, 3, wx.ALL | wx.EXPAND, 0)
|
||||
|
||||
|
||||
range_low = wx.StaticText(self, wx.ID_ANY, ItemParams.FormatValue(*m.attribute.unit.TranslateValue(worse_range[0])))
|
||||
range_low.SetForegroundColour(self.goodColor if worse_range[2] else self.badColor)
|
||||
|
||||
@@ -168,4 +167,3 @@ class ItemMutator(wx.Panel):
|
||||
|
||||
# Send signal to GUI to update stats with current active fit
|
||||
wx.PostEvent(mainFrame, GE.FitChanged(fitID=activeFit))
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ class PFGeneralPref(PreferenceView):
|
||||
self.sFit = Fit.getInstance()
|
||||
|
||||
self.cbGlobalChar.SetValue(self.sFit.serviceFittingOptions["useGlobalCharacter"])
|
||||
self.cbDefaultCharImplants.SetValue(self.sFit.serviceFittingOptions["useCharecterImplantsByDefault"])
|
||||
self.cbDefaultCharImplants.SetValue(self.sFit.serviceFittingOptions["useCharacterImplantsByDefault"])
|
||||
self.cbGlobalDmgPattern.SetValue(self.sFit.serviceFittingOptions["useGlobalDamagePattern"])
|
||||
self.cbFitColorSlots.SetValue(self.sFit.serviceFittingOptions["colorFitBySlot"] or False)
|
||||
self.cbRackSlots.SetValue(self.sFit.serviceFittingOptions["rackSlots"] or False)
|
||||
@@ -194,7 +194,7 @@ class PFGeneralPref(PreferenceView):
|
||||
event.Skip()
|
||||
|
||||
def OnCBDefaultCharImplantsStateChange(self, event):
|
||||
self.sFit.serviceFittingOptions["useCharecterImplantsByDefault"] = self.cbDefaultCharImplants.GetValue()
|
||||
self.sFit.serviceFittingOptions["useCharacterImplantsByDefault"] = self.cbDefaultCharImplants.GetValue()
|
||||
event.Skip()
|
||||
|
||||
def OnCBGlobalDmgPatternStateChange(self, event):
|
||||
|
||||
@@ -130,7 +130,7 @@ class PyGauge(wx.Window):
|
||||
return self._max_range
|
||||
|
||||
def Animate(self):
|
||||
#sFit = Fit.getInstance()
|
||||
# sFit = Fit.getInstance()
|
||||
if True:
|
||||
if not self._timer:
|
||||
self._timer = wx.Timer(self, self._timer_id)
|
||||
|
||||
@@ -238,8 +238,8 @@ class exportHtmlThread(threading.Thread):
|
||||
HTML += (
|
||||
' <li data-role="collapsible" data-iconpos="right" data-shadow="false" data-corners="false">\n'
|
||||
' <h2>' + group.groupName + ' <span class="ui-li-count">' + str(groupFits) + '</span></h2>\n'
|
||||
' <ul data-role="listview" data-shadow="false" data-inset="true" data-corners="false">\n'
|
||||
+ HTMLgroup +
|
||||
' <ul data-role="listview" data-shadow="false" data-inset="true" data-corners="false">\n' +
|
||||
HTMLgroup +
|
||||
' </ul>\n'
|
||||
' </li>'
|
||||
)
|
||||
|
||||
BIN
imgs/icons/21000.png
Normal file
BIN
imgs/icons/21000.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 695 B |
BIN
imgs/icons/21833.png
Normal file
BIN
imgs/icons/21833.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 769 B |
BIN
imgs/icons/21988.png
Normal file
BIN
imgs/icons/21988.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 767 B |
BIN
imgs/icons/21999.png
Normal file
BIN
imgs/icons/21999.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 756 B |
BIN
imgs/icons/22010.png
Normal file
BIN
imgs/icons/22010.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 797 B |
80
scripts/dynamicattributes.py
Normal file
80
scripts/dynamicattributes.py
Normal file
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env python2.7
|
||||
|
||||
"""
|
||||
This script will generate a dynamicItemAttributes.json file using res files
|
||||
"""
|
||||
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import sqlite3
|
||||
import json
|
||||
|
||||
from PIL import Image
|
||||
|
||||
from shutil import copyfile
|
||||
|
||||
parser = argparse.ArgumentParser(description='This script updates module icons for pyfa')
|
||||
parser.add_argument('-e', '--eve', required=True, type=str, help='path to eve\'s ')
|
||||
parser.add_argument('-s', '--server', required=False, default='tq', type=str, help='which server to use (defaults to tq)')
|
||||
args = parser.parse_args()
|
||||
|
||||
LOADER_FILE = 'app:/bin/dynamicItemAttributesLoader.pyd'
|
||||
RES_FILE = 'res:/staticdata/dynamicitemattributes.fsdbinary'
|
||||
|
||||
binaryfile = os.path.split(RES_FILE)[1]
|
||||
|
||||
eve_path = os.path.join(args.eve, 'index_{}.txt'.format(args.server))
|
||||
with open(eve_path, 'r') as f:
|
||||
lines = f.readlines()
|
||||
file_index = {x.split(',')[0]: x.split(',') for x in lines}
|
||||
|
||||
resfileindex = file_index['app:/resfileindex.txt']
|
||||
|
||||
res_cache = os.path.join(args.eve, 'ResFiles')
|
||||
|
||||
with open(os.path.join(res_cache, resfileindex[1]), 'r') as f:
|
||||
lines = f.readlines()
|
||||
res_index = {x.split(',')[0].lower(): x.split(',') for x in lines}
|
||||
|
||||
# Need to copy the file to our cuirrent directory
|
||||
attribute_loader_file = os.path.join(res_cache, file_index[LOADER_FILE][1])
|
||||
to_path = os.path.dirname(os.path.abspath(__file__))
|
||||
copyfile(attribute_loader_file, os.path.join(os.path.dirname(os.path.abspath(__file__)), os.path.split(LOADER_FILE)[1]))
|
||||
|
||||
# The loader expect it to be the correct filename, so copy trhe file as well
|
||||
dynattribute_file = os.path.join(res_cache, res_index[RES_FILE.lower()][1])
|
||||
to_path = os.path.dirname(os.path.abspath(__file__))
|
||||
copyfile(dynattribute_file, os.path.join(os.path.dirname(os.path.abspath(__file__)), binaryfile))
|
||||
|
||||
import dynamicItemAttributesLoader
|
||||
|
||||
attributes = dynamicItemAttributesLoader.load(os.path.join(to_path, binaryfile))
|
||||
|
||||
attributes_obj = {}
|
||||
|
||||
# convert top level to dict
|
||||
attributes = dict(attributes)
|
||||
|
||||
# This is such a brute force method. todo: recursively generate this by inspecting the objects
|
||||
for k, v in attributes.items():
|
||||
attributes_obj[k] = {
|
||||
'attributeIDs': dict(v.attributeIDs),
|
||||
'inputOutputMapping': list(v.inputOutputMapping)
|
||||
}
|
||||
|
||||
for i, x in enumerate(v.inputOutputMapping):
|
||||
attributes_obj[k]['inputOutputMapping'][i] = {
|
||||
'resultingType': x.resultingType,
|
||||
'applicableTypes': list(x.applicableTypes)
|
||||
}
|
||||
|
||||
for k2, v2 in v.attributeIDs.items():
|
||||
attributes_obj[k]['attributeIDs'][k2] = {
|
||||
'min': v2.min,
|
||||
'max': v2.max
|
||||
}
|
||||
|
||||
with open('dynamicattributes.json', 'w') as outfile:
|
||||
json.dump(attributes_obj, outfile)
|
||||
@@ -62,6 +62,7 @@ class Fit(object):
|
||||
serviceFittingDefaultOptions = {
|
||||
"useCharecterImplantsByDefault": True,
|
||||
"useGlobalCharacter": False,
|
||||
"useCharacterImplantsByDefault": True,
|
||||
"useGlobalDamagePattern": False,
|
||||
"defaultCharacter": self.character.ID,
|
||||
"useGlobalForceReload": False,
|
||||
@@ -96,7 +97,12 @@ class Fit(object):
|
||||
fits = eos.db.getFitsWithShip(shipID)
|
||||
names = []
|
||||
for fit in fits:
|
||||
names.append((fit.ID, fit.name, fit.booster, fit.modified or fit.created or datetime.datetime.fromtimestamp(fit.timestamp), fit.notes, fit.ship.item.graphicID))
|
||||
names.append((fit.ID,
|
||||
fit.name,
|
||||
fit.booster,
|
||||
fit.modified or fit.created or datetime.datetime.fromtimestamp(fit.timestamp),
|
||||
fit.notes,
|
||||
fit.ship.item.graphicID))
|
||||
|
||||
return names
|
||||
|
||||
@@ -148,9 +154,8 @@ class Fit(object):
|
||||
fit.targetResists = self.targetResists
|
||||
fit.character = self.character
|
||||
fit.booster = self.booster
|
||||
fit.implantLocation = ImplantLocation.CHARACTER if\
|
||||
self.serviceFittingOptions["useCharecterImplantsByDefault"] else\
|
||||
ImplantLocation.FIT
|
||||
useCharImplants = self.serviceFittingOptions["useCharacterImplantsByDefault"]
|
||||
fit.implantLocation = ImplantLocation.CHARACTER if useCharImplants else ImplantLocation.FIT
|
||||
eos.db.save(fit)
|
||||
self.recalc(fit)
|
||||
return fit.ID
|
||||
@@ -713,11 +718,11 @@ class Fit(object):
|
||||
|
||||
if not module.isEmpty: # if module is placeholder, we don't want to convert/add it
|
||||
moduleItem = module.item if not module.item.isAbyssal else module.baseItem
|
||||
for x in fit.cargo.find(moduleItem ):
|
||||
for x in fit.cargo.find(moduleItem):
|
||||
x.amount += 1
|
||||
break
|
||||
else:
|
||||
moduleP = es_Cargo(moduleItem )
|
||||
moduleP = es_Cargo(moduleItem)
|
||||
moduleP.amount = 1
|
||||
fit.cargo.insert(cargoIdx, moduleP)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user