Будь проклят тот день, когда я решил ввести неймспейсы...
This commit is contained in:
@@ -0,0 +1,237 @@
|
||||
<?php
|
||||
/**
|
||||
* Author: lopiu
|
||||
* Date: 03.07.2020
|
||||
* Time: 07:24
|
||||
*/
|
||||
namespace Battles;
|
||||
|
||||
class Bank
|
||||
{
|
||||
public $user_id;
|
||||
private $money;
|
||||
private $user;
|
||||
|
||||
const ERROR_NO_MONEY_IN_WALLET = "Ошибка! Нет денег в кошельке!";
|
||||
const ERROR_NO_BANK_ACCOUNT = "Ошибка! Счёта не существует!";
|
||||
const ERROR_NO_MONEY_IN_BANK_ACCOUNT = "Ошибка! Нет денег на счету!";
|
||||
const ERROR_WRONG_AMOUNT = "Ошибка! Сумма должна быть положительной!";
|
||||
const LOG = [
|
||||
'sendMoney' => 'Банк: Перевод средств на другой счёт.',
|
||||
'receiveMoney' => 'Банк: Получение средств.',
|
||||
'depositMoney' => 'Пополнение счёта.',
|
||||
'withdrawMoney' => 'Снятие денег со счёта.',
|
||||
'clanRegister' => 'Оплата стоимости регистрации клана.',
|
||||
];
|
||||
|
||||
public function __construct($row)
|
||||
{
|
||||
$bank_row = \db::c()->query('SELECT user_id, money FROM bank WHERE user_id = ?i', $row)->fetch_assoc();
|
||||
$this->user = \db::c()->query('SELECT money FROM users WHERE id = ?i', $row)->fetch_object();
|
||||
foreach ($this as $key => $value) {
|
||||
if (isset($bank_row[$key])) {
|
||||
$this->$key = $bank_row[$key];
|
||||
}
|
||||
}
|
||||
// Если ВДРУГ у человека нет счёта в банке - создаём.
|
||||
if (empty($this->user_id)) {
|
||||
\db::c()->query('INSERT INTO bank (user_id) VALUES (?i)', $row);
|
||||
$this->user_id = $row;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Комиссия: процент от переводимой суммы, но не менее 1 кр. Задаётся в config.php.
|
||||
*
|
||||
* @param int $amount сумма.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function bankCommission(int $amount): int
|
||||
{
|
||||
$bankCommission = round($amount * \Config::$bank_commission);
|
||||
if ($bankCommission < 1) {
|
||||
return 1;
|
||||
} else {
|
||||
return (int)$bankCommission;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Пишем банковское событие в лог в БД
|
||||
*
|
||||
* @param int $receiverId ID получателя.
|
||||
* @param int $amount сумма.
|
||||
* @param string $operationType тип банковской операции.
|
||||
* @param int $senderId ID отправителя (ID игрока, если не указано иное).
|
||||
*
|
||||
* @return void
|
||||
* @throws \Krugozor\Database\Mysql\Exception
|
||||
*/
|
||||
private function bankLogs(int $receiverId, int $amount, string $operationType, int $senderId = 0): void
|
||||
{
|
||||
if (!$senderId) {
|
||||
$senderId = $this->user_id;
|
||||
}
|
||||
$text = self::LOG[$operationType];
|
||||
if ($operationType == "sendMoney") {
|
||||
$text .= " Комиссия: " . $this->bankCommission($amount);
|
||||
} elseif ($operationType == "depositMoney") {
|
||||
$receiverId = $this->user_id;
|
||||
} elseif ($operationType == "withdrawMoney") {
|
||||
$receiverId = $this->user_id;
|
||||
$text .= " Комиссия: " . $this->bankCommission($amount);
|
||||
}
|
||||
|
||||
\db::c()->query('INSERT INTO `bank_logs` (sender_id, receiver_id, amount_result, type, text)
|
||||
VALUES (?i, ?i, ?i, "?s", "?s")', $senderId, $receiverId, $amount, $operationType, $text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Перевод денег между банковскими счетами игроков с банковской комиссией.
|
||||
*
|
||||
* @param int $receiver ID получателя.
|
||||
* @param int $amount сумма.
|
||||
*
|
||||
* @return int
|
||||
* @throws \Krugozor\Database\Mysql\Exception
|
||||
*/
|
||||
public function sendMoney(int $receiver, int $amount): int
|
||||
{
|
||||
$receiverWallet = \db::c()->query('SELECT money FROM bank WHERE user_id = ?i', $receiver)->fetch_object();
|
||||
if ($amount <= 0) {
|
||||
throw new \Exceptions\GameException(self::ERROR_WRONG_AMOUNT);
|
||||
}
|
||||
if (!$receiverWallet) {
|
||||
throw new \Exceptions\GameException(self::ERROR_NO_BANK_ACCOUNT);
|
||||
}
|
||||
$amountWithComission = $amount + $this->bankCommission($amount);
|
||||
if ($amountWithComission > $this->money) {
|
||||
throw new \Exceptions\GameException(self::ERROR_NO_MONEY_IN_BANK_ACCOUNT);
|
||||
}
|
||||
// Снимаем сумму с комиссией у отправителя
|
||||
$this->money -= $amountWithComission;
|
||||
self::setBankMoney($this->money, $this->user_id);
|
||||
$this->bankLogs($receiver, $this->money, "sendMoney");
|
||||
// Отдаём сумму на счёт получателю
|
||||
$receiverWallet->money += $amount;
|
||||
self::setBankMoney($receiverWallet->money, $receiver);
|
||||
$this->bankLogs($receiver, $receiverWallet->money, "receiveMoney");
|
||||
// Возвращаем изменившиеся значения
|
||||
return $this->money;
|
||||
}
|
||||
|
||||
/**
|
||||
* Пополнение банковского счёта игрока
|
||||
*
|
||||
* @param int $amount сумма.
|
||||
*
|
||||
* @return array
|
||||
* @throws \Krugozor\Database\Mysql\Exception
|
||||
*/
|
||||
public function depositMoney(int $amount): array
|
||||
{
|
||||
if ($amount <= 0) {
|
||||
throw new \Exceptions\GameException(self::ERROR_WRONG_AMOUNT);
|
||||
}
|
||||
$wallet = \db::c()->query('SELECT money FROM users WHERE id = ?i', $this->user_id)->fetch_object();
|
||||
if ($wallet->money < $amount) {
|
||||
throw new \Exceptions\GameException(self::ERROR_NO_MONEY_IN_WALLET);
|
||||
}
|
||||
// Забираем деньги из кошелька получателя
|
||||
$this->user->money -= $amount;
|
||||
self::setWalletMoney($this->user->money, $this->user_id);
|
||||
// Отдаём сумму на счёт получателю
|
||||
$this->money += $amount;
|
||||
self::setBankMoney($this->money, $this->user_id);
|
||||
$this->bankLogs(0, $this->money, "depositMoney");
|
||||
// Возвращаем изменившиеся значения
|
||||
return [
|
||||
'walletMoney' => $this->user->money,
|
||||
'bankMoney' => $this->money
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Снятие денег с банковского счёта игрока с банковской комиссией.
|
||||
*
|
||||
* @param int $amount сумма.
|
||||
*
|
||||
* @return array
|
||||
* @throws \Krugozor\Database\Mysql\Exception
|
||||
*/
|
||||
public function withdrawMoney(int $amount):array
|
||||
{
|
||||
if ($amount <= 0) {
|
||||
throw new \Exceptions\GameException(self::ERROR_WRONG_AMOUNT);
|
||||
}
|
||||
$amountWithComission = $amount + $this->bankCommission($amount);
|
||||
if ($this->money < $amountWithComission) {
|
||||
throw new \Exceptions\GameException(self::ERROR_NO_MONEY_IN_BANK_ACCOUNT);
|
||||
}
|
||||
// Снимаем сумму с комиссией у отправителя
|
||||
$this->money -= $amountWithComission;
|
||||
self::setBankMoney($this->money, $this->user_id);
|
||||
$this->bankLogs(0, $this->money, "withdrawMoney");
|
||||
// Отдаём сумму в кошелёк получателя
|
||||
$this->user->money += $amount;
|
||||
self::setWalletMoney($this->user->money, $this->user_id);
|
||||
// Возвращаем изменившиеся значения
|
||||
return [
|
||||
'walletMoney' => $this->user->money,
|
||||
'bankMoney' => $this->money
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Установить количество денег на банковском счету.
|
||||
*
|
||||
* @param int $amount сумма.
|
||||
* @param int $user_id ID пользователя.
|
||||
* @param string $operationType Тип операции. По умолчанию пусто. Если ввести, система запишет событие в банковский лог.
|
||||
*
|
||||
* @return void
|
||||
* @throws \Krugozor\Database\Mysql\Exception
|
||||
*/
|
||||
public static function setBankMoney(int $amount, int $user_id, string $operationType = ''): void
|
||||
{
|
||||
try {
|
||||
\db::c()->query('UPDATE bank SET money = ?i WHERE user_id = ?i', $amount, $user_id);
|
||||
if ($operationType) {
|
||||
(new Bank($user_id))->bankLogs(0, $amount, $operationType);
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
echo "Не отработал запрос в БД в файле {$e->getFile()}({$e->getLine()})";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Установить количество денег на руках.
|
||||
*
|
||||
* @param int $amount сумма.
|
||||
* @param int $user_id ID пользователя.
|
||||
*
|
||||
* @return void
|
||||
* @throws \Krugozor\Database\Mysql\Exception
|
||||
*/
|
||||
public static function setWalletMoney(int $amount, int $user_id): void
|
||||
{
|
||||
try {
|
||||
\db::c()->query('UPDATE users SET money = ?i WHERE `id` = ?i', $amount, $user_id);
|
||||
} catch (\Throwable $e) {
|
||||
echo "Не отработал запрос в БД в файле {$e->getFile()}({$e->getLine()})";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function getMoney()
|
||||
{
|
||||
return $this->money;
|
||||
}
|
||||
|
||||
public function setMoney($amount)
|
||||
{
|
||||
$this->money = $amount;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
# Date: 26.10.2020 (17:56)
|
||||
namespace Battles;
|
||||
// todo: #10
|
||||
class City
|
||||
{
|
||||
use Rooms;
|
||||
public static function showStreet(int $id)
|
||||
{
|
||||
if ($id === 20) {
|
||||
echo '<div style="position:relative; display: inline-block;" id="ione"><img alt="background" src="/i/city/spring_cap_cp_day.jpg">' .
|
||||
self::showBuilding(1, "spring_cap_club", 30, 235, self::$roomNames[1]) .
|
||||
self::showBuilding(2, "spring_cap_shop", 202, 171, self::$roomNames[22]) .
|
||||
self::showBuilding(3, "spring_cap_kom", 205, 105, self::$roomNames[25]) .
|
||||
self::showBuilding(4, "spring_cap_rem", 202, 290, self::$roomNames[23]) .
|
||||
self::showBuilding(6, "spring_cap_po4ta", 180, 540, self::$roomNames[27]) .
|
||||
self::showBuilding(7, "cap_arr_right", 260, 710, self::$roomNames[21]) .
|
||||
self::showBuilding(8, "cap_arr_left", 258, 21, self::$roomNames[26]) .
|
||||
self::showBuilding(9, "winter_cap_tree2", 215, 500, self::$roomNames[44]) .
|
||||
self::showBuilding(13, "spring_cap_statue", 222, 365, self::$roomNames[24]) .
|
||||
self::showBuilding(14, "winter_cap_statue", 210, 390, "Снеговик") .
|
||||
self::showBuilding(222, "cap_arr_top", 180, 650, "Торговая улица") .
|
||||
'</div>';
|
||||
} elseif ($id === 21) {
|
||||
echo '<div style="position:relative; display: inline-block;" id="ione"><img alt="background" src="/i/city/spring_cap_strash_day.jpg">' .
|
||||
self::showBuilding(3, "cap_arr_right", 255, 708, "Ристалище") .
|
||||
self::showBuilding(4, "cap_arr_left", 258, 21, self::$roomNames[20]) .
|
||||
self::showBuilding(5, "spring_cap_bank", 180, 485, self::$roomNames[29]) .
|
||||
self::showBuilding(13, "spring_cap_flowershop", 220, 613, self::$roomNames[34]) .
|
||||
self::showBuilding(14, "spring_cap_registratura", 170, 113, self::$roomNames[30]) .
|
||||
self::showBuilding(16, "spring_cap_tower", 5, 315, self::$roomNames[31]) .
|
||||
'</div>';
|
||||
} elseif ($id === 26) {
|
||||
echo '<div style="position:relative; display: inline-block;" id="ione"><img alt="background" src="/i/city/spring_cap_park_day.jpg">' .
|
||||
self::showBuilding(3, "cap_arr_left", 259, 27, self::$roomNames[2601]) .
|
||||
self::showBuilding(4, "cap_arr_right", 259, 715, self::$roomNames[20]) .
|
||||
self::showBuilding(6, "cap_gate", 170, 340, "Городские ворота") .
|
||||
self::showBuilding(660, "spring_cap_vokzal", 163, 43, self::$roomNames[661]) .
|
||||
'</div>';
|
||||
} elseif ($id === 2601) {
|
||||
echo '<div style="position:relative; display: inline-block;" id="ione"><img alt="background" src="/i/city/sub/cap_zamk_day.jpg">' .
|
||||
self::showBuilding(1, "spring_cap_ruins", 166, 48, "Руины Старого замка") .
|
||||
self::showBuilding(4, "cap_arr_right", 260, 710, self::$roomNames[26]) .
|
||||
self::showBuilding(10, "ava_post", 240, 300, self::$roomNames[35]) .
|
||||
self::showBuilding(55, "cap_arr_left", 258, 21, self::$roomNames[2655]) .
|
||||
self::showBuilding(1051, "spring_cap_lab", 130, 327, self::$roomNames[33]) .
|
||||
self::showBuilding(1052, "spring_cap_lavka", 240, 425, self::$roomNames[1053]) .
|
||||
'</div>';
|
||||
} elseif ($id === 2655) {
|
||||
echo '<div style="position:relative; display: inline-block;" id="ione"><img alt="background" src="/i/city/ar_e_d.jpg">' .
|
||||
self::showBuilding(10, "arr_right_png2", 260, 710, self::$roomNames[2601]) .
|
||||
self::showBuilding(2055, "altr_g", 230, 340, self::$roomNames[603]) .
|
||||
'</div>';
|
||||
} elseif ($id === 2111) {
|
||||
echo '<div style="position:relative; display: inline-block;" id="ione"><img alt="background" src="/i/city/av_rist_day.jpg">' .
|
||||
self::showBuilding(1, "cap_arr_left", 240, 30, self::$roomNames[21]) .
|
||||
self::showBuilding(14, "spring_cap_rist_solo", 210, 160, "Вход в Одиночные сражения") .
|
||||
self::showBuilding(14, "spring_cap_rist_group", 243, 340, "Вход в Сражение отрядов") .
|
||||
self::showBuilding(203, "spring_cap_rist_monstr", 145, 570, "Вход в Груповые сражения") .
|
||||
self::showBuilding(1000, "av_zamk_rud", 80, 310, self::$roomNames[1001]) .
|
||||
'</div>';
|
||||
} elseif ($id === 2701) {
|
||||
echo '<div style="position:relative; display: inline-block;" id="ione"><img alt="background" src="/i/city/av_arena_bg1_day2.jpg">' .
|
||||
self::showBuilding(1, "cap_3strelka", 260, 30, "Берег Залива") .
|
||||
self::showBuilding(2, "cap_shar_dark", 234, 356, "Лабиринт Хаоса") .
|
||||
'</div>';
|
||||
} elseif ($id === 2702) {
|
||||
echo '<div style="position:relative; display: inline-block;" id="ione"><img alt="background" src="/i/city/spring_cap_torg_day.jpg">' .
|
||||
self::showBuilding(6, "spring_cap_build1", 175, 70, "Академия") .
|
||||
self::showBuilding(10, "cap_rist_arr_left", 259, 25, self::$roomNames[20]) .
|
||||
self::showBuilding(16, "auk", 120, 300, "Аукцион") .
|
||||
self::showBuilding(21, "spring_cap_build2", 150, 565, "Ломбард") .
|
||||
self::showBuilding(16555, "spring_cap_build3", 155, 480, "Прокатная лавка") .
|
||||
'</div>';
|
||||
}
|
||||
}
|
||||
|
||||
private static function showBuilding(int $id, string $image, int $top, int $left, string $description)
|
||||
{
|
||||
return sprintf('
|
||||
<div style="position:absolute; left:%spx; top:%spx; z-index:90; cursor: pointer;">
|
||||
<img src="/i/city/sub/%s.png" alt="%s" title="%s" class="building" id="%s" onclick="window.location.href = \'city.php?got/level%s\'">
|
||||
</div>',
|
||||
$left, $top, $image, $description, $description, $id, $id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
/**
|
||||
* Author: lopiu
|
||||
* Date: 06.07.2020
|
||||
* Time: 22:41
|
||||
*/
|
||||
namespace Battles;
|
||||
class DressedItems
|
||||
{
|
||||
private $DB;
|
||||
private $DBSUM;
|
||||
private $USERID;
|
||||
private $dressedItem;
|
||||
|
||||
/**
|
||||
* DressedItems constructor.
|
||||
*
|
||||
* @param $user_id - ID игрока.
|
||||
*/
|
||||
public function __construct($user_id)
|
||||
{
|
||||
$this->USERID = $user_id;
|
||||
}
|
||||
|
||||
private function getDressedItems()
|
||||
{
|
||||
try {
|
||||
$this->DB = db::c()->query('SELECT * FROM inventory WHERE owner_id = ?i AND dressed_slot > 0', $this->USERID);
|
||||
} catch (Exception $e) {
|
||||
echo '<div class="debug">Не прогрузилась таблица inventory (*) для класса DressedItems.</div>';
|
||||
}
|
||||
}
|
||||
|
||||
private function getDressedItemById($item_id)
|
||||
{
|
||||
return db::c()->query('SELECT * FROM inventory WHERE item_id = ?i AND dressed_slot > 0', $item_id)->fetch_assoc();
|
||||
}
|
||||
|
||||
private function getBonusesFromDressedItems()
|
||||
{
|
||||
try {
|
||||
$query = <<<SQL
|
||||
SELECT SUM(add_strength) as sum_strength,
|
||||
SUM(add_dexterity) as sum_dexterity,
|
||||
SUM(add_intuition) as sum_intuition,
|
||||
SUM(add_endurance) as sum_endurance,
|
||||
SUM(add_intelligence) as sum_intelligence,
|
||||
SUM(add_wisdom) as sum_wisdom,
|
||||
SUM(add_accuracy) as sum_accuracy,
|
||||
SUM(add_evasion) as sum_evasion,
|
||||
SUM(add_criticals) as sum_criticals,
|
||||
SUM(add_min_physical_damage) as sum_min_phys_damage,
|
||||
SUM(add_max_physical_damage) as sum_max_phys_damage
|
||||
FROM inventory WHERE owner_id = ?i AND dressed_slot > 0
|
||||
SQL;
|
||||
$this->DBSUM = db::c()->query($query, $this->USERID)->fetch_assoc();
|
||||
} catch (Exception $e) {
|
||||
echo '<div class="debug">Не прогрузилась таблица inventory (SUM) для класса DressedItems:' . $e . '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
public function getItemsInSlots()
|
||||
{
|
||||
if (!$this->DB) {
|
||||
self::getDressedItems();
|
||||
}
|
||||
while ($row = $this->DB->fetch_assoc()) {
|
||||
$this->dressedItem[$row['dressed_slot']] = $row;
|
||||
}
|
||||
return $this->dressedItem;
|
||||
}
|
||||
|
||||
private function getBonuses()
|
||||
{
|
||||
if (!$this->DBSUM) {
|
||||
self::getBonusesFromDressedItems();
|
||||
}
|
||||
return $this->DBSUM;
|
||||
}
|
||||
|
||||
public function getStrengthBonus()
|
||||
{
|
||||
return self::getBonuses()['sum_strength'];
|
||||
}
|
||||
public function getDexterityBonus()
|
||||
{
|
||||
return self::getBonuses()['sum_dexterity'];
|
||||
}
|
||||
public function getIntuitionBonus()
|
||||
{
|
||||
return self::getBonuses()['sum_intuition'];
|
||||
}
|
||||
public function getEnduranceBonus()
|
||||
{
|
||||
return self::getBonuses()['sum_endurance'];
|
||||
}
|
||||
public function getIntelliganceBonus()
|
||||
{
|
||||
return self::getBonuses()['sum_intelligence'];
|
||||
}
|
||||
public function getWisdomBonus()
|
||||
{
|
||||
return self::getBonuses()['sum_wisdom'];
|
||||
}
|
||||
public function getAccuracyBonus()
|
||||
{
|
||||
return self::getBonuses()['sum_accuracy'] ?? 0;
|
||||
}
|
||||
public function getEvasionBonus()
|
||||
{
|
||||
return self::getBonuses()['sum_evasion'] ?? 0;
|
||||
}
|
||||
public function getCriticalsBonus()
|
||||
{
|
||||
return self::getBonuses()['sum_criticals'] ?? 0;
|
||||
}
|
||||
public function getMinPhysDamage()
|
||||
{
|
||||
return self::getBonuses()['sum_min_phys_damage'];
|
||||
}
|
||||
public function getMaxPhysDamage()
|
||||
{
|
||||
return self::getBonuses()['sum_max_phys_damage'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Снимает с предмета статус одетого на персонажа в определённом слоте персонажа.
|
||||
* @param $slot_id - номер слота.
|
||||
*
|
||||
* @throws \Krugozor\Database\Mysql\Exception
|
||||
*/
|
||||
public function undressItem($slot_id)
|
||||
{
|
||||
self::getItemsInSlots();
|
||||
// Проверяем, что используется один из 12 слотов и наличие предмета в слоте.
|
||||
if (in_array($slot_id, Item::ITEM_TYPES_ALLOWED_IN_SLOTS) && $this->dressedItem[$slot_id]) {
|
||||
db::c()->query('UPDATE inventory SET dressed_slot = 0 WHERE dressed_slot = ?i AND owner_id = ?i', $slot_id, $this->USERID);
|
||||
}
|
||||
}
|
||||
|
||||
public function slotStatus($slot_id)
|
||||
{
|
||||
self::getItemsInSlots();
|
||||
if ($this->dressedItem[$slot_id]) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
namespace Battles;
|
||||
class InventoryItem extends Item
|
||||
{
|
||||
private $present;
|
||||
|
||||
public function __construct($row)
|
||||
{
|
||||
parent::__construct($row);
|
||||
if (isset($row['present'])) {
|
||||
$this->present = $row['present'];
|
||||
}
|
||||
}
|
||||
|
||||
public function printInfo()
|
||||
{
|
||||
parent::printAllInfo();
|
||||
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 "<a href=/main.php?edit=1&dress={$this->item_id} title='Надеть'>";
|
||||
parent::printImage();
|
||||
echo "</a>";
|
||||
} else {
|
||||
parent::printImage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Для кнопок управления под картинкой предмета в зависимости от ситуации.
|
||||
*/
|
||||
public function printControls()
|
||||
{
|
||||
//FIXME Сменить заглушку на нормальную функцию!!
|
||||
echo <<<BTN
|
||||
<p><button class="button danger" onclick="location.href='/admin.php'">Выбросить</button>
|
||||
BTN;
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->item_id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
<?php
|
||||
namespace Battles;
|
||||
abstract class Item
|
||||
{
|
||||
protected $item_id;
|
||||
protected $name;
|
||||
protected $item_type;
|
||||
protected $durability;
|
||||
protected $price;
|
||||
protected $need_strength;
|
||||
protected $need_dexterity;
|
||||
protected $need_intuition;
|
||||
protected $need_endurance;
|
||||
protected $need_intelligence;
|
||||
protected $need_wisdom;
|
||||
protected $add_strength;
|
||||
protected $add_dexterity;
|
||||
protected $add_intuition;
|
||||
protected $add_endurance;
|
||||
protected $add_intelligence;
|
||||
protected $add_wisdom;
|
||||
protected $add_accuracy;
|
||||
protected $add_evasion;
|
||||
protected $add_criticals;
|
||||
protected $add_min_physical_damage;
|
||||
protected $add_max_physical_damage;
|
||||
protected $weight;
|
||||
protected $image;
|
||||
public const ITEM_TYPES_ALLOWED_IN_SLOTS = [1,2,3,4,5,6,7,8,9,10,11,12];
|
||||
public const ITEM_TYPE_HELMET = 1;
|
||||
public const ITEM_TYPE_ARMOR = 2;
|
||||
const ITEM_TYPE_LEGS = 3;
|
||||
const ITEM_TYPE_BOOTS = 4;
|
||||
const ITEM_TYPE_GLOVES = 5;
|
||||
const ITEM_TYPE_WEAPON = 6;
|
||||
const ITEM_TYPE_SHIELD = 7;
|
||||
const ITEM_TYPE_BELT = 8;
|
||||
public const ITEM_TYPE_RING = 9;
|
||||
const ITEM_TYPE_AMULET = 10;
|
||||
const ITEM_TYPE_CONSUMABLE = 20;
|
||||
const ITEM_TYPE_OTHER = 50;
|
||||
const ITEM_TYPE_TRASH = 100;
|
||||
|
||||
/**
|
||||
* Item constructor.
|
||||
*
|
||||
* @param $row
|
||||
*/
|
||||
public function __construct($row)
|
||||
{
|
||||
foreach ($this as $key => $value) {
|
||||
if (isset($row[$key])) {
|
||||
$this->$key = $row[$key];
|
||||
}
|
||||
}
|
||||
|
||||
switch ($this->item_type) {
|
||||
case self::ITEM_TYPE_HELMET:
|
||||
$this->typename = 'Шлем';
|
||||
break;
|
||||
case self::ITEM_TYPE_ARMOR:
|
||||
$this->typename = 'Броня';
|
||||
break;
|
||||
case self::ITEM_TYPE_LEGS:
|
||||
$this->typename = 'Поножи';
|
||||
break;
|
||||
case self::ITEM_TYPE_BOOTS:
|
||||
$this->typename = 'Сапоги';
|
||||
break;
|
||||
case self::ITEM_TYPE_GLOVES:
|
||||
$this->typename = 'Перчатки';
|
||||
break;
|
||||
case self::ITEM_TYPE_WEAPON:
|
||||
$this->typename = 'Оружие';
|
||||
break;
|
||||
case self::ITEM_TYPE_SHIELD:
|
||||
$this->typename = 'Щит';
|
||||
break;
|
||||
case self::ITEM_TYPE_BELT:
|
||||
$this->typename = 'Пояс';
|
||||
break;
|
||||
case self::ITEM_TYPE_RING:
|
||||
$this->typename = 'Кольцо';
|
||||
break;
|
||||
case self::ITEM_TYPE_AMULET:
|
||||
$this->typename = 'Амулет';
|
||||
break;
|
||||
case self::ITEM_TYPE_CONSUMABLE:
|
||||
$this->typename = 'Расходуемый предмет';
|
||||
break;
|
||||
default:
|
||||
$this->typename = 'Хлам';
|
||||
}
|
||||
}
|
||||
|
||||
abstract public function printInfo();
|
||||
|
||||
public function printImage()
|
||||
{
|
||||
echo <<<IMG
|
||||
<img src="/i/sh/{$this->image}" class="item-wrap-normal" alt="">
|
||||
IMG;
|
||||
}
|
||||
|
||||
protected function wrap($number)
|
||||
{
|
||||
if ($number > 0) {
|
||||
return ": <b>" . $number . "</b>";
|
||||
} else {
|
||||
return ": <b style='color: maroon;'>" . $number . "</b>";
|
||||
}
|
||||
}
|
||||
|
||||
protected function printAllInfo()
|
||||
{
|
||||
echo "<b>" . $this->name . "</b> (Масса: " . $this->weight . ")";
|
||||
if ($this->durability) {
|
||||
echo "<br> Долговечность: " . $this->durability;
|
||||
}
|
||||
echo "<br><em>{$this->typename}</em><br>";
|
||||
if ($this->need_strength > 0) {
|
||||
echo "<br>Требуется сила" . $this->wrap($this->need_strength);
|
||||
}
|
||||
if ($this->need_dexterity > 0) {
|
||||
echo "<br>Требуется ловкость" . $this->wrap($this->need_dexterity);
|
||||
}
|
||||
if ($this->need_intuition > 0) {
|
||||
echo "<br>Требуется интуиция" . $this->wrap($this->need_intuition);
|
||||
}
|
||||
if ($this->need_endurance > 0) {
|
||||
echo "<br>Требуется выносливость" . $this->wrap($this->need_endurance);
|
||||
}
|
||||
if ($this->need_intelligence > 0) {
|
||||
echo "<br>Требуется интеллект" . $this->wrap($this->need_intelligence);
|
||||
}
|
||||
if ($this->need_wisdom > 0) {
|
||||
echo "<br>Требуется мудрость" . $this->wrap($this->need_wisdom);
|
||||
}
|
||||
if ($this->add_strength) {
|
||||
echo "<br>Сила" . $this->wrap($this->add_strength);
|
||||
}
|
||||
if ($this->add_dexterity) {
|
||||
echo "<br>Ловкость" . $this->wrap($this->add_dexterity);
|
||||
}
|
||||
if ($this->add_intuition) {
|
||||
echo "<br>Интуиция" . $this->wrap($this->add_intuition);
|
||||
}
|
||||
if ($this->add_endurance) {
|
||||
echo "<br>Выносливость" . $this->wrap($this->add_endurance);
|
||||
}
|
||||
if ($this->add_intelligence) {
|
||||
echo "<br>Интеллект" . $this->wrap($this->add_intelligence);
|
||||
}
|
||||
if ($this->add_wisdom) {
|
||||
echo "<br>Мудрость" . $this->wrap($this->add_wisdom);
|
||||
}
|
||||
if ($this->add_accuracy) {
|
||||
echo "<br>Точность" . $this->wrap($this->add_accuracy);
|
||||
}
|
||||
if ($this->add_evasion) {
|
||||
echo "<br>Увёртливость" . $this->wrap($this->add_evasion);
|
||||
}
|
||||
if ($this->add_criticals) {
|
||||
echo "<br>Шанс крита" . $this->wrap($this->add_criticals);
|
||||
}
|
||||
if ($this->add_min_physical_damage && !$this->add_max_physical_damage) {
|
||||
$damage = $this->add_min_physical_damage . " - " . $this->add_min_physical_damage;
|
||||
} elseif (!$this->add_min_physical_damage && $this->add_max_physical_damage) {
|
||||
$damage = $this->add_max_physical_damage . " - " . $this->add_max_physical_damage;
|
||||
} elseif ($this->add_min_physical_damage && $this->add_max_physical_damage) {
|
||||
$damage = $this->add_min_physical_damage . " - " . $this->add_max_physical_damage;
|
||||
}
|
||||
if (isset($damage)) {
|
||||
echo "<br>Урон: " . $damage;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
# Date: 16.09.2020 (08:23)
|
||||
// Магия лечения травм
|
||||
namespace Battles\Magic;
|
||||
use Battles\UserEffects;
|
||||
use Battles\User;
|
||||
|
||||
class CureInjury extends magic
|
||||
{
|
||||
private $target;
|
||||
use UserEffects;
|
||||
|
||||
/**
|
||||
* Магия лечения травм. Если у персонажа несколько травм, лечится самая тяжёлая.
|
||||
* @param $target - кого лечим.
|
||||
* @param $injuryType - тип травмы, которую лечим. 11 лёгкая, 12 средняя, 13 тяжёлая, 14 неизлечимая.
|
||||
* @throws \Krugozor\Database\Mysql\Exception
|
||||
*/
|
||||
public function __construct($target, $injuryType)
|
||||
{
|
||||
$this->target = $target;
|
||||
if ($target && $this->isUsable()) {
|
||||
$injury = \db::c()->query('SELECT effect_id, type, name FROM users_effects WHERE type IN (11,12,13,14) AND owner_id = ?i ORDER BY type DESC LIMIT 1', $target)->fetch_object();
|
||||
$targetName = $this->target->login;
|
||||
if (in_array($injury->effect_id, [11, 12, 13, 14]) && $injuryType >= $injury->type) {
|
||||
\db::c()->query('DELETE FROM users_effects WHERE effect_id = ?i', $injury->effect_id);
|
||||
if (empty($injury->name) || $injury->name == 'Неизвестный эффект') {
|
||||
$injuryName = self::$effectName[$injury->type];
|
||||
} else {
|
||||
$injuryName = $injury->name;
|
||||
}
|
||||
return "Вы вылечили повреждение ${injuryName} персонажу ${targetName}.";
|
||||
} elseif ($injury->effect_id && $injuryType == 15) {
|
||||
\db::c()->query('DELETE FROM users_effects WHERE type IN (11,12,13,14) AND owner_id = ?i', $target);
|
||||
return "Вы вылечили все повреждения персонажу ${targetName}.";
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return $this->status;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверки на успех.
|
||||
* @return bool
|
||||
*/
|
||||
private function isUsable()
|
||||
{
|
||||
$caster = new User($_SESSION['uid']);
|
||||
if ($this->target == $_SESSION['uid']) {
|
||||
$this->target = $caster;
|
||||
} else {
|
||||
$this->target = new User($this->target);
|
||||
}
|
||||
return ($this->isVisible($caster, $this->target) && $this->isNotDead($caster) && $this->enoughMana($caster) && $this->isNotInBattle($caster));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
# Date: 16.09.2020 (08:45)
|
||||
namespace Battles\Magic;
|
||||
class Magic
|
||||
{
|
||||
protected $status;
|
||||
|
||||
protected function isVisible($caster, $target)
|
||||
{
|
||||
if ($caster->battle != $target->battle || $caster->room != $target->room) {
|
||||
$this->status = 'Вы не видите цель!';
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected function isNotDead($caster)
|
||||
{
|
||||
if ($caster->health < 1) {
|
||||
$this->status = 'Вы мертвы!';
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected function enoughMana($caster)
|
||||
{
|
||||
if ($caster->mana < 1) {
|
||||
$this->status = 'Недостаточно пыли!';
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected function isNotInBattle($caster)
|
||||
{
|
||||
if ($caster->battle) {
|
||||
$this->status = 'Невозможно применить в поединке!';
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Battles\Magic;
|
||||
|
||||
use db;
|
||||
|
||||
class attack
|
||||
{
|
||||
private $target_user;
|
||||
private $caster;
|
||||
|
||||
private function __construct($target_user_id)
|
||||
{
|
||||
if (!$this->caster) {
|
||||
$this->caster = db::c()->query('SELECT * FROM `users` WHERE `id` = ?i', $_SESSION['uid']);
|
||||
}
|
||||
if (!$this->target_user) {
|
||||
$this->target_user = db::c()->query('SELECT * FROM `users` WHERE `id` = ?i', $target_user_id);
|
||||
}
|
||||
if ($this->checks() == 1) {
|
||||
return 'Done!';
|
||||
}
|
||||
}
|
||||
|
||||
private function checks()
|
||||
{
|
||||
if ($this->caster['battle']) {
|
||||
return 'Не в бою...';
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public static function id($playerId)
|
||||
{
|
||||
return new self($playerId);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* Author: lopiu
|
||||
* Date: 05.07.2020
|
||||
* Time: 23:32
|
||||
*/
|
||||
namespace Battles\Models;
|
||||
class EffectsModel
|
||||
{
|
||||
protected $DB;
|
||||
const EFFECT_HIDEUSERINFO = 5; // Обезлик
|
||||
public function __construct(int $user_id) {
|
||||
try {
|
||||
$this->DB = \db::c()->query('SELECT * FROM users_effects WHERE owner_id = ?i', $user_id);
|
||||
} catch (\Throwable $e) {echo '<div class="debug">class EffectsModel: Не могу подключиться к таблице effects!</div>';}
|
||||
}
|
||||
|
||||
private function getEffects($user_id)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверка обезличен ли персонаж.
|
||||
* @return int date() до конца эффекта или 0.
|
||||
*/
|
||||
public function getHideUserInfoStatus()
|
||||
{
|
||||
if ($this->DB) {
|
||||
while ($row = $this->DB->fetch_object()) {
|
||||
if ($row->type == self::EFFECT_HIDEUSERINFO) {
|
||||
return $row->time;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* Author: lopiu
|
||||
* Date: 04.07.2020
|
||||
* Time: 13:17
|
||||
*/
|
||||
namespace Battles\Models;
|
||||
use Exceptions\GameException;
|
||||
|
||||
class PresentsModel
|
||||
{
|
||||
protected $DB;
|
||||
|
||||
public function __construct(int $user_id)
|
||||
{
|
||||
if (!$this->DB) {
|
||||
$this->DB = \db::c()->query('SELECT sender_id, image FROM `users_presents` WHERE owner_id = ?i', $user_id);
|
||||
if ($this->DB->getNumRows() == 0) {
|
||||
throw new GameException("<div class='debug'>class PresentsModel: Не прогрузилась база!</div>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getAllPresents()
|
||||
{
|
||||
return $this->DB;
|
||||
}
|
||||
|
||||
public function getPresentsSum()
|
||||
{
|
||||
return $this->DB->getNumRows();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Author: lopiu
|
||||
* Date: 05.07.2020
|
||||
* Time: 22:38
|
||||
*/
|
||||
namespace Battles\Models;
|
||||
class UserLogModel
|
||||
{
|
||||
protected $DB;
|
||||
|
||||
public function __construct(int $user_id)
|
||||
{
|
||||
$this->DB = \db::c()->query('SELECT * FROM users_logs WHERE user_id = ?i ORDER BY `id` ASC', $user_id);
|
||||
|
||||
}
|
||||
|
||||
public function getUserLog()
|
||||
{
|
||||
return $this->DB;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
namespace Battles;
|
||||
/**
|
||||
* Разные способы отображения строки с логином персонажа.
|
||||
*/
|
||||
|
||||
class Nick extends User
|
||||
{
|
||||
private function getInvisibilityStatus()
|
||||
{
|
||||
return db::c()->query('SELECT 1 FROM users_effects WHERE type = 1022 AND owner_id = ?i', $this->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Отображение иконки склонности.
|
||||
* @return string
|
||||
*/
|
||||
private function getAlign()
|
||||
{
|
||||
if (isset($this->align)) {
|
||||
return sprintf('<img src="i/align_%s.gif">', $this->align);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Отображение иконки клана.
|
||||
* @return string
|
||||
*/
|
||||
private function getClan()
|
||||
{
|
||||
if (isset($this->clan)) {
|
||||
return sprintf('<img src="i/clan/%s.png">', $this->clan);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Берем ID и возвращаем его. Что-то для обратной совместимости, скорее всего.
|
||||
* TODO: Отвязаться от функции и удалить.
|
||||
* @param $playerId
|
||||
*
|
||||
* @return Nick
|
||||
*/
|
||||
public static function id($playerId)
|
||||
{
|
||||
return new self($playerId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает строку со склонностью, кланом, логином, уровнем, ссылкой на профиль.
|
||||
*
|
||||
* @param int $showInvisibility - По умолчанию 0. Выбрать 1, если надо отображать невидимый статус.
|
||||
*
|
||||
* @return string
|
||||
* @throws \Krugozor\Database\Mysql\Exception
|
||||
*/
|
||||
public function full($showInvisibility = 0)
|
||||
{
|
||||
if ($showInvisibility && $this->getInvisibilityStatus()) {
|
||||
return '<i>невидимка</i>';
|
||||
}
|
||||
return $this->getAlign().$this->getClan().sprintf('<b>%s</b> [%s] <a href="inf.php?%s" target="_blank"><img src="i/inf.gif" style="width:12px;height:11px"></a>', $this->login, $this->level, $this->login);
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает строку с логином или невидимым статусом.
|
||||
* @return string
|
||||
* @throws \Krugozor\Database\Mysql\Exception
|
||||
*/
|
||||
public function short()
|
||||
{
|
||||
if ($this->getInvisibilityStatus()) {
|
||||
return '<i>невидимка</i>';
|
||||
} else {
|
||||
return htmlspecialchars($this->login);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает строку со склонностью, кланом, логином, уровнем, ссылкой на профиль, здоровьем.
|
||||
* @return string
|
||||
*/
|
||||
public function battle()
|
||||
{
|
||||
return $this->getAlign().$this->getClan().sprintf('<b>%s</b> [%s] <a href="inf.php?%s" target="_blank"><img src="i/inf.gif" style="width:12px;height:11px"></a> <img src="i/herz.gif" alt="HP"> _hp_/_maxhp_', $this->login, $this->level, $this->login);
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает строку с логином и здоровьем, выделяя строку определённым стилем.
|
||||
* @param $textstyle - Название стиля отображения логина персонажа (main.css) для цветового разделения команд.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function battleShort($textstyle)
|
||||
{
|
||||
if ($this->getInvisibilityStatus()) {
|
||||
return '<i>невидимка</i>';
|
||||
}
|
||||
else {
|
||||
return sprintf('<span style="%s">%s</span> [_hp_/_maxhp_]', $textstyle, $this->login);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
<?php
|
||||
namespace Battles;
|
||||
/*
|
||||
* Список наименований игровых комнат.
|
||||
*/
|
||||
trait Rooms
|
||||
{
|
||||
public static $roomNames = [
|
||||
0 => "Секретная Комната",
|
||||
1 => "Дом поединков",
|
||||
20 => "Центральная площадь",
|
||||
21 => "Страшилкина улица",
|
||||
22 => "Магазин",
|
||||
23 => "Ремонтная мастерская",
|
||||
24 => "Памятник Архангелу",
|
||||
25 => "Комиссионный магазин",
|
||||
26 => "Большая парковая улица",
|
||||
27 => "Почта",
|
||||
29 => "Банк",
|
||||
30 => "Регистратура кланов",
|
||||
31 => "Башня смерти",
|
||||
32 => "Готический замок",
|
||||
33 => "Лабиринт хаоса",
|
||||
34 => "Цветочный магазин",
|
||||
35 => "Сувенирный магазин",
|
||||
37 => "Готический замок - приемная",
|
||||
38 => "Готический замок - арсенал",
|
||||
39 => "Готический замок - внутренний двор",
|
||||
40 => "Готический замок - мастерские",
|
||||
41 => "Готический замок - комнаты отдыха",
|
||||
42 => "Лотерея Сталкеров",
|
||||
43 => "Хижина Знахаря",
|
||||
44 => "Новогодняя елка",
|
||||
45 => "Замок Мэра",
|
||||
47 => "Замок (строительство)",
|
||||
48 => "Обитель Хаоса",
|
||||
49 => "Проход к Цитадели Хаоса",
|
||||
51 => "Парковая улица",
|
||||
52 => "Квартал Законников",
|
||||
53 => "Библиотека",
|
||||
61 => "Академия",
|
||||
200 => "Турнир",
|
||||
401 => "Врата Ада",
|
||||
// БС
|
||||
501 => "Восточная Крыша",
|
||||
502 => "Бойница",
|
||||
503 => "Келья 3",
|
||||
504 => "Келья 2",
|
||||
505 => "Западная Крыша 2",
|
||||
506 => "Келья 4",
|
||||
507 => "Келья 1",
|
||||
508 => "Служебная комната",
|
||||
509 => "Зал Отдыха 2",
|
||||
510 => "Западная Крыша 1",
|
||||
511 => "Выход на Крышу",
|
||||
512 => "Зал Статуй 2",
|
||||
513 => "Храм",
|
||||
514 => "Восточная комната",
|
||||
515 => "Зал Отдыха 1",
|
||||
516 => "Старый Зал 2",
|
||||
517 => "Старый Зал 1",
|
||||
518 => "Красный Зал 3",
|
||||
519 => "Зал Статуй 1",
|
||||
520 => "Зал Статуй 3",
|
||||
521 => "Трапезная 3",
|
||||
522 => "Зал Ожиданий",
|
||||
523 => "Оружейная",
|
||||
524 => "Красный Зал-Окна",
|
||||
525 => "Красный Зал",
|
||||
526 => "Гостинная",
|
||||
527 => "Трапезная 1",
|
||||
528 => "Внутренний Двор",
|
||||
529 => "Внутр.Двор-Вход",
|
||||
530 => "Желтый Коридор",
|
||||
531 => "Мраморный Зал 1",
|
||||
532 => "Красный Зал 2",
|
||||
533 => "Библиотека 1",
|
||||
534 => "Трапезная 2",
|
||||
535 => "Проход Внутр. Двора",
|
||||
536 => "Комната с Камином",
|
||||
537 => "Библиотека 3",
|
||||
538 => "Выход из Мрам.Зала",
|
||||
539 => "Красный Зал-Коридор",
|
||||
540 => "Лестница в Подвал 1",
|
||||
541 => "Южный Внутр. Двор",
|
||||
542 => "Трапезная 4",
|
||||
543 => "Мраморный Зал 3",
|
||||
544 => "Мраморный Зал 2",
|
||||
545 => "Картинная Галерея 1",
|
||||
546 => "Лестница в Подвал 2",
|
||||
547 => "Проход Внутр. Двора 2",
|
||||
548 => "Внутр.Двор-Выход",
|
||||
549 => "Библиотека 2",
|
||||
550 => "Картинная Галерея 3",
|
||||
551 => "Картинная Галерея 2",
|
||||
552 => "Лестница в Подвал 3",
|
||||
553 => "Терасса",
|
||||
554 => "Оранжерея",
|
||||
555 => "Зал Ораторов",
|
||||
556 => "Лестница в Подвал 4",
|
||||
557 => "Темная Комната",
|
||||
558 => "Винный Погреб",
|
||||
559 => "Комната в Подвале",
|
||||
560 => "Подвал",
|
||||
600 => "Вход в Цитадель Хаоса",
|
||||
601 => "Цитадель Хаоса",
|
||||
602 => "Городской парк",
|
||||
603 => "Арена Ангелов",
|
||||
620 => "Вход в Рудник",
|
||||
621 => "Рудник",
|
||||
660 => "Гостиница, холл",
|
||||
661 => "Гостиница",
|
||||
662 => "Памятник Архангелу",
|
||||
// Клановая улица
|
||||
650 => "Клановая улица",
|
||||
651 => "Клановая улица",
|
||||
652 => "Клановый Замок",
|
||||
760 => "Тёмный Лес",
|
||||
1000 => "Вход в рудник",
|
||||
1001 => "Рудник",
|
||||
1051 => "Вход в Лабиринты",
|
||||
1052 => "Лабиринты",
|
||||
1053 => "Храмовая лавка",
|
||||
1054 => "Фонтан Удачи",
|
||||
1055 => "Групповое сражение",
|
||||
// Тайный проход из Клуба в Замок Законников
|
||||
2000 => "Подземный проход",
|
||||
2001 => "Подземный проход (1)",
|
||||
2002 => "Подземный проход (2)",
|
||||
2003 => "Подземный проход (3)",
|
||||
2004 => "Подземный проход (4)",
|
||||
2005 => "Подземный проход (5)",
|
||||
2006 => "Подземный проход (6)",
|
||||
2007 => "Подземный проход (7)",
|
||||
2008 => "Подземный проход (8)",
|
||||
2009 => "Подземный проход (9)",
|
||||
2010 => "Подземный проход (10)",
|
||||
2011 => "Подземный проход (11)",
|
||||
2012 => "Подземный проход (12)",
|
||||
2013 => "Подземный проход (13)",
|
||||
2014 => "Подземный проход (14)",
|
||||
2015 => "Подземный проход (15)",
|
||||
2016 => "Подземный проход (16)",
|
||||
2017 => "Подземный проход (17)",
|
||||
2018 => "Подземный проход (18)",
|
||||
2019 => "Подземный проход (19)",
|
||||
2020 => "Подземный проход (20)",
|
||||
2021 => "Подземный проход (21)",
|
||||
2022 => "Подземный проход (22)",
|
||||
2023 => "Подземный проход (23)",
|
||||
2024 => "Подземный проход (24)",
|
||||
2025 => "Подземный проход (25)",
|
||||
2026 => "Подземный проход (26)",
|
||||
2027 => "Подземный проход (27)",
|
||||
2028 => "Подземный проход (28)",
|
||||
2029 => "Подземный проход (29)",
|
||||
2030 => "Подземный проход (30)",
|
||||
2031 => "Подземный проход (31)",
|
||||
2032 => "Подземный проход (32)",
|
||||
2033 => "Подземный проход (33)",
|
||||
2034 => "Подземный проход (34)",
|
||||
2035 => "Подземный проход (35)",
|
||||
2036 => "Подземный проход (36)",
|
||||
2037 => "Подземный проход (37)",
|
||||
2038 => "Подземный проход (38)",
|
||||
2039 => "Подземный проход (39)",
|
||||
2040 => "Подземный проход (40)",
|
||||
2041 => "Подземный проход (41)",
|
||||
2042 => "Подземный проход (42)",
|
||||
2043 => "Подземный проход (43)",
|
||||
2044 => "Подземный проход (44)",
|
||||
2045 => "Подземный проход (45)",
|
||||
2046 => "Подземный проход (46)",
|
||||
2047 => "Подземный проход (47)",
|
||||
2048 => "Подземный проход (48)",
|
||||
2049 => "Подземный проход (49)",
|
||||
2050 => "Подземный проход (50)",
|
||||
2051 => "Подземный проход (51)",
|
||||
2052 => "Подземный проход (52)",
|
||||
2053 => "Подземный проход (53)",
|
||||
2054 => "Подземный проход (54)",
|
||||
2055 => "Подземный проход (55)",
|
||||
2056 => "Подземный проход (56)",
|
||||
2057 => "Подземный проход (57)",
|
||||
2100 => "Сектор 2100",
|
||||
2655 => "Арена Богов",
|
||||
2601 => "Замковая Площадь",
|
||||
2702 => "Центральная площадь (мираж)",
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
namespace Battles;
|
||||
class ShopItem extends Item
|
||||
{
|
||||
public function printInfo()
|
||||
{
|
||||
parent::printAllInfo();
|
||||
}
|
||||
|
||||
public function buyItem($owner)
|
||||
{
|
||||
if ($owner) {
|
||||
db::c()->query('
|
||||
INSERT INTO `inventory` (`prototype`,`owner`,`name`,`type`,`massa`,`cost`,`img`,`maxdur`,`isrep`,`gsila`,`glovk`,`ginta`,`gintel`,
|
||||
`ghp`,`gnoj`,`gtopor`,`gdubina`,`gmech`,`gfire`,`gwater`,`gair`,`gearth`,`glight`,`ggray`,`gdark`,
|
||||
`needident`,`nsila`,`nlovk`,`ninta`,`nintel`,`nmudra`,`nvinos`,`nnoj`,`ntopor`,`ndubina`,`nmech`,
|
||||
`nfire`,`nwater`,`nair`,`nearth`,`nlight`,`ngray`,`ndark`,`mfkrit`,`mfakrit`,`mfuvorot`,`mfauvorot`,
|
||||
`bron1`,`bron2`,`bron3`,`bron4`,`maxu`,`minu`,`magic`,`nlevel`,`nalign`,`dategoden`,`goden`,`otdel`,
|
||||
`artefact`, `koll`) VALUES (?i,?i,"?s",?i,?i,?i,"?s",?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,
|
||||
?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,?i,"?s",?i,?i)
|
||||
', $this->id, $owner, $this->name, $this->type, $this->massa, $this->cost, $this->img, $this->maxdur, $this->isrep, $this->gsila, $this->glovk, $this->ginta, $this->gintel,
|
||||
$this->ghp, $this->gnoj, $this->gtopor, $this->gdubina, $this->gmech, $this->gfire, $this->gwater, $this->gair, $this->gearth, $this->glight, $this->ggray, $this->gdark,
|
||||
$this->needident, $this->nsila, $this->nlovk, $this->ninta, $this->nintel, $this->nmudra, $this->nvinos, $this->nnoj, $this->ntopor, $this->ndubina, $this->nmech,
|
||||
$this->nfire, $this->nwater, $this->nair, $this->nearth, $this->nlight, $this->ngray, $this->ndark, $this->mfkrit, $this->mfakrit, $this->mfuvorot, $this->mfauvorot,
|
||||
$this->bron1, $this->bron2, $this->bron3, $this->bron4, $this->maxu, $this->minu, $this->magic, $this->nlevel, $this->nalign, $this->dategoden, $this->goden, $this->razdel,
|
||||
$this->artefact, $this->koll);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Для кнопок управления под картинкой прелмета в зависимости от ситуации.
|
||||
*/
|
||||
public function printControls($shopType = false)
|
||||
{
|
||||
if ($shopType === 'marketput') {
|
||||
echo <<<BTN
|
||||
<form method="post">
|
||||
<input placeholder="{$this->cost}" name="cost">
|
||||
<input type="hidden" name="putId" value="{$this->id}">
|
||||
<br><input type="submit" name="putToMarket" value="Cдать в магазин">
|
||||
</form>
|
||||
BTN;
|
||||
|
||||
} else {
|
||||
switch ($shopType) {
|
||||
default:
|
||||
$btnValue = "Купить за " . intval($this->cost) . " кр.";
|
||||
$btnLink = "/shop.php?buy={$this->id}&rnd=" . mt_rand();
|
||||
break;
|
||||
case 'sell':
|
||||
$btnValue = "Продать";
|
||||
$btnLink = "/shop.php?sell={$this->id}&rnd=" . mt_rand();
|
||||
break;
|
||||
case 'marketgetback':
|
||||
$btnValue = "Снять с продажи";
|
||||
$btnLink = "?back={$this->id}&rnd=" . mt_rand();
|
||||
break;
|
||||
case 'marketbuy':
|
||||
$btnValue = "Купить за " . intval($this->setsale) . " кр.";
|
||||
$btnLink = "?otdel={$this->otdel}&set={$this->id}&rnd=" . mt_rand();
|
||||
break;
|
||||
}
|
||||
|
||||
echo <<<BTN
|
||||
<p><input type="button" style="background: darkgrey; border: 1px solid grey; border-radius: 2px;" value="{$btnValue}"
|
||||
onclick="location='{$btnLink}'">
|
||||
BTN;
|
||||
if ($this->count > 0) echo "<br><small>В наличии: {$this->count} штук</small>";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
# Date: 30.09.2020 (09:42)
|
||||
namespace Battles;
|
||||
class Template
|
||||
{
|
||||
/**
|
||||
* Template constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $title
|
||||
* @param int|null $return
|
||||
*
|
||||
* @return false|string
|
||||
*/
|
||||
public static function header(string $title = null, int $return = null)
|
||||
{
|
||||
$head = <<<HTML_HEADER
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<meta charset="utf-8">
|
||||
<link href="/css/main.css" rel="stylesheet">
|
||||
<link href="/css/btn.css" rel=stylesheet >
|
||||
<title>$title</title>
|
||||
HTML_HEADER;
|
||||
if (!$return) {
|
||||
echo $head;
|
||||
return false;
|
||||
}
|
||||
return $head;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $buildingName название здания
|
||||
* @param string $streetName служебное название улицы на которой стоит здание для кнопки возврата.
|
||||
* @return string
|
||||
*/
|
||||
public static function buildingTop(string $buildingName, string $streetName): void
|
||||
{
|
||||
echo <<<HTML
|
||||
<div style="float: right">
|
||||
<button onclick="top.frames['gameframe'].location = 'city.php?$streetName'">Выйти из здания</button>
|
||||
</div>
|
||||
<h1>$buildingName</h1>
|
||||
HTML;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
# Date: 26.10.2020 (16:08)
|
||||
namespace Battles;
|
||||
class Travel
|
||||
{
|
||||
/**
|
||||
* Соответствие ID комнаты игровому файлу.
|
||||
* @var string[]
|
||||
*/
|
||||
private static $roomFileName = [
|
||||
1 => 'main.php',
|
||||
20 => 'city.php',
|
||||
21 => 'city.php',
|
||||
22 => 'shop.php',
|
||||
23 => 'repair.php',
|
||||
25 => 'comission.php',
|
||||
26 => 'city.php',
|
||||
27 => 'post.php',
|
||||
29 => 'bank.php',
|
||||
30 => 'clan_create.php',
|
||||
31 => 'tower.php',
|
||||
34 => 'fshop.php',
|
||||
37 => 'gotzamok.php',
|
||||
51 => 'city.php',
|
||||
61 => 'akadem.php',
|
||||
401 => 'hell.php',
|
||||
402 => 'lab_chaos_enter.php',
|
||||
404 => 'vxod.php',
|
||||
603 => 'aren_of_angels.php',
|
||||
620 => 'enter_cave.php',
|
||||
650 => 'ul_clans.php',
|
||||
660 => 'hostel.php',
|
||||
666 => 'jail.php',
|
||||
777 => 'obshaga.php',
|
||||
1051 => 'lab_enter.php',
|
||||
1055 => 'group_arena.php',
|
||||
2111 => 'city.php',
|
||||
2601 => 'city.php',
|
||||
2655 => 'city.php',
|
||||
2702 => 'city.php'
|
||||
];
|
||||
|
||||
/**
|
||||
* Перемещение по комнатам.
|
||||
* @param int $roomId ID куда идём.
|
||||
* @param int $roomIdCurrent ID откуда идём.
|
||||
* @throws \Krugozor\Database\Mysql\Exception
|
||||
*/
|
||||
public static function toRoom(int $roomId, int $roomIdCurrent): void
|
||||
{
|
||||
$itemsWeight = \db::c()->query('SELECT SUM(weight) AS all_weight FROM `inventory` WHERE owner_id = ?i AND on_sale = 0', $_SESSION['uid'])->fetch_assoc();
|
||||
$eff = \db::c()->query('SELECT type FROM users_effects WHERE owner_id = ?i AND (`type` = 10 OR `type` = 13 OR `type` = 14)', $_SESSION['uid'])->fetch_assoc();
|
||||
$errors = [];
|
||||
if ($itemsWeight['all_weight'] > get_meshok()) {
|
||||
$errors[0] = 'У вас переполнен рюкзак, вы не можете передвигаться...';
|
||||
}
|
||||
if ($eff['type'] == 10) {
|
||||
$errors[1] = 'Вы парализованы и не можете передвигаться...';
|
||||
}
|
||||
if ($eff['type'] == 13 || $eff['type'] == 14) {
|
||||
$errors[2] = 'У вас тяжелая травма, вы не можете передвигаться...';
|
||||
}
|
||||
if ($errors) {
|
||||
foreach ($errors as $error) {
|
||||
echo sprintf('<span class="error">%s</span>', $error);
|
||||
}
|
||||
} elseif (in_array($roomId, self::allowedRoomMoves($roomIdCurrent))) {
|
||||
\db::c()->query('UPDATE users, online SET users.room = ?i, online.room = ?i WHERE `online`.`user_id` = `users`.`id` AND `online`.`user_id` = ?i', $roomId, $roomId, $_SESSION['uid']);
|
||||
header('location: ' . self::$roomFileName[$roomId]);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверка можно ли перейти из комнаты в комнату.
|
||||
* @param int $roomId ID комнаты
|
||||
* @return array|int[]
|
||||
*/
|
||||
private static function allowedRoomMoves(int $roomId): array
|
||||
{
|
||||
/*
|
||||
* 1 location: main.php?goto=arena
|
||||
* 2 Room 22 shop.php
|
||||
* 3 Room 25 comission.php
|
||||
* 4 Room 23 repair.php
|
||||
* 6 Room 27 posr.php
|
||||
* 7 Room 21 [STREET]
|
||||
* 8 Room 26 [STREET]
|
||||
* 13 location: quest_room.php
|
||||
* 222 Room 2702 [STREET]
|
||||
*/
|
||||
$room[20] = [1, 21, 22, 23, 25, 26, 27, 2702];
|
||||
$room[1] = $room[22] = $room[23] = $room[25] = $room[27] = [20];
|
||||
/*
|
||||
* 3 Room 2111 [STREET]
|
||||
* 4 Room 20 [STREET]
|
||||
* 5 Room 29 Bank.php
|
||||
* 13 Room 34 fshop.php
|
||||
* 14 Room 30 clan_create.php
|
||||
* 16 Room 31 tower.php
|
||||
* 650 Room 650 ul_clans.php
|
||||
*/
|
||||
$room[21] = [20, 29, 30, 31, 34, 650, 2111];
|
||||
$room[29] = $room[30] = $room[31] = $room[34] = [21];
|
||||
|
||||
$room[26] = [20, 401, 660, 777, 2601];
|
||||
$room[401] = $room[660] = $room[777] = [26];
|
||||
|
||||
$room[2601] = [26, 37, 404, 1051, 2655];
|
||||
|
||||
$room[2655] = [603, 2601];
|
||||
|
||||
/*
|
||||
* 1 Room 21 [STREET]
|
||||
* 2 location: city.php?haos - где эта херня вообще?
|
||||
* 14 NULL
|
||||
* 21 NULL
|
||||
* 203 Room 1055 group_arena.php
|
||||
* [!not on map]666 Room 666 jail.php
|
||||
* 1000
|
||||
*/
|
||||
$room[2111] = [21, 620, 666, 1055];
|
||||
$room[2701] = [402, 2111];
|
||||
$room[2702] = [20, 61];
|
||||
if ($room[$roomId] === null) {
|
||||
return [];
|
||||
}
|
||||
return $room[$roomId];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
namespace Battles;
|
||||
use Exceptions\GameException;
|
||||
|
||||
class User
|
||||
{
|
||||
public $id = 0;
|
||||
public $login = '<em>Некто</em>';
|
||||
public $pass;
|
||||
public $email = '<em>неизвестно</em>';
|
||||
public $realname;
|
||||
public $borndate;
|
||||
public $info;
|
||||
public $level = 0;
|
||||
public $align = 0;
|
||||
public $clan = 0;
|
||||
public $money = 0;
|
||||
public $strength = 0;
|
||||
public $dexterity = 0;
|
||||
public $intuition = 0;
|
||||
public $endurance = 0;
|
||||
public $intelligence = 0;
|
||||
public $wisdom = 0;
|
||||
public $health;
|
||||
public $mana;
|
||||
public $ip;
|
||||
public $session_id;
|
||||
public $admin = 0;
|
||||
public $enter_game;
|
||||
public $room;
|
||||
public $block;
|
||||
public $shadow;
|
||||
// Удар кулаком всегда 1-2.
|
||||
public $minDamage = 1;
|
||||
public $maxDamage = 2;
|
||||
//Броня без предметов не существует.
|
||||
public $headArmor = 0;
|
||||
public $chestArmor = 0;
|
||||
public $legArmor = 0;
|
||||
public $free_stat_points = 0;
|
||||
public const STAT_MAXIMUM_AMOUNT = 40;
|
||||
private const ERROR_STAT_IS_MAXIMUM = 'Ошибка: Параметр достиг своего лимита!';
|
||||
private const ERROR_STAT_UNKNOWN = 'Ошибка: Неизвестный параметр!';
|
||||
// Пока несуществующие, для совместимости.
|
||||
public $married = 'Someone или нет.';
|
||||
public $experience = 200;
|
||||
public $battle = 0;
|
||||
public $in_tower = 0; // Скорее башню похороним чем запустим...
|
||||
public $zayavka = 0;
|
||||
// Динамически рассчитываемые
|
||||
public $maxHealth = 5;
|
||||
public $maxMana = 5;
|
||||
|
||||
public function __construct($user)
|
||||
{
|
||||
$user_query = \db::c()->query('SELECT * FROM users WHERE id = "?s" OR login = "?s"', $user, $user)->fetch_assoc();
|
||||
foreach ($this as $key => $value) {
|
||||
if (isset($user_query[$key])) {
|
||||
$this->$key = $user_query[$key];
|
||||
}
|
||||
}
|
||||
$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
|
||||
* @throws GameException
|
||||
*/
|
||||
public function getStat($stat_name, $isMainWindow = 0)
|
||||
{
|
||||
$allowed = ['strength', 'dexterity', 'intuition', 'endurance', 'intelligence', 'wisdom'];
|
||||
if (in_array($stat_name, $allowed)) {
|
||||
if ($this->free_stat_points && $isMainWindow && $this->$stat_name < self::STAT_MAXIMUM_AMOUNT) {
|
||||
return sprintf('%s <a href="/main.php?edit=%s&ups=%s">[+]</a>', $this->$stat_name, mt_rand(), $stat_name);
|
||||
} else {
|
||||
return $this->$stat_name;
|
||||
}
|
||||
} else {
|
||||
throw new \Exceptions\GameException(self::ERROR_STAT_UNKNOWN);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Повышает один из выбранных статов на 1, но не выше self::STAT_MAXIMUM_AMOUNT при условии наличия свободных очков статов.
|
||||
* @param $stat_name - имя стата. Может принимать значения 'strength', 'dexterity', 'intuition', 'endurance', 'intelligence', 'wisdom'.
|
||||
* @throws GameException
|
||||
*/
|
||||
public function addOnePointToStat($stat_name)
|
||||
{
|
||||
$allowed = ['strength', 'dexterity', 'intuition', 'endurance', 'intelligence', 'wisdom'];
|
||||
if (in_array($stat_name, $allowed)) {
|
||||
if ($this->free_stat_points > 0 && $this->$stat_name <= self::STAT_MAXIMUM_AMOUNT) {
|
||||
$query = 'UPDATE users SET ?f = ?f + 1, free_stat_points = free_stat_points - 1 WHERE id = ?i';
|
||||
\db::c()->query($query, $stat_name, $stat_name, $this->id);
|
||||
} else {
|
||||
throw new \Exceptions\GameException(self::ERROR_STAT_IS_MAXIMUM);
|
||||
}
|
||||
} else {
|
||||
throw new \Exceptions\GameException(self::ERROR_STAT_UNKNOWN);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected function showStarSign()
|
||||
{
|
||||
/*
|
||||
* 1 aries
|
||||
* 2 taurus
|
||||
* 3 gemini
|
||||
* 4 cancer
|
||||
* 5 leo
|
||||
* 6 virgo
|
||||
* 7 libra
|
||||
* 8 scorpio
|
||||
* 9 sagittarios
|
||||
* 10 capricorn
|
||||
* 11 aquarius
|
||||
* 12 pisches
|
||||
*/
|
||||
$zodiac[356] = "10";
|
||||
$zodiac[326] = "09";
|
||||
$zodiac[296] = "08";
|
||||
$zodiac[266] = "07";
|
||||
$zodiac[235] = "06";
|
||||
$zodiac[203] = "05";
|
||||
$zodiac[172] = "04";
|
||||
$zodiac[140] = "03";
|
||||
$zodiac[111] = "02";
|
||||
$zodiac[78] = "01";
|
||||
$zodiac[51] = "12";
|
||||
$zodiac[20] = "11";
|
||||
$zodiac[0] = "10";
|
||||
$dayOfYear = date("z", strtotime($this->borndate));
|
||||
$isLeapYear = date("L", strtotime($this->borndate)); //Высокосный?
|
||||
if ($isLeapYear && $dayOfYear > 59) {
|
||||
--$dayOfYear;
|
||||
}
|
||||
foreach ($zodiac as $day => $sign) {
|
||||
if ($dayOfYear > $day) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $sign ?? null;
|
||||
}
|
||||
|
||||
public function getHealth(): string
|
||||
{
|
||||
return $this->health . '/' . $this->maxHealth;
|
||||
}
|
||||
|
||||
public function getMana(): string
|
||||
{
|
||||
return $this->mana . '/' . $this->maxMana;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
# Date: 16.09.2020 (08:28)
|
||||
# Названия эффектов, налагаемых на персонажа.
|
||||
namespace Battles;
|
||||
trait UserEffects
|
||||
{
|
||||
public static $effectName = [
|
||||
10 => 'паралич',
|
||||
11 => 'легкая травма',
|
||||
12 => 'средняя травма',
|
||||
13 => 'тяжёлая травма',
|
||||
14 => 'неизлечимая травма',
|
||||
1022 => 'невидимость',
|
||||
2 => 'Заклинание молчания',
|
||||
3 => 'Заклятие форумного молчания',
|
||||
4 => 'Заклятие хаоса',
|
||||
5 => 'Заклятие обезличивания',
|
||||
20 => 'Проверка Паладинов',
|
||||
21 => 'Сила нейтралитета',
|
||||
22 => 'Защита от кулачного нападения',
|
||||
51 => 'Опьянение',
|
||||
201 => 'Защита от оружия',
|
||||
202 => 'Сокрушение',
|
||||
203 => 'Туманный образ [1]',
|
||||
204 => 'Туманный образ [2]',
|
||||
205 => 'Туманный образ [3]',
|
||||
206 => 'Гравитация [1]',
|
||||
207 => 'Гравитация [2]',
|
||||
208 => 'Гравитация [3]',
|
||||
209 => 'Стена Огня [1]',
|
||||
210 => 'Стена Огня [2]',
|
||||
211 => 'Стена Огня [3]',
|
||||
212 => 'Чистота Воды [1]',
|
||||
213 => 'Чистота Воды [2]',
|
||||
214 => 'Чистота Воды [3]',
|
||||
215 => 'Защита эфира [1]',
|
||||
216 => 'Защита эфира [2]',
|
||||
217 => 'Защита эфира [3]',
|
||||
218 => 'Песчаный щит [1]',
|
||||
219 => 'Песчаный щит [2]',
|
||||
220 => 'Песчаный щит [3]',
|
||||
221 => 'Огненный Щит [1]',
|
||||
222 => 'Огненный Щит [2]',
|
||||
223 => 'Огненный Щит [3]',
|
||||
224 => 'Стена Воды [1]',
|
||||
225 => 'Стена Воды [2]',
|
||||
226 => 'Стена Воды [3]',
|
||||
227 => 'Защита от нападений',
|
||||
405 => 'Микстура жизненных сил',
|
||||
9994 => 'Антидот/Путы (Эликсир?)',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
<?php
|
||||
namespace Battles;
|
||||
class UserInfo extends User
|
||||
{
|
||||
use Rooms;
|
||||
//Статусы того, кто смотрит на информацию.
|
||||
public $watcher_id;
|
||||
private $watcherIsAdmin;
|
||||
private $watcherIsModerator;
|
||||
|
||||
/**
|
||||
* Отображает куклу персонажа (образ и слоты).
|
||||
*
|
||||
* @param int $isBattle - установить 1, если куклу нужно отобразить в поединке (показывает параметры при наведении
|
||||
* на образ).
|
||||
* @param int $isMain - установить 1, если куклу надо показать на странице игрока (по клику на предмет снимает
|
||||
* его).
|
||||
*
|
||||
* @throws \Krugozor\Database\Mysql\Exception
|
||||
*/
|
||||
private function UserInfoDoll($isBattle = 0, $isMain = 0)
|
||||
{
|
||||
//https://jsfiddle.net/ngx0yvhc
|
||||
//TODO переверстать grid, чтобы он касался только куклы.
|
||||
$di = new DressedItems($this->id);
|
||||
$dressedItems = $di->getItemsInSlots();
|
||||
for ($i = 1; $i <= 12; $i++) {
|
||||
echo sprintf('<div class="slot-%s">', $i);
|
||||
if (!empty($dressedItems[$i])) {
|
||||
if (!$isBattle && $isMain) {
|
||||
$itemString = '<a href="?edit=%s&drop=%s"><img src="/i/sh/%s" class="item-wrap-normal" alt="%s" title="%s"></a>';
|
||||
echo sprintf($itemString, mt_rand(), $i, $dressedItems[$i]['image'], $dressedItems[$i]['name'], $dressedItems[$i]['name']);
|
||||
} else {
|
||||
$itemString = '<img src="/i/sh/%s" class="item-wrap-normal tip" alt="%s"><span class="tiptext"><strong>%s</strong></span>';
|
||||
echo sprintf($itemString, $dressedItems[$i]['image'], $dressedItems[$i]['name'], $dressedItems[$i]['name']);
|
||||
}
|
||||
} else {
|
||||
echo sprintf('<img src="/i/sh/noitem.png" class="item-wrap-normal" title="Пустой слот [%s]" alt="Пустой слот [%s]">', $i, $i);
|
||||
}
|
||||
echo sprintf('</div><!-- slot-%s -->', $i);
|
||||
}
|
||||
echo '<div class="slot-image">';
|
||||
if ($isBattle) {
|
||||
$sh = '<img src="/i/shadow/%s" alt="%s" class="tip"><span class="tiptext"><b>%s</b>Уровень: %s<br>Сила: %s<br>Ловкость: %s<br>Интуиция: %s<br>Выносливость: %s<br>Интеллект: %s<br>Мудрость: %s</span>';
|
||||
echo sprintf($sh, $this->shadow, $this->login, $this->login, $this->level, $this->strength, $this->dexterity, $this->intuition, $this->endurance, $this->intelligence, $this->wisdom);
|
||||
unset($sh);
|
||||
} else {
|
||||
echo '<img src="/i/shadow/' . $this->shadow . '" alt="' . $this->login . '">';
|
||||
}
|
||||
echo '</div><!-- slot-image -->';
|
||||
}
|
||||
|
||||
private function UserInfoStats($isMainWindow = 0)
|
||||
{
|
||||
$captions = 'Уровень:<br>Сила:<br>Ловкость:<br>Интуиция:<br>Выносливость:<br>Интеллект:<br>Мудрость:<br>Местонахождение:';
|
||||
$variables =
|
||||
$this->level . '<br>' .
|
||||
parent::getStat('strength') . '<br>' .
|
||||
parent::getStat('dexterity') . '<br>' .
|
||||
parent::getStat('intuition') . '<br>' .
|
||||
parent::getStat('endurance') . '<br>' .
|
||||
parent::getStat('intelligence') . '<br>' .
|
||||
parent::getStat('wisdom') . '<br>' .
|
||||
Rooms::$roomNames[$this->room];
|
||||
if ($isMainWindow) {
|
||||
$this->Bank = new Bank($this->id);
|
||||
$captions = 'Уровень:<br>Здоровье:<br>Сила:<br>Ловкость:<br>Интуиция:<br>Выносливость:<br>Интеллект:<br>Мудрость:<br>Опыт:<br>Очки характеристик:<br>Деньги:<br>Деньги в банке:';
|
||||
$variables =
|
||||
$this->level . '<br>' .
|
||||
$this->health . '<br>' .
|
||||
parent::getStat('strength', 1) . '<br>' .
|
||||
parent::getStat('dexterity', 1) . '<br>' .
|
||||
parent::getStat('intuition', 1) . '<br>' .
|
||||
parent::getStat('endurance', 1) . '<br>' .
|
||||
parent::getStat('intelligence', 1) . '<br>' .
|
||||
parent::getStat('wisdom', 1) . '<br>' .
|
||||
$this->experience . '<br>' .
|
||||
$this->free_stat_points . '<br>' .
|
||||
$this->money . '<br>' .
|
||||
$this->Bank->getMoney();
|
||||
}
|
||||
$nameString = '';
|
||||
if ($this->align) {
|
||||
$nameString = sprintf('<img src="/i/align_%s.png" alt="Склонность">', $this->align);
|
||||
}
|
||||
if ($this->block) {
|
||||
$nameString .= '<span class="private"><s>' . $this->login . '</s></span>';
|
||||
} else {
|
||||
$nameString .= ' <b>' . $this->login . '</b> ';
|
||||
}
|
||||
if ($this->clan) {
|
||||
$nameString .= sprintf('<img src="/i/clan/%s.png" alt="Клан">', $this->clan);
|
||||
}
|
||||
echo '<div class="user-info">';
|
||||
echo '<div class="info">';
|
||||
echo '<b>' . $nameString . '</b>';
|
||||
echo '</div><!-- info -->';
|
||||
echo '<div class="stats-container">';
|
||||
echo '<div class="column">';
|
||||
echo $captions;
|
||||
echo '</div><!-- column -->';
|
||||
echo '<div class="column">';
|
||||
echo $variables;
|
||||
echo '</div><!-- column -->';
|
||||
echo '</div><!-- stats-container -->';
|
||||
echo '<div class="debug">TODO: Сделать рассчёт модификаторов. Вывести полоску здоровья когда будет от чего отталкиваться.</div>';
|
||||
echo '</div><!-- user-info -->';
|
||||
}
|
||||
|
||||
private function Info()
|
||||
{
|
||||
echo '<div class="user-info-container">';
|
||||
$this->UserInfoDoll();
|
||||
$this->UserInfoStats();
|
||||
echo '<div class="slot-lower">';
|
||||
if ($this->married) {
|
||||
echo sprintf('<a href = "inf.php?%s" target = _blank ><img alt = "В браке с %s" src = "i/married.gif" title = "В браке с %s"></a >', $this->married, $this->married, $this->married);
|
||||
}
|
||||
echo '</div><!-- slot-lower -->';
|
||||
echo '<div class="user-signs">';
|
||||
echo sprintf('<img src="i/zodiac/%s.png" alt="Родовой знак">', $this->showStarSign());
|
||||
echo '</div><!-- user-signs -->';
|
||||
echo '</div><!-- user-info-container -->';
|
||||
echo '<hr><!-- Нижняя часть -->';
|
||||
echo '<div class="user-info-container-lower">';
|
||||
echo '<h2>Об игроке</h2>';
|
||||
if ($this->realname) {
|
||||
echo sprintf('Имя: %s<br>', $this->realname);
|
||||
}
|
||||
if ($this->info) {
|
||||
echo nl2br($this->info);
|
||||
}
|
||||
echo '</div><!-- user-info-container-lower -->';
|
||||
|
||||
if ($this->watcherIsAdmin || $this->watcherIsModerator) {
|
||||
echo '<div class="secret-info">';
|
||||
$infoString = 'E-Mail: %s<br> ДР Игрока: %s<br> IP Регистрации: %s';
|
||||
echo sprintf($infoString, $this->email, date('d.m.Y', strtotime($this->borndate)), $this->ip);
|
||||
if ($this->watcherIsAdmin) {
|
||||
$this->Bank = new Bank($this->id);
|
||||
$infoString = '<br><span>ИД Игрока: %s<br> ИД Комнаты: %s<br> Деньги: %s<br> Деньги в банке: %s<br> Опыт: %s<br> Нераспределённые очки: %s<br> Текущая сессия: %s</span>';
|
||||
echo sprintf($infoString, $this->id, $this->room, $this->money, $this->Bank->getMoney(), $this->experience, $this->free_stat_points, $this->session_id);
|
||||
}
|
||||
$this->UserLogs = new \Battles\Models\UserLogModel($this->id);
|
||||
echo '<div class="secret-info-user-log"><b>Личное дело</b><br>';
|
||||
while ($userLogRow = $this->UserLogs->getUserLog()->fetch_object()) {
|
||||
echo sprintf('<code>%s</code><br>', date("d.m.Y H:i ", strtotime($userLogRow->date)) . $userLogRow->text);
|
||||
}
|
||||
echo '</div><!-- secret-info-user-log -->';
|
||||
echo '</div><!-- secret-info -->';
|
||||
}
|
||||
}
|
||||
|
||||
public function showUserInfo()
|
||||
{
|
||||
$this->effects = new \Battles\Models\EffectsModel($this->id);
|
||||
$this->WatcherStatus();
|
||||
|
||||
if ($this->block && (!$this->watcherIsAdmin || !$this->watcherIsModerator)) {
|
||||
throw new \Exceptions\GameException('<span class="error">Персонаж ' . $this->login . ' заблокирован!</span>');
|
||||
} elseif ($this->effects->getHideUserInfoStatus() && (!$this->watcherIsAdmin || !$this->watcherIsModerator)) {
|
||||
if ($this->effects->getHideUserInfoStatus() == -1) {
|
||||
$date = 'навсегда';
|
||||
} else {
|
||||
$date = 'до' . date('d.m.Y', strtotime($this->effects->getHideUserInfoStatus()));
|
||||
}
|
||||
throw new \Exceptions\GameException('<span class="error">Персонаж ' . $this->login . ' обезличен ' . $date . '.</span>');
|
||||
} else {
|
||||
$this->Info();
|
||||
}
|
||||
}
|
||||
|
||||
private function WatcherStatus()
|
||||
{
|
||||
$query = db::c()->query('SELECT `align`,`admin` FROM `users` WHERE `id` = ?i', $this->watcher_id)->fetch_assoc();
|
||||
if ($query['admin']) {
|
||||
$this->watcherIsAdmin = 1;
|
||||
}
|
||||
if ($query['align'] == 1) {
|
||||
$this->watcherIsModerator = 1;
|
||||
}
|
||||
}
|
||||
|
||||
public function showUserDoll($isBattle = 0, $isMain = 0)
|
||||
{
|
||||
echo '<div class="user-info-container">';
|
||||
$this->UserInfoDoll($isBattle, $isMain);
|
||||
echo '</div><!-- user-info-container -->';
|
||||
}
|
||||
|
||||
public function showUserInfoMain()
|
||||
{
|
||||
echo '<div class="user-info-container">';
|
||||
$this->UserInfoDoll();
|
||||
$this->userInfoStats(1);
|
||||
echo '</div><!-- user-info-container -->';
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user