Вход Регистрация
Файл: pages/economy/rings.php
Строк: 725
<?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']='/rings.php'$_SERVER['SCRIPT_NAME']='/rings.php'; }

include 
'./system/common.php';
include 
'./system/functions.php';
include 
'./system/user.php';
include 
'./system/menu.php';
if(empty(
$user['id'])){ header('Location:/'); exit; }

$uid=(int)$user['id'];
$viewUid=(int)($_GET['user']??$uid);
if(
$viewUid<=0$viewUid=$uid;
$canManage=$viewUid===$uid;
game_ring_normalize_user_slots($viewUid);

$redirectRing = static function(int $slot,string $manage='') use ($uid): never {
    
$url='/rings/?slot='.max(1,min(3,$slot));
    if(
$manage!==''$url.='&manage='.rawurlencode($manage);
    
header('Location:'.$url);
    exit;
};

if(
$_SERVER['REQUEST_METHOD']==='POST'){
    
security_require_csrf();
    if(!
$canManage){ http_response_code(403); exit('Недостаточно прав.'); }

    
$rid=(int)($_POST['ring_id']??0);
    
$act=(string)($_POST['act']??'');
    
$ring=db_fetch_assoc(db_query('SELECT * FROM `ring_catalog` WHERE `id`='.$rid.' LIMIT 1'));
    if(!
$ring){ $_SESSION['err']='Кольцо не найдено.'header('Location:/rings/'); exit; }

    
$owned=db_fetch_assoc(db_query('SELECT * FROM `user_rings` WHERE `user`='.$uid.' AND `ring_id`='.$rid.' LIMIT 1'));
    
$slot=game_ring_slot_for_catalog($ring);

    try{
        if(
$act==='buy'){
            if(
$owned) throw new RuntimeException('Это кольцо уже куплено.');
            
$price=max(0,(int)$ring['price']);
            
db_pdo()->beginTransaction();
            
$pay=db_prepare(
                
'UPDATE `users` SET `g`=`g`-:price WHERE `id`=:uid AND `g`>=:min_price',
                [
'price'=>$price,'uid'=>$uid,'min_price'=>$price]
            );
            if(
$pay->rowCount()<1) throw new RuntimeException('Недостаточно золота.');
            
db_execute('UPDATE `user_rings` SET `slot`=0 WHERE `user`=:uid AND `slot`=:slot',['uid'=>$uid,'slot'=>$slot]);
            
db_execute(
                
'INSERT INTO `user_rings` (`user`,`ring_id`,`slot`,`level`,`rune`,`bonus`,`stars`,`smith`) VALUES (:uid,:rid,:slot,1,0,0,0,0)',
                [
'uid'=>$uid,'rid'=>$rid,'slot'=>$slot]
            );
            
db_pdo()->commit();
            
$_SESSION['ok']='Кольцо куплено и установлено.';
            
$redirectRing($slot);
        }

        if(!
$owned) throw new RuntimeException('Сначала купите это кольцо.');

        if(
$act==='upgrade'){
            
$level=max(1,(int)$owned['level']);
            if(
$level>=80) throw new RuntimeException('Кольцо уже максимально прокачано.');
            
$cost=(int)$ring['price']+250*$level;
            
db_pdo()->beginTransaction();
            
$pay=db_prepare(
                
'UPDATE `users` SET `g`=`g`-:cost WHERE `id`=:uid AND `g`>=:min_cost',
                [
'cost'=>$cost,'uid'=>$uid,'min_cost'=>$cost]
            );
            if(
$pay->rowCount()<1) throw new RuntimeException('Недостаточно золота.');
            
$up=db_prepare(
                
'UPDATE `user_rings` SET `level`=`level`+1 WHERE `user`=:uid AND `ring_id`=:rid AND `level`=:old_level',
                [
'uid'=>$uid,'rid'=>$rid,'old_level'=>$level]
            );
            if(
$up->rowCount()<1) throw new RuntimeException('Кольцо уже изменилось. Обновите страницу.');
            
db_pdo()->commit();
            
$_SESSION['ok']='Уровень кольца повышен до '.($level+1).'.';
            
$redirectRing($slot);
        }

        if(
$act==='ring_rune'){
            
$target=max(1,min(6,(int)($_POST['rune']??0)));
            
$values=game_ring_rune_values();
            
$costs=game_ring_rune_costs();
            
$current=max(0,min(6,(int)($owned['rune']??0)));
            if(
$target<=$current) throw new RuntimeException('Выберите руну качеством выше текущей.');
            
$cost=game_ring_discounted_cost((int)$costs[$target],3);
            
$delta=(int)$values[$target]-(int)$values[$current];
            
$stat=game_ring_rune_stat((string)$ring['kind']);

            
db_pdo()->beginTransaction();
            
$pay=db_prepare(
                
'UPDATE `users` SET `g`=`g`-:cost WHERE `id`=:uid AND `g`>=:min_cost',
                [
'cost'=>$cost,'uid'=>$uid,'min_cost'=>$cost]
            );
            if(
$pay->rowCount()<1) throw new RuntimeException('Недостаточно золота для руны.');
            
$up=db_prepare(
                
'UPDATE `user_rings` SET `rune`=:new_rune WHERE `user`=:uid AND `ring_id`=:rid AND `rune`=:old_rune',
                [
'new_rune'=>$target,'uid'=>$uid,'rid'=>$rid,'old_rune'=>$current]
            );
            if(
$up->rowCount()<1) throw new RuntimeException('Руна уже изменилась. Обновите страницу.');
            
game_ring_add_stats($uid,[$stat=>$delta]);
            
db_pdo()->commit();
            
$_SESSION['ok']='Руна установлена: +'.$values[$target].' к '.game_ring_rune_stat_label((string)$ring['kind']).'.';
            
$redirectRing($slot,'rune');
        }

        if(
$act==='ring_bonus'){
            
$current=max(0,(int)($owned['bonus']??0));
            
$max=game_ring_bonus_max((int)$owned['level']);
            if(
$current>=$max) throw new RuntimeException('Бонус кольца уже максимальный.');
            
$base=$current<10 5+$current*100+($current-10)*100;
            
$cost=game_ring_discounted_cost(max(5,$base),5);
            
$per=game_ring_bonus_per_stat();

            
db_pdo()->beginTransaction();
            
$pay=db_prepare(
                
'UPDATE `users` SET `g`=`g`-:cost WHERE `id`=:uid AND `g`>=:min_cost',
                [
'cost'=>$cost,'uid'=>$uid,'min_cost'=>$cost]
            );
            if(
$pay->rowCount()<1) throw new RuntimeException('Недостаточно золота для повышения бонуса.');
            
$up=db_prepare(
                
'UPDATE `user_rings` SET `bonus`=`bonus`+1 WHERE `user`=:uid AND `ring_id`=:rid AND `bonus`=:old_bonus',
                [
'uid'=>$uid,'rid'=>$rid,'old_bonus'=>$current]
            );
            if(
$up->rowCount()<1) throw new RuntimeException('Бонус уже изменился. Обновите страницу.');
            
game_ring_add_stats($uid,['str'=>$per,'vit'=>$per,'agi'=>$per,'def'=>$per]);
            
db_pdo()->commit();
            
$_SESSION['ok']='Бонус кольца повышен до '.($current+1).'/'.$max.'.';
            
$redirectRing($slot,'bonus');
        }

        if(
$act==='ring_star'){
            
$current=max(0,min(5,(int)($owned['stars']??0)));
            if(
$current>=5) throw new RuntimeException('Все пять звезд уже открыты.');
            
$costs=game_ring_star_costs();
            
$cost=(int)$costs[$current];
            
game_star_chest_state($uid);
            
$per=game_ring_star_per_stat();

            
db_pdo()->beginTransaction();
            
$dust=db_prepare(
                
'UPDATE `stars_dust_users` SET `dust`=`dust`-:cost WHERE `user`=:uid AND `dust`>=:min_cost',
                [
'cost'=>$cost,'uid'=>$uid,'min_cost'=>$cost]
            );
            if(
$dust->rowCount()<1) throw new RuntimeException('Недостаточно звездной пыли.');
            
$up=db_prepare(
                
'UPDATE `user_rings` SET `stars`=`stars`+1 WHERE `user`=:uid AND `ring_id`=:rid AND `stars`=:old_stars',
                [
'uid'=>$uid,'rid'=>$rid,'old_stars'=>$current]
            );
            if(
$up->rowCount()<1) throw new RuntimeException('Звезды уже изменились. Обновите страницу.');
            
game_ring_add_stats($uid,['str'=>$per,'vit'=>$per,'agi'=>$per,'def'=>$per]);
            
db_pdo()->commit();
            
$_SESSION['ok']='Открыта '.($current+1).'-я звезда кольца.';
            
$redirectRing($slot,'stars');
        }

        if(
$act==='ring_smith'){
            
$current=max(0,min(50,(int)($owned['smith']??0)));
            if(
$current>=50) throw new RuntimeException('Заточка кольца уже +50.');
            
$need1=1+$current;
            
$need=2+$current*2;
            
$silver=1000+1000*$current;
            
$per=game_ring_smith_per_stat();

            
db_pdo()->beginTransaction();
            
$sack=db_fetch_one('SELECT * FROM `sack` WHERE `user`=:uid FOR UPDATE',['uid'=>$uid]);
            if(!
$sack || (int)($sack['1']??0)<$need1 || (int)($sack['2']??0)<$need || (int)($sack['3']??0)<$need || (int)($sack['4']??0)<$need || (int)($sack['5']??0)<$need){
                throw new 
RuntimeException('Недостаточно ресурсов для заточки.');
            }
            
$pay=db_prepare(
                
'UPDATE `users` SET `s`=`s`-:silver WHERE `id`=:uid AND `s`>=:min_silver',
                [
'silver'=>$silver,'uid'=>$uid,'min_silver'=>$silver]
            );
            if(
$pay->rowCount()<1) throw new RuntimeException('Недостаточно серебра для заточки.');
            
db_execute(
                
'UPDATE `sack` SET `1`=`1`-:r1,`2`=`2`-:r2,`3`=`3`-:r3,`4`=`4`-:r4,`5`=`5`-:r5 WHERE `user`=:uid',
                [
'r1'=>$need1,'r2'=>$need,'r3'=>$need,'r4'=>$need,'r5'=>$need,'uid'=>$uid]
            );
            
$up=db_prepare(
                
'UPDATE `user_rings` SET `smith`=`smith`+1 WHERE `user`=:uid AND `ring_id`=:rid AND `smith`=:old_smith',
                [
'uid'=>$uid,'rid'=>$rid,'old_smith'=>$current]
            );
            if(
$up->rowCount()<1) throw new RuntimeException('Заточка уже изменилась. Обновите страницу.');
            
game_ring_add_stats($uid,['str'=>$per,'vit'=>$per,'agi'=>$per,'def'=>$per]);
            
db_pdo()->commit();
            
$_SESSION['ok']='Кольцо заточено до +'.($current+1).'.';
            
$redirectRing($slot,'smith');
        }
    } catch(
Throwable $e){
        if(
db_pdo()->inTransaction()) db_pdo()->rollBack();
        
error_log('[RING_ACTION] '.$e->getMessage());
        
$_SESSION['err']=$e->getMessage();
        if(
$owned$redirectRing($slot,(string)($_POST['manage']??''));
        
header('Location:/rings/'); exit;
    }
}

$slot=max(0,(int)($_GET['slot']??0));
$manage=(string)($_GET['manage']??'');
$slotRows=game_ring_slot_details($viewUid);
$detail=($slot>=1&&$slot<=3)?($slotRows[$slot]??null):null;
include 
'./system/h.php';

if(!empty(
$_SESSION['ok'])){ echo '<div class="ok center">'.security_html((string)$_SESSION['ok']).'</div>'; unset($_SESSION['ok']); }
if(!empty(
$_SESSION['err'])){ echo '<div class="error center">'.security_html((string)$_SESSION['err']).'</div>'; unset($_SESSION['err']); }
?>
<div class="title">Магические кольца</div>
<?php if($detail):
    
$catalog=db_fetch_assoc(db_query('SELECT * FROM `ring_catalog` WHERE `id`='.(int)$detail['ring_id'].' LIMIT 1')) ?: ['name'=>'Кольцо','description'=>'','kind'=>'rage'];
    
$level=max(1,(int)$detail['level']);
    
$effects=game_ring_effects($level,(string)$catalog['kind']);
    
$quality=$detail['quality'];
    
$rune=max(0,min(6,(int)$detail['rune']));
    
$bonus=max(0,(int)$detail['bonus']);
    
$bonusMax=game_ring_bonus_max($level);
    
$stars=max(0,min(5,(int)$detail['stars']));
    
$smith=max(0,min(50,(int)$detail['smith']));
    
$runeValues=game_ring_rune_values();
    
$runeValue=(int)$runeValues[$rune];
    
$smithTotal=$smith*game_ring_smith_per_stat()*4;
    
$bonusTotal=$bonus*game_ring_bonus_per_stat()*4;
    
$starTotal=$stars*game_ring_star_per_stat()*4;
?>
<div class="ring-detail-page ring-classic-detail">
  <div class="ring-detail-head">
    <div class="ring-detail-icon-wrap" style="border-color:<?=htmlspecialchars($quality['color'],ENT_QUOTES,'UTF-8')?>">
      <img class="ring-detail-icon" src="<?=htmlspecialchars($quality['image'],ENT_QUOTES,'UTF-8')?>" alt="">
      <?php if($smith>0):?><span class="slot-smith">+<?=$smith?></span><?php endif;?>
      <?php if($rune>0):?><img class="slot-rune" src="/images/icon/quality/<?=$rune?>.png" alt=""><?php endif;?>
      <?php if($stars>0):?><span class="slot-stars"><?=str_repeat('★',$stars)?></span><?php endif;?>
    </div>
    <div class="ring-detail-main">
      <div class="ring-detail-title" style="color:<?=htmlspecialchars($quality['color'],ENT_QUOTES,'UTF-8')?>"><?=htmlspecialchars($catalog['name'],ENT_QUOTES,'UTF-8')?></div>
      <div class="ring-special-line"><?=htmlspecialchars($effects['label'],ENT_QUOTES,'UTF-8')?>: <b><?=$effects['bonus']?> <?=htmlspecialchars($effects['unit'],ENT_QUOTES,'UTF-8')?></b></div>
      <div class="ring-special-line"><?=htmlspecialchars($effects['proc_label'],ENT_QUOTES,'UTF-8')?>: <b><?=$effects['chance']?>%</b></div>
    </div>
  </div>

  <div class="mini-line"></div>
  <div class="ring-upgrade-row">
    <div><img src="/images/icon/rune.png" alt=""> <b>Руна:</b>
      <?php if($rune>0):?><span class="green">+<?=$runeValue?> к <?=game_ring_rune_stat_label((string)$catalog['kind'])?></span><?php else:?><span class="grey">не установлена</span><?php endif;?><br>
      <span class="white">Руна — мощное усиление вещи!</span>
    </div>
    <?php if($canManage):?><a class="old-btn" href="/rings/?slot=<?=$slot?>&manage=rune">Магазин рун</a><?php endif;?>
  </div>

  <div class="mini-line"></div>
  <div class="ring-upgrade-row">
    <div><img src="/images/icon/smith.png" alt=""> <b>Заточка:</b> <span class="green">+<?=$smith?></span><br><span class="green">+<?=n_f($smithTotal)?> к параметрам</span></div>
    <?php if($canManage && $smith<50):?><a class="old-btn" href="/rings/?slot=<?=$slot?>&manage=smith">Заточка</a><?php endif;?>
  </div>

  <div class="mini-line"></div>
  <div class="ring-upgrade-row">
    <div><img src="/images/icon/quality/<?=max(1,min(6,(int)$quality['tier']))?>.png" alt=""> <b>Бонус:</b> <span class="green"><?=$bonus?> из <?=$bonusMax?></span><br><span class="green">+<?=n_f($bonusTotal)?> к параметрам</span></div>
    <?php if($canManage && $bonus<$bonusMax):?><a class="old-btn" href="/rings/?slot=<?=$slot?>&manage=bonus">Бонус</a><?php endif;?>
  </div>

  <div class="mini-line"></div>
  <div class="ring-upgrade-row">
    <div><span class="ring-star-symbol">★</span> <b>Звезды:</b> <span class="green"><?=$stars?> из 5</span><br><span class="green">+<?=n_f($starTotal)?> к параметрам</span></div>
    <?php if($canManage && $stars<5):?><a class="old-btn" href="/rings/?slot=<?=$slot?>&manage=stars">Звезды</a><?php endif;?>
  </div>

  <?php if($canManage && $manage==='rune'):
      
$costs=game_ring_rune_costs(); $vals=game_ring_rune_values(); $discount=game_ring_discount_percent(3); ?>
    <div class="ring-manage-panel">
      <div class="center blue"><b>Установка руны</b><?php if($discount>0):?> · скидка <?=$discount?>%<?php endif;?></div>
      <?php for($r=$rune+1;$r<=6;$r++): $cost=game_ring_discounted_cost((int)$costs[$r],3); ?>
        <form method="post" class="ring-rune-choice">
          <?=security_csrf_field()?><input type="hidden" name="ring_id" value="<?=$detail['ring_id']?>"><input type="hidden" name="act" value="ring_rune"><input type="hidden" name="rune" value="<?=$r?>"><input type="hidden" name="manage" value="rune">
          <img src="/images/runes/<?=htmlspecialchars(game_ring_rune_stat((string)$catalog['kind']),ENT_QUOTES,'UTF-8')?>.png" alt="">
          <span><img src="/images/icon/quality/<?=$r?>.png" alt=""> +<?=$vals[$r]?> к <?=game_ring_rune_stat_label((string)$catalog['kind'])?></span>
          <button class="old-btn" type="submit">Купить за <img src="/images/icon/gold.png" alt=""> <?=n_f($cost)?></button>
        </form>
      <?php endfor; ?>
    </div>
  <?php elseif($canManage && $manage==='bonus'):
      
$base=$bonus<10?5+$bonus*5:100+($bonus-10)*100$cost=game_ring_discounted_cost(max(5,$base),5); ?>
    <div class="ring-manage-panel center">
      <div class="blue">Каждая единица бонуса даёт <b>+24</b> к сумме основных параметров кольца.</div>
      <div>Текущий бонус: <b><?=$bonus?>/<?=$bonusMax?></b></div>
      <form method="post"><?=security_csrf_field()?><input type="hidden" name="ring_id" value="<?=$detail['ring_id']?>"><input type="hidden" name="act" value="ring_bonus"><input type="hidden" name="manage" value="bonus"><button class="old-btn" type="submit">Улучшить за <img src="/images/icon/gold.png" alt=""> <?=n_f($cost)?></button></form>
    </div>
  <?php elseif($canManage && $manage==='stars'):
      
$dust=game_star_chest_state($uid); $costs=game_ring_star_costs(); $starCost=(int)$costs[$stars]; ?>
    <div class="ring-manage-panel center">
      <div class="blue">Звезды улучшаются только за звездную пыль.</div>
      <div>Звездная пыль: <b><?=n_f((int)$dust['dust'])?></b> · следующая звезда: <b><?=n_f($starCost)?></b></div>
      <form method="post"><?=security_csrf_field()?><input type="hidden" name="ring_id" value="<?=$detail['ring_id']?>"><input type="hidden" name="act" value="ring_star"><input type="hidden" name="manage" value="stars"><button class="old-btn" type="submit">Прокачать звезду</button></form>
    </div>
  <?php elseif($canManage && $manage==='smith'):
      
$need1=1+$smith$need=2+$smith*2$silver=1000+1000*$smith?>
    <div class="ring-manage-panel center">
      <div class="blue">Заточка кольца использует ресурсы пещеры и серебро.</div>
      <div>Нужно: ресурс 1 — <b><?=$need1?></b>, ресурсы 2–5 — по <b><?=$need?></b>, серебро — <b><?=n_f($silver)?></b>.</div>
      <form method="post"><?=security_csrf_field()?><input type="hidden" name="ring_id" value="<?=$detail['ring_id']?>"><input type="hidden" name="act" value="ring_smith"><input type="hidden" name="manage" value="smith"><button class="old-btn" type="submit">Заточить до +<?=($smith+1)?></button></form>
    </div>
  <?php endif; ?>

  <div class="mini-line"></div>
  <div class="center"><a class="old-btn" href="/rings/">Кольца</a></div>
</div>
<?php else: ?>
<div class="rings-v50-list rings-classic-list">
<?php
$q
=db_query('SELECT * FROM `ring_catalog` ORDER BY `id`');
while(
$r=db_fetch_assoc($q)):
    
$owned=db_fetch_assoc(db_query('SELECT * FROM `user_rings` WHERE `user`='.$uid.' AND `ring_id`='.(int)$r['id'].' LIMIT 1'));
    
$level=$owned?max(1,(int)($owned['level']??1)):1;
    
$quality=game_ring_quality($level,(string)($r['kind']??'rage'));
    
$nextCost=(int)$r['price']+250*$level;
    
$effects=game_ring_effects($level,(string)($r['kind']??'rage'));
    
$selected=$owned && (int)($owned['slot']??0)>0;
    
$pct=min(100,(int)round($level/80*100));
?>
<div class="rings-v50-row">
  <div class="rings-v50-left"><img class="rings-v50-icon" src="<?=htmlspecialchars($quality['image'],ENT_QUOTES,'UTF-8')?>" alt=""></div>
  <div class="rings-v50-mid">
    <div class="rings-v50-title" style="color:<?=htmlspecialchars($quality['color'],ENT_QUOTES,'UTF-8')?>"><?=htmlspecialchars($r['name'],ENT_QUOTES,'UTF-8')?><?php if($selected):?>, <span class="green">✔ Выбрано</span><?php endif;?></div>
    <div class="white"><?=htmlspecialchars($r['description'],ENT_QUOTES,'UTF-8')?></div>
    <div class="rings-v50-stats"><?=htmlspecialchars($effects['label'],ENT_QUOTES,'UTF-8')?>: <span class="green"><?=$effects['bonus']?> <?=htmlspecialchars($effects['unit'],ENT_QUOTES,'UTF-8')?></span></div>
    <div class="rings-v50-stats"><?=htmlspecialchars($effects['proc_label'],ENT_QUOTES,'UTF-8')?>: <span class="green"><?=$effects['chance']?>%</span></div>
    <div class="ring-level-progress"><span style="width:<?=$pct?>%"></span></div>
    <?php if(!$owned):?>
      <form method="post" class="center"><?=security_csrf_field()?><input type="hidden" name="ring_id" value="<?=$r['id']?>"><button class="old-btn" name="act" value="buy">Купить за <img src="/images/icon/gold.png" alt=""> <?=n_f((int)$r['price'])?></button></form>
    <?php else:?>
      <form method="post" class="center"><?=security_csrf_field()?><input type="hidden" name="ring_id" value="<?=$r['id']?>"><button class="old-btn" name="act" value="upgrade">Улучшить за <img src="/images/icon/gold.png" alt=""> <?=n_f($nextCost)?></button></form>
      <div class="center"><a class="old-btn" href="/rings/?slot=<?=game_ring_slot_for_catalog($r)?>">Выбрать</a></div>
    <?php endif;?>
  </div>
</div>
<div class="mini-line"></div>
<?php endwhile; ?>
<div class="block_zero"><a href="/smith/"><img src="/images/icon/arrow.png" alt=""> Вернуться в кузницу</a></div>
</div>
<?php endif; include './system/f.php'?>
Онлайн: 3
Реклама