Исключение ненужных режимов наблюдения

Сообщения
474
Реакции
249
Помог
6 раз(а)
Текущая задача: Пропускать режимы наблюдения OBS_MAP_FREE и OBS_MAP_CHASE.

Как-то давно интересовался, как это делается, на что получил такой ответ:
в реапи есть хукы
RG_GetForceCamera
RG_CBasePlayer_Observer_IsValidTarget
RG_CBasePlayer_StartObserver
Смотрите что они делают и меняйте под себя

Конкретно ваш случай тут. За мод отвечает var_iuser1 (pev_iuser1) и может принимать следующые значения
Код:
#define OBS_NONE         0
#define OBS_CHASE_LOCKED 1
#define OBS_CHASE_FREE   2
#define OBS_ROAMING      3
#define OBS_IN_EYE       4
#define OBS_MAP_FREE     5
#define OBS_MAP_CHASE    6

Сейчас взялся за реализацию. Как я понял, из трёх предложенных, тут подходит хук RG_GetForceCamera.
Дополнительные вопросы:
  1. Нужна-ли в Pre проверка мембера m_afButtonPressed на то, что нажата именно кнопка переключения режима?
  2. Каким образом происходит пропуск ненужного режима?
Код:
switch(get_entvar(pPlayer, var_iuser1)) {
    case OBS_MAP_FREE, OBS_MAP_CHASE: {
        ???
    }
}
 
Сообщения
474
Реакции
249
Помог
6 раз(а)
Есть догадки, что можно не пропускать, а подменять режим. При переходе в спектра выставлять, например, OBS_ROAMING, а при нажатии на IN_JUMP переключать на нужные и суперцидить. Но опять же вопрос, нужна-ли проверка на IN_JUMP? Или хук RG_GetForceCamera именно такое переключение и ловит?
 
Сообщения
474
Реакции
249
Помог
6 раз(а)
Добрался до тест серва и протестил свои догадки:
Код:
#include <amxmodx>
#include <reapi>

public plugin_init() {
    register_plugin("Test", "1", "CHEL74")
    
    RegisterHookChain(RG_CBasePlayer_StartObserver, "StartObserver_Post", true)
    RegisterHookChain(RG_GetForceCamera, "GetForceCamera_Pre")
}

public StartObserver_Post(pObserver) {
    new pPlayers[MAX_PLAYERS], iPlayersNum
    get_players(pPlayers, iPlayersNum, "ach")
    
    set_entvar(pObserver, var_iuser1, iPlayersNum > 1 ? OBS_IN_EYE : OBS_ROAMING)
}

public GetForceCamera_Pre(pObserver) {
    set_entvar(pObserver, var_iuser1, get_entvar(pObserver, var_iuser1) == OBS_IN_EYE ? OBS_ROAMING : OBS_IN_EYE)
    
    return HC_SUPERCEDE
}
Тут я оставил только 2 режима: от 1 лица и свободный просмотр (для CSDM). Пока норм работает.
 
Последнее редактирование:
Сообщения
2,721
Реакции
2,997
Помог
60 раз(а)
Наглядная работа с режимами наблюдения.
Код:
#include <amxmodx>
#include <reapi>

const ACCESS_FLAG = ADMIN_BAN;

public plugin_init()
{
    register_plugin("[ReAPI] AdminFreeLook", "1.0", "ReHLDS Team");

    if(!is_regamedll()) {
        set_fail_state("ReGameDLL is not available");
        return;
    }

    RegisterHookChain(RG_GetForceCamera, "GetForceCamera");
    RegisterHookChain(RG_CBasePlayer_Observer_IsValidTarget, "Observer_IsValidTarget");
}

public GetForceCamera(const index)
{
    if (!shouldRunCode())
        return HC_CONTINUE;
    
    if (canFreeLook(index)) {
        SetHookChainReturn(ATYPE_INTEGER, 0);
        return HC_SUPERCEDE;
    }

    return HC_CONTINUE;
}

public Observer_IsValidTarget(const this, const iPlayerIndex, bool:bSameTeam)
{
    if (shouldRunCode())
        return HC_CONTINUE;

    if (!is_user_connected(iPlayerIndex))
        return HC_CONTINUE;

    if (iPlayerIndex == this || get_entvar(iPlayerIndex, var_iuser1) > 0 || (get_entvar(iPlayerIndex, var_effects) & EF_NODRAW) || get_member(iPlayerIndex, m_iTeam) == TEAM_UNASSIGNED)
        return HC_CONTINUE;

    // Don't spec observers or players who haven't picked a class yet
    if (bSameTeam && get_member(iPlayerIndex, m_iTeam) != get_member(this, m_iTeam))
        return HC_CONTINUE;

    if (canFreeLook(iPlayerIndex)) {
        SetHookChainReturn(ATYPE_INTEGER, iPlayerIndex);
        return HC_SUPERCEDE;
    }

    return HC_CONTINUE;
}

stock bool:canFreeLook(const index) {
    return bool:(get_user_flags(index) & ACCESS_FLAG);
}

stock bool:shouldRunCode()
{
    return bool:(Float:get_member_game(m_flFadeToBlackValue) <= 0.0
        && Float:get_member_game(m_flForceCameraValue) > 0.0
        && Float:get_member_game(m_flForceChaseCamValue) > 0.0);
}
 
Сообщения
474
Реакции
249
Помог
6 раз(а)
wopox1337, та я смотрел. Там ведь не то. Там если наблюдатель админ, идёт разблокировка всех режимов. Мне надо только конкретные.

По моему коду выше, судя по всему, хук вызывается чаще, чем я думал) Поэтому добавил всё же условие:
Код:
public GetForceCamera_Pre(pObserver) {
    if(get_member(pObserver, m_afButtonPressed) == IN_JUMP) {
        set_entvar(pObserver, var_iuser1, get_entvar(pObserver, var_iuser1) == OBS_IN_EYE ? OBS_ROAMING : OBS_IN_EYE)
     
        return HC_SUPERCEDE
    }
 
    return HC_CONTINUE
}
Не знаю, достаточно-ли этого. Мб ещё чекать, наблюдатель-ли игрок? Потому что когда бот выходил с сервера, камера перекидывалась на меня и я был недвижимым, но живым при этом.
 
Сообщения
474
Реакции
249
Помог
6 раз(а)
alecsey18, там проблемная реализация, вроде как. Так и не разобрался, как сделать наиболее грамотно.
 

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

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