Trigger Discipline

Сообщения
2,713
Реакции
2,993
Помог
59 раз(а)
wopox1337 добавил(а) новый ресурс:

Trigger Discipline - Стреляй точнее, иначе - наказан.

Посмотреть вложение 9655
Режим "Trigger Discipline" (из update CS:GO - Operation Hydra)
Мод учит игроков стрельбе. За каждую пулю, что полетела мимо противника - игрок будет наказан на -10HP, однако если убьёт противника - будет награждён +50HP.
Рекомендуемые карты: играть можно как маленькие карты (по типу $2000$)...
Узнать больше об этом ресурсе...
 
Сообщения
198
Реакции
273
Помог
5 раз(а)
Я тут подумал, а не закинуть ли это в качестве отдельного режима игры на зомбимод? XD
 
Сообщения
203
Реакции
324
Помог
3 раз(а)
Код:
#define m_PlayerPainShock             108
set_pdata_float(id, m_PlayerPainShock, 1.0, 5)
Как еще один вариант нанесения урона без замедления: просто после события применить этот оффесет на игроке.
Еще надо зарегистрировать урон с func_wall, он тоже может встретиться. А в идеале вообще отвязаться от отлова трейсатаки по отдельным объектам и наносить урон только если игрок после выстрела не попал по игроку.
 
Сообщения
2,713
Реакции
2,993
Помог
59 раз(а)
если игрок после выстрела не попал по игроку
как представляешь себе эту реализацию? (Желательно без trace)
концепт от Garey
Код:
public TraceAttack_World_Post(iVictim, iAttacker, Float: fDamage, Float: vDirection[3], tracehandle, damagebits)
{     
    static trace, found, Float:start[3], Float:end[3];
    get_tr2(tracehandle, TR_vecEndPos, start);
    pev(iAttacker, pev_origin, end);
    engfunc(EngFunc_TraceLine, start, end, DONT_IGNORE_MONSTERS, iAttacker, trace);
    found = get_tr2(trace, TR_pHit);
    if(found && is_user_alive(found) && get_user_team(found) != get_user_team(iAttacker))
        add_user_health(iAttacker, HEALTH_BONUS);
    else
        add_user_health(iAttacker, HEALTH_PUNISH);
}
9 Июн 2018
зарегистрировать урон с func_wall
Не скажу точно, но вроде бы проверял. Урон из хука worldspawn так же подходит к func_wall.
 
Сообщения
203
Реакции
324
Помог
3 раз(а)
wopox1337, ловим события выстрела из оружия и событие трейсатаки по игроку в Pre и Post. При корректном вызове трейсатаки (если игрок попадет по противнику) запоминаем это установкой значения true для какой-то специальной переменной. В Post событии уже обрабатывать эту переменную. Соответственно там же после всех действий обнуляем.
Я не знаю, как в кс го реализовано для дробовиков, но для их поддержки я завёл счётчик атак (на каждую дробь пройдет своя трейсатака) и уже обрабатывал в Post счётчик.
9 Июн 2018
Не скажу точно, но вроде бы проверял. Урон из хука worldspawn так же подходит к func_wall.
Я не думаю так
 
Сообщения
2,713
Реакции
2,993
Помог
59 раз(а)
Последнее редактирование:
Сообщения
203
Реакции
324
Помог
3 раз(а)
wopox1337, еще в конце прошлого года) Но он приватный и для одного проекта, так что релизить не буду.
 
Сообщения
2,713
Реакции
2,993
Помог
59 раз(а)
нанесения урона без замедления
в моей реализации как раз не замедляет игрока. Если наносить урон через ExecuteHamB(Ham_TakeDamage) - то да, замедляет, что мешает непомерно, и приходится костылить. А так же clamp на health points сложнее делать. (излишние движения). Так что принял решение сделать именно такой реализацией. (мессага не страшная шлётся)
 
Последнее редактирование:
Сообщения
203
Реакции
324
Помог
3 раз(а)
Pokemoshka,
с именем пока что не определились, множество вариантов на рассмотрении. Да и до релиза проекта еще надо подождать: в разработке два глобальных и уникальных режима. Так что, пока надо подождать.
 

ssx

Сообщения
272
Реакции
71
Сперва думал такое на CSDM реализовать но потом подумал - а как игрокам тренеровать зажимы?
 
Сообщения
59
Реакции
27
Помог
1 раз(а)
как представляешь себе эту реализацию? (Желательно без trace)
концепт от Garey
Код:
public TraceAttack_World_Post(iVictim, iAttacker, Float: fDamage, Float: vDirection[3], tracehandle, damagebits)
{  
    static trace, found, Float:start[3], Float:end[3];
    get_tr2(tracehandle, TR_vecEndPos, start);
    pev(iAttacker, pev_origin, end);
    engfunc(EngFunc_TraceLine, start, end, DONT_IGNORE_MONSTERS, iAttacker, trace);
    found = get_tr2(trace, TR_pHit);
    if(found && is_user_alive(found) && get_user_team(found) != get_user_team(iAttacker))
        add_user_health(iAttacker, HEALTH_BONUS);
    else
        add_user_health(iAttacker, HEALTH_PUNISH);
}
А что если ловить Ham_Weapon_PrimaryAttack для каждого оружия, в пре выставлять глобальной переменной для игрока значение = true, а в takedamage проверять переменную, если true, то проверять дамаг?
Хотя наверное если дамага не будет, то takedamage не вызовется :\
Но можно насильно вызывать takedamage через execute
 
Сообщения
2,491
Реакции
2,790
Помог
61 раз(а)
unreal fart, В принципе как вариант.
1. Ham_Weapon_PrimaryAttack_Pre -> g_Hit = false
2. Ham_TakeDamage_Post -> g_Hit = true
3. Ham_Weapon_PrimaryAttack_Post -> если g_Hit добавляем жизнь, иначе - убираем
 
Сообщения
59
Реакции
27
Помог
1 раз(а)
fantom, Я пытался, но до меня так и не дошло как можно сделать отключение форвадов Ham_Weapon_PrimaryAttack, регистрировать их не через цикл как мне кажется глупо :\
13 Июн 2018
Версия без Trace на PrimaryAttack
Код:
#include <amxmodx>

#include <hamsandwich>
#include <fun>
#include <hlsdk_const>
#include <fakemeta>

new bool: g_bModeEnabled;

enum _:Health_settings
{
    HEALTH_PUNISH    = -10,    // How many health will be taken
    HEALTH_BONUS    = 50,    // .. given for the kill
    HEALTH_MIN        = 1,    // Min health points (HP) on player
    HEALTH_MAX        = 100,    // Max HP can be on player
}

new const g_szWeaponName[][] =
{
    "weapon_p228",
    "weapon_scout",
    "weapon_xm1014",
    "weapon_mac10",
    "weapon_aug",
    "weapon_elite",
    "weapon_fiveseven",
    "weapon_ump45",
    "weapon_sg550",
    "weapon_galil",
    "weapon_famas",
    "weapon_usp",
    "weapon_glock18",
    "weapon_awp",
    "weapon_mp5navy",
    "weapon_m249",
    "weapon_m3",
    "weapon_m4a1",
    "weapon_tmp",
    "weapon_g3sg1",
    "weapon_deagle",
    "weapon_sg552",
    "weapon_ak47",
    "weapon_p90"
};

enum _:H_TYPES_s
{
    _TakeDamage_player,
    _Killed
};

new HamHook:g_hPrimaryPre[sizeof(g_szWeaponName)];
new HamHook:g_hPrimaryPost[sizeof(g_szWeaponName)];
new HamHook:Hooks[H_TYPES_s];
new bool:g_bHit[MAX_PLAYERS + 1];

public plugin_init()
{
    register_plugin("Mode: Trigger Discipline", "0.0.2b", "wopox1337 && unrealfart @ Dev-CS.ru");

    Hooks[_TakeDamage_player] = RegisterHam(Ham_TakeDamage, "player", "CBasePlayer_TakeDamage", .Post = true, .specialbot = true);
    Hooks[_Killed] = RegisterHam(Ham_Killed, "player", "CBasePlayer_Killed_Post", .Post = true, .specialbot = true);

    for (new i; i < sizeof(g_szWeaponName); i++)
    {
        g_hPrimaryPre[i] = RegisterHam(Ham_Weapon_PrimaryAttack, g_szWeaponName[i], "CBaseWeapon_PrimaryAttack_Pre", .Post = false);
        g_hPrimaryPost[i] = RegisterHam(Ham_Weapon_PrimaryAttack, g_szWeaponName[i], "CBaseWeapon_PrimaryAttack_Post", .Post = true);
    }

    new pcvar = create_cvar
    (
        .name = "mp_gamemode_Trigger_Discipline",
        .string = "0",
        .flags = FCVAR_PROTECTED,
        .description = "Toggle Trigger Discipline mode.",
        .has_min = true,
        .min_val = 0.0,
        .has_max = true,
        .max_val = 1.0
    );

    hook_cvar_change(pcvar, "hookCvar_ModeChange");
    bind_pcvar_num(pcvar, g_bModeEnabled);

    Toggle_Mode(g_bModeEnabled);
}
public CBasePlayer_TakeDamage(pPlayer, idinflictor, iAttacker, Float:flDamage, damagebits)
{
    if(is_user_alive(iAttacker) && flDamage > 0.0)
        g_bHit[iAttacker] = true;
}
public CBasePlayer_Killed_Post(iVictim, iAttacker, shouldgib)
{
    if(is_user_alive(iAttacker))
        add_user_health(iAttacker, HEALTH_BONUS);
    // Need hud ?!
    // may be (c) unrealfart
}
public CBaseWeapon_PrimaryAttack_Pre(iWeapon)
{
    new iPlayer;
    iPlayer = pev(iWeapon, pev_owner);

    g_bHit[iPlayer] = false;
}
public CBaseWeapon_PrimaryAttack_Post(iWeapon)
{
    new iPlayer;
    iPlayer = pev(iWeapon, pev_owner);

    if(!g_bHit[iPlayer])
    {
        add_user_health(iPlayer, HEALTH_PUNISH);
        Show_DamageHUD(iPlayer);
    }
}

public hookCvar_ModeChange(pCvar)
{
    Toggle_Mode(g_bModeEnabled);

    log_amx("== [Mode %s]", g_bModeEnabled ? "enabled" : "disabled");
}
new g_szCvars_Enabled[][] =
{
    "sv_restart 1"
}
new g_szCvars_Disabled[][] =
{
    "sv_restart 1"
}
Toggle_Mode(iStatus)
{
    switch(iStatus)
    {
        case true:
        {
            for(new i; i < H_TYPES_s; i++)
            {
                if(Hooks[i])
                {
                    EnableHamForward(Hooks[i]);
                }
            }
            for(new i; i < sizeof(g_szWeaponName); i++)
            {
                if(g_hPrimaryPre[i])
                {
                    EnableHamForward(g_hPrimaryPre[i]);
                }
                if(g_hPrimaryPost[i])
                {
                    EnableHamForward(g_hPrimaryPost[i]);
                }
            }
            ExecCMDS(g_szCvars_Enabled, charsmax(g_szCvars_Enabled));
        }
        case false:
        {
            for(new i; i < H_TYPES_s; i++)
            {
                if(Hooks[i])
                {
                    DisableHamForward(Hooks[i]);
                }
            }
            for(new i; i < sizeof(g_szWeaponName); i++)
            {
                if(g_hPrimaryPre[i])
                {
                    DisableHamForward(g_hPrimaryPre[i]);
                }
                if(g_hPrimaryPost[i])
                {
                    DisableHamForward(g_hPrimaryPost[i]);
                }
            }
            ExecCMDS(g_szCvars_Disabled, charsmax(g_szCvars_Disabled));
        }
    }
}

stock ExecCMDS(szBuffer[][], const iLen)
{
    for(new i; i <= iLen; i++)
    {
        server_cmd(szBuffer[i]);
    }
}
stock add_user_health(const pPlayer, const iHealth)
{
    if(!is_user_alive(pPlayer))
        return;

    // ExecuteHam - not approach
    set_user_health(pPlayer, clamp(get_user_health(pPlayer) + iHealth, HEALTH_MIN, HEALTH_MAX));
}

Show_DamageHUD(pPlayer)
{
    static msgDamage;
    if(!msgDamage)
        msgDamage = get_user_msgid("Damage");

    static vecOrigin[3];
    get_user_origin(pPlayer, vecOrigin);

    message_begin(MSG_ONE_UNRELIABLE, msgDamage, .player = pPlayer)
    write_byte(0);
    write_byte(1);
    write_long(DMG_BULLET);
    write_coord(vecOrigin[0]);
    write_coord(vecOrigin[1]);
    write_coord(vecOrigin[2]);
    message_end();
}
 
Последнее редактирование модератором:
Сообщения
2,713
Реакции
2,993
Помог
59 раз(а)
С использованием ReAPI и оптимизацией
Код:
#include < amxmodx >
#include < fakemeta >
#include < hamsandwich >
#include < reapi >

#define gmsgDamage                                    71

#define TD_GIVE_HEALTH                                50.0 // How many health will be give
#define TD_LOSE_HEALTH                                10.0 // How many health will be lose

#define TD_MAX_HEALTH                                100.0 // Max HP can be on player
#define TD_MIN_HEALTH                                1.0 // Min health points (HP) on player

new const ENABLED_CMDS[ ][ ] = { "sv_restart 1" }; // Executed commands turn on mode
new const DISABLED_CMDS[ ][ ] = { "sv_restart 1" }; // Executed commands turn off mode

new bool: g_bModeEnabled;

new HookChain: g_hCBasePlayerTraceAttackPost;
new HookChain: g_hCBasePlayerTakeDamagePost;
new HookChain: g_hCBasePlayerKilledPost;

new HamHook: g_hPrimariesPrimaryAttackPre[ 18 ];
new HamHook: g_hPrimariesPrimaryAttackPost[ 18 ];

new HamHook: g_hSecondariesPrimaryAttackPre[ 6 ];
new HamHook: g_hSecondariesPrimaryAttackPost[ 6 ];

public plugin_init( )
{
    register_plugin( "Mode: Trigger Discipline", "0.0.2b", "wopox1337 @ Dev-Cs.Ru" );

    new cvar_toogle = create_cvar( "mp_gamemode_trigger_discipline", "0", FCVAR_PROTECTED, "Toggle Trigger Discipline mode.", true, 0.0, true, 1.0 );

    hook_cvar_change( cvar_toogle, "@CCvar_HookChange" );
    bind_pcvar_num( cvar_toogle, g_bModeEnabled );

    DisableHookChain( g_hCBasePlayerTraceAttackPost = RegisterHookChain( RG_CBasePlayer_TraceAttack, "@CBasePlayer_TraceAttack_Post", true ) );
    DisableHookChain( g_hCBasePlayerTakeDamagePost = RegisterHookChain( RG_CBasePlayer_TakeDamage, "@CBasePlayer_TakeDamage_Post", true ) );
    DisableHookChain( g_hCBasePlayerKilledPost = RegisterHookChain( RG_CBasePlayer_Killed, "@CBasePlayer_Killed_Post", true ) );

    new const szPrimaries[ 18 ][ ] = { "weapon_scout", "weapon_xm1014", "weapon_mac10", "weapon_aug", "weapon_ump45", "weapon_sg550", "weapon_galil", "weapon_famas", "weapon_awp", "weapon_mp5navy", "weapon_m249", "weapon_m3", "weapon_m4a1", "weapon_tmp", "weapon_g3sg1", "weapon_sg552", "weapon_ak47", "weapon_p90" };
    new const szSecondaries[ 6 ][ ] = { "weapon_p228", "weapon_elite", "weapon_fiveseven", "weapon_usp", "weapon_glock18", "weapon_deagle" };

    new i;

    for( i = 0; i < sizeof szPrimaries; i++ )
    {
        DisableHamForward( g_hPrimariesPrimaryAttackPre[ i ] = RegisterHam( Ham_Weapon_PrimaryAttack, szPrimaries[ i ], "@CPrimaries_PrimaryAttack_Pre", false ) );
        DisableHamForward( g_hPrimariesPrimaryAttackPost[ i ] = RegisterHam( Ham_Weapon_PrimaryAttack, szPrimaries[ i ], "@CPrimaries_PrimaryAttack_Post", true ) );
    }

    for( i = 0; i < sizeof szSecondaries; i++ )
    {
        DisableHamForward( g_hSecondariesPrimaryAttackPre[ i ] = RegisterHam( Ham_Weapon_PrimaryAttack, szSecondaries[ i ], "@CSecondaries_PrimaryAttack_Pre", false ) );
        DisableHamForward( g_hSecondariesPrimaryAttackPost[ i ] = RegisterHam( Ham_Weapon_PrimaryAttack, szSecondaries[ i ], "@CSecondaries_PrimaryAttack_Post", true ) );
    }
}

@CCvar_HookChange( iCvar )
{
    CTriggerDiscipline__ToogleStatus( g_bModeEnabled );
    log_amx( "[Trigger Discipline] Mode is %s.", g_bModeEnabled ? "enabled" : "disabled" );
}

@CBasePlayer_Killed_Post( iVictim, iAttacker, iGib )
{
    if( !is_user_connected( iAttacker ) || iVictim == iAttacker )
        return;

    set_entvar( iAttacker, var_health, floatmin( Float: get_entvar( iAttacker, var_health ) + TD_GIVE_HEALTH, TD_MAX_HEALTH ) );
}

@CBasePlayer_TraceAttack_Post( iVictim, iAttacker, Float: flDamage, Float: vecDir[ 3 ], iTrace, iBitsDamage )
{
    DisableHookChain( g_hCBasePlayerTraceAttackPost );

    if( !is_user_connected( iAttacker ) || iVictim == iAttacker )
        return;

    if( !rg_is_player_can_takedamage( iVictim, iAttacker ) )
        return;

    for( new i = 0; i < 6; i++ )
        DisableHamForward( g_hSecondariesPrimaryAttackPost[ i ] );
}

@CBasePlayer_TakeDamage_Post( iVictim, iInflictor, iAttacker, Float: flDamage, iBitsDamage )
{
    DisableHookChain( g_hCBasePlayerTakeDamagePost );

    if( !is_user_connected( iAttacker ) || iVictim == iAttacker )
        return;

    if( !rg_is_player_can_takedamage( iVictim, iAttacker ) )
        return;

    for( new i = 0; i < 18; i++ )
        DisableHamForward( g_hPrimariesPrimaryAttackPost[ i ] );
}

@CPrimaries_PrimaryAttack_Pre( iEntity )
{
    EnableHookChain( g_hCBasePlayerTakeDamagePost );

    if( get_member( iEntity, m_Weapon_fFireOnEmpty ) )
        return HAM_IGNORED;

    for( new i = 0; i < 18; i++ )
        EnableHamForward( g_hPrimariesPrimaryAttackPost[ i ] );

    return HAM_IGNORED;
}

@CPrimaries_PrimaryAttack_Post( iEntity )
{
    for( new i = 0; i < 18; i++ )
        DisableHamForward( g_hPrimariesPrimaryAttackPost[ i ] );

    CTriggerDiscipline_InflictDamage( get_member( iEntity, m_pPlayer ) );
}

@CSecondaries_PrimaryAttack_Pre( iEntity )
{
    EnableHookChain( g_hCBasePlayerTraceAttackPost );

    if( get_member( iEntity, m_Weapon_fFireOnEmpty ) || get_member( iEntity, m_Weapon_iShotsFired ) )
        return HAM_IGNORED;

    for( new i = 0; i < 6; i++ )
        EnableHamForward( g_hSecondariesPrimaryAttackPost[ i ] );

    return HAM_IGNORED;
}

@CSecondaries_PrimaryAttack_Post( iEntity )
{
    for( new i = 0; i < 6; i++ )
        DisableHamForward( g_hSecondariesPrimaryAttackPost[ i ] );

    CTriggerDiscipline_InflictDamage( get_member( iEntity, m_pPlayer ) );
}

CTriggerDiscipline__ToogleStatus( iStatus )
{
    new i;

    switch( iStatus )
    {
        case true:
        {
            EnableHookChain( g_hCBasePlayerTraceAttackPost );
            EnableHookChain( g_hCBasePlayerTakeDamagePost );
            EnableHookChain( g_hCBasePlayerKilledPost );

            for( i = 0; i < 18; i++ )
            {
                EnableHamForward( g_hPrimariesPrimaryAttackPre[ i ] );
                EnableHamForward( g_hPrimariesPrimaryAttackPost[ i ] );
            }

            for( i = 0; i < 6; i++ )
            {
                EnableHamForward( g_hSecondariesPrimaryAttackPre[ i ] );
                EnableHamForward( g_hSecondariesPrimaryAttackPost[ i ] );
            }

            CTriggerDiscipline__ExecCmds( ENABLED_CMDS, sizeof ENABLED_CMDS );
        }
        case false:
        {
            DisableHookChain( g_hCBasePlayerTraceAttackPost );
            DisableHookChain( g_hCBasePlayerTakeDamagePost );
            DisableHookChain( g_hCBasePlayerKilledPost );

            for( i = 0; i < 18; i++ )
            {
                DisableHamForward( g_hPrimariesPrimaryAttackPre[ i ] );
                DisableHamForward( g_hPrimariesPrimaryAttackPost[ i ] );
            }

            for( i = 0; i < 6; i++ )
            {
                DisableHamForward( g_hSecondariesPrimaryAttackPre[ i ] );
                DisableHamForward( g_hSecondariesPrimaryAttackPost[ i ] );
            }

            CTriggerDiscipline__ExecCmds( DISABLED_CMDS, sizeof DISABLED_CMDS );
        }
    }
}

CTriggerDiscipline_InflictDamage( iPlayer )
{
    new Float: vecOrigin[ 3 ];
    get_entvar( iPlayer, var_origin, vecOrigin );

    message_begin( MSG_ONE_UNRELIABLE, gmsgDamage, _, iPlayer );
    write_byte( 0 );
    write_byte( 1 );
    write_long( DMG_BULLET );
    engfunc( EngFunc_WriteCoord, vecOrigin[ 0 ] );
    engfunc( EngFunc_WriteCoord, vecOrigin[ 1 ] );
    engfunc( EngFunc_WriteCoord, vecOrigin[ 2 ] );
    message_end( );

    set_entvar( iPlayer, var_health, floatmax( Float: get_entvar( iPlayer, var_health ) - TD_LOSE_HEALTH, TD_MIN_HEALTH ) );
}

CTriggerDiscipline__ExecCmds( const szBuffer[ ][ ], iLen )
{
    for( new i = 0; i < iLen; i++ )
        server_cmd( szBuffer[ i ] );
}
13 Июн 2018
Поправлены мелкие недочёты
 
Последнее редактирование:
Сообщения
24
Реакции
9
Пару идей:
1. Сделать бы отлов урона, и не наказывать за попадания (Можно квар замутить)
2. СкринФейд и квары для Попадания/Промаха/Убийства
3. Уведомление в Чат и Дхуд/Худ, что нефиг мазать, ибо кара настигнет
4. Админ и Вип Флаги (или стим) которым бы Хп при Убийстве и Промахе, увеличивалось и уменьшалось НЕМНОГО больше и меньше, чем обычным игрокам
4.1 Так же для флагов, например, при убийстве, можно было бы сделать скринфейд другого цвета.
 
Сообщения
165
Реакции
-8
Неверный раздел форума
Извиняю , можете помочь мне , с этим плагином , не компилируется !
1556118479609.png
 
Сообщения
80
Реакции
24
Не думали доработать его например так: Кто стреляет мимо отнимается нужное количество жизней (настройка в конфиге) если он убивает то те жизни что были отняты возвращаются. Такой тогда плагин можно было бы и на паблик поставить допустим сделал чтобы отнималось по 1-3 хп и норм.
 
Сообщения
2,713
Реакции
2,993
Помог
59 раз(а)
отнимается нужное количество жизней (настройка в конфиге)
Настраивается, настройка описана тут: https://dev-cs.ru/resources/485/extra
если он убивает то те жизни что были отняты возвращаются
Настраивается, настройка описана тут: https://dev-cs.ru/resources/485/extra
 

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

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