Merge branch 'newTempChar'

This commit is contained in:
blitzmann
2015-09-24 17:16:14 -04:00
9 changed files with 139 additions and 100 deletions

View File

@@ -5,7 +5,7 @@ debug = False
gamedataCache = True
saveddataCache = True
gamedata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "staticdata", "eve.db")), sys.getfilesystemencoding())
saveddata_connectionstring = 'sqlite:///:memory:'
saveddata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "saveddata", "saveddata.db")), sys.getfilesystemencoding())
#Autodetect path, only change if the autodetection bugs out.
path = dirname(unicode(__file__, sys.getfilesystemencoding()))

View File

@@ -21,11 +21,10 @@
from sqlalchemy.orm import validates, reconstructor
from eos.effectHandlerHelpers import HandledItem
import eos.db
import eos
class Character(object):
__all5 = None
__all0 = None
__itemList = None
__itemIDMap = None
__itemNameMap = None
@@ -33,7 +32,6 @@ class Character(object):
@classmethod
def getSkillList(cls):
if cls.__itemList is None:
import eos.db
cls.__itemList = eos.db.getItemsByCategory("Skill")
return cls.__itemList
@@ -66,36 +64,38 @@ class Character(object):
@classmethod
def getAll5(cls):
if cls.__all5 is None:
import eos.db
all5 = eos.db.getCharacter("All 5")
if all5 is None:
all5 = Character("All 5")
all5.defaultLevel = 5
eos.db.add(all5)
all5 = eos.db.getCharacter("All 5")
cls.__all5 = all5
return cls.__all5
if all5 is None:
# We do not have to be afraid of committing here and saving
# edited character data. If this ever runs, it will be during the
# get character list phase when pyfa first starts
all5 = Character("All 5", 5)
eos.db.save(all5)
return all5
@classmethod
def getAll0(cls):
if cls.__all0 is None:
import eos.db
all0 = eos.db.getCharacter("All 0")
if all0 is None:
all0 = Character("All 0")
all0.defaultLevel = None
eos.db.add(all0)
all0 = eos.db.getCharacter("All 0")
cls.__all0 = all0
return cls.__all0
if all0 is None:
all0 = Character("All 0")
eos.db.save(all0)
def __init__(self, name):
return all0
def __init__(self, name, defaultLevel=None):
self.name = name
self.__owner = None
self.defaultLevel = None
self.defaultLevel = defaultLevel
self.__skills = []
self.__skillIdMap = {}
self.dirtySkills = set()
for item in self.getSkillList():
self.addSkill(Skill(item.ID, self.defaultLevel))
self.__implants = eos.saveddata.fit.HandledImplantBoosterList()
self.apiKey = None
@@ -104,12 +104,12 @@ class Character(object):
self.__skillIdMap = {}
for skill in self.__skills:
self.__skillIdMap[skill.itemID] = skill
self.dirtySkills = set()
def apiUpdateCharSheet(self, skills):
del self.__skills[:]
self.__skillIdMap.clear()
for skillRow in skills:
self.addSkill(Skill(skillRow["typeID"], skillRow["level"]))
@property
@@ -120,6 +120,10 @@ class Character(object):
def owner(self, owner):
self.__owner = owner
@property
def skills(self):
return self.__skills
def addSkill(self, skill):
self.__skills.append(skill)
self.__skillIdMap[skill.itemID] = skill
@@ -137,11 +141,7 @@ class Character(object):
skill = self.__skillIdMap.get(item.ID)
if skill is None:
if self.defaultLevel is None:
skill = Skill(item, 0, False, False)
else:
skill = Skill(item, self.defaultLevel, False, True)
skill = Skill(item, self.defaultLevel, False, True)
self.addSkill(skill)
return skill
@@ -150,40 +150,51 @@ class Character(object):
def implants(self):
return self.__implants
def iterSkills(self):
for item in self.getSkillList():
yield self.getSkill(item)
@property
def isDirty(self):
return len(self.dirtySkills) > 0
def saveLevels(self):
if self == self.getAll5() or self == self.getAll0():
raise ReadOnlyException("This character is read-only")
for skill in self.dirtySkills:
skill.saveLevel()
self.dirtySkills = set()
eos.db.commit()
def filteredSkillIncrease(self, filter, *args, **kwargs):
for element in self.iterSkills():
for element in self.skills:
if filter(element):
element.increaseItemAttr(*args, **kwargs)
def filteredSkillMultiply(self, filter, *args, **kwargs):
for element in self.iterSkills():
for element in self.skills:
if filter(element):
element.multiplyItemAttr(*args, **kwargs)
def filteredSkillBoost(self, filter, *args, **kwargs):
for element in self.iterSkills():
for element in self.skills:
if filter(element):
element.boostItemAttr(*args, **kwargs)
def calculateModifiedAttributes(self, fit, runTime, forceProjected = False):
if forceProjected: return
for skill in self.iterSkills():
for skill in self.skills:
fit.register(skill)
skill.calculateModifiedAttributes(fit, runTime)
def clear(self):
for skill in self.iterSkills():
for skill in self.skills:
skill.clear()
def __deepcopy__(self, memo):
copy = Character("%s copy" % self.name)
copy.apiKey = self.apiKey
copy.apiID = self.apiID
for skill in self.iterSkills():
for skill in self.skills:
copy.addSkill(Skill(skill.itemID, skill.level, False, skill.learned))
return copy
@@ -199,7 +210,7 @@ class Character(object):
else: return val
class Skill(HandledItem):
def __init__(self, item, level = 0, ro = False, learned = True):
def __init__(self, item, level=0, ro=False, learned=True):
self.__item = item if not isinstance(item, int) else None
self.itemID = item.ID if not isinstance(item, int) else item
self.__level = level if learned else None
@@ -214,14 +225,18 @@ class Skill(HandledItem):
def build(self, ro):
self.__ro = ro
self.__suppressed = False
self.activeLevel = self.__level
def saveLevel(self):
self.__level = self.activeLevel
@property
def learned(self):
return self.__level is not None
return self.activeLevel is not None
@property
def level(self):
return self.__level or 0
return self.activeLevel or 0
@level.setter
def level(self, level):
@@ -231,7 +246,11 @@ class Skill(HandledItem):
if hasattr(self, "_Skill__ro") and self.__ro == True:
raise ReadOnlyException()
self.__level = level
self.activeLevel = level
if self.activeLevel == self.__level and self in self.character.dirtySkills:
self.character.dirtySkills.remove(self)
else:
self.character.dirtySkills.add(self)
@property
def item(self):

View File

@@ -247,7 +247,7 @@ class Store(object):
dict.clear()
# Go through everything which can be used as gang booster
for thing in chain(fitBooster.modules, fitBooster.implants, fitBooster.character.iterSkills(), (fitBooster.ship,)):
for thing in chain(fitBooster.modules, fitBooster.implants, fitBooster.character.skills, (fitBooster.ship,)):
if thing.item is None:
continue
for effect in thing.item.effects.itervalues():

View File

@@ -21,8 +21,8 @@ class ChangeAffectingSkills(ContextMenu):
self.charID = fit.character.ID
if self.sChar.getCharName(self.charID) in ("All 0", "All 5"):
return False
#if self.sChar.getCharName(self.charID) in ("All 0", "All 5"):
# return False
if srcContext == "fittingShip":
fitID = self.mainFrame.getActiveFit()
@@ -94,6 +94,7 @@ class ChangeAffectingSkills(ContextMenu):
fitID = self.mainFrame.getActiveFit()
self.sFit.changeChar(fitID, self.charID)
wx.PostEvent(self.mainFrame, GE.CharListUpdated())
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
ChangeAffectingSkills.register()

View File

@@ -34,6 +34,8 @@ class CharacterEditor(wx.Frame):
wx.Frame.__init__ (self, parent, id=wx.ID_ANY, title=u"pyfa: Character Editor", pos=wx.DefaultPosition,
size=wx.Size(641, 600), style=wx.DEFAULT_FRAME_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.TAB_TRAVERSAL)
self.mainFrame = parent
i = wx.IconFromBitmap(bitmapLoader.getBitmap("character_small", "icons"))
self.SetIcon(i)
@@ -45,8 +47,6 @@ class CharacterEditor(wx.Frame):
self.navSizer = wx.BoxSizer(wx.HORIZONTAL)
sChar = service.Character.getInstance()
charList = sChar.getCharacterList()
charList.sort(key=lambda t: t[1])
self.btnSave = wx.Button(self, wx.ID_SAVE)
self.btnSave.Hide()
@@ -56,14 +56,17 @@ class CharacterEditor(wx.Frame):
self.characterRename.Hide()
self.characterRename.Bind(wx.EVT_TEXT_ENTER, self.processRename)
self.skillTreeChoice = wx.Choice(self, wx.ID_ANY, style=0)
self.charChoice = wx.Choice(self, wx.ID_ANY, style=0)
self.navSizer.Add(self.charChoice, 1, wx.ALL | wx.EXPAND, 5)
self.refreshCharacterList()
'''
for id, name, active in charList:
i = self.skillTreeChoice.Append(name, id)
i = self.charChoice.Append(name, id)
if active:
self.skillTreeChoice.SetSelection(i)
self.navSizer.Add(self.skillTreeChoice, 1, wx.ALL | wx.EXPAND, 5)
self.charChoice.SetSelection(i)
'''
buttons = (("new", wx.ART_NEW),
("rename", bitmapLoader.getBitmap("rename", "icons")),
@@ -128,7 +131,16 @@ class CharacterEditor(wx.Frame):
self.registerEvents()
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
def refreshCharacterList(self, event=None):
sChar = service.Character.getInstance()
charList = sChar.getCharacterList()
self.charChoice.Clear()
for id, name, active in charList:
i = self.charChoice.Append(name, id)
if active:
self.charChoice.SetSelection(i)
def editingFinished(self, event):
del self.disableWin
@@ -137,7 +149,8 @@ class CharacterEditor(wx.Frame):
def registerEvents(self):
self.Bind(wx.EVT_CLOSE, self.closeEvent)
self.skillTreeChoice.Bind(wx.EVT_CHOICE, self.charChanged)
self.Bind(GE.CHAR_LIST_UPDATED, self.refreshCharacterList)
self.charChoice.Bind(wx.EVT_CHOICE, self.charChanged)
def closeEvent(self, event):
del self.disableWin
@@ -147,7 +160,7 @@ class CharacterEditor(wx.Frame):
def restrict(self):
self.btnRename.Enable(False)
self.btnDelete.Enable(False)
self.aview.stDisabledTip.Show(True)
self.aview.stDisabledTip.Show()
self.aview.inputID.Enable(False)
self.aview.inputKey.Enable(False)
self.aview.charChoice.Enable(False)
@@ -159,7 +172,7 @@ class CharacterEditor(wx.Frame):
def unrestrict(self):
self.btnRename.Enable(True)
self.btnDelete.Enable(True)
self.aview.stDisabledTip.Show(False)
self.aview.stDisabledTip.Hide()
self.aview.inputID.Enable(True)
self.aview.inputKey.Enable(True)
self.aview.btnFetchCharList.Enable(True)
@@ -182,14 +195,14 @@ class CharacterEditor(wx.Frame):
event.Skip()
def getActiveCharacter(self):
selection = self.skillTreeChoice.GetCurrentSelection()
return self.skillTreeChoice.GetClientData(selection) if selection is not None else None
selection = self.charChoice.GetCurrentSelection()
return self.charChoice.GetClientData(selection) if selection is not None else None
def new(self, event):
sChar = service.Character.getInstance()
charID = sChar.new()
id = self.skillTreeChoice.Append(sChar.getCharName(charID), charID)
self.skillTreeChoice.SetSelection(id)
id = self.charChoice.Append(sChar.getCharName(charID), charID)
self.charChoice.SetSelection(id)
self.unrestrict()
self.btnSave.SetLabel("Create")
self.rename(None)
@@ -198,9 +211,9 @@ class CharacterEditor(wx.Frame):
def rename(self, event):
if event is not None:
self.btnSave.SetLabel("Rename")
self.skillTreeChoice.Hide()
self.charChoice.Hide()
self.characterRename.Show()
self.navSizer.Replace(self.skillTreeChoice, self.characterRename)
self.navSizer.Replace(self.charChoice, self.characterRename)
self.characterRename.SetFocus()
for btn in (self.btnNew, self.btnCopy, self.btnRename, self.btnDelete):
btn.Hide()
@@ -225,9 +238,9 @@ class CharacterEditor(wx.Frame):
charID = self.getActiveCharacter()
sChar.rename(charID, newName)
self.skillTreeChoice.Show()
self.charChoice.Show()
self.characterRename.Hide()
self.navSizer.Replace(self.characterRename, self.skillTreeChoice)
self.navSizer.Replace(self.characterRename, self.charChoice)
for btn in (self.btnNew, self.btnCopy, self.btnRename, self.btnDelete):
btn.Show()
self.navSizer.Add(btn, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 2)
@@ -235,16 +248,13 @@ class CharacterEditor(wx.Frame):
self.navSizer.Remove(self.btnSave)
self.btnSave.Hide()
self.navSizer.Layout()
selection = self.skillTreeChoice.GetCurrentSelection()
self.skillTreeChoice.Delete(selection)
self.skillTreeChoice.Insert(newName, selection, charID)
self.skillTreeChoice.SetSelection(selection)
self.refreshCharacterList()
def copy(self, event):
sChar = service.Character.getInstance()
charID = sChar.copy(self.getActiveCharacter())
id = self.skillTreeChoice.Append(sChar.getCharName(charID), charID)
self.skillTreeChoice.SetSelection(id)
id = self.charChoice.Append(sChar.getCharName(charID), charID)
self.charChoice.SetSelection(id)
self.unrestrict()
self.btnSave.SetLabel("Copy")
self.rename(None)
@@ -253,9 +263,9 @@ class CharacterEditor(wx.Frame):
def delete(self, event):
sChar = service.Character.getInstance()
sChar.delete(self.getActiveCharacter())
sel = self.skillTreeChoice.GetSelection()
self.skillTreeChoice.Delete(sel)
self.skillTreeChoice.SetSelection(sel - 1)
sel = self.charChoice.GetSelection()
self.charChoice.Delete(sel)
self.charChoice.SetSelection(sel - 1)
newSelection = self.getActiveCharacter()
if sChar.getCharName(newSelection) in ("All 0", "All 5"):
self.restrict()
@@ -366,12 +376,8 @@ class SkillTreeView (wx.Panel):
sChar = service.Character.getInstance()
charID = self.Parent.Parent.getActiveCharacter()
sMkt = service.Market.getInstance()
if sChar.getCharName(charID) not in ("All 0", "All 5"):
self.levelChangeMenu.selection = sMkt.getItem(self.skillTreeListCtrl.GetPyData(item))
self.PopupMenu(self.levelChangeMenu)
else:
self.statsMenu.selection = sMkt.getItem(self.skillTreeListCtrl.GetPyData(item))
self.PopupMenu(self.statsMenu)
self.levelChangeMenu.selection = sMkt.getItem(self.skillTreeListCtrl.GetPyData(item))
self.PopupMenu(self.levelChangeMenu)
def changeLevel(self, event):
level = self.levelIds.get(event.Id)
@@ -383,6 +389,8 @@ class SkillTreeView (wx.Panel):
self.skillTreeListCtrl.SetItemText(selection, "Level %d" % level if isinstance(level, int) else level, 1)
sChar.changeLevel(charID, skillID, level)
sChar.saveCharacter(charID)
wx.PostEvent(self.Parent.Parent, GE.CharListUpdated())
event.Skip()
@@ -547,6 +555,7 @@ class APIView (wx.Panel):
u"Please select another character or make a new one.", style=wx.ALIGN_CENTER )
self.stDisabledTip.Wrap( -1 )
hintSizer.Add( self.stDisabledTip, 0, wx.TOP | wx.BOTTOM, 10 )
self.stDisabledTip.Hide()
hintSizer.AddStretchSpacer()
pmainSizer.Add(hintSizer, 0, wx.EXPAND, 5)
@@ -652,7 +661,7 @@ class APIView (wx.Panel):
sChar = service.Character.getInstance()
try:
list = sChar.charList(self.Parent.Parent.getActiveCharacter(), self.inputID.GetLineText(0), self.inputKey.GetLineText(0))
list = sChar.apiCharList(self.Parent.Parent.getActiveCharacter(), self.inputID.GetLineText(0), self.inputKey.GetLineText(0))
except service.network.AuthenticationError, e:
self.stStatus.SetLabel("Authentication failure. Please check keyID and vCode combination.")
except service.network.TimeoutError, e:

View File

@@ -81,7 +81,6 @@ class CharacterSelection(wx.Panel):
choice.Clear()
charList = sChar.getCharacterList()
sChar.getCharacterList()
picked = False
for id, name, active in charList:

View File

@@ -418,6 +418,8 @@ class MainFrame(wx.Frame):
self.Bind(wx.EVT_MENU, self.goWiki, id = menuBar.wikiId)
# EVE Forums
self.Bind(wx.EVT_MENU, self.goForums, id = menuBar.forumId)
# Save current character
self.Bind(wx.EVT_MENU, self.saveChar, id = menuBar.saveCharId)
#Clipboard exports
self.Bind(wx.EVT_MENU, self.exportToClipboard, id=wx.ID_COPY)
@@ -482,6 +484,12 @@ class MainFrame(wx.Frame):
atable = wx.AcceleratorTable(actb)
self.SetAcceleratorTable(atable)
def saveChar(self, event):
sChr = service.Character.getInstance()
charID = self.charSelection.getActiveCharacter()
sChr.saveCharacter(charID)
wx.PostEvent(self, GE.CharListUpdated())
def AdditionsTabSelect(self, event):
selTab = self.additionsSelect.index(event.GetId())

View File

@@ -36,6 +36,7 @@ class MainMenuBar(wx.MenuBar):
self.exportHtmlId = wx.NewId()
self.wikiId = wx.NewId()
self.forumId = wx.NewId()
self.saveCharId = wx.NewId()
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
@@ -70,6 +71,8 @@ class MainMenuBar(wx.MenuBar):
pasteText = "&From Clipboard" + ("\tCTRL+V" if 'wxMSW' in wx.PlatformInfo else "")
editMenu.Append(wx.ID_COPY, copyText, "Export a fit to the clipboard")
editMenu.Append(wx.ID_PASTE, pasteText, "Import a fit from the clipboard")
editMenu.AppendSeparator()
editMenu.Append(self.saveCharId, "Save Character")
# Character menu
windowMenu = wx.Menu()

View File

@@ -171,32 +171,34 @@ class Character(object):
thread.start()
def all0(self):
all0 = eos.types.Character.getAll0()
eos.db.commit()
return all0
return eos.types.Character.getAll0()
def all0ID(self):
return self.all0().ID
def all5(self):
all5 = eos.types.Character.getAll5()
eos.db.commit()
return all5
return eos.types.Character.getAll5()
def all5ID(self):
return self.all5().ID
def getCharacterList(self):
baseChars = [eos.types.Character.getAll0(), eos.types.Character.getAll5()]
# Flush incase all0 & all5 weren't in the db yet
eos.db.commit()
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 if not c.isDirty else "{} *".format(c.name), c == sFit.character), eos.db.getCharacterList())
def getCharacter(self, charID):
char = eos.db.getCharacter(charID)
return char
def saveCharacter(self, charID):
"""Save edited skills"""
if charID == self.all5ID() or charID == self.all0ID():
return
char = eos.db.getCharacter(charID)
char.saveLevels()
def getSkillGroups(self):
cat = eos.db.getCategory(16)
groups = []
@@ -223,18 +225,18 @@ class Character(object):
skill = eos.db.getCharacter(charID).getSkill(skillID)
return skill.level if skill.learned else "Not learned"
def rename(self, charID, newName):
char = eos.db.getCharacter(charID)
char.name = newName
eos.db.commit()
def getCharName(self, charID):
return eos.db.getCharacter(charID).name
def new(self):
char = eos.types.Character("New Character")
eos.db.save(char)
return char.ID
def getCharName(self, charID):
return eos.db.getCharacter(charID).name
def rename(self, charID, newName):
char = eos.db.getCharacter(charID)
char.name = newName
eos.db.commit()
def copy(self, charID):
char = eos.db.getCharacter(charID)
@@ -259,7 +261,7 @@ class Character(object):
id, key, default, _ = self.getApiDetails(charID)
return id is not "" and key is not "" and default is not ""
def charList(self, charID, userID, apiKey):
def apiCharList(self, charID, userID, apiKey):
char = eos.db.getCharacter(charID)
char.apiID = userID
@@ -306,8 +308,6 @@ class Character(object):
else:
skill.level = level
eos.db.commit()
def addImplant(self, charID, itemID):
char = eos.db.getCharacter(charID)
implant = eos.types.Implant(eos.db.getItem(itemID))