Run.php 15 KB

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