Compare commits

...

3 Commits

Author SHA1 Message Date
Ivor Barhansky 0398425205 Code smell. 2022-12-17 03:03:56 +02:00
lopar b1f578f4b0 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	admin/admin.php
#	classes/Battles/User.php
#	classes/Battles/UserStats.php
#	fbattle.php
#	functions.php
2022-08-10 02:34:12 +03:00
lopar b9b4c01cf0 Зимние правки. MVC/
Signed-off-by: lopar <lopar.4ever@gmail.com>
2022-08-09 22:57:43 +03:00
122 changed files with 2808 additions and 2544 deletions

View File

@ -15,86 +15,142 @@ if (isset($_POST)) {
<tr>
<th id="main">Основное
<tr>
<td><input name="name" placeholder="Название">
<td><label>
<input name="name" placeholder="Название">
</label>
<tr>
<td><input name="image" placeholder="Картинка">
<td><label>
<input name="image" placeholder="Картинка">
</label>
<tr>
<td><select name="shop">
<option value="0" selected disabled>Тип магазина</option>
<option value="1">Обычный</option>
<option value="2">Цветной</option>
</select>
<td><label>
<select name="shop">
<option value="0" selected disabled>Тип магазина</option>
<option value="1">Обычный</option>
<option value="2">Цветной</option>
</select>
</label>
<tr>
<td><input name=count placeholder="Количество (шт.)" disabled>
<td><label>
<input name=count placeholder="Количество (шт.)" disabled>
</label>
<tr>
<td><select name="item_type">
<option value="0" selected disabled>Тип предмета</option>
<option value="1">Шлем</option>
<option value="2">Броня</option>
<option value="3">Поножи</option>
<option value="4">Сапоги</option>
<option value="5">Перчатки</option>
<option value="6">Оружие</option>
<option value="7">Щит</option>
<option value="8">Пояс</option>
<option value="9">Кольцо</option>
<option value="10">Амулет</option>
<option value="20">Расходник</option>
<option value="50">Всё остальное</option>
<option value="100">Хлам</option>
</select>
<td><label>
<select name="item_type">
<option value="0" selected disabled>Тип предмета</option>
<option value="1">Шлем</option>
<option value="2">Броня</option>
<option value="3">Поножи</option>
<option value="4">Сапоги</option>
<option value="5">Перчатки</option>
<option value="6">Оружие</option>
<option value="7">Щит</option>
<option value="8">Пояс</option>
<option value="9">Кольцо</option>
<option value="10">Амулет</option>
<option value="20">Расходник</option>
<option value="50">Всё остальное</option>
<option value="100">Хлам</option>
</select>
</label>
<tr>
<td><input name=weight placeholder="Масса">
<td><label>
<input name=weight placeholder="Масса">
</label>
<tr>
<td><input name=durability placeholder="Макс. износ">
<td><label>
<input name=durability placeholder="Макс. износ">
</label>
<tr>
<td><input name=price placeholder="Цена (кр.)" disabled>
<td><label>
<input name=price placeholder="Цена (кр.)" disabled>
</label>
<tr>
<th id="needs">Требования
<tr>
<td><input name=need_level placeholder="Уровень">
<td><label>
<input name=need_level placeholder="Уровень">
</label>
<tr>
<td><input name=need_strength placeholder="Сила">
<td><label>
<input name=need_strength placeholder="Сила">
</label>
<tr>
<td><input name=need_dexterity placeholder="Ловкость">
<td><label>
<input name=need_dexterity placeholder="Ловкость">
</label>
<tr>
<td><input name=need_intuition placeholder="Интуиция">
<td><label>
<input name=need_intuition placeholder="Интуиция">
</label>
<tr>
<td><input name=need_endurance placeholder="Выносливость">
<td><label>
<input name=need_endurance placeholder="Выносливость">
</label>
<tr>
<td><input name=need_intelligence placeholder="Интеллект">
<td><label>
<input name=need_intelligence placeholder="Интеллект">
</label>
<tr>
<td><input name=need_wisdom placeholder="Мудрость">
<td><label>
<input name=need_wisdom placeholder="Мудрость">
</label>
<tr>
<th id="adds">Характеристики
<tr>
<td><input name=minu placeholder="Мин.урон">
<td><label>
<input name=minu placeholder="Мин.урон">
</label>
<tr>
<td><input name=maxu placeholder="Макс.урон">
<td><label>
<input name=maxu placeholder="Макс.урон">
</label>
<tr>
<td><input name=add_strength placeholder="Сила">
<td><label>
<input name=add_strength placeholder="Сила">
</label>
<tr>
<td><input name=add_dexterity placeholder="Ловкость">
<td><label>
<input name=add_dexterity placeholder="Ловкость">
</label>
<tr>
<td><input name=add_intuition placeholder="Интуиция">
<td><label>
<input name=add_intuition placeholder="Интуиция">
</label>
<tr>
<td><input name=add_endurance placeholder="Выносливость">
<td><label>
<input name=add_endurance placeholder="Выносливость">
</label>
<tr>
<td><input name=add_intelligence placeholder="Интеллект">
<td><label>
<input name=add_intelligence placeholder="Интеллект">
</label>
<tr>
<td><input name=add_wisdom placeholder="Мудрость">
<td><label>
<input name=add_wisdom placeholder="Мудрость">
</label>
<tr>
<td><input name=add_accuracy placeholder="Точность">
<td><label>
<input name=add_accuracy placeholder="Точность">
</label>
<tr>
<td><input name=add_evasion placeholder="Уворот">
<td><label>
<input name=add_evasion placeholder="Уворот">
</label>
<tr>
<td><input name=add_criticals placeholder="Крит">
<td><label>
<input name=add_criticals placeholder="Крит">
</label>
<tr>
<td><input name=add_min_physical_damage placeholder="Мин.удар">
<td><label>
<input name=add_min_physical_damage placeholder="Мин.удар">
</label>
<tr>
<td><input name=add_min_physical_damage placeholder="Макс.удар">
<td><label>
<input name=add_min_physical_damage placeholder="Макс.удар">
</label>
</table>
<INPUT TYPE="submit" value="Добавить">
</div>
</form>
</form>

View File

@ -123,4 +123,4 @@ Template::header('ᐰdminка');
</form>
<span class="legend">Невидимки</span><br>
<div class="abils" style="width: fit-content; font-weight: bold;"><?= AUser::getInvisiblesList() ?></div>
<div class="abils" style="width: fit-content; font-weight: bold;"><?= AUser::getInvisiblesList() ?></div>

View File

@ -20,6 +20,7 @@ $player = $_POST['player'] ?? null;
$undress_char = $_POST['undress_char'] ?? null;
$end = $_POST['end'] ?? null;
$del = $_POST['del'] ?? null;
$inv = [];
if ($player) {
$row = Db::getInstance()->ofetch('select id, login from users where id = ? or login = ?', [$player, $player]);
@ -35,10 +36,10 @@ if ($end) {
unset($_SESSION['player_name']);
}
if (isset($_SESSION['player_id'])) {
$inv = db::c()->query('SELECT item_id, name, image FROM inventory WHERE owner = ?i ORDER BY id DESC', $_SESSION['player_id']);
$inv = Db::getInstance()->fetchAll('SELECT item_id, name, image FROM inventory WHERE owner_id = ? ORDER BY item_id DESC', $_SESSION['player_id']);
}
if ($del) {
$itemdel = db::c()->query('SELECT item_type, dressed_slot FROM inventory WHERE id=?i', $del)->fetch_assoc();
$itemdel = Db::getInstance()->fetch('SELECT item_type, dressed_slot FROM inventory WHERE item_id = ?', $del);
if ($itemdel['dressed_slot'] == 1) {
$item = new DressedItems($del);
$item->undressItem($itemdel['item_type']);
@ -47,34 +48,36 @@ if ($del) {
$item->undressItem(7);
}
}
Db::getInstance()->execute('delete from inventory where id = ?', $del);
Db::getInstance()->execute('delete from inventory where item_id = ?', $del);
}
Template::header('ᐰdminка инвентаря');
?>
<h1>Администрирование инвентаря <?php if (isset($_SESSION['player_name'])) echo $_SESSION['player_name']; ?></h1>
<h1>Администрирование инвентаря <?php if (isset($_SESSION['player_name'])) { echo $_SESSION['player_name']; } ?></h1>
<table class='adm'>
<tr>
<th>ID</th>
<th>Название</th>
<th>Количество</th>
<th>Картинка</th>
<th></th>
<th scope="col">ID</th>
<th scope="col">Название</th>
<th scope="col">Количество</th>
<th scope="col">Картинка</th>
<th scope="col"></th>
</tr>
<?php if (empty($_SESSION['player_id'])): ?>
<tr>
<th colspan="5">
<th scope="col" colspan="5">
<form method="post">
<input placeholder="Логин или ID" name="player">
<label>
<input placeholder="Логин или ID" name="player">
</label>
<input type="submit">
</form>
</th>
</tr>
<?php else: while ($row = $inv->fetch_assoc()): ?>
<?php else: foreach ($inv as $row): ?>
<tr>
<td><?= $row['id'] ?></td>
<td><?= $row['name'] ?></td>
<td><?= $row['koll'] ?></td>
<td><img src='/i/sh/<?= $row['img'] ?>'></td>
<td><img src='/i/sh/<?= $row['img'] ?>' alt=""></td>
<td>
<form method='post'>
<input name='del' type='hidden' value='<?= $row['id'] ?>'>
@ -82,7 +85,7 @@ Template::header('ᐰdminка инвентаря');
</form>
</td>
</tr>
<?php endwhile; ?>
<?php endforeach; ?>
<th colspan='6'>
<form method='post'>
<input name='undress_char' type='submit' value='Стриптиз'>
@ -92,4 +95,4 @@ Template::header('ᐰdminка инвентаря');
</form>
</th>
<?php endif; ?>
</table>
</table>

View File

@ -1,73 +0,0 @@
<?php
include "config.php";
//$user = mysql_fetch_array(mysql_query("SELECT * FROM `users` WHERE `id` = '2106' LIMIT 1;"));
//include "functions.php";
//$komp_users = mysql_query("SELECT * FROM `users`,`online` WHERE `users`.`id`=`online`.`id` AND `online`.`date` >= ".(time()-60).";");
$komp_users = mysql_query("SELECT * FROM `users`;");
while($ku=mysql_fetch_array($komp_users))
{
$kompl_raw=mysql_query("SELECT * FROM inventory where owner=".$ku['id']." AND dressed=1");
$items_on_user=array();
$set_id_wear=array();
$kompl_har=0;
while ($kompl=mysql_fetch_array($kompl_raw))
{
$items_on_user[]=$kompl['prototype'];
}
$sets_raw=mysql_query("SELECT * FROM item_sets;");
while ($set_items=mysql_fetch_array($sets_raw))
{
$kompl_full=1;
$in_set=explode(',',$set_items['prot_id']);
foreach($in_set as $tmp_set)
if (!in_array($tmp_set,$items_on_user))
{$kompl_full=0;}
if ($kompl_full==1) $set_id_wear[]=$set_items['set_id'];
}
foreach($set_id_wear as $s)
{
$items_raw=mysql_fetch_array(mysql_query("SELECT * FROM item_sets where set_id='{$s}' limit 1;"));
$kompl_har+=$items_raw['gsila'];
$kompl_har+=$items_raw['glovk'];
$kompl_har+=$items_raw['gintel'];
$kompl_har+=$items_raw['ginta'];
}
if(!$kompl_har) $kompl_har=0;
$explim=0;
foreach(array_keys(EXPTABLE) as $k)
{
if($k>=$ku['exp'])
{
$explim=$k;
break;
}
}
$sum_stat=15;
foreach(array_keys(EXPTABLE) as $k)
{
if($k==$explim)
break;
else
{
$sum_stat+=EXPTABLE[$k][0];
$sum_stat+=EXPTABLE[$k][2];
}
}
$res=mysql_fetch_array(
mysql_query("SELECT IFNULL( (SUM( gsila ) + SUM( glovk ) + SUM( ginta ) + SUM( gintel )) , 0)+ {$kompl_har} + {$sum_stat}
FROM `inventory` WHERE `owner` = '{$ku['id']}' AND `dressed` = 1;"));
$res2=mysql_fetch_array(mysql_query("SELECT `sila`+`lovk`+`intel`+`inta`+`vinos`+`mudra`+`stats` FROM `users` WHERE `id`={$ku['id']};"));
if($res[0]!=$res2[0])
echo("<br/>".$kompl_har." _ ID=".$ku['id']."[".$ku['exp']."] : All=".$res2[0]."/norm=".$res[0]);
}

View File

@ -1,8 +1,8 @@
<?php
use Battles\Bank;
use Battles\GameLogs;
use Battles\Template;
use Battles\Travel;
use Battles\User;
require_once 'functions.php';
@ -13,7 +13,7 @@ const MEDIC = 'лекарь';
$status = 'Внимание! Моментальная оплата без подтверждения!';
$get = urldecode(filter_input(INPUT_SERVER, 'QUERY_STRING'));
function setProfession($name, $type, $needMoney, $needLevel)
function setProfession($name, $type, $needMoney, $needLevel): string
{
global $user;
$profId = 0;
@ -43,8 +43,7 @@ function setProfession($name, $type, $needMoney, $needLevel)
$profId = 22;
}
if (!empty($profId)) {
User::getInstance()->setMoney(User::getInstance()->getMoney() - $needMoney);
Bank::setWalletMoney(User::getInstance()->getMoney(), User::getInstance()->getId());
User::getInstance()->money()->spend($needMoney);
db::c()->query('UPDATE `users` SET ?f = ?i WHERE `id` = ?i', 'prof' . $type, $profId, User::getInstance()->getId());
$deloText = "{$user['login']} купил профессию «{$name}» в академии за {$needMoney} кр.";
GameLogs::addUserLog($_SESSION['uid'], $deloText);
@ -67,8 +66,7 @@ if ($get == 'medic') {
}
if ($get == 'exit') {
db::c()->query('UPDATE `users`,`online` SET `users`.`room` = 2702, `online`.`room` = 2702 WHERE `users`.`id` = ?i AND `online`.`id` = ?i', User::getInstance()->getId(), User::getInstance()->getId());
header('Location: city.php');
Travel::toRoom(2702, User::getInstance()->getRoom());
}
Template::header('Академия');
?>
@ -80,7 +78,7 @@ Template::header('Академия');
<div><?= $status ?></div>
<div class="appblock appblock-main">
<span class="legend">Информация</span>
<span class="wrap">Кредиты<span class="num"><?= User::getInstance()->getMoney() ?></span></span>
<span class="wrap">Кредиты<span class="num"><?= User::getInstance()->money()->get() ?></span></span>
<span class="wrap">Уровень персонажа<span class="num"><?= User::getInstance()->getLevel() ?></span></span>
</div>
<div class="appblock">

View File

@ -1,77 +1,23 @@
<?php
use Battles\Bank;
use Battles\GameConfigs;
use Battles\Rooms;
use Battles\Template;
use Exceptions\GameException;
use Battles\User;
require_once "functions.php";
const SUCCESS = "Успешная операция!";
$bank = new Bank(User::getInstance()->getId());
$status = '';
$_POST['action'] ??= null;
$bank = new Bank();
$toid = $_POST['to_id'] ?? 0;
$summa = $_POST['summa'] ?? 0;
$submit = $_POST['action'] ?? '';
try {
// Зачисление кредитов на счёт.
if ($submit === 'depositMoney' && $summa) {
$operation = $bank->depositMoney($summa);
User::getInstance()->setMoney($operation['walletMoney']);
$bank->setMoney($operation['bankMoney']);
$status = SUCCESS;
}
// Снятие кредитов со счёта.
if ($submit === 'withdrawMoney' && $summa) {
$operation = $bank->withdrawMoney($summa);
User::getInstance()->setMoney($operation['walletMoney']);
$bank->setMoney($operation['bankMoney']);
$status = SUCCESS;
}
// Перевод кредитов на другой счёт.
if ($submit === 'sendMoney' && $summa && $toid) {
User::getInstance()->setMoney($bank->sendMoney($toid, $summa));
$status = SUCCESS;
}
} catch (GameException $e) {
echo 'Банковская ошибка!';
} finally {
unset($submit, $summa, $toid);
if ($_POST['action'] === 'depositMoney' && !empty($_POST['summa'])) {
$bank->depositMoney($_POST['summa']);
}
Template::header('Банк');
?>
<link href="css/secondary.css" rel="stylesheet"/>
<script src="js/main.js"></script>
<?php Template::buildingTop(Rooms::$roomNames[29], 'strah') ?>
<div><?= $status ?></div>
<div class="appblock appblock-main">
<span class="wrap">На счету: <span class="num"><?= $bank->getMoney() ?></span></span>
<hr>
<span class="wrap">На руках: <span class="num"><?= User::getInstance()->getMoney() ?></span></span>
</div>
<div class="appblock">
<span class="legend">Работа со счётом</span>
<form method="post">
<input size="10" name="summa" placeholder="Сумма">
<input type="hidden" name="action" value="depositMoney">
<input type="submit" value="Положить деньги">
</form>
<form method="post">
<input size="10" name="summa" placeholder="Сумма">
<input type="hidden" name="action" value="withdrawMoney">
<input type="submit" value="Снять деньги">
</form>
</div>
<div class="appblock">
<span class="legend">Перевод кредитов</span>
<form method="post">
<input size="10" name="summa" placeholder="Сумма">
<input size="10" name="to-id" placeholder="Cчёт"><br>
<input type="hidden" name="action" value="sendMoney">
<input type="submit" value="Перевести кредиты">
</form>
<span class="wrap">Комиссия: <?= GameConfigs::BANK_COMISSION * 100 ?>% от переводимой суммы, но не менее 1 кр.</span>
</div>
// Снятие кредитов со счёта.
if ($_POST['action'] === 'withdrawMoney' && !empty($_POST['summa'])) {
$bank->withdrawMoney($_POST['summa']);
}
// Перевод кредитов на другой счёт.
if ($_POST['action'] === 'sendMoney' && !empty($_POST['summa']) && !empty($_POST['to-id'])) {
$bank->sendMoney($_POST['to-id'], $_POST['summa']);
}
require_once 'views/bank.php';

View File

@ -1,6 +1,5 @@
<?php
use Battles\Bank;
use Battles\Database\Db;
use Battles\User;
@ -34,14 +33,12 @@ if (!$check_bonuses) {
function buy_bonus($name): bool
{
global $prices;
$bank = new Bank(User::getInstance()->getId());
if ($bank->getMoney() <= PRICES[$name]) {
if (User::getInstance()->money()->getBank() <= PRICES[$name]) {
return false;
}
$query = sprintf('update users_bonuses set %s = %s + 1 where user_id = ?', $name, $name);
Db::getInstance()->execute($query, User::getInstance()->getId());
$bank->setMoney($bank->getMoney() - $prices[$name]);
User::getInstance()->money()->modifyBank(-PRICES[$name]);
return true;
}

View File

@ -1,6 +1,5 @@
<?php
use Battles\Bank;
use Battles\Database\Db;
use Battles\User;
@ -38,14 +37,13 @@ if (!$check_bonuses) {
function buy_bonus($name): bool
{
$bank = new Bank(User::getInstance()->getId());
if ($bank->getMoney() <= PRICES[$name]) {
if (User::getInstance()->money()->getBank() <= PRICES[$name]) {
return false;
}
$query = sprintf('update clan_bonuses set %s = %s + 1 where short_name = ?', $name, $name);
Db::getInstance()->execute($query, User::getInstance()->getClan());
$bank->setMoney($bank->getMoney() - PRICES[$name]);
User::getInstance()->money()->modifyBank(-PRICES[$name]);
return true;
}

View File

@ -323,7 +323,7 @@ if (!$ch_rooms[$in_haos['room']]) {
addchp('За убийство босса Цитадели Хаоса вы получили ' . $dress['name'], '{[]}' . Nick::id($all_get[$l_id])->short() . '{[]}');
}
if ($priz_exp > 0) {
GiveExp($all_get[$l_id], $priz_exp);
\Battles\User::getInstance($all_get[$l_id])->addExperience($priz_exp);
addchp('За убийство босса Цитадели Хаоса вы получили ' . $priz_exp . ' опыта', '{[]}' . Nick::id($all_get[$l_id])->short() . '{[]}');
mysql_query("INSERT INTO `delo` (`id` , `author` ,`pers`, `text`, `type`, `date`)
VALUES ('','0','{$cur_user['id']}','\"" . $all_get[$l_id] . "\" получил в ЦХ \"" . $priz_exp . "\" опыта',1,'" . time() . "');");

View File

@ -5,18 +5,17 @@ use Battles\GameLogs;
use Battles\ShopItem;
use Battles\Template;
use Battles\User;
use Battles\UserEffect;
require_once 'functions.php';
//require_once 'cave/cave_bots.php';
$userslots = ['sergi', 'kulon', 'perchi', 'weap', 'bron', 'r1', 'r2', 'r3', 'helm', 'shit', 'boots', 'rybax', 'plaw', 'm1', 'm2', 'm3', 'm4', 'm5', 'm6', 'm7', 'm8', 'm9', 'm10'];
function cancarry($m, $uid)
function cancarry($m, $uid): bool
{
if (!$uid) {
$uid = User::getInstance()->getId();
}
$weight = \Battles\Database\Db::getInstance()->execute('select sum(weight) from inventory where owner_id = ? and on_sale = 0', $uid)->fetchColumn();
$maxWeight = \Battles\Database\Db::getInstance()->execute('select strength * 4 from users where id = ?', $uid)->fetchColumn();
return $weight + $m > $maxWeight ? false : true;
return !UserEffect::isOverEncumbered($uid, $m);
}
function placeinbackpack($qty, $userid = null)
@ -339,7 +338,7 @@ while ($rec = mysql_fetch_assoc($r)) {
}
if (User::getInstance()->getRoom() == 621) {
$base = "/underdesigns/alchcave";
$base = "/i/underdesigns/alchcave";
}
$maxloses = 3;
@ -1194,6 +1193,7 @@ Template::header('cave');
if ($user['hp'] <= 0) {
makedeath();
}
$botNames = CaveBots::$botnames;
$botIds = CaveBots::$bots;
function drawmap($map1, $players, $x, $y, $direction)

View File

@ -1,18 +1,16 @@
<?php
// Здание регистратуры!
use Battles\Bank;
use Battles\Database\Db;
use Battles\GameConfigs;
use Battles\Rooms;
use Battles\Template;
use Battles\User;
use Battles\Database\Db;
require_once 'functions.php';
$userClan = Db::getInstance()->ofetch('select * from clans where owner_id = ?', User::getInstance()->getId());
$clanFullName = $_POST['clan_full_name'] ?? '';
$clanShortName = $_POST['clan_short_name'] ?? '';
$clanInfo = $_POST['clan_info'] ?? '';
$userBank = new Bank(User::getInstance()->getId());
if ($clanFullName && $clanShortName && $clanInfo && !$userClan) {
$eff = Db::getInstance()->execute('select count(*) from users_effects where type = 20 and owner_id = ?', User::getInstance()->getId())->fetchColumn();
@ -27,7 +25,7 @@ if ($clanFullName && $clanShortName && $clanInfo && !$userClan) {
if (User::getInstance()->getClan()) {
$errorMessage[1] = 'Вы уже состоите в клане!. <BR>';
}
if (GameConfigs::CLAN['clan_register_cost'] >= $userBank->getMoney()) {
if (GameConfigs::CLAN['clan_register_cost'] >= User::getInstance()->money()->getBank()) {
$errorMessage[2] = 'Не хватает денег на регистрацию клана. <BR>';
}
if (!$eff) {
@ -39,8 +37,8 @@ if ($clanFullName && $clanShortName && $clanInfo && !$userClan) {
if (!$errorMessage || User::getInstance()->getAdmin()) {
try {
Db::getInstance()->execute('insert into clans (owner_id, full_name, short_name, info) values (?,?,?,?)', [User::getInstance()->getId(), $clanFullName, $clanShortName, $clanInfo]);
$userBank->setMoney($userBank->getMoney() - GameConfigs::CLAN['clan_register_cost']);
Battles\Bank::setBankMoney($userBank->getMoney(), User::getInstance()->getId(), 'clanRegister');
User::getInstance()->money()->modifyBank(-GameConfigs::CLAN['clan_register_cost'], 'clanRegister');
// Заглушка для отображения данных по только что зарегистрированному клану, когда запрос в базу в начале файла ещё не проходит.
$userClan = new stdClass();
$userClan->full_name = $clanFullName;
@ -101,7 +99,7 @@ if ($userClan): ?>
Для регистрации клана необходимо иметь:
<ol>
<li>Проверку на чистоту. У вас её нет.
<li>10000 кредитов на банковском счёте. У вас на счету <?= $userBank->getMoney() ?>.
<li>10000 кредитов на банковском счёте. У вас на счету <?= User::getInstance()->money()->getBank() ?>.
</ol>
Поле информации не обазательное. Но его содержимое может серьёзно повысить шансы на регистрацию клана.<BR>
Заявку на регистрацию подает глава клана.

View File

@ -44,6 +44,6 @@ UNREGCLANLIST;
{
$bank = new Bank($id);
Db::getInstance()->execute('DELETE FROM clans WHERE status = 0 AND owner_id = ?', $id);
$bank::setBankMoney($bank->getMoney() + GameConfigs::CLAN['clan_register_cost'], $id);
$bank->modify(GameConfigs::CLAN['clan_register_cost']);
}
}
}

View File

@ -9,16 +9,16 @@ class Item
public static function add(array $params): void
{
$query = 'insert into items (
name, item_type, durability,
need_strength, need_dexterity, need_intuition, need_endurance, need_intelligence, need_wisdom,
add_strength, add_dexterity, add_intuition, add_endurance, add_intelligence, add_wisdom,
add_accuracy, add_evasion, add_criticals, add_min_physical_damage, add_max_physical_damage,
image, weight)
name, item_type, durability,
need_strength, need_dexterity, need_intuition, need_endurance, need_intelligence, need_wisdom,
add_strength, add_dexterity, add_intuition, add_endurance, add_intelligence, add_wisdom,
add_accuracy, add_evasion, add_criticals, add_min_physical_damage, add_max_physical_damage,
image, weight)
values (
:name, :item_type, :durability,
:need_strength, :need_dexterity, :need_intuition, :need_endurance, :need_intelligence, :need_wisdom,
:add_strength, :add_dexterity, :add_intuition, :add_endurance, :add_intelligence, :add_wisdom,
:add_accuracy, :add_evasion, :add_criticals, :add_min_physical_damage, :add_max_physical_damage,
:name, :item_type, :durability,
:need_strength, :need_dexterity, :need_intuition, :need_endurance, :need_intelligence, :need_wisdom,
:add_strength, :add_dexterity, :add_intuition, :add_endurance, :add_intelligence, :add_wisdom,
:add_accuracy, :add_evasion, :add_criticals, :add_min_physical_damage, :add_max_physical_damage,
:image, :weight)';
$values = [
'name' => $params['name'] ?? uniqid(),
@ -46,4 +46,4 @@ class Item
];
Db::getInstance()->execute($query, $values);
}
}
}

View File

@ -17,4 +17,4 @@ class User
}
return $list;
}
}
}

View File

@ -7,21 +7,22 @@
namespace Battles;
use Exceptions\GameException;
use Battles\Database\Db;
use Throwable;
class Bank
{
public int $user_id = 0;
private int $userId = 0;
private int $money = 0;
private $user;
private string $error = '';
private string $status = '';
private int $comission = 0;
const ERROR_NO_MONEY_IN_WALLET = "Ошибка! Нет денег в кошельке!";
const ERROR_NO_BANK_ACCOUNT = "Ошибка! Счёта не существует!";
const ERROR_NO_MONEY_IN_BANK_ACCOUNT = "Ошибка! Нет денег на счету!";
const ERROR_WRONG_AMOUNT = "Ошибка! Сумма должна быть положительной!";
const LOG = [
private const ERROR_NO_MONEY_IN_WALLET = "Ошибка! Нет денег в кошельке!";
private const ERROR_NO_BANK_ACCOUNT = "Ошибка! Счёта не существует!";
private const ERROR_NO_MONEY_IN_BANK_ACCOUNT = "Ошибка! Нет денег на счету!";
private const ERROR_WRONG_AMOUNT = "Ошибка! Сумма должна быть положительной!";
private const ERROR_WRONG_ID = 'Неверный ID!';
private const LOG = [
'sendMoney' => 'Банк: Перевод средств на другой счёт.',
'receiveMoney' => 'Банк: Получение средств.',
'depositMoney' => 'Пополнение счёта.',
@ -30,13 +31,15 @@ class Bank
'sellShop' => 'Продажа товара в магазине.'
];
public function __construct(int $user_id)
public function __construct(int $userId = null)
{
$bank_row = Db::getInstance()->fetch('SELECT user_id, money FROM bank WHERE user_id = ?', $user_id);
$this->user = Db::getInstance()->fetch('SELECT money FROM users WHERE id = ?', $user_id);
if (empty($userId)) {
$userId = User::getInstance()->getId();
}
$bankRow = Db::getInstance()->fetch('SELECT user_id, money FROM bank WHERE user_id = ?', $userId);
foreach ($this as $key => $value) {
if (isset($bank_row[$key])) {
$this->$key = $bank_row[$key];
if (isset($bankRow[$key])) {
$this->$key = $bankRow[$key];
}
}
}
@ -48,14 +51,11 @@ class Bank
*
* @return int
*/
private function bankCommission(int $amount): int
private function commission(int $amount): int
{
$bankCommission = round($amount * GameConfigs::BANK_COMISSION);
if ($bankCommission < 1) {
return 1;
} else {
return (int)$bankCommission;
}
$this->comission = max(1, (int)$bankCommission);
return $this->comission;
}
/**
@ -64,59 +64,56 @@ class Bank
* @param int $receiverId ID получателя.
* @param int $amount сумма.
* @param string $operationType тип банковской операции.
* @param int $senderId ID отправителя (ID игрока, если не указано иное).
* @param ?int $senderId ID отправителя (ID игрока, если не указано иное).
*
* @return void
*/
private function bankLogs(int $receiverId, int $amount, string $operationType, int $senderId = null): void
private function addLog(int $receiverId, int $amount, string $operationType, ?int $senderId = null): void
{
if (is_null($senderId)) {
$senderId = $this->user_id;
$senderId = $this->userId;
}
$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);
if ($operationType === 'depositMoney' || $operationType === 'withdrawMoney') {
$receiverId = $this->userId;
}
GameLogs::addBankLog($senderId,$receiverId,$amount,$operationType,$text);
$commText = $this->comission ? ' Комиссия: ' . $this->comission : '';
$text = self::LOG[$operationType] . $commText;
$this->status = $text;
GameLogs::addBankLog($senderId, $receiverId, $amount, $operationType, $text);
}
/**
* Перевод денег между банковскими счетами игроков с банковской комиссией.
*
* @param int $receiver ID получателя.
* @param int $amount сумма.
*
* @return int
* @throws GameException
* @param mixed $receiver ID получателя.
* @param mixed $amount Cумма.
*/
public function sendMoney(int $receiver, int $amount): int
public function sendMoney($receiver, $amount)
{
$receiverWallet = Db::getInstance()->ofetch('SELECT money FROM bank WHERE user_id = ?', $receiver);
if ($amount <= 0) {
throw new GameException(self::ERROR_WRONG_AMOUNT);
if (!is_numeric($receiver)) {
$this->error = self::ERROR_WRONG_ID;
return;
}
if (!$receiverWallet) {
throw new GameException(self::ERROR_NO_BANK_ACCOUNT);
$rec = new self($receiver);
if (!is_numeric($amount) || $amount <= 0) {
$this->error = self::ERROR_WRONG_AMOUNT;
}
$amountWithComission = $amount + $this->bankCommission($amount);
if (!$rec->userId) {
$this->error = self::ERROR_NO_BANK_ACCOUNT;
}
$amountWithComission = $amount + $this->commission($amount);
if ($amountWithComission > $this->money) {
throw new GameException(self::ERROR_NO_MONEY_IN_BANK_ACCOUNT);
$this->error = self::ERROR_NO_MONEY_IN_BANK_ACCOUNT;
}
if ($this->error) {
return;
}
// Снимаем сумму с комиссией у отправителя
$this->money -= $amountWithComission;
self::setBankMoney($this->money, $this->user_id);
$this->bankLogs($receiver, $this->money, "sendMoney");
$this->modify(-$amountWithComission);
$this->addLog($rec->userId, $this->money, 'sendMoney', $this->userId);
// Отдаём сумму на счёт получателю
$receiverWallet->money += $amount;
self::setBankMoney($receiverWallet->money, $receiver);
$this->bankLogs($receiver, $receiverWallet->money, "receiveMoney");
// Возвращаем изменившиеся значения
return $this->money;
$rec->modify($amount);
$rec->addLog($rec->userId, $rec->money, 'receiveMoney', $this->userId);
}
/**
@ -124,30 +121,22 @@ class Bank
*
* @param int $amount сумма.
*
* @return array
* @throws GameException
*/
public function depositMoney(int $amount): array
public function depositMoney(int $amount)
{
if ($amount <= 0) {
throw new GameException(self::ERROR_WRONG_AMOUNT);
}
$walletMoney = Db::getInstance()->fetchColumn('SELECT money FROM users WHERE id = ?', $this->user_id);
if ($walletMoney < $amount) {
throw new GameException(self::ERROR_NO_MONEY_IN_WALLET);
$this->error = self::ERROR_WRONG_AMOUNT;
}
// Забираем деньги из кошелька получателя
$this->user->money -= $amount;
self::setWalletMoney($this->user->money, $this->user_id);
if (!User::getInstance($this->userId)->money()->spend($amount)) {
$this->error = self::ERROR_NO_MONEY_IN_WALLET;
}
if ($this->error) {
return;
}
// Отдаём сумму на счёт получателю
$this->money += $amount;
self::setBankMoney($this->money, $this->user_id);
$this->bankLogs(0, $this->money, "depositMoney");
// Возвращаем изменившиеся значения
return [
'walletMoney' => $this->user->money,
'bankMoney' => $this->money
];
$this->modify($amount);
$this->addLog(0, $this->money, 'depositMoney');
}
/**
@ -155,66 +144,29 @@ class Bank
*
* @param int $amount сумма.
*
* @return array
* @throws GameException
*/
public function withdrawMoney(int $amount): array
public function withdrawMoney(int $amount)
{
if ($amount <= 0) {
throw new GameException(self::ERROR_WRONG_AMOUNT);
$this->error = self::ERROR_WRONG_AMOUNT;
}
$amountWithComission = $amount + $this->bankCommission($amount);
$amountWithComission = $amount + $this->commission($amount);
if ($this->money < $amountWithComission) {
throw new GameException(self::ERROR_NO_MONEY_IN_BANK_ACCOUNT);
$this->error = self::ERROR_NO_MONEY_IN_BANK_ACCOUNT;
}
if ($this->error) {
return;
}
// Снимаем сумму с комиссией у отправителя
$this->money -= $amountWithComission;
self::setBankMoney($this->money, $this->user_id);
$this->bankLogs(0, $this->money, "withdrawMoney");
$this->modify(-$amountWithComission);
$this->addLog(0, $this->money, 'withdrawMoney');
// Отдаём сумму в кошелёк получателя
$this->user['money'] += $amount;
self::setWalletMoney($this->user['money'], $this->user_id);
// Возвращаем изменившиеся значения
return [
'walletMoney' => $this->user['money'],
'bankMoney' => $this->money
];
User::getInstance($this->userId)->money()->earn($amount);
}
/**
* Установить количество денег на банковском счету.
*
* @param int $amount сумма.
* @param int $user_id ID пользователя.
* @param string $operationType Тип операции. По умолчанию пусто. Если ввести, система запишет событие в банковский лог.
*
* @return void
*/
public static function setBankMoney(int $amount, int $user_id, string $operationType = ''): void
private function save()
{
try {
Db::getInstance()->execute('UPDATE bank SET money = ? WHERE user_id = ?', [$amount, $user_id]);
if ($operationType) {
GameLogs::addBankLog(0, 0, $amount, $operationType, self::LOG[$operationType]);
}
} catch (Throwable $e) {
echo "Не отработал запрос в БД в файле {$e->getFile()}({$e->getLine()})";
}
}
/**
* Установить количество денег на руках.
*
* @param int $amount сумма.
* @param int $user_id ID пользователя.
*
* @return void
*/
public static function setWalletMoney(int $amount, int $user_id): void
{
User::getInstance($user_id)->setMoney($amount);
User::getInstance($user_id)->saveMoney();
Db::getInstance()->execute('UPDATE bank SET money = ? WHERE user_id = ?', [$this->money, $this->userId]);
}
public function getMoney(): int
@ -222,8 +174,30 @@ class Bank
return $this->money;
}
public function setMoney($amount)
public function modify(int $amount, string $logType = '')
{
$this->money = $amount;
if ($amount > 0) {
// add_money
$this->money += $amount;
$this->save();
} elseif ($amount < 0) {
// remove_money
if ($this->money < $amount) {
return;
}
$this->money -= $amount;
$this->save();
}
if ($logType && $amount !== 0) {
$this->addLog(0, $this->money, $logType);
}
}
}
public function getStatus(): string
{
if (!$this->error) {
return $this->status;
}
return $this->error;
}
}

View File

@ -18,21 +18,21 @@ class Chat
public function getMessages(): ?string
{
$query = 'select
$query = 'select
msg,
msgdate,
type,
s.login as sender,
r.login as receiver,
s.id as sid,
r.id as rid
from chat
left join users s on s.id = chat.user_id
left join users r on r.id = chat.receiver_id
where
r.id = ?
or r.id is null
or s.id = ?
s.login as sender,
r.login as receiver,
s.id as sid,
r.id as rid
from chat
left join users s on s.id = chat.user_id
left join users r on r.id = chat.receiver_id
where
r.id = ?
or r.id is null
or s.id = ?
order by chat.id';
$chatrows = $this->db->ofetchALL($query, [User::getInstance()->getId(), User::getInstance()->getId()]);
$wrappedMessage = null;
@ -67,13 +67,14 @@ class Chat
$this->db->execute('insert into chat (user_id, msg) values (?,?)', [User::getInstance()->getId(), $msg]);
}
public static function sendSys(string $msg, ?int $receiver_id = null)
public static function sendSys(string $msg, ?int $receiverId = null)
{
Db::getInstance()->execute('insert into chat (user_id, msg, receiver_id, type) values (-1,?,?,?)', [$msg, $receiver_id, 'sys']);
}
public static function sendTelegraf(string $msg, int $receiver_id)
{
Db::getInstance()->execute('insert into chat (user_id, msg, receiver_id, type) values (-1,?,?,?)', [$msg, $receiver_id, 'sms']);
Db::getInstance()->execute('insert into chat (user_id, msg, receiver_id, type) values (-1,?,?,?)', [$msg, $receiverId, 'sys']);
}
}
public static function sendTelegraf(string $msg, int $receiverId)
{
Db::getInstance()->execute('insert into chat (user_id, msg, receiver_id, type) values (-1,?,?,?)', [$msg, $receiverId, 'sms']);
}
}

View File

@ -14,6 +14,7 @@ class Check
* Check constructor.
*
* @param User $user
* @param Db $db
*/
public function __construct(User $user, Db $db)
{
@ -21,8 +22,13 @@ class Check
$this->db = $db;
}
public function Effects()
public static function expiredEffects()
{
return $this->db->execute('delete from users_effects where remaining_time <= ?', strtotime('now'));
return Db::getInstance()->execute('delete from users_effects where remaining_time <= ?', strtotime('now'));
}
}
public static function userExists($id): bool
{
return Db::getInstance()->fetchColumn('select count(*) from users where id = ?', $id) > 0;
}
}

View File

@ -1,13 +1,16 @@
<?php
# Date: 26.10.2020 (17:56)
namespace Battles;
class City
{
use Rooms;
public static function showStreet(int $id)
{
echo '<div style="position:relative; display: inline-block;" id="ione">';
if ($id === 20) {
echo '<div style="position:relative; display: inline-block;" id="ione"><img alt="background" src="/i/city/spring_cap_cp_day.jpg">' .
echo '<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(4, "spring_cap_rem", 202, 290, self::$roomNames[23]) .
@ -17,68 +20,61 @@ class City
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>';
self::showBuilding(222, "cap_arr_top", 180, 650, "Торговая улица");
} elseif ($id === 21) {
echo '<div style="position:relative; display: inline-block;" id="ione"><img alt="background" src="/i/city/spring_cap_strash_day.jpg">' .
echo '<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>';
self::showBuilding(16, "spring_cap_tower", 5, 315, self::$roomNames[31]);
} elseif ($id === 26) {
echo '<div style="position:relative; display: inline-block;" id="ione"><img alt="background" src="/i/city/spring_cap_park_day.jpg">' .
echo '<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>';
self::showBuilding(660, "spring_cap_vokzal", 163, 43, self::$roomNames[661]);
} elseif ($id === 2601) {
echo '<div style="position:relative; display: inline-block;" id="ione"><img alt="background" src="/i/city/sub/cap_zamk_day.jpg">' .
echo '<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>';
self::showBuilding(1052, "spring_cap_lavka", 240, 425, self::$roomNames[1053]);
} elseif ($id === 2655) {
echo '<div style="position:relative; display: inline-block;" id="ione"><img alt="background" src="/i/city/ar_e_d.jpg">' .
echo '<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>';
self::showBuilding(2055, "altr_g", 230, 340, self::$roomNames[603]);
} elseif ($id === 2111) {
echo '<div style="position:relative; display: inline-block;" id="ione"><img alt="background" src="/i/city/av_rist_day.jpg">' .
echo '<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>';
self::showBuilding(1000, "av_zamk_rud", 80, 310, self::$roomNames[1001]);
} elseif ($id === 2701) {
echo '<div style="position:relative; display: inline-block;" id="ione"><img alt="background" src="/i/city/av_arena_bg1_day2.jpg">' .
echo '<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>';
self::showBuilding(2, "cap_shar_dark", 234, 356, "Лабиринт Хаоса");
} elseif ($id === 2702) {
echo '<div style="position:relative; display: inline-block;" id="ione"><img alt="background" src="/i/city/spring_cap_torg_day.jpg">' .
echo '<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>';
self::showBuilding(16555, "spring_cap_build3", 155, 480, "Прокатная лавка");
}
echo '</div>';
}
private static function showBuilding(int $id, string $image, int $top, int $left, string $description)
private static function showBuilding(int $id, string $image, int $top, int $left, string $description): string
{
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);
return <<<HTML
<div style="position:absolute; left:{$left}px; top:{$top}px; z-index:90; cursor: pointer;">
<img src="/i/city/sub/$image.png" alt="$description" title="$description" class="building" id="$id" onclick="window.location.href = 'city.php?got/level$id'">
</div>
HTML;
}
}
}

View File

@ -3,10 +3,11 @@
namespace Battles;
use Battles\Database\Db;
use Battles\Models\User\Effects;
class Clan
{
private static ?self $_instance = null;
private static ?self $instance = null;
private $clan;
private function __construct()
@ -16,10 +17,10 @@ class Clan
public static function getInstance(): self
{
if (is_null(self::$_instance)) {
self::$_instance = new self();
if (is_null(self::$instance)) {
self::$instance = new self();
}
return self::$_instance;
return self::$instance;
}
public function addMember(string $login): string
@ -34,35 +35,37 @@ class Clan
if (User::getInstance($login)->getLevel() < 1) {
$error .= '<br>Персонаж 0 уровня не может быть принят!';
}
if (User::getInstance()->getMoney() < GameConfigs::CLAN['add_member_cost']) {
if (!User::getInstance()->money()->spend(GameConfigs::CLAN['add_member_cost'])) {
$error .= '<br>Недостаточно денег!';
}
if ($error) {
return $error;
}
User::getInstance()->setMoney(User::getInstance()->getMoney() - GameConfigs::CLAN['add_member_cost']);
User::getInstance()->saveMoney();
User::getInstance($login)->setClan(User::getInstance()->getClan());
return "Персонаж «{$login}» успешно принят в клан.";
}
private function getProverka($userId)
{
return Effects::count($userId, 20);
}
public function removeMember(string $login): string
{
$error = null;
if (User::getInstance()->getMoney() < GameConfigs::CLAN['remove_member_cost']) {
$error .= '<br>Недостаточно денег!';
}
if (User::getInstance($login)->getId() === User::getInstance()->getId()) {
$error .= '<br>Себя выгонять нельзя!';
}
if (User::getInstance($login)->getClan() !== User::getInstance()->getClan()) {
$error .= '<br>Персонаж не состоит в этом клане!';
}
if (!User::getInstance()->money()->spend(GameConfigs::CLAN['remove_member_cost'])) {
$error .= '<br>Недостаточно денег!';
}
if ($error) {
return $error;
}
User::getInstance()->setMoney(User::getInstance()->getMoney() - GameConfigs::CLAN['remove_member_cost']);
User::getInstance()->saveMoney();
User::getInstance($login)->setClan(null);
return "Персонаж «{$login}» покинул клан.";
}
@ -98,11 +101,6 @@ class Clan
return Db::getInstance()->fetchAll('select id, (select 1 from clans where short_name = clan and owner_id = id) as clan_owner, room from users where clan = ? order by clan_owner desc, room, login', User::getInstance()->getClan());
}
private function getProverka($user_id)
{
return Db::getInstance()->fetchColumn('select count(*) from users_effects where type = 20 and owner_id = ?', $user_id);
}
public function getClanOwnerId(): ?int
{
return $this->clan->owner_id;
@ -117,4 +115,4 @@ class Clan
{
return $this->clan->short_name;
}
}
}

View File

@ -4,13 +4,14 @@ declare(strict_types=1);
namespace Battles\Database;
use Battles\GameConfigs;
use PDO, PDOException;
use PDO;
use PDOException;
class Db
{
private PDO $pdo;
private static ?self $_instance = null;
private static ?self $instance = null;
private function __construct()
{
@ -32,10 +33,10 @@ class Db
public static function getInstance(): self
{
if (is_null(self::$_instance)) {
self::$_instance = new self();
if (is_null(self::$instance)) {
self::$instance = new self();
}
return self::$_instance;
return self::$instance;
}
public function execute($query, $values = null)
@ -74,11 +75,11 @@ class Db
// 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 = array();
$keyedResults = [];
foreach ($results as $result) {
$keyed_results[$result[$key]] = $result;
$keyedResults[$result[$key]] = $result;
}
$results = $keyed_results;
$results = $keyedResults;
}
return $results;
}
@ -107,11 +108,11 @@ class Db
// 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)[];
$keyedResults = (object)[];
foreach ($results as $result) {
$keyed_results->$result[$key] = $result;
$keyedResults->$result[$key] = $result;
}
$results = $keyed_results;
$results = $keyedResults;
}
return $results;
}
@ -131,4 +132,4 @@ class Db
$stmt = $this->execute($query, $values);
return $stmt->fetchColumn();
}
}
}

View File

@ -8,24 +8,25 @@
namespace Battles;
use Battles\Database\Db;
use Battles\Models\Inventory;
use stdClass;
class DressedItems
{
private int $USERID;
private int $userId;
private stdClass $dressedItem;
private static Db $db;
private object $dressed;
/**
* DressedItems constructor.
* @param int $user_id ID игрока.
* @param int $userId ID игрока.
*/
public function __construct(int $user_id)
public function __construct(int $userId)
{
self::$db = Db::getInstance();
$this->USERID = $user_id;
$this->dressed = self::$db->ofetchAll('select * from inventory where dressed_slot > 0 and owner_id = ?', $this->USERID);
$this->userId = $userId;
$this->dressed = self::$db->ofetchAll('select * from inventory where dressed_slot > 0 and owner_id = ?', $this->userId);
}
public static function getDressedItemBySlot($itemSlot, $ownerId)
@ -45,33 +46,33 @@ class DressedItems
/**
* Снимает с предмета статус одетого на персонажа в определённом слоте персонажа.
* @param $slot_id - номер слота.
* @param $slotId - номер слота.
*/
public function undressItem($slot_id)
public function undressItem($slotId)
{
self::getItemsInSlots();
// Проверяем, что используется один из 12 слотов и наличие предмета в слоте.
if (in_array($slot_id, Item::ITEM_TYPES_ALLOWED_IN_SLOTS) && $this->dressedItem->$slot_id) {
self::$db->execute('UPDATE inventory SET dressed_slot = 0 WHERE dressed_slot = ? AND owner_id = ?', [$slot_id, $this->USERID]);
if (in_array($slotId, Item::TYPES_ALLOWED_IN_SLOTS) && $this->dressedItem->$slotId) {
Inventory::undressOne($slotId, $this->userId);
}
}
public static function undressAllItems($user_id)
public static function undressAllItems($userId)
{
return self::$db->execute('UPDATE inventory SET dressed_slot = 0 WHERE dressed_slot BETWEEN 1 AND 12 AND owner_id = ?', $user_id);
return self::$db->execute('UPDATE inventory SET dressed_slot = 0 WHERE dressed_slot BETWEEN 1 AND 12 AND owner_id = ?', $userId);
}
public function checkRequirements()
{
$stats = (new UserStats($this->USERID))->getFullStats();
$q = 'select count(*) from inventory where
dressed_slot > 0 and
$stats = (new UserStats($this->userId))->getFullStats();
$q = 'select count(*) from inventory where
dressed_slot > 0 and
need_strength > ? and
need_dexterity > ? and
need_intuition > ? and
need_endurance > ? and
need_dexterity > ? and
need_intuition > ? and
need_endurance > ? and
need_intelligence > ? and
need_wisdom > ? and
need_wisdom > ? and
owner_id = ?';
$args = [
$stats->strength,
@ -80,10 +81,10 @@ class DressedItems
$stats->endurance,
$stats->intelligence,
$stats->wisdom,
$this->USERID
$this->userId
];
if (self::$db->fetchColumn($q, $args) > 0) {
self::undressAllItems($this->USERID);
self::undressAllItems($this->userId);
}
}
}
}

View File

@ -23,4 +23,4 @@ class GameConfigs
const BANK_COMISSION = 0.05; // 5%
const DB_SQLITE = '/volume2/web/battles/databases/logs.sqlite';
}
}

View File

@ -3,11 +3,14 @@
namespace Battles;
use SQLite3;
use SQLite3Result;
use Battles\Database\Db;
class GameLogs
{
private const BANK = 1;
private const USER_ACTIONS = 2;
private const BATTLE = 3;
/**
* Добавление записи в лог банковских операций.
* @param int $senderId отправитель средств.
@ -18,15 +21,16 @@ class GameLogs
*/
public static function addBankLog(int $senderId, int $receiverId, int $amount, string $type, string $text)
{
$db = new SQLite3(GameConfigs::DB_SQLITE);
$row = $db->prepare("INSERT INTO bank_logs (sender_id, receiver_id, amount, type, text) VALUES (?, ?, ?, ?, ?)");
$row->bindParam(1, $senderId, SQLITE3_INTEGER);
$row->bindParam(2, $receiverId, SQLITE3_INTEGER);
$row->bindParam(3, $amount, SQLITE3_INTEGER);
$row->bindParam(4, $type, SQLITE3_TEXT);
$row->bindParam(5, $text, SQLITE3_TEXT);
$row->execute();
$row->close();
self::addLog(
json_encode([
'senderId' => $senderId,
'receiverId' => $receiverId,
'amount' => $amount,
'type' => $type,
'text' => $text,
]),
self::BANK,
);
}
/**
@ -44,48 +48,61 @@ class GameLogs
if (empty($type)) {
$type = "system";
}
$db = new SQLite3(GameConfigs::DB_SQLITE);
$row = $db->prepare("INSERT INTO users_logs (user_id, author_id, type, text) VALUES (?,?,?,?)");
$row->bindParam(1, $userId, SQLITE3_INTEGER);
$row->bindParam(2, $authorId, SQLITE3_INTEGER);
$row->bindParam(3, $type, SQLITE3_TEXT);
$row->bindParam(4, $text, SQLITE3_TEXT);
$row->execute();
$row->close();
self::addLog(
json_encode([
'userId' => $userId,
'authotId' => $authorId,
'type' => $type,
'text' => $text,
]),
self::USER_ACTIONS,
);
}
public static function getUserLogs($userId = null, $type = null): SQLite3Result
private static function addLog($jsonString, $logType)
{
$db = new SQLite3(GameConfigs::DB_SQLITE);
$row = false;
if ($userId && $type) {
$query = "SELECT * FROM users_logs WHERE user_id = ? AND type = ?";
$row = $db->prepare($query);
$row->bindValue(1, $userId, SQLITE3_INTEGER);
$row->bindValue(2, $type, SQLITE3_TEXT);
} elseif ($userId && !$type) {
$query = "SELECT * FROM users_logs WHERE user_id = ?";
$row = $db->prepare($query);
$row->bindValue(1, $userId, SQLITE3_INTEGER);
} elseif (!$userId && $type) {
$query = "SELECT * FROM users_logs WHERE type= ?";
$row = $db->prepare($query);
$row->bindValue(1, $type, SQLITE3_TEXT);
} elseif (!$userId && !$type) {
$query = "SELECT * FROM users_logs";
$row = $db->prepare($query);
Db::getInstance()->execute('insert into logs (json_data, type) VALUES (?,?)', [
$jsonString,
$logType
]);
}
private static function getLogByType(int $type): array
{
$result = [];
$logs = Db::getInstance()->fetchAll('select json_data from logs where type = ?', $type);
foreach ($logs as $log) {
$result[] = json_decode($log, true);
}
return $result;
}
public static function getUserLogs(?int $userId): array
{
$logs = self::getLogByType(self::USER_ACTIONS);
if (is_null($userId)) {
return $logs;
}
return $row->execute();
$result = [];
foreach ($logs as $log) {
if ($userId !== $log['userId']) {
continue;
}
$result[] = $log;
}
return $result;
}
public static function addBattleLog(int $battle_id, string $text)
public static function addBattleLog(int $battleId, string $text)
{
$db = new SQLite3(__DIR__ . '../../Database/battle.logs.getInstance');
$row = $db->prepare('insert into newbattles (battle_id, text) values (?,?)');
$row->bindParam(1, $battle_id, SQLITE3_INTEGER);
$row->bindParam(2, $text, SQLITE3_TEXT);
$row->execute();
$row->close();
self::addLog(
json_encode([
'battleId' => $battleId,
'text' => $text,
]),
self::BATTLE,
);
}
}
}

177
classes/Battles/Hostel.php Normal file
View File

@ -0,0 +1,177 @@
<?php
# Date: 19.02.2022 (2:33)
namespace Battles;
use Battles\Database\Db;
class Hostel
{
private array $status = [];
private int $uid;
private int $hid;
private int $type;
private int $time;
public const PRICEPERTYPE = [
1 => [8, 16, 24, 32],
2 => [15, 30, 45, 60],
3 => [25, 50, 75, 100],
4 => [40, 80, 120, 160]
];
public const BASENAME = [
1 => 'Сумка',
2 => 'Сундук',
3 => 'Комната',
4 => 'Амбар',
];
public function __construct()
{
$this->uid = User::getInstance()->getId();
$data = Db::getInstance()->ofetch('select id, type, time from hostel where uid = ?', $this->uid);
$this->hid = $data->id ?? null;
$this->type = $data->type ?? null;
$this->time = $data->time ?? null;
}
private function add7DayRent($type)
{
Db::getInstance()->execute('insert into hostel (uid, type, time) values (?,?,?)', [$this->uid, $type, time() + 60 * 60 * 24 * 7]);
}
private function addRentTime($hostelId, $time)
{
Db::getInstance()->execute('update hostel set time = ? where id = ? and uid = ?', [$time, $hostelId, $this->uid]);
}
private function removeItems()
{
Db::getInstance()->execute('update inventory set in_hostel = 0 where owner_id = ? and in_hostel = 1', $this->uid);
}
private function removeRent()
{
Db::getInstance()->execute('delete from hostel where id = ? and uid = ?', [$this->hid, $this->uid]);
}
private function pay($amount): bool
{
if (!User::getInstance()->money()->spend($amount)) {
$this->setError('Недостаточно денег!');
return false;
}
return true;
}
private function hasNoRents(): bool
{
if ($this->hid) {
$this->setError('Не более 1 арендованного места!');
return false;
}
return true;
}
private function typeIsAllowed($type): bool
{
if (!in_array($type, [1, 2, 3, 4])) {
$this->setError('Неверный тип аренды!');
return false;
}
return true;
}
public function setError(string $message)
{
$this->status = ['type' => 'error', 'message' => $message];
}
private function setSuccess(string $message)
{
$this->status = ['type' => 'success', 'message' => $message];
}
public function newRent($type): bool
{
if (
!$this->typeIsAllowed($type) ||
!$this->hasNoRents() ||
!$this->pay(self::PRICEPERTYPE[$type][0])
) {
return false;
}
$this->add7DayRent($type);
$this->setSuccess('Поздравляем с успешной арендой!');
return true;
}
public function remove(): bool
{
if ($this->time < time()) {
$this->setError('Нельзя отказаться от услуг если имеется задолежнность!');
return false;
}
$this->removeRent();
$this->removeItems();
$this->setSuccess('Вы успешно отказались от аренды!');
return true;
}
public function changeType(int $type)
{
$this->remove();
$this->newRent($type);
}
public function changeTime(int $orderedTime): bool
{
$daysByOrder = [
1 => 7,
2 => 14,
3 => 21,
4 => 28,
];
if (
!$this->typeIsAllowed($orderedTime) ||
!$this->pay(self::PRICEPERTYPE[$this->type][$orderedTime - 1])
) {
return false;
}
$this->time += 60 * 60 * 24 * $daysByOrder[$orderedTime];
$this->addRentTime($this->hid, $this->time);
$this->setSuccess('Всё прошло успешно!');
return true;
}
/**
* @return int|null
*/
public function getHid(): ?int
{
return $this->hid;
}
/**
* @return int|null
*/
public function getType(): ?int
{
return $this->type;
}
/**
* @return int|null
*/
public function getTime(): ?int
{
return $this->time;
}
/**
* @return array
*/
public function getStatus(): array
{
return $this->status;
}
}

View File

@ -1,12 +1,13 @@
<?php
namespace Battles;
use Battles\Database\Db;
use Battles\Models\Inventory;
class InventoryItem extends Item
{
private $present;
private $owner_id;
private ?string $present;
private int $ownerId;
private const TOO_MANY_ITEMS_IN_SLOTS = 'Критическая ошибка: Переполнение слота!';
private const UNKNOWN_ITEM_TYPE = 'Неизвестный тип предмета!';
private const REQUIREMENTS_NOT_MET = 'Персонаж не соответствует требованиям!';
@ -19,7 +20,7 @@ class InventoryItem extends Item
public function __construct($row)
{
parent::__construct($row);
$this->owner_id = $row->owner_id;
$this->ownerId = $row->owner_id;
$this->present = $row->present;
}
@ -33,9 +34,9 @@ class InventoryItem extends Item
public function printImage()
{
if (in_array($this->item_type, range(1, 12))) {
if (in_array($this->type, range(1, 12))) {
echo <<<HTML
<a href=/main.php?edit=1&dress=$this->item_id title='Надеть'>
<a href=/main.php?edit=1&dress=$this->id title='Надеть'>
<img src="/i/sh/$this->image" class="item-wrap-normal" alt="">
</a>
HTML;
@ -46,22 +47,16 @@ IMG;
}
}
public function printControls(){
// Для кнопок управления под картинкой.
}
private function dressStatsChecks(): ?string
private function dressStatsChecks(): bool
{
$checkStats = new UserStats($this->owner_id);
$checkStats = new UserStats($this->ownerId);
$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 $this->needStrength > $stat->strength
|| $this->needDexterity > $stat->dexterity
|| $this->needIntuition > $stat->intuition
|| $this->needEndurance > $stat->endurance
|| $this->needIntelligence > $stat->intelligence
|| $this->needWisdom > $stat->wisdom;
}
/**
@ -77,33 +72,33 @@ IMG;
// считаем сколько ОДЕТЫХ предметов в слоте в который мы хотим одеть предмет. 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]);
$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->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 (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) {
//если слот занят, снимаем старый предмет и одеваем новый предмет
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]);
Inventory::undressOne($itemInSlot[0], $this->ownerId);
Inventory::dressOne($this->id, $this->ownerId);
} 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]);
Inventory::dressOne($this->id, $this->ownerId);
} else {
/* проверка на переполнение слотов */
$error = self::TOO_MANY_ITEMS_IN_SLOTS;
DressedItems::undressAllItems($this->owner_id);
DressedItems::undressAllItems($this->ownerId);
}
} elseif ($this->item_type == self::ITEM_TYPE_RING) {
} elseif ($this->type == self::TYPE_RING) {
// работаем с кольцами
if ($wearedCount->c < 3) {
// Сравниваем массив колец и массив слотов для колец.
@ -111,15 +106,14 @@ IMG;
// Сортируем массив свободных слотов по возрастанию.
sort($emptyRingSlots);
// Одеваем предмет в первый свободный слот.
Db::getInstance()->execute('update inventory set dressed_slot = ? where item_id = ?', [$emptyRingSlots[0], $this->item_id]);
Inventory::dressOneToSlot($this->id, $emptyRingSlots[0]);
} 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);
Inventory::changeRings($this->id);
} else {
/* проверка на переполнение слотов */
$error = self::TOO_MANY_ITEMS_IN_SLOTS;
DressedItems::undressAllItems($this->owner_id);
DressedItems::undressAllItems($this->ownerId);
}
} else {
$error = self::UNKNOWN_ITEM_TYPE;
@ -128,9 +122,30 @@ IMG;
return $error ?? true;
}
public static function destroyItem($itemId)
// Выбрасываем вещь.
public function drop(): string
{
Db::getInstance()->execute('delete from inventory where dressed_slot = 0 and owner_id = ? and item_id = ?', [$_SESSION['uid'], $itemId]);
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() и другую выдачу одной строкой.
@ -138,9 +153,9 @@ IMG;
*/
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>";
$all = Inventory::getWeight(User::getInstance()->getId());
$max = User::getInstance()->stats()->getMaxWeight();
$css = $all > $max ? ' style="color:maroon;"' : '';
return "<span$css>$all / $max</span>";
}
}
}

View File

@ -1,48 +1,49 @@
<?php
namespace Battles;
use Battles\Database\Db;
class Item
{
protected int $item_id;
protected int $id;
protected string $name = '';
protected int $item_type = self::ITEM_TYPE_TRASH;
protected int $type = self::TYPE_TRASH;
protected int $durability = 0;
protected int $need_strength = 0;
protected int $need_dexterity = 0;
protected int $need_intuition = 0;
protected int $need_endurance = 0;
protected int $need_intelligence = 0;
protected int $need_wisdom = 0;
protected int $add_strength = 0;
protected int $add_dexterity = 0;
protected int $add_intuition = 0;
protected int $add_endurance = 0;
protected int $add_intelligence = 0;
protected int $add_wisdom = 0;
protected int $add_accuracy = 0;
protected int $add_evasion = 0;
protected int $add_criticals = 0;
protected int $add_min_physical_damage = 0;
protected int $add_max_physical_damage = 0;
protected int $needStrength = 0;
protected int $needDexterity = 0;
protected int $needIntuition = 0;
protected int $needEndurance = 0;
protected int $needIntelligence = 0;
protected int $needWisdom = 0;
protected int $addStrength = 0;
protected int $addDexterity = 0;
protected int $addIntuition = 0;
protected int $addEndurance = 0;
protected int $addIntelligence = 0;
protected int $addWisdom = 0;
protected int $addAccuracy = 0;
protected int $addEvasion = 0;
protected int $addCriticals = 0;
protected int $addMinPhysicalDamage = 0;
protected int $addMaxPhysicalDamage = 0;
protected int $weight = 0;
protected string $image = '';
protected int $item_cost = 0;
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;
public const ITEM_TYPE_LEGS = 3;
public const ITEM_TYPE_BOOTS = 4;
public const ITEM_TYPE_GLOVES = 5;
public const ITEM_TYPE_WEAPON = 6;
public const ITEM_TYPE_SHIELD = 7;
public const ITEM_TYPE_BELT = 8;
public const ITEM_TYPE_RING = 9;
public const ITEM_TYPE_AMULET = 10;
public const ITEM_TYPE_CONSUMABLE = 20;
public const ITEM_TYPE_OTHER = 50;
public const ITEM_TYPE_TRASH = 100;
protected int $cost = 0;
public const TYPES_ALLOWED_IN_SLOTS = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
public const TYPE_HELMET = 1;
public const TYPE_ARMOR = 2;
public const TYPE_LEGS = 3;
public const TYPE_BOOTS = 4;
public const TYPE_GLOVES = 5;
public const TYPE_WEAPON = 6;
public const TYPE_SHIELD = 7;
public const TYPE_BELT = 8;
public const TYPE_RING = 9;
public const TYPE_AMULET = 10;
public const TYPE_CONSUMABLE = 20;
public const TYPE_OTHER = 50;
public const TYPE_TRASH = 100;
private string $typename;
/**
@ -66,45 +67,45 @@ class Item
}
}
switch ($this->item_type) {
case self::ITEM_TYPE_HELMET:
switch ($this->type) {
case self::TYPE_HELMET:
$this->typename = 'Шлем';
break;
case self::ITEM_TYPE_ARMOR:
case self::TYPE_ARMOR:
$this->typename = 'Броня';
break;
case self::ITEM_TYPE_LEGS:
case self::TYPE_LEGS:
$this->typename = 'Поножи';
break;
case self::ITEM_TYPE_BOOTS:
case self::TYPE_BOOTS:
$this->typename = 'Сапоги';
break;
case self::ITEM_TYPE_GLOVES:
case self::TYPE_GLOVES:
$this->typename = 'Перчатки';
break;
case self::ITEM_TYPE_WEAPON:
case self::TYPE_WEAPON:
$this->typename = 'Оружие';
break;
case self::ITEM_TYPE_SHIELD:
case self::TYPE_SHIELD:
$this->typename = 'Щит';
break;
case self::ITEM_TYPE_BELT:
case self::TYPE_BELT:
$this->typename = 'Пояс';
break;
case self::ITEM_TYPE_RING:
case self::TYPE_RING:
$this->typename = 'Кольцо';
break;
case self::ITEM_TYPE_AMULET:
case self::TYPE_AMULET:
$this->typename = 'Амулет';
break;
case self::ITEM_TYPE_CONSUMABLE:
case self::TYPE_CONSUMABLE:
$this->typename = 'Расходуемый предмет';
break;
default:
$this->typename = 'Хлам';
}
$this->item_cost = $this->calculateItemCost();
$this->cost = $this->calculateItemCost();
}
/** Рассчёт стоимости предмета в зависимости от его характеристик.
@ -112,26 +113,26 @@ class Item
*/
protected function calculateItemCost(): int
{
$sum_stats =
$this->add_strength +
$this->add_dexterity +
$this->add_intuition +
$this->add_endurance +
$this->add_intelligence +
$this->add_wisdom;
$sum_mods =
$this->add_accuracy +
$this->add_evasion +
$this->add_criticals;
$sum_damage =
$this->add_min_physical_damage +
$this->add_max_physical_damage;
$sumStats =
$this->addStrength +
$this->addDexterity +
$this->addIntuition +
$this->addEndurance +
$this->addIntelligence +
$this->addWisdom;
$sumMods =
$this->addAccuracy +
$this->addEvasion +
$this->addCriticals;
$sumDamage =
$this->addMinPhysicalDamage +
$this->addMaxPhysicalDamage;
// За каждые N параметров повышаем множитель на 1 чтобы цена пропрорционально росла.
$stats_cost_modifier = 5 + floor($sum_stats / 10);
$mods_cost_modifier = 2 + floor($sum_mods / 50);
$damage_cost_modifier = 1 + floor($sum_damage / 100);
$result = intval($sum_stats * $stats_cost_modifier + $sum_mods * $mods_cost_modifier + $sum_damage * $damage_cost_modifier);
return $result < 1 ? 1 : $result;
$statsCostModifier = 5 + floor($sumStats / 10);
$modsCostModifier = 2 + floor($sumMods / 50);
$damageCostModifier = 1 + floor($sumDamage / 100);
$result = intval($sumStats * $statsCostModifier + $sumMods * $modsCostModifier + $sumDamage * $damageCostModifier);
return max($result, 1);
}
protected function wrap(int $number): string
@ -146,26 +147,26 @@ class Item
public function getAllInfo(): string
{
$needsLines = [
'сила' => $this->need_strength,
'ловкость' => $this->need_dexterity,
'интуиция' => $this->need_intuition,
'выносливость' => $this->need_endurance,
'интеллект' => $this->need_intelligence,
'мудрость' => $this->need_wisdom,
'сила' => $this->needStrength,
'ловкость' => $this->needDexterity,
'интуиция' => $this->needIntuition,
'выносливость' => $this->needEndurance,
'интеллект' => $this->needIntelligence,
'мудрость' => $this->needWisdom,
];
$addsLines = [
'Сила' => $this->add_strength,
'Ловкость' => $this->add_dexterity,
'Интуиция' => $this->add_intuition,
'Выносливость' => $this->add_endurance,
'Интеллект' => $this->add_intelligence,
'Мудрость' => $this->add_wisdom,
'Точность' => $this->add_accuracy,
'Увёртливость' => $this->add_evasion,
'Шанс крита' => $this->add_criticals,
'Сила' => $this->addStrength,
'Ловкость' => $this->addDexterity,
'Интуиция' => $this->addIntuition,
'Выносливость' => $this->addEndurance,
'Интеллект' => $this->addIntelligence,
'Мудрость' => $this->addWisdom,
'Точность' => $this->addAccuracy,
'Увёртливость' => $this->addEvasion,
'Шанс крита' => $this->addCriticals,
];
$str = "<b>$this->name</b> (Масса: $this->weight)";
$str .= '<br> Стоимость: ' . $this->item_cost;
$str .= '<br> Стоимость: ' . $this->cost;
$str .= '<br> Долговечность: ' . $this->durability;
$str .= "<br><em>$this->typename</em><br>";
foreach ($needsLines as $stat => $value) {
@ -178,12 +179,12 @@ class Item
$str .= "<br>$stat" . $this->wrap($value);
}
}
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 ($this->addMinPhysicalDamage && !$this->addMaxPhysicalDamage) {
$damage = $this->addMinPhysicalDamage . ' - ' . $this->addMinPhysicalDamage;
} elseif (!$this->addMinPhysicalDamage && $this->addMaxPhysicalDamage) {
$damage = $this->addMaxPhysicalDamage . ' - ' . $this->addMaxPhysicalDamage;
} elseif ($this->addMinPhysicalDamage && $this->addMaxPhysicalDamage) {
$damage = $this->addMinPhysicalDamage . ' - ' . $this->addMaxPhysicalDamage;
}
if (isset($damage)) {
$str .= '<br>Урон: ' . $damage;
@ -191,8 +192,8 @@ class Item
return $str;
}
public static function getItemById($item_id): Item
public static function getItemById($itemId): Item
{
return new Item(Db::getInstance()->ofetch('select * from items where id = ?', $item_id));
return new Item(Db::getInstance()->ofetch('select * from items where id = ?', $itemId));
}
}
}

View File

@ -3,13 +3,13 @@
// Магия лечения травм
namespace Battles\Magic;
use Battles\UserEffects, Battles\Database\Db, Battles\User;
use Battles\Database\Db, Battles\User, Battles\UserEffect;
class CureInjury extends Magic
{
private $target;
private $login;
use UserEffects;
//use UserEffects;
/**
* Магия лечения травм. Если у персонажа несколько травм, лечится самая тяжёлая.
@ -25,16 +25,14 @@ class CureInjury extends Magic
}
$ok = null;
$injury = $db->ofetch('SELECT effect_id, type, name FROM users_effects WHERE type IN (11,12,13,14) AND owner_id = ? ORDER BY type DESC LIMIT 1', $target);
if (in_array($injury->type, [11, 12, 13, 14]) && $injuryType >= $injury->type) {
$db->execute('DELETE FROM users_effects WHERE effect_id = ?', $injury->effect_id);
if (empty($injury->name) || $injury->name == 'Неизвестный эффект') {
$injuryName = self::$effectName[$injury->type];
if (in_array($injury->type, [11, 12, 13, 14]) && $injuryType >= $injury->type && UserEffect::remove($target, $injury->effect_id)) {
if (empty($injury->name) || $injury->name === 'Неизвестный эффект') {
$injuryName = UserEffect::$effectName[$injury->type];
} else {
$injuryName = $injury->name;
}
$ok = "Вы вылечили повреждение ${injuryName} персонажу $this->login.";
} elseif ($injury->effect_id && $injuryType == 15) {
$db->execute('DELETE FROM users_effects WHERE type IN (11,12,13,14) AND owner_id = ?', $target);
} elseif ($injury->effect_id && $injuryType === 15 && UserEffect::massRemove($target, [11,12,13,14])) {
$ok = "Вы вылечили все повреждения персонажу $this->login.";
}
return $ok;

View File

@ -25,16 +25,16 @@ class Sharpen extends Magic
if (!$this->isUsable()) {
return $this->status;
}
$item = DressedItems::getDressedItemBySlot(Item::ITEM_TYPE_WEAPON, $_SESSION['uid']);
$item = DressedItems::getDressedItemBySlot(Item::TYPE_WEAPON, $_SESSION['uid']);
// Проверяем, что в названии предмета нет цифр и плюсов.
if (preg_match('/[\W\S]+\+\[?[\d]]?/', $item->name)) {
if (preg_match('/\+\d/', $item->name)) {
return 'Этот предмет точить нельзя!';
}
$newMinPhysicalDamage = $item->add_min_physical_damage + $sharpenStrength;
$newMaxPhysicalDamage = $item->add_max_physical_damage + $sharpenStrength;
$newItemName = $item->name . " [+$sharpenStrength]";
Db::getInstance()->execute('UPDATE battles.inventory SET name = ?, add_min_physical_damage = ?, add_max_physical_damage = ? WHERE item_id = ? ', [$newItemName, $newMinPhysicalDamage, $newMaxPhysicalDamage, $item->item_id]);
Db::getInstance()->execute('UPDATE inventory SET name = ?, add_min_physical_damage = ?, add_max_physical_damage = ? WHERE item_id = ? ', [$newItemName, $newMinPhysicalDamage, $newMaxPhysicalDamage, $item->item_id]);
return "У вас получилось изготовить предмет $newItemName!";
}
@ -42,4 +42,4 @@ class Sharpen extends Magic
{
return $this->isNotInBattle(User::getInstance()) && $this->isSuccess(User::getInstance(), $this->magicDifficulty);
}
}
}

View File

@ -1,39 +0,0 @@
<?php
/**
* Author: lopiu
* Date: 05.07.2020
* Time: 23:32
*/
namespace Battles\Models;
use Battles\Database\Db;
class EffectsModel
{
protected $DB;
const EFFECT_HIDEUSERINFO = 5; // Обезлик
public function __construct(int $user_id)
{
$this->DB = Db::getInstance()->ofetchAll('SELECT * FROM users_effects WHERE owner_id = ?', $user_id);
}
/**
* Проверка обезличен ли персонаж.
* @return int date() до конца эффекта или 0.
*/
public function getHideUserInfoStatus(): int
{
if ($this->DB) {
$i = 0;
while ($i < count($this->DB)) {
if ($this->DB[$i]->type == self::EFFECT_HIDEUSERINFO) {
return $this->DB[$i]->remaining_time;
}
$i++;
}
}
return 0;
}
}

View File

@ -0,0 +1,119 @@
<?php
# Date: 23.02.2022 (2:47)
namespace Battles\Models;
use Battles\Database\Db;
class Inventory
{
public static function getWeight(int $userId): int
{
return Db::getInstance()->fetchColumn(
'select sum(weight) from inventory where owner_id = ? and on_sale = 0',
$userId
);
}
public static function getBonuses(int $userId)
{
return Db::getInstance()->ofetch(
"select
sum(add_strength) as item_strength,
sum(add_dexterity) as item_dexterity,
sum(add_intuition) as item_intuition,
sum(add_endurance) as item_endurance,
sum(add_intelligence) as item_intelligence,
sum(add_wisdom) as item_wisdom,
sum(add_accuracy) as item_accuracy,
sum(add_evasion) as item_evasion,
sum(add_criticals) as item_criticals,
sum(add_min_physical_damage) as item_min_physical_damage,
sum(add_max_physical_damage) as item_max_physical_damage
from
inventory
where
dressed_slot != 0 and owner_id = ?",
$userId
);
}
public static function getDressed(int $itemType, int $userId): object
{
return Db::getInstance()->ofetchAll(
'SELECT
dressed_slot
FROM
inventory
WHERE
dressed_slot != 0 AND item_type = ? AND owner_id = ?',
[$itemType, $userId]
);
}
public static function countDressed(int $itemType, int $userId): object
{
return Db::getInstance()->ofetchAll(
'SELECT
count(dressed_slot)
FROM
inventory
WHERE
dressed_slot != 0 AND item_type = ? AND owner_id = ?',
[$itemType, $userId]
);
}
public static function undressOne(int $slot, int $userId)
{
Db::getInstance()->execute(
'UPDATE
inventory
SET
dressed_slot = 0
WHERE
dressed_slot = ? AND owner_id = ?',
[$slot, $userId]
);
}
public static function dressOne(int $itemId, int $userId)
{
Db::getInstance()->execute(
'UPDATE
inventory
SET
dressed_slot = item_type
WHERE
item_id = ? AND owner_id = ?',
[$itemId, $userId]
);
}
public static function dressOneToSlot(int $itemId, int $slot)
{
Db::getInstance()->execute('UPDATE inventory SET dressed_slot = ? WHERE item_id = ?', [$slot, $itemId]);
}
public static function destroyItem(int $itemId, int $userId)
{
Db::getInstance()->execute(
'delete
from
inventory
where
dressed_slot = 0 and owner_id = ? and item_id = ?',
[$userId, $itemId]
);
}
public static function changeRings(int $itemId)
{
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 = ?', $itemId);
}
public static function isWeared(int $itemId): bool
{
return Db::getInstance()->fetchColumn('select count(*) from inventory where item_id = ? and dressed_slot > 0', $itemId) > 0;
}
}

View File

@ -0,0 +1,23 @@
<?php
/**
* Author: lopiu
* Date: 04.07.2020
* Time: 13:17
*/
namespace Battles\Models;
use Battles\Database\Db;
use Battles\User;
class Presents
{
public function getAll($userId = null)
{
if (is_null($userId)) {
$userId = User::getInstance()->getId();
}
return Db::getInstance()->execute('SELECT sender_id, image FROM `users_presents` WHERE owner_id = ?', $userId);
}
}

View File

@ -1,26 +0,0 @@
<?php
/**
* Author: lopiu
* Date: 04.07.2020
* Time: 13:17
*/
namespace Battles\Models;
use Battles\Database\Db;
class PresentsModel
{
protected $DB;
public function __construct(int $user_id)
{
if (!$this->DB) {
$this->DB = Db::getInstance()->execute('SELECT sender_id, image FROM `users_presents` WHERE owner_id = ?', $user_id);
}
}
public function getAllPresents()
{
return $this->DB;
}
}

View File

@ -0,0 +1,36 @@
<?php
# Date: 23.02.2022 (3:02)
namespace Battles\Models\User;
use Battles\Database\Db;
class Effects
{
public static function getStatMods(int $userId)
{
return Db::getInstance()->ofetch(
"select
sum(mod_strength) as effect_strength,
sum(mod_dexterity) as effect_dexterity,
sum(mod_intuition) as effect_intuition,
sum(mod_endurance) as effect_endurance,
sum(mod_intelligence) as effect_intelligence,
sum(mod_wisdom) as effect_wisdom
from
users_effects
where
owner_id = ?",
$userId
);
}
public static function getAll(int $userId): object
{
return Db::getInstance()->ofetchAll('SELECT * FROM users_effects WHERE owner_id = ?', $userId);
}
public static function count(int $userId, int $type)
{
return Db::getInstance()->fetchColumn('select count(*) from users_effects where type = ? and owner_id = ?', [$type, $userId]);
}
}

View File

@ -0,0 +1,54 @@
<?php
# Date: 23.02.2022 (2:32)
namespace Battles\Models\User;
use Battles\Database\Db;
class Stats
{
/**
* @param int|string $user
*/
public static function getAll($user)
{
$col = ctype_digit(strval($user)) ? 'id' : 'login';
return Db::getInstance()->ofetch('select id, strength, dexterity, intuition, endurance, intelligence, wisdom, health, mana, free_stat_points, level from users where ' . $col . ' = ?', $user);
}
public static function addOne(string $stat, int $userId)
{
Db::getInstance()->execute(
"UPDATE
users
SET
$stat = $stat + 1,
free_stat_points = free_stat_points - 1
WHERE
id = ?",
$userId
);
}
public static function save(array $vars)
{
Db::getInstance()->execute(
'update
users
set
strength = ?,
dexterity = ?,
intuition = ?,
endurance = ?,
intelligence = ?,
wisdom = ?,
health = ?,
mana = ?,
free_stat_points = ?,
level = ?
where
id = ?',
$vars
);
}
}

View File

@ -17,50 +17,50 @@ class Moderation
public static function muteChat(int $target, int $time)
{
self::addEffectStatusToUserLog($target, UserEffects::$effectName[2]);
User::addUserEffect($target, 2, UserEffects::$effectName[2], $time);
self::addEffectStatusToUserLog($target, UserEffect::$effectName[2]);
UserEffect::add($target, 2, UserEffect::$effectName[2], $time);
}
public static function unmuteChat(int $target)
{
self::addEffectStatusToUserLog($target, UserEffects::$effectName[2] . self::STATUS_OFF);
User::removeUserEffect($target, 2);
self::addEffectStatusToUserLog($target, UserEffect::$effectName[2] . self::STATUS_OFF);
UserEffect::remove($target, 2);
}
public static function muteForum(int $target, int $time)
{
self::addEffectStatusToUserLog($target, UserEffects::$effectName[3]);
User::addUserEffect($target, 3, UserEffects::$effectName[3], $time);
self::addEffectStatusToUserLog($target, UserEffect::$effectName[3]);
UserEffect::add($target, 3, UserEffect::$effectName[3], $time);
}
public static function unmuteForum(int $target)
{
self::addEffectStatusToUserLog($target, UserEffects::$effectName[3] . self::STATUS_OFF);
User::removeUserEffect($target, 3);
self::addEffectStatusToUserLog($target, UserEffect::$effectName[3] . self::STATUS_OFF);
UserEffect::remove($target, 3);
}
public static function hideUserInfo(int $target, int $time)
{
self::addEffectStatusToUserLog($target, UserEffects::$effectName[5]);
User::addUserEffect($target, 5, UserEffects::$effectName[5], $time);
self::addEffectStatusToUserLog($target, UserEffect::$effectName[5]);
UserEffect::add($target, 5, UserEffect::$effectName[5], $time);
}
public static function unHideUserInfo(int $target)
{
self::addEffectStatusToUserLog($target, UserEffects::$effectName[5] . self::STATUS_OFF);
User::removeUserEffect($target, 5);
self::addEffectStatusToUserLog($target, UserEffect::$effectName[5] . self::STATUS_OFF);
UserEffect::remove($target, 5);
}
public static function blockUser(int $target)
{
self::addEffectStatusToUserLog($target, "Блокировка");
Db::getInstance()->execute('UPDATE battles.users SET block = 1 WHERE id = ?', $target);
Db::getInstance()->execute('UPDATE users SET block = 1 WHERE id = ?', $target);
}
public static function unBlockUser(int $target)
public static function unblockUser(int $target)
{
self::addEffectStatusToUserLog($target, "Блокировка" . self::STATUS_OFF);
Db::getInstance()->execute('UPDATE battles.users SET block = 0 WHERE block = 1 AND id = ?', $target);
Db::getInstance()->execute('UPDATE users SET block = 0 WHERE block = 1 AND id = ?', $target);
}
public static function addToUserLog(int $target, string $message, int $senderId)
@ -80,7 +80,7 @@ class Moderation
public static function addUserCheck(int $target)
{
self::addEffectStatusToUserLog($target, UserEffects::$effectName[20]);
User::addUserEffect($target, 20, UserEffects::$effectName[20], strtotime('3days'));
self::addEffectStatusToUserLog($target, UserEffect::$effectName[20]);
UserEffect::add($target, 20, UserEffect::$effectName[20], strtotime('3days'));
}
}
}

View File

@ -2,17 +2,17 @@
namespace Battles;
use Battles\Database\Db;
/**
* Разные способы отображения строки с логином персонажа.
*/
const INVIS = '<i>невидимка</i>';
class Nick extends UserStats
class Nick
{
private function isInvisible()
private User $user;
private function __construct(int $userid)
{
return Db::getInstance()->execute('SELECT count(*) FROM users_effects WHERE type = 1022 AND owner_id = ?', $this->id)->fetchColumn();
$this->user = User::getInstance($userid);
}
/**
@ -21,25 +21,41 @@ class Nick extends UserStats
*/
private function getAlignImage(): ?string
{
return $this->align ? "<img src='i/align_$this->align.gif' alt='Склонность'>" : null;
return $this->getImage($this->user->getAlign(), '/i/align_');
}
/**
* Отображение иконки клана.
* @return string
*/
private function getClanImage(): ?string
private function getClanImage(): string
{
return $this->clan ? "<img src='i/clan/$this->clan.png' alt='Клан'>" : null;
return $this->getImage($this->user->getClan(), '/i/clan/');
}
private function getImage($name, $path): string
{
if (empty($name)) {
return '';
}
$file = $path . $name . '.png';
$alt = '';
if (strpos($path, 'align')) {
$alt = '{a:' . $name . '}';
} elseif (strpos($path, 'clan')) {
$alt = '{c:' . $name . '}';
}
return file_exists($file) ? "<img src='$file' alt='$alt'>" : $alt;
}
private function getInfolinkImage(): string
{
return "<a href='inf.php?$this->login' target='_blank'><img src='i/inf.gif' alt='Ссылка на профиль'></a>";
return "<a href='inf.php?" . $this->user->getLogin() . "' target='_blank'><img src='i/inf.gif' alt='Ссылка на профиль'></a>";
}
/**
* Вызов класса из самого себя. Читать про обратное связывание и пытаться что-то понять.
*
* @param $playerId
*
* @return Nick
@ -58,7 +74,10 @@ class Nick extends UserStats
*/
public function full(int $showInvisibility = 0): string
{
return !$showInvisibility && $this->isInvisible() ? INVIS : $this->getAlignImage() . $this->getClanImage() . " <b>$this->login</b> [$this->level] " . $this->getInfolinkImage();
if ($showInvisibility === 0 && UserEffect::isInvisible($this->user->getId())) {
return INVIS;
}
return $this->getAlignImage() . '&nbsp;' . $this->getClanImage() . '&nbsp;' . $this->user->getLogin() . " [" . $this->user->getLevel() . "] " . $this->getInfolinkImage();
}
/**
@ -68,7 +87,7 @@ class Nick extends UserStats
*/
public function short(): string
{
return $this->login;
return $this->user->getLogin();
}
/**
@ -77,6 +96,6 @@ class Nick extends UserStats
*/
public function battle(): string
{
return $this->full() . "<img src='i/herz.gif' alt='HP'> [$this->health/$this->maxHealth]";
return $this->full() . "<img src='i/herz.gif' alt='HP'> [" . $this->user->stats()->getHealth() . "/" . $this->user->stats()->getMaxHealth() . "]";
}
}
}

View File

@ -44,9 +44,15 @@ class RememberPassword
$hash = uniqid();
$tomorrow = date('d-M-Y', strtotime('+1 days'));
Db::getInstance()->execute('INSERT INTO users_recovery (login, hash, ip, date) VALUES (?,?,?,?)', [$to, $hash, $tomorrow, $_SERVER['REMOTE_ADDR']]);
$message = sprintf('Здравствуйте!<br><br>Кто-то запросил восстановление пароля к вашему персонажу %s <br><br>
Для смены пароля пройдите по <a href="//%s/rememberpassword.php?change=%s">данной ссылке</a>.<br><br>
Ссылка будет действовать до <em>%s</em>',$to, GAMEDOMAIN, $hash, $tomorrow);
$message = sprintf(
'Здравствуйте!<br><br>Кто-то запросил восстановление пароля к вашему персонажу %s <br><br>
Для смены пароля пройдите по <a href="//%s/rememberpassword.php?change=%s">данной ссылке</a>.<br><br>
Ссылка будет действовать до <em>%s</em>',
$to,
GAMEDOMAIN,
$hash,
$tomorrow
);
return self::mailSend($check->email, $message) ? self::OK_MAIL_SENT : self::ERROR_MAIL_NOT_SENT;
}
public function isAllowed($hash)
@ -65,4 +71,4 @@ class RememberPassword
Db::getInstance()->execute('DELETE FROM users_recovery WHERE hash = ?', $hash);
return self::OK_PASSWORD_CHANGED;
}
}
}

View File

@ -1,11 +1,12 @@
<?php
namespace Battles;
/*
* Список наименований игровых комнат.
*/
trait Rooms
{
public static $roomNames = [
public static array $roomNames = [
0 => "Секретная Комната",
1 => "Дом поединков",
20 => "Центральная площадь",
@ -186,4 +187,4 @@ trait Rooms
2601 => "Замковая Площадь",
2702 => "Центральная площадь (мираж)",
];
}
}

View File

@ -12,9 +12,9 @@ class Shop
public int $categoryType = 0;
private int $shopId;
private function __construct($shop_id)
private function __construct($shopId)
{
$this->shopId = $shop_id;
$this->shopId = $shopId;
}
public static function id($shopid): self
@ -70,18 +70,18 @@ class Shop
public function getCategoryName(): string
{
$names = [
Item::ITEM_TYPE_HELMET => 'Шлемы',
Item::ITEM_TYPE_ARMOR => 'Броня',
Item::ITEM_TYPE_LEGS => 'Поножи',
Item::ITEM_TYPE_BOOTS => 'Сапоги',
Item::ITEM_TYPE_GLOVES => 'Перчатки',
Item::ITEM_TYPE_WEAPON => 'Оружие',
Item::ITEM_TYPE_SHIELD => 'Щиты',
Item::ITEM_TYPE_BELT => 'Пояса',
Item::ITEM_TYPE_RING => 'Кольца',
Item::ITEM_TYPE_AMULET => 'Амулеты',
Item::ITEM_TYPE_CONSUMABLE => 'Расходники',
Item::ITEM_TYPE_OTHER => 'Разное',
Item::TYPE_HELMET => 'Шлемы',
Item::TYPE_ARMOR => 'Броня',
Item::TYPE_LEGS => 'Поножи',
Item::TYPE_BOOTS => 'Сапоги',
Item::TYPE_GLOVES => 'Перчатки',
Item::TYPE_WEAPON => 'Оружие',
Item::TYPE_SHIELD => 'Щиты',
Item::TYPE_BELT => 'Пояса',
Item::TYPE_RING => 'Кольца',
Item::TYPE_AMULET => 'Амулеты',
Item::TYPE_CONSUMABLE => 'Расходники',
Item::TYPE_OTHER => 'Разное',
self::CATEGORY_SALE_ITEMS => 'Предметы в инвентаре',
0 => 'Все товары',
];
@ -92,4 +92,4 @@ class Shop
{
return $this->categoryType !== self::CATEGORY_SALE_ITEMS || $this->categoryType !== self::BARTER_SHOP ? $this->showGoods() : $this->showUserSellItems();
}
}
}

View File

@ -3,13 +3,10 @@
namespace Battles;
use Battles\Database\Db;
use Battles\Models\PresentsModel;
use Exceptions\GameException;
class ShopItem extends Item
{
private const NO_ITEMS_IN_STOCK = "Товара нет в наличии!";
private const NO_MONEY = "У вас нет денег!";
private const NO_BARTER_ITEMS = 'У вас нет требуемых предметов!';
private const BUTTON = [
'setmarket' => 'Сдать в магазин',
@ -23,32 +20,32 @@ insert into inventory (
need_strength, need_dexterity, need_intuition, need_endurance, need_intelligence, need_wisdom,
add_strength, add_dexterity, add_intuition, add_endurance, add_intelligence, add_wisdom,
add_accuracy, add_evasion, add_criticals, add_min_physical_damage, add_max_physical_damage,
image, weight, price)
select
image, weight, price)
select
?, name, item_type, durability,
need_strength, need_dexterity, need_intuition, need_endurance, need_intelligence, need_wisdom,
add_strength, add_dexterity, add_intuition, add_endurance, add_intelligence, add_wisdom,
add_accuracy, add_evasion, add_criticals, add_min_physical_damage, add_max_physical_damage,
image, weight, greatest(
(
(add_strength + add_dexterity + add_intuition + add_endurance + add_intelligence + add_wisdom) *
(5 + floor((add_strength + add_dexterity + add_intuition + add_endurance + add_intelligence + add_wisdom) / 10))
) +
(
(add_accuracy + add_criticals + add_evasion) *
(2 + floor((add_accuracy + add_criticals + add_evasion) / 50))
) +
(
(add_min_physical_damage + add_max_physical_damage) *
(add_strength + add_dexterity + add_intuition + add_endurance + add_intelligence + add_wisdom) *
(5 + floor((add_strength + add_dexterity + add_intuition + add_endurance + add_intelligence + add_wisdom) / 10))
) +
(
(add_accuracy + add_criticals + add_evasion) *
(2 + floor((add_accuracy + add_criticals + add_evasion) / 50))
) +
(
(add_min_physical_damage + add_max_physical_damage) *
(1 + floor((add_min_physical_damage + add_max_physical_damage) / 100))
)
,1)
,1)
from items where id = ?
SQL;
// Тип операции в магазине. Для отображения разных блоков в разных случаях.
private $optype;
private ?int $shop_item_quantity;
private ?int $shopItemQuantity;
private ?int $price;
public static string $status = '';
private ?string $jsonBarterList;
@ -62,8 +59,8 @@ SQL;
$this->optype = $operationType;
}
$this->price = $row->price ?? null;
$this->shop_item_quantity = $row->shop_item_quantity ?? null;
$this->item_id = $row->item_id ?? $row->id;
$this->shopItemQuantity = $row->shop_item_quantity ?? null;
$this->id = $row->item_id ?? $row->id;
if ($operationType === 'buyshop' || $operationType === 'buymarket') {
$this->offerId = $row->offer_id ?? 0; // Ид позиции в магазине.
$this->jsonBarterList = $row->barter_items_list_json ?? null;
@ -105,10 +102,10 @@ SQL;
private function getLowItemQuantityNote(): string
{
if ($this->shop_item_quantity < 1 || $this->shop_item_quantity > 19) {
if ($this->shopItemQuantity < 1 || $this->shopItemQuantity > 19) {
return '';
}
return "<div style='margin-top: 9px; font-style: italic;'>На складе осталось $this->shop_item_quantity единиц товара!</div>";
return "<div style='margin-top: 9px; font-style: italic;'>На складе осталось $this->shopItemQuantity единиц товара!</div>";
}
private function getTextBasedOnPrice(): string
@ -135,34 +132,34 @@ SQL;
return "<img src='/i/sh/$this->image' class='item-wrap-normal' alt=''>";
}
public static function buyItem($id, User $buyer)
public static function buyItem($id)
{
$check = Db::getInstance()->ofetch("select * from trade_offers where offer_id = ?", $id);
$item = new Item(Db::getInstance()->fetch('select * from items where id = ?', $check->shop_item_id));
$price = $item->calculateItemCost();
if (
!self::checkAndRemoveBarteredItems($check->barter_items_list_json, $buyer->getId()) ||
!self::checkAndPayTheBills($price, $buyer) ||
!self::checkAndRemoveBarteredItems($check->barter_items_list_json, User::getInstance()->getId()) ||
!self::checkAndPayTheBills($price) ||
!self::checkAndChangeRemainingItems($check->shop_item_quantity, $check->shop_item_id)
) {
return;
}
Db::getInstance()->execute(self::BUY_QUERY, [$buyer->getId(), $check->shop_item_id]);
$deloText = $buyer->getLogin() . " купил товар «" . $item->name . "» id:(" . $check->shop_item_id . ") в магазине за " . $price . ".";
GameLogs::addUserLog($buyer->getId(), $deloText);
Db::getInstance()->execute(self::BUY_QUERY, [User::getInstance()->getId(), $check->shop_item_id]);
$deloText = User::getInstance()->getLogin() . " купил товар «" . $item->name . "» id:(" . $check->shop_item_id . ") в магазине за " . $price . ".";
GameLogs::addUserLog(User::getInstance()->getId(), $deloText);
self::$status = "Предмет " . $item->name . " куплен за " . $price . ".";
}
private static function checkAndRemoveBarteredItems(?string $json_list, int $user_id): bool
private static function checkAndRemoveBarteredItems(?string $jsonList, int $userId): bool
{
if (empty($json_list)) {
if (empty($jsonList)) {
return true;
}
$allowItemRemove = true;
foreach (json_decode($json_list) as $item) {
$row = Db::getInstance()->ofetch('select sum(1) as s from inventory where name = ? and owner_id = ?', [Item::getItemById($item->item_id)->name, $user_id]);
foreach (json_decode($jsonList) as $item) {
$row = Db::getInstance()->ofetch('select sum(1) as s from inventory where name = ? and owner_id = ?', [Item::getItemById($item->item_id)->name, $userId]);
if ($row->s < $item->quantity) {
$allowItemRemove = false;
}
@ -171,45 +168,37 @@ SQL;
self::$status = self::NO_BARTER_ITEMS;
return false;
}
foreach (json_decode($json_list) as $item) {
foreach (json_decode($jsonList) as $item) {
$query = 'delete from inventory where name = ? and owner_id = ? limit ' . (int)$item->quantity;
// У-у-у, сука! https://phpdelusions.net/pdo#limit
Db::getInstance()->execute($query, [Item::getItemById($item->item_id)->name, $user_id]);
Db::getInstance()->execute($query, [Item::getItemById($item->item_id)->name, $userId]);
}
return true;
}
private static function checkAndPayTheBills(int $price, User $user): bool
private static function checkAndPayTheBills(int $price): bool
{
if (User::getInstance()->getMoney() > $price) {
User::getInstance()->setMoney(User::getInstance()->getMoney() - $price);
User::getInstance()->saveMoney();
if (User::getInstance()->money()->spend($price)) {
return true;
}
try {
$bank = new Bank(User::getInstance()->getId());
$bank->withdrawMoney($price);
return true;
} catch (GameException $e) {
self::$status = 'Банковская ошибка! ' . self::NO_MONEY;
return false;
}
(new Bank())->withdrawMoney($price);
return true;
}
private static function checkAndChangeRemainingItems(int $current_quantity, $item_id): bool
private static function checkAndChangeRemainingItems(int $currentQuantity, $itemId): bool
{
if (empty($current_quantity)) {
if (empty($currentQuantity)) {
self::$status = self::NO_ITEMS_IN_STOCK;
return false;
}
if ($current_quantity === -1) {
if ($currentQuantity === -1) {
return true;
}
Db::getInstance()->execute("update trade_offers set shop_item_quantity = shop_item_quantity -1 where shop_item_quantity != -1 and shop_item_id = ? ", $item_id);
Db::getInstance()->execute("update trade_offers set shop_item_quantity = shop_item_quantity -1 where shop_item_quantity != -1 and shop_item_id = ? ", $itemId);
return true;
}
public static function sellItem($id, User $seller, $bankTrade = 0)
public static function sellItem($id, $bankTrade = 0)
{
$item = Db::getInstance()->ofetch('select * from inventory where item_id = ?', $id);
$sellingItemName = $item->name;
@ -217,14 +206,12 @@ SQL;
$sellingPrice = $item->price > 1 ? mt_rand(0, $item->price / 2) : mt_rand(0, 1);
Db::getInstance()->execute('delete from inventory where item_id = ?', $id);
if ($bankTrade) {
$bank = new Bank($seller->getId());
$bank->setMoney($bank->getMoney() + $sellingPrice);
Bank::setBankMoney($bank->getMoney(), $seller->getId(), 'sellShop');
User::getInstance()->money()->modifyBank($sellingPrice, 'sellShop');
} else {
Db::getInstance()->execute('update users set money = money - ? where id = ?', [$sellingPrice, $_SESSION['uid']]);
User::getInstance()->money()->earn($sellingPrice);
}
$deloText = "{$seller->getLogin()} продал товар «{$sellingItemName}» id:($id) в магазине за $sellingPrice кр.";
GameLogs::addUserLog($seller->getId(), $deloText);
$deloText = User::getInstance()->getLogin() . " продал товар «{$sellingItemName}» id:($id) в магазине за $sellingPrice кр.";
GameLogs::addUserLog(User::getInstance()->getId(), $deloText);
if ($sellingPrice == 0) {
self::$status = "После длительных и изнурительных торгов вы плюнули на всё и просто подарили ваш «{$sellingItemName}» торговцу.";
} else {
@ -254,12 +241,12 @@ SQL;
return '';
}
$str = $this->optype == 'setmarket' ? '<input placeholder=" ' . $this->price . ' " name="cost">' : '';
$hiddenValue = $this->optype === 'buyshop' ? $this->offerId : $this->item_id;
$button_name = self::BUTTON[$this->optype];
$hiddenValue = $this->optype === 'buyshop' ? $this->offerId : $this->id;
$buttonName = self::BUTTON[$this->optype];
return <<<FORM
<form method="post">$str
<input type="hidden" name="itemId" value="$hiddenValue">
<br><input type="submit" name="$this->optype" value="$button_name">
<br><input type="submit" name="$this->optype" value="$buttonName">
</form>
FORM;
}
@ -269,27 +256,28 @@ FORM;
*/
public function getItemType(): int
{
return $this->item_type;
return $this->type;
}
/** Выдача магазинных предметов по запросу.
* Ввелась чтобы перебить takeshopitem() в functions с идентичным функционалом.
* @param int $item_id ИД предмета.
* @param int $to ИД пперсонажа-получателя.
*
* @param int $itemId ИД предмета.
* @param int $to ИД пперсонажа-получателя.
*/
public static function giveNewItem(int $item_id, int $to): array
public static function giveNewItem(int $itemId, int $to): array
{
$check = Db::getInstance()->ofetch('select 1 from items where id = ?', $item_id);
$check = Db::getInstance()->ofetch('select 1 from items where id = ?', $itemId);
if (!$check) {
return [];
}
Db::getInstance()->execute(self::BUY_QUERY, [$to, $item_id]);
Db::getInstance()->execute(self::BUY_QUERY, [$to, $itemId]);
$return = Db::getInstance()->ofetch('select image, name from inventory where item_id = ?', Db::getInstance()->lastInsertId());
return [
'img' => $return->image,
'name' => $return->name,
'id' => $item_id,
'id' => $itemId,
];
}
}
}

View File

@ -1,6 +1,7 @@
<?php
# Date: 30.09.2020 (09:42)
namespace Battles;
class Template
{
/**
@ -47,4 +48,4 @@ HTML_HEADER;
<h1>$buildingName</h1>
HTML;
}
}
}

View File

@ -8,9 +8,9 @@ class Travel
{
/**
* Соответствие ID комнаты игровому файлу.
* @var string[]
* @var array
*/
public static $roomFileName = [
public static array $roomFileName = [
1 => 'main.php',
20 => 'city.php',
21 => 'city.php',
@ -91,18 +91,16 @@ class Travel
private static array $roomsCheck = [22, 23, 27, 29, 30, 31, 37, 38, 39, 40, 41, 45, 53, 61, 401, 402, 600, 601, 602, 621, 650, 1051, 1052];
/**
* Перемещение по комнатам.
* Перемещение по комнатам. Header:Location уже включён.
*
* @param int $roomId ID куда идём.
* @param int $roomIdCurrent ID откуда идём.
*/
public static function toRoom(int $roomId, int $roomIdCurrent): void
{
UserStats::getInstance()->
$itemsWeightOverflow = Db::getInstance()->fetchColumn('SELECT SUM(weight) - (select strength * 4 from users where id = ?) AS weight_overflow FROM inventory WHERE owner_id = ? AND on_sale = 0', [$_SESSION['uid'], $_SESSION['uid']]);
$eff = Db::getInstance()->fetchColumn('SELECT type FROM users_effects WHERE owner_id = ? AND (`type` = 10 OR `type` = 13 OR `type` = 14)', $_SESSION['uid']);
$errors = [];
if ($itemsWeightOverflow > 0) {
if (UserEffect::isOverEncumbered($_SESSION['uid'])) {
$errors[0] = 'У вас переполнен рюкзак, вы не можете передвигаться...';
}
if ($eff == 10) {
@ -155,8 +153,8 @@ class Travel
$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[26] = [20, 401, 660, 661, 777, 2601];
$room[401] = $room[660] = $room[661] = $room[777] = [26];
$room[2601] = [26, 37, 404, 1051, 2655];
@ -187,7 +185,7 @@ class Travel
*
* @return void
*/
public static function roomRedirects(int $inRoom, int $inBattle, int $inTower)
public static function roomRedirects(int $inRoom, int $inBattle, int $inTower = 0)
{
if ($inBattle && in_array(pathinfo(debug_backtrace()[0]['file'])['basename'], self::$fbattleCheckFiles)) {
header('location: fbattle.php');
@ -207,4 +205,4 @@ class Travel
exit;
}
}
}
}

View File

@ -6,79 +6,99 @@ use Battles\Database\Db;
class User
{
private static ?self $_instance = null;
use Users;
private static ?self $instance = null;
private ?UserProfile $profile = null;
private ?UserEffect $effect = null;
private ?UserStats $stats = null;
private ?UserInfo $userInfo = null;
private ?UserMoney $userMoney = null;
protected int $id = 0;
protected string $login = '';
protected ?string $pass = null;
protected ?string $email = null;
protected ?string $realname = null;
protected ?string $borndate = null;
protected ?string $info = null;
protected int $level = 0;
protected ?int $align = null;
protected ?string $clan = null;
protected ?int $money = null;
protected ?string $ip = null;
protected ?int $admin = null;
protected int $room = 0;
protected int $block = 0;
protected string $shadow = '';
// Пока несуществующие, для совместимости.
protected int $experience = 0;
protected int $battle = 0;
protected int $in_tower = 0; // Скорее башню похороним чем запустим...
protected int $zayavka = 0;
public const INFO_CHAR_LIMIT = 1500;
private object $profileData;
protected function __construct($user = null)
{
if (is_null($user)) {
$user = $_SESSION['uid'];
}
$query = 'select * from users where login = ?';
if (is_numeric($user)) {
$query = 'select * from users where id = ?';
$user = (int)$user;
}
$user_query = Db::getInstance()->fetch($query, $user);
// Отсекаем 2.0000~
$col = ctype_digit(strval($user)) ? 'id' : 'login';
$query = "select * from users where $col = ?";
$userQuery = Db::getInstance()->fetch($query, $user);
foreach ($this as $key => $value) {
if (isset($user_query[$key])) {
$this->$key = $user_query[$key];
if (isset($userQuery[$key])) {
$this->$key = $userQuery[$key];
}
}
$this->profileData = (object)[
$this->id,
$this->pass,
$this->email,
$this->realname,
$this->borndate,
$this->info,
$this->ip,
];
}
public static function getInstance($user = null): self
{
if (is_null(self::$_instance)) {
self::$_instance = new self($user);
if (is_null(self::$instance)) {
self::$instance = new self($user);
}
return self::$_instance;
return self::$instance;
}
/**
* @param int $userId
* @param int $type
* @param string $name
* @param int $time
* @param string|null $json_modifiers_list (str, dex, int, end, intel, wis).
*/
public static function addUserEffect(int $userId, int $type, string $name, int $time, string $json_modifiers_list = null)
public function profile(): UserProfile
{
$mods = json_decode($json_modifiers_list);
Db::getInstance()->execute('INSERT INTO users_effects (owner_id, type, name, remaining_time, mod_strength, mod_dexterity, mod_intuition, mod_endurance, mod_intelligence, mod_wisdom) VALUES (?,?,?,?,?,?,?,?,?,?)', [$userId, $type, $name, $time, $mods->str ?? null, $mods->dex ?? null, $mods->int ?? null, $mods->end ?? null, $mods->intel ?? null, $mods->wis ?? null]);
if (is_null($this->profile)) {
$this->profile = new UserProfile(
$this->id,
$this->pass,
$this->email,
$this->realname,
$this->borndate,
$this->info,
$this->ip,
);
}
return $this->profile;
}
public static function removeUserEffect(int $userId, int $type): bool
public function effect(): UserEffect
{
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]);
if (is_null($this->effect)) {
$this->effect = new UserEffect();
}
return false;
return $this->effect;
}
public function stats(): UserStats
{
if (is_null($this->stats)) {
$this->stats = new UserStats($this->id);
}
return $this->stats;
}
public function userInfo(): UserInfo
{
if (is_null($this->userInfo)) {
$this->userInfo = new UserInfo($this->id);
}
return $this->userInfo;
}
public function money(): UserMoney
{
if (is_null($this->userMoney)) {
$this->userMoney = new UserMoney($this->id, $this->money);
}
return $this->userMoney;
}
public function getId(): int
@ -91,44 +111,6 @@ class User
return $this->login;
}
public function getPass(): string
{
return $this->pass;
}
/**
* @param mixed $pass
*/
public function setPass($pass): void
{
$this->pass = $pass;
}
public function getRealname(): string
{
return $this->realname;
}
/**
* @param mixed $realname
*/
public function setRealname($realname): void
{
$this->realname = $realname;
}
public function getInfo(): string
{
return $this->info;
}
/**
* @param mixed $info
*/
public function setInfo($info)
{
$this->info = $info;
}
public function getLevel(): int
{
@ -146,29 +128,14 @@ class User
}
/**
* @param string|null $short_name Короткое название клана. Передать null для очистки.
* @param string|null $shortName Короткое название клана. Передать null для очистки.
*/
public function setClan(?string $short_name)
public function setClan(?string $shortName)
{
$this->clan = is_null($short_name) ? null : $short_name;
$this->clan = is_null($shortName) ? null : $shortName;
$this->saveUser();
}
public function getMoney(): int
{
return $this->money;
}
public function setMoney(int $money)
{
$this->money = max($money, 0);
}
public function saveMoney()
{
Db::getInstance()->execute('update users set money = ? where id = ?', [$this->money, $this->id]);
}
public function getAdmin(): int
{
return $this->admin;
@ -206,7 +173,7 @@ class User
'm01', 'm02', 'm03', 'm04', 'm05', 'm06', 'm07', 'm08', 'm09', 'm10',
'f01', 'f02', 'f03', 'f04', 'f05', 'f06', 'f07', 'f08', 'f09', 'f10',
];
if (in_array($shadow, $shadows) && $this->getShadow() == '0.png') {
if (in_array($shadow, $shadows) && $this->getShadow() === '0.png') {
$this->shadow = $shadow . '.png';
}
}
@ -216,9 +183,13 @@ class User
return $this->experience;
}
public function addExperience(int $amount): void
/**
* @param int $experience
*/
public function addExperience(int $experience): void
{
$this->experience += max($amount, 0);
$this->experience += $experience;
Db::getInstance()->execute('update users set experience = ? where id = ?', [$experience, $this->id]);
}
public function getBattle(): int
@ -226,11 +197,6 @@ class User
return $this->battle;
}
public function getInTower(): int
{
return $this->in_tower;
}
public function getZayavka(): int
{
return $this->zayavka;
@ -241,53 +207,14 @@ class User
Db::getInstance()->execute('update online set real_time = ? where user_id = ?', [time(), $this->getId()]);
}
public function setInjury(int $type): bool
{
if (!in_array($type, [11, 12, 13, 14])) {
return false;
}
$names1 = ['разбитый нос', 'сотрясение первой степени', 'потрепанные уши', 'прикушенный язык', 'перелом переносицы', 'растяжение ноги', 'растяжение руки', 'подбитый глаз', 'синяк под глазом', 'кровоточащее рассечение', 'отбитая «пятая точка»', 'заклинившая челюсть', 'выбитый зуб «мудрости»', 'косоглазие'];
$names2 = ['отбитые почки', 'вывих «вырезано цензурой»', 'сотрясение второй степени', 'оторванное ухо', 'вывих руки', 'оторванные уши', 'поврежденный позвоночник', 'поврежденный копчик', 'разрыв сухожилия', 'перелом ребра', 'перелом двух ребер', 'вывих ноги', 'сломанная челюсть'];
$names3 = ['пробитый череп', 'разрыв селезенки', 'смещение позвонков', 'открытый перелом руки', 'открытый перелом «вырезано цензурой»', 'излом носоглотки', 'непонятные, но множественные травмы', 'сильное внутреннее кровотечение', 'раздробленная коленная чашечка', 'перелом шеи', 'смещение позвонков', 'открытый перелом ключицы', 'перелом позвоночника', 'вывих позвоночника', 'сотрясение третьей степени'];
$param_names = ['str', 'dex', 'int', 'end', 'intel', 'wis',];
shuffle($param_names);
switch ($type) {
case 11:
shuffle($names1);
$name = UserEffects::$effectName[$type] . ': ' . $names1(0);
self::addUserEffect($this->id, $type, $name, strtotime('30min'), json_encode([$param_names(0) => -1]));
break;
case 12:
shuffle($names2);
$name = UserEffects::$effectName[$type] . ': ' . $names2(0);
self::addUserEffect($this->id, $type, $name, strtotime('3hours'), json_encode([$param_names(0) => mt_rand(-3, -1), $param_names(1) => mt_rand(-3, -1)]));
break;
case 13:
shuffle($names3);
$name = UserEffects::$effectName[$type] . ': ' . $names3(0);
self::addUserEffect($this->id, $type, $name, strtotime('12hours'), json_encode([$param_names(0) => mt_rand(-5, -1), $param_names(1) => mt_rand(-5, -1), $param_names(2) => mt_rand(-5, -1)]));
break;
default: //type 14
self::addUserEffect($this->id, $type, UserEffects::$effectName[$type], strtotime('1day'), json_encode([$param_names(0) => -10]));
break;
}
return true;
}
/** Сохраняет в базу актуальные логин, пароль, email, имя, дату рождения, текст инфы, склонность, клан, образ, права админа.
*
*/
public function saveUser()
{
$query = 'update users set login = ?, pass = ?, email = ?, realname = ?, borndate = ?, info = ?, align = ?, clan = ?, shadow = ?, admin = ? where id = ?';
$query = 'update users set login = ?, align = ?, clan = ?, shadow = ?, admin = ? where id = ?';
$vals = [
$this->login, //set
$this->pass,
$this->email,
$this->realname,
$this->borndate,
$this->info,
$this->align,
$this->clan,
$this->shadow,
@ -296,4 +223,5 @@ class User
];
Db::getInstance()->execute($query, $vals);
}
}
}

View File

@ -1,14 +1,17 @@
<?php
# Date: 16.09.2020 (08:28)
# Названия эффектов, налагаемых на персонажа.
# Date: 16.02.2022 (23:01)
namespace Battles;
trait UserEffects
use Battles\Database\Db;
class UserEffect
{
public static $effectName = [
public static array $effectName = [
2 => 'Заклинание молчания',
3 => 'Заклятие форумного молчания',
4 => 'Заклятие хаоса',
5 => 'Заклятие обезличивания',
8 => 'Сон',
10 => 'паралич',
11 => 'Легкая травма',
12 => 'Средняя травма',
@ -50,7 +53,7 @@ trait UserEffects
9994 => 'Антидот/Путы (Эликсир?)',
];
public static $effectImage = [
public static array $effectImage = [
1 => 'travma.gif',
2 => 'magic/sleep.gif',
3 => 'magic/sleepf.gif',
@ -85,4 +88,75 @@ trait UserEffects
227 => 'magic/attack_defence.gif',
1022 => 'sh/hidden.gif',
];
}
/**
* @param int $userId
* @param int $type
* @param string $name
* @param int $time
* @param string|null $jsonModifiersList (str, dex, int, end, intel, wis).
*/
public static function add(int $userId, int $type, string $name, int $time, string $jsonModifiersList = null)
{
$mods = json_decode($jsonModifiersList);
Db::getInstance()->execute('INSERT INTO users_effects (owner_id, type, name, remaining_time, mod_strength, mod_dexterity, mod_intuition, mod_endurance, mod_intelligence, mod_wisdom) VALUES (?,?,?,?,?,?,?,?,?,?)', [$userId, $type, $name, $time, $mods->str ?? null, $mods->dex ?? null, $mods->int ?? null, $mods->end ?? null, $mods->intel ?? null, $mods->wis ?? null]);
}
public static function updateTime(int $userId, int $type, int $time)
{
if (self::hasEffect($userId, $type)) {
Db::getInstance()->execute('update users_effects set remaining_time = remaining_time + ? where owner_id = ? and type = ?', [$time, $userId, $type]);
}
}
public static function remove(int $userId, int $type): bool
{
if (self::hasEffect($userId, $type)) {
Db::getInstance()->execute('DELETE FROM users_effects WHERE owner_id = ? AND type = ?', [$userId, $type]);
return true;
}
return false;
}
public static function massRemove(int $userId, array $type): bool
{
if (Db::getInstance()->fetchColumn('SELECT count(*) FROM users_effects WHERE owner_id = ? AND type in (?)', [$userId, $type])) {
Db::getInstance()->execute('DELETE FROM users_effects WHERE owner_id = ? AND type in (?)', [$userId, $type]);
return true;
}
return false;
}
public static function hasEffect(int $userId, int $type): bool
{
return Db::getInstance()->fetchColumn('select count(*) from users_effects where owner_id = ? and type = ?', [$userId, $type]) > 0;
}
public static function getRemainingEffectTime(int $userId, int $type): int
{
return Db::getInstance()->fetchColumn('select remaining_time from users_effects where owner_id = ? and type = ?', [$userId, $type]);
}
public static function isInvisible(int $userId): bool
{
return self::hasEffect($userId, 1022);
}
public static function hasHiddenProfile(int $userId): string
{
$time = self::getRemainingEffectTime($userId, 5);
if (empty($time)) {
return '';
}
if ($time === -1) {
return 'навсегда';
}
return 'до' . date('d.m.Y', strtotime($time));
}
public static function isOverEncumbered(int $userid, int $addWeight = 0): bool
{
$query = 'select strength * 5 + ' . $addWeight . ' as max from inventory left join users u on owner_id = id where owner_id = ? having sum(weight) > max';
return Db::getInstance()->fetchColumn($query, $userid) > 0;
}
}

View File

@ -2,22 +2,34 @@
namespace Battles;
use Battles\Database\Db;
use Battles\Models\EffectsModel;
use Battles\Models\User\Effects;
use Exceptions\GameException;
class UserInfo extends UserStats
{
private const STRENGTH = 'Сила';
private const DEXTERITY = 'Ловкость';
private const INTUITION = 'Интуиция';
private const ENDURANCE = 'Выносливость';
private const INTELLIGENCE = 'Интеллект';
private const WISDOM = 'Мудрость';
private const PERCENT_20 = (20 / 100);
private const PERCENT_80 = (80 / 100);
private const LEVEL = 'Уровень';
private const HEALTH = 'Здоровье';
private const MANA = 'Пыль';
private const EXPERIENCE = 'Опыт';
private const FREE_STAT_POINTS = 'Очки характеристик';
private const MONEY = 'Деньги';
private const MONEY_IN_BANK = self::MONEY . ' в банке';
private const EVASION = 'Уворот';
private const ACCURACY = 'Точность';
private const CRITICALS = 'Шанс крита';
private const DAMAGE = 'Урон';
private const LOCATION = 'Локация';
use Rooms;
private int $bankMoney;
public function __construct($user)
{
parent::__construct($user);
$bank = new Bank($this->id);
$this->bankMoney = $bank->getMoney();
}
/**
* Отображает куклу персонажа (образ и слоты).
*
@ -25,237 +37,219 @@ class UserInfo extends UserStats
* на образ).
* @param int $isMain установить 1, если куклу надо показать на странице игрока (по клику на предмет снимает
* его).
*
* @throws GameException
*/
private function UserInfoDoll(int $isBattle = 0, int $isMain = 0)
private function userInfoDoll(int $isBattle = 0, int $isMain = 0): string
{
$di = new DressedItems($this->id);
$stats = new UserStats($this->id);
$dressedItems = $di->getItemsInSlots();
$str = null;
for ($i = 1; $i <= 12; $i++) {
echo sprintf('<div class="slot-%s">', $i);
$str .= sprintf('<div class="slot-%s">', $i);
if (!empty($dressedItems->$i)) {
if (!$isBattle && $isMain) {
echo sprintf('<a href="?edit=%s&drop=%s"><img src="/i/sh/%s" class="item-wrap-normal" alt="%s" title="%s"></a>',
mt_rand(), $i, $dressedItems->$i->image, $dressedItems->$i->name, $dressedItems->$i->name);
$str .= sprintf(
'<a href="?edit=%s&drop=%s"><img src="/i/sh/%s" class="item-wrap-normal" alt="%s" title="%s"></a>',
mt_rand(),
$i,
$dressedItems->$i->image,
$dressedItems->$i->name,
$dressedItems->$i->name
);
} else {
echo sprintf('<img src="/i/sh/%s" class="item-wrap-normal tip" alt="%s"><span class="tiptext"><strong>%s</strong></span>',
$dressedItems->$i->image, $dressedItems->$i->name, $dressedItems->$i->name);
$str .= sprintf(
'<img src="/i/sh/%s" class="item-wrap-normal tip" alt="%s"><span class="tiptext"><strong>%s</strong></span>',
$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);
$str .= sprintf('<img src="/i/sh/noitem.png" class="item-wrap-normal" title="Пустой слот [%s]" alt="Пустой слот [%s]">', $i, $i);
}
echo sprintf('</div><!-- slot-%s -->', $i);
$str .= sprintf('</div><!-- slot-%s -->', $i);
}
echo '<div class="slot-image">';
$str .= '<div class="slot-image">';
$str .= '<img src="/i/shadow/' . $this->shadow . '" alt="' . $this->login;
if ($isBattle) {
echo sprintf('<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>',
$this->shadow, $this->login, $this->login, $this->level, $this->strength, $this->dexterity, $this->intuition, $this->endurance, $this->intelligence, $this->wisdom);
unset($sh);
$str .= '" class = "tip">';
$str .= '<span class="tiptext"><b>' . $stats->getLogin() . '</b>';
$str .= self::LEVEL . ': ' . $stats->getLevel();
$str .= '<br>' . self::STRENGTH . ': ' . $stats->getStat('strength');
$str .= '<br>' . self::DEXTERITY . ': ' . $stats->getStat('dexterity');
$str .= '<br>' . self::INTUITION . ': ' . $stats->getStat('intuition');
$str .= '<br>' . self::ENDURANCE . ': ' . $stats->getStat('endurance');
$str .= '<br>' . self::INTELLIGENCE . ': ' . $stats->getStat('intelligence');
$str .= '<br>' . self::WISDOM . ': ' . $stats->getStat('wisdom');
$str .= '</span>';
} else {
echo '<img src="/i/shadow/' . $this->shadow . '" alt="' . $this->login . '">';
$str .= '">';
}
echo '</div><!-- slot-image -->';
$str .= '</div><!-- slot-image -->';
return $str;
}
private function ttz()
/** Вызов из inf.php */
private function ttz(): string
{
$stat = $this->getFullStats();
$arr = [
'Уровень' => $this->level,
'Сила' => $this->printStat('strength'),
'Ловкость' => $this->printStat('dexterity'),
'Интуиция' => $this->printStat('intuition'),
'Выносливость' => $this->printStat('endurance'),
'Интеллект' => $this->printStat('intelligence'),
'Мудрость' => $this->printStat('wisdom'),
'Уворот' => $stat->evasion,
'Точность' => $stat->accuracy,
'Шанс крита' => $stat->criticals,
'Урон' => $stat->min_physical_damage . ' - ' . $stat->max_physical_damage,
'Локация' => Rooms::$roomNames[$this->room],
self::LEVEL => $this->level,
self::STRENGTH => $this->strength,
self::DEXTERITY => $this->dexterity,
self::INTUITION => $this->intuition,
self::ENDURANCE => $this->endurance,
self::INTELLIGENCE => $this->intelligence,
self::WISDOM => $this->wisdom,
self::EVASION => $stat->evasion,
self::ACCURACY => $stat->accuracy,
self::CRITICALS => $stat->criticals,
self::DAMAGE => $stat->min_physical_damage . ' - ' . $stat->max_physical_damage,
self::LOCATION => Rooms::$roomNames[$this->room],
];
$str = null;
$i = 0;
foreach ($arr as $item => $value) {
$str .= "<div class='column' style='text-align: right; margin-right: 10px;'>$item</div><div class='column'>$value</div>";
if (in_array($i,[6,9])) {
$str .= "<div class='column' style='text-align: right; margin-right: 10px;'>$item</div><div class='column' style='width: max-content;'>$value</div>";
if (in_array($i, [6, 9])) {
$str .= "<div style='margin-top: 10px;'></div><div></div>";
}
$i++;
}
$nameString = $this->align ? "<img src='/i/align_$this->align.png' alt='Склонность'>" : "";
$nameString .= $this->block ? "<span class='private' style='text-decoration: line-through;'>$this->login</span>" : "<b>$this->login</b>";
$nameString .= $this->clan ? "<img src='/i/clan/$this->clan.png' alt='Клан'>" : "";
echo "<div class='info'><b>$nameString</b></div><!-- info -->";
echo "<div class='stats-container' style='display: grid; grid-template-columns: 150px 100px; font-size: 1.2em;'>$str</div>";
return sprintf(
"<div class='info'>%s</div><!-- info --><div class='stats-container' style='display: grid; grid-template-columns: 150px 100px; font-size: 1.2em;'>%s</div>",
Nick::id($this->id)->full(1),
$str
);
}
private function printStat($statName): string
private function showProgressBar(int $value, int $maxValue)
{
$values = [
'%20%' => (int)round(self::PERCENT_20 * $maxValue),
'%80%' => (int)round(self::PERCENT_80 * $maxValue),
'%value' => $value,
'%max' => $maxValue
];
$string = '<meter max="%max" low="%20%" high="%80%" optimum="%max" value="%value">%value / %max</meter>';
return str_replace(array_keys($values), array_values($values), $string);
}
/** Для вызова из main.php
* @throws GameException
*/
private function userInfoStats(): string
{
$data = [
self::LEVEL => $this->level,
self::HEALTH => $this->showProgressBar($this->health, $this->maxHealth),
self::MANA => $this->showProgressBar($this->mana, $this->maxMana),
self::STRENGTH => parent::getStat('strength', 1),
self::DEXTERITY => parent::getStat('dexterity', 1),
self::INTUITION => parent::getStat('intuition', 1),
self::ENDURANCE => parent::getStat('endurance', 1),
self::INTELLIGENCE => parent::getStat('intelligence', 1),
self::WISDOM => parent::getStat('wisdom', 1),
self::EXPERIENCE => $this->experience,
self::FREE_STAT_POINTS => $this->freeStatPoints,
self::MONEY => User::getInstance()->money()->get(),
self::MONEY_IN_BANK => User::getInstance()->money()->getBank(),
];
$str = '<div class="user-info">';
$str .= '<div class="info"><b>' . Nick::id($this->id)->full() . '</b></div><!-- info -->';
$str .= '<div class="stats-container">';
foreach ($data as $caption => $variable) {
$str .= '<div class="column" style="float: left;">' . $caption . '</div><!-- column -->';
$str .= '<div class="column">' . $variable . '</div><!-- column -->';
}
$str .= '</div><!-- stats-container -->';
$str .= '</div><!-- user-info -->';
return $str;
}
public function userInfoStatsTest(): array
{
$stat = $this->getFullStats();
return $this->getFreeStatPoints() ? $this->getStat($statName, 1) . '(' . $stat->$statName . ')' : $stat->$statName;
return [
self::STRENGTH => $this->strength,
self::DEXTERITY => $this->dexterity,
self::INTUITION => $this->intuition,
self::ENDURANCE => $this->endurance,
self::INTELLIGENCE => $this->intelligence,
self::WISDOM => $this->wisdom,
'<br>' . self::HEALTH => $this->health . ' / ' . $this->maxHealth,
self::MANA => $this->mana . ' / ' . $this->maxMana,
self::EVASION => $stat->evasion,
self::ACCURACY => $stat->accuracy,
self::CRITICALS => $stat->criticals,
self::DAMAGE => $stat->min_physical_damage . ' - ' . $stat->max_physical_damage,
'<br>' . self::LEVEL => $this->level,
self::EXPERIENCE => $this->experience,
self::MONEY => $this->money()->get(),
'<br>' . self::LOCATION => Rooms::$roomNames[$this->room],
];
}
//TODO вызывать из main.php
private function UserInfoStats($isMainWindow = 0)
{
$stat = $this->getFullStats();
$captions = 'Уровень:<br>Сила:<br>Ловкость:<br>Интуиция:<br>Выносливость:<br>Интеллект:<br>Мудрость:<br>Местонахождение:';
$variables =
$this->level . '<br>' .
$stat->strength . '<br>' .
$stat->dexterity . '<br>' .
$stat->intuition . '<br>' .
$stat->endurance . '<br>' .
$stat->intelligence . '<br>' .
$stat->wisdom . '<br>' .
Rooms::$roomNames[$this->room];
if ($isMainWindow) {
$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->bankMoney;
}
$nameString = null;
if ($this->align) {
if (file_exists("/i/align_$this->align.png")) {
$nameString .= "<img src='/i/align_$this->align.png' alt='Склонность'>";
} else {
$nameString .= "<svg width=16 height=16><circle cx=8 cy=8 r=6 stroke=darkorange stroke-width=1 fill=orange></circle></svg>";
}
} else {
$nameString .= "";
}
$nameString .= $this->block ? "<span class='private' style='text-decoration: line-through;'>$this->login</span>" : "<b>$this->login</b>";
if ($this->clan) {
if (file_exists("/i/clan/$this->clan.png")) {
$nameString .= "<img src='/i/clan/$this->clan.png' alt='Клан'>";
} else {
$nameString .= "<svg width=16 height=16><circle cx=8 cy=8 r=6 stroke=darkred stroke-width=1 fill=red></circle></svg>";
}
} else {
$nameString .= "";
}
echo <<<HTML
<div class="user-info">
<div class="info"><b>$nameString</b></div><!-- info -->
<div class="stats-container">
<div class="column">$captions</div><!-- column -->
<div class="column">$variables</div><!-- column -->
</div><!-- stats-container -->
</div><!-- user-info -->
HTML;
}
/**
* О персонаже для модераторов.
* @return string|null
/** Для вызова из inf.php
* @throws GameException
*/
private function showPrivateData(): ?string
{
$birthday = date('d.m.Y', strtotime($this->borndate));
$userLogs = GameLogs::getUserLogs($this->id);
$log = null;
while ($userLogRow = $userLogs->fetchArray(SQLITE3_ASSOC)) {
$log .= sprintf('<code>%s</code><br>', date('d.m.Y H:i ', strtotime($userLogRow['date'])) . $userLogRow['text']);
}
$adminData = User::getInstance()->getAdmin() ? $this->showAdminOnlyData() : null;
return <<<INFO
<div class="secret-info">
E-Mail: $this->email<br>
ДР Игрока: $birthday<br>
IP Регистрации: $this->ip<br>
$adminData<br>
<div class="secret-info-user-log"><b>Личное дело</b><br>
$log
</div><!-- secret-info-user-log -->
</div><!-- secret-info -->
INFO;
}
/**
* О персонаже для администраторов.
* @return string|null
*/
private function showAdminOnlyData(): ?string
{
return <<<INFO
ИД Игрока: $this->id<br>
ИД Комнаты: $this->room<br>
Деньги: $this->money<br>
Деньги в банке: $this->bankMoney<br>
Опыт: $this->experience<br>
Нераспределённые очки: $this->free_stat_points<br>
INFO;
}
private function Info()
{
echo '<div class="user-info-container">';
$this->UserInfoDoll();
$this->ttz();
echo '<div class="slot-lower"> <!-- statuses! --></div>';
echo '</div><!-- u-i-c -->';
echo '<hr><!-- Нижняя часть -->';
echo '<div class="user-info-container-lower">';
echo '<h2>Об игроке</h2>';
echo $this->realname ? "Имя: $this->realname" : "";
echo $this->info ? "<br>" . nl2br($this->info) : "";
echo '</div><!-- u-i-c-l -->';
if (User::getInstance()->getAdmin() || User::getInstance()->getAlign() == 1) {
echo $this->showPrivateData();
}
}
public function showUserInfo()
{
$effects = new EffectsModel($this->id);
if ($this->block && (!User::getInstance()->getAdmin() || !User::getInstance()->getAlign() == 1)) {
echo "<span class='error'>Персонаж $this->login заблокирован!</span>";
} elseif ($effects->getHideUserInfoStatus() && (!User::getInstance()->getAdmin() || !User::getInstance()->getAlign() == 1)) {
if ($effects->getHideUserInfoStatus() == -1) {
$date = 'навсегда';
} else {
$date = 'до' . date('d.m.Y', strtotime($effects->getHideUserInfoStatus()));
}
echo "<span class='error'>Персонаж $this->login обезличен $date.</span>";
$str = null;
$hidden = UserEffect::hasHiddenProfile($this->id);
if ($this->block && !User::getInstance()->getAdmin()) {
$str .= "<span class='error'>Персонаж $this->login заблокирован!</span>";
} elseif (!empty($hidden) && !User::getInstance()->getAdmin()) {
$str .= "<span class='error'>Персонаж $this->login обезличен $hidden.</span>";
} else {
$this->Info();
$str .= '<div class="user-info-container">';
$str .= $this->userInfoDoll();
$str .= $this->ttz();
$str .= '<div class="slot-lower" style="font-size: xxx-large">' . $this->showProgressBar($this->health, $this->maxHealth) . '<br>' . $this->showProgressBar($this->mana, $this->maxMana) . '</div>';
$str .= '</div><!-- u-i-c -->';
$str .= '<hr><!-- Нижняя часть -->';
$str .= '<div class="user-info-container-lower">';
$str .= '<h2>Об игроке</h2>';
$str .= $this->profile()->getRealname() ? "Имя: {$this->profile()->getRealname()}" : '';
$str .= $this->profile()->getInfo() ? '<br>' . nl2br($this->profile()->getInfo()) : '';
$str .= '</div><!-- u-i-c-l -->';
if (User::getInstance()->getAdmin()) {
$str .= UserPrivateInfo::get(User::getInstance());
}
}
echo $str;
}
public function showUserDoll($isBattle = 0, $isMain = 0): string
{
try {
return '<div class="user-info-container">' . $this->userInfoDoll($isBattle, $isMain) . '</div><!-- u-i-c -->';
} catch (GameException $e) {
return $e;
}
}
public function showUserDoll($isBattle = 0, $isMain = 0)
/** Отображение на main.php
*/
public function showUserInfoMain(): string
{
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 -->';
try {
return '<div class="user-doll-container">' . $this->userInfoDoll() . '</div><!-- user-doll-container -->' . $this->userInfoStats();
} catch (GameException $e) {
return $e;
}
}
public function showUserEffects(): string
{
$effs = Db::getInstance()->ofetchAll('SELECT * FROM users_effects WHERE owner_id = ?', $this->id);
$img = UserEffects::$effectImage;
$effs = Effects::getAll($this->id);
$img = UserEffect::$effectImage;
$r = '';
foreach ($effs as $effect) {
$timeleft = timeOut($effect->remaining_time - time());
@ -269,4 +263,4 @@ INFO;
}
return $r;
}
}
}

View File

@ -0,0 +1,71 @@
<?php
# Date: 19.02.2022 (18:54)
namespace Battles;
use Battles\Database\Db;
class UserMoney
{
private int $uid;
private int $walletMoney;
private Bank $bank;
public function __construct(int $uid, int $money)
{
$this->uid = $uid;
$this->walletMoney = $money;
$this->initBank();
}
private function initBank()
{
$this->bank = new Bank($this->uid);
}
public function get(): int
{
return $this->walletMoney;
}
public function set(int $money)
{
$this->walletMoney = max($money, 0);
}
public function getBank(): int
{
return $this->bank->getMoney();
}
public function modifyBank(int $money, string $logType = '')
{
$this->bank->modify($money, $logType);
}
private function save()
{
Db::getInstance()->execute('update users set money = ? where id = ?', [$this->walletMoney, $this->uid]);
}
/** Тратим деньги */
public function spend(int $value): bool
{
if ($this->walletMoney > $value && $value > 0) {
$this->walletMoney -= $value;
$this->save();
return true;
}
return false;
}
/** Получаем деньги */
public function earn(int $value): bool
{
if ($value <= 0) {
return false;
}
$this->walletMoney += $value;
$this->save();
return true;
}
}

View File

@ -0,0 +1,37 @@
<?php
# Date: 17.02.2022 (22:27)
namespace Battles;
use Battles\Database\Db;
class UserPrivateInfo
{
/** Блок информации для модераторов. */
public static function get(User $user)
{
$log = '';
$userLogs = GameLogs::getUserLogs($user->getId());
foreach ($userLogs as $row) {
$log .= sprintf('<code>%s</code><br>', date('d.m.Y H:i ', strtotime($row['date'])) . $row['text']);
}
$data = [
'%email' => $user->profile()->getEmail(),
'%bday' => date('d.m.Y', strtotime($user->profile()->getBorndate())),
'%regip' => $user->profile()->getIp(),
'%uid' => $user->getId(),
'%room' => $user->getRoom(),
'%wallet' => $user->money()->get(),
'%bank' => Db::getInstance()->fetchColumn('select money from bank where user_id = ?', $user->getId()),
'%exp' => $user->getExperience(),
'%fp' => Db::getInstance()->fetchColumn('select free_stat_points from users where id = ?', $user->getId()),
'%log' => $log ?? 'Журнал пуст.',
];
$string = '<div class="secret-info">E-Mail: %email<br>ДР Игрока: %bday<br>IP Регистрации: %regip<br>
ИД Игрока: %uid<br> ИД Комнаты: %room<br> Деньги: %wallet<br> Деньги в банке: %bank<br>
Опыт: %exp<br> Нераспределённые очки: %fp<br><br>
<div class="secret-info-user-log"><b>Личное дело</b><br>%log</div><!-- secret-info-user-log -->
</div><!-- secret-info -->';
return str_replace(array_keys($data), array_values($data), $string);
}
}

View File

@ -0,0 +1,163 @@
<?php
# Date: 16.02.2022 (21:22)
namespace Battles;
use Battles\Database\Db;
class UserProfile
{
private int $id;
private string $pass;
private string $email;
private string $realname;
private string $borndate;
private string $info;
private string $ip;
private const INFO_CHAR_LIMIT = 1500;
private string $status = '';
/**
* @param int $id
* @param string $pass
* @param string $email
* @param string $realname
* @param string $borndate
* @param string $info
* @param string $ip
*/
public function __construct(
int $id,
string $pass,
string $email,
string $realname,
string $borndate,
string $info,
string $ip
)
{
$this->id = $id;
$this->pass = $pass;
$this->email = $email;
$this->realname = $realname;
$this->borndate = $borndate;
$this->info = $info;
$this->ip = $ip;
}
public function changePassword($oldPassword, $newPassword)
{
if (password_verify($oldPassword, $this->pass)) {
$this->pass = password_hash($newPassword, PASSWORD_DEFAULT);
} else {
$this->status .= 'Неверный пароль!';
}
}
/**
* @return string
*/
public function getEmail(): string
{
return $this->email;
}
/**
* @param string $email
*/
public function setEmail(string $email): void
{
$this->email = $email;
}
/**
* @return string
*/
public function getRealname(): string
{
return $this->realname;
}
/**
* @param string $realname
*/
public function setRealname(string $realname): void
{
$this->realname = htmlspecialchars($realname);
}
/**
* @return string
*/
public function getBorndate(): string
{
return $this->borndate;
}
/**
* @param string $borndate
*/
public function setBorndate(string $borndate): void
{
$this->borndate = $borndate;
}
/**
* @return string
*/
public function getInfo(): string
{
return $this->info;
}
/**
* @param string $info
*/
public function setInfo(string $info): void
{
if (strlen($info) > self::INFO_CHAR_LIMIT) {
$this->status .= 'Максимальная длинна поля Хобби: ' . self::INFO_CHAR_LIMIT . ' символов!';
} else {
$info = htmlspecialchars($info);
$info = str_replace("\\n", '<br />', $info);
$info = str_replace("\\r", '', $info);
$info = str_replace('&lt;br&nbsp;/&gt;', '<br />', $info);
$this->info = $info;
}
}
/**
* @return string
*/
public function getIp(): string
{
return $this->ip;
}
/** Сохраняет в базу актуальные имя, пароль, email, дату рождения, текст инфы.
*
*/
public function save(): string
{
if ($this->status) {
return $this->status;
}
$query = 'update users set pass = ?, email = ?, realname = ?, borndate = ?, info = ? where id = ?';
$vals = [
//set
$this->pass,
$this->email,
$this->realname,
$this->borndate,
$this->info,
// where
$this->id
];
Db::getInstance()->execute($query, $vals);
return 'Успешно!';
}
}

View File

@ -3,33 +3,35 @@
namespace Battles;
use Battles\Database\Db;
use Battles\Models\Inventory;
use Battles\Models\User\Effects;
use Battles\Models\User\Stats;
use Exceptions\GameException;
class UserStats extends User
{
protected $strength;
protected $dexterity;
protected $intuition;
protected $endurance;
protected $intelligence;
protected $wisdom;
protected $health;
protected $mana;
protected $free_stat_points;
protected int $id;
protected int $strength;
protected int $dexterity;
protected int $intuition;
protected int $endurance;
protected int $intelligence;
protected int $wisdom;
protected int $health;
protected int $mana;
protected int $freeStatPoints = 0;
protected int $level;
private const STAT_MAXIMUM_AMOUNT = 40;
private const ERROR_STAT_IS_MAXIMUM = 'Ошибка: Параметр достиг своего лимита!';
private const ERROR_STAT_UNKNOWN = 'Ошибка: Неизвестный параметр!';
private const STAT_NAMES_ARRAY = ['strength', 'dexterity', 'intuition', 'endurance', 'intelligence', 'wisdom'];
//// Неизменяемые для игрока(!) переменные.
// Удар кулаком всегда 1-2.
protected int $minDamage = 1;
protected int $maxDamage = 2;
// Природная броня всегда 0.
// Зачем их три, если во всех формулах она одна?
protected int $headArmor = 0;
protected int $chestArmor = 0;
protected int $legArmor = 0;
// Динамически рассчитываемые
protected int $maxHealth;
protected int $maxMana;
@ -41,6 +43,19 @@ class UserStats extends User
*/
public function __construct($user)
{
$data = Stats::getAll($user);
$this->id = $data->id;
$this->strength = $data->strength;
$this->dexterity = $data->dexterity;
$this->intuition = $data->intuition;
$this->endurance = $data->endurance;
$this->intelligence = $data->intelligence;
$this->wisdom = $data->wisdom;
$this->health = $data->health;
$this->mana = $data->mana;
$this->freeStatPoints = $data->free_stat_points;
$this->level = $data->level;
parent::__construct($user);
$this->maxHealth = round(($this->endurance * 3) + ($this->endurance / 2) * ($this->level - 1) + ($this->endurance / 5) * (($this->level - 1) * ($this->level - 2) / 2));
$this->maxMana = round(($this->wisdom * 3) + ($this->wisdom / 2) * ($this->level - 1) + ($this->wisdom / 5) * (($this->level - 1) * ($this->level - 2) / 2));
@ -49,50 +64,51 @@ class UserStats extends User
/**
* Отдаёт информацию о базовом(!) стате.
*
* @param $stat_name - имя стата. Может принимать значения 'strength', 'dexterity', 'intuition',
* 'endurance', 'intelligence', 'wisdom'.
* @param int $isMainWindow - переключатель "главного окна". Если включить, дополнительно будет показывать ссылку
* на повышение стата на 1, при условии наличия свободных очков статов.
* @param string $statName - имя стата. Может принимать значения 'strength', 'dexterity', 'intuition',
* 'endurance', 'intelligence', 'wisdom'.
* @param int $isMainWindow - переключатель "главного окна". Если включить, дополнительно будет показывать ссылку
* на повышение стата на 1, при условии наличия свободных очков статов.
*
* @return string
* @throws GameException
*/
public function getStat($stat_name, int $isMainWindow = 0): string
public function getStat(string $statName, int $isMainWindow = 0): string
{
if (!in_array($stat_name, ['strength', 'dexterity', 'intuition', 'endurance', 'intelligence', 'wisdom'])) {
return self::ERROR_STAT_UNKNOWN;
if (!in_array($statName, self::STAT_NAMES_ARRAY)) {
throw new GameException(self::ERROR_STAT_UNKNOWN);
}
if ($this->free_stat_points && $isMainWindow && $this->$stat_name < self::STAT_MAXIMUM_AMOUNT) {
$this->$stat_name .= " <a href='/main.php?edit=" . mt_rand() . "&ups=$stat_name'>[+]</a>";
$stat = strval($this->$statName);
if ($this->freeStatPoints && $isMainWindow && $this->$statName < self::STAT_MAXIMUM_AMOUNT) {
$rand = strval(mt_rand());
$stat .= " <a href='/main.php?edit=$rand&ups=$statName'>[+]</a>";
}
return $this->$stat_name;
return $stat;
}
/**
* Повышает один из выбранных статов на 1, но не выше self::STAT_MAXIMUM_AMOUNT при условии наличия свободных очков
* статов.
*
* @param string $stat_name - имя стата. Может принимать значения 'strength', 'dexterity', 'intuition',
* @param string $statName - имя стата. Может принимать значения 'strength', 'dexterity', 'intuition',
* 'endurance', 'intelligence', 'wisdom'.
*
* @throws GameException
*/
public function addOnePointToStat(string $stat_name)
public function addOnePointToStat(string $statName)
{
if (!in_array($stat_name, ['strength', 'dexterity', 'intuition', 'endurance', 'intelligence', 'wisdom'])) {
if (!in_array($statName, self::STAT_NAMES_ARRAY)) {
throw new GameException(self::ERROR_STAT_UNKNOWN);
}
if ($this->free_stat_points <= 0 || $this->$stat_name >= self::STAT_MAXIMUM_AMOUNT) {
if ($this->freeStatPoints <= 0 || $this->$statName >= self::STAT_MAXIMUM_AMOUNT) {
throw new GameException(self::ERROR_STAT_IS_MAXIMUM);
} else {
$query = "UPDATE users SET {$stat_name} = {$stat_name} + 1, free_stat_points = free_stat_points - 1 WHERE id = ?";
Db::getInstance()->execute($query, $this->id);
Stats::addOne($statName, $this->id);
}
}
public function getMaxWeight(): int
{
return $this->strength * 4;
return max($this->strength * 5, 50);
}
/**
@ -116,7 +132,7 @@ class UserStats extends User
*/
public function getFreeStatPoints()
{
return $this->free_stat_points;
return $this->freeStatPoints;
}
/**
@ -135,71 +151,15 @@ class UserStats extends User
return $this->maxMana;
}
/**
* @return int
*/
public function getHeadArmor(): int
{
return $this->headArmor;
}
/**
* @return int
*/
public function getChestArmor(): int
{
return $this->chestArmor;
}
/**
* @return int
*/
public function getLegArmor(): int
{
return $this->legArmor;
}
public function getFullStats(): object
{
$stats = Db::getInstance()->ofetch("
select
strength,
dexterity,
intuition,
endurance,
intelligence,
wisdom
from users where id = $this->id");
$itemBonuses = Db::getInstance()->ofetch("
select
sum(add_strength) as item_strength,
sum(add_dexterity) as item_dexterity,
sum(add_intuition) as item_intuition,
sum(add_endurance) as item_endurance,
sum(add_intelligence) as item_intelligence,
sum(add_wisdom) as item_wisdom,
sum(add_accuracy) as item_accuracy,
sum(add_evasion) as item_evasion,
sum(add_criticals) as item_criticals,
sum(add_min_physical_damage) as item_min_physical_damage,
sum(add_max_physical_damage) as item_max_physical_damage
from inventory where dressed_slot != 0 and owner_id = $this->id");
$effectBonuses = Db::getInstance()->ofetch("
select
sum(mod_strength) as effect_strength,
sum(mod_dexterity) as effect_dexterity,
sum(mod_intuition) as effect_intuition,
sum(mod_endurance) as effect_endurance,
sum(mod_intelligence) as effect_intelligence,
sum(mod_wisdom) as effect_wisdom
from users_effects where owner_id = $this->id");
$stats = Stats::getAll($this->id);
$itemBonuses = Inventory::getBonuses($this->id);
$effectBonuses = Effects::getStatMods($this->id);
$obj = (object)[];
$obj->strength = max(0,$stats->strength + $itemBonuses->item_strength + $effectBonuses->effect_strength);
$obj->dexterity = max(0,$stats->dexterity + $itemBonuses->item_dexterity + $effectBonuses->effect_dexterity);
$obj->intuition = max(0,$stats->intuition + $itemBonuses->item_intuition + $effectBonuses->effect_intuition);
$obj->endurance = max(0,$stats->endurance + $itemBonuses->item_endurance + $effectBonuses->effect_endurance);
$obj->intelligence = max(0,$stats->intelligence + $itemBonuses->item_intelligence + $effectBonuses->effect_intelligence);
$obj->wisdom = max(0,$stats->wisdom + $itemBonuses->item_wisdom + $effectBonuses->effect_wisdom);
foreach (self::STAT_NAMES_ARRAY as $stat) {
$obj->$stat = max(0, $stats->$stat + $itemBonuses->{'item_' . $stat} + $effectBonuses->{'effect_' . $stat});
}
$obj->accuracy = max(0, $itemBonuses->item_accuracy);
$obj->evasion = max(0, $itemBonuses->item_evasion);
$obj->criticals = max(0, $itemBonuses->item_criticals);
@ -211,8 +171,8 @@ class UserStats extends User
public function levelUp(): string
{
$this->level += 1;
$this->free_stat_points += 2;
$this->saveStats();
$this->freeStatPoints += 2;
$this->save();
Chat::sendSys('Внимание, вы получили ' . $this->level . 'уровень. Доступны очки распределения параметров.');
return 'Персонаж перешёл на ' . $this->level . 'уровень.';
}
@ -220,12 +180,9 @@ class UserStats extends User
/** Сохраняет в базу актуальные статы, здоровье, ману, свободные очки статов и уровень.
*
*/
private function saveStats()
private function save()
{
$query = 'update users set strength = ?, dexterity = ?, intuition = ?, endurance = ?,
intelligence = ?, wisdom = ?, health = ?, mana = ?, free_stat_points = ?,
level = ? where id = ?';
$vals = [
Stats::save([
$this->strength, //set
$this->dexterity,
$this->intuition,
@ -234,10 +191,9 @@ class UserStats extends User
$this->wisdom,
$this->health,
$this->mana,
$this->free_stat_points,
$this->freeStatPoints,
$this->level,
$this->id //where
];
Db::getInstance()->execute($query, $vals);
]);
}
}
}

29
classes/Battles/Users.php Normal file
View File

@ -0,0 +1,29 @@
<?php
# Date: 23.02.2022 (1:49)
namespace Battles;
trait Users
{
protected int $id = 0;
protected string $login = '';
protected int $level = 0;
protected ?int $align = null;
protected ?string $clan = null;
protected ?int $admin = null;
protected int $room = 0;
protected int $block = 0;
protected string $shadow = '';
//userprofile
private string $pass = '';
private string $email = '';
private string $realname = '';
private string $borndate = '';
private string $info = '';
private string $ip = '';
private ?int $money = null;
private bool $fuk;
}

View File

@ -2,6 +2,8 @@
# Date: 28.10.2020 (17:41)
namespace Exceptions;
use Exception;
class GameException extends Exception { }
class GameException extends Exception //custom exception
{}

View File

@ -1,6 +1,6 @@
<?php
namespace Battles;
//namespace /;
use Battles\Database\Db;
@ -8,14 +8,22 @@ class Register
{
public static function addUser(string $login, string $password, string $email, string $birthday): int
{
if (Db::getInstance()->execute('select count(*) from users where login = ? or email = ?', [$login, $email])->fetchColumn()) {
$password = password_hash($password, PASSWORD_DEFAULT);
$email = filter_var($email, FILTER_VALIDATE_EMAIL);
if (
!$email ||
Db::getInstance()->execute('select count(*) from users where login = ? or email = ?', [$login, $email])->fetchColumn()
) {
return 0;
}
Db::getInstance()->execute('insert into users (login,pass,email,borndate,ip,session_id,shadow) values (?,?,?,?,?,?,?)',
[$login, $password, $email, $birthday, $_SERVER['REMOTE_ADDR'], session_id(), '0.png']);
Db::getInstance()->execute(
'insert into users (login,pass,email,borndate,ip,session_id) values (?,?,?,?,?,?)',
[$login, $password, $email, $birthday, $_SERVER['REMOTE_ADDR'], session_id()]
);
$userId = Db::getInstance()->lastInsertId();
Db::getInstance()->execute('insert into online (user_id, login_time, room, real_time) values (?,?,1,?)', [$userId, time(), time()]);
Db::getInstance()->execute('insert into bank (user_id) values ?', $userId);
return $userId;
}
}
}

View File

@ -1612,9 +1612,9 @@ class fbattle
addchp('<font color=red>Внимание!</font> Победа! Бой окончен. Всего вами нанесено урона : ' . $this->damage[$v] . ' HP. Получено опыта : ' . $this->exp[$v] . ' (' . $dop_exp . '%)' . $ads . ' ', '{[]}' . Nick::id($v)->short() . '{[]}');
mysql_query('UPDATE `users` SET `win` = (`win` +1), `fullhptime` = ' . time() . ' WHERE `id` = "' . $v . '"');
GiveExp($v, $this->exp[$v]);
\Battles\User::getInstance($v)->addExperience($this->exp[$v]);
if ($user['caveleader'] > 0 || $user['laba'] > 0) {
GiveRep($v, $rep);
\Battles\User::getInstance($v)->addExperience($rep);
}
if ($user['klan']) {
mysql_query('UPDATE `clans` SET `clanexp` = (`clanexp`+' . (int)$this->exp[$user['id']] . ') WHERE `id` = "' . $v[$user['klan']] . '" LIMIT 1');
@ -1628,7 +1628,7 @@ class fbattle
$flag = 2;
foreach ($this->t2 as $k => $v) {
mysql_query('UPDATE `battle` SET `win` = 2 WHERE `id` = "' . $this->user['battle'] . '" LIMIT 1');
$this->t2[$k] = Nick::id($v)->short();
$this->t2[$k] = \Battles\Nick::id($v)->short();
if ($this->battle_data['aren_of'] == 1 && $this->t2[$k] && $v < _BOTSEPARATOR_) {
mysql_query('INSERT INTO `logs_arena` (`battle`, `user`, `uid`, `damage`, `team`) VALUES ("' . $this->user['battle'] . '", "' . $this->t1[$k] . '", "' . $v . '", "' . $this->damage[$v] . '", "2")');
@ -1668,9 +1668,9 @@ class fbattle
echo "<script>console.log('Win fiz 1');</script>";
}
mysql_query('UPDATE `users` SET `win` = (`win` +1), `fullhptime` = ' . time() . ' WHERE `id` = "' . $v . '"');
GiveExp($v, $this->exp[$v]);
\Battles\User::getInstance($v)->addExperience($this->exp[$v]);
if ($user['caveleader'] > 0 || $user['laba'] > 0) {
GiveRep($v, $rep);
\Battles\User::getInstance($v)->addExperience($rep);
}
if ($user['klan']) {
mysql_query('UPDATE `clans` SET `clanexp` = (`clanexp`+' . (int)$this->exp[$user['id']] . ') WHERE `id` = "' . $v[$user['klan']] . '" LIMIT 1');

View File

@ -419,7 +419,7 @@ TASK;
return $ins;
}
public function timeOut($ttm)
public function timeOut($ttm): string
{
$out = '';
$time_still = $ttm;
@ -590,5 +590,3 @@ TASK;
fclose($fp);
}
}
$q = new Quests;

View File

@ -1,44 +0,0 @@
<?php
/**
* Copyright (c) 2018.
* Author: Igor Barkov <lopar.4ever@gmail.com>
* Project name: Battles-Game
*/
class showpers
{
private $pers_data;
private $weared_items;
private function __construct($id)
{
if (!$this->pers_data) {
$query = db::c()->query('SELECT * FROM `users` WHERE `id` = ?i', $id)->fetch_assoc();
$this->pers_data = $query;
}
if (!$this->weared_items) {
$query = db::c()->query('SELECT `name`, `img`, `type` FROM `inventory` WHERE `owner` = ?i AND `dressed` = 1', $id);
$this->weared_items = $query;
}
}
private function dgfs()
{
$w_items['sergi'] = $this->pers_data['sergi'];
$w_items['kulon'] = $this->pers_data['kulon'];
$w_items['weap'] = $this->pers_data['weap'];
$w_items['bron'] = $this->pers_data['bron'];
$w_items['r1'] = $this->pers_data['r1'];
$w_items['r2'] = $this->pers_data['r2'];
$w_items['r3'] = $this->pers_data['r3'];
$w_items['helm'] = $this->pers_data['helm'];
$w_items['perchi'] = $this->pers_data['perchi'];
$w_items['shit'] = $this->pers_data['shit'];
$w_items['boots'] = $this->pers_data['boots'];
$w_items['rubax'] = $this->pers_data['rubax'];
$w_items['plaw'] = $this->pers_data['plaw'];
$w_items['rune1'] = $this->pers_data['rune1'];
$w_items['rune2'] = $this->pers_data['rune2'];
$w_items['rune3'] = $this->pers_data['rune3'];
}
}

View File

@ -30,7 +30,7 @@ header("Cache-Control: post-check=0, pre-check=0", false);
*/
spl_autoload_register(function ($className) {
$fileName = __DIR__ . '/classes/' . str_replace('\\', '/', $className . '.php');
$fileName = __DIR__ . '/classes/' . str_replace('\\', DIRECTORY_SEPARATOR, $className . '.php');
if (file_exists($fileName)) {
require_once $fileName;
}

View File

@ -372,9 +372,9 @@ class fbattle
addchp('<font color=red>Внимание!</font> Победа! Бой окончен. Всего вами нанесено урона : ' . $this->damage[$v] . ' HP. Получено опыта : ' . $this->exp[$v] . ' (' . $dop_exp . '%)' . $ads . ' ', '{[]}' . Nick::id($v)->short() . '{[]}');
mysql_query('UPDATE `users` SET `win` = (`win` +1), `fullhptime` = ' . time() . ' WHERE `id` = "' . $v . '"');
GiveExp($v, $this->exp[$v]);
\Battles\User::getInstance($v)->addExperience($this->exp[$v]);
if ($user['caveleader'] > 0 || $user['laba'] > 0) {
GiveRep($v, $rep);
\Battles\User::getInstance($v)->addExperience($rep);
}
if ($user['klan']) {
mysql_query('UPDATE `clans` SET `clanexp` = (`clanexp`+' . (int)$this->exp[$user['id']] . ') WHERE `id` = "' . $v[$user['klan']] . '" LIMIT 1');
@ -449,7 +449,7 @@ class fbattle
addchp('<font color=red>Внимание!</font> Победа! Бой окончен. Всего вами нанесено урона : ' . (int)$this->damage[$v] . ' HP. Получено опыта ' . $this->exp[$v] . ' (' . $dop_exp . '%). ', '{[]}' . Nick::id($v)->short() . '{[]}');
mysql_query('UPDATE `users` SET `win` = (`win`+1), `fullhptime` = ' . time() . ' WHERE `id` = "' . $v . '"');
GiveExp($v, $this->exp[$v]);
\Battles\User::getInstance($v)->addExperience($this->exp[$v]);
}
$winers .= implode("</B>, <B>", $this->t2);

View File

@ -319,7 +319,7 @@ img.tip:hover + span.tiptext {
/* Отображение информации о персонаже в inf.php (класс User.php) */
div.user-info-container {
display: grid;
grid-template-columns: repeat(4, 75px) auto 100px;
grid-template-columns: repeat(4, 75px) auto;
grid-template-rows: repeat(5, 75px) auto;
grid-gap: 10px;
}
@ -409,11 +409,68 @@ div.user-info-container > div.user-info > div.stats-container > div.column {
div.user-info-container > div.user-info > div.stats-container > div.column + div.column {
text-align: left;
}
div.user-info-container > div.user-signs {
grid-column: 6;
grid-row: 1 / 6;
/*--DOLL-----------------------*/
div.user-doll-container {
display: grid;
grid-template-columns: repeat(4, 75px);
grid-template-rows: repeat(5, 75px);
grid-gap: 10px;
float: left;
margin-right: 10px;
}
div.user-doll-container > div.slot-1,
div.user-doll-container > div.slot-2,
div.user-doll-container > div.slot-3,
div.user-doll-container > div.slot-4 {
grid-column: 1;
}
div.user-doll-container > div.slot-5,
div.user-doll-container > div.slot-6,
div.user-doll-container > div.slot-7,
div.user-doll-container > div.slot-8 {
grid-column: 4;
}
div.user-doll-container > div.slot-1,
div.user-doll-container > div.slot-5 {
grid-row: 1;
}
div.user-doll-container > div.slot-2,
div.user-doll-container > div.slot-6 {
grid-row: 2;
}
div.user-doll-container > div.slot-3,
div.user-doll-container > div.slot-7 {
grid-row: 3;
}
div.user-doll-container > div.slot-4,
div.user-doll-container > div.slot-8 {
grid-row: 4;
}
div.user-doll-container > div.slot-9,
div.user-doll-container > div.slot-10,
div.user-doll-container > div.slot-11,
div.user-doll-container > div.slot-12 {
grid-row: 5;
}
div.user-doll-container > div.slot-image {
grid-column: 2 / 4;
grid-row: 1 / 5;
}
div.user-doll-container > div.slot-image > img {
width: 160px;
height: 330px;
border-radius: 5px;
}
/*-----------------------------*/
div.debug {
background:#fef;
@ -422,14 +479,14 @@ div.debug {
padding:5px;
margin: 3px;
}
div.secret-info {
.secret-info {
background:#fee;
border:1px dashed #faa;
border-radius:5px;
padding:5px;
margin: 3px;
}
div.secret-info > span {
.secret-info > span {
color: #966;
}
/* for classes/City.php included in /city.php */

View File

@ -137,10 +137,7 @@ Template::header('fbattle');
<table width=250 cellspacing=0 cellpadding=0>
<tr>
<td valign=top width=250 nowrap>
<?php
$myinfo = new User($_SESSION['uid']);
$myinfo->showUserDoll(1);
?>
<?= \Battles\User::getInstance()->userInfo()->showUserDoll(1) ?>
</td>
</tr>
</table>
@ -165,7 +162,7 @@ Template::header('fbattle');
$dressed = db::c()->query('SELECT `id` FROM `inventory` WHERE `id` = ?i AND `dressed` = 1', $_GET['use'])->fetch_row();
if ((int)$dressed[0] > 0) {
$my_class = $fbattle->my_class;
usemagic($_GET['use'], "" . $_POST['target']);
$bb = explode("<!--", ob_get_clean());
$bb = str_replace('"', "&quot;", (strip_tags($bb[0])));
header("Location: " . $_SERVER['PHP_SELF'] . "?buf=" . $bb);
@ -473,8 +470,7 @@ Template::header('fbattle');
<?php
if ($fbattle->return == 1) {
$enemyInfo = new User($fbattle->enemy);
$enemyInfo->showUserDoll(1);
echo \Battles\User::getInstance($fbattle->enemy)->userInfo()->showUserDoll(1);
} else {
if ($fbattle->battle_data['type'] == 4 || $fbattle->battle_data['type'] == 5) {
$a = [6, 16];

View File

@ -7,8 +7,6 @@
use Battles\Chat;
use Battles\Database\Db;
use Battles\DressedItems;
use Battles\InventoryItem;
use Battles\Travel;
use Battles\User;
use Battles\UserStats;
@ -25,59 +23,7 @@ if (User::getInstance()->getBlock()) {
}
//Проверки на соответствие скрипта и комнаты, которые были натыканы по всем файлам.
Travel::roomRedirects(User::getInstance()->getRoom(), User::getInstance()->getBattle(), User::getInstance()->getInTower());
///*
// * Проверки на соответствие скрипта и комнаты, которые были натыканы по всем файлам.
// */
//$fbattleCheckFiles = [
// 'c_haos_in.php',
// 'c_haos.php',
// 'c_park.php',
// 'city.php',
// 'clan_castle.php',
// 'enter_cave.php',
// 'library.php',
// 'atk.php',
// 'podzem_dialog.php',
// 'post.php',
// 'shop.php',
// 'tournament.php',
// 'vxod.php',
// 'bank.php',
// 'canalizaciya,php',
// 'forest.php',
// 'main.php',
// 'repair.php',
// 'towerstamp.php',
// 'hell.php',
// 'ul_clans.php',
// 'labirint.php',
// 'akadem.php',
// 'towerin.php',
// 'user_anketa.php',
// 'zayavka.php',
//];
////Может просто отовсюду? О_о
//if (User::$current->getBattle() && in_array(pathinfo(debug_backtrace()[0]['file'])['basename'], $fbattleCheckFiles)) {
// header('location: fbattle.php');
// exit;
//}
//$towerinCheckFiles = ['main.php', 'city.php', 'tower.php'];
//if (User::$current->getInTower() && in_array(pathinfo(debug_backtrace()[0]['file'])['basename'], $towerinCheckFiles)) {
// header('location: towerin.php');
// exit;
//}
//$roomsCheck = [22, 23, 25, 27, 29, 30, 31, 37, 38, 39, 40, 41, 45, 53, 61, 401, 402, 600, 601, 602, 621, 650, 1051, 1052];
//// Если я в одной из этих комнат,
//// [И] Имя файла который инклюдит файл с проверкой не совпадает с именем файла локации в которой я нахожусь
//// [И] Номер комнаты который я пытаюсь открыть есть в списке проверяемых
//if (in_array(User::$current->getRoom(), $roomsCheck)
// && pathinfo(debug_backtrace()[0]['file'])['basename'] != Travel::$roomFileName[User::$current->getRoom()]
// && in_array(array_search(pathinfo(debug_backtrace()[0]['file'])['basename'], Travel::$roomFileName), $roomsCheck)) {
// header('location: main.php');
// exit;
//}
Travel::roomRedirects(User::getInstance()->getRoom(), User::getInstance()->getBattle());
if (
!empty($_GET['goto']) &&
@ -90,15 +36,19 @@ if (
User::getInstance()->setRoom(intval($_GET['goto']));
}
function createbot($bot, $login = null)
function createbot($bot, $login = null): array
{
if (!User::getInstance($bot)->getId()) {
return false;
if (empty($login)) {
$login = Db::getInstance()->fetchColumn('select login from users where id = ?', $bot);
}
$botname = $login ?: User::getInstance($bot)->getLogin();
Db::getInstance()->execute('insert into bots (name, prototype, hp) values (?, ?, ?)',
[$botname, $bot, (new UserStats($bot))->getMaxHealth()]);
return ["id" => Db::getInstance()->lastInsertId(), "login" => $botname];
if (empty($login)) {
return [];
}
Db::getInstance()->execute('insert into bots (name, prototype) values (?,?)', [$login, $bot]);
return [
'id' => Db::getInstance()->lastInsertId(),
'login' => $login,
];
}
$var_map = [
@ -122,27 +72,25 @@ function savecavedata($cavedata, $caveleader, $floor)
fclose($f1);
}
function GiveExp($id, $exp)
{
User::getInstance($id)->addExperience($exp);
}
/**
* Генератор прогрессбара.
* @param $current - Текущее значение.
* @param $maximum - Максимальное значение.
* @param string $line_color - Цвет полоски прогрессбара.
* @param string $bg_color - Фон прогрессбара.
*
* @param $current - Текущее значение.
* @param $maximum - Максимальное значение.
* @param string $lineColor - Цвет полоски прогрессбара.
* @param string $bgColor - Фон прогрессбара.
*
* @return string
*/
function showProgressBar($current, $maximum, string $line_color = 'limegreen', string $bg_color = 'silver'): string
function showProgressBar($current, $maximum, string $lineColor = 'limegreen', string $bgColor = 'silver'): string
{
$bar = round($current / $maximum * 100);
return <<<HTML
<div style="width: 100%; height: 16px; background: $bg_color; overflow: hidden; border-radius: 3px;">
<div style="height: 16px; background: $line_color; border-radius: 3px; width: $bar%;"></div>
<div style="width: 100%; height: 16px; background: $bgColor; overflow: hidden; border-radius: 3px;">
<div style="height: 16px; background: $lineColor; border-radius: 3px; width: $bar%;"></div>
</div>
<div style="width: 100%; height: 16px; font-size: 14px; text-align: center; margin-top: -16px;">
<div style="width: 100%; height: 16px; font-size: 14px; text-align: center; margi
n-top: -16px;">
$current / $maximum
</div>
HTML;
@ -154,115 +102,55 @@ HTML;
*
* @param $slot
*
* @throws \Krugozor\Database\Mysql\Exception
* @return string
*/
function echoscroll($slot)
function echoscroll($slot): string
{
$all_magic = 0;
$allMagic = 0;
if (User::getInstance()->getBattle()) {
$script = 'fbattle';
$bat = db::c()->query('SELECT `magic` FROM `battle` WHERE `id` = ?i', User::getInstance()->getBattle())->fetch_assoc();
$all_magic = unserialize($bat['magic']);
$allMagic = Db::getInstance()->fetchColumn('select magic from battle where id = ?', User::getInstance()->getBattle());
$allMagic = unserialize($allMagic);
} else {
$script = 'main';
}
$dress = db::c()->query('SELECT `id`, `magic`, `name`, `img`, `duration`, `maxdur` FROM `inventory` WHERE `id` = ?i', User::getInstance()->$slot)->fetch_assoc();
$need_charge = db::c()->query('SELECT `needcharge` FROM `magic` WHERE `id` = ?i', $dress['magic'])->fetch_assoc();
if ((User::getInstance()->$slot > 0) && ($all_magic[User::getInstance()->getId()] < 1 || empty($need_charge['needcharge']))) {
$dress = Db::getInstance()->fetch('select magic, name, image, durability from inventory where item_id = ?', User::getInstance()->$slot);
$needCharge = Db::getInstance()->fetchColumn('select needcharge from magic where id = ?', $dress['magic']);
$str = null;
if ((User::getInstance()->$slot > 0) && ($allMagic[User::getInstance()->getId()] < 1 || empty($needCharge))) {
$row['id'] = User::getInstance()->$slot;
if ($dress['magic']) {
$magic = db::c()->query('SELECT targeted FROM `magic` WHERE `id` = ?i', $dress['magic'])->fetch_assoc();
echo "<a onclick=\"";
if ($magic['targeted'] == 1) {
echo "okno('Введите название предмета', '" . $script . ".php?use={$row['id']}', 'target'); ";
} else
if ($magic['targeted'] == 2) {
echo "findlogin('Введите имя персонажа', '" . $script . ".php?use={$row['id']}', 'target'); ";
$magicTargeted = Db::getInstance()->fetchColumn('select targeted from magic where id = ?', $dress['magic']);
$str .= "<a onclick=\"";
if ($magicTargeted === 1) {
$str .= "okno('Введите название предмета', '" . $script . ".php?use={$row['id']}', 'target'); ";
} elseif ($magicTargeted === 2) {
$str .= "findlogin('Введите имя персонажа', '" . $script . ".php?use={$row['id']}', 'target'); ";
} else {
echo "if(confirm('Использовать сейчас?')) { window.location='" . $script . ".php?use=" . $row['id'] . "';}";
$str .= "if(confirm('Использовать сейчас?')) { window.location='" . $script . ".php?use=" . $row['id'] . "';}";
}
echo "\"href='#'>";
$str .= "\"href='#'>";
}
echo <<<ACTIVE_SCROLL
$str .= <<<ACTIVE_SCROLL
<img class='tooltip' src="i/sh/{$dress['img']}" width='40' title="<b>{$dress['name']}</b><br> Прочность {$dress['duration']} / {$dress['maxdur']} " height='25' alt="Свиток"></a>
ACTIVE_SCROLL;
} elseif ((User::getInstance()->$slot > 0) && ($all_magic[User::getInstance()->getId()] >= 1) && $need_charge['needcharge'] > 0) {
echo <<<INACTIVE_SCROLL
} elseif ((User::getInstance()->$slot > 0) && ($allMagic[User::getInstance()->getId()] >= 1) && $needCharge['needcharge'] > 0) {
$str .= <<<INACTIVE_SCROLL
<img src="i/sh/magicclock.gif" width="40" height="25" title='Произведите размен ударами и магия снова станет доступна' alt="Свиток">
INACTIVE_SCROLL;
} else {
echo <<<EMPTY_SLOT
$str .= <<<EMPTY_SLOT
<img class="tooltip" src="i/w13.gif" width="40" height="25" title='<b>Пустой слот магия</b>' alt="Слот для свитка">
EMPTY_SLOT;
}
return $str;
}
// ссылка на магию
function showhrefmagic(array $dress): string
function timeOut($ttm): string
{
$magic = new Battles\Magic\Magic(Db::getInstance(), $dress['includemagic']);
$r = '';
$script = User::getInstance()->getBattle() ? 'fbattle' : 'main';
$r .= "<a onclick=\"";
if ($magic->getMagic()->targeted == 1) {
$r .= "okno('Введите название предмета', '{$script}.php?use={$dress['id']}', 'target')";
} elseif ($magic->getMagic()->targeted == 2) {
$r .= "findlogin('" . $magic->getMagic()->name . "', '{$script}.php?use={$dress['id']}', 'target')";
} else {
$r .= "if (confirm('Использовать сейчас?')) window.location='" . $script . ".php?use=" . $dress['id'] . "';";
}
$r .= "\"href='#'>";
$r .= "<img src=\"i/sh/{$dress['img']}\" style=\"filter:shadow(color=red, direction=90, strength=3);\" title=\"" . $dress['name'] . (($dress['text'] != null) ? "<br />На оружии выгравировано '{$dress['text']}'" : "") . "\"><br>";
return $r;
}
function timeOut($ttm)
{
$out = '';
$time_still = $ttm;
$tmp = floor($time_still / 2592000);
$id = 0;
if ($tmp > 0) {
$id++;
if ($id < 3) {
$out .= $tmp . " мес. ";
}
$time_still = $time_still - $tmp * 2592000;
}
$tmp = floor($time_still / 86400);
if ($tmp > 0) {
$id++;
if ($id < 3) {
$out .= $tmp . " дн. ";
}
$time_still = $time_still - $tmp * 86400;
}
$tmp = floor($time_still / 3600);
if ($tmp > 0) {
$id++;
if ($id < 3) {
$out .= $tmp . " ч. ";
}
$time_still = $time_still - $tmp * 3600;
}
$tmp = floor($time_still / 60);
if ($tmp > 0) {
$id++;
if ($id < 3) {
$out .= $tmp . " мин. ";
}
}
if ($out == '') {
if ($time_still < 0) {
$time_still = 0;
}
$out = $time_still . ' сек.';
}
return $out;
require_once 'classes/quests_class.php';
$q = new Quests();
return $q->timeOut($ttm);
}
/**
@ -270,103 +158,14 @@ function timeOut($ttm)
* @param $vars
* @param $vls
* @param $uid
*
* @return bool
*/
function addActions($time, $vars, $vls, $uid)
{
db::c()->query('LOCK TABLES `actions` WRITE');
$ins = db::c()->query('INSERT INTO `actions` (`uid`,`time`,`city`,`room`,`vars`,`ip`,`vals`) VALUES (?i, ?i, "?s", ?i, "?s", "?s", "?s")', $uid, $time, "capitalcity", 0, $vars, $_SERVER['REMOTE_ADDR'], $vls);
db::c()->query('UNLOCK TABLES');
return $ins;
}
// использовать магию
function usemagic($id, $target)
{
$user = Db::getInstance()->fetch('select * from users where id = ?', $_SESSION['uid']);
$row = db::c()->query('SELECT * FROM `inventory` WHERE `owner` = ?i AND id = ?i', User::getInstance()->getId(), $id)->fetch_assoc_array();
$bat = db::c()->query('SELECT * FROM `battle` WHERE `id` = ?i', User::getInstance()->getBattle())->fetch_assoc_array();
$all_magic = unserialize($bat['magic']);
$charge = 0;
$magic = db::c()->query('SELECT * FROM `magic` WHERE `id` = ?i', $row['magic'])->fetch_assoc_array();
if ($magic['needcharge'] > 0) {
$charge = $magic['needcharge'];
}
$incmagic = db::c()->query('SELECT * FROM `magic` WHERE `id` = ?i', $row['includemagic'])->fetch_assoc_array();
if ($incmagic['needcharge'] > 0) {
$charge = $incmagic['needcharge'];
}
//Переделать под новую базу
if (($all_magic[User::getInstance()->getId()] < 1 || $charge == 0) &&
($user['sila'] >= $row['nsila'] &&
$user['lovk'] >= $row['nlovk'] &&
$user['inta'] >= $row['ninta'] &&
$user['vinos'] >= $row['nvinos'] &&
$user['intel'] >= $row['nintel'] &&
$user['level'] >= $row['nlevel'] &&
(($user['align'] > 7 && $user['align'] < 8) || ((int)$user['align'] == (int)$row['nalign']) || ($row['nalign'] == 0)) &&
$user['noj'] >= $row['nnoj'] &&
$user['topor'] >= $row['ntopor'] &&
$user['dubina'] >= $row['ndubina'] &&
$user['mec'] >= $row['nmech'] &&
($row['type'] < 13 || $row['type'] == 50) && ($user['mfire'] >= $row['nfire']) &&
$user['mwater'] >= $row['nwater'] &&
$user['mair'] >= $row['nair'] &&
$user['mearth'] >= $row['nearth'] &&
$user['mlight'] >= $row['nlight'] &&
$user['mgray'] >= $row['ngray'] &&
$user['mdark'] >= $row['ndark'] &&
$row['needident'] == 0
) || $row['magic'] == 48 || $row['magic'] == 50) {
if (!$row['magic']) {
$incmagic['name'] = $row['includemagicname'];
$incmagic['cur'] = $row['includemagicdex'];
$incmagic['max'] = $row['includemagicmax'];
if ($incmagic['cur'] <= 0) {
return false;
}
$magic['targeted'] = $incmagic['targeted'];
echo "<span class='error'>";
include("magic/" . $incmagic['file']);
echo "</span>";
} else {
echo "<span class='error'>";
include("magic/" . $magic['file']);
echo "</span>";
}
if ($bat) {
if ($row['maxdur'] <= ($row['duration'] + 1)) {
InventoryItem::destroyItem($row['id']);
} else {
if (!$row['magic']) {
$query = 'update inventory set includemagicdex = includemagicdex - ? where item_id = ?';
} else {
$query = 'update inventory set durability = durability + ? where item_id = ?';
}
Db::getInstance()->execute($query, [$bat, $row['id']]);
}
if (!$charge) {
$charge = 0;
}
//ограничение по кол-ву за ход
if (User::getInstance()->getBattle()) {
$batMagic = Db::getInstance()->fetchColumn('select magic from battle where battle_id = ?', User::getInstance()->getBattle());
}
if (empty($batMagic)) {
$all_magic = [];
} else {
$all_magic = unserialize($batMagic);
}
$all_magic[User::getInstance()->getId()] += $charge;
Db::getInstance()->execute('update battle set magic = ? where battle_id = ?', [serialize($all_magic), User::getInstance()->getBattle()]);
}
}
return false;
$query = 'insert into actions (uid, time, city, room, vars, ip, vals) values (?,?,?,?,?,?,?)';
$values = [$uid, $time, 'capitalcity', 0, $vars, $_SERVER['REMOTE_ADDR'], $vls];
Db::getInstance()->execute('lock tables actions write');
Db::getInstance()->execute($query, $values);
Db::getInstance()->execute('unlock tables');
}
/* ВАЖНО! (#44)
@ -377,12 +176,26 @@ function usemagic($id, $target)
* по нескольку раз вызывают эти функции.
*/
function addch($text, $room = 0)
/**
* @param $text
* @param $room
* @param $smth
* @return void
* @deprecated use Chat::sendSys($msg) instead.
*/
function addch($text, $room = 0, $smth = null)
{
Chat::sendSys($text);
}
/**
* @param $text
* @param $who
* @param $room
* @return void
* @deprecated use Chat::sendSys($msg, $receiverId) instead.
*/
function addchp($text, $who, $room = 0)
{
Chat::sendSys($text, $who);
@ -393,6 +206,19 @@ function err($t)
echo '<span class="error">' . $t . '</span>';
}
/**
* @param int $userId
* @param string $text
*
*/
function telegraph(int $userId, string $text)
{
if (User::getInstance($userId)->getId() > 0) {
Chat::sendTelegraf($text, $userId);
}
}
function SolveExp($at_id, $def_id, $damage): float
{
$mods = [
@ -521,4 +347,4 @@ function SolveExp($at_id, $def_id, $damage): float
}
return round((($baseexp[$defInfo->getLevel()]) * ($defAllPrice / (($atAllPrice + $defAllPrice) / 2)) * ($damage / $defInfo->getMaxHealth()) * $expmf * $mfit * $mfbot * $mfbot2) / 3);
}
}

View File

@ -1,315 +1,60 @@
<?php
use Battles\Template;
use Battles\User;
use Battles\{Database\Db, Hostel, Travel, User, UserEffect};
require_once 'config.php';
$hostel = mysql_fetch_array(mysql_query('SELECT `id`, `uid`, `type`, `time` FROM `hostel` WHERE `uid` = "' . User::getInstance()->getId() . '" LIMIT 1'));
$error = '';
$rs = '';
$base = [1 => ['type' => 'Сумка'], 2 => ['type' => 'Сундук'], 3 => ['type' => 'Комната'], 4 => ['type' => 'Амбар']];
$times = [1 => 7, 2 => 14, 3 => 21, 4 => 28];
$cost = [1 => [8, 16, 24, 32], 2 => [15, 30, 45, 60], 3 => [25, 50, 75, 100], 4 => [40, 80, 120, 160]];
function remove_hostel_items($u)
{
$itms = mysql_query('SELECT `id`, `owner` FROM `inventory` WHERE `owner` = "-101' . $u . '"');
while ($pl = mysql_fetch_array($itms)) {
mysql_query('UPDATE `inventory` SET `owner` = "' . $u . '" WHERE `id` = "' . $pl['id'] . '" AND `owner` = "-101' . $u . '"');
$host = new Hostel();
if (!empty($_GET['exit'])) {
Travel::toRoom(26, 661);
}
if (!empty($_GET['to_room'])) {
if (empty($host->getHid())) {
$host->setError('У Вас, нету комнаты!');
}
if ($host->getTime() <= time()) {
$host->setError('У Вас просрочена аренда. Оплатите что-бы продолжить пользоваться нашими услугами!');
}
if ($host->getStatus()['type'] !== 'error') {
Travel::toRoom(661, 26);
}
}
function select_arenda($u, $type, $redirect = false)
{
$hostel = mysql_fetch_array(mysql_query('SELECT `id` FROM `hostel` WHERE `uid` = "' . $u['id'] . '" LIMIT 1'));
$price = [1 => 8, 2 => 15, 3 => 25, 4 => 40];
if (!isset($u['id'])) {
$r = 'Персонаж не найден ...';
} else {
if ($type > 0 && $type <= 4) {
if (isset($hostel['id'])) {
$r = 'Не более 1 арендованного места ...';
} else {
if ($u['money'] >= $price[$type]) {
$u['money'] -= $price[$type];
mysql_query('UPDATE `users` SET `money` = "' . $u['money'] . '" WHERE `id` = "' . $u['id'] . '" LIMIT 1');
mysql_query('INSERT INTO `hostel` (`uid`, `type`, `time`) VALUES ("' . $u['id'] . '", "' . $type . '", "' . (time() + 60 * 60 * 24 * 7) . '")');
$r = 'Поздравляем с успешной арендой ...';
} else {
$r = 'Недостаточно денег ...';
}
}
} else {
$r = 'Неверный тип аренды ...';
}
}
if ($redirect) {
header('Location: main.php');
}
return $r;
if (!empty($_GET['pays'])) {
$host->changeTime($_GET['pays']);
}
if ($_GET['exit'] == 1) {
if ($user['sleep'] == 0) {
mysql_query('UPDATE `users`,`online` SET `users`.`room` = 26, `online`.`room` = 26 WHERE `users`.`id` = "' . User::getInstance()->getId() . '" AND `online`.`id` = "' . User::getInstance()->getId() . '"');
header('Location: city.php');
} else {
$error = 'Вы спите ...';
}
if (!empty($_POST['select']) && !empty($_POST['tariff'])) {
$host->newRent((int)$_POST['tariff']);
}
if ($_GET['to_room'] == 1) {
if (isset($hostel['id'])) {
if ($hostel['time'] > time()) {
mysql_query('UPDATE `users`,`online` SET `users`.`room` = 661, `online`.`room` = 661 WHERE `users`.`id` = "' . User::getInstance()->getId() . '" AND `online`.`id` = "' . User::getInstance()->getId() . '"');
header('Location: hostel_room.php');
} else {
$error = 'У Вас просрочена аренда. Оплатите что-бы продолжить пользоваться нашими услугами ...';
}
} else {
$error = 'У Вас, нету комнаты ...';
}
if (!empty($_GET['del'])) {
$host->remove();
}
if ($_GET['pays'] && (int)$_GET['pays'] >= 1 && (int)$_GET['pays'] <= 4) {
if (isset($hostel['id'])) {
if (User::getInstance()->getMoney() >= $cost[$hostel['type']][(int)$_GET['pays']]) {
$time = $hostel['time'] + 60 * 60 * 24 * $times[(int)$_GET['pays']];
User::getInstance()->setMoney(User::getInstance()->getMoney() -= $cost[$hostel['type']][(int)$_GET['pays']]);
$hostel['time'] = $time;
mysql_query('UPDATE `users` SET `money` = "' . User::getInstance()->getMoney() . '" WHERE `id` = "' . User::getInstance()->getId() . '" LIMIT 1');
mysql_query('UPDATE `hostel` SET `time` = "' . $time . '" WHERE `uid` = "' . User::getInstance()->getId() . '" AND `id` = "' . $hostel['id'] . '" LIMIT 1');
$error = 'Всё прошло успешно ...';
} else {
$error = 'Недостаточно денег ...';
}
} else {
$error = 'Ошибка #1';
}
if (!empty($_POST['deselect']) && !empty($_POST['retariff'])) {
$host->changeType((int)$_POST['retariff']);
header('Location: main.php');
}
if (isset($_POST['select']) && isset($_POST['tariff'])) {
if ($_POST['tariff'] == 0) {
$error = 'Выберите тариф ...';
} else {
$error = select_arenda(User::getInstance(), (int)$_POST['tariff']);
}
}
if ($_GET['del'] == 1) {
if (isset($hostel['id']) && $hostel['time'] > time()) {
mysql_query('DELETE FROM `hostel` WHERE `uid` = "' . User::getInstance()->getId() . '" AND `id` = "' . $hostel['id'] . '" LIMIT 1');
remove_hostel_items(User::getInstance()->getId());
$error = 'Вы успешно отказались от аренды ...';
unset($hostel);
} elseif (isset($hostel['id']) && $hostel['time'] < time()) {
$error = 'Нельзя отказаться от услуг если имеется задолежнность ...';
}
}
if (isset($_POST['deselect']) && isset($_POST['retariff'])) {
if (isset($hostel['id']) && $hostel['time'] > time()) {
mysql_query('DELETE FROM `hostel` WHERE `uid` = "' . User::getInstance()->getId() . '" AND `id` = "' . $hostel['id'] . '" LIMIT 1');
remove_hostel_items(User::getInstance()->getId());
select_arenda(User::getInstance(), (int)$_POST['retariff'], true);
} elseif (isset($hostel['id']) && $hostel['time'] < time()) {
$error = 'Нельзя сменить услугу если имеется задолежнность ...';
}
}
if ($_GET['sleep'] && $user['sleep'] == 0) {
if ($user['sleep_time'] <= time()) {
$sl = 2;
mysql_query('UPDATE `users` SET `sleep` = "' . (time() + 60 * 60 * $sl) . '", `sleep_time` = "' . (time() + 60 * 60 * 8) . '" WHERE `id` = "' . User::getInstance()->getId() . '" LIMIT 1');
mysql_query('INSERT INTO `effects` (`type`, `name`, `time`, `owner`) VALUES ("8", "Сон", "' . (time() + 60 * 60 * $sl) . '", "' . User::getInstance()->getId() . '")');
$ef = mysql_query('SELECT `id`, `time`, `type` FROM `effects` WHERE `owner` = "' . User::getInstance()->getId() . '" AND `type` != 11 AND `type` != 12 AND `type` != 13 AND `type` != 14 AND `type` != 5 AND `type` != 4 AND `type` != 2 AND `type` != 3 AND `type` != 8');
while ($pl = mysql_fetch_array($ef)) {
$tm = $pl['time'] - time();
mysql_query('UPDATE `effects` SET `sleep` = "' . $tm . '" WHERE `id` = "' . $pl['id'] . '" AND `owner` = "' . User::getInstance()->getId() . '"');
}
if (!empty($_GET['sleep'])) {
if (UserEffect::getRemainingEffectTime(User::getInstance()->getId(), 8) <= time()) {
//Разморозка таймеров эффектов??!
UserEffect::add(User::getInstance()->getId(), 8, UserEffect::$effectName[8], time() + 60 * 60 * 2);
Db::getInstance()->execute('update users_effects set remaining_time = remaining_time - ? where owner_id = ? and type not in (11,12,13,14,5,4,3,2,8)', [time(), User::getInstance()->getId()]);
header('Location: hostel.php');
} else {
$error = 'Нельзя спать ... Приходите через : ' . timeOut($user['sleep_time'] - time());
$host->setError('Нельзя спать! Приходите через: ' . timeOut($user['sleep_time'] - time()));
}
}
if ($_GET['unsleep'] && $user['sleep'] > 0) {
mysql_query('UPDATE `users` SET `sleep` = "0" WHERE `id` = "' . User::getInstance()->getId() . '" LIMIT 1');
mysql_query('DELETE FROM `effects` WHERE `owner` = "' . User::getInstance()->getId() . '" AND `type` = "8" LIMIT 1');
$ef = mysql_query('SELECT `id`, `time`, `sleep` FROM `effects` WHERE `owner` = "' . User::getInstance()->getId() . '" AND `sleep` != 0');
while ($pl = mysql_fetch_array($ef)) {
$tm = time() + $pl['sleep'];
mysql_query('UPDATE `effects` SET `time` = "' . $tm . '", `sleep` = "0" WHERE `id` = "' . $pl['id'] . '" AND `owner` = "' . User::getInstance()->getId() . '"');
}
if (!empty($_GET['unsleep'])) {
//Заморозка таймеров эффектов??!
UserEffect::remove(User::getInstance()->getId(), 8);
Db::getInstance()->execute('update users_effects set remaining_time = remaining_time + ? where owner_id = ? and type not in (11,12,13,14,5,4,3,2,8)', [time(), User::getInstance()->getId()]);
header('Location: hostel.php');
}
Template::header('Хостел');
?>
<script src="js/ajaxLoad.js"></script>
<? if (isset($hostel['id'])) { ?>
<script>
$(document).ready(function () {
$("#retariff option[value='<?=$hostel['type']; ?>']").remove();
});
</script>
<? } ?>
<link rel="stylesheet" href="css/hostel.css"/>
<div class="contentContainer">
<div style="text-align: center;"><span class="hs">Гостиница, Холл</span></div>
<div class="buttonContainer">
<? if ($user['sleep'] == 0) { ?>
<input type="button" class="btns button-route" value="Уснуть" onclick="location.href='?sleep=1';"/>
<? } else { ?>
<input type="button" class="btns button-route" value="Пробудиться" onclick="location.href='?unsleep=1';"/>
<? } ?>
<input type="button" class="btns" value="Обновить" onclick="location.href='main.php';"/>
<input type="button" class="btns button-route" value="На улицу" onclick="location.href='?exit=1';"/>
<input type="button" class="btns button-route" value="Комната" onclick="location.href='?to_room=1';"/>
</div>
<div id="hostelLeft">
<div id="hostelInteractive">
<? if (!isset($hostel['id'])) { ?>
<fieldset class="hostelClientState">
<legend>Станьте нашим клиентом</legend>
<form method="post" style="text-align: center; width: 100%;">
<input type="hidden" name="act" value="settariff"/>
<p>Выберите подходящий для Вас вариант обслуживания:</p>
<div style="text-align: center; width: 100%;">
<select name="tariff" class="tariff">
<option value="0">Выбор ...</option>
<option value="1">Сумка</option>
<option value="2">Сундук</option>
<option value="3">Комната</option>
<option value="4">Амбар</option>
</select>
<input type="submit" class="button" value="Выбрал" name="select"/>
<? if ($error != '') {
echo '<br /><b style="color: Red;">' . $error . '</b><br />';
} ?>
</div>
</form>
</fieldset>
<? } else { ?>
<fieldset class="hostelClientState">
<legend>Добро пожаловать!</legend>
<form method="post" style="text-align: center; width: 100%;">
<p>Вы выбрали вариант предоставления жилья : <b><?= $base[$hostel['type']]['type']; ?></b></p>
<p>Аренда оплачена по: <? echo date('h:i d.m.y', $hostel['time']); ?>
(<small><? echo timeOut($hostel['time'] - time()); ?></small>)</p>
<div style="text-align: center; width: 100%;">
Сменить вариант аренды <select name="retariff" id="retariff">
<option value="0">Выбор ...</option>
<option value="1">Сумка</option>
<option value="2">Сундук</option>
<option value="3">Комната</option>
<option value="4">Амбар</option>
</select>
<input type="submit" class="button" value="Сменить" name="deselect"/>
</div>
</form>
<a href="javascript: void(0);" style="float: left; margin-left: 3px;"
onclick="if(confirm('Вы уверены?')) { location.href='?del=1'; }">Расторгнуть договор</a> <a
href="javascript: void(0);"
onclick="ajaxLoad('/hostel_checkpoint.php', 'hostelInteractive', {act:'pay'})"
style="float: right; margin-right: 3px;">Внести предоплату</a>
<? if ($error != '') {
echo '<br /><center><b style="color: Red;">' . $error . '</b></center><br />';
} ?>
</fieldset>
<? } ?>
</div>
<fieldset class="hostelRules" style="overflow: hidden;">
<legend>Правила проживания</legend>
<div style="overflow: auto; height: 168px !important; margin: 0; padding: 0;">
<div style="margin: 0; padding: 0; height: 100%;">
<h2>И что я получу за свои кровные?</h2>
У нас ты можешь:
<br/>- хранить свое барахло и прочий хлам.
<h2>Охрана у вас есть? Не воруют?</h2>
Самые любопытные могут получить в сурло прямо здесь - в холле.
<br/>- Устраивать беспорядки в комнатах не позволено.
<br/>- Прислуга у нас проверенная - пожитки твои не тронут.
<h2>И сколько стоит всё это удовольствие?</h2>
- Комнаты есть разные, для людей разного достатка. Смотри справа расценки.
<br/>- Платить нужно каждый день. Пока не заплатишь - на лестницу не ногой.
<br/>- Вместимость - это сколько твоих вещей влезет в комнату, имеется ввиду общая масса инвентаря.
<h2>Как всем этим пользоваться?</h2>
Всё просто. Плати и живи.
<br/>Приходишь, платишь по долгам, проходишь в аппартаменты. В сундуке есть секции для каждого вида
вещей, фильтр поможет разобраться.
<h2>Что ещё мне нужно знать?</h2>
- При смене размера комнаты, ты теряешь оставшееся оплаченное время.
<br/>- При просрочке платы более 60 суток, мы оставляем за собой право сдать вещи на аукцион для
погашения задолжености.
<br/>- Если долг будет разумный, то подарки забирать с полки не будем.
<br/>- Быстро сориентироваться с шмотом поможет фильтр предметов.
<br/>- Если что потеряешь - твои проблемы.
</div>
</div>
</fieldset>
</div>
<div id="hostelRight">
<fieldset>
<legend>Тарифы и услуги</legend>
<br/>
<table class="tarifsList" cellpadding="0" cellspacing="0">
<caption>Сумка</caption>
<tbody>
<tr>
<td class="tarifListLabel">Вместимость</td>
<td class="tarifListValue">15 ед.</td>
</tr>
<tr>
<td class="tarifListLabel">Стоимость (7 сут.)</td>
<td class="tarifListValue">8.00 кр.</td>
</tr>
</tbody>
</table>
<br/>
<table class="tarifsList" cellpadding="0" cellspacing="0">
<caption>Сундук</caption>
<tbody>
<tr>
<td class="tarifListLabel">Вместимость</td>
<td class="tarifListValue">30 ед.</td>
</tr>
<tr>
<td class="tarifListLabel">Стоимость (7 сут.)</td>
<td class="tarifListValue">15.00 кр.</td>
</tr>
</tbody>
</table>
<br/>
<table class="tarifsList" cellpadding="0" cellspacing="0">
<caption>Комната</caption>
<tbody>
<tr>
<td class="tarifListLabel">Вместимость</td>
<td class="tarifListValue">50 ед.</td>
</tr>
<tr>
<td class="tarifListLabel">Стоимость (7 сут.)</td>
<td class="tarifListValue">25.00 кр.</td>
</tr>
</tbody>
</table>
<br/>
<table class="tarifsList" cellpadding="0" cellspacing="0">
<caption>Амбар</caption>
<tbody>
<tr>
<td class="tarifListLabel">Вместимость</td>
<td class="tarifListValue">100 ед.</td>
</tr>
<tr>
<td class="tarifListLabel">Стоимость (7 сут.)</td>
<td class="tarifListValue">40.00 кр.</td>
</tr>
</tbody>
</table>
</fieldset>
</div>
</div>
require_once 'views/hostel.php';

View File

@ -1,22 +1,9 @@
<?php
use Battles\User, Battles\Database\Db;
use Battles\Hostel;
require_once "functions.php";
$hostel = Db::getInstance()->execute('select id, time, type from hostel where uid = ?', User::getInstance()->getId());
$base = [1 => [8, 16, 24, 32], 2 => [15, 30, 45, 60], 3 => [25, 50, 75, 100], 4 => [40, 80, 120, 160]];
require_once 'config.php';
if (isset($_POST['act']) && $_POST['act'] == 'pay' && isset($user['id']) && !empty($hostel->fetchColumn())) {
echo '<fieldset class="hostelClientState">';
echo '<legend>Предварительная оплата</legend>';
echo '<div style="text-align: center;"><p class="NORMAL" style="margin: 5px 0">';
echo 'Аренда оплачена по: <b>' . date('h:i d.m.y', $hostel->fetchColumn(1)) . '</b> <small>(' . timeOut($hostel->fetchColumn(1) - time()) . ')</small></p></div>';
$host = new Hostel();
echo '<table align="center" class="periods"><caption style="text-align: left;">Выберите срок предоплаты.</caption>
<tbody>
<tr class="caption"><th>Сутки</th><td title="7 дн.">7</td><td title="14 дн.">14</td><td title="21 дн.">21</td><td title="28 дн.">28</td></tr>
<tr class="value"><th>Сумма</th><td title="7 дн."><a href="?pays=1">' . $base[$hostel->fetchColumn(2)][0] . '</a></td><td title="14 дн."><a href="?pays=2">' . $base[$hostel->fetchColumn(2)][1] . '</a></td><td title="21 дн."><a href="?pays=3">' . $base[$hostel->fetchColumn(2)][2] . '</a></td><td title="28 дн."><a href="?pays=4">' . $base[$hostel->fetchColumn(2)][3] . '</a></td></tr>
</tbody>
</table>
<div style="color: red; font-size: 9px; padding-top: 3px;"><b>Внимание!</b> При расторжении договора или смене тарифа, внесенная плата не возвращается</div></fieldset></div>';
}
require_once 'views/hostel-checkpoint.php';

View File

@ -2,6 +2,7 @@
use Battles\Database\Db;
use Battles\InventoryItem;
use Battles\Models\Inventory;
use Battles\Template;
use Battles\User;
use Battles\UserInfo;
@ -29,7 +30,7 @@ function get_meshok(): object
function show_item($row, $txt, $place)
{
if (($row['maxdur'] <= $row['duration']) || ($row['dategoden'] && $row['dategoden'] <= time())) {
InventoryItem::destroyItem($row['id']);
Inventory::destroyItem($row['id'], User::getInstance()->getId());
}
$r = '';

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

View File

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@ -6,29 +6,4 @@ if ($_SESSION['uid']) {
header('Location: fight.php');
exit;
}
?>
<!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>
<h1>Демонстрационная версия</h1>
<div>
<p>Ребята, давайте сперва сделаем чтобы работало, а потом будем делать красиво. Идёт?</p>
<p>Пол персонажа выбирать нельзя. Это не ошибка. Все ограничения только для мальчиков или только для девочек
постепенно будут удалены.<br>
Любой человек может играть любым персонажем. Только его образ сможет показать кто перед вами. Мы живём в эпоху
толерантности, знаете ли! 😉</p>
<form method='post' action="enter.php">
Авторизация<br>
<input name='username' placeholder='Логин'>
<input name='password' placeholder='Пароль' type="password">
<br>
<input type=submit value='Войти в игру' class="button big">
</form>
</div>
<div class="button-group minor-group">
<a class="button" href="register.php">Зарегистрироваться</a>
<a class="button" href="rememberpassword.php">Восстановить пароль</a>
</div>
require_once 'views/index.html';

18
inf.php
View File

@ -1,17 +1,15 @@
<?php
use Battles\Models\PresentsModel;
use Battles\Template;
use Battles\UserInfo;
use Battles\{Template, User};
use Battles\Models\Presents;
include_once 'config.php';
$userInfo = new UserInfo(urldecode($_SERVER['QUERY_STRING']));
$presentsModel = new PresentsModel($userInfo->getId());
$presentsList = $presentsModel->getAllPresents();
Template::header('Информация о ' . $userInfo->getLogin());
if (!$userInfo->getId()) {
$presentsList = (new Presents())->getAll(User::getInstance($_SERVER['QUERY_STRING'])->getId());
Template::header('Информация о ' . User::getInstance($_SERVER['QUERY_STRING'])->getLogin());
if (!User::getInstance($_SERVER['QUERY_STRING'])->getId()) {
echo sprintf('Ошибка: персонаж <em>%s</em> не найден...<p><a style="color: #99f;" href="javascript:window.history.go(-1);">←назад</a></p>', urldecode($_SERVER['QUERY_STRING']));
exit;
}
$userInfo->showUserInfo();
include_once 'views/presents-list.php';
User::getInstance($_SERVER['QUERY_STRING'])->userInfo()->showUserInfo();
include_once 'views/inf-presents.php';

View File

@ -34,8 +34,6 @@ if ($user['battle'] > 0) {
echo "Персонаж под защитой от нападений ...";
} elseif(isset($effect['id'])) {
echo "Персонаж под защитой от нападений ...";
} elseif ($us['align']==2.99) {
echo "Не атакуйте Администратора!";
} elseif ($owntravma['id'] && !$us['battle']) {
echo "Персонаж тяжело травмирован...";
} elseif ($user['klan'] != '' && ($user['klan'] == $us['klan'])) {
@ -44,10 +42,6 @@ if ($user['battle'] > 0) {
echo "Персонаж в другой комнате!";
} elseif ($us['room'] == 31 || $us['room'] == 46 || $us['room'] == 47 || $us['room'] == 48 || $us['room'] == 49 ||$us['room'] == 600 || $us['room'] == 601 || $us['room'] == 45 || $us['room'] ==603 || $us['room'] == 602 || $us['room'] == 43 || $us['room'] ==45) {
echo "Нападения в этой локации запрещены!";
} elseif ($us['align'] == 2.9) {
echo "Нападение на Ангела строго запрещено!";
} elseif ($us['align'] == 4.99) {
echo "Нападение на Комментатора запрещено!";
} elseif ($us['level'] < 1) {
echo "Новички находятся под защитой Мироздателя!";
} elseif ($us['hp'] < $us['maxhp']*0.33 && !$us['battle']) {

Some files were not shown because too many files have changed in this diff Show More