ReAPI 5.24 + m_signals = 0

Сообщения
401
Реакции
113
Помог
2 раз(а)
Здравствуйте!

После обновления до ReAPI 5.24 перестала работать (а может и не работала) стоковая функция rg_get_user_buyzone(), не знаю кто ее автор, но суть сводится к получению 2 ячеек данных:

Код:
new i_signals[UnifiedSignals];
get_member(id, m_signals, i_signals);
return bool:(SignalState:i_signals[US_State] & SIGNAL_BUY);
Я пытаюсь читать эти данные в RG_CBasePlayer_OnSpawnEquip (Post). В обоих ячейках (UnifiedSignals = 2) всегда 0.

Подскажите, пожалуйста, что я делаю не так? Сейчас буду проверять работу стоковой функции cs_get_user_buyzone()...
 
Последнее редактирование:
Сообщения
401
Реакции
113
Помог
2 раз(а)
Vaqtincha, эмм... А есть какое-то событие для этого момента?

UPD: Стоковая cs_get_user_buyzone() работает корректно, это какой-то косяк ReAPI 5.24...
 
Сообщения
657
Реакции
562
Предупреждения
8
Помог
9 раз(а)
Refresh, а зачем надо проверять именно при спавне? Через таск 0.6 сек вызвать функцию.
 
Сообщения
401
Реакции
113
Помог
2 раз(а)
Vaqtincha, чтобы пересчитать и выдать оружие. Все эти магические 0.5-0.6 секунд выглядят как костыль... Пойду смотреть что там в ReAPI :sad: В 5.21, скорее всего, это все работало...
 
Сообщения
1,698
Реакции
1,510
Помог
26 раз(а)
Refresh, сигнал всегда так работал. Если надо мгновенно, то проверь нахождение игрока в энтити байзоны.
 
Сообщения
657
Реакции
562
Предупреждения
8
Помог
9 раз(а)
Сообщения
401
Реакции
113
Помог
2 раз(а)
Хмм... все оказалось еще интереснее...:wacko: оба варианта то работают, на некоторых картах в некоторых раундах, то нет... увеличим задержку чтения с 0.1 до 0.5 сек...

UPD: Заработали оба варианта...:swoon2:
 
Последнее редактирование:
Сообщения
401
Реакции
113
Помог
2 раз(а)
Refresh, сигнал всегда так работал. Если надо мгновенно, то проверь нахождение игрока в энтити байзоны.
Что-то вроде entity_intersects ? Или есть еще какие-то функции?

UPD: Нашел в регейм... (pSpot->pev->origin - pPlayer->pev->origin).Length() < 200.0f Спасибо :good2:Пойду тестить...
 
Последнее редактирование:
Сообщения
401
Реакции
113
Помог
2 раз(а)
Nordic Warrior, это я уже попробовал... задержка около 1 сек на buyzone, мне нужно что-то очень быстрое :sad: RG_CBasePlayer_OnSpawnEquip (Post)+ 0.5-0.6 сек не гарантирует что сигнал будет активирован... в 10% случаях все равно там 0, хотя игрок в зоне покупки... хрень какая-то.
 
Сообщения
657
Реакции
562
Предупреждения
8
Помог
9 раз(а)
Зачем эти проверки если игрок по умолчанию спавниться на зоне покупки (если это не какой-нибудь дм) . Зачем так заморачиваться.
 
Сообщения
401
Реакции
113
Помог
2 раз(а)
Vaqtincha, его могут воскресить где угодно... нужно не дать ему повторно какие-то предметы, например, комплект гранат..
 
Сообщения
657
Реакции
562
Предупреждения
8
Помог
9 раз(а)
Refresh, ну для предотвращения повторной выдачи есть другие способы
 
Сообщения
401
Реакции
113
Помог
2 раз(а)
Спасибо всем за помощь... Если кому-то из новичков, вроде меня, нужен рабочий вариант acs_get_user_buyzone():

Код:
#include <amxmodx>
#include <amxmisc>
#include <reapi>
#include <engine>

#define ACS_MAX_BUFFER_SIZE         256
#define ACS_MAX_NAME_LENGTH         32
#define ACS_MAX_NAME_ML_LENGTH      64
#define ACS_MAX_INT_STR_LENGTH      12
#define ACS_MAX_RANDOM_ITEM         20
#define is_valid_team(%0)           (TEAM_TERRORIST <= (tm_player = get_member(%0, m_iTeam)) <= TEAM_CT)

new g_ent_bz[2], Float:gf_bz_mins[2][3], Float:gf_bz_maxs[2][3];

public plugin_init() {
    register_plugin("ACS Test BuyZone", "1.0.0", "DEV-CS.RU");
    register_concmd("bz_test", "cmd_test")
    RegisterHookChain(RG_CBasePlayer_OnSpawnEquip, "CBasePlayer_OnSpawnEquip_Post", true);
    new tm, ent = -1;
    while ((ent = rg_find_ent_by_class(ent, "func_buyzone", true))) {
        tm = clamp(get_entvar(ent, var_team) - 1, 0, 1);
        g_ent_bz[tm] = ent;
        get_entvar(ent, var_mins, gf_bz_mins[tm]);
        get_entvar(ent, var_maxs, gf_bz_maxs[tm]);
        log_acs("BUY_ZONE_MINS( %2d ): team = %d", ent, tm);
        log_acs("BUY_ZONE_MINS( %2d ): X = %f, Y = %f, Z = %f", ent, gf_bz_mins[tm][0], gf_bz_mins[tm][1], gf_bz_mins[tm][2]);
        log_acs("BUY_ZONE_MAXS( %2d ): X = %f, Y = %f, Z = %f", ent, gf_bz_maxs[tm][0], gf_bz_maxs[tm][1], gf_bz_maxs[tm][2]);
    }
}

public CBasePlayer_OnSpawnEquip_Post(id, bool:add_default, bool:equip_game) {
    acs_test_buyzone(id);
}

public cmd_test(const id) {
    acs_test_buyzone(id);
    return PLUGIN_HANDLED;
}

public acs_test_buyzone(const id) {
    if (is_user_connected(id))
        if (acs_get_user_buyzone(id))
            client_print_color(id, print_team_default, "^3BUYZONE DETECTED!!!");
        else
            client_print_color(id, print_team_red, "^3BUYZONE NOT FOUND!!!");
}

public bool:acs_get_user_buyzone(const id) {
    new bool:b_result, TeamName:tm_player, Float:f_pl_orig[3];
    if (is_user_connected(id) && is_valid_team(id)) {
        get_entvar(id, var_origin, f_pl_orig);
        log_acs("PLAYER_ORIG( %2d ): X = %f, Y = %f, Z = %f", id, f_pl_orig[0], f_pl_orig[1], f_pl_orig[2]);
        b_result = entity_intersects(g_ent_bz[any:tm_player - 1], id);
    }
    return b_result;
}

stock log_acs(const message[], any:...) {
    static _PLUGIN_NAME[ACS_MAX_NAME_LENGTH];
    static _LOGPATH[PLATFORM_MAX_PATH];
    static s_log_data[4 * ACS_MAX_BUFFER_SIZE];
    //if (CVAR[LOG]) {
    if (!_PLUGIN_NAME[0]) {
        get_plugin(-1, _PLUGIN_NAME, charsmax(_PLUGIN_NAME));
        replace(_PLUGIN_NAME, charsmax(_PLUGIN_NAME), ".amxx", "");
    }
    if (!_LOGPATH[0]) {
        get_localinfo("amxx_logs", _LOGPATH, charsmax(_LOGPATH));
        format(_LOGPATH, charsmax(_LOGPATH), "%s/%s.log", _LOGPATH, _PLUGIN_NAME);
    }
    vformat(s_log_data, charsmax(s_log_data), message, 2);
    acs_log_to_file(_LOGPATH, s_log_data);
    //}
}

stock acs_log_to_file(const filename[], const message[], const bool:is_buffered = false) {
    static _MOD_NAME[ACS_MAX_NAME_LENGTH];
    static _AMXX_VERSION[ACS_MAX_NAME_LENGTH];
    static h_file, bool:b_file_exists, s_date[ACS_MAX_NAME_LENGTH];
    if (filename[0] && message[0]) {
        if (!_MOD_NAME[0])
            get_modname(_MOD_NAME, charsmax(_MOD_NAME));
        if (!_AMXX_VERSION[0])
            get_amxx_verstring(_AMXX_VERSION, charsmax(_AMXX_VERSION));
        format_time(s_date, charsmax(s_date), "%m/%d/%Y - %H:%M:%S");
        b_file_exists = h_file ? true : bool:file_exists(filename);
        if (!h_file)
            h_file = fopen(filename, "at");
        if (h_file) {
            if (!b_file_exists)
                fprintf(h_file, "L %s: Log file started (file ^"%s^") (game ^"%s^") (amx ^"%s^")^n", s_date, filename, _MOD_NAME, _AMXX_VERSION);
            fprintf(h_file, "L %s: %s^n", s_date, message);
        } else
            log_error(AMX_ERR_GENERAL, "[ACS_WCS] ERROR: acs_log_to_file(), can't open file %s", filename);
    }
    if (h_file && !is_buffered) {
        fclose(h_file);
        h_file = 0;
    }
}
 
Последнее редактирование:
Сообщения
401
Реакции
113
Помог
2 раз(а)
Предыдущий вариант, работает не всегда и не везде.... Целый день ушел на разбор и исправление всех ошибок:
  • Оказалось, что объектов "func_buyzone" может быть больше 2...:scratch_one-s_head:
  • Оказалось, что объектов "func_buyzone" может вообще не быть... Например, de_inferno. И регейм проверяет расстояние от игрока до ближайшей точки спавна команды, если < 200 - в зоне закупки.
Исправленный вариант:
Код:
#include <amxmodx>
#include <amxmisc>
#include <reapi>
#include <engine>

#define ACS_MAX_BUYZONES            20
#define ACS_MAX_BUFFER_SIZE         256
#define ACS_MAX_NAME_LENGTH         32
#define ACS_MAX_NAME_ML_LENGTH      64
#define ACS_MAX_INT_STR_LENGTH      12
#define ACS_MAX_RANDOM_ITEM         20
#define is_valid_team(%0)           (TEAM_TERRORIST <= (tm_player = get_member(%0, m_iTeam)) <= TEAM_CT)

enum _:ACS_BUYZONES {
    bz_ent[ACS_MAX_BUYZONES],
    bz_count
}

new g_buyzone[2][ACS_BUYZONES];
new bool:gb_buyzone_exist;

public plugin_init() {
    register_plugin("ACS Test BuyZone", "1.0.1", "DEV-CS.RU");
    register_concmd("bz_test", "cmd_test")
    RegisterHookChain(RG_CBasePlayer_OnSpawnEquip, "CBasePlayer_OnSpawnEquip_Post", true);
    new tm, ent = -1;
    if ((gb_buyzone_exist = get_member_game(m_bMapHasBuyZone))) {
        new Float:f_bz_mins[2][3], Float:f_bz_maxs[2][3];
        while ((ent = rg_find_ent_by_class(ent, "func_buyzone", true))) {
            tm = clamp(get_entvar(ent, var_team) - 1, 0, 1);
            g_buyzone[tm][bz_ent][g_buyzone[tm][bz_count]++] = ent;
            get_entvar(ent, var_mins, f_bz_mins[tm]);
            get_entvar(ent, var_maxs, f_bz_maxs[tm]);
            log_acs("BUY_ZONE_EXIST ( %2d ): team = %d", ent, tm);
            log_acs("BUY_ZONE_MINS( %2d ): X = %f, Y = %f, Z = %f", ent, f_bz_mins[tm][0], f_bz_mins[tm][1], f_bz_mins[tm][2]);
            log_acs("BUY_ZONE_MAXS( %2d ): X = %f, Y = %f, Z = %f", ent, f_bz_maxs[tm][0], f_bz_maxs[tm][1], f_bz_maxs[tm][2]);
        }
    } else {
        new spawn_class[2][32] = {
            "info_player_deathmatch",
            "info_player_start"
        };
        new Float:f_bz_origin[2][3];
        for (tm = 0; tm < 2; tm++) {
            while ((ent = rg_find_ent_by_class(ent, spawn_class[tm], true))) {
                g_buyzone[tm][bz_ent][g_buyzone[tm][bz_count]++] = ent;
                get_entvar(ent, var_origin, f_bz_origin[tm]);
                log_acs("BUY_ZONE_NO_EXIST ( %2d ): team = %d", ent, tm);
                log_acs("BUY_ZONE_ORIGIN( %2d ): X = %f, Y = %f, Z = %f", ent, f_bz_origin[tm][0], f_bz_origin[tm][1], f_bz_origin[tm][2]);
            }
        }
    }
    log_acs("BUY_ZONE_COUNT: TT = %d, CT = %d", g_buyzone[0][bz_count], g_buyzone[1][bz_count]);
}

public CBasePlayer_OnSpawnEquip_Post(id, bool:add_default, bool:equip_game) {
    acs_test_buyzone(id);
}

public cmd_test(const id) {
    acs_test_buyzone(id);
    return PLUGIN_HANDLED;
}

public acs_test_buyzone(const id) {
    if (acs_get_user_buyzone(id))
        client_print_color(id, print_team_default, "BUYZONE DETECTED!!!");
    else
        client_print_color(id, print_team_red, "BUYZONE NOT FOUND!!!");
}

public bool:acs_get_user_buyzone(const id) {
    new bool:b_result, TeamName:tm_player, Float:f_pl_orig[3], Float:f_spwn_orig[3];
    new i_i;
    if (is_user_connected(id) && is_valid_team(id)) {
        get_entvar(id, var_origin, f_pl_orig);
        log_acs("PLAYER_ORIG( %2d ): X = %f, Y = %f, Z = %f", id, f_pl_orig[0], f_pl_orig[1], f_pl_orig[2]);
        for (i_i = 0; i_i < g_buyzone[any:tm_player - 1][bz_count]; i_i++) {
            if (gb_buyzone_exist) {
                if ((b_result |= entity_intersects(g_buyzone[any:tm_player - 1][bz_ent][i_i], id)))
                    break;
            } else {
                get_entvar(g_buyzone[any:tm_player - 1][bz_ent][i_i], var_origin, f_spwn_orig);   
                if ((b_result |= get_distance_f(f_pl_orig, f_spwn_orig) < 200.0))
                    break;
            }
        }
    }
    return b_result;
}

stock log_acs(const message[], any:...) {
    static _PLUGIN_NAME[ACS_MAX_NAME_LENGTH];
    static _LOGPATH[PLATFORM_MAX_PATH];
    static s_log_data[4 * ACS_MAX_BUFFER_SIZE];
    //if (CVAR[LOG]) {
    if (!_PLUGIN_NAME[0]) {
        get_plugin(-1, _PLUGIN_NAME, charsmax(_PLUGIN_NAME));
        replace(_PLUGIN_NAME, charsmax(_PLUGIN_NAME), ".amxx", "");
    }
    if (!_LOGPATH[0]) {
        get_localinfo("amxx_logs", _LOGPATH, charsmax(_LOGPATH));
        format(_LOGPATH, charsmax(_LOGPATH), "%s/%s.log", _LOGPATH, _PLUGIN_NAME);
    }
    vformat(s_log_data, charsmax(s_log_data), message, 2);
    acs_log_to_file(_LOGPATH, s_log_data);
    //}
}

stock acs_log_to_file(const filename[], const message[], const bool:is_buffered = false) {
    static _MOD_NAME[ACS_MAX_NAME_LENGTH];
    static _AMXX_VERSION[ACS_MAX_NAME_LENGTH];
    static h_file, bool:b_file_exists, s_date[ACS_MAX_NAME_LENGTH];
    if (filename[0] && message[0]) {
        if (!_MOD_NAME[0])
            get_modname(_MOD_NAME, charsmax(_MOD_NAME));
        if (!_AMXX_VERSION[0])
            get_amxx_verstring(_AMXX_VERSION, charsmax(_AMXX_VERSION));
        format_time(s_date, charsmax(s_date), "%m/%d/%Y - %H:%M:%S");
        b_file_exists = h_file ? true : bool:file_exists(filename);
        if (!h_file)
            h_file = fopen(filename, "at");
        if (h_file) {
            if (!b_file_exists)
                fprintf(h_file, "L %s: Log file started (file ^"%s^") (game ^"%s^") (amx ^"%s^")^n", s_date, filename, _MOD_NAME, _AMXX_VERSION);
            fprintf(h_file, "L %s: %s^n", s_date, message);
        } else
            log_error(AMX_ERR_GENERAL, "[ACS_WCS] ERROR: acs_log_to_file(), can't open file %s", filename);
    }
    if (h_file && !is_buffered) {
        fclose(h_file);
        h_file = 0;
    }
}
 
Последнее редактирование:
Сообщения
112
Реакции
14
Помог
1 раз(а)
Сообщения
401
Реакции
113
Помог
2 раз(а)
avice, вообще, я получил рекомендацию "Если надо мгновенно, то проверь нахождение игрока в энтити байзоны"... и выглядела она (рекомендация) по трудоемкости, как нечто однострочное :rofl: на 5 мин работы. Но я учусь...
 
Последнее редактирование:
Сообщения
401
Реакции
113
Помог
2 раз(а)
Это, конечно, немного сложнее таймера на 0,6-0,8 сек....:pardon:Зато сколько опыта и эмоций :boast:

Код:
#define ACS_MAX_BUYZONES            20
#define is_valid_player(%0)         is_user_connected(%0)
#define is_valid_team(%0)           (TEAM_TERRORIST <= (tm_player = get_member(%0, m_iTeam)) <= TEAM_CT)

enum _:ACS_WCS_BUYZONES {
    bz_ent[ACS_MAX_BUYZONES],
    bz_count
}

new g_buyzone[2][ACS_WCS_BUYZONES];
new bool:gb_buyzone_exist;

// Вызвать в plugin_init() или plugin_cfg()
stock acs_get_ent_buyzone() {
    new tm, i_ent = -1;
    if ((gb_buyzone_exist = get_member_game(m_bMapHasBuyZone))) {
        while ((i_ent = rg_find_ent_by_class(i_ent, "func_buyzone", true))) {
            tm = clamp(get_entvar(i_ent, var_team) - 1, 0, 1);
            g_buyzone[tm][bz_ent][g_buyzone[tm][bz_count]++] = i_ent;
        }
    } else {
        new spawn_class[2][32] = { "info_player_deathmatch", "info_player_start" };
        for (tm = 0; tm < 2; tm++)
            while ((i_ent = rg_find_ent_by_class(i_ent, spawn_class[tm], true)))
                g_buyzone[tm][bz_ent][g_buyzone[tm][bz_count]++] = i_ent;
    }
}

// Проверка нахождения игрока в зоне закупки
stock bool:acs_get_user_buyzone(const id) {
    static i_i, TeamName:tm_player, Float:f_pl_orig[3], Float:f_spwn_orig[3];
    if (is_valid_player(id) && is_valid_team(id) && is_user_alive(id)) {
        if (!gb_buyzone_exist)
            get_entvar(id, var_origin, f_pl_orig);
        for (i_i = 0; i_i < g_buyzone[any:tm_player - 1][bz_count]; i_i++)
            if (gb_buyzone_exist) {
                if (entity_intersects(g_buyzone[any:tm_player - 1][bz_ent][i_i], id))
                    return true;
            } else {
                get_entvar(g_buyzone[any:tm_player - 1][bz_ent][i_i], var_origin, f_spwn_orig);
                if (get_distance_f(f_pl_orig, f_spwn_orig) < 200.0)
                    return true;
            }
    }
    return false;
}
 
Последнее редактирование:

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

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