Monster.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  1. <?php
  2. /**
  3. * Base monster entity file.
  4. *
  5. * Creates the entity and makes it available.
  6. *
  7. * @category Entity
  8. */
  9. /**
  10. * Require dependent entities if not present.
  11. */
  12. require_once(PATH::ENTITY . "Entity.php");
  13. require_once(PATH::ENTITY . "Skill.php");
  14. require_once(PATH::ENTITY . "Leader_Skill.php");
  15. require_once(PATH::ENTITY . "Source.php");
  16. require_once(PATH::ENTITY . "Inventory.php");
  17. require_once(PATH::ENTITY . "Monster_Transformation.php");
  18. /**
  19. * A monster.
  20. *
  21. * Represents an object from the table 'monster'.
  22. *
  23. * @category Entity
  24. */
  25. class Monster extends Entity{
  26. private $id;
  27. private $family;
  28. private $name;
  29. private $element;
  30. private $element_name;
  31. private $archetype;
  32. private $archetype_name;
  33. private $base_stars;
  34. private $natural_stars;
  35. private $obtainable;
  36. private $can_awaken;
  37. private $awaken_bonus;
  38. private $skill_ups_to_max;
  39. private $stats = array(
  40. "hp" => 0,
  41. "atk" => 0,
  42. "def" => 0,
  43. "spd" => 0,
  44. "crr" => 0,
  45. "crd" => 0,
  46. "acc" => 0,
  47. "res" => 0,
  48. );
  49. private $raw_stats = array(
  50. "hp" => 0,
  51. "atk" => 0,
  52. "def" => 0,
  53. "spd" => 0,
  54. "crr" => 0,
  55. "crd" => 0,
  56. "acc" => 0,
  57. "res" => 0,
  58. );
  59. private $max_level_statss = array(
  60. "hp" => 0,
  61. "atk" => 0,
  62. "def" => 0,
  63. "spd" => 0,
  64. "crr" => 0,
  65. "crd" => 0,
  66. "acc" => 0,
  67. "res" => 0,
  68. );
  69. private $awakens_from;
  70. private $awakens_to;
  71. private $fusion_food;
  72. private $homunculus;
  73. private $craft_cost;
  74. private $flag_skills = false;
  75. private $leader_skill;
  76. private $leader_skill_id;
  77. private $skill = [];
  78. private $flag_essences = false;
  79. private $essences = [];
  80. private $flag_sources = false;
  81. private $sources = [];
  82. private $title;
  83. private $flag_transformation = false;
  84. private $transformation;
  85. /**
  86. * Constructor.
  87. *
  88. * Searches the database and retrieves the information about the
  89. * monster, populating it and it's items.
  90. *
  91. * @param int $id Monster identifier.
  92. */
  93. public function __construct($id){
  94. $this->id = $id;
  95. $statement = get_context()->get_db()->prepare("
  96. SELECT
  97. id,
  98. family,
  99. name,
  100. element,
  101. archetype,
  102. base_stars,
  103. natural_stars,
  104. obtainable,
  105. can_awaken,
  106. awaken_bonus,
  107. skill_ups_to_max,
  108. leader_skill,
  109. hp,
  110. attack,
  111. defense,
  112. speed,
  113. crit_rate,
  114. crit_damage,
  115. resistance,
  116. accuracy,
  117. raw_hp,
  118. raw_attack,
  119. raw_defense,
  120. max_lvl_hp,
  121. max_lvl_attack,
  122. max_lvl_defense,
  123. awakens_from,
  124. awakens_to,
  125. fusion_food,
  126. homunculus,
  127. craft_cost
  128. FROM monster
  129. WHERE id = :id;
  130. ");
  131. $statement->bindValue(':id', $id, SQLITE3_TEXT);
  132. $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
  133. if ($r){
  134. $this->family = $r["family"];
  135. $this->name = HTML::e($r["name"]);
  136. $this->element = $r["element"];
  137. switch($this->element){
  138. case ELEMENT_ID::WATER:
  139. $this->element_name = "Water";
  140. break;
  141. case ELEMENT_ID::FIRE:
  142. $this->element_name = "Fire";
  143. break;
  144. case ELEMENT_ID::WIND:
  145. $this->element_name = "Wind";
  146. break;
  147. case ELEMENT_ID::LIGHT:
  148. $this->element_name = "Light";
  149. break;
  150. case ELEMENT_ID::DARK:
  151. $this->element_name = "Dark";
  152. break;
  153. }
  154. $this->archetype = $r["archetype"];
  155. switch($this->archetype){
  156. case ARCHETYPE_ID::ATTACK:
  157. $this->archetype_name = "Attack";
  158. break;
  159. case ARCHETYPE_ID::DEFENSE:
  160. $this->archetype_name = "Defense";
  161. break;
  162. case ARCHETYPE_ID::HP:
  163. $this->archetype_name = "HP";
  164. break;
  165. case ARCHETYPE_ID::SUPPORT:
  166. $this->archetype_name = "Support";
  167. break;
  168. case ARCHETYPE_ID::MATERIAL:
  169. $this->archetype_name = "Material";
  170. break;
  171. }
  172. $this->base_stars = $r["base_stars"];
  173. $this->natural_stars = $r["natural_stars"];
  174. $this->obtainable = $r["obtainable"];
  175. if ($r["can_awaken"] == 1){
  176. $this->can_awaken = true;
  177. }
  178. else{
  179. $this->can_awaken = false;
  180. }
  181. $this->awaken_bonus = HTML::e($r["awaken_bonus"]);
  182. $this->skill_ups_to_max = $r["skill_ups_to_max"];
  183. if (strlen($r["leader_skill"]) > 0){
  184. $this->leader_skill_id = $r["leader_skill"];
  185. }
  186. $this->stats["hp"] = $r["hp"];
  187. $this->stats["atk"] = $r["attack"];
  188. $this->stats["def"] = $r["defense"];
  189. $this->stats["spd"] = $r["speed"];
  190. $this->stats["crr"] = $r["crit_rate"];
  191. $this->stats["crd"] = $r["crit_damage"];
  192. $this->stats["res"] = $r["resistance"];
  193. $this->stats["acc"] = $r["accuracy"];
  194. $this->min_stats["hp"] = $r["raw_hp"];
  195. $this->min_stats["atk"] = $r["raw_attack"];
  196. $this->min_stats["def"] = $r["raw_defense"];
  197. $this->min_stats["spd"] = $r["speed"];
  198. $this->min_stats["crr"] = $r["crit_rate"];
  199. $this->min_stats["crd"] = $r["crit_damage"];
  200. $this->min_stats["res"] = $r["resistance"];
  201. $this->min_stats["acc"] = $r["accuracy"];
  202. $this->max_stats["hp"] = $r["max_lvl_hp"];
  203. $this->max_stats["atk"] = $r["max_lvl_attack"];
  204. $this->max_stats["def"] = $r["max_lvl_defense"];
  205. $this->max_stats["spd"] = $r["speed"];
  206. $this->max_stats["crr"] = $r["crit_rate"];
  207. $this->max_stats["crd"] = $r["crit_damage"];
  208. $this->max_stats["res"] = $r["resistance"];
  209. $this->max_stats["acc"] = $r["accuracy"];
  210. $this->awakens_from = $r["awakens_from"];
  211. $this->awakens_to = $r["awakens_to"];
  212. if ($r["fusion_food"] == 1){
  213. $this->fusion_food = true;
  214. }
  215. else{
  216. $this->fusion_food = false;
  217. }
  218. if ($r["homunculus"] == 1){
  219. $this->homunculus = true;
  220. }
  221. else{
  222. $this->homunculus = false;
  223. }
  224. $this->craft_cost = $r["craft_cost"];
  225. }
  226. // Guess monster name
  227. if ($this->awakens_from == "" && $this->awakens_to == ""){
  228. // No to, no from. Silver monster.
  229. if ($this->base_stars >= 4){
  230. // SFV Collab event monsters, always awakened.
  231. $this->title = $this->name;
  232. }
  233. elseif($this->archetype == ARCHETYPE_ID::MATERIAL && $this->element == ELEMENT_ID::LIGHT){
  234. // Rainbowmon, always awakened
  235. $this->title = $this->name;
  236. }
  237. elseif($this->archetype == ARCHETYPE_ID::MATERIAL && $this->element == ELEMENT_ID::DARK){
  238. // Devilmon, always unawakened, but dont include element
  239. $this->title = $this->name;
  240. }
  241. else{
  242. // Unawakeable monster
  243. $this->title = $this->element_name . " " . $this->name;
  244. }
  245. }
  246. // Awakened
  247. elseif ($this->awakens_from != ""){
  248. $this->title = $this->name;
  249. }
  250. // Gold
  251. elseif (strlen($this->awakens_to) > 0){
  252. $this->title = $this->element_name . " " . $this->name;
  253. }
  254. }
  255. private function load_skills(){
  256. $statement = get_context()->get_db()->prepare("
  257. SELECT skill.id AS skill
  258. FROM
  259. skill,
  260. monster_skill
  261. WHERE
  262. skill.id = monster_skill.skill AND
  263. monster_skill.monster = :monster
  264. ORDER BY slot;
  265. ");
  266. $statement->bindValue(':monster', $this->id, SQLITE3_TEXT);
  267. $q = $statement->execute();
  268. while ($r = $q->fetchArray(SQLITE3_ASSOC)){
  269. array_push($this->skill, new Skill($r["skill"]));
  270. }
  271. if ($this->leader_skill_id != null){
  272. $this->leader_skill = new Leader_Skill($this->leader_skill_id);
  273. }
  274. $this->flag_skills = true;
  275. }
  276. private function load_sources(){
  277. $statement = get_context()->get_db()->prepare("
  278. SELECT source
  279. FROM monster_source
  280. WHERE monster = :monster;
  281. ");
  282. $statement->bindValue(':monster', $this->id, SQLITE3_TEXT);
  283. $q = $statement->execute();
  284. while ($r = $q->fetchArray(SQLITE3_ASSOC)){
  285. array_push($this->sources, new Source($r["source"]));
  286. }
  287. $this->flag_sources = true;
  288. }
  289. private function load_essences(){
  290. $statement = get_context()->get_db()->prepare("
  291. SELECT
  292. item,
  293. amount
  294. FROM monster_essence
  295. WHERE
  296. monster = :monster
  297. ORDER BY item;
  298. ");
  299. $statement->bindValue(':monster', $this->id, SQLITE3_TEXT);
  300. $q = $statement->execute();
  301. while ($r = $q->fetchArray(SQLITE3_ASSOC)){
  302. $e = [
  303. "item" => new Inventory($r["item"], INVENTORY_TYPE_ID::ESSENCES),
  304. "amount" => $r["amount"]
  305. ];
  306. array_push($this->essences, $e);
  307. }
  308. $this->flag_essences = true;
  309. }
  310. private function load_transformation(){
  311. $statement = get_context()->get_db()->prepare("
  312. SELECT id
  313. FROM monster_transformation
  314. WHERE monster = :monster;
  315. ");
  316. $statement->bindValue(':monster', $this->id, SQLITE3_TEXT);
  317. $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
  318. if ($r){
  319. $this->transformation = new Monster_Transformation($r["id"]);
  320. }
  321. $this->flag_transformation = true;
  322. }
  323. /**
  324. * Retrieves the monster identifier.
  325. *
  326. * @return string Monster ID
  327. */
  328. public function get_id(){
  329. return $this->id;
  330. }
  331. /**
  332. * Retrieves the monsters family identifier.
  333. *
  334. * @return string Family ID.
  335. */
  336. public function get_family(){
  337. return $this->family;
  338. }
  339. /**
  340. * Retrieves the monster name.
  341. *
  342. * @return string Monster name.
  343. */
  344. public function get_name(){
  345. return $this->name;
  346. }
  347. /**
  348. * Retrieves the monster's element.
  349. *
  350. * @see ELEMENT_ID
  351. *
  352. * @return int Element ID.
  353. */
  354. public function get_element(){
  355. return $this->element;
  356. }
  357. /**
  358. * Retrieves the monster's element name.
  359. *
  360. * @return string Element name.
  361. */
  362. public function get_element_name(){
  363. return $this->element_name;
  364. }
  365. /**
  366. * Retrieves the monster's archetype.
  367. *
  368. * @see ARCHETYPE_ID
  369. *
  370. * @return int Monster's archetype ID.
  371. */
  372. public function get_archetype(){
  373. return $this->archetype;
  374. }
  375. /**
  376. * Retrieves the monster's archetype name.
  377. *
  378. * @return string Archetype name.
  379. */
  380. public function get_archetype_name(){
  381. return $this->archetype_name;
  382. }
  383. /**
  384. * Retrieves the monster's base stars.
  385. * Base stars are the default stars of the monsters in it's current form. I.E awakened
  386. * monsters have always one more base stars than their unawakened forms, and second awaken
  387. * monster always have 6 stars.
  388. *
  389. * @return int Monster base stars (1-6).
  390. */
  391. public function get_base_stars(){
  392. return $this->base_stars;
  393. }
  394. /**
  395. * Retrieves the monster's natural stars.
  396. * Natural stars are the default stars of the monsters in it's unawakened form.
  397. *
  398. * @return int Monster natural stars (1-5).
  399. */
  400. public function get_natural_stars(){
  401. return $this->natural_stars;
  402. }
  403. /**
  404. * Checks if the monster is obtainable.
  405. * Non obtainable monster are usually enemies (boses, towers, pure units...)
  406. *
  407. * @return boolean True for obtainable monsters, false for unobtainable.
  408. */
  409. public function is_obtainable(){
  410. return $this->obtainable;
  411. }
  412. /**
  413. * Checks if the monster can be awakened.
  414. * It also includes monsters that can second awaken.
  415. *
  416. * @return boolean True if the monster can awaken, false otherwise.
  417. */
  418. public function can_awaken(){
  419. return $this->can_awaken;
  420. }
  421. /**
  422. * Retrieves the awakening bonus description.
  423. * Note that for second awakenings, the bonus always is described as "Secondary Awakening".
  424. * For units that can't awaken, it will return an empty string.
  425. *
  426. * @return string Awaken bonus.
  427. */
  428. public function get_awaken_bonus(){
  429. return $this->awaken_bonus;
  430. }
  431. /**
  432. * Retrieves the number of skill-ups needed to fully skill-up the monster.
  433. *
  434. * @return int Required skill-ups
  435. */
  436. public function get_skill_ups_to_max(){
  437. return $this->skill_ups_to_max;
  438. }
  439. /**
  440. * Retrieves the monster's leader skill.
  441. *
  442. * @return Leader_Skill The leader skill.
  443. */
  444. public function get_leader_skill(){
  445. if (! $this->flag_skills){
  446. $this->load_skills();
  447. }
  448. return $this->leader_skill;
  449. }
  450. /**
  451. * Retrieves the monster stats.
  452. * These stats are the ones for the monster in it's base grade, at max level.
  453. *
  454. * It's an associative array with the following keys:
  455. * atk, def, hp, spd, crr, crd, acc, res
  456. *
  457. * @see get_min_stats()
  458. * @see get_max_stats()
  459. *
  460. * @return int[] Monster stats.
  461. */
  462. public function get_stats(){
  463. return $this->stats;
  464. }
  465. /**
  466. * Retrieves the monster stats.
  467. * These stats are the ones for the monster in it's base grade, at level 1.
  468. *
  469. * It's an associative array with the following keys:
  470. * atk, def, hp, spd, crr, crd, acc, res
  471. *
  472. * @see get_stats()
  473. * @see get_max_stats()
  474. *
  475. * @return int[] Monster stats.
  476. */
  477. public function get_min_stats(){
  478. return $this->stats();
  479. }
  480. /**
  481. * Retrieves the monster stats.
  482. * These stats are the ones for the monster with 6 stars at level 40.
  483. *
  484. * It's an associative array with the following keys:
  485. * atk, def, hp, spd, crr, crd, acc, res
  486. *
  487. * @return int[] Monster stats.
  488. *
  489. * @see get_stats()
  490. * @see get_min_stats()
  491. */
  492. public function get_max_stats(){
  493. return $this->stats();
  494. }
  495. /**
  496. * Retrieves the identifier of the monster who awakens to this one.
  497. *
  498. * @return string Unawakened monster identifier, null for unawakened monsters.
  499. */
  500. public function get_awakens_from(){
  501. return $this->awakens_from;
  502. }
  503. /**
  504. * Retrieves the identifier of the monster this one awakens to.
  505. *
  506. * @return string Next awaken monster identifier, null for fully awakened monsters.
  507. */
  508. public function get_awakens_to(){
  509. return $this->awakens_to;
  510. }
  511. /**
  512. * Checks if skill-ups can be created by fussion.
  513. *
  514. * @return boolean True if skill-us can be fused, false otherwise.
  515. */
  516. public function has_fusion_food(){
  517. return $this->fusion_food;
  518. }
  519. /**
  520. * Checks if the monster is an Homunculus.
  521. *
  522. * @return boolean True if Homunculus, false otherwise.
  523. */
  524. public function is_homunculus(){
  525. return $this->homunculus;
  526. }
  527. /**
  528. * // TODO: Unimplemented.
  529. * Retrieves $craft_cost
  530. *
  531. * @return number
  532. */
  533. public function get_craft_cost(){
  534. return $this->craft_cost;
  535. }
  536. /**
  537. * Retrieves the monster skills
  538. *
  539. * @return Skill[] Monster skills.
  540. */
  541. public function get_skills(){
  542. if (! $this->flag_skills){
  543. $this->load_skills();
  544. }
  545. return $this->skill;
  546. }
  547. /**
  548. * Retrieves the essences required to awaken the monster.
  549. *
  550. * @return [[Inventory][int]] Essences required to awaken the monster.s
  551. */
  552. public function get_essences(){
  553. if (! $this->flag_essences){
  554. $this->load_essences();
  555. }
  556. return $this->essences;
  557. }
  558. /**
  559. * Retrieves the sources the monster can be obtained from.
  560. *
  561. * @return Source[] Array of sources.s
  562. */
  563. public function get_sources(){
  564. if (! $this->flag_sources){
  565. $this->load_sources();
  566. }
  567. return $this->sources;
  568. }
  569. /**
  570. * Retrieves the unit's $title
  571. * If awakened, it will be the awakened from name.
  572. * If unawakened, it will be <element> <name>.
  573. *
  574. * @return string Units title.
  575. */
  576. public function get_title(){
  577. return $this->title;
  578. }
  579. /**
  580. * Retrieves the unit this ne can transform to.
  581. *
  582. * @return Monster_Transformation The transformation, null if none.
  583. */
  584. public function get_transformation(){
  585. if (! $this->flag_transformation){
  586. $this->load_transformation();
  587. }
  588. return $this->transformation;
  589. }
  590. /**
  591. * Gets the path to the monster image. The image must be in the
  592. * img/monster/ directory, and it's name must be the monster id,
  593. * padded with '0' to 8 digits, and the extension must be '.png'.
  594. *
  595. * @return string Image URL, or a fixed unknown image.
  596. */
  597. public function get_image(){
  598. return APPLICATION::img("UNIT", $this->id);
  599. }
  600. }
  601. ?>