game/_incl_data/class/Tournament/TournamentModel.php

357 lines
11 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

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

<?php
namespace Tournament;
use Chat;
use ChatMessage;
use Core\Db;
class TournamentModel
{
/**
* проверка уровня, стоимости эквипа, прочие проверки, что персонаж свободен
* таймер ожидания 30 минут
*
* @param int $uid
*
* @return int
*/
public static function getUserLevel(int $uid): int
{
$level = Db::getValue('select level from users where id = ? and level between 8 and 12 and battle = 0', [$uid]);
return $level ?: 0;
}
/**
* @param int $uid
* @param int|null $level
*
* @return bool
*/
public static function isEkrOverpriced(int $uid, ?int $level = null): bool
{
if (is_null($level)) {
$level = Db::getValue('select level from users where id = ?', [$uid]);
}
$wearedItemsEkrPrice = Db::getValue('select sum(2price) from items_users where inOdet > 0 and uid = ?', [$uid]);
return $wearedItemsEkrPrice > Tournament::ekrOverpriceFormula($level);
}
/**
* @param int $uid
*
* @return bool
*/
public static function isEnoughExperience(int $uid): bool
{
return Db::getValue('select exp from stats where id = ?', [$uid]) >= Tournament::MIN_EXP;
}
/**
* @param int $uid
*
* @return bool
*/
public static function isRestrictedToJoin(int $uid): bool
{
return Db::getValue('select count(*) from eff_users where uid = ? and id_eff = 486 and `delete` = 0', [$uid]);
}
/**
* @param int $tid
*
* @return bool
*/
public static function isStarted(int $tid): bool
{
return Db::getValue('select count(*) from tournaments where start_time = -1 and tid = ?', [$tid]);
}
/**
* Считаем сколько игроков ждут в заявке на турнир.
*
* @param int $tid
*
* @return int
*/
public static function getWaitingMembersQuantity(int $tid): int
{
return Db::getValue('select count(*) from tournaments_users where tid = ?', [$tid]);
}
/**
* Создание нового турнира.
*
* @param int $tid
*
* @return void
*/
public static function createTournament(int $tid): void
{
Db::sql('insert into tournaments (tid) values (?)', [$tid]);
}
/**
* Игрок присоединяется к турниру и телепортируется в турнирную комнату.
*
* @param int $uid
* @param int $tid
*
* @return void
*/
public static function joinTournament(int $uid, int $tid): void
{
/** Кастомные комнаты 25008 - 25012. */
$roomId = 25000 + $tid;
Db::sql('insert into tournaments_users (tid, uid) values (?, ?)', [$tid, $uid]);
self::teleport($uid, $roomId);
}
/**
* Старт турнира.
*
* @param int $tid
*
* @return void
*/
public static function startTournament(int $tid): void
{
Db::sql('update tournaments set start_time = -1 where tid = ?', [$tid]);
}
/**
* Чистим базы от прошедшего турнира.
*
* @param int $tid
*
* @return void
*/
public static function destroyTournament(int $tid): void
{
//Убедиться что в базе настроен foreign_keys и последует автоочистка tournaments_users !!!
Db::sql('delete from tournaments where tid = ?', [$tid]);
}
/**
* Получаем список бойцов и бьём их на пары. Возвращаем списки пар + 1 последний без пары если есть.
*
* @param array $fightersList
*
* @return array
*/
public static function getFightersTeams(array $fightersList): array
{
$query = sprintf("select id from users where battle = 0 and id in (%s)", implode(', ', $fightersList));
return array_chunk(Db::getColumn($query), 2);
}
/**
* Выбираем живых бойцов не сражающихся в данный момент.
*
* @param int $tid
*
* @return array
*/
public static function getFreeFighters(int $tid): array
{
return Db::getColumn(
'select uid from tournaments_users where tid = ? and death_time = 0 order by uid', [$tid]
);
}
/**
* Выбираем победителей. Смещаем массив, чтобы возврат шёл с единицы.
*
* @param int $tid
*
* @return array
*/
public static function getWinners(int $tid): array
{
$winners = Db::getColumn(
'select uid from tournaments_users where tid = ? order by death_time desc limit 3', [$tid]
);
return [
1 => $winners[0],
2 => $winners[1],
3 => $winners[2],
];
}
/**
* Пробуем выкусить проигравшего в последней турнирной битве и удалить эту самую битву во избежание.
* @return mixed
*/
public static function getLooser()
{
$query = '
select uid, battle
from
battle_users,
(select id, team_win
from battle
where
team_win > 0 and
typeBattle = 25000
order by time_over desc
limit 1) as last_battle
where
battle_users.battle = last_battle.id and
battle_users.team != last_battle.team_win and
battle_users.uid in (select uid from tournaments_users where death_time = 0)';
$query2 = 'select bu.uid from battle b
inner join battle_users bu on b.team_win != bu.team and b.id = bu.battle
inner join tournaments_users tu on bu.uid = tu.uid
where typeBattle = 25000 and death_time = 0 order by b.time_start desc limit 1';
$row = Db::getRow($query);
return $row['uid'] ?? 0;
}
/**
* Выбывший из турнира покидает комнату и получает время смерти.
*
* @param int $uid
* @param bool $winner
* @return void
*/
public static function removeFighter(int $uid, bool $winner = false): void
{
if (!$uid) {
return;
}
//$winner_timer_add = $winner? 500 : 0; # Последный ДОЛЖЕН быть последним.
Db::sql(
'update tournaments_users set death_time = unix_timestamp() + 500 where death_time = 0 and uid = ?', [$uid]
);
self::teleport($uid, 9);
//fixme: Классы не подключаются друг к другу. Нужно менять архитектуру игры. :(
Db::sql("update users_achiv set trn = trn + 1 where id = ?", [$uid]);
//(new Achievements(\user::start()))->updateCounter('trn');
}
/**
* Узнаём id турнира по id игрока.
*
* @param int $uid
*
* @return mixed
*/
public static function getTournamentIdByUserId(int $uid)
{
return Db::getValue('select tid from tournaments_users where uid = ?', [$uid]);
}
/**
* Попробуем стартонуть поединок.
* 25000 - Уникальный id поединка под турниры.
* noinc - запрет на вмешательство
* invis - невидимый бой
*
* @param int $uid1
* @param int $uid2
*
* @return void
*/
public static function startBattle(int $uid1, int $uid2): void
{
$check = Db::getValue('select count(*) from users where id in (?, ?) and battle = 0', [$uid1, $uid2]);
if ($check !== 2) {
return;
}
Db::exec(
'insert into battle (city, time_start, timeout, type, invis, noinc, travmChance, typeBattle)
values (\'capitalcity\', unix_timestamp(), 60, 0, 1, 1, 0, 25000)'
);
$bid = Db::lastInsertId(); // ВАЖНО!
Db::sql('update stats set team = 1, hpNow = hpAll, mpNow = mpAll where id = ?', [$uid1]);
Db::sql('update stats set team = 2, hpNow = hpAll, mpNow = mpAll where id = ?', [$uid2]);
Db::sql('update users set battle = ? where id in (?, ?)', [$bid, $uid1, $uid2]);
}
/**
* Узнаём логин персонажа по его id.
*
* @param int $uid
*
* @return mixed
*/
public static function uidToLogin(int $uid)
{
return Db::getValue('select login from users where id = ?', [$uid]);
}
/**
* Телепорт по комнатам.
*
* @param int $uid
* @param int $roomId
*
* @return void
*/
private static function teleport(int $uid, int $roomId): void
{
Db::sql('update users set room = ? where id = ?', [$roomId, $uid]);
}
/**
* Нет проверок $message потому что оно всегда задаётся в коде и игрок на него не влияет.
*
* @param string $message
*
* @return void
*/
public static function sysMessage(string $message): void
{
if (empty($message)) {
return;
}
$cmsg = new ChatMessage();
$cmsg->setDa(1);
$cmsg->setType(6);
$cmsg->setText($message);
$cmsg->setColor('forestgreen');
(new Chat())->sendMsg($cmsg);
}
/**
* Генерирует множественный запрос сразу на $quantity однотипных предметов в инвентарь пользователя $uid.
*
* @param int $uid
* @param int $quantity
*
* @return void
*/
public static function givePrizeItems(int $uid, int $quantity): void
{
return; //реликвии вывели из игры!
$query = 'insert into items_users (item_id, uid, data, iznosMAX, lastUPD, time_create)
values (4754, :uid, :data, 1, unix_timestamp(), unix_timestamp())';
$args = [
'uid' => $uid,
'data' => 'nosale=1|musor=1|sudba=' . self::uidToLogin($uid) . '|lvl=8|tr_s1=0|tr_s2=0|tr_s3=0|tr_s4=0',
];
$stmt = Db::prepare($query);
for ($i = 0; $i < $quantity; $i++) {
$stmt->execute($args);
}
}
/** Эффект-ограничитель на участие в турнире.
* @param int $uid
* @param int $unixtime
*
* @return void
*/
public static function giveDelay(int $uid, int $unixtime): void
{
$query = 'insert into eff_users (id_eff, uid, name, timeUse) VALUES (?,?,?,?)';
$args = [486, $uid, 'Призёр городского турнира!', $unixtime];
Db::sql($query, $args);
}
}