Merge branch 'master' into development

This commit is contained in:
blitzmann
2017-06-01 00:32:06 -04:00
15 changed files with 107 additions and 37 deletions

View File

@@ -20,7 +20,7 @@ saveInRoot = False
# Version data
version = "1.29.3"
tag = "git"
tag = "Stable"
expansionName = "YC119.5"
expansionVersion = "1.0"
evemonMinVersion = "4081"

View File

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

View File

@@ -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"
@@ -500,7 +506,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 +521,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
@@ -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:

View File

@@ -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
@@ -37,7 +38,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

View File

@@ -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 "<unknown>"
else:
return "%s (%s)" % (stuff.name, stuff.ship.item.name)
elif isinstance(stuff, Rack):

View File

@@ -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):
@@ -273,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:
@@ -282,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()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -19,17 +19,21 @@
# noinspection PyPackageRequirements
import wx
from logbook import Logger
import gui.display as d
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
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):
@@ -52,7 +56,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 +132,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):
@@ -170,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)
@@ -182,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[:]

View File

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

View File

@@ -0,0 +1,5 @@
class DragDropHelper:
data = None
def __init__(self):
pass

View File

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