optimizer_unit.php 103 KB

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