optimizer_unit.php 101 KB

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