203 lines
6.4 KiB
PHP
203 lines
6.4 KiB
PHP
<?php
|
||
# Date: 03.02.2021 (11:05)
|
||
|
||
namespace Battles;
|
||
|
||
use Battles\Database\Db;
|
||
use Exceptions\GameException;
|
||
|
||
class UserStats extends User
|
||
{
|
||
protected $strength;
|
||
protected $dexterity;
|
||
protected $intuition;
|
||
protected $endurance;
|
||
protected $intelligence;
|
||
protected $wisdom;
|
||
protected $health;
|
||
protected $mana;
|
||
protected $free_stat_points;
|
||
private Models\UserStats $db;
|
||
private const STAT_MAXIMUM_AMOUNT = 40;
|
||
private const ERROR_STAT_IS_MAXIMUM = 'Ошибка: Параметр достиг своего лимита!';
|
||
private const ERROR_STAT_UNKNOWN = 'Ошибка: Неизвестный параметр!';
|
||
|
||
//// Неизменяемые для игрока(!) переменные.
|
||
// Удар кулаком всегда 1-2.
|
||
protected int $minDamage = 1;
|
||
protected int $maxDamage = 2;
|
||
// Природная броня всегда 0.
|
||
// Зачем их три, если во всех формулах она одна?
|
||
protected int $headArmor = 0;
|
||
protected int $chestArmor = 0;
|
||
protected int $legArmor = 0;
|
||
// Динамически рассчитываемые
|
||
protected int $maxHealth;
|
||
protected int $maxMana;
|
||
|
||
/**
|
||
* UserStats constructor.
|
||
*
|
||
* @param $user
|
||
*/
|
||
public function __construct($user)
|
||
{
|
||
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));
|
||
}
|
||
|
||
/**
|
||
* Отдаёт информацию о базовом(!) стате.
|
||
*
|
||
* @param $stat_name - имя стата. Может принимать значения 'strength', 'dexterity', 'intuition',
|
||
* 'endurance', 'intelligence', 'wisdom'.
|
||
* @param int $isMainWindow - переключатель "главного окна". Если включить, дополнительно будет показывать ссылку
|
||
* на повышение стата на 1, при условии наличия свободных очков статов.
|
||
*
|
||
* @return string
|
||
*/
|
||
public function getStat($stat_name, int $isMainWindow = 0): string
|
||
{
|
||
if (!in_array($stat_name, ['strength', 'dexterity', 'intuition', 'endurance', 'intelligence', 'wisdom'])) {
|
||
return self::ERROR_STAT_UNKNOWN;
|
||
}
|
||
if ($this->free_stat_points && $isMainWindow && $this->$stat_name < self::STAT_MAXIMUM_AMOUNT) {
|
||
$this->$stat_name .= " <a href='/main.php?edit=" . mt_rand() . "&ups=$stat_name'>[+]</a>";
|
||
}
|
||
return $this->$stat_name;
|
||
|
||
}
|
||
|
||
/**
|
||
* Повышает один из выбранных статов на 1, но не выше self::STAT_MAXIMUM_AMOUNT при условии наличия свободных очков
|
||
* статов.
|
||
*
|
||
* @param string $stat_name - имя стата. Может принимать значения 'strength', 'dexterity', 'intuition',
|
||
* 'endurance', 'intelligence', 'wisdom'.
|
||
*
|
||
* @throws GameException
|
||
*/
|
||
public function addOnePointToStat(string $stat_name)
|
||
{
|
||
if (!in_array($stat_name, ['strength', 'dexterity', 'intuition', 'endurance', 'intelligence', 'wisdom'])) {
|
||
throw new GameException(self::ERROR_STAT_UNKNOWN);
|
||
}
|
||
if ($this->free_stat_points <= 0 || $this->$stat_name >= self::STAT_MAXIMUM_AMOUNT) {
|
||
throw new GameException(self::ERROR_STAT_IS_MAXIMUM);
|
||
} else {
|
||
$query = "UPDATE users SET {$stat_name} = {$stat_name} + 1, free_stat_points = free_stat_points - 1 WHERE id = ?";
|
||
Db::getInstance()->execute($query, $this->id);
|
||
//$this->db = new \Battles\Models\UserStats(23);
|
||
$this->db->addPoint($stat_name);
|
||
}
|
||
}
|
||
|
||
public function getMaxWeight(): int
|
||
{
|
||
return $this->strength * 4;
|
||
}
|
||
|
||
/**
|
||
* @return mixed
|
||
*/
|
||
public function getHealth()
|
||
{
|
||
return $this->health;
|
||
}
|
||
|
||
/**
|
||
* @return mixed
|
||
*/
|
||
public function getMana()
|
||
{
|
||
return $this->mana;
|
||
}
|
||
|
||
/**
|
||
* @return mixed
|
||
*/
|
||
public function getFreeStatPoints()
|
||
{
|
||
return $this->free_stat_points;
|
||
}
|
||
|
||
/**
|
||
* @return float
|
||
*/
|
||
public function getMaxHealth(): float
|
||
{
|
||
return $this->maxHealth;
|
||
}
|
||
|
||
/**
|
||
* @return float
|
||
*/
|
||
public function getMaxMana(): float
|
||
{
|
||
return $this->maxMana;
|
||
}
|
||
|
||
/**
|
||
* @return int
|
||
*/
|
||
public function getHeadArmor(): int
|
||
{
|
||
return $this->headArmor;
|
||
}
|
||
|
||
/**
|
||
* @return int
|
||
*/
|
||
public function getChestArmor(): int
|
||
{
|
||
return $this->chestArmor;
|
||
}
|
||
|
||
/**
|
||
* @return int
|
||
*/
|
||
public function getLegArmor(): int
|
||
{
|
||
return $this->legArmor;
|
||
}
|
||
|
||
public function getFullStats(): object
|
||
{
|
||
return (new Models\UserStats($this->id))->getFull();
|
||
}
|
||
|
||
public function levelUp(): string
|
||
{
|
||
$this->level += 1;
|
||
$this->free_stat_points += 2;
|
||
$this->saveStats();
|
||
Chat::sendSys('Внимание, вы получили ' . $this->level . 'уровень. Доступны очки распределения параметров.');
|
||
return 'Персонаж перешёл на ' . $this->level . 'уровень.';
|
||
}
|
||
|
||
/** Сохраняет в базу актуальные статы, здоровье, ману, свободные очки статов и уровень.
|
||
*
|
||
*/
|
||
private function saveStats()
|
||
{
|
||
//$this->db->save();
|
||
$query = 'update users set strength = ?, dexterity = ?, intuition = ?, endurance = ?,
|
||
intelligence = ?, wisdom = ?, health = ?, mana = ?, free_stat_points = ?,
|
||
level = ? where id = ?';
|
||
$vals = [
|
||
$this->strength, //set
|
||
$this->dexterity,
|
||
$this->intuition,
|
||
$this->endurance,
|
||
$this->intelligence,
|
||
$this->wisdom,
|
||
$this->health,
|
||
$this->mana,
|
||
$this->free_stat_points,
|
||
$this->level,
|
||
$this->id //where
|
||
];
|
||
Db::getInstance()->execute($query, $vals);
|
||
}
|
||
} |