Detectar tocar entidad
#1
Hay alguna forma de detectar cuando una entidad del tipo func_tracktrain le toca la cabeza a algún jugador? Lo que quiero es que si algún jugador esta debajo de esa entidad lo mate porque en teoría la esta bugeando.
Responder
#2
https://forums.alliedmods.net/showpost.p...stcount=17

Podrias hacer algo como esto, lo que hace es que cuando un jugador cae en la cabeza de otro lo mata, pero en vez de detectar al jugador podrias detectar al func_tracktrain

------

Otra idea más compleja, obtenes maxs mins y medis la parte de abajo del func_tracktrain y creas un trigger, cuando ese trigger lo toque mate al jugador.
Responder
#3
Con la primera opción no se puede. El func_tracktrain nunca toca el suelo (pev_groundentity). La segunda no tengo ni idea de como hacerla... la verdad que con los vectores no voy muy alla.

Tiene que haber alguna forma de detectar si el func_tracktrain le toca la cabeza al jugador...
Responder
#4
(17/12/2019, 11:30 AM)kryder11 escribió: Con la primera opción no se puede. El func_tracktrain nunca toca el suelo (pev_groundentity). La segunda no tengo ni idea de como hacerla... la verdad que con los vectores no voy muy alla.

Tiene que haber alguna forma de detectar si el func_tracktrain le toca la cabeza al jugador...

Kpo, groundentity es para ver la entidad que está en el suelo, en este caso el jugador...........
Responder
#5
Código PHP:
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>

#define PLUGIN ""
#define VERSION "0.0.1"

new g_iMaxPlayers
#define IsPlayer(%0)    ( 1 <= (%0) <= g_iMaxPlayers )

public plugin_init()
{
    
register_pluginPLUGINVERSION"ConnorMcLeod" )
    
RegisterHam(Ham_Player_PostThink"func_tracktrain""OnCBasePlayer_PostThink"false)
    
g_iMaxPlayers get_maxplayers()
}

public 
OnCBasePlayer_PostThinkent )
{
    if(!
pev_valid(ent) )
    {
        
//Una entidad no tiene velocidad de caida por lo que lo siguiente se comenta
        //new Float:flFallVelocity = get_pdata_float(id, m_flFallVelocity)
        //if( flFallVelocity > 10.0 )
        //{


        // No puedo obtener el target si la entidad NO TIENE pev_groundentity
        
new target pev(entpev_groundentity// <-- No da ningun target
        
if( IsPlayer(target) && is_user_alive(target) )
        {
             
ExecuteHam(Ham_TakeDamagetargetididflFallVelocity 0.1DMG_FALL)
        }
        
//}
    
}

Responder
#6
Tenes que usar Ham_Touch, no postthink. Los argumentos que devuelve son los que necesitas, id de entidad e id del player, toucher touched
Responder
#7
(19/12/2019, 10:54 PM)Gonza.-* escribió: Tenes que usar Ham_Touch, no postthink. Los argumentos que devuelve son los que necesitas, id de entidad e id del player, toucher touched

Ah si? y si decis como detectar cuando toca la cabeza?, xq si hookeas touch directo el tipo se sube y se muere.
Responder
#8
para detectar si toca la cabeza usas min y mix size de ambas entidades, así hacía yo en mi blockmaker para el antibug de los bhop, si tocaban de abajo con la cabeza return...
Responder
#9
(19/12/2019, 11:01 PM)Gonza.-* escribió: para detectar si toca la cabeza usas min y mix size de ambas entidades, así hacía yo en mi blockmaker para el antibug de los bhop, si tocaban de abajo con la cabeza return...

(17/12/2019, 11:30 AM)kryder11 escribió: Con la primera opción no se puede. El func_tracktrain nunca toca el suelo (pev_groundentity). La segunda no tengo ni idea de como hacerla... la verdad que con los vectores no voy muy alla.

Tiene que haber alguna forma de detectar si el func_tracktrain le toca la cabeza al jugador...
Responder
#10
Que la entidad no toque el suelo no es impedimento, los bhop tampoco tocaban el suelo, estaban flotando en el aire e igualmente detectaba el touch y los mins y maxs... Si el problema es que no sabe usar los vectores, pues a estudiar como todos hemos hecho para lograr nuestros cometidos. Un saludo, y si no tenes idea de como usar los vectores para detectar lo que necesitas, pegale una leida a la funcion fw_touch del bcm expmod que está en mi firma.
Responder
#11
Vale le pego una mirada y os digo mi resultado. Aunque hubiera estado bien un ejemplo sencillo para hacerme la idea... pero gracias de todas formas ahora voy algo más encaminado.
Responder
#12
Bueno no se si está permitido comentar dos veces en tan poco tiempo.
Gonza he analizado tu código y hay una función que no se como darle la vuelta.
Lo que necesito es detectar cuando el func_tracktrain toca al jugador y NO cuando el jugador toca el func_tracktrain. El que se mueve es el func_tracktrain y necesito que solo detecte la parte superior (cabeza) del jugador ya que los jugadores de por si pueden ir subidos en el func_tracktrain.

Haciendo pruebas me he dado cuenta que el func_tracktrain no llega a tocar el jugador ni viceversa. Es decir se queda encima del jugador pero no lo toca, tengo que saltar para que me imprima algún mensaje que lo estoy tocando en la funcion touch. Así que esto lo tendré que solucionar poniendo zonas prohibidas para que nadie pueda ponerse debajo del func_tracktrain.
Responder
#13
Lo que se me ocurre es verificar la posición Z de ambas entidades:

Si el origen Z del func_tracktrain es mayor a # valor al origen Z del jugador entonces la entidad está sobre el jugador (creo que en este caso sería necesario utilizar el max Z del jugador y el min[z] de la entidad), algo como:


posicioncabeza = originplayer[z] + max[z]
posiciontracktrain = origintrack[z] - min[z]
if(0 <= (posiciontracktrain - posicioncabeza) <= 5)

(es la unica manera que se me ocurre la verdad) Insecure
[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
#14
Ten cuidado, quizas el func_tracktrain no sea todo el model que ocupa la entidad.
Bueno, todo es cuestión de probar.

Lo que dice totopizza de chequear el vector z es la mejor opción.
Si es inferior al de la entidad, goodbye.
Ten cuidado con los negativos
(17/04/2015, 03:36 PM)Neeeeeeeeeel.- escribió: No se va a volver a conectar a internet en toda su puta vida... nadie sube porno a mi foro y vive para contarlo.
Responder
#15
Bueno, viendo lo ocurrido, lo que dice totopizza va encaminado... creo que a ambos debes sumar los maxs, ya que si restas min (float negativo) estas sumando ya que -*- = +. Por otra parte, si nunca llega a tocar la entidad la cabeza del player, lo que podes hacer es crear una entidad solid_trigger que se mueva junto al func_tracktrain por debajo de la misma, justo a la altura que debería tocar la cabeza del player, y entonces detectas el touch de esa entidad, si la toca un jugador, de la forma que sea, muere, ya que al estar siempre por debajo del tren el que la toca es porque el tren lo piso, y ahí te ahorras de chequear vectores, solo asignandole valores de referencia con respecto al origin de la entidad podes mantener otra entidad [solid_trigger] "agarrada" y que se mueva junto a ella. Cualquier cosa deja tu codigo e intentamos ayudarte mejor.

Con respecto a lo que dice raulitop, si vas a hacerlo de la manera que te dijo toto, ten cuidado con los negativos se refiere al eje Z en origin, puede que en algun mapa ande y en otro no debido a que el centro del eje Z (0) no sea el punto mas "bajo" del mapa, y de la casualidad que en esa parte está tu tren Lengua
Responder
#16
(23/12/2019, 05:55 AM)Gonza.-* escribió: Con respecto a lo que dice raulitop, si vas a hacerlo de la manera que te dijo toto, ten cuidado con los negativos se refiere al eje Z en origin, puede que en algun mapa ande y en otro no debido a que el centro del eje Z (0) no sea el punto mas "bajo" del mapa, y de la casualidad que en esa parte está tu tren Lengua
Oh my god. Me entendió rapidísimo Rainbow
(17/04/2015, 03:36 PM)Neeeeeeeeeel.- escribió: No se va a volver a conectar a internet en toda su puta vida... nadie sube porno a mi foro y vive para contarlo.
Responder
#17
Vale muchísimas gracias, he conseguido que si esta debajo lo mate pero al ser un helicóptero el min solo lo detecta si estoy en los patines, si me pongo debajo del helicóptero justo en el centro ya no me detecta que estoy debajo por lo cual el helicóptero no puede aterrizar.

Código PHP:
public fw_TouchTrain(entitycaller)
{
    
// Player died
    
if(!is_user_alive(caller)) return HAM_IGNORED;
    
    
// Invalid entity
    
if (!pev_valid(entity)) return HAM_IGNORED;
    
    static 
Float:fMaxs[2][3], Float:fMins[2][3], Float:fOrigin[2][3], Float:posicionCabezaFloat:posicionTracktrain
    
static IDENTID 0ENT 1
    
    pev
(callerpev_originfOrigin[ID])
    
pev(entitypev_originfOrigin[ENT])
            
    
pev(callerpev_minsfMins[ID])
    
pev(entitypev_minsfMins[ENT])
    
    
pev(callerpev_maxsfMaxs[ID])
    
pev(entitypev_maxsfMaxs[ENT])
    
    
posicionCabeza fOrigin[ID][2] + fMaxs[ID][2]
    
posicionTracktrain fOrigin[ENT][2] - floatabs(fMins[ENT][2])
    
    
client_print(0print_chat"P.T: %f"posicionTracktrain)
    
client_print(0print_chat"P.C: %f"posicionCabeza)
    
    if(
posicionCabeza posicionTracktrain+2.0)
    {
        
client_print(0print_chat"estoy debajo")
    } 
Y esto son los respectivos valores del print y le sumo 2.0 para que me imprima el mensaje y lo detecte como toca.
Código PHP:
P.T: -56.883998
P
.C: -55.968750
estoy debajo 

Lo que no entiendo es porque no detecta el touch directamente sino que tengo que saltar para que lo detecte. Estoy utilizando un plugin "Entity Lab" para ver que entidad es. https://forums.alliedmods.net/showthread.php?p=681712
Responder
#18
Te dejo un ejemplo de como lo tengo yo

Código PHP:
new const NameEntArsenalBox[] = "ArsenalBox"


public plugin_init() {
    
RegisterHam(Ham_Touch"info_target""fw_ArsenalBoxTouched_Post"true)
}

public 
fw_ArsenalBoxTouched_Post(enttoucher)
{
    if(!
pev_valid(ent) || !is_user_alive(toucher))
        return 
HAM_IGNORED;
        
    new 
classname[32]
    
entity_get_string(entEV_SZ_classnameclassnamecharsmax(classname))
    
    if(
equal(classnameNameEntArsenalBox))
    {
        
ColorChat(toucherNORMAL"^4%s^3 Estas tocando la entidad! CAJA"g_playername[toucher])
    }
    
    return 
HAM_IGNORED;

[Imagen: 76561198068808877.png]
Responder
#19
con respecto a que no te detecta hasta que te muevas, entonces tendras que usar think, tambien en mi plugin de bcm expmod tenes la funcion que necesitas, chequeas los mismos parametros (origin y min/max) usando este metodo ya no vas a necesitar al jugador con movimiento para detectar el touch, y tu helicoptero podrá aterrizar! Saludos!
Responder
#20
(25/12/2019, 10:28 PM)Gonza.-* escribió: con respecto a que no te detecta hasta que te muevas, entonces tendras que usar think, tambien en mi plugin de bcm expmod tenes la funcion que necesitas, chequeas los mismos parametros (origin y min/max) usando este metodo ya no vas a necesitar al jugador con movimiento para detectar el touch, y tu helicoptero podrá aterrizar! Saludos!

Se me ocurren 2 formas con Think, por favor corrige mi código si no compila, no programo en AMXX hace años Yao ming

Código PHP:
public fwPreThink(iEnt)
{
    
// se me ocurren dos metodos
    // 1. trace
    // 2. loop y comprobar origins de los jugadores
    // que venga metalicross y diga cual es mas eficiente xD

    
static Float:fEntOrigin[3];
    
entity_get_vector(iEntEV_VEC_originfEntOrigin);

    static 
Float:fEntMins[3], Float:fEntMaxs[3] = {0.00.00.0};
    
    if (
fEntMaxs[0] == 0.0)
    {
        
entity_get_vector(iEntEV_VEC_minsfEntMins);
        
entity_get_vector(iEntEV_VEC_maxsfEntMaxs);
    }

    
// metodo 1: trace
    // se haran traces en lineas horizontales, a 5 unidades bajo el minimo de la entidad
    // dejando fPlayerMinWidth unidades de espacio entre los traces
    
const Float:fPlayerMinWidth 32.0// creo que es 32? obtener con floatmin(fPlayerMaxs[0] - fPlayerMins[0], fPlayerMaxs[1] - fPlayerMins[1])
    
    
static iIterNum 0;
    if (!
iIterNum)
    {
        
iIterNum floatround((fEntMaxs[1] - fEntMins[1]) / fPlayerMinWidthfloatround_floor);
    }

    static 
Float:fTraceStart[3], Float:fTraceEnd[3];
    
    
xs_vec_add(fEntOriginfEntMinsfTraceStart);
    
fTraceStart[2] -= 5.0;
    
    
xs_vec_copy(fTraceStartfTraceEnd);
    
fTraceEnd[0] = fEntOrigin[0] + fEntMaxs[0];
    
    static 
iFoundEntFloat:fFoundEntOrigin[3];
    for (new 
0iIterNumi++)
    {
        
iFoundEnt trace_line(0fTraceStartfTraceEndfFoundEntOrigin);
        
        if (
is_user_alive(iFoundEnt))
        {
            
// kill?
            
user_kill(iFoundEnt);
        }
        
        
fTraceStart[1] += fPlayerMinWidth;
        
fTraceEnd[1] = fTraceStart[1];
    }
    
    
// metodo 2: loop
    // se comprobara que el origin de cada player este entre los limites en X e Y, y a menos de 5 unidades en Z
    
    
static Float:fPlayerOrigin[3], Float:fPlayerMins[3], Float:fPlayerMaxs[3];
    static 
Float:fEntAbsoluteMaxs[3], Float:fEntAbsoluteMins[3], Float:fAbsoluteZ;
    
    
xs_vec_add(fEntOriginfEntMinsfEntAbsoluteMins);
    
xs_vec_add(fEntOriginfEntMaxsfEntAbsoluteMaxs);
    
    
// los mins y maxs del player no son los mismos si el jugador esta de pie o duckeado
    
    
static players[32], numiId;
    
get_players(playersnum"a");
    for (new 
0numi++)
    {
        
iId players[i];
        if (!
is_user_alive(iId))
        {
            continue;
        }
        
        
entity_get_vector(iIdEV_VEC_originfPlayerOrigin);
        
entity_get_vector(iIdEV_VEC_minsfPlayerMins);
        
entity_get_vector(iIdEV_VEC_maxsfPlayerMaxs);
        
        
fAbsoluteZ fPlayerOrigin[2] + fPlayerMaxs[2];
        
xs_vec_add(fEntAbsoluteMinsfPlayerMinsfPlayerMins);
        
xs_vec_add(fEntAbsoluteMaxsfPlayerMaxsfPlayerMaxs);
        
        if (
fPlayerMins[0] <= fPlayerOrigin[0] <= fPlayerMaxs[0] && fPlayerMins[1] <= fPlayerOrigin[1] <= fPlayerMaxs[1] && fEntAbsoluteMins[2] - fAbsoluteZ <= 5.0)
        {
            
// kill?
            
user_kill(iId);
        }
    }

Responder
#21
Código PHP:
void CFuncTrackTrain::Blocked(CBaseEntity *pOther)
{
    
entvars_t *pevOther pOther->pev;

    
// Blocker is on-ground on the train
    
if ((pevOther->flags FL_ONGROUND) && VARS(pevOther->groundentity) == pev)
    {
        
real_t deltaSpeed Q_fabs(real_t(pev->speed));

        if (
deltaSpeed 50)
        {
            
deltaSpeed 50;
        }

        if (!
pevOther->velocity.z)
        {
            
pevOther->velocity.+= deltaSpeed;
        }

        return;
    }
    else
        
pevOther->velocity = (pevOther->origin pev->origin).Normalize() * pev->dmg;

    
ALERT(at_aiconsole"TRAIN(%s): Blocked by %s (dmg:%.2f)\n"STRING(pev->targetname), STRING(pOther->pev->classname), pev->dmg);

#ifdef REGAMEDLL_FIXES
    
if (pev->dmg <= 0)
        return;

    
// we can't hurt this thing, so we're not concerned with it
    
pOther->TakeDamage(pevpevpev->dmgDMG_CRUSH);
#endif

Github regamedll/dlls/plats.cpp
[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
#22
Después de unos días buscando información, al final he conseguido lo que quería. Lo que estaba preguntando estaba mal... lo que queria era detectar cuando un jugador bloquea una entidad y no cuando la toca. Por lo cual, hay que utilizar Ham_Blocked.

Aquí les dejo la solución a mi problema:

Código PHP:
RegisterHam(Ham_Blocked"func_tracktrain""fw_Block")

public 
fw_Block(entityblocker)
{
    
// Player died
    
if(!is_user_alive(blocker)) return HAM_IGNORED;
    
    
// Invalid entity
    
if (!pev_valid(entity)) return HAM_IGNORED;
    
    
user_kill(blocker1)
    
    return 
HAM_IGNORED

Responder
#23
No tenia idea de esa función! Al final era mucho mas simple que lo que todos pensabamos! Éxitos y bien trabajado kryder11!!
Responder
#24
"Blocked" funciona con cualquier entidad push, es decir, de movetype MOVETYPE_PUSH (no se considera MOVETYPE_PUSHSTEP). Y es llamado siempre y cuando una entidad bloquea el momentum de la entidad en el frame específico. Pueden ver ejemplos de sus callbacks en el SDK sobre cómo son tratados, mayormente estos realizan Damage y reflejan el vector de movimiento (ej. se devuelve la puerta al aplastar algo)
Responder
#25
Que raro metal dando luz sobre lo desconocido (? Abrazo genio!
Responder


Salto de foro:


Usuarios navegando en este tema: 1 invitado(s)