Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
f3e0b73931 | |||
|
6509a796f6 | ||
|
fdaadf69e6 | ||
|
1bf7a40fe9 | ||
|
b652c242c4 | ||
|
54da589f45 | ||
|
7596d115fa | ||
|
d8ccb13873 | ||
|
e4cce2e96e |
51
arena.php
Normal file
51
arena.php
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Арена. Принцип: https://src.liks.pw/lopar/battles-game-test/issues/3
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Battles\Arena;
|
||||||
|
use Battles\Template;
|
||||||
|
|
||||||
|
if (isset($_POST['startTime']) && isset($_POST['teamMembersQuantity'])) {
|
||||||
|
Arena::fight()->addNew((int)$_POST['teamMembersQuantity'], 2, (int)$_POST['startTime']);
|
||||||
|
}
|
||||||
|
if (isset($_POST['fight_id']) && isset($_POST['team_id'])) {
|
||||||
|
Arena::fight()->join((int)$_POST['fight_id'], (int)$_POST['team_id']);
|
||||||
|
}
|
||||||
|
Template::header('Арена');
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php if(Arena::fight()->hasNoPendingFights()): ?>
|
||||||
|
<form method='post' id='newbattle'></form>
|
||||||
|
<H3>Подать заявку на поединок</H3>
|
||||||
|
<label for='startTime'>Начало боя</label>
|
||||||
|
<select name='startTime' id='startTime' form='newbattle'>
|
||||||
|
<option value=1 selected>через 1 минуту</option>
|
||||||
|
<option value=3>через 3 минуты</option>
|
||||||
|
<option value=5>через 5 минут</option>
|
||||||
|
<option value=10>через 10 минут</option>
|
||||||
|
</select>
|
||||||
|
<br><br>
|
||||||
|
<label>Размер команды (1-20)
|
||||||
|
<input type='number' min='1' max='20' name='teamMembersQuantity' form='newbattle' value='5'>
|
||||||
|
</label>
|
||||||
|
<br><br>
|
||||||
|
<input type='submit' value='Подать заявку' form='newbattle'>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?= Arena::fight()->getPendingList() ?>
|
||||||
|
<?php foreach (Arena::fight()->getPendingList() as $row): ?>
|
||||||
|
<!-- !!PLACEHOLDER!! -->
|
||||||
|
<div>
|
||||||
|
User1, User2, User3
|
||||||
|
<form method='post' style='display:inline'>
|
||||||
|
<input type='hidden' name='teamId' value='1'>
|
||||||
|
<input type='submit' value='Я за этих'>
|
||||||
|
</form>
|
||||||
|
<em>против</em>
|
||||||
|
User4, User5, User6
|
||||||
|
<form method='post' style='display:inline'>
|
||||||
|
<input type='hidden' name='teamId' value='2'>
|
||||||
|
<input type='submit' value='Я за этих'>
|
||||||
|
</form>
|
||||||
|
<? endforeach; ?>
|
||||||
|
</div>
|
117
classes/Battles/Arena.php
Normal file
117
classes/Battles/Arena.php
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
<?php
|
||||||
|
# Date: 12.02.2022 (20:33)
|
||||||
|
namespace Battles;
|
||||||
|
|
||||||
|
use Battles\Database\Db;
|
||||||
|
|
||||||
|
class Arena
|
||||||
|
{
|
||||||
|
private int $fight_id;
|
||||||
|
private int $team_id;
|
||||||
|
|
||||||
|
function addNew(int $membersLimit = 5, int $groupsLimit = 2, int $startTime = 3)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
$this->isOnArena() &&
|
||||||
|
$this->hasNoPendingFights() &&
|
||||||
|
$this->hasNoActiveFights() &&
|
||||||
|
in_array($startTime, [1,3,5,10])
|
||||||
|
) {
|
||||||
|
$query1 = 'insert into fights_pending (fight_id, start_time, members_limit, groups_limit) VALUES (?,?,?,?)';
|
||||||
|
$query2 = 'insert into fights_pending_users (fight_id, user_id, team_id) values (?,?,?)';
|
||||||
|
$startTime = strtotime("+{$startTime}minutes");
|
||||||
|
$uid = User::getInstance()->getId();
|
||||||
|
//последовательность важна!
|
||||||
|
Db::getInstance()->execute($query1, [$uid, $startTime, $membersLimit, $groupsLimit]);
|
||||||
|
Db::getInstance()->execute($query2, [$uid, $uid, 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function join(int $fight_id, int $team_id)
|
||||||
|
{
|
||||||
|
$this->fight_id = $fight_id;
|
||||||
|
$this->team_id = $team_id;
|
||||||
|
if (
|
||||||
|
$this->hasNoClanEnemies() &&
|
||||||
|
$this->hasFreeSpace() &&
|
||||||
|
$this->isOnArena() &&
|
||||||
|
$this->hasNoPendingFights() &&
|
||||||
|
$this->hasNoActiveFights()
|
||||||
|
) {
|
||||||
|
$query = 'insert into fights_pending_users (fight_id, user_id, team_id) values (?,?,?)';
|
||||||
|
Db::getInstance()->execute($query, [$fight_id, User::getInstance()->getId(), $team_id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function leave()
|
||||||
|
{
|
||||||
|
// чтобы не вылететь из заявки в момент начала поединка
|
||||||
|
if (
|
||||||
|
$this->hasNoActiveFights() &&
|
||||||
|
!$this->isFightStarter()
|
||||||
|
) {
|
||||||
|
Db::getInstance()->execute('delete from fights_pending_users where user_id = ?', User::getInstance()->getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPendingList(): object
|
||||||
|
{
|
||||||
|
return new \stdClass();
|
||||||
|
/** !!PLACEHOLDER!! */
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function fight(): self
|
||||||
|
{
|
||||||
|
return new self();
|
||||||
|
}
|
||||||
|
|
||||||
|
// проверка на соклана
|
||||||
|
private function hasNoClanEnemies(): bool
|
||||||
|
{
|
||||||
|
$query = 'select user_id from fights_pending_users where fight_id = ? and team_id = ?';
|
||||||
|
$enemies = Db::getInstance()->ofetchAll($query, [$this->fight_id, $this->team_id]);
|
||||||
|
foreach ($enemies as $enemy) {
|
||||||
|
if (User::getInstance()->getClan() && User::getInstance()->getClan() === User::getInstance($enemy->user_id)->getClan()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// проверка на переполнение
|
||||||
|
private function hasFreeSpace(): bool
|
||||||
|
{
|
||||||
|
$query = 'select members_limit, groups_limit from fights_pending where fight_id = ?';
|
||||||
|
$query2 = 'select count(*) from fights_pending_users where fight_id = ? and team_id = ?';
|
||||||
|
$limits = Db::getInstance()->ofetch($query, $this->fight_id);
|
||||||
|
$currentUsers = Db::getInstance()->fetchColumn($query2, [$this->fight_id, $this->team_id]);
|
||||||
|
return $limits->members_limit > $currentUsers && $limits->groups_limit >= $this->team_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// проверка на нахождение в комнате (1 = арена)
|
||||||
|
private function isOnArena(): bool
|
||||||
|
{
|
||||||
|
return User::getInstance()->getRoom() === 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// проверка на нахождение в другой заявке
|
||||||
|
public function hasNoPendingFights(): bool
|
||||||
|
{
|
||||||
|
$query = 'select count(*) from fights_pending_users where user_id = ?';
|
||||||
|
return Db::getInstance()->fetchColumn($query, User::getInstance()->getId()) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// проверка на нахождение в поединке
|
||||||
|
public function hasNoActiveFights(): bool
|
||||||
|
{
|
||||||
|
$query = 'select count(*) from fighters where user_id = ?';
|
||||||
|
return Db::getInstance()->fetchColumn($query, User::getInstance()->getId()) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// проверка на создателя поединка
|
||||||
|
private function isFightStarter(): bool
|
||||||
|
{
|
||||||
|
$query = 'select count(*) from fights_pending_users where user_id = fight_id and user_id = ?';
|
||||||
|
return Db::getInstance()->fetchColumn($query, User::getInstance()->getId()) > 0;
|
||||||
|
}
|
||||||
|
}
|
@ -74,7 +74,7 @@ class Db
|
|||||||
// Allows the user to retrieve results using a
|
// Allows the user to retrieve results using a
|
||||||
// column from the results as a key for the array
|
// column from the results as a key for the array
|
||||||
if (!is_null($key) && $results[0][$key]) {
|
if (!is_null($key) && $results[0][$key]) {
|
||||||
$keyed_results = array();
|
$keyed_results = [];
|
||||||
foreach ($results as $result) {
|
foreach ($results as $result) {
|
||||||
$keyed_results[$result[$key]] = $result;
|
$keyed_results[$result[$key]] = $result;
|
||||||
}
|
}
|
||||||
@ -94,7 +94,7 @@ class Db
|
|||||||
return $stmt->fetch(PDO::FETCH_OBJ);
|
return $stmt->fetch(PDO::FETCH_OBJ);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function ofetchAll($query, $values = null, $key = null): object
|
public function ofetchAll($query, $values = null)
|
||||||
{
|
{
|
||||||
if (is_null($values)) {
|
if (is_null($values)) {
|
||||||
$values = [];
|
$values = [];
|
||||||
@ -102,18 +102,7 @@ class Db
|
|||||||
$values = [$values];
|
$values = [$values];
|
||||||
}
|
}
|
||||||
$stmt = $this->execute($query, $values);
|
$stmt = $this->execute($query, $values);
|
||||||
$results = $stmt->fetchAll(PDO::FETCH_OBJ);
|
return $stmt->fetchAll(PDO::FETCH_OBJ);
|
||||||
|
|
||||||
// Allows the user to retrieve results using a
|
|
||||||
// column from the results as a key for the array
|
|
||||||
if (!is_null($key) && $results[0][$key]) {
|
|
||||||
$keyed_results = (object)[];
|
|
||||||
foreach ($results as $result) {
|
|
||||||
$keyed_results->$result[$key] = $result;
|
|
||||||
}
|
|
||||||
$results = $keyed_results;
|
|
||||||
}
|
|
||||||
return $results;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function lastInsertId()
|
public function lastInsertId()
|
||||||
|
142
classes/Battles/Fight.php
Normal file
142
classes/Battles/Fight.php
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Battles;
|
||||||
|
|
||||||
|
use Battles\Database\Db;
|
||||||
|
|
||||||
|
class Fight
|
||||||
|
{
|
||||||
|
public static Fight $current;
|
||||||
|
private $db;
|
||||||
|
private \DateTimeImmutable $timer;
|
||||||
|
public const MELEE_ATTACK = 1;
|
||||||
|
public const RANGED_ATTACK = 2;
|
||||||
|
public const USE_MAGIC = 3;
|
||||||
|
public const MOVE = 4;
|
||||||
|
public const FLEE = 5;
|
||||||
|
public const PASS = 0;
|
||||||
|
private int $turn_timeout;
|
||||||
|
|
||||||
|
public function init($fighters)
|
||||||
|
{
|
||||||
|
$defaultRow = 2;
|
||||||
|
$defaultTimer = $this->timer->format('U');
|
||||||
|
$query = 'insert into fighters (
|
||||||
|
user_id,
|
||||||
|
strength,
|
||||||
|
dexterity,
|
||||||
|
intuition,
|
||||||
|
endurance,
|
||||||
|
intelligence,
|
||||||
|
wisdom,
|
||||||
|
accuracy,
|
||||||
|
evasion,
|
||||||
|
criticals,
|
||||||
|
health,
|
||||||
|
max_health,
|
||||||
|
mana,
|
||||||
|
max_mana,
|
||||||
|
melee_min,
|
||||||
|
melee_max,
|
||||||
|
battle_id,
|
||||||
|
team_id,
|
||||||
|
row_id,
|
||||||
|
turn_timeout
|
||||||
|
) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)';
|
||||||
|
$i = 1;
|
||||||
|
$mergedOptions = [];
|
||||||
|
foreach ($fighters as $fighter) {
|
||||||
|
$statsObj = new UserStats($fighter->user_id);
|
||||||
|
$stats = $statsObj->getFullStats();
|
||||||
|
$options[$i] = [
|
||||||
|
$fighter->user_id,
|
||||||
|
$stats->strength,
|
||||||
|
$stats->dexterity,
|
||||||
|
$stats->intuition,
|
||||||
|
$stats->endurance,
|
||||||
|
$stats->intelligence,
|
||||||
|
$stats->wisdom,
|
||||||
|
$stats->accuracy,
|
||||||
|
$stats->evasion,
|
||||||
|
$stats->criticals,
|
||||||
|
$statsObj->getHealth(),
|
||||||
|
$statsObj->getMaxHealth(),
|
||||||
|
$statsObj->getMana(),
|
||||||
|
$statsObj->getMaxMana(),
|
||||||
|
$stats->min_physical_damage,
|
||||||
|
$stats->max_physical_damage,
|
||||||
|
$fighter->fight_id,
|
||||||
|
$fighter->team_id,
|
||||||
|
$defaultRow,
|
||||||
|
$defaultTimer,
|
||||||
|
];
|
||||||
|
if ($i > 1) {
|
||||||
|
$query .= ', (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)';
|
||||||
|
$mergedOptions = array_merge_recursive($mergedOptions, $options[$i]);
|
||||||
|
}
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
Db::getInstance()->execute($query, $mergedOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function playerTurn(int $action, int $uid): void
|
||||||
|
{
|
||||||
|
// Перед ходом проверить, а жив ли ты вообще?
|
||||||
|
if (empty($this->turn_timeout)) {
|
||||||
|
$this->turn_timeout = $this->db->querySingle('select turn_timeout from fighters where uid = ' . $uid);
|
||||||
|
}
|
||||||
|
$now = date('U');
|
||||||
|
|
||||||
|
/* select from last_turn_time and look at $now_plus_3_minutes - if ok, continue, if no, do nothing */
|
||||||
|
if ($now > $this->turn_timeout && !in_array($action, [self::MELEE_ATTACK, self::RANGED_ATTACK, self::USE_MAGIC, self::MOVE, self::PASS, self::FLEE])) {
|
||||||
|
$action = self::PASS;
|
||||||
|
$stmt_update_timer = $this->db->prepare('update fighters set last_turn_time = ? where uid = ?');
|
||||||
|
$stmt_update_timer->bindValue(1, date('U', strtotime('+3 minute')));
|
||||||
|
$stmt_update_timer->bindValue(2, $uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($action === self::MELEE_ATTACK) {
|
||||||
|
//Выполнимо только с клетки 1, только по вражеской клетке 1.
|
||||||
|
//Выполнимо по клетке 2, если клетка 1 пуста _у всех сторон_;
|
||||||
|
//Выполнимо по клетке 3, если клетка 2 пуста _у всех сторон_;
|
||||||
|
//Стоя на клетке 2 при пустой клетке 1 - атака невозможна!
|
||||||
|
echo 'Melee!';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($action === self::RANGED_ATTACK) {
|
||||||
|
//С клетки 1 атака на вражеские клетки 1 и 2;
|
||||||
|
//С клетки 2 атака на свою клетку 1 и вражескую клетку 1;
|
||||||
|
//С клетки 2 атака на вражескую 2, только если пустая клетка 1, либо нет клеток 1 _ни у одной из сторон_.
|
||||||
|
echo 'Ranged!';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($action === self::USE_MAGIC) {
|
||||||
|
//Достаёт кого угодно откуда угодно в любых обстоятельствах.
|
||||||
|
//ОЧЕНЬ внимательно проверять цель. Случайный хил трупа вызовёт апокалипсис в логике.
|
||||||
|
echo '!MAGIC!';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($action === self::MOVE) {
|
||||||
|
//клетка 1 - ближний ряд, только шаг назад
|
||||||
|
//клетка 2 - средний ряд, вперёд или назад
|
||||||
|
//клетка 3 - тыл, только вперёд
|
||||||
|
//В момент хода при соблюдении условий удара может прилететь неблокируемая атака на расстоянии.
|
||||||
|
//Перемещение - это ручной гарантированный уворот от всех летящих физических атак.
|
||||||
|
//Перемещение на пустующую клетку 1 с клетки 2 - это ручной гарантированный уворот всех стоящих на клетке 2 от всех летящих немагических атак по всей клетке.
|
||||||
|
echo 'I have legs!!';
|
||||||
|
}
|
||||||
|
if ($action === self::FLEE) {
|
||||||
|
//побег из боя, только с клетки 3.
|
||||||
|
echo 'Help me, mommy!';
|
||||||
|
}
|
||||||
|
if ($action === self::PASS) {
|
||||||
|
//Пропуск хода.
|
||||||
|
echo 'I pass this turn.';
|
||||||
|
}
|
||||||
|
|
||||||
|
// ПИСАТЬ РЕЗУЛЬТАТ ХОДА ТОЛЬКО ПОСЛЕ ПОВТОРНОЙ ПРОВЕРКИ НА НАЛИЧИЕ ПРОТИВНИКА - ОН МОГ УСПЕТЬ ОТОЙТИ!
|
||||||
|
// !!ИЛИ УМЕРЕТЬ!!
|
||||||
|
$stmt_update_timer->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
127
classes/Battles/Fight/PhysicalDamage.php
Normal file
127
classes/Battles/Fight/PhysicalDamage.php
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Battles\Fight;
|
||||||
|
|
||||||
|
class PhysicalDamage
|
||||||
|
{
|
||||||
|
const BASE_STAT = 10;
|
||||||
|
|
||||||
|
private function rangeCheck(int $var, int $min, int $max = null): bool
|
||||||
|
{
|
||||||
|
if (is_null($max)) {
|
||||||
|
if ($var > $min) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($var > $min && $var <= $max) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Бонус 1 очко выше 10: +5% профильного урона.
|
||||||
|
* Штраф 1 очко ниже 10: -10% профильного урона.
|
||||||
|
* @param int $stat
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
private function statDamageModificator(int $stat): int
|
||||||
|
{
|
||||||
|
$bonus = ($stat - self::BASE_STAT) * 5;
|
||||||
|
if ($bonus < 0) {
|
||||||
|
$bonus *= 2;
|
||||||
|
}
|
||||||
|
return $bonus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Бонус 1 очко выше 10: +1% шанса крита.
|
||||||
|
* Штраф 1 очко ниже 10: -2% шанса крита.
|
||||||
|
* @param int $stat
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
private function statCriticalsModificator(int $stat): int
|
||||||
|
{
|
||||||
|
$bonus = ($stat - self::BASE_STAT);
|
||||||
|
if ($bonus < 0) {
|
||||||
|
$bonus *= 2;
|
||||||
|
}
|
||||||
|
return $bonus;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Рассчёт типа удара в зависимости от параметров.
|
||||||
|
* Значения проверок смещаются в зависимости от разницы двух параметров.
|
||||||
|
* @param int $player_accuracy
|
||||||
|
* @param int $enemy_evasion
|
||||||
|
* @param int $player_criticals
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function attack(int $player_accuracy, int $enemy_evasion, int $player_criticals): string
|
||||||
|
{
|
||||||
|
$result = '';
|
||||||
|
$d100 = mt_rand(0, 100);
|
||||||
|
$mf = $player_accuracy - $enemy_evasion;
|
||||||
|
if ($this->rangeCheck($d100, min(1, 0 - $mf), 15 - $mf)) {
|
||||||
|
$result = 'selfharm';
|
||||||
|
}
|
||||||
|
if ($this->rangeCheck($d100, min(1, 16 - $mf), 50 - $mf)) {
|
||||||
|
$result = 'miss';
|
||||||
|
}
|
||||||
|
if ($this->rangeCheck($d100, 51 - $mf, 100 - $mf - $player_criticals)) {
|
||||||
|
$result = 'hit';
|
||||||
|
}
|
||||||
|
if ($this->rangeCheck($d100, 101 - $mf - $player_criticals)) {
|
||||||
|
$result = 'crit';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Рассчёт базового урона до применения модификаторов.
|
||||||
|
* Если урон меньше равно нулю, получается удар в 20% от минималки.
|
||||||
|
* Учитывая удар кулака 1-2, значения прибавляются к $min и $max в формуле.
|
||||||
|
* @param int $min минимальный урон
|
||||||
|
* @param int $max максимальный урон
|
||||||
|
* @param int $enemyDefence защита противника
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
protected function baseDamage(int $min, int $max, int $enemyDefence): int
|
||||||
|
{
|
||||||
|
return max(mt_rand(1 + $min, 2 + $max) - $enemyDefence, intval(round((1 + $min) * (20 / 100))));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param object $attacker [str,dex,intu,accuracy,crit,min_dmg,max_dmg]
|
||||||
|
* @param object $defender [evasion,defence]
|
||||||
|
* @param int $type тип удара: ближний бой (1), дальний бой (2).
|
||||||
|
* @return object
|
||||||
|
*/
|
||||||
|
public function hit(object $attacker, object $defender, int $type): object
|
||||||
|
{
|
||||||
|
$result = (object)[];
|
||||||
|
$attackType = $this->attack($attacker->accuracy, $defender->evasion, $attacker->criticals + $this->statCriticalsModificator($attacker->intuition));
|
||||||
|
if ($attackType === 'miss') {
|
||||||
|
$result->damage = 0;
|
||||||
|
$result->attackType = $attackType;
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
$damage = $this->baseDamage($attacker->min_damage, $attacker->max_damage, $defender->defence);
|
||||||
|
$critDamageMultiplier = $attackType === 'crit' ? 2 : 1;
|
||||||
|
if ($type === 1) {
|
||||||
|
$damage = $damage * ($this->statDamageModificator($attacker->strength) / 100);
|
||||||
|
}
|
||||||
|
if ($type === 2) {
|
||||||
|
$damage = $damage * ($this->statDamageModificator($attacker->dexterity) / 100);
|
||||||
|
}
|
||||||
|
$damage = $damage * $critDamageMultiplier;
|
||||||
|
|
||||||
|
$result->damage = $damage;
|
||||||
|
$result->attackType = $attackType;
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
@ -28,7 +28,6 @@ class User
|
|||||||
|
|
||||||
// Пока несуществующие, для совместимости.
|
// Пока несуществующие, для совместимости.
|
||||||
protected int $experience = 0;
|
protected int $experience = 0;
|
||||||
protected int $battle = 0;
|
|
||||||
protected int $in_tower = 0; // Скорее башню похороним чем запустим...
|
protected int $in_tower = 0; // Скорее башню похороним чем запустим...
|
||||||
protected int $zayavka = 0;
|
protected int $zayavka = 0;
|
||||||
|
|
||||||
@ -77,6 +76,7 @@ class User
|
|||||||
{
|
{
|
||||||
if (Db::getInstance()->fetchColumn('SELECT 1 FROM users_effects WHERE owner_id = ? AND type = ?', [$userId, $type])) {
|
if (Db::getInstance()->fetchColumn('SELECT 1 FROM users_effects WHERE owner_id = ? AND type = ?', [$userId, $type])) {
|
||||||
Db::getInstance()->execute('DELETE FROM users_effects WHERE owner_id = ? AND type = ?', [$userId, $type]);
|
Db::getInstance()->execute('DELETE FROM users_effects WHERE owner_id = ? AND type = ?', [$userId, $type]);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -223,7 +223,7 @@ class User
|
|||||||
|
|
||||||
public function getBattle(): int
|
public function getBattle(): int
|
||||||
{
|
{
|
||||||
return $this->battle;
|
return Arena::fight()->hasNoActiveFights();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getInTower(): int
|
public function getInTower(): int
|
||||||
|
Loading…
Reference in New Issue
Block a user