Run.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. <?php
  2. /**
  3. * Saved run 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 . "Unit.php");
  13. require_once(PATH::ENTITY . "Monster.php");
  14. require_once(PATH::ENTITY . "Rune.php");
  15. require_once(PATH::ENTITY . "Enchantment.php");
  16. require_once(PATH::ENTITY . "Item.php");
  17. require_once(PATH::ENTITY . "Area.php");
  18. require_once(PATH::ENTITY . "Rune_Set.php");
  19. /**
  20. * A run.
  21. *
  22. * Represent a saved run in a playable area.
  23. *
  24. * @category Entity
  25. * @todo Consider artifact drops.
  26. */
  27. class Run extends Entity{
  28. /**
  29. * @var int Owner's player identifier.
  30. */
  31. private $player;
  32. /**
  33. * @var int Run identifier.
  34. */
  35. private $id;
  36. /**
  37. * @var DateTime Run start times.
  38. */
  39. private $start_time;
  40. /**
  41. * @var Area Area.
  42. */
  43. private $area;
  44. /**
  45. * @var int Stage.
  46. */
  47. private $stage;
  48. /**
  49. * @var int Difficulty (only scenario and dimension hole)
  50. */
  51. private $difficulty;
  52. /**
  53. * @var bool Won or lost run.
  54. */
  55. private $win;
  56. /**
  57. * @var int Clear time, milliseconds.
  58. */
  59. private $time;
  60. /**
  61. * @var bool Indicates if a frind/mentor helped.
  62. */
  63. private $helper;
  64. /**
  65. * @var int Score in battles that are rated (WB, rift dungeons...).
  66. */
  67. private $score;
  68. /**
  69. * @var String Rank in battles that are rated (WB, rift dungeons...).
  70. */
  71. private $rank;
  72. /**
  73. * @var bool Internal flag to check if the run parti has been loaded.
  74. */
  75. private $flag_party = false;
  76. /**
  77. * @var Unit[]|Monster[] Units or monsters used.
  78. * If the unit is still owned, it will be a instance of Unit.
  79. * If not, it will be a instance of monster.
  80. */
  81. private $party = [];
  82. /**
  83. * @var int ID of the leader unit or monster.
  84. */
  85. private $leader;
  86. /**
  87. * @var int[] List of IDs of the frontline units or monsters.
  88. */
  89. private $frontline = [];
  90. /**
  91. * @var bool Internal flag to check if run rewards have been loaded.
  92. */
  93. private $flag_reward = false;
  94. /**
  95. * @var array List of run rewards.
  96. */
  97. private $reward = [
  98. "mana" => 0,
  99. "energy" => 0,
  100. "crystal" => 0,
  101. "honor_points" => 0,
  102. "guild_points" => 0,
  103. "item" => [],
  104. "monster" => null,
  105. "sd" => null,
  106. "monster_piece" => [],
  107. "shapeshifting" => 0,
  108. "rune" => [],
  109. "enchantment" => [],
  110. "artifact" => []
  111. ];
  112. /**
  113. * Constructor.
  114. *
  115. * Searches the database and retrieves the information about the
  116. * run, populating it and it's items.
  117. *
  118. * @param int $id Run identifier.
  119. */
  120. public function __construct($id){
  121. $statement = get_context()->get_db()->prepare("
  122. SELECT
  123. id,
  124. player,
  125. dtime,
  126. area_type,
  127. area,
  128. stage,
  129. difficulty,
  130. win,
  131. time,
  132. mana,
  133. energy,
  134. crystal,
  135. honor_points,
  136. guild_points,
  137. helper,
  138. score,
  139. rank
  140. FROM run
  141. WHERE id = :id;
  142. ");
  143. $statement->bindValue(':id', $id, SQLITE3_TEXT);
  144. $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
  145. if ($r){
  146. $this->id = $r["id"];
  147. $this->player = $r["player"];
  148. $this->start_time = new Datetime();
  149. $this->start_time->setTimestamp($r["dtime"]);
  150. $this->area = new Area($r["area"], $r["area_type"]);
  151. $this->stage = $r["stage"];
  152. $this->difficulty = $r["difficulty"];
  153. $this->win = filter_var($r["win"], FILTER_VALIDATE_BOOLEAN);
  154. $this->time = $r["time"];
  155. $this->reward["mana"] = $r["mana"];
  156. $this->reward["energy"] = $r["energy"];
  157. $this->reward["crystal"] = $r["crystal"];
  158. $this->reward["honor_points"] = $r["honor_points"];
  159. $this->reward["guild_points"] = $r["guild_points"];
  160. $this->helper = filter_var($r["helper"], FILTER_VALIDATE_BOOLEAN);
  161. $this->score = $r["score"];
  162. $this->rank = $r["rank"];
  163. }
  164. }
  165. private function load_party(){
  166. $statement = get_context()->get_db()->prepare("
  167. SELECT
  168. unit,
  169. monster,
  170. (SELECT count(id) FROM unit WHERE unit.id = run_party.unit) AS owned,
  171. leader,
  172. front
  173. FROM run_party
  174. WHERE run = :run
  175. ORDER BY
  176. front DESC,
  177. leader DESC;
  178. ");
  179. $statement->bindValue(':run', $this->id, SQLITE3_TEXT);
  180. $q = $statement->execute();
  181. while ($r = $q->fetchArray(SQLITE3_ASSOC)){
  182. if ($r["owned"] > 0){
  183. array_push($this->party, new Unit($r["unit"], false));
  184. }
  185. else{
  186. array_push($this->party, new Monster($r["monster"], false));
  187. }
  188. if ($r["leader"] == 1){
  189. $this->leader = $r["unit"];
  190. }
  191. if ($r["front"] == 1){
  192. array_push($this->frontline, $r["unit"]);
  193. }
  194. }
  195. $this->flag_party = true;
  196. }
  197. private function load_reward(){
  198. $statement = get_context()->get_db()->prepare("
  199. SELECT
  200. item,
  201. amount
  202. FROM run_drop_item
  203. WHERE run = :run;
  204. ");
  205. $statement->bindValue(':run', $this->id, SQLITE3_TEXT);
  206. $q = $statement->execute();
  207. while ($r = $q->fetchArray(SQLITE3_ASSOC)){
  208. $item = [
  209. "inventory" => new Inventory($r["item"]),
  210. "amount" => $r["amount"]
  211. ];
  212. array_push($this->reward["item"], $item);
  213. }
  214. $statement = get_context()->get_db()->prepare("
  215. SELECT unit AS monster
  216. FROM run_drop_unit
  217. WHERE run = :run;
  218. ");
  219. $statement->bindValue(':run', $this->id, SQLITE3_TEXT);
  220. $q = $statement->execute();
  221. while ($r = $q->fetchArray(SQLITE3_ASSOC)){
  222. $this->reward["monster"] = new Monster($r["monster"]);
  223. }
  224. $statement = get_context()->get_db()->prepare("
  225. SELECT unit AS monster
  226. FROM run_drop_sd
  227. WHERE run = :run;
  228. ");
  229. $statement->bindValue(':run', $this->id, SQLITE3_TEXT);
  230. $q = $statement->execute();
  231. while ($r = $q->fetchArray(SQLITE3_ASSOC)){
  232. $this->reward["sd"] = new Monster($r["monster"]);
  233. }
  234. $statement = get_context()->get_db()->prepare("
  235. SELECT
  236. unit AS monster,
  237. amount
  238. FROM run_drop_unit_pieces
  239. WHERE run = :run;
  240. ");
  241. $statement->bindValue(':run', $this->id, SQLITE3_TEXT);
  242. $q = $statement->execute();
  243. while ($r = $q->fetchArray(SQLITE3_ASSOC)){
  244. $i = [
  245. "monster" => new Monster($r["monster"]),
  246. "amount" => $r["amount"]
  247. ];
  248. array_push($this->reward["monster_piece"], $i);
  249. }
  250. $statement = get_context()->get_db()->prepare("
  251. SELECT amount
  252. FROM run_drop_shapeshifting
  253. WHERE run = :run;
  254. ");
  255. $statement->bindValue(':run', $this->id, SQLITE3_TEXT);
  256. $q = $statement->execute();
  257. $r = $q->fetchArray(SQLITE3_ASSOC);
  258. if ($r){
  259. $this->reward["shapeshifting"] = $r["amount"];
  260. }
  261. $statement = get_context()->get_db()->prepare("
  262. SELECT id
  263. FROM run_drop_rune
  264. WHERE run = :run;
  265. ");
  266. $statement->bindValue(':run', $this->id, SQLITE3_TEXT);
  267. $q = $statement->execute();
  268. while ($r = $q->fetchArray(SQLITE3_ASSOC)){
  269. $rune = new Rune($r["id"]);
  270. array_push($this->reward["rune"], $rune);
  271. }
  272. $statement = get_context()->get_db()->prepare("
  273. SELECT id
  274. FROM run_drop_artifact
  275. WHERE run = :run;
  276. ");
  277. $statement->bindValue(':run', $this->id, SQLITE3_TEXT);
  278. $q = $statement->execute();
  279. while ($r = $q->fetchArray(SQLITE3_ASSOC)){
  280. $artifact = new Artifact($r["id"]);
  281. array_push($this->reward["artifact"], $artifact);
  282. }
  283. $statement = get_context()->get_db()->prepare("
  284. SELECT id
  285. FROM run_drop_enchantment
  286. WHERE run = :run;
  287. ");
  288. $statement->bindValue(':run', $this->id, SQLITE3_TEXT);
  289. $q = $statement->execute();
  290. while ($r = $q->fetchArray(SQLITE3_ASSOC)){
  291. $enchantment = new Enchantment($r["id"]);
  292. array_push($this->reward[enchantment], $enchantment);
  293. }
  294. $this->flag_reward = true;
  295. }
  296. /**
  297. * Retrieves the player identifier.
  298. *
  299. * @return int Player ID.
  300. */
  301. public function get_player(){
  302. return $this->player;
  303. }
  304. /**
  305. * Retrieves the run identifier.
  306. *
  307. * @return int Run ID.
  308. */
  309. public function get_id(){
  310. return $this->id;
  311. }
  312. /**
  313. * Gets the time of the run start.
  314. *
  315. * If $format is supplied, a string in the desired format will be returned. If not, the raw
  316. * DateTime object will e returned.
  317. *
  318. * @param string $format A date format (optional).
  319. * @return DateTime | string The raw date, or a formatted version.
  320. */
  321. public function get_start_time($format = null){
  322. if (null == $format){
  323. return $this->start_time;
  324. }
  325. else{
  326. return $this->start_time->format($format);
  327. }
  328. }
  329. /**
  330. * Retrieves the area of the run.
  331. *
  332. * @return Area Run area.
  333. */
  334. public function get_area(){
  335. return $this->area;
  336. }
  337. /**
  338. * Retrieves the stage of the run, if any.
  339. *
  340. * @return int Stage number, null if none.
  341. */
  342. public function get_stage(){
  343. return $this->stage;
  344. }
  345. /**
  346. * Retrieves the difficulty of the run, if any.
  347. *
  348. * @see DIFFICULTY_ID
  349. * @return int Difficulty ID, null if none.
  350. */
  351. public function get_difficulty(){
  352. return $this->difficulty;
  353. }
  354. /**
  355. * Checks if the run was won.
  356. *
  357. * @return bool True if voctory, false otherwise.
  358. */
  359. public function is_win(){
  360. return $this->win;
  361. }
  362. /**
  363. * Retrieves the duration of the run in millisecondes.
  364. *
  365. * @return int Run time.
  366. */
  367. public function get_time(){
  368. return $this->time;
  369. }
  370. /**
  371. * Check if a frind or mentor representative's help was used.
  372. *
  373. * @return bool True if helper included, false otherwise.
  374. */
  375. public function had_help(){
  376. return $this->helper;
  377. }
  378. /**
  379. * Retrieves the score of the run.
  380. *
  381. * @return int Run score. Null if it's not a score based run.
  382. */
  383. public function get_score(){
  384. return $this->score;
  385. }
  386. /**
  387. * Retrieves the rank reached on the run.
  388. *
  389. * @return string Rank, in human readable form. Null if not a rank based run.
  390. */
  391. public function get_rank(){
  392. return $this->rank;
  393. }
  394. /**
  395. * Retrieves the party used in the run. If one of the units is not still owned, it will get
  396. * the base monster instead.
  397. *
  398. * @return (Unit|Monster)[] Party units or monsters.
  399. */
  400. public function get_party(){
  401. if (! $this->flag_party){
  402. $this->load_party();
  403. }
  404. return $this->party;
  405. }
  406. /**
  407. * Retrieves the party leader identifier. If the leader unit is not still owned, it will get
  408. * the base monster identifierinstead.
  409. *
  410. * @return int Leader unit or monster ID.
  411. */
  412. public function get_leader(){
  413. if (! $this->flag_party){
  414. $this->load_party();
  415. }
  416. return $this->leader;
  417. }
  418. /**
  419. * Retrieves the identifiers of the party members in the frontline. If one of the units is not
  420. * still owned, it will get the base monster instead.
  421. *
  422. * @return int Unit or Monster identifiers.
  423. */
  424. public function get_frontline(){
  425. if (! $this->flag_party){
  426. $this->load_party();
  427. }
  428. return $this->frontline;
  429. }
  430. /**
  431. * Retrieves the list of rewards from the run reward.
  432. *
  433. * Here is an example (note that, in most cases, only a few items will be populated for a run):
  434. * <code>
  435. * [
  436. * "mana" => 2365, // Dropped mana, 0 if none
  437. * "energy" => 1, // Dropped energy, 0 if none.
  438. * "crystal" => 0, // Dropped crystals, 0 if none.
  439. * "honor_points" => 3, // Dropped honor points, 0 if none.
  440. * "guild_points" => 8, // Dropped guild points, 0 if none.
  441. * "item" => [ // Items dropped, empty if none.
  442. * [ // One item.
  443. * "inventory" => (Inventory), // Inventory ID.
  444. * "amount => 4 // Dropped quantity.
  445. * ],
  446. * [ // One item.
  447. * "inventory" => (Inventory), // Inventory ID.
  448. * "amount => 3 // Dropped quantity.
  449. * ],
  450. * ],
  451. * "monster" => (Monster), // Dropped monster instance, null if none.
  452. * "sd" => (Monster), // Opened Secret Dungeon monster instance, null if none.
  453. * "monster_piece" => [ // Dropped monster pieces.
  454. * "monster" => (Monster), // Monster entity
  455. * "amount" => 4 // Quantity
  456. * ],
  457. * "shapeshifting" => 0, // Dropped transmogification stones, 0 if none.
  458. * "rune" => [ // Dropped runes, empty if none.
  459. * (Rune), // Rune instance.
  460. * (Rune), // Rune instance.
  461. * (Rune) // Rune instance.
  462. * ],
  463. * "enchantment" => [ // Dropped enchantments, empty if none.
  464. * (Enchantment), // Enchantment instance.
  465. * (Enchantment) // Enchantment instance.
  466. * ],
  467. * "artifact" => [ // Dropped artifacts, empty if none.
  468. * (Artifact), // Enchantment instance.
  469. * (Artifact), // Artifact instance.
  470. * ]
  471. * </code>
  472. *
  473. * @return mixed[]
  474. */
  475. public function get_rewards(){
  476. if (! $this->flag_reward){
  477. $this->load_reward();
  478. }
  479. return $this->reward;
  480. }
  481. }