Unit.php 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028
  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. $player = get_context()->get_player()->get_id();
  243. $statement = get_context()->get_db()->prepare("
  244. SELECT
  245. player,
  246. id,
  247. building,
  248. monster,
  249. stars,
  250. level,
  251. hp,
  252. attack,
  253. defense,
  254. speed,
  255. crit_rate,
  256. crit_damage,
  257. resistance,
  258. accuracy,
  259. experience,
  260. exp_gained,
  261. exp_gain_rate,
  262. costume,
  263. source,
  264. create_time,
  265. homunculus_name,
  266. lock
  267. FROM unit
  268. WHERE
  269. id = :id;
  270. ");
  271. $statement->bindValue(':id', $id, SQLITE3_TEXT);
  272. $statement->bindValue(':player', $player, SQLITE3_TEXT);
  273. $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
  274. if ($r){
  275. $this->player = $r["player"];
  276. $this->id = $r["id"];
  277. if ($r["building"] != null && $r["building"] > 0){
  278. $this->building = $r["building"];
  279. }
  280. if (strlen($r["monster"]) > 0){
  281. $this->monster = new Monster($r["monster"]);
  282. }
  283. $this->stars = $r["stars"];
  284. $this->level = $r["level"];
  285. $this->base_stats["hp"] = $r["hp"];
  286. $this->base_stats["atk"] = $r["attack"];
  287. $this->base_stats["def"] = $r["defense"];
  288. $this->base_stats["spd"] = $r["speed"];
  289. $this->base_stats["crr"] = $r["crit_rate"];
  290. $this->base_stats["crd"] = $r["crit_damage"];
  291. $this->base_stats["res"] = $r["resistance"];
  292. $this->base_stats["acc"] = $r["accuracy"];
  293. $this->base_stats["ehp"] = APPLICATION::calculate_ehp($r["hp"], $r["defense"]);
  294. $this->base_stats["dmg"] = APPLICATION::calculate_dmg($r["attack"], $r["crit_rate"], $r["crit_damage"]);
  295. $this->experience = $r["experience"];
  296. $this->exp_gained = $r["exp_gained"];
  297. $this->exp_gain_rate = $r["exp_gain_rate"];
  298. $this->costume = $r["costume"];
  299. if ($r["source"]){
  300. $this->source_id = $r["source"];
  301. }
  302. $this->create_time = new Datetime();
  303. $this->create_time->setTimestamp($r["create_time"]);
  304. $this->homunculus_name = $r["homunculus_name"];
  305. if ($this->monster->is_homunculus()){
  306. $this->title = $this->homunculus_name;
  307. }
  308. else{
  309. $this->title = $this->monster->get_title();
  310. }
  311. $this->lock = $r["lock"];
  312. }
  313. }
  314. /**
  315. * Loads the unit skills into the entity.
  316. *
  317. * Must be called only once before trying to get the skills. Sets the flag
  318. * {@link Unit:$flag_skills} to true.
  319. */
  320. private function load_skills(){
  321. $statement = get_context()->get_db()->prepare("
  322. SELECT level
  323. FROM
  324. unit_skill,
  325. skill
  326. WHERE
  327. skill.id = unit_skill.skill AND
  328. unit_skill.unit = :unit
  329. ORDER BY slot;
  330. ");
  331. $statement->bindValue(':unit', $this->id, SQLITE3_TEXT);
  332. $q = $statement->execute();
  333. while ($r = $q->fetchArray(SQLITE3_ASSOC)){
  334. array_push($this->skill_levels, $r["level"]);
  335. }
  336. $this->flag_skills = true;
  337. }
  338. /**
  339. * Loads the unit's current level experience parameters into the entity.
  340. *
  341. * Must be called only once before trying to get experience parameters. Sets the flag
  342. * {@link Unit:$flag_experience} to true.
  343. */
  344. private function load_experience(){
  345. $statement = get_context()->get_db()->prepare("
  346. SELECT exp
  347. FROM experience
  348. WHERE
  349. stars = :stars AND
  350. level = :level;
  351. ");
  352. $statement->bindValue(':stars', $this->stars, SQLITE3_TEXT);
  353. $statement->bindValue(':level', $this->level, SQLITE3_TEXT);
  354. $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
  355. if ($r){
  356. $this->experience_level = $r["exp"];
  357. $this->experience_level_up = $r["exp"] - $this->exp_gained;
  358. }
  359. $this->flag_experience = true;
  360. }
  361. /**
  362. * Loads the unit storage status into the entity.
  363. *
  364. * Must be called only once before trying to get the skills. Sets the flag
  365. * {@link Unit:$flag_storage} to true.
  366. */
  367. private function load_storage(){
  368. $statement = get_context()->get_db()->prepare("
  369. SELECT 1
  370. FROM
  371. unit,
  372. building
  373. WHERE
  374. unit.id = :id AND
  375. unit.player = :player AND
  376. building.player = :player AND
  377. unit.building = building.id AND
  378. building.buildable = :buildable;
  379. ");
  380. $statement->bindValue(':id', $this->id, SQLITE3_TEXT);
  381. $statement->bindValue(':player', $this->player, SQLITE3_TEXT);
  382. $statement->bindValue(':buildable', BUILDING_ID::MONSTER_STORAGE, SQLITE3_TEXT);
  383. $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
  384. if ($r){
  385. $this->in_storage = true;
  386. }
  387. else{
  388. $this->in_storage = false;
  389. }
  390. $this->flag_storage = true;
  391. }
  392. /**
  393. * Loads the building stats into the entity.
  394. *
  395. * Must be called only once before trying to get the building or total stats. Sets the flag
  396. * {@link Unit:$flag_buildings} to true.
  397. */
  398. private function load_buildings(){
  399. $statement = get_context()->get_db()->prepare("
  400. SELECT
  401. affected_stat,
  402. bonus,
  403. element
  404. FROM
  405. decorative,
  406. decorative_level,
  407. decoration
  408. WHERE
  409. decoration.player = :player AND
  410. decorative.id = decoration.decorative AND
  411. decoration.decorative = decorative_level.decorative AND
  412. decoration.level = decorative_level.level AND
  413. area = :area AND
  414. affected_stat IN (:stat_atk, :stat_def, :stat_hp, :stat_spd, :stat_crd);
  415. ");
  416. $statement->bindValue(':player', $this->player, SQLITE3_TEXT);
  417. $statement->bindValue(':area', EFFECT_AREA_ID::GENERAL, SQLITE3_INTEGER);
  418. $statement->bindValue(':stat_atk', STAT_ID::ATK, SQLITE3_INTEGER);
  419. $statement->bindValue(':stat_def', STAT_ID::DEF, SQLITE3_INTEGER);
  420. $statement->bindValue(':stat_hp', STAT_ID::HP, SQLITE3_INTEGER);
  421. $statement->bindValue(':stat_spd', STAT_ID::SPD, SQLITE3_INTEGER);
  422. $statement->bindValue(':stat_crd', STAT_ID::CRIT_DMG, SQLITE3_INTEGER);
  423. $q = $statement->execute();
  424. while ($r = $q->fetchArray(SQLITE3_ASSOC)){
  425. switch($r["affected_stat"]){
  426. case STAT_ID::DEF:
  427. $this->building_stats["def"] += ($this->base_stats["def"]* $r["bonus"] / 100);
  428. break;
  429. case STAT_ID::HP:
  430. $this->building_stats["hp"] += ($this->base_stats["hp"]* $r["bonus"] / 100);
  431. break;
  432. case STAT_ID::SPD:
  433. $this->building_stats["spd"] += ($this->base_stats["spd"]* $r["bonus"] / 100);
  434. break;
  435. case STAT_ID::CRIT_DMG:
  436. $this->building_stats["crd"] += $r["bonus"];
  437. break;
  438. case STAT_ID::ATK:
  439. if(strlen($r["element"]) > 0 && $r["element"] == $this->monster->get_element()){
  440. $this->building_stats["atk"] += ($this->base_stats["atk"]* $r["bonus"] / 100);
  441. }
  442. else{
  443. $this->building_stats["atk"] += ($this->base_stats["atk"]* $r["bonus"] / 100);
  444. }
  445. break;
  446. }
  447. }
  448. $this->building_stats["hp"] = ceil($this->building_stats["hp"]);
  449. $this->building_stats["atk"] = ceil($this->building_stats["atk"]);
  450. $this->building_stats["def"] = ceil($this->building_stats["def"]);
  451. $this->building_stats["spd"] = ceil($this->building_stats["spd"]);
  452. $this->building_stats["ehp"] = APPLICATION::calculate_ehp($this->building_stats["hp"], $this->building_stats["def"]);
  453. $this->building_stats["dmg"] = APPLICATION::calculate_dmg($this->building_stats["atk"], $this->building_stats["crr"], $this->building_stats["crd"]);
  454. $this->flag_buildings = true;
  455. }
  456. /**
  457. * Loads the unit source into the entity.
  458. *
  459. * Must be called only once before trying to get the source. Sets the flag
  460. * {@link Unit:$flag_source} to true.
  461. */
  462. private function load_source(){
  463. if ($this->source_id != null){
  464. $this->source = new Source($this->source_id);
  465. }
  466. $this->flag_source = true;
  467. }
  468. /**
  469. * Loads the unit runes and artifacts into the entity.
  470. *
  471. * Must be called only once before trying to the runes or artifact or their stats. Sets the
  472. * flag {@link Unit:$flag_skills} to true.
  473. */
  474. private function load_runes(){
  475. // Runes
  476. $statement = get_context()->get_db()->prepare("
  477. SELECT rune
  478. FROM unit_rune
  479. WHERE
  480. unit = :unit AND
  481. rta = :rta;
  482. ");
  483. $statement->bindValue(':unit', $this->id, SQLITE3_TEXT);
  484. $statement->bindValue(':rta', get_context()->get_game_mode(), SQLITE3_TEXT);
  485. $q = $statement->execute();
  486. while ($r = $q->fetchArray(SQLITE3_ASSOC)){
  487. array_push($this->rune, new Rune($r["rune"]));
  488. }
  489. foreach ($this->rune as $rune){
  490. foreach ($rune->get_stats() as $stat){
  491. $this->sum_rune_stat($stat->get_stat(), $stat->get_value() + $stat->get_grind());
  492. }
  493. }
  494. $this->rune_stats["atk"] = ceil($this->rune_stats["atk"]);
  495. $this->rune_stats["def"] = ceil($this->rune_stats["def"]);
  496. $this->rune_stats["hp"] = ceil($this->rune_stats["hp"]);
  497. $this->rune_stats["ehp"] = APPLICATION::calculate_ehp($this->rune_stats["hp"], $this->rune_stats["def"]);
  498. $this->rune_stats["dmg"] = APPLICATION::calculate_dmg($this->rune_stats["atk"], $this->rune_stats["crr"], $this->rune_stats["crd"]);
  499. // Artifacts
  500. $this->artifact = [];
  501. $statement = get_context()->get_db()->prepare("
  502. SELECT artifact
  503. FROM unit_artifact
  504. WHERE
  505. unit = :unit AND
  506. rta = :rta;
  507. ");
  508. $statement->bindValue(':unit', $this->id, SQLITE3_TEXT);
  509. $statement->bindValue(':rta', get_context()->get_game_mode(), SQLITE3_TEXT);
  510. $q = $statement->execute();
  511. while ($r = $q->fetchArray(SQLITE3_ASSOC)){
  512. $artifact = new Artifact($r["artifact"]);
  513. if ($artifact->is_archetypal()){
  514. $this->artifact_type = $artifact;
  515. }
  516. else{
  517. $this->artifact_element = $artifact;
  518. }
  519. switch($artifact->get_stat()->get_stat()){
  520. case ARTIFACT_STAT_ID::ATK:
  521. $this->artifact_stats["atk"] += $artifact->get_stat()->get_value();
  522. break;
  523. case ARTIFACT_STAT_ID::DEF:
  524. $this->artifact_stats["def"] += $artifact->get_stat()->get_value();
  525. break;
  526. case ARTIFACT_STAT_ID::HP:
  527. $this->artifact_stats["hp"] += $artifact->get_stat()->get_value();
  528. break;
  529. }
  530. }
  531. $this->artifact_stats["ehp"] = APPLICATION::calculate_ehp($this->artifact_stats["hp"], $this->artifact_stats["def"]);
  532. $this->artifact_stats["dmg"] = APPLICATION::calculate_dmg($this->artifact_stats["atk"], $this->artifact_stats["crr"], $this->artifact_stats["crd"]);
  533. $this->flag_runes = true;
  534. }
  535. /**
  536. * Calculates the unit's total stats.
  537. *
  538. * Must be called only once before trying to get the stats. Sets the flag
  539. * {@link Unit:$flag_stats} to true.
  540. */
  541. private function load_stats(){
  542. if (! $this->flag_buildings){
  543. $this->load_buildings();
  544. }
  545. if (! $this->flag_runes){
  546. $this->load_runes();
  547. }
  548. $keys = ["atk", "def", "hp", "spd", "crr", "crd", "res", "acc", "ehp", "dmg"];
  549. foreach ($keys as $key){
  550. $this->stats[$key] = $this->base_stats[$key] + $this->rune_stats[$key] + $this->artifact_stats[$key] + $this->building_stats[$key];
  551. }
  552. $this->flag_stats = true;
  553. }
  554. /**
  555. * Loads the unit teams into the entity.
  556. *
  557. * Must be called only once before trying to get the teams. Sets the flag
  558. * {@link Unit:$flag_teams} to true.
  559. */
  560. private function load_teams(){
  561. $statement = get_context()->get_db()->prepare("
  562. SELECT DISTINCT team.id AS id
  563. FROM
  564. team,
  565. team_unit
  566. WHERE
  567. team.player = :player AND
  568. team.id = team_unit.team AND
  569. team_unit.unit = :unit;
  570. ");
  571. $statement->bindValue(':player', $this->player, SQLITE3_TEXT);
  572. $statement->bindValue(':unit', $this->id, SQLITE3_TEXT);
  573. $q = $statement->execute();
  574. while ($r = $q->fetchArray(SQLITE3_ASSOC)){
  575. array_push($this->teams, new Team($r["id"], false));
  576. }
  577. $this->flag_teams = true;
  578. }
  579. /**
  580. * Calculates the stat increase by a rune property.
  581. *
  582. * @param string $stat Stat type.
  583. * @param int $value Stat value.
  584. * @param int $value Stat increase value.
  585. */
  586. private function sum_rune_stat($stat, $value){
  587. switch ($stat){
  588. case RUNE_STAT_ID::ATK:
  589. $this->rune_stats["atk"] += $value;
  590. break;
  591. case RUNE_STAT_ID::DEF:
  592. $this->rune_stats["def"] += $value;
  593. break;
  594. case RUNE_STAT_ID::HP:
  595. $this->rune_stats["hp"] += $value;
  596. break;
  597. case RUNE_STAT_ID::SPD:
  598. $this->rune_stats["spd"] += $value;
  599. break;
  600. case RUNE_STAT_ID::CRR:
  601. $this->rune_stats["crr"] += $value;
  602. break;
  603. case RUNE_STAT_ID::CRD:
  604. $this->rune_stats["crd"] += $value;
  605. break;
  606. case RUNE_STAT_ID::ACC:
  607. $this->rune_stats["acc"] += $value;
  608. break;
  609. case RUNE_STAT_ID::RES:
  610. $this->rune_stats["res"] += $value;
  611. break;
  612. case RUNE_STAT_ID::ATK_P:
  613. $this->rune_stats["atk"] += ($this->base_stats["atk"] * $value / 100);
  614. break;
  615. case RUNE_STAT_ID::DEF_P:
  616. $this->rune_stats["def"] += ($this->base_stats["def"] * $value / 100);
  617. break;
  618. case RUNE_STAT_ID::HP_P:
  619. $this->rune_stats["hp"] += ($this->base_stats["hp"] * $value / 100);
  620. break;
  621. }
  622. }
  623. /**
  624. * Checks if the unit skills are completly maxed.
  625. *
  626. * @return bool True if all skills maxed, false otherwise.
  627. */
  628. public function is_fully_skilled(){
  629. if (! $this->flag_skills){
  630. $this->load_skills();
  631. }
  632. $maxed = true;
  633. $skills = $this->monster->get_skills();
  634. for ($i = 0; $i < sizeof($skills); $i ++){
  635. if ($skills[$i]->get_max_level() > $this->skill_levels[$i]){
  636. $maxed = false;
  637. break;
  638. }
  639. }
  640. return $maxed;
  641. }
  642. /**
  643. * Retrieves the owner's player identifier.
  644. *
  645. * @return int Player ID.
  646. */
  647. public function get_player(){
  648. return $this->player;
  649. }
  650. /**
  651. * Retrieves the unit identifier.
  652. *
  653. * @return int Unit ID.
  654. */
  655. public function get_id(){
  656. return $this->id;
  657. }
  658. /**
  659. * Retrieves the identifier of the building the unit is in, if any.
  660. *
  661. * @return int Building ID, null if unit not in building.
  662. */
  663. public function get_building_id(){
  664. return $this->building;
  665. }
  666. /**
  667. * Retrieves the base monster.
  668. *
  669. * @return Monster The base monster.
  670. */
  671. public function get_monster(){
  672. return $this->monster;
  673. }
  674. /**
  675. * Retrieves the unit stars (grade).
  676. *
  677. * @return int Unit stars (1-6).
  678. */
  679. public function get_stars(){
  680. return $this->stars;
  681. }
  682. /**
  683. * Retrieves the unit current level.
  684. *
  685. * @return int Unit level.
  686. */
  687. public function get_level(){
  688. return $this->level;
  689. }
  690. /**
  691. * Retrieves the unit's base stats.
  692. *
  693. * It's an associative array with the following keys:
  694. * atk, def, hp, spd, crr, crd, acc, res, ehp, dmg
  695. *
  696. * @return int[] Unit stats.
  697. */
  698. public function get_base_stats(){
  699. return $this->base_stats;
  700. }
  701. /**
  702. * Retrieves the unit's stats provided by runes.
  703. *
  704. * It's an associative array with the following keys:
  705. * atk, def, hp, spd, crr, crd, acc, res, ehp, dmg
  706. *
  707. * @return int[] Rune stats.
  708. */
  709. public function get_rune_stats(){
  710. if (! $this->flag_runes){
  711. $this->load_runes();
  712. }
  713. return $this->rune_stats;
  714. }
  715. /**
  716. * Retrieves the unit's stats provided by artifacts.
  717. *
  718. * It's an associative array with the following keys:
  719. * atk, def, hp, spd, crr, crd, acc, res, ehp, dmg
  720. * Note that only "atk", "def", "hp", "dmg" and "ehp" can me non-zero.
  721. *
  722. * @return int[] Artifact stats.
  723. */
  724. public function get_artifact_stats(){
  725. if (! $this->flag_runes){
  726. $this->load_runes();
  727. }
  728. return $this->artifact_stats;
  729. }
  730. /**
  731. * Retrieves the unit's stat bonus provided by buildings.
  732. *
  733. * Only building bonuses are considered.
  734. * It's an associative array with the following keys:
  735. * atk, def, hp, spd, crr, crd, acc, res, ehp, dmg
  736. *
  737. * @return int[] Building stats.
  738. */
  739. public function get_building_stats(){
  740. if (! $this->flag_buildings){
  741. $this->load_buildings();
  742. }
  743. return $this->building_stats;
  744. }
  745. /**
  746. * Retrieves the unit's stats.
  747. *
  748. * It's an associative array with the following keys:
  749. * atk, def, hp, spd, crr, crd, acc, res, ehp, dmg
  750. *
  751. * Includes the unit base stats, the runes and artifact increases and the building bonuses.
  752. *
  753. * @return int[] Unit stats.
  754. */
  755. public function get_stats(){
  756. if (! $this->flag_stats){
  757. $this->load_stats();
  758. }
  759. return $this->stats;
  760. }
  761. /**
  762. * Retrieves the total experience earned by the unit.
  763. *
  764. * @return int Total experience.
  765. */
  766. public function get_experience(){
  767. return $this->experience;
  768. }
  769. /**
  770. * Retrieves the total experience earned by the unit since it's level is the current one..
  771. *
  772. * @return int Current level experience.
  773. */
  774. public function get_current_level_experience(){
  775. return $this->exp_gained;
  776. }
  777. /**
  778. * Retrieves the experience being gained by the hour from a building.
  779. *
  780. * @return int Experience by the hour, 0 if not in an exp building.
  781. */
  782. public function get_exp_gain_rate(){
  783. return $this->exp_gain_rate;
  784. }
  785. /**
  786. * Retrieves the current transmogrification identifier.
  787. *
  788. * @return int Transmogification ID, null if none.
  789. */
  790. public function get_costume(){
  791. return $this->costume;
  792. }
  793. /**
  794. * Retrieves the $source the unit was obtained from.
  795. *
  796. * @return Source Unit source.
  797. */
  798. public function get_source(){
  799. if (! $this->flag_source){
  800. $this->load_source();
  801. }
  802. return $this->source;
  803. }
  804. /**
  805. * Gets the date the unit was obtained.
  806. *
  807. * If $format is supplied, a string in the desired format will be returned. If not, the raw
  808. * DateTime object will e returned.
  809. *
  810. * @param string $format A date format (optional).
  811. * @return DateTime | string The raw date, or a formatted version.
  812. */
  813. public function get_creation_time($format = null){
  814. if (null == $format){
  815. return $this->create_time;
  816. }
  817. else{
  818. return $this->create_time->format($format);
  819. }
  820. }
  821. /**
  822. * Retrieves the name if the unit is an homunculus.
  823. *
  824. * @return string Homunculus name, null if not Homunculus.
  825. */
  826. public function get_homunculus_name(){
  827. return $this->homunculus_name;
  828. }
  829. /**
  830. * Checks if the unit is locked.
  831. *
  832. * @return bool True if locked, false if unlocked.
  833. */
  834. public function is_locked(){
  835. return $this->lock;
  836. }
  837. /**
  838. * Retrieves the average rune efficiency.
  839. *
  840. * @return int Average efficiency of the runes.
  841. */
  842. public function get_avg_rune_efficiency(){
  843. if (! $this->flag_runes){
  844. $this->load_runes();
  845. }
  846. return $this->avg_rune_efficiency;
  847. }
  848. /**
  849. * Retrieves the currently equipped runes.
  850. *
  851. * @return Rune[] Equipped runes.
  852. */
  853. public function get_runes(){
  854. if (! $this->flag_runes){
  855. $this->load_runes();
  856. }
  857. return $this->rune;
  858. }
  859. /**
  860. * Retrieves equipped artifacts.
  861. *
  862. * Can be read with the indexes ARTIFACT_TYPE:ELEMENT and ARTIFACT_TYPE:ARCHETYPE.
  863. *
  864. * @see ARTIFACT_TYPE
  865. * @return Artifact[] Equiped artifact array. Null positions if not equipped.
  866. */
  867. public function get_artifacts(){
  868. if (! $this->flag_runes){
  869. $this->load_runes();
  870. }
  871. return [$this->artifact_element, $this->artifact_type];
  872. }
  873. /**
  874. * Retrieves the teams the unit is in.
  875. *
  876. * @return Team[] Teams the unit is in.
  877. */
  878. public function get_teams(){
  879. if (! $this->flag_teams){
  880. $this->load_teams();
  881. }
  882. return $this->teams;
  883. }
  884. /**
  885. * Retrieves the skill levels.
  886. *
  887. * @return int[] Skill levels, ordered by skill slot.
  888. */
  889. public function get_skill_levels(){
  890. if (! $this->flag_skills){
  891. $this->load_skills();
  892. }
  893. return $this->skill_levels;
  894. }
  895. /**
  896. * Retrieves the total experience required for the current level.
  897. *
  898. * @return int Level experience.
  899. */
  900. public function get_experience_level(){
  901. if (! $this->flag_experience){
  902. $this->load_experience();
  903. }
  904. return $this->experience_level;
  905. }
  906. /**
  907. * Retrieves the experience required to level-up.
  908. *
  909. * @return int Experience to level-up.
  910. */
  911. public function get_experience_level_up(){
  912. if (! $this->flag_experience){
  913. $this->load_experience();
  914. }
  915. return $this->experience_level_up;
  916. }
  917. /**
  918. * Checks if the unit is in storage.
  919. *
  920. * @return bool True if in storage, false otherwise.
  921. */
  922. public function is_in_storage(){
  923. if (! $this->flag_storage){
  924. $this->load_storage();
  925. }
  926. return $this->in_storage;
  927. }
  928. /**
  929. * Retrieves the unit's title.
  930. *
  931. * If Homunculus,it will be it's name.
  932. * If awakened, it will be the awakened from name.
  933. * If unawakened, it will be <element> <name>.
  934. *
  935. * @return string The unit's title.
  936. */
  937. public function get_title(){
  938. return $this->title;
  939. }
  940. }