PanelResults.py 42 KB

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