В какую часть тела прилетел снежок?

Svyatoy

Участник
Сообщения
335
Реакции
137
Добрый день, Единомышленники!
Решил увеличить урон от попадания снежка в голову и столкнулся с проблемой отслеживания точки касания. У обычных пуль не составляет проблем получить корректную hitgroup, но при попадании снежка значение всегда равно 0
Долго бился над этим вопросом и перепробовал множество вариантов, но либо я чего-то недопонимаю, либо, как говорится, глаз замылился.
Прошу вашей помощи в решении этой задачи! 🧐
 

DeathScore13

пирожок. пирожочек.
Сообщения
734
Реакции
403
попробуй вычислить по нанесённому урону
 

Mr_panica

XenForo one 💖
Сообщения
921
Реакции
436
Можно отслеживать касание снежка по игроку и записывать координаты снежка, затем вычитать z координату из координат игрока.

Если разность небольшая, то близко к голове прилетело, как-то так можно.
 

Svyatoy

Участник
Сообщения
335
Реакции
137
в разные части тела разный урон
Снежок от ноги до головы наносит 5 Hp
Увы, это эвент ослепления игрока снегом. Он срабатывает даже если в грудь попасть
Можно отслеживать касание снежка по игроку и записывать координаты снежка, затем вычитать z координату из координат игрока.

Если разность небольшая, то близко к голове прилетело, как-то так можно.
Тоже не выход, так как у всех скинов расстояние разное, даже у стандартных, даже есть смотреть от положения глаз
Сообщения автоматически склеены:

Возможно кто-то сможет реализовать через отслеживание местоположения снежка и Trace от его последнего зафиксированного положения перед попаданием, но у меня не получилось этого сделать, да и не селён я в трассировке
Буду крайне признателен за ваш вклад в зимний плагин :)
 
Последнее редактирование:

Manifest

Ура, не такой как все
Сообщения
180
Реакции
127
Данный пользователь был уличен в использовании бэкдора в приватных плагинах. Крайне не рекомендуется покупать какие либо товары у пользователя.
Снежок от ноги до головы наносит 5 Hp

Увы, это эвент ослепления игрока снегом. Он срабатывает даже если в грудь попасть

Тоже не выход, так как у всех скинов расстояние разное, даже у стандартных, даже есть смотреть от положения глаз
Сообщения автоматически склеены:

Возможно кто-то сможет реализовать через отслеживание местоположения снежка и Trace от его последнего зафиксированного положения перед попаданием, но у меня не получилось этого сделать, да и не селён я в трассировке
Буду крайне признателен за ваш вклад в зимний плагин :)
Изобретать велосипед нынче модно видимо
C-подобный:
#include <sourcemod>
#include <sdkhooks>
#include <sdktools>

new const String:PLUGIN_VERSION[] = "1.4";

new bool:g_bCheckedEngine = false;
new bool:g_bNeedsFakePrecache = false;

public Plugin:myinfo =
{
    name = "Knife Headshot",
    author = "Eyal282",
    description = "Doubles inflicted damage with knife on a successful headshot",
    version = PLUGIN_VERSION,
    url = "None."
}

new LastHitGroup[MAXPLAYERS+1][MAXPLAYERS+1]; // First is victim, second is attacker.

new Handle:hcv_Enabled = INVALID_HANDLE;
new Handle:hcv_Multiplier = INVALID_HANDLE;

public OnPluginStart()
{
    HookEvent("player_hurt", Event_PlayerHurt, EventHookMode_Pre);
    HookEvent("player_death", Event_PlayerDeath, EventHookMode_Pre);
   
    hcv_Enabled = CreateConVar("knife_headshot_enabled", "1", "Determines if to allow knife headshots", FCVAR_NOTIFY);
    hcv_Multiplier = CreateConVar("knife_headshot_multiplier", "2.0", "Determines how much to multiply knife headshot damage", FCVAR_NOTIFY);
   
    SetConVarString(CreateConVar("knife_headshot_version", PLUGIN_VERSION, "", FCVAR_NOTIFY), PLUGIN_VERSION);
   
    for(new i=1;i <= MaxClients;i++) // If plugin gets reloaded...
    {
        if(!IsClientInGame(i))
            continue;
           
        SDKHook(i, SDKHook_TraceAttack, Event_TraceAttack);
    }
}

public OnMapStart()
{              
    PrecacheSoundAny("*player/bhit_helmet-1.wav");
    PrecacheSoundAny("*player/headshot1.wav");
    PrecacheSoundAny("*player/headshot2.wav");
}

public OnClientPutInServer(client)
{
    SDKHook(client, SDKHook_TraceAttack, Event_TraceAttack);
}

// https://forums.alliedmods.net/showpost.php?p=2565252&postcount=6

// https://forums.alliedmods.net/showpost.php?p=2565443&postcount=10

// His code is broken so don't use it but I gotta give credit for it :). Also trace to only hit victim is safer than don't hit self.

// The second guy is the fix for the broken code.

public Action:Event_PlayerHurt(Handle:hEvent, const String:Name[], bool:dontBroadcast)
{
    if(!GetConVarBool(hcv_Enabled))
        return Plugin_Continue;
       
    new attacker = GetClientOfUserId(GetEventInt(hEvent, "attacker"));
   
    if(attacker == 0)
        return Plugin_Continue;
       
    new victim = GetClientOfUserId(GetEventInt(hEvent, "userid"));
   
    if(victim == attacker)
        return Plugin_Continue;
       
    new String:WeaponName[50];
   
    GetEventString(hEvent, "weapon", WeaponName, sizeof(WeaponName));
   
    if(!IsKnifeClass(WeaponName))
        return Plugin_Continue;
   
    new Float:Position[3], Float:Angles[3];
   
    GetClientEyePosition(attacker, Position);
    GetClientEyeAngles(attacker, Angles);
   
    TR_TraceRayFilter(Position, Angles, MASK_SHOT, RayType_Infinite, Trace_HitVictimOnly, victim); //Start the trace
   
    new HitGroup = TR_GetHitGroup(); //Get the hit group
   
    SetEventInt(hEvent, "hitgroup", HitGroup); // Would be nice to have Chest and legs instead of just Body.
   
    if(HitGroup == 1)
    {
        new Float:Origin[3];
        GetEntPropVector(victim, Prop_Data, "m_vecOrigin", Origin);
        SetEventBool(hEvent, "headshot", true);
       
        if(GetClientHelmet(victim))
        {
            EmitSoundToAllAny("player/bhit_helmet-1.wav", victim, SNDCHAN_AUTO, 60, _, 1.0, 100, _, Origin, _, _, _);
        }
        else
        {
            if(GetRandomBool())
                EmitSoundToAllAny("player/headshot1.wav", victim, SNDCHAN_AUTO, 60, _, 1.0, 100, _, Origin, _, _, _);
               
            else
                EmitSoundToAllAny("player/headshot2.wav", victim, SNDCHAN_AUTO, 60, _, 1.0, 100, _, Origin, _, _, _);
        }
           
    }
       
    LastHitGroup[victim][attacker] = HitGroup;
       
    return Plugin_Continue;
}

public Action:Event_PlayerDeath(Handle:hEvent, const String:Name[], bool:dontBroadcast)
{
    if(!GetConVarBool(hcv_Enabled))
        return Plugin_Continue;
       
    new attacker = GetClientOfUserId(GetEventInt(hEvent, "attacker"));
   
    if(attacker == 0)
        return Plugin_Continue;
       
    new victim = GetClientOfUserId(GetEventInt(hEvent, "userid"));
   
    if(victim == attacker)
        return Plugin_Continue;
       
    new String:WeaponName[50];
   
    GetEventString(hEvent, "weapon", WeaponName, sizeof(WeaponName));
   
    if(!IsKnifeClass(WeaponName))
        return Plugin_Continue;
   
   
    if(LastHitGroup[victim][attacker] == 1)
    {
        new Float:Origin[3];
        GetEntPropVector(victim, Prop_Data, "m_vecOrigin", Origin);
        SetEventBool(hEvent, "headshot", true);
       
        if(GetRandomBool())
            EmitSoundToAllAny("player/headshot1.wav", victim, SNDCHAN_AUTO, 60, _, 1.0, 100, _, Origin, _, _, _);
           
        else
            EmitSoundToAllAny("player/headshot2.wav", victim, SNDCHAN_AUTO, 60, _, 1.0, 100, _, Origin, _, _, _);
    }
       
    return Plugin_Continue;
}

public Action:Event_TraceAttack(victim, &attacker, &inflictor, &Float:damage, &damagetype, &ammotype, hitbox, hitgroup)
{
    if(!GetConVarBool(hcv_Enabled))
        return Plugin_Continue;
       
    else if(attacker == victim)
        return Plugin_Continue;
       
    if(!IsPlayer(attacker))
        return Plugin_Continue;
   
    new Float:Position[3], Float:Angles[3];
    GetClientEyePosition(attacker, Position);
    GetClientEyeAngles(attacker, Angles);
   
    TR_TraceRayFilter(Position, Angles, MASK_SHOT, RayType_Infinite, Trace_HitVictimOnly, victim); //Start the trace

    new HitGroup = TR_GetHitGroup(); //Get the hit group
   
    new bool:headshot = false;
   
    if (HitGroup == 1)
    {
        headshot = true;
    }

    new String:Classname[13];
   
    new weapon = GetEntPropEnt(attacker, Prop_Data, "m_hActiveWeapon");
   
    if(weapon == -1)
        return Plugin_Continue;
       
    GetEdictClassname(weapon, Classname, sizeof(Classname)); // weapon_knifegg will also be taken into consideration.

    if(!IsKnifeClass(Classname))
        return Plugin_Continue;
   
    if(headshot)
    {
        damage *= GetConVarFloat(hcv_Multiplier);
        return Plugin_Changed;
    }
       
    return Plugin_Continue;
}

public bool:Trace_HitVictimOnly(entity, contentsMask, victim)
{
    return entity == victim;
}

stock bool:GetClientHelmet(client)
{
    return bool:GetEntProp(client, Prop_Send, "m_bHasHelmet");
}

stock bool:IsPlayer(client)
{
    return (client > 0 && client <= MaxClients);
}

stock bool:GetRandomBool()
{
    return (GetRandomInt(0, 1) == 1);
}

stock bool:IsKnifeClass(const String:classname[])
{
    if(StrContains(classname, "knife") != -1)
        return true;
       
    return false;
}

// Emit sound any.

stock EmitSoundToAllAny(const String:sample[],
                 entity = SOUND_FROM_PLAYER,
                 channel = SNDCHAN_AUTO,
                 level = SNDLEVEL_NORMAL,
                 flags = SND_NOFLAGS,
                 Float:volume = SNDVOL_NORMAL,
                 pitch = SNDPITCH_NORMAL,
                 speakerentity = -1,
                 const Float:origin[3] = NULL_VECTOR,
                 const Float:dir[3] = NULL_VECTOR,
                 bool:updatePos = true,
                 Float:soundtime = 0.0)
{
    new clients[MaxClients];
    new total = 0;
   
    for (new i=1; i<=MaxClients; i++)
    {
        if (IsClientInGame(i))
        {
            clients[total++] = i;
        }
    }
   
    if (!total)
    {
        return;
    }
   
    EmitSoundAny(clients, total, sample, entity, channel,
    level, flags, volume, pitch, speakerentity,
    origin, dir, updatePos, soundtime);
}

stock bool:PrecacheSoundAny( const String:szPath[], bool:preload=false)
{
    EmitSoundCheckEngineVersion();
   
    if (g_bNeedsFakePrecache)
    {
        return FakePrecacheSoundEx(szPath);
    }
    else
    {
        return PrecacheSound(szPath, preload);
    }
}

stock static EmitSoundCheckEngineVersion()
{
    if (g_bCheckedEngine)
    {
        return;
    }

    new EngineVersion:engVersion = GetEngineVersion();
   
    if (engVersion == Engine_CSGO || engVersion == Engine_DOTA)
    {
        g_bNeedsFakePrecache = true;
    }
    g_bCheckedEngine = true;
}

stock static bool:FakePrecacheSoundEx( const String:szPath[] )
{
    decl String:szPathStar[PLATFORM_MAX_PATH];
    Format(szPathStar, sizeof(szPathStar), "*%s", szPath);
   
    AddToStringTable( FindStringTable( "soundprecache" ), szPathStar );
    return true;
}

stock EmitSoundAny(const clients[],
                 numClients,
                 const String:sample[],
                 entity = SOUND_FROM_PLAYER,
                 channel = SNDCHAN_AUTO,
                 level = SNDLEVEL_NORMAL,
                 flags = SND_NOFLAGS,
                 Float:volume = SNDVOL_NORMAL,
                 pitch = SNDPITCH_NORMAL,
                 speakerentity = -1,
                 const Float:origin[3] = NULL_VECTOR,
                 const Float:dir[3] = NULL_VECTOR,
                 bool:updatePos = true,
                 Float:soundtime = 0.0)
{
    EmitSoundCheckEngineVersion();

    decl String:szSound[PLATFORM_MAX_PATH];
   
    if (g_bNeedsFakePrecache)
    {
        Format(szSound, sizeof(szSound), "*%s", sample);
    }
    else
    {
        strcopy(szSound, sizeof(szSound), sample);
    }
   
    EmitSound(clients, numClients, szSound, entity, channel, level, flags, volume, pitch, speakerentity, origin, dir, updatePos, soundtime);  
}
 
Последнее редактирование:

Svyatoy

Участник
Сообщения
335
Реакции
137
Изо метать велосипед нынче модно видимо
C-подобный:
#include <sourcemod>
#include <sdkhooks>
#include <sdktools>

new const String:PLUGIN_VERSION[] = "1.4";

new bool:g_bCheckedEngine = false;
new bool:g_bNeedsFakePrecache = false;

public Plugin:myinfo =
{
    name = "Knife Headshot",
    author = "Eyal282",
    description = "Doubles inflicted damage with knife on a successful headshot",
    version = PLUGIN_VERSION,
    url = "None."
}

new LastHitGroup[MAXPLAYERS+1][MAXPLAYERS+1]; // First is victim, second is attacker.

new Handle:hcv_Enabled = INVALID_HANDLE;
new Handle:hcv_Multiplier = INVALID_HANDLE;

public OnPluginStart()
{
    HookEvent("player_hurt", Event_PlayerHurt, EventHookMode_Pre);
    HookEvent("player_death", Event_PlayerDeath, EventHookMode_Pre);
   
    hcv_Enabled = CreateConVar("knife_headshot_enabled", "1", "Determines if to allow knife headshots", FCVAR_NOTIFY);
    hcv_Multiplier = CreateConVar("knife_headshot_multiplier", "2.0", "Determines how much to multiply knife headshot damage", FCVAR_NOTIFY);
   
    SetConVarString(CreateConVar("knife_headshot_version", PLUGIN_VERSION, "", FCVAR_NOTIFY), PLUGIN_VERSION);
   
    for(new i=1;i <= MaxClients;i++) // If plugin gets reloaded...
    {
        if(!IsClientInGame(i))
            continue;
           
        SDKHook(i, SDKHook_TraceAttack, Event_TraceAttack);
    }
}

public OnMapStart()
{              
    PrecacheSoundAny("*player/bhit_helmet-1.wav");
    PrecacheSoundAny("*player/headshot1.wav");
    PrecacheSoundAny("*player/headshot2.wav");
}

public OnClientPutInServer(client)
{
    SDKHook(client, SDKHook_TraceAttack, Event_TraceAttack);
}

// https://forums.alliedmods.net/showpost.php?p=2565252&postcount=6

// https://forums.alliedmods.net/showpost.php?p=2565443&postcount=10

// His code is broken so don't use it but I gotta give credit for it :). Also trace to only hit victim is safer than don't hit self.

// The second guy is the fix for the broken code.

public Action:Event_PlayerHurt(Handle:hEvent, const String:Name[], bool:dontBroadcast)
{
    if(!GetConVarBool(hcv_Enabled))
        return Plugin_Continue;
       
    new attacker = GetClientOfUserId(GetEventInt(hEvent, "attacker"));
   
    if(attacker == 0)
        return Plugin_Continue;
       
    new victim = GetClientOfUserId(GetEventInt(hEvent, "userid"));
   
    if(victim == attacker)
        return Plugin_Continue;
       
    new String:WeaponName[50];
   
    GetEventString(hEvent, "weapon", WeaponName, sizeof(WeaponName));
   
    if(!IsKnifeClass(WeaponName))
        return Plugin_Continue;
   
    new Float:Position[3], Float:Angles[3];
   
    GetClientEyePosition(attacker, Position);
    GetClientEyeAngles(attacker, Angles);
   
    TR_TraceRayFilter(Position, Angles, MASK_SHOT, RayType_Infinite, Trace_HitVictimOnly, victim); //Start the trace
   
    new HitGroup = TR_GetHitGroup(); //Get the hit group
   
    SetEventInt(hEvent, "hitgroup", HitGroup); // Would be nice to have Chest and legs instead of just Body.
   
    if(HitGroup == 1)
    {
        new Float:Origin[3];
        GetEntPropVector(victim, Prop_Data, "m_vecOrigin", Origin);
        SetEventBool(hEvent, "headshot", true);
       
        if(GetClientHelmet(victim))
        {
            EmitSoundToAllAny("player/bhit_helmet-1.wav", victim, SNDCHAN_AUTO, 60, _, 1.0, 100, _, Origin, _, _, _);
        }
        else
        {
            if(GetRandomBool())
                EmitSoundToAllAny("player/headshot1.wav", victim, SNDCHAN_AUTO, 60, _, 1.0, 100, _, Origin, _, _, _);
               
            else
                EmitSoundToAllAny("player/headshot2.wav", victim, SNDCHAN_AUTO, 60, _, 1.0, 100, _, Origin, _, _, _);
        }
           
    }
       
    LastHitGroup[victim][attacker] = HitGroup;
       
    return Plugin_Continue;
}

public Action:Event_PlayerDeath(Handle:hEvent, const String:Name[], bool:dontBroadcast)
{
    if(!GetConVarBool(hcv_Enabled))
        return Plugin_Continue;
       
    new attacker = GetClientOfUserId(GetEventInt(hEvent, "attacker"));
   
    if(attacker == 0)
        return Plugin_Continue;
       
    new victim = GetClientOfUserId(GetEventInt(hEvent, "userid"));
   
    if(victim == attacker)
        return Plugin_Continue;
       
    new String:WeaponName[50];
   
    GetEventString(hEvent, "weapon", WeaponName, sizeof(WeaponName));
   
    if(!IsKnifeClass(WeaponName))
        return Plugin_Continue;
   
   
    if(LastHitGroup[victim][attacker] == 1)
    {
        new Float:Origin[3];
        GetEntPropVector(victim, Prop_Data, "m_vecOrigin", Origin);
        SetEventBool(hEvent, "headshot", true);
       
        if(GetRandomBool())
            EmitSoundToAllAny("player/headshot1.wav", victim, SNDCHAN_AUTO, 60, _, 1.0, 100, _, Origin, _, _, _);
           
        else
            EmitSoundToAllAny("player/headshot2.wav", victim, SNDCHAN_AUTO, 60, _, 1.0, 100, _, Origin, _, _, _);
    }
       
    return Plugin_Continue;
}

public Action:Event_TraceAttack(victim, &attacker, &inflictor, &Float:damage, &damagetype, &ammotype, hitbox, hitgroup)
{
    if(!GetConVarBool(hcv_Enabled))
        return Plugin_Continue;
       
    else if(attacker == victim)
        return Plugin_Continue;
       
    if(!IsPlayer(attacker))
        return Plugin_Continue;
   
    new Float:Position[3], Float:Angles[3];
    GetClientEyePosition(attacker, Position);
    GetClientEyeAngles(attacker, Angles);
   
    TR_TraceRayFilter(Position, Angles, MASK_SHOT, RayType_Infinite, Trace_HitVictimOnly, victim); //Start the trace

    new HitGroup = TR_GetHitGroup(); //Get the hit group
   
    new bool:headshot = false;
   
    if (HitGroup == 1)
    {
        headshot = true;
    }

    new String:Classname[13];
   
    new weapon = GetEntPropEnt(attacker, Prop_Data, "m_hActiveWeapon");
   
    if(weapon == -1)
        return Plugin_Continue;
       
    GetEdictClassname(weapon, Classname, sizeof(Classname)); // weapon_knifegg will also be taken into consideration.

    if(!IsKnifeClass(Classname))
        return Plugin_Continue;
   
    if(headshot)
    {
        damage *= GetConVarFloat(hcv_Multiplier);
        return Plugin_Changed;
    }
       
    return Plugin_Continue;
}

public bool:Trace_HitVictimOnly(entity, contentsMask, victim)
{
    return entity == victim;
}

stock bool:GetClientHelmet(client)
{
    return bool:GetEntProp(client, Prop_Send, "m_bHasHelmet");
}

stock bool:IsPlayer(client)
{
    return (client > 0 && client <= MaxClients);
}

stock bool:GetRandomBool()
{
    return (GetRandomInt(0, 1) == 1);
}

stock bool:IsKnifeClass(const String:classname[])
{
    if(StrContains(classname, "knife") != -1)
        return true;
       
    return false;
}

// Emit sound any.

stock EmitSoundToAllAny(const String:sample[],
                 entity = SOUND_FROM_PLAYER,
                 channel = SNDCHAN_AUTO,
                 level = SNDLEVEL_NORMAL,
                 flags = SND_NOFLAGS,
                 Float:volume = SNDVOL_NORMAL,
                 pitch = SNDPITCH_NORMAL,
                 speakerentity = -1,
                 const Float:origin[3] = NULL_VECTOR,
                 const Float:dir[3] = NULL_VECTOR,
                 bool:updatePos = true,
                 Float:soundtime = 0.0)
{
    new clients[MaxClients];
    new total = 0;
   
    for (new i=1; i<=MaxClients; i++)
    {
        if (IsClientInGame(i))
        {
            clients[total++] = i;
        }
    }
   
    if (!total)
    {
        return;
    }
   
    EmitSoundAny(clients, total, sample, entity, channel,
    level, flags, volume, pitch, speakerentity,
    origin, dir, updatePos, soundtime);
}

stock bool:PrecacheSoundAny( const String:szPath[], bool:preload=false)
{
    EmitSoundCheckEngineVersion();
   
    if (g_bNeedsFakePrecache)
    {
        return FakePrecacheSoundEx(szPath);
    }
    else
    {
        return PrecacheSound(szPath, preload);
    }
}

stock static EmitSoundCheckEngineVersion()
{
    if (g_bCheckedEngine)
    {
        return;
    }

    new EngineVersion:engVersion = GetEngineVersion();
   
    if (engVersion == Engine_CSGO || engVersion == Engine_DOTA)
    {
        g_bNeedsFakePrecache = true;
    }
    g_bCheckedEngine = true;
}

stock static bool:FakePrecacheSoundEx( const String:szPath[] )
{
    decl String:szPathStar[PLATFORM_MAX_PATH];
    Format(szPathStar, sizeof(szPathStar), "*%s", szPath);
   
    AddToStringTable( FindStringTable( "soundprecache" ), szPathStar );
    return true;
}

stock EmitSoundAny(const clients[],
                 numClients,
                 const String:sample[],
                 entity = SOUND_FROM_PLAYER,
                 channel = SNDCHAN_AUTO,
                 level = SNDLEVEL_NORMAL,
                 flags = SND_NOFLAGS,
                 Float:volume = SNDVOL_NORMAL,
                 pitch = SNDPITCH_NORMAL,
                 speakerentity = -1,
                 const Float:origin[3] = NULL_VECTOR,
                 const Float:dir[3] = NULL_VECTOR,
                 bool:updatePos = true,
                 Float:soundtime = 0.0)
{
    EmitSoundCheckEngineVersion();

    decl String:szSound[PLATFORM_MAX_PATH];
   
    if (g_bNeedsFakePrecache)
    {
        Format(szSound, sizeof(szSound), "*%s", sample);
    }
    else
    {
        strcopy(szSound, sizeof(szSound), sample);
    }
   
    EmitSound(clients, numClients, szSound, entity, channel, level, flags, volume, pitch, speakerentity, origin, dir, updatePos, soundtime);  
}
Не могу знать насчёт метания велосипеда, но знаю только, что снежок при полёте снижается.
Данный код был также обнаружен и проверен.
Он отслеживает прицел игрока, что в итоге позволяет попасть в ситуацию, когда игрок кинул снежок издалека, смотря на голову. В тоге снежок прилетает в ногу, но код засчитывает как Headshot 👍
Если бы всё было так просто....
 

Manifest

Ура, не такой как все
Сообщения
180
Реакции
127
Данный пользователь был уличен в использовании бэкдора в приватных плагинах. Крайне не рекомендуется покупать какие либо товары у пользователя.
Не могу знать насчёт метания велосипеда, но знаю только, что снежок при полёте снижается.
Данный код был также обнаружен и проверен.
Он отслеживает прицел игрока, что в итоге позволяет попасть в ситуацию, когда игрок кинул снежок издалека, смотря на голову. В тоге снежок прилетает в ногу, но код засчитывает как Headshot 👍
Если бы всё было так просто....
Зачем обращать внимание на опечатки.


Просили пример трассировки, вот он, перед вашими глазами, правильно применить его и будет шикарно.
 

Fr4nch

Кінчена птаха
Сообщения
319
Реакции
470
@Svyatoy, я если понял вопрос, и нужно увеличить урон при попадании в голову, то в чем проблема через OnTakeDamage проверять, является ли тип damage, CS_DMG_HEADSHOT, и просто увеличивать сам damage?
 

Madness aka null138

Участник
Сообщения
713
Реакции
734
можно сделать через трассировку луча при попадании в тело снежком. пустить прямой луч от снежка и получить hitgroup игрока, а если возвращает что луч не попало, то в этом случае уже пустить луч вниз, так как может быть моменты когда снежок попадает именно сверху головы.
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
А как на счёт вот этого события?
C-подобный:
    "snowball_hit_player_face"
    {
        "userid"        "short"        // player userid
    }
 

Svyatoy

Участник
Сообщения
335
Реакции
137
А как на счёт вот этого события?
C-подобный:
    "snowball_hit_player_face"
    {
        "userid"        "short"        // player userid
    }
Увы, это эвент ослепления игрока снегом. Он срабатывает даже если в грудь попасть


А как на счёт вот этого события?
C-подобный:
    "snowball_hit_player_face"
    {
        "userid"        "short"        // player userid
    }
Я пытался так сделать, но не получилось, буду признателен, если вы попробуете
@Svyatoy, я если понял вопрос, и нужно увеличить урон при попадании в голову, то в чем проблема через OnTakeDamage проверять, является ли тип damage, CS_DMG_HEADSHOT, и просто увеличивать сам damage?
Речь идёт о SDKHook? Hook_OnTakeDamage
Если да, то я не видел там возможность отследить част тела. Снежок наносит урон типа DMG_SONIC, позицию удара которого, видимо, CS даже не пытается отследить
 
Сверху Снизу