battles/classes/Battles/InventoryItem.php
Ivor Barhansky 0398425205 Code smell.
2022-12-17 03:03:56 +02:00

162 lines
6.8 KiB
PHP
Raw 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\Models\Inventory;
class InventoryItem extends Item
{
private ?string $present;
private int $ownerId;
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->ownerId = $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->type, range(1, 12))) {
echo <<<HTML
<a href=/main.php?edit=1&dress=$this->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;
}
}
private function dressStatsChecks(): bool
{
$checkStats = new UserStats($this->ownerId);
$stat = $checkStats->getFullStats();
return $this->needStrength > $stat->strength
|| $this->needDexterity > $stat->dexterity
|| $this->needIntuition > $stat->intuition
|| $this->needEndurance > $stat->endurance
|| $this->needIntelligence > $stat->intelligence
|| $this->needWisdom > $stat->wisdom;
}
/**
* Одевание предмета из инвентаря в слот.
* @return bool|string
*/
public function dressItem()
{
$itemInSlot = [];
if ($this->dressStatsChecks()) {
return self::REQUIREMENTS_NOT_MET;
}
// считаем сколько ОДЕТЫХ предметов в слоте в который мы хотим одеть предмет. 1=просто вещь 1-3=шашни с кольцами
// Count добавленный в первый запрос возвращает одну строку в любом случае.
// fetch возвращает одну строку в любом случае.
$weared = Inventory::getDressed($this->type, $this->ownerId);
$wearedCount = Inventory::countDressed($this->type, $this->ownerId);
// Если в слоте есть предмет(ы), забиваем их массив одетых в слот предметов.
if ($wearedCount) {
foreach ($weared as $item) {
$itemInSlot[] = $item->dressed_slot;
}
}
if (in_array($this->type, [
self::TYPE_HELMET, self::TYPE_ARMOR, self::TYPE_LEGS, self::TYPE_BOOTS,
self::TYPE_GLOVES, self::TYPE_WEAPON, self::TYPE_SHIELD, self::TYPE_BELT,
self::TYPE_AMULET,
])) {
//работаем с нормальными слотами
if ($wearedCount->c == 1) {
//если слот занят, снимаем старый предмет и одеваем новый предмет
Inventory::undressOne($itemInSlot[0], $this->ownerId);
Inventory::dressOne($this->id, $this->ownerId);
} elseif (!$wearedCount->c) {
//если слот пуст, одеваем новый предмет
Inventory::dressOne($this->id, $this->ownerId);
} else {
/* проверка на переполнение слотов */
$error = self::TOO_MANY_ITEMS_IN_SLOTS;
DressedItems::undressAllItems($this->ownerId);
}
} elseif ($this->type == self::TYPE_RING) {
// работаем с кольцами
if ($wearedCount->c < 3) {
// Сравниваем массив колец и массив слотов для колец.
$emptyRingSlots = array_diff([9, 10, 11], $itemInSlot);
// Сортируем массив свободных слотов по возрастанию.
sort($emptyRingSlots);
// Одеваем предмет в первый свободный слот.
Inventory::dressOneToSlot($this->id, $emptyRingSlots[0]);
} elseif ($wearedCount->c == 3) {
// Cнимаем предмет из последнего слота 11 и одеваем новый предмет
Inventory::changeRings($this->id);
} else {
/* проверка на переполнение слотов */
$error = self::TOO_MANY_ITEMS_IN_SLOTS;
DressedItems::undressAllItems($this->ownerId);
}
} else {
$error = self::UNKNOWN_ITEM_TYPE;
}
return $error ?? true;
}
// Выбрасываем вещь.
public function drop(): string
{
if (empty($this->id)) {
return 'Ошибка: предмет не найден!';
}
if (Inventory::isWeared($this->id)) {
return 'Ошибка: нельзя выбросить одетый предмет!';
}
Inventory::destroyItem($this->id, $this->ownerId);
GameLogs::addUserLog(User::getInstance()->getId(), User::getInstance()->getLogin() . ' выбросил предмет ' . $this->name . ' id:(cap' . $this->id . ')');
return 'Предмет ' . $this->name . ' выброшен.';
}
/** Снятие всех предметов, которые не подходят по статам. */
public static function autoDrop()
{
$di = new DressedItems(User::getInstance()->getId());
foreach ($di->getItemsInSlots() as $dressedItem) {
$itm = new self($dressedItem);
if (!$itm->dressStatsChecks()) {
$di->undressItem($dressedItem->dressed_slot);
}
}
}
/** Надеюсь, временная заглушка, которая объединяет get_meshok() и другую выдачу одной строкой.
* @return string
*/
public static function getWeightData(): string
{
$all = Inventory::getWeight(User::getInstance()->getId());
$max = User::getInstance()->stats()->getMaxWeight();
$css = $all > $max ? ' style="color:maroon;"' : '';
return "<span$css>$all / $max</span>";
}
}