PanelResults.py 43 KB

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