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

Сообщения
2,491
Реакции
2,795
Помог
61 раз(а)
Код:
#include <amxmodx>
#include <hamsandwich>
#include <reapi>

#if AMXX_VERSION_NUM < 183
new MaxClients;
#endif

#define FLAG ADMIN_LEVEL_H

#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 DAMAGE 1.5
#define CLIPSIZE 35
#define AMMOSIZE 140

#if defined DAMAGE
new Float:g_PlayerDamage[MAX_PLAYERS + 1];
#endif

public plugin_precache() {
    precache_model(MODEL_V);
    precache_model(MODEL_P);
    precache_model(MODEL_W);
}

public plugin_init() {
#if AMXX_VERSION_NUM < 183
    MaxClients = get_maxplayers();
#endif

    register_clcmd("gold_m4a1", "CmdGive");
    register_clcmd("say /gold_m4a1", "CmdGive");
    register_clcmd("say_team /gold_m4a1", "CmdGive");
    
    RegisterHam(Ham_Item_Deploy, "weapon_m4a1", "HookItemDeploy", 1);
    RegisterHam(Ham_Item_Holster, "weapon_m4a1", "HookHolster", 1);
    RegisterHookChain(RG_CWeaponBox_SetModel, "HookSetModel", 0);
    
#if defined DAMAGE
    RegisterHookChain(RG_CBasePlayer_TakeDamage, "HookTakeDamage", 0);
#endif    
}

public CmdGive(id) {
    if (~get_user_flags(id) & FLAG) {
        return PLUGIN_HANDLED;
    }
    
    new weapon = rg_give_item(id, "weapon_m4a1", GT_REPLACE);
    if (is_nullent(weapon)) {
        return PLUGIN_HANDLED;
    }
    
    set_entvar(weapon, var_impulse, 1);
    
#if defined CLIPSIZE
    rg_set_iteminfo(weapon, ItemInfo_iMaxClip, CLIPSIZE);
    rg_set_user_ammo(id, WEAPON_M4A1, CLIPSIZE);
#endif

#if defined AMMOSIZE
    rg_set_user_bpammo(id, WEAPON_M4A1, AMMOSIZE);
#else
    rg_set_user_bpammo(id, WEAPON_M4A1, 90);
#endif

    if (get_member(id, m_pActiveItem) == weapon) {
        set_entvar(id, var_viewmodel, MODEL_V);
        set_entvar(id, var_weaponmodel, MODEL_P);
#if defined DAMAGE
        g_PlayerDamage[id] = DAMAGE;
#endif
    }
    
    return PLUGIN_HANDLED;
}

public HookItemDeploy(weapon) {
    new id = get_member(weapon, m_pPlayer);
    if (id < 1 || id > MaxClients) {
        return HAM_IGNORED;
    }

    if (get_entvar(weapon, var_impulse) == 0) {
        return HAM_IGNORED;
    }

    set_entvar(id, var_viewmodel, MODEL_V);
    set_entvar(id, var_weaponmodel, MODEL_P);

#if defined DAMAGE
    g_PlayerDamage[id] = DAMAGE;
#endif

    return HAM_IGNORED;
}

public HookHolster(weapon) {
    new id = get_member(weapon, m_pPlayer);
    if (id < 1 || id > MaxClients) {
        return HAM_IGNORED;
    }

#if defined DAMAGE
    g_PlayerDamage[id] = 0.0;
#endif

    return HAM_IGNORED;
}

public HookSetModel(const ent, const model[]) {
    for (new i = 0, weapon; i < MAX_ITEM_TYPES; i++) {
        weapon = get_member(ent, m_WeaponBox_rgpPlayerItems, i);
        if (!is_nullent(weapon) && get_entvar(weapon, var_impulse) == 1) {
            SetHookChainArg(2, ATYPE_STRING, MODEL_W);
            return HC_CONTINUE;    
        }
    }
    return HC_CONTINUE;
}

#if defined DAMAGE
public HookTakeDamage(const id, inflictor, attacker, Float:damage, damageType) {
    if (
        attacker < 1 || attacker > MaxClients 
        || id == attacker 
        || attacker != inflictor 
        || (damageType & DMG_BULLET) == 0
    ) {
        return HC_CONTINUE;
    }

    if (g_PlayerDamage[attacker] > 0.0) {
        SetHookChainArg(4, ATYPE_FLOAT, damage * g_PlayerDamage[attacker]);
    }

    return HC_CONTINUE;
}
#endif
 
Сообщения
2,750
Реакции
3,013
Помог
61 раз(а)
fantom, почему не оставил данный код на "Складе полезного кода"?
 
Сообщения
2,491
Реакции
2,795
Помог
61 раз(а)
wopox1337, потому что это не законченая наработка. А так же я не проверял на работоспособность. Потому и здесь во флудилке
 
Сообщения
594
Реакции
350
Предупреждения
1
Помог
9 раз(а)
fantom, бага с перезарядкой нету?
 
Сообщения
2,143
Реакции
1,225
Помог
44 раз(а)
Лучше заюзать rg_give_custom_item и в аргументе указать GT_DROP_AND_REPLACE, т.к. если в руках будет эта кастомная M4A1, и захочешь купить обычную M4A1, то в руках появится вновь кастомная пушка.
 
Сообщения
833
Реакции
516
Помог
12 раз(а)
steelzzz, нет, минус постфрейм в некоторых пушках
 
Сообщения
2,491
Реакции
2,795
Помог
61 раз(а)
steelzzz, из вариантов которые я вижу только отправку сообщения CurWeapon. Возможно поможет. Но нужно проверить
7 Фев 2018
Я не настолько хорошый скриптер. Потому предложение. Давайте всем форумом раз и навсегда создадим грамотный подход к созданию кастом оружия
 
Сообщения
584
Реакции
1,006
Помог
18 раз(а)
steelzzz, еще нет фиксов под ItemInfo_iMaxClip, так что баг остается.
 
Сообщения
2,491
Реакции
2,795
Помог
61 раз(а)
Благодаря neygomon, Vaqtincha и еще одного скриптера который пожелал остаться неизвестным получилось сделать вот такое. Есть небольшой баг с анимации перезарядки, но он уже малозаметен. Есть еще один баг с грушитилем, но думаю будет пофикшено

C:
#include <amxmodx>
#include <hamsandwich>
#include <reapi>

#if AMXX_VERSION_NUM < 183
new MaxClients;
#endif

#define ACCESS_FLAG ADMIN_LEVEL_H
#define DAMAGE 1.5
#define CLIPSIZE 35
#define AMMOSIZE 140

#define MODEL_V "models/gold/v_m4a1.mdl"
#define MODEL_P "models/gold/p_m4a1.mdl"
#define MODEL_W "models/gold/w_m4a1.mdl"

#if defined MODEL_V || defined MODEL_P || defined MODEL_W
#define MODELS
#endif

#if defined DAMAGE
new Float:g_PlayerDamage[MAX_PLAYERS + 1];
#endif

#if defined MODELS
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() {
#if AMXX_VERSION_NUM < 183
    MaxClients = get_maxplayers();
#endif

    register_clcmd("gold_m4a1", "CmdGive");
    register_clcmd("say /gold_m4a1", "CmdGive");
    register_clcmd("say_team /gold_m4a1", "CmdGive");
   
#if defined MODELS || defined DAMAGE
    RegisterHam(Ham_Item_Deploy, "weapon_m4a1", "HookItemDeploy", 1);
#endif

#if defined MODELS
    RegisterHam(Ham_Item_Holster, "weapon_m4a1", "HookHolster", 1);
#endif

#if defined MODELS_W  
    RegisterHookChain(RG_CWeaponBox_SetModel, "HookSetModel", 0);
#endif
   
#if defined DAMAGE
    RegisterHookChain(RG_CBasePlayer_TakeDamage, "HookTakeDamage", 0);
#endif

#if defined CLIPSIZE
    RegisterHam(Ham_Weapon_Reload, "weapon_m4a1", "HookReloaded", 1);
    RegisterHookChain(RG_CBasePlayer_SetAnimation, "HookSetAnimation", 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_m4a1", GT_REPLACE, 1);
    if (is_nullent(weapon)) {
        return PLUGIN_HANDLED;
    }
   
    set_entvar(weapon, var_impulse, 1);
   
#if defined CLIPSIZE
    rg_set_iteminfo(weapon, ItemInfo_iMaxClip, CLIPSIZE);
    rg_set_user_ammo(id, WEAPON_M4A1, CLIPSIZE);
#endif

#if defined AMMOSIZE
    rg_set_user_bpammo(id, WEAPON_M4A1, AMMOSIZE);
#else
    rg_set_user_bpammo(id, WEAPON_M4A1, 90);
#endif

    return PLUGIN_HANDLED;
}

#if defined MODELS || defined DAMAGE
public HookItemDeploy(weapon) {
    new id = get_member(weapon, m_pPlayer);
    if (id < 1 || id > MaxClients) {
        return HAM_IGNORED;
    }

    if (get_entvar(weapon, var_impulse) == 0) {
        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 DAMAGE
    g_PlayerDamage[id] = DAMAGE;
#endif

    return HAM_IGNORED;
}
#endif

#if defined MODELS
public HookHolster(weapon) {
    new id = get_member(weapon, m_pPlayer);
    if (id < 1 || id > MaxClients) {
        return HAM_IGNORED;
    }

#if defined DAMAGE
    g_PlayerDamage[id] = 0.0;
#endif

    return HAM_IGNORED;
}
#endif

#if defined MODELS_W  
public HookSetModel(const ent, const model[]) {
    for (new i = 0, weapon; i < MAX_ITEM_TYPES; i++) {
        weapon = get_member(ent, m_WeaponBox_rgpPlayerItems, i);
        if (!is_nullent(weapon) && get_entvar(weapon, var_impulse) == 1) {
            SetHookChainArg(2, ATYPE_STRING, MODEL_W);
            return HC_CONTINUE;  
        }
    }
    return HC_CONTINUE;
}
#endif

#if defined DAMAGE
public HookTakeDamage(const id, inflictor, attacker, Float:damage, damageType) {
    if (
        attacker < 1 || attacker > MaxClients
        || id == attacker
        || attacker != inflictor
        || (damageType & DMG_BULLET) == 0
    ) {
        return HC_CONTINUE;
    }

    if (g_PlayerDamage[attacker] > 0.0) {
        SetHookChainArg(4, ATYPE_FLOAT, damage * g_PlayerDamage[attacker]);
    }

    return HC_CONTINUE;
}
#endif

#if defined CLIPSIZE
new bool:g_PlayerInReload[MAX_PLAYERS + 1] = { false, ... };
public HookSetAnimation(const id, PLAYER_ANIM:animation) {
    g_PlayerInReload[id] = bool:(animation == PLAYER_RELOAD);
}

public HookReloaded(weapon) {
    new id = get_member(weapon, m_pPlayer);
    if (id < 1 || id > MaxClients) {
        return HAM_IGNORED;
    }

    if (get_entvar(weapon, var_impulse) == 0) {
        return HAM_IGNORED;
    }

    if (g_PlayerInReload[id]) {
        g_PlayerInReload[id] = false;
        return HAM_IGNORED;
    }

    set_entvar(id, var_weaponanim, PLAYER_IDLE);

    message_begin(MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, .player = id);
    write_byte(cell:PLAYER_IDLE);
    write_byte(get_entvar(id, var_body));
    message_end();

    return HAM_SUPERCEDE;
}
#endif
8 Фев 2018
еще нет фиксов под ItemInfo_iMaxClip, так что баг остается.
Там сложность в том что клиент при cl_lw 1 клиент сам начинает проигривать анимацию. При отключеном предикшине все ок
 
Сообщения
3
Реакции
0
А можно ли будет прикрутить в этот плагин нативную функцию, чтобы можно было прикручивать это кастомное оружие в различные бонусные системы, например лучший игрок раунда/стим бонусы и прочее ?
 
Сообщения
2,491
Реакции
2,795
Помог
61 раз(а)
pakistan, ну это уже сами. Здесь показан алгоритм
 
Сообщения
2,491
Реакции
2,795
Помог
61 раз(а)
И так KOBRA сделал второй вариант фикса m_iMaxClip. О даном способе так же говорил steelzzz
Код:
#include < amxmodx >
#include < fakemeta >
#include < hamsandwich >
#include < reapi >

#define WEAPON_COMMAND                "say /m4a1"
#define WEAPON_ACCESS                ADMIN_IMMUNITY

#define WEAPON_NAME                    "weapon_m4a1"
#define WEAPON_TYPE                    WEAPON_M4A1
#define WEAPON_UID                    1

#define WEAPON_CLIP                    35
#define WEAPON_AMMO                    120
#define WEAPON_DAMAGE                1.5
#define WEAPON_SPEED                250.0

#define WEAPON_MODEL_VIEW            "models/v_m4a1.mdl"
#define WEAPON_MODEL_PLAYER            "models/p_m4a1.mdl"
#define WEAPON_MODEL_WORLD            "models/w_m4a1.mdl"

#if defined WEAPON_MODEL_VIEW || defined WEAPON_MODEL_PLAYER || defined WEAPON_MODEL_WORLD
    #define ENABLE_PRECACHE_MODEL
    #define PRECACHE_MODEL(%0)        engfunc( EngFunc_PrecacheModel, %0 )
#endif

public plugin_init( )
{
    register_plugin( "", "", "KOBRA" );

    #if defined WEAPON_ACCESS
        register_clcmd( WEAPON_COMMAND, "Command_GiveWeapon", WEAPON_ACCESS );
    #else
        register_clcmd( WEAPON_COMMAND, "Command_GiveWeapon" );
    #endif

    #if defined WEAPON_CLIP
        register_forward( FM_UpdateClientData, "FM_Hook_UpdateClientData_Post", true );
    #endif

    #if defined WEAPON_MODEL_VIEW || defined WEAPON_MODEL_PLAYER
        RegisterHam( Ham_Item_Deploy, WEAPON_NAME, "CBaseWeapon_Deploy_Post", true );
    #endif

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

    #if defined WEAPON_DAMAGE
        RegisterHookChain( RG_CBasePlayer_TakeDamage, "CBasePlayer_TakeDamage_Pre", false );
    #endif

    #if defined WEAPON_SPEED
        RegisterHookChain( RG_CBasePlayer_ResetMaxSpeed, "CBasePlayer_ResetMaxSpeed_Post", true );
    #endif
}

#if defined ENABLE_PRECACHE_MODEL
    public plugin_precache( )
    {
        #if defined WEAPON_MODEL_VIEW
            PRECACHE_MODEL( WEAPON_MODEL_VIEW );
        #endif

        #if defined WEAPON_MODEL_PLAYER
            PRECACHE_MODEL( WEAPON_MODEL_PLAYER );
        #endif

        #if defined WEAPON_MODEL_WORLD
            PRECACHE_MODEL( WEAPON_MODEL_WORLD );
        #endif
    }
#endif

public Command_GiveWeapon( iPlayer, iBitsLevel )
{
    #if defined WEAPON_ACCESS
        if( ~get_user_flags( iPlayer ) & iBitsLevel )
            return PLUGIN_HANDLED;
    #else
        #pragma unused iBitsLevel
    #endif

    new iWeapon = rg_give_custom_item( iPlayer, WEAPON_NAME, GT_DROP_AND_REPLACE, WEAPON_UID );

    if( is_nullent( iWeapon ) )
        return PLUGIN_HANDLED;

    #if defined WEAPON_CLIP
        rg_set_iteminfo( iWeapon, ItemInfo_iMaxClip, WEAPON_CLIP );
        rg_set_user_ammo( iPlayer, WEAPON_TYPE, WEAPON_CLIP );
    #endif

    #if defined WEAPON_AMMO
        rg_set_iteminfo( iWeapon, ItemInfo_iMaxAmmo1, WEAPON_AMMO );
        rg_set_user_bpammo( iPlayer, WEAPON_TYPE, WEAPON_AMMO );
    #endif

    return PLUGIN_HANDLED;
}

#if defined WEAPON_CLIP
    public FM_Hook_UpdateClientData_Post( iPlayer, SendWeapons, CD_Handle )
    {
        if( !is_user_alive( iPlayer ) )
            return;

        new iActiveItem = get_member( iPlayer, m_pActiveItem );

        if( iActiveItem == NULLENT )
            return;

        new WeaponIdType: iId = get_member( iActiveItem, m_iId );

        if( iId == WEAPON_TYPE && get_entvar( iActiveItem, var_impulse ) == WEAPON_UID && get_member( iActiveItem, m_Weapon_iClip ) >= WEAPON_CLIP && get_entvar( iPlayer, var_button ) & IN_RELOAD )
        {
            if( get_member( iPlayer, m_flNextAttack ) > 0.0 )
                return;

            #if WEAPON_TYPE == WEAPON_M4A1
                set_entvar( iPlayer, var_weaponanim, get_member( iActiveItem, m_Weapon_iWeaponState ) & WPNSTATE_M4A1_SILENCED ? 0 : 7 );
            #elseif WEAPON_TYPE == WEAPON_USP
                set_entvar( iPlayer, var_weaponanim, get_member( iActiveItem, m_Weapon_iWeaponState ) & WPNSTATE_USP_SILENCED ? 0 : 8 );
            #else
                set_entvar( iPlayer, var_weaponanim, 0 );
            #endif

            set_cd( CD_Handle, CD_flNextAttack, get_gametime( ) + 0.001 );
        }
    }
#endif

#if defined WEAPON_MODEL_VIEW || defined WEAPON_MODEL_PLAYER
    public CBaseWeapon_Deploy_Post( iEntity )
    {
        if( !get_entvar( iEntity, var_impulse ) )
            return;

        new iPlayer = get_member( iEntity, m_pPlayer );

        #if defined WEAPON_MODEL_VIEW
            set_entvar( iPlayer, var_viewmodel, WEAPON_MODEL_VIEW );
        #endif

        #if defined WEAPON_MODEL_PLAYER
            set_entvar( iPlayer, var_weaponmodel, WEAPON_MODEL_PLAYER );
        #endif
    }
#endif

#if defined WEAPON_MODEL_WORLD
    public CWeaponBox_SetModel_Pre( iEntity, szModel[ ] )
    {
        for( new i = 0, iWeapon; i < MAX_ITEM_TYPES; i++ )
        {
            iWeapon = get_member( iEntity, m_WeaponBox_rgpPlayerItems, i );

            if( !is_nullent( iWeapon ) && get_entvar( iWeapon, var_impulse ) == WEAPON_UID )
                SetHookChainArg( 2, ATYPE_STRING, WEAPON_MODEL_WORLD );
        }

        return HC_CONTINUE;
    }
#endif

#if defined WEAPON_DAMAGE
    public CBasePlayer_TakeDamage_Pre( iVictim, iInflictor, iAttacker, Float: flDamage, iBitsDamageType )
    {
        if( !is_user_connected( iAttacker ) || iVictim == iAttacker )
            return HC_CONTINUE;

        if( ~iBitsDamageType & ( DMG_BULLET | DMG_NEVERGIB ) )
            return HC_CONTINUE;

        if( is_user_connected( iVictim ) && !rg_is_player_can_takedamage( iVictim, iAttacker ) )
            return HC_CONTINUE;

        new iActiveItem = get_member( iAttacker, m_pActiveItem );

        if( iActiveItem == NULLENT )
            return HC_CONTINUE;

        new WeaponIdType: iId = get_member( iActiveItem, m_iId );

        if( iId == WEAPON_TYPE && get_entvar( iActiveItem, var_impulse ) == WEAPON_UID )
            SetHookChainArg( 4, ATYPE_FLOAT, flDamage * WEAPON_DAMAGE );

        return HC_CONTINUE;
    }
#endif

#if defined WEAPON_SPEED
    public CBasePlayer_ResetMaxSpeed_Post( iPlayer )
    {
        if( !is_user_alive( iPlayer ) )
            return;

        new iActiveItem = get_member( iPlayer, m_pActiveItem );

        if( iActiveItem == NULLENT )
            return;

        new WeaponIdType: iId = get_member( iActiveItem, m_iId );

        if( iId == WEAPON_TYPE && get_entvar( iActiveItem, var_impulse ) == WEAPON_UID )
            set_entvar( iPlayer, var_maxspeed, WEAPON_SPEED );
    }
#endif
 
Сообщения
265
Реакции
315
Помог
10 раз(а)
Обратите внимание, если вы хотите заключить сделку с этим пользователем, он заблокирован
Есть еще один баг с грушитилем, но думаю будет пофикшено
#define get_no_silent(%0,%1) ((%0 == WEAPON_M4A1 || %0 == WEAPON_USP) && !get_pdata_int(%1, 74, 4))
send_weapon_anim(id, get_no_silent(get_member(ent, m_iId), ent) ? (get_member(ent, m_iId) == WEAPON_USP ? 8 : 7) : 0);
8 Фев 2018
И так KOBRA сделал второй вариант фикса m_iMaxClip
FM_UpdateClientData крайне хреновая вещь.
юзать не советую в принципе для таких целей :\
вызывается крайне часто и без дела....
 
Сообщения
2,491
Реакции
2,795
Помог
61 раз(а)
Спасибо neygomon, Vaqtincha и KOBRA за указание на мои ошибки
Код:
#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 2.0 // Множитель урона. Закоментировать  если не нужно
#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 WEAPON_DAMAGE
new Float:g_PlayerDamage[MAX_PLAYERS + 1];
#endif

#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_DAMAGE || defined WEAPON_GRAVITY
    RegisterHam(Ham_Item_Deploy, WEAPON_NAME, "HookItemDeploy", 1);
#endif

#if defined WEAPON_DAMAGE || 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_DAMAGE
    RegisterHookChain(RG_CBasePlayer_TakeDamage, "HookTakeDamage", 0);
#endif

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

#if defined WEAPON_SPEED
    RegisterHookChain(RG_CBasePlayer_ResetMaxSpeed, "HookResetMaxSpeed", 1);
#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

    return PLUGIN_HANDLED;
}

#if defined MODEL_V || defined MODEL_P || defined WEAPON_DAMAGE || 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_DAMAGE
    g_PlayerDamage[id] = WEAPON_DAMAGE;
#endif

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

    return HAM_IGNORED;
}
#endif

#if defined WEAPON_DAMAGE || defined WEAPON_GRAVITY
public HookHolster(weapon) {
    new id = get_member(weapon, m_pPlayer);
    if (!is_user_connected(id)) {
        return HAM_IGNORED;
    }

#if defined WEAPON_DAMAGE
    g_PlayerDamage[id] = 0.0;
#endif

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

    return HAM_IGNORED;
}
#endif

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

#if defined WEAPON_DAMAGE
public HookTakeDamage(const id, inflictor, attacker, Float:damage, type) {
    if (
        !is_user_connected(id) ||
        id == attacker ||
        attacker != inflictor ||
        (type & (DMG_BULLET | DMG_NEVERGIB)) == 0
    ) {
        return HC_CONTINUE;
    }

    if (g_PlayerDamage[attacker] > 0.0) {
        SetHookChainArg(4, ATYPE_FLOAT, damage * g_PlayerDamage[attacker]);
    }

    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(get_entvar(id, var_body));
    message_end();

    return HAM_SUPERCEDE;
}

#endif

#if defined WEAPON_SPEED
public HookResetMaxSpeed(const id)
{
    new speed = floatround(Float:get_entvar(id, var_maxspeed));
    if (speed == 900 || speed == 1) { // Observer mode or Freeze period
        return HC_CONTINUE;
    }

    new weapon = get_member(id, m_pActiveItem);

    if(
        weapon == NULLENT ||
        WeaponIdType:get_member(weapon, m_iId ) != WEAPON_ID ||
        !IsCustomWeapon(weapon)
    ) {
        return HC_CONTINUE;
    }

    set_entvar(id, var_maxspeed, WEAPON_SPEED);
    return HC_CONTINUE;     
}
#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,449
Реакции
1,175
Помог
10 раз(а)
Можно еще добавить фикс закупа стандартного итема через обычное веапонменю, когда в руках кастом (выдает сообщение о том, что мы уже имеем этот итем и получается, что купить дефолтную пуху мы не можем, пока не дропнем этот)
Код:
new g_iWeaponID, g_iWeaponCost;
new g_iCvarBuyTime, Float:g_flBuyTime;

public plugin_precache()
{
    g_iWeaponID = rg_get_weapon_info(WEAPON_NAME, WI_ID);
    g_iWeaponCost = rg_get_weapon_info(g_iWeaponID, WI_COST);
}

public plugin_init()
{
    RegisterHookChain(RG_BuyWeaponByWeaponID, "fw_BuyWeaponByWeaponID_Pre", false);

    g_iCvarBuyTime = get_cvar_pointer("mp_buytime");
    g_flBuyTime    = get_pcvar_float(g_iCvarBuyTime);
}

public fw_BuyWeaponByWeaponID_Pre(const iIndex, const WeaponIdType:iId)
{
    if(g_flBuyTime == 0.0 || (get_gametime() - Float:get_member_game(m_fRoundStartTime) > (g_flBuyTime * 60)))
        return HC_CONTINUE;

    if(iId != WeaponIdType:g_iWeaponID && !IsCustomWeapon(iId))
        return HC_CONTINUE;

    new iPlMoney = get_member(iIndex, m_iAccount);

    if(iPlMoney >= g_iWeaponCost)
    {      
        rg_drop_item(iIndex, WEAPON_NAME);            
    } else {
        client_print(iIndex, print_center, "Недостаточно средств для покупки данного предмета!");
        SetHookChainReturn(ATYPE_INTEGER, 0);

        return HC_SUPERCEDE;
    }

    return HC_CONTINUE;
}
 
Сообщения
60
Реакции
38
Помог
1 раз(а)
fantom, #define WEAPON_DAMAGE 2.0 // Множитель урона. Закоментировать чтобы было доступно всем???)
 

d3m37r4

111111
Сообщения
1,449
Реакции
1,175
Помог
10 раз(а)
Mmonster, прост очепятка, наверно)
 

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

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