Есть ли возможность сделать так что бы в игре сквозь модель можно было пройти, но срабатывало столкновение с частью модели?

Сообщения
1,116
Реакции
346
Допустим есть модель(прикрепил и вот видео анимации в игре)
При создании в SOLID_BBOX, игрок застряет в ней изначально.

Возможно ли сделать так что бы через модель можно было пройти, но так же срабатывало столкновение части модели (например bone2) с другими entity ?

C++:
#include <amxmodx>
#include <reapi>
#include <engine>
#include <fakemeta>
#include <hamsandwich>

#include <msg_floatstocks>
 
new PLUGIN_NAME[] = "Weapon Knife 2";
new PLUGIN_VERSION[] = "1.0";
new PLUGIN_AUTHOR[] = "Karaulov";

new KNIFE_CLASSNAME[] = "weapon_unrealknife";

new KNIFE_AMMO1_CLASSNAME[] = "unrealknife_bolt1";
new KNIFE_AMMO2_CLASSNAME[] = "unrealknife_bolt2";

new KNIFE_WEAPONNAME[] = "weapon_unrealknife";

new KNIFE_WEAPON[] = "weapon_knife";

new const AMMO_NAME[] = "KnifeAmmo";
new const AMMO_ID = 16;

new const UNREAL_KNIFE_P_MODEL[] = "models/rm_reloaded/p_unreknife.mdl";
new const UNREAL_KNIFE_V_MODEL[] = "models/rm_reloaded/v_unreknife.mdl";
new const UNREAL_KNIFE_W_MODEL[] = "models/rm_reloaded/w_unreknife.mdl";

new KNIFE_SPRITE_AMMO[] = "sprites/laserbeam.spr"
new KNIFE_SPRITE_AMMO_ID = 0;

new UNREAL_KNIFE_W_MODEL_ID = 0;

new WeaponIdType: KNIFE_UNUSED_WEAPONID = WEAPON_GLOCK;
new WeaponIdType: KNIFE_FAKE_WEAPONID = WeaponIdType:77;

new MsgIdWeaponList,MsgIdAmmoPickup, FwdRegUserMsg, MsgHookWeaponList;
 
enum _:knife_e
{
    KNIFE_IDLE = 0,
    KNIFE_ATTACK1HIT,
    KNIFE_ATTACK2HIT,
    KNIFE_DRAW,
    KNIFE_STABHIT,
    KNIFE_STABMISS,
    KNIFE_MIDATTACK1HIT,
    KNIFE_MIDATTACK2HIT
}

public plugin_init()
{
    register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR);
    
    MsgIdAmmoPickup = get_user_msgid("AmmoPickup");
    
    register_clcmd(KNIFE_WEAPONNAME, "CmdSelect")
    
    RegisterHookChain(RG_CBasePlayer_AddPlayerItem, "AddItem", true);
    RegisterHookChain(RG_CBasePlayer_GiveAmmo, "CBasePlayer_GiveAmmo_Pre", false);
    
    RegisterHookChain(RG_CWeaponBox_SetModel, "CWeaponBox_SetModel_Pre");
    
    RegisterHam(Ham_Weapon_PrimaryAttack, "weapon_knife", "PrimaryAttack");
    RegisterHam(Ham_Weapon_SecondaryAttack, "weapon_knife", "SecondaryAttack");
    
    RegisterHam(Ham_Weapon_PrimaryAttack, "weapon_knife", "PrimaryAttack",true);
    RegisterHam(Ham_Weapon_SecondaryAttack, "weapon_knife", "SecondaryAttack",true);
    
    
    RegisterHookChain(RG_CBasePlayerWeapon_CanDeploy, "CBasePlayerWeapon_CanDeploy");
    RegisterHookChain(RG_CBasePlayerWeapon_DefaultDeploy, "CBasePlayerWeapon_DefaultDeploy_Pre");
}

public CmdSelect(const id)
{
    if(!is_user_alive(id)) return PLUGIN_HANDLED;

    new item = rg_get_player_item(id, KNIFE_CLASSNAME, KNIFE_SLOT);

    if(item != 0 && get_member(id, m_pActiveItem) != item) rg_switch_weapon(id, item);

    return PLUGIN_HANDLED;
}

public PrimaryAttack(pItem)
{
    if (WeaponIdType:rg_get_iteminfo(pItem,ItemInfo_iId) == KNIFE_FAKE_WEAPONID)
    {
        new pAttacker = get_entvar(pItem, var_owner);
        if (!is_user_connected(pAttacker))
            return HAM_SUPERCEDE;
            
        UTIL_WeaponAnim(pItem, KNIFE_MIDATTACK1HIT, 0.7);
        set_member(pItem, m_Weapon_flNextPrimaryAttack, 0.7);
        set_member(pItem, m_Weapon_flNextSecondaryAttack, 0.7);
        set_member(pItem, m_Weapon_flTimeWeaponIdle, 0.7);
        
        new Float:vVelocity[3] = {0.0,0.0,0.0};
        new Float:vAngles[3];
        new Float:vMins[3];
        new Float:vMaxs[3];
        new Float:vOrigin[3];
        
        get_entvar(pAttacker, var_origin, vOrigin);
        get_entvar(pAttacker, var_maxs, vMins);
        get_entvar(pAttacker, var_mins, vMaxs);
        
        for (new i = 0; i < 3; ++i)
            vOrigin[i] = (vMaxs[i] + vMins[i]) * 0.5 + vOrigin[i];
        
        vOrigin[2] -= 10;
        
        //velocity_by_aim(pAttacker, 900, vVelocity);
        
        new iEnt = rg_create_entity("info_target");
        if (!iEnt || is_nullent(iEnt))
        {
            return HAM_SUPERCEDE;
        }
        
        set_entvar(iEnt, var_classname, KNIFE_AMMO1_CLASSNAME);
        
        set_entvar(iEnt, var_model, UNREAL_KNIFE_W_MODEL);
        set_entvar(iEnt, var_modelindex, UNREAL_KNIFE_W_MODEL_ID);
        
        set_entvar(iEnt, var_mins, Float:{-2.0,-2.0,-2.0});
        set_entvar(iEnt, var_maxs, Float:{2.0,2.0,2.0});
        
        set_entvar(iEnt, var_solid, SOLID_BBOX );

        set_entvar(iEnt, var_movetype, MOVETYPE_FLY);
        
        set_entvar(iEnt, var_sequence, 1);
        set_entvar(iEnt, var_framerate, 0.2);
        
        set_entvar(iEnt, var_iuser1, pAttacker);
        
        entity_set_origin(iEnt, vOrigin);
        
    
        set_entvar(iEnt, var_velocity, vVelocity);
        
        get_entvar(pAttacker,var_v_angle,vAngles);
        
        vAngles[0] = 360 - vAngles[0];
        set_entvar(iEnt, var_angles, vAngles);

    
        te_create_following_beam(iEnt, KNIFE_SPRITE_AMMO_ID, 5, 5, 240, 0, 0, 200);
        
        
        SetTouch(iEnt, "TouchAmmo1");
        
        return HAM_SUPERCEDE;
    }
    return HAM_IGNORED;
}

public TouchAmmo1(const rune_ent, const player_id)
{
    if (!is_nullent(rune_ent))
    {
        new pAttacker = get_entvar(rune_ent,var_iuser1)
        if (pAttacker != player_id)
        {
            set_entvar(rune_ent, var_nextthink, get_gametime());
            set_entvar(rune_ent, var_flags, FL_KILLME);
            client_print_color(0,print_team_red,"%d %d",rune_ent,player_id);
            if (player_id >= 1 && player_id <= MAX_PLAYERS && is_user_connected(player_id))
            {
                
            }
        }
    }
}

public SecondaryAttack(pItem)
{
    if (WeaponIdType:rg_get_iteminfo(pItem,ItemInfo_iId) == KNIFE_FAKE_WEAPONID)
    {
        UTIL_WeaponAnim(pItem, KNIFE_STABHIT, 4.0);
        set_member(pItem, m_Weapon_flNextPrimaryAttack, 1.0);
        set_member(pItem, m_Weapon_flNextSecondaryAttack, 4.0);
        set_member(pItem, m_Weapon_flTimeWeaponIdle, 2.0);
        
        return HAM_SUPERCEDE;
    }
    return HAM_IGNORED;
}

public plugin_precache() {

    precache_generic("sprites/weapon_unrealknife.txt");
    precache_generic("sprites/unreal_knife.spr");

    KNIFE_SPRITE_AMMO_ID = precache_model(KNIFE_SPRITE_AMMO);
    
    precache_model(UNREAL_KNIFE_P_MODEL);
    UNREAL_KNIFE_W_MODEL_ID = precache_model(UNREAL_KNIFE_W_MODEL);
    precache_model(UNREAL_KNIFE_V_MODEL);
    
    MsgIdWeaponList = get_user_msgid("WeaponList");
    if (MsgIdWeaponList)
    {
        MsgHookWeaponList = register_message(MsgIdWeaponList, "HookWeaponList");
    }
    else
    {
        FwdRegUserMsg = register_forward(FM_RegUserMsg, "RegUserMsg_Post", true);
    }
}

public CBasePlayerWeapon_CanDeploy(const pItem) {

    if(is_nullent(pItem))
        return HC_CONTINUE;

    if (WeaponIdType:rg_get_iteminfo(pItem,ItemInfo_iId) == KNIFE_FAKE_WEAPONID)
    {
        SetHookChainReturn(ATYPE_INTEGER, true);
    }
    return HC_CONTINUE;
}

public CBasePlayerWeapon_DefaultDeploy_Pre(const pItem, szViewModel[], szWeaponModel[], iAnim, szAnimExt[], skiplocal)
{
    if (is_nullent(pItem)) return HC_CONTINUE;

    if (WeaponIdType:rg_get_iteminfo(pItem,ItemInfo_iId) == KNIFE_FAKE_WEAPONID)
    {
        SetHookChainArg(2, ATYPE_STRING, UNREAL_KNIFE_V_MODEL);
        SetHookChainArg(3, ATYPE_STRING, UNREAL_KNIFE_P_MODEL);
        
        UTIL_WeaponAnim(pItem, KNIFE_DRAW, 2.0);
        set_member(pItem, m_Weapon_flNextPrimaryAttack, 1.0);
        set_member(pItem, m_Weapon_flNextSecondaryAttack, 1.0);
        set_member(pItem, m_Weapon_flTimeWeaponIdle, 1.0);
    }
    return HC_CONTINUE;
}

public CWeaponBox_SetModel_Pre(const iWeaponBox)
{
    new pItem = func_GetWeaponBoxWeapon(iWeaponBox);
    if (pItem == NULLENT) return HC_CONTINUE;
    
    if ( WeaponIdType:rg_get_iteminfo(pItem,ItemInfo_iId) == KNIFE_FAKE_WEAPONID)
    {
        SetHookChainArg(2, ATYPE_STRING, UNREAL_KNIFE_W_MODEL);
    }
    return HC_CONTINUE;
}

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;
}

public RegUserMsg_Post(const name[])
{
    if (strcmp(name, "WeaponList") == 0)
    {
        MsgIdWeaponList = get_orig_retval();
        MsgHookWeaponList = register_message(MsgIdWeaponList, "HookWeaponList");
    }
}

public HookWeaponList(const msg_id, const msg_dst, const msg_entity)
{
    enum
    {
        arg_name = 1,
        arg_ammo1,
        arg_ammo1_max,
        arg_ammo2,
        arg_ammo2_max,
        arg_slot,
        arg_position,
        arg_id,
        arg_flags,
    };

    if (msg_dst != MSG_INIT || WeaponIdType:get_msg_arg_int(arg_id) != WEAPON_KNIFE)
    {
        return PLUGIN_CONTINUE;
    }
    
    if (FwdRegUserMsg)
    {
        unregister_forward(FM_RegUserMsg, FwdRegUserMsg, true);
    }
    
    unregister_message(MsgIdWeaponList, MsgHookWeaponList);
    
    UTIL_WeaponList(MSG_INIT,0,_, KNIFE_WEAPONNAME,AMMO_ID,
                    1,get_msg_arg_int(arg_ammo2),get_msg_arg_int(arg_ammo2_max),
                    get_msg_arg_int(arg_slot),get_msg_arg_int(arg_position) + 1,cell:KNIFE_UNUSED_WEAPONID,get_msg_arg_int(arg_flags));
    
    return PLUGIN_CONTINUE;
}

public CBasePlayer_GiveAmmo_Pre(const id, const amount, const name[]) {
    if (strcmp(name, AMMO_NAME) != 0) {
        return HC_CONTINUE;
    }

    giveAmmo(id, amount, AMMO_ID, 1);
    SetHookChainReturn(ATYPE_INTEGER, AMMO_ID);
    return HC_SUPERCEDE;
}

stock rg_get_player_item(const id, const classname[], const InventorySlotType:slot = NONE_SLOT) {
    new item = get_member(id, m_rgpPlayerItems, slot);
    while (!is_nullent(item)) {
        if (FClassnameIs(item, classname)) {
            return item;
        }
        item = get_member(item, m_pNext);
    }

    return 0;
}

giveKnife(const id)
{
    new item = rg_get_player_item(id, KNIFE_CLASSNAME, KNIFE_SLOT);
    if (item != 0) {
        giveAmmo(id, 1, AMMO_ID, 1);
        return item;
    }

    item = rg_create_entity(KNIFE_WEAPON, false);
    if (is_nullent(item)) {
        return NULLENT;
    }

    new Float:origin[3];
    get_entvar(id, var_origin, origin);
    set_entvar(item, var_origin, origin);
    set_entvar(item, var_spawnflags, get_entvar(item, var_spawnflags) | SF_NORESPAWN);

    set_member(item, m_Weapon_iPrimaryAmmoType, AMMO_ID);
    set_member(item, m_Weapon_iSecondaryAmmoType, -1);

    set_entvar(item, var_classname, KNIFE_CLASSNAME);

    dllfunc(DLLFunc_Spawn, item);

    set_member(item, m_iId, KNIFE_UNUSED_WEAPONID);

    rg_set_iteminfo(item, ItemInfo_pszName, KNIFE_WEAPONNAME);
    rg_set_iteminfo(item, ItemInfo_pszAmmo1, AMMO_NAME);
    rg_set_iteminfo(item, ItemInfo_iMaxAmmo1, 1);
    rg_set_iteminfo(item, ItemInfo_iId, KNIFE_FAKE_WEAPONID);
    rg_set_iteminfo(item, ItemInfo_iPosition, 10);
    rg_set_iteminfo(item, ItemInfo_iWeight, 1);
    rg_set_iteminfo(item, ItemInfo_iSlot, KNIFE_SLOT);

    dllfunc(DLLFunc_Touch, item, id);

    if (get_entvar(item, var_owner) != id) {
        set_entvar(item, var_flags, FL_KILLME);
        return NULLENT;
    }
    giveAmmo(id, 1, AMMO_ID, 1);
    return item;
}

giveAmmo(const id, const amount, const ammo, const maxammo) {
    if (!is_user_connected(id) || get_entvar(id, var_flags) & FL_SPECTATOR) {
        return;
    }

    new count = get_member(id, m_rgAmmo, ammo);
    new addammo = min(amount, maxammo - count);
    if (addammo < 1) {
        return;
    }

    set_member(id, m_rgAmmo, count + addammo, ammo);

    message_begin(MSG_ONE, MsgIdAmmoPickup, .player = id);
    write_byte(ammo);
    write_byte(addammo);
    message_end();
}
 
public AddItem(id, pItem)
{
    if (is_nullent(pItem))
        return HC_CONTINUE;
    
    if (get_member(pItem, m_iId) == WEAPON_KNIFE)
        giveKnife(id);
    
    return HC_CONTINUE;
}


stock UTIL_WeaponAnim(pItem, iSequence, Float:flDuration) {
    PlayWeaponAnim(pItem, iSequence);
    set_member(pItem, m_Weapon_flTimeWeaponIdle, flDuration);
}

stock SendPlayerWeaponAnim(pPlayer, pWeapon, iAnim)
{
    if (!is_user_connected(pPlayer))
        return;
    set_entvar(pPlayer, var_weaponanim, iAnim);
    message_begin(MSG_ONE, SVC_WEAPONANIM, _, pPlayer);
    write_byte(iAnim);
    write_byte(get_entvar(pWeapon, var_body));
    message_end();

}

stock PlayWeaponAnim(pItem, iAnim) {
    new pPlayer = get_entvar(pItem,var_owner);
    
    SendPlayerWeaponAnim(pPlayer, pItem, iAnim);

    for (new pSpectator = 1; pSpectator <= MaxClients; pSpectator++) {
        if (!is_user_connected(pSpectator)) {
            continue;
        }

        if (get_entvar(pSpectator, var_iuser1) != OBS_IN_EYE) {
            continue;
        }

        if (get_entvar(pSpectator, var_iuser2) != pPlayer) {
            continue;
        }

        SendPlayerWeaponAnim(pSpectator, pItem, iAnim);
    }
}

 
// from https://github.com/YoshiokaHaruki/AMXX-Dynamic-Crosshair
stock UTIL_WeaponList( const iDest, const pReceiver, const pItem = -1, szWeaponName[ ] = "", const iPrimaryAmmoType = -2, iMaxPrimaryAmmo = -2, iSecondaryAmmoType = -2, iMaxSecondaryAmmo = -2, iSlot = -2, iPosition = -2, iWeaponId = -2, iFlags = -2 )
{
    if (pReceiver != 0 && !is_user_connected(pReceiver))
        return;
    static iMsgId_Weaponlist; if ( !iMsgId_Weaponlist ) iMsgId_Weaponlist = get_user_msgid( "WeaponList" );
 
    message_begin( iDest, iMsgId_Weaponlist, .player = pReceiver );
    if ( szWeaponName[ 0 ] == EOS && pItem > 0)
    {   
        new szWeaponName2[128];
        rg_get_iteminfo( pItem, ItemInfo_pszName, szWeaponName2, charsmax( szWeaponName2 ) )
        write_string( szWeaponName2 );
    }
    else
        write_string( szWeaponName );
        
    write_byte( ( iPrimaryAmmoType <= -2 && pItem > 0 ) ? get_member( pItem, m_Weapon_iPrimaryAmmoType ) : iPrimaryAmmoType );
    write_byte( ( iMaxPrimaryAmmo <= -2 && pItem > 0 ) ? rg_get_iteminfo( pItem, ItemInfo_iMaxAmmo1 ) : iMaxPrimaryAmmo );
    write_byte( ( iSecondaryAmmoType <= -2 && pItem > 0 ) ? get_member( pItem, m_Weapon_iSecondaryAmmoType ) : iSecondaryAmmoType );
    write_byte( ( iMaxSecondaryAmmo <= -2 && pItem > 0 ) ? rg_get_iteminfo( pItem, ItemInfo_iMaxAmmo2 ) : iMaxSecondaryAmmo );
    write_byte( ( iSlot <= -2 && pItem > 0 ) ? rg_get_iteminfo( pItem, ItemInfo_iSlot ) : iSlot );
    write_byte( ( iPosition <= -2 && pItem > 0 ) ? rg_get_iteminfo( pItem, ItemInfo_iPosition ) : iPosition );
    write_byte( ( iWeaponId <= -2 && pItem > 0 ) ? rg_get_iteminfo( pItem, ItemInfo_iId ) : iWeaponId );
    write_byte( ( iFlags <= -2 && pItem > 0 ) ? rg_get_iteminfo( pItem, ItemInfo_iFlags ) : iFlags );
    
    message_end( );
}

Не уверен в чем проблема, в модели или в SOLID_ типе, или вообще в том что это не возможно сделать?
 

Вложения

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

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