Не завершается раунд

Статус
В этой теме нельзя размещать новые ответы.

d3m37r4

111111
Сообщения
1,424
Реакции
1,162
Помог
10 раз(а)
Есть следующий код:
Код:
#include <amxmodx>
#include <amxmisc>
#include <reapi>

new const PLUGIN_NAME[]    = "Simple WarmUp Mode";
new const PLUGIN_VERSION[] = "0.2.0b";
new const PLUGIN_AUTHOR[]  = "d3m37r4";

#define RESTRICT_GRENADES                    // Запретить гранаты на разминке
//#define EQUIP_ARMOR_ON_SPAWN                 // Выдавать броню при спавне
#define FREE_WEAPON                          // Бесплатные патроны и оружие из стандартного меню закупки

#if defined EQUIP_ARMOR_ON_SPAWN
    const ARMOR_VALUE = 100;                 // Сколько выдавать игроку AP.
#endif

new const g_SpriteName[] = "suithelmet_full";

const TASK_INDEX = 200;

enum {
    STATUSICON_HIDE,
    STATUSICON_SHOW,
    STATUSICON_FLASH
};

enum CVAR_TYPE {
    OLD_VALUE,
    NEW_VALUE
};

enum PCVARS {
    PCVAR_FREEZETIME,
    PCVAR_ROUNDTIME, 
    PCVAR_BUY_TIME,
    PCVAR_ROUND_INFINITE,
    PCVAR_FORCERESPAWN,
    PCVAR_REFILL_BPAMMO,
    PCVAR_RESPAWN_IMMUNITYTIME,
    PCVAR_ITEM_STAYTIME,
    PCVAR_REFILL_BPAMMO
};

enum CVARS {
    CVAR_FREEZETIME,
    Float:CVAR_ROUNDTIME, 
    CVAR_BUY_TIME,
    CVAR_ROUND_INFINITE,
    Float:CVAR_FORCERESPAWN,
    CVAR_REFILL_BPAMMO,
    CVAR_RESPAWN_IMMUNITYTIME,
    CVAR_ITEM_STAYTIME,
    CVAR_REFILL_BPAMMO
};

enum _:HOOK_CHAINS {
#if defined RESTRICT_GRENADES     
    HookChain:HAS_RESTRICT_ITEM_PRE,
#endif   
#if defined EQUIP_ARMOR_ON_SPAWN
    HookChain:ON_SPAWN_EQUIP_POST,
#endif
    HookChain:DROP_PLAYER_ITEM_PRE,
    HookChain:GIVEC4_PRE,
    HookChain:BUY_WEAPON_PRE,
    HookChain:BUY_WEAPON_POST,
    HookChain:SET_SPAWN_PROTECT_POST,
    HookChain:REMOVE_SPAWN_PROTECT_POST
};

#if defined RESTRICT_GRENADES
    new ItemID:g_RestrictGrenades[] = {
        ITEM_HEGRENADE,
        ITEM_SMOKEGRENADE,
        ITEM_FLASHBANG,
        ITEM_NONE
    };
    new g_BitsItemsBlocked;
#endif

#if defined FREE_WEAPON
    enum COST_TYPE {
        WEAPON_COST,
        CLIP_COST
    };
    new WeaponIdType:g_DefaultWeapCost[WeaponIdType][COST_TYPE];
#endif

new bool:g_WarmupIsStarted;

new g_Pointer[PCVARS];
new g_Cvar[CVAR_TYPE][CVARS];
new HookChain:g_HookChain[HOOK_CHAINS];

public plugin_init() {
    register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR);

    RegisterHookChain(RG_RoundEnd, "HC_RoundEnd", true);

    DisableHookChain(g_HookChain[GIVEC4_PRE] = RegisterHookChain(RG_CSGameRules_GiveC4, "HC_CSGameRules_GiveC4_Pre", false));
    DisableHookChain(g_HookChain[DROP_PLAYER_ITEM_PRE] = RegisterHookChain(RG_CBasePlayer_DropPlayerItem, "HC_CBasePlayer_DropPlayerItem_Pre", false));
    DisableHookChain(g_HookChain[BUY_WEAPON_PRE] = RegisterHookChain(RG_BuyWeaponByWeaponID, "HC_BuyWeaponByWeaponID_Pre", false));
    DisableHookChain(g_HookChain[BUY_WEAPON_POST] = RegisterHookChain(RG_BuyWeaponByWeaponID, "HC_BuyWeaponByWeaponID_Post", true));
    DisableHookChain(g_HookChain[SET_SPAWN_PROTECT_POST] = RegisterHookChain(RG_CBasePlayer_SetSpawnProtection, "HC_CBasePlayer_SetSpawnProtection_Post", true));
    DisableHookChain(g_HookChain[REMOVE_SPAWN_PROTECT_POST] = RegisterHookChain(RG_CBasePlayer_RemoveSpawnProtection, "HC_CBasePlayer_RemoveSpawnProtection_Post", true));

#if defined EQUIP_ARMOR_ON_SPAWN
    DisableHookChain(g_HookChain[ON_SPAWN_EQUIP_POST] = RegisterHookChain(RG_CBasePlayer_OnSpawnEquip, "HC_CBasePlayer_OnSpawnEquip_Post", true));
#endif

#if defined RESTRICT_GRENADES
    DisableHookChain(g_HookChain[HAS_RESTRICT_ITEM_PRE] = RegisterHookChain(RG_CBasePlayer_HasRestrictItem, "HC_CBasePlayer_HasRestrictItem_Pre", false));
    for(new i; g_RestrictGrenades[i] != ITEM_NONE; i++) {
        g_BitsItemsBlocked |= BIT(any:g_RestrictGrenades[i]);
    }
#endif

    register_clcmd("warmup_start", "CmdWarmUpStart");
    register_clcmd("warmup_stop", "CmdWarmUpStop");

#if defined FREE_WEAPON
    for(new WeaponIdType:weapon = WEAPON_P228; weapon <= WEAPON_P90; weapon++) {
    #if !defined RESTRICT_GRENADES
        if(weapon == WEAPON_C4 || weapon == WEAPON_HEGRENADE || weapon == WEAPON_SMOKEGRENADE || weapon == WEAPON_FLASHBANG || weapon == WEAPON_KNIFE) {
    #else
        if(weapon == WEAPON_C4 || weapon == WEAPON_KNIFE) {
    #endif
            continue;
        }

        g_DefaultWeapCost[weapon][WEAPON_COST] = rg_get_weapon_info(weapon, WI_COST);
        g_DefaultWeapCost[weapon][CLIP_COST] = rg_get_weapon_info(weapon, WI_CLIP_COST);
    }
#endif

    GetCvarsPointers();
}

public HC_RoundEnd() {
    log_amx("HC_RoundEnd")
}

public TaskWarmupMsg() {
    client_print(0, print_center, "Разминочный режим DeathMatch!");
}

public CmdWarmUpStart(id) {
    if(!g_WarmupIsStarted) {
        set_task_ex(10.0, "TaskWarmupMsg", .id = TASK_INDEX, .flags = SetTask_Repeat);
        log_amx("[%s] Warmup mode started!", PLUGIN_NAME);

        rg_round_end(1.5, WINSTATUS_DRAW, ROUND_NONE, "Разминочный режим DeathMatch запущен!", _, false);

        SetCvarsValues(.valueType = NEW_VALUE);

        //set_member_game(m_bCompleteReset, false);
        //set_member_game(m_bGameStarted, false);

        Toggle_Forwards(.enable = true);
    #if defined FREE_WEAPON
        SetAllFreeWeapon(.freeWeapon = true);
    #endif

    g_WarmupIsStarted = true;
    }
}

public CmdWarmUpStop(id) {
    if(g_WarmupIsStarted) {
        remove_task(TASK_INDEX);
        log_amx("[%s] Warmup mode finished!", PLUGIN_NAME);

        rg_round_end(1.5, WINSTATUS_DRAW, ROUND_GAME_RESTART, "Разминочный режим DeathMatch отключен!^rПриготовьтесь к бою, игра началась!", _, true);

        SetCvarsValues(.valueType = OLD_VALUE);

        //set_member_game(m_bCompleteReset, true);
        //set_member_game(m_bGameStarted, true);

        Toggle_Forwards(.enable = false);

    #if defined FREE_WEAPON
        SetAllFreeWeapon(.freeWeapon = false);
    #endif

        g_WarmupIsStarted = false;
        //pause("d");
    }
}

public HC_BuyWeaponByWeaponID_Pre() {
    DisableHookChain(g_HookChain[DROP_PLAYER_ITEM_PRE]);
}

public HC_BuyWeaponByWeaponID_Post() {
    EnableHookChain(g_HookChain[DROP_PLAYER_ITEM_PRE]);
}

public HC_CBasePlayer_DropPlayerItem_Pre(const id) {
    client_print(id, print_center, /*"#Weapon_Cannot_Be_Dropped"*/"Данный предмет нельзя выбросить!");
    SetHookChainReturn(ATYPE_INTEGER, 1);
    return HC_SUPERCEDE;
}

// Как вариант выставлять мемберу m_bMapHasBombTarget значение false
// https://github.com/s1lentq/ReGameDLL_CS/blob/e924a266b047d4bc866cf1e66ec9030b33fc85f7/regamedll/dlls/multiplay_gamerules.cpp#L1967
public HC_CSGameRules_GiveC4_Pre() {
    return HC_SUPERCEDE;
}

public HC_CBasePlayer_SetSpawnProtection_Post(const id, Float:time) {
    SendStatusIcon(id, .icon = g_SpriteName, .status = STATUSICON_FLASH);
}

public HC_CBasePlayer_RemoveSpawnProtection_Post(const id) {
    SendStatusIcon(id, .icon = g_SpriteName, .status = STATUSICON_HIDE);
}

#if defined RESTRICT_GRENADES
public HC_CBasePlayer_HasRestrictItem_Pre(const id, const ItemID:item, ItemRestType:type) {
    if(g_BitsItemsBlocked & BIT(any:item)) {       
        client_print(id, print_center, "Данный предмет запрещен в разминочное время!");
        SetHookChainReturn(ATYPE_INTEGER, 1);

        return HC_SUPERCEDE;
    }

    return HC_CONTINUE;
}
#endif

#if defined EQUIP_ARMOR_ON_SPAWN
public HC_CBasePlayer_OnSpawnEquip_Post(const id) {
    if(is_user_connected(id)) {
        new ArmorType:armorType;
        if(rg_get_user_armor(id, armorType) < ARMOR_VALUE || armorType != ARMOR_VESTHELM) {
            rg_set_user_armor(id, min(ARMOR_VALUE, 255), ARMOR_VESTHELM);                                                       
        }
    }
}
#endif

#if defined FREE_WEAPON
SetAllFreeWeapon(bool:freeWeapon = true) {
    for(new WeaponIdType:weapon = WEAPON_P228; weapon <= WEAPON_P90; weapon++) {
    #if !defined RESTRICT_GRENADES
        if(weapon == WEAPON_C4 || weapon == WEAPON_HEGRENADE || weapon == WEAPON_SMOKEGRENADE || weapon == WEAPON_FLASHBANG || weapon == WEAPON_KNIFE)
            continue;
    #else
        if(weapon == WEAPON_C4 || weapon == WEAPON_KNIFE)
            continue;
    #endif
        rg_set_weapon_info(weapon, WI_COST, freeWeapon ? 0 : g_DefaultWeapCost[weapon][WEAPON_COST]);
        rg_set_weapon_info(weapon, WI_CLIP_COST, freeWeapon ? 0 : g_DefaultWeapCost[weapon][CLIP_COST]);         
    }
}
#endif

GetCvarsPointers() {
    g_Pointer[PCVAR_FREEZETIME] = get_cvar_pointer("mp_freezetime");
    g_Pointer[PCVAR_ROUNDTIME] = get_cvar_pointer("mp_roundtime"); 
    g_Pointer[PCVAR_BUY_TIME] = get_cvar_pointer("mp_buytime");
    g_Pointer[PCVAR_ROUND_INFINITE] = get_cvar_pointer("mp_round_infinite");
    g_Pointer[PCVAR_FORCERESPAWN] = get_cvar_pointer("mp_forcerespawn");
    g_Pointer[PCVAR_REFILL_BPAMMO] = get_cvar_pointer("mp_refill_bpammo_weapons");
    g_Pointer[PCVAR_RESPAWN_IMMUNITYTIME] = get_cvar_pointer("mp_respawn_immunitytime");
    g_Pointer[PCVAR_ITEM_STAYTIME] = get_cvar_pointer("mp_item_staytime");
    g_Pointer[PCVAR_REFILL_BPAMMO] = get_cvar_pointer("mp_refill_bpammo_weapons");
}

SetCvarsValues(CVAR_TYPE:valueType) {
    if(valueType == NEW_VALUE) {
        g_Cvar[NEW_VALUE][CVAR_ROUNDTIME] = 1.50;
        g_Cvar[NEW_VALUE][CVAR_FORCERESPAWN] = 1.0;       
        g_Cvar[NEW_VALUE][CVAR_FREEZETIME] = 0;
        g_Cvar[NEW_VALUE][CVAR_BUY_TIME] = -1;
        g_Cvar[NEW_VALUE][CVAR_ROUND_INFINITE] = 1;
        g_Cvar[NEW_VALUE][CVAR_REFILL_BPAMMO] = 1;
        g_Cvar[NEW_VALUE][CVAR_RESPAWN_IMMUNITYTIME] = 3;
        g_Cvar[NEW_VALUE][CVAR_ITEM_STAYTIME] = 0;
        g_Cvar[NEW_VALUE][CVAR_REFILL_BPAMMO] = 3;

        g_Cvar[OLD_VALUE][CVAR_ROUNDTIME] = get_pcvar_float(g_Pointer[PCVAR_ROUNDTIME]);
        g_Cvar[OLD_VALUE][CVAR_FORCERESPAWN] = get_pcvar_float(g_Pointer[PCVAR_FORCERESPAWN]);
        g_Cvar[OLD_VALUE][CVAR_FREEZETIME] = get_pcvar_num(g_Pointer[PCVAR_FREEZETIME]); 
        g_Cvar[OLD_VALUE][CVAR_BUY_TIME] = get_pcvar_num(g_Pointer[PCVAR_BUY_TIME]);
        g_Cvar[OLD_VALUE][CVAR_ROUND_INFINITE] = get_pcvar_num(g_Pointer[PCVAR_ROUND_INFINITE]);
        g_Cvar[OLD_VALUE][CVAR_REFILL_BPAMMO] = get_pcvar_num(g_Pointer[PCVAR_REFILL_BPAMMO]);
        g_Cvar[OLD_VALUE][CVAR_RESPAWN_IMMUNITYTIME] = get_pcvar_num(g_Pointer[PCVAR_RESPAWN_IMMUNITYTIME]);
        g_Cvar[OLD_VALUE][CVAR_ITEM_STAYTIME] = get_pcvar_num(g_Pointer[PCVAR_ITEM_STAYTIME]);
        g_Cvar[OLD_VALUE][CVAR_REFILL_BPAMMO] = get_pcvar_num(g_Pointer[PCVAR_REFILL_BPAMMO]);             
    }

    set_pcvar_float(g_Pointer[PCVAR_ROUNDTIME], g_Cvar[valueType][CVAR_ROUNDTIME]);
    set_pcvar_float(g_Pointer[PCVAR_FORCERESPAWN], g_Cvar[valueType][CVAR_FORCERESPAWN]);
    set_pcvar_num(g_Pointer[PCVAR_FREEZETIME], g_Cvar[valueType][CVAR_FREEZETIME]); 
    set_pcvar_num(g_Pointer[PCVAR_BUY_TIME], g_Cvar[valueType][CVAR_BUY_TIME]);
    set_pcvar_num(g_Pointer[PCVAR_ROUND_INFINITE], g_Cvar[valueType][CVAR_ROUND_INFINITE]);
    set_pcvar_num(g_Pointer[PCVAR_REFILL_BPAMMO], g_Cvar[valueType][CVAR_REFILL_BPAMMO]);
    set_pcvar_num(g_Pointer[PCVAR_RESPAWN_IMMUNITYTIME], g_Cvar[valueType][CVAR_RESPAWN_IMMUNITYTIME]);
    set_pcvar_num(g_Pointer[PCVAR_ITEM_STAYTIME], g_Cvar[valueType][CVAR_ITEM_STAYTIME]);
    set_pcvar_num(g_Pointer[PCVAR_REFILL_BPAMMO], g_Cvar[valueType][CVAR_REFILL_BPAMMO]);
}

Toggle_Forwards(const bool:enable) {
    for (new i; i < sizeof g_HookChain; i++) {
        enable ? EnableHookChain(g_HookChain[i]) : DisableHookChain(g_HookChain[i]);
    }
}

stock SendStatusIcon(const index, const icon[], const status = STATUSICON_HIDE, red = 0, green = 160, blue = 0) {
    static iMsgIdStatusIcon;
    if(iMsgIdStatusIcon || (iMsgIdStatusIcon = get_user_msgid("StatusIcon"))) {
        //message_begin(index ? MSG_ONE : MSG_ALL, iMsgIdStatusIcon, _, index);
        message_begin(index ? MSG_ONE_UNRELIABLE : MSG_BROADCAST, iMsgIdStatusIcon, _, index);
        write_byte(status);
        write_string(icon);
        if(status) {
            write_byte(red);
            write_byte(green);
            write_byte(blue);
        }
        message_end();
    }
}
CSDM разминка, запускается консольной командой warmup_start. В начале разминки выставляется g_Cvar[NEW_VALUE][CVAR_ROUNDTIME] = 1.50; время раунда в полторы минуты. Собственно, в чем проблема: после окончания времени таймер зависает на нуликах и не наступает конец раунда, хотя в кваре время не бесконечное. Пробовал играться с мемберами m_bCompleteReset, m_bGameStarted, а также с нативом rg_round_end результатов никаких.
Для чего нужен конец раунда применительно в этом плагине? Чтобы останавливать разминку (не тасками и прочими вещами, а именно через отлов конца раунда хотел это реализовать).
27 Апр 2019
P.S. забыл указать, что других плагинов, работающих с раундами и т.д. на момент тестов на сервере нет.
27 Апр 2019
UPD: проблема была в кваре регейма mp_round_infinite, выставлял значение 1, т.е. все проверки на окончание раунда, спасение заложников, взрыв/дефуз бомбы и т.д. игнорировались.
Тему можно закрыть:)
 
Статус
В этой теме нельзя размещать новые ответы.

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

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