""" This file is part of RuneOptimizer. RuneOptimizer 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. RuneOptimizer 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 RuneOptimizer. If not, see . """ class PanelOptimizer(wx.Panel): """ The optimizer form Panel. Parameters ---------- unitId : string Currently selected unit ID (default None) unitStats : int[10] The current stats of the selected unit (HP, ATK, DEF, SPD, CRR, CRD, RES, ACC). (default is [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]). teamIds : string[] IDs of all teams, indexed by the order they appear in the team selector. unitIdSelectorIndex : int[] Array with the IDs of all units, in the same order as displayed in unitChoice, so an ID can be retrived knowing the choice selected index. optionsSizer : wx.BoxSizer Holds every widget that is hidden until a unit is selected. unitInfoBox : wx.StaticBox Box containig the non-editable elements with a unit info. unitChoice : wx.Choice Unit selecctor. Choosing a unit triggers selectUnit. statGrid : wx.Grid.grid Table with the unit base and current stats. runeLabelList : wx.StaticText[6] Labels with all the info about the currently equipped runes. minStatSlidList : wx.Slider[6] List of sliders for the minimum selectors for each stat. minStatTextList : wx.StaticText[6] List of text inputs for the minimum selectors for each stat. statCheckListList : wx.CheckListBox[2] Tho selctors to choose stats allowed in optimization. setChoiceList : wx.Choice[3] List of selector to pik rune sets. levelChoice : wx.Choice Selector to pick the level for the rune optimization. inventoryCheck : wx.Checkbox Checkbox to use only runes in the inventory teamCheckList : wx.CheckboxList : List of selectable teams to exclude from the optimization. progressGauge : wx.Gauge A progress bar timer : wx.Timer Timer to check the update process for new output to display. process : wx.Process The update process. Methods ------- selectAllTeams(event) Selects all teams in the list. deselectAllTeams(event) Deselects all teams in the list. selectUnit(event) Loads a unit info and enables optimizaton options. processResults(jsonData) Processes data obtained from RuneOptimizer. startOptimization(event) Prepares and runs a command optimization. checkProcess(event) Checks the process and update the progress bar. updateComplete(event) Called at process end, rediresct to the result view. minStatChangeBySlider(event) Changes text when a slider is changed. minStatChangeByText(event) Changes the slider when the text is changed. adaptStats(event) Sets all stats requeriments to the unit current values. resetsStats(event) Sets all stats requeriments to the unit base values. """ unitId = None unitStats = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] teamIds = [] unidIdSelectorIndex = [] optionsSizer = None unitInfoBox = None unitChoice = None statGrid = None runeLabelList = None minStatSlidList = None minStatTextList = None statCheckListList = None setChoiceList = None levelChoice = None inventoryCheck = None teamCheckList = None progressGauge = None timer = None process = None def __init__(self, parent, id=wx.ID_ANY): """Initializes the panel. Sets upt all the widgets. Parameters ---------- parent : wx.* Panel parent. id : int, optional ID for the panel (default wx.ID_ANY). """ # Parent constructor wx.Panel.__init__(self, parent=parent, id=id) # Prepare some fonts. monospaceFont = wx.Font( pointSize=8, family=wx.FONTFAMILY_TELETYPE, style=wx.FONTSTYLE_NORMAL, weight=wx.FONTWEIGHT_NORMAL ) # Sizer for all optimization options. Will be hidden until a unit is # selected. self.optionsSizer = wx.BoxSizer(wx.VERTICAL) # Unit info box self.unitInfoBox = wx.StaticBox( self, label="Select unit:", id=wx.ID_ANY, pos=(10, 0), size=(450, 300) ) # Get data from all units and populate the unit selector cursor = conn.execute("SELECT id, name FROM units ORDER BY name") names = [] for row in cursor: names.append(row[1]) self.unidIdSelectorIndex.append(row[0]) self.unitChoice =wx.Choice( parent=self.unitInfoBox, id=wx.ID_ANY, pos=(10, 0), size=(200, 30), choices=names ) self.Bind(wx.EVT_CHOICE, self.selectUnit, self.unitChoice) # Stats table self.statGrid = wx.grid.Grid( parent=self.unitInfoBox, id=wx.ID_ANY, pos=(0, 30), size=(165, 220) ) self.statGrid.CreateGrid( numRows=10, numCols=2 ) self.statGrid.EnableEditing(False) self.statGrid.SetDefaultCellAlignment( horiz=wx.ALIGN_RIGHT, vert=wx.ALIGN_CENTRE ) self.statGrid.SetDefaultCellFont(monospaceFont) self.statGrid.SetColSize(col=0, width=50) self.statGrid.SetColLabelValue(col=0, value="Base") self.statGrid.SetColSize(col=0, width=50) self.statGrid.SetColLabelValue(col=1, value="Current") self.statGrid.SetRowLabelSize(width=35) self.statGrid.SetColLabelSize(height=20) self.statGrid.SetRowSize(row=0, height=20) self.statGrid.SetRowSize(row=1, height=20) self.statGrid.SetRowSize(row=2, height=20) self.statGrid.SetRowSize(row=3, height=20) self.statGrid.SetRowSize(row=4, height=20) self.statGrid.SetRowSize(row=5, height=20) self.statGrid.SetRowSize(row=6, height=20) self.statGrid.SetRowSize(row=7, height=20) self.statGrid.SetRowSize(row=8, height=20) self.statGrid.SetRowSize(row=9, height=20) self.statGrid.SetRowLabelValue(row=0, value=" HP") self.statGrid.SetRowLabelValue(row=1, value="ATK") self.statGrid.SetRowLabelValue(row=2, value="DEF") self.statGrid.SetRowLabelValue(row=3, value="SPD") self.statGrid.SetRowLabelValue(row=4, value="CRR") self.statGrid.SetRowLabelValue(row=5, value="CRD") self.statGrid.SetRowLabelValue(row=6, value="RES") self.statGrid.SetRowLabelValue(row=7, value="ACC") self.statGrid.SetRowLabelValue(row=8, value="EHP") self.statGrid.SetRowLabelValue(row=9, value="DMG") #self.unitContent.Add(self.statGrid) #Rune set list runeBoxList = [ wx.StaticBox( parent=self.unitInfoBox, label="Slot1:", id=wx.ID_ANY, pos=(265, 30), size=(80, 115) ), wx.StaticBox( parent=self.unitInfoBox, label="Slot2:", id=wx.ID_ANY, pos=(350, 30), size=(80, 115) ), wx.StaticBox( parent=self.unitInfoBox, label="Slot3:", id=wx.ID_ANY, pos=(350, 150), size=(80, 115) ), wx.StaticBox( parent=self.unitInfoBox, label="Slot4:", id=wx.ID_ANY, pos=(265, 150), size=(80, 115) ), wx.StaticBox( parent=self.unitInfoBox, label="Slot5:", id=wx.ID_ANY, pos=(180, 150), size=(80, 115) ), wx.StaticBox( parent=self.unitInfoBox, label="Slot6:", id=wx.ID_ANY, pos=(180, 30), size=(80, 115) ) ] self.runeLabelList = [ wx.StaticText( parent=runeBoxList[0], id=wx.ID_ANY, label="", pos=(0, 0), size=(80, 115) ), wx.StaticText( parent=runeBoxList[1], id=wx.ID_ANY, label="", pos=(0, 0), size=(80, 115) ), wx.StaticText( parent=runeBoxList[2], id=wx.ID_ANY, label="", pos=(0, 0), size=(80, 115) ), wx.StaticText( parent=runeBoxList[3], id=wx.ID_ANY, label="", pos=(0, 0), size=(80, 115) ), wx.StaticText( parent=runeBoxList[4], id=wx.ID_ANY, label="", pos=(0, 0), size=(80, 115) ), wx.StaticText( parent=runeBoxList[5], id=wx.ID_ANY, label="", pos=(0, 0), size=(80, 115) ) ] monospaceFont.PointSize -= 2 for i in range(0, 6): runeBoxList[i].SetFont(monospaceFont) monospaceFont.PointSize += 2 # Min stats minStatBox = wx.StaticBox( parent=self, label="Min. stats:", id=wx.ID_ANY, pos=(470, 0), size=(240, 300) ) wx.StaticText( parent=minStatBox, label="HP", id=wx.ID_ANY, pos=(0, 0), size=(30, 25) ) wx.StaticText( parent=minStatBox, label="ATK", id=wx.ID_ANY, pos=(0, 25), size=(30, 25) ) wx.StaticText( parent=minStatBox, label="DEF", id=wx.ID_ANY, pos=(0, 50), size=(30, 25) ) wx.StaticText( parent=minStatBox, label="SPD", id=wx.ID_ANY, pos=(0, 75), size=(30, 25) ) wx.StaticText( parent=minStatBox, label="CRR", id=wx.ID_ANY, pos=(0, 100), size=(30, 25) ) wx.StaticText( parent=minStatBox, label="CRD", id=wx.ID_ANY, pos=(0, 125), size=(30, 25) ) wx.StaticText( parent=minStatBox, label="RES", id=wx.ID_ANY, pos=(0, 150), size=(30, 25) ) wx.StaticText( parent=minStatBox, label="ACC", id=wx.ID_ANY, pos=(0, 175), size=(30, 25) ) wx.StaticText( parent=minStatBox, label="EHP", id=wx.ID_ANY, pos=(0, 200), size=(30, 25) ) wx.StaticText( parent=minStatBox, label="DMG", id=wx.ID_ANY, pos=(0, 225), size=(30, 25) ) self.minStatSlidList = [ wx.Slider( parent=minStatBox, id=wx.ID_ANY, pos=(30, 0), size=(120, 25), name="slid0" ), wx.Slider( parent=minStatBox, id=wx.ID_ANY, pos=(30, 25), size=(120, 25), name="slid1" ), wx.Slider( parent=minStatBox, id=wx.ID_ANY, pos=(30, 50), size=(120, 25), name="slid2" ), wx.Slider( parent=minStatBox, id=wx.ID_ANY, pos=(30, 75), size=(120, 25), name="slid3" ), wx.Slider( parent=minStatBox, id=wx.ID_ANY, pos=(30, 100), size=(120, 25), name="slid4" ), wx.Slider( parent=minStatBox, id=wx.ID_ANY, pos=(30, 125), size=(120, 25), name="slid5" ), wx.Slider( parent=minStatBox, id=wx.ID_ANY, pos=(30, 150), size=(120, 25), name="slid6" ), wx.Slider( parent=minStatBox, id=wx.ID_ANY, pos=(30, 175), size=(120, 25), name="slid7" ), wx.Slider( parent=minStatBox, id=wx.ID_ANY, pos=(30, 200), size=(120, 25), name="slid8" ), wx.Slider( parent=minStatBox, id=wx.ID_ANY, pos=(30, 225), size=(120, 25), name="slid9" ) ] for i in range(0, 10): self.minStatSlidList[i].SetMin(0) self.minStatSlidList[i].SetMax(0) self.minStatSlidList[i].SetValue(0) self.Bind( wx.EVT_SCROLL, self.minStatChangeBySlider, self.minStatSlidList[i] ) self.minStatTextList = [ wx.TextCtrl( parent=minStatBox, id=wx.ID_ANY, value="", pos=(155, 0), size=(65, 25), name="tx0", style=wx.TE_RIGHT|wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB ), wx.TextCtrl( parent=minStatBox, id=wx.ID_ANY, value="", pos=(155, 25), size=(65, 25), name="tx1", style=wx.TE_RIGHT|wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB ), wx.TextCtrl( parent=minStatBox, id=wx.ID_ANY, value="", pos=(155, 50), size=(65, 25), name="tx2", style=wx.TE_RIGHT|wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB ), wx.TextCtrl( parent=minStatBox, id=wx.ID_ANY, value="", pos=(155, 75), size=(65, 25), name="tx3", style=wx.TE_RIGHT|wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB ), wx.TextCtrl( parent=minStatBox, id=wx.ID_ANY, value="", pos=(155, 100), size=(65, 25), name="tx4", style=wx.TE_RIGHT|wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB ), wx.TextCtrl( parent=minStatBox, id=wx.ID_ANY, value="", pos=(155, 125), size=(65, 25), name="tx5", style=wx.TE_RIGHT|wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB ), wx.TextCtrl( parent=minStatBox, id=wx.ID_ANY, value="", pos=(155, 150), size=(65, 25), name="tx6", style=wx.TE_RIGHT|wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB ), wx.TextCtrl( parent=minStatBox, id=wx.ID_ANY, value="", pos=(155, 175), size=(65, 25), name="tx7", style=wx.TE_RIGHT|wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB ), wx.TextCtrl( parent=minStatBox, id=wx.ID_ANY, value="", pos=(155, 200), size=(65, 25), name="tx8", style=wx.TE_RIGHT|wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB ), wx.TextCtrl( parent=minStatBox, id=wx.ID_ANY, value="", pos=(155, 225), size=(65, 25), name="tx9", style=wx.TE_RIGHT|wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB ) ] for i in range(0, 9): self.Bind( wx.EVT_TEXT, self.minStatChangeByText, self.minStatTextList[i] ) minStatsReset = wx.Button( parent=minStatBox, id=wx.ID_ANY, pos=(10, 250), size=(100, 20), style=wx.LC_REPORT, label="Reset all" ) self.Bind(wx.EVT_BUTTON, self.resetStats, minStatsReset) minStatsAdapt = wx.Button( parent=minStatBox, id=wx.ID_ANY, pos=(120, 250), size=(100, 20), style=wx.LC_REPORT, label="Adapt all") self.Bind(wx.EVT_BUTTON, self.adaptStats, minStatsAdapt) self.optionsSizer.Add(minStatBox) # Allowed main stats for even slots names = [ ["HP ", "HP% ", "ATK ", "ATK%", "DEF ", "DEF%"], ["SPD ", "CRR ", "CRD ", "RES ", "ACC "] ] statBox = wx.StaticBox( self, id=wx.ID_ANY, label="Main stats (2, 4, 6):", pos=(10, 300), size=(150, 190) ) self.statCheckListList = [ wx.CheckListBox( parent=statBox, id=wx.ID_ANY, pos=(5, 5), size=(70, 155), choices=names[0] ), wx.CheckListBox( parent=statBox, id=wx.ID_ANY, pos=(70, 5), size=(70, 155), choices=names[1] ) ] self.optionsSizer.Add(statBox) # Rune sets names = [ "", "ENERGY ", "GUARD ", "SWIFT ", "BLADE ", "RAGE ", "FOCUS ", "ENDURE ", "FATAL ", "DESPAIR", "VAMPIRE", "VIOLENT", "NEMESIS", "WILL ", "SHIELD ", "REVENGE", "DESTROY", "FIGHT ", "DETERMI", "ENHANCE", "ACCURAC", "TOLERAN" ] setBox = wx.StaticBox( self, label="Rune Sets:", id=wx.ID_ANY, pos=(170, 300), size=(115, 120) ) self.setChoiceList = [ wx.Choice( parent=setBox, id=wx.ID_ANY, pos=(5, 0), size=(100, 30), choices=names ), wx.Choice( parent=setBox, id=wx.ID_ANY, pos=(5, 30), size=(100, 30), choices=names ), wx.Choice( parent=setBox, id=wx.ID_ANY, pos=(5, 60), size=(100, 30), choices=names ) ] self.optionsSizer.Add(setBox) # Rune level selector levelBox = wx.StaticBox( self, label="Rune Level:", id=wx.ID_ANY, pos=(170, 420), size=(115, 70) ) self.levelChoice = wx.Choice( parent=levelBox, id=wx.ID_ANY, pos=(5, 0), choices=["Current", "+ 12", " + 15"] ) self.optionsSizer.Add(levelBox) # Team list teams = [] cursor = conn.execute(""" SELECT id, name, priority FROM teams ORDER BY priority DESC; """) for row in cursor: self.teamIds.append(row[0]) teams.append(str(row[1]) + " (" + str(row[2]) + ")") teamsBox = wx.StaticBox( parent=self, label="Exclude runes from units in teams", id=wx.ID_ANY, pos=(290, 300), size=(260, 190) ) # Inventory only option self.optionsSizer.Add(teamsBox) self.inventoryCheck = wx.CheckBox( parent=self, id=wx.ID_ANY, label="Only runes in storage", pos=(560, 310), size=(180, 20) ) self.optionsSizer.Add(self.inventoryCheck) self.teamCheckList = wx.CheckListBox( parent=teamsBox, id=wx.ID_ANY, pos=(5, 5), size=(250, 130), choices=teams ) btAllTeams = wx.Button( parent=teamsBox, id=wx.ID_ANY, pos=(5, 135), size=(120, 20), label="Select all" ) btNoTeams = wx.Button( parent=teamsBox, id=wx.ID_ANY, pos=(130, 135), size=(120, 20), label="Deselect all" ) self.Bind(wx.EVT_BUTTON, self.selectAllTeams, btAllTeams) self.Bind(wx.EVT_BUTTON, self.deselectAllTeams, btNoTeams) # Button to start btOptimize = wx.Button( parent=self, id=wx.ID_ANY, pos=(600, 500), size=(100, 40), style=wx.LC_REPORT, label="OPTIMIZE" ) self.optionsSizer.Add(btOptimize) self.Bind(wx.EVT_BUTTON, self.startOptimization, btOptimize) # Progress bar self.progressGauge = wx.Gauge( parent=self, id=wx.ID_ANY, range=20, pos=(50, 485), size=(500, 40), style=wx.GA_HORIZONTAL ) # By default, hide all optimization options self.optionsSizer.ShowItems(False) def selectAllTeams(self, event = None): """Selects all teams in the list. Parameters ---------- event : wxEvent, optional The event that triggered the call (default is None). """ for i in range(0, len(self.teamIds)): self.teamCheckList.Check(i, True) def deselectAllTeams(self, event = None): """Deselects all teams in the list. Parameters ---------- event : wxEvent, optional The event that triggered the call (default is None). """ for i in range(0, len(self.teamIds)): self.teamCheckList.Check(i, False) def selectUnit(self, event = None): """Loads a unit info and enables optimizaton options. Called when a unit is selected in unitChoice. If called from an an event, the unit selected in unitChoice gets priority. When manually called, it uses unitId, so it must be set beforehand. Parameters ---------- event : wxEvent, optional The event that triggered the call (default is None). """ # If its called from an event, it means a unit has been selected in this # panel selector. if event != None: self.unitId = \ self.unidIdSelectorIndex[self.unitChoice.GetSelection()] # It it was not called from an event, it uses self.unitId and sets the # selected unit in the unit selector automatically. else: for i in range(0, len(self.unidIdSelectorIndex)): if self.unidIdSelectorIndex[i] == self.unitId: self.unitChoice.SetSelection(i) break # Get the unit details cursor = conn.execute(""" SELECT base_hp, base_atk, base_def, base_spd, base_crr, base_crd, base_res, base_acc, current_hp, current_atk, current_def, current_spd, current_crr, current_crd, current_res, current_acc, id, name FROM units WHERE id = """ + self.unitId + """; """) row = cursor.fetchone() # First, set sliders max values self.minStatSlidList[0].SetMax(100000) #HP self.minStatSlidList[1].SetMax(5000) #ATK self.minStatSlidList[2].SetMax(5000) #DEF self.minStatSlidList[3].SetMax(500) #SPD self.minStatSlidList[4].SetMax(100) #CRR self.minStatSlidList[5].SetMax(500) #CRD self.minStatSlidList[6].SetMax(100) #RES self.minStatSlidList[7].SetMax(85) #ACC self.minStatSlidList[8].SetMax(500000) #EHP self.minStatSlidList[9].SetMax(8000) #DMG self.unitInfoBox.SetLabel(row[17] + " #" + row[16]) for i in range(0, 8): value = str(row[i]) self.minStatSlidList[i].SetMin(int(value)) if i > 3: value = value + "%" else: value = value + " " self.statGrid.SetCellValue(row=i, col=0, s=value) for i in range(0, 8): value = str(row[8 + i]) self.minStatSlidList[i].SetValue(int(value)) self.minStatTextList[i].SetValue(value) self.unitStats[i] = int(value) if i > 3: value = value + "%" else: value = value + " " self.statGrid.SetCellValue(row=i, col=1, s=value) # Galculate EHP and DMG baseHp = int(self.statGrid.GetCellValue(row=0, col=0)) baseDef = int(self.statGrid.GetCellValue(row=2, col=0).replace("%", "")) baseEhp = math.ceil((((baseDef * 3.5) + 1140) * baseHp) / 1000) self.statGrid.SetCellValue(row=8, col=0, s=str(baseEhp)) self.minStatSlidList[8].SetMin(baseEhp) currentHp = int(self.statGrid.GetCellValue(row=0, col=1)) currentDef = \ int(self.statGrid.GetCellValue(row=2, col=1).replace("%", "")) currentEhp = math.ceil((((currentDef * 3.5) + 1140) * currentHp) / 1000) self.statGrid.SetCellValue(row=8, col=1, s=str(currentEhp)) self.minStatSlidList[8].SetValue(currentEhp) self.minStatTextList[8].SetValue(str(currentEhp)) baseAtk = int(self.statGrid.GetCellValue(row=1, col=0)) baseCrr = int(self.statGrid.GetCellValue(row=4, col=0).replace("%", "")) baseCrd = int(self.statGrid.GetCellValue(row=5, col=0).replace("%", "")) if (baseCrr > 100): # Dont use crit rate over 100 baseCrr = 100 baseDmg = math.ceil( (baseAtk * (100 - baseCrr) / 100) + (baseAtk * ( baseCrr / 100) * baseCrd / 100) ) self.statGrid.SetCellValue(row=9, col=0, s=str(baseDmg)) self.minStatSlidList[9].SetMin(baseDmg) currentAtk = int(self.statGrid.GetCellValue(row=1, col=1)) currentCrr = \ int(self.statGrid.GetCellValue(row=4, col=1).replace("%", "")) currentCrd = \ int(self.statGrid.GetCellValue(row=5, col=1).replace("%", "")) if (currentCrr > 100): # Dont use crit rate over 100 currentCrr = 100 currentDmg = math.ceil( (currentAtk * (100 - currentCrr) / 100) + # Non-crit (currentAtk * ( currentCrr / 100) * currentCrd / 100) # Crit ) self.statGrid.SetCellValue(row=9, col=1, s=str(currentDmg)) self.minStatSlidList[9].SetValue(currentDmg) self.minStatTextList[9].SetValue(str(currentDmg)) # Populate the runes for i in range(0, 6): self.runeLabelList[i].SetLabel("") cursor = conn.execute(""" SELECT id, slot, type FROM runes WHERE unit = """ + self.unitId + """ ORDER BY slot; """) i = 0 currEvenStats = [0, 0, 0] currSets = [0] * 23; for row in cursor: currSets[row[2]] += 1 label = "" label = label + set_names[row[2]] + "\n" # Get all stats cursorStats = conn.execute(""" SELECT slot, stat, value, grind, enchant FROM rune_stats WHERE rune = """ + row[0] + """ ORDER BY slot; """) j = -1 for rowStats in cursorStats: if (int(row[1]) == 2 and rowStats[0] == -1): currEvenStats[0] = rowStats[1] elif (int(row[1]) == 4 and rowStats[0] == -1): currEvenStats[1] = rowStats[1] elif (int(row[1]) == 6 and rowStats[0] == -1): currEvenStats[2] = rowStats[1] while (j != rowStats[0]): label = label + "\n" j = j + 1; label = label + \ stat_names[rowStats[1]] + str(rowStats[2]).rjust(4) + "" if rowStats[3] > 0: label = label + " +" + str(rowStats[3]) self.runeLabelList[i].SetLabel(label) i = i + 1 # Try to infer data to set the default options, reset the rest # Except the team list, rune level and storage: never reset those. self.statCheckListList[0].SetCheckedItems(()) self.statCheckListList[1].SetCheckedItems(()) for i in range(0, 3): if currEvenStats[i] == 1: # HP self.statCheckListList[0].Check(0, True) elif currEvenStats[i] == 2: # HP% self.statCheckListList[0].Check(1, True) elif currEvenStats[i] == 3: # ATK self.statCheckListList[0].Check(2, True) elif currEvenStats[i] == 4: # ATK% self.statCheckListList[0].Check(3, True) elif currEvenStats[i] == 5: # DEF self.statCheckListList[0].Check(4, True) elif currEvenStats[i] == 6: # DEF% self.statCheckListList[0].Check(5, True) elif currEvenStats[i] == 8: # SPD self.statCheckListList[1].Check(0, True) elif currEvenStats[i] == 9: # CRR self.statCheckListList[1].Check(1, True) elif currEvenStats[i] == 10: # CRD self.statCheckListList[1].Check(2, True) elif currEvenStats[i] == 11: # RES self.statCheckListList[1].Check(3, True) elif currEvenStats[i] == 12: # ACC self.statCheckListList[1].Check(4, True) currSetList = [-1, -1, -1] j = 0 for i in range(0, 23): if j < 3: # If a set of 2 has 4 or 2: if i in [1, 2, 4, 6, 7, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]: if currSets[i] >= 4: currSetList[j] = i - 1 currSetList[j + 1] = i - 1 j += 2 elif currSets[i] >= 2: currSetList[j] = i - 1 j += 1 # If a set of 4 has 4 elif i in [3, 5, 8, 10, 11, 13]: if currSets[i] >= 4: currSetList[j] = i - 1 j += 1 # Rune set IDs 9 and 12 dont exist, so do a little trick with indexes. for i in range(0, 3): #if currSetList[i] != 0: actualId = currSetList[i] + 1 if (actualId > 8): actualId -= 1 if (actualId > 11): actualId -= 1 self.setChoiceList[i].SetSelection(actualId) self.optionsSizer.ShowItems(True) def startOptimization(self, event): """Prepares and runs a command optimization. Once is done, switches to the results view. Parameters ---------- event : wxEvent, optional The event that triggered the call (default is None). """ # Example call: # ../RuneOptimizer optimize 7223811472 -l 15 #-e rage,blade --stats atk,crr,crd -h 10000 -f 10 # TODO: Executable name for windows. command = "RuneOptimizer optimize " unitId = self.unitId command += unitId level = self.levelChoice.GetSelection() if level == 1: level = "12" elif level == 2: level = "15" else: level = "current" command += (" --level " + level) sets = "" for i in range (0, 3): selected = self.setChoiceList[i].GetString( self.setChoiceList[i].GetSelection() ).upper().replace(" ", ""); for j in range(0, 22): name = set_names[j].upper() if len(name) > 7: name = name[0:7] if selected == name: sets += set_names[j].lower() + "," if len(sets) > 0: sets = sets[:-1] # TODO: ELSE ERROR command += (" --sets " + sets) stats = "" selected_stats = \ self.statCheckListList[0].GetCheckedItems() + \ self.statCheckListList[1].GetCheckedItems() for s in self.statCheckListList[0].GetCheckedItems(): if s == 0: stats += "hpflat," elif s == 1: stats += "hp," elif s == 2: stats += "atkflat," elif s == 3: stats += "atk," elif s == 4: stats += "defflat," elif s == 5: stats += "def," for s in self.statCheckListList[1].GetCheckedItems(): if s == 0: stats += "spd," elif s == 1: stats += "crr," elif s == 2: stats += "crd," elif s == 3: stats += "res," elif s == 4: stats += "acc," if len(stats) > 0: stats = stats[:-1] # TODO: ELSE ERROR command += (" --stats " + stats) command += (" --min-hp " + str(self.minStatSlidList[0].GetValue())) command += (" --min-atk " + str(self.minStatSlidList[1].GetValue())) command += (" --min-def " + str(self.minStatSlidList[2].GetValue())) command += (" --min-spd " + str(self.minStatSlidList[3].GetValue())) command += (" --min-crr " + str(self.minStatSlidList[4].GetValue())) command += (" --min-crd " + str(self.minStatSlidList[5].GetValue())) command += (" --min-res " + str(self.minStatSlidList[6].GetValue())) command += (" --min-acc " + str(self.minStatSlidList[7].GetValue())) command += (" --min-ehp " + str(self.minStatSlidList[8].GetValue())) command += (" --min-dmg " + str(self.minStatSlidList[9].GetValue())) if self.inventoryCheck.GetValue(): command += " --storage" if len(self.teamCheckList.GetCheckedItems()) > 0: command += " --no-teams " for team in self.teamCheckList.GetCheckedItems(): command += str(self.teamIds[team]) + "," command = command[:-1] command += (" --gui ") print("Command: " + command) self.progressGauge.SetValue(0) # Timer ot periodically check on the process self.timer = wx.Timer(self) self.timer.Start(1000) self.Bind(wx.EVT_TIMER, self.checkProcess) # Create and execute the process self.Bind(wx.EVT_END_PROCESS, self.optimizationComplete) #print("Command: " + command) self.process = wx.Process(self) self.process.Redirect() wx.Execute(command, wx.EXEC_ASYNC, self.process) def checkProcess(self, event): """Checks the process output and updates progress bar. Parameters ---------- event : wxEvent, optional The event that triggered the call. """ if self.process is not None: stream = self.process.GetInputStream() if stream.CanRead(): text = bytes.decode(stream.read()) text = text[:-1] # Remove the last newline # Get only the last line if text.rfind("\n") != -1: text = text[text.rfind("\n") + 1:] # If the line is just a number, it's a progress indicator (1-20) if text.isnumeric() and int(text) <= 20: self.progressGauge.SetValue(int(text)) else: self.timer.Stop() def optimizationComplete(self, event): """Called when the update process is complete. Hiddes the progress image, checks for errors in the output, prints a message annd sets self.updateDone and self.updateError. Parameters ---------- event : wxEvent, optional The event that triggered the call. """ self.timer.Stop() self.progressGauge.SetValue(20) stream = self.process.GetInputStream() jsonText = "" if stream.CanRead(): text = bytes.decode(stream.read()) text = text[:-1] # Remove the last newline # Get only the last line if text.rfind("\n") != -1: text = text[text.rfind("\n") + 1:] jsonText = text # DEBUG: Sample data. #self.unitId = "7223811472" #json = ""{"result_count":5000,"results":[ # {"id":0,"rating":215,"hp":20461,"atk":2521,"dfc":845,"spd":137,"crr":63,"crd":167,"res":29,"acc":15,"ehp":83839,"dmg":5174,"runes":["22677809846","22920616295","21755980400","25633344349","26207902579","28512560500"]}, # {"id":1,"rating":195,"hp":18876,"atk":2521,"dfc":853,"spd":137,"crr":60,"crd":174,"res":37,"acc":8,"ehp":77873,"dmg":5153,"runes":["22677809846","22920616295","27654723287","25633344349","26207902579","28512560500"]}, # {"id":2,"rating":185,"hp":17730,"atk":2521,"dfc":862,"spd":147,"crr":60,"crd":164,"res":28,"acc":15,"ehp":73704,"dmg":5002,"runes":["21564691276","22920616295","27654723287","25633344349","26207902579","22348038576"]}, # {"id":3,"rating":179,"hp":15810,"atk":2431,"dfc":1011,"spd":137,"crr":61,"crd":160,"res":27,"acc":15,"ehp":73968,"dmg":4804,"runes":["21564691276","22920616295","27444728625","22750814840","26670411873","22348038576"]}, # {"id":4,"rating":176,"hp":15319,"atk":2530,"dfc":909,"spd":142,"crr":60,"crd":165,"res":28,"acc":15,"ehp":66202,"dmg":5035,"runes":["21564691276","16759622995","27654723287","22750814840","26207902579","22348038576"]}]} # print ("---- RESULT OUTPUT -------------------------------------------") print(jsonText) print ("--------------------------------------------------------------") if jsonText != "": data = json.loads( jsonText, object_hook=lambda d: SimpleNamespace(**d) ) if data.result_count == 0: wx.MessageBox( parent=self, message="No results found for the current settings.", caption="No results found" ) else: self.GetParent().frameResults.processResults( self.unitId, jsonText ) self.GetParent().ChangeSelection(3) else: wx.MessageBox( parent=self, message="No data received from RuneOptimizer.", caption="Error" ) def minStatChangeBySlider(self, event=None): """Changes text when a slider is changed. Doesn't do validation. Parameters ---------- event : wxEvent, optional The event that triggered the call (default is None). """ slidId = int(event.GetEventObject().GetName().replace("slid", "")) self.minStatTextList[slidId].SetValue( str(event.GetEventObject().GetValue()) ) def minStatChangeByText(self, event=None): """Changes the slider when the text is changed. Validates the text value. Parameters ---------- event : wxEvent, optional The event that triggered the call (default is None). """ textId = int(event.GetEventObject().GetName().replace("tx", "")) if event.GetEventObject().GetValue().isdigit() == False and \ event.GetEventObject().GetValue() != "": event.GetEventObject().SetValue( str(self.minStatSlidList[textId].GetValue()) ) minValue = self.minStatSlidList[textId].GetMin() maxValue = self.minStatSlidList[textId].GetMax() if event.GetEventObject().GetValue().isdigit(): value = int(event.GetEventObject().GetValue()) else: value = minValue # Unbind scroll event of the slider, set value and rebind. self.Unbind(wx.EVT_SCROLL, self.minStatSlidList[textId]) self.minStatSlidList[textId].SetValue(value) self.Bind( wx.EVT_SCROLL, self.minStatChangeBySlider, self.minStatSlidList[textId] ) def adaptStats(self, event=None): """Sets all stats requeriments to the unit current values. Parameters ---------- event : wxEvent, optional The event that triggered the call (default is None). """ for i in range(0, 10): self.minStatSlidList[i].SetValue(self.unitStats[i]) self.minStatTextList[i].SetValue(str(self.unitStats[i])) def resetStats(self, event=None): """Sets all stats requeriments to the unit base values. Parameters ---------- event : wxEvent, optional The event that triggered the call (default is None). """ for i in range(0, 10): self.minStatSlidList[i].SetValue(self.minStatSlidList[i].GetMin()) self.minStatTextList[i].SetValue( str(self.minStatSlidList[i].GetMin()) )