Rune.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  1. <?php
  2. /**
  3. * Rune entity file.
  4. *
  5. * Creates the entity and makes it available.
  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. */
  11. require_once(PATH::ENTITY . "Entity.php");
  12. require_once(PATH::ENTITY . "Rune_Set.php");
  13. require_once(PATH::ENTITY . "Rune_Stat.php");
  14. /**
  15. * Owned rune.
  16. *
  17. * Represents a rune.
  18. *
  19. * @category Entity
  20. */
  21. class Rune extends Entity{
  22. /**
  23. * @var int Owner identifier.
  24. */
  25. private $player;
  26. /**
  27. * @var int Rune identifier.
  28. */
  29. private $id;
  30. /**
  31. * @var Rune_Set Rune set.
  32. */
  33. private $type;
  34. /**
  35. * @var int Position of the rune type (1-6).
  36. */
  37. private $slot;
  38. /**
  39. * @var int Rune stars.
  40. */
  41. private $stars;
  42. /**
  43. * @var bool Indicates if the rune is ancient.
  44. */
  45. private $ancient;
  46. /**
  47. * @var int Level of the rune.
  48. */
  49. private $level;
  50. /**
  51. * @var int Rune quality.
  52. * @see QUALITY_ID
  53. */
  54. private $quality;
  55. /**
  56. * @var int Rune original quality.
  57. * @see QUALITY_ID
  58. */
  59. private $original_quality;
  60. /**
  61. * @var string Rune quality name (uppercase).
  62. */
  63. private $quality_name;
  64. /**
  65. * @var string Rune original quality name (uppercase).
  66. */
  67. private $original_quality_name;
  68. /**
  69. * @var int Price of the rune.
  70. */
  71. private $value;
  72. /**
  73. * @var float Current efficiency of the rune.
  74. */
  75. private $efficiency;
  76. /**
  77. * @var float Maximum potential efficiency of the rune.
  78. */
  79. private $max_efficiency;
  80. /**
  81. * @var int Indicates if the rune is locked.
  82. */
  83. private $locked;
  84. /**
  85. * @var bool Internal flag to check if the rune stats have been loaded into the entity.
  86. */
  87. private $flag_stats = false;
  88. /**
  89. * @var Rune_Stat Main stat of the rune.
  90. */
  91. private $main_stat;
  92. /**
  93. * @var Rune_Stat Extra stat of the rune.
  94. */
  95. private $innate_stat;
  96. /**
  97. * @var Rune_Stat[] Substats of the rune.
  98. */
  99. private $substats = [];
  100. /**
  101. * @var Rune_Stat[] All stats.
  102. *
  103. * Includes main, innate and substats
  104. */
  105. private $stats = [];
  106. /**
  107. * @var bool Internal flag to check if the unit who equips the rune has been loaded.
  108. */
  109. private $flag_unit = false;
  110. /**
  111. * @var Unit Unit the rune is assigned to.
  112. */
  113. private $unit;
  114. /**
  115. * Constructor.
  116. *
  117. * Searches the database and retrieves the information about the
  118. * rune, populating it and it's items.
  119. *
  120. * @param int $id Rune id.
  121. */
  122. public function __construct($id){
  123. $statement = get_context()->get_db()->prepare("
  124. SELECT
  125. id,
  126. type,
  127. slot,
  128. stars,
  129. level,
  130. ancient,
  131. quality,
  132. original_quality,
  133. value,
  134. efficiency,
  135. max_efficiency,
  136. locked
  137. FROM rune
  138. WHERE id = :id;
  139. ");
  140. $statement->bindValue(':id', $id, SQLITE3_TEXT);
  141. $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
  142. if ($r){
  143. $this->id = $r["id"];
  144. $this->type = new Rune_Set($r["type"]);
  145. $this->slot = $r["slot"];
  146. $this->stars = $r["stars"];
  147. $this->level = $r["level"];
  148. $this->ancient = $r["ancient"];
  149. $this->quality = $r["quality"];
  150. $this->original_quality = $r["original_quality"];
  151. $this->value = $r["value"];
  152. $this->efficiency = $r["efficiency"];
  153. $this->max_efficiency = $r["max_efficiency"];
  154. $this->locked = filter_var($r["locked"], FILTER_VALIDATE_BOOLEAN);
  155. $this->quality_name = $this->map_quality_name($this->quality);
  156. $this->original_quality_name = $this->map_quality_name($this->original_quality);
  157. // Read efficiencies. If not set in DB, calculate and update.
  158. if ($this->efficiency == null || $this->efficiency == "" || intval($this->efficiency) == 0){
  159. $this->efficiency = $this->calculate_efficiency();
  160. $this->max_efficiency = $this->calculate_maximum_efficiency();
  161. $statement = get_context()->get_db()->prepare("
  162. UPDATE rune
  163. SET
  164. efficiency = :efficiency,
  165. max_efficiency = :max_efficiency
  166. WHERE id = :rune
  167. ");
  168. $statement->bindValue(':efficiency', $this->efficiency, SQLITE3_FLOAT);
  169. $statement->bindValue(':max_efficiency', $this->max_efficiency, SQLITE3_FLOAT);
  170. $statement->bindValue(':rune', $this->id, SQLITE3_INTEGER);
  171. $statement->execute();
  172. }
  173. }
  174. }
  175. /**
  176. * Loads the stats.
  177. *
  178. * Must be called only once before trying to get any of the stats (main, innate or subs) or
  179. * efficiencies. Sets the flag {@link Rune:$flag_stats} to true.
  180. */
  181. private function load_stats(){
  182. $statement = get_context()->get_db()->prepare("
  183. SELECT slot
  184. FROM rune_stat
  185. WHERE rune = :rune
  186. ORDER BY slot;
  187. ");
  188. $statement->bindValue(':rune', $this->id, SQLITE3_TEXT);
  189. $q = $statement->execute();
  190. while ($r = $q->fetchArray(SQLITE3_ASSOC)){
  191. $stat = new Rune_Stat($this->id, $r["slot"]);
  192. array_push($this->stats, $stat);
  193. switch ($r["slot"]){
  194. case RUNE_STAT_SLOT_ID::MAIN:
  195. $this->main_stat = $stat;
  196. break;
  197. case RUNE_STAT_SLOT_ID::INNATE:
  198. $this->innate_stat = $stat;
  199. break;
  200. default:
  201. array_push($this->substats, $stat);
  202. break;
  203. }
  204. }
  205. $this->flag_stats = true;
  206. }
  207. /**
  208. * Loads the unit into the entity.
  209. *
  210. * Must be called only once before trying to get the unit. Sets the flag
  211. * {@link Rune:$flag_unit} to true.
  212. */
  213. private function load_unit(){
  214. $statement = get_context()->get_db()->prepare("
  215. SELECT unit
  216. FROM unit_rune
  217. WHERE
  218. rune = :rune AND
  219. rta = :mode;
  220. ");
  221. $statement->bindValue(':rune', $this->id, SQLITE3_TEXT);
  222. $statement->bindValue(':mode', get_context()->get_game_mode(), SQLITE3_TEXT);
  223. $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
  224. if ($r){
  225. $this->unit = new Unit($r["unit"]);
  226. }
  227. $this->flag_unit = true;
  228. }
  229. /**
  230. * Retrieves the owner's player identifier.
  231. *
  232. * @return int Player ID.
  233. */
  234. public function get_player(){
  235. return $this->player;
  236. }
  237. /**
  238. * Retrieves the rune identifier.
  239. *
  240. * @return int Rune ID.
  241. */
  242. public function get_id(){
  243. return $this->id;
  244. }
  245. /**
  246. * Retrieves the rune set.
  247. *
  248. * @return Rune_Set Set of the rune.
  249. */
  250. public function get_set(){
  251. return $this->type;
  252. }
  253. /**
  254. * Retrieves the rune slot.
  255. *
  256. * @return int Rune slot (1-6).
  257. */
  258. public function get_slot(){
  259. return $this->slot;
  260. }
  261. /**
  262. * Retrieves the rune stars (the grade).
  263. *
  264. * @return int Rune stars (1-6).
  265. */
  266. public function get_stars(){
  267. return $this->stars;
  268. }
  269. /**
  270. * Checks if it's an ancient rune.
  271. *
  272. * @return bool True for ancient, false for normal.
  273. */
  274. public function is_ancient(){
  275. return $this->ancient;
  276. }
  277. /**
  278. * Retrieves the rune level
  279. *
  280. * @return int Rune level (0-15).
  281. */
  282. public function get_level(){
  283. return $this->level;
  284. }
  285. /**
  286. * Retrieves the rune quality identifier.
  287. *
  288. * @see QUALITY_ID
  289. *
  290. * @return int Quality identifier.
  291. */
  292. public function get_quality(){
  293. return $this->quality;
  294. }
  295. /**
  296. * Retrieves the rune original quality identifier.
  297. *
  298. * @see QUALITY_ID
  299. *
  300. * @return int Original quality identifier.
  301. */
  302. public function get_original_quality(){
  303. return $this->original_quality;
  304. }
  305. /**
  306. * Retrieves the rune quality name.
  307. *
  308. * @return string Quality name.
  309. */
  310. public function get_quality_name(){
  311. return $this->quality_name;
  312. }
  313. /**
  314. * Retrieves the rune original quality name.
  315. *
  316. * @return string Original quality name.
  317. */
  318. public function get_original_quality_name(){
  319. return $this->original_quality_name;
  320. }
  321. /**
  322. * Retrieves the rune value.
  323. *
  324. * @return int Rune value in mana stones.
  325. */
  326. public function get_value(){
  327. return $this->value;
  328. }
  329. /**
  330. * Retrieves the rune efficiency.
  331. *
  332. * @return int Rune efficiency (0-100)
  333. */
  334. public function get_efficiency(){
  335. return $this->efficiency;
  336. }
  337. /**
  338. * Retrieves the rune efficiency.
  339. *
  340. * @return int Rune efficiency (0-100)
  341. */
  342. public function get_max_efficiency(){
  343. return $this->max_efficiency;
  344. }
  345. /**
  346. * Checks if the rune is locked.
  347. *
  348. * @return bool True if locked, false otherwise.
  349. */
  350. public function is_locked(){
  351. return $this->locked;
  352. }
  353. /**
  354. * Retrieves the rune main_stat.
  355. *
  356. * @return Rune_Stat The main stat.
  357. */
  358. public function get_main_stat(){
  359. if (! $this->flag_stats){
  360. $this->load_stats();
  361. }
  362. return $this->main_stat;
  363. }
  364. /**
  365. * Retrieves the rune innate stat.
  366. *
  367. * @return Rune_Stat Innate stat, null if it hasn't.
  368. */
  369. public function get_innate_stat(){
  370. if (! $this->flag_stats){
  371. $this->load_stats();
  372. }
  373. return $this->innate_stat;
  374. }
  375. /**
  376. * Retrieves as many substats as the rune has, sorted.
  377. *
  378. * @return Rune_Stat[] Sorted array of the rune substats.
  379. */
  380. public function get_substats(){
  381. if (! $this->flag_stats){
  382. $this->load_stats();
  383. }
  384. return $this->substats;
  385. }
  386. /**
  387. * Retrieves all the rune stats, including main, innate and substats, in an unsorted array.
  388. *
  389. * @return Rune_Stat Every rune stat.
  390. */
  391. public function get_stats(){
  392. if (! $this->flag_stats){
  393. $this->load_stats();
  394. }
  395. return $this->stats;
  396. }
  397. /**
  398. * Retrieves the unit that has equipped the rune in the current game mode.
  399. *
  400. * @return Unit Unit that has the rune.
  401. */
  402. public function get_unit(){
  403. if (! $this->flag_unit){
  404. $this->load_unit();
  405. }
  406. return $this->unit;
  407. }
  408. /**
  409. * Gets the value of the main stat at an arbitrary level.
  410. *
  411. * @param int $level Desired level.
  412. * @return int Value of the main stat at the selected level.
  413. */
  414. public function get_main_stat_at_level($level){
  415. $level = intval($level);
  416. if ($level < 0 || $level > 15){
  417. return 0;
  418. }
  419. switch ($this->main_stat->get_stat()){
  420. case RUNE_STAT_ID::HP:
  421. return RUNE_STAT_VALUES::HP[$this->stars][$level];
  422. case RUNE_STAT_ID::HP_P:
  423. return RUNE_STAT_VALUES::HP_P[$this->stars][$level];
  424. case RUNE_STAT_ID::ATK:
  425. return RUNE_STAT_VALUES::ATK[$this->stars][$level];
  426. case RUNE_STAT_ID::ATK_P:
  427. return RUNE_STAT_VALUES::ATK_P[$this->stars][$level];
  428. case RUNE_STAT_ID::DEF:
  429. return RUNE_STAT_VALUES::DEF[$this->stars][$level];
  430. case RUNE_STAT_ID::DEF_P:
  431. return RUNE_STAT_VALUES::DEF_P[$this->stars][$level];
  432. case RUNE_STAT_ID::SPD:
  433. return RUNE_STAT_VALUES::SPD[$this->stars][$level];
  434. case RUNE_STAT_ID::CRR:
  435. return RUNE_STAT_VALUES::CRR[$this->stars][$level];
  436. case RUNE_STAT_ID::CRD:
  437. return RUNE_STAT_VALUES::CRD[$this->stars][$level];
  438. case RUNE_STAT_ID::RES:
  439. return RUNE_STAT_VALUES::RES[$this->stars][$level];
  440. case RUNE_STAT_ID::ACC:
  441. return RUNE_STAT_VALUES::ACC[$this->stars][$level];
  442. default:
  443. return 0;
  444. }
  445. }
  446. /**
  447. * Gets a stat name frm the mappings.
  448. *
  449. * @param int $q Quality id.
  450. * @return string Quality (Uppercase)
  451. */
  452. private function map_quality_name($q){
  453. switch ($q){
  454. case QUALITY_ID::NORMAL:
  455. return "NORMAL";
  456. case QUALITY_ID::MAGIC:
  457. return "MAGIC";
  458. case QUALITY_ID::RARE:
  459. return "RARE";
  460. case QUALITY_ID::HERO:
  461. return "HERO";
  462. case QUALITY_ID::LEGEND:
  463. return "LEGEND";
  464. default:
  465. return "";
  466. }
  467. }
  468. /**
  469. * Calcuates the efficiency of the rune.
  470. *
  471. * @return float Efficiency
  472. */
  473. private function calculate_efficiency(){
  474. $eff = [0.0, 0.0, 0.0, 0.0, 0.0];
  475. $query = "
  476. SELECT
  477. min,
  478. max
  479. FROM
  480. rune_roll_type,
  481. rune_stat_roll
  482. WHERE
  483. rune_roll_type.id = rune_stat_roll.type AND
  484. rune_roll_type.ancient = :ancient AND
  485. rune_roll_type.initial = :initial AND
  486. rune_roll_type.upgrade = :upgrade AND
  487. rune_stat_roll.stars = :stars AND
  488. rune_stat_roll.stat = :stat
  489. ";
  490. // Fixed stat
  491. if ($this->innate_stat != null && $this->innate_stat->get_value() > 0){
  492. $value = $this->innate_stat->get_value();
  493. $statement = get_context()->get_db()->prepare($query);
  494. $statement->bindValue(':ancient', $this->ancient, SQLITE3_TEXT);
  495. $statement->bindValue(':initial', 1, SQLITE3_TEXT);
  496. $statement->bindValue(':upgrade', 0, SQLITE3_TEXT);
  497. $statement->bindValue(':stars', $this->stars, SQLITE3_TEXT);
  498. $statement->bindValue(':stat', $this->innate_stat->stat, SQLITE3_TEXT);
  499. $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
  500. if ($r){
  501. $min_initial = 0;//$r["min"];
  502. $max_initial = $r["max"];
  503. $eff[0] = ($value - $min_initial) / (9 * ($max_initial - $min_initial));
  504. }
  505. }
  506. for ($i = 1; $i <= 4; $i ++){
  507. if (sizeof($this->stats) > $i && $this->stats[$i] != null && $this->stats[$i]->get_value() > 0){
  508. $value = $this->stats[$i]->get_value();
  509. $value = $this->stats[$i]->get_value();
  510. $statement = get_context()->get_db()->prepare($query);
  511. $statement->bindValue(':ancient', $this->ancient, SQLITE3_TEXT);
  512. $statement->bindValue(':initial', 1, SQLITE3_TEXT);
  513. $statement->bindValue(':upgrade', 0, SQLITE3_TEXT);
  514. $statement->bindValue(':stars', $this->stars, SQLITE3_TEXT);
  515. $statement->bindValue(':stat', $this->stats[$i]->stat, SQLITE3_TEXT);
  516. $r_initial = $statement->execute()->fetchArray(SQLITE3_ASSOC);
  517. $statement = get_context()->get_db()->prepare($query);
  518. $statement->bindValue(':ancient', $this->ancient, SQLITE3_TEXT);
  519. $statement->bindValue(':initial', 0, SQLITE3_TEXT);
  520. $statement->bindValue(':upgrade', 1, SQLITE3_TEXT);
  521. $statement->bindValue(':stars', $this->stars, SQLITE3_TEXT);
  522. $statement->bindValue(':stat', $this->stats[$i]->stat, SQLITE3_TEXT);
  523. $r_upgrade = $statement->execute()->fetchArray(SQLITE3_ASSOC);
  524. if ($r_initial && $r_upgrade){
  525. $min_initial = 0;//$r_initial["min"];
  526. $max_initial = $r_initial["max"];
  527. $min_upgrade = 0;//$r_upgrade["min"];
  528. $max_upgrade = $r_upgrade["max"];
  529. $eff[$i] = ((5 * $value) - ( 4 * $min_upgrade + $min_initial)) / ( 9 * ($max_initial - $min_initial + (4 * ($max_upgrade + $min_upgrade))));
  530. }
  531. }
  532. }
  533. $efficiency = 0.0;
  534. for ($i = 0; $i <= 4; $i ++){
  535. $efficiency += $eff[$i];
  536. }
  537. $efficiency *= 100;
  538. return $efficiency;
  539. }
  540. /**
  541. * Calcuates the maximum efficiency of the rune.
  542. *
  543. * @return float Max efficiency
  544. */
  545. private function calculate_maximum_efficiency(){
  546. $max_efficiency = $this->efficiency;
  547. if ($this->level < 12){
  548. $max_efficiency += (1/9);
  549. }
  550. if ($this->level < 9){
  551. $max_efficiency += (1/9);
  552. }
  553. if ($this->level < 6){
  554. $max_efficiency += (1/9);
  555. }
  556. if ($this->level < 3){
  557. $max_efficiency += (1/9);
  558. }
  559. return $max_efficiency;
  560. }
  561. }