Merge branch 'singularity'

This commit is contained in:
DarkPhoenix
2011-11-29 17:44:10 +04:00
16 changed files with 711 additions and 69 deletions

View File

@@ -13,8 +13,8 @@ debug = False
# Version data # Version data
version = "1.0.6" version = "1.0.6"
tag = "git" tag = "git"
expansionName = "Incarna" expansionName = "Singularity"
expansionVersion = "1.1.1" expansionVersion = "0.0"
# You can adjust these paths to your needs # You can adjust these paths to your needs

2
eos

Submodule eos updated: eb491d7fb5...8c66bc7140

View File

@@ -24,6 +24,7 @@ from gui.droneView import DroneView
from gui.implantView import ImplantView from gui.implantView import ImplantView
from gui.projectedView import ProjectedView from gui.projectedView import ProjectedView
from gui.pyfatogglepanel import TogglePanel from gui.pyfatogglepanel import TogglePanel
from gui.gangView import GangView
from gui import bitmapLoader from gui import bitmapLoader
import gui.chromeTabs import gui.chromeTabs
@@ -45,7 +46,7 @@ class AdditionsPane(TogglePanel):
self.notebook = gui.chromeTabs.PFNotebook(pane, False) self.notebook = gui.chromeTabs.PFNotebook(pane, False)
size = wx.Size() size = wx.Size()
# This size lets you see 4 drones at a time # This size lets you see 4 drones at a time
size.SetHeight(160) size.SetHeight(180)
self.notebook.SetMinSize(size) self.notebook.SetMinSize(size)
baseSizer.Add(self.notebook, 1, wx.EXPAND) baseSizer.Add(self.notebook, 1, wx.EXPAND)
@@ -53,6 +54,7 @@ class AdditionsPane(TogglePanel):
implantImg = bitmapLoader.getImage("implant_small", "icons") implantImg = bitmapLoader.getImage("implant_small", "icons")
boosterImg = bitmapLoader.getImage("booster_small", "icons") boosterImg = bitmapLoader.getImage("booster_small", "icons")
projectedImg = bitmapLoader.getImage("projected_small", "icons") projectedImg = bitmapLoader.getImage("projected_small", "icons")
gangImg = bitmapLoader.getImage("fleet_fc_small", "icons")
self.notebook.AddPage(DroneView(self.notebook), "Drones", tabImage = droneImg, showClose = False) self.notebook.AddPage(DroneView(self.notebook), "Drones", tabImage = droneImg, showClose = False)
self.notebook.AddPage(ImplantView(self.notebook), "Implants", tabImage = implantImg, showClose = False) self.notebook.AddPage(ImplantView(self.notebook), "Implants", tabImage = implantImg, showClose = False)
@@ -60,9 +62,12 @@ class AdditionsPane(TogglePanel):
self.projectedPage = ProjectedView(self.notebook) self.projectedPage = ProjectedView(self.notebook)
self.notebook.AddPage(self.projectedPage, "Projected", tabImage = projectedImg, showClose = False) self.notebook.AddPage(self.projectedPage, "Projected", tabImage = projectedImg, showClose = False)
self.gangPage = GangView(self.notebook)
self.notebook.AddPage(self.gangPage, "Fleet", tabImage = gangImg, showClose = False)
self.notebook.SetSelection(0) self.notebook.SetSelection(0)
PANES = ["Drones", "Implants", "Boosters"] PANES = ["Drones", "Implants", "Boosters", "Projected", "Fleet"]
def select(self, name): def select(self, name):
self.notebook.SetSelection(self.PANES.index(name)) self.notebook.SetSelection(self.PANES.index(name))

View File

@@ -1,2 +1,2 @@
__all__ = ["moduleAmmoPicker", "itemStats", "damagePattern", "marketJump", "droneSplit", __all__ = ["moduleAmmoPicker", "itemStats", "damagePattern", "marketJump", "droneSplit",
"ammoPattern", "project", "factorReload"] "ammoPattern", "project", "factorReload", "whProjector"]

View File

@@ -8,9 +8,17 @@ class MarketJump(ContextMenu):
self.mainFrame = gui.mainFrame.MainFrame.getInstance() self.mainFrame = gui.mainFrame.MainFrame.getInstance()
def display(self, srcContext, selection): def display(self, srcContext, selection):
return srcContext in ("marketItemMisc", "fittingModule", "fittingCharge", "droneItem", validContexts = ("marketItemMisc", "fittingModule", "fittingCharge", "droneItem", "implantItem",
"implantItem", "boosterItem", "projectedModule", "projectedDrone", "projectedCharge") \ "boosterItem", "projectedModule", "projectedDrone", "projectedCharge")
and (not selection[0].isEmpty if srcContext == "fittingModule" else True) if not srcContext in validContexts:
return False
sMkt = service.Market.getInstance()
if selection is None or len(selection) < 1:
return False
item = getattr(selection[0], "item", selection[0])
doit = not selection[0].isEmpty if srcContext == "fittingModule" else True \
and sMkt.getMarketGroupByItem(item) is not None
return doit
def getText(self, itmContext, selection): def getText(self, itmContext, selection):
return "{0} Market Group".format(itmContext if itmContext is not None else "Item") return "{0} Market Group".format(itmContext if itmContext is not None else "Item")

View File

@@ -0,0 +1,47 @@
from gui.contextMenu import ContextMenu
import gui.mainFrame
import gui.globalEvents as GE
import service
import wx
class WhProjector(ContextMenu):
def __init__(self):
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
def display(self, srcContext, selection):
return srcContext in ("projectedDrone", "projectedModule", "projectedCharge", "projectedFit", "projectedNone")
def getText(self, itmContext, selection):
return "Add System Effects"
def activate(self, fullContext, selection, i):
pass
def getSubMenu(self, context, selection, menu, i):
self.idmap = {}
m = wx.Menu()
sMkt = service.Market.getInstance()
effdata = sMkt.getSystemWideEffects()
for swType in sorted(effdata):
item = wx.MenuItem(m, wx.ID_ANY, swType)
sub = wx.Menu()
sub.Bind(wx.EVT_MENU, self.handleSelection)
item.SetSubMenu(sub)
m.AppendItem(item)
for swData in sorted(effdata[swType], key=lambda tpl: tpl[2]):
wxid = wx.NewId()
swObj, swName, swClass = swData
self.idmap[wxid] = (swObj, swName)
subitem = wx.MenuItem(sub, wxid, swClass)
sub.AppendItem(subitem)
return m
def handleSelection(self, event):
swObj, swName = self.idmap[event.Id]
sFit = service.Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
sFit.project(fitID, swObj)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
WhProjector.register()

View File

@@ -223,6 +223,10 @@ class CharacterEditor(wx.Frame):
def processRename(self, event): def processRename(self, event):
cChar = service.Character.getInstance() cChar = service.Character.getInstance()
newName = self.characterRename.GetLineText(0) newName = self.characterRename.GetLineText(0)
if newName == "All 0" or newName == "All 5":
newName = newName + " bases are belong to us"
charID = self.getActiveCharacter() charID = self.getActiveCharacter()
cChar.rename(charID, newName) cChar.rename(charID, newName)

403
gui/gangView.py Normal file
View File

@@ -0,0 +1,403 @@
#===============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
#
# pyfa is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# pyfa 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
import wx
from wx.lib.scrolledpanel import ScrolledPanel
import service
import gui.mainFrame
import gui.shipBrowser
import gui.globalEvents as GE
from gui import characterEditor as CharEditor
class GangView ( ScrolledPanel ):
def __init__( self, parent ):
ScrolledPanel.__init__ ( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size( 100,20 ), style = wx.TAB_TRAVERSAL | wx.HSCROLL | wx.VSCROLL )
mainSizer = wx.BoxSizer( wx.VERTICAL )
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
self.draggedFitID = None
self.FitDNDPopupMenu = wx.Menu()
self.options = ["Fleet booster", "Wing booster", "Squad booster"]
for option in self.options:
item = self.FitDNDPopupMenu.Append(-1, option)
self.Bind(wx.EVT_MENU, self.OnPopupItemSelected, item)
contentFGSizer = wx.FlexGridSizer( 5, 3, 0, 0 )
contentFGSizer.AddGrowableCol( 1 )
contentFGSizer.SetFlexibleDirection( wx.BOTH )
contentFGSizer.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )
self.oneonePlaceholder = wx.StaticText( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
self.oneonePlaceholder.Wrap( -1 )
contentFGSizer.Add( self.oneonePlaceholder, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 5 )
self.stFits = wx.StaticText( self, wx.ID_ANY, u"Fits", wx.DefaultPosition, wx.DefaultSize, 0 )
self.stFits.Wrap( -1 )
self.stFits.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), 70, 90, 92, False, wx.EmptyString ) )
contentFGSizer.Add( self.stFits, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER_HORIZONTAL, 5 )
self.stCharacters = wx.StaticText( self, wx.ID_ANY, u"Characters", wx.DefaultPosition, wx.DefaultSize, 0 )
self.stCharacters.Wrap( -1 )
self.stCharacters.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), 70, 90, 92, False, wx.EmptyString ) )
contentFGSizer.Add( self.stCharacters, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER_HORIZONTAL, 5 )
self.m_staticline2 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL )
contentFGSizer.Add( self.m_staticline2, 0, wx.EXPAND, 5 )
self.m_staticline3 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL )
contentFGSizer.Add( self.m_staticline3, 0, wx.EXPAND, 5 )
self.m_staticline4 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL )
contentFGSizer.Add( self.m_staticline4, 0, wx.EXPAND, 5 )
self.stFleet = wx.StaticText( self, wx.ID_ANY, u"Fleet booster:", wx.DefaultPosition, wx.DefaultSize, 0 )
self.stFleet.Wrap( -1 )
self.stFleet.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), 70, 90, 92, False, wx.EmptyString ) )
contentFGSizer.Add( self.stFleet, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
self.stFleetFit = wx.StaticText( self, wx.ID_ANY, u"None", wx.DefaultPosition, wx.DefaultSize, 0 )
self.stFleetFit.Wrap( -1 )
contentFGSizer.Add( self.stFleetFit, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
chFleetCharChoices = []
self.chFleetChar = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, chFleetCharChoices, 0 )
self.chFleetChar.SetSelection( 0 )
contentFGSizer.Add( self.chFleetChar, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5 )
self.stWing = wx.StaticText( self, wx.ID_ANY, u"Wing booster:", wx.DefaultPosition, wx.DefaultSize, 0 )
self.stWing.Wrap( -1 )
self.stWing.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), 70, 90, 92, False, wx.EmptyString ) )
contentFGSizer.Add( self.stWing, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
self.stWingFit = wx.StaticText( self, wx.ID_ANY, u"None", wx.DefaultPosition, wx.DefaultSize, 0 )
self.stWingFit.Wrap( -1 )
contentFGSizer.Add( self.stWingFit, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
chWingCharChoices = []
self.chWingChar = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, chWingCharChoices, 0 )
self.chWingChar.SetSelection( 0 )
contentFGSizer.Add( self.chWingChar, 0, wx.ALL| wx.ALIGN_CENTER_VERTICAL, 5 )
self.stSquad = wx.StaticText( self, wx.ID_ANY, u"Squad booster:", wx.DefaultPosition, wx.DefaultSize, 0 )
self.stSquad.Wrap( -1 )
self.stSquad.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), 70, 90, 92, False, wx.EmptyString ) )
contentFGSizer.Add( self.stSquad, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
self.stSquadFit = wx.StaticText( self, wx.ID_ANY, u"None", wx.DefaultPosition, wx.DefaultSize, 0 )
self.stSquadFit.Wrap( -1 )
contentFGSizer.Add( self.stSquadFit, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
chSquadCharChoices = []
self.chSquadChar = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, chSquadCharChoices, 0 )
self.chSquadChar.SetSelection( 0 )
contentFGSizer.Add( self.chSquadChar, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5 )
mainSizer.Add( contentFGSizer, 1, wx.EXPAND, 0 )
self.stBoosters = []
self.stBoosters.append(self.stFleetFit)
self.stBoosters.append(self.stWingFit)
self.stBoosters.append(self.stSquadFit)
self.chCharacters = []
self.chCharacters.append(self.chFleetChar)
self.chCharacters.append(self.chWingChar)
self.chCharacters.append(self.chSquadChar)
self.SetSizer( mainSizer )
self.SetAutoLayout(True)
self.SetupScrolling()
self.Disable()
self.mainFrame.Bind(CharEditor.CHAR_LIST_UPDATED, self.RefreshCharacterList)
self.mainFrame.Bind(GE.FIT_CHANGED, self.fitSelected)
self.mainFrame.Bind(gui.shipBrowser.EVT_FIT_RENAMED, self.fitRenamed)
for stBooster in self.stBoosters:
stBooster.Bind(wx.EVT_LEFT_DCLICK, self.RemoveBooster)
stBooster.Bind(wx.EVT_ENTER_WINDOW, self.OnEnterWindow)
stBooster.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow)
stBooster.SetToolTip(wx.ToolTip("Double click to remove booster"))
for chCharacter in self.chCharacters:
chCharacter.Bind(wx.EVT_CHOICE, self.CharChanged)
self.RefreshCharacterList()
def OnEnterWindow(self, event):
obj = event.GetEventObject()
obj.SetCursor(wx.StockCursor(wx.CURSOR_HAND))
event.Skip()
def OnLeaveWindow(self, event):
obj = event.GetEventObject()
obj.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
event.Skip()
def CharChanged(self, event):
chBooster = event.GetEventObject()
type = -1
if chBooster == self.chFleetChar:
type = 0
if chBooster == self.chWingChar:
type = 1
if chBooster == self.chSquadChar:
type = 2
if type == -1:
event.Skip()
return
cFit = service.Fit.getInstance()
fleetSrv = service.Fleet.getInstance()
activeFitID = self.mainFrame.getActiveFit()
fit = cFit.getFit(activeFitID)
cChar = service.Character.getInstance()
charList = cChar.getCharacterList()
if activeFitID:
commanders = fleetSrv.loadLinearFleet(fit)
if commanders is None:
fleetCom, wingCom, squadCom = (None, None, None)
else:
fleetCom, wingCom, squadCom = commanders
if type == 0:
if fleetCom:
charID = chBooster.GetClientData(chBooster.GetSelection())
cFit.changeChar(fleetCom.ID, charID)
else:
chBooster.SetSelection(0)
if type == 1:
if wingCom:
charID = chBooster.GetClientData(chBooster.GetSelection())
cFit.changeChar(wingCom.ID, charID)
else:
chBooster.SetSelection(0)
if type == 2:
if squadCom:
charID = chBooster.GetClientData(chBooster.GetSelection())
cFit.changeChar(squadCom.ID, charID)
else:
chBooster.SetSelection(0)
cFit.recalc(fit, withBoosters=True)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=activeFitID))
else:
chBooster.SetSelection(0)
def RemoveBooster(self, event):
activeFitID = self.mainFrame.getActiveFit()
if not activeFitID:
return
location = event.GetEventObject()
if location == self.stFleetFit:
type = 0
if location == self.stWingFit:
type = 1
if location == self.stSquadFit:
type = 2
sFit = service.Fit.getInstance()
boostee = sFit.getFit(activeFitID)
booster = None
fleetSrv = service.Fleet.getInstance()
if type == 0:
fleetSrv.setLinearFleetCom(boostee, booster)
elif type == 1:
fleetSrv.setLinearWingCom(boostee, booster)
elif type == 2:
fleetSrv.setLinearSquadCom(boostee, booster)
sFit.recalc(boostee, withBoosters=True)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=activeFitID))
def fitRenamed(self, event):
fleetSrv = service.Fleet.getInstance()
activeFitID = self.mainFrame.getActiveFit()
if activeFitID:
ev = event
ev.fitID = activeFitID
self.fitSelected(ev)
def fitSelected(self, event):
cFit = service.Fit.getInstance()
fit = cFit.getFit(event.fitID)
fleetSrv = service.Fleet.getInstance()
activeFitID = self.mainFrame.getActiveFit()
if activeFitID:
commanders = fleetSrv.loadLinearFleet(fit)
if commanders is None:
fleetCom, wingCom, squadCom = (None, None, None)
else:
fleetCom, wingCom, squadCom = commanders
if fleetCom:
fleetComName = fleetCom.ship.item.name + ": " + fleetCom.name
fleetComCharName = fleetCom.character.name if fleetCom.character is not None else "All 0"
else:
fleetComName = "None"
fleetComCharName = "All 0"
if wingCom:
wingComName = wingCom.ship.item.name + ": " + wingCom.name
wingComCharName = wingCom.character.name if wingCom.character is not None else "All 0"
else:
wingComName = "None"
wingComCharName = "All 0"
if squadCom:
squadComName = squadCom.ship.item.name + ": " + squadCom.name
squadComCharName = squadCom.character.name if squadCom.character is not None else "All 0"
else:
squadComName = "None"
squadComCharName = "All 0"
self.UpdateFleetFitsUI( fleetComName, wingComName, squadComName, fleetComCharName, wingComCharName, squadComCharName )
self.Enable()
else:
fleetComName = "None"
fleetComCharName = "All 0"
wingComName = "None"
wingComCharName = "All 0"
squadComName = "None"
squadComCharName = "All 0"
self.UpdateFleetFitsUI( fleetComName, wingComName, squadComName, fleetComCharName, wingComCharName, squadComCharName )
self.Disable()
def UpdateFleetFitsUI(self, fleet, wing, squad, fleetChar, wingChar, squadChar):
self.stFleetFit.SetLabel(fleet)
self.stWingFit.SetLabel(wing)
self.stSquadFit.SetLabel(squad)
self.chFleetChar.SetStringSelection(fleetChar)
self.chWingChar.SetStringSelection(wingChar)
self.chSquadChar.SetStringSelection(squadChar)
self.Layout()
self.SendSizeEvent()
def AddCommander(self, fitID, type = None):
if type is None:
return
activeFitID = self.mainFrame.getActiveFit()
if activeFitID:
sFit = service.Fit.getInstance()
boostee = sFit.getFit(activeFitID)
booster = sFit.getFit(fitID)
fleetSrv = service.Fleet.getInstance()
if type == 0:
fleetSrv.setLinearFleetCom(boostee, booster)
elif type == 1:
fleetSrv.setLinearWingCom(boostee, booster)
elif type == 2:
fleetSrv.setLinearSquadCom(boostee, booster)
sFit.recalc(boostee, withBoosters=True)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=activeFitID))
def RefreshCharacterList(self, event = None):
cChar = service.Character.getInstance()
charList = cChar.getCharacterList()
for choice in self.chCharacters:
chCurrSelection = choice.GetSelection()
chCurrData = -1
if chCurrSelection != -1:
chCurrData = choice.GetClientData(chCurrSelection)
chCurrSelString = choice.GetString(chCurrSelection)
choice.Clear()
currSelFound = False
for char in charList:
id,name,_ = char
choice.Append(name, id)
if chCurrData == id:
currSelFound = True
if chCurrSelection == -1:
choice.SetSelection(1)
else:
if currSelFound:
choice.SetStringSelection(chCurrSelString)
else:
choice.SetSelection(1)
def handleDrag(self, type, fitID):
#Those are drags coming from pyfa sources, NOT builtin wx drags
self.draggedFitID = None
if type == "fit":
activeFit = self.mainFrame.getActiveFit()
if activeFit:
self.draggedFitID = fitID
pos = wx.GetMousePosition()
pos = self.ScreenToClient(pos)
self.PopupMenu(self.FitDNDPopupMenu, pos)
# sFit.project(activeFit,draggedFit)
# wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=activeFit))
def OnPopupItemSelected(self, event):
item = self.FitDNDPopupMenu.FindItemById(event.GetId())
text = item.GetText()
booster = self.options.index(text)
if self.draggedFitID:
sFit = service.Fit.getInstance()
draggedFit = sFit.getFit(self.draggedFitID)
# self.stBoosters[booster].SetLabel(draggedFit.name)
# self.Layout()
self.AddCommander(draggedFit.ID, booster)
self.mainFrame.additionsPane.select("Fleet")

View File

@@ -571,6 +571,8 @@ class ItemAffectedBy (wx.Panel):
for fit, afflictors in cont.getAfflictions(attrName).iteritems(): for fit, afflictors in cont.getAfflictions(attrName).iteritems():
for afflictor, modifier, amount in afflictors: for afflictor, modifier, amount in afflictors:
if afflictor.item is None:
continue
if afflictor.item.name not in things: if afflictor.item.name not in things:
things[afflictor.item.name] = [type(afflictor), set(), set()] things[afflictor.item.name] = [type(afflictor), set(), set()]

View File

@@ -200,11 +200,18 @@ class ProjectedView(d.Display):
else: else:
context = (modFullContext,) context = (modFullContext,)
else: else:
context = ("projectedFit",) context = (("projectedFit",),)
menu = ContextMenu.getMenu((item,), *context) menu = ContextMenu.getMenu((item,), *context)
if menu is not None: if menu is not None:
self.PopupMenu(menu) self.PopupMenu(menu)
elif row == -1 and event.Button == 3:
fitID = self.mainFrame.getActiveFit()
if fitID is None:
return
context = (("projectedNone",),)
menu = ContextMenu.getMenu([], *context)
if menu is not None:
self.PopupMenu(menu)
def remove(self, event): def remove(self, event):
row, _ = self.HitTest(event.Position) row, _ = self.HitTest(event.Position)

View File

@@ -1427,6 +1427,13 @@ class FitItem(SFItem.SFBrowserItem):
self.selTimer = wx.Timer(self,self.selTimerID) self.selTimer = wx.Timer(self,self.selTimerID)
self.selTimer.Start(100) self.selTimer.Start(100)
self.Bind(wx.EVT_RIGHT_UP, self.OnContextMenu)
def OnContextMenu(self, event):
self.mainFrame.additionsPane.gangPage.handleDrag("fit", self.fitID)
event.Skip()
def GetType(self): def GetType(self):
return 3 return 3

View File

@@ -40,6 +40,14 @@ class Character():
def all0ID(self): def all0ID(self):
return self.all0().ID return self.all0().ID
def all5(self):
all5 = eos.types.Character.getAll5()
eos.db.commit()
return all5
def all5ID(self):
return self.all5().ID
def getCharacterList(self): def getCharacterList(self):
baseChars = [eos.types.Character.getAll0(), eos.types.Character.getAll5()] baseChars = [eos.types.Character.getAll0(), eos.types.Character.getAll5()]
# Flush incase all0 & all5 weren't in the db yet # Flush incase all0 & all5 weren't in the db yet
@@ -47,6 +55,10 @@ class Character():
sFit = service.Fit.getInstance() sFit = service.Fit.getInstance()
return map(lambda c: (c.ID, c.name, c == sFit.character), eos.db.getCharacterList()) return map(lambda c: (c.ID, c.name, c == sFit.character), eos.db.getCharacterList())
def getCharacter(self, charID):
char = eos.db.getCharacter(charID)
return char
def getSkillGroups(self): def getSkillGroups(self):
cat = eos.db.getCategory(16) cat = eos.db.getCategory(16)
groups = [] groups = []

View File

@@ -32,6 +32,7 @@ from eos.types import State, Slot
from service.market import Market from service.market import Market
from service.damagePattern import DamagePattern from service.damagePattern import DamagePattern
from service.character import Character from service.character import Character
from service.fleet import Fleet
class FitBackupThread(threading.Thread): class FitBackupThread(threading.Thread):
def __init__(self, path, callback): def __init__(self, path, callback):
@@ -77,6 +78,7 @@ class Fit(object):
def __init__(self): def __init__(self):
self.pattern = DamagePattern.getInstance().getDamagePattern("Uniform") self.pattern = DamagePattern.getInstance().getDamagePattern("Uniform")
self.character = Character.getInstance().all0() self.character = Character.getInstance().all0()
self.dirtyFitIDs = set()
def getAllFits(self): def getAllFits(self):
fits = eos.db.getFitList() fits = eos.db.getFitList()
@@ -118,7 +120,7 @@ class Fit(object):
fit.damagePattern = self.pattern fit.damagePattern = self.pattern
fit.character = self.character fit.character = self.character
eos.db.save(fit) eos.db.save(fit)
fit.calculateModifiedAttributes() self.recalc(fit)
return fit.ID return fit.ID
def renameFit(self, fitID, newName): def renameFit(self, fitID, newName):
@@ -128,6 +130,8 @@ class Fit(object):
def deleteFit(self, fitID): def deleteFit(self, fitID):
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
sFlt = Fleet.getInstance()
sFlt.removeAssociatedFleetData(fit)
eos.db.remove(fit) eos.db.remove(fit)
def copyFit(self, fitID): def copyFit(self, fitID):
@@ -151,8 +155,7 @@ class Fit(object):
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
fit.factorReload = not fit.factorReload fit.factorReload = not fit.factorReload
eos.db.commit() eos.db.commit()
fit.clear() self.recalc(fit)
fit.calculateModifiedAttributes()
def switchFit(self, fitID): def switchFit(self, fitID):
if fitID is None: if fitID is None:
@@ -166,17 +169,25 @@ class Fit(object):
fit.damagePattern = self.pattern fit.damagePattern = self.pattern
eos.db.commit() eos.db.commit()
fit.clear() self.recalc(fit, withBoosters=True)
fit.calculateModifiedAttributes()
def getFit(self, fitID): def getFit(self, fitID):
if fitID is None: if fitID is None:
return None return None
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
fit.calculateModifiedAttributes() inited = getattr(fit, "inited", None)
fit.fill() if inited is None or inited is False:
eos.db.commit() sFlt = Fleet.getInstance()
f = sFlt.getLinearFleet(fit)
if f is None:
sFlt.removeAssociatedFleetData(fit)
fit.fleet = None
else:
fit.fleet = f
self.recalc(fit, withBoosters=True)
fit.fill()
eos.db.commit()
fit.inited = True
return fit return fit
def searchFits(self, name): def searchFits(self, name):
@@ -199,8 +210,7 @@ class Fit(object):
fit.implants.freeSlot(implant) fit.implants.freeSlot(implant)
fit.implants.append(implant) fit.implants.append(implant)
fit.clear() self.recalc(fit)
fit.calculateModifiedAttributes()
return True return True
def removeImplant(self, fitID, position): def removeImplant(self, fitID, position):
@@ -210,8 +220,7 @@ class Fit(object):
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
implant = fit.implants[position] implant = fit.implants[position]
fit.implants.remove(implant) fit.implants.remove(implant)
fit.clear() self.recalc(fit)
fit.calculateModifiedAttributes()
return True return True
def addBooster(self, fitID, itemID): def addBooster(self, fitID, itemID):
@@ -227,8 +236,7 @@ class Fit(object):
fit.boosters.freeSlot(booster) fit.boosters.freeSlot(booster)
fit.boosters.append(booster) fit.boosters.append(booster)
fit.clear() self.recalc(fit)
fit.calculateModifiedAttributes()
return True return True
def removeBooster(self, fitID, position): def removeBooster(self, fitID, position):
@@ -238,13 +246,14 @@ class Fit(object):
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
booster = fit.boosters[position] booster = fit.boosters[position]
fit.boosters.remove(booster) fit.boosters.remove(booster)
fit.clear() self.recalc(fit)
fit.calculateModifiedAttributes()
return True return True
def project(self, fitID, thing): def project(self, fitID, thing):
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
if isinstance(thing, eos.types.Fit): if isinstance(thing, eos.types.Fit):
if thing.ID == fitID:
return
fit.projectedFits.append(thing) fit.projectedFits.append(thing)
elif thing.category.name == "Drone": elif thing.category.name == "Drone":
drone = None drone = None
@@ -258,6 +267,10 @@ class Fit(object):
fit.projectedDrones.append(drone) fit.projectedDrones.append(drone)
drone.amount += 1 drone.amount += 1
elif thing.group.name == "Effect Beacon":
module = eos.types.Module(thing)
module.state = State.ONLINE
fit.projectedModules.append(module)
else: else:
module = eos.types.Module(thing) module = eos.types.Module(thing)
module.state = State.ACTIVE module.state = State.ACTIVE
@@ -266,8 +279,7 @@ class Fit(object):
fit.projectedModules.append(module) fit.projectedModules.append(module)
eos.db.commit() eos.db.commit()
fit.clear() self.recalc(fit)
fit.calculateModifiedAttributes()
def toggleProjected(self, fitID, thing, click): def toggleProjected(self, fitID, thing, click):
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
@@ -282,8 +294,7 @@ class Fit(object):
thing.state = State.OFFLINE thing.state = State.OFFLINE
eos.db.commit() eos.db.commit()
fit.clear() self.recalc(fit)
fit.calculateModifiedAttributes()
def removeProjected(self, fitID, thing): def removeProjected(self, fitID, thing):
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
@@ -295,8 +306,7 @@ class Fit(object):
fit.projectedFits.remove(thing) fit.projectedFits.remove(thing)
eos.db.commit() eos.db.commit()
fit.clear() self.recalc(fit)
fit.calculateModifiedAttributes()
def appendModule(self, fitID, itemID): def appendModule(self, fitID, itemID):
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
@@ -316,8 +326,7 @@ class Fit(object):
if m.isValidState(State.ACTIVE): if m.isValidState(State.ACTIVE):
m.state = State.ACTIVE m.state = State.ACTIVE
fit.clear() self.recalc(fit)
fit.calculateModifiedAttributes()
self.checkStates(fit, m) self.checkStates(fit, m)
fit.fill() fit.fill()
eos.db.commit() eos.db.commit()
@@ -333,8 +342,7 @@ class Fit(object):
numSlots = len(fit.modules) numSlots = len(fit.modules)
fit.modules.toDummy(position) fit.modules.toDummy(position)
fit.clear() self.recalc(fit)
fit.calculateModifiedAttributes()
self.checkStates(fit, None) self.checkStates(fit, None)
fit.fill() fit.fill()
eos.db.commit() eos.db.commit()
@@ -365,12 +373,13 @@ class Fit(object):
if drone is None: if drone is None:
drone = eos.types.Drone(item) drone = eos.types.Drone(item)
fit.drones.append(drone) if drone.fits(fit) is True:
fit.drones.append(drone)
else:
return False
drone.amount += 1 drone.amount += 1
eos.db.commit() eos.db.commit()
fit.clear() self.recalc(fit)
fit.calculateModifiedAttributes()
return True return True
else: else:
return False return False
@@ -391,8 +400,7 @@ class Fit(object):
d2.amount += d1.amount d2.amount += d1.amount
d2.amountActive += d1.amountActive if d1.amountActive > 0 else -d2.amountActive d2.amountActive += d1.amountActive if d1.amountActive > 0 else -d2.amountActive
eos.db.commit() eos.db.commit()
fit.clear() self.recalc(fit)
fit.calculateModifiedAttributes()
return True return True
def splitDrones(self, fit, d, amount, l): def splitDrones(self, fit, d, amount, l):
@@ -432,8 +440,7 @@ class Fit(object):
del fit.drones[i] del fit.drones[i]
eos.db.commit() eos.db.commit()
fit.clear() self.recalc(fit)
fit.calculateModifiedAttributes()
return True return True
def toggleDrone(self, fitID, i): def toggleDrone(self, fitID, i):
@@ -445,8 +452,7 @@ class Fit(object):
d.amountActive = d.amount d.amountActive = d.amount
eos.db.commit() eos.db.commit()
fit.clear() self.recalc(fit)
fit.calculateModifiedAttributes()
return True return True
def toggleImplant(self, fitID, i): def toggleImplant(self, fitID, i):
@@ -455,8 +461,7 @@ class Fit(object):
implant.active = not implant.active implant.active = not implant.active
eos.db.commit() eos.db.commit()
fit.clear() self.recalc(fit)
fit.calculateModifiedAttributes()
return True return True
def toggleBooster(self, fitID, i): def toggleBooster(self, fitID, i):
@@ -465,8 +470,7 @@ class Fit(object):
booster.active = not booster.active booster.active = not booster.active
eos.db.commit() eos.db.commit()
fit.clear() self.recalc(fit)
fit.calculateModifiedAttributes()
return True return True
def changeChar(self, fitID, charID): def changeChar(self, fitID, charID):
@@ -478,8 +482,7 @@ class Fit(object):
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
fit.character = self.character = eos.db.getCharacter(charID) fit.character = self.character = eos.db.getCharacter(charID)
fit.clear() self.recalc(fit)
fit.calculateModifiedAttributes()
def isAmmo(self, itemID): def isAmmo(self, itemID):
return eos.db.getItem(itemID).category.name == "Charge" return eos.db.getItem(itemID).category.name == "Charge"
@@ -495,8 +498,7 @@ class Fit(object):
if mod.isValidCharge(ammo): if mod.isValidCharge(ammo):
mod.charge = ammo mod.charge = ammo
fit.clear() self.recalc(fit)
fit.calculateModifiedAttributes()
def getDamagePattern(self, fitID): def getDamagePattern(self, fitID):
if fitID is None: if fitID is None:
@@ -513,8 +515,7 @@ class Fit(object):
fit.damagePattern = self.pattern = pattern fit.damagePattern = self.pattern = pattern
eos.db.commit() eos.db.commit()
fit.clear() self.recalc(fit)
fit.calculateModifiedAttributes()
def setAsPattern(self, fitID, ammo): def setAsPattern(self, fitID, ammo):
if fitID is None: if fitID is None:
@@ -531,8 +532,7 @@ class Fit(object):
setattr(dp, "%sAmount" % attr, ammo.getAttribute("%sDamage" % attr)) setattr(dp, "%sAmount" % attr, ammo.getAttribute("%sDamage" % attr))
fit.damagePattern = dp fit.damagePattern = dp
fit.clear() self.recalc(fit)
fit.calculateModifiedAttributes()
def exportFit(self, fitID): def exportFit(self, fitID):
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
@@ -615,14 +615,12 @@ class Fit(object):
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
# As some items may affect state-limiting attributes of the ship, calculate new attributes first # As some items may affect state-limiting attributes of the ship, calculate new attributes first
fit.clear() self.recalc(fit)
fit.calculateModifiedAttributes()
# Then, check states of all modules and change where needed # Then, check states of all modules and change where needed
changed = self.checkStates(fit, base) changed = self.checkStates(fit, base)
# If any state was changed, recalulate attributes again # If any state was changed, recalulate attributes again
if changed is True: if changed is True:
fit.clear() self.recalc(fit)
fit.calculateModifiedAttributes()
# Old state : New State # Old state : New State
localMap = {State.OVERHEATED: State.ACTIVE, localMap = {State.OVERHEATED: State.ACTIVE,
@@ -653,3 +651,7 @@ class Fit(object):
return state return state
else: else:
return currState return currState
def recalc(self, fit, withBoosters=False):
fit.clear()
fit.calculateModifiedAttributes(withBoosters=withBoosters, dirtyStorage=self.dirtyFitIDs)

View File

@@ -18,7 +18,7 @@
#=============================================================================== #===============================================================================
import eos.db import eos.db
from eos.types import Fleet as Fleet_ from eos.types import Fleet as Fleet_, Wing, Squad
import copy import copy
class Fleet(object): class Fleet(object):
@@ -69,3 +69,147 @@ class Fleet(object):
def deleteFleetByID(self, ID): def deleteFleetByID(self, ID):
fleet = self.getFleetByID(ID) fleet = self.getFleetByID(ID)
self.deleteFleet(fleet) self.deleteFleet(fleet)
def makeLinearFleet(self, fit):
f = Fleet_()
w = Wing()
f.wings.append(w)
s = Squad()
w.squads.append(s)
s.members.append(fit)
fit.fleet = f
eos.db.save(f)
def setLinearFleetCom(self, boostee, booster):
if boostee == booster:
return
if self.getLinearFleet(boostee) is None:
self.removeAssociatedFleetData(boostee)
self.makeLinearFleet(boostee)
squadIDs = set(eos.db.getSquadsIDsWithFitID(boostee.ID))
squad = eos.db.getSquad(squadIDs.pop())
if squad.wing.gang.leader is not None and booster is None:
try:
squad.wing.gang.leader.boostsFits.remove(boostee.ID)
except KeyError:
pass
squad.wing.gang.leader = booster
if self.anyBoosters(squad) is False:
self.removeAssociatedFleetData(boostee)
from service.fit import Fit
sFit = Fit.getInstance()
sFit.recalc(boostee, withBoosters=True)
def setLinearWingCom(self, boostee, booster):
if boostee == booster:
return
if self.getLinearFleet(boostee) is None:
self.removeAssociatedFleetData(boostee)
self.makeLinearFleet(boostee)
squadIDs = set(eos.db.getSquadsIDsWithFitID(boostee.ID))
squad = eos.db.getSquad(squadIDs.pop())
if squad.wing.leader is not None and booster is None:
try:
squad.wing.leader.boostsFits.remove(boostee.ID)
except KeyError:
pass
squad.wing.leader = booster
if self.anyBoosters(squad) is False:
self.removeAssociatedFleetData(boostee)
from service.fit import Fit
sFit = Fit.getInstance()
sFit.recalc(boostee, withBoosters=True)
def setLinearSquadCom(self, boostee, booster):
if boostee == booster:
return
if self.getLinearFleet(boostee) is None:
self.removeAssociatedFleetData(boostee)
self.makeLinearFleet(boostee)
squadIDs = set(eos.db.getSquadsIDsWithFitID(boostee.ID))
squad = eos.db.getSquad(squadIDs.pop())
if squad.leader is not None and booster is None:
try:
squad.leader.boostsFits.remove(boostee.ID)
except KeyError:
pass
squad.leader = booster
if self.anyBoosters(squad) is False:
self.removeAssociatedFleetData(boostee)
from service.fit import Fit
sFit = Fit.getInstance()
sFit.recalc(boostee, withBoosters=True)
def getLinearFleet(self, fit):
sqIDs = eos.db.getSquadsIDsWithFitID(fit.ID)
if len(sqIDs) != 1:
return None
s = eos.db.getSquad(sqIDs[0])
if len(s.members) != 1:
return None
w = s.wing
if len(w.squads) != 1:
return None
f = w.gang
if len(f.wings) != 1:
return None
return f
def removeAssociatedFleetData(self, fit):
squadIDs = set(eos.db.getSquadsIDsWithFitID(fit.ID))
if len(squadIDs) == 0:
return
squads = list(eos.db.getSquad(sqID) for sqID in squadIDs)
wingIDs = set(squad.wing.ID for squad in squads)
fleetIDs = set(squad.wing.gang.ID for squad in squads)
for fleetID in fleetIDs:
fleet = eos.db.getFleet(fleetID)
for wing in fleet.wings:
wingIDs.add(wing.ID)
for wingID in wingIDs:
wing = eos.db.getWing(wingID)
for squad in wing.squads:
squadIDs.add(squad.ID)
for squadID in squadIDs:
squad = eos.db.getSquad(squadID)
if squad.leader is not None:
try:
squad.leader.boostsFits.remove(fit.ID)
except KeyError:
pass
eos.db.remove(squad)
for wingID in wingIDs:
wing = eos.db.getWing(wingID)
if wing.leader is not None:
try:
wing.leader.boostsFits.remove(fit.ID)
except KeyError:
pass
eos.db.remove(wing)
for fleetID in fleetIDs:
fleet = eos.db.getFleet(fleetID)
if fleet.leader is not None:
try:
fleet.leader.boostsFits.remove(fit.ID)
except KeyError:
pass
eos.db.remove(fleet)
fit.fleet = None
return
def anyBoosters(self, squad):
wing = squad.wing
fleet = wing.gang
if squad.leader is None and wing.leader is None and fleet.leader is None:
return False
return True
def loadLinearFleet(self, fit):
if self.getLinearFleet(fit) is None:
return None
squadID = eos.db.getSquadsIDsWithFitID(fit.ID)[0]
s = eos.db.getSquad(squadID)
w = s.wing
f = w.gang
return (f.leader, w.leader, s.leader)

View File

@@ -184,7 +184,6 @@ class Market():
"Impairor": True, # Noobship "Impairor": True, # Noobship
"Velator": True, # Noobship "Velator": True, # Noobship
"Reaper": True, # Noobship "Reaper": True, # Noobship
"TEST Damage Mod": False, # Marked as published by CCP for whatever reason
"Ghost Heavy Missile": False, # Missile used by Sansha "Ghost Heavy Missile": False, # Missile used by Sansha
"Nano Paint": False } # It will be used for ship paint job, no use as of today "Nano Paint": False } # It will be used for ship paint job, no use as of today
@@ -232,6 +231,8 @@ class Market():
"Civilian Standard Missile Launcher": 760, # Ship Equipment > Civilian Modules "Civilian Standard Missile Launcher": 760, # Ship Equipment > Civilian Modules
"Civilian Stasis Webifier": 760, # Ship Equipment > Civilian Modules "Civilian Stasis Webifier": 760, # Ship Equipment > Civilian Modules
"Civilian Warp Disruptor": 760, # Ship Equipment > Civilian Modules "Civilian Warp Disruptor": 760, # Ship Equipment > Civilian Modules
"Hardwiring - Genolution Core Augmentation CA-1": 618, # Implants & Boosters > Implants > Attribute Enhancers > Implant Slot 1
"Hardwiring - Genolution Core Augmentation CA-2": 621, # Implants & Boosters > Implants > Attribute Enhancers > Implant Slot 4
"Hardwiring - Inherent Implants 'Gentry' ZEX10": 1152, # Implants & Boosters > Implants > Skill Hardwiring > Implant Slot 6 > Armor Implants "Hardwiring - Inherent Implants 'Gentry' ZEX10": 1152, # Implants & Boosters > Implants > Skill Hardwiring > Implant Slot 6 > Armor Implants
"Hardwiring - Inherent Implants 'Gentry' ZEX100": 1152, # Implants & Boosters > Implants > Skill Hardwiring > Implant Slot 6 > Armor Implants "Hardwiring - Inherent Implants 'Gentry' ZEX100": 1152, # Implants & Boosters > Implants > Skill Hardwiring > Implant Slot 6 > Armor Implants
"Hardwiring - Inherent Implants 'Gentry' ZEX1000": 1152, # Implants & Boosters > Implants > Skill Hardwiring > Implant Slot 6 > Armor Implants "Hardwiring - Inherent Implants 'Gentry' ZEX1000": 1152, # Implants & Boosters > Implants > Skill Hardwiring > Implant Slot 6 > Armor Implants
@@ -681,9 +682,9 @@ class Market():
"Pulsar Effect Beacon", "Pulsar Effect Beacon",
"Red Giant Beacon", "Red Giant Beacon",
"Wolf Rayet Effect Beacon", "Wolf Rayet Effect Beacon",
"Incursion Effect") "Incursion ship attributes effects")
# Stuff we don't want to see in names # Stuff we don't want to see in names
garbages = ("Effect", "Beacon") garbages = ("Effect", "Beacon", "ship attributes effects")
# Get group with all the system-wide beacons # Get group with all the system-wide beacons
grp = self.getGroup("Effect Beacon") grp = self.getGroup("Effect Beacon")
beacons = self.getItemsByGroup(grp) beacons = self.getItemsByGroup(grp)