optimizer_unit.php 94 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873
  1. <?php
  2. /**
  3. * Monster view.
  4. *
  5. * Contains the view layout and some code to present the data.
  6. *
  7. * @category View
  8. * @var Monster_Page $page The page model.
  9. * @var int $UID Player ID.
  10. */
  11. ?>
  12. <!DOCTYPE html>
  13. <html lang='en'>
  14. <head>
  15. <meta content='text/html; charset=utf-8' http-equiv='content-type'/>
  16. <meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1'/>
  17. <title><?=$page->title?></title>
  18. <link rel='shortcut icon' href='<?=$page->favicon?>'/>
  19. <!-- CSS files -->
  20. <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui.css'/>
  21. <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>optimizer.css'/>
  22. <!-- Meta tags -->
  23. <link rel='canonical' href='<?=$page->canonical?>'/>
  24. <link rel='author' href='<?=$page->author?>'/>
  25. <link rel='publisher' href='<?=$page->author?>'/>
  26. <meta name='description' content='<?=$page->description?>'/>
  27. <meta property='og:title' content='<?=$page->title?>'/>
  28. <meta property='og:url' content='<?=$page->canonical?>'/>
  29. <meta property='og:description' content='<?=$page->description?>'/>
  30. <meta property='og:image' content='<?=$page->icon?>'/>
  31. <meta property='og:site_name' content='<?=$page->name?>'/>
  32. <meta property='og:type' content='website'/>
  33. <meta property='og:locale' content='en'/>
  34. <meta name='twitter:card' content='summary'/>
  35. <meta name='twitter:title' content='<?=$page->title?>'/>
  36. <meta name='twitter:description' content='<?=$page->description?>'/>
  37. <meta name='twitter:image' content='<?=$page->icon?>'/>
  38. <meta name='twitter:url' content='<?=$page->canonical?>'/>
  39. <meta name='robots' content='index follow'/>
  40. <script>
  41. /**
  42. * Unit current stats.
  43. */
  44. var current_stats = {
  45. "attack": <?=$page->unit->total_attack?>,
  46. "defense": <?=$page->unit->total_defense?>,
  47. "hp": <?=$page->unit->total_hp?>,
  48. "speed": <?=$page->unit->total_speed?>,
  49. "crit_rate": <?=$page->unit->total_crit_rate?>,
  50. "crit_damage": <?=$page->unit->total_crit_damage?>,
  51. "accuracy": <?=$page->unit->total_accuracy?>,
  52. "resistance": <?=$page->unit->total_resistance?>,
  53. "ehp": <?=$page->unit->effective_hp?>,
  54. "dmg": <?=$page->unit->effective_dmg?>
  55. }
  56. var set_stats = {
  57. "attack": 0,
  58. "defense": 0,
  59. "hp": 0,
  60. "speed": 0,
  61. "crit_rate": 0,
  62. "crit_damage": 0,
  63. "accuracy": 0,
  64. "resistance": 0
  65. }
  66. var base_stats = {
  67. "attack": <?=$page->unit->attack?>,
  68. "defense": <?=$page->unit->defense?>,
  69. "hp": <?=$page->unit->hp?>,
  70. "speed": <?=$page->unit->speed?>,
  71. "crit_rate": <?=$page->unit->crit_rate?>,
  72. "crit_damage": <?=$page->unit->crit_damage?>,
  73. "accuracy": <?=$page->unit->accuracy?>,
  74. "resistance": <?=$page->unit->resistance?>,
  75. "ehp": <?=$page->unit->effective_hp?>,
  76. "dmg": <?=$page->unit->effective_dmg?>
  77. }
  78. var requested_sets = {
  79. 'RUNE_SET_<?=RUNE_SET_ID::ENERGY?>': 0, // ENERGY
  80. 'RUNE_SET_<?=RUNE_SET_ID::GUARD?>': 0, // GUARD
  81. 'RUNE_SET_<?=RUNE_SET_ID::SWIFT?>': 0, // SWIFT
  82. 'RUNE_SET_<?=RUNE_SET_ID::BLADE?>': 0, // BLADE
  83. 'RUNE_SET_<?=RUNE_SET_ID::RAGE?>': 0, // RAGE
  84. 'RUNE_SET_<?=RUNE_SET_ID::FOCUS?>': 0, // FOCUS
  85. 'RUNE_SET_<?=RUNE_SET_ID::ENDURE?>': 0, // ENDURE
  86. 'RUNE_SET_<?=RUNE_SET_ID::FATAL?>': 0, // FATAL
  87. 'RUNE_SET_<?=RUNE_SET_ID::DESPAIR?>': 0, // DESPAIR
  88. 'RUNE_SET_<?=RUNE_SET_ID::VAMPIRE?>': 0, // VAMPIRE
  89. 'RUNE_SET_<?=RUNE_SET_ID::VIOLENT?>': 0, // VIOLENT
  90. 'RUNE_SET_<?=RUNE_SET_ID::NEMESIS?>': 0, // NEMESIS
  91. 'RUNE_SET_<?=RUNE_SET_ID::WILL?>': 0, // WILL
  92. 'RUNE_SET_<?=RUNE_SET_ID::SHIELD?>': 0, // SHIELD
  93. 'RUNE_SET_<?=RUNE_SET_ID::REVENGE?>': 0, // REVENGE
  94. 'RUNE_SET_<?=RUNE_SET_ID::DESTROY?>': 0, // DESTROY
  95. 'RUNE_SET_<?=RUNE_SET_ID::FIGHT?>': 0, // FIGHT
  96. 'RUNE_SET_<?=RUNE_SET_ID::DETERMINATION?>': 0, // DETERMINATION
  97. 'RUNE_SET_<?=RUNE_SET_ID::ENHANCE?>': 0, // ENHANCE
  98. 'RUNE_SET_<?=RUNE_SET_ID::ACCURACY?>': 0, // ACCURACY
  99. 'RUNE_SET_<?=RUNE_SET_ID::TOLERANCE?>': 0 // TOLERANCE
  100. };
  101. <?php
  102. // Get current rune sets
  103. $sets = [];
  104. foreach ($page->unit->rune as $rune){
  105. if (!in_array($rune->type->id, $sets)){
  106. array_push($sets, $rune->type->id);
  107. }
  108. }
  109. for ($i = sizeof($sets); $i < 3; $i ++){
  110. array_push($sets, 0);
  111. }
  112. ?>
  113. var current_sets = [<?=$sets[0]?>, <?=$sets[1]?>, <?=$sets[2]?>];
  114. // Get current main stats in even slots
  115. <?php
  116. $mains = [0, 0, 0];
  117. foreach ($page->unit->rune as $rune){
  118. if ($rune->slot % 2 == 0){
  119. $mains[($rune->slot / 2) - 1] = $rune->main_stat;
  120. }
  121. }
  122. ?>
  123. /**
  124. * To calculate time.
  125. */
  126. var timestamp = 0;
  127. /**
  128. * Enables or disables a new search.
  129. *
  130. * When disabled, the apply button will be disabled and a waiting
  131. * icon will be shown.
  132. *
  133. * @param enable true to enable, false to disable.
  134. */
  135. function enableNewSearch(enable){
  136. if (enable === true){
  137. document.getElementById('apply').removeAttribute('disabled');
  138. document.getElementById('wait').style.display = 'none';
  139. }
  140. else{
  141. document.getElementById('apply').setAttribute('disabled', 'disabled');
  142. document.getElementById('wait').style.display = 'block';
  143. }
  144. }
  145. /**
  146. * Updates the value next to the sliders when they change.
  147. *
  148. * @param stat Name of the stat to set.
  149. * @param value Value of the slider.
  150. */
  151. function updateMinValue(stat, element){
  152. var value = Number(element.value);
  153. var max = Number(element.max);
  154. var min = Number(element.min);
  155. if (value < min){
  156. value = min;
  157. }
  158. if (value > max){
  159. value = max;
  160. }
  161. document.getElementById('lbl_min_' + stat).value = value;
  162. document.getElementById('min_' + stat).value = value;
  163. }
  164. /**
  165. * Resets filter to the unit's current stat status.
  166. *
  167. * @param stat Name of the stat to set.
  168. */
  169. function resetFilter(stat){
  170. document.getElementById('lbl_min_' + stat).value = current_stats[stat];
  171. document.getElementById('min_' + stat).value = current_stats[stat];
  172. }
  173. /**
  174. * Sets a filter to it's lowest possible value.
  175. *
  176. * @param stat Name of the stat to set.
  177. */
  178. function removeFilter(stat){
  179. document.getElementById('lbl_min_' + stat).value = document.getElementById('lbl_min_' + stat).min;
  180. document.getElementById('min_' + stat).value = document.getElementById('min_' + stat).min;
  181. }
  182. function log(text){
  183. var log_window = document.getElementById('log_window');
  184. var span = document.createElement('span');
  185. span.setAttribute('class', 'log_message');
  186. text = document.createTextNode(text);
  187. span.appendChild(text);
  188. log_window.appendChild(span);
  189. log_window.scrollTo(0, 2 * log_window.offsetHeight);
  190. }
  191. function clearLog(){
  192. const elements = document.querySelectorAll('.log_message');
  193. Array.from(elements).forEach((element, index) => {
  194. element.remove();
  195. });
  196. }
  197. /**
  198. * Starts the optimization.
  199. *
  200. * Checks for error in the combination of the parameters, and
  201. * shows an error window if there is an invalid conbination. If
  202. * not, builds the url to fetch all candidate runes.
  203. *
  204. * @return false on error, true on success.
  205. */
  206. function apply(){
  207. log("Start optimization...");
  208. var params = '';
  209. var x;
  210. // Player id - mandatory
  211. params = 'uid=<?=$UID?>';
  212. // Unit id - mandatory
  213. params += '&unit=<?=$page->unit->id?>';
  214. // Rune set 1 - mandatory
  215. params += '&set[]=' + document.getElementById('set_1').options[document.getElementById('set_1').selectedIndex].value;
  216. // Rune set 2 - mandatory
  217. params += '&set[]=' + document.getElementById('set_2').options[document.getElementById('set_2').selectedIndex].value;
  218. // Rune set 3 - optional
  219. x = document.getElementById('set_3').options[document.getElementById('set_3').selectedIndex].value;
  220. if (x != ''){
  221. params += '&set[]=' + x;
  222. }
  223. // Slot 2 - mandatory
  224. params += '&stat[]=' + document.getElementById('slot_2').options[document.getElementById('slot_2').selectedIndex].value;
  225. // Slot 4 - mandatory
  226. params += '&stat[]=' + document.getElementById('slot_4').options[document.getElementById('slot_4').selectedIndex].value;
  227. // Slot 5 - mandatory
  228. params += '&stat[]=' + document.getElementById('slot_6').options[document.getElementById('slot_6').selectedIndex].value;
  229. // Rune source - mandatory
  230. params += '&source=' + document.getElementById('rune_source').options[document.getElementById('rune_source').selectedIndex].value;
  231. // Optimizer tuning - mandatory
  232. params += '&tuning=' + document.getElementById('tuning').options[document.getElementById('tuning').selectedIndex].value;
  233. // Limit combinations - mandatory
  234. params += '&limit=' + document.getElementById('limit').value;
  235. // Min HP - Optional
  236. if (Number(document.getElementById('min_hp').value) > Number(document.getElementById('min_hp').min)){
  237. params += '&min_hp=' + document.getElementById('min_hp').value;
  238. }
  239. // Min ATK - Optional
  240. if (Number(document.getElementById('min_attack').value) > Number(document.getElementById('min_attack').min)){
  241. params += '&min_attack=' + document.getElementById('min_attack').value;
  242. }
  243. // Min DEF - Optional
  244. if (Number(document.getElementById('min_defense').value) > Number(document.getElementById('min_defense').min)){
  245. params += '&min_defense=' + document.getElementById('min_defense').value;
  246. }
  247. // Min SPD - Optional
  248. if (Number(document.getElementById('min_speed').value) > Number(document.getElementById('min_speed').min)){
  249. params += '&min_speed=' + document.getElementById('min_speed').value;
  250. }
  251. // Min CRR - Optional
  252. if (Number(document.getElementById('min_crit_rate').value) > Number(document.getElementById('min_crit_rate').min)){
  253. params += '&min_crit_rate=' + document.getElementById('min_crit_rate').value;
  254. }
  255. // Min CRD - Optional
  256. if (Number(document.getElementById('min_crit_damage').value) > Number(document.getElementById('min_crit_damage').min)){
  257. params += '&min_crit_damage=' + document.getElementById('min_crit_damage').value;
  258. }
  259. // Min ACC - Optional
  260. if (Number(document.getElementById('min_accuracy').value) > Number(document.getElementById('min_accuracy').min)){
  261. params += '&min_accuracy=' + document.getElementById('min_accuracy').value;
  262. }
  263. // Min RES - Optional
  264. if (Number(document.getElementById('min_resistance').value) > Number(document.getElementById('min_resistance').min)){
  265. params += '&min_resistance=' + document.getElementById('min_resistance').value;
  266. }
  267. // Min EHP - Optional
  268. if (Number(document.getElementById('min_ehp').value) > 0){
  269. params += '&min_ehp=' + document.getElementById('min_ehp').value;
  270. }
  271. // Min DMG - Optional
  272. if (Number(document.getElementById('min_dmg').value) > 0){
  273. params += '&min_dmg=' + document.getElementById('min_dmg').value;
  274. }
  275. // Clear and calculate new requested sets
  276. requested_sets['RUNE_SET_<?=RUNE_SET_ID::ENERGY?>'] = 0; // ENERGY
  277. requested_sets['RUNE_SET_<?=RUNE_SET_ID::GUARD?>'] = 0; // GUARD
  278. requested_sets['RUNE_SET_<?=RUNE_SET_ID::SWIFT?>'] = 0; // SWIFT
  279. requested_sets['RUNE_SET_<?=RUNE_SET_ID::BLADE?>'] = 0; // BLADE
  280. requested_sets['RUNE_SET_<?=RUNE_SET_ID::RAGE?>'] = 0; // RAGE
  281. requested_sets['RUNE_SET_<?=RUNE_SET_ID::FOCUS?>'] = 0; // FOCUS
  282. requested_sets['RUNE_SET_<?=RUNE_SET_ID::ENDURE?>'] = 0; // ENDURE
  283. requested_sets['RUNE_SET_<?=RUNE_SET_ID::FATAL?>'] = 0; // FATAL
  284. requested_sets['RUNE_SET_<?=RUNE_SET_ID::DESPAIR?>'] = 0; // DESPAIR
  285. requested_sets['RUNE_SET_<?=RUNE_SET_ID::VAMPIRE?>'] = 0; // VAMPIRE
  286. requested_sets['RUNE_SET_<?=RUNE_SET_ID::VIOLENT?>'] = 0; // VIOLENT
  287. requested_sets['RUNE_SET_<?=RUNE_SET_ID::NEMESIS?>'] = 0; // NEMESIS
  288. requested_sets['RUNE_SET_<?=RUNE_SET_ID::WILL?>'] = 0; // WILL
  289. requested_sets['RUNE_SET_<?=RUNE_SET_ID::SHIELD?>'] = 0; // SHIELD
  290. requested_sets['RUNE_SET_<?=RUNE_SET_ID::REVENGE?>'] = 0; // REVENGE
  291. requested_sets['RUNE_SET_<?=RUNE_SET_ID::DESTROY?>'] = 0; // DESTROY
  292. requested_sets['RUNE_SET_<?=RUNE_SET_ID::FIGHT?>'] = 0; // FIGHT
  293. requested_sets['RUNE_SET_<?=RUNE_SET_ID::DETERMINATION?>'] = 0; // DETERMINATION
  294. requested_sets['RUNE_SET_<?=RUNE_SET_ID::ENHANCE?>'] = 0; // ENHANCE
  295. requested_sets['RUNE_SET_<?=RUNE_SET_ID::ACCURACY?>'] = 0; // ACCURACY
  296. requested_sets['RUNE_SET_<?=RUNE_SET_ID::TOLERANCE?>'] = 0; // TOLERANCE
  297. var selected_1 = document.getElementById('set_1').options[document.getElementById('set_1').selectedIndex].value;
  298. var selected_2 = document.getElementById('set_2').options[document.getElementById('set_2').selectedIndex].value;
  299. var selected_3 = document.getElementById('set_3').options[document.getElementById('set_3').selectedIndex].value;
  300. var requested_values = [
  301. document.getElementById('set_1').options[document.getElementById('set_1').selectedIndex].value,
  302. document.getElementById('set_2').options[document.getElementById('set_2').selectedIndex].value,
  303. document.getElementById('set_3').options[document.getElementById('set_3').selectedIndex].value
  304. ];
  305. for (var i = 0; i < 3; i ++){
  306. switch (requested_values[i]){
  307. case '<?=RUNE_SET_ID::ENERGY?>':
  308. case '<?=RUNE_SET_ID::GUARD?>':
  309. case '<?=RUNE_SET_ID::NEMESIS?>':
  310. case '<?=RUNE_SET_ID::BLADE?>':
  311. case '<?=RUNE_SET_ID::FOCUS?>':
  312. case '<?=RUNE_SET_ID::ENDURE?>':
  313. case '<?=RUNE_SET_ID::WILL?>':
  314. case '<?=RUNE_SET_ID::SHIELD?>':
  315. case '<?=RUNE_SET_ID::REVENGE?>':
  316. case '<?=RUNE_SET_ID::DESTROY?>':
  317. case '<?=RUNE_SET_ID::FIGHT?>':
  318. case '<?=RUNE_SET_ID::DETERMINATION?>':
  319. case '<?=RUNE_SET_ID::ENHANCE?>':
  320. case '<?=RUNE_SET_ID::ACCURACY?>':
  321. case '<?=RUNE_SET_ID::TOLERANCE?>':
  322. requested_sets['RUNE_SET_' + requested_values[i]] += 2;
  323. break;
  324. case '<?=RUNE_SET_ID::DESPAIR?>':
  325. case '<?=RUNE_SET_ID::SWIFT?>':
  326. case '<?=RUNE_SET_ID::RAGE?>':
  327. case '<?=RUNE_SET_ID::FATAL?>':
  328. case '<?=RUNE_SET_ID::VAMPIRE?>':
  329. case '<?=RUNE_SET_ID::VIOLENT?>':
  330. requested_sets['RUNE_SET_' + requested_values[i]] += 4;
  331. break;
  332. }
  333. }
  334. // Clear and calculate the new rune set stats
  335. set_stats['hp'] = 0;
  336. set_stats['attack'] = 0;
  337. set_stats['defense'] = 0;
  338. set_stats['speed'] = 0;
  339. set_stats['crit_rate'] = 0;
  340. set_stats['crit_damage'] = 0;
  341. set_stats['accuracy'] = 0;
  342. set_stats['resistance'] = 0;
  343. var rune_sets = [
  344. Number(document.getElementById('set_1').options[document.getElementById('set_1').selectedIndex].value),
  345. Number(document.getElementById('set_2').options[document.getElementById('set_2').selectedIndex].value),
  346. Number(document.getElementById('set_3').options[document.getElementById('set_3').selectedIndex].value)
  347. ];
  348. for (var i = 0; i < rune_sets.length; i ++){
  349. switch (rune_sets[i]){
  350. case <?=RUNE_SET_ID::ENERGY?>:
  351. set_stats['hp'] += (base_stats['hp'] * 0.15);
  352. break;
  353. case <?=RUNE_SET_ID::GUARD?>:
  354. set_stats['defense'] += (base_stats['defense'] * 0.15);
  355. break;
  356. case <?=RUNE_SET_ID::BLADE?>:
  357. set_stats['crit_rate'] += 12;
  358. break;
  359. case <?=RUNE_SET_ID::FOCUS?>:
  360. set_stats['accuracy'] += 20;
  361. break;
  362. case <?=RUNE_SET_ID::ENDURE?>:
  363. set_stats['resistance'] += 20;
  364. break;
  365. case <?=RUNE_SET_ID::FIGHT?>:
  366. set_stats['attack'] += (base_stats['attack'] * 0.08);
  367. break;
  368. case <?=RUNE_SET_ID::DETERMINATION?>:
  369. set_stats['defense'] += (base_stats['defense'] * 0.2);
  370. break;
  371. case <?=RUNE_SET_ID::ENHANCE?>:
  372. set_stats['hp'] += (base_stats['hp'] * 0.2);
  373. break;
  374. case <?=RUNE_SET_ID::ACCURACY?>:
  375. set_stats['accuracy'] += 10;
  376. break;
  377. case <?=RUNE_SET_ID::TOLERANCE?>:
  378. set_stats['resistance'] += 10;
  379. break;
  380. case <?=RUNE_SET_ID::SWIFT?>:
  381. set_stats['speed'] += (base_stats['speed'] * 0.24);
  382. break;
  383. case <?=RUNE_SET_ID::RAGE?>:
  384. set_stats['crit_damage'] += 40;
  385. break;
  386. case <?=RUNE_SET_ID::FATAL?>:
  387. set_stats['attack'] += (base_stats['attack'] * 0.35);
  388. break;
  389. }
  390. }
  391. // Send the request
  392. var xhttp = new XMLHttpRequest();
  393. xhttp.onreadystatechange = function() {
  394. if (this.readyState == 4){
  395. if (this.status == 200) {
  396. time = ((+ new Date()) - timestamp) / 1000;
  397. calculateOptimizations(this.response, time);
  398. }
  399. else{
  400. enableNewSearch(true);
  401. var time = ((+ new Date()) - timestamp) / 1000;
  402. log('Error ' + this.status + '(' + time + 's)');
  403. showMessage('Error', 'Unexpected error ' + this.status);
  404. }
  405. }
  406. };
  407. // DEBUG
  408. //params = 'uid=8114048&unit=6441802832&limit=6&set[]=2&set[]=4&set[]=4&stat[]=4&stat[]=4&stat[]=4&source=0&tuning=2&min_defense=800';
  409. // Clear result table, disable button and show spinner
  410. var container = document.getElementById('optimizations');
  411. while (container.firstChild) {
  412. container.removeChild(container.firstChild);
  413. }
  414. enableNewSearch(false);
  415. document.getElementById('results').style.display = 'none';
  416. // Start timer
  417. timestamp = + new Date();
  418. // Make the request
  419. xhttp.open('POST', '/action/optimize_get_rune_list/', true);
  420. xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
  421. xhttp.send(params);
  422. }
  423. /**
  424. * Checks if a rune combination is a valid set. To do so, checks:
  425. *
  426. * - That the sets are valid
  427. * - That the sets are the same as requested
  428. * - That it complies with the filters min values.
  429. *
  430. * @param candidates Array of 6 runes
  431. * @return true if the set matches the criteria, false otherwise.
  432. */
  433. function valid_set(candidates){
  434. // Number of applied sets with the current candidates.
  435. var sets = {
  436. 'RUNE_SET_<?=RUNE_SET_ID::ENERGY?>': 0, // ENERGY
  437. 'RUNE_SET_<?=RUNE_SET_ID::GUARD?>': 0, // GUARD
  438. 'RUNE_SET_<?=RUNE_SET_ID::SWIFT?>': 0, // SWIFT
  439. 'RUNE_SET_<?=RUNE_SET_ID::BLADE?>': 0, // BLADE
  440. 'RUNE_SET_<?=RUNE_SET_ID::RAGE?>': 0, // RAGE
  441. 'RUNE_SET_<?=RUNE_SET_ID::FOCUS?>': 0, // FOCUS
  442. 'RUNE_SET_<?=RUNE_SET_ID::ENDURE?>': 0, // ENDURE
  443. 'RUNE_SET_<?=RUNE_SET_ID::FATAL?>': 0, // FATAL
  444. 'RUNE_SET_<?=RUNE_SET_ID::DESPAIR?>': 0, // DESPAIR
  445. 'RUNE_SET_<?=RUNE_SET_ID::VAMPIRE?>': 0, // VAMPIRE
  446. 'RUNE_SET_<?=RUNE_SET_ID::VIOLENT?>': 0, // VIOLENT
  447. 'RUNE_SET_<?=RUNE_SET_ID::NEMESIS?>': 0, // NEMESIS
  448. 'RUNE_SET_<?=RUNE_SET_ID::WILL?>': 0, // WILL
  449. 'RUNE_SET_<?=RUNE_SET_ID::SHIELD?>': 0, // SHIELD
  450. 'RUNE_SET_<?=RUNE_SET_ID::REVENGE?>': 0, // REVENGE
  451. 'RUNE_SET_<?=RUNE_SET_ID::DESTROY?>': 0, // DESTROY
  452. 'RUNE_SET_<?=RUNE_SET_ID::FIGHT?>': 0, // FIGHT
  453. 'RUNE_SET_<?=RUNE_SET_ID::DETERMINATION?>': 0, // DETERMINATION
  454. 'RUNE_SET_<?=RUNE_SET_ID::ENHANCE?>': 0, // ENHANCE
  455. 'RUNE_SET_<?=RUNE_SET_ID::ACCURACY?>': 0, // ACCURACY
  456. 'RUNE_SET_<?=RUNE_SET_ID::TOLERANCE?>': 0 // TOLERANCE
  457. };
  458. for (var i = 0; i <= 5; i ++){
  459. sets['RUNE_SET_' + candidates[i].TYPE] ++;
  460. }
  461. // TEST I think i dont need to check for valid sets, only that
  462. // they match the requested sets.
  463. /*for (var i = 0; i < sets.length; i ++){
  464. switch (i){
  465. case <?=RUNE_SET_ID::ENERGY?>:
  466. case <?=RUNE_SET_ID::GUARD?>:
  467. case <?=RUNE_SET_ID::NEMESIS?>:
  468. case <?=RUNE_SET_ID::BLADE?>:
  469. case <?=RUNE_SET_ID::FOCUS?>:
  470. case <?=RUNE_SET_ID::ENDURE?>:
  471. case <?=RUNE_SET_ID::WILL?>:
  472. case <?=RUNE_SET_ID::SHIELD?>:
  473. case <?=RUNE_SET_ID::REVENGE?>:
  474. case <?=RUNE_SET_ID::DESTROY?>:
  475. case <?=RUNE_SET_ID::FIGHT?>:
  476. case <?=RUNE_SET_ID::DETERMINATION?>:
  477. case <?=RUNE_SET_ID::ENHANCE?>:
  478. case <?=RUNE_SET_ID::ACCURACY?>:
  479. case <?=RUNE_SET_ID::TOLERANCE?>:
  480. if (sets[i] % 2 != 0){
  481. return false;
  482. }
  483. break;
  484. case <?=RUNE_SET_ID::DESPAIR?>:
  485. case <?=RUNE_SET_ID::SWIFT?>:
  486. case <?=RUNE_SET_ID::RAGE?>:
  487. case <?=RUNE_SET_ID::FATAL?>:
  488. case <?=RUNE_SET_ID::VAMPIRE?>:
  489. case <?=RUNE_SET_ID::VIOLENT?>:
  490. if (sets[i] != 4 && sets[i] != 0){
  491. return false;
  492. }
  493. break;
  494. }
  495. }*/
  496. // Its a valid set, but does it match the requested sets?
  497. if (JSON.stringify(sets) !== JSON.stringify(requested_sets)){
  498. return false;
  499. }
  500. // Compare with filters
  501. var new_stats = {
  502. "ATK": base_stats["attack"] + set_stats["attack"],
  503. "DEF": base_stats["defense"] + set_stats["defense"],
  504. "HP": base_stats["hp"] + set_stats["hp"],
  505. "SPD": base_stats["speed"] + set_stats["speed"],
  506. "CRR": base_stats["crit_rate"] + set_stats["crit_rate"],
  507. "CRD": base_stats["crit_damage"] + set_stats["crit_damage"],
  508. "ACC": base_stats["accuracy"] + set_stats["accuracy"],
  509. "RES": base_stats["resistance"] + set_stats["resistance"],
  510. "EHP": 0,
  511. "DMG": 0
  512. }
  513. for (var i = 0; i <= 5; i ++){
  514. new_stats["ATK"] += candidates[i].ATK;
  515. new_stats["DEF"] += candidates[i].DEF;
  516. new_stats["HP"] += candidates[i].HP;
  517. new_stats["SPD"] += candidates[i].SPD;
  518. new_stats["CRR"] += candidates[i].CRR;
  519. new_stats["CRD"] += candidates[i].CRD;
  520. new_stats["ACC"] += candidates[i].ACC;
  521. new_stats["RES"] += candidates[i].RES;
  522. }
  523. new_stats["EHP"] = Math.ceil((((new_stats["DEF"] * 3.5) + 1140) * new_stats["HP"]) / 1000);
  524. new_stats["DMG"] = Math.ceil((new_stats["ATK"] * (100 - new_stats["CRR"]) / 100) + ((new_stats["ATK"] + (new_stats["ATK"] * new_stats["CRD"] / 100)) * new_stats["CRR"] / 100));
  525. if (
  526. new_stats["ATK"] >= document.getElementById('min_attack').value &&
  527. new_stats["DEF"] >= document.getElementById('min_defense').value &&
  528. new_stats["HP"] >= document.getElementById('min_hp').value &&
  529. new_stats["SPD"] >= document.getElementById('min_speed').value &&
  530. new_stats["CRR"] >= document.getElementById('min_crit_rate').value &&
  531. new_stats["CRD"] >= document.getElementById('min_crit_damage').value &&
  532. new_stats["ACC"] >= document.getElementById('min_accuracy').value &&
  533. new_stats["RES"] >= document.getElementById('min_resistance').value &&
  534. new_stats["EHP"] >= document.getElementById('min_ehp').value &&
  535. new_stats["DMG"] >= document.getElementById('min_dmg').value
  536. ){
  537. return true;
  538. }
  539. return false;
  540. }
  541. /**
  542. * Parses the received runes and looks for valid candidates.
  543. * Once it's done, it calls the server agai to get rune info.
  544. *
  545. * @param content JSON received from server.
  546. */
  547. async function calculateOptimizations(content, time){
  548. var container = document.getElementById('optimizations');
  549. var data = JSON.parse(content);
  550. // Create a 0-index array grouped by slot
  551. var candidates = [
  552. data[1],
  553. data[2],
  554. data[3],
  555. data[4],
  556. data[5],
  557. data[6]
  558. ];
  559. // Calculate total combinations.
  560. var total_runes = data[1].length + data[2].length + data[3].length + data[4].length + data[5].length + data[6].length;
  561. var total_combinations = data[1].length * data[2].length * data[3].length * data[4].length * data[5].length * data[6].length;
  562. if (total_combinations == 0){
  563. var time = ((+ new Date()) - timestamp) / 1000;
  564. log('No rune combinations found (' + time + 's)');
  565. showMessage('No results', 'No runes found matching your criteria.');
  566. }
  567. var time = ((+ new Date()) - timestamp) / 1000;
  568. log(total_runes + ' runes found (' + total_combinations + ' combinations) (' + time + 's)');
  569. // TODO Prevent user on high numbers
  570. var checked_combinations = 0;
  571. // Valid combinations that match the minimum requeriments
  572. var valid_combinations = [];
  573. // Counters to keep track on array indexes
  574. var counters = [0, 0, 0, 0, 0, 0];
  575. // Loop all posible combinations. When a valid set is found,
  576. // add it to valid_combinations
  577. while (true){
  578. if (valid_set([
  579. candidates[0][counters[0]],
  580. candidates[1][counters[1]],
  581. candidates[2][counters[2]],
  582. candidates[3][counters[3]],
  583. candidates[4][counters[4]],
  584. candidates[5][counters[5]]
  585. ])){
  586. valid_combinations.push({
  587. 'score': 0,
  588. 'runes': [
  589. candidates[0][counters[0]],
  590. candidates[1][counters[1]],
  591. candidates[2][counters[2]],
  592. candidates[3][counters[3]],
  593. candidates[4][counters[4]],
  594. candidates[5][counters[5]]
  595. ]
  596. });
  597. }
  598. // Increase counters
  599. checked_combinations ++;
  600. counters[5] ++;
  601. if (counters[5] >= candidates[5].length){
  602. counters[5] = 0;
  603. counters[4] ++;
  604. }
  605. if (counters[4] >= candidates[4].length){
  606. counters[4] = 0;
  607. counters[3] ++;
  608. }
  609. if (counters[3] >= candidates[3].length){
  610. counters[3] = 0;
  611. counters[2] ++;
  612. }
  613. if (counters[2] >= candidates[2].length){
  614. counters[2] = 0;
  615. counters[1] ++;
  616. }
  617. if (counters[1] >= candidates[1].length){
  618. counters[1] = 0;
  619. counters[0] ++;
  620. }
  621. if (counters[0] >= candidates[0].length){
  622. break;
  623. }
  624. /*if (checked_combinations % 1000 == 0){
  625. console.log("COMBINATIONS CHECKED: " + checked_combinations + " / " + total_combinations + "(" + (checked_combinations * 100 / total_combinations) + "%)");
  626. console.log(" 0: " + counters[0] + "/" + candidates[0].length);
  627. console.log(" 1: " + counters[1] + "/" + candidates[1].length);
  628. console.log(" 2: " + counters[2] + "/" + candidates[2].length);
  629. console.log(" 3: " + counters[3] + "/" + candidates[3].length);
  630. console.log(" 4: " + counters[4] + "/" + candidates[4].length);
  631. console.log(" 5: " + counters[5] + "/" + candidates[5].length);
  632. }*/
  633. }
  634. // If no valid combinations: exit now
  635. if (valid_combinations.length == 0){
  636. enableNewSearch(true);
  637. var time = ((+ new Date()) - timestamp) / 1000;
  638. log('No suitable combination found (' + time + 's).');
  639. showMessage('No results', 'No suitable combination found. Plesase relax your criteria and retry.');
  640. }
  641. // Foreach valid combination, rate it and sort the array
  642. for (var i = 0; i < valid_combinations.length; i ++){
  643. for (var r = 0; r < 6; r ++){
  644. valid_combinations[i]['score'] += valid_combinations[i]["runes"][r]["ATK"];
  645. valid_combinations[i]['score'] += valid_combinations[i]["runes"][r]["DEF"];
  646. valid_combinations[i]['score'] += (valid_combinations[i]["runes"][r]["HP"] / 15);
  647. valid_combinations[i]['score'] += (valid_combinations[i]["runes"][r]["SPD"] * 1.5);
  648. valid_combinations[i]['score'] += (valid_combinations[i]["runes"][r]["CRR"] * 1.2);
  649. valid_combinations[i]['score'] += (valid_combinations[i]["runes"][r]["CRD"] * 1.2);
  650. valid_combinations[i]['score'] += (valid_combinations[i]["runes"][r]["ACC"] * 1.2);
  651. valid_combinations[i]['score'] += (valid_combinations[i]["runes"][r]["ATK"] * 1.2);
  652. }
  653. }
  654. var time = ((+ new Date()) - timestamp) / 1000;
  655. log(valid_combinations.length + ' suitable combinations found (' + time + 's)');
  656. valid_combinations.sort(function(a, b) {return b['score'] - a['score'];});
  657. if (valid_combinations.length > document.getElementById('limit').value){
  658. var time = ((+ new Date()) - timestamp) / 1000;
  659. log('Selecting the ' + document.getElementById('limit').value + ' best combinations (' + time + 's)');
  660. valid_combinations = valid_combinations.slice(0, document.getElementById('limit').value);
  661. }
  662. // Request to fetch the runes.
  663. var xhttp = new XMLHttpRequest();
  664. xhttp.onreadystatechange = function() {
  665. if (this.readyState == 4){
  666. if (this.status == 200) {
  667. //time = ((+ new Date()) - timestamp) / 1000;
  668. presentOptions(this.response, timestamp);
  669. }
  670. else{
  671. enableNewSearch(true);
  672. showMessage('Error', 'Unexpected error ' + this.status);
  673. }
  674. }
  675. };
  676. params = 'uid=<?=$UID?>&unit=<?=$page->unit->id?>&tuning=' + document.getElementById('tuning').options[document.getElementById('tuning').selectedIndex].value;
  677. params += '&options=' + JSON.stringify(valid_combinations);
  678. xhttp.open('POST', '/action/optimize_get_options/', true);
  679. xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
  680. xhttp.send(params);
  681. return;
  682. }
  683. /**
  684. * Displays the options.
  685. *
  686. * Builds a table with the calculated options and their scores.
  687. * If none. It will show a message. In any case, it reenables the search
  688. * button
  689. *
  690. * @param content Response from /action/optimize_get_options/
  691. * @param timestamp Time counter
  692. */
  693. function presentOptions(content, timestamp){
  694. var container = document.getElementById('optimizations');
  695. var data = JSON.parse(content);
  696. if (data.length == 0){
  697. enableNewSearch(true);
  698. return;
  699. }
  700. var option;
  701. var tr;
  702. var td;
  703. var stat_table;
  704. var stat_tr;
  705. var stat_td;
  706. var span;
  707. var text;
  708. for (i = 0; i < data.length; i++){
  709. option = data[i];
  710. // Add the rune set stats
  711. option.stats.attack += set_stats['attack'];
  712. option.stats.defense += set_stats['defense'];
  713. option.stats.hp += set_stats['hp'];
  714. option.stats.speed += set_stats['speed'];
  715. option.stats.crit_rate += set_stats['crit_rate'];
  716. option.stats.crit_damage += set_stats['crit_damage'];
  717. option.stats.accuracy += set_stats['accuracy'];
  718. option.stats.resistance += set_stats['resistance'];
  719. tr = document.createElement('tr');
  720. td = document.createElement('td');
  721. td.setAttribute('class', 'option_stats');
  722. stat_table = document.createElement('table');
  723. stat_table.setAttribute('class', 'stat_table');
  724. // attack
  725. stat_tr = document.createElement('tr');
  726. stat_td = document.createElement('td');
  727. stat_td.setAttribute('class', 'label');
  728. text = document.createTextNode('ATK');
  729. stat_td.appendChild(text);
  730. stat_tr.appendChild(stat_td);
  731. stat_td = document.createElement('td');
  732. stat_td.setAttribute('class', 'value');
  733. span = document.createElement('span');
  734. span.setAttribute('class', 'stat');
  735. text = document.createTextNode(option.stats.attack + " ");
  736. span.appendChild(text);
  737. stat_td.appendChild(span);
  738. span = document.createElement('span');
  739. if (Number(option.stats.attack) > Number(current_stats["attack"])){
  740. span.setAttribute('class', 'variation increment');
  741. text = document.createTextNode(option.stats.attack - current_stats["attack"]);
  742. }
  743. else if (Number(option.stats.attack) < Number(current_stats["attack"])){
  744. span.setAttribute('class', 'variation decrement');
  745. text = document.createTextNode(current_stats["attack"] - option.stats.attack);
  746. }
  747. else{
  748. span.setAttribute('class', 'variation');
  749. text = document.createTextNode(" ");
  750. }
  751. span.appendChild(text);
  752. stat_td.appendChild(span);
  753. stat_tr.appendChild(stat_td);
  754. stat_table.appendChild(stat_tr);
  755. // defense
  756. stat_tr = document.createElement('tr');
  757. stat_td = document.createElement('td');
  758. stat_td.setAttribute('class', 'label');
  759. text = document.createTextNode('DEF');
  760. stat_td.appendChild(text);
  761. stat_tr.appendChild(stat_td);
  762. stat_td = document.createElement('td');
  763. stat_td.setAttribute('class', 'value');
  764. span = document.createElement('span');
  765. span.setAttribute('class', 'stat');
  766. text = document.createTextNode(option.stats.defense + " ");
  767. span.appendChild(text);
  768. stat_td.appendChild(span);
  769. span = document.createElement('span');
  770. if (Number(option.stats.defense) > Number(current_stats["defense"])){
  771. span.setAttribute('class', 'variation increment');
  772. text = document.createTextNode(option.stats.defense - current_stats["defense"]);
  773. }
  774. else if (Number(option.stats.defense) < Number(current_stats["defense"])){
  775. span.setAttribute('class', 'variation decrement');
  776. text = document.createTextNode(current_stats["defense"] - option.stats.defense);
  777. }
  778. else{
  779. span.setAttribute('class', 'variation');
  780. text = document.createTextNode(" ");
  781. }
  782. span.appendChild(text);
  783. stat_td.appendChild(span);
  784. stat_tr.appendChild(stat_td);
  785. stat_table.appendChild(stat_tr);
  786. // hp
  787. stat_tr = document.createElement('tr');
  788. stat_td = document.createElement('td');
  789. stat_td.setAttribute('class', 'label');
  790. text = document.createTextNode('HP ');
  791. stat_td.appendChild(text);
  792. stat_tr.appendChild(stat_td);
  793. stat_td = document.createElement('td');
  794. stat_td.setAttribute('class', 'value');
  795. span = document.createElement('span');
  796. span.setAttribute('class', 'stat');
  797. text = document.createTextNode(option.stats.hp + " ");
  798. span.appendChild(text);
  799. stat_td.appendChild(span);
  800. span = document.createElement('span');
  801. if (Number(option.stats.hp) > Number(current_stats["hp"])){
  802. span.setAttribute('class', 'variation increment');
  803. text = document.createTextNode(option.stats.hp - current_stats["hp"]);
  804. }
  805. else if (Number(option.stats.hp) < Number(current_stats["hp"])){
  806. span.setAttribute('class', 'variation decrement');
  807. text = document.createTextNode(current_stats["hp"] - option.stats.hp);
  808. }
  809. else{
  810. span.setAttribute('class', 'variation');
  811. text = document.createTextNode(" ");
  812. }
  813. span.appendChild(text);
  814. stat_td.appendChild(span);
  815. stat_tr.appendChild(stat_td);
  816. stat_table.appendChild(stat_tr);
  817. // speed
  818. stat_tr = document.createElement('tr');
  819. stat_td = document.createElement('td');
  820. stat_td.setAttribute('class', 'label');
  821. text = document.createTextNode('SPD');
  822. stat_td.appendChild(text);
  823. stat_tr.appendChild(stat_td);
  824. stat_td = document.createElement('td');
  825. stat_td.setAttribute('class', 'value');
  826. span = document.createElement('span');
  827. span.setAttribute('class', 'stat');
  828. text = document.createTextNode(option.stats.speed + " ");
  829. span.appendChild(text);
  830. stat_td.appendChild(span);
  831. span = document.createElement('span');
  832. if (Number(option.stats.speed) > Number(current_stats["speed"])){
  833. span.setAttribute('class', 'variation increment');
  834. text = document.createTextNode(option.stats.speed - current_stats["speed"]);
  835. }
  836. else if (Number(option.stats.speed) < Number(current_stats["speed"])){
  837. span.setAttribute('class', 'variation decrement');
  838. text = document.createTextNode(current_stats["speed"] - option.stats.speed);
  839. }
  840. else{
  841. span.setAttribute('class', 'variation');
  842. text = document.createTextNode(" ");
  843. }
  844. span.appendChild(text);
  845. stat_td.appendChild(span);
  846. stat_tr.appendChild(stat_td);
  847. stat_table.appendChild(stat_tr);
  848. // crit_rate
  849. stat_tr = document.createElement('tr');
  850. stat_td = document.createElement('td');
  851. stat_td.setAttribute('class', 'label');
  852. text = document.createTextNode('CRR');
  853. stat_td.appendChild(text);
  854. stat_tr.appendChild(stat_td);
  855. stat_td = document.createElement('td');
  856. stat_td.setAttribute('class', 'value');
  857. span = document.createElement('span');
  858. span.setAttribute('class', 'stat');
  859. text = document.createTextNode(option.stats.crit_rate + "%");
  860. span.appendChild(text);
  861. stat_td.appendChild(span);
  862. span = document.createElement('span');
  863. if (Number(option.stats.crit_rate) > Number(current_stats["crit_rate"])){
  864. span.setAttribute('class', 'variation increment');
  865. text = document.createTextNode(option.stats.crit_rate - current_stats["crit_rate"]);
  866. }
  867. else if (Number(option.stats.crit_rate) < Number(current_stats["crit_rate"])){
  868. span.setAttribute('class', 'variation decrement');
  869. text = document.createTextNode(current_stats["crit_rate"] - option.stats.crit_rate);
  870. }
  871. else{
  872. span.setAttribute('class', 'variation');
  873. text = document.createTextNode(" ");
  874. }
  875. span.appendChild(text);
  876. stat_td.appendChild(span);
  877. stat_tr.appendChild(stat_td);
  878. stat_table.appendChild(stat_tr);
  879. // crit_damage
  880. stat_tr = document.createElement('tr');
  881. stat_td = document.createElement('td');
  882. stat_td.setAttribute('class', 'label');
  883. text = document.createTextNode('CRD');
  884. stat_td.appendChild(text);
  885. stat_tr.appendChild(stat_td);
  886. stat_td = document.createElement('td');
  887. stat_td.setAttribute('class', 'value');
  888. span = document.createElement('span');
  889. span.setAttribute('class', 'stat');
  890. text = document.createTextNode(option.stats.crit_damage + "%");
  891. span.appendChild(text);
  892. stat_td.appendChild(span);
  893. span = document.createElement('span');
  894. if (Number(option.stats.crit_damage) > Number(current_stats["crit_damage"])){
  895. span.setAttribute('class', 'variation increment');
  896. text = document.createTextNode(option.stats.crit_damage - current_stats["crit_damage"]);
  897. }
  898. else if (Number(option.stats.crit_damage) < Number(current_stats["crit_damage"])){
  899. span.setAttribute('class', 'variation decrement');
  900. text = document.createTextNode(current_stats["crit_damage"] - option.stats.crit_damage);
  901. }
  902. else{
  903. span.setAttribute('class', 'variation');
  904. text = document.createTextNode(" ");
  905. }
  906. span.appendChild(text);
  907. stat_td.appendChild(span);
  908. stat_tr.appendChild(stat_td);
  909. stat_table.appendChild(stat_tr);
  910. // accuracy
  911. stat_tr = document.createElement('tr');
  912. stat_td = document.createElement('td');
  913. stat_td.setAttribute('class', 'label');
  914. text = document.createTextNode('ACC');
  915. stat_td.appendChild(text);
  916. stat_tr.appendChild(stat_td);
  917. stat_td = document.createElement('td');
  918. stat_td.setAttribute('class', 'value');
  919. span = document.createElement('span');
  920. span.setAttribute('class', 'stat');
  921. text = document.createTextNode(option.stats.accuracy + "%");
  922. span.appendChild(text);
  923. stat_td.appendChild(span);
  924. span = document.createElement('span');
  925. if (Number(option.stats.accuracy) > Number(current_stats["accuracy"])){
  926. span.setAttribute('class', 'variation increment');
  927. text = document.createTextNode(option.stats.accuracy - current_stats["accuracy"]);
  928. }
  929. else if (Number(option.stats.accuracy) < Number(current_stats["accuracy"])){
  930. span.setAttribute('class', 'variation decrement');
  931. text = document.createTextNode(current_stats["accuracy"] - option.stats.accuracy);
  932. }
  933. else{
  934. span.setAttribute('class', 'variation');
  935. text = document.createTextNode(" ");
  936. }
  937. span.appendChild(text);
  938. stat_td.appendChild(span);
  939. stat_tr.appendChild(stat_td);
  940. stat_table.appendChild(stat_tr);
  941. // resistance
  942. stat_tr = document.createElement('tr');
  943. stat_td = document.createElement('td');
  944. stat_td.setAttribute('class', 'label');
  945. text = document.createTextNode('RES');
  946. stat_td.appendChild(text);
  947. stat_tr.appendChild(stat_td);
  948. stat_td = document.createElement('td');
  949. stat_td.setAttribute('class', 'value');
  950. span = document.createElement('span');
  951. span.setAttribute('class', 'stat');
  952. text = document.createTextNode(option.stats.resistance + "%");
  953. span.appendChild(text);
  954. stat_td.appendChild(span);
  955. span = document.createElement('span');
  956. if (Number(option.stats.resistance) > Number(current_stats["resistance"])){
  957. span.setAttribute('class', 'variation increment');
  958. text = document.createTextNode(option.stats.resistance - current_stats["resistance"]);
  959. }
  960. else if (Number(option.stats.resistance) < Number(current_stats["resistance"])){
  961. span.setAttribute('class', 'variation decrement');
  962. text = document.createTextNode(current_stats["resistance"] - option.stats.resistance);
  963. }
  964. else{
  965. span.setAttribute('class', 'variation');
  966. text = document.createTextNode(" ");
  967. }
  968. span.appendChild(text);
  969. stat_td.appendChild(span);
  970. stat_tr.appendChild(stat_td);
  971. stat_table.appendChild(stat_tr);
  972. // ehp
  973. stat_tr = document.createElement('tr');
  974. stat_td = document.createElement('td');
  975. stat_td.setAttribute('class', 'label');
  976. text = document.createTextNode('EHP');
  977. stat_td.appendChild(text);
  978. stat_tr.appendChild(stat_td);
  979. stat_td = document.createElement('td');
  980. stat_td.setAttribute('class', 'value');
  981. span = document.createElement('span');
  982. span.setAttribute('class', 'stat');
  983. text = document.createTextNode(option.stats.ehp + " ");
  984. span.appendChild(text);
  985. stat_td.appendChild(span);
  986. span = document.createElement('span');
  987. if (Number(option.stats.ehp) > Number(current_stats["ehp"])){
  988. span.setAttribute('class', 'variation increment');
  989. text = document.createTextNode(option.stats.ehp - current_stats["ehp"]);
  990. }
  991. else if (Number(option.stats.ehp) < Number(current_stats["ehp"])){
  992. span.setAttribute('class', 'variation decrement');
  993. text = document.createTextNode(current_stats["ehp"] - option.stats.ehp);
  994. }
  995. else{
  996. span.setAttribute('class', 'variation');
  997. text = document.createTextNode(" ");
  998. }
  999. span.appendChild(text);
  1000. stat_td.appendChild(span);
  1001. stat_tr.appendChild(stat_td);
  1002. stat_table.appendChild(stat_tr);
  1003. // dmg
  1004. stat_tr = document.createElement('tr');
  1005. stat_td = document.createElement('td');
  1006. stat_td.setAttribute('class', 'label');
  1007. text = document.createTextNode('DMG');
  1008. stat_td.appendChild(text);
  1009. stat_tr.appendChild(stat_td);
  1010. stat_td = document.createElement('td');
  1011. stat_td.setAttribute('class', 'value');
  1012. span = document.createElement('span');
  1013. span.setAttribute('class', 'stat');
  1014. text = document.createTextNode(option.stats.dmg + " ");
  1015. span.appendChild(text);
  1016. stat_td.appendChild(span);
  1017. span = document.createElement('span');
  1018. if (Number(option.stats.dmg) > Number(current_stats["dmg"])){
  1019. span.setAttribute('class', 'variation increment');
  1020. text = document.createTextNode(option.stats.dmg - current_stats["dmg"]);
  1021. }
  1022. else if (Number(option.stats.dmg) < Number(current_stats["dmg"])){
  1023. span.setAttribute('class', 'variation decrement');
  1024. text = document.createTextNode(current_stats["dmg"] - option.stats.dmg);
  1025. }
  1026. else{
  1027. span.setAttribute('class', 'variation');
  1028. text = document.createTextNode(" ");
  1029. }
  1030. span.appendChild(text);
  1031. stat_td.appendChild(span);
  1032. stat_tr.appendChild(stat_td);
  1033. stat_table.appendChild(stat_tr);
  1034. // Add to the main table
  1035. td.appendChild(stat_table);
  1036. tr.appendChild(td);
  1037. // Runes td
  1038. td = document.createElement('td');
  1039. td.setAttribute('class', 'runes');
  1040. td.innerHTML += option.runes[6 - 1].html;
  1041. td.innerHTML += option.runes[1 - 1].html;
  1042. td.innerHTML += option.runes[2 - 1].html;
  1043. td.innerHTML += "<br/>";
  1044. td.innerHTML += option.runes[5 - 1].html;
  1045. td.innerHTML += option.runes[4 - 1].html;
  1046. td.innerHTML += option.runes[3 - 1].html;
  1047. // Add the table
  1048. tr.appendChild(td);
  1049. container.appendChild(tr);
  1050. // Make the section visible
  1051. document.getElementById('results').style.display = 'block';
  1052. }
  1053. time = ((+ new Date()) - timestamp) / 1000;
  1054. log('Done in ' + time + ' seconds');
  1055. enableNewSearch(true);
  1056. }
  1057. /**
  1058. * Function to sort rune combinations based on their score.
  1059. *
  1060. * @param a One combination.
  1061. * @param b Other combination.
  1062. * @return Numeric index for sorting.
  1063. */
  1064. function sortOptions(a, b) {
  1065. return b["score"] - a["score"];
  1066. }
  1067. /**
  1068. * Displays a pop-up message.
  1069. *
  1070. * @param title Message title.
  1071. * @param text Message content.
  1072. */
  1073. function showMessage(title, text){
  1074. document.getElementById('message_title').innerHTML = title;
  1075. document.getElementById('message_text').innerHTML = text;
  1076. document.getElementById('message_container').style.display = 'block';
  1077. }
  1078. /**
  1079. * Closes the message pop-up.
  1080. */
  1081. function closeMessage(){
  1082. document.getElementById('message_container').style.display = 'none';
  1083. }
  1084. /**
  1085. * DEBUG FUNCTION
  1086. *
  1087. * Sets filters to a known value for debugging.
  1088. */
  1089. function debug(){
  1090. document.getElementById('set_1').selectedIndex = 0;
  1091. document.getElementById('set_2').selectedIndex = 0;
  1092. document.getElementById('set_3').selectedIndex = 1;
  1093. removeFilter('attack');
  1094. removeFilter('defense');
  1095. removeFilter('speed');
  1096. removeFilter('crit_rate');
  1097. removeFilter('crit_damage');
  1098. removeFilter('accuracy');
  1099. removeFilter('resistance');
  1100. removeFilter('ehp');
  1101. removeFilter('dmg');
  1102. document.getElementById('lbl_min_hp').value = 13500;
  1103. updateMinValue('hp', document.getElementById('lbl_min_hp'));
  1104. }
  1105. </script>
  1106. </head>
  1107. <body>
  1108. <?php
  1109. include __DIR__ . "/inc/header.php";
  1110. ?>
  1111. <aside>
  1112. <h2>
  1113. Optimize <?=$page->unit->title?>
  1114. </h2>
  1115. <div id='monster_info'>
  1116. <div class='monster_panel'>
  1117. <?=HTML::unit_panel($page->unit)?>
  1118. </div>
  1119. <?php
  1120. $now = time();
  1121. //$datediff = $now - $page->unit->create_time->getTimestamp();
  1122. $datediff = $now - strtotime($page->unit->create_time->format('Y-m-d H:i:s'));
  1123. $datediff = floor($datediff / (60 * 60 * 24));
  1124. ?>
  1125. <div id='monster_details'>
  1126. <?php
  1127. if (sizeof($page->unit->teams) > 0){
  1128. ?>
  1129. <div id='teams'>
  1130. <h4>
  1131. Teams:
  1132. </h4>
  1133. <ul>
  1134. <?php
  1135. foreach($page->unit->teams as $team){
  1136. ?>
  1137. <li>
  1138. <a target='blank' href='/<?=$UID?>/teams/<?=$team->id?>'>
  1139. <?=$team->name?>
  1140. </a>
  1141. </li>
  1142. <?php
  1143. }
  1144. ?>
  1145. </ul>
  1146. </div>
  1147. <?php
  1148. }
  1149. ?>
  1150. </div>
  1151. </div>
  1152. </aside>
  1153. <main>
  1154. <section id='monster' class='content'>
  1155. <h2>
  1156. Optimize <?=$page->unit->title?>
  1157. </h2>
  1158. <article id='profile'>
  1159. <table id='stats'>
  1160. <tr>
  1161. <th>
  1162. Stats
  1163. </th>
  1164. <th>
  1165. Base
  1166. </th>
  1167. <th>
  1168. Runes
  1169. </th>
  1170. <th>
  1171. Artifacts
  1172. </th>
  1173. <th>
  1174. Buildings
  1175. </th>
  1176. <th>
  1177. Total
  1178. </th>
  1179. </tr>
  1180. <tr>
  1181. <th>
  1182. ATK
  1183. </th>
  1184. <td class='base'>
  1185. <?=$page->unit->attack?>
  1186. <span class='percent'>&nbsp;</span>
  1187. </td>
  1188. <td class='extra'>
  1189. +<?=$page->unit->rune_attack?>
  1190. <span class='percent'>&nbsp;</span>
  1191. </td>
  1192. <td class='extra'>
  1193. +<?=$page->unit->artifact_attack?>
  1194. <span class='percent'>&nbsp;</span>
  1195. </td>
  1196. <td class='extra'>
  1197. +<?=$page->unit->building_attack?>
  1198. <span class='percent'>&nbsp;</span>
  1199. </td>
  1200. <td class='total'>
  1201. <?=$page->unit->total_attack?>
  1202. <span class='percent'>&nbsp;</span>
  1203. </td>
  1204. </tr>
  1205. <tr>
  1206. <th>
  1207. DEF
  1208. </th>
  1209. <td class='base'>
  1210. <?=$page->unit->defense?>
  1211. <span class='percent'>&nbsp;</span>
  1212. </td>
  1213. <td class='extra'>
  1214. +<?=$page->unit->rune_defense?>
  1215. <span class='percent'>&nbsp;</span>
  1216. </td>
  1217. <td class='extra'>
  1218. +<?=$page->unit->artifact_defense?>
  1219. <span class='percent'>&nbsp;</span>
  1220. </td>
  1221. <td class='extra'>
  1222. +<?=$page->unit->building_defense?>
  1223. <span class='percent'>&nbsp;</span>
  1224. </td>
  1225. <td class='total'>
  1226. <?=$page->unit->total_defense?>
  1227. <span class='percent'>&nbsp;</span>
  1228. </td>
  1229. </tr>
  1230. <tr>
  1231. <th>
  1232. HP
  1233. </th>
  1234. <td class='base'>
  1235. <?=$page->unit->hp?>
  1236. <span class='percent'>&nbsp;</span>
  1237. </td>
  1238. <td class='extra'>
  1239. +<?=$page->unit->rune_hp?>
  1240. <span class='percent'>&nbsp;</span>
  1241. </td>
  1242. <td class='extra'>
  1243. +<?=$page->unit->artifact_hp?>
  1244. <span class='percent'>&nbsp;</span>
  1245. </td>
  1246. <td class='extra'>
  1247. +<?=$page->unit->building_hp?>
  1248. <span class='percent'>&nbsp;</span>
  1249. </td>
  1250. <td class='total'>
  1251. <?=$page->unit->total_hp?>
  1252. <span class='percent'>&nbsp;</span>
  1253. </td>
  1254. </tr>
  1255. <tr>
  1256. <th>
  1257. SPD
  1258. </th>
  1259. <td class='base'>
  1260. <?=$page->unit->speed?>
  1261. <span class='percent'>&nbsp;</span>
  1262. </td>
  1263. <td class='extra'>
  1264. +<?=$page->unit->rune_speed?>
  1265. <span class='percent'>&nbsp;</span>
  1266. </td>
  1267. <td class='extra'>
  1268. +<?=$page->unit->artifact_speed?>
  1269. <span class='percent'>&nbsp;</span>
  1270. </td>
  1271. <td class='extra'>
  1272. +<?=$page->unit->building_speed?>
  1273. <span class='percent'>&nbsp;</span>
  1274. </td>
  1275. <td class='total'>
  1276. <?=$page->unit->total_speed?>
  1277. <span class='percent'>&nbsp;</span>
  1278. </td>
  1279. </tr>
  1280. <tr>
  1281. <th>
  1282. CRR
  1283. </th>
  1284. <td class='base'>
  1285. <?=$page->unit->crit_rate?>
  1286. <span class='percent'>%</span>
  1287. </td>
  1288. <td class='extra'>
  1289. +<?=$page->unit->rune_crit_rate?>
  1290. <span class='percent'>%</span>
  1291. </td>
  1292. <td class='extra'>
  1293. +<?=$page->unit->artifact_crit_rate?>
  1294. <span class='percent'>%</span>
  1295. </td>
  1296. <td class='extra'>
  1297. +<?=$page->unit->building_crit_rate?>
  1298. <span class='percent'>%</span>
  1299. </td>
  1300. <td class='total'>
  1301. <?=$page->unit->total_crit_rate?>
  1302. <span class='percent'>%</span>
  1303. </td>
  1304. </tr>
  1305. <tr>
  1306. <th>
  1307. CRD
  1308. </th>
  1309. <td class='base'>
  1310. <?=$page->unit->crit_damage?>
  1311. <span class='percent'>%</span>
  1312. </td>
  1313. <td class='extra'>
  1314. +<?=$page->unit->rune_crit_damage?>
  1315. <span class='percent'>%</span>
  1316. </td>
  1317. <td class='extra'>
  1318. +<?=$page->unit->artifact_crit_damage?>
  1319. <span class='percent'>%</span>
  1320. </td>
  1321. <td class='extra'>
  1322. +<?=$page->unit->building_crit_damage?>
  1323. <span class='percent'>%</span>
  1324. </td>
  1325. <td class='total'>
  1326. <?=$page->unit->total_crit_damage?>
  1327. <span class='percent'>%</span>
  1328. </td>
  1329. </tr>
  1330. <tr>
  1331. <th>
  1332. ACC
  1333. </th>
  1334. <td class='base'>
  1335. <?=$page->unit->accuracy?>
  1336. <span class='percent'>%</span>
  1337. </td>
  1338. <td class='extra'>
  1339. +<?=$page->unit->rune_accuracy?>
  1340. <span class='percent'>%</span>
  1341. </td>
  1342. <td class='extra'>
  1343. +<?=$page->unit->artifact_accuracy?>
  1344. <span class='percent'>%</span>
  1345. </td>
  1346. <td class='extra'>
  1347. +<?=$page->unit->building_accuracy?>
  1348. <span class='percent'>%</span>
  1349. </td>
  1350. <td class='total'>
  1351. <?=$page->unit->total_accuracy?>
  1352. <span class='percent'>%</span>
  1353. </td>
  1354. </tr>
  1355. <tr>
  1356. <th>
  1357. RES
  1358. </th>
  1359. <td class='base'>
  1360. <?=$page->unit->resistance?>
  1361. <span class='percent'>%</span>
  1362. </td>
  1363. <td class='extra'>
  1364. +<?=$page->unit->rune_resistance?>
  1365. <span class='percent'>%</span>
  1366. </td>
  1367. <td class='extra'>
  1368. +<?=$page->unit->artifact_resistance?>
  1369. <span class='percent'>%</span>
  1370. </td>
  1371. <td class='extra'>
  1372. +<?=$page->unit->building_resistance?>
  1373. <span class='percent'>%</span>
  1374. </td>
  1375. <td class='total'>
  1376. <?=$page->unit->total_resistance?>
  1377. <span class='percent'>%</span>
  1378. </td>
  1379. </tr>
  1380. <tr>
  1381. <th colspan='5'>
  1382. Effective HP
  1383. </th>
  1384. <td class='total'>
  1385. <?=$page->unit->effective_hp?>
  1386. <span class='percent'>&nbsp;</span>
  1387. </td>
  1388. </tr>
  1389. <tr>
  1390. <th colspan='5'>
  1391. Effective DMG
  1392. </th>
  1393. <td class='total'>
  1394. <?=$page->unit->effective_dmg?>
  1395. <span class='percent'>&nbsp;</span>
  1396. </td>
  1397. </tr>
  1398. </table>
  1399. <div id='artifacts'>
  1400. <?=HTML::artifact_table($page->unit->artifact_type)?>
  1401. <?=HTML::artifact_table($page->unit->artifact_element)?>
  1402. </div>
  1403. </article> <!-- #profile -->
  1404. <article id='current_runes'>
  1405. <?php
  1406. $show_list = [6, 1, 2, 5, 4, 3];
  1407. //foreach ($page->unit->rune as $rune){
  1408. foreach ($show_list as $i){
  1409. $rune = $page->unit->rune[$i - 1];
  1410. ?>
  1411. <?=HTML::rune_table($rune)?>
  1412. <?php
  1413. if ($i == 2){
  1414. ?>
  1415. <br/>
  1416. <?php
  1417. }
  1418. }
  1419. ?>
  1420. </article>
  1421. </section> <!-- runes -->
  1422. <section id='parameters' class='content'>
  1423. <h2>
  1424. Optimization parameters
  1425. </h2>
  1426. <article>
  1427. <table id='parameters'>
  1428. <tr>
  1429. <td class='name'>
  1430. Rune sets
  1431. </td>
  1432. <td class='value'>
  1433. <?php
  1434. $reflect = new ReflectionClass("RUNE_SET_ID");
  1435. ?>
  1436. <select id='set_1'>
  1437. <?php
  1438. foreach($reflect->getConstants() as $name => $id){
  1439. $selected = "";
  1440. if ($id == $sets[0]){
  1441. $selected = "selected='selected'";
  1442. }
  1443. ?>
  1444. <option value='<?=$id?>' <?=$selected?>><?=substr($name, 0, 7)?></option>
  1445. <?php
  1446. }
  1447. ?>
  1448. </select>
  1449. <select id='set_2'>
  1450. <?php
  1451. foreach($reflect->getConstants() as $name => $id){
  1452. $selected = "";
  1453. if ($id == $sets[1]){
  1454. $selected = "selected='selected'";
  1455. }
  1456. ?>
  1457. <option value='<?=$id?>' <?=$selected?>><?=substr($name, 0, 7)?></option>
  1458. <?php
  1459. }
  1460. ?>
  1461. </select>
  1462. <select id='set_3'>
  1463. <option value='' <?=$selected?>></option>
  1464. <?php
  1465. foreach($reflect->getConstants() as $name => $id){
  1466. $selected = "";
  1467. if ($id == $sets[2]){
  1468. $selected = "selected='selected'";
  1469. }
  1470. ?>
  1471. <option value='<?=$id?>' <?=$selected?>><?=substr($name, 0, 7)?></option>
  1472. <?php
  1473. }
  1474. ?>
  1475. </select>
  1476. </td>
  1477. <td class='empty'>
  1478. </td>
  1479. <td class='name'>
  1480. Min HP
  1481. </td>
  1482. <td class='value'>
  1483. <input id='min_hp' type='range' value='<?=$page->unit->total_hp?>' min='<?=$page->unit->hp?>' max='50000' oninput='updateMinValue("hp", this);'>
  1484. <input type='number' id='lbl_min_hp' value='<?=$page->unit->total_hp?>' min='<?=$page->unit->hp?>' max='50000' onChange='updateMinValue("hp", this);'></input><span class='slider_percent'> </span>
  1485. <a title='Remove filter' class='filter_control a_button' onclick='removeFilter("hp");'>
  1486. <img alt='Remove filter' src='<?=URL::IMG["ICON"]?>nok.png'/>
  1487. </a>
  1488. <a title='Reset filter' class='filter_control a_button' onclick='resetFilter("hp");'>
  1489. <img alt='Reset filter' src='<?=URL::IMG["ICON"]?>edit.png'/>
  1490. </a>
  1491. </td>
  1492. </tr>
  1493. <tr>
  1494. <td class='name'>
  1495. Even slots
  1496. </td>
  1497. <td class='value'>
  1498. <select id='slot_2'>
  1499. <option value='<?=RUNE_STAT_ID::HP_P?>' <?=($mains[0] == RUNE_STAT_ID::HP_P) ? ("selected='selected'") : ("");?>>HP%</option>
  1500. <option value='<?=RUNE_STAT_ID::ATK_P?>' <?=($mains[0] == RUNE_STAT_ID::ATK_P) ? ("selected='selected'") : ("");?>>ATK%</option>
  1501. <option value='<?=RUNE_STAT_ID::DEF_P?>' <?=($mains[0] == RUNE_STAT_ID::DEF_P) ? ("selected='selected'") : ("");?>>DEF%</option>
  1502. <option value='<?=RUNE_STAT_ID::SPD?>' <?=($mains[0] == RUNE_STAT_ID::SPD) ? ("selected='selected'") : ("");?>>SPD</option>
  1503. </select>
  1504. <select id='slot_4'>
  1505. <option value='<?=RUNE_STAT_ID::HP_P?>' <?=($mains[1] == RUNE_STAT_ID::HP_P) ? ("selected='selected'") : ("");?>>HP%</option>
  1506. <option value='<?=RUNE_STAT_ID::ATK_P?>' <?=($mains[1] == RUNE_STAT_ID::ATK_P) ? ("selected='selected'") : ("");?>>ATK%</option>
  1507. <option value='<?=RUNE_STAT_ID::DEF_P?>' <?=($mains[1] == RUNE_STAT_ID::DEF_P) ? ("selected='selected'") : ("");?>>DEF%</option>
  1508. <option value='<?=RUNE_STAT_ID::CRR?>' <?=($mains[1] == RUNE_STAT_ID::CRR) ? ("selected='selected'") : ("");?>>CRR</option>
  1509. <option value='<?=RUNE_STAT_ID::CRR?>' <?=($mains[1] == RUNE_STAT_ID::CRD) ? ("selected='selected'") : ("");?>>CRD</option>
  1510. </select>
  1511. <select id='slot_6'>
  1512. <option value='<?=RUNE_STAT_ID::HP_P?>' <?=($mains[2] == RUNE_STAT_ID::HP_P) ? ("selected='selected'") : ("");?>>HP%</option>
  1513. <option value='<?=RUNE_STAT_ID::ATK_P?>' <?=($mains[2] == RUNE_STAT_ID::ATK_P) ? ("selected='selected'") : ("");?>>ATK%</option>
  1514. <option value='<?=RUNE_STAT_ID::DEF_P?>' <?=($mains[2] == RUNE_STAT_ID::DEF_P) ? ("selected='selected'") : ("");?>>DEF%</option>
  1515. <option value='<?=RUNE_STAT_ID::ACC?>' <?=($mains[2] == RUNE_STAT_ID::ACC) ? ("selected='selected'") : ("");?>>ACC</option>
  1516. <option value='<?=RUNE_STAT_ID::RES?>' <?=($mains[2] == RUNE_STAT_ID::RES) ? ("selected='selected'") : ("");?>>RES</option>
  1517. </select>
  1518. </td>
  1519. <td class='empty'>
  1520. </td>
  1521. <td class='name'>
  1522. Min ATK
  1523. </td>
  1524. <td class='value'>
  1525. <input id='min_attack' type='range' value='<?=$page->unit->total_attack?>' min='<?=$page->unit->attack?>' max='4000' oninput='updateMinValue("attack", this);'>
  1526. <input type='number' id='lbl_min_attack' value='<?=$page->unit->total_attack?>' min='<?=$page->unit->attack?>' max='4000' onChange='updateMinValue("attack", this);'></input><span class='slider_percent'> </span>
  1527. <a title='Remove filter' class='filter_control a_button' onclick='removeFilter("attack");'>
  1528. <img alt='Remove filter' src='<?=URL::IMG["ICON"]?>nok.png'/>
  1529. </a>
  1530. <a title='Reset filter' class='filter_control a_button' onclick='resetFilter("attack");'>
  1531. <img alt='Reset filter' src='<?=URL::IMG["ICON"]?>edit.png'/>
  1532. </a>
  1533. </td>
  1534. </tr>
  1535. <tr>
  1536. <td class='name'>
  1537. Use runes from
  1538. </td>
  1539. <td class='value'>
  1540. <select id='rune_source'>
  1541. <option value='0'>Storage only</option>
  1542. <option value='1'>Units in no teams</option>
  1543. <option value='2'>Units in teams with 0 score</option>
  1544. <option value='3'>Units with lower overall score</option>
  1545. <option value='4'>All runes</option>
  1546. </select>
  1547. </td>
  1548. <td class='empty'>
  1549. </td>
  1550. <td class='name'>
  1551. Min DEF
  1552. </td>
  1553. <td class='value'>
  1554. <input id='min_defense' type='range' value='<?=$page->unit->total_defense?>' min='<?=$page->unit->defense?>' max='4000' oninput='updateMinValue("defense", this);'>
  1555. <input type='number' id='lbl_min_defense' value='<?=$page->unit->total_defense?>' min='<?=$page->unit->defense?>' max='4000' onChange='updateMinValue("defense", this);'></input><span class='slider_percent'> </span>
  1556. <a title='Remove filter' class='filter_control a_button' onclick='removeFilter("defense");'>
  1557. <img alt='Remove filter' src='<?=URL::IMG["ICON"]?>nok.png'/>
  1558. </a>
  1559. <a title='Reset filter' class='filter_control a_button' onclick='resetFilter("defense");'>
  1560. <img alt='Reset filter' src='<?=URL::IMG["ICON"]?>edit.png'/>
  1561. </a>
  1562. </td>
  1563. </tr>
  1564. <tr>
  1565. <td class='name'>
  1566. Tune optimizer for
  1567. </td>
  1568. <td class='value'>
  1569. <select id='tuning'>
  1570. <option value='0'>Rune current levels</option>
  1571. <option value='1'>+12</option>
  1572. <option value='2'>2/4/6 +15, 1/3/5 + 12</option>
  1573. <option value='3'>+15</option>
  1574. </select>
  1575. </td>
  1576. <td class='empty'>
  1577. </td>
  1578. <td class='name'>
  1579. Min SPD
  1580. </td>
  1581. <td class='value'>
  1582. <input id='min_speed' type='range' value='<?=$page->unit->total_speed?>' min='<?=$page->unit->speed?>' max='400' oninput='updateMinValue("speed", this);'>
  1583. <input type='number' id='lbl_min_speed' value='<?=$page->unit->total_speed?>' min='<?=$page->unit->speed?>' max='400' onChange='updateMinValue("speed", this);'></input><span class='slider_percent'> </span>
  1584. <a title='Remove filter' class='filter_control a_button' onclick='removeFilter("speed");'>
  1585. <img alt='Remove filter' src='<?=URL::IMG["ICON"]?>nok.png'/>
  1586. </a>
  1587. <a title='Reset filter' class='filter_control a_button' onclick='resetFilter("speed");'>
  1588. <img alt='Reset filter' src='<?=URL::IMG["ICON"]?>edit.png'/>
  1589. </a>
  1590. </td>
  1591. </tr>
  1592. <tr>
  1593. <td class='empty'>
  1594. Max. combinations
  1595. </td>
  1596. <td class='empty'>
  1597. <input id='limit' type='number' value='10' max='100' min='1'>
  1598. </td>
  1599. <td class='empty'>
  1600. </td>
  1601. <td class='name'>
  1602. Min CRR
  1603. </td>
  1604. <td class='value'>
  1605. <input id='min_crit_rate' type='range' value='<?=$page->unit->total_crit_rate?>' min='<?=$page->unit->crit_rate?>' max='100' oninput='updateMinValue("crit_rate", this);'>
  1606. <input type='number' id='lbl_min_crit_rate' value='<?=$page->unit->total_crit_rate?>' min='<?=$page->unit->crit_rate?>' max='100' onChange='updateMinValue("crit_rate", this);'></input><span class='slider_percent'>%</span>
  1607. <a title='Remove filter' class='filter_control a_button' onclick='removeFilter("crit_rate");'>
  1608. <img alt='Remove filter' src='<?=URL::IMG["ICON"]?>nok.png'/>
  1609. </a>
  1610. <a title='Reset filter' class='filter_control a_button' onclick='resetFilter("crit_rate");'>
  1611. <img alt='Reset filter' src='<?=URL::IMG["ICON"]?>edit.png'/>
  1612. </a>
  1613. </td>
  1614. </tr>
  1615. <tr>
  1616. <td id='log' colspan='2' rowspan='4'>
  1617. <div id='log_title'>
  1618. LOG
  1619. <span id='log_clear' onClick='clearLog();'>
  1620. clear
  1621. </span>
  1622. </div>
  1623. <div id='log_window'>
  1624. </div>
  1625. </td>
  1626. <td class='empty'>
  1627. </td>
  1628. <td class='name'>
  1629. Min CRD
  1630. </td>
  1631. <td class='value'>
  1632. <input id='min_crit_damage' type='range' value='<?=$page->unit->total_crit_damage?>' min='<?=$page->unit->crit_damage?>' max='400' oninput='updateMinValue("crit_damage", this);'>
  1633. <input type='number' id='lbl_min_crit_damage' value='<?=$page->unit->total_crit_damage?>' min='<?=$page->unit->crit_damage?>' max='400' onChange='updateMinValue("crit_damage", this);'></input><span class='slider_percent'>%</span>
  1634. <a title='Remove filter' class='filter_control a_button' onclick='removeFilter("crit_damage");'>
  1635. <img alt='Remove filter' src='<?=URL::IMG["ICON"]?>nok.png'/>
  1636. </a>
  1637. <a title='Reset filter' class='filter_control a_button' onclick='resetFilter("crit_damage");'>
  1638. <img alt='Reset filter' src='<?=URL::IMG["ICON"]?>edit.png'/>
  1639. </a>
  1640. </td>
  1641. </tr>
  1642. <tr>
  1643. <!--<td class='empty'>
  1644. </td>-->
  1645. <!--<td class='empty'>
  1646. </td>-->
  1647. <td class='empty'>
  1648. </td>
  1649. <td class='name'>
  1650. Min ACC
  1651. </td>
  1652. <td class='value'>
  1653. <input id='min_accuracy' type='range' value='<?=$page->unit->total_accuracy?>' min='<?=$page->unit->accuracy?>' max='85' oninput='updateMinValue("accuracy", this);'>
  1654. <input type='number' id='lbl_min_accuracy' value='<?=$page->unit->total_accuracy?>' min='<?=$page->unit->accuracy?>' max='85' onChange='updateMinValue("accuracy", this);'></input><span class='slider_percent'>%</span>
  1655. <a title='Remove filter' class='filter_control a_button' onclick='removeFilter("accuracy");'>
  1656. <img alt='Remove filter' src='<?=URL::IMG["ICON"]?>nok.png'/>
  1657. </a>
  1658. <a title='Reset filter' class='filter_control a_button' onclick='resetFilter("accuracy");'>
  1659. <img alt='Reset filter' src='<?=URL::IMG["ICON"]?>edit.png'/>
  1660. </a>
  1661. </td>
  1662. </tr>
  1663. <tr>
  1664. <!--<td class='empty'>
  1665. </td>-->
  1666. <!--<td class='empty'>
  1667. </td>-->
  1668. <td class='empty'>
  1669. </td>
  1670. <td class='name'>
  1671. Min RES
  1672. </td>
  1673. <td class='value'>
  1674. <input id='min_resistance' type='range' value='<?=$page->unit->total_resistance?>' min='<?=$page->unit->resistance?>' max='85' oninput='updateMinValue("resistance", this);'>
  1675. <input type='number' id='lbl_min_resistance' value='<?=$page->unit->total_resistance?>' min='<?=$page->unit->resistance?>' max='85' onChange='updateMinValue("resistance", this);'></input><span class='slider_percent'>%</span>
  1676. <a title='Remove filter' class='filter_control a_button' onclick='removeFilter("resistance");'>
  1677. <img alt='Remove filter' src='<?=URL::IMG["ICON"]?>nok.png'/>
  1678. </a>
  1679. <a title='Reset filter' class='filter_control a_button' onclick='resetFilter("resistance");'>
  1680. <img alt='Reset filter' src='<?=URL::IMG["ICON"]?>edit.png'/>
  1681. </a>
  1682. </td>
  1683. </tr>
  1684. <tr>
  1685. <!--<td class='empty'>
  1686. </td>-->
  1687. <!--<td class='empty'>
  1688. </td>-->
  1689. <td class='empty'>
  1690. </td>
  1691. <td class='name'>
  1692. Min EHP
  1693. </td>
  1694. <td class='value'>
  1695. <input id='min_ehp' type='range' value='<?=$page->unit->effective_hp?>' min='0' max='200000' oninput='updateMinValue("ehp", this);'>
  1696. <input type='number' id='lbl_min_ehp' value='<?=$page->unit->effective_hp?>' min='0' max='200000' onChange='updateMinValue("ehp", this);'></input><span class='slider_percent'> </span>
  1697. <a title='Remove filter' class='filter_control a_button' onclick='removeFilter("ehp");'>
  1698. <img alt='Remove filter' src='<?=URL::IMG["ICON"]?>nok.png'/>
  1699. </a>
  1700. <a title='Reset filter' class='filter_control a_button' onclick='resetFilter("ehp");'>
  1701. <img alt='Reset filter' src='<?=URL::IMG["ICON"]?>edit.png'/>
  1702. </a>
  1703. </td>
  1704. </tr>
  1705. <tr>
  1706. <td class='action'>
  1707. <input id='apply' type='button' value='Apply' onClick='apply();'/>
  1708. <!--<input id='apply' type='button' value='DEBUG' onClick='debug();'/>-->
  1709. </td>
  1710. <td class='empty'>
  1711. <img id='wait' src='<?=URL::IMG["ICON"] . "wait.gif";?>'>
  1712. </td>
  1713. <td class='empty'>
  1714. </td>
  1715. <td class='name'>
  1716. Min DMG
  1717. </td>
  1718. <td class='value'>
  1719. <input id='min_dmg' type='range' value='<?=$page->unit->effective_dmg?>' min='0' max='7000' oninput='updateMinValue("dmg", this);'>
  1720. <input type='number' id='lbl_min_dmg' value='<?=$page->unit->effective_dmg?>' min='0' max='7000' onChange='updateMinValue("dmg", this);'></input><span class='slider_percent'> </span>
  1721. <a title='Remove filter' class='filter_control a_button' onclick='removeFilter("dmg");'>
  1722. <img alt='Remove filter' src='<?=URL::IMG["ICON"]?>nok.png'/>
  1723. </a>
  1724. <a title='Reset filter' class='filter_control a_button' onclick='resetFilter("dmg");'>
  1725. <img alt='Reset filter' src='<?=URL::IMG["ICON"]?>edit.png'/>
  1726. </a>
  1727. </td>
  1728. </tr>
  1729. </table>
  1730. </article>
  1731. </section>
  1732. <section id='results' class='content'>
  1733. <h2>
  1734. Optimization results
  1735. </h2>
  1736. <article>
  1737. <table id='table_optimizations'>
  1738. <tbody id='optimizations'>
  1739. </tbody>
  1740. </table>
  1741. </article>
  1742. </section>
  1743. </main>
  1744. <div id='message_container'>
  1745. <section class='content'>
  1746. <h2 id='message_title'>
  1747. Message
  1748. </h2>
  1749. <article>
  1750. <p id='message_text'>
  1751. Message Text
  1752. </p>
  1753. </article>
  1754. <input type='button' value='OK' id='message_button' onclick='closeMessage();'/>
  1755. </section>
  1756. </div>
  1757. <?php
  1758. include __DIR__ . "/inc/footer.php";
  1759. ?>
  1760. </body>
  1761. </html>