Вход Регистрация
Файл: system/v23_features.php
Строк: 330
<?php
/* Автоматизация, кольца, бонусный комплект и рекорды: by Метриум (Стэлп) */
declare(strict_types=1);
function 
game_v23_bootstrap(): void {
    static 
$done=false; if($done)return; $done=true;
    
$ver=(int)(game_meta_get('v23_schema','0'));
    
// Старые установки v48 проходят миграцию один раз; после v52 лишние SHOW/ALTER не выполняются.
    
if($ver>=53)return;
    
db_query("CREATE TABLE IF NOT EXISTS `bonus_kit_offer` (`user` int NOT NULL,`expires_at` int NOT NULL,`claimed` tinyint NOT NULL DEFAULT 0,`topup_gold` int NOT NULL DEFAULT 0,`eligible` tinyint NOT NULL DEFAULT 0,`kit_id` int NOT NULL DEFAULT 27,`granted_at` int NOT NULL DEFAULT 0,PRIMARY KEY(`user`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci");
    foreach([
'topup_gold'=>'int NOT NULL DEFAULT 0','eligible'=>'tinyint NOT NULL DEFAULT 0','kit_id'=>'int NOT NULL DEFAULT 27','granted_at'=>'int NOT NULL DEFAULT 0'] as $column=>$def){ $c=db_fetch_assoc(db_query("SHOW COLUMNS FROM `bonus_kit_offer` LIKE '".db_real_escape_string($column)."'")); if(!$cdb_query("ALTER TABLE `bonus_kit_offer` ADD COLUMN `".$column."` ".$def); }
    
db_query("CREATE TABLE IF NOT EXISTS `payment_receipts` (`receipt_hash` char(64) NOT NULL,`user` int NOT NULL,`gold` int NOT NULL DEFAULT 0,`amount` decimal(12,2) NOT NULL DEFAULT 0,`created_at` int NOT NULL,PRIMARY KEY(`receipt_hash`),KEY `user_time`(`user`,`created_at`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci");
    
db_query("CREATE TABLE IF NOT EXISTS `ring_catalog` (`id` tinyint NOT NULL,`name` varchar(80) NOT NULL,`description` varchar(255) NOT NULL,`price` int NOT NULL DEFAULT 250,`kind` varchar(20) NOT NULL,PRIMARY KEY(`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci");
    
db_query("CREATE TABLE IF NOT EXISTS `user_rings` (`user` int NOT NULL,`ring_id` tinyint NOT NULL,`slot` tinyint NOT NULL DEFAULT 0,`level` smallint NOT NULL DEFAULT 1,PRIMARY KEY(`user`,`ring_id`),KEY `slot`(`user`,`slot`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci");
    
$ringColumns=[
        
'level'=>"smallint NOT NULL DEFAULT 1 AFTER `slot`",
        
'rune'=>"tinyint NOT NULL DEFAULT 0 AFTER `level`",
        
'bonus'=>"smallint NOT NULL DEFAULT 0 AFTER `rune`",
        
'stars'=>"tinyint NOT NULL DEFAULT 0 AFTER `bonus`",
        
'smith'=>"smallint NOT NULL DEFAULT 0 AFTER `stars`",
    ];
    foreach(
$ringColumns as $column=>$definition){
        
$has=db_fetch_assoc(db_query("SHOW COLUMNS FROM `user_rings` LIKE '".db_real_escape_string($column)."'"));
        if(!
$has){ db_query("ALTER TABLE `user_rings` ADD COLUMN `".$column."` ".$definition); }
    }
    
db_query("INSERT IGNORE INTO `ring_catalog` (`id`,`name`,`description`,`price`,`kind`) VALUES
      (1,'Кольцо Ярости','Увеличивает силу критического удара в зависимости от потерянного здоровья',250,'rage'),
      (2,'Кольцо Защиты','Увеличивает броню при отражении критического удара в зависимости от потерянного здоровья',250,'guard'),
      (3,'Кольцо Воскрешения','Воскрешает владельца в момент получения смертельного удара',250,'revive')"
);
    
game_meta_set('v23_schema','53');
}
function 
game_bonus_offer_ensure(int $uid): array {
    
$r=db_fetch_one('SELECT * FROM `bonus_kit_offer` WHERE `user`=:u LIMIT 1',['u'=>$uid]);
    if(!
$r){$exp=time()+3*86400;db_execute('INSERT INTO `bonus_kit_offer` (`user`,`expires_at`,`claimed`,`topup_gold`,`eligible`,`kit_id`,`granted_at`) VALUES (:u,:e,0,0,0,27,0)',['u'=>$uid,'e'=>$exp]);$r=db_fetch_one('SELECT * FROM `bonus_kit_offer` WHERE `user`=:u',['u'=>$uid])??[];}
    return 
$r;
}
function 
game_bonus_kit_details(int $uid): array {
    
$offer=game_bonus_offer_ensure($uid); $kitId=max(1,(int)($offer['kit_id']??27));
    
$kit=db_fetch_one('SELECT * FROM `complects` WHERE `id`=:i',['i'=>$kitId]);
    if(!
$kit) throw new RuntimeException('Бонусный комплект не найден.');
    
$ids=[]; for($i=1;$i<=8;$i++) if((int)($kit['w_'.$i]??0)>0)$ids[]=(int)$kit['w_'.$i];
    
$items=[]; $sum=0;
    foreach(
$ids as $id){
        
$row=db_fetch_one('SELECT i.`id`,i.`name`,i.`w`,s.`quality`,s.`bonus`,s.`_str`,s.`_vit`,s.`_agi`,s.`_def` FROM `items` i JOIN `shop` s ON s.`id`=i.`id` WHERE i.`id`=:i',['i'=>$id]);
        if(
$row){$sum+=(int)$row['_str']+(int)$row['_vit']+(int)$row['_agi']+(int)$row['_def'];$items[]=$row;}
    }
    return [
'offer'=>$offer,'kit'=>$kit,'items'=>$items,'sum'=>$sum,'ids'=>$ids];
}
function 
game_bonus_kit_grant(int $uid): bool {
    
$pdo=db_pdo(); $own=!$pdo->inTransaction(); if($own)$pdo->beginTransaction();
    try{
        
$o=db_fetch_one('SELECT * FROM `bonus_kit_offer` WHERE `user`=:u FOR UPDATE',['u'=>$uid]);
        if(!
$o || (int)$o['claimed']===1){ if($own)$pdo->commit(); return false; }
        if((int)
$o['eligible']!==|| (int)$o['topup_gold']<100) throw new RuntimeException('Для комплекта требуется реальное пополнение минимум на 100 золота.');
        
$kit=db_fetch_one('SELECT * FROM `complects` WHERE `id`=:i',['i'=>max(1,(int)($o['kit_id']??27))]);
        if(!
$kit) throw new RuntimeException('Комплект не найден.');
        for(
$slot=1;$slot<=8;$slot++){
            
$itemId=(int)($kit['w_'.$slot]??0); if($itemId<=0)continue;
            
$row=db_fetch_one('SELECT i.`id`,s.`quality`,s.`bonus`,s.`_str`,s.`_vit`,s.`_agi`,s.`_def` FROM `items` i JOIN `shop` s ON s.`id`=i.`id` WHERE i.`id`=:i',['i'=>$itemId]);
            if(!
$row)continue;
            
db_execute('INSERT INTO `inv` (`user`,`item`,`quality`,`bonus`,`smith`,`equip`,`new`,`rune`,`_str`,`_vit`,`_agi`,`_def`,`place`) VALUES (:u,:i,:q,:b,0,0,1,0,:s,:v,:a,:d,0)',[
                
'u'=>$uid,'i'=>$itemId,'q'=>(int)$row['quality'],'b'=>(int)$row['bonus'],'s'=>(int)$row['_str'],'v'=>(int)$row['_vit'],'a'=>(int)$row['_agi'],'d'=>(int)$row['_def']]);
        }
        
db_execute('UPDATE `bonus_kit_offer` SET `claimed`=1,`granted_at`=:t WHERE `user`=:u',['t'=>time(),'u'=>$uid]);
        if(
function_exists('game_system_mail')) game_system_mail($uid,'[color=green]Бонусный комплект за пополнение на 100 золота выдан в вашу сумку.[/color]');
        if(
$own)$pdo->commit(); return true;
    }catch(
Throwable $e){ if($own&&$pdo->inTransaction())$pdo->rollBack(); throw $e; }
}
function 
game_bonus_offer_register_topup(int $uid,int $purchasedGold): bool {
    if(
$uid<=0||$purchasedGold<=0)return false$o=game_bonus_offer_ensure($uid);
    if((int)
$o['claimed']===1)return false;
    if(
time()>(int)$o['expires_at'])return false;
    
db_execute('UPDATE `bonus_kit_offer` SET `topup_gold`=LEAST(1000000,`topup_gold`+:g) WHERE `user`=:u',['g'=>$purchasedGold,'u'=>$uid]);
    
$o=db_fetch_one('SELECT * FROM `bonus_kit_offer` WHERE `user`=:u',['u'=>$uid]);
    if((int)(
$o['topup_gold']??0)>=100){ db_execute('UPDATE `bonus_kit_offer` SET `eligible`=1 WHERE `user`=:u',['u'=>$uid]); return game_bonus_kit_grant($uid); }
    return 
false;
}
function 
game_live_time_attr(int $ts): string { return ' data-live-until="'.max(0,$ts).'"'; }
function 
game_ring_slots(int $uid): array { $out=[1=>0,2=>0,3=>0];$q=db_query("SELECT `ring_id`,`slot` FROM `user_rings` WHERE `user`=$uid AND `slot` IN (1,2,3)");while($r=db_fetch_assoc($q))$out[(int)$r['slot']]=(int)$r['ring_id'];return $out; }
function 
game_personal_records(array $u): array { return [
 [
'Общий рейтинг',(int)($u['exp']??0),1000,'+200 к параметрам'],
 [
'Золотая лихорадка',(int)($u['g']??0),2500,'+200 к параметрам'],
 [
'Титан арены',(int)($u['arena_pobed']??0),1000,'+200 к параметрам'],
 [
'Поиск с камней',(int)($u['stone']??0),50,'+200 к параметрам'],
 [
'Поиск с травы',(int)($u['grass']??0),50,'+200 к параметрам'],
 [
'Монстры подземелья',(int)($u['bos_1']??0),20,'+200 к параметрам'],
 [
'Титан лиги',(int)($u['league_fights']??0),53,'+200 к параметрам'],
 [
'Алхимик',(int)($u['parse']??0),25,'+200 к параметрам'] ]; }

/** Автоматически переводит Долину бессмертных в фазу боя по таймеру. by Метриум (Стэлп) */
function game_undying_tick(): void {
    static 
$done=false; if($done) return; $done=true;
    if(
function_exists('game_v51_events_tick')) { game_v51_events_tick(); return; }
}


/** Качество и изображение кольца зависят только от уровня прокачки. by Метриум (Стэлп) */
function game_ring_quality(int $levelstring $kind='rage'): array {
    
$level=max(1,$level);
    
$tier=min(7,intdiv($level-1,10));
    
$names=['Простое','Обычное','Редкое','Эпическое','Легендарное','Божественное','Сверхбожественное','Мифическое'];
    
$colors=['#b6aa8d','#79d35d','#6eb6ff','#d18cff','#ffb14a','#ffdf61','#ff6666','#58f0e8'];
    
$families=['rage'=>'rage','guard'=>'guard','revive'=>'revive'];
    
$family=$families[$kind] ?? 'rage';
    return [
        
'tier'=>$tier,
        
'name'=>$names[$tier],
        
'color'=>$colors[$tier],
        
'image'=>'/images/rings/'.$family.'_'.$tier.'.png',
        
'family'=>$family,
    ];
}

/** Фиксированный слот кольца по его игровому типу. Игрок слот не выбирает. by Метриум (Стэлп) */
function game_ring_slot_for_catalog(array $ring): int {
    
$kind=(string)($ring['kind']??'');
    return 
match($kind){'rage'=>1,'guard'=>2,'revive'=>3,default=>max(1,min(3,(int)($ring['id']??1)))};
}

/** Нормализует старые кольца после обновления: каждое возвращается в свой слот. by Метриум (Стэлп) */
function game_ring_normalize_user_slots(int $uid): void {
    if(
$uid<=0) return;
    
$rows=[];
    
$q=db_query('SELECT ur.ring_id,ur.slot,rc.kind FROM user_rings ur LEFT JOIN ring_catalog rc ON rc.id=ur.ring_id WHERE ur.user='.(int)$uid.' ORDER BY ur.ring_id');
    while(
$r=db_fetch_assoc($q)) $rows[]=$r;
    foreach(
$rows as $r){
        
$slot=game_ring_slot_for_catalog($r);
        if((int)(
$r['slot']??0)!==$slot){
            
db_query('UPDATE user_rings SET slot=0 WHERE user='.(int)$uid.' AND slot='.(int)$slot.' AND ring_id<>'.(int)$r['ring_id']);
            
db_query('UPDATE user_rings SET slot='.(int)$slot.' WHERE user='.(int)$uid.' AND ring_id='.(int)$r['ring_id']);
        }
    }
}

function 
game_ring_slot_details(int $uid): array {
    
game_ring_normalize_user_slots($uid);
    
$out=[1=>null,2=>null,3=>null];
    
$q=db_query('SELECT ur.ring_id,ur.slot,COALESCE(ur.level,1) level,COALESCE(ur.rune,0) rune,COALESCE(ur.bonus,0) bonus,COALESCE(ur.stars,0) stars,COALESCE(ur.smith,0) smith,rc.name,rc.kind FROM user_rings ur LEFT JOIN ring_catalog rc ON rc.id=ur.ring_id WHERE ur.user='.(int)$uid.' AND ur.slot IN (1,2,3)');
    while(
$r=db_fetch_assoc($q)){ $slot=(int)$r['slot']; $r['quality']=game_ring_quality((int)$r['level'],(string)($r['kind']??'rage')); $out[$slot]=$r; }
    return 
$out;
}
Онлайн: 4
Реклама