battles/classes/Battles/InventoryItem.php
Igor Barkov (iwork) 3502904656 Рефакторинг, очистка, работа над ошибками, связанными с базой, отказ от глобальной переменной $user во многих файлах.
Singleton в некоторых местах вместо решения #42.
Новые шаги для решения #16 и #52.
Closes #42.
Closes #32.
Closes #31.
2022-01-27 01:15:33 +02:00

146 lines
7.0 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace Battles;
use Battles\Database\Db;
class InventoryItem extends Item
{
private $present;
private $owner_id;
private const TOO_MANY_ITEMS_IN_SLOTS = 'Критическая ошибка: Переполнение слота!';
private const UNKNOWN_ITEM_TYPE = 'Неизвестный тип предмета!';
private const REQUIREMENTS_NOT_MET = 'Персонаж не соответствует требованиям!';
/**
* InventoryItem constructor.
*
* @param $row
*/
public function __construct($row)
{
parent::__construct($row);
$this->owner_id = $row->owner_id;
$this->present = $row->present;
}
public function printInfo()
{
echo $this->getAllInfo();
if ($this->present) {
echo "<p style='color: maroon; font-style: italic'>Это подарок от $this->present. Вы не можете передать его кому-либо ещё.</p>";
}
}
public function printImage()
{
if (in_array($this->item_type, range(1, 12))) {
echo <<<HTML
<a href=/main.php?edit=1&dress=$this->item_id title='Надеть'>
<img src="/i/sh/$this->image" class="item-wrap-normal" alt="">
</a>
HTML;
} else {
echo <<<IMG
<img src="/i/sh/$this->image" class="item-wrap-normal" alt="">
IMG;
}
}
public function printControls(){
// Для кнопок управления под картинкой.
}
private function dressStatsChecks(): ?string
{
$checkStats = new UserStats($this->owner_id);
$stat = $checkStats->getFullStats();
return
$this->need_strength > $stat->strength
|| $this->need_dexterity > $stat->dexterity
|| $this->need_intuition > $stat->intuition
|| $this->need_endurance > $stat->endurance
|| $this->need_intelligence > $stat->intelligence
|| $this->need_wisdom > $stat->wisdom
? true : null;
}
/**
* Одевание предмета из инвентаря в слот.
* @return bool|string
*/
public function dressItem()
{
$itemInSlot = [];
if ($this->dressStatsChecks()) {
return self::REQUIREMENTS_NOT_MET;
}
// считаем сколько ОДЕТЫХ предметов в слоте в который мы хотим одеть предмет. 1=просто вещь 1-3=шашни с кольцами
// Count добавленный в первый запрос возвращает одну строку в любом случае.
// fetch возвращает одну строку в любом случае.
$weared = Db::getInstance()->ofetchAll('SELECT dressed_slot FROM inventory WHERE dressed_slot != 0 AND item_type = ? AND owner_id = ?', [$this->item_type, $this->owner_id]);
$wearedCount = Db::getInstance()->ofetch('select count(dressed_slot) as c from inventory where dressed_slot !=0 and item_type = ? and owner_id = ?', [$this->item_type, $this->owner_id]);
// Если в слоте есть предмет(ы), забиваем их массив одетых в слот предметов.
if ($wearedCount) {
foreach ($weared as $item) {
$itemInSlot[] = $item->dressed_slot;
}
}
if (in_array($this->item_type, [
self::ITEM_TYPE_HELMET, self::ITEM_TYPE_ARMOR, self::ITEM_TYPE_LEGS, self::ITEM_TYPE_BOOTS,
self::ITEM_TYPE_GLOVES, self::ITEM_TYPE_WEAPON, self::ITEM_TYPE_SHIELD, self::ITEM_TYPE_BELT,
self::ITEM_TYPE_AMULET,
])) {
//работаем с нормальными слотами
if ($wearedCount->c == 1) {
//если слот занят, снимаем старый предмет и одеваем новый предмет
Db::getInstance()->execute('UPDATE inventory SET dressed_slot = 0 WHERE dressed_slot = ? AND owner_id = ?', [$itemInSlot[0], $this->owner_id]);
Db::getInstance()->execute('UPDATE inventory SET dressed_slot = item_type WHERE item_id = ? AND owner_id = ?', [$this->item_id, $this->owner_id]);
} elseif (!$wearedCount->c) {
//если слот пуст, одеваем новый предмет
Db::getInstance()->execute('UPDATE inventory SET dressed_slot = item_type WHERE item_id = ? AND owner_id = ?', [$this->item_id, $this->owner_id]);
} else {
/* проверка на переполнение слотов */
$error = self::TOO_MANY_ITEMS_IN_SLOTS;
DressedItems::undressAllItems($this->owner_id);
}
} elseif ($this->item_type == self::ITEM_TYPE_RING) {
// работаем с кольцами
if ($wearedCount->c < 3) {
// Сравниваем массив колец и массив слотов для колец.
$emptyRingSlots = array_diff([9, 10, 11], $itemInSlot);
// Сортируем массив свободных слотов по возрастанию.
sort($emptyRingSlots);
// Одеваем предмет в первый свободный слот.
Db::getInstance()->execute('update inventory set dressed_slot = ? where item_id = ?', [$emptyRingSlots[0], $this->item_id]);
} elseif ($wearedCount->c == 3) {
// Cнимаем предмет из последнего слота 11 и одеваем новый предмет
Db::getInstance()->execute('UPDATE inventory SET dressed_slot = 0 WHERE dressed_slot = 11');
Db::getInstance()->execute('UPDATE inventory SET dressed_slot = 11 WHERE item_id = ?', $this->item_id);
} else {
/* проверка на переполнение слотов */
$error = self::TOO_MANY_ITEMS_IN_SLOTS;
DressedItems::undressAllItems($this->owner_id);
}
} else {
$error = self::UNKNOWN_ITEM_TYPE;
}
return $error ?? true;
}
public static function destroyItem($itemId)
{
Db::getInstance()->execute('delete from inventory where dressed_slot = 0 and owner_id = ? and item_id = ?', [$_SESSION['uid'], $itemId]);
}
/** Надеюсь, временная заглушка, которая объединяет get_meshok() и другую выдачу одной строкой.
* @return string
*/
public static function getWeightData(): string
{
$query = 'select sum(weight) as `all`, strength * 4 as max from inventory left join users u on owner_id = id where owner_id = ?';
$weight = Db::getInstance()->ofetch($query, User::getInstance()->getId());
$css = $weight->all > $weight->max ? ' style="color:maroon;"' : '';
return "<span$css>$weight->all / $weight->max</span>";
}
}