battle->atacks[$this->id]['uid1']; $uid2 = $this->battle->atacks[$this->id]['uid2']; $stats1 = $this->battle->stats[$this->battle->uids[$uid1]]; $stats2 = $this->battle->stats[$this->battle->uids[$uid2]]; if ($stats1['yhod'] > 0) { $uid1 = $this->battle->yhod_user($uid2, $uid1, $stats1['yhod']); } elseif ($stats2['yhod'] > 0) { $uid2 = $this->battle->yhod_user($uid1, $uid2, $stats2['yhod']); } $this->uid1 = $uid1; $this->uid2 = $uid2; $this->attackerStats = $this->battle->stats[$this->battle->uids[$uid1]]; $this->targetStats = $this->battle->stats[$this->battle->uids[$uid2]]; # Переменные - Моё почтение! # $this->stats[$this->uids[$this->yhod_user($this->atacks[$this->id]['uid2'], $this->atacks[$this->id]['uid1'], $this->stats[$this->uids[$this->atacks[$this->id]['uid1']]]['yhod'])]]; # $this->battle->stats[$this->battle->uids[$this->battle->yhod_user($this->battle->atacks[$this->id]['uid2'], $this->battle->atacks[$this->id]['uid1'], $this->battle->stats[$this->battle->uids[$this->battle->atacks[$this->id]['uid1']]]['yhod'])]]; } private function updateBattleStats(): void { $this->battle->stats[$this->battle->uids[$this->uid1]] = $this->attackerStats; $this->battle->stats[$this->battle->uids[$this->uid2]] = $this->targetStats; } /** * Расчет парирования Цели (uid2) от Атакующего (uid1) * @param int $counterstrikecheck * @param bool $pat * @param int $loopstart * @return void */ public function parry(int $counterstrikecheck = 0, bool $pat = false, int $loopstart = 0): void { if ($pat) { $tempAt = $this->at; $this->at = $tempAt['p']; } if ($loopstart > 0) { $loopstart--; } if (is_array($this->at[1]['atack'])) { for ($j = $loopstart; $j < count($this->at[1]['atack']) && $j < 8; $j++) { if ( !empty($this->targetStats['no_pr1']) || $this->at[1]['atack'][$j][2] != $counterstrikecheck || $this->mfs(__FUNCTION__, [1 => $this->targetStats['m7'], 2 => $this->attackerStats['m7'],]) != 1 || $this->battle->atacks[$this->id]['out2'] != 0 ) { continue; } if (!empty($this->attackerStats['nopryh']) || $this->attackerStats['nopryh_act'] > 0) { continue; } // Парировал $this->attackerStats['nopryh'] = (int)floor($this->attackerStats['nopryh']); $this->at[1]['atack'][$j][1] = 6; $this->attackerStats['nopryh']--; $this->attackerStats['nopryh_act']++; } } if (is_array($this->at[2]['atack'])) { for ($j = $loopstart; $j < count($this->at[2]['atack']) && $j < 8; $j++) { if ( !empty($this->attackerStats['no_pr1']) || $this->at[2]['atack'][$j][2] != $counterstrikecheck || $this->mfs(__FUNCTION__, [1 => $this->attackerStats['m7'], 2 => $this->targetStats['m7'],]) != 1 || $this->battle->atacks[$this->id]['out1'] != 0 ) { continue; } if (!empty($this->targetStats['nopryh']) || $this->targetStats['nopryh_act'] > 0) { continue; } // Парировал $this->targetStats['nopryh'] = (int)floor($this->targetStats['nopryh']); $this->at[2]['atack'][$j][1] = 6; $this->targetStats['nopryh']--; $this->targetStats['nopryh_act']++; } } if (isset($tempAt)) { $tempAt['p'] = $this->at; $this->at = $tempAt; } $this->updateBattleStats(); } /** * Расчет блока щитом Цели (uid2) от Атакующего (uid1) * @param int $counterstrikecheck * @param bool $pat * @return void */ public function blockByShield(int $counterstrikecheck = 0, bool $pat = false): void { if ($pat) { $tempAt = $this->at; $this->at = $tempAt['p']; } //m8 блок щитом, m18 абсолютный блок щитом if ($this->targetStats['shield1'] > 0) { for ($j = 0; $j < count($this->at[1]['atack']) && $j < 8; $j++) { if ( $this->at[1]['atack'][$j][2] != $counterstrikecheck || $this->battle->atacks[$this->id]['out2'] != 0 || $this->mfs(__FUNCTION__, $this->targetStats['m8'] / 2 + $this->targetStats['m18']) != 1 ) { continue; } $this->at[1]['atack'][$j][1] = 7; } } if ($this->attackerStats['shield1'] > 0) { for ($j = 0; $j < count($this->at[2]['atack']) && $j < 8; $j++) { if ( $this->at[2]['atack'][$j][2] != $counterstrikecheck || $this->battle->atacks[$this->id]['out1'] != 0 || $this->mfs(__FUNCTION__, $this->attackerStats['m8'] / 2 + $this->attackerStats['m18']) != 1 ) { continue; } $this->at[2]['atack'][$j][1] = 7; } } if (isset($tempAt)) { $tempAt['p'] = $this->at; $this->at = $tempAt; } $this->updateBattleStats(); } /** * Расчет крита Атакующего (uid1) по Цели (uid2) * @param bool $pat * @param int $loopstart * @return void */ public function criticalDamage(bool $pat = false, int $loopstart = 0): void { if ($pat) { $tempAt = $this->at; $this->at = $tempAt['p']; } if ($loopstart > 0) { $loopstart--; } $checkhand = false; if (is_array($this->at[1]['atack'])) { for ($j = $loopstart; $j < count($this->at[1]['atack']) && $j < 8; $j++) { [$data, $checkhand] = $this->getDataArrayByHand($checkhand, $this->attackerStats); if ($this->mfs(__FUNCTION__, ['mf' => $this->attackerStats['m1'] + $data['sv_m1'], 'amf' => $this->attackerStats['m14'], 'smf' => $this->targetStats['m2']]) != 1) { continue; } $this->at[1]['atack'][$j][1] = match (true) { $this->at[1]['atack'][$j][1] == 3 => 4, //в блок !in_array($this->at[1]['atack'][$j][1], [2, 6, 7, 8]) => 5, //обычный крит default => 1 // а ты что такое? }; } } if (is_array($this->at[2]['atack'])) { for ($j = $loopstart; $j < count($this->at[2]['atack']) && $j < 8; $j++) { [$data, $checkhand] = $this->getDataArrayByHand($checkhand, $this->targetStats); if ($this->mfs(__FUNCTION__, ['mf' => $this->targetStats['m1'] + $data['sv_m1'], 'amf' => $this->targetStats['m14'], 'smf' => $this->attackerStats['m2']]) != 1) { continue; } $this->at[2]['atack'][$j][1] = match (true) { $this->at[2]['atack'][$j][1] == 3 => 4, //в блок !in_array($this->at[2]['atack'][$j][1], [2, 6, 7, 8]) => 5, //обычный крит default => 1 // а ты что такое? }; } } if (isset($tempAt)) { $tempAt['p'] = $this->at; $this->at = $tempAt; } $this->updateBattleStats(); } /** * Расчет уворота Цели (uid2) от Атакующего (uid1) * @param int $counterstrikecheck * @param bool $pat * @param int $loopstart * @return void */ public function evasion(int $counterstrikecheck = 0, bool $pat = false, int $loopstart = 0): void { if ($pat) { $tempAt = $this->at; $this->at = $tempAt['p']; } if ($loopstart > 0) { $loopstart--; } $checkhand = false; if (is_array($this->at[1]['atack'])) { for ($j = $loopstart; $j < count($this->at[1]['atack']) && $j < 8; $j++) { [$data, $checkhand] = $this->getDataArrayByHand($checkhand, $this->attackerStats); if ( $this->at[1]['atack'][$j][2] != $counterstrikecheck || $this->battle->atacks[$this->id]['out2'] != 0 || $this->mfs( __FUNCTION__, [ 'mf' => $this->targetStats['m4'], 'amf' => $this->targetStats['m15'], 'smf' => $this->attackerStats['m5'] + $data['sv_m5'], 'asmf' => $this->attackerStats['m21'], ] ) != 1 ) { continue; } $this->attackerStats['nopryh'] = (int)floor($this->attackerStats['nopryh']); if (!isset($this->attackerStats['nopryh']) || $this->attackerStats['nopryh'] < 1) { $this->at[1]['atack'][$j][1] = 2; } else { $this->attackerStats['nopryh']--; $this->attackerStats['nopryh_act']++; } } } if (is_array($this->at[2]['atack'])) { for ($j = $loopstart; $j < count($this->at[2]['atack']) && $j < 8; $j++) { [$data, $checkhand] = $this->getDataArrayByHand($checkhand, $this->targetStats); if ( $this->at[2]['atack'][$j][2] != $counterstrikecheck || $this->battle->atacks[$this->id]['out1'] != 0 || $this->mfs( __FUNCTION__, [ 'mf' => $this->attackerStats['m4'], 'amf' => $this->attackerStats['m15'], 'smf' => $this->targetStats['m5'] + $data['sv_m5'], 'asmf' => $this->targetStats['m21'], ] ) != 1 ) { continue; } $this->targetStats['nopryh'] = (int)floor($this->targetStats['nopryh']); if (!isset($this->targetStats['nopryh']) || $this->targetStats['nopryh'] < 1) { $this->at[2]['atack'][$j][1] = 2; } else { $this->targetStats['nopryh']--; $this->targetStats['nopryh_act']++; } } } if (isset($tempAt)) { $tempAt['p'] = $this->at; $this->at = $tempAt; } $this->updateBattleStats(); } /** * Расчет контрудара Цели (uid2) по Атакующему (uid1) * @param int $counterstrikecheck * @return void */ public function counterstrike(int $counterstrikecheck = 0): void //terrorists win! { if (is_array($this->at[1]['atack'])) { for ($j = 0; $j < count($this->at[1]['atack']) && $j < 8; $j++) { if ( $this->at[1]['atack'][$j][1] != 2 || $this->at[1]['atack'][$j][2] != $counterstrikecheck || $this->mfs(__FUNCTION__, ['a' => $this->targetStats['m6'], 'b' => $this->attackerStats['m6']]) != 1 ) { continue; } $this->at[1]['atack'][$j][1] = 8; $rand = mt_rand(1, 5); if ($this->battle->testRazmenblock1($this->id, $this->uid2, $this->uid1)) { $this->at[2]['atack'][] = [$rand, 3, 0, 1]; } else { $this->at[2]['atack'][] = [$rand, 1, 0, 1]; // 3 , 0 , 1 } $this->counterstrikehit(count($this->at[2]['atack'])); } } if (is_array($this->at[2]['atack'])) { for ($j = 0; $j < count($this->at[2]['atack']) && $j < 8; $j++) { if ( $this->at[2]['atack'][$j][1] != 2 || $this->at[2]['atack'][$j][2] != $counterstrikecheck || $this->mfs(__FUNCTION__, ['a' => $this->attackerStats['m6'], 'b' => $this->targetStats['m6']]) != 1 ) { continue; } $this->at[2]['atack'][$j][1] = 8; $rand = mt_rand(1, 5); if ($this->battle->testRazmenblock1($this->id, $this->uid1, $this->uid2)) { $this->at[1]['atack'][] = [$rand, 3, 0, 1]; } else { $this->at[1]['atack'][] = [$rand, 1, 0, 1]; // 3 , 0 , 1 } $this->counterstrikehit(count($this->at[1]['atack'])); } } $this->updateBattleStats(); } /** * Рассчёт урона. * @param bool $pat * @param int $loopstart * @return void */ public function damage(bool $pat = false, int $loopstart = 0): void { $yhod = [1 => 0, 0]; if ($this->battle->stats[$this->battle->uids[$this->uid1]]['yhod'] > 0) { $yhod = [1 => 1, 0]; } elseif ($this->battle->stats[$this->battle->uids[$this->uid2]]['yhod'] > 0) { $yhod = [1 => 0, 1]; } if ($pat) { $tempAt = $this->at; $this->at = $tempAt['p']; } if ($loopstart > 0) { $loopstart--; } $checkhand = false; if (is_array($this->at[1]['atack'])) { for ($j = $loopstart; $j < count($this->at[1]['atack']) && $j < 8; $j++) { [$data, $checkhand, $wp, $witm] = $this->getDataArrayByHand($checkhand, $this->attackerStats); $this->at[1]['atack'][$j]['wt'] = $witm['type']; $this->at[1]['atack'][$j]['yhod'] = $yhod[1]; if ( !isset($this->at[1]['atack'][$j]['yron']) && in_array($this->at[1]['atack'][$j][1], [1, 4, 5]) ) { $type = 'yron'; } else { $type = 'block'; } $this->at[1]['atack'][$j][$type] = $this->battle->yronGetrazmen($this->uid2, $this->uid1, $witm); if ($this->at[1]['atack'][$j][1] == 4) { $this->at[1]['atack'][$j][$type]['y_old'] = $this->at[1]['atack'][$j][$type]['y']; $this->at[1]['atack'][$j][$type]['y'] = (int)round($this->at[1]['atack'][$j][$type]['k'] / 2); } elseif ($this->at[1]['atack'][$j][1] == 5) { $this->at[1]['atack'][$j][$type]['y_old'] = $this->at[1]['atack'][$j][$type]['y']; $this->at[1]['atack'][$j][$type]['y'] = $this->at[1]['atack'][$j][$type]['k']; } $this->at[1]['atack'][$j][$type]['2h'] = $data['2h']; $this->at[1]['atack'][$j][$type]['w'] = $wp; if ($this->at[1]['atack'][$j][$type]['y'] > 0) { $this->at[1]['atack'][$j][$type]['r'] = '-' . $this->at[1]['atack'][$j][$type]['y']; } else { $this->at[1]['atack'][$j][$type]['r'] = '--'; } } } if (is_array($this->at[2]['atack'])) { for ($j = $loopstart; $j < count($this->at[2]['atack']) && $j < 8; $j++) { [$data, $checkhand, $wp, $witm] = $this->getDataArrayByHand($checkhand, $this->targetStats); $this->at[2]['atack'][$j]['wt'] = $witm['type']; $this->at[2]['atack'][$j]['yhod'] = $yhod[1]; if ( !isset($this->at[2]['atack'][$j]['yron']) && in_array($this->at[2]['atack'][$j][1], [1, 4, 5]) ) { $type = 'yron'; } else { $type = 'block'; } $this->at[2]['atack'][$j][$type] = $this->battle->yronGetrazmen($this->uid1, $this->uid2, $witm); if ($this->at[2]['atack'][$j][1] == 4) { $this->at[2]['atack'][$j][$type]['y_old'] = $this->at[2]['atack'][$j][$type]['y']; $this->at[2]['atack'][$j][$type]['y'] = (int)round($this->at[2]['atack'][$j][$type]['k'] / 2); } elseif ($this->at[2]['atack'][$j][1] == 5) { $this->at[2]['atack'][$j][$type]['y_old'] = $this->at[2]['atack'][$j][$type]['y']; $this->at[2]['atack'][$j][$type]['y'] = $this->at[2]['atack'][$j][$type]['k']; } $this->at[2]['atack'][$j][$type]['2h'] = $data['2h']; $this->at[2]['atack'][$j][$type]['w'] = $wp; if ($this->at[2]['atack'][$j][$type]['y'] > 0) { $this->at[2]['atack'][$j][$type]['r'] = '-' . $this->at[2]['atack'][$j][$type]['y']; } else { $this->at[2]['atack'][$j][$type]['r'] = '--'; } } } if (isset($tempAt)) { $tempAt['p'] = $this->at; $this->at = $tempAt; } $this->updateBattleStats(); } /** * Возвращает массив: * * 0 => data предмета в зависимости от руки в которой тот находится, * * 1 => флажок проверки руки, * * 2 => число слота руки(?!), * * 3 => массив параметров предмета для Battle::class->yronGetrazmen() * @param bool $check * @param array $stats * @return array{array,bool,int,array} */ private function getDataArrayByHand(bool $check, array $stats): array { if (!$check && isset($stats['wp3id'])) { //Левая рука $wp = 3; $check = true; } else { //Правая рука if (isset($stats['wp14id']) && $stats['items'][$stats['wp14id']]['type'] != 13) { $wp = 14; } else { $wp = 3; } $check = false; } $witm = $stats['items'][$stats["wp{$wp}id"]]; return [Conversion::dataStringToArray($witm['data']), $check, $wp, $witm]; } private function mfs(int|string $type, array|int $mf): int { if (is_array($mf)) { $mf = array_map(fn($a) => max($a, 0), $mf); } $rval = 0; if ($type == 'criticalDamage') { //Крит if ($mf['mf'] > $mf['smf']) { $rval = 100 - floor(((($mf['smf']) / ($mf['mf'] + 1)) * 100)); } $rval = Comparsion::minimax($rval, 0, 75); if ($mf['amf'] > 0) { $mf['amf'] = min(100, $mf['amf']); if (($mf['amf'] * 100) >= mt_rand(1, 10000)) { $rval = 100; } } } elseif ($type == 'evasion') { if ($mf['mf'] > $mf['smf']) { $rval = 100 - floor(((($mf['smf']) / ($mf['mf'] + 1)) * 100)); //2.5 } $rval = Comparsion::minimax($rval, 0, 75); if ($mf['asmf'] > 0) { $mf['asmf'] = min(100, $mf['asmf']); if ($mf['asmf'] >= mt_rand(1, 100)) { $rval = 0; } } if ($mf['amf'] >= 0) { $mf['amf'] = min(100, $mf['amf']); if ($mf['amf'] >= mt_rand(1, 100)) { $rval = 100; } } } elseif ($type == 'parry') { $mf[1] = max($mf[1], 1); $mf[2] = max($mf[2], 1); $rval = $mf[1] - $mf[2] / 2; $rval = Comparsion::minimax($rval, 1, 75); } elseif ($type == 4) { $mf = round($mf * 0.6); $mf = Comparsion::minimax($mf, 0, 100); $rval = min($mf, 100); //пробой брони } elseif ($type == 'blockByShield') { $mf = max($mf, 0); $rval = min($mf, 85); //блок щитом } elseif ($type == 'counterstrike') { //Контрудар if ($mf['a'] > 0) { if ($mf['b'] > 0) { $rval = round($mf['a'] - ($mf['b'] / 2)); } else { $rval = $mf['a']; } } $rval = Comparsion::minimax($rval, 0, 75); } return Helper::getChanse($rval) ? 1 : 0; } /** * Повторный просчёт всего для успешного контрудара. * @param int $loopstart * @return void */ private function counterstrikehit(int $loopstart): void { $this->evasion(1, true, $loopstart); $this->parry(1, true, $loopstart); $this->blockByShield(1, true); $this->criticalDamage(true, $loopstart); $this->damage(true, $loopstart); } public function getAt(): array { return $this->at; } }