Вход Регистрация
Файл: pages/combat/ursa.php
Строк: 380
<?php
// Physical module map v50.6: public URL stays clean while code lives in /pages.
if (!defined('GAME_ROOT')) define('GAME_ROOT'dirname(__DIR__2));
chdir(GAME_ROOT);
if (
PHP_SAPI !== 'cli') { $_SERVER['PHP_SELF']='/ursa.php'$_SERVER['SCRIPT_NAME']='/ursa.php'; }

require_once 
'./system/common.php';
require_once 
'./system/functions.php';
require_once 
'./system/user.php';
if(!
$user){ header('Location:/'); exit; }
$title='Олимп';
$uid=(int)$user['id'];

/** Keep the legacy Olimp battle table compatible with the PHP 8.4 battle renderer. */
function ursa_bootstrap_schema(): void {
    static 
$done=false; if($done) return; $done=true;
    
$ver=function_exists('game_meta_get')?(int)game_meta_get('ursa_schema','0'):0;
    if(
$ver>=3) return;
    
db_query("CREATE TABLE IF NOT EXISTS `boiarena` (
      `id` int unsigned NOT NULL,
      `id_vrag` int NOT NULL DEFAULT 0,
      `hp` bigint unsigned NOT NULL DEFAULT 1,
      `hp_max` bigint unsigned NOT NULL DEFAULT 1,
      `hp_vrag` bigint unsigned NOT NULL DEFAULT 1,
      `hp_vrag_max` bigint unsigned NOT NULL DEFAULT 1,
      `login` varchar(80) NOT NULL DEFAULT 'Гладиатор',
      `att` bigint unsigned NOT NULL DEFAULT 1,
      `deff` bigint unsigned NOT NULL DEFAULT 0,
      `time` int unsigned NOT NULL DEFAULT 0,
      `user_att` bigint unsigned NOT NULL DEFAULT 1,
      `user_deff` bigint unsigned NOT NULL DEFAULT 0,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"
);
    
$defs=[
      
'id_vrag'=>'int NOT NULL DEFAULT 0','hp'=>'bigint unsigned NOT NULL DEFAULT 1','hp_max'=>'bigint unsigned NOT NULL DEFAULT 1',
      
'hp_vrag'=>'bigint unsigned NOT NULL DEFAULT 1','hp_vrag_max'=>'bigint unsigned NOT NULL DEFAULT 1','login'=>"varchar(80) NOT NULL DEFAULT 'Гладиатор'",
      
'att'=>'bigint unsigned NOT NULL DEFAULT 1','deff'=>'bigint unsigned NOT NULL DEFAULT 0','time'=>'int unsigned NOT NULL DEFAULT 0',
      
'user_att'=>'bigint unsigned NOT NULL DEFAULT 1','user_deff'=>'bigint unsigned NOT NULL DEFAULT 0'
    
];
    foreach(
$defs as $col=>$def){
        
$has=db_fetch_one("SHOW COLUMNS FROM `boiarena` LIKE '".db_real_escape_string($col)."'");
        if(!
$hasdb_query("ALTER TABLE `boiarena` ADD COLUMN `{$col}{$def}");
    }
    
// Old installations used SMALLINT and overflowed real HP/parameters.
    
foreach(['hp','hp_max','hp_vrag','hp_vrag_max','att','deff','user_att','user_deff'] as $col){
        
db_query("ALTER TABLE `boiarena` MODIFY COLUMN `{$col}` bigint unsigned NOT NULL DEFAULT ".(in_array($col,['deff','user_deff'],true)?'0':'1'));
    }
    
// boiarena is transient. Old partial rows cannot be reconstructed reliably after adding columns.
    
db_query('DELETE FROM `boiarena`');
    if(
function_exists('game_meta_set')) game_meta_set('ursa_schema','3');
}
ursa_bootstrap_schema();
function 
ursa_avatar(array $ubool $battle=false): string {
    
$sex=((int)($u['sex']??0)===1)?1:0$items=[];
    for(
$slot=1;$slot<=8;$slot++){
        
$invId=(int)($u['w_'.$slot]??0); $itemId=0;
        if(
$invId>0){ $r=db_fetch_assoc(db_query('SELECT `item` FROM `inv` WHERE `id`='.$invId.' AND `user`='.(int)($u['id']??0).' LIMIT 1')); $itemId=(int)($r['item']??0); }
        
$items[]=$itemId;
    }
    return 
'/'.($battle?'manekenImage2':'manekenImage').'/'.$sex.'/'.implode('/',$items).'/';
}
function 
ursa_calc_hp(array $u): int { return max(10, (int)($u['vit']??1) * 2); }
function 
ursa_make_enemy(array $user): array {
    
$uid=(int)$user['id']; $lvl=(int)$user['level'];
    if(
random_int(1,100)<=42){
        
$names=['Берсерк Урсы','Ледяной страж','Клык Олимпа','Теневой гладиатор','Каменный воин','Северный хищник'];
        
$scale=random_int(92,115)/100;
        return [
'id'=>0,'login'=>$names[array_rand($names)],'level'=>$lvl,'sex'=>random_int(0,1),'vit'=>max(30,(int)round((int)$user['vit']*$scale)),'str'=>max(18,(int)round((int)$user['str']*$scale)),'def'=>max(12,(int)round((int)$user['def']*$scale))];
    }
    
$min=max(1,$lvl-2); $max=$lvl+2;
    
$r=db_fetch_assoc(db_query('SELECT `id`,`login`,`level`,`sex`,`vit`,`str`,`def`,`w_1`,`w_2`,`w_3`,`w_4`,`w_5`,`w_6`,`w_7`,`w_8` FROM `users` WHERE `id`<>'.$uid.' AND `level` BETWEEN '.$min.' AND '.$max.' ORDER BY RAND() LIMIT 1'));
    return 
$r ?: ['id'=>0,'login'=>'Гладиатор Урсы','level'=>$lvl,'sex'=>1,'vit'=>max(25,(int)$user['vit']),'str'=>max(15,(int)$user['str']),'def'=>max(10,(int)$user['def'])];
}
function 
ursa_create_battle(array $user): array {
    
$uid=(int)$user['id']; $enemy=ursa_make_enemy($user);
    
$hpCurrent=max(1,min(ursa_calc_hp($user),(int)($user['hp']??ursa_calc_hp($user)))); $hpMax=ursa_calc_hp($user); $ehp=ursa_calc_hp($enemy);
    
db_query('DELETE FROM `boiarena` WHERE `id`='.$uid);
    
$name=db_real_escape_string((string)$enemy['login']);
    
db_query("INSERT INTO `boiarena` (`id`,`id_vrag`,`hp`,`hp_max`,`hp_vrag`,`hp_vrag_max`,`login`,`att`,`deff`,`time`,`user_att`,`user_deff`) VALUES (".$uid.",".(int)$enemy['id'].",".$hpCurrent.",".$hpMax.",".$ehp.",".$ehp.",'".$name."',".max(1,(int)$enemy['str']).",".max(0,(int)$enemy['def']).",0,".max(1,(int)$user['str']).",".max(0,(int)$user['def']).")");
    return 
db_fetch_assoc(db_query('SELECT * FROM `boiarena` WHERE `id`='.$uid.' LIMIT 1')) ?: [];
}
function 
ursa_finish(array $user,array $battle,array $anim): array {
    
$uid=(int)$user['id']; $won=(int)($battle['hp_vrag']??1)<=0$oppLevel=(int)$user['level'];
    if((int)(
$battle['id_vrag']??0)>0){ $o=db_fetch_assoc(db_query('SELECT `level` FROM `users` WHERE `id`='.(int)($battle['id_vrag']??0).' LIMIT 1')); $oppLevel=max(1,(int)($o['level']??$oppLevel)); }
    
$valor=$won 1;
    
$exp=$won $oppLevel*random_int(25,35)+(int)($user['alex_arena']??0) : $oppLevel*random_int(12,18);
    
$silver=$won $oppLevel*random_int(25,45)+(int)($user['alex_arena']??0) : $oppLevel*random_int(10,25);
    
db_execute('UPDATE `users` SET `ar_boi`=GREATEST(`ar_boi`-1,0),`exp`=`exp`+:e,`s`=`s`+:s,`alex_dobl`=`alex_dobl`+:v,`hp`=:hp WHERE `id`=:u',['e'=>$exp,'s'=>$silver,'v'=>$valor,'hp'=>max(1,(int)($battle['hp']??1)),'u'=>$uid]);
    if(!empty(
$GLOBALS['clan']['id'])){ @db_query('UPDATE `clan_memb` SET `exp`=`exp`+'.(int)$exp.' WHERE `user`='.$uid); @db_query('UPDATE `clans` SET `exp`=`exp`+'.(int)$exp.' WHERE `id`='.(int)$GLOBALS['clan']['id']); }
    
db_query('DELETE FROM `boiarena` WHERE `id`='.$uid);
    return [
'won'=>$won,'exp'=>$exp,'silver'=>$silver,'valor'=>$valor,'my_damage'=>(int)$anim['u'],'enemy_damage'=>(int)$anim['v'],'my_hp_left'=>(int)($battle['hp']??0),'enemy_hp_left'=>(int)($battle['hp_vrag']??0)];
}
$battle=db_fetch_assoc(db_query('SELECT * FROM `boiarena` WHERE `id`='.$uid.' LIMIT 1')) ?: [];
$requiredBattleKeys=['id_vrag','hp','hp_max','hp_vrag','hp_vrag_max','login','att','deff','user_att','user_deff'];
foreach(
$requiredBattleKeys as $requiredKey){ if(!array_key_exists($requiredKey,$battle)){ $battle=[]; break; } }
if((
$_SERVER['REQUEST_METHOD']??'GET')==='POST' && isset($_POST['ursa_attack'])){
    
security_require_csrf();
    if((int)(
$user['ar_boi']??0)<1){ $_SESSION['err']='Бои закончились. Восстановите попытки.'header('Location:/olimp/'); exit; }
    if(!
$battle$battle=ursa_create_battle($user);
    if(
$battle){
        
$base=max(6,(int)floor((((int)($battle['user_att']??1)-((int)($battle['deff']??0)/5))/6)));
        
$baseV=max(6,(int)floor((((int)($battle['att']??1)-((int)($battle['user_deff']??0)/5))/6)));
        
$dmg=max(1,random_int(max(1,(int)floor($base*.75)),max(1,$base)));
        
$dmgV=max(1,random_int(max(1,(int)floor($baseV*.75)),max(1,$baseV)));
        
$dmg=min($dmg,(int)($battle['hp_vrag']??1)); $dmgV=min($dmgV,(int)($battle['hp']??1));
        
db_query('UPDATE `boiarena` SET `hp`=GREATEST(`hp`-'.(int)$dmgV.',0),`hp_vrag`=GREATEST(`hp_vrag`-'.(int)$dmg.',0) WHERE `id`='.$uid);
        
$battle=db_fetch_assoc(db_query('SELECT * FROM `boiarena` WHERE `id`='.$uid.' LIMIT 1')) ?: [];
        
$anim=['u'=>$dmg,'v'=>$dmgV]; $_SESSION['ursa_anim']=$anim;
        if(
$battle && ((int)($battle['hp']??1)<=|| (int)($battle['hp_vrag']??1)<=0)) $_SESSION['ursa_result']=ursa_finish($user,$battle,$anim);
    }
    
header('Location:/olimp/'); exit;
}
if(isset(
$_POST['ursa_restore'])){ security_require_csrf(); if((int)($user['g']??0)<15){ $_SESSION['err']='Нужно 15 золота для восстановления боёв.'header('Location:/olimp/'); exit; } db_query('UPDATE `users` SET `ar_time`=0,`ar_boi`=5,`g`=`g`-15 WHERE `id`='.$uid.' AND `g`>=15'); $_SESSION['ok']='Бои восстановлены.'header('Location:/olimp/'); exit; }
if(!
$battle && (int)($user['ar_boi']??0)>0$battle=ursa_create_battle($user);
$result=$_SESSION['ursa_result']??null; unset($_SESSION['ursa_result']); $anim=$_SESSION['ursa_anim']??null; unset($_SESSION['ursa_anim']);
require 
'./system/h.php';
echo 
'<div class="title">Олимп</div><div class="center blue">Сражайся с игроками и стражами Олимпа. На экране всегда показаны реальные текущие значения здоровья, нанесённый урон и награда.</div>';
if(
$result){
    
$fresh=db_fetch_assoc(db_query('SELECT `lvl_dobl`,`alex_dobl`,`ar_boi` FROM `users` WHERE `id`='.$uid.' LIMIT 1')) ?: ['lvl_dobl'=>$user['lvl_dobl']??0,'alex_dobl'=>$user['alex_dobl']??0,'ar_boi'=>$user['ar_boi']??0];
    echo 
'<div class="ursa-v45 ursa-result"><div class="big '.($result['won']?'green':'red').'">'.($result['won']?'⚔ Победа! ⚔':'☠ Поражение ☠').'</div><div class="mini-line"></div>';
    echo 
'<div>Вы нанесли: <span class="green">-'.$result['my_damage'].'</span> HP · Получили: <span class="red">-'.$result['enemy_damage'].'</span> HP</div>';
    echo 
'<div>Ваше здоровье после боя: <b>'.(int)$result['my_hp_left'].'</b> · Здоровье соперника: <b>'.(int)$result['enemy_hp_left'].'</b></div>';
    echo 
'<div class="mini-line"></div><div>Награда: <img src="/images/icon/silver.png" alt=""> '.(int)$result['silver'].' серебра &nbsp; <img src="/images/icon/exp.png" alt=""> '.(int)$result['exp'].' опыта &nbsp; <img src="/images/icon/valor.png" alt=""> +'.(int)$result['valor'].' доблести</div>';
    echo 
'<div class="blue">Текущий уровень доблести: '.(int)$fresh['lvl_dobl'].' · Очков до следующего уровня: '.max(0,400-(int)$fresh['alex_dobl']).'</div>';
    echo 
'<div class="block item_center"><a class="btn" href="/olimp/">Следующий бой</a></div></div>'; require './system/f.php'; exit;
}
if((int)(
$user['ar_boi']??0)<1){ echo '<div class="block item_center">Вы устали. Бои закончились.<form method="post" action="/olimp/">'.security_csrf_field().'<button class="btn" type="submit" name="ursa_restore" value="1">Восстановить бои за 15 золота</button></form></div>'; require './system/f.php'; exit; }
if(!
$battle){ echo '<div class="error">Не удалось подобрать соперника.</div>'; require './system/f.php'; exit; }
$enemy=['id'=>(int)($battle['id_vrag']??0),'login'=>(string)($battle['login']??'Гладиатор'),'sex'=>1];
if((int)(
$battle['id_vrag']??0)>0){ $real=db_fetch_assoc(db_query('SELECT `id`,`login`,`sex`,`w_1`,`w_2`,`w_3`,`w_4`,`w_5`,`w_6`,`w_7`,`w_8` FROM `users` WHERE `id`='.(int)($battle['id_vrag']??0).' LIMIT 1')); if($real)$enemy=$real; }
$userAvatar=ursa_avatar($user,true); $enemyAvatar=ursa_avatar($enemy,true);
$uhp=max(0,(int)($battle['hp']??1)); $uhpm=max(1,(int)($battle['hp_max']??1)); $ehp=max(0,(int)($battle['hp_vrag']??1)); $ehpm=max(1,(int)($battle['hp_vrag_max']??1));
$up=min(100,(int)round($uhp/$uhpm*100)); $ep=min(100,(int)round($ehp/$ehpm*100));
$animU=$anim?' attack':''$animE=$anim?' hit':'';
echo 
'<div class="ursa-v45"><div class="ursa-fighters">';
echo 
'<div class="ursa-fighter'.$animU.'"><div class="ursa-name">Вы</div><div class="ursa-hp"><span style="width:'.$up.'%"></span></div><img src="'.security_html($userAvatar).'" alt="Ваш персонаж"><div class="ursa-stats">⚔ '.(int)($battle['user_att']??1).' &nbsp; 🛡 '.(int)($battle['user_deff']??0).'<br>❤ '.$uhp.' / '.$uhpm.'</div>'.($anim?'<div class="ursa-damage">-'.$anim['v'].'</div>':'').'</div>';
echo 
'<div class="ursa-fighter'.$animE.'"><div class="ursa-name">'.security_html((string)($battle['login']??'Гладиатор')).'</div><div class="ursa-hp"><span style="width:'.$ep.'%"></span></div><img src="'.security_html($enemyAvatar).'" alt="Соперник"><div class="ursa-stats">⚔ '.(int)($battle['att']??1).' &nbsp; 🛡 '.(int)($battle['deff']??0).'<br>❤ '.$ehp.' / '.$ehpm.'</div>'.($anim?'<div class="ursa-damage">-'.$anim['u'].'</div>':'').'</div>';
echo 
'</div><div class="ursa-actions"><div class="gray">Осталось боёв: '.(int)$user['ar_boi'].' · Доблесть: '.(int)($user['lvl_dobl']??0).' ур. / '.(int)($user['alex_dobl']??0).' оч.</div><form method="post" action="/olimp/">'.security_csrf_field().'<button class="btn" type="submit" name="ursa_attack" value="1">Атаковать</button></form></div></div>';
require 
'./system/f.php';
Онлайн: 2
Реклама