diff options
author | Andrey Nazarov <skuller@skuller.net> | 2010-02-28 19:41:35 +0000 |
---|---|---|
committer | Andrey Nazarov <skuller@skuller.net> | 2010-02-28 19:41:35 +0000 |
commit | f73160ca01dd262d2031890e697dd63963f4bc8b (patch) | |
tree | f7acfadeeb5c57568190ac616da4849eed689ddd | |
parent | 7e48fd890309c7d2bd2176e6df1ed0cc661bcb6f (diff) |
Moved some fx code to where it really belongs.
-rw-r--r-- | source/cl_ents.c | 43 | ||||
-rw-r--r-- | source/cl_fx.c | 613 | ||||
-rw-r--r-- | source/cl_local.h | 275 | ||||
-rw-r--r-- | source/cl_main.c | 1 | ||||
-rw-r--r-- | source/cl_newfx.c | 199 | ||||
-rw-r--r-- | source/cl_parse.c | 6 | ||||
-rw-r--r-- | source/cl_tent.c | 1428 |
7 files changed, 1252 insertions, 1313 deletions
diff --git a/source/cl_ents.c b/source/cl_ents.c index 3937df0..d60215d 100644 --- a/source/cl_ents.c +++ b/source/cl_ents.c @@ -117,6 +117,48 @@ static void CL_SetEntityState( entity_state_t *state ) { } /* +============== +CL_EntityEvent + +An entity has just been parsed that has an event value +============== +*/ +extern qhandle_t cl_sfx_footsteps[4]; + +static void CL_EntityEvent (int number) { + centity_t *cent = &cl_entities[number]; + + // EF_TELEPORTER acts like an event, but is not cleared each frame + if( cent->current.effects & EF_TELEPORTER ) { + CL_TeleporterParticles( cent->current.origin ); + } + + switch (cent->current.event) { + case EV_ITEM_RESPAWN: + S_StartSound (NULL, number, CHAN_WEAPON, S_RegisterSound("items/respawn1.wav"), 1, ATTN_IDLE, 0); + CL_ItemRespawnParticles (cent->current.origin); + break; + case EV_PLAYER_TELEPORT: + S_StartSound (NULL, number, CHAN_WEAPON, S_RegisterSound("misc/tele1.wav"), 1, ATTN_IDLE, 0); + CL_TeleportParticles (cent->current.origin); + break; + case EV_FOOTSTEP: + if (cl_footsteps->integer) + S_StartSound (NULL, number, CHAN_BODY, cl_sfx_footsteps[rand()&3], 1, ATTN_NORM, 0); + break; + case EV_FALLSHORT: + S_StartSound (NULL, number, CHAN_AUTO, S_RegisterSound ("player/land1.wav"), 1, ATTN_NORM, 0); + break; + case EV_FALL: + S_StartSound (NULL, number, CHAN_AUTO, S_RegisterSound ("*fall2.wav"), 1, ATTN_NORM, 0); + break; + case EV_FALLFAR: + S_StartSound (NULL, number, CHAN_AUTO, S_RegisterSound ("*fall1.wav"), 1, ATTN_NORM, 0); + break; + } +} + +/* ================== CL_DeltaFrame @@ -946,7 +988,6 @@ void CL_AddEntities( void ) { CL_CalcViewValues(); CL_AddPacketEntities(); CL_AddTEnts(); - CL_AddLasers(); CL_AddParticles(); CL_AddDLights(); CL_AddLightStyles(); diff --git a/source/cl_fx.c b/source/cl_fx.c index 64cb6a2..07aaa4b 100644 --- a/source/cl_fx.c +++ b/source/cl_fx.c @@ -24,10 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. void CL_LogoutEffect (vec3_t org, int type); void CL_ItemRespawnParticles (vec3_t org); -static vec3_t avelocities [NUMVERTEXNORMALS]; - -extern qhandle_t cl_mod_smoke; -extern qhandle_t cl_mod_flash; +static vec3_t avelocities[NUMVERTEXNORMALS]; /* ============================================================== @@ -48,12 +45,7 @@ static clightstyle_t cl_lightstyles[MAX_LIGHTSTYLES]; static LIST_DECL( cl_lightlist ); static int cl_lastofs; -/* -================ -CL_ClearLightStyles -================ -*/ -void CL_ClearLightStyles( void ) { +static void clear_lightstyles( void ) { memset( cl_lightstyles, 0, sizeof( cl_lightstyles ) ); List_Init( &cl_lightlist ); cl_lastofs = -1; @@ -124,15 +116,9 @@ DLIGHT MANAGEMENT ============================================================== */ -cdlight_t cl_dlights[MAX_DLIGHTS]; +static cdlight_t cl_dlights[MAX_DLIGHTS]; -/* -================ -CL_ClearDlights -================ -*/ -void CL_ClearDlights (void) -{ +static void clear_dlights (void) { memset (cl_dlights, 0, sizeof(cl_dlights)); } @@ -182,24 +168,6 @@ cdlight_t *CL_AllocDlight (int key) /* =============== -CL_NewDlight -=============== -*/ -void CL_NewDlight (int key, float x, float y, float z, float radius, float time) -{ - cdlight_t *dl; - - dl = CL_AllocDlight (key); - dl->origin[0] = x; - dl->origin[1] = y; - dl->origin[2] = z; - dl->radius = radius; - dl->die = cl.time + time; -} - - -/* -=============== CL_RunDLights =============== @@ -227,113 +195,51 @@ void CL_RunDLights (void) } /* -============================================================== - -LASER BEAM MANAGEMENT +=============== +CL_AddDLights -============================================================== +=============== */ - -#define LASER_FADE_NOT 1 -#define LASER_FADE_ALPHA 2 -#define LASER_FADE_RGBA 3 - -typedef struct { - entity_t ent; - vec3_t start; - vec3_t end; - int fadeType; - qboolean indexed; - color_t color; - float width; - int lifeTime; - int startTime; -} laser_t; - -#define MAX_LASERS 32 - -static laser_t cl_lasers[MAX_LASERS]; - -static laser_t *alloc_laser( void ) { - laser_t *l; - int i; - - for( i=0, l=cl_lasers ; i<MAX_LASERS ; i++, l++ ) { - if( cl.time - l->startTime >= l->lifeTime ) { - memset( l, 0, sizeof( *l ) ); - l->startTime = cl.time; - return l; - } - } - - return NULL; -} - -void CL_AddLasers( void ) { - laser_t *l; - entity_t ent; +void CL_AddDLights (void) +{ int i; - //color_t color; - int time; - float f; + cdlight_t *dl; - memset( &ent, 0, sizeof( ent ) ); + dl = cl_dlights; - for( i = 0, l = cl_lasers; i < MAX_LASERS; i++, l++ ) { - time = l->lifeTime - ( cl.time - l->startTime ); - if( time < 0 ) { - continue; +//===== +//PGM + if( scr_glconfig.renderer != GL_RENDERER_SOFTWARE ) + { + for (i=0 ; i<MAX_DLIGHTS ; i++, dl++) + { + if (!dl->radius) + continue; + V_AddLight (dl->origin, dl->radius, + dl->color[0], dl->color[1], dl->color[2]); } + } + else + { + for (i=0 ; i<MAX_DLIGHTS ; i++, dl++) + { + if (!dl->radius) + continue; - ent.alpha = l->color[3] / 255.0f; - - if( l->fadeType != LASER_FADE_NOT ) { - f = (float)time / (float)l->lifeTime; - - ent.alpha *= f; - /*if( l->fadeType == LASER_FADE_RGBA ) { - *(int *)color = *(int *)l->color; - color[0] *= f; - color[1] *= f; - color[2] *= f; - ent.skinnum = *(int *)color; - }*/ - } /*else*/ { - ent.skinnum = *(int *)l->color; + // negative light in softwaref. only black allowed + if ((dl->color[0] < 0) || (dl->color[1] < 0) || (dl->color[2] < 0)) + { + dl->radius = -(dl->radius); + dl->color[0] = 1; + dl->color[1] = 1; + dl->color[2] = 1; + } + V_AddLight (dl->origin, dl->radius, + dl->color[0], dl->color[1], dl->color[2]); } - - ent.flags = RF_TRANSLUCENT|RF_BEAM; - VectorCopy( l->start, ent.origin ); - VectorCopy( l->end, ent.oldorigin ); - ent.frame = l->width; - ent.lightstyle = !l->indexed; - - V_AddEntity( &ent ); } -} - -/* -================= -CL_ParseLaser -================= -*/ -void CL_ParseLaser( int colors ) { - laser_t *l; - - l = alloc_laser(); - if (!l) - return; - - VectorCopy( te.pos1, l->start ); - VectorCopy( te.pos2, l->end ); - l->fadeType = LASER_FADE_NOT; - l->lifeTime = 100; - l->indexed = qtrue; - l->color[0] = ( colors >> ( ( rand() % 4 ) * 8 ) ) & 0xff; - l->color[1] = 0; - l->color[2] = 0; - l->color[3] = 77; - l->width = 4; +//PGM +//===== } // ============================================================== @@ -913,57 +819,6 @@ void CL_ParseMuzzleFlash2 (void) } } - -/* -=============== -CL_AddDLights - -=============== -*/ -void CL_AddDLights (void) -{ - int i; - cdlight_t *dl; - - dl = cl_dlights; - -//===== -//PGM - if( scr_glconfig.renderer != GL_RENDERER_SOFTWARE ) - { - for (i=0 ; i<MAX_DLIGHTS ; i++, dl++) - { - if (!dl->radius) - continue; - V_AddLight (dl->origin, dl->radius, - dl->color[0], dl->color[1], dl->color[2]); - } - } - else - { - for (i=0 ; i<MAX_DLIGHTS ; i++, dl++) - { - if (!dl->radius) - continue; - - // negative light in softwaref. only black allowed - if ((dl->color[0] < 0) || (dl->color[1] < 0) || (dl->color[2] < 0)) - { - dl->radius = -(dl->radius); - dl->color[0] = 1; - dl->color[1] = 1; - dl->color[2] = 1; - } - V_AddLight (dl->origin, dl->radius, - dl->color[0], dl->color[1], dl->color[2]); - } - } -//PGM -//===== -} - - - /* ============================================================== @@ -977,13 +832,7 @@ static cparticle_t *active_particles, *free_particles; static cparticle_t particles[MAX_PARTICLES]; static const int cl_numparticles = MAX_PARTICLES; - -/* -=============== -CL_ClearParticles -=============== -*/ -void CL_ClearParticles (void) +static void clear_particles (void) { int i; @@ -1082,42 +931,6 @@ void CL_ParticleEffect2 (vec3_t org, vec3_t dir, int color, int count) } -// RAFAEL -/* -=============== -CL_ParticleEffect3 -=============== -*/ -void CL_ParticleEffect3 (vec3_t org, vec3_t dir, int color, int count) -{ - int i, j; - cparticle_t *p; - float d; - - for (i=0 ; i<count ; i++) - { - p = CL_AllocParticle(); - if (!p) - return; - - p->time = cl.time; - p->color = color; - - d = rand()&7; - for (j=0 ; j<3 ; j++) - { - p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j]; - p->vel[j] = crand()*20; - } - - p->accel[0] = p->accel[1] = 0; - p->accel[2] = PARTICLE_GRAVITY; - p->alpha = 1.0; - - p->alphavel = -1.0 / (0.5 + frand()*0.3); - } -} - /* =============== CL_TeleporterParticles @@ -1743,166 +1556,6 @@ void CL_OldRailTrail (vec3_t start, vec3_t end) } } -static color_t railcore_color; -static color_t railspiral_color; - -static cvar_t *cl_railtrail_type; -static cvar_t *cl_railtrail_time; -static cvar_t *cl_railcore_color; -static cvar_t *cl_railcore_width; -static cvar_t *cl_railspiral_color; -static cvar_t *cl_railspiral_radius; - - -static void cl_railcore_color_changed( cvar_t *self ) { - if( !SCR_ParseColor( self->string, railcore_color ) ) { - Com_WPrintf( "Invalid value '%s' for '%s'\n", self->string, self->name ); - *( uint32_t *)railcore_color = *( uint32_t * )colorRed; - } -} - -static void cl_railspiral_color_changed( cvar_t *self ) { - if( !SCR_ParseColor( self->string, railspiral_color ) ) { - Com_WPrintf( "Invalid value '%s' for '%s'\n", self->string, self->name ); - *( uint32_t *)railspiral_color = *( uint32_t * )colorBlue; - } -} - -static void CL_NewRailCore( vec3_t start, vec3_t end ) { - laser_t *l; - - l = alloc_laser(); - if (!l) - return; - - VectorCopy( start, l->start ); - VectorCopy( end, l->end ); - l->fadeType = LASER_FADE_RGBA; - l->lifeTime = 1000 * cl_railtrail_time->value; - l->indexed = qfalse; - l->width = cl_railcore_width->value; - *( uint32_t * )l->color = *( uint32_t * )railcore_color; -} - -static void CL_NewRailSpiral( vec3_t start, vec3_t end ) { - vec3_t move; - vec3_t vec; - float len; - int j; - cparticle_t *p; -// float dec; - vec3_t right, up; - int i; - float d, c, s; - vec3_t dir; - - VectorCopy( start, move ); - VectorSubtract( end, start, vec ); - len = VectorNormalize( vec ); - - MakeNormalVectors( vec, right, up ); - - for( i=0 ; i<len ; i++ ) { - p = CL_AllocParticle(); - if (!p) - return; - - p->time = cl.time; - VectorClear( p->accel ); - - d = i * 0.1; - c = cos( d ); - s = sin( d ); - - VectorScale( right, c, dir ); - VectorMA( dir, s, up, dir ); - - p->alpha = railspiral_color[3] / 255.0f; - p->alphavel = -1.0 / ( cl_railtrail_time->value + frand() * 0.2 ); - p->color = 0xff; - *( uint32_t * )p->rgb = *( uint32_t * )railspiral_color; - for( j=0 ; j<3 ; j++ ) { - p->org[j] = move[j] + dir[j] * cl_railspiral_radius->value; - p->vel[j] = dir[j] * 6; - } - - VectorAdd( move, vec, move ); - } -} - -void CL_RailTrail( vec3_t start, vec3_t end ) { - if( !cl_railtrail_type->integer || scr_glconfig.renderer == GL_RENDERER_SOFTWARE ) { - CL_OldRailTrail( start, end ); - } else { - CL_NewRailCore( start, end ); - if( cl_railtrail_type->integer > 1 ) { - CL_NewRailSpiral( start, end ); - } - } -} - - - -// RAFAEL -/* -=============== -CL_IonripperTrail -=============== -*/ -void CL_IonripperTrail (vec3_t start, vec3_t ent) -{ - vec3_t move; - vec3_t vec; - float len; - int j; - cparticle_t *p; - int dec; - int left = 0; - - VectorCopy (start, move); - VectorSubtract (ent, start, vec); - len = VectorNormalize (vec); - - dec = 5; - VectorScale (vec, 5, vec); - - while (len > 0) - { - len -= dec; - - p = CL_AllocParticle(); - if (!p) - return; - VectorClear (p->accel); - - p->time = cl.time; - p->alpha = 0.5; - p->alphavel = -1.0 / (0.3 + frand() * 0.2); - p->color = 0xe4 + (rand()&3); - - for (j=0; j<3; j++) - { - p->org[j] = move[j]; - p->accel[j] = 0; - } - if (left) - { - left = 0; - p->vel[0] = 10; - } - else - { - left = 1; - p->vel[0] = -10; - } - - p->vel[1] = 0; - p->vel[2] = 0; - - VectorAdd (move, vec, move); - } -} - /* =============== @@ -1971,13 +1624,6 @@ void CL_FlyParticles (vec3_t origin, int count) if (count > NUMVERTEXNORMALS) count = NUMVERTEXNORMALS; - if (!avelocities[0][0]) - { - for (i=0 ; i<NUMVERTEXNORMALS*3 ; i++) - avelocities[0][i] = (rand()&255) * 0.01; - } - - ltime = (float)cl.time / 1000.0; for (i=0 ; i<count ; i+=2) { @@ -2067,13 +1713,6 @@ void CL_BfgParticles (entity_t *ent) vec3_t v; float ltime; - if (!avelocities[0][0]) - { - for (i=0 ; i<NUMVERTEXNORMALS*3 ; i++) - avelocities[0][i] = (rand()&255) * 0.01; - } - - ltime = (float)cl.time / 1000.0; for (i=0 ; i<NUMVERTEXNORMALS ; i++) { @@ -2118,107 +1757,6 @@ void CL_BfgParticles (entity_t *ent) /* =============== -CL_TrapParticles -=============== -*/ -// RAFAEL -void CL_TrapParticles (entity_t *ent) -{ - vec3_t move; - vec3_t vec; - vec3_t start, end; - float len; - int j; - cparticle_t *p; - int dec; - - ent->origin[2]-=14; - VectorCopy (ent->origin, start); - VectorCopy (ent->origin, end); - end[2]+=64; - - VectorCopy (start, move); - VectorSubtract (end, start, vec); - len = VectorNormalize (vec); - - dec = 5; - VectorScale (vec, 5, vec); - - // FIXME: this is a really silly way to have a loop - while (len > 0) - { - len -= dec; - - p = CL_AllocParticle(); - if (!p) - return; - VectorClear (p->accel); - - p->time = cl.time; - - p->alpha = 1.0; - p->alphavel = -1.0 / (0.3+frand()*0.2); - p->color = 0xe0; - for (j=0 ; j<3 ; j++) - { - p->org[j] = move[j] + crand(); - p->vel[j] = crand()*15; - p->accel[j] = 0; - } - p->accel[2] = PARTICLE_GRAVITY; - - VectorAdd (move, vec, move); - } - - { - - - int i, j, k; - cparticle_t *p; - float vel; - vec3_t dir; - vec3_t org; - - - ent->origin[2]+=14; - VectorCopy (ent->origin, org); - - - for (i=-2 ; i<=2 ; i+=4) - for (j=-2 ; j<=2 ; j+=4) - for (k=-2 ; k<=4 ; k+=4) - { - p = CL_AllocParticle(); - if (!p) - return; - - p->time = cl.time; - p->color = 0xe0 + (rand()&3); - - p->alpha = 1.0; - p->alphavel = -1.0 / (0.3 + (rand()&7) * 0.02); - - p->org[0] = org[0] + i + ((rand()&23) * crand()); - p->org[1] = org[1] + j + ((rand()&23) * crand()); - p->org[2] = org[2] + k + ((rand()&23) * crand()); - - dir[0] = j * 8; - dir[1] = i * 8; - dir[2] = k * 8; - - VectorNormalize (dir); - vel = 50 + (rand()&63); - VectorScale (dir, vel, p->vel); - - p->accel[0] = p->accel[1] = 0; - p->accel[2] = -PARTICLE_GRAVITY; - } - } -} - - -/* -=============== CL_BFGExplosionParticles =============== */ @@ -2385,75 +1923,22 @@ void CL_AddParticles (void) /* ============== -CL_EntityEvent - -An entity has just been parsed that has an event value -============== -*/ -extern qhandle_t cl_sfx_footsteps[4]; - -void CL_EntityEvent (int number) -{ - centity_t *cent = &cl_entities[number]; - - // EF_TELEPORTER acts like an event, but is not cleared each frame - if( cent->current.effects & EF_TELEPORTER ) { - CL_TeleporterParticles( cent->current.origin ); - } - - switch (cent->current.event) - { - case EV_ITEM_RESPAWN: - S_StartSound (NULL, number, CHAN_WEAPON, S_RegisterSound("items/respawn1.wav"), 1, ATTN_IDLE, 0); - CL_ItemRespawnParticles (cent->current.origin); - break; - case EV_PLAYER_TELEPORT: - S_StartSound (NULL, number, CHAN_WEAPON, S_RegisterSound("misc/tele1.wav"), 1, ATTN_IDLE, 0); - CL_TeleportParticles (cent->current.origin); - break; - case EV_FOOTSTEP: - if (cl_footsteps->integer) - S_StartSound (NULL, number, CHAN_BODY, cl_sfx_footsteps[rand()&3], 1, ATTN_NORM, 0); - break; - case EV_FALLSHORT: - S_StartSound (NULL, number, CHAN_AUTO, S_RegisterSound ("player/land1.wav"), 1, ATTN_NORM, 0); - break; - case EV_FALL: - S_StartSound (NULL, number, CHAN_AUTO, S_RegisterSound ("*fall2.wav"), 1, ATTN_NORM, 0); - break; - case EV_FALLFAR: - S_StartSound (NULL, number, CHAN_AUTO, S_RegisterSound ("*fall1.wav"), 1, ATTN_NORM, 0); - break; - } -} - - -/* -============== CL_ClearEffects ============== */ void CL_ClearEffects (void) { - CL_ClearParticles (); - CL_ClearDlights (); - CL_ClearLightStyles (); - memset (cl_lasers, 0, sizeof(cl_lasers)); + clear_particles (); + clear_dlights (); + clear_lightstyles (); } void CL_InitEffects( void ) { - cl_railtrail_type = Cvar_Get( "cl_railtrail_type", "0", 0 ); - cl_railtrail_time = Cvar_Get( "cl_railtrail_time", "1.0", 0 ); - cl_railcore_color = Cvar_Get( "cl_railcore_color", "red", 0 ); - cl_railcore_color->changed = cl_railcore_color_changed; - cl_railcore_color->generator = Com_Color_g; - cl_railcore_color_changed( cl_railcore_color ); - cl_railcore_width = Cvar_Get( "cl_railcore_width", "2", 0 ); - cl_railspiral_color = Cvar_Get( "cl_railspiral_color", "blue", 0 ); - cl_railspiral_color->changed = cl_railspiral_color_changed; - cl_railspiral_color->generator = Com_Color_g; - cl_railspiral_color_changed( cl_railspiral_color ); - cl_railspiral_radius = Cvar_Get( "cl_railspiral_radius", "3", 0 ); + int i; + + for (i=0 ; i<NUMVERTEXNORMALS*3 ; i++) + avelocities[0][i] = (rand()&255) * 0.01; + } diff --git a/source/cl_local.h b/source/cl_local.h index 584c1ea..27fbd81 100644 --- a/source/cl_local.h +++ b/source/cl_local.h @@ -58,6 +58,8 @@ typedef struct centity_s { int fly_stoptime; } centity_t; +extern centity_t cl_entities[MAX_EDICTS]; + #define MAX_CLIENTWEAPONMODELS 20 // PGM -- upped from 16 to fit the chainfist vwep typedef struct clientinfo_s { @@ -225,8 +227,6 @@ typedef struct client_state_s { extern client_state_t cl; -int CL_GetSoundInfo( vec3_t origin, vec3_t forward, vec3_t right, vec3_t up ); - /* ================================================================== @@ -399,141 +399,8 @@ extern cvar_t *info_hand; extern cvar_t *info_gender; extern cvar_t *info_uf; - -typedef struct cdlight_s { - int key; // so entities can reuse same entry - vec3_t color; - vec3_t origin; - float radius; - float die; // stop lighting after this time - float decay; // drop this each second - float minlight; // don't add when contributing less -} cdlight_t; - -extern centity_t cl_entities[MAX_EDICTS]; -extern cdlight_t cl_dlights[MAX_DLIGHTS]; - - //============================================================================= - -#ifdef _DEBUG -void CL_AddNetgraph (void); -#endif - -//ROGUE -typedef struct cl_sustain_s { - int id; - int type; - int endtime; - int nextthink; - int thinkinterval; - vec3_t org; - vec3_t dir; - int color; - int count; - int magnitude; - void (*think)(struct cl_sustain_s *self); -} cl_sustain_t; - -void CL_ParticleSteamEffect2(cl_sustain_t *self); - -void CL_TeleporterParticles (vec3_t org); -void CL_ParticleEffect (vec3_t org, vec3_t dir, int color, int count); -void CL_ParticleEffect2 (vec3_t org, vec3_t dir, int color, int count); - -// RAFAEL -void CL_ParticleEffect3 (vec3_t org, vec3_t dir, int color, int count); - - -//================================================= - -// ======== -// PGM -typedef struct cparticle_s{ - struct cparticle_s *next; - - float time; - - vec3_t org; - vec3_t vel; - vec3_t accel; - float color; - float colorvel; - float alpha; - float alphavel; - color_t rgb; -} cparticle_t; - -cparticle_t *CL_AllocParticle( void ); - -#define PARTICLE_GRAVITY 40 -#define BLASTER_PARTICLE_COLOR 0xe0 -// PMM -#define INSTANT_PARTICLE -10000.0 -// PGM -// ======== - -void CL_InitEffects (void); -void CL_ClearEffects (void); -void CL_ClearTEnts (void); -void CL_BlasterTrail (vec3_t start, vec3_t end); -void CL_QuadTrail (vec3_t start, vec3_t end); -void CL_RailTrail (vec3_t start, vec3_t end); -void CL_BubbleTrail (vec3_t start, vec3_t end); -void CL_FlagTrail (vec3_t start, vec3_t end, float color); - -// RAFAEL -void CL_IonripperTrail (vec3_t start, vec3_t end); - -// ======== -// PGM -void CL_BlasterParticles2 (vec3_t org, vec3_t dir, unsigned int color); -void CL_BlasterTrail2 (vec3_t start, vec3_t end); -void CL_DebugTrail (vec3_t start, vec3_t end); -void CL_SmokeTrail (vec3_t start, vec3_t end, int colorStart, int colorRun, int spacing); -void CL_Flashlight (int ent, vec3_t pos); -void CL_ForceWall (vec3_t start, vec3_t end, int color); -void CL_FlameEffects (centity_t *ent, vec3_t origin); -void CL_GenericParticleEffect (vec3_t org, vec3_t dir, int color, int count, int numcolors, int dirspread, float alphavel); -void CL_BubbleTrail2 (vec3_t start, vec3_t end, int dist); -void CL_Heatbeam (vec3_t start, vec3_t end); -void CL_ParticleSteamEffect (vec3_t org, vec3_t dir, int color, int count, int magnitude); -void CL_TrackerTrail (vec3_t start, vec3_t end, int particleColor); -void CL_Tracker_Explode(vec3_t origin); -void CL_TagTrail (vec3_t start, vec3_t end, float color); -void CL_ColorFlash (vec3_t pos, int ent, int intensity, float r, float g, float b); -void CL_Tracker_Shell(vec3_t origin); -void CL_MonsterPlasma_Shell(vec3_t origin); -void CL_ColorExplosionParticles (vec3_t org, int color, int run); -void CL_ParticleSmokeEffect (vec3_t org, vec3_t dir, int color, int count, int magnitude); -void CL_Widowbeamout (cl_sustain_t *self); -void CL_Nukeblast (cl_sustain_t *self); -void CL_WidowSplash (void); -// PGM -// ======== - - -void CL_ParseMuzzleFlash (void); -void CL_ParseMuzzleFlash2 (void); -void SmokeAndFlash(vec3_t origin); - -void CL_SetLightstyle( int index, const char *string, size_t length ); - -void CL_ParseLaser( int colors ); - -void CL_RunParticles (void); -void CL_RunDLights (void); -void CL_RunLightStyles (void); - -void CL_AddEntities (void); -void CL_AddDLights (void); -void CL_AddTEnts (void); -void CL_AddLasers( void ); -void CL_AddLightStyles (void); - -//================================================= - // // cl_main // @@ -552,11 +419,6 @@ void CL_LoadState( load_state_t state ); void CL_SendRcon( const netadr_t *adr, const char *pass, const char *cmd ); const char *CL_Server_g( const char *partial, int argnum, int state ); -// the sound code makes callbacks to the client for entitiy position -// information, so entities can be dynamically re-spatialized -void CL_GetEntitySoundOrigin( int ent, vec3_t org ); - - // // cl_input // @@ -593,7 +455,16 @@ qboolean CL_CheckOrDownloadFile( const char *filename ); void CL_ParseServerMessage (void); void CL_LoadClientinfo (clientinfo_t *ci, const char *s); void CL_Download_f (void); + +// +// cl_ents.c +// void CL_DeltaFrame( void ); +void CL_AddEntities (void); + +// the sound code makes callbacks to the client for entitiy position +// information, so entities can be dynamically re-spatialized +void CL_GetEntitySoundOrigin( int ent, vec3_t org ); // // cl_view.c @@ -613,11 +484,30 @@ void CL_PrepRefresh (void); // // cl_tent.c // -void CL_RegisterTEntSounds (void); -void CL_RegisterTEntModels (void); + +//ROGUE +typedef struct cl_sustain_s { + int id; + int type; + int endtime; + int nextthink; + int thinkinterval; + vec3_t org; + vec3_t dir; + int color; + int count; + int magnitude; + void (*think)(struct cl_sustain_s *self); +} cl_sustain_t; + void CL_SmokeAndFlash(vec3_t origin); -void CL_AddTEnt (void); +void CL_RegisterTEntSounds (void); +void CL_RegisterTEntModels (void); +void CL_ParseTEnt (void); +void CL_AddTEnts (void); +void CL_ClearTEnts (void); +void CL_InitTEnts( void ); // @@ -629,16 +519,110 @@ void CL_CheckPredictionError (void); // // cl_fx.c // + +#define PARTICLE_GRAVITY 40 +#define BLASTER_PARTICLE_COLOR 0xe0 +// PMM +#define INSTANT_PARTICLE -10000.0 +// PGM +// ======== + +typedef struct cparticle_s { + struct cparticle_s *next; + + float time; + + vec3_t org; + vec3_t vel; + vec3_t accel; + float color; + float colorvel; + float alpha; + float alphavel; + color_t rgb; +} cparticle_t; + +typedef struct cdlight_s { + int key; // so entities can reuse same entry + vec3_t color; + vec3_t origin; + float radius; + float die; // stop lighting after this time + float decay; // drop this each second + float minlight; // don't add when contributing less +} cdlight_t; + cdlight_t *CL_AllocDlight (int key); +cparticle_t *CL_AllocParticle( void ); void CL_BigTeleportParticles (vec3_t org); void CL_RocketTrail (vec3_t start, vec3_t end, centity_t *old); void CL_DiminishingTrail (vec3_t start, vec3_t end, centity_t *old, int flags); void CL_FlyEffect (centity_t *ent, vec3_t origin); void CL_BfgParticles (entity_t *ent); +void CL_ItemRespawnParticles (vec3_t org); +void CL_InitEffects (void); +void CL_ClearEffects (void); +void CL_BlasterParticles (vec3_t org, vec3_t dir); +void CL_ExplosionParticles (vec3_t org); +void CL_BFGExplosionParticles (vec3_t org); +void CL_BlasterTrail (vec3_t start, vec3_t end); +void CL_QuadTrail (vec3_t start, vec3_t end); +void CL_OldRailTrail (vec3_t start, vec3_t end); +void CL_BubbleTrail (vec3_t start, vec3_t end); +void CL_FlagTrail (vec3_t start, vec3_t end, float color); +void CL_ParseMuzzleFlash (void); +void CL_ParseMuzzleFlash2 (void); +void CL_TeleporterParticles (vec3_t org); +void CL_TeleportParticles (vec3_t org); +void CL_ParticleEffect (vec3_t org, vec3_t dir, int color, int count); +void CL_ParticleEffect2 (vec3_t org, vec3_t dir, int color, int count); +void CL_SetLightstyle( int index, const char *string, size_t length ); +void CL_RunParticles (void); +void CL_RunDLights (void); +void CL_RunLightStyles (void); void CL_AddParticles (void); -void CL_EntityEvent (int number); +void CL_AddDLights (void); +void CL_AddLightStyles (void); + +// +// cl_newfx.c +// + +// ======== +// PGM +void CL_BlasterParticles2 (vec3_t org, vec3_t dir, unsigned int color); +void CL_BlasterTrail2 (vec3_t start, vec3_t end); +void CL_DebugTrail (vec3_t start, vec3_t end); +void CL_SmokeTrail (vec3_t start, vec3_t end, int colorStart, int colorRun, int spacing); +void CL_Flashlight (int ent, vec3_t pos); +void CL_ForceWall (vec3_t start, vec3_t end, int color); +void CL_FlameEffects (centity_t *ent, vec3_t origin); +void CL_GenericParticleEffect (vec3_t org, vec3_t dir, int color, int count, int numcolors, int dirspread, float alphavel); +void CL_BubbleTrail2 (vec3_t start, vec3_t end, int dist); +void CL_Heatbeam (vec3_t start, vec3_t end); +void CL_ParticleSteamEffect (vec3_t org, vec3_t dir, int color, int count, int magnitude); +void CL_TrackerTrail (vec3_t start, vec3_t end, int particleColor); +void CL_Tracker_Explode(vec3_t origin); +void CL_TagTrail (vec3_t start, vec3_t end, float color); +void CL_ColorFlash (vec3_t pos, int ent, int intensity, float r, float g, float b); +void CL_Tracker_Shell(vec3_t origin); +void CL_MonsterPlasma_Shell(vec3_t origin); +void CL_ColorExplosionParticles (vec3_t org, int color, int run); +void CL_ParticleSmokeEffect (vec3_t org, vec3_t dir, int color, int count, int magnitude); +void CL_Widowbeamout (cl_sustain_t *self); +void CL_Nukeblast (cl_sustain_t *self); +void CL_WidowSplash (void); +// PGM +// ======== + // RAFAEL +void CL_IonripperTrail (vec3_t start, vec3_t end); void CL_TrapParticles (entity_t *ent); +void CL_ParticleEffect3 (vec3_t org, vec3_t dir, int color, int count); +// RAFAEL + +void CL_ParticleSteamEffect2(cl_sustain_t *self); + // // cl_demo.c @@ -721,6 +705,9 @@ float SCR_FadeAlpha( unsigned startTime, unsigned visTime, unsigned fadeTime ) int SCR_DrawStringEx( int x, int y, int flags, size_t maxlen, const char *s, qhandle_t font ); void SCR_DrawStringMulti( int x, int y, int flags, size_t maxlen, const char *s, qhandle_t font ); +#ifdef _DEBUG +void CL_AddNetgraph (void); +#endif // // cl_keys.c diff --git a/source/cl_main.c b/source/cl_main.c index e9da85c..7fc972c 100644 --- a/source/cl_main.c +++ b/source/cl_main.c @@ -2523,6 +2523,7 @@ static void CL_InitLocal ( void ) { LOC_Init(); CL_InitAscii(); CL_InitEffects(); + CL_InitTEnts(); Cmd_Register( c_client ); diff --git a/source/cl_newfx.c b/source/cl_newfx.c index 43e7dee..a1de0b3 100644 --- a/source/cl_newfx.c +++ b/source/cl_newfx.c @@ -1035,3 +1035,202 @@ void CL_BlasterTrail2 (vec3_t start, vec3_t end) VectorAdd (move, vec, move); } } + +// RAFAEL +/* +=============== +CL_IonripperTrail +=============== +*/ +void CL_IonripperTrail (vec3_t start, vec3_t ent) +{ + vec3_t move; + vec3_t vec; + float len; + int j; + cparticle_t *p; + int dec; + int left = 0; + + VectorCopy (start, move); + VectorSubtract (ent, start, vec); + len = VectorNormalize (vec); + + dec = 5; + VectorScale (vec, 5, vec); + + while (len > 0) + { + len -= dec; + + p = CL_AllocParticle(); + if (!p) + return; + VectorClear (p->accel); + + p->time = cl.time; + p->alpha = 0.5; + p->alphavel = -1.0 / (0.3 + frand() * 0.2); + p->color = 0xe4 + (rand()&3); + + for (j=0; j<3; j++) + { + p->org[j] = move[j]; + p->accel[j] = 0; + } + if (left) + { + left = 0; + p->vel[0] = 10; + } + else + { + left = 1; + p->vel[0] = -10; + } + + p->vel[1] = 0; + p->vel[2] = 0; + + VectorAdd (move, vec, move); + } +} + +/* +=============== +CL_TrapParticles +=============== +*/ +// RAFAEL +void CL_TrapParticles (entity_t *ent) +{ + vec3_t move; + vec3_t vec; + vec3_t start, end; + float len; + int j; + cparticle_t *p; + int dec; + + ent->origin[2]-=14; + VectorCopy (ent->origin, start); + VectorCopy (ent->origin, end); + end[2]+=64; + + VectorCopy (start, move); + VectorSubtract (end, start, vec); + len = VectorNormalize (vec); + + dec = 5; + VectorScale (vec, 5, vec); + + // FIXME: this is a really silly way to have a loop + while (len > 0) + { + len -= dec; + + p = CL_AllocParticle(); + if (!p) + return; + VectorClear (p->accel); + + p->time = cl.time; + + p->alpha = 1.0; + p->alphavel = -1.0 / (0.3+frand()*0.2); + p->color = 0xe0; + for (j=0 ; j<3 ; j++) + { + p->org[j] = move[j] + crand(); + p->vel[j] = crand()*15; + p->accel[j] = 0; + } + p->accel[2] = PARTICLE_GRAVITY; + + VectorAdd (move, vec, move); + } + + { + + + int i, j, k; + cparticle_t *p; + float vel; + vec3_t dir; + vec3_t org; + + + ent->origin[2]+=14; + VectorCopy (ent->origin, org); + + + for (i=-2 ; i<=2 ; i+=4) + for (j=-2 ; j<=2 ; j+=4) + for (k=-2 ; k<=4 ; k+=4) + { + p = CL_AllocParticle(); + if (!p) + return; + + p->time = cl.time; + p->color = 0xe0 + (rand()&3); + + p->alpha = 1.0; + p->alphavel = -1.0 / (0.3 + (rand()&7) * 0.02); + + p->org[0] = org[0] + i + ((rand()&23) * crand()); + p->org[1] = org[1] + j + ((rand()&23) * crand()); + p->org[2] = org[2] + k + ((rand()&23) * crand()); + + dir[0] = j * 8; + dir[1] = i * 8; + dir[2] = k * 8; + + VectorNormalize (dir); + vel = 50 + (rand()&63); + VectorScale (dir, vel, p->vel); + + p->accel[0] = p->accel[1] = 0; + p->accel[2] = -PARTICLE_GRAVITY; + } + } +} + +// RAFAEL +/* +=============== +CL_ParticleEffect3 +=============== +*/ +void CL_ParticleEffect3 (vec3_t org, vec3_t dir, int color, int count) +{ + int i, j; + cparticle_t *p; + float d; + + for (i=0 ; i<count ; i++) + { + p = CL_AllocParticle(); + if (!p) + return; + + p->time = cl.time; + p->color = color; + + d = rand()&7; + for (j=0 ; j<3 ; j++) + { + p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j]; + p->vel[j] = crand()*20; + } + + p->accel[0] = p->accel[1] = 0; + p->accel[2] = PARTICLE_GRAVITY; + p->alpha = 1.0; + + p->alphavel = -1.0 / (0.5 + frand()*0.3); + } +} + + + diff --git a/source/cl_parse.c b/source/cl_parse.c index bb1f0e1..5b32eaf 100644 --- a/source/cl_parse.c +++ b/source/cl_parse.c @@ -1012,7 +1012,7 @@ ACTION MESSAGES tent_params_t te; -static void CL_ParseTEnt( void ) { +static void CL_ParseTEntParams( void ) { te.type = MSG_ReadByte(); switch( te.type ) { @@ -1132,7 +1132,7 @@ static void CL_ParseTEnt( void ) { Com_Error( ERR_DROP, "%s: bad type", __func__ ); } - CL_AddTEnt(); + CL_ParseTEnt(); } /* @@ -1532,7 +1532,7 @@ void CL_ParseServerMessage( void ) { break; case svc_temp_entity: - CL_ParseTEnt(); + CL_ParseTEntParams(); break; case svc_muzzleflash: diff --git a/source/cl_tent.c b/source/cl_tent.c index 920f574..5a4859d 100644 --- a/source/cl_tent.c +++ b/source/cl_tent.c @@ -21,62 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "cl_local.h" -typedef struct { - enum { - ex_free, - ex_explosion, - ex_misc, - ex_flash, - ex_mflash, - ex_poly, - ex_poly2, - ex_light - } type; - - entity_t ent; - int frames; - float light; - vec3_t lightcolor; - float start; - int baseframe; -} explosion_t; - -#define MAX_EXPLOSIONS 32 - -static explosion_t cl_explosions[MAX_EXPLOSIONS]; - -typedef struct { - int entity; - int dest_entity; - qhandle_t model; - int endtime; - vec3_t offset; - vec3_t start, end; -} beam_t; - -#define MAX_BEAMS 32 - -static beam_t cl_beams[MAX_BEAMS]; - -//PMM - added this for player-linked beams. -//Currently only used by the plasma beam -static beam_t cl_playerbeams[MAX_BEAMS]; - -#define MAX_SUSTAINS 32 - -//ROGUE -static cl_sustain_t cl_sustains[MAX_SUSTAINS]; -//ROGUE - -//PGM -extern void CL_TeleportParticles (vec3_t org); -//PGM - -void CL_BlasterParticles (vec3_t org, vec3_t dir); -void CL_ExplosionParticles (vec3_t org); -void CL_BFGExplosionParticles (vec3_t org); -// RAFAEL -void CL_BlueBlasterParticles (vec3_t org, vec3_t dir); +void MakeNormalVectors (vec3_t forward, vec3_t right, vec3_t up); qhandle_t cl_sfx_ric1; qhandle_t cl_sfx_ric2; @@ -113,9 +58,6 @@ qhandle_t cl_mod_heatbeam; qhandle_t cl_mod_monster_heatbeam; qhandle_t cl_mod_explo4_big; - - - //ROGUE /* ================= @@ -127,9 +69,6 @@ void CL_RegisterTEntSounds (void) int i; char name[MAX_QPATH]; - // PMM - version stuff -// Com_Printf ("%s\n", ROGUE_VERSION_STRING); - // PMM cl_sfx_ric1 = S_RegisterSound ("world/ric1.wav"); cl_sfx_ric2 = S_RegisterSound ("world/ric2.wav"); cl_sfx_ric3 = S_RegisterSound ("world/ric3.wav"); @@ -157,10 +96,6 @@ void CL_RegisterTEntSounds (void) //PGM cl_sfx_lightning = S_RegisterSound ("weapons/tesla.wav"); cl_sfx_disrexp = S_RegisterSound ("weapons/disrupthit.wav"); - // version stuff -// sprintf (name, "weapons/sound%d.wav", ROGUE_VERSION_ID); -// if (name[0] == 'w') -// name[0] = 'W'; //PGM } @@ -206,19 +141,39 @@ void CL_RegisterTEntModels (void) } /* -================= -CL_ClearTEnts -================= +============================================================== + +EXPLOSION MANAGEMENT + +============================================================== */ -void CL_ClearTEnts (void) -{ - memset (cl_beams, 0, sizeof(cl_beams)); - memset (cl_explosions, 0, sizeof(cl_explosions)); -//ROGUE - memset (cl_playerbeams, 0, sizeof(cl_playerbeams)); - memset (cl_sustains, 0, sizeof(cl_sustains)); -//ROGUE +typedef struct { + enum { + ex_free, + ex_explosion, + ex_misc, + ex_flash, + ex_mflash, + ex_poly, + ex_poly2, + ex_light + } type; + + entity_t ent; + int frames; + float light; + vec3_t lightcolor; + float start; + int baseframe; +} explosion_t; + +#define MAX_EXPLOSIONS 32 + +static explosion_t cl_explosions[MAX_EXPLOSIONS]; + +static void clear_explosions( void ) { + memset (cl_explosions, 0, sizeof(cl_explosions)); } static explosion_t *alloc_explosion( void ) { @@ -246,6 +201,25 @@ static explosion_t *alloc_explosion( void ) { return oldest; } +static explosion_t *plain_explosion( void ) { + explosion_t *ex; + + ex = alloc_explosion (); + VectorCopy (te.pos1, ex->ent.origin); + ex->type = ex_poly; + ex->ent.flags = RF_FULLBRIGHT; + ex->start = cl.servertime - cl.frametime; + ex->light = 350; + VectorSet( ex->lightcolor, 1.0, 0.5, 0.5 ); + ex->ent.angles[1] = rand() % 360; + ex->ent.model = cl_mod_explo4; + if (frand() < 0.5) + ex->baseframe = 15; + ex->frames = 15; + + return ex; +} + /* ================= CL_SmokeAndFlash @@ -272,8 +246,250 @@ void CL_SmokeAndFlash(vec3_t origin) ex->ent.model = cl_mod_flash; } -static void CL_ParseBeam (qhandle_t model) +/* +================= +CL_AddExplosions +================= +*/ +static void CL_AddExplosions (void) { + entity_t *ent; + int i; + explosion_t *ex; + float frac; + int f; + + memset (&ent, 0, sizeof(ent)); + + for (i=0, ex=cl_explosions ; i< MAX_EXPLOSIONS ; i++, ex++) + { + if (ex->type == ex_free) + continue; + frac = (cl.time - ex->start)/100.0; + f = floor(frac); + + ent = &ex->ent; + + switch (ex->type) { + case ex_mflash: + if (f >= ex->frames-1) + ex->type = ex_free; + break; + case ex_misc: + case ex_light: + if (f >= ex->frames-1) { + ex->type = ex_free; + break; + } + ent->alpha = 1.0 - frac/(ex->frames-1); + break; + case ex_flash: + if (f >= 1) { + ex->type = ex_free; + break; + } + ent->alpha = 1.0; + break; + case ex_poly: + if (f >= ex->frames-1) { + ex->type = ex_free; + break; + } + + ent->alpha = (16.0 - (float)f)/16.0; + + if (f < 10) { + ent->skinnum = (f>>1); + if (ent->skinnum < 0) + ent->skinnum = 0; + } else { + ent->flags |= RF_TRANSLUCENT; + if (f < 13) + ent->skinnum = 5; + else + ent->skinnum = 6; + } + break; + case ex_poly2: + if (f >= ex->frames-1) { + ex->type = ex_free; + break; + } + + ent->alpha = (5.0 - (float)f)/5.0; + ent->skinnum = 0; + ent->flags |= RF_TRANSLUCENT; + break; + default: + break; + } + + if (ex->type == ex_free) + continue; + if (ex->light) { + V_AddLight (ent->origin, ex->light*ent->alpha, + ex->lightcolor[0], ex->lightcolor[1], ex->lightcolor[2]); + } + + if( ex->type != ex_light ) { + VectorCopy (ent->origin, ent->oldorigin); + + if (f < 0) + f = 0; + ent->frame = ex->baseframe + f + 1; + ent->oldframe = ex->baseframe + f; + ent->backlerp = 1.0 - cl.lerpfrac; + + V_AddEntity (ent); + } + } +} + +/* +============================================================== + +LASER MANAGEMENT + +============================================================== +*/ + +#define LASER_FADE_NOT 1 +#define LASER_FADE_ALPHA 2 +#define LASER_FADE_RGBA 3 + +typedef struct { + entity_t ent; + vec3_t start; + vec3_t end; + int fadeType; + qboolean indexed; + color_t color; + float width; + int lifeTime; + int startTime; +} laser_t; + +#define MAX_LASERS 32 + +static laser_t cl_lasers[MAX_LASERS]; + +static void clear_lasers( void ) { + memset (cl_lasers, 0, sizeof(cl_lasers)); +} + +static laser_t *alloc_laser( void ) { + laser_t *l; + int i; + + for( i=0, l=cl_lasers ; i<MAX_LASERS ; i++, l++ ) { + if( cl.time - l->startTime >= l->lifeTime ) { + memset( l, 0, sizeof( *l ) ); + l->startTime = cl.time; + return l; + } + } + + return NULL; +} + +static void CL_AddLasers( void ) { + laser_t *l; + entity_t ent; + int i; + //color_t color; + int time; + float f; + + memset( &ent, 0, sizeof( ent ) ); + + for( i = 0, l = cl_lasers; i < MAX_LASERS; i++, l++ ) { + time = l->lifeTime - ( cl.time - l->startTime ); + if( time < 0 ) { + continue; + } + + ent.alpha = l->color[3] / 255.0f; + + if( l->fadeType != LASER_FADE_NOT ) { + f = (float)time / (float)l->lifeTime; + + ent.alpha *= f; + /*if( l->fadeType == LASER_FADE_RGBA ) { + *(int *)color = *(int *)l->color; + color[0] *= f; + color[1] *= f; + color[2] *= f; + ent.skinnum = *(int *)color; + }*/ + } /*else*/ { + ent.skinnum = *(int *)l->color; + } + + ent.flags = RF_TRANSLUCENT|RF_BEAM; + VectorCopy( l->start, ent.origin ); + VectorCopy( l->end, ent.oldorigin ); + ent.frame = l->width; + ent.lightstyle = !l->indexed; + + V_AddEntity( &ent ); + } +} + +/* +================= +CL_ParseLaser +================= +*/ +static void CL_ParseLaser( int colors ) { + laser_t *l; + + l = alloc_laser(); + if (!l) + return; + + VectorCopy( te.pos1, l->start ); + VectorCopy( te.pos2, l->end ); + l->fadeType = LASER_FADE_NOT; + l->lifeTime = 100; + l->indexed = qtrue; + l->color[0] = ( colors >> ( ( rand() % 4 ) * 8 ) ) & 0xff; + l->color[1] = 0; + l->color[2] = 0; + l->color[3] = 77; + l->width = 4; +} + +/* +============================================================== + +BEAM MANAGEMENT + +============================================================== +*/ + +typedef struct { + int entity; + int dest_entity; + qhandle_t model; + int endtime; + vec3_t offset; + vec3_t start, end; +} beam_t; + +#define MAX_BEAMS 32 + +static beam_t cl_beams[MAX_BEAMS]; + +//PMM - added this for player-linked beams. +//Currently only used by the plasma beam +static beam_t cl_playerbeams[MAX_BEAMS]; + +static void clear_beams( void ) { + memset (cl_beams, 0, sizeof(cl_beams)); + memset (cl_playerbeams, 0, sizeof(cl_playerbeams)); +} + +static void CL_ParseBeam (qhandle_t model) { beam_t *b; int i; @@ -283,10 +499,8 @@ static void CL_ParseBeam (qhandle_t model) goto override; // find a free beam - for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) - { - if (!b->model || b->endtime < cl.time) - { + for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) { + if (!b->model || b->endtime < cl.time) { override: b->entity = te.entity1; b->dest_entity = te.entity2; @@ -301,17 +515,14 @@ override: } // ROGUE -static void CL_ParsePlayerBeam (qhandle_t model) -{ +static void CL_ParsePlayerBeam (qhandle_t model) { beam_t *b; int i; // override any beam with the same entity // PMM - For player beams, we only want one per player (entity) so.. - for (i=0, b=cl_playerbeams ; i< MAX_BEAMS ; i++, b++) - { - if (b->entity == te.entity1) - { + for (i=0, b=cl_playerbeams ; i< MAX_BEAMS ; i++, b++) { + if (b->entity == te.entity1) { b->entity = te.entity1; b->model = model; b->endtime = cl.time + 200; @@ -323,10 +534,8 @@ static void CL_ParsePlayerBeam (qhandle_t model) } // find a free beam - for (i=0, b=cl_playerbeams ; i< MAX_BEAMS ; i++, b++) - { - if (!b->model || b->endtime < cl.time) - { + for (i=0, b=cl_playerbeams ; i< MAX_BEAMS ; i++, b++) { + if (!b->model || b->endtime < cl.time) { b->entity = te.entity1; b->model = model; b->endtime = cl.time + 100; // PMM - this needs to be 100 to prevent multiple heatbeams @@ -340,6 +549,390 @@ static void CL_ParsePlayerBeam (qhandle_t model) } //rogue +/* +================= +CL_AddBeams +================= +*/ +static void CL_AddBeams (void) +{ + int i,j; + beam_t *b; + vec3_t dist, org; + float d; + entity_t ent; + float yaw, pitch; + float forward; + float len, steps; + float model_length; + +// update beams + for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) + { + if (!b->model || b->endtime < cl.time) + continue; + + // if coming from the player, update the start position + if (b->entity == cl.frame.clientNum+1) // entity 0 is the world + { + VectorCopy (cl.refdef.vieworg, b->start); + b->start[2] -= 22; // adjust for view height + } + VectorAdd (b->start, b->offset, org); + + // calculate pitch and yaw + VectorSubtract (b->end, org, dist); + + if (dist[1] == 0 && dist[0] == 0) + { + yaw = 0; + if (dist[2] > 0) + pitch = 90; + else + pitch = 270; + } + else + { + // PMM - fixed to correct for pitch of 0 + if (dist[0]) + yaw = (atan2(dist[1], dist[0]) * 180 / M_PI); + else if (dist[1] > 0) + yaw = 90; + else + yaw = 270; + if (yaw < 0) + yaw += 360; + + forward = sqrt (dist[0]*dist[0] + dist[1]*dist[1]); + pitch = (atan2(dist[2], forward) * -180.0 / M_PI); + if (pitch < 0) + pitch += 360.0; + } + + // add new entities for the beams + d = VectorNormalize(dist); + + memset (&ent, 0, sizeof(ent)); + if (b->model == cl_mod_lightning) + { + model_length = 35.0; + d-= 20.0; // correction so it doesn't end in middle of tesla + } + else + { + model_length = 30.0; + } + steps = ceil(d/model_length); + len = (d-model_length)/(steps-1); + + // PMM - special case for lightning model .. if the real length is shorter than the model, + // flip it around & draw it from the end to the start. This prevents the model from going + // through the tesla mine (instead it goes through the target) + if ((b->model == cl_mod_lightning) && (d <= model_length)) + { +// Com_Printf ("special case\n"); + VectorCopy (b->end, ent.origin); + // offset to push beam outside of tesla model (negative because dist is from end to start + // for this beam) +// for (j=0 ; j<3 ; j++) +// ent.origin[j] -= dist[j]*10.0; + ent.model = b->model; + ent.flags = RF_FULLBRIGHT; + ent.angles[0] = pitch; + ent.angles[1] = yaw; + ent.angles[2] = rand()%360; + V_AddEntity (&ent); + return; + } + while (d > 0) + { + VectorCopy (org, ent.origin); + ent.model = b->model; + if (b->model == cl_mod_lightning) + { + ent.flags = RF_FULLBRIGHT; + ent.angles[0] = -pitch; + ent.angles[1] = yaw + 180.0; + ent.angles[2] = rand()%360; + } + else + { + ent.angles[0] = pitch; + ent.angles[1] = yaw; + ent.angles[2] = rand()%360; + } + +// Com_Printf("B: %d -> %d\n", b->entity, b->dest_entity); + V_AddEntity (&ent); + + for (j=0 ; j<3 ; j++) + org[j] += dist[j]*len; + d -= model_length; + } + } +} + +/* +================= +ROGUE - draw player locked beams +CL_AddPlayerBeams +================= +*/ +static void CL_AddPlayerBeams (void) +{ + int i,j; + beam_t *b; + vec3_t dist, org; + float d; + entity_t ent; + float yaw, pitch; + float forward; + float len, steps; + int framenum = 0; + float model_length; + + float hand_multiplier; +// frame_t *oldframe; + player_state_t *ps, *ops; + +//PMM + if (info_hand->integer == 2) + hand_multiplier = 0; + else if (info_hand->integer == 1) + hand_multiplier = -1; + else + hand_multiplier = 1; +//PMM + +// update beams + for (i=0, b=cl_playerbeams ; i< MAX_BEAMS ; i++, b++) + { + vec3_t f,r,u; + if (!b->model || b->endtime < cl.time) + continue; + + if(cl_mod_heatbeam && (b->model == cl_mod_heatbeam)) + { + + // if coming from the player, update the start position + if (b->entity == cl.frame.clientNum+1) // entity 0 is the world + { + // set up gun position + ps = &cl.frame.ps; + ops = &cl.oldframe.ps; + + if( !cl.oldframe.valid || cl.oldframe.number != cl.frame.number - 1 ) + ops = ps; // previous frame was dropped or invalid + + for (j=0 ; j<3 ; j++) + { + b->start[j] = cl.refdef.vieworg[j] + ops->gunoffset[j] + + cl.lerpfrac * (ps->gunoffset[j] - ops->gunoffset[j]); + } + VectorMA (b->start, (hand_multiplier * b->offset[0]), cl.v_right, org); + VectorMA ( org, b->offset[1], cl.v_forward, org); + VectorMA ( org, b->offset[2], cl.v_up, org); + if (info_hand->integer == 2) { + VectorMA (org, -1, cl.v_up, org); + } + // FIXME - take these out when final + VectorCopy (cl.v_right, r); + VectorCopy (cl.v_forward, f); + VectorCopy (cl.v_up, u); + + } + else + VectorCopy (b->start, org); + } + else + { + // if coming from the player, update the start position + if (b->entity == cl.frame.clientNum+1) // entity 0 is the world + { + VectorCopy (cl.refdef.vieworg, b->start); + b->start[2] -= 22; // adjust for view height + } + VectorAdd (b->start, b->offset, org); + } + + // calculate pitch and yaw + VectorSubtract (b->end, org, dist); + +//PMM + if(cl_mod_heatbeam && (b->model == cl_mod_heatbeam) && (b->entity == cl.frame.clientNum+1)) + { + vec_t len; + + len = VectorLength (dist); + VectorScale (f, len, dist); + VectorMA (dist, (hand_multiplier * b->offset[0]), r, dist); + VectorMA (dist, b->offset[1], f, dist); + VectorMA (dist, b->offset[2], u, dist); + if (info_hand->integer == 2) { + VectorMA (org, -1, cl.v_up, org); + } + } +//PMM + + if (dist[1] == 0 && dist[0] == 0) + { + yaw = 0; + if (dist[2] > 0) + pitch = 90; + else + pitch = 270; + } + else + { + // PMM - fixed to correct for pitch of 0 + if (dist[0]) + yaw = (atan2(dist[1], dist[0]) * 180 / M_PI); + else if (dist[1] > 0) + yaw = 90; + else + yaw = 270; + if (yaw < 0) + yaw += 360; + + forward = sqrt (dist[0]*dist[0] + dist[1]*dist[1]); + pitch = (atan2(dist[2], forward) * -180.0 / M_PI); + if (pitch < 0) + pitch += 360.0; + } + + if (cl_mod_heatbeam && (b->model == cl_mod_heatbeam)) + { + if (b->entity != cl.frame.clientNum+1) + { + framenum = 2; +// Com_Printf ("Third person\n"); + ent.angles[0] = -pitch; + ent.angles[1] = yaw + 180.0; + ent.angles[2] = 0; +// Com_Printf ("%f %f - %f %f %f\n", -pitch, yaw+180.0, b->offset[0], b->offset[1], b->offset[2]); + AngleVectors(ent.angles, f, r, u); + + // if it's a non-origin offset, it's a player, so use the hardcoded player offset + if (!VectorCompare (b->offset, vec3_origin)) + { + VectorMA (org, -(b->offset[0])+1, r, org); + VectorMA (org, -(b->offset[1]), f, org); + VectorMA (org, -(b->offset[2])-10, u, org); + } + else + { + // if it's a monster, do the particle effect + CL_MonsterPlasma_Shell(b->start); + } + } + else + { + framenum = 1; + } + } + + // if it's the heatbeam, draw the particle effect + if ((cl_mod_heatbeam && (b->model == cl_mod_heatbeam) && (b->entity == cl.frame.clientNum+1))) + { + CL_Heatbeam (org, dist); + } + + // add new entities for the beams + d = VectorNormalize(dist); + + memset (&ent, 0, sizeof(ent)); + if (b->model == cl_mod_heatbeam) + { + model_length = 32.0; + } + else if (b->model == cl_mod_lightning) + { + model_length = 35.0; + d-= 20.0; // correction so it doesn't end in middle of tesla + } + else + { + model_length = 30.0; + } + steps = ceil(d/model_length); + len = (d-model_length)/(steps-1); + + // PMM - special case for lightning model .. if the real length is shorter than the model, + // flip it around & draw it from the end to the start. This prevents the model from going + // through the tesla mine (instead it goes through the target) + if ((b->model == cl_mod_lightning) && (d <= model_length)) + { +// Com_Printf ("special case\n"); + VectorCopy (b->end, ent.origin); + // offset to push beam outside of tesla model (negative because dist is from end to start + // for this beam) +// for (j=0 ; j<3 ; j++) +// ent.origin[j] -= dist[j]*10.0; + ent.model = b->model; + ent.flags = RF_FULLBRIGHT; + ent.angles[0] = pitch; + ent.angles[1] = yaw; + ent.angles[2] = rand()%360; + V_AddEntity (&ent); + return; + } + while (d > 0) + { + VectorCopy (org, ent.origin); + ent.model = b->model; + if(cl_mod_heatbeam && (b->model == cl_mod_heatbeam)) + { +// ent.flags = RF_FULLBRIGHT|RF_TRANSLUCENT; +// ent.alpha = 0.3; + ent.flags = RF_FULLBRIGHT; + ent.angles[0] = -pitch; + ent.angles[1] = yaw + 180.0; + ent.angles[2] = (cl.time) % 360; +// ent.angles[2] = rand()%360; + ent.frame = framenum; + } + else if (b->model == cl_mod_lightning) + { + ent.flags = RF_FULLBRIGHT; + ent.angles[0] = -pitch; + ent.angles[1] = yaw + 180.0; + ent.angles[2] = rand()%360; + } + else + { + ent.angles[0] = pitch; + ent.angles[1] = yaw; + ent.angles[2] = rand()%360; + } + +// Com_Printf("B: %d -> %d\n", b->entity, b->dest_entity); + V_AddEntity (&ent); + + for (j=0 ; j<3 ; j++) + org[j] += dist[j]*len; + d -= model_length; + } + } +} + + + +/* +============================================================== + +SUSTAIN MANAGEMENT + +============================================================== +*/ + +#define MAX_SUSTAINS 32 + +static cl_sustain_t cl_sustains[MAX_SUSTAINS]; + +static void clear_sustains( void ) { + memset (cl_sustains, 0, sizeof(cl_sustains)); +} + static cl_sustain_t *alloc_sustain( void ) { int i; cl_sustain_t *s; @@ -352,8 +945,20 @@ static cl_sustain_t *alloc_sustain( void ) { return NULL; } -//============= -//ROGUE +static void CL_ProcessSustain (void) { + cl_sustain_t *s; + int i; + + for (i=0, s=cl_sustains; i< MAX_SUSTAINS; i++, s++) { + if (s->id) { + if ((s->endtime >= cl.time) && (cl.time >= s->nextthink)) + s->think (s); + else if (s->endtime < cl.time) + s->id = 0; + } + } +} + static void CL_ParseSteam (void) { cl_sustain_t *s; @@ -408,28 +1013,106 @@ static void CL_ParseNuke (void) { s->nextthink = cl.time; } -//ROGUE -//============= +//============================================================== -static explosion_t *plain_explosion( void ) { - explosion_t *ex; +static color_t railcore_color; +static color_t railspiral_color; - ex = alloc_explosion (); - VectorCopy (te.pos1, ex->ent.origin); - ex->type = ex_poly; - ex->ent.flags = RF_FULLBRIGHT; - ex->start = cl.servertime - cl.frametime; - ex->light = 350; - VectorSet( ex->lightcolor, 1.0, 0.5, 0.5 ); - ex->ent.angles[1] = rand() % 360; - ex->ent.model = cl_mod_explo4; - if (frand() < 0.5) - ex->baseframe = 15; - ex->frames = 15; +static cvar_t *cl_railtrail_type; +static cvar_t *cl_railtrail_time; +static cvar_t *cl_railcore_color; +static cvar_t *cl_railcore_width; +static cvar_t *cl_railspiral_color; +static cvar_t *cl_railspiral_radius; - return ex; +static void cl_railcore_color_changed( cvar_t *self ) { + if( !SCR_ParseColor( self->string, railcore_color ) ) { + Com_WPrintf( "Invalid value '%s' for '%s'\n", self->string, self->name ); + *( uint32_t *)railcore_color = *( uint32_t * )colorRed; + } +} + +static void cl_railspiral_color_changed( cvar_t *self ) { + if( !SCR_ParseColor( self->string, railspiral_color ) ) { + Com_WPrintf( "Invalid value '%s' for '%s'\n", self->string, self->name ); + *( uint32_t *)railspiral_color = *( uint32_t * )colorBlue; + } +} + +static void CL_RailCore( void ) { + laser_t *l; + + l = alloc_laser(); + if (!l) + return; + + VectorCopy( te.pos1, l->start ); + VectorCopy( te.pos2, l->end ); + l->fadeType = LASER_FADE_RGBA; + l->lifeTime = 1000 * cl_railtrail_time->value; + l->indexed = qfalse; + l->width = cl_railcore_width->value; + *( uint32_t * )l->color = *( uint32_t * )railcore_color; } +static void CL_RailSpiral( void ) { + vec3_t move; + vec3_t vec; + float len; + int j; + cparticle_t *p; +// float dec; + vec3_t right, up; + int i; + float d, c, s; + vec3_t dir; + + VectorCopy( te.pos1, move ); + VectorSubtract( te.pos2, te.pos1, vec ); + len = VectorNormalize( vec ); + + MakeNormalVectors( vec, right, up ); + + for( i=0 ; i<len ; i++ ) { + p = CL_AllocParticle(); + if (!p) + return; + + p->time = cl.time; + VectorClear( p->accel ); + + d = i * 0.1; + c = cos( d ); + s = sin( d ); + + VectorScale( right, c, dir ); + VectorMA( dir, s, up, dir ); + + p->alpha = railspiral_color[3] / 255.0f; + p->alphavel = -1.0 / ( cl_railtrail_time->value + frand() * 0.2 ); + p->color = 0xff; + *( uint32_t * )p->rgb = *( uint32_t * )railspiral_color; + for( j=0 ; j<3 ; j++ ) { + p->org[j] = move[j] + dir[j] * cl_railspiral_radius->value; + p->vel[j] = dir[j] * 6; + } + + VectorAdd( move, vec, move ); + } +} + +static void CL_RailTrail( void ) { + if( !cl_railtrail_type->integer || scr_glconfig.renderer == GL_RENDERER_SOFTWARE ) { + CL_OldRailTrail( te.pos1, te.pos2 ); + } else { + CL_RailCore(); + if( cl_railtrail_type->integer > 1 ) { + CL_RailSpiral(); + } + } +} + + static void dirtoangles( vec3_t angles ) { angles[0] = acos(te.dir[2])/M_PI*180; // PMM - fixed to correct for pitch of 0 @@ -445,12 +1128,12 @@ static void dirtoangles( vec3_t angles ) { /* ================= -CL_AddTEnt +CL_ParseTEnt ================= */ static const byte splash_color[] = {0x00, 0xe0, 0xb0, 0x50, 0xd0, 0xe0, 0xe8}; -void CL_AddTEnt (void) +void CL_ParseTEnt (void) { explosion_t *ex; int r; @@ -564,7 +1247,7 @@ void CL_AddTEnt (void) break; case TE_RAILTRAIL: // railgun effect - CL_RailTrail (te.pos1, te.pos2); + CL_RailTrail (); S_StartSound (te.pos2, 0, 0, cl_sfx_railg, 1, ATTN_NORM, 0); break; @@ -809,505 +1492,48 @@ void CL_AddTEnt (void) /* ================= -CL_AddBeams -================= -*/ -static void CL_AddBeams (void) -{ - int i,j; - beam_t *b; - vec3_t dist, org; - float d; - entity_t ent; - float yaw, pitch; - float forward; - float len, steps; - float model_length; - -// update beams - for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) - { - if (!b->model || b->endtime < cl.time) - continue; - - // if coming from the player, update the start position - if (b->entity == cl.frame.clientNum+1) // entity 0 is the world - { - VectorCopy (cl.refdef.vieworg, b->start); - b->start[2] -= 22; // adjust for view height - } - VectorAdd (b->start, b->offset, org); - - // calculate pitch and yaw - VectorSubtract (b->end, org, dist); - - if (dist[1] == 0 && dist[0] == 0) - { - yaw = 0; - if (dist[2] > 0) - pitch = 90; - else - pitch = 270; - } - else - { - // PMM - fixed to correct for pitch of 0 - if (dist[0]) - yaw = (atan2(dist[1], dist[0]) * 180 / M_PI); - else if (dist[1] > 0) - yaw = 90; - else - yaw = 270; - if (yaw < 0) - yaw += 360; - - forward = sqrt (dist[0]*dist[0] + dist[1]*dist[1]); - pitch = (atan2(dist[2], forward) * -180.0 / M_PI); - if (pitch < 0) - pitch += 360.0; - } - - // add new entities for the beams - d = VectorNormalize(dist); - - memset (&ent, 0, sizeof(ent)); - if (b->model == cl_mod_lightning) - { - model_length = 35.0; - d-= 20.0; // correction so it doesn't end in middle of tesla - } - else - { - model_length = 30.0; - } - steps = ceil(d/model_length); - len = (d-model_length)/(steps-1); - - // PMM - special case for lightning model .. if the real length is shorter than the model, - // flip it around & draw it from the end to the start. This prevents the model from going - // through the tesla mine (instead it goes through the target) - if ((b->model == cl_mod_lightning) && (d <= model_length)) - { -// Com_Printf ("special case\n"); - VectorCopy (b->end, ent.origin); - // offset to push beam outside of tesla model (negative because dist is from end to start - // for this beam) -// for (j=0 ; j<3 ; j++) -// ent.origin[j] -= dist[j]*10.0; - ent.model = b->model; - ent.flags = RF_FULLBRIGHT; - ent.angles[0] = pitch; - ent.angles[1] = yaw; - ent.angles[2] = rand()%360; - V_AddEntity (&ent); - return; - } - while (d > 0) - { - VectorCopy (org, ent.origin); - ent.model = b->model; - if (b->model == cl_mod_lightning) - { - ent.flags = RF_FULLBRIGHT; - ent.angles[0] = -pitch; - ent.angles[1] = yaw + 180.0; - ent.angles[2] = rand()%360; - } - else - { - ent.angles[0] = pitch; - ent.angles[1] = yaw; - ent.angles[2] = rand()%360; - } - -// Com_Printf("B: %d -> %d\n", b->entity, b->dest_entity); - V_AddEntity (&ent); - - for (j=0 ; j<3 ; j++) - org[j] += dist[j]*len; - d -= model_length; - } - } -} - -extern cvar_t *hand; - -/* -================= -ROGUE - draw player locked beams -CL_AddPlayerBeams +CL_AddTEnts ================= */ -static void CL_AddPlayerBeams (void) -{ - int i,j; - beam_t *b; - vec3_t dist, org; - float d; - entity_t ent; - float yaw, pitch; - float forward; - float len, steps; - int framenum = 0; - float model_length; - - float hand_multiplier; -// frame_t *oldframe; - player_state_t *ps, *ops; - -//PMM - if (info_hand->integer == 2) - hand_multiplier = 0; - else if (info_hand->integer == 1) - hand_multiplier = -1; - else - hand_multiplier = 1; -//PMM - -// update beams - for (i=0, b=cl_playerbeams ; i< MAX_BEAMS ; i++, b++) - { - vec3_t f,r,u; - if (!b->model || b->endtime < cl.time) - continue; - - if(cl_mod_heatbeam && (b->model == cl_mod_heatbeam)) - { - - // if coming from the player, update the start position - if (b->entity == cl.frame.clientNum+1) // entity 0 is the world - { - // set up gun position - ps = &cl.frame.ps; - ops = &cl.oldframe.ps; - - if( !cl.oldframe.valid || cl.oldframe.number != cl.frame.number - 1 ) - ops = ps; // previous frame was dropped or invalid - - for (j=0 ; j<3 ; j++) - { - b->start[j] = cl.refdef.vieworg[j] + ops->gunoffset[j] - + cl.lerpfrac * (ps->gunoffset[j] - ops->gunoffset[j]); - } - VectorMA (b->start, (hand_multiplier * b->offset[0]), cl.v_right, org); - VectorMA ( org, b->offset[1], cl.v_forward, org); - VectorMA ( org, b->offset[2], cl.v_up, org); - if (info_hand->integer == 2) { - VectorMA (org, -1, cl.v_up, org); - } - // FIXME - take these out when final - VectorCopy (cl.v_right, r); - VectorCopy (cl.v_forward, f); - VectorCopy (cl.v_up, u); - - } - else - VectorCopy (b->start, org); - } - else - { - // if coming from the player, update the start position - if (b->entity == cl.frame.clientNum+1) // entity 0 is the world - { - VectorCopy (cl.refdef.vieworg, b->start); - b->start[2] -= 22; // adjust for view height - } - VectorAdd (b->start, b->offset, org); - } - - // calculate pitch and yaw - VectorSubtract (b->end, org, dist); - -//PMM - if(cl_mod_heatbeam && (b->model == cl_mod_heatbeam) && (b->entity == cl.frame.clientNum+1)) - { - vec_t len; - - len = VectorLength (dist); - VectorScale (f, len, dist); - VectorMA (dist, (hand_multiplier * b->offset[0]), r, dist); - VectorMA (dist, b->offset[1], f, dist); - VectorMA (dist, b->offset[2], u, dist); - if (info_hand->integer == 2) { - VectorMA (org, -1, cl.v_up, org); - } - } -//PMM - - if (dist[1] == 0 && dist[0] == 0) - { - yaw = 0; - if (dist[2] > 0) - pitch = 90; - else - pitch = 270; - } - else - { - // PMM - fixed to correct for pitch of 0 - if (dist[0]) - yaw = (atan2(dist[1], dist[0]) * 180 / M_PI); - else if (dist[1] > 0) - yaw = 90; - else - yaw = 270; - if (yaw < 0) - yaw += 360; - - forward = sqrt (dist[0]*dist[0] + dist[1]*dist[1]); - pitch = (atan2(dist[2], forward) * -180.0 / M_PI); - if (pitch < 0) - pitch += 360.0; - } - - if (cl_mod_heatbeam && (b->model == cl_mod_heatbeam)) - { - if (b->entity != cl.frame.clientNum+1) - { - framenum = 2; -// Com_Printf ("Third person\n"); - ent.angles[0] = -pitch; - ent.angles[1] = yaw + 180.0; - ent.angles[2] = 0; -// Com_Printf ("%f %f - %f %f %f\n", -pitch, yaw+180.0, b->offset[0], b->offset[1], b->offset[2]); - AngleVectors(ent.angles, f, r, u); - - // if it's a non-origin offset, it's a player, so use the hardcoded player offset - if (!VectorCompare (b->offset, vec3_origin)) - { - VectorMA (org, -(b->offset[0])+1, r, org); - VectorMA (org, -(b->offset[1]), f, org); - VectorMA (org, -(b->offset[2])-10, u, org); - } - else - { - // if it's a monster, do the particle effect - CL_MonsterPlasma_Shell(b->start); - } - } - else - { - framenum = 1; - } - } - - // if it's the heatbeam, draw the particle effect - if ((cl_mod_heatbeam && (b->model == cl_mod_heatbeam) && (b->entity == cl.frame.clientNum+1))) - { - CL_Heatbeam (org, dist); - } - - // add new entities for the beams - d = VectorNormalize(dist); - - memset (&ent, 0, sizeof(ent)); - if (b->model == cl_mod_heatbeam) - { - model_length = 32.0; - } - else if (b->model == cl_mod_lightning) - { - model_length = 35.0; - d-= 20.0; // correction so it doesn't end in middle of tesla - } - else - { - model_length = 30.0; - } - steps = ceil(d/model_length); - len = (d-model_length)/(steps-1); - - // PMM - special case for lightning model .. if the real length is shorter than the model, - // flip it around & draw it from the end to the start. This prevents the model from going - // through the tesla mine (instead it goes through the target) - if ((b->model == cl_mod_lightning) && (d <= model_length)) - { -// Com_Printf ("special case\n"); - VectorCopy (b->end, ent.origin); - // offset to push beam outside of tesla model (negative because dist is from end to start - // for this beam) -// for (j=0 ; j<3 ; j++) -// ent.origin[j] -= dist[j]*10.0; - ent.model = b->model; - ent.flags = RF_FULLBRIGHT; - ent.angles[0] = pitch; - ent.angles[1] = yaw; - ent.angles[2] = rand()%360; - V_AddEntity (&ent); - return; - } - while (d > 0) - { - VectorCopy (org, ent.origin); - ent.model = b->model; - if(cl_mod_heatbeam && (b->model == cl_mod_heatbeam)) - { -// ent.flags = RF_FULLBRIGHT|RF_TRANSLUCENT; -// ent.alpha = 0.3; - ent.flags = RF_FULLBRIGHT; - ent.angles[0] = -pitch; - ent.angles[1] = yaw + 180.0; - ent.angles[2] = (cl.time) % 360; -// ent.angles[2] = rand()%360; - ent.frame = framenum; - } - else if (b->model == cl_mod_lightning) - { - ent.flags = RF_FULLBRIGHT; - ent.angles[0] = -pitch; - ent.angles[1] = yaw + 180.0; - ent.angles[2] = rand()%360; - } - else - { - ent.angles[0] = pitch; - ent.angles[1] = yaw; - ent.angles[2] = rand()%360; - } - -// Com_Printf("B: %d -> %d\n", b->entity, b->dest_entity); - V_AddEntity (&ent); - - for (j=0 ; j<3 ; j++) - org[j] += dist[j]*len; - d -= model_length; - } - } +void CL_AddTEnts (void) { + CL_AddBeams (); + // PMM - draw plasma beams + CL_AddPlayerBeams (); + CL_AddExplosions (); + // PMM - set up sustain + CL_ProcessSustain(); + CL_AddLasers(); } /* ================= -CL_AddExplosions +CL_ClearTEnts ================= */ -static void CL_AddExplosions (void) -{ - entity_t *ent; - int i; - explosion_t *ex; - float frac; - int f; +void CL_ClearTEnts (void) { + clear_beams(); + clear_explosions(); + clear_lasers(); - memset (&ent, 0, sizeof(ent)); - - for (i=0, ex=cl_explosions ; i< MAX_EXPLOSIONS ; i++, ex++) - { - if (ex->type == ex_free) - continue; - frac = (cl.time - ex->start)/100.0; - f = floor(frac); - - ent = &ex->ent; - - switch (ex->type) { - case ex_mflash: - if (f >= ex->frames-1) - ex->type = ex_free; - break; - case ex_misc: - case ex_light: - if (f >= ex->frames-1) { - ex->type = ex_free; - break; - } - ent->alpha = 1.0 - frac/(ex->frames-1); - break; - case ex_flash: - if (f >= 1) { - ex->type = ex_free; - break; - } - ent->alpha = 1.0; - break; - case ex_poly: - if (f >= ex->frames-1) { - ex->type = ex_free; - break; - } - - ent->alpha = (16.0 - (float)f)/16.0; - - if (f < 10) { - ent->skinnum = (f>>1); - if (ent->skinnum < 0) - ent->skinnum = 0; - } else { - ent->flags |= RF_TRANSLUCENT; - if (f < 13) - ent->skinnum = 5; - else - ent->skinnum = 6; - } - break; - case ex_poly2: - if (f >= ex->frames-1) { - ex->type = ex_free; - break; - } - - ent->alpha = (5.0 - (float)f)/5.0; - ent->skinnum = 0; - ent->flags |= RF_TRANSLUCENT; - break; - default: - break; - } - - if (ex->type == ex_free) - continue; - if (ex->light) { - V_AddLight (ent->origin, ex->light*ent->alpha, - ex->lightcolor[0], ex->lightcolor[1], ex->lightcolor[2]); - } - - if( ex->type != ex_light ) { - VectorCopy (ent->origin, ent->oldorigin); - - if (f < 0) - f = 0; - ent->frame = ex->baseframe + f + 1; - ent->oldframe = ex->baseframe + f; - ent->backlerp = 1.0 - cl.lerpfrac; - - V_AddEntity (ent); - } - } +//ROGUE + clear_sustains(); +//ROGUE } -// PMM - CL_Sustains -static void CL_ProcessSustain (void) -{ - cl_sustain_t *s; - int i; - for (i=0, s=cl_sustains; i< MAX_SUSTAINS; i++, s++) - { - if (s->id) - { - if ((s->endtime >= cl.time) && (cl.time >= s->nextthink)) - { -// Com_Printf ("think %d %d %d\n", cl.time, s->nextthink, s->thinkinterval); - s->think (s); - } - else if (s->endtime < cl.time) - s->id = 0; - } - } -} - -/* -================= -CL_AddTEnts -================= -*/ -void CL_AddTEnts (void) -{ - CL_AddBeams (); - // PMM - draw plasma beams - CL_AddPlayerBeams (); - CL_AddExplosions (); - // PMM - set up sustain - CL_ProcessSustain(); +void CL_InitTEnts( void ) { + cl_railtrail_type = Cvar_Get( "cl_railtrail_type", "0", 0 ); + cl_railtrail_time = Cvar_Get( "cl_railtrail_time", "1.0", 0 ); + cl_railcore_color = Cvar_Get( "cl_railcore_color", "red", 0 ); + cl_railcore_color->changed = cl_railcore_color_changed; + cl_railcore_color->generator = Com_Color_g; + cl_railcore_color_changed( cl_railcore_color ); + cl_railcore_width = Cvar_Get( "cl_railcore_width", "2", 0 ); + cl_railspiral_color = Cvar_Get( "cl_railspiral_color", "blue", 0 ); + cl_railspiral_color->changed = cl_railspiral_color_changed; + cl_railspiral_color->generator = Com_Color_g; + cl_railspiral_color_changed( cl_railspiral_color ); + cl_railspiral_radius = Cvar_Get( "cl_railspiral_radius", "3", 0 ); } |