2021-03-10 21:38:14 +00:00
|
|
|
|
<?php
|
|
|
|
|
# Date: 03.02.2021 (11:05)
|
|
|
|
|
|
|
|
|
|
namespace Battles;
|
|
|
|
|
|
2022-08-09 19:57:43 +00:00
|
|
|
|
use Battles\Models\Inventory;
|
|
|
|
|
use Battles\Models\User\Effects;
|
|
|
|
|
use Battles\Models\User\Stats;
|
2021-03-10 21:38:14 +00:00
|
|
|
|
use Exceptions\GameException;
|
|
|
|
|
|
|
|
|
|
class UserStats extends User
|
|
|
|
|
{
|
2022-08-09 19:57:43 +00:00
|
|
|
|
protected int $id;
|
|
|
|
|
protected int $strength;
|
|
|
|
|
protected int $dexterity;
|
|
|
|
|
protected int $intuition;
|
|
|
|
|
protected int $endurance;
|
|
|
|
|
protected int $intelligence;
|
|
|
|
|
protected int $wisdom;
|
|
|
|
|
protected int $health;
|
|
|
|
|
protected int $mana;
|
2022-12-16 23:20:43 +00:00
|
|
|
|
protected int $freeStatPoints = 0;
|
2022-08-09 19:57:43 +00:00
|
|
|
|
protected int $level;
|
2021-03-10 21:38:14 +00:00
|
|
|
|
private const STAT_MAXIMUM_AMOUNT = 40;
|
|
|
|
|
private const ERROR_STAT_IS_MAXIMUM = 'Ошибка: Параметр достиг своего лимита!';
|
|
|
|
|
private const ERROR_STAT_UNKNOWN = 'Ошибка: Неизвестный параметр!';
|
2022-08-09 19:57:43 +00:00
|
|
|
|
private const STAT_NAMES_ARRAY = ['strength', 'dexterity', 'intuition', 'endurance', 'intelligence', 'wisdom'];
|
2021-03-10 21:38:14 +00:00
|
|
|
|
|
|
|
|
|
//// Неизменяемые для игрока(!) переменные.
|
|
|
|
|
// Удар кулаком всегда 1-2.
|
2021-08-26 14:44:14 +00:00
|
|
|
|
protected int $minDamage = 1;
|
|
|
|
|
protected int $maxDamage = 2;
|
2021-03-10 21:38:14 +00:00
|
|
|
|
// Природная броня всегда 0.
|
2022-08-09 19:57:43 +00:00
|
|
|
|
|
2021-03-10 21:38:14 +00:00
|
|
|
|
// Динамически рассчитываемые
|
2021-08-26 14:44:14 +00:00
|
|
|
|
protected int $maxHealth;
|
|
|
|
|
protected int $maxMana;
|
2021-03-10 21:38:14 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* UserStats constructor.
|
|
|
|
|
*
|
|
|
|
|
* @param $user
|
|
|
|
|
*/
|
|
|
|
|
public function __construct($user)
|
|
|
|
|
{
|
2022-08-09 19:57:43 +00:00
|
|
|
|
|
|
|
|
|
$data = Stats::getAll($user);
|
|
|
|
|
$this->id = $data->id;
|
|
|
|
|
$this->strength = $data->strength;
|
|
|
|
|
$this->dexterity = $data->dexterity;
|
|
|
|
|
$this->intuition = $data->intuition;
|
|
|
|
|
$this->endurance = $data->endurance;
|
|
|
|
|
$this->intelligence = $data->intelligence;
|
|
|
|
|
$this->wisdom = $data->wisdom;
|
|
|
|
|
$this->health = $data->health;
|
|
|
|
|
$this->mana = $data->mana;
|
2022-12-16 23:20:43 +00:00
|
|
|
|
$this->freeStatPoints = $data->free_stat_points;
|
2022-08-09 19:57:43 +00:00
|
|
|
|
$this->level = $data->level;
|
2021-03-10 21:38:14 +00:00
|
|
|
|
parent::__construct($user);
|
|
|
|
|
$this->maxHealth = round(($this->endurance * 3) + ($this->endurance / 2) * ($this->level - 1) + ($this->endurance / 5) * (($this->level - 1) * ($this->level - 2) / 2));
|
|
|
|
|
$this->maxMana = round(($this->wisdom * 3) + ($this->wisdom / 2) * ($this->level - 1) + ($this->wisdom / 5) * (($this->level - 1) * ($this->level - 2) / 2));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Отдаёт информацию о базовом(!) стате.
|
|
|
|
|
*
|
2022-12-16 23:20:43 +00:00
|
|
|
|
* @param string $statName - имя стата. Может принимать значения 'strength', 'dexterity', 'intuition',
|
2022-08-09 19:57:43 +00:00
|
|
|
|
* 'endurance', 'intelligence', 'wisdom'.
|
|
|
|
|
* @param int $isMainWindow - переключатель "главного окна". Если включить, дополнительно будет показывать ссылку
|
|
|
|
|
* на повышение стата на 1, при условии наличия свободных очков статов.
|
2021-03-10 21:38:14 +00:00
|
|
|
|
*
|
|
|
|
|
* @return string
|
2022-08-09 19:57:43 +00:00
|
|
|
|
* @throws GameException
|
2021-03-10 21:38:14 +00:00
|
|
|
|
*/
|
2022-12-16 23:20:43 +00:00
|
|
|
|
public function getStat(string $statName, int $isMainWindow = 0): string
|
2021-03-10 21:38:14 +00:00
|
|
|
|
{
|
2022-12-16 23:20:43 +00:00
|
|
|
|
if (!in_array($statName, self::STAT_NAMES_ARRAY)) {
|
2022-08-09 19:57:43 +00:00
|
|
|
|
throw new GameException(self::ERROR_STAT_UNKNOWN);
|
2021-03-10 21:38:14 +00:00
|
|
|
|
}
|
2022-12-16 23:20:43 +00:00
|
|
|
|
$stat = strval($this->$statName);
|
|
|
|
|
if ($this->freeStatPoints && $isMainWindow && $this->$statName < self::STAT_MAXIMUM_AMOUNT) {
|
2022-08-09 19:57:43 +00:00
|
|
|
|
$rand = strval(mt_rand());
|
2022-12-16 23:20:43 +00:00
|
|
|
|
$stat .= " <a href='/main.php?edit=$rand&ups=$statName'>[+]</a>";
|
2021-03-10 21:38:14 +00:00
|
|
|
|
}
|
2022-08-09 19:57:43 +00:00
|
|
|
|
return $stat;
|
2021-03-10 21:38:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Повышает один из выбранных статов на 1, но не выше self::STAT_MAXIMUM_AMOUNT при условии наличия свободных очков
|
|
|
|
|
* статов.
|
|
|
|
|
*
|
2022-12-16 23:20:43 +00:00
|
|
|
|
* @param string $statName - имя стата. Может принимать значения 'strength', 'dexterity', 'intuition',
|
2021-03-10 21:38:14 +00:00
|
|
|
|
* 'endurance', 'intelligence', 'wisdom'.
|
|
|
|
|
*
|
|
|
|
|
* @throws GameException
|
|
|
|
|
*/
|
2022-12-16 23:20:43 +00:00
|
|
|
|
public function addOnePointToStat(string $statName)
|
2021-03-10 21:38:14 +00:00
|
|
|
|
{
|
2022-12-16 23:20:43 +00:00
|
|
|
|
if (!in_array($statName, self::STAT_NAMES_ARRAY)) {
|
2021-03-10 21:38:14 +00:00
|
|
|
|
throw new GameException(self::ERROR_STAT_UNKNOWN);
|
|
|
|
|
}
|
2022-12-16 23:20:43 +00:00
|
|
|
|
if ($this->freeStatPoints <= 0 || $this->$statName >= self::STAT_MAXIMUM_AMOUNT) {
|
2021-03-10 21:38:14 +00:00
|
|
|
|
throw new GameException(self::ERROR_STAT_IS_MAXIMUM);
|
|
|
|
|
} else {
|
2022-12-16 23:20:43 +00:00
|
|
|
|
Stats::addOne($statName, $this->id);
|
2021-03-10 21:38:14 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-25 16:16:09 +00:00
|
|
|
|
public function getMaxWeight(): int
|
2021-03-10 21:38:14 +00:00
|
|
|
|
{
|
2022-08-09 19:57:43 +00:00
|
|
|
|
return max($this->strength * 5, 50);
|
2021-03-10 21:38:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return mixed
|
|
|
|
|
*/
|
|
|
|
|
public function getHealth()
|
|
|
|
|
{
|
|
|
|
|
return $this->health;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return mixed
|
|
|
|
|
*/
|
|
|
|
|
public function getMana()
|
|
|
|
|
{
|
|
|
|
|
return $this->mana;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return mixed
|
|
|
|
|
*/
|
|
|
|
|
public function getFreeStatPoints()
|
|
|
|
|
{
|
2022-12-16 23:20:43 +00:00
|
|
|
|
return $this->freeStatPoints;
|
2021-03-10 21:38:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return float
|
|
|
|
|
*/
|
|
|
|
|
public function getMaxHealth(): float
|
|
|
|
|
{
|
|
|
|
|
return $this->maxHealth;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return float
|
|
|
|
|
*/
|
|
|
|
|
public function getMaxMana(): float
|
|
|
|
|
{
|
|
|
|
|
return $this->maxMana;
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-25 16:16:09 +00:00
|
|
|
|
public function getFullStats(): object
|
|
|
|
|
{
|
2022-08-09 19:57:43 +00:00
|
|
|
|
$stats = Stats::getAll($this->id);
|
|
|
|
|
$itemBonuses = Inventory::getBonuses($this->id);
|
|
|
|
|
$effectBonuses = Effects::getStatMods($this->id);
|
2022-01-25 16:16:09 +00:00
|
|
|
|
$obj = (object)[];
|
2022-08-09 19:57:43 +00:00
|
|
|
|
foreach (self::STAT_NAMES_ARRAY as $stat) {
|
|
|
|
|
$obj->$stat = max(0, $stats->$stat + $itemBonuses->{'item_' . $stat} + $effectBonuses->{'effect_' . $stat});
|
|
|
|
|
}
|
2022-01-25 16:16:09 +00:00
|
|
|
|
$obj->accuracy = max(0, $itemBonuses->item_accuracy);
|
|
|
|
|
$obj->evasion = max(0, $itemBonuses->item_evasion);
|
|
|
|
|
$obj->criticals = max(0, $itemBonuses->item_criticals);
|
|
|
|
|
$obj->min_physical_damage = max($this->minDamage, $this->minDamage + $itemBonuses->item_min_physical_damage);
|
|
|
|
|
$obj->max_physical_damage = max($this->maxDamage, $this->maxDamage + $itemBonuses->item_max_physical_damage);
|
|
|
|
|
return $obj;
|
2021-03-11 17:43:20 +00:00
|
|
|
|
}
|
2021-03-10 21:38:14 +00:00
|
|
|
|
|
2021-08-26 14:44:14 +00:00
|
|
|
|
public function levelUp(): string
|
|
|
|
|
{
|
|
|
|
|
$this->level += 1;
|
2022-12-16 23:20:43 +00:00
|
|
|
|
$this->freeStatPoints += 2;
|
2022-08-09 19:57:43 +00:00
|
|
|
|
$this->save();
|
2022-12-16 23:20:43 +00:00
|
|
|
|
Chat::sendSys('Внимание, вы получили ' . $this->level . 'уровень. Доступны очки распределения параметров.');
|
2021-08-26 14:44:14 +00:00
|
|
|
|
return 'Персонаж перешёл на ' . $this->level . 'уровень.';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Сохраняет в базу актуальные статы, здоровье, ману, свободные очки статов и уровень.
|
|
|
|
|
*
|
|
|
|
|
*/
|
2022-08-09 19:57:43 +00:00
|
|
|
|
private function save()
|
2021-08-26 14:44:14 +00:00
|
|
|
|
{
|
2022-08-09 19:57:43 +00:00
|
|
|
|
Stats::save([
|
2021-08-26 14:44:14 +00:00
|
|
|
|
$this->strength, //set
|
|
|
|
|
$this->dexterity,
|
|
|
|
|
$this->intuition,
|
|
|
|
|
$this->endurance,
|
|
|
|
|
$this->intelligence,
|
|
|
|
|
$this->wisdom,
|
|
|
|
|
$this->health,
|
|
|
|
|
$this->mana,
|
2022-12-16 23:20:43 +00:00
|
|
|
|
$this->freeStatPoints,
|
2021-08-26 14:44:14 +00:00
|
|
|
|
$this->level,
|
|
|
|
|
$this->id //where
|
2022-08-09 19:57:43 +00:00
|
|
|
|
]);
|
2021-08-26 14:44:14 +00:00
|
|
|
|
}
|
2022-12-16 23:20:43 +00:00
|
|
|
|
}
|