From d09f21fe15ed71a92863cb20351692fd7ae8d3aa Mon Sep 17 00:00:00 2001 From: Michael Ryan Date: Tue, 30 May 2017 20:18:32 -0500 Subject: [PATCH 1/7] updated drag and drop behavior to not trigger a suspected wx bug on Mac --- gui/boosterView.py | 3 ++- gui/builtinViews/fittingView.py | 11 ++++++++--- gui/cargoView.py | 8 ++++++-- gui/commandView.py | 8 ++++++-- gui/droneView.py | 8 ++++++-- gui/fighterView.py | 8 ++++++-- gui/marketBrowser.py | 2 ++ gui/projectedView.py | 8 ++++++-- gui/utils/staticHelpers.py | 5 +++++ 9 files changed, 47 insertions(+), 14 deletions(-) create mode 100644 gui/utils/staticHelpers.py diff --git a/gui/boosterView.py b/gui/boosterView.py index db0e0eba5..98d07753f 100644 --- a/gui/boosterView.py +++ b/gui/boosterView.py @@ -37,7 +37,8 @@ class BoosterViewDrop(wx.PyDropTarget): def OnData(self, x, y, t): if self.GetData(): - data = self.dropData.GetText().split(':') + dragged_data = DragDropHelper.data + data = dragged_data.split(':') self.dropFn(x, y, data) return t diff --git a/gui/builtinViews/fittingView.py b/gui/builtinViews/fittingView.py index 0fde55718..d5dee9608 100644 --- a/gui/builtinViews/fittingView.py +++ b/gui/builtinViews/fittingView.py @@ -38,6 +38,8 @@ from gui.chromeTabs import EVT_NOTEBOOK_PAGE_CHANGED from service.fit import Fit from service.market import Market +from gui.utils.staticHelpers import DragDropHelper + import gui.globalEvents as GE pyfalog = Logger(__name__) @@ -110,8 +112,9 @@ class FittingViewDrop(wx.PyDropTarget): def OnData(self, x, y, t): if self.GetData(): - pyfalog.debug("fittingView: recieved drag: " + self.dropData.GetText()) - data = self.dropData.GetText().split(':') + dragged_data = DragDropHelper.data + #pyfalog.debug("fittingView: recieved drag: " + self.dropData.GetText()) + data = dragged_data.split(':') self.dropFn(x, y, data) return t @@ -235,10 +238,12 @@ class FittingView(d.Display): if row != -1 and row not in self.blanks and isinstance(self.mods[row], Module) and not self.mods[row].isEmpty: data = wx.PyTextDataObject() - data.SetText("fitting:" + str(self.mods[row].modPosition)) + dataStr = "fitting:" + str(self.mods[row].modPosition) + data.SetText(dataStr) dropSource = wx.DropSource(self) dropSource.SetData(data) + DragDropHelper.data = dataStr dropSource.DoDragDrop() def getSelectedMods(self): diff --git a/gui/cargoView.py b/gui/cargoView.py index cd560c1c2..8230cb975 100644 --- a/gui/cargoView.py +++ b/gui/cargoView.py @@ -23,6 +23,7 @@ import gui.display as d from gui.builtinViewColumns.state import State from gui.contextMenu import ContextMenu import globalEvents as GE +from gui.utils.staticHelpers import DragDropHelper from service.fit import Fit from service.market import Market @@ -37,7 +38,8 @@ class CargoViewDrop(wx.PyDropTarget): def OnData(self, x, y, t): if self.GetData(): - data = self.dropData.GetText().split(':') + dragged_data = DragDropHelper.data + data = dragged_data.split(':') self.dropFn(x, y, data) return t @@ -87,10 +89,12 @@ class CargoView(d.Display): if row != -1: data = wx.PyTextDataObject() - data.SetText("cargo:" + str(row)) + dataStr = "cargo:" + str(row) + data.SetText(dataStr) dropSource = wx.DropSource(self) dropSource.SetData(data) + DragDropHelper.data = dataStr dropSource.DoDragDrop() def kbEvent(self, event): diff --git a/gui/commandView.py b/gui/commandView.py index 2d8899dff..8341e79fb 100644 --- a/gui/commandView.py +++ b/gui/commandView.py @@ -26,6 +26,7 @@ import gui.droneView from gui.builtinViewColumns.state import State from gui.contextMenu import ContextMenu from gui.builtinContextMenus.commandFits import CommandFits +from gui.utils.staticHelpers import DragDropHelper from service.fit import Fit from eos.saveddata.drone import Drone as es_Drone @@ -51,7 +52,8 @@ class CommandViewDrop(wx.PyDropTarget): def OnData(self, x, y, t): if self.GetData(): - data = self.dropData.GetText().split(':') + dragged_data = DragDropHelper.data + data = dragged_data.split(':') self.dropFn(x, y, data) return t @@ -116,10 +118,12 @@ class CommandView(d.Display): row = event.GetIndex() if row != -1 and isinstance(self.get(row), es_Drone): data = wx.PyTextDataObject() - data.SetText("command:" + str(self.GetItemData(row))) + dataStr = "command:" + str(self.GetItemData(row)) + data.SetText(dataStr) dropSource = wx.DropSource(self) dropSource.SetData(data) + DragDropHelper.data = dataStr dropSource.DoDragDrop() @staticmethod diff --git a/gui/droneView.py b/gui/droneView.py index b075cfee0..e4316059c 100644 --- a/gui/droneView.py +++ b/gui/droneView.py @@ -25,6 +25,7 @@ from gui.marketBrowser import ITEM_SELECTED, ItemSelected from gui.display import Display from gui.builtinViewColumns.state import State from gui.contextMenu import ContextMenu +from gui.utils.staticHelpers import DragDropHelper from service.fit import Fit from service.market import Market @@ -39,7 +40,8 @@ class DroneViewDrop(wx.PyDropTarget): def OnData(self, x, y, t): if self.GetData(): - data = self.dropData.GetText().split(':') + dragged_data = DragDropHelper.data + data = dragged_data.split(':') self.dropFn(x, y, data) return t @@ -122,10 +124,12 @@ class DroneView(Display): row = event.GetIndex() if row != -1: data = wx.PyTextDataObject() - data.SetText("drone:" + str(row)) + dataStr = "drone:" + str(row) + data.SetText(dataStr) dropSource = wx.DropSource(self) dropSource.SetData(data) + DragDropHelper.data = dataStr dropSource.DoDragDrop() def handleDragDrop(self, x, y, data): diff --git a/gui/fighterView.py b/gui/fighterView.py index 6332817fe..e5fdfd1c2 100644 --- a/gui/fighterView.py +++ b/gui/fighterView.py @@ -27,6 +27,7 @@ import gui.display as d from gui.builtinViewColumns.state import State from eos.saveddata.module import Slot from gui.contextMenu import ContextMenu +from gui.utils.staticHelpers import DragDropHelper from service.fit import Fit from service.market import Market @@ -41,7 +42,8 @@ class FighterViewDrop(wx.PyDropTarget): def OnData(self, x, y, t): if self.GetData(): - data = self.dropData.GetText().split(':') + dragged_data = DragDropHelper.data + data = dragged_data.split(':') self.dropFn(x, y, data) return t @@ -184,10 +186,12 @@ class FighterDisplay(d.Display): row = event.GetIndex() if row != -1: data = wx.PyTextDataObject() - data.SetText("fighter:" + str(row)) + dataStr = "fighter:" + str(row) + data.SetText(dataStr) dropSource = wx.DropSource(self) dropSource.SetData(data) + DragDropHelper.data = dataStr dropSource.DoDragDrop() def handleDragDrop(self, x, y, data): diff --git a/gui/marketBrowser.py b/gui/marketBrowser.py index d42ea56ec..d914069b7 100644 --- a/gui/marketBrowser.py +++ b/gui/marketBrowser.py @@ -28,6 +28,7 @@ from gui.cachingImageList import CachingImageList from gui.contextMenu import ContextMenu from gui.bitmapLoader import BitmapLoader from logbook import Logger +from utils.staticHelpers import DragDropHelper pyfalog = Logger(__name__) @@ -285,6 +286,7 @@ class ItemView(Display): data.SetText(dataStr) dropSource = wx.DropSource(self) dropSource.SetData(data) + DragDropHelper.data = dataStr dropSource.DoDragDrop() def itemActivated(self, event=None): diff --git a/gui/projectedView.py b/gui/projectedView.py index b971272b6..e131b88a4 100644 --- a/gui/projectedView.py +++ b/gui/projectedView.py @@ -24,6 +24,7 @@ import gui.globalEvents as GE import gui.droneView from gui.builtinViewColumns.state import State from gui.contextMenu import ContextMenu +from gui.utils.staticHelpers import DragDropHelper from service.fit import Fit from service.market import Market from eos.saveddata.drone import Drone as es_Drone @@ -52,7 +53,8 @@ class ProjectedViewDrop(wx.PyDropTarget): def OnData(self, x, y, t): if self.GetData(): - data = self.dropData.GetText().split(':') + dragged_data = DragDropHelper.data + data = dragged_data.split(':') self.dropFn(x, y, data) return t @@ -127,10 +129,12 @@ class ProjectedView(d.Display): row = event.GetIndex() if row != -1 and isinstance(self.get(row), es_Drone): data = wx.PyTextDataObject() - data.SetText("projected:" + str(self.GetItemData(row))) + dataStr = "projected:" + str(self.GetItemData(row)) + data.SetText(dataStr) dropSource = wx.DropSource(self) dropSource.SetData(data) + DragDropHelper.data = dataStr dropSource.DoDragDrop() def mergeDrones(self, x, y, itemID): diff --git a/gui/utils/staticHelpers.py b/gui/utils/staticHelpers.py new file mode 100644 index 000000000..538936e3a --- /dev/null +++ b/gui/utils/staticHelpers.py @@ -0,0 +1,5 @@ +class DragDropHelper: + data = None + + def __init__(self): + pass From 46f61ecfa3141ff10547617749311db2c87c69ff Mon Sep 17 00:00:00 2001 From: Michael Ryan Date: Tue, 30 May 2017 21:07:02 -0500 Subject: [PATCH 2/7] address travis errors --- gui/boosterView.py | 1 + gui/builtinViews/fittingView.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/gui/boosterView.py b/gui/boosterView.py index 98d07753f..5f43aca04 100644 --- a/gui/boosterView.py +++ b/gui/boosterView.py @@ -24,6 +24,7 @@ import gui.globalEvents as GE import gui.marketBrowser as marketBrowser from gui.builtinViewColumns.state import State from gui.contextMenu import ContextMenu +from gui.utils.staticHelpers import DragDropHelper from service.fit import Fit diff --git a/gui/builtinViews/fittingView.py b/gui/builtinViews/fittingView.py index d5dee9608..cc82acdbe 100644 --- a/gui/builtinViews/fittingView.py +++ b/gui/builtinViews/fittingView.py @@ -113,7 +113,7 @@ class FittingViewDrop(wx.PyDropTarget): def OnData(self, x, y, t): if self.GetData(): dragged_data = DragDropHelper.data - #pyfalog.debug("fittingView: recieved drag: " + self.dropData.GetText()) + # pyfalog.debug("fittingView: recieved drag: " + self.dropData.GetText()) data = dragged_data.split(':') self.dropFn(x, y, data) return t From 4286f2ea5ac2dd90d5138f3a0a6b159492b41509 Mon Sep 17 00:00:00 2001 From: Ryan Holmes Date: Tue, 30 May 2017 22:44:01 -0400 Subject: [PATCH 3/7] Add stacking penalties to armor and shield resist command links (#1198) --- eos/saveddata/fit.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eos/saveddata/fit.py b/eos/saveddata/fit.py index 64d6f91f8..7dfb5fc8c 100644 --- a/eos/saveddata/fit.py +++ b/eos/saveddata/fit.py @@ -500,7 +500,7 @@ class Fit(object): if warfareBuffID == 10: # Shield Burst: Shield Harmonizing: Shield Resistance for damageType in ("Em", "Explosive", "Thermal", "Kinetic"): - self.ship.boostItemAttr("shield%sDamageResonance" % damageType, value) + self.ship.boostItemAttr("shield%sDamageResonance" % damageType, value, stackingPenalties=True) if warfareBuffID == 11: # Shield Burst: Active Shielding: Repair Duration/Capacitor self.modules.filteredItemBoost( @@ -515,7 +515,7 @@ class Fit(object): if warfareBuffID == 13: # Armor Burst: Armor Energizing: Armor Resistance for damageType in ("Em", "Thermal", "Explosive", "Kinetic"): - self.ship.boostItemAttr("armor%sDamageResonance" % damageType, value) + 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 From 45c3533501af3d3b51fe95335bbbc576f607f0d5 Mon Sep 17 00:00:00 2001 From: Ryan Holmes Date: Tue, 30 May 2017 22:57:52 -0400 Subject: [PATCH 4/7] Make some extra logging statements and stuff to troubleshoot fit deletion bugs (#1199) --- gui/builtinViewColumns/baseName.py | 8 ++++++++ gui/builtinViews/fittingView.py | 4 +++- gui/projectedView.py | 5 +++++ gui/shipBrowser.py | 7 +++++-- service/fit.py | 13 ++++++++----- 5 files changed, 29 insertions(+), 8 deletions(-) diff --git a/gui/builtinViewColumns/baseName.py b/gui/builtinViewColumns/baseName.py index 6939b8e21..aeae8339f 100644 --- a/gui/builtinViewColumns/baseName.py +++ b/gui/builtinViewColumns/baseName.py @@ -20,6 +20,7 @@ # noinspection PyPackageRequirements import wx +from logbook import Logger from eos.saveddata.cargo import Cargo from eos.saveddata.implant import Implant from eos.saveddata.drone import Drone @@ -30,6 +31,8 @@ from service.fit import Fit as FitSvc from gui.viewColumn import ViewColumn import gui.mainFrame +pyfalog = Logger(__name__) + class BaseName(ViewColumn): name = "Base Name" @@ -56,8 +59,13 @@ class BaseName(ViewColumn): # we need a little more information for the projected view fitID = self.mainFrame.getActiveFit() info = stuff.getProjectionInfo(fitID) + if info: return "%dx %s (%s)" % (stuff.getProjectionInfo(fitID).amount, stuff.name, stuff.ship.item.name) + + pyfalog.warning("Projected View trying to display things that aren't there. stuff: {}, info: {}", repr(stuff), + info) + return "" else: return "%s (%s)" % (stuff.name, stuff.ship.item.name) elif isinstance(stuff, Rack): diff --git a/gui/builtinViews/fittingView.py b/gui/builtinViews/fittingView.py index cc82acdbe..41d3df87f 100644 --- a/gui/builtinViews/fittingView.py +++ b/gui/builtinViews/fittingView.py @@ -278,7 +278,9 @@ class FittingView(d.Display): We also refresh the fit of the new current page in case delete fit caused change in stats (projected) """ + pyfalog.debug("FittingView::fitRemoved") if event.fitID == self.getActiveFit(): + pyfalog.debug(" Deleted fit is currently active") self.parent.DeletePage(self.parent.GetPageIndex(self)) try: @@ -287,7 +289,7 @@ class FittingView(d.Display): sFit.refreshFit(self.getActiveFit()) wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.activeFitID)) except wx._core.PyDeadObjectError: - pyfalog.error("Caught dead object") + pyfalog.warning("Caught dead object") pass event.Skip() diff --git a/gui/projectedView.py b/gui/projectedView.py index e131b88a4..9a772e6ab 100644 --- a/gui/projectedView.py +++ b/gui/projectedView.py @@ -19,6 +19,7 @@ # noinspection PyPackageRequirements import wx +from logbook import Logger import gui.display as d import gui.globalEvents as GE import gui.droneView @@ -31,6 +32,8 @@ from eos.saveddata.drone import Drone as es_Drone from eos.saveddata.fighter import Fighter as es_Fighter from eos.saveddata.module import Module as es_Module +pyfalog = Logger(__name__) + class DummyItem(object): def __init__(self, txt): @@ -174,6 +177,7 @@ class ProjectedView(d.Display): def fitChanged(self, event): sFit = Fit.getInstance() fit = sFit.getFit(event.fitID) + pyfalog.debug("ProjectedView::fitChanged: {}", repr(fit)) self.Parent.Parent.DisablePage(self, not fit or fit.isStructure) @@ -186,6 +190,7 @@ class ProjectedView(d.Display): stuff = [] if fit is not None: + pyfalog.debug(" Collecting list of stuff to display in ProjectedView") self.modules = fit.projectedModules[:] self.drones = fit.projectedDrones[:] self.fighters = fit.projectedFighters[:] diff --git a/gui/shipBrowser.py b/gui/shipBrowser.py index 7570b2aa5..2e5233acb 100644 --- a/gui/shipBrowser.py +++ b/gui/shipBrowser.py @@ -1811,6 +1811,11 @@ class FitItem(SFItem.SFBrowserItem): sFit = Fit.getInstance() fit = sFit.getFit(self.fitID) + # need to delete from import cache before actually deleting fit + if self.shipBrowser.GetActiveStage() == 5: + if fit in self.shipBrowser.lastdata: # remove fit from import cache + self.shipBrowser.lastdata.remove(fit) + sFit.deleteFit(self.fitID) # Notify other areas that a fit has been deleted @@ -1818,8 +1823,6 @@ class FitItem(SFItem.SFBrowserItem): # todo: would a simple RefreshList() work here instead of posting that a stage has been selected? if self.shipBrowser.GetActiveStage() == 5: - if fit in self.shipBrowser.lastdata: # remove fit from import cache - self.shipBrowser.lastdata.remove(fit) wx.PostEvent(self.shipBrowser, ImportSelected(fits=self.shipBrowser.lastdata)) elif self.shipBrowser.GetActiveStage() == 4: wx.PostEvent(self.shipBrowser, SearchSelected(text=self.shipBrowser.navpanel.lastSearch, back=True)) diff --git a/service/fit.py b/service/fit.py index 0031a137d..896ca689d 100644 --- a/service/fit.py +++ b/service/fit.py @@ -166,10 +166,8 @@ class Fit(object): @staticmethod def deleteFit(fitID): - pyfalog.debug("Deleting fit for fit ID: {0}", fitID) fit = eos.db.getFit(fitID) - - eos.db.remove(fit) + pyfalog.debug("Fit::deleteFit - Deleting fit: {}", fit) # refresh any fits this fit is projected onto. Otherwise, if we have # already loaded those fits, they will not reflect the changes @@ -180,16 +178,21 @@ class Fit(object): # error during the command loop refreshFits = set() for projection in fit.projectedOnto.values(): - if projection.victim_fit in eos.db.saveddata_session: # GH issue #359 + if projection.victim_fit != fit and projection.victim_fit in eos.db.saveddata_session: # GH issue #359 refreshFits.add(projection.victim_fit) for booster in fit.boostedOnto.values(): - if booster.boosted_fit in eos.db.saveddata_session: # GH issue #359 + if booster.boosted_fit != fit and booster.boosted_fit in eos.db.saveddata_session: # GH issue #359 refreshFits.add(booster.boosted_fit) + eos.db.saveddata_session.delete(fit) + + pyfalog.debug(" Need to refresh {} fits: {}", len(refreshFits), refreshFits) for fit in refreshFits: eos.db.saveddata_session.refresh(fit) + eos.db.saveddata_session.commit() + @staticmethod def copyFit(fitID): pyfalog.debug("Creating copy of fit ID: {0}", fitID) From 3371086d5404a935b221e32234b469ef34bb4188 Mon Sep 17 00:00:00 2001 From: Ryan Holmes Date: Wed, 31 May 2017 00:01:59 -0400 Subject: [PATCH 5/7] Fix for #1193 - compounded bonuses during recursive command / projected fittings (#1197) * Teak calculated logic * test * clear() on every calculation if it's not already calculated * tox fix --- eos/saveddata/fit.py | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/eos/saveddata/fit.py b/eos/saveddata/fit.py index 7dfb5fc8c..1a186f74b 100644 --- a/eos/saveddata/fit.py +++ b/eos/saveddata/fit.py @@ -403,11 +403,12 @@ class Fit(object): } if not map[key](val): + raise ValueError(str(val) + " is not a valid value for " + key) else: return val - def clear(self, projected=False): + def clear(self, projected=False, command=False): self.__effectiveTank = None self.__weaponDPS = None self.__minerYield = None @@ -424,7 +425,7 @@ class Fit(object): self.__capUsed = None self.__capRecharge = None self.ecmProjectedStr = 1 - self.commandBonuses = {} + # self.commandBonuses = {} for remoterep_type in self.__remoteReps: self.__remoteReps[remoterep_type] = None @@ -454,10 +455,15 @@ class Fit(object): # If this is the active fit that we are clearing, not a projected fit, # then this will run and clear the projected ships and flag the next # iteration to skip this part to prevent recursion. - if not projected: - for stuff in self.projectedFits: - if stuff is not None and stuff != self: - stuff.clear(projected=True) + # if not projected: + # for stuff in self.projectedFits: + # if stuff is not None and stuff != self: + # stuff.clear(projected=True) + # + # if not command: + # for stuff in self.commandFits: + # if stuff is not None and stuff != self: + # stuff.clear(command=True) # Methods to register and get the thing currently affecting the fit, # so we can correctly map "Affected By" @@ -688,9 +694,10 @@ class Fit(object): The type of calculation our current iteration is in. This helps us determine the interactions between fits that rely on others for proper calculations """ - pyfalog.debug("Starting fit calculation on: {0}, calc: {1}", repr(self), CalcType.getName(type)) + pyfalog.info("Starting fit calculation on: {0}, calc: {1}", repr(self), CalcType.getName(type)) # If we are projecting this fit onto another one, collect the projection info for later use + # We also deal with self-projection here by setting self as a copy (to get a new fit object) to apply onto original fit # First and foremost, if we're looking at a local calc, reset the calculated state of fits that this fit affects # Thankfully, due to the way projection mechanics currently work, we don't have to traverse down a projection @@ -714,7 +721,7 @@ class Fit(object): # We run the command calculations first so that they can calculate fully and store the command effects on the # target fit to be used later on in the calculation. This does not apply when we're already calculating a # command fit. - if type != CalcType.COMMAND and self.commandFits: + if type != CalcType.COMMAND and self.commandFits and not self.__calculated: for fit in self.commandFits: commandInfo = fit.getCommandInfo(self.ID) # Continue loop if we're trying to apply ourselves or if this fit isn't active @@ -743,6 +750,10 @@ class Fit(object): pyfalog.debug("Fit has already been calculated and is local, returning: {0}", self) return + if not self.__calculated: + pyfalog.info("Fit is not yet calculated; will be running local calcs for {}".format(repr(self))) + self.clear() + # Loop through our run times here. These determine which effects are run in which order. for runTime in ("early", "normal", "late"): pyfalog.debug("Run time: {0}", runTime) @@ -795,8 +806,12 @@ class Fit(object): if type == CalcType.PROJECTED and projectionInfo: self.__runProjectionEffects(runTime, targetFit, projectionInfo) - # Mark fit as calculated - self.__calculated = True + # Recursive command ships (A <-> B) get marked as calculated, which means that they aren't recalced when changing + # tabs. See GH issue 1193 + if type == CalcType.COMMAND and targetFit in self.commandFits: + pyfalog.debug("{} is in the command listing for COMMAND ({}), do not mark self as calculated (recursive)".format(repr(targetFit), repr(self))) + else: + self.__calculated = True # Only apply projected fits if fit it not projected itself. if type == CalcType.LOCAL: From 373ead8da69368ff6d524e4a7d51859dd71e3add Mon Sep 17 00:00:00 2001 From: Ryan Holmes Date: Wed, 31 May 2017 23:14:17 -0400 Subject: [PATCH 6/7] Add structure painter / web to dps graph (#1203) (#1202) --- eos/graph/fitDps.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eos/graph/fitDps.py b/eos/graph/fitDps.py index cfa70187a..12cfda8d1 100644 --- a/eos/graph/fitDps.py +++ b/eos/graph/fitDps.py @@ -47,11 +47,11 @@ class FitDpsGraph(Graph): for mod in fit.modules: if not mod.isEmpty and mod.state >= State.ACTIVE: - if "remoteTargetPaintFalloff" in mod.item.effects: + if "remoteTargetPaintFalloff" in mod.item.effects or "structureModuleEffectTargetPainter" in mod.item.effects: ew['signatureRadius'].append( 1 + (mod.getModifiedItemAttr("signatureRadiusBonus") / 100) * self.calculateModuleMultiplier( mod, data)) - if "remoteWebifierFalloff" in mod.item.effects: + if "remoteWebifierFalloff" in mod.item.effects or "structureModuleEffectStasisWebifier" in mod.item.effects: if distance <= mod.getModifiedItemAttr("maxRange"): ew['velocity'].append(1 + (mod.getModifiedItemAttr("speedFactor") / 100)) elif mod.getModifiedItemAttr("falloffEffectiveness") > 0: From 461f5219e5f2677f6dd2ce27304f4735d09bf62e Mon Sep 17 00:00:00 2001 From: Ryan Holmes Date: Wed, 31 May 2017 23:51:46 -0400 Subject: [PATCH 7/7] bump release (#1204) --- config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.py b/config.py index bf7cb5f89..098f2bebd 100644 --- a/config.py +++ b/config.py @@ -20,7 +20,7 @@ saveInRoot = False # Version data version = "1.29.3" -tag = "git" +tag = "Stable" expansionName = "YC119.5" expansionVersion = "1.0" evemonMinVersion = "4081"