diff --git a/source/cgame/cg_event.c b/source/cgame/cg_event.c index bcad970..35826aa 100644 --- a/source/cgame/cg_event.c +++ b/source/cgame/cg_event.c @@ -541,6 +541,8 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) { case EV_JUMP_PAD: DEBUGNAME("EV_JUMP_PAD"); // CG_Printf( "EV_JUMP_PAD w/effect #%i\n", es->eventParm ); +// BFP - No smoke puff effect when using a jump pad +#if 0 { localEntity_t *smoke; vec3_t up = {0, 0, 1}; @@ -554,6 +556,7 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) { LEF_PUFF_DONT_SCALE, cgs.media.smokePuffShader ); } +#endif // boing sound at origin, jump sound on player trap_S_StartSound ( cent->lerpOrigin, -1, CHAN_VOICE, cgs.media.jumpPadSound ); @@ -563,7 +566,7 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) { case EV_JUMP: DEBUGNAME("EV_JUMP"); // BFP - Use the second jump sound when using ki boost only when it isn't flying - if ( ( es->eFlags & EF_AURA ) && !( cg.predictedPlayerState.pm_flags & PMF_FLYING ) ) { + if ( ( es->eFlags & EF_AURA ) && !( cent->currentState.powerups & ( 1 << PW_FLIGHT ) ) ) { trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "sound/bfp/jump2.wav" ) ); // BFP - Ki boost jump sound } else { trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "sound/bfp/jump1.wav" ) ); // BFP - Normal jump sound @@ -674,6 +677,43 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) { CG_FireWeapon( cent ); break; + case EV_MELEE_READY: + // DEBUGNAME("EV_MELEE_READY"); + break; + + // BFP - TODO: Implement EV_MELEE (when punching someone using Melee) + case EV_MELEE: + DEBUGNAME("EV_MELEE"); + break; + + // BFP - TODO: Implement EV_TIER_0-4 (Tiers) + case EV_TIER_0: + DEBUGNAME("EV_TIER_0"); + break; + + case EV_TIER_1: + DEBUGNAME("EV_TIER_1"); + break; + + case EV_TIER_2: + DEBUGNAME("EV_TIER_2"); + break; + + case EV_TIER_3: + DEBUGNAME("EV_TIER_3"); + break; + + case EV_TIER_4: + DEBUGNAME("EV_TIER_4"); + break; + // BFP - TODO: Implement EV_TIER_0-4 (Tiers) ^ + + // BFP - A normal jump sound is played when enables the flight + case EV_ENABLE_FLIGHT: + // DEBUGNAME("EV_ENABLE_FLIGHT"); + trap_S_StartSound (NULL, es->number, CHAN_BODY, CG_CustomSound( es->number, "sound/bfp/jump1.wav" ) ); + break; + case EV_USE_ITEM0: DEBUGNAME("EV_USE_ITEM0"); CG_UseItem( cent ); @@ -796,6 +836,11 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) { CG_MissileHitWall( es->weapon, 0, position, dir, IMPACTSOUND_METAL ); break; + // BFP - TODO: Implement EV_MISSILE_DETONATE (it has been used on ki grenade bounces and ki disc, that happens when these explode after some time) + case EV_MISSILE_DETONATE: + DEBUGNAME("EV_MISSILE_DETONATE"); + break; + case EV_RAILTRAIL: DEBUGNAME("EV_RAILTRAIL"); cent->currentState.weapon = WP_RAILGUN; @@ -990,9 +1035,10 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) { // don't play gib sound when using the kamikaze because it interferes // with the kamikaze sound, downside is that the gib sound will also // not be played when someone is gibbed while just carrying the kamikaze - if ( !(es->eFlags & EF_KAMIKAZE) ) { + // BFP - No EF_KAMIKAZE flag + // if ( !(es->eFlags & EF_KAMIKAZE) ) { trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.gibSound ); - } + // } CG_GibPlayer( cent->lerpOrigin ); break; diff --git a/source/cgame/cg_local.h b/source/cgame/cg_local.h index 92ebf7e..ba60bbd 100644 --- a/source/cgame/cg_local.h +++ b/source/cgame/cg_local.h @@ -1486,22 +1486,27 @@ qboolean trap_GetEntityToken( char *buffer, int bufferSize ); void CG_ClearParticles (void); void CG_AddParticles (void); -void CG_ParticleSnow (qhandle_t pshader, vec3_t origin, vec3_t origin2, int turb, float range, int snum); void CG_ParticleSmoke (qhandle_t pshader, centity_t *cent); -void CG_AddParticleShrapnel (localEntity_t *le); -void CG_ParticleSnowFlurry (qhandle_t pshader, centity_t *cent); void CG_ParticleBulletDebris (vec3_t org, vec3_t vel, int duration); void CG_ParticleSparks (vec3_t org, vec3_t vel, int duration, float x, float y, float speed); 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 turb, float range, int snum); +void CG_ParticleBubble (centity_t *cent, qhandle_t pshader, vec3_t origin, vec3_t origin2, int turb, float range, int snum); // BFP - Dash smoke particle for ki boost when moving in the ground -void CG_ParticleDashSmoke (centity_t *cent, qhandle_t pshader, vec3_t origin); +void CG_ParticleDashSmoke (centity_t *cent, qhandle_t pshader, vec3_t origin); // BFP - Antigrav rock particles for charging -void CG_ParticleAntigravRock (qhandle_t pshader, centity_t *cent, vec3_t origin); +void CG_ParticleAntigravRock (qhandle_t pshader, centity_t *cent, vec3_t origin); +void CG_AntigravRockHandling (centity_t *cent); + +// BFP - Unused particle stuff, saved for later :P +#if 0 +void CG_ParticleSnow (qhandle_t pshader, vec3_t origin, vec3_t origin2, int turb, float range, int snum); +void CG_ParticleSnowFlurry (qhandle_t pshader, centity_t *cent); +int CG_NewParticleArea ( int num ); // BFP - Unused function for particles, looks like here is to determine in the areas +#endif + extern qboolean initparticles; -int CG_NewParticleArea ( int num ); diff --git a/source/cgame/cg_main.c b/source/cgame/cg_main.c index e1f50c2..7d656b1 100644 --- a/source/cgame/cg_main.c +++ b/source/cgame/cg_main.c @@ -684,7 +684,9 @@ static void CG_RegisterGraphics( void ) { } CG_ClearParticles (); -/* + +// BFP - Unused function for particles, looks like here is to determine in the areas +#if 0 for (i=1; itype == P_WEATHER || p->type == P_WEATHER_TURBULENT || p->type == P_WEATHER_FLURRY) {// create a front facing polygon @@ -212,7 +216,6 @@ void CG_AddParticleToScene (cparticle_t *p, vec3_t org, float alpha) p->org[2] += (p->start - p->end); } - if (p->type == P_WEATHER_TURBULENT) { p->vel[0] = crandom() * 16; @@ -264,7 +267,9 @@ void CG_AddParticleToScene (cparticle_t *p, vec3_t org, float alpha) TRIverts[2].modulate[2] = 255; TRIverts[2].modulate[3] = 255 * p->alpha; } - else if (p->type == P_SPRITE) + // else if ... +#endif + if (p->type == P_SPRITE) { vec3_t rr, ru; vec3_t rotate_ang; @@ -342,9 +347,12 @@ void CG_AddParticleToScene (cparticle_t *p, vec3_t org, float alpha) || p->type == P_ANTIGRAV_ROCK) // BFP - Added antigrav rock type {// create a front rotating facing polygon +// BFP - No smoke distance +#if 0 if ( p->type == P_SMOKE_IMPACT && Distance( cg.snap->ps.origin, org ) > 1024) { return; } +#endif if (p->color == BLOODRED) VectorSet (color, 0.22f, 0.0f, 0.0f); @@ -412,13 +420,30 @@ void CG_AddParticleToScene (cparticle_t *p, vec3_t org, float alpha) // BFP - Bubble types here if (p->type == P_BUBBLE || p->type == P_BUBBLE_TURBULENT) { + // BFP - Apply less end time to remove particles if the player is still charging + if (p->type == P_BUBBLE) { + if ( ( cg.snap->ps.eFlags & EF_AURA ) + && ( cg.snap->ps.legsAnim & ~ANIM_TOGGLEBIT ) == LEGS_CHARGE + && !p->link ) + { + p->endtime = timenonscaled + 400; + p->link = qtrue; + } + if ( ( cg.snap->ps.legsAnim & ~ANIM_TOGGLEBIT ) != LEGS_CHARGE + && p->link ) + { + p->endtime = timenonscaled + 2000 + (crandom() * 150); + p->link = qfalse; + } + } + if (org[2] > p->end) { p->time = timenonscaled; VectorCopy (org, p->org); // Ridah, fixes rare snow flakes that flicker on the ground // BFP - Stop shivering, before: ( p->start + crandom () * 4 ) - p->org[2] = ( p->start ); + p->org[2] = ( p->start - p->end ); // BFP - Make move less if (p->type == P_BUBBLE_TURBULENT) { @@ -434,31 +459,32 @@ void CG_AddParticleToScene (cparticle_t *p, vec3_t org, float alpha) // BFP - Antigrav rock type if (p->type == P_ANTIGRAV_ROCK) { - // BFP - To detect if there is something solid - trace_t trace; - CG_Trace( &trace, p->org, vec3_origin, vec3_origin, org, -1, MASK_PLAYERSOLID ); - - // BFP - Make each particle fall when they aren't on ki charging status - if ( !( cg.snap->ps.pm_flags & PMF_KI_CHARGE ) && !p->link ) { - p->endtime = timenonscaled + 1650; - p->link = qtrue; - } - // BFP - When the particle, checked to be fallen, won't be reactivated when entering ki charging status again - if (p->link) { + if (p->link) + { + // BFP - To detect if there is something solid + trace_t trace; + // contents should be MASK_DEADSOLID, so the particles don't touch any entity like the player + CG_Trace( &trace, p->org, vec3_origin, vec3_origin, org, -1, MASK_DEADSOLID ); + p->time = timenonscaled; + p->snum = 1; // handle the p->snum when already entered in this phase for correction of client side visuals + p->vel[0] = 0; + p->vel[1] = 0; + p->accel[0] = 0; + p->accel[1] = 0; // not hit anything or not a collider if ( trace.fraction == 1.0f && p->roll > 0 ) { VectorCopy (org, p->org); - p->vel[2] -= 30; + p->vel[2] -= 50; p->accel[2] -= 200; } else // bouncing { // BFP - TODO: Temporary solution... Make bouncing more interactive when there's a mover moving - if ( trace.fraction <= 0 // if the particle is touching a mover and moves down, so keep bouncing - && cg.snap->ps.groundEntityNum != ENTITYNUM_NONE ) { + // if the particle is touching a mover and moves down, so keep bouncing + if ( trace.fraction <= 0 ) { p->roll = 10; } else { p->vel[2] = p->accel[2] = (p->roll > 0) ? 50 * p->roll : 0; @@ -466,6 +492,13 @@ void CG_AddParticleToScene (cparticle_t *p, vec3_t org, float alpha) } } } + + // BFP - When reaching into this top, remove the particle! + if (org[2] > p->end) + { + p->next = NULL; + p->type = p->color = p->alpha = p->snum = 0; + } } if (p->rotate) @@ -601,6 +634,7 @@ void CG_AddParticleToScene (cparticle_t *p, vec3_t org, float alpha) verts[3].modulate[3] = 255 * alpha; } +#if 0 /* // BFP - Unused particle type conditionals */ else if (p->type == P_FLAT_SCALEUP) { float width, height; @@ -711,6 +745,7 @@ void CG_AddParticleToScene (cparticle_t *p, vec3_t org, float alpha) verts[3].modulate[3] = 255; } +#endif // Ridah else if (p->type == P_ANIM) { vec3_t rr, ru; @@ -804,9 +839,11 @@ void CG_AddParticleToScene (cparticle_t *p, vec3_t org, float alpha) return; } +#if 0 /* // BFP - Unused particle type conditionals */ if (p->type == P_WEATHER || p->type == P_WEATHER_TURBULENT || p->type == P_WEATHER_FLURRY) trap_R_AddPolyToScene( p->pshader, 3, TRIverts ); else +#endif trap_R_AddPolyToScene( p->pshader, 4, verts ); } @@ -866,7 +903,9 @@ void CG_AddParticles (void) } if (p->type == P_SMOKE || p->type == P_ANIM || p->type == P_BLEED || p->type == P_SMOKE_IMPACT +#if 0 /* // BFP - Unused particle type conditionals */ || p->type == P_WEATHER_FLURRY || p->type == P_FLAT_SCALEUP_FADE +#endif || p->type == P_BUBBLE || p->type == P_BUBBLE_TURBULENT // BFP - Add P_BUBBLE types to remove particles || p->type == P_ANTIGRAV_ROCK) // BFP - Add P_ANTIGRAV_ROCK to remove particles { @@ -874,7 +913,7 @@ void CG_AddParticles (void) { p->next = free_particles; free_particles = p; - p->type = p->color = p->alpha = 0; + p->type = p->color = p->alpha = p->snum = 0; continue; } } @@ -916,131 +955,6 @@ void CG_AddParticles (void) active_particles = active; } -void CG_ParticleSnowFlurry (qhandle_t pshader, centity_t *cent) -{ - cparticle_t *p; - qboolean turb = qtrue; - - if (!pshader) - CG_Printf ("CG_ParticleSnowFlurry pshader == ZERO!\n"); - - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - p->time = timenonscaled; - p->color = 0; - p->alpha = 0.90f; - p->alphavel = 0; - - p->start = cent->currentState.origin2[0]; - p->end = cent->currentState.origin2[1]; - - p->endtime = timenonscaled + cent->currentState.time; - p->startfade = timenonscaled + cent->currentState.time2; - - p->pshader = pshader; - - if (rand()%100 > 90) - { - p->height = 32; - p->width = 32; - p->alpha = 0.10f; - } - else - { - p->height = 1; - p->width = 1; - } - - p->vel[2] = -20; - - p->type = P_WEATHER_FLURRY; - - if (turb) - p->vel[2] = -10; - - VectorCopy(cent->currentState.origin, p->org); - - p->org[0] = p->org[0]; - p->org[1] = p->org[1]; - p->org[2] = p->org[2]; - - p->vel[0] = p->vel[1] = 0; - - p->accel[0] = p->accel[1] = p->accel[2] = 0; - - p->vel[0] += cent->currentState.angles[0] * 32 + (crandom() * 16); - p->vel[1] += cent->currentState.angles[1] * 32 + (crandom() * 16); - p->vel[2] += cent->currentState.angles[2]; - - if (turb) - { - p->accel[0] = crandom () * 16; - p->accel[1] = crandom () * 16; - } - -} - -void CG_ParticleSnow (qhandle_t pshader, vec3_t origin, vec3_t origin2, int turb, float range, int snum) -{ - cparticle_t *p; - - if (!pshader) - CG_Printf ("CG_ParticleSnow pshader == ZERO!\n"); - - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - p->time = timenonscaled; - p->color = 0; - p->alpha = 0.40f; - p->alphavel = 0; - p->start = origin[2]; - p->end = origin2[2]; - p->pshader = pshader; - p->height = 1; - p->width = 1; - - p->vel[2] = -50; - - if (turb) - { - p->type = P_WEATHER_TURBULENT; - p->vel[2] = -50 * 1.3; - } - else - { - p->type = P_WEATHER; - } - - VectorCopy(origin, p->org); - - p->org[0] = p->org[0] + ( crandom() * range); - p->org[1] = p->org[1] + ( crandom() * range); - p->org[2] = p->org[2] + ( crandom() * (p->start - p->end)); - - p->vel[0] = p->vel[1] = 0; - - p->accel[0] = p->accel[1] = p->accel[2] = 0; - - if (turb) - { - p->vel[0] = crandom() * 16; - p->vel[1] = crandom() * 16; - } - - // Rafael snow pvs check - p->snum = snum; - p->link = qtrue; - -} - void CG_ParticleBubble (centity_t *cent, qhandle_t pshader, vec3_t origin, vec3_t origin2, int turb, float range, int snum) { cparticle_t *p; @@ -1056,7 +970,7 @@ void CG_ParticleBubble (centity_t *cent, qhandle_t pshader, vec3_t origin, vec3_ p->time = timenonscaled; // BFP - Add end time to remove particles, if there's no end time the particles will remain there - p->endtime = timenonscaled + 1250 + (crandom() * 20); + p->endtime = timenonscaled + 2000 + (crandom() * 150); p->startfade = timenonscaled + 200; p->color = 0; @@ -1091,7 +1005,7 @@ void CG_ParticleBubble (centity_t *cent, qhandle_t pshader, vec3_t origin, vec3_ VectorSet( p->vel, (rand() % 801) - 400, (rand() % 801) - 400, - 20 ); + 40 ); // dispersion VectorSet( p->accel, @@ -1108,62 +1022,84 @@ void CG_ParticleBubble (centity_t *cent, qhandle_t pshader, vec3_t origin, vec3_ // Rafael snow pvs check p->snum = snum; - p->link = qtrue; + p->link = qfalse; } -void CG_ParticleSmoke (qhandle_t pshader, centity_t *cent) +// BFP - Particle for dash smoke when using ki boost and moving in the ground +void CG_ParticleDashSmoke (centity_t *cent, qhandle_t pshader, vec3_t origin) { - - // using cent->density = enttime - // cent->frame = startfade cparticle_t *p; - if (!pshader) - CG_Printf ("CG_ParticleSmoke == ZERO!\n"); + // if (!pshader) CG_Printf ("CG_ParticleDashSmoke pshader == ZERO!\n"); + + // Too much smoke... + // That cent->trailTime can be handled to avoid spawning too much and only spawn when the game isn't paused, hehehe :P + if ( cent->trailTime > cg.time ) { + return; + } + cent->trailTime += 50; + if ( cent->trailTime < cg.time ) { + cent->trailTime = cg.time; + } if (!free_particles) return; + p = free_particles; free_particles = p->next; p->next = active_particles; active_particles = p; + p->time = timenonscaled; - - p->endtime = timenonscaled + cent->currentState.time; - p->startfade = timenonscaled + cent->currentState.time2; - - p->color = 0; - p->alpha = 1.0; - p->alphavel = 0; + + p->alpha = 0.45; + p->alphavel = -0.1; + + p->pshader = pshader; p->start = cent->currentState.origin[2]; p->end = cent->currentState.origin2[2]; - p->pshader = pshader; - p->rotate = qfalse; - p->height = 8; - p->width = 8; - p->endheight = 32; - p->endwidth = 32; - p->type = P_SMOKE; - - VectorCopy(cent->currentState.origin, p->org); - p->vel[0] = p->vel[1] = 0; - p->accel[0] = p->accel[1] = p->accel[2] = 0; + p->endtime = timenonscaled + 2000; + p->startfade = timenonscaled + 100; - p->vel[2] = 5; + p->height = p->width = 25; - if (cent->currentState.frame == 1)// reverse gravity - p->vel[2] *= -1; + p->endheight = p->height * 2; + p->endwidth = p->width * 2; - p->roll = 8 + (crandom() * 4); -} + p->type = P_SMOKE_IMPACT; + + VectorCopy( origin, p->org ); + VectorSet( p->vel, + (rand() % 401) - 200, + (rand() % 401) - 200, + 20 ); + // dispersion + VectorSet( p->accel, + crandom() * 10, + crandom() * 10, + 1400 ); +} -void CG_ParticleBulletDebris (vec3_t org, vec3_t vel, int duration) +// BFP - Antigrav rock particles for ki charging status +void CG_ParticleAntigravRock (qhandle_t pshader, centity_t *cent, vec3_t origin) { - cparticle_t *p; + // if (!pshader) CG_Printf ("CG_ParticleAntigravRock == ZERO!\n"); + + // Too many rocks... That cent->dustTrailTime can be handled to avoid spawning too many, hehehe :P + // cent->dustTrailTime was unused on Q3 before, so now it's being used for this kind of particles + // reusing cent->trailTime would make the time more delayed to spawn the particles, so not visually good + if ( cent->dustTrailTime > timenonscaled ) { + return; + } + cent->dustTrailTime += 20; + if ( cent->dustTrailTime < timenonscaled ) { + cent->dustTrailTime = timenonscaled; + } + if (!free_particles) return; p = free_particles; @@ -1171,31 +1107,163 @@ void CG_ParticleBulletDebris (vec3_t org, vec3_t vel, int duration) p->next = active_particles; active_particles = p; p->time = timenonscaled; - - p->endtime = timenonscaled + duration; - p->startfade = timenonscaled + duration/2; - - p->color = EMISIVEFADE; - p->alpha = 1.0; - p->alphavel = 0; - p->height = 0.5; - p->width = 0.5; - p->endheight = 0.5; - p->endwidth = 0.5; + p->endtime = timenonscaled + 450 + (crandom() * 20); - p->pshader = cgs.media.tracerShader; + p->color = 0; + p->alpha = 1; + p->alphavel = 0; + p->pshader = pshader; + p->height = p->width = 2 + (crandom() * 0.5); + p->type = P_ANTIGRAV_ROCK; - p->type = P_SMOKE; - - VectorCopy(org, p->org); + VectorCopy( origin, p->org ); - p->vel[0] = vel[0]; - p->vel[1] = vel[1]; - p->vel[2] = vel[2]; - p->accel[0] = p->accel[1] = p->accel[2] = 0; + p->org[0] += (crandom() * 50); + p->org[1] += (crandom() * 50); - p->accel[2] = -60; + p->start = cent->currentState.origin[2]; + // maybe BFP used to debug the client side visual of the other player with this top limit + p->end = (cent->currentState.clientNum != cg.snap->ps.clientNum) + ? p->org[2] + 130 + (crandom() * 10) + : p->org[2] + 170 + (crandom() * 10); + + p->vel[0] = 0; + p->vel[1] = 0; + // maybe BFP used to debug the client side visual of the other player with this velocity + p->vel[2] = (cent->currentState.clientNum != cg.snap->ps.clientNum) + ? 200 + : 470; + + p->accel[0] = 0; + p->accel[1] = 0; + // maybe BFP used to debug the client side visual of the other player with this acceleration + p->accel[2] = (cent->currentState.clientNum != cg.snap->ps.clientNum) + ? 10 + : 20; + + p->roll = 5; // used as bounce counter + p->link = qfalse; // to handle the ki charging status + p->snum = 0; // to handle the client side visuals +} + +// BFP - To handle the client side visuals of antigrav rock particles +void CG_AntigravRockHandling (centity_t *cent) +{ + cparticle_t *p, *next; + + for (p=active_particles ; p ; p=next) + { + next = p->next; + if (p->type == P_ANTIGRAV_ROCK) + { + if ( cent->currentState.clientNum == cg.snap->ps.clientNum + && ( cent->currentState.legsAnim & ~ANIM_TOGGLEBIT ) != LEGS_CHARGE ) + { + // BFP - Make each particle fall when they aren't on ki charging status + if (!p->link && !p->snum) // to handle the client side visuals + { + p->endtime = timenonscaled + 1650; + p->link = qtrue; + } + } + // if the player sees the other player doing that, the handling is different from itself, + // to correct the client side visuals in this case + if ( cent->currentState.clientNum != cg.snap->ps.clientNum + && ( cent->currentState.eFlags & EF_AURA ) + && ( 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 + } + } + } +} + + +void CG_ParticleSmoke (qhandle_t pshader, centity_t *cent) +{ + + // using cent->density = enttime + // cent->frame = startfade + cparticle_t *p; + + // if (!pshader) CG_Printf ("CG_ParticleSmoke == ZERO!\n"); + + if (!free_particles) + return; + p = free_particles; + free_particles = p->next; + p->next = active_particles; + active_particles = p; + p->time = timenonscaled; + + p->endtime = timenonscaled + cent->currentState.time; + p->startfade = timenonscaled + cent->currentState.time2; + + p->color = 0; + p->alpha = 1.0; + p->alphavel = 0; + p->start = cent->currentState.origin[2]; + p->end = cent->currentState.origin2[2]; + p->pshader = pshader; + p->rotate = qfalse; + p->height = 8; + p->width = 8; + p->endheight = 32; + p->endwidth = 32; + p->type = P_SMOKE; + + VectorCopy(cent->currentState.origin, p->org); + + p->vel[0] = p->vel[1] = 0; + p->accel[0] = p->accel[1] = p->accel[2] = 0; + + p->vel[2] = 5; + + if (cent->currentState.frame == 1)// reverse gravity + p->vel[2] *= -1; + + p->roll = 8 + (crandom() * 4); +} + + +void CG_ParticleBulletDebris (vec3_t org, vec3_t vel, int duration) +{ + + cparticle_t *p; + + if (!free_particles) + return; + p = free_particles; + free_particles = p->next; + p->next = active_particles; + active_particles = p; + p->time = timenonscaled; + + p->endtime = timenonscaled + duration; + p->startfade = timenonscaled + duration/2; + + p->color = EMISIVEFADE; + p->alpha = 1.0; + p->alphavel = 0; + + p->height = 0.5; + p->width = 0.5; + p->endheight = 0.5; + p->endwidth = 0.5; + + p->pshader = cgs.media.tracerShader; + + p->type = P_SMOKE; + + VectorCopy(org, p->org); + + p->vel[0] = vel[0]; + p->vel[1] = vel[1]; + p->vel[2] = vel[2]; + p->accel[0] = p->accel[1] = p->accel[2] = 0; + + p->accel[2] = -60; p->vel[2] += -20; } @@ -1205,7 +1273,6 @@ void CG_ParticleBulletDebris (vec3_t org, vec3_t vel, int duration) CG_ParticleExplosion ====================== */ - void CG_ParticleExplosion (char *animStr, vec3_t origin, vec3_t vel, int duration, int sizeStart, int sizeEnd) { cparticle_t *p; @@ -1259,13 +1326,193 @@ void CG_ParticleExplosion (char *animStr, vec3_t origin, vec3_t vel, int duratio } -// Rafael Shrapnel -void CG_AddParticleShrapnel (localEntity_t *le) +void CG_ParticleSparks (vec3_t org, vec3_t vel, int duration, float x, float y, float speed) { - return; + cparticle_t *p; + + if (!free_particles) + return; + p = free_particles; + free_particles = p->next; + p->next = active_particles; + active_particles = p; + p->time = timenonscaled; + + p->endtime = timenonscaled + duration; + p->startfade = timenonscaled + duration/2; + + p->color = EMISIVEFADE; + p->alpha = 0.4f; + p->alphavel = 0; + + p->height = 0.5; + p->width = 0.5; + p->endheight = 0.5; + p->endwidth = 0.5; + + p->pshader = cgs.media.tracerShader; + + p->type = P_SMOKE; + + VectorCopy(org, p->org); + + p->org[0] += (crandom() * x); + p->org[1] += (crandom() * y); + + p->vel[0] = vel[0]; + p->vel[1] = vel[1]; + p->vel[2] = vel[2]; + + p->accel[0] = p->accel[1] = p->accel[2] = 0; + + p->vel[0] += (crandom() * 4); + p->vel[1] += (crandom() * 4); + p->vel[2] += (20 + (crandom() * 10)) * speed; + + p->accel[0] = crandom () * 4; + p->accel[1] = crandom () * 4; + } -// done. +void CG_ParticleDust (centity_t *cent, vec3_t origin, vec3_t dir) +{ + float length; + float dist; + float crittersize; + vec3_t angles, forward; + vec3_t point; + cparticle_t *p; + int i; + + dist = 0; + + VectorNegate (dir, dir); + length = VectorLength (dir); + vectoangles (dir, angles); + AngleVectors (angles, forward, NULL, NULL); + + crittersize = LARGESIZE; + + if (length) + dist = length / crittersize; + + if (dist < 1) + dist = 1; + + VectorCopy (origin, point); + + for (i=0; inext; + p->next = active_particles; + active_particles = p; + + p->time = timenonscaled; + p->alpha = 5.0; + p->alphavel = 0; + p->roll = 0; + + p->pshader = cgs.media.smokePuffShader; + + // RF, stay around for long enough to expand and dissipate naturally + if (length) + p->endtime = timenonscaled + 4500 + (crandom() * 3500); + else + p->endtime = timenonscaled + 750 + (crandom() * 500); + + p->startfade = timenonscaled; + + p->width = LARGESIZE; + p->height = LARGESIZE; + + // RF, expand while falling + p->endheight = LARGESIZE*3.0; + p->endwidth = LARGESIZE*3.0; + + if (!length) + { + p->width *= 0.2f; + p->height *= 0.2f; + + p->endheight = NORMALSIZE; + p->endwidth = NORMALSIZE; + } + + p->type = P_SMOKE; + + VectorCopy( point, p->org ); + + p->vel[0] = crandom()*6; + p->vel[1] = crandom()*6; + p->vel[2] = random()*20; + + // RF, add some gravity/randomness + p->accel[0] = crandom()*3; + p->accel[1] = crandom()*3; + p->accel[2] = -PARTICLE_GRAVITY*0.4; + + VectorClear( p->accel ); + + p->rotate = qfalse; + + p->roll = rand()%179; + + p->alpha = 0.75; + + } + + +} + +void CG_ParticleMisc (qhandle_t pshader, vec3_t origin, int size, int duration, float alpha) +{ + cparticle_t *p; + + // if (!pshader) CG_Printf ("CG_ParticleImpactSmokePuff pshader == ZERO!\n"); + + if (!free_particles) + return; + + p = free_particles; + free_particles = p->next; + p->next = active_particles; + active_particles = p; + p->time = timenonscaled; + p->alpha = 1.0; + p->alphavel = 0; + p->roll = rand()%179; + + p->pshader = pshader; + + if (duration > 0) + p->endtime = timenonscaled + duration; + else + p->endtime = duration; + + p->startfade = timenonscaled; + + p->width = size; + p->height = size; + + p->endheight = size; + p->endwidth = size; + + p->type = P_SPRITE; + + VectorCopy( origin, p->org ); + + p->rotate = qfalse; +} + +// BFP - Unused function for particles, looks like here is to determine in the areas +// CG_SnowLink was never used in Q3 +#if 0 int CG_NewParticleArea (int num) { // const char *str; @@ -1351,60 +1598,83 @@ void CG_SnowLink (centity_t *cent, qboolean particleOn) } } +#endif -// BFP - Particle for dash smoke when using ki boost and moving in the ground -void CG_ParticleDashSmoke (centity_t *cent, qhandle_t pshader, vec3_t origin) + +// BFP - Unused particle stuff, saved for later :P +#if 0 +void CG_ParticleSnowFlurry (qhandle_t pshader, centity_t *cent) { cparticle_t *p; + qboolean turb = qtrue; - // if (!pshader) CG_Printf ("CG_ParticleDashSmoke pshader == ZERO!\n"); + // if (!pshader) CG_Printf ("CG_ParticleSnowFlurry pshader == ZERO!\n"); if (!free_particles) return; - p = free_particles; free_particles = p->next; p->next = active_particles; active_particles = p; - p->time = timenonscaled; + p->color = 0; + p->alpha = 0.90f; + p->alphavel = 0; - p->alpha = 0.45; - p->alphavel = -0.1; - + p->start = cent->currentState.origin2[0]; + p->end = cent->currentState.origin2[1]; + + p->endtime = timenonscaled + cent->currentState.time; + p->startfade = timenonscaled + cent->currentState.time2; + p->pshader = pshader; - p->start = cent->currentState.origin[2]; - p->end = cent->currentState.origin2[2]; + + if (rand()%100 > 90) + { + p->height = 32; + p->width = 32; + p->alpha = 0.10f; + } + else + { + p->height = 1; + p->width = 1; + } - p->endtime = timenonscaled + 2000; - p->startfade = timenonscaled + 100; + p->vel[2] = -20; - p->height = p->width = 25; + p->type = P_WEATHER_FLURRY; + + if (turb) + p->vel[2] = -10; + + VectorCopy(cent->currentState.origin, p->org); - p->endheight = p->height * 2; - p->endwidth = p->width * 2; + p->org[0] = p->org[0]; + p->org[1] = p->org[1]; + p->org[2] = p->org[2]; + + p->vel[0] = p->vel[1] = 0; + + p->accel[0] = p->accel[1] = p->accel[2] = 0; - p->type = P_SMOKE_IMPACT; + p->vel[0] += cent->currentState.angles[0] * 32 + (crandom() * 16); + p->vel[1] += cent->currentState.angles[1] * 32 + (crandom() * 16); + p->vel[2] += cent->currentState.angles[2]; - VectorCopy( origin, p->org ); - VectorSet( p->vel, - (rand() % 401) - 200, - (rand() % 401) - 200, - 20 ); + if (turb) + { + p->accel[0] = crandom () * 16; + p->accel[1] = crandom () * 16; + } - // dispersion - VectorSet( p->accel, - crandom() * 10, - crandom() * 10, - 1400 ); } -// BFP - Antigrav rock particles for ki charging status -void CG_ParticleAntigravRock (qhandle_t pshader, centity_t *cent, vec3_t origin) +void CG_ParticleSnow (qhandle_t pshader, vec3_t origin, vec3_t origin2, int turb, float range, int snum) { cparticle_t *p; - // if (!pshader) CG_Printf ("CG_ParticleAntigravRock == ZERO!\n"); + // if (!pshader) CG_Printf ("CG_ParticleSnow pshader == ZERO!\n"); if (!free_particles) return; @@ -1413,40 +1683,54 @@ void CG_ParticleAntigravRock (qhandle_t pshader, centity_t *cent, vec3_t origin) p->next = active_particles; active_particles = p; p->time = timenonscaled; - - p->endtime = timenonscaled + 450 + (crandom() * 20); - p->startfade = timenonscaled + 200; - p->roll = 5; // used as bounce counter - p->link = qfalse; // to handle the ki charging status - p->color = 0; - p->alpha = 1; + p->alpha = 0.40f; p->alphavel = 0; - p->start = cent->currentState.origin[2]; - p->end = cent->currentState.origin2[2]; + p->start = origin[2]; + p->end = origin2[2]; p->pshader = pshader; - p->height = p->width = 2 + (crandom() * 0.5); - p->type = P_ANTIGRAV_ROCK; + p->height = 1; + p->width = 1; + + p->vel[2] = -50; - VectorCopy( origin, p->org ); + if (turb) + { + p->type = P_WEATHER_TURBULENT; + p->vel[2] = -50 * 1.3; + } + else + { + p->type = P_WEATHER; + } + + VectorCopy(origin, p->org); - p->org[0] += (crandom() * 40); - p->org[1] += (crandom() * 40); + p->org[0] = p->org[0] + ( crandom() * range); + p->org[1] = p->org[1] + ( crandom() * range); + p->org[2] = p->org[2] + ( crandom() * (p->start - p->end)); p->vel[0] = p->vel[1] = 0; - p->accel[0] = p->accel[1] = 0; + + p->accel[0] = p->accel[1] = p->accel[2] = 0; + + if (turb) + { + p->vel[0] = crandom() * 16; + p->vel[1] = crandom() * 16; + } + + // Rafael snow pvs check + p->snum = snum; + p->link = qtrue; - p->vel[2] = 20; - p->accel[2] = 1000; } -#if 0 void CG_ParticleImpactSmokePuff (qhandle_t pshader, vec3_t origin) { cparticle_t *p; - if (!pshader) - CG_Printf ("CG_ParticleImpactSmokePuff pshader == ZERO!\n"); + // if (!pshader) CG_Printf ("CG_ParticleImpactSmokePuff pshader == ZERO!\n"); if (!free_particles) return; @@ -1485,8 +1769,7 @@ void CG_Particle_Bleed (qhandle_t pshader, vec3_t start, vec3_t dir, int fleshEn { cparticle_t *p; - if (!pshader) - CG_Printf ("CG_Particle_Bleed pshader == ZERO!\n"); + // if (!pshader) CG_Printf ("CG_Particle_Bleed pshader == ZERO!\n"); if (!free_particles) return; @@ -1546,8 +1829,7 @@ void CG_Particle_OilParticle (qhandle_t pshader, centity_t *cent) ratio =(float)1 - ((float)time / (float)time2); - if (!pshader) - CG_Printf ("CG_Particle_OilParticle == ZERO!\n"); + // if (!pshader) CG_Printf ("CG_Particle_OilParticle == ZERO!\n"); if (!free_particles) return; @@ -1599,8 +1881,7 @@ void CG_Particle_OilSlick (qhandle_t pshader, centity_t *cent) { cparticle_t *p; - if (!pshader) - CG_Printf ("CG_Particle_OilSlick == ZERO!\n"); + // if (!pshader) CG_Printf ("CG_Particle_OilSlick == ZERO!\n"); if (!free_particles) return; @@ -1742,8 +2023,7 @@ void CG_BloodPool (localEntity_t *le, qhandle_t pshader, trace_t *tr) vec3_t start; float rndSize; - if (!pshader) - CG_Printf ("CG_BloodPool pshader == ZERO!\n"); + // if (!pshader) CG_Printf ("CG_BloodPool pshader == ZERO!\n"); if (!free_particles) return; @@ -1872,187 +2152,3 @@ void CG_ParticleBloodCloud (centity_t *cent, vec3_t origin, vec3_t dir) } #endif - -void CG_ParticleSparks (vec3_t org, vec3_t vel, int duration, float x, float y, float speed) -{ - cparticle_t *p; - - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - p->time = timenonscaled; - - p->endtime = timenonscaled + duration; - p->startfade = timenonscaled + duration/2; - - p->color = EMISIVEFADE; - p->alpha = 0.4f; - p->alphavel = 0; - - p->height = 0.5; - p->width = 0.5; - p->endheight = 0.5; - p->endwidth = 0.5; - - p->pshader = cgs.media.tracerShader; - - p->type = P_SMOKE; - - VectorCopy(org, p->org); - - p->org[0] += (crandom() * x); - p->org[1] += (crandom() * y); - - p->vel[0] = vel[0]; - p->vel[1] = vel[1]; - p->vel[2] = vel[2]; - - p->accel[0] = p->accel[1] = p->accel[2] = 0; - - p->vel[0] += (crandom() * 4); - p->vel[1] += (crandom() * 4); - p->vel[2] += (20 + (crandom() * 10)) * speed; - - p->accel[0] = crandom () * 4; - p->accel[1] = crandom () * 4; - -} - -void CG_ParticleDust (centity_t *cent, vec3_t origin, vec3_t dir) -{ - float length; - float dist; - float crittersize; - vec3_t angles, forward; - vec3_t point; - cparticle_t *p; - int i; - - dist = 0; - - VectorNegate (dir, dir); - length = VectorLength (dir); - vectoangles (dir, angles); - AngleVectors (angles, forward, NULL, NULL); - - crittersize = LARGESIZE; - - if (length) - dist = length / crittersize; - - if (dist < 1) - dist = 1; - - VectorCopy (origin, point); - - for (i=0; inext; - p->next = active_particles; - active_particles = p; - - p->time = timenonscaled; - p->alpha = 5.0; - p->alphavel = 0; - p->roll = 0; - - p->pshader = cgs.media.smokePuffShader; - - // RF, stay around for long enough to expand and dissipate naturally - if (length) - p->endtime = timenonscaled + 4500 + (crandom() * 3500); - else - p->endtime = timenonscaled + 750 + (crandom() * 500); - - p->startfade = timenonscaled; - - p->width = LARGESIZE; - p->height = LARGESIZE; - - // RF, expand while falling - p->endheight = LARGESIZE*3.0; - p->endwidth = LARGESIZE*3.0; - - if (!length) - { - p->width *= 0.2f; - p->height *= 0.2f; - - p->endheight = NORMALSIZE; - p->endwidth = NORMALSIZE; - } - - p->type = P_SMOKE; - - VectorCopy( point, p->org ); - - p->vel[0] = crandom()*6; - p->vel[1] = crandom()*6; - p->vel[2] = random()*20; - - // RF, add some gravity/randomness - p->accel[0] = crandom()*3; - p->accel[1] = crandom()*3; - p->accel[2] = -PARTICLE_GRAVITY*0.4; - - VectorClear( p->accel ); - - p->rotate = qfalse; - - p->roll = rand()%179; - - p->alpha = 0.75; - - } - - -} - -void CG_ParticleMisc (qhandle_t pshader, vec3_t origin, int size, int duration, float alpha) -{ - cparticle_t *p; - - // if (!pshader) CG_Printf ("CG_ParticleImpactSmokePuff pshader == ZERO!\n"); - - if (!free_particles) - return; - - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - p->time = timenonscaled; - p->alpha = 1.0; - p->alphavel = 0; - p->roll = rand()%179; - - p->pshader = pshader; - - if (duration > 0) - p->endtime = timenonscaled + duration; - else - p->endtime = duration; - - p->startfade = timenonscaled; - - p->width = size; - p->height = size; - - p->endheight = size; - p->endwidth = size; - - p->type = P_SPRITE; - - VectorCopy( origin, p->org ); - - p->rotate = qfalse; -} diff --git a/source/cgame/cg_players.c b/source/cgame/cg_players.c index 520e995..fbcb11d 100644 --- a/source/cgame/cg_players.c +++ b/source/cgame/cg_players.c @@ -1440,10 +1440,10 @@ static void CG_PlayerAngles( centity_t *cent, vec3_t legs[3], vec3_t torso[3], v dest = headAngles[PITCH] * 0.75f; } // BFP - When flying, set the legs in the first case - if ( cg.predictedPlayerState.pm_flags & PMF_FLYING ) { + if ( cent->currentState.powerups & ( 1 << PW_FLIGHT ) ) { CG_SwingAngles( dest, 15, 30, 0.1f, ¢->pe.legs.pitchAngle, ¢->pe.legs.pitching ); legsAngles[PITCH] = cent->pe.legs.pitchAngle; - } + } else if ( ( cent->currentState.legsAnim & ~ANIM_TOGGLEBIT ) == LEGS_CHARGE ) {} // BFP - When flying, set the torso correctly into these angles CG_SwingAngles( dest, 30, 30, 0.1f, ¢->pe.torso.pitchAngle, ¢->pe.torso.pitching ); @@ -1460,8 +1460,6 @@ static void CG_PlayerAngles( centity_t *cent, vec3_t legs[3], vec3_t torso[3], v // --------- roll ------------- - // BFP - TODO: Make forward and backwards movements smooth when starting to move - // lean towards the direction of travel VectorCopy( cent->currentState.pos.trDelta, velocity ); speed = VectorNormalize( velocity ); @@ -1482,10 +1480,12 @@ static void CG_PlayerAngles( centity_t *cent, vec3_t legs[3], vec3_t torso[3], v side = speed * DotProduct( velocity, axis[0] ); legsAngles[PITCH] += side; - // BFP - Make the torso move the pitch angle a bit - AnglesToAxis( torsoAngles, axis ); - side = speed * DotProduct( velocity, axis[0] ); - torsoAngles[PITCH] += side; + // BFP - Make the torso move the pitch angle a bit in the flight + if ( cent->currentState.powerups & ( 1 << PW_FLIGHT ) ) { + AnglesToAxis( torsoAngles, axis ); + side = speed * DotProduct( velocity, axis[0] ); + torsoAngles[PITCH] += side; + } } // BFP - Don't make every player forced to see this way with their legs to the others @@ -1516,40 +1516,32 @@ static void CG_PlayerAngles( centity_t *cent, vec3_t legs[3], vec3_t torso[3], v //========================================================================== +// BFP - No smoke puff effect +#if 0 /* =============== CG_HasteTrail =============== */ -static void CG_HasteTrail( centity_t *cent, vec3_t endPos ) { // BFP - Second parameter added for smoke particles - // BFP - No smoke puff effect -#if 0 +static void CG_HasteTrail( centity_t *cent ) { localEntity_t *smoke; vec3_t origin; int anim; -#endif if ( cent->trailTime > cg.time ) { return; } - // BFP - No handling running and backwards animations -#if 0 + anim = cent->pe.legs.animationNumber & ~ANIM_TOGGLEBIT; if ( anim != LEGS_RUN && anim != LEGS_BACK ) { return; } -#endif - cent->trailTime += 50; // BFP - Before: += 100 + cent->trailTime += 100; if ( cent->trailTime < cg.time ) { cent->trailTime = cg.time; } - // BFP - Apply dash smoke particle for the trail, if the function were used directly, it would generate too many particles than we expected - CG_ParticleDashSmoke( cent, cgs.media.particleSmokeShader, endPos ); - - // BFP - No smoke puff effect -#if 0 VectorCopy( cent->lerpOrigin, origin ); origin[2] -= 16; @@ -1564,8 +1556,8 @@ static void CG_HasteTrail( centity_t *cent, vec3_t endPos ) { // BFP - Second pa // use the optimized local entity add smoke->leType = LE_SCALE_FADE; -#endif } +#endif /* =============== @@ -1871,15 +1863,6 @@ static qboolean CG_PlayerShadow( centity_t *cent, float *shadowPlane ) { *shadowPlane = 0; - if ( cg_shadows.integer == 0 ) { - return qfalse; - } - - // no shadows when invisible - if ( cent->currentState.powerups & ( 1 << PW_INVIS ) ) { - return qfalse; - } - // send a trace down from the player to the ground VectorCopy( cent->lerpOrigin, end ); end[2] -= SHADOW_DISTANCE; @@ -1891,44 +1874,59 @@ static qboolean CG_PlayerShadow( centity_t *cent, float *shadowPlane ) { // BFP - Dash smoke and bubble particles when using ki boost on the ground or above the water contents = CG_PointContents( trace.endpos, -1 ); if ( cent->currentState.eFlags & EF_AURA ) { - if ( !( cg.snap->ps.pm_flags & PMF_KI_CHARGE ) && - ( ( cent->currentState.legsAnim & ~ANIM_TOGGLEBIT ) == LEGS_RUN + if ( !( cent->currentState.powerups & ( 1 << PW_HASTE ) ) + && ( ( cent->currentState.legsAnim & ~ANIM_TOGGLEBIT ) == LEGS_RUN || ( cent->currentState.legsAnim & ~ANIM_TOGGLEBIT ) == LEGS_BACK || ( cent->currentState.legsAnim & ~ANIM_TOGGLEBIT ) == LEGS_FLYA || ( cent->currentState.legsAnim & ~ANIM_TOGGLEBIT ) == LEGS_FLYB ) ) { - if ( ( !( contents & ( CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA ) ) - && trace.fraction <= 0.70f ) + if ( !( contents & ( CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA ) ) + && ( trace.fraction <= 0.70f // If the player is stepping a mover: - || cg.snap->ps.groundEntityNum != ENTITYNUM_NONE ) { - CG_HasteTrail( cent, trace.endpos ); - } else if ( waterTrace.fraction >= 0.10f && waterTrace.fraction <= 0.70f ) { - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, waterTrace.endpos, end, 1, 0, 0 ); - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, waterTrace.endpos, end, 1, 0, 0 ); - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, waterTrace.endpos, end, 1, 0, 0 ); + || cent->currentState.groundEntityNum != ENTITYNUM_NONE ) ) { + // BFP - Apply dash smoke particle for the trail, if the function were used directly, it would generate too many particles than we expected + CG_ParticleDashSmoke( cent, cgs.media.particleSmokeShader, trace.endpos ); } - } else if ( ( cg.snap->ps.pm_flags & PMF_KI_CHARGE ) // BFP - Antigrav rock particles on ki charging status - && ( ( !( contents & ( CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA ) ) - && trace.fraction <= 0.50f ) - // If the player is stepping a mover: - || cg.snap->ps.groundEntityNum != ENTITYNUM_NONE ) ) { - // BFP - Spawn randomly the antigrav rock shaders with the particles - int shaderIndex = rand() % 3; - switch ( shaderIndex ) { - case 0: { - CG_ParticleAntigravRock( cgs.media.pebbleShader1, cent, trace.endpos ); - break; - } - case 1: { - CG_ParticleAntigravRock( cgs.media.pebbleShader2, cent, trace.endpos ); - break; - } - default: { - CG_ParticleAntigravRock( cgs.media.pebbleShader3, cent, trace.endpos ); + + if ( waterTrace.fraction >= 0.10f && waterTrace.fraction <= 0.70f ) { + CG_ParticleBubble( cent, cgs.media.waterBubbleShader, waterTrace.endpos, end, 1, 10, 0 ); + CG_ParticleBubble( cent, cgs.media.waterBubbleShader, waterTrace.endpos, end, 1, 10, 0 ); + CG_ParticleBubble( cent, cgs.media.waterBubbleShader, waterTrace.endpos, end, 1, 10, 0 ); + } + } + + if ( ( cent->currentState.legsAnim & ~ANIM_TOGGLEBIT ) == LEGS_CHARGE ) { // BFP - Antigrav rock particles on ki charging status + if ( !( contents & ( CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA ) ) + && ( trace.fraction <= 0.30f + // If the player is stepping a mover: + || cent->currentState.groundEntityNum != ENTITYNUM_NONE ) ) { + // BFP - Spawn randomly the antigrav rock shaders with the particles + int shaderIndex = rand() % 3; + switch ( shaderIndex ) { + case 0: { + CG_ParticleAntigravRock( cgs.media.pebbleShader1, cent, trace.endpos ); + break; + } + case 1: { + CG_ParticleAntigravRock( cgs.media.pebbleShader2, cent, trace.endpos ); + break; + } + default: { + CG_ParticleAntigravRock( cgs.media.pebbleShader3, cent, trace.endpos ); + } } } } } + if ( cg_shadows.integer == 0 ) { + return qfalse; + } + + // no shadows when invisible + if ( cent->currentState.powerups & ( 1 << PW_INVIS ) ) { + return qfalse; + } + // no shadow if too high if ( trace.fraction == 1.0 || trace.startsolid || trace.allsolid ) { return qfalse; @@ -2073,7 +2071,8 @@ void CG_AddRefEntityWithPowerups( refEntity_t *ent, entityState_t *state, int te // BFP - If the player is using lightweight auras or their own small aura if ( ( state->eFlags & EF_AURA ) && ( cg_lightweightAuras.integer > 0 - || cg_smallOwnAura.integer > 0 ) ) { + || ( state->clientNum == cg.snap->ps.clientNum + && cg_smallOwnAura.integer > 0 ) ) ) { // BFP - TODO: If player is transformed: // ent->customShader = cgs.media.auraYellowShader; @@ -2197,7 +2196,7 @@ void CG_Player( centity_t *cent ) { // get the player model information renderfx = 0; - if ( cent->currentState.number == cg.snap->ps.clientNum ) { + if ( clientNum == cg.snap->ps.clientNum ) { if (!cg.renderingThirdPerson) { renderfx = RF_THIRD_PERSON; // only draw in mirrors } /*else { // BFP - cg_cameraMode cvar doesn't exist @@ -2227,6 +2226,9 @@ void CG_Player( centity_t *cent ) { // add the shadow shadow = CG_PlayerShadow( cent, &shadowPlane ); + // BFP - Handle the antigrav rock particles when the player is charging + CG_AntigravRockHandling( cent ); + // add a water splash if partially in and out of water CG_PlayerSplash( cent ); @@ -2338,9 +2340,11 @@ void CG_Player( centity_t *cent ) { } // Macro for the dynamic aura light, note: when charging it changes the shinning a bit + // Aura lights like cg_smallOwnAura only can be shown to itself and not the other clients, + // the other clients only show small lights #define AURA_LIGHT(r, g, b) \ if ( cg_lightAuras.integer > 0 ) { \ - if ( cg_smallOwnAura.integer > 0 ) { \ + if ( clientNum == cg.snap->ps.clientNum && cg_smallOwnAura.integer > 0 ) { \ trap_R_AddLightToScene( cent->lerpOrigin, 200, r, g, b ); \ trap_R_AddLightToScene( cent->lerpOrigin, 200, r, g, b ); \ if ( !( cg.predictedPlayerState.pm_flags & PMF_KI_CHARGE ) ) { \ @@ -2356,7 +2360,7 @@ void CG_Player( centity_t *cent ) { trap_R_AddLightToScene( cent->lerpOrigin, 100 + (rand()&100), r, g, b ); \ trap_R_AddLightToScene( cent->lerpOrigin, 100 + (rand()&100), r, g, b ); \ } \ - } else if ( cg_lightweightAuras.integer > 0 || cg_polygonAura.integer > 0 || cg_highPolyAura.integer > 0 ) { \ + } else if ( clientNum != cg.snap->ps.clientNum || cg_lightweightAuras.integer > 0 || cg_polygonAura.integer > 0 || cg_highPolyAura.integer > 0 ) { \ trap_R_AddLightToScene( cent->lerpOrigin, 50 + (rand()&100), r, g, b ); \ trap_R_AddLightToScene( cent->lerpOrigin, 50 + (rand()&100), r, g, b ); \ trap_R_AddLightToScene( cent->lerpOrigin, 50 + (rand()&100), r, g, b ); \ @@ -2391,17 +2395,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, 1, 0, 0 ); - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 1, 0, 0 ); - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 1, 0, 0 ); + CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 1, 10, 0 ); + CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 1, 10, 0 ); + CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 1, 10, 0 ); } else if ( ( cent->currentState.legsAnim & ~ANIM_TOGGLEBIT ) == LEGS_CHARGE ) { bubbleOrigin[2] += -10; // put the origin a little below - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 0, 0, 0 ); - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 0, 0, 0 ); - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 0, 0, 0 ); - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 0, 0, 0 ); - CG_ParticleBubble( cent, cgs.media.waterBubbleShader, bubbleOrigin, trace.endpos, 0, 0, 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, 0 ); } } @@ -2445,7 +2451,7 @@ void CG_Player( centity_t *cent ) { VectorCopy( aura2.origin, aura2.oldorigin ); // don't positionally lerp at all // Ki boost and ki charge sounds - if ( ( cent->currentState.torsoAnim & ~ANIM_TOGGLEBIT ) == TORSO_CHARGE ) { + if ( ( cent->currentState.legsAnim & ~ANIM_TOGGLEBIT ) == LEGS_CHARGE ) { trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin, cgs.media.kiChargeSound ); } else { diff --git a/source/cgame/cg_view.c b/source/cgame/cg_view.c index e620fc8..7aa4933 100644 --- a/source/cgame/cg_view.c +++ b/source/cgame/cg_view.c @@ -339,9 +339,9 @@ static void CG_OffsetThirdPersonView( void ) { rightAngled = LERP( lastRightAngled, 0.0f, (float)(cg.frametime / 1000.00f) * 20.0f ); upAngled = LERP( lastUpAngled, 0.0f, (float)(cg.frametime / 1000.00f) * 20.0f ); - if ( cg_flytilt.integer >= 1 + if ( cg_flytilt.integer > 0 && ( cg.predictedPlayerState.eFlags & EF_AURA ) - && ( cg.predictedPlayerState.pm_flags & PMF_FLYING ) + && cg.predictedPlayerState.powerups[PW_FLIGHT] > 0 && !( cg.predictedPlayerState.pm_flags & PMF_KI_CHARGE ) ) { if ( cmd.rightmove < 0 ) { // Left focusAngles[ROLL] = LERP( lastAngled, -20.0f, (float)(cg.frametime / 1000.00f) * 15.0f ); diff --git a/source/game/bg_pmove.c b/source/game/bg_pmove.c index 196a170..5703e9d 100644 --- a/source/game/bg_pmove.c +++ b/source/game/bg_pmove.c @@ -252,7 +252,7 @@ static void PM_Friction( void ) { // apply flying friction // BFP - Flight - if ( pm->ps->pm_flags & PMF_FLYING ) { + if ( pm->ps->powerups[PW_FLIGHT] > 0 ) { control = speed < pm_stopspeed ? pm_stopspeed : speed; drop += control*pm_flightfriction*pml.frametime; } @@ -526,7 +526,7 @@ static void PM_WaterMove( void ) { // BFP - Avoid adding friction in the water while charging and flying if ( ( ( pm->ps->pm_flags & PMF_KI_CHARGE ) || ( pm->cmd.buttons & BUTTON_KI_CHARGE ) ) - && ( pm->ps->pm_flags & PMF_FLYING ) ) { + && pm->ps->powerups[PW_FLIGHT] > 0 ) { return; } @@ -624,7 +624,7 @@ static void PM_FlyMove( void ) { VectorCopy (wishvel, wishdir); wishspeed = VectorNormalize(wishdir); if ( !( pm->ps->pm_flags & PMF_INVULEXPAND ) // BFP - Don't increase the speed when blocking - && ( ( pm->ps->pm_flags & PMF_KI_BOOST ) || ( pm->cmd.buttons & BUTTON_KI_USE ) ) ) { + && ( pm->ps->powerups[PW_HASTE] > 0 || ( pm->cmd.buttons & BUTTON_KI_USE ) ) ) { wishspeed *= scale; } @@ -1189,14 +1189,14 @@ static void PM_GroundTrace( void ) { } // BFP - Make sure to handle the PMF flags when the player isn't flying - if ( !( pm->ps->pm_flags & PMF_FLYING ) ) { + if ( pm->ps->powerups[PW_FLIGHT] <= 0 ) { pm->ps->pm_flags |= PMF_FALLING; pm->ps->pm_flags &= ~PMF_NEARGROUND; } // BFP - If the player is in the ground, then jump! // And make sure to handle the PMF flag when the player isn't flying and falling - if ( ( pm->ps->pm_flags & PMF_FLYING ) + if ( pm->ps->powerups[PW_FLIGHT] > 0 && ( pm->ps->pm_flags & PMF_FALLING ) && !( pm->ps->pm_flags & PMF_NEARGROUND ) ) { if ( pml.groundTrace.contents & MASK_PLAYERSOLID ) { @@ -1226,7 +1226,7 @@ static void PM_GroundTrace( void ) { pml.walking = qfalse; // BFP - If flying, prevent from doing a jumping action on slopes - if ( pm->ps->pm_flags & PMF_FLYING ) { + if ( pm->ps->powerups[PW_FLIGHT] > 0 ) { return; } @@ -1251,7 +1251,7 @@ static void PM_GroundTrace( void ) { // BFP - NOTE: Originally, BFP doesn't stop "groundtracing" until here when the player is flying // BFP - If flying, prevent from doing a jumping action on flat ground - if ( pm->ps->pm_flags & PMF_FLYING ) { + if ( pm->ps->powerups[PW_FLIGHT] > 0 ) { // BFP - To stick to the movers if the player is near to them pm->ps->groundEntityNum = trace.entityNum; PM_AddTouchEnt( trace.entityNum ); @@ -1274,7 +1274,7 @@ static void PM_GroundTrace( void ) { // BFP - Handle when the player isn't flying if ( pm->ps->groundEntityNum == ENTITYNUM_NONE - && !( pm->ps->pm_flags & PMF_FLYING ) ) { + && pm->ps->powerups[PW_FLIGHT] <= 0 ) { // just hit the ground if ( pm->debugLevel ) { Com_Printf("%i:Land\n", c_pmove); @@ -1438,7 +1438,7 @@ static void PM_Footsteps( void ) { } // BFP - Avoid when flying - if ( pm->ps->pm_flags & PMF_FLYING ) { + if ( pm->ps->powerups[PW_FLIGHT] > 0 ) { return; } @@ -1578,7 +1578,7 @@ static void PM_WaterEvents( void ) { // FIXME? if (pml.previous_waterlevel && !pm->waterlevel) { PM_AddEvent( EV_WATER_LEAVE ); // BFP - Handle jumping animation when getting out of the water - if ( !( pm->ps->pm_flags & PMF_FLYING ) + if ( pm->ps->powerups[PW_FLIGHT] <= 0 && ( pm->ps->pm_flags & PMF_FALLING ) ) { pm->ps->pm_flags &= ~PMF_FALLING; FORCEJUMP_ANIM_HANDLING(); @@ -1682,7 +1682,7 @@ static void PM_TorsoAnimation( void ) { // BFP - Falling distantly from the ground if ( trace.fraction == 1.0 && !( pm->ps->pm_flags & PMF_NEARGROUND ) - && !( pm->ps->pm_flags & PMF_FLYING ) ) { + && pm->ps->powerups[PW_FLIGHT] <= 0 ) { pm->ps->pm_flags |= PMF_NEARGROUND; FORCEJUMP_ANIM_HANDLING(); TORSOSTATUS_ANIM_HANDLING( TORSO_STAND ); @@ -1696,7 +1696,7 @@ static void PM_TorsoAnimation( void ) { // Handle the player movement animation when stopping to fly and falling near to the ground // that happens when PMF_FALLING flag isn't handled correctly if ( ( pml.groundTrace.contents & MASK_PLAYERSOLID ) - && !( pm->ps->pm_flags & PMF_FLYING ) + && pm->ps->powerups[PW_FLIGHT] <= 0 && !( pm->ps->pm_flags & PMF_FALLING ) && ( pm->ps->pm_flags & PMF_NEARGROUND ) ) { pm->ps->pm_flags |= PMF_FALLING; @@ -1705,7 +1705,7 @@ static void PM_TorsoAnimation( void ) { // BFP - That happens when the player is landing nearly if ( !( pm->ps->pm_flags & PMF_NEARGROUND ) - && !( pm->ps->pm_flags & PMF_FLYING ) + && pm->ps->powerups[PW_FLIGHT] <= 0 && pm->ps->groundEntityNum == ENTITYNUM_NONE // hasn't touched the ground yet && ( pml.groundTrace.contents & MASK_PLAYERSOLID ) ) { @@ -1732,7 +1732,7 @@ PM_FlightAnimation */ static void PM_FlightAnimation( void ) { // BFP - Flight - if ( ( pm->ps->pm_flags & PMF_FLYING ) && pm->ps->pm_time <= 0 ) { + if ( pm->ps->powerups[PW_FLIGHT] > 0 && pm->ps->pm_time <= 0 ) { // make sure to handle the PMF flag pm->ps->pm_flags &= ~PMF_FALLING; @@ -1744,7 +1744,7 @@ static void PM_FlightAnimation( void ) { // BFP - Flight // Handle the player movement animation if trying to change quickly the direction of forward or backward if ( !( pml.groundTrace.contents & MASK_PLAYERSOLID ) && !( pm->ps->pm_flags & PMF_FALLING ) - && !( pm->ps->pm_flags & PMF_FLYING ) ) { + && pm->ps->powerups[PW_FLIGHT] <= 0 ) { // stops entering again here and don't change the animation to backwards/forward pm->ps->pm_flags |= PMF_FALLING; @@ -1777,7 +1777,7 @@ static void PM_KiChargeAnimation( void ) { // BFP - Ki Charge pm->ps->pm_time = 0; // do jump animation if it's falling if ( !( pml.groundTrace.contents & MASK_PLAYERSOLID ) - && !( pm->ps->pm_flags & PMF_FLYING ) + && pm->ps->powerups[PW_FLIGHT] <= 0 && ( pm->ps->pm_flags & PMF_FALLING ) && pm->waterlevel <= 1 ) { // Don't force inside the water pm->ps->pm_flags &= ~PMF_FALLING; // Handle PMF_FALLING when falling @@ -1806,15 +1806,15 @@ static void PM_KiChargeAnimation( void ) { // BFP - Ki Charge if ( !( pm->ps->pm_flags & PMF_KI_CHARGE ) ) { pm->ps->pm_time = 300; } - pm->ps->pm_flags &= ~PMF_KI_BOOST; + pm->ps->powerups[PW_HASTE] = 0; pm->ps->pm_flags |= PMF_KI_CHARGE; PM_ContinueTorsoAnim( TORSO_CHARGE ); PM_ContinueLegsAnim( LEGS_CHARGE ); } // handle the button to avoid toggling ki boost when already used "kiusetoggle" key bind - if ( ( pm->cmd.buttons & BUTTON_KI_USE ) && ( pm->ps->pm_flags & PMF_KI_BOOST ) ) { - pm->ps->pm_flags &= ~PMF_KI_BOOST; + if ( ( pm->cmd.buttons & BUTTON_KI_USE ) && ( pm->ps->powerups[PW_HASTE] > 0 ) ) { + pm->ps->powerups[PW_HASTE] = 0; } } @@ -1832,7 +1832,7 @@ static void PM_HitStunAnimation( void ) { // BFP - Hit stun // When the player doesn't have more ki, play hit stun animation if ( pm->ps->stats[STAT_KI] <= 0 && !( pm->ps->pm_flags & PMF_HITSTUN ) - || ( ( pm->ps->pm_flags & PMF_FLYING ) && pm->ps->stats[STAT_KI] <= 24 ) // BFP - TODO: Apply some timer if used any ki, if flying and has less ki, then hit stun (also BFP does that) + || ( pm->ps->powerups[PW_FLIGHT] > 0 && pm->ps->stats[STAT_KI] <= 24 ) // BFP - TODO: Apply some timer if used any ki, if flying and has less ki, then hit stun (also BFP does that) || ( ( pm->cmd.buttons & BUTTON_ATTACK ) && ( pm->ps->pm_flags & PMF_HITSTUN ) ) ) { pm->ps->pm_time = 1000; pm->ps->pm_flags |= PMF_HITSTUN; @@ -2123,7 +2123,7 @@ void PM_UpdateViewAngles( playerState_t *ps, const usercmd_t *cmd ) { // circularly clamp the angles with deltas for (i=0 ; i<3 ; i++) { temp = cmd->angles[i] + ps->delta_angles[i]; - if ( i == PITCH && !( ps->pm_flags & PMF_FLYING ) ) { // BFP - Avoid that when flying + if ( i == PITCH && ps->powerups[PW_FLIGHT] <= 0 ) { // BFP - Avoid that when flying // don't let the player look up or down more than 90 degrees if ( temp > 16000 ) { ps->delta_angles[i] = 16000 - cmd->angles[i]; @@ -2151,17 +2151,17 @@ static qboolean PM_EnableFlight( void ) { // BFP - Flight return qfalse; } - if ( !( pm->ps->pm_flags & PMF_FLYING ) ) { + if ( pm->ps->powerups[PW_FLIGHT] <= 0 ) { return qfalse; } // Handle the PMF flag if it's already flying - if ( ( pm->ps->pm_flags & PMF_FLYING ) && !( pm->ps->pm_flags & PMF_FALLING ) ) { + if ( pm->ps->powerups[PW_FLIGHT] > 0 && !( pm->ps->pm_flags & PMF_FALLING ) ) { return qtrue; } // do not proceed to the jump event while enables the flight in the charging status - if ( ( pm->ps->pm_flags & PMF_KI_CHARGE ) && ( pm->ps->pm_flags & PMF_FLYING ) ) { + if ( ( pm->ps->pm_flags & PMF_KI_CHARGE ) && pm->ps->powerups[PW_FLIGHT] > 0 ) { pm->ps->groundEntityNum = ENTITYNUM_NONE; return qfalse; } @@ -2191,7 +2191,7 @@ static void PM_KiCharge( void ) { // BFP - Ki Charge pm->cmd.buttons &= ~( BUTTON_ATTACK | BUTTON_KI_USE | BUTTON_MELEE | BUTTON_BLOCK | BUTTON_ENABLEFLIGHT ); } - if ( !( pm->ps->pm_flags & PMF_FLYING ) ) { + if ( pm->ps->powerups[PW_FLIGHT] <= 0 ) { pm->ps->pm_flags |= PMF_FALLING; // Handle PMF_FALLING flag } @@ -2213,8 +2213,8 @@ static void PM_HitStun( void ) { // BFP - Hit stun pm->cmd.buttons &= ~( BUTTON_MELEE | BUTTON_KI_USE | BUTTON_KI_CHARGE | BUTTON_BLOCK | BUTTON_ENABLEFLIGHT ); } - pm->ps->pm_flags &= ~PMF_FLYING; - pm->ps->pm_flags &= ~PMF_KI_BOOST; + pm->ps->powerups[PW_FLIGHT] = 0; + pm->ps->powerups[PW_HASTE] = 0; pm->ps->eFlags &= ~EF_AURA; // BFP - NOTE: BFP doesn't handle nothing the button directions when there's hit stun @@ -2332,8 +2332,8 @@ void PmoveSingle (pmove_t *pmove) { if ( pm->ps->pm_type >= PM_DEAD ) { // BFP - If player is dead, disable the following statuses - pm->ps->pm_flags &= ~PMF_FLYING; - pm->ps->pm_flags &= ~PMF_KI_BOOST; + pm->ps->powerups[PW_FLIGHT] = 0; + pm->ps->powerups[PW_HASTE] = 0; pm->ps->eFlags &= ~EF_AURA; // BFP - NOTE: disabled for notes, don't allow pressing these buttons diff --git a/source/game/bg_public.h b/source/game/bg_public.h index 0dedc07..02f3900 100644 --- a/source/game/bg_public.h +++ b/source/game/bg_public.h @@ -142,7 +142,6 @@ typedef enum { // pmove->pm_flags #define PMF_DUCKED 1 #define PMF_JUMP_HELD 2 -#define PMF_FLYING 4 // BFP - Flight // BFP - PMF_BACKWARDS_JUMP is unused // #define PMF_BACKWARDS_JUMP 8 // go into backwards land #define PMF_NEARGROUND 8 // BFP - Near ground check @@ -153,7 +152,7 @@ typedef enum { #define PMF_FALLING 32 // BFP - Falling status // BFP - PMF_TIME_KNOCKBACK is unused // #define PMF_TIME_KNOCKBACK 64 // pm_time is an air-accelerate only time -#define PMF_KI_BOOST 128 // BFP - Using Ki +#define PMF_KI_CHARGE 128 // BFP - Ki charge // BFP - PMF_TIME_WATERJUMP is unused // #define PMF_TIME_WATERJUMP 256 // pm_time is waterjump #define PMF_RESPAWNED 512 // clear after attack and jump buttons come up @@ -164,7 +163,6 @@ typedef enum { #define PMF_FOLLOW 4096 // spectate following another player // BFP - PMF_SCOREBOARD is unused // #define PMF_SCOREBOARD 8192 // spectate as a scoreboard -#define PMF_KI_CHARGE 8192 // BFP - Ki charge // BFP - TODO: Reuse the following flag (used on Team Arena), change name if it'll be used #define PMF_INVULEXPAND 16384 // invulnerability sphere set to full size // BFP - Last pm_flag after 32768. That's the limit of pm_flags, it can't reach more @@ -264,7 +262,8 @@ typedef enum { #define EF_AWARD_GAUNTLET 0x00000040 // draw a gauntlet sprite #define EF_NODRAW 0x00000080 // may have an event, but no model (unspawned items) #define EF_FIRING 0x00000100 // for lightning gun -#define EF_KAMIKAZE 0x00000200 +// BFP - No EF_KAMIKAZE flag +// #define EF_KAMIKAZE 0x00000200 #define EF_MOVER_STOP 0x00000400 // will push otherwise #define EF_AWARD_CAP 0x00000800 // draw the capture sprite #define EF_TALK 0x00001000 // draw a talk balloon @@ -273,22 +272,20 @@ typedef enum { #define EF_AWARD_IMPRESSIVE 0x00008000 // draw an impressive sprite #define EF_AWARD_DEFEND 0x00010000 // draw a defend sprite #define EF_AWARD_ASSIST 0x00020000 // draw a assist sprite -#define EF_AWARD_DENIED 0x00040000 // denied +// BFP - Unused EF flag +// #define EF_AWARD_DENIED 0x00040000 // denied #define EF_TEAMVOTED 0x00080000 // already cast a team vote -// BFP - NOTE: Should use PW_* instead using pm_flags? -// That goes for PW_HASTE and PW_FLIGHT, instead using PMF_KI_BOOST and PMF_FLYING - // NOTE: may not have more than 16 typedef enum { PW_NONE, PW_QUAD, PW_BATTLESUIT, - PW_HASTE, + PW_HASTE, // BFP - Used for ki boost status PW_INVIS, PW_REGEN, - PW_FLIGHT, + PW_FLIGHT, // BFP - Used for flying status PW_REDFLAG, PW_BLUEFLAG, @@ -355,9 +352,24 @@ typedef enum { #define EVENT_VALID_MSEC 300 +// BFP - NOTE: Take a look about original BFP events, the events (and event numbers) should be the same typedef enum { EV_NONE, + EV_MELEE_READY, // BFP - EV_MELEE_READY (10), preparing melee + EV_MELEE, // BFP - EV_MELEE (11), melee attack + + // EV_TIER_RESET, // EV_TIER_RESET (13), reset tier when the player respawns and changes to the default or a bit less ki energy? + + // BFP - EV_TIER_0-4 (14-18), when the player frags, increases their PL and obtains a new skill (in the last tier, transforms) + EV_TIER_0, + EV_TIER_1, + EV_TIER_2, + EV_TIER_3, + EV_TIER_4, + + EV_ENABLE_FLIGHT, // BFP - EV_ENABLE_FLIGHT (22), enable flight + EV_FOOTSTEP, EV_FOOTSTEP_METAL, EV_FOOTSPLASH, @@ -426,6 +438,7 @@ typedef enum { EV_SHOTGUN, EV_BULLET, // otherEntity is the shooter + EV_MISSILE_DETONATE, // BFP - EV_MISSILE_DETONATE (76), when ki attack explodes after some time EV_PAIN, EV_DEATH1, EV_DEATH2, diff --git a/source/game/g_active.c b/source/game/g_active.c index 2935917..afaf801 100644 --- a/source/game/g_active.c +++ b/source/game/g_active.c @@ -430,7 +430,7 @@ void ClientTimerActions( gentity_t *ent, int msec ) { } // BFP - Ki up/down when flying/ki use - if ( client->ps.pm_flags & PMF_FLYING ) { + if ( client->ps.powerups[PW_FLIGHT] > 0 ) { // BFP - TODO: Add cvar for flight cost @@ -447,7 +447,7 @@ void ClientTimerActions( gentity_t *ent, int msec ) { // BFP - if ki drops to 0, disable flight if ( client->ps.stats[STAT_KI] <= 0 ) { client->ps.stats[STAT_KI] = 0; - client->ps.pm_flags &= ~PMF_FLYING; + client->ps.powerups[PW_FLIGHT] = 0; // Com_Printf( "ki amount: %d\n", client->ps.stats[STAT_KI] ); } @@ -731,33 +731,36 @@ void ClientThink_real( gentity_t *ent ) { // set speed client->ps.speed = g_speed.value; - // BFP - Ki use has 2 options: "kiusetoggle" to toggle and "+button8" when key is being hold - if ( !( client->ps.pm_flags & PMF_HITSTUN ) - && ( ( ucmd->buttons & BUTTON_KI_USE ) // BFP - Using Ki - || ( client->ps.pm_flags & PMF_KI_BOOST ) ) ) { // BFP - When "kiusetoggle" is binded, enables/disables - if ( !( client->ps.pm_flags & PMF_FLYING ) ) { - client->ps.speed *= 2.5; + if ( client->ps.pm_type != PM_DEAD && client->ps.pm_type != PM_SPECTATOR ) { + + // BFP - Ki use has 2 options: "kiusetoggle" to toggle and "+button8" when key is being hold + if ( !( client->ps.pm_flags & PMF_HITSTUN ) + && ( ( ucmd->buttons & BUTTON_KI_USE ) // BFP - Using Ki + || client->ps.powerups[PW_HASTE] > 0 ) ) { // BFP - When "kiusetoggle" is binded, enables/disables + if ( client->ps.powerups[PW_FLIGHT] <= 0 ) { + client->ps.speed *= 2.5; + } + client->ps.eFlags |= EF_AURA; + } else { + if ( !( ucmd->buttons & BUTTON_KI_CHARGE ) ) { // BFP - If it's charging while it was using ki boost, don't remove the aura! + client->ps.eFlags &= ~EF_AURA; + } } - client->ps.eFlags |= EF_AURA; - } else { - if ( !( ucmd->buttons & BUTTON_KI_CHARGE ) ) { // BFP - If it's charging while it was using ki boost, don't remove the aura! - client->ps.eFlags &= ~EF_AURA; + + // BFP - Ki Charge + if ( ( ucmd->buttons & BUTTON_KI_CHARGE ) && client->ps.pm_time <= 0 + && ( client->ps.pm_flags & PMF_KI_CHARGE ) ) { + client->ps.eFlags |= EF_AURA; } - } - // BFP - Ki Charge - if ( ( ucmd->buttons & BUTTON_KI_CHARGE ) && client->ps.pm_time <= 0 - && ( client->ps.pm_flags & PMF_KI_CHARGE ) ) { - client->ps.eFlags |= EF_AURA; - } + if ( client->ps.powerups[PW_FLIGHT] > 0 ) { // BFP - Flight speed + client->ps.speed *= 2; + } + // BFP - TODO: When charging a ki attack like beam wave, consult FlyingThink and SpectatorThink if that's the case - if ( client->ps.pm_flags & PMF_FLYING ) { // BFP - Flight speed - client->ps.speed *= 1.5; + // BFP - Enable flight + FlyingThink( ent, ucmd ); // prevents client-server side issues when there's other client in-game } - // BFP - TODO: When charging a ki attack like beam wave, consult FlyingThink and SpectatorThink if that's the case - - // BFP - Enable flight - FlyingThink( ent, ucmd ); // prevents client-server side issues when there's other client in-game // BFP - no hook #if 0 @@ -990,6 +993,8 @@ void ClientEndFrame( gentity_t *ent ) { // turn off any expired powerups for ( i = 0 ; i < MAX_POWERUPS ; i++ ) { + // BFP - Flight and haste are skipped, these are treated for player status + if ( i == PW_FLIGHT || i == PW_HASTE ) continue; if ( ent->client->ps.powerups[ i ] < level.time ) { ent->client->ps.powerups[ i ] = 0; } diff --git a/source/game/g_client.c b/source/game/g_client.c index 59284a1..bf5c134 100644 --- a/source/game/g_client.c +++ b/source/game/g_client.c @@ -1080,7 +1080,7 @@ void ClientSpawn(gentity_t *ent) { client->pers.teamState.state = TEAM_ACTIVE; // always clear the kamikaze flag - ent->s.eFlags &= ~EF_KAMIKAZE; + // ent->s.eFlags &= ~EF_KAMIKAZE; // BFP - No EF_KAMIKAZE flag // toggle the teleport bit so the client knows to not lerp // and never clear the voted flag @@ -1148,9 +1148,9 @@ void ClientSpawn(gentity_t *ent) { client->ps.clientNum = index; - // TODO: BFP - list of 5 skills + // BFP - TODO: list of 5 skills - client->ps.stats[STAT_KI] = 1000; // BFP - give ki at start + client->ps.stats[STAT_KI] = 8160.0f; // BFP - TODO: give ki at start client->ps.stats[STAT_WEAPONS] = ( 1 << WP_MACHINEGUN ); client->ps.ammo[WP_MACHINEGUN] = 100; diff --git a/source/game/g_cmds.c b/source/game/g_cmds.c index 4cf81a9..c9c07fc 100644 --- a/source/game/g_cmds.c +++ b/source/game/g_cmds.c @@ -1604,10 +1604,10 @@ void Cmd_BFP_Fly_f( gentity_t* ent ) { // BFP - Flight if ( ent->client->ps.pm_type != PM_DEAD ) { // do not play the sound in the charging status - if ( !( ent->client->ps.pm_flags & PMF_FLYING ) && !( ent->client->ps.pm_flags & PMF_KI_CHARGE ) ) { - G_AddEvent( ent, EV_JUMP, 0 ); // play jump sound + if ( ent->client->ps.powerups[PW_FLIGHT] <= 0 && !( ent->client->ps.pm_flags & PMF_KI_CHARGE ) ) { + G_AddEvent( ent, EV_ENABLE_FLIGHT, 0 ); // play the sound } - ent->client->ps.pm_flags ^= PMF_FLYING; + ent->client->ps.powerups[PW_FLIGHT] ^= 1; } } @@ -1640,7 +1640,7 @@ void Cmd_BFP_SetKiUse_f( gentity_t* ent ) { // BFP - Set Ki use // BFP - NOTE: Originally, an unfinished command... #if 0 if ( ent->client->ps.pm_type != PM_DEAD ) { - ent->client->ps.pm_flags |= PMF_KI_BOOST; + ent->client->ps.powerups[PW_HASTE] = 1; } #endif } @@ -1653,7 +1653,7 @@ Cmd_BFP_KiUseToggle_f void Cmd_BFP_KiUseToggle_f( gentity_t* ent ) { // BFP - Ki use toggle if ( ent->client->ps.pm_type != PM_DEAD ) { - ent->client->ps.pm_flags ^= PMF_KI_BOOST; + ent->client->ps.powerups[PW_HASTE] ^= 1; } } @@ -1666,7 +1666,7 @@ void Cmd_BFP_SetKiIdle_f( gentity_t* ent ) { // BFP - Set Ki idle // BFP - NOTE: originally... Ki idling means disabling the ki? Sounds like it isn't operating... if ( ent->client->ps.pm_type != PM_DEAD ) { - ent->client->ps.pm_flags &= ~PMF_KI_BOOST; + ent->client->ps.powerups[PW_HASTE] = 0; } } diff --git a/source/game/g_combat.c b/source/game/g_combat.c index c9cd729..e75b1da 100644 --- a/source/game/g_combat.c +++ b/source/game/g_combat.c @@ -160,6 +160,8 @@ void GibEntity( gentity_t *self, int killer ) { gentity_t *ent; int i; +// BFP - No EF_KAMIKAZE flag +#if 0 //if this entity still has kamikaze if (self->s.eFlags & EF_KAMIKAZE) { // check if there is a kamikaze timer around for this owner @@ -175,6 +177,7 @@ void GibEntity( gentity_t *self, int killer ) { break; } } +#endif G_AddEvent( self, EV_GIB_PLAYER, killer ); self->takedamage = qfalse; self->s.eType = ET_INVISIBLE; @@ -761,9 +764,9 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, damage *= 0.5; } -// BFP - TODO: Make hit stun received from melee attack with PMF_KI_BOOST +// BFP - TODO: Make hit stun received from melee attack with PW_HASTE #if 0 - if ( g_hitStun.integer >= 1 && ( attacker->client->ps.pm_flags & PMF_KI_BOOST ) + if ( g_hitStun.integer >= 1 && ( attacker->client->ps.powerups[PW_HASTE] > 0 ) && targ != attacker && !OnSameTeam (targ, attacker) ) { attacker->client->ps.hitStunTime = -3; // just an idea, enable the hit stun with a conditional of == -3 } diff --git a/source/game/g_items.c b/source/game/g_items.c index 0dc67ba..5c81053 100644 --- a/source/game/g_items.c +++ b/source/game/g_items.c @@ -120,9 +120,12 @@ int Pickup_Holdable( gentity_t *ent, gentity_t *other ) { other->client->ps.stats[STAT_HOLDABLE_ITEM] = ent->item - bg_itemlist; +// BFP - No EF_KAMIKAZE flag +#if 0 if( ent->item->giTag == HI_KAMIKAZE ) { other->client->ps.eFlags |= EF_KAMIKAZE; } +#endif return RESPAWN_HOLDABLE; } diff --git a/source/game/g_target.c b/source/game/g_target.c index 062d058..fccdb42 100644 --- a/source/game/g_target.c +++ b/source/game/g_target.c @@ -65,6 +65,19 @@ takes away all the activators powerups. Used to drop flight powerups into death puts. */ void Use_target_remove_powerups( gentity_t *ent, gentity_t *other, gentity_t *activator ) { + // BFP - To keep flight and ki boost statuses + int keepPW[MAX_POWERUPS]; + + // BFP - NOTE: Originally, on BFP, they used PMF flags to keep the statuses, + // as long as these weren't affected from that, + // when the powerups variable is being reset entering in a target_remove_powerups zone. + // BFP original solution was ugly, because the client side visual of CG_PlayerAngles + // didn't handle the positions of the legs. + // This solution here is better than the original one. + + keepPW[PW_FLIGHT] = activator->client->ps.powerups[PW_FLIGHT]; + keepPW[PW_HASTE] = activator->client->ps.powerups[PW_HASTE]; + if( !activator->client ) { return; } @@ -78,6 +91,10 @@ void Use_target_remove_powerups( gentity_t *ent, gentity_t *other, gentity_t *ac } memset( activator->client->ps.powerups, 0, sizeof( activator->client->ps.powerups ) ); + + // BFP - Keep the statuses! + activator->client->ps.powerups[PW_FLIGHT] = keepPW[PW_FLIGHT]; + activator->client->ps.powerups[PW_HASTE] = keepPW[PW_HASTE]; } void SP_target_remove_powerups( gentity_t *ent ) {