diff --git a/reaction/cgame/cg_draw.c b/reaction/cgame/cg_draw.c index e294cc2b..2b8b4dea 100644 --- a/reaction/cgame/cg_draw.c +++ b/reaction/cgame/cg_draw.c @@ -2776,19 +2776,22 @@ static void CG_DrawDamageBlend() float dmg; vec4_t damageColor; - //Leave if no true damage, disabled, or ragepro - if ( !cg.rq3_trueDamage || !cg_RQ3_painblend.integer || - cgs.glconfig.hardwareType == GLHW_RAGEPRO) - { - return; - } + //CG_Printf("CG_DrawDamageBlend: trueDamage (%i)\n", cg.rq3_trueDamage); + //Leave if no true damage, disabled, or ragepro + if (!cg_RQ3_painblend.integer) + return; + + if ( !cg.rq3_trueDamage || cgs.glconfig.hardwareType == GLHW_RAGEPRO) + return; + //Clamp blend time if (cg.rq3_blendTime > MAX_BLEND_TIME) cg.rq3_blendTime = MAX_BLEND_TIME; //Reset if we've gone past our blendTime - if (cg.time - cg.damageTime > cg.rq3_blendTime) { + if (cg.time - cg.damageTime > cg.rq3_blendTime) + { //cg.rq3_trueDamage = 0; cg.rq3_blendTime = 0; return; diff --git a/reaction/cgame/cg_effects.c b/reaction/cgame/cg_effects.c index 006176af..d31ee721 100644 --- a/reaction/cgame/cg_effects.c +++ b/reaction/cgame/cg_effects.c @@ -471,7 +471,7 @@ Based on bubble trail code + other stuff ================= */ #define MAX_SPRAY_BURSTS 16 -void CG_BleedSpray ( vec3_t start, vec3_t end, int entityNum ) +void CG_BleedSpray ( vec3_t start, vec3_t end, int entityNum, int numBursts ) { //vec3_t dir; vec3_t trueEnd; @@ -484,11 +484,15 @@ void CG_BleedSpray ( vec3_t start, vec3_t end, int entityNum ) int i; int spacing = 30; int bloodCount = 0; - + if ( !cg_blood.integer ) { return; } + //Clamp number so we don't generate too many blood entities + if (numBursts > MAX_SPRAY_BURSTS) + numBursts = MAX_SPRAY_BURSTS; + VectorCopy (end, move); VectorSubtract (end, start, vec); @@ -513,10 +517,10 @@ void CG_BleedSpray ( vec3_t start, vec3_t end, int entityNum ) VectorScale (vec, spacing, vec); - for ( ; i < len; i += spacing ) + for ( ; i < len ; i += spacing ) { //restrict amount of spurts - if (bloodCount++ > MAX_SPRAY_BURSTS) + if (bloodCount++ > numBursts) break; blood = CG_SmokePuff(move, velocity, 8, diff --git a/reaction/cgame/cg_event.c b/reaction/cgame/cg_event.c index 88c837e6..2a3fa9b3 100644 --- a/reaction/cgame/cg_event.c +++ b/reaction/cgame/cg_event.c @@ -1943,20 +1943,20 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) { case EV_RQ3_SOUND: DEBUGNAME("EV_RQ3_SOUND"); - //CG_Printf("EV_RQ3_SOUND: %d\n", es->eventParm); switch (es->eventParm) { case RQ3_SOUND_KICK: - //CG_Printf("EV_RQ3_SOUND: Kick\n"); trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.kickSound); break; + //Elder: handled in EV_HEADSHOT now + /* case RQ3_SOUND_HEADSHOT: //CG_Printf("EV_RQ3_SOUND: Headshot\n"); //Elder: extra blood - synched with sound //CG_Bleed( position, es->number ); trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.headshotSound); break; + */ case RQ3_SOUND_LCA: - //CG_Printf("EV_RQ3_SOUND: Lights, Camera, Action\n"); //Global sound trap_S_StartSound( NULL, cg.snap->ps.clientNum, CHAN_AUTO, cgs.media.lcaSound); break; @@ -2090,6 +2090,16 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) { break; } + case EV_HEADSHOT: + //Elder: headshot spray + sound + DEBUGNAME("EV_HEADSHOT"); + //trap_S_StartSound( es->pos.trBase, es->number, CHAN_AUTO, cgs.media.headshotSound); + trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.headshotSound); + ByteToDir(es->eventParm, dir); + VectorAdd(es->pos.trBase, dir, dir); + CG_BleedSpray(es->pos.trBase, dir, es->otherEntityNum, 8); + break; + case EV_PAIN: // local player sounds are triggered in CG_CheckLocalSounds, // so ignore events on the player diff --git a/reaction/cgame/cg_local.h b/reaction/cgame/cg_local.h index db186062..b210a075 100644 --- a/reaction/cgame/cg_local.h +++ b/reaction/cgame/cg_local.h @@ -877,6 +877,7 @@ typedef struct { sfxHandle_t lensSound; //Elder: sniper lens zoom sfxHandle_t silencerSound; sfxHandle_t kevlarHitSound; + sfxHandle_t weapToggleSound; sfxHandle_t quadSound; sfxHandle_t tracerSound; @@ -1503,7 +1504,7 @@ void CG_BigExplode( vec3_t playerOrigin ); void CG_BreakGlass( vec3_t playerOrigin, int glassParm, int type ); void CG_Bleed( vec3_t origin, int entityNum ); //Elder: for SSG shots -void CG_BleedSpray ( vec3_t origin, vec3_t dir, int entityNum ); +void CG_BleedSpray ( vec3_t start, vec3_t end, int entityNum, int numBursts ); localEntity_t *CG_MakeExplosion( vec3_t origin, vec3_t dir, qhandle_t hModel, qhandle_t shader, int msec, diff --git a/reaction/cgame/cg_main.c b/reaction/cgame/cg_main.c index 8c94d050..3c9cc25e 100644 --- a/reaction/cgame/cg_main.c +++ b/reaction/cgame/cg_main.c @@ -644,6 +644,7 @@ static void CG_RegisterSounds( void ) { cgs.media.lcaSound = trap_S_RegisterSound( "sound/misc/lca.wav", qfalse); cgs.media.silencerSound = trap_S_RegisterSound( "sound/misc/silencershot.wav", qfalse); cgs.media.kevlarHitSound = trap_S_RegisterSound( "sound/misc/vest.wav", qfalse); + cgs.media.weapToggleSound = trap_S_RegisterSound( "sound/misc/click.wav", qfalse); #ifdef MISSIONPACK diff --git a/reaction/cgame/cg_playerstate.c b/reaction/cgame/cg_playerstate.c index 2c3c8165..686b1d1a 100644 --- a/reaction/cgame/cg_playerstate.c +++ b/reaction/cgame/cg_playerstate.c @@ -362,7 +362,8 @@ void CG_CheckLocalSounds( playerState_t *ps, playerState_t *ops ) { if (cg_RQ3_anouncer.integer == 1) trap_S_StartLocalSound( cgs.media.hitSound, CHAN_LOCAL_SOUND ); } #else - if (cg_RQ3_anouncer.integer == 1) trap_S_StartLocalSound( cgs.media.hitSound, CHAN_LOCAL_SOUND ); + //Elder: completely remove cowbell sound + //if (cg_RQ3_anouncer.integer == 1) trap_S_StartLocalSound( cgs.media.hitSound, CHAN_LOCAL_SOUND ); #endif } else if ( ps->persistant[PERS_HITS] < ops->persistant[PERS_HITS] ) { if (cg_RQ3_anouncer.integer == 1) trap_S_StartLocalSound( cgs.media.hitTeamSound, CHAN_LOCAL_SOUND ); diff --git a/reaction/cgame/cg_weapons.c b/reaction/cgame/cg_weapons.c index 34de5042..d20fb332 100644 --- a/reaction/cgame/cg_weapons.c +++ b/reaction/cgame/cg_weapons.c @@ -670,6 +670,10 @@ void CG_RegisterWeapon( int weaponNum ) { MAKERGB( weaponInfo->flashDlightColor, 1, 1, 0 ); weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/m3/m3fire.wav", qfalse ); weaponInfo->ejectBrassFunc = CG_ShotgunEjectBrass; + Com_sprintf( filename, sizeof(filename), "models/weapons2/m3/animation.cfg" ); + if ( !CG_ParseWeaponAnimFile(filename, weaponInfo) ) { + Com_Printf("Failed to load weapon animation file %s\n", filename); + } break; case WP_AKIMBO: @@ -758,24 +762,28 @@ CG_MapTorsoToWeaponFrame */ static int CG_MapTorsoToWeaponFrame( clientInfo_t *ci, int frame ) { - // change weapon - if ( frame >= ci->animations[TORSO_DROP].firstFrame - && frame < ci->animations[TORSO_DROP].firstFrame + 9 ) { - return frame - ci->animations[TORSO_DROP].firstFrame + 6; - } + //Elder: another hack + if (ci->curWeapon != WP_PISTOL && ci->curWeapon != WP_M3) + { + // change weapon + if ( frame >= ci->animations[TORSO_DROP].firstFrame + && frame < ci->animations[TORSO_DROP].firstFrame + 9 ) { + return frame - ci->animations[TORSO_DROP].firstFrame + 6; + } + - // stand attack - if ( frame >= ci->animations[TORSO_ATTACK].firstFrame - && frame < ci->animations[TORSO_ATTACK].firstFrame + 6 ) { - return 1 + frame - ci->animations[TORSO_ATTACK].firstFrame; - } + // stand attack + if ( frame >= ci->animations[TORSO_ATTACK].firstFrame + && frame < ci->animations[TORSO_ATTACK].firstFrame + 6 ) { + return 1 + frame - ci->animations[TORSO_ATTACK].firstFrame; + } - // stand attack 2 - if ( frame >= ci->animations[TORSO_ATTACK2].firstFrame - && frame < ci->animations[TORSO_ATTACK2].firstFrame + 6 ) { - return 1 + frame - ci->animations[TORSO_ATTACK2].firstFrame; + // stand attack 2 + if ( frame >= ci->animations[TORSO_ATTACK2].firstFrame + && frame < ci->animations[TORSO_ATTACK2].firstFrame + 6 ) { + return 1 + frame - ci->animations[TORSO_ATTACK2].firstFrame; + } } - return 0; } @@ -1927,6 +1935,7 @@ void CG_Weapon_f( void ) { else { //do weapon select sound + trap_S_StartLocalSound( cgs.media.weapToggleSound, CHAN_ITEM); } trap_SendClientCommand("weapon"); //Elder: added to get out of function at this point @@ -2096,6 +2105,7 @@ void CG_FireWeapon( centity_t *cent, int weapModification ) { } } } + //Elder: TODO: eject sync with animation for M3 and only eject for HC when reloading // do brass ejection if ( weap->ejectBrassFunc && cg_brassTime.integer > 0 ) { weap->ejectBrassFunc( cent ); @@ -2853,7 +2863,7 @@ void CG_Bullet( vec3_t end, int sourceEntityNum, vec3_t normal, if ( flesh ) { //Elder: added if ( armorPiercing && CG_CalcMuzzlePoint( sourceEntityNum, start)) - CG_BleedSpray(start, end, fleshEntityNum); + CG_BleedSpray(start, end, fleshEntityNum, 16); else CG_Bleed( end, fleshEntityNum ); } else { diff --git a/reaction/game/bg_misc.c b/reaction/game/bg_misc.c index 6fdeb56d..b6531fbe 100644 --- a/reaction/game/bg_misc.c +++ b/reaction/game/bg_misc.c @@ -1346,6 +1346,7 @@ char *eventnames[] = { "EV_HANDCANNON", "EV_BULLET", // otherEntity is the shooter + "EV_HEADSHOT", // Elder: spray like SSG shot "EV_PAIN", "EV_DEATH1", "EV_DEATH2", diff --git a/reaction/game/bg_pmove.c b/reaction/game/bg_pmove.c index ea5891dd..954daf33 100644 --- a/reaction/game/bg_pmove.c +++ b/reaction/game/bg_pmove.c @@ -1880,6 +1880,9 @@ static void PM_TorsoAnimation( void ) { } // QUARANTINE - Weapon Animation // Should always draw the weapon when it is just ready + //Elder: temp hack + if (pm->ps->weapon == WP_PISTOL || pm->ps->weapon == WP_M3) + PM_ContinueWeaponAnim( WP_ANIM_IDLE ); // PM_ContinueWeaponAnim( WP_ANIM_READY ); return; @@ -1895,9 +1898,17 @@ PM_WeaponAnimation static void PM_WeaponAnimation( void ) { if (pm->ps->weaponstate == WEAPON_RELOADING) { - PM_StartWeaponAnim( WP_ANIM_RELOAD ); - pm->ps->weaponstate = WEAPON_READY; + PM_ContinueWeaponAnim( WP_ANIM_RELOAD ); + //Elder - using the above now + //PM_StartWeaponAnim( WP_ANIM_RELOAD ); + //Elder: only reason it's like this is b/c reloading causes WEAPON_DROPPING + //and we can't see the weapon -- but this screws with fast-reloads + //Remedy is to not call a TORSO_DROP in Cmd_Reload + //pm->ps->weaponstate = WEAPON_READY; } + else if (pm->ps->weaponstate == WEAPON_READY) + PM_ContinueWeaponAnim( WP_ANIM_IDLE ); + return; } @@ -2015,7 +2026,8 @@ static void PM_Weapon( void ) { // QUARANTINE - Weapon Animation // Should always draw the weapon when it is just ready // PM_StartWeaponAnim( WP_ANIM_READY ); - + if (pm->ps->weapon == WP_PISTOL || pm->ps->weapon == WP_M3) + PM_StartWeaponAnim( WP_ANIM_IDLE ); return; } @@ -2084,26 +2096,7 @@ static void PM_Weapon( void ) { } else { PM_StartTorsoAnim( TORSO_ATTACK ); } - // QUARANTINE - Weapon animations - // This should change pm->ps->generic1 so we can animate - PM_StartWeaponAnim( WP_ANIM_FIRE ); - - // Elder: the client side portion is in - // Homer: if weapon can set to be burst mode, check for burst value - // M4 - //if ( pm->ps->weapon == WP_M4 && pm->ps->stats[STAT_BURST] > 2 ) { - //return; - //} - // MP5 - //if ( pm->ps->weapon == WP_MP5 && pm->ps->stats[STAT_BURST] > 2 ) { - //return; - //} - // MK23 - //if ( pm->ps->weapon == WP_PISTOL && pm->ps->stats[STAT_BURST] > 0 ) { - //return; - //} - // end Homer - + pm->ps->weaponstate = WEAPON_FIRING; // check for out of ammo @@ -2113,6 +2106,10 @@ static void PM_Weapon( void ) { return; } + // QUARANTINE - Weapon animations + // This should change pm->ps->generic1 so we can animate + PM_StartWeaponAnim( WP_ANIM_FIRE ); + //Elder: M4 kick code //ent->client->ps.delta_angles[0] = ANGLE2SHORT(SHORT2ANGLE(ent->client->ps.delta_angles[0]) - 0.7); @@ -2660,7 +2657,7 @@ void PmoveSingle (pmove_t *pmove) { //weapon animations(rq3 specific) //Elder: hack to avoid messing up fast-reloads - if (pm->ps->weapon == WP_PISTOL) + if (pm->ps->weapon == WP_PISTOL || pm->ps->weapon == WP_M3) PM_WeaponAnimation(); // torso animation diff --git a/reaction/game/bg_public.h b/reaction/game/bg_public.h index 9cf2818c..2223f54b 100644 --- a/reaction/game/bg_public.h +++ b/reaction/game/bg_public.h @@ -226,7 +226,7 @@ typedef enum { //Elder: reload delays //Also kinda "derived" from the AQ2 source -#define RQ3_PISTOL_RELOAD_DELAY 1100 +#define RQ3_PISTOL_RELOAD_DELAY 2100 #define RQ3_M4_RELOAD_DELAY 1900 #define RQ3_MP5_RELOAD_DELAY 1800 #define RQ3_HANDCANNON_RELOAD_DELAY 2100 @@ -379,6 +379,10 @@ typedef enum { //WP_ANIM_READY, WP_ANIM_FIRE, WP_ANIM_RELOAD, + WP_ANIM_IDLE, + //WP_ANIM_ACTIVATE, + //WP_ANIM_DISARM, + //WP_ANIM_FIRE2, MAX_WEAPON_ANIMATIONS } wpAnimNumber_t; @@ -708,6 +712,7 @@ typedef enum { EV_HANDCANNON, EV_BULLET, // otherEntity is the shooter + EV_HEADSHOT, // Elder: spray like SSG shot EV_PAIN, EV_DEATH1, EV_DEATH2, diff --git a/reaction/game/g_active.c b/reaction/game/g_active.c index fbead069..e9ecfde6 100644 --- a/reaction/game/g_active.c +++ b/reaction/game/g_active.c @@ -128,13 +128,17 @@ void P_DamageFeedback( gentity_t *player ) { //Elder: headshot sound case LOCATION_HEAD: case LOCATION_FACE: - tent = G_TempEntity2(client->ps.origin, EV_RQ3_SOUND, RQ3_SOUND_HEADSHOT); + //Elder: do nothing -- sound is handled in g_combat.c again + //tent = G_TempEntity2(client->ps.origin, EV_RQ3_SOUND, RQ3_SOUND_HEADSHOT); //Elder: takes more bandwidth but guarantees a headshot sound //G_Sound(player, CHAN_AUTO, G_SoundIndex("sound/misc/headshot.wav")); //G_AddEvent ( player, EV_RQ3_SOUND, RQ3_SOUND_HEADSHOT); break; + /* case LOCATION_CHEST: + case LOCATION_SHOULDER: //Play metal impact if vest was hit + if (client->damage_vest == qtrue) { tent = G_TempEntity2(client->ps.origin, EV_RQ3_SOUND, RQ3_SOUND_KEVLARHIT); @@ -143,6 +147,7 @@ void P_DamageFeedback( gentity_t *player ) { else G_AddEvent( player, EV_PAIN, player->health ); break; + */ default: G_AddEvent( player, EV_PAIN, player->health ); break; @@ -675,6 +680,7 @@ void ClientEvents( gentity_t *ent, int oldEventSequence ) { ent->pain_debounce_time = level.time + 200; // no normal pain sound //Elder: added so we can trigger AQ2 pain blends ent->client->ps.damageEvent++; + ent->client->ps.damageCount += damage; G_Damage (ent, NULL, NULL, NULL, NULL, damage, 0, MOD_FALLING); break; @@ -693,6 +699,7 @@ void ClientEvents( gentity_t *ent, int oldEventSequence ) { ent->pain_debounce_time = level.time + 200; // no normal pain sound //Elder: added so we can trigger AQ2 pain blends ent->client->ps.damageEvent++; + ent->client->ps.damageCount += damage; G_Damage (ent, NULL, NULL, NULL, NULL, damage, 0, MOD_FALLING); break; @@ -1569,29 +1576,9 @@ void ClientEndFrame( gentity_t *ent ) { if ( bg_itemlist[ent->client->ps.stats[STAT_HOLDABLE_ITEM]].giTag == HI_LASER ) { - //Disable laser if switching weapons, bandaging, etc. - if (ent->client->lasersight && - (ent->client->ps.weaponstate == WEAPON_DROPPING || - ent->client->ps.weaponstate == WEAPON_RELOADING)) - { - Laser_Gen(ent, qfalse); - } - //Using M4/MP5/MK23 but not on yet so turn it on - else if (ent->client->lasersight == NULL && - (ent->client->ps.weapon == WP_M4 || - ent->client->ps.weapon == WP_MP5 || - ent->client->ps.weapon == WP_PISTOL)) - { + //Try to turn the laser on if it's off + if (ent->client->lasersight == NULL) Laser_Gen(ent, qtrue); - } - //Not using M4/MP5/MK23 -- turn it off - else if (ent->client->lasersight && - !( ent->client->ps.weapon == WP_M4 || - ent->client->ps.weapon == WP_MP5 || - ent->client->ps.weapon == WP_PISTOL)) - { - Laser_Gen(ent, qfalse); - } } diff --git a/reaction/game/g_cmds.c b/reaction/game/g_cmds.c index 01df81a7..b9ca1856 100644 --- a/reaction/game/g_cmds.c +++ b/reaction/game/g_cmds.c @@ -1829,6 +1829,8 @@ void Cmd_Reload( gentity_t *ent ) { if (ent->client->fastReloads) { //Fast reload //G_Printf("Using fast reloads\n"); + ent->client->ps.generic1 = ( ( ent->client->ps.generic1 & ANIM_TOGGLEBIT ) + ^ ANIM_TOGGLEBIT ) | WP_ANIM_RELOAD; delay = RQ3_M3_FAST_RELOAD_DELAY; ent->client->fastReloads = 1; } @@ -1993,7 +1995,8 @@ void Cmd_Reload( gentity_t *ent ) { //ent->client->ps.weaponstate = WEAPON_RELOADING; ent->client->ps.weaponstate = WEAPON_RELOADING; //Elder: temporary hack to drop weapon if it's not the MK23 - if (ent->client->ps.weapon != WP_PISTOL) + if (ent->client->ps.weapon != WP_PISTOL && + ent->client->ps.weapon != WP_M3) { ent->client->ps.torsoAnim = ( ( ent->client->ps.torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | TORSO_DROP; @@ -2354,6 +2357,7 @@ void Cmd_DropItem_f( gentity_t *ent ) if (ent->client->numClips[WP_GRENADE] > RQ3_GRENADE_MAXCLIP) ent->client->numClips[WP_GRENADE] = RQ3_GRENADE_MAXCLIP; } + //Force laser off else if (bg_itemlist[ent->client->ps.stats[STAT_HOLDABLE_ITEM]].giTag == HI_LASER) Laser_Gen(ent, qfalse); diff --git a/reaction/game/g_combat.c b/reaction/game/g_combat.c index f49aabfe..3f32deaf 100644 --- a/reaction/game/g_combat.c +++ b/reaction/game/g_combat.c @@ -1135,10 +1135,9 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, int knockback; int max; int bleeding = 0; // damage causes bleeding - int instant_dam = 1; - vec3_t bulletPath; + vec3_t bulletPath; vec3_t bulletAngle; //Elder: added for M3 and Pistols @@ -1151,6 +1150,9 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, int bulletHeight; int bulletRotation; // Degrees rotation around client. int impactRotation; + + gentity_t *tent; + #ifdef MISSIONPACK vec3_t bouncedir, impactpoint; #endif @@ -1621,44 +1623,34 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, trap_SendServerCommand( attacker-g_entities, va("print \"You hit %s^7\n\"", targ->client->pers.netname)); } else */ - if (1) + if (1) { switch ( targ->client->lasthurt_location & ~(LOCATION_BACK | LOCATION_LEFT | LOCATION_RIGHT | LOCATION_FRONT) ) { - case (LOCATION_HEAD): - { + case LOCATION_HEAD: + case LOCATION_FACE: + //Elder: reusing line so we don't have to declare more variables + line[0] = 0; + line[1] = 0; + line[2] = 20; + trap_SendServerCommand( attacker-g_entities, va("print \"You hit %s^7 in the head.\n\"", targ->client->pers.netname)); trap_SendServerCommand( targ-g_entities, va("print \"Head Damage.\n\"")); - //Elder: headshot sound moved to g_active.c - //if ( mod != MOD_KNIFE && mod != MOD_KNIFE_THROWN ) { - //G_Printf("play headshot sound\n"); - //G_AddEvent ( targ, EV_RQ3_SOUND, RQ3_SOUND_HEADSHOT); - //} + + //Setup headshot spray and sound + //Only do if not knife or SSG -- SSG has its own trail of blood + if (mod != MOD_SNIPER && mod != MOD_KNIFE && mode != MOD_KNIFE_THROWN) + { + VectorAdd(targ->s.pos.trBase, line, line); + tent = G_TempEntity(line, EV_HEADSHOT); + tent->s.eventParm = DirToByte(dir); + tent->s.otherEntityNum = targ->s.clientNum; + } take *= 1.8; //+ 1; break; - } - case (LOCATION_FACE): - { - trap_SendServerCommand( attacker-g_entities, va("print \"You hit %s^7 in the head.\n\"", targ->client->pers.netname)); - trap_SendServerCommand( targ-g_entities, va("print \"Head Damage.\n\"")); - //Elder: headshot sound - no events here - //if ( mod != MOD_KNIFE && mod != MOD_KNIFE_THROWN ) { - //G_Printf("play headshot sound\n"); - //G_AddEvent ( targ, EV_RQ3_SOUND, RQ3_SOUND_HEADSHOT); - //} - take *= 1.8; //+ 1; - break; - } - case (LOCATION_SHOULDER): - { - trap_SendServerCommand( attacker-g_entities, va("print \"You hit %s^7 in the chest.\n\"", targ->client->pers.netname)); - trap_SendServerCommand( targ-g_entities, va("print \"Chest Damage.\n\"")); - take *= 0.65; - break; - } - case (LOCATION_CHEST): - { + case LOCATION_SHOULDER: + case LOCATION_CHEST: //Vest stuff if (bg_itemlist[targ->client->ps.stats[STAT_HOLDABLE_ITEM]].giTag == HI_KEVLAR) { @@ -1676,8 +1668,10 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, instant_dam = 1; bleeding = 0; } + //Kevlar sound + tent = G_TempEntity2(targ->s.pos.trBase, EV_RQ3_SOUND, RQ3_SOUND_KEVLARHIT); //Elder: flag for sound in feedback - targ->client->damage_vest = qtrue; + //targ->client->damage_vest = qtrue; } else { @@ -1686,38 +1680,19 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, take *= 0.65; } break; - } - case (LOCATION_STOMACH): - { + case LOCATION_STOMACH: + case LOCATION_GROIN: trap_SendServerCommand( attacker-g_entities, va("print \"You hit %s^7 in the stomach.\n\"", targ->client->pers.netname)); trap_SendServerCommand( targ-g_entities, va("print \"Stomach Damage.\n\"")); take *= 0.4; break; - } - case (LOCATION_GROIN): - { - trap_SendServerCommand( attacker-g_entities, va("print \"You hit %s^7 in the stomach.\n\"", targ->client->pers.netname)); - trap_SendServerCommand( targ-g_entities, va("print \"Stomach Damage.\n\"")); - take *= 0.4; - break; - } - case (LOCATION_LEG): - { - trap_SendServerCommand( attacker-g_entities, va("print \"You hit %s^7 in the leg.\n\"", targ->client->pers.netname)); - trap_SendServerCommand( targ-g_entities, va("print \"Leg Damage.\n\"")); - take *= 0.25; - targ->client->ps.stats[STAT_RQ3] |= RQ3_LEGDAMAGE; - break; - } - case (LOCATION_FOOT): - { + case LOCATION_LEG: + case LOCATION_FOOT: trap_SendServerCommand( attacker-g_entities, va("print \"You hit %s^7 in the leg.\n\"", targ->client->pers.netname)); trap_SendServerCommand( targ-g_entities, va("print \"Leg Damage.\n\"")); targ->client->ps.stats[STAT_RQ3] |= RQ3_LEGDAMAGE; take *= 0.25; - break; - } - + break; } } // G_Printf("In loc damage: %d outgoing\n",take); diff --git a/reaction/game/g_items.c b/reaction/game/g_items.c index d412d54d..1169c798 100644 --- a/reaction/game/g_items.c +++ b/reaction/game/g_items.c @@ -181,7 +181,7 @@ int Pickup_Holdable( gentity_t *ent, gentity_t *other ) { //other->client->ps.stats[STAT_HOLDABLE_ITEM] = ent->item->giTag; other->client->uniqueItems++; - //Fire up the laser if it's picked up + //Try to fire up the laser if it's picked up if (ent->item->giTag == HI_LASER) { Laser_Gen(other, qtrue); diff --git a/reaction/game/g_local.h b/reaction/game/g_local.h index 05547f40..927fc1a0 100644 --- a/reaction/game/g_local.h +++ b/reaction/game/g_local.h @@ -296,7 +296,7 @@ struct gclient_s { int damage_knockback; // impact damage vec3_t damage_from; // origin for vector calculation qboolean damage_fromWorld; // if true, don't use the damage_from vector - qboolean damage_vest; // Elder: if true, play the vest-hit sound + //qboolean damage_vest; // Elder: if true, play the vest-hit sound int accurateCount; // for "impressive" reward sound diff --git a/reaction/game/g_weapon.c b/reaction/game/g_weapon.c index 9e1f55c8..ed0cf7f1 100644 --- a/reaction/game/g_weapon.c +++ b/reaction/game/g_weapon.c @@ -2100,8 +2100,22 @@ void Laser_Gen( gentity_t *ent, qboolean enabled ) { //Elder: force it to laser int type = 1; + // First, if it's not the right weapon, leave + if ( ent->client->ps.weapon != WP_PISTOL && + ent->client->ps.weapon != WP_MP5 && + ent->client->ps.weapon != WP_M4 ) + { + //Kill laser if it exists + if (ent->client->lasersight) + { + G_FreeEntity( ent->client->lasersight ); + ent->client->lasersight = NULL; + } + return; + } + //Get rid of you? - if ( ent->client->lasersight && !enabled) + if ( ent->client->lasersight || enabled == qfalse) { G_FreeEntity( ent->client->lasersight ); ent->client->lasersight = NULL; @@ -2139,8 +2153,14 @@ void Laser_Think( gentity_t *self ) vec3_t end, start, forward, up; trace_t tr; - //If Player Dies, You Die -> now thanks to Camouflage! - if (self->parent->client->ps.pm_type == PM_DEAD) { + //If the player dies, or wrong weapon, kill the dot + if (self->parent->client->ps.pm_type == PM_DEAD || + (self->parent->client->ps.weapon != WP_PISTOL && + self->parent->client->ps.weapon != WP_MP5 && + self->parent->client->ps.weapon != WP_M4)) + { + //Make sure you kill the reference before freeing the entity + self->parent->client->lasersight = NULL; G_FreeEntity(self); return; }