* @license https://www.gnu.org/licenses/gpl-3.0.en.html GNU General Public License V3 * @package SWDB */ require_once(PATH::ENTITY . "Entity.php"); require_once(PATH::ENTITY . "Unit.php"); require_once(PATH::ENTITY . "Monster.php"); require_once(PATH::ENTITY . "Rune.php"); require_once(PATH::ENTITY . "Enchantment.php"); require_once(PATH::ENTITY . "Item.php"); require_once(PATH::ENTITY . "Area.php"); require_once(PATH::ENTITY . "Rune_Set.php"); /** * A run. * * Represent a saved run in a playable area. * * @category Entity */ class Run extends Entity{ /** * @var int Owner's player identifier. */ private $player; /** * @var int Run identifier. */ private $id; /** * @var DateTime Run start times. */ private $start_time; /** * @var Area Area. */ private $area; /** * @var int Stage. */ private $stage; /** * @var int Difficulty (only scenario and dimension hole) */ private $difficulty; /** * @var bool Won or lost run. */ private $win; /** * @var int Clear time, milliseconds. */ private $time; /** * @var bool Indicates if a frind/mentor helped. */ private $helper; /** * @var int Score in battles that are rated (WB, rift dungeons...). */ private $score; /** * @var String Rank in battles that are rated (WB, rift dungeons...). */ private $rank; /** * @var bool Internal flag to check if the run parti has been loaded. */ private $flag_party = false; /** * @var Unit[]|Monster[] Units or monsters used. * If the unit is still owned, it will be a instance of Unit. * If not, it will be a instance of monster. */ private $party = []; /** * @var int ID of the leader unit or monster. */ private $leader; /** * @var int[] List of IDs of the frontline units or monsters. */ private $frontline = []; /** * @var bool Internal flag to check if run rewards have been loaded. */ private $flag_reward = false; /** * @var array List of run rewards. */ private $reward = [ "mana" => 0, "energy" => 0, "crystal" => 0, "honor_points" => 0, "guild_points" => 0, "item" => [], "monster" => null, "sd" => null, "monster_piece" => [], "shapeshifting" => 0, "rune" => [], "enchantment" => [], "artifact" => [] ]; /** * Constructor. * * Searches the database and retrieves the information about the * run, populating it and it's items. * * @param int $id Run identifier. */ public function __construct($id){ $statement = get_context()->get_db()->prepare(" SELECT id, player, dtime, area_type, area, stage, difficulty, win, time, mana, energy, crystal, honor_points, guild_points, helper, score, rank FROM run WHERE id = :id; "); $statement->bindValue(':id', $id, SQLITE3_TEXT); $r = $statement->execute()->fetchArray(SQLITE3_ASSOC); if ($r){ $this->id = $r["id"]; $this->player = $r["player"]; $this->start_time = new Datetime(); $this->start_time->setTimestamp($r["dtime"]); $this->area = new Area($r["area"], $r["area_type"]); $this->stage = $r["stage"]; $this->difficulty = $r["difficulty"]; $this->win = filter_var($r["win"], FILTER_VALIDATE_BOOLEAN); $this->time = $r["time"]; $this->reward["mana"] = $r["mana"]; $this->reward["energy"] = $r["energy"]; $this->reward["crystal"] = $r["crystal"]; $this->reward["honor_points"] = $r["honor_points"]; $this->reward["guild_points"] = $r["guild_points"]; $this->helper = filter_var($r["helper"], FILTER_VALIDATE_BOOLEAN); $this->score = $r["score"]; $this->rank = $r["rank"]; } } private function load_party(){ $statement = get_context()->get_db()->prepare(" SELECT unit, monster, (SELECT count(id) FROM unit WHERE unit.id = run_party.unit) AS owned, leader, front FROM run_party WHERE run = :run ORDER BY front DESC, leader DESC; "); $statement->bindValue(':run', $this->id, SQLITE3_TEXT); $q = $statement->execute(); while ($r = $q->fetchArray(SQLITE3_ASSOC)){ if ($r["owned"] > 0){ array_push($this->party, new Unit($r["unit"], false)); } else{ array_push($this->party, new Monster($r["monster"], false)); } if ($r["leader"] == 1){ $this->leader = $r["unit"]; } if ($r["front"] == 1){ array_push($this->frontline, $r["unit"]); } } $this->flag_party = true; } private function load_reward(){ $statement = get_context()->get_db()->prepare(" SELECT item, amount FROM run_drop_item WHERE run = :run; "); $statement->bindValue(':run', $this->id, SQLITE3_TEXT); $q = $statement->execute(); while ($r = $q->fetchArray(SQLITE3_ASSOC)){ $item = [ "inventory" => new Inventory($r["item"]), "amount" => $r["amount"] ]; array_push($this->reward["item"], $item); } $statement = get_context()->get_db()->prepare(" SELECT unit AS monster FROM run_drop_unit WHERE run = :run; "); $statement->bindValue(':run', $this->id, SQLITE3_TEXT); $q = $statement->execute(); while ($r = $q->fetchArray(SQLITE3_ASSOC)){ $this->reward["monster"] = new Monster($r["monster"]); } $statement = get_context()->get_db()->prepare(" SELECT unit AS monster FROM run_drop_sd WHERE run = :run; "); $statement->bindValue(':run', $this->id, SQLITE3_TEXT); $q = $statement->execute(); while ($r = $q->fetchArray(SQLITE3_ASSOC)){ $this->reward["sd"] = new Monster($r["monster"]); } $statement = get_context()->get_db()->prepare(" SELECT unit AS monster, amount FROM run_drop_unit_pieces WHERE run = :run; "); $statement->bindValue(':run', $this->id, SQLITE3_TEXT); $q = $statement->execute(); while ($r = $q->fetchArray(SQLITE3_ASSOC)){ $i = [ "monster" => new Monster($r["monster"]), "amount" => $r["amount"] ]; array_push($this->reward["monster_piece"], $i); } $statement = get_context()->get_db()->prepare(" SELECT amount FROM run_drop_shapeshifting WHERE run = :run; "); $statement->bindValue(':run', $this->id, SQLITE3_TEXT); $q = $statement->execute(); $r = $q->fetchArray(SQLITE3_ASSOC); if ($r){ $this->reward["shapeshifting"] = $r["amount"]; } $statement = get_context()->get_db()->prepare(" SELECT id FROM run_drop_rune WHERE run = :run; "); $statement->bindValue(':run', $this->id, SQLITE3_TEXT); $q = $statement->execute(); while ($r = $q->fetchArray(SQLITE3_ASSOC)){ $rune = new Rune($r["id"]); array_push($this->reward["rune"], $rune); } $statement = get_context()->get_db()->prepare(" SELECT id FROM run_drop_artifact WHERE run = :run; "); $statement->bindValue(':run', $this->id, SQLITE3_TEXT); $q = $statement->execute(); while ($r = $q->fetchArray(SQLITE3_ASSOC)){ $artifact = new Artifact($r["id"]); array_push($this->reward["artifact"], $artifact); } $statement = get_context()->get_db()->prepare(" SELECT id FROM run_drop_enchantment WHERE run = :run; "); $statement->bindValue(':run', $this->id, SQLITE3_TEXT); $q = $statement->execute(); while ($r = $q->fetchArray(SQLITE3_ASSOC)){ $enchantment = new Enchantment($r["id"]); array_push($this->reward["enchantment"], $enchantment); } $this->flag_reward = true; } /** * Retrieves the player identifier. * * @return int Player ID. */ public function get_player(){ return $this->player; } /** * Retrieves the run identifier. * * @return int Run ID. */ public function get_id(){ return $this->id; } /** * Gets the time of the run start. * * If $format is supplied, a string in the desired format will be returned. If not, the raw * DateTime object will e returned. * * @param string $format A date format (optional). * @return DateTime | string The raw date, or a formatted version. */ public function get_start_time($format = null){ if (null == $format){ return $this->start_time; } else{ return $this->start_time->format($format); } } /** * Retrieves the area of the run. * * @return Area Run area. */ public function get_area(){ return $this->area; } /** * Retrieves the stage of the run, if any. * * @return int Stage number, null if none. */ public function get_stage(){ return $this->stage; } /** * Retrieves the difficulty of the run, if any. * * @see DIFFICULTY_ID * @return int Difficulty ID, null if none. */ public function get_difficulty(){ return $this->difficulty; } /** * Checks if the run was won. * * @return bool True if voctory, false otherwise. */ public function is_win(){ return $this->win; } /** * Retrieves the duration of the run in millisecondes. * * @return int Run time. */ public function get_time(){ return $this->time; } /** * Check if a frind or mentor representative's help was used. * * @return bool True if helper included, false otherwise. */ public function had_help(){ return $this->helper; } /** * Retrieves the score of the run. * * @return int Run score. Null if it's not a score based run. */ public function get_score(){ return $this->score; } /** * Retrieves the rank reached on the run. * * @return string Rank, in human readable form. Null if not a rank based run. */ public function get_rank(){ return $this->rank; } /** * Retrieves the party used in the run. If one of the units is not still owned, it will get * the base monster instead. * * @return (Unit|Monster)[] Party units or monsters. */ public function get_party(){ if (! $this->flag_party){ $this->load_party(); } return $this->party; } /** * Retrieves the party leader identifier. If the leader unit is not still owned, it will get * the base monster identifierinstead. * * @return int Leader unit or monster ID. */ public function get_leader(){ if (! $this->flag_party){ $this->load_party(); } return $this->leader; } /** * Retrieves the identifiers of the party members in the frontline. If one of the units is not * still owned, it will get the base monster instead. * * @return int Unit or Monster identifiers. */ public function get_frontline(){ if (! $this->flag_party){ $this->load_party(); } return $this->frontline; } /** * Retrieves the list of rewards from the run reward. * * Here is an example (note that, in most cases, only a few items will be populated for a run): * * [ * "mana" => 2365, // Dropped mana, 0 if none * "energy" => 1, // Dropped energy, 0 if none. * "crystal" => 0, // Dropped crystals, 0 if none. * "honor_points" => 3, // Dropped honor points, 0 if none. * "guild_points" => 8, // Dropped guild points, 0 if none. * "item" => [ // Items dropped, empty if none. * [ // One item. * "inventory" => (Inventory), // Inventory ID. * "amount => 4 // Dropped quantity. * ], * [ // One item. * "inventory" => (Inventory), // Inventory ID. * "amount => 3 // Dropped quantity. * ], * ], * "monster" => (Monster), // Dropped monster instance, null if none. * "sd" => (Monster), // Opened Secret Dungeon monster instance, null if none. * "monster_piece" => [ // Dropped monster pieces. * "monster" => (Monster), // Monster entity * "amount" => 4 // Quantity * ], * "shapeshifting" => 0, // Dropped transmogification stones, 0 if none. * "rune" => [ // Dropped runes, empty if none. * (Rune), // Rune instance. * (Rune), // Rune instance. * (Rune) // Rune instance. * ], * "enchantment" => [ // Dropped enchantments, empty if none. * (Enchantment), // Enchantment instance. * (Enchantment) // Enchantment instance. * ], * "artifact" => [ // Dropped artifacts, empty if none. * (Artifact), // Enchantment instance. * (Artifact), // Artifact instance. * ] * * * @return mixed[] */ public function get_rewards(){ if (! $this->flag_reward){ $this->load_reward(); } return $this->reward; } }