battles/functions.php

524 lines
19 KiB
PHP
Raw Normal View History

2018-01-28 16:40:49 +00:00
<?php
/**
* Copyright (c) 2018.
* Author: Igor Barkov <lopar.4ever@gmail.com>
* Project name: Battles-Game
*/
2022-06-10 23:18:04 +00:00
use Battles\Chat;
use Battles\Database\Db;
use Battles\DressedItems;
use Battles\InventoryItem;
use Battles\Travel;
use Battles\User;
use Battles\UserStats;
2018-01-28 16:40:49 +00:00
require_once 'config.php';
2021-08-26 16:15:47 +00:00
if (empty($_SESSION['uid'])) {
header("Location: index.php");
exit;
}
if (User::getInstance()->getBlock()) {
exit('user blocked!');
}
2020-06-23 15:13:20 +00:00
2022-02-12 12:25:43 +00:00
//Проверки на соответствие скрипта и комнаты, которые были натыканы по всем файлам.
2022-06-10 23:18:04 +00:00
Travel::roomRedirects(User::getInstance()->getRoom(), User::getInstance()->getBattle(), User::getInstance()->getInTower());
2022-02-12 12:25:43 +00:00
///*
// * Проверки на соответствие скрипта и комнаты, которые были натыканы по всем файлам.
// */
//$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;
//}
2022-06-10 23:18:04 +00:00
if (
!empty($_GET['goto']) &&
!empty($_GET['tStamp']) &&
!empty($_GET['vcode']) &&
$_GET['vcode'] == md5(sha1($_GET['goto'] . $_GET['tStamp']))
) {
$query = 'update users u, online o set u.room = ?, o.room = ? where user_id = id and user_id = ?';
Db::getInstance()->execute($query, [$_GET['goto'], $_GET['goto'], User::getInstance()->getId()]);
User::getInstance()->setRoom(intval($_GET['goto']));
2020-06-23 19:34:52 +00:00
}
2018-01-28 16:40:49 +00:00
2022-06-10 23:18:04 +00:00
function createbot($bot, $login = null)
2018-01-28 16:40:49 +00:00
{
2022-06-10 23:18:04 +00:00
if (!User::getInstance($bot)->getId()) {
2018-01-28 16:40:49 +00:00
return false;
}
2022-06-10 23:18:04 +00:00
$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];
2018-01-28 16:40:49 +00:00
}
2018-12-27 14:46:00 +00:00
$var_map = [
2018-01-28 16:40:49 +00:00
'cell_1' => 'Березовая роща', 'cell_2' => 'Березовая просека', 'cell_3' => 'Тёмный угол', 'cell_4' => 'Мрачная опушка',
'cell_5' => 'Тёмное урочище', 'cell_6' => 'Бурелом', 'cell_7' => 'Старая ива', 'cell_8' => 'Разнолесье',
'cell_9' => 'Сосновая тропа', 'cell_10' => 'Забытая дорога', 'cell_11' => 'Новая дорога', 'cell_12' => 'Мщаник',
'cell_13' => 'Ясная поляна', 'cell_14' => 'Заросший тракт', 'cell_15' => 'Смутный ельник', 'cell_16' => 'Сосновый бор',
'cell_17' => 'Тихоход', 'cell_18' => 'Сосновый гай', 'cell_19' => 'Смешаный лес', 'cell_20' => 'Темная поляна',
'cell_21' => 'Осенний угол', 'cell_22' => 'Грибное место', 'cell_23' => 'Опушка', 'cell_24' => 'Рыжий лес',
'cell_25' => 'Полесье',
2018-12-27 14:46:00 +00:00
];
2018-01-28 16:40:49 +00:00
const _BOTSEPARATOR_ = 10000000;
2018-01-28 16:40:49 +00:00
function savecavedata($cavedata, $caveleader, $floor)
{
$f1 = fopen("cavedata/$caveleader-$floor.dat", "wb+");
flock($f1, LOCK_EX);
fwrite($f1, serialize($cavedata));
flock($f1, LOCK_UN);
fclose($f1);
}
2020-06-23 20:24:15 +00:00
function GiveExp($id, $exp)
{
2022-06-10 23:18:04 +00:00
User::getInstance($id)->addExperience($exp);
2018-01-28 16:40:49 +00:00
}
2018-12-27 13:18:55 +00:00
/**
* Генератор прогрессбара.
2022-06-10 23:18:04 +00:00
* @param $current - Текущее значение.
* @param $maximum - Максимальное значение.
* @param string $line_color - Цвет полоски прогрессбара.
2022-06-10 23:18:04 +00:00
* @param string $bg_color - Фон прогрессбара.
* @return string
2018-12-27 13:18:55 +00:00
*/
function showProgressBar($current, $maximum, string $line_color = 'limegreen', string $bg_color = 'silver'): string
2018-12-27 12:59:45 +00:00
{
2018-12-27 23:13:46 +00:00
$bar = round($current / $maximum * 100);
2020-06-23 20:24:15 +00:00
return <<<HTML
2018-12-27 23:13:46 +00:00
<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>
2018-12-27 12:59:45 +00:00
</div>
2018-12-27 13:18:55 +00:00
<div style="width: 100%; height: 16px; font-size: 14px; text-align: center; margin-top: -16px;">
2018-12-27 23:13:46 +00:00
$current / $maximum
2018-12-27 12:59:45 +00:00
</div>
2018-12-27 13:18:55 +00:00
HTML;
2018-12-27 12:59:45 +00:00
}
/**
* Функция отображает слот для свитков в окне персонажа.
*
* @param $slot
*
* @throws \Krugozor\Database\Mysql\Exception
*/
2018-01-28 16:40:49 +00:00
function echoscroll($slot)
{
$all_magic = 0;
if (User::getInstance()->getBattle()) {
2018-01-28 16:40:49 +00:00
$script = 'fbattle';
$bat = db::c()->query('SELECT `magic` FROM `battle` WHERE `id` = ?i', User::getInstance()->getBattle())->fetch_assoc();
2018-03-08 22:30:57 +00:00
$all_magic = unserialize($bat['magic']);
} else {
$script = 'main';
2018-03-08 22:30:57 +00:00
}
$dress = db::c()->query('SELECT `id`, `magic`, `name`, `img`, `duration`, `maxdur` FROM `inventory` WHERE `id` = ?i', User::getInstance()->$slot)->fetch_assoc();
2018-03-08 22:14:29 +00:00
$need_charge = db::c()->query('SELECT `needcharge` FROM `magic` WHERE `id` = ?i', $dress['magic'])->fetch_assoc();
2018-03-08 22:30:57 +00:00
if ((User::getInstance()->$slot > 0) && ($all_magic[User::getInstance()->getId()] < 1 || empty($need_charge['needcharge']))) {
$row['id'] = User::getInstance()->$slot;
2018-01-28 16:40:49 +00:00
if ($dress['magic']) {
$magic = db::c()->query('SELECT targeted FROM `magic` WHERE `id` = ?i', $dress['magic'])->fetch_assoc();
2018-01-28 16:40:49 +00:00
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'); ";
} else {
echo "if(confirm('Использовать сейчас?')) { window.location='" . $script . ".php?use=" . $row['id'] . "';}";
}
echo "\"href='#'>";
}
echo <<<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
<img src="i/sh/magicclock.gif" width="40" height="25" title='Произведите размен ударами и магия снова станет доступна' alt="Свиток">
INACTIVE_SCROLL;
2018-01-28 16:40:49 +00:00
} else {
echo <<<EMPTY_SLOT
<img class="tooltip" src="i/w13.gif" width="40" height="25" title='<b>Пустой слот магия</b>' alt="Слот для свитка">
EMPTY_SLOT;
2018-01-28 16:40:49 +00:00
}
}
// ссылка на магию
2022-06-10 23:18:04 +00:00
function showhrefmagic(array $dress): string
2018-01-28 16:40:49 +00:00
{
2022-06-10 23:18:04 +00:00
$magic = new Battles\Magic\Magic(Db::getInstance(), $dress['includemagic']);
2018-12-27 16:13:40 +00:00
2018-01-28 16:40:49 +00:00
$r = '';
2022-06-10 23:18:04 +00:00
$script = User::getInstance()->getBattle() ? 'fbattle' : 'main';
2018-01-28 16:40:49 +00:00
$r .= "<a onclick=\"";
2022-06-10 23:18:04 +00:00
if ($magic->getMagic()->targeted == 1) {
2018-01-28 16:40:49 +00:00
$r .= "okno('Введите название предмета', '{$script}.php?use={$dress['id']}', 'target')";
2022-06-10 23:18:04 +00:00
} elseif ($magic->getMagic()->targeted == 2) {
$r .= "findlogin('" . $magic->getMagic()->name . "', '{$script}.php?use={$dress['id']}', 'target')";
2018-01-28 16:40:49 +00:00
} 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>";
2018-01-28 16:40:49 +00:00
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;
}
2018-03-01 10:57:27 +00:00
/**
* @param $time
* @param $vars
* @param $vls
* @param $uid
2018-12-27 14:46:00 +00:00
*
2018-03-01 10:57:27 +00:00
* @return bool
*/
2018-01-28 16:40:49 +00:00
function addActions($time, $vars, $vls, $uid)
{
2018-03-01 10:57:27 +00:00
db::c()->query('LOCK TABLES `actions` WRITE');
2021-03-10 21:26:53 +00:00
$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);
2018-03-01 10:57:27 +00:00
db::c()->query('UNLOCK TABLES');
2020-06-23 20:24:15 +00:00
return $ins;
2018-01-28 16:40:49 +00:00
}
// использовать магию
function usemagic($id, $target)
2018-01-28 16:40:49 +00:00
{
$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();
2018-01-28 16:40:49 +00:00
$all_magic = unserialize($bat['magic']);
$charge = 0;
2020-06-23 19:10:00 +00:00
$magic = db::c()->query('SELECT * FROM `magic` WHERE `id` = ?i', $row['magic'])->fetch_assoc_array();
2018-01-28 16:40:49 +00:00
if ($magic['needcharge'] > 0) {
$charge = $magic['needcharge'];
}
2020-06-23 19:10:00 +00:00
$incmagic = db::c()->query('SELECT * FROM `magic` WHERE `id` = ?i', $row['includemagic'])->fetch_assoc_array();
2018-01-28 16:40:49 +00:00
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'] &&
2020-06-23 20:24:15 +00:00
(($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'] &&
2020-06-23 20:24:15 +00:00
($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
2020-06-23 20:24:15 +00:00
) || $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;
2018-01-28 16:40:49 +00:00
}
2020-06-23 20:24:15 +00:00
$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']);
2020-06-23 20:24:15 +00:00
} else {
if (!$row['magic']) {
$query = 'update inventory set includemagicdex = includemagicdex - ? where item_id = ?';
2018-01-28 16:40:49 +00:00
} else {
$query = 'update inventory set durability = durability + ? where item_id = ?';
2018-01-28 16:40:49 +00:00
}
Db::getInstance()->execute($query, [$bat, $row['id']]);
2018-01-28 16:40:49 +00:00
}
2020-06-23 20:24:15 +00:00
if (!$charge) {
$charge = 0;
}
//ограничение по кол-ву за ход
if (User::getInstance()->getBattle()) {
$batMagic = Db::getInstance()->fetchColumn('select magic from battle where battle_id = ?', User::getInstance()->getBattle());
2020-06-23 20:24:15 +00:00
}
if (empty($batMagic)) {
2020-06-23 20:24:15 +00:00
$all_magic = [];
} else {
$all_magic = unserialize($batMagic);
2020-06-23 20:24:15 +00:00
}
$all_magic[User::getInstance()->getId()] += $charge;
Db::getInstance()->execute('update battle set magic = ? where battle_id = ?', [serialize($all_magic), User::getInstance()->getBattle()]);
2018-01-28 16:40:49 +00:00
}
2020-06-23 19:10:00 +00:00
}
2020-06-23 20:24:15 +00:00
return false;
2018-01-28 16:40:49 +00:00
}
/* ВАЖНО! (#44)
* addch() и addchp() заменяются на Chat::class->sendSys($message, [optional]$receiver);
* Для addchp() используется второй опциональный ключ.
* Это 150+ вхождений в куче файлов, где надо менять структуру вызова функции из-за их несовместимости.
* Возможно, приоритетом стоит сделать унификацию свитков нападения, которых самих около 20 и которые
* по нескольку раз вызывают эти функции.
*/
2018-01-28 16:40:49 +00:00
function addch($text, $room = 0)
{
2022-06-10 23:18:04 +00:00
Chat::sendSys($text);
2018-01-28 16:40:49 +00:00
}
function addchp($text, $who, $room = 0)
{
2022-06-10 23:18:04 +00:00
Chat::sendSys($text, $who);
2018-01-28 16:40:49 +00:00
}
function err($t)
{
echo '<span class="error">' . $t . '</span>';
2018-01-28 16:40:49 +00:00
}
function SolveExp($at_id, $def_id, $damage): float
2018-01-28 16:40:49 +00:00
{
$mods = [
'bloodb' => 1.2,
'btl_1' => 1,
'btl_2' => 0.5,
'btl_3' => 0.05,
];
$baseexp = [
"0" => "2",
"1" => "5",
"2" => "10",
"3" => "15",
"4" => "30",
"5" => "60",
"6" => "90",
"7" => "115",
"8" => "300",
"9" => "400",
"10" => "500",
"11" => "600",
"12" => "700",
"13" => "800",
"14" => "900",
"15" => "1000",
"16" => "1100",
"17" => "1200",
"18" => "1300",
"19" => "1400",
"20" => "1500",
"21" => "1600",
];
2018-12-10 20:16:42 +00:00
$expmf = 0;
$bot_active = false;
$bot_def = false;
2018-01-28 16:40:49 +00:00
if ($at_id > _BOTSEPARATOR_) {
$at_id = Db::getInstance()->fetchColumn('select prototype from bots where bot_id = ?', $at_id);
2018-01-28 16:40:49 +00:00
$bot_active = true;
}
$query = 'select greatest(1, sum(price)) as allprice from users left join inventory on users.id = inventory.owner_id where id = ?';
$atAllPrice = Db::getInstance()->fetchColumn($query, $at_id);
$defAllPrice = Db::getInstance()->fetchColumn($query, $def_id);
2018-01-28 16:40:49 +00:00
$atInfo = new UserStats($at_id);
$defInfo = new UserStats($def_id);
$table_name = $at_id > _BOTSEPARATOR_ ? 'bots' : 'users';
$bt = Db::getInstance()->ofetch('select blood, type, t1, t2 from battle where battle_id = (select battle from ? where id = ?)', [$table_name, $at_id]);
2018-01-28 16:40:49 +00:00
if ($def_id > _BOTSEPARATOR_) {
$def_id = Db::getInstance()->fetchColumn('select prototype from bots where bot_id = ?', $def_id);
2018-01-28 16:40:49 +00:00
$bot_def = true;
}
if ($bt->blood) {
2018-02-27 02:48:51 +00:00
$expmf = $mods['bloodb'];
2018-01-28 16:40:49 +00:00
}
$filebtl = '/tmp/' . $at_id . '.btl';
if ($bt->type == 1 && file_exists($filebtl)) {
2018-01-28 16:40:49 +00:00
$btfl = fopen($filebtl, 'r');
$contents = fread($btfl, filesize($filebtl));
fclose($btfl);
$cnt = substr_count($contents, $def_id);
$exmod = 1;
if ($cnt <= 1) {
$exmod = $mods['btl_1'];
} elseif ($cnt == 2) {
$exmod = $mods['btl_2'];
} elseif ($cnt > 2) {
$exmod = $mods['btl_3'];
}
$expmf = $expmf * $exmod;
}
2018-02-27 02:48:51 +00:00
$standart = [
"0" => 1,
"1" => 1,
"2" => 15,
"3" => 111,
"4" => 265,
"5" => 526,
"6" => 882,
"7" => 919,
"8" => 919,
"9" => 919,
"10" => 919,
"11" => 919,
"12" => 919,
"13" => 919,
"14" => 919,
"15" => 919,
"16" => 919,
"17" => 919,
"18" => 919,
"19" => 919,
"20" => 919,
"21" => 919,
"22" => 919,
"23" => 919,
"24" => 919,
"25" => 919
];
$mfit = ($atAllPrice / ($standart[$atInfo->getLevel()] / 3));
2018-01-28 16:40:49 +00:00
if ($mfit < 0.8) {
$mfit = 0.8;
}
if ($mfit > 1.5) {
$mfit = 1.5;
}
$pls = count(explode(";", $bt->t1)) + count(explode(";", $bt->t2));
2018-01-28 16:40:49 +00:00
if ($pls > 2) {
2020-06-23 20:24:15 +00:00
$mfbot = $bot_active ? 0.3 : 1;
$mfbot2 = $bot_def ? 0.7 : 1;
2018-01-28 16:40:49 +00:00
} else {
$mfbot = 1;
$mfbot2 = 1;
}
if ($expmf == 0) {
$expmf = 1;
}
2020-06-23 20:24:15 +00:00
return round((($baseexp[$defInfo->getLevel()]) * ($defAllPrice / (($atAllPrice + $defAllPrice) / 2)) * ($damage / $defInfo->getMaxHealth()) * $expmf * $mfit * $mfbot * $mfbot2) / 3);
}