optimize_get_rune_list.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. <?php
  2. /**
  3. * File for the optimization action.
  4. *
  5. * Implements an action function to be called from the {@see Controller}.
  6. *
  7. * @category Action
  8. */
  9. /**
  10. * TODO
  11. * Executes the optimization action.
  12. *
  13. * Reads the POST parameters looking for the following KEYS:
  14. * mail
  15. * pass + currentPass
  16. * api
  17. * Then it updates the selected info with the prameter vlue. Multiple
  18. * itemas can be updated at the same time.
  19. *
  20. * @return int|string 0 on success, negative values on error. If the API
  21. * key has been updated, the new key.
  22. * @category Action
  23. */
  24. function action(){
  25. // Increase max execution time.
  26. set_time_limit(60);
  27. $candidates = [
  28. 1 => [],
  29. 2 => [],
  30. 3 => [],
  31. 4 => [],
  32. 5 => [],
  33. 6 => []
  34. ];
  35. $response = null;
  36. $player = filter_input(INPUT_POST, 'player');
  37. if ($player == null){
  38. return -1;
  39. }
  40. $unit_id = filter_input(INPUT_POST, 'unit');
  41. if ($unit_id == null){
  42. return -2;
  43. }
  44. // Sets
  45. $sets = [];
  46. foreach ($_POST["set"] as $x){
  47. array_push($sets, intval($x));
  48. }
  49. if (sizeof($sets) < 2 || sizeof($sets) > 3){
  50. return -3;
  51. }
  52. // Main stats in even slots.
  53. $stats = [];
  54. foreach ($_POST["stat"] as $x){
  55. array_push($stats, intval($x));
  56. }
  57. $source = filter_input(INPUT_POST, 'source');
  58. if ($source == null){
  59. return -4;
  60. }
  61. $limit = intval(filter_input(INPUT_POST, 'limit'));
  62. if ($limit == 0){
  63. return -5;
  64. }
  65. $tuning = filter_input(INPUT_POST, 'tuning');
  66. if ($tuning == null){
  67. return -6;
  68. }
  69. // Instantiate the unit
  70. $unit = new Unit($unit_id, true, $player);
  71. // Get build query:
  72. $base_s = "
  73. SELECT
  74. id,
  75. type,
  76. slot,
  77. level,
  78. stars,
  79. (SELECT stat FROM rune_stat WHERE rune = rune.id AND slot = " . RUNE_STAT_SLOT_ID::MAIN . " ) AS main_stat,
  80. (SELECT value FROM rune_stat WHERE rune = rune.id AND slot = " . RUNE_STAT_SLOT_ID::MAIN . " ) AS main_stat_value,
  81. (SELECT stat FROM rune_stat WHERE rune = rune.id AND slot = " . RUNE_STAT_SLOT_ID::INNATE . " ) AS innate_stat,
  82. (SELECT value FROM rune_stat WHERE rune = rune.id AND slot = " . RUNE_STAT_SLOT_ID::INNATE . " ) AS innate_stat_value,
  83. (SELECT stat FROM rune_stat WHERE rune = rune.id AND slot = " . RUNE_STAT_SLOT_ID::SUBSTAT_1 . " ) AS substat_1,
  84. (SELECT value + grind FROM rune_stat WHERE rune = rune.id AND slot = " . RUNE_STAT_SLOT_ID::SUBSTAT_1 . " ) AS substat_1_value,
  85. (SELECT stat FROM rune_stat WHERE rune = rune.id AND slot = " . RUNE_STAT_SLOT_ID::SUBSTAT_2 . " ) AS substat_2,
  86. (SELECT value + grind FROM rune_stat WHERE rune = rune.id AND slot = " . RUNE_STAT_SLOT_ID::SUBSTAT_2 . " ) AS substat_2_value,
  87. (SELECT stat FROM rune_stat WHERE rune = rune.id AND slot = " . RUNE_STAT_SLOT_ID::SUBSTAT_3 . " ) AS substat_3,
  88. (SELECT value + grind FROM rune_stat WHERE rune = rune.id AND slot = " . RUNE_STAT_SLOT_ID::SUBSTAT_3 . " ) AS substat_3_value,
  89. (SELECT stat FROM rune_stat WHERE rune = rune.id AND slot = " . RUNE_STAT_SLOT_ID::SUBSTAT_4 . " ) AS substat_4,
  90. (SELECT value + grind FROM rune_stat WHERE rune = rune.id AND slot = " . RUNE_STAT_SLOT_ID::SUBSTAT_4 . " ) AS substat_4_value
  91. FROM data.rune
  92. WHERE
  93. player = :player AND
  94. type IN (
  95. ";
  96. foreach ($sets as $set){
  97. $base_s .= ($set . ",");
  98. }
  99. $base_s .= "-1) AND ";
  100. switch ($source){
  101. case 0: // Storage only (or itself)
  102. $base_s .= "
  103. (
  104. rune.id IN (SELECT DISTINCT unit FROM data.unit_rune WHERE unit = :unit_id AND rta = " . get_context()->get_game_mode() . ")
  105. OR rune.id NOT IN (SELECT DISTINCT unit FROM data.unit_rune WHERE rta = " . get_context()->get_game_mode() . ")
  106. )";
  107. break;
  108. case 1: // Units in no teams (or itself)
  109. $base_s .= "
  110. (
  111. rune.id IN (SELECT DISTINCT unit FROM data.unit_rune WHERE unit = :unit_id AND rta = " . get_context()->get_game_mode() . ")
  112. OR rune.id NOT IN (SELECT DISTINCT unit FROM data.unit_rune WHERE rta = " . get_context()->get_game_mode() . ")
  113. OR rune.id NOT IN (SELECT DISTINCT unit FROM data.unit_rune WHERE rta = " . get_context()->get_game_mode() . " AND unit NOT IN (SELECT DISTINCT unit FROM team_unit))
  114. )
  115. ";
  116. break;
  117. case 2: // Units in teams with 0 score (or itself)
  118. $base_s .= "
  119. (
  120. rune.id IN (SELECT DISTINCT unit FROM data.unit_rune WHERE unit = :unit_id AND rta = " . get_context()->get_game_mode() . ")
  121. OR rune.id NOT IN (SELECT DISTINCT unit FROM data.unit_rune WHERE rta = " . get_context()->get_game_mode() . ")
  122. OR rune.id NOT IN (
  123. SELECT DISTINCT unit
  124. FROM unit_rune
  125. WHERE
  126. rta = " . get_context()->get_game_mode() . "
  127. AND unit NOT IN (
  128. SELECT DISTINCT unit
  129. FROM
  130. team,
  131. team_unit
  132. WHERE
  133. team.id = team_unit.team
  134. AND team.score > 0
  135. )
  136. )
  137. )
  138. ";
  139. break;
  140. case 3: // Units with lower overall score (or itself)
  141. // TODO
  142. break;
  143. case 4: // All runes - dont filter
  144. $base_s .= " 1 = 1 ";
  145. break;
  146. default: // Invalid options - return nothing
  147. $base_s .= " 1 = 0 ";
  148. }
  149. $s_order = " ORDER BY stars DESC, original_quality DESC, max_efficiency DESC, efficiency DESC, level DESC";
  150. $s_in = " main_stat IN (:stat_0, :stat_1, :stat_2) ";
  151. $s = ["", "", "", "", "", "", ""];
  152. $s[1] = $base_s . " AND slot = 1 " . $s_order;
  153. $s[3] = $base_s . " AND slot = 3 " . $s_order;
  154. $s[5] = $base_s . " AND slot = 5 " . $s_order;
  155. $s[2] = $base_s . " AND slot = 2 AND " . $s_in . $s_order;
  156. $s[4] = $base_s . " AND slot = 4 AND " . $s_in . $s_order;
  157. $s[6] = $base_s . " AND slot = 6 AND " . $s_in . $s_order;
  158. $total_candidates = 0;
  159. for ($i = 1; $i <= 6; $i ++){
  160. $statement = get_context()->get_db()->prepare($s[$i]);
  161. $statement->bindValue(':player', $player, SQLITE3_TEXT);
  162. $statement->bindValue(':unit_id', $unit_id, SQLITE3_TEXT);
  163. $statement->bindValue(':stat_0', $stats[0], SQLITE3_TEXT);
  164. $statement->bindValue(':stat_1', $stats[1], SQLITE3_TEXT);
  165. $statement->bindValue(':stat_2', $stats[2], SQLITE3_TEXT);
  166. $q = $statement->execute();
  167. while ($r = $q->fetchArray(SQLITE3_ASSOC)){
  168. $rune = create_rune_array($unit, $r, $tuning);
  169. //array_push($candidates[$i], new Rune($r["id"]));
  170. array_push($candidates[$i], $rune);
  171. $total_candidates ++;
  172. }
  173. }
  174. //$max_combinations = sizeof($candidates[1]) * sizeof($candidates[2]) * sizeof($candidates[3]) * sizeof($candidates[4]) * sizeof($candidates[5]) * sizeof($candidates[6]);
  175. // Build response
  176. $response = json_encode($candidates);
  177. if ($response == null){
  178. return 0;
  179. }
  180. else{
  181. return $response;
  182. }
  183. }
  184. /**
  185. * Creates an array with the stats provided by a rune on a unit.
  186. *
  187. * @param Unit $unit Target unit.
  188. * @param int $r Rune main stat ID.
  189. * @param int $stars Rune stars.
  190. * @return int Value of the main stat at the selected level.
  191. */
  192. function create_rune_array($unit, $r, $tuning){
  193. $rune = [
  194. "ID" => $r["id"],
  195. "TYPE" => $r["type"],
  196. "ATK" => 0,
  197. "DEF" => 0,
  198. "HP" => 0,
  199. "SPD" => 0,
  200. "CRR" => 0,
  201. "CRD" => 0,
  202. "ACC" => 0,
  203. "RES" => 0
  204. ];
  205. // Calculate main stat value based on requested level.
  206. $level = $r["level"];
  207. $main_value = $r["main_stat_value"];
  208. switch ($tuning){
  209. case 1: // All +12
  210. if ($level < 12){
  211. $main_value = get_main_stat_at_level(12, $r["main_stat"], $r["stars"]);
  212. }
  213. break;
  214. case 2: // Even +15, Odd + 12
  215. if ($level < 15 && $r["slot"] % 2 == 0){
  216. $main_value = get_main_stat_at_level(15, $r["main_stat"], $r["stars"]);
  217. }
  218. elseif ($level < 12 && $r["slot"] % 2 != 0){
  219. $main_value = get_main_stat_at_level(12, $r["main_stat"], $r["stars"]);
  220. }
  221. break;
  222. case 3: // All +15
  223. if ($level < 15){
  224. $main_value = get_main_stat_at_level(15, $r["main_stat"], $r["stars"]);
  225. }
  226. break;
  227. }
  228. // Array to loop.
  229. $stats = [
  230. [
  231. "STAT" => $r["main_stat"],
  232. "VALUE" => $main_value
  233. ],
  234. [
  235. "STAT" => $r["innate_stat"],
  236. "VALUE" => $r["innate_stat_value"]
  237. ],
  238. [
  239. "STAT" => $r["substat_1"],
  240. "VALUE" => $r["substat_1_value"]
  241. ],
  242. [
  243. "STAT" => $r["substat_2"],
  244. "VALUE" => $r["substat_2_value"]
  245. ],
  246. [
  247. "STAT" => $r["substat_3"],
  248. "VALUE" => $r["substat_3_value"]
  249. ],
  250. [
  251. "STAT" => $r["substat_4"],
  252. "VALUE" => $r["substat_4_value"]
  253. ]
  254. ];
  255. foreach ($stats as $stat){
  256. switch ($stat["STAT"]){
  257. case RUNE_STAT_ID::ATK:
  258. $rune["ATK"] += $stat["VALUE"];
  259. break;
  260. case RUNE_STAT_ID::ATK_P:
  261. $rune["ATK"] += ($unit->attack * $stat["VALUE"] / 100);
  262. break;
  263. case RUNE_STAT_ID::DEF:
  264. $rune["DEF"] += $stat["VALUE"];
  265. break;
  266. case RUNE_STAT_ID::DEF_P:
  267. $rune["DEF"] += ($unit->defense * $stat["VALUE"] / 100);
  268. break;
  269. case RUNE_STAT_ID::HP:
  270. $rune["HP"] += $stat["VALUE"];
  271. break;
  272. case RUNE_STAT_ID::HP_P:
  273. $rune["HP"] += ($unit->hp * $stat["VALUE"] / 100);
  274. break;
  275. case RUNE_STAT_ID::SPD:
  276. $rune["SPD"] += $stat["VALUE"];
  277. break;
  278. case RUNE_STAT_ID::CRR:
  279. $rune["CRR"] += $stat["VALUE"];
  280. break;
  281. case RUNE_STAT_ID::CRD:
  282. $rune["CRD"] += $stat["VALUE"];
  283. break;
  284. case RUNE_STAT_ID::ACC:
  285. $rune["ACC"] += $stat["VALUE"];
  286. break;
  287. case RUNE_STAT_ID::RES:
  288. $rune["RES"] += $stat["VALUE"];
  289. break;
  290. }
  291. }
  292. return $rune;
  293. }
  294. /**
  295. * Gets the value of the main stat at an arbitrary level.
  296. *
  297. * @param int $level Desired level.
  298. * @param int $stat Rune main stat ID.
  299. * @param int $stars Rune stars.
  300. * @return int Value of the main stat at the selected level.
  301. */
  302. function get_main_stat_at_level($level, $stat, $stars){
  303. $level = intval($level);
  304. if ($level < 0 || $level > 15){
  305. return 0;
  306. }
  307. switch ($stat){
  308. case RUNE_STAT_ID::HP:
  309. return RUNE_STAT_VALUES::HP[$stars][$level];
  310. case RUNE_STAT_ID::HP_P:
  311. return RUNE_STAT_VALUES::HP_P[$stars][$level];
  312. case RUNE_STAT_ID::ATK:
  313. return RUNE_STAT_VALUES::ATK[$stars][$level];
  314. case RUNE_STAT_ID::ATK_P:
  315. return RUNE_STAT_VALUES::ATK_P[$stars][$level];
  316. case RUNE_STAT_ID::DEF:
  317. return RUNE_STAT_VALUES::DEF[$stars][$level];
  318. case RUNE_STAT_ID::DEF_P:
  319. return RUNE_STAT_VALUES::DEF_P[$stars][$level];
  320. case RUNE_STAT_ID::SPD:
  321. return RUNE_STAT_VALUES::SPD[$stars][$level];
  322. case RUNE_STAT_ID::CRR:
  323. return RUNE_STAT_VALUES::CRR[$stars][$level];
  324. case RUNE_STAT_ID::CRD:
  325. return RUNE_STAT_VALUES::CRD[$stars][$level];
  326. case RUNE_STAT_ID::RES:
  327. return RUNE_STAT_VALUES::RES[$stars][$level];
  328. case RUNE_STAT_ID::ACC:
  329. return RUNE_STAT_VALUES::ACC[$stars][$level];
  330. default:
  331. return 0;
  332. }
  333. }
  334. ?>