diff --git a/source/cgame/cg_event.c b/source/cgame/cg_event.c index 177cc61..692d08d 100644 --- a/source/cgame/cg_event.c +++ b/source/cgame/cg_event.c @@ -599,11 +599,11 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) { vec3_t end = {0, 0, 1}; // Blub, blub, blub... - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, cent->lerpOrigin, end, 700, 20, 0 ); - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, cent->lerpOrigin, end, 700, 20, 0 ); - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, cent->lerpOrigin, end, 700, 20, 0 ); - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, cent->lerpOrigin, end, 700, 20, 0 ); - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, cent->lerpOrigin, end, 700, 20, 0 ); + CG_ParticleBubble( cent, cgs.media.waterBubbleShader, cent->lerpOrigin, end, 700, 20 ); + CG_ParticleBubble( cent, cgs.media.waterBubbleShader, cent->lerpOrigin, end, 700, 20 ); + CG_ParticleBubble( cent, cgs.media.waterBubbleShader, cent->lerpOrigin, end, 700, 20 ); + CG_ParticleBubble( cent, cgs.media.waterBubbleShader, cent->lerpOrigin, end, 700, 20 ); + CG_ParticleBubble( cent, cgs.media.waterBubbleShader, cent->lerpOrigin, end, 700, 20 ); } break; case EV_WATER_CLEAR: diff --git a/source/cgame/cg_local.h b/source/cgame/cg_local.h index a5accff..bf95501 100644 --- a/source/cgame/cg_local.h +++ b/source/cgame/cg_local.h @@ -1493,7 +1493,7 @@ void CG_ParticleDust (centity_t *cent, vec3_t origin, vec3_t dir); void CG_ParticleMisc (qhandle_t pshader, vec3_t origin, int size, int duration, float alpha); void CG_ParticleExplosion (char *animStr, vec3_t origin, vec3_t vel, int duration, int sizeStart, int sizeEnd); // BFP - Bubble particle -void CG_ParticleBubble (centity_t *cent, qhandle_t pshader, vec3_t origin, vec3_t origin2, int turbtime, float range, int snum); +void CG_ParticleBubble (centity_t *cent, qhandle_t pshader, vec3_t origin, vec3_t origin2, int turbtime, float range); // BFP - Dash smoke particle for ki boost when moving in the ground void CG_ParticleDashSmoke (centity_t *cent, qhandle_t pshader, vec3_t origin); // BFP - Antigrav rock particles for charging diff --git a/source/cgame/cg_particles.c b/source/cgame/cg_particles.c index 20e2b49..2ca1f92 100644 --- a/source/cgame/cg_particles.c +++ b/source/cgame/cg_particles.c @@ -125,7 +125,7 @@ static int numShaderAnims; // done. #define PARTICLE_GRAVITY 40 -#define MAX_PARTICLES 1024 * 8 +#define MAX_PARTICLES 1024 * 3 static cparticle_t *active_particles, *free_particles; static cparticle_t particles[MAX_PARTICLES]; @@ -934,7 +934,7 @@ void CG_AddParticles (void) active_particles = active; } -void CG_ParticleBubble (centity_t *cent, qhandle_t pshader, vec3_t origin, vec3_t origin2, int turbtime, float range, int snum) +void CG_ParticleBubble (centity_t *cent, qhandle_t pshader, vec3_t origin, vec3_t origin2, int turbtime, float range) { cparticle_t *p; @@ -970,20 +970,24 @@ void CG_ParticleBubble (centity_t *cent, qhandle_t pshader, vec3_t origin, vec3_ p->endtime = timenonscaled + turbtime; p->height = p->width = (rand() % 1) + 2; - p->org[0] += (rand() % (int)range) + (crandom() * range); - p->org[1] += (rand() % (int)range) + (crandom() * range); + p->org[0] += (crandom() * range); + p->org[1] += (crandom() * range); p->org[2] += (rand() % (int)20); VectorSet( p->vel, - (rand() % 401) - 200, - (rand() % 401) - 200, - 20 ); + (rand() % 521) - 250, + (rand() % 521) - 250, + 30 * (rand() % (int)range) ); // dispersion VectorSet( p->accel, crandom() * 10, crandom() * 10, - 300 ); + 20 * (rand() % (int)range) ); + + // avoid if both upwards are zero or less + if ( p->vel[2] <= 0 ) p->vel[2] = 10 + (rand() % (int)range); + if ( p->accel[2] <= 0 ) p->accel[2] = 10 + (rand() % (int)range); } else { @@ -1014,6 +1018,7 @@ void CG_BubblesWaterHandling( cparticle_t *p, vec3_t org ) { trace_t trace; vec3_t start, end; int contents; + int i; VectorCopy( org, end ); end[2] -= 15; @@ -1021,45 +1026,58 @@ void CG_BubblesWaterHandling( cparticle_t *p, vec3_t org ) { VectorCopy( org, start ); start[2] += 10; - // BFP - Make move less - if ( p->vel[0] > -0.9 && p->vel[0] < 0.9 ) p->vel[0] = 0; - if ( p->vel[1] > -0.9 && p->vel[1] < 0.9 ) p->vel[1] = 0; - if ( p->vel[0] != 0 ) p->vel[0] *= 0.99; - if ( p->vel[1] != 0 ) p->vel[1] *= 0.99; + // decelerate + for (i = 0; i < 2; ++i) { + if (fabs(p->vel[i]) != 0) { + p->vel[i] *= 0.99; + } else { + p->vel[0] = 0; + p->vel[1] = 0; + p->accel[0] = 0; + p->accel[1] = 0; + } + } - // Decelerate - if ( p->accel[2] > 0 ) p->accel[2]--; + for (i = 0; i < 2; ++i) { + if (fabs(p->accel[i]) != 0) { + p->accel[i] *= 0.99; + } else { + p->accel[i] = 0; + } + } + + // stop acceleration + if ( fabs(p->accel[0]) <= 1 ) p->accel[0] = 0; + if ( fabs(p->accel[1]) <= 1 ) p->accel[1] = 0; + if ( fabs(p->accel[2]) <= 1 ) p->accel[2] = 0; // trace down to find the surface trap_CM_BoxTrace( &trace, start, end, vec3_origin, vec3_origin, 0, CONTENTS_WATER ); // if the particle is touching something solid, it will skip instead stopping - contents = trap_CM_PointContents( start, 0 ); + contents = trap_CM_PointContents( trace.endpos, 0 ); if ( contents & (CONTENTS_WATER | CONTENTS_SOLID) ) { return; } - contents = trap_CM_PointContents( trace.endpos, 0 ); if ( !( contents & CONTENTS_WATER ) ) { p->time = timenonscaled; VectorCopy (trace.endpos, p->org); p->org[2] = trace.endpos[2] - p->snum; + // stop going up and decrease dispersion speed + p->vel[2] = 0; + VectorClear( p->accel ); + // trace again if the bubble went outside, then set it near to the surface contents = trap_CM_PointContents( p->org, 0 ); if ( !( contents & CONTENTS_WATER ) ) { - p->org[2] = trace.endpos[2]; + VectorCopy (trace.endpos, p->org); + } + if ( p->type == P_BUBBLE ) { + if ( p->vel[0] != 0 ) p->vel[0] *= 0.9; + if ( p->vel[1] != 0 ) p->vel[1] *= 0.9; } - - // BFP - Stop going up and decrease dispersion speed - p->vel[2] = 0; - VectorClear( p->accel ); - - // BFP - Make move less - if ( p->vel[0] >= -1 && p->vel[0] <= 0.9 ) p->vel[0] = 0; - else p->vel[0] *= 0.9; - if ( p->vel[1] >= -1 && p->vel[1] <= 0.9 ) p->vel[1] = 0; - else p->vel[1] *= 0.9; } } @@ -1196,6 +1214,7 @@ void CG_AntigravRockHandling (centity_t *cent) if (p->type == P_ANTIGRAV_ROCK) { if ( cent->currentState.clientNum == cg.snap->ps.clientNum + && !( cent->currentState.eFlags & EF_DEAD ) && ( cent->currentState.legsAnim & ~ANIM_TOGGLEBIT ) != LEGS_CHARGE ) { // BFP - Make each particle fall when they aren't on ki charging status @@ -1209,6 +1228,7 @@ void CG_AntigravRockHandling (centity_t *cent) // to correct the client side visuals in this case if ( cent->currentState.clientNum != cg.snap->ps.clientNum && ( cent->currentState.eFlags & EF_AURA ) + && !( cent->currentState.eFlags & EF_DEAD ) && ( cent->currentState.legsAnim & ~ANIM_TOGGLEBIT ) == LEGS_CHARGE && !p->snum ) { // use p->snum to handle the client side visual of the other player p->link = qfalse; // keep this way, otherwise the rocks fall diff --git a/source/cgame/cg_players.c b/source/cgame/cg_players.c index 30b99de..90c4911 100644 --- a/source/cgame/cg_players.c +++ b/source/cgame/cg_players.c @@ -1889,9 +1889,9 @@ static qboolean CG_PlayerShadow( centity_t *cent, float *shadowPlane ) { waterTrace.endpos[2] -= 20; // BFP - Put a bit down to make the bubbles move if ( waterTrace.fraction >= 0.10f && waterTrace.fraction <= 0.70f ) { - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, waterTrace.endpos, end, 700, 10, 0 ); - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, waterTrace.endpos, end, 700, 10, 0 ); - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, waterTrace.endpos, end, 700, 10, 0 ); + CG_ParticleBubble( cent, cgs.media.waterBubbleShader, waterTrace.endpos, end, 700, 10 ); + CG_ParticleBubble( cent, cgs.media.waterBubbleShader, waterTrace.endpos, end, 700, 10 ); + CG_ParticleBubble( cent, cgs.media.waterBubbleShader, waterTrace.endpos, end, 700, 10 ); } } @@ -2398,19 +2398,19 @@ void CG_Player( centity_t *cent ) { if ( ( cent->currentState.legsAnim & ~ANIM_TOGGLEBIT ) == LEGS_FLYA || ( cent->currentState.legsAnim & ~ANIM_TOGGLEBIT ) == LEGS_FLYB ) { - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 700, 10, 0 ); - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 700, 10, 0 ); - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 700, 10, 0 ); + CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 700, 10 ); + CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 700, 10 ); + CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 700, 10 ); } else if ( ( cent->currentState.legsAnim & ~ANIM_TOGGLEBIT ) == LEGS_CHARGE ) { bubbleOrigin[2] += -7; // put the origin a little below - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 0, 20, 0 ); - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 0, 20, 0 ); - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 0, 20, 0 ); - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 0, 20, 0 ); - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 0, 20, 0 ); - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 0, 20, 0 ); - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 0, 20, 0 ); + CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 0, 20 ); + CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 0, 20 ); + CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 0, 20 ); + CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 0, 20 ); + CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 0, 20 ); + CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 0, 20 ); + CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 0, 20 ); } } @@ -2441,7 +2441,7 @@ void CG_Player( centity_t *cent ) { // trap_R_AddLightToScene( cent->lerpOrigin, 200 + (rand()&255), 1.0, 1.0, 0 ); // Apply light blinking - if ( ci->team == TEAM_BLUE) { + if ( ci->team == TEAM_BLUE ) { aura.customShader = aura2.customShader = cgs.media.auraBlueShader; AURA_LIGHT( 0.2f, 0.2f, 1.0 ) } else { diff --git a/source/cgame/cg_weapons.c b/source/cgame/cg_weapons.c index 0f2e243..0a56d1a 100644 --- a/source/cgame/cg_weapons.c +++ b/source/cgame/cg_weapons.c @@ -329,9 +329,9 @@ static void CG_RocketTrail( centity_t *ent, const weaponInfo_t *wi ) { if ( ( contents & lastContents & CONTENTS_WATER ) && cg.frametime > 0.0f ) { // BFP - If paused, don't spawn bubble particles (cg_paused.integer < 1 is another solution, but not good enough for server responses) // BFP - Apply particle bubble effect in that case - CG_ParticleBubble( ent, cgs.media.waterBubbleShader, origin, lastPos, 1200, 20, 0 ); - CG_ParticleBubble( ent, cgs.media.waterBubbleShader, origin, lastPos, 1200, 20, 0 ); - CG_ParticleBubble( ent, cgs.media.waterBubbleShader, origin, lastPos, 1200, 20, 0 ); + CG_ParticleBubble( ent, cgs.media.waterBubbleShader, origin, lastPos, 1200, 10 ); + CG_ParticleBubble( ent, cgs.media.waterBubbleShader, origin, lastPos, 1200, 10 ); + CG_ParticleBubble( ent, cgs.media.waterBubbleShader, origin, lastPos, 1200, 10 ); // CG_BubbleTrail( lastPos, origin, 8 ); } return;