Unit.php 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026
  1. <?php
  2. /**
  3. * Unit 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 . "Monster.php");
  13. require_once(PATH::ENTITY . "Team.php");
  14. require_once(PATH::ENTITY . "Rune.php");
  15. require_once(PATH::ENTITY . "Artifact.php");
  16. require_once(PATH::ENTITY . "Building.php");
  17. /**
  18. * A Unit.
  19. *
  20. * Represents an unit owned by the player.
  21. *
  22. * @category Entity
  23. */
  24. class Unit extends Entity{
  25. /**
  26. * @var int Owner's player ID.
  27. */
  28. private $player;
  29. /**
  30. * @var int Unit ID.
  31. */
  32. private $id;
  33. /**
  34. * @var int ID of the building the unit is in, if any.
  35. */
  36. private $building;
  37. /**
  38. * @var Monster Base monster
  39. */
  40. private $monster;
  41. /**
  42. * @var int Unit's current stars.
  43. */
  44. private $stars;
  45. /**
  46. * @var int Unit's current stars.
  47. */
  48. private $level;
  49. /**
  50. * @var int Total gained experience.
  51. */
  52. private $experience;
  53. /**
  54. * @var int Gainex experience in the curent level.
  55. */
  56. private $exp_gained;
  57. /**
  58. * @var int Experience gained by the hour, if in an EXP building.
  59. */
  60. private $exp_gain_rate;
  61. /**
  62. * @var bool Internal flag to check if current level experience parameters have been loaded.
  63. */
  64. private $flag_experience = false;
  65. /**
  66. * @var int Total experience for the current level.
  67. */
  68. private $experience_level = 0;
  69. /**
  70. * @var int Experience remaining until next level.
  71. */
  72. private $experience_level_up = 0;
  73. /**
  74. * @var bool Internal flag to inidicate if it has been checked that the unit is in the storage
  75. * building.
  76. */
  77. private $flag_storage = false;
  78. /**
  79. * @var bool Indicates if the unit is in storage.
  80. */
  81. private $in_storage = false;
  82. /**
  83. * @var string Unit's title.
  84. */
  85. private $title;
  86. /**
  87. * @var int Transmogification ID.
  88. */
  89. private $costume;
  90. /**
  91. * @var bool Internal flag to check if the source has been loaded into the entity.
  92. */
  93. private $flag_source = false;
  94. /**
  95. * @var int Unit source ID.
  96. */
  97. private $source_id;
  98. /**
  99. * @var Source Unit source.
  100. */
  101. private $source;
  102. /**
  103. * @var DateTime Unit creation time.
  104. */
  105. private $create_time;
  106. /**
  107. * @var string Name for Homunculus units.
  108. */
  109. private $homunculus_name;
  110. /**
  111. * @var bool Indicates if the unit is locked.
  112. */
  113. private $lock;
  114. /**
  115. * @var int[] The unit's base stats.
  116. */
  117. private $base_stats = array(
  118. "hp" => 0,
  119. "atk" => 0,
  120. "def" => 0,
  121. "spd" => 0,
  122. "crr" => 0,
  123. "crd" => 0,
  124. "acc" => 0,
  125. "res" => 0,
  126. "ehp" => 0,
  127. "dmg" => 0,
  128. );
  129. /**
  130. * @var int[] The unit's stat bonus gained from runes.
  131. */
  132. private $rune_stats = array(
  133. "hp" => 0,
  134. "atk" => 0,
  135. "def" => 0,
  136. "spd" => 0,
  137. "crr" => 0,
  138. "crd" => 0,
  139. "acc" => 0,
  140. "res" => 0,
  141. "ehp" => 0,
  142. "dmg" => 0,
  143. );
  144. /**
  145. * @var int[] The unit's stat bonus gained from artifacts.
  146. */
  147. private $artifact_stats = array(
  148. "hp" => 0,
  149. "atk" => 0,
  150. "def" => 0,
  151. "spd" => 0,
  152. "crr" => 0,
  153. "crd" => 0,
  154. "acc" => 0,
  155. "res" => 0,
  156. "ehp" => 0,
  157. "dmg" => 0,
  158. );
  159. /**
  160. * @var bool Internal flag to check if building stats have been loaded.
  161. */
  162. private $flag_buildings = false;
  163. /**
  164. * @var int[] The unit's stat bonus gained from buildings.
  165. */
  166. private $building_stats = array(
  167. "hp" => 0,
  168. "atk" => 0,
  169. "def" => 0,
  170. "spd" => 0,
  171. "crr" => 0,
  172. "crd" => 0,
  173. "acc" => 0,
  174. "res" => 0,
  175. "ehp" => 0,
  176. "dmg" => 0,
  177. );
  178. /**
  179. * @var bool Internal flag to check if all the stats have been loaded.
  180. */
  181. private $flag_stats = false;
  182. /**
  183. * @var int[] The unit's total stats.
  184. */
  185. private $stats = array(
  186. "hp" => 0,
  187. "atk" => 0,
  188. "def" => 0,
  189. "spd" => 0,
  190. "crr" => 0,
  191. "crd" => 0,
  192. "acc" => 0,
  193. "res" => 0,
  194. "ehp" => 0,
  195. "dmg" => 0,
  196. );
  197. /**
  198. * @var bool Internal flag to check if runes and artifacts have been loaded.
  199. */
  200. private $flag_runes = false;
  201. /**
  202. * @var float Average rune eficiency.
  203. */
  204. private $avg_rune_efficiency = 0.0;
  205. /**
  206. * @var Rune[] Equipped runes.
  207. */
  208. private $rune = [];
  209. /**
  210. * @var Artifact Equiped archetype artifact.
  211. */
  212. private $artifact_type;
  213. /**
  214. * @var Artifact Equipped elemental artifact.
  215. */
  216. private $artifact_element;
  217. /**
  218. * @var bool Internla flag to check if the teams have been loaded into the entity.
  219. */
  220. private $flag_teams = false;
  221. /**
  222. * @var Team [] The teams the unit is in.
  223. */
  224. private $teams = [];
  225. /**
  226. * @var bool Internal flag to check if the skill levels have been loded.
  227. */
  228. private $flag_skills = false;
  229. /**
  230. * @var int[] Skill levels.
  231. */
  232. private $skill_levels = [];
  233. /**
  234. * Constructor.
  235. *
  236. * Searches the database and retrieves the information about the
  237. * unit, populating it and it's items.
  238. *
  239. * @param int $id Unit identifier.
  240. */
  241. public function __construct($id){
  242. $statement = get_context()->get_db()->prepare("
  243. SELECT
  244. player,
  245. id,
  246. building,
  247. monster,
  248. stars,
  249. level,
  250. hp,
  251. attack,
  252. defense,
  253. speed,
  254. crit_rate,
  255. crit_damage,
  256. resistance,
  257. accuracy,
  258. experience,
  259. exp_gained,
  260. exp_gain_rate,
  261. costume,
  262. source,
  263. create_time,
  264. homunculus_name,
  265. lock
  266. FROM unit
  267. WHERE
  268. id = :id;
  269. ");
  270. $statement->bindValue(':id', $id, SQLITE3_TEXT);
  271. $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
  272. if ($r){
  273. $this->player = $r["player"];
  274. $this->id = $r["id"];
  275. if ($r["building"] != null && $r["building"] > 0){
  276. $this->building = $r["building"];
  277. }
  278. if (strlen($r["monster"]) > 0){
  279. $this->monster = new Monster($r["monster"]);
  280. }
  281. $this->stars = $r["stars"];
  282. $this->level = $r["level"];
  283. $this->base_stats["hp"] = $r["hp"];
  284. $this->base_stats["atk"] = $r["attack"];
  285. $this->base_stats["def"] = $r["defense"];
  286. $this->base_stats["spd"] = $r["speed"];
  287. $this->base_stats["crr"] = $r["crit_rate"];
  288. $this->base_stats["crd"] = $r["crit_damage"];
  289. $this->base_stats["res"] = $r["resistance"];
  290. $this->base_stats["acc"] = $r["accuracy"];
  291. $this->base_stats["ehp"] = APPLICATION::calculate_ehp($r["hp"], $r["defense"]);
  292. $this->base_stats["dmg"] = APPLICATION::calculate_dmg($r["attack"], $r["crit_rate"], $r["crit_damage"]);
  293. $this->experience = $r["experience"];
  294. $this->exp_gained = $r["exp_gained"];
  295. $this->exp_gain_rate = $r["exp_gain_rate"];
  296. $this->costume = $r["costume"];
  297. if ($r["source"]){
  298. $this->source_id = $r["source"];
  299. }
  300. $this->create_time = new Datetime();
  301. $this->create_time->setTimestamp($r["create_time"]);
  302. $this->homunculus_name = $r["homunculus_name"];
  303. if ($this->monster->is_homunculus()){
  304. $this->title = $this->homunculus_name;
  305. }
  306. else{
  307. $this->title = $this->monster->get_title();
  308. }
  309. $this->lock = $r["lock"];
  310. }
  311. }
  312. /**
  313. * Loads the unit skills into the entity.
  314. *
  315. * Must be called only once before trying to get the skills. Sets the flag
  316. * {@link Unit:$flag_skills} to true.
  317. */
  318. private function load_skills(){
  319. $statement = get_context()->get_db()->prepare("
  320. SELECT level
  321. FROM
  322. unit_skill,
  323. skill
  324. WHERE
  325. skill.id = unit_skill.skill AND
  326. unit_skill.unit = :unit
  327. ORDER BY slot;
  328. ");
  329. $statement->bindValue(':unit', $this->id, SQLITE3_TEXT);
  330. $q = $statement->execute();
  331. while ($r = $q->fetchArray(SQLITE3_ASSOC)){
  332. array_push($this->skill_levels, $r["level"]);
  333. }
  334. $this->flag_skills = true;
  335. }
  336. /**
  337. * Loads the unit's current level experience parameters into the entity.
  338. *
  339. * Must be called only once before trying to get experience parameters. Sets the flag
  340. * {@link Unit:$flag_experience} to true.
  341. */
  342. private function load_experience(){
  343. $statement = get_context()->get_db()->prepare("
  344. SELECT exp
  345. FROM experience
  346. WHERE
  347. stars = :stars AND
  348. level = :level;
  349. ");
  350. $statement->bindValue(':stars', $this->stars, SQLITE3_TEXT);
  351. $statement->bindValue(':level', $this->level, SQLITE3_TEXT);
  352. $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
  353. if ($r){
  354. $this->experience_level = $r["exp"];
  355. $this->experience_level_up = $r["exp"] - $this->exp_gained;
  356. }
  357. $this->flag_experience = true;
  358. }
  359. /**
  360. * Loads the unit storage status into the entity.
  361. *
  362. * Must be called only once before trying to get the skills. Sets the flag
  363. * {@link Unit:$flag_storage} to true.
  364. */
  365. private function load_storage(){
  366. $statement = get_context()->get_db()->prepare("
  367. SELECT 1
  368. FROM
  369. unit,
  370. building
  371. WHERE
  372. unit.id = :id AND
  373. unit.player = :player AND
  374. building.player = :player AND
  375. unit.building = building.id AND
  376. building.buildable = :buildable;
  377. ");
  378. $statement->bindValue(':id', $this->id, SQLITE3_TEXT);
  379. $statement->bindValue(':player', $this->player, SQLITE3_TEXT);
  380. $statement->bindValue(':buildable', BUILDING_ID::MONSTER_STORAGE, SQLITE3_TEXT);
  381. $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
  382. if ($r){
  383. $this->in_storage = true;
  384. }
  385. else{
  386. $this->in_storage = false;
  387. }
  388. $this->flag_storage = true;
  389. }
  390. /**
  391. * Loads the building stats into the entity.
  392. *
  393. * Must be called only once before trying to get the building or total stats. Sets the flag
  394. * {@link Unit:$flag_buildings} to true.
  395. */
  396. private function load_buildings(){
  397. $statement = get_context()->get_db()->prepare("
  398. SELECT
  399. affected_stat,
  400. bonus,
  401. element
  402. FROM
  403. decorative,
  404. decorative_level,
  405. decoration
  406. WHERE
  407. decoration.player = :player AND
  408. decorative.id = decoration.decorative AND
  409. decoration.decorative = decorative_level.decorative AND
  410. decoration.level = decorative_level.level AND
  411. area = :area AND
  412. affected_stat IN (:stat_atk, :stat_def, :stat_hp, :stat_spd, :stat_crd);
  413. ");
  414. $statement->bindValue(':player', $this->player, SQLITE3_TEXT);
  415. $statement->bindValue(':area', EFFECT_AREA_ID::GENERAL, SQLITE3_INTEGER);
  416. $statement->bindValue(':stat_atk', STAT_ID::ATK, SQLITE3_INTEGER);
  417. $statement->bindValue(':stat_def', STAT_ID::DEF, SQLITE3_INTEGER);
  418. $statement->bindValue(':stat_hp', STAT_ID::HP, SQLITE3_INTEGER);
  419. $statement->bindValue(':stat_spd', STAT_ID::SPD, SQLITE3_INTEGER);
  420. $statement->bindValue(':stat_crd', STAT_ID::CRD, SQLITE3_INTEGER);
  421. $q = $statement->execute();
  422. while ($r = $q->fetchArray(SQLITE3_ASSOC)){
  423. switch($r["affected_stat"]){
  424. case STAT_ID::DEF:
  425. $this->building_stats["def"] += ($this->base_stats["def"]* $r["bonus"] / 100);
  426. break;
  427. case STAT_ID::HP:
  428. $this->building_stats["hp"] += ($this->base_stats["hp"]* $r["bonus"] / 100);
  429. break;
  430. case STAT_ID::SPD:
  431. $this->building_stats["spd"] += ($this->base_stats["spd"]* $r["bonus"] / 100);
  432. break;
  433. case STAT_ID::CRD:
  434. $this->building_stats["crd"] += $r["bonus"];
  435. break;
  436. case STAT_ID::ATK:
  437. if(strlen($r["element"]) > 0 && $r["element"] == $this->monster->get_element()){
  438. $this->building_stats["atk"] += ($this->base_stats["atk"] * $r["bonus"] / 100);
  439. }
  440. elseif(strlen($r["element"]) == 0){
  441. $this->building_stats["atk"] += ($this->base_stats["atk"] * $r["bonus"] / 100);
  442. }
  443. break;
  444. }
  445. }
  446. $this->building_stats["hp"] = ceil($this->building_stats["hp"]);
  447. $this->building_stats["atk"] = ceil($this->building_stats["atk"]);
  448. $this->building_stats["def"] = ceil($this->building_stats["def"]);
  449. $this->building_stats["spd"] = ceil($this->building_stats["spd"]);
  450. $this->building_stats["ehp"] = APPLICATION::calculate_ehp($this->building_stats["hp"], $this->building_stats["def"]);
  451. $this->building_stats["dmg"] = APPLICATION::calculate_dmg($this->building_stats["atk"], $this->building_stats["crr"], $this->building_stats["crd"]);
  452. $this->flag_buildings = true;
  453. }
  454. /**
  455. * Loads the unit source into the entity.
  456. *
  457. * Must be called only once before trying to get the source. Sets the flag
  458. * {@link Unit:$flag_source} to true.
  459. */
  460. private function load_source(){
  461. if ($this->source_id != null){
  462. $this->source = new Source($this->source_id);
  463. }
  464. $this->flag_source = true;
  465. }
  466. /**
  467. * Loads the unit runes and artifacts into the entity.
  468. *
  469. * Must be called only once before trying to the runes or artifact or their stats. Sets the
  470. * flag {@link Unit:$flag_skills} to true.
  471. */
  472. private function load_runes(){
  473. // Runes
  474. $statement = get_context()->get_db()->prepare("
  475. SELECT rune
  476. FROM unit_rune
  477. WHERE
  478. unit = :unit AND
  479. rta = :rta;
  480. ");
  481. $statement->bindValue(':unit', $this->id, SQLITE3_TEXT);
  482. $statement->bindValue(':rta', get_context()->get_game_mode(), SQLITE3_TEXT);
  483. $q = $statement->execute();
  484. while ($r = $q->fetchArray(SQLITE3_ASSOC)){
  485. array_push($this->rune, new Rune($r["rune"]));
  486. }
  487. foreach ($this->rune as $rune){
  488. foreach ($rune->get_stats() as $stat){
  489. $this->sum_rune_stat($stat->get_stat(), $stat->get_value() + $stat->get_grind());
  490. }
  491. }
  492. $this->rune_stats["atk"] = ceil($this->rune_stats["atk"]);
  493. $this->rune_stats["def"] = ceil($this->rune_stats["def"]);
  494. $this->rune_stats["hp"] = ceil($this->rune_stats["hp"]);
  495. $this->rune_stats["ehp"] = APPLICATION::calculate_ehp($this->rune_stats["hp"], $this->rune_stats["def"]);
  496. $this->rune_stats["dmg"] = APPLICATION::calculate_dmg($this->rune_stats["atk"], $this->rune_stats["crr"], $this->rune_stats["crd"]);
  497. // Artifacts
  498. $this->artifact = [];
  499. $statement = get_context()->get_db()->prepare("
  500. SELECT artifact
  501. FROM unit_artifact
  502. WHERE
  503. unit = :unit AND
  504. rta = :rta;
  505. ");
  506. $statement->bindValue(':unit', $this->id, SQLITE3_TEXT);
  507. $statement->bindValue(':rta', get_context()->get_game_mode(), SQLITE3_TEXT);
  508. $q = $statement->execute();
  509. while ($r = $q->fetchArray(SQLITE3_ASSOC)){
  510. $artifact = new Artifact($r["artifact"]);
  511. if ($artifact->is_archetypal()){
  512. $this->artifact_type = $artifact;
  513. }
  514. else{
  515. $this->artifact_element = $artifact;
  516. }
  517. switch($artifact->get_stat()->get_stat()){
  518. case ARTIFACT_STAT_ID::ATK:
  519. $this->artifact_stats["atk"] += $artifact->get_stat()->get_value();
  520. break;
  521. case ARTIFACT_STAT_ID::DEF:
  522. $this->artifact_stats["def"] += $artifact->get_stat()->get_value();
  523. break;
  524. case ARTIFACT_STAT_ID::HP:
  525. $this->artifact_stats["hp"] += $artifact->get_stat()->get_value();
  526. break;
  527. }
  528. }
  529. $this->artifact_stats["ehp"] = APPLICATION::calculate_ehp($this->artifact_stats["hp"], $this->artifact_stats["def"]);
  530. $this->artifact_stats["dmg"] = APPLICATION::calculate_dmg($this->artifact_stats["atk"], $this->artifact_stats["crr"], $this->artifact_stats["crd"]);
  531. $this->flag_runes = true;
  532. }
  533. /**
  534. * Calculates the unit's total stats.
  535. *
  536. * Must be called only once before trying to get the stats. Sets the flag
  537. * {@link Unit:$flag_stats} to true.
  538. */
  539. private function load_stats(){
  540. if (! $this->flag_buildings){
  541. $this->load_buildings();
  542. }
  543. if (! $this->flag_runes){
  544. $this->load_runes();
  545. }
  546. $keys = ["atk", "def", "hp", "spd", "crr", "crd", "res", "acc", "ehp", "dmg"];
  547. foreach ($keys as $key){
  548. $this->stats[$key] = $this->base_stats[$key] + $this->rune_stats[$key] + $this->artifact_stats[$key] + $this->building_stats[$key];
  549. }
  550. $this->flag_stats = true;
  551. }
  552. /**
  553. * Loads the unit teams into the entity.
  554. *
  555. * Must be called only once before trying to get the teams. Sets the flag
  556. * {@link Unit:$flag_teams} to true.
  557. */
  558. private function load_teams(){
  559. $statement = get_context()->get_db()->prepare("
  560. SELECT DISTINCT team.id AS id
  561. FROM
  562. team,
  563. team_unit
  564. WHERE
  565. team.player = :player AND
  566. team.id = team_unit.team AND
  567. team_unit.unit = :unit;
  568. ");
  569. $statement->bindValue(':player', $this->player, SQLITE3_TEXT);
  570. $statement->bindValue(':unit', $this->id, SQLITE3_TEXT);
  571. $q = $statement->execute();
  572. while ($r = $q->fetchArray(SQLITE3_ASSOC)){
  573. array_push($this->teams, new Team($r["id"], false));
  574. }
  575. $this->flag_teams = true;
  576. }
  577. /**
  578. * Calculates the stat increase by a rune property.
  579. *
  580. * @param string $stat Stat type.
  581. * @param int $value Stat value.
  582. * @param int $value Stat increase value.
  583. */
  584. private function sum_rune_stat($stat, $value){
  585. switch ($stat){
  586. case RUNE_STAT_ID::ATK:
  587. $this->rune_stats["atk"] += $value;
  588. break;
  589. case RUNE_STAT_ID::DEF:
  590. $this->rune_stats["def"] += $value;
  591. break;
  592. case RUNE_STAT_ID::HP:
  593. $this->rune_stats["hp"] += $value;
  594. break;
  595. case RUNE_STAT_ID::SPD:
  596. $this->rune_stats["spd"] += $value;
  597. break;
  598. case RUNE_STAT_ID::CRR:
  599. $this->rune_stats["crr"] += $value;
  600. break;
  601. case RUNE_STAT_ID::CRD:
  602. $this->rune_stats["crd"] += $value;
  603. break;
  604. case RUNE_STAT_ID::ACC:
  605. $this->rune_stats["acc"] += $value;
  606. break;
  607. case RUNE_STAT_ID::RES:
  608. $this->rune_stats["res"] += $value;
  609. break;
  610. case RUNE_STAT_ID::ATK_P:
  611. $this->rune_stats["atk"] += ($this->base_stats["atk"] * $value / 100);
  612. break;
  613. case RUNE_STAT_ID::DEF_P:
  614. $this->rune_stats["def"] += ($this->base_stats["def"] * $value / 100);
  615. break;
  616. case RUNE_STAT_ID::HP_P:
  617. $this->rune_stats["hp"] += ($this->base_stats["hp"] * $value / 100);
  618. break;
  619. }
  620. }
  621. /**
  622. * Checks if the unit skills are completly maxed.
  623. *
  624. * @return bool True if all skills maxed, false otherwise.
  625. */
  626. public function is_fully_skilled(){
  627. if (! $this->flag_skills){
  628. $this->load_skills();
  629. }
  630. $maxed = true;
  631. $skills = $this->monster->get_skills();
  632. for ($i = 0; $i < sizeof($skills); $i ++){
  633. if ($skills[$i]->get_max_level() > $this->skill_levels[$i]){
  634. $maxed = false;
  635. break;
  636. }
  637. }
  638. return $maxed;
  639. }
  640. /**
  641. * Retrieves the owner's player identifier.
  642. *
  643. * @return int Player ID.
  644. */
  645. public function get_player(){
  646. return $this->player;
  647. }
  648. /**
  649. * Retrieves the unit identifier.
  650. *
  651. * @return int Unit ID.
  652. */
  653. public function get_id(){
  654. return $this->id;
  655. }
  656. /**
  657. * Retrieves the identifier of the building the unit is in, if any.
  658. *
  659. * @return int Building ID, null if unit not in building.
  660. */
  661. public function get_building_id(){
  662. return $this->building;
  663. }
  664. /**
  665. * Retrieves the base monster.
  666. *
  667. * @return Monster The base monster.
  668. */
  669. public function get_monster(){
  670. return $this->monster;
  671. }
  672. /**
  673. * Retrieves the unit stars (grade).
  674. *
  675. * @return int Unit stars (1-6).
  676. */
  677. public function get_stars(){
  678. return $this->stars;
  679. }
  680. /**
  681. * Retrieves the unit current level.
  682. *
  683. * @return int Unit level.
  684. */
  685. public function get_level(){
  686. return $this->level;
  687. }
  688. /**
  689. * Retrieves the unit's base stats.
  690. *
  691. * It's an associative array with the following keys:
  692. * atk, def, hp, spd, crr, crd, acc, res, ehp, dmg
  693. *
  694. * @return int[] Unit stats.
  695. */
  696. public function get_base_stats(){
  697. return $this->base_stats;
  698. }
  699. /**
  700. * Retrieves the unit's stats provided by runes.
  701. *
  702. * It's an associative array with the following keys:
  703. * atk, def, hp, spd, crr, crd, acc, res, ehp, dmg
  704. *
  705. * @return int[] Rune stats.
  706. */
  707. public function get_rune_stats(){
  708. if (! $this->flag_runes){
  709. $this->load_runes();
  710. }
  711. return $this->rune_stats;
  712. }
  713. /**
  714. * Retrieves the unit's stats provided by artifacts.
  715. *
  716. * It's an associative array with the following keys:
  717. * atk, def, hp, spd, crr, crd, acc, res, ehp, dmg
  718. * Note that only "atk", "def", "hp", "dmg" and "ehp" can me non-zero.
  719. *
  720. * @return int[] Artifact stats.
  721. */
  722. public function get_artifact_stats(){
  723. if (! $this->flag_runes){
  724. $this->load_runes();
  725. }
  726. return $this->artifact_stats;
  727. }
  728. /**
  729. * Retrieves the unit's stat bonus provided by buildings.
  730. *
  731. * Only building bonuses are considered.
  732. * It's an associative array with the following keys:
  733. * atk, def, hp, spd, crr, crd, acc, res, ehp, dmg
  734. *
  735. * @return int[] Building stats.
  736. */
  737. public function get_building_stats(){
  738. if (! $this->flag_buildings){
  739. $this->load_buildings();
  740. }
  741. return $this->building_stats;
  742. }
  743. /**
  744. * Retrieves the unit's stats.
  745. *
  746. * It's an associative array with the following keys:
  747. * atk, def, hp, spd, crr, crd, acc, res, ehp, dmg
  748. *
  749. * Includes the unit base stats, the runes and artifact increases and the building bonuses.
  750. *
  751. * @return int[] Unit stats.
  752. */
  753. public function get_stats(){
  754. if (! $this->flag_stats){
  755. $this->load_stats();
  756. }
  757. return $this->stats;
  758. }
  759. /**
  760. * Retrieves the total experience earned by the unit.
  761. *
  762. * @return int Total experience.
  763. */
  764. public function get_experience(){
  765. return $this->experience;
  766. }
  767. /**
  768. * Retrieves the total experience earned by the unit since it's level is the current one..
  769. *
  770. * @return int Current level experience.
  771. */
  772. public function get_current_level_experience(){
  773. return $this->exp_gained;
  774. }
  775. /**
  776. * Retrieves the experience being gained by the hour from a building.
  777. *
  778. * @return int Experience by the hour, 0 if not in an exp building.
  779. */
  780. public function get_exp_gain_rate(){
  781. return $this->exp_gain_rate;
  782. }
  783. /**
  784. * Retrieves the current transmogrification identifier.
  785. *
  786. * @return int Transmogification ID, null if none.
  787. */
  788. public function get_costume(){
  789. return $this->costume;
  790. }
  791. /**
  792. * Retrieves the $source the unit was obtained from.
  793. *
  794. * @return Source Unit source.
  795. */
  796. public function get_source(){
  797. if (! $this->flag_source){
  798. $this->load_source();
  799. }
  800. return $this->source;
  801. }
  802. /**
  803. * Gets the date the unit was obtained.
  804. *
  805. * If $format is supplied, a string in the desired format will be returned. If not, the raw
  806. * DateTime object will e returned.
  807. *
  808. * @param string $format A date format (optional).
  809. * @return DateTime | string The raw date, or a formatted version.
  810. */
  811. public function get_creation_time($format = null){
  812. if (null == $format){
  813. return $this->create_time;
  814. }
  815. else{
  816. return $this->create_time->format($format);
  817. }
  818. }
  819. /**
  820. * Retrieves the name if the unit is an homunculus.
  821. *
  822. * @return string Homunculus name, null if not Homunculus.
  823. */
  824. public function get_homunculus_name(){
  825. return $this->homunculus_name;
  826. }
  827. /**
  828. * Checks if the unit is locked.
  829. *
  830. * @return bool True if locked, false if unlocked.
  831. */
  832. public function is_locked(){
  833. return $this->lock;
  834. }
  835. /**
  836. * Retrieves the average rune efficiency.
  837. *
  838. * @return int Average efficiency of the runes.
  839. */
  840. public function get_avg_rune_efficiency(){
  841. if (! $this->flag_runes){
  842. $this->load_runes();
  843. }
  844. return $this->avg_rune_efficiency;
  845. }
  846. /**
  847. * Retrieves the currently equipped runes.
  848. *
  849. * @return Rune[] Equipped runes.
  850. */
  851. public function get_runes(){
  852. if (! $this->flag_runes){
  853. $this->load_runes();
  854. }
  855. return $this->rune;
  856. }
  857. /**
  858. * Retrieves equipped artifacts.
  859. *
  860. * Can be read with the indexes ARTIFACT_TYPE:ELEMENT and ARTIFACT_TYPE:ARCHETYPE.
  861. *
  862. * @see ARTIFACT_TYPE
  863. * @return Artifact[] Equiped artifact array. Null positions if not equipped.
  864. */
  865. public function get_artifacts(){
  866. if (! $this->flag_runes){
  867. $this->load_runes();
  868. }
  869. return [$this->artifact_element, $this->artifact_type];
  870. }
  871. /**
  872. * Retrieves the teams the unit is in.
  873. *
  874. * @return Team[] Teams the unit is in.
  875. */
  876. public function get_teams(){
  877. if (! $this->flag_teams){
  878. $this->load_teams();
  879. }
  880. return $this->teams;
  881. }
  882. /**
  883. * Retrieves the skill levels.
  884. *
  885. * @return int[] Skill levels, ordered by skill slot.
  886. */
  887. public function get_skill_levels(){
  888. if (! $this->flag_skills){
  889. $this->load_skills();
  890. }
  891. return $this->skill_levels;
  892. }
  893. /**
  894. * Retrieves the total experience required for the current level.
  895. *
  896. * @return int Level experience.
  897. */
  898. public function get_experience_level(){
  899. if (! $this->flag_experience){
  900. $this->load_experience();
  901. }
  902. return $this->experience_level;
  903. }
  904. /**
  905. * Retrieves the experience required to level-up.
  906. *
  907. * @return int Experience to level-up.
  908. */
  909. public function get_experience_level_up(){
  910. if (! $this->flag_experience){
  911. $this->load_experience();
  912. }
  913. return $this->experience_level_up;
  914. }
  915. /**
  916. * Checks if the unit is in storage.
  917. *
  918. * @return bool True if in storage, false otherwise.
  919. */
  920. public function is_in_storage(){
  921. if (! $this->flag_storage){
  922. $this->load_storage();
  923. }
  924. return $this->in_storage;
  925. }
  926. /**
  927. * Retrieves the unit's title.
  928. *
  929. * If Homunculus,it will be it's name.
  930. * If awakened, it will be the awakened from name.
  931. * If unawakened, it will be <element> <name>.
  932. *
  933. * @return string The unit's title.
  934. */
  935. public function get_title(){
  936. return $this->title;
  937. }
  938. }