. */ public $title; /** * Constructor. * * Searches the database and retrieves the information about the * monster, populating it and it's items. * * @param int $id Monster identifier. * @param bool $complete If false, query only monster and k_monster. * @global int Player ID. * @global resource Database connection. */ public function __construct($id, $complete = true, $uid = 0){ global $UID; global $db; if ($uid == 0){ $uid = $UID; } $statement = $db->prepare(" SELECT uid, id, building, unit, stars, level, hp, attack, defense, speed, crit_rate, crit_damage, resistance, accuracy, experience, exp_gained, exp_gain_rate, costume, source, create_time, homunculus_name, lock FROM unit WHERE uid = :uid AND id = :id; "); $statement->bindValue(':id', $id, SQLITE3_INTEGER); $statement->bindValue(':uid', $uid, SQLITE3_INTEGER); $r = $statement->execute()->fetchArray(SQLITE3_ASSOC); if ($r){ $this->uid = $r["uid"]; $this->id = $r["id"]; if ($r["building"] != null && $r["building"] > 0){ $this->building = new Building($r["building"]); } if (strlen($r["unit"]) > 0){ $this->unit = new K_Unit($r["unit"], $complete); } $this->stars = $r["stars"]; $this->level = $r["level"]; $this->hp = $r["hp"]; $this->attack = $r["attack"]; $this->defense = $r["defense"]; $this->speed = $r["speed"]; $this->crit_rate = $r["crit_rate"]; $this->crit_damage = $r["crit_damage"]; $this->resistance = $r["resistance"]; $this->accuracy = $r["accuracy"]; $this->experience = $r["experience"]; $this->exp_gained = $r["exp_gained"]; $this->exp_gain_rate = $r["exp_gain_rate"]; $this->costume = $r["costume"]; $this->source = new K_Source($r["source"]); $this->create_time = date_create($r["create_time"]); $this->homunculus_name = $r["homunculus_name"]; if ($complete){ $this->load_stats(); $this->load_teams(); $this->check_storage(); $this->lock = $r["lock"]; $statement = $db->prepare(" SELECT level FROM unit_skill, k_skill WHERE k_skill.id = unit_skill.skill AND unit = :unit ORDER BY slot; "); $statement->bindValue(':unit', $this->id, SQLITE3_INTEGER); $q = $statement->execute(); while ($r = $q->fetchArray(SQLITE3_ASSOC)){ array_push($this->skill_levels, $r["level"]); } $statement = $db->prepare(" SELECT exp FROM k_experience WHERE stars = :stars AND level = :level; "); $statement->bindValue(':stars', $this->stars, SQLITE3_INTEGER); $statement->bindValue(':level', $this->level, SQLITE3_INTEGER); $r = $statement->execute()->fetchArray(SQLITE3_ASSOC); if ($r){ $this->experience_level = $r["exp"]; $this->experience_level_up = $r["exp"] - $this->exp_gained; } } if ($this->unit->homunculus){ $this->title = $this->homunculus_name; } else{ $this->title = $this->unit->title; } } } /** * Checks if the monster is in storage and sets {@see $in_storage} to * true or false. * * @global int Player ID. * @global resource Database connection. */ public function check_storage(){ global $UID; global $db; $statement = $db->prepare(" SELECT 1 FROM unit, building WHERE unit.id = :id AND unit.uid = :uid AND building.uid = :uid AND unit.building = building.id AND building.building = :building; "); $statement->bindValue(':id', $this->id, SQLITE3_INTEGER); $statement->bindValue(':uid', $UID, SQLITE3_INTEGER); $statement->bindValue(':building', BUILDING_ID::MONSTER_STORAGE, SQLITE3_INTEGER); $r = $statement->execute()->fetchArray(SQLITE3_ASSOC); if ($r){ $this->in_storage = true; } else{ $this->in_storage = false; } } /** * Calculates the stats gained from runes, artifacts and buildings. * Calculates the totalls and the effective stats. * * @gobal int User ID. * @gobal int Game mode (Normal/RTA). * @global resource Database connection. */ public function load_stats(){ global $UID; global $MODE; global $db; // Runes $this->rune = []; $statement = $db->prepare(" SELECT rune FROM unit_rune WHERE unit = :unit AND rta = :rta; "); $statement->bindValue(':unit', $this->id, SQLITE3_INTEGER); $statement->bindValue(':rta', $MODE, SQLITE3_INTEGER); $q = $statement->execute(); while ($r = $q->fetchArray(SQLITE3_ASSOC)){ array_push($this->rune, new Rune($r["rune"])); } foreach ($this->rune as $rune){ foreach ($rune->stats as $stat){ $this->sum_rune_stat($stat->stat, $stat->value + $stat->grind); } } $this->rune_attack = ceil($this->rune_attack); $this->rune_defense = ceil($this->rune_defense); $this->rune_hp = ceil($this->rune_hp); // Artifacts $statement = $db->prepare(" SELECT id FROM artifact WHERE assigned_to = :assigned; "); $statement->bindValue(':assigned', $this->id, SQLITE3_INTEGER); $q = $statement->execute(); while ($r = $q->fetchArray(SQLITE3_ASSOC)){ $artifact = new Artifact($r["id"]); if ($artifact->type == ARTIFACT_TYPE::ARCHETYPE){ $this->artifact_type = $artifact; } else{ $this->artifact_element = $artifact; } switch($artifact->main_stat){ case ARTIFACT_STAT_ID::ATK: $this->artifact_attack += $artifact->main_stat_value; break; case ARTIFACT_STAT_ID::DEF: $this->artifact_defense += $artifact->main_stat_value; break; case ARTIFACT_STAT_ID::HP: $this->artifact_hp += $artifact->main_stat_value; break; } } // Buildings $statement = $db->prepare(" SELECT affected_stat, bonus, element FROM k_decoration, k_decoration_level, decoration WHERE decoration.uid = :uid AND k_decoration.id = decoration.decoration AND decoration.decoration = k_decoration_level.decoration AND decoration.level = k_decoration_level.level AND area = :area AND affected_stat IN (:stat_atk, :stat_def, :stat_hp, :stat_spd, :stat_crd); "); $statement->bindValue(':uid', $UID, SQLITE3_INTEGER); $statement->bindValue(':area', EFFECT_AREA_ID::GENERAL, SQLITE3_INTEGER); $statement->bindValue(':stat_atk', STAT_ID::ATK, SQLITE3_INTEGER); $statement->bindValue(':stat_def', STAT_ID::DEF, SQLITE3_INTEGER); $statement->bindValue(':stat_hp', STAT_ID::HP, SQLITE3_INTEGER); $statement->bindValue(':stat_spd', STAT_ID::SPD, SQLITE3_INTEGER); $statement->bindValue(':stat_crd', STAT_ID::CRIT_DMG, SQLITE3_INTEGER); $q = $statement->execute(); while ($r = $q->fetchArray(SQLITE3_ASSOC)){ switch($r["affected_stat"]){ case STAT_ID::DEF: $this->building_defense += ($this->defense * $r["bonus"] / 100); break; case STAT_ID::HP: $this->building_hp += ($this->hp * $r["bonus"] / 100); break; case STAT_ID::SPD: $this->building_speed += ($this->speed * $r["bonus"] / 100); break; case STAT_ID::CRIT_DMG: $this->building_crit_damage += $r["bonus"]; break; case STAT_ID::ATK: if(strlen($r["element"]) > 0 && $r["element"] == $this->unit->element){ $this->building_attack += ($this->attack * $r["bonus"] / 100); } else{ $this->building_attack += ($this->attack * $r["bonus"] / 100); } break; } } $this->building_attack = ceil($this->building_attack); $this->building_defense = ceil($this->building_defense); $this->building_hp = ceil($this->building_hp); $this->building_speed = ceil($this->building_speed); $this->building_crit_damage = ceil($this->building_crit_damage); // Totals $this->total_hp = $this->hp + $this->rune_hp + $this->building_hp + $this->artifact_hp; $this->total_attack = $this->attack + $this->rune_attack + $this->building_attack + $this->artifact_attack; $this->total_defense = $this->defense + $this->rune_defense + $this->building_defense + $this->artifact_defense; $this->total_speed = $this->speed + $this->rune_speed + $this->building_speed; $this->total_crit_rate = $this->crit_rate + $this->rune_crit_rate + $this->building_crit_rate; $this->total_crit_damage = $this->crit_damage + $this->rune_crit_damage + $this->building_crit_damage; $this->total_accuracy = $this->accuracy + $this->rune_accuracy + $this->building_accuracy; $this->total_resistance = $this->resistance + $this->rune_resistance + $this->building_resistance; // Effective stats $ehp = 0; $edmg = 0; // Calculate effective_hp $hp = $this->total_hp; $def = $this->total_defense; $ehp = ceil(((($def * 3.5) + 1140) * $hp) / 1000); $this->effective_hp = $ehp; // Calculate effective_dmg $atk = $this->total_attack; $crr = $this->total_crit_rate; if ($crr > 100){ $crr = 100; } $crd = $this->total_crit_damage; $edmg = ceil(($atk * (100 - $crr) / 100) + (($atk + ($atk * $crd / 100)) * $crr / 100)); $this->effective_dmg = $edmg; } /** * Loads the {@see teams} array, with the teams the unit is on. * * @global int Player ID. * @global resource Database connection. */ public function load_teams(){ global $UID; global $db; $this->teams = []; $statement = $db->prepare(" SELECT DISTINCT team.id AS id FROM team, team_unit WHERE team.uid = :uid AND team.id = team_unit.team AND team_unit.unit = :unit; "); $statement->bindValue(':uid', $UID, SQLITE3_INTEGER); $statement->bindValue(':unit', $this->id, SQLITE3_INTEGER); $q = $statement->execute(); while ($r = $q->fetchArray(SQLITE3_ASSOC)){ array_push($this->teams, new Team($r["id"], false)); } } /** * Calculates the stat increase by a rune property. * * @param string $stat Stat type. * @param int $value Stat increase value. */ private function sum_rune_stat($stat, $value){ switch ($stat){ case RUNE_STAT_ID::ATK: $this->rune_attack += $value; break; case RUNE_STAT_ID::DEF: $this->rune_defense += $value; break; case RUNE_STAT_ID::HP: $this->rune_hp += $value; break; case RUNE_STAT_ID::SPD: $this->rune_speed += $value; break; case RUNE_STAT_ID::CRR: $this->rune_crit_rate += $value; break; case RUNE_STAT_ID::CRD: $this->rune_crit_damage += $value; break; case RUNE_STAT_ID::ACC: $this->rune_accuracy += $value; break; case RUNE_STAT_ID::RES: $this->rune_resistance += $value; break; case RUNE_STAT_ID::ATK_P: $this->rune_attack += ($this->attack * $value / 100); break; case RUNE_STAT_ID::DEF_P: $this->rune_defense += ($this->defense * $value / 100); break; case RUNE_STAT_ID::HP_P: $this->rune_hp += ($this->hp * $value / 100); break; } } /** * Checks if the unit skills are completly maxed. * * @return bool True if all skills maxed, false otherwise. */ public function are_skills_maxed(){ $maxed = true; for ($i = 0; $i < sizeof($this->unit->skill); $i ++){ if ($this->unit->skill[$i]->max_level > $this->skill_levels[$i]){ $maxed = false; break; } } return $maxed; } } ?>