[GUIA] Detectar Ataques de Knife
#1
Me nació querer publicar esto ya que, a diferencia del resto, se ve poco y para muchos debe ser interesante Whatever

Si bien saben, el cuchillo tiene 2 ataques, el Primario, y Segundario.

► El Primario se divide en 2:
  • Primer Ataque: Si han pasado más de 0.4 segundos desde el Primer Ataque, este dará 20 de Damage.
  • Ataque Constante: Condición contraria a la anterior, este dará 15 de Damage.

Es por eso que al estar pegando con Primario, el primero siempre quita más y el resto 15.

Referencia SDK:

Código PHP:
ClearMultiDamage();
float damage = ( m_flNextPrimaryAttack 0.4 UTIL_WeaponTimeBase() ) ? 20.0 15.0;

pEntity->TraceAttackm_pPlayer->pevdamagegpGlobals->v_forward, &trDMG_BULLET DMG_NEVERGIB );
ApplyMultiDamagem_pPlayer->pevm_pPlayer->pev ); 

► El Segundario se divide en 2:
  • Espalda: Si se le llega a dar un Stab en la Espalda del Jugador, este dará 195 (65 * 3) de Damage.
  • Cuerpo: En cualquier parte del cuerpo excluyendo la espalda, este dará 65 de Damage.[/b].

El CS calcula la "espada" del jugador con respecto a sus angulos de vision. No es especificamente la espalda, puesto que es solo la parte trasera de su vision -> infiero que si le das en los pies también habrá multiplo por 3.

Referencia SDK:

Código PHP:
// Arkshine
        
float damage 65.0;

        if( 
pEntity && pEntity->IsPlayer() )
        {
            
Vector2D vec2LOS;
            
Vector   vecForward gpGlobals->v_forward;

            
UTIL_MakeVectorsm_pPlayer->pev->angles );

            
vec2LOS vecForward.Make2D();
            
vec2LOS vec2LOS.Normalize();

            if( 
DotProductvec2LOSgpGlobals->v_forward.Make2D() ) > 0.8 )
            {
                
damage *= 3.0;
            }
        } 

El calculo es medio raro, pasé Física con 50% asi que no me hinchen Nothingdohere

Todos los daños realizados con el cuchillo pasan por la multiplicación de daño según el hitbox del jugador (si es a una entidad, pasa directo), puesto que si quieres detectar ataque de un Knife con respecto a su daño, será falso positivo en más del 50% de los casos.

Es por eso que aquí les dejo métodos hábiles y decentes para detectar el ataque de un Knife.

Partamos por lo más sencillo. Estos metodos son validos para TakeDamage y TraceAttack, debido que uno llama al otro. Lo que si:

TakeDamage pasa el daño ya multiplicado por la diferencia de los hitboxes
TraceAttack pasa el daño entero, dentro de esta misma funcion llama a TakeDamage con el daño multiplicado.

Todo depende de lo que quieran hacer.

1) Los Damage Bits del daño siempre serán DMG_BULLET | DMG_NEVERGIB, es primordial su chequeo y no es costoso de rendimiento debido que el parametro DamageBits es una variable ya.

2) El Atacante será siempre igual a quien Infringe el Damage. (attacker == inflictor)

3) Antes de efectuar el Daño, se llama SendWeaponAnim actualizando el valor de pev->weaponanim, el que podemos utilizar para chequear.

*** No incluyo el metodo de chequeo con los botones debido que un usuario puede estar presionando los 2 al mismo tiempo y causar falsos positivos. Hay un metodo de arreglarlo pero no vale la pena con lo escrito arriba. ***

Se vería algo así:

Código PHP:
#include <amxmodx>
#include <hamsandwich>
#include <engine>

enum
{
    
KNIFE_IDLE1 0,
    
KNIFE_SLASH1,
    
KNIFE_SLASH2,
    
KNIFE_DRAW,
    
KNIFE_STAB,
    
KNIFE_STAB_MISS,
    
KNIFE_MIDSLASH1,
    
KNIFE_MIDSLASH2
};

public 
plugin_init()
{
    
register_plugin("Deteccion de Ataques de Cuchillo""0.1""PM");
    
    
RegisterHam(Ham_TakeDamage"player""OnPlayer_TakeDamage");
}

public 
OnPlayer_TakeDamage(iVictimiInflictoriAttackerFloat:flDamagebitsDamageType)
{
    if(
iAttacker == iInflictor && bitsDamageType == (DMG_BULLET|DMG_NEVERGIB) && is_user_alive(iAttacker) && get_user_weapon(iAttacker) == CSW_KNIFE
    
// is_user_alive lo dejo al final, asi no hago que llame siempre a la native vez que se llame TakeDamage
    // dejando primero los chequeos de parametros que no hacen nada en comparacion a una native.
    
{
        new 
iAnim entity_get_int(iAttackerEV_INT_weaponanim);
        
// no le doy static debido a que TakeDamage, puede ser brutalmente llamado en hordas de ataques, pero no es el caso de un Knife
        
        
if(KNIFE_STAB <= iAnim <= KNIFE_STAB_MISS)
            
client_print(iVictimprint_center"Te han atacado con un Golpe Segundario de Cuchillo");
        else if(
KNIFE_MIDSLASH1 <= iAnim <= KNIFE_MIDSLASH2// es necesario aun asi, hay que ponerse en cualquier caso...
            
client_print(iVictimprint_center"Te han atacado con un Golpe Primario de Cuchillo");
    }


Para poder detectar si fue por la espalda, podemos transformar el codigo del mismo SDK. Me quedó algo así, sean libres de utilizarlo

Código PHP:
stock IsBackStab(iVictimiAttacker)
{
    
// Angulos del Atacante
    
new Float:vecFwd[3];
    
entity_get_vector(iAttackerEV_VEC_v_anglevecFwd);
    
angle_vector(vecFwdANGLEVECTOR_FORWARDvecFwd);
    
    
vecFwd[2] = 0.0 // 3D a 2D
    
xs_vec_normalize(vecFwdvecFwd);
    
    
// Angulos de Cuerpo de la Victima
    
new Float:vecVictimFwd[3]
    
entity_get_vector(iVictimEV_VEC_anglesvecVictimFwd);
    
angle_vector(vecVictimFwdANGLEVECTOR_FORWARDvecVictimFwd);
    
    
vecVictimFwd[2] = 0.0 // 3D a 2D
    
    
return xs_vec_dot(vecFwdvecVictimFwd) > 0.8;


Y en conjunto con el plugin, sería:

Código PHP:
#include <amxmodx>
#include <hamsandwich>
#include <engine>
#include <xs>

enum
{
    
KNIFE_IDLE1 0,
    
KNIFE_SLASH1,
    
KNIFE_SLASH2,
    
KNIFE_DRAW,
    
KNIFE_STAB,
    
KNIFE_STAB_MISS,
    
KNIFE_MIDSLASH1,
    
KNIFE_MIDSLASH2
};

public 
plugin_init()
{
    
register_plugin("Deteccion de Ataques de Cuchillo""0.1""PM");
    
    
RegisterHam(Ham_TakeDamage"player""OnPlayer_TakeDamage");
}

public 
OnPlayer_TakeDamage(iVictimiInflictoriAttackerFloat:flDamagebitsDamageType)
{
    if(
iAttacker == iInflictor && bitsDamageType == (DMG_BULLET|DMG_NEVERGIB) && is_user_alive(iAttacker) && get_user_weapon(iAttacker) == CSW_KNIFE
    
// is_user_alive lo dejo al final, asi no hago que llame siempre a la native vez que se llame TakeDamage
    // dejando primero los chequeos de parametros que no hacen nada en comparacion a una native.
    
{
        if( (
KNIFE_STAB <= entity_get_int(iAttackerEV_INT_weaponanim) <= KNIFE_STAB_MISS) && IsBackStab(iVictimiAttacker) )
            
client_print(iVictimprint_center"Te han atacado con un Golpe Segundario de Cuchillo, y por la espalda, uugh");
    }
}

stock IsBackStab(iVictimiAttacker)
{
    
// Angulos del Atacante
    
new Float:vecFwd[3];
    
entity_get_vector(iAttackerEV_VEC_v_anglevecFwd);
    
angle_vector(vecFwdANGLEVECTOR_FORWARDvecFwd);
    
    
vecFwd[2] = 0.0 // 3D a 2D
    
xs_vec_normalize(vecFwdvecFwd);
    
    
// Angulos de Cuerpo de la Victima
    
new Float:vecVictimFwd[3]
    
entity_get_vector(iVictimEV_VEC_anglesvecVictimFwd);
    
angle_vector(vecVictimFwdANGLEVECTOR_FORWARDvecVictimFwd);
    
    
vecVictimFwd[2] = 0.0 // 3D a 2D
    
    
return xs_vec_dot(vecFwdvecVictimFwd) > 0.8;


EXISTE OTRO METODO, no llama al módulo, pero si genera muchas llamadas. Es útil y pueden utilizarlo tal cual como el code de arriba. Solo que aquí utilizamos variables.

Código PHP:
#include <amxmodx>
#include <hamsandwich>
#include <engine>
#include <xs>

enum KnifeAttack
{
    
KA_NONE 0,
    
KA_SLASH,
    
KA_STAB
}

new 
KnifeAttack:g_iKnifeAttack

public plugin_init()
{
    
register_plugin("Deteccion de Ataques de Cuchillo""0.1""PM");
    
    
RegisterHam(Ham_TakeDamage"player""OnPlayer_TakeDamage");
    
    
RegisterHam(Ham_Weapon_PrimaryAttack"weapon_knife""OnKnife_PrimaryAttack")
    
RegisterHam(Ham_Weapon_SecondaryAttack"weapon_knife""OnKnife_SecondaryAttack")
    
    
RegisterHam(Ham_Weapon_PrimaryAttack"weapon_knife""OnKnife_Attack_Post"true)
    
RegisterHam(Ham_Weapon_SecondaryAttack"weapon_knife""OnKnife_Attack_Post"true)
}

public 
OnPlayer_TakeDamage(iVictimiInflictoriAttackerFloat:flDamagebitsDamageType)
{
    if(
iAttacker == iInflictor && bitsDamageType == (DMG_BULLET|DMG_NEVERGIB) && is_user_alive(iAttacker)) 
    
// is_user_alive lo dejo al final, asi no hago que llame siempre a la native vez que se llame TakeDamage
    // dejando primero los chequeos de parametros que no hacen nada en comparacion a una native.
    
{
        if( 
g_iKnifeAttack == KA_STAB && IsBackStab(iVictimiAttacker) )
            
client_print(iVictimprint_center"Te han atacado con un Golpe Segundario de Cuchillo, y por la espalda, uugh");
    }
}

public 
OnKnife_PrimaryAttack() g_iKnifeAttack KA_SLASH;
public 
OnKnife_SecondaryAttack() g_iKnifeAttack KA_STAB;
public 
OnKnife_Attack_Post() g_iKnifeAttack KA_NONE;


stock IsBackStab(iVictimiAttacker)
{
    
// Angulos del Atacante
    
new Float:vecFwd[3];
    
entity_get_vector(iAttackerEV_VEC_v_anglevecFwd);
    
angle_vector(vecFwdANGLEVECTOR_FORWARDvecFwd);
    
    
vecFwd[2] = 0.0 // 3D a 2D
    
xs_vec_normalize(vecFwdvecFwd);
    
    
// Angulos de Cuerpo de la Victima
    
new Float:vecVictimFwd[3]
    
entity_get_vector(iVictimEV_VEC_anglesvecVictimFwd);
    
angle_vector(vecVictimFwdANGLEVECTOR_FORWARDvecVictimFwd);
    
    
vecVictimFwd[2] = 0.0 // 3D a 2D
    
    
return xs_vec_dot(vecFwdvecVictimFwd) > 0.8;


Dentro de PrimaryAttack y SecondaryAttack no hay restricciones de por medio en las que no exista un ataque de cuchillo. (A excepcion de SecondaryAttack cuando se tiene Escudo, por que no hay daño)

Es por eso que la asignacion en las variables es inmediata, no hay mayor enrredo ahí.

Cualquier duda pueden avisar, es un area algo rebuscada y me animé en aclarar algunas cosas con esta guia. Proud espero la reputacion gordos de $%#&@

Referencias: https://github.com/Arkshine/CSSDK/blob/m..._knife.cpp
Responder
#2
Como desearía tener tantos conocimientos como vos :/ que envidia. Whatdone
Responder
#3
excelente guía, algunas cosas no las entendí , pero con releerlo lo entenderé, cualquier cosa si no llego a entenderlo preguntaré.

te daría rep, pero ya te di Whatever
Responder
#4
Rainbow
Buena guía metalicross
[Imagen: b_350_20_323957_202743_f19a15_111111.png]

Estudia siempre; el tiempo es oro, lo material se puede recuperar pero el tiempo no se puede recuperar.
(02/10/2016, 05:05 PM)meTaLiCroSS escribió: Siempre me gusta ayudar cuando alguien esta interesado realmente en ver que esta programando.
(08/08/2019, 05:32 PM)meTaLiCroSS escribió: grax x el dato cr4ck


Mis aportes

PLUGINS
MAPAS
Menú LANG [SF] Sistema de Frags
Say System (Admin Prefix)
Responder
#5
Muy buena guia Roflmao entendí casi todo
Responder
#6
Exelente guia metal, al menos entendere este Whatever

(21/01/2015, 05:39 PM)kenshiNN escribió: Como desearía tener tantos conocimientos como vos :/ que envidia. Whatdone

Yo tambien quisiera tener ese conocimiento, pero date cuenta que nadie aca nacio sabiendo, todos, hasta el pt meTaLiCroSS inicio como nosotros, sin saber ni como crear una variable o por lo menos saber lo minimo Roflmao

Si no me crees, cree lo que salio de sus mismas palabras (esto lo encontre por ahi en alliedmodders pacman, solo date tiempo de leerlo todo completo y en calma)

[ES] Solo un Simple empujon para los Novatos (meTaLiCroSS)
P.D: pacman pacman pacman j1j1j1j1

P.D2: Disculpen el off y nuevamente, buena guia, bastante interesante Rainbow

EDIT: Aprovechando la ocasion, date una pasada por el foro de Plugins nuevos que necesitan desempolvarse un poco pacman
Heber[S]ourcE
Veteran Member
in
Desvirtue
Tatakae
Responder
#7
buena guia

aja!! una duda,

por que si tanto el atacante y la victima van a una alta velocidad asi le peges en una pata con el SecondaryAttack, se saca mas de 200???
Competitive/Face it Pick Up Game (PUG) servidor de prueba: 45.77.94.109:27016 Click para Entrar
[Imagen: b_350_20_5A6C3E_383F2D_D2E1B5_2E3226.png]

(14/08/2015, 10:15 PM)Sugisaki escribió: "El mundo es caotico, irracional e injusto. No tiene ningun significado"
Palabras que desde hace mucho tiempo he buscado para describir, ¿Que es el mundo?
Crab

Código PHP:
if(ayuda && free)
{
    exit();

Responder
#8
(21/01/2015, 07:31 PM)Sugisaki escribió: buena guia

aja!! una duda,

por que si tanto el atacante y la victima van a una alta velocidad asi le peges en una pata con el SecondaryAttack, se saca mas de 200???

Headshot quizas?
Responder
#9
(21/01/2015, 06:51 PM)Heber[$]ource escribió: Exelente guia metal, al menos entendere este Whatever

(21/01/2015, 05:39 PM)kenshiNN escribió: Como desearía tener tantos conocimientos como vos :/ que envidia. Whatdone

Yo tambien quisiera tener ese conocimiento, pero date cuenta que nadie aca nacio sabiendo, todos, hasta el pt meTaLiCroSS inicio como nosotros, sin saber ni como crear una variable o por lo menos saber lo minimo Roflmao

Si no me crees, cree lo que salio de sus mismas palabras (esto lo encontre por ahi en alliedmodders pacman, solo date tiempo de leerlo todo completo y en calma)

[ES] Solo un Simple empujon para los Novatos
P.D: pacman pacman pacman j1j1j1j1

P.D2: Disculpen el off y nuevamente, buena guia, bastante interesante Rainbow

Totalmente cierto, aún recuerdo cuando hacía mi deathmatch y no sabía qué significaba poner "id" en las funciones Whatdone

Buen tuto maderacross.

Hermosa física vectorial Rainbow
Responder
#10
buen tutorial metalicross, nunca hice ningún plugin para el ataque de los cuchillos aunque es bueno saber esto, gracias.

tu stock IsBackStab, por lo que vi sirve para detectar el golpe en la espalda de cualquier arma, o estoy equivocado?
Ingeniero agrónomo y desarrollador de Software.

tutoriales-allied
buscas un zp?

"La imitación es la forma más sincera de admiración con la que puede pagar la mediocridad a la grandeza"

Merci Alliedmodders pour m'introduire dans la programmation.
Responder
#11
(21/01/2015, 09:46 PM)roccoxx escribió: buen tutorial metalicross, nunca hice ningún plugin para el ataque de los cuchillos aunque es bueno saber esto, gracias.

tu stock IsBackStab, por lo que vi sirve para detectar el golpe en la espalda de cualquier arma, o estoy equivocado?

Simplemente ve si está ciertos angulos detrás del player. Esa misma funcion se utiliza para detectar si un jugador esta en tu viewcone (cono de vision, angulo de vista), puesto este es el inverso.
Responder


Salto de foro:


Usuarios navegando en este tema: 1 invitado(s)