summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cgame/cg_local.h10
-rw-r--r--src/cgame/cg_particles.c80
2 files changed, 85 insertions, 5 deletions
diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h
index 53841e45..54477662 100644
--- a/src/cgame/cg_local.h
+++ b/src/cgame/cg_local.h
@@ -203,7 +203,9 @@ typedef enum
PMT_STATIC_TRANSFORM,
PMT_TAG,
PMT_CENT_ANGLES,
- PMT_NORMAL
+ PMT_NORMAL,
+ PMT_LAST_NORMAL,
+ PMT_OPPORTUNISTIC_NORMAL
} pMoveType_t;
typedef enum
@@ -357,6 +359,9 @@ typedef struct particleSystem_s
//for PMT_NORMAL
qboolean normalValid;
vec3_t normal;
+ //for PMT_LAST_NORMAL and PMT_OPPORTUNISTIC_NORMAL
+ qboolean lastNormalIsCurrent;
+ vec3_t lastNormal;
int charge;
} particleSystem_t;
@@ -384,6 +389,8 @@ typedef struct particle_s
baseParticle_t *class;
particleEjector_t *parent;
+ particleSystem_t *childParticleSystem;
+
int birthTime;
int lifeTime;
@@ -1814,6 +1821,7 @@ qboolean CG_IsParticleSystemInfinite( particleSystem_t *ps );
qboolean CG_IsParticleSystemValid( particleSystem_t **ps );
void CG_SetParticleSystemNormal( particleSystem_t *ps, vec3_t normal );
+void CG_SetParticleSystemLastNormal( particleSystem_t *ps, const float *normal );
void CG_AddParticles( void );
diff --git a/src/cgame/cg_particles.c b/src/cgame/cg_particles.c
index 0c60ed4c..f3a63efd 100644
--- a/src/cgame/cg_particles.c
+++ b/src/cgame/cg_particles.c
@@ -261,6 +261,21 @@ static particle_t *CG_SpawnNewParticle( baseParticle_t *bp, particleEjector_t *p
VectorNormalize( p->velocity );
VectorMA( p->origin, bp->normalDisplacement, p->velocity, p->origin );
break;
+
+ case PMT_LAST_NORMAL:
+ VectorCopy( ps->lastNormal, p->velocity );
+ VectorNormalize( p->velocity );
+ VectorMA( p->origin, bp->normalDisplacement, p->velocity, p->origin );
+ break;
+
+ case PMT_OPPORTUNISTIC_NORMAL:
+ if( ps->lastNormalIsCurrent )
+ {
+ VectorCopy( ps->lastNormal, p->velocity );
+ VectorNormalize( p->velocity );
+ VectorMA( p->origin, bp->normalDisplacement, p->velocity, p->origin );
+ }
+ break;
}
VectorNormalize( p->velocity );
@@ -283,12 +298,18 @@ static particle_t *CG_SpawnNewParticle( baseParticle_t *bp, particleEjector_t *p
//this particle has a child particle system attached
if( bp->childSystemName[ 0 ] != '\0' )
{
- particleSystem_t *ps = CG_SpawnNewParticleSystem( bp->childSystemHandle );
+ particleSystem_t *chps = CG_SpawnNewParticleSystem( bp->childSystemHandle );
- if( CG_IsParticleSystemValid( &ps ) )
+ if( CG_IsParticleSystemValid( &chps ) )
{
- CG_SetAttachmentParticle( &ps->attachment, p );
- CG_AttachToParticle( &ps->attachment );
+ CG_SetAttachmentParticle( &chps->attachment, p );
+ CG_AttachToParticle( &chps->attachment );
+ p->childParticleSystem = chps;
+
+ if( ps->lastNormalIsCurrent )
+ CG_SetParticleSystemLastNormal( chps, ps->lastNormal );
+ else
+ VectorCopy( ps->lastNormal, chps->lastNormal );
}
}
@@ -467,6 +488,9 @@ particleSystem_t *CG_SpawnNewParticleSystem( qhandle_t psHandle )
ps->valid = qtrue;
ps->lazyRemove = qfalse;
+ // use "up" as an arbitrary (non-null) "last" normal
+ VectorSet( ps->lastNormal, 0, 0, 1 );
+
for( j = 0; j < bps->numEjectors; j++ )
CG_SpawnNewParticleEjector( bps->ejectors[ j ], ps );
@@ -675,6 +699,10 @@ static qboolean CG_ParseType( pMoveType_t *pmt, char **text_p )
*pmt = PMT_CENT_ANGLES;
else if( !Q_stricmp( token, "normal" ) )
*pmt = PMT_NORMAL;
+ else if( !Q_stricmp( token, "last_normal" ) )
+ *pmt = PMT_LAST_NORMAL;
+ else if( !Q_stricmp( token, "opportunistic_normal" ) )
+ *pmt = PMT_OPPORTUNISTIC_NORMAL;
return qtrue;
}
@@ -1676,6 +1704,31 @@ void CG_SetParticleSystemNormal( particleSystem_t *ps, vec3_t normal )
ps->normalValid = qtrue;
VectorCopy( normal, ps->normal );
VectorNormalize( ps->normal );
+
+ CG_SetParticleSystemLastNormal( ps, normal );
+}
+
+/*
+===============
+CG_SetParticleSystemLastNormal
+===============
+*/
+void CG_SetParticleSystemLastNormal( particleSystem_t *ps, const float *normal )
+{
+ if( ps == NULL || !ps->valid )
+ {
+ CG_Printf( S_COLOR_YELLOW "WARNING: tried to modify a NULL particle system\n" );
+ return;
+ }
+
+ if( normal )
+ {
+ ps->lastNormalIsCurrent = qtrue;
+ VectorCopy( normal, ps->lastNormal );
+ VectorNormalize( ps->lastNormal );
+ }
+ else
+ ps->lastNormalIsCurrent = qfalse;
}
@@ -1922,6 +1975,17 @@ static void CG_EvaluateParticlePhysics( particle_t *p )
VectorCopy( ps->normal, acceleration );
break;
+
+ case PMT_LAST_NORMAL:
+ VectorCopy( ps->lastNormal, acceleration );
+ break;
+
+ case PMT_OPPORTUNISTIC_NORMAL:
+ if( ps->lastNormalIsCurrent )
+ VectorCopy( ps->lastNormal, acceleration );
+ else
+ VectorClear( acceleration );
+ break;
}
#define MAX_ACC_RADIUS 1000.0f
@@ -1989,6 +2053,8 @@ static void CG_EvaluateParticlePhysics( particle_t *p )
if( trace.fraction == 1.0f || bounce == 0.0f )
{
VectorCopy( newOrigin, p->origin );
+ if( CG_IsParticleSystemValid( &p->childParticleSystem ) )
+ CG_SetParticleSystemLastNormal( p->childParticleSystem, NULL );
return;
}
@@ -2030,6 +2096,12 @@ static void CG_EvaluateParticlePhysics( particle_t *p )
}
VectorCopy( trace.endpos, p->origin );
+
+ if( !trace.allsolid )
+ {
+ if( CG_IsParticleSystemValid( &p->childParticleSystem ) )
+ CG_SetParticleSystemLastNormal( p->childParticleSystem, trace.plane.normal );
+ }
}