No Wallbang - Plugin

CSLover

Участник
Сообщения
60
Реакции
5
Помог
2 раз(а)
Баллы
8
We used this plugin on an older server — it’s responsible for preventing players from shooting through walls.


Unfortunately, it doesn’t work anymore.


Could it possibly be fixed so that it works on the new ReHLDS servers as well?

Код:
 #include <amxmodx>
 #include <fakemeta>

 new normalTrace[33], lastTrace[33], cvEnabled, weapon, dummy;

 // plugin load
 public plugin_init()
 {
    register_plugin("No Walls","0.13","Avalanche");

    register_cvar("nowalls_version","0.13",FCVAR_SERVER);
    cvEnabled = register_cvar("nowalls_enabled","1");

    register_event("ResetHUD","event_resethud","b");
    register_clcmd("fullupdate","cmd_fullupdate");

    register_forward(FM_TraceLine,"fw_traceline");
    register_forward(FM_PlayerPostThink,"fw_playerpostthink");
 }

 // reset normal trace id on join or leave
 public client_connect(id)
 {
    normalTrace[id] = 0;
 }

 public client_disconnect(id)
 {
    normalTrace[id] = 0;
 }

 // player spawns, and some other such things
 public event_resethud(id)
 {
    lastTrace[id] = 0;
 }

 // block forced resethud call
 public cmd_fullupdate(id)
 {
    return PLUGIN_HANDLED;
 }

 // traceline hook, meat and bones of the entire plugin
 public fw_traceline(Float:vecStart[3],Float:vecEnd[3],ignoreM,id,ptr) // pentToSkip == id, for clarity
 {
    if(!is_user_connected(id))
        return FMRES_IGNORED;

    // grab normal trace
    if(!normalTrace[id])
    {
        normalTrace[id] = ptr;
        return FMRES_IGNORED;
    }

    // ignore normal trace
    else if(ptr == normalTrace[id])
        return FMRES_IGNORED;

    // no functionality
    if(!get_pcvar_num(cvEnabled))
        return FMRES_IGNORED;

    // not a player entity, or player is dead
    if(!is_user_alive(id))
        return FMRES_IGNORED;

    // not shooting anything
    if(!(pev(id,pev_button) & IN_ATTACK))
        return FMRES_IGNORED;

    weapon = get_user_weapon(id,dummy,dummy);

    // using a shotgun, expect multiple tracelines
    if(weapon == CSW_M3 || weapon == CSW_XM1014)
        return FMRES_IGNORED;

    // this is a second traceline, for shooting through walls
    if(ptr == lastTrace[id])
    {
        // values sure to throw off any traceline
        set_tr(TR_vecEndPos,Float:{4096.0,4096.0,4096.0});
        set_tr(TR_AllSolid,1);
        set_tr(TR_pHit,0);
        set_tr(TR_iHitgroup,0);
        set_tr(TR_flFraction,1.0);

        return FMRES_SUPERCEDE;
    }

    // remeber traceline index for next time
    lastTrace[id] = ptr;

    return FMRES_IGNORED;
 }

 // finished client calculations, reset our traceline index
 public fw_playerpostthink(id)
 {
    lastTrace[id] = 0;
 }
 
Последнее редактирование модератором:
Решение
This code solved my problem:

Код:
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>

// - - - - - - - -
#define PLUGIN "NoWall Damage"
#define VERSION "1.0"
// - - - - - - - -

new toggle_plugin, toggle_fade;
new g_msgscreenfade;

public plugin_init()
{
    register_plugin( PLUGIN, VERSION, "anakin_cstrike" );
    RegisterHam( Ham_TakeDamage, "player", "fw_takedamage" );
    
    toggle_plugin = register_cvar( "nowalldamage", "1" );
    toggle_fade = register_cvar( "nowalldamage_fade", "3" );
    
    g_msgscreenfade = get_user_msgid( "ScreenFade" );
}

public fw_takedamage( victim, inflictor, attacker, Float:damage, damagebits )
{
    if( ! ( damagebits & DMG_BULLET ) )
        return HAM_IGNORED;
    if( !get_pcvar_num(...
This code solved my problem:

Код:
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>

// - - - - - - - -
#define PLUGIN "NoWall Damage"
#define VERSION "1.0"
// - - - - - - - -

new toggle_plugin, toggle_fade;
new g_msgscreenfade;

public plugin_init()
{
    register_plugin( PLUGIN, VERSION, "anakin_cstrike" );
    RegisterHam( Ham_TakeDamage, "player", "fw_takedamage" );
    
    toggle_plugin = register_cvar( "nowalldamage", "1" );
    toggle_fade = register_cvar( "nowalldamage_fade", "3" );
    
    g_msgscreenfade = get_user_msgid( "ScreenFade" );
}

public fw_takedamage( victim, inflictor, attacker, Float:damage, damagebits )
{
    if( ! ( damagebits & DMG_BULLET ) )
        return HAM_IGNORED;
    if( !get_pcvar_num( toggle_plugin ) )
        return HAM_IGNORED;
        
    if( ExecuteHam( Ham_FVisible, attacker, victim ) )
        return HAM_IGNORED
    
    switch( get_pcvar_num( toggle_fade ) )
    {
        case 1:
            Fade( attacker, (1<<10), (1<<10), (1<<12), 0, 170, 0, 75 );
        case 2:
            Fade( victim, (1<<10), (1<<10), (1<<12), 255, 85, 85, 75 );
        case 3:
        {
            Fade( attacker, (1<<10), (1<<10), (1<<12), 0, 170, 0, 75 );
            Fade( victim, (1<<10), (1<<10), (1<<12), 255, 85, 85, 75 );
        }
    }
    return HAM_SUPERCEDE;
}

Fade( index, duration, holdtime, flags, red, green ,blue, alpha )
{
    message_begin( MSG_ONE_UNRELIABLE, g_msgscreenfade, { 0, 0, 0 }, index );
    write_short( duration );
    write_short( holdtime );
    write_short( flags );
    write_byte( red );
    write_byte( green );
    write_byte( blue) ;
    write_byte( alpha );
    message_end();
}
 
Решение
Если я правильно понял, суть плагина — заблокировать урон от прострелов. В таком случае советую использовать member из ReGameDLL (если есть возможность), а именно — m_ucDmgPenetrationLevel.

Дело в том, что Ham_FVisible сработает даже тогда, когда вы видите игрока не полностью, а лишь часть его модели. В результате, если вы стреляете сквозь текстуру, проверка всё равно вернёт true, и код не пойдет дальше. Но если нужно заблокировать только стены (в случае, когда игрока никак не может быть видно), то сойдет и ваш метод.

Сам сталкивался с такой проблемой ранее.
 

Кто просматривает тему

Назад
Верх