[HL] Смена v_ модели оружия по нажатию кнопки R

Glaster

Разработчик
Моделлер
Проверенный
Сообщения
71
Реакции
98
Баллы
18
Всем привет!

Делаю плагин по смене режима работы и v_ модели для обычных ручных гранат для Half-Life. Предполагается, что происходить это по нажатию кнопки R. Казалось бы, отловить событие перезарядки и дело с концом, например, через Ham_Weapon_Reload но для HLW_HANDGRENADE этот метод не работает. Можно пойти через FM_CmdStart, однако в таком случае смена режима будет срабатывать, даже если R зажата, из-за чего его смена превратится в рулетку.

Есть какой-то способ реализовать указанный функционал без описанных недостатков?

Код:
public plugin_init(){
    register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR);
    RegisterHam( Ham_Weapon_Reload , "weapon_handgrenade", "f_HamWeaponReload")
    register_forward(FM_CmdStart, "fw_SwitchGrenadeMode");
}

public fw_SwitchGrenadeMode(id, UC_Handle, seed){
    // РАБОТАЕТ, НО В РУКАХ У ИГРОКА ПРОИСХОДИТ ДИСКОТЕКА
    
    if (!is_user_alive(id) || get_user_weapon(id) != HLW_HANDGRENADE)
        return FMRES_IGNORED;

    static buttons; 
    buttons = get_uc(UC_Handle, UC_Buttons);   

    if (buttons & IN_RELOAD) {
        iPlayerGrenadeStates[id]++;
        if (iPlayerGrenadeStates[id] > 4){
            iPlayerGrenadeStates[id] = 0;
        }
        set_pev(id, pev_viewmodel2, szGrenadeModels[iPlayerGrenadeStates[id]]);
        set_user_weaponanim(id, GRENADE_DRAW_ANIM);
    }
    return FMRES_IGNORED;  
}


public f_HamWeaponReload(wid){
    // НЕ РАБОТАЕТ!
    client_print(0,print_chat,"Weapon id reload: %d",wid)
 
}
 
Решение
Делал что-то подобное давно (тоже через FM_CmdStart).

C++:
public Forward_CmdStart(id, uc_handle, seed) {
    static bool: bUseKey[MAX_PLAYERS + 1];
    
    static bitButtons;
    bitButtons = get_uc(uc_handle, UC_Buttons)

    if(bitButtons & IN_ATTACK2) {
        if(!bUseKey[id]) {
            new iActiveItem = get_member(id, m_pActiveItem);

            if(!is_nullent(iActiveItem)) {
                new iWeaponId = get_member(iActiveItem, m_iId);
                if(iWeaponId == CSW_HEGRENADE || iWeaponId == CSW_FLASHBANG) {
                    new iType = p_TypeGrenade[id][iWeaponId];

                    if(++iType >= sizeof(szExpName)) {
                        iType = 0;
                    }

                    p_TypeGrenade[id][iWeaponId] =...
Я обычно в похожих ситуациях просто сохранял gametime, в которое начала проигрываться анимация, и при последующих вызовах чекал по длительности анимации, завершилась ли она, если нет, то блочим событие смены модели или вызова анимации.
 
@Glaster, попробуй хукнуть ItemPostFrame для гранаты и там повторить логику отлова Reload.
 
Делал что-то подобное давно (тоже через FM_CmdStart).

C++:
public Forward_CmdStart(id, uc_handle, seed) {
    static bool: bUseKey[MAX_PLAYERS + 1];
    
    static bitButtons;
    bitButtons = get_uc(uc_handle, UC_Buttons)

    if(bitButtons & IN_ATTACK2) {
        if(!bUseKey[id]) {
            new iActiveItem = get_member(id, m_pActiveItem);

            if(!is_nullent(iActiveItem)) {
                new iWeaponId = get_member(iActiveItem, m_iId);
                if(iWeaponId == CSW_HEGRENADE || iWeaponId == CSW_FLASHBANG) {
                    new iType = p_TypeGrenade[id][iWeaponId];

                    if(++iType >= sizeof(szExpName)) {
                        iType = 0;
                    }

                    p_TypeGrenade[id][iWeaponId] = iType;
                    client_print(id, print_center, "Mode: %s", szExpName[iType]);
                }
            }
        }
        bUseKey[id] = true;
    }
    else {
        bUseKey[id] = false;
    }
    
    return FMRES_IGNORED;
}

Брал метод от старого плагина для зомби мода. Может понадобиться. Там есть реализация и "проверка" на зажатие кнопки.
 

Вложения

Решение
Код:
public plugin_init() {
    RegisterHookChain(RG_CBasePlayer_ImpulseCommands, "@CBasePlayer_ImpulseCommands", false);
}

@CBasePlayer_ImpulseCommands(id) {
    if (get_member(id, m_afButtonPressed) & IN_RELOAD)
        //
}
 
Код:
public plugin_init() {
    RegisterHookChain(RG_CBasePlayer_ImpulseCommands, "@CBasePlayer_ImpulseCommands", false);
}

@CBasePlayer_ImpulseCommands(id) {
    if (get_member(id, m_afButtonPressed) & IN_RELOAD)
        //
}
У его HL
К сожалению там реапи не работает
 
PM_Move для чтения кнопок, get_ucmd(get_pmove(pm_cmd), ucmd_buttons) & IN_USE, а для определения гранаты в руках, чтобы инициализировать триггер register_event("CurWeapon", "event_curweapon", "be", "1=1");

Код:
RegisterHookChain(RG_PM_Move, "PM_Move_Post", true);

register_event("CurWeapon", "event_curweapon", "be", "1=1");

new bool:gb_flag_HE[MAX_PLAYER + 1], bool: gb_flag_old[MAX_PLAYER + 1];

public event_curweapon(const id) {

    new s_weapon_name[32];
    get_weaponname(read_data(2), s_weapon_name, charsmax(s_weapon_name));
    client_print(id, print_chat, "%s", s_weapon_name);

    // Для нужного класса "weapon_hegrenade"
    gb_flag_HE[id] = strcmp(s_weapon_name, "weapon_hegrenade", true) == 0; // или read_data(2) == CSW_HEGRENADE

}


public PM_Move_Post(const id) {
  
    new bool:b_flag = get_ucmd(get_pmove(pm_cmd), ucmd_buttons) & IN_USE;

    if (gb_flag_HE[id] && !gb_flag_old[id] && b_flag) {
      
        // Делаем что нужно....
      
    }
  
    gb_flag_old[id] = b_flag;
}
 

Кто просматривает тему

Назад
Верх