[GUIA] El Parametro fNoMonsters de los Traces
#1
Muchos se han fijado alguna vez cuando ven ejecutado un Trace cualquiera (TraceLine más recurrente) siempre se fijan en un parametro de escasa informacion la cual intriga saber que porqueria trata de decir.

Estas recurrentemente suelen verse declaradas así:

Cita:engfunc(EngFunc_TraceLine, vecStart, vecAim, IGNORE_MONSTERS, iIgnoreEnt, 0)

La cual corresponde al parametro fNoMonsters de éste trace. El conjunto de valores validos de este parametro la podemos encontrar en hlsdk_const.inc

Código PHP:
#define DONT_IGNORE_MONSTERS            0
#define IGNORE_MONSTERS                 1
#define IGNORE_MISSILE                  2
#define IGNORE_GLASS                    0x100 

Y aparece en los siguientes Trace functions:
  • TraceLine
  • TraceMonsterHull
  • TraceHull
  • TraceSphere (el cual no se toma en cuenta porque es una función que no hace nada, solo tira un error al usarla, asi que descartenla)
Todas posibles de hookear y ejecutar con Fakemeta. (ver fakemeta_const.inc)

La parte buena de esto es saber como interactuan estos valores. Y es aquí donde uno por curiosidad se pone a investigar cuando no tiene otra mierda más interesante que hacer en un Domingo típico.

Antes de empezar a explicar, cabe decir que las 3 funciones hacen lo mismo, solo que varía el tamaño del Trace que viaja detectando colisiones. Eso es practicamente la labor de una Trace function. El tamaño del Trace es definido por 2 vectores, mins y maxs.
  1. TraceLine viaja con un tamaño nulo, es decir, {0,0,0} y {0,0,0} como mins y maxs, es decir, como una linea o recta.
  2. TraceHull tendra un tamaño variado según su parametro hullNumber, los cuales son las constantes HULL_ de hlsdk_const.inc y esos tamaños quedan hardcodeados en el engine despues que le preguntan al mod sus correspondientes valores (es por eso que el tamaño de un player en Half-Life es distinto al de uno en Counter-Strike).
  3. TraceMonsterHull viajara usando el tamaño de la entidad que es pasada en el primer parametro. Es muy útil al momento de querer usar un tamaño definido por nosotros si es que queremos detectar si una entidad esta atascada.

Empecemos.

El parametro fNoMonsters define que solidos puede ignorar o no, ademas de la entidad del parametro pentToSkip que tienen estas Trace functions. Todos los Trace si o si van a parar cuando toquen una parte del mapa que no sea entidad, que vendria siendo un solido del mapa, worldspawn, bloque, o como quieran decirle.

DONT_IGNORE_MONSTERS (0) es el más sencillo. Se entiende que refiere a "NO IGNORAR MOUNSTRUOS", dando a saber que debe para al primer toque. Todo lo que no es parte de la integridad del mapa, es considerado un monstruo, por lo que este valor nos da a saber que el trace parará en CUALQUIER punto solido.

IGNORE_MONSTERS (1) entra en dudas. Se entiende que refiere a "IGNORAR MONSTRUOS", y eso esta claro a simple vista, pero ¿que condiciones tiene una entidad que la haga ser un mounstruo?

Este flag hará que el Trace ignore cualquier entidad, excepto las que tengan su movetype igual a MOVETYPE_PUSHSTEP. Las únicas entidades que tienen su movetype igual a MOVETYPE_PUSHSTEP son las entidades func_pushable.

IGNORE_MISSILE (2) podría afirmar con toda seguridad que nadie sabe a que se refiere. Y lo chistoso es que su referencia a "IGNORAR MISILES" no tiene nada que ver a ignorar misiles literalmente, y da muy poco que decir.

Este flag hará (lee bien) que el Trace tome OTRO tamaño (sea TraceLine/[Monster]Hull) a toda entidad que tenga en su flags (el pev) el bit FL_MONSTER por un tamaño de maxs {15,15,15} y mins {-15,-15,-15} (un cuadrado perfecto de 15 unidades por dimension)

Como dije arriba, cada Trace tiene un tamaño (definido como una caja, mins y maxs), definamoslo como mins1 y maxs1.
Antes de ser ejecutado el Trace, estos valores se copian a otro tamaño, llamemosle mins2 y maxs2.
- Los mins1 y maxs1 seran el tamaño con el que seran verificados con todas las entidades 'exceptuando las de flag FL_MONSTER'
- Mientras que los mins2 y maxs2 seran el tamaño con el que seran verificados las entidades 'de flag FL_MONSTER'.
Pero como dije, estas se copian en un principio y terminan siendo lo mismo mins1 con mins2, y maxs1 con maxs2.

IGNORE_MISSILE lo que hace es simplemente hacer que mins2 y maxs2 sean {15,15,15} y {-15,-15,-15} (ignorando el tamaño del Trace) respecticamente para las entidades con su flags que tengan el bit FL_MONSTER.

Algo idiota, no le veo utilidad.

_________________________________________________________________

IGNORE_GLASS es distinto a los 3 mencionados arriba.

Los 3 mencionados son valores que son detectados directamente como 0 1 o 2, mientras que IGNORE_GLASS es detectado como un flag.

Es por eso que el parametro fNoMonsters se divide en 2:
  • El tipo mismo, que puede ser 0-1-2
  • Si ignorará vidrios o no.

Las siguientes combinaciones son totalmente validas y únicamente validas:

DONT_IGNORE_MONSTERS
IGNORE_MONSTERS
IGNORE_MISSILE
IGNORE_GLASS
DONT_IGNORE_MONSTERS | IGNORE_GLASS
IGNORE_MONSTERS | IGNORE_GLASS
IGNORE_MISSILE | IGNORE_GLASS


Mientras que por ejemplo, las siguientes son invalidas:

DONT_IGNORE_MONSTERS | IGNORE_MISSILE
IGNORE_MONSTERS | IGNORE_MISSILE
DONT_IGNORE_MONSTERS | IGNORE_MONSTERS
(reverendo idiota para hacer esto)

Y ahora, es donde vamos a definir que es considerado "un vidrio" para el engine.

IGNORE_GLASS puesto como flag en cualquiera de los 3 mencionados, hará que el Trace ignore entidades que:
  1. Tengan su rendermode distinto a kRenderNormal
  2. No tengan su flags con el bit FL_WORLDBRUSH
Ejemplo: La mayoria de las veces que uno crea un mapa y hace "vidrios", suelen ser func_breakable con algo de trasparencia -> su "Render Mode" debe ser "Texture - Some Light" equivalente al rendermode kRenderTransTexture. Esta ya seria una entidad ignorada por el flag IGNORE_GLASS ya que los func_breakable no tienen el flag FL_WORLDBRUSH.

Las unicas entidades que tienen el flag FL_WORLDBRUSH son las "func_wall", siendo estas, ademas del mismo mundo, las unicas entidades imposibles de traspasar con un Trace.

Por lo mismo al flag se le dice "World Brush", ya que es considerado como un bloque del mapa, y estos tienen la caracteristica de que ningun Trace puede traspasarlos.

Esta escrito en el mismo HLSDK

Código PHP:
    // Flag unbreakable glass as "worldbrush" so it will block ALL tracelines
    
if ( !IsBreakable() && pev->rendermode != kRenderNormal )
        
pev->flags |= FL_WORLDBRUSH

Espero haya hecho activar un buen grupo de neuronas haciendolos leer este tutorial. Todo lo escrito fue un research hecho en el engine, y acredito a OpenHLDS, OSHLDS, HLSDK y el IDA Pro por verificar con el mismo engine Gran sonrisa

Dudas haganlas saber en el tema, y no se desvien preguntando estupideces.
Responder


Mensajes en este tema
[GUIA] El Parametro fNoMonsters de los Traces - por meTaLiCroSS - 28/09/2014, 11:43 PM

Salto de foro:


Usuarios navegando en este tema: 2 invitado(s)