[ReAPI] Пример кастомного оружия с дополнительними свойствами

Сообщения
1,420
Реакции
2,511
Помог
58 раз(а)
INFIX, если компилятор от 1.8.3-dev то там ничего добавлять не нужно, всё компилируется отлично. Всегда нужно скачивать с официального сайта - https://www.amxmodx.org
 
Сообщения
33
Реакции
-2
Помог
2 раз(а)
Сообщения
33
Реакции
-2
Помог
2 раз(а)
Заметил баг если сделать несколько оружий на этом коде, а после поставить их на сервер то на всех оружиях показывается w_models последнего загруженного плагина (оружия).
 

d3m37r4

111111
Сообщения
1,455
Реакции
1,194
Помог
10 раз(а)
INFIX, индекс у оружия одинаковый?
9 Июн 2018
Если не ошибаюсь в var_impulse выставляется "идентификатор" оружия?
 
Сообщения
33
Реакции
-2
Помог
2 раз(а)
d3m37r4, Простите, я просто тупенький. Все нормально ложная. Спасибо за указание на ошибку)
 
Сообщения
58
Реакции
25
Помог
4 раз(а)
Покажите плиз, как правильно массив организовать? А то я в этом не силен. Хочу заменить deagle, m4a1, ak47, awp на голд
 
Сообщения
58
Реакции
25
Помог
4 раз(а)
Sonyx, мне бы именно в рамках данного плагина пример, как туда запихнуть;)
 
Сообщения
2,491
Реакции
2,794
Помог
61 раз(а)
Учитивая послении апдейты ReGame_DLL и ReAPI привожу пример улучшеного кастомного оружия
Код:
#include <amxmodx>
#include <hamsandwich>
#include <reapi>

#define WEAPON_CMD "give_m4a1" // Команда по которой будет выдано оружие
#define WEAPON_ID WEAPON_M4A1 // ID оружия
#define WEAPON_NAME "weapon_m4a1" // Название оружия
#define ACCESS_FLAG ADMIN_LEVEL_H // Флаг которому доступно оружие. Закоментировать чтобы было доступно всем
#define WEAPON_DAMAGE 1.2 // Множитель урона. Закоментировать если не нужно
#define WEAPON_CLIP 35 // Количество патронов в обойме. Закоментировать если количество по умолчанию
#define WEAPON_AMMO 120 // Количество патронов в запасе
#define WEAPON_SPEED 300.0 // Скорость бега. Закоментировать если количество по умолчанию
// #define WEAPON_GRAVITY 0.8 // Гравитация (1.0 == sv_gravity). Закоментировать если количество по умолчанию.
#define MODEL_V "models/gold/v_m4a1.mdl" // Модель оружия. Закоментировать если не нужно
#define MODEL_P "models/gold/p_m4a1.mdl" // Модель оружия. Закоментировать если не нужно
#define MODEL_W "models/gold/w_m4a1.mdl" // Модель оружия. Закоментировать если не нужно
// #define WEAPON_CAN_TOUCH_ONLY_OWNER // Поднять сможет только владелец. Закоментировать если не нужно

#define WEAPON_UID 1
#define IsCustomWeapon(%1) bool:(get_entvar(%1, var_impulse) == WEAPON_UID)

#if defined MODEL_V || defined MODEL_P || defined MODEL_W
public plugin_precache() {
#if defined MODEL_V
    precache_model(MODEL_V);
#endif

#if defined MODEL_P
    precache_model(MODEL_P);
#endif

#if defined MODEL_W
    precache_model(MODEL_W);
#endif
}
#endif

public plugin_init() {
    register_clcmd(WEAPON_CMD, "CmdGive");

#if defined MODEL_V || defined MODEL_P || defined WEAPON_GRAVITY
    RegisterHam(Ham_Item_Deploy, WEAPON_NAME, "HookItemDeploy", 1);
#endif

#if defined WEAPON_GRAVITY
    RegisterHam(Ham_Item_Holster, WEAPON_NAME, "HookHolster", 1);
#endif

#if defined MODEL_W
    RegisterHookChain(RG_CWeaponBox_SetModel, "HookSetModel", 0);
#endif

#if defined WEAPON_CLIP
    RegisterHam(Ham_Weapon_Reload, WEAPON_NAME, "HookReloaded", 0);
#endif

#if defined WEAPON_SPEED
    RegisterHam(Ham_CS_Item_GetMaxSpeed, WEAPON_NAME, "HookGetMaxSpeed", 0);
#endif

#if defined WEAPON_CAN_TOUCH_ONLY_OWNER
    RegisterHam(Ham_Touch, "weaponbox", "HookWeaponBoxTouch", 0);
#endif
}

public CmdGive(id) {
#if defined ACCESS_FLAG
    if (~get_user_flags(id) & ACCESS_FLAG) {
        return PLUGIN_HANDLED;
    }
#endif

    new weapon = rg_give_custom_item(id, WEAPON_NAME, GT_REPLACE, WEAPON_UID);
    if (is_nullent(weapon)) {
        return PLUGIN_HANDLED;
    }

#if defined WEAPON_CLIP
    rg_set_iteminfo(weapon, ItemInfo_iMaxClip, WEAPON_CLIP);
    rg_set_user_ammo(id, WEAPON_ID, WEAPON_CLIP);
#endif

#if defined WEAPON_AMMO
    rg_set_user_bpammo(id, WEAPON_ID, WEAPON_AMMO);
#endif

#if defined WEAPON_DAMAGE
    set_member(weapon, m_Weapon_flBaseDamage, Float:get_member(weapon, m_Weapon_flBaseDamage) * WEAPON_DAMAGE);
    #if WEAPON_ID == WEAPON_M4A1
    set_member(weapon, m_M4A1_flBaseDamageSil, Float:get_member(weapon, m_M4A1_flBaseDamageSil) * WEAPON_DAMAGE);
    #elseif WEAPON_ID == WEAPON_USP
    set_member(weapon, m_USP_flBaseDamageSil, Float:get_member(weapon, m_USP_flBaseDamageSil) * WEAPON_DAMAGE);
    #elseif WEAPON_ID == WEAPON_FAMAS
    set_member(weapon, m_Famas_flBaseDamageBurst, Float:get_member(weapon, m_Famas_flBaseDamageBurst) * WEAPON_DAMAGE);
    #endif
#endif
    return PLUGIN_HANDLED;
}

#if defined MODEL_V || defined MODEL_P || defined WEAPON_GRAVITY
public HookItemDeploy(weapon) {
    new id = get_member(weapon, m_pPlayer);
    if (!is_user_connected(id) || !IsCustomWeapon(weapon)) {
        return HAM_IGNORED;
    }

#if defined MODEL_V
    set_entvar(id, var_viewmodel, MODEL_V);
#endif

#if defined MODEL_V
    set_entvar(id, var_weaponmodel, MODEL_P);
#endif

#if defined WEAPON_GRAVITY
    set_entvar(id, var_gravity, WEAPON_GRAVITY);
#endif

    return HAM_IGNORED;
}
#endif

#if defined WEAPON_GRAVITY
public HookHolster(weapon) {
    new id = get_member(weapon, m_pPlayer);
    if (!is_user_connected(id) || !IsCustomWeapon(weapon)) {
        return HAM_IGNORED;
    }
    set_entvar(id, var_gravity, 1.0);
    return HAM_IGNORED;
}
#endif

#if defined MODEL_W
public HookSetModel(const weaponbox, const model[]) {
    new weapon = getWeaponBoxWeapon(weaponbox);
    if (weapon != NULLENT && IsCustomWeapon(weapon)) {
        SetHookChainArg(2, ATYPE_STRING, MODEL_W);
    }
    return HC_CONTINUE;
}
#endif

#if defined WEAPON_CLIP
public HookReloaded(weapon) {
    new id = get_member(weapon, m_pPlayer);
    if (!is_user_connected(id) || !IsCustomWeapon(weapon)) {
        return HAM_IGNORED;
    }

    if (get_member(weapon, m_Weapon_iClip) < WEAPON_CLIP) {
        return HAM_IGNORED;
    }

    #if WEAPON_ID == WEAPON_M4A1
    new animation = get_member(weapon, m_Weapon_iWeaponState) & WPNSTATE_M4A1_SILENCED ? 0 : 7;
    #elseif WEAPON_ID == WEAPON_USP
    new animation = get_member(weapon, m_Weapon_iWeaponState) & WPNSTATE_USP_SILENCED ? 0 : 8;
    #else
    new animation = 0
    #endif

    set_entvar(id, var_weaponanim, animation);

    message_begin(MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, .player = id);
    write_byte(animation);
    write_byte(0);
    message_end();

    return HAM_SUPERCEDE;
}
#endif

#if defined WEAPON_SPEED
public HookGetMaxSpeed(const weapon) {
    if (!IsCustomWeapon(weapon)) {
        return HAM_IGNORED;
    }

    new id = get_member(weapon, m_pPlayer);
    if (!is_user_connected(id)) {
        return HAM_IGNORED;
    }

    SetHamReturnFloat(WEAPON_SPEED);
    return HAM_SUPERCEDE;
}
#endif

#if defined WEAPON_CAN_TOUCH_ONLY_OWNER
public HookWeaponBoxTouch(const weaponbox, const id) {
    new weapon = getWeaponBoxWeapon(weaponbox);
    if(
        weapon == NULLENT ||
        WeaponIdType:get_member(weapon, m_iId ) != WEAPON_ID ||
        !IsCustomWeapon(weapon)
    ) {
        return HAM_IGNORED;
    }

    return get_entvar(weaponbox, var_owner) == id ? HAM_IGNORED : HAM_SUPERCEDE;
}
#endif

stock getWeaponBoxWeapon(const weaponbox) {
    for (new i = 0, weapon; i < MAX_ITEM_TYPES; i++) {
        weapon = get_member(weaponbox, m_WeaponBox_rgpPlayerItems, i);
        if (!is_nullent(weapon)) {
            return weapon;
        }
    }
    return NULLENT;
}
 

d3m37r4

111111
Сообщения
1,455
Реакции
1,194
Помог
10 раз(а)
Minni, как минимум изавились от RG_CBasePlayer_TakeDamage, чтобы поменять урон)
 
Сообщения
1,701
Реакции
1,512
Помог
26 раз(а)
Макросный кал. Непонятно где пост хуки.
 
Сообщения
2,491
Реакции
2,794
Помог
61 раз(а)
fl0wer, согласен
2 Фев 2019
Код:
#include <amxmodx>
#include <hamsandwich>
#include <reapi>

#define WEAPON_CMD "give_m4a1" // Команда по которой будет выдано оружие
#define WEAPON_ID WEAPON_M4A1 // ID оружия
#define WEAPON_NAME "weapon_m4a1" // Название оружия
#define ACCESS_FLAG ADMIN_LEVEL_H // Флаг которому доступно оружие. Закоментировать чтобы было доступно всем
#define WEAPON_DAMAGE 1.2 // Множитель урона. Закоментировать если не нужно
#define WEAPON_CLIP 35 // Количество патронов в обойме. Закоментировать если количество по умолчанию
#define WEAPON_AMMO 120 // Количество патронов в запасе
#define WEAPON_SPEED 300.0 // Скорость бега. Закоментировать если количество по умолчанию
// #define WEAPON_GRAVITY 0.8 // Гравитация (1.0 == sv_gravity). Закоментировать если количество по умолчанию.
#define MODELS // Включить модели оружия. Закоментировать чтобы отключить
#if defined MODELS
#define MODEL_V "models/gold/v_m4a1.mdl" // Модель V оружия.
#define MODEL_P "models/gold/p_m4a1.mdl" // Модель P оружия.
#define MODEL_W "models/gold/w_m4a1.mdl" // Модель W оружия.
#endif
// #define WEAPON_CAN_TOUCH_ONLY_OWNER // Поднять сможет только владелец. Закоментировать если не нужно

#define WEAPON_UID 1
#define GetWeponID(%1) WeaponIdType:get_member(%1, m_iId)
#define IsCustomWeapon(%1) bool:(get_entvar(%1, var_impulse) == WEAPON_UID)

#if defined MODELS
public plugin_precache() {
    precache_model(MODEL_V);
    precache_model(MODEL_P);

    #if defined MODEL_W
    precache_model(MODEL_W);
    #endif
}
#endif

public plugin_init() {
    register_clcmd(WEAPON_CMD, "CmdGive");

#if defined MODELS || defined WEAPON_GRAVITY
    RegisterHam(Ham_Item_Deploy, WEAPON_NAME, "Item_Deploy_Post", true);
#endif

#if defined WEAPON_GRAVITY
    RegisterHam(Ham_Item_Holster, WEAPON_NAME, "Item_Holster_Post", true);
#endif

#if defined MODEL_W
    RegisterHookChain(RG_CWeaponBox_SetModel, "CWeaponBox_SetModel_Pre", false);
#endif

#if defined WEAPON_CLIP
    RegisterHam(Ham_Weapon_Reload, WEAPON_NAME, "Weapon_Reload_Pre", false);
#endif

#if defined WEAPON_SPEED
    RegisterHam(Ham_CS_Item_GetMaxSpeed, WEAPON_NAME, "CS_Item_GetMaxSpeed_Pre", false);
#endif

#if defined WEAPON_CAN_TOUCH_ONLY_OWNER
    RegisterHam(Ham_Touch, "weaponbox", "Weaponbox_Touch_Pre", false);
#endif
}

public CmdGive(id) {
#if defined ACCESS_FLAG
    if (~get_user_flags(id) & ACCESS_FLAG) {
        return PLUGIN_HANDLED;
    }
#endif

    new weapon = rg_give_custom_item(id, WEAPON_NAME, GT_REPLACE, WEAPON_UID);
    if (is_nullent(weapon)) {
        return PLUGIN_HANDLED;
    }

#if defined WEAPON_CLIP
    rg_set_iteminfo(weapon, ItemInfo_iMaxClip, WEAPON_CLIP);
    rg_set_user_ammo(id, WEAPON_ID, WEAPON_CLIP);
#endif

#if defined WEAPON_AMMO
    rg_set_user_bpammo(id, WEAPON_ID, WEAPON_AMMO);
#endif

#if defined WEAPON_DAMAGE
    set_member(weapon, m_Weapon_flBaseDamage, Float:get_member(weapon, m_Weapon_flBaseDamage) * WEAPON_DAMAGE);
    #if WEAPON_ID == WEAPON_M4A1
    set_member(weapon, m_M4A1_flBaseDamageSil, Float:get_member(weapon, m_M4A1_flBaseDamageSil) * WEAPON_DAMAGE);
    #elseif WEAPON_ID == WEAPON_USP
    set_member(weapon, m_USP_flBaseDamageSil, Float:get_member(weapon, m_USP_flBaseDamageSil) * WEAPON_DAMAGE);
    #elseif WEAPON_ID == WEAPON_FAMAS
    set_member(weapon, m_Famas_flBaseDamageBurst, Float:get_member(weapon, m_Famas_flBaseDamageBurst) * WEAPON_DAMAGE);
    #endif
#endif
    return PLUGIN_HANDLED;
}

#if defined MODELS || defined WEAPON_GRAVITY
public Item_Deploy_Post(weapon) {
    if (!IsCustomWeapon(weapon)) {
        return HAM_IGNORED;
    }

    new id = get_member(weapon, m_pPlayer);

    #if defined MODELS
    set_entvar(id, var_viewmodel, MODEL_V);
    set_entvar(id, var_weaponmodel, MODEL_P);
    #endif

    #if defined WEAPON_GRAVITY
    set_entvar(id, var_gravity, WEAPON_GRAVITY);
    #endif

    return HAM_IGNORED;
}
#endif

#if defined WEAPON_GRAVITY
public Item_Holster_Post(weapon) {
    if (IsCustomWeapon(weapon)) {
        new id = get_member(weapon, m_pPlayer);
        set_entvar(id, var_gravity, 1.0);
    }
}
#endif

#if defined MODEL_W
public CWeaponBox_SetModel_Pre(const weaponbox, const model[]) {
    new weapon = getWeaponBoxWeapon(weaponbox);
    if (weapon != NULLENT && IsCustomWeapon(weapon)) {
        SetHookChainArg(2, ATYPE_STRING, MODEL_W);
    }
}
#endif

#if defined WEAPON_CLIP
public Weapon_Reload_Pre(weapon) {
    if (!IsCustomWeapon(weapon) || get_member(weapon, m_Weapon_iClip) < WEAPON_CLIP) {
        return HAM_IGNORED;
    }

    new id = get_member(weapon, m_pPlayer);
    #if WEAPON_ID == WEAPON_M4A1
    sendWeaponAmimation(id, get_member(weapon, m_Weapon_iWeaponState) & WPNSTATE_M4A1_SILENCED ? 0 : 7);
    #elseif WEAPON_ID == WEAPON_USP
    sendWeaponAmimation(id, get_member(weapon, m_Weapon_iWeaponState) & WPNSTATE_USP_SILENCED ? 0 : 8);
    #else
    sendWeaponAmimation(id, 0);
    #endif

    return HAM_SUPERCEDE;
}
#endif

#if defined WEAPON_SPEED
public CS_Item_GetMaxSpeed_Pre(const weapon) {
    if (IsCustomWeapon(weapon)) {
        SetHamReturnFloat(WEAPON_SPEED);
        return HAM_SUPERCEDE;
    }

    return HAM_IGNORED;
}
#endif

#if defined WEAPON_CAN_TOUCH_ONLY_OWNER
public Weaponbox_Touch_Pre(const weaponbox, const id) {
    new weapon = getWeaponBoxWeapon(weaponbox);
    if (weapon == NULLENT || GetWeponID(weapon) != WEAPON_ID || !IsCustomWeapon(weapon) {
        return HAM_IGNORED;
    }

    return get_entvar(weaponbox, var_owner) == id ? HAM_IGNORED : HAM_SUPERCEDE;
}
#endif

stock getWeaponBoxWeapon(const weaponbox) {
    for (new i = 0, weapon; i < MAX_ITEM_TYPES; i++) {
        weapon = get_member(weaponbox, m_WeaponBox_rgpPlayerItems, i);
        if (!is_nullent(weapon)) {
            return weapon;
        }
    }
    return NULLENT;
}

stock sendWeaponAmimation(const id, const animation) {
    set_entvar(id, var_weaponanim, animation);

    message_begin(MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, .player = id);
    write_byte(animation);
    write_byte(0);
    message_end();
}
 
Последнее редактирование:
Сообщения
1,420
Реакции
2,511
Помог
58 раз(а)
Прикладываю пример исходя из кода выше, делалось с целью выдачи игроку Золотого AK-47 с двойным уроном. Из отличий: используются квары и есть натив для выдачи оружия.

Код:
/*
* Last update: 09.02.2019
*
* Original code by F@nt0M: https://dev-cs.ru/threads/1983/page-3#post-51426
*/

#include <amxmodx>
#include <hamsandwich>
#include <reapi>

#pragma semicolon 1

new const PLUGIN_VERSION[] = "1.0";

/****************************************************************************************
****************************************************************************************/

#define IsUserValid(%0) (1 <= %0 <= MaxClients)
#define GetCvarDesc(%0) fmt("%l", %0)

// Режим DEBUG. Раскомментировать если нужно включить команду для выдачи оружия
//#define DEBUG

// Уникальный ID (impulse) для оружия
#define WEAPON_UID            130
// ID оружия (берётся из файла cssdk_const.inc из enum WeaponIdType)
#define WEAPON_ID            WEAPON_AK47
// Получить ID оружия
#define GetWeaponID(%0)        WeaponIdType:get_member(%0, m_iId)
// Является ли оружие нашим кастомным
#define IsCustomWeapon(%0)    bool:(get_entvar(%0, var_impulse) == WEAPON_UID)

// Нужны ли модели
#define MODELS
// Нужна ли модель "w_"
//#define MODEL_W

#if defined MODELS
new const g_szModelV[]                = "models/custom/gold/v_gold_ak47.mdl";        // Модель "v_"
new const g_szModelP[]                = "models/custom/gold/p_gold_ak47.mdl";        // Модель "p_"
#if defined MODEL_W
new const g_szModelW[]                = "models/custom/gold/w_gold_ak47.mdl";        // Модель "w_"
#endif
#endif

#if defined DEBUG
    // Команда для выдачи оружия
    new const g_szGiveWeaponCmd[]    = "give_ak47";
#endif

// Название оружия (информация: https://dev-cs.ru/threads/772/)
new const g_szWeaponName[]            = "weapon_ak47";

/****************************************************************************************
****************************************************************************************/

enum _:CVARS
{
    CVAR_WEAPON_DAMAGE,
    CVAR_WEAPON_CLIP,
    CVAR_WEAPON_AMMO
};

new g_eCvar[CVARS];

new HamHook:g_iHamHookReloadPre, HamHook:g_iHamHookTouchPre;

/****************************************************************************************
****************************************************************************************/

#if defined MODELS
public plugin_precache()
{
    precache_model(g_szModelV);
    precache_model(g_szModelP);

#if defined MODEL_W
    precache_model(g_szModelW);
#endif
}
#endif

public plugin_init()
{
    register_plugin("[Custom] Weapon: Gold AK-47", PLUGIN_VERSION, "w0w");
    register_dictionary("custom_weapon.ini");

#if defined DEBUG
    register_clcmd(g_szGiveWeaponCmd, "func_CmdGiveWeapon");
#endif

#if defined MODELS
    RegisterHam(Ham_Item_Deploy, g_szWeaponName, "hamfwd_ItemDeploy_Post", true);

#if defined MODEL_W
    RegisterHookChain(RG_CWeaponBox_SetModel, "refwd_WeaponBox_SetModel_Pre", false);
#endif
#endif

    DisableHamForward(g_iHamHookReloadPre = RegisterHam(Ham_Weapon_Reload, g_szWeaponName, "hamfwd_WeaponReload_Pre", false));
    DisableHamForward(g_iHamHookTouchPre = RegisterHam(Ham_Touch, "weaponbox", "hamfwd_WeaponBox_Touch_Pre", false));

    func_RegisterCvars();
}

public func_CmdGiveWeapon(id)
{
    new iWeapon = rg_give_custom_item(id, g_szWeaponName, GT_REPLACE, WEAPON_UID);

    if(is_nullent(iWeapon))
        return PLUGIN_HANDLED;

    if(g_eCvar[CVAR_WEAPON_CLIP])
    {
        rg_set_iteminfo(iWeapon, ItemInfo_iMaxClip, g_eCvar[CVAR_WEAPON_CLIP]);
        rg_set_user_ammo(id, WEAPON_ID, g_eCvar[CVAR_WEAPON_CLIP]);
    }

    if(g_eCvar[CVAR_WEAPON_AMMO])
        rg_set_user_bpammo(id, WEAPON_ID, g_eCvar[CVAR_WEAPON_AMMO]);

    if(g_eCvar[CVAR_WEAPON_DAMAGE])
    {
        set_member(iWeapon, m_Weapon_flBaseDamage, Float:get_member(iWeapon, m_Weapon_flBaseDamage) * g_eCvar[CVAR_WEAPON_DAMAGE]);
    #if WEAPON_ID == WEAPON_M4A1
        set_member(iWeapon, m_M4A1_flBaseDamageSil, Float:get_member(iWeapon, m_M4A1_flBaseDamageSil) * g_eCvar[CVAR_WEAPON_DAMAGE]);
    #elseif WEAPON_ID == WEAPON_USP
        set_member(iWeapon, m_USP_flBaseDamageSil, Float:get_member(iWeapon, m_USP_flBaseDamageSil) * g_eCvar[CVAR_WEAPON_DAMAGE]);
    #elseif WEAPON_ID == WEAPON_FAMAS
        set_member(iWeapon, m_Famas_flBaseDamageBurst, Float:get_member(iWeapon, m_Famas_flBaseDamageBurst) * g_eCvar[CVAR_WEAPON_DAMAGE]);
    #endif
    }
    return PLUGIN_HANDLED;
}

#if defined MODELS
public hamfwd_ItemDeploy_Post(iWeapon)
{
    if (!IsCustomWeapon(iWeapon))
        return HAM_IGNORED;

    new id = get_member(iWeapon, m_pPlayer);

#if defined MODELS
    set_entvar(id, var_viewmodel, g_szModelV);
    set_entvar(id, var_weaponmodel, g_szModelP);
#endif

    return HAM_IGNORED;
}
#endif

#if defined MODEL_W
public refwd_WeaponBox_SetModel_Pre(const iWeaponBox, const szModel[])
{
    new iWeapon = func_GetWeaponBoxWeapon(iWeaponBox);
    if(iWeapon != NULLENT && IsCustomWeapon(iWeapon))
        SetHookChainArg(2, ATYPE_STRING, g_szModelW);
}
#endif

public hamfwd_WeaponReload_Pre(iWeapon)
{
    if(!IsCustomWeapon(iWeapon) || get_member(iWeapon, m_Weapon_iClip) < g_eCvar[CVAR_WEAPON_CLIP])
        return HAM_IGNORED;

    new id = get_member(iWeapon, m_pPlayer);
#if WEAPON_ID == WEAPON_M4A1
    func_SendWeaponAnimation(id, get_member(iWeapon, m_Weapon_iWeaponState) & WPNSTATE_M4A1_SILENCED ? 0 : 7);
#elseif WEAPON_ID == WEAPON_USP
    func_SendWeaponAnimation(id, get_member(iWeapon, m_Weapon_iWeaponState) & WPNSTATE_USP_SILENCED ? 0 : 8);
#else
    func_SendWeaponAnimation(id, 0);
#endif

    return HAM_SUPERCEDE;
}

public hamfwd_WeaponBox_Touch_Pre(const iWeaponBox, const id)
{
    new iWeapon = func_GetWeaponBoxWeapon(iWeaponBox);
    if(iWeapon == NULLENT || GetWeaponID(iWeapon) != WEAPON_ID || !IsCustomWeapon(iWeapon))
        return HAM_IGNORED;

    return get_entvar(iWeaponBox, var_owner) == id ? HAM_IGNORED : HAM_SUPERCEDE;
}

stock func_GetWeaponBoxWeapon(const iWeaponBox)
{
    for(new i, iWeapon; i < MAX_ITEM_TYPES; i++)
    {
        iWeapon = get_member(iWeaponBox, m_WeaponBox_rgpPlayerItems, i);
        if(!is_nullent(iWeapon))
            return iWeapon;
    }
    return NULLENT;
}

stock func_SendWeaponAnimation(const id, const iAnimation)
{
    set_entvar(id, var_weaponanim, iAnimation);

    message_begin(MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, .player = id);
    write_byte(iAnimation);
    write_byte(0);
    message_end();
}

/****************************************************************************************
****************************************************************************************/

func_RegisterCvars()
{
    new pCvar;

    pCvar = create_cvar("custom_weapon_gold_ak47_clip", "30", FCVAR_NONE, GetCvarDesc("CUSTOM_WEAPON_CVAR_CLIP"), true, 0.0);
    hook_cvar_change(pCvar, "hook_CvarChange_Clip");

    pCvar = create_cvar("custom_weapon_gold_ak47_ammo", "500", FCVAR_NONE, GetCvarDesc("CUSTOM_WEAPON_CVAR_AMMO"), true, 0.0);
    bind_pcvar_num(pCvar, g_eCvar[CVAR_WEAPON_AMMO]);

    pCvar = create_cvar("custom_weapon_gold_ak47_damage", "2", FCVAR_NONE, GetCvarDesc("CUSTOM_WEAPON_CVAR_DAMAGE"), true, 0.0);
    bind_pcvar_num(pCvar, g_eCvar[CVAR_WEAPON_DAMAGE]);

    pCvar = create_cvar("custom_weapon_gold_ak47_touch_only_owner", "0", FCVAR_NONE, GetCvarDesc("CUSTOM_WEAPON_CVAR_TOUCH_ONLY_OWNER"), true, 0.0, true, 1.0);
    hook_cvar_change(pCvar, "hook_CvarChange_TouchOnlyOwner");

    AutoExecConfig(true, "custom_weapon_gold_ak47");
}

public hook_CvarChange_Clip(pCvar, const szOldValue[], const szNewValue[])
{
    g_eCvar[CVAR_WEAPON_CLIP] = str_to_num(szNewValue);

    if(g_eCvar[CVAR_WEAPON_CLIP])
        EnableHamForward(g_iHamHookReloadPre);
    else
        DisableHamForward(g_iHamHookReloadPre);
}

public hook_CvarChange_TouchOnlyOwner(pCvar, const szOldValue[], const szNewValue[])
{
    new iValue = str_to_num(szNewValue);

    if(iValue)
        EnableHamForward(g_iHamHookTouchPre);
    else
        DisableHamForward(g_iHamHookTouchPre);
}

/****************************************************************************************
****************************************************************************************/

public plugin_natives()
{
    register_native("give_custom_weapon_gold_ak47",    "__give_custom_weapon_gold_ak47");
}

public __give_custom_weapon_gold_ak47(iPlugin, iParams)
{
    enum { player = 1 };

    new id = get_param(player);

    if(!IsUserValid(id))
        abort(AMX_ERR_NATIVE, "Player out of range (%i)", id);

    func_CmdGiveWeapon(id);
}

Перевод из файла custom_weapon.ini:
[ru]
CUSTOM_WEAPON_CVAR_ACCESS = Доступ к команде взятия оружия
CUSTOM_WEAPON_CVAR_CLIP = Количество патронов в обойме
CUSTOM_WEAPON_CVAR_AMMO = Количество патронов в запасе
CUSTOM_WEAPON_CVAR_DAMAGE = На сколько умножать урон от оружия. 0 - не умножать
CUSTOM_WEAPON_CVAR_TOUCH_ONLY_OWNER = 0 - подбирать оружие могут все. 1 - только тот кто его получил
9 Фев 2019
Можно ещё добавить оптимизации включая хуки только когда кто-то получает оружие. Если оружие выкидывается то отключать такие хуки как Deploy/Reload/SetModel (после выброса оружия) если больше ни у кого нет кастомного этого оружия.
9 Фев 2019
Код:
/*
* Last update: 09.02.2019
*
* Original code by F@nt0M: https://dev-cs.ru/threads/1983/page-3#post-51426
*/

#include <amxmodx>
#include <hamsandwich>
#include <reapi>

#pragma semicolon 1

new const PLUGIN_VERSION[] = "1.0";

/****************************************************************************************
****************************************************************************************/

#define IsUserValid(%0) (1 <= %0 <= MaxClients)
#define GetCvarDesc(%0) fmt("%l", %0)

// Режим DEBUG. Раскомментировать если нужно включить команду для выдачи оружия
//#define DEBUG

// Уникальный ID (impulse) для оружия
#define WEAPON_UID            130
// ID оружия (берётся из файла cssdk_const.inc из enum WeaponIdType)
#define WEAPON_ID            WEAPON_AK47
// Получить ID оружия
#define GetWeaponID(%0)        WeaponIdType:get_member(%0, m_iId)
// Является ли оружие нашим кастомным
#define IsCustomWeapon(%0)    bool:(get_entvar(%0, var_impulse) == WEAPON_UID)

// Нужны ли модели
#define MODELS
// Нужна ли модель "w_"
#define MODEL_W

#if defined MODELS
new const g_szModelV[]                = "models/custom/gold/v_gold_ak47.mdl";        // Модель "v_"
new const g_szModelP[]                = "models/custom/gold/p_gold_ak47.mdl";        // Модель "p_"
#if defined MODEL_W
new const g_szModelW[]                = "models/custom/gold/w_gold_ak47.mdl";        // Модель "w_"
#endif
#endif

#if defined DEBUG
    // Команда для выдачи оружия
    new const g_szGiveWeaponCmd[]    = "give_ak47";
#endif

// Название оружия (информация: https://dev-cs.ru/threads/772/)
new const g_szWeaponName[]            = "weapon_ak47";

/****************************************************************************************
****************************************************************************************/

enum _:CVARS
{
    CVAR_WEAPON_DAMAGE,
    CVAR_WEAPON_CLIP,
    CVAR_WEAPON_AMMO,
    CVAR_TOUCH_ONLY_OWNER
};

new g_eCvar[CVARS];

new HamHook:g_iHamHookDeployPost, HamHook:g_iHamHookReloadPre, HamHook:g_iHamHookTouchPre;
new HookChain:g_iHookChainSetModelPre, HookChain:g_iHookChainAddPlayerItemPre;

new g_iWeaponsInHands;

/****************************************************************************************
****************************************************************************************/

#if defined MODELS
public plugin_precache()
{
    precache_model(g_szModelV);
    precache_model(g_szModelP);

#if defined MODEL_W
    precache_model(g_szModelW);
#endif
}
#endif

public plugin_init()
{
    register_plugin("[Custom] Weapon: Gold AK-47", PLUGIN_VERSION, "w0w");
    register_dictionary("custom_weapon.ini");

#if defined DEBUG
    register_clcmd(g_szGiveWeaponCmd, "func_CmdGiveWeapon");
#endif

    RegisterHookChain(RG_CBasePlayer_DropPlayerItem, "refwd_PlayerDropPlayerItem_Post", true);
    DisableHookChain(g_iHookChainAddPlayerItemPre = RegisterHookChain(RG_CBasePlayer_AddPlayerItem, "refwd_PlayerAddPlayerItem_Pre", false));

#if defined MODELS
    DisableHamForward(g_iHamHookDeployPost = RegisterHam(Ham_Item_Deploy, g_szWeaponName, "hamfwd_ItemDeploy_Post", true));
#endif
    DisableHookChain(g_iHookChainSetModelPre = RegisterHookChain(RG_CWeaponBox_SetModel, "refwd_WeaponBox_SetModel_Pre", false));

    DisableHamForward(g_iHamHookReloadPre = RegisterHam(Ham_Weapon_Reload, g_szWeaponName, "hamfwd_WeaponReload_Pre", false));
    DisableHamForward(g_iHamHookTouchPre = RegisterHam(Ham_Touch, "weaponbox", "hamfwd_WeaponBox_Touch_Pre", false));

    func_RegisterCvars();
}

public func_CmdGiveWeapon(id)
{
    if(++g_iWeaponsInHands == 1)
        func_EnableHooks();

    new iWeapon = rg_give_custom_item(id, g_szWeaponName, GT_REPLACE, WEAPON_UID);

    if(is_nullent(iWeapon))
        return PLUGIN_HANDLED;

    if(g_eCvar[CVAR_WEAPON_CLIP])
    {
        rg_set_iteminfo(iWeapon, ItemInfo_iMaxClip, g_eCvar[CVAR_WEAPON_CLIP]);
        rg_set_user_ammo(id, WEAPON_ID, g_eCvar[CVAR_WEAPON_CLIP]);
    }

    if(g_eCvar[CVAR_WEAPON_AMMO])
        rg_set_user_bpammo(id, WEAPON_ID, g_eCvar[CVAR_WEAPON_AMMO]);

    if(g_eCvar[CVAR_WEAPON_DAMAGE])
    {
        set_member(iWeapon, m_Weapon_flBaseDamage, Float:get_member(iWeapon, m_Weapon_flBaseDamage) * g_eCvar[CVAR_WEAPON_DAMAGE]);
    #if WEAPON_ID == WEAPON_M4A1
        set_member(iWeapon, m_M4A1_flBaseDamageSil, Float:get_member(iWeapon, m_M4A1_flBaseDamageSil) * g_eCvar[CVAR_WEAPON_DAMAGE]);
    #elseif WEAPON_ID == WEAPON_USP
        set_member(iWeapon, m_USP_flBaseDamageSil, Float:get_member(iWeapon, m_USP_flBaseDamageSil) * g_eCvar[CVAR_WEAPON_DAMAGE]);
    #elseif WEAPON_ID == WEAPON_FAMAS
        set_member(iWeapon, m_Famas_flBaseDamageBurst, Float:get_member(iWeapon, m_Famas_flBaseDamageBurst) * g_eCvar[CVAR_WEAPON_DAMAGE]);
    #endif
    }

    return PLUGIN_HANDLED;
}

public refwd_PlayerAddPlayerItem_Pre(const id, const pItem)
{
    DisableHookChain(g_iHookChainAddPlayerItemPre);

    if(!is_entity(pItem))
        return HC_CONTINUE;

    if(IsCustomWeapon(pItem) && ++g_iWeaponsInHands == 1)
        func_EnableHooks();

    return HC_CONTINUE;
}

public refwd_PlayerDropPlayerItem_Post(const id, const pszItemName[])
{
    new iEnt = GetHookChainReturn(ATYPE_INTEGER);

    if(!is_entity(iEnt))
        return HC_CONTINUE;

    new iWeapon = func_GetWeaponBoxWeapon(iEnt);
    if(iWeapon != NULLENT && IsCustomWeapon(iWeapon))
        EnableHookChain(g_iHookChainSetModelPre);

    return HC_CONTINUE;
}

#if defined MODELS
public hamfwd_ItemDeploy_Post(iWeapon)
{
    if(!IsCustomWeapon(iWeapon))
        return HAM_IGNORED;

    new id = get_member(iWeapon, m_pPlayer);

#if defined MODELS
    set_entvar(id, var_viewmodel, g_szModelV);
    set_entvar(id, var_weaponmodel, g_szModelP);
#endif

    return HAM_IGNORED;
}
#endif

public refwd_WeaponBox_SetModel_Pre(const iWeaponBox, const szModel[])
{
    new iWeapon = func_GetWeaponBoxWeapon(iWeaponBox);
    if(iWeapon != NULLENT && IsCustomWeapon(iWeapon))
    {
        SetHookChainArg(2, ATYPE_STRING, g_szModelW);

        if(!(--g_iWeaponsInHands))
        {
            DisableHookChain(g_iHookChainSetModelPre);
            DisableHamForward(g_iHamHookReloadPre);
            DisableHamForward(g_iHamHookDeployPost);
            EnableHookChain(g_iHookChainAddPlayerItemPre);
        }
    }
}

public hamfwd_WeaponReload_Pre(iWeapon)
{
    if(!IsCustomWeapon(iWeapon) || get_member(iWeapon, m_Weapon_iClip) < g_eCvar[CVAR_WEAPON_CLIP])
        return HAM_IGNORED;

    new id = get_member(iWeapon, m_pPlayer);
#if WEAPON_ID == WEAPON_M4A1
    func_SendWeaponAnimation(id, get_member(iWeapon, m_Weapon_iWeaponState) & WPNSTATE_M4A1_SILENCED ? 0 : 7);
#elseif WEAPON_ID == WEAPON_USP
    func_SendWeaponAnimation(id, get_member(iWeapon, m_Weapon_iWeaponState) & WPNSTATE_USP_SILENCED ? 0 : 8);
#else
    func_SendWeaponAnimation(id, 0);
#endif

    return HAM_SUPERCEDE;
}

public hamfwd_WeaponBox_Touch_Pre(const iWeaponBox, const id)
{
    new iWeapon = func_GetWeaponBoxWeapon(iWeaponBox);

    if(iWeapon == NULLENT || GetWeaponID(iWeapon) != WEAPON_ID || !IsCustomWeapon(iWeapon))
        return HAM_IGNORED;

    if(g_eCvar[CVAR_TOUCH_ONLY_OWNER] && get_entvar(iWeaponBox, var_owner) == id)
        return HAM_SUPERCEDE;

    EnableHookChain(g_iHookChainAddPlayerItemPre);

    return HAM_IGNORED;
}

func_EnableHooks()
{
    if(g_eCvar[CVAR_WEAPON_CLIP])
        EnableHamForward(g_iHamHookReloadPre);
    if(g_eCvar[CVAR_TOUCH_ONLY_OWNER])
        EnableHamForward(g_iHamHookTouchPre);
    EnableHamForward(g_iHamHookDeployPost);
    EnableHookChain(g_iHookChainSetModelPre);
}

stock func_GetWeaponBoxWeapon(const iWeaponBox)
{
    for(new i, iWeapon; i < MAX_ITEM_TYPES; i++)
    {
        iWeapon = get_member(iWeaponBox, m_WeaponBox_rgpPlayerItems, i);
        if(!is_nullent(iWeapon))
            return iWeapon;
    }
    return NULLENT;
}

stock func_SendWeaponAnimation(const id, const iAnimation)
{
    set_entvar(id, var_weaponanim, iAnimation);

    message_begin(MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, .player = id);
    write_byte(iAnimation);
    write_byte(0);
    message_end();
}

/****************************************************************************************
****************************************************************************************/

func_RegisterCvars()
{
    new pCvar;

    pCvar = create_cvar("custom_weapon_gold_ak47_clip", "30", FCVAR_NONE, GetCvarDesc("CUSTOM_WEAPON_CVAR_CLIP"), true, 0.0);
    hook_cvar_change(pCvar, "hook_CvarChange_Clip");

    pCvar = create_cvar("custom_weapon_gold_ak47_ammo", "500", FCVAR_NONE, GetCvarDesc("CUSTOM_WEAPON_CVAR_AMMO"), true, 0.0);
    bind_pcvar_num(pCvar, g_eCvar[CVAR_WEAPON_AMMO]);

    pCvar = create_cvar("custom_weapon_gold_ak47_damage", "2", FCVAR_NONE, GetCvarDesc("CUSTOM_WEAPON_CVAR_DAMAGE"), true, 0.0);
    bind_pcvar_num(pCvar, g_eCvar[CVAR_WEAPON_DAMAGE]);

    pCvar = create_cvar("custom_weapon_gold_ak47_touch_only_owner", "0", FCVAR_NONE, GetCvarDesc("CUSTOM_WEAPON_CVAR_TOUCH_ONLY_OWNER"), true, 0.0, true, 1.0);
    bind_pcvar_num(pCvar, g_eCvar[CVAR_TOUCH_ONLY_OWNER]);
}

public hook_CvarChange_Clip(pCvar, const szOldValue[], const szNewValue[])
{
    g_eCvar[CVAR_WEAPON_CLIP] = str_to_num(szNewValue);

    if(g_iWeaponsInHands && g_eCvar[CVAR_WEAPON_CLIP] == 0)
        DisableHamForward(g_iHamHookReloadPre);
}

/****************************************************************************************
****************************************************************************************/

public plugin_natives()
{
    register_native("custom_give_weapon_gold_ak47",    "__custom_give_weapon_gold_ak47");
}

public __custom_give_weapon_gold_ak47(iPlugin, iParams)
{
    enum { player = 1 };

    new id = get_param(player);

    if(!IsUserValid(id))
        abort(AMX_ERR_NATIVE, "Player out of range (%i)", id);

    func_CmdGiveWeapon(id);
}
 
Последнее редактирование:
Сообщения
1,701
Реакции
1,512
Помог
26 раз(а)
Я так понимаю если отобрать оружие, то хуки остануться активными? И что это за InHands? Лучше было бы InRuki.
 
Сообщения
1,701
Реакции
1,512
Помог
26 раз(а)
Ну всё пишите аркшайну чтоб EntityDestroyed форвард добавлял. Или по-человечески хуки на конкретную энтити, а не весь класс энтити.
 

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

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