[Voice Manager] Модель функционирования

Сообщения
1,012
Реакции
814
Помог
10 раз(а)
Добрый вечер. В общем ребят, не могу определиться с моделью построения система распределения голоса.

На данный момент имею следующую возможность:

Могу слушать: всех/живых/мертвых/команду/никого
Могу говорить: всем/живым/мертвым/команде

Так же реализован функционал мута (не слушать определенных игроков)

Примерная менюшка

2019-08-30_194718.jpg

Сейчас необходимо реализовать систему приватного разговора, и вот тут не знаю как поступить.

Либо в режиме "Могу говорить" выбирать режим: приватный, затем появляется пункт где можно выбрать игрока кому говорить.
Либо этот режим выбирать автоматически, когда выбирается игрок или несколько игроков кому можно говорить.

Либо вообще не трогать пункт: Кому говорить, а функционал сделать самостоятельным.

Либо при выборе игрока еще - оповещать его о том, что с вами хотят поговорить приватно, и если соглашается, то добавлять его в приватный канал, но таких приватных каналов может быть много и тут я уже по коду буду вопросы задавать =DDD Ибо приватный канал может иметь 2 и более игроков.

В общем, у кого какие мысли, буду рад послушать, может другие идеи появятся.
 
Сообщения
70
Реакции
0
Зачем так заморачиваться? Esc, список игроков, заглушить.
 
Сообщения
3,257
Реакции
1,437
Помог
121 раз(а)
при выборе игрока еще - оповещать его о том, что с вами хотят поговорить приватно, и если соглашается, то добавлять его в приватный канал
Мне кажется, так будет лучше
 
Сообщения
2,491
Реакции
2,790
Помог
61 раз(а)
Alex1985, как показала практика о данном функционале знает от силы 30% игроков. Да и лично мне удобней когда есть менюшка прям на сервере.
 
Сообщения
2,491
Реакции
2,790
Помог
61 раз(а)
Alex1985, оповещение в чат также нагрузку дает
 
Сообщения
1,012
Реакции
814
Помог
10 раз(а)
Alex1985, и она будет висеть вечно там, игрок уйдет, другой придет и будет в муте у меня сидеть не за что
30 Авг 2019
В общем, ладно, попробую сделать приватные каналы с оповещением, но видимо стоит учитывать куче нюансов.

Пока пилю только ядро, менюшку буду отдельном плагином пилить, ибо запутаюсь нафиг.

Жалко тестить не с кем, может че накосячить успел =D

C++:
#include < amxmodx >
#include < amxmisc >
#include < nvault >
#include < reapi >

#pragma semicolon 1

const Float: TASK_DELAY                    =    5.0;                        // Время после смерти, через которое живые не услышат мертвого игрока

const INACTIVITY_DAYS                    =    7;                            // Удалять неактивных игроков через 'n' дней
const SECONDS_IN_DAY                    =    86400;                        // Количество секунд в одном дне

new const VAULT_FOLDER_NAME[ ]            =    "voice_manager";            // Директория хранилища nvault
new const VAULT_FILE_NAME__HEARER[ ]    =    "voice_manager_hearer";        // Имя хранилища nvault для слушателя
new const VAULT_FILE_NAME__SPEAKER[ ]    =    "voice_manager_speaker";    // Имя хранилища nvault для вещателя

const START_DATE                            =        0;

const MAX_LENGTH__PATH                        =        64;
const MAX_LENGTH__AUTHID                    =        24;
const MAX_LENGTH__VOICE_MODE                =        2;

enum _: HEARER_VOICE_MODE
{
    HEARER_VOICE_MODE__ALL,
    HEARER_VOICE_MODE__LIVING,
    HEARER_VOICE_MODE__DEAD,
    HEARER_VOICE_MODE__TEAM,
    HEARER_VOICE_MODE__NOONE
}

enum _: SPEAKER_VOICE_MODE
{
    SPEAKER_VOICE_MODE__ALL,
    SPEAKER_VOICE_MODE__ALIVE,
    SPEAKER_VOICE_MODE__DEAD,
    SPEAKER_VOICE_MODE__TEAM
}

new g_iHearerVaultID;
new g_iSpeakerVaultID;

new g_iHearerVoiceMode[ MAX_PLAYERS + 1 ];
new g_iSpeakerVoiceMode[ MAX_PLAYERS + 1 ];

new bool: g_bPlayerAlive[ MAX_PLAYERS + 1 ];

new bool: g_bPlayerMuteVoice[ MAX_PLAYERS + 1 ][ MAX_PLAYERS + 1 ];

new bool: g_bPrivateVoiceMode[ MAX_PLAYERS + 1 ];
new bool: g_bPlayerPrivateVoice[ MAX_PLAYERS + 1 ][ MAX_PLAYERS + 1 ];

public plugin_natives( )
{
    register_native( "native_VoiceManager_HearerVoiceMode", "native_VoiceManager_HearerVoiceMode", .style = false);
    register_native( "native_VoiceManager_SpeakerVoiceMode", "native_VoiceManager_SpeakerVoiceMode", .style = false);
}

public plugin_init( )
{
    register_plugin( "Voice Manager", "1.0", "Javekson" );
    
    RegisterHookChain( RG_CBasePlayer_Spawn, "CBasePlayer_Spawn", .post = true );
    RegisterHookChain( RG_CBasePlayer_Killed, "CBasePlayer_Killed", .post = true );
    RegisterHookChain( RG_HandleMenu_ChooseTeam, "HandleMenu_ChooseTeam", .post = true );
    RegisterHookChain( RG_CSGameRules_CanPlayerHearPlayer, "CSGameRules_CanPlayerHearPlayer", .post = false );
}

public plugin_cfg( )
{
    new sVaultDir[ MAX_LENGTH__PATH ];
    get_localinfo( "amxx_datadir", sVaultDir, charsmax( sVaultDir ) );
    
    formatex( sVaultDir, charsmax( sVaultDir ), "%s/vault/%s", sVaultDir, VAULT_FOLDER_NAME );
    
    if( !dir_exists( sVaultDir ) )
    {
        mkdir( sVaultDir );
    }
    
    new sHearerVaultName[ MAX_LENGTH__PATH + 32 ];
    formatex( sHearerVaultName, charsmax( sHearerVaultName ), "%s/%s", VAULT_FOLDER_NAME, VAULT_FILE_NAME__HEARER );
    
    g_iHearerVaultID = nvault_open( sHearerVaultName );
    
    new sSpeakerVaultName[ MAX_LENGTH__PATH + 32 ];
    formatex( sSpeakerVaultName, charsmax( sSpeakerVaultName ), "%s/%s", VAULT_FOLDER_NAME, VAULT_FILE_NAME__SPEAKER );
    
    g_iSpeakerVaultID = nvault_open( sSpeakerVaultName );
    
    nvault_prune( g_iHearerVaultID, START_DATE, get_systime( ) - SECONDS_IN_DAY * INACTIVITY_DAYS );
    nvault_prune( g_iSpeakerVaultID, START_DATE, get_systime( ) - SECONDS_IN_DAY * INACTIVITY_DAYS );
}

public plugin_end( )
{
    nvault_close( g_iHearerVaultID );
    nvault_close( g_iSpeakerVaultID );
}

public client_putinserver( id )
{
    new sAuthID[ MAX_LENGTH__AUTHID ];
    get_user_authid( id, sAuthID, charsmax( sAuthID ) );
    
    if(( g_iHearerVoiceMode[ id ] = nvault_get( g_iHearerVaultID, sAuthID ) ))
    {
        nvault_touch( g_iHearerVaultID, sAuthID );
    }
    
    if(( g_iSpeakerVoiceMode[ id ] = nvault_get( g_iSpeakerVaultID, sAuthID ) ))
    {
        nvault_touch( g_iSpeakerVaultID, sAuthID );
    }
}

public client_disconnected( id )
{
    remove_task( id );
    
    g_bPlayerAlive[ id ] = false;
    
    for( new iPlayerID = 1; iPlayerID <= MAX_PLAYERS; iPlayerID++ )
    {
        g_bPlayerMuteVoice[ iPlayerID ][ id ] = false;
    }
    
    arrayset( g_bPlayerMuteVoice[ id ], false , sizeof g_bPlayerMuteVoice[ ] );
    
    for( new iPlayerID = 1; iPlayerID <= MAX_PLAYERS; iPlayerID++ )
    {
        g_bPlayerPrivateVoice[ iPlayerID ][ id ] = false;
    }
    
    arrayset( g_bPlayerPrivateVoice[ id ], false , sizeof g_bPlayerPrivateVoice[ ] );
    
    func_TogglePrivateVoiceMode( id );
}

public CBasePlayer_Spawn( const id )
{
    g_bPlayerAlive[ id ] = true;
}

public CBasePlayer_Killed( const id )
{
    set_task_ex( TASK_DELAY, "task_AfterDeath", id, .flags = SetTask_Once );
}

public HandleMenu_ChooseTeam( const id, const MenuChooseTeam:slot )
{
    g_bPlayerAlive[ id ] = bool: is_user_alive( id );
}

public task_AfterDeath( const id )
{
    g_bPlayerAlive[ id ] = bool: is_user_alive( id );
}

public CSGameRules_CanPlayerHearPlayer( const iListener, const iSender )
{
    if( g_bPlayerMuteVoice[ iListener ][ iSender ] )
    {
        SetHookChainReturn( ATYPE_BOOL, false );
        
        return HC_SUPERCEDE;
    }
    
    if( g_bPrivateVoiceMode[ iListener ] )
    {
        if( !g_bPlayerPrivateVoice[ iListener ][ iSender ] )
        {
            SetHookChainReturn( ATYPE_BOOL, false );
            
            return HC_SUPERCEDE;
        }
    }
    else
    {
        switch( g_iHearerVoiceMode[ iListener ] )
        {
            case HEARER_VOICE_MODE__LIVING:
            {
                if( g_bPlayerAlive[ iListener ] && !g_bPlayerAlive[ iSender ] )
                {
                    SetHookChainReturn( ATYPE_BOOL, false );
                    
                    return HC_SUPERCEDE;
                }
            }
            
            case HEARER_VOICE_MODE__NOONE:
            {
                SetHookChainReturn( ATYPE_BOOL, false );
                
                return HC_SUPERCEDE;
            }
            
            case HEARER_VOICE_MODE__TEAM:
            {
                if( get_member( iListener, m_iTeam ) != get_member( iSender, m_iTeam ) )
                {
                    SetHookChainReturn( ATYPE_BOOL, false );
                    
                    return HC_SUPERCEDE;
                }
            }
            
            case HEARER_VOICE_MODE__DEAD:
            {
                if( g_bPlayerAlive[ iSender ] )
                {
                    SetHookChainReturn( ATYPE_BOOL, false );
                    
                    return HC_SUPERCEDE;
                }
            }
        }
    }
    
/*==========================================================================================================*/
    
    if( g_bPrivateVoiceMode[ iSender ] )
    {
        if( !g_bPlayerPrivateVoice[ iSender ][ iListener ] )
        {
            SetHookChainReturn( ATYPE_BOOL, false );
            
            return HC_SUPERCEDE;
        }
    }
    else
    {
        switch( g_iSpeakerVoiceMode[ iSender ] )
        {
            case SPEAKER_VOICE_MODE__TEAM:
            {
                if( get_member( iListener, m_iTeam ) != get_member( iSender, m_iTeam ) )
                {
                    SetHookChainReturn( ATYPE_BOOL, false );
                    
                    return HC_SUPERCEDE;
                }
            }
            
            case SPEAKER_VOICE_MODE__ALIVE:
            {
                if( !g_bPlayerAlive[ iListener ] )
                {
                    SetHookChainReturn( ATYPE_BOOL, false );
                    
                    return HC_SUPERCEDE;
                }
            }
            
            case SPEAKER_VOICE_MODE__DEAD:
            {
                if( g_bPlayerAlive[ iListener ] )
                {
                    SetHookChainReturn( ATYPE_BOOL, false );
                    
                    return HC_SUPERCEDE;
                }
            }
        }
    }
    
    return HC_CONTINUE;
}

func_TogglePrivateVoiceMode( const id )
{
    g_bPrivateVoiceMode[ id ] = false;
    
    for( new iPlayerID = 1; iPlayerID <= MAX_PLAYERS; iPlayerID++ )
    {
        if( g_bPlayerPrivateVoice[ id ][ iPlayerID ] )
        {
            g_bPrivateVoiceMode[ id ] = true;
            
            break;
        }
    }
}

public native_VoiceManager_HearerVoiceMode( iPluginID, iParamCount )
{
    new id = get_param( 1 );
    
    return g_iHearerVoiceMode[ id ];
}

public native_VoiceManager_SpeakerVoiceMode( iPluginID, iParamCount )
{
    new id = get_param( 1 );
    
    return g_iSpeakerVoiceMode[ id ];
}

public callfunc_ToggleHearerVoiceMode( const id )
{
    new sAuthID[ MAX_LENGTH__AUTHID ];
    get_user_authid( id, sAuthID, charsmax( sAuthID ) );
    
    g_iHearerVoiceMode[ id ] = ++g_iHearerVoiceMode[ id ] % HEARER_VOICE_MODE;
    
    if( g_iHearerVoiceMode[ id ] )
    {
        new sHearerVoiceMode[ MAX_LENGTH__VOICE_MODE ];
        
        num_to_str( g_iHearerVoiceMode[ id ], sHearerVoiceMode, charsmax( sHearerVoiceMode ) );
        
        nvault_set( g_iHearerVaultID, sAuthID, sHearerVoiceMode );
    }
    else
    {
        nvault_remove( g_iHearerVaultID, sAuthID );
    }
}

public callfunc_ToggleSpeakerVoiceMode( const id )
{
    new sAuthID[ MAX_LENGTH__AUTHID ];
    get_user_authid( id, sAuthID, charsmax( sAuthID ) );
    
    g_iSpeakerVoiceMode[ id ] = ++g_iSpeakerVoiceMode[ id ] % SPEAKER_VOICE_MODE;
    
    if( g_iSpeakerVoiceMode[ id ] )
    {
        new sSpeakerVoiceMode[ MAX_LENGTH__VOICE_MODE ];
        
        num_to_str( g_iSpeakerVoiceMode[ id ], sSpeakerVoiceMode, charsmax( sSpeakerVoiceMode ) );
        
        nvault_set( g_iSpeakerVaultID, sAuthID, sSpeakerVoiceMode );
    }
    else
    {
        nvault_remove( g_iSpeakerVaultID, sAuthID );
    }
}

public callfunc_TogglePlayerMuteVoice( id, iPlayerID )
{
    g_bPlayerMuteVoice[ id ][ iPlayerID ] = !g_bPlayerMuteVoice[ id ][ iPlayerID ];
}

public callfunc_TogglePlayerPrivateVoice( id, iPlayerID )
{
    g_bPlayerPrivateVoice[ id ][ iPlayerID ] = !g_bPlayerPrivateVoice[ id ][ iPlayerID ];
    
    func_TogglePrivateVoiceMode( id );
}
30 Авг 2019
Если я правильно понимаю приват должна выглядеть примерно так:

1. Я выбираю игрока(активирую себе g_bPrivateVoiceMode ) - ему приходит оповещение, меню с двумя кнопками,

2. Если соглашается, то и ему активирую тоже g_bPrivateVoiceMode, а так же g_bPlayerPrivateVoice[ id с кем приватка].
Ибо таким образом я смогу создать несколько каналов и несколько человек в приватке.

2.1 Офаю все прочие режимы, дабы не путались(тупо пропускаю условия, даже если другие режимы активны)

1.2. Если человек отказывается, я ничего ему не активирую, а у себя чекаю, есть ли у меня еще игроки в приватки, если нету, то офаю g_bPrivateVoiceMode у себя.

Что еще я упустить мог?
 

d3m37r4

111111
Сообщения
1,420
Реакции
1,162
Помог
10 раз(а)
#include < nvault >
Javekson, а чего не PDS ?
 

fox

Сообщения
173
Реакции
49
Помог
7 раз(а)
Javekson, увидел, что вы в конце концов реализовали замысел, на своем сервере. Стоит ли ждать в вашем блоге? Или это приват? :scratch_one-s_head:
 
Сообщения
1,012
Реакции
814
Помог
10 раз(а)
fox, смотрю ко мне заходишь, следишь? =D Нет, не приват, но пока не совсем нравится то, что я сделал, делать приватные каналы слишком муторно для меня, а в таком виде как сейчас возникают пересечение между приватным общением, небольшой минус, в принципе не критичный, может быть оставлю как есть, но по коду еще надо поработать, каждый день нюансы всплывают после тестов, надеюсь к выходным допилю
 

fox

Сообщения
173
Реакции
49
Помог
7 раз(а)
Javekson, что-то я совсем ушёл в работу, что аж забыл ответить. Благо выходные настали ??? Как успехи? Нужна ли помощь в тестах?
 
Сообщения
1,012
Реакции
814
Помог
10 раз(а)
fox, по командировкам катаюсь ) напиши мне вк, дам в лс )
 

Пользователи, просматривающие эту тему

Сейчас на форуме нет ни одного пользователя.
Сверху Снизу