Иконка ресурса

CSDM Menu 1.1.0

Нет прав для скачивания
C++:
#pragma semicolon 1

//#define FFA_MODE    uncomment to enable FFA Mode support

#include <amxmodx>
#include <fakemeta>
#include <reapi>
#include <json>
#include <nvault>

new const PLUGIN_VERSION[] = "1.1.0";
new const JSON_CONFIG_FILE[] = "/CSDM_Menu.json";

#define IsPlayer(%1)                     (1 <= %1 <= MaxClients)

#if defined FFA_MODE
    #define IS_VALID_ATTACK(%1,%2) (%1 != %2)
#else
    #define IS_VALID_ATTACK(%1,%2) (%1 != %2 && get_user_team(%1) != get_user_team(%2))
#endif

enum (+=1000) {
    TASK_KILLS,
    TASK_CHAT
}

enum _:RGB { R, G, B }

enum _:CSDM_CONFIG {
    Float:HUD_HS_POS_X,
    Float:HUD_HS_POS_Y,
    Float:HUD_KILL_POS_X,
    Float:HUD_KILL_POS_Y,
    Float:BONUS_MAX_HP,
    Float:BONUS_HP_NORMAL,
    Float:BONUS_HP_HS
}

enum _:CSDM_COLORS {
    COLOR_HUD_HS,
    COLOR_HUD_KILL,
    COLOR_FADE
}

enum _:CsdmSettings {
    bool:bHeadshotMode,
    bool:bKillFeed,
    bool:bScreenFade,
    bool:bBulletDamage,
    bool:bHeadshotMsg,
    bool:bKillsCounter,
    bool:bHealing
}

enum _:KillType {
    Normal,
    Headshot
}

new const g_iMenuSettings[][] = {
    "CSDM_ONLY_HS",
    "CSDM_KILLFEED",
    "CSDM_FADE_SCREEN",
    "CSDM_BULLET_DAMAGE",
    "CSDM_HEADSHOT_MSG",
    "CSDM_ALL_KILLS",
    "CSDM_BONUS_HP"
};

new g_eConfig[CSDM_CONFIG], g_iHudSyncObj,
    g_ePlayerSettings[MAX_PLAYERS + 1][CsdmSettings],
    g_iKillsCounter[MAX_PLAYERS + 1][KillType],
    g_eColors[CSDM_COLORS][RGB],
    g_hVault,
    g_szVaultName[32],
    g_iObsoleteDays,
    g_iMsgDeath, g_iMsgScreenFade;
new bool:g_bIsUserDead[MAX_PLAYERS + 1],
    bool:PlayerSettings[CsdmSettings] = {false, false, true, true, true, true, true};

public plugin_init() {
    register_plugin("[ReAPI] CSDM Menu", PLUGIN_VERSION, "mIDnight");
    create_cvar("csdm_menu_ver", PLUGIN_VERSION, FCVAR_SERVER | FCVAR_SPONLY);
 
    register_dictionary("csdm_menu.txt");

    register_message(get_user_msgid("DeathMsg"), "event_MessageDeathMsg");
    RegisterHookChain(RG_CBasePlayer_TakeDamage, "Player_Damage_Post", .post = true);
    RegisterHookChain(RG_CBasePlayer_TraceAttack, "Player_TraceAttack_Pre", .post = false);
    RegisterHookChain(RG_CBasePlayer_Killed, "Player_Killed_Post", .post = true);
    RegisterHookChain(RG_CBasePlayer_Spawn, "Player_Spawn_Post", .post = true);

    g_iHudSyncObj = CreateHudSyncObj();
    g_iMsgDeath = get_user_msgid("DeathMsg");
    g_iMsgScreenFade = get_user_msgid("ScreenFade");
}

public plugin_cfg() {
    LoadJsonConfig();
    g_hVault = nvault_open(g_szVaultName);
    if (g_hVault == INVALID_HANDLE) {
        set_fail_state("Failed to open nVault for CSDM Menu");
    }
    
    nvault_prune(g_hVault, 0, get_systime() - (g_iObsoleteDays * 86400));
}

public plugin_end() {
    if (g_hVault != INVALID_HANDLE) {
        nvault_close(g_hVault);
    }
}

LoadJsonConfig() {
    new szConfigPath[PLATFORM_MAX_PATH];
    get_localinfo("amxx_configsdir", szConfigPath, charsmax(szConfigPath));
    add(szConfigPath, charsmax(szConfigPath), JSON_CONFIG_FILE);

    new JSON:jConfig = json_parse(szConfigPath, true, true);
    if (jConfig == Invalid_JSON) {
        set_fail_state("[CSDM Menu] JSON syntax error in config file (%s)", szConfigPath);
    }

    if (!json_is_object(jConfig)) {
        set_fail_state("[CSDM Menu] JSON config must contain a valid object (%s)", szConfigPath);
    }

    new JSON:jSettings = json_object_get_value(jConfig, "settings", .dot_not = true);

    g_iObsoleteDays = json_object_get_number(jSettings, "vault_obsolete_days", .dot_not = true);
    json_object_get_string(jSettings, "vault_name", g_szVaultName, charsmax(g_szVaultName), .dot_not = true);

    g_eConfig[HUD_HS_POS_X] = json_object_get_real(jSettings, "hud_hs_position.x", .dot_not = true);
    g_eConfig[HUD_HS_POS_Y] = json_object_get_real(jSettings, "hud_hs_position.y", .dot_not = true);
    g_eConfig[HUD_KILL_POS_X] = json_object_get_real(jSettings, "hud_kills_position.x", .dot_not = true);
    g_eConfig[HUD_KILL_POS_Y] = json_object_get_real(jSettings, "hud_kills_position.y", .dot_not = true);

    g_eConfig[BONUS_MAX_HP] = json_object_get_real(jSettings, "bonus_max_hp", .dot_not = true);
    g_eConfig[BONUS_HP_NORMAL] = json_object_get_real(jSettings, "bonus_hp_normal", .dot_not = true);
    g_eConfig[BONUS_HP_HS] = json_object_get_real(jSettings, "bonus_hp_hs", .dot_not = true);

    LoadColorArray(jSettings, "hud_hs_color", g_eColors[COLOR_HUD_HS]);
    LoadColorArray(jSettings, "hud_kills_color", g_eColors[COLOR_HUD_KILL]);
    LoadColorArray(jSettings, "fade_color", g_eColors[COLOR_FADE]);

    new JSON:jCommands = json_object_get_value(jSettings, "menu_commands", .dot_not = true);
    if (jCommands != Invalid_JSON && json_is_array(jCommands)) {
        new iCommandCount = json_array_get_count(jCommands);
        for (new i = 0; i < iCommandCount; i++) {
            new szCommand[32];
            json_array_get_string(jCommands, i, szCommand, charsmax(szCommand));
            if (szCommand[0] != EOS) {
                register_clcmd(szCommand, "Clcmd_CSDM_Menu");
            }
        }
    }

    json_free(jConfig);
    server_print("[CSDM Menu] Configuration loaded successfully");
}

LoadColorArray(JSON:settings, const szKey[], iColorArray[RGB]) {
    new JSON:jsonColors = json_object_get_value(settings, szKey, .dot_not = true);
    if (jsonColors != Invalid_JSON && json_is_array(jsonColors)) {
        for (new i = 0; i < RGB; i++) {
            iColorArray[i] = json_array_get_number(jsonColors, i);
        }
    }
}

public client_putinserver(id) {
    if (task_exists(id + TASK_KILLS)) {
        remove_task(id + TASK_KILLS);
    }
    if (task_exists(id + TASK_CHAT)) {
        remove_task(id + TASK_CHAT);
    }

    for (new i = 0; i < CsdmSettings; i++) {
        g_ePlayerSettings[id][i] = PlayerSettings[i];
    }

    LoadPlayerSettings(id);

    arrayset(g_iKillsCounter[id], 0, KillType);
    g_bIsUserDead[id] = true;

    set_task(180.0, "task_show_chat_ad", id + TASK_CHAT, .flags = "b");
}

public event_MessageDeathMsg(msgid, dest, receiver) {
    enum { arg_killer = 1, arg_victim, arg_headshot, arg_weapon_name };

    new killer = get_msg_arg_int(arg_killer);
    new victim = get_msg_arg_int(arg_victim);
    new headshot = get_msg_arg_int(arg_headshot);
    new killerWeaponName[64];
    get_msg_arg_string(arg_weapon_name, killerWeaponName, charsmax(killerWeaponName));

    if (g_ePlayerSettings[killer][bKillFeed]) {
        UTIL_DeathMsg(MSG_ONE, killer, killer, victim, headshot, killerWeaponName);
    }
    if (g_ePlayerSettings[victim][bKillFeed]) {
        UTIL_DeathMsg(MSG_ONE, victim, killer, victim, headshot, killerWeaponName);
    }

    for (new p = 1; p <= MaxClients; p++) {
        if (is_user_connected(p) && !is_user_hltv(p) && !is_user_bot(p) && !g_ePlayerSettings[p][bKillFeed]) {
            UTIL_DeathMsg(MSG_ONE, p, killer, victim, headshot, killerWeaponName);
        }
    }

    return PLUGIN_HANDLED;
}

public Player_Damage_Post(iVictim, iInflictor, iAttacker, Float:fDamage, bitsDamageType) {
    if(!IsPlayer(iVictim) || !IsPlayer(iAttacker) || !IS_VALID_ATTACK(iAttacker, iVictim)) {
        return HC_CONTINUE;
    }

    static const Float: iDamageCoords[][] = { {0.50, 0.40}, {0.56, 0.44}, {0.60, 0.50}, {0.56, 0.56}, {0.50, 0.60}, {0.44, 0.56}, {0.40, 0.50}, {0.44, 0.44} };
    static iDamageCoordPos[MAX_CLIENTS + 1];

    if(g_ePlayerSettings[iAttacker][bBulletDamage] && !(g_ePlayerSettings[iAttacker][bHeadshotMode] && get_member(iAttacker , m_LastHitGroup) == HIT_HEAD)) {
        set_hudmessage(random_num(0, 255), random_num(0, 255), random_num(0, 255), iDamageCoords[iDamageCoordPos[iAttacker]][0], iDamageCoords[iDamageCoordPos[iAttacker]][1], _, _, 1.0);
        ShowSyncHudMsg(iAttacker, g_iHudSyncObj, "%.0f", fDamage);

        iDamageCoordPos[iAttacker] = (iDamageCoordPos[iAttacker] + 1) % sizeof(iDamageCoords);
    }
    
    return HC_CONTINUE;
}

public Player_TraceAttack_Pre(iVictim, iAttacker, Float:fDamage, Float:fDirection[3], trhandle) {
    if (!IsPlayer(iVictim) || !IsPlayer(iAttacker) || !IS_VALID_ATTACK(iAttacker, iVictim)) {
        return HC_CONTINUE;
    }

    if (g_ePlayerSettings[iAttacker][bHeadshotMode] &&
        get_tr2(trhandle, TR_iHitgroup) != HIT_HEAD &&
        get_user_weapon(iAttacker) != CSW_KNIFE) {
        return HC_SUPERCEDE;
    }

    return HC_CONTINUE;
}

public Player_Killed_Post(const iVictim, iAttacker, iGibs) {
    g_bIsUserDead[iVictim] = true;

    if(!is_user_connected(iAttacker) || iVictim == iAttacker) {
        return HC_CONTINUE;
    }

    if(g_ePlayerSettings[iAttacker][bScreenFade]) {
        UTIL_FadeScreen(iAttacker);
    }

    if(g_ePlayerSettings[iAttacker][bHeadshotMsg] && get_member(iVictim, m_bHeadshotKilled)) {
        set_dhudmessage(g_eColors[COLOR_HUD_HS][R], g_eColors[COLOR_HUD_HS][G], g_eColors[COLOR_HUD_HS][B], g_eConfig[HUD_HS_POS_X], g_eConfig[HUD_HS_POS_Y], 0, 0.1, 0.5, 0.02, 0.02);
        show_dhudmessage(iAttacker, "HEAD SHOT");
    }

    if (g_ePlayerSettings[iAttacker][bKillsCounter]) {
        g_iKillsCounter[iAttacker][Normal]++;
        g_iKillsCounter[iAttacker][Headshot] += get_member(iVictim, m_bHeadshotKilled);

        if (g_iKillsCounter[iAttacker][Normal] || g_iKillsCounter[iAttacker][Headshot]) {
            remove_task(iAttacker + TASK_KILLS);
            set_task(0.1, "task_show_hudkills", iAttacker + TASK_KILLS);
        }
    }

    if (g_ePlayerSettings[iAttacker][bHealing]) {
        set_entvar(iAttacker, var_health, floatmin(Float:get_entvar(iAttacker, var_health) + (get_member(iVictim, m_bHeadshotKilled) ? g_eConfig[BONUS_HP_HS] : g_eConfig[BONUS_HP_NORMAL]), g_eConfig[BONUS_MAX_HP]));
    }

    return HC_CONTINUE;
}

public Player_Spawn_Post(iEntity) {
    if (IsPlayer(iEntity) && g_bIsUserDead[iEntity]) {
        arrayset(g_iKillsCounter[iEntity], 0, KillType);
        g_bIsUserDead[iEntity] = false;
    }
}

public Clcmd_CSDM_Menu(id) {
    new szBuffer[128];
    formatex(szBuffer, charsmax(szBuffer), "\w%L", LANG_PLAYER, "CSDM_SETTINGS_TITLE");
    new menu = menu_create(szBuffer, "settings_menu_handler");

    for (new setting = 0; setting < sizeof(g_iMenuSettings); setting++) {
        formatex(szBuffer, charsmax(szBuffer), "\w%L %s", LANG_PLAYER, g_iMenuSettings[setting],
            g_ePlayerSettings[id][setting] ? "\w[\yON\w]" : "\w[\rOFF\w]");
        menu_additem(menu, szBuffer);
    }

    menu_display(id, menu);

    return PLUGIN_HANDLED;
}

public settings_menu_handler(id, menu, item) {
    if (item == MENU_EXIT || !is_user_connected(id)) {
        return MenuExit(menu);
    }

    if (item >= 0 && item < CsdmSettings) {
        g_ePlayerSettings[id][item] = !g_ePlayerSettings[id][item];
        SavePlayerSettings(id);
        Clcmd_CSDM_Menu(id);
    }

    return MenuExit(menu);
}

public task_show_chat_ad(id) {
    id -= TASK_CHAT;
    if(is_user_connected(id)) {
        client_print_color(id, print_chat, "%L", LANG_PLAYER, "CSDM_CHAT_AD");
    }
}

public task_show_hudkills(id) {
    id -= TASK_KILLS;
    if(g_ePlayerSettings[id][bKillsCounter]) {
        set_dhudmessage(g_eColors[COLOR_HUD_KILL][R], g_eColors[COLOR_HUD_KILL][G], g_eColors[COLOR_HUD_KILL][B], g_eConfig[HUD_KILL_POS_X], g_eConfig[HUD_KILL_POS_Y], 0, 0.1, 1.5, 0.02, 0.02);
        show_dhudmessage(id, "%i (%i)", g_iKillsCounter[id][Normal], g_iKillsCounter[id][Headshot]);

        if(g_iKillsCounter[id][Normal] > 0 || g_iKillsCounter[id][Headshot] > 0) {
            remove_task(id + TASK_KILLS);
            set_task(1.0, "task_show_hudkills", id + TASK_KILLS);
        }
    }
    else {
        remove_task(id + TASK_KILLS);
    }

    if(g_bIsUserDead[id]) {
        g_iKillsCounter[id][Normal] = 0;
        g_iKillsCounter[id][Headshot] = 0;
    }

    return PLUGIN_HANDLED;
}

SavePlayerSettings(id) {
    if (g_hVault == INVALID_HANDLE || !is_user_connected(id)) {
        return;
    }
    
    new szAuthID[MAX_AUTHID_LENGTH], szSettings[16];
    get_user_authid(id, szAuthID, charsmax(szAuthID));
    
    for (new i = 0; i < CsdmSettings; i++) {
        szSettings[i] = g_ePlayerSettings[id][i] ? '1' : '0';
    }
    szSettings[CsdmSettings] = 0;
    
    nvault_set(g_hVault, szAuthID, szSettings);
}

LoadPlayerSettings(id) {
    if (g_hVault == INVALID_HANDLE || !is_user_connected(id)) {
        return;
    }

    new szAuthID[MAX_AUTHID_LENGTH], szSettings[16];
    get_user_authid(id, szAuthID, charsmax(szAuthID));

    if (nvault_get(g_hVault, szAuthID, szSettings, charsmax(szSettings)) > 0) {
        for (new i = 0; i < CsdmSettings; i++) {
            g_ePlayerSettings[id][i] = (szSettings[i] == '1');
        }

        nvault_touch(g_hVault, szAuthID);
    }
}

stock MenuExit(menu) {
    menu_destroy(menu);
    return PLUGIN_HANDLED;
}

stock UTIL_DeathMsg(dest, const receiver, const killer, const victim, const headshot, const weaponName[]) {
    message_begin(dest, g_iMsgDeath, _, receiver);
    write_byte(killer);
    write_byte(victim);
    write_byte(headshot);
    write_string(weaponName);
    message_end();
}

stock UTIL_FadeScreen(id) {
    message_begin(MSG_ONE_UNRELIABLE, g_iMsgScreenFade, {0,0,0}, id);
    write_short(1 << 10);
    write_short(1 << 9);
    write_short(0x0000);
    write_byte(52);
    write_byte(g_eColors[COLOR_FADE][R]);
    write_byte(g_eColors[COLOR_FADE][G]);
    write_byte(g_eColors[COLOR_FADE][B]);
    message_end();
}
Назад
Верх