optimizer_unit.php 95 KB

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