You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
874 lines
21 KiB
874 lines
21 KiB
/**************************************************************** |
|
* * |
|
* particules.cpp * |
|
* * |
|
* par Julien * |
|
* * |
|
****************************************************************/ |
|
|
|
// code du syst |
|
// et des decals |
|
|
|
|
|
|
|
#include "hud.h" |
|
#include "cl_util.h" |
|
#include "const.h" |
|
#include "entity_state.h" |
|
#include "cl_entity.h" |
|
#include "triangleapi.h" |
|
#include <string.h> |
|
#include "cdll_int.h" |
|
#include "pmtrace.h" |
|
#include "event_api.h" |
|
#include "pm_defs.h" |
|
#include "parsemsg.h" |
|
#include "eventscripts.h" |
|
#include "r_efx.h" |
|
|
|
extern void EV_HLDM_EjectParticules ( Vector vecOrigin, Vector vecNormal, char chTextureType, int decal, int iParticules ); |
|
void VectorAngles( const float *forward, float *angles ); |
|
|
|
extern vec3_t v_angles; |
|
|
|
|
|
|
|
#define PARTICULES_LARGEUR 2 |
|
#define DECALS_LARGEUR 4 |
|
|
|
|
|
|
|
|
|
//======================== |
|
// ajout de particule |
|
// |
|
|
|
void CHudParticules :: AddParticule ( vec3_t origin, vec3_t angles, vec3_t velocity, vec3_t avelocity, char model [64], int deathtime, int flags ) |
|
{ |
|
|
|
int iIndex; |
|
|
|
for ( iIndex = 0 ; iIndex < MAX_PARTICULES ; iIndex ++ ) |
|
{ |
|
if ( m_pParticules [ iIndex ].libre == 1 ) |
|
break; |
|
} |
|
|
|
|
|
// array rempli |
|
if ( m_pParticules [ iIndex ].libre != 1 ) |
|
{ |
|
// gEngfuncs.Con_Printf ( "client.dll : Particule overflow : > %i\n", MAX_PARTICULES ); //alertatconsole |
|
return; |
|
} |
|
|
|
|
|
//remplissage du nouveau tableau de donnees |
|
|
|
m_pParticules [ iIndex ].origin = origin; |
|
m_pParticules [ iIndex ].angles = angles; |
|
m_pParticules [ iIndex ].velocity = velocity; |
|
m_pParticules [ iIndex ].avelocity = avelocity; |
|
m_pParticules [ iIndex ].deathtime = deathtime; |
|
m_pParticules [ iIndex ].flags = flags; |
|
m_pParticules [ iIndex ].libre = 0; |
|
|
|
strcpy ( m_pParticules [ iIndex ].model, model ); |
|
|
|
} |
|
|
|
|
|
|
|
//========================= |
|
// ajout de decal |
|
// |
|
|
|
void CHudParticules :: AddDecal ( vec3_t origin, vec3_t angles, char model [64], float deathtime, int flags ) |
|
{ |
|
|
|
// recherche de place libre |
|
int iIndex; |
|
int iIndexNew = 0; |
|
|
|
for ( iIndex = 0 ; iIndex < MAX_DECALS ; iIndex ++ ) |
|
{ |
|
if ( m_pDecals [ iIndex ].libre == 1 ) |
|
break; |
|
} |
|
|
|
// place libre |
|
if ( m_pDecals [ iIndex ].libre == 1 ) |
|
{ |
|
// demande acceptee |
|
iIndexNew = iIndex; |
|
} |
|
// tableau rempli |
|
else |
|
{ |
|
|
|
float age = m_pDecals[0].deathtime; |
|
int oldindex = 0; |
|
|
|
// cherche le plus ancien |
|
for ( iIndex = 0; iIndex < MAX_DECALS ; iIndex ++ ) |
|
{ |
|
if ( m_pDecals[iIndex].deathtime < age ) |
|
{ |
|
age = m_pDecals[iIndex].deathtime; |
|
oldindex = iIndex; |
|
} |
|
} |
|
|
|
// detruit le plus ancient |
|
RemoveDecal ( oldindex ); |
|
|
|
// prend la place nouvellement libre |
|
// demande acceptee |
|
iIndexNew = oldindex; |
|
|
|
|
|
// actualise l age minimum |
|
age = m_pDecals[0].deathtime; |
|
|
|
for ( iIndex = 0; iIndex < MAX_DECALS ; iIndex ++ ) |
|
{ |
|
if ( m_pDecals[iIndex].deathtime < age ) |
|
age = m_pDecals[iIndex].deathtime; |
|
} |
|
|
|
} |
|
|
|
// enregistre |
|
|
|
m_pDecals[iIndexNew].angles = angles; |
|
m_pDecals[iIndexNew].deathtime = deathtime; |
|
m_pDecals[iIndexNew].flags = flags; |
|
m_pDecals[iIndexNew].libre = 0; |
|
m_pDecals[iIndexNew].origin = origin; |
|
|
|
strcpy ( m_pDecals [ iIndex ].model, model ); |
|
|
|
// electro-rocket |
|
|
|
if ( flags & ( FLAG_DECAL_DISK | flags & FLAG_DECAL_SG | FLAG_DECAL_XENO ) ) |
|
{ |
|
m_pDecals[iIndexNew].iRndSensX = m_pDecals[iIndexNew].iRndSensY = 1; |
|
return; |
|
} |
|
|
|
|
|
|
|
// fixe |
|
|
|
Vector forward, right, up; |
|
AngleVectors ( m_pDecals[iIndexNew].angles, forward, right, up ); |
|
pmtrace_t pmtrace; |
|
|
|
gEngfuncs.pEventAPI->EV_SetTraceHull( 2 ); |
|
gEngfuncs.pEventAPI->EV_PlayerTrace( m_pDecals[iIndexNew].origin - forward.Normalize()*0.2, m_pDecals[iIndexNew].origin, PM_STUDIO_BOX | PM_STUDIO_IGNORE, -1, &pmtrace ); |
|
|
|
physent_s *pe = gEngfuncs.pEventAPI->EV_GetPhysent( pmtrace.ent ); |
|
int entity = gEngfuncs.pEventAPI->EV_IndexFromTrace( &pmtrace ); |
|
|
|
if ( pmtrace.fraction == 0.0 && pe && pe->solid == SOLID_BSP && entity != 0 ) |
|
{ |
|
|
|
// contre un mur et contre une entit |
|
|
|
m_pDecals[iIndexNew].entity = entity; |
|
m_pDecals[iIndexNew].offset = m_pDecals[iIndexNew].origin - pe->origin; |
|
m_pDecals[iIndexNew].angoffset = pe->angles; |
|
m_pDecals[iIndexNew].oldangles = m_pDecals[iIndexNew].angles; |
|
|
|
cl_entity_s *pClEnt = GetEntity( entity ); |
|
|
|
// pas de d |
|
if ( pe->rendermode != kRenderNormal && pClEnt->curstate.renderamt == 0 ) |
|
{ |
|
RemoveDecal ( iIndexNew ); |
|
return; |
|
} |
|
|
|
if ( pe->rendermode == kRenderTransTexture ) |
|
{ |
|
//entit |
|
|
|
if ( pClEnt->curstate.renderamt == 0 && m_pDecals[iIndexNew].flags & FLAG_DECAL_GLASS ) |
|
{ |
|
RemoveDecal ( iIndexNew ); |
|
return; |
|
} |
|
|
|
// entit |
|
|
|
else if ( m_pDecals[iIndexNew].flags & FLAG_DECAL_GLASS && gEngfuncs.pfnRandomLong (0,3) != 0 ) |
|
{ |
|
m_pDecals[iIndexNew].flags |= FLAG_DECAL_WIDEGLASS; |
|
} |
|
} |
|
|
|
// grille |
|
else if ( pe->rendermode == kRenderTransAlpha ) |
|
{ |
|
RemoveDecal ( iIndexNew ); |
|
return; |
|
} |
|
|
|
|
|
} |
|
else |
|
{ |
|
m_pDecals[iIndexNew].entity = 0; |
|
m_pDecals[iIndexNew].offset = m_pDecals[iIndexNew].angoffset = Vector(0,0,0); |
|
} |
|
|
|
|
|
// taille al |
|
|
|
float iRnd = gEngfuncs.pfnRandomFloat( 0.75, 1 ); |
|
|
|
if ( m_pDecals[iIndexNew].flags & FLAG_DECAL_WIDEGLASS ) |
|
iRnd *= 6; |
|
|
|
else if ( m_pDecals[iIndexNew].flags & FLAG_DECAL_GLASS ) |
|
iRnd *= 4; |
|
|
|
m_pDecals[iIndexNew].iRndSensX = m_pDecals[iIndexNew].iRndSensY = iRnd; |
|
|
|
iRnd = gEngfuncs.pfnRandomLong( 0, 1 ); |
|
|
|
m_pDecals[iIndexNew].iRndSensX = iRnd == 1 ? - m_pDecals[iIndexNew].iRndSensX : m_pDecals[iIndexNew].iRndSensX; |
|
m_pDecals[iIndexNew].iRndSensY = iRnd == 1 ? - m_pDecals[iIndexNew].iRndSensY : m_pDecals[iIndexNew].iRndSensY; |
|
|
|
|
|
// sens du crowbar |
|
|
|
if ( m_pDecals[iIndexNew].flags & FLAG_DECAL_CROWBAR_INVERT ) |
|
m_pDecals[iIndexNew].iRndSensX = - m_pDecals[iIndexNew].iRndSensX; |
|
|
|
// A FAIRE : enlever les d |
|
|
|
// demande acceptee |
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
//=========================================== |
|
// application des lois physiques |
|
|
|
int CHudParticules :: Draw ( float flTime ) |
|
{ |
|
|
|
static const Vector gravity (0,0,-400); |
|
|
|
float delta = flTime - m_flLastTime; |
|
m_flLastTime = flTime; |
|
|
|
if ( delta == 0 ) |
|
return 1; |
|
|
|
for ( int iIndex = 0; iIndex < MAX_PARTICULES ; iIndex ++ ) |
|
{ |
|
// fin de la liste |
|
if ( m_pParticules [ iIndex ].libre == 1 ) |
|
continue; |
|
|
|
vec3_t lastpos = m_pParticules [ iIndex ].origin; |
|
|
|
if ( m_pParticules [ iIndex ].deathtime < flTime ) |
|
{ |
|
RemoveParticule ( iIndex ); |
|
continue; |
|
} |
|
|
|
|
|
|
|
m_pParticules[iIndex].angles = m_pParticules[iIndex].angles + m_pParticules[iIndex].avelocity * delta; |
|
|
|
m_pParticules[iIndex].origin = m_pParticules[iIndex].origin + m_pParticules[iIndex].velocity * delta; |
|
|
|
if ( !(m_pParticules[iIndex].flags & ( FLAG_PARTICULE_OUTRO1 | FLAG_PARTICULE_OUTRO2 | FLAG_PARTICULE_OUTRO3 | FLAG_PARTICULE_SMOKE )) ) |
|
{ |
|
m_pParticules[iIndex].velocity = m_pParticules[iIndex].velocity + gravity * delta; |
|
} |
|
|
|
if ( m_pParticules[iIndex].flags & FLAG_PARTICULE_OUTRO2 ) |
|
{ |
|
if ( m_pParticules [ iIndex ].deathtime - flTime < 4.5 ) |
|
{ |
|
m_pParticules[iIndex].velocity = m_pParticules[iIndex].velocity.Normalize() * Q_max( 0, m_pParticules[iIndex].velocity.Length() - 10 * delta ); |
|
} |
|
else if ( m_pParticules [ iIndex ].deathtime - flTime < 6) |
|
{ |
|
int i = ( m_pParticules[iIndex].angles.x - 1.2 ) / 0.3; |
|
m_pParticules[iIndex].velocity = m_pParticules[iIndex].velocity.Normalize() * 14 * ( 0.3 - i*0.03 ) * 2.5; |
|
} |
|
} |
|
|
|
if ( m_pParticules[iIndex].flags & ( FLAG_PARTICULE_OUTRO1 | FLAG_PARTICULE_OUTRO2 | FLAG_PARTICULE_OUTRO3 ) ) |
|
{ |
|
if ( m_pParticules [ iIndex ].deathtime - flTime < 2.5 ) |
|
{ |
|
m_pParticules [ iIndex ].angles.y -= delta * 0.3 / 2.5; |
|
|
|
m_pParticules [ iIndex ].angles.y = Q_max ( 0, m_pParticules [ iIndex ].angles.y ); |
|
} |
|
} |
|
|
|
|
|
|
|
pmtrace_t pmtrace; |
|
gEngfuncs.pEventAPI->EV_SetTraceHull( 2 ); |
|
gEngfuncs.pEventAPI->EV_PlayerTrace( lastpos, m_pParticules [ iIndex ].origin, PM_STUDIO_BOX | PM_WORLD_ONLY, -1, &pmtrace ); |
|
|
|
if ( pmtrace.fraction != 1 ) |
|
m_pParticules [ iIndex ].deathtime = gEngfuncs.GetClientTime(); |
|
} |
|
|
|
|
|
|
|
for ( int iDecal = 0; iDecal < MAX_DECALS ; iDecal ++ ) |
|
{ |
|
// innocupp |
|
if ( m_pDecals[iDecal].libre == 1 ) |
|
continue; |
|
|
|
if ( m_pDecals[iDecal].deathtime < flTime ) |
|
{ |
|
RemoveDecal ( iDecal ); |
|
return 1; |
|
} |
|
|
|
if ( m_pDecals[iDecal].flags & FLAG_DECAL_DISK ) |
|
{ |
|
if ( m_pDecals[iDecal].iRndSensX < ELECTRO_DISK_MAX ) |
|
{ |
|
m_pDecals[iDecal].iRndSensX += ELECTRO_DISK_SPEED * delta; |
|
m_pDecals[iDecal].iRndSensY = m_pDecals[iDecal].iRndSensX; |
|
} |
|
continue; |
|
} |
|
|
|
if ( m_pDecals[iDecal].flags & FLAG_DECAL_SG ) |
|
{ |
|
if ( m_pDecals[iDecal].iRndSensX < 8 ) |
|
{ |
|
m_pDecals[iDecal].iRndSensX += 16 * delta; |
|
m_pDecals[iDecal].iRndSensY = m_pDecals[iDecal].iRndSensX = Q_min ( 8, m_pDecals[iDecal].iRndSensX ); |
|
} |
|
continue; |
|
} |
|
|
|
if ( m_pDecals[iDecal].flags & FLAG_DECAL_XENO ) |
|
{ |
|
if ( m_pDecals[iDecal].iRndSensX < 3 ) |
|
{ |
|
m_pDecals[iDecal].iRndSensX += 3 * delta; |
|
m_pDecals[iDecal].iRndSensY = m_pDecals[iDecal].iRndSensX = Q_min ( 3, m_pDecals[iDecal].iRndSensX ); |
|
} |
|
continue; |
|
} |
|
|
|
|
|
Vector forward, right, up; |
|
AngleVectors ( m_pDecals[iDecal].angles, forward, right, up ); |
|
|
|
pmtrace_t pmtrace; |
|
|
|
gEngfuncs.pEventAPI->EV_SetTraceHull( 2 ); |
|
gEngfuncs.pEventAPI->EV_PlayerTrace( m_pDecals[iDecal].origin - forward.Normalize()*0.35, m_pDecals[iDecal].origin, PM_STUDIO_BOX | PM_STUDIO_IGNORE, -1, &pmtrace ); |
|
|
|
physent_s *pe = gEngfuncs.pEventAPI->EV_GetPhysent( pmtrace.ent ); |
|
int entity = gEngfuncs.pEventAPI->EV_IndexFromTrace( &pmtrace ); |
|
|
|
// sprite anim |
|
|
|
if ( m_pDecals[iDecal].flags & FLAG_DECAL_WIDEGLASS ) |
|
{ |
|
// 9.0 fps - - 5 frames max |
|
|
|
m_pDecals[iDecal].flFrame += delta * 9; |
|
m_pDecals[iDecal].flFrame = m_pDecals[iDecal].flFrame > 4 ? 4 : m_pDecals[iDecal].flFrame; |
|
} |
|
|
|
|
|
|
|
|
|
if ( m_pDecals[iDecal].entity != 0 ) |
|
{ |
|
|
|
//suit le d |
|
|
|
cl_entity_t *pClEnt = GetEntity( m_pDecals[iDecal].entity ); |
|
|
|
if ( pClEnt == 0 ) |
|
{ |
|
m_pDecals[iDecal].entity = 0; |
|
} |
|
|
|
else if ( m_pDecals[iDecal].angoffset != pClEnt->angles ) |
|
{ |
|
// entit |
|
|
|
float flLength = m_pDecals[iDecal].offset.Length(); |
|
|
|
vec3_t angDiff, angNewAngles; |
|
VectorAngles( m_pDecals[iDecal].offset.Normalize(), angDiff ); |
|
|
|
angNewAngles = pClEnt->angles + ( angDiff - m_pDecals[iDecal].angoffset ); |
|
|
|
vec3_t forward, right, up; |
|
angNewAngles.x += 180; |
|
angNewAngles.y += 180; |
|
|
|
AngleVectors ( angNewAngles, forward, right, up ); |
|
|
|
m_pDecals[iDecal].origin = pClEnt->origin + forward.Normalize() * flLength; |
|
|
|
m_pDecals[iDecal].angles = pClEnt->angles + ( m_pDecals[iDecal].oldangles - m_pDecals[iDecal].angoffset ); |
|
|
|
} |
|
|
|
else if ( ( ( pmtrace.startsolid == 1 && m_pDecals[iDecal].entity != 0 ) || |
|
( pmtrace.fraction == 0.0 && m_pDecals[iDecal].entity != 0 ) ) |
|
&& ( m_pDecals[iDecal].origin - pClEnt->origin != m_pDecals[iDecal].offset ) ) |
|
{ |
|
// porte coulissante |
|
m_pDecals[iDecal].origin = pClEnt->origin + m_pDecals[iDecal].offset; |
|
} |
|
|
|
else if ( pmtrace.fraction != 0.0 ) |
|
{ |
|
// d |
|
RemoveDecal ( iDecal ); |
|
} |
|
|
|
|
|
} |
|
else if ( pmtrace.fraction != 0.0 ) |
|
{ |
|
// d |
|
RemoveDecal ( iDecal ); |
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return 1; |
|
} |
|
|
|
|
|
//================================= |
|
// suppression d une particule |
|
|
|
void CHudParticules :: RemoveParticule ( int iIndex ) |
|
{ |
|
m_pParticules[iIndex].libre = 1; |
|
m_pParticules[iIndex].angles = m_pParticules[iIndex].origin = m_pParticules[iIndex].avelocity = m_pParticules[iIndex].velocity = Vector ( 0,0,0 ); |
|
m_pParticules[iIndex].deathtime = m_pParticules[iIndex].flags = 0; |
|
strcpy ( m_pParticules[iIndex].model, "" ); |
|
} |
|
|
|
// suppression d'un d |
|
|
|
void CHudParticules :: RemoveDecal ( int iIndex ) |
|
{ |
|
m_pDecals[iIndex].libre = 1; |
|
m_pDecals[iIndex].angles = m_pDecals[iIndex].origin = m_pDecals[iIndex].offset = Vector ( 0,0,0 ); |
|
m_pDecals[iIndex].deathtime = 0; |
|
m_pDecals[iIndex].flags = 0; |
|
m_pDecals[iIndex].entity = 0; |
|
// strcpy ( m_pDecals[iIndex].model, " " ); |
|
} |
|
|
|
|
|
|
|
|
|
//===================================== |
|
// |
|
// trac |
|
|
|
|
|
void CHudParticules :: DrawAll ( void ) |
|
{ |
|
|
|
//particules |
|
|
|
int iIndex, iresult = 0; |
|
|
|
for ( iIndex = 0; iIndex < MAX_PARTICULES ; iIndex ++ ) |
|
{ |
|
// fin de la liste |
|
if ( m_pParticules [ iIndex ].libre == 1 ) |
|
continue; |
|
|
|
iresult ++; |
|
|
|
|
|
// vecteurs de base |
|
|
|
vec3_t forward, right, up, vertex, ang; |
|
|
|
if ( m_pParticules[iIndex].flags & ( FLAG_PARTICULE_OUTRO1 | FLAG_PARTICULE_OUTRO2 | FLAG_PARTICULE_OUTRO3 ) ) |
|
{ |
|
ang = v_angles + Vector(0.0f, 0.0f, m_pParticules[iIndex].angles.z ); |
|
} |
|
else if ( m_pParticules[iIndex].flags & FLAG_PARTICULE_SMOKE ) |
|
{ |
|
ang = v_angles; |
|
} |
|
else |
|
{ |
|
ang = m_pParticules[iIndex].angles; |
|
} |
|
|
|
AngleVectors ( ang, forward, right, up ); |
|
|
|
float largeurX = PARTICULES_LARGEUR / 2; |
|
float largeurY = PARTICULES_LARGEUR / 2; |
|
|
|
if ( m_pParticules[iIndex].flags & FLAG_PARTICULE_WOOD ) |
|
{ |
|
largeurY *= 0.5; |
|
largeurX *= 2; |
|
} |
|
|
|
if ( m_pParticules[iIndex].flags & ( FLAG_PARTICULE_OUTRO1 | FLAG_PARTICULE_OUTRO2 | FLAG_PARTICULE_OUTRO3 ) ) |
|
{ |
|
largeurX = largeurY = m_pParticules[iIndex].angles.x; |
|
} |
|
|
|
if ( m_pParticules[iIndex].flags & FLAG_PARTICULE_SMOKE ) |
|
{ |
|
largeurX = largeurY = 0.75 * 32 * 0.5; |
|
} |
|
|
|
int modelindex; |
|
struct model_s *mod = gEngfuncs.CL_LoadModel( m_pParticules[iIndex].model, &modelindex ); |
|
|
|
|
|
gEngfuncs.pTriAPI->SpriteTexture( (struct model_s *)mod, 0 ); //chargement du sprite |
|
|
|
|
|
// mode de transparence |
|
|
|
if ( m_pParticules[iIndex].flags & ( FLAG_PARTICULE_OUTRO1 | FLAG_PARTICULE_OUTRO2 | FLAG_PARTICULE_OUTRO3 ) ) |
|
{ |
|
gEngfuncs.pTriAPI->RenderMode( kRenderTransAdd ); |
|
gEngfuncs.pTriAPI->Brightness( m_pParticules[iIndex].angles.y ); |
|
gEngfuncs.pTriAPI->Color4f( 1.0, 1.0, 1.0, m_pParticules[iIndex].angles.y ); |
|
} |
|
else if ( m_pParticules[iIndex].flags & FLAG_PARTICULE_SMOKE ) |
|
{ |
|
gEngfuncs.pTriAPI->RenderMode( kRenderTransAdd ); |
|
gEngfuncs.pTriAPI->Brightness( 240/255 ); |
|
gEngfuncs.pTriAPI->Color4f( 1.0, 1.0, 1.0, 240/255 ); |
|
} |
|
else |
|
{ |
|
gEngfuncs.pTriAPI->RenderMode( kRenderTransAlpha ); |
|
gEngfuncs.pTriAPI->Brightness( 1 ); |
|
gEngfuncs.pTriAPI->Color4f( 1.0, 1.0, 1.0, 1.0 ); |
|
} |
|
|
|
|
|
|
|
gEngfuncs.pTriAPI->CullFace( TRI_NONE ); //(des)activer le face culling |
|
|
|
|
|
gEngfuncs.pTriAPI->Begin( TRI_QUADS ); //d |
|
|
|
gEngfuncs.pTriAPI->TexCoord2f( 0, 0 ); //premier vertex |
|
vertex = m_pParticules[iIndex].origin - up*largeurY - right * largeurX; |
|
gEngfuncs.pTriAPI->Vertex3f( vertex.x, vertex.y, vertex.z ); |
|
|
|
gEngfuncs.pTriAPI->TexCoord2f( 1, 0 ); //deuxieme vertex |
|
vertex = m_pParticules[iIndex].origin + right* largeurX - up*largeurY; |
|
gEngfuncs.pTriAPI->Vertex3f( vertex.x, vertex.y, vertex.z ); |
|
|
|
gEngfuncs.pTriAPI->TexCoord2f( 1, 1 ); //troisieme vertex |
|
vertex = m_pParticules[iIndex].origin + right* largeurX + up* largeurY; |
|
gEngfuncs.pTriAPI->Vertex3f( vertex.x, vertex.y, vertex.z ); |
|
|
|
gEngfuncs.pTriAPI->TexCoord2f( 0, 1 ); //quatrieme vertex |
|
vertex = m_pParticules[iIndex].origin + up* largeurX - right* largeurY; |
|
gEngfuncs.pTriAPI->Vertex3f( vertex.x, vertex.y, vertex.z ); |
|
|
|
gEngfuncs.pTriAPI->End(); //fin du trac |
|
gEngfuncs.pTriAPI->RenderMode( kRenderNormal ); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
int iDecalIndex, idecalresult = 0; |
|
|
|
for ( iDecalIndex = 0; iDecalIndex < MAX_DECALS ; iDecalIndex ++ ) |
|
{ |
|
// emplacement vide |
|
if ( m_pDecals [ iDecalIndex ].libre == 1 ) |
|
continue; |
|
|
|
idecalresult ++; |
|
|
|
// frame |
|
|
|
int frame; |
|
|
|
if ( m_pDecals[iDecalIndex].flags & FLAG_DECAL_WIDEGLASS ) |
|
frame = ( int ) m_pDecals[iDecalIndex].flFrame; |
|
else |
|
frame = 0; |
|
|
|
|
|
//trac |
|
vec3_t forward, right, up, vertex; |
|
AngleVectors ( m_pDecals[iDecalIndex].angles, forward, right, up ); |
|
|
|
// sens al |
|
up = m_pDecals[iDecalIndex].iRndSensX * up; |
|
right = m_pDecals[iDecalIndex].iRndSensY * right; |
|
|
|
const float largeur = DECALS_LARGEUR / 2; |
|
|
|
int modelindex; |
|
struct model_s *mod = gEngfuncs.CL_LoadModel( m_pDecals[iDecalIndex].model, &modelindex ); |
|
|
|
gEngfuncs.pTriAPI->SpriteTexture( (struct model_s *)mod, frame ); //chargement du sprite |
|
|
|
if ( m_pDecals[iDecalIndex].flags & ( FLAG_DECAL_DISK | FLAG_DECAL_SG | FLAG_DECAL_XENO ) ) |
|
{ |
|
gEngfuncs.pTriAPI->RenderMode( kRenderTransAdd ); //mode de transparence |
|
gEngfuncs.pTriAPI->CullFace( TRI_NONE ); //(des)activer le face culling |
|
|
|
float timeleft = m_pDecals[iDecalIndex].deathtime - gHUD.m_flTime; |
|
float alpha = timeleft <= 0.5 ? timeleft * 2 : 1.0; |
|
gEngfuncs.pTriAPI->Color4f( 1.0, 1.0, 1.0, alpha ); |
|
} |
|
else if ( m_pDecals[iDecalIndex].flags & FLAG_DECAL_XENO ) |
|
{ |
|
gEngfuncs.pTriAPI->RenderMode( kRenderTransAdd ); //mode de transparence |
|
gEngfuncs.pTriAPI->CullFace( TRI_FRONT ); //(des)activer le face culling |
|
|
|
gEngfuncs.pTriAPI->Color4f( 1.0, 1.0, 1.0, 0.6 ); |
|
} |
|
else |
|
{ |
|
gEngfuncs.pTriAPI->RenderMode( kRenderTransColor ); //mode de transparence |
|
|
|
if ( m_pDecals[iDecalIndex].flags & (FLAG_DECAL_WIDEGLASS|FLAG_DECAL_CROWBAR|FLAG_DECAL_CROWBAR_INVERT) ) |
|
gEngfuncs.pTriAPI->CullFace( TRI_NONE ); |
|
|
|
else |
|
gEngfuncs.pTriAPI->CullFace( TRI_FRONT ); //(des)activer le face culling |
|
|
|
gEngfuncs.pTriAPI->Color4f( 1.0, 1.0, 1.0, 1.0 ); |
|
} |
|
|
|
|
|
gEngfuncs.pTriAPI->Begin( TRI_QUADS ); //d |
|
|
|
gEngfuncs.pTriAPI->Brightness( 1 ); |
|
|
|
gEngfuncs.pTriAPI->TexCoord2f( 0, 0 ); //premier vertex |
|
vertex = m_pDecals[iDecalIndex].origin - ( up + right ) * largeur; |
|
gEngfuncs.pTriAPI->Vertex3f( vertex.x, vertex.y, vertex.z ); |
|
|
|
gEngfuncs.pTriAPI->Brightness( 1 ); |
|
gEngfuncs.pTriAPI->TexCoord2f( 1, 0 ); //deuxieme vertex |
|
vertex = m_pDecals[iDecalIndex].origin + ( right - up ) * largeur; |
|
gEngfuncs.pTriAPI->Vertex3f( vertex.x, vertex.y, vertex.z ); |
|
|
|
gEngfuncs.pTriAPI->Brightness( 1 ); |
|
gEngfuncs.pTriAPI->TexCoord2f( 1, 1 ); //troisieme vertex |
|
vertex = m_pDecals[iDecalIndex].origin + ( right + up ) * largeur; |
|
gEngfuncs.pTriAPI->Vertex3f( vertex.x, vertex.y, vertex.z ); |
|
|
|
gEngfuncs.pTriAPI->Brightness( 1 ); |
|
gEngfuncs.pTriAPI->TexCoord2f( 0, 1 ); //quatrieme vertex |
|
vertex = m_pDecals[iDecalIndex].origin + ( up - right ) * largeur; |
|
gEngfuncs.pTriAPI->Vertex3f( vertex.x, vertex.y, vertex.z ); |
|
|
|
gEngfuncs.pTriAPI->End(); //fin du trac |
|
gEngfuncs.pTriAPI->RenderMode( kRenderNormal ); |
|
|
|
|
|
} |
|
|
|
|
|
//controle du nombre de quads dessin |
|
|
|
// gEngfuncs.Con_Printf ( "client.dll : particules %i quads\n", iresult ); |
|
// gEngfuncs.Con_Printf ( "client.dll : decals : %i quads\n", idecalresult ); |
|
|
|
} |
|
|
|
|
|
DECLARE_MESSAGE(m_Particules, ClientDecal); //modif de Julien 7/7/01 |
|
|
|
// |
|
// |
|
// initialisation au chargement de la dll |
|
// |
|
|
|
int CHudParticules :: Init( void ) |
|
{ |
|
for ( int i = 0; i < MAX_PARTICULES ; i ++ ) |
|
{ |
|
RemoveParticule ( i ); |
|
} |
|
|
|
for ( int i = 0; i < MAX_DECALS ; i ++ ) |
|
{ |
|
RemoveDecal ( i ); |
|
} |
|
|
|
|
|
HOOK_MESSAGE(ClientDecal); //modif de Julien npopopoy gvzakdsupp |
|
|
|
m_iFlags |= HUD_ACTIVE; |
|
|
|
gHUD.AddHudElem(this); |
|
|
|
return 1; |
|
} |
|
|
|
|
|
|
|
|
|
// |
|
// |
|
// initialisation apr |
|
// |
|
|
|
int CHudParticules :: VidInit( void ) |
|
{ |
|
|
|
for ( int i = 0; i < MAX_PARTICULES ; i ++ ) |
|
{ |
|
RemoveParticule ( i ); |
|
} |
|
|
|
for ( int i = 0; i < MAX_DECALS ; i ++ ) |
|
{ |
|
RemoveDecal ( i ); |
|
} |
|
|
|
|
|
m_iFlags |= HUD_ACTIVE; |
|
|
|
return 1; |
|
} |
|
|
|
|
|
|
|
|
|
// |
|
// activation du syst |
|
// et de particules |
|
// depuis le serveur |
|
// |
|
|
|
|
|
int CHudParticules::MsgFunc_ClientDecal( const char *pszName, int iSize, void *pbuf ) |
|
{ |
|
BEGIN_READ( pbuf, iSize ); |
|
|
|
Vector vecSrc, vecNormal; |
|
char chTextureType; |
|
|
|
vecSrc.x = READ_COORD(); |
|
vecSrc.y = READ_COORD(); |
|
vecSrc.z = READ_COORD(); |
|
|
|
vecNormal.x = READ_COORD(); |
|
vecNormal.y = READ_COORD(); |
|
vecNormal.z = READ_COORD(); |
|
|
|
chTextureType = READ_CHAR(); |
|
int decal = READ_BYTE(); |
|
|
|
if ( decal == 4 ) // explo electro-roquette |
|
{ |
|
AddDecal ( vecSrc, Vector ( 90,0,0 ), "sprites/rpg_disk.spr", gHUD.m_flTime + ELECTRO_DISK_MAX / ELECTRO_DISK_SPEED + 0.5, FLAG_DECAL_DISK ); |
|
return 1; |
|
} |
|
if ( decal == 5 ) // explo supergun |
|
{ |
|
Vector angDir; |
|
VectorAngles ( -vecNormal, angDir ); |
|
angDir.y += 180; |
|
|
|
AddDecal ( vecSrc, angDir, "sprites/rpg_disk.spr", gHUD.m_flTime + 0.5, FLAG_DECAL_SG ); |
|
return 1; |
|
} |
|
|
|
if ( decal == 6 ) // muzzle outro |
|
{ |
|
Vector vecDir = vecNormal, velocity (0,0,0), avelocity(0,0,0), src = vecSrc; |
|
float largeur, brightness; |
|
|
|
//gros |
|
|
|
for ( int j=0; j<4; j++ ) |
|
{ |
|
avelocity = Vector (0.0f, 0.0f, gEngfuncs.pfnRandomFloat(30,60)* ((j%2)==0?1:-1) ); |
|
velocity = Vector (vecDir - vecSrc) * 0/*( 0.08 - j*0.02 )*/; |
|
largeur = 5; |
|
brightness = 0.3; |
|
|
|
AddParticule ( src, Vector (largeur,brightness,0.0f), velocity, avelocity , "sprites/outro_muzzle.spr", gHUD.m_flTime + 7, FLAG_PARTICULE_OUTRO1 ); |
|
} |
|
|
|
// petits |
|
|
|
for ( int i=0; i<10; i++ ) |
|
{ |
|
brightness = 0.3; |
|
avelocity = Vector (0.0f, 0.0f, gEngfuncs.pfnRandomFloat(-300,300) ); |
|
// velocity = Vector (vecDir - vecSrc) * ( 0.3 - i*0.03 ) * 2.5; |
|
velocity = Vector (vecDir - vecSrc).Normalize() * 0.1; |
|
largeur = 1.2 + i*0.3; |
|
src = vecSrc + 0.1*(vecDir-vecSrc); |
|
|
|
AddParticule ( src, Vector (largeur,brightness,0.0f), velocity, avelocity, "sprites/outro_muzzle.spr", gHUD.m_flTime + 7, FLAG_PARTICULE_OUTRO2 ); |
|
} |
|
|
|
return 1; |
|
} |
|
|
|
EV_HLDM_EjectParticules ( vecSrc, vecNormal, chTextureType, decal, 1 ); |
|
|
|
return 1; |
|
} |
|
|
|
/* |
|
message du serveur |
|
|
|
MESSAGE_BEGIN( MSG_ALL, gmsgClientDecal ); |
|
|
|
WRITE_COORD( vecSrc.x ); // xyz source |
|
WRITE_COORD( vecSrc.y ); |
|
WRITE_COORD( vecSrc.z ); |
|
WRITE_COORD( pTrace->vecPlaneNormal.x ); // xyz norme |
|
WRITE_COORD( pTrace->vecPlaneNormal.y ); |
|
WRITE_COORD( pTrace->vecPlaneNormal.z ); |
|
WRITE_CHAR ( chTextureType ); // type de texture |
|
|
|
MESSAGE_END(); |
|
*/ |
|
|
|
|
|
|
|
|
|
|