PanelResults.py 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209
  1. """
  2. This file is part of RuneOptimizer.
  3. RuneOptimizer is free software: you can redistribute it and/or modify it
  4. under the terms of the GNU General Public License as published by the Free
  5. Software Foundation, either version 3 of the License, or (at your option)
  6. any later version.
  7. RuneOptimizer is distributed in the hope that it will be useful, but WITHOUT
  8. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  9. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  10. more details.
  11. You should have received a copy of the GNU General Public License along with
  12. RuneOptimizer. If not, see <https://www.gnu.org/licenses/>.
  13. """
  14. class PanelResults(wx.Panel):
  15. """
  16. The panel that shows results.
  17. Parameters
  18. ----------
  19. unitId : string
  20. ID of the unit being optimized (default "").
  21. unitName : string
  22. Name of the unit being optimized (default "").
  23. data : Python Object
  24. Results from RuneOptimizer (default None).
  25. unitStats : int[10]
  26. The current stats of the unit being optimized. (default is
  27. [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).
  28. page : int
  29. Currently displayed page, 0-index (default 0).
  30. totalPages : int
  31. Number of pages of results (default 0).
  32. linesPerPage : int
  33. Number of results to show per page (default 10).
  34. selectedResultndex : int
  35. Selected result index (default -1).
  36. unitNameLabel : wx.StaticText
  37. Labels for the unit name.
  38. tableSizer : wx.BoxSizer
  39. Holds the result list. Hidden until processResults is called.
  40. detailsSizer : wx.BoxSizer
  41. Holds every widget that is hidden until a result is selected.
  42. resultGrid : wx.Grid.grid
  43. Table of results.
  44. pgPrevButton : wx.Button
  45. Button to go to the previous page.
  46. pageLabel : wx.StaticText
  47. Label to indicate the current and maximum pages.
  48. pgPrevButton : wx.Button
  49. Button to go to the previous page.
  50. statGrid : wx.Grid.grid
  51. Table to show the new stats with the selected result.
  52. idLabelList : wx.StaticText[6]
  53. Labels with the IDs of the runes in the current result.
  54. locationLabelList : wx.StaticText[6]
  55. Labels with the locations of the runes in the current result.
  56. setLabelList : wx.StaticText[6]
  57. Labels with the set names of the runes in the current result.
  58. mainLabelList : wx.StaticText[6]
  59. Labels with the main stats of the runes in the current result.
  60. innateLabelList : wx.StaticText[6]
  61. Labels with the innates of the runes in the current result.
  62. statLabelList : wx.StaticText[6][4]
  63. Labels with the stats of the runes in the current result.
  64. Methods
  65. -------
  66. processResults(jsonData)
  67. Processes data obtained from RuneOptimizer.
  68. pgPrev(event)
  69. Goes to the previous result page.
  70. pgNext(event)
  71. Goes to the next result page.
  72. applyRunes(event)
  73. Applies the runes in the currently selected result.
  74. printResults()
  75. Populates the results table with the results in the currently
  76. selected page.
  77. resultSelected(event)
  78. Populates and shows the runes and effective stats with the
  79. currently seleced result.
  80. recalculteStatsOfModifiedUnits():
  81. Recalculates the stats of all the units marked as modified.
  82. """
  83. unitId = ""
  84. unitName = ""
  85. data = None
  86. unitStats = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  87. page = 0
  88. totalPages = 0
  89. linesPerPage = 10
  90. selectedResultIndex = -1
  91. unitNameLabel = None
  92. tableSizer = None
  93. detailsSizer = None
  94. resultGrid = None
  95. pgPrevButton = None
  96. pageLabel = None
  97. pgNextButton = None
  98. statGrid = None
  99. idLabelList = None
  100. locationLabelList = None
  101. setLabelList = None
  102. mainLabelList = None
  103. innateLabelList = None
  104. statLabelList = None
  105. def __init__(self, parent, id=wx.ID_ANY):
  106. """Initializes the panel.
  107. Sets upt all the widgets.
  108. Parameters
  109. ----------
  110. parent : wx.*
  111. Panel parent.
  112. id : int, optional
  113. ID for the panel (default wx.ID_ANY).
  114. """
  115. # Parent constructor
  116. wx.Panel.__init__(self, parent=parent, id=id)
  117. # Prepare some fonts
  118. titleFont = wx.Font(
  119. pointSize=14, family=wx.FONTFAMILY_DEFAULT,
  120. style=wx.FONTSTYLE_NORMAL, weight=wx.FONTWEIGHT_BOLD
  121. )
  122. monospaceFont = wx.Font(
  123. pointSize=10, family=wx.FONTFAMILY_TELETYPE,
  124. style=wx.FONTSTYLE_NORMAL, weight=wx.FONTWEIGHT_NORMAL
  125. )
  126. monospaceFontBold = wx.Font(
  127. pointSize=8, family=wx.FONTFAMILY_TELETYPE,
  128. style=wx.FONTSTYLE_NORMAL, weight=wx.FONTWEIGHT_BOLD
  129. )
  130. monospaceFontItalic = wx.Font(
  131. pointSize=8, family=wx.FONTFAMILY_TELETYPE,
  132. style=wx.FONTSTYLE_ITALIC, weight=wx.FONTWEIGHT_NORMAL
  133. )
  134. # Unit name and id
  135. self.unitNameLabel = wx.StaticText(
  136. parent=self, id=wx.ID_ANY, label="Nothing yet. Optimize something!",
  137. pos=(0, 0), size=(400, 30)
  138. )
  139. self.unitNameLabel.SetFont(titleFont)
  140. # Contains the results table. Hidden until they are loaded.
  141. self.tableSizer = wx.BoxSizer(wx.VERTICAL)
  142. # Contains all thigs to be shown once a result is selected
  143. self.detailsSizer = wx.BoxSizer(wx.VERTICAL)
  144. # The result list table
  145. self.resultGrid = wx.grid.Grid(
  146. parent=self, id=wx.ID_ANY, pos=(0, 30), size=(525, 170)
  147. )
  148. self.resultGrid.CreateGrid(
  149. numRows=10, numCols=11
  150. )
  151. self.resultGrid.EnableEditing(False)
  152. self.resultGrid.SetSelectionMode(wx.grid.Grid.GridSelectionModes.SelectRows)
  153. self.resultGrid.SetDefaultCellAlignment(
  154. horiz=wx.ALIGN_RIGHT, vert=wx.ALIGN_CENTRE
  155. )
  156. monospaceFont.PointSize -= 1
  157. self.resultGrid.SetDefaultCellFont(monospaceFont)
  158. monospaceFont.PointSize += 1
  159. self.resultGrid.SetRowLabelSize(width=35)
  160. self.resultGrid.SetColLabelValue(col=0, value="Rating")
  161. self.resultGrid.SetColSize(col=0, width=50)
  162. self.resultGrid.SetColLabelValue(col=1, value="HP")
  163. self.resultGrid.SetColSize(col=1, width=50)
  164. self.resultGrid.SetColLabelValue(col=2, value="ATK")
  165. self.resultGrid.SetColSize(col=2, width=40)
  166. self.resultGrid.SetColLabelValue(col=3, value="DEF")
  167. self.resultGrid.SetColSize(col=3, width=40)
  168. self.resultGrid.SetColLabelValue(col=4, value="SPD")
  169. self.resultGrid.SetColSize(col=4, width=40)
  170. self.resultGrid.SetColLabelValue(col=5, value="CRR")
  171. self.resultGrid.SetColSize(col=5, width=40)
  172. self.resultGrid.SetColLabelValue(col=6, value="CRD")
  173. self.resultGrid.SetColSize(col=6, width=40)
  174. self.resultGrid.SetColLabelValue(col=7, value="RES")
  175. self.resultGrid.SetColSize(col=7, width=40)
  176. self.resultGrid.SetColLabelValue(col=8, value="ACC")
  177. self.resultGrid.SetColSize(col=8, width=40)
  178. self.resultGrid.SetColLabelValue(col=9, value="EHP")
  179. self.resultGrid.SetColSize(col=9, width=60)
  180. self.resultGrid.SetColLabelValue(col=10, value="DMG")
  181. self.resultGrid.SetColSize(col=10, width=50)
  182. self.resultGrid.SetColLabelSize(height=20)
  183. self.resultGrid.SetDefaultRowSize(height=15)
  184. self.Bind(
  185. wx.grid.EVT_GRID_SELECT_CELL, self.resultSelected, self.resultGrid
  186. )
  187. self.tableSizer.Add(self.resultGrid)
  188. # Paginator
  189. self.pgPrevButton = wx.Button(
  190. parent=self, id=wx.ID_ANY, pos=(530, 30), size=(40, 50),
  191. style=wx.LC_REPORT, label="Prev\npage"
  192. )
  193. self.tableSizer.Add(self.pgPrevButton)
  194. self.pageLabel = wx.StaticText(
  195. parent=self,id=wx.ID_ANY, pos=(530, 80), size=(40, 15),
  196. style=wx.ALIGN_CENTRE_HORIZONTAL, label="1/1"
  197. )
  198. self.tableSizer.Add(self.pageLabel)
  199. self.pgNextButton = wx.Button(
  200. parent=self, id=wx.ID_ANY, pos=(530, 100), size=(40, 50),
  201. style=wx.LC_REPORT, label="Next\npage"
  202. )
  203. self.tableSizer.Add(self.pgNextButton)
  204. self.Bind(wx.EVT_BUTTON, self.pgPrev, self.pgPrevButton)
  205. self.Bind(wx.EVT_BUTTON, self.pgNext, self.pgNextButton)
  206. # Stats table
  207. self.statGrid = wx.grid.Grid(
  208. parent=self, id=wx.ID_ANY, pos=(0, 210),
  209. size=(185, 220), style=wx.LC_REPORT
  210. )
  211. self.statGrid.CreateGrid(
  212. numRows=10, numCols=2
  213. )
  214. self.statGrid.EnableEditing(False)
  215. self.statGrid.SetDefaultCellAlignment(
  216. horiz=wx.ALIGN_RIGHT, vert=wx.ALIGN_CENTRE
  217. )
  218. self.statGrid.SetDefaultCellFont(monospaceFont)
  219. self.statGrid.SetColSize(col=0, width=70)
  220. self.statGrid.SetColLabelValue(col=0, value="Value")
  221. self.statGrid.SetColLabelValue(col=1, value="Diff")
  222. self.statGrid.SetRowLabelSize(width=35)
  223. self.statGrid.SetColLabelSize(height=20)
  224. self.statGrid.SetRowSize(row=0, height=20)
  225. self.statGrid.SetRowSize(row=1, height=20)
  226. self.statGrid.SetRowSize(row=2, height=20)
  227. self.statGrid.SetRowSize(row=3, height=20)
  228. self.statGrid.SetRowSize(row=4, height=20)
  229. self.statGrid.SetRowSize(row=5, height=20)
  230. self.statGrid.SetRowSize(row=6, height=20)
  231. self.statGrid.SetRowSize(row=7, height=20)
  232. self.statGrid.SetRowSize(row=8, height=20)
  233. self.statGrid.SetRowSize(row=9, height=20)
  234. self.statGrid.SetRowLabelValue(row=0, value=" HP")
  235. self.statGrid.SetRowLabelValue(row=1, value="ATK")
  236. self.statGrid.SetRowLabelValue(row=2, value="DEF")
  237. self.statGrid.SetRowLabelValue(row=3, value="SPD")
  238. self.statGrid.SetRowLabelValue(row=4, value="CRR")
  239. self.statGrid.SetRowLabelValue(row=5, value="CRD")
  240. self.statGrid.SetRowLabelValue(row=6, value="RES")
  241. self.statGrid.SetRowLabelValue(row=7, value="ACC")
  242. self.statGrid.SetRowLabelValue(row=8, value="EHP")
  243. self.statGrid.SetRowLabelValue(row=9, value="DMG")
  244. self.detailsSizer.Add(self.statGrid)
  245. #Rune set list
  246. monospaceFont.PointSize -= 2
  247. rubeBoxList = [
  248. wx.StaticBox(
  249. parent=self, label="Slot1:",id=wx.ID_ANY,
  250. pos=(350, 210), size=(140, 160)
  251. ),
  252. wx.StaticBox(
  253. parent=self, label="Slot2:",id=wx.ID_ANY,
  254. pos=(500, 210), size=(140, 160)
  255. ),
  256. wx.StaticBox(
  257. parent=self, label="Slot3:",id=wx.ID_ANY,
  258. pos=(500, 375), size=(140, 160)
  259. ),
  260. wx.StaticBox(
  261. parent=self, label="Slot4:",id=wx.ID_ANY,
  262. pos=(350, 375), size=(140, 160)
  263. ),
  264. wx.StaticBox(
  265. parent=self, label="Slot5:",id=wx.ID_ANY,
  266. pos=(200, 375), size=(140, 160)
  267. ),
  268. wx.StaticBox(
  269. parent=self, label="Slot6:",id=wx.ID_ANY,
  270. pos=(200, 210), size=(140, 160)
  271. )
  272. ]
  273. for i in range(0, 6):
  274. rubeBoxList[i].SetFont(monospaceFont)
  275. self.detailsSizer.Add(rubeBoxList[i])
  276. self.idLabelList = [
  277. wx.StaticText(
  278. rubeBoxList[0], id=wx.ID_ANY, label="", pos=(5, 0), size=(120, 10)
  279. ),
  280. wx.StaticText(
  281. rubeBoxList[1], id=wx.ID_ANY, label="", pos=(5, 0), size=(120, 10)
  282. ),
  283. wx.StaticText(
  284. rubeBoxList[2], id=wx.ID_ANY, label="", pos=(5, 0), size=(120, 10)
  285. ),
  286. wx.StaticText(
  287. rubeBoxList[3], id=wx.ID_ANY, label="", pos=(5, 0), size=(120, 10)
  288. ),
  289. wx.StaticText(
  290. rubeBoxList[4], id=wx.ID_ANY, label="", pos=(5, 0), size=(120, 10)
  291. ),
  292. wx.StaticText(
  293. rubeBoxList[5], id=wx.ID_ANY, label="", pos=(5, 0), size=(120, 10)
  294. )
  295. ]
  296. self.locationLabelList = [
  297. wx.StaticText(
  298. rubeBoxList[0], id=wx.ID_ANY, label="", pos=(5, 15), size=(120, 10)
  299. ),
  300. wx.StaticText(
  301. rubeBoxList[1], id=wx.ID_ANY, label="", pos=(5, 15), size=(120, 10)
  302. ),
  303. wx.StaticText(
  304. rubeBoxList[2], id=wx.ID_ANY, label="", pos=(5, 15), size=(120, 10)
  305. ),
  306. wx.StaticText(
  307. rubeBoxList[3], id=wx.ID_ANY, label="", pos=(5, 15), size=(120, 10)
  308. ),
  309. wx.StaticText(
  310. rubeBoxList[4], id=wx.ID_ANY, label="", pos=(5, 15), size=(120, 10)
  311. ),
  312. wx.StaticText(
  313. rubeBoxList[5], id=wx.ID_ANY, label="", pos=(5, 15), size=(120, 10)
  314. ),
  315. ]
  316. self.setLabelList = [
  317. wx.StaticText(
  318. rubeBoxList[0], id=wx.ID_ANY, label="", pos=(5, 30), size=(120, 10)
  319. ),
  320. wx.StaticText(
  321. rubeBoxList[1], id=wx.ID_ANY, label="", pos=(5, 30), size=(120, 10)
  322. ),
  323. wx.StaticText(
  324. rubeBoxList[2], id=wx.ID_ANY, label="", pos=(5, 30), size=(120, 10)
  325. ),
  326. wx.StaticText(
  327. rubeBoxList[3], id=wx.ID_ANY, label="", pos=(5, 30), size=(120, 10)
  328. ),
  329. wx.StaticText(
  330. rubeBoxList[4], id=wx.ID_ANY, label="", pos=(5, 30), size=(120, 10)
  331. ),
  332. wx.StaticText(
  333. rubeBoxList[5], id=wx.ID_ANY, label="", pos=(5, 30), size=(120, 10)
  334. ),
  335. ]
  336. wx.StaticLine(
  337. parent=rubeBoxList[0], id=wx.ID_ANY,
  338. pos=(5, 45), size=(130, 1), style=wx.LC_REPORT
  339. )
  340. wx.StaticLine(
  341. parent=rubeBoxList[1], id=wx.ID_ANY,
  342. pos=(5, 45), size=(130, 1), style=wx.LC_REPORT
  343. )
  344. wx.StaticLine(
  345. parent=rubeBoxList[2], id=wx.ID_ANY,
  346. pos=(5, 45), size=(130, 1), style=wx.LC_REPORT
  347. )
  348. wx.StaticLine(
  349. parent=rubeBoxList[3], id=wx.ID_ANY,
  350. pos=(5, 45), size=(130, 1), style=wx.LC_REPORT
  351. )
  352. wx.StaticLine(
  353. parent=rubeBoxList[4], id=wx.ID_ANY,
  354. pos=(5, 45), size=(130, 1), style=wx.LC_REPORT
  355. )
  356. wx.StaticLine(
  357. parent=rubeBoxList[5], id=wx.ID_ANY,
  358. pos=(5, 45), size=(130, 1), style=wx.LC_REPORT
  359. )
  360. self.mainLabelList = [
  361. wx.StaticText(
  362. parent=rubeBoxList[0], id=wx.ID_ANY, label="",
  363. pos=(5, 50), size=(120, 10)
  364. ),
  365. wx.StaticText(
  366. parent=rubeBoxList[1], id=wx.ID_ANY, label="",
  367. pos=(5, 50), size=(120, 10)
  368. ),
  369. wx.StaticText(
  370. parent=rubeBoxList[2], id=wx.ID_ANY, label="",
  371. pos=(5, 50), size=(120, 10)
  372. ),
  373. wx.StaticText(
  374. parent=rubeBoxList[3], id=wx.ID_ANY, label="",
  375. pos=(5, 50), size=(120, 10)
  376. ),
  377. wx.StaticText(
  378. parent=rubeBoxList[4], id=wx.ID_ANY, label="",
  379. pos=(5, 50), size=(120, 10)
  380. ),
  381. wx.StaticText(
  382. parent=rubeBoxList[5], id=wx.ID_ANY, label="",
  383. pos=(5, 50), size=(120, 10)
  384. ),
  385. ]
  386. for i in range(0, 6):
  387. self.mainLabelList[i].SetFont(monospaceFontBold)
  388. self.innateLabelList = [
  389. wx.StaticText(
  390. parent=rubeBoxList[0], id=wx.ID_ANY, label="",
  391. pos=(5, 65), size=(120, 10)
  392. ),
  393. wx.StaticText(
  394. parent=rubeBoxList[1], id=wx.ID_ANY, label="",
  395. pos=(5, 65), size=(120, 10)
  396. ),
  397. wx.StaticText(
  398. parent=rubeBoxList[2], id=wx.ID_ANY, label="",
  399. pos=(5, 65), size=(120, 10)
  400. ),
  401. wx.StaticText(
  402. parent=rubeBoxList[3], id=wx.ID_ANY, label="",
  403. pos=(5, 65), size=(120, 10)
  404. ),
  405. wx.StaticText(
  406. parent=rubeBoxList[4], id=wx.ID_ANY, label="",
  407. pos=(5, 65), size=(120, 10)
  408. ),
  409. wx.StaticText(
  410. parent=rubeBoxList[5], id=wx.ID_ANY, label="",
  411. pos=(5, 65), size=(120, 10)
  412. )
  413. ]
  414. for i in range(0, 6):
  415. self.innateLabelList[i].SetFont(monospaceFontItalic)
  416. self.statLabelList = [
  417. [
  418. wx.StaticText(
  419. parent=rubeBoxList[0], id=wx.ID_ANY, label="",
  420. pos=(5, 80), size=(120, 10)
  421. ),
  422. wx.StaticText(
  423. parent=rubeBoxList[0], id=wx.ID_ANY, label="",
  424. pos=(5, 95), size=(120, 10)
  425. ),
  426. wx.StaticText(
  427. parent=rubeBoxList[0], id=wx.ID_ANY, label="",
  428. pos=(5, 110), size=(120, 10)
  429. ),
  430. wx.StaticText(
  431. parent=rubeBoxList[0], id=wx.ID_ANY, label="",
  432. pos=(5, 125), size=(120, 10)
  433. )
  434. ],
  435. [
  436. wx.StaticText(
  437. parent=rubeBoxList[1], id=wx.ID_ANY, label="",
  438. pos=(5, 80), size=(120, 10)
  439. ),
  440. wx.StaticText(
  441. parent=rubeBoxList[1], id=wx.ID_ANY, label="",
  442. pos=(5, 95), size=(120, 10)
  443. ),
  444. wx.StaticText(
  445. parent=rubeBoxList[1], id=wx.ID_ANY, label="",
  446. pos=(5, 110), size=(120, 10)
  447. ),
  448. wx.StaticText(
  449. parent=rubeBoxList[1], id=wx.ID_ANY, label="",
  450. pos=(5, 125), size=(120, 10)
  451. )
  452. ],
  453. [
  454. wx.StaticText(
  455. parent=rubeBoxList[2], id=wx.ID_ANY, label="",
  456. pos=(5, 80), size=(120, 10)
  457. ),
  458. wx.StaticText(
  459. parent=rubeBoxList[2], id=wx.ID_ANY, label="",
  460. pos=(5, 95), size=(120, 10)
  461. ),
  462. wx.StaticText(
  463. parent=rubeBoxList[2], id=wx.ID_ANY, label="",
  464. pos=(5, 110), size=(120, 10)
  465. ),
  466. wx.StaticText(
  467. parent=rubeBoxList[2], id=wx.ID_ANY, label="",
  468. pos=(5, 125), size=(120, 10)
  469. )
  470. ],
  471. [
  472. wx.StaticText(
  473. parent=rubeBoxList[3], id=wx.ID_ANY, label="",
  474. pos=(5, 80), size=(120, 10)
  475. ),
  476. wx.StaticText(
  477. parent=rubeBoxList[3], id=wx.ID_ANY, label="",
  478. pos=(5, 95), size=(120, 10)
  479. ),
  480. wx.StaticText(
  481. parent=rubeBoxList[3], id=wx.ID_ANY, label="",
  482. pos=(5, 110), size=(120, 10)
  483. ),
  484. wx.StaticText(
  485. parent=rubeBoxList[3], id=wx.ID_ANY, label="",
  486. pos=(5, 125), size=(120, 10)
  487. )
  488. ],
  489. [
  490. wx.StaticText(
  491. parent=rubeBoxList[4], id=wx.ID_ANY, label="",
  492. pos=(5, 80), size=(120, 10)
  493. ),
  494. wx.StaticText(
  495. parent=rubeBoxList[4], id=wx.ID_ANY, label="",
  496. pos=(5, 95), size=(120, 10)
  497. ),
  498. wx.StaticText(
  499. parent=rubeBoxList[4], id=wx.ID_ANY, label="",
  500. pos=(5, 110), size=(120, 10)
  501. ),
  502. wx.StaticText(
  503. parent=rubeBoxList[4], id=wx.ID_ANY, label="",
  504. pos=(5, 125), size=(120, 10)
  505. )
  506. ],
  507. [
  508. wx.StaticText(
  509. parent=rubeBoxList[5], id=wx.ID_ANY, label="",
  510. pos=(5, 80), size=(120, 10)
  511. ),
  512. wx.StaticText(
  513. parent=rubeBoxList[5], id=wx.ID_ANY, label="",
  514. pos=(5, 95), size=(120, 10)
  515. ),
  516. wx.StaticText(
  517. parent=rubeBoxList[5], id=wx.ID_ANY, label="",
  518. pos=(5, 110), size=(120, 10)
  519. ),
  520. wx.StaticText(
  521. parent=rubeBoxList[5], id=wx.ID_ANY, label="",
  522. pos=(5, 125), size=(120, 10)
  523. )
  524. ],
  525. ]
  526. # Action buttons
  527. applyButton = wx.Button(
  528. parent=self, id=wx.ID_ANY, pos=(10, 450), size=(165, 60),
  529. style=wx.LC_REPORT, label="Apply runes"
  530. )
  531. self.Bind(wx.EVT_BUTTON, self.applyRunes, applyButton)
  532. self.detailsSizer.Add(applyButton)
  533. # By default, hide everything TODO
  534. self.tableSizer.ShowItems(False)
  535. self.detailsSizer.ShowItems(False)
  536. def processResults(self, unitId=None, jsonData=""):
  537. """Processes data obtained from RuneOptimizer.
  538. Reads the JSON data and initializes the property data.
  539. Automatically calls printResults();
  540. Parameters
  541. ----------
  542. jsonData : str
  543. The data, as received from RuneOptimizer.
  544. """
  545. if unitId != None:
  546. self.unitId = unitId
  547. cursor = conn.execute("""
  548. SELECT
  549. current_hp,
  550. current_atk,
  551. current_def,
  552. current_spd,
  553. current_crr,
  554. current_crd,
  555. current_res,
  556. current_acc,
  557. name
  558. FROM units
  559. WHERE
  560. id = '""" + unitId + """';
  561. """)
  562. row = cursor.fetchone()
  563. self.unitName = row[8]
  564. for i in range(0, 8):
  565. self.unitStats[i] = row[i]
  566. # Calculate EHP and DMG
  567. hp = row[0]
  568. dfc = row[2]
  569. ehp = math.ceil((((dfc * 3.5) + 1140) * hp) / 1000)
  570. self.unitStats[8] = ehp
  571. atk = row[1]
  572. crr = row[4]
  573. crd = row[5]
  574. dmg = math.ceil(
  575. (atk * (100 - crr) / 100) + # Non-crit
  576. (atk * ( crr / 100) * crd / 100) # Crit
  577. )
  578. self.unitStats[9] = dmg
  579. self.data = json.loads(
  580. jsonData,
  581. object_hook=lambda d: SimpleNamespace(**d)
  582. )
  583. self.totalPages = math.ceil(len(self.data.results) / self.linesPerPage)
  584. self.page = 0
  585. self.printResults()
  586. def pgPrev(self, event):
  587. """Goes to the previous page of results.
  588. Checks if there is a previous page to go to. If so, it
  589. automatically calls printResults();
  590. Parameters
  591. ----------
  592. event : wx.Event, optional
  593. The event that triggered the call (default is None).
  594. """
  595. if self.page > 0:
  596. self.page -= 1
  597. self.printResults()
  598. def pgNext(self, event):
  599. """Goes to the next page of results.
  600. Checks if there is a next page to go to. If so, it
  601. automatically calls printResults();
  602. Parameters
  603. ----------
  604. event : wx.Event, optional
  605. The event that triggered the call (default is None).
  606. """
  607. if self.page < self.totalPages:
  608. self.page += 1
  609. self.printResults()
  610. def applyRunes(self, event):
  611. """Applies the selected results and saves data to the database.
  612. Parameters
  613. ----------
  614. event : wx.Event, optional
  615. The event that triggered the call (default is None).
  616. """
  617. global conn
  618. if (self.selectedResultIndex < 0):
  619. # TODO: Show error
  620. return;
  621. # First, unassign all runes currently assigned to the unit
  622. cursor = conn.execute(
  623. """
  624. UPDATE runes SET unit = null
  625. WHERE unit = ?
  626. """,
  627. (
  628. self.unitId,
  629. )
  630. )
  631. # Next, mark units as modified
  632. cursor = conn.execute(
  633. """
  634. UPDATE units SET modified = 1
  635. WHERE
  636. id = ? OR
  637. id IN (SELECT unit FROM runes WHERE id IN (?, ?, ?, ?, ?, ?))
  638. """,
  639. (
  640. self.unitId,
  641. self.data.results[self.selectedResultIndex].runes[0],
  642. self.data.results[self.selectedResultIndex].runes[1],
  643. self.data.results[self.selectedResultIndex].runes[2],
  644. self.data.results[self.selectedResultIndex].runes[3],
  645. self.data.results[self.selectedResultIndex].runes[4],
  646. self.data.results[self.selectedResultIndex].runes[5]
  647. )
  648. )
  649. # Lastly, assign the runes
  650. cursor = conn.execute(
  651. """
  652. UPDATE runes SET unit = ?
  653. WHERE id IN (?, ?, ?, ?, ?, ?)
  654. """,
  655. (
  656. self.unitId,
  657. self.data.results[self.selectedResultIndex].runes[0],
  658. self.data.results[self.selectedResultIndex].runes[1],
  659. self.data.results[self.selectedResultIndex].runes[2],
  660. self.data.results[self.selectedResultIndex].runes[3],
  661. self.data.results[self.selectedResultIndex].runes[4],
  662. self.data.results[self.selectedResultIndex].runes[5]
  663. )
  664. )
  665. conn.commit()
  666. # TODO: Recalculate all modified units stats from the database
  667. print("Applied!")
  668. recalculteStatsOfModifiedUnits()
  669. print("All recalculated!")
  670. # Fetch the new values for self.unitStats
  671. cursor = conn.execute(
  672. """
  673. SELECT
  674. current_hp,
  675. current_atk,
  676. current_def,
  677. current_spd,
  678. current_crr,
  679. current_crd,
  680. current_res,
  681. current_acc
  682. FROM units
  683. WHERE id = ?
  684. """,
  685. (
  686. self.unitId,
  687. )
  688. )
  689. row = cursor.fetchone()
  690. for i in range(0, 8):
  691. self.unitStats[i] = int(row[i])
  692. self.unitStats[9] = math.ceil(
  693. (((self.unitStats[2] * 3.5) + 1140) * self.unitStats[0]) / 1000
  694. )
  695. self.unitStats[10] = math.ceil(
  696. (self.unitStats[1] * (100 - self.unitStats[4]) / 100) +
  697. (
  698. (
  699. self.unitStats[1] +
  700. (self.unitStats[1] * self.unitStats[5] / 100)
  701. ) *
  702. self.unitStats[4] / 100
  703. )
  704. )
  705. self.resultSelected(None)
  706. def printResults(self):
  707. """Populates the results table with the results in the
  708. currently selected page.
  709. It doesn't change the selcted result. Automaticcaly called
  710. after changing pages or processing data.
  711. """
  712. self.pgPrevButton.Enable(True)
  713. self.pgNextButton.Enable(True)
  714. if self.totalPages == 1:
  715. self.pgPrevButton.Enable(False)
  716. self.pgNextButton.Enable(False)
  717. elif self.page == 0:
  718. self.pgPrevButton.Enable(False)
  719. elif self.page + 1 == self.totalPages:
  720. self.pgNextButton.Enable(False)
  721. self.pageLabel.SetLabel(
  722. str(self.page + 1) + "/" + str(self.totalPages)
  723. )
  724. for i in range(0, 10):
  725. rindex = i + (self.linesPerPage * self.page)
  726. if (len(self.data.results) > rindex):
  727. self.resultGrid.SetRowLabelValue(row=i, value=str(rindex + 1))
  728. result = self.data.results[rindex]
  729. self.resultGrid.SetCellValue(row=i, col=0, s=str(result.rating))
  730. self.resultGrid.SetCellValue(row=i, col=1, s=str(result.hp))
  731. self.resultGrid.SetCellValue(row=i, col=2, s=str(result.atk))
  732. self.resultGrid.SetCellValue(row=i, col=3, s=str(result.dfc))
  733. self.resultGrid.SetCellValue(row=i, col=4, s=str(result.spd))
  734. self.resultGrid.SetCellValue(row=i, col=5, s=str(result.crr))
  735. self.resultGrid.SetCellValue(row=i, col=6, s=str(result.crd))
  736. self.resultGrid.SetCellValue(row=i, col=7, s=str(result.res))
  737. self.resultGrid.SetCellValue(row=i, col=8, s=str(result.acc))
  738. self.resultGrid.SetCellValue(row=i, col=9, s=str(result.ehp))
  739. self.resultGrid.SetCellValue(row=i, col=10, s=str(result.dmg))
  740. else:
  741. self.resultGrid.SetRowLabelValue(row=i, value="")
  742. for j in range(0, 11):
  743. self.resultGrid.SetCellValue(row=i, col=j, s="")
  744. # Display the unit name
  745. self.unitNameLabel.SetLabel(self.unitName + " #" + self.unitId)
  746. # Make the table visible
  747. self.tableSizer.ShowItems(True)
  748. def resultSelected(self, event):
  749. """Populates and shows the runes and effective stats with the
  750. currently seleced result.
  751. It also enables the apply button.
  752. Parameters
  753. ----------
  754. event : wx.Event, optional
  755. The event that triggered the call (default is None).
  756. """
  757. selectedLine = self.resultGrid.GetSelectedRows()[0]
  758. self.selectedResultIndex = \
  759. selectedLine + (self.linesPerPage * self.page)
  760. if self.selectedResultIndex >= len(self.data.results):
  761. self.selectedResultIndex = -1;
  762. self.detailsSizer.ShowItems(False)
  763. return
  764. self.statGrid.SetCellValue(
  765. row=0, col=0,
  766. s=str(self.data.results[self.selectedResultIndex].hp) + " "
  767. )
  768. diff = \
  769. self.data.results[self.selectedResultIndex].hp - self.unitStats[0]
  770. if (diff < 0):
  771. self.statGrid.SetCellValue(
  772. row=0, col=1, s="- " + str(abs(diff)) + " "
  773. )
  774. self.statGrid.SetCellTextColour(
  775. row=0, col=1, colour=wx.Colour(red=255, green=0, blue=0)
  776. )
  777. elif (diff > 0):
  778. self.statGrid.SetCellValue(
  779. row=0, col=1, s="+ " + str(diff) + " "
  780. )
  781. self.statGrid.SetCellTextColour(
  782. row=0, col=1, colour=wx.Colour(red=0, green=255, blue=0)
  783. )
  784. else:
  785. self.statGrid.SetCellValue(row=0, col=1, s="")
  786. self.statGrid.SetCellValue(
  787. row=1, col=0,
  788. s=str(self.data.results[self.selectedResultIndex].atk) + " "
  789. )
  790. diff = \
  791. self.data.results[self.selectedResultIndex].atk - self.unitStats[1]
  792. if (diff < 0):
  793. self.statGrid.SetCellValue(
  794. row=1, col=1, s="- " + str(abs(diff)) + " "
  795. )
  796. self.statGrid.SetCellTextColour(
  797. row=1, col=1, colour=wx.Colour(red=255, green=0, blue=0)
  798. )
  799. elif (diff > 0):
  800. self.statGrid.SetCellValue(row=1, col=1, s="+ " + str(diff) + " ")
  801. self.statGrid.SetCellTextColour(
  802. row=1, col=1, colour=wx.Colour(red=0, green=255, blue=0)
  803. )
  804. else:
  805. self.statGrid.SetCellValue(row=1, col=1, s="")
  806. self.statGrid.SetCellValue(
  807. row=2, col=0,
  808. s=str(self.data.results[self.selectedResultIndex].dfc) + " "
  809. )
  810. diff = \
  811. self.data.results[self.selectedResultIndex].dfc - self.unitStats[2]
  812. if (diff < 0):
  813. self.statGrid.SetCellValue(
  814. row=2, col=1, s="- " + str(abs(diff)) + " "
  815. )
  816. self.statGrid.SetCellTextColour(
  817. row=1, col=1, colour=wx.Colour(red=255, green=0, blue=0)
  818. )
  819. elif (diff > 0):
  820. self.statGrid.SetCellValue(
  821. row=2, col=1, s="+ " + str(diff) + " "
  822. )
  823. self.statGrid.SetCellTextColour(
  824. row=2, col=1, colour=wx.Colour(red=0, green=255, blue=0)
  825. )
  826. else:
  827. self.statGrid.SetCellValue(row=2, col=1, s="")
  828. self.statGrid.SetCellValue(
  829. row=3, col=0,
  830. s=str(self.data.results[self.selectedResultIndex].spd) + " "
  831. )
  832. diff = \
  833. self.data.results[self.selectedResultIndex].spd - self.unitStats[3]
  834. if (diff < 0):
  835. self.statGrid.SetCellValue(
  836. row=3, col=1, s="- " + str(abs(diff)) + " "
  837. )
  838. self.statGrid.SetCellTextColour(
  839. row=3, col=1, colour=wx.Colour(red=255, green=0, blue=0)
  840. )
  841. elif (diff > 0):
  842. self.statGrid.SetCellValue(
  843. row=3, col=1, s="+ " + str(diff) + " "
  844. )
  845. self.statGrid.SetCellTextColour(
  846. row=3, col=1, colour=wx.Colour(red=0, green=255, blue=0)
  847. )
  848. else:
  849. self.statGrid.SetCellValue(row=3, col=1, s="")
  850. self.statGrid.SetCellValue(
  851. row=4, col=0,
  852. s=str(self.data.results[self.selectedResultIndex].crr) + "%"
  853. )
  854. diff = \
  855. self.data.results[self.selectedResultIndex].crr - self.unitStats[4]
  856. if (diff < 0):
  857. self.statGrid.SetCellValue(
  858. row=4, col=1, s="- " + str(abs(diff)) + "%"
  859. )
  860. self.statGrid.SetCellTextColour(
  861. row=4, col=1, colour=wx.Colour(red=255, green=0, blue=0)
  862. )
  863. elif (diff > 0):
  864. self.statGrid.SetCellValue(row=4, col=1, s="+ " + str(diff) + "%")
  865. self.statGrid.SetCellTextColour(
  866. row=4, col=1, colour=wx.Colour(red=0, green=255, blue=0)
  867. )
  868. else:
  869. self.statGrid.SetCellValue(row=4, col=1, s="")
  870. self.statGrid.SetCellValue(
  871. row=5, col=0,
  872. s=str(self.data.results[self.selectedResultIndex].crd) + "%"
  873. )
  874. diff = \
  875. self.data.results[self.selectedResultIndex].crd - self.unitStats[5]
  876. if (diff < 0):
  877. self.statGrid.SetCellValue(
  878. row=5, col=1, s="- " + str(abs(diff)) + "%"
  879. )
  880. self.statGrid.SetCellTextColour(
  881. row=5, col=1, colour=wx.Colour(red=255, green=0, blue=0)
  882. )
  883. elif (diff > 0):
  884. self.statGrid.SetCellValue(
  885. row=5, col=1, s="+ " + str(diff) + "%"
  886. )
  887. self.statGrid.SetCellTextColour(
  888. row=5, col=1, colour=wx.Colour(red=0, green=255, blue=0)
  889. )
  890. else:
  891. self.statGrid.SetCellValue(row=5, col=1, s="")
  892. self.statGrid.SetCellValue(
  893. row=6, col=0,
  894. s=str(self.data.results[self.selectedResultIndex].res) + "%"
  895. )
  896. diff = \
  897. self.data.results[self.selectedResultIndex].res - self.unitStats[6]
  898. if (diff < 0):
  899. self.statGrid.SetCellValue(
  900. row=6, col=1, s="- " + str(abs(diff)) + "%"
  901. )
  902. self.statGrid.SetCellTextColour(
  903. row=6, col=1, colour=wx.Colour(red=255, green=0, blue=0)
  904. )
  905. elif (diff > 0):
  906. self.statGrid.SetCellValue(row=6, col=1, s="+ " + str(diff) + "%")
  907. self.statGrid.SetCellTextColour(
  908. row=6, col=1, colour=wx.Colour(red=0, green=255, blue=0)
  909. )
  910. else:
  911. self.statGrid.SetCellValue(row=6, col=1, s="")
  912. self.statGrid.SetCellValue(
  913. row=7, col=0, s=str(self.data.results[self.selectedResultIndex].acc) + "%"
  914. )
  915. diff = \
  916. self.data.results[self.selectedResultIndex].acc - self.unitStats[7]
  917. if (diff < 0):
  918. self.statGrid.SetCellValue(
  919. row=7, col=1, s="- " + str(abs(diff)) + "%"
  920. )
  921. self.statGrid.SetCellTextColour(
  922. row=7, col=1, colour=wx.Colour(red=255, green=0, blue=0)
  923. )
  924. elif (diff > 0):
  925. self.statGrid.SetCellValue(
  926. row=7, col=1, s="+ " + str(diff) + "%"
  927. )
  928. self.statGrid.SetCellTextColour(
  929. row=7, col=1, colour=wx.Colour(red=0, green=255, blue=0)
  930. )
  931. else:
  932. self.statGrid.SetCellValue(row=7, col=1, s="")
  933. self.statGrid.SetCellValue(
  934. row=8, col=0,
  935. s=str(self.data.results[self.selectedResultIndex].ehp) + " "
  936. )
  937. diff = \
  938. self.data.results[self.selectedResultIndex].ehp - self.unitStats[8]
  939. if (diff < 0):
  940. self.statGrid.SetCellValue(
  941. row=8, col=1, s="- " + str(abs(diff)) + " "
  942. )
  943. self.statGrid.SetCellTextColour(
  944. row=8, col=1, colour=wx.Colour(red=255, green=0, blue=0)
  945. )
  946. elif (diff > 0):
  947. self.statGrid.SetCellValue(
  948. row=8, col=1, s="+ " + str(diff) + " "
  949. )
  950. self.statGrid.SetCellTextColour(
  951. row=8, col=1, colour=wx.Colour(red=0, green=255, blue=0)
  952. )
  953. else:
  954. self.statGrid.SetCellValue(row=8, col=1, s="")
  955. self.statGrid.SetCellValue(
  956. row=9, col=0,
  957. s=str(self.data.results[self.selectedResultIndex].dmg) + " "
  958. )
  959. diff = self.data.results[self.selectedResultIndex].dmg - self.unitStats[9]
  960. if (diff < 0):
  961. self.statGrid.SetCellValue(
  962. row=9, col=1, s="- " + str(abs(diff)) + " "
  963. )
  964. self.statGrid.SetCellTextColour(
  965. row=9, col=1, colour=wx.Colour(red=255, green=0, blue=0)
  966. )
  967. elif (diff > 0):
  968. self.statGrid.SetCellValue(row=9, col=1, s="+ " + str(diff) + " ")
  969. self.statGrid.SetCellTextColour(
  970. row=9, col=1, colour=wx.Colour(red=0, green=255, blue=0)
  971. )
  972. else:
  973. self.statGrid.SetCellValue(row=9, col=1, s="")
  974. self.detailsSizer.ShowItems(True)
  975. # Clean the runes
  976. for i in range(0, 5):
  977. self.idLabelList[i].SetLabel("")
  978. self.locationLabelList[i].SetLabel("")
  979. self.setLabelList[i].SetLabel("")
  980. self.mainLabelList[i].SetLabel("")
  981. self.innateLabelList[i].SetLabel("")
  982. for j in range(0, 3):
  983. self.statLabelList[i][j].SetLabel("")
  984. # Display the runes
  985. cursor = conn.execute(
  986. """
  987. SELECT
  988. runes.id,
  989. runes.slot,
  990. runes.type,
  991. runes.level,
  992. units.id,
  993. units.name
  994. FROM runes LEFT JOIN units ON runes.unit = units.id
  995. WHERE runes.id IN (?, ?, ?, ?, ?, ?)
  996. ORDER BY runes.slot;
  997. """,
  998. (
  999. self.data.results[self.selectedResultIndex].runes[0],
  1000. self.data.results[self.selectedResultIndex].runes[1],
  1001. self.data.results[self.selectedResultIndex].runes[2],
  1002. self.data.results[self.selectedResultIndex].runes[3],
  1003. self.data.results[self.selectedResultIndex].runes[4],
  1004. self.data.results[self.selectedResultIndex].runes[5]
  1005. )
  1006. )
  1007. i = 0
  1008. for row in cursor:
  1009. # Rows are 21 charactes width
  1010. self.idLabelList[i].SetLabel(("#" + str(row[0])).rjust(21, " "))
  1011. if row[4] == None:
  1012. self.locationLabelList[i].SetLabel("Storage")
  1013. else:
  1014. self.locationLabelList[i].SetLabel(
  1015. str(row[5])[0:9].ljust(9, " ") + " #" + str(row[4]) + ""
  1016. )
  1017. self.setLabelList[i].SetLabel(
  1018. set_names[row[2]].ljust(18, " ") + "+" + str(row[3])
  1019. )
  1020. cursorStats = conn.execute(
  1021. """
  1022. SELECT
  1023. slot, stat, value, grind, enchant
  1024. FROM rune_stats
  1025. WHERE
  1026. rune = ?
  1027. ORDER BY slot;
  1028. """,
  1029. (self.data.results[self.selectedResultIndex].runes[i],)
  1030. )
  1031. for rowStats in cursorStats:
  1032. slot = rowStats[0]
  1033. if rowStats[4] == 1: # if enchanted
  1034. name = (
  1035. stat_names[rowStats[1]]
  1036. .replace("%", "")
  1037. .replace(" ", "") + " * "
  1038. ).rjust(8, " ")
  1039. else:
  1040. name = (
  1041. stat_names[rowStats[1]]
  1042. .replace("%", "")
  1043. .replace(" ", "") + " "
  1044. ).rjust(8, " ")
  1045. value = str(rowStats[2])
  1046. if rowStats[1] in [2, 4, 6, 9, 10, 11, 23]:
  1047. value = value + "%"
  1048. else:
  1049. value = value + " "
  1050. value = value.rjust(5)
  1051. if rowStats[3] > 0: # if grinded
  1052. value = value + " + " + str(rowStats[3])
  1053. if rowStats[1] in [2, 4, 6, 9, 10, 11, 23]:
  1054. value = value + "%"
  1055. line = name + value
  1056. if slot == -1: # main
  1057. self.mainLabelList[i].SetLabel(line)
  1058. elif slot == 0: # innate
  1059. self.innateLabelList[i].SetLabel(line)
  1060. else: # normal stats
  1061. self.statLabelList[i][slot - 1].SetLabel(line)
  1062. i += 1
  1063. # Make the info visible
  1064. self.detailsSizer.ShowItems(True)
  1065. def recalculteStatsOfModifiedUnits(self):
  1066. """Recalculates the stats of all the units marked as modified.
  1067. """
  1068. global conn
  1069. unitCursor = conn.execute("""
  1070. SELECT
  1071. base_hp,
  1072. base_atk,
  1073. base_def,
  1074. base_spd,
  1075. base_crr,
  1076. base_crd,
  1077. base_res,
  1078. base_acc,
  1079. id
  1080. FROM units
  1081. WHERE modified = 1
  1082. """)
  1083. i = 0
  1084. for unitRow in unitCursor:
  1085. runeCursor = conn.execute(
  1086. """
  1087. SELECT
  1088. sum(current_hp_percent) AS hp,
  1089. sum(current_hp_flat) AS hp_flat,
  1090. sum(current_atk_percent) AS atk,
  1091. sum(current_atk_flat) AS atk_flat,
  1092. sum(current_def_percent) AS def,
  1093. sum(current_def_flat) AS def_flat,
  1094. sum(current_spd) AS spd,
  1095. sum(current_crr) AS crr,
  1096. sum(current_crd) AS crd,
  1097. sum(current_res) AS res,
  1098. sum(current_acc) AS acc
  1099. FROM runes
  1100. WHERE unit = ?
  1101. """,
  1102. (unitRow[8],)
  1103. )
  1104. runeRow = runeCursor.fetchone()
  1105. hp = unitRow[0] + runeRow[1] + math.ceil(unitRow[0] + runeRow[0])
  1106. atk = unitRow[1] + runeRow[3] + math.ceil(unitRow[1] + runeRow[2])
  1107. dfc = unitRow[2] + runeRow[5] + math.ceil(unitRow[2] + runeRow[4])
  1108. spd = unitRow[3] + runeRow[6]
  1109. crr = unitRow[4] + runeRow[7]
  1110. crd = unitRow[5] + runeRow[8]
  1111. res = unitRow[6] + runeRow[9]
  1112. acc = unitRow[7] + runeRow[10]
  1113. conn.execute(
  1114. """
  1115. UPDATE units SET
  1116. current_hp = ?,
  1117. current_atk = ?,
  1118. current_def = ?,
  1119. current_spd = ?,
  1120. current_crr = ?,
  1121. current_crd = ?,
  1122. current_res = ?,
  1123. current_acc = ?
  1124. WHERE id = ?
  1125. """,
  1126. (hp, atk, dfc, spd, crr, crd, res, acc, unitRow[8],)
  1127. )
  1128. conn.commit()