332 lines
14 KiB
PHP
332 lines
14 KiB
PHP
<?php
|
||
|
||
namespace Magic;
|
||
|
||
use Chat;
|
||
use ChatMessage;
|
||
use Core\Config;
|
||
use Core\Db;
|
||
use Insallah\Math;
|
||
use Magic;
|
||
use User;
|
||
|
||
class Attack
|
||
{
|
||
|
||
private Magic $magic;
|
||
private int $pigAnimalBonus = 0;
|
||
|
||
public function __construct(Magic $magic)
|
||
{
|
||
$this->magic = $magic;
|
||
}
|
||
|
||
public function atackUser($uid1, $uid2, $tm, $btl, $addExp = 0, $type = 0)
|
||
{
|
||
global $u;
|
||
$attacker = User::getInfo($uid1);
|
||
$target = User::getInfo($uid2);
|
||
|
||
$battleTest = Db::getRow('select * from battle where id = ? and team_win = -1');
|
||
|
||
$good = 0;
|
||
$error = '';
|
||
|
||
if (
|
||
self::isMonster($target) &&
|
||
(
|
||
$target['level'] == 9 && $attacker['level'] > 9 ||
|
||
$target['level'] == 10 && ($attacker['level'] < 10 || $attacker['level'] > 11)
|
||
)
|
||
) {
|
||
$error = 'Нельзя нападать на монстра этого уровня!';
|
||
} elseif (self::isMonster($target) && User\Effects::hasAttackTimeLimit($attacker['id'])) {
|
||
$error = 'Нельзя нападать на монстра чаще одного раза в 3 часа!';
|
||
} elseif (User\Effects::isImmuneToAttack($target['id'])) {
|
||
$error = 'Персонаж имеет защиту от нападения!';
|
||
} elseif ($target['level'] == 8 && !self::isMonster($target) && self::canAttack8Level(
|
||
$attacker['id'], $target['id']
|
||
)) {
|
||
$error = 'На 8-е уровни нападать нельзя.';
|
||
} elseif ($attacker['level'] != $target['level'] && !self::isMonster($target)) {
|
||
$error = 'Нападать можно на персонажей только своего уровня!!!';
|
||
} elseif (isset($battleTest['id']) && $battleTest['noatack'] > 0) {
|
||
$error = 'Поединок защищен магией! Вы не можете вмешаться!';
|
||
} elseif ($target['level'] < 8) {
|
||
$error = 'Новички находятся под защитой Мироздателя...';
|
||
} elseif ($attacker['level'] < 8) {
|
||
$error = 'Тренируйтесь вам пока еще рано...';
|
||
} elseif ($target['admin'] == 1 && $attacker['admin'] == 0) {
|
||
$error = 'Уважайте хранителей...';
|
||
} elseif ($this->magic->testTravma($uid2, 3)) {
|
||
$error = 'Противник тяжело травмирован, нельзя напасть!';
|
||
} elseif ($this->magic->testTravma($uid1, 2)) {
|
||
$error = 'Вы травмированы, нельзя напасть!';
|
||
} elseif ($target['clan'] != 0 && ($target['clan'] == $attacker['clan']) && $attacker['admin'] == 0) {
|
||
$error = 'Чтите честь ваших сокланов.';
|
||
} elseif ($btl != 0 && $battleTest['smert'] == 1 && $type != 222) {
|
||
$error = 'Вы не можете вмешаться в этот кровавый поединок!';
|
||
} elseif ($btl == 0) {
|
||
$s01 = $u->getStats($uid1, 0);
|
||
if ($s01['hpNow'] < floor($s01['hpAll'] / 100 * 33)) {
|
||
$error = 'Нельзя напасть, у противника не восстановилось здоровье';
|
||
} else {
|
||
$addExp += $target['bbexp'];
|
||
//effect ненападения
|
||
if (self::isMonster($target)) {
|
||
User\Effects::giveAttackImmunity($attacker['id']);
|
||
}
|
||
|
||
//тут клан вар
|
||
|
||
//************
|
||
//нападаем на персонажа
|
||
//===Удаление защиты от нападения в результате нападения пользователем
|
||
User\Effects::removeByIds($attacker['id'], 479, 480, 481);
|
||
//=======
|
||
if ($type == 222) {
|
||
$battleId = self::battleInit($attacker, $target, 99, $addExp, true, 1);
|
||
} elseif (self::haveClanWar($attacker['clan'], $target['clan'])) {
|
||
$battleId = self::battleInit($attacker, $target, 250, $addExp, true);
|
||
} else {
|
||
$battleId = self::battleInit($attacker, $target, $type, $addExp);
|
||
}
|
||
|
||
if ($battleId > 0) {
|
||
//
|
||
$s01 = self::updateHpAndMp($s01);
|
||
$s02 = $u->getStats($uid2, 0);
|
||
$s02 = self::updateHpAndMp($s02);
|
||
|
||
Db::sql('update users set battle = ? where id in (?,?)', [$uid1, $uid2]);
|
||
$sql = 'update stats set lider = ?, tactic7 = ?, hpNow = ?, mpNow = ?, team = ? where id = ?';
|
||
Db::sql($sql, [
|
||
$battleId,
|
||
$s01['tactic7'],
|
||
$s01['hpNow'],
|
||
$s01['mpNow'],
|
||
1,
|
||
$uid1,
|
||
]);
|
||
Db::sql($sql, [
|
||
$battleId,
|
||
$s02['tactic7'],
|
||
$s02['hpNow'],
|
||
$s02['mpNow'],
|
||
2,
|
||
$uid2,
|
||
]);
|
||
unset($sql);
|
||
|
||
$good = $battleId;
|
||
}
|
||
}
|
||
} elseif (isset($battleTest['id']) && $battleTest['type'] == 500 && $target['team'] == 1) {
|
||
$error = 'Нельзя сражаться на стороне монстров!';
|
||
} elseif (isset($battleTest['id']) && $battleTest['type'] == 250 && $attacker['clan'] != $battleTest['clan1'] && $attacker['clan'] != $battleTest['clan2']) {
|
||
$error = 'Нельзя попасть в клановые бои - если вы неявляетесь представителем данных кланов!!!';
|
||
} elseif (isset($battleTest['id']) && $battleTest['invis'] > 0) {
|
||
$error = 'Нельзя вмешиваться в невидимый бой!';
|
||
} elseif ($battleTest['noatack'] > 0) {
|
||
$error = 'В этот поединок нельзя вмешиваться!';
|
||
} else {
|
||
|
||
//вмешиваемся в бой
|
||
//effect ненападения
|
||
if (self::isMonster($target)) {
|
||
User\Effects::giveAttackImmunity($attacker['id']);
|
||
}
|
||
|
||
Db::sql('update users set battle = ? where id = ?', [$btl, $uid1]);
|
||
|
||
$uid1st = $u->getStats($uid1);
|
||
$uid1u = User::getInfo($uid1);
|
||
|
||
if ($uid1u['level'] <= 7) {
|
||
$uid1st['tactic7'] = floor((10 + $uid1st['s7']) / $uid1st['hpAll'] * $uid1st['hpNow']);
|
||
} elseif ($uid1u['level'] == 8) {
|
||
$uid1st['tactic7'] = floor((20 + $uid1st['s7']) / $uid1st['hpAll'] * $uid1st['hpNow']);
|
||
} elseif ($uid1u['level'] == 9) {
|
||
$uid1st['tactic7'] = floor((30 + $uid1st['s7']) / $uid1st['hpAll'] * $uid1st['hpNow']);
|
||
} elseif ($uid1u['level'] >= 10) {
|
||
$uid1st['tactic7'] = floor((40 + $uid1st['s7']) / $uid1st['hpAll'] * $uid1st['hpNow']);
|
||
} else {
|
||
$uid1st['tactic7'] = floor((10 + $uid1st['s7']) / $uid1st['hpAll'] * $uid1st['hpNow']);
|
||
}
|
||
|
||
//Духовность, спасение
|
||
if ($uid1st['s7'] > 49) {
|
||
User\Effects::addSpasenie($uid1st['id']);
|
||
}
|
||
|
||
$btxt = '';
|
||
if ($uid1u['align'] > 0) {
|
||
$btxt = $btxt . '<img src=' . Config::img() . '/i/align/align' . $uid1u['align'] . '.gif >';
|
||
}
|
||
if ($uid1u['align2'] > 0) {
|
||
$btxt = $btxt . '<img src=' . Config::img() . '/i/align/align' . $uid1u['align2'] . '.gif >';
|
||
}
|
||
if ($uid1u['clan'] > 0) {
|
||
$btxt = $btxt . '<img src=' . Config::img() . '/i/clan/' . $uid1u['clan'] . '.gif >';
|
||
}
|
||
$btxt = $btxt . '<b>{u1}</b>[' . $uid1u['level'] . ']<a href=info/' . $uid1u['id'] . ' target=_blank ><img src=' . Config::img() . '/i/inf_capitalcity.gif alt=""></a>';
|
||
if ($uid1u['sex'] == 1) {
|
||
$btxt = $btxt . ' вмешалась в поединок.';
|
||
} else {
|
||
$btxt = $btxt . ' вмешался в поединок.';
|
||
}
|
||
|
||
$lastHOD = Db::getRow('select id, id_hod, type from battle_logs where battle = ? order by id_hod desc limit 1');
|
||
|
||
if (isset($lastHOD['id'])) {
|
||
$idHod = $lastHOD['id_hod'];
|
||
if ($lastHOD['type'] != 6) {
|
||
$idHod++;
|
||
}
|
||
|
||
Db::sql('insert into battle_logs (time, battle, id_hod, text, vars, zona1, zonb1, zona2, zonb2, type) values (unix_timestamp(),?,?,?,?,?,?,?,?,6)', [
|
||
$btl,
|
||
$idHod,
|
||
"{tm1} $btxt",
|
||
"login1={$uid1st['login']}||t1={$uid1st['team']}||login2={$uid1st['login']}||t2={$uid1st['team']}||time=" . time(),
|
||
"",
|
||
"",
|
||
"",
|
||
"",
|
||
]);
|
||
}
|
||
|
||
// Бафф Зверя animal_bonus ---------------------------------
|
||
$this->setAnimalBonus($attacker);
|
||
User::start()->info['hpNow'] += $this->pigAnimalBonus;
|
||
// Бафф Зверя animal_bonus ---------------------------------
|
||
|
||
$ltm = [1 => 2, 2 => 1];
|
||
Db::sql('update stats set hpNow = ?, hpAll = ?, team = ?, tactic7 = ? where id = ?', [$uid1st['hpNow'], $uid1st['mpNow'], $ltm[$tm], (int)$uid1st['tactic7'], $uid1]);
|
||
$good = $btl;
|
||
unset($uid1st);
|
||
}
|
||
$u->error = $error;
|
||
return $good;
|
||
}
|
||
|
||
private static function isMonster(array $target): bool
|
||
{
|
||
return $target['no_ip'] === 'trupojor';
|
||
}
|
||
|
||
private static function canAttack8Level($attacker, $target): bool
|
||
{
|
||
$aSum = User\ItemsModel::getDressedEkrTotalPrice($attacker);
|
||
$tRange = Math::get20PercentRange(User\ItemsModel::getDressedEkrTotalPrice($target));
|
||
|
||
return $aSum >= $tRange['min'] && $aSum <= $tRange['max'];
|
||
}
|
||
|
||
private static function battleInit(array $attacker, array $defender, int $type, float $addExp, bool $isClanWar = false, $smert = 0): int
|
||
{
|
||
$fighters = "{$attacker['login']},{$defender['login']}";
|
||
$clan1 = 0;
|
||
$clan2 = 0;
|
||
if ($isClanWar) {
|
||
$clan1 = $attacker['clan'];
|
||
$clan2 = $defender['clan'];
|
||
}
|
||
$sql = 'insert into battle (city, time_start, players, timeout, type, travmChance, typeBattle, addExp, clan1, clan2, smert) values (?,unix_timestamp(),?,60 * ?,?,50,9,?,?,?,?)';
|
||
$args = ['capitalcity', $fighters, mt_rand(1, 3), $type, $addExp, $clan1, $clan2, $smert];
|
||
|
||
Db::sql($sql, $args);
|
||
return (int)Db::lastInsertId();
|
||
}
|
||
|
||
private static function haveClanWar(int $clan1, int $clan2): bool
|
||
{
|
||
$listStr = "$clan1, $clan2";
|
||
return Db::getValue('select count(*) from clan_wars where clan1 in (?) and clan2 in (?) and clan1 != clan2', [$listStr, $listStr]) > 0;
|
||
}
|
||
|
||
/**
|
||
* Обновляем НР и МР игрокам.
|
||
* @param array $userStats
|
||
* @return array
|
||
*/
|
||
private static function updateHpAndMp(array $userStats): array
|
||
{
|
||
if ($userStats['level'] <= 7) {
|
||
$userStats['tactic7'] = floor(10 / $userStats['hpAll'] * $userStats['hpNow']);
|
||
} elseif ($userStats['level'] == 8) {
|
||
$userStats['tactic7'] = floor(20 / $userStats['hpAll'] * $userStats['hpNow']);
|
||
} elseif ($userStats['level'] == 9) {
|
||
$userStats['tactic7'] = floor(30 / $userStats['hpAll'] * $userStats['hpNow']);
|
||
} elseif ($userStats['level'] >= 10) {
|
||
$userStats['tactic7'] = floor(40 / $userStats['hpAll'] * $userStats['hpNow']);
|
||
}
|
||
return $userStats;
|
||
}
|
||
|
||
private function setAnimalBonus(array $owner)
|
||
{
|
||
if ($owner['animal'] < 1) {
|
||
return;
|
||
}
|
||
$animal = Db::getRow('select * from users_animal where uid = ? and id = ? and pet_in_cage = 0', [$owner['id'], $owner['animal']]);
|
||
|
||
if (!$animal) {
|
||
return;
|
||
}
|
||
|
||
if ($animal['eda'] < 1) {
|
||
$cmsg = new ChatMessage();
|
||
$cmsg->setRoom($owner['room']);
|
||
$cmsg->setTo($owner['login']);
|
||
$cmsg->setText('<strong>' . $animal['name'] . '</strong> нуждается в еде...');
|
||
$cmsg->setType(6);
|
||
(new Chat())->sendMsg($cmsg);
|
||
return;
|
||
}
|
||
|
||
$animalBonus = Db::getValue('select bonus from levels_animal where type = ? and level = ?', [$animal['type'], $animal['level']]);
|
||
|
||
$statusName = [
|
||
1 => ['cat', 'Кошачья Ловкость'],
|
||
2 => ['owl', 'Интуиция Совы'],
|
||
3 => ['wisp', 'Сила Стихий'],
|
||
4 => ['demon', 'Демоническая Сила'],
|
||
5 => ['dog', 'Друг'],
|
||
6 => ['pig', 'Полная Броня'],
|
||
7 => ['dragon', 'Инферно'],
|
||
];
|
||
|
||
User\Effects::removeByOverType($owner['id'], 100);
|
||
User\Effects::addCustom([
|
||
'v2' => 201,
|
||
'img2' => "summon_pet_{$statusName[$animal['type']][0]}.gif",
|
||
'id_eff' => 22,
|
||
'uid' => $owner['id'],
|
||
'name' => "{$statusName[$animal['type']][1]}[{$animal['level']}]",
|
||
'data' => $animalBonus,
|
||
'overType' => 100,
|
||
'timeUse' => 77,
|
||
'v1' => 'priem',
|
||
'user_use' => $owner['id'],
|
||
]);
|
||
|
||
if ($animal['type'] == 6) {
|
||
if ($animal['level'] == 1 || $animal['level'] == 2 || $animal['level'] == 3) {
|
||
$this->pigAnimalBonus = 50;
|
||
} elseif ($animal['level'] == 4) {
|
||
$this->pigAnimalBonus = 75;
|
||
} elseif ($animal['level'] == 5 || $animal['level'] == 6) {
|
||
$this->pigAnimalBonus = 125;
|
||
} elseif ($animal['level'] == 7 || $animal['level'] == 8) {
|
||
$this->pigAnimalBonus = 150;
|
||
} elseif ($animal['level'] == 9) {
|
||
$this->pigAnimalBonus = 200;
|
||
} elseif ($animal['level'] == 10) {
|
||
$this->pigAnimalBonus = 300;
|
||
}
|
||
Db::sql('update stats set hpNow = hpNow + ? where id = ?', [$this->pigAnimalBonus, $owner['id']]);
|
||
}
|
||
}
|
||
}
|